diff options
Diffstat (limited to 'src/Java/cofh/mod/BaseMod.java')
-rw-r--r-- | src/Java/cofh/mod/BaseMod.java | 284 |
1 files changed, 284 insertions, 0 deletions
diff --git a/src/Java/cofh/mod/BaseMod.java b/src/Java/cofh/mod/BaseMod.java new file mode 100644 index 0000000000..7ab858eabd --- /dev/null +++ b/src/Java/cofh/mod/BaseMod.java @@ -0,0 +1,284 @@ +package cofh.mod; + +import cofh.mod.updater.IUpdatableMod; +import cofh.mod.updater.ModRange; +import cofh.mod.updater.ModVersion; +import com.google.common.base.Strings; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.ICrashCallable; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.common.ObfuscationReflectionHelper; +import cpw.mods.fml.common.network.NetworkCheckHandler; +import cpw.mods.fml.common.registry.LanguageRegistry; +import cpw.mods.fml.common.versioning.InvalidVersionSpecificationException; +import cpw.mods.fml.relauncher.FMLLaunchHandler; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IReloadableResourceManager; +import net.minecraft.client.resources.IResource; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.resources.IResourceManagerReloadListener; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StringTranslate; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.helpers.Loader; +import org.apache.logging.log4j.spi.AbstractLogger; + +public abstract class BaseMod implements IUpdatableMod { + + protected File _configFolder; + protected final String _modid; + protected final Logger _log; + + protected BaseMod(Logger log) { + + String name = getModId(); + _modid = name.toLowerCase(Locale.US); + _log = log; + init(); + } + + protected BaseMod() { + + String name = getModId(); + _modid = name.toLowerCase(Locale.US); + _log = LogManager.getLogger(name); + init(); + } + + private void init() { + + ModContainer container = cpw.mods.fml.common.Loader.instance().activeModContainer(); + if (container.getSource().isDirectory()) { + FMLCommonHandler.instance().registerCrashCallable(new CrashCallable("Loaded from a directory")); + } else { + try { + JarFile jar = new JarFile(container.getSource()); + ZipEntry file = jar.getEntry("vers.prop"); + if (file != null) { + BufferedReader reader = new BufferedReader(new InputStreamReader(jar.getInputStream(file))); + String data = reader.readLine(); + FMLCommonHandler.instance().registerCrashCallable(new CrashCallable(data)); + } else { + FMLCommonHandler.instance().registerCrashCallable(new CrashCallable("Lacking version information.")); + } + jar.close(); + } catch (IOException e) { + FMLCommonHandler.instance().registerCrashCallable(new CrashCallable("Error reading version information." + e.getMessage())); + } + } + } + + @NetworkCheckHandler + public final boolean networkCheck(Map<String, String> remoteVersions, Side side) throws InvalidVersionSpecificationException { + + if (!requiresRemoteFrom(side)) { + return true; + } + Mod mod = getClass().getAnnotation(Mod.class); + String _modid = mod.modid(); + if (!remoteVersions.containsKey(_modid)) { + return false; + } + String remotes = mod.acceptableRemoteVersions(); + if (!"*".equals(remotes)) { + + String remote = remoteVersions.get(_modid); + if (Strings.isNullOrEmpty(remotes)) { + return getModVersion().equalsIgnoreCase(remote); + } + return ModRange.createFromVersionSpec(_modid, remotes).containsVersion(new ModVersion(_modid, remote)); + } + return true; + } + + protected boolean requiresRemoteFrom(Side side) { + + return true; + } + + protected String getConfigBaseFolder() { + + String base = getClass().getPackage().getName(); + int i = base.indexOf('.'); + if (i >= 0) { + return base.substring(0, i); + } + return ""; + } + + protected void setConfigFolderBase(File folder) { + + _configFolder = new File(folder, getConfigBaseFolder() + "/" + _modid + "/"); + } + + protected File getConfig(String name) { + + return new File(_configFolder, name + ".cfg"); + } + + protected File getClientConfig() { + + return getConfig("client"); + } + + protected File getCommonConfig() { + + return getConfig("common"); + } + + protected String getAssetDir() { + + return _modid; + } + + @Override + public Logger getLogger() { + + return _log; + } + + private void loadLanguageFile(Properties lang, InputStream stream) throws Throwable { + + InputStreamReader is = new InputStreamReader(stream, "UTF-8"); + + Properties langPack = new Properties(); + langPack.load(is); + + lang.putAll(langPack); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void loadLanguageFile(String lang, Properties langPack) { + + HashMap<String, String> parsedLangFile = new HashMap<String, String>(); + parsedLangFile.putAll((Map) langPack); // lovely casting hack + + LanguageRegistry.instance().injectLanguage(lang.intern(), parsedLangFile); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected void loadLang() { + + if (FMLLaunchHandler.side() == Side.CLIENT) { + try { + loadClientLang(); + return; + } catch (Throwable t) { + _log.error(AbstractLogger.CATCHING_MARKER, "???", t); + } + } + + String path = "assets/" + getAssetDir() + "/language/"; + String lang = "en_US"; + try (InputStream is = Loader.getResource(path + lang + ".lang", null).openStream();) { + Properties langPack = new Properties(); + loadLanguageFile(langPack, is); + + StringTranslate i = ObfuscationReflectionHelper.getPrivateValue(StringTranslate.class, null, "instance", "field_74817_a"); + Map m = ObfuscationReflectionHelper.getPrivateValue(StringTranslate.class, i, "field_74816_c", "languageList"); + m.putAll(langPack); + } catch (Throwable t) { + _log.catching(Level.INFO, t); + } + } + + @SideOnly(Side.CLIENT) + private void loadClientLang() { + + IReloadableResourceManager manager = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager(); + manager.registerReloadListener(new LangManager(manager)); + } + + @SideOnly(Side.CLIENT) + private class LangManager implements IResourceManagerReloadListener { + + private final String _path; + + public LangManager(IResourceManager manager) { + + _path = getAssetDir() + ":language/"; + onResourceManagerReload(manager); + } + + @Override + public void onResourceManagerReload(IResourceManager manager) { + + String l = null; + try { + l = Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode(); + } catch (Throwable t) { + _log.catching(Level.WARN, t); + } + + for (String lang : Arrays.asList("en_US", l)) { + if (lang != null) { + Properties langPack = new Properties(); + try { + List<IResource> files = manager.getAllResources(new ResourceLocation(_path + lang + ".lang")); + for (IResource file : files) { + if (file.getInputStream() == null) { + _log.warn("A resource pack defines an entry for language '" + lang + "' but the InputStream is null."); + continue; + } + try { + loadLanguageFile(langPack, file.getInputStream()); + } catch (Throwable t) { + _log.warn(AbstractLogger.CATCHING_MARKER, "A resource pack has a file for language '" + lang + "' but the file is invalid.", t); + } + } + } catch (Throwable t) { + _log.info(AbstractLogger.CATCHING_MARKER, "No language data for '" + lang + "'", t); + } + loadLanguageFile(lang, langPack); + } + } + + Minecraft.getMinecraft().getLanguageManager().onResourceManagerReload(manager); + } + } + + private class CrashCallable implements ICrashCallable { + + private final String data; + + private CrashCallable(String data) { + + this.data = data; + } + + @Override + public String call() throws Exception { + + return data; + } + + @Override + public String getLabel() { + + return getModId(); + } + + } + +} |