Polish resource pack support

This commit is contained in:
LOOHP 2021-11-22 01:16:20 +00:00
parent 7ce2c6b194
commit d86bcdb48d
9 changed files with 91 additions and 46 deletions

View File

@ -5,7 +5,7 @@
<groupId>com.loohp</groupId> <groupId>com.loohp</groupId>
<artifactId>Limbo</artifactId> <artifactId>Limbo</artifactId>
<name>Limbo</name> <name>Limbo</name>
<version>0.6.2-ALPHA</version> <version>0.6.3-ALPHA</version>
<description>Standalone Limbo Minecraft Server.</description> <description>Standalone Limbo Minecraft Server.</description>
<url>https://github.com/LOOHP/Limbo</url> <url>https://github.com/LOOHP/Limbo</url>

View File

@ -12,6 +12,7 @@ public class PlayerResourcePackStatusEvent extends PlayerEvent {
super(player); super(player);
} }
@Override
public Player getPlayer() { public Player getPlayer() {
return player; return player;
} }

View File

@ -50,10 +50,10 @@ public class ServerProperties {
private double ticksPerSecond; private double ticksPerSecond;
private boolean handshakeVerbose; private boolean handshakeVerbose;
private String resourcePackSHA; private String resourcePackSHA1;
private String resourcePackLink; private String resourcePackLink;
private boolean resourcePackRequired; private boolean resourcePackRequired;
private String resourcePackPrompt; private String resourcePackPromptJson;
Optional<BufferedImage> favicon; Optional<BufferedImage> favicon;
@ -129,9 +129,9 @@ public class ServerProperties {
handshakeVerbose = Boolean.parseBoolean(prop.getProperty("handshake-verbose")); handshakeVerbose = Boolean.parseBoolean(prop.getProperty("handshake-verbose"));
resourcePackLink = prop.getProperty("resource-pack"); 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")); 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"); File png = new File("server-icon.png");
if (png.exists()) { if (png.exists()) {
@ -257,16 +257,16 @@ public class ServerProperties {
return resourcePackLink; return resourcePackLink;
} }
public String getResourcePackSHA() { public String getResourcePackSHA1() {
return resourcePackSHA; return resourcePackSHA1;
} }
public boolean getResourcePackRequired() { public boolean getResourcePackRequired() {
return resourcePackRequired; return resourcePackRequired;
} }
public String getResourcePackPrompt() { public String getResourcePackPromptJson() {
return resourcePackPrompt; return resourcePackPromptJson;
} }
} }

View File

