package codechicken.nei; import codechicken.core.*; import codechicken.lib.config.ConfigFile; import codechicken.lib.config.ConfigTag; import codechicken.lib.config.ConfigTagParent; import codechicken.nei.api.*; import codechicken.nei.config.*; import codechicken.nei.recipe.RecipeInfo; import codechicken.obfuscator.ObfuscationRun; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.world.World; import net.minecraft.world.storage.SaveFormatComparator; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.input.Keyboard; import java.io.File; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; public class NEIClientConfig { private static boolean configLoaded; private static boolean enabledOverride; public static Logger logger = LogManager.getLogger("NotEnoughItems"); public static File configDir = new File(CommonUtils.getMinecraftDir(), "config/NEI/"); public static ConfigSet global = new ConfigSet(new File("saves/NEI/client.dat"), new ConfigFile(new File(configDir, "client.cfg"))); public static ConfigSet world; public static ItemStack creativeInv[]; private static boolean statesSaved[] = new boolean[7]; public static boolean hasSMPCounterpart; public static HashSet<String> permissableActions = new HashSet<String>(); public static HashSet<String> disabledActions = new HashSet<String>(); public static HashSet<String> enabledActions = new HashSet<String>(); public static ItemStackSet bannedBlocks = new ItemStackSet(); static { if (global.config.getTag("checkUpdates").getBooleanValue(true)) { CCUpdateChecker.updateCheck("NotEnoughItems"); } linkOptionList(); setDefaults(); } private static void setDefaults() { ConfigTagParent tag = global.config; tag.setComment("Main configuration of NEI.\nMost of these options can be changed ingame.\nDeleting any element will restore it to it's default value"); tag.getTag("command").useBraces().setComment("Change these options if you have a different mod installed on the server that handles the commands differently, Eg. Bukkit Essentials"); tag.setNewLineMode(1); tag.getTag("inventory.widgetsenabled").getBooleanValue(true); API.addOption(new OptionToggleButton("inventory.widgetsenabled")); tag.getTag("inventory.hidden").getBooleanValue(false); tag.getTag("inventory.cheatmode").getIntValue(2); tag.getTag("inventory.lockmode").setComment("For those who can't help themselves.\nSet this to a mode and you will be unable to change it ingame").getIntValue(-1); API.addOption(new OptionCycled("inventory.cheatmode", 3) { @Override public boolean optionValid(int index) { return getLockedMode() == -1 || getLockedMode() == index && NEIInfo.isValidMode(index); } }); checkCheatMode(); tag.getTag("inventory.utilities").setDefaultValue("delete, magnet"); API.addOption(new OptionUtilities("inventory.utilities")); tag.getTag("inventory.gamemodes").setDefaultValue("creative, creative+, adventure"); API.addOption(new OptionGamemodes("inventory.gamemodes")); tag.getTag("inventory.layoutstyle").getIntValue(0); API.addOption(new OptionCycled("inventory.layoutstyle", 0) { @Override public String getPrefix() { return translateN(name); } @Override public String getButtonText() { return NEIClientUtils.translate("layoutstyle." + LayoutManager.getLayoutStyle(renderTag().getIntValue()).getName()); } @Override public boolean cycle() { LinkedList<Integer> list = new LinkedList<Integer>(); for (Entry<Integer, LayoutStyle> entry : LayoutManager.layoutStyles.entrySet()) { list.add(entry.getKey()); } Collections.sort(list); int nextLayout = renderTag().getIntValue(); if (nextLayout == list.getLast())//loop list { nextLayout = -1; } for (Integer i : list) { if (i > nextLayout) { nextLayout = i; break; } } getTag().setIntValue(nextLayout); return true; } }); ItemSorter.initConfig(tag); tag.getTag("inventory.itemIDs").getIntValue(1); API.addOption(new OptionCycled("inventory.itemIDs", 3, true)); tag.getTag("inventory.searchmode").getIntValue(1); API.addOption(new OptionCycled("inventory.searchmode", 3, true)); tag.getTag("world.highlight_tips").getBooleanValue(false); tag.getTag("world.highlight_tips.x").getIntValue(5000); tag.getTag("world.highlight_tips.y").getIntValue(100); API.addOption(new OptionOpenGui("world.highlight_tips", GuiHighlightTips.class)); tag.getTag("inventory.profileRecipes").getBooleanValue(false); API.addOption(new OptionToggleButton("inventory.profileRecipes", true)); tag.getTag("command.creative").setDefaultValue("/gamemode {0} {1}"); API.addOption(new OptionTextField("command.creative")); tag.getTag("command.item").setDefaultValue("/give {0} {1} {2} {3} {4}"); API.addOption(new OptionTextField("command.item")); tag.getTag("command.time").setDefaultValue("/time set {0}"); API.addOption(new OptionTextField("command.time")); tag.getTag("command.rain").setDefaultValue("/toggledownfall"); API.addOption(new OptionTextField("command.rain")); tag.getTag("command.heal").setDefaultValue(""); API.addOption(new OptionTextField("command.heal")); setDefaultKeyBindings(); } private static void linkOptionList() { OptionList.setOptionList(new OptionList("nei.options") { @Override public ConfigSet globalConfigSet() { return global; } @Override public ConfigSet worldConfigSet() { return world; } @Override public OptionList configBase() { return this; } @Override public GuiOptionList getGui(GuiScreen parent, OptionList list, boolean world) { return new GuiNEIOptionList(parent, list, world); } }); } private static void setDefaultKeyBindings() { API.addKeyBind("gui.recipe", Keyboard.KEY_R); API.addKeyBind("gui.usage", Keyboard.KEY_U); API.addKeyBind("gui.back", Keyboard.KEY_BACK); API.addKeyBind("gui.enchant", Keyboard.KEY_X); API.addKeyBind("gui.potion", Keyboard.KEY_P); API.addKeyBind("gui.prev", Keyboard.KEY_PRIOR); API.addKeyBind("gui.next", Keyboard.KEY_NEXT); API.addKeyBind("gui.hide", Keyboard.KEY_O); API.addKeyBind("gui.search", Keyboard.KEY_F); API.addKeyBind("world.chunkoverlay", Keyboard.KEY_F9); API.addKeyBind("world.moboverlay", Keyboard.KEY_F7); API.addKeyBind("world.highlight_tips", Keyboard.KEY_NUMPAD0); API.addKeyBind("world.dawn", 0); API.addKeyBind("world.noon", 0); API.addKeyBind("world.dusk", 0); API.addKeyBind("world.midnight", 0); API.addKeyBind("world.rain", 0); API.addKeyBind("world.heal", 0); API.addKeyBind("world.creative", 0); } public static OptionList getOptionList() { return OptionList.getOptionList("nei.options"); } public static void loadWorld(String saveName) { setInternalEnabled(true); logger.debug("Loading " + (Minecraft.getMinecraft().isSingleplayer() ? "Local" : "Remote") + " World"); bootNEI(ClientUtils.getWorld()); File saveDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + saveName); boolean newWorld = !saveDir.exists(); if (newWorld) { saveDir.mkdirs(); } world = new ConfigSet(new File(saveDir, "NEI.dat"), new ConfigFile(new File(saveDir, "NEI.cfg"))); onWorldLoad(newWorld); } private static void onWorldLoad(boolean newWorld) { world.config.setComment("World based configuration of NEI.\nMost of these options can be changed ingame.\nDeleting any element will restore it to it's default value"); setWorldDefaults(); creativeInv = new ItemStack[54]; LayoutManager.searchField.setText(getSearchExpression()); LayoutManager.quantity.setText(Integer.toString(getItemQuantity())); SubsetWidget.loadHidden(); if (newWorld && Minecraft.getMinecraft().isSingleplayer()) { world.config.getTag("inventory.cheatmode").setIntValue(Minecraft.getMinecraft().playerController.isInCreativeMode() ? 2 : 0); } NEIInfo.load(ClientUtils.getWorld()); } private static void setWorldDefaults() { NBTTagCompound nbt = world.nbt; if (!nbt.hasKey("search")) { nbt.setString("search", ""); } if (!nbt.hasKey("quantity")) { nbt.setInteger("quantity", 0); } if (!nbt.hasKey("validateenchantments")) { nbt.setBoolean("validateenchantments", false); } world.saveNBT(); } public static int getKeyBinding(String string) { return getSetting("keys." + string).getIntValue(); } public static void setDefaultKeyBinding(String string, int key) { getSetting("keys." + string).getIntValue(key); } public static void bootNEI(World world) { if (configLoaded) { return; } loadStates(); //ItemVisibilityHash.loadStates(); //vishash = new ItemVisibilityHash(); ItemInfo.load(world); GuiInfo.load(); RecipeInfo.load(); LayoutManager.load(); NEIController.load(); configLoaded = true; ClassDiscoverer classDiscoverer = new ClassDiscoverer(new IStringMatcher() { public boolean matches(String test) { return test.startsWith("NEI") && test.endsWith("Config.class"); } }, IConfigureNEI.class); classDiscoverer.findClasses(); for (Class<?> clazz : classDiscoverer.classes) { try { IConfigureNEI config = (IConfigureNEI) clazz.newInstance(); config.loadConfig(); NEIModContainer.plugins.add(config); logger.debug("Loaded " + clazz.getName()); } catch (Exception e) { logger.error("Failed to Load " + clazz.getName(), e); } } ItemSorter.loadConfig(); } public static void loadStates() { for (int state = 0; state < 7; state++) { statesSaved[state] = !global.nbt.getCompoundTag("save" + state).hasNoTags(); } } public static boolean isWorldSpecific(String setting) { if (world == null) { return false; } ConfigTag tag = world.config.getTag(setting, false); return tag != null && tag.value != null; } public static boolean isStateSaved(int i) { return statesSaved[i]; } public static ConfigTag getSetting(String s) { return isWorldSpecific(s) ? world.config.getTag(s) : global.config.getTag(s); } public static boolean getBooleanSetting(String s) { return getSetting(s).getBooleanValue(); } public static boolean isHidden() { return !enabledOverride || getBooleanSetting("inventory.hidden"); } public static boolean isEnabled() { return enabledOverride && getBooleanSetting("inventory.widgetsenabled"); } public static void setEnabled(boolean flag) { getSetting("inventory.widgetsenabled").setBooleanValue(flag); } public static int getItemQuantity() { return world.nbt.getInteger("quantity"); } public static int getCheatMode() { return getIntSetting("inventory.cheatmode"); } private static void checkCheatMode() { if (getLockedMode() != -1) { setIntSetting("inventory.cheatmode", getLockedMode()); } } public static int getLockedMode() { return getIntSetting("inventory.lockmode"); } public static int getLayoutStyle() { return getIntSetting("inventory.layoutstyle"); } public static String getStringSetting(String s) { return getSetting(s).getValue(); } public static boolean showIDs() { int i = getIntSetting("inventory.itemIDs"); return i == 2 || (i == 1 && isEnabled() && !isHidden()); } public static void toggleBooleanSetting(String setting) { ConfigTag tag = getSetting(setting); tag.setBooleanValue(!tag.getBooleanValue()); } public static void cycleSetting(String setting, int max) { ConfigTag tag = getSetting(setting); tag.setIntValue((tag.getIntValue() + 1) % max); } public static int getIntSetting(String setting) { return getSetting(setting).getIntValue(); } public static void setIntSetting(String setting, int val) { getSetting(setting).setIntValue(val); } public static String getSearchExpression() { return world.nbt.getString("search"); } public static void setSearchExpression(String expression) { world.nbt.setString("search", expression); world.saveNBT(); } public static boolean getMagnetMode() { return enabledActions.contains("magnet"); } public static boolean invCreativeMode() { return enabledActions.contains("creative+") && canPerformAction("creative+"); } public static boolean areDamageVariantsShown() { return hasSMPCounterPart() || getSetting("command.item").getValue().contains("{3}"); } public static void clearState(int state) { statesSaved[state] = false; global.nbt.setTag("save" + state, new NBTTagCompound()); global.saveNBT(); } public static void loadState(int state) { if (!statesSaved[state]) { return; } NBTTagCompound statesave = global.nbt.getCompoundTag("save" + state); GuiContainer currentContainer = NEIClientUtils.getGuiContainer(); LinkedList<TaggedInventoryArea> saveAreas = new LinkedList<TaggedInventoryArea>(); saveAreas.add(new TaggedInventoryArea(Minecraft.getMinecraft().thePlayer.inventory)); for (INEIGuiHandler handler : GuiInfo.guiHandlers) { List<TaggedInventoryArea> areaList = handler.getInventoryAreas(currentContainer); if (areaList != null) { saveAreas.addAll(areaList); } } for (TaggedInventoryArea area : saveAreas) { if (!statesave.hasKey(area.tagName)) { continue; } for (int slot : area.slots) { NEIClientUtils.setSlotContents(slot, null, area.isContainer()); } NBTTagList areaTag = statesave.getTagList(area.tagName, 10); for (int i = 0; i < areaTag.tagCount(); i++) { NBTTagCompound stacksave = areaTag.getCompoundTagAt(i); int slot = stacksave.getByte("Slot") & 0xFF; if (!area.slots.contains(slot)) { continue; } NEIClientUtils.setSlotContents(slot, ItemStack.loadItemStackFromNBT(stacksave), area.isContainer()); } } } public static void saveState(int state) { NBTTagCompound statesave = global.nbt.getCompoundTag("save" + state); GuiContainer currentContainer = NEIClientUtils.getGuiContainer(); LinkedList<TaggedInventoryArea> saveAreas = new LinkedList<TaggedInventoryArea>(); saveAreas.add(new TaggedInventoryArea(Minecraft.getMinecraft().thePlayer.inventory)); for (INEIGuiHandler handler : GuiInfo.guiHandlers) { List<TaggedInventoryArea> areaList = handler.getInventoryAreas(currentContainer); if (areaList != null) { saveAreas.addAll(areaList); } } for (TaggedInventoryArea area : saveAreas) { NBTTagList areaTag = new NBTTagList(); for (int i : area.slots) { ItemStack stack = area.getStackInSlot(i); if (stack == null) { continue; } NBTTagCompound stacksave = new NBTTagCompound(); stacksave.setByte("Slot", (byte) i); stack.writeToNBT(stacksave); areaTag.appendTag(stacksave); } statesave.setTag(area.tagName, areaTag); } global.nbt.setTag("save" + state, statesave); global.saveNBT(); statesSaved[state] = true; } public static boolean hasSMPCounterPart() { return hasSMPCounterpart; } public static void setHasSMPCounterPart(boolean flag) { hasSMPCounterpart = flag; permissableActions.clear(); bannedBlocks.clear(); disabledActions.clear(); enabledActions.clear(); } public static boolean canCheatItem(ItemStack stack) { return canPerformAction("item") && !bannedBlocks.contains(stack); } public static boolean canPerformAction(String name) { if (!isEnabled()) { return false; } if (!modePermitsAction(name)) { return false; } String base = NEIActions.base(name); if (hasSMPCounterpart) { return permissableActions.contains(base); } if (NEIActions.smpRequired(name)) { return false; } String cmd = getStringSetting("command." + base); if (cmd == null || !cmd.startsWith("/")) { return false; } return true; } private static boolean modePermitsAction(String name) { if (getCheatMode() == 0) { return false; } if (getCheatMode() == 2) { return true; } String[] actions = getStringArrSetting("inventory.utilities"); for (String action : actions) { if (action.equalsIgnoreCase(name)) { return true; } } return false; } public static String[] getStringArrSetting(String s) { return getStringSetting(s).replace(" ", "").split(","); } public static void setInternalEnabled(boolean b) { enabledOverride = b; } public static void reloadSaves() { File saveDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/local"); if (!saveDir.exists()) { return; } List<SaveFormatComparator> saves; try { saves = Minecraft.getMinecraft().getSaveLoader().getSaveList(); } catch (Exception e) { logger.error("Error loading saves", e); return; } HashSet<String> saveFileNames = new HashSet<String>(); for (SaveFormatComparator save : saves) { saveFileNames.add(save.getFileName()); } for (File file : saveDir.listFiles()) { if (file.isDirectory() && !saveFileNames.contains(file.getName())) { ObfuscationRun.deleteDir(file, true); } } } }