hexidecimal

This commit is contained in:
2025-03-26 17:50:38 +01:00
parent 6fc49863e1
commit 5e7ed4381e
18 changed files with 475 additions and 30 deletions
@@ -7,6 +7,7 @@ import net.minecraft.util.math.ColorHelper;
import org.saturnclient.saturnclient.auth.SaturnSocket; import org.saturnclient.saturnclient.auth.SaturnSocket;
import org.saturnclient.saturnclient.cloaks.Cloaks; import org.saturnclient.saturnclient.cloaks.Cloaks;
import org.saturnclient.saturnclient.config.ConfigManager; import org.saturnclient.saturnclient.config.ConfigManager;
import org.saturnclient.saturnclient.config.Property;
import org.saturnclient.saturnclient.event.KeyInputHandler; import org.saturnclient.saturnclient.event.KeyInputHandler;
import org.saturnclient.saturnmods.ModManager; import org.saturnclient.saturnmods.ModManager;
import org.saturnclient.ui.SaturnAnimation; import org.saturnclient.ui.SaturnAnimation;
@@ -23,13 +24,31 @@ public class SaturnClient implements ModInitializer {
public static final String MOD_ID = "saturnclient"; public static final String MOD_ID = "saturnclient";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
public static int COLOR = ColorHelper.getArgb(255, 251, 60, 79);
public static ConfigManager config = new ConfigManager("Saturn Client");
public static Property<Integer> COLOR = config.property(
"Primary color",
new Property<Integer>(
ColorHelper.getArgb(255, 251, 60, 79),
Property.PropertyType.HEX
)
);
public static Property<Integer> NORMAL = config.property(
"Normal color",
new Property<Integer>(
ColorHelper.getArgb(255, 182, 182, 182),
Property.PropertyType.HEX
)
);
// public static int NORMAL = ColorHelper.getArgb(255, 182, 182, 182);
public static int WHITE = ColorHelper.getArgb(255, 255, 255, 255); public static int WHITE = ColorHelper.getArgb(255, 255, 255, 255);
public static int NORMAL = ColorHelper.getArgb(255, 182, 182, 182);
public static TextRenderer textRenderer = null; public static TextRenderer textRenderer = null;
public static int getWhite(float alpha) { public static int getWhite(float alpha) {
return ((int) (alpha * 255) << 24) | (NORMAL & 0x00FFFFFF); return ((int) (alpha * 255) << 24) | (NORMAL.value & 0x00FFFFFF);
} }
public static SaturnAnimation[] getAnimations() { public static SaturnAnimation[] getAnimations() {
@@ -41,6 +41,7 @@ public class ConfigManager {
SaturnClient.LOGGER.info("Starting to load config..."); SaturnClient.LOGGER.info("Starting to load config...");
if (!configFile.exists()) { if (!configFile.exists()) {
configFile.createNewFile(); configFile.createNewFile();
Files.write(configFile.toPath(), "{}".getBytes());
} }
JsonObject jsonObject = JsonParser.parseString( JsonObject jsonObject = JsonParser.parseString(
@@ -97,6 +98,9 @@ public class ConfigManager {
case STRING: case STRING:
((Property<String>) p).value = c.getAsString(); ((Property<String>) p).value = c.getAsString();
break; break;
case HEX:
((Property<Integer>) p).value = c.getAsInt();
break;
default: default:
break; break;
} }
@@ -152,6 +156,11 @@ public class ConfigManager {
(String) property.value (String) property.value
); );
break; break;
case HEX:
propertyValue = new JsonPrimitive(
(Integer) property.value
);
break;
default: default:
SaturnClient.LOGGER.warn( SaturnClient.LOGGER.warn(
"Unknown property type for: " + propertyName "Unknown property type for: " + propertyName
@@ -10,12 +10,28 @@ public class Property<T> {
INTEGER, INTEGER,
FLOAT, FLOAT,
STRING, STRING,
HEX,
} }
public T value; public T value;
private PropertyType type;
public Property(T value) { public Property(T value) {
this.value = value; this.value = value;
if (value instanceof Boolean) {
type = PropertyType.BOOLEAN;
} else if (value instanceof Integer) {
type = PropertyType.INTEGER;
} else if (value instanceof Float) {
type = PropertyType.FLOAT;
} else if (value instanceof String) {
type = PropertyType.STRING;
}
}
public Property(T value, PropertyType type) {
this.value = value;
this.type = type;
} }
public boolean getBool() { public boolean getBool() {
@@ -46,20 +62,26 @@ public class Property<T> {
throw new IllegalStateException("Property does not contain a string"); throw new IllegalStateException("Property does not contain a string");
} }
public PropertyType getType() { public int getHexString() {
if (value instanceof Boolean) {
return PropertyType.BOOLEAN;
}
if (value instanceof Integer) {
return PropertyType.INTEGER;
}
if (value instanceof Float) {
return PropertyType.FLOAT;
}
if (value instanceof String) { if (value instanceof String) {
return PropertyType.STRING; String str = (String) value;
if (str.startsWith("0x") || str.startsWith("0X")) {
try {
return Integer.parseInt(str.substring(2), 16);
} catch (NumberFormatException e) {
throw new IllegalStateException(
"Invalid hexadecimal integer format"
);
} }
return null; }
}
throw new IllegalStateException(
"Property does not contain a valid hex integer"
);
}
public PropertyType getType() {
return type;
} }
public boolean matchesJson(JsonElement element) { public boolean matchesJson(JsonElement element) {
@@ -69,6 +91,12 @@ public class Property<T> {
if (value instanceof Integer && primitive.isNumber()) return true; if (value instanceof Integer && primitive.isNumber()) return true;
if (value instanceof Float && primitive.isNumber()) return true; if (value instanceof Float && primitive.isNumber()) return true;
if (value instanceof String && primitive.isString()) return true; if (value instanceof String && primitive.isString()) return true;
// Check if JSON string represents a valid hex integer
if (value instanceof String && primitive.isString()) {
String str = primitive.getAsString();
return str.matches("0x[0-9A-Fa-f]+");
}
} }
return false; return false;
} }
@@ -8,6 +8,7 @@ import org.saturnclient.saturnclient.config.Property;
import org.saturnclient.ui.SaturnUi; import org.saturnclient.ui.SaturnUi;
import org.saturnclient.ui.Textures; import org.saturnclient.ui.Textures;
import org.saturnclient.ui.components.SaturnFloat; import org.saturnclient.ui.components.SaturnFloat;
import org.saturnclient.ui.components.SaturnHex;
import org.saturnclient.ui.components.SaturnInteger; import org.saturnclient.ui.components.SaturnInteger;
import org.saturnclient.ui.components.SaturnString; import org.saturnclient.ui.components.SaturnString;
import org.saturnclient.ui.components.SaturnToggle; import org.saturnclient.ui.components.SaturnToggle;
@@ -151,6 +152,26 @@ public class ConfigEditor extends SaturnUi {
) )
); );
break; break;
case HEX:
configScroll.draw(
new SaturnText(
propName.substring(0, 1).toUpperCase() +
propName.substring(1)
)
.setX(modX)
.setY(modY)
.setScale(0.8f)
);
configScroll.draw(
new SaturnHex(
(Property<Integer>) prop,
(rectWidth / 2) - 17,
modY,
70
)
);
break;
} }
if (full) { if (full) {
@@ -50,7 +50,7 @@ public class ModMenu extends SaturnUi {
tabsX = (width - tabSize) / 2; tabsX = (width - tabSize) / 2;
draw( draw(
new SaturnClickableImage(Textures.SETTINGS, () -> { new SaturnClickableImage(Textures.SETTINGS, () -> {
System.out.println("Pressed"); client.setScreen(new SaturnConfigEditor());
}) })
.setX(tabsX) .setX(tabsX)
.setY(tabsY + 3) .setY(tabsY + 3)
@@ -0,0 +1,204 @@
package org.saturnclient.saturnclient.menus;
import java.util.Map;
import net.minecraft.text.Text;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.config.Property;
import org.saturnclient.ui.SaturnUi;
import org.saturnclient.ui.Textures;
import org.saturnclient.ui.components.SaturnFloat;
import org.saturnclient.ui.components.SaturnHex;
import org.saturnclient.ui.components.SaturnInteger;
import org.saturnclient.ui.components.SaturnString;
import org.saturnclient.ui.components.SaturnToggle;
import org.saturnclient.ui.widgets.SaturnScroll;
import org.saturnclient.ui.widgets.SaturnSprite;
import org.saturnclient.ui.widgets.SaturnText;
public class SaturnConfigEditor extends SaturnUi {
public SaturnConfigEditor() {
super(Text.of("Config editor"));
}
@SuppressWarnings("unchecked")
@Override
protected void init() {
int rectWidth = 330;
int rectHeight = 228;
int rectX = (width - rectWidth) / 2;
int rectY = (height - rectHeight + 15) / 2;
draw(
new SaturnSprite(Textures.SETTINGS_BG)
.setX(rectX)
.setY(rectY)
.setWidth(rectWidth)
.setHeight(rectHeight)
.setAnimations(SaturnClient.getAnimations())
);
int tabsX = (width - 43) / 2;
int tabsY = rectY - 17;
draw(
new SaturnSprite(Textures.TABS)
.setX(tabsX)
.setY(tabsY)
.setWidth(43)
.setHeight(15)
.setAnimations(SaturnClient.getAnimations())
);
SaturnScroll configScroll = new SaturnScroll();
int row = 0;
int col = 0;
for (Map.Entry<String, Property<?>> propEntry : SaturnClient.config
.getProperties()
.entrySet()) {
Property<?> prop = propEntry.getValue();
String propName = propEntry.getKey();
boolean full = isFull(prop);
if (full && col > 0) {
col = 0;
row++;
}
int modX = ((rectWidth / 2) - 17) * col;
int modY = 14 * row;
switch (prop.getType()) {
case BOOLEAN:
configScroll.draw(
new SaturnToggle((Property<Boolean>) prop)
.setX(modX)
.setY(modY)
);
configScroll.draw(
new SaturnText(
propName.substring(0, 1).toUpperCase() +
propName.substring(1)
)
.setX(modX + 18)
.setY(modY)
.setScale(0.8f)
);
break;
case INTEGER:
configScroll.draw(
new SaturnText(
propName.substring(0, 1).toUpperCase() +
propName.substring(1)
)
.setX(modX)
.setY(modY)
.setScale(0.8f)
);
configScroll.draw(
new SaturnInteger(
(Property<Integer>) prop,
(rectWidth / 2) - 17,
modY,
70
)
);
break;
case FLOAT:
configScroll.draw(
new SaturnText(
propName.substring(0, 1).toUpperCase() +
propName.substring(1)
)
.setX(modX)
.setY(modY)
.setScale(0.8f)
);
configScroll.draw(
new SaturnFloat(
(Property<Float>) prop,
(rectWidth / 2) - 17,
modY,
70
)
);
break;
case STRING:
configScroll.draw(
new SaturnText(
propName.substring(0, 1).toUpperCase() +
propName.substring(1)
)
.setX(modX)
.setY(modY)
.setScale(0.8f)
);
configScroll.draw(
new SaturnString(
(Property<String>) prop,
(rectWidth / 2) - 17,
modY,
70
)
);
break;
case HEX:
configScroll.draw(
new SaturnText(
propName.substring(0, 1).toUpperCase() +
propName.substring(1)
)
.setX(modX)
.setY(modY)
.setScale(0.8f)
);
configScroll.draw(
new SaturnHex(
(Property<Integer>) prop,
(rectWidth / 2) - 17,
modY,
70
)
);
break;
}
if (full) {
row++;
} else {
col++;
if (col > 1) {
col = 0;
row++;
}
}
}
draw(
configScroll
.setX(rectX + 17)
.setY(rectY + 10)
.setWidth(rectWidth - 17)
.setHeight(rectHeight - 10)
.setAnimations(SaturnClient.getAnimations())
);
super.init();
}
public static boolean isFull(Property<?> prop) {
switch (prop.getType()) {
case BOOLEAN:
return false;
default:
return true;
}
}
}
@@ -31,6 +31,11 @@ public class ArmorDisplay implements SaturnMod, HudMod {
75 75
); );
public static Property<Integer> fgColor = config.property(
"Foreground color",
new Property<>(SaturnClient.WHITE, Property.PropertyType.HEX)
);
private boolean renderItem(DrawContext context, ItemStack item, int y) { private boolean renderItem(DrawContext context, ItemStack item, int y) {
if (item.isEmpty()) { if (item.isEmpty()) {
return false; return false;
@@ -52,7 +57,7 @@ public class ArmorDisplay implements SaturnMod, HudMod {
"" + (item.getMaxDamage() - item.getDamage()), "" + (item.getMaxDamage() - item.getDamage()),
0, 0,
0, 0,
SaturnClient.WHITE, fgColor.value,
false false
); );
@@ -21,6 +21,11 @@ public class Coordinates implements SaturnMod, HudMod {
); );
private static ModDimensions dimensions = new ModDimensions(config); private static ModDimensions dimensions = new ModDimensions(config);
public static Property<Integer> fgColor = config.property(
"Foreground color",
new Property<>(SaturnClient.WHITE, Property.PropertyType.HEX)
);
public Coordinates() {} public Coordinates() {}
public void renderDummy(DrawContext context) { public void renderDummy(DrawContext context) {
@@ -33,7 +38,7 @@ public class Coordinates implements SaturnMod, HudMod {
playerX + " " + playerY + " " + playerZ, playerX + " " + playerY + " " + playerZ,
0, 0,
0, 0,
SaturnClient.WHITE, fgColor.value,
false false
); );
@@ -54,7 +59,7 @@ public class Coordinates implements SaturnMod, HudMod {
playerX + " " + playerY + " " + playerZ, playerX + " " + playerY + " " + playerZ,
0, 0,
0, 0,
SaturnClient.WHITE, fgColor.value,
false false
); );
} }
@@ -108,7 +108,9 @@ public class SaturnFloat extends SaturnWidget {
0, 0,
this.width, this.width,
this.height, this.height,
focused ? SaturnClient.COLOR : SaturnClient.getWhite(this.alpha) focused
? SaturnClient.COLOR.value
: SaturnClient.getWhite(this.alpha)
); );
int scrollOffset = getScrollOffset(); int scrollOffset = getScrollOffset();
@@ -0,0 +1,146 @@
package org.saturnclient.ui.components;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderLayer;
import org.lwjgl.glfw.GLFW;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.config.Property;
import org.saturnclient.ui.SaturnUi;
import org.saturnclient.ui.SaturnWidget;
import org.saturnclient.ui.Textures;
public class SaturnHex extends SaturnWidget {
private String text = "#"; // Always starts with '#'
public Property<Integer> prop;
public int cursorPosition = 1; // After '#'
private final TextRenderer textRenderer = MinecraftClient.getInstance()
.textRenderer;
public SaturnHex(Property<Integer> prop, int x, int y, int width) {
this.x = x;
this.y = y;
this.width = width;
this.prop = prop;
this.text = intToHex(prop.value); // Convert stored int to hex
this.height = textRenderer.fontHeight + 4;
this.scale = 0.8f;
}
@Override
public void click(int mouseX, int mouseY) {
cursorPosition = Math.min(7, text.length()); // Keep cursor inside hex length
}
@Override
public void charTyped(char chr) {
if (isHexChar(chr) && text.length() < 7) { // Limit to 6 hex digits + '#'
text =
text.substring(0, cursorPosition) +
chr +
text.substring(cursorPosition);
cursorPosition++;
if (text.length() == 7) { // Only update value when full hex is entered
prop.value = hexToInt(text);
}
}
}
@Override
public void keyPressed(int keyCode, int scanCode, int modifiers) {
if (keyCode == GLFW.GLFW_KEY_BACKSPACE && cursorPosition > 1) { // Prevent deleting '#'
text =
text.substring(0, cursorPosition - 1) +
text.substring(cursorPosition);
cursorPosition--;
} else if (keyCode == GLFW.GLFW_KEY_LEFT && cursorPosition > 1) {
cursorPosition--;
} else if (
keyCode == GLFW.GLFW_KEY_RIGHT && cursorPosition < text.length()
) {
cursorPosition++;
}
if (text.length() == 1) { // Reset if empty (keep '#')
text = "#";
cursorPosition = 1;
}
if (text.length() == 7) { // Update only when valid hex
prop.value = hexToInt(text);
}
}
@Override
public void render(
DrawContext context,
boolean hovering,
int mouseX,
int mouseY
) {
context.drawGuiTexture(
RenderLayer::getGuiTextured,
Textures.BUTTON_BORDER,
0,
0,
this.width,
this.height,
focused
? SaturnClient.COLOR.value
: SaturnClient.getWhite(this.alpha)
);
int textColor = focused ? 0xFFFFFF : 0xAAAAAA;
context.drawText(
textRenderer,
SaturnUi.text(text),
2,
2,
textColor,
false
);
if (focused) {
int cursorX =
2 +
textRenderer.getWidth(
SaturnUi.text(text.substring(0, cursorPosition))
);
context.fill(
cursorX,
2,
cursorX + 1,
textRenderer.fontHeight + 4,
0xFFFFFFFF
);
}
}
public void clearText() {
text = "#";
cursorPosition = 1;
prop.value = 0xFFFFFFFF; // Default white
}
private boolean isHexChar(char chr) {
return (
(chr >= '0' && chr <= '9') ||
(chr >= 'A' && chr <= 'F') ||
(chr >= 'a' && chr <= 'f')
);
}
public static int hexToInt(String hex) {
hex = hex.replace("#", "");
int rgb = Integer.parseInt(hex, 16);
return (0xFF << 24) | rgb;
}
public static String intToHex(int color) {
int rgb = color & 0xFFFFFF;
return String.format("#%06X", rgb).toLowerCase();
}
}
@@ -108,7 +108,9 @@ public class SaturnInteger extends SaturnWidget {
0, 0,
this.width, this.width,
this.height, this.height,
focused ? SaturnClient.COLOR : SaturnClient.getWhite(this.alpha) focused
? SaturnClient.COLOR.value
: SaturnClient.getWhite(this.alpha)
); );
int scrollOffset = getScrollOffset(); int scrollOffset = getScrollOffset();
@@ -30,7 +30,7 @@ public class SaturnModComp extends SaturnWidget {
boolean hovering_settings = settingsHovering(mouseX, mouseY); boolean hovering_settings = settingsHovering(mouseX, mouseY);
int color = !hovering_settings && (enabled || hovering) int color = !hovering_settings && (enabled || hovering)
? SaturnClient.COLOR ? SaturnClient.COLOR.value
: SaturnClient.getWhite(alpha); : SaturnClient.getWhite(alpha);
int size = 12; int size = 12;
@@ -47,7 +47,7 @@ public class SaturnModComp extends SaturnWidget {
20, 20,
86, 86,
20, 20,
SaturnClient.COLOR SaturnClient.COLOR.value
); );
} }
@@ -100,7 +100,7 @@ public class SaturnModComp extends SaturnWidget {
7, 7,
7, 7,
hovering_settings hovering_settings
? SaturnClient.COLOR ? SaturnClient.COLOR.value
: SaturnClient.getWhite(alpha) : SaturnClient.getWhite(alpha)
); );
} }
@@ -92,7 +92,9 @@ public class SaturnString extends SaturnWidget {
0, 0,
this.width, this.width,
this.height, this.height,
focused ? SaturnClient.COLOR : SaturnClient.getWhite(this.alpha) focused
? SaturnClient.COLOR.value
: SaturnClient.getWhite(this.alpha)
); );
int scrollOffset = getScrollOffset(); int scrollOffset = getScrollOffset();
@@ -25,7 +25,7 @@ public class SaturnToggle extends SaturnWidget {
int mouseY int mouseY
) { ) {
int color = prop.value int color = prop.value
? SaturnClient.COLOR ? SaturnClient.COLOR.value
: SaturnClient.getWhite(alpha); : SaturnClient.getWhite(alpha);
int w = 13; int w = 13;
int h = 6; int h = 6;
@@ -40,7 +40,8 @@ public class SaturnButton extends SaturnWidget {
MinecraftClient minecraftClient = MinecraftClient.getInstance(); MinecraftClient minecraftClient = MinecraftClient.getInstance();
int hoverColor = int hoverColor =
((int) (alpha * 255) << 24) | (SaturnClient.COLOR & 0x00FFFFFF); ((int) (alpha * 255) << 24) |
(SaturnClient.COLOR.value & 0x00FFFFFF);
if (background) { if (background) {
RenderSystem.setShaderTexture(0, Textures.BUTTON); RenderSystem.setShaderTexture(0, Textures.BUTTON);
@@ -14,7 +14,7 @@ public class SaturnClickableImage extends SaturnWidget {
public boolean selected = false; public boolean selected = false;
public Consumer<SaturnClickableImage> onPress; public Consumer<SaturnClickableImage> onPress;
public int color = SaturnClient.getWhite(1.0f); public int color = SaturnClient.getWhite(1.0f);
public int hoverColor = SaturnClient.COLOR; public int hoverColor = SaturnClient.COLOR.value;
public SaturnClickableImage( public SaturnClickableImage(
Identifier texture, Identifier texture,
@@ -14,7 +14,7 @@ public class SaturnClickableSprite extends SaturnWidget {
public boolean selected = false; public boolean selected = false;
public Consumer<SaturnClickableSprite> onPress; public Consumer<SaturnClickableSprite> onPress;
public int color = SaturnClient.getWhite(1.0f); public int color = SaturnClient.getWhite(1.0f);
public int hoverColor = SaturnClient.COLOR; public int hoverColor = SaturnClient.COLOR.value;
public SaturnClickableSprite( public SaturnClickableSprite(
Identifier sprite, Identifier sprite,
@@ -47,7 +47,8 @@ public class SaturnImageButton extends SaturnButton {
super.render(context, hovering, mouseX, mouseY); super.render(context, hovering, mouseX, mouseY);
int hoverColor = int hoverColor =
((int) (alpha * 255) << 24) | (SaturnClient.COLOR & 0x00FFFFFF); ((int) (alpha * 255) << 24) |
(SaturnClient.COLOR.value & 0x00FFFFFF);
context.drawTexture( context.drawTexture(
RenderLayer::getGuiTextured, RenderLayer::getGuiTextured,