SteamWar/FightSystem
Archiviert
13
1

Prepare RLE Recordings
Einige Prüfungen sind fehlgeschlagen
SteamWarCI Build failed

Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Lixfel 2023-06-03 14:15:35 +02:00
Ursprung c7248cfb45
Commit 1934debfd7
8 geänderte Dateien mit 99 neuen und 20 gelöschten Zeilen

Datei anzeigen

@ -85,7 +85,7 @@ public class FlatteningWrapper14 implements FlatteningWrapper {
@Override @Override
public boolean doRecord(BlockPhysicsEvent e) { public boolean doRecord(BlockPhysicsEvent e) {
return e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR; return e.getBlock() == e.getSourceBlock() || e.getChangedType() == Material.AIR; //TODO why air
} }
@Override @Override
@ -94,8 +94,8 @@ public class FlatteningWrapper14 implements FlatteningWrapper {
} }
@Override @Override
public boolean checkPistonMoving(Block block) { public Material getMovingPiston() {
return block.getType() == Material.MOVING_PISTON; return Material.MOVING_PISTON;
} }
@Override @Override

Datei anzeigen

@ -70,8 +70,8 @@ public class FlatteningWrapper8 implements FlatteningWrapper {
} }
@Override @Override
public boolean checkPistonMoving(Block block) { public Material getMovingPiston() {
return block.getType() == Material.PISTON_MOVING_PIECE; return Material.PISTON_MOVING_PIECE;
} }
@Override @Override

Datei anzeigen

