From 1373935193b55b77762dd41c880a337c23405031 Mon Sep 17 00:00:00 2001 From: Recursive G Date: Mon, 27 Apr 2015 14:22:27 +0800 Subject: [PATCH] cleanup --- .../uniskinmod/AsmTransformer.java | 49 +---- .../uniskinmod/MojangTexturePayload.java | 6 +- .../uniskinmod/ProfileResponseBuilder.java | 190 ------------------ .../uniskinmod/UniSkinApiProfile.java | 16 +- .../devinprogress/uniskinmod/UniSkinMod.java | 67 +----- 5 files changed, 11 insertions(+), 317 deletions(-) delete mode 100644 src/main/java/org/devinprogress/uniskinmod/ProfileResponseBuilder.java diff --git a/src/main/java/org/devinprogress/uniskinmod/AsmTransformer.java b/src/main/java/org/devinprogress/uniskinmod/AsmTransformer.java index 48b9828..6da55d3 100644 --- a/src/main/java/org/devinprogress/uniskinmod/AsmTransformer.java +++ b/src/main/java/org/devinprogress/uniskinmod/AsmTransformer.java @@ -3,21 +3,10 @@ import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.*; -/** - * Transformers for authlib-1.5.17 and MC1.8 - */ public class AsmTransformer extends BaseAsmTransformer { private static final String INVOKE_TARGET_CLASS=UniSkinMod.class.getName().replace(".","/"); public AsmTransformer(){ - /*hookMethod("com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository","findProfilesByNames","findProfilesByNames", - "([Ljava/lang/String;Lcom/mojang/authlib/Agent;Lcom/mojang/authlib/ProfileLookupCallback;)V", - new findProfilesByNamesTransformer()); - hookMethod("com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService","fillGameProfile","fillGameProfile", - "(Lcom/mojang/authlib/GameProfile;Z)Lcom/mojang/authlib/GameProfile;", - new fillGameProfileTransformer()); - */ - hookMethod("net.minecraft.client.network.NetworkPlayerInfo","","", "(Lnet/minecraft/network/play/server/S38PacketPlayerListItem$AddPlayerData;)V", new NetworkPlayerInfoTransformer()); @@ -37,7 +26,7 @@ public AsmTransformer(){ private class NetworkPlayerInfoTransformer implements IMethodTransformer{ @Override public void transform(MethodNode mn, String srgName, boolean devEnv, String classObfName) { - final String FIELD_NAME=devEnv?"gameProfile":"field_178867_a"; + final String FIELD_NAME=devEnv?"gameProfile":"a"; //field_178867_a AbstractInsnNode n= getInsnPutField(mn, FIELD_NAME, 1); mn.instructions.insertBefore(n, new MethodInsnNode(Opcodes.INVOKESTATIC,INVOKE_TARGET_CLASS, "fillGameProfile","(Lcom/mojang/authlib/GameProfile;)Lcom/mojang/authlib/GameProfile;",false)); @@ -64,42 +53,6 @@ public void transform(MethodNode mn, String srgName, boolean devEnv, String clas } } - private class findProfilesByNamesTransformer implements IMethodTransformer{ - @Override - public void transform(MethodNode mn, String srgName, boolean devEnv, String classObfName) { - AbstractInsnNode n=getNthInsnNode(mn, Opcodes.CHECKCAST,2).getNext(); - mn.instructions.insertBefore(n,new VarInsnNode(Opcodes.ALOAD,7)); - mn.instructions.insertBefore(n,new MethodInsnNode(Opcodes.INVOKESTATIC,INVOKE_TARGET_CLASS, - "fillMissionProfile","(Lcom/mojang/authlib/yggdrasil/response/ProfileSearchResultsResponse;Ljava/util/List;)Lcom/mojang/authlib/yggdrasil/response/ProfileSearchResultsResponse;",false)); - } - } - - private class fillGameProfileTransformer implements IMethodTransformer{ - @Override - public void transform(MethodNode mn, String srgName, boolean devEnv, String classObfName) { - AbstractInsnNode n=getNthInsnNode(mn,Opcodes.ALOAD,3); - LabelNode label=new LabelNode(); - LabelNode label2=new LabelNode(); - mn.instructions.insertBefore(n,new VarInsnNode(Opcodes.ALOAD,1)); - mn.instructions.insertBefore(n,new MethodInsnNode(Opcodes.INVOKESTATIC,INVOKE_TARGET_CLASS, - "isOnlinePlayer","(Lcom/mojang/authlib/GameProfile;)Z",false)); - mn.instructions.insertBefore(n,new JumpInsnNode(Opcodes.IFEQ,label)); - - n=getNthInsnNode(mn,Opcodes.ASTORE,3); - mn.instructions.insertBefore(n,new JumpInsnNode(Opcodes.GOTO,label2)); - mn.instructions.insertBefore(n,label); - mn.instructions.insertBefore(n,new InsnNode(Opcodes.ACONST_NULL)); - mn.instructions.insertBefore(n,label2); - - n=getNthInsnNode(mn,Opcodes.ALOAD,6); - mn.instructions.insertBefore(n,new VarInsnNode(Opcodes.ALOAD,1)); - mn.instructions.insertBefore(n,new VarInsnNode(Opcodes.ALOAD,4)); - mn.instructions.insertBefore(n,new MethodInsnNode(Opcodes.INVOKESTATIC,INVOKE_TARGET_CLASS, - "fillResponse","(Lcom/mojang/authlib/GameProfile;Lcom/mojang/authlib/yggdrasil/response/MinecraftProfilePropertiesResponse;)Lcom/mojang/authlib/yggdrasil/response/MinecraftProfilePropertiesResponse;",false)); - mn.instructions.insertBefore(n,new VarInsnNode(Opcodes.ASTORE,4)); - } - } - /** Bypass the Signature Verification */ private class getTexturesTransformer implements IMethodTransformer{ @Override diff --git a/src/main/java/org/devinprogress/uniskinmod/MojangTexturePayload.java b/src/main/java/org/devinprogress/uniskinmod/MojangTexturePayload.java index 44945c5..34d6cb3 100644 --- a/src/main/java/org/devinprogress/uniskinmod/MojangTexturePayload.java +++ b/src/main/java/org/devinprogress/uniskinmod/MojangTexturePayload.java @@ -27,7 +27,7 @@ public class MojangTexturePayload { public MojangTexturePayload(String playerName){ isPublic=true; profileName=playerName; - profileId=UniSkinMod.getOfflineUUID(playerName); + profileId= getOfflineUUID(playerName); textures=new HashMap(); } @@ -39,6 +39,10 @@ public static MojangTexturePayload fromProperty(Property property){ return gson.fromJson(e, MojangTexturePayload.class); } + public static UUID getOfflineUUID(String name){ + return UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)); + } + public Property toProperty(){ String j = gson.toJson(this); String b64 = Base64.encodeBase64String(j.getBytes(Charsets.UTF_8)); diff --git a/src/main/java/org/devinprogress/uniskinmod/ProfileResponseBuilder.java b/src/main/java/org/devinprogress/uniskinmod/ProfileResponseBuilder.java deleted file mode 100644 index dc5c5a1..0000000 --- a/src/main/java/org/devinprogress/uniskinmod/ProfileResponseBuilder.java +++ /dev/null @@ -1,190 +0,0 @@ -package org.devinprogress.uniskinmod; - -import com.google.common.collect.Iterables; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.mojang.authlib.minecraft.MinecraftProfileTexture; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import com.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse; -import com.mojang.authlib.yggdrasil.response.ProfileSearchResultsResponse; -import com.mojang.util.UUIDTypeAdapter; -import net.minecraft.client.Minecraft; -import org.apache.commons.codec.Charsets; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.IOUtils; - -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.*; - -/** - * Pack & Unpack Mojang's official RequestResponse to add custom URLs - */ -public class ProfileResponseBuilder { - private final MinecraftProfilePropertiesResponse orig; - private static final Gson gson=new GsonBuilder() - .registerTypeAdapter(UUID.class, new UUIDTypeAdapter()) - .registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()) - .registerTypeAdapter(ProfileSearchResultsResponse.class, new ProfileSearchResultsResponse.Serializer()) - .create(); - - private UUID id; - private String name; - private PropertyMap otherProperties; - private MojangTexturePayload payload; - - private class MojangTexturePayload { - public long timestamp; - public UUID profileId; - public String profileName; - public boolean isPublic; - public Map textures; - } - - private class UniSkinApiJson{ - public String player_name; - public long last_update; - public List model_preference; - public Map skins; - public String cape; - } - - private class ResponseStructure{ - public UUID id; - public String name; - public PropertyMap properties=new PropertyMap(); - } - - public ProfileResponseBuilder(final MinecraftProfilePropertiesResponse orig, String name){ - this.orig=orig; - - if (orig==null||orig.getName()==null||orig.getName().trim().equals("")) - this.name=name; - else - this.name=orig.getName(); - - if (orig==null||orig.getId()==null) - this.id=UniSkinMod.getOfflineUUID(name); - else - this.id=orig.getId(); - - this.otherProperties=new PropertyMap(); - if (orig!=null&&orig.getProperties()!=null) - this.otherProperties.putAll(orig.getProperties()); - - Property textureProperty = Iterables.getFirst(this.otherProperties.get("textures"), null); - if (textureProperty==null) { - this.payload = new MojangTexturePayload(); - this.payload.profileName=this.name; - this.payload.profileId=this.id; - this.payload.isPublic=true; - this.payload.textures=new HashMap(); - this.payload.timestamp=System.currentTimeMillis(); - }else{ - String json = new String(Base64.decodeBase64(textureProperty.getValue()), Charsets.UTF_8); - this.payload=gson.fromJson(json,MojangTexturePayload.class); - } - - this.otherProperties.removeAll("textures"); - } - - private static final String URL_PROFILE_FMT="{root}/{player_name}.json"; - private static final String URL_TEXTURE_FMT="{root}/textures/{texture_hash}"; - - public MinecraftProfilePropertiesResponse getFilledResponse(final List roots){ - if (this.payload.textures.containsKey(MinecraftProfileTexture.Type.CAPE) && - this.payload.textures.containsKey(MinecraftProfileTexture.Type.SKIN)) - return this.orig; - - boolean modified=false; - for (String root:roots){ - try { - String jsonURI = URL_PROFILE_FMT.replace("{player_name}", this.name).replace("{root}",root); - String json = httpRequest(jsonURI); - if (json == null) continue; - UniSkinMod.log.debug(String.format("Querying player %s@%s got reply %s",this.name,root,json.replace("\n",""))); - UniSkinApiJson obj=gson.fromJson(json,UniSkinApiJson.class); - - if (!this.payload.textures.containsKey(MinecraftProfileTexture.Type.CAPE)) { - if (obj.cape!=null){ - String cape_url=URL_TEXTURE_FMT.replace("{root}",root). - replace("{texture_hash}",obj.cape); - this.payload.textures.put(MinecraftProfileTexture.Type.CAPE, - new MinecraftProfileTexture(cape_url,null)); - modified=true; - UniSkinMod.log.info(String.format("New cape url from %s for player %s added: %s",root,this.name,cape_url)); - } - } - - if (!this.payload.textures.containsKey(MinecraftProfileTexture.Type.SKIN)) { - if (obj.skins!=null&&obj.model_preference!=null&&obj.model_preference.size()>0){ - for(String model:obj.model_preference) { - if (obj.skins.containsKey(model) && obj.skins.get(model)!=null && obj.skins.get(model).length()>0){ - boolean slimModel=model.equalsIgnoreCase("slim"); - String skin_url=URL_TEXTURE_FMT.replace("{root}",root).replace("{texture_hash}", obj.skins.get(model)); - this.payload.textures.put(MinecraftProfileTexture.Type.SKIN, - new MinecraftProfileTexture(skin_url,slimModel? - new HashMap(){{put("model","slim");}}:null)); - modified=true; - UniSkinMod.log.info(String.format("New %s skin url from %s for player %s added: %s", - model,root,this.name,skin_url)); - } - } - } - } - - if (this.payload.textures.containsKey(MinecraftProfileTexture.Type.CAPE) && - this.payload.textures.containsKey(MinecraftProfileTexture.Type.SKIN)) - break; - }catch(Exception ex){ - ex.printStackTrace(); - } - } - - if (modified) { - try{ - ResponseStructure tmp=new ResponseStructure(); - tmp.id=this.id; - tmp.name=this.name; - tmp.properties=this.otherProperties; - - String payloadJson=gson.toJson(this.payload); - UniSkinMod.log.debug(String.format("Final texture property for player %s: %s",this.name,payloadJson)); - String payloadBase64=Base64.encodeBase64String(payloadJson.getBytes(Charsets.UTF_8)); - Property property=new Property("textures",payloadBase64); - - tmp.properties.put("textures",property); - - String payloadStr=gson.toJson(tmp); - UniSkinMod.log.debug(String.format("Full payload for player %s: %s",this.name,payloadStr)); - - return gson.fromJson(payloadStr,MinecraftProfilePropertiesResponse.class); - }catch(Exception ex){ - ex.printStackTrace(); - return this.orig; - } - }else{ - return this.orig; - } - } - - private String httpRequest(String url) { - try { - HttpURLConnection conn = (HttpURLConnection) (new URL(url)).openConnection(Minecraft.getMinecraft().getProxy()); - conn.setReadTimeout(1000 * 5); - conn.setConnectTimeout(1000 * 5); - conn.setUseCaches(false); - conn.setInstanceFollowRedirects(true); - conn.connect(); - int errorNo = conn.getResponseCode(); - if (errorNo != 200) - return null; - InputStream iStream = conn.getInputStream(); - return IOUtils.toString(iStream, Charsets.UTF_8); - } catch (Exception e) { - return null; - } - } -} diff --git a/src/main/java/org/devinprogress/uniskinmod/UniSkinApiProfile.java b/src/main/java/org/devinprogress/uniskinmod/UniSkinApiProfile.java index 97f2dd8..241cb50 100644 --- a/src/main/java/org/devinprogress/uniskinmod/UniSkinApiProfile.java +++ b/src/main/java/org/devinprogress/uniskinmod/UniSkinApiProfile.java @@ -1,12 +1,7 @@ package org.devinprogress.uniskinmod; import com.google.common.base.Charsets; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; import com.google.gson.Gson; -import com.mojang.authlib.GameProfile; import net.minecraft.client.Minecraft; import org.apache.commons.io.IOUtils; @@ -15,11 +10,8 @@ import java.net.URL; import java.util.List; import java.util.Map; -import java.util.concurrent.TimeUnit; -/** - * Created by recursiveg on 15-4-26. - */ +/** Universal Skin API */ public class UniSkinApiProfile { private class ProfileJSON{ @@ -74,14 +66,14 @@ private UniSkinApiProfile(String name, String root){ model=m; skin=URL_TEXTURE_FMT.replace("{root}",root).replace("{texture_hash}",json.skins.get(m)); hasProfile=true; - UniSkinMod.log.info("Player Skin Selected: %s %s %s",name,model,json.skins.get(m)); + UniSkinMod.log.info(String.format("Player Skin Selected: %s %s %s",name,model,json.skins.get(m))); break; } } if(json.cape!=null&&json.cape.length()>3){ cape=URL_TEXTURE_FMT.replace("{root}",root).replace("{texture_hash}",json.cape); hasProfile=true; - UniSkinMod.log.info("Player Cape Selected: %s %s",name,json.cape); + UniSkinMod.log.info(String.format("Player Cape Selected: %s %s",name,json.cape)); } update=json.last_update; } @@ -97,4 +89,4 @@ public String getModel(){ public long lastUpdate(){ return update; } -} \ No newline at end of file +} diff --git a/src/main/java/org/devinprogress/uniskinmod/UniSkinMod.java b/src/main/java/org/devinprogress/uniskinmod/UniSkinMod.java index 7db9119..7b568e8 100644 --- a/src/main/java/org/devinprogress/uniskinmod/UniSkinMod.java +++ b/src/main/java/org/devinprogress/uniskinmod/UniSkinMod.java @@ -42,25 +42,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ public class UniSkinMod { - private static Field profilesFieldAccessor; public static final Logger log= LogManager.getLogger("UniSkinMod"); public static final List roots=new ArrayList(); - - static{ - try{ - profilesFieldAccessor=ProfileSearchResultsResponse.class.getDeclaredField("profiles"); - profilesFieldAccessor.setAccessible(true); - }catch(Exception ex){ - profilesFieldAccessor=null; - } - } - private static Cache cache = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).build(); - /** Hijack the constructor of NetworkPlayerInfo & Skull renderer*/ + /** Hijack the GameProfile in NetworkPlayerInfo & Skull renderer*/ public static GameProfile fillGameProfile(final GameProfile gameProfileIn) { - //if (cache.getIfPresent(gameProfileIn)!=null) return gameProfileIn; if (gameProfileIn==null) return null; final String player_name=gameProfileIn.getName(); @@ -92,60 +80,7 @@ public Property call() throws Exception { gameProfileIn.getProperties().removeAll("textures"); gameProfileIn.getProperties().put("textures", finalP); - //cache.put(gameProfileIn,gameProfileIn); return gameProfileIn; } - public static ProfileSearchResultsResponse fillMissionProfile(ProfileSearchResultsResponse response, List request){ - if(response.getProfiles().length profs=new ArrayList(); - try{ - profs.addAll(Arrays.asList((GameProfile[]) profilesFieldAccessor.get(response))); - - for (String name : request) { - boolean ok=false; - for (GameProfile prof:profs) { - if (name.equalsIgnoreCase(prof.getName())) { - ok=true; break; - } - } - if (!ok) { - UUID uuid=getOfflineUUID(name); - profs.add(new GameProfile(uuid, name)); - log.info(String.format("Player: %s has no uuid, assigning: %s",name,uuid.toString())); - } - } - - GameProfile[] tmp=new GameProfile[profs.size()]; - for(int i=0;i