├── LICENSE ├── README.md ├── build.gradle └── src └── main ├── java └── me │ └── frosty │ └── client │ ├── Client.java │ ├── mixin │ ├── Tweaker.java │ └── impl │ │ ├── MixinGuiIngame.java │ │ ├── MixinGuiMainMenu.java │ │ └── MixinMinecraft.java │ ├── module │ ├── AbstractModule.java │ ├── ModuleManager.java │ └── impl │ │ └── TestModule.java │ ├── ui │ ├── UIElement.java │ ├── UIScreen.java │ ├── component │ │ ├── button │ │ │ └── LargeButton.java │ │ └── module │ │ │ └── Position.java │ └── menu │ │ └── MainMenu.java │ └── util │ ├── Logger.java │ └── RenderUtil.java └── resources └── mixins.client.json /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 frosty 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ClientBase 2 | A simple mixin client base for beginners. 3 | 4 | I made this via a video on youtube in around 20 minutes. 5 | https://www.youtube.com/watch?v=QN1oiW2rY3g 6 | 7 | I would really appreciate if you credit me for the code if you decide to use it :) 8 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | jcenter() 5 | maven { 6 | name = "forge" 7 | url = "http://files.minecraftforge.net/maven" 8 | } 9 | maven { 10 | name = 'sponge' 11 | url = 'https://repo.spongepowered.org/maven' 12 | } 13 | } 14 | dependencies { 15 | classpath 'net.minecraftforge.gradle:ForgeGradle:2.1-SNAPSHOT' 16 | classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT' 17 | } 18 | } 19 | 20 | apply plugin: 'net.minecraftforge.gradle.tweaker-client' 21 | apply plugin: 'org.spongepowered.mixin' 22 | apply plugin: 'java' 23 | 24 | version = "1.0" 25 | group= "me.frosty" 26 | archivesBaseName = "Client" 27 | 28 | sourceCompatibility = targetCompatibility = 1.8 29 | compileJava.options.encoding = 'UTF-8' 30 | 31 | minecraft { 32 | version = "1.8.9" 33 | tweakClass = "me.frosty.client.mixin.Tweaker" 34 | runDir = "run" 35 | mappings = "stable_20" 36 | makeObfSourceJar = false 37 | } 38 | 39 | repositories { 40 | maven { url "https://jitpack.io" } 41 | maven { 42 | name = 'sponge' 43 | url = 'https://repo.spongepowered.org/maven/' 44 | } 45 | mavenCentral() 46 | jcenter() 47 | } 48 | 49 | configurations { 50 | embed 51 | compile.extendsFrom(embed) 52 | } 53 | 54 | dependencies { 55 | embed('org.spongepowered:mixin:0.7.11-SNAPSHOT') { 56 | exclude module: 'launchwrapper' 57 | exclude module: 'guava' 58 | exclude module: 'gson' 59 | exclude module: 'commons-io' 60 | } 61 | 62 | compileOnly 'org.projectlombok:lombok:1.18.20' 63 | annotationProcessor 'org.projectlombok:lombok:1.18.20' 64 | 65 | testCompileOnly 'org.projectlombok:lombok:1.18.20' 66 | testAnnotationProcessor 'org.projectlombok:lombok:1.18.20' 67 | compile('org.spongepowered:mixin:0.7.11-SNAPSHOT') 68 | } 69 | 70 | mixin { 71 | defaultObfuscationEnv notch 72 | add sourceSets.main, "mixins.tecknix.refmap.json" 73 | } 74 | 75 | processResources { 76 | inputs.files "src/main/resources" 77 | outputs.dir "build/classes/main" 78 | copy { 79 | from("src/main/resources") 80 | into("build/classes/main") 81 | } 82 | } 83 | 84 | jar { 85 | dependsOn configurations.compile 86 | from { 87 | configurations.embed.collect { 88 | it.isDirectory() ? it : zipTree(it) 89 | } 90 | } 91 | exclude 'META-INF/*.RSA', 'META-INF/*.SF', 'META-INF/*.DSA' 92 | } 93 | 94 | jar { 95 | manifest.attributes( 96 | "MixinConfigs": 'mixins.client.json', 97 | "TweakClass": "me.frosty.client.mixin.Tweaker", 98 | "TweakOrder": 0, 99 | "Manifest-Version": 1.0 100 | ) 101 | 102 | configurations.embed.each { dep -> 103 | from(project.zipTree(dep)) { 104 | exclude 'META-INF', 'META-INF/**' 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/Client.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client; 2 | 3 | import lombok.Getter; 4 | import me.frosty.client.module.ModuleManager; 5 | import me.frosty.client.util.Logger; 6 | import org.lwjgl.opengl.Display; 7 | 8 | @Getter public final class Client { 9 | 10 | @Getter private static Client instance; 11 | 12 | private ModuleManager moduleManager; 13 | 14 | /** 15 | * Starts and registers everything! 16 | * 17 | * @author frosty 18 | * @see me.frosty.client.mixin.impl.MixinMinecraft 19 | */ 20 | public void start() { 21 | instance = this; 22 | Display.setTitle("Client - v" + this.getVersion()); 23 | 24 | Logger.info("Starting Up."); 25 | 26 | this.moduleManager = new ModuleManager(); 27 | Logger.info("Created Module Manager."); 28 | } 29 | 30 | /** 31 | * Called on game shutdown. 32 | * 33 | * @author frosty 34 | * @see me.frosty.client.mixin.impl.MixinMinecraft 35 | */ 36 | public void stop() { 37 | Logger.info("Shutting Down."); 38 | } 39 | 40 | /** 41 | * Returns the client version. 42 | * 43 | * @return String. 44 | * @author frosty 45 | */ 46 | public String getVersion() { 47 | return "1.0.0"; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/mixin/Tweaker.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.mixin; 2 | 3 | 4 | import net.minecraft.launchwrapper.ITweaker; 5 | import net.minecraft.launchwrapper.LaunchClassLoader; 6 | import org.spongepowered.asm.launch.MixinBootstrap; 7 | import org.spongepowered.asm.mixin.MixinEnvironment; 8 | 9 | import java.io.File; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class Tweaker implements ITweaker { 14 | 15 | private final List arguments = new ArrayList<>(); 16 | 17 | @Override 18 | public final void acceptOptions(List args, File gameDir, File assetsDir, String profile) { 19 | this.arguments.addAll(args); 20 | 21 | final String version = "--version"; 22 | final String assetDir = "--assetDir"; 23 | final String gamesDir = "--gameDir"; 24 | 25 | if (!args.contains(version) && profile != null) { 26 | this.arguments.add(version); 27 | this.arguments.add(profile); 28 | } 29 | 30 | if (!args.contains(assetDir) && profile != null) { 31 | this.arguments.add(assetDir); 32 | this.arguments.add(profile); 33 | } 34 | 35 | if (!args.contains(gamesDir) && profile != null) { 36 | this.arguments.add(gamesDir); 37 | this.arguments.add(profile); 38 | } 39 | } 40 | 41 | @Override 42 | public final void injectIntoClassLoader(LaunchClassLoader classLoader) { 43 | MixinBootstrap.init(); 44 | 45 | MixinEnvironment environment = MixinEnvironment.getDefaultEnvironment(); 46 | 47 | //noinspection deprecation 48 | environment.addConfiguration("mixins.client.json"); 49 | 50 | if (environment.getObfuscationContext() == null) { 51 | environment.setObfuscationContext("notch"); 52 | } 53 | 54 | environment.setSide(MixinEnvironment.Side.CLIENT); 55 | } 56 | 57 | @Override 58 | public String getLaunchTarget() { 59 | return MixinBootstrap.getPlatform().getLaunchTarget(); 60 | } 61 | 62 | @Override 63 | public String[] getLaunchArguments() { 64 | return this.arguments.toArray(new String[0]); 65 | } 66 | } -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/mixin/impl/MixinGuiIngame.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.mixin.impl; 2 | 3 | import me.frosty.client.Client; 4 | import net.minecraft.client.gui.GuiIngame; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | @Mixin(GuiIngame.class) 11 | public class MixinGuiIngame { 12 | 13 | @Inject(method = "renderGameOverlay", at = @At("RETURN")) 14 | public void injectRenderGameOverlay(float partialTicks, CallbackInfo ci) { 15 | Client.getInstance().getModuleManager().renderHud(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/mixin/impl/MixinGuiMainMenu.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.mixin.impl; 2 | 3 | import me.frosty.client.ui.menu.MainMenu; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.GuiMainMenu; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(GuiMainMenu.class) 12 | public class MixinGuiMainMenu { 13 | 14 | @Inject(method = "initGui", at = @At("HEAD")) 15 | public void injectInitGui(CallbackInfo ci) { 16 | Minecraft.getMinecraft().displayGuiScreen(new MainMenu()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/mixin/impl/MixinMinecraft.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.mixin.impl; 2 | 3 | import me.frosty.client.Client; 4 | import net.minecraft.client.Minecraft; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.Inject; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | @Mixin(Minecraft.class) 11 | public class MixinMinecraft { 12 | 13 | @Inject(method = "startGame", at = @At("RETURN")) 14 | public void injectStartGame(CallbackInfo ci) { 15 | new Client().start(); 16 | } 17 | 18 | @Inject(method = "shutdownMinecraftApplet", at = @At("HEAD")) 19 | public void injectShutdown(CallbackInfo ci) { 20 | Client.getInstance().stop(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/module/AbstractModule.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.module; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import me.frosty.client.ui.component.module.Position; 6 | import net.minecraft.client.Minecraft; 7 | 8 | @Getter @Setter 9 | public abstract class AbstractModule { 10 | 11 | protected final Minecraft mc = Minecraft.getMinecraft(); 12 | 13 | protected final String name; 14 | protected final String description; 15 | 16 | @Setter private Position position; 17 | 18 | protected Integer width; 19 | protected Integer height; 20 | 21 | protected Boolean enabled; 22 | 23 | /** 24 | * Module constructor. 25 | * 26 | * @param name - The name of the module. 27 | * @param description - The description of the module. 28 | * @author frosty 29 | */ 30 | public AbstractModule(String name, String description) { 31 | this.name = name; 32 | this.description = description; 33 | this.position = new Position(5, 5); 34 | } 35 | 36 | /** 37 | * Renders the module to the hud. 38 | * 39 | * @param position - The modules position object storing its X and Y. 40 | * @author frosty 41 | */ 42 | public abstract void render(Position position); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/module/ModuleManager.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.module; 2 | 3 | import lombok.Getter; 4 | import me.frosty.client.util.Logger; 5 | import me.frosty.client.module.impl.TestModule; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | public class ModuleManager { 12 | 13 | @Getter private final List modules = new ArrayList<>(); 14 | 15 | public ModuleManager() { 16 | this.register(new TestModule()); 17 | 18 | Logger.info("Registered " + this.modules.size() + " Modules!"); 19 | } 20 | 21 | /** 22 | * Registers a module. 23 | * 24 | * @author frosty 25 | */ 26 | public void register(final AbstractModule module) { 27 | this.modules.add(module); 28 | } 29 | 30 | /** 31 | * Gets all enabled modules as a list. 32 | * 33 | * @author frosty 34 | * @return List. 35 | */ 36 | public List getEnabledModules() { 37 | return this.modules.stream().filter(AbstractModule::getEnabled).collect(Collectors.toList()); 38 | } 39 | 40 | /** 41 | * Renders the hud to the display. 42 | * 43 | * @author frosty 44 | * @see me.frosty.client.mixin.impl.MixinGuiIngame 45 | */ 46 | public void renderHud() { 47 | for (AbstractModule module : this.getEnabledModules()) { 48 | module.render(module.getPosition()); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/module/impl/TestModule.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.module.impl; 2 | 3 | import me.frosty.client.module.AbstractModule; 4 | import me.frosty.client.ui.component.module.Position; 5 | 6 | public class TestModule extends AbstractModule { 7 | 8 | public TestModule() { 9 | super("TestModule", "Epic test module!"); 10 | this.setEnabled(true); 11 | } 12 | 13 | @Override 14 | public void render(Position position) { 15 | this.mc.fontRendererObj.drawString("Test Module!", position.getX(), position.getY(), -1); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/ui/UIElement.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.ui; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.experimental.Accessors; 6 | import net.minecraft.client.Minecraft; 7 | 8 | /** 9 | * This class is used for rendering any possible element to the screen! 10 | * 11 | * @author frosty 12 | */ 13 | @Setter @Getter 14 | @Accessors(chain = true) 15 | public abstract class UIElement { 16 | 17 | protected Integer x; 18 | protected Integer y; 19 | 20 | protected Integer width; 21 | protected Integer height; 22 | 23 | protected final Minecraft mc = Minecraft.getMinecraft(); 24 | 25 | /** 26 | * Sets the size of the element. This can be replaced with chain accessors. 27 | * 28 | * @param x - X Position on the screen to set the element. 29 | * @param y - Y Position on the screen to set the element. 30 | * @param width - The width of the element. 31 | * @param height - The height of the element. 32 | * @author frosty 33 | */ 34 | public void setSize(Integer x, Integer y, Integer width, Integer height) { 35 | this.x = x; 36 | this.y = y; 37 | this.width = width; 38 | this.height = height; 39 | } 40 | 41 | /** 42 | * Renders the element given the mouse X and Y positions. 43 | * 44 | * @param mouseX The mouse X position. 45 | * @param mouseY The mouse Y position. 46 | * @author frosty 47 | */ 48 | public abstract void renderElement(float mouseX, float mouseY); 49 | 50 | /** 51 | * Fired when the mouse is pressed. 52 | * 53 | * @param mouseX The mouse X position. 54 | * @param mouseY The mouse Y position. 55 | * @param button The mouse button pressed. (Left or right) 56 | * @author frosty 57 | */ 58 | public abstract void mouseClicked(float mouseX, float mouseY, int button); 59 | 60 | /** 61 | * Fired when the mouse is released. 62 | * 63 | * @param mouseX The mouse X position. 64 | * @param mouseY The mouse Y position. 65 | * @author frosty 66 | */ 67 | public abstract void mouseReleased(float mouseX, float mouseY); 68 | 69 | 70 | /** 71 | * Checks if the mouse is over the element. 72 | * 73 | * @param mouseX The mouse X position. 74 | * @param mouseY The mouse Y position. 75 | * @author frosty 76 | */ 77 | public boolean mouseInside(float mouseX, float mouseY) { 78 | return mouseX >= this.x && mouseY >= this.y && mouseX <= this.x + this.width && mouseY <= this.y + this.height; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/ui/UIScreen.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.ui; 2 | 3 | import net.minecraft.client.gui.GuiScreen; 4 | 5 | /* 6 | * This class is used for rendering a "custom" menu instead of extending GuiScreen. 7 | * This makes multi-version support easier etc etc. 8 | */ 9 | public abstract class UIScreen extends GuiScreen { 10 | 11 | /** 12 | * Renders the screen given the mouse X and Y positions. 13 | * 14 | * @param mouseX The mouse X position. 15 | * @param mouseY The mouse Y position. 16 | * @author frosty 17 | */ 18 | public abstract void renderUI(float mouseX, float mouseY); 19 | 20 | /** 21 | * Fired when the mouse is pressed. 22 | * 23 | * @param mouseX The mouse X position. 24 | * @param mouseY The mouse Y position. 25 | * @param button The mouse button pressed. (Left or right) 26 | * @author frosty 27 | */ 28 | public abstract void mousePressed(float mouseX, float mouseY, int button); 29 | 30 | /** 31 | * Fired when the mouse is released. 32 | * 33 | * @param mouseX The mouse X position. 34 | * @param mouseY The mouse Y position. 35 | * @author frosty 36 | */ 37 | public abstract void mouseReleased(float mouseX, float mouseY); 38 | 39 | /* 40 | * Methods below are just calling our abstract methods. 41 | */ 42 | @Override 43 | public void drawScreen(int mouseX, int mouseY, float partialTicks) { 44 | super.drawScreen(mouseX, mouseY, partialTicks); 45 | this.renderUI(mouseX, mouseY); 46 | } 47 | 48 | @Override 49 | protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { 50 | this.mousePressed(mouseX, mouseY, mouseButton); 51 | } 52 | 53 | @Override 54 | protected void mouseReleased(int mouseX, int mouseY, int state) { 55 | this.mouseReleased(mouseX, mouseY); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/ui/component/button/LargeButton.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.ui.component.button; 2 | 3 | import lombok.AllArgsConstructor; 4 | import me.frosty.client.ui.UIElement; 5 | import me.frosty.client.util.RenderUtil; 6 | 7 | import java.awt.*; 8 | 9 | @AllArgsConstructor 10 | public class LargeButton extends UIElement { 11 | 12 | private final String text; 13 | 14 | @Override 15 | public void renderElement(float mouseX, float mouseY) { 16 | RenderUtil.drawRect(this.x, this.y, this.x + this.width, this.y + this.height, new Color(0,0,0, 100).getRGB()); //Cba to do this. 17 | this.mc.fontRendererObj.drawString(this.text, this.x + this.width / 2 - (this.mc.fontRendererObj.getStringWidth(this.text) / 2) , this.y + 4, -1); 18 | } 19 | 20 | @Override public void mouseClicked(float mouseX, float mouseY, int button) {} 21 | 22 | @Override public void mouseReleased(float mouseX, float mouseY) {} 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/ui/component/module/Position.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.ui.component.module; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter @Setter 7 | public class Position { 8 | 9 | private final Integer x; 10 | private final Integer y; 11 | 12 | /** 13 | * Position Constructor. 14 | * 15 | * @param x - The X position of the module. 16 | * @param y - The Y position of the module. 17 | * @author frosty 18 | */ 19 | public Position(Integer x, Integer y) { 20 | this.x = x; 21 | this.y = y; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/ui/menu/MainMenu.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.ui.menu; 2 | 3 | import me.frosty.client.ui.UIScreen; 4 | import me.frosty.client.ui.component.button.LargeButton; 5 | import me.frosty.client.util.RenderUtil; 6 | import net.minecraft.client.gui.GuiMultiplayer; 7 | import net.minecraft.client.gui.GuiSelectWorld; 8 | 9 | import java.awt.*; 10 | 11 | public class MainMenu extends UIScreen { 12 | 13 | private final LargeButton singleplayer = new LargeButton("SINGLEPLAYER"); 14 | private final LargeButton multiplayer = new LargeButton("MULTIPLAYER"); 15 | 16 | @Override 17 | public void renderUI(float mouseX, float mouseY) { 18 | RenderUtil.drawRect(0, 0, this.width, this.height, new Color(150, 150, 150).getRGB()); 19 | 20 | this.singleplayer.renderElement(mouseX, mouseY); 21 | this.multiplayer.renderElement(mouseX, mouseY); 22 | 23 | this.mc.fontRendererObj.drawString("By Frosty!", 3, this.height - 12, -1); 24 | } 25 | 26 | @Override 27 | public void initGui() { 28 | this.singleplayer.setX(this.width / 2 - 100).setY(this.height / 2 - 15).setWidth(200).setHeight(17); 29 | this.multiplayer.setX(this.width / 2 - 100).setY(this.height / 2 + 15).setWidth(200).setHeight(17); 30 | } 31 | 32 | @Override 33 | public void mousePressed(float mouseX, float mouseY, int button) { 34 | if (this.singleplayer.mouseInside(mouseX, mouseY)) { 35 | this.mc.displayGuiScreen(new GuiSelectWorld(this.mc.currentScreen)); 36 | } else if (this.multiplayer.mouseInside(mouseX, mouseY)) { 37 | this.mc.displayGuiScreen(new GuiMultiplayer(this.mc.currentScreen)); 38 | } 39 | } 40 | 41 | @Override 42 | public void mouseReleased(float mouseX, float mouseY) {} 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/util/Logger.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.util; 2 | 3 | public class Logger { 4 | 5 | /** 6 | * Prints anything out with a tag. 7 | * 8 | * @param message The object you wish to print. 9 | * @author frosty 10 | */ 11 | public static void info(Object message) { 12 | System.out.println("[CLIENT] " + message); 13 | } 14 | 15 | /** 16 | * Prints anything out with a tag. 17 | * 18 | * @param message The object you wish to print. 19 | * @author frosty 20 | */ 21 | public static void warning(Object message) { 22 | System.out.println("[CLIENT] " + message); 23 | } 24 | 25 | /** 26 | * Prints anything out with a tag. 27 | * 28 | * @param message The object you wish to print. 29 | * @author frosty 30 | */ 31 | public static void error(Object message) { 32 | System.err.println("[CLIENT] " + message); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/me/frosty/client/util/RenderUtil.java: -------------------------------------------------------------------------------- 1 | package me.frosty.client.util; 2 | 3 | import net.minecraft.client.renderer.GlStateManager; 4 | import net.minecraft.client.renderer.Tessellator; 5 | import net.minecraft.client.renderer.WorldRenderer; 6 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 7 | 8 | public class RenderUtil { 9 | 10 | /** 11 | * Taken from Gui.java. Renders a rectangle to the screen. 12 | */ 13 | public static void drawRect(int left, int top, int right, int bottom, int color) { 14 | if (left < right) { 15 | int i = left; 16 | left = right; 17 | right = i; 18 | } 19 | if (top < bottom) { 20 | int j = top; 21 | top = bottom; 22 | bottom = j; 23 | } 24 | 25 | float f3 = (float) (color >> 24 & 255) / 255.0F; 26 | float f = (float) (color >> 16 & 255) / 255.0F; 27 | float f1 = (float) (color >> 8 & 255) / 255.0F; 28 | float f2 = (float) (color & 255) / 255.0F; 29 | Tessellator tessellator = Tessellator.getInstance(); 30 | WorldRenderer worldrenderer = tessellator.getWorldRenderer(); 31 | GlStateManager.enableBlend(); 32 | GlStateManager.disableTexture2D(); 33 | GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); 34 | GlStateManager.color(f, f1, f2, f3); 35 | worldrenderer.begin(7, DefaultVertexFormats.POSITION); 36 | worldrenderer.pos(left, bottom, 0.0D).endVertex(); 37 | worldrenderer.pos(right, bottom, 0.0D).endVertex(); 38 | worldrenderer.pos(right, top, 0.0D).endVertex(); 39 | worldrenderer.pos(left, top, 0.0D).endVertex(); 40 | tessellator.draw(); 41 | GlStateManager.enableTexture2D(); 42 | GlStateManager.disableBlend(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/resources/mixins.client.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "compatibilityLevel": "JAVA_8", 4 | "verbose": true, 5 | "package": "me.frosty.client.mixin.impl", 6 | "mixins": [ 7 | "MixinGuiIngame", 8 | "MixinGuiMainMenu", 9 | "MixinMinecraft" 10 | ] 11 | } --------------------------------------------------------------------------------