diff --git a/1.7.10-mcp908/src/minecraft/customskinloader/profile/ModelManager0.java b/1.7.10-mcp908/src/minecraft/customskinloader/profile/ModelManager0.java index ca1db15..8e7de5f 100644 --- a/1.7.10-mcp908/src/minecraft/customskinloader/profile/ModelManager0.java +++ b/1.7.10-mcp908/src/minecraft/customskinloader/profile/ModelManager0.java @@ -36,6 +36,14 @@ public class ModelManager0 { public static Model getEnumModel(String model){ return models.get(model); } + + /** + * Check if model is skin. + * @since 14.5 + * */ + public static boolean isSkin(Model model){ + return model==Model.SKIN_DEFAULT||model==Model.SKIN_SLIM; + } /** * Check if elytra is supported. diff --git a/Common/LICENSE b/Common/LICENSE index b87558a..a189b32 100644 --- a/Common/LICENSE +++ b/Common/LICENSE @@ -1,3 +1,5 @@ +English(en) + LICENSE - Binary File You could not modify binary file. Feel free to use and share this mod and unmodified file in anyway like modpack. @@ -5,9 +7,30 @@ When using in modpack, you must put 'CustomSkinLoader' in mod list. You could not repost this mod to any website without permission. You could not earn money with this mod excluding modpack. +LICENSE - Source Code +GPLv3: http://www.gnu.org/licenses/gpl.html +When using the code, you should change the name of package to avoid others' misunderstanding. + +OTHER - Useful Link +Source Code: https://github.com/xfl03/MCCustomSkinLoader +Release Page: http://www.mcbbs.net/thread-269807-1-1.html +Build Server: https://ci.infstudio.net/job/CustomSkinLoader/ + + +中文简体(zh_cn) + 许可 - 编译产物 您不得对CustomSkinLoader的成品jar内部内容进行任何修改 您可以在不经我许可的情况下,以任意方式传播这一mod以及jar文件(例如加入整合包)。 -在加入整合包时,请必须在帖子内mod列表中明确写上"万用皮肤补丁"或者"CustomSkinLoader"或者附上本贴地址。 +在加入整合包时,请必须在帖子内mod列表中明确写上"万用皮肤补丁"或者"CustomSkinLoader"或者附上发布页面地址。 您不得在未经许可的情况下,在国内外任何网站进行二次发布(包括皮肤站)。 -您不得以任何形式出售CustomSkinLoader或任何使用或参考CustomSkinLoader源代码的作品。 \ No newline at end of file +您不得以任何形式出售CustomSkinLoader或任何使用或参考CustomSkinLoader源代码的作品。 + +许可 - 源代码 +GPLv3: http://www.gnu.org/licenses/gpl.html +为避免他人误解,您在使用代码时必须修改包名。 + +其他 - 有用的链接 +源代码: https://github.com/xfl03/MCCustomSkinLoader +发布页面: http://www.mcbbs.net/thread-269807-1-1.html +构建服务器: https://ci.infstudio.net/job/CustomSkinLoader/ \ No newline at end of file diff --git a/Common/customskinloader/loader/JsonAPILoader.java b/Common/customskinloader/loader/JsonAPILoader.java index c2c3f06..afe79f2 100644 --- a/Common/customskinloader/loader/JsonAPILoader.java +++ b/Common/customskinloader/loader/JsonAPILoader.java @@ -20,12 +20,17 @@ import customskinloader.utils.HttpTextureUtil; import customskinloader.utils.HttpUtil0; public class JsonAPILoader implements ProfileLoader.IProfileLoader { - public static final String TEXTURES="textures/"; + public interface IJsonAPI { public String toJsonUrl(String root,String username); + public String getPayload(); public UserProfile toUserProfile(String root,String json,boolean local); public String getName(); } + public static class ErrorProfile{ + public int errno; + public String msg; + } public static enum Type{ CustomSkinAPI(new CustomSkinAPI()),UniSkinAPI(new UniSkinAPI()); public IJsonAPI jsonAPI; @@ -33,10 +38,12 @@ public class JsonAPILoader implements ProfileLoader.IProfileLoader { this.jsonAPI=jsonAPI; } } + private Type type; public JsonAPILoader(Type type){ this.type=type; } + @Override public UserProfile loadProfile(SkinSiteProfile ssp, GameProfile gameProfile) throws Exception { String username=gameProfile.getName(); @@ -55,12 +62,19 @@ public class JsonAPILoader implements ProfileLoader.IProfileLoader { } json=IOUtils.toString(new FileInputStream(jsonFile)); }else{ - json=HttpUtil0.readHttp(jsonUrl,ssp.userAgent); + json=HttpUtil0.readHttp(jsonUrl,ssp.userAgent,type.jsonAPI.getPayload()); } if(json==null||json.equals("")){ CustomSkinLoader.logger.info("Profile not found."); return null; } + + ErrorProfile profile=CustomSkinLoader.GSON.fromJson(json, ErrorProfile.class); + if(profile.errno!=0){ + CustomSkinLoader.logger.info("Error "+profile.errno+": "+profile.msg); + return null; + } + UserProfile p=type.jsonAPI.toUserProfile(ssp.root, json, local); if(p==null||p.isEmpty()){ CustomSkinLoader.logger.info("Both skin and cape not found."); diff --git a/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java b/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java index 740aebc..eac37a6 100644 --- a/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java +++ b/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java @@ -25,10 +25,6 @@ public class CustomSkinAPI implements IJsonAPI { @Override public UserProfile toUserProfile(String root, String json, boolean local) { CustomSkinAPIProfile profile=CustomSkinLoader.GSON.fromJson(json, CustomSkinAPIProfile.class); - if(profile.errno!=0){ - CustomSkinLoader.logger.info("Error "+profile.errno+": "+profile.msg); - return null; - } UserProfile p=new UserProfile(); if(StringUtils.isNotBlank(profile.skin)){ @@ -54,10 +50,17 @@ public class CustomSkinAPI implements IJsonAPI { textures.putAll(profile.textures); if(textures.isEmpty()) return p; + + boolean hasSkin=false; for(String model:textures.keySet()){ Model enumModel=ModelManager0.getEnumModel(model); if(enumModel==null||StringUtils.isEmpty(textures.get(model))) continue; + if(ModelManager0.isSkin(enumModel)) + if(hasSkin) + continue; + else + hasSkin=true; String url=root+TEXTURES+textures.get(model); if(local) url=HttpTextureUtil.getLocalFakeUrl(url); @@ -71,12 +74,14 @@ public class CustomSkinAPI implements IJsonAPI { public Map textures; public Map skins; + public String skin; public String cape; public String elytra; - - public int errno; - public String msg; + } + @Override + public String getPayload() { + return null; } @Override public String getName() { diff --git a/Common/customskinloader/loader/jsonapi/UniSkinAPI.java b/Common/customskinloader/loader/jsonapi/UniSkinAPI.java index 17edfe7..28b156a 100644 --- a/Common/customskinloader/loader/jsonapi/UniSkinAPI.java +++ b/Common/customskinloader/loader/jsonapi/UniSkinAPI.java @@ -25,10 +25,6 @@ public class UniSkinAPI implements IJsonAPI { @Override public UserProfile toUserProfile(String root, String json, boolean local) { UniSkinAPIProfile profile=CustomSkinLoader.GSON.fromJson(json, UniSkinAPIProfile.class); - if(profile.errno!=0){ - CustomSkinLoader.logger.info("Error "+profile.errno+": "+profile.msg); - return null; - } UserProfile p=new UserProfile(); if(StringUtils.isNotBlank(profile.cape)){ @@ -39,10 +35,17 @@ public class UniSkinAPI implements IJsonAPI { if(profile.skins==null||profile.skins.isEmpty()) return p; + + boolean hasSkin=false; for(String model:profile.model_preference){ Model enumModel=ModelManager0.getEnumModel(model); if(enumModel==null||StringUtils.isEmpty(profile.skins.get(model))) continue; + if(ModelManager0.isSkin(enumModel)) + if(hasSkin) + continue; + else + hasSkin=true; String url=root+TEXTURES+profile.skins.get(model); if(local) url=HttpTextureUtil.getLocalFakeUrl(url); @@ -63,9 +66,10 @@ public class UniSkinAPI implements IJsonAPI { public Map skins; public String cape; - - public int errno; - public String msg; + } + @Override + public String getPayload() { + return null; } @Override public String getName() { diff --git a/Common/customskinloader/profile/ModelManager0.java b/Common/customskinloader/profile/ModelManager0.java index cc90205..e095f96 100644 --- a/Common/customskinloader/profile/ModelManager0.java +++ b/Common/customskinloader/profile/ModelManager0.java @@ -45,6 +45,14 @@ public class ModelManager0 { return models.get(model); } + /** + * Check if model is skin. + * @since 14.5 + * */ + public static boolean isSkin(Model model){ + return model==Model.SKIN_DEFAULT||model==Model.SKIN_SLIM; + } + /** * Check if elytra is supported. * @since 14.5 diff --git a/Common/customskinloader/utils/HttpUtil0.java b/Common/customskinloader/utils/HttpUtil0.java index fb896aa..09058e8 100644 --- a/Common/customskinloader/utils/HttpUtil0.java +++ b/Common/customskinloader/utils/HttpUtil0.java @@ -3,6 +3,7 @@ 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.MalformedURLException; import java.net.URL; @@ -11,6 +12,7 @@ import java.util.zip.GZIPInputStream; 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; @@ -20,10 +22,13 @@ public class HttpUtil0 { * @since 13.11 */ public static String readHttp(String url,String userAgent){ + return readHttp(url,userAgent,null); + } + public static String readHttp(String url,String userAgent,String payload){ HttpURLConnection c=null; try { CustomSkinLoader.logger.info("Try to read '"+url+(userAgent==null?"' without user agent.":"' with user agent '"+userAgent+"'.")); - c=createConnection(url,userAgent); + c=createConnection(url,userAgent,payload); int res = c.getResponseCode()/100; if (res==4||res==5||c.getResponseCode()==HttpURLConnection.HTTP_NO_CONTENT) { CustomSkinLoader.logger.info("Failed to read (Response Code: "+c.getResponseCode()+")"); @@ -31,7 +36,9 @@ public class HttpUtil0 { } CustomSkinLoader.logger.info("Successfully read (Response Code: "+c.getResponseCode()+" , Content Length: "+c.getContentLength()+")"); InputStream is = getStream(c); - return IOUtils.toString(is, Charsets.UTF_8); + String text=IOUtils.toString(is, Charsets.UTF_8); + CustomSkinLoader.logger.info("Content: "+text); + return text; } catch (Exception e) { CustomSkinLoader.logger.info("Failed to read (Exception: "+e.toString()+")"); return null; @@ -101,14 +108,26 @@ public class HttpUtil0 { } } private static HttpURLConnection createConnection(String url,String userAgent) throws MalformedURLException, IOException{ + return createConnection(url,userAgent,null); + } + private static HttpURLConnection createConnection(String url,String userAgent,String payload) throws MalformedURLException, IOException{ HttpURLConnection c = (HttpURLConnection) (new URL(url)).openConnection(); c.setReadTimeout(1000 * 10); c.setConnectTimeout(1000 * 10); + c.setDoInput(true); + c.setUseCaches(false); + c.setInstanceFollowRedirects(true); + c.setRequestProperty("Accept-Encoding", "gzip"); if(userAgent!=null) c.setRequestProperty("User-Agent",userAgent); - c.setUseCaches(false); - c.setInstanceFollowRedirects(true); + if(StringUtils.isNotEmpty(payload)){ + CustomSkinLoader.logger.info("Payload: "+payload); + c.setDoOutput(true); + OutputStream os=c.getOutputStream(); + IOUtils.write(payload, os); + IOUtils.closeQuietly(os); + } c.connect(); return c; } diff --git a/README.md b/README.md index c4252f4..78143b1 100644 --- a/README.md +++ b/README.md @@ -70,10 +70,11 @@ You could not repost this mod to any website without permission. You could not earn money with this mod excluding modpack. ###Source Code ####Package 'customskinloader' -Copyright(C) 2013-2016 JLChnToZ xfl03 +Copyright(C) 2013-2016 JLChnToZ xfl03 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -GPLv3: http://www.gnu.org/licenses/gpl.html +GPLv3: http://www.gnu.org/licenses/gpl.html +You should change the name of package to avoid others' misunderstanding. diff --git a/build.properties b/build.properties index da6a3d1..dba4480 100644 --- a/build.properties +++ b/build.properties @@ -3,4 +3,4 @@ group=customskinloader version=14.5 dev_version= #RELEASE: snapshot=0 -snapshot=1 \ No newline at end of file +snapshot=0 \ No newline at end of file