diff --git a/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java b/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java index c44ff36..f34c5bf 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/DefaultClientCommsListener.java @@ -7,7 +7,7 @@ import ru.windcorp.progressia.common.comms.CommsListener; import ru.windcorp.progressia.common.comms.packets.Packet; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.PacketSetLocalPlayer; -import ru.windcorp.progressia.common.world.PacketWorldChange; +import ru.windcorp.progressia.common.world.PacketAffectWorld; // TODO refactor with no mercy public class DefaultClientCommsListener implements CommsListener { @@ -20,8 +20,8 @@ public class DefaultClientCommsListener implements CommsListener { @Override public void onPacketReceived(Packet packet) { - if (packet instanceof PacketWorldChange) { - ((PacketWorldChange) packet).apply( + if (packet instanceof PacketAffectWorld) { + ((PacketAffectWorld) packet).apply( getClient().getWorld().getData() ); } else if (packet instanceof PacketSetLocalPlayer) { diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketChunkChange.java b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectChunk.java similarity index 58% rename from src/main/java/ru/windcorp/progressia/common/world/PacketChunkChange.java rename to src/main/java/ru/windcorp/progressia/common/world/PacketAffectChunk.java index 2cd1a96..fd5282c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketChunkChange.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectChunk.java @@ -2,9 +2,9 @@ package ru.windcorp.progressia.common.world; import glm.vec._3.i.Vec3i; -public abstract class PacketChunkChange extends PacketWorldChange { +public abstract class PacketAffectChunk extends PacketAffectWorld { - public PacketChunkChange(String id) { + public PacketAffectChunk(String id) { super(id); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketWorldChange.java b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java similarity index 61% rename from src/main/java/ru/windcorp/progressia/common/world/PacketWorldChange.java rename to src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java index 350c3f9..1aad748 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketWorldChange.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketAffectWorld.java @@ -2,9 +2,9 @@ package ru.windcorp.progressia.common.world; import ru.windcorp.progressia.common.comms.packets.Packet; -public abstract class PacketWorldChange extends Packet { +public abstract class PacketAffectWorld extends Packet { - public PacketWorldChange(String id) { + public PacketAffectWorld(String id) { super(id); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java b/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java index e923259..faf6331 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketRevokeChunk.java @@ -6,7 +6,7 @@ import java.io.IOException; import glm.vec._3.i.Vec3i; -public class PacketRevokeChunk extends PacketChunkChange { +public class PacketRevokeChunk extends PacketAffectChunk { private final Vec3i position = new Vec3i(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java index 903f8ca..69451ab 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSendChunk.java @@ -10,7 +10,7 @@ import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.DataBuffer; import ru.windcorp.progressia.common.util.crash.CrashReports; -public class PacketSendChunk extends PacketChunkChange { +public class PacketSendChunk extends PacketAffectChunk { private final DataBuffer data = new DataBuffer(); private final Vec3i position = new Vec3i(); diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/PacketAffectBlock.java b/src/main/java/ru/windcorp/progressia/common/world/block/PacketAffectBlock.java new file mode 100644 index 0000000..8ade185 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/block/PacketAffectBlock.java @@ -0,0 +1,45 @@ +package ru.windcorp.progressia.common.world.block; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.DecodingException; +import ru.windcorp.progressia.common.world.PacketAffectChunk; + +public abstract class PacketAffectBlock extends PacketAffectChunk { + + private final Vec3i blockInWorld = new Vec3i(); + + public PacketAffectBlock(String id) { + super(id); + } + + public Vec3i getBlockInWorld() { + return blockInWorld; + } + + public void set(Vec3i blockInWorld) { + this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); + } + + @Override + public void read(DataInput input) throws IOException, DecodingException { + this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt()); + } + + @Override + public void write(DataOutput output) throws IOException { + output.writeInt(this.blockInWorld.x); + output.writeInt(this.blockInWorld.y); + output.writeInt(this.blockInWorld.z); + } + + @Override + public void getAffectedChunk(Vec3i output) { + Coordinates.convertInWorldToChunk(this.blockInWorld, output); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java b/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java index 0eefa71..e166aad 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java +++ b/src/main/java/ru/windcorp/progressia/common/world/block/PacketSetBlock.java @@ -5,15 +5,12 @@ import java.io.DataOutput; import java.io.IOException; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.PacketChunkChange; import ru.windcorp.progressia.common.world.WorldData; -public class PacketSetBlock extends PacketChunkChange { +public class PacketSetBlock extends PacketAffectBlock { - private String id; - private final Vec3i blockInWorld = new Vec3i(); + private String blockId; public PacketSetBlock() { this("Core:SetBlock"); @@ -23,34 +20,31 @@ public class PacketSetBlock extends PacketChunkChange { super(id); } + public String getBlockId() { + return blockId; + } + public void set(BlockData block, Vec3i blockInWorld) { - this.id = block.getId(); - this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); + super.set(blockInWorld); + this.blockId = block.getId(); } @Override public void read(DataInput input) throws IOException, DecodingException { - this.id = input.readUTF(); - this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt()); + super.read(input); + this.blockId = input.readUTF(); } @Override public void write(DataOutput output) throws IOException { - output.writeUTF(this.id); - output.writeInt(this.blockInWorld.x); - output.writeInt(this.blockInWorld.y); - output.writeInt(this.blockInWorld.z); + super.write(output); + output.writeUTF(this.blockId); } @Override public void apply(WorldData world) { - BlockData block = BlockDataRegistry.getInstance().get(id); - world.setBlock(blockInWorld, block, true); - } - - @Override - public void getAffectedChunk(Vec3i output) { - Coordinates.convertInWorldToChunk(this.blockInWorld, output); + BlockData block = BlockDataRegistry.getInstance().get(getBlockId()); + world.setBlock(getBlockInWorld(), block, true); } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java new file mode 100644 index 0000000..4d6d403 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketAffectEntity.java @@ -0,0 +1,42 @@ +package ru.windcorp.progressia.common.world.entity; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import ru.windcorp.progressia.common.world.DecodingException; +import ru.windcorp.progressia.common.world.PacketAffectWorld; +import ru.windcorp.progressia.common.world.WorldData; + +public class PacketAffectEntity extends PacketAffectWorld { + + private long entityId; + + public PacketAffectEntity(String id) { + super(id); + } + + public long getEntityId() { + return entityId; + } + + public void set(long entityId) { + this.entityId = entityId; + } + + @Override + public void read(DataInput input) throws IOException, DecodingException { + this.entityId = input.readLong(); + } + + @Override + public void write(DataOutput output) throws IOException { + output.writeLong(this.entityId); + } + + @Override + public void apply(WorldData world) { + world.removeEntity(this.entityId); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketEntityChange.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java similarity index 65% rename from src/main/java/ru/windcorp/progressia/common/world/entity/PacketEntityChange.java rename to src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java index aea1d06..fcfadc5 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketEntityChange.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketChangeEntity.java @@ -8,44 +8,27 @@ import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.DataBuffer; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.PacketWorldChange; import ru.windcorp.progressia.common.world.WorldData; -public class PacketEntityChange extends PacketWorldChange { +public class PacketChangeEntity extends PacketAffectEntity { - private long entityId; private final DataBuffer buffer = new DataBuffer(); - public PacketEntityChange() { + public PacketChangeEntity() { super("Core:EntityChange"); } - protected PacketEntityChange(String id) { + protected PacketChangeEntity(String id) { super(id); } - - public long getEntityId() { - return entityId; - } - - public void setEntityId(long entityId) { - this.entityId = entityId; - } - + public DataBuffer getBuffer() { return buffer; } - - public DataInput getReader() { - return buffer.getReader(); - } - - public DataOutput getWriter() { - return buffer.getWriter(); - } public void set(EntityData entity) { - this.entityId = entity.getEntityId(); + super.set(entity.getEntityId()); + try { entity.write(this.buffer.getWriter(), IOContext.COMMS); } catch (IOException e) { @@ -55,13 +38,13 @@ public class PacketEntityChange extends PacketWorldChange { @Override public void read(DataInput input) throws IOException, DecodingException { - this.entityId = input.readLong(); + super.read(input); this.buffer.fill(input, input.readInt()); } @Override public void write(DataOutput output) throws IOException { - output.writeLong(this.entityId); + super.write(output); output.writeInt(this.buffer.getSize()); this.buffer.flush(output); } @@ -75,7 +58,7 @@ public class PacketEntityChange extends PacketWorldChange { } try { - entity.read(getReader(), IOContext.COMMS); + entity.read(getBuffer().getReader(), IOContext.COMMS); } catch (IOException e) { throw CrashReports.report(e, "Entity could not be read"); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java index 03ec081..b7bf77e 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketRevokeEntity.java @@ -4,12 +4,10 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import ru.windcorp.progressia.common.world.PacketWorldChange; +import ru.windcorp.progressia.common.world.DecodingException; import ru.windcorp.progressia.common.world.WorldData; -public class PacketRevokeEntity extends PacketWorldChange { - - private long entityId; +public class PacketRevokeEntity extends PacketAffectEntity { public PacketRevokeEntity() { this("Core:RevokeEntity"); @@ -19,23 +17,24 @@ public class PacketRevokeEntity extends PacketWorldChange { super(id); } + @Override public void set(long entityId) { - this.entityId = entityId; + super.set(entityId); } @Override - public void read(DataInput input) throws IOException { - this.entityId = input.readLong(); + public void read(DataInput input) throws IOException, DecodingException { + super.read(input); } @Override public void write(DataOutput output) throws IOException { - output.writeLong(this.entityId); + super.write(output); } @Override public void apply(WorldData world) { - world.removeEntity(this.entityId); + world.removeEntity(getEntityId()); } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java index 780332b..569be14 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java +++ b/src/main/java/ru/windcorp/progressia/common/world/entity/PacketSendEntity.java @@ -8,13 +8,11 @@ import ru.windcorp.progressia.common.state.IOContext; import ru.windcorp.progressia.common.util.DataBuffer; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.PacketWorldChange; import ru.windcorp.progressia.common.world.WorldData; -public class PacketSendEntity extends PacketWorldChange { +public class PacketSendEntity extends PacketAffectEntity { - private String id; - private long entityId; + private String entityTypeId; private final DataBuffer buffer = new DataBuffer(); public PacketSendEntity() { @@ -25,9 +23,23 @@ public class PacketSendEntity extends PacketWorldChange { super(id); } + /** + * Returns the text ID of the entity added by this packet. + * @return text ID + * @see #getEntityId() + */ + public String getEntityTypeId() { + return entityTypeId; + } + + public DataBuffer getBuffer() { + return buffer; + } + public void set(EntityData entity) { - this.id = entity.getId(); - this.entityId = entity.getEntityId(); + super.set(entity.getEntityId()); + + this.entityTypeId = entity.getId(); try { entity.write(this.buffer.getWriter(), IOContext.COMMS); @@ -38,26 +50,28 @@ public class PacketSendEntity extends PacketWorldChange { @Override public void read(DataInput input) throws IOException, DecodingException { - this.id = input.readUTF(); - this.entityId = input.readLong(); + super.read(input); + + this.entityTypeId = input.readUTF(); this.buffer.fill(input, input.readInt()); } @Override public void write(DataOutput output) throws IOException { - output.writeUTF(this.id); - output.writeLong(this.entityId); + super.write(output); + + output.writeUTF(this.entityTypeId); output.writeInt(this.buffer.getSize()); this.buffer.flush(output); } @Override public void apply(WorldData world) { - EntityData entity = EntityDataRegistry.getInstance().create(this.id); + EntityData entity = EntityDataRegistry.getInstance().create(getEntityTypeId()); - entity.setEntityId(this.entityId); + entity.setEntityId(getEntityId()); try { - entity.read(this.buffer.getReader(), IOContext.COMMS); + entity.read(getBuffer().getReader(), IOContext.COMMS); } catch (IOException e) { throw CrashReports.report(e, "Could not read an entity from an internal buffer"); } diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java index 5cc12ee..e9555ae 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAddTile.java @@ -5,17 +5,13 @@ import java.io.DataOutput; import java.io.IOException; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.Coordinates; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.PacketChunkChange; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockFace; -public class PacketAddTile extends PacketChunkChange { +public class PacketAddTile extends PacketAffectTile { - private String id; - private final Vec3i blockInWorld = new Vec3i(); - private BlockFace face; + private String tileId; public PacketAddTile() { this("Core:AddTile"); @@ -25,37 +21,31 @@ public class PacketAddTile extends PacketChunkChange { super(id); } + public String getTileId() { + return tileId; + } + public void set(TileData tile, Vec3i blockInWorld, BlockFace face) { - this.id = tile.getId(); - this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); - this.face = face; + super.set(blockInWorld, face, -1); + this.tileId = tile.getId(); } @Override public void read(DataInput input) throws IOException, DecodingException { - this.id = input.readUTF(); - this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt()); - this.face = BlockFace.getFaces().get(input.readByte()); + super.read(input); + this.tileId = input.readUTF(); } @Override public void write(DataOutput output) throws IOException { - output.writeUTF(this.id); - output.writeInt(this.blockInWorld.x); - output.writeInt(this.blockInWorld.y); - output.writeInt(this.blockInWorld.z); - output.writeByte(this.face.getId()); + super.write(output); + output.writeUTF(this.tileId); } @Override public void apply(WorldData world) { - TileData tile = TileDataRegistry.getInstance().get(id); - world.getTiles(blockInWorld, face).add(tile); - } - - @Override - public void getAffectedChunk(Vec3i output) { - Coordinates.convertInWorldToChunk(this.blockInWorld, output); + TileData tile = TileDataRegistry.getInstance().get(getTileId()); + world.getTiles(getBlockInWorld(), getFace()).add(tile); } } diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java new file mode 100644 index 0000000..6d9fcf5 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketAffectTile.java @@ -0,0 +1,62 @@ +package ru.windcorp.progressia.common.world.tile; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.DecodingException; +import ru.windcorp.progressia.common.world.PacketAffectChunk; +import ru.windcorp.progressia.common.world.block.BlockFace; + +public abstract class PacketAffectTile extends PacketAffectChunk { + + private final Vec3i blockInWorld = new Vec3i(); + private BlockFace face; + private int tag; + + public PacketAffectTile(String id) { + super(id); + } + + public Vec3i getBlockInWorld() { + return blockInWorld; + } + + public BlockFace getFace() { + return face; + } + + public int getTag() { + return tag; + } + + public void set(Vec3i blockInWorld, BlockFace face, int tag) { + this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); + this.face = face; + this.tag = tag; + } + + @Override + public void read(DataInput input) throws IOException, DecodingException { + this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt()); + this.face = BlockFace.getFaces().get(input.readByte()); + this.tag = input.readInt(); + } + + @Override + public void write(DataOutput output) throws IOException { + output.writeInt(this.blockInWorld.x); + output.writeInt(this.blockInWorld.y); + output.writeInt(this.blockInWorld.z); + output.writeByte(this.face.getId()); + output.writeInt(this.tag); + } + + @Override + public void getAffectedChunk(Vec3i output) { + Coordinates.convertInWorldToChunk(this.blockInWorld, output); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java index b7d9e0b..e59ca37 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java +++ b/src/main/java/ru/windcorp/progressia/common/world/tile/PacketRemoveTile.java @@ -5,17 +5,12 @@ import java.io.DataOutput; import java.io.IOException; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.DecodingException; -import ru.windcorp.progressia.common.world.PacketChunkChange; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.common.world.block.BlockFace; -public class PacketRemoveTile extends PacketChunkChange { - - private final Vec3i blockInWorld = new Vec3i(); - private BlockFace face; - private int tag; +public class PacketRemoveTile extends PacketAffectTile { public PacketRemoveTile() { this("Core:RemoveTile"); @@ -25,37 +20,37 @@ public class PacketRemoveTile extends PacketChunkChange { super(id); } + @Override public void set(Vec3i blockInWorld, BlockFace face, int tag) { - this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); - this.face = face; - this.tag = tag; + super.set(blockInWorld, face, tag); } @Override public void read(DataInput input) throws IOException, DecodingException { - this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt()); - this.face = BlockFace.getFaces().get(input.readByte()); - this.tag = input.readInt(); + super.read(input); } @Override public void write(DataOutput output) throws IOException { - output.writeInt(this.blockInWorld.x); - output.writeInt(this.blockInWorld.y); - output.writeInt(this.blockInWorld.z); - output.writeByte(this.face.getId()); - output.writeInt(this.tag); + super.write(output); } @Override public void apply(WorldData world) { - TileDataStack stack = world.getTiles(blockInWorld, face); - stack.remove(stack.getIndexByTag(tag)); - } - - @Override - public void getAffectedChunk(Vec3i output) { - Coordinates.convertInWorldToChunk(this.blockInWorld, output); + TileDataStack stack = world.getTiles(getBlockInWorld(), getFace()); + + int index = stack.getIndexByTag(getTag()); + + if (index < 0) { + throw CrashReports.report(null, + "Could not find tile with tag %d at (%d; %d; %d; %s)", + getTag(), + getBlockInWorld().x, getBlockInWorld().y, getBlockInWorld().z, + getFace() + ); + } + + stack.remove(index); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java index 411c3ab..a64419f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java +++ b/src/main/java/ru/windcorp/progressia/server/world/TickAndUpdateUtil.java @@ -22,7 +22,7 @@ public class TickAndUpdateUtil { try { block.tick(context); } catch (Exception e) { - throw CrashReports.report(e, "Could not tick block {}", block); + throw CrashReports.report(e, "Could not tick block %s", block); } } @@ -38,7 +38,7 @@ public class TickAndUpdateUtil { try { tile.tick(context); } catch (Exception e) { - throw CrashReports.report(e, "Could not tick tile {}", tile); + throw CrashReports.report(e, "Could not tick tile %s", tile); } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/AddTile.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/AddTile.java index d058ac9..358acdd 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/AddTile.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/AddTile.java @@ -4,7 +4,7 @@ import java.util.function.Consumer; import ru.windcorp.progressia.common.world.tile.PacketAddTile; -class AddTile extends CachedChunkChange { +class AddTile extends CachedTileChange { public AddTile(Consumer disposer) { super(disposer, new PacketAddTile()); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedBlockChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedBlockChange.java new file mode 100644 index 0000000..589fa15 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedBlockChange.java @@ -0,0 +1,45 @@ +package ru.windcorp.progressia.server.world.tasks; + +import java.util.function.Consumer; + +import glm.Glm; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.block.PacketAffectBlock; + +public class CachedBlockChange

