diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..a5d9509
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..0446c9d
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ Limbo
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..82e28d1
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+encoding//src/main/java=ISO-8859-1
+encoding//src/main/resources=UTF-8
+encoding/=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2f5cc74
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/src/main/java/com/loohp/limbo/events/player/PlayerResourcePackStatusEvent.java b/src/main/java/com/loohp/limbo/events/player/PlayerResourcePackStatusEvent.java
new file mode 100644
index 0000000..0c41004
--- /dev/null
+++ b/src/main/java/com/loohp/limbo/events/player/PlayerResourcePackStatusEvent.java
@@ -0,0 +1,22 @@
+package com.loohp.limbo.events.player;
+
+import com.loohp.limbo.player.Player;
+import com.loohp.limbo.server.packets.PacketPlayInResourcePackStatus.EnumResourcePackStatus;
+
+public class PlayerResourcePackStatusEvent extends PlayerEvent {
+
+ private Player player;
+ private EnumResourcePackStatus status;
+
+ public PlayerResourcePackStatusEvent(Player player, EnumResourcePackStatus status) {
+ super(player);
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ public EnumResourcePackStatus getStatus() {
+ return status;
+ }
+}
diff --git a/src/main/java/com/loohp/limbo/file/ServerProperties.java b/src/main/java/com/loohp/limbo/file/ServerProperties.java
index 85da867..c16cc40 100644
--- a/src/main/java/com/loohp/limbo/file/ServerProperties.java
+++ b/src/main/java/com/loohp/limbo/file/ServerProperties.java
@@ -50,6 +50,11 @@ public class ServerProperties {
private double ticksPerSecond;
private boolean handshakeVerbose;
+ private String resourcePackSHA;
+ private String resourcePackLink;
+ private boolean resourcePackRequired;
+ private String resourcePackPrompt;
+
Optional favicon;
public ServerProperties(File file) throws IOException {
@@ -122,6 +127,11 @@ public class ServerProperties {
viewDistance = Integer.parseInt(prop.getProperty("view-distance"));
ticksPerSecond = Double.parseDouble(prop.getProperty("ticks-per-second"));
handshakeVerbose = Boolean.parseBoolean(prop.getProperty("handshake-verbose"));
+
+ resourcePackLink = prop.getProperty("resource-pack");
+ resourcePackSHA = prop.getProperty("resource-pack-sha1");
+ resourcePackRequired = Boolean.parseBoolean(prop.getProperty("required-resource-pack"));
+ resourcePackPrompt = prop.getProperty("resource-pack-prompt");
File png = new File("server-icon.png");
if (png.exists()) {
@@ -242,5 +252,21 @@ public class ServerProperties {
public boolean handshakeVerboseEnabled() {
return handshakeVerbose;
}
+
+ public String getResourcePackLink() {
+ return resourcePackLink;
+ }
+
+ public String getResourcePackSHA() {
+ return resourcePackSHA;
+ }
+
+ public boolean getResourcePackRequired() {
+ return resourcePackRequired;
+ }
+
+ public String getResourcePackPrompt() {
+ return resourcePackPrompt;
+ }
}
diff --git a/src/main/java/com/loohp/limbo/player/Player.java b/src/main/java/com/loohp/limbo/player/Player.java
index ff34b48..71ab2d1 100644
--- a/src/main/java/com/loohp/limbo/player/Player.java
+++ b/src/main/java/com/loohp/limbo/player/Player.java
@@ -18,6 +18,7 @@ import com.loohp.limbo.server.packets.PacketPlayOutChat;
import com.loohp.limbo.server.packets.PacketPlayOutGameState;
import com.loohp.limbo.server.packets.PacketPlayOutHeldItemChange;
import com.loohp.limbo.server.packets.PacketPlayOutPositionAndLook;
+import com.loohp.limbo.server.packets.PacketPlayOutResourcePackSend;
import com.loohp.limbo.server.packets.PacketPlayOutRespawn;
import com.loohp.limbo.utils.GameMode;
@@ -259,5 +260,17 @@ public class Player extends LivingEntity implements CommandSender {
}
}
}
+
+
+ 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));
+ 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 93f6b67..e9d31b7 100644
--- a/src/main/java/com/loohp/limbo/server/ClientConnection.java
+++ b/src/main/java/com/loohp/limbo/server/ClientConnection.java
@@ -26,6 +26,7 @@ import com.loohp.limbo.events.player.PlayerJoinEvent;
import com.loohp.limbo.events.player.PlayerLoginEvent;
import com.loohp.limbo.events.player.PlayerMoveEvent;
import com.loohp.limbo.events.player.PlayerQuitEvent;
+import com.loohp.limbo.events.player.PlayerResourcePackStatusEvent;
import com.loohp.limbo.events.player.PlayerSelectedSlotChangeEvent;
import com.loohp.limbo.events.status.StatusPingEvent;
import com.loohp.limbo.file.ServerProperties;
@@ -45,6 +46,7 @@ import com.loohp.limbo.server.packets.PacketPlayInHeldItemChange;
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.PacketPlayInRotation;
import com.loohp.limbo.server.packets.PacketPlayInTabComplete;
import com.loohp.limbo.server.packets.PacketPlayOutDeclareCommands;
@@ -417,6 +419,20 @@ public class ClientConnection extends Thread {
sendPacket(state);
}
+ if (properties.getResourcePackLink() != null && !properties.getResourcePackLink().equalsIgnoreCase("")) {
+ if (properties.getResourcePackSHA() != null && !properties.getResourcePackSHA().equalsIgnoreCase("")) {
+ //SEND RESOURCEPACK
+ player.setResourcePack(properties.getResourcePackLink(),
+ properties.getResourcePackSHA(), properties.getResourcePackRequired(),
+ ComponentSerializer.parse(properties.getResourcePackPrompt()));
+ } else {
+ //NO SHA
+ Limbo.getInstance().getConsole().sendMessage("ResourcePacks require SHA1s");
+ }
+ } else {
+ //RESOURCEPACK NOT ENABLED
+ }
+
ready = true;
while (client_socket.isConnected()) {
@@ -510,6 +526,11 @@ public class ClientConnection extends Thread {
} else {
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
}
+
+ } else if (packetType.equals(PacketPlayInResourcePackStatus.class)) {
+ PacketPlayInResourcePackStatus rpcheck = new PacketPlayInResourcePackStatus(input);
+ // Pass on result to the events
+ Limbo.getInstance().getEventsManager().callEvent(new PlayerResourcePackStatusEvent(player, rpcheck.getLoadedValue()));
} 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
new file mode 100644
index 0000000..1f98a6d
--- /dev/null
+++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayInResourcePackStatus.java
@@ -0,0 +1,42 @@
+package com.loohp.limbo.server.packets;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import com.loohp.limbo.utils.DataTypeIO;
+
+public class PacketPlayInResourcePackStatus extends PacketIn {
+
+
+ public enum EnumResourcePackStatus {
+ SUCCESS,
+ DECLINED,
+ FAILED,
+ ACCEPTED;
+ }
+
+ private int loaded;
+
+ public PacketPlayInResourcePackStatus(int 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;
+ }
+ }
+
+ public boolean isLoadedValue(EnumResourcePackStatus status) {
+ return getLoadedValue() == status;
+ }
+
+}
diff --git a/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutResourcePackSend.java b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutResourcePackSend.java
new file mode 100644
index 0000000..f0e2bd9
--- /dev/null
+++ b/src/main/java/com/loohp/limbo/server/packets/PacketPlayOutResourcePackSend.java
@@ -0,0 +1,62 @@
+package com.loohp.limbo.server.packets;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+import com.loohp.limbo.utils.DataTypeIO;
+
+public class PacketPlayOutResourcePackSend extends PacketOut {
+
+ private String url;
+ private String hash;
+ private boolean isForced;
+ private boolean hasPromptMessage;
+ private String promptMessage;
+
+ public PacketPlayOutResourcePackSend(String url, String hash, boolean isForced, boolean hasPromptMessage, String promptMessage) {
+ this.url = url;
+ this.hash = hash;
+ this.isForced = isForced;
+ this.hasPromptMessage = hasPromptMessage;
+ this.promptMessage = promptMessage;
+ }
+
+ public String getURL() {
+ return url;
+ }
+
+ public String getHash() {
+ return hash;
+ }
+
+ public boolean isForced() {
+ return isForced;
+ }
+
+ public boolean hasPromptMessage() {
+ return hasPromptMessage;
+ }
+
+ public String getPromptMessage() {
+ return promptMessage;
+ }
+
+ @Override
+ public byte[] serializePacket() throws IOException {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+ DataOutputStream output = new DataOutputStream(buffer);
+ output.writeByte(Packet.getPlayOut().get(getClass()));
+ DataTypeIO.writeString(output, url, StandardCharsets.UTF_8);
+ DataTypeIO.writeString(output, hash, StandardCharsets.UTF_8);
+ output.writeBoolean(isForced);
+ output.writeBoolean(hasPromptMessage);
+ if (hasPromptMessage) {
+ DataTypeIO.writeString(output, promptMessage, StandardCharsets.UTF_8);
+ }
+ return buffer.toByteArray();
+ }
+
+}