Compare commits

..
Author SHA1 Message Date
selimaj-dev c567b282a5 Merge pull request #12 from RudideC/master
added health display
2026-02-13 12:03:56 +01:00
RudideC 5f19abebbf added health display
ts tuff
2026-02-13 10:06:13 +01:00
Klesti Selimaj 58eda56f37 Merge pull request #11 from RudideC/master
zoom mod
2026-01-21 21:57:42 +01:00
RudideC 50cab402d4 image 2026-01-21 21:52:28 +01:00
RudideC fa7161d371 zoom module 2026-01-21 21:52:24 +01:00
Klesti Selimaj 252808a467 Merge pull request #10 from RudideC/master
added nofog, daycounter and speedometer
2026-01-20 21:56:36 +01:00
RudideC 31e9a8d56e speedometer module finished
logo included
2026-01-20 15:30:57 +01:00
RudideC ba1b68d8fa speedometer works in vehicles 2026-01-20 14:57:59 +01:00
RudideC dcd82fa58e default is x axis 2026-01-20 14:51:22 +01:00
RudideC 4132a05c8f blocks/tick -> blocks/s 2026-01-20 14:44:29 +01:00
RudideC 47f8dd5e22 testing speedometer 2026-01-20 14:35:49 +01:00
RudideC 9b30ec7016 small change 2026-01-20 14:18:44 +01:00
RudideC d10f229ffa daycounter image 2026-01-19 20:55:07 +01:00
RudideC 061ed674e3 daycounter mod
counts days
2026-01-19 20:54:59 +01:00
RudideC 5b5f781095 nofog mod
you can customise if you want to be able to see through liquids, but only lava and powdered snow work (not water)
2026-01-17 00:24:39 +01:00
Klesti Selimaj 48f7aefbf6 Merge pull request #9 from RudideC/master 2026-01-16 22:12:15 +01:00
RudideC 8f111badf6 oops, forgot 2026-01-16 22:05:35 +01:00
RudideC 687bda68a1 renamed potiondisplay to status effects
this is the name most clients use
2026-01-16 22:04:57 +01:00
RudideC 8e2c986ae4 fullbright
new mod
2026-01-16 22:02:48 +01:00
RudideC faa95e664a faster timeout
(so i don't have to wait minutes before testing)
2026-01-16 22:02:25 +01:00
RudideC c9230da168 faster builds
yes
2026-01-16 22:01:59 +01:00
RudideC 7002fbec0e prevent race condition 2026-01-16 19:41:37 +01:00
RudideC 496d27b861 enabled mod list updates
each mod enable/disable updates the list
2026-01-16 19:41:29 +01:00
RudideC 3c37b80bc2 dont sprint when using item
anticheat compliance
2026-01-16 19:02:51 +01:00
29 changed files with 527 additions and 21 deletions
+6 -1
View File
@@ -1,5 +1,10 @@
# Done to increase the memory available to gradle. # Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G org.gradle.jvmargs=-Xmx1G -XX:+UseParallelGC
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.caching=true
minecraft_version=1.21.4 minecraft_version=1.21.4
yarn_mappings=1.21.4+build.7 yarn_mappings=1.21.4+build.7
@@ -13,10 +13,16 @@ public class ModManager {
new AutoSprint(), new AutoSprint(),
new ArmorDisplay(), new ArmorDisplay(),
new Fps(), new Fps(),
new PotionDisplay(), new StatusEffects(),
new Coordinates(), new Coordinates(),
new Freelook(), new Freelook(),
new Keystrokes() new Keystrokes(),
new Fullbright(),
new NoFog(),
new DayCounter(),
new Speedometer(),
new Zoom(),
new HealthDisplay()
}; };
public static void init() { public static void init() {
@@ -31,7 +37,7 @@ public class ModManager {
}); });
} }
public static void updateEnabledModules() { public static synchronized void updateEnabledModules() {
ENABLED_MODS.clear(); ENABLED_MODS.clear();
for (Module m : ALL_MODS) { for (Module m : ALL_MODS) {
if (m.isEnabled()) { if (m.isEnabled()) {
@@ -24,7 +24,12 @@ public abstract class Module {
public abstract boolean isEnabled(); public abstract boolean isEnabled();
public abstract void setEnabled(boolean e); public final void setEnabled(boolean e) {
onEnabled(e);
ModManager.updateEnabledModules();
}
public abstract void onEnabled(boolean e);
public final String getName() { public final String getName() {
return details.name; return details.name;
@@ -96,7 +96,7 @@ public class ArmorDisplay extends Module implements HudMod {
} }
@Override @Override
public void setEnabled(boolean e) { public void onEnabled(boolean e) {
enabled.value = e; enabled.value = e;
} }
} }
@@ -24,8 +24,12 @@ public class AutoSprint extends Module {
if (SaturnClient.client.player == null || SaturnClient.client.getNetworkHandler() == null) { if (SaturnClient.client.player == null || SaturnClient.client.getNetworkHandler() == null) {
return; return;
} }
if (SaturnClient.client.options.forwardKey.isPressed() && !SaturnClient.client.options.backKey.isPressed() && !SaturnClient.client.player.isSneaking() && if (SaturnClient.client.options.forwardKey.isPressed()
!SaturnClient.client.player.horizontalCollision) { && !SaturnClient.client.options.backKey.isPressed()
&& !SaturnClient.client.player.isSneaking()
&& !SaturnClient.client.player.horizontalCollision
&& !SaturnClient.client.player.isUsingItem()) {
Objects.requireNonNull(SaturnClient.client.player).setSprinting(true); Objects.requireNonNull(SaturnClient.client.player).setSprinting(true);
} }
} }
@@ -36,7 +40,7 @@ public class AutoSprint extends Module {
} }
@Override @Override
public void setEnabled(boolean e) { public void onEnabled(boolean e) {
enabled.value = e; enabled.value = e;
} }
} }
@@ -69,7 +69,7 @@ public class Coordinates extends Module implements HudMod {
} }
@Override @Override
public void setEnabled(boolean e) { public void onEnabled(boolean e) {
enabled.value = e; enabled.value = e;
} }
} }
@@ -42,7 +42,7 @@ public class Crosshair extends Module {
} }
@Override @Override
public void setEnabled(boolean e) { public void onEnabled(boolean e) {
enabled.value = e; enabled.value = e;
} }
} }
@@ -0,0 +1,61 @@
package org.saturnclient.modules.mods;
import org.saturnclient.modules.HudMod;
import org.saturnclient.modules.ModDimensions;
import org.saturnclient.modules.Module;
import org.saturnclient.modules.ModuleDetails;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.config.Property;
import org.saturnclient.ui2.RenderScope;
import org.saturnclient.ui2.resources.Fonts;
public class DayCounter extends Module implements HudMod {
private static Property<Boolean> enabled = Property.bool(false);
private static ModDimensions dimensions = new ModDimensions(40, 18);
long day = 0;
public DayCounter() {
super(new ModuleDetails("DayCounter", "day")
.description("Displays the number of days that have passed")
.version("v0.1.0")
.tags("Utility"),
enabled.named("Enabled"),
dimensions.prop()
);
}
@Override
public void renderDummy(RenderScope scope) {
renderDay(271, scope);
}
@Override
public void renderHud(RenderScope scope) {
day = (SaturnClient.client.world.getTimeOfDay() / 24000L);
renderDay(day, scope);
}
public void renderDay(long day, RenderScope scope) {
String text = "Day: " + day;
scope.drawText(text,
0, 0, dimensions.font.value, dimensions.fgColor.value);
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
dimensions.height = 18 * text.split("\n").length;
}
@Override
public boolean isEnabled() {
return enabled.value;
}
@Override
public ModDimensions getDimensions() {
return dimensions;
}
@Override
public void onEnabled(boolean e) {
enabled.value = e;
}
}
@@ -42,7 +42,7 @@ public class Fps extends Module implements HudMod {
} }
@Override @Override
public void setEnabled(boolean e) { public void onEnabled(boolean e) {
enabled.value = e; enabled.value = e;
} }
@@ -60,7 +60,7 @@ public class Freelook extends Module {
} }
@Override @Override
public void setEnabled(boolean e) { public void onEnabled(boolean e) {
enabled.value = e; enabled.value = e;
} }
@@ -0,0 +1,39 @@
package org.saturnclient.modules.mods;
import org.saturnclient.modules.Module;
import org.saturnclient.modules.ModuleDetails;
import org.saturnclient.saturnclient.config.Property;
public class Fullbright extends Module {
private static Property<Boolean> enabled = Property.bool(false);
private static Property<Integer> brightness = Property.integer(100);
public Fullbright() {
super(
new ModuleDetails("Fullbright", "fullbright")
.description("Allows you to see in the dark")
.tags("Camera")
.version("v0.1.0"),
enabled.named("Enabled"),
brightness.named("Brightness %"));
}
@Override
public boolean isEnabled() {
return enabled.value;
}
@Override
public void onEnabled(boolean e) {
enabled.value = e;
}
public static boolean shouldOverrideBrightness() {
return enabled.value;
}
public static float getBrightnessValue() {
return brightness.value / 10;
}
}
@@ -0,0 +1,85 @@
package org.saturnclient.modules.mods;
import org.saturnclient.modules.HudMod;
import org.saturnclient.modules.ModDimensions;
import org.saturnclient.modules.Module;
import org.saturnclient.modules.ModuleDetails;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.config.Property;
import org.saturnclient.ui2.RenderScope;
import org.saturnclient.ui2.resources.Fonts;
import net.minecraft.util.math.Vec3d;
public class HealthDisplay extends Module implements HudMod {
private static Property<Boolean> enabled = Property.bool(false);
private static Property<Integer> displayMode = Property.select(0, "Health", "Hearts");
private static Property<Integer> decimals = Property.select(0, "0", "1", "2");
private static ModDimensions dimensions = new ModDimensions(40, 18);
double speed = 0.;
Vec3d velocity;
double y = 0.;
public HealthDisplay() {
super(new ModuleDetails("Health display", "health")
.description("Displays your current health")
.version("v0.1.0")
.tags("Utility"),
enabled.named("Enabled"),
displayMode.named("Display mode"),
decimals.named("Decimals"),
dimensions.prop()
);
}
@Override
public void renderDummy(RenderScope scope) {
renderSpeed(10, scope);
}
@Override
public void renderHud(RenderScope scope) {
float health = SaturnClient.client.player.getHealth();
switch (displayMode.value) {
case 1:
health = health / 2;
}
renderSpeed(health, scope);
}
public void renderSpeed(float health, RenderScope scope) {
String text = "";
switch (decimals.value) {
case 0:
text = String.format("%.0f ", health);
break;
case 1:
text = String.format("%.1f ", health);
break;
case 2:
text = String.format("%.2f ", health);
break;
}
scope.drawText(text,
0, 0, dimensions.font.value, dimensions.fgColor.value);
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
dimensions.height = 18 * text.split("\n").length;
}
@Override
public boolean isEnabled() {
return enabled.value;
}
@Override
public ModDimensions getDimensions() {
return dimensions;
}
@Override
public void onEnabled(boolean e) {
enabled.value = e;
}
}
@@ -167,7 +167,7 @@ public class Keystrokes extends Module implements HudMod {
} }
@Override @Override
public void setEnabled(boolean e) { public void onEnabled(boolean e) {
enabled.value = e; enabled.value = e;
dimensionsDirty = true; dimensionsDirty = true;
} }
@@ -0,0 +1,39 @@
package org.saturnclient.modules.mods;
import org.saturnclient.modules.Module;
import org.saturnclient.modules.ModuleDetails;
import org.saturnclient.saturnclient.config.Property;
public class NoFog extends Module {
private static Property<Boolean> enabled = Property.bool(false);
private static Property<Boolean> liquids = Property.bool(false);
public NoFog() {
super(
new ModuleDetails("No Fog", "nofog")
.description("Stops fog from rendering")
.tags("Camera")
.version("v0.1.0"),
enabled.named("Enabled"),
liquids.named("See through liquids"));
}
@Override
public boolean isEnabled() {
return enabled.value;
}
@Override
public void onEnabled(boolean e) {
enabled.value = e;
}
// static for the mixin
public static boolean isActive() {
return enabled.value;
}
public static boolean liquids() {
return liquids.value;
}
}
@@ -0,0 +1,114 @@
package org.saturnclient.modules.mods;
import org.saturnclient.modules.HudMod;
import org.saturnclient.modules.ModDimensions;
import org.saturnclient.modules.Module;
import org.saturnclient.modules.ModuleDetails;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.config.Property;
import org.saturnclient.ui2.RenderScope;
import org.saturnclient.ui2.resources.Fonts;
import net.minecraft.util.math.Vec3d;
import net.minecraft.entity.Entity;
public class Speedometer extends Module implements HudMod {
private static Property<Boolean> enabled = Property.bool(false);
private static Property<Integer> axis = Property.select(1, "Absolute", "X axis", "Y axis");
private static Property<Integer> unitText = Property.select(0, "None", "Blocks/s", "blocks/s", "b/s");
private static Property<Boolean> speedText = Property.bool(true);
private static ModDimensions dimensions = new ModDimensions(40, 18);
double speed = 0.;
Vec3d velocity;
double y = 0.;
public Speedometer() {
super(new ModuleDetails("Speedometer", "speed")
.description("Displays your current speed")
.version("v0.1.0")
.tags("Utility"),
enabled.named("Enabled"),
axis.named("Speed type"),
unitText.named("Unit text"),
speedText.named("Show speed text"),
dimensions.prop()
);
}
@Override
public void renderDummy(RenderScope scope) {
renderSpeed(2.71, scope);
}
@Override
public void renderHud(RenderScope scope) {
Entity vehicle = SaturnClient.client.player.getVehicle();
Entity player = SaturnClient.client.player;
if (vehicle == null) {
velocity = player.getVelocity();
y = player.isOnGround() ? 0. : velocity.y;
} else {
velocity = vehicle.getVelocity();
y = vehicle.isOnGround() ? 0. : velocity.y;
}
switch (axis.value) {
case 0: // Absolute
speed = (Math.sqrt(Math.pow(velocity.x, 2) + Math.pow(y, 2) + Math.pow(velocity.z, 2)));
break;
case 1: // x axis
speed = (Math.sqrt(Math.pow(velocity.x, 2) + Math.pow(velocity.z, 2)));
break;
case 2: // y axis
speed = (Math.abs(y));
break;
}
renderSpeed(speed * 20, scope); // blocks/tick to blocks/s
}
public void renderSpeed(double speed, RenderScope scope) {
String f = String.format("%.2f ", speed);
switch (unitText.value) {
case 1:
f += "Blocks/s";
break;
case 2:
f += "blocks/s";
break;
case 3:
f += "b/s";
break;
}
String text = f;
if (speedText.value) {
text = "Speed: " + text;
}
scope.drawText(text,
0, 0, dimensions.font.value, dimensions.fgColor.value);
dimensions.width = Fonts.getWidth(text, dimensions.font.value);
dimensions.height = 18 * text.split("\n").length;
}
@Override
public boolean isEnabled() {
return enabled.value;
}
@Override
public ModDimensions getDimensions() {
return dimensions;
}
@Override
public void onEnabled(boolean e) {
enabled.value = e;
}
}
@@ -20,7 +20,7 @@ import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public class PotionDisplay extends Module implements HudMod { public class StatusEffects extends Module implements HudMod {
public static Property<Boolean> enabled = Property.bool(false); public static Property<Boolean> enabled = Property.bool(false);
private static ModDimensions dimensions = new ModDimensions(60, 0); private static ModDimensions dimensions = new ModDimensions(60, 0);
@@ -30,9 +30,9 @@ public class PotionDisplay extends Module implements HudMod {
new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2), new StatusEffectInstance(Registries.STATUS_EFFECT.getEntry(Identifier.ofVanilla("fire_resistance")).get(), 12000, 2),
}; };
public PotionDisplay() { public StatusEffects() {
super(new ModuleDetails("Potion Display", "potion") super(new ModuleDetails("Status effects", "effect")
.description("Displays potion effects") .description("Displays status effects")
.version("v0.1.0") .version("v0.1.0")
.tags("Utility"), .tags("Utility"),
@@ -99,7 +99,7 @@ public class PotionDisplay extends Module implements HudMod {
} }
@Override @Override
public void setEnabled(boolean e) { public void onEnabled(boolean e) {
enabled.value = e; enabled.value = e;
} }
} }
@@ -0,0 +1,60 @@
package org.saturnclient.modules.mods;
import org.lwjgl.glfw.GLFW;
import org.saturnclient.modules.Module;
import org.saturnclient.modules.ModuleDetails;
import org.saturnclient.saturnclient.config.Property;
public class Zoom extends Module {
private static Property<Boolean> enabled = Property.bool(false);
private static Property<Boolean> toggle = Property.bool(false);
public static Property<Integer> zoomKey = Property.keybinding(GLFW.GLFW_KEY_C);
public static Property<Float> zoomLevel = Property.floatProp(3.0f);
public static boolean isZooming = false;
public Zoom() {
super(
new ModuleDetails("Zoom", "zoom")
.description("Allows you to zoom in for a closer view")
.tags("Camera", "Utility")
.version("0.1.0"),
enabled.named("Enabled"),
toggle.named("Toggle zoom"),
zoomKey.named("Zoom Keybinding"),
zoomLevel.named("Zoom Level")
);
}
@Override
public void tick() {
if (toggle.value) {
if (zoomKey.wasKeyPressed()) {
isZooming = !isZooming;
}
} else {
isZooming = zoomKey.isKeyPressed();
}
}
public static float getZoomLevel() {
return zoomLevel.value;
}
public static boolean shouldZoom() {
return enabled.value;
}
@Override
public void onEnabled(boolean e) {
enabled.value = e;
if (!e) {
isZooming = false;
}
}
@Override
public boolean isEnabled() {
return enabled.value;
}
}
@@ -0,0 +1,33 @@
package org.saturnclient.modules.mods.mixins;
import net.minecraft.client.render.BackgroundRenderer;
import org.saturnclient.modules.mods.NoFog;
import net.minecraft.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(BackgroundRenderer.class)
public class BackgroundRendererMixin {
@ModifyVariable(method = "applyFog", at = @At("HEAD"), ordinal = 0, argsOnly = true)
private static float modifyFogStart(float viewDistance) {
if (NoFog.isActive()) {
return Float.MAX_VALUE; // this could be customised
}
return viewDistance;
}
// liquids
@Redirect(
method = "applyFog",
at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;isSpectator()Z")
)
private static boolean redirectIsSpectator(Entity entity) {
if (NoFog.isActive() && NoFog.liquids()) {
return true; // pretend to be spectator
}
return entity.isSpectator();
}
}
@@ -0,0 +1,22 @@
package org.saturnclient.modules.mods.mixins;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.saturnclient.modules.mods.Zoom;
import net.minecraft.client.render.GameRenderer;
@Mixin(GameRenderer.class)
public class GameRendererMixin {
@Inject(method = "getFov", at = @At("RETURN"), cancellable = true)
private void onGetFov(CallbackInfoReturnable<Float> cir) {
if (Zoom.isZooming && Zoom.shouldZoom()) {
float originalFov = cir.getReturnValue();
float zoomedFov = originalFov / Zoom.getZoomLevel();
cir.setReturnValue(zoomedFov);
}
}
}
@@ -0,0 +1,23 @@
// code modified from Gamma utils: https://github.com/Sjouwer/gamma-utils
package org.saturnclient.modules.mods.mixins;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.client.render.LightmapTextureManager;
import org.saturnclient.modules.mods.Fullbright;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(LightmapTextureManager.class)
public class LightmapTextureManagerMixin {
@ModifyExpressionValue(
method = "update",
at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0)
)
private float modifyGamma(float original) {
if (Fullbright.shouldOverrideBrightness()) {
return Fullbright.getBrightnessValue();
}
return original;
}
}
@@ -15,6 +15,9 @@ public class Network {
static BufferedReader in; static BufferedReader in;
static byte[] key = new byte[32]; static byte[] key = new byte[32];
private static final int CONNECTION_TIMEOUT = 5000;
private static final int READ_TIMEOUT = 5000;
public static class AES { public static class AES {
public static byte[] encryptAES256(String message, byte[] key) throws Exception { public static byte[] encryptAES256(String message, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
@@ -37,7 +40,11 @@ public class Network {
// Generate AES key // Generate AES key
new SecureRandom().nextBytes(key); new SecureRandom().nextBytes(key);
socket = new Socket("77.247.92.168", 8080); socket = new Socket();
socket.connect(new InetSocketAddress("77.247.92.168", 8080), CONNECTION_TIMEOUT);
socket.setSoTimeout(READ_TIMEOUT);
// out = new DataOutputStream(socket.getOutputStream()); // out = new DataOutputStream(socket.getOutputStream());
out = new PrintWriter(socket.getOutputStream(), true); out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

+4 -1
View File
@@ -6,7 +6,10 @@
"client": [ "client": [
"CameraMixin", "CameraMixin",
"EntityMixin", "EntityMixin",
"RenderMixin" "RenderMixin",
"LightmapTextureManagerMixin",
"BackgroundRendererMixin",
"GameRendererMixin"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1