diff --git a/pom.xml b/pom.xml
index 4f79490..07f83fb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.loohp
Limbo
Limbo
- 0.6.2-ALPHA
+ 0.6.3-ALPHA
Standalone Limbo Minecraft Server.
https://github.com/LOOHP/Limbo
diff --git a/src/main/java/com/loohp/limbo/events/player/PlayerResourcePackStatusEvent.java b/src/main/java/com/loohp/limbo/events/player/PlayerResourcePackStatusEvent.java
index 0c41004..91ecb8d 100644
--- a/src/main/java/com/loohp/limbo/events/player/PlayerResourcePackStatusEvent.java
+++ b/src/main/java/com/loohp/limbo/events/player/PlayerResourcePackStatusEvent.java
@@ -12,6 +12,7 @@ public class PlayerResourcePackStatusEvent extends PlayerEvent {
super(player);
}
+ @Override
public Player getPlayer() {
return player;
}
diff --git a/src/main/java/com/loohp/limbo/file/ServerProperties.java b/src/main/java/com/loohp/limbo/file/ServerProperties.java
index c16cc40..c6a2828 100644
--- a/src/main/java/com/loohp/limbo/file/ServerProperties.java
+++ b/src/main/java/com/loohp/limbo/file/ServerProperties.java
@@ -50,10 +50,10 @@ public class ServerProperties {
private double ticksPerSecond;
private boolean handshakeVerbose;
- private String resourcePackSHA;
+ private String resourcePackSHA1;
private String resourcePackLink;
private boolean resourcePackRequired;
- private String resourcePackPrompt;
+ private String resourcePackPromptJson;
Optional favicon;
@@ -129,9 +129,9 @@ public class ServerProperties {
handshakeVerbose = Boolean.parseBoolean(prop.getProperty("handshake-verbose"));
resourcePackLink = prop.getProperty("resource-pack");
- resourcePackSHA = prop.getProperty("resource-pack-sha1");
+ resourcePackSHA1 = prop.getProperty("resource-pack-sha1");
resourcePackRequired = Boolean.parseBoolean(prop.getProperty("required-resource-pack"));
- resourcePackPrompt = prop.getProperty("resource-pack-prompt");
+ resourcePackPromptJson = prop.getProperty("resource-pack-prompt");
File png = new File("server-icon.png");
if (png.exists()) {
@@ -257,16 +257,16 @@ public class ServerProperties {
return resourcePackLink;
}
- public String getResourcePackSHA() {
- return resourcePackSHA;
+ public String getResourcePackSHA1() {
+ return resourcePackSHA1;
}
public boolean getResourcePackRequired() {
return resourcePackRequired;
}
- public String getResourcePackPrompt() {
- return resourcePackPrompt;
+ public String getResourcePackPromptJson() {
+ return resourcePackPromptJson;
}
}
diff --git a/src/main/java/com/loohp/limbo/player/Player.java b/src/main/java/com/loohp/limbo/player/Player.java
index 71ab2d1..e24d9fe 100644
--- a/src/main/java/com/loohp/limbo/player/Player.java
+++ b/src/main/java/com/loohp/limbo/player/Player.java
@@ -24,9 +24,12 @@ import com.loohp.limbo.utils.GameMode;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
+import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public class Player extends LivingEntity implements CommandSender {
+
+ public static final String CHAT_DEFAULT_FORMAT = "<%name%> %message%";
public final ClientConnection clientConnection;
public final PlayerInteractManager playerInteractManager;
@@ -200,7 +203,7 @@ public class Player extends LivingEntity implements CommandSender {
}
public void sendMessage(BaseComponent component, UUID uuid) {
- sendMessage(new BaseComponent[] { component }, uuid);
+ sendMessage(new BaseComponent[] {component}, uuid);
}
@Override
@@ -218,7 +221,7 @@ public class Player extends LivingEntity implements CommandSender {
}
public void sendMessage(BaseComponent component) {
- sendMessage(new BaseComponent[] { component });
+ sendMessage(new BaseComponent[] {component});
}
@Override
@@ -232,7 +235,7 @@ public class Player extends LivingEntity implements CommandSender {
}
public void disconnect() {
- disconnect("Disconnected!");
+ disconnect(new TranslatableComponent("multiplayer.disconnect.kicked"));
}
public void disconnect(String reason) {
@@ -249,24 +252,31 @@ public class Player extends LivingEntity implements CommandSender {
public void chat(String message) {
if (Limbo.getInstance().getServerProperties().isAllowChat()) {
- String format = "<%name%> %message%";
- PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, format, message, false));
+ PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, CHAT_DEFAULT_FORMAT, message, false));
if (!event.isCancelled() && this.hasPermission("limboserver.chat")) {
String chat = event.getFormat().replace("%name%", username).replace("%message%", event.getMessage());
Limbo.getInstance().getConsole().sendMessage(chat);
- for (Player each : Limbo.getInstance().getPlayers()) {
- each.sendMessage(chat, uuid);
+ if (event.getFormat().equals(CHAT_DEFAULT_FORMAT)) {
+ TranslatableComponent translatable = new TranslatableComponent("chat.type.text", username, event.getMessage());
+ for (Player each : Limbo.getInstance().getPlayers()) {
+ each.sendMessage(translatable, uuid);
+ }
+ } else {
+ for (Player each : Limbo.getInstance().getPlayers()) {
+ each.sendMessage(chat, uuid);
+ }
}
}
}
}
+ public void setResourcePack(String url, String hash, boolean forced, BaseComponent promptmessage) {
+ setResourcePack(url, hash, forced, new BaseComponent[] {promptmessage});
+ }
public void setResourcePack(String url, String hash, boolean forced, BaseComponent[] promptmessage) {
try {
- PacketPlayOutResourcePackSend packsend = new PacketPlayOutResourcePackSend(url, hash, forced,
- (promptmessage != null || !ComponentSerializer.toString(promptmessage).equalsIgnoreCase("")) ? true : false,
- ComponentSerializer.toString(promptmessage));
+ PacketPlayOutResourcePackSend packsend = new PacketPlayOutResourcePackSend(url, hash, forced, promptmessage != null, promptmessage != null ? promptmessage : null);
clientConnection.sendPacket(packsend);
} catch (IOException e) {
e.printStackTrace();
diff --git a/src/main/java/com/loohp/limbo/server/ClientConnection.java b/src/main/java/com/loohp/limbo/server/ClientConnection.java
index e9d31b7..6e284f4 100644
--- a/src/main/java/com/loohp/limbo/server/ClientConnection.java
+++ b/src/main/java/com/loohp/limbo/server/ClientConnection.java
@@ -47,6 +47,7 @@ import com.loohp.limbo.server.packets.PacketPlayInKeepAlive;
import com.loohp.limbo.server.packets.PacketPlayInPosition;
import com.loohp.limbo.server.packets.PacketPlayInPositionAndLook;
import com.loohp.limbo.server.packets.PacketPlayInResourcePackStatus;
+import com.loohp.limbo.server.packets.PacketPlayInResourcePackStatus.EnumResourcePackStatus;
import com.loohp.limbo.server.packets.PacketPlayInRotation;
import com.loohp.limbo.server.packets.PacketPlayInTabComplete;
import com.loohp.limbo.server.packets.PacketPlayOutDeclareCommands;
@@ -85,6 +86,7 @@ import com.loohp.limbo.world.World;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
+import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer;
public class ClientConnection extends Thread {
@@ -420,11 +422,11 @@ public class ClientConnection extends Thread {
}
if (properties.getResourcePackLink() != null && !properties.getResourcePackLink().equalsIgnoreCase("")) {
- if (properties.getResourcePackSHA() != null && !properties.getResourcePackSHA().equalsIgnoreCase("")) {
+ if (properties.getResourcePackSHA1() != null && !properties.getResourcePackSHA1().equalsIgnoreCase("")) {
//SEND RESOURCEPACK
player.setResourcePack(properties.getResourcePackLink(),
- properties.getResourcePackSHA(), properties.getResourcePackRequired(),
- ComponentSerializer.parse(properties.getResourcePackPrompt()));
+ properties.getResourcePackSHA1(), properties.getResourcePackRequired(),
+ ComponentSerializer.parse(properties.getResourcePackPromptJson()));
} else {
//NO SHA
Limbo.getInstance().getConsole().sendMessage("ResourcePacks require SHA1s");
@@ -531,6 +533,9 @@ public class ClientConnection extends Thread {
PacketPlayInResourcePackStatus rpcheck = new PacketPlayInResourcePackStatus(input);
// Pass on result to the events
Limbo.getInstance().getEventsManager().callEvent(new PlayerResourcePackStatusEvent(player, rpcheck.getLoadedValue()));
+ if (rpcheck.getLoadedValue().equals(EnumResourcePackStatus.DECLINED) && properties.getResourcePackRequired()) {
+ player.disconnect(new TranslatableComponent("multiplayer.requiredTexturePrompt.disconnect"));
+ }
} else {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
}
diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInResourcePackStatus.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInResourcePackStatus.java
index 1f98a6d..1e5b9d4 100644
--- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayInResourcePackStatus.java
+++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInResourcePackStatus.java
@@ -7,36 +7,40 @@ import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayInResourcePackStatus extends PacketIn {
-
- public enum EnumResourcePackStatus {
+ public static enum EnumResourcePackStatus {
SUCCESS,
DECLINED,
FAILED,
ACCEPTED;
}
- private int loaded;
+ private EnumResourcePackStatus loaded;
- public PacketPlayInResourcePackStatus(int loaded) {
+ public PacketPlayInResourcePackStatus(EnumResourcePackStatus loaded) {
this.loaded = loaded;
}
public PacketPlayInResourcePackStatus(DataInputStream in) throws IOException {
- this(DataTypeIO.readVarInt(in));
- }
-
- public EnumResourcePackStatus getLoadedValue() {
- switch (loaded) {
- case 0: return EnumResourcePackStatus.SUCCESS;
- case 1: return EnumResourcePackStatus.DECLINED;
- case 2: return EnumResourcePackStatus.FAILED;
- case 3: return EnumResourcePackStatus.ACCEPTED;
- default: return EnumResourcePackStatus.FAILED;
- }
+ this(toLoadedValue(DataTypeIO.readVarInt(in)));
}
- public boolean isLoadedValue(EnumResourcePackStatus status) {
- return getLoadedValue() == status;
+ public EnumResourcePackStatus getLoadedValue() {
+ return loaded;
+ }
+
+ private static EnumResourcePackStatus toLoadedValue(int value) {
+ switch (value) {
+ case 0:
+ return EnumResourcePackStatus.SUCCESS;
+ case 1:
+ return EnumResourcePackStatus.DECLINED;
+ case 2:
+ return EnumResourcePackStatus.FAILED;
+ case 3:
+ return EnumResourcePackStatus.ACCEPTED;
+ default:
+ return EnumResourcePackStatus.FAILED;
+ }
}
}
diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutResourcePackSend.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutResourcePackSend.java
index f0e2bd9..2da6c0e 100644
--- a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutResourcePackSend.java
+++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutResourcePackSend.java
@@ -7,19 +7,30 @@ import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO;
+import net.md_5.bungee.api.chat.BaseComponent;
+import net.md_5.bungee.chat.ComponentSerializer;
+
public class PacketPlayOutResourcePackSend extends PacketOut {
+ public static final int MAX_HASH_LENGTH = 40;
+
private String url;
private String hash;
private boolean isForced;
private boolean hasPromptMessage;
- private String promptMessage;
+ private BaseComponent[] promptMessage;
- public PacketPlayOutResourcePackSend(String url, String hash, boolean isForced, boolean hasPromptMessage, String promptMessage) {
+ public PacketPlayOutResourcePackSend(String url, String hash, boolean isForced, boolean hasPromptMessage, BaseComponent[] promptMessage) {
+ if (hash.length() > MAX_HASH_LENGTH) {
+ throw new IllegalArgumentException("Hash is too long (max " + MAX_HASH_LENGTH + ", was " + hash.length() + ")");
+ }
this.url = url;
this.hash = hash;
this.isForced = isForced;
this.hasPromptMessage = hasPromptMessage;
+ if (hasPromptMessage && promptMessage == null) {
+ throw new IllegalArgumentException("promptMessage cannot be null when hasPromptMessage is true");
+ }
this.promptMessage = promptMessage;
}
@@ -39,7 +50,7 @@ public class PacketPlayOutResourcePackSend extends PacketOut {
return hasPromptMessage;
}
- public String getPromptMessage() {
+ public BaseComponent[] getPromptMessage() {
return promptMessage;
}
@@ -54,7 +65,7 @@ public class PacketPlayOutResourcePackSend extends PacketOut {
output.writeBoolean(isForced);
output.writeBoolean(hasPromptMessage);
if (hasPromptMessage) {
- DataTypeIO.writeString(output, promptMessage, StandardCharsets.UTF_8);
+ DataTypeIO.writeString(output, ComponentSerializer.toString(promptMessage), StandardCharsets.UTF_8);
}
return buffer.toByteArray();
}
diff --git a/src/main/resources/mapping.json b/src/main/resources/mapping.json
index 76341ff..6dde965 100644
--- a/src/main/resources/mapping.json
+++ b/src/main/resources/mapping.json
@@ -19,7 +19,8 @@
"0x13": "PacketPlayInRotation",
"0x0A": "PacketPlayInPluginMessaging",
"0x06": "PacketPlayInTabComplete",
- "0x25": "PacketPlayInHeldItemChange"
+ "0x25": "PacketPlayInHeldItemChange",
+ "0x21": "PacketPlayInResourcePackStatus"
},
"PlayOut": {
"PacketPlayOutLogin": "0x26",
@@ -43,7 +44,8 @@
"PacketPlayOutEntityMetadata": "0x4D",
"PacketPlayOutSpawnEntity": "0x00",
"PacketPlayOutSpawnEntityLiving": "0x02",
- "PacketPlayOutHeldItemChange": "0x48"
+ "PacketPlayOutHeldItemChange": "0x48",
+ "PacketPlayOutResourcePackSend": "0x3C"
},
"StatusIn": {
"0x01": "PacketStatusInPing",
diff --git a/src/main/resources/server.properties b/src/main/resources/server.properties
index bdf62be..9b0c5d6 100644
--- a/src/main/resources/server.properties
+++ b/src/main/resources/server.properties
@@ -57,4 +57,16 @@ handshake-verbose=true
motd={"text":"","extra":[{"text":"Limbo Server!","color":"yellow"}]}
#Server list version as string
-version=Limbo!
\ No newline at end of file
+version=Limbo!
+
+#Server resource pack url (May be left blank)
+resource-pack=
+
+#Server resource pack hash (May be left blank)
+resource-pack-sha1=
+
+#Whether to kick players if they do not accept the server resource pack
+required-resource-pack=false
+
+#JSON formatted text to show when prompting the player to install the resource pack (May be left blank)
+resource-pack-prompt={"text":"","extra":[{"text":"Install server resource pack!","color":"yellow"}]}
\ No newline at end of file