@ -104,7 +104,7 @@ public class FightSystem extends JavaPlugin {
techHider = new TechHiderWrapper(); techHider = new TechHiderWrapper();
new FightWorld(); new FightWorld();
new FightUI(); new FightUI();
new FightStatistics(); //new FightStatistics();
new BungeeFightInfo(); new BungeeFightInfo();
new WinconditionAllDead(); new WinconditionAllDead();

Datei anzeigen

@ -33,6 +33,7 @@ import de.steamwar.fightsystem.utils.Region;
import de.steamwar.fightsystem.utils.WorldeditWrapper; import de.steamwar.fightsystem.utils.WorldeditWrapper;
import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicNode;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material;
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;
@ -44,13 +45,15 @@ import java.util.Set;
public class PrepareSchem implements Listener { public class PrepareSchem implements Listener {
private static final Material MOVING_PISTON = FlatteningWrapper.impl.getMovingPiston();
private final Set<Vector> stationaryMovingPistons = new HashSet<>(); private final Set<Vector> stationaryMovingPistons = new HashSet<>();
public PrepareSchem() { public PrepareSchem() {
new OneShotStateDependent(ArenaMode.Prepare, FightState.PostSchemSetup, () -> Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> { new OneShotStateDependent(ArenaMode.Prepare, FightState.PostSchemSetup, () -> Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
stationaryMovingPistons.clear(); stationaryMovingPistons.clear();
Fight.getUnrotated().getSchemRegion().forEach((x, y, z) -> { Fight.getUnrotated().getSchemRegion().forEach((x, y, z) -> {
if(FlatteningWrapper.impl.checkPistonMoving(Config.world.getBlockAt(x, y, z))) if(Config.world.getBlockAt(x, y, z).getType() == MOVING_PISTON)
stationaryMovingPistons.add(new Vector(x, y, z)); stationaryMovingPistons.add(new Vector(x, y, z));
}); });
}, 1)); }, 1));
@ -73,7 +76,7 @@ public class PrepareSchem implements Listener {
try{ try{
region.forEach((x, y, z) -> { region.forEach((x, y, z) -> {
if(FlatteningWrapper.impl.checkPistonMoving(Config.world.getBlockAt(x, y, z)) && !stationaryMovingPistons.contains(new Vector(x, y, z))){ if(Config.world.getBlockAt(x, y, z).getType() == MOVING_PISTON && !stationaryMovingPistons.contains(new Vector(x, y, z))){
FightSystem.getMessage().broadcast("PREPARE_ACTIVE_PISTON"); FightSystem.getMessage().broadcast("PREPARE_ACTIVE_PISTON");
Bukkit.shutdown(); Bukkit.shutdown();
throw new IllegalStateException(); throw new IllegalStateException();

Datei anzeigen

@ -22,6 +22,7 @@ package de.steamwar.fightsystem.listener;
import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.Reflection;
import com.comphenix.tinyprotocol.TinyProtocol; import com.comphenix.tinyprotocol.TinyProtocol;
import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.ArenaMode;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.fight.FightPlayer;
@ -32,9 +33,11 @@ import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.fightsystem.states.StateDependentTask; import de.steamwar.fightsystem.states.StateDependentTask;
import de.steamwar.fightsystem.utils.*; import de.steamwar.fightsystem.utils.*;
import de.steamwar.techhider.BlockIds;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -48,7 +51,7 @@ import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.*; import org.bukkit.event.player.*;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.Random; import java.util.*;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -75,6 +78,8 @@ public class Recording implements Listener {
CraftbukkitWrapper.impl.entityIterator().filter(filter).map(entity -> (Entity) getBukkitEntity.invoke(entity)).forEach(consumer); CraftbukkitWrapper.impl.entityIterator().filter(filter).map(entity -> (Entity) getBukkitEntity.invoke(entity)).forEach(consumer);
} }
private final HashMap<Integer, TreeSet<Block>> changedBlocks = new HashMap<>();
public Recording() { public Recording() {
new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this); new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this);
new StateDependentListener(ArenaMode.AntiReplay, FightState.All, BountifulWrapper.impl.newHandSwapRecorder()); new StateDependentListener(ArenaMode.AntiReplay, FightState.All, BountifulWrapper.impl.newHandSwapRecorder());
@ -88,6 +93,7 @@ public class Recording implements Listener {
public void disable() { public void disable() {
Fight.teams().forEach(Recording.this::despawnTeam); Fight.teams().forEach(Recording.this::despawnTeam);
despawnTNT(); despawnTNT();
sendChangedBlocks();
} }
}.register(); }.register();
new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) { new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) {
@ -107,19 +113,22 @@ public class Recording implements Listener {
} }
}.register(); }.register();
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> { new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> {
GlobalRecorder.getInstance().tick();
if(FightState.getFightState() == FightState.SPECTATE || !GlobalRecorder.getInstance().recording()) if(FightState.getFightState() == FightState.SPECTATE || !GlobalRecorder.getInstance().recording())
return; return;
sendChangedBlocks();
iterateOverEntities(primedTnt::isInstance, this::trackEntity); iterateOverEntities(primedTnt::isInstance, this::trackEntity);
}, 1, 1);
GlobalRecorder.getInstance().tick();
}, 0, 1);
} }
private void trackEntity(Entity entity) { private void trackEntity(Entity entity) {
if(entity.getVelocity().lengthSquared() != 0) {
GlobalRecorder.getInstance().entityMoves(entity); GlobalRecorder.getInstance().entityMoves(entity);
GlobalRecorder.getInstance().entitySpeed(entity); GlobalRecorder.getInstance().entitySpeed(entity);
} }
}
private static final Class<?> blockDigPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockDig"); private static final Class<?> blockDigPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockDig");
private static final Class<?> playerDigType = blockDigPacket.getDeclaredClasses()[0]; private static final Class<?> playerDigType = blockDigPacket.getDeclaredClasses()[0];
@ -163,10 +172,65 @@ public class Recording implements Listener {
GlobalRecorder.getInstance().entityDespawns(e.getPlayer()); GlobalRecorder.getInstance().entityDespawns(e.getPlayer());
} }
private static final Set<Integer> movingPistonIds = BlockIds.impl.materialToAllIds(FlatteningWrapper.impl.getMovingPiston());
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockPhysics(BlockPhysicsEvent e){ public void onBlockPhysics(BlockPhysicsEvent e){
if(FlatteningWrapper.impl.doRecord(e)) Block block = e.getBlock();
GlobalRecorder.getInstance().blockChange(e.getBlock()); if(!FlatteningWrapper.impl.doRecord(e) || !Config.PlayerRegion.inRegion(block))
return;
int blockId = BlockIdWrapper.impl.blockToId(block);
if(movingPistonIds.contains(blockId))
return;
changedBlocks.computeIfAbsent(blockId, blockId_ -> new TreeSet<>(Recording::compareBlocks)).add(block);
}
private static int compareBlocks(Block b1, Block b2) {
//negative if first arg is less than
return b1.getY() - b2.getY(); //TODO
}
private void sendChangedBlocks() {
HashMap<Integer, TreeSet<Short>> cache = new HashMap<>();
changedBlocks.forEach((chunkId, blocks) -> {
if(blocks.isEmpty())
return;
//TODO filter blocks (outside of Y range)
blocks.forEach(block -> cache.computeIfAbsent(BlockIdWrapper.impl.blockToId(block), blockId -> new TreeSet<>()).add((short) ((block.getY() - Config.PlayerRegion.getMinY()) << 8 + (block.getZ() % 16) << 4 + (block.getX() % 16))));
blocks.clear();
cache.forEach((blockId, positions) -> {
if(positions.isEmpty())
return;
if(movingPistonIds.contains(blockId)) {
positions.clear();
return;
}
if(positions.size() < 2) {
GlobalRecorder.getInstance().blockChange(); //TODO block
positions.clear();
return;
}
});
blocks.forEach(GlobalRecorder.getInstance()::blockChange);
// byte chunkX << 4 + chunkZ & 0xF (ArenaRelative)
// short blockState
// VarInts: NoChange, ChangedBlocks interleaved until 256 height (65536 blocks) reached
// 7 byte none, 8-10 byte 1 block
// TODO use starting from 2 blocks?
//Run length encoding for block types (assuming 256 block height)
//VarInt RLE
//TODO analyze amount of int/large block states
// 181MB ShortBlockPackets, 30MB BlockPackets
//TODO ChunkIndependent over whole arena (Arenarelative 10Mio Blocks)
//TODO RLE interleaved or RLE till Block
});
} }
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)

