diff --git a/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java b/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java index 3bd22ae..ed722db 100644 --- a/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java +++ b/FightSystem_15/src/de/steamwar/fightsystem/utils/TechHider_15.java @@ -25,8 +25,6 @@ import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.wrappers.ChunkCoordIntPair; -import com.comphenix.protocol.wrappers.MultiBlockChangeInfo; import com.comphenix.protocol.wrappers.WrappedBlockData; import com.comphenix.protocol.wrappers.nbt.NbtBase; import com.comphenix.protocol.wrappers.nbt.NbtCompound; @@ -34,15 +32,12 @@ import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.IFightSystem; import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; -import net.minecraft.server.v1_15_R1.Block; -import net.minecraft.server.v1_15_R1.ChunkSection; import org.bukkit.Bukkit; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; import org.bukkit.entity.Player; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; +import java.nio.ByteBuffer; +import java.nio.LongBuffer; import java.util.List; import static de.steamwar.fightsystem.utils.ITechHider.bypass; @@ -64,6 +59,7 @@ public class TechHider_15 { ProtocolLibrary.getProtocolManager().getAsynchronousManager().registerAsyncHandler(new PacketAdapter(IFightSystem.getPlugin(), PacketType.Play.Server.MAP_CHUNK) { @Override public void onPacketSending(PacketEvent e) { + long startTime = System.nanoTime(); PacketContainer packet = e.getPacket(); StructureModifier ints = packet.getIntegers(); @@ -73,16 +69,9 @@ public class TechHider_15 { if(bypass(p, chunkX, chunkZ)) return; - PacketContainer cached = ITechHider.packetCache.get(packet); - if(cached != null){ - e.setPacket(cached); - return; - } - - cached = packet.shallowClone(); - ITechHider.packetCache.put(packet, cached); - e.setPacket(cached); - StructureModifier>> list = cached.getListNbtModifier(); + packet = packet.shallowClone(); + e.setPacket(packet); + StructureModifier>> list = packet.getListNbtModifier(); List> nmsTags = list.read(0); boolean changed = false; for(int i = nmsTags.size() - 1; i >= 0; i--){ @@ -99,9 +88,9 @@ public class TechHider_15 { } changed = false; - StructureModifier byteArray = cached.getByteArrays(); + StructureModifier byteArray = packet.getByteArrays(); int primaryBitMask = ints.read(2); - byte [] data = byteArray.read(0); + byte[] data = byteArray.read(0); ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(data.length + 100); int i = 0; @@ -116,13 +105,8 @@ public class TechHider_15 { i += 2; byte bitsPerBlock = data[i++]; buffer.writeByte(bitsPerBlock); - if(bitsPerBlock < 4) - bitsPerBlock = 4; - else if(bitsPerBlock > 8){ - bitsPerBlock = 14; - } - if(bitsPerBlock != 14){ + if(bitsPerBlock < 9){ int paletteLength = ITechHider.readVarInt(data, i); int paletteLengthLength = ITechHider.readVarIntLength(data, i); buffer.writeBytes(data, i, paletteLengthLength); @@ -148,66 +132,28 @@ public class TechHider_15 { i += dataArrayLengthLength; i += dataArrayLength * 8; }else{ + System.out.println("Full chunk: " + (chunkX*16) + " " + (chunkY*16) + " " + (chunkZ*16)); //Full Chunk/no palette, so the chunk has to be crawled through - //This didn't work, so workaround with MultiBlockChange-Packets was created int dataArrayLength = ITechHider.readVarInt(data, i); int dataArrayLengthLength = ITechHider.readVarIntLength(data, i); - buffer.writeBytes(data, i, dataArrayLengthLength + dataArrayLength * 8); - i += dataArrayLengthLength + dataArrayLength * 8; + buffer.writeBytes(data, i, dataArrayLengthLength); + i += dataArrayLengthLength; + System.out.println(dataArrayLength + " " + bitsPerBlock); - /* - ByteBuf chunkData = UnpooledByteBufAllocator.DEFAULT.directBuffer(dataArrayLength * 8); - chunkData.writeBytes(data, i, dataArrayLength * 8); + ByteBuffer source = ByteBuffer.wrap(data, i, dataArrayLength * 8); + VariableValueArray values = new VariableValueArray(bitsPerBlock, dataArrayLength, source.asLongBuffer()); - int bitsOver = 0; // Anzahl an Bits, die aus dem letzten Durchlauf noch über sind - int lastBits = 0; // Die letzten Bits aus dem vorigen Durchlauf - while(chunkData.readableBytes() > 0){ - int currentPos = 70 - bitsOver; // 14 * 5, Die Größe des Bitshifts, der durchgeführt werden muss, um den ersten Block zu lesen - if(currentPos >= 64) - currentPos -= 14; - - long values = chunkData.readLong(); - long result = 0; - - int newLastBits = (int)(values >> currentPos); - while(currentPos >= 0){ - int blockId = (int)(values >> currentPos) & 0x3FFF; - - if(currentPos > 50){ //64 - 14, Prüfen auf Ende des Longs - int offset = 14 - (currentPos - 50); - blockId |= (data[i+14] << (offset + 8) | data[i+15] << offset) & 0x3FFF; - } - - if(Config.HiddenBlocks.contains(blockId)) - blockId = Config.ObfuscateWith; - - //if(blockId > 11336) Should not occur, but occurs - - result <<= 14; - result |= blockId; - currentPos -= 14; + for(int pos = 0; pos < 4096; pos++){ + if(Config.HiddenBlocks.contains(values.get(pos))){ + changed = true; + values.set(pos, Config.ObfuscateWith); } + } - if(currentPos > -14){ // Check the first bits of the chunk - int blockId = ((int)values << -currentPos | lastBits) & 0x3FFF; - if(Config.HiddenBlocks.contains(blockId)) - blockId = Config.ObfuscateWith; - result <<= (14 + currentPos); - result |= blockId >> -currentPos; - } + for(long l : values.backing) + buffer.writeLong(l); - lastBits = newLastBits; - bitsOver += 8; - if(bitsOver >= 14) - bitsOver -= 14; - - buffer.writeLong(result); - i += 8; - }*/ - - final int cY = chunkY; - Bukkit.getScheduler().runTaskLater(IFightSystem.getPlugin(), - () -> fullChunkHider(p, chunkX, cY, chunkZ), 1); + i += dataArrayLength * 8; } primaryBitMask >>= 1; @@ -219,44 +165,53 @@ public class TechHider_15 { data = new byte[buffer.readableBytes()]; buffer.readBytes(data); byteArray.write(0, data); + System.out.println("changes: " + (System.nanoTime() - startTime)); + }else{ + System.out.println("without changes: " + (System.nanoTime() - startTime)); } } }).start(ITechHider.threadMultiplier * 4); } - private static void fullChunkHider(Player player, int chunkX, int chunkY, int chunkZ){ - if(!player.isOnline()) - return; + private static final class VariableValueArray { + private final long[] backing; + private final int bitsPerValue; + private final long valueMask; - ArrayList blockChangeList = new ArrayList<>(); - ChunkCoordIntPair chunkCoords = new ChunkCoordIntPair(chunkX, chunkZ); - ChunkSection chunk = ((CraftWorld) WORLD).getHandle().getChunkAt(chunkX, chunkZ).getSections()[chunkY]; //This takes ~70ms async. - if(ChunkSection.a(chunk)) - return; - - int minY = chunkY * 16; - for(int x = 0; x < 16; x++){ - for(int y = 0; y < 16; y++){ - for(int z = 0; z < 16; z++){ - if(Config.HiddenBlocks.contains(Block.REGISTRY_ID.getId(chunk.getType(x, y, z)))) - blockChangeList.add(new MultiBlockChangeInfo((short)(x << 12 | z << 8 | (y + minY)), WRAPPED_BLOCK_DATA, chunkCoords)); - } - } + public VariableValueArray(int bitsPerEntry, int dataArrayLength, LongBuffer buffer) { + this.bitsPerValue = bitsPerEntry; + this.backing = new long[dataArrayLength]; + buffer.get(backing); + this.valueMask = (1L << this.bitsPerValue) - 1; } - if(blockChangeList.isEmpty()) - return; + public int get(int index) { + index *= bitsPerValue; + int i0 = index >> 6; + int i1 = index & 0x3f; - PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.MULTI_BLOCK_CHANGE); - packet.getChunkCoordIntPairs().write(0, chunkCoords); - packet.getMultiBlockChangeInfoArrays().write(0, blockChangeList.toArray(new MultiBlockChangeInfo[0])); + long value = backing[i0] >>> i1; - try { - ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); - } catch (InvocationTargetException e) { - throw new SecurityException("Something went wrong sending the multiblockchange packet", e); - } catch (NullPointerException e){ - //ignored, player offline + // The value is divided over two long values + if (i1 + bitsPerValue > 64) { + value |= backing[++i0] << 64 - i1; + } + + return (int) (value & valueMask); + } + + public void set(int index, int value) { + index *= bitsPerValue; + int i0 = index >> 6; + int i1 = index & 0x3f; + + backing[i0] = this.backing[i0] & ~(this.valueMask << i1) | (value & valueMask) << i1; + int i2 = i1 + bitsPerValue; + // The value is divided over two long values + if (i2 > 64) { + i0++; + backing[i0] = backing[i0] & -(1L << i2 - 64) | value >> 64 - i1; + } } } } diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/TechKOCountdown.java b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/TechKOCountdown.java index 47ab7bb..af2378d 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/countdown/TechKOCountdown.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/countdown/TechKOCountdown.java @@ -36,7 +36,7 @@ public class TechKOCountdown extends Countdown { @Override final String countdownCounting() { - return "bis " + team.getColoredName() + " §7einen Schuss abgegeben haben muss!"; + return "bis " + team.getColoredName() + " §feinen Schuss abgegeben haben muss!"; } @Override diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java index 57380a2..a46ca76 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -61,7 +61,7 @@ public class FightTeam implements IFightTeam{ private FightPlayer leader; private final UUID designatedLeader; - private final Set players = new HashSet<>(); + private final Map players = new HashMap<>(); private boolean ready; private final Set invited = new HashSet<>(); private final String name; @@ -123,21 +123,15 @@ public class FightTeam implements IFightTeam{ } public void teleportToSpawn(){ - for(FightPlayer player : players){ - player.getPlayer().teleport(spawn); - } + players.forEach((player, fp) -> player.teleport(spawn)); } public FightPlayer getFightPlayer(Player player) { - for(FightPlayer fightPlayer : players) { - if(fightPlayer.getPlayer().equals(player)) - return fightPlayer; - } - return null; + return players.get(player); } public boolean allPlayersOut() { - for(FightPlayer fightPlayer : players) { + for(FightPlayer fightPlayer : players.values()) { if(fightPlayer.isLiving()) return false; } @@ -146,11 +140,7 @@ public class FightTeam implements IFightTeam{ @Override public boolean isPlayerInTeam(Player player) { - for(FightPlayer fightPlayer : players) { - if(fightPlayer.getPlayer().equals(player)) - return true; - } - return false; + return players.containsKey(player); } @Override @@ -166,15 +156,13 @@ public class FightTeam implements IFightTeam{ } public void broadcast(String message) { - for(FightPlayer fightPlayer : players) { - fightPlayer.sendMessage(message); - } + players.forEach((player, fp) -> player.sendMessage(message)); } public FightPlayer addMember(Player player) { final List chunksToReload = TechHider.prepareChunkReload(player); FightPlayer fightPlayer = new FightPlayer(player, this); - players.add(fightPlayer); + players.put(player, fightPlayer); invited.remove(player); team.addEntry(player.getName()); @@ -227,7 +215,7 @@ public class FightTeam implements IFightTeam{ public void setLeader(FightPlayer leader) { if (leader == null){ if(!players.isEmpty()) { - setLeader(players.iterator().next()); + setLeader(players.values().iterator().next()); Bukkit.broadcastMessage(FightSystem.PREFIX + "§aDer Spieler §e" + this.leader.getPlayer().getName() + " §aist nun Leader von Team " + getColoredName() + "§a!"); }else if(Config.Ranked){ RankedPlayerLeftWincondition.leaderQuit(this); @@ -263,8 +251,8 @@ public class FightTeam implements IFightTeam{ inventory.setItem(0, new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).removeAllAttributs().addEnchantment(Enchantment.DURABILITY, 1).setDisplayName("§e" + Config.GameName + " wählen").build()); } - public Set getPlayers() { - return players; + public Collection getPlayers() { + return players.values(); } public boolean isReady() { @@ -398,7 +386,7 @@ public class FightTeam implements IFightTeam{ public double getHeartRatio(){ int maximumHearts = 0; double currentHearts = 0; - for(FightPlayer fightPlayer : players){ + for(FightPlayer fightPlayer : players.values()){ maximumHearts += 20; if(!fightPlayer.isLiving()) continue; @@ -411,7 +399,7 @@ public class FightTeam implements IFightTeam{ } public void loadKits(){ - for(FightPlayer fightPlayer : players) { + for(FightPlayer fightPlayer : players.values()) { if(fightPlayer.getPlayer() == null) continue; fightPlayer.getPlayer().getInventory().clear(); diff --git a/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionTechKO.java b/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionTechKO.java index 7210c4d..117e966 100644 --- a/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionTechKO.java +++ b/FightSystem_Main/src/de/steamwar/fightsystem/winconditions/WinconditionTechKO.java @@ -68,8 +68,14 @@ public class WinconditionTechKO extends ListenerWincondition { @Override public void disable() { super.disable(); - smallerZcountdown.disable(); - biggerZcountdown.disable(); + if(smallerZcountdown != null){ + smallerZcountdown.disable(); + smallerZcountdown = null; + } + if(biggerZcountdown != null){ + biggerZcountdown.disable(); + biggerZcountdown = null; + } task.cancel(); }