@ -24,10 +24,13 @@ import com.loohp.limbo.utils.GameMode;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.chat.ComponentSerializer;
public class Player extends LivingEntity implements CommandSender { public class Player extends LivingEntity implements CommandSender {
public static final String CHAT_DEFAULT_FORMAT = "<%name%> %message%";
public final ClientConnection clientConnection; public final ClientConnection clientConnection;
public final PlayerInteractManager playerInteractManager; public final PlayerInteractManager playerInteractManager;
@ -232,7 +235,7 @@ public class Player extends LivingEntity implements CommandSender {
} }
public void disconnect() { public void disconnect() {
disconnect("Disconnected!"); disconnect(new TranslatableComponent("multiplayer.disconnect.kicked"));
} }
public void disconnect(String reason) { public void disconnect(String reason) {
@ -249,24 +252,31 @@ public class Player extends LivingEntity implements CommandSender {
public void chat(String message) { public void chat(String message) {
if (Limbo.getInstance().getServerProperties().isAllowChat()) { if (Limbo.getInstance().getServerProperties().isAllowChat()) {
String format = "<%name%> %message%"; PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, CHAT_DEFAULT_FORMAT, message, false));
PlayerChatEvent event = (PlayerChatEvent) Limbo.getInstance().getEventsManager().callEvent(new PlayerChatEvent(this, format, message, false));
if (!event.isCancelled() && this.hasPermission("limboserver.chat")) { if (!event.isCancelled() && this.hasPermission("limboserver.chat")) {
String chat = event.getFormat().replace("%name%", username).replace("%message%", event.getMessage()); String chat = event.getFormat().replace("%name%", username).replace("%message%", event.getMessage());
Limbo.getInstance().getConsole().sendMessage(chat); Limbo.getInstance().getConsole().sendMessage(chat);
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()) { for (Player each : Limbo.getInstance().getPlayers()) {
each.sendMessage(chat, uuid); 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) { public void setResourcePack(String url, String hash, boolean forced, BaseComponent[] promptmessage) {
try { try {
PacketPlayOutResourcePackSend packsend = new PacketPlayOutResourcePackSend(url, hash, forced, PacketPlayOutResourcePackSend packsend = new PacketPlayOutResourcePackSend(url, hash, forced, promptmessage != null, promptmessage != null ? promptmessage : null);
(promptmessage != null || !ComponentSerializer.toString(promptmessage).equalsIgnoreCase("")) ? true : false,
ComponentSerializer.toString(promptmessage));
clientConnection.sendPacket(packsend); clientConnection.sendPacket(packsend);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -47,6 +47,7 @@ import com.loohp.limbo.server.packets.PacketPlayInKeepAlive;
import com.loohp.limbo.server.packets.PacketPlayInPosition; import com.loohp.limbo.server.packets.PacketPlayInPosition;
import com.loohp.limbo.server.packets.PacketPlayInPositionAndLook; import com.loohp.limbo.server.packets.PacketPlayInPositionAndLook;
import com.loohp.limbo.server.packets.PacketPlayInResourcePackStatus; 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.PacketPlayInRotation;
import com.loohp.limbo.server.packets.PacketPlayInTabComplete; import com.loohp.limbo.server.packets.PacketPlayInTabComplete;
import com.loohp.limbo.server.packets.PacketPlayOutDeclareCommands; 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.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.chat.ComponentSerializer;
public class ClientConnection extends Thread { public class ClientConnection extends Thread {
@ -420,11 +422,11 @@ public class ClientConnection extends Thread {
} }
if (properties.getResourcePackLink() != null && !properties.getResourcePackLink().equalsIgnoreCase("")) { if (properties.getResourcePackLink() != null && !properties.getResourcePackLink().equalsIgnoreCase("")) {
if (properties.getResourcePackSHA() != null && !properties.getResourcePackSHA().equalsIgnoreCase("")) { if (properties.getResourcePackSHA1() != null && !properties.getResourcePackSHA1().equalsIgnoreCase("")) {
//SEND RESOURCEPACK //SEND RESOURCEPACK
player.setResourcePack(properties.getResourcePackLink(), player.setResourcePack(properties.getResourcePackLink(),
properties.getResourcePackSHA(), properties.getResourcePackRequired(), properties.getResourcePackSHA1(), properties.getResourcePackRequired(),
ComponentSerializer.parse(properties.getResourcePackPrompt())); ComponentSerializer.parse(properties.getResourcePackPromptJson()));
} else { } else {
//NO SHA //NO SHA
Limbo.getInstance().getConsole().sendMessage("ResourcePacks require SHA1s"); Limbo.getInstance().getConsole().sendMessage("ResourcePacks require SHA1s");
@ -531,6 +533,9 @@ public class ClientConnection extends Thread {
PacketPlayInResourcePackStatus rpcheck = new PacketPlayInResourcePackStatus(input); PacketPlayInResourcePackStatus rpcheck = new PacketPlayInResourcePackStatus(input);
// Pass on result to the events // Pass on result to the events
Limbo.getInstance().getEventsManager().callEvent(new PlayerResourcePackStatusEvent(player, rpcheck.getLoadedValue())); 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 { } else {
input.skipBytes(size - DataTypeIO.getVarIntLength(packetId)); input.skipBytes(size - DataTypeIO.getVarIntLength(packetId));
} }

View File

@ -7,36 +7,40 @@ import com.loohp.limbo.utils.DataTypeIO;
public class PacketPlayInResourcePackStatus extends PacketIn { public class PacketPlayInResourcePackStatus extends PacketIn {
public static enum EnumResourcePackStatus {
public enum EnumResourcePackStatus {
SUCCESS, SUCCESS,
DECLINED, DECLINED,
FAILED, FAILED,
ACCEPTED; ACCEPTED;
} }
private int loaded; private EnumResourcePackStatus loaded;
public PacketPlayInResourcePackStatus(int loaded) { public PacketPlayInResourcePackStatus(EnumResourcePackStatus loaded) {
this.loaded = loaded; this.loaded = loaded;
} }
public PacketPlayInResourcePackStatus(DataInputStream in) throws IOException { public PacketPlayInResourcePackStatus(DataInputStream in) throws IOException {
this(DataTypeIO.readVarInt(in)); this(toLoadedValue(DataTypeIO.readVarInt(in)));
} }
public EnumResourcePackStatus getLoadedValue() { public EnumResourcePackStatus getLoadedValue() {
switch (loaded) { return loaded;
case 0: return EnumResourcePackStatus.SUCCESS; }
case 1: return EnumResourcePackStatus.DECLINED;
case 2: return EnumResourcePackStatus.FAILED; private static EnumResourcePackStatus toLoadedValue(int value) {
case 3: return EnumResourcePackStatus.ACCEPTED; switch (value) {
default: return EnumResourcePackStatus.FAILED; case 0:
return EnumResourcePackStatus.SUCCESS;
case 1:
return EnumResourcePackStatus.DECLINED;
case 2:
return EnumResourcePackStatus.FAILED;
case 3:
return EnumResourcePackStatus.ACCEPTED;
default:
return EnumResourcePackStatus.FAILED;
} }
} }
public boolean isLoadedValue(EnumResourcePackStatus status) {
return getLoadedValue() == status;
}
} }

View File

@ -7,19 +7,30 @@ import java.nio.charset.StandardCharsets;
import com.loohp.limbo.utils.DataTypeIO; 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 class PacketPlayOutResourcePackSend extends PacketOut {
public static final int MAX_HASH_LENGTH = 40;
private String url; private String url;
private String hash; private String hash;
private boolean isForced; private boolean isForced;
private boolean hasPromptMessage; 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.url = url;
this.hash = hash; this.hash = hash;
this.isForced = isForced; this.isForced = isForced;
this.hasPromptMessage = hasPromptMessage; this.hasPromptMessage = hasPromptMessage;
if (hasPromptMessage && promptMessage == null) {
throw new IllegalArgumentException("promptMessage cannot be null when hasPromptMessage is true");
}
this.promptMessage = promptMessage; this.promptMessage = promptMessage;
} }
@ -39,7 +50,7 @@ public class PacketPlayOutResourcePackSend extends PacketOut {
return hasPromptMessage; return hasPromptMessage;
} }
public String getPromptMessage() { public BaseComponent[] getPromptMessage() {
return promptMessage; return promptMessage;
} }
@ -54,7 +65,7 @@ public class PacketPlayOutResourcePackSend extends PacketOut {
output.writeBoolean(isForced); output.writeBoolean(isForced);
output.writeBoolean(hasPromptMessage); output.writeBoolean(hasPromptMessage);
if (hasPromptMessage) { if (hasPromptMessage) {
DataTypeIO.writeString(output, promptMessage, StandardCharsets.UTF_8); DataTypeIO.writeString(output, ComponentSerializer.toString(promptMessage), StandardCharsets.UTF_8);
} }
return buffer.toByteArray(); return buffer.toByteArray();
} }

View File

@ -19,7 +19,8 @@
"0x13": "PacketPlayInRotation", "0x13": "PacketPlayInRotation",
"0x0A": "PacketPlayInPluginMessaging", "0x0A": "PacketPlayInPluginMessaging",
"0x06": "PacketPlayInTabComplete", "0x06": "PacketPlayInTabComplete",
"0x25": "PacketPlayInHeldItemChange" "0x25": "PacketPlayInHeldItemChange",
"0x21": "PacketPlayInResourcePackStatus"
}, },
"PlayOut": { "PlayOut": {
"PacketPlayOutLogin": "0x26", "PacketPlayOutLogin": "0x26",
@ -43,7 +44,8 @@
"PacketPlayOutEntityMetadata": "0x4D", "PacketPlayOutEntityMetadata": "0x4D",
"PacketPlayOutSpawnEntity": "0x00", "PacketPlayOutSpawnEntity": "0x00",
"PacketPlayOutSpawnEntityLiving": "0x02", "PacketPlayOutSpawnEntityLiving": "0x02",
"PacketPlayOutHeldItemChange": "0x48" "PacketPlayOutHeldItemChange": "0x48",
"PacketPlayOutResourcePackSend": "0x3C"
}, },
"StatusIn": { "StatusIn": {
"0x01": "PacketStatusInPing", "0x01": "PacketStatusInPing",

View File

@ -58,3 +58,15 @@ motd={"text":"","extra":[{"text":"Limbo Server!","color":"yellow"}]}
#Server list version as string #Server list version as string
version=Limbo! 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"}]}