Commits vergleichen
1 Commits
master
...
rleRecordi
Autor | SHA1 | Datum | |
---|---|---|---|
1934debfd7 |
@ -85,7 +85,7 @@ public class FlatteningWrapper14 implements FlatteningWrapper {
|
||||
|
||||
@Override
|
||||
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
|
||||
@ -94,8 +94,8 @@ public class FlatteningWrapper14 implements FlatteningWrapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkPistonMoving(Block block) {
|
||||
return block.getType() == Material.MOVING_PISTON;
|
||||
public Material getMovingPiston() {
|
||||
return Material.MOVING_PISTON;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,8 +70,8 @@ public class FlatteningWrapper8 implements FlatteningWrapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkPistonMoving(Block block) {
|
||||
return block.getType() == Material.PISTON_MOVING_PIECE;
|
||||
public Material getMovingPiston() {
|
||||
return Material.PISTON_MOVING_PIECE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,7 +104,7 @@ public class FightSystem extends JavaPlugin {
|
||||
techHider = new TechHiderWrapper();
|
||||
new FightWorld();
|
||||
new FightUI();
|
||||
new FightStatistics();
|
||||
//new FightStatistics();
|
||||
new BungeeFightInfo();
|
||||
|
||||
new WinconditionAllDead();
|
||||
|
@ -33,6 +33,7 @@ import de.steamwar.fightsystem.utils.Region;
|
||||
import de.steamwar.fightsystem.utils.WorldeditWrapper;
|
||||
import de.steamwar.sql.SchematicNode;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -44,13 +45,15 @@ import java.util.Set;
|
||||
|
||||
public class PrepareSchem implements Listener {
|
||||
|
||||
private static final Material MOVING_PISTON = FlatteningWrapper.impl.getMovingPiston();
|
||||
|
||||
private final Set<Vector> stationaryMovingPistons = new HashSet<>();
|
||||
|
||||
public PrepareSchem() {
|
||||
new OneShotStateDependent(ArenaMode.Prepare, FightState.PostSchemSetup, () -> Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||
stationaryMovingPistons.clear();
|
||||
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));
|
||||
});
|
||||
}, 1));
|
||||
@ -73,7 +76,7 @@ public class PrepareSchem implements Listener {
|
||||
|
||||
try{
|
||||
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");
|
||||
Bukkit.shutdown();
|
||||
throw new IllegalStateException();
|
||||
|
@ -22,6 +22,7 @@ package de.steamwar.fightsystem.listener;
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
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.StateDependentTask;
|
||||
import de.steamwar.fightsystem.utils.*;
|
||||
import de.steamwar.techhider.BlockIds;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -48,7 +51,7 @@ import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
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);
|
||||
}
|
||||
|
||||
private final HashMap<Integer, TreeSet<Block>> changedBlocks = new HashMap<>();
|
||||
|
||||
public Recording() {
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this);
|
||||
new StateDependentListener(ArenaMode.AntiReplay, FightState.All, BountifulWrapper.impl.newHandSwapRecorder());
|
||||
@ -88,6 +93,7 @@ public class Recording implements Listener {
|
||||
public void disable() {
|
||||
Fight.teams().forEach(Recording.this::despawnTeam);
|
||||
despawnTNT();
|
||||
sendChangedBlocks();
|
||||
}
|
||||
}.register();
|
||||
new StateDependent(ArenaMode.AntiReplay, FightState.Ingame) {
|
||||
@ -107,18 +113,21 @@ public class Recording implements Listener {
|
||||
}
|
||||
}.register();
|
||||
new StateDependentTask(ArenaMode.AntiReplay, FightState.All, () -> {
|
||||
GlobalRecorder.getInstance().tick();
|
||||
|
||||
if(FightState.getFightState() == FightState.SPECTATE || !GlobalRecorder.getInstance().recording())
|
||||
return;
|
||||
|
||||
sendChangedBlocks();
|
||||
iterateOverEntities(primedTnt::isInstance, this::trackEntity);
|
||||
}, 1, 1);
|
||||
|
||||
GlobalRecorder.getInstance().tick();
|
||||
}, 0, 1);
|
||||
}
|
||||
|
||||
private void trackEntity(Entity entity) {
|
||||
GlobalRecorder.getInstance().entityMoves(entity);
|
||||
GlobalRecorder.getInstance().entitySpeed(entity);
|
||||
if(entity.getVelocity().lengthSquared() != 0) {
|
||||
GlobalRecorder.getInstance().entityMoves(entity);
|
||||
GlobalRecorder.getInstance().entitySpeed(entity);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Class<?> blockDigPacket = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockDig");
|
||||
@ -163,10 +172,65 @@ public class Recording implements Listener {
|
||||
GlobalRecorder.getInstance().entityDespawns(e.getPlayer());
|
||||
}
|
||||
|
||||
private static final Set<Integer> movingPistonIds = BlockIds.impl.materialToAllIds(FlatteningWrapper.impl.getMovingPiston());
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onBlockPhysics(BlockPhysicsEvent e){
|
||||
if(FlatteningWrapper.impl.doRecord(e))
|
||||
GlobalRecorder.getInstance().blockChange(e.getBlock());
|
||||
Block block = 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)
|
||||
|
@ -20,7 +20,6 @@
|
||||
package de.steamwar.fightsystem.record;
|
||||
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.sql.Replay;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
@ -41,7 +40,8 @@ public class FileSource extends PacketSource {
|
||||
|
||||
if(Config.ReplayID > 0) {
|
||||
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) {
|
||||
throw new SecurityException("Could not start replay", e);
|
||||
}
|
||||
|
@ -626,10 +626,12 @@ public class PacketProcessor implements Listener {
|
||||
tickFinished = true;
|
||||
}
|
||||
|
||||
private final int[] stats = new int[256];
|
||||
private void process(){
|
||||
tickFinished = false;
|
||||
int ticks = 0;
|
||||
try{
|
||||
while(!source.isClosed() && !tickFinished){
|
||||
while(!source.isClosed() && ticks < 30){
|
||||
int packetType = Byte.toUnsignedInt(source.readByte());
|
||||
|
||||
lastPackets.add(packetType);
|
||||
@ -637,8 +639,13 @@ public class PacketProcessor implements Listener {
|
||||
lastPackets.remove(0);
|
||||
|
||||
PacketParser parser = packetDecoder[packetType];
|
||||
stats[packetType]++;
|
||||
if(parser != null){
|
||||
parser.process();
|
||||
if(tickFinished) {
|
||||
ticks++;
|
||||
tickFinished = false;
|
||||
}
|
||||
}else{
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Unknown packet " + packetType + " recieved, closing. LastPacket: " + Arrays.toString(lastPackets.toArray()));
|
||||
source.close();
|
||||
@ -654,6 +661,10 @@ public class PacketProcessor implements Listener {
|
||||
|
||||
if(source.isClosed()){
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ package de.steamwar.fightsystem.utils;
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -44,7 +45,7 @@ public interface FlatteningWrapper {
|
||||
|
||||
void forceLoadChunk(World world, int cX, int cZ);
|
||||
|
||||
boolean checkPistonMoving(Block block);
|
||||
Material getMovingPiston();
|
||||
|
||||
boolean isFacingWater(Block dispenser);
|
||||
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren