From 80cc8fcef76a0959d67f50a86baf516fd2b91b91 Mon Sep 17 00:00:00 2001 From: Guichaguri Date: Tue, 31 Jan 2017 20:10:14 -0200 Subject: [PATCH] Options UI revamp (Closes #29) and fixes --- build.gradle | 104 ++-- mappings.srg | 1 + .../betterfps/gui/BetterFpsResourcePack.java | 1 + .../betterfps/gui/GuiBetterFpsConfig.java | 508 +++++++----------- .../betterfps/gui/GuiConfigOption.java | 98 ++++ .../betterfps/gui/GuiCycleButton.java | 85 ++- .../betterfps/gui/GuiRestartDialog.java | 29 +- .../betterfps/gui/data/AlgorithmAction.java | 100 ++++ .../betterfps/gui/data/OptionManager.java | 134 +++++ .../betterfps/gui/data/UpdateCheckAction.java | 25 + .../installer/GuiAlgorithmTester.java | 1 + .../betterfps/patches/misc/OptionsButton.java | 2 +- .../transformers/MathTransformer.java | 22 +- .../betterfps/tweaker/Mappings.java | 2 +- 14 files changed, 657 insertions(+), 455 deletions(-) create mode 100644 src/main/java/guichaguri/betterfps/gui/GuiConfigOption.java create mode 100644 src/main/java/guichaguri/betterfps/gui/data/AlgorithmAction.java create mode 100644 src/main/java/guichaguri/betterfps/gui/data/OptionManager.java create mode 100644 src/main/java/guichaguri/betterfps/gui/data/UpdateCheckAction.java diff --git a/build.gradle b/build.gradle index 5199e48..ce04864 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,3 @@ - buildscript { repositories { mavenLocal() @@ -19,7 +18,7 @@ buildscript { apply plugin: 'net.minecraftforge.gradle.tweaker-client' -version = "1.3.3" +version = "1.3.4" group = "guichaguri.betterfps" archivesBaseName = "BetterFps" @@ -32,12 +31,35 @@ minecraft { at 'betterfps_at.cfg' } -sourceCompatibility = targetCompatibility = "1.6" // Need this here so eclipse task generates correctly. +reobf { + jar { + extraLines 'PK: com/eclipsesource/json guichaguri/betterfps/json' + } +} + +configurations { + shade + compile.extendsFrom shade +} + +sourceCompatibility = targetCompatibility = "1.6" compileJava { sourceCompatibility = targetCompatibility = "1.6" } +dependencies { + //compile 'org.ow2.asm:asm-debug-all:5.0.3' + //compile 'net.minecraft:launchwrapper:1.12' + shade 'com.eclipsesource.minimal-json:minimal-json:0.9.4' + testCompile 'junit:junit:4.12' +} + jar { + configurations.shade.each { dep -> + from(project.zipTree(dep)){ + exclude 'META-INF', 'META-INF/**' + } + } manifest { attributes 'TweakClass': project.minecraft.tweakClass, 'TweakOrder': '600', @@ -49,87 +71,23 @@ jar { } } -dependencies { - //compile 'org.ow2.asm:asm-debug-all:5.0.3' - //compile 'net.minecraft:launchwrapper:1.12' - testCompile 'junit:junit:4.12' -} - processResources { - // this will ensure that this task is redone when the version change. inputs.property "version", project.version - // replace stuff in the json, nothing else from(sourceSets.main.resources.srcDirs) { include 'META-INF/betterfps.json' - - // replace version expand 'version': project.version } - - // copy everything else, except the json from(sourceSets.main.resources.srcDirs) { exclude 'META-INF/betterfps.json' } } -String srgInput = 'mappings.srg' -String srgOutput = 'src/main/resources/betterfps.srg' - -/** - * Task created by Guichaguri to update the requested mappings of a SRG file - * You might have to update the input file when the mappings version change. - */ -task updateMappings(dependsOn: 'genSrgs') { - File notchToMcp = tasks['genSrgs'].getNotchToMcp(); - if(!notchToMcp.exists()) { - println 'SRG file does not exist yet.' - return; - } +//TODO? +/* +File mappingsFile = file('src/main/java/guichaguri/betterfps/tweaker/Mappings.java'); +Pattern mappingRegex = Pattern.compile("\\(Type\\.([A-Z]+), ([a-zA-Z0-9_ \".\\(\\)\\;\\/,\\$]+)\\)"); - def classes = [:]; - def fields = [:]; - def methods = [:]; - def i = 0; +task processMappings() { - println 'Searching mappings to update' - String[] reqMapping = file(srgInput).readLines() - reqMapping.each { - String[] mapping = it.split(' ') - if(it.startsWith('#')) { - // Comment - } else if(mapping[0].equals('CL:')) { // Class - if(mapping.length >= 2) classes.put(mapping[2], mapping[1]); - } else if(mapping[0].equals('FD:')) { // Field - if(mapping.length >= 2) fields.put(mapping[2], mapping[1]); - } else if(mapping[0].equals('MD:')) { // Method - if(mapping.length >= 3) methods.put(mapping[2] + mapping[3], mapping[1]); - } - } - println 'Updating mappings' - file(srgOutput).withWriter { out -> - String[] mappings = notchToMcp.readLines() - mappings.each { - String[] mapping = it.split(' ') - if (mapping[0].equals('CL:')) { // Class - if(mapping.length >= 3 && classes.containsKey(mapping[2])) { - out.println it + ' ' + classes.get(mapping[2]) - i++ - } - } else if(mapping[0].equals('FD:')) { // Field - if(mapping.length >= 3 && fields.containsKey(mapping[2])) { - out.println it + ' ' + fields.get(mapping[2]) - i++ - } - } else if(mapping[0].equals('MD:')) { // Method - if(mapping.length >= 5 && methods.containsKey(mapping[3] + mapping[4])) { - out.println it + ' ' + methods.get(mapping[3] + mapping[4]) - i++ - } - } - } - def entries = classes.size() + fields.size() + methods.size(); - println 'Done. Updated ' + i + '/' + entries + ' entries' - if(i < entries) println 'WARNING: ' + (entries - i) + ' entries were not found! You should check them' - } -} \ No newline at end of file +}*/ diff --git a/mappings.srg b/mappings.srg index 63678a1..d888e2a 100644 --- a/mappings.srg +++ b/mappings.srg @@ -8,6 +8,7 @@ CL: Minecraft net/minecraft/client/Minecraft CL: World net/minecraft/world/World CL: Chunk net/minecraft/world/chunk/Chunk CL: EntityPlayer net/minecraft/entity/player/EntityPlayer +CL: EntityPlayerSP net/minecraft/client/entity/EntityPlayerSP CL: MathHelper net/minecraft/util/math/MathHelper CL: EntityTNTPrimed net/minecraft/entity/item/EntityTNTPrimed CL: ClientBrandRetriever net/minecraft/client/ClientBrandRetriever diff --git a/src/main/java/guichaguri/betterfps/gui/BetterFpsResourcePack.java b/src/main/java/guichaguri/betterfps/gui/BetterFpsResourcePack.java index 64cd65d..b5b2bfb 100644 --- a/src/main/java/guichaguri/betterfps/gui/BetterFpsResourcePack.java +++ b/src/main/java/guichaguri/betterfps/gui/BetterFpsResourcePack.java @@ -13,6 +13,7 @@ import net.minecraft.util.ResourceLocation; /** + * A resource pack that serves the purpose to provide lang files * @author Guilherme Chaguri */ public class BetterFpsResourcePack implements IResourcePack { diff --git a/src/main/java/guichaguri/betterfps/gui/GuiBetterFpsConfig.java b/src/main/java/guichaguri/betterfps/gui/GuiBetterFpsConfig.java index dbd02a5..cc016db 100644 --- a/src/main/java/guichaguri/betterfps/gui/GuiBetterFpsConfig.java +++ b/src/main/java/guichaguri/betterfps/gui/GuiBetterFpsConfig.java @@ -1,310 +1,198 @@ -package guichaguri.betterfps.gui; - -import guichaguri.betterfps.BetterFpsConfig; -import guichaguri.betterfps.BetterFpsHelper; -import guichaguri.betterfps.UpdateChecker; -import guichaguri.betterfps.gui.GuiCycleButton.GuiBooleanButton; -import guichaguri.betterfps.tweaker.BetterFpsTweaker; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.resources.I18n; -import net.minecraft.util.Util; -import net.minecraft.util.Util.EnumOS; -import net.minecraft.util.text.TextComponentString; -import org.lwjgl.input.Mouse; - -/** - * @author Guilherme Chaguri - */ -public class GuiBetterFpsConfig extends GuiScreen { - - private GuiScreen parent = null; - public GuiBetterFpsConfig() {} - public GuiBetterFpsConfig(GuiScreen parent) { - this.parent = parent; - } - - - private List initButtons() { - List buttons = new ArrayList(); - BetterFpsConfig config = BetterFpsConfig.getConfig(); - buttons.add(new AlgorithmButton(2, "Algorithm", BetterFpsHelper.displayHelpers, - config.algorithm, new String[] { - "The algorithm for calculating sine and cosine", - "§cRequires restarting to take effect", "", - "§eShift-click me to test algorithms §7(This will take a few seconds)", "", - "§aMore information here soon", "", - "Default in Vanilla: Vanilla Algorithm", - "Default in BetterFps: Riven's \"Half\" Algorithm", - })); - buttons.add(new UpdateCheckerButton(3, "Update Checker", config.updateChecker, new String[] { - "Whether updates will be checked on startup", "", - "§eShift-click me to check for updates §7(This will take a few seconds)", "", - "Default: On" - })); - buttons.add(new GuiBooleanButton(4, "Preallocate Memory", config.preallocateMemory, new String[] { - "Whether will preallocate 10MB on startup.", - "§cRequires restarting to take effect", "", - "Default in Vanilla: On", - "Default in BetterFps: Off", - "", - "Note: This allocation will be cleaned only when the memory is almost full", - "Useful for modpacks that require a lot of RAM" - })); - buttons.add(new GuiBooleanButton(5, "Fast Box Render", config.fastBoxRender, new String[] { - "Whether will only render the exterior of boxes.", - "§cRequires restarting to take effect", "", - "Default in Vanilla: Off", - "Default in BetterFps: On" - })); - buttons.add(new GuiBooleanButton(6, "Fog", config.fog, new String[] { - "Whether fog will be rendered.", - "§cRequires restarting to take effect", "", - "Default: On" - })); - buttons.add(new GuiBooleanButton(7, "Fast Hopper", config.fastHopper, new String[] { - "Whether hopper improvements will be enabled.", - "§cRequires restarting to take effect", "", - "Default in Vanilla: Off", - "Default in BetterFps: On" - })); - buttons.add(new GuiBooleanButton(8, "Fast Beacon", config.fastBeacon, new String[] { - "Whether the beacon improvements will be enabled.", - "§cRequires restarting to take effect", "", - "Default in Vanilla: Off", - "Default in BetterFps: On" - })); - buttons.add(new GuiBooleanButton(9, "Fast Beacon Rendering", config.fastBeaconRender, new String[] { - "Whether the beacon glow will be removed.", - "§cRequires restarting to take effect", "", - "Default: Off" - })); - return buttons; - } - - @Override - public void initGui() { - int x1 = width / 2 - 155; - int x2 = width / 2 + 5; - - buttonList.clear(); - buttonList.add(new GuiButton(-1, x1, height - 27, 150, 20, I18n.format("gui.done"))); - buttonList.add(new GuiButton(-2, x2, height - 27, 150, 20, I18n.format("gui.cancel"))); - - List buttons = initButtons(); - - int y = 25; - int lastId = 0; - - for(GuiButton button : buttons) { - boolean first = button.id % 2 != 0; - boolean large = button.id - 1 != lastId; - button.xPosition = (first || large) ? x1 : x2; - button.yPosition = y; - button.setWidth(large ? 310 : 150); - buttonList.add(button); - if((!first) || (large)) y += 25; - lastId = button.id; - } - - } - - @Override - public void drawScreen(int mouseX, int mouseY, float partialTicks) { - drawDefaultBackground(); - if(mouseY < fontRendererObj.FONT_HEIGHT + 14) { - if(Mouse.isButtonDown(1)) { - drawCenteredString(fontRendererObj, "This is not a button", this.width / 2, 7, 0xC0C0C0); - } else { - drawCenteredString(fontRendererObj, "Hold right-click on a button for information", this.width / 2, 7, 0xC0C0C0); - } - } else { - drawCenteredString(fontRendererObj, "BetterFps Options", this.width / 2, 7, 0xFFFFFF); - } - super.drawScreen(mouseX, mouseY, partialTicks); - if(Mouse.isButtonDown(1)) { // Right Click - for(GuiButton button : buttonList) { - if((button instanceof GuiCycleButton) && (button.isMouseOver())) { - int y = mouseY + 5; - - String[] help = ((GuiCycleButton)button).getHelpText(); - int fontHeight = fontRendererObj.FONT_HEIGHT, i = 0; - drawGradientRect(0, y, mc.displayWidth, y + (fontHeight * help.length) + 10, -1072689136, -804253680); - for(String h : help) { - if(!h.isEmpty()) fontRendererObj.drawString(h, 5, y + (i * fontHeight) + 5, 0xFFFFFF); - i++; - } - break; - } - } - } - } - - @Override - protected void actionPerformed(GuiButton button) throws IOException { - super.actionPerformed(button); - if(button instanceof GuiCycleButton) { - ((GuiCycleButton)button).actionPerformed(); - } else if(button.id == -1) { - // Save - boolean restart = false; - BetterFpsConfig config = BetterFpsConfig.getConfig(); - - GuiCycleButton algorithmButton = getCycleButton(2); - String algorithm = algorithmButton.getSelectedValue(); - if(!algorithm.equals(config.algorithm)) restart = true; - - config.algorithm = algorithm; - - GuiCycleButton updateButton = getCycleButton(3); - config.updateChecker = updateButton.getSelectedValue(); - - GuiCycleButton preallocateButton = getCycleButton(4); - boolean preallocate = preallocateButton.getSelectedValue(); - if(preallocate != config.preallocateMemory) restart = true; - config.preallocateMemory = preallocate; - - GuiCycleButton boxRenderButton = getCycleButton(5); - boolean boxRender = boxRenderButton.getSelectedValue(); - if(boxRender != config.fastBoxRender) restart = true; - config.fastBoxRender = boxRender; - - GuiCycleButton fogButton = getCycleButton(6); - boolean fog = fogButton.getSelectedValue(); - if(fog != config.fog) restart = true; - config.fog = fog; - - GuiCycleButton hopperButton = getCycleButton(7); - boolean fastHopper = hopperButton.getSelectedValue(); - if(fastHopper != config.fastHopper) restart = true; - config.fastHopper = fastHopper; - - GuiCycleButton beaconButton = getCycleButton(8); - boolean fastBeacon = beaconButton.getSelectedValue(); - if(fastBeacon != config.fastBeacon) restart = true; - config.fastBeacon = fastBeacon; - - GuiCycleButton beaconRenderButton = getCycleButton(9); - boolean fastBeaconRender = beaconRenderButton.getSelectedValue(); - if(fastBeaconRender != config.fastBeaconRender) restart = true; - config.fastBeaconRender = fastBeaconRender; - - BetterFpsHelper.saveConfig(); - - mc.displayGuiScreen(restart ? new GuiRestartDialog(parent) : parent); - } else if(button.id == -2) { - mc.displayGuiScreen(parent); - } - } - - private GuiCycleButton getCycleButton(int id) { - for(GuiButton button : buttonList) { - if(button.id == id) { - return (GuiCycleButton)button; - } - } - return null; - } - - @Override - public boolean doesGuiPauseGame() { - return true; - } - - private static class AlgorithmButton extends GuiCycleButton { - Process process = null; - public AlgorithmButton(int buttonId, String title, HashMap values, T defaultValue, String[] helpLines) { - super(buttonId, title, values, defaultValue, helpLines); - } - - private String getJavaDir() { - String separator = System.getProperty("file.separator"); - String path = System.getProperty("java.home") + separator + "bin" + separator; - if((Util.getOSType() == EnumOS.WINDOWS) && (new File(path + "javaw.exe").isFile())) { - return path + "javaw.exe"; - } - return path + "java"; - } - - private boolean isRunning() { - try { - process.exitValue(); - return false; - } catch(Exception ex) { - return true; - } - } - - private void updateAlgorithm() { - if((process != null) && (!isRunning())) { - try { - BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); - String line; - while((line = in.readLine()) != null) { - if(BetterFpsHelper.helpers.containsKey(line)) { - BetterFpsHelper.LOG.info("Found an algorithm! (" + line + ")"); - for(int i = 0; i < keys.size(); i++) { - if(keys.get(i).equals(line)) { - key = i; - break; - } - } - } - } - } catch(Exception ex) {} - updateTitle(); - process = null; - } - } - - @Override - public void drawButton(Minecraft mc, int mouseX, int mouseY) { - updateAlgorithm(); - super.drawButton(mc, mouseX, mouseY); - } - - @Override - public boolean shiftClick() { - if((process != null) && (isRunning())) { - return true; - } - - BetterFpsHelper.LOG.info("Testing algorithms..."); - List args = new ArrayList(); - args.add(getJavaDir()); - args.add("-Dtester=" + Minecraft.getMinecraft().mcDataDir.getAbsolutePath()); - args.add("-cp"); - args.add(BetterFpsTweaker.class.getProtectionDomain().getCodeSource().getLocation().getFile()); - args.add("BetterFpsInstaller"); - - try { - process = new ProcessBuilder(args).start(); - displayString = "Testing..."; - } catch(Exception ex) { - ex.printStackTrace(); - } - return true; - } - } - - private static class UpdateCheckerButton extends GuiBooleanButton { - public UpdateCheckerButton(int buttonId, String title, boolean defaultValue, String[] helpLines) { - super(buttonId, title, defaultValue, helpLines); - } - - @Override - public boolean shiftClick() { - Minecraft.getMinecraft().thePlayer.addChatComponentMessage(new TextComponentString("Checking updates..."), true); - UpdateChecker.checkForced(); - return true; - } - } -} +package guichaguri.betterfps.gui; + +import guichaguri.betterfps.gui.data.OptionManager; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.resources.I18n; +import org.lwjgl.input.Mouse; + +/** + * @author Guilherme Chaguri + */ +public class GuiBetterFpsConfig extends GuiScreen { + + private final GuiScreen parent; + private String title, titleMouseOver, titleRightClick; + + private final List options = new ArrayList(); + private float scrollY = 0, lastScrollY = 0; + private int pageHeight = 0; + + public GuiBetterFpsConfig() { + this.parent = null; + } + + public GuiBetterFpsConfig(GuiScreen parent) { + this.parent = parent; + } + + @Override + public void initGui() { + this.title = I18n.format("betterfps.options.title"); + this.titleMouseOver = I18n.format("betterfps.options.title.mouseover"); + this.titleRightClick = I18n.format("betterfps.options.title.rightclick"); + + int middleX = width / 2; + int xLeft = middleX - 155; + int xRight = middleX + 5; + int y = height - 27; + + this.buttonList.add(new GuiButton(-1, xLeft, y, 150, 20, I18n.format("gui.done"))); + this.buttonList.add(new GuiButton(-2, xRight, y, 150, 20, I18n.format("gui.cancel"))); + + this.options.clear(); + OptionManager.addButtons(this.options); + + y = 5; + boolean left = true; + + for(GuiConfigOption button : options) { + + if(button.isWide()) { + y += 25; + button.xPosition = xLeft; + button.setWidth(310); + } else { + if(left) y += 25; + button.xPosition = left ? xLeft : xRight; + button.setWidth(150); + left = !left; + } + + button.yPosition = y; + } + + pageHeight = y + 60; + } + + private void updateScroll(float partialTicks) { + scrollY += Mouse.getDWheel() / 6F; + if(Mouse.isButtonDown(0)) { + scrollY -= (float)Mouse.getDY() / mc.gameSettings.guiScale; + lastScrollY = scrollY; + } + + int pageHeightDelta = height - pageHeight; + if(scrollY > 0) { + scrollY = 0; + if(lastScrollY > 0) lastScrollY = 0; + } else if(scrollY < pageHeightDelta) { + int scroll = pageHeightDelta > 0 ? 0 : pageHeightDelta; + scrollY = scroll; + if(lastScrollY < pageHeightDelta) lastScrollY = scroll; + } + + lastScrollY = lastScrollY + (scrollY - lastScrollY) * partialTicks; + } + + private int getScrollMouseY(int mouseY) { + if(mouseY < 30 || height - mouseY < 30) { + return Integer.MIN_VALUE; + } + return mouseY - (int)lastScrollY; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) { + drawDefaultBackground(); + updateScroll(partialTicks); + + int mouseYScroll = getScrollMouseY(mouseY); + + GlStateManager.translate(0, lastScrollY, 0); + for(int i = 0; i < options.size(); ++i) { + options.get(i).drawButton(mc, mouseX, mouseYScroll); + } + GlStateManager.translate(0, -lastScrollY, 0); + + drawGradientRect(0, 0, width, 30, 0xC8101010, 0x00000000); + drawGradientRect(0, height - 30, width, height, 0x00000000, 0xC8101010); + + super.drawScreen(mouseX, mouseY, partialTicks); + + int x = width / 2; + int y = (30 - fontRendererObj.FONT_HEIGHT) / 2; + if(mouseY < 30) { + if(Mouse.isButtonDown(1)) { + drawCenteredString(fontRendererObj, titleRightClick, x, y, 0xFF0000); + } else { + drawCenteredString(fontRendererObj, titleMouseOver, x, y, 0xC0C0C0); + } + } else { + drawCenteredString(fontRendererObj, title, x, y, 0xFFFFFF); + } + + if(Mouse.isButtonDown(1)) { + for(int i = 0; i < this.options.size(); ++i) { + GuiConfigOption button = this.options.get(i); + if(!button.isMouseOver()) continue; + + String description = button.getDescription(); + if(description == null) continue; + + List lines = fontRendererObj.listFormattedStringToWidth(description, width - 10); + + int tooltipY = mouseY + 10; + int tooltipHeight = (lines.size() * fontRendererObj.FONT_HEIGHT) + 10; + int tooltipBottom = tooltipY + tooltipHeight; + + if(tooltipBottom > height) { + tooltipY = height - tooltipHeight; + tooltipBottom = height; + } + + drawRect(0, tooltipY, width, tooltipBottom, 0xC8101010); + + tooltipY += 5; + int line = 0; + for(String l : lines) { + fontRendererObj.drawString(l, 5, tooltipY + (line * fontRendererObj.FONT_HEIGHT), 0xFFFFFF, true); + line++; + } + } + } + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + super.mouseClicked(mouseX, mouseY, mouseButton); + + if(mouseButton == 0) { + int mouseYScroll = getScrollMouseY(mouseY); + + for(int i = 0; i < options.size(); ++i) { + GuiConfigOption button = options.get(i); + + if(button.mousePressed(mc, mouseX, mouseYScroll)) { + button.playPressSound(mc.getSoundHandler()); + button.actionPerformed(); + actionPerformed(button); + } + } + } + } + + @Override + public boolean doesGuiPauseGame() { + return true; + } + + @Override + protected void actionPerformed(GuiButton button) throws IOException { + switch(button.id) { + case -1: + // Done + boolean restart = OptionManager.store(options); + mc.displayGuiScreen(restart ? new GuiRestartDialog(parent) : parent); + break; + case -2: + // Cancel + mc.displayGuiScreen(parent); + break; + } + } +} diff --git a/src/main/java/guichaguri/betterfps/gui/GuiConfigOption.java b/src/main/java/guichaguri/betterfps/gui/GuiConfigOption.java new file mode 100644 index 0000000..d2cba55 --- /dev/null +++ b/src/main/java/guichaguri/betterfps/gui/GuiConfigOption.java @@ -0,0 +1,98 @@ +package guichaguri.betterfps.gui; + +import com.mojang.realmsclient.gui.ChatFormatting; +import net.minecraft.client.resources.I18n; +import org.lwjgl.input.Keyboard; + +/** + * @author Guilherme Chaguri + */ +public class GuiConfigOption extends GuiCycleButton { + + private String description; + private boolean wide = false; + private boolean restart = false; + private int originalValue = -1; + private T defaultVanilla, defaultBetterFps; + private Runnable shiftClick; + + public GuiConfigOption(int id, String title) { + super(id, I18n.format(title)); + } + + public boolean isWide() { + return wide; + } + + public void setWide(boolean wide) { + this.wide = wide; + } + + public boolean shouldRestart() { + return restart && originalValue != index; + } + + public void setRestart(boolean restart) { + this.restart = restart; + } + + public void setShiftClick(Runnable shiftClick) { + this.shiftClick = shiftClick; + } + + public void setDefaults(T defaultVanilla, T defaultBetterFps, T originalValue) { + this.defaultVanilla = defaultVanilla; + this.defaultBetterFps = defaultBetterFps; + + setValue(originalValue); + this.originalValue = index; + } + + public String getDescription() { + return description; + } + + public void setDescription(String ... lines) { + StringBuilder builder = new StringBuilder(); + + for(String line : lines) { + builder.append(line); + builder.append('\n'); + } + + builder.append('\n'); + builder.append(ChatFormatting.GRAY); + if(defaultVanilla == defaultBetterFps) { + builder.append(I18n.format("betterfps.options.default", toDisplayName(defaultBetterFps))); + } else { + builder.append(I18n.format("betterfps.options.default.vanilla", toDisplayName(defaultVanilla))); + builder.append('\n'); + builder.append(I18n.format("betterfps.options.default.betterfps", toDisplayName(defaultBetterFps))); + } + if(restart) { + builder.append('\n'); + builder.append(ChatFormatting.RED); + builder.append(I18n.format("betterfps.options.restart")); + } + + description = builder.toString(); + } + + @Override + public void add(T value, String displayName) { + super.add(value, I18n.format(displayName)); + } + + @Override + public void actionPerformed() { + if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { + if(shiftClick != null) { + shiftClick.run(); + return; + } + } + + super.actionPerformed(); + } + +} diff --git a/src/main/java/guichaguri/betterfps/gui/GuiCycleButton.java b/src/main/java/guichaguri/betterfps/gui/GuiCycleButton.java index bc93ad9..8509d40 100644 --- a/src/main/java/guichaguri/betterfps/gui/GuiCycleButton.java +++ b/src/main/java/guichaguri/betterfps/gui/GuiCycleButton.java @@ -1,71 +1,70 @@ package guichaguri.betterfps.gui; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; import net.minecraft.client.gui.GuiButton; -import org.lwjgl.input.Keyboard; +import org.apache.commons.lang3.ArrayUtils; /** * @author Guilherme Chaguri */ -public class GuiCycleButton extends GuiButton { - private String title; - protected int key = 0; - protected List keys; - protected HashMap values; - private String[] helpLines; +public class GuiCycleButton extends GuiButton { - public GuiCycleButton(int buttonId, String title, HashMap values, T defaultValue, String[] helpLines) { - super(buttonId, 0, 0, title); - this.title = title; - this.keys = new ArrayList(values.keySet()); - this.helpLines = helpLines; - for(int i = 0; i < keys.size(); i++) { - if(defaultValue.equals(keys.get(i))) { - key = i; break; - } - } - this.values = values; - updateTitle(); - } + protected final String title; + protected int index = 0; + protected Object[] values = new Object[0]; + protected String[] displayNames = new String[0]; + public GuiCycleButton(int id, String title) { + super(id, 0, 0, title); + this.title = title; - public void actionPerformed() { - if(Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && shiftClick()) return; - key++; - if(key >= keys.size()) key = 0; updateTitle(); } - public boolean shiftClick() { - return false; + public void set(T[] values, String[] displayNames) { + this.values = values; + this.displayNames = displayNames; } - protected void updateTitle() { - displayString = title + ": " + values.get(keys.get(key)); + public void add(T value, String displayName) { + displayNames = ArrayUtils.add(displayNames, displayName); + values = ArrayUtils.add(values, value); } - public T getSelectedValue() { - return (T)keys.get(key); + public T getValue() { + return (T)values[index]; } - public String[] getHelpText() { - return helpLines; + public void setValue(T elem) { + for(int i = 0; i < values.length; i++) { + if(values[i] == elem) { + this.index = i; + this.updateTitle(); + break; + } + } } - public static class GuiBooleanButton extends GuiCycleButton { - private static final HashMap booleanValues = new HashMap(); - static { - booleanValues.put(true, "On"); - booleanValues.put(false, "Off"); + public String toDisplayName(T elem) { + for(int i = 0; i < values.length; i++) { + if(values[i] == elem) return displayNames[i]; } + return null; + } - public GuiBooleanButton(int buttonId, String title, boolean defaultValue, String[] helpLines) { - super(buttonId, title, booleanValues, defaultValue, helpLines); - } + public void actionPerformed() { + index++; + if(index >= values.length) index = 0; + updateTitle(); + } + + public void setTitle(String title) { + displayString = title; + } + public void updateTitle() { + if(index >= displayNames.length) return; + displayString = String.format("%s: %s", title, displayNames[index]); } } diff --git a/src/main/java/guichaguri/betterfps/gui/GuiRestartDialog.java b/src/main/java/guichaguri/betterfps/gui/GuiRestartDialog.java index 2004f13..3850465 100644 --- a/src/main/java/guichaguri/betterfps/gui/GuiRestartDialog.java +++ b/src/main/java/guichaguri/betterfps/gui/GuiRestartDialog.java @@ -9,12 +9,7 @@ * @author Guilherme Chaguri */ public class GuiRestartDialog extends GuiScreen { - private GuiScreen parent = null; - - private final String[] message = new String[]{ - "You need to restart your game to apply some changes", - "Do you want restart now?" - }; + private final GuiScreen parent; public GuiRestartDialog(GuiScreen parent) { this.parent = parent; @@ -31,11 +26,11 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) { drawDefaultBackground(); int centerX = width / 2; int centerY = height / 2; - int i = 0; - for(String msg : message) { - drawCenteredString(fontRendererObj, msg, centerX, centerY - - ((message.length - i) * fontRendererObj.FONT_HEIGHT), 0xFFFFFF); - i++; + int dialogTextAmount = 2; + + for(int i = 0; i < dialogTextAmount; i++) { + String msg = I18n.format("betterfps.options.restart.dialog." + (i + 1)); + drawCenteredString(fontRendererObj, msg, centerX, centerY - ((dialogTextAmount - i) * fontRendererObj.FONT_HEIGHT), 0xFFFFFF); } super.drawScreen(mouseX, mouseY, partialTicks); } @@ -47,11 +42,13 @@ public boolean doesGuiPauseGame() { @Override protected void actionPerformed(GuiButton button) throws IOException { - super.actionPerformed(button); - if(button.id == 1) { - mc.shutdown(); - } else if(button.id == 2) { - mc.displayGuiScreen(parent); + switch(button.id) { + case 1: + mc.shutdown(); + break; + case 2: + mc.displayGuiScreen(parent); + break; } } } diff --git a/src/main/java/guichaguri/betterfps/gui/data/AlgorithmAction.java b/src/main/java/guichaguri/betterfps/gui/data/AlgorithmAction.java new file mode 100644 index 0000000..a1b164e --- /dev/null +++ b/src/main/java/guichaguri/betterfps/gui/data/AlgorithmAction.java @@ -0,0 +1,100 @@ +package guichaguri.betterfps.gui.data; + +import guichaguri.betterfps.BetterFpsConfig.AlgorithmType; +import guichaguri.betterfps.BetterFpsHelper; +import guichaguri.betterfps.gui.GuiConfigOption; +import guichaguri.betterfps.tweaker.BetterFpsTweaker; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import net.minecraft.client.resources.I18n; +import net.minecraft.util.Util; +import net.minecraft.util.Util.EnumOS; + +/** + * @author Guilherme Chaguri + */ +public class AlgorithmAction implements Runnable { + private final GuiConfigOption button; + private Thread thread; + private Process process; + + public AlgorithmAction(GuiConfigOption button) { + this.button = button; + } + + private String getJavaDir() { + String separator = System.getProperty("file.separator"); + String path = System.getProperty("java.home") + separator + "bin" + separator; + if((Util.getOSType() == EnumOS.WINDOWS) && (new File(path + "javaw.exe").isFile())) { + return path + "javaw.exe"; + } + return path + "java"; + } + + private AlgorithmType parseAlgorithm(String algorithm) { + if(algorithm == null) { + return null; + } else if(algorithm.equals("java")) { + return AlgorithmType.JAVA; + } else if(algorithm.equals("rivens")) { + return AlgorithmType.RIVENS; + } else if(algorithm.equals("rivens-full")) { + return AlgorithmType.RIVENS_FULL; + } else if(algorithm.equals("rivens-half")) { + return AlgorithmType.RIVENS_HALF; + } else if(algorithm.equals("libgdx")) { + return AlgorithmType.LIBGDX; + } else if(algorithm.equals("taylors")) { + return AlgorithmType.TAYLORS; + } else if(algorithm.equals("vanilla")) { + return AlgorithmType.VANILLA; + } + return null; + } + + @Override + public void run() { + if(process != null && thread != null && thread.isAlive()) return; + BetterFpsHelper.LOG.info("Benchmarking algorithms..."); + button.setTitle(I18n.format("betterfps.installer.algorithm.working")); + + List args = new ArrayList(); + args.add(getJavaDir()); + args.add("-cp"); + args.add(BetterFpsTweaker.class.getProtectionDomain().getCodeSource().getLocation().getFile()); + args.add("guichaguri.betterfps.installer.GuiAlgorithmTester"); + + thread = new Thread(new Runnable() { + @Override + public void run() { + try { + process.waitFor(); + + BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream())); + String line = in.readLine(); + + BetterFpsHelper.LOG.info("Benchmark is done."); + button.setValue(parseAlgorithm(line)); + button.updateTitle(); + process.destroy(); + process = null; + thread = null; + } catch(Exception ex) { + ex.printStackTrace(); + } + } + }); + + try { + process = new ProcessBuilder(args).start(); + thread.start(); + } catch(IOException ex) { + BetterFpsHelper.LOG.error("Couldn't launch the benchmark", ex); + } + } + +} diff --git a/src/main/java/guichaguri/betterfps/gui/data/OptionManager.java b/src/main/java/guichaguri/betterfps/gui/data/OptionManager.java new file mode 100644 index 0000000..f295ff3 --- /dev/null +++ b/src/main/java/guichaguri/betterfps/gui/data/OptionManager.java @@ -0,0 +1,134 @@ +package guichaguri.betterfps.gui.data; + +import com.mojang.realmsclient.gui.ChatFormatting; +import guichaguri.betterfps.BetterFpsConfig; +import guichaguri.betterfps.BetterFpsConfig.AlgorithmType; +import guichaguri.betterfps.BetterFpsHelper; +import guichaguri.betterfps.gui.GuiConfigOption; +import java.util.List; +import net.minecraft.client.resources.I18n; + +/** + * @author Guilherme Chaguri + */ +public class OptionManager { + + public static void addButtons(List buttons) { + BetterFpsConfig config = BetterFpsHelper.getConfig(); + + Boolean[] boolMap = new Boolean[]{true, false}; + + String[] enabledNames = new String[]{ + I18n.format("betterfps.options.on"), + I18n.format("betterfps.options.off") + }; + String[] fancyFast = new String[]{ + I18n.format("betterfps.options.fancy"), + I18n.format("betterfps.options.fast") + }; + + // Algorithm + GuiConfigOption algorithm = new GuiConfigOption(0, "betterfps.options.algorithm.title"); + algorithm.add(AlgorithmType.VANILLA, "betterfps.options.algorithm.vanilla"); + algorithm.add(AlgorithmType.RIVENS, "betterfps.options.algorithm.rivens"); + algorithm.add(AlgorithmType.RIVENS_FULL, "betterfps.options.algorithm.rivens-full"); + algorithm.add(AlgorithmType.RIVENS_HALF, "betterfps.options.algorithm.rivens-half"); + algorithm.add(AlgorithmType.TAYLORS, "betterfps.options.algorithm.taylors"); + algorithm.add(AlgorithmType.JAVA, "betterfps.options.algorithm.java"); + algorithm.add(AlgorithmType.RANDOM, "betterfps.options.algorithm.random"); + algorithm.setRestart(true); + algorithm.setWide(true); + algorithm.setDefaults(AlgorithmType.VANILLA, AlgorithmType.RIVENS_HALF, config.algorithm); + algorithm.setDescription( + I18n.format("betterfps.options.algorithm.desc"), + ChatFormatting.YELLOW + I18n.format("betterfps.options.algorithm.action") + ); + algorithm.setShiftClick(new AlgorithmAction(algorithm)); + buttons.add(algorithm); + + // Update Checker + GuiConfigOption updateChecker = new GuiConfigOption(1, "betterfps.options.updatechecker.title"); + updateChecker.set(boolMap, enabledNames); + updateChecker.setDefaults(true, true, config.updateChecker); + updateChecker.setDescription( + I18n.format("betterfps.options.updatechecker.desc"), + ChatFormatting.YELLOW + I18n.format("betterfps.options.updatechecker.action") + ); + updateChecker.setShiftClick(new UpdateCheckAction()); + buttons.add(updateChecker); + + // Pre-allocate memory + GuiConfigOption allocMemory = new GuiConfigOption(2, "betterfps.options.allocmemory.title"); + allocMemory.set(boolMap, enabledNames); + allocMemory.setRestart(true); + allocMemory.setDefaults(true, false, config.preallocateMemory); + allocMemory.setDescription(I18n.format("betterfps.options.allocmemory.desc")); + buttons.add(allocMemory); + + // Fog + GuiConfigOption fog = new GuiConfigOption(3, "betterfps.options.fog.title"); + fog.set(boolMap, fancyFast); + fog.setRestart(true); + fog.setDefaults(true, false, config.fog); + fog.setDescription(I18n.format("betterfps.options.fog.desc")); + buttons.add(fog); + + // Beacon Beam + GuiConfigOption beam = new GuiConfigOption(4, "betterfps.options.beaconbeam.title"); + beam.set(boolMap, fancyFast); + beam.setRestart(true); + beam.setDefaults(true, false, config.beaconBeam); + beam.setDescription(I18n.format("betterfps.options.beaconbeam.desc")); + buttons.add(beam); + + // Hopper Improvement + GuiConfigOption hopper = new GuiConfigOption(5, "betterfps.options.hopper.title"); + hopper.set(boolMap, enabledNames); + hopper.setRestart(true); + hopper.setDefaults(false, true, config.fastHopper); + hopper.setDescription(I18n.format("betterfps.options.hopper.desc")); + hopper.setRestart(true); + buttons.add(hopper); + + // Hopper Improvement + GuiConfigOption beacon; + beacon = new GuiConfigOption(6, "betterfps.options.beacon.title"); + beacon.set(boolMap, enabledNames); + beacon.setRestart(true); + beacon.setDefaults(false, true, config.fastBeacon); + beacon.setDescription(I18n.format("betterfps.options.beacon.desc")); + buttons.add(beacon); + } + + public static boolean store(List buttons) { + BetterFpsConfig config = BetterFpsHelper.getConfig(); + + config.algorithm = getButtonValue(buttons, 0, AlgorithmType.class); + config.updateChecker = getButtonValue(buttons, 1); + config.preallocateMemory = getButtonValue(buttons, 2); + config.fog = getButtonValue(buttons, 3); + config.beaconBeam = getButtonValue(buttons, 4); + config.fastHopper = getButtonValue(buttons, 5); + config.fastBeacon = getButtonValue(buttons, 6); + + for(GuiConfigOption button : buttons) { + if(button.shouldRestart()) return true; + } + return false; + } + + private static boolean getButtonValue(List buttons, int id) { + Boolean b = getButtonValue(buttons, id, Boolean.class); + return b == null ? true : b; + } + + private static T getButtonValue(List buttons, int id, Class type) { + for(GuiConfigOption button : buttons) { + if(button.id == id) { + return (T)button.getValue(); + } + } + return null; + } + +} diff --git a/src/main/java/guichaguri/betterfps/gui/data/UpdateCheckAction.java b/src/main/java/guichaguri/betterfps/gui/data/UpdateCheckAction.java new file mode 100644 index 0000000..cf30ca2 --- /dev/null +++ b/src/main/java/guichaguri/betterfps/gui/data/UpdateCheckAction.java @@ -0,0 +1,25 @@ +package guichaguri.betterfps.gui.data; + +import guichaguri.betterfps.BetterFpsHelper; +import guichaguri.betterfps.UpdateChecker; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.util.text.TextComponentTranslation; + +/** + * @author Guilherme Chaguri + */ +public class UpdateCheckAction implements Runnable { + + @Override + public void run() { + BetterFpsHelper.LOG.info("Checking for updates..."); + EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; + if(player != null) { + player.addChatComponentMessage(new TextComponentTranslation("betterfps.installer.update.check"), true); + } + + UpdateChecker.checkForced(); + } + +} diff --git a/src/main/java/guichaguri/betterfps/installer/GuiAlgorithmTester.java b/src/main/java/guichaguri/betterfps/installer/GuiAlgorithmTester.java index b8c9bb1..c48ef6d 100644 --- a/src/main/java/guichaguri/betterfps/installer/GuiAlgorithmTester.java +++ b/src/main/java/guichaguri/betterfps/installer/GuiAlgorithmTester.java @@ -43,6 +43,7 @@ public static void main(String[] args) { } System.out.println(bestAlgorithm); + System.exit(0); } private static void warmupClasses() { diff --git a/src/main/java/guichaguri/betterfps/patches/misc/OptionsButton.java b/src/main/java/guichaguri/betterfps/patches/misc/OptionsButton.java index a75335a..30e1354 100644 --- a/src/main/java/guichaguri/betterfps/patches/misc/OptionsButton.java +++ b/src/main/java/guichaguri/betterfps/patches/misc/OptionsButton.java @@ -1,6 +1,6 @@ package guichaguri.betterfps.patches.misc; -import guichaguri.betterfps.gui.newgui.GuiBetterFpsConfig; +import guichaguri.betterfps.gui.GuiBetterFpsConfig; import guichaguri.betterfps.transformers.annotations.Copy; import guichaguri.betterfps.transformers.annotations.Copy.Mode; import java.io.IOException; diff --git a/src/main/java/guichaguri/betterfps/transformers/MathTransformer.java b/src/main/java/guichaguri/betterfps/transformers/MathTransformer.java index ad3dee2..1311825 100644 --- a/src/main/java/guichaguri/betterfps/transformers/MathTransformer.java +++ b/src/main/java/guichaguri/betterfps/transformers/MathTransformer.java @@ -23,17 +23,17 @@ public class MathTransformer implements IClassTransformer { // Config Name, Class Name - private static final LinkedHashMap algorithmClasses = new LinkedHashMap(); + private static final LinkedHashMap algorithmClasses = new LinkedHashMap(); static { - algorithmClasses.put("vanilla", "guichaguri/betterfps/math/VanillaMath"); - algorithmClasses.put("rivens", "guichaguri/betterfps/math/RivensMath"); - algorithmClasses.put("taylors", "guichaguri/betterfps/math/TaylorMath"); - algorithmClasses.put("libgdx", "guichaguri/betterfps/math/LibGDXMath"); - algorithmClasses.put("rivens-full", "guichaguri/betterfps/math/RivensFullMath"); - algorithmClasses.put("rivens-half", "guichaguri/betterfps/math/RivensHalfMath"); - algorithmClasses.put("java", "guichaguri/betterfps/math/JavaMath"); - algorithmClasses.put("random", "guichaguri/betterfps/math/RandomMath"); + algorithmClasses.put(AlgorithmType.VANILLA, "guichaguri/betterfps/math/VanillaMath"); + algorithmClasses.put(AlgorithmType.RIVENS, "guichaguri/betterfps/math/RivensMath"); + algorithmClasses.put(AlgorithmType.TAYLORS, "guichaguri/betterfps/math/TaylorMath"); + algorithmClasses.put(AlgorithmType.LIBGDX, "guichaguri/betterfps/math/LibGDXMath"); + algorithmClasses.put(AlgorithmType.RIVENS_FULL, "guichaguri/betterfps/math/RivensFullMath"); + algorithmClasses.put(AlgorithmType.RIVENS_HALF, "guichaguri/betterfps/math/RivensHalfMath"); + algorithmClasses.put(AlgorithmType.JAVA, "guichaguri/betterfps/math/JavaMath"); + algorithmClasses.put(AlgorithmType.RANDOM, "guichaguri/betterfps/math/RandomMath"); } private final String METHOD_SIN = "sin"; @@ -47,7 +47,7 @@ public byte[] transform(String name, String transformedName, byte[] bytes) { try { return patchMath(bytes); } catch(Exception ex) { - ex.printStackTrace(); + BetterFpsHelper.LOG.error("Couldn't patch math algorithms", ex); } } @@ -107,7 +107,7 @@ private byte[] patchMath(byte[] bytes) throws Exception { FieldNode sinTable = ASMUtils.findField(classNode, Mappings.F_SIN_TABLE); - if(patchedSin && patchedCos && sinTable != null) { + if(patchedSin && patchedCos && sinTable != null && init != null) { classNode.fields.remove(sinTable); InsnList inst = init.instructions; diff --git a/src/main/java/guichaguri/betterfps/tweaker/Mappings.java b/src/main/java/guichaguri/betterfps/tweaker/Mappings.java index 027eb9c..f4a9762 100644 --- a/src/main/java/guichaguri/betterfps/tweaker/Mappings.java +++ b/src/main/java/guichaguri/betterfps/tweaker/Mappings.java @@ -14,7 +14,7 @@ * * @author Guilherme Chaguri */ -public enum Mappings { // TODO BUKKIT +public enum Mappings { // TODO: new mapping system. Maybe reading this class by a gradle task and saving the map in a file?