Remove some more wrappers

This commit is contained in:
2026-05-20 13:27:49 +02:00
parent 8da7956523
commit 2fd6c40b15
5 changed files with 80 additions and 133 deletions
@@ -21,7 +21,6 @@ package de.steamwar.bausystem.features.slaves.laufbau;
import com.sk89q.worldedit.blocks.SkullBlock; import com.sk89q.worldedit.blocks.SkullBlock;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.inventory.SWItem; import de.steamwar.inventory.SWItem;
import lombok.Getter; import lombok.Getter;
import lombok.ToString; 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.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(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)); addPixel(Material.MUD.createBlockData(), 0, 0, 0, 16, 14, 16, createItem("LAUFBAU_BLOCK_SOUL_SAND", Material.SOUL_SAND));
Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData(); Cocoa cocoaNorth = (Cocoa) Material.COCOA.createBlockData();
@@ -21,17 +21,22 @@ 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;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.command.SWCommand; 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 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.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
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.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@@ -61,7 +66,7 @@ public class NoClipCommand extends SWCommand implements Listener {
NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null); NoClipData noClipData = SWPlayer.of(player).getComponent(NoClipData.class).orElse(null);
if (noClipData == null) return o; if (noClipData == null) return o;
if (noClipData.lastTick == TPSUtils.currentTick.get()) 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(); noClipData.lastTick = TPSUtils.currentTick.get();
return o; return o;
}; };
@@ -71,7 +76,7 @@ public class NoClipCommand extends SWCommand implements Listener {
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);
if (noClipData == null) return o; if (noClipData == null) return o;
NMSWrapper.impl.setInternalGameMode(player, GameMode.CREATIVE); setInternalGameMode(player, GameMode.CREATIVE);
noClipData.lastTick = TPSUtils.currentTick.get(); noClipData.lastTick = TPSUtils.currentTick.get();
return o; return o;
}; };
@@ -79,13 +84,29 @@ public class NoClipCommand extends SWCommand implements Listener {
TinyProtocol.instance.addFilter(ServerboundPlayerActionPacket.class, second); TinyProtocol.instance.addFilter(ServerboundPlayerActionPacket.class, second);
TinyProtocol.instance.addFilter(ServerboundContainerClickPacket.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)) { 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; return o;
}; };
TinyProtocol.instance.addFilter(ServerboundSetCreativeModeSlotPacket.class, third); TinyProtocol.instance.addTypedFilter(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) @Register(help = true)
@@ -95,7 +116,9 @@ public class NoClipCommand extends SWCommand implements Listener {
swPlayer.removeComponent(NoClipData.class); swPlayer.removeComponent(NoClipData.class);
} else { } else {
player.setGameMode(GameMode.SPECTATOR); player.setGameMode(GameMode.SPECTATOR);
NMSWrapper.impl.setPlayerBuildAbilities(player); Abilities abilities = (((CraftPlayer) player).getHandle()).getAbilities();
abilities.mayBuild = true;
abilities.mayfly = true;
swPlayer.setComponent(new NoClipData()); swPlayer.setComponent(new NoClipData());
BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player); BauSystem.MESSAGE.send("OTHER_NOCLIP_SLOT_INFO", player);
@@ -19,8 +19,9 @@
package de.steamwar.bausystem.features.world; package de.steamwar.bausystem.features.world;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.linkage.Linked; 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.attribute.Attribute;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -32,6 +33,8 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import java.util.List;
@Linked @Linked
public class InventoryListener implements Listener { public class InventoryListener implements Listener {
@@ -57,7 +60,7 @@ public class InventoryListener implements Listener {
} }
stack.setItemMeta(meta); stack.setItemMeta(meta);
} }
if (NMSWrapper.impl.checkItemStack(stack)) { if (checkItemStack(stack)) {
e.setCurrentItem(null); e.setCurrentItem(null);
e.setCancelled(true); e.setCancelled(true);
return; return;
@@ -73,7 +76,7 @@ public class InventoryListener implements Listener {
for (int i = 0; i < content.length; i++) { for (int i = 0; i < content.length; i++) {
if (content[i] == null) continue; if (content[i] == null) continue;
int finalI = i; int finalI = i;
if (NMSWrapper.impl.checkItemStack(content[finalI])) { if (checkItemStack(content[finalI])) {
p.getInventory().setItem(i, null); p.getInventory().setItem(i, null);
} }
} }
@@ -82,11 +85,44 @@ public class InventoryListener implements Listener {
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent event) { public void onBlockPlace(BlockPlaceEvent event) {
Player p = event.getPlayer(); Player p = event.getPlayer();
if (NMSWrapper.impl.checkItemStack(event.getItemInHand())) { if (checkItemStack(event.getItemInHand())) {
event.setCancelled(true); event.setCancelled(true);
event.setBuild(false); event.setBuild(false);
p.getInventory().setItemInMainHand(null); p.getInventory().setItemInMainHand(null);
p.getInventory().setItemInOffHand(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; package de.steamwar.bausystem.features.world;
import com.comphenix.tinyprotocol.TinyProtocol; import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.bausystem.utils.NMSWrapper;
import de.steamwar.linkage.Linked; import de.steamwar.linkage.Linked;
import net.minecraft.network.protocol.game.ClientboundExplodePacket; import net.minecraft.network.protocol.game.ClientboundExplodePacket;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import java.util.Optional;
@Linked @Linked
public class NoCreativeKnockback { public class NoCreativeKnockback {
public NoCreativeKnockback() { public NoCreativeKnockback() {
TinyProtocol.instance.addFilter(ClientboundExplodePacket.class, (player, o) -> { TinyProtocol.instance.addTypedFilter(ClientboundExplodePacket.class, (player, o) -> {
if (player.getGameMode() != GameMode.CREATIVE) return o; if (player.getGameMode() != GameMode.CREATIVE) return o;
return NMSWrapper.impl.resetExplosionKnockback(o); return new ClientboundExplodePacket(
o.center(),
Optional.empty(),
o.explosionParticle(),
o.explosionSound()
);
}); });
} }
} }
@@ -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()
);
}
}