Merge branch 'main' into FightSystem/fix-tech-and-hull-hider

# Conflicts:
#	FightSystem/FightSystem_Core/src/de/steamwar/fightsystem/utils/HullHider.java
#	SpigotCore/SpigotCore_Main/src/de/steamwar/core/events/AntiNocom.java
This commit is contained in:
2026-05-21 12:59:22 +02:00
68 changed files with 796 additions and 985 deletions
@@ -80,7 +80,7 @@ public class SimulatorCursor implements Listener {
}
public SimulatorCursor() {
BiFunction<Player, Object, Object> function = (player, object) -> {
BiFunction<Player, ServerboundMovePlayerPacket, Object> function = (player, object) -> {
calcCursor(player);
return object;
};
@@ -21,7 +21,6 @@ package de.steamwar.bausystem.features.slaves.laufbau;
import com.sk89q.worldedit.blocks.SkullBlock;
import com.sk89q.worldedit.world.block.BaseBlock;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.inventory.SWItem;
import lombok.Getter;
import lombok.ToString;
@@ -99,7 +98,7 @@ public class BlockBoundingBox {
// addPixel(Material.COBWEB.createBlockData(), 0, 0, 0, 0, 0, 0, createItem("LAUFBAU_BLOCK_COBWEB", Material.COBWEB));
addPixel(Material.END_STONE.createBlockData(), 0, 0, 0, 16, 16, 16, null);
addPixel(NMSWrapper.impl.pathMaterial().createBlockData(), 0, 0, 0, 16, 15, 16, createItem("LAUFBAU_BLOCK_GRASS_PATH", NMSWrapper.impl.pathMaterial()));
addPixel(Material.DIRT_PATH.createBlockData(), 0, 0, 0, 16, 15, 16, createItem("LAUFBAU_BLOCK_GRASS_PATH", Material.DIRT_PATH));
addPixel(Material.MUD.createBlockData(), 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SOUL_SAND", Material.SOUL_SAND));
Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData();
@@ -21,17 +21,22 @@ package de.steamwar.bausystem.features.util;
import com.comphenix.tinyprotocol.TinyProtocol;
import com.mojang.authlib.GameProfile;
import de.steamwar.Reflection;
import de.steamwar.bausystem.BauSystem;
import de.steamwar.bausystem.features.tpslimit.TPSUtils;
import de.steamwar.bausystem.utils.BauMemberUpdateEvent;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.command.SWCommand;
import de.steamwar.core.ProtocolWrapper;
import de.steamwar.core.SWPlayer;
import de.steamwar.linkage.Linked;
import net.minecraft.network.protocol.game.*;
import net.minecraft.server.level.ServerPlayerGameMode;
import net.minecraft.world.entity.player.Abilities;
import net.minecraft.world.level.GameType;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -57,11 +62,11 @@ public class NoClipCommand extends SWCommand implements Listener {
public NoClipCommand() {
super("noclip", "nc");
BiFunction<Player, Object, Object> first = (player, o) -> {
BiFunction<Player, ServerboundMovePlayerPacket, Object> first = (player, o) -> {
NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null);
if (noClipData == null) return o;
if (noClipData.lastTick == TPSUtils.currentTick.get()) return o;
NMSWrapper.impl.setInternalGameMode(player, GameMode.SPECTATOR);
setInternalGameMode(player, GameMode.SPECTATOR);
noClipData.lastTick = TPSUtils.currentTick.get();
return o;
};
@@ -71,7 +76,7 @@ public class NoClipCommand extends SWCommand implements Listener {
BiFunction<Player, Object, Object> second = (player, o) -> {
NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null);
if (noClipData == null) return o;
NMSWrapper.impl.setInternalGameMode(player, GameMode.CREATIVE);
setInternalGameMode(player, GameMode.CREATIVE);
noClipData.lastTick = TPSUtils.currentTick.get();
return o;
};
@@ -79,15 +84,31 @@ public class NoClipCommand extends SWCommand implements Listener {
TinyProtocol.instance.addFilter(ServerboundPlayerActionPacket.class, second);
TinyProtocol.instance.addFilter(ServerboundContainerClickPacket.class, second);
BiFunction<Player, Object, Object> third = (player, o) -> {
BiFunction<Player, ServerboundSetCreativeModeSlotPacket, Object> third = (player, o) -> {
if (SWPlayer.of(player).hasComponent(NoClipData.class)) {
NMSWrapper.impl.setSlotToItemStack(player, o);
int index = o.slotNum();
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(o.itemStack()));
if (index < 9) player.getInventory().setHeldItemSlot(index);
player.updateInventory();
}
return o;
};
TinyProtocol.instance.addFilter(ServerboundSetCreativeModeSlotPacket.class, third);
}
private static final Reflection.Field<GameType> playerGameMode = Reflection.getField(ServerPlayerGameMode.class, GameType.class, 0);
private void setInternalGameMode(Player player, GameMode gameMode) {
playerGameMode.set(((CraftPlayer) player).getHandle().gameMode, GameType.byId(gameMode.getValue()));
}
@Register(help = true)
public void genericCommand(@Validator Player player) {
SWPlayer swPlayer = SWPlayer.of(player);
@@ -95,7 +116,9 @@ public class NoClipCommand extends SWCommand implements Listener {
swPlayer.removeComponent(NoClipData.class);
} else {
player.setGameMode(GameMode.SPECTATOR);
NMSWrapper.impl.setPlayerBuildAbilities(player);
Abilities abilities = (((CraftPlayer) player).getHandle()).getAbilities();
abilities.mayBuild = true;
abilities.mayfly = true;
swPlayer.setComponent(new NoClipData());
BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player);
@@ -19,8 +19,9 @@
package de.steamwar.bausystem.features.world;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.linkage.Linked;
import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.datacomponent.item.ItemContainerContents;
import org.bukkit.attribute.Attribute;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
@@ -32,6 +33,8 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.List;
@Linked
public class InventoryListener implements Listener {
@@ -57,7 +60,7 @@ public class InventoryListener implements Listener {
}
stack.setItemMeta(meta);
}
if (NMSWrapper.impl.checkItemStack(stack)) {
if (checkItemStack(stack)) {
e.setCurrentItem(null);
e.setCancelled(true);
return;
@@ -73,7 +76,7 @@ public class InventoryListener implements Listener {
for (int i = 0; i < content.length; i++) {
if (content[i] == null) continue;
int finalI = i;
if (NMSWrapper.impl.checkItemStack(content[finalI])) {
if (checkItemStack(content[finalI])) {
p.getInventory().setItem(i, null);
}
}
@@ -82,11 +85,44 @@ public class InventoryListener implements Listener {
@EventHandler(ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent event) {
Player p = event.getPlayer();
if (NMSWrapper.impl.checkItemStack(event.getItemInHand())) {
if (checkItemStack(event.getItemInHand())) {
event.setCancelled(true);
event.setBuild(false);
p.getInventory().setItemInMainHand(null);
p.getInventory().setItemInOffHand(null);
}
}
private static final int threshold = 2048;
private 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;
}
}
@@ -20,18 +20,24 @@
package de.steamwar.bausystem.features.world;
import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.linkage.Linked;
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
import org.bukkit.GameMode;
import java.util.Optional;
@Linked
public class NoCreativeKnockback {
public NoCreativeKnockback() {
TinyProtocol.instance.addFilter(ClientboundExplodePacket.class, (player, o) -> {
if (player.getGameMode() != GameMode.CREATIVE) return o;
return NMSWrapper.impl.resetExplosionKnockback(o);
return new ClientboundExplodePacket(
o.center(),
Optional.empty(),
o.explosionParticle(),
o.explosionSound()
);
});
}
}
@@ -101,7 +101,7 @@ public class SignEdit implements Listener {
}
{
TinyProtocol.instance.addTypedFilter(ServerboundSignUpdatePacket.class, (player, o) -> {
TinyProtocol.instance.addFilter(ServerboundSignUpdatePacket.class, (player, o) -> {
Bukkit.getScheduler().runTask(BauSystem.getInstance(), () -> {
ServerLevel serverLevel = ((CraftWorld) player.getWorld()).getHandle();
Block signLoc = CraftBlock.at(serverLevel, o.getPos());
@@ -114,8 +114,8 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
return packet;
};
TinyProtocol.instance.addTypedFilter(ServerboundMovePlayerPacket.Pos.class, positionSetter);
TinyProtocol.instance.addTypedFilter(ServerboundMovePlayerPacket.PosRot.class, positionSetter);
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.Pos.class, positionSetter);
TinyProtocol.instance.addFilter(ServerboundMovePlayerPacket.PosRot.class, positionSetter);
}
@EventHandler
@@ -1,117 +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 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.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 NMSWrapper {
public static final NMSWrapper impl = new NMSWrapper();
private static final Reflection.Field<GameType> playerGameMode = Reflection.getField(ServerPlayerGameMode.class, GameType.class, 0);
public void setInternalGameMode(Player player, GameMode gameMode) {
playerGameMode.set(((CraftPlayer) player).getHandle().gameMode, GameType.byId(gameMode.getValue()));
}
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();
}
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()
);
}
}
@@ -42,7 +42,7 @@ public class TickManager implements Listener {
TinyProtocol.instance.addFilter(ClientboundTickingStatePacket.class, this::blockPacket);
}
private Object blockPacket(Player player, Object packet) {
private Object blockPacket(Player player, ClientboundTickingStatePacket packet) {
if (blockTpsPacket) {
return new ClientboundTickingStatePacket(20, manager.isFrozen());
} else {