mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-31 21:48:08 +01:00
Merge branch 'master' of https://github.com/Minestom/Minestom
Conflicts: build.gradle src/main/java/net/minestom/server/entity/Player.java
This commit is contained in:
commit
e203d9c45a
@ -56,6 +56,6 @@ dependencies {
|
|||||||
annotationProcessor 'org.projectlombok:lombok:1.18.12'
|
annotationProcessor 'org.projectlombok:lombok:1.18.12'
|
||||||
|
|
||||||
// Pathfinding
|
// Pathfinding
|
||||||
implementation 'com.github.MadMartian:hydrazine-path-finding:1.02'
|
implementation 'com.github.MadMartian:hydrazine-path-finding:1.1.0'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
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.demo.generator.NoiseTestGenerator;
|
import fr.themode.demo.generator.NoiseTestGenerator;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.attribute.Attribute;
|
import net.minestom.server.attribute.Attribute;
|
||||||
import net.minestom.server.benchmark.BenchmarkManager;
|
import net.minestom.server.benchmark.BenchmarkManager;
|
||||||
import net.minestom.server.benchmark.ThreadResult;
|
import net.minestom.server.benchmark.ThreadResult;
|
||||||
|
import net.minestom.server.chat.*;
|
||||||
import net.minestom.server.entity.*;
|
import net.minestom.server.entity.*;
|
||||||
import net.minestom.server.entity.damage.DamageType;
|
import net.minestom.server.entity.damage.DamageType;
|
||||||
|
import net.minestom.server.entity.type.EntityZombie;
|
||||||
import net.minestom.server.event.entity.EntityAttackEvent;
|
import net.minestom.server.event.entity.EntityAttackEvent;
|
||||||
import net.minestom.server.event.item.ItemDropEvent;
|
import net.minestom.server.event.item.ItemDropEvent;
|
||||||
import net.minestom.server.event.item.ItemUpdateStateEvent;
|
import net.minestom.server.event.item.ItemUpdateStateEvent;
|
||||||
@ -39,19 +40,13 @@ import java.util.Map;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PlayerInit {
|
public class PlayerInit {
|
||||||
|
|
||||||
private static String textures = "ewogICJ0aW1lc3RhbXAiIDogMTU5MDg1NTI3NjIwNCwKICAicHJvZmlsZUlkIiA6ICI0NTY2ZTY5ZmM5MDc0OGVlOGQ3MWQ3YmE1YWEwMGQyMCIsCiAgInByb2ZpbGVOYW1lIiA6ICJUaGlua29mZGVhdGgiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzRkMWUwOGIwYmI3ZTlmNTkwYWYyNzc1ODEyNWJiZWQxNzc4YWM2Y2VmNzI5YWVkZmNiOTYxM2U5OTExYWU3NSIKICAgIH0sCiAgICAiQ0FQRSIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjBjYzA4ODQwNzAwNDQ3MzIyZDk1M2EwMmI5NjVmMWQ2NWExM2E2MDNiZjY0YjE3YzgwM2MyMTQ0NmZlMTYzNSIKICAgIH0KICB9Cn0=";
|
|
||||||
private static String signature = "rCVVwVpLF9ovy+Hm4cOXOLSPOMjNo5WoBfHo9K2OcTUPqcZJ1P/1k4lAnQkChD/Ri11iJ84PejWJzDkHMXM8196Wh+jf12d2GJVhca9/SRLms0cFJjdZZjs72+82AdX0OtO3+qzwKRHzHoEYb+ZVZLfgx37ZKKo4DD3IKmaSnwEjOVJ4BOhnsXLmcNW37kdZUmv2/hlg7ZuWZaayWPhadCYEMnkpVtDIpnpzAeV9EcRfg/ysQoynO2v6WEW0RtnfFEczMN6vXtfiuC8UqyA2SK9aiLnBgpGaehDfFIq/0dpo2uFilVDS/Il6uQ1JSwq7yNT5lNF+i1AlH9SGf1VVy5mT9ShmkVmRxCXX5cSNLXZD0acsNNJb/GAuDHuXpE32GsfgKxWAXMHLw0GnbADbFDfdl5nQyQTDS7FRfUjsFpF8a8Z83muFXaty2WLFy1zxy2JEkI/q+ltLaEG6mQbWI2zhOS7ARvK0OmPz4lDYVInfrwL93AIdMUg2Re817hsapkN6Dm1ND+iirvayR90gqQ9C9J0dMMBlSyTSoKBQeLsi8qETS+7LuhvletPTDFolnTIvP8hj2bWLmQ7LfXJ2arJCUw86YEavVYuF0gYrBuKcEYTC4DA0kO4yLj63gwEgOj9dEigCgyqUcenzmZBffSZ365/QF0cGrG7HC7HmF0w=";
|
|
||||||
|
|
||||||
private static PlayerSkin skin = new PlayerSkin(textures, signature);
|
|
||||||
|
|
||||||
private static volatile InstanceContainer instanceContainer;
|
private static volatile InstanceContainer instanceContainer;
|
||||||
private static volatile InstanceContainer netherTest;
|
private static volatile InstanceContainer netherTest;
|
||||||
|
|
||||||
private static volatile Inventory inventory;
|
private static volatile Inventory inventory;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
//StorageFolder storageFolder = MinecraftServer.getStorageManager().getFolder("chunk_data");
|
//StorageFolder storageFolder = MinecraftServer.getStorageManager().getFolder("instance_data");
|
||||||
ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo();
|
ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo();
|
||||||
NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator();
|
NoiseTestGenerator noiseTestGenerator = new NoiseTestGenerator();
|
||||||
//instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(storageFolder);
|
//instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(storageFolder);
|
||||||
@ -96,23 +91,26 @@ public class PlayerInit {
|
|||||||
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();
|
||||||
benchmarkMessage += "&7" + name;
|
benchmarkMessage += ChatColor.GRAY + name;
|
||||||
benchmarkMessage += ": ";
|
benchmarkMessage += ": ";
|
||||||
benchmarkMessage += "&e" + MathUtils.round(result.getCpuPercentage(), 2) + "% CPU ";
|
benchmarkMessage += ChatColor.YELLOW.toString() + MathUtils.round(result.getCpuPercentage(), 2) + "% CPU ";
|
||||||
benchmarkMessage += "&c" + MathUtils.round(result.getUserPercentage(), 2) + "% USER ";
|
benchmarkMessage += ChatColor.RED.toString() + MathUtils.round(result.getUserPercentage(), 2) + "% USER ";
|
||||||
benchmarkMessage += "&d" + MathUtils.round(result.getBlockedPercentage(), 2) + "% BLOCKED ";
|
benchmarkMessage += ChatColor.PINK.toString() + MathUtils.round(result.getBlockedPercentage(), 2) + "% BLOCKED ";
|
||||||
benchmarkMessage += "&a" + MathUtils.round(result.getWaitedPercentage(), 2) + "% WAITED ";
|
benchmarkMessage += ChatColor.BRIGHT_GREEN.toString() + MathUtils.round(result.getWaitedPercentage(), 2) + "% WAITED ";
|
||||||
benchmarkMessage += "\n";
|
benchmarkMessage += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Player player : connectionManager.getOnlinePlayers()) {
|
for (Player player : connectionManager.getOnlinePlayers()) {
|
||||||
player.sendHeaderFooter("RAM USAGE: " + ramUsage + " MB", benchmarkMessage, '&');
|
ColoredText header = ColoredText.of("RAM USAGE: " + ramUsage + " MB");
|
||||||
|
ColoredText footer = ColoredText.of(benchmarkMessage);
|
||||||
|
player.sendHeaderFooter(header, footer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, new UpdateOption(10, TimeUnit.TICK));
|
}, new UpdateOption(10, TimeUnit.TICK));
|
||||||
|
|
||||||
connectionManager.addPacketConsumer((player, packetController, packet) -> {
|
connectionManager.addPacketConsumer((player, packetController, packet) -> {
|
||||||
// Listen to all received packet
|
// Listen to all received packet
|
||||||
|
//System.out.println("PACKET: "+packet.getClass().getSimpleName());
|
||||||
packetController.setCancel(false);
|
packetController.setCancel(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -153,9 +151,13 @@ 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());
|
||||||
chickenCreature.setAttribute(Attribute.MOVEMENT_SPEED, 0.4f);
|
chickenCreature.setAttribute(Attribute.MOVEMENT_SPEED, 0.4f);*/
|
||||||
|
|
||||||
|
EntityZombie zombie = new EntityZombie(player.getPosition());
|
||||||
|
zombie.setAttribute(Attribute.MOVEMENT_SPEED, 0.25f);
|
||||||
|
zombie.setInstance(player.getInstance());
|
||||||
|
|
||||||
/*FakePlayer fakePlayer = new FakePlayer(UUID.randomUUID(), "test");
|
/*FakePlayer fakePlayer = new FakePlayer(UUID.randomUUID(), "test");
|
||||||
fakePlayer.addEventCallback(EntityDeathEvent.class, e -> {
|
fakePlayer.addEventCallback(EntityDeathEvent.class, e -> {
|
||||||
@ -198,13 +200,19 @@ public class PlayerInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
player.addEventCallback(PlayerLoginEvent.class, event -> {
|
player.addEventCallback(PlayerLoginEvent.class, event -> {
|
||||||
|
//final String url = "https://download.mc-packs.net/pack/a83a04f5d78061e0890e13519fea925550461c74.zip";
|
||||||
|
//final String hash = "a83a04f5d78061e0890e13519fea925550461c74";
|
||||||
|
//player.setResourcePack(new ResourcePack(url, hash));
|
||||||
|
|
||||||
event.setSpawningInstance(instanceContainer);
|
event.setSpawningInstance(instanceContainer);
|
||||||
|
player.setEnableRespawnScreen(false);
|
||||||
|
|
||||||
player.setPermissionLevel(4);
|
player.setPermissionLevel(4);
|
||||||
|
|
||||||
player.getInventory().addInventoryCondition((p, slot, clickType, inventoryConditionResult) -> {
|
player.getInventory().addInventoryCondition((p, slot, clickType, inventoryConditionResult) -> {
|
||||||
player.sendMessage("CLICK PLAYER INVENTORY");
|
player.sendMessage("CLICK PLAYER INVENTORY");
|
||||||
System.out.println("slot player: " + slot);
|
System.out.println("slot player: " + slot);
|
||||||
|
p.closeInventory();
|
||||||
});
|
});
|
||||||
|
|
||||||
/*Sidebar scoreboard = new Sidebar("Scoreboard Title");
|
/*Sidebar scoreboard = new Sidebar("Scoreboard Title");
|
||||||
@ -217,27 +225,27 @@ public class PlayerInit {
|
|||||||
scoreboard.setTitle("test");*/
|
scoreboard.setTitle("test");*/
|
||||||
});
|
});
|
||||||
|
|
||||||
player.addEventCallback(PlayerSkinInitEvent.class, event -> {
|
|
||||||
event.setSkin(skin);
|
|
||||||
});
|
|
||||||
|
|
||||||
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
||||||
player.setGameMode(GameMode.CREATIVE);
|
player.setGameMode(GameMode.SURVIVAL);
|
||||||
player.teleport(new Position(0, 41f, 0));
|
player.teleport(new Position(0, 41f, 0));
|
||||||
|
|
||||||
|
player.setHeldItemSlot((byte) 5);
|
||||||
|
|
||||||
player.setGlowing(true);
|
player.setGlowing(true);
|
||||||
|
|
||||||
ItemStack item = new ItemStack(Material.STONE_SWORD, (byte) 1);
|
ItemStack item = new ItemStack(Material.STONE_SWORD, (byte) 1);
|
||||||
item.setDisplayName("Item name");
|
item.setDisplayName(ColoredText.of(ChatColor.BLUE + "Item name"));
|
||||||
item.getLore().add("a lore line");
|
item.getLore().add(ColoredText.of(ChatColor.RED + "a lore line"));
|
||||||
item.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
item.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||||
item.setEnchantment(Enchantment.SHARPNESS, (short) 50);
|
item.setEnchantment(Enchantment.SHARPNESS, (short) 50);
|
||||||
player.getInventory().addItemStack(item);
|
player.getInventory().addItemStack(item);
|
||||||
|
|
||||||
inventory.addItemStack(item.clone());
|
//player.setHelmet(new ItemStack(Material.DIAMOND_HELMET, (byte) 1));
|
||||||
player.openInventory(inventory);
|
|
||||||
|
|
||||||
player.getInventory().addItemStack(new ItemStack(Material.STONE, (byte) 100));
|
inventory.addItemStack(item.clone());
|
||||||
|
//player.openInventory(inventory);
|
||||||
|
|
||||||
|
//player.getInventory().addItemStack(new ItemStack(Material.STONE, (byte) 100));
|
||||||
|
|
||||||
Instance instance = player.getInstance();
|
Instance instance = player.getInstance();
|
||||||
WorldBorder worldBorder = instance.getWorldBorder();
|
WorldBorder worldBorder = instance.getWorldBorder();
|
||||||
@ -264,6 +272,23 @@ public class PlayerInit {
|
|||||||
setBelowNameScoreboard(belowNameScoreboard);
|
setBelowNameScoreboard(belowNameScoreboard);
|
||||||
belowNameScoreboard.updateScore(this, 50);*/
|
belowNameScoreboard.updateScore(this, 50);*/
|
||||||
|
|
||||||
|
ColoredText coloredText1 = ColoredText.of(ChatColor.BLUE, "I am colored")
|
||||||
|
.append(ChatColor.BLUE, "I am the next")
|
||||||
|
.appendFormat("I am {#blue}here");
|
||||||
|
|
||||||
|
ColoredText coloredText2 =
|
||||||
|
ColoredText.ofFormat(
|
||||||
|
"I am {#green}colo{#red}red {#white}{&key.jump} keybind, {@attack.fall} translatable");
|
||||||
|
|
||||||
|
|
||||||
|
RichMessage richMessage1 = RichMessage.of(coloredText1)
|
||||||
|
.setClickEvent(ChatClickEvent.runCommand("/test"))
|
||||||
|
.setHoverEvent(ChatHoverEvent.showText("I'm a text"))
|
||||||
|
.append(coloredText2)
|
||||||
|
.setHoverEvent(ChatHoverEvent.showText("I'm a second text"));
|
||||||
|
|
||||||
|
player.sendMessage(richMessage1);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
player.addEventCallback(PlayerRespawnEvent.class, event -> {
|
player.addEventCallback(PlayerRespawnEvent.class, event -> {
|
||||||
|
@ -12,6 +12,7 @@ import net.minestom.server.entity.EntityManager;
|
|||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.extras.mojangAuth.MojangCrypt;
|
import net.minestom.server.extras.mojangAuth.MojangCrypt;
|
||||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
import net.minestom.server.gamedata.loottables.LootTableManager;
|
||||||
|
import net.minestom.server.gamedata.tags.TagManager;
|
||||||
import net.minestom.server.instance.InstanceManager;
|
import net.minestom.server.instance.InstanceManager;
|
||||||
import net.minestom.server.instance.block.BlockManager;
|
import net.minestom.server.instance.block.BlockManager;
|
||||||
import net.minestom.server.listener.manager.PacketListenerManager;
|
import net.minestom.server.listener.manager.PacketListenerManager;
|
||||||
@ -105,6 +106,7 @@ public class MinecraftServer {
|
|||||||
private static ResponseDataConsumer responseDataConsumer;
|
private static ResponseDataConsumer responseDataConsumer;
|
||||||
private static Difficulty difficulty = Difficulty.NORMAL;
|
private static Difficulty difficulty = Difficulty.NORMAL;
|
||||||
private static LootTableManager lootTableManager;
|
private static LootTableManager lootTableManager;
|
||||||
|
private static TagManager tagManager;
|
||||||
|
|
||||||
//Mojang Auth
|
//Mojang Auth
|
||||||
@Getter
|
@Getter
|
||||||
@ -133,6 +135,7 @@ public class MinecraftServer {
|
|||||||
updateManager = new UpdateManager();
|
updateManager = new UpdateManager();
|
||||||
|
|
||||||
lootTableManager = new LootTableManager();
|
lootTableManager = new LootTableManager();
|
||||||
|
tagManager = new TagManager();
|
||||||
|
|
||||||
nettyServer = new NettyServer(packetProcessor);
|
nettyServer = new NettyServer(packetProcessor);
|
||||||
|
|
||||||
@ -230,6 +233,10 @@ public class MinecraftServer {
|
|||||||
return lootTableManager;
|
return lootTableManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TagManager getTagManager() {
|
||||||
|
return tagManager;
|
||||||
|
}
|
||||||
|
|
||||||
public void start(String address, int port, ResponseDataConsumer responseDataConsumer) {
|
public void start(String address, int port, ResponseDataConsumer responseDataConsumer) {
|
||||||
LOGGER.info("Starting Minestom server.");
|
LOGGER.info("Starting Minestom server.");
|
||||||
MinecraftServer.responseDataConsumer = responseDataConsumer;
|
MinecraftServer.responseDataConsumer = responseDataConsumer;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.minestom.server;
|
package net.minestom.server;
|
||||||
|
|
||||||
import net.kyori.text.TextComponent;
|
import net.minestom.server.chat.ChatColor;
|
||||||
import net.kyori.text.format.TextColor;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.entity.EntityManager;
|
import net.minestom.server.entity.EntityManager;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.instance.InstanceManager;
|
import net.minestom.server.instance.InstanceManager;
|
||||||
@ -48,9 +48,7 @@ public final class UpdateManager {
|
|||||||
player.refreshKeepAlive(time);
|
player.refreshKeepAlive(time);
|
||||||
player.getPlayerConnection().sendPacket(keepAlivePacket);
|
player.getPlayerConnection().sendPacket(keepAlivePacket);
|
||||||
} else if (lastKeepAlive >= KEEP_ALIVE_KICK) {
|
} else if (lastKeepAlive >= KEEP_ALIVE_KICK) {
|
||||||
TextComponent textComponent = TextComponent.of("Timeout")
|
player.kick(ColoredText.of(ChatColor.RED + "Timeout"));
|
||||||
.color(TextColor.RED);
|
|
||||||
player.kick(textComponent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.minestom.server.bossbar;
|
package net.minestom.server.bossbar;
|
||||||
|
|
||||||
import net.minestom.server.Viewable;
|
import net.minestom.server.Viewable;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.network.packet.server.play.BossBarPacket;
|
import net.minestom.server.network.packet.server.play.BossBarPacket;
|
||||||
import net.minestom.server.utils.MathUtils;
|
import net.minestom.server.utils.MathUtils;
|
||||||
@ -20,13 +20,13 @@ public class BossBar implements Viewable {
|
|||||||
private UUID uuid = UUID.randomUUID();
|
private UUID uuid = UUID.randomUUID();
|
||||||
private Set<Player> viewers = new CopyOnWriteArraySet<>();
|
private Set<Player> viewers = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
private String title;
|
private ColoredText title;
|
||||||
private float progress;
|
private float progress;
|
||||||
private BarColor color;
|
private BarColor color;
|
||||||
private BarDivision division;
|
private BarDivision division;
|
||||||
private byte flags;
|
private byte flags;
|
||||||
|
|
||||||
public BossBar(String title, BarColor color, BarDivision division) {
|
public BossBar(ColoredText title, BarColor color, BarDivision division) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
this.division = division;
|
this.division = division;
|
||||||
@ -58,7 +58,7 @@ public class BossBar implements Viewable {
|
|||||||
*
|
*
|
||||||
* @return the current title of the bossbar
|
* @return the current title of the bossbar
|
||||||
*/
|
*/
|
||||||
public String getTitle() {
|
public ColoredText getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ public class BossBar implements Viewable {
|
|||||||
*
|
*
|
||||||
* @param title the new title of the bossbar
|
* @param title the new title of the bossbar
|
||||||
*/
|
*/
|
||||||
public void setTitle(String title) {
|
public void setTitle(ColoredText title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ public class BossBar implements Viewable {
|
|||||||
BossBarPacket bossBarPacket = new BossBarPacket();
|
BossBarPacket bossBarPacket = new BossBarPacket();
|
||||||
bossBarPacket.uuid = uuid;
|
bossBarPacket.uuid = uuid;
|
||||||
bossBarPacket.action = BossBarPacket.Action.ADD;
|
bossBarPacket.action = BossBarPacket.Action.ADD;
|
||||||
bossBarPacket.title = Chat.fromLegacyText(title);
|
bossBarPacket.title = title;
|
||||||
bossBarPacket.health = progress;
|
bossBarPacket.health = progress;
|
||||||
bossBarPacket.color = color;
|
bossBarPacket.color = color;
|
||||||
bossBarPacket.division = division;
|
bossBarPacket.division = division;
|
||||||
@ -165,7 +165,7 @@ public class BossBar implements Viewable {
|
|||||||
BossBarPacket bossBarPacket = new BossBarPacket();
|
BossBarPacket bossBarPacket = new BossBarPacket();
|
||||||
bossBarPacket.uuid = uuid;
|
bossBarPacket.uuid = uuid;
|
||||||
bossBarPacket.action = BossBarPacket.Action.UPDATE_TITLE;
|
bossBarPacket.action = BossBarPacket.Action.UPDATE_TITLE;
|
||||||
bossBarPacket.title = Chat.fromLegacyText(title);
|
bossBarPacket.title = title;
|
||||||
sendPacketToViewers(bossBarPacket);
|
sendPacketToViewers(bossBarPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,22 +1,13 @@
|
|||||||
package net.minestom.server.chat;
|
package net.minestom.server.chat;
|
||||||
|
|
||||||
import net.kyori.text.Component;
|
import net.kyori.text.Component;
|
||||||
import net.kyori.text.TextComponent;
|
|
||||||
import net.kyori.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
/**
|
|
||||||
* Thank for the minecraft-text library made by rbrick:
|
|
||||||
* https://github.com/ctmclub/minecraft-text
|
|
||||||
*/
|
|
||||||
public class Chat {
|
public class Chat {
|
||||||
|
|
||||||
public static final char COLOR_CHAR = (char) 0xA7; // Represent the character '§'
|
public static final char COLOR_CHAR = (char) 0xA7; // Represent the character '§'
|
||||||
|
|
||||||
public static String toJsonString(Component component) {
|
|
||||||
return GsonComponentSerializer.INSTANCE.serialize(component);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Component fromJsonString(String json) {
|
public static Component fromJsonString(String json) {
|
||||||
return GsonComponentSerializer.INSTANCE.deserialize(json);
|
return GsonComponentSerializer.INSTANCE.deserialize(json);
|
||||||
}
|
}
|
||||||
@ -24,12 +15,4 @@ public class Chat {
|
|||||||
public static String toLegacyText(Component component) {
|
public static String toLegacyText(Component component) {
|
||||||
return LegacyComponentSerializer.legacyLinking().serialize(component);
|
return LegacyComponentSerializer.legacyLinking().serialize(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextComponent fromLegacyText(String text, char colorChar) {
|
|
||||||
return LegacyComponentSerializer.legacyLinking().deserialize(text, colorChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TextComponent fromLegacyText(String text) {
|
|
||||||
return fromLegacyText(text, COLOR_CHAR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
32
src/main/java/net/minestom/server/chat/ChatClickEvent.java
Normal file
32
src/main/java/net/minestom/server/chat/ChatClickEvent.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package net.minestom.server.chat;
|
||||||
|
|
||||||
|
public class ChatClickEvent {
|
||||||
|
|
||||||
|
private String action;
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
private ChatClickEvent(String action, String value) {
|
||||||
|
this.action = action;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatClickEvent openUrl(String url) {
|
||||||
|
return new ChatClickEvent("open_url", url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatClickEvent runCommand(String command) {
|
||||||
|
return new ChatClickEvent("run_command", command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatClickEvent suggestCommand(String command) {
|
||||||
|
return new ChatClickEvent("suggest_command", command);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
135
src/main/java/net/minestom/server/chat/ChatColor.java
Normal file
135
src/main/java/net/minestom/server/chat/ChatColor.java
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
package net.minestom.server.chat;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ChatColor {
|
||||||
|
|
||||||
|
public static final ChatColor NO_COLOR = new ChatColor();
|
||||||
|
|
||||||
|
public static final ChatColor BLACK = new ChatColor("black", 0);
|
||||||
|
public static final ChatColor DARK_BLUE = new ChatColor("dark_blue", 1);
|
||||||
|
public static final ChatColor DARK_GREEN = new ChatColor("dark_green", 2);
|
||||||
|
public static final ChatColor DARK_CYAN = new ChatColor("dark_cyan", 3);
|
||||||
|
public static final ChatColor DARK_RED = new ChatColor("dark_red", 4);
|
||||||
|
public static final ChatColor PURPLE = new ChatColor("dark_purple", 5);
|
||||||
|
public static final ChatColor GOLD = new ChatColor("gold", 6);
|
||||||
|
public static final ChatColor GRAY = new ChatColor("gray", 7);
|
||||||
|
public static final ChatColor DARK_GRAY = new ChatColor("dark_gray", 8);
|
||||||
|
public static final ChatColor BLUE = new ChatColor("blue", 9);
|
||||||
|
public static final ChatColor BRIGHT_GREEN = new ChatColor("green", 10);
|
||||||
|
public static final ChatColor CYAN = new ChatColor("cyan", 11);
|
||||||
|
public static final ChatColor RED = new ChatColor("red", 12);
|
||||||
|
public static final ChatColor PINK = new ChatColor("light_purple", 13);
|
||||||
|
public static final ChatColor YELLOW = new ChatColor("yellow", 14);
|
||||||
|
public static final ChatColor WHITE = new ChatColor("white", 15);
|
||||||
|
|
||||||
|
/*public static final ChatColor BLACK = fromRGB(0, 0, 0);
|
||||||
|
public static final ChatColor DARK_BLUE = fromRGB(0, 0, 170);
|
||||||
|
public static final ChatColor DARK_GREEN = fromRGB(0, 170, 0);
|
||||||
|
public static final ChatColor DARK_CYAN = fromRGB(0, 170, 170);
|
||||||
|
public static final ChatColor DARK_RED = fromRGB(170, 0, 0);
|
||||||
|
public static final ChatColor PURPLE = fromRGB(170, 0, 170);
|
||||||
|
public static final ChatColor GOLD = fromRGB(255, 170, 0);
|
||||||
|
public static final ChatColor GRAY = fromRGB(170, 170, 170);
|
||||||
|
public static final ChatColor DARK_GRAY = fromRGB(85, 85, 85);
|
||||||
|
public static final ChatColor BLUE = fromRGB(85, 85, 255);
|
||||||
|
public static final ChatColor BRIGHT_GREEN = fromRGB(85, 255, 85);
|
||||||
|
public static final ChatColor CYAN = fromRGB(85, 255, 255);
|
||||||
|
public static final ChatColor RED = fromRGB(255, 85, 85);
|
||||||
|
public static final ChatColor PINK = fromRGB(255, 85, 255);
|
||||||
|
public static final ChatColor YELLOW = fromRGB(255, 255, 85);
|
||||||
|
public static final ChatColor WHITE = fromRGB(255, 255, 255);*/
|
||||||
|
private static Map<String, ChatColor> colorCode = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
colorCode.put("black", BLACK);
|
||||||
|
colorCode.put("dark_blue", DARK_BLUE);
|
||||||
|
colorCode.put("dark_green", DARK_GREEN);
|
||||||
|
colorCode.put("dark_cyan", DARK_CYAN);
|
||||||
|
colorCode.put("dark_red", DARK_RED);
|
||||||
|
colorCode.put("purple", PURPLE);
|
||||||
|
colorCode.put("gold", GOLD);
|
||||||
|
colorCode.put("gray", GRAY);
|
||||||
|
colorCode.put("dark_gray", DARK_GRAY);
|
||||||
|
colorCode.put("blue", BLUE);
|
||||||
|
colorCode.put("bright_green", BRIGHT_GREEN);
|
||||||
|
colorCode.put("cyan", CYAN);
|
||||||
|
colorCode.put("red", RED);
|
||||||
|
colorCode.put("pink", PINK);
|
||||||
|
colorCode.put("yellow", YELLOW);
|
||||||
|
colorCode.put("white", WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean empty;
|
||||||
|
private int red, green, blue;
|
||||||
|
private int id;
|
||||||
|
// 1.15
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
// 1.15
|
||||||
|
private ChatColor(String name, int id) {
|
||||||
|
this.name = name;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.16
|
||||||
|
private ChatColor(int r, int g, int b) {
|
||||||
|
this.empty = false;
|
||||||
|
this.red = r;
|
||||||
|
this.green = g;
|
||||||
|
this.blue = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChatColor() {
|
||||||
|
this.empty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatColor fromRGB(int r, int g, int b) {
|
||||||
|
return new ChatColor(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatColor fromName(String name) {
|
||||||
|
return colorCode.getOrDefault(name.toLowerCase(), NO_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRed() {
|
||||||
|
return red;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getGreen() {
|
||||||
|
return green;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlue() {
|
||||||
|
return blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.15
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
// 1.15
|
||||||
|
if (name != null)
|
||||||
|
return "{#" + name + "}";
|
||||||
|
// 1.16
|
||||||
|
if (empty)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
String redH = Integer.toHexString(red);
|
||||||
|
String greenH = Integer.toHexString(green);
|
||||||
|
String blueH = Integer.toHexString(blue);
|
||||||
|
return "{#" + redH + greenH + blueH + "}";
|
||||||
|
}
|
||||||
|
}
|
59
src/main/java/net/minestom/server/chat/ChatHoverEvent.java
Normal file
59
src/main/java/net/minestom/server/chat/ChatHoverEvent.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package net.minestom.server.chat;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import net.minestom.server.entity.Entity;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
|
||||||
|
public class ChatHoverEvent {
|
||||||
|
|
||||||
|
private String action;
|
||||||
|
private String value;
|
||||||
|
private JsonObject valueObject;
|
||||||
|
private boolean isJson;
|
||||||
|
|
||||||
|
private ChatHoverEvent(String action, String value) {
|
||||||
|
this.action = action;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChatHoverEvent(String action, JsonObject valueObject) {
|
||||||
|
this.action = action;
|
||||||
|
this.valueObject = valueObject;
|
||||||
|
this.isJson = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatHoverEvent showText(ColoredText text) {
|
||||||
|
return new ChatHoverEvent("show_text", text.getJsonObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static ChatHoverEvent showText(String text) {
|
||||||
|
return new ChatHoverEvent("show_text", text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatHoverEvent showItem(ItemStack itemStack) {
|
||||||
|
throw new UnsupportedOperationException("Feature in progress");
|
||||||
|
//return new ChatHoverEvent("show_item", parsedItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChatHoverEvent showEntity(Entity entity) {
|
||||||
|
throw new UnsupportedOperationException("Feature in progress");
|
||||||
|
//return new ChatHoverEvent("show_entity", parsedEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsonObject getValueObject() {
|
||||||
|
return valueObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isJson() {
|
||||||
|
return isJson;
|
||||||
|
}
|
||||||
|
}
|
180
src/main/java/net/minestom/server/chat/ColoredText.java
Normal file
180
src/main/java/net/minestom/server/chat/ColoredText.java
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
package net.minestom.server.chat;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ColoredText {
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private ColoredText(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColoredText of(ChatColor color, String message) {
|
||||||
|
return new ColoredText(color + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColoredText of(String message) {
|
||||||
|
return of(ChatColor.WHITE, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColoredText ofFormat(String message) {
|
||||||
|
return new ColoredText(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColoredText append(ChatColor color, String message) {
|
||||||
|
this.message += color + message;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColoredText append(String message) {
|
||||||
|
return append(ChatColor.NO_COLOR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColoredText appendFormat(String message) {
|
||||||
|
this.message += message;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getJsonObject().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsonObject getJsonObject() {
|
||||||
|
List<JsonObject> components = getComponents();
|
||||||
|
|
||||||
|
// No message, return empty object
|
||||||
|
if (components.isEmpty()) {
|
||||||
|
return new JsonObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the first element and remove it
|
||||||
|
JsonObject mainObject = components.remove(0);
|
||||||
|
|
||||||
|
// Append all the components
|
||||||
|
if (!components.isEmpty()) {
|
||||||
|
JsonArray extraArray = new JsonArray();
|
||||||
|
for (JsonObject component : components) {
|
||||||
|
extraArray.add(component);
|
||||||
|
}
|
||||||
|
mainObject.add("extra", extraArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return mainObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of objects composing the message
|
||||||
|
*
|
||||||
|
* @return the list of objects composing the message
|
||||||
|
*/
|
||||||
|
protected List<JsonObject> getComponents() {
|
||||||
|
final List<JsonObject> objects = new ArrayList<>();
|
||||||
|
// No message, return empty list
|
||||||
|
if (message.isEmpty())
|
||||||
|
return objects;
|
||||||
|
|
||||||
|
boolean inFormat = false;
|
||||||
|
int formatStart = 0;
|
||||||
|
int formatEnd = 0;
|
||||||
|
|
||||||
|
String currentColor = "";
|
||||||
|
|
||||||
|
for (int i = 0; i < message.length(); i++) {
|
||||||
|
// Last char or null
|
||||||
|
Character p = i == 0 ? null : message.charAt(i - 1);
|
||||||
|
// Current char
|
||||||
|
char c = message.charAt(i);
|
||||||
|
if ((p == null || (p != '/')) && c == '{' && !inFormat) {
|
||||||
|
|
||||||
|
formatEnd = formatEnd > 0 ? formatEnd + 1 : formatEnd;
|
||||||
|
String rawMessage = message.substring(formatEnd, i);
|
||||||
|
if (!rawMessage.isEmpty()) {
|
||||||
|
objects.add(getMessagePart(MessageType.RAW, rawMessage, currentColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
inFormat = true;
|
||||||
|
formatStart = i;
|
||||||
|
continue;
|
||||||
|
} else if ((p == null || (p != '/')) && c == '}' && inFormat) {
|
||||||
|
// Represent the custom format between the brackets
|
||||||
|
String formatString = message.substring(formatStart + 1, i);
|
||||||
|
if (formatString.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
inFormat = false;
|
||||||
|
formatStart = 0;
|
||||||
|
formatEnd = i;
|
||||||
|
|
||||||
|
// Color component
|
||||||
|
if (formatString.startsWith("#")) {
|
||||||
|
// Remove the first # character to get code
|
||||||
|
String colorCode = formatString.substring(1);
|
||||||
|
ChatColor color = ChatColor.fromName(colorCode);
|
||||||
|
if (color == ChatColor.NO_COLOR) {
|
||||||
|
// Use rgb formatting
|
||||||
|
currentColor = colorCode;
|
||||||
|
} else {
|
||||||
|
// Use color name formatiing
|
||||||
|
currentColor = color.getName();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Translatable component
|
||||||
|
if (formatString.startsWith("@")) {
|
||||||
|
String translatableCode = formatString.substring(1);
|
||||||
|
objects.add(getMessagePart(MessageType.TRANSLATABLE, translatableCode, currentColor));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Keybind component
|
||||||
|
if (formatString.startsWith("&")) {
|
||||||
|
String keybindCode = formatString.substring(1);
|
||||||
|
objects.add(getMessagePart(MessageType.KEYBIND, keybindCode, currentColor));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the remaining of the message as a raw message when any
|
||||||
|
if (formatEnd < message.length()) {
|
||||||
|
String lastRawMessage = message.substring(formatEnd + 1);
|
||||||
|
objects.add(getMessagePart(MessageType.RAW, lastRawMessage, currentColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonObject getMessagePart(MessageType messageType, String message, String color) {
|
||||||
|
JsonObject object = new JsonObject();
|
||||||
|
switch (messageType) {
|
||||||
|
case RAW:
|
||||||
|
object.addProperty("text", message);
|
||||||
|
break;
|
||||||
|
case KEYBIND:
|
||||||
|
object.addProperty("keybind", message);
|
||||||
|
break;
|
||||||
|
case TRANSLATABLE:
|
||||||
|
object.addProperty("translate", message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!color.isEmpty()) {
|
||||||
|
object.addProperty("color", color);
|
||||||
|
}
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum MessageType {
|
||||||
|
RAW, KEYBIND, TRANSLATABLE
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
178
src/main/java/net/minestom/server/chat/RichMessage.java
Normal file
178
src/main/java/net/minestom/server/chat/RichMessage.java
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
package net.minestom.server.chat;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import net.minestom.server.utils.validate.Check;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class RichMessage {
|
||||||
|
|
||||||
|
private List<RichComponent> components = new ArrayList<>();
|
||||||
|
private RichComponent currentComponent;
|
||||||
|
|
||||||
|
public static RichMessage of(ColoredText coloredText, FormatRetention formatRetention) {
|
||||||
|
Check.notNull(coloredText, "ColoredText cannot be null");
|
||||||
|
|
||||||
|
RichMessage richMessage = new RichMessage();
|
||||||
|
appendText(richMessage, coloredText, formatRetention);
|
||||||
|
|
||||||
|
return richMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RichMessage of(ColoredText coloredText) {
|
||||||
|
return of(coloredText, FormatRetention.ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void appendText(RichMessage richMessage, ColoredText coloredText, FormatRetention formatRetention) {
|
||||||
|
RichComponent component = new RichComponent(coloredText, formatRetention);
|
||||||
|
richMessage.components.add(component);
|
||||||
|
richMessage.currentComponent = component;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RichMessage setClickEvent(ChatClickEvent clickEvent) {
|
||||||
|
Check.notNull(clickEvent, "ChatClickEvent cannot be null");
|
||||||
|
|
||||||
|
currentComponent.setClickEvent(clickEvent);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RichMessage setHoverEvent(ChatHoverEvent hoverEvent) {
|
||||||
|
Check.notNull(hoverEvent, "ChatHoverEvent cannot be null");
|
||||||
|
|
||||||
|
currentComponent.setHoverEvent(hoverEvent);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RichMessage append(ColoredText coloredText, FormatRetention formatRetention) {
|
||||||
|
Check.notNull(coloredText, "ColoredText cannot be null");
|
||||||
|
|
||||||
|
appendText(this, coloredText, formatRetention);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RichMessage append(ColoredText coloredText) {
|
||||||
|
return append(coloredText, FormatRetention.ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getJsonObject().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonObject getJsonObject() {
|
||||||
|
// No component, return empty json object
|
||||||
|
if (components.isEmpty())
|
||||||
|
return new JsonObject();
|
||||||
|
|
||||||
|
RichComponent firstComponent = components.remove(0);
|
||||||
|
List<JsonObject> firstComponentObjects = getComponentObject(firstComponent);
|
||||||
|
JsonObject mainObject = firstComponentObjects.remove(0);
|
||||||
|
|
||||||
|
if (components.isEmpty() && firstComponentObjects.isEmpty())
|
||||||
|
return mainObject;
|
||||||
|
|
||||||
|
JsonArray extraArray = new JsonArray();
|
||||||
|
for (JsonObject firstComponentObject : firstComponentObjects) {
|
||||||
|
extraArray.add(firstComponentObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RichComponent component : components) {
|
||||||
|
List<JsonObject> componentObjects = getComponentObject(component);
|
||||||
|
for (JsonObject componentObject : componentObjects) {
|
||||||
|
extraArray.add(componentObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mainObject.add("extra", extraArray);
|
||||||
|
|
||||||
|
|
||||||
|
return mainObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<JsonObject> getComponentObject(RichComponent component) {
|
||||||
|
ColoredText coloredText = component.getText();
|
||||||
|
List<JsonObject> componentObjects = coloredText.getComponents();
|
||||||
|
|
||||||
|
ChatClickEvent clickEvent = component.getClickEvent();
|
||||||
|
ChatHoverEvent hoverEvent = component.getHoverEvent();
|
||||||
|
|
||||||
|
// Nothing to process
|
||||||
|
if (clickEvent == null && hoverEvent == null) {
|
||||||
|
return componentObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (JsonObject componentObject : componentObjects) {
|
||||||
|
if (clickEvent != null) {
|
||||||
|
final JsonObject clickObject =
|
||||||
|
getEventObject(clickEvent.getAction(), clickEvent.getValue());
|
||||||
|
componentObject.add("clickEvent", clickObject);
|
||||||
|
}
|
||||||
|
if (hoverEvent != null) {
|
||||||
|
final JsonObject hoverObject;
|
||||||
|
if (hoverEvent.isJson()) {
|
||||||
|
// The value is a JsonObject
|
||||||
|
hoverObject = new JsonObject();
|
||||||
|
hoverObject.addProperty("action", hoverEvent.getAction());
|
||||||
|
hoverObject.add("value", hoverEvent.getValueObject());
|
||||||
|
} else {
|
||||||
|
// The value is a raw string
|
||||||
|
hoverObject = getEventObject(hoverEvent.getAction(), hoverEvent.getValue());
|
||||||
|
}
|
||||||
|
componentObject.add("hoverEvent", hoverObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return componentObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonObject getEventObject(String action, String value) {
|
||||||
|
JsonObject eventObject = new JsonObject();
|
||||||
|
eventObject.addProperty("action", action);
|
||||||
|
eventObject.addProperty("value", value);
|
||||||
|
return eventObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum FormatRetention {
|
||||||
|
ALL, CLICK_EVENT, HOVER_EVENT, NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RichComponent {
|
||||||
|
|
||||||
|
private ColoredText text;
|
||||||
|
private FormatRetention formatRetention;
|
||||||
|
private ChatClickEvent clickEvent;
|
||||||
|
private ChatHoverEvent hoverEvent;
|
||||||
|
|
||||||
|
private RichComponent(ColoredText text, FormatRetention formatRetention) {
|
||||||
|
this.text = text;
|
||||||
|
this.formatRetention = formatRetention;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ColoredText getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FormatRetention getFormatRetention() {
|
||||||
|
return formatRetention;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatClickEvent getClickEvent() {
|
||||||
|
return clickEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClickEvent(ChatClickEvent clickEvent) {
|
||||||
|
this.clickEvent = clickEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatHoverEvent getHoverEvent() {
|
||||||
|
return hoverEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHoverEvent(ChatHoverEvent hoverEvent) {
|
||||||
|
this.hoverEvent = hoverEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,7 @@ package net.minestom.server.entity;
|
|||||||
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.Viewable;
|
import net.minestom.server.Viewable;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.collision.BoundingBox;
|
import net.minestom.server.collision.BoundingBox;
|
||||||
import net.minestom.server.collision.CollisionUtils;
|
import net.minestom.server.collision.CollisionUtils;
|
||||||
import net.minestom.server.data.Data;
|
import net.minestom.server.data.Data;
|
||||||
@ -95,7 +95,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
protected boolean glowing;
|
protected boolean glowing;
|
||||||
protected boolean usingElytra;
|
protected boolean usingElytra;
|
||||||
protected int air = 300;
|
protected int air = 300;
|
||||||
protected String customName;
|
protected ColoredText customName;
|
||||||
protected boolean customNameVisible;
|
protected boolean customNameVisible;
|
||||||
protected boolean silent;
|
protected boolean silent;
|
||||||
protected boolean noGravity;
|
protected boolean noGravity;
|
||||||
@ -824,7 +824,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
*
|
*
|
||||||
* @return the custom name of the entity, null if there is not
|
* @return the custom name of the entity, null if there is not
|
||||||
*/
|
*/
|
||||||
public String getCustomName() {
|
public ColoredText getCustomName() {
|
||||||
return customName;
|
return customName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -833,7 +833,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
*
|
*
|
||||||
* @param customName the custom name of the entity, null to remove it
|
* @param customName the custom name of the entity, null to remove it
|
||||||
*/
|
*/
|
||||||
public void setCustomName(String customName) {
|
public void setCustomName(ColoredText customName) {
|
||||||
this.customName = customName;
|
this.customName = customName;
|
||||||
sendMetadataIndex(2);
|
sendMetadataIndex(2);
|
||||||
}
|
}
|
||||||
@ -1227,13 +1227,13 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fillCustomNameMetaData(PacketWriter packet) {
|
private void fillCustomNameMetaData(PacketWriter packet) {
|
||||||
boolean hasCustomName = customName != null && !customName.isEmpty();
|
boolean hasCustomName = customName != null;
|
||||||
|
|
||||||
packet.writeByte((byte) 2);
|
packet.writeByte((byte) 2);
|
||||||
packet.writeByte(METADATA_OPTCHAT);
|
packet.writeByte(METADATA_OPTCHAT);
|
||||||
packet.writeBoolean(hasCustomName);
|
packet.writeBoolean(hasCustomName);
|
||||||
if (hasCustomName) {
|
if (hasCustomName) {
|
||||||
packet.writeSizedString(Chat.toJsonString(Chat.fromLegacyText(customName)));
|
packet.writeSizedString(customName.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
package net.minestom.server.entity;
|
package net.minestom.server.entity;
|
||||||
|
|
||||||
import net.kyori.text.Component;
|
|
||||||
import net.kyori.text.TextComponent;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.attribute.Attribute;
|
import net.minestom.server.attribute.Attribute;
|
||||||
import net.minestom.server.bossbar.BossBar;
|
import net.minestom.server.bossbar.BossBar;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.ColoredText;
|
||||||
|
import net.minestom.server.chat.RichMessage;
|
||||||
import net.minestom.server.collision.BoundingBox;
|
import net.minestom.server.collision.BoundingBox;
|
||||||
import net.minestom.server.command.CommandManager;
|
import net.minestom.server.command.CommandManager;
|
||||||
import net.minestom.server.command.CommandSender;
|
import net.minestom.server.command.CommandSender;
|
||||||
@ -63,7 +62,7 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
private ConcurrentLinkedQueue<ClientPlayPacket> packets = new ConcurrentLinkedQueue<>();
|
private ConcurrentLinkedQueue<ClientPlayPacket> packets = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
private int latency;
|
private int latency;
|
||||||
private String displayName;
|
private ColoredText displayName;
|
||||||
private PlayerSkin skin;
|
private PlayerSkin skin;
|
||||||
|
|
||||||
private Dimension dimension;
|
private Dimension dimension;
|
||||||
@ -79,9 +78,13 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
private PlayerSettings settings;
|
private PlayerSettings settings;
|
||||||
private float exp;
|
private float exp;
|
||||||
private int level;
|
private int level;
|
||||||
|
|
||||||
private PlayerInventory inventory;
|
private PlayerInventory inventory;
|
||||||
private short heldSlot;
|
|
||||||
private Inventory openInventory;
|
private Inventory openInventory;
|
||||||
|
// Used internally to allow the closing of inventory within the inventory listener
|
||||||
|
private boolean didCloseInventory;
|
||||||
|
|
||||||
|
private byte heldSlot;
|
||||||
|
|
||||||
private Position respawnPoint;
|
private Position respawnPoint;
|
||||||
|
|
||||||
@ -402,21 +405,23 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
public void kill() {
|
public void kill() {
|
||||||
if (!isDead()) {
|
if (!isDead()) {
|
||||||
// send death message to player
|
// send death message to player
|
||||||
Component deathMessage;
|
ColoredText deathMessage;
|
||||||
if (lastDamageSource != null) {
|
if (lastDamageSource != null) {
|
||||||
deathMessage = lastDamageSource.buildDeathScreenMessage(this);
|
deathMessage = lastDamageSource.buildDeathScreenMessage(this);
|
||||||
} else { // may happen if killed by the server without applying damage
|
} else { // may happen if killed by the server without applying damage
|
||||||
deathMessage = TextComponent.of("Killed by poor programming.");
|
deathMessage = ColoredText.of("Killed by poor programming.");
|
||||||
}
|
}
|
||||||
CombatEventPacket deathPacket = CombatEventPacket.death(this, Optional.empty(), deathMessage);
|
CombatEventPacket deathPacket = CombatEventPacket.death(this, Optional.empty(), deathMessage);
|
||||||
playerConnection.sendPacket(deathPacket);
|
playerConnection.sendPacket(deathPacket);
|
||||||
|
|
||||||
// send death message to chat
|
// send death message to chat
|
||||||
Component chatMessage;
|
RichMessage chatMessage;
|
||||||
if (lastDamageSource != null) {
|
if (lastDamageSource != null) {
|
||||||
chatMessage = lastDamageSource.buildChatMessage(this);
|
chatMessage = lastDamageSource.buildChatMessage(this);
|
||||||
} else { // may happen if killed by the server without applying damage
|
} else { // may happen if killed by the server without applying damage
|
||||||
chatMessage = TextComponent.of(getUsername() + " was killed by poor programming.");
|
ColoredText coloredChatMessage =
|
||||||
|
ColoredText.of(getUsername() + " was killed by poor programming.");
|
||||||
|
chatMessage = RichMessage.of(coloredChatMessage);
|
||||||
}
|
}
|
||||||
MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(player -> {
|
MinecraftServer.getConnectionManager().getOnlinePlayers().forEach(player -> {
|
||||||
player.sendMessage(chatMessage);
|
player.sendMessage(chatMessage);
|
||||||
@ -598,27 +603,25 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
// Use legacy color formatting
|
// Use legacy color formatting
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(String message) {
|
public void sendMessage(String message) {
|
||||||
sendMessage(Chat.fromLegacyText(message));
|
sendMessage(ColoredText.of(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a message to the player
|
* Send a message to the player
|
||||||
*
|
*
|
||||||
* @param message the message to send
|
* @param coloredText the text to send
|
||||||
* @param colorChar the character used to represent the color
|
|
||||||
*/
|
*/
|
||||||
public void sendMessage(String message, char colorChar) {
|
public void sendMessage(ColoredText coloredText) {
|
||||||
sendMessage(Chat.fromLegacyText(message, colorChar));
|
playerConnection.sendPacket(new ChatMessagePacket(coloredText.toString(), ChatMessagePacket.Position.CHAT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a message to the player
|
* Send a message to the player
|
||||||
*
|
*
|
||||||
* @param component the text component
|
* @param richMessage the rich text to send
|
||||||
*/
|
*/
|
||||||
public void sendMessage(Component component) {
|
public void sendMessage(RichMessage richMessage) {
|
||||||
String json = Chat.toJsonString(component);
|
playerConnection.sendPacket(new ChatMessagePacket(richMessage.toString(), ChatMessagePacket.Position.CHAT));
|
||||||
playerConnection.sendPacket(new ChatMessagePacket(json, ChatMessagePacket.Position.CHAT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playSound(Sound sound, SoundCategory soundCategory, int x, int y, int z, float volume, float pitch) {
|
public void playSound(Sound sound, SoundCategory soundCategory, int x, int y, int z, float volume, float pitch) {
|
||||||
@ -661,33 +664,29 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
playerConnection.sendPacket(stopSoundPacket);
|
playerConnection.sendPacket(stopSoundPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendHeaderFooter(Component header, Component footer) {
|
public void sendHeaderFooter(ColoredText header, ColoredText footer) {
|
||||||
PlayerListHeaderAndFooterPacket playerListHeaderAndFooterPacket = new PlayerListHeaderAndFooterPacket();
|
PlayerListHeaderAndFooterPacket playerListHeaderAndFooterPacket = new PlayerListHeaderAndFooterPacket();
|
||||||
playerListHeaderAndFooterPacket.emptyHeader = header == null;
|
playerListHeaderAndFooterPacket.emptyHeader = header == null;
|
||||||
playerListHeaderAndFooterPacket.emptyFooter = footer == null;
|
playerListHeaderAndFooterPacket.emptyFooter = footer == null;
|
||||||
playerListHeaderAndFooterPacket.header = Chat.toJsonString(header);
|
playerListHeaderAndFooterPacket.header = header.toString();
|
||||||
playerListHeaderAndFooterPacket.footer = Chat.toJsonString(footer);
|
playerListHeaderAndFooterPacket.footer = footer.toString();
|
||||||
|
|
||||||
playerConnection.sendPacket(playerListHeaderAndFooterPacket);
|
playerConnection.sendPacket(playerListHeaderAndFooterPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendHeaderFooter(String header, String footer, char colorChar) {
|
private void sendTitle(ColoredText text, TitlePacket.Action action) {
|
||||||
sendHeaderFooter(Chat.fromLegacyText(header, colorChar), Chat.fromLegacyText(footer, colorChar));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendTitle(Component title, TitlePacket.Action action) {
|
|
||||||
TitlePacket titlePacket = new TitlePacket();
|
TitlePacket titlePacket = new TitlePacket();
|
||||||
titlePacket.action = action;
|
titlePacket.action = action;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case SET_TITLE:
|
case SET_TITLE:
|
||||||
titlePacket.titleText = Chat.toJsonString(title);
|
titlePacket.titleText = text.toString();
|
||||||
break;
|
break;
|
||||||
case SET_SUBTITLE:
|
case SET_SUBTITLE:
|
||||||
titlePacket.subtitleText = Chat.toJsonString(title);
|
titlePacket.subtitleText = text.toString();
|
||||||
break;
|
break;
|
||||||
case SET_ACTION_BAR:
|
case SET_ACTION_BAR:
|
||||||
titlePacket.actionBarText = Chat.toJsonString(title);
|
titlePacket.actionBarText = text.toString();
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Invalid TitlePacket.Action type!");
|
throw new UnsupportedOperationException("Invalid TitlePacket.Action type!");
|
||||||
}
|
}
|
||||||
@ -695,47 +694,23 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
playerConnection.sendPacket(titlePacket);
|
playerConnection.sendPacket(titlePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendTitleSubtitleMessage(Component title, Component subtitle) {
|
public void sendTitleSubtitleMessage(ColoredText title, ColoredText subtitle) {
|
||||||
sendTitle(title, TitlePacket.Action.SET_TITLE);
|
sendTitle(title, TitlePacket.Action.SET_TITLE);
|
||||||
sendTitle(subtitle, TitlePacket.Action.SET_SUBTITLE);
|
sendTitle(subtitle, TitlePacket.Action.SET_SUBTITLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendTitleMessage(Component title) {
|
public void sendTitleMessage(ColoredText title) {
|
||||||
sendTitle(title, TitlePacket.Action.SET_TITLE);
|
sendTitle(title, TitlePacket.Action.SET_TITLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendTitleMessage(String title, char colorChar) {
|
public void sendSubtitleMessage(ColoredText subtitle) {
|
||||||
sendTitleMessage(Chat.fromLegacyText(title, colorChar));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendTitleMessage(String title) {
|
|
||||||
sendTitleMessage(title, Chat.COLOR_CHAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendSubtitleMessage(Component subtitle) {
|
|
||||||
sendTitle(subtitle, TitlePacket.Action.SET_SUBTITLE);
|
sendTitle(subtitle, TitlePacket.Action.SET_SUBTITLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendSubtitleMessage(String subtitle, char colorChar) {
|
public void sendActionBarMessage(ColoredText actionBar) {
|
||||||
sendSubtitleMessage(Chat.fromLegacyText(subtitle, colorChar));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendSubtitleMessage(String subtitle) {
|
|
||||||
sendSubtitleMessage(subtitle, Chat.COLOR_CHAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendActionBarMessage(Component actionBar) {
|
|
||||||
sendTitle(actionBar, TitlePacket.Action.SET_ACTION_BAR);
|
sendTitle(actionBar, TitlePacket.Action.SET_ACTION_BAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendActionBarMessage(String message, char colorChar) {
|
|
||||||
sendActionBarMessage(Chat.fromLegacyText(message, colorChar));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendActionBarMessage(String message) {
|
|
||||||
sendActionBarMessage(message, Chat.COLOR_CHAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isImmune(DamageType type) {
|
public boolean isImmune(DamageType type) {
|
||||||
if (!getGameMode().canTakeDamage()) {
|
if (!getGameMode().canTakeDamage()) {
|
||||||
@ -844,7 +819,7 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
* @return the player display name,
|
* @return the player display name,
|
||||||
* null means that {@link #getUsername()} is displayed
|
* null means that {@link #getUsername()} is displayed
|
||||||
*/
|
*/
|
||||||
public String getDisplayName() {
|
public ColoredText getDisplayName() {
|
||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -855,10 +830,10 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
*
|
*
|
||||||
* @param displayName the display name
|
* @param displayName the display name
|
||||||
*/
|
*/
|
||||||
public void setDisplayName(String displayName) {
|
public void setDisplayName(ColoredText displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
|
|
||||||
String jsonDisplayName = displayName != null ? Chat.toJsonString(Chat.fromLegacyText(displayName)) : null;
|
String jsonDisplayName = displayName != null ? displayName.toString() : null;
|
||||||
PlayerInfoPacket infoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.UPDATE_DISPLAY_NAME);
|
PlayerInfoPacket infoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.UPDATE_DISPLAY_NAME);
|
||||||
infoPacket.playerInfos.add(new PlayerInfoPacket.UpdateDisplayName(getUuid(), jsonDisplayName));
|
infoPacket.playerInfos.add(new PlayerInfoPacket.UpdateDisplayName(getUuid(), jsonDisplayName));
|
||||||
sendPacketToViewersAndSelf(infoPacket);
|
sendPacketToViewersAndSelf(infoPacket);
|
||||||
@ -1291,11 +1266,11 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
/**
|
/**
|
||||||
* Kick the player with a reason
|
* Kick the player with a reason
|
||||||
*
|
*
|
||||||
* @param textComponent the kick reason
|
* @param text the kick reason
|
||||||
*/
|
*/
|
||||||
public void kick(TextComponent textComponent) {
|
public void kick(ColoredText text) {
|
||||||
DisconnectPacket disconnectPacket = new DisconnectPacket();
|
DisconnectPacket disconnectPacket = new DisconnectPacket();
|
||||||
disconnectPacket.message = Chat.toJsonString(textComponent);
|
disconnectPacket.message = text.toString();
|
||||||
playerConnection.sendPacket(disconnectPacket);
|
playerConnection.sendPacket(disconnectPacket);
|
||||||
playerConnection.disconnect();
|
playerConnection.disconnect();
|
||||||
playerConnection.refreshOnline(false);
|
playerConnection.refreshOnline(false);
|
||||||
@ -1307,7 +1282,7 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
* @param message the kick reason
|
* @param message the kick reason
|
||||||
*/
|
*/
|
||||||
public void kick(String message) {
|
public void kick(String message) {
|
||||||
kick(Chat.fromLegacyText(message));
|
kick(ColoredText.of(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
public LevelType getLevelType() {
|
public LevelType getLevelType() {
|
||||||
@ -1320,7 +1295,7 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
* @param slot the slot that the player has to held
|
* @param slot the slot that the player has to held
|
||||||
* @throws IllegalArgumentException if {@code slot} is not between 0 and 8
|
* @throws IllegalArgumentException if {@code slot} is not between 0 and 8
|
||||||
*/
|
*/
|
||||||
public void setHeldItemSlot(short slot) {
|
public void setHeldItemSlot(byte slot) {
|
||||||
Check.argCondition(!MathUtils.isBetween(slot, 0, 8), "Slot has to be between 0 and 8");
|
Check.argCondition(!MathUtils.isBetween(slot, 0, 8), "Slot has to be between 0 and 8");
|
||||||
|
|
||||||
HeldItemChangePacket heldItemChangePacket = new HeldItemChangePacket();
|
HeldItemChangePacket heldItemChangePacket = new HeldItemChangePacket();
|
||||||
@ -1334,7 +1309,7 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
*
|
*
|
||||||
* @return the current held slot for the player
|
* @return the current held slot for the player
|
||||||
*/
|
*/
|
||||||
public short getHeldSlot() {
|
public byte getHeldSlot() {
|
||||||
return heldSlot;
|
return heldSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1369,15 +1344,6 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the player open inventory
|
|
||||||
*
|
|
||||||
* @return the currently open inventory, null if there is not (player inventory is not detected)
|
|
||||||
*/
|
|
||||||
public Inventory getOpenInventory() {
|
|
||||||
return openInventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to get the {@link CustomBlock} that the player is currently mining
|
* Used to get the {@link CustomBlock} that the player is currently mining
|
||||||
*
|
*
|
||||||
@ -1394,6 +1360,15 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
return Collections.unmodifiableSet(bossBars);
|
return Collections.unmodifiableSet(bossBars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the player open inventory
|
||||||
|
*
|
||||||
|
* @return the currently open inventory, null if there is not (player inventory is not detected)
|
||||||
|
*/
|
||||||
|
public Inventory getOpenInventory() {
|
||||||
|
return openInventory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the specified Inventory, close the previous inventory if existing
|
* Open the specified Inventory, close the previous inventory if existing
|
||||||
*
|
*
|
||||||
@ -1428,7 +1403,7 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the current inventory if there is any
|
* Close the current inventory if there is any
|
||||||
* It closes the player inventory if {@link #getOpenInventory()} returns null
|
* It closes the player inventory (when opened) if {@link #getOpenInventory()} returns null
|
||||||
*/
|
*/
|
||||||
public void closeInventory() {
|
public void closeInventory() {
|
||||||
Inventory openInventory = getOpenInventory();
|
Inventory openInventory = getOpenInventory();
|
||||||
@ -1440,6 +1415,7 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
getInventory().setCursorItem(ItemStack.getAirItem());
|
getInventory().setCursorItem(ItemStack.getAirItem());
|
||||||
} else {
|
} else {
|
||||||
cursorItem = openInventory.getCursorItem(this);
|
cursorItem = openInventory.getCursorItem(this);
|
||||||
|
openInventory.setCursorItem(this, ItemStack.getAirItem());
|
||||||
}
|
}
|
||||||
if (!cursorItem.isAir()) {
|
if (!cursorItem.isAir()) {
|
||||||
// Add item to inventory if he hasn't been able to drop it
|
// Add item to inventory if he hasn't been able to drop it
|
||||||
@ -1458,6 +1434,30 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
}
|
}
|
||||||
playerConnection.sendPacket(closeWindowPacket);
|
playerConnection.sendPacket(closeWindowPacket);
|
||||||
inventory.update();
|
inventory.update();
|
||||||
|
this.didCloseInventory = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally to prevent an inventory click to be processed
|
||||||
|
* when the inventory listeners closed the inventory
|
||||||
|
* <p>
|
||||||
|
* Should only be used within an inventory listener (event or condition)
|
||||||
|
*
|
||||||
|
* @return true if the inventory has been closed, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean didCloseInventory() {
|
||||||
|
return didCloseInventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally to reset the didCloseInventory field
|
||||||
|
* <p>
|
||||||
|
* Shouldn't be used externally without proper understanding of its consequence
|
||||||
|
*
|
||||||
|
* @param didCloseInventory the new didCloseInventory field
|
||||||
|
*/
|
||||||
|
public void UNSAFE_changeDidCloseInventory(boolean didCloseInventory) {
|
||||||
|
this.didCloseInventory = didCloseInventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1743,11 +1743,11 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
* Also cancel eating if {@link #isEating()} was true
|
* Also cancel eating if {@link #isEating()} was true
|
||||||
* <p>
|
* <p>
|
||||||
* Warning: the player will not be noticed by this chance, only his viewers,
|
* Warning: the player will not be noticed by this chance, only his viewers,
|
||||||
* see instead: {@link #setHeldItemSlot(short)}
|
* see instead: {@link #setHeldItemSlot(byte)}
|
||||||
*
|
*
|
||||||
* @param slot the new held slot
|
* @param slot the new held slot
|
||||||
*/
|
*/
|
||||||
public void refreshHeldSlot(short slot) {
|
public void refreshHeldSlot(byte slot) {
|
||||||
this.heldSlot = slot;
|
this.heldSlot = slot;
|
||||||
syncEquipment(EntityEquipmentPacket.Slot.MAIN_HAND);
|
syncEquipment(EntityEquipmentPacket.Slot.MAIN_HAND);
|
||||||
|
|
||||||
@ -1888,7 +1888,7 @@ public class Player extends LivingEntity implements CommandSender {
|
|||||||
final String textures = skin == null ? "" : skin.getTextures();
|
final String textures = skin == null ? "" : skin.getTextures();
|
||||||
final String signature = skin == null ? null : skin.getSignature();
|
final String signature = skin == null ? null : skin.getSignature();
|
||||||
|
|
||||||
String jsonDisplayName = displayName != null ? Chat.toJsonString(Chat.fromLegacyText(displayName)) : null;
|
String jsonDisplayName = displayName != null ? displayName.toString() : null;
|
||||||
PlayerInfoPacket playerInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER);
|
PlayerInfoPacket playerInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER);
|
||||||
|
|
||||||
PlayerInfoPacket.AddPlayer addPlayer =
|
PlayerInfoPacket.AddPlayer addPlayer =
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package net.minestom.server.entity.damage;
|
package net.minestom.server.entity.damage;
|
||||||
|
|
||||||
import net.kyori.text.Component;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.kyori.text.TextComponent;
|
import net.minestom.server.chat.RichMessage;
|
||||||
import net.kyori.text.TranslatableComponent;
|
|
||||||
import net.minestom.server.entity.Entity;
|
import net.minestom.server.entity.Entity;
|
||||||
import net.minestom.server.entity.LivingEntity;
|
import net.minestom.server.entity.LivingEntity;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
@ -35,8 +34,10 @@ public class DamageType {
|
|||||||
return new EntityProjectileDamage(shooter, projectile);
|
return new EntityProjectileDamage(shooter, projectile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component buildChatMessage(Player killed) {
|
public RichMessage buildChatMessage(Player killed) {
|
||||||
return TranslatableComponent.of("death." + identifier, TextComponent.of(killed.getUsername()));
|
RichMessage richMessage = RichMessage.of(ColoredText.ofFormat("{@death." + identifier + "}"))
|
||||||
|
.append(ColoredText.ofFormat(killed.getUsername()));
|
||||||
|
return richMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityDamage fromPlayer(Player player) {
|
public static EntityDamage fromPlayer(Player player) {
|
||||||
@ -47,8 +48,8 @@ public class DamageType {
|
|||||||
return new EntityDamage(entity);
|
return new EntityDamage(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component buildDeathScreenMessage(Player killed) {
|
public ColoredText buildDeathScreenMessage(Player killed) {
|
||||||
return buildChatMessage(killed);
|
return ColoredText.ofFormat("{@death." + identifier + "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.minestom.server.entity.hologram;
|
package net.minestom.server.entity.hologram;
|
||||||
|
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.entity.type.EntityArmorStand;
|
import net.minestom.server.entity.type.EntityArmorStand;
|
||||||
import net.minestom.server.instance.Instance;
|
import net.minestom.server.instance.Instance;
|
||||||
import net.minestom.server.utils.Position;
|
import net.minestom.server.utils.Position;
|
||||||
@ -12,11 +13,11 @@ public class Hologram {
|
|||||||
private HologramEntity entity;
|
private HologramEntity entity;
|
||||||
|
|
||||||
private Position position;
|
private Position position;
|
||||||
private String text;
|
private ColoredText text;
|
||||||
|
|
||||||
private boolean removed;
|
private boolean removed;
|
||||||
|
|
||||||
public Hologram(Instance instance, Position spawnPosition, String text, boolean autoViewable) {
|
public Hologram(Instance instance, Position spawnPosition, ColoredText text, boolean autoViewable) {
|
||||||
this.entity = new HologramEntity(spawnPosition.clone().add(0, OFFSET_Y, 0));
|
this.entity = new HologramEntity(spawnPosition.clone().add(0, OFFSET_Y, 0));
|
||||||
this.entity.setInstance(instance);
|
this.entity.setInstance(instance);
|
||||||
this.entity.setAutoViewable(autoViewable);
|
this.entity.setAutoViewable(autoViewable);
|
||||||
@ -25,7 +26,7 @@ public class Hologram {
|
|||||||
setText(text);
|
setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hologram(Instance instance, Position spawnPosition, String text) {
|
public Hologram(Instance instance, Position spawnPosition, ColoredText text) {
|
||||||
this(instance, spawnPosition, text, true);
|
this(instance, spawnPosition, text, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,11 +41,11 @@ public class Hologram {
|
|||||||
this.entity.teleport(position);
|
this.entity.teleport(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public ColoredText getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(String text) {
|
public void setText(ColoredText text) {
|
||||||
checkRemoved();
|
checkRemoved();
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.entity.setCustomName(text);
|
this.entity.setCustomName(text);
|
||||||
@ -70,7 +71,7 @@ public class Hologram {
|
|||||||
setSmall(true);
|
setSmall(true);
|
||||||
|
|
||||||
setNoGravity(true);
|
setNoGravity(true);
|
||||||
setCustomName("");
|
setCustomName(ColoredText.of(""));
|
||||||
setCustomNameVisible(true);
|
setCustomNameVisible(true);
|
||||||
setInvisible(true);
|
setInvisible(true);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
package net.minestom.server.event.player;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.event.CancellableEvent;
|
||||||
|
import net.minestom.server.utils.MathUtils;
|
||||||
|
import net.minestom.server.utils.validate.Check;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a player change his held slot (by pressing 1-9 keys)
|
||||||
|
*/
|
||||||
|
public class PlayerChangeHeldSlotEvent extends CancellableEvent {
|
||||||
|
|
||||||
|
private Player player;
|
||||||
|
private byte slot;
|
||||||
|
|
||||||
|
public PlayerChangeHeldSlotEvent(Player player, byte slot) {
|
||||||
|
this.player = player;
|
||||||
|
this.slot = slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the player who changed his held slot
|
||||||
|
*
|
||||||
|
* @return the player
|
||||||
|
*/
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the slot which the player will held
|
||||||
|
*
|
||||||
|
* @return the held slot
|
||||||
|
*/
|
||||||
|
public byte getSlot() {
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the final held slot of the player
|
||||||
|
*
|
||||||
|
* @param slot the new held slot
|
||||||
|
* @throws IllegalArgumentException if {@param slot} is not between 0 and 8
|
||||||
|
*/
|
||||||
|
public void setSlot(byte slot) {
|
||||||
|
Check.argCondition(!MathUtils.isBetween(slot, 0, 8), "The held slot needs to be between 0 and 8");
|
||||||
|
this.slot = slot;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package net.minestom.server.event.player;
|
package net.minestom.server.event.player;
|
||||||
|
|
||||||
import net.kyori.text.TextComponent;
|
import net.minestom.server.chat.RichMessage;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.event.CancellableEvent;
|
import net.minestom.server.event.CancellableEvent;
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ public class PlayerChatEvent extends CancellableEvent {
|
|||||||
private Player sender;
|
private Player sender;
|
||||||
private Collection<Player> recipients;
|
private Collection<Player> recipients;
|
||||||
private String message;
|
private String message;
|
||||||
private Function<PlayerChatEvent, TextComponent> chatFormat;
|
private Function<PlayerChatEvent, RichMessage> chatFormat;
|
||||||
|
|
||||||
public PlayerChatEvent(Player sender, Collection<Player> recipients, String message) {
|
public PlayerChatEvent(Player sender, Collection<Player> recipients, String message) {
|
||||||
this.sender = sender;
|
this.sender = sender;
|
||||||
@ -28,7 +28,7 @@ public class PlayerChatEvent extends CancellableEvent {
|
|||||||
/**
|
/**
|
||||||
* @param chatFormat the custom chat format
|
* @param chatFormat the custom chat format
|
||||||
*/
|
*/
|
||||||
public void setChatFormat(Function<PlayerChatEvent, TextComponent> chatFormat) {
|
public void setChatFormat(Function<PlayerChatEvent, RichMessage> chatFormat) {
|
||||||
this.chatFormat = chatFormat;
|
this.chatFormat = chatFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ public class PlayerChatEvent extends CancellableEvent {
|
|||||||
*
|
*
|
||||||
* @return the chat format which will be used
|
* @return the chat format which will be used
|
||||||
*/
|
*/
|
||||||
public Function<PlayerChatEvent, TextComponent> getChatFormatFunction() {
|
public Function<PlayerChatEvent, RichMessage> getChatFormatFunction() {
|
||||||
return chatFormat;
|
return chatFormat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
73
src/main/java/net/minestom/server/gamedata/tags/Tag.java
Normal file
73
src/main/java/net/minestom/server/gamedata/tags/Tag.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package net.minestom.server.gamedata.tags;
|
||||||
|
|
||||||
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a group of items, blocks, fluids, entity types or function.
|
||||||
|
* Immutable by design
|
||||||
|
*/
|
||||||
|
public class Tag {
|
||||||
|
|
||||||
|
public static final Tag EMPTY = new Tag();
|
||||||
|
|
||||||
|
private Set<NamespaceID> values;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new empty tag
|
||||||
|
*/
|
||||||
|
public Tag() {
|
||||||
|
values = new HashSet<>();
|
||||||
|
lockValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new tag with the contents of the container
|
||||||
|
* @param manager Used to load tag contents (as tags are valid values inside 'values')
|
||||||
|
* @param lowerPriority Tag contents from lower priority data packs. If 'replace' is false in 'container',
|
||||||
|
* appends the contents of that pack to the one being constructed
|
||||||
|
* @param container
|
||||||
|
*/
|
||||||
|
public Tag(TagManager manager, String type, Tag lowerPriority, TagContainer container) throws FileNotFoundException {
|
||||||
|
values = new HashSet<>();
|
||||||
|
if(!container.replace) {
|
||||||
|
values.addAll(lowerPriority.values);
|
||||||
|
}
|
||||||
|
Objects.requireNonNull(container.values, "Attempted to load from a TagContainer with no 'values' array");
|
||||||
|
for(String line : container.values) {
|
||||||
|
if(line.startsWith("#")) { // pull contents from a tag
|
||||||
|
Tag subtag = manager.load(NamespaceID.from(line.substring(1)), type);
|
||||||
|
values.addAll(subtag.values);
|
||||||
|
} else {
|
||||||
|
values.add(NamespaceID.from(line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lockValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lockValues() {
|
||||||
|
values = Set.copyOf(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given id in inside this tag
|
||||||
|
* @param id the id to check against
|
||||||
|
* @return 'true' iif this tag contains the given id
|
||||||
|
*/
|
||||||
|
public boolean contains(NamespaceID id) {
|
||||||
|
return values.contains(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an immutable set of values present in this tag
|
||||||
|
* @return immutable set of values present in this tag
|
||||||
|
*/
|
||||||
|
public Set<NamespaceID> getValues() {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package net.minestom.server.gamedata.tags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meant only for parsing tag JSON
|
||||||
|
*/
|
||||||
|
public class TagContainer {
|
||||||
|
boolean replace;
|
||||||
|
String[] values;
|
||||||
|
}
|
102
src/main/java/net/minestom/server/gamedata/tags/TagManager.java
Normal file
102
src/main/java/net/minestom/server/gamedata/tags/TagManager.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package net.minestom.server.gamedata.tags;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import net.minestom.server.registry.ResourceGatherer;
|
||||||
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles loading and caching of tags
|
||||||
|
*/
|
||||||
|
public class TagManager {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(TagManager.class);
|
||||||
|
private final Gson gson;
|
||||||
|
private Map<NamespaceID, Tag> cache = new HashMap<>();
|
||||||
|
|
||||||
|
public TagManager() {
|
||||||
|
gson = new GsonBuilder()
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a tag with the given name. This method attempts to read from "data/<name.domain>/tags/<tagType>/<name.path>.json" if the given name is not already present in cache
|
||||||
|
* @param name
|
||||||
|
* @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants)
|
||||||
|
* @return
|
||||||
|
* @throws FileNotFoundException if the file does not exist
|
||||||
|
*/
|
||||||
|
public Tag load(NamespaceID name, String tagType) throws FileNotFoundException {
|
||||||
|
return load(name, tagType, () -> new FileReader(new File(ResourceGatherer.DATA_FOLDER, "data/"+name.getDomain()+"/tags/"+tagType+"/"+name.getPath()+".json")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a tag with the given name. This method attempts to read from 'reader' if the given name is not already present in cache
|
||||||
|
* @param name
|
||||||
|
* @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants)
|
||||||
|
* @param reader
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Tag load(NamespaceID name, String tagType, Reader reader) throws FileNotFoundException {
|
||||||
|
return load(name, tagType, () -> reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a tag with the given name. This method reads from 'reader'. This will override the previous tag
|
||||||
|
* @param name
|
||||||
|
* @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants)
|
||||||
|
* @param readerSupplier
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Tag forceLoad(NamespaceID name, String tagType, ReaderSupplierWithFileNotFound readerSupplier) throws FileNotFoundException {
|
||||||
|
Tag prev = cache.getOrDefault(name, Tag.EMPTY);
|
||||||
|
FileNotFoundException[] ex = new FileNotFoundException[1]; // very ugly code but Java does not let its standard interfaces throw exceptions
|
||||||
|
Tag result = create(prev, tagType, readerSupplier);
|
||||||
|
cache.put(name, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a tag with the given name. This method attempts to read from 'reader' if the given name is not already present in cache
|
||||||
|
* @param name
|
||||||
|
* @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants)
|
||||||
|
* @param readerSupplier
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Tag load(NamespaceID name, String tagType, ReaderSupplierWithFileNotFound readerSupplier) throws FileNotFoundException {
|
||||||
|
Tag prev = cache.getOrDefault(name, Tag.EMPTY);
|
||||||
|
FileNotFoundException[] ex = new FileNotFoundException[1]; // very ugly code but Java does not let its standard interfaces throw exceptions
|
||||||
|
Tag result = cache.computeIfAbsent(name, _name -> {
|
||||||
|
try {
|
||||||
|
return create(prev, tagType, readerSupplier);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
ex[0] = e;
|
||||||
|
return Tag.EMPTY;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(ex[0] != null) {
|
||||||
|
throw ex[0];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Tag create(Tag prev, String tagType, ReaderSupplierWithFileNotFound reader) throws FileNotFoundException {
|
||||||
|
TagContainer container = gson.fromJson(reader.get(), TagContainer.class);
|
||||||
|
try {
|
||||||
|
return new Tag(this, tagType, prev, container);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
LOGGER.error("Failed to load tag due to error", e);
|
||||||
|
return Tag.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ReaderSupplierWithFileNotFound {
|
||||||
|
Reader get() throws FileNotFoundException;
|
||||||
|
}
|
||||||
|
}
|
@ -186,14 +186,34 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View
|
|||||||
* Get the cursor item of a viewer
|
* Get the cursor item of a viewer
|
||||||
*
|
*
|
||||||
* @param player the player to get the cursor item from
|
* @param player the player to get the cursor item from
|
||||||
* @return the player cursor item
|
* @return the player cursor item, air item if the player is not a viewer
|
||||||
* @throws IllegalStateException if {@code player} is not in the viewer list
|
|
||||||
*/
|
*/
|
||||||
public ItemStack getCursorItem(Player player) {
|
public ItemStack getCursorItem(Player player) {
|
||||||
Check.stateCondition(!isViewer(player), "You can only get the cursor item of a viewer");
|
|
||||||
return cursorPlayersItem.getOrDefault(player, ItemStack.getAirItem());
|
return cursorPlayersItem.getOrDefault(player, ItemStack.getAirItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the cursor item of a viewer,
|
||||||
|
* does nothing if {@param player} is not a viewer
|
||||||
|
*
|
||||||
|
* @param player the player to change the cursor item
|
||||||
|
* @param cursorItem the new player cursor item
|
||||||
|
*/
|
||||||
|
public void setCursorItem(Player player, ItemStack cursorItem) {
|
||||||
|
if (!isViewer(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
cursorItem = ItemStackUtils.notNull(cursorItem);
|
||||||
|
|
||||||
|
SetSlotPacket setSlotPacket = new SetSlotPacket();
|
||||||
|
setSlotPacket.windowId = -1;
|
||||||
|
setSlotPacket.slot = -1;
|
||||||
|
setSlotPacket.itemStack = cursorItem;
|
||||||
|
player.getPlayerConnection().sendPacket(setSlotPacket);
|
||||||
|
|
||||||
|
this.cursorPlayersItem.put(player, cursorItem);
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized void safeItemInsert(int slot, ItemStack itemStack) {
|
private synchronized void safeItemInsert(int slot, ItemStack itemStack) {
|
||||||
itemStack = ItemStackUtils.notNull(itemStack);
|
itemStack = ItemStackUtils.notNull(itemStack);
|
||||||
this.itemStacks[slot] = itemStack;
|
this.itemStacks[slot] = itemStack;
|
||||||
|
@ -218,7 +218,13 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
|
|||||||
* @param cursorItem the new cursor item
|
* @param cursorItem the new cursor item
|
||||||
*/
|
*/
|
||||||
public void setCursorItem(ItemStack cursorItem) {
|
public void setCursorItem(ItemStack cursorItem) {
|
||||||
this.cursorItem = ItemStackUtils.notNull(cursorItem);
|
cursorItem = ItemStackUtils.notNull(cursorItem);
|
||||||
|
this.cursorItem = cursorItem;
|
||||||
|
SetSlotPacket setSlotPacket = new SetSlotPacket();
|
||||||
|
setSlotPacket.windowId = -1;
|
||||||
|
setSlotPacket.slot = -1;
|
||||||
|
setSlotPacket.itemStack = cursorItem;
|
||||||
|
player.getPlayerConnection().sendPacket(setSlotPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -233,7 +239,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
|
|||||||
Check.argCondition(!MathUtils.isBetween(slot, 0, getSize()),
|
Check.argCondition(!MathUtils.isBetween(slot, 0, getSize()),
|
||||||
"The slot " + slot + " does not exist for player");
|
"The slot " + slot + " does not exist for player");
|
||||||
Check.notNull(itemStack, "The ItemStack cannot be null, you can set air instead");
|
Check.notNull(itemStack, "The ItemStack cannot be null, you can set air instead");
|
||||||
|
|
||||||
EntityEquipmentPacket.Slot equipmentSlot;
|
EntityEquipmentPacket.Slot equipmentSlot;
|
||||||
|
|
||||||
if (slot == player.getHeldSlot()) {
|
if (slot == player.getHeldSlot()) {
|
||||||
|
@ -532,6 +532,12 @@ public class InventoryClickProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cancel the click if the inventory has been closed by Player#closeInventory within an inventory listener
|
||||||
|
if (player.didCloseInventory()) {
|
||||||
|
clickResult.setCancel(true);
|
||||||
|
player.UNSAFE_changeDidCloseInventory(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return clickResult;
|
return clickResult;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.minestom.server.item;
|
package net.minestom.server.item;
|
||||||
|
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.data.Data;
|
import net.minestom.server.data.Data;
|
||||||
import net.minestom.server.data.DataContainer;
|
import net.minestom.server.data.DataContainer;
|
||||||
import net.minestom.server.item.attribute.ItemAttribute;
|
import net.minestom.server.item.attribute.ItemAttribute;
|
||||||
@ -24,9 +25,9 @@ public class ItemStack implements DataContainer {
|
|||||||
private byte amount;
|
private byte amount;
|
||||||
private short damage;
|
private short damage;
|
||||||
|
|
||||||
private String displayName;
|
private ColoredText displayName;
|
||||||
private boolean unbreakable;
|
private boolean unbreakable;
|
||||||
private ArrayList<String> lore;
|
private ArrayList<ColoredText> lore;
|
||||||
|
|
||||||
private Map<Enchantment, Short> enchantmentMap;
|
private Map<Enchantment, Short> enchantmentMap;
|
||||||
private Map<Enchantment, Short> storedEnchantmentMap;
|
private Map<Enchantment, Short> storedEnchantmentMap;
|
||||||
@ -103,7 +104,7 @@ public class ItemStack implements DataContainer {
|
|||||||
*/
|
*/
|
||||||
public synchronized boolean isSimilar(ItemStack itemStack) {
|
public synchronized boolean isSimilar(ItemStack itemStack) {
|
||||||
synchronized (itemStack) {
|
synchronized (itemStack) {
|
||||||
final String itemDisplayName = itemStack.getDisplayName();
|
final ColoredText itemDisplayName = itemStack.getDisplayName();
|
||||||
final boolean displayNameCheck = (displayName == null && itemDisplayName == null) ||
|
final boolean displayNameCheck = (displayName == null && itemDisplayName == null) ||
|
||||||
(displayName != null && itemDisplayName != null && displayName.equals(itemDisplayName));
|
(displayName != null && itemDisplayName != null && displayName.equals(itemDisplayName));
|
||||||
|
|
||||||
@ -179,7 +180,7 @@ public class ItemStack implements DataContainer {
|
|||||||
*
|
*
|
||||||
* @return the item display name, can be null if not present
|
* @return the item display name, can be null if not present
|
||||||
*/
|
*/
|
||||||
public String getDisplayName() {
|
public ColoredText getDisplayName() {
|
||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +189,7 @@ public class ItemStack implements DataContainer {
|
|||||||
*
|
*
|
||||||
* @param displayName the item display name
|
* @param displayName the item display name
|
||||||
*/
|
*/
|
||||||
public void setDisplayName(String displayName) {
|
public void setDisplayName(ColoredText displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +207,7 @@ public class ItemStack implements DataContainer {
|
|||||||
*
|
*
|
||||||
* @return the item lore, can be null if not present
|
* @return the item lore, can be null if not present
|
||||||
*/
|
*/
|
||||||
public ArrayList<String> getLore() {
|
public ArrayList<ColoredText> getLore() {
|
||||||
return lore;
|
return lore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +216,7 @@ public class ItemStack implements DataContainer {
|
|||||||
*
|
*
|
||||||
* @param lore the item lore, can be null to remove
|
* @param lore the item lore, can be null to remove
|
||||||
*/
|
*/
|
||||||
public void setLore(ArrayList<String> lore) {
|
public void setLore(ArrayList<ColoredText> lore) {
|
||||||
this.lore = lore;
|
this.lore = lore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
package net.minestom.server.listener;
|
package net.minestom.server.listener;
|
||||||
|
|
||||||
import net.kyori.text.TextComponent;
|
|
||||||
import net.kyori.text.event.ClickEvent;
|
|
||||||
import net.kyori.text.event.HoverEvent;
|
|
||||||
import net.kyori.text.format.TextColor;
|
|
||||||
import net.kyori.text.serializer.plain.PlainComponentSerializer;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.*;
|
||||||
import net.minestom.server.command.CommandManager;
|
import net.minestom.server.command.CommandManager;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.event.player.PlayerChatEvent;
|
import net.minestom.server.event.player.PlayerChatEvent;
|
||||||
@ -19,7 +14,7 @@ import java.util.function.Function;
|
|||||||
public class ChatMessageListener {
|
public class ChatMessageListener {
|
||||||
|
|
||||||
public static void listener(ClientChatMessagePacket packet, Player player) {
|
public static void listener(ClientChatMessagePacket packet, Player player) {
|
||||||
String message = PlainComponentSerializer.INSTANCE.serialize(Chat.fromLegacyText(packet.message));
|
String message = packet.message;
|
||||||
|
|
||||||
CommandManager commandManager = MinecraftServer.getCommandManager();
|
CommandManager commandManager = MinecraftServer.getCommandManager();
|
||||||
String cmdPrefix = commandManager.getCommandPrefix();
|
String cmdPrefix = commandManager.getCommandPrefix();
|
||||||
@ -43,9 +38,9 @@ public class ChatMessageListener {
|
|||||||
// Call the event
|
// Call the event
|
||||||
player.callCancellableEvent(PlayerChatEvent.class, playerChatEvent, () -> {
|
player.callCancellableEvent(PlayerChatEvent.class, playerChatEvent, () -> {
|
||||||
|
|
||||||
Function<PlayerChatEvent, TextComponent> formatFunction = playerChatEvent.getChatFormatFunction();
|
Function<PlayerChatEvent, RichMessage> formatFunction = playerChatEvent.getChatFormatFunction();
|
||||||
|
|
||||||
TextComponent textObject;
|
RichMessage textObject;
|
||||||
|
|
||||||
if (formatFunction != null) {
|
if (formatFunction != null) {
|
||||||
// Custom format
|
// Custom format
|
||||||
@ -63,16 +58,17 @@ public class ChatMessageListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextComponent buildDefaultChatMessage(PlayerChatEvent chatEvent) {
|
private static RichMessage buildDefaultChatMessage(PlayerChatEvent chatEvent) {
|
||||||
String username = chatEvent.getSender().getUsername();
|
String username = chatEvent.getSender().getUsername();
|
||||||
|
|
||||||
TextComponent usernameText = TextComponent.of(String.format("<%s>", username))
|
ColoredText usernameText = ColoredText.of(String.format("<%s>", username));
|
||||||
.color(TextColor.WHITE)
|
|
||||||
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Its " + username).color(TextColor.GRAY)))
|
|
||||||
.clickEvent(ClickEvent.of(ClickEvent.Action.SUGGEST_COMMAND, "/msg " + username + " "))
|
|
||||||
.append(TextComponent.of(" " + chatEvent.getMessage()));
|
|
||||||
|
|
||||||
return usernameText;
|
RichMessage richMessage = RichMessage.of(usernameText)
|
||||||
|
.setHoverEvent(ChatHoverEvent.showText(ColoredText.of(ChatColor.GRAY + "Its " + username)))
|
||||||
|
.setClickEvent(ChatClickEvent.suggestCommand("/msg " + username + " "))
|
||||||
|
.append(ColoredText.of(" " + chatEvent.getMessage()));
|
||||||
|
|
||||||
|
return richMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.minestom.server.listener;
|
package net.minestom.server.listener;
|
||||||
|
|
||||||
import net.kyori.text.TextComponent;
|
import net.minestom.server.chat.ChatColor;
|
||||||
import net.kyori.text.format.TextColor;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.network.packet.client.play.ClientKeepAlivePacket;
|
import net.minestom.server.network.packet.client.play.ClientKeepAlivePacket;
|
||||||
|
|
||||||
@ -12,9 +12,7 @@ public class KeepAliveListener {
|
|||||||
final long playerId = player.getLastKeepAlive();
|
final long playerId = player.getLastKeepAlive();
|
||||||
final boolean equals = packetId == playerId;
|
final boolean equals = packetId == playerId;
|
||||||
if (!equals) {
|
if (!equals) {
|
||||||
TextComponent textComponent = TextComponent.of("Bad Keep Alive packet")
|
player.kick(ColoredText.of(ChatColor.RED + "Bad Keep Alive packet"));
|
||||||
.color(TextColor.RED);
|
|
||||||
player.kick(textComponent);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,39 @@
|
|||||||
package net.minestom.server.listener;
|
package net.minestom.server.listener;
|
||||||
|
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.event.player.PlayerChangeHeldSlotEvent;
|
||||||
import net.minestom.server.network.packet.client.play.ClientHeldItemChangePacket;
|
import net.minestom.server.network.packet.client.play.ClientHeldItemChangePacket;
|
||||||
import net.minestom.server.utils.MathUtils;
|
import net.minestom.server.utils.MathUtils;
|
||||||
|
|
||||||
public class PlayerHeldListener {
|
public class PlayerHeldListener {
|
||||||
|
|
||||||
public static void heldListener(ClientHeldItemChangePacket packet, Player player) {
|
public static void heldListener(ClientHeldItemChangePacket packet, Player player) {
|
||||||
short slot = packet.slot;
|
if (!MathUtils.isBetween(packet.slot, 0, 8)) {
|
||||||
if (!MathUtils.isBetween(slot, 0, 8)) {
|
|
||||||
// Incorrect packet, ignore
|
// Incorrect packet, ignore
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
player.refreshHeldSlot(slot);
|
|
||||||
|
final byte slot = (byte) packet.slot;
|
||||||
|
|
||||||
|
PlayerChangeHeldSlotEvent changeHeldSlotEvent = new PlayerChangeHeldSlotEvent(player, slot);
|
||||||
|
player.callEvent(PlayerChangeHeldSlotEvent.class, changeHeldSlotEvent);
|
||||||
|
|
||||||
|
if (!changeHeldSlotEvent.isCancelled()) {
|
||||||
|
// Event hasn't been canceled, process it
|
||||||
|
|
||||||
|
final byte resultSlot = changeHeldSlotEvent.getSlot();
|
||||||
|
|
||||||
|
// If the held slot has been changed by the event, send the change to the player
|
||||||
|
if (resultSlot != slot) {
|
||||||
|
player.setHeldItemSlot(resultSlot);
|
||||||
|
} else {
|
||||||
|
// Otherwise, simply refresh the player field
|
||||||
|
player.refreshHeldSlot(resultSlot);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Event has been canceled, send the last held slot to refresh the client
|
||||||
|
player.setHeldItemSlot(player.getHeldSlot());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,10 @@ public class WindowListener {
|
|||||||
player.getPlayerConnection().sendPacket(windowConfirmationPacket);
|
player.getPlayerConnection().sendPacket(windowConfirmationPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param player the player to refresh the cursor item
|
||||||
|
* @param inventory the player open inventory, null if not any (could be player inventory)
|
||||||
|
*/
|
||||||
private static void refreshCursorItem(Player player, Inventory inventory) {
|
private static void refreshCursorItem(Player player, Inventory inventory) {
|
||||||
PlayerInventory playerInventory = player.getInventory();
|
PlayerInventory playerInventory = player.getInventory();
|
||||||
|
|
||||||
@ -100,8 +104,10 @@ public class WindowListener {
|
|||||||
cursorItem = playerInventory.getCursorItem();
|
cursorItem = playerInventory.getCursorItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setting the window id properly seems to broke +64 stack support
|
// Error occurred while retrieving the cursor item, stop here
|
||||||
//byte windowId = inventory == null ? 0 : inventory.getWindowId();
|
if (cursorItem == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SetSlotPacket setSlotPacket = new SetSlotPacket();
|
SetSlotPacket setSlotPacket = new SetSlotPacket();
|
||||||
setSlotPacket.windowId = -1;
|
setSlotPacket.windowId = -1;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package net.minestom.server.network;
|
package net.minestom.server.network;
|
||||||
|
|
||||||
import net.kyori.text.TextComponent;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.listener.manager.PacketConsumer;
|
import net.minestom.server.listener.manager.PacketConsumer;
|
||||||
import net.minestom.server.network.player.PlayerConnection;
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
@ -50,17 +50,17 @@ public final class ConnectionManager {
|
|||||||
/**
|
/**
|
||||||
* Send a message to all online players who validate the condition {@code condition}
|
* Send a message to all online players who validate the condition {@code condition}
|
||||||
*
|
*
|
||||||
* @param textComponent the message to send
|
* @param coloredText the message to send
|
||||||
* @param condition the condition to receive the message
|
* @param condition the condition to receive the message
|
||||||
*/
|
*/
|
||||||
public void broadcastMessage(TextComponent textComponent, Function<Player, Boolean> condition) {
|
public void broadcastMessage(ColoredText coloredText, Function<Player, Boolean> condition) {
|
||||||
if (condition == null) {
|
if (condition == null) {
|
||||||
getOnlinePlayers().forEach(player -> player.sendMessage(textComponent));
|
getOnlinePlayers().forEach(player -> player.sendMessage(coloredText));
|
||||||
} else {
|
} else {
|
||||||
getOnlinePlayers().forEach(player -> {
|
getOnlinePlayers().forEach(player -> {
|
||||||
boolean result = condition.apply(player);
|
boolean result = condition.apply(player);
|
||||||
if (result)
|
if (result)
|
||||||
player.sendMessage(textComponent);
|
player.sendMessage(coloredText);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,10 +68,10 @@ public final class ConnectionManager {
|
|||||||
/**
|
/**
|
||||||
* Send a message to all online players without exception
|
* Send a message to all online players without exception
|
||||||
*
|
*
|
||||||
* @param textComponent the message to send
|
* @param coloredText the message to send
|
||||||
*/
|
*/
|
||||||
public void broadcastMessage(TextComponent textComponent) {
|
public void broadcastMessage(ColoredText coloredText) {
|
||||||
broadcastMessage(textComponent, null);
|
broadcastMessage(coloredText, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package net.minestom.server.network.packet.server.play;
|
package net.minestom.server.network.packet.server.play;
|
||||||
|
|
||||||
import net.minestom.server.chat.Chat;
|
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.network.packet.PacketWriter;
|
import net.minestom.server.network.packet.PacketWriter;
|
||||||
import net.minestom.server.network.packet.server.ServerPacket;
|
import net.minestom.server.network.packet.server.ServerPacket;
|
||||||
@ -92,8 +91,8 @@ public class AdvancementsPacket implements ServerPacket {
|
|||||||
public float y;
|
public float y;
|
||||||
|
|
||||||
private void write(PacketWriter writer) {
|
private void write(PacketWriter writer) {
|
||||||
writer.writeSizedString(Chat.toJsonString(Chat.fromLegacyText(title)));
|
writer.writeSizedString(title);
|
||||||
writer.writeSizedString(Chat.toJsonString(Chat.fromLegacyText(title)));
|
writer.writeSizedString(description);
|
||||||
writer.writeItemStack(icon);
|
writer.writeItemStack(icon);
|
||||||
writer.writeVarInt(frameType.ordinal());
|
writer.writeVarInt(frameType.ordinal());
|
||||||
writer.writeInt(flags);
|
writer.writeInt(flags);
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package net.minestom.server.network.packet.server.play;
|
package net.minestom.server.network.packet.server.play;
|
||||||
|
|
||||||
import net.kyori.text.Component;
|
|
||||||
import net.minestom.server.bossbar.BarColor;
|
import net.minestom.server.bossbar.BarColor;
|
||||||
import net.minestom.server.bossbar.BarDivision;
|
import net.minestom.server.bossbar.BarDivision;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.network.packet.PacketWriter;
|
import net.minestom.server.network.packet.PacketWriter;
|
||||||
import net.minestom.server.network.packet.server.ServerPacket;
|
import net.minestom.server.network.packet.server.ServerPacket;
|
||||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||||
@ -15,7 +14,7 @@ public class BossBarPacket implements ServerPacket {
|
|||||||
public UUID uuid;
|
public UUID uuid;
|
||||||
public Action action;
|
public Action action;
|
||||||
|
|
||||||
public Component title;
|
public ColoredText title;
|
||||||
public float health;
|
public float health;
|
||||||
public BarColor color;
|
public BarColor color;
|
||||||
public BarDivision division;
|
public BarDivision division;
|
||||||
@ -29,7 +28,7 @@ public class BossBarPacket implements ServerPacket {
|
|||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ADD:
|
case ADD:
|
||||||
writer.writeSizedString(Chat.toJsonString(title));
|
writer.writeSizedString(title.toString());
|
||||||
writer.writeFloat(health);
|
writer.writeFloat(health);
|
||||||
writer.writeVarInt(color.ordinal());
|
writer.writeVarInt(color.ordinal());
|
||||||
writer.writeVarInt(division.ordinal());
|
writer.writeVarInt(division.ordinal());
|
||||||
@ -42,7 +41,7 @@ public class BossBarPacket implements ServerPacket {
|
|||||||
writer.writeFloat(health);
|
writer.writeFloat(health);
|
||||||
break;
|
break;
|
||||||
case UPDATE_TITLE:
|
case UPDATE_TITLE:
|
||||||
writer.writeSizedString(Chat.toJsonString(title));
|
writer.writeSizedString(title.toString());
|
||||||
break;
|
break;
|
||||||
case UPDATE_STYLE:
|
case UPDATE_STYLE:
|
||||||
writer.writeVarInt(color.ordinal());
|
writer.writeVarInt(color.ordinal());
|
||||||
|
@ -26,7 +26,6 @@ public class ChatMessagePacket implements ServerPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum Position {
|
public enum Position {
|
||||||
|
|
||||||
CHAT,
|
CHAT,
|
||||||
SYSTEM_MESSAGE,
|
SYSTEM_MESSAGE,
|
||||||
GAME_INFO
|
GAME_INFO
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.minestom.server.network.packet.server.play;
|
package net.minestom.server.network.packet.server.play;
|
||||||
|
|
||||||
import net.kyori.text.Component;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.chat.Chat;
|
|
||||||
import net.minestom.server.entity.Entity;
|
import net.minestom.server.entity.Entity;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.network.packet.PacketWriter;
|
import net.minestom.server.network.packet.PacketWriter;
|
||||||
@ -20,7 +19,7 @@ public class CombatEventPacket implements ServerPacket {
|
|||||||
private int duration;
|
private int duration;
|
||||||
private int opponent;
|
private int opponent;
|
||||||
private int playerID;
|
private int playerID;
|
||||||
private Component deathMessage;
|
private ColoredText deathMessage;
|
||||||
|
|
||||||
private CombatEventPacket() {
|
private CombatEventPacket() {
|
||||||
}
|
}
|
||||||
@ -39,7 +38,7 @@ public class CombatEventPacket implements ServerPacket {
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CombatEventPacket death(Player player, Optional<Entity> killer, Component message) {
|
public static CombatEventPacket death(Player player, Optional<Entity> killer, ColoredText message) {
|
||||||
CombatEventPacket packet = new CombatEventPacket();
|
CombatEventPacket packet = new CombatEventPacket();
|
||||||
packet.type = EventType.DEATH;
|
packet.type = EventType.DEATH;
|
||||||
packet.playerID = player.getEntityId();
|
packet.playerID = player.getEntityId();
|
||||||
@ -64,7 +63,7 @@ public class CombatEventPacket implements ServerPacket {
|
|||||||
case DEATH:
|
case DEATH:
|
||||||
writer.writeVarInt(playerID);
|
writer.writeVarInt(playerID);
|
||||||
writer.writeInt(opponent);
|
writer.writeInt(opponent);
|
||||||
writer.writeSizedString(Chat.toJsonString(deathMessage));
|
writer.writeSizedString(deathMessage.toString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,11 @@ import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
|||||||
|
|
||||||
public class HeldItemChangePacket implements ServerPacket {
|
public class HeldItemChangePacket implements ServerPacket {
|
||||||
|
|
||||||
public short slot;
|
public byte slot;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(PacketWriter writer) {
|
public void write(PacketWriter writer) {
|
||||||
writer.writeShort(slot);
|
writer.writeByte(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.minestom.server.network.packet.server.play;
|
package net.minestom.server.network.packet.server.play;
|
||||||
|
|
||||||
import net.kyori.text.Component;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.chat.Chat;
|
|
||||||
import net.minestom.server.network.packet.PacketWriter;
|
import net.minestom.server.network.packet.PacketWriter;
|
||||||
import net.minestom.server.network.packet.server.ServerPacket;
|
import net.minestom.server.network.packet.server.ServerPacket;
|
||||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||||
@ -10,7 +9,7 @@ public class ScoreboardObjectivePacket implements ServerPacket {
|
|||||||
|
|
||||||
public String objectiveName;
|
public String objectiveName;
|
||||||
public byte mode;
|
public byte mode;
|
||||||
public Component objectiveValue;
|
public ColoredText objectiveValue;
|
||||||
public int type;
|
public int type;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -19,7 +18,7 @@ public class ScoreboardObjectivePacket implements ServerPacket {
|
|||||||
writer.writeByte(mode);
|
writer.writeByte(mode);
|
||||||
|
|
||||||
if (mode == 0 || mode == 2) {
|
if (mode == 0 || mode == 2) {
|
||||||
writer.writeSizedString(Chat.toJsonString(objectiveValue));
|
writer.writeSizedString(objectiveValue.toString());
|
||||||
writer.writeVarInt(type);
|
writer.writeVarInt(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package net.minestom.server.network.packet.server.play;
|
package net.minestom.server.network.packet.server.play;
|
||||||
|
|
||||||
import net.kyori.text.Component;
|
|
||||||
import net.minestom.server.chat.Chat;
|
|
||||||
import net.minestom.server.network.packet.PacketWriter;
|
import net.minestom.server.network.packet.PacketWriter;
|
||||||
import net.minestom.server.network.packet.server.ServerPacket;
|
import net.minestom.server.network.packet.server.ServerPacket;
|
||||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||||
@ -11,13 +9,13 @@ public class TeamsPacket implements ServerPacket {
|
|||||||
public String teamName;
|
public String teamName;
|
||||||
public Action action;
|
public Action action;
|
||||||
|
|
||||||
public Component teamDisplayName;
|
public String teamDisplayName;
|
||||||
public byte friendlyFlags;
|
public byte friendlyFlags;
|
||||||
public NameTagVisibility nameTagVisibility;
|
public NameTagVisibility nameTagVisibility;
|
||||||
public CollisionRule collisionRule;
|
public CollisionRule collisionRule;
|
||||||
public int teamColor;
|
public int teamColor;
|
||||||
public Component teamPrefix;
|
public String teamPrefix;
|
||||||
public Component teamSuffix;
|
public String teamSuffix;
|
||||||
public String[] entities;
|
public String[] entities;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -28,13 +26,13 @@ public class TeamsPacket implements ServerPacket {
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
case CREATE_TEAM:
|
case CREATE_TEAM:
|
||||||
case UPDATE_TEAM_INFO:
|
case UPDATE_TEAM_INFO:
|
||||||
writer.writeSizedString(Chat.toJsonString(teamDisplayName));
|
writer.writeSizedString(teamDisplayName);
|
||||||
writer.writeByte(friendlyFlags);
|
writer.writeByte(friendlyFlags);
|
||||||
writer.writeSizedString(nameTagVisibility.getIdentifier());
|
writer.writeSizedString(nameTagVisibility.getIdentifier());
|
||||||
writer.writeSizedString(collisionRule.getIdentifier());
|
writer.writeSizedString(collisionRule.getIdentifier());
|
||||||
writer.writeVarInt(teamColor);
|
writer.writeVarInt(teamColor);
|
||||||
writer.writeSizedString(Chat.toJsonString(teamPrefix));
|
writer.writeSizedString(teamPrefix);
|
||||||
writer.writeSizedString(Chat.toJsonString(teamSuffix));
|
writer.writeSizedString(teamSuffix);
|
||||||
break;
|
break;
|
||||||
case REMOVE_TEAM:
|
case REMOVE_TEAM:
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.minestom.server.scoreboard;
|
package net.minestom.server.scoreboard;
|
||||||
|
|
||||||
import net.minestom.server.Viewable;
|
import net.minestom.server.Viewable;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.network.packet.server.play.DisplayScoreboardPacket;
|
import net.minestom.server.network.packet.server.play.DisplayScoreboardPacket;
|
||||||
import net.minestom.server.network.packet.server.play.ScoreboardObjectivePacket;
|
import net.minestom.server.network.packet.server.play.ScoreboardObjectivePacket;
|
||||||
@ -35,7 +35,7 @@ public class BelowNameScoreboard implements Viewable {
|
|||||||
scoreboardObjectivePacket = new ScoreboardObjectivePacket();
|
scoreboardObjectivePacket = new ScoreboardObjectivePacket();
|
||||||
scoreboardObjectivePacket.objectiveName = objectiveName;
|
scoreboardObjectivePacket.objectiveName = objectiveName;
|
||||||
scoreboardObjectivePacket.mode = 0;
|
scoreboardObjectivePacket.mode = 0;
|
||||||
scoreboardObjectivePacket.objectiveValue = Chat.fromLegacyText(objectiveName);
|
scoreboardObjectivePacket.objectiveValue = ColoredText.of(objectiveName);
|
||||||
scoreboardObjectivePacket.type = 0;
|
scoreboardObjectivePacket.type = 0;
|
||||||
|
|
||||||
displayScoreboardPacket = new DisplayScoreboardPacket();
|
displayScoreboardPacket = new DisplayScoreboardPacket();
|
||||||
|
@ -2,6 +2,7 @@ package net.minestom.server.scoreboard;
|
|||||||
|
|
||||||
import net.minestom.server.Viewable;
|
import net.minestom.server.Viewable;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.Chat;
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.network.packet.server.play.DisplayScoreboardPacket;
|
import net.minestom.server.network.packet.server.play.DisplayScoreboardPacket;
|
||||||
import net.minestom.server.network.packet.server.play.ScoreboardObjectivePacket;
|
import net.minestom.server.network.packet.server.play.ScoreboardObjectivePacket;
|
||||||
@ -53,7 +54,7 @@ public class Sidebar implements Viewable {
|
|||||||
ScoreboardObjectivePacket scoreboardObjectivePacket = new ScoreboardObjectivePacket();
|
ScoreboardObjectivePacket scoreboardObjectivePacket = new ScoreboardObjectivePacket();
|
||||||
scoreboardObjectivePacket.objectiveName = objectiveName;
|
scoreboardObjectivePacket.objectiveName = objectiveName;
|
||||||
scoreboardObjectivePacket.mode = 2; // Update display text
|
scoreboardObjectivePacket.mode = 2; // Update display text
|
||||||
scoreboardObjectivePacket.objectiveValue = Chat.fromLegacyText(title);
|
scoreboardObjectivePacket.objectiveValue = ColoredText.of(title);
|
||||||
scoreboardObjectivePacket.type = 0;
|
scoreboardObjectivePacket.type = 0;
|
||||||
|
|
||||||
sendPacketToViewers(scoreboardObjectivePacket);
|
sendPacketToViewers(scoreboardObjectivePacket);
|
||||||
@ -82,7 +83,7 @@ public class Sidebar implements Viewable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLineContent(String id, String content) {
|
public void updateLineContent(String id, ColoredText content) {
|
||||||
ScoreboardLine scoreboardLine = getLine(id);
|
ScoreboardLine scoreboardLine = getLine(id);
|
||||||
if (scoreboardLine != null) {
|
if (scoreboardLine != null) {
|
||||||
scoreboardLine.refreshContent(content);
|
scoreboardLine.refreshContent(content);
|
||||||
@ -131,7 +132,7 @@ public class Sidebar implements Viewable {
|
|||||||
ScoreboardObjectivePacket scoreboardObjectivePacket = new ScoreboardObjectivePacket();
|
ScoreboardObjectivePacket scoreboardObjectivePacket = new ScoreboardObjectivePacket();
|
||||||
scoreboardObjectivePacket.objectiveName = objectiveName;
|
scoreboardObjectivePacket.objectiveName = objectiveName;
|
||||||
scoreboardObjectivePacket.mode = 0; // Create scoreboard
|
scoreboardObjectivePacket.mode = 0; // Create scoreboard
|
||||||
scoreboardObjectivePacket.objectiveValue = Chat.fromLegacyText(title);
|
scoreboardObjectivePacket.objectiveValue = ColoredText.of(title);
|
||||||
scoreboardObjectivePacket.type = 0; // Type integer
|
scoreboardObjectivePacket.type = 0; // Type integer
|
||||||
|
|
||||||
DisplayScoreboardPacket displayScoreboardPacket = new DisplayScoreboardPacket();
|
DisplayScoreboardPacket displayScoreboardPacket = new DisplayScoreboardPacket();
|
||||||
@ -172,7 +173,7 @@ public class Sidebar implements Viewable {
|
|||||||
public static class ScoreboardLine {
|
public static class ScoreboardLine {
|
||||||
|
|
||||||
private String id; // ID used to modify the line later
|
private String id; // ID used to modify the line later
|
||||||
private String content;
|
private ColoredText content;
|
||||||
private int line;
|
private int line;
|
||||||
|
|
||||||
private String teamName;
|
private String teamName;
|
||||||
@ -180,7 +181,7 @@ public class Sidebar implements Viewable {
|
|||||||
private String entityName;
|
private String entityName;
|
||||||
private SidebarTeam sidebarTeam;
|
private SidebarTeam sidebarTeam;
|
||||||
|
|
||||||
public ScoreboardLine(String id, String content, int line) {
|
public ScoreboardLine(String id, ColoredText content, int line) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
this.line = line;
|
this.line = line;
|
||||||
@ -192,7 +193,7 @@ public class Sidebar implements Viewable {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContent() {
|
public ColoredText getContent() {
|
||||||
return sidebarTeam == null ? content : sidebarTeam.getPrefix();
|
return sidebarTeam == null ? content : sidebarTeam.getPrefix();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +210,7 @@ public class Sidebar implements Viewable {
|
|||||||
private void createTeam() {
|
private void createTeam() {
|
||||||
this.entityName = Chat.COLOR_CHAR + Integer.toHexString(colorName);
|
this.entityName = Chat.COLOR_CHAR + Integer.toHexString(colorName);
|
||||||
|
|
||||||
this.sidebarTeam = new SidebarTeam(teamName, content, "", entityName);
|
this.sidebarTeam = new SidebarTeam(teamName, content, ColoredText.of(""), entityName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void returnName(LinkedList<Integer> colors) {
|
private void returnName(LinkedList<Integer> colors) {
|
||||||
@ -241,7 +242,7 @@ public class Sidebar implements Viewable {
|
|||||||
return updateScorePacket;
|
return updateScorePacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshContent(String content) {
|
private void refreshContent(ColoredText content) {
|
||||||
this.sidebarTeam.refreshPrefix(content);
|
this.sidebarTeam.refreshPrefix(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
package net.minestom.server.scoreboard;
|
package net.minestom.server.scoreboard;
|
||||||
|
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.network.packet.server.play.TeamsPacket;
|
import net.minestom.server.network.packet.server.play.TeamsPacket;
|
||||||
|
|
||||||
public class SidebarTeam {
|
public class SidebarTeam {
|
||||||
|
|
||||||
private String teamName;
|
private String teamName;
|
||||||
private String prefix, suffix;
|
private ColoredText prefix, suffix;
|
||||||
private String entityName;
|
private String entityName;
|
||||||
|
|
||||||
private String teamDisplayName = "displaynametest";
|
private ColoredText teamDisplayName = ColoredText.of("displaynametest");
|
||||||
private byte friendlyFlags = 0x00;
|
private byte friendlyFlags = 0x00;
|
||||||
private TeamsPacket.NameTagVisibility nameTagVisibility = TeamsPacket.NameTagVisibility.NEVER;
|
private TeamsPacket.NameTagVisibility nameTagVisibility = TeamsPacket.NameTagVisibility.NEVER;
|
||||||
private TeamsPacket.CollisionRule collisionRule = TeamsPacket.CollisionRule.NEVER;
|
private TeamsPacket.CollisionRule collisionRule = TeamsPacket.CollisionRule.NEVER;
|
||||||
private int teamColor = 2;
|
private int teamColor = 2;
|
||||||
|
|
||||||
|
|
||||||
protected SidebarTeam(String teamName, String prefix, String suffix, String entityName) {
|
protected SidebarTeam(String teamName, ColoredText prefix, ColoredText suffix, String entityName) {
|
||||||
this.teamName = teamName;
|
this.teamName = teamName;
|
||||||
this.prefix = prefix;
|
this.prefix = prefix;
|
||||||
this.suffix = suffix;
|
this.suffix = suffix;
|
||||||
@ -27,13 +27,13 @@ public class SidebarTeam {
|
|||||||
TeamsPacket teamsPacket = new TeamsPacket();
|
TeamsPacket teamsPacket = new TeamsPacket();
|
||||||
teamsPacket.teamName = teamName;
|
teamsPacket.teamName = teamName;
|
||||||
teamsPacket.action = TeamsPacket.Action.CREATE_TEAM;
|
teamsPacket.action = TeamsPacket.Action.CREATE_TEAM;
|
||||||
teamsPacket.teamDisplayName = Chat.fromLegacyText(teamDisplayName);
|
teamsPacket.teamDisplayName = teamDisplayName.toString();
|
||||||
teamsPacket.friendlyFlags = friendlyFlags;
|
teamsPacket.friendlyFlags = friendlyFlags;
|
||||||
teamsPacket.nameTagVisibility = nameTagVisibility;
|
teamsPacket.nameTagVisibility = nameTagVisibility;
|
||||||
teamsPacket.collisionRule = collisionRule;
|
teamsPacket.collisionRule = collisionRule;
|
||||||
teamsPacket.teamColor = teamColor;
|
teamsPacket.teamColor = teamColor;
|
||||||
teamsPacket.teamPrefix = Chat.fromLegacyText(prefix);
|
teamsPacket.teamPrefix = prefix.toString();
|
||||||
teamsPacket.teamSuffix = Chat.fromLegacyText(suffix);
|
teamsPacket.teamSuffix = suffix.toString();
|
||||||
teamsPacket.entities = new String[]{entityName};
|
teamsPacket.entities = new String[]{entityName};
|
||||||
return teamsPacket;
|
return teamsPacket;
|
||||||
}
|
}
|
||||||
@ -45,17 +45,17 @@ public class SidebarTeam {
|
|||||||
return teamsPacket;
|
return teamsPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TeamsPacket updatePrefix(String prefix) {
|
protected TeamsPacket updatePrefix(ColoredText prefix) {
|
||||||
TeamsPacket teamsPacket = new TeamsPacket();
|
TeamsPacket teamsPacket = new TeamsPacket();
|
||||||
teamsPacket.teamName = teamName;
|
teamsPacket.teamName = teamName;
|
||||||
teamsPacket.action = TeamsPacket.Action.UPDATE_TEAM_INFO;
|
teamsPacket.action = TeamsPacket.Action.UPDATE_TEAM_INFO;
|
||||||
teamsPacket.teamDisplayName = Chat.fromLegacyText(teamDisplayName);
|
teamsPacket.teamDisplayName = teamDisplayName.toString();
|
||||||
teamsPacket.friendlyFlags = friendlyFlags;
|
teamsPacket.friendlyFlags = friendlyFlags;
|
||||||
teamsPacket.nameTagVisibility = nameTagVisibility;
|
teamsPacket.nameTagVisibility = nameTagVisibility;
|
||||||
teamsPacket.collisionRule = collisionRule;
|
teamsPacket.collisionRule = collisionRule;
|
||||||
teamsPacket.teamColor = teamColor;
|
teamsPacket.teamColor = teamColor;
|
||||||
teamsPacket.teamPrefix = Chat.fromLegacyText(prefix);
|
teamsPacket.teamPrefix = prefix.toString();
|
||||||
teamsPacket.teamSuffix = Chat.fromLegacyText(suffix);
|
teamsPacket.teamSuffix = suffix.toString();
|
||||||
return teamsPacket;
|
return teamsPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,11 +63,11 @@ public class SidebarTeam {
|
|||||||
return entityName;
|
return entityName;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getPrefix() {
|
protected ColoredText getPrefix() {
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void refreshPrefix(String prefix) {
|
protected void refreshPrefix(ColoredText prefix) {
|
||||||
this.prefix = prefix;
|
this.prefix = prefix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package net.minestom.server.scoreboard;
|
package net.minestom.server.scoreboard;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.kyori.text.format.TextColor;
|
import net.minestom.server.chat.ChatColor;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
||||||
import net.minestom.server.network.packet.server.play.TeamsPacket;
|
import net.minestom.server.network.packet.server.play.TeamsPacket;
|
||||||
import net.minestom.server.utils.PacketUtils;
|
import net.minestom.server.utils.PacketUtils;
|
||||||
@ -14,12 +14,15 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
public class Team {
|
public class Team {
|
||||||
|
|
||||||
private String teamName;
|
private String teamName;
|
||||||
private String teamDisplayName = "";
|
private ColoredText teamDisplayName = ColoredText.of("");
|
||||||
private byte friendlyFlags = 0x00;
|
private byte friendlyFlags = 0x00;
|
||||||
private TeamsPacket.NameTagVisibility nameTagVisibility = TeamsPacket.NameTagVisibility.ALWAYS;
|
private TeamsPacket.NameTagVisibility nameTagVisibility = TeamsPacket.NameTagVisibility.ALWAYS;
|
||||||
private TeamsPacket.CollisionRule collisionRule = TeamsPacket.CollisionRule.NEVER;
|
private TeamsPacket.CollisionRule collisionRule = TeamsPacket.CollisionRule.NEVER;
|
||||||
private TextColor teamColor = TextColor.WHITE;
|
private ChatColor teamColor = ChatColor.WHITE;
|
||||||
private String prefix = "", suffix = "";
|
|
||||||
|
private ColoredText prefix = ColoredText.of("");
|
||||||
|
private ColoredText suffix = ColoredText.of("");
|
||||||
|
|
||||||
private String[] entities = new String[0];
|
private String[] entities = new String[0];
|
||||||
private Set<Player> players = new CopyOnWriteArraySet<>();
|
private Set<Player> players = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
@ -33,13 +36,13 @@ public class Team {
|
|||||||
teamsCreationPacket = new TeamsPacket();
|
teamsCreationPacket = new TeamsPacket();
|
||||||
teamsCreationPacket.teamName = teamName;
|
teamsCreationPacket.teamName = teamName;
|
||||||
teamsCreationPacket.action = TeamsPacket.Action.CREATE_TEAM;
|
teamsCreationPacket.action = TeamsPacket.Action.CREATE_TEAM;
|
||||||
teamsCreationPacket.teamDisplayName = Chat.fromLegacyText(teamDisplayName);
|
teamsCreationPacket.teamDisplayName = teamDisplayName.toString();
|
||||||
teamsCreationPacket.friendlyFlags = friendlyFlags;
|
teamsCreationPacket.friendlyFlags = friendlyFlags;
|
||||||
teamsCreationPacket.nameTagVisibility = nameTagVisibility;
|
teamsCreationPacket.nameTagVisibility = nameTagVisibility;
|
||||||
teamsCreationPacket.collisionRule = collisionRule;
|
teamsCreationPacket.collisionRule = collisionRule;
|
||||||
teamsCreationPacket.teamColor = teamColor.ordinal();
|
teamsCreationPacket.teamColor = teamColor.getId();
|
||||||
teamsCreationPacket.teamPrefix = Chat.fromLegacyText(prefix);
|
teamsCreationPacket.teamPrefix = prefix.toString();
|
||||||
teamsCreationPacket.teamSuffix = Chat.fromLegacyText(suffix);
|
teamsCreationPacket.teamSuffix = suffix.toString();
|
||||||
teamsCreationPacket.entities = entities;
|
teamsCreationPacket.entities = entities;
|
||||||
|
|
||||||
TeamsPacket destroyPacket = new TeamsPacket();
|
TeamsPacket destroyPacket = new TeamsPacket();
|
||||||
@ -90,9 +93,9 @@ public class Team {
|
|||||||
this.teamsCreationPacket.entities = entities;
|
this.teamsCreationPacket.entities = entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTeamDisplayName(String teamDisplayName) {
|
public void setTeamDisplayName(ColoredText teamDisplayName) {
|
||||||
this.teamDisplayName = teamDisplayName;
|
this.teamDisplayName = teamDisplayName;
|
||||||
this.teamsCreationPacket.teamDisplayName = Chat.fromLegacyText(teamDisplayName);
|
this.teamsCreationPacket.teamDisplayName = teamDisplayName.toString();
|
||||||
sendUpdatePacket();
|
sendUpdatePacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,21 +111,21 @@ public class Team {
|
|||||||
sendUpdatePacket();
|
sendUpdatePacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTeamColor(TextColor teamColor) {
|
public void setTeamColor(ChatColor teamColor) {
|
||||||
this.teamColor = teamColor;
|
this.teamColor = teamColor;
|
||||||
this.teamsCreationPacket.teamColor = teamColor.ordinal();
|
this.teamsCreationPacket.teamColor = teamColor.getId();
|
||||||
sendUpdatePacket();
|
sendUpdatePacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPrefix(String prefix) {
|
public void setPrefix(ColoredText prefix) {
|
||||||
this.prefix = prefix;
|
this.prefix = prefix;
|
||||||
this.teamsCreationPacket.teamPrefix = Chat.fromLegacyText(prefix);
|
this.teamsCreationPacket.teamPrefix = prefix.toString();
|
||||||
sendUpdatePacket();
|
sendUpdatePacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSuffix(String suffix) {
|
public void setSuffix(ColoredText suffix) {
|
||||||
this.suffix = suffix;
|
this.suffix = suffix;
|
||||||
this.teamsCreationPacket.teamSuffix = Chat.fromLegacyText(suffix);
|
this.teamsCreationPacket.teamSuffix = suffix.toString();
|
||||||
sendUpdatePacket();
|
sendUpdatePacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,13 +152,13 @@ public class Team {
|
|||||||
TeamsPacket updatePacket = new TeamsPacket();
|
TeamsPacket updatePacket = new TeamsPacket();
|
||||||
updatePacket.teamName = teamName;
|
updatePacket.teamName = teamName;
|
||||||
updatePacket.action = TeamsPacket.Action.UPDATE_TEAM_INFO;
|
updatePacket.action = TeamsPacket.Action.UPDATE_TEAM_INFO;
|
||||||
updatePacket.teamDisplayName = Chat.fromLegacyText(teamDisplayName);
|
updatePacket.teamDisplayName = teamDisplayName.toString();
|
||||||
updatePacket.friendlyFlags = friendlyFlags;
|
updatePacket.friendlyFlags = friendlyFlags;
|
||||||
updatePacket.nameTagVisibility = nameTagVisibility;
|
updatePacket.nameTagVisibility = nameTagVisibility;
|
||||||
updatePacket.collisionRule = collisionRule;
|
updatePacket.collisionRule = collisionRule;
|
||||||
updatePacket.teamColor = teamColor.ordinal();
|
updatePacket.teamColor = teamColor.getId();
|
||||||
updatePacket.teamPrefix = Chat.fromLegacyText(prefix);
|
updatePacket.teamPrefix = prefix.toString();
|
||||||
updatePacket.teamSuffix = Chat.fromLegacyText(suffix);
|
updatePacket.teamSuffix = suffix.toString();
|
||||||
ByteBuf buffer = PacketUtils.writePacket(updatePacket);
|
ByteBuf buffer = PacketUtils.writePacket(updatePacket);
|
||||||
players.forEach(p -> p.getPlayerConnection().sendPacket(buffer));
|
players.forEach(p -> p.getPlayerConnection().sendPacket(buffer));
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.minestom.server.utils;
|
package net.minestom.server.utils;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.instance.Chunk;
|
import net.minestom.server.instance.Chunk;
|
||||||
import net.minestom.server.item.Enchantment;
|
import net.minestom.server.item.Enchantment;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
@ -127,17 +127,16 @@ public class Utils {
|
|||||||
if (hasDisplayName || hasLore) {
|
if (hasDisplayName || hasLore) {
|
||||||
writer.writeCompound("display", displayWriter -> {
|
writer.writeCompound("display", displayWriter -> {
|
||||||
if (hasDisplayName) {
|
if (hasDisplayName) {
|
||||||
final String name = Chat.toJsonString(Chat.fromLegacyText(itemStack.getDisplayName()));
|
final String name = itemStack.getDisplayName().toString();
|
||||||
displayWriter.writeString("Name", name);
|
displayWriter.writeString("Name", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasLore) {
|
if (hasLore) {
|
||||||
final ArrayList<String> lore = itemStack.getLore();
|
final ArrayList<ColoredText> lore = itemStack.getLore();
|
||||||
|
|
||||||
displayWriter.writeList("Lore", NBT.NBT_STRING, lore.size(), () -> {
|
displayWriter.writeList("Lore", NBT.NBT_STRING, lore.size(), () -> {
|
||||||
for (String line : lore) {
|
for (ColoredText line : lore) {
|
||||||
line = Chat.toJsonString(Chat.fromLegacyText(line));
|
packet.writeShortSizedString(line.toString());
|
||||||
packet.writeShortSizedString(line);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@ import net.minestom.server.item.ItemStack;
|
|||||||
public class ItemStackUtils {
|
public class ItemStackUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Ensure that the returned ItemStack won't be null
|
||||||
|
* by replacing every null instance by a new Air one
|
||||||
|
*
|
||||||
* @param itemStack the ItemStack to return if not null
|
* @param itemStack the ItemStack to return if not null
|
||||||
* @return {@code itemStack} if not null, {@link ItemStack#getAirItem()} otherwise
|
* @return {@code itemStack} if not null, {@link ItemStack#getAirItem()} otherwise
|
||||||
*/
|
*/
|
||||||
|
@ -4,6 +4,7 @@ import net.kyori.text.Component;
|
|||||||
import net.minestom.server.attribute.Attribute;
|
import net.minestom.server.attribute.Attribute;
|
||||||
import net.minestom.server.attribute.AttributeOperation;
|
import net.minestom.server.attribute.AttributeOperation;
|
||||||
import net.minestom.server.chat.Chat;
|
import net.minestom.server.chat.Chat;
|
||||||
|
import net.minestom.server.chat.ColoredText;
|
||||||
import net.minestom.server.item.Enchantment;
|
import net.minestom.server.item.Enchantment;
|
||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.item.attribute.AttributeSlot;
|
import net.minestom.server.item.attribute.AttributeSlot;
|
||||||
@ -213,7 +214,7 @@ public class NbtReaderUtils {
|
|||||||
Component textObject = Chat.fromJsonString(jsonDisplayName);
|
Component textObject = Chat.fromJsonString(jsonDisplayName);
|
||||||
String displayName = Chat.toLegacyText(textObject);
|
String displayName = Chat.toLegacyText(textObject);
|
||||||
|
|
||||||
item.setDisplayName(displayName);
|
item.setDisplayName(ColoredText.of(displayName));
|
||||||
readItemStackDisplayNBT(reader, item);
|
readItemStackDisplayNBT(reader, item);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -225,13 +226,13 @@ public class NbtReaderUtils {
|
|||||||
reader.readByte(); // lore type, should always be 0x08 (TAG_String)
|
reader.readByte(); // lore type, should always be 0x08 (TAG_String)
|
||||||
|
|
||||||
int size = reader.readInteger();
|
int size = reader.readInteger();
|
||||||
ArrayList<String> lore = new ArrayList<>(size);
|
ArrayList<ColoredText> lore = new ArrayList<>(size);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
String string = reader.readShortSizedString();
|
String string = reader.readShortSizedString();
|
||||||
Component textObject = Chat.fromJsonString(string);
|
Component textObject = Chat.fromJsonString(string);
|
||||||
String line = Chat.toLegacyText(textObject);
|
String line = Chat.toLegacyText(textObject);
|
||||||
|
|
||||||
lore.add(line);
|
lore.add(ColoredText.of(line));
|
||||||
if (lore.size() == size) {
|
if (lore.size() == size) {
|
||||||
item.setLore(lore);
|
item.setLore(lore);
|
||||||
}
|
}
|
||||||
|
104
src/test/java/tags/TestTags.java
Normal file
104
src/test/java/tags/TestTags.java
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package tags;
|
||||||
|
|
||||||
|
import net.minestom.server.gamedata.tags.Tag;
|
||||||
|
import net.minestom.server.gamedata.tags.TagManager;
|
||||||
|
import net.minestom.server.utils.NamespaceID;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
public class TestTags {
|
||||||
|
|
||||||
|
private TagManager tags;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
tags = new TagManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSubTag() throws FileNotFoundException {
|
||||||
|
String tag1 = "{\n" +
|
||||||
|
"\t\"replace\": false,\n" +
|
||||||
|
"\t\"values\": [\n" +
|
||||||
|
"\t\t\"minestom:an_item\"\n" +
|
||||||
|
"\t]\n" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
String tag2 = "{\n" +
|
||||||
|
"\t\"replace\": false,\n" +
|
||||||
|
"\t\"values\": [\n" +
|
||||||
|
"\t\t\"#minestom:test_sub\",\n" +
|
||||||
|
"\t\t\"minestom:some_other_item\"\n" +
|
||||||
|
"\t]\n" +
|
||||||
|
"}";
|
||||||
|
Assert.assertNotEquals(Tag.EMPTY, tags.load(NamespaceID.from("minestom:test_sub"), "any", new StringReader(tag1)));
|
||||||
|
Tag loaded = tags.load(NamespaceID.from("minestom:test"), "any", new StringReader(tag2));
|
||||||
|
NamespaceID[] values = loaded.getValues().toArray(new NamespaceID[0]);
|
||||||
|
Assert.assertEquals(2, values.length);
|
||||||
|
Assert.assertTrue(loaded.contains(NamespaceID.from("minestom:an_item")));
|
||||||
|
Assert.assertTrue(loaded.contains(NamespaceID.from("minestom:some_other_item")));
|
||||||
|
Assert.assertFalse(loaded.contains(NamespaceID.from("minestom:some_other_item_that_is_not_in_the_tag")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A value of 'true' in 'replace' should replace previous contents
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testReplacement() throws FileNotFoundException {
|
||||||
|
String tag1 = "{\n" +
|
||||||
|
"\t\"replace\": false,\n" +
|
||||||
|
"\t\"values\": [\n" +
|
||||||
|
"\t\t\"minestom:an_item\"\n" +
|
||||||
|
"\t]\n" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
String tag2 = "{\n" +
|
||||||
|
"\t\"replace\": true,\n" +
|
||||||
|
"\t\"values\": [\n" +
|
||||||
|
"\t\t\"minestom:some_other_item\"\n" +
|
||||||
|
"\t]\n" +
|
||||||
|
"}";
|
||||||
|
Assert.assertNotEquals(Tag.EMPTY, tags.load(NamespaceID.from("minestom:test"), "any", new StringReader(tag1)));
|
||||||
|
Tag loaded = tags.forceLoad(NamespaceID.from("minestom:test"), "any", () -> new StringReader(tag2));
|
||||||
|
Assert.assertNotEquals(Tag.EMPTY, loaded);
|
||||||
|
Assert.assertEquals(1, loaded.getValues().size());
|
||||||
|
Assert.assertTrue(loaded.contains(NamespaceID.from("minestom:some_other_item")));
|
||||||
|
Assert.assertFalse(loaded.contains(NamespaceID.from("minestom:an_item")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A value of 'false' in 'replace' should append to previous contents
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAppend() throws FileNotFoundException {
|
||||||
|
String tag1 = "{\n" +
|
||||||
|
"\t\"replace\": false,\n" +
|
||||||
|
"\t\"values\": [\n" +
|
||||||
|
"\t\t\"minestom:an_item\"\n" +
|
||||||
|
"\t]\n" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
String tag2 = "{\n" +
|
||||||
|
"\t\"replace\": false,\n" +
|
||||||
|
"\t\"values\": [\n" +
|
||||||
|
"\t\t\"minestom:some_other_item\"\n" +
|
||||||
|
"\t]\n" +
|
||||||
|
"}";
|
||||||
|
Assert.assertNotEquals(Tag.EMPTY, tags.load(NamespaceID.from("minestom:test"), "any", new StringReader(tag1)));
|
||||||
|
Tag loaded = tags.forceLoad(NamespaceID.from("minestom:test"), "any", () -> new StringReader(tag2));
|
||||||
|
Assert.assertNotEquals(Tag.EMPTY, loaded);
|
||||||
|
Assert.assertEquals(2, loaded.getValues().size());
|
||||||
|
Assert.assertTrue(loaded.contains(NamespaceID.from("minestom:some_other_item")));
|
||||||
|
Assert.assertTrue(loaded.contains(NamespaceID.from("minestom:an_item")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanup() {
|
||||||
|
tags = null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user