mirror of
https://github.com/Minestom/Minestom.git
synced 2024-09-27 14:13:24 +02:00
Update + added particles
This commit is contained in:
parent
c2580789b9
commit
db9549560c
@ -9,6 +9,8 @@ An example of how to use the Minestom library is available [here](src/main/java/
|
|||||||
Minecraft evolved a lot since its release, most of the servers today do not take advantage of vanilla features and even have to struggle because of them. Our target audience is those who want to make a completely different server compared to default Minecraft gamemode such as survival or creative building.
|
Minecraft evolved a lot since its release, most of the servers today do not take advantage of vanilla features and even have to struggle because of them. Our target audience is those who want to make a completely different server compared to default Minecraft gamemode such as survival or creative building.
|
||||||
The goal is to offer more performance for those who need it, Minecraft being single-threaded is the most important problem for them.
|
The goal is to offer more performance for those who need it, Minecraft being single-threaded is the most important problem for them.
|
||||||
|
|
||||||
|
In other words, it makes sense to use Minestom when it takes less time to implement everything you want than removing everything you don't need.
|
||||||
|
|
||||||
# API features
|
# API features
|
||||||
Even if we do not include anything by default in the game, we simplify the way you add them, here is a preview.
|
Even if we do not include anything by default in the game, we simplify the way you add them, here is a preview.
|
||||||
|
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package fr.themode.demo;
|
package fr.themode.demo;
|
||||||
|
|
||||||
import fr.themode.demo.entity.ChickenCreature;
|
|
||||||
import fr.themode.demo.generator.ChunkGeneratorDemo;
|
import fr.themode.demo.generator.ChunkGeneratorDemo;
|
||||||
import fr.themode.minestom.MinecraftServer;
|
import fr.themode.minestom.MinecraftServer;
|
||||||
import fr.themode.minestom.benchmark.BenchmarkManager;
|
import fr.themode.minestom.benchmark.BenchmarkManager;
|
||||||
import fr.themode.minestom.benchmark.ThreadResult;
|
|
||||||
import fr.themode.minestom.entity.Entity;
|
import fr.themode.minestom.entity.Entity;
|
||||||
import fr.themode.minestom.entity.EntityCreature;
|
import fr.themode.minestom.entity.EntityCreature;
|
||||||
import fr.themode.minestom.entity.GameMode;
|
import fr.themode.minestom.entity.GameMode;
|
||||||
@ -16,13 +14,12 @@ import fr.themode.minestom.inventory.InventoryType;
|
|||||||
import fr.themode.minestom.item.ItemStack;
|
import fr.themode.minestom.item.ItemStack;
|
||||||
import fr.themode.minestom.net.ConnectionManager;
|
import fr.themode.minestom.net.ConnectionManager;
|
||||||
import fr.themode.minestom.timer.TaskRunnable;
|
import fr.themode.minestom.timer.TaskRunnable;
|
||||||
import fr.themode.minestom.utils.MathUtils;
|
|
||||||
import fr.themode.minestom.utils.Position;
|
import fr.themode.minestom.utils.Position;
|
||||||
import fr.themode.minestom.utils.Vector;
|
import fr.themode.minestom.utils.Vector;
|
||||||
import fr.themode.minestom.utils.time.TimeUnit;
|
import fr.themode.minestom.utils.time.TimeUnit;
|
||||||
import fr.themode.minestom.utils.time.UpdateOption;
|
import fr.themode.minestom.utils.time.UpdateOption;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PlayerInit {
|
public class PlayerInit {
|
||||||
|
|
||||||
@ -51,10 +48,10 @@ public class PlayerInit {
|
|||||||
MinecraftServer.getSchedulerManager().addRepeatingTask(new TaskRunnable() {
|
MinecraftServer.getSchedulerManager().addRepeatingTask(new TaskRunnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
long ramUsage = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
long ramUsage = benchmarkManager.getUsedMemory();
|
||||||
ramUsage /= 1e6; // To MB
|
ramUsage /= 1e6; // bytes to MB
|
||||||
|
|
||||||
String benchmarkMessage = "";
|
/*String benchmarkMessage = "";
|
||||||
for (Map.Entry<String, ThreadResult> resultEntry : benchmarkManager.getResultMap().entrySet()) {
|
for (Map.Entry<String, ThreadResult> resultEntry : benchmarkManager.getResultMap().entrySet()) {
|
||||||
String name = resultEntry.getKey();
|
String name = resultEntry.getKey();
|
||||||
ThreadResult result = resultEntry.getValue();
|
ThreadResult result = resultEntry.getValue();
|
||||||
@ -66,7 +63,7 @@ public class PlayerInit {
|
|||||||
benchmarkMessage += "\n";
|
benchmarkMessage += "\n";
|
||||||
}
|
}
|
||||||
if (benchmarkMessage.length() > 0)
|
if (benchmarkMessage.length() > 0)
|
||||||
System.out.println(benchmarkMessage);
|
System.out.println(benchmarkMessage);*/
|
||||||
|
|
||||||
for (Player player : connectionManager.getOnlinePlayers()) {
|
for (Player player : connectionManager.getOnlinePlayers()) {
|
||||||
player.sendHeaderFooter("RAM USAGE: " + ramUsage + " MB", "", '&');
|
player.sendHeaderFooter("RAM USAGE: " + ramUsage + " MB", "", '&');
|
||||||
@ -74,12 +71,14 @@ public class PlayerInit {
|
|||||||
}
|
}
|
||||||
}, new UpdateOption(5, TimeUnit.TICK));
|
}, new UpdateOption(5, TimeUnit.TICK));
|
||||||
|
|
||||||
connectionManager.setResponseDataConsumer(responseData -> {
|
connectionManager.setResponseDataConsumer((playerConnection, responseData) -> {
|
||||||
responseData.setName("1.15.2");
|
responseData.setName("1.15.2");
|
||||||
responseData.setProtocol(578);
|
responseData.setProtocol(578);
|
||||||
responseData.setMaxPlayer(100);
|
responseData.setMaxPlayer(100);
|
||||||
responseData.setOnline(0);
|
responseData.setOnline(0);
|
||||||
responseData.setDescription("test");
|
responseData.addPlayer("A name", UUID.randomUUID());
|
||||||
|
responseData.addPlayer("Could be some message", UUID.randomUUID());
|
||||||
|
responseData.setDescription("IP test: " + playerConnection.getRemoteAddress());
|
||||||
responseData.setFavicon("data:image/png;base64,<data>");
|
responseData.setFavicon("data:image/png;base64,<data>");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -114,8 +113,8 @@ public class PlayerInit {
|
|||||||
p.teleport(player.getPosition());
|
p.teleport(player.getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
ChickenCreature chickenCreature = new ChickenCreature(player.getPosition());
|
//ChickenCreature chickenCreature = new ChickenCreature(player.getPosition());
|
||||||
chickenCreature.setInstance(player.getInstance());
|
//chickenCreature.setInstance(player.getInstance());
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -128,7 +127,7 @@ public class PlayerInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
player.setEventCallback(PlayerSpawnEvent.class, event -> {
|
player.setEventCallback(PlayerSpawnEvent.class, event -> {
|
||||||
player.setGameMode(GameMode.CREATIVE);
|
player.setGameMode(GameMode.SURVIVAL);
|
||||||
player.teleport(new Position(0, 66, 0));
|
player.teleport(new Position(0, 66, 0));
|
||||||
|
|
||||||
/*Random random = new Random();
|
/*Random random = new Random();
|
||||||
@ -159,7 +158,7 @@ public class PlayerInit {
|
|||||||
});
|
});
|
||||||
inventory.setItemStack(0, item.clone());
|
inventory.setItemStack(0, item.clone());
|
||||||
|
|
||||||
player.openInventory(inventory);
|
//player.openInventory(inventory);
|
||||||
|
|
||||||
player.getInventory().addItemStack(new ItemStack((short) 1, (byte) 100));
|
player.getInventory().addItemStack(new ItemStack((short) 1, (byte) 100));
|
||||||
|
|
||||||
|
@ -100,6 +100,7 @@ public class MinecraftServer {
|
|||||||
RegistryMain.registerItems();
|
RegistryMain.registerItems();
|
||||||
RegistryMain.registerEntities();
|
RegistryMain.registerEntities();
|
||||||
RegistryMain.registerSounds();
|
RegistryMain.registerSounds();
|
||||||
|
RegistryMain.registerParticles();
|
||||||
|
|
||||||
minecraftServer = new MinecraftServer();
|
minecraftServer = new MinecraftServer();
|
||||||
|
|
||||||
|
@ -74,6 +74,10 @@ public class BenchmarkManager {
|
|||||||
this.enabled = false;
|
this.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getUsedMemory() {
|
||||||
|
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
||||||
|
}
|
||||||
|
|
||||||
public Map<String, ThreadResult> getResultMap() {
|
public Map<String, ThreadResult> getResultMap() {
|
||||||
return Collections.unmodifiableMap(resultMap);
|
return Collections.unmodifiableMap(resultMap);
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,34 @@ public class BoundingBox {
|
|||||||
(getMinZ() <= boundingBox.getMaxZ() && getMaxZ() >= boundingBox.getMinZ());
|
(getMinZ() <= boundingBox.getMaxZ() && getMaxZ() >= boundingBox.getMinZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: seems to do not work properly
|
||||||
public boolean intersect(BlockPosition blockPosition) {
|
public boolean intersect(BlockPosition blockPosition) {
|
||||||
final float x = 1.6f;
|
final float x = 1.6f;
|
||||||
final float y = 1;
|
final float y = 1;
|
||||||
final float z = 1.6f;
|
final float z = 1.6f;
|
||||||
|
|
||||||
|
float minX = blockPosition.getX() - (x / 2) + 0.5f;
|
||||||
|
float maxX = blockPosition.getX() + (x / 2) + 0.5f;
|
||||||
|
|
||||||
|
float minY = blockPosition.getY();
|
||||||
|
float maxY = blockPosition.getY() + y;
|
||||||
|
|
||||||
|
float minZ = blockPosition.getZ() - (z / 2) + 0.5f;
|
||||||
|
float maxZ = blockPosition.getZ() + (z / 2) + 0.5f;
|
||||||
|
|
||||||
|
if (getMinX() > maxX) return false;
|
||||||
|
if (getMaxX() < minX) return false;
|
||||||
|
if (getMinY() > maxY) return false;
|
||||||
|
if (getMaxY() < minY) return false;
|
||||||
|
if (getMinZ() > maxZ) return false;
|
||||||
|
return !(getMaxZ() < minZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*public boolean intersect(BlockPosition blockPosition) {
|
||||||
|
final float x = 1.6f;
|
||||||
|
final float y = 1;
|
||||||
|
final float z = 1.6f;
|
||||||
float minX = blockPosition.getX() - (x / 2) + 0.5f;
|
float minX = blockPosition.getX() - (x / 2) + 0.5f;
|
||||||
float maxX = blockPosition.getX() + (x / 2) + 0.5f;
|
float maxX = blockPosition.getX() + (x / 2) + 0.5f;
|
||||||
|
|
||||||
@ -42,7 +66,7 @@ public class BoundingBox {
|
|||||||
boolean checkY = getMinY() + y < maxY && getMaxY() + y > minY;
|
boolean checkY = getMinY() + y < maxY && getMaxY() + y > minY;
|
||||||
boolean checkZ = getMinZ() + z / 2 < maxZ && getMaxZ() - z / 2 > minZ;
|
boolean checkZ = getMinZ() + z / 2 < maxZ && getMaxZ() - z / 2 > minZ;
|
||||||
return checkX && checkY && checkZ;
|
return checkX && checkY && checkZ;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public boolean intersect(float x, float y, float z) {
|
public boolean intersect(float x, float y, float z) {
|
||||||
return (x >= getMinX() && x <= getMaxX()) &&
|
return (x >= getMinX() && x <= getMaxX()) &&
|
||||||
|
@ -226,10 +226,15 @@ public abstract class Entity implements Viewable, DataContainer {
|
|||||||
boolean xAir = getInstance().getBlockId(xBlock) == Material.AIR.getId();
|
boolean xAir = getInstance().getBlockId(xBlock) == Material.AIR.getId();
|
||||||
boolean yAir = getInstance().getBlockId(yBlock) == Material.AIR.getId();
|
boolean yAir = getInstance().getBlockId(yBlock) == Material.AIR.getId();
|
||||||
boolean zAir = getInstance().getBlockId(zBlock) == Material.AIR.getId();
|
boolean zAir = getInstance().getBlockId(zBlock) == Material.AIR.getId();
|
||||||
System.out.println(xAir + " : " + yAir + " : " + zAir);
|
|
||||||
newX = xAir ? newX : boundingBox.intersect(xBlock) ? Math.round(position.getX()) : newX;
|
boolean xIntersect = boundingBox.intersect(xBlock);
|
||||||
newY = yAir ? newY : boundingBox.intersect(yBlock) ? Math.round(position.getY()) : newY;
|
boolean yIntersect = boundingBox.intersect(yBlock);
|
||||||
newZ = zAir ? newZ : boundingBox.intersect(zBlock) ? Math.round(position.getZ()) : newZ;
|
boolean zIntersect = boundingBox.intersect(zBlock);
|
||||||
|
|
||||||
|
System.out.println(xIntersect + " : " + yIntersect + " : " + zIntersect);
|
||||||
|
newX = xAir ? newX : xIntersect ? position.getX() : newX;
|
||||||
|
newY = yAir ? newY : yIntersect ? position.getY() : newY;
|
||||||
|
newZ = zAir ? newZ : zIntersect ? position.getZ() : newZ;
|
||||||
|
|
||||||
refreshPosition(newX, newY, newZ);
|
refreshPosition(newX, newY, newZ);
|
||||||
if (this instanceof ObjectEntity) {
|
if (this instanceof ObjectEntity) {
|
||||||
|
@ -6,6 +6,9 @@ public class PlayerBlockBreakEvent extends CancellableEvent {
|
|||||||
|
|
||||||
private BlockPosition blockPosition;
|
private BlockPosition blockPosition;
|
||||||
|
|
||||||
|
private short blockId;
|
||||||
|
private boolean customBlock;
|
||||||
|
|
||||||
public PlayerBlockBreakEvent(BlockPosition blockPosition) {
|
public PlayerBlockBreakEvent(BlockPosition blockPosition) {
|
||||||
this.blockPosition = blockPosition;
|
this.blockPosition = blockPosition;
|
||||||
}
|
}
|
||||||
@ -13,4 +16,22 @@ public class PlayerBlockBreakEvent extends CancellableEvent {
|
|||||||
public BlockPosition getBlockPosition() {
|
public BlockPosition getBlockPosition() {
|
||||||
return blockPosition;
|
return blockPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public short getResultBlock() {
|
||||||
|
return blockId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultBlock(short blockId) {
|
||||||
|
this.blockId = blockId;
|
||||||
|
this.customBlock = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isResultCustomBlock() {
|
||||||
|
return customBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultCustomBlock(short customBlockId) {
|
||||||
|
this.blockId = customBlockId;
|
||||||
|
this.customBlock = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@ import fr.themode.minestom.instance.block.rule.BlockPlacementRule;
|
|||||||
import fr.themode.minestom.net.PacketWriterUtils;
|
import fr.themode.minestom.net.PacketWriterUtils;
|
||||||
import fr.themode.minestom.net.packet.server.play.BlockChangePacket;
|
import fr.themode.minestom.net.packet.server.play.BlockChangePacket;
|
||||||
import fr.themode.minestom.net.packet.server.play.ParticlePacket;
|
import fr.themode.minestom.net.packet.server.play.ParticlePacket;
|
||||||
|
import fr.themode.minestom.particle.Particle;
|
||||||
|
import fr.themode.minestom.particle.ParticleCreator;
|
||||||
import fr.themode.minestom.utils.BlockPosition;
|
import fr.themode.minestom.utils.BlockPosition;
|
||||||
import fr.themode.minestom.utils.ChunkUtils;
|
import fr.themode.minestom.utils.ChunkUtils;
|
||||||
import fr.themode.minestom.utils.SerializerUtils;
|
import fr.themode.minestom.utils.SerializerUtils;
|
||||||
@ -165,23 +167,26 @@ public class InstanceContainer extends Instance {
|
|||||||
PlayerBlockBreakEvent blockBreakEvent = new PlayerBlockBreakEvent(blockPosition);
|
PlayerBlockBreakEvent blockBreakEvent = new PlayerBlockBreakEvent(blockPosition);
|
||||||
player.callEvent(PlayerBlockBreakEvent.class, blockBreakEvent);
|
player.callEvent(PlayerBlockBreakEvent.class, blockBreakEvent);
|
||||||
if (!blockBreakEvent.isCancelled()) {
|
if (!blockBreakEvent.isCancelled()) {
|
||||||
// TODO blockbreak setBlock result
|
|
||||||
int x = blockPosition.getX();
|
int x = blockPosition.getX();
|
||||||
int y = blockPosition.getY();
|
int y = blockPosition.getY();
|
||||||
int z = blockPosition.getZ();
|
int z = blockPosition.getZ();
|
||||||
setBlock(x, y, z, (short) 0);
|
|
||||||
ParticlePacket particlePacket = new ParticlePacket(); // TODO change to a proper particle API
|
// Break or change the broken block based on event result
|
||||||
particlePacket.particleId = 3; // Block particle
|
short resultBlockId = blockBreakEvent.getResultBlock();
|
||||||
particlePacket.longDistance = false;
|
boolean custom = blockBreakEvent.isResultCustomBlock();
|
||||||
particlePacket.x = x + 0.5f;
|
if (custom) {
|
||||||
particlePacket.y = y;
|
setCustomBlock(x, y, z, resultBlockId);
|
||||||
particlePacket.z = z + 0.5f;
|
} else {
|
||||||
particlePacket.offsetX = 0.4f;
|
setBlock(x, y, z, resultBlockId);
|
||||||
particlePacket.offsetY = 0.5f;
|
}
|
||||||
particlePacket.offsetZ = 0.4f;
|
|
||||||
particlePacket.particleData = 0.3f;
|
ParticlePacket particlePacket = ParticleCreator.createParticlePacket(Particle.BLOCK, false,
|
||||||
particlePacket.particleCount = 125;
|
x + 0.5f, y, z + 0.5f,
|
||||||
particlePacket.blockId = blockId;
|
0.4f, 0.5f, 0.4f,
|
||||||
|
0.3f, 125, writer -> {
|
||||||
|
writer.writeVarInt(blockId);
|
||||||
|
});
|
||||||
|
|
||||||
chunk.sendPacketToViewers(particlePacket);
|
chunk.sendPacketToViewers(particlePacket);
|
||||||
} else {
|
} else {
|
||||||
sendChunkSectionUpdate(chunk, ChunkUtils.getSectionAt(blockPosition.getY()), player);
|
sendChunkSectionUpdate(chunk, ChunkUtils.getSectionAt(blockPosition.getY()), player);
|
||||||
|
@ -12,7 +12,7 @@ public class BlockManager {
|
|||||||
private Short2ObjectMap<CustomBlock> blocksInternalId = new Short2ObjectOpenHashMap<>();
|
private Short2ObjectMap<CustomBlock> blocksInternalId = new Short2ObjectOpenHashMap<>();
|
||||||
private Map<String, CustomBlock> blocksId = new HashMap<>();
|
private Map<String, CustomBlock> blocksId = new HashMap<>();
|
||||||
|
|
||||||
private Map<Block, BlockPlacementRule> placementRules = new HashMap<>();
|
private Short2ObjectOpenHashMap<BlockPlacementRule> placementRules = new Short2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
public void registerCustomBlock(CustomBlock customBlock) {
|
public void registerCustomBlock(CustomBlock customBlock) {
|
||||||
String identifier = customBlock.getIdentifier();
|
String identifier = customBlock.getIdentifier();
|
||||||
@ -22,12 +22,13 @@ public class BlockManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void registerBlockPlacementRule(BlockPlacementRule blockPlacementRule) {
|
public void registerBlockPlacementRule(BlockPlacementRule blockPlacementRule) {
|
||||||
this.placementRules.put(blockPlacementRule.getBlock(), blockPlacementRule);
|
this.placementRules.put(blockPlacementRule.getBlockId(), blockPlacementRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockPlacementRule getBlockPlacementRule(short blockId) {
|
public BlockPlacementRule getBlockPlacementRule(short blockId) {
|
||||||
Block block = Block.getBlockFromId(blockId);
|
Block block = Block.getBlockFromId(blockId); // Convert block alternative
|
||||||
return this.placementRules.get(block);
|
blockId = block.getBlockId();
|
||||||
|
return this.placementRules.get(blockId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomBlock getBlock(String identifier) {
|
public CustomBlock getBlock(String identifier) {
|
||||||
|
@ -6,15 +6,19 @@ import fr.themode.minestom.utils.BlockPosition;
|
|||||||
|
|
||||||
public abstract class BlockPlacementRule {
|
public abstract class BlockPlacementRule {
|
||||||
|
|
||||||
private Block block;
|
private short blockId;
|
||||||
|
|
||||||
|
public BlockPlacementRule(short blockId) {
|
||||||
|
this.blockId = blockId;
|
||||||
|
}
|
||||||
|
|
||||||
public BlockPlacementRule(Block block) {
|
public BlockPlacementRule(Block block) {
|
||||||
this.block = block;
|
this(block.getBlockId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract short blockRefresh(Instance instance, BlockPosition blockPosition);
|
public abstract short blockRefresh(Instance instance, BlockPosition blockPosition);
|
||||||
|
|
||||||
public Block getBlock() {
|
public short getBlockId() {
|
||||||
return block;
|
return blockId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import fr.themode.minestom.utils.BlockPosition;
|
|||||||
|
|
||||||
public class RedstonePlacementRule extends BlockPlacementRule {
|
public class RedstonePlacementRule extends BlockPlacementRule {
|
||||||
|
|
||||||
|
|
||||||
public RedstonePlacementRule() {
|
public RedstonePlacementRule() {
|
||||||
super(Block.REDSTONE_WIRE);
|
super(Block.REDSTONE_WIRE);
|
||||||
}
|
}
|
||||||
@ -18,6 +17,11 @@ public class RedstonePlacementRule extends BlockPlacementRule {
|
|||||||
int y = blockPosition.getY();
|
int y = blockPosition.getY();
|
||||||
int z = blockPosition.getZ();
|
int z = blockPosition.getZ();
|
||||||
|
|
||||||
|
if (isAir(instance, x, y - 1, z)) {
|
||||||
|
return Block.AIR.getBlockId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String east = "none";
|
String east = "none";
|
||||||
String north = "none";
|
String north = "none";
|
||||||
String power = "0";
|
String power = "0";
|
||||||
@ -67,4 +71,9 @@ public class RedstonePlacementRule extends BlockPlacementRule {
|
|||||||
return Block.getBlockFromId(blockId) == Block.REDSTONE_WIRE;
|
return Block.getBlockFromId(blockId) == Block.REDSTONE_WIRE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isAir(Instance instance, int x, int y, int z) {
|
||||||
|
short blockId = instance.getBlockId(x, y, z);
|
||||||
|
return Block.getBlockFromId(blockId) == Block.AIR;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package fr.themode.minestom.net;
|
|||||||
|
|
||||||
import fr.themode.minestom.entity.Player;
|
import fr.themode.minestom.entity.Player;
|
||||||
import fr.themode.minestom.net.player.PlayerConnection;
|
import fr.themode.minestom.net.player.PlayerConnection;
|
||||||
import fr.themode.minestom.ping.ResponseData;
|
import fr.themode.minestom.ping.ResponseDataConsumer;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
@ -14,7 +14,7 @@ public class ConnectionManager {
|
|||||||
private Set<Player> players = new CopyOnWriteArraySet<>();
|
private Set<Player> players = new CopyOnWriteArraySet<>();
|
||||||
private Map<PlayerConnection, Player> connectionPlayerMap = Collections.synchronizedMap(new HashMap<>());
|
private Map<PlayerConnection, Player> connectionPlayerMap = Collections.synchronizedMap(new HashMap<>());
|
||||||
|
|
||||||
private Consumer<ResponseData> responseDataConsumer;
|
private ResponseDataConsumer responseDataConsumer;
|
||||||
private Consumer<Player> playerInitialization;
|
private Consumer<Player> playerInitialization;
|
||||||
|
|
||||||
public Player getPlayer(PlayerConnection connection) {
|
public Player getPlayer(PlayerConnection connection) {
|
||||||
@ -49,11 +49,11 @@ public class ConnectionManager {
|
|||||||
broadcastMessage(message, null);
|
broadcastMessage(message, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Consumer<ResponseData> getResponseDataConsumer() {
|
public ResponseDataConsumer getResponseDataConsumer() {
|
||||||
return responseDataConsumer;
|
return responseDataConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResponseDataConsumer(Consumer<ResponseData> responseDataConsumer) {
|
public void setResponseDataConsumer(ResponseDataConsumer responseDataConsumer) {
|
||||||
this.responseDataConsumer = responseDataConsumer;
|
this.responseDataConsumer = responseDataConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ import fr.themode.minestom.net.packet.client.ClientPacket;
|
|||||||
|
|
||||||
public class ClientPacketsHandler {
|
public class ClientPacketsHandler {
|
||||||
|
|
||||||
private static final int SIZE = 0xFF;
|
// Max packet id
|
||||||
|
private static final int SIZE = 0x2E;
|
||||||
|
|
||||||
private ConstructorAccess[] constructorAccesses = new ConstructorAccess[SIZE];
|
private ConstructorAccess[] constructorAccesses = new ConstructorAccess[SIZE];
|
||||||
|
|
||||||
|
@ -7,18 +7,17 @@ import fr.themode.minestom.net.packet.client.ClientPreplayPacket;
|
|||||||
import fr.themode.minestom.net.packet.server.handshake.ResponsePacket;
|
import fr.themode.minestom.net.packet.server.handshake.ResponsePacket;
|
||||||
import fr.themode.minestom.net.player.PlayerConnection;
|
import fr.themode.minestom.net.player.PlayerConnection;
|
||||||
import fr.themode.minestom.ping.ResponseData;
|
import fr.themode.minestom.ping.ResponseData;
|
||||||
|
import fr.themode.minestom.ping.ResponseDataConsumer;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class StatusRequestPacket implements ClientPreplayPacket {
|
public class StatusRequestPacket implements ClientPreplayPacket {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(PlayerConnection connection, ConnectionManager connectionManager) {
|
public void process(PlayerConnection connection, ConnectionManager connectionManager) {
|
||||||
Consumer<ResponseData> consumer = MinecraftServer.getConnectionManager().getResponseDataConsumer();
|
ResponseDataConsumer consumer = MinecraftServer.getConnectionManager().getResponseDataConsumer();
|
||||||
ResponseData responseData = new ResponseData();
|
ResponseData responseData = new ResponseData();
|
||||||
if (responseData == null)
|
if (responseData == null)
|
||||||
throw new NullPointerException("You need to register a ResponseDataConsumer");
|
throw new NullPointerException("You need to register a ResponseDataConsumer");
|
||||||
consumer.accept(responseData);
|
consumer.accept(connection, responseData);
|
||||||
|
|
||||||
ResponsePacket responsePacket = new ResponsePacket();
|
ResponsePacket responsePacket = new ResponsePacket();
|
||||||
responsePacket.jsonResponse = responseData.build().toString();
|
responsePacket.jsonResponse = responseData.build().toString();
|
||||||
|
@ -4,6 +4,8 @@ import fr.themode.minestom.net.packet.PacketWriter;
|
|||||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||||
import fr.themode.minestom.net.packet.server.ServerPacketIdentifier;
|
import fr.themode.minestom.net.packet.server.ServerPacketIdentifier;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class ParticlePacket implements ServerPacket {
|
public class ParticlePacket implements ServerPacket {
|
||||||
|
|
||||||
public int particleId;
|
public int particleId;
|
||||||
@ -13,7 +15,7 @@ public class ParticlePacket implements ServerPacket {
|
|||||||
public float particleData;
|
public float particleData;
|
||||||
public int particleCount;
|
public int particleCount;
|
||||||
|
|
||||||
public int blockId;
|
public Consumer<PacketWriter> dataConsumer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(PacketWriter writer) {
|
public void write(PacketWriter writer) {
|
||||||
@ -27,8 +29,10 @@ public class ParticlePacket implements ServerPacket {
|
|||||||
writer.writeFloat(offsetZ);
|
writer.writeFloat(offsetZ);
|
||||||
writer.writeFloat(particleData);
|
writer.writeFloat(particleData);
|
||||||
writer.writeInt(particleCount);
|
writer.writeInt(particleCount);
|
||||||
if (particleId == 3)
|
|
||||||
writer.writeVarInt(blockId);
|
if (dataConsumer != null) {
|
||||||
|
dataConsumer.accept(writer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,6 +6,9 @@ import fr.themode.minestom.net.ConnectionState;
|
|||||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||||
import fr.themode.minestom.utils.PacketUtils;
|
import fr.themode.minestom.utils.PacketUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
public class PlayerConnection {
|
public class PlayerConnection {
|
||||||
|
|
||||||
private Client client;
|
private Client client;
|
||||||
@ -36,6 +39,15 @@ public class PlayerConnection {
|
|||||||
client.flush();
|
client.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SocketAddress getRemoteAddress() {
|
||||||
|
try {
|
||||||
|
return client.getChannel().getRemoteAddress();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Client getClient() {
|
public Client getClient() {
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
87
src/main/java/fr/themode/minestom/particle/Particle.java
Normal file
87
src/main/java/fr/themode/minestom/particle/Particle.java
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package fr.themode.minestom.particle;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
|
||||||
|
public enum Particle {
|
||||||
|
|
||||||
|
AMBIENT_ENTITY_EFFECT,
|
||||||
|
ANGRY_VILLAGER,
|
||||||
|
BARRIER,
|
||||||
|
BLOCK,
|
||||||
|
BUBBLE,
|
||||||
|
CLOUD,
|
||||||
|
CRIT,
|
||||||
|
DAMAGE_INDICATOR,
|
||||||
|
DRAGON_BREATH,
|
||||||
|
DRIPPING_LAVA,
|
||||||
|
FALLING_LAVA,
|
||||||
|
LANDING_LAVA,
|
||||||
|
DRIPPING_WATER,
|
||||||
|
FALLING_WATER,
|
||||||
|
DUST,
|
||||||
|
EFFECT,
|
||||||
|
ELDER_GUARDIAN,
|
||||||
|
ENCHANTED_HIT,
|
||||||
|
ENCHANT,
|
||||||
|
END_ROD,
|
||||||
|
ENTITY_EFFECT,
|
||||||
|
EXPLOSION_EMITTER,
|
||||||
|
EXPLOSION,
|
||||||
|
FALLING_DUST,
|
||||||
|
FIREWORK,
|
||||||
|
FISHING,
|
||||||
|
FLAME,
|
||||||
|
FLASH,
|
||||||
|
HAPPY_VILLAGER,
|
||||||
|
COMPOSTER,
|
||||||
|
HEART,
|
||||||
|
INSTANT_EFFECT,
|
||||||
|
ITEM,
|
||||||
|
ITEM_SLIME,
|
||||||
|
ITEM_SNOWBALL,
|
||||||
|
LARGE_SMOKE,
|
||||||
|
LAVA,
|
||||||
|
MYCELIUM,
|
||||||
|
NOTE,
|
||||||
|
POOF,
|
||||||
|
PORTAL,
|
||||||
|
RAIN,
|
||||||
|
SMOKE,
|
||||||
|
SNEEZE,
|
||||||
|
SPIT,
|
||||||
|
SQUID_INK,
|
||||||
|
SWEEP_ATTACK,
|
||||||
|
TOTEM_OF_UNDYING,
|
||||||
|
UNDERWATER,
|
||||||
|
SPLASH,
|
||||||
|
WITCH,
|
||||||
|
BUBBLE_POP,
|
||||||
|
CURRENT_DOWN,
|
||||||
|
BUBBLE_COLUMN_UP,
|
||||||
|
NAUTILUS,
|
||||||
|
DOLPHIN,
|
||||||
|
CAMPFIRE_COSY_SMOKE,
|
||||||
|
CAMPFIRE_SIGNAL_SMOKE,
|
||||||
|
DRIPPING_HONEY,
|
||||||
|
FALLING_HONEY,
|
||||||
|
LANDING_HONEY,
|
||||||
|
FALLING_NECTAR;
|
||||||
|
|
||||||
|
private static Int2ObjectOpenHashMap<Particle> map = new Int2ObjectOpenHashMap();
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
public static Particle fromId(int id) {
|
||||||
|
return map.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIdentifier(int id) {
|
||||||
|
this.id = id;
|
||||||
|
|
||||||
|
map.put(id, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package fr.themode.minestom.particle;
|
||||||
|
|
||||||
|
import fr.themode.minestom.net.packet.PacketWriter;
|
||||||
|
import fr.themode.minestom.net.packet.server.play.ParticlePacket;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class ParticleCreator {
|
||||||
|
|
||||||
|
public static ParticlePacket createParticlePacket(Particle particle, boolean distance,
|
||||||
|
double x, double y, double z,
|
||||||
|
float offsetX, float offsetY, float offsetZ,
|
||||||
|
float particleData, int count, Consumer<PacketWriter> dataWriter) {
|
||||||
|
ParticlePacket particlePacket = new ParticlePacket();
|
||||||
|
particlePacket.particleId = particle.getId();
|
||||||
|
particlePacket.longDistance = distance;
|
||||||
|
|
||||||
|
particlePacket.x = x;
|
||||||
|
particlePacket.y = y;
|
||||||
|
particlePacket.z = z;
|
||||||
|
|
||||||
|
particlePacket.offsetX = offsetX;
|
||||||
|
particlePacket.offsetY = offsetY;
|
||||||
|
particlePacket.offsetZ = offsetZ;
|
||||||
|
|
||||||
|
particlePacket.particleData = particleData;
|
||||||
|
particlePacket.particleCount = count;
|
||||||
|
particlePacket.dataConsumer = dataWriter;
|
||||||
|
|
||||||
|
return particlePacket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ParticlePacket createParticlePacket(Particle particle,
|
||||||
|
double x, double y, double z,
|
||||||
|
float offsetX, float offsetY, float offsetZ,
|
||||||
|
int count) {
|
||||||
|
return createParticlePacket(particle, false,
|
||||||
|
x, y, z,
|
||||||
|
offsetX, offsetY, offsetZ,
|
||||||
|
0, count, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package fr.themode.minestom.ping;
|
||||||
|
|
||||||
|
import fr.themode.minestom.net.player.PlayerConnection;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ResponseDataConsumer {
|
||||||
|
|
||||||
|
void accept(PlayerConnection playerConnection, ResponseData responseData);
|
||||||
|
|
||||||
|
}
|
@ -7,6 +7,7 @@ import com.google.gson.JsonObject;
|
|||||||
import fr.themode.minestom.entity.EntityType;
|
import fr.themode.minestom.entity.EntityType;
|
||||||
import fr.themode.minestom.instance.block.Block;
|
import fr.themode.minestom.instance.block.Block;
|
||||||
import fr.themode.minestom.item.Material;
|
import fr.themode.minestom.item.Material;
|
||||||
|
import fr.themode.minestom.particle.Particle;
|
||||||
import fr.themode.minestom.sound.Sound;
|
import fr.themode.minestom.sound.Sound;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
@ -23,16 +24,19 @@ public class RegistryMain {
|
|||||||
public static final String ITEMS_PATH = "registry/registries.json";
|
public static final String ITEMS_PATH = "registry/registries.json";
|
||||||
public static final String ENTITIES_PATH = "registry/registries.json";
|
public static final String ENTITIES_PATH = "registry/registries.json";
|
||||||
public static final String SOUNDS_PATH = "registry/registries.json";
|
public static final String SOUNDS_PATH = "registry/registries.json";
|
||||||
|
public static final String PARTICLES_PATH = "registry/registries.json";
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
List<RegistryBlock> blocks = parseBlocks(BLOCKS_PATH);
|
List<RegistryBlock> blocks = parseBlocks(BLOCKS_PATH);
|
||||||
List<RegistryItem> items = parseItems(ITEMS_PATH);
|
List<RegistryItem> items = parseItems(ITEMS_PATH);
|
||||||
List<RegistryEntityType> entities = parseEntities(ENTITIES_PATH);
|
List<RegistryEntityType> entities = parseEntities(ENTITIES_PATH);
|
||||||
List<RegistrySound> sounds = parseSounds(SOUNDS_PATH);
|
List<RegistrySound> sounds = parseSounds(SOUNDS_PATH);
|
||||||
|
List<RegistryParticle> particles = parseParticles(PARTICLES_PATH);
|
||||||
//writeBlocksClass(blocks);
|
//writeBlocksClass(blocks);
|
||||||
//writeItemsClass(items);
|
//writeItemsClass(items);
|
||||||
//writeEntitiesClass(entities);
|
//writeEntitiesClass(entities);
|
||||||
writeSoundsClass(sounds);
|
//writeSoundsClass(sounds);
|
||||||
|
writeParticlesClass(particles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerBlocks() {
|
public static void registerBlocks() {
|
||||||
@ -90,6 +94,15 @@ public class RegistryMain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void registerParticles() {
|
||||||
|
List<RegistryParticle> registryParticles = parseParticles(PARTICLES_PATH);
|
||||||
|
|
||||||
|
for (RegistryParticle registryParticle : registryParticles) {
|
||||||
|
Particle particle = Particle.valueOf(registryParticle.name);
|
||||||
|
particle.setIdentifier(registryParticle.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void writeBlocksClass(List<RegistryBlock> blocks) {
|
private static void writeBlocksClass(List<RegistryBlock> blocks) {
|
||||||
for (RegistryBlock registryBlock : blocks) {
|
for (RegistryBlock registryBlock : blocks) {
|
||||||
String line = registryBlock.name + ",";
|
String line = registryBlock.name + ",";
|
||||||
@ -119,6 +132,13 @@ public class RegistryMain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void writeParticlesClass(List<RegistryParticle> particles) {
|
||||||
|
for (RegistryParticle registryParticle : particles) {
|
||||||
|
String line = registryParticle.name + ",";
|
||||||
|
System.out.println(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static List<RegistryBlock> parseBlocks(String path) {
|
private static List<RegistryBlock> parseBlocks(String path) {
|
||||||
List<RegistryBlock> blocks = new ArrayList<>();
|
List<RegistryBlock> blocks = new ArrayList<>();
|
||||||
@ -279,4 +299,34 @@ public class RegistryMain {
|
|||||||
return registrySounds;
|
return registrySounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<RegistryParticle> parseParticles(String path) {
|
||||||
|
List<RegistryParticle> registryParticles = new ArrayList<>();
|
||||||
|
|
||||||
|
BufferedReader bufferedReader = null;
|
||||||
|
try {
|
||||||
|
bufferedReader = new BufferedReader(new FileReader(path));
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
Gson gson = new Gson();
|
||||||
|
JsonObject obj = gson.fromJson(bufferedReader, JsonObject.class);
|
||||||
|
|
||||||
|
JsonObject itemsObject = obj.getAsJsonObject("minecraft:particle_type");
|
||||||
|
JsonObject entriesObject = itemsObject.getAsJsonObject("entries");
|
||||||
|
|
||||||
|
Set<Map.Entry<String, JsonElement>> entriesEntries = entriesObject.entrySet();//will return members of your object
|
||||||
|
for (Map.Entry<String, JsonElement> entryEntry : entriesEntries) {
|
||||||
|
RegistryParticle registryParticle = new RegistryParticle();
|
||||||
|
registryParticles.add(registryParticle);
|
||||||
|
String item = entryEntry.getKey();
|
||||||
|
String itemName = item.toUpperCase().replace("MINECRAFT:", "").replace(".", "_");
|
||||||
|
registryParticle.name = itemName;
|
||||||
|
short id = entryEntry.getValue().getAsJsonObject().get("protocol_id").getAsShort();
|
||||||
|
registryParticle.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return registryParticles;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package fr.themode.minestom.registry;
|
||||||
|
|
||||||
|
public class RegistryParticle {
|
||||||
|
|
||||||
|
protected String name;
|
||||||
|
protected int id;
|
||||||
|
|
||||||
|
}
|
@ -13,6 +13,7 @@ public class NbtReaderUtils {
|
|||||||
|
|
||||||
public static void readItemStackNBT(PacketReader reader, Consumer<ItemStack> consumer, ItemStack item) {
|
public static void readItemStackNBT(PacketReader reader, Consumer<ItemStack> consumer, ItemStack item) {
|
||||||
reader.readByte(typeId -> {
|
reader.readByte(typeId -> {
|
||||||
|
//System.out.println("DEBUG TYPE: " + typeId);
|
||||||
switch (typeId) {
|
switch (typeId) {
|
||||||
case 0x00: // TAG_End
|
case 0x00: // TAG_End
|
||||||
// End of item NBT
|
// End of item NBT
|
||||||
@ -37,6 +38,15 @@ public class NbtReaderUtils {
|
|||||||
case 0x03: // TAG_Int
|
case 0x03: // TAG_Int
|
||||||
reader.readShortSizedString((name, length) -> {
|
reader.readShortSizedString((name, length) -> {
|
||||||
|
|
||||||
|
// Damage
|
||||||
|
if (name.equals("Damage")) {
|
||||||
|
reader.readInteger(damage -> {
|
||||||
|
//item.setDamage(damage);
|
||||||
|
// TODO short vs int damage
|
||||||
|
readItemStackNBT(reader, consumer, item);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Unbreakable
|
// Unbreakable
|
||||||
if (name.equals("Unbreakable")) {
|
if (name.equals("Unbreakable")) {
|
||||||
reader.readInteger(value -> {
|
reader.readInteger(value -> {
|
||||||
@ -64,6 +74,14 @@ public class NbtReaderUtils {
|
|||||||
break;
|
break;
|
||||||
case 0x09: // TAG_List
|
case 0x09: // TAG_List
|
||||||
|
|
||||||
|
reader.readShortSizedString((name, length) -> {
|
||||||
|
|
||||||
|
if (name.equals("StoredEnchantments")) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0x0A: // TAG_Compound
|
case 0x0A: // TAG_Compound
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user