Compare commits

..

2 Commits

Author SHA1 Message Date
YoyoNow 026937bc7b Merge branch 'main' into VelocityCore/NoEvent
SteamWarCI Build successful
2025-12-03 14:07:02 +01:00
YoyoNow 771c77247a Add Punishment.PunishmentType.NoEvent
SteamWarCI Build successful
2025-12-01 15:52:15 +01:00
1048 changed files with 34474 additions and 22729 deletions
-60
View File
@@ -1,60 +0,0 @@
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.
-1
View File
@@ -1 +0,0 @@
blank_issues_enabled: true
@@ -1,17 +0,0 @@
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.
-193
View File
@@ -1,193 +0,0 @@
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
-149
View File
@@ -1,149 +0,0 @@
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 clean build --no-daemon --no-build-cache --refresh-dependencies
- 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 "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'"
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mkdir -p '$DEPLOY_PATH/upload'"
scp -i ~/.ssh/deploy_key -P "$port" deploy/* "${DEPLOY_USER}@${DEPLOY_HOST}:$DEPLOY_PATH/upload"
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "rm -f '$DEPLOY_PATH'/*.jar '$DEPLOY_PATH'/*.zip"
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "mv '$DEPLOY_PATH'/upload/* '$DEPLOY_PATH'"
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "rm -r '$DEPLOY_PATH/upload'"
ssh -i ~/.ssh/deploy_key -p "$port" "${DEPLOY_USER}@${DEPLOY_HOST}" "chmod o-w '$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"
-76
View File
@@ -1,76 +0,0 @@
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"
+1 -2
View File
@@ -20,5 +20,4 @@ lib
/WebsiteBackend/data
/WebsiteBackend/logs
/WebsiteBackend/skins
/WebsiteBackend/config.json
/WebsiteBackend/sessions
/WebsiteBackend/config.json
+35
View File
@@ -0,0 +1,35 @@
/*
* 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)
}
@@ -0,0 +1,239 @@
/*
* 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();
}
}
@@ -0,0 +1,129 @@
/*
* 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);
}
}
@@ -0,0 +1,43 @@
/*
* 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);
}
}
@@ -0,0 +1,51 @@
/*
* 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;
}
}
@@ -17,11 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bausystem.region;
package de.steamwar.bausystem.utils;
public interface RegionDataStore {
void save();
void load(RegionData regionData);
default void delete() {
}
public class TickListener15 implements TickListener {
}
@@ -0,0 +1,140 @@
/*
* 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);
}
}
}
@@ -0,0 +1,131 @@
/*
* 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));
}
}
}
@@ -0,0 +1,76 @@
/*
* 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;
}
}
}
@@ -0,0 +1,124 @@
/*
* 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);
}
}
+35
View File
@@ -0,0 +1,35 @@
/*
* 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)
}
@@ -0,0 +1,135 @@
/*
* 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);
}
}
@@ -0,0 +1,51 @@
/*
* 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,7 +1,7 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2024 SteamWar.de-Serverteam
* 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
@@ -21,24 +21,17 @@ plugins {
steamwar.java
}
tasks.compileJava {
options.isWarnings = false
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
dependencies {
compileOnly(libs.classindex)
annotationProcessor(libs.classindex)
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
compileOnly(libs.paperapi)
compileOnly(libs.axiom)
compileOnly(libs.authlib)
compileOnly(libs.viaapi)
compileOnly(libs.nms)
compileOnly(libs.fawe)
implementation(libs.luaj)
compileOnly(libs.nms19)
}
@@ -0,0 +1,134 @@
/*
* 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);
}
}
@@ -0,0 +1,51 @@
/*
* 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;
}
}
@@ -0,0 +1,50 @@
/*
* 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;
}
}
+36
View File
@@ -0,0 +1,36 @@
/*
* 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)
}
@@ -0,0 +1,136 @@
/*
* 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);
}
}
@@ -0,0 +1,43 @@
/*
* 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);
}
}
}
}
@@ -0,0 +1,51 @@
/*
* 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;
}
}
+36
View File
@@ -0,0 +1,36 @@
/*
* 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)
}
@@ -0,0 +1,133 @@
/*
* 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()
);
}
}
@@ -0,0 +1,46 @@
/*
* 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;
}
}
@@ -0,0 +1,150 @@
/*
* 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;
}
}
+4 -7
View File
@@ -26,8 +26,8 @@ tasks.compileJava {
}
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
dependencies {
@@ -35,14 +35,11 @@ dependencies {
annotationProcessor(libs.classindex)
compileOnly(project(":SpigotCore", "default"))
compileOnly(libs.spigotapi)
compileOnly(libs.axiom)
compileOnly(libs.authlib)
compileOnly(libs.paperapi)
compileOnly(libs.nms)
compileOnly(libs.fawe)
compileOnly(libs.netty)
compileOnly(libs.fawe18)
implementation(libs.luaj)
implementation(files("$projectDir/../libs/YAPION-SNAPSHOT.jar"))
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -34,22 +34,23 @@ import de.steamwar.bausystem.features.world.BauScoreboard;
import de.steamwar.bausystem.linkage.BauGuiItem;
import de.steamwar.bausystem.region.RegionSystem;
import de.steamwar.bausystem.utils.ScoreboardElement;
import de.steamwar.bausystem.utils.TickListener;
import de.steamwar.bausystem.utils.TickManager;
import de.steamwar.bausystem.worlddata.WorldData;
import de.steamwar.command.AbstractValidator;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.core.Core;
import de.steamwar.core.CRIUSleepEvent;
import de.steamwar.core.WorldEditRendererCUIEditor;
import de.steamwar.core.WorldIdentifier;
import de.steamwar.linkage.AbstractLinker;
import de.steamwar.linkage.SpigotLinker;
import de.steamwar.message.Message;
import de.steamwar.providers.BauServerInfo;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.GameRule;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
@@ -62,7 +63,7 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.logging.Level;
public class BauSystem extends JavaPlugin {
public class BauSystem extends JavaPlugin implements Listener {
// This should be treated as final!
public static Message MESSAGE;
@@ -120,24 +121,28 @@ public class BauSystem extends JavaPlugin {
} catch (AbstractLinker.LinkException e) {
getLogger().log(Level.SEVERE, "Could not link a class.", e);
Bukkit.shutdown();
return;
}
TickListener.impl.init();
TraceManager.instance.init();
TraceRecorder.instance.init();
new WorldEditRendererCUIEditor();
Bukkit.getWorlds().get(0).setGameRule(GameRule.SEND_COMMAND_FEEDBACK, false);
}
String identifier = BauServerInfo.getOwnerUser().getUUID().toString().replace("-", "");
WorldIdentifier.set("bau/" + Core.getVersion() + "/" + identifier);
@EventHandler
public void onCRIUSleep(CRIUSleepEvent event) {
RegionSystem.INSTANCE.save();
}
@Override
public void onDisable() {
linker.unlink();
WorldData.write();
RegionSystem.INSTANCE.save();
Config.getInstance().saveAll();
}
@@ -76,21 +76,13 @@ public class AttributesCopyCommand extends SWCommand {
if (itemStack.getType() == Material.ZOMBIE_HEAD && block.getType() == Material.ZOMBIE_WALL_HEAD) return true;
if (itemStack.getType() == Material.CREEPER_HEAD && block.getType() == Material.CREEPER_WALL_HEAD) return true;
if (itemStack.getType() == Material.DRAGON_HEAD && block.getType() == Material.DRAGON_WALL_HEAD) return true;
if (itemStack.getType() == Material.SKELETON_SKULL && block.getType() == Material.SKELETON_WALL_SKULL) {
return true;
}
if (itemStack.getType() == Material.WITHER_SKELETON_SKULL && block.getType() == Material.WITHER_SKELETON_WALL_SKULL) {
return true;
}
if (itemStack.getType() == Material.SKELETON_SKULL && block.getType() == Material.SKELETON_WALL_SKULL) return true;
if (itemStack.getType() == Material.WITHER_SKELETON_SKULL && block.getType() == Material.WITHER_SKELETON_WALL_SKULL) return true;
if (itemStack.getType() == Material.TORCH && block.getType() == Material.WALL_TORCH) return true;
if (itemStack.getType() == Material.SOUL_TORCH && block.getType() == Material.SOUL_WALL_TORCH) return true;
if (itemStack.getType() == Material.REDSTONE_TORCH && block.getType() == Material.REDSTONE_WALL_TORCH) {
return true;
}
if (itemStack.getType() == Material.REDSTONE_TORCH && block.getType() == Material.REDSTONE_WALL_TORCH) return true;
if (itemStack.getType() == Material.WHEAT_SEEDS && block.getType() == Material.WHEAT) return true;
if (itemStack.getType().name().contains("_BANNER") && block.getType().name().contains("_WALL_BANNER")) {
return true;
}
if (itemStack.getType().name().contains("_BANNER") && block.getType().name().contains("_WALL_BANNER")) return true;
return false;
}
}
@@ -41,7 +41,7 @@ public class AttributesPlaceListener implements Listener {
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ItemStack itemStack = event.getItemInHand();
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) return;
@@ -65,7 +65,7 @@ public class AutostartListener implements Listener {
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!ItemUtils.isItem(event.getItem(), "autostart")) {
return;
}
@@ -89,7 +89,7 @@ public class AutostartListener implements Listener {
if (!(event.getPlayer() instanceof Player)) {
return;
}
if (!Permission.BUILD.hasPermission((Player) event.getPlayer())) return;
if(!Permission.BUILD.hasPermission((Player) event.getPlayer())) return;
if (!ItemUtils.isItem(event.getPlayer().getInventory().getItemInMainHand(), "autostart")) {
return;
}
@@ -104,8 +104,7 @@ public class BackupCommand extends SWCommand {
List<String> lore = Arrays.asList(BauSystem.MESSAGE.parse("BACKUP_LORE", p));
for (int i = 0; i < backups.size(); i++) {
RegionBackups.Backup backup = backups.get(i);
SWItem swItem = new SWItem(Material.BRICK, BauSystem.MESSAGE.parse("BACKUP_ITEM_NAME", p, backup.getName()), lore, false, clickType -> {
});
SWItem swItem = new SWItem(Material.BRICK, BauSystem.MESSAGE.parse("BACKUP_ITEM_NAME", p, backup.getName()), lore, false, clickType -> {});
swItem.getItemStack().setAmount(i + 1);
swListEntries.add(new SWListInv.SWListEntry<>(swItem, backup));
}
@@ -56,7 +56,6 @@ public class BauInfoBauGuiItem extends BauGuiItem {
Region region = Region.getRegion(player.getLocation());
List<String> stringList = new ArrayList<>();
for (Flag flag : Flag.getFlags()) {
if (flag == Flag.CHANGED) continue;
if (!region.getRegionData().has(flag).isApplicable()) continue;
FlagOptional<?> value = region.getRegionData().get(flag);
if (value.isPresent()) {
@@ -58,14 +58,14 @@ public class Countingwand {
}
}
public static ItemStack getWandItem(Player player) {
ItemStack itemStack = new SWItem(Material.STICK, BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_NAME", player), Arrays.asList(BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_LORE1", player), BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_LORE2", player)), false, null).getItemStack();
ItemUtils.setItem(itemStack, "countingwand");
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setCustomModelData(1);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public static ItemStack getWandItem(Player player) {
ItemStack itemStack = new SWItem(Material.STICK, BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_NAME", player), Arrays.asList(BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_LORE1", player), BauSystem.MESSAGE.parse("COUNTINGWAND_ITEM_LORE2", player)), false, null).getItemStack();
ItemUtils.setItem(itemStack, "countingwand");
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setCustomModelData(1);
itemStack.setItemMeta(itemMeta);
return itemStack;
}
public boolean isCountingwand(ItemStack itemStack) {
return ItemUtils.isItem(itemStack, "countingwand");
@@ -28,12 +28,12 @@ import org.bukkit.entity.Player;
@Linked
public class CountingwandCommand extends SWCommand {
public CountingwandCommand() {
super("countingwand", "/countingwand", "cwand", "/cwand", "zollstock", "/zollstock");
}
public CountingwandCommand() {
super("countingwand", "/countingwand", "cwand", "/cwand", "zollstock", "/zollstock");
}
@Register(description = "COUNTINGWAND_COMMAND_HELP")
public void genericCommand(final Player p) {
SWUtils.giveItemToPlayer(p, Countingwand.getWandItem(p));
}
@Register(description = "COUNTINGWAND_COMMAND_HELP")
public void genericCommand(final Player p) {
SWUtils.giveItemToPlayer(p, Countingwand.getWandItem(p));
}
}
@@ -30,24 +30,24 @@ import org.bukkit.inventory.ItemStack;
@Linked
public class CountingwandGuiItem extends BauGuiItem {
public CountingwandGuiItem() {
super(22);
}
public CountingwandGuiItem() {
super(22);
}
@Override
public ItemStack getItem(Player player) {
return Countingwand.getWandItem(player);
}
@Override
public ItemStack getItem(Player player) {
return Countingwand.getWandItem(player);
}
@Override
public boolean click(ClickType click, Player p) {
p.closeInventory();
p.performCommand("countingwand");
return false;
}
@Override
public boolean click(ClickType click, Player p) {
p.closeInventory();
p.performCommand("countingwand");
return false;
}
@Override
public Permission permission() {
return Permission.MEMBER;
}
@Override
public Permission permission() {
return Permission.MEMBER;
}
}
@@ -35,35 +35,35 @@ import java.util.Objects;
@Linked
public class CountingwandListener implements Listener {
@EventHandler
public void onBlockBreak(final BlockBreakEvent event) {
if (!Countingwand.isCountingwand(event.getPlayer().getInventory().getItemInMainHand())) {
return;
}
@EventHandler
public void onBlockBreak(final BlockBreakEvent event) {
if (!Countingwand.isCountingwand(event.getPlayer().getInventory().getItemInMainHand())) {
return;
}
event.setCancelled(true);
Countingwand.checkSelection(Point.fromLocation(event.getBlock().getLocation()), true, event.getPlayer());
}
event.setCancelled(true);
Countingwand.checkSelection(Point.fromLocation(event.getBlock().getLocation()), true, event.getPlayer());
}
@EventHandler
public void onPlayerInteract(final PlayerInteractEvent event) {
if (!Countingwand.isCountingwand(event.getItem())) {
return;
}
@EventHandler
public void onPlayerInteract(final PlayerInteractEvent event) {
if (!Countingwand.isCountingwand(event.getItem())) {
return;
}
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_AIR) {
RayTraceResult rayTraceResult = event.getPlayer().rayTraceBlocks(200, FluidCollisionMode.NEVER);
if (rayTraceResult == null) {
return;
}
Countingwand.checkSelection(Point.fromLocation(Objects.requireNonNull(rayTraceResult.getHitBlock()).getLocation()), event.getAction() == Action.LEFT_CLICK_AIR, event.getPlayer());
return;
}
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_AIR) {
RayTraceResult rayTraceResult = event.getPlayer().rayTraceBlocks(200, FluidCollisionMode.NEVER);
if (rayTraceResult == null) {
return;
}
Countingwand.checkSelection(Point.fromLocation(Objects.requireNonNull(rayTraceResult.getHitBlock()).getLocation()), event.getAction() == Action.LEFT_CLICK_AIR, event.getPlayer());
return;
}
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
event.setCancelled(true);
Countingwand.checkSelection(Point.fromLocation(Objects.requireNonNull(event.getClickedBlock()).getLocation()), false, event.getPlayer());
}
event.setCancelled(true);
Countingwand.checkSelection(Point.fromLocation(Objects.requireNonNull(event.getClickedBlock()).getLocation()), false, event.getPlayer());
}
}
@@ -31,7 +31,10 @@ import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class DesignEndStone {
@@ -53,10 +56,11 @@ public class DesignEndStone {
this.maxY = region.getBuildArea().getMaxPoint(false).getY();
this.maxZ = region.getBuildArea().getMaxPoint(false).getZ();
limited = Arrays.stream(Material.values())
.filter(Material::isBlock)
.filter(material -> !material.isLegacy())
.filter(material -> material.getBlastResistance() > region.getGameModeConfig().Schematic.MaxDesignBlastResistance)
limited = region.getGameModeConfig().Schematic.Limited
.entrySet()
.stream()
.filter(entry -> entry.getValue() == 0)
.flatMap(entry -> entry.getKey().stream())
.collect(Collectors.toSet());
calculateFromBottom = region.getGameModeConfig().Arena.NoFloor;
@@ -1,63 +0,0 @@
/*
* 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);
}
}
}
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.gui.editor;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.gui.BauGUI;
import de.steamwar.bausystem.linkage.BauGuiItem;
import de.steamwar.core.TrickyTrialsWrapper;
import de.steamwar.data.CMDs;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
@@ -73,7 +74,7 @@ public class BauGuiEditor implements Listener {
inv.setItem(mapping.getSize() + 5, new SWItem(Material.BARRIER, BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_TRASH", p), Arrays.asList(BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_TRASH_LORE", p)), false, clickType -> {
}).getItemStack());
inv.setItem(mapping.getSize() + 6, new SWItem(Material.TURTLE_SCUTE, BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_MORE", p)).getItemStack());
inv.setItem(mapping.getSize() + 6, new SWItem(TrickyTrialsWrapper.impl.getTurtleScute(), BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_MORE", p)).getItemStack());
inv.setItem(mapping.getSize() + 8, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("GUI_EDITOR_ITEM_CLOSE", p)).setCustomModelData(CMDs.BACK).getItemStack());
p.openInventory(inv);
@@ -31,7 +31,7 @@ public class HotbarListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerJoin(PlayerJoinEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (allNull(event.getPlayer().getInventory().getContents()) && allNull(event.getPlayer().getInventory().getArmorContents())) {
DefaultHotbar.setHotbar(event.getPlayer());
}
@@ -50,8 +50,7 @@ public class InventoryFillBauGuiItem extends BauGuiItem {
@Override
public ItemStack getItem(Player player) {
String loreKey = Config.getInstance().get(player).getPlainValueOrDefault("inventoryfill", false) ? "OTHER_ITEMS_INVENTORY_FILL_LORE_ACTIVE" : "OTHER_ITEMS_INVENTORY_FILL_LORE_INACTIVE";
return new SWItem(Material.HOPPER, BauSystem.MESSAGE.parse("OTHER_ITEMS_INVENTORY_FILL_NAME", player), Collections.singletonList(BauSystem.MESSAGE.parse(loreKey, player)), false, clickType -> {
}).getItemStack();
return new SWItem(Material.HOPPER, BauSystem.MESSAGE.parse("OTHER_ITEMS_INVENTORY_FILL_NAME", player), Collections.singletonList(BauSystem.MESSAGE.parse(loreKey, player)), false, clickType -> {}).getItemStack();
}
@Override
@@ -39,7 +39,7 @@ public class InventoryFiller implements Listener {
@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
if (!event.getPlayer().isSneaking()) return;
Block block = event.getPlayer().getTargetBlockExact(5);
@@ -61,7 +61,7 @@ public class InventoryFiller implements Listener {
*/
@EventHandler
public void onPlayerItemHeld(PlayerItemHeldEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!Config.getInstance().get(event.getPlayer()).getPlainValueOrDefault("inventoryfill", false)) return;
if (!event.getPlayer().isSneaking()) return;
ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand();
@@ -58,9 +58,9 @@ public class KillcheckerVisualizer {
Material.BLACK_CONCRETE,
};
private static final World WORLD = Bukkit.getWorlds().get(0);
private static final double SURROUND = 4.5;
private final Point minPoint;
private final Point maxPoint;
@@ -104,9 +104,7 @@ public class KillcheckerVisualizer {
Block block = WORLD.getBlockAt(x, y, z);
if (block.getType().isAir()) continue;
String name = block.getType().name();
if (!name.endsWith("_WOOL") && !name.endsWith("_STAINED_GLASS") && !name.endsWith("_CONCRETE") && !name.endsWith("_TERRACOTTA")) {
continue;
}
if (!name.endsWith("_WOOL") && !name.endsWith("_STAINED_GLASS") && !name.endsWith("_CONCRETE") && !name.endsWith("_TERRACOTTA")) continue;
if (name.equals("_GLAZED_TERRACOTTA")) continue;
Cuboid cuboid = create(block.getType(), x, y, z);
cuboids.add(cuboid);
@@ -285,9 +283,7 @@ public class KillcheckerVisualizer {
}
kill.forEach((point, count) -> {
if (rEntities.containsKey(point)) {
if (killCount.get(point) == count && outlinePoints.contains(point) == outlinePointsCacheLast.contains(point)) {
return;
}
if (killCount.get(point) == count && outlinePoints.contains(point) == outlinePointsCacheLast.contains(point)) return;
rEntities.get(point).die();
}
RFallingBlockEntity entity = new RFallingBlockEntity(outlinePoints.contains(point) ? outline : inner, point.toLocation(WORLD, 0.5, 0, 0.5), MATERIALS[Math.min(count - 1, MATERIALS.length) - 1]);
@@ -329,7 +325,7 @@ public class KillcheckerVisualizer {
if (point.getX() < minPoint.getX() || point.getX() > maxPoint.getX()) continue;
if (point.getY() < minPoint.getY() || point.getY() > maxPoint.getY()) continue;
if (point.getZ() < minPoint.getZ() || point.getZ() > maxPoint.getZ()) continue;
if (WORLD.getBlockAt(point.getX() + 1, point.getY(), point.getZ()).getType() == type) {
points.add(new Point(point.getX() + 1, point.getY(), point.getZ()));
}
@@ -71,7 +71,7 @@ public class Loader implements Listener, SWPlayer.Component {
BauSystem.runTaskTimer(BauSystem.getInstance(), () -> {
if (stage != Stage.RUNNING && stage != Stage.SINGLE) return;
if (!Permission.BUILD.hasPermission(p)) return;
if(!Permission.BUILD.hasPermission(p)) return;
if (waitTime > 0) {
waitTime--;
return;
@@ -213,8 +213,7 @@ public class Loader implements Listener, SWPlayer.Component {
};
updateRunnable.run();
SWListInv<LoaderElement> swListInv = new SWListInv<>(p, BauSystem.MESSAGE.parse("LOADER_GUI_TITLE", p), false, list, (clickType, loaderElement) -> {
});
SWListInv<LoaderElement> swListInv = new SWListInv<>(p, BauSystem.MESSAGE.parse("LOADER_GUI_TITLE", p), false, list, (clickType, loaderElement) -> {});
swListInv.setCallback((clickType, entry) -> entry.click(p, () -> {
updateRunnable.run();
swListInv.open();
@@ -364,9 +363,7 @@ public class Loader implements Listener, SWPlayer.Component {
public static int LENGTH = SettingsSorting.values().length;
public abstract Material getMaterial();
public abstract String getName();
public abstract boolean shouldShow(LoaderElement previous, LoaderElement current, LoaderElement next);
}
@@ -41,7 +41,7 @@ public class LoaderScoreboardElement implements ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (!Permission.BUILD.hasPermission(p)) return null;
if(!Permission.BUILD.hasPermission(p)) return null;
Loader loader = Loader.getLoader(p);
if (loader == null) return null;
if (loader.getStage() == Loader.Stage.RUNNING) {
@@ -26,8 +26,6 @@ import java.util.function.Consumer;
public interface LoaderElement {
SWItem menu(Player player);
void execute(Consumer<Long> delay);
void click(Player player, Runnable backAction);
}
@@ -95,8 +95,7 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
};
updateRunnable.run();
SWListInv<Integer> listInv = new SWListInv<>(player, "Interaction Settings", false, entries, (clickType, entry) -> {
});
SWListInv<Integer> listInv = new SWListInv<>(player, "Interaction Settings", false, entries, (clickType, entry) -> {});
listInv.setCallback((clickType, entry) -> {
openIndividualSettingsMenu(player, entry, () -> {
updateRunnable.run();
@@ -151,10 +150,7 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
}
SWInventory swInventory = new SWInventory(player, guiSize, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_TITLE", player));
for (int i = guiSize - 9; i < guiSize; i++) {
swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", clickType -> {
}));
}
for (int i = guiSize - 9; i < guiSize; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7", clickType -> {}));
swInventory.setItem(guiSize - 9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_BACK", player)).setCustomModelData(CMDs.BACK).getItemStack(), clickType -> back.run());
swInventory.setItem(guiSize - 5, new SWItem(Material.WOODEN_AXE, BauSystem.MESSAGE.parse("LOADER_GUI_SETTINGS_COPY", player)).getItemStack(), clickType -> {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("LOADER_GUI_COPY_TITLE", player), "1");
@@ -201,8 +197,7 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
for (int power = 0; power < 16; power++) {
int finalPowerPosition = power;
if (power >= 9) finalPowerPosition++;
SWItem powerItem = new SWItem(Material.REDSTONE, BauSystem.MESSAGE.parse("LOADER_SETTING_POWER", player, power), Arrays.asList(), false, clickType -> {
});
SWItem powerItem = new SWItem(Material.REDSTONE, BauSystem.MESSAGE.parse("LOADER_SETTING_POWER", player, power), Arrays.asList(), false, clickType -> {});
powerItem.getItemStack().setAmount(Math.max(power, 1));
if (extraPower.get(index) == power) powerItem.setEnchanted(true);
@@ -215,8 +210,7 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
}
if (currentElement.hasTicks(this)) {
swInventory.setItem(ticksStart + 3, new SWItem(Material.RED_DYE, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {
}).getItemStack(), clickType -> {
swInventory.setItem(ticksStart + 3, new SWItem(SWItem.getDye(1), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
long ticks = extraTicks.get(index);
ticks -= clickType.isShiftClick() ? 5 : 1;
if (ticks < 1) ticks = 1;
@@ -224,8 +218,7 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
openIndividualSettingsMenu(player, index, back, delete);
});
SWItem ticksItem = new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS", player, extraTicks.get(index)), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)), false, clickType -> {
});
SWItem ticksItem = new SWItem(Material.CLOCK, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS", player, extraTicks.get(index)), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_GUI_CLICK_TO_EDIT", player)), false, clickType -> {});
ticksItem.getItemStack().setAmount((int) Math.min(extraTicks.get(index), 64));
swInventory.setItem(ticksStart + 4, ticksItem.getItemStack(), clickType -> {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_NAME", player), extraTicks.get(index) + "");
@@ -241,8 +234,7 @@ public abstract class LoaderInteractionElement<T extends Enum<T> & LoaderSetting
swAnvilInv.open();
});
swInventory.setItem(ticksStart + 5, new SWItem(Material.LIME_DYE, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {
}).getItemStack(), clickType -> {
swInventory.setItem(ticksStart + 5, new SWItem(SWItem.getDye(10), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
long ticks = extraTicks.get(index);
ticks += clickType.isShiftClick() ? 5 : 1;
extraTicks.set(index, ticks);
@@ -28,13 +28,10 @@ import java.util.function.Consumer;
public interface LoaderSettingsEnum<T, P extends LoaderInteractionElement<E>, E extends Enum<E> & LoaderSettingsEnum<T, P, E>> {
int getPos();
SWItem menu(Player player, P parent, int power, long ticks);
default boolean hasPower(P parent) {
return false;
}
default boolean hasTicks(P parent) {
return false;
}
@@ -63,8 +63,7 @@ public class LoaderWait implements LoaderElement {
for (int i = 9; i < 18; i++) swInventory.setItem(i, new SWItem(Material.GRAY_STAINED_GLASS_PANE, "§7"));
swInventory.setItem(9, new SWItem(Material.ARROW, BauSystem.MESSAGE.parse("LOADER_GUI_WAIT_BACK", player)).setCustomModelData(CMDs.BACK).getItemStack(), clickType -> backAction.run());
swInventory.setItem(3, new SWItem(Material.RED_DYE, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {
}).getItemStack(), clickType -> {
swInventory.setItem(3, new SWItem(SWItem.getDye(1), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_REMOVE_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
delay -= clickType.isShiftClick() ? 5 : 1;
if (delay < 0) delay = 0;
swInventory.setItem(4, menu(player));
@@ -81,8 +80,7 @@ public class LoaderWait implements LoaderElement {
});
swAnvilInv.open();
});
swInventory.setItem(5, new SWItem(Material.LIME_DYE, BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {
}).getItemStack(), clickType -> {
swInventory.setItem(5, new SWItem(SWItem.getDye(10), BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE", player), Arrays.asList(BauSystem.MESSAGE.parse("LOADER_SETTING_TICKS_ADD_ONE_SHIFT", player)), false, clickType -> {}).getItemStack(), clickType -> {
delay += clickType.isShiftClick() ? 5 : 1;
swInventory.setItem(4, menu(player));
});
@@ -146,7 +146,8 @@ public class Loadtimer implements Listener {
if ((stage == Stage.COUNTING || stage == Stage.ACTIVATED)) {
stage = Stage.IGNITION;
ignite = TPSUtils.currentRealTick.get();
if (activate == -1) activate = TPSUtils.currentRealTick.get();
if (activate == -1)
activate = TPSUtils.currentRealTick.get();
if (finishOnActive) {
stage = Stage.END;
print();
@@ -183,7 +184,8 @@ public class Loadtimer implements Listener {
long ignTime = ignite - activate;
long explTime = explode - ignTime - activate;
if (explTime < 0) explTime = loadTime;
if (explTime < 0)
explTime = loadTime;
int finalAllTnt = allTnt;
long finalExplTime = explTime;
@@ -40,18 +40,16 @@ public class LoadtimerCommand extends SWCommand {
public void start(@Validator Player p, TimerMode mode) {
Region r = Region.getRegion(p.getLocation());
if (r.getType().isGlobal()) return;
if (!Loadtimer.hasTimer(r)) {
if (!Loadtimer.hasTimer(r))
Loadtimer.createLoadtimer(r, mode == TimerMode.HALF);
}
}
@Register(value = "stop", description = "LOADTIMER_HELP_STOP")
public void stop(@Validator Player p) {
Region r = Region.getRegion(p.getLocation());
if (r.getType().isGlobal()) return;
if (Loadtimer.hasTimer(r)) {
if (Loadtimer.hasTimer(r))
Loadtimer.getTimer(r).delete();
}
}
public enum TimerMode {
@@ -46,9 +46,8 @@ public class LoadtimerGuiItem extends BauGuiItem {
@Override
public ItemStack getItem(Player player) {
Region r = Region.getRegion(player.getLocation());
if (r.getType().isGlobal()) {
if (r.getType().isGlobal())
return new SWItem(Material.BOWL, BauSystem.MESSAGE.parse("LOADTIMER_GUI_GLOBAL", player)).getItemStack();
}
if (Loadtimer.hasTimer(r)) {
return new SWItem(Material.BOW, BauSystem.MESSAGE.parse("LOADTIMER_GUI_STOP", player)).getItemStack();
} else {
@@ -20,9 +20,9 @@
package de.steamwar.bausystem.features.loadtimer;
import de.steamwar.bausystem.region.Region;
import de.steamwar.core.TrickyTrialsWrapper;
import de.steamwar.linkage.Linked;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
@@ -57,7 +57,7 @@ public class LoadtimerListener implements Listener {
@EventHandler
public void onEntitySpawn(EntitySpawnEvent event) {
if (!getTimers().isEmpty() && event.getEntityType() == EntityType.TNT) {
if (!getTimers().isEmpty() && event.getEntityType() == TrickyTrialsWrapper.impl.getTntEntityType()) {
Region r = Region.getRegion(event.getLocation());
if (hasTimer(r)) {
getTimer(r).onTntSpawn();
@@ -67,7 +67,7 @@ public class LoadtimerListener implements Listener {
@EventHandler
public void onEntityExplode(EntityExplodeEvent event) {
if (!getTimers().isEmpty() && event.getEntityType() == EntityType.TNT) {
if (!getTimers().isEmpty() && event.getEntityType() == TrickyTrialsWrapper.impl.getTntEntityType()) {
Region r = Region.getRegion(event.getLocation());
if (hasTimer(r)) {
getTimer(r).onTntExplode(event);
@@ -19,6 +19,7 @@
package de.steamwar.bausystem.features.observer;
import de.steamwar.Reflection;
import de.steamwar.bausystem.region.Point;
import de.steamwar.core.SWPlayer;
import org.bukkit.Location;
@@ -28,9 +29,8 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.*;
import org.bukkit.block.data.type.Observer;
import org.bukkit.craftbukkit.block.impl.CraftPoweredRail;
import org.bukkit.block.data.type.*;
import org.bukkit.entity.Player;
import java.util.*;
@@ -171,6 +171,7 @@ 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) {
if (checkMaterial(block)) return true;
if (block.getType() == Material.BELL) {
@@ -179,7 +180,7 @@ public class ObserverTracer implements SWPlayer.Component {
return blockData instanceof Door
|| blockData instanceof Gate
|| blockData instanceof CraftPoweredRail
|| craftPoweredRail.isInstance(blockData)
|| blockData instanceof TrapDoor
|| blockData instanceof GlassPane;
}
@@ -46,15 +46,15 @@ public class ObserverTracerListener implements Listener {
public ObserverTracerListener() {
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
if (pair.getPlayer().getGameMode() != GameMode.SPECTATOR) return;
pair.getComponent().show();
if (pair.getKey().getGameMode() != GameMode.SPECTATOR) return;
pair.getValue().show();
});
}, 15L, 15L);
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
if (!enabled.contains(event.getPlayer())) return;
if (event.getClickedBlock() == null) return;
ObserverTracer observerTracer = SWPlayer.of(event.getPlayer()).getComponent(ObserverTracer.class).orElse(null);
@@ -64,7 +64,7 @@ public class ObserverTracerListener implements Listener {
createNew(event);
}
SWPlayer.allWithSingleComponent(ObserverTracer.class).forEach(pair -> {
pair.getComponent().trace();
pair.getValue().trace();
});
}, 1L);
} else {
@@ -28,6 +28,7 @@ import de.steamwar.command.SWCommand;
import de.steamwar.entity.CRay;
import de.steamwar.entity.REntityServer;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import org.bukkit.*;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
@@ -41,6 +42,7 @@ import org.bukkit.util.RayTraceResult;
import java.util.List;
@Linked
@MinVersion(20)
public class RayVisualizerCommand extends SWCommand implements Listener {
private BlockData VISIBLE = Material.LIME_CONCRETE.createBlockData();
@@ -61,9 +63,9 @@ public class RayVisualizerCommand extends SWCommand implements Listener {
}
private boolean locEquals(Location loc1, Location loc2) {
if ((long) (loc1.getX() * 1000) != (long) (loc2.getX() * 1000)) return false;
if ((long) (loc1.getY() * 1000) != (long) (loc2.getY() * 1000)) return false;
if ((long) (loc1.getZ() * 1000) != (long) (loc2.getZ() * 1000)) return false;
if ((long)(loc1.getX() * 1000) != (long)(loc2.getX() * 1000)) return false;
if ((long)(loc1.getY() * 1000) != (long)(loc2.getY() * 1000)) return false;
if ((long)(loc1.getZ() * 1000) != (long)(loc2.getZ() * 1000)) return false;
return true;
}
@@ -63,7 +63,7 @@ public class ColorCommand extends SWCommand {
}
region.getRegionData().set(Flag.COLOR, color);
try {
PasteBuilder pasteBuilder = new PasteBuilder()
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
.ignoreAir(true)
.onlyColors(true)
.color(color);
@@ -36,16 +36,12 @@ public class FireListener implements Listener, ScoreboardElement {
@EventHandler
public void onFireDamage(BlockBurnEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) {
e.setCancelled(true);
}
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) e.setCancelled(true);
}
@EventHandler
public void onFireSpread(BlockSpreadEvent e) {
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) {
e.setCancelled(true);
}
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) e.setCancelled(true);
}
@Override
@@ -60,7 +56,6 @@ public class FireListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getRegionData().has(Flag.FIRE).notVisibleInScoreboard()) return null;
if (region.getRegionData().get(Flag.FIRE).isWithDefault(FireMode.DENY)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.FIRE.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.FIRE).getWithDefault().getChatValue(), p);
}
@@ -44,11 +44,11 @@ public class FreezeCommand extends SWCommand {
}
}
private String getEnableMessage() {
private String getEnableMessage(){
return "REGION_FREEZE_ENABLED";
}
private String getDisableMessage() {
private String getDisableMessage(){
return "REGION_FREEZE_DISABLED";
}
@@ -24,6 +24,8 @@ import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.FreezeMode;
import de.steamwar.bausystem.utils.ScoreboardElement;
import de.steamwar.core.Core;
import de.steamwar.core.TrickyTrialsWrapper;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -31,7 +33,6 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.type.NoteBlock;
import org.bukkit.block.data.type.Switch;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -45,25 +46,11 @@ import org.bukkit.event.player.PlayerInteractEvent;
@Linked
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
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;
e.setCancelled(true);
if (e.getEntityType() == EntityType.TNT) {
if (e.getEntityType() == TrickyTrialsWrapper.impl.getTntEntityType()) {
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
e.getLocation().getBlock().setType(Material.TNT, false);
}, 1L);
@@ -73,9 +60,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler
public void onBlockCanBuild(BlockCanBuildEvent e) {
if (!e.isBuildable()) return;
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) {
return;
}
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return;
if (e.getMaterial() == Material.TNT) {
e.setBuildable(false);
e.getBlock().setType(Material.TNT, false);
@@ -160,6 +145,7 @@ public class FreezeListener implements Listener, ScoreboardElement {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent e) {
if (Core.getVersion() < 19) return;
if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return;
if (Region.getRegion(e.getBlock().getLocation()).getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.ACTIVE)) {
e.setCancelled(true);
@@ -249,7 +235,6 @@ public class FreezeListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getRegionData().has(Flag.FREEZE).notVisibleInScoreboard()) return null;
if (region.getRegionData().get(Flag.FREEZE).isWithDefault(FreezeMode.INACTIVE)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.FREEZE.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.FREEZE).getWithDefault().getChatValue(), p);
}
@@ -25,9 +25,11 @@ import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.ItemMode;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import org.bukkit.entity.Player;
@Linked
@MinVersion(19)
public class ItemsCommand extends SWCommand {
public ItemsCommand() {
@@ -44,11 +46,11 @@ public class ItemsCommand extends SWCommand {
}
}
private String getEnableMessage() {
private String getEnableMessage(){
return "REGION_ITEMS_ENABLED";
}
private String getDisableMessage() {
private String getDisableMessage(){
return "REGION_ITEMS_DISABLED";
}
@@ -25,12 +25,14 @@ import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.region.flags.ItemMode;
import de.steamwar.bausystem.utils.ScoreboardElement;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ItemSpawnEvent;
@Linked
@MinVersion(19)
public class ItemsListener implements Listener, ScoreboardElement {
@EventHandler
@@ -52,7 +54,6 @@ public class ItemsListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getRegionData().has(Flag.ITEMS).notVisibleInScoreboard()) return null;
if (region.getRegionData().get(Flag.ITEMS).isWithDefault(ItemMode.INACTIVE)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.ITEMS.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.ITEMS).getWithDefault().getChatValue(), p);
}
@@ -54,7 +54,6 @@ public class NoGravityListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getRegionData().has(Flag.NO_GRAVITY).notVisibleInScoreboard()) return null;
if (region.getRegionData().get(Flag.NO_GRAVITY).isWithDefault(NoGravityMode.INACTIVE)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.NO_GRAVITY.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.NO_GRAVITY).getWithDefault().getChatValue(), p);
}
@@ -70,7 +70,6 @@ public class ProtectListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getRegionData().has(Flag.PROTECT).notVisibleInScoreboard()) return null;
if (region.getRegionData().get(Flag.PROTECT).isWithDefault(ProtectMode.INACTIVE)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.PROTECT.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.PROTECT).getWithDefault().getChatValue(), p);
}
@@ -30,7 +30,6 @@ import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.util.SelectCommand;
import de.steamwar.bausystem.region.Point;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionHistory;
import de.steamwar.bausystem.region.RegionUtils;
import de.steamwar.bausystem.region.flags.Flag;
import de.steamwar.bausystem.shared.Pair;
@@ -72,10 +71,7 @@ public class RegionCommand extends SWCommand {
@Register(value = "undo", description = "REGION_REGION_HELP_UNDO")
public void undoCommand(@Validator Player p) {
Region region = Region.getRegion(p.getLocation());
if (region.getHistory() == RegionHistory.EMPTY) {
BauSystem.MESSAGE.send("REGION_REGION_NO_REGION", p);
return;
}
if (checkGlobalRegion(region, p)) return;
if (region.getHistory().undo()) {
RegionUtils.message(region, "REGION_REGION_UNDID");
@@ -87,8 +83,7 @@ public class RegionCommand extends SWCommand {
@Register(value = "redo", description = "REGION_REGION_HELP_REDO")
public void redoCommand(@Validator Player p) {
Region region = Region.getRegion(p.getLocation());
if (region.getHistory() == RegionHistory.EMPTY) {
BauSystem.MESSAGE.send("REGION_REGION_NO_REGION", p);
if (checkGlobalRegion(region, p)) {
return;
}
@@ -102,10 +97,10 @@ public class RegionCommand extends SWCommand {
@Register(value = "restore", description = "REGION_REGION_HELP_RESTORE")
public void genericRestoreCommand(@Validator Player p) {
Region region = Region.getRegion(p.getLocation());
if (checkGlobalRegion(region, p)) return;
if(checkGlobalRegion(region, p)) return;
try {
PasteBuilder pasteBuilder = new PasteBuilder()
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
.ignoreAir(true)
.color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, false);
@@ -121,13 +116,13 @@ public class RegionCommand extends SWCommand {
Region region = Region.getRegion(p.getLocation());
if (checkGlobalRegion(region, p)) return;
if (node.isDir()) {
if(node.isDir()) {
BauSystem.MESSAGE.send("ONLY_SCHEMS", p);
return;
}
try {
PasteBuilder pasteBuilder = new PasteBuilder(PasteBuilder.ClipboardProvider.schematic(node))
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.SchematicProvider(node))
.ignoreAir(true)
.color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, false);
@@ -148,7 +143,7 @@ public class RegionCommand extends SWCommand {
BauSystem.MESSAGE.send("REGION_REGION_TP_UNKNOWN", p);
return;
}
p.teleport(region.getBuildArea().getCopyPoint(false).toLocation(p, 0.5, 0, 0.5), PlayerTeleportEvent.TeleportCause.COMMAND);
p.teleport(region.getBuildArea().getCopyPoint().toLocation(p, 0.5, 0, 0.5), PlayerTeleportEvent.TeleportCause.COMMAND);
BauSystem.MESSAGE.send("REGION_REGION_TP_COPY", p);
}
@@ -163,7 +158,7 @@ public class RegionCommand extends SWCommand {
BauSystem.MESSAGE.send("REGION_REGION_TP_UNKNOWN", p);
return;
}
p.teleport(region.getTestblockArea().getCopyPoint(false).toLocation(p, 0.5, 0, 0.5), PlayerTeleportEvent.TeleportCause.COMMAND);
p.teleport(region.getTestblockArea().getCopyPoint().toLocation(p, 0.5, 0, 0.5), PlayerTeleportEvent.TeleportCause.COMMAND);
BauSystem.MESSAGE.send("REGION_REGION_TP_TEST_BLOCK", p);
}
@@ -196,7 +191,7 @@ public class RegionCommand extends SWCommand {
break;
}
Clipboard clipboard = FlatteningWrapper.impl.copy(minPoint, maxPoint, region.getBuildArea().getCopyPoint(false));
Clipboard clipboard = FlatteningWrapper.impl.copy(minPoint, maxPoint, region.getBuildArea().getCopyPoint());
WorldEdit.getInstance()
.getSessionManager()
.get(BukkitAdapter.adapt(p))
@@ -241,13 +236,13 @@ public class RegionCommand extends SWCommand {
}
try (EditSession e = WorldEditUtils.getEditSession(p)) {
Operations.completeBlindly(clipboardHolder.createPaste(e).ignoreAirBlocks(ignoreAir).to(toBlockVector3(region.getBuildArea().getCopyPoint(false))).build());
Operations.completeBlindly(clipboardHolder.createPaste(e).ignoreAirBlocks(ignoreAir).to(toBlockVector3(region.getBuildArea().getCopyPoint())).build());
WorldEditUtils.addToPlayer(p, e);
if (selectPasted) {
Clipboard clipboard = clipboardHolder.getClipboards().get(0);
BlockVector3 minPointSelection = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()).add(toBlockVector3(region.getBuildArea().getCopyPoint(false)));
BlockVector3 maxPointSelection = clipboard.getRegion().getMaximumPoint().subtract(clipboard.getOrigin()).add(toBlockVector3(region.getBuildArea().getCopyPoint(false)));
BlockVector3 minPointSelection = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin()).add(toBlockVector3(region.getBuildArea().getCopyPoint()));
BlockVector3 maxPointSelection = clipboard.getRegion().getMaximumPoint().subtract(clipboard.getOrigin()).add(toBlockVector3(region.getBuildArea().getCopyPoint()));
FlatteningWrapper.impl.setSelection(p, Point.fromBlockVector3(minPointSelection), Point.fromBlockVector3(maxPointSelection));
}
BauSystem.MESSAGE.send("REGION_REGION_PASTE_DONE", p);
@@ -59,9 +59,7 @@ public class RegionListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockPhysics(final BlockPhysicsEvent event) {
if (event.getBlock().getType() != event.getChangedType()) {
RegionListener.tagChangedRegion(event.getBlock().getLocation());
}
if (event.getBlock().getType() != event.getChangedType()) RegionListener.tagChangedRegion(event.getBlock().getLocation());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
@@ -29,6 +29,9 @@ import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.command.SWCommand;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@@ -49,7 +52,7 @@ public class ResetCommand extends SWCommand {
Region region = regionCheck(p);
if (region == null) return;
try {
PasteBuilder pasteBuilder = new PasteBuilder()
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.FileProvider(region.getArea().getResetFile()))
.color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, false);
region.getRegionData().clear();
@@ -60,6 +63,35 @@ public class ResetCommand extends SWCommand {
}
}
@Register(description = "REGION_RESET_HELP_SCHEMATIC")
public void schematicResetCommand(@Validator Player p, SchematicNode node) {
Region region = regionCheck(p);
if (region == null) return;
if (!p.getUniqueId().equals(bauServer.getOwner())) {
if (Punishment.isPunished(SteamwarUser.get(bauServer.getOwner()), Punishment.PunishmentType.NoSchemReceiving, punishment -> BauSystem.MESSAGE.send("REGION_TB_NO_SCHEMRECEIVING", p, punishment.getEndTime()))) {
return;
}
if (Punishment.isPunished(SteamwarUser.get(p.getUniqueId()), Punishment.PunishmentType.NoSchemSharing, punishment -> BauSystem.MESSAGE.send("REGION_TB_NO_SCHEMSHARING", p, punishment.getEndTime()))) {
return;
}
}
if (node.isDir()) {
BauSystem.MESSAGE.send("ONLY_SCHEMS", p);
return;
}
try {
PasteBuilder pasteBuilder = new PasteBuilder(new PasteBuilder.SchematicProvider(node))
.color(region.getRegionData().get(Flag.COLOR).getWithDefault());
region.getArea().reset(pasteBuilder, true);
RegionUtils.message(region, "REGION_RESET_RESETED");
} catch (SecurityException e) {
BauSystem.MESSAGE.send("REGION_RESET_ERROR", p);
Bukkit.getLogger().log(Level.WARNING, "Failed reset", e);
}
}
private Region regionCheck(Player player) {
Region region = Region.getRegion(player.getLocation());
if (region == RegionSystem.INSTANCE.getGlobalRegion()) {
@@ -67,7 +67,11 @@ public class TNTListener implements Listener, ScoreboardElement {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onExplode(EntityExplodeEvent event) {
explode(event.blockList(), event.getEntity() instanceof TNTPrimed);
if (!(event.getEntity() instanceof TNTPrimed)) {
event.blockList().clear();
return;
}
explode(event.blockList(), true);
}
@Override
@@ -82,7 +86,6 @@ public class TNTListener implements Listener, ScoreboardElement {
@Override
public String get(Region region, Player p) {
if (region.getRegionData().has(Flag.TNT).notVisibleInScoreboard()) return null;
if (region.getRegionData().get(Flag.TNT).isWithDefault(TNTMode.ALLOW)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.TNT.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.TNT).getWithDefault().getChatValue(), p);
}
@@ -21,11 +21,9 @@ package de.steamwar.bausystem.features.region;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.config.BauServer;
import de.steamwar.bausystem.region.Point;
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.TestblockMode;
import de.steamwar.bausystem.region.utils.RegionExtensionType;
import de.steamwar.bausystem.utils.PasteBuilder;
import de.steamwar.command.PreviousArguments;
@@ -57,12 +55,12 @@ public class TestblockCommand extends SWCommand {
super("testblock", "tb", "dummy");
}
@Register(description = {"REGION_TB_HELP_RESET", "REGION_TB_HELP_RESET_EXTENSION"})
@Register
public void schematicTestblockCommand(@Validator Player p, TestblockParameterType... testblockParameterTypes) {
schematicTestblockCommand(p, null, testblockParameterTypes);
}
@Register(description = {"REGION_TB_HELP_SCHEMATIC", "REGION_TB_HELP_SCHEMATIC_EXTENSION"})
@Register
public void schematicTestblockCommand(@Validator Player p, @Mapper("withPublic") SchematicNode node, TestblockParameterType... testblockParameterTypes) {
Set<TestblockParameterType> testblockParameterTypesSet = new HashSet<>(Arrays.asList(testblockParameterTypes));
boolean isExtension = testblockParameterTypesSet.contains(TestblockParameterType.EXTENSION);
@@ -74,7 +72,7 @@ public class TestblockCommand extends SWCommand {
resetRegion(p, node, isExtension ? RegionExtensionType.EXTENSION : RegionExtensionType.NORMAL, isIgnoreAir, isOnlyColor, replaceTNT, replaceWater);
}
@Register(value = "default")
@Register(value="default")
public void setTestblockDefault(Player p) {
Region region = regionCheck(p);
if (region == null) return;
@@ -108,7 +106,13 @@ public class TestblockCommand extends SWCommand {
region.getRegionData().setTestblockSchematic(node);
}
PasteBuilder.ClipboardProvider clipboardProvider = node == null ? PasteBuilder.ClipboardProvider.EMPTY : PasteBuilder.ClipboardProvider.schematic(node);
PasteBuilder.ClipboardProvider clipboardProvider;
if (node == null) {
clipboardProvider = new PasteBuilder.FileProvider(region.getTestblockArea().getResetFile());
} else {
clipboardProvider = new PasteBuilder.SchematicProvider(node);
}
try {
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider)
.ignoreAir(ignoreAir)
@@ -169,17 +173,6 @@ public class TestblockCommand extends SWCommand {
private Region regionCheck(Player player) {
Region region = Region.getRegion(player.getLocation());
if (region.getRegionData().has(Flag.TESTBLOCK).isWritable() && region.getRegionData().get(Flag.TESTBLOCK).isWithDefault(TestblockMode.NO_VALUE)) {
Point minPoint = region.getArea().getMinPoint(false);
Point maxPoint = region.getArea().getMaxPoint(false);
// TODO: Check if empty!
int half = minPoint.getZ() + (maxPoint.getZ() - minPoint.getZ()) / 2;
if (player.getLocation().getBlockZ() <= half) {
region.getRegionData().set(Flag.TESTBLOCK, TestblockMode.SOUTH);
} else {
region.getRegionData().set(Flag.TESTBLOCK, TestblockMode.NORTH);
}
}
if (region.getTestblockArea().isEmpty()) {
BauSystem.MESSAGE.send("REGION_TB_NO_REGION", player);
return null;
@@ -1,49 +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.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.TestblockMode;
import de.steamwar.bausystem.utils.ScoreboardElement;
import de.steamwar.linkage.Linked;
import org.bukkit.entity.Player;
@Linked
public class TestblockScoreboardElement implements ScoreboardElement {
@Override
public ScoreboardGroup getGroup() {
return ScoreboardGroup.REGION;
}
@Override
public int order() {
return 6;
}
@Override
public String get(Region region, Player p) {
if (region.getRegionData().has(Flag.TESTBLOCK).notVisibleInScoreboard()) return null;
if (region.getRegionData().get(Flag.TESTBLOCK).is(TestblockMode.NO_VALUE)) return null;
return "§e" + BauSystem.MESSAGE.parse(Flag.TESTBLOCK.getChatValue(), p) + "§8: " + BauSystem.MESSAGE.parse(region.getRegionData().get(Flag.TESTBLOCK).getWithDefault().getChatValue(), p);
}
}
@@ -1,64 +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.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;
}
}
}
@@ -1,60 +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.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().has(Flag.WATER_DESTROY).notVisibleInScoreboard()) return null;
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);
}
}
@@ -50,8 +50,16 @@ public class ResetBauGuiItem extends BauGuiItem {
@Override
public boolean click(ClickType click, Player p) {
p.closeInventory();
resetCommand.genericResetCommand(p);
if (click == ClickType.LEFT) {
p.closeInventory();
resetCommand.genericResetCommand(p);
} else {
SchematicSelector selector = new SchematicSelector(p, SchematicSelector.selectSchematic(), node -> {
p.closeInventory();
resetCommand.schematicResetCommand(p, node);
});
selector.open();
}
return false;
}
@@ -67,7 +67,7 @@ public class ScriptGUI implements Listener {
lore.add(BauSystem.MESSAGE.parse("SCRIPT_ERROR_GUI", player, String.join(":", Arrays.copyOfRange(sp, 1, sp.length))));
}
if (!lore.isEmpty()) {
if(!lore.isEmpty()) {
lore.add("");
}
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_1", player));
@@ -75,17 +75,16 @@ public class ScriptGUI implements Listener {
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_3", player));
lore.add(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_LORE_4", player));
entries.add(new SWListInv.SWListEntry<>(new SWItem(Material.ENCHANTED_BOOK, script.getName(), new ArrayList<>(lore), false, clickType -> {
}), script));
entries.add(new SWListInv.SWListEntry<>(new SWItem(Material.ENCHANTED_BOOK, script.getName(), new ArrayList<>(lore), false, clickType -> {}), script));
lore.clear();
});
SWListInv<Script> inv = new SWListInv<>(player, BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_NAME", player), false, entries, (clickType, script) -> {
ItemStack itemStack = ScriptHelper.getScriptItem(script, clickType.isRightClick());
if (clickType == ClickType.MIDDLE) {
if(clickType == ClickType.MIDDLE) {
player.openBook(itemStack);
} else if (!clickType.isShiftClick()) {
} else if(!clickType.isShiftClick()) {
script.delete();
ScriptRunner.updateGlobalScript(player);
open(player, itemStack);
@@ -94,14 +93,14 @@ public class ScriptGUI implements Listener {
}
});
inv.setItem(49, Material.HOPPER, BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_ADD_NAME", player), Collections.singletonList(BauSystem.MESSAGE.parse("SCRIPT_MENU_GUI_ITEM_ADD_LORE", player)), false, click -> {
if (player.getOpenInventory().getCursor() != null) {
if(player.getOpenInventory().getCursor() != null) {
ItemStack cursor = player.getOpenInventory().getCursor();
if (!(cursor.getItemMeta() instanceof BookMeta)) {
if(!(cursor.getItemMeta() instanceof BookMeta)) {
return;
}
BookMeta meta = (BookMeta) cursor.getItemMeta();
if (meta == null) {
if(meta == null) {
return;
}
@@ -109,14 +108,14 @@ public class ScriptGUI implements Listener {
}
});
inv.open();
if (setCursor != null) {
if(setCursor != null) {
player.getOpenInventory().setCursor(setCursor);
}
}
private static void saveWithName(Player player, BookMeta meta, String name) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if (name != null && Script.list(user).stream().noneMatch(script -> script.getName().equalsIgnoreCase(name))) {
if(name != null && Script.list(user).stream().noneMatch(script -> script.getName().equalsIgnoreCase(name))) {
Script.create(user, name, ScriptHelper.getScriptString(meta.getPages()));
player.getOpenInventory().setCursor(null);
ScriptRunner.updateGlobalScript(player);
@@ -36,7 +36,7 @@ public class ScriptHelper {
public static ItemStack getScriptItem(Script script, boolean writeable) {
ItemStack itemStack = new ItemStack(writeable ? Material.WRITABLE_BOOK : Material.WRITTEN_BOOK);
BookMeta meta = (BookMeta) itemStack.getItemMeta();
if (!writeable) {
if(!writeable) {
meta.setTitle(script.getName());
meta.setAuthor(SteamwarUser.byId(script.getUserId()).getUserName());
}
@@ -44,7 +44,7 @@ public class ScriptListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onLeftClick(PlayerInteractEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ItemStack item = event.getItem();
if (item == null || FlatteningWrapper.impl.isNoBook(item) || item.getItemMeta() == null) {
@@ -72,7 +72,7 @@ public class ScriptListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
ScriptRunner.updateGlobalScript(event.getPlayer());
}
@@ -102,7 +102,7 @@ public class ScriptRunner {
.orElse(Collections.emptyMap())
.getOrDefault(event, Collections.emptyList());
if (luaFunctions.isEmpty()) {
if (event == SteamWarGlobalLuaPlugin.EventType.DoubleSwap) {
if(event == SteamWarGlobalLuaPlugin.EventType.DoubleSwap) {
player.performCommand("gui");
}
return;
@@ -32,7 +32,7 @@ public class CommandListener implements Listener {
@EventHandler
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
if(!Permission.BUILD.hasPermission(event.getPlayer())) return;
String[] split = event.getMessage().split(" ");
ScriptRunner.ScriptData scriptData = SWPlayer.of(event.getPlayer()).getComponentOrDefault(ScriptRunner.ScriptData.class, ScriptRunner.ScriptData::new);
if (scriptData.getCalledCommands().contains(split[0])) return;
@@ -26,10 +26,10 @@ import de.steamwar.bausystem.features.script.lua.SteamWarGlobalLuaPlugin;
import de.steamwar.bausystem.features.script.lua.libs.StorageLib;
import de.steamwar.bausystem.region.Region;
import de.steamwar.core.SWPlayer;
import de.steamwar.core.TrickyTrialsWrapper;
import de.steamwar.linkage.Linked;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -51,8 +51,8 @@ public class EventListener implements Listener {
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), () -> {
long millis = System.currentTimeMillis();
SWPlayer.allWithSingleComponent(ScriptRunner.ScriptData.class)
.filter(pair -> millis - pair.getComponent().getLastF() > 200)
.forEach(pair -> pair.getComponent().setLastF(Long.MAX_VALUE));
.filter(pair -> millis - pair.getValue().getLastF() > 200)
.forEach(pair -> pair.getValue().setLastF(Long.MAX_VALUE));
}, 1, 1);
}
@@ -141,7 +141,7 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onEntitySpawn(EntitySpawnEvent event) {
if (event.getEntityType() != EntityType.TNT) {
if (event.getEntityType() != TrickyTrialsWrapper.impl.getTntEntityType()) {
return;
}
Region tntRegion = Region.getRegion(event.getLocation());
@@ -156,7 +156,7 @@ public class EventListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onEntityExplode(EntityExplodeEvent event) {
if (event.getEntityType() != EntityType.TNT) {
if (event.getEntityType() != TrickyTrialsWrapper.impl.getTntEntityType()) {
return;
}
Region tntRegion = Region.getRegion(event.getLocation());
@@ -72,7 +72,7 @@ public interface LuaLib {
default LuaTable toPos(Point point) {
if (point == null) return LuaTable.tableOf();
return LuaValue.tableOf(new LuaValue[]{
return LuaValue.tableOf(new LuaValue[] {
LuaValue.valueOf("x"), LuaValue.valueOf(point.getX()),
LuaValue.valueOf("y"), LuaValue.valueOf(point.getY()),
LuaValue.valueOf("z"), LuaValue.valueOf(point.getZ())
@@ -82,9 +82,7 @@ public interface LuaLib {
default Class<? extends LuaLib> parent() {
return null;
}
String name();
LuaTable get(Player player);
@AllArgsConstructor
@@ -105,33 +103,27 @@ public interface LuaLib {
try {
consumer.accept(luaValue.toboolean());
return NIL;
} catch (Exception ingored) {
}
} catch (Exception ingored) {}
try {
consumer.accept((long) luaValue.toint());
return NIL;
} catch (Exception ignored) {
}
} catch (Exception ignored) {}
try {
consumer.accept(luaValue.toint());
return NIL;
} catch (Exception ignored) {
}
} catch (Exception ignored) {}
try {
consumer.accept(luaValue.todouble());
return NIL;
} catch (Exception ignored) {
}
} catch (Exception ignored) {}
try {
consumer.accept((float) luaValue.todouble());
return NIL;
} catch (Exception ignored) {
}
} catch (Exception ignored) {}
try {
consumer.accept(luaValue.toString());
return NIL;
} catch (Exception ignored) {
}
} catch (Exception ignored) {}
throw new LuaError("Invalid lua type: " + luaValue.typename());
} catch (Throwable throwable) {
throw new LuaError("Error in '" + name + "' " + throwable.getMessage());
@@ -84,12 +84,12 @@ public class RandomLib implements LuaLib {
private static class NextBool extends VarArgFunction {
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
return LuaValue.valueOf(random.nextBoolean());
@Override
public Varargs invoke(Varargs args) {
if (args.narg() == 0) {
return LuaValue.valueOf(random.nextBoolean());
}
throw new LuaError("Invalid number of arguments for random.nextBoolean() zero expected got " + args.narg());
}
throw new LuaError("Invalid number of arguments for random.nextBoolean() zero expected got " + args.narg());
}
}
}
@@ -78,13 +78,13 @@ public class RegionLib implements LuaLib {
Loader loader = Loader.getLoader(player);
table.set("loader", getter(() -> loader == null ? "OFF" : loader.getStage().name()));
table.set("copyPoint", getter(() -> toPos(region.get().getBuildArea().getCopyPoint(false))));
table.set("copyPoint", getter(() -> toPos(region.get().getBuildArea().getCopyPoint())));
table.set("minPointBuild", getter(() -> toPos(region.get().getBuildArea().getMinPoint(false))));
table.set("maxPointBuild", getter(() -> toPos(region.get().getBuildArea().getMinPoint(false))));
table.set("minPointBuildExtension", getter(() -> toPos(region.get().getBuildArea().getMinPoint(true))));
table.set("maxPointBuildExtension", getter(() -> toPos(region.get().getBuildArea().getMinPoint(true))));
table.set("testblockPoint", getter(() -> toPos(region.get().getTestblockArea().getCopyPoint(false))));
table.set("testblockPoint", getter(() -> toPos(region.get().getTestblockArea().getCopyPoint())));
table.set("minPointTestblock", getter(() -> toPos(region.get().getTestblockArea().getMinPoint(false))));
table.set("maxPointTestblock", getter(() -> toPos(region.get().getTestblockArea().getMinPoint(false))));
table.set("minPointTestblockExtension", getter(() -> toPos(region.get().getTestblockArea().getMinPoint(true))));
@@ -22,6 +22,7 @@ package de.steamwar.bausystem.features.script.lua.libs;
import com.google.gson.*;
import de.steamwar.bausystem.region.Region;
import de.steamwar.bausystem.region.RegionSystem;
import de.steamwar.core.Core;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.api.Disable;
import de.steamwar.linkage.api.Enable;
@@ -55,6 +56,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
@Override
public void enable() {
if (Core.getVersion() <= 15) return;
if (!storageDirectory.exists()) storageDirectory.mkdirs();
try {
@@ -62,8 +64,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
jsonObject.keySet().forEach(key -> {
GLOBAL_STORAGE.put(key, fromJson(jsonObject.get(key)));
});
} catch (Exception e) {
}
} catch (Exception e) {}
File regionStorageDirectory = new File(storageDirectory, "region");
regionStorageDirectory.mkdirs();
@@ -76,8 +77,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
});
Region region = RegionSystem.INSTANCE.getRegion(UUID.fromString(regionStorage.getName().substring(0, regionStorage.getName().length() - ".json".length()))).orElse(null);
REGION_STORAGE.put(region, map);
} catch (Exception e) {
}
} catch (Exception e) {}
}
File playerStorageDirectory = new File(storageDirectory, "player");
@@ -91,8 +91,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
});
SteamwarUser steamwarUser = SteamwarUser.byId(Integer.parseInt(playerStorage.getName().substring(0, playerStorage.getName().length() - ".json".length())));
PLAYER_STORAGE.put(steamwarUser.getUUID(), map);
} catch (Exception e) {
}
} catch (Exception e) {}
}
}
@@ -108,12 +107,10 @@ public class StorageLib implements LuaLib, Enable, Disable {
if (jsonPrimitive.isNumber()) {
try {
return LuaValue.valueOf(jsonPrimitive.getAsInt());
} catch (NumberFormatException e) {
}
} catch (NumberFormatException e) {}
try {
return LuaValue.valueOf(jsonPrimitive.getAsDouble());
} catch (NumberFormatException e) {
}
} catch (NumberFormatException e) {}
}
if (jsonPrimitive.isString()) {
return LuaValue.valueOf(jsonPrimitive.getAsString());
@@ -135,13 +132,13 @@ public class StorageLib implements LuaLib, Enable, Disable {
@Override
public void disable() {
if (Core.getVersion() <= 15) return;
if (!storageDirectory.exists()) storageDirectory.mkdirs();
try {
FileWriter fileWriter = new FileWriter(new File(storageDirectory, "global.json"));
gson.toJson(toJson(GLOBAL_STORAGE), fileWriter);
fileWriter.close();
} catch (IOException e) {
}
} catch (IOException e) {}
File regionStorageDirectory = new File(storageDirectory, "region");
regionStorageDirectory.mkdirs();
@@ -150,8 +147,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
FileWriter fileWriter = new FileWriter(new File(regionStorageDirectory, entry.getKey().getID().toString() + ".json"));
gson.toJson(toJson(entry.getValue()), fileWriter);
fileWriter.close();
} catch (IOException e) {
}
} catch (IOException e) {}
}
File playerStorageDirectory = new File(storageDirectory, "player");
@@ -161,8 +157,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
FileWriter fileWriter = new FileWriter(new File(playerStorageDirectory, SteamwarUser.get(entry.getKey()).getId() + ".json"));
gson.toJson(toJson(entry.getValue()), fileWriter);
fileWriter.close();
} catch (IOException e) {
}
} catch (IOException e) {}
}
}
@@ -182,16 +177,13 @@ public class StorageLib implements LuaLib, Enable, Disable {
}
try {
return new JsonPrimitive(luaValue.checkboolean());
} catch (Exception e) {
}
} catch (Exception e) {}
try {
return new JsonPrimitive(luaValue.checkint());
} catch (Exception e) {
}
} catch (Exception e) {}
try {
return new JsonPrimitive(luaValue.checkdouble());
} catch (Exception e) {
}
} catch (Exception e) {}
if (luaValue.isstring()) {
return new JsonPrimitive(luaValue.tojstring());
@@ -204,8 +196,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
if (value == null) continue;
try {
jsonObject.add(key.checkjstring(), value);
} catch (Exception e) {
}
} catch (Exception e) {}
}
return jsonObject;
}
@@ -261,9 +252,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
}
}
};
}
;
};
});
storageLib.set("global", global);
@@ -308,9 +297,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
}
}
};
}
;
};
});
storageLib.set("player", playerStorage);
@@ -359,9 +346,7 @@ public class StorageLib implements LuaLib, Enable, Disable {
}
}
};
}
;
};
});
storageLib.set("region", regionStorage);
@@ -45,7 +45,7 @@ public class WorldEditLib implements LuaLib {
return selection;
}, o -> {
LuaTable selection = o.checktable();
if (selection.length() != 2) {
if(selection.length() != 2) {
throw new IllegalArgumentException("selection must have exactly 2 elements");
}
@@ -26,9 +26,7 @@ import org.bukkit.entity.Player;
public interface BlockDataConfiguration<T extends BlockData> {
void previous();
void next();
SWItem get(Player player);
void apply(T copied, T worldOriginal);
@@ -29,12 +29,14 @@ import de.steamwar.command.TypeMapper;
import de.steamwar.command.TypeValidator;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.LinkedInstance;
import de.steamwar.linkage.MinVersion;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Collection;
@Linked
@MinVersion(19)
public class SimulatorCommand extends SWCommand {
@LinkedInstance
@@ -20,6 +20,7 @@
package de.steamwar.bausystem.features.simulator;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.Reflection;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.Permission;
import de.steamwar.bausystem.SWUtils;
@@ -44,9 +45,9 @@ import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RFallingBlockEntity;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -67,9 +68,13 @@ import java.util.function.Function;
import java.util.stream.Collectors;
@Linked
@MinVersion(19)
public class SimulatorCursor implements Listener {
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, REntityServer> cursors = Collections.synchronizedMap(new HashMap<>());
@@ -84,9 +89,9 @@ public class SimulatorCursor implements Listener {
calcCursor(player);
return object;
};
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, function);
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Rot.class, function);
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, function);
TinyProtocol.instance.addFilter(position, function);
TinyProtocol.instance.addFilter(look, function);
TinyProtocol.instance.addFilter(positionLook, function);
}
@EventHandler
@@ -293,9 +298,8 @@ public class SimulatorCursor implements Listener {
if (!player.isSneaking()) {
pos.setX(pos.getBlockX() + 0.5);
if (face == null || face.getModY() == 0) {
if (face == null || face.getModY() == 0)
pos.setY(pos.getBlockY() + 0.0);
}
pos.setZ(pos.getBlockZ() + 0.5);
}
@@ -32,6 +32,7 @@ import de.steamwar.bausystem.utils.ItemUtils;
import de.steamwar.inventory.SWAnvilInv;
import de.steamwar.inventory.SWItem;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import de.steamwar.linkage.api.Enable;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -46,6 +47,7 @@ import java.util.*;
import java.util.stream.Collectors;
@Linked
@MinVersion(19)
public class SimulatorStorage implements Enable {
public static final File simulatorsDir = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "simulators");
@@ -28,6 +28,7 @@ import de.steamwar.entity.REntity;
import de.steamwar.entity.REntityServer;
import de.steamwar.entity.RFallingBlockEntity;
import de.steamwar.linkage.Linked;
import de.steamwar.linkage.MinVersion;
import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -74,6 +75,7 @@ public class SimulatorWatcher {
}
@Linked
@MinVersion(19)
public static class QuitListener implements Listener {
@EventHandler
@@ -120,10 +120,6 @@ public abstract class SimulatorElement<T extends SimulatorPhase> {
}
public abstract String getType();
public void saveExtra(YAPIONObject elementObject) {
}
public void loadExtra(YAPIONObject elementObject) {
}
public void saveExtra(YAPIONObject elementObject) {}
public void loadExtra(YAPIONObject elementObject) {}
}
@@ -37,10 +37,6 @@ public abstract class SimulatorPhase {
protected int order = 0;
public abstract void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd);
public void saveExtra(YAPIONObject phaseObject) {
}
public void loadExtra(YAPIONObject phaseObject) {
}
public void saveExtra(YAPIONObject phaseObject) {}
public void loadExtra(YAPIONObject phaseObject) {}
}

Some files were not shown because too many files have changed in this diff Show More