diff --git a/CHANGELOG.md b/CHANGELOG.md
index 119be284..f5f98bce 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+######0.4
+
+* Added forward premium skin
+
######0.3.2
* Run packet readers in a different thread (separated from the Netty I/O Thread)
diff --git a/README.md b/README.md
index a8cf6d58..4c63ea75 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# FastLogin
[](https://travis-ci.org/games647/FastLogin)
+[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8ZBULMAPN7MZC)
Checks if a minecraft player has a paid account (premium). If so, they can skip offline authentication (auth plugins).
So they don't need to enter passwords. This is also called auto login (auto-login).
@@ -134,8 +135,4 @@ It's not tested yet, but all needed methods also exists in Cauldron so it could
###Useful Links:
* [Login Protocol](http://wiki.vg/Protocol#Login)
-* [Protocol Encryption](http://wiki.vg/Protocol_Encryption)
-
-###Donate
-
-[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8ZBULMAPN7MZC)
\ No newline at end of file
+* [Protocol Encryption](http://wiki.vg/Protocol_Encryption)
\ No newline at end of file
diff --git a/bukkit/pom.xml b/bukkit/pom.xml
index f58ebcfc..d0e1f35c 100644
--- a/bukkit/pom.xml
+++ b/bukkit/pom.xml
@@ -5,7 +5,7 @@
com.github.games647
fastlogin-parent
- 0.3
+ 0.4
../pom.xml
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/PlayerSession.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/PlayerSession.java
index 57fe00c7..d1abc6f0 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/PlayerSession.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/PlayerSession.java
@@ -1,5 +1,6 @@
package com.github.games647.fastlogin.bukkit;
+import com.comphenix.protocol.wrappers.WrappedSignedProperty;
import org.apache.commons.lang.ArrayUtils;
/**
@@ -12,6 +13,8 @@ public class PlayerSession {
private final String username;
private final String serverId;
private final byte[] verifyToken;
+
+ private WrappedSignedProperty skinProperty;
private boolean verified;
public PlayerSession(String username, String serverId, byte[] verifyToken) {
@@ -51,6 +54,24 @@ public class PlayerSession {
return username;
}
+ /**
+ * Gets the premium skin of this player
+ *
+ * @return skin property or null if the player has no skin or is a cracked account
+ */
+ public synchronized WrappedSignedProperty getSkin() {
+ return this.skinProperty;
+ }
+
+ /**
+ * Sets the premium skin property which was retrieved by the session server
+ *
+ * @param skinProperty premium skin property
+ */
+ public synchronized void setSkin(WrappedSignedProperty skinProperty) {
+ this.skinProperty = skinProperty;
+ }
+
/**
* Sets whether the player has a premium (paid account) account
* and valid session
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BukkitJoinListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BukkitJoinListener.java
index 6ceb07a4..faf02881 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BukkitJoinListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/BukkitJoinListener.java
@@ -1,5 +1,7 @@
package com.github.games647.fastlogin.bukkit.listener;
+import com.comphenix.protocol.wrappers.WrappedGameProfile;
+import com.comphenix.protocol.wrappers.WrappedSignedProperty;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.PlayerSession;
import com.github.games647.fastlogin.bukkit.hooks.AuthPlugin;
@@ -15,8 +17,8 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.metadata.FixedMetadataValue;
/**
- * This listener tells authentication plugins if the player has a premium account and we checked it successfully.
- * So the plugin can skip authentication.
+ * This listener tells authentication plugins if the player has a premium account and we checked it successfully. So the
+ * plugin can skip authentication.
*/
public class BukkitJoinListener implements Listener {
@@ -34,6 +36,15 @@ public class BukkitJoinListener implements Listener {
public void onPlayerJoin(PlayerJoinEvent joinEvent) {
final Player player = joinEvent.getPlayer();
+ PlayerSession session = plugin.getSessions().get(player.getAddress().toString());
+ if (session != null) {
+ WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player);
+ WrappedSignedProperty skin = session.getSkin();
+ if (skin != null) {
+ gameProfile.getProperties().put("textures", skin);
+ }
+ }
+
Bukkit.getScheduler().runTaskLater(plugin, new Runnable() {
@Override
diff --git a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/EncryptionPacketListener.java b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/EncryptionPacketListener.java
index 3108e48b..0dfcc9a9 100644
--- a/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/EncryptionPacketListener.java
+++ b/bukkit/src/main/java/com/github/games647/fastlogin/bukkit/listener/EncryptionPacketListener.java
@@ -9,6 +9,7 @@ import com.comphenix.protocol.injector.server.TemporaryPlayerFactory;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
+import com.comphenix.protocol.wrappers.WrappedSignedProperty;
import com.github.games647.fastlogin.bukkit.EncryptionUtil;
import com.github.games647.fastlogin.bukkit.FastLoginBukkit;
import com.github.games647.fastlogin.bukkit.PlayerSession;
@@ -28,6 +29,7 @@ import java.util.logging.Level;
import javax.crypto.SecretKey;
import org.bukkit.entity.Player;
+import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
@@ -109,7 +111,7 @@ public class EncryptionPacketListener extends PacketAdapter {
String serverId = (new BigInteger(serverIdHash)).toString(16);
String username = session.getUsername();
- if (hasJoinedServer(username, serverId)) {
+ if (hasJoinedServer(session, serverId)) {
plugin.getLogger().log(Level.FINE, "Player {0} has a verified premium account", username);
session.setVerified(true);
@@ -201,9 +203,9 @@ public class EncryptionPacketListener extends PacketAdapter {
}
}
- private boolean hasJoinedServer(String username, String serverId) {
+ private boolean hasJoinedServer(PlayerSession session, String serverId) {
try {
- String url = HAS_JOINED_URL + "username=" + username + "&serverId=" + serverId;
+ String url = HAS_JOINED_URL + "username=" + session.getUsername() + "&serverId=" + serverId;
HttpURLConnection conn = plugin.getConnection(url);
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
@@ -213,6 +215,17 @@ public class EncryptionPacketListener extends PacketAdapter {
//http://wiki.vg/Protocol_Encryption#Server
JSONObject userData = (JSONObject) JSONValue.parseWithException(line);
String uuid = (String) userData.get("id");
+
+ JSONArray properties = (JSONArray) userData.get("properties");
+ JSONObject skinProperty = (JSONObject) properties.get(0);
+
+ String propertyName = (String) skinProperty.get("name");
+ if (propertyName.equals("textures")) {
+ String skinValue = (String) skinProperty.get("value");
+ String signature = (String) skinProperty.get("signature");
+ session.setSkin(WrappedSignedProperty.fromValues(propertyName, skinValue, signature));
+ }
+
return true;
}
} catch (Exception ex) {
diff --git a/bungee/pom.xml b/bungee/pom.xml
index c3ef0f67..f235bd04 100644
--- a/bungee/pom.xml
+++ b/bungee/pom.xml
@@ -5,7 +5,7 @@
com.github.games647
fastlogin-parent
- 0.3
+ 0.4
../pom.xml
diff --git a/pom.xml b/pom.xml
index a8f241f1..e764e098 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
pom
FastLogin
- 0.3
+ 0.4
2015
https://www.spigotmc.org/resources/fastlogin.14153/