Files
MCCustomSkinLoader/Common/customskinloader/CustomSkinLoader.java
T

232 lines
8.6 KiB
Java
Raw Normal View History

2016-02-27 15:22:35 +08:00
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;
2016-02-27 21:43:46 +08:00
import java.util.Map;
2016-02-27 15:22:35 +08:00
import org.apache.commons.io.IOUtils;
2016-04-04 13:13:18 +08:00
import com.google.common.collect.Maps;
2016-02-27 15:22:35 +08:00
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
2016-07-31 22:00:46 +08:00
import com.mojang.authlib.GameProfile;
2016-04-03 01:14:33 +08:00
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
2016-02-27 15:22:35 +08:00
import customskinloader.config.Config;
import customskinloader.config.SkinSiteProfile;
import customskinloader.loader.CustomSkinAPILoader;
import customskinloader.loader.IProfileLoader;
import customskinloader.loader.LegacyLoader;
import customskinloader.loader.MojangAPILoader;
import customskinloader.loader.UniSkinAPILoader;
2016-07-31 22:00:46 +08:00
import customskinloader.profile.ModelManager0;
import customskinloader.profile.ProfileCache;
import customskinloader.profile.UserProfile;
2016-04-30 22:12:26 +08:00
import customskinloader.utils.MinecraftUtil;
2016-02-27 15:22:35 +08:00
/**
* Custom skin loader mod for Minecraft.
* @author (C) Jeremy Lam [JLChnToZ] 2013 & Alexander Xia [xfl03] 2014-2016
2016-07-31 22:00:46 +08:00
* @version 14.1 (2016.7.31)
2016-02-27 15:22:35 +08:00
*/
2016-06-06 13:48:59 +08:00
public class CustomSkinLoader {
2016-07-31 22:00:46 +08:00
public static final String CustomSkinLoader_VERSION="14.1";
2016-06-06 13:48:59 +08:00
public static final File DATA_DIR=new File(MinecraftUtil.getMinecraftDataDir0(),"CustomSkinLoader"),
2016-06-06 13:53:45 +08:00
LOG_FILE=new File(DATA_DIR,"CustomSkinLoader.log"),
CONFIG_FILE=new File(DATA_DIR,"CustomSkinLoader.json");
2016-06-06 13:48:59 +08:00
public static final SkinSiteProfile[] DEFAULT_LOAD_LIST={
2016-07-31 22:00:46 +08:00
SkinSiteProfile.createMojangAPI("Mojang"),
SkinSiteProfile.createCustomSkinAPI("BlessingSkin","https://skin.prinzeugen.net/csl/"),
SkinSiteProfile.createCustomSkinAPI("OneSkin","http://fleey.org/skin/skin_user/skin_json.php/"),
2016-06-06 13:48:59 +08:00
//Minecrack could not load skin correctly
2016-07-31 22:00:46 +08:00
//SkinSiteProfile.creatLegacy("Minecrack","http://minecrack.fr.nf/mc/skinsminecrackd/{USERNAME}.png","http://minecrack.fr.nf/mc/cloaksminecrackd/{USERNAME}.png"),
SkinSiteProfile.createUniSkinAPI("SkinMe","http://www.skinme.cc/uniskin/"),
SkinSiteProfile.createCustomSkinAPI("McSkin","http://www.mcskin.cc/"),
SkinSiteProfile.createLegacy("LocalSkin", true, "LocalSkin/skins/{USERNAME}.png", "LocalSkin/capes/{USERNAME}.png")};
2016-06-06 13:48:59 +08:00
public static final HashMap<String,IProfileLoader> LOADERS=initLoaders();
2016-07-31 22:00:46 +08:00
public static final Gson GSON=new GsonBuilder().setPrettyPrinting().create();
2016-06-06 13:48:59 +08:00
public static final Logger logger=initLogger();
public static final Config config=loadConfig0();
2016-07-31 22:00:46 +08:00
private static final ProfileCache profileCache=new ProfileCache();
2016-06-06 13:48:59 +08:00
2016-07-31 22:00:46 +08:00
//For User Skin
public static Map loadProfile(GameProfile gameProfile){
String username=gameProfile.getName();
//Fix: http://hopper.minecraft.net/crashes/minecraft/MCX-2773713
if(username==null){
2016-06-30 23:40:10 +08:00
logger.warning("Could not load profile: username is null.");
return Maps.newHashMap();
}
2016-06-06 13:48:59 +08:00
String tempName=Thread.currentThread().getName();
Thread.currentThread().setName(username);//Change Thread Name
2016-07-31 22:00:46 +08:00
UserProfile profile=null;
if(profileCache.isReady(username)){
logger.info("Cached profile will be used.");
profile=profileCache.getProfile(username);
if(profile==null){
logger.warning("(!Cached Profile is empty!) Expiry:"+profileCache.getExpiry(username));
if(profileCache.isExpired(username)){//force load
profileCache.setLoading(username, true);
profile=loadProfile0(gameProfile);
}
}
else
logger.info(profile.toString(profileCache.getExpiry(username)));
}else{
profileCache.setLoading(username, true);
profile=loadProfile0(gameProfile);
}
2016-06-06 13:48:59 +08:00
Thread.currentThread().setName(tempName);
return ModelManager0.fromUserProfile(profile);
}
2016-07-31 22:00:46 +08:00
//Core
public static UserProfile loadProfile0(GameProfile gameProfile){
String username=gameProfile.getName();
profileCache.setLoading(username, true);
2016-06-06 13:48:59 +08:00
logger.info("Loading "+username+"'s profile.");
for(int i=0;i<config.loadlist.length;i++){
SkinSiteProfile ssp=config.loadlist[i];
logger.info((i+1)+"/"+config.loadlist.length+" Try to load profile from '"+ssp.name+"'.");
IProfileLoader loader=LOADERS.get(ssp.type.toLowerCase());
if(loader==null){
logger.info("Type '"+ssp.type+"' is not defined.");
continue;
}
UserProfile profile=null;
try{
2016-07-31 22:00:46 +08:00
if(ssp.local==null||ssp.local==false)
profile=loader.loadProfile(ssp, gameProfile);
else
profile=loader.loadLocalProfile(ssp, gameProfile);
2016-06-06 13:48:59 +08:00
}catch(Exception e){
2016-07-31 22:00:46 +08:00
logger.warning("Exception occurs while loading.");
logger.warning(e);
2016-06-06 13:48:59 +08:00
}
if(profile==null)
continue;
logger.info(username+"'s profile loaded.");
2016-07-31 22:00:46 +08:00
profileCache.updateCache(username, profile);
profileCache.setLoading(username, false);
logger.info(profile.toString(profileCache.getExpiry(username)));
2016-06-06 13:48:59 +08:00
return profile;
}
2016-07-31 22:00:46 +08:00
logger.info(username+"'s profile not found in load list.");
if(config.enableLocalProfileCache){
UserProfile profile=profileCache.getLocalProfile(username);
if(profile==null)
logger.info(username+"'s LocalProfile not found.");
else{
profileCache.updateCache(username, profile, false);
profileCache.setLoading(username, false);
logger.info(username+"'s LocalProfile will be used.");
logger.info(profile.toString(profileCache.getExpiry(username)));
return profile;
}
}
profileCache.setLoading(username, false);
return null;
2016-06-06 13:48:59 +08:00
}
//For Skull
2016-07-31 22:00:46 +08:00
public static Map<Type, MinecraftProfileTexture> loadProfileFromCache(final GameProfile gameProfile) {
String username=gameProfile.getName();
if(username==null){
logger.warning("Could not load profile from cache: username is null.");
return Maps.newHashMap();
}
if(config.enableUpdateSkull?profileCache.isReady(username):profileCache.isExist(username)){
UserProfile profile=profileCache.getProfile(username);
2016-06-06 13:48:59 +08:00
return ModelManager0.fromUserProfile(profile);
}
2016-07-31 22:00:46 +08:00
//profileCache.setLoading(username, true);
2016-06-06 13:48:59 +08:00
Thread loadThread=new Thread(){
public void run(){
2016-07-31 22:00:46 +08:00
loadProfile0(gameProfile);//Load in thread
2016-06-06 13:48:59 +08:00
}
};
loadThread.setName(username+"'s skull");
loadThread.start();
return Maps.newHashMap();
}
private static Logger initLogger() {
Logger logger=new Logger(LOG_FILE);
logger.info("CustomSkinLoader "+CustomSkinLoader_VERSION);
logger.info("DataDir: "+DATA_DIR.getAbsolutePath());
logger.info("Minecraft: "+MinecraftUtil.getMinecraftVersion());
return logger;
}
private static HashMap<String, IProfileLoader> initLoaders() {
HashMap<String, IProfileLoader> loaders=new HashMap<String, IProfileLoader>();
loaders.put("mojangapi", new MojangAPILoader());
loaders.put("customskinapi", new CustomSkinAPILoader());
loaders.put("legacy", new LegacyLoader());
loaders.put("uniskinapi", new UniSkinAPILoader());
return loaders;
}
private static Config loadConfig0() {
Config config=loadConfig();
2016-07-31 22:00:46 +08:00
logger.info("Enable:"+config.enable+
", EnableSkull:"+config.enableSkull+
", EnableTranSkin:"+config.enableTransparentSkin+
", CacheExpiry:"+config.cacheExpiry+
", enableUpdateSkull:"+config.enableUpdateSkull+
", LocalProfileCache:"+config.enableLocalProfileCache+
2016-06-06 13:48:59 +08:00
", LoadList:"+(config.loadlist==null?0:config.loadlist.length));
2016-07-31 22:00:46 +08:00
if(config.version==null||Float.parseFloat(CustomSkinLoader_VERSION)-Float.parseFloat(config.version)>0.01){
2016-06-06 13:48:59 +08:00
logger.info("Config File is out of date: "+config.version);
config.version=CustomSkinLoader_VERSION;
writeConfig(config,true);
}
return config;
}
private static Config loadConfig() {
logger.info("Config File: "+CONFIG_FILE.getAbsolutePath());
if(!CONFIG_FILE.exists()){
logger.info("Config file not found, use default instead.");
return initConfig();
}
try {
logger.info("Try to load config.");
String json=IOUtils.toString(new FileInputStream(CONFIG_FILE));
2016-07-31 22:00:46 +08:00
Config config=GSON.fromJson(json, Config.class);
2016-06-06 13:48:59 +08:00
logger.info("Successfully load config.");
return config;
}catch (Exception e) {
logger.info("Failed to load config, use default instead.("+e.getMessage()+")");
2016-07-04 14:10:44 +08:00
File brokenFile=new File(DATA_DIR,"BROKEN-CustomSkinLoader.json");
if(brokenFile.exists())
brokenFile.delete();
CONFIG_FILE.renameTo(brokenFile);
2016-06-06 13:48:59 +08:00
return initConfig();
}
}
private static Config initConfig() {
Config config=new Config(DEFAULT_LOAD_LIST);
writeConfig(config,false);
return config;
}
private static void writeConfig(Config config,boolean update){
2016-07-31 22:00:46 +08:00
String json=GSON.toJson(config);
2016-06-06 13:48:59 +08:00
if(CONFIG_FILE.exists())
CONFIG_FILE.delete();
try {
CONFIG_FILE.createNewFile();
IOUtils.write(json, new FileOutputStream(CONFIG_FILE));
logger.info("Successfully "+(update?"update":"create")+" config.");
} catch (Exception e) {
logger.info("Failed to "+(update?"update":"create")+" config.("+e.getMessage()+")");
}
}
2016-02-27 15:22:35 +08:00
}