mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-12 11:21:15 +01: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.
|
||||
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
|
||||
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;
|
||||
|
||||
import fr.themode.demo.entity.ChickenCreature;
|
||||
import fr.themode.demo.generator.ChunkGeneratorDemo;
|
||||
import fr.themode.minestom.MinecraftServer;
|
||||
import fr.themode.minestom.benchmark.BenchmarkManager;
|
||||
import fr.themode.minestom.benchmark.ThreadResult;
|
||||
import fr.themode.minestom.entity.Entity;
|
||||
import fr.themode.minestom.entity.EntityCreature;
|
||||
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.net.ConnectionManager;
|
||||
import fr.themode.minestom.timer.TaskRunnable;
|
||||
import fr.themode.minestom.utils.MathUtils;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
import fr.themode.minestom.utils.Vector;
|
||||
import fr.themode.minestom.utils.time.TimeUnit;
|
||||
import fr.themode.minestom.utils.time.UpdateOption;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerInit {
|
||||
|
||||
@ -51,10 +48,10 @@ public class PlayerInit {
|
||||
MinecraftServer.getSchedulerManager().addRepeatingTask(new TaskRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long ramUsage = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
||||
ramUsage /= 1e6; // To MB
|
||||
long ramUsage = benchmarkManager.getUsedMemory();
|
||||
ramUsage /= 1e6; // bytes to MB
|
||||
|
||||
String benchmarkMessage = "";
|
||||
/*String benchmarkMessage = "";
|
||||
for (Map.Entry<String, ThreadResult> resultEntry : benchmarkManager.getResultMap().entrySet()) {
|
||||
String name = resultEntry.getKey();
|
||||
ThreadResult result = resultEntry.getValue();
|
||||
@ -66,7 +63,7 @@ public class PlayerInit {
|
||||
benchmarkMessage += "\n";
|
||||
}
|
||||
if (benchmarkMessage.length() > 0)
|
||||
System.out.println(benchmarkMessage);
|
||||
System.out.println(benchmarkMessage);*/
|
||||
|
||||
for (Player player : connectionManager.getOnlinePlayers()) {
|
||||
player.sendHeaderFooter("RAM USAGE: " + ramUsage + " MB", "", '&');
|
||||
@ -74,12 +71,14 @@ public class PlayerInit {
|
||||
}
|
||||
}, new UpdateOption(5, TimeUnit.TICK));
|
||||
|
||||
connectionManager.setResponseDataConsumer(responseData -> {
|
||||
connectionManager.setResponseDataConsumer((playerConnection, responseData) -> {
|
||||
responseData.setName("1.15.2");
|
||||
responseData.setProtocol(578);
|
||||
responseData.setMaxPlayer(100);
|
||||
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>");
|
||||
});
|
||||
|
||||
@ -114,8 +113,8 @@ public class PlayerInit {
|
||||
p.teleport(player.getPosition());
|
||||
}
|
||||
|
||||
ChickenCreature chickenCreature = new ChickenCreature(player.getPosition());
|
||||
chickenCreature.setInstance(player.getInstance());
|
||||
//ChickenCreature chickenCreature = new ChickenCreature(player.getPosition());
|
||||
//chickenCreature.setInstance(player.getInstance());
|
||||
|
||||
});
|
||||
|
||||
@ -128,7 +127,7 @@ public class PlayerInit {
|
||||
});
|
||||
|
||||
player.setEventCallback(PlayerSpawnEvent.class, event -> {
|
||||
player.setGameMode(GameMode.CREATIVE);
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
player.teleport(new Position(0, 66, 0));
|
||||
|
||||
/*Random random = new Random();
|
||||
@ -159,7 +158,7 @@ public class PlayerInit {
|
||||
});
|
||||
inventory.setItemStack(0, item.clone());
|
||||
|
||||
player.openInventory(inventory);
|
||||
//player.openInventory(inventory);
|
||||
|
||||
player.getInventory().addItemStack(new ItemStack((short) 1, (byte) 100));
|
||||
|
||||
|
@ -100,6 +100,7 @@ public class MinecraftServer {
|
||||
RegistryMain.registerItems();
|
||||
RegistryMain.registerEntities();
|
||||
RegistryMain.registerSounds();
|
||||
RegistryMain.registerParticles();
|
||||
|
||||
minecraftServer = new MinecraftServer();
|
||||
|
||||
|
@ -74,6 +74,10 @@ public class BenchmarkManager {
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
public long getUsedMemory() {
|
||||
return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
|
||||
}
|
||||
|
||||
public Map<String, ThreadResult> getResultMap() {
|
||||
return Collections.unmodifiableMap(resultMap);
|
||||
}
|
||||
|
@ -25,10 +25,34 @@ public class BoundingBox {
|
||||
(getMinZ() <= boundingBox.getMaxZ() && getMaxZ() >= boundingBox.getMinZ());
|
||||
}
|
||||
|
||||
// FIXME: seems to do not work properly
|
||||
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 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 maxX = blockPosition.getX() + (x / 2) + 0.5f;
|
||||
|
||||
@ -42,7 +66,7 @@ public class BoundingBox {
|
||||
boolean checkY = getMinY() + y < maxY && getMaxY() + y > minY;
|
||||
boolean checkZ = getMinZ() + z / 2 < maxZ && getMaxZ() - z / 2 > minZ;
|
||||
return checkX && checkY && checkZ;
|
||||
}
|
||||
}*/
|
||||
|
||||
public boolean intersect(float x, float y, float z) {
|
||||
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 yAir = getInstance().getBlockId(yBlock) == 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;
|
||||
newY = yAir ? newY : boundingBox.intersect(yBlock) ? Math.round(position.getY()) : newY;
|
||||
newZ = zAir ? newZ : boundingBox.intersect(zBlock) ? Math.round(position.getZ()) : newZ;
|
||||
|
||||
boolean xIntersect = boundingBox.intersect(xBlock);
|
||||
boolean yIntersect = boundingBox.intersect(yBlock);
|
||||
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);
|
||||
if (this instanceof ObjectEntity) {
|
||||
|
@ -6,6 +6,9 @@ public class PlayerBlockBreakEvent extends CancellableEvent {
|
||||
|
||||
private BlockPosition blockPosition;
|
||||
|
||||
private short blockId;
|
||||
private boolean customBlock;
|
||||
|
||||
public PlayerBlockBreakEvent(BlockPosition blockPosition) {
|
||||
this.blockPosition = blockPosition;
|
||||
}
|
||||
@ -13,4 +16,22 @@ public class PlayerBlockBreakEvent extends CancellableEvent {
|
||||
public BlockPosition getBlockPosition() {
|
||||
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.packet.server.play.BlockChangePacket;
|
||||
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.ChunkUtils;
|
||||
import fr.themode.minestom.utils.SerializerUtils;
|
||||
@ -165,23 +167,26 @@ public class InstanceContainer extends Instance {
|
||||
PlayerBlockBreakEvent blockBreakEvent = new PlayerBlockBreakEvent(blockPosition);
|
||||
player.callEvent(PlayerBlockBreakEvent.class, blockBreakEvent);
|
||||
if (!blockBreakEvent.isCancelled()) {
|
||||
// TODO blockbreak setBlock result
|
||||
int x = blockPosition.getX();
|
||||
int y = blockPosition.getY();
|
||||
int z = blockPosition.getZ();
|
||||
setBlock(x, y, z, (short) 0);
|
||||
ParticlePacket particlePacket = new ParticlePacket(); // TODO change to a proper particle API
|
||||
particlePacket.particleId = 3; // Block particle
|
||||
particlePacket.longDistance = false;
|
||||
particlePacket.x = x + 0.5f;
|
||||
particlePacket.y = y;
|
||||
particlePacket.z = z + 0.5f;
|
||||
particlePacket.offsetX = 0.4f;
|
||||
particlePacket.offsetY = 0.5f;
|
||||
particlePacket.offsetZ = 0.4f;
|
||||
particlePacket.particleData = 0.3f;
|
||||
particlePacket.particleCount = 125;
|
||||
particlePacket.blockId = blockId;
|
||||
|
||||
// Break or change the broken block based on event result
|
||||
short resultBlockId = blockBreakEvent.getResultBlock();
|
||||
boolean custom = blockBreakEvent.isResultCustomBlock();
|
||||
if (custom) {
|
||||
setCustomBlock(x, y, z, resultBlockId);
|
||||
} else {
|
||||
setBlock(x, y, z, resultBlockId);
|
||||
}
|
||||
|
||||
ParticlePacket particlePacket = ParticleCreator.createParticlePacket(Particle.BLOCK, false,
|
||||
x + 0.5f, y, z + 0.5f,
|
||||
0.4f, 0.5f, 0.4f,
|
||||
0.3f, 125, writer -> {
|
||||
writer.writeVarInt(blockId);
|
||||
});
|
||||
|
||||
chunk.sendPacketToViewers(particlePacket);
|
||||
} else {
|
||||
sendChunkSectionUpdate(chunk, ChunkUtils.getSectionAt(blockPosition.getY()), player);
|
||||
|
@ -12,7 +12,7 @@ public class BlockManager {
|
||||
private Short2ObjectMap<CustomBlock> blocksInternalId = new Short2ObjectOpenHashMap<>();
|
||||
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) {
|
||||
String identifier = customBlock.getIdentifier();
|
||||
@ -22,12 +22,13 @@ public class BlockManager {
|
||||
}
|
||||
|
||||
public void registerBlockPlacementRule(BlockPlacementRule blockPlacementRule) {
|
||||
this.placementRules.put(blockPlacementRule.getBlock(), blockPlacementRule);
|
||||
this.placementRules.put(blockPlacementRule.getBlockId(), blockPlacementRule);
|
||||
}
|
||||
|
||||
public BlockPlacementRule getBlockPlacementRule(short blockId) {
|
||||
Block block = Block.getBlockFromId(blockId);
|
||||
return this.placementRules.get(block);
|
||||
Block block = Block.getBlockFromId(blockId); // Convert block alternative
|
||||
blockId = block.getBlockId();
|
||||
return this.placementRules.get(blockId);
|
||||
}
|
||||
|
||||
public CustomBlock getBlock(String identifier) {
|
||||
|
@ -6,15 +6,19 @@ import fr.themode.minestom.utils.BlockPosition;
|
||||
|
||||
public abstract class BlockPlacementRule {
|
||||
|
||||
private Block block;
|
||||
private short blockId;
|
||||
|
||||
public BlockPlacementRule(short blockId) {
|
||||
this.blockId = blockId;
|
||||
}
|
||||
|
||||
public BlockPlacementRule(Block block) {
|
||||
this.block = block;
|
||||
this(block.getBlockId());
|
||||
}
|
||||
|
||||
public abstract short blockRefresh(Instance instance, BlockPosition blockPosition);
|
||||
|
||||
public Block getBlock() {
|
||||
return block;
|
||||
public short getBlockId() {
|
||||
return blockId;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import fr.themode.minestom.utils.BlockPosition;
|
||||
|
||||
public class RedstonePlacementRule extends BlockPlacementRule {
|
||||
|
||||
|
||||
public RedstonePlacementRule() {
|
||||
super(Block.REDSTONE_WIRE);
|
||||
}
|
||||
@ -18,6 +17,11 @@ public class RedstonePlacementRule extends BlockPlacementRule {
|
||||
int y = blockPosition.getY();
|
||||
int z = blockPosition.getZ();
|
||||
|
||||
if (isAir(instance, x, y - 1, z)) {
|
||||
return Block.AIR.getBlockId();
|
||||
}
|
||||
|
||||
|
||||
String east = "none";
|
||||
String north = "none";
|
||||
String power = "0";
|
||||
@ -67,4 +71,9 @@ public class RedstonePlacementRule extends BlockPlacementRule {
|
||||
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.net.player.PlayerConnection;
|
||||
import fr.themode.minestom.ping.ResponseData;
|
||||
import fr.themode.minestom.ping.ResponseDataConsumer;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
@ -14,7 +14,7 @@ public class ConnectionManager {
|
||||
private Set<Player> players = new CopyOnWriteArraySet<>();
|
||||
private Map<PlayerConnection, Player> connectionPlayerMap = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
private Consumer<ResponseData> responseDataConsumer;
|
||||
private ResponseDataConsumer responseDataConsumer;
|
||||
private Consumer<Player> playerInitialization;
|
||||
|
||||
public Player getPlayer(PlayerConnection connection) {
|
||||
@ -49,11 +49,11 @@ public class ConnectionManager {
|
||||
broadcastMessage(message, null);
|
||||
}
|
||||
|
||||
public Consumer<ResponseData> getResponseDataConsumer() {
|
||||
public ResponseDataConsumer getResponseDataConsumer() {
|
||||
return responseDataConsumer;
|
||||
}
|
||||
|
||||
public void setResponseDataConsumer(Consumer<ResponseData> responseDataConsumer) {
|
||||
public void setResponseDataConsumer(ResponseDataConsumer responseDataConsumer) {
|
||||
this.responseDataConsumer = responseDataConsumer;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,8 @@ import fr.themode.minestom.net.packet.client.ClientPacket;
|
||||
|
||||
public class ClientPacketsHandler {
|
||||
|
||||
private static final int SIZE = 0xFF;
|
||||
// Max packet id
|
||||
private static final int SIZE = 0x2E;
|
||||
|
||||
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.player.PlayerConnection;
|
||||
import fr.themode.minestom.ping.ResponseData;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import fr.themode.minestom.ping.ResponseDataConsumer;
|
||||
|
||||
public class StatusRequestPacket implements ClientPreplayPacket {
|
||||
|
||||
@Override
|
||||
public void process(PlayerConnection connection, ConnectionManager connectionManager) {
|
||||
Consumer<ResponseData> consumer = MinecraftServer.getConnectionManager().getResponseDataConsumer();
|
||||
ResponseDataConsumer consumer = MinecraftServer.getConnectionManager().getResponseDataConsumer();
|
||||
ResponseData responseData = new ResponseData();
|
||||
if (responseData == null)
|
||||
throw new NullPointerException("You need to register a ResponseDataConsumer");
|
||||
consumer.accept(responseData);
|
||||
consumer.accept(connection, responseData);
|
||||
|
||||
ResponsePacket responsePacket = new ResponsePacket();
|
||||
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.ServerPacketIdentifier;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ParticlePacket implements ServerPacket {
|
||||
|
||||
public int particleId;
|
||||
@ -13,7 +15,7 @@ public class ParticlePacket implements ServerPacket {
|
||||
public float particleData;
|
||||
public int particleCount;
|
||||
|
||||
public int blockId;
|
||||
public Consumer<PacketWriter> dataConsumer;
|
||||
|
||||
@Override
|
||||
public void write(PacketWriter writer) {
|
||||
@ -27,8 +29,10 @@ public class ParticlePacket implements ServerPacket {
|
||||
writer.writeFloat(offsetZ);
|
||||
writer.writeFloat(particleData);
|
||||
writer.writeInt(particleCount);
|
||||
if (particleId == 3)
|
||||
writer.writeVarInt(blockId);
|
||||
|
||||
if (dataConsumer != null) {
|
||||
dataConsumer.accept(writer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,6 +6,9 @@ import fr.themode.minestom.net.ConnectionState;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.PacketUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
|
||||
public class PlayerConnection {
|
||||
|
||||
private Client client;
|
||||
@ -36,6 +39,15 @@ public class PlayerConnection {
|
||||
client.flush();
|
||||
}
|
||||
|
||||
public SocketAddress getRemoteAddress() {
|
||||
try {
|
||||
return client.getChannel().getRemoteAddress();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Client getClient() {
|
||||
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.instance.block.Block;
|
||||
import fr.themode.minestom.item.Material;
|
||||
import fr.themode.minestom.particle.Particle;
|
||||
import fr.themode.minestom.sound.Sound;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@ -23,16 +24,19 @@ public class RegistryMain {
|
||||
public static final String ITEMS_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 PARTICLES_PATH = "registry/registries.json";
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<RegistryBlock> blocks = parseBlocks(BLOCKS_PATH);
|
||||
List<RegistryItem> items = parseItems(ITEMS_PATH);
|
||||
List<RegistryEntityType> entities = parseEntities(ENTITIES_PATH);
|
||||
List<RegistrySound> sounds = parseSounds(SOUNDS_PATH);
|
||||
List<RegistryParticle> particles = parseParticles(PARTICLES_PATH);
|
||||
//writeBlocksClass(blocks);
|
||||
//writeItemsClass(items);
|
||||
//writeEntitiesClass(entities);
|
||||
writeSoundsClass(sounds);
|
||||
//writeSoundsClass(sounds);
|
||||
writeParticlesClass(particles);
|
||||
}
|
||||
|
||||
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) {
|
||||
for (RegistryBlock registryBlock : blocks) {
|
||||
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) {
|
||||
List<RegistryBlock> blocks = new ArrayList<>();
|
||||
@ -279,4 +299,34 @@ public class RegistryMain {
|
||||
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) {
|
||||
reader.readByte(typeId -> {
|
||||
//System.out.println("DEBUG TYPE: " + typeId);
|
||||
switch (typeId) {
|
||||
case 0x00: // TAG_End
|
||||
// End of item NBT
|
||||
@ -37,6 +38,15 @@ public class NbtReaderUtils {
|
||||
case 0x03: // TAG_Int
|
||||
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
|
||||
if (name.equals("Unbreakable")) {
|
||||
reader.readInteger(value -> {
|
||||
@ -64,6 +74,14 @@ public class NbtReaderUtils {
|
||||
break;
|
||||
case 0x09: // TAG_List
|
||||
|
||||
reader.readShortSizedString((name, length) -> {
|
||||
|
||||
if (name.equals("StoredEnchantments")) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
break;
|
||||
case 0x0A: // TAG_Compound
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user