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 3d94bb6..ca1db15 100644 --- a/1.7.10-mcp908/src/minecraft/customskinloader/profile/ModelManager0.java +++ b/1.7.10-mcp908/src/minecraft/customskinloader/profile/ModelManager0.java @@ -1,6 +1,5 @@ package customskinloader.profile; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -16,17 +15,34 @@ import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; * @since 13.1 */ public class ModelManager0 { - private static ArrayList models=null; + public static enum Model{ + SKIN_DEFAULT, + SKIN_SLIM, + CAPE, + ELYTRA + } + private static HashMap models=new HashMap(); + private static Type typeElytra=null; + static{ + models.put("default", Model.SKIN_DEFAULT); + models.put("cape", Model.CAPE); + } /** - * Check if model is available. - * @param model - default/slim - * @since 13.1 + * Get enum for the model. + * @param model - string model + * @since 14.5 */ - public static boolean checkModel(String model){ - if(models==null) - refreshModels(); - return models.contains(model); + public static Model getEnumModel(String model){ + return models.get(model); + } + + /** + * Check if elytra is supported. + * @since 14.5 + */ + public static boolean isElytraSupported(){ + return false; } /** @@ -80,9 +96,4 @@ public class ModelManager0 { MinecraftProfileTexture pt=gson.fromJson(json, MinecraftProfileTexture.class); return pt; } - - private static void refreshModels(){ - models=new ArrayList(); - models.add("default"); - } } diff --git a/Common/customskinloader/CustomSkinLoader.java b/Common/customskinloader/CustomSkinLoader.java index 94ed013..481651e 100644 --- a/Common/customskinloader/CustomSkinLoader.java +++ b/Common/customskinloader/CustomSkinLoader.java @@ -35,6 +35,7 @@ import customskinloader.utils.MinecraftUtil; public class CustomSkinLoader { public static final String CustomSkinLoader_VERSION="@MOD_VERSION@"; public static final String CustomSkinLoader_FULL_VERSION="@MOD_FULL_VERSION@"; + public static final File DATA_DIR=new File(MinecraftUtil.getMinecraftDataDir0(),"CustomSkinLoader"), LOG_FILE=new File(DATA_DIR,"CustomSkinLoader.log"), CONFIG_FILE=new File(DATA_DIR,"CustomSkinLoader.json"); @@ -43,10 +44,10 @@ public class CustomSkinLoader { SkinSiteProfile.createCustomSkinAPI("BlessingSkin","https://skin.prinzeugen.net/csl/"), SkinSiteProfile.createCustomSkinAPI("OneSkin","http://fleey.org/skin/skin_user/skin_json.php/"), //Minecrack could not load skin correctly - //SkinSiteProfile.creatLegacy("Minecrack","http://minecrack.fr.nf/mc/skinsminecrackd/{USERNAME}.png","http://minecrack.fr.nf/mc/cloaksminecrackd/{USERNAME}.png"), + //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.createLegacy("LocalSkin", "LocalSkin/skins/{USERNAME}.png", "LocalSkin/capes/{USERNAME}.png")}; + SkinSiteProfile.createLegacy("LocalSkin","LocalSkin/skins/{USERNAME}.png","LocalSkin/capes/{USERNAME}.png","LocalSkin/elytras/{USERNAME}.png")}; public static final Gson GSON=new GsonBuilder().setPrettyPrinting().create(); public static final Logger logger=initLogger(); diff --git a/Common/customskinloader/config/SkinSiteProfile.java b/Common/customskinloader/config/SkinSiteProfile.java index f02004a..ad54540 100644 --- a/Common/customskinloader/config/SkinSiteProfile.java +++ b/Common/customskinloader/config/SkinSiteProfile.java @@ -3,13 +3,15 @@ package customskinloader.config; public class SkinSiteProfile { public String name; public String type; - public Boolean local=null; - public String root; - public String skin; - public String cape; - public String model; public String userAgent; + public String root; + + public String skin; + public String model; + public String cape; + public String elytra; + public static SkinSiteProfile createMojangAPI(String name){ SkinSiteProfile ssp=new SkinSiteProfile(); ssp.name=name; @@ -30,12 +32,13 @@ public class SkinSiteProfile { ssp.root=root; return ssp; } - public static SkinSiteProfile createLegacy(String name,String skin,String cape){ + public static SkinSiteProfile createLegacy(String name,String skin,String cape,String elytra){ SkinSiteProfile ssp=new SkinSiteProfile(); ssp.name=name; ssp.type="Legacy"; ssp.skin=skin; ssp.cape=cape; + ssp.elytra=elytra; return ssp; } } diff --git a/Common/customskinloader/loader/LegacyLoader.java b/Common/customskinloader/loader/LegacyLoader.java index 3c47531..a9e15ec 100644 --- a/Common/customskinloader/loader/LegacyLoader.java +++ b/Common/customskinloader/loader/LegacyLoader.java @@ -8,6 +8,7 @@ import com.mojang.authlib.GameProfile; import customskinloader.CustomSkinLoader; import customskinloader.config.SkinSiteProfile; +import customskinloader.profile.ModelManager0; import customskinloader.profile.UserProfile; import customskinloader.utils.HttpTextureUtil; import customskinloader.utils.HttpUtil0; @@ -44,6 +45,18 @@ public class LegacyLoader implements ProfileLoader.IProfileLoader { profile.capeUrl=fakeCapeUrl; } } + if(ModelManager0.isElytraSupported()&&StringUtils.isNoneEmpty(ssp.elytra)){ + String elytra=ssp.elytra.replaceAll(USERNAME_REGEX, username); + if(HttpUtil0.isLocal(ssp.elytra)){ + File elytraFile=new File(CustomSkinLoader.DATA_DIR,elytra); + if(elytraFile.exists()&&elytraFile.isFile()) + profile.elytraUrl=HttpTextureUtil.getLocalLegacyFakeUrl(elytra, HttpTextureUtil.getHash(elytra, elytraFile.length(), elytraFile.lastModified())); + }else{ + String fakeCapeUrl=HttpUtil0.getFakeUrl(elytra,ssp.userAgent); + if(fakeCapeUrl!=null&&fakeCapeUrl.equals("")) + profile.elytraUrl=fakeCapeUrl; + } + } if(profile.isEmpty()){ CustomSkinLoader.logger.info("Both skin and cape not found."); return null; diff --git a/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java b/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java index 6000790..cb3872c 100644 --- a/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java +++ b/Common/customskinloader/loader/jsonapi/CustomSkinAPI.java @@ -1,11 +1,15 @@ package customskinloader.loader.jsonapi; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.StringUtils; + import customskinloader.CustomSkinLoader; import customskinloader.loader.JsonAPILoader.IJsonAPI; import customskinloader.profile.ModelManager0; +import customskinloader.profile.ModelManager0.Model; import customskinloader.profile.UserProfile; import customskinloader.utils.HttpTextureUtil; @@ -22,39 +26,50 @@ public class CustomSkinAPI implements IJsonAPI { public UserProfile toUserProfile(String root, String json, boolean local) { CustomSkinAPIProfile profile=CustomSkinLoader.GSON.fromJson(json, CustomSkinAPIProfile.class); UserProfile p=new UserProfile(); - if(profile.skins!=null && !profile.skins.isEmpty()){ - Set keys=profile.skins.keySet(); - for(String s:keys){ - //System.out.println(s+" "+ModelManager0.checkModel(s)); - if(ModelManager0.checkModel(s)){ - if(profile.skins.get(s)==null||profile.skins.get(s).equals("")) - continue; - p.skinUrl=root+TEXTURES+profile.skins.get(s); - p.model=s; - break; - } - } - if(p.skinUrl==null){ - p.skinUrl=root+TEXTURES+profile.skins.get(keys.toArray()[0]); - p.model="default"; - } - }else if(profile.skin!=null && !profile.skin.equals("")){ + + if(StringUtils.isNotBlank(profile.skin)){ p.skinUrl=root+TEXTURES+profile.skin; if(local) p.skinUrl=HttpTextureUtil.getLocalFakeUrl(p.skinUrl); } - if(profile.cape!=null && !profile.cape.equals("")){ + if(StringUtils.isNotBlank(profile.cape)){ p.capeUrl=root+TEXTURES+profile.cape; if(local) p.capeUrl=HttpTextureUtil.getLocalFakeUrl(p.capeUrl); } + if(StringUtils.isNotBlank(profile.elytra)){ + p.elytraUrl=root+TEXTURES+profile.elytra; + if(local) + p.elytraUrl=HttpTextureUtil.getLocalFakeUrl(p.elytraUrl); + } + + Map textures=new LinkedHashMap(); + if(profile.skins!=null) + textures.putAll(profile.skins); + if(profile.textures!=null) + textures.putAll(profile.textures); + if(textures.isEmpty()) + return p; + for(String model:textures.keySet()){ + Model enumModel=ModelManager0.getEnumModel(model); + if(enumModel==null||StringUtils.isEmpty(textures.get(model))) + continue; + String url=root+TEXTURES+textures.get(model); + if(local) + url=HttpTextureUtil.getLocalFakeUrl(url); + p.put(enumModel, url); + } + return p; } private class CustomSkinAPIProfile{ public String username; + public Map textures; + public Map skins; public String skin; public String cape; + public String elytra; } @Override public String getName() { diff --git a/Common/customskinloader/loader/jsonapi/UniSkinAPI.java b/Common/customskinloader/loader/jsonapi/UniSkinAPI.java index 9ab5e5d..21815ff 100644 --- a/Common/customskinloader/loader/jsonapi/UniSkinAPI.java +++ b/Common/customskinloader/loader/jsonapi/UniSkinAPI.java @@ -1,12 +1,16 @@ package customskinloader.loader.jsonapi; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; + import customskinloader.CustomSkinLoader; import customskinloader.loader.JsonAPILoader.IJsonAPI; import customskinloader.profile.ModelManager0; import customskinloader.profile.UserProfile; +import customskinloader.profile.ModelManager0.Model; import customskinloader.utils.HttpTextureUtil; public class UniSkinAPI implements IJsonAPI { @@ -26,39 +30,25 @@ public class UniSkinAPI implements IJsonAPI { return null; } UserProfile p=new UserProfile(); - if(profile.skins!=null && !profile.skins.isEmpty()){ - if(profile.model_preference!=null && !profile.model_preference.isEmpty()){ - for(String s:profile.model_preference){ - if(ModelManager0.checkModel(s)){ - if(profile.skins.get(s)==null||profile.skins.get(s).equals("")) - continue; - p.skinUrl=root+TEXTURES+profile.skins.get(s); - if(local) - p.skinUrl=HttpTextureUtil.getLocalFakeUrl(p.skinUrl); - p.model=s; - break; - } - } - } - if(p.skinUrl==null){ - String s=profile.skins.get("default"); - if(s!=null){ - p.skinUrl=root+TEXTURES+s; - if(local) - p.skinUrl=HttpTextureUtil.getLocalFakeUrl(p.skinUrl); - p.model="default"; - } - } - } - if(profile.skins.get("cape")!=null && !profile.skins.get("cape").equals("")){ - p.capeUrl=root+TEXTURES+profile.skins.get("cape"); - if(local) - p.capeUrl=HttpTextureUtil.getLocalFakeUrl(p.capeUrl); - }else if(profile.cape!=null && !profile.cape.equals("")){ + + if(StringUtils.isNotBlank(profile.cape)){ p.capeUrl=root+TEXTURES+profile.cape; if(local) p.capeUrl=HttpTextureUtil.getLocalFakeUrl(p.capeUrl); } + + if(profile.skins==null||profile.skins.isEmpty()) + return p; + for(String model:profile.model_preference){ + Model enumModel=ModelManager0.getEnumModel(model); + if(enumModel==null||StringUtils.isEmpty(profile.skins.get(model))) + continue; + String url=root+TEXTURES+profile.skins.get(model); + if(local) + url=HttpTextureUtil.getLocalFakeUrl(url); + p.put(enumModel, url); + } + return p; } /** diff --git a/Common/customskinloader/profile/ModelManager0.java b/Common/customskinloader/profile/ModelManager0.java index f1d2c67..cc90205 100644 --- a/Common/customskinloader/profile/ModelManager0.java +++ b/Common/customskinloader/profile/ModelManager0.java @@ -1,8 +1,10 @@ package customskinloader.profile; -import java.util.ArrayList; +import java.util.HashMap; import java.util.Map; +import org.apache.commons.lang3.StringUtils; + import com.google.common.collect.Maps; import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; @@ -14,17 +16,41 @@ import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type; * @since 13.1 */ public class ModelManager0 { - private static ArrayList models=null; + public static enum Model{ + SKIN_DEFAULT, + SKIN_SLIM, + CAPE, + ELYTRA + } + private static HashMap models=new HashMap(); + private static Type typeElytra=null; + static{ + for(Type type:Type.values()){ + if(type.ordinal()==2)//ELYTRA + typeElytra=type; + } + models.put("default", Model.SKIN_DEFAULT); + models.put("slim", Model.SKIN_SLIM); + models.put("cape", Model.CAPE); + if(typeElytra!=null) + models.put("elytra", Model.ELYTRA); + } /** - * Check if model is available. - * @param model - default/slim - * @since 13.1 + * Get enum for the model. + * @param model - string model + * @since 14.5 */ - public static boolean checkModel(String model){ - if(models==null) - refreshModels(); - return models.contains(model); + public static Model getEnumModel(String model){ + return models.get(model); + } + + /** + * Check if elytra is supported. + * @since 14.5 + */ + public static boolean isElytraSupported(){ + return typeElytra!=null; } /** @@ -40,8 +66,9 @@ public class ModelManager0 { MinecraftProfileTexture skin=(MinecraftProfileTexture)profile.get(Type.SKIN); userProfile.skinUrl= skin==null?null:skin.getUrl();//Avoid NullPointerException userProfile.model= skin==null?null:skin.getMetadata("model"); - if(userProfile.model==null||userProfile.model.equals("")) + if(StringUtils.isEmpty(userProfile.model)) userProfile.model="default"; + MinecraftProfileTexture cape=(MinecraftProfileTexture)profile.get(Type.CAPE); userProfile.capeUrl= cape==null?null:cape.getUrl(); return userProfile; @@ -67,6 +94,8 @@ public class ModelManager0 { } if(profile.capeUrl!=null) map.put(Type.CAPE, getProfileTexture(profile.capeUrl,null)); + if(typeElytra!=null && profile.elytraUrl!=null) + map.put(typeElytra, getProfileTexture(profile.elytraUrl,null)); return map; } @@ -81,10 +110,4 @@ public class ModelManager0 { public static MinecraftProfileTexture getProfileTexture(String url,Map metadata){ return new MinecraftProfileTexture(url,metadata); } - - private static void refreshModels(){ - models=new ArrayList(); - models.add("default"); - models.add("slim"); - } } diff --git a/Common/customskinloader/profile/UserProfile.java b/Common/customskinloader/profile/UserProfile.java index 832159b..b751dea 100644 --- a/Common/customskinloader/profile/UserProfile.java +++ b/Common/customskinloader/profile/UserProfile.java @@ -1,5 +1,9 @@ package customskinloader.profile; +import org.apache.commons.lang3.StringUtils; + +import customskinloader.profile.ModelManager0.Model; + /**The instance to storage user's profile in memory temporarily. * In this manner, it could be easier to pass profile in program. * @since 13.1 @@ -25,6 +29,33 @@ public class UserProfile { */ public String capeUrl=null; + /** + * Direct url for elytra. + * @since 14.5 + */ + public String elytraUrl=null; + + public void put(Model model,String url){ + if(model==null||StringUtils.isEmpty(url)) + return; + switch(model){ + case SKIN_DEFAULT: + this.skinUrl=url; + this.model="default"; + return; + case SKIN_SLIM: + this.skinUrl=url; + this.model="slim"; + return; + case CAPE: + this.capeUrl=url; + return; + case ELYTRA: + this.capeUrl=url; + return; + } + } + /** * Get parsed String to output the instance. */ @@ -33,7 +64,7 @@ public class UserProfile { return toString(0); } public String toString(long expiry){ - return "(SkinUrl: "+skinUrl+" , Model: "+model+" , CapeUrl: "+capeUrl+(expiry==0?"":(" , Expiry: "+expiry))+")"; + return "(SkinUrl: "+skinUrl+" , Model: "+model+" , CapeUrl: "+capeUrl+" , ElytraUrl: "+elytraUrl+(expiry==0?"":(" , Expiry: "+expiry))+")"; } /** @@ -41,9 +72,9 @@ public class UserProfile { * @return status (true - empty) */ public boolean isEmpty(){ - return skinUrl==null && capeUrl==null; + return skinUrl==null && capeUrl==null && elytraUrl==null; } public boolean hasSkinUrl(){ - return (skinUrl!=null&&!skinUrl.equals("")); + return StringUtils.isNotEmpty(skinUrl); } } diff --git a/Common/customskinloader/renderer/SkinBuffer.java b/Common/customskinloader/renderer/SkinBuffer.java index 3d0e8ed..ace6e88 100644 --- a/Common/customskinloader/renderer/SkinBuffer.java +++ b/Common/customskinloader/renderer/SkinBuffer.java @@ -23,18 +23,20 @@ public class SkinBuffer implements net.minecraft.client.renderer.IImageBuffer { graphics.drawImage(image,0,0,(ImageObserver)null); if (image.getHeight() == 32 * ratio){//Single Layer //Revert to original algorithm - graphics.drawImage(bufferedimage, 24 * ratio, 48 * ratio, 20 * ratio, 52 * ratio, 4 * ratio, 16 * ratio, 8 * ratio, 20 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 28 * ratio, 48 * ratio, 24 * ratio, 52 * ratio, 8 * ratio, 16 * ratio, 12 * ratio, 20 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 20 * ratio, 52 * ratio, 16 * ratio, 64 * ratio, 8 * ratio, 20 * ratio, 12 * ratio, 32 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 24 * ratio, 52 * ratio, 20 * ratio, 64 * ratio, 4 * ratio, 20 * ratio, 8 * ratio, 32 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 28 * ratio, 52 * ratio, 24 * ratio, 64 * ratio, 0 * ratio, 20 * ratio, 4 * ratio, 32 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 32 * ratio, 52 * ratio, 28 * ratio, 64 * ratio, 12 * ratio, 20 * ratio, 16 * ratio, 32 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 40 * ratio, 48 * ratio, 36 * ratio, 52 * ratio, 44 * ratio, 16 * ratio, 48 * ratio, 20 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 44 * ratio, 48 * ratio, 40 * ratio, 52 * ratio, 48 * ratio, 16 * ratio, 52 * ratio, 20 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 36 * ratio, 52 * ratio, 32 * ratio, 64 * ratio, 48 * ratio, 20 * ratio, 52 * ratio, 32 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 40 * ratio, 52 * ratio, 36 * ratio, 64 * ratio, 44 * ratio, 20 * ratio, 48 * ratio, 32 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 44 * ratio, 52 * ratio, 40 * ratio, 64 * ratio, 40 * ratio, 20 * ratio, 44 * ratio, 32 * ratio, (ImageObserver)null); - graphics.drawImage(bufferedimage, 48 * ratio, 52 * ratio, 44 * ratio, 64 * ratio, 52 * ratio, 20 * ratio, 56 * ratio, 32 * ratio, (ImageObserver)null); + //Right Leg -> Left Leg + graphics.drawImage(bufferedimage, 24 * ratio, 48 * ratio, 20 * ratio, 52 * ratio, 4 * ratio, 16 * ratio, 8 * ratio, 20 * ratio, (ImageObserver)null);//Top + graphics.drawImage(bufferedimage, 28 * ratio, 48 * ratio, 24 * ratio, 52 * ratio, 8 * ratio, 16 * ratio, 12 * ratio, 20 * ratio, (ImageObserver)null);//Bottom + graphics.drawImage(bufferedimage, 20 * ratio, 52 * ratio, 16 * ratio, 64 * ratio, 8 * ratio, 20 * ratio, 12 * ratio, 32 * ratio, (ImageObserver)null);//Left + graphics.drawImage(bufferedimage, 24 * ratio, 52 * ratio, 20 * ratio, 64 * ratio, 4 * ratio, 20 * ratio, 8 * ratio, 32 * ratio, (ImageObserver)null);//Front + graphics.drawImage(bufferedimage, 28 * ratio, 52 * ratio, 24 * ratio, 64 * ratio, 0 * ratio, 20 * ratio, 4 * ratio, 32 * ratio, (ImageObserver)null);//Right + graphics.drawImage(bufferedimage, 32 * ratio, 52 * ratio, 28 * ratio, 64 * ratio, 12 * ratio, 20 * ratio, 16 * ratio, 32 * ratio, (ImageObserver)null);//Back + //Right Arm -> Left Arm + graphics.drawImage(bufferedimage, 40 * ratio, 48 * ratio, 36 * ratio, 52 * ratio, 44 * ratio, 16 * ratio, 48 * ratio, 20 * ratio, (ImageObserver)null);//Top + graphics.drawImage(bufferedimage, 44 * ratio, 48 * ratio, 40 * ratio, 52 * ratio, 48 * ratio, 16 * ratio, 52 * ratio, 20 * ratio, (ImageObserver)null);//Bottom + graphics.drawImage(bufferedimage, 36 * ratio, 52 * ratio, 32 * ratio, 64 * ratio, 48 * ratio, 20 * ratio, 52 * ratio, 32 * ratio, (ImageObserver)null);//Left + graphics.drawImage(bufferedimage, 40 * ratio, 52 * ratio, 36 * ratio, 64 * ratio, 44 * ratio, 20 * ratio, 48 * ratio, 32 * ratio, (ImageObserver)null);//Front + graphics.drawImage(bufferedimage, 44 * ratio, 52 * ratio, 40 * ratio, 64 * ratio, 40 * ratio, 20 * ratio, 44 * ratio, 32 * ratio, (ImageObserver)null);//Right + graphics.drawImage(bufferedimage, 48 * ratio, 52 * ratio, 44 * ratio, 64 * ratio, 52 * ratio, 20 * ratio, 56 * ratio, 32 * ratio, (ImageObserver)null);//Back } graphics.dispose(); this.imageData = ((DataBufferInt)bufferedimage.getRaster().getDataBuffer()).getData();