forked from SteamWar/SteamWar
Cleanup BauSystem
This commit is contained in:
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.nms15)
|
|
||||||
compileOnly(libs.worldedit15)
|
|
||||||
}
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
|
||||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
|
||||||
import com.sk89q.worldedit.function.mask.Mask2D;
|
|
||||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
|
||||||
import com.sk89q.worldedit.function.operation.Operations;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
|
||||||
import com.sk89q.worldedit.world.World;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
|
||||||
import de.steamwar.bausystem.region.Point;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
import org.bukkit.block.data.Waterlogged;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.function.BiPredicate;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class FlatteningWrapper15 implements FlatteningWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNoBook(ItemStack item) {
|
|
||||||
return item.getType() != Material.WRITABLE_BOOK && item.getType() != Material.WRITTEN_BOOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Set<Material> unpushable = new HashSet<>(Arrays.asList(Material.BARRIER, Material.BEACON, Material.COMMAND_BLOCK, Material.CHAIN_COMMAND_BLOCK, Material.REPEATING_COMMAND_BLOCK, Material.ENCHANTING_TABLE, Material.END_GATEWAY, Material.END_PORTAL, Material.ENDER_CHEST, Material.GRINDSTONE, Material.JIGSAW, Material.JUKEBOX, Material.NETHER_PORTAL, Material.OBSIDIAN, Material.STRUCTURE_VOID, Material.BARREL, Material.BEEHIVE, Material.BEE_NEST, Material.BLAST_FURNACE, Material.BREWING_STAND, Material.CHEST, Material.DAYLIGHT_DETECTOR, Material.DISPENSER, Material.DROPPER, Material.FURNACE, Material.HOPPER, Material.LECTERN, Material.SMOKER, Material.TRAPPED_CHEST));
|
|
||||||
|
|
||||||
// TODO: FLOWER
|
|
||||||
private static final Set<Material> breaking = new HashSet<>(Arrays.asList(Material.BAMBOO, Material.CACTUS, Material.CAKE, Material.CARVED_PUMPKIN, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.COBWEB, Material.COCOA, Material.DRAGON_EGG, Material.FIRE, Material.FLOWER_POT, Material.JACK_O_LANTERN, Material.LADDER, Material.LAVA, Material.LAVA, Material.LEVER, Material.LILY_PAD, Material.MELON, Material.NETHER_WART, Material.PUMPKIN, Material.COMPARATOR, Material.REDSTONE_WIRE, Material.REPEATER, Material.TORCH, Material.STRUCTURE_VOID, Material.SCAFFOLDING, Material.SEA_PICKLE, Material.SNOW, Material.SUGAR_CANE, Material.TORCH, Material.TRIPWIRE, Material.TRIPWIRE_HOOK, Material.TURTLE_EGG, Material.VINE, Material.WATER, Material.WHEAT));
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isUnpusheable(Material material) {
|
|
||||||
if (unpushable.contains(material)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
String name = material.name();
|
|
||||||
return name.contains("BANNER") || name.contains("SIGN");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isBreakingOnPush(Material material) {
|
|
||||||
if (breaking.contains(material)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
String name = material.name();
|
|
||||||
return name.contains("BED") || name.contains("BUTTON") || name.contains("CARPET") || (name.contains("DOOR") && !name.contains("TRAPDOOR")) || name.contains("HEAD") || name.contains("LEAVES") || name.contains("MUSHROOM") || name.contains("PRESSURE_PLATE") || name.contains("SHULKER_BOX");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isWorldEditCommand(String command) {
|
|
||||||
if (command.startsWith("/")) {
|
|
||||||
command = command.replaceFirst("/", "");
|
|
||||||
}
|
|
||||||
command = command.toLowerCase();
|
|
||||||
return WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getCommandManager().containsCommand(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final WorldEditPlugin WORLDEDIT_PLUGIN = Objects.requireNonNull((WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"));
|
|
||||||
private static final World BUKKITWORLD = new BukkitWorld(Bukkit.getWorlds().get(0));
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSelection(Player p, Point minPoint, Point maxPoint) {
|
|
||||||
WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, minPoint.toBlockVector3(), maxPoint.toBlockVector3()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Clipboard loadSchematic(File file) {
|
|
||||||
Clipboard clipboard;
|
|
||||||
try (ClipboardReader reader = Objects.requireNonNull(ClipboardFormats.findByFile(file)).getReader(new FileInputStream(file))) {
|
|
||||||
clipboard = reader.read();
|
|
||||||
} catch (NullPointerException | IOException e) {
|
|
||||||
throw new SecurityException("Bausystem schematic not found", e);
|
|
||||||
}
|
|
||||||
return clipboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EditSession paste(PasteBuilder pasteBuilder) {
|
|
||||||
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
|
|
||||||
Clipboard clipboard = pasteBuilder.getClipboard();
|
|
||||||
|
|
||||||
if (!pasteBuilder.getMappers().isEmpty()) {
|
|
||||||
BlockVector3 minimum = clipboard.getRegion().getMinimumPoint();
|
|
||||||
for (int x = 0; x < clipboard.getDimensions().getX(); x++) {
|
|
||||||
for (int y = 0; y < clipboard.getDimensions().getY(); y++) {
|
|
||||||
for (int z = 0; z < clipboard.getDimensions().getZ(); z++) {
|
|
||||||
BlockVector3 pos = minimum.add(x, y, z);
|
|
||||||
pasteBuilder.getMappers().forEach(mapper -> mapper.accept(clipboard, pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AtomicReference<BlockVector3> pastePoint = new AtomicReference<>();
|
|
||||||
if (!pasteBuilder.getPredicates().isEmpty()) {
|
|
||||||
e.setMask(new Mask() {
|
|
||||||
@Override
|
|
||||||
public boolean test(BlockVector3 blockVector3) {
|
|
||||||
BaseBlock block = clipboard.getFullBlock(blockVector3.subtract(pastePoint.get()).add(clipboard.getRegion().getMinimumPoint()));
|
|
||||||
String blockName = block.getBlockType().toString().toLowerCase();
|
|
||||||
for (BiPredicate<BaseBlock, String> predicate : pasteBuilder.getPredicates()) {
|
|
||||||
if (!predicate.test(block, blockName)) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mask copy() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Mask2D toMask2D() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ClipboardHolder ch = new ClipboardHolder(clipboard);
|
|
||||||
BlockVector3 dimensions = clipboard.getDimensions();
|
|
||||||
BlockVector3 v = BlockVector3.at(pasteBuilder.getPastPoint().getX(), pasteBuilder.getPastPoint().getY(), pasteBuilder.getPastPoint().getZ());
|
|
||||||
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
|
||||||
if (pasteBuilder.isRotate()) {
|
|
||||||
ch.setTransform(new AffineTransform().rotateY(180));
|
|
||||||
v = v.add(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset.multiply(-1, 1, -1)).subtract(0, 0, 1);
|
|
||||||
} else {
|
|
||||||
v = v.subtract(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset);
|
|
||||||
}
|
|
||||||
pastePoint.set(v);
|
|
||||||
|
|
||||||
if (pasteBuilder.isReset()) {
|
|
||||||
e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
|
|
||||||
if (pasteBuilder.getWaterLevel() != 0) {
|
|
||||||
e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3().withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(pasteBuilder.isIgnoreAir()).build());
|
|
||||||
return e;
|
|
||||||
} catch (WorldEditException e) {
|
|
||||||
throw new SecurityException(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Clipboard copy(Point minPoint, Point maxPoint, Point copyPoint) {
|
|
||||||
BukkitWorld bukkitWorld = new BukkitWorld(Bukkit.getWorlds().get(0));
|
|
||||||
CuboidRegion region = new CuboidRegion(bukkitWorld, minPoint.toBlockVector3(), maxPoint.toBlockVector3());
|
|
||||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
|
|
||||||
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(bukkitWorld, -1)) {
|
|
||||||
ForwardExtentCopy copy = new ForwardExtentCopy(
|
|
||||||
e, region, clipboard, region.getMinimumPoint()
|
|
||||||
);
|
|
||||||
|
|
||||||
copy.setCopyingEntities(false);
|
|
||||||
copy.setCopyingBiomes(false);
|
|
||||||
|
|
||||||
Operations.complete(copy);
|
|
||||||
clipboard.setOrigin(copyPoint.toBlockVector3());
|
|
||||||
return clipboard;
|
|
||||||
} catch (WorldEditException e) {
|
|
||||||
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean backup(Point minPoint, Point maxPoint, File file) {
|
|
||||||
Clipboard clipboard = copy(minPoint, maxPoint, minPoint);
|
|
||||||
try (ClipboardWriter writer = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) {
|
|
||||||
writer.write(clipboard);
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {
|
|
||||||
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean inWater(org.bukkit.World world, Vector tntPosition) {
|
|
||||||
Block block = world.getBlockAt(tntPosition.getBlockX(), tntPosition.getBlockY(), tntPosition.getBlockZ());
|
|
||||||
if (block.getType() == Material.WATER)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
BlockData data = block.getBlockData();
|
|
||||||
if (!(data instanceof Waterlogged))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return ((Waterlogged) data).isWaterlogged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import net.minecraft.server.v1_15_R1.*;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NMSWrapper15 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(((CraftPlayer) player).getHandle().playerInteractManager, EnumGamemode.getById(gameMode.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.b();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.getItemStack()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<Integer> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, int.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
((CraftPlayer) player).getHandle().abilities.mayBuild = true;
|
|
||||||
((CraftPlayer) player).getHandle().abilities.canInstantlyBuild = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.GRASS_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
net.minecraft.server.v1_15_R1.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
|
|
||||||
NBTTagCompound tag = nmsItem.getTag();
|
|
||||||
if (tag != null && tag.hasKey("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = tag.getCompound("BlockEntityTag");
|
|
||||||
if (blockTag.hasKey("Items")) {
|
|
||||||
return drillDown(blockTag.getList("Items", 10), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(NBTTagList items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (NBTBase nbtBase : items) {
|
|
||||||
if (!(nbtBase instanceof NBTTagCompound))
|
|
||||||
continue;
|
|
||||||
NBTTagCompound slot = (NBTTagCompound) nbtBase;
|
|
||||||
if (slot.hasKey("tag")) {
|
|
||||||
invalid += slot.getByte("Count");
|
|
||||||
NBTTagCompound iTag = slot.getCompound("tag");
|
|
||||||
if (iTag.hasKey("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = iTag.getCompound("BlockEntityTag");
|
|
||||||
if (blockTag.hasKey("Items")) {
|
|
||||||
invalid = drillDown(blockTag.getList("Items", 10), layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalid > threshold)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
|
|
||||||
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
|
|
||||||
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
|
|
||||||
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
|
|
||||||
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
|
|
||||||
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
PacketPlayOutExplosion packetPlayOutExplosion = (PacketPlayOutExplosion) packet;
|
|
||||||
return new PacketPlayOutExplosion(a.get(packetPlayOutExplosion), b.get(packetPlayOutExplosion), c.get(packetPlayOutExplosion), d.get(packetPlayOutExplosion), e.get(packetPlayOutExplosion), Vec3D.a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
|
|
||||||
public class PlaceItemWrapper15 implements PlaceItemWrapper {
|
|
||||||
|
|
||||||
public PlaceItemWrapper15() {
|
|
||||||
for (Material material : Material.values()) {
|
|
||||||
if (!material.isBlock()) continue;
|
|
||||||
if (material.isLegacy()) continue;
|
|
||||||
|
|
||||||
String nonWall = material.name().replace("_WALL_", "").replace("WALL_", "").replace("_WALL", "");
|
|
||||||
try {
|
|
||||||
Material nonWallMaterial = Material.valueOf(nonWall);
|
|
||||||
if (nonWallMaterial != material && nonWallMaterial.isItem() && !nonWallMaterial.isBlock()) {
|
|
||||||
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(nonWallMaterial, material);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ITEM_MATERIAL_TO_BLOCK_MATERIAL.put(Material.REDSTONE, Material.REDSTONE_WIRE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import net.minecraft.server.v1_15_R1.EntityPlayer;
|
|
||||||
import net.minecraft.server.v1_15_R1.PacketPlayInFlying;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper15 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (Float.isNaN(packetPlayInFlying.a(Float.NaN))) {
|
|
||||||
entityPlayer.e(packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0));
|
|
||||||
} else {
|
|
||||||
entityPlayer.setLocation(packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0), packetPlayInFlying.a(0F), packetPlayInFlying.b(0F));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
Object packet = Reflection.newInstance(teleportPacket);
|
|
||||||
teleportEntity.set(packet, player.getEntityId());
|
|
||||||
teleportPosition.set(packet, packetPlayInFlying.a(0.0), packetPlayInFlying.b(0.0), packetPlayInFlying.c(0.0),
|
|
||||||
Float.isNaN(packetPlayInFlying.a(Float.NaN)) ? player.getLocation().getYaw() : packetPlayInFlying.a(0.0F),
|
|
||||||
Float.isNaN(packetPlayInFlying.b(Float.NaN)) ? player.getLocation().getPitch() : packetPlayInFlying.b(0.0F));
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
public class TickListener15 implements TickListener {
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.bausystem.region.Region;
|
|
||||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
|
||||||
import de.steamwar.bausystem.utils.tps.TPSFreezeUtils;
|
|
||||||
import de.steamwar.bausystem.utils.tps.TPSLimitUtils;
|
|
||||||
import de.steamwar.core.TPSWarpUtils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
public class TickManager15 implements TickManager, Listener {
|
|
||||||
|
|
||||||
private static float currentTPSLimit = 20;
|
|
||||||
private boolean currentlyStepping = false;
|
|
||||||
private float currentLimit;
|
|
||||||
private int stepsTotal;
|
|
||||||
private int stepsLeft;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFreeze() {
|
|
||||||
return TPSFreezeUtils.isCanFreeze();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTickRate(float tickRate) {
|
|
||||||
if (currentlyStepping) {
|
|
||||||
currentlyStepping = false;
|
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
|
||||||
BossBarService.instance.remove(player, Region.getGlobalRegion(), "TickStep");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
TPSWarpUtils.warp(tickRate);
|
|
||||||
if (currentTPSLimit == 0 && tickRate != 0) {
|
|
||||||
TPSFreezeUtils.unfreeze();
|
|
||||||
}
|
|
||||||
currentTPSLimit = tickRate;
|
|
||||||
if (tickRate == 0) {
|
|
||||||
TPSLimitUtils.unlimit();
|
|
||||||
TPSFreezeUtils.freeze();
|
|
||||||
} else if (tickRate < 20.0) {
|
|
||||||
TPSLimitUtils.limit(tickRate);
|
|
||||||
} else if (tickRate >= 20) {
|
|
||||||
TPSLimitUtils.unlimit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFrozen() {
|
|
||||||
return TPSFreezeUtils.frozen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFreeze(boolean freeze) {
|
|
||||||
if (freeze) {
|
|
||||||
setTickRate(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stepTicks(int ticks) {
|
|
||||||
currentLimit = 0;
|
|
||||||
setTickRate(20);
|
|
||||||
stepsLeft = ticks;
|
|
||||||
stepsTotal = ticks;
|
|
||||||
currentlyStepping = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sprintTicks(int ticks) {
|
|
||||||
currentLimit = currentTPSLimit;
|
|
||||||
setTickRate(4000);
|
|
||||||
stepsLeft = ticks;
|
|
||||||
stepsTotal = ticks;
|
|
||||||
currentlyStepping = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSprinting() {
|
|
||||||
return currentlyStepping && currentTPSLimit > 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isStepping() {
|
|
||||||
return currentlyStepping && currentTPSLimit <= 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getTickRate() {
|
|
||||||
return currentTPSLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlockTpsPacket(boolean block) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalTicks() {
|
|
||||||
return stepsTotal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDoneTicks() {
|
|
||||||
return stepsTotal - stepsLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getRemainingTicks() {
|
|
||||||
return stepsLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onTickEnd(TickEndEvent event) {
|
|
||||||
if (!currentlyStepping) return;
|
|
||||||
stepsLeft--;
|
|
||||||
if (stepsLeft <= 0) {
|
|
||||||
setTickRate(currentLimit);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils.tps;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.core.BountifulWrapper;
|
|
||||||
import de.steamwar.core.ChatWrapper;
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.entity.TNTPrimed;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
class PacketCache {
|
|
||||||
|
|
||||||
private static List<Object> packets = new ArrayList<>();
|
|
||||||
private static Set<Entity> entities = new HashSet<>();
|
|
||||||
private static BukkitTask task = null;
|
|
||||||
|
|
||||||
private static Class<?> vec3dClass = Reflection.getClass("net.minecraft.world.phys.Vec3");
|
|
||||||
private static Reflection.Field<Object> zeroVec3d = (Reflection.Field<Object>) Reflection.getField(vec3dClass, vec3dClass, 0);
|
|
||||||
private static Object ZERO_VEC3D = zeroVec3d.get(null);
|
|
||||||
private static Class<?> velocityPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket");
|
|
||||||
private static Reflection.Constructor velocityPacketConstructor = Reflection.getConstructor(velocityPacketClass, int.class, vec3dClass);
|
|
||||||
|
|
||||||
private static Class<?> teleportPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket");
|
|
||||||
private static Class<?> entityClass = Reflection.getClass("net.minecraft.world.entity.Entity");
|
|
||||||
private static Reflection.Constructor teleportPacketConstructor = Reflection.getConstructor(teleportPacketClass, entityClass);
|
|
||||||
|
|
||||||
private static Class<?> craftEntityClass = Reflection.getClass("org.bukkit.craftbukkit.entity.CraftEntity");
|
|
||||||
private static Reflection.Method getHandle = Reflection.getMethod(craftEntityClass, "getHandle");
|
|
||||||
|
|
||||||
private static Object noGravityDataWatcher = BountifulWrapper.impl.getDataWatcherObject(5, Boolean.class);
|
|
||||||
private static Object fuseDataWatcher = BountifulWrapper.impl.getDataWatcherObject(8, Integer.class);
|
|
||||||
|
|
||||||
public void continuousSendCache() {
|
|
||||||
if (task != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
createPackets();
|
|
||||||
task = new BukkitRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
_sendCache();
|
|
||||||
}
|
|
||||||
}.runTaskTimer(Core.getInstance(), 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendCache() {
|
|
||||||
if (task != null) {
|
|
||||||
task.cancel();
|
|
||||||
task = null;
|
|
||||||
}
|
|
||||||
_sendCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _sendCache() {
|
|
||||||
createPackets();
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
|
||||||
for (Object packet : packets) {
|
|
||||||
TinyProtocol.instance.sendPacket(player, packet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearCache() {
|
|
||||||
packets.clear();
|
|
||||||
entities.clear();
|
|
||||||
|
|
||||||
if (task != null) {
|
|
||||||
task.cancel();
|
|
||||||
task = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createPackets() {
|
|
||||||
if (entities.stream().anyMatch(Entity::isDead)) {
|
|
||||||
entities.clear();
|
|
||||||
packets.clear();
|
|
||||||
}
|
|
||||||
List<Entity> entities = Bukkit.getWorlds().get(0).getEntities().stream()
|
|
||||||
.filter(e -> !(e instanceof Player))
|
|
||||||
.filter(e -> PacketCache.entities.add(e))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
packets.add(teleportPacketConstructor.invoke(getHandle.invoke(entity)));
|
|
||||||
}
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
packets.add(velocityPacketConstructor.invoke(entity.getEntityId(), ZERO_VEC3D));
|
|
||||||
}
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), noGravityDataWatcher, true));
|
|
||||||
}
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
if (!(entity instanceof TNTPrimed)) continue;
|
|
||||||
TNTPrimed tnt = (TNTPrimed) entity;
|
|
||||||
int fuse = tnt.getFuseTicks();
|
|
||||||
packets.add(ChatWrapper.impl.getDataWatcherPacket(entity.getEntityId(), fuseDataWatcher, fuse - (fuse % 5) + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils.tps;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.World;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class TPSFreezeUtils {
|
|
||||||
|
|
||||||
private static Reflection.Field<Boolean> fieldAccessor;
|
|
||||||
@Getter
|
|
||||||
private static final boolean canFreeze;
|
|
||||||
|
|
||||||
private static final Reflection.Method getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("org.bukkit.craftbukkit.CraftWorld"), "getHandle", null);
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private static boolean frozen = false;
|
|
||||||
|
|
||||||
private static final World world = Bukkit.getWorlds().get(0);
|
|
||||||
|
|
||||||
static {
|
|
||||||
Reflection.Field<Boolean> fieldAccessor;
|
|
||||||
try {
|
|
||||||
fieldAccessor = Reflection.getField(Reflection.getClass("net.minecraft.server.level.ServerLevel"), "freezed", boolean.class);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
fieldAccessor = null;
|
|
||||||
}
|
|
||||||
canFreeze = fieldAccessor != null;
|
|
||||||
TPSFreezeUtils.fieldAccessor = fieldAccessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void freeze() {
|
|
||||||
setFreeze(world, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unfreeze() {
|
|
||||||
setFreeze(world, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean frozen() {
|
|
||||||
return canFreeze && frozen;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setFreeze(World world, boolean state) {
|
|
||||||
if (canFreeze) {
|
|
||||||
fieldAccessor.set(getWorldHandle.invoke(world), state);
|
|
||||||
if (state) {
|
|
||||||
PacketCache.continuousSendCache();
|
|
||||||
} else {
|
|
||||||
PacketCache.clearCache();
|
|
||||||
}
|
|
||||||
frozen = state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils.tps;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
|
||||||
import de.steamwar.core.Core;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class TPSLimitUtils {
|
|
||||||
|
|
||||||
private static long currentTime = System.nanoTime();
|
|
||||||
private static BukkitTask tpsLimiter = null;
|
|
||||||
private static Queue<Runnable> packetQueue = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
public void unlimit() {
|
|
||||||
if (tpsLimiter != null) tpsLimiter.cancel();
|
|
||||||
tpsLimiter = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void limit(double tps) {
|
|
||||||
if (tpsLimiter != null) tpsLimiter.cancel();
|
|
||||||
|
|
||||||
double delay = 20 / tps;
|
|
||||||
int loops = (int) Math.ceil(delay);
|
|
||||||
long sleepDelay = (long) (50 * delay) / loops;
|
|
||||||
|
|
||||||
tpsLimiter = Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> {
|
|
||||||
PacketCache.sendCache();
|
|
||||||
for (int i = 0; i < loops; i++) {
|
|
||||||
sleepUntilNextTick(sleepDelay);
|
|
||||||
PacketCache.sendCache();
|
|
||||||
while (true) {
|
|
||||||
Runnable runnable = packetQueue.poll();
|
|
||||||
if (runnable == null) break;
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PacketCache.clearCache();
|
|
||||||
}, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sleepUntilNextTick(long neededDelta) {
|
|
||||||
long lastTime = currentTime;
|
|
||||||
currentTime = System.nanoTime();
|
|
||||||
|
|
||||||
long timeDelta = (currentTime - lastTime) / 1000000;
|
|
||||||
if (neededDelta - timeDelta < 0) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(neededDelta - timeDelta);
|
|
||||||
currentTime = System.nanoTime();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
static {
|
|
||||||
long timeInterval = 50;
|
|
||||||
final long[] lastTime = {System.currentTimeMillis()};
|
|
||||||
final double[] tps = {20.0};
|
|
||||||
Bukkit.getScheduler().runTaskTimer(Core.getInstance(), () -> {
|
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
if (currentTime > lastTime[0]) {
|
|
||||||
tps[0] = (double)timeInterval / (double)(currentTime - lastTime[0]) * 20.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastTime[0] = currentTime;
|
|
||||||
|
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
|
||||||
SWUtils.sendToActionbar(player, String.valueOf((int) (tps[0] * 10.0) / 10.0));
|
|
||||||
});
|
|
||||||
}, timeInterval / 50L, timeInterval / 50L);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
private static final Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
|
||||||
private static final Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
|
||||||
static {
|
|
||||||
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
|
||||||
if (tpsLimiter != null) {
|
|
||||||
Object object = PlayerMovementWrapper.impl.convertToOut(player, o);
|
|
||||||
packetQueue.add(() -> {
|
|
||||||
PlayerMovementWrapper.impl.setPosition(player, o);
|
|
||||||
Bukkit.getOnlinePlayers().forEach(p -> {
|
|
||||||
if (p == player) return;
|
|
||||||
TinyProtocol.instance.sendPacket(p, object);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
};
|
|
||||||
TinyProtocol.instance.addFilter(position, positionSetter);
|
|
||||||
TinyProtocol.instance.addFilter(positionLook, positionSetter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.spigotapi)
|
|
||||||
compileOnly(libs.nms18)
|
|
||||||
}
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import net.minecraft.nbt.NBTBase;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.nbt.NBTTagList;
|
|
||||||
import net.minecraft.network.protocol.game.*;
|
|
||||||
import net.minecraft.server.level.PlayerInteractManager;
|
|
||||||
import net.minecraft.world.level.EnumGamemode;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NMSWrapper18 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(((CraftPlayer) player).getHandle().d, EnumGamemode.a(gameMode.getValue()));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.b();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.c()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, PacketPlayOutGameStateChange.d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
((CraftPlayer) player).getHandle().fs().d = true;
|
|
||||||
((CraftPlayer) player).getHandle().fs().e = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.DIRT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
|
|
||||||
NBTTagCompound tag = nmsItem.t();
|
|
||||||
if (tag != null && tag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = tag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
return drillDown(blockTag.c("Items", 10), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(NBTTagList items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (NBTBase nbtBase : items) {
|
|
||||||
if (!(nbtBase instanceof NBTTagCompound))
|
|
||||||
continue;
|
|
||||||
NBTTagCompound slot = (NBTTagCompound) nbtBase;
|
|
||||||
if (slot.e("tag")) {
|
|
||||||
invalid += slot.f("Count");
|
|
||||||
NBTTagCompound iTag = slot.p("tag");
|
|
||||||
if (iTag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = iTag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
invalid = drillDown(blockTag.c("Items", 10), layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalid > threshold)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
|
|
||||||
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
|
|
||||||
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
|
|
||||||
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
|
|
||||||
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
|
|
||||||
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
PacketPlayOutExplosion packetPlayOutExplosion = (PacketPlayOutExplosion) packet;
|
|
||||||
return new PacketPlayOutExplosion(a.get(packetPlayOutExplosion), b.get(packetPlayOutExplosion), c.get(packetPlayOutExplosion), d.get(packetPlayOutExplosion), e.get(packetPlayOutExplosion), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
|
||||||
import net.minecraft.server.level.EntityPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper18 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (packetPlayInFlying.h) {
|
|
||||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
|
||||||
} else {
|
|
||||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
Object packet = Reflection.newInstance(teleportPacket);
|
|
||||||
teleportEntity.set(packet, player.getEntityId());
|
|
||||||
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getYaw() : packetPlayInFlying.d,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getPitch() : packetPlayInFlying.e);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.spigotapi)
|
|
||||||
compileOnly(libs.paperapi)
|
|
||||||
|
|
||||||
compileOnly(libs.nms19)
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import net.minecraft.nbt.NBTBase;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.nbt.NBTTagList;
|
|
||||||
import net.minecraft.network.protocol.game.*;
|
|
||||||
import net.minecraft.server.level.PlayerInteractManager;
|
|
||||||
import net.minecraft.world.level.EnumGamemode;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NMSWrapper19 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(((CraftPlayer) player).getHandle().d, EnumGamemode.a(gameMode.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.b();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.c()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, PacketPlayOutGameStateChange.d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
((CraftPlayer) player).getHandle().fF().d = true;
|
|
||||||
((CraftPlayer) player).getHandle().fF().e = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.DIRT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
|
|
||||||
NBTTagCompound tag = nmsItem.v();
|
|
||||||
if (tag != null && tag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = tag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
return drillDown(blockTag.c("Items", 10), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(NBTTagList items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (NBTBase nbtBase : items) {
|
|
||||||
if (!(nbtBase instanceof NBTTagCompound))
|
|
||||||
continue;
|
|
||||||
NBTTagCompound slot = (NBTTagCompound) nbtBase;
|
|
||||||
if (slot.e("tag")) {
|
|
||||||
invalid += slot.f("Count");
|
|
||||||
NBTTagCompound iTag = slot.p("tag");
|
|
||||||
if (iTag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = iTag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
invalid = drillDown(blockTag.c("Items", 10), layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalid > threshold)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
|
|
||||||
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
|
|
||||||
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
|
|
||||||
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
|
|
||||||
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
|
|
||||||
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
PacketPlayOutExplosion packetPlayOutExplosion = (PacketPlayOutExplosion) packet;
|
|
||||||
return new PacketPlayOutExplosion(a.get(packetPlayOutExplosion), b.get(packetPlayOutExplosion), c.get(packetPlayOutExplosion), d.get(packetPlayOutExplosion), e.get(packetPlayOutExplosion), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
|
||||||
import net.minecraft.server.level.EntityPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper19 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (packetPlayInFlying.h) {
|
|
||||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
|
||||||
} else {
|
|
||||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
Object packet = Reflection.newInstance(teleportPacket);
|
|
||||||
teleportEntity.set(packet, player.getEntityId());
|
|
||||||
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getYaw() : packetPlayInFlying.d,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getPitch() : packetPlayInFlying.e);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import com.destroystokyo.paper.event.server.ServerTickEndEvent;
|
|
||||||
import com.destroystokyo.paper.event.server.ServerTickStartEvent;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
public class TickListener19 implements TickListener, Listener {
|
|
||||||
|
|
||||||
private boolean tickStartRan = false;
|
|
||||||
|
|
||||||
public TickListener19() {
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, BauSystem.getInstance());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onServerTickStart(ServerTickStartEvent event) {
|
|
||||||
if (TickManager.impl.isFrozen()) return;
|
|
||||||
Bukkit.getPluginManager().callEvent(new TickStartEvent());
|
|
||||||
tickStartRan = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onServerTickEnd(ServerTickEndEvent event) {
|
|
||||||
if (!tickStartRan) return;
|
|
||||||
Bukkit.getPluginManager().callEvent(new TickEndEvent());
|
|
||||||
tickStartRan = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.spigotapi)
|
|
||||||
|
|
||||||
compileOnly(libs.nms20)
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import net.minecraft.nbt.NBTBase;
|
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
|
||||||
import net.minecraft.nbt.NBTTagList;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInSetCreativeSlot;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayOutExplosion;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayOutGameStateChange;
|
|
||||||
import net.minecraft.server.level.PlayerInteractManager;
|
|
||||||
import net.minecraft.world.level.EnumGamemode;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NMSWrapper20 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<EnumGamemode> playerGameMode = Reflection.getField(PlayerInteractManager.class, EnumGamemode.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(((CraftPlayer) player).getHandle().e, EnumGamemode.a(gameMode.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.a();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.c()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<PacketPlayOutGameStateChange.a> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, PacketPlayOutGameStateChange.a.class, 12);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, PacketPlayOutGameStateChange.d);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
((CraftPlayer) player).getHandle().fO().d = true;
|
|
||||||
((CraftPlayer) player).getHandle().fO().e = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.DIRT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
|
|
||||||
NBTTagCompound tag = nmsItem.v();
|
|
||||||
if (tag != null && tag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = tag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
return drillDown(blockTag.c("Items", 10), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(NBTTagList items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (NBTBase nbtBase : items) {
|
|
||||||
if (!(nbtBase instanceof NBTTagCompound))
|
|
||||||
continue;
|
|
||||||
NBTTagCompound slot = (NBTTagCompound) nbtBase;
|
|
||||||
if (slot.e("tag")) {
|
|
||||||
invalid += slot.f("Count");
|
|
||||||
NBTTagCompound iTag = slot.p("tag");
|
|
||||||
if (iTag.e("BlockEntityTag")) {
|
|
||||||
NBTTagCompound blockTag = iTag.p("BlockEntityTag");
|
|
||||||
if (blockTag.e("Items")) {
|
|
||||||
invalid = drillDown(blockTag.c("Items", 10), layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalid > threshold)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<?> explosionPacket = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket");
|
|
||||||
private final Reflection.Field<Double> a = Reflection.getField(explosionPacket, double.class, 0);
|
|
||||||
private final Reflection.Field<Double> b = Reflection.getField(explosionPacket, double.class, 1);
|
|
||||||
private final Reflection.Field<Double> c = Reflection.getField(explosionPacket, double.class, 2);
|
|
||||||
private final Reflection.Field<Float> d = Reflection.getField(explosionPacket, float.class, 0);
|
|
||||||
private final Reflection.Field<List> e = Reflection.getField(explosionPacket, List.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
PacketPlayOutExplosion packetPlayOutExplosion = (PacketPlayOutExplosion) packet;
|
|
||||||
return new PacketPlayOutExplosion(a.get(packetPlayOutExplosion), b.get(packetPlayOutExplosion), c.get(packetPlayOutExplosion), d.get(packetPlayOutExplosion), e.get(packetPlayOutExplosion), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.data.BlockData;
|
|
||||||
|
|
||||||
public class PlaceItemWrapper20 implements PlaceItemWrapper {
|
|
||||||
|
|
||||||
public PlaceItemWrapper20() {
|
|
||||||
for (Material material : Material.values()) {
|
|
||||||
if (!material.isBlock()) continue;
|
|
||||||
if (material.isLegacy()) continue;
|
|
||||||
BlockData blockData = material.createBlockData();
|
|
||||||
Material placementMaterial = blockData.getPlacementMaterial();
|
|
||||||
if (material == placementMaterial) continue;
|
|
||||||
if (placementMaterial == Material.AIR) continue;
|
|
||||||
if (placementMaterial.isItem() && !placementMaterial.isBlock()) {
|
|
||||||
ITEM_MATERIAL_TO_BLOCK_MATERIAL.put(placementMaterial, material);
|
|
||||||
}
|
|
||||||
if (material.name().contains("WALL")) {
|
|
||||||
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(placementMaterial, material);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import net.minecraft.network.protocol.game.PacketPlayInFlying;
|
|
||||||
import net.minecraft.server.level.EntityPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper20 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (packetPlayInFlying.h) {
|
|
||||||
entityPlayer.b(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c, packetPlayInFlying.d, packetPlayInFlying.e);
|
|
||||||
} else {
|
|
||||||
entityPlayer.e(packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
PacketPlayInFlying packetPlayInFlying = ((PacketPlayInFlying) object);
|
|
||||||
Object packet = Reflection.newInstance(teleportPacket);
|
|
||||||
teleportEntity.set(packet, player.getEntityId());
|
|
||||||
teleportPosition.set(packet, packetPlayInFlying.a, packetPlayInFlying.b, packetPlayInFlying.c,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getYaw() : packetPlayInFlying.d,
|
|
||||||
packetPlayInFlying.h ? player.getLocation().getPitch() : packetPlayInFlying.e);
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
steamwar.java
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_21
|
|
||||||
targetCompatibility = JavaVersion.VERSION_21
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":BauSystem:BauSystem_Main", "default"))
|
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
|
||||||
|
|
||||||
compileOnly(libs.paperapi21)
|
|
||||||
|
|
||||||
compileOnly(libs.nms21)
|
|
||||||
}
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.features.util.NoClipCommand;
|
|
||||||
import io.papermc.paper.datacomponent.DataComponentTypes;
|
|
||||||
import io.papermc.paper.datacomponent.item.ItemContainerContents;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.server.level.ServerPlayerGameMode;
|
|
||||||
import net.minecraft.world.entity.player.Abilities;
|
|
||||||
import net.minecraft.world.level.GameType;
|
|
||||||
import org.bukkit.GameMode;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class NMSWrapper21 implements NMSWrapper {
|
|
||||||
|
|
||||||
private static final Reflection.Field<ServerPlayerGameMode> playerInteractManager = Reflection.getField(ServerPlayer.class, null, ServerPlayerGameMode.class);
|
|
||||||
private static final Reflection.Field<GameType> playerGameMode = Reflection.getField(ServerPlayerGameMode.class, GameType.class, 0);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setInternalGameMode(Player player, GameMode gameMode) {
|
|
||||||
playerGameMode.set(playerInteractManager.get(((CraftPlayer) player).getHandle()), GameType.byId(gameMode.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSlotToItemStack(Player player, Object o) {
|
|
||||||
ClientboundContainerSetSlotPacket packetPlayInSetCreativeSlot = (ClientboundContainerSetSlotPacket) o;
|
|
||||||
int index = packetPlayInSetCreativeSlot.getSlot();
|
|
||||||
if (index >= 36 && index <= 44) {
|
|
||||||
index -= 36;
|
|
||||||
} else if (index > 44) {
|
|
||||||
index -= 5;
|
|
||||||
} else if (index <= 8) {
|
|
||||||
index = index - 8 + 36;
|
|
||||||
}
|
|
||||||
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.getItem()));
|
|
||||||
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
|
||||||
player.updateInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Reflection.Field<ClientboundGameEventPacket.Type> gameStateChangeReason = Reflection.getField(NoClipCommand.gameStateChange, ClientboundGameEventPacket.Type.class, 14);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setGameStateChangeReason(Object packet) {
|
|
||||||
gameStateChangeReason.set(packet, ClientboundGameEventPacket.CHANGE_GAME_MODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPlayerBuildAbilities(Player player) {
|
|
||||||
Abilities abilities = (((CraftPlayer) player).getHandle()).getAbilities();
|
|
||||||
abilities.mayBuild = true;
|
|
||||||
abilities.mayfly = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material pathMaterial() {
|
|
||||||
return Material.DIRT_PATH;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int threshold = 2048;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkItemStack(ItemStack item) {
|
|
||||||
ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER);
|
|
||||||
if (data == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return drillDown(data.contents(), 0, 0) > threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int drillDown(List<ItemStack> items, int layer, int start) {
|
|
||||||
if (layer > 2) return start + threshold;
|
|
||||||
int invalid = start;
|
|
||||||
for (int i = start; i < items.size(); i++) {
|
|
||||||
ItemStack item = items.get(i);
|
|
||||||
if (item.isEmpty()) continue;
|
|
||||||
|
|
||||||
invalid += item.getAmount();
|
|
||||||
|
|
||||||
ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER);
|
|
||||||
if (data == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ItemStack> subItems = data.contents();
|
|
||||||
if (subItems.size() > 1) {
|
|
||||||
invalid = drillDown(subItems, layer + 1, invalid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object resetExplosionKnockback(Object packet) {
|
|
||||||
ClientboundExplodePacket explosion = (ClientboundExplodePacket) packet;
|
|
||||||
|
|
||||||
return new ClientboundExplodePacket(
|
|
||||||
explosion.center(),
|
|
||||||
Optional.empty(),
|
|
||||||
explosion.explosionParticle(),
|
|
||||||
explosion.explosionSound()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlayerMovementWrapper21 implements PlayerMovementWrapper {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPosition(Player player, Object object) {
|
|
||||||
ServerboundMovePlayerPacket packetPlayInFlying = ((ServerboundMovePlayerPacket) object);
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
if (packetPlayInFlying.hasPos) {
|
|
||||||
serverPlayer.setPosRaw(packetPlayInFlying.x, packetPlayInFlying.y, packetPlayInFlying.z);
|
|
||||||
}
|
|
||||||
if (packetPlayInFlying.hasRot) {
|
|
||||||
serverPlayer.setXRot(packetPlayInFlying.xRot);
|
|
||||||
serverPlayer.setYRot(packetPlayInFlying.yRot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertToOut(Player player, Object object) {
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundTickingStatePacket;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.ServerTickRateManager;
|
|
||||||
import net.minecraft.world.TickRateManager;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class TickManager21 implements TickManager {
|
|
||||||
private static final ServerTickRateManager manager = MinecraftServer.getServer().tickRateManager();
|
|
||||||
private static final Reflection.Field<Integer> frozenTicksToRun = Reflection.getField(TickRateManager.class, int.class, 0);
|
|
||||||
private static final Reflection.Field<Long> remainingSprintTicks = Reflection.getField(ServerTickRateManager.class, long.class, 0);
|
|
||||||
|
|
||||||
private boolean blockTpsPacket = true;
|
|
||||||
private int totalSteps;
|
|
||||||
|
|
||||||
public TickManager21() {
|
|
||||||
TinyProtocol.instance.addFilter(ClientboundTickingStatePacket.class, this::blockPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object blockPacket(Player player, Object packet) {
|
|
||||||
if (blockTpsPacket) {
|
|
||||||
return new ClientboundTickingStatePacket(20, manager.isFrozen());
|
|
||||||
} else {
|
|
||||||
return packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canFreeze() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBlockTpsPacket(boolean block) {
|
|
||||||
blockTpsPacket = block;
|
|
||||||
if (blockTpsPacket) {
|
|
||||||
ClientboundTickingStatePacket packet = new ClientboundTickingStatePacket(20, manager.isFrozen());
|
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
|
|
||||||
} else {
|
|
||||||
ClientboundTickingStatePacket packet = new ClientboundTickingStatePacket(manager.tickrate(), manager.isFrozen());
|
|
||||||
Bukkit.getOnlinePlayers().forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTickRate(float tickRate) {
|
|
||||||
if (isFrozen()) {
|
|
||||||
setFreeze(false);
|
|
||||||
}
|
|
||||||
manager.setTickRate(tickRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFrozen() {
|
|
||||||
return manager.isFrozen();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setFreeze(boolean freeze) {
|
|
||||||
manager.setFrozen(freeze);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stepTicks(int ticks) {
|
|
||||||
if (manager.isSprinting()) {
|
|
||||||
manager.stopSprinting();
|
|
||||||
} else if (manager.isSteppingForward()) {
|
|
||||||
manager.stopStepping();
|
|
||||||
}
|
|
||||||
this.totalSteps = ticks;
|
|
||||||
manager.setFrozen(true);
|
|
||||||
manager.stepGameIfPaused(ticks);
|
|
||||||
manager.setFrozen(false);
|
|
||||||
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), (bukkitTask) -> {
|
|
||||||
if (manager.isSteppingForward()) return;
|
|
||||||
manager.setFrozen(true);
|
|
||||||
bukkitTask.cancel();
|
|
||||||
}, 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sprintTicks(int ticks) {
|
|
||||||
if (manager.isSteppingForward()) {
|
|
||||||
manager.stopStepping();
|
|
||||||
} else if (manager.isSprinting()) {
|
|
||||||
manager.stopSprinting();
|
|
||||||
}
|
|
||||||
this.totalSteps = ticks;
|
|
||||||
manager.requestGameToSprint(ticks, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isSprinting() {
|
|
||||||
return manager.isSprinting();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isStepping() {
|
|
||||||
return manager.isSteppingForward();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getTickRate() {
|
|
||||||
return manager.tickrate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getRemainingTicks() {
|
|
||||||
if (isSprinting()) {
|
|
||||||
return remainingSprintTicks.get(manager);
|
|
||||||
} else {
|
|
||||||
return frozenTicksToRun.get(manager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDoneTicks() {
|
|
||||||
return totalSteps - getRemainingTicks();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTotalTicks() {
|
|
||||||
return totalSteps;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,8 +26,8 @@ tasks.compileJava {
|
|||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -35,10 +35,12 @@ dependencies {
|
|||||||
annotationProcessor(libs.classindex)
|
annotationProcessor(libs.classindex)
|
||||||
compileOnly(project(":SpigotCore", "default"))
|
compileOnly(project(":SpigotCore", "default"))
|
||||||
|
|
||||||
compileOnly(libs.spigotapi)
|
|
||||||
compileOnly(libs.axiom)
|
compileOnly(libs.axiom)
|
||||||
compileOnly(libs.authlib)
|
compileOnly(libs.authlib)
|
||||||
|
|
||||||
|
compileOnly(libs.paperapi21)
|
||||||
|
compileOnly(libs.nms21)
|
||||||
|
|
||||||
compileOnly(libs.fawe18)
|
compileOnly(libs.fawe18)
|
||||||
|
|
||||||
implementation(libs.luaj)
|
implementation(libs.luaj)
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import de.steamwar.bausystem.features.world.BauScoreboard;
|
|||||||
import de.steamwar.bausystem.linkage.BauGuiItem;
|
import de.steamwar.bausystem.linkage.BauGuiItem;
|
||||||
import de.steamwar.bausystem.region.RegionSystem;
|
import de.steamwar.bausystem.region.RegionSystem;
|
||||||
import de.steamwar.bausystem.utils.ScoreboardElement;
|
import de.steamwar.bausystem.utils.ScoreboardElement;
|
||||||
import de.steamwar.bausystem.utils.TickListener;
|
|
||||||
import de.steamwar.bausystem.utils.TickManager;
|
import de.steamwar.bausystem.utils.TickManager;
|
||||||
import de.steamwar.bausystem.worlddata.WorldData;
|
import de.steamwar.bausystem.worlddata.WorldData;
|
||||||
import de.steamwar.command.AbstractValidator;
|
import de.steamwar.command.AbstractValidator;
|
||||||
@@ -127,8 +126,6 @@ public class BauSystem extends JavaPlugin implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TickListener.impl.init();
|
|
||||||
|
|
||||||
TraceManager.instance.init();
|
TraceManager.instance.init();
|
||||||
TraceRecorder.instance.init();
|
TraceRecorder.instance.init();
|
||||||
|
|
||||||
|
|||||||
+3
-4
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.observer;
|
package de.steamwar.bausystem.features.observer;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.region.Point;
|
import de.steamwar.bausystem.region.Point;
|
||||||
import de.steamwar.core.SWPlayer;
|
import de.steamwar.core.SWPlayer;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
@@ -29,8 +28,9 @@ import org.bukkit.block.Block;
|
|||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.data.Bisected;
|
import org.bukkit.block.data.Bisected;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.type.Observer;
|
|
||||||
import org.bukkit.block.data.type.*;
|
import org.bukkit.block.data.type.*;
|
||||||
|
import org.bukkit.block.data.type.Observer;
|
||||||
|
import org.bukkit.craftbukkit.block.impl.CraftPoweredRail;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -171,7 +171,6 @@ public class ObserverTracer implements SWPlayer.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> craftPoweredRail = Reflection.getClass("org.bukkit.craftbukkit.block.impl.CraftPoweredRail");
|
|
||||||
private boolean checkAllowed(Block block, BlockData blockData) {
|
private boolean checkAllowed(Block block, BlockData blockData) {
|
||||||
if (checkMaterial(block)) return true;
|
if (checkMaterial(block)) return true;
|
||||||
if (block.getType() == Material.BELL) {
|
if (block.getType() == Material.BELL) {
|
||||||
@@ -180,7 +179,7 @@ public class ObserverTracer implements SWPlayer.Component {
|
|||||||
|
|
||||||
return blockData instanceof Door
|
return blockData instanceof Door
|
||||||
|| blockData instanceof Gate
|
|| blockData instanceof Gate
|
||||||
|| craftPoweredRail.isInstance(blockData)
|
|| blockData instanceof CraftPoweredRail
|
||||||
|| blockData instanceof TrapDoor
|
|| blockData instanceof TrapDoor
|
||||||
|| blockData instanceof GlassPane;
|
|| blockData instanceof GlassPane;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-7
@@ -20,7 +20,6 @@
|
|||||||
package de.steamwar.bausystem.features.simulator;
|
package de.steamwar.bausystem.features.simulator;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.SWUtils;
|
import de.steamwar.bausystem.SWUtils;
|
||||||
@@ -48,6 +47,7 @@ import de.steamwar.linkage.Linked;
|
|||||||
import de.steamwar.linkage.MinVersion;
|
import de.steamwar.linkage.MinVersion;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -72,9 +72,6 @@ import java.util.stream.Collectors;
|
|||||||
public class SimulatorCursor implements Listener {
|
public class SimulatorCursor implements Listener {
|
||||||
|
|
||||||
private static final World WORLD = Bukkit.getWorlds().get(0);
|
private static final World WORLD = Bukkit.getWorlds().get(0);
|
||||||
private Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
|
||||||
private Class<?> look = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Rot");
|
|
||||||
private Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
|
||||||
|
|
||||||
private static Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
|
private static Map<Player, CursorType> cursorType = Collections.synchronizedMap(new HashMap<>());
|
||||||
private static Map<Player, REntityServer> cursors = Collections.synchronizedMap(new HashMap<>());
|
private static Map<Player, REntityServer> cursors = Collections.synchronizedMap(new HashMap<>());
|
||||||
@@ -89,9 +86,9 @@ public class SimulatorCursor implements Listener {
|
|||||||
calcCursor(player);
|
calcCursor(player);
|
||||||
return object;
|
return object;
|
||||||
};
|
};
|
||||||
TinyProtocol.instance.addFilter(position, function);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, function);
|
||||||
TinyProtocol.instance.addFilter(look, function);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Rot.class, function);
|
||||||
TinyProtocol.instance.addFilter(positionLook, function);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
+13
-4
@@ -19,14 +19,15 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.simulator.execute;
|
package de.steamwar.bausystem.features.simulator.execute;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.event.server.ServerTickEndEvent;
|
||||||
|
import com.destroystokyo.paper.event.server.ServerTickStartEvent;
|
||||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||||
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
|
import de.steamwar.bausystem.features.simulator.data.SimulatorElement;
|
||||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
import de.steamwar.bausystem.utils.TickEndEvent;
|
import de.steamwar.bausystem.utils.TickManager;
|
||||||
import de.steamwar.bausystem.utils.TickStartEvent;
|
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
import de.steamwar.linkage.MinVersion;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -109,8 +110,13 @@ public class SimulatorExecutor implements Listener {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean tickStartRan = false;
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onTickStart(TickStartEvent event) {
|
public void onServerTickStart(ServerTickStartEvent event) {
|
||||||
|
if (TickManager.impl.isFrozen()) return;
|
||||||
|
tickStartRan = true;
|
||||||
|
|
||||||
long currentTick = TPSUtils.currentRealTick.get();
|
long currentTick = TPSUtils.currentRealTick.get();
|
||||||
Map<Integer, List<SimulatorAction>> actionsToRun = tickStartActions.remove(currentTick);
|
Map<Integer, List<SimulatorAction>> actionsToRun = tickStartActions.remove(currentTick);
|
||||||
if (actionsToRun == null) return;
|
if (actionsToRun == null) return;
|
||||||
@@ -123,7 +129,10 @@ public class SimulatorExecutor implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onTickEnd(TickEndEvent event) {
|
public void onServerTickEnd(ServerTickEndEvent event) {
|
||||||
|
if (!tickStartRan) return;
|
||||||
|
tickStartRan = false;
|
||||||
|
|
||||||
long currentTick = TPSUtils.currentRealTick.get() - 1;
|
long currentTick = TPSUtils.currentRealTick.get() - 1;
|
||||||
List<SimulatorAction> actionsToRun = tickEndActions.remove(currentTick);
|
List<SimulatorAction> actionsToRun = tickEndActions.remove(currentTick);
|
||||||
if (actionsToRun == null) return;
|
if (actionsToRun == null) return;
|
||||||
|
|||||||
+2
-4
@@ -20,13 +20,13 @@
|
|||||||
package de.steamwar.bausystem.features.smartplace;
|
package de.steamwar.bausystem.features.smartplace;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.configplayer.Config;
|
import de.steamwar.bausystem.configplayer.Config;
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.Core;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundUseItemOnPacket;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
@@ -83,13 +83,11 @@ public class SmartPlaceListener implements Listener {
|
|||||||
IGNORED.remove(Material.BARRIER);
|
IGNORED.remove(Material.BARRIER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> useItem = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundUseItemOnPacket");
|
|
||||||
|
|
||||||
private static final Set<Player> SMART_PLACING = new HashSet<>();
|
private static final Set<Player> SMART_PLACING = new HashSet<>();
|
||||||
private static final Set<Player> WAS_EXECUTED = new HashSet<>();
|
private static final Set<Player> WAS_EXECUTED = new HashSet<>();
|
||||||
|
|
||||||
public SmartPlaceListener() {
|
public SmartPlaceListener() {
|
||||||
TinyProtocol.instance.addFilter(useItem, (player, packet) -> {
|
TinyProtocol.instance.addFilter(ServerboundUseItemOnPacket.class, (player, packet) -> {
|
||||||
if(!Permission.BUILD.hasPermission(player)) return packet;
|
if(!Permission.BUILD.hasPermission(player)) return packet;
|
||||||
if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) return packet;
|
if (!Config.getInstance().get(player).getPlainValueOrDefault("smartPlace", false)) return packet;
|
||||||
RayTraceResult rayTraceResult = player.rayTraceBlocks(6);
|
RayTraceResult rayTraceResult = player.rayTraceBlocks(6);
|
||||||
|
|||||||
@@ -39,10 +39,7 @@ import lombok.Setter;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|||||||
+8
-22
@@ -21,7 +21,6 @@ package de.steamwar.bausystem.features.util;
|
|||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
|
||||||
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
|
||||||
@@ -30,6 +29,7 @@ import de.steamwar.command.SWCommand;
|
|||||||
import de.steamwar.core.ProtocolWrapper;
|
import de.steamwar.core.ProtocolWrapper;
|
||||||
import de.steamwar.core.SWPlayer;
|
import de.steamwar.core.SWPlayer;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import net.minecraft.network.protocol.game.*;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -45,16 +45,6 @@ import java.util.function.BiFunction;
|
|||||||
@Linked
|
@Linked
|
||||||
public class NoClipCommand extends SWCommand implements Listener {
|
public class NoClipCommand extends SWCommand implements Listener {
|
||||||
|
|
||||||
public static final Class<?> gameStateChange = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundGameEventPacket");
|
|
||||||
private static final Reflection.Field<Float> floatFieldAccessor = Reflection.getField(gameStateChange, float.class, 0);
|
|
||||||
|
|
||||||
private static final Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
|
||||||
private static final Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
|
||||||
private static final Class<?> useItem = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundUseItemOnPacket");
|
|
||||||
private static final Class<?> blockDig = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundPlayerActionPacket");
|
|
||||||
private static final Class<?> windowClick = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundContainerClickPacket");
|
|
||||||
private static final Class<?> setSlotStack = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket");
|
|
||||||
|
|
||||||
public static class NoClipData implements SWPlayer.Component {
|
public static class NoClipData implements SWPlayer.Component {
|
||||||
private long lastTick = -1;
|
private long lastTick = -1;
|
||||||
|
|
||||||
@@ -75,8 +65,8 @@ public class NoClipCommand extends SWCommand implements Listener {
|
|||||||
noClipData.lastTick = TPSUtils.currentTick.get();
|
noClipData.lastTick = TPSUtils.currentTick.get();
|
||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
TinyProtocol.instance.addFilter(position, first);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, first);
|
||||||
TinyProtocol.instance.addFilter(positionLook, first);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, first);
|
||||||
|
|
||||||
BiFunction<Player, Object, Object> second = (player, o) -> {
|
BiFunction<Player, Object, Object> second = (player, o) -> {
|
||||||
NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null);
|
NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null);
|
||||||
@@ -85,9 +75,9 @@ public class NoClipCommand extends SWCommand implements Listener {
|
|||||||
noClipData.lastTick = TPSUtils.currentTick.get();
|
noClipData.lastTick = TPSUtils.currentTick.get();
|
||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
TinyProtocol.instance.addFilter(useItem, second);
|
TinyProtocol.instance.addFilter(ServerboundUseItemOnPacket.class, second);
|
||||||
TinyProtocol.instance.addFilter(blockDig, second);
|
TinyProtocol.instance.addFilter(ServerboundPlayerActionPacket.class, second);
|
||||||
TinyProtocol.instance.addFilter(windowClick, second);
|
TinyProtocol.instance.addFilter(ServerboundContainerClickPacket.class, second);
|
||||||
|
|
||||||
BiFunction<Player, Object, Object> third = (player, o) -> {
|
BiFunction<Player, Object, Object> third = (player, o) -> {
|
||||||
if (SWPlayer.of(player).hasComponent(NoClipData.class)) {
|
if (SWPlayer.of(player).hasComponent(NoClipData.class)) {
|
||||||
@@ -95,7 +85,7 @@ public class NoClipCommand extends SWCommand implements Listener {
|
|||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
TinyProtocol.instance.addFilter(setSlotStack, third);
|
TinyProtocol.instance.addFilter(ServerboundSetCreativeModeSlotPacket.class, third);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(help = true)
|
@Register(help = true)
|
||||||
@@ -107,13 +97,9 @@ public class NoClipCommand extends SWCommand implements Listener {
|
|||||||
player.setGameMode(GameMode.SPECTATOR);
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
NMSWrapper.impl.setPlayerBuildAbilities(player);
|
NMSWrapper.impl.setPlayerBuildAbilities(player);
|
||||||
|
|
||||||
Object gameStateChangeObject = Reflection.newInstance(gameStateChange);
|
|
||||||
NMSWrapper.impl.setGameStateChangeReason(gameStateChangeObject);
|
|
||||||
floatFieldAccessor.set(gameStateChangeObject, 1F);
|
|
||||||
|
|
||||||
swPlayer.setComponent(new NoClipData());
|
swPlayer.setComponent(new NoClipData());
|
||||||
BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player);
|
BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player);
|
||||||
TinyProtocol.instance.sendPacket(player, gameStateChangeObject);
|
TinyProtocol.instance.sendPacket(player, new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, 1F));
|
||||||
pseudoGameMode(player, GameMode.SPECTATOR);
|
pseudoGameMode(player, GameMode.SPECTATOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -22,8 +22,8 @@ package de.steamwar.bausystem.features.util.items;
|
|||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.features.util.KillAllCommand;
|
import de.steamwar.bausystem.features.util.KillAllCommand;
|
||||||
import de.steamwar.bausystem.linkage.BauGuiItem;
|
|
||||||
import de.steamwar.bausystem.features.util.RegionSelectionType;
|
import de.steamwar.bausystem.features.util.RegionSelectionType;
|
||||||
|
import de.steamwar.bausystem.linkage.BauGuiItem;
|
||||||
import de.steamwar.inventory.SWItem;
|
import de.steamwar.inventory.SWItem;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.LinkedInstance;
|
import de.steamwar.linkage.LinkedInstance;
|
||||||
|
|||||||
+2
-3
@@ -19,11 +19,11 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.world;
|
package de.steamwar.bausystem.features.world;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.api.Enable;
|
import de.steamwar.linkage.api.Enable;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundContainerClosePacket;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
|
|
||||||
@@ -32,8 +32,7 @@ public class AntiCursorReCentering implements Enable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enable() {
|
public void enable() {
|
||||||
Class<?> closeWindow = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundContainerClosePacket");
|
TinyProtocol.instance.addFilter(ClientboundContainerClosePacket.class, (player, object) -> {
|
||||||
TinyProtocol.instance.addFilter(closeWindow, (player, object) -> {
|
|
||||||
if (player.getOpenInventory().getTopInventory().getType() == InventoryType.CRAFTING) {
|
if (player.getOpenInventory().getTopInventory().getType() == InventoryType.CRAFTING) {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -19,17 +19,17 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.world;
|
package de.steamwar.bausystem.features.world;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.utils.NMSWrapper;
|
import de.steamwar.bausystem.utils.NMSWrapper;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
public class NoCreativeKnockback {
|
public class NoCreativeKnockback {
|
||||||
|
|
||||||
public NoCreativeKnockback() {
|
public NoCreativeKnockback() {
|
||||||
TinyProtocol.instance.addFilter(Reflection.getClass("net.minecraft.network.protocol.game.ClientboundExplodePacket"), (player, o) -> {
|
TinyProtocol.instance.addFilter(ClientboundExplodePacket.class, (player, o) -> {
|
||||||
if (player.getGameMode() != GameMode.CREATIVE) return o;
|
if (player.getGameMode() != GameMode.CREATIVE) return o;
|
||||||
return NMSWrapper.impl.resetExplosionKnockback(o);
|
return NMSWrapper.impl.resetExplosionKnockback(o);
|
||||||
});
|
});
|
||||||
|
|||||||
+12
-28
@@ -19,13 +19,14 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.features.world;
|
package de.steamwar.bausystem.features.world;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.Permission;
|
import de.steamwar.bausystem.Permission;
|
||||||
import de.steamwar.bausystem.utils.PlaceItemUtils;
|
import de.steamwar.bausystem.utils.PlaceItemUtils;
|
||||||
import de.steamwar.linkage.Linked;
|
import de.steamwar.linkage.Linked;
|
||||||
import de.steamwar.linkage.MinVersion;
|
import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundSignUpdatePacket;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -37,6 +38,8 @@ import org.bukkit.block.data.Directional;
|
|||||||
import org.bukkit.block.data.Rotatable;
|
import org.bukkit.block.data.Rotatable;
|
||||||
import org.bukkit.block.sign.Side;
|
import org.bukkit.block.sign.Side;
|
||||||
import org.bukkit.block.sign.SignSide;
|
import org.bukkit.block.sign.SignSide;
|
||||||
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
@@ -45,24 +48,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
|||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
@Linked
|
@Linked
|
||||||
@MinVersion(20)
|
public class SignEdit implements Listener {
|
||||||
public class SignEditFrom20 implements Listener {
|
|
||||||
|
|
||||||
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
|
|
||||||
private static final Class<?> craftBlock = Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlock");
|
|
||||||
private static final Class<?> craftWorld = Reflection.getClass("org.bukkit.craftbukkit.CraftWorld");
|
|
||||||
private static final Class<?> generatorAccess = Reflection.getClass("net.minecraft.world.level.LevelAccessor");
|
|
||||||
private static final Reflection.Method getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
|
|
||||||
private static final Reflection.Method getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
|
|
||||||
private static final Reflection.Method at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
|
|
||||||
|
|
||||||
private static final Class<?> openSign = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket");
|
|
||||||
private static final Reflection.Field<?> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
|
|
||||||
private static final Reflection.Field<?> sideFieldAccessor = Reflection.getField(openSign, boolean.class, 0);
|
|
||||||
|
|
||||||
private static final Class<?> updateSign = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSignUpdatePacket");
|
|
||||||
private static final Reflection.Field<?> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
|
|
||||||
private static final Reflection.Field<String[]> stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void editSign(PlayerInteractEvent event) {
|
public void editSign(PlayerInteractEvent event) {
|
||||||
@@ -93,10 +79,8 @@ public class SignEditFrom20 implements Listener {
|
|||||||
sign.update(true);
|
sign.update(true);
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||||
Object openSignObject = Reflection.newInstance(openSign);
|
ClientboundOpenSignEditorPacket packet = new ClientboundOpenSignEditorPacket(((CraftBlock) block).getPosition(), side == Side.FRONT);
|
||||||
blockPositionFieldAccessor.set(openSignObject, getPosition.invoke(block));
|
TinyProtocol.instance.sendPacket(player, packet);
|
||||||
sideFieldAccessor.set(openSignObject, side == Side.FRONT);
|
|
||||||
TinyProtocol.instance.sendPacket(player, openSignObject);
|
|
||||||
}, 1);
|
}, 1);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -117,14 +101,14 @@ public class SignEditFrom20 implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
TinyProtocol.instance.addFilter(updateSign, (player, o) -> {
|
TinyProtocol.instance.addTypedFilter(ServerboundSignUpdatePacket.class, (player, o) -> {
|
||||||
Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> {
|
Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> {
|
||||||
String[] lines = stringFieldAccessor.get(o);
|
ServerLevel serverLevel = ((CraftWorld) player.getWorld()).getHandle();
|
||||||
|
Block signLoc = CraftBlock.at(serverLevel, o.getPos());
|
||||||
Block signLoc = (Block) at.invoke(null, getWorldHandle.invoke(player.getWorld()), getBlockPositionFieldAccessor.get(o));
|
|
||||||
if (!signLoc.getType().name().contains("SIGN"))
|
if (!signLoc.getType().name().contains("SIGN"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
String[] lines = o.getLines();
|
||||||
Sign sign = ((Sign) signLoc.getState());
|
Sign sign = ((Sign) signLoc.getState());
|
||||||
SignSide signSide = sign.getSide(signSide(player, signLoc));
|
SignSide signSide = sign.getSide(signSide(player, signLoc));
|
||||||
for (int i = 0; i < lines.length; i++) {
|
for (int i = 0; i < lines.length; i++) {
|
||||||
-105
@@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.features.world;
|
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import de.steamwar.bausystem.Permission;
|
|
||||||
import de.steamwar.linkage.Linked;
|
|
||||||
import de.steamwar.linkage.MaxVersion;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.Sign;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
|
|
||||||
@Linked
|
|
||||||
@MaxVersion(19)
|
|
||||||
public class SignEditUntil19 implements Listener {
|
|
||||||
|
|
||||||
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
|
|
||||||
private static final Class<?> craftBlock = Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlock");
|
|
||||||
private static final Class<?> craftWorld = Reflection.getClass("org.bukkit.craftbukkit.CraftWorld");
|
|
||||||
private static final Class<?> generatorAccess = Reflection.getClass("net.minecraft.world.level.LevelAccessor");
|
|
||||||
private static final Reflection.Method getPosition = Reflection.getTypedMethod(craftBlock, "getPosition", blockPosition);
|
|
||||||
private static final Reflection.Method getWorldHandle = Reflection.getTypedMethod(craftWorld, "getHandle", null);
|
|
||||||
private static final Reflection.Method at = Reflection.getTypedMethod(craftBlock, "at", craftBlock, generatorAccess, blockPosition);
|
|
||||||
|
|
||||||
private static final Class<?> openSign = Reflection.getClass("net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket");
|
|
||||||
private static final Reflection.Field<?> blockPositionFieldAccessor = Reflection.getField(openSign, blockPosition, 0);
|
|
||||||
|
|
||||||
private static final Class<?> updateSign = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundSignUpdatePacket");
|
|
||||||
private static final Reflection.Field<?> getBlockPositionFieldAccessor = Reflection.getField(updateSign, blockPosition, 0);
|
|
||||||
private static final Reflection.Field<String[]> stringFieldAccessor = Reflection.getField(updateSign, String[].class, 0);
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void editSign(PlayerInteractEvent event) {
|
|
||||||
if (!event.getPlayer().isSneaking()) return;
|
|
||||||
if (event.getClickedBlock() == null || !event.getClickedBlock().getType().name().contains("SIGN")) return;
|
|
||||||
|
|
||||||
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && (event.getItem() == null || event.getItem().getType() == Material.AIR) || event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
|
||||||
edit(event.getPlayer(), event.getClickedBlock());
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void edit(Player player, Block block) {
|
|
||||||
if (!Permission.BUILD.hasPermission(player)) return;
|
|
||||||
Sign sign = (org.bukkit.block.Sign) block.getState();
|
|
||||||
String[] lines = sign.getLines();
|
|
||||||
for (int i = 0; i < lines.length; i++) {
|
|
||||||
sign.setLine(i, lines[i].replace('§', '&'));
|
|
||||||
}
|
|
||||||
sign.update(true);
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
|
||||||
Object openSignObject = Reflection.newInstance(openSign);
|
|
||||||
blockPositionFieldAccessor.set(openSignObject, getPosition.invoke(block));
|
|
||||||
TinyProtocol.instance.sendPacket(player, openSignObject);
|
|
||||||
}, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
TinyProtocol.instance.addFilter(updateSign, (player, o) -> {
|
|
||||||
Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> {
|
|
||||||
String[] lines = stringFieldAccessor.get(o);
|
|
||||||
|
|
||||||
Block signLoc = (Block) at.invoke(null, getWorldHandle.invoke(player.getWorld()), getBlockPositionFieldAccessor.get(o));
|
|
||||||
if (!signLoc.getType().name().contains("SIGN"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
org.bukkit.block.Sign sign = ((Sign) signLoc.getState());
|
|
||||||
for (int i = 0; i < lines.length; i++) {
|
|
||||||
sign.setLine(i, ChatColor.translateAlternateColorCodes('&', lines[i]));
|
|
||||||
}
|
|
||||||
sign.update();
|
|
||||||
});
|
|
||||||
return o;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
package de.steamwar.bausystem.features.xray;
|
package de.steamwar.bausystem.features.xray;
|
||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.bausystem.features.techhider.TechHiderCommand;
|
import de.steamwar.bausystem.features.techhider.TechHiderCommand;
|
||||||
import de.steamwar.bausystem.region.Region;
|
import de.steamwar.bausystem.region.Region;
|
||||||
@@ -32,6 +31,7 @@ import de.steamwar.linkage.Linked;
|
|||||||
import de.steamwar.linkage.LinkedInstance;
|
import de.steamwar.linkage.LinkedInstance;
|
||||||
import de.steamwar.techhider.TechHider;
|
import de.steamwar.techhider.TechHider;
|
||||||
import net.md_5.bungee.api.ChatMessageType;
|
import net.md_5.bungee.api.ChatMessageType;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -95,9 +95,6 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> position = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
|
||||||
private static final Class<?> positionLook = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
|
||||||
|
|
||||||
{
|
{
|
||||||
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
||||||
Region region = Region.getRegion(player.getLocation());
|
Region region = Region.getRegion(player.getLocation());
|
||||||
@@ -110,8 +107,8 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
|
|||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
|
|
||||||
TinyProtocol.instance.addFilter(position, positionSetter);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, positionSetter);
|
||||||
TinyProtocol.instance.addFilter(positionLook, positionSetter);
|
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, positionSetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
@@ -20,34 +20,211 @@
|
|||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||||
|
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
|
import com.sk89q.worldedit.function.mask.Mask2D;
|
||||||
|
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operations;
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||||
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
|
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||||
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import de.steamwar.bausystem.region.Point;
|
import de.steamwar.bausystem.region.Point;
|
||||||
import de.steamwar.core.VersionDependent;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.block.data.Waterlogged;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.BiPredicate;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public interface FlatteningWrapper {
|
public class FlatteningWrapper {
|
||||||
FlatteningWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
public static final FlatteningWrapper impl = new FlatteningWrapper();
|
||||||
|
|
||||||
boolean isNoBook(ItemStack item);
|
public boolean isNoBook(ItemStack item) {
|
||||||
|
return item.getType() != Material.WRITABLE_BOOK && item.getType() != Material.WRITTEN_BOOK;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isUnpusheable(Material material);
|
private static final Set<Material> unpushable = new HashSet<>(Arrays.asList(Material.BARRIER, Material.BEACON, Material.COMMAND_BLOCK, Material.CHAIN_COMMAND_BLOCK, Material.REPEATING_COMMAND_BLOCK, Material.ENCHANTING_TABLE, Material.END_GATEWAY, Material.END_PORTAL, Material.ENDER_CHEST, Material.GRINDSTONE, Material.JIGSAW, Material.JUKEBOX, Material.NETHER_PORTAL, Material.OBSIDIAN, Material.STRUCTURE_VOID, Material.BARREL, Material.BEEHIVE, Material.BEE_NEST, Material.BLAST_FURNACE, Material.BREWING_STAND, Material.CHEST, Material.DAYLIGHT_DETECTOR, Material.DISPENSER, Material.DROPPER, Material.FURNACE, Material.HOPPER, Material.LECTERN, Material.SMOKER, Material.TRAPPED_CHEST));
|
||||||
boolean isBreakingOnPush(Material material);
|
|
||||||
|
|
||||||
boolean isWorldEditCommand(String command);
|
// TODO: FLOWER
|
||||||
void setSelection(Player p, Point minPoint, Point maxPoint);
|
private static final Set<Material> breaking = new HashSet<>(Arrays.asList(Material.BAMBOO, Material.CACTUS, Material.CAKE, Material.CARVED_PUMPKIN, Material.CHORUS_FLOWER, Material.CHORUS_PLANT, Material.COBWEB, Material.COCOA, Material.DRAGON_EGG, Material.FIRE, Material.FLOWER_POT, Material.JACK_O_LANTERN, Material.LADDER, Material.LAVA, Material.LAVA, Material.LEVER, Material.LILY_PAD, Material.MELON, Material.NETHER_WART, Material.PUMPKIN, Material.COMPARATOR, Material.REDSTONE_WIRE, Material.REPEATER, Material.TORCH, Material.STRUCTURE_VOID, Material.SCAFFOLDING, Material.SEA_PICKLE, Material.SNOW, Material.SUGAR_CANE, Material.TORCH, Material.TRIPWIRE, Material.TRIPWIRE_HOOK, Material.TURTLE_EGG, Material.VINE, Material.WATER, Material.WHEAT));
|
||||||
|
|
||||||
Clipboard loadSchematic(File file);
|
public boolean isUnpusheable(Material material) {
|
||||||
EditSession paste(PasteBuilder pasteBuilder);
|
if (unpushable.contains(material)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String name = material.name();
|
||||||
|
return name.contains("BANNER") || name.contains("SIGN");
|
||||||
|
}
|
||||||
|
|
||||||
Clipboard copy(Point minPoint, Point maxPoint, Point copyPoint);
|
public boolean isBreakingOnPush(Material material) {
|
||||||
boolean backup(Point minPoint, Point maxPoint, File file);
|
if (breaking.contains(material)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String name = material.name();
|
||||||
|
return name.contains("BED") || name.contains("BUTTON") || name.contains("CARPET") || (name.contains("DOOR") && !name.contains("TRAPDOOR")) || name.contains("HEAD") || name.contains("LEAVES") || name.contains("MUSHROOM") || name.contains("PRESSURE_PLATE") || name.contains("SHULKER_BOX");
|
||||||
|
}
|
||||||
|
|
||||||
boolean inWater(World world, Vector tntPosition);
|
public boolean isWorldEditCommand(String command) {
|
||||||
|
if (command.startsWith("/")) {
|
||||||
|
command = command.replaceFirst("/", "");
|
||||||
|
}
|
||||||
|
command = command.toLowerCase();
|
||||||
|
return WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getCommandManager().containsCommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final WorldEditPlugin WORLDEDIT_PLUGIN = Objects.requireNonNull((WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"));
|
||||||
|
private static final BukkitWorld BUKKITWORLD = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||||
|
|
||||||
|
public void setSelection(Player p, Point minPoint, Point maxPoint) {
|
||||||
|
WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, minPoint.toBlockVector3(), maxPoint.toBlockVector3()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Clipboard loadSchematic(File file) {
|
||||||
|
Clipboard clipboard;
|
||||||
|
try (ClipboardReader reader = Objects.requireNonNull(ClipboardFormats.findByFile(file)).getReader(new FileInputStream(file))) {
|
||||||
|
clipboard = reader.read();
|
||||||
|
} catch (NullPointerException | IOException e) {
|
||||||
|
throw new SecurityException("Bausystem schematic not found", e);
|
||||||
|
}
|
||||||
|
return clipboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EditSession paste(PasteBuilder pasteBuilder) {
|
||||||
|
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
|
||||||
|
Clipboard clipboard = pasteBuilder.getClipboard();
|
||||||
|
|
||||||
|
if (!pasteBuilder.getMappers().isEmpty()) {
|
||||||
|
BlockVector3 minimum = clipboard.getRegion().getMinimumPoint();
|
||||||
|
for (int x = 0; x < clipboard.getDimensions().getX(); x++) {
|
||||||
|
for (int y = 0; y < clipboard.getDimensions().getY(); y++) {
|
||||||
|
for (int z = 0; z < clipboard.getDimensions().getZ(); z++) {
|
||||||
|
BlockVector3 pos = minimum.add(x, y, z);
|
||||||
|
pasteBuilder.getMappers().forEach(mapper -> mapper.accept(clipboard, pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AtomicReference<BlockVector3> pastePoint = new AtomicReference<>();
|
||||||
|
if (!pasteBuilder.getPredicates().isEmpty()) {
|
||||||
|
e.setMask(new Mask() {
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockVector3 blockVector3) {
|
||||||
|
BaseBlock block = clipboard.getFullBlock(blockVector3.subtract(pastePoint.get()).add(clipboard.getRegion().getMinimumPoint()));
|
||||||
|
String blockName = block.getBlockType().toString().toLowerCase();
|
||||||
|
for (BiPredicate<BaseBlock, String> predicate : pasteBuilder.getPredicates()) {
|
||||||
|
if (!predicate.test(block, blockName)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Mask copy() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Mask2D toMask2D() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipboardHolder ch = new ClipboardHolder(clipboard);
|
||||||
|
BlockVector3 dimensions = clipboard.getDimensions();
|
||||||
|
BlockVector3 v = BlockVector3.at(pasteBuilder.getPastPoint().getX(), pasteBuilder.getPastPoint().getY(), pasteBuilder.getPastPoint().getZ());
|
||||||
|
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
|
||||||
|
if (pasteBuilder.isRotate()) {
|
||||||
|
ch.setTransform(new AffineTransform().rotateY(180));
|
||||||
|
v = v.add(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset.multiply(-1, 1, -1)).subtract(0, 0, 1);
|
||||||
|
} else {
|
||||||
|
v = v.subtract(dimensions.getX() / 2, 0, dimensions.getZ() / 2).subtract(offset);
|
||||||
|
}
|
||||||
|
pastePoint.set(v);
|
||||||
|
|
||||||
|
if (pasteBuilder.isReset()) {
|
||||||
|
e.setBlocks((Region) new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
|
||||||
|
if (pasteBuilder.getWaterLevel() != 0) {
|
||||||
|
e.setBlocks((Region) new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3().withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(pasteBuilder.isIgnoreAir()).build());
|
||||||
|
return e;
|
||||||
|
} catch (WorldEditException e) {
|
||||||
|
throw new SecurityException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Clipboard copy(Point minPoint, Point maxPoint, Point copyPoint) {
|
||||||
|
BukkitWorld bukkitWorld = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||||
|
CuboidRegion region = new CuboidRegion(bukkitWorld, minPoint.toBlockVector3(), maxPoint.toBlockVector3());
|
||||||
|
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
|
||||||
|
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(bukkitWorld, -1)) {
|
||||||
|
ForwardExtentCopy copy = new ForwardExtentCopy(
|
||||||
|
e, region, clipboard, region.getMinimumPoint()
|
||||||
|
);
|
||||||
|
|
||||||
|
copy.setCopyingEntities(false);
|
||||||
|
copy.setCopyingBiomes(false);
|
||||||
|
|
||||||
|
Operations.complete(copy);
|
||||||
|
clipboard.setOrigin(copyPoint.toBlockVector3());
|
||||||
|
return clipboard;
|
||||||
|
} catch (WorldEditException e) {
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean backup(Point minPoint, Point maxPoint, File file) {
|
||||||
|
Clipboard clipboard = copy(minPoint, maxPoint, minPoint);
|
||||||
|
try (ClipboardWriter writer = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(file))) {
|
||||||
|
writer.write(clipboard);
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean inWater(org.bukkit.World world, Vector tntPosition) {
|
||||||
|
Block block = world.getBlockAt(tntPosition.getBlockX(), tntPosition.getBlockY(), tntPosition.getBlockZ());
|
||||||
|
if (block.getType() == Material.WATER)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
BlockData data = block.getBlockData();
|
||||||
|
if (!(data instanceof Waterlogged))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ((Waterlogged) data).isWaterlogged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,25 +19,99 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.core.VersionDependent;
|
import io.papermc.paper.datacomponent.DataComponentTypes;
|
||||||
|
import io.papermc.paper.datacomponent.item.ItemContainerContents;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
||||||
|
import net.minecraft.server.level.ServerPlayerGameMode;
|
||||||
|
import net.minecraft.world.entity.player.Abilities;
|
||||||
|
import net.minecraft.world.level.GameType;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
public interface NMSWrapper {
|
import java.util.List;
|
||||||
NMSWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
import java.util.Optional;
|
||||||
|
|
||||||
void setInternalGameMode(Player player, GameMode gameMode);
|
public class NMSWrapper {
|
||||||
void setSlotToItemStack(Player player, Object o);
|
public static final NMSWrapper impl = new NMSWrapper();
|
||||||
|
|
||||||
void setGameStateChangeReason(Object packet);
|
private static final Reflection.Field<GameType> playerGameMode = Reflection.getField(ServerPlayerGameMode.class, GameType.class, 0);
|
||||||
void setPlayerBuildAbilities(Player player);
|
|
||||||
|
|
||||||
Material pathMaterial();
|
public void setInternalGameMode(Player player, GameMode gameMode) {
|
||||||
|
playerGameMode.set(((CraftPlayer) player).getHandle().gameMode, GameType.byId(gameMode.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
boolean checkItemStack(ItemStack item);
|
public void setSlotToItemStack(Player player, Object o) {
|
||||||
|
ClientboundContainerSetSlotPacket packetPlayInSetCreativeSlot = (ClientboundContainerSetSlotPacket) o;
|
||||||
|
int index = packetPlayInSetCreativeSlot.getSlot();
|
||||||
|
if (index >= 36 && index <= 44) {
|
||||||
|
index -= 36;
|
||||||
|
} else if (index > 44) {
|
||||||
|
index -= 5;
|
||||||
|
} else if (index <= 8) {
|
||||||
|
index = index - 8 + 36;
|
||||||
|
}
|
||||||
|
player.getInventory().setItem(index, CraftItemStack.asBukkitCopy(packetPlayInSetCreativeSlot.getItem()));
|
||||||
|
if (index < 9) player.getInventory().setHeldItemSlot(index);
|
||||||
|
player.updateInventory();
|
||||||
|
}
|
||||||
|
|
||||||
Object resetExplosionKnockback(Object packet);
|
public void setPlayerBuildAbilities(Player player) {
|
||||||
|
Abilities abilities = (((CraftPlayer) player).getHandle()).getAbilities();
|
||||||
|
abilities.mayBuild = true;
|
||||||
|
abilities.mayfly = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material pathMaterial() {
|
||||||
|
return Material.DIRT_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int threshold = 2048;
|
||||||
|
|
||||||
|
public boolean checkItemStack(ItemStack item) {
|
||||||
|
ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER);
|
||||||
|
if (data == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return drillDown(data.contents(), 0, 0) > threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int drillDown(List<ItemStack> items, int layer, int start) {
|
||||||
|
if (layer > 2) return start + threshold;
|
||||||
|
int invalid = start;
|
||||||
|
for (int i = start; i < items.size(); i++) {
|
||||||
|
ItemStack item = items.get(i);
|
||||||
|
if (item.isEmpty()) continue;
|
||||||
|
|
||||||
|
invalid += item.getAmount();
|
||||||
|
|
||||||
|
ItemContainerContents data = item.getData(DataComponentTypes.CONTAINER);
|
||||||
|
if (data == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ItemStack> subItems = data.contents();
|
||||||
|
if (subItems.size() > 1) {
|
||||||
|
invalid = drillDown(subItems, layer + 1, invalid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object resetExplosionKnockback(Object packet) {
|
||||||
|
ClientboundExplodePacket explosion = (ClientboundExplodePacket) packet;
|
||||||
|
|
||||||
|
return new ClientboundExplodePacket(
|
||||||
|
explosion.center(),
|
||||||
|
Optional.empty(),
|
||||||
|
explosion.explosionParticle(),
|
||||||
|
explosion.explosionSound()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,15 @@ import de.steamwar.Reflection;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.*;
|
import org.bukkit.block.*;
|
||||||
|
import org.bukkit.block.Skull;
|
||||||
import org.bukkit.block.data.*;
|
import org.bukkit.block.data.*;
|
||||||
import org.bukkit.block.data.type.Hopper;
|
|
||||||
import org.bukkit.block.data.type.*;
|
import org.bukkit.block.data.type.*;
|
||||||
|
import org.bukkit.block.data.type.Hopper;
|
||||||
|
import org.bukkit.craftbukkit.CraftWorld;
|
||||||
|
import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.block.BlockCanBuildEvent;
|
import org.bukkit.event.block.BlockCanBuildEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
@@ -82,27 +86,23 @@ public class PlaceItemUtils {
|
|||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Class<?> blockPosition = Reflection.getClass("net.minecraft.core.BlockPos");
|
private static final Reflection.Field<?> positionAccessor = Reflection.getField(CraftBlockState.class, BlockPos.class, 0);
|
||||||
private static final Reflection.Constructor blockPositionConstructor = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
|
private static final Reflection.Field<?> worldAccessor = Reflection.getField(CraftBlockState.class, CraftWorld.class, 0);
|
||||||
private static final Class<?> craftBlock = Reflection.getClass("org.bukkit.craftbukkit.block.CraftBlockState");
|
|
||||||
private static final Class<?> craftWorld = Reflection.getClass("org.bukkit.craftbukkit.CraftWorld");
|
|
||||||
private static final Reflection.Field<?> positionAccessor = Reflection.getField(craftBlock, blockPosition, 0);
|
|
||||||
private static final Reflection.Field<?> worldAccessor = Reflection.getField(craftBlock, craftWorld, 0);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempt to place an {@link ItemStack} the {@link Player} is holding against a {@link Block} inside the World.
|
* Attempt to place an {@link ItemStack} the {@link Player} is holding against a {@link Block} inside the World.
|
||||||
* This can be easily used inside the {@link org.bukkit.event.player.PlayerInteractEvent} to mimik placing a
|
* This can be easily used inside the {@link org.bukkit.event.player.PlayerInteractEvent} to mimik placing a
|
||||||
* block without any minecraft related GUI's etc. executing.
|
* block without any minecraft related GUI's etc. executing.
|
||||||
*
|
*
|
||||||
* @param player the Player placing the block
|
* @param player the Player placing the block
|
||||||
* @param itemStack the ItemStack to be placed
|
* @param itemStack the ItemStack to be placed
|
||||||
* @param against the Block at which the player aims (does not need to be in range of the player)
|
* @param against the Block at which the player aims (does not need to be in range of the player)
|
||||||
* @param againstSide the BlockFace the player aims
|
* @param againstSide the BlockFace the player aims
|
||||||
* @param hand the Hand the player is using
|
* @param hand the Hand the player is using
|
||||||
* @param force allow illegal states to be created by placing the block
|
* @param force allow illegal states to be created by placing the block
|
||||||
* @param applyPhysics apply physics while placing the block
|
* @param applyPhysics apply physics while placing the block
|
||||||
* @param rotateAway rotate everything in the opposite direction, so a block facing the Player will face away, and the other way round
|
* @param rotateAway rotate everything in the opposite direction, so a block facing the Player will face away, and the other way round
|
||||||
* @param playSound enables sound of placing
|
* @param playSound enables sound of placing
|
||||||
*/
|
*/
|
||||||
public PlaceItemResult placeItem(Player player, ItemStack itemStack, Block against, BlockFace againstSide, EquipmentSlot hand, boolean force, boolean applyPhysics, boolean rotateAway, boolean playSound) {
|
public PlaceItemResult placeItem(Player player, ItemStack itemStack, Block against, BlockFace againstSide, EquipmentSlot hand, boolean force, boolean applyPhysics, boolean rotateAway, boolean playSound) {
|
||||||
// If the ItemStack is null or air we cannot place it
|
// If the ItemStack is null or air we cannot place it
|
||||||
@@ -288,7 +288,7 @@ public class PlaceItemUtils {
|
|||||||
} else {
|
} else {
|
||||||
// If a BlockState is present set the Position and World to the Block you want to place
|
// If a BlockState is present set the Position and World to the Block you want to place
|
||||||
Location blockLocation = block.getLocation();
|
Location blockLocation = block.getLocation();
|
||||||
positionAccessor.set(blockState, blockPositionConstructor.invoke(blockLocation.getBlockX(), blockLocation.getBlockY(), blockLocation.getBlockZ()));
|
positionAccessor.set(blockState, new BlockPos(blockLocation.getBlockX(), blockLocation.getBlockY(), blockLocation.getBlockZ()));
|
||||||
worldAccessor.set(blockState, blockLocation.getWorld());
|
worldAccessor.set(blockState, blockLocation.getWorld());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +300,7 @@ public class PlaceItemUtils {
|
|||||||
Location blockmin = block.getLocation();
|
Location blockmin = block.getLocation();
|
||||||
Location blockmax = block.getLocation().add(1.0, 1.0, 1.0);
|
Location blockmax = block.getLocation().add(1.0, 1.0, 1.0);
|
||||||
if (
|
if (
|
||||||
!(max.getX() <= blockmin.getX() || min.getX() >= blockmax.getX() ||
|
!(max.getX() <= blockmin.getX() || min.getX() >= blockmax.getX() ||
|
||||||
max.getY() <= blockmin.getY() || min.getY() >= blockmax.getY() ||
|
max.getY() <= blockmin.getY() || min.getY() >= blockmax.getY() ||
|
||||||
max.getZ() <= blockmin.getZ() || min.getZ() >= blockmax.getZ())
|
max.getZ() <= blockmin.getZ() || min.getZ() >= blockmax.getZ())
|
||||||
) {
|
) {
|
||||||
@@ -369,8 +369,8 @@ public class PlaceItemUtils {
|
|||||||
return usedForcePlace.get() ? PlaceItemResult.SUCCESS_FORCE : PlaceItemResult.SUCCESS;
|
return usedForcePlace.get() ? PlaceItemResult.SUCCESS_FORCE : PlaceItemResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockFace[] axis = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST };
|
public BlockFace[] axis = {BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
|
||||||
public BlockFace[] radial = { BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST };
|
public BlockFace[] radial = {BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST};
|
||||||
|
|
||||||
public BlockFace yawToFace(float yaw) {
|
public BlockFace yawToFace(float yaw) {
|
||||||
return radial[Math.round(yaw / 45f) & 0x7];
|
return radial[Math.round(yaw / 45f) & 0x7];
|
||||||
|
|||||||
@@ -19,16 +19,32 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import lombok.experimental.UtilityClass;
|
||||||
import de.steamwar.core.VersionDependent;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface PlaceItemWrapper {
|
@UtilityClass
|
||||||
Map<Material, Material> ITEM_MATERIAL_TO_BLOCK_MATERIAL = new HashMap<>();
|
public class PlaceItemWrapper {
|
||||||
Map<Material, Material> BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL = new HashMap<>();
|
public static final Map<Material, Material> ITEM_MATERIAL_TO_BLOCK_MATERIAL = new HashMap<>();
|
||||||
|
public static final Map<Material, Material> BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL = new HashMap<>();
|
||||||
|
|
||||||
PlaceItemWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
static {
|
||||||
|
for (Material material : Material.values()) {
|
||||||
|
if (!material.isBlock()) continue;
|
||||||
|
if (material.isLegacy()) continue;
|
||||||
|
BlockData blockData = material.createBlockData();
|
||||||
|
Material placementMaterial = blockData.getPlacementMaterial();
|
||||||
|
if (material == placementMaterial) continue;
|
||||||
|
if (placementMaterial == Material.AIR) continue;
|
||||||
|
if (placementMaterial.isItem() && !placementMaterial.isBlock()) {
|
||||||
|
ITEM_MATERIAL_TO_BLOCK_MATERIAL.put(placementMaterial, material);
|
||||||
|
}
|
||||||
|
if (material.name().contains("WALL")) {
|
||||||
|
BLOCK_MATERIAL_TO_WALL_BLOCK_MATERIAL.put(placementMaterial, material);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-6
@@ -20,19 +20,33 @@
|
|||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import de.steamwar.core.BountifulWrapper;
|
import de.steamwar.core.BountifulWrapper;
|
||||||
import de.steamwar.core.VersionDependent;
|
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.REntity;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public interface PlayerMovementWrapper {
|
public class PlayerMovementWrapper {
|
||||||
Class<?> teleportPacket = REntity.teleportPacket;
|
Class<?> teleportPacket = REntity.teleportPacket;
|
||||||
Reflection.Field<Integer> teleportEntity = REntity.teleportEntity;
|
Reflection.Field<Integer> teleportEntity = REntity.teleportEntity;
|
||||||
BountifulWrapper.PositionSetter teleportPosition = REntity.teleportPosition;
|
BountifulWrapper.PositionSetter teleportPosition = REntity.teleportPosition;
|
||||||
|
|
||||||
PlayerMovementWrapper impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
public static final PlayerMovementWrapper impl = new PlayerMovementWrapper();
|
||||||
|
|
||||||
void setPosition(Player player, Object object);
|
public void setPosition(Player player, Object object) {
|
||||||
Object convertToOut(Player player, Object object);
|
ServerboundMovePlayerPacket packetPlayInFlying = ((ServerboundMovePlayerPacket) object);
|
||||||
|
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||||
|
if (packetPlayInFlying.hasPos) {
|
||||||
|
serverPlayer.setPosRaw(packetPlayInFlying.x, packetPlayInFlying.y, packetPlayInFlying.z);
|
||||||
|
}
|
||||||
|
if (packetPlayInFlying.hasRot) {
|
||||||
|
serverPlayer.setXRot(packetPlayInFlying.xRot);
|
||||||
|
serverPlayer.setYRot(packetPlayInFlying.yRot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object convertToOut(Player player, Object object) {
|
||||||
|
return object;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of the SteamWar software.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
|
||||||
|
|
||||||
import de.steamwar.bausystem.BauSystem;
|
|
||||||
import de.steamwar.core.VersionDependent;
|
|
||||||
|
|
||||||
public interface TickListener {
|
|
||||||
|
|
||||||
TickListener impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
|
||||||
|
|
||||||
default void init() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -19,28 +19,119 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.bausystem.BauSystem;
|
import de.steamwar.bausystem.BauSystem;
|
||||||
import de.steamwar.core.VersionDependent;
|
import net.minecraft.network.protocol.game.ClientboundTickingStatePacket;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.ServerTickRateManager;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
public interface TickManager extends Listener {
|
public class TickManager implements Listener {
|
||||||
TickManager impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
public static final TickManager impl = new TickManager();
|
||||||
|
|
||||||
void setTickRate(float tickRate);
|
private static final ServerTickRateManager manager = MinecraftServer.getServer().tickRateManager();
|
||||||
float getTickRate();
|
private static final Reflection.Field<Long> remainingSprintTicks = Reflection.getField(ServerTickRateManager.class, long.class, 0);
|
||||||
|
|
||||||
boolean canFreeze();
|
private boolean blockTpsPacket = true;
|
||||||
void setFreeze(boolean freeze);
|
private int totalSteps;
|
||||||
boolean isFrozen();
|
|
||||||
|
|
||||||
void stepTicks(int ticks);
|
private TickManager() {
|
||||||
boolean isStepping();
|
TinyProtocol.instance.addFilter(ClientboundTickingStatePacket.class, this::blockPacket);
|
||||||
|
}
|
||||||
|
|
||||||
void sprintTicks(int ticks);
|
private Object blockPacket(Player player, Object packet) {
|
||||||
boolean isSprinting();
|
if (blockTpsPacket) {
|
||||||
|
return new ClientboundTickingStatePacket(20, manager.isFrozen());
|
||||||
|
} else {
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setBlockTpsPacket(boolean block);
|
public boolean canFreeze() {
|
||||||
long getRemainingTicks();
|
return true;
|
||||||
long getDoneTicks();
|
}
|
||||||
long getTotalTicks();
|
|
||||||
|
public void setBlockTpsPacket(boolean block) {
|
||||||
|
blockTpsPacket = block;
|
||||||
|
if (blockTpsPacket) {
|
||||||
|
ClientboundTickingStatePacket packet = new ClientboundTickingStatePacket(20, manager.isFrozen());
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
|
||||||
|
} else {
|
||||||
|
ClientboundTickingStatePacket packet = new ClientboundTickingStatePacket(manager.tickrate(), manager.isFrozen());
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> TinyProtocol.instance.sendPacket(player, packet));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTickRate(float tickRate) {
|
||||||
|
if (isFrozen()) {
|
||||||
|
setFreeze(false);
|
||||||
|
}
|
||||||
|
manager.setTickRate(tickRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFrozen() {
|
||||||
|
return manager.isFrozen();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFreeze(boolean freeze) {
|
||||||
|
manager.setFrozen(freeze);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stepTicks(int ticks) {
|
||||||
|
if (manager.isSprinting()) {
|
||||||
|
manager.stopSprinting();
|
||||||
|
} else if (manager.isSteppingForward()) {
|
||||||
|
manager.stopStepping();
|
||||||
|
}
|
||||||
|
this.totalSteps = ticks;
|
||||||
|
manager.setFrozen(true);
|
||||||
|
manager.stepGameIfPaused(ticks);
|
||||||
|
manager.setFrozen(false);
|
||||||
|
Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), (bukkitTask) -> {
|
||||||
|
if (manager.isSteppingForward()) return;
|
||||||
|
manager.setFrozen(true);
|
||||||
|
bukkitTask.cancel();
|
||||||
|
}, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sprintTicks(int ticks) {
|
||||||
|
if (manager.isSteppingForward()) {
|
||||||
|
manager.stopStepping();
|
||||||
|
} else if (manager.isSprinting()) {
|
||||||
|
manager.stopSprinting();
|
||||||
|
}
|
||||||
|
this.totalSteps = ticks;
|
||||||
|
manager.requestGameToSprint(ticks, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSprinting() {
|
||||||
|
return manager.isSprinting();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStepping() {
|
||||||
|
return manager.isSteppingForward();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getTickRate() {
|
||||||
|
return manager.tickrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRemainingTicks() {
|
||||||
|
if (isSprinting()) {
|
||||||
|
return remainingSprintTicks.get(manager);
|
||||||
|
} else {
|
||||||
|
return manager.frozenTicksToRun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDoneTicks() {
|
||||||
|
return totalSteps - getRemainingTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTotalTicks() {
|
||||||
|
return totalSteps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.utils;
|
package de.steamwar.bausystem.utils;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.IncompleteRegionException;
|
import com.sk89q.worldedit.IncompleteRegionException;
|
||||||
import com.sk89q.worldedit.LocalSession;
|
import com.sk89q.worldedit.LocalSession;
|
||||||
@@ -34,6 +33,7 @@ import com.sk89q.worldedit.math.BlockVector3;
|
|||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.regions.RegionSelector;
|
import com.sk89q.worldedit.regions.RegionSelector;
|
||||||
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
|
import com.sk89q.worldedit.regions.selector.limit.SelectorLimits;
|
||||||
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.bausystem.shared.Pair;
|
import de.steamwar.bausystem.shared.Pair;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|||||||
+1
-1
@@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
package de.steamwar.bausystem.region.fixed.loader;
|
package de.steamwar.bausystem.region.fixed.loader;
|
||||||
|
|
||||||
import de.steamwar.bausystem.region.fixed.FixedGlobalRegionData;
|
|
||||||
import de.steamwar.bausystem.region.fixed.FixedGlobalRegion;
|
import de.steamwar.bausystem.region.fixed.FixedGlobalRegion;
|
||||||
|
import de.steamwar.bausystem.region.fixed.FixedGlobalRegionData;
|
||||||
import de.steamwar.bausystem.region.fixed.Prototype;
|
import de.steamwar.bausystem.region.fixed.Prototype;
|
||||||
import de.steamwar.bausystem.worlddata.WorldData;
|
import de.steamwar.bausystem.worlddata.WorldData;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|||||||
@@ -29,11 +29,6 @@ tasks.build {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":BauSystem:BauSystem_RegionFixed"))
|
implementation(project(":BauSystem:BauSystem_RegionFixed"))
|
||||||
implementation(project(":BauSystem:BauSystem_Main"))
|
implementation(project(":BauSystem:BauSystem_Main"))
|
||||||
implementation(project(":BauSystem:BauSystem_15"))
|
|
||||||
implementation(project(":BauSystem:BauSystem_18"))
|
|
||||||
implementation(project(":BauSystem:BauSystem_19"))
|
|
||||||
implementation(project(":BauSystem:BauSystem_20"))
|
|
||||||
implementation(project(":BauSystem:BauSystem_21"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<DevServer>("DevBau20") {
|
tasks.register<DevServer>("DevBau20") {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.listener;
|
package de.steamwar.fightsystem.listener;
|
||||||
|
|
||||||
import de.steamwar.Reflection;
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.core.TrickyTrialsWrapper;
|
import de.steamwar.core.TrickyTrialsWrapper;
|
||||||
import de.steamwar.fightsystem.ArenaMode;
|
import de.steamwar.fightsystem.ArenaMode;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ package com.comphenix.tinyprotocol;
|
|||||||
import de.steamwar.Reflection;
|
import de.steamwar.Reflection;
|
||||||
import de.steamwar.Reflection.Field;
|
import de.steamwar.Reflection.Field;
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.Core;
|
||||||
import io.netty.channel.*;
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelDuplexHandler;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelPromise;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -113,6 +116,10 @@ public class TinyProtocol implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> void addTypedFilter(Class<T> packetType, BiFunction<Player, T, Object> filter) {
|
||||||
|
packetFilters.computeIfAbsent(packetType, c -> new CopyOnWriteArrayList<>()).add((BiFunction) filter);
|
||||||
|
}
|
||||||
|
|
||||||
public void addFilter(Class<?> packetType, BiFunction<Player, Object, Object> filter) {
|
public void addFilter(Class<?> packetType, BiFunction<Player, Object, Object> filter) {
|
||||||
packetFilters.computeIfAbsent(packetType, c -> new CopyOnWriteArrayList<>()).add(filter);
|
packetFilters.computeIfAbsent(packetType, c -> new CopyOnWriteArrayList<>()).add(filter);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-6
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
import org.apache.tools.ant.taskdefs.condition.Os
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.util.Properties
|
import java.util.*
|
||||||
|
|
||||||
rootProject.name = "SteamWar"
|
rootProject.name = "SteamWar"
|
||||||
|
|
||||||
@@ -172,11 +172,6 @@ dependencyResolutionManagement {
|
|||||||
|
|
||||||
include(
|
include(
|
||||||
"BauSystem",
|
"BauSystem",
|
||||||
"BauSystem:BauSystem_15",
|
|
||||||
"BauSystem:BauSystem_18",
|
|
||||||
"BauSystem:BauSystem_19",
|
|
||||||
"BauSystem:BauSystem_20",
|
|
||||||
"BauSystem:BauSystem_21",
|
|
||||||
"BauSystem:BauSystem_Main",
|
"BauSystem:BauSystem_Main",
|
||||||
"BauSystem:BauSystem_RegionFixed"
|
"BauSystem:BauSystem_RegionFixed"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user