1
0
Fork 0
mirror of https://github.com/Miasmusa/Shadow.git synced 2025-04-09 02:34:22 -04:00

5000 kromer

This commit is contained in:
0x150 2021-12-18 19:30:00 +01:00
parent 3102b0a1be
commit 6b57aecbd4
31 changed files with 1874 additions and 380 deletions

View file

@ -12,7 +12,9 @@ group = project.maven_group
minecraft {
}
configurations {
impl
}
dependencies {
//to change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
@ -20,6 +22,19 @@ dependencies {
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
impl('io.github.spair:imgui-java-binding:1.82.2')
impl('io.github.spair:imgui-java-lwjgl3:1.82.2') {
exclude group: "org.lwjgl"
}
["linux", "linux-x86", "macos", "windows", "windows-x86"].each {
impl("io.github.spair:imgui-java-natives-$it:1.82.2")
}
configurations.impl.dependencies.each {
implementation(group: it.group, name: it.name, version: it.version)
include(group: it.group, name: it.name, version: it.version)
}
}
processResources {

View file

@ -12,10 +12,10 @@ import java.io.File;
public class SipoverPrivate implements ModInitializer {
public static final String MOD_ID = "sipoverprivate";
public static final String MOD_NAME = "SipoverPrivate";
public static Logger LOGGER = LogManager.getLogger();
public static MinecraftClient client = MinecraftClient.getInstance();
public static final String MOD_ID = "sipoverprivate";
public static final String MOD_NAME = "SipoverPrivate";
public static Logger LOGGER = LogManager.getLogger();
public static MinecraftClient client = MinecraftClient.getInstance();
public static File BASE = new File(MinecraftClient.getInstance().runDirectory, "sip");

View file

@ -1,59 +0,0 @@
package me.x150.sipprivate.command;
import net.minecraft.client.MinecraftClient;
/**
* A class representing a command
*/
public abstract class Command {
/**
* The minecraft instance
*/
public final MinecraftClient mc;
/**
* The main command name
*/
private final String command;
/**
* The command's aliases
*/
private final String[] alias;
/**
* Constructs a new command instance
*
* @param command The name of the command
* @param aliases Triggers for the command
*/
public Command(String command, String... aliases) {
this.command = command;
this.alias = aliases;
this.mc = MinecraftClient.getInstance();
}
/**
* Gets the command's name
*
* @return The command name
*/
public String getCommand() {
return command;
}
/**
* Gets the command's aliases
*
* @return The command's aliases
*/
public String[] getAliases() {
return alias;
}
/**
* Called when the command is executed
*
* @param args The arguments (excluding prefix and command name) specified
*/
public abstract void runCommand(String[] args);
}

View file

@ -1,49 +0,0 @@
package me.x150.sipprivate.command;
import me.x150.sipprivate.command.commands.BindCommand;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CommandManager {
/**
* A list of all registered commands
*/
private final List<Command> commands = new ArrayList<>();
/**
* Constructs a new command manager
*/
public CommandManager() {
addCommands();
}
/**
* Registers the commands
*/
public void addCommands() {
addCommand(new BindCommand());
}
/**
* Adds a command to the list of registered commands, registering it
*
* @param command The command instance
*/
private void addCommand(Command command) {
commands.add(command);
}
/**
* Gets all registered commands
*
* @return The list of registered commands
*/
@NotNull public List<Command> getCommands() {
return Collections.unmodifiableList(commands);
}
}

View file

@ -1,38 +0,0 @@
package me.x150.sipprivate.command.commands;
import me.x150.sipprivate.command.Command;
import me.x150.sipprivate.keybinding.KeybindingManager;
import me.x150.sipprivate.module.Module;
import me.x150.sipprivate.module.ModuleManager;
import me.x150.sipprivate.util.ChatUtil;
public class BindCommand extends Command {
public BindCommand() {
super("BindCommand", "bind");
}
@Override public void runCommand(String[] args) {
if (args.length < 2) {
ChatUtil.send("I need the module and key to bind");
return;
}
String mod = args[0];
String key = args[1];
if (key.length() != 1) {
ChatUtil.send("One character as key allowed only");
return;
}
int kc = key.toUpperCase().charAt(0);
Module m = ModuleManager.instance().getModuleByName(mod);
if (m == null) {
ChatUtil.send("Cant find that module");
return;
}
ChatUtil.send("BIND " + m.getName() + " -> " + kc + " (" + ((char) kc) + ")");
//m.config.get("Keybind").setValue(kc);
m.keybind.setValue(kc);
KeybindingManager.reload();
}
}

View file

@ -0,0 +1,38 @@
/*
* This file is part of the atomic client distribution.
* Copyright (c) 2021-2021 0x150.
*/
package me.x150.sipprivate.feature.command;
public abstract class Command {
private final String name;
private final String description;
private final String[] aliases;
public Command(String n, String d, String... a) {
this.name = n;
this.description = d;
this.aliases = a;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String[] getAliases() {
return aliases;
}
public abstract void onExecute(String[] args);
public String[] getSuggestions(String fullCommand, String[] args) {
return new String[0];
}
}

View file

@ -0,0 +1,64 @@
/*
* This file is part of the atomic client distribution.
* Copyright (c) 2021-2021 0x150.
*/
package me.x150.sipprivate.feature.command;
import me.x150.sipprivate.feature.gui.AtomicConsoleScreen;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CommandRegistry {
private static final List<Command> commands = new ArrayList<>();
static {
// TODO: 18.12.21 add commands
}
public static void init() {
}
public static List<Command> getCommands() {
return commands;
}
public static void execute(String command) {
String[] spl = command.split(" +");
String cmd = spl[0].toLowerCase();
String[] args = Arrays.copyOfRange(spl, 1, spl.length);
Command c = CommandRegistry.getByAlias(cmd);
if (c == null) {
AtomicConsoleScreen.instance().log("Command \"" + cmd + "\" not found", AtomicConsoleScreen.ERROR);
} else {
AtomicConsoleScreen.instance().log("> " + command, AtomicConsoleScreen.CLIENT);
try {
c.onExecute(args);
} catch (Exception e) {
AtomicConsoleScreen.instance().log("Error while running command " + command, AtomicConsoleScreen.ERROR);
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
for (String s : sw.toString().split("\n")) {
AtomicConsoleScreen.instance().log(s, AtomicConsoleScreen.BACKGROUND);
}
}
}
}
public static Command getByAlias(String n) {
for (Command command : getCommands()) {
for (String alias : command.getAliases()) {
if (alias.equalsIgnoreCase(n)) {
return command;
}
}
}
return null;
}
}

View file

@ -0,0 +1,138 @@
package me.x150.sipprivate.feature.gui;
import imgui.ImVec2;
import imgui.flag.ImGuiCol;
import imgui.flag.ImGuiKey;
import imgui.flag.ImGuiStyleVar;
import imgui.flag.ImGuiWindowFlags;
import imgui.internal.ImGui;
import imgui.type.ImString;
import me.x150.sipprivate.feature.command.Command;
import me.x150.sipprivate.feature.command.CommandRegistry;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class AtomicConsoleScreen extends ImGuiProxyScreen {
public static final Color ERROR = new Color(214, 93, 62);
public static final Color SUCCESS = new Color(65, 217, 101);
public static final Color DEFAULT = Color.WHITE;
public static final Color CLIENT = new Color(61, 173, 217);
public static final Color BACKGROUND = new Color(80, 99, 107);
static AtomicConsoleScreen inst = null;
final List<LogEntry> logs = new ArrayList<>();
ImString current = new ImString();
boolean focusBefore = false;
private AtomicConsoleScreen() {
}
public static AtomicConsoleScreen instance() {
if (inst == null) {
inst = new AtomicConsoleScreen();
}
return inst;
}
public void log(String t, Color c) {
logs.add(new LogEntry(c.getRed() / 255f, c.getGreen() / 255f, c.getBlue() / 255f, t));
}
@Override protected void renderInternal() {
current.inputData.isResizable = true;
ImGui.setNextWindowSizeConstraints(300, 200, 800, 500);
ImGui.begin("Console");
ImGui.pushItemWidth(-1);
if (ImGui.beginChild("ScrollRegion##", 0, -(ImGui.getStyle().getItemSpacingY() + ImGui.getFrameHeightWithSpacing()), false)) {
ImGui.pushTextWrapPos();
ImGui.pushStyleVar(ImGuiStyleVar.ItemSpacing, 4, 0);
for (LogEntry log : logs) {
ImGui.pushStyleColor(ImGuiCol.Text, log.r, log.g, log.b, 1f);
ImGui.textUnformatted(" " + log.text);
ImGui.popStyleColor();
}
ImGui.popStyleVar();
ImGui.popTextWrapPos();
if (ImGui.getScrollY() >= ImGui.getScrollMaxY()) {
ImGui.setScrollHereY(1f);
}
ImGui.endChild();
}
boolean reclaimFocus = false;
ImGui.inputText("", current);
if (focusBefore && !ImGui.isItemActive() && ImGui.isKeyPressed(ImGui.getIO().getKeyMap(ImGuiKey.Enter))) {
String command = current.get();
if (!command.isEmpty()) {
CommandRegistry.execute(command);
}
current.set("");
reclaimFocus = true;
}
focusBefore = ImGui.isItemActive();
ImGui.popItemWidth();
if (reclaimFocus) {
ImGui.setKeyboardFocusHere(-1);
}
String cmd = current.get();
if (!cmd.isEmpty() && !getSuggestions(cmd).isEmpty()) {
List<String> s = getSuggestions(cmd);
ImVec2 c = ImGui.getWindowPos();
c.y += ImGui.getWindowHeight() + ImGui.getStyle().getWindowPaddingY();
ImGui.setNextWindowSizeConstraints(0, 0, 200, 170);
ImGui.begin("cmdSuggestions", ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoFocusOnAppearing);
ImGui.setWindowPos(c.x, c.y);
for (String suggestion : s) {
ImGui.text(suggestion);
}
ImGui.end();
}
ImGui.end();
}
List<String> getSuggestions(String command) {
List<String> a = new ArrayList<>();
String[] args = command.split(" +");
String cmd = args[0].toLowerCase();
args = Arrays.copyOfRange(args, 1, args.length);
if (command.endsWith(" ")) { // append empty arg when we end with a space
String[] args1 = new String[args.length + 1];
System.arraycopy(args, 0, args1, 0, args.length);
args1[args1.length - 1] = "";
args = args1;
}
if (args.length > 0) {
Command c = CommandRegistry.getByAlias(cmd);
if (c != null) {
a = List.of(c.getSuggestions(command, args));
} else {
return new ArrayList<>(); // we have no command to ask -> we have no suggestions
}
} else {
for (Command command1 : CommandRegistry.getCommands()) {
for (String alias : command1.getAliases()) {
if (alias.toLowerCase().startsWith(cmd.toLowerCase())) {
a.add(alias);
}
}
}
}
String[] finalArgs = args;
return finalArgs.length > 0 ? a.stream().filter(s -> s.toLowerCase().startsWith(finalArgs[finalArgs.length - 1].toLowerCase())).collect(Collectors.toList()) : a;
}
@Override public boolean isPauseScreen() {
return false;
}
record LogEntry(float r, float g, float b, String text) {
}
}

View file

@ -0,0 +1,59 @@
package me.x150.sipprivate.feature.gui;
import imgui.ImGui;
import me.x150.sipprivate.SipoverPrivate;
import me.x150.sipprivate.helper.ImGuiManager;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
public abstract class ImGuiProxyScreen extends Screen {
public static boolean imguiDebugWindow = false;
boolean closed = false;
boolean closedAck = false;
public ImGuiProxyScreen() {
super(Text.of(""));
ImGuiManager.init();
}
protected abstract void renderInternal();
@Override protected void init() {
closed = closedAck = false;
}
@Override public void onClose() {
closed = true;
// super.onClose();
}
@Override public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
if (closed && closedAck) {
super.onClose();
return;
}
// sets the size of the window in case it got resized
ImGui.getIO().setDisplaySize(SipoverPrivate.client.getWindow().getWidth(), SipoverPrivate.client.getWindow().getHeight());
// new frame
ImGuiManager.getImplGlfw().newFrame();
ImGui.newFrame();
if (!closed) { // render empty frame when closed
if (imguiDebugWindow) {
ImGui.showMetricsWindow(); // show debug window on all imgui screens if we wish to
}
renderInternal(); // pass it to homeboy
} else {
closedAck = true;
}
// end the frame
ImGui.endFrame();
// draw
ImGui.render();
ImGuiManager.getImplGl3().renderDrawData(ImGui.getDrawData());
}
}

View file

@ -0,0 +1,84 @@
/*
* This file is part of the atomic client distribution.
* Copyright (c) 2021-2021 0x150.
*/
package me.x150.sipprivate.feature.module;
import me.x150.sipprivate.config.BooleanSetting;
import me.x150.sipprivate.config.IntSetting;
import me.x150.sipprivate.config.ModuleConfig;
import net.minecraft.client.util.math.MatrixStack;
public abstract class Module {
public final ModuleConfig config;
public final IntSetting keybind;
private final String name;
private final String description;
private final ModuleType moduleType;
private final BooleanSetting toasts;
private boolean enabled = false;
public Module(String n, String d, ModuleType type) {
this.name = n;
this.description = d;
this.moduleType = type;
this.config = new ModuleConfig();
this.keybind = this.config.create(new IntSetting.Builder(-1).name("Keybind").description("The keybind to toggle the module with").min(-1).get());
this.toasts = this.config.create(new BooleanSetting.Builder(true).name("Toasts").description("Whether to show enabled / disabled toasts").get());
}
public ModuleType getModuleType() {
return moduleType;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public abstract void tick();
public abstract void enable();
public abstract void disable();
public abstract String getContext();
public abstract void onWorldRender(MatrixStack matrices);
public abstract void onHudRender();
public void onFastTick() {
}
public void onFastTick_NWC() {
}
public void toggle() {
setEnabled(!enabled);
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
if (toasts.getValue()) {
// Notification.create(1000, "Module toggle", (this.enabled ? "§aEn" : "§cDis") + "abled §r" + this.getName());
}
if (this.enabled) {
this.enable();
} else {
this.disable();
}
}
}

View file

@ -0,0 +1,51 @@
/*
* This file is part of the atomic client distribution.
* Copyright (c) 2021-2021 0x150.
*/
package me.x150.sipprivate.feature.module;
import java.util.ArrayList;
import java.util.List;
public class ModuleRegistry {
static final List<Module> modules = new ArrayList<>();
static boolean initialized = false;
public static void init() {
initialized = true;
// TODO: 18.12.21 add modules
}
public static List<Module> getModules() {
if (!initialized) {
init();
}
return modules;
}
@SuppressWarnings("unchecked") public static <T extends Module> T getByClass(Class<T> clazz) {
if (!initialized) {
init();
}
for (Module module : getModules()) {
if (module.getClass() == clazz) {
return (T) module;
}
}
throw new IllegalStateException("Unregistered module: " + clazz.getName());
}
public static Module getByName(String n) {
if (!initialized) {
init();
}
for (Module module : getModules()) {
if (module.getName().equalsIgnoreCase(n)) {
return module;
}
}
return null;
}
}

View file

@ -0,0 +1,21 @@
/*
* This file is part of the atomic client distribution.
* Copyright (c) 2021-2021 0x150.
*/
package me.x150.sipprivate.feature.module;
public enum ModuleType {
RENDER("Render"), MOVEMENT("Movement"), MISC("Miscellaneous"), CLIENT("Client"), COMBAT("Combat"), WORLD("World"), EXPLOIT("Exploit"), HIDDEN(""), FUN("Fun");
final String name;
ModuleType(String n) {
this.name = n;
}
public String getName() {
return name;
}
}

View file

@ -0,0 +1,139 @@
package me.x150.sipprivate.helper;
import imgui.ImGui;
import imgui.flag.ImGuiCol;
import imgui.gl3.ImGuiImplGl3;
import imgui.glfw.ImGuiImplGlfw;
import me.x150.sipprivate.SipoverPrivate;
import me.x150.sipprivate.feature.gui.ImGuiProxyScreen;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class ImGuiManager {
protected static final ImGuiImplGlfw implGlfw = new ImGuiImplGlfw();
protected static final ImGuiImplGl3 implGl3 = new ImGuiImplGl3();
private static boolean init = false;
public static boolean isInitialized() {
return init;
}
public static ImGuiImplGl3 getImplGl3() {
return implGl3;
}
public static ImGuiImplGlfw getImplGlfw() {
return implGlfw;
}
private static byte[] getMainFont() {
try {
return Files.readAllBytes(Paths.get(ImGuiProxyScreen.class.getClassLoader().getResource("Font.ttf").toURI()));
} catch (IOException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
public static void style() {
// ImGui.getStyle().setWindowRounding(6f);
ImGui.getStyle().setWindowPadding(8, 8);
ImGui.getStyle().setFramePadding(4, 4);
ImGui.getStyle().setCellPadding(4, 2);
ImGui.getStyle().setItemSpacing(8, 4);
ImGui.getStyle().setItemInnerSpacing(4, 4);
ImGui.getStyle().setTouchExtraPadding(0, 0);
ImGui.getStyle().setIndentSpacing(21);
ImGui.getStyle().setScrollbarSize(10);
ImGui.getStyle().setGrabMinSize(4);
ImGui.getStyle().setWindowRounding(6);
ImGui.getStyle().setChildRounding(6);
ImGui.getStyle().setFrameRounding(6);
ImGui.getStyle().setPopupRounding(6);
ImGui.getStyle().setScrollbarRounding(6);
ImGui.getStyle().setGrabRounding(6);
ImGui.getStyle().setLogSliderDeadzone(4);
ImGui.getStyle().setTabRounding(4);
ImGui.getStyle().setColor(ImGuiCol.Text, 1.00f, 1.00f, 1.00f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.TextDisabled, 0.50f, 0.50f, 0.50f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.WindowBg, 0.07f, 0.10f, 0.10f, 0.94f);
ImGui.getStyle().setColor(ImGuiCol.ChildBg, 0.09f, 0.11f, 0.12f, 0.94f);
ImGui.getStyle().setColor(ImGuiCol.PopupBg, 0.05f, 0.07f, 0.08f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.Border, 0.20f, 0.50f, 0.35f, 0.50f);
ImGui.getStyle().setColor(ImGuiCol.BorderShadow, 0.00f, 0.00f, 0.00f, 0.00f);
ImGui.getStyle().setColor(ImGuiCol.FrameBg, 0.09f, 0.13f, 0.15f, 0.94f);
ImGui.getStyle().setColor(ImGuiCol.FrameBgHovered, 0.12f, 0.18f, 0.20f, 0.94f);
ImGui.getStyle().setColor(ImGuiCol.FrameBgActive, 0.17f, 0.23f, 0.26f, 0.94f);
ImGui.getStyle().setColor(ImGuiCol.TitleBg, 0.06f, 0.10f, 0.12f, 0.94f);
ImGui.getStyle().setColor(ImGuiCol.TitleBgActive, 0.09f, 0.15f, 0.16f, 0.94f);
ImGui.getStyle().setColor(ImGuiCol.TitleBgCollapsed, 0.03f, 0.05f, 0.06f, 0.94f);
ImGui.getStyle().setColor(ImGuiCol.MenuBarBg, 0.14f, 0.14f, 0.14f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.ScrollbarBg, 0.07f, 0.12f, 0.13f, 0.94f);
ImGui.getStyle().setColor(ImGuiCol.ScrollbarGrab, 0.20f, 0.50f, 0.35f, 0.50f);
ImGui.getStyle().setColor(ImGuiCol.ScrollbarGrabHovered, 0.28f, 0.54f, 0.41f, 0.50f);
ImGui.getStyle().setColor(ImGuiCol.ScrollbarGrabActive, 0.20f, 0.50f, 0.28f, 0.50f);
ImGui.getStyle().setColor(ImGuiCol.CheckMark, 0.26f, 0.59f, 0.98f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.SliderGrab, 0.24f, 0.52f, 0.88f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.SliderGrabActive, 0.26f, 0.59f, 0.98f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.Button, 0.10f, 0.23f, 0.24f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.ButtonHovered, 0.12f, 0.30f, 0.31f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.ButtonActive, 0.13f, 0.27f, 0.24f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.Header, 0.15f, 0.22f, 0.31f, 0.31f);
ImGui.getStyle().setColor(ImGuiCol.HeaderHovered, 0.16f, 0.28f, 0.41f, 0.31f);
ImGui.getStyle().setColor(ImGuiCol.HeaderActive, 0.25f, 0.35f, 0.47f, 0.31f);
ImGui.getStyle().setColor(ImGuiCol.Separator, 0.43f, 0.43f, 0.50f, 0.50f);
ImGui.getStyle().setColor(ImGuiCol.SeparatorHovered, 0.10f, 0.40f, 0.75f, 0.78f);
ImGui.getStyle().setColor(ImGuiCol.SeparatorActive, 0.10f, 0.40f, 0.75f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.ResizeGrip, 0.16f, 0.32f, 0.35f, 0.20f);
ImGui.getStyle().setColor(ImGuiCol.ResizeGripHovered, 0.13f, 0.34f, 0.39f, 0.20f);
ImGui.getStyle().setColor(ImGuiCol.ResizeGripActive, 0.16f, 0.35f, 0.33f, 0.20f);
ImGui.getStyle().setColor(ImGuiCol.Tab, 0.10f, 0.19f, 0.20f, 0.86f);
ImGui.getStyle().setColor(ImGuiCol.TabHovered, 0.12f, 0.25f, 0.26f, 0.86f);
ImGui.getStyle().setColor(ImGuiCol.TabActive, 0.12f, 0.26f, 0.24f, 0.86f);
ImGui.getStyle().setColor(ImGuiCol.TabUnfocused, 0.07f, 0.10f, 0.15f, 0.97f);
ImGui.getStyle().setColor(ImGuiCol.TabUnfocusedActive, 0.14f, 0.26f, 0.42f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.DockingPreview, 0.26f, 0.59f, 0.98f, 0.70f);
ImGui.getStyle().setColor(ImGuiCol.DockingEmptyBg, 0.15f, 0.18f, 0.19f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.PlotLines, 0.61f, 0.85f, 0.80f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.PlotLinesHovered, 1.00f, 0.43f, 0.35f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.PlotHistogram, 0.90f, 0.70f, 0.00f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.PlotHistogramHovered, 1.00f, 0.60f, 0.00f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.TableHeaderBg, 0.19f, 0.19f, 0.20f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.TableBorderStrong, 0.31f, 0.31f, 0.35f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.TableBorderLight, 0.23f, 0.23f, 0.25f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.TableRowBg, 0.00f, 0.00f, 0.00f, 0.00f);
ImGui.getStyle().setColor(ImGuiCol.TableRowBgAlt, 1.00f, 1.00f, 1.00f, 0.06f);
ImGui.getStyle().setColor(ImGuiCol.TextSelectedBg, 0.26f, 0.98f, 0.61f, 0.35f);
ImGui.getStyle().setColor(ImGuiCol.DragDropTarget, 1.00f, 1.00f, 0.00f, 0.90f);
ImGui.getStyle().setColor(ImGuiCol.NavHighlight, 0.26f, 0.59f, 0.98f, 1.00f);
ImGui.getStyle().setColor(ImGuiCol.NavWindowingHighlight, 1.00f, 1.00f, 1.00f, 0.70f);
ImGui.getStyle().setColor(ImGuiCol.NavWindowingDimBg, 0.80f, 0.80f, 0.80f, 0.20f);
ImGui.getStyle().setColor(ImGuiCol.ModalWindowDimBg, 0.80f, 0.80f, 0.80f, 0.35f);
}
public static void init() {
if (init) {
return;
}
init = true;
long win = SipoverPrivate.client.getWindow().getHandle();
ImGui.createContext();
initFonts();
style();
implGlfw.init(win, true);
implGl3.init();
ImGui.getIO().setConfigWindowsMoveFromTitleBarOnly(true);
// ImGui.getIO().addConfigFlags(ImGuiConfigFlags.ViewportsEnable);
ImGui.getStyle().setWindowMenuButtonPosition(-1);
}
public static void initFonts() {
ImGui.getIO().getFonts().addFontFromMemoryTTF(getMainFont(), 18);
}
}

View file

@ -0,0 +1,56 @@
package me.x150.sipprivate.helper.font;
import me.x150.sipprivate.helper.font.adapter.FontAdapter;
import me.x150.sipprivate.helper.font.adapter.impl.ClientFontRenderer;
import me.x150.sipprivate.helper.font.render.GlyphPageFontRenderer;
import java.util.ArrayList;
import java.util.List;
public class FontRenderers {
private static final List<ClientFontRenderer> fontRenderers = new ArrayList<>();
private static FontAdapter normal, title, mono, vanilla;
public static FontAdapter getNormal() {
return normal;
}
public static void setNormal(FontAdapter normal) {
FontRenderers.normal = normal;
}
public static ClientFontRenderer getCustomNormal(int size) {
for (ClientFontRenderer fontRenderer : fontRenderers) {
if (fontRenderer.getSize() == size) {
return fontRenderer;
}
}
ClientFontRenderer cfr = new ClientFontRenderer(GlyphPageFontRenderer.createFromID("Font.ttf", size, false, false, false));
fontRenderers.add(cfr);
return cfr;
}
public static FontAdapter getMono() {
return mono;
}
public static void setMono(FontAdapter mono) {
FontRenderers.mono = mono;
}
public static FontAdapter getTitle() {
return title;
}
public static void setTitle(FontAdapter title) {
FontRenderers.title = title;
}
public static FontAdapter getVanilla() {
return vanilla;
}
public static void setVanilla(FontAdapter vanilla) {
FontRenderers.vanilla = vanilla;
}
}

View file

@ -0,0 +1,19 @@
package me.x150.sipprivate.helper.font.adapter;
import net.minecraft.client.util.math.MatrixStack;
public interface FontAdapter {
int drawString(MatrixStack matrices, String text, float x, float y, int color);
int drawString(MatrixStack matrices, String text, double x, double y, int color);
int drawCenteredString(MatrixStack matrices, String text, double x, double y, int color);
float getStringWidth(String text);
float getFontHeight();
float getMarginHeight();
void drawString(MatrixStack matrices, String s, float x, float y, int color, boolean dropShadow);
}

View file

@ -0,0 +1,45 @@
package me.x150.sipprivate.helper.font.adapter.impl;
import me.x150.sipprivate.helper.font.adapter.FontAdapter;
import me.x150.sipprivate.helper.font.render.GlyphPageFontRenderer;
import net.minecraft.client.util.math.MatrixStack;
public class ClientFontRenderer implements FontAdapter {
final GlyphPageFontRenderer renderer;
public ClientFontRenderer(GlyphPageFontRenderer gpfr) {
this.renderer = gpfr;
}
@Override public int drawString(MatrixStack matrices, String text, float x, float y, int color) {
return renderer.drawString(matrices, text, x, y, color);
}
@Override public int drawString(MatrixStack matrices, String text, double x, double y, int color) {
return renderer.drawString(matrices, text, x, y, color);
}
@Override public int drawCenteredString(MatrixStack matrices, String text, double x, double y, int color) {
return renderer.drawCenteredString(matrices, text, x, y, color);
}
@Override public float getStringWidth(String text) {
return renderer.getStringWidth(text);
}
@Override public float getFontHeight() {
return renderer.getFontHeight();
}
@Override public float getMarginHeight() {
return getFontHeight();
}
@Override public void drawString(MatrixStack matrices, String s, float x, float y, int color, boolean dropShadow) {
renderer.drawString(matrices, s, x, y, color, dropShadow);
}
public int getSize() {
return renderer.size;
}
}

View file

@ -0,0 +1,35 @@
package me.x150.sipprivate.helper.font.adapter.impl;
import me.x150.sipprivate.SipoverPrivate;
import me.x150.sipprivate.helper.font.adapter.FontAdapter;
import net.minecraft.client.util.math.MatrixStack;
public class VanillaFontRenderer implements FontAdapter {
@Override public int drawString(MatrixStack matrices, String text, float x, float y, int color) {
return SipoverPrivate.client.textRenderer.draw(matrices, text, x, y, color);
}
@Override public int drawString(MatrixStack matrices, String text, double x, double y, int color) {
return SipoverPrivate.client.textRenderer.draw(matrices, text, (float) x, (float) y, color);
}
@Override public int drawCenteredString(MatrixStack matrices, String text, double x, double y, int color) {
return drawString(matrices, text, x - getStringWidth(text) / 2d, y, color);
}
@Override public float getStringWidth(String text) {
return SipoverPrivate.client.textRenderer.getWidth(text);
}
@Override public float getFontHeight() {
return 8;
}
@Override public float getMarginHeight() {
return 9;
}
@Override public void drawString(MatrixStack matrices, String s, float x, float y, int color, boolean dropShadow) {
drawString(matrices, s, x, y, color);
}
}

View file

@ -0,0 +1,227 @@
package me.x150.sipprivate.helper.font.render;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.texture.AbstractTexture;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.client.util.math.MatrixStack;
import org.lwjgl.BufferUtils;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.HashMap;
public class GlyphPage {
private final Font font;
private final boolean antiAliasing;
private final boolean fractionalMetrics;
private final HashMap<Character, Glyph> glyphCharacterMap = new HashMap<>();
private int imgSize;
private int maxFontHeight = -1;
private BufferedImage bufferedImage;
private AbstractTexture loadedTexture;
public GlyphPage(Font font, boolean antiAliasing, boolean fractionalMetrics) {
this.font = font;
this.antiAliasing = antiAliasing;
this.fractionalMetrics = fractionalMetrics;
}
public void generateGlyphPage(char[] chars) {
// Calculate glyphPageSize
double maxWidth = -1;
double maxHeight = -1;
AffineTransform affineTransform = new AffineTransform();
FontRenderContext fontRenderContext = new FontRenderContext(affineTransform, antiAliasing, fractionalMetrics);
for (char ch : chars) {
Rectangle2D bounds = font.getStringBounds(Character.toString(ch), fontRenderContext);
if (maxWidth < bounds.getWidth()) {
maxWidth = bounds.getWidth();
}
if (maxHeight < bounds.getHeight()) {
maxHeight = bounds.getHeight();
}
}
// Leave some additional space
maxWidth += 2;
maxHeight += 2;
imgSize = (int) Math.ceil(Math.max(Math.ceil(Math.sqrt(maxWidth * maxWidth * chars.length) / maxWidth), Math.ceil(Math.sqrt(maxHeight * maxHeight * chars.length) / maxHeight)) * Math.max(maxWidth, maxHeight)) + 1;
bufferedImage = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bufferedImage.createGraphics();
g.setFont(font);
// Set Color to Transparent
g.setColor(new Color(255, 255, 255, 0));
// Set the image background to transparent
g.fillRect(0, 0, imgSize, imgSize);
g.setColor(Color.white);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, fractionalMetrics ? RenderingHints.VALUE_FRACTIONALMETRICS_ON : RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antiAliasing ? RenderingHints.VALUE_ANTIALIAS_OFF : RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, antiAliasing ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
FontMetrics fontMetrics = g.getFontMetrics();
int currentCharHeight = 0;
int posX = 0;
int posY = 1;
for (char ch : chars) {
Glyph glyph = new Glyph();
Rectangle2D bounds = fontMetrics.getStringBounds(Character.toString(ch), g);
glyph.width = bounds.getBounds().width + 8; // Leave some additional space
glyph.height = bounds.getBounds().height;
if (posX + glyph.width >= imgSize) {
posX = 0;
posY += currentCharHeight;
currentCharHeight = 0;
}
glyph.x = posX;
glyph.y = posY;
if (glyph.height > maxFontHeight) {
maxFontHeight = glyph.height;
}
if (glyph.height > currentCharHeight) {
currentCharHeight = glyph.height;
}
g.drawString(Character.toString(ch), posX + 2, posY + fontMetrics.getAscent());
posX += glyph.width;
glyphCharacterMap.put(ch, glyph);
}
}
public void setupTexture() {
try {
// Converting to ByteBuffer
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "png", baos);
byte[] bytes = baos.toByteArray();
ByteBuffer data = BufferUtils.createByteBuffer(bytes.length).put(bytes);
data.flip();
loadedTexture = new NativeImageBackedTexture(NativeImage.read(data));
} catch (Exception e) {
e.printStackTrace();
}
}
public void bindTexture() {
RenderSystem.setShaderTexture(0, loadedTexture.getGlId());
}
public void unbindTexture() {
RenderSystem.setShaderTexture(0, 0);
}
public float drawChar(MatrixStack stack, char ch, float x, float y, float red, float blue, float green, float alpha) {
Glyph glyph = glyphCharacterMap.get(ch);
if (glyph == null) {
return 0;
}
float pageX = glyph.x / (float) imgSize;
float pageY = glyph.y / (float) imgSize;
float pageWidth = glyph.width / (float) imgSize;
float pageHeight = glyph.height / (float) imgSize;
float width = glyph.width;
float height = glyph.height;
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
RenderSystem.setShader(GameRenderer::getPositionColorTexShader);
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE);
bufferBuilder.vertex(stack.peek().getPositionMatrix(), x, y + height, 0).color(red, green, blue, alpha).texture(pageX, pageY + pageHeight).next();
bufferBuilder.vertex(stack.peek().getPositionMatrix(), x + width, y + height, 0).color(red, green, blue, alpha).texture(pageX + pageWidth, pageY + pageHeight).next();
bufferBuilder.vertex(stack.peek().getPositionMatrix(), x + width, y, 0).color(red, green, blue, alpha).texture(pageX + pageWidth, pageY).next();
bufferBuilder.vertex(stack.peek().getPositionMatrix(), x, y, 0).color(red, green, blue, alpha).texture(pageX, pageY).next();
bufferBuilder.end();
BufferRenderer.draw(bufferBuilder);
return width - 8;
}
public float getWidth(char ch) {
Glyph g = glyphCharacterMap.get(ch);
return g == null ? 0 : g.width;
}
public int getMaxFontHeight() {
return maxFontHeight;
}
public boolean isAntiAliasingEnabled() {
return antiAliasing;
}
public boolean isFractionalMetricsEnabled() {
return fractionalMetrics;
}
static class Glyph {
private int x;
private int y;
private int width;
private int height;
Glyph() {
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
}

View file

@ -0,0 +1,528 @@
package me.x150.sipprivate.helper.font.render;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack;
import java.awt.Font;
import java.io.InputStream;
import java.util.Objects;
import static org.lwjgl.opengl.GL11.GL_LINEAR;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
public class GlyphPageFontRenderer {
/**
* Array of RGB triplets defining the 16 standard chat colors followed by 16 darker version of the same colors for drop shadows.
*/
private final int[] colorCode = new int[32];
private final GlyphPage regularGlyphPage;
private final GlyphPage boldGlyphPage;
private final GlyphPage italicGlyphPage;
private final GlyphPage boldItalicGlyphPage;
public int size = -1;
/**
* Current X coordinate at which to draw the next character.
*/
private float posX;
/**
* Current Y coordinate at which to draw the next character.
*/
private float posY;
/**
* Set if the "l" style (bold) is active in currently rendering string
*/
private boolean boldStyle;
/**
* Set if the "o" style (italic) is active in currently rendering string
*/
private boolean italicStyle;
/**
* Set if the "n" style (underlined) is active in currently rendering string
*/
private boolean underlineStyle;
/**
* Set if the "m" style (strikethrough) is active in currently rendering string
*/
private boolean strikethroughStyle;
public GlyphPageFontRenderer(GlyphPage regularGlyphPage, GlyphPage boldGlyphPage, GlyphPage italicGlyphPage, GlyphPage boldItalicGlyphPage) {
this.regularGlyphPage = regularGlyphPage;
this.boldGlyphPage = boldGlyphPage;
this.italicGlyphPage = italicGlyphPage;
this.boldItalicGlyphPage = boldItalicGlyphPage;
for (int i = 0; i < 32; ++i) {
int j = (i >> 3 & 1) * 85;
int k = (i >> 2 & 1) * 170 + j;
int l = (i >> 1 & 1) * 170 + j;
int i1 = (i & 1) * 170 + j;
if (i == 6) {
k += 85;
}
if (i >= 16) {
k /= 4;
l /= 4;
i1 /= 4;
}
this.colorCode[i] = (k & 255) << 16 | (l & 255) << 8 | i1 & 255;
}
}
public static GlyphPageFontRenderer create(String fontName, int size, boolean bold, boolean italic, boolean boldItalic) {
char[] chars = new char[256];
for (int i = 0; i < chars.length; i++) {
chars[i] = (char) i;
}
GlyphPage regularPage;
regularPage = new GlyphPage(new Font(fontName, Font.PLAIN, size), true, true);
regularPage.generateGlyphPage(chars);
regularPage.setupTexture();
GlyphPage boldPage = regularPage;
GlyphPage italicPage = regularPage;
GlyphPage boldItalicPage = regularPage;
if (bold) {
boldPage = new GlyphPage(new Font(fontName, Font.BOLD, size), true, true);
boldPage.generateGlyphPage(chars);
boldPage.setupTexture();
}
if (italic) {
italicPage = new GlyphPage(new Font(fontName, Font.ITALIC, size), true, true);
italicPage.generateGlyphPage(chars);
italicPage.setupTexture();
}
if (boldItalic) {
boldItalicPage = new GlyphPage(new Font(fontName, Font.BOLD | Font.ITALIC, size), true, true);
boldItalicPage.generateGlyphPage(chars);
boldItalicPage.setupTexture();
}
GlyphPageFontRenderer gpfr = new GlyphPageFontRenderer(regularPage, boldPage, italicPage, boldItalicPage);
gpfr.size = size;
return gpfr;
}
public static GlyphPageFontRenderer createFromStream(InputStream inp, int size, boolean bold, boolean italic, boolean boldItalic) {
char[] chars = new char[256];
for (int i = 0; i < chars.length; i++) {
chars[i] = (char) i;
}
Font font = null;
try {
font = Font.createFont(Font.TRUETYPE_FONT, inp).deriveFont(Font.PLAIN, size);
} catch (Exception e) {
e.printStackTrace();
}
GlyphPage regularPage;
regularPage = new GlyphPage(font, true, true);
regularPage.generateGlyphPage(chars);
regularPage.setupTexture();
GlyphPage boldPage = regularPage;
GlyphPage italicPage = regularPage;
GlyphPage boldItalicPage = regularPage;
try {
if (bold) {
boldPage = new GlyphPage(Font.createFont(Font.TRUETYPE_FONT, inp).deriveFont(Font.BOLD, size), true, true);
boldPage.generateGlyphPage(chars);
boldPage.setupTexture();
}
if (italic) {
italicPage = new GlyphPage(Font.createFont(Font.TRUETYPE_FONT, inp).deriveFont(Font.ITALIC, size), true, true);
italicPage.generateGlyphPage(chars);
italicPage.setupTexture();
}
if (boldItalic) {
boldItalicPage = new GlyphPage(Font.createFont(Font.TRUETYPE_FONT, inp).deriveFont(Font.BOLD | Font.ITALIC, size), true, true);
boldItalicPage.generateGlyphPage(chars);
boldItalicPage.setupTexture();
}
} catch (Exception e) {
e.printStackTrace();
}
return new GlyphPageFontRenderer(regularPage, boldPage, italicPage, boldItalicPage);
}
public static GlyphPageFontRenderer createFromID(String id, int size, boolean bold, boolean italic, boolean boldItalic) {
char[] chars = new char[256];
for (int i = 0; i < chars.length; i++) {
chars[i] = (char) i;
}
Font font = null;
try {
font = Font.createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(GlyphPageFontRenderer.class.getClassLoader().getResourceAsStream(id))).deriveFont(Font.PLAIN, size);
} catch (Exception e) {
e.printStackTrace();
}
GlyphPage regularPage;
regularPage = new GlyphPage(font, true, true);
regularPage.generateGlyphPage(chars);
regularPage.setupTexture();
GlyphPage boldPage = regularPage;
GlyphPage italicPage = regularPage;
GlyphPage boldItalicPage = regularPage;
try {
if (bold) {
boldPage = new GlyphPage(Font.createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(GlyphPageFontRenderer.class.getClassLoader().getResourceAsStream(id)))
.deriveFont(Font.BOLD, size), true, true);
boldPage.generateGlyphPage(chars);
boldPage.setupTexture();
}
if (italic) {
italicPage = new GlyphPage(Font.createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(GlyphPageFontRenderer.class.getClassLoader().getResourceAsStream(id)))
.deriveFont(Font.ITALIC, size), true, true);
italicPage.generateGlyphPage(chars);
italicPage.setupTexture();
}
if (boldItalic) {
boldItalicPage = new GlyphPage(Font.createFont(Font.TRUETYPE_FONT, Objects.requireNonNull(GlyphPageFontRenderer.class.getClassLoader().getResourceAsStream(id)))
.deriveFont(Font.BOLD | Font.ITALIC, size), true, true);
boldItalicPage.generateGlyphPage(chars);
boldItalicPage.setupTexture();
}
} catch (Exception e) {
e.printStackTrace();
}
GlyphPageFontRenderer gp = new GlyphPageFontRenderer(regularPage, boldPage, italicPage, boldItalicPage);
gp.size = size;
return gp;
}
public int drawString(MatrixStack matrices, String text, float x, float y, int color) {
return drawString(matrices, text, x, y, color, true);
}
public int drawString(MatrixStack matrices, String text, double x, double y, int color) {
return drawString(matrices, text, (float) x, (float) y, color, true);
}
public int drawCenteredString(MatrixStack matrices, String text, double x, double y, int color) {
return drawString(matrices, text, (float) x - getStringWidth(text) / 2f, (float) y, color, true);
}
/**
* Draws the specified string.
*/
public int drawString(MatrixStack matrices, String text, float x, float y, int color, boolean dropShadow) {
this.resetStyles();
int i;
if (dropShadow) {
i = this.renderString(matrices, text, x + .5F, y + .5F, color, true);
i = Math.max(i, this.renderString(matrices, text, x, y, color, false));
} else {
i = this.renderString(matrices, text, x, y, color, false);
}
return i;
}
/**
* Render single line string by setting GL color, current (posX,posY), and calling renderStringAtPos()
*/
private int renderString(MatrixStack matrices, String text, float x, float y, int color, boolean dropShadow) {
if (text == null) {
return 0;
} else {
if ((color & 0xfc000000) == 0) {
color |= 0xff000000;
}
if (dropShadow) {
color = 0xFF323232;
}
this.posX = x * 2.0f;
this.posY = y * 2.0f;
this.renderStringAtPos(matrices, text, dropShadow, color);
return (int) (this.posX / 4.0f);
}
}
/**
* Render a single line string at the current (posX,posY) and update posX
*/
private void renderStringAtPos(MatrixStack matrices, String text, boolean shadow, int color) {
GlyphPage glyphPage = getCurrentGlyphPage();
float alpha = (float) (color >> 24 & 255) / 255.0F;
float r = (float) (color >> 16 & 255) / 255.0F;
float g = (float) (color >> 8 & 255) / 255.0F;
float b = (float) (color & 255) / 255.0F;
matrices.push();
matrices.scale(0.5F, 0.5F, 0.5F);
RenderSystem.enableBlend();
RenderSystem.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
RenderSystem.enableTexture();
glyphPage.bindTexture();
GlStateManager._texParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
for (int i = 0; i < text.length(); ++i) {
char c0 = text.charAt(i);
if (c0 == '§' && i + 1 < text.length()) {
int i1 = "0123456789abcdefklmnor".indexOf(text.toLowerCase().charAt(i + 1));
if (i1 < 16) {
resetStyles();
if (i1 < 0) {
i1 = 15;
}
if (shadow) {
i1 += 16;
}
int j1 = this.colorCode[i1];
r = (float) (j1 >> 16 & 255) / 255.0F;
g = (float) (j1 >> 8 & 255) / 255.0F;
b = (float) (j1 & 255) / 255.0F;
} else if (i1 == 17) {
this.boldStyle = true;
} else if (i1 == 18) {
this.strikethroughStyle = true;
} else if (i1 == 19) {
this.underlineStyle = true;
} else if (i1 == 20) {
this.italicStyle = true;
} else if (i1 == 21) {
resetStyles();
alpha = (float) (color >> 24 & 255) / 255.0F;
r = (float) (color >> 16 & 255) / 255.0F;
g = (float) (color >> 8 & 255) / 255.0F;
b = (float) (color & 255) / 255.0F;
}
++i;
} else {
float f = glyphPage.drawChar(matrices, c0, posX, posY, r, b, g, alpha);
doDraw(f, glyphPage);
}
}
//glyphPage.unbindTexture();
matrices.pop();
}
private void doDraw(float f, GlyphPage glyphPage) {
BufferBuilder bufferBuilder = Tessellator.getInstance().getBuffer();
GlStateManager._disableTexture();
if (this.strikethroughStyle) {
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION);
bufferBuilder.vertex(this.posX, this.posY + (float) (glyphPage.getMaxFontHeight() / 2), 0.0D).next();
bufferBuilder.vertex(this.posX + f, this.posY + (float) (glyphPage.getMaxFontHeight() / 2), 0.0D).next();
bufferBuilder.vertex(this.posX + f, this.posY + (float) (glyphPage.getMaxFontHeight() / 2) - 1.0F, 0.0D).next();
bufferBuilder.vertex(this.posX, this.posY + (float) (glyphPage.getMaxFontHeight() / 2) - 1.0F, 0.0D).next();
bufferBuilder.end();
BufferRenderer.draw(bufferBuilder);
GlStateManager._enableTexture();
}
if (this.underlineStyle) {
bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION);
int l = this.underlineStyle ? -1 : 0;
bufferBuilder.vertex(this.posX + (float) l, this.posY + (float) glyphPage.getMaxFontHeight(), 0.0D).next();
bufferBuilder.vertex(this.posX + f, this.posY + (float) glyphPage.getMaxFontHeight(), 0.0D).next();
bufferBuilder.vertex(this.posX + f, this.posY + (float) glyphPage.getMaxFontHeight() - 1.0F, 0.0D).next();
bufferBuilder.vertex(this.posX + (float) l, this.posY + (float) glyphPage.getMaxFontHeight() - 1.0F, 0.0D).next();
bufferBuilder.end();
BufferRenderer.draw(bufferBuilder);
GlStateManager._enableTexture();
}
this.posX += f;
}
private GlyphPage getCurrentGlyphPage() {
if (boldStyle && italicStyle) {
return boldItalicGlyphPage;
} else if (boldStyle) {
return boldGlyphPage;
} else if (italicStyle) {
return italicGlyphPage;
} else {
return regularGlyphPage;
}
}
/**
* Reset all style flag fields in the class to false; called at the start of string rendering
*/
private void resetStyles() {
this.boldStyle = false;
this.italicStyle = false;
this.underlineStyle = false;
this.strikethroughStyle = false;
}
public int getFontHeight() {
return regularGlyphPage.getMaxFontHeight() / 2;
}
public int getStringWidth(String text) {
if (text == null) {
return 0;
}
int width = 0;
GlyphPage currentPage;
int size = text.length();
boolean on = false;
for (int i = 0; i < size; i++) {
char character = text.charAt(i);
if (character == '§') {
on = true;
} else if (on && character >= '0' && character <= 'r') {
int colorIndex = "0123456789abcdefklmnor".indexOf(character);
if (colorIndex < 16) {
boldStyle = false;
italicStyle = false;
} else if (colorIndex == 17) {
boldStyle = true;
} else if (colorIndex == 20) {
italicStyle = true;
} else if (colorIndex == 21) {
boldStyle = false;
italicStyle = false;
}
on = false;
} else {
on = false;
character = text.charAt(i);
currentPage = getCurrentGlyphPage();
width += currentPage.getWidth(character) - 8;
//i++;
}
}
return width / 2;
}
/**
* Trims a string to fit a specified Width.
*/
public String trimStringToWidth(String text, int width) {
return this.trimStringToWidth(text, width, false);
}
/**
* Trims a string to a specified width, and will reverse it if par3 is set.
*/
public String trimStringToWidth(String text, int maxWidth, boolean reverse) {
StringBuilder stringbuilder = new StringBuilder();
boolean on = false;
int j = reverse ? text.length() - 1 : 0;
int k = reverse ? -1 : 1;
int width = 0;
GlyphPage currentPage;
for (int i = j; i >= 0 && i < text.length() && i < maxWidth; i += k) {
char character = text.charAt(i);
if (character == '§') {
on = true;
} else if (on && character >= '0' && character <= 'r') {
int colorIndex = "0123456789abcdefklmnor".indexOf(character);
if (colorIndex < 16) {
boldStyle = false;
italicStyle = false;
} else if (colorIndex == 17) {
boldStyle = true;
} else if (colorIndex == 20) {
italicStyle = true;
} else if (colorIndex == 21) {
boldStyle = false;
italicStyle = false;
}
on = false;
} else {
if (on) {
i--; // include the §, because color code is invalid
}
character = text.charAt(i);
currentPage = getCurrentGlyphPage();
width += (currentPage.getWidth(character) - 8) / 2;
}
if (i > width) {
break;
}
if (reverse) {
stringbuilder.insert(0, character);
} else {
stringbuilder.append(character);
}
}
return stringbuilder.toString();
}
}

View file

@ -1,7 +1,7 @@
package me.x150.sipprivate.keybinding;
import me.x150.sipprivate.module.Module;
import me.x150.sipprivate.module.ModuleManager;
import me.x150.sipprivate.feature.module.Module;
import me.x150.sipprivate.feature.module.ModuleRegistry;
import java.util.HashMap;
import java.util.Map;
@ -20,7 +20,7 @@ public class KeybindingManager {
* Init the keybinding manager
*/
public static void init() {
for (Module module : ModuleManager.instance().getModules()) {
for (Module module : ModuleRegistry.getModules()) {
keybindMap.put(module, new Keybind(module.keybind.getValue()));
}
}

View file

@ -7,8 +7,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPlayerEntity.class)
public class ClientPlayerEntityMixin {
@Mixin(ClientPlayerEntity.class) public class ClientPlayerEntityMixin {
@Inject(method = "tick", at = @At("HEAD")) void tick(CallbackInfo ci) {
if (!ConfigManager.enabled) {
ConfigManager.enableModules();

View file

@ -0,0 +1,15 @@
package me.x150.sipprivate.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.util.Session;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(MinecraftClient.class) public interface IMinecraftClientAccessor {
@Mutable @Accessor("session") void setSession(Session newSession);
@Accessor("renderTickCounter") RenderTickCounter getRenderTickCounter();
}

View file

@ -0,0 +1,11 @@
package me.x150.sipprivate.mixin;
import net.minecraft.client.render.RenderTickCounter;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(RenderTickCounter.class) public interface IRenderTickCounterAccessor {
@Mutable @Accessor("tickTime") void setTickTime(float v);
}

View file

@ -8,8 +8,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Keyboard.class)
public class KeyboardMixin {
@Mixin(Keyboard.class) public class KeyboardMixin {
@Inject(method = "onKey", at = @At("RETURN")) void atomic_postKeyPressed(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) {
if (window == MinecraftClient.getInstance().getWindow()
.getHandle() && MinecraftClient.getInstance().currentScreen == null) { // make sure we are in game and the screen has been there for at least 10 ms

View file

@ -7,8 +7,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MinecraftClient.class)
public class MinecraftClientMixin {
@Mixin(MinecraftClient.class) public class MinecraftClientMixin {
@Inject(method = "stop", at = @At("HEAD")) void real(CallbackInfo ci) {
ConfigManager.saveState();
}

View file

@ -1,18 +0,0 @@
package me.x150.sipprivate.module;
/**
* Enum containing each category of module
*/
public enum Category {
COMBAT("Combat"), MOVEMENT("Movement"), RENDER("Render"), EXPLOIT("Exploit"), PLAYER("Player"), MISC("Miscellaneous");
String name;
Category(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

View file

@ -1,123 +0,0 @@
package me.x150.sipprivate.module;
import me.x150.sipprivate.config.IntSetting;
import me.x150.sipprivate.config.ModuleConfig;
import net.minecraft.client.MinecraftClient;
/**
* A container describing a module
*/
public abstract class Module {
/**
* The minecraft instance
*/
protected static final MinecraftClient mc = MinecraftClient.getInstance();
/**
* The configuration of this module
*/
public final ModuleConfig config;
/**
* The name of this module
*/
private final String name;
/**
* The description of this module
*/
private final String description;
/**
* The category this module belongs in
*/
private final Category category;
/**
* The keybind of this module
*/
public IntSetting keybind;
/**
* Whether this module is currently enabled
*/
private boolean enabled;
/**
* Constructs a new module
*
* @param name The name of the module
* @param description The description of this module
* @param category Which category this module belongs in
*/
public Module(String name, String description, Category category) {
this.name = name;
this.description = description;
this.category = category;
this.config = new ModuleConfig();
keybind = config.create(new IntSetting.Builder(-1).min(-1).name("Keybind").description("The keybind to toggle the module with").get());
// this.config.create("Keybind", -1).description("The keybind to toggle the module with");
}
/**
* Gets the name of this module
*
* @return This module's name
*/
public String getName() {
return name;
}
/**
* Gets the description of this module
*
* @return This module's description
*/
public String getDescription() {
return description;
}
/**
* Gets the category of this module
*
* @return This module's category
*/
public Category getCategory() {
return category;
}
/**
* Whether this module is enabled or not
*
* @return true if the module is enabled, false if otherwise
*/
public boolean isEnabled() {
return enabled;
}
/**
* Sets this module's enabled state
*
* @param enabled The new enabled state
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
if (this.enabled) {
onEnable();
} else {
onDisable();
}
}
/**
* Turns this module on if it's off, off when otherwise
*/
public void toggle() {
setEnabled(!isEnabled());
}
/**
* Gets called when the module switches from disabled to enabled, not implemented in base class
*/
protected abstract void onEnable();
/**
* Gets called when the module switches from enabled to disabled, not implemented in base class
*/
protected abstract void onDisable();
}

View file

@ -1,69 +0,0 @@
package me.x150.sipprivate.module;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* The module manager
*/
public class ModuleManager {
private static final ModuleManager instance = new ModuleManager();
/**
* A list of all registered modules
*/
private final List<Module> modules = new ArrayList<>();
private ModuleManager() {
addModules();
}
public static ModuleManager instance() {
return instance;
}
/**
* Adds all modules we want to register
*/
public void addModules() {
}
/**
* Registers a module
*
* @param module The module to register
*/
private void addModule(Module module) {
modules.add(module);
}
/**
* Returns all modules
*
* @return The modules
*/
@NotNull public List<Module> getModules() {
return Collections.unmodifiableList(modules);
}
/**
* Returns the first module which has the name we specified, null if no module matches
*
* @param name The name we want to find
* @return The module found, null otherwise
*/
@Nullable public Module getModuleByName(String name) {
for (Module m : modules) {
if (m.getName().equalsIgnoreCase(name)) {
return m;
}
}
return null;
}
}

View file

@ -6,9 +6,9 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.x150.sipprivate.SipoverPrivate;
import me.x150.sipprivate.config.SettingBase;
import me.x150.sipprivate.feature.module.Module;
import me.x150.sipprivate.feature.module.ModuleRegistry;
import me.x150.sipprivate.keybinding.KeybindingManager;
import me.x150.sipprivate.module.Module;
import me.x150.sipprivate.module.ModuleManager;
import org.apache.commons.io.FileUtils;
import javax.crypto.Cipher;
@ -116,7 +116,7 @@ public class ConfigManager {
JsonObject base = new JsonObject();
JsonArray enabled = new JsonArray();
JsonArray config = new JsonArray();
for (Module module : ModuleManager.instance().getModules()) {
for (Module module : ModuleRegistry.getModules()) {
if (module.isEnabled()) {
enabled.add(module.getName());
}
@ -169,7 +169,7 @@ public class ConfigManager {
if (jsonElement.isJsonObject()) {
JsonObject jobj = jsonElement.getAsJsonObject();
String name = jobj.get("name").getAsString();
Module j = ModuleManager.instance().getModuleByName(name);
Module j = ModuleRegistry.getByName(name);
if (j == null) {
continue;
}
@ -192,7 +192,7 @@ public class ConfigManager {
if (config.has("enabled") && config.get("enabled").isJsonArray()) {
for (JsonElement enabled : config.get("enabled").getAsJsonArray()) {
String name = enabled.getAsString();
Module m = ModuleManager.instance().getModuleByName(name);
Module m = ModuleRegistry.getByName(name);
if (m != null) {
toBeEnabled.add(m);
}

View file

@ -1,16 +1,322 @@
/*
* This file is part of the atomic client distribution.
* Copyright (c) 2021-2021 0x150.
*/
package me.x150.sipprivate.util;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.x150.sipprivate.SipoverPrivate;
import me.x150.sipprivate.feature.gui.AtomicConsoleScreen;
import me.x150.sipprivate.helper.font.adapter.FontAdapter;
import me.x150.sipprivate.mixin.IMinecraftClientAccessor;
import me.x150.sipprivate.mixin.IRenderTickCounterAccessor;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtDouble;
import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.StringNbtReader;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.text.Text;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext;
import net.minecraft.world.World;
import java.awt.Color;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
public class Utils {
/**
* Returns an RGB color based on time
*
* @return The color
*/
public static ServerInfo latestServerInfo;
public static void sleep(long ms) {
try {
Thread.sleep(ms);
} catch (Exception ignored) {
}
}
public static void setClientTps(float tps) {
IRenderTickCounterAccessor accessor = ((IRenderTickCounterAccessor) ((IMinecraftClientAccessor) SipoverPrivate.client).getRenderTickCounter());
accessor.setTickTime(1000f / tps);
}
public static Color getCurrentRGB() {
return new Color(Color.HSBtoRGB((System.currentTimeMillis() % 4750) / 4750f, 0.5f, 1));
}
public static String[] splitLinesToWidth(String input, double maxWidth, FontAdapter rendererUsed) {
List<String> dSplit = List.of(input.split("\n"));
List<String> splits = new ArrayList<>();
for (String s : dSplit) {
List<String> splitContent = new ArrayList<>();
StringBuilder line = new StringBuilder();
for (String c : s.split(" ")) {
if (rendererUsed.getStringWidth(line + c) >= maxWidth - 10) {
splitContent.add(line.toString().trim());
line = new StringBuilder();
}
line.append(c).append(" ");
}
splitContent.add(line.toString().trim());
splits.addAll(splitContent);
}
return splits.toArray(new String[0]);
}
@SuppressWarnings("UnusedReturnValue") public static NbtCompound putPos(Vec3d pos, NbtCompound comp) {
NbtList list = new NbtList();
list.add(NbtDouble.of(pos.x));
list.add(NbtDouble.of(pos.y));
list.add(NbtDouble.of(pos.z));
comp.put("Pos", list);
return comp;
}
public static ItemStack generateItemStackWithMeta(String nbt, Item item) {
try {
ItemStack stack = new ItemStack(item);
stack.setNbt(StringNbtReader.parse(nbt));
return stack;
} catch (Exception ignored) {
return new ItemStack(item);
}
}
public static class Inventory {
public static int slotIndexToId(int index) {
int translatedSlotId;
if (index >= 0 && index < 9) {
translatedSlotId = 36 + index;
} else {
translatedSlotId = index;
}
return translatedSlotId;
}
public static void drop(int index) {
int translatedSlotId = slotIndexToId(index);
Objects.requireNonNull(SipoverPrivate.client.interactionManager)
.clickSlot(Objects.requireNonNull(SipoverPrivate.client.player).currentScreenHandler.syncId, translatedSlotId, 1, SlotActionType.THROW, SipoverPrivate.client.player);
}
public static void moveStackToOther(int slotIdFrom, int slotIdTo) {
Objects.requireNonNull(SipoverPrivate.client.interactionManager).clickSlot(0, slotIdFrom, 0, SlotActionType.PICKUP, SipoverPrivate.client.player); // pick up item from stack
SipoverPrivate.client.interactionManager.clickSlot(0, slotIdTo, 0, SlotActionType.PICKUP, SipoverPrivate.client.player); // put item to target
SipoverPrivate.client.interactionManager.clickSlot(0, slotIdFrom, 0, SlotActionType.PICKUP, SipoverPrivate.client.player); // (in case target slot had item) put item from target back to from
}
}
public static class Math {
public static boolean isNumber(String in) {
try {
Integer.parseInt(in);
return true;
} catch (Exception ignored) {
return false;
}
}
public static double roundToDecimal(double n, int point) {
if (point == 0) {
return java.lang.Math.floor(n);
}
double factor = java.lang.Math.pow(10, point);
return java.lang.Math.round(n * factor) / factor;
}
public static int tryParseInt(String input, int defaultValue) {
try {
return Integer.parseInt(input);
} catch (Exception ignored) {
return defaultValue;
}
}
public static Vec3d getRotationVector(float pitch, float yaw) {
float f = pitch * 0.017453292F;
float g = -yaw * 0.017453292F;
float h = MathHelper.cos(g);
float i = MathHelper.sin(g);
float j = MathHelper.cos(f);
float k = MathHelper.sin(f);
return new Vec3d(i * j, -k, h * j);
}
public static boolean isABObstructed(Vec3d a, Vec3d b, World world, Entity requester) {
RaycastContext rcc = new RaycastContext(a, b, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, requester);
BlockHitResult bhr = world.raycast(rcc);
return !bhr.getPos().equals(b);
}
}
public static class Mouse {
public static double getMouseX() {
return SipoverPrivate.client.mouse.getX() / SipoverPrivate.client.getWindow().getScaleFactor();
}
public static double getMouseY() {
return SipoverPrivate.client.mouse.getY() / SipoverPrivate.client.getWindow().getScaleFactor();
}
}
public static class Players {
static final Map<String, UUID> UUID_CACHE = new HashMap<>();
static final Map<UUID, String> NAME_CACHE = new HashMap<>();
static final HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
public static String getNameFromUUID(UUID uuid) {
if (NAME_CACHE.containsKey(uuid)) {
return NAME_CACHE.get(uuid);
}
try {
HttpRequest req = HttpRequest.newBuilder().GET().uri(URI.create("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid)).build();
HttpResponse<String> response = client.send(req, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 204 || response.statusCode() == 400) {
return null; // no user / invalid username
}
JsonObject root = JsonParser.parseString(response.body()).getAsJsonObject();
return root.get("name").getAsString();
} catch (Exception ignored) {
return null;
}
}
public static UUID getUUIDFromName(String name) {
if (!isPlayerNameValid(name)) {
return null;
}
if (UUID_CACHE.containsKey(name.toLowerCase())) {
return UUID_CACHE.get(name.toLowerCase());
}
try {
HttpRequest req = HttpRequest.newBuilder().GET().uri(URI.create("https://api.mojang.com/users/profiles/minecraft/" + name)).build();
HttpResponse<String> response = client.send(req, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 204 || response.statusCode() == 400) {
return null; // no user / invalid username
}
JsonObject root = JsonParser.parseString(response.body()).getAsJsonObject();
String id = root.get("id").getAsString();
String uuid = id.replaceAll("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5");
UUID u = UUID.fromString(uuid);
UUID_CACHE.put(name.toLowerCase(), u);
return u;
} catch (Exception ignored) {
return null;
}
}
public static boolean isPlayerNameValid(String name) {
if (name.length() < 3 || name.length() > 16) {
return false;
}
String valid = "abcdefghijklmnopqrstuvwxyz0123456789_";
boolean isValidEntityName = true;
for (char c : name.toLowerCase().toCharArray()) {
if (!valid.contains(c + "")) {
isValidEntityName = false;
break;
}
}
return isValidEntityName;
}
public static int[] decodeUUID(UUID uuid) {
long sigLeast = uuid.getLeastSignificantBits();
long sigMost = uuid.getMostSignificantBits();
return new int[]{(int) (sigMost >> 32), (int) sigMost, (int) (sigLeast >> 32), (int) sigLeast};
}
}
public static class Logging {
public static void warn(String n) {
message0(n, Color.YELLOW);
}
public static void success(String n) {
message0(n, AtomicConsoleScreen.SUCCESS);
}
public static void error(String n) {
message0(n, AtomicConsoleScreen.ERROR);
}
public static void message(String n) {
message0(n, AtomicConsoleScreen.DEFAULT);
}
public static void message0(String n, Color c) {
AtomicConsoleScreen.instance().log(n, c);
}
public static void messageChat(String n) {
if (SipoverPrivate.client.player == null) {
return;
}
SipoverPrivate.client.player.sendMessage(Text.of("[§9A§r] " + n), false);
}
}
public static class TickManager {
static final List<TickEntry> entries = new ArrayList<>();
static final List<Runnable> nextTickRunners = new ArrayList<>();
public static void runInNTicks(int n, Runnable toRun) {
entries.add(new TickEntry(n, toRun));
}
public static void tick() {
for (TickEntry entry : entries.toArray(new TickEntry[0])) {
entry.v--;
if (entry.v <= 0) {
entry.r.run();
entries.remove(entry);
}
}
}
public static void runOnNextRender(Runnable r) {
nextTickRunners.add(r);
}
public static void render() {
for (Runnable nextTickRunner : nextTickRunners) {
nextTickRunner.run();
}
nextTickRunners.clear();
}
static class TickEntry {
final Runnable r;
int v;
public TickEntry(int v, Runnable r) {
this.v = v;
this.r = r;
}
}
}
}

View file

@ -4,6 +4,8 @@
"compatibilityLevel": "JAVA_8",
"mixins": [
"ClientPlayerEntityMixin",
"IMinecraftClientAccessor",
"IRenderTickCounterAccessor",
"KeyboardMixin",
"MinecraftClientMixin"
],