Compare commits
208 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b97fe7e5b1 | |||
| 01db4fa951 | |||
|
cb153b50f1
|
|||
|
8b33bf40c3
|
|||
| 9a6221b723 | |||
|
a20b1cb263
|
|||
|
cfe6055083
|
|||
|
eea9abdc56
|
|||
| 138b94e562 | |||
|
d11467bd1b
|
|||
| 7be40d9bf9 | |||
|
dae8073992
|
|||
|
143e7dc17c
|
|||
| f4ace64173 | |||
|
236b486845
|
|||
|
c666f0228d
|
|||
| 81049856b5 | |||
| 4813e24848 | |||
| d61d001ddf | |||
| 060364abb5 | |||
| 13185f0e05 | |||
| fd266969f5 | |||
| bd471330e1 | |||
|
92602efa9e
|
|||
|
55a39ac85a
|
|||
|
39898825ef
|
|||
| 59a2d1454e | |||
|
16c324cf32
|
|||
|
b923b98b2c
|
|||
| afca7d5135 | |||
|
a05bebcd81
|
|||
|
02cc8330ca
|
|||
|
f8397b8bab
|
|||
| 38603fbe45 | |||
|
78700e868d
|
|||
|
259e8bdb7b
|
|||
| 0ea3c25b7b | |||
|
2fa1b7d329
|
|||
| af805f6ba4 | |||
|
34c361d3f8
|
|||
| 83eb621b0f | |||
|
65aaf4857d
|
|||
| 7d52447b00 | |||
| 046ab8d1a8 | |||
|
33c032092d
|
|||
| b8eeb93a8f | |||
|
e95f68406f
|
|||
|
c6f432a5c4
|
|||
| 9ca7446dba | |||
| 773a1adf64 | |||
|
6afe5d4c0d
|
|||
|
755a05fe34
|
|||
|
202da658ee
|
|||
| a5856cf240 | |||
|
38099e6167
|
|||
|
d307038e5e
|
|||
|
d5aeeaf5e3
|
|||
|
134a05ea23
|
|||
|
db63f2a67c
|
|||
| 97a3c3ef35 | |||
| a40e904ab3 | |||
| a8a89b0809 | |||
|
480efd1f8b
|
|||
| 26baccf3c4 | |||
| 916f9b2557 | |||
| 34992344b2 | |||
| 1ea8dea381 | |||
| 15aa0572f3 | |||
|
6a843f4a71
|
|||
|
a63c1a94ca
|
|||
| 43263035d9 | |||
|
42ab55d0f8
|
|||
|
44846cce57
|
|||
|
1451750bcb
|
|||
| 8ade5180cb | |||
| d0535d0c47 | |||
| 79fa09e39b | |||
|
4010c2125c
|
|||
| 32de0077de | |||
| bd53e016c5 | |||
| 5b1ed644d1 | |||
| a41787d89d | |||
| 8e392b56c3 | |||
| 42feadcd2d | |||
| 15f0344416 | |||
| c90a977ab2 | |||
| b186228f4e | |||
| 5f38474809 | |||
| 4f27320548 | |||
| ba7bd1f1dd | |||
| fbe70e7ead | |||
| 30a499be1d | |||
|
86e212fe42
|
|||
| 4a646e6be0 | |||
| bc0dc1925e | |||
| c3af4dbc68 | |||
| 703639537d | |||
| 9ac3bf6a6c | |||
| 41ea6c9407 | |||
| 67e9a3544e | |||
| f69ae3e77b | |||
|
2208dcc0fb
|
|||
| b466216b3a | |||
| 5a862b251b | |||
| 60a82a685d | |||
| 573b0c14ae | |||
| 82abe7e20f | |||
| 34da59714e | |||
| 97071165cd | |||
| 634465fbf1 | |||
| 2ad8cc3f4a | |||
| e190fe0858 | |||
| 569d91a0d3 | |||
| 487a15849a | |||
| e110033315 | |||
| c0b192e2bf | |||
| 612254296c | |||
|
1dbcb122c2
|
|||
|
f2ee9dbeb3
|
|||
| 404ab2abfb | |||
| 59a927c33c | |||
|
6c062216a1
|
|||
| 72d62dfbe5 | |||
| 76ecaccc41 | |||
| 9587b9e1fd | |||
| 14dc807fd9 | |||
| 63ad85f727 | |||
| 72e88502d2 | |||
| 71767ef6d9 | |||
| 5e19629df5 | |||
| ca70c6685c | |||
| f00bd153fe | |||
| c1221e5cf5 | |||
| 236944ff69 | |||
| ab85c72fe3 | |||
| a750185df0 | |||
| 008ff1091f | |||
| 5d24581038 | |||
| bce07a4ac8 | |||
|
30b7bbc283
|
|||
|
46a11af6ca
|
|||
| 73f903fc23 | |||
| 361c698323 | |||
| db4ea2d69d | |||
| 3cecc58bce | |||
| ce3d50fcb7 | |||
| 61bd28150b | |||
| bb9caa28a3 | |||
| 4b2970d243 | |||
|
834767edbe
|
|||
|
25116c3865
|
|||
|
4bea077d36
|
|||
|
74d6ccc24f
|
|||
|
d9f905d957
|
|||
|
663a745d8f
|
|||
|
1f64c3383d
|
|||
| e4676d5eba | |||
|
ebb2ec817d
|
|||
| b6445ce2e9 | |||
|
a454da6da8
|
|||
|
22ed7e23da
|
|||
| a87cc94700 | |||
| 31dac93698 | |||
| 1f568f3d8b | |||
| b8b8dd1ba0 | |||
| 99f864d889 | |||
| 711a21b634 | |||
| 9a85e8b442 | |||
|
8358203cd4
|
|||
|
6a619c2fd1
|
|||
|
d348e4a480
|
|||
|
1269e4d971
|
|||
|
feac17d732
|
|||
|
975b2bb8e6
|
|||
| a1add4f997 | |||
| b517fe3ad0 | |||
| ac5dda58a1 | |||
| 9efe625603 | |||
| 146ed598c8 | |||
| 50e86fbf89 | |||
| 7216806a1c | |||
| 6cda79f7e1 | |||
| 87cc43a348 | |||
| f9509c19d1 | |||
| e7bd5a9e74 | |||
| aa74e0b887 | |||
|
fe8d37c966
|
|||
| ccb79737db | |||
|
1eea792e23
|
|||
| 19c6ad0965 | |||
| 2c5306bfd1 | |||
| 1982b5e42c | |||
| 3ad4081add | |||
|
33a7961979
|
|||
| 4e994813eb | |||
| 367a72141a | |||
| c29788f1eb | |||
| 9d32a331ca | |||
| c55494aeba | |||
| 61dcee6f8e | |||
|
8b2b7e011a
|
|||
|
09d2ed5384
|
|||
|
b576c36c2d
|
|||
|
a089d42d9a
|
|||
|
0a7a753c48
|
|||
|
86bfde90b8
|
|||
|
7c5a927d0f
|
|||
|
c0163d813e
|
@@ -0,0 +1,60 @@
|
|||||||
|
name: Bug Report
|
||||||
|
about: Du hast einen Fehler gefunden? Melde ihn hier!
|
||||||
|
labels: [ "typ/bug" ]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
ACHTUNG: Sollte es bei dem Bug ein Sicherheitsrisiko geben, melde es bitte auf unserem Discord Server
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: |
|
||||||
|
Beschreibe deinen Bug in kurzer Form.
|
||||||
|
- type: input
|
||||||
|
id: mc-ver
|
||||||
|
attributes:
|
||||||
|
label: Minecraft Version
|
||||||
|
description: Minecraft Version des Clients
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: mc-ver-ser
|
||||||
|
attributes:
|
||||||
|
label: Minecraft Version Server
|
||||||
|
description: Minecraft Version des Servers, nur bei Bau oder Arenen Servern
|
||||||
|
- type: dropdown
|
||||||
|
id: can-reproduce
|
||||||
|
attributes:
|
||||||
|
label: Kannst du den Fehler wiederholen?
|
||||||
|
description: |
|
||||||
|
Wenn du den Fehler wiederholen kannst, können wir dieses Problem schneller beheben.
|
||||||
|
Solltest du den Fehler nicht wiederholen können, melde dich bitte auf unserem Discord Server.
|
||||||
|
options:
|
||||||
|
- "Yes"
|
||||||
|
- "No"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reproduce-steps
|
||||||
|
attributes:
|
||||||
|
label: Wie kannst du den Fehler wiederholen?
|
||||||
|
description: Welche Schritte musst du ausführen, um den Fehler wiederholen zu können?
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: expected-result
|
||||||
|
attributes:
|
||||||
|
label: Was sollte passieren?
|
||||||
|
description: Was sollte hier deiner Erwartung nach passieren?
|
||||||
|
- type: input
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Auf welchem Server ist der Fehler aufgetreten?
|
||||||
|
description: Gebe bitte den Namen des Servers an, auf dem der Fehler aufgetreten ist. z.B. "Lobby", "Lixfels Bauserver" etc.
|
||||||
|
- type: textarea
|
||||||
|
id: screenshots
|
||||||
|
attributes:
|
||||||
|
label: Screenshots
|
||||||
|
description: Sollte es ein Visuelles Problem geben, kannst du hier Screenshots hinzufügen.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: true
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
name: Feature Idee
|
||||||
|
about: Du hast eine Idee für ein neues Feature, welches SteamWar nicht hat? Stelle sie hier vor.
|
||||||
|
labels: ["typ/idee"]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Feature Beschreibung
|
||||||
|
placeholder: |
|
||||||
|
Ich glaube, dass ...
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: screenshots
|
||||||
|
attributes:
|
||||||
|
label: Screenshots
|
||||||
|
description: Wenn es sich um etwas grafisches handelt, kannst du hier Screenshots hinzufügen.
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
name: Backport CommonCore
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
BACKPORT_PATH: CommonCore
|
||||||
|
BACKPORT_BRANCH_PREFIX: backport/commoncore
|
||||||
|
DISABLE_BACKPORT_LABEL: no-backport
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
backport:
|
||||||
|
name: Create CommonCore backport PRs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Check backport eligibility
|
||||||
|
id: eligibility
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
api_url="${GITHUB_API_URL:-${GITHUB_SERVER_URL}/api/v1}"
|
||||||
|
|
||||||
|
echo "Backport debug: event=${GITHUB_EVENT_NAME:-unknown}"
|
||||||
|
echo "Backport debug: server=${GITHUB_SERVER_URL}"
|
||||||
|
echo "Backport debug: api=${api_url}"
|
||||||
|
echo "Backport debug: repository=${GITHUB_REPOSITORY}"
|
||||||
|
echo "Backport debug: action=$(jq -r '.action // ""' "$GITHUB_EVENT_PATH")"
|
||||||
|
|
||||||
|
merged="$(jq -r '.pull_request.merged // (.pull_request.merged_at != null)' "$GITHUB_EVENT_PATH")"
|
||||||
|
base_branch="$(jq -r '.pull_request.base.ref' "$GITHUB_EVENT_PATH")"
|
||||||
|
has_disable_label="$(jq -r --arg disable_backport_label "$DISABLE_BACKPORT_LABEL" 'any(.pull_request.labels[]?; .name == $disable_backport_label)' "$GITHUB_EVENT_PATH")"
|
||||||
|
echo "Backport debug: pr=$(jq -r '.pull_request.number // ""' "$GITHUB_EVENT_PATH") base=${base_branch} merged=${merged}"
|
||||||
|
echo "Backport debug: disable label present=${has_disable_label}"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "should_backport=$([[ "$merged" == "true" && "$base_branch" == "main" && "$has_disable_label" != "true" ]] && echo true || echo false)"
|
||||||
|
echo "pr_number=$(jq -r '.pull_request.number' "$GITHUB_EVENT_PATH")"
|
||||||
|
echo "pr_title<<EOF"
|
||||||
|
jq -r '.pull_request.title' "$GITHUB_EVENT_PATH"
|
||||||
|
echo "EOF"
|
||||||
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
labels="$(curl -fsS \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||||
|
"${api_url}/repos/${GITHUB_REPOSITORY}/labels")"
|
||||||
|
|
||||||
|
if ! jq -e --arg disable_backport_label "$DISABLE_BACKPORT_LABEL" 'any(.[]; .name == $disable_backport_label)' <<< "$labels" >/dev/null; then
|
||||||
|
curl -fsS -X POST \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$(jq -n --arg name "$DISABLE_BACKPORT_LABEL" --arg color "ededed" --arg description "Disable automatic CommonCore backporting for this pull request." '{name: $name, color: $color, description: $description}')" \
|
||||||
|
"${api_url}/repos/${GITHUB_REPOSITORY}/labels"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Create backport pull requests
|
||||||
|
if: steps.eligibility.outputs.should_backport == 'true'
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }}
|
||||||
|
PR_NUMBER: ${{ steps.eligibility.outputs.pr_number }}
|
||||||
|
PR_TITLE: ${{ steps.eligibility.outputs.pr_title }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
api_url="${GITHUB_API_URL:-${GITHUB_SERVER_URL}/api/v1}"
|
||||||
|
repo_api_path="/repos/${GITHUB_REPOSITORY}"
|
||||||
|
|
||||||
|
api_request() {
|
||||||
|
local method="$1"
|
||||||
|
local path="$2"
|
||||||
|
local output="$3"
|
||||||
|
local data_file="${4:-}"
|
||||||
|
local status
|
||||||
|
local args=(-sS -X "$method" -H "Accept: application/json" -H "Authorization: token ${GITHUB_TOKEN}" -w "%{http_code}" -o "$output")
|
||||||
|
|
||||||
|
if [[ -n "$data_file" ]]; then
|
||||||
|
args+=(-H "Content-Type: application/json" --data-binary "@${data_file}")
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Backport debug: ${method} ${path}"
|
||||||
|
if ! status="$(curl "${args[@]}" "${api_url}${path}")"; then
|
||||||
|
echo "Backport debug: ${method} ${path} failed before HTTP status was captured."
|
||||||
|
if [[ -s "$output" ]]; then
|
||||||
|
echo "Backport debug: response body:"
|
||||||
|
cat "$output"
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Backport debug: ${method} ${path} -> HTTP ${status}"
|
||||||
|
if [[ ! "$status" =~ ^2 ]]; then
|
||||||
|
echo "Backport debug: response body:"
|
||||||
|
cat "$output"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Backport debug: event=${GITHUB_EVENT_NAME:-unknown}"
|
||||||
|
echo "Backport debug: server=${GITHUB_SERVER_URL}"
|
||||||
|
echo "Backport debug: api=${api_url}"
|
||||||
|
echo "Backport debug: repository=${GITHUB_REPOSITORY}"
|
||||||
|
echo "Backport debug: pr=${PR_NUMBER}"
|
||||||
|
echo "Backport debug: actor=${GITHUB_ACTOR:-unknown}"
|
||||||
|
|
||||||
|
git config user.name "SteamWar Backport Bot"
|
||||||
|
git config user.email "actions@steamwar.de"
|
||||||
|
|
||||||
|
if [[ "${GITHUB_SERVER_URL}" == https://* ]]; then
|
||||||
|
auth_host="${GITHUB_SERVER_URL#https://}"
|
||||||
|
git remote set-url origin "https://oauth2:${GITHUB_TOKEN}@${auth_host}/${GITHUB_REPOSITORY}.git"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git fetch --prune origin '+refs/heads/version/*:refs/remotes/origin/version/*'
|
||||||
|
|
||||||
|
api_request GET "${repo_api_path}" repo-debug.json
|
||||||
|
jq -r '"Backport debug: repo permissions admin=\(.permissions.admin // "unknown") push=\(.permissions.push // "unknown") pull=\(.permissions.pull // "unknown")"' repo-debug.json || true
|
||||||
|
|
||||||
|
echo "Backport debug: GET ${repo_api_path}/pulls/${PR_NUMBER}.diff"
|
||||||
|
curl -fsSL -w "Backport debug: GET ${repo_api_path}/pulls/${PR_NUMBER}.diff -> HTTP %{http_code}\n" \
|
||||||
|
-H "Accept: text/plain" \
|
||||||
|
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||||
|
"${api_url}${repo_api_path}/pulls/${PR_NUMBER}.diff" \
|
||||||
|
-o pull-request.diff
|
||||||
|
|
||||||
|
if ! grep -Eq "^diff --git a/${BACKPORT_PATH}/" pull-request.diff; then
|
||||||
|
echo "Pull request #${PR_NUMBER} has no ${BACKPORT_PATH} changes to backport."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mapfile -t target_branches < <(git for-each-ref --format='%(refname:strip=3)' refs/remotes/origin/version)
|
||||||
|
if [[ "${#target_branches[@]}" -eq 0 ]]; then
|
||||||
|
echo "No version/* branches found."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for target_branch in "${target_branches[@]}"; do
|
||||||
|
safe_target="${target_branch//\//-}"
|
||||||
|
backport_branch="${BACKPORT_BRANCH_PREFIX}/pr-${PR_NUMBER}-to-${safe_target}"
|
||||||
|
|
||||||
|
git checkout -B "${backport_branch}" "origin/${target_branch}"
|
||||||
|
git reset --hard "origin/${target_branch}"
|
||||||
|
|
||||||
|
if ! git apply --3way --index --include="${BACKPORT_PATH}/**" pull-request.diff; then
|
||||||
|
echo "Failed to apply CommonCore backport for ${target_branch}."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if git diff --cached --quiet; then
|
||||||
|
echo "CommonCore changes from #${PR_NUMBER} are already present in ${target_branch}."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
git commit -m "Backport CommonCore changes from #${PR_NUMBER}" -m "${PR_TITLE}"
|
||||||
|
git push --force-with-lease origin "${backport_branch}"
|
||||||
|
|
||||||
|
api_request GET "${repo_api_path}/pulls?state=open" open-pulls.json
|
||||||
|
open_pr_number="$(jq -r --arg base "$target_branch" --arg head "$backport_branch" '[.[] | select(.base.ref == $base and .head.ref == $head) | (.number // .index)][0] // empty' open-pulls.json)"
|
||||||
|
|
||||||
|
if [[ -n "$open_pr_number" ]]; then
|
||||||
|
echo "Backport PR #${open_pr_number} already exists for ${target_branch}."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
pr_body="$(printf 'Automatic CommonCore backport of #%s.\n\nOriginal PR title: %s\n\nOnly files below `CommonCore/` are included.' "$PR_NUMBER" "$PR_TITLE")"
|
||||||
|
|
||||||
|
jq -n \
|
||||||
|
--arg base "$target_branch" \
|
||||||
|
--arg head "$backport_branch" \
|
||||||
|
--arg title "Backport CommonCore changes from #${PR_NUMBER} to ${target_branch}" \
|
||||||
|
--arg body "$pr_body" \
|
||||||
|
'{base: $base, head: $head, title: $title, body: $body}' > create-pull.json
|
||||||
|
|
||||||
|
echo "Backport debug: create PR base=${target_branch} head=${backport_branch}"
|
||||||
|
api_request POST "${repo_api_path}/pulls" create-pull-response.json create-pull.json
|
||||||
|
done
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
name: Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- version/*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
- name: Setup Java 8
|
||||||
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 8
|
||||||
|
- name: Setup Java 11
|
||||||
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 11
|
||||||
|
- name: Setup Java 17
|
||||||
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 17
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 21
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@v6
|
||||||
|
- name: Setup Maven Repository
|
||||||
|
env:
|
||||||
|
SW_MAVEN_CREDENTIALS: ${{ secrets.SW_MAVEN_CREDENTIALS }}
|
||||||
|
run: |
|
||||||
|
echo "$SW_MAVEN_CREDENTIALS" > steamwar.properties
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: ./gradlew build --no-daemon
|
||||||
|
|
||||||
|
- name: Stage deploy artifacts
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
rm -rf deploy
|
||||||
|
mkdir -p deploy
|
||||||
|
|
||||||
|
cp "BauSystem/build/libs/BauSystem-all.jar" "deploy/BauSystem.jar"
|
||||||
|
cp "LegacyBauSystem/build/libs/LegacyBauSystem.jar" "deploy/BauSystem-1.12.jar"
|
||||||
|
cp "FightSystem/build/libs/FightSystem-all.jar" "deploy/FightSystem.jar"
|
||||||
|
cp "KotlinCore/build/libs/KotlinCore-all.jar" "deploy/KotlinCore.jar"
|
||||||
|
cp "TNTLeague/build/libs/TNTLeague.jar" "deploy/TNTLeague.jar"
|
||||||
|
cp "LobbySystem/build/libs/LobbySystem.jar" "deploy/LobbySystem.jar"
|
||||||
|
cp "MissileWars/build/libs/MissileWars.jar" "deploy/MissileWars.jar"
|
||||||
|
cp "Realtime/build/libs/Realtime.jar" "deploy/RealTime.jar"
|
||||||
|
cp "SchematicSystem/build/libs/SchematicSystem-all.jar" "deploy/SchematicSystem.jar"
|
||||||
|
cp "SpigotCore/build/libs/SpigotCore-all.jar" "deploy/SpigotCore.jar"
|
||||||
|
cp "Teamserver/build/libs/Teamserver.jar" "deploy/Builder.jar"
|
||||||
|
cp "TowerRun/build/libs/TowerRun.jar" "deploy/TowerRun.jar"
|
||||||
|
cp "VelocityCore/Persistent/build/libs/Persistent.jar" "deploy/PersistentVelocityCore.jar"
|
||||||
|
cp "VelocityCore/Dependencies/build/libs/Dependencies-all.jar" "deploy/DependenciesVelocityCore.jar"
|
||||||
|
cp "VelocityCore/build/libs/VelocityCore-all.jar" "deploy/VelocityCore.jar"
|
||||||
|
cp "WebsiteBackend/build/libs/WebsiteBackend-all.jar" "deploy/website-api.jar"
|
||||||
|
cp "CLI/build/distributions/sw.zip" "deploy/sw.zip"
|
||||||
|
|
||||||
|
- name: Upload deploy artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: steamwar-jars
|
||||||
|
path: deploy/
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
name: Deploy
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
|
- name: Download deploy artifacts
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: steamwar-jars
|
||||||
|
path: deploy
|
||||||
|
|
||||||
|
- name: Resolve deploy target
|
||||||
|
id: target
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [[ "${GITHUB_REF_NAME}" == "main" ]]; then
|
||||||
|
echo "path=/jars/current" >> "$GITHUB_OUTPUT"
|
||||||
|
elif [[ "${GITHUB_REF_NAME}" == version/* ]]; then
|
||||||
|
version="${GITHUB_REF_NAME#version/}"
|
||||||
|
if [[ ! "$version" =~ ^[A-Za-z0-9._-]+$ ]]; then
|
||||||
|
echo "Unsupported version branch name: ${GITHUB_REF_NAME}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "path=/jars/${version}" >> "$GITHUB_OUTPUT"
|
||||||
|
else
|
||||||
|
echo "Unsupported deployment branch: ${GITHUB_REF_NAME}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Upload jars with scp
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||||
|
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||||
|
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
|
||||||
|
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||||
|
DEPLOY_PATH: ${{ steps.target.outputs.path }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
: "${DEPLOY_HOST:?Missing DEPLOY_HOST secret}"
|
||||||
|
: "${DEPLOY_USER:?Missing DEPLOY_USER secret}"
|
||||||
|
: "${DEPLOY_SSH_KEY:?Missing DEPLOY_SSH_KEY secret}"
|
||||||
|
|
||||||
|
port="${DEPLOY_PORT:-22}"
|
||||||
|
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
chmod 700 ~/.ssh
|
||||||
|
echo "$DEPLOY_SSH_KEY" > ~/.ssh/deploy_key
|
||||||
|
chmod 600 ~/.ssh/deploy_key
|
||||||
|
ssh-keyscan -p "$port" "$DEPLOY_HOST" >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p '$DEPLOY_PATH'"
|
||||||
|
scp -i ~/.ssh/deploy_key -P "$port" deploy/* "${DEPLOY_USER}@${DEPLOY_HOST}:$DEPLOY_PATH/"
|
||||||
|
- name: Restart Services
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||||
|
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||||
|
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
|
||||||
|
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ssh -i ~/.ssh/deploy_key -p "$DEPLOY_PORT" "${DEPLOY_USER}@${DEPLOY_HOST}" "sudo systemctl restart api.service"
|
||||||
|
ssh -i ~/.ssh/deploy_key -p "$DEPLOY_PORT" "${DEPLOY_USER}@${DEPLOY_HOST}" "unzip -o /jars/current/sw.zip -d /jars"
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
name: Pull Request Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout sources
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
- name: Setup Java 8
|
||||||
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 8
|
||||||
|
- name: Setup Java 11
|
||||||
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 11
|
||||||
|
- name: Setup Java 17
|
||||||
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 17
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v5
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 21
|
||||||
|
- name: Setup Gradle
|
||||||
|
uses: gradle/actions/setup-gradle@v6
|
||||||
|
- name: Setup Maven Repository
|
||||||
|
env:
|
||||||
|
SW_MAVEN_CREDENTIALS: ${{ secrets.SW_MAVEN_CREDENTIALS }}
|
||||||
|
run: |
|
||||||
|
echo "$SW_MAVEN_CREDENTIALS" > steamwar.properties
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: ./gradlew build --no-daemon
|
||||||
|
|
||||||
|
- name: Merge successful backport PR
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }}
|
||||||
|
BACKPORT_BRANCH_PREFIX: backport/commoncore
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
head_branch="$(jq -r '.pull_request.head.ref // ""' "$GITHUB_EVENT_PATH")"
|
||||||
|
base_branch="$(jq -r '.pull_request.base.ref // ""' "$GITHUB_EVENT_PATH")"
|
||||||
|
pr_number="$(jq -r '.pull_request.number' "$GITHUB_EVENT_PATH")"
|
||||||
|
|
||||||
|
if [[ "${head_branch}" != "${BACKPORT_BRANCH_PREFIX}/"* ]]; then
|
||||||
|
echo "Not a CommonCore backport PR."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${base_branch}" != version/* ]]; then
|
||||||
|
echo "Backport PR target is not a version/* branch."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
api_url="${GITHUB_API_URL:-${GITHUB_SERVER_URL}/api/v1}"
|
||||||
|
|
||||||
|
curl -fsS -X POST \
|
||||||
|
-H "Accept: application/json" \
|
||||||
|
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"Do":"merge","delete_branch_after_merge":true}' \
|
||||||
|
"${api_url}/repos/${GITHUB_REPOSITORY}/pulls/${pr_number}/merge"
|
||||||
+2
-1
@@ -20,4 +20,5 @@ lib
|
|||||||
/WebsiteBackend/data
|
/WebsiteBackend/data
|
||||||
/WebsiteBackend/logs
|
/WebsiteBackend/logs
|
||||||
/WebsiteBackend/skins
|
/WebsiteBackend/skins
|
||||||
/WebsiteBackend/config.json
|
/WebsiteBackend/config.json
|
||||||
|
/WebsiteBackend/sessions
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.nms15)
|
|
||||||
compileOnly(libs.worldedit15)
|
|
||||||
}
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
|
||||||
import de.steamwar.bausystem.region.Point;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.bukkit.block.data.Waterlogged;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.function.BiPredicate;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class FlatteningWrapper15 implements FlatteningWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNoBook(ItemStack item) {
|
|
||||||
return item.getType() != Material.WRITABLE_BOOK && item.getType() != Material.WRITTEN_BOOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Set<Material> unpushable = new HashSet<>(Arrays.asList(Material.BARRIER, Material.BEACON, Material.COMMAND_BLOCK, Material.CHAIN_COMMAND_BLOCK, Material.REPEATING_COMMAND_BLOCK, Material.ENCHANTING_TABLE, Material.END_GATEWAY, Material.END_PORTAL, Material.ENDER_CHEST, Material.GRINDSTONE, Material.JIGSAW, Material.JUKEBOX, Material.NETHER_PORTAL, Material.OBSIDIAN, Material.STRUCTURE_VOID, Material.BARREL, Material.BEEHIVE, Material.BEE_NEST, Material.BLAST_FURNACE, Material.BREWING_STAND, Material.CHEST, Material.DAYLIGHT_DETECTOR, Material.DISPENSER, Material.DROPPER, Material.FURNACE, Material.HOPPER, Material.LECTERN, Material.SMOKER, Material.TRAPPED_CHEST));
|
|
||||||
|
|
||||||
// TODO: FLOWER
|
|
||||||
private static final Set<Material> breaking = new HashSet<>(Arrays.asList(Material.BAMBOO, Material.CACTUS, Material.CAKE, Material.CARVED_PUMPKIN, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.COBWEB, Material.COCOA, Material.DRAGON_EGG, Material.FIRE, Material.FLOWER_POT, Material.JACK_O_LANTERN, Material.LADDER, Material.LAVA, Material.LAVA, Material.LEVER, Material.LILY_PAD, Material.MELON, Material.NETHER_WART, Material.PUMPKIN, Material.COMPARATOR, Material.REDSTONE_WIRE, Material.REPEATER, Material.TORCH, Material.STRUCTURE_VOID, Material.SCAFFOLDING, Material.SEA_PICKLE, Material.SNOW, Material.SUGAR_CANE, Material.TORCH, Material.TRIPWIRE, Material.TRIPWIRE_HOOK, Material.TURTLE_EGG, Material.VINE, Material.WATER, Material.WHEAT));
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isUnpusheable(Material material) {
|
|
||||||
if (unpushable.contains(material)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
String name = material.name();
|
|
||||||
return name.contains("BANNER") || name.contains("SIGN");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBreakingOnPush(Material material) {
|
|
||||||
if (breaking.contains(material)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
String name = material.name();
|
|
||||||
return name.contains("BED") || name.contains("BUTTON") || name.contains("CARPET") || (name.contains("DOOR") && !name.contains("TRAPDOOR")) || name.contains("HEAD") || name.contains("LEAVES") || name.contains("MUSHROOM") || name.contains("PRESSURE_PLATE") || name.contains("SHULKER_BOX");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isWorldEditCommand(String command) {
|
|
||||||
if (command.startsWith("/")) {
|
|
||||||
command = command.replaceFirst("/", "");
|
|
||||||
}
|
|
||||||
command = command.toLowerCase();
|
|
||||||
return WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getCommandManager().containsCommand(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final WorldEditPlugin WORLDEDIT_PLUGIN = Objects.requireNonNull((WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"));
|
|
||||||
private static final World BUKKITWORLD = new BukkitWorld(Bukkit.getWorlds().get(0));
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSelection(Player p, Point minPoint, Point maxPoint) {
|
|
||||||
WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, minPoint.toBlockVector3(), maxPoint.toBlockVector3()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Clipboard loadSchematic(File file) {
|
|
||||||
Clipboard clipboard;
|
|
||||||
try (ClipboardReader reader = Objects.requireNonNull(ClipboardFormats.findByFile(file)).getReader(new FileInputStream(file))) {
|
|
||||||
clipboard = reader.read();
|
|
||||||
} catch (NullPointerException | IOException e) {
|
|
||||||
throw new SecurityException("Bausystem schematic not found", e);
|
|
||||||
}
|
|
||||||
return clipboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EditSession paste(PasteBuilder pasteBuilder) {
|
|
||||||
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
|
|
||||||
Clipboard clipboard = pasteBuilder.getClipboard();
|
|
||||||
|
|
||||||
if (!pasteBuilder.getMappers().isEmpty()) {
|
|
||||||
BlockVector3 minimum = clipboard.getRegion().getMinimumPoint();
|
|
||||||
for (int x = 0; x < clipboard.getDimensions().getX(); x++) {
|
|
||||||
for (int y = 0; y < clipboard.getDimensions().getY(); y++) {
|
|
||||||
for (int z = 0; z < clipboard.getDimensions().getZ(); z++) {
|
|
||||||
BlockVector3 pos = minimum.add(x, y, z);
|
|
||||||
pasteBuilder.getMappers().forEach(mapper -> mapper.accept(clipboard, pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AtomicReference<BlockVector3> pastePoint = new AtomicReference<>();
|
|
||||||
if (!pasteBuilder.getPredicates().isEmpty()) {
|
|
||||||
e.setMask(new Mask() {
|
|
||||||
@Override
|
|
||||||
public boolean test(BlockVector3 blockVector3) {
|
|
||||||
BaseBlock block = clipboard.getFullBlock(blockVector3.subtract(pastePoint.get()).add(clipboard.getRegion().getMinimumPoint()));
|
|
||||||
String blockName = block.getBlockType().toString().toLowerCase();
|
|
||||||
for (BiPredicate<BaseBlock, String> predicate : pasteBuilder.getPredicates()) {
|
|
||||||
if (!predicate.test(block, blockName)) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mask copy() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Mask2D toMask2D() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ClipboardHolder ch = new ClipboardHolder(clipboard);
|
|
||||||
BlockVector3 dimensions = clipboard.getDimensions();
|
|
||||||
BlockVector3 v = BlockVector3.at(pasteBuilder.getPastPoint().getX(), pasteBuilder.getPastPoint().getY(), pasteBuilder.getPastPoint().getZ());
|
|
||||||
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
|
||||||
if (pasteBuilder.isRotate()) {
|
|
||||||
ch.setTransform(new AffineTransform().rotateY(180));
|
|
||||||
v = v.add(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset.multiply(-1, 1, -1)).subtract(0, 0, 1);
|
|
||||||
} else {
|
|
||||||
v = v.subtract(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset);
|
|
||||||
}
|
|
||||||
pastePoint.set(v);
|
|
||||||
|
|
||||||
if (pasteBuilder.isReset()) {
|
|
||||||
e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
|
|
||||||
if (pasteBuilder.getWaterLevel() != 0) {
|
|
||||||
e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3().withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(pasteBuilder.isIgnoreAir()).build());
|
|
||||||
return e;
|
|
||||||
} catch (WorldEditException e) {
|
|
||||||
throw new SecurityException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Clipboard copy(Point minPoint, Point maxPoint, Point copyPoint) {
|
|
||||||
BukkitWorld bukkitWorld = new BukkitWorld(Bukkit.getWorlds().get(0));
|
|
||||||
CuboidRegion region = new CuboidRegion(bukkitWorld, minPoint.toBlockVector3(), maxPoint.toBlockVector3());
|
|
||||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
|
|
||||||
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(bukkitWorld, -1)) {
|
|
||||||
ForwardExtentCopy copy = new ForwardExtentCopy(
|
|
||||||
e, region, clipboard, region.getMinimumPoint()
|
|
||||||
);
|
|
||||||
|
|
||||||
copy.setCopyingEntities(false);
|
|
||||||
copy.setCopyingBiomes(false);
|
|
||||||
|
|
||||||
Operations.complete(copy);
|
|
||||||
clipboard.setOrigin(copyPoint.toBlockVector3());
|
|
||||||
return clipboard;
|
|
||||||
} catch (WorldEditException e) {
|
|
||||||
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean backup(Point minPoint, Point maxPoint, File file) {
|
|
||||||
Clipboard clipboard = copy(minPoint, maxPoint, minPoint);
|
|
||||||
try (ClipboardWriter writer = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) {
|
|
||||||
writer.write(clipboard);
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean inWater(org.bukkit.World world, Vector tntPosition) {
|
|
||||||
Block block = world.getBlockAt(tntPosition.getBlockX(), tntPosition.getBlockY(), tntPosition.getBlockZ());
|
|
||||||
if (block.getType() == Material.WATER)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
BlockData data = block.getBlockData();
|
|
||||||
if (!(data instanceof Waterlogged))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return ((Waterlogged) data).isWaterlogged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import net.minecraft.server.v1_15_R1.*;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NMSWrapper15 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(((CraftPlayer) player).getHandle().playerInteractManager, EnumGamemode.getById(gameMode.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.b();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.getItemStack()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<Integer> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, int.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
((CraftPlayer) player).getHandle().abilities.mayBuild = true;
|
|
||||||
((CraftPlayer) player).getHandle().abilities.canInstantlyBuild = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.GRASS_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
net.minecraft.server.v1_15_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
|
|
||||||
NBTTagCompound tag = nmsItem.getTag();
|
|
||||||
if (tag != null && tag.hasKey("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = tag.getCompound("BlockEntityTag");
|
|
||||||
if (blockTag.hasKey("Items")) {
|
|
||||||
return drillDown(blockTag.getList("Items", 10), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(NBTTagList items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (NBTBase nbtBase : items) {
|
|
||||||
if (!(nbtBase instanceof NBTTagCompound))
|
|
||||||
continue;
|
|
||||||
NBTTagCompound slot = (NBTTagCompound) nbtBase;
|
|
||||||
if (slot.hasKey("tag")) {
|
|
||||||
invalid += slot.getByte("Count");
|
|
||||||
NBTTagCompound iTag = slot.getCompound("tag");
|
|
||||||
if (iTag.hasKey("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = iTag.getCompound("BlockEntityTag");
|
|
||||||
if (blockTag.hasKey("Items")) {
|
|
||||||
invalid = drillDown(blockTag.getList("Items", 10), layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalid > threshold)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
|
|
||||||
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
|
|
||||||
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
|
|
||||||
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
|
|
||||||
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
|
|
||||||
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
PacketPlayOutExplosion packetPlayOutExplosion = (PacketPlayOutExplosion) packet;
|
|
||||||
return new PacketPlayOutExplosion(a.get(packetPlayOutExplosion), b.get(packetPlayOutExplosion), c.get(packetPlayOutExplosion), d.get(packetPlayOutExplosion), e.get(packetPlayOutExplosion), Vec3D.a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
|
|
||||||
public class PlaceItemWrapper15 implements PlaceItemWrapper {
|
|
||||||
|
|
||||||
public PlaceItemWrapper15() {
|
|
||||||
for (Material material : Material.values()) {
|
|
||||||
if (!material.isBlock()) continue;
|
|
||||||
if (material.isLegacy()) continue;
|
|
||||||
|
|
||||||
String nonWall = material.name().replace("_WALL_", "").replace("WALL_", "").replace("_WALL", "");
|
|
||||||
try {
|
|
||||||
Material nonWallMaterial = Material.valueOf(nonWall);
|
|
||||||
if (nonWallMaterial != material && nonWallMaterial.isItem() && !nonWallMaterial.isBlock()) {
|
|
||||||
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(nonWallMaterial, material);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ITEM_MATERIAL_TO_BLOCK_MATERIAL.put(Material.REDSTONE, Material.REDSTONE_WIRE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import net.minecraft.server.v1_15_R1.EntityPlayer;
|
|
||||||
import net.minecraft.server.v1_15_R1.PacketPlayInFlying;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper15 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (Float.isNaN(packetPlayInFlying.a(Float.NaN))) {
|
|
||||||
entityPlayer.e(packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0));
|
|
||||||
} else {
|
|
||||||
entityPlayer.setLocation(packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0), packetPlayInFlying.a(0F), packetPlayInFlying.b(0F));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
Object packet = Reflection.newInstance(teleportPacket);
|
|
||||||
teleportEntity.set(packet, player.getEntityId());
|
|
||||||
teleportPosition.set(packet, packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0),
|
|
||||||
Float.isNaN(packetPlayInFlying.a(Float.NaN)) ? player.getLocation().getYaw() : packetPlayInFlying.a(0.0F),
|
|
||||||
Float.isNaN(packetPlayInFlying.b(Float.NaN)) ? player.getLocation().getPitch() : packetPlayInFlying.b(0.0F));
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
public class TickListener15 implements TickListener {
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.bausystem.region.Region;
|
|
||||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
|
||||||
import de.steamwar.bausystem.utils.tps.TPSFreezeUtils;
|
|
||||||
import de.steamwar.bausystem.utils.tps.TPSLimitUtils;
|
|
||||||
import de.steamwar.core.TPSWarpUtils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
public class TickManager15 implements TickManager, Listener {
|
|
||||||
|
|
||||||
private static float currentTPSLimit = 20;
|
|
||||||
private boolean currentlyStepping = false;
|
|
||||||
private float currentLimit;
|
|
||||||
private int stepsTotal;
|
|
||||||
private int stepsLeft;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFreeze() {
|
|
||||||
return TPSFreezeUtils.isCanFreeze();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTickRate(float tickRate) {
|
|
||||||
if (currentlyStepping) {
|
|
||||||
currentlyStepping = false;
|
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
|
||||||
BossBarService.instance.remove(player, Region.getGlobalRegion(), "TickStep");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
TPSWarpUtils.warp(tickRate);
|
|
||||||
if (currentTPSLimit == 0 && tickRate != 0) {
|
|
||||||
TPSFreezeUtils.unfreeze();
|
|
||||||
}
|
|
||||||
currentTPSLimit = tickRate;
|
|
||||||
if (tickRate == 0) {
|
|
||||||
TPSLimitUtils.unlimit();
|
|
||||||
TPSFreezeUtils.freeze();
|
|
||||||
} else if (tickRate < 20.0) {
|
|
||||||
TPSLimitUtils.limit(tickRate);
|
|
||||||
} else if (tickRate >= 20) {
|
|
||||||
TPSLimitUtils.unlimit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFrozen() {
|
|
||||||
return TPSFreezeUtils.frozen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFreeze(boolean freeze) {
|
|
||||||
if (freeze) {
|
|
||||||
setTickRate(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stepTicks(int ticks) {
|
|
||||||
currentLimit = 0;
|
|
||||||
setTickRate(20);
|
|
||||||
stepsLeft = ticks;
|
|
||||||
stepsTotal = ticks;
|
|
||||||
currentlyStepping = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sprintTicks(int ticks) {
|
|
||||||
currentLimit = currentTPSLimit;
|
|
||||||
setTickRate(4000);
|
|
||||||
stepsLeft = ticks;
|
|
||||||
stepsTotal = ticks;
|
|
||||||
currentlyStepping = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSprinting() {
|
|
||||||
return currentlyStepping && currentTPSLimit > 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isStepping() {
|
|
||||||
return currentlyStepping && currentTPSLimit <= 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getTickRate() {
|
|
||||||
return currentTPSLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlockTpsPacket(boolean block) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalTicks() {
|
|
||||||
return stepsTotal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDoneTicks() {
|
|
||||||
return stepsTotal - stepsLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getRemainingTicks() {
|
|
||||||
return stepsLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onTickEnd(TickEndEvent event) {
|
|
||||||
if (!currentlyStepping) return;
|
|
||||||
stepsLeft--;
|
|
||||||
if (stepsLeft <= 0) {
|
|
||||||
setTickRate(currentLimit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils.tps;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.core.BountifulWrapper;
|
|
||||||
import de.steamwar.core.ChatWrapper;
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.entity.TNTPrimed;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
class PacketCache {
|
|
||||||
|
|
||||||
private static List<Object> packets = new ArrayList<>();
|
|
||||||
private static Set<Entity> entities = new HashSet<>();
|
|
||||||
private static BukkitTask task = null;
|
|
||||||
|
|
||||||
private static Class<?> vec3dClass = Reflection.getClass("net.minecraft.world.phys.Vec3");
|
|
||||||
private static Reflection.Field<Object> zeroVec3d = (Reflection.Field<Object>) Reflection.getField(vec3dClass, vec3dClass, 0);
|
|
||||||
private static Object ZERO_VEC3D = zeroVec3d.get(null);
|
|
||||||
private static Class<?> velocityPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket");
|
|
||||||
private static Reflection.Constructor velocityPacketConstructor = Reflection.getConstructor(velocityPacketClass, int.class, vec3dClass);
|
|
||||||
|
|
||||||
private static Class<?> teleportPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket");
|
|
||||||
private static Class<?> entityClass = Reflection.getClass("net.minecraft.world.entity.Entity");
|
|
||||||
private static Reflection.Constructor teleportPacketConstructor = Reflection.getConstructor(teleportPacketClass, entityClass);
|
|
||||||
|
|
||||||
private static Class<?> craftEntityClass = Reflection.getClass("org.bukkit.craftbukkit.entity.CraftEntity");
|
|
||||||
private static Reflection.Method getHandle = Reflection.getMethod(craftEntityClass, "getHandle");
|
|
||||||
|
|
||||||
private static Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5, Boolean.class);
|
|
||||||
private static Object fuseDataWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class);
|
|
||||||
|
|
||||||
public void continuousSendCache() {
|
|
||||||
if (task != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
createPackets();
|
|
||||||
task = new BukkitRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
_sendCache();
|
|
||||||
}
|
|
||||||
}.runTaskTimer(Core.getInstance(), 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendCache() {
|
|
||||||
if (task != null) {
|
|
||||||
task.cancel();
|
|
||||||
task = null;
|
|
||||||
}
|
|
||||||
_sendCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _sendCache() {
|
|
||||||
createPackets();
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
|
||||||
for (Object packet : packets) {
|
|
||||||
TinyProtocol.instance.sendPacket(player, packet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearCache() {
|
|
||||||
packets.clear();
|
|
||||||
entities.clear();
|
|
||||||
|
|
||||||
if (task != null) {
|
|
||||||
task.cancel();
|
|
||||||
task = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createPackets() {
|
|
||||||
if (entities.stream().anyMatch(Entity::isDead)) {
|
|
||||||
entities.clear();
|
|
||||||
packets.clear();
|
|
||||||
}
|
|
||||||
List<Entity> entities = Bukkit.getWorlds().get(0).getEntities().stream()
|
|
||||||
.filter(e -> !(e instanceof Player))
|
|
||||||
.filter(e -> PacketCache.entities.add(e))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
packets.add(teleportPacketConstructor.invoke(getHandle.invoke(entity)));
|
|
||||||
}
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
packets.add(velocityPacketConstructor.invoke(entity.getEntityId(), ZERO_VEC3D));
|
|
||||||
}
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), noGravityDataWatcher, true));
|
|
||||||
}
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
if (!(entity instanceof TNTPrimed)) continue;
|
|
||||||
TNTPrimed tnt = (TNTPrimed) entity;
|
|
||||||
int fuse = tnt.getFuseTicks();
|
|
||||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, fuse - (fuse % 5) + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils.tps;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class TPSFreezeUtils {
|
|
||||||
|
|
||||||
private static Reflection.Field<Boolean> fieldAccessor;
|
|
||||||
@Getter
|
|
||||||
private static final boolean canFreeze;
|
|
||||||
|
|
||||||
private static final Reflection.Method getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.CraftWorld"), "getHandle", null);
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private static boolean frozen = false;
|
|
||||||
|
|
||||||
private static final World world = Bukkit.getWorlds().get(0);
|
|
||||||
|
|
||||||
static {
|
|
||||||
Reflection.Field<Boolean> fieldAccessor;
|
|
||||||
try {
|
|
||||||
fieldAccessor = Reflection.getField(Reflection.getClass("net.minecraft.server.level.ServerLevel"), "freezed", boolean.class);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
fieldAccessor = null;
|
|
||||||
}
|
|
||||||
canFreeze = fieldAccessor != null;
|
|
||||||
TPSFreezeUtils.fieldAccessor = fieldAccessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void freeze() {
|
|
||||||
setFreeze(world, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unfreeze() {
|
|
||||||
setFreeze(world, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean frozen() {
|
|
||||||
return canFreeze && frozen;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setFreeze(World world, boolean state) {
|
|
||||||
if (canFreeze) {
|
|
||||||
fieldAccessor.set(getWorldHandle.invoke(world), state);
|
|
||||||
if (state) {
|
|
||||||
PacketCache.continuousSendCache();
|
|
||||||
} else {
|
|
||||||
PacketCache.clearCache();
|
|
||||||
}
|
|
||||||
frozen = state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils.tps;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class TPSLimitUtils {
|
|
||||||
|
|
||||||
private static long currentTime = System.nanoTime();
|
|
||||||
private static BukkitTask tpsLimiter = null;
|
|
||||||
private static Queue<Runnable> packetQueue = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
public void unlimit() {
|
|
||||||
if (tpsLimiter != null) tpsLimiter.cancel();
|
|
||||||
tpsLimiter = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void limit(double tps) {
|
|
||||||
if (tpsLimiter != null) tpsLimiter.cancel();
|
|
||||||
|
|
||||||
double delay = 20 / tps;
|
|
||||||
int loops = (int) Math.ceil(delay);
|
|
||||||
long sleepDelay = (long) (50 * delay) / loops;
|
|
||||||
|
|
||||||
tpsLimiter = Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> {
|
|
||||||
PacketCache.sendCache();
|
|
||||||
for (int i = 0; i < loops; i++) {
|
|
||||||
sleepUntilNextTick(sleepDelay);
|
|
||||||
PacketCache.sendCache();
|
|
||||||
while (true) {
|
|
||||||
Runnable runnable = packetQueue.poll();
|
|
||||||
if (runnable == null) break;
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PacketCache.clearCache();
|
|
||||||
}, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sleepUntilNextTick(long neededDelta) {
|
|
||||||
long lastTime = currentTime;
|
|
||||||
currentTime = System.nanoTime();
|
|
||||||
|
|
||||||
long timeDelta = (currentTime - lastTime) / 1000000;
|
|
||||||
if (neededDelta - timeDelta < 0) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(neededDelta - timeDelta);
|
|
||||||
currentTime = System.nanoTime();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static {
|
|
||||||
long timeInterval = 50;
|
|
||||||
final long[] lastTime = {System.currentTimeMillis()};
|
|
||||||
final double[] tps = {20.0};
|
|
||||||
Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> {
|
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
if (currentTime > lastTime[0]) {
|
|
||||||
tps[0] = (double)timeInterval / (double)(currentTime - lastTime[0]) * 20.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastTime[0] = currentTime;
|
|
||||||
|
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
|
||||||
SWUtils.sendToActionbar(player, String.valueOf((int) (tps[0] * 10.0) / 10.0));
|
|
||||||
});
|
|
||||||
}, timeInterval / 50L, timeInterval / 50L);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
private static final Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
|
||||||
private static final Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
|
||||||
static {
|
|
||||||
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
|
||||||
if (tpsLimiter != null) {
|
|
||||||
Object object = PlayerMovementWrapper.impl.convertToOut(player, o);
|
|
||||||
packetQueue.add(() -> {
|
|
||||||
PlayerMovementWrapper.impl.setPosition(player, o);
|
|
||||||
Bukkit.getOnlinePlayers().forEach(p -> {
|
|
||||||
if (p == player) return;
|
|
||||||
TinyProtocol.instance.sendPacket(p, object);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
};
|
|
||||||
TinyProtocol.instance.addFilter(position, positionSetter);
|
|
||||||
TinyProtocol.instance.addFilter(positionLook, positionSetter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.spigotapi)
|
|
||||||
compileOnly(libs.nms18)
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import net.minecraft.nbt.NBTBase;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.nbt.NBTTagList;
|
|
||||||
import net.minecraft.network.protocol.game.*;
|
|
||||||
import net.minecraft.server.level.PlayerInteractManager;
|
|
||||||
import net.minecraft.world.level.EnumGamemode;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NMSWrapper18 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(((CraftPlayer) player).getHandle().d, EnumGamemode.a(gameMode.getValue()));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.b();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.c()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, PacketPlayOutGameStateChange.d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
((CraftPlayer) player).getHandle().fs().d = true;
|
|
||||||
((CraftPlayer) player).getHandle().fs().e = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.DIRT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
|
|
||||||
NBTTagCompound tag = nmsItem.t();
|
|
||||||
if (tag != null && tag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = tag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
return drillDown(blockTag.c("Items", 10), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(NBTTagList items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (NBTBase nbtBase : items) {
|
|
||||||
if (!(nbtBase instanceof NBTTagCompound))
|
|
||||||
continue;
|
|
||||||
NBTTagCompound slot = (NBTTagCompound) nbtBase;
|
|
||||||
if (slot.e("tag")) {
|
|
||||||
invalid += slot.f("Count");
|
|
||||||
NBTTagCompound iTag = slot.p("tag");
|
|
||||||
if (iTag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = iTag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
invalid = drillDown(blockTag.c("Items", 10), layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalid > threshold)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
|
|
||||||
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
|
|
||||||
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
|
|
||||||
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
|
|
||||||
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
|
|
||||||
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
PacketPlayOutExplosion packetPlayOutExplosion = (PacketPlayOutExplosion) packet;
|
|
||||||
return new PacketPlayOutExplosion(a.get(packetPlayOutExplosion), b.get(packetPlayOutExplosion), c.get(packetPlayOutExplosion), d.get(packetPlayOutExplosion), e.get(packetPlayOutExplosion), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
|
||||||
import net.minecraft.server.level.EntityPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper18 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (packetPlayInFlying.h) {
|
|
||||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
|
||||||
} else {
|
|
||||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
Object packet = Reflection.newInstance(teleportPacket);
|
|
||||||
teleportEntity.set(packet, player.getEntityId());
|
|
||||||
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getYaw() : packetPlayInFlying.d,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getPitch() : packetPlayInFlying.e);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.spigotapi)
|
|
||||||
compileOnly(libs.paperapi)
|
|
||||||
|
|
||||||
compileOnly(libs.nms19)
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import net.minecraft.nbt.NBTBase;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.nbt.NBTTagList;
|
|
||||||
import net.minecraft.network.protocol.game.*;
|
|
||||||
import net.minecraft.server.level.PlayerInteractManager;
|
|
||||||
import net.minecraft.world.level.EnumGamemode;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NMSWrapper19 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(((CraftPlayer) player).getHandle().d, EnumGamemode.a(gameMode.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.b();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.c()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, PacketPlayOutGameStateChange.d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
((CraftPlayer) player).getHandle().fF().d = true;
|
|
||||||
((CraftPlayer) player).getHandle().fF().e = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.DIRT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
|
|
||||||
NBTTagCompound tag = nmsItem.v();
|
|
||||||
if (tag != null && tag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = tag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
return drillDown(blockTag.c("Items", 10), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(NBTTagList items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (NBTBase nbtBase : items) {
|
|
||||||
if (!(nbtBase instanceof NBTTagCompound))
|
|
||||||
continue;
|
|
||||||
NBTTagCompound slot = (NBTTagCompound) nbtBase;
|
|
||||||
if (slot.e("tag")) {
|
|
||||||
invalid += slot.f("Count");
|
|
||||||
NBTTagCompound iTag = slot.p("tag");
|
|
||||||
if (iTag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = iTag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
invalid = drillDown(blockTag.c("Items", 10), layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalid > threshold)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
|
|
||||||
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
|
|
||||||
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
|
|
||||||
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
|
|
||||||
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
|
|
||||||
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
PacketPlayOutExplosion packetPlayOutExplosion = (PacketPlayOutExplosion) packet;
|
|
||||||
return new PacketPlayOutExplosion(a.get(packetPlayOutExplosion), b.get(packetPlayOutExplosion), c.get(packetPlayOutExplosion), d.get(packetPlayOutExplosion), e.get(packetPlayOutExplosion), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
|
||||||
import net.minecraft.server.level.EntityPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper19 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (packetPlayInFlying.h) {
|
|
||||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
|
||||||
} else {
|
|
||||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
Object packet = Reflection.newInstance(teleportPacket);
|
|
||||||
teleportEntity.set(packet, player.getEntityId());
|
|
||||||
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getYaw() : packetPlayInFlying.d,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getPitch() : packetPlayInFlying.e);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import com.destroystokyo.paper.event.server.ServerTickEndEvent;
|
|
||||||
import com.destroystokyo.paper.event.server.ServerTickStartEvent;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
public class TickListener19 implements TickListener, Listener {
|
|
||||||
|
|
||||||
private boolean tickStartRan = false;
|
|
||||||
|
|
||||||
public TickListener19() {
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onServerTickStart(ServerTickStartEvent event) {
|
|
||||||
if (TickManager.impl.isFrozen()) return;
|
|
||||||
Bukkit.getPluginManager().callEvent(new TickStartEvent());
|
|
||||||
tickStartRan = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onServerTickEnd(ServerTickEndEvent event) {
|
|
||||||
if (!tickStartRan) return;
|
|
||||||
Bukkit.getPluginManager().callEvent(new TickEndEvent());
|
|
||||||
tickStartRan = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.spigotapi)
|
|
||||||
|
|
||||||
compileOnly(libs.nms20)
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import net.minecraft.nbt.NBTBase;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.nbt.NBTTagList;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInSetCreativeSlot;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayOutExplosion;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayOutGameStateChange;
|
|
||||||
import net.minecraft.server.level.PlayerInteractManager;
|
|
||||||
import net.minecraft.world.level.EnumGamemode;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NMSWrapper20 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(((CraftPlayer) player).getHandle().e, EnumGamemode.a(gameMode.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.a();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.c()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, PacketPlayOutGameStateChange.d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
((CraftPlayer) player).getHandle().fO().d = true;
|
|
||||||
((CraftPlayer) player).getHandle().fO().e = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.DIRT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
|
|
||||||
NBTTagCompound tag = nmsItem.v();
|
|
||||||
if (tag != null && tag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = tag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
return drillDown(blockTag.c("Items", 10), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(NBTTagList items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (NBTBase nbtBase : items) {
|
|
||||||
if (!(nbtBase instanceof NBTTagCompound))
|
|
||||||
continue;
|
|
||||||
NBTTagCompound slot = (NBTTagCompound) nbtBase;
|
|
||||||
if (slot.e("tag")) {
|
|
||||||
invalid += slot.f("Count");
|
|
||||||
NBTTagCompound iTag = slot.p("tag");
|
|
||||||
if (iTag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = iTag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
invalid = drillDown(blockTag.c("Items", 10), layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalid > threshold)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
|
|
||||||
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
|
|
||||||
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
|
|
||||||
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
|
|
||||||
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
|
|
||||||
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
PacketPlayOutExplosion packetPlayOutExplosion = (PacketPlayOutExplosion) packet;
|
|
||||||
return new PacketPlayOutExplosion(a.get(packetPlayOutExplosion), b.get(packetPlayOutExplosion), c.get(packetPlayOutExplosion), d.get(packetPlayOutExplosion), e.get(packetPlayOutExplosion), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
|
|
||||||
public class PlaceItemWrapper20 implements PlaceItemWrapper {
|
|
||||||
|
|
||||||
public PlaceItemWrapper20() {
|
|
||||||
for (Material material : Material.values()) {
|
|
||||||
if (!material.isBlock()) continue;
|
|
||||||
if (material.isLegacy()) continue;
|
|
||||||
BlockData blockData = material.createBlockData();
|
|
||||||
Material placementMaterial = blockData.getPlacementMaterial();
|
|
||||||
if (material == placementMaterial) continue;
|
|
||||||
if (placementMaterial == Material.AIR) continue;
|
|
||||||
if (placementMaterial.isItem() && !placementMaterial.isBlock()) {
|
|
||||||
ITEM_MATERIAL_TO_BLOCK_MATERIAL.put(placementMaterial, material);
|
|
||||||
}
|
|
||||||
if (material.name().contains("WALL")) {
|
|
||||||
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(placementMaterial, material);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
|
||||||
import net.minecraft.server.level.EntityPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper20 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (packetPlayInFlying.h) {
|
|
||||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
|
||||||
} else {
|
|
||||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
Object packet = Reflection.newInstance(teleportPacket);
|
|
||||||
teleportEntity.set(packet, player.getEntityId());
|
|
||||||
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getYaw() : packetPlayInFlying.d,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getPitch() : packetPlayInFlying.e);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_21
|
|
||||||
targetCompatibility = JavaVersion.VERSION_21
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.paperapi21)
|
|
||||||
|
|
||||||
compileOnly(libs.nms21)
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import io.papermc.paper.datacomponent.DataComponentTypes;
|
|
||||||
import io.papermc.paper.datacomponent.item.ItemContainerContents;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.server.level.ServerPlayerGameMode;
|
|
||||||
import net.minecraft.world.entity.player.Abilities;
|
|
||||||
import net.minecraft.world.level.GameType;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class NMSWrapper21 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<ServerPlayerGameMode> playerInteractManager = Reflection.getField(ServerPlayer.class, null, ServerPlayerGameMode.class);
|
|
||||||
private static final Reflection.Field<GameType> playerGameMode = Reflection.getField(ServerPlayerGameMode.class, GameType.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(playerInteractManager.get(((CraftPlayer) player).getHandle()), GameType.byId(gameMode.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
ClientboundContainerSetSlotPacket packetPlayInSetCreativeSlot = (ClientboundContainerSetSlotPacket) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.getSlot();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.getItem()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<ClientboundGameEventPacket.Type> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, ClientboundGameEventPacket.Type.class, 14);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, ClientboundGameEventPacket.CHANGE_GAME_MODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
Abilities abilities = (((CraftPlayer) player).getHandle()).getAbilities();
|
|
||||||
abilities.mayBuild = true;
|
|
||||||
abilities.mayfly = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.DIRT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER);
|
|
||||||
if (data == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return drillDown(data.contents(), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(List<ItemStack> items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (int i = start; i < items.size(); i++) {
|
|
||||||
ItemStack item = items.get(i);
|
|
||||||
if (item.isEmpty()) continue;
|
|
||||||
|
|
||||||
invalid += item.getAmount();
|
|
||||||
|
|
||||||
ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER);
|
|
||||||
if (data == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ItemStack> subItems = data.contents();
|
|
||||||
if (subItems.size() > 1) {
|
|
||||||
invalid = drillDown(subItems, layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
ClientboundExplodePacket explosion = (ClientboundExplodePacket) packet;
|
|
||||||
|
|
||||||
return new ClientboundExplodePacket(
|
|
||||||
explosion.center(),
|
|
||||||
Optional.empty(),
|
|
||||||
explosion.explosionParticle(),
|
|
||||||
explosion.explosionSound()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper21 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
ServerboundMovePlayerPacket packetPlayInFlying = ((ServerboundMovePlayerPacket) object);
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (packetPlayInFlying.hasPos) {
|
|
||||||
serverPlayer.setPosRaw(packetPlayInFlying.x, packetPlayInFlying.y, packetPlayInFlying.z);
|
|
||||||
}
|
|
||||||
if (packetPlayInFlying.hasRot) {
|
|
||||||
serverPlayer.setXRot(packetPlayInFlying.xRot);
|
|
||||||
serverPlayer.setYRot(packetPlayInFlying.yRot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundTickingStatePacket;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.ServerTickRateManager;
|
|
||||||
import net.minecraft.world.TickRateManager;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class TickManager21 implements TickManager {
|
|
||||||
private static final ServerTickRateManager manager = MinecraftServer.getServer().tickRateManager();
|
|
||||||
private static final Reflection.Field<Integer> frozenTicksToRun = Reflection.getField(TickRateManager.class, int.class, 0);
|
|
||||||
private static final Reflection.Field<Long> remainingSprintTicks = Reflection.getField(ServerTickRateManager.class, long.class, 0);
|
|
||||||
|
|
||||||
private boolean blockTpsPacket = true;
|
|
||||||
private int totalSteps;
|
|
||||||
|
|
||||||
public TickManager21() {
|
|
||||||
TinyProtocol.instance.addFilter(ClientboundTickingStatePacket.class, this::blockPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object blockPacket(Player player, Object packet) {
|
|
||||||
if (blockTpsPacket) {
|
|
||||||
return new ClientboundTickingStatePacket(20, manager.isFrozen());
|
|
||||||
} else {
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFreeze() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlockTpsPacket(boolean block) {
|
|
||||||
blockTpsPacket = block;
|
|
||||||
if (blockTpsPacket) {
|
|
||||||
ClientboundTickingStatePacket packet = new ClientboundTickingStatePacket(20, manager.isFrozen());
|
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
|
|
||||||
} else {
|
|
||||||
ClientboundTickingStatePacket packet = new ClientboundTickingStatePacket(manager.tickrate(), manager.isFrozen());
|
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTickRate(float tickRate) {
|
|
||||||
if (isFrozen()) {
|
|
||||||
setFreeze(false);
|
|
||||||
}
|
|
||||||
manager.setTickRate(tickRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFrozen() {
|
|
||||||
return manager.isFrozen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFreeze(boolean freeze) {
|
|
||||||
manager.setFrozen(freeze);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stepTicks(int ticks) {
|
|
||||||
if (manager.isSprinting()) {
|
|
||||||
manager.stopSprinting();
|
|
||||||
} else if (manager.isSteppingForward()) {
|
|
||||||
manager.stopStepping();
|
|
||||||
}
|
|
||||||
this.totalSteps = ticks;
|
|
||||||
manager.setFrozen(true);
|
|
||||||
manager.stepGameIfPaused(ticks);
|
|
||||||
manager.setFrozen(false);
|
|
||||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), (bukkitTask) -> {
|
|
||||||
if (manager.isSteppingForward()) return;
|
|
||||||
manager.setFrozen(true);
|
|
||||||
bukkitTask.cancel();
|
|
||||||
}, 1, 1);
|
|
||||||
manager.tick();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sprintTicks(int ticks) {
|
|
||||||
if (manager.isSteppingForward()) {
|
|
||||||
manager.stopStepping();
|
|
||||||
} else if (manager.isSprinting()) {
|
|
||||||
manager.stopSprinting();
|
|
||||||
}
|
|
||||||
this.totalSteps = ticks;
|
|
||||||
manager.requestGameToSprint(ticks, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSprinting() {
|
|
||||||
return manager.isSprinting();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isStepping() {
|
|
||||||
return manager.isSteppingForward();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getTickRate() {
|
|
||||||
return manager.tickrate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getRemainingTicks() {
|
|
||||||
if (isSprinting()) {
|
|
||||||
return remainingSprintTicks.get(manager);
|
|
||||||
} else {
|
|
||||||
return frozenTicksToRun.get(manager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDoneTicks() {
|
|
||||||
return totalSteps - getRemainingTicks();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalTicks() {
|
|
||||||
return totalSteps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,8 +26,8 @@ tasks.compileJava {
|
|||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -35,10 +35,12 @@ dependencies {
|
|||||||
annotationProcessor(libs.classindex)
|
annotationProcessor(libs.classindex)
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
compileOnly(project(":SpigotCore", "default"))
|
||||||
|
|
||||||
compileOnly(libs.spigotapi)
|
|
||||||
compileOnly(libs.axiom)
|
compileOnly(libs.axiom)
|
||||||
compileOnly(libs.authlib)
|
compileOnly(libs.authlib)
|
||||||
|
|
||||||
|
compileOnly(libs.paperapi21)
|
||||||
|
compileOnly(libs.nms21)
|
||||||
|
|
||||||
compileOnly(libs.fawe18)
|
compileOnly(libs.fawe18)
|
||||||
|
|
||||||
implementation(libs.luaj)
|
implementation(libs.luaj)
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ FLAG_ITEMS=Items
|
|||||||
FLAG_NO_GRAVITY = No Gravity
|
FLAG_NO_GRAVITY = No Gravity
|
||||||
FLAG_TESTBLOCK=Testblock
|
FLAG_TESTBLOCK=Testblock
|
||||||
FLAG_CHANGED=Changed
|
FLAG_CHANGED=Changed
|
||||||
|
FLAG_WATER_DESTROY=Water Destroy
|
||||||
|
FLAG_WATER_DESTROY_ALLOW=§coff
|
||||||
|
FLAG_WATER_DESTROY_DENY=§aon
|
||||||
FLAG_FIRE_ALLOW=§con
|
FLAG_FIRE_ALLOW=§con
|
||||||
FLAG_FIRE_DENY=§aoff
|
FLAG_FIRE_DENY=§aoff
|
||||||
FLAG_FREEZE_ACTIVE=§aon
|
FLAG_FREEZE_ACTIVE=§aon
|
||||||
@@ -140,6 +143,7 @@ BAU_INFO_ITEM_LORE_ITEMS=§7Items§8: §e{0}
|
|||||||
BAU_INFO_ITEM_LORE_NO_GRAVITY = §7NoGravity§8: §e{0}
|
BAU_INFO_ITEM_LORE_NO_GRAVITY = §7NoGravity§8: §e{0}
|
||||||
BAU_INFO_ITEM_LORE_TESTBLOCK=§7Testblock§8: §e{0}
|
BAU_INFO_ITEM_LORE_TESTBLOCK=§7Testblock§8: §e{0}
|
||||||
BAU_INFO_ITEM_LORE_CHANGED=§7Changed§8: §e{0}
|
BAU_INFO_ITEM_LORE_CHANGED=§7Changed§8: §e{0}
|
||||||
|
BAU_INFO_ITEM_LORE_WATER_DESTROY=§7Water Destroy§8: §e{0}
|
||||||
BAU_INFO_COMMAND_HELP=§8/§ebauinfo §8- §7Information regarding this build server
|
BAU_INFO_COMMAND_HELP=§8/§ebauinfo §8- §7Information regarding this build server
|
||||||
BAU_INFO_COMMAND_OWNER=§7Owner§8: §e{0}
|
BAU_INFO_COMMAND_OWNER=§7Owner§8: §e{0}
|
||||||
BAU_INFO_COMMAND_MEMBER=§7{0} §8[§7{1}§8]§8: §e{2}
|
BAU_INFO_COMMAND_MEMBER=§7{0} §8[§7{1}§8]§8: §e{2}
|
||||||
@@ -756,6 +760,9 @@ REGION_FIRE_DISABLED=§aFire damage activated in this region
|
|||||||
REGION_FREEZE_HELP=§8/§efreeze §8- §7Toggle Freeze
|
REGION_FREEZE_HELP=§8/§efreeze §8- §7Toggle Freeze
|
||||||
REGION_FREEZE_ENABLED=§cRegion frozen
|
REGION_FREEZE_ENABLED=§cRegion frozen
|
||||||
REGION_FREEZE_DISABLED=§aRegion thawed
|
REGION_FREEZE_DISABLED=§aRegion thawed
|
||||||
|
REGION_WATER_HELP=§8/§ewaterdestroy §8- §7Toggle water damage
|
||||||
|
REGION_WATER_ENABLED=§aWater damage deactivated in this region
|
||||||
|
REGION_WATER_DISABLED=§cWater damage activated in this region
|
||||||
REGION_ITEMS_HELP=§8/§eitems §8- §7Toggle Items
|
REGION_ITEMS_HELP=§8/§eitems §8- §7Toggle Items
|
||||||
REGION_ITEMS_ENABLED=§aItems enabled in this region
|
REGION_ITEMS_ENABLED=§aItems enabled in this region
|
||||||
REGION_ITEMS_DISABLED=§cItems disabled in this region
|
REGION_ITEMS_DISABLED=§cItems disabled in this region
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ FLAG_FREEZE_ACTIVE=§aan
|
|||||||
FLAG_FREEZE_INACTIVE=§caus
|
FLAG_FREEZE_INACTIVE=§caus
|
||||||
FLAG_PROTECT_ACTIVE=§aan
|
FLAG_PROTECT_ACTIVE=§aan
|
||||||
FLAG_PROTECT_INACTIVE=§caus
|
FLAG_PROTECT_INACTIVE=§caus
|
||||||
|
FLAG_WATER_DESTROY=Wasserschaden
|
||||||
|
FLAG_WATER_DESTROY_ALLOW=§cerlaubt
|
||||||
|
FLAG_WATER_DESTROY_DENY=§aaus
|
||||||
FLAG_TNT_ALLOW=§aan
|
FLAG_TNT_ALLOW=§aan
|
||||||
FLAG_TNT_DENY=§caus
|
FLAG_TNT_DENY=§caus
|
||||||
FLAG_TNT_ONLY_TB=§7Kein §eBaurahmen
|
FLAG_TNT_ONLY_TB=§7Kein §eBaurahmen
|
||||||
@@ -122,6 +125,7 @@ BAU_INFO_ITEM_NAME=§eBau-Management
|
|||||||
BAU_INFO_ITEM_LORE_FIRE=§7Feuer§8: §e{0}
|
BAU_INFO_ITEM_LORE_FIRE=§7Feuer§8: §e{0}
|
||||||
BAU_INFO_ITEM_LORE_COLOR=§7Farbe§8: §e{0}
|
BAU_INFO_ITEM_LORE_COLOR=§7Farbe§8: §e{0}
|
||||||
BAU_INFO_ITEM_LORE_CHANGED=§7Verändert§8: §e{0}
|
BAU_INFO_ITEM_LORE_CHANGED=§7Verändert§8: §e{0}
|
||||||
|
BAU_INFO_ITEM_LORE_WATER_DESTROY=§7Wasserschaden§8: §e{0}
|
||||||
BAU_INFO_COMMAND_HELP=§8/§ebauinfo §8- §7Gibt Informationen über den Bau
|
BAU_INFO_COMMAND_HELP=§8/§ebauinfo §8- §7Gibt Informationen über den Bau
|
||||||
BAU_INFO_COMMAND_OWNER=§7Besitzer§8: §e{0}
|
BAU_INFO_COMMAND_OWNER=§7Besitzer§8: §e{0}
|
||||||
BAU_INFO_COMMAND_MEMBER=§7{0} §8[§7{1}§8]§8: §e{2}
|
BAU_INFO_COMMAND_MEMBER=§7{0} §8[§7{1}§8]§8: §e{2}
|
||||||
@@ -704,6 +708,9 @@ REGION_PROTECT_FALSE_REGION=§cDu befindest dich derzeit in keiner (M)WG-Region
|
|||||||
REGION_NO_GRAVITY_HELP = §8/§enogravity §8- §7Toggle NoGravity
|
REGION_NO_GRAVITY_HELP = §8/§enogravity §8- §7Toggle NoGravity
|
||||||
REGION_NO_GRAVITY_ENABLED = §aNoGravity aktiviert in dieser Region
|
REGION_NO_GRAVITY_ENABLED = §aNoGravity aktiviert in dieser Region
|
||||||
REGION_NO_GRAVITY_DISABLED = §cNoGravity deaktiviert in dieser Region
|
REGION_NO_GRAVITY_DISABLED = §cNoGravity deaktiviert in dieser Region
|
||||||
|
REGION_WATER_HELP=§8/§ewaterblock §8- §7Wasserschaden umschalten
|
||||||
|
REGION_WATER_ENABLED=§aWasserschaden deaktiviert
|
||||||
|
REGION_WATER_DISABLED=§cWasserschaden aktiviert
|
||||||
REGION_REGION_HELP_UNDO=§8/§eregion undo §8- §7Mache die letzten 20 /testblock oder /reset rückgängig
|
REGION_REGION_HELP_UNDO=§8/§eregion undo §8- §7Mache die letzten 20 /testblock oder /reset rückgängig
|
||||||
REGION_REGION_HELP_REDO=§8/§eregion redo §8- §7Wiederhole die letzten 20 §8/§7rg undo
|
REGION_REGION_HELP_REDO=§8/§eregion redo §8- §7Wiederhole die letzten 20 §8/§7rg undo
|
||||||
REGION_REGION_HELP_RESTORE=§8/§eregion restore §8- §7Setzte die Region zurück, ohne das Gebaute zu löschen
|
REGION_REGION_HELP_RESTORE=§8/§eregion restore §8- §7Setzte die Region zurück, ohne das Gebaute zu löschen
|
||||||
|
|||||||
@@ -34,16 +34,18 @@ import de.steamwar.bausystem.features.world.BauScoreboard;
|
|||||||
import de.steamwar.bausystem.linkage.BauGuiItem;
|
import de.steamwar.bausystem.linkage.BauGuiItem;
|
||||||
import de.steamwar.bausystem.region.RegionSystem;
|
import de.steamwar.bausystem.region.RegionSystem;
|
||||||
import de.steamwar.bausystem.utils.ScoreboardElement;
|
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||||
import de.steamwar.bausystem.utils.TickListener;
|
|
||||||
import de.steamwar.bausystem.utils.TickManager;
|
import de.steamwar.bausystem.utils.TickManager;
|
||||||
import de.steamwar.bausystem.worlddata.WorldData;
|
import de.steamwar.bausystem.worlddata.WorldData;
|
||||||
import de.steamwar.command.AbstractValidator;
|
import de.steamwar.command.AbstractValidator;
|
||||||
import de.steamwar.command.SWCommandUtils;
|
import de.steamwar.command.SWCommandUtils;
|
||||||
import de.steamwar.core.CRIUSleepEvent;
|
import de.steamwar.core.CRIUSleepEvent;
|
||||||
|
import de.steamwar.core.Core;
|
||||||
import de.steamwar.core.WorldEditRendererCUIEditor;
|
import de.steamwar.core.WorldEditRendererCUIEditor;
|
||||||
|
import de.steamwar.core.WorldIdentifier;
|
||||||
import de.steamwar.linkage.AbstractLinker;
|
import de.steamwar.linkage.AbstractLinker;
|
||||||
import de.steamwar.linkage.SpigotLinker;
|
import de.steamwar.linkage.SpigotLinker;
|
||||||
import de.steamwar.message.Message;
|
import de.steamwar.message.Message;
|
||||||
|
import de.steamwar.providers.BauServerInfo;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameRule;
|
import org.bukkit.GameRule;
|
||||||
@@ -121,16 +123,18 @@ public class BauSystem extends JavaPlugin implements Listener {
|
|||||||
} catch (AbstractLinker.LinkException e) {
|
} catch (AbstractLinker.LinkException e) {
|
||||||
getLogger().log(Level.SEVERE, "Could not link a class.", e);
|
getLogger().log(Level.SEVERE, "Could not link a class.", e);
|
||||||
Bukkit.shutdown();
|
Bukkit.shutdown();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TickListener.impl.init();
|
|
||||||
|
|
||||||
TraceManager.instance.init();
|
TraceManager.instance.init();
|
||||||
TraceRecorder.instance.init();
|
TraceRecorder.instance.init();
|
||||||
|
|
||||||
new WorldEditRendererCUIEditor();
|
new WorldEditRendererCUIEditor();
|
||||||
|
|
||||||
Bukkit.getWorlds().get(0).setGameRule(GameRule.SEND_COMMAND_FEEDBACK, false);
|
Bukkit.getWorlds().get(0).setGameRule(GameRule.SEND_COMMAND_FEEDBACK, false);
|
||||||
|
|
||||||
|
String identifier = BauServerInfo.getOwnerUser().getUUID().toString().replace("-", "");
|
||||||
|
WorldIdentifier.set("bau/" + Core.getVersion() + "/" + identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
+5
-9
@@ -31,10 +31,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class DesignEndStone {
|
public class DesignEndStone {
|
||||||
@@ -56,11 +53,10 @@ public class DesignEndStone {
|
|||||||
this.maxY = region.getBuildArea().getMaxPoint(false).getY();
|
this.maxY = region.getBuildArea().getMaxPoint(false).getY();
|
||||||
this.maxZ = region.getBuildArea().getMaxPoint(false).getZ();
|
this.maxZ = region.getBuildArea().getMaxPoint(false).getZ();
|
||||||
|
|
||||||
limited = region.getGameModeConfig().Schematic.Limited
|
limited = Arrays.stream(Material.values())
|
||||||
.entrySet()
|
.filter(Material::isBlock)
|
||||||
.stream()
|
.filter(material -> !material.isLegacy())
|
||||||
.filter(entry -> entry.getValue() == 0)
|
.filter(material -> material.getBlastResistance() > region.getGameModeConfig().Schematic.MaxDesignBlastResistance)
|
||||||
.flatMap(entry -> entry.getKey().stream())
|
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
calculateFromBottom = region.getGameModeConfig().Arena.NoFloor;
|
calculateFromBottom = region.getGameModeConfig().Arena.NoFloor;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2026 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.features.dev;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.command.SWCommand;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Linked
|
||||||
|
public class CreateKitCommand extends SWCommand {
|
||||||
|
|
||||||
|
public CreateKitCommand() {
|
||||||
|
super("createkit");
|
||||||
|
if (!BauSystem.DEV_SERVER) unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register
|
||||||
|
public void onCommand(Player player, String name) {
|
||||||
|
YamlConfiguration yaml = new YamlConfiguration();
|
||||||
|
|
||||||
|
yaml.set("Items", player.getInventory().getContents());
|
||||||
|
yaml.set("Armor", player.getInventory().getArmorContents());
|
||||||
|
yaml.set("Effects", player.getActivePotionEffects());
|
||||||
|
yaml.set("LeaderAllowed", true);
|
||||||
|
yaml.set("MemberAllowed", true);
|
||||||
|
yaml.set("EnterStage", 0);
|
||||||
|
yaml.set("TNT", true);
|
||||||
|
|
||||||
|
YamlConfiguration kits = new YamlConfiguration();
|
||||||
|
|
||||||
|
kits.set("Kits." + name, yaml);
|
||||||
|
|
||||||
|
try {
|
||||||
|
kits.save(new File("new.kits.yaml"));
|
||||||
|
|
||||||
|
player.sendMessage("Kit created!");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-4
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.observer;
|
package de.steamwar.bausystem.features.observer;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.region.Point;
|
import de.steamwar.bausystem.region.Point;
|
||||||
import de.steamwar.core.SWPlayer;
|
import de.steamwar.core.SWPlayer;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -29,8 +28,9 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.data.Bisected;
|
import org.bukkit.block.data.Bisected;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.type.Observer;
|
|
||||||
import org.bukkit.block.data.type.*;
|
import org.bukkit.block.data.type.*;
|
||||||
|
import org.bukkit.block.data.type.Observer;
|
||||||
|
import org.bukkit.craftbukkit.block.impl.CraftPoweredRail;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -171,7 +171,6 @@ public class ObserverTracer implements SWPlayer.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> craftPoweredRail = Reflection.getClass("org.bukkit.craftbukkit.block.impl.CraftPoweredRail");
|
|
||||||
private boolean checkAllowed(Block block, BlockData blockData) {
|
private boolean checkAllowed(Block block, BlockData blockData) {
|
||||||
if (checkMaterial(block)) return true;
|
if (checkMaterial(block)) return true;
|
||||||
if (block.getType() == Material.BELL) {
|
if (block.getType() == Material.BELL) {
|
||||||
@@ -180,7 +179,7 @@ public class ObserverTracer implements SWPlayer.Component {
|
|||||||
|
|
||||||
return blockData instanceof Door
|
return blockData instanceof Door
|
||||||
|| blockData instanceof Gate
|
|| blockData instanceof Gate
|
||||||
|| craftPoweredRail.isInstance(blockData)
|
|| blockData instanceof CraftPoweredRail
|
||||||
|| blockData instanceof TrapDoor
|
|| blockData instanceof TrapDoor
|
||||||
|| blockData instanceof GlassPane;
|
|| blockData instanceof GlassPane;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -46,8 +46,8 @@ public class ObserverTracerListener implements Listener {
|
|||||||
public ObserverTracerListener() {
|
public ObserverTracerListener() {
|
||||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||||
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
|
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
|
||||||
if (pair.getKey().getGameMode() != GameMode.SPECTATOR) return;
|
if (pair.getPlayer().getGameMode() != GameMode.SPECTATOR) return;
|
||||||
pair.getValue().show();
|
pair.getComponent().show();
|
||||||
});
|
});
|
||||||
}, 15L, 15L);
|
}, 15L, 15L);
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ public class ObserverTracerListener implements Listener {
|
|||||||
createNew(event);
|
createNew(event);
|
||||||
}
|
}
|
||||||
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
|
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
|
||||||
pair.getValue().trace();
|
pair.getComponent().trace();
|
||||||
});
|
});
|
||||||
}, 1L);
|
}, 1L);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+10
@@ -46,6 +46,16 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
|||||||
@Linked
|
@Linked
|
||||||
public class FreezeListener implements Listener, ScoreboardElement {
|
public class FreezeListener implements Listener, ScoreboardElement {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockExplode(BlockExplodeEvent e) {
|
||||||
|
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return;
|
||||||
|
e.setCancelled(true);
|
||||||
|
BlockState state = e.getBlock().getState();
|
||||||
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
|
state.update(true, false);
|
||||||
|
}, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onEntitySpawn(EntitySpawnEvent e) {
|
public void onEntitySpawn(EntitySpawnEvent e) {
|
||||||
if (Region.getRegion(e.getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return;
|
if (Region.getRegion(e.getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return;
|
||||||
|
|||||||
@@ -67,11 +67,7 @@ public class TNTListener implements Listener, ScoreboardElement {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
public void onExplode(EntityExplodeEvent event) {
|
public void onExplode(EntityExplodeEvent event) {
|
||||||
if (!(event.getEntity() instanceof TNTPrimed)) {
|
explode(event.blockList(), event.getEntity() instanceof TNTPrimed);
|
||||||
event.blockList().clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
explode(event.blockList(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.features.region;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.region.Region;
|
||||||
|
import de.steamwar.bausystem.region.RegionUtils;
|
||||||
|
import de.steamwar.bausystem.region.flags.Flag;
|
||||||
|
import de.steamwar.bausystem.region.flags.WaterDestroyMode;
|
||||||
|
import de.steamwar.command.SWCommand;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
@Linked
|
||||||
|
public class WaterDestroyCommand extends SWCommand {
|
||||||
|
public WaterDestroyCommand() {
|
||||||
|
super("waterdestroy");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getEnableMessage(){
|
||||||
|
return "REGION_WATER_ENABLED";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDisableMessage(){
|
||||||
|
return "REGION_WATER_DISABLED";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register(description = "REGION_WATER_HELP")
|
||||||
|
public void toggleCommand(@Validator Player p) {
|
||||||
|
Region region = Region.getRegion(p.getLocation());
|
||||||
|
|
||||||
|
if (toggle(region)) {
|
||||||
|
RegionUtils.actionBar(region, getEnableMessage());
|
||||||
|
} else {
|
||||||
|
RegionUtils.actionBar(region, getDisableMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean toggle(Region region) {
|
||||||
|
if (region.getRegionData().get(Flag.WATER_DESTROY).isWithDefault(WaterDestroyMode.DENY)) {
|
||||||
|
region.getRegionData().set(Flag.WATER_DESTROY, WaterDestroyMode.ALLOW);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
region.getRegionData().set(Flag.WATER_DESTROY, WaterDestroyMode.DENY);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bausystem.features.region;
|
||||||
|
|
||||||
|
import de.steamwar.bausystem.BauSystem;
|
||||||
|
import de.steamwar.bausystem.region.Region;
|
||||||
|
import de.steamwar.bausystem.region.flags.Flag;
|
||||||
|
import de.steamwar.bausystem.region.flags.WaterDestroyMode;
|
||||||
|
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||||
|
import de.steamwar.linkage.Linked;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockFromToEvent;
|
||||||
|
|
||||||
|
@Linked
|
||||||
|
public class WaterDestroyListener implements Listener, ScoreboardElement {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockFromTo(BlockFromToEvent event) {
|
||||||
|
if (event.getBlock().getType() == Material.WATER && event.getToBlock().getType() != Material.AIR && Region.getRegion(event.getBlock().getLocation()).getRegionData().get(Flag.WATER_DESTROY).isWithDefault(WaterDestroyMode.DENY)) event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScoreboardGroup getGroup() {
|
||||||
|
return ScoreboardGroup.REGION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int order() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get(Region region, Player p) {
|
||||||
|
if (region.getRegionData().get(Flag.WATER_DESTROY).isWithDefault(WaterDestroyMode.ALLOW)) return null;
|
||||||
|
return "§e" + BauSystem.MESSAGE.parse(Flag.WATER_DESTROY.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.WATER_DESTROY).getWithDefault().getChatValue(), p);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -51,8 +51,8 @@ public class EventListener implements Listener {
|
|||||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
||||||
long millis = System.currentTimeMillis();
|
long millis = System.currentTimeMillis();
|
||||||
SWPlayer.allWithSingleComponent(ScriptRunner.ScriptData.class)
|
SWPlayer.allWithSingleComponent(ScriptRunner.ScriptData.class)
|
||||||
.filter(pair -> millis - pair.getValue().getLastF() > 200)
|
.filter(pair -> millis - pair.getComponent().getLastF() > 200)
|
||||||
.forEach(pair -> pair.getValue().setLastF(Long.MAX_VALUE));
|
.forEach(pair -> pair.getComponent().setLastF(Long.MAX_VALUE));
|
||||||
}, 1, 1);
|
}, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-7
@@ -20,7 +20,6 @@
|
|||||||
package de.steamwar.bausystem.features.simulator;
|
package de.steamwar.bausystem.features.simulator;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.SWUtils;
|
import de.steamwar.bausystem.SWUtils;
|
||||||
@@ -48,6 +47,7 @@ import de.steamwar.linkage.Linked;
|
|||||||
import de.steamwar.linkage.MinVersion;
|
import de.steamwar.linkage.MinVersion;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -72,9 +72,6 @@ import java.util.stream.Collectors;
|
|||||||
public class SimulatorCursor implements Listener {
|
public class SimulatorCursor implements Listener {
|
||||||
|
|
||||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
private static final World WORLD = Bukkit.getWorlds().get(0);
|
||||||
private Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
|
||||||
private Class<?> look = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Rot");
|
|
||||||
private Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
|
||||||
|
|
||||||
private static Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
|
private static Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
|
||||||
private static Map<Player, REntityServer> cursors = Collections.synchronizedMap(new HashMap<>());
|
private static Map<Player, REntityServer> cursors = Collections.synchronizedMap(new HashMap<>());
|
||||||
@@ -89,9 +86,9 @@ public class SimulatorCursor implements Listener {
|
|||||||
calcCursor(player);
|
calcCursor(player);
|
||||||
return object;
|
return object;
|
||||||
};
|
};
|
||||||
TinyProtocol.instance.addFilter(position, function);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, function);
|
||||||
TinyProtocol.instance.addFilter(look, function);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Rot.class, function);
|
||||||
TinyProtocol.instance.addFilter(positionLook, function);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
+13
-4
@@ -19,14 +19,15 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.simulator.execute;
|
package de.steamwar.bausystem.features.simulator.execute;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.event.server.ServerTickEndEvent;
|
||||||
|
import com.destroystokyo.paper.event.server.ServerTickStartEvent;
|
||||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||||
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
|
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
|
||||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.utils.TickEndEvent;
|
import de.steamwar.bausystem.utils.TickManager;
|
||||||
import de.steamwar.bausystem.utils.TickStartEvent;
|
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
import de.steamwar.linkage.MinVersion;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -109,8 +110,13 @@ public class SimulatorExecutor implements Listener {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean tickStartRan = false;
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onTickStart(TickStartEvent event) {
|
public void onServerTickStart(ServerTickStartEvent event) {
|
||||||
|
if (TickManager.impl.isFrozen()) return;
|
||||||
|
tickStartRan = true;
|
||||||
|
|
||||||
long currentTick = TPSUtils.currentRealTick.get();
|
long currentTick = TPSUtils.currentRealTick.get();
|
||||||
Map<Integer, List<SimulatorAction>> actionsToRun = tickStartActions.remove(currentTick);
|
Map<Integer, List<SimulatorAction>> actionsToRun = tickStartActions.remove(currentTick);
|
||||||
if (actionsToRun == null) return;
|
if (actionsToRun == null) return;
|
||||||
@@ -123,7 +129,10 @@ public class SimulatorExecutor implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onTickEnd(TickEndEvent event) {
|
public void onServerTickEnd(ServerTickEndEvent event) {
|
||||||
|
if (!tickStartRan) return;
|
||||||
|
tickStartRan = false;
|
||||||
|
|
||||||
long currentTick = TPSUtils.currentRealTick.get() - 1;
|
long currentTick = TPSUtils.currentRealTick.get() - 1;
|
||||||
List<SimulatorAction> actionsToRun = tickEndActions.remove(currentTick);
|
List<SimulatorAction> actionsToRun = tickEndActions.remove(currentTick);
|
||||||
if (actionsToRun == null) return;
|
if (actionsToRun == null) return;
|
||||||
|
|||||||
+2
@@ -150,11 +150,13 @@ public class SimulatorObserverGui extends SimulatorScrollGui<ObserverPhase> {
|
|||||||
Consumer<Integer> setter = observerPhase::setTickOffset;
|
Consumer<Integer> setter = observerPhase::setTickOffset;
|
||||||
return new SWItem[] {
|
return new SWItem[] {
|
||||||
new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1)));
|
setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
||||||
observer,
|
observer,
|
||||||
new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1)));
|
setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
||||||
|
|||||||
+5
@@ -32,6 +32,7 @@ import de.steamwar.inventory.SWItem;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -97,6 +98,7 @@ public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
//Tick Offset
|
//Tick Offset
|
||||||
int offset = observer.getTickOffset();
|
int offset = observer.getTickOffset();
|
||||||
inventory.setItem(10, new SWItem(SWItem.getDye(offset < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(10, new SWItem(SWItem.getDye(offset < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.setTickOffset(Math.min(max, offset + (clickType.isShiftClick() ? 5 : 1)));
|
observer.setTickOffset(Math.min(max, offset + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -113,6 +115,7 @@ public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
inventory.setItem(19, offsetItem);
|
inventory.setItem(19, offsetItem);
|
||||||
|
|
||||||
inventory.setItem(28, new SWItem(SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(28, new SWItem(SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
|
observer.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
@@ -120,6 +123,7 @@ public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
//Order
|
//Order
|
||||||
int order = observer.getOrder();
|
int order = observer.getOrder();
|
||||||
inventory.setItem(13, new SWItem(SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(13, new SWItem(SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
observer.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -138,6 +142,7 @@ public class SimulatorObserverPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
inventory.setItem(22, orderItem);
|
inventory.setItem(22, orderItem);
|
||||||
|
|
||||||
inventory.setItem(31, new SWItem(SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(31, new SWItem(SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
observer.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|||||||
+9
@@ -28,6 +28,7 @@ import de.steamwar.data.CMDs;
|
|||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
// Base Tick
|
// Base Tick
|
||||||
int baseTicks = observer.getBaseTick();
|
int baseTicks = observer.getBaseTick();
|
||||||
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
observer.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -81,6 +83,7 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
||||||
inventory.setItem(18, baseTick);
|
inventory.setItem(18, baseTick);
|
||||||
inventory.setItem(27, new SWItem(SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(27, new SWItem(SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
||||||
observer.changeBaseTicks(-baseTicks);
|
observer.changeBaseTicks(-baseTicks);
|
||||||
} else {
|
} else {
|
||||||
@@ -91,6 +94,7 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
//Pos X
|
//Pos X
|
||||||
inventory.setItem(15, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(15, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(clickType.isShiftClick() ? 5 : 1, 0, 0);
|
observer.move(clickType.isShiftClick() ? 5 : 1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -102,12 +106,14 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(33, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(33, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(clickType.isShiftClick() ? -5 : -1, 0, 0);
|
observer.move(clickType.isShiftClick() ? -5 : -1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
//Pos Y
|
//Pos Y
|
||||||
inventory.setItem(16, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(16, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(0, clickType.isShiftClick() ? 5 : 1, 0);
|
observer.move(0, clickType.isShiftClick() ? 5 : 1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.ENABLED_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.ENABLED_OR_DISABLED));
|
||||||
@@ -119,12 +125,14 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(34, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(34, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(0, clickType.isShiftClick() ? -5 : -1, 0);
|
observer.move(0, clickType.isShiftClick() ? -5 : -1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
//Pos Z
|
//Pos Z
|
||||||
inventory.setItem(17, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(17, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(0, 0, clickType.isShiftClick() ? 5 : 1);
|
observer.move(0, 0, clickType.isShiftClick() ? 5 : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.ENABLED_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.ENABLED_OR_DISABLED));
|
||||||
@@ -136,6 +144,7 @@ public class SimulatorObserverSettingsGui extends SimulatorBaseGui {
|
|||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(35, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(35, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
observer.move(0, 0, clickType.isShiftClick() ? -5 : -1);
|
observer.move(0, 0, clickType.isShiftClick() ? -5 : -1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|||||||
+2
@@ -165,11 +165,13 @@ public class SimulatorRedstoneGui extends SimulatorScrollGui<SimulatorRedstoneGu
|
|||||||
Consumer<Integer> setter = redstoneSubPhase.place ? redstoneSubPhase.phase::setTickOffset : redstoneSubPhase.phase::setLifetime;
|
Consumer<Integer> setter = redstoneSubPhase.place ? redstoneSubPhase.phase::setTickOffset : redstoneSubPhase.phase::setLifetime;
|
||||||
return new SWItem[] {
|
return new SWItem[] {
|
||||||
new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
new SWItem(SWItem.getDye(getter.get() < max ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1)));
|
setter.accept(Math.min(max, getter.get() + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
||||||
redstone,
|
redstone,
|
||||||
new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
new SWItem(SWItem.getDye(getter.get() > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1)));
|
setter.accept(Math.max(min, getter.get() - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
||||||
|
|||||||
+7
@@ -31,6 +31,7 @@ import de.steamwar.data.CMDs;
|
|||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
//Tick Offset
|
//Tick Offset
|
||||||
int offset = redstone.getTickOffset();
|
int offset = redstone.getTickOffset();
|
||||||
inventory.setItem(10, new SWItem(SWItem.getDye(offset < maxOffset ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(10, new SWItem(SWItem.getDye(offset < maxOffset ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setTickOffset(Math.min(maxOffset, offset + (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setTickOffset(Math.min(maxOffset, offset + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -114,6 +116,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
inventory.setItem(19, offsetItem);
|
inventory.setItem(19, offsetItem);
|
||||||
|
|
||||||
inventory.setItem(28, new SWItem(SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(28, new SWItem(SWItem.getDye(offset > min ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setTickOffset(Math.max(min, offset - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
@@ -121,6 +124,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
//Lifetime
|
//Lifetime
|
||||||
int lifetime = redstone.getLifetime();
|
int lifetime = redstone.getLifetime();
|
||||||
inventory.setItem(11, new SWItem(SWItem.getDye(lifetime < maxLifetime ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(11, new SWItem(SWItem.getDye(lifetime < maxLifetime ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setLifetime(Math.min(maxLifetime, lifetime + (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setLifetime(Math.min(maxLifetime, lifetime + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -137,6 +141,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
inventory.setItem(20, lifetimeItem);
|
inventory.setItem(20, lifetimeItem);
|
||||||
|
|
||||||
inventory.setItem(29, new SWItem(SWItem.getDye(lifetime > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(29, new SWItem(SWItem.getDye(lifetime > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setLifetime(Math.max(0, lifetime - (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setLifetime(Math.max(0, lifetime - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
@@ -144,6 +149,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
//Order
|
//Order
|
||||||
int order = redstone.getOrder();
|
int order = redstone.getOrder();
|
||||||
inventory.setItem(13, new SWItem(SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(13, new SWItem(SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -162,6 +168,7 @@ public class SimulatorRedstonePhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
inventory.setItem(22, orderItem);
|
inventory.setItem(22, orderItem);
|
||||||
|
|
||||||
inventory.setItem(31, new SWItem(SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(31, new SWItem(SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
redstone.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|||||||
+9
@@ -28,6 +28,7 @@ import de.steamwar.data.CMDs;
|
|||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ public class SimulatorRedstoneSettingsGui extends SimulatorBaseGui {
|
|||||||
// Base Tick
|
// Base Tick
|
||||||
int baseTicks = redstone.getBaseTick();
|
int baseTicks = redstone.getBaseTick();
|
||||||
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
redstone.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -80,6 +82,7 @@ public class SimulatorRedstoneSettingsGui extends SimulatorBaseGui {
|
|||||||
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
||||||
inventory.setItem(18, baseTick);
|
inventory.setItem(18, baseTick);
|
||||||
inventory.setItem(27, new SWItem(SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(27, new SWItem(SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
||||||
redstone.changeBaseTicks(-baseTicks);
|
redstone.changeBaseTicks(-baseTicks);
|
||||||
} else {
|
} else {
|
||||||
@@ -90,6 +93,7 @@ public class SimulatorRedstoneSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
//Pos X
|
//Pos X
|
||||||
inventory.setItem(15, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(15, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.move(clickType.isShiftClick() ? 5 : 1, 0, 0);
|
redstone.move(clickType.isShiftClick() ? 5 : 1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -101,12 +105,14 @@ public class SimulatorRedstoneSettingsGui extends SimulatorBaseGui {
|
|||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(33, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(33, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.move(clickType.isShiftClick() ? -5 : -1, 0, 0);
|
redstone.move(clickType.isShiftClick() ? -5 : -1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
//Pos Y
|
//Pos Y
|
||||||
inventory.setItem(16, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(16, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.move(0, clickType.isShiftClick() ? 5 : 1, 0);
|
redstone.move(0, clickType.isShiftClick() ? 5 : 1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -118,12 +124,14 @@ public class SimulatorRedstoneSettingsGui extends SimulatorBaseGui {
|
|||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(34, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(34, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.move(0, clickType.isShiftClick() ? -5 : -1, 0);
|
redstone.move(0, clickType.isShiftClick() ? -5 : -1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
//Pos Z
|
//Pos Z
|
||||||
inventory.setItem(17, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(17, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.move(0, 0, clickType.isShiftClick() ? 5 : 1);
|
redstone.move(0, 0, clickType.isShiftClick() ? 5 : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -135,6 +143,7 @@ public class SimulatorRedstoneSettingsGui extends SimulatorBaseGui {
|
|||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(35, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(35, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
redstone.move(0, 0, clickType.isShiftClick() ? -5 : -1);
|
redstone.move(0, 0, clickType.isShiftClick() ? -5 : -1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|||||||
+2
@@ -138,11 +138,13 @@ public class SimulatorTNTGui extends SimulatorScrollGui<TNTPhase> {
|
|||||||
|
|
||||||
return new SWItem[]{
|
return new SWItem[]{
|
||||||
new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8:§e +5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tntSetting.setCount(tntSetting.getCount() + (clickType.isShiftClick() ? 5 : 1));
|
tntSetting.setCount(tntSetting.getCount() + (clickType.isShiftClick() ? 5 : 1));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED),
|
||||||
tnt,
|
tnt,
|
||||||
new SWItem(SWItem.getDye(tntSetting.getCount() > 1 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
new SWItem(SWItem.getDye(tntSetting.getCount() > 1 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8:§e -5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tntSetting.setCount(Math.max(1, tntSetting.getCount() - (clickType.isShiftClick() ? 5 : 1)));
|
tntSetting.setCount(Math.max(1, tntSetting.getCount() - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED),
|
||||||
|
|||||||
+13
@@ -31,6 +31,7 @@ import de.steamwar.data.CMDs;
|
|||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
//Count
|
//Count
|
||||||
int count = tnt.getCount();
|
int count = tnt.getCount();
|
||||||
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setCount(count + (clickType.isShiftClick() ? 5 : 1));
|
tnt.setCount(count + (clickType.isShiftClick() ? 5 : 1));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -94,6 +96,7 @@ public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
inventory.setItem(18, countItem);
|
inventory.setItem(18, countItem);
|
||||||
|
|
||||||
inventory.setItem(27, new SWItem(SWItem.getDye(count > 1 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(27, new SWItem(SWItem.getDye(count > 1 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setCount(Math.max(1, count - (clickType.isShiftClick() ? 5 : 1)));
|
tnt.setCount(Math.max(1, count - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
@@ -101,6 +104,7 @@ public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
//Tick Offset
|
//Tick Offset
|
||||||
int offset = tnt.getTickOffset();
|
int offset = tnt.getTickOffset();
|
||||||
inventory.setItem(10, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(10, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setTickOffset(offset + (clickType.isShiftClick() ? 5 : 1));
|
tnt.setTickOffset(offset + (clickType.isShiftClick() ? 5 : 1));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -117,6 +121,7 @@ public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
inventory.setItem(19, offsetItem);
|
inventory.setItem(19, offsetItem);
|
||||||
|
|
||||||
inventory.setItem(28, new SWItem(SWItem.getDye(offset > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(28, new SWItem(SWItem.getDye(offset > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setTickOffset(Math.max(0, offset - (clickType.isShiftClick() ? 5 : 1)));
|
tnt.setTickOffset(Math.max(0, offset - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
@@ -124,6 +129,7 @@ public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
//Lifetime
|
//Lifetime
|
||||||
int lifetime = tnt.getLifetime();
|
int lifetime = tnt.getLifetime();
|
||||||
inventory.setItem(11, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(11, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setLifetime(lifetime + (clickType.isShiftClick() ? 5 : 1));
|
tnt.setLifetime(lifetime + (clickType.isShiftClick() ? 5 : 1));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -140,6 +146,7 @@ public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
inventory.setItem(20, lifetimeItem);
|
inventory.setItem(20, lifetimeItem);
|
||||||
|
|
||||||
inventory.setItem(29, new SWItem(SWItem.getDye(lifetime > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(29, new SWItem(SWItem.getDye(lifetime > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setLifetime(Math.max(1, lifetime - (clickType.isShiftClick() ? 5 : 1)));
|
tnt.setLifetime(Math.max(1, lifetime - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
@@ -147,6 +154,7 @@ public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
//Order
|
//Order
|
||||||
int order = tnt.getOrder();
|
int order = tnt.getOrder();
|
||||||
inventory.setItem(13, new SWItem(SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(13, new SWItem(SWItem.getDye(order < SimulatorPhase.ORDER_LIMIT ? 10 : 8), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
tnt.setOrder(Math.min(SimulatorPhase.ORDER_LIMIT, order + (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -165,30 +173,35 @@ public class SimulatorTNTPhaseSettingsGui extends SimulatorBaseGui {
|
|||||||
inventory.setItem(22, orderItem);
|
inventory.setItem(22, orderItem);
|
||||||
|
|
||||||
inventory.setItem(31, new SWItem(SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(31, new SWItem(SWItem.getDye(order > -SimulatorPhase.ORDER_LIMIT ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
tnt.setOrder(Math.max(-SimulatorPhase.ORDER_LIMIT, order - (clickType.isShiftClick() ? 5 : 1)));
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
//Jump
|
//Jump
|
||||||
SWItem jumpX = new SWItem(tnt.isXJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump X§8: " + (tnt.isZJump() ? "§aon" : "§coff"), clickType -> {
|
SWItem jumpX = new SWItem(tnt.isXJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump X§8: " + (tnt.isZJump() ? "§aon" : "§coff"), clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setXJump(!tnt.isXJump());
|
tnt.setXJump(!tnt.isXJump());
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
});
|
});
|
||||||
inventory.setItem(33, jumpX);
|
inventory.setItem(33, jumpX);
|
||||||
|
|
||||||
SWItem jumpY = new SWItem(tnt.isYJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump Y§8: " + (tnt.isYJump() ? "§aon" : "§coff"), clickType -> {
|
SWItem jumpY = new SWItem(tnt.isYJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump Y§8: " + (tnt.isYJump() ? "§aon" : "§coff"), clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setYJump(!tnt.isYJump());
|
tnt.setYJump(!tnt.isYJump());
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
});
|
});
|
||||||
inventory.setItem(16, jumpY);
|
inventory.setItem(16, jumpY);
|
||||||
|
|
||||||
SWItem jumpZ = new SWItem(tnt.isZJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump Z§8: " + (tnt.isZJump() ? "§aon" : "§coff"), clickType -> {
|
SWItem jumpZ = new SWItem(tnt.isZJump() ? Material.LIME_WOOL : Material.RED_WOOL, "§7TNT §eJump Z§8: " + (tnt.isZJump() ? "§aon" : "§coff"), clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setZJump(!tnt.isZJump());
|
tnt.setZJump(!tnt.isZJump());
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
});
|
});
|
||||||
inventory.setItem(35, jumpZ);
|
inventory.setItem(35, jumpZ);
|
||||||
|
|
||||||
SWItem jumpAll = new SWItem(Material.TNT, "§7TNT §eJump §8: " + (tnt.hasJump() ? "§aon" : "§coff"), clickType -> {
|
SWItem jumpAll = new SWItem(Material.TNT, "§7TNT §eJump §8: " + (tnt.hasJump() ? "§aon" : "§coff"), clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.setJump(!tnt.hasJump());
|
tnt.setJump(!tnt.hasJump());
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
});
|
});
|
||||||
|
|||||||
+9
@@ -28,6 +28,7 @@ import de.steamwar.data.CMDs;
|
|||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -75,6 +76,7 @@ public class SimulatorTNTSettingsGui extends SimulatorBaseGui {
|
|||||||
// Base Tick
|
// Base Tick
|
||||||
int baseTicks = tnt.getBaseTick();
|
int baseTicks = tnt.getBaseTick();
|
||||||
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
inventory.setItem(9, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
tnt.changeBaseTicks(clickType.isShiftClick() ? 5 : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -89,6 +91,7 @@ public class SimulatorTNTSettingsGui extends SimulatorBaseGui {
|
|||||||
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
baseTick.getItemStack().setAmount(Math.max(1, Math.min(baseTicks, 64)));
|
||||||
inventory.setItem(18, baseTick);
|
inventory.setItem(18, baseTick);
|
||||||
inventory.setItem(27, new SWItem(SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
inventory.setItem(27, new SWItem(SWItem.getDye(baseTicks > 0 ? 1 : 8), "§e-1", Arrays.asList("§7Shift§8: §e-5"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
if (baseTicks - (clickType.isShiftClick() ? 5 : 1) < 0) {
|
||||||
tnt.changeBaseTicks(-baseTicks);
|
tnt.changeBaseTicks(-baseTicks);
|
||||||
} else {
|
} else {
|
||||||
@@ -136,6 +139,7 @@ public class SimulatorTNTSettingsGui extends SimulatorBaseGui {
|
|||||||
|
|
||||||
// Pos X
|
// Pos X
|
||||||
inventory.setItem(15, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> {
|
inventory.setItem(15, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.move(clickType.isShiftClick() ? 0.0625 : 1, 0, 0);
|
tnt.move(clickType.isShiftClick() ? 0.0625 : 1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -147,12 +151,14 @@ public class SimulatorTNTSettingsGui extends SimulatorBaseGui {
|
|||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(33, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> {
|
inventory.setItem(33, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.move(clickType.isShiftClick() ? -0.0625 : -1, 0, 0);
|
tnt.move(clickType.isShiftClick() ? -0.0625 : -1, 0, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
// Pos Y
|
// Pos Y
|
||||||
inventory.setItem(16, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> {
|
inventory.setItem(16, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.move(0, clickType.isShiftClick() ? 0.0625 : 1, 0);
|
tnt.move(0, clickType.isShiftClick() ? 0.0625 : 1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -164,12 +170,14 @@ public class SimulatorTNTSettingsGui extends SimulatorBaseGui {
|
|||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(34, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> {
|
inventory.setItem(34, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.move(0, clickType.isShiftClick() ? -0.0625 : -1, 0);
|
tnt.move(0, clickType.isShiftClick() ? -0.0625 : -1, 0);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|
||||||
// Pos Z
|
// Pos Z
|
||||||
inventory.setItem(17, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> {
|
inventory.setItem(17, new SWItem(SWItem.getDye(10), "§e+1", Arrays.asList("§7Shift§8: §e+0.0625"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.move(0, 0, clickType.isShiftClick() ? 0.0625 : 1);
|
tnt.move(0, 0, clickType.isShiftClick() ? 0.0625 : 1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.INCREMENT_OR_DISABLED));
|
||||||
@@ -181,6 +189,7 @@ public class SimulatorTNTSettingsGui extends SimulatorBaseGui {
|
|||||||
}, this).open();
|
}, this).open();
|
||||||
}));
|
}));
|
||||||
inventory.setItem(35, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> {
|
inventory.setItem(35, new SWItem(SWItem.getDye(1), "§e-1", Arrays.asList("§7Shift§8: §e-0.0625"), false, clickType -> {
|
||||||
|
if (clickType == ClickType.DOUBLE_CLICK) return;
|
||||||
tnt.move(0, 0, clickType.isShiftClick() ? -0.0625 : -1);
|
tnt.move(0, 0, clickType.isShiftClick() ? -0.0625 : -1);
|
||||||
SimulatorWatcher.update(simulator);
|
SimulatorWatcher.update(simulator);
|
||||||
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
}).setCustomModelData(CMDs.Simulator.DECREMENT_OR_DISABLED));
|
||||||
|
|||||||
+1
-1
@@ -101,7 +101,7 @@ public class BlockBoundingBox {
|
|||||||
addPixel(Material.END_STONE.createBlockData(), 0, 0, 0, 16, 16, 16, null);
|
addPixel(Material.END_STONE.createBlockData(), 0, 0, 0, 16, 16, 16, null);
|
||||||
|
|
||||||
addPixel(NMSWrapper.impl.pathMaterial().createBlockData(), 0, 0, 0, 16, 15, 16, createItem("LAUFBAU_BLOCK_GRASS_PATH", NMSWrapper.impl.pathMaterial()));
|
addPixel(NMSWrapper.impl.pathMaterial().createBlockData(), 0, 0, 0, 16, 15, 16, createItem("LAUFBAU_BLOCK_GRASS_PATH", NMSWrapper.impl.pathMaterial()));
|
||||||
addPixel(Material.SOUL_SAND.createBlockData(), 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SOUL_SAND", Material.SOUL_SAND));
|
addPixel(Material.MUD.createBlockData(), 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SOUL_SAND", Material.SOUL_SAND));
|
||||||
|
|
||||||
Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData();
|
Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData();
|
||||||
cocoaNorth.setAge(2);
|
cocoaNorth.setAge(2);
|
||||||
|
|||||||
+2
@@ -25,12 +25,14 @@ import de.steamwar.bausystem.shared.Pair;
|
|||||||
import de.steamwar.bausystem.utils.WorldEditUtils;
|
import de.steamwar.bausystem.utils.WorldEditUtils;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.linkage.MinVersion;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
|
@MinVersion(19)
|
||||||
public class LaufbauCommand extends SWCommand {
|
public class LaufbauCommand extends SWCommand {
|
||||||
|
|
||||||
public LaufbauCommand() {
|
public LaufbauCommand() {
|
||||||
|
|||||||
+2
-4
@@ -20,13 +20,13 @@
|
|||||||
package de.steamwar.bausystem.features.smartplace;
|
package de.steamwar.bausystem.features.smartplace;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.configplayer.Config;
|
import de.steamwar.bausystem.configplayer.Config;
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.Core;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundUseItemOnPacket;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
@@ -83,13 +83,11 @@ public class SmartPlaceListener implements Listener {
|
|||||||
IGNORED.remove(Material.BARRIER);
|
IGNORED.remove(Material.BARRIER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> useItem = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundUseItemOnPacket");
|
|
||||||
|
|
||||||
private static final Set<Player> SMART_PLACING = new HashSet<>();
|
private static final Set<Player> SMART_PLACING = new HashSet<>();
|
||||||
private static final Set<Player> WAS_EXECUTED = new HashSet<>();
|
private static final Set<Player> WAS_EXECUTED = new HashSet<>();
|
||||||
|
|
||||||
public SmartPlaceListener() {
|
public SmartPlaceListener() {
|
||||||
TinyProtocol.instance.addFilter(useItem, (player, packet) -> {
|
TinyProtocol.instance.addFilter(ServerboundUseItemOnPacket.class, (player, packet) -> {
|
||||||
if(!Permission.BUILD.hasPermission(player)) return packet;
|
if(!Permission.BUILD.hasPermission(player)) return packet;
|
||||||
if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) return packet;
|
if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) return packet;
|
||||||
RayTraceResult rayTraceResult = player.rayTraceBlocks(6);
|
RayTraceResult rayTraceResult = player.rayTraceBlocks(6);
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ public class TraceManager implements Listener {
|
|||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
if (!tracesFolder.exists())
|
if (!tracesFolder.exists())
|
||||||
tracesFolder.mkdir();
|
tracesFolder.mkdir();
|
||||||
|
|||||||
+11
-1
@@ -135,7 +135,7 @@ public abstract class ViewFlag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Location secoundLocation;
|
Location secoundLocation;
|
||||||
if (previousVelocity.getX() >= previousVelocity.getZ()) {
|
if (Math.abs(previousVelocity.getX()) >= Math.abs(previousVelocity.getZ())) {
|
||||||
secoundLocation = previous.getLocation().clone().add(delta.getX(), delta.getY(), 0);
|
secoundLocation = previous.getLocation().clone().add(delta.getX(), delta.getY(), 0);
|
||||||
} else {
|
} else {
|
||||||
secoundLocation = previous.getLocation().clone().add(0, delta.getY(), delta.getZ());
|
secoundLocation = previous.getLocation().clone().add(0, delta.getY(), delta.getZ());
|
||||||
@@ -198,6 +198,16 @@ public abstract class ViewFlag {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static ViewFlag HIGHLIGHT = new ViewFlag(true, false, "highlight", "h") {
|
||||||
|
@Override
|
||||||
|
public void modify(REntityServer server, List<TraceEntity> entities) {
|
||||||
|
for (TraceEntity entity : entities) {
|
||||||
|
entity.setGlowing(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the flag
|
* Name of the flag
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -39,10 +39,7 @@ import lombok.Setter;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|||||||
+8
-22
@@ -21,7 +21,6 @@ package de.steamwar.bausystem.features.util;
|
|||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||||
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
||||||
@@ -30,6 +29,7 @@ import de.steamwar.command.SWCommand;
|
|||||||
import de.steamwar.core.ProtocolWrapper;
|
import de.steamwar.core.ProtocolWrapper;
|
||||||
import de.steamwar.core.SWPlayer;
|
import de.steamwar.core.SWPlayer;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import net.minecraft.network.protocol.game.*;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -45,16 +45,6 @@ import java.util.function.BiFunction;
|
|||||||
@Linked
|
@Linked
|
||||||
public class NoClipCommand extends SWCommand implements Listener {
|
public class NoClipCommand extends SWCommand implements Listener {
|
||||||
|
|
||||||
public static final Class<?> gameStateChange = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundGameEventPacket");
|
|
||||||
private static final Reflection.Field<Float> floatFieldAccessor = Reflection.getField(gameStateChange, float.class, 0);
|
|
||||||
|
|
||||||
private static final Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
|
||||||
private static final Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
|
||||||
private static final Class<?> useItem = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundUseItemOnPacket");
|
|
||||||
private static final Class<?> blockDig = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundPlayerActionPacket");
|
|
||||||
private static final Class<?> windowClick = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundContainerClickPacket");
|
|
||||||
private static final Class<?> setSlotStack = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket");
|
|
||||||
|
|
||||||
public static class NoClipData implements SWPlayer.Component {
|
public static class NoClipData implements SWPlayer.Component {
|
||||||
private long lastTick = -1;
|
private long lastTick = -1;
|
||||||
|
|
||||||
@@ -75,8 +65,8 @@ public class NoClipCommand extends SWCommand implements Listener {
|
|||||||
noClipData.lastTick = TPSUtils.currentTick.get();
|
noClipData.lastTick = TPSUtils.currentTick.get();
|
||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
TinyProtocol.instance.addFilter(position, first);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, first);
|
||||||
TinyProtocol.instance.addFilter(positionLook, first);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, first);
|
||||||
|
|
||||||
BiFunction<Player, Object, Object> second = (player, o) -> {
|
BiFunction<Player, Object, Object> second = (player, o) -> {
|
||||||
NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null);
|
NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null);
|
||||||
@@ -85,9 +75,9 @@ public class NoClipCommand extends SWCommand implements Listener {
|
|||||||
noClipData.lastTick = TPSUtils.currentTick.get();
|
noClipData.lastTick = TPSUtils.currentTick.get();
|
||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
TinyProtocol.instance.addFilter(useItem, second);
|
TinyProtocol.instance.addFilter(ServerboundUseItemOnPacket.class, second);
|
||||||
TinyProtocol.instance.addFilter(blockDig, second);
|
TinyProtocol.instance.addFilter(ServerboundPlayerActionPacket.class, second);
|
||||||
TinyProtocol.instance.addFilter(windowClick, second);
|
TinyProtocol.instance.addFilter(ServerboundContainerClickPacket.class, second);
|
||||||
|
|
||||||
BiFunction<Player, Object, Object> third = (player, o) -> {
|
BiFunction<Player, Object, Object> third = (player, o) -> {
|
||||||
if (SWPlayer.of(player).hasComponent(NoClipData.class)) {
|
if (SWPlayer.of(player).hasComponent(NoClipData.class)) {
|
||||||
@@ -95,7 +85,7 @@ public class NoClipCommand extends SWCommand implements Listener {
|
|||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
TinyProtocol.instance.addFilter(setSlotStack, third);
|
TinyProtocol.instance.addFilter(ServerboundSetCreativeModeSlotPacket.class, third);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(help = true)
|
@Register(help = true)
|
||||||
@@ -107,13 +97,9 @@ public class NoClipCommand extends SWCommand implements Listener {
|
|||||||
player.setGameMode(GameMode.SPECTATOR);
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
NMSWrapper.impl.setPlayerBuildAbilities(player);
|
NMSWrapper.impl.setPlayerBuildAbilities(player);
|
||||||
|
|
||||||
Object gameStateChangeObject = Reflection.newInstance(gameStateChange);
|
|
||||||
NMSWrapper.impl.setGameStateChangeReason(gameStateChangeObject);
|
|
||||||
floatFieldAccessor.set(gameStateChangeObject, 1F);
|
|
||||||
|
|
||||||
swPlayer.setComponent(new NoClipData());
|
swPlayer.setComponent(new NoClipData());
|
||||||
BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player);
|
BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player);
|
||||||
TinyProtocol.instance.sendPacket(player, gameStateChangeObject);
|
TinyProtocol.instance.sendPacket(player, new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, 1F));
|
||||||
pseudoGameMode(player, GameMode.SPECTATOR);
|
pseudoGameMode(player, GameMode.SPECTATOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -22,8 +22,8 @@ package de.steamwar.bausystem.features.util.items;
|
|||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.features.util.KillAllCommand;
|
import de.steamwar.bausystem.features.util.KillAllCommand;
|
||||||
import de.steamwar.bausystem.linkage.BauGuiItem;
|
|
||||||
import de.steamwar.bausystem.features.util.RegionSelectionType;
|
import de.steamwar.bausystem.features.util.RegionSelectionType;
|
||||||
|
import de.steamwar.bausystem.linkage.BauGuiItem;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.LinkedInstance;
|
import de.steamwar.linkage.LinkedInstance;
|
||||||
|
|||||||
+2
-3
@@ -19,11 +19,11 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.world;
|
package de.steamwar.bausystem.features.world;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.api.Enable;
|
import de.steamwar.linkage.api.Enable;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundContainerClosePacket;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
|
|
||||||
@@ -32,8 +32,7 @@ public class AntiCursorReCentering implements Enable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
Class<?> closeWindow = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundContainerClosePacket");
|
TinyProtocol.instance.addFilter(ClientboundContainerClosePacket.class, (player, object) -> {
|
||||||
TinyProtocol.instance.addFilter(closeWindow, (player, object) -> {
|
|
||||||
if (player.getOpenInventory().getTopInventory().getType() == InventoryType.CRAFTING) {
|
if (player.getOpenInventory().getTopInventory().getType() == InventoryType.CRAFTING) {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -19,17 +19,17 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.world;
|
package de.steamwar.bausystem.features.world;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.utils.NMSWrapper;
|
import de.steamwar.bausystem.utils.NMSWrapper;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
public class NoCreativeKnockback {
|
public class NoCreativeKnockback {
|
||||||
|
|
||||||
public NoCreativeKnockback() {
|
public NoCreativeKnockback() {
|
||||||
TinyProtocol.instance.addFilter(Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket"), (player, o) -> {
|
TinyProtocol.instance.addFilter(ClientboundExplodePacket.class, (player, o) -> {
|
||||||
if (player.getGameMode() != GameMode.CREATIVE) return o;
|
if (player.getGameMode() != GameMode.CREATIVE) return o;
|
||||||
return NMSWrapper.impl.resetExplosionKnockback(o);
|
return NMSWrapper.impl.resetExplosionKnockback(o);
|
||||||
});
|
});
|
||||||
|
|||||||
+12
-28
@@ -19,13 +19,14 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.world;
|
package de.steamwar.bausystem.features.world;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.utils.PlaceItemUtils;
|
import de.steamwar.bausystem.utils.PlaceItemUtils;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -37,6 +38,8 @@ import org.bukkit.block.data.Directional;
|
|||||||
import org.bukkit.block.data.Rotatable;
|
import org.bukkit.block.data.Rotatable;
|
||||||
import org.bukkit.block.sign.Side;
|
import org.bukkit.block.sign.Side;
|
||||||
import org.bukkit.block.sign.SignSide;
|
import org.bukkit.block.sign.SignSide;
|
||||||
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@@ -45,24 +48,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
|||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(20)
|
public class SignEdit implements Listener {
|
||||||
public class SignEditFrom20 implements Listener {
|
|
||||||
|
|
||||||
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
|
|
||||||
private static final Class<?> craftBlock = Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlock");
|
|
||||||
private static final Class<?> craftWorld = Reflection.getClass("org.bukkit.craftbukkit.CraftWorld");
|
|
||||||
private static final Class<?> generatorAccess = Reflection.getClass("net.minecraft.world.level.LevelAccessor");
|
|
||||||
private static final Reflection.Method getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
|
|
||||||
private static final Reflection.Method getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
|
|
||||||
private static final Reflection.Method at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
|
|
||||||
|
|
||||||
private static final Class<?> openSign = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket");
|
|
||||||
private static final Reflection.Field<?> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
|
|
||||||
private static final Reflection.Field<?> sideFieldAccessor = Reflection.getField(openSign, boolean.class, 0);
|
|
||||||
|
|
||||||
private static final Class<?> updateSign = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSignUpdatePacket");
|
|
||||||
private static final Reflection.Field<?> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
|
|
||||||
private static final Reflection.Field<String[]> stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void editSign(PlayerInteractEvent event) {
|
public void editSign(PlayerInteractEvent event) {
|
||||||
@@ -93,10 +79,8 @@ public class SignEditFrom20 implements Listener {
|
|||||||
sign.update(true);
|
sign.update(true);
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
Object openSignObject = Reflection.newInstance(openSign);
|
ClientboundOpenSignEditorPacket packet = new ClientboundOpenSignEditorPacket(((CraftBlock) block).getPosition(), side == Side.FRONT);
|
||||||
blockPositionFieldAccessor.set(openSignObject, getPosition.invoke(block));
|
TinyProtocol.instance.sendPacket(player, packet);
|
||||||
sideFieldAccessor.set(openSignObject, side == Side.FRONT);
|
|
||||||
TinyProtocol.instance.sendPacket(player, openSignObject);
|
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -117,14 +101,14 @@ public class SignEditFrom20 implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
TinyProtocol.instance.addFilter(updateSign, (player, o) -> {
|
TinyProtocol.instance.addTypedFilter(ServerboundSignUpdatePacket.class, (player, o) -> {
|
||||||
Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> {
|
||||||
String[] lines = stringFieldAccessor.get(o);
|
ServerLevel serverLevel = ((CraftWorld) player.getWorld()).getHandle();
|
||||||
|
Block signLoc = CraftBlock.at(serverLevel, o.getPos());
|
||||||
Block signLoc = (Block) at.invoke(null, getWorldHandle.invoke(player.getWorld()), getBlockPositionFieldAccessor.get(o));
|
|
||||||
if (!signLoc.getType().name().contains("SIGN"))
|
if (!signLoc.getType().name().contains("SIGN"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
String[] lines = o.getLines();
|
||||||
Sign sign = ((Sign) signLoc.getState());
|
Sign sign = ((Sign) signLoc.getState());
|
||||||
SignSide signSide = sign.getSide(signSide(player, signLoc));
|
SignSide signSide = sign.getSide(signSide(player, signLoc));
|
||||||
for (int i = 0; i < lines.length; i++) {
|
for (int i = 0; i < lines.length; i++) {
|
||||||
-105
@@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.features.world;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import de.steamwar.bausystem.Permission;
|
|
||||||
import de.steamwar.linkage.Linked;
|
|
||||||
import de.steamwar.linkage.MaxVersion;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.Sign;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
|
|
||||||
@Linked
|
|
||||||
@MaxVersion(19)
|
|
||||||
public class SignEditUntil19 implements Listener {
|
|
||||||
|
|
||||||
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
|
|
||||||
private static final Class<?> craftBlock = Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlock");
|
|
||||||
private static final Class<?> craftWorld = Reflection.getClass("org.bukkit.craftbukkit.CraftWorld");
|
|
||||||
private static final Class<?> generatorAccess = Reflection.getClass("net.minecraft.world.level.LevelAccessor");
|
|
||||||
private static final Reflection.Method getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
|
|
||||||
private static final Reflection.Method getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
|
|
||||||
private static final Reflection.Method at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
|
|
||||||
|
|
||||||
private static final Class<?> openSign = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket");
|
|
||||||
private static final Reflection.Field<?> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
|
|
||||||
|
|
||||||
private static final Class<?> updateSign = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSignUpdatePacket");
|
|
||||||
private static final Reflection.Field<?> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
|
|
||||||
private static final Reflection.Field<String[]> stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void editSign(PlayerInteractEvent event) {
|
|
||||||
if (!event.getPlayer().isSneaking()) return;
|
|
||||||
if (event.getClickedBlock() == null || !event.getClickedBlock().getType().name().contains("SIGN")) return;
|
|
||||||
|
|
||||||
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && (event.getItem() == null || event.getItem().getType() == Material.AIR) || event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
|
||||||
edit(event.getPlayer(), event.getClickedBlock());
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void edit(Player player, Block block) {
|
|
||||||
if (!Permission.BUILD.hasPermission(player)) return;
|
|
||||||
Sign sign = (org.bukkit.block.Sign) block.getState();
|
|
||||||
String[] lines = sign.getLines();
|
|
||||||
for (int i = 0; i < lines.length; i++) {
|
|
||||||
sign.setLine(i, lines[i].replace('§', '&'));
|
|
||||||
}
|
|
||||||
sign.update(true);
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
|
||||||
Object openSignObject = Reflection.newInstance(openSign);
|
|
||||||
blockPositionFieldAccessor.set(openSignObject, getPosition.invoke(block));
|
|
||||||
TinyProtocol.instance.sendPacket(player, openSignObject);
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
TinyProtocol.instance.addFilter(updateSign, (player, o) -> {
|
|
||||||
Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> {
|
|
||||||
String[] lines = stringFieldAccessor.get(o);
|
|
||||||
|
|
||||||
Block signLoc = (Block) at.invoke(null, getWorldHandle.invoke(player.getWorld()), getBlockPositionFieldAccessor.get(o));
|
|
||||||
if (!signLoc.getType().name().contains("SIGN"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
org.bukkit.block.Sign sign = ((Sign) signLoc.getState());
|
|
||||||
for (int i = 0; i < lines.length; i++) {
|
|
||||||
sign.setLine(i, ChatColor.translateAlternateColorCodes('&', lines[i]));
|
|
||||||
}
|
|
||||||
sign.update();
|
|
||||||
});
|
|
||||||
return o;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-189
@@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.features.worldedit;
|
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import de.steamwar.bausystem.region.Point;
|
|
||||||
import de.steamwar.bausystem.region.Region;
|
|
||||||
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
|
||||||
import de.steamwar.core.SWPlayer;
|
|
||||||
import de.steamwar.core.WorldEditRenderer;
|
|
||||||
import de.steamwar.linkage.Linked;
|
|
||||||
import de.steamwar.linkage.MinVersion;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
@Linked
|
|
||||||
@MinVersion(20)
|
|
||||||
public class SelectAdjacent implements Listener {
|
|
||||||
|
|
||||||
private Vector[] FACES = {
|
|
||||||
new Vector(1, 0, 0),
|
|
||||||
new Vector(-1, 0, 0),
|
|
||||||
new Vector(0, 1, 0),
|
|
||||||
new Vector(0, -1, 0),
|
|
||||||
new Vector(0, 0, 1),
|
|
||||||
new Vector(0, 0, -1),
|
|
||||||
|
|
||||||
new Vector(1, 1, 0),
|
|
||||||
new Vector(1, -1, 0),
|
|
||||||
new Vector(1, 0, 1),
|
|
||||||
new Vector(1, 0, -1),
|
|
||||||
new Vector(-1, 1, 0),
|
|
||||||
new Vector(-1, -1, 0),
|
|
||||||
new Vector(-1, 0, 1),
|
|
||||||
new Vector(-1, 0, -1),
|
|
||||||
new Vector(0, 1, 1),
|
|
||||||
new Vector(0, 1, -1),
|
|
||||||
new Vector(0, -1, 1),
|
|
||||||
new Vector(0, -1, -1),
|
|
||||||
};
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
|
||||||
if (!event.hasItem()) return;
|
|
||||||
if (event.getItem().getType() != Material.WOODEN_AXE) return;
|
|
||||||
if (!event.getPlayer().isSneaking()) return;
|
|
||||||
if (event.getAction() != Action.LEFT_CLICK_BLOCK) return;
|
|
||||||
Material material = event.getPlayer().getInventory().getItemInOffHand().getType();
|
|
||||||
Selector selector;
|
|
||||||
if (material.isAir()) {
|
|
||||||
selector = new Selector(event.getClickedBlock(), event.getPlayer(), __ -> true);
|
|
||||||
} else {
|
|
||||||
selector = new Selector(event.getClickedBlock(), event.getPlayer(), type -> type == material);
|
|
||||||
}
|
|
||||||
SWPlayer.of(event.getPlayer()).setComponent(selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Selector implements SWPlayer.Component {
|
|
||||||
|
|
||||||
private static final int MAX_BLOCKS = 500_000;
|
|
||||||
|
|
||||||
private int minX;
|
|
||||||
private int minY;
|
|
||||||
private int minZ;
|
|
||||||
private int maxX;
|
|
||||||
private int maxY;
|
|
||||||
private int maxZ;
|
|
||||||
|
|
||||||
private BukkitTask bukkitTask;
|
|
||||||
private Predicate<Material> predicate;
|
|
||||||
private Set<Location> seen = new HashSet<>();
|
|
||||||
private Set<Location> toCalc = new HashSet<>();
|
|
||||||
|
|
||||||
private Region.Area area;
|
|
||||||
|
|
||||||
public Selector(Block block, Player player, Predicate<Material> predicate) {
|
|
||||||
this.predicate = predicate;
|
|
||||||
toCalc.add(block.getLocation());
|
|
||||||
minX = block.getX();
|
|
||||||
minY = block.getY();
|
|
||||||
minZ = block.getZ();
|
|
||||||
maxX = block.getX();
|
|
||||||
maxY = block.getY();
|
|
||||||
maxZ = block.getZ();
|
|
||||||
|
|
||||||
Region region = Region.getRegion(block.getLocation());
|
|
||||||
area = Region.Area.EMPTY;
|
|
||||||
if (region.getBuildArea().inRegion(block.getLocation(), true)) {
|
|
||||||
area = region.getBuildArea();
|
|
||||||
} else if (region.getTestblockArea().inRegion(block.getLocation(), true)) {
|
|
||||||
area = region.getTestblockArea();
|
|
||||||
} else if (region.getArea().inRegion(block.getLocation(), true)) {
|
|
||||||
area = region.getArea();
|
|
||||||
}
|
|
||||||
|
|
||||||
bukkitTask = Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
|
|
||||||
run();
|
|
||||||
|
|
||||||
long volume = (long)(maxX - minX + 1) * (long)(maxY - minY + 1) * (long)(maxZ - minZ + 1);
|
|
||||||
player.sendTitle("", "§e" + volume + " §7Blocks", 0, 5, 0);
|
|
||||||
|
|
||||||
Point minPoint = new Point(minX, minY, minZ);
|
|
||||||
Point maxPoint = new Point(maxX, maxY, maxZ);
|
|
||||||
|
|
||||||
FlatteningWrapper.impl.setSelection(player, minPoint, maxPoint);
|
|
||||||
WorldEditRenderer.renderPlayer(player);
|
|
||||||
|
|
||||||
// boolean finished = toCalc.stream().allMatch(location -> {
|
|
||||||
// return location.getBlockX() >= minX && location.getBlockY() >= minY && location.getBlockZ() >= minZ &&
|
|
||||||
// location.getBlockX() <= maxX && location.getBlockY() <= maxY && location.getBlockZ() <= maxZ;
|
|
||||||
// });
|
|
||||||
|
|
||||||
if (toCalc.isEmpty() || seen.size() > MAX_BLOCKS) {
|
|
||||||
bukkitTask.cancel();
|
|
||||||
player.sendTitle("§aDone", "§e" + volume + " §7Blocks", 0, 20, 5);
|
|
||||||
SWPlayer.of(player).removeComponent(Selector.class);
|
|
||||||
}
|
|
||||||
}, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cancel() {
|
|
||||||
bukkitTask.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void run() {
|
|
||||||
Set<Location> current = toCalc;
|
|
||||||
toCalc = new HashSet<>();
|
|
||||||
|
|
||||||
for (Location location : current) {
|
|
||||||
Block block = location.getBlock();
|
|
||||||
if (block.isEmpty() || block.isLiquid()) continue;
|
|
||||||
if (!predicate.test(block.getType())) continue;
|
|
||||||
seen.add(location);
|
|
||||||
if (!area.inRegion(block.getLocation(), true)) continue;
|
|
||||||
|
|
||||||
minX = Math.min(minX, location.getBlockX());
|
|
||||||
maxX = Math.max(maxX, location.getBlockX());
|
|
||||||
minY = Math.min(minY, location.getBlockY());
|
|
||||||
maxY = Math.max(maxY, location.getBlockY());
|
|
||||||
minZ = Math.min(minZ, location.getBlockZ());
|
|
||||||
maxZ = Math.max(maxZ, location.getBlockZ());
|
|
||||||
|
|
||||||
for (Vector face : FACES) {
|
|
||||||
Block next = block.getRelative(face.getBlockX(), face.getBlockY(), face.getBlockZ());
|
|
||||||
if (next.isEmpty() || next.isLiquid()) continue;
|
|
||||||
if (!predicate.test(next.getType())) continue;
|
|
||||||
Location loc = next.getLocation();
|
|
||||||
if (seen.contains(loc)) continue;
|
|
||||||
toCalc.add(loc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUnmount(SWPlayer player) {
|
|
||||||
cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+2
@@ -26,6 +26,7 @@ import com.sk89q.worldedit.extension.input.ParserContext;
|
|||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.linkage.MinVersion;
|
||||||
import de.steamwar.linkage.PluginCheck;
|
import de.steamwar.linkage.PluginCheck;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -33,6 +34,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@PluginCheck("FastAsyncWorldEdit")
|
@PluginCheck("FastAsyncWorldEdit")
|
||||||
|
@MinVersion(19)
|
||||||
public class FAWEAboveMaskParser extends FAWEMaskParser {
|
public class FAWEAboveMaskParser extends FAWEMaskParser {
|
||||||
|
|
||||||
public FAWEAboveMaskParser() {
|
public FAWEAboveMaskParser() {
|
||||||
|
|||||||
+2
@@ -26,6 +26,7 @@ import com.sk89q.worldedit.extension.input.ParserContext;
|
|||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.linkage.MinVersion;
|
||||||
import de.steamwar.linkage.PluginCheck;
|
import de.steamwar.linkage.PluginCheck;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -33,6 +34,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@PluginCheck("FastAsyncWorldEdit")
|
@PluginCheck("FastAsyncWorldEdit")
|
||||||
|
@MinVersion(19)
|
||||||
public class FAWEBelowMaskParser extends FAWEMaskParser {
|
public class FAWEBelowMaskParser extends FAWEMaskParser {
|
||||||
|
|
||||||
public FAWEBelowMaskParser() {
|
public FAWEBelowMaskParser() {
|
||||||
|
|||||||
+2
@@ -25,6 +25,7 @@ import com.sk89q.worldedit.extension.input.ParserContext;
|
|||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.linkage.MinVersion;
|
||||||
import de.steamwar.linkage.PluginCheck;
|
import de.steamwar.linkage.PluginCheck;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -32,6 +33,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@PluginCheck("FastAsyncWorldEdit")
|
@PluginCheck("FastAsyncWorldEdit")
|
||||||
|
@MinVersion(19)
|
||||||
public class FAWECheckerboard3DMaskParser extends FAWEMaskParser {
|
public class FAWECheckerboard3DMaskParser extends FAWEMaskParser {
|
||||||
|
|
||||||
public FAWECheckerboard3DMaskParser() {
|
public FAWECheckerboard3DMaskParser() {
|
||||||
|
|||||||
+2
@@ -25,6 +25,7 @@ import com.sk89q.worldedit.extension.input.ParserContext;
|
|||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.linkage.MinVersion;
|
||||||
import de.steamwar.linkage.PluginCheck;
|
import de.steamwar.linkage.PluginCheck;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -32,6 +33,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@PluginCheck("FastAsyncWorldEdit")
|
@PluginCheck("FastAsyncWorldEdit")
|
||||||
|
@MinVersion(19)
|
||||||
public class FAWECheckerboardMaskParser extends FAWEMaskParser {
|
public class FAWECheckerboardMaskParser extends FAWEMaskParser {
|
||||||
|
|
||||||
public FAWECheckerboardMaskParser() {
|
public FAWECheckerboardMaskParser() {
|
||||||
|
|||||||
+2
@@ -25,6 +25,7 @@ import com.sk89q.worldedit.extension.input.ParserContext;
|
|||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
import de.steamwar.bausystem.features.worldedit.utils.FAWEMaskParser;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.linkage.MinVersion;
|
||||||
import de.steamwar.linkage.PluginCheck;
|
import de.steamwar.linkage.PluginCheck;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@@ -32,6 +33,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@PluginCheck("FastAsyncWorldEdit")
|
@PluginCheck("FastAsyncWorldEdit")
|
||||||
|
@MinVersion(19)
|
||||||
public class FAWEGridMaskParser extends FAWEMaskParser {
|
public class FAWEGridMaskParser extends FAWEMaskParser {
|
||||||
|
|
||||||
public FAWEGridMaskParser() {
|
public FAWEGridMaskParser() {
|
||||||
|
|||||||
+2
@@ -27,6 +27,7 @@ import com.sk89q.worldedit.regions.Region;
|
|||||||
import de.steamwar.bausystem.features.worldedit.utils.FAWEPatternParser;
|
import de.steamwar.bausystem.features.worldedit.utils.FAWEPatternParser;
|
||||||
import de.steamwar.bausystem.utils.WorldEditUtils;
|
import de.steamwar.bausystem.utils.WorldEditUtils;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import de.steamwar.linkage.MinVersion;
|
||||||
import de.steamwar.linkage.PluginCheck;
|
import de.steamwar.linkage.PluginCheck;
|
||||||
import org.bukkit.Axis;
|
import org.bukkit.Axis;
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@PluginCheck("FastAsyncWorldEdit")
|
@PluginCheck("FastAsyncWorldEdit")
|
||||||
|
@MinVersion(19)
|
||||||
public class FAWEGradientPatternParser extends FAWEPatternParser {
|
public class FAWEGradientPatternParser extends FAWEPatternParser {
|
||||||
|
|
||||||
public FAWEGradientPatternParser() {
|
public FAWEGradientPatternParser() {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
package de.steamwar.bausystem.features.xray;
|
package de.steamwar.bausystem.features.xray;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.features.techhider.TechHiderCommand;
|
import de.steamwar.bausystem.features.techhider.TechHiderCommand;
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
@@ -32,6 +31,7 @@ import de.steamwar.linkage.Linked;
|
|||||||
import de.steamwar.linkage.LinkedInstance;
|
import de.steamwar.linkage.LinkedInstance;
|
||||||
import de.steamwar.techhider.TechHider;
|
import de.steamwar.techhider.TechHider;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -95,9 +95,6 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
|
||||||
private static final Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
|
||||||
|
|
||||||
{
|
{
|
||||||
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
||||||
Region region = Region.getRegion(player.getLocation());
|
Region region = Region.getRegion(player.getLocation());
|
||||||
@@ -110,8 +107,8 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
|
|||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
|
|
||||||
TinyProtocol.instance.addFilter(position, positionSetter);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, positionSetter);
|
||||||
TinyProtocol.instance.addFilter(positionLook, positionSetter);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, positionSetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public final class Flag<T extends Enum<T> & Flag.Value<T>> implements EnumDispla
|
|||||||
public static final Flag<NoGravityMode> NO_GRAVITY = new Flag<>("NO_GRAVITY", "FLAG_NO_GRAVITY", NoGravityMode.class, NoGravityMode.INACTIVE);
|
public static final Flag<NoGravityMode> NO_GRAVITY = new Flag<>("NO_GRAVITY", "FLAG_NO_GRAVITY", NoGravityMode.class, NoGravityMode.INACTIVE);
|
||||||
public static final Flag<TestblockMode> TESTBLOCK = new Flag<>("TESTBLOCK", "FLAG_TESTBLOCK", TestblockMode.class, TestblockMode.NO_VALUE);
|
public static final Flag<TestblockMode> TESTBLOCK = new Flag<>("TESTBLOCK", "FLAG_TESTBLOCK", TestblockMode.class, TestblockMode.NO_VALUE);
|
||||||
public static final Flag<ChangedMode> CHANGED = new Flag<>("CHANGED", "FLAG_CHANGED", ChangedMode.class, ChangedMode.NO_CHANGE);
|
public static final Flag<ChangedMode> CHANGED = new Flag<>("CHANGED", "FLAG_CHANGED", ChangedMode.class, ChangedMode.NO_CHANGE);
|
||||||
|
public static final Flag<WaterDestroyMode> WATER_DESTROY = new Flag<>("WATER_DESTROY", "FLAG_WATER_DESTROY", WaterDestroyMode.class, WaterDestroyMode.ALLOW);
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private int ordinal;
|
private int ordinal;
|
||||||
|
|||||||
+29
-15
@@ -17,26 +17,40 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.steamwar.core;
|
package de.steamwar.bausystem.region.flags;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
import lombok.AllArgsConstructor;
|
||||||
import net.minecraft.world.entity.PositionMoveRotation;
|
import lombok.Getter;
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
|
|
||||||
public class BountifulWrapper21 extends BountifulWrapper9 {
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum WaterDestroyMode implements Flag.Value<WaterDestroyMode> {
|
||||||
|
|
||||||
|
ALLOW("FLAG_WATER_DESTROY_ALLOW"),
|
||||||
|
DENY("FLAG_WATER_DESTROY_DENY");
|
||||||
|
|
||||||
|
private static WaterDestroyMode[] values;
|
||||||
|
private final String chatValue;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BountifulWrapper.PositionSetter getPositionSetter(Class<?> packetClass, int fieldOffset) {
|
public WaterDestroyMode[] getValues() {
|
||||||
|
if (WaterDestroyMode.values == null) {
|
||||||
|
WaterDestroyMode.values = WaterDestroyMode.values();
|
||||||
|
}
|
||||||
|
return WaterDestroyMode.values;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WaterDestroyMode getValue() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WaterDestroyMode getValueOf(final String name) {
|
||||||
try {
|
try {
|
||||||
Reflection.Field<PositionMoveRotation> field = Reflection.getField(packetClass, PositionMoveRotation.class, 0);
|
return WaterDestroyMode.valueOf(name.toUpperCase());
|
||||||
|
|
||||||
return (packet, x, y, z, pitch, yaw) -> {
|
|
||||||
PositionMoveRotation pos = field.get(packet);
|
|
||||||
|
|
||||||
field.set(packet, new PositionMoveRotation(new Vec3(x, y, z), pos.deltaMovement(), yaw, pitch));
|
|
||||||
};
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
return super.getPositionSetter(packetClass, fieldOffset);
|
return ALLOW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,34 +20,211 @@
|
|||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operations;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||||
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import de.steamwar.bausystem.region.Point;
|
import de.steamwar.bausystem.region.Point;
|
||||||
import de.steamwar.core.VersionDependent;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.block.data.Waterlogged;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.BiPredicate;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public interface FlatteningWrapper {
|
public class FlatteningWrapper {
|
||||||
FlatteningWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
public static final FlatteningWrapper impl = new FlatteningWrapper();
|
||||||
|
|
||||||
boolean isNoBook(ItemStack item);
|
public boolean isNoBook(ItemStack item) {
|
||||||
|
return item.getType() != Material.WRITABLE_BOOK && item.getType() != Material.WRITTEN_BOOK;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isUnpusheable(Material material);
|
private static final Set<Material> unpushable = new HashSet<>(Arrays.asList(Material.BARRIER, Material.BEACON, Material.COMMAND_BLOCK, Material.CHAIN_COMMAND_BLOCK, Material.REPEATING_COMMAND_BLOCK, Material.ENCHANTING_TABLE, Material.END_GATEWAY, Material.END_PORTAL, Material.ENDER_CHEST, Material.GRINDSTONE, Material.JIGSAW, Material.JUKEBOX, Material.NETHER_PORTAL, Material.OBSIDIAN, Material.STRUCTURE_VOID, Material.BARREL, Material.BEEHIVE, Material.BEE_NEST, Material.BLAST_FURNACE, Material.BREWING_STAND, Material.CHEST, Material.DAYLIGHT_DETECTOR, Material.DISPENSER, Material.DROPPER, Material.FURNACE, Material.HOPPER, Material.LECTERN, Material.SMOKER, Material.TRAPPED_CHEST));
|
||||||
boolean isBreakingOnPush(Material material);
|
|
||||||
|
|
||||||
boolean isWorldEditCommand(String command);
|
// TODO: FLOWER
|
||||||
void setSelection(Player p, Point minPoint, Point maxPoint);
|
private static final Set<Material> breaking = new HashSet<>(Arrays.asList(Material.BAMBOO, Material.CACTUS, Material.CAKE, Material.CARVED_PUMPKIN, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.COBWEB, Material.COCOA, Material.DRAGON_EGG, Material.FIRE, Material.FLOWER_POT, Material.JACK_O_LANTERN, Material.LADDER, Material.LAVA, Material.LAVA, Material.LEVER, Material.LILY_PAD, Material.MELON, Material.NETHER_WART, Material.PUMPKIN, Material.COMPARATOR, Material.REDSTONE_WIRE, Material.REPEATER, Material.TORCH, Material.STRUCTURE_VOID, Material.SCAFFOLDING, Material.SEA_PICKLE, Material.SNOW, Material.SUGAR_CANE, Material.TORCH, Material.TRIPWIRE, Material.TRIPWIRE_HOOK, Material.TURTLE_EGG, Material.VINE, Material.WATER, Material.WHEAT));
|
||||||
|
|
||||||
Clipboard loadSchematic(File file);
|
public boolean isUnpusheable(Material material) {
|
||||||
EditSession paste(PasteBuilder pasteBuilder);
|
if (unpushable.contains(material)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String name = material.name();
|
||||||
|
return name.contains("BANNER") || name.contains("SIGN");
|
||||||
|
}
|
||||||
|
|
||||||
Clipboard copy(Point minPoint, Point maxPoint, Point copyPoint);
|
public boolean isBreakingOnPush(Material material) {
|
||||||
boolean backup(Point minPoint, Point maxPoint, File file);
|
if (breaking.contains(material)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String name = material.name();
|
||||||
|
return name.contains("BED") || name.contains("BUTTON") || name.contains("CARPET") || (name.contains("DOOR") && !name.contains("TRAPDOOR")) || name.contains("HEAD") || name.contains("LEAVES") || name.contains("MUSHROOM") || name.contains("PRESSURE_PLATE") || name.contains("SHULKER_BOX");
|
||||||
|
}
|
||||||
|
|
||||||
boolean inWater(World world, Vector tntPosition);
|
public boolean isWorldEditCommand(String command) {
|
||||||
|
if (command.startsWith("/")) {
|
||||||
|
command = command.replaceFirst("/", "");
|
||||||
|
}
|
||||||
|
command = command.toLowerCase();
|
||||||
|
return WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getCommandManager().containsCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final WorldEditPlugin WORLDEDIT_PLUGIN = Objects.requireNonNull((WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"));
|
||||||
|
private static final BukkitWorld BUKKITWORLD = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||||
|
|
||||||
|
public void setSelection(Player p, Point minPoint, Point maxPoint) {
|
||||||
|
WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, minPoint.toBlockVector3(), maxPoint.toBlockVector3()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Clipboard loadSchematic(File file) {
|
||||||
|
Clipboard clipboard;
|
||||||
|
try (ClipboardReader reader = Objects.requireNonNull(ClipboardFormats.findByFile(file)).getReader(new FileInputStream(file))) {
|
||||||
|
clipboard = reader.read();
|
||||||
|
} catch (NullPointerException | IOException e) {
|
||||||
|
throw new SecurityException("Bausystem schematic not found", e);
|
||||||
|
}
|
||||||
|
return clipboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EditSession paste(PasteBuilder pasteBuilder) {
|
||||||
|
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
|
||||||
|
Clipboard clipboard = pasteBuilder.getClipboard();
|
||||||
|
|
||||||
|
if (!pasteBuilder.getMappers().isEmpty()) {
|
||||||
|
BlockVector3 minimum = clipboard.getRegion().getMinimumPoint();
|
||||||
|
for (int x = 0; x < clipboard.getDimensions().getX(); x++) {
|
||||||
|
for (int y = 0; y < clipboard.getDimensions().getY(); y++) {
|
||||||
|
for (int z = 0; z < clipboard.getDimensions().getZ(); z++) {
|
||||||
|
BlockVector3 pos = minimum.add(x, y, z);
|
||||||
|
pasteBuilder.getMappers().forEach(mapper -> mapper.accept(clipboard, pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AtomicReference<BlockVector3> pastePoint = new AtomicReference<>();
|
||||||
|
if (!pasteBuilder.getPredicates().isEmpty()) {
|
||||||
|
e.setMask(new Mask() {
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockVector3 blockVector3) {
|
||||||
|
BaseBlock block = clipboard.getFullBlock(blockVector3.subtract(pastePoint.get()).add(clipboard.getRegion().getMinimumPoint()));
|
||||||
|
String blockName = block.getBlockType().toString().toLowerCase();
|
||||||
|
for (BiPredicate<BaseBlock, String> predicate : pasteBuilder.getPredicates()) {
|
||||||
|
if (!predicate.test(block, blockName)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mask copy() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Mask2D toMask2D() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipboardHolder ch = new ClipboardHolder(clipboard);
|
||||||
|
BlockVector3 dimensions = clipboard.getDimensions();
|
||||||
|
BlockVector3 v = BlockVector3.at(pasteBuilder.getPastPoint().getX(), pasteBuilder.getPastPoint().getY(), pasteBuilder.getPastPoint().getZ());
|
||||||
|
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
||||||
|
if (pasteBuilder.isRotate()) {
|
||||||
|
ch.setTransform(new AffineTransform().rotateY(180));
|
||||||
|
v = v.add(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset.multiply(-1, 1, -1)).subtract(0, 0, 1);
|
||||||
|
} else {
|
||||||
|
v = v.subtract(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset);
|
||||||
|
}
|
||||||
|
pastePoint.set(v);
|
||||||
|
|
||||||
|
if (pasteBuilder.isReset()) {
|
||||||
|
e.setBlocks((Region) new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
|
||||||
|
if (pasteBuilder.getWaterLevel() != 0) {
|
||||||
|
e.setBlocks((Region) new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3().withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(pasteBuilder.isIgnoreAir()).build());
|
||||||
|
return e;
|
||||||
|
} catch (WorldEditException e) {
|
||||||
|
throw new SecurityException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Clipboard copy(Point minPoint, Point maxPoint, Point copyPoint) {
|
||||||
|
BukkitWorld bukkitWorld = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||||
|
CuboidRegion region = new CuboidRegion(bukkitWorld, minPoint.toBlockVector3(), maxPoint.toBlockVector3());
|
||||||
|
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
|
||||||
|
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(bukkitWorld, -1)) {
|
||||||
|
ForwardExtentCopy copy = new ForwardExtentCopy(
|
||||||
|
e, region, clipboard, region.getMinimumPoint()
|
||||||
|
);
|
||||||
|
|
||||||
|
copy.setCopyingEntities(false);
|
||||||
|
copy.setCopyingBiomes(false);
|
||||||
|
|
||||||
|
Operations.complete(copy);
|
||||||
|
clipboard.setOrigin(copyPoint.toBlockVector3());
|
||||||
|
return clipboard;
|
||||||
|
} catch (WorldEditException e) {
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean backup(Point minPoint, Point maxPoint, File file) {
|
||||||
|
Clipboard clipboard = copy(minPoint, maxPoint, minPoint);
|
||||||
|
try (ClipboardWriter writer = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) {
|
||||||
|
writer.write(clipboard);
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean inWater(org.bukkit.World world, Vector tntPosition) {
|
||||||
|
Block block = world.getBlockAt(tntPosition.getBlockX(), tntPosition.getBlockY(), tntPosition.getBlockZ());
|
||||||
|
if (block.getType() == Material.WATER)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
BlockData data = block.getBlockData();
|
||||||
|
if (!(data instanceof Waterlogged))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ((Waterlogged) data).isWaterlogged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,25 +19,99 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.core.VersionDependent;
|
import io.papermc.paper.datacomponent.DataComponentTypes;
|
||||||
|
import io.papermc.paper.datacomponent.item.ItemContainerContents;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
||||||
|
import net.minecraft.server.level.ServerPlayerGameMode;
|
||||||
|
import net.minecraft.world.entity.player.Abilities;
|
||||||
|
import net.minecraft.world.level.GameType;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
public interface NMSWrapper {
|
import java.util.List;
|
||||||
NMSWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
import java.util.Optional;
|
||||||
|
|
||||||
void setInternalGameMode(Player player, GameMode gameMode);
|
public class NMSWrapper {
|
||||||
void setSlotToItemStack(Player player, Object o);
|
public static final NMSWrapper impl = new NMSWrapper();
|
||||||
|
|
||||||
void setGameStateChangeReason(Object packet);
|
private static final Reflection.Field<GameType> playerGameMode = Reflection.getField(ServerPlayerGameMode.class, GameType.class, 0);
|
||||||
void setPlayerBuildAbilities(Player player);
|
|
||||||
|
|
||||||
Material pathMaterial();
|
public void setInternalGameMode(Player player, GameMode gameMode) {
|
||||||
|
playerGameMode.set(((CraftPlayer) player).getHandle().gameMode, GameType.byId(gameMode.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
boolean checkItemStack(ItemStack item);
|
public void setSlotToItemStack(Player player, Object o) {
|
||||||
|
ClientboundContainerSetSlotPacket packetPlayInSetCreativeSlot = (ClientboundContainerSetSlotPacket) o;
|
||||||
|
int index = packetPlayInSetCreativeSlot.getSlot();
|
||||||
|
if (index >= 36 && index <= 44) {
|
||||||
|
index -= 36;
|
||||||
|
} else if (index > 44) {
|
||||||
|
index -= 5;
|
||||||
|
} else if (index <= 8) {
|
||||||
|
index = index - 8 + 36;
|
||||||
|
}
|
||||||
|
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.getItem()));
|
||||||
|
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
||||||
|
player.updateInventory();
|
||||||
|
}
|
||||||
|
|
||||||
Object resetExplosionKnockback(Object packet);
|
public void setPlayerBuildAbilities(Player player) {
|
||||||
|
Abilities abilities = (((CraftPlayer) player).getHandle()).getAbilities();
|
||||||
|
abilities.mayBuild = true;
|
||||||
|
abilities.mayfly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material pathMaterial() {
|
||||||
|
return Material.DIRT_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int threshold = 2048;
|
||||||
|
|
||||||
|
public boolean checkItemStack(ItemStack item) {
|
||||||
|
ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER);
|
||||||
|
if (data == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return drillDown(data.contents(), 0, 0) > threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int drillDown(List<ItemStack> items, int layer, int start) {
|
||||||
|
if (layer > 2) return start + threshold;
|
||||||
|
int invalid = start;
|
||||||
|
for (int i = start; i < items.size(); i++) {
|
||||||
|
ItemStack item = items.get(i);
|
||||||
|
if (item.isEmpty()) continue;
|
||||||
|
|
||||||
|
invalid += item.getAmount();
|
||||||
|
|
||||||
|
ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER);
|
||||||
|
if (data == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ItemStack> subItems = data.contents();
|
||||||
|
if (subItems.size() > 1) {
|
||||||
|
invalid = drillDown(subItems, layer + 1, invalid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object resetExplosionKnockback(Object packet) {
|
||||||
|
ClientboundExplodePacket explosion = (ClientboundExplodePacket) packet;
|
||||||
|
|
||||||
|
return new ClientboundExplodePacket(
|
||||||
|
explosion.center(),
|
||||||
|
Optional.empty(),
|
||||||
|
explosion.explosionParticle(),
|
||||||
|
explosion.explosionSound()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,15 @@ import de.steamwar.Reflection;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.*;
|
import org.bukkit.block.*;
|
||||||
|
import org.bukkit.block.Skull;
|
||||||
import org.bukkit.block.data.*;
|
import org.bukkit.block.data.*;
|
||||||
import org.bukkit.block.data.type.Hopper;
|
|
||||||
import org.bukkit.block.data.type.*;
|
import org.bukkit.block.data.type.*;
|
||||||
|
import org.bukkit.block.data.type.Hopper;
|
||||||
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.block.BlockCanBuildEvent;
|
import org.bukkit.event.block.BlockCanBuildEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
@@ -82,27 +86,23 @@ public class PlaceItemUtils {
|
|||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
|
private static final Reflection.Field<?> positionAccessor = Reflection.getField(CraftBlockState.class, BlockPos.class, 0);
|
||||||
private static final Reflection.Constructor blockPositionConstructor = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
|
private static final Reflection.Field<?> worldAccessor = Reflection.getField(CraftBlockState.class, CraftWorld.class, 0);
|
||||||
private static final Class<?> craftBlock = Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlockState");
|
|
||||||
private static final Class<?> craftWorld = Reflection.getClass("org.bukkit.craftbukkit.CraftWorld");
|
|
||||||
private static final Reflection.Field<?> positionAccessor = Reflection.getField(craftBlock, blockPosition, 0);
|
|
||||||
private static final Reflection.Field<?> worldAccessor = Reflection.getField(craftBlock, craftWorld, 0);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to place an {@link ItemStack} the {@link Player} is holding against a {@link Block} inside the World.
|
* Attempt to place an {@link ItemStack} the {@link Player} is holding against a {@link Block} inside the World.
|
||||||
* This can be easily used inside the {@link org.bukkit.event.player.PlayerInteractEvent} to mimik placing a
|
* This can be easily used inside the {@link org.bukkit.event.player.PlayerInteractEvent} to mimik placing a
|
||||||
* block without any minecraft related GUI's etc. executing.
|
* block without any minecraft related GUI's etc. executing.
|
||||||
*
|
*
|
||||||
* @param player the Player placing the block
|
* @param player the Player placing the block
|
||||||
* @param itemStack the ItemStack to be placed
|
* @param itemStack the ItemStack to be placed
|
||||||
* @param against the Block at which the player aims (does not need to be in range of the player)
|
* @param against the Block at which the player aims (does not need to be in range of the player)
|
||||||
* @param againstSide the BlockFace the player aims
|
* @param againstSide the BlockFace the player aims
|
||||||
* @param hand the Hand the player is using
|
* @param hand the Hand the player is using
|
||||||
* @param force allow illegal states to be created by placing the block
|
* @param force allow illegal states to be created by placing the block
|
||||||
* @param applyPhysics apply physics while placing the block
|
* @param applyPhysics apply physics while placing the block
|
||||||
* @param rotateAway rotate everything in the opposite direction, so a block facing the Player will face away, and the other way round
|
* @param rotateAway rotate everything in the opposite direction, so a block facing the Player will face away, and the other way round
|
||||||
* @param playSound enables sound of placing
|
* @param playSound enables sound of placing
|
||||||
*/
|
*/
|
||||||
public PlaceItemResult placeItem(Player player, ItemStack itemStack, Block against, BlockFace againstSide, EquipmentSlot hand, boolean force, boolean applyPhysics, boolean rotateAway, boolean playSound) {
|
public PlaceItemResult placeItem(Player player, ItemStack itemStack, Block against, BlockFace againstSide, EquipmentSlot hand, boolean force, boolean applyPhysics, boolean rotateAway, boolean playSound) {
|
||||||
// If the ItemStack is null or air we cannot place it
|
// If the ItemStack is null or air we cannot place it
|
||||||
@@ -288,7 +288,7 @@ public class PlaceItemUtils {
|
|||||||
} else {
|
} else {
|
||||||
// If a BlockState is present set the Position and World to the Block you want to place
|
// If a BlockState is present set the Position and World to the Block you want to place
|
||||||
Location blockLocation = block.getLocation();
|
Location blockLocation = block.getLocation();
|
||||||
positionAccessor.set(blockState, blockPositionConstructor.invoke(blockLocation.getBlockX(), blockLocation.getBlockY(), blockLocation.getBlockZ()));
|
positionAccessor.set(blockState, new BlockPos(blockLocation.getBlockX(), blockLocation.getBlockY(), blockLocation.getBlockZ()));
|
||||||
worldAccessor.set(blockState, blockLocation.getWorld());
|
worldAccessor.set(blockState, blockLocation.getWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +300,7 @@ public class PlaceItemUtils {
|
|||||||
Location blockmin = block.getLocation();
|
Location blockmin = block.getLocation();
|
||||||
Location blockmax = block.getLocation().add(1.0, 1.0, 1.0);
|
Location blockmax = block.getLocation().add(1.0, 1.0, 1.0);
|
||||||
if (
|
if (
|
||||||
!(max.getX() <= blockmin.getX() || min.getX() >= blockmax.getX() ||
|
!(max.getX() <= blockmin.getX() || min.getX() >= blockmax.getX() ||
|
||||||
max.getY() <= blockmin.getY() || min.getY() >= blockmax.getY() ||
|
max.getY() <= blockmin.getY() || min.getY() >= blockmax.getY() ||
|
||||||
max.getZ() <= blockmin.getZ() || min.getZ() >= blockmax.getZ())
|
max.getZ() <= blockmin.getZ() || min.getZ() >= blockmax.getZ())
|
||||||
) {
|
) {
|
||||||
@@ -369,8 +369,8 @@ public class PlaceItemUtils {
|
|||||||
return usedForcePlace.get() ? PlaceItemResult.SUCCESS_FORCE : PlaceItemResult.SUCCESS;
|
return usedForcePlace.get() ? PlaceItemResult.SUCCESS_FORCE : PlaceItemResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockFace[] axis = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
|
public BlockFace[] axis = {BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
|
||||||
public BlockFace[] radial = { BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST };
|
public BlockFace[] radial = {BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST};
|
||||||
|
|
||||||
public BlockFace yawToFace(float yaw) {
|
public BlockFace yawToFace(float yaw) {
|
||||||
return radial[Math.round(yaw / 45f) & 0x7];
|
return radial[Math.round(yaw / 45f) & 0x7];
|
||||||
|
|||||||
@@ -19,16 +19,32 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import lombok.experimental.UtilityClass;
|
||||||
import de.steamwar.core.VersionDependent;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface PlaceItemWrapper {
|
@UtilityClass
|
||||||
Map<Material, Material> ITEM_MATERIAL_TO_BLOCK_MATERIAL = new HashMap<>();
|
public class PlaceItemWrapper {
|
||||||
Map<Material, Material> BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL = new HashMap<>();
|
public static final Map<Material, Material> ITEM_MATERIAL_TO_BLOCK_MATERIAL = new HashMap<>();
|
||||||
|
public static final Map<Material, Material> BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL = new HashMap<>();
|
||||||
|
|
||||||
PlaceItemWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
static {
|
||||||
|
for (Material material : Material.values()) {
|
||||||
|
if (!material.isBlock()) continue;
|
||||||
|
if (material.isLegacy()) continue;
|
||||||
|
BlockData blockData = material.createBlockData();
|
||||||
|
Material placementMaterial = blockData.getPlacementMaterial();
|
||||||
|
if (material == placementMaterial) continue;
|
||||||
|
if (placementMaterial == Material.AIR) continue;
|
||||||
|
if (placementMaterial.isItem() && !placementMaterial.isBlock()) {
|
||||||
|
ITEM_MATERIAL_TO_BLOCK_MATERIAL.put(placementMaterial, material);
|
||||||
|
}
|
||||||
|
if (material.name().contains("WALL")) {
|
||||||
|
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(placementMaterial, material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-6
@@ -20,19 +20,33 @@
|
|||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import de.steamwar.core.BountifulWrapper;
|
import de.steamwar.core.BountifulWrapper;
|
||||||
import de.steamwar.core.VersionDependent;
|
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.REntity;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public interface PlayerMovementWrapper {
|
public class PlayerMovementWrapper {
|
||||||
Class<?> teleportPacket = REntity.teleportPacket;
|
Class<?> teleportPacket = REntity.teleportPacket;
|
||||||
Reflection.Field<Integer> teleportEntity = REntity.teleportEntity;
|
Reflection.Field<Integer> teleportEntity = REntity.teleportEntity;
|
||||||
BountifulWrapper.PositionSetter teleportPosition = REntity.teleportPosition;
|
BountifulWrapper.PositionSetter teleportPosition = REntity.teleportPosition;
|
||||||
|
|
||||||
PlayerMovementWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
public static final PlayerMovementWrapper impl = new PlayerMovementWrapper();
|
||||||
|
|
||||||
void setPosition(Player player, Object object);
|
public void setPosition(Player player, Object object) {
|
||||||
Object convertToOut(Player player, Object object);
|
ServerboundMovePlayerPacket packetPlayInFlying = ((ServerboundMovePlayerPacket) object);
|
||||||
|
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||||
|
if (packetPlayInFlying.hasPos) {
|
||||||
|
serverPlayer.setPosRaw(packetPlayInFlying.x, packetPlayInFlying.y, packetPlayInFlying.z);
|
||||||
|
}
|
||||||
|
if (packetPlayInFlying.hasRot) {
|
||||||
|
serverPlayer.setXRot(packetPlayInFlying.xRot);
|
||||||
|
serverPlayer.setYRot(packetPlayInFlying.yRot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object convertToOut(Player player, Object object) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import de.steamwar.core.VersionDependent;
|
|
||||||
|
|
||||||
public interface TickListener {
|
|
||||||
|
|
||||||
TickListener impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
|
||||||
|
|
||||||
default void init() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -19,28 +19,119 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.core.VersionDependent;
|
import net.minecraft.network.protocol.game.ClientboundTickingStatePacket;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.ServerTickRateManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
public interface TickManager extends Listener {
|
public class TickManager implements Listener {
|
||||||
TickManager impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
public static final TickManager impl = new TickManager();
|
||||||
|
|
||||||
void setTickRate(float tickRate);
|
private static final ServerTickRateManager manager = MinecraftServer.getServer().tickRateManager();
|
||||||
float getTickRate();
|
private static final Reflection.Field<Long> remainingSprintTicks = Reflection.getField(ServerTickRateManager.class, long.class, 0);
|
||||||
|
|
||||||
boolean canFreeze();
|
private boolean blockTpsPacket = true;
|
||||||
void setFreeze(boolean freeze);
|
private int totalSteps;
|
||||||
boolean isFrozen();
|
|
||||||
|
|
||||||
void stepTicks(int ticks);
|
private TickManager() {
|
||||||
boolean isStepping();
|
TinyProtocol.instance.addFilter(ClientboundTickingStatePacket.class, this::blockPacket);
|
||||||
|
}
|
||||||
|
|
||||||
void sprintTicks(int ticks);
|
private Object blockPacket(Player player, Object packet) {
|
||||||
boolean isSprinting();
|
if (blockTpsPacket) {
|
||||||
|
return new ClientboundTickingStatePacket(20, manager.isFrozen());
|
||||||
|
} else {
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setBlockTpsPacket(boolean block);
|
public boolean canFreeze() {
|
||||||
long getRemainingTicks();
|
return true;
|
||||||
long getDoneTicks();
|
}
|
||||||
long getTotalTicks();
|
|
||||||
|
public void setBlockTpsPacket(boolean block) {
|
||||||
|
blockTpsPacket = block;
|
||||||
|
if (blockTpsPacket) {
|
||||||
|
ClientboundTickingStatePacket packet = new ClientboundTickingStatePacket(20, manager.isFrozen());
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
|
||||||
|
} else {
|
||||||
|
ClientboundTickingStatePacket packet = new ClientboundTickingStatePacket(manager.tickrate(), manager.isFrozen());
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTickRate(float tickRate) {
|
||||||
|
if (isFrozen()) {
|
||||||
|
setFreeze(false);
|
||||||
|
}
|
||||||
|
manager.setTickRate(tickRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFrozen() {
|
||||||
|
return manager.isFrozen();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFreeze(boolean freeze) {
|
||||||
|
manager.setFrozen(freeze);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stepTicks(int ticks) {
|
||||||
|
if (manager.isSprinting()) {
|
||||||
|
manager.stopSprinting();
|
||||||
|
} else if (manager.isSteppingForward()) {
|
||||||
|
manager.stopStepping();
|
||||||
|
}
|
||||||
|
this.totalSteps = ticks;
|
||||||
|
manager.setFrozen(true);
|
||||||
|
manager.stepGameIfPaused(ticks);
|
||||||
|
manager.setFrozen(false);
|
||||||
|
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), (bukkitTask) -> {
|
||||||
|
if (manager.isSteppingForward()) return;
|
||||||
|
manager.setFrozen(true);
|
||||||
|
bukkitTask.cancel();
|
||||||
|
}, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sprintTicks(int ticks) {
|
||||||
|
if (manager.isSteppingForward()) {
|
||||||
|
manager.stopStepping();
|
||||||
|
} else if (manager.isSprinting()) {
|
||||||
|
manager.stopSprinting();
|
||||||
|
}
|
||||||
|
this.totalSteps = ticks;
|
||||||
|
manager.requestGameToSprint(ticks, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSprinting() {
|
||||||
|
return manager.isSprinting();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStepping() {
|
||||||
|
return manager.isSteppingForward();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTickRate() {
|
||||||
|
return manager.tickrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRemainingTicks() {
|
||||||
|
if (isSprinting()) {
|
||||||
|
return remainingSprintTicks.get(manager);
|
||||||
|
} else {
|
||||||
|
return manager.frozenTicksToRun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDoneTicks() {
|
||||||
|
return totalSteps - getRemainingTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTotalTicks() {
|
||||||
|
return totalSteps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.IncompleteRegionException;
|
import com.sk89q.worldedit.IncompleteRegionException;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
@@ -34,6 +33,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.regions.RegionSelector;
|
import com.sk89q.worldedit.regions.RegionSelector;
|
||||||
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
|
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
|
||||||
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.bausystem.shared.Pair;
|
import de.steamwar.bausystem.shared.Pair;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ tasks.compileJava {
|
|||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ public class FixedRegionData extends RegionData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
|
public @NonNull <T extends Enum<T> & Flag.Value<T>> RegionFlagPolicy has(@NonNull Flag<T> flag) {
|
||||||
if (flag.oneOf(Flag.COLOR, Flag.TNT, Flag.FIRE, Flag.FREEZE, Flag.PROTECT, Flag.NO_GRAVITY, Flag.CHANGED)) {
|
if (flag.oneOf(Flag.COLOR, Flag.TNT, Flag.FIRE, Flag.FREEZE, Flag.PROTECT, Flag.NO_GRAVITY, Flag.CHANGED, Flag.WATER_DESTROY)) {
|
||||||
return RegionFlagPolicy.WRITABLE;
|
return RegionFlagPolicy.WRITABLE;
|
||||||
}
|
}
|
||||||
if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) {
|
if (flag.oneOf(Flag.ITEMS) && Core.getVersion() >= 20) {
|
||||||
|
|||||||
+1
-1
@@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.region.fixed.loader;
|
package de.steamwar.bausystem.region.fixed.loader;
|
||||||
|
|
||||||
import de.steamwar.bausystem.region.fixed.FixedGlobalRegionData;
|
|
||||||
import de.steamwar.bausystem.region.fixed.FixedGlobalRegion;
|
import de.steamwar.bausystem.region.fixed.FixedGlobalRegion;
|
||||||
|
import de.steamwar.bausystem.region.fixed.FixedGlobalRegionData;
|
||||||
import de.steamwar.bausystem.region.fixed.Prototype;
|
import de.steamwar.bausystem.region.fixed.Prototype;
|
||||||
import de.steamwar.bausystem.worlddata.WorldData;
|
import de.steamwar.bausystem.worlddata.WorldData;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|||||||
@@ -29,11 +29,6 @@ tasks.build {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":BauSystem:BauSystem_RegionFixed"))
|
implementation(project(":BauSystem:BauSystem_RegionFixed"))
|
||||||
implementation(project(":BauSystem:BauSystem_Main"))
|
implementation(project(":BauSystem:BauSystem_Main"))
|
||||||
implementation(project(":BauSystem:BauSystem_15"))
|
|
||||||
implementation(project(":BauSystem:BauSystem_18"))
|
|
||||||
implementation(project(":BauSystem:BauSystem_19"))
|
|
||||||
implementation(project(":BauSystem:BauSystem_20"))
|
|
||||||
implementation(project(":BauSystem:BauSystem_21"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<DevServer>("DevBau20") {
|
tasks.register<DevServer>("DevBau20") {
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
plugins {
|
||||||
|
steamwar.kotlin
|
||||||
|
application
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvmToolchain(21)
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass.set("de.steamwar.MainKt")
|
||||||
|
applicationName = "sw"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":CommonCore:SQL"))
|
||||||
|
|
||||||
|
implementation("com.github.ajalt.clikt:clikt:5.0.3")
|
||||||
|
implementation("com.github.ajalt.mordant:mordant:3.0.2")
|
||||||
|
implementation(libs.logback)
|
||||||
|
implementation("org.mariadb.jdbc:mariadb-java-client:3.3.1")
|
||||||
|
|
||||||
|
implementation(libs.exposedCore)
|
||||||
|
implementation(libs.exposedDao)
|
||||||
|
implementation(libs.exposedJdbc)
|
||||||
|
implementation(libs.exposedTime)
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package de.steamwar
|
||||||
|
|
||||||
|
import com.github.ajalt.clikt.core.main
|
||||||
|
import com.github.ajalt.clikt.core.subcommands
|
||||||
|
import de.steamwar.commands.SteamWar
|
||||||
|
import de.steamwar.commands.database.DatabaseCommand
|
||||||
|
import de.steamwar.commands.database.InfoCommand
|
||||||
|
import de.steamwar.commands.database.ResetCommand
|
||||||
|
import de.steamwar.commands.dev.DevCommand
|
||||||
|
import de.steamwar.commands.profiler.ProfilerCommand
|
||||||
|
import de.steamwar.commands.user.UserCommand
|
||||||
|
import de.steamwar.commands.user.UserInfoCommand
|
||||||
|
import de.steamwar.commands.user.UserSearchCommand
|
||||||
|
|
||||||
|
fun main(args: Array<String>) = SteamWar()
|
||||||
|
.subcommands(
|
||||||
|
DatabaseCommand().subcommands(InfoCommand(), ResetCommand()),
|
||||||
|
UserCommand().subcommands(UserInfoCommand(), UserSearchCommand()),
|
||||||
|
DevCommand(),
|
||||||
|
ProfilerCommand()
|
||||||
|
)
|
||||||
|
.main(args)
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package de.steamwar.commands
|
||||||
|
|
||||||
|
import com.github.ajalt.clikt.core.CliktCommand
|
||||||
|
import com.github.ajalt.mordant.rendering.TextStyles
|
||||||
|
|
||||||
|
class SteamWar: CliktCommand(name = "sw") {
|
||||||
|
override fun run() {
|
||||||
|
echo(TextStyles.bold("SteamWar-CLI"))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package de.steamwar.commands.database
|
||||||
|
|
||||||
|
import com.github.ajalt.clikt.core.CliktCommand
|
||||||
|
import com.github.ajalt.clikt.core.CliktError
|
||||||
|
import com.github.ajalt.clikt.core.Context
|
||||||
|
import com.github.ajalt.clikt.core.findOrSetObject
|
||||||
|
import com.github.ajalt.clikt.parameters.options.flag
|
||||||
|
import com.github.ajalt.clikt.parameters.options.option
|
||||||
|
import de.steamwar.db.Database
|
||||||
|
|
||||||
|
class DatabaseCommand: CliktCommand(name = "db") {
|
||||||
|
val useProduction by option().flag()
|
||||||
|
val db by findOrSetObject { Database }
|
||||||
|
|
||||||
|
override fun help(context: Context): String = "Run database commands"
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
if (!useProduction && db.database == "production") {
|
||||||
|
throw CliktError("You should not use the production database!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package de.steamwar.commands.database
|
||||||
|
|
||||||
|
import com.github.ajalt.clikt.core.CliktCommand
|
||||||
|
import com.github.ajalt.clikt.core.requireObject
|
||||||
|
import com.github.ajalt.mordant.table.table
|
||||||
|
import de.steamwar.db.Database
|
||||||
|
import de.steamwar.db.execute
|
||||||
|
import de.steamwar.db.useDb
|
||||||
|
|
||||||
|
class InfoCommand: CliktCommand() {
|
||||||
|
val db by requireObject<Database>()
|
||||||
|
|
||||||
|
override fun run() = useDb {
|
||||||
|
val tables = execute("SHOW TABLES") { it.getString(1) }
|
||||||
|
|
||||||
|
echo(
|
||||||
|
table {
|
||||||
|
header { row("Name") }
|
||||||
|
body {
|
||||||
|
tables.map { row(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package de.steamwar.commands.database
|
||||||
|
|
||||||
|
import com.github.ajalt.clikt.core.CliktCommand
|
||||||
|
import com.github.ajalt.clikt.core.CliktError
|
||||||
|
import com.github.ajalt.clikt.core.requireObject
|
||||||
|
import com.github.ajalt.mordant.rendering.TextColors
|
||||||
|
import com.github.ajalt.mordant.rendering.TextStyles
|
||||||
|
import de.steamwar.db.Database
|
||||||
|
import de.steamwar.db.execute
|
||||||
|
import de.steamwar.db.useDb
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class ResetCommand: CliktCommand() {
|
||||||
|
val db by requireObject<Database>()
|
||||||
|
|
||||||
|
override fun run() = useDb {
|
||||||
|
val schemaFile = File("/var/Schema.sql")
|
||||||
|
if (!schemaFile.exists()) {
|
||||||
|
throw CliktError("Schema file not found!")
|
||||||
|
}
|
||||||
|
|
||||||
|
val schema = schemaFile.readText()
|
||||||
|
|
||||||
|
val tables = execute("SHOW TABLES;") { it.getString(1) }
|
||||||
|
for (table in tables) {
|
||||||
|
execute("DROP TABLE IF EXISTS $table;") { }
|
||||||
|
}
|
||||||
|
|
||||||
|
execute(schema) { }
|
||||||
|
|
||||||
|
echo(TextColors.brightGreen(TextStyles.bold("Database reset!")))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
package de.steamwar.commands.dev
|
||||||
|
|
||||||
|
import com.github.ajalt.clikt.core.CliktCommand
|
||||||
|
import com.github.ajalt.clikt.core.CliktError
|
||||||
|
import com.github.ajalt.clikt.core.Context
|
||||||
|
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||||
|
import com.github.ajalt.clikt.parameters.arguments.help
|
||||||
|
import com.github.ajalt.clikt.parameters.arguments.multiple
|
||||||
|
import com.github.ajalt.clikt.parameters.options.default
|
||||||
|
import com.github.ajalt.clikt.parameters.options.defaultLazy
|
||||||
|
import com.github.ajalt.clikt.parameters.options.flag
|
||||||
|
import com.github.ajalt.clikt.parameters.options.help
|
||||||
|
import com.github.ajalt.clikt.parameters.options.option
|
||||||
|
import com.github.ajalt.clikt.parameters.types.file
|
||||||
|
import com.github.ajalt.clikt.parameters.types.long
|
||||||
|
import com.github.ajalt.clikt.parameters.types.path
|
||||||
|
import com.sun.security.auth.module.UnixSystem
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.io.path.absolute
|
||||||
|
import kotlin.io.path.absolutePathString
|
||||||
|
|
||||||
|
const val LOG4J_CONFIG = """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Configuration status="WARN" packages="com.mojang.util">
|
||||||
|
<Appenders>
|
||||||
|
<Console name="WINDOWS_COMPAT" target="SYSTEM_OUT"></Console>
|
||||||
|
<Queue name="TerminalConsole">
|
||||||
|
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg{nolookups}%n" />
|
||||||
|
</Queue>
|
||||||
|
<RollingRandomAccessFile name="File" fileName="$\{'sys:logPath'}/latest.log" filePattern="$\{'sys:logPath'}/%d{yyyy.MM.dd}.log.gz">
|
||||||
|
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg{nolookups}%n" />
|
||||||
|
<Policies>
|
||||||
|
<TimeBasedTriggeringPolicy />
|
||||||
|
</Policies>
|
||||||
|
<DefaultRolloverStrategy max="7"/>
|
||||||
|
</RollingRandomAccessFile>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Root level="info">
|
||||||
|
<filters>
|
||||||
|
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
|
||||||
|
</filters>
|
||||||
|
<AppenderRef ref="WINDOWS_COMPAT" level="info"/>
|
||||||
|
<AppenderRef ref="File"/>
|
||||||
|
<AppenderRef ref="TerminalConsole" level="info"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>"""
|
||||||
|
|
||||||
|
class DevCommand : CliktCommand("dev") {
|
||||||
|
override fun help(context: Context): String = "Start a dev Server"
|
||||||
|
|
||||||
|
override val treatUnknownOptionsAsArgs = true
|
||||||
|
|
||||||
|
val server by argument().help("Server Template")
|
||||||
|
val port by option("--port").long().defaultLazy { UnixSystem().uid + 1010 }.help("Port for Server")
|
||||||
|
val world by option("--world", "-w").path(canBeFile = false).help("User World")
|
||||||
|
val plugins by option("--plugins", "-p").path(true, canBeFile = false).help("Plugin Dir")
|
||||||
|
val profile by option().flag().help("Add Profiling Arguments")
|
||||||
|
val forceUpgrade by option().flag().help("Force Upgrade")
|
||||||
|
val jar by option().file(true, canBeDir = false).help("Jar File")
|
||||||
|
val jvm by option().file(true, canBeDir = false).help("Java Executable")
|
||||||
|
val jvmArgs by argument().multiple()
|
||||||
|
|
||||||
|
override val printHelpOnEmptyArgs = true
|
||||||
|
|
||||||
|
val workingDir = File("").absoluteFile
|
||||||
|
val log4jConfig = File(workingDir, "log4j2.xml")
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
val args = mutableListOf<String>()
|
||||||
|
|
||||||
|
val serverDirectory = File(workingDir, server)
|
||||||
|
val serverDir =
|
||||||
|
if (serverDirectory.exists() && serverDirectory.isDirectory) serverDirectory else File(workingDir, server)
|
||||||
|
|
||||||
|
if (isVelocity(server)) {
|
||||||
|
runServer(args, jvmArgs, listOf(jar?.absolutePath ?: File("/jar/Velocity.jar").absolutePath), serverDir)
|
||||||
|
} else {
|
||||||
|
setLogConfig(args)
|
||||||
|
val version = findVersion(server) ?: throw CliktError("Unknown Server Version")
|
||||||
|
val worldFile = world?.absolute()?.toFile() ?: File(serverDir, "devtempworld")
|
||||||
|
val jarFile = jar?.absolutePath ?: additionalVersions[server]?.let { supportedVersionJars[it] } ?: supportedVersionJars[version]
|
||||||
|
?: throw CliktError("Unknown Server Version")
|
||||||
|
|
||||||
|
if (!worldFile.exists()) {
|
||||||
|
val templateFile = File(serverDir, "Bauwelt")
|
||||||
|
if (!templateFile.exists()) {
|
||||||
|
throw CliktError("World Template not found!")
|
||||||
|
}
|
||||||
|
templateFile.copyRecursively(worldFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
val devFile = File("/configs/DevServer/${System.getProperty("user.name")}.$port.$version")
|
||||||
|
if (System.getProperty("user.name") != "minecraft") {
|
||||||
|
devFile.createNewFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
runServer(
|
||||||
|
args, jvmArgs, listOf(
|
||||||
|
jarFile,
|
||||||
|
*(if (forceUpgrade) arrayOf("-forceUpgrade") else arrayOf()),
|
||||||
|
"--port", port.toString(),
|
||||||
|
"--level-name", worldFile.name,
|
||||||
|
"--world-dir", workingDir.absolutePath,
|
||||||
|
"--nogui",
|
||||||
|
*(if (plugins != null) arrayOf("--plugins", plugins!!.absolutePathString()) else arrayOf())
|
||||||
|
), serverDir
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
devFile.delete()
|
||||||
|
} catch (_: Exception) { /* ignored */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val jvmDefaultParams = arrayOf(
|
||||||
|
"-Xmx1G",
|
||||||
|
"-Xgc:excessiveGCratio=80",
|
||||||
|
"-Xsyslog:none",
|
||||||
|
"-Xtrace:none",
|
||||||
|
"-Xnoclassgc",
|
||||||
|
"-Xdisableexplicitgc",
|
||||||
|
"-XX:+AlwaysPreTouch",
|
||||||
|
"-XX:+CompactStrings",
|
||||||
|
"-XX:-HeapDumpOnOutOfMemory",
|
||||||
|
"-XX:+ExitOnOutOfMemoryError"
|
||||||
|
)
|
||||||
|
|
||||||
|
val jvmArgOverrides = arrayOf("--add-opens", "java.base/jdk.internal.misc=ALL-UNNAMED")
|
||||||
|
|
||||||
|
val supportedVersionJars = mapOf(
|
||||||
|
8 to "/jars/paper-1.8.8.jar",
|
||||||
|
9 to "/jars/spigot-1.9.4.jar",
|
||||||
|
10 to "/jars/paper-1.10.2.jar",
|
||||||
|
12 to "/jars/spigot-1.12.2.jar",
|
||||||
|
14 to "/jars/spigot-1.14.4.jar",
|
||||||
|
15 to "/jars/spigot-1.15.2.jar",
|
||||||
|
18 to "/jars/paper-1.18.2.jar",
|
||||||
|
19 to "/jars/paper-1.19.3.jar",
|
||||||
|
20 to "/jars/paper-1.20.1.jar",
|
||||||
|
21 to "/jars/paper-1.21.6.jar"
|
||||||
|
)
|
||||||
|
|
||||||
|
val additionalVersions = mapOf(
|
||||||
|
"Tutorial" to 15,
|
||||||
|
"Lobby" to 20
|
||||||
|
)
|
||||||
|
|
||||||
|
fun findVersion(server: String): Int? = server.dropWhile { !it.isDigit() }.toIntOrNull()
|
||||||
|
|
||||||
|
fun isJava8(server: String): Boolean = findVersion(server)?.let { it <= 10 } ?: false
|
||||||
|
|
||||||
|
fun isVelocity(server: String): Boolean = server.endsWith("Velocity")
|
||||||
|
|
||||||
|
fun setLogConfig(args: MutableList<String>) {
|
||||||
|
args += "-DlogPath=${workingDir.absolutePath}/logs"
|
||||||
|
args += "-Dlog4j.configurationFile=${log4jConfig.absolutePath}"
|
||||||
|
|
||||||
|
if (!log4jConfig.exists()) {
|
||||||
|
log4jConfig.writeText(LOG4J_CONFIG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runServer(args: List<String>, jvmArgs: List<String>, cmd: List<String>, serverDir: File) {
|
||||||
|
val process = ProcessBuilder(
|
||||||
|
jvm?.absolutePath ?: if (isJava8(server)) "/usr/lib/jvm/openj9-8/bin/java" else "java",
|
||||||
|
*jvmArgs.toTypedArray(),
|
||||||
|
*args.toTypedArray(),
|
||||||
|
*jvmDefaultParams,
|
||||||
|
*(if (isJava8(server)) arrayOf() else jvmArgOverrides),
|
||||||
|
*(if (profile) arrayOf("-javaagent:/jars/LixfelsProfiler.jar=start") else arrayOf()),
|
||||||
|
"-Xshareclasses:nonfatal,name=$server",
|
||||||
|
"-jar",
|
||||||
|
*cmd.toTypedArray()
|
||||||
|
).directory(serverDir).inheritIO().start()
|
||||||
|
Runtime.getRuntime().addShutdownHook(Thread { if (process.isAlive) process.destroyForcibly() })
|
||||||
|
process.waitFor()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package de.steamwar.commands.profiler
|
||||||
|
|
||||||
|
import com.github.ajalt.clikt.core.CliktCommand
|
||||||
|
import com.github.ajalt.clikt.core.Context
|
||||||
|
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||||
|
import com.github.ajalt.clikt.parameters.arguments.help
|
||||||
|
import com.github.ajalt.clikt.parameters.arguments.optional
|
||||||
|
import com.github.ajalt.clikt.parameters.options.default
|
||||||
|
import com.github.ajalt.clikt.parameters.options.option
|
||||||
|
import com.github.ajalt.clikt.parameters.types.int
|
||||||
|
|
||||||
|
const val SPARK = "/jars/spark.jar"
|
||||||
|
|
||||||
|
class ProfilerCommand: CliktCommand("profiler") {
|
||||||
|
val pid by argument().help("Process id").int().optional()
|
||||||
|
val port by option("--port", "-p").int().default(8543)
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
if (pid != null) {
|
||||||
|
ProcessBuilder()
|
||||||
|
.command("java", "-jar", SPARK, pid.toString(), "port=$port")
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
|
||||||
|
Thread.sleep(1000)
|
||||||
|
|
||||||
|
ProcessBuilder()
|
||||||
|
.command("ssh", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", "-p", port.toString(), "spark@localhost")
|
||||||
|
.inheritIO()
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
} else {
|
||||||
|
ProcessBuilder()
|
||||||
|
.command("java", "-jar", SPARK)
|
||||||
|
.inheritIO()
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun help(context: Context): String = "Start a profiler"
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package de.steamwar.commands.user
|
||||||
|
|
||||||
|
import com.github.ajalt.clikt.core.CliktCommand
|
||||||
|
import com.github.ajalt.clikt.core.Context
|
||||||
|
|
||||||
|
class UserCommand: CliktCommand("user") {
|
||||||
|
override fun run() = Unit
|
||||||
|
override fun help(context: Context): String = "User related commands"
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package de.steamwar.commands.user
|
||||||
|
|
||||||
|
import com.github.ajalt.clikt.core.CliktCommand
|
||||||
|
import com.github.ajalt.clikt.core.CliktError
|
||||||
|
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||||
|
import com.github.ajalt.clikt.parameters.arguments.help
|
||||||
|
import com.github.ajalt.mordant.table.table
|
||||||
|
import de.steamwar.db.findUser
|
||||||
|
import de.steamwar.db.useDb
|
||||||
|
import de.steamwar.sql.Punishment
|
||||||
|
import de.steamwar.sql.SessionTable
|
||||||
|
import de.steamwar.sql.SteamwarUser
|
||||||
|
import de.steamwar.sql.Team
|
||||||
|
import org.jetbrains.exposed.v1.core.eq
|
||||||
|
import org.jetbrains.exposed.v1.jdbc.selectAll
|
||||||
|
import java.time.Duration
|
||||||
|
|
||||||
|
class UserInfoCommand : CliktCommand("info") {
|
||||||
|
val userId by argument().help("Id, Name, UUID or DiscordId")
|
||||||
|
val user by lazy { findUser(userId) ?: throw CliktError("User not found") }
|
||||||
|
|
||||||
|
override val printHelpOnEmptyArgs = true
|
||||||
|
|
||||||
|
override fun run() = useDb {
|
||||||
|
val sessions =
|
||||||
|
SessionTable.selectAll().where { SessionTable.userId eq user.id.value }
|
||||||
|
.map { it[SessionTable.startTime] to it[SessionTable.endTime] }
|
||||||
|
|
||||||
|
val totalPlayed = sessions.sumOf { Duration.between(it.first, it.second).toMinutes() } / 60.0
|
||||||
|
val firstJoin = sessions.minByOrNull { it.first }?.first
|
||||||
|
val lastJoin = sessions.maxByOrNull { it.second }?.second
|
||||||
|
|
||||||
|
val punishments = Punishment.getAllPunishmentsOfPlayer(user.id.value)
|
||||||
|
|
||||||
|
echo(
|
||||||
|
table {
|
||||||
|
body {
|
||||||
|
row("Name", user.userName)
|
||||||
|
row("UUID", user.uuid)
|
||||||
|
row("Team", Team.byId(user.team).teamName)
|
||||||
|
row("Leader", user.leader)
|
||||||
|
row("Locale", user.locale)
|
||||||
|
row("Beigetreten am", firstJoin)
|
||||||
|
row("Zuletzt gesehen am", lastJoin)
|
||||||
|
row("Spielzeit", totalPlayed.toString() + "h")
|
||||||
|
row("Punishments", if (punishments.isEmpty()) "Keine" else table {
|
||||||
|
header { row("Typ", "Ersteller", "Von", "Bis", "Grund") }
|
||||||
|
body {
|
||||||
|
punishments.map {
|
||||||
|
row(
|
||||||
|
it.type,
|
||||||
|
SteamwarUser.byId(it.punisher)?.userName ?: it.punisher,
|
||||||
|
it.startTime.toString(),
|
||||||
|
if (it.perma) "Perma" else it.endTime.toString(),
|
||||||
|
it.reason
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user