Merge pull request '1.8 - 1.15 HullHider, fix Tab Hiding, fix appearing NameTags, improve Performance' (#419) from fixTagAndTab into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #419 Reviewed-by: YoyoNow <jwsteam@nidido.de>
Dieser Commit ist enthalten in:
Commit
f5a150c203
@ -46,6 +46,8 @@ dependencies {
|
||||
implementation project(":FightSystem_9")
|
||||
implementation project(":FightSystem_8")
|
||||
|
||||
compileOnly 'it.unimi.dsi:fastutil:8.5.6'
|
||||
|
||||
compileOnly swdep("Spigot-1.14")
|
||||
compileOnly swdep("WorldEdit-1.15")
|
||||
compileOnly swdep("SpigotCore")
|
||||
|
@ -21,18 +21,29 @@ package de.steamwar.fightsystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class BlockIdWrapper14 implements BlockIdWrapper {
|
||||
|
||||
private static final Class<?> worldServer = Reflection.getClass("{nms.server.level}.WorldServer");
|
||||
private static final Class<?> chunkProviderServer = Reflection.getClass("{nms.server.level}.ChunkProviderServer");
|
||||
private static final Reflection.MethodInvoker getChunkProvider = Reflection.getTypedMethod(worldServer, null, chunkProviderServer);
|
||||
private static final Class<?> playerChunkMap = Reflection.getClass("{nms.server.level}.PlayerChunkMap");
|
||||
private static final Reflection.FieldAccessor<?> getPlayerChunkMap = Reflection.getField(chunkProviderServer, playerChunkMap, 0);
|
||||
private static final Reflection.FieldAccessor<Int2ObjectMap> entityTrackers = Reflection.getField(playerChunkMap, Int2ObjectMap.class, 0);
|
||||
private static final Class<?> block = Reflection.getClass("{nms.world.level.block}.Block");
|
||||
private static final Class<?> iBlockData = Reflection.getClass("{nms.world.level.block.state}.IBlockData");
|
||||
private static final Class<?> blockPosition = Reflection.getClass("{nms.core}.BlockPosition");
|
||||
|
||||
private final Int2ObjectMap trackers;
|
||||
public BlockIdWrapper14() {
|
||||
trackers = entityTrackers.get(getPlayerChunkMap.get(getChunkProvider.invoke(getWorldHandle.invoke(Config.world))));
|
||||
}
|
||||
|
||||
private static final Reflection.MethodInvoker getCombinedId = Reflection.getTypedMethod(block, null, int.class, iBlockData);
|
||||
private static final Reflection.MethodInvoker getNMS = Reflection.getTypedMethod(Reflection.getClass("{obc}.block.CraftBlock"), "getNMS", iBlockData);
|
||||
@Override
|
||||
@ -41,11 +52,9 @@ public class BlockIdWrapper14 implements BlockIdWrapper {
|
||||
}
|
||||
|
||||
private static final Reflection.MethodInvoker getByCombinedId = Reflection.getTypedMethod(block, null, iBlockData, int.class);
|
||||
private static final Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", worldServer);
|
||||
private static final Reflection.ConstructorInvoker newBlockPosition = Reflection.getConstructor(blockPosition, int.class, int.class, int.class);
|
||||
private static final Reflection.MethodInvoker getTypeAndData = Reflection.getMethod(worldServer, null, blockPosition, iBlockData, int.class);
|
||||
private static final Reflection.MethodInvoker removeTileEntity = Reflection.getMethod(worldServer, Core.getVersion() > 15 ? "m" : "removeTileEntity", blockPosition);
|
||||
private static final Reflection.MethodInvoker getChunkProvider = Reflection.getTypedMethod(worldServer, null, chunkProviderServer);
|
||||
private static final Reflection.MethodInvoker flagDirty = Reflection.getMethod(chunkProviderServer, null, blockPosition);
|
||||
@Override
|
||||
public void setBlock(World world, int x, int y, int z, int blockState) {
|
||||
@ -58,6 +67,19 @@ public class BlockIdWrapper14 implements BlockIdWrapper {
|
||||
flagDirty.invoke(getChunkProvider.invoke(nworld), pos);
|
||||
}
|
||||
|
||||
private static final Class<?> entityTracker = Reflection.getClass("{nms.server.level}.PlayerChunkMap$EntityTracker");
|
||||
private static final Reflection.MethodInvoker updatePlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "b" : "updatePlayer", entityPlayer);
|
||||
@Override
|
||||
public void trackEntity(Player player, int entity) {
|
||||
updatePlayer.invoke(trackers.get(entity), getPlayer.invoke(player));
|
||||
}
|
||||
|
||||
private static final Reflection.MethodInvoker clearPlayer = Reflection.getMethod(entityTracker, Core.getVersion() > 15 ? "a" : "clear", entityPlayer);
|
||||
@Override
|
||||
public void untrackEntity(Player player, int entity) {
|
||||
clearPlayer.invoke(trackers.get(entity), getPlayer.invoke(player));
|
||||
}
|
||||
|
||||
private static final Reflection.MethodInvoker getMaterialByBlock = Reflection.getTypedMethod(Reflection.getClass("{obc}.util.CraftMagicNumbers"), "getMaterial", Material.class, block);
|
||||
private static final Reflection.MethodInvoker getBlockByBlockData = Reflection.getTypedMethod(iBlockData, null, block);
|
||||
@Override
|
||||
|
@ -42,7 +42,7 @@ public class HullHiderWrapper18 implements HullHiderWrapper {
|
||||
|
||||
changes.removeIf(change -> {
|
||||
BlockData data = Config.world.getBlockData(change.getX(), change.getY(), change.getZ());
|
||||
boolean unchanged = data.getMaterial() == Config.ObfuscateWith;
|
||||
boolean unchanged = data.getMaterial() == Config.ObfuscateWith || Config.HiddenBlocks.contains(data.getMaterial());
|
||||
if(!unchanged)
|
||||
blockdata.add(getState.invoke(data));
|
||||
return unchanged;
|
||||
|
@ -19,11 +19,25 @@
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class BlockIdWrapper8 implements BlockIdWrapper {
|
||||
|
||||
private static final Class<?> entityTracker = Reflection.getClass("{nms}.EntityTracker");
|
||||
private static final Reflection.FieldAccessor<?> getEntityTracker = Reflection.getField(worldServer, entityTracker, 0);
|
||||
private static final Class<?> intHashMap = Reflection.getClass("{nms}.IntHashMap");
|
||||
private static final Reflection.FieldAccessor<?> getTrackedEntities = Reflection.getField(entityTracker, intHashMap, 0);
|
||||
|
||||
private final Object trackers;
|
||||
public BlockIdWrapper8() {
|
||||
trackers = getTrackedEntities.get(getEntityTracker.get(getWorldHandle.invoke(Config.world)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int blockToId(Block block) {
|
||||
@ -39,6 +53,20 @@ public class BlockIdWrapper8 implements BlockIdWrapper {
|
||||
world.getBlockAt(x, y, z).setTypeIdAndData(blockState >> 4, (byte)(blockState & 0b1111), false);
|
||||
}
|
||||
|
||||
private static final Class<?> entityTrackerEntry = Reflection.getClass("{nms}.EntityTrackerEntry");
|
||||
private static final Reflection.MethodInvoker get = Reflection.getTypedMethod(intHashMap, "get", Object.class, int.class);
|
||||
private static final Reflection.MethodInvoker updatePlayer = Reflection.getMethod(entityTrackerEntry, "updatePlayer", entityPlayer);
|
||||
@Override
|
||||
public void trackEntity(Player player, int entity) {
|
||||
updatePlayer.invoke(get.invoke(trackers, entity), getPlayer.invoke(player));
|
||||
}
|
||||
|
||||
private static final Reflection.MethodInvoker clearPlayer = Reflection.getMethod(entityTrackerEntry, "a", entityPlayer);
|
||||
@Override
|
||||
public void untrackEntity(Player player, int entity) {
|
||||
clearPlayer.invoke(get.invoke(trackers, entity), getPlayer.invoke(player));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public Material idToMaterial(int blockState) {
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2024 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.fightsystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HullHiderWrapper8 implements HullHiderWrapper {
|
||||
|
||||
private static final Reflection.ConstructorInvoker newMultiBlockChange = Reflection.getConstructor("{nms}.PacketPlayOutMultiBlockChange", int.class, short[].class, Reflection.getClass("{nms}.Chunk"));
|
||||
private static final Reflection.MethodInvoker getHandle = Reflection.getMethod("{obc}.CraftChunk", "getHandle");
|
||||
@Override
|
||||
public Object generateBlockChangePacket(List<Hull.IntVector> changes) {
|
||||
changes.removeIf(change -> {
|
||||
Material material = Config.world.getBlockAt(change.getX(), change.getY(), change.getZ()).getType();
|
||||
return material == Config.ObfuscateWith || Config.HiddenBlocks.contains(material);
|
||||
});
|
||||
|
||||
if(changes.isEmpty())
|
||||
return null;
|
||||
|
||||
Hull.IntVector chunk = changes.get(0);
|
||||
chunk = new Hull.IntVector(chunk.getX() >> 4, chunk.getY() >> 4, chunk.getZ() >> 4);
|
||||
int xOffset = 16*chunk.getX();
|
||||
int zOffset = 16*chunk.getZ();
|
||||
short[] pos = new short[changes.size()];
|
||||
|
||||
for(int i = 0; i < changes.size(); i++) {
|
||||
Hull.IntVector change = changes.get(i);
|
||||
pos[i] = (short) (((change.getX()-xOffset) << 12) + ((change.getZ()-zOffset) << 8) + change.getY());
|
||||
}
|
||||
|
||||
return newMultiBlockChange.invoke(pos.length, pos, getHandle.invoke(Config.world.getChunkAt(chunk.getX(), chunk.getZ())));
|
||||
}
|
||||
}
|
@ -19,16 +19,28 @@
|
||||
|
||||
package de.steamwar.fightsystem.utils;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface BlockIdWrapper {
|
||||
Class<?> worldServer = Reflection.getClass("{nms.server.level}.WorldServer");
|
||||
Reflection.MethodInvoker getWorldHandle = Reflection.getTypedMethod(Reflection.getClass("{obc}.CraftWorld"), "getHandle", worldServer);
|
||||
|
||||
Class<?> craftPlayer = Reflection.getClass("{obc}.entity.CraftPlayer");
|
||||
Class<?> entityPlayer = Reflection.getClass("{nms.server.level}.EntityPlayer");
|
||||
Reflection.MethodInvoker getPlayer = Reflection.getTypedMethod(craftPlayer, "getHandle", entityPlayer);
|
||||
|
||||
BlockIdWrapper impl = VersionDependent.getVersionImpl(FightSystem.getPlugin());
|
||||
|
||||
Material idToMaterial(int blockState);
|
||||
int blockToId(Block block);
|
||||
void setBlock(World world, int x, int y, int z, int blockState);
|
||||
|
||||
void trackEntity(Player player, int entity);
|
||||
void untrackEntity(Player player, int entity);
|
||||
}
|
||||
|
@ -106,19 +106,17 @@ public class Hull {
|
||||
return players.contains(player) && region.inRegion(location) && !visibility.get(new IntVector(location).toId(region));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void addPlayer(Player player) {
|
||||
if(players.add(player)) {
|
||||
for(Entity entity : entities)
|
||||
player.hideEntity(FightSystem.getPlugin(), entity);
|
||||
BlockIdWrapper.impl.untrackEntity(player, entity.getEntityId());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void removePlayer(Player player, boolean activeRemoval) {
|
||||
if(players.remove(player) && activeRemoval) {
|
||||
for(Entity entity : entities)
|
||||
player.showEntity(FightSystem.getPlugin(), entity);
|
||||
BlockIdWrapper.impl.trackEntity(player, entity.getEntityId());
|
||||
// techhider triggers block change sending
|
||||
}
|
||||
}
|
||||
@ -128,12 +126,12 @@ public class Hull {
|
||||
if(region.inRegion(location) && !visibility.get(new IntVector(location).toId(region))) { //TODO more precise
|
||||
if(entities.add(entity)) {
|
||||
for(Player player : players)
|
||||
player.hideEntity(FightSystem.getPlugin(), entity);
|
||||
BlockIdWrapper.impl.untrackEntity(player, entity.getEntityId());
|
||||
}
|
||||
} else {
|
||||
if(entities.remove(entity)) {
|
||||
for(Player player : players)
|
||||
player.showEntity(FightSystem.getPlugin(), entity);
|
||||
BlockIdWrapper.impl.trackEntity(player, entity.getEntityId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -180,7 +178,6 @@ public class Hull {
|
||||
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> "[HullHider] initialisation finished: " + (System.currentTimeMillis() - start) + " ms, visible blocks: " + visibility.cardinality());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void updateBlockVisibility(Block b, Material changedType) {
|
||||
IntVector root = new IntVector(b.getX(), b.getY(), b.getZ());
|
||||
if (root.notInRegion(region))
|
||||
@ -211,7 +208,7 @@ public class Hull {
|
||||
if(uncoveredSet.contains(new IntVector(entity.getLocation()))) { //TODO more precise
|
||||
it.remove();
|
||||
for(Player player : players)
|
||||
player.showEntity(FightSystem.getPlugin(), entity);
|
||||
BlockIdWrapper.impl.trackEntity(player, entity.getEntityId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,13 +56,12 @@ import java.util.function.Function;
|
||||
|
||||
public class HullHider implements Listener {
|
||||
|
||||
public static final boolean ENABLED = TechHiderWrapper.ENABLED && Core.getVersion() >= 18;
|
||||
private final Map<FightTeam, Hull> hullMap = new HashMap<>();
|
||||
private final Hull[] hulls;
|
||||
private final Map<Class<?>, BiFunction<Player, Object, Object>> packetHiders = new HashMap<>();
|
||||
|
||||
public HullHider() {
|
||||
if(!ENABLED) {
|
||||
if(!TechHiderWrapper.ENABLED) {
|
||||
hulls = new Hull[0];
|
||||
return;
|
||||
}
|
||||
@ -77,8 +76,8 @@ public class HullHider implements Listener {
|
||||
if(Core.getVersion() >= 9 && Core.getVersion() < 18)
|
||||
posHiderGenerator("{nms.network.protocol.game}.PacketPlayOutCustomSoundEffect", int.class, 8.0);
|
||||
|
||||
new StateDependentListener(ENABLED, FightState.Schem, this);
|
||||
new StateDependent(ENABLED, FightState.Schem) {
|
||||
new StateDependentListener(TechHiderWrapper.ENABLED, FightState.Schem, this);
|
||||
new StateDependent(TechHiderWrapper.ENABLED, FightState.Schem) {
|
||||
@Override
|
||||
public void enable() {
|
||||
packetHiders.forEach(TinyProtocol.instance::addFilter);
|
||||
@ -91,11 +90,11 @@ public class HullHider implements Listener {
|
||||
packetHiders.forEach(TinyProtocol.instance::removeFilter);
|
||||
}
|
||||
}.register();
|
||||
new StateDependentTask(ENABLED, FightState.Schem, this::onTick, 0, 1);
|
||||
new StateDependentTask(TechHiderWrapper.ENABLED, FightState.Schem, this::onTick, 0, 1);
|
||||
}
|
||||
|
||||
public void initialize(FightTeam team) {
|
||||
if(!ENABLED)
|
||||
if(!TechHiderWrapper.ENABLED)
|
||||
return;
|
||||
|
||||
hullMap.get(team).initialize();
|
||||
@ -113,7 +112,7 @@ public class HullHider implements Listener {
|
||||
}
|
||||
|
||||
public void updatePlayer(Player player) {
|
||||
if(!ENABLED)
|
||||
if(!TechHiderWrapper.ENABLED)
|
||||
return;
|
||||
|
||||
FightTeam team = Fight.getPlayerTeam(player);
|
||||
@ -145,7 +144,7 @@ public class HullHider implements Listener {
|
||||
}
|
||||
|
||||
public boolean isBlockHidden(Player player, int x, int y, int z) {
|
||||
if(!ENABLED)
|
||||
if(!TechHiderWrapper.ENABLED)
|
||||
return false;
|
||||
|
||||
for (Hull hull : hulls)
|
||||
@ -156,7 +155,7 @@ public class HullHider implements Listener {
|
||||
}
|
||||
|
||||
public boolean blockPrecise(Player player, int chunkX, int chunkY, int chunkZ) {
|
||||
if(!ENABLED)
|
||||
if(!TechHiderWrapper.ENABLED)
|
||||
return false;
|
||||
|
||||
for (Hull hull : hulls)
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren