FULLCHUNK TECHHIDER + Performanceimprovement + Bugfix #211
@ -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<Integer> 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<NbtBase<?>>> list = cached.getListNbtModifier();
|
||||
packet = packet.shallowClone();
|
||||
e.setPacket(packet);
|
||||
StructureModifier<List<NbtBase<?>>> list = packet.getListNbtModifier();
|
||||
List<NbtBase<?>> 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<byte[]> byteArray = cached.getByteArrays();
|
||||
StructureModifier<byte[]> 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;
|
||||
for(int pos = 0; pos < 4096; pos++){
|
||||
if(Config.HiddenBlocks.contains(values.get(pos))){
|
||||
changed = true;
|
||||
values.set(pos, Config.ObfuscateWith);
|
||||
}
|
||||
}
|
||||
|
||||
if(Config.HiddenBlocks.contains(blockId))
|
||||
blockId = Config.ObfuscateWith;
|
||||
for(long l : values.backing)
|
||||
buffer.writeLong(l);
|
||||
|
||||
//if(blockId > 11336) Should not occur, but occurs
|
||||
|
||||
result <<= 14;
|
||||
result |= blockId;
|
||||
currentPos -= 14;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
Chaoscaot
hat
Hier sind noch Debug messages Hier sind noch Debug messages
|
||||
}
|
||||
}
|
||||
}).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<MultiBlockChangeInfo> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -61,7 +61,7 @@ public class FightTeam implements IFightTeam{
|
||||
|
||||
private FightPlayer leader;
|
||||
private final UUID designatedLeader;
|
||||
private final Set<FightPlayer> players = new HashSet<>();
|
||||
private final Map<Player, FightPlayer> players = new HashMap<>();
|
||||
private boolean ready;
|
||||
private final Set<Player> 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<TechHider.ChunkPos> 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<FightPlayer> getPlayers() {
|
||||
return players;
|
||||
public Collection<FightPlayer> 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();
|
||||
|
@ -68,8 +68,14 @@ public class WinconditionTechKO extends ListenerWincondition {
|
||||
@Override
|
||||
public void disable() {
|
||||
super.disable();
|
||||
if(smallerZcountdown != null){
|
||||
smallerZcountdown.disable();
|
||||
smallerZcountdown = null;
|
||||
}
|
||||
if(biggerZcountdown != null){
|
||||
biggerZcountdown.disable();
|
||||
biggerZcountdown = null;
|
||||
}
|
||||
task.cancel();
|
||||
}
|
||||
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren
Noch eine