diff --git a/src/main/java/de/bixilon/minosoft/modding/event/EventListener.java b/src/main/java/de/bixilon/minosoft/modding/event/EventListener.java
index 92e126882..08f556219 100644
--- a/src/main/java/de/bixilon/minosoft/modding/event/EventListener.java
+++ b/src/main/java/de/bixilon/minosoft/modding/event/EventListener.java
@@ -84,4 +84,16 @@ public class EventListener {
public void onLightningBoltSpawn(LightningBoltSpawnEvent event) {
}
+
+ public void onMultiBlockChange(MultiBlockChangeEvent event) {
+ }
+
+ public void onBlockEntityMetaDataChange(BlockEntityMetaDataChangeEvent event) {
+ }
+
+ public void onChunkDataChange(ChunkDataChangeEvent event) {
+ }
+
+ public void onEffect(EffectEvent event) {
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/BlockEntityMetaDataChangeEvent.java b/src/main/java/de/bixilon/minosoft/modding/event/events/BlockEntityMetaDataChangeEvent.java
new file mode 100644
index 000000000..4362afa40
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/modding/event/events/BlockEntityMetaDataChangeEvent.java
@@ -0,0 +1,62 @@
+/*
+ * Codename Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.modding.event.events;
+
+import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
+import de.bixilon.minosoft.modding.event.EventListener;
+import de.bixilon.minosoft.protocol.network.Connection;
+import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketBlockEntityMetadata;
+import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
+
+import javax.annotation.Nullable;
+
+public class BlockEntityMetaDataChangeEvent extends Event {
+ final BlockPosition position;
+ final PacketBlockEntityMetadata.BlockEntityActions action;
+ final CompoundTag nbt;
+
+ public BlockEntityMetaDataChangeEvent(Connection connection, BlockPosition position, PacketBlockEntityMetadata.BlockEntityActions action, CompoundTag nbt) {
+ super(connection);
+ this.position = position;
+ this.action = action;
+ this.nbt = nbt;
+ this.nbt.setFinal();
+ }
+
+ public BlockEntityMetaDataChangeEvent(Connection connection, PacketBlockEntityMetadata pkg) {
+ super(connection);
+ this.position = pkg.getPosition();
+ this.action = pkg.getAction();
+ this.nbt = pkg.getNbt();
+ this.nbt.setFinal();
+ }
+
+ public BlockPosition getPosition() {
+ return position;
+ }
+
+ @Nullable
+ public PacketBlockEntityMetadata.BlockEntityActions getAction() {
+ return action;
+ }
+
+ public CompoundTag getNbt() {
+ return nbt;
+ }
+
+ @Override
+ public void handle(EventListener listener) {
+ listener.onBlockEntityMetaDataChange(this);
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/ChunkDataChangeEvent.java b/src/main/java/de/bixilon/minosoft/modding/event/events/ChunkDataChangeEvent.java
new file mode 100644
index 000000000..0f6eb6d70
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/modding/event/events/ChunkDataChangeEvent.java
@@ -0,0 +1,68 @@
+/*
+ * Codename Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.modding.event.events;
+
+import de.bixilon.minosoft.game.datatypes.world.Chunk;
+import de.bixilon.minosoft.game.datatypes.world.ChunkLocation;
+import de.bixilon.minosoft.modding.event.EventListener;
+import de.bixilon.minosoft.protocol.network.Connection;
+import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketChunkData;
+import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
+
+/**
+ * Fired when a new chunk is received or a full chunk changes
+ */
+public class ChunkDataChangeEvent extends Event {
+ private final ChunkLocation location;
+ private final Chunk chunk;
+ private final CompoundTag heightMap;
+
+ public ChunkDataChangeEvent(Connection connection, ChunkLocation location, Chunk chunk, CompoundTag heightMap) {
+ super(connection);
+ this.location = location;
+ this.chunk = chunk;
+ this.heightMap = heightMap;
+ }
+
+ public ChunkDataChangeEvent(Connection connection, ChunkLocation location, Chunk chunk) {
+ super(connection);
+ this.location = location;
+ this.chunk = chunk;
+ this.heightMap = new CompoundTag();
+ }
+
+ public ChunkDataChangeEvent(Connection connection, PacketChunkData pkg) {
+ super(connection);
+ this.location = pkg.getLocation();
+ this.chunk = pkg.getChunk();
+ this.heightMap = pkg.getHeightMap();
+ }
+
+ public ChunkLocation getLocation() {
+ return location;
+ }
+
+ public Chunk getChunk() {
+ return chunk;
+ }
+
+ public CompoundTag getHeightMap() {
+ return heightMap;
+ }
+
+ @Override
+ public void handle(EventListener listener) {
+ listener.onChunkDataChange(this);
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/EffectEvent.java b/src/main/java/de/bixilon/minosoft/modding/event/events/EffectEvent.java
new file mode 100644
index 000000000..dd2b60413
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/modding/event/events/EffectEvent.java
@@ -0,0 +1,63 @@
+/*
+ * Codename Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.modding.event.events;
+
+import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
+import de.bixilon.minosoft.modding.event.EventListener;
+import de.bixilon.minosoft.protocol.network.Connection;
+import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketEffect;
+
+public class EffectEvent extends CancelableEvent {
+ final PacketEffect.EffectEffects effect;
+ final BlockPosition position;
+ final int data;
+ final boolean disableRelativeVolume;
+
+ public EffectEvent(Connection connection, PacketEffect.EffectEffects effect, BlockPosition position, int data, boolean disableRelativeVolume) {
+ super(connection);
+ this.effect = effect;
+ this.position = position;
+ this.data = data;
+ this.disableRelativeVolume = disableRelativeVolume;
+ }
+
+ public EffectEvent(Connection connection, PacketEffect pkg) {
+ super(connection);
+ this.effect = pkg.getEffect();
+ this.position = pkg.getPosition();
+ this.data = pkg.getData();
+ this.disableRelativeVolume = pkg.isDisableRelativeVolume();
+ }
+
+ public PacketEffect.EffectEffects getEffect() {
+ return effect;
+ }
+
+ public BlockPosition getPosition() {
+ return position;
+ }
+
+ public int getData() {
+ return data;
+ }
+
+ public boolean isDisableRelativeVolume() {
+ return disableRelativeVolume;
+ }
+
+ @Override
+ public void handle(EventListener listener) {
+ listener.onEffect(this);
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/modding/event/events/MultiBlockChangeEvent.java b/src/main/java/de/bixilon/minosoft/modding/event/events/MultiBlockChangeEvent.java
new file mode 100644
index 000000000..e8b22f9e9
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/modding/event/events/MultiBlockChangeEvent.java
@@ -0,0 +1,56 @@
+/*
+ * Codename Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program. If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.modding.event.events;
+
+import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block;
+import de.bixilon.minosoft.game.datatypes.world.ChunkLocation;
+import de.bixilon.minosoft.game.datatypes.world.InChunkLocation;
+import de.bixilon.minosoft.modding.event.EventListener;
+import de.bixilon.minosoft.protocol.network.Connection;
+import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketMultiBlockChange;
+
+import java.util.HashMap;
+
+/**
+ * Fired when at least block is changed
+ */
+public class MultiBlockChangeEvent extends Event {
+ private final HashMap blocks;
+ private final ChunkLocation location;
+
+ public MultiBlockChangeEvent(Connection connection, HashMap blocks, ChunkLocation location) {
+ super(connection);
+ this.blocks = blocks;
+ this.location = location;
+ }
+
+ public MultiBlockChangeEvent(Connection connection, PacketMultiBlockChange pkg) {
+ super(connection);
+ this.blocks = pkg.getBlocks();
+ this.location = pkg.getLocation();
+ }
+
+ public HashMap getBlocks() {
+ return blocks;
+ }
+
+ public ChunkLocation getLocation() {
+ return location;
+ }
+
+ @Override
+ public void handle(EventListener listener) {
+ listener.onMultiBlockChange(this);
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketBlockEntityMetadata.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketBlockEntityMetadata.java
index 7a8241fde..2de2eea2d 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketBlockEntityMetadata.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketBlockEntityMetadata.java
@@ -29,7 +29,6 @@ public class PacketBlockEntityMetadata implements ClientboundPacket {
@Override
public boolean read(InByteBuffer buffer) {
-
if (buffer.getProtocolId() < 6) {
position = buffer.readBlockPositionShort();
action = BlockEntityActions.byId(buffer.readByte(), buffer.getProtocolId());
@@ -56,6 +55,10 @@ public class PacketBlockEntityMetadata implements ClientboundPacket {
return position;
}
+ public BlockEntityActions getAction() {
+ return action;
+ }
+
public CompoundTag getNbt() {
return nbt;
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChunkBulk.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChunkBulk.java
index 4dc7cf292..785c50346 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChunkBulk.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChunkBulk.java
@@ -25,7 +25,7 @@ import de.bixilon.minosoft.util.Util;
import java.util.HashMap;
public class PacketChunkBulk implements ClientboundPacket {
- final HashMap chunkMap = new HashMap<>();
+ final HashMap chunks = new HashMap<>();
@Override
public boolean read(InByteBuffer buffer) {
@@ -49,7 +49,7 @@ public class PacketChunkBulk implements ClientboundPacket {
short sectionBitMask = buffer.readShort();
short addBitMask = buffer.readShort();
- chunkMap.put(new ChunkLocation(x, z), ChunkUtil.readChunkPacket(decompressed, sectionBitMask, addBitMask, true, containsSkyLight));
+ chunks.put(new ChunkLocation(x, z), ChunkUtil.readChunkPacket(decompressed, sectionBitMask, addBitMask, true, containsSkyLight));
}
return true;
}
@@ -67,7 +67,7 @@ public class PacketChunkBulk implements ClientboundPacket {
sectionBitMask[i] = buffer.readShort();
}
for (int i = 0; i < chunkCount; i++) {
- chunkMap.put(new ChunkLocation(x[i], z[i]), ChunkUtil.readChunkPacket(buffer, sectionBitMask[i], (short) 0, true, containsSkyLight));
+ chunks.put(new ChunkLocation(x[i], z[i]), ChunkUtil.readChunkPacket(buffer, sectionBitMask[i], (short) 0, true, containsSkyLight));
}
return true;
}
@@ -79,10 +79,10 @@ public class PacketChunkBulk implements ClientboundPacket {
@Override
public void log() {
- Log.protocol(String.format("Chunk bulk packet received (chunks=%s)", chunkMap.size()));
+ Log.protocol(String.format("Chunk bulk packet received (chunks=%s)", chunks.size()));
}
- public HashMap getChunkMap() {
- return chunkMap;
+ public HashMap getChunks() {
+ return chunks;
}
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEffect.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEffect.java
index e6b6d9ed7..13fbcb008 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEffect.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEffect.java
@@ -22,11 +22,10 @@ import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
public class PacketEffect implements ClientboundPacket {
- // is this class used??? What about PacketParticle or PacketSoundEffect?
EffectEffects effect;
BlockPosition position;
int data;
- boolean disableRelativeVolume; // normally only at MOB_ENDERDRAGON_END and MOB_WITHER_SPAWN, but we allow this everywhere
+ boolean disableRelativeVolume;
@Override
public boolean read(InByteBuffer buffer) {
diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java
index 07a6041d4..5caed8f9e 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java
@@ -167,7 +167,9 @@ public class PacketHandler {
}
public void handle(PacketChunkBulk pkg) {
- connection.getPlayer().getWorld().setChunks(pkg.getChunkMap());
+ pkg.getChunks().forEach(((location, chunk) -> connection.fireEvent(new ChunkDataChangeEvent(connection, location, chunk))));
+
+ connection.getPlayer().getWorld().setChunks(pkg.getChunks());
}
public void handle(PacketUpdateHealth pkg) {
@@ -311,6 +313,7 @@ public class PacketHandler {
Log.warn(String.format("Server tried to change blocks in unloaded chunks! (location=%s)", pkg.getLocation()));
return;
}
+ connection.fireEvent(new MultiBlockChangeEvent(connection, pkg));
chunk.setBlocks(pkg.getBlocks());
}
@@ -343,6 +346,9 @@ public class PacketHandler {
}
public void handle(PacketChunkData pkg) {
+ pkg.getBlockEntities().forEach(((position, compoundTag) -> connection.fireEvent(new BlockEntityMetaDataChangeEvent(connection, position, null, compoundTag))));
+ connection.fireEvent(new ChunkDataChangeEvent(connection, pkg));
+
connection.getPlayer().getWorld().setChunk(pkg.getLocation(), pkg.getChunk());
connection.getPlayer().getWorld().setBlockEntityData(pkg.getBlockEntities());
}
@@ -404,6 +410,7 @@ public class PacketHandler {
}
public void handle(PacketBlockEntityMetadata pkg) {
+ connection.fireEvent(new BlockEntityMetaDataChangeEvent(connection, pkg));
connection.getPlayer().getWorld().setBlockEntityData(pkg.getPosition(), pkg.getNbt());
}
@@ -487,7 +494,9 @@ public class PacketHandler {
}
public void handle(PacketEffect pkg) {
- // ToDo
+ if (connection.fireEvent(new EffectEvent(connection, pkg))) {
+ return;
+ }
}
public void handle(PacketScoreboardObjective pkg) {
@@ -499,7 +508,6 @@ public class PacketHandler {
}
public void handle(PacketScoreboardUpdateScore pkg) {
- // ToDo handle correctly
switch (pkg.getAction()) {
case CREATE_UPDATE -> connection.getPlayer().getScoreboardManager().getObjective(pkg.getScoreName()).addScore(new ScoreboardScore(pkg.getItemName(), pkg.getScoreName(), pkg.getScoreValue()));
case REMOVE -> {
@@ -547,7 +555,6 @@ public class PacketHandler {
if (connection.fireEvent(event)) {
return;
}
- // ToDo ask user, download pack. for now just send an okay
}
public void handle(PacketEntityProperties pkg) {