extends CachedChunkChange

{ + + public CachedBlockChange(Consumer disposer, P packet) { + super(disposer, packet); + } + + @Override + public int hashCode() { + PacketAffectBlock packet = getPacket(); + Vec3i biw = packet.getBlockInWorld(); + + final int prime = 31; + int result = 1; + result = prime * result + biw.x; + result = prime * result + biw.y; + result = prime * result + biw.z; + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj == null || getClass() != obj.getClass()) return false; + + PacketAffectBlock my = getPacket(); + PacketAffectBlock other = ((CachedBlockChange) obj).getPacket(); + + return Glm.equals(my.getBlockInWorld(), other.getBlockInWorld()); + } + + @Override + public String toString() { + Vec3i biw = getPacket().getBlockInWorld(); + + return getClass().getSimpleName() + " (" + biw.x + "; " + biw.y + "; " + biw.z + ")"; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChunkChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChunkChange.java index d9164dd..4f03486 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChunkChange.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedChunkChange.java @@ -3,9 +3,9 @@ package ru.windcorp.progressia.server.world.tasks; import java.util.function.Consumer; import glm.vec._3.i.Vec3i; -import ru.windcorp.progressia.common.world.PacketChunkChange; +import ru.windcorp.progressia.common.world.PacketAffectChunk; -public abstract class CachedChunkChange

extends CachedWorldChange

{ +public abstract class CachedChunkChange

extends CachedWorldChange

{ public CachedChunkChange(Consumer disposer, P packet) { super(disposer, packet); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedTileChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedTileChange.java new file mode 100644 index 0000000..ee76f86 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedTileChange.java @@ -0,0 +1,54 @@ +package ru.windcorp.progressia.server.world.tasks; + +import java.util.Objects; +import java.util.function.Consumer; + +import glm.Glm; +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.world.tile.PacketAffectTile; + +public class CachedTileChange

extends CachedChunkChange

{ + + public CachedTileChange(Consumer disposer, P packet) { + super(disposer, packet); + } + + @Override + public int hashCode() { + PacketAffectTile packet = getPacket(); + Vec3i biw = packet.getBlockInWorld(); + + final int prime = 31; + int result = 1; + result = prime * result + biw.x; + result = prime * result + biw.y; + result = prime * result + biw.z; + result = prime * result + Objects.hashCode(packet.getFace()); + result = prime * result + packet.getTag(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CachedTileChange)) return false; + + PacketAffectTile my = getPacket(); + PacketAffectTile other = ((CachedTileChange) obj).getPacket(); + + // Tag of -1 signals that we should ignore it + if (my.getTag() == -1 || other.getTag() == -1) return false; + + return Glm.equals(my.getBlockInWorld(), other.getBlockInWorld()) + && (my.getFace() == other.getFace()) + && (my.getTag() == other.getTag()); + } + + @Override + public String toString() { + PacketAffectTile packet = getPacket(); + Vec3i biw = packet.getBlockInWorld(); + + return getClass().getSimpleName() + " (" + biw.x + "; " + biw.y + "; " + biw.z + "; " + packet.getFace() + "; tag: " + packet.getTag() + ")"; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedWorldChange.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedWorldChange.java index e3929a7..9230961 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedWorldChange.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/CachedWorldChange.java @@ -4,10 +4,10 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.Vectors; -import ru.windcorp.progressia.common.world.PacketWorldChange; +import ru.windcorp.progressia.common.world.PacketAffectWorld; import ru.windcorp.progressia.server.Server; -public abstract class CachedWorldChange

extends CachedChange { +public abstract class CachedWorldChange

extends CachedChange { private final P packet; diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java index a813f15..847b9ae 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/ChangeEntity.java @@ -4,7 +4,7 @@ import java.util.function.Consumer; import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.world.entity.EntityData; -import ru.windcorp.progressia.common.world.entity.PacketEntityChange; +import ru.windcorp.progressia.common.world.entity.PacketChangeEntity; import ru.windcorp.progressia.server.Server; class ChangeEntity extends CachedChange { @@ -12,7 +12,7 @@ class ChangeEntity extends CachedChange { private EntityData entity; private StateChange change; - private final PacketEntityChange packet = new PacketEntityChange(); + private final PacketChangeEntity packet = new PacketChangeEntity(); public ChangeEntity(Consumer disposer) { super(disposer); @@ -55,5 +55,16 @@ class ChangeEntity extends CachedChange { this.entity = null; this.change = null; } + + @Override + public int hashCode() { + return System.identityHashCode(entity); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ChangeEntity)) return false; + return ((ChangeEntity) obj).entity == entity; + } } \ No newline at end of file diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/RemoveTile.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/RemoveTile.java index 02c01ba..17512b2 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/RemoveTile.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/RemoveTile.java @@ -4,7 +4,7 @@ import java.util.function.Consumer; import ru.windcorp.progressia.common.world.tile.PacketRemoveTile; -class RemoveTile extends CachedChunkChange { +class RemoveTile extends CachedTileChange { public RemoveTile(Consumer disposer) { super(disposer, new PacketRemoveTile()); diff --git a/src/main/java/ru/windcorp/progressia/server/world/tasks/SetBlock.java b/src/main/java/ru/windcorp/progressia/server/world/tasks/SetBlock.java index e595f2a..9b9d869 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/tasks/SetBlock.java +++ b/src/main/java/ru/windcorp/progressia/server/world/tasks/SetBlock.java @@ -4,7 +4,7 @@ import java.util.function.Consumer; import ru.windcorp.progressia.common.world.block.PacketSetBlock; -class SetBlock extends CachedChunkChange { +class SetBlock extends CachedBlockChange { public SetBlock(Consumer disposer) { super(disposer, new PacketSetBlock()); diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/Change.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/Change.java index 408ed3a..314aef7 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/Change.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/Change.java @@ -23,5 +23,17 @@ public abstract class Change extends TickerTask { void run(Server server) { affect(server); } + + @Override + public int hashCode() { + // Use instance hash code by default + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + // Use instance-based equals() by default + return super.equals(obj); + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java index 84d3a2a..ebc548f 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/ticking/TickerCoordinator.java @@ -3,7 +3,9 @@ package ru.windcorp.progressia.server.world.ticking; import java.util.ArrayList; import java.util.Collection; import java.util.ConcurrentModificationException; +import java.util.HashSet; import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import org.apache.logging.log4j.LogManager; @@ -14,6 +16,9 @@ import com.google.common.collect.ImmutableList; import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.crash.CrashReports; +import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.ChunkDataListener; +import ru.windcorp.progressia.common.world.ChunkDataListeners; import ru.windcorp.progressia.server.Server; /** @@ -28,7 +33,7 @@ public class TickerCoordinator { private final Server server; // Synchronized manually - private final Collection pendingChanges = new ArrayList<>(INITIAL_QUEUE_SIZE); + private final Collection pendingChanges = new HashSet<>(INITIAL_QUEUE_SIZE); // Synchronized manually private final Collection pendingEvaluations = new ArrayList<>(INITIAL_QUEUE_SIZE); @@ -49,6 +54,8 @@ public class TickerCoordinator { private final AtomicInteger workingTickers = new AtomicInteger(); + private final AtomicBoolean canChange = new AtomicBoolean(true); + private boolean isTickStartSet = false; private long tickStart = -1; private double tickLength = 1.0 / 20; // Do something about it @@ -66,6 +73,15 @@ public class TickerCoordinator { this.tickers = ImmutableList.copyOf(tickerCollection); this.threads = Collections2.transform(this.tickers, Ticker::getThread); // Immutable because it is a view + + server.getWorld().getData().addListener(ChunkDataListeners.createAdder(new ChunkDataListener() { + @Override + public void onChunkChanged(ChunkData chunk) { + if (!canChange.get()) { + throw CrashReports.report(null, "A change has been detected during evaluation phase"); + } + } + })); } /* @@ -157,7 +173,9 @@ public class TickerCoordinator { } private synchronized void runOnePass() throws InterruptedException { + canChange.set(false); runPassStage(pendingEvaluations, "EVALUATION"); + canChange.set(true); runPassStage(pendingChanges, "CHANGE"); }