Skip to content
This repository was archived by the owner on Nov 28, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
62e28f6
feat: initial bridge API implementation (1.8.9, some hud modules port)
Floweynt Feb 23, 2025
56ffc97
cleanup based on github comments
Floweynt Mar 16, 2025
11946c4
fix compilation on some other versions (1.21.4 is not implemented bec…
Floweynt Mar 19, 2025
eb79328
preliminary bridge implementation for 1.21.4
Floweynt Mar 21, 2025
aa04636
begin porting hypixel modules
Floweynt Apr 3, 2025
38be609
scissor and some other stuff
Floweynt Apr 14, 2025
594785a
Things compile now
Floweynt May 12, 2025
421d605
Get rid of hypixel modules
Floweynt May 12, 2025
32856e4
Fix some startup crashes + things not building for some reason.
Floweynt May 12, 2025
f304381
migrate 1.8.9 to the common hud system rather than hosting both systems.
Floweynt May 13, 2025
1e304c0
Improve bridge implementation on 1.8.9
Floweynt May 16, 2025
be16f6c
squashme
Floweynt May 16, 2025
90acafa
cleanup for 1.16
Floweynt May 16, 2025
9fdabd1
hud now doesn't crash
Floweynt May 16, 2025
2db0554
1.20 runs without crashing, mostly
Floweynt May 17, 2025
76f749e
add license headers
Floweynt May 17, 2025
b718887
"stable" for 1.21
Floweynt May 18, 2025
74d3d27
merge "properly"
Floweynt Jun 19, 2025
b2568b4
implement new bridge apis for 1.8.9
Floweynt Jun 20, 2025
d2bdcb9
merge dev, again
Floweynt Jun 20, 2025
da95df1
implement new bridge api for 1.16
Floweynt Jun 20, 2025
9e25fb9
bridge clean up & commands
Floweynt Jun 22, 2025
44c521b
merge dev
Floweynt Jun 30, 2025
1719dca
bug fixes
Floweynt Jul 5, 2025
557925c
uncomment some TODOs
Floweynt Jul 6, 2025
0b1a547
fix config file logic
Floweynt Jul 7, 2025
8983413
validate bridge implementations for 1.8.9, 1.16, and 1.20
Floweynt Jul 10, 2025
273549b
validate most (all?) bridge implementations
Floweynt Jul 10, 2025
986e6a5
license header fixes
Floweynt Jul 10, 2025
bc9480e
update config version manager & fix NPE with datetimeformatter
Floweynt Jul 12, 2025
7ebfbe2
resolve some comments
Floweynt Jul 17, 2025
e4ef4e1
fix mixin config
Floweynt Jul 17, 2025
864f402
fix imports
Floweynt Jul 17, 2025
4c4b6e4
bump gradle & loom
moehreag Jul 19, 2025
df128cc
cleanup user agent
moehreag Jul 19, 2025
0a8dd01
ensure config loading
moehreag Jul 21, 2025
ac93b88
attempt some bugfixes
Floweynt Jul 22, 2025
dbbbda5
fix a lot of bugs
moehreag Jul 22, 2025
9d213e7
bump config lib
moehreag Jul 22, 2025
760c861
add keybind to toggle hud rendering
moehreag Jul 30, 2025
0d55989
use `consumeClick` handlers for keybindings
moehreag Jul 30, 2025
343f83e
add bridge API for resource manager access
moehreag Jul 30, 2025
57ac88b
Merge remote-tracking branch 'origin/dev' into flowey/bridge
moehreag Jul 30, 2025
29c909a
fix another bug
moehreag Jul 30, 2025
f9dbf40
disable mc jar verification for 1.16_combat-6
moehreag Jul 30, 2025
17e89e0
the same but so that it hopefully works
moehreag Jul 30, 2025
81bb698
clean up main class
moehreag Jul 31, 2025
63b4729
Implement bridge for AutoBoop filters
moehreag Jul 31, 2025
bd531a4
bump config lib + fabric loader version
moehreag Aug 1, 2025
840d55d
fix resource reloads
moehreag Aug 1, 2025
768dd83
add missing AxoSprites Mixin to 1.21.8
moehreag Aug 1, 2025
dafa142
(1.8.9) fix hotbar hud
moehreag Aug 3, 2025
b9f5cd6
Implement `PlayerHud`s
moehreag Aug 4, 2025
55f1159
rename common hud package
moehreag Aug 5, 2025
dbb7a95
clean up a bit
moehreag Aug 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
156 changes: 37 additions & 119 deletions 1.16_combat-6/src/main/java/io/github/axolotlclient/AxolotlClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,12 @@

package io.github.axolotlclient;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import com.google.gson.JsonObject;
import io.github.axolotlclient.AxolotlClientConfig.api.manager.ConfigManager;
import io.github.axolotlclient.AxolotlClientConfig.api.options.OptionCategory;
import io.github.axolotlclient.AxolotlClientConfig.api.ui.ConfigUI;
import io.github.axolotlclient.AxolotlClientConfig.impl.managers.VersionedJsonConfigManager;
import io.github.axolotlclient.AxolotlClientConfig.impl.options.BooleanOption;
import io.github.axolotlclient.api.API;
import io.github.axolotlclient.api.APIOptions;
import io.github.axolotlclient.api.StatusUpdateProviderImpl;
import io.github.axolotlclient.config.AxolotlClientConfig;
import io.github.axolotlclient.modules.Module;
import io.github.axolotlclient.bridge.impl.Bridge;
import io.github.axolotlclient.modules.ModuleLoader;
import io.github.axolotlclient.modules.auth.Auth;
import io.github.axolotlclient.modules.blur.MenuBlur;
Expand All @@ -59,137 +49,65 @@
import io.github.axolotlclient.util.LoggerImpl;
import io.github.axolotlclient.util.notifications.Notifications;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.resource.Resource;
import net.minecraft.util.Identifier;

public class AxolotlClient implements ClientModInitializer {
public class AxolotlClient extends AxolotlClientCommon implements ClientModInitializer {

public static final String MODID = "axolotlclient";
public static final HashMap<Identifier, Resource> runtimeResources = new HashMap<>();
public static final Identifier badgeIcon = new Identifier(MODID, "textures/badge.png");
public static final OptionCategory config = OptionCategory.create("storedOptions");
public static final BooleanOption someNiceBackground = new BooleanOption("defNoSecret", false);
public static final List<Module> modules = new ArrayList<>();
public static final Identifier badgeIcon = new Identifier("axolotlclient", "textures/badge.png");
public static final Logger LOGGER = new LoggerImpl();
public static String VERSION;
public static AxolotlClientConfig CONFIG;
public static ConfigManager configManager;

public static void getModules() {
modules.add(SkyResourceManager.getInstance());
modules.add(Zoom.getInstance());
modules.add(HudManager.getInstance());
modules.add(HypixelMods.getInstance());
modules.add(MotionBlur.getInstance());
modules.add(MenuBlur.getInstance());
modules.add(ScrollableTooltips.getInstance());
modules.add(DiscordRPC.getInstance());
modules.add(Freelook.getInstance());
modules.add(TntTime.getInstance());
modules.add(Particles.getInstance());
modules.add(ScreenshotUtils.getInstance());
modules.add(BeaconBeam.getInstance());
modules.add(Tablist.getInstance());
modules.add(Auth.getInstance());
modules.add(APIOptions.getInstance());
private void addBuiltinModules() {
registerModule(SkyResourceManager.getInstance());
registerModule(Zoom.getInstance());
registerModule(HudManager.getInstance());
registerModule(HypixelMods.getInstance());
registerModule(MotionBlur.getInstance());
registerModule(MenuBlur.getInstance());
registerModule(ScrollableTooltips.getInstance());
registerModule(DiscordRPC.getInstance());
registerModule(Freelook.getInstance());
registerModule(TntTime.getInstance());
registerModule(Particles.getInstance());
registerModule(ScreenshotUtils.getInstance());
registerModule(BeaconBeam.getInstance());
registerModule(Tablist.getInstance());
registerModule(Auth.getInstance());
registerModule(APIOptions.getInstance());
}

private static void addExternalModules() {
modules.addAll(ModuleLoader.loadExternalModules());
private void addExternalModules() {
ModuleLoader.loadExternalModules().forEach(this::registerModule);
}

@Override
public void onInitializeClient() {
Bridge.init();

VERSION = FabricLoader.getInstance().getModContainer(MODID).orElseThrow(IllegalStateException::new)
.getMetadata().getVersion().getFriendlyString();

CONFIG = new AxolotlClientConfig();
config.add(someNiceBackground);

getModules();
addBuiltinModules();
addExternalModules();
CONFIG.init();

new AxolotlClientCommon(LOGGER, Notifications.getInstance(), () -> configManager);
init(LOGGER, Notifications.getInstance());
new API(LOGGER, I18n::translate, new StatusUpdateProviderImpl(), APIOptions.getInstance());
ClientLifecycleEvents.CLIENT_STOPPING.register(c -> API.getInstance().shutdown());

modules.forEach(Module::init);

CONFIG.config.add(config);

io.github.axolotlclient.AxolotlClientConfig.api.AxolotlClientConfig.getInstance()
.register(configManager = new VersionedJsonConfigManager(AxolotlClientCommon.getInstance().getMainConfigFile(),
CONFIG.config, 4, (oldVersion, newVersion, config, json) -> {
if (oldVersion.getMajor() <= 1) {
if (json.has("hud")) {
var hud = json.get("hud").getAsJsonObject();
if (hud.has("keystrokehud")) {
var keystrokes = hud.get("keystrokehud")
.getAsJsonObject();
var mousemovement = new JsonObject();
mousemovement.addProperty("enabled", keystrokes.get("enabled").getAsBoolean() && keystrokes.get("mousemovement").getAsBoolean());
mousemovement.addProperty("mouseMovementIndicator", keystrokes.get("mouseMovementIndicator").getAsString());
mousemovement.addProperty("mouseMovementIndicatorOuter", keystrokes.get("mouseMovementIndicatorOuter").getAsString());
hud.add("mousemovementhud", mousemovement);
}
}
}
if (oldVersion.getMajor() <= 2) {
if (json.has("hud")) {
var hud = json.get("hud").getAsJsonObject();
if (hud.has("armorhud")) {
var armorhud = hud.get("armorhud").getAsJsonObject();
if (armorhud.has("armorhud.main_hand_item_top")) {
var mainItemTop = armorhud.get("armorhud.main_hand_item_top").getAsBoolean();
if (mainItemTop) {
armorhud.addProperty("armorhud.main_hand_item_position", "armorhud.main_hand_item_position.top");
}
}
}
}
}
if (oldVersion.getMajor() <= 3) {
if (json.has("storedOptions")) {
var hiddenOptions = json.get("storedOptions").getAsJsonObject();

JsonObject apiOptions;
if (json.has("api.category")) {
apiOptions = json.get("api.category").getAsJsonObject();
} else {
apiOptions = new JsonObject();
json.add("api.category", apiOptions);
}

apiOptions.addProperty("api.privacy_policy_accepted", "privacy_policy_state." + hiddenOptions.get("privacyPolicyAccepted").getAsString().toLowerCase(Locale.ROOT));
}
}
return json;
}));
configManager.suppressName("x");
configManager.suppressName("y");
configManager.suppressName(config.getName());

ConfigUI.getInstance().runWhenLoaded(this::postConfigLoad);

LOGGER.debug("Debug Output activated, Logs will be more verbose!");

LOGGER.debug("Debug Output enabled, Logs will be quite verbose!");
LOGGER.info("AxolotlClient Initialized");
Bridge.postInit();
}

private boolean configLoaded;
private void postConfigLoad() {
if (configLoaded) return;
configLoaded = true;
modules.forEach(Module::lateInit);
@Override
protected void initFeatureDisabler() {
FeatureDisabler.init();
}

ClientTickEvents.END_CLIENT_TICK.register(client -> modules.forEach(Module::tick));
@Override
protected AxolotlClientConfigCommon createConfig() {
return new io.github.axolotlclient.config.AxolotlClientConfig();
}

FeatureDisabler.init();
public static io.github.axolotlclient.config.AxolotlClientConfig config() {
return (io.github.axolotlclient.config.AxolotlClientConfig) getInstance().getConfig();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public void init() {
}
};
if (Constants.ENABLED) {
AxolotlClient.CONFIG.addCategory(category);
AxolotlClient.config().addCategory(category);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright © 2025 moehreag <moehreag@gmail.com> & Contributors
*
* This file is part of AxolotlClient.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* For more information, see the LICENSE file.
*/

package io.github.axolotlclient.bridge.impl;

import com.mojang.blaze3d.systems.RenderSystem;
import io.github.axolotlclient.AxolotlClientConfig.impl.options.GraphicsOption;
import io.github.axolotlclient.bridge.render.AxoSprite;
import io.github.axolotlclient.util.Util;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;

public interface AxoSpriteImpl extends AxoSprite {
void draw(MinecraftClient client, MatrixStack stack, int sX, int sY, int sW, int sH);

record Simple(Identifier id, int x, int y, int width, int height) implements AxoSpriteImpl {
@Override
public void draw(MinecraftClient client, MatrixStack stack, int sX, int sY, int sW, int sH) {
client.getTextureManager().bindTexture(id);
DrawableHelper.drawTexture(stack, sX, sY, x, y, sW, sH, width, height);
}
}

record Vanilla(Sprite sprite) implements AxoSpriteImpl {
@Override
public void draw(MinecraftClient client, MatrixStack stack, int sX, int sY, int sW, int sH) {
MinecraftClient.getInstance().getTextureManager().bindTexture(sprite.getAtlas().getId());
RenderSystem.color4f(1, 1, 1, 1);
DrawableHelper.drawSprite(stack, sX, sY, 0, sW, sH, sprite);
}
}

record Config(GraphicsOption option) implements AxoSpriteImpl {
@Override
public void draw(MinecraftClient client, MatrixStack stack, int sX, int sY, int sW, int sH) {
Util.bindTexture(option);
DrawableHelper.drawTexture(stack, sX, sY, 0, 0, sW, sH, option.get().getWidth(), option.get().getHeight());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright © 2025 moehreag <moehreag@gmail.com> & Contributors
*
* This file is part of AxolotlClient.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* For more information, see the LICENSE file.
*/

package io.github.axolotlclient.bridge.impl;

import com.mojang.brigadier.CommandDispatcher;
import io.github.axolotlclient.bridge.events.Events;
import net.fabricmc.fabric.api.client.command.v1.ClientCommandManager;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;

public class Bridge {
public static void init() {
ClientLifecycleEvents.CLIENT_STARTED.register(minecraft -> Events.CLIENT_START.invoker().run());
ClientLifecycleEvents.CLIENT_STOPPING.register(minecraft -> Events.CLIENT_STOP.invoker().run());
ClientTickEvents.END_CLIENT_TICK.register(minecraft -> Events.TICK.invoker().run());
}

@SuppressWarnings({"unchecked", "rawtypes"})
public static void postInit() {
Events.COMMAND_REGISTER.invoker().accept(
() -> (CommandDispatcher) ClientCommandManager.DISPATCHER
);
}
}
Loading
Loading