From bcf5dc4ceadde06d843f7812c6a7fcf2778a2f41 Mon Sep 17 00:00:00 2001 From: xfl03 Date: Fri, 11 Nov 2016 19:48:42 +0800 Subject: [PATCH] RFC-2396 URL encode Remove unused imports Added ElfSkin for test --- Common/customskinloader/CustomSkinLoader.java | 9 +- .../config/SkinSiteProfile.java | 13 ++ .../loader/ElfSkinLoader.java | 132 ++++++++++++++++++ .../loader/JsonAPILoader.java | 5 - .../loader/MojangAPILoader.java | 4 - .../loader/ProfileLoader.java | 4 +- .../loader/jsonapi/CustomSkinAPI.java | 1 - .../loader/jsonapi/UniSkinAPI.java | 1 - .../profile/ProfileCache.java | 3 - .../customskinloader/profile/UserProfile.java | 2 +- Common/customskinloader/tweaker/Tweaker.java | 1 - .../utils/HttpRequestUtil.java | 21 ++- Common/customskinloader/utils/HttpUtil0.java | 13 -- .../customskinloader/utils/MinecraftUtil.java | 11 +- README.md | 2 + 15 files changed, 167 insertions(+), 55 deletions(-) create mode 100644 Common/customskinloader/loader/ElfSkinLoader.java diff --git a/Common/customskinloader/CustomSkinLoader.java b/Common/customskinloader/CustomSkinLoader.java index f55ae91..601235a 100644 --- a/Common/customskinloader/CustomSkinLoader.java +++ b/Common/customskinloader/CustomSkinLoader.java @@ -1,16 +1,8 @@ package customskinloader; import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.HashMap; import java.util.Map; -import org.apache.commons.io.Charsets; -import org.apache.commons.io.IOUtils; - import com.google.common.collect.Maps; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -47,6 +39,7 @@ public class CustomSkinLoader { //SkinSiteProfile.creatLegacy("Minecrack","http://minecrack.fr.nf/mc/skinsminecrackd/{USERNAME}.png","http://minecrack.fr.nf/mc/cloaksminecrackd/{USERNAME}.png",null), SkinSiteProfile.createUniSkinAPI("SkinMe","http://www.skinme.cc/uniskin/"), SkinSiteProfile.createCustomSkinAPI("McSkin","http://www.mcskin.cc/"), + SkinSiteProfile.createElfSkin("ElfSkin"), SkinSiteProfile.createLegacy("LocalSkin","LocalSkin/skins/{USERNAME}.png","LocalSkin/capes/{USERNAME}.png","LocalSkin/elytras/{USERNAME}.png")}; public static final Gson GSON=new GsonBuilder().setPrettyPrinting().create(); diff --git a/Common/customskinloader/config/SkinSiteProfile.java b/Common/customskinloader/config/SkinSiteProfile.java index ad54540..4ae83b6 100644 --- a/Common/customskinloader/config/SkinSiteProfile.java +++ b/Common/customskinloader/config/SkinSiteProfile.java @@ -25,6 +25,13 @@ public class SkinSiteProfile { ssp.root=root; return ssp; } + public static SkinSiteProfile creatCustomSkinAPIPlus(String name,String root){ + SkinSiteProfile ssp=new SkinSiteProfile(); + ssp.name=name; + ssp.type="CustomSkinAPIPlus"; + ssp.root=root; + return ssp; + } public static SkinSiteProfile createUniSkinAPI(String name,String root){ SkinSiteProfile ssp=new SkinSiteProfile(); ssp.name=name; @@ -41,4 +48,10 @@ public class SkinSiteProfile { ssp.elytra=elytra; return ssp; } + public static SkinSiteProfile createElfSkin(String name){ + SkinSiteProfile ssp=new SkinSiteProfile(); + ssp.name=name; + ssp.type="ElfSkin"; + return ssp; + } } diff --git a/Common/customskinloader/loader/ElfSkinLoader.java b/Common/customskinloader/loader/ElfSkinLoader.java new file mode 100644 index 0000000..0778444 --- /dev/null +++ b/Common/customskinloader/loader/ElfSkinLoader.java @@ -0,0 +1,132 @@ +package customskinloader.loader; + +import java.util.HashMap; +import java.util.prefs.Preferences; + +import org.apache.commons.lang3.StringUtils; + +import com.mojang.authlib.GameProfile; + +import customskinloader.CustomSkinLoader; +import customskinloader.config.SkinSiteProfile; +import customskinloader.loader.ProfileLoader.IProfileLoader; +import customskinloader.profile.UserProfile; +import customskinloader.utils.HttpRequestUtil; +import customskinloader.utils.HttpRequestUtil.HttpRequest; +import customskinloader.utils.HttpRequestUtil.HttpResponce; +import customskinloader.utils.MinecraftUtil; + +//For ElfSkin http://www.mcelf.com/s/mcskin +public class ElfSkinLoader implements IProfileLoader { + private static final String LOGIN_URL="http://status.mcelf.com/login?gid=%SERVER_IP%&name=%USERNAME%&oid=%ELF_ID%"; + private static final String LOGOUT_URL="http://status.mcelf.com/logout?gid=%SERVER_IP%&name=%USERNAME%"; + private static final String PROFILE_URL="http://status.mcelf.com/s?gid=%SERVER_IP%&name=%USERNAME%"; + + private static String elfID=Preferences.userRoot().node("elfskin").get("elfid", "null"); + private static String lastLoginServer=null; + private static HashMap cache=new HashMap(); + @Override + public UserProfile loadProfile(SkinSiteProfile ssp, GameProfile gameProfile) throws Exception { + String username=gameProfile.getName(); + String ip=MinecraftUtil.getServerAddress(); + if(elfID!=null && isIPChange(ip)){ + if(lastLoginServer!=null) + makeLogout(lastLoginServer,MinecraftUtil.getCurrentUsername()); + Profile[] ps=makeLogin(ip,MinecraftUtil.getCurrentUsername(),elfID); + cache.clear(); + for(Profile pp:ps){ + cache.put(pp.name, pp); + } + } + + Profile p=cache.containsKey(username)?cache.get(username):getProfile(MinecraftUtil.getServerAddress(),username); + if(p==null) + return null; + UserProfile profile=new UserProfile(); + profile.skinUrl=p.skin; + profile.capeUrl=p.cape; + if(profile.isEmpty()){ + CustomSkinLoader.logger.info("Profile is empty."); + return null; + } + return profile; + } + private boolean isIPChange(String newIP){ + return lastLoginServer==null ? newIP!=null : !lastLoginServer.equalsIgnoreCase(newIP); + } + + public static Profile[] makeLogin(String ip,String username,String elfID){ + String url=LOGIN_URL.replaceAll("%SERVER_IP%", ip).replaceAll("%USERNAME%", username).replaceAll("%ELF_ID%", elfID); + HttpResponce responce=HttpRequestUtil.makeHttpRequest(new HttpRequest(url)); + + if(!responce.success||StringUtils.isEmpty(responce.content)){ + CustomSkinLoader.logger.info("Request failed."); + return null; + } + BasicResponce r=CustomSkinLoader.GSON.fromJson(responce.content, BasicResponce.class); + if(r.error!=0){ + CustomSkinLoader.logger.info("Error "+r.error+": "+r.msg); + return null; + } + if(r.players==null||r.players.length==0){ + CustomSkinLoader.logger.info("No Profile found."); + return null; + } + + return r.players; + } + public static void makeLogout(String ip,String username){ + String url=LOGOUT_URL.replaceAll("%SERVER_IP%", ip).replaceAll("%USERNAME%", username); + HttpResponce responce=HttpRequestUtil.makeHttpRequest(new HttpRequest(url).setCacheTime(-1)); + } + public static Profile getProfile(String ip,String username){ + String url=PROFILE_URL.replaceAll("%SERVER_IP%", ip).replaceAll("%USERNAME%", username); + HttpResponce responce=HttpRequestUtil.makeHttpRequest(new HttpRequest(url)); + + if(!responce.success||StringUtils.isEmpty(responce.content)){ + CustomSkinLoader.logger.info("Request failed."); + return null; + } + BasicResponce r=CustomSkinLoader.GSON.fromJson(responce.content, BasicResponce.class); + if(r.error!=0){ + CustomSkinLoader.logger.info("Error "+r.error+": "+r.msg); + return null; + } + if(r.players==null||r.players.length==0){ + CustomSkinLoader.logger.info("Profile not found."); + return null; + } + + return r.players[0]; + } + private static class BasicResponce{ + int error; + String msg; + + String gid; + String expired_at; + Profile[] players; + } + private static class Profile{ + String name; + String login_time; + String skin; + String cape; + } + + + @Override + public boolean compare(SkinSiteProfile ssp0, SkinSiteProfile ssp1) { + return true; + } + + @Override + public String getName() { + return "ElfSkin"; + } + + @Override + public void initLocalFolder(SkinSiteProfile ssp) { + //No local skin + } +} diff --git a/Common/customskinloader/loader/JsonAPILoader.java b/Common/customskinloader/loader/JsonAPILoader.java index fadb80c..961fff2 100644 --- a/Common/customskinloader/loader/JsonAPILoader.java +++ b/Common/customskinloader/loader/JsonAPILoader.java @@ -2,9 +2,6 @@ package customskinloader.loader; import java.io.File; import java.io.FileInputStream; -import java.util.List; -import java.util.Map; -import java.util.Set; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; @@ -14,10 +11,8 @@ import com.mojang.authlib.GameProfile; import customskinloader.CustomSkinLoader; import customskinloader.config.SkinSiteProfile; import customskinloader.loader.jsonapi.*; -import customskinloader.profile.ModelManager0; import customskinloader.profile.UserProfile; import customskinloader.utils.HttpRequestUtil; -import customskinloader.utils.HttpTextureUtil; import customskinloader.utils.HttpUtil0; import customskinloader.utils.HttpRequestUtil.HttpRequest; import customskinloader.utils.HttpRequestUtil.HttpResponce; diff --git a/Common/customskinloader/loader/MojangAPILoader.java b/Common/customskinloader/loader/MojangAPILoader.java index f4c7a56..4d409fa 100644 --- a/Common/customskinloader/loader/MojangAPILoader.java +++ b/Common/customskinloader/loader/MojangAPILoader.java @@ -11,10 +11,8 @@ import org.apache.commons.lang3.StringUtils; import com.google.common.collect.Iterables; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.JsonSyntaxException; import com.mojang.authlib.GameProfile; import com.mojang.authlib.minecraft.MinecraftProfileTexture; -import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; import com.mojang.authlib.minecraft.MinecraftSessionService; import com.mojang.authlib.properties.Property; import com.mojang.authlib.yggdrasil.response.MinecraftTexturesPayload; @@ -27,8 +25,6 @@ import customskinloader.profile.UserProfile; import customskinloader.utils.HttpRequestUtil; import customskinloader.utils.HttpRequestUtil.HttpRequest; import customskinloader.utils.HttpRequestUtil.HttpResponce; -import customskinloader.utils.HttpUtil0; -import net.minecraft.client.Minecraft; public class MojangAPILoader implements ProfileLoader.IProfileLoader { diff --git a/Common/customskinloader/loader/ProfileLoader.java b/Common/customskinloader/loader/ProfileLoader.java index d7e2e5c..a5cbdb2 100644 --- a/Common/customskinloader/loader/ProfileLoader.java +++ b/Common/customskinloader/loader/ProfileLoader.java @@ -11,8 +11,10 @@ public class ProfileLoader { private static final IProfileLoader[] DEFAULT_LOADERS={ new MojangAPILoader(), new JsonAPILoader(JsonAPILoader.Type.CustomSkinAPI), + new JsonAPILoader(JsonAPILoader.Type.CustomSkinAPIPlus), new LegacyLoader(), - new JsonAPILoader(JsonAPILoader.Type.UniSkinAPI)}; + new JsonAPILoader(JsonAPILoader.Type.UniSkinAPI), + new ElfSkinLoader()}; public static final HashMap LOADERS=initLoaders(); diff --git a/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java b/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java index 63e8add..2f89059 100644 --- a/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java +++ b/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java @@ -2,7 +2,6 @@ package customskinloader.loader.jsonapi; import java.util.LinkedHashMap; import java.util.Map; -import java.util.Set; import org.apache.commons.lang3.StringUtils; diff --git a/Common/customskinloader/loader/jsonapi/UniSkinAPI.java b/Common/customskinloader/loader/jsonapi/UniSkinAPI.java index a12df00..c4b08aa 100644 --- a/Common/customskinloader/loader/jsonapi/UniSkinAPI.java +++ b/Common/customskinloader/loader/jsonapi/UniSkinAPI.java @@ -1,6 +1,5 @@ package customskinloader.loader.jsonapi; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; diff --git a/Common/customskinloader/profile/ProfileCache.java b/Common/customskinloader/profile/ProfileCache.java index e9b42ce..918ec76 100644 --- a/Common/customskinloader/profile/ProfileCache.java +++ b/Common/customskinloader/profile/ProfileCache.java @@ -7,10 +7,7 @@ import java.util.HashMap; import org.apache.commons.io.IOUtils; -import com.google.gson.Gson; - import customskinloader.CustomSkinLoader; -import customskinloader.config.Config; import customskinloader.utils.TimeUtil; public class ProfileCache { diff --git a/Common/customskinloader/profile/UserProfile.java b/Common/customskinloader/profile/UserProfile.java index b751dea..576b579 100644 --- a/Common/customskinloader/profile/UserProfile.java +++ b/Common/customskinloader/profile/UserProfile.java @@ -72,7 +72,7 @@ public class UserProfile { * @return status (true - empty) */ public boolean isEmpty(){ - return skinUrl==null && capeUrl==null && elytraUrl==null; + return StringUtils.isEmpty(skinUrl) && StringUtils.isEmpty(capeUrl) && StringUtils.isEmpty(elytraUrl); } public boolean hasSkinUrl(){ return StringUtils.isNotEmpty(skinUrl); diff --git a/Common/customskinloader/tweaker/Tweaker.java b/Common/customskinloader/tweaker/Tweaker.java index 51d8e0c..182dfe3 100644 --- a/Common/customskinloader/tweaker/Tweaker.java +++ b/Common/customskinloader/tweaker/Tweaker.java @@ -4,7 +4,6 @@ import customskinloader.Logger; import customskinloader.utils.MinecraftUtil; import java.io.File; -import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.ArrayUtils; diff --git a/Common/customskinloader/utils/HttpRequestUtil.java b/Common/customskinloader/utils/HttpRequestUtil.java index 4e2f689..85a8afd 100644 --- a/Common/customskinloader/utils/HttpRequestUtil.java +++ b/Common/customskinloader/utils/HttpRequestUtil.java @@ -5,20 +5,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; +import java.net.URI; import java.net.URL; -import java.net.URLDecoder; -import java.security.cert.X509Certificate; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.Charsets; import org.apache.commons.io.FileUtils; @@ -102,7 +94,10 @@ public class HttpRequestUtil { } //Init Connection - HttpURLConnection c = (HttpURLConnection) (new URL(request.url)).openConnection(); + String url=new URI(request.url).toASCIIString(); + if(!url.equalsIgnoreCase(request.url)) + CustomSkinLoader.logger.info("Encoded URL: "+url); + HttpURLConnection c = (HttpURLConnection) (new URL(url)).openConnection(); c.setReadTimeout(1000 * 10); c.setConnectTimeout(1000 * 10); c.setDoInput(true); @@ -188,13 +183,13 @@ public class HttpRequestUtil { } return responce; } - private final static Pattern MAX_AGE_PATTERN = Pattern.compile("(\\d+)"); + private final static Pattern MAX_AGE_PATTERN = Pattern.compile(".*?max-age=(\\d+).*?"); private static long getExpire(HttpURLConnection connection,int cacheTime){ String cacheControl=connection.getHeaderField("Cache-Control"); if(StringUtils.isNotEmpty(cacheControl)){ Matcher m=MAX_AGE_PATTERN.matcher(cacheControl); - if(m!=null && (m.matches()||m.find())) - return TimeUtil.getUnixTimestamp(Long.parseLong(m.group(0))); + if(m!=null && m.matches()) + return TimeUtil.getUnixTimestamp(Long.parseLong(m.group(m.groupCount()))); } long expires=connection.getExpiration(); if(expires>0) diff --git a/Common/customskinloader/utils/HttpUtil0.java b/Common/customskinloader/utils/HttpUtil0.java index 561ea4c..aa77e04 100644 --- a/Common/customskinloader/utils/HttpUtil0.java +++ b/Common/customskinloader/utils/HttpUtil0.java @@ -1,16 +1,8 @@ package customskinloader.utils; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.URL; import java.net.UnknownHostException; import java.security.cert.X509Certificate; -import java.util.zip.GZIPInputStream; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; @@ -19,13 +11,8 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; -import org.apache.commons.io.Charsets; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; -import customskinloader.CustomSkinLoader; - public class HttpUtil0 { public static boolean isLocal(String url){ return url==null? false : !url.startsWith("http"); diff --git a/Common/customskinloader/utils/MinecraftUtil.java b/Common/customskinloader/utils/MinecraftUtil.java index 8ccd987..e4099b7 100644 --- a/Common/customskinloader/utils/MinecraftUtil.java +++ b/Common/customskinloader/utils/MinecraftUtil.java @@ -35,7 +35,7 @@ public class MinecraftUtil { private static ArrayList minecraftVersion=new ArrayList(); private static String minecraftMainVersion=null; - private final static Pattern MINECRAFT_VERSION_PATTERN = Pattern.compile("(\\d+\\.\\d+[\\.]?\\d*)"); + private final static Pattern MINECRAFT_VERSION_PATTERN = Pattern.compile(".*?(\\d+\\.\\d+[\\.]?\\d*).*?"); public static ArrayList getMinecraftVersions(){ if(minecraftVersion!=null&&!minecraftVersion.isEmpty()) return minecraftVersion; @@ -54,13 +54,13 @@ public class MinecraftUtil { for(String version:getMinecraftVersions()){ Matcher m = null; try{ - m=MINECRAFT_VERSION_PATTERN.matcher(" "+version+" "); + m=MINECRAFT_VERSION_PATTERN.matcher(version); }catch(Exception e){ e.printStackTrace(); } - if(m==null || (!m.matches() && !m.find())) + if(m==null || !m.matches()) continue; - minecraftMainVersion=m.group(0); + minecraftMainVersion=m.group(m.groupCount()); break; } return minecraftMainVersion; @@ -78,6 +78,9 @@ public class MinecraftUtil { return true; return HttpUtil0.isLanServer(data.serverIP); } + public static String getCurrentUsername(){ + return net.minecraft.client.Minecraft.getMinecraft().getSession().getProfile().getName(); + } private final static Pattern MINECRAFT_CORE_FILE_PATTERN = Pattern.compile("^(.*?)/versions/([^\\/\\\\]*?)/([^\\/\\\\]*?).jar$"); private static void testProbe(){ diff --git a/README.md b/README.md index 78143b1..dc1f032 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,10 @@ Release Page : [MCBBS](http://www.mcbbs.net/thread-269807-1-1.html) Skin Load API Supported: - [Mojang API](http://wiki.vg/Mojang_API) - [CustomSkinAPI](https://github.com/xfl03/CustomSkinLoaderAPI/tree/master/CustomSkinAPI) +- CustomSkinAPIPlus (Test Only) - [UniSkinAPI](https://github.com/RecursiveG/UniSkinServer/tree/master/doc) - Legacy +- ElfSkin (Test Only) You can use this feature to customize your skin load list so as to load from any skin server you want. If you are the owner of skin server, you can use CustomSkinLoader to load skin from your server if one of the api has been actualized.