Overhaul JSON message classes to be immutable and use a builder pattern.

This commit is contained in:
Steveice10 2020-06-01 16:41:06 -07:00
parent a2478aeb9d
commit f142eab3a2
51 changed files with 992 additions and 489 deletions

View file

@ -8,12 +8,11 @@ import com.github.steveice10.mc.protocol.ServerLoginHandler;
import com.github.steveice10.mc.protocol.data.SubProtocol; import com.github.steveice10.mc.protocol.data.SubProtocol;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.world.WorldType; import com.github.steveice10.mc.protocol.data.game.world.WorldType;
import com.github.steveice10.mc.protocol.data.message.ChatColor;
import com.github.steveice10.mc.protocol.data.message.ChatFormat;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageStyle;
import com.github.steveice10.mc.protocol.data.message.TextMessage; import com.github.steveice10.mc.protocol.data.message.TextMessage;
import com.github.steveice10.mc.protocol.data.message.TranslationMessage; import com.github.steveice10.mc.protocol.data.message.style.ChatColor;
import com.github.steveice10.mc.protocol.data.message.style.ChatFormat;
import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import com.github.steveice10.mc.protocol.data.status.PlayerInfo; import com.github.steveice10.mc.protocol.data.status.PlayerInfo;
import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo; import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo;
import com.github.steveice10.mc.protocol.data.status.VersionInfo; import com.github.steveice10.mc.protocol.data.status.VersionInfo;
@ -60,7 +59,7 @@ public class MinecraftProtocolTest {
return new ServerStatusInfo( return new ServerStatusInfo(
new VersionInfo(MinecraftConstants.GAME_VERSION, MinecraftConstants.PROTOCOL_VERSION), new VersionInfo(MinecraftConstants.GAME_VERSION, MinecraftConstants.PROTOCOL_VERSION),
new PlayerInfo(100, 0, new GameProfile[0]), new PlayerInfo(100, 0, new GameProfile[0]),
new TextMessage("Hello world!"), new TextMessage.Builder().text("Hello world!").build(),
null null
); );
} }
@ -89,11 +88,28 @@ public class MinecraftProtocolTest {
ClientChatPacket packet = event.getPacket(); ClientChatPacket packet = event.getPacket();
GameProfile profile = event.getSession().getFlag(MinecraftConstants.PROFILE_KEY); GameProfile profile = event.getSession().getFlag(MinecraftConstants.PROFILE_KEY);
System.out.println(profile.getName() + ": " + packet.getMessage()); System.out.println(profile.getName() + ": " + packet.getMessage());
Message msg = new TextMessage("Hello, ").setStyle(new MessageStyle().setColor(ChatColor.GREEN));
Message name = new TextMessage(profile.getName()).setStyle(new MessageStyle().setColor(ChatColor.AQUA).addFormat(ChatFormat.UNDERLINED)); MessageStyle green = new MessageStyle.Builder()
Message end = new TextMessage("!"); .color(ChatColor.GREEN)
msg.addExtra(name); .build();
msg.addExtra(end); MessageStyle aquaUnderline = new MessageStyle.Builder()
.color(ChatColor.AQUA)
.formats(ChatFormat.UNDERLINED)
.build();
Message msg = new TextMessage.Builder()
.text("Hello, ")
.style(green)
.extra(new TextMessage.Builder()
.text(profile.getName())
.style(aquaUnderline)
.build())
.extra(new TextMessage.Builder()
.text("!")
.style(green)
.build())
.build();
event.getSession().send(new ServerChatPacket(msg)); event.getSession().send(new ServerChatPacket(msg));
} }
} }
@ -127,7 +143,7 @@ public class MinecraftProtocolTest {
System.out.println("Version: " + info.getVersionInfo().getVersionName() + ", " + info.getVersionInfo().getProtocolVersion()); System.out.println("Version: " + info.getVersionInfo().getVersionName() + ", " + info.getVersionInfo().getProtocolVersion());
System.out.println("Player Count: " + info.getPlayerInfo().getOnlinePlayers() + " / " + info.getPlayerInfo().getMaxPlayers()); System.out.println("Player Count: " + info.getPlayerInfo().getOnlinePlayers() + " / " + info.getPlayerInfo().getMaxPlayers());
System.out.println("Players: " + Arrays.toString(info.getPlayerInfo().getPlayers())); System.out.println("Players: " + Arrays.toString(info.getPlayerInfo().getPlayers()));
System.out.println("Description: " + info.getDescription().getFullText()); System.out.println("Description: " + info.getDescription());
System.out.println("Icon: " + info.getIconPng()); System.out.println("Icon: " + info.getIconPng());
} }
}); });
@ -172,18 +188,14 @@ public class MinecraftProtocolTest {
event.getSession().send(new ClientChatPacket("Hello, this is a test of MCProtocolLib.")); event.getSession().send(new ClientChatPacket("Hello, this is a test of MCProtocolLib."));
} else if(event.getPacket() instanceof ServerChatPacket) { } else if(event.getPacket() instanceof ServerChatPacket) {
Message message = event.<ServerChatPacket>getPacket().getMessage(); Message message = event.<ServerChatPacket>getPacket().getMessage();
System.out.println("Received Message: " + message.getFullText()); System.out.println("Received Message: " + message);
if(message instanceof TranslationMessage) {
System.out.println("Received Translation Components: " + Arrays.toString(((TranslationMessage) message).getTranslationParams()));
}
event.getSession().disconnect("Finished"); event.getSession().disconnect("Finished");
} }
} }
@Override @Override
public void disconnected(DisconnectedEvent event) { public void disconnected(DisconnectedEvent event) {
System.out.println("Disconnected: " + Message.fromString(event.getReason()).getFullText()); System.out.println("Disconnected: " + event.getReason());
if(event.getCause() != null) { if(event.getCause() != null) {
event.getCause().printStackTrace(); event.getCause().printStackTrace();
} }

View file

@ -83,7 +83,7 @@ public class ClientListener extends SessionAdapter {
protocol.setSubProtocol(SubProtocol.GAME, true, event.getSession()); protocol.setSubProtocol(SubProtocol.GAME, true, event.getSession());
} else if(event.getPacket() instanceof LoginDisconnectPacket) { } else if(event.getPacket() instanceof LoginDisconnectPacket) {
LoginDisconnectPacket packet = event.getPacket(); LoginDisconnectPacket packet = event.getPacket();
event.getSession().disconnect(packet.getReason().getFullText()); event.getSession().disconnect(packet.getReason().toString());
} else if(event.getPacket() instanceof LoginSetCompressionPacket) { } else if(event.getPacket() instanceof LoginSetCompressionPacket) {
event.getSession().setCompressionThreshold(event.<LoginSetCompressionPacket>getPacket().getThreshold()); event.getSession().setCompressionThreshold(event.<LoginSetCompressionPacket>getPacket().getThreshold());
} }
@ -109,7 +109,7 @@ public class ClientListener extends SessionAdapter {
if(event.getPacket() instanceof ServerKeepAlivePacket) { if(event.getPacket() instanceof ServerKeepAlivePacket) {
event.getSession().send(new ClientKeepAlivePacket(event.<ServerKeepAlivePacket>getPacket().getPingId())); event.getSession().send(new ClientKeepAlivePacket(event.<ServerKeepAlivePacket>getPacket().getPingId()));
} else if(event.getPacket() instanceof ServerDisconnectPacket) { } else if(event.getPacket() instanceof ServerDisconnectPacket) {
event.getSession().disconnect(event.<ServerDisconnectPacket>getPacket().getReason().getFullText()); event.getSession().disconnect(event.<ServerDisconnectPacket>getPacket().getReason().toString());
} else if(event.getPacket() instanceof ServerSetCompressionPacket) { } else if(event.getPacket() instanceof ServerSetCompressionPacket) {
event.getSession().setCompressionThreshold(event.<ServerSetCompressionPacket>getPacket().getThreshold()); event.getSession().setCompressionThreshold(event.<ServerSetCompressionPacket>getPacket().getThreshold());
} }

View file

@ -102,12 +102,12 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.Serv
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerHealthPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerHealthPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerSetExperiencePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerSetExperiencePacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnExpOrbPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnWeatherEntityPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnLivingEntityPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnEntityPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnEntityPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnExpOrbPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnLivingEntityPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPaintingPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPaintingPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPlayerPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnPlayerPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn.ServerSpawnWeatherEntityPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerDisplayScoreboardPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerDisplayScoreboardPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerScoreboardObjectivePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerScoreboardObjectivePacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerTeamPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.scoreboard.ServerTeamPacket;

View file

@ -4,7 +4,7 @@ import com.github.steveice10.mc.auth.data.GameProfile;
import com.github.steveice10.mc.auth.exception.request.RequestException; import com.github.steveice10.mc.auth.exception.request.RequestException;
import com.github.steveice10.mc.auth.service.SessionService; import com.github.steveice10.mc.auth.service.SessionService;
import com.github.steveice10.mc.protocol.data.SubProtocol; import com.github.steveice10.mc.protocol.data.SubProtocol;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.TextMessage;
import com.github.steveice10.mc.protocol.data.status.PlayerInfo; import com.github.steveice10.mc.protocol.data.status.PlayerInfo;
import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo; import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo;
import com.github.steveice10.mc.protocol.data.status.VersionInfo; import com.github.steveice10.mc.protocol.data.status.VersionInfo;
@ -127,7 +127,7 @@ public class ServerListener extends SessionAdapter {
builder = session -> new ServerStatusInfo( builder = session -> new ServerStatusInfo(
VersionInfo.CURRENT, VersionInfo.CURRENT,
new PlayerInfo(0, 20, new GameProfile[0]), new PlayerInfo(0, 20, new GameProfile[0]),
Message.fromString("A Minecraft Server"), new TextMessage.Builder().text("A Minecraft Server").build(),
null null
); );
} }

View file

@ -23,6 +23,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOper
import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierType; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierType;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection;
import com.github.steveice10.mc.protocol.data.game.entity.object.MinecartType;
import com.github.steveice10.mc.protocol.data.game.entity.player.Animation; import com.github.steveice10.mc.protocol.data.game.entity.player.Animation;
import com.github.steveice10.mc.protocol.data.game.entity.player.BlockBreakStage; import com.github.steveice10.mc.protocol.data.game.entity.player.BlockBreakStage;
import com.github.steveice10.mc.protocol.data.game.entity.player.CombatState; import com.github.steveice10.mc.protocol.data.game.entity.player.CombatState;
@ -32,11 +34,9 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState;
import com.github.steveice10.mc.protocol.data.game.entity.player.PositionElement; import com.github.steveice10.mc.protocol.data.game.entity.player.PositionElement;
import com.github.steveice10.mc.protocol.data.game.entity.type.WeatherEntityType;
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
import com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType; import com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType;
import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection; import com.github.steveice10.mc.protocol.data.game.entity.type.WeatherEntityType;
import com.github.steveice10.mc.protocol.data.game.entity.object.MinecartType;
import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType;
import com.github.steveice10.mc.protocol.data.game.scoreboard.CollisionRule; import com.github.steveice10.mc.protocol.data.game.scoreboard.CollisionRule;
import com.github.steveice10.mc.protocol.data.game.scoreboard.NameTagVisibility; import com.github.steveice10.mc.protocol.data.game.scoreboard.NameTagVisibility;

View file

@ -8,6 +8,7 @@ import com.github.steveice10.mc.protocol.data.game.world.particle.Particle;
import com.github.steveice10.mc.protocol.data.game.world.particle.ParticleData; import com.github.steveice10.mc.protocol.data.game.world.particle.ParticleData;
import com.github.steveice10.mc.protocol.data.game.world.particle.ParticleType; import com.github.steveice10.mc.protocol.data.game.world.particle.ParticleType;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
@ -56,7 +57,7 @@ public class EntityMetadata {
// Intentional fall-through // Intentional fall-through
case CHAT: case CHAT:
value = Message.fromString(in.readString()); value = MessageSerializer.fromString(in.readString());
break; break;
case ITEM: case ITEM:
value = ItemStack.read(in); value = ItemStack.read(in);
@ -142,7 +143,7 @@ public class EntityMetadata {
// Intentional fall-through // Intentional fall-through
case CHAT: case CHAT:
out.writeString(((Message) meta.getValue()).toJsonString()); out.writeString(MessageSerializer.toJsonString((Message) meta.getValue()));
break; break;
case ITEM: case ITEM:
ItemStack.write(out, (ItemStack) meta.getValue()); ItemStack.write(out, (ItemStack) meta.getValue());

View file

@ -0,0 +1,43 @@
package com.github.steveice10.mc.protocol.data.message;
import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
public class BlockNbtMessage extends NbtMessage {
public static class Builder extends NbtMessage.Builder<Builder, BlockNbtMessage> {
@NonNull
private String pos = "";
public Builder pos(@NonNull String pos) {
this.pos = pos;
return this;
}
@Override
public Builder copy(@NonNull BlockNbtMessage message) {
super.copy(message);
this.pos = message.getPos();
return this;
}
@Override
public BlockNbtMessage build() {
return new BlockNbtMessage(this.style, this.extra, this.path, this.interpret, this.pos);
}
}
private final String pos;
private BlockNbtMessage(MessageStyle style, List<Message> extra, String path, boolean interpret, String pos) {
super(style, extra, path, interpret);
this.pos = pos;
}
public String getPos() {
return this.pos;
}
}

View file

@ -1,11 +0,0 @@
package com.github.steveice10.mc.protocol.data.message;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class ClickEvent {
private final ClickAction action;
private final String value;
}

View file

@ -0,0 +1,43 @@
package com.github.steveice10.mc.protocol.data.message;
import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
public class EntityNbtMessage extends NbtMessage {
public static class Builder extends NbtMessage.Builder<Builder, EntityNbtMessage> {
@NonNull
private String selector = "";
public Builder selector(@NonNull String selector) {
this.selector = selector;
return this;
}
@Override
public Builder copy(@NonNull EntityNbtMessage message) {
super.copy(message);
this.selector = message.getSelector();
return this;
}
@Override
public EntityNbtMessage build() {
return new EntityNbtMessage(this.style, this.extra, this.path, this.interpret, this.selector);
}
}
private final String selector;
private EntityNbtMessage(MessageStyle style, List<Message> extra, String path, boolean interpret, String selector) {
super(style, extra, path, interpret);
this.selector = selector;
}
public String getSelector() {
return this.selector;
}
}

View file

@ -1,11 +0,0 @@
package com.github.steveice10.mc.protocol.data.message;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class HoverEvent {
private final HoverAction action;
private final Message value;
}

View file

@ -1,36 +1,43 @@
package com.github.steveice10.mc.protocol.data.message; package com.github.steveice10.mc.protocol.data.message;
import com.google.gson.JsonElement; import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import com.google.gson.JsonObject;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.NonNull;
import java.util.List;
@Getter
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
public class KeybindMessage extends Message { public class KeybindMessage extends Message {
private final String keybind; public static class Builder extends Message.Builder<Builder, KeybindMessage> {
@NonNull
private String keybind = "";
@Override public Builder keybind(@NonNull String keybind) {
public String getText() { this.keybind = keybind;
return this.keybind; return this;
} }
@Override @Override
public KeybindMessage clone() { public Builder copy(@NonNull KeybindMessage message) {
return (KeybindMessage) new KeybindMessage(this.keybind).setStyle(this.getStyle().clone()).setExtra(this.getExtra()); super.copy(message);
} this.keybind = message.getKeybind();
return this;
}
@Override @Override
public JsonElement toJson() { public KeybindMessage build() {
JsonElement e = super.toJson(); return new KeybindMessage(this.style, this.extra, this.keybind);
if(e.isJsonObject()) {
JsonObject json = e.getAsJsonObject();
json.addProperty("keybind", this.keybind);
return json;
} else {
return e;
} }
} }
private final String keybind;
private KeybindMessage(MessageStyle style, List<Message> extra, String keybind) {
super(style, extra);
this.keybind = keybind;
}
public String getKeybind() {
return this.keybind;
}
} }

View file

@ -1,206 +1,64 @@
package com.github.steveice10.mc.protocol.data.message; package com.github.steveice10.mc.protocol.data.message;
import com.google.gson.JsonArray; import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
@Getter
@EqualsAndHashCode @EqualsAndHashCode
public abstract class Message implements Cloneable { public abstract class Message {
private MessageStyle style = new MessageStyle(); public abstract static class Builder<B extends Builder<?, M>, M extends Message> {
private final List<Message> extra = new ArrayList<Message>(); @NonNull
protected MessageStyle style = MessageStyle.DEFAULT;
@NonNull
protected List<Message> extra = new ArrayList<>();
public static Message fromString(String str) { public B style(@NonNull MessageStyle style) {
try { this.style = style;
return fromJson(new JsonParser().parse(str)); return (B) this;
} catch(Exception e) {
return new TextMessage(str);
}
}
public static Message fromJson(JsonElement e) {
if(e.isJsonPrimitive()) {
return new TextMessage(e.getAsString());
} else if(e.isJsonArray()) {
JsonArray array = e.getAsJsonArray();
if(array.size() == 0) {
return new TextMessage("");
}
Message msg = Message.fromJson(array.get(0));
for(int index = 1; index < array.size(); index++) {
msg.addExtra(Message.fromJson(array.get(index)));
}
return msg;
} else if(e.isJsonObject()) {
JsonObject json = e.getAsJsonObject();
Message msg = null;
if(json.has("text")) {
msg = new TextMessage(json.get("text").getAsString());
} else if(json.has("translate")) {
Message with[] = new Message[0];
if(json.has("with")) {
JsonArray withJson = json.get("with").getAsJsonArray();
with = new Message[withJson.size()];
for(int index = 0; index < withJson.size(); index++) {
JsonElement el = withJson.get(index);
if(el.isJsonPrimitive()) {
with[index] = new TextMessage(el.getAsString());
} else {
with[index] = Message.fromJson(el.getAsJsonObject());
}
}
}
msg = new TranslationMessage(json.get("translate").getAsString(), with);
} else if(json.has("keybind")) {
msg = new KeybindMessage(json.get("keybind").getAsString());
} else {
throw new IllegalArgumentException("Unknown message type in json: " + json.toString());
}
MessageStyle style = new MessageStyle();
if(json.has("color")) {
style.setColor(ChatColor.byName(json.get("color").getAsString()));
}
for(ChatFormat format : ChatFormat.values()) {
if(json.has(format.toString()) && json.get(format.toString()).getAsBoolean()) {
style.addFormat(format);
}
}
if(json.has("clickEvent")) {
JsonObject click = json.get("clickEvent").getAsJsonObject();
style.setClickEvent(new ClickEvent(ClickAction.byName(click.get("action").getAsString()), click.get("value").getAsString()));
}
if(json.has("hoverEvent")) {
JsonObject hover = json.get("hoverEvent").getAsJsonObject();
style.setHoverEvent(new HoverEvent(HoverAction.byName(hover.get("action").getAsString()), Message.fromJson(hover.get("value"))));
}
if(json.has("insertion")) {
style.setInsertion(json.get("insertion").getAsString());
}
msg.setStyle(style);
if(json.has("extra")) {
JsonArray extraJson = json.get("extra").getAsJsonArray();
for(int index = 0; index < extraJson.size(); index++) {
msg.addExtra(Message.fromJson(extraJson.get(index)));
}
}
return msg;
} else {
throw new IllegalArgumentException("Cannot convert " + e.getClass().getSimpleName() + " to a message.");
}
}
public abstract String getText();
public String getFullText() {
StringBuilder build = new StringBuilder(this.getText());
for(Message msg : this.extra) {
build.append(msg.getFullText());
} }
return build.toString(); public B extra(@NonNull Message... extra) {
return this.extra(Arrays.asList(extra));
}
public B extra(@NonNull Collection<Message> extra) {
this.extra.addAll(extra);
return (B) this;
}
public B copy(@NonNull M message) {
this.style = message.getStyle();
this.extra = new ArrayList<>(message.getExtra());
return (B) this;
}
public abstract M build();
} }
public Message setStyle(MessageStyle style) { private final MessageStyle style;
private final List<Message> extra;
protected Message(MessageStyle style, List<Message> extra) {
this.style = style; this.style = style;
return this; this.extra = Collections.unmodifiableList(extra);
} }
public Message setExtra(List<Message> extra) { public MessageStyle getStyle() {
this.clearExtra(); return this.style;
for(Message msg : extra) {
this.addExtra(msg.clone());
}
return this;
} }
public Message addExtra(Message message) { public List<Message> getExtra() {
this.extra.add(message); return this.extra;
message.getStyle().setParent(this.style);
return this;
} }
public Message removeExtra(Message message) {
this.extra.remove(message);
message.getStyle().setParent(null);
return this;
}
public Message clearExtra() {
for(Message msg : this.extra) {
msg.getStyle().setParent(null);
}
this.extra.clear();
return this;
}
@Override
public abstract Message clone();
@Override @Override
public String toString() { public String toString() {
return this.getFullText(); return MessageSerializer.toJsonString(this);
}
public String toJsonString() {
return this.toJson().toString();
}
public JsonElement toJson() {
JsonObject json = new JsonObject();
if(this.style.hasColor()) {
json.addProperty("color", this.style.getColor().toString());
}
for(ChatFormat format : this.style.getFormats()) {
json.addProperty(format.toString(), true);
}
if(this.style.getClickEvent() != null) {
JsonObject click = new JsonObject();
click.addProperty("action", this.style.getClickEvent().getAction().toString());
click.addProperty("value", this.style.getClickEvent().getValue());
json.add("clickEvent", click);
}
if(this.style.getHoverEvent() != null) {
JsonObject hover = new JsonObject();
hover.addProperty("action", this.style.getHoverEvent().getAction().toString());
hover.add("value", this.style.getHoverEvent().getValue().toJson());
json.add("hoverEvent", hover);
}
if(this.style.getInsertion() != null) {
json.addProperty("insertion", this.style.getInsertion());
}
if(this.extra.size() > 0) {
JsonArray extra = new JsonArray();
for(Message msg : this.extra) {
extra.add(msg.toJson());
}
json.add("extra", extra);
}
return json;
} }
} }

View file

@ -0,0 +1,255 @@
package com.github.steveice10.mc.protocol.data.message;
import com.github.steveice10.mc.protocol.data.message.style.ChatColor;
import com.github.steveice10.mc.protocol.data.message.style.ChatFormat;
import com.github.steveice10.mc.protocol.data.message.style.ClickAction;
import com.github.steveice10.mc.protocol.data.message.style.ClickEvent;
import com.github.steveice10.mc.protocol.data.message.style.HoverAction;
import com.github.steveice10.mc.protocol.data.message.style.HoverEvent;
import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import java.util.ArrayList;
import java.util.List;
public class MessageSerializer {
public static Message fromString(String str) {
try {
return fromJson(new JsonParser().parse(str));
} catch(Exception e) {
return new TextMessage.Builder().text(str).build();
}
}
public static Message fromJson(JsonElement e) {
return builderFromJson(e).build();
}
private static Message.Builder<?, ?> builderFromJson(JsonElement e) {
if(e.isJsonPrimitive()) {
return new TextMessage.Builder().text(e.getAsString());
} else if(e.isJsonArray()) {
JsonArray array = e.getAsJsonArray();
if(array.size() == 0) {
return new TextMessage.Builder().text("");
}
Message.Builder<?, ?> msg = builderFromJson(array.get(0));
for(int index = 1; index < array.size(); index++) {
msg.extra(fromJson(array.get(index)));
}
return msg;
} else if(e.isJsonObject()) {
JsonObject json = e.getAsJsonObject();
Message.Builder<?, ?> msg = dataFromJson(json);
msg.style(styleFromJson(json));
msg.extra(extraFromJson(json));
return msg;
} else {
throw new IllegalArgumentException("Cannot convert JSON type " + e.getClass().getSimpleName() + " to a message.");
}
}
public static String toJsonString(Message message) {
return toJson(message).toString();
}
public static JsonElement toJson(Message message) {
if(message instanceof TextMessage && message.getStyle().equals(MessageStyle.DEFAULT) && message.getExtra().isEmpty()) {
return new JsonPrimitive(((TextMessage) message).getText());
}
JsonObject json = new JsonObject();
dataToJson(json, message);
styleToJson(json, message.getStyle());
extraToJson(json, message.getExtra());
return json;
}
private static Message.Builder<?, ?> dataFromJson(JsonObject json) {
if(json.has("text")) {
return new TextMessage.Builder()
.text(json.get("text").getAsString());
} else if(json.has("translate")) {
List<Message> with = new ArrayList<>();
if(json.has("with")) {
JsonArray withJson = json.get("with").getAsJsonArray();
for(int index = 0; index < withJson.size(); index++) {
with.add(fromJson(withJson.get(index)));
}
}
return new TranslationMessage.Builder()
.key(json.get("translate").getAsString())
.with(with);
} else if(json.has("keybind")) {
return new KeybindMessage.Builder()
.keybind(json.get("keybind").getAsString());
} else if(json.has("score")) {
JsonObject score = json.get("score").getAsJsonObject();
return new ScoreMessage.Builder()
.name(score.get("name").getAsString())
.objective(score.get("objective").getAsString())
.value(score.has("value") ? score.get("value").getAsString() : null);
} else if(json.has("selector")) {
return new SelectorMessage.Builder()
.selector(json.get("selector").getAsString());
} else if(json.has("nbt")) {
String path = json.get("nbt").getAsString();
boolean interpret = json.has("interpret") && json.get("interpret").getAsBoolean();
if(json.has("block")) {
return new BlockNbtMessage.Builder()
.path(path)
.interpret(interpret)
.pos(json.get("block").getAsString());
} else if(json.has("entity")) {
return new EntityNbtMessage.Builder()
.path(path)
.interpret(interpret)
.selector(json.get("entity").getAsString());
} else if(json.has("storage")) {
return new StorageNbtMessage.Builder()
.path(path)
.interpret(interpret)
.id(json.get("storage").getAsString());
} else {
throw new IllegalArgumentException("Unknown NBT message type in json: " + json);
}
} else {
throw new IllegalArgumentException("Unknown message type in json: " + json);
}
}
private static void dataToJson(JsonObject json, Message message) {
if(message instanceof TextMessage) {
json.addProperty("text", ((TextMessage) message).getText());
} else if(message instanceof TranslationMessage) {
TranslationMessage translationMessage = (TranslationMessage) message;
json.addProperty("translate", translationMessage.getKey());
List<Message> with = translationMessage.getWith();
if(!with.isEmpty()) {
JsonArray jsonWith = new JsonArray();
for(Message msg : with) {
jsonWith.add(toJson(msg));
}
json.add("with", jsonWith);
}
} else if(message instanceof KeybindMessage) {
json.addProperty("keybind", ((KeybindMessage) message).getKeybind());
} else if(message instanceof ScoreMessage) {
ScoreMessage scoreMessage = (ScoreMessage) message;
JsonObject score = new JsonObject();
score.addProperty("name", scoreMessage.getName());
score.addProperty("objective", scoreMessage.getObjective());
if(scoreMessage.getValue() != null) {
score.addProperty("value", scoreMessage.getValue());
}
json.add("score", score);
} else if(message instanceof SelectorMessage) {
json.addProperty("selector", ((SelectorMessage) message).getSelector());
} else if(message instanceof NbtMessage) {
NbtMessage nbtMessage = (NbtMessage) message;
json.addProperty("nbt", nbtMessage.getPath());
json.addProperty("interpret", nbtMessage.shouldInterpret());
if(message instanceof BlockNbtMessage) {
json.addProperty("block", ((BlockNbtMessage) nbtMessage).getPos());
} else if(message instanceof EntityNbtMessage) {
json.addProperty("entity", ((EntityNbtMessage) nbtMessage).getSelector());
} else if(message instanceof StorageNbtMessage) {
json.addProperty("storage", ((StorageNbtMessage) nbtMessage).getId());
}
}
}
private static MessageStyle styleFromJson(JsonObject json) {
MessageStyle.Builder style = new MessageStyle.Builder();
if(json.has("color")) {
style.color(ChatColor.byName(json.get("color").getAsString()));
}
for(ChatFormat format : ChatFormat.values()) {
if(json.has(format.toString()) && json.get(format.toString()).getAsBoolean()) {
style.formats(format);
}
}
if(json.has("clickEvent")) {
JsonObject click = json.get("clickEvent").getAsJsonObject();
style.clickEvent(new ClickEvent(ClickAction.byName(click.get("action").getAsString()), click.get("value").getAsString()));
}
if(json.has("hoverEvent")) {
JsonObject hover = json.get("hoverEvent").getAsJsonObject();
style.hoverEvent(new HoverEvent(HoverAction.byName(hover.get("action").getAsString()), fromJson(hover.get("value"))));
}
if(json.has("insertion")) {
style.insertion(json.get("insertion").getAsString());
}
return style.build();
}
private static void styleToJson(JsonObject json, MessageStyle style) {
if(style.getColor() != ChatColor.NONE) {
json.addProperty("color", style.getColor().toString());
}
for(ChatFormat format : style.getFormats()) {
json.addProperty(format.toString(), true);
}
if(style.getClickEvent() != null) {
JsonObject click = new JsonObject();
click.addProperty("action", style.getClickEvent().getAction().toString());
click.addProperty("value", style.getClickEvent().getValue());
json.add("clickEvent", click);
}
if(style.getHoverEvent() != null) {
JsonObject hover = new JsonObject();
hover.addProperty("action", style.getHoverEvent().getAction().toString());
hover.add("value", toJson(style.getHoverEvent().getValue()));
json.add("hoverEvent", hover);
}
if(style.getInsertion() != null) {
json.addProperty("insertion", style.getInsertion());
}
}
private static List<Message> extraFromJson(JsonObject json) {
List<Message> extra = new ArrayList<>();
if(json.has("extra")) {
JsonArray extraJson = json.get("extra").getAsJsonArray();
for(int index = 0; index < extraJson.size(); index++) {
extra.add(fromJson(extraJson.get(index)));
}
}
return extra;
}
private static void extraToJson(JsonObject json, List<Message> extra) {
if(!extra.isEmpty()) {
JsonArray jsonExtra = new JsonArray();
for(Message msg : extra) {
jsonExtra.add(toJson(msg));
}
json.add("extra", jsonExtra);
}
}
}

View file

@ -1,89 +0,0 @@
package com.github.steveice10.mc.protocol.data.message;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Data
@Setter(AccessLevel.NONE)
public class MessageStyle implements Cloneable {
private static final MessageStyle DEFAULT = new MessageStyle();
private ChatColor color = ChatColor.NONE;
private List<ChatFormat> formats = new ArrayList<ChatFormat>();
private ClickEvent clickEvent;
private HoverEvent hoverEvent;
private String insertion;
private MessageStyle parent = DEFAULT;
public boolean isDefault() {
return this.equals(DEFAULT);
}
public boolean hasColor() {
return color != ChatColor.NONE;
}
public MessageStyle setColor(ChatColor color) {
this.color = color;
return this;
}
public MessageStyle setFormats(List<ChatFormat> formats) {
this.formats = new ArrayList<ChatFormat>(formats);
return this;
}
public MessageStyle setClickEvent(ClickEvent event) {
this.clickEvent = event;
return this;
}
public MessageStyle setHoverEvent(HoverEvent event) {
this.hoverEvent = event;
return this;
}
public MessageStyle setInsertion(String insertion) {
this.insertion = insertion;
return this;
}
protected MessageStyle setParent(MessageStyle parent) {
if(parent == null) {
parent = DEFAULT;
}
this.parent = parent;
return this;
}
public MessageStyle addFormat(ChatFormat format) {
this.formats.add(format);
return this;
}
public MessageStyle removeFormat(ChatFormat format) {
this.formats.remove(format);
return this;
}
public MessageStyle clearFormats() {
this.formats.clear();
return this;
}
@Override
public MessageStyle clone() {
return new MessageStyle()
.setParent(this.parent)
.setColor(this.color)
.setFormats(this.formats)
.setClickEvent(this.clickEvent)
.setHoverEvent(this.hoverEvent)
.setInsertion(this.insertion);
}
}

View file

@ -0,0 +1,54 @@
package com.github.steveice10.mc.protocol.data.message;
import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
public abstract class NbtMessage extends Message {
public abstract static class Builder<B extends Builder<?, M>, M extends NbtMessage> extends Message.Builder<B, M> {
@NonNull
protected String path = "";
protected boolean interpret = false;
public B path(@NonNull String path) {
this.path = path;
return (B) this;
}
public B interpret(boolean interpret) {
this.interpret = interpret;
return (B) this;
}
@Override
public B copy(@NonNull M message) {
super.copy(message);
this.path = message.getPath();
this.interpret = message.shouldInterpret();
return (B) this;
}
@Override
public abstract M build();
}
private final String path;
private final boolean interpret;
protected NbtMessage(MessageStyle style, List<Message> extra, String path, boolean interpret) {
super(style, extra);
this.path = path;
this.interpret = interpret;
}
public String getPath() {
return this.path;
}
public boolean shouldInterpret() {
return this.interpret;
}
}

View file

@ -0,0 +1,70 @@
package com.github.steveice10.mc.protocol.data.message;
import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
public class ScoreMessage extends Message {
public static class Builder extends Message.Builder<Builder, ScoreMessage> {
@NonNull
private String name = "";
@NonNull
private String objective = "";
private String value = null;
public Builder name(@NonNull String name) {
this.name = name;
return this;
}
public Builder objective(@NonNull String objective) {
this.objective = objective;
return this;
}
public Builder value(String value) {
this.value = value;
return this;
}
@Override
public Builder copy(@NonNull ScoreMessage message) {
super.copy(message);
this.name = message.getName();
this.objective = message.getObjective();
this.value = message.getValue();
return this;
}
@Override
public ScoreMessage build() {
return new ScoreMessage(this.style, this.extra, this.name, this.objective, this.value);
}
}
private final String name;
private final String objective;
private final String value;
private ScoreMessage(MessageStyle style, List<Message> extra, String name, String objective, String value) {
super(style, extra);
this.name = name;
this.objective = objective;
this.value = value;
}
public String getName() {
return this.name;
}
public String getObjective() {
return this.objective;
}
public String getValue() {
return this.value;
}
}

View file

@ -0,0 +1,43 @@
package com.github.steveice10.mc.protocol.data.message;
import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
public class SelectorMessage extends Message {
public static class Builder extends Message.Builder<Builder, SelectorMessage> {
@NonNull
private String selector = "";
public Builder selector(@NonNull String selector) {
this.selector = selector;
return this;
}
@Override
public Builder copy(@NonNull SelectorMessage message) {
super.copy(message);
this.selector = message.getSelector();
return this;
}
@Override
public SelectorMessage build() {
return new SelectorMessage(this.style, this.extra, this.selector);
}
}
private final String selector;
private SelectorMessage(MessageStyle style, List<Message> extra, String selector) {
super(style, extra);
this.selector = selector;
}
public String getSelector() {
return this.selector;
}
}

View file

@ -0,0 +1,43 @@
package com.github.steveice10.mc.protocol.data.message;
import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
public class StorageNbtMessage extends NbtMessage {
public static class Builder extends NbtMessage.Builder<Builder, StorageNbtMessage> {
@NonNull
private String id = "";
public Builder id(@NonNull String id) {
this.id = id;
return this;
}
@Override
public Builder copy(@NonNull StorageNbtMessage message) {
super.copy(message);
this.id = message.getId();
return this;
}
@Override
public StorageNbtMessage build() {
return new StorageNbtMessage(this.style, this.extra, this.path, this.interpret, this.id);
}
}
private final String id;
private StorageNbtMessage(MessageStyle style, List<Message> extra, String path, boolean interpret, String id) {
super(style, extra, path, interpret);
this.id = id;
}
public String getId() {
return this.id;
}
}

View file

@ -1,36 +1,43 @@
package com.github.steveice10.mc.protocol.data.message; package com.github.steveice10.mc.protocol.data.message;
import com.google.gson.JsonElement; import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.NonNull;
import java.util.List;
@Getter
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
public class TextMessage extends Message { public class TextMessage extends Message {
private final String text; public static class Builder extends Message.Builder<Builder, TextMessage> {
@NonNull
private String text = "";
@Override public Builder text(@NonNull String text) {
public TextMessage clone() { this.text = text;
return (TextMessage) new TextMessage(this.getText()).setStyle(this.getStyle().clone()).setExtra(this.getExtra()); return this;
} }
@Override @Override
public JsonElement toJson() { public Builder copy(@NonNull TextMessage message) {
if(this.getStyle().isDefault() && this.getExtra().isEmpty()) { super.copy(message);
return new JsonPrimitive(this.text); this.text = message.getText();
} else { return this;
JsonElement e = super.toJson(); }
if(e.isJsonObject()) {
JsonObject json = e.getAsJsonObject(); @Override
json.addProperty("text", this.text); public TextMessage build() {
return json; return new TextMessage(this.style, this.extra, this.text);
} else {
return e;
}
} }
} }
private final String text;
private TextMessage(MessageStyle style, List<Message> extra, String text) {
super(style, extra);
this.text = text;
}
public String getText() {
return this.text;
}
} }

View file

@ -1,61 +1,65 @@
package com.github.steveice10.mc.protocol.data.message; package com.github.steveice10.mc.protocol.data.message;
import com.google.gson.JsonArray; import com.github.steveice10.mc.protocol.data.message.style.MessageStyle;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.NonNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@Getter
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class TranslationMessage extends Message { public class TranslationMessage extends Message {
private final String translationKey; public static class Builder extends Message.Builder<Builder, TranslationMessage> {
private final Message[] translationParams; @NonNull
private String key = "";
@NonNull
private List<Message> with = new ArrayList<>();
public TranslationMessage(String translationKey, Message... translationParams) { public Builder key(@NonNull String key) {
this.translationKey = translationKey; this.key = key;
this.translationParams = new Message[translationParams.length]; return this;
for(int index = 0; index < this.translationParams.length; index++) { }
this.translationParams[index] = translationParams[index].clone();
this.translationParams[index].getStyle().setParent(this.getStyle()); public Builder with(@NonNull Message... with) {
return this.with(Arrays.asList(with));
}
public Builder with(@NonNull Collection<Message> with) {
this.with.addAll(with);
return this;
}
@Override
public Builder copy(@NonNull TranslationMessage message) {
super.copy(message);
this.key = message.getKey();
this.with = new ArrayList<>(message.getWith());
return this;
}
@Override
public TranslationMessage build() {
return new TranslationMessage(this.style, this.extra, this.key, this.with);
} }
} }
@Override private final String key;
public String getText() { private final List<Message> with;
return this.translationKey;
private TranslationMessage(MessageStyle style, List<Message> extra, String key, List<Message> with) {
super(style, extra);
this.key = key;
this.with = Collections.unmodifiableList(with);
} }
@Override public String getKey() {
public Message setStyle(MessageStyle style) { return this.key;
super.setStyle(style);
for(Message param : this.translationParams) {
param.getStyle().setParent(this.getStyle());
}
return this;
} }
@Override public List<Message> getWith() {
public TranslationMessage clone() { return this.with;
return (TranslationMessage) new TranslationMessage(this.translationKey, this.translationParams).setStyle(this.getStyle().clone()).setExtra(this.getExtra());
}
@Override
public JsonElement toJson() {
JsonElement e = super.toJson();
if(e.isJsonObject()) {
JsonObject json = e.getAsJsonObject();
json.addProperty("translate", this.translationKey);
JsonArray params = new JsonArray();
for(Message param : this.translationParams) {
params.add(param.toJson());
}
json.add("with", params);
return json;
} else {
return e;
}
} }
} }

View file

@ -1,4 +1,4 @@
package com.github.steveice10.mc.protocol.data.message; package com.github.steveice10.mc.protocol.data.message.style;
public enum ChatColor { public enum ChatColor {
BLACK, BLACK,
@ -21,9 +21,9 @@ public enum ChatColor {
NONE; NONE;
public static ChatColor byName(String name) { public static ChatColor byName(String name) {
name = name.toLowerCase(); String lowerCase = name.toLowerCase();
for(ChatColor color : values()) { for(ChatColor color : values()) {
if(color.toString().equals(name)) { if(color.toString().equals(lowerCase)) {
return color; return color;
} }
} }

View file

@ -1,4 +1,4 @@
package com.github.steveice10.mc.protocol.data.message; package com.github.steveice10.mc.protocol.data.message.style;
public enum ChatFormat { public enum ChatFormat {
BOLD, BOLD,
@ -8,9 +8,9 @@ public enum ChatFormat {
OBFUSCATED; OBFUSCATED;
public static ChatFormat byName(String name) { public static ChatFormat byName(String name) {
name = name.toLowerCase(); String lowerCase = name.toLowerCase();
for(ChatFormat format : values()) { for(ChatFormat format : values()) {
if(format.toString().equals(name)) { if(format.toString().equals(lowerCase)) {
return format; return format;
} }
} }

View file

@ -1,15 +1,15 @@
package com.github.steveice10.mc.protocol.data.message; package com.github.steveice10.mc.protocol.data.message.style;
public enum ClickAction { public enum ClickAction {
RUN_COMMAND, RUN_COMMAND,
SUGGEST_COMMAND, SUGGEST_COMMAND,
OPEN_URL, OPEN_URL,
OPEN_FILE; CHANGE_PAGE;
public static ClickAction byName(String name) { public static ClickAction byName(String name) {
name = name.toLowerCase(); String lowerCase = name.toLowerCase();
for(ClickAction action : values()) { for(ClickAction action : values()) {
if(action.toString().equals(name)) { if(action.toString().equals(lowerCase)) {
return action; return action;
} }
} }

View file

@ -0,0 +1,27 @@
package com.github.steveice10.mc.protocol.data.message.style;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
@ToString
@EqualsAndHashCode
public class ClickEvent {
@NonNull
private final ClickAction action;
@NonNull
private final String value;
public ClickEvent(@NonNull ClickAction action, @NonNull String value) {
this.action = action;
this.value = value;
}
public ClickAction getAction() {
return this.action;
}
public String getValue() {
return this.value;
}
}

View file

@ -1,15 +1,14 @@
package com.github.steveice10.mc.protocol.data.message; package com.github.steveice10.mc.protocol.data.message.style;
public enum HoverAction { public enum HoverAction {
SHOW_TEXT, SHOW_TEXT,
SHOW_ITEM, SHOW_ITEM,
SHOW_ACHIEVEMENT,
SHOW_ENTITY; SHOW_ENTITY;
public static HoverAction byName(String name) { public static HoverAction byName(String name) {
name = name.toLowerCase(); String lowerCase = name.toLowerCase();
for(HoverAction action : values()) { for(HoverAction action : values()) {
if(action.toString().equals(name)) { if(action.toString().equals(lowerCase)) {
return action; return action;
} }
} }

View file

@ -0,0 +1,28 @@
package com.github.steveice10.mc.protocol.data.message.style;
import com.github.steveice10.mc.protocol.data.message.Message;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
@ToString
@EqualsAndHashCode
public class HoverEvent {
@NonNull
private final HoverAction action;
@NonNull
private final Message value;
public HoverEvent(@NonNull HoverAction action, @NonNull Message value) {
this.action = action;
this.value = value;
}
public HoverAction getAction() {
return this.action;
}
public Message getValue() {
return this.value;
}
}

View file

@ -0,0 +1,103 @@
package com.github.steveice10.mc.protocol.data.message.style;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ToString
@EqualsAndHashCode
public class MessageStyle {
public static class Builder {
@NonNull
private ChatColor color = ChatColor.NONE;
@NonNull
private List<ChatFormat> formats = new ArrayList<>();
private ClickEvent clickEvent;
private HoverEvent hoverEvent;
private String insertion;
public Builder color(@NonNull ChatColor color) {
this.color = color;
return this;
}
public Builder formats(@NonNull ChatFormat... formats) {
return this.formats(Arrays.asList(formats));
}
public Builder formats(@NonNull Collection<ChatFormat> formats) {
this.formats.addAll(formats);
return this;
}
public Builder clickEvent(ClickEvent clickEvent) {
this.clickEvent = clickEvent;
return this;
}
public Builder hoverEvent(HoverEvent hoverEvent) {
this.hoverEvent = hoverEvent;
return this;
}
public Builder insertion(String insertion) {
this.insertion = insertion;
return this;
}
public Builder copy(MessageStyle style) {
this.color = style.getColor();
this.formats = new ArrayList<>(style.getFormats());
this.clickEvent = style.getClickEvent();
this.hoverEvent = style.getHoverEvent();
this.insertion = style.getInsertion();
return this;
}
public MessageStyle build() {
return new MessageStyle(this.color, this.formats, this.clickEvent, this.hoverEvent, this.insertion);
}
}
public static final MessageStyle DEFAULT = new MessageStyle.Builder().build();
private final ChatColor color;
private final List<ChatFormat> formats;
private final ClickEvent clickEvent;
private final HoverEvent hoverEvent;
private final String insertion;
private MessageStyle(ChatColor color, List<ChatFormat> formats, ClickEvent clickEvent, HoverEvent hoverEvent, String insertion) {
this.color = color;
this.formats = Collections.unmodifiableList(formats);
this.clickEvent = clickEvent;
this.hoverEvent = hoverEvent;
this.insertion = insertion;
}
public ChatColor getColor() {
return this.color;
}
public List<ChatFormat> getFormats() {
return this.formats;
}
public ClickEvent getClickEvent() {
return this.clickEvent;
}
public HoverEvent getHoverEvent() {
return this.hoverEvent;
}
public String getInsertion() {
return this.insertion;
}
}

View file

@ -7,8 +7,6 @@ import lombok.Data;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter; import lombok.Setter;
import java.awt.image.BufferedImage;
@Data @Data
@Setter(AccessLevel.NONE) @Setter(AccessLevel.NONE)
@AllArgsConstructor @AllArgsConstructor

View file

@ -6,6 +6,7 @@ import com.github.steveice10.mc.protocol.data.game.advancement.Advancement.Displ
import com.github.steveice10.mc.protocol.data.game.advancement.Advancement.DisplayData.FrameType; import com.github.steveice10.mc.protocol.data.game.advancement.Advancement.DisplayData.FrameType;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack; import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -59,8 +60,8 @@ public class ServerAdvancementsPacket implements Packet {
String parentId = in.readBoolean() ? in.readString() : null; String parentId = in.readBoolean() ? in.readString() : null;
DisplayData displayData = null; DisplayData displayData = null;
if(in.readBoolean()) { if(in.readBoolean()) {
Message title = Message.fromString(in.readString()); Message title = MessageSerializer.fromString(in.readString());
Message description = Message.fromString(in.readString()); Message description = MessageSerializer.fromString(in.readString());
ItemStack icon = ItemStack.read(in); ItemStack icon = ItemStack.read(in);
FrameType frameType = MagicValues.key(FrameType.class, in.readVarInt()); FrameType frameType = MagicValues.key(FrameType.class, in.readVarInt());
@ -136,8 +137,8 @@ public class ServerAdvancementsPacket implements Packet {
DisplayData displayData = advancement.getDisplayData(); DisplayData displayData = advancement.getDisplayData();
if(displayData != null) { if(displayData != null) {
out.writeBoolean(true); out.writeBoolean(true);
out.writeString(displayData.getTitle().toJsonString()); out.writeString(MessageSerializer.toJsonString(displayData.getTitle()));
out.writeString(displayData.getDescription().toJsonString()); out.writeString(MessageSerializer.toJsonString(displayData.getDescription()));
ItemStack.write(out, displayData.getIcon()); ItemStack.write(out, displayData.getIcon());
out.writeVarInt(MagicValues.value(Integer.class, displayData.getFrameType())); out.writeVarInt(MagicValues.value(Integer.class, displayData.getFrameType()));
String backgroundTexture = displayData.getBackgroundTexture(); String backgroundTexture = displayData.getBackgroundTexture();

View file

@ -5,6 +5,7 @@ import com.github.steveice10.mc.protocol.data.game.BossBarAction;
import com.github.steveice10.mc.protocol.data.game.BossBarColor; import com.github.steveice10.mc.protocol.data.game.BossBarColor;
import com.github.steveice10.mc.protocol.data.game.BossBarDivision; import com.github.steveice10.mc.protocol.data.game.BossBarDivision;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -91,7 +92,7 @@ public class ServerBossBarPacket implements Packet {
this.action = MagicValues.key(BossBarAction.class, in.readVarInt()); this.action = MagicValues.key(BossBarAction.class, in.readVarInt());
if(this.action == BossBarAction.ADD || this.action == BossBarAction.UPDATE_TITLE) { if(this.action == BossBarAction.ADD || this.action == BossBarAction.UPDATE_TITLE) {
this.title = Message.fromString(in.readString()); this.title = MessageSerializer.fromString(in.readString());
} }
if(this.action == BossBarAction.ADD || this.action == BossBarAction.UPDATE_HEALTH) { if(this.action == BossBarAction.ADD || this.action == BossBarAction.UPDATE_HEALTH) {
@ -117,7 +118,7 @@ public class ServerBossBarPacket implements Packet {
out.writeVarInt(MagicValues.value(Integer.class, this.action)); out.writeVarInt(MagicValues.value(Integer.class, this.action));
if(this.action == BossBarAction.ADD || this.action == BossBarAction.UPDATE_TITLE) { if(this.action == BossBarAction.ADD || this.action == BossBarAction.UPDATE_TITLE) {
out.writeString(this.title.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.title));
} }
if(this.action == BossBarAction.ADD || this.action == BossBarAction.UPDATE_HEALTH) { if(this.action == BossBarAction.ADD || this.action == BossBarAction.UPDATE_HEALTH) {

View file

@ -3,6 +3,7 @@ package com.github.steveice10.mc.protocol.packet.ingame.server;
import com.github.steveice10.mc.protocol.data.MagicValues; import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.MessageType; import com.github.steveice10.mc.protocol.data.game.MessageType;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -24,7 +25,7 @@ public class ServerChatPacket implements Packet {
private @NonNull MessageType type; private @NonNull MessageType type;
public ServerChatPacket(@NonNull String text) { public ServerChatPacket(@NonNull String text) {
this(Message.fromString(text)); this(MessageSerializer.fromString(text));
} }
public ServerChatPacket(@NonNull Message message) { public ServerChatPacket(@NonNull Message message) {
@ -32,18 +33,18 @@ public class ServerChatPacket implements Packet {
} }
public ServerChatPacket(@NonNull String text, @NonNull MessageType type) { public ServerChatPacket(@NonNull String text, @NonNull MessageType type) {
this(Message.fromString(text), type); this(MessageSerializer.fromString(text), type);
} }
@Override @Override
public void read(NetInput in) throws IOException { public void read(NetInput in) throws IOException {
this.message = Message.fromString(in.readString()); this.message = MessageSerializer.fromString(in.readString());
this.type = MagicValues.key(MessageType.class, in.readByte()); this.type = MagicValues.key(MessageType.class, in.readByte());
} }
@Override @Override
public void write(NetOutput out) throws IOException { public void write(NetOutput out) throws IOException {
out.writeString(this.message.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.message));
out.writeByte(MagicValues.value(Integer.class, this.type)); out.writeByte(MagicValues.value(Integer.class, this.type));
} }

View file

@ -3,6 +3,7 @@ package com.github.steveice10.mc.protocol.packet.ingame.server;
import com.github.steveice10.mc.protocol.data.MagicValues; import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.entity.player.CombatState; import com.github.steveice10.mc.protocol.data.game.entity.player.CombatState;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -51,7 +52,7 @@ public class ServerCombatPacket implements Packet {
} else if(this.combatState == CombatState.ENTITY_DEAD) { } else if(this.combatState == CombatState.ENTITY_DEAD) {
this.playerId = in.readVarInt(); this.playerId = in.readVarInt();
this.entityId = in.readInt(); this.entityId = in.readInt();
this.message = Message.fromString(in.readString()); this.message = MessageSerializer.fromString(in.readString());
} }
} }
@ -64,7 +65,7 @@ public class ServerCombatPacket implements Packet {
} else if(this.combatState == CombatState.ENTITY_DEAD) { } else if(this.combatState == CombatState.ENTITY_DEAD) {
out.writeVarInt(this.playerId); out.writeVarInt(this.playerId);
out.writeInt(this.entityId); out.writeInt(this.entityId);
out.writeString(this.message.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.message));
} }
} }

View file

@ -1,6 +1,7 @@
package com.github.steveice10.mc.protocol.packet.ingame.server; package com.github.steveice10.mc.protocol.packet.ingame.server;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -21,17 +22,17 @@ public class ServerDisconnectPacket implements Packet {
private @NonNull Message reason; private @NonNull Message reason;
public ServerDisconnectPacket(@NonNull String reason) { public ServerDisconnectPacket(@NonNull String reason) {
this(Message.fromString(reason)); this(MessageSerializer.fromString(reason));
} }
@Override @Override
public void read(NetInput in) throws IOException { public void read(NetInput in) throws IOException {
this.reason = Message.fromString(in.readString()); this.reason = MessageSerializer.fromString(in.readString());
} }
@Override @Override
public void write(NetOutput out) throws IOException { public void write(NetOutput out) throws IOException {
out.writeString(this.reason.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.reason));
} }
@Override @Override

View file

@ -1,6 +1,7 @@
package com.github.steveice10.mc.protocol.packet.ingame.server; package com.github.steveice10.mc.protocol.packet.ingame.server;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -23,14 +24,14 @@ public class ServerPlayerListDataPacket implements Packet {
@Override @Override
public void read(NetInput in) throws IOException { public void read(NetInput in) throws IOException {
this.header = Message.fromString(in.readString()); this.header = MessageSerializer.fromString(in.readString());
this.footer = Message.fromString(in.readString()); this.footer = MessageSerializer.fromString(in.readString());
} }
@Override @Override
public void write(NetOutput out) throws IOException { public void write(NetOutput out) throws IOException {
out.writeString(this.header.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.header));
out.writeString(this.footer.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.footer));
} }
@Override @Override

View file

@ -6,6 +6,7 @@ import com.github.steveice10.mc.protocol.data.game.PlayerListEntry;
import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction; import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -61,11 +62,11 @@ public class ServerPlayerListEntryPacket implements Packet {
profile.setProperties(propertyList); profile.setProperties(propertyList);
int rawGameMode = in.readVarInt(); int rawGameMode = in.readVarInt();
GameMode gameMode = MagicValues.key(GameMode.class, rawGameMode < 0 ? 0 : rawGameMode); GameMode gameMode = MagicValues.key(GameMode.class, Math.max(rawGameMode, 0));
int ping = in.readVarInt(); int ping = in.readVarInt();
Message displayName = null; Message displayName = null;
if(in.readBoolean()) { if(in.readBoolean()) {
displayName = Message.fromString(in.readString()); displayName = MessageSerializer.fromString(in.readString());
} }
entry = new PlayerListEntry(profile, gameMode, ping, displayName); entry = new PlayerListEntry(profile, gameMode, ping, displayName);
@ -73,7 +74,7 @@ public class ServerPlayerListEntryPacket implements Packet {
} }
case UPDATE_GAMEMODE: { case UPDATE_GAMEMODE: {
int rawGameMode = in.readVarInt(); int rawGameMode = in.readVarInt();
GameMode mode = MagicValues.key(GameMode.class, rawGameMode < 0 ? 0 : rawGameMode); GameMode mode = MagicValues.key(GameMode.class, Math.max(rawGameMode, 0));
entry = new PlayerListEntry(profile, mode); entry = new PlayerListEntry(profile, mode);
break; break;
@ -87,7 +88,7 @@ public class ServerPlayerListEntryPacket implements Packet {
case UPDATE_DISPLAY_NAME: { case UPDATE_DISPLAY_NAME: {
Message displayName = null; Message displayName = null;
if(in.readBoolean()) { if(in.readBoolean()) {
displayName = Message.fromString(in.readString()); displayName = MessageSerializer.fromString(in.readString());
} }
entry = new PlayerListEntry(profile, displayName); entry = new PlayerListEntry(profile, displayName);
@ -125,7 +126,7 @@ public class ServerPlayerListEntryPacket implements Packet {
out.writeVarInt(entry.getPing()); out.writeVarInt(entry.getPing());
out.writeBoolean(entry.getDisplayName() != null); out.writeBoolean(entry.getDisplayName() != null);
if(entry.getDisplayName() != null) { if(entry.getDisplayName() != null) {
out.writeString(entry.getDisplayName().toJsonString()); out.writeString(MessageSerializer.toJsonString(entry.getDisplayName()));
} }
break; break;
@ -138,7 +139,7 @@ public class ServerPlayerListEntryPacket implements Packet {
case UPDATE_DISPLAY_NAME: case UPDATE_DISPLAY_NAME:
out.writeBoolean(entry.getDisplayName() != null); out.writeBoolean(entry.getDisplayName() != null);
if(entry.getDisplayName() != null) { if(entry.getDisplayName() != null) {
out.writeString(entry.getDisplayName().toJsonString()); out.writeString(MessageSerializer.toJsonString(entry.getDisplayName()));
} }
break; break;

View file

@ -1,6 +1,7 @@
package com.github.steveice10.mc.protocol.packet.ingame.server; package com.github.steveice10.mc.protocol.packet.ingame.server;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -45,7 +46,7 @@ public class ServerTabCompletePacket implements Packet {
for(int index = 0; index < this.matches.length; index++) { for(int index = 0; index < this.matches.length; index++) {
this.matches[index] = in.readString(); this.matches[index] = in.readString();
if (in.readBoolean()) { if (in.readBoolean()) {
this.tooltips[index] = Message.fromString(in.readString()); this.tooltips[index] = MessageSerializer.fromString(in.readString());
} }
} }
} }
@ -61,7 +62,7 @@ public class ServerTabCompletePacket implements Packet {
Message tooltip = this.tooltips[index]; Message tooltip = this.tooltips[index];
if (tooltip != null) { if (tooltip != null) {
out.writeBoolean(true); out.writeBoolean(true);
out.writeString(tooltip.toJsonString()); out.writeString(MessageSerializer.toJsonString(tooltip));
} else { } else {
out.writeBoolean(false); out.writeBoolean(false);
} }

View file

@ -3,6 +3,7 @@ package com.github.steveice10.mc.protocol.packet.ingame.server;
import com.github.steveice10.mc.protocol.data.MagicValues; import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.TitleAction; import com.github.steveice10.mc.protocol.data.game.TitleAction;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -59,7 +60,7 @@ public class ServerTitlePacket implements Packet {
case TITLE: case TITLE:
case SUBTITLE: case SUBTITLE:
case ACTION_BAR: case ACTION_BAR:
this.title = Message.fromString(in.readString()); this.title = MessageSerializer.fromString(in.readString());
break; break;
case TIMES: case TIMES:
this.fadeIn = in.readInt(); this.fadeIn = in.readInt();
@ -79,7 +80,7 @@ public class ServerTitlePacket implements Packet {
case TITLE: case TITLE:
case SUBTITLE: case SUBTITLE:
case ACTION_BAR: case ACTION_BAR:
out.writeString(this.title.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.title));
break; break;
case TIMES: case TIMES:
out.writeInt(this.fadeIn); out.writeInt(this.fadeIn);

View file

@ -1,7 +1,6 @@
package com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn; package com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn;
import com.github.steveice10.mc.protocol.data.MagicValues; import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
import com.github.steveice10.mc.protocol.data.game.entity.object.FallingBlockData; import com.github.steveice10.mc.protocol.data.game.entity.object.FallingBlockData;
import com.github.steveice10.mc.protocol.data.game.entity.object.GenericObjectData; import com.github.steveice10.mc.protocol.data.game.entity.object.GenericObjectData;
import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection; import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection;
@ -9,6 +8,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.object.MinecartType;
import com.github.steveice10.mc.protocol.data.game.entity.object.ObjectData; import com.github.steveice10.mc.protocol.data.game.entity.object.ObjectData;
import com.github.steveice10.mc.protocol.data.game.entity.object.ProjectileData; import com.github.steveice10.mc.protocol.data.game.entity.object.ProjectileData;
import com.github.steveice10.mc.protocol.data.game.entity.object.SplashPotionData; import com.github.steveice10.mc.protocol.data.game.entity.object.SplashPotionData;
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;

View file

@ -2,8 +2,8 @@ package com.github.steveice10.mc.protocol.packet.ingame.server.entity.spawn;
import com.github.steveice10.mc.protocol.data.MagicValues; import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType;
import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection; import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection;
import com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;

View file

@ -4,6 +4,7 @@ import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.scoreboard.ObjectiveAction; import com.github.steveice10.mc.protocol.data.game.scoreboard.ObjectiveAction;
import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreType; import com.github.steveice10.mc.protocol.data.game.scoreboard.ScoreType;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -46,7 +47,7 @@ public class ServerScoreboardObjectivePacket implements Packet {
this.name = in.readString(); this.name = in.readString();
this.action = MagicValues.key(ObjectiveAction.class, in.readByte()); this.action = MagicValues.key(ObjectiveAction.class, in.readByte());
if(this.action == ObjectiveAction.ADD || this.action == ObjectiveAction.UPDATE) { if(this.action == ObjectiveAction.ADD || this.action == ObjectiveAction.UPDATE) {
this.displayName = Message.fromString(in.readString()); this.displayName = MessageSerializer.fromString(in.readString());
this.type = MagicValues.key(ScoreType.class, in.readVarInt()); this.type = MagicValues.key(ScoreType.class, in.readVarInt());
} }
} }
@ -56,7 +57,7 @@ public class ServerScoreboardObjectivePacket implements Packet {
out.writeString(this.name); out.writeString(this.name);
out.writeByte(MagicValues.value(Integer.class, this.action)); out.writeByte(MagicValues.value(Integer.class, this.action));
if(this.action == ObjectiveAction.ADD || this.action == ObjectiveAction.UPDATE) { if(this.action == ObjectiveAction.ADD || this.action == ObjectiveAction.UPDATE) {
out.writeString(this.displayName.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.displayName));
out.writeVarInt(MagicValues.value(Integer.class, this.type)); out.writeVarInt(MagicValues.value(Integer.class, this.type));
} }
} }

View file

@ -7,6 +7,7 @@ import com.github.steveice10.mc.protocol.data.game.scoreboard.NameTagVisibility;
import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamAction; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamAction;
import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor; import com.github.steveice10.mc.protocol.data.game.scoreboard.TeamColor;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -92,7 +93,7 @@ public class ServerTeamPacket implements Packet {
this.teamName = in.readString(); this.teamName = in.readString();
this.action = MagicValues.key(TeamAction.class, in.readByte()); this.action = MagicValues.key(TeamAction.class, in.readByte());
if(this.action == TeamAction.CREATE || this.action == TeamAction.UPDATE) { if(this.action == TeamAction.CREATE || this.action == TeamAction.UPDATE) {
this.displayName = Message.fromString(in.readString()); this.displayName = MessageSerializer.fromString(in.readString());
byte flags = in.readByte(); byte flags = in.readByte();
this.friendlyFire = (flags & 0x1) != 0; this.friendlyFire = (flags & 0x1) != 0;
this.seeFriendlyInvisibles = (flags & 0x2) != 0; this.seeFriendlyInvisibles = (flags & 0x2) != 0;
@ -105,8 +106,8 @@ public class ServerTeamPacket implements Packet {
this.color = TeamColor.NONE; this.color = TeamColor.NONE;
} }
this.prefix = Message.fromString(in.readString()); this.prefix = MessageSerializer.fromString(in.readString());
this.suffix = Message.fromString(in.readString()); this.suffix = MessageSerializer.fromString(in.readString());
} }
if(this.action == TeamAction.CREATE || this.action == TeamAction.ADD_PLAYER || this.action == TeamAction.REMOVE_PLAYER) { if(this.action == TeamAction.CREATE || this.action == TeamAction.ADD_PLAYER || this.action == TeamAction.REMOVE_PLAYER) {
@ -122,13 +123,13 @@ public class ServerTeamPacket implements Packet {
out.writeString(this.teamName); out.writeString(this.teamName);
out.writeByte(MagicValues.value(Integer.class, this.action)); out.writeByte(MagicValues.value(Integer.class, this.action));
if(this.action == TeamAction.CREATE || this.action == TeamAction.UPDATE) { if(this.action == TeamAction.CREATE || this.action == TeamAction.UPDATE) {
out.writeString(this.displayName.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.displayName));
out.writeByte((this.friendlyFire ? 0x1 : 0x0) | (this.seeFriendlyInvisibles ? 0x2 : 0x0)); out.writeByte((this.friendlyFire ? 0x1 : 0x0) | (this.seeFriendlyInvisibles ? 0x2 : 0x0));
out.writeString(MagicValues.value(String.class, this.nameTagVisibility)); out.writeString(MagicValues.value(String.class, this.nameTagVisibility));
out.writeString(MagicValues.value(String.class, this.collisionRule)); out.writeString(MagicValues.value(String.class, this.collisionRule));
out.writeVarInt(MagicValues.value(Integer.class, this.color)); out.writeVarInt(MagicValues.value(Integer.class, this.color));
out.writeString(this.prefix.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.prefix));
out.writeString(this.suffix.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.suffix));
} }
if(this.action == TeamAction.CREATE || this.action == TeamAction.ADD_PLAYER || this.action == TeamAction.REMOVE_PLAYER) { if(this.action == TeamAction.CREATE || this.action == TeamAction.ADD_PLAYER || this.action == TeamAction.REMOVE_PLAYER) {

View file

@ -8,7 +8,6 @@ import lombok.AccessLevel;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter; import lombok.Setter;
import java.io.IOException; import java.io.IOException;

View file

@ -5,6 +5,7 @@ import com.github.steveice10.mc.protocol.data.game.world.map.MapData;
import com.github.steveice10.mc.protocol.data.game.world.map.MapIcon; import com.github.steveice10.mc.protocol.data.game.world.map.MapIcon;
import com.github.steveice10.mc.protocol.data.game.world.map.MapIconType; import com.github.steveice10.mc.protocol.data.game.world.map.MapIconType;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -48,7 +49,7 @@ public class ServerMapDataPacket implements Packet {
int rotation = in.readUnsignedByte(); int rotation = in.readUnsignedByte();
Message displayName = null; Message displayName = null;
if(in.readBoolean()) { if(in.readBoolean()) {
displayName = Message.fromString(in.readString()); displayName = MessageSerializer.fromString(in.readString());
} }
this.icons[index] = new MapIcon(x, z, MagicValues.key(MapIconType.class, type), rotation, displayName); this.icons[index] = new MapIcon(x, z, MagicValues.key(MapIconType.class, type), rotation, displayName);
@ -81,7 +82,7 @@ public class ServerMapDataPacket implements Packet {
out.writeByte(icon.getIconRotation()); out.writeByte(icon.getIconRotation());
if (icon.getDisplayName() != null) { if (icon.getDisplayName() != null) {
out.writeBoolean(false); out.writeBoolean(false);
out.writeString(icon.getDisplayName().toJsonString()); out.writeString(MessageSerializer.toJsonString(icon.getDisplayName()));
} else { } else {
out.writeBoolean(true); out.writeBoolean(true);
} }

View file

@ -2,7 +2,13 @@ package com.github.steveice10.mc.protocol.packet.ingame.server.world;
import com.github.steveice10.mc.protocol.data.MagicValues; import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.world.notify.*; import com.github.steveice10.mc.protocol.data.game.world.notify.ClientNotification;
import com.github.steveice10.mc.protocol.data.game.world.notify.ClientNotificationValue;
import com.github.steveice10.mc.protocol.data.game.world.notify.DemoMessageValue;
import com.github.steveice10.mc.protocol.data.game.world.notify.EnterCreditsValue;
import com.github.steveice10.mc.protocol.data.game.world.notify.RainStrengthValue;
import com.github.steveice10.mc.protocol.data.game.world.notify.RespawnScreenValue;
import com.github.steveice10.mc.protocol.data.game.world.notify.ThunderStrengthValue;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;

View file

@ -1,6 +1,7 @@
package com.github.steveice10.mc.protocol.packet.login.server; package com.github.steveice10.mc.protocol.packet.login.server;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.packetlib.io.NetInput; import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput; import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet; import com.github.steveice10.packetlib.packet.Packet;
@ -21,17 +22,17 @@ public class LoginDisconnectPacket implements Packet {
private @NonNull Message reason; private @NonNull Message reason;
public LoginDisconnectPacket(String text) { public LoginDisconnectPacket(String text) {
this(Message.fromString(text)); this(MessageSerializer.fromString(text));
} }
@Override @Override
public void read(NetInput in) throws IOException { public void read(NetInput in) throws IOException {
this.reason = Message.fromString(in.readString()); this.reason = MessageSerializer.fromString(in.readString());
} }
@Override @Override
public void write(NetOutput out) throws IOException { public void write(NetOutput out) throws IOException {
out.writeString(this.reason.toJsonString()); out.writeString(MessageSerializer.toJsonString(this.reason));
} }
@Override @Override

View file

@ -3,6 +3,7 @@ package com.github.steveice10.mc.protocol.packet.status.server;
import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.data.GameProfile;
import com.github.steveice10.mc.auth.util.Base64; import com.github.steveice10.mc.auth.util.Base64;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.Message;
import com.github.steveice10.mc.protocol.data.message.MessageSerializer;
import com.github.steveice10.mc.protocol.data.status.PlayerInfo; import com.github.steveice10.mc.protocol.data.status.PlayerInfo;
import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo; import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo;
import com.github.steveice10.mc.protocol.data.status.VersionInfo; import com.github.steveice10.mc.protocol.data.status.VersionInfo;
@ -50,7 +51,7 @@ public class StatusResponsePacket implements Packet {
PlayerInfo players = new PlayerInfo(plrs.get("max").getAsInt(), plrs.get("online").getAsInt(), profiles); PlayerInfo players = new PlayerInfo(plrs.get("max").getAsInt(), plrs.get("online").getAsInt(), profiles);
JsonElement desc = obj.get("description"); JsonElement desc = obj.get("description");
Message description = Message.fromJson(desc); Message description = MessageSerializer.fromJson(desc);
byte[] icon = null; byte[] icon = null;
if(obj.has("favicon")) { if(obj.has("favicon")) {
icon = this.stringToIcon(obj.get("favicon").getAsString()); icon = this.stringToIcon(obj.get("favicon").getAsString());
@ -82,7 +83,7 @@ public class StatusResponsePacket implements Packet {
obj.add("version", ver); obj.add("version", ver);
obj.add("players", plrs); obj.add("players", plrs);
obj.add("description", this.info.getDescription().toJson()); obj.add("description", MessageSerializer.toJson(this.info.getDescription()));
if(this.info.getIconPng() != null) { if(this.info.getIconPng() != null) {
obj.addProperty("favicon", this.iconToString(this.info.getIconPng())); obj.addProperty("favicon", this.iconToString(this.info.getIconPng()));
} }

View file

@ -42,7 +42,7 @@ public class MinecraftProtocolTest {
private static final ServerStatusInfo SERVER_INFO = new ServerStatusInfo( private static final ServerStatusInfo SERVER_INFO = new ServerStatusInfo(
VersionInfo.CURRENT, VersionInfo.CURRENT,
new PlayerInfo(100, 0, new GameProfile[0]), new PlayerInfo(100, 0, new GameProfile[0]),
new TextMessage("Hello world!"), new TextMessage.Builder().text("Hello world!").build(),
null null
); );
private static final ServerJoinGamePacket JOIN_GAME_PACKET = new ServerJoinGamePacket(0, false, GameMode.SURVIVAL, 0, 100, 0, DEFAULT, 16, false, false); private static final ServerJoinGamePacket JOIN_GAME_PACKET = new ServerJoinGamePacket(0, false, GameMode.SURVIVAL, 0, 100, 0, DEFAULT, 16, false, false);

View file

@ -23,6 +23,8 @@ import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierOper
import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierType; import com.github.steveice10.mc.protocol.data.game.entity.attribute.ModifierType;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose; import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection;
import com.github.steveice10.mc.protocol.data.game.entity.object.MinecartType;
import com.github.steveice10.mc.protocol.data.game.entity.player.Animation; import com.github.steveice10.mc.protocol.data.game.entity.player.Animation;
import com.github.steveice10.mc.protocol.data.game.entity.player.BlockBreakStage; import com.github.steveice10.mc.protocol.data.game.entity.player.BlockBreakStage;
import com.github.steveice10.mc.protocol.data.game.entity.player.CombatState; import com.github.steveice10.mc.protocol.data.game.entity.player.CombatState;
@ -32,11 +34,9 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState; import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerState;
import com.github.steveice10.mc.protocol.data.game.entity.player.PositionElement; import com.github.steveice10.mc.protocol.data.game.entity.player.PositionElement;
import com.github.steveice10.mc.protocol.data.game.entity.type.WeatherEntityType;
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType; import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
import com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType; import com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType;
import com.github.steveice10.mc.protocol.data.game.entity.object.HangingDirection; import com.github.steveice10.mc.protocol.data.game.entity.type.WeatherEntityType;
import com.github.steveice10.mc.protocol.data.game.entity.object.MinecartType;
import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType; import com.github.steveice10.mc.protocol.data.game.recipe.RecipeType;
import com.github.steveice10.mc.protocol.data.game.scoreboard.CollisionRule; import com.github.steveice10.mc.protocol.data.game.scoreboard.CollisionRule;
import com.github.steveice10.mc.protocol.data.game.scoreboard.NameTagVisibility; import com.github.steveice10.mc.protocol.data.game.scoreboard.NameTagVisibility;

View file

@ -28,7 +28,7 @@ public abstract class PacketTest {
Packet decoded = this.createPacket(packet.getClass()); Packet decoded = this.createPacket(packet.getClass());
decoded.read(new StreamNetInput(new ByteArrayInputStream(encoded))); decoded.read(new StreamNetInput(new ByteArrayInputStream(encoded)));
assertEquals("Decoded packet does not match original.", packet, decoded); assertEquals("Decoded packet does not match original: " + packet + " vs " + decoded, packet, decoded);
} }
} }

View file

@ -1,6 +1,6 @@
package com.github.steveice10.mc.protocol.packet.login.server; package com.github.steveice10.mc.protocol.packet.login.server;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.TextMessage;
import com.github.steveice10.mc.protocol.packet.PacketTest; import com.github.steveice10.mc.protocol.packet.PacketTest;
import org.junit.Before; import org.junit.Before;
@ -8,6 +8,6 @@ public class LoginDisconnectPacketTest extends PacketTest {
@Before @Before
public void setup() { public void setup() {
this.setPackets(new LoginDisconnectPacket("Message"), this.setPackets(new LoginDisconnectPacket("Message"),
new LoginDisconnectPacket(Message.fromString("Message"))); new LoginDisconnectPacket(new TextMessage.Builder().text("Message").build()));
} }
} }

View file

@ -1,7 +1,7 @@
package com.github.steveice10.mc.protocol.packet.status.server; package com.github.steveice10.mc.protocol.packet.status.server;
import com.github.steveice10.mc.auth.data.GameProfile; import com.github.steveice10.mc.auth.data.GameProfile;
import com.github.steveice10.mc.protocol.data.message.Message; import com.github.steveice10.mc.protocol.data.message.TextMessage;
import com.github.steveice10.mc.protocol.data.status.PlayerInfo; import com.github.steveice10.mc.protocol.data.status.PlayerInfo;
import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo; import com.github.steveice10.mc.protocol.data.status.ServerStatusInfo;
import com.github.steveice10.mc.protocol.data.status.VersionInfo; import com.github.steveice10.mc.protocol.data.status.VersionInfo;
@ -19,7 +19,7 @@ public class StatusResponsePacketTest extends PacketTest {
new PlayerInfo(100, 10, new GameProfile[] { new PlayerInfo(100, 10, new GameProfile[] {
new GameProfile(UUID.randomUUID(), "Username") new GameProfile(UUID.randomUUID(), "Username")
}), }),
Message.fromString("Description"), new TextMessage.Builder().text("Description").build(),
null null
) )
)); ));