Datei anzeigen

@ -20,7 +20,6 @@
package de.steamwar.fightsystem.record; package de.steamwar.fightsystem.record;
import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.Config;
import de.steamwar.sql.Replay;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -41,7 +40,8 @@ public class FileSource extends PacketSource {
if(Config.ReplayID > 0) { if(Config.ReplayID > 0) {
try { try {
new FileSource(Replay.get(Config.ReplayID).getReplay()); //new FileSource(Replay.get(Config.ReplayID).getReplay());
new FileSource(new File("/home/lixfel/GRMAHeXa.recording"));
} catch (IOException e) { } catch (IOException e) {
throw new SecurityException("Could not start replay", e); throw new SecurityException("Could not start replay", e);
} }

Datei anzeigen

@ -626,10 +626,12 @@ public class PacketProcessor implements Listener {
tickFinished = true; tickFinished = true;
} }
private final int[] stats = new int[256];
private void process(){ private void process(){
tickFinished = false; tickFinished = false;
int ticks = 0;
try{ try{
while(!source.isClosed() && !tickFinished){ while(!source.isClosed() && ticks < 30){
int packetType = Byte.toUnsignedInt(source.readByte()); int packetType = Byte.toUnsignedInt(source.readByte());
lastPackets.add(packetType); lastPackets.add(packetType);
@ -637,8 +639,13 @@ public class PacketProcessor implements Listener {
lastPackets.remove(0); lastPackets.remove(0);
PacketParser parser = packetDecoder[packetType]; PacketParser parser = packetDecoder[packetType];
stats[packetType]++;
if(parser != null){ if(parser != null){
parser.process(); parser.process();
if(tickFinished) {
ticks++;
tickFinished = false;
}
}else{ }else{
Bukkit.getLogger().log(Level.SEVERE, "Unknown packet " + packetType + " recieved, closing. LastPacket: " + Arrays.toString(lastPackets.toArray())); Bukkit.getLogger().log(Level.SEVERE, "Unknown packet " + packetType + " recieved, closing. LastPacket: " + Arrays.toString(lastPackets.toArray()));
source.close(); source.close();
@ -654,6 +661,10 @@ public class PacketProcessor implements Listener {
if(source.isClosed()){ if(source.isClosed()){
execSync(() -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endReplay)); execSync(() -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), this::endReplay));
for(int i = 0; i < 256; i++) {
if(stats[i] != 0)
System.out.println(Integer.toHexString(i) + ": " + stats[i]);
}
} }
} }

Datei anzeigen

@ -22,6 +22,7 @@ package de.steamwar.fightsystem.utils;
import de.steamwar.core.VersionDependent; import de.steamwar.core.VersionDependent;
import de.steamwar.fightsystem.FightSystem; import de.steamwar.fightsystem.FightSystem;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -44,7 +45,7 @@ public interface FlatteningWrapper {
void forceLoadChunk(World world, int cX, int cZ); void forceLoadChunk(World world, int cX, int cZ);
boolean checkPistonMoving(Block block); Material getMovingPiston();
boolean isFacingWater(Block dispenser); boolean isFacingWater(Block dispenser);