diff --git a/README.md b/README.md
index 3a1b9c6f..6c85ac2c 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ See ch.spacebase.mc.protocol.test.Test.
--------
MCProtocolLib uses Maven to manage dependencies. Simply run 'mvn clean install' in the source's directory.
-You can also download a build [here](http://build.spacebase.ch/job/MCProtocolLib14w03b/).
+You can also download a build [here](http://build.spacebase.ch/job/MCProtocolLib14w04b/).
License
diff --git a/pom.xml b/pom.xml
index 0d3f8f2b..544c0d47 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
ch.spacebase
mcprotocollib
- 14w03b-SNAPSHOT
+ 14w04b-SNAPSHOT
jar
MCProtocolLib
@@ -85,6 +85,13 @@
clean install
${basedir}/src/main/java
+
+
+
+ ${basedir}/src/main/resources
+ false
+
+
org.apache.maven.plugins
diff --git a/src/main/java/ch/spacebase/mc/auth/GameProfile.java b/src/main/java/ch/spacebase/mc/auth/GameProfile.java
index 104a8af2..00385c70 100644
--- a/src/main/java/ch/spacebase/mc/auth/GameProfile.java
+++ b/src/main/java/ch/spacebase/mc/auth/GameProfile.java
@@ -1,9 +1,14 @@
package ch.spacebase.mc.auth;
+import java.util.HashMap;
+import java.util.Map;
+
public class GameProfile {
private String id;
private String name;
+ private Map properties = new HashMap();
+ private boolean legacy;
public GameProfile(String id, String name) {
if((id == null || id.equals("")) && (name == null || name.equals(""))) {
@@ -21,6 +26,14 @@ public class GameProfile {
public String getName() {
return this.name;
}
+
+ public Map getProperties() {
+ return this.properties;
+ }
+
+ public boolean isLegacy() {
+ return this.legacy;
+ }
public boolean isComplete() {
return this.id != null && !this.id.equals("") && this.name != null && !this.name.equals("");
diff --git a/src/main/java/ch/spacebase/mc/auth/ProfileProperty.java b/src/main/java/ch/spacebase/mc/auth/ProfileProperty.java
new file mode 100644
index 00000000..01c45174
--- /dev/null
+++ b/src/main/java/ch/spacebase/mc/auth/ProfileProperty.java
@@ -0,0 +1,54 @@
+package ch.spacebase.mc.auth;
+
+import java.security.PublicKey;
+import java.security.Signature;
+
+import ch.spacebase.mc.util.Base64;
+
+public class ProfileProperty {
+
+ private String name;
+ private String value;
+ private String signature;
+
+ public ProfileProperty(String value, String name) {
+ this(value, name, null);
+ }
+
+ public ProfileProperty(String name, String value, String signature) {
+ this.name = name;
+ this.value = value;
+ this.signature = signature;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+ public String getSignature() {
+ return this.signature;
+ }
+
+ public boolean hasSignature() {
+ return this.signature != null;
+ }
+
+ public boolean isSignatureValid(PublicKey key) {
+ try {
+ Signature sig = Signature.getInstance("SHA1withRSA");
+ sig.initVerify(key);
+ sig.update(this.value.getBytes());
+ return sig.verify(Base64.decode(this.signature.getBytes("UTF-8")));
+ } catch(Exception e) {
+ System.err.println("Failed to check profile property signature validity.");
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+}
diff --git a/src/main/java/ch/spacebase/mc/auth/ProfileTexture.java b/src/main/java/ch/spacebase/mc/auth/ProfileTexture.java
new file mode 100644
index 00000000..69af60ea
--- /dev/null
+++ b/src/main/java/ch/spacebase/mc/auth/ProfileTexture.java
@@ -0,0 +1,31 @@
+package ch.spacebase.mc.auth;
+
+public class ProfileTexture {
+
+ private String url;
+
+ public ProfileTexture(String url) {
+ this.url = url;
+ }
+
+ public String getUrl() {
+ return this.url;
+ }
+
+ public String getHash() {
+ String url = this.url.endsWith("/") ? this.url.substring(0, this.url.length() - 1) : this.url;
+ int slash = url.lastIndexOf("/");
+ int dot = url.lastIndexOf(".", slash);
+ return url.substring(slash + 1, dot != -1 ? dot : url.length());
+ }
+
+ public String toString() {
+ return "ProfileTexture{url=" + this.url + ", hash=" + this.getHash() + "}";
+ }
+
+ public static enum Type {
+ SKIN,
+ CAPE;
+ }
+
+}
diff --git a/src/main/java/ch/spacebase/mc/auth/SessionService.java b/src/main/java/ch/spacebase/mc/auth/SessionService.java
index 054106dd..317d358f 100644
--- a/src/main/java/ch/spacebase/mc/auth/SessionService.java
+++ b/src/main/java/ch/spacebase/mc/auth/SessionService.java
@@ -4,18 +4,38 @@ import ch.spacebase.mc.auth.exceptions.AuthenticationException;
import ch.spacebase.mc.auth.exceptions.AuthenticationUnavailableException;
import ch.spacebase.mc.auth.request.JoinServerRequest;
import ch.spacebase.mc.auth.response.HasJoinedResponse;
+import ch.spacebase.mc.auth.response.MinecraftTexturesPayload;
import ch.spacebase.mc.auth.response.Response;
+import ch.spacebase.mc.util.Base64;
+import ch.spacebase.mc.util.IOUtils;
import ch.spacebase.mc.util.URLUtils;
import java.net.URL;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
+import com.google.gson.Gson;
+
public class SessionService {
private static final String BASE_URL = "https://sessionserver.mojang.com/session/minecraft/";
private static final URL JOIN_URL = URLUtils.constantURL(BASE_URL + "join");
private static final URL CHECK_URL = URLUtils.constantURL(BASE_URL + "hasJoined");
+
+ private static final PublicKey SIGNATURE_KEY;
+
+ static {
+ try {
+ X509EncodedKeySpec spec = new X509EncodedKeySpec(IOUtils.toByteArray(SessionService.class.getResourceAsStream("/yggdrasil_session_pubkey.der")));
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ SIGNATURE_KEY = keyFactory.generatePublic(spec);
+ } catch(Exception var4) {
+ throw new ExceptionInInitializerError("Missing/invalid yggdrasil public key.");
+ }
+ }
public void joinServer(GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException {
JoinServerRequest request = new JoinServerRequest(authenticationToken, profile.getId(), serverId);
@@ -28,8 +48,19 @@ public class SessionService {
arguments.put("serverId", serverId);
URL url = URLUtils.concatenateURL(CHECK_URL, URLUtils.buildQuery(arguments));
try {
- HasJoinedResponse e = URLUtils.makeRequest(url, null, HasJoinedResponse.class);
- return e != null && e.getId() != null ? new GameProfile(e.getId(), user.getName()) : null;
+ HasJoinedResponse response = URLUtils.makeRequest(url, null, HasJoinedResponse.class);
+ if(response != null && response.getId() != null) {
+ GameProfile result = new GameProfile(response.getId(), user.getName());
+ if(response.getProperties() != null) {
+ for(ProfileProperty prop : response.getProperties()) {
+ result.getProperties().put(prop.getName(), prop);
+ }
+ }
+
+ return result;
+ } else {
+ return null;
+ }
} catch(AuthenticationUnavailableException var6) {
throw var6;
} catch(AuthenticationException var7) {
@@ -37,6 +68,41 @@ public class SessionService {
}
}
+ public Map getTextures(GameProfile profile) {
+ ProfileProperty textures = profile.getProperties().get("textures");
+ if(textures == null) {
+ return new HashMap();
+ } else if(!textures.hasSignature()) {
+ System.err.println("Signature is missing from textures payload.");
+ return new HashMap();
+ } else if(!textures.isSignatureValid(SIGNATURE_KEY)) {
+ System.err.println("Textures payload has been tampered with. (signature invalid)");
+ return new HashMap();
+ } else {
+ MinecraftTexturesPayload result;
+ try {
+ String e = new String(Base64.decode(textures.getValue().getBytes("UTF-8")));
+ result = new Gson().fromJson(e, MinecraftTexturesPayload.class);
+ } catch(Exception e) {
+ System.err.println("Could not decode textures payload.");
+ e.printStackTrace();
+ return new HashMap();
+ }
+
+ if(result.getProfileId() != null && result.getProfileId().equals(profile.getId())) {
+ if(result.getProfileName() != null && result.getProfileName().equals(profile.getName())) {
+ return result.getTextures() == null ? new HashMap() : result.getTextures();
+ } else {
+ System.err.println("Decrypted textures payload was for another user. (expected name " + profile.getName() + " but was for " + result.getProfileName() + ")");
+ return new HashMap();
+ }
+ } else {
+ System.err.println("Decrypted textures payload was for another user. (expected id " + profile.getId() + " but was for " + result.getProfileId() + ")");
+ return new HashMap();
+ }
+ }
+ }
+
@Override
public String toString() {
return "SessionService{}";
diff --git a/src/main/java/ch/spacebase/mc/auth/UserAuthentication.java b/src/main/java/ch/spacebase/mc/auth/UserAuthentication.java
index f8efb69c..372bcd11 100644
--- a/src/main/java/ch/spacebase/mc/auth/UserAuthentication.java
+++ b/src/main/java/ch/spacebase/mc/auth/UserAuthentication.java
@@ -7,6 +7,7 @@ import ch.spacebase.mc.auth.request.RefreshRequest;
import ch.spacebase.mc.auth.response.AuthenticationResponse;
import ch.spacebase.mc.auth.response.RefreshResponse;
import ch.spacebase.mc.auth.response.User;
+import ch.spacebase.mc.auth.response.User.Property;
import ch.spacebase.mc.util.URLUtils;
import java.net.URL;
@@ -14,7 +15,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -30,7 +30,7 @@ public class UserAuthentication {
private static final String STORAGE_KEY_ACCESS_TOKEN = "accessToken";
private String clientToken;
- private Map userProperties = new HashMap();
+ private Map> userProperties = new HashMap>();
private String userId;
private String username;
private String password;
@@ -38,6 +38,7 @@ public class UserAuthentication {
private boolean isOnline;
private List profiles = new ArrayList();
private GameProfile selectedProfile;
+ private UserType userType;
public UserAuthentication(String clientToken) {
if(clientToken == null) {
@@ -67,8 +68,12 @@ public class UserAuthentication {
return this.selectedProfile;
}
- public Map getUserProperties() {
- return this.isLoggedIn() ? Collections.unmodifiableMap(this.userProperties) : Collections.unmodifiableMap(new HashMap());
+ public UserType getUserType() {
+ return this.isLoggedIn() ? (this.userType == null ? UserType.LEGACY : this.userType) : null;
+ }
+
+ public Map> getUserProperties() {
+ return this.isLoggedIn() ? Collections.unmodifiableMap(this.userProperties) : Collections.unmodifiableMap(new HashMap>());
}
public boolean isLoggedIn() {
@@ -170,8 +175,14 @@ public class UserAuthentication {
AuthenticationRequest request = new AuthenticationRequest(this, this.username, this.password);
AuthenticationResponse response = URLUtils.makeRequest(ROUTE_AUTHENTICATE, request, AuthenticationResponse.class);
if(!response.getClientToken().equals(this.getClientToken())) {
- throw new AuthenticationException("Server requested we change our client token. Don\'t know how to handle this!");
+ throw new AuthenticationException("Server requested we change our client token. Don't know how to handle this!");
} else {
+ if(response.getSelectedProfile() != null) {
+ this.userType = response.getSelectedProfile().isLegacy() ? UserType.LEGACY : UserType.MOJANG;
+ } else if(response.getAvailableProfiles() != null && response.getAvailableProfiles().length != 0) {
+ this.userType = response.getAvailableProfiles()[0].isLegacy() ? UserType.LEGACY : UserType.MOJANG;
+ }
+
if(response.getUser() != null && response.getUser().getId() != null) {
this.userId = response.getUser().getId();
} else {
@@ -182,14 +193,7 @@ public class UserAuthentication {
this.accessToken = response.getAccessToken();
this.profiles = Arrays.asList(response.getAvailableProfiles());
this.selectedProfile = response.getSelectedProfile();
- this.userProperties.clear();
- if(response.getUser() != null && response.getUser().getProperties() != null) {
- Iterator it = response.getUser().getProperties().iterator();
- while(it.hasNext()) {
- User.Property property = it.next();
- this.userProperties.put(property.getKey(), property.getValue());
- }
- }
+ this.updateProperties(response.getUser());
}
}
}
@@ -209,8 +213,14 @@ public class UserAuthentication {
RefreshRequest request = new RefreshRequest(this);
RefreshResponse response = URLUtils.makeRequest(ROUTE_REFRESH, request, RefreshResponse.class);
if(!response.getClientToken().equals(this.getClientToken())) {
- throw new AuthenticationException("Server requested we change our client token. Don\'t know how to handle this!");
+ throw new AuthenticationException("Server requested we change our client token. Don't know how to handle this!");
} else {
+ if(response.getSelectedProfile() != null) {
+ this.userType = response.getSelectedProfile().isLegacy() ? UserType.LEGACY : UserType.MOJANG;
+ } else if(response.getAvailableProfiles() != null && response.getAvailableProfiles().length != 0) {
+ this.userType = response.getAvailableProfiles()[0].isLegacy() ? UserType.LEGACY : UserType.MOJANG;
+ }
+
if(response.getUser() != null && response.getUser().getId() != null) {
this.userId = response.getUser().getId();
} else {
@@ -221,15 +231,7 @@ public class UserAuthentication {
this.accessToken = response.getAccessToken();
this.profiles = Arrays.asList(response.getAvailableProfiles());
this.selectedProfile = response.getSelectedProfile();
- this.userProperties.clear();
- if(response.getUser() != null && response.getUser().getProperties() != null) {
- Iterator it = response.getUser().getProperties().iterator();
- while(it.hasNext()) {
- User.Property property = it.next();
- this.userProperties.put(property.getKey(), property.getValue());
- }
- }
-
+ this.updateProperties(response.getUser());
}
}
}
@@ -242,6 +244,7 @@ public class UserAuthentication {
this.accessToken = null;
this.profiles = null;
this.isOnline = false;
+ this.userType = null;
}
public void selectGameProfile(GameProfile profile) throws AuthenticationException {
@@ -253,14 +256,14 @@ public class UserAuthentication {
RefreshRequest request = new RefreshRequest(this, profile);
RefreshResponse response = URLUtils.makeRequest(ROUTE_REFRESH, request, RefreshResponse.class);
if(!response.getClientToken().equals(this.getClientToken())) {
- throw new AuthenticationException("Server requested we change our client token. Don\'t know how to handle this!");
+ throw new AuthenticationException("Server requested we change our client token. Don't know how to handle this!");
} else {
this.isOnline = true;
this.accessToken = response.getAccessToken();
this.selectedProfile = response.getSelectedProfile();
}
} else {
- throw new IllegalArgumentException("Invalid profile \'" + profile + "\'");
+ throw new IllegalArgumentException("Invalid profile '" + profile + "'");
}
}
@@ -268,5 +271,18 @@ public class UserAuthentication {
public String toString() {
return "UserAuthentication{profiles=" + this.profiles + ", selectedProfile=" + this.getSelectedProfile() + ", username=" + this.username + ", isLoggedIn=" + this.isLoggedIn() + ", canPlayOnline=" + this.canPlayOnline() + ", accessToken=" + this.accessToken + ", clientToken=" + this.getClientToken() + "}";
}
+
+ private void updateProperties(User user) {
+ this.userProperties.clear();
+ if(user != null && user.getProperties() != null) {
+ for(Property property : user.getProperties()) {
+ if(this.userProperties.get(property.getKey()) == null) {
+ this.userProperties.put(property.getKey(), new ArrayList());
+ }
+
+ this.userProperties.get(property.getKey()).add(property.getValue());
+ }
+ }
+ }
}
diff --git a/src/main/java/ch/spacebase/mc/auth/UserType.java b/src/main/java/ch/spacebase/mc/auth/UserType.java
new file mode 100644
index 00000000..31f91740
--- /dev/null
+++ b/src/main/java/ch/spacebase/mc/auth/UserType.java
@@ -0,0 +1,8 @@
+package ch.spacebase.mc.auth;
+
+public enum UserType {
+
+ LEGACY,
+ MOJANG;
+
+}
diff --git a/src/main/java/ch/spacebase/mc/auth/response/HasJoinedResponse.java b/src/main/java/ch/spacebase/mc/auth/response/HasJoinedResponse.java
index c749d855..f16eb3db 100644
--- a/src/main/java/ch/spacebase/mc/auth/response/HasJoinedResponse.java
+++ b/src/main/java/ch/spacebase/mc/auth/response/HasJoinedResponse.java
@@ -1,13 +1,21 @@
package ch.spacebase.mc.auth.response;
+import java.util.List;
+
+import ch.spacebase.mc.auth.ProfileProperty;
import ch.spacebase.mc.auth.response.Response;
public class HasJoinedResponse extends Response {
private String id;
+ private List properties;
public String getId() {
return this.id;
}
+ public List getProperties() {
+ return this.properties;
+ }
+
}
diff --git a/src/main/java/ch/spacebase/mc/auth/response/MinecraftTexturesPayload.java b/src/main/java/ch/spacebase/mc/auth/response/MinecraftTexturesPayload.java
new file mode 100644
index 00000000..9eeb2045
--- /dev/null
+++ b/src/main/java/ch/spacebase/mc/auth/response/MinecraftTexturesPayload.java
@@ -0,0 +1,30 @@
+package ch.spacebase.mc.auth.response;
+
+import java.util.Map;
+
+import ch.spacebase.mc.auth.ProfileTexture;
+
+public class MinecraftTexturesPayload {
+
+ private long timestamp;
+ private String profileId;
+ private String profileName;
+ private Map textures;
+
+ public long getTimestamp() {
+ return this.timestamp;
+ }
+
+ public String getProfileId() {
+ return this.profileId;
+ }
+
+ public String getProfileName() {
+ return this.profileName;
+ }
+
+ public Map getTextures() {
+ return this.textures;
+ }
+
+}
diff --git a/src/main/java/ch/spacebase/mc/protocol/MinecraftProtocol.java b/src/main/java/ch/spacebase/mc/protocol/MinecraftProtocol.java
index c26749d8..0f4c5bf1 100644
--- a/src/main/java/ch/spacebase/mc/protocol/MinecraftProtocol.java
+++ b/src/main/java/ch/spacebase/mc/protocol/MinecraftProtocol.java
@@ -33,6 +33,8 @@ import ch.spacebase.mc.protocol.packet.ingame.client.window.ClientEnchantItemPac
import ch.spacebase.mc.protocol.packet.ingame.client.window.ClientWindowActionPacket;
import ch.spacebase.mc.protocol.packet.ingame.client.world.ClientUpdateSignPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerChatPacket;
+import ch.spacebase.mc.protocol.packet.ingame.server.ServerCombatPacket;
+import ch.spacebase.mc.protocol.packet.ingame.server.ServerDifficultyPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerDisconnectPacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
import ch.spacebase.mc.protocol.packet.ingame.server.ServerKeepAlivePacket;
@@ -326,6 +328,8 @@ public class MinecraftProtocol extends PacketProtocol {
this.registerIncoming(62, ServerTeamPacket.class);
this.registerIncoming(63, ServerPluginMessagePacket.class);
this.registerIncoming(64, ServerDisconnectPacket.class);
+ this.registerIncoming(65, ServerDifficultyPacket.class);
+ this.registerIncoming(66, ServerCombatPacket.class);
this.registerOutgoing(0, ClientKeepAlivePacket.class);
this.registerOutgoing(1, ClientChatPacket.class);
@@ -444,6 +448,8 @@ public class MinecraftProtocol extends PacketProtocol {
this.registerOutgoing(62, ServerTeamPacket.class);
this.registerOutgoing(63, ServerPluginMessagePacket.class);
this.registerOutgoing(64, ServerDisconnectPacket.class);
+ this.registerOutgoing(65, ServerDifficultyPacket.class);
+ this.registerOutgoing(66, ServerCombatPacket.class);
}
private void initClientStatus(Session session) {
diff --git a/src/main/java/ch/spacebase/mc/protocol/ProtocolConstants.java b/src/main/java/ch/spacebase/mc/protocol/ProtocolConstants.java
index f024595b..7b5e8025 100644
--- a/src/main/java/ch/spacebase/mc/protocol/ProtocolConstants.java
+++ b/src/main/java/ch/spacebase/mc/protocol/ProtocolConstants.java
@@ -3,8 +3,8 @@ package ch.spacebase.mc.protocol;
public class ProtocolConstants {
// General Constants
- public static final String GAME_VERSION = "14w03b";
- public static final int PROTOCOL_VERSION = 6;
+ public static final String GAME_VERSION = "14w04b";
+ public static final int PROTOCOL_VERSION = 8;
// General Key Constants
public static final String PROFILE_KEY = "profile";
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/ClientKeepAlivePacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/ClientKeepAlivePacket.java
index f2582d48..2f7d2171 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/ClientKeepAlivePacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/ClientKeepAlivePacket.java
@@ -24,12 +24,12 @@ public class ClientKeepAlivePacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.id = in.readInt();
+ this.id = in.readVarInt();
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.id);
+ out.writeVarInt(this.id);
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/ClientRequestPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/ClientRequestPacket.java
index ee75c373..e4ae8da6 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/ClientRequestPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/ClientRequestPacket.java
@@ -24,7 +24,7 @@ public class ClientRequestPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.request = Request.values()[in.readByte()];
+ this.request = Request.values()[in.readUnsignedByte()];
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientAnimationPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientAnimationPacket.java
index 9ee01a56..e569a873 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientAnimationPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientAnimationPacket.java
@@ -8,45 +8,20 @@ import ch.spacebase.packetlib.packet.Packet;
public class ClientAnimationPacket implements Packet {
- private int entityId;
- private Animation animation;
-
- @SuppressWarnings("unused")
- private ClientAnimationPacket() {
- }
-
- public ClientAnimationPacket(int entityId, Animation animation) {
- this.entityId = entityId;
- this.animation = animation;
- }
-
- public int getEntityId() {
- return this.entityId;
- }
-
- public Animation getAnimation() {
- return this.animation;
+ public ClientAnimationPacket() {
}
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
- this.animation = Animation.values()[in.readByte() - 1];
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
- out.writeByte(this.animation.ordinal() + 1);
}
@Override
public boolean isPriority() {
return false;
}
-
- public static enum Animation {
- SWING_ARM;
- }
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientEntityActionPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientEntityActionPacket.java
index fcfdf011..0f80dd00 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientEntityActionPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientEntityActionPacket.java
@@ -40,16 +40,16 @@ public class ClientEntityActionPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
- this.action = Action.values()[in.readByte() - 1];
- this.jumpBoost = in.readInt();
+ this.entityId = in.readVarInt();
+ this.action = Action.values()[in.readUnsignedByte() - 1];
+ this.jumpBoost = in.readVarInt();
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
out.writeByte(this.action.ordinal() + 1);
- out.writeInt(this.jumpBoost);
+ out.writeVarInt(this.jumpBoost);
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientEntityInteractPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientEntityInteractPacket.java
index 48255008..cf8286d3 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientEntityInteractPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/ClientEntityInteractPacket.java
@@ -30,13 +30,13 @@ public class ClientEntityInteractPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
- this.action = Action.values()[in.readByte()];
+ this.entityId = in.readVarInt();
+ this.action = Action.values()[in.readUnsignedByte()];
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
out.writeByte(this.action.ordinal());
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/player/ClientSteerVehiclePacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/player/ClientSteerVehiclePacket.java
index d6c2b407..b232a34b 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/player/ClientSteerVehiclePacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/client/entity/player/ClientSteerVehiclePacket.java
@@ -44,16 +44,25 @@ public class ClientSteerVehiclePacket implements Packet {
public void read(NetInput in) throws IOException {
this.sideways = in.readFloat();
this.forward = in.readFloat();
- this.jump = in.readBoolean();
- this.dismount = in.readBoolean();
+ int flags = in.readUnsignedByte();
+ this.jump = (flags & 1) > 0;
+ this.dismount = (flags & 2) > 0;
}
@Override
public void write(NetOutput out) throws IOException {
out.writeFloat(this.sideways);
out.writeFloat(this.forward);
- out.writeBoolean(this.jump);
- out.writeBoolean(this.dismount);
+ byte flags = 0;
+ if(this.jump) {
+ flags = (byte) (flags | 1);
+ }
+
+ if(this.dismount) {
+ flags = (byte) (flags | 2);
+ }
+
+ out.writeByte(flags);
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/ServerCombatPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/ServerCombatPacket.java
new file mode 100644
index 00000000..f7808684
--- /dev/null
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/ServerCombatPacket.java
@@ -0,0 +1,91 @@
+package ch.spacebase.mc.protocol.packet.ingame.server;
+
+import java.io.IOException;
+
+import ch.spacebase.packetlib.io.NetInput;
+import ch.spacebase.packetlib.io.NetOutput;
+import ch.spacebase.packetlib.packet.Packet;
+
+public class ServerCombatPacket implements Packet {
+
+ private CombatState state;
+ private int entityId;
+ private int duration;
+ private int playerId;
+ private String message;
+
+ public ServerCombatPacket() {
+ this.state = CombatState.ENTER_COMBAT;
+ }
+
+ public ServerCombatPacket(int entityId, int duration) {
+ this.state = CombatState.END_COMBAT;
+ this.entityId = entityId;
+ this.duration = duration;
+ }
+
+ public ServerCombatPacket(int entityId, int playerId, String message) {
+ this.state = CombatState.ENTITY_DEAD;
+ this.entityId = entityId;
+ this.playerId = playerId;
+ this.message = message;
+ }
+
+ public CombatState getCombatState() {
+ return this.state;
+ }
+
+ public int getEntityId() {
+ return this.entityId;
+ }
+
+ public int getDuration() {
+ return this.duration;
+ }
+
+ public int getPlayerId() {
+ return this.playerId;
+ }
+
+ public String getMessage() {
+ return this.message;
+ }
+
+ @Override
+ public void read(NetInput in) throws IOException {
+ this.state = CombatState.values()[in.readUnsignedByte()];
+ if(this.state == CombatState.END_COMBAT) {
+ this.duration = in.readVarInt();
+ this.entityId = in.readInt();
+ } else if(this.state == CombatState.ENTITY_DEAD) {
+ this.playerId = in.readVarInt();
+ this.entityId = in.readInt();
+ this.message = in.readString();
+ }
+ }
+
+ @Override
+ public void write(NetOutput out) throws IOException {
+ out.writeByte(this.state.ordinal());
+ if(this.state == CombatState.END_COMBAT) {
+ out.writeVarInt(this.duration);
+ out.writeInt(this.entityId);
+ } else if(this.state == CombatState.ENTITY_DEAD) {
+ out.writeVarInt(this.playerId);
+ out.writeInt(this.entityId);
+ out.writeString(this.message);
+ }
+ }
+
+ @Override
+ public boolean isPriority() {
+ return false;
+ }
+
+ public static enum CombatState {
+ ENTER_COMBAT,
+ END_COMBAT,
+ ENTITY_DEAD;
+ }
+
+}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/ServerPlayerListEntryPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/ServerPlayerListEntryPacket.java
index 41290d8d..24f96ff4 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/ServerPlayerListEntryPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/ServerPlayerListEntryPacket.java
@@ -38,14 +38,14 @@ public class ServerPlayerListEntryPacket implements Packet {
public void read(NetInput in) throws IOException {
this.name = in.readString();
this.online = in.readBoolean();
- this.ping = in.readShort();
+ this.ping = in.readVarInt();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.name);
out.writeBoolean(this.online);
- out.writeShort(this.ping);
+ out.writeVarInt(this.ping);
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerCollectItemPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerCollectItemPacket.java
index 32a72ffb..b9f3676a 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerCollectItemPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerCollectItemPacket.java
@@ -30,14 +30,14 @@ public class ServerCollectItemPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.collectedEntityId = in.readInt();
- this.collectorEntityId = in.readInt();
+ this.collectedEntityId = in.readVarInt();
+ this.collectorEntityId = in.readVarInt();
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.collectedEntityId);
- out.writeInt(this.collectorEntityId);
+ out.writeVarInt(this.collectedEntityId);
+ out.writeVarInt(this.collectorEntityId);
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerDestroyEntitiesPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerDestroyEntitiesPacket.java
index 2091e7a2..af5fdf2e 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerDestroyEntitiesPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerDestroyEntitiesPacket.java
@@ -24,17 +24,17 @@ public class ServerDestroyEntitiesPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityIds = new int[in.readByte()];
+ this.entityIds = new int[in.readVarInt()];
for(int index = 0; index < this.entityIds.length; index++) {
- this.entityIds[index] = in.readInt();
+ this.entityIds[index] = in.readVarInt();
}
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeByte(this.entityIds.length);
+ out.writeVarInt(this.entityIds.length);
for(int entityId : this.entityIds) {
- out.writeInt(entityId);
+ out.writeVarInt(entityId);
}
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityEffectPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityEffectPacket.java
index c878f86a..73f348cd 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityEffectPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityEffectPacket.java
@@ -42,18 +42,18 @@ public class ServerEntityEffectPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
this.effect = Effect.values()[in.readByte()];
this.amplifier = in.readByte();
- this.duration = in.readShort();
+ this.duration = in.readVarInt();
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
out.writeByte(this.effect.ordinal());
out.writeByte(this.amplifier);
- out.writeShort(this.duration);
+ out.writeVarInt(this.duration);
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityEquipmentPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityEquipmentPacket.java
index 126b036d..40182791 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityEquipmentPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityEquipmentPacket.java
@@ -38,14 +38,14 @@ public class ServerEntityEquipmentPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
this.slot = in.readShort();
this.item = NetUtil.readItem(in);
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
out.writeShort(this.slot);
NetUtil.writeItem(out, this.item);
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityHeadLookPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityHeadLookPacket.java
index 457a7ced..0a1a454c 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityHeadLookPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityHeadLookPacket.java
@@ -26,13 +26,13 @@ public class ServerEntityHeadLookPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
this.headYaw = in.readByte() * 360 / 256f;
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
out.writeByte((byte) (this.headYaw * 256 / 360));
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityMetadataPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityMetadataPacket.java
index 747116d7..fed065fa 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityMetadataPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityMetadataPacket.java
@@ -32,13 +32,13 @@ public class ServerEntityMetadataPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
this.metadata = NetUtil.readEntityMetadata(in);
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
NetUtil.writeEntityMetadata(out, this.metadata);
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityMovementPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityMovementPacket.java
index 40e3875c..5fa11e1a 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityMovementPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityMovementPacket.java
@@ -51,7 +51,7 @@ public class ServerEntityMovementPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
if(this.pos) {
this.moveX = in.readByte() / 32D;
this.moveY = in.readByte() / 32D;
@@ -66,7 +66,7 @@ public class ServerEntityMovementPacket implements Packet {
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
if(this.pos) {
out.writeByte((int) (this.moveX * 32));
out.writeByte((int) (this.moveY * 32));
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityPropertiesPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityPropertiesPacket.java
index bf235e56..fc0d596a 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityPropertiesPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityPropertiesPacket.java
@@ -35,9 +35,9 @@ public class ServerEntityPropertiesPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
this.attributes = new ArrayList();
- int length = in.readInt();
+ int length = in.readVarInt();
for(int index = 0; index < length; index++) {
String key = in.readString();
double value = in.readDouble();
@@ -53,8 +53,8 @@ public class ServerEntityPropertiesPacket implements Packet {
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
- out.writeInt(this.attributes.size());
+ out.writeVarInt(this.entityId);
+ out.writeVarInt(this.attributes.size());
for(Attribute attribute : this.attributes) {
out.writeString(attribute.getKey());
out.writeDouble(attribute.getValue());
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityRemoveEffectPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityRemoveEffectPacket.java
index a42ff155..1a585048 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityRemoveEffectPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityRemoveEffectPacket.java
@@ -10,18 +10,14 @@ public class ServerEntityRemoveEffectPacket implements Packet {
private int entityId;
private Effect effect;
- private int amplifier;
- private int duration;
@SuppressWarnings("unused")
private ServerEntityRemoveEffectPacket() {
}
- public ServerEntityRemoveEffectPacket(int entityId, Effect effect, int amplifier, int duration) {
+ public ServerEntityRemoveEffectPacket(int entityId, Effect effect) {
this.entityId = entityId;
this.effect = effect;
- this.amplifier = amplifier;
- this.duration = duration;
}
public int getEntityId() {
@@ -31,29 +27,17 @@ public class ServerEntityRemoveEffectPacket implements Packet {
public Effect getEffect() {
return this.effect;
}
-
- public int getAmplifier() {
- return this.amplifier;
- }
-
- public int getDuration() {
- return this.duration;
- }
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
this.effect = Effect.values()[in.readByte()];
- this.amplifier = in.readByte();
- this.duration = in.readShort();
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
out.writeByte(this.effect.ordinal());
- out.writeByte(this.amplifier);
- out.writeShort(this.duration);
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityTeleportPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityTeleportPacket.java
index 9928b999..c3bb93c3 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityTeleportPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityTeleportPacket.java
@@ -54,7 +54,7 @@ public class ServerEntityTeleportPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
this.x = in.readInt() / 32D;
this.y = in.readInt() / 32D;
this.z = in.readInt() / 32D;
@@ -64,7 +64,7 @@ public class ServerEntityTeleportPacket implements Packet {
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
out.writeInt((int) (this.x * 32));
out.writeInt((int) (this.y * 32));
out.writeInt((int) (this.z * 32));
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityVelocityPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityVelocityPacket.java
index 0e13f186..e0176920 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityVelocityPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/ServerEntityVelocityPacket.java
@@ -42,7 +42,7 @@ public class ServerEntityVelocityPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
this.motX = in.readShort() / 8000D;
this.motY = in.readShort() / 8000D;
this.motZ = in.readShort() / 8000D;
@@ -50,7 +50,7 @@ public class ServerEntityVelocityPacket implements Packet {
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
out.writeShort((int) (this.motX * 8000));
out.writeShort((int) (this.motY * 8000));
out.writeShort((int) (this.motZ * 8000));
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerPlayerUseBedPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerPlayerUseBedPacket.java
index 33261509..90a41b31 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerPlayerUseBedPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerPlayerUseBedPacket.java
@@ -32,13 +32,13 @@ public class ServerPlayerUseBedPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
- this.entityId = in.readInt();
+ this.entityId = in.readVarInt();
this.position = NetUtil.readPosition(in);
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeInt(this.entityId);
+ out.writeVarInt(this.entityId);
NetUtil.writePosition(out, this.position);
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerSetExperiencePacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerSetExperiencePacket.java
index 1df92cfe..a45b828f 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerSetExperiencePacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerSetExperiencePacket.java
@@ -37,15 +37,15 @@ public class ServerSetExperiencePacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
this.experience = in.readFloat();
- this.level = in.readShort();
- this.totalExperience = in.readShort();
+ this.level = in.readVarInt();
+ this.totalExperience = in.readVarInt();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeFloat(this.experience);
- out.writeShort(this.level);
- out.writeShort(this.totalExperience);
+ out.writeVarInt(this.level);
+ out.writeVarInt(this.totalExperience);
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerUpdateHealthPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerUpdateHealthPacket.java
index 362bf1e9..82ff2155 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerUpdateHealthPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/player/ServerUpdateHealthPacket.java
@@ -37,14 +37,14 @@ public class ServerUpdateHealthPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
this.health = in.readFloat();
- this.food = in.readShort();
+ this.food = in.readVarInt();
this.saturation = in.readFloat();
}
@Override
public void write(NetOutput out) throws IOException {
out.writeFloat(this.health);
- out.writeShort(this.food);
+ out.writeVarInt(this.food);
out.writeFloat(this.saturation);
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/spawn/ServerSpawnPaintingPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/spawn/ServerSpawnPaintingPacket.java
index b46370d7..68f77baa 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/spawn/ServerSpawnPaintingPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/spawn/ServerSpawnPaintingPacket.java
@@ -2,6 +2,8 @@ package ch.spacebase.mc.protocol.packet.ingame.server.entity.spawn;
import java.io.IOException;
+import ch.spacebase.mc.protocol.data.game.Position;
+import ch.spacebase.mc.util.NetUtil;
import ch.spacebase.packetlib.io.NetInput;
import ch.spacebase.packetlib.io.NetOutput;
import ch.spacebase.packetlib.packet.Packet;
@@ -10,21 +12,17 @@ public class ServerSpawnPaintingPacket implements Packet {
private int entityId;
private Art art;
- private int x;
- private int y;
- private int z;
+ private Position position;
private Direction direction;
@SuppressWarnings("unused")
private ServerSpawnPaintingPacket() {
}
- public ServerSpawnPaintingPacket(int entityId, Art art, int x, int y, int z, Direction direction) {
+ public ServerSpawnPaintingPacket(int entityId, Art art, Position position, Direction direction) {
this.entityId = entityId;
this.art = art;
- this.x = x;
- this.y = y;
- this.z = z;
+ this.position = position;
this.direction = direction;
}
@@ -36,16 +34,8 @@ public class ServerSpawnPaintingPacket implements Packet {
return this.art;
}
- public int getX() {
- return this.x;
- }
-
- public int getY() {
- return this.y;
- }
-
- public int getZ() {
- return this.z;
+ public Position getPosition() {
+ return this.position;
}
public Direction getDirection() {
@@ -56,20 +46,16 @@ public class ServerSpawnPaintingPacket implements Packet {
public void read(NetInput in) throws IOException {
this.entityId = in.readVarInt();
this.art = Art.valueOf(in.readString());
- this.x = in.readInt();
- this.y = in.readInt();
- this.z = in.readInt();
- this.direction = Direction.values()[in.readInt()];
+ this.position = NetUtil.readPosition(in);
+ this.direction = Direction.values()[in.readUnsignedByte()];
}
@Override
public void write(NetOutput out) throws IOException {
out.writeVarInt(this.entityId);
out.writeString(this.art.name());
- out.writeInt(this.x);
- out.writeInt(this.y);
- out.writeInt(this.z);
- out.writeInt(this.direction.ordinal());
+ NetUtil.writePosition(out, this.position);
+ out.writeByte(this.direction.ordinal());
}
@Override
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/spawn/ServerSpawnPlayerPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/spawn/ServerSpawnPlayerPacket.java
index 0cc5dcaf..c4121e1a 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/spawn/ServerSpawnPlayerPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/entity/spawn/ServerSpawnPlayerPacket.java
@@ -2,6 +2,8 @@ package ch.spacebase.mc.protocol.packet.ingame.server.entity.spawn;
import java.io.IOException;
+import ch.spacebase.mc.auth.GameProfile;
+import ch.spacebase.mc.auth.ProfileProperty;
import ch.spacebase.mc.protocol.data.game.EntityMetadata;
import ch.spacebase.mc.util.NetUtil;
import ch.spacebase.packetlib.io.NetInput;
@@ -11,8 +13,7 @@ import ch.spacebase.packetlib.packet.Packet;
public class ServerSpawnPlayerPacket implements Packet {
private int entityId;
- private String uuid;
- private String name;
+ private GameProfile profile;
private double x;
private double y;
private double z;
@@ -25,10 +26,9 @@ public class ServerSpawnPlayerPacket implements Packet {
private ServerSpawnPlayerPacket() {
}
- public ServerSpawnPlayerPacket(int entityId, String uuid, String name, double x, double y, double z, float yaw, float pitch, int currentItem, EntityMetadata metadata[]) {
+ public ServerSpawnPlayerPacket(int entityId, GameProfile profile, double x, double y, double z, float yaw, float pitch, int currentItem, EntityMetadata metadata[]) {
this.entityId = entityId;
- this.uuid = uuid;
- this.name = name;
+ this.profile = profile;
this.x = x;
this.y = y;
this.z = z;
@@ -42,12 +42,8 @@ public class ServerSpawnPlayerPacket implements Packet {
return this.entityId;
}
- public String getUUID() {
- return this.uuid;
- }
-
- public String getName() {
- return this.name;
+ public GameProfile getProfile() {
+ return this.profile;
}
public double getX() {
@@ -81,8 +77,14 @@ public class ServerSpawnPlayerPacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
this.entityId = in.readVarInt();
- this.uuid = in.readString();
- this.name = in.readString();
+ this.profile = new GameProfile(in.readString(), in.readString());
+ for(int count = 0; count < in.readVarInt(); count++) {
+ String name = in.readString();
+ String value = in.readString();
+ String signature = in.readString();
+ this.profile.getProperties().put(name, new ProfileProperty(name, value, signature));
+ }
+
this.x = in.readInt() / 32D;
this.y = in.readInt() / 32D;
this.z = in.readInt() / 32D;
@@ -95,8 +97,15 @@ public class ServerSpawnPlayerPacket implements Packet {
@Override
public void write(NetOutput out) throws IOException {
out.writeVarInt(this.entityId);
- out.writeString(this.uuid);
- out.writeString(this.name);
+ out.writeString(this.profile.getId());
+ out.writeString(this.profile.getName());
+ out.writeVarInt(this.profile.getProperties().size());
+ for(ProfileProperty property : this.profile.getProperties().values()) {
+ out.writeString(property.getName());
+ out.writeString(property.getValue());
+ out.writeString(property.getSignature());
+ }
+
out.writeInt((int) (this.x * 32));
out.writeInt((int) (this.y * 32));
out.writeInt((int) (this.z * 32));
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerScoreboardObjectivePacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerScoreboardObjectivePacket.java
index 48c09663..99ff5a46 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerScoreboardObjectivePacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerScoreboardObjectivePacket.java
@@ -9,16 +9,16 @@ import ch.spacebase.packetlib.packet.Packet;
public class ServerScoreboardObjectivePacket implements Packet {
private String name;
- private String value;
+ private String displayName;
private Action action;
@SuppressWarnings("unused")
private ServerScoreboardObjectivePacket() {
}
- public ServerScoreboardObjectivePacket(String name, String value, Action action) {
+ public ServerScoreboardObjectivePacket(String name, String displayName, Action action) {
this.name = name;
- this.value = value;
+ this.displayName = displayName;
this.action = action;
}
@@ -26,8 +26,8 @@ public class ServerScoreboardObjectivePacket implements Packet {
return this.name;
}
- public String getValue() {
- return this.value;
+ public String getDisplayName() {
+ return this.displayName;
}
public Action getAction() {
@@ -37,14 +37,14 @@ public class ServerScoreboardObjectivePacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
this.name = in.readString();
- this.value = in.readString();
+ this.displayName = in.readString();
this.action = Action.values()[in.readByte()];
}
@Override
public void write(NetOutput out) throws IOException {
out.writeString(this.name);
- out.writeString(this.value);
+ out.writeString(this.displayName);
out.writeByte(this.action.ordinal());
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerTeamPacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerTeamPacket.java
index 4fc72452..33072b95 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerTeamPacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerTeamPacket.java
@@ -95,7 +95,7 @@ public class ServerTeamPacket implements Packet {
}
if(this.action == Action.CREATE || this.action == Action.ADD_PLAYER || this.action == Action.REMOVE_PLAYER) {
- this.players = new String[in.readShort()];
+ this.players = new String[in.readVarInt()];
for(int index = 0; index < this.players.length; index++) {
this.players[index] = in.readString();
}
@@ -114,7 +114,7 @@ public class ServerTeamPacket implements Packet {
}
if(this.action == Action.CREATE || this.action == Action.ADD_PLAYER || this.action == Action.REMOVE_PLAYER) {
- out.writeShort(this.players.length);
+ out.writeVarInt(this.players.length);
for(String player : this.players) {
out.writeString(player);
}
diff --git a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerUpdateScorePacket.java b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerUpdateScorePacket.java
index ea7b526c..a3b76c4f 100644
--- a/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerUpdateScorePacket.java
+++ b/src/main/java/ch/spacebase/mc/protocol/packet/ingame/server/scoreboard/ServerUpdateScorePacket.java
@@ -8,60 +8,60 @@ import ch.spacebase.packetlib.packet.Packet;
public class ServerUpdateScorePacket implements Packet {
- private String name;
+ private String entry;
private Action action;
- private String scoreName;
- private int scoreValue;
+ private String objective;
+ private int value;
@SuppressWarnings("unused")
private ServerUpdateScorePacket() {
}
- public ServerUpdateScorePacket(String name) {
- this.name = name;
+ public ServerUpdateScorePacket(String entry) {
+ this.entry = entry;
this.action = Action.REMOVE;
}
- public ServerUpdateScorePacket(String name, String scoreName, int scoreValue) {
- this.name = name;
- this.scoreName = scoreName;
- this.scoreValue = scoreValue;
+ public ServerUpdateScorePacket(String entry, String objective, int value) {
+ this.entry = entry;
+ this.objective = objective;
+ this.value = value;
this.action = Action.ADD_OR_UPDATE;
}
- public String getScoreboardName() {
- return this.name;
+ public String getEntry() {
+ return this.entry;
}
public Action getAction() {
return this.action;
}
- public String getScoreName() {
- return this.scoreName;
+ public String getObjective() {
+ return this.objective;
}
- public int getScoreValue() {
- return this.scoreValue;
+ public int getValue() {
+ return this.value;
}
@Override
public void read(NetInput in) throws IOException {
- this.name = in.readString();
+ this.entry = in.readString();
this.action = Action.values()[in.readByte()];
if(this.action == Action.ADD_OR_UPDATE) {
- this.scoreName = in.readString();
- this.scoreValue = in.readInt();
+ this.objective = in.readString();
+ this.value = in.readVarInt();
}
}
@Override
public void write(NetOutput out) throws IOException {
- out.writeString(this.name);
+ out.writeString(this.entry);
out.writeByte(this.action.ordinal());
if(this.action == Action.ADD_OR_UPDATE) {
- out.writeString(this.scoreName);
- out.writeInt(this.scoreValue);
+ out.writeString(this.objective);
+ out.writeVarInt(this.value);
}
}
diff --git a/src/main/java/ch/spacebase/mc/util/IOUtils.java b/src/main/java/ch/spacebase/mc/util/IOUtils.java
index 09e246ce..b0550518 100644
--- a/src/main/java/ch/spacebase/mc/util/IOUtils.java
+++ b/src/main/java/ch/spacebase/mc/util/IOUtils.java
@@ -1,5 +1,6 @@
package ch.spacebase.mc.util;
+import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
@@ -31,5 +32,18 @@ public class IOUtils {
in.close();
return writer.toString();
}
+
+ public static byte[] toByteArray(InputStream in) throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte buffer[] = new byte[DEFAULT_BUFFER_SIZE];
+ int n = 0;
+ while(-1 != (n = in.read(buffer))) {
+ out.write(buffer, 0, n);
+ }
+
+ in.close();
+ out.close();
+ return out.toByteArray();
+ }
}
diff --git a/src/main/java/ch/spacebase/mc/util/NetUtil.java b/src/main/java/ch/spacebase/mc/util/NetUtil.java
index f2d894b4..18ba115e 100644
--- a/src/main/java/ch/spacebase/mc/util/NetUtil.java
+++ b/src/main/java/ch/spacebase/mc/util/NetUtil.java
@@ -22,10 +22,44 @@ import ch.spacebase.packetlib.io.NetOutput;
public class NetUtil {
+ private static final int[] EXPONENTS_OF_TWO = new int[] { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 };
+
+ private static final int POSITION_X_SIZE = 1 + lastExponentOfTwo(nextPowerOfTwo(30000000));
+ private static final int POSITION_Z_SIZE = POSITION_X_SIZE;
+ private static final int POSITION_Y_SIZE = 64 - POSITION_X_SIZE - POSITION_Z_SIZE;
+ private static final int POSITION_Y_SHIFT = POSITION_Z_SIZE;
+ private static final int POSITION_X_SHIFT = POSITION_Y_SHIFT + POSITION_Y_SIZE;
+ private static final long POSITION_X_MASK = (1L << POSITION_X_SIZE) - 1;
+ private static final long POSITION_Y_MASK = (1L << POSITION_Y_SIZE) - 1;
+ private static final long POSITION_Z_MASK = (1L << POSITION_Z_SIZE) - 1;
+
/**
* An unfortunately necessary hack value for chunk data packet checks as to whether a packet contains skylight values or not.
*/
public static boolean hasSky = true;
+
+ private static int nextPowerOfTwo(int i) {
+ int minusOne = i - 1;
+ minusOne |= minusOne >> 1;
+ minusOne |= minusOne >> 2;
+ minusOne |= minusOne >> 4;
+ minusOne |= minusOne >> 8;
+ minusOne |= minusOne >> 16;
+ return minusOne + 1;
+ }
+
+ private static boolean isPowerOfTwo(int i) {
+ return i != 0 && (i & i - 1) == 0;
+ }
+
+ private static int nextExponentOfTwo(int i) {
+ int power = isPowerOfTwo(i) ? i : nextPowerOfTwo(i);
+ return EXPONENTS_OF_TWO[(int) (power * 125613361L >> 27) & 31];
+ }
+
+ public static int lastExponentOfTwo(int i) {
+ return nextExponentOfTwo(i) - (isPowerOfTwo(i) ? 0 : 1);
+ }
public static CompoundTag readNBT(NetInput in) throws IOException {
short length = in.readShort();
@@ -50,13 +84,15 @@ public class NetUtil {
}
public static Position readPosition(NetInput in) throws IOException {
- return new Position(in.readInt(), in.readUnsignedByte(), in.readInt());
+ long val = in.readLong();
+ int x = (int) (val << 64 - POSITION_X_SHIFT - POSITION_X_SIZE >> 64 - POSITION_X_SIZE);
+ int y = (int) (val << 64 - POSITION_Y_SHIFT - POSITION_Y_SIZE >> 64 - POSITION_Y_SIZE);
+ int z = (int) (val << 64 - POSITION_Z_SIZE >> 64 - POSITION_Z_SIZE);
+ return new Position(x, y, z);
}
-
+
public static void writePosition(NetOutput out, Position pos) throws IOException {
- out.writeInt(pos.getX());
- out.writeByte(pos.getY());
- out.writeInt(pos.getZ());
+ out.writeLong((pos.getX() & POSITION_X_MASK) << POSITION_X_SHIFT | (pos.getY() & POSITION_Y_MASK) << POSITION_Y_SHIFT | (pos.getZ() & POSITION_Z_MASK));
}
public static ItemStack readItem(NetInput in) throws IOException {
diff --git a/src/main/resources/yggdrasil_session_pubkey.der b/src/main/resources/yggdrasil_session_pubkey.der
new file mode 100644
index 00000000..9c79a3aa
Binary files /dev/null and b/src/main/resources/yggdrasil_session_pubkey.der differ