Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updated UUIDFetcher and GameProfileBuilder to make skin chnage work a… #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 0 additions & 13 deletions .idea/libraries/Maven__org_projectlombok_lombok_1_18_4.xml

This file was deleted.

4 changes: 2 additions & 2 deletions .idea/zTag.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 13 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>de.pkmnplatin.ztag</groupId>
<artifactId>ztag</artifactId>
<version>1.0-SNAPSHOT</version>
<version>2.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
Expand All @@ -20,17 +20,25 @@
</plugins>
</build>


<dependencies>
<!-- mvn install:install-file \-->
<!-- -Dfile=src\main\resources\craftbukkit-1.8.8.jar \-->
<!-- -DgroupId=org.bukkit \-->
<!-- -DartifactId=craftbukkit \-->
<!-- -Dversion=1.8.8-R0.1-SNAPSHOT \-->
<!-- -Dpackaging=jar \-->
<!-- -DgeneratePom=true-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>LATEST</version>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
<version>2.8.6</version>
<scope>compile</scope>
</dependency>
</dependencies>
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/de/pkmnplatin/ztag/TagBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,32 @@

import de.pkmnplatin.ztag.profile.ProfileManager;
import de.pkmnplatin.ztag.reflect.Version;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.mcstats.Metrics;

/**
* Created by Jona on 16.06.2017.
*/
@Getter
public class TagBase extends JavaPlugin {

@Getter
private static TagBase instance;

private Version version;
private ProfileManager profileManager;

public static TagBase getInstance() {
return instance;
}

public Version getVersion() {
return version;
}

public ProfileManager getProfileManager() {
return profileManager;
}

public static void log(String msg) {
instance.getLogger().info(msg);
}
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/de/pkmnplatin/ztag/profile/TagProfile.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package de.pkmnplatin.ztag.profile;

import de.pkmnplatin.ztag.TagBase;
import lombok.Getter;
import org.bukkit.entity.Player;

/**
* Created by Jona on 06.07.2017.
*/
@Getter
public class TagProfile {

private final Player player;
Expand All @@ -16,6 +14,22 @@ public class TagProfile {
private String skin;
private final String realName;

public Player getPlayer() {
return player;
}

public String getTag() {
return tag;
}

public String getSkin() {
return skin;
}

public String getRealName() {
return realName;
}

public TagProfile(Player player, String realName, String tag, String skin) {
this.player = player;
this.realName = realName;
Expand Down
13 changes: 10 additions & 3 deletions src/main/java/de/pkmnplatin/ztag/reflect/Version.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package de.pkmnplatin.ztag.reflect;

import lombok.Getter;
import org.bukkit.Bukkit;

/**
Expand All @@ -20,14 +19,22 @@ public enum Version {
v1_8_R2("1.8.2", 182),
v1_8_R1("1.8.0 - 1.8.1", 181);

@Getter private String mcVersion;
@Getter private int versionId;
private String mcVersion;
private int versionId;

Version(String mcVersion, int versionId) {
this.mcVersion = mcVersion;
this.versionId = versionId;
}

public String getMcVersion() {
return mcVersion;
}

public int getVersionId() {
return versionId;
}

public static Version detectServerVersion() {
String versionString = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
for (Version v : Version.values()) {
Expand Down
176 changes: 176 additions & 0 deletions src/main/java/de/pkmnplatin/ztag/util/GameProfileBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
package de.pkmnplatin.ztag.util;

import com.google.gson.*;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.properties.PropertyMap;
import com.mojang.util.UUIDTypeAdapter;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;

/**
* @author Jofkos
* @see https://gist.github.com/Jofkos/79af290e94acdc7d7d5b
*/

public class GameProfileBuilder {

private static final String SERVICE_URL = "https://sessionserver.mojang.com/session/minecraft/profile/%s?unsigned=false";
private static final String JSON_SKIN = "{\"timestamp\":%d,\"profileId\":\"%s\",\"profileName\":\"%s\",\"isPublic\":true,\"textures\":{\"SKIN\":{\"url\":\"%s\"}}}";
private static final String JSON_CAPE = "{\"timestamp\":%d,\"profileId\":\"%s\",\"profileName\":\"%s\",\"isPublic\":true,\"textures\":{\"SKIN\":{\"url\":\"%s\"},\"CAPE\":{\"url\":\"%s\"}}}";

private static Gson gson = new GsonBuilder().disableHtmlEscaping().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).registerTypeAdapter(GameProfile.class, new GameProfileSerializer()).registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create();

private static HashMap<UUID, CachedProfile> cache = new HashMap<UUID, CachedProfile>();

private static long cacheTime = -1;

/**
* Don't run in main thread!
* <p>
* Fetches the GameProfile from the Mojang servers
*
* @param uuid The player uuid
* @return The GameProfile
* @throws IOException If something wents wrong while fetching
* @see GameProfile
*/
public static GameProfile fetch(UUID uuid) throws IOException {
return fetch(uuid, false);
}

/**
* Don't run in main thread!
* <p>
* Fetches the GameProfile from the Mojang servers
*
* @param uuid The player uuid
* @param forceNew If true the cache is ignored
* @return The GameProfile
* @throws IOException If something wents wrong while fetching
* @see GameProfile
*/
public static GameProfile fetch(UUID uuid, boolean forceNew) throws IOException {
if (!forceNew && cache.containsKey(uuid) && cache.get(uuid).isValid()) {
return cache.get(uuid).profile;
} else {
HttpURLConnection connection = (HttpURLConnection) new URL(String.format(SERVICE_URL, UUIDTypeAdapter.fromUUID(uuid))).openConnection();
connection.setReadTimeout(5000);

if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
String json = new BufferedReader(new InputStreamReader(connection.getInputStream())).readLine();

GameProfile result = gson.fromJson(json, GameProfile.class);
cache.put(uuid, new CachedProfile(result));
return result;
} else {
if (!forceNew && cache.containsKey(uuid)) {
return cache.get(uuid).profile;
}
JsonObject error = (JsonObject) new JsonParser().parse(new BufferedReader(new InputStreamReader(connection.getErrorStream())).readLine());
throw new IOException(error.get("error").getAsString() + ": " + error.get("errorMessage").getAsString());
}
}
}

/**
* Builds a GameProfile for the specified args
*
* @param uuid The uuid
* @param name The name
* @param skin The url from the skin image
* @return A GameProfile built from the arguments
* @see GameProfile
*/
public static GameProfile getProfile(UUID uuid, String name, String skin) {
return getProfile(uuid, name, skin, null);
}

/**
* Builds a GameProfile for the specified args
*
* @param uuid The uuid
* @param name The name
* @param skinUrl Url from the skin image
* @param capeUrl Url from the cape image
* @return A GameProfile built from the arguments
* @see GameProfile
*/
public static GameProfile getProfile(UUID uuid, String name, String skinUrl, String capeUrl) {
GameProfile profile = new GameProfile(uuid, name);
boolean cape = capeUrl != null && !capeUrl.isEmpty();

List<Object> args = new ArrayList<Object>();
args.add(System.currentTimeMillis());
args.add(UUIDTypeAdapter.fromUUID(uuid));
args.add(name);
args.add(skinUrl);
if (cape) args.add(capeUrl);

profile.getProperties().put("textures", new Property("textures", Base64Coder.encodeString(String.format(cape ? JSON_CAPE : JSON_SKIN, args.toArray(new Object[args.size()])))));
return profile;
}

/**
* Sets the time as long as you want to keep the gameprofiles in cache (-1 = never remove it)
*
* @param time cache time (default = -1)
*/
public static void setCacheTime(long time) {
cacheTime = time;
}

private static class GameProfileSerializer implements JsonSerializer<GameProfile>, JsonDeserializer<GameProfile> {

public GameProfile deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
JsonObject object = (JsonObject) json;
UUID id = object.has("id") ? (UUID) context.deserialize(object.get("id"), UUID.class) : null;
String name = object.has("name") ? object.getAsJsonPrimitive("name").getAsString() : null;
GameProfile profile = new GameProfile(id, name);

if (object.has("properties")) {
for (Entry<String, Property> prop : ((PropertyMap) context.deserialize(object.get("properties"), PropertyMap.class)).entries()) {
profile.getProperties().put(prop.getKey(), prop.getValue());
}
}
return profile;
}

public JsonElement serialize(GameProfile profile, Type type, JsonSerializationContext context) {
JsonObject result = new JsonObject();
if (profile.getId() != null)
result.add("id", context.serialize(profile.getId()));
if (profile.getName() != null)
result.addProperty("name", profile.getName());
if (!profile.getProperties().isEmpty())
result.add("properties", context.serialize(profile.getProperties()));
return result;
}

}

private static class CachedProfile {

private long timestamp = System.currentTimeMillis();
private GameProfile profile;

public CachedProfile(GameProfile profile) {
this.profile = profile;
}

public boolean isValid() {
return cacheTime < 0 || (System.currentTimeMillis() - timestamp) < cacheTime;
}
}
}
Loading