This commit is contained in:
retuci0 committed 2026-05-09 20:55:38 +02:00
1 parent b2bc2b36ab
commit 321505657c
30 files changed
+372 -242

No files matched your search

+7 -3
View File
@@ -1,15 +1,19 @@
# v5.0!!!
# v5.1
## novedades
### adiciones
- panel individual para cada categoría de módulos
#### módulos nuevos:
### arreglos / mejoras
- añadido el grupo de ajustes `módulo` para distinguir los ajustes individuales de cada módulo con los comunes;
y añadido la opción de notificar el alternado de estado de un módulo mediante widgets de notificaciones
- varios arreglos relacionados con la config.
- cambiado `manos` de categoría: de "jugador" a "renderizado"
- `don quijote` ya funciona correctamente, en cuanto a los amigos
## problemas reconocidos
- lo de siempre.
+1 -1
View File
@@ -10,6 +10,6 @@ discord_rpc_version=1.0.3
neutrino_version=1.1.0
jdk_version=25
mod_version=5.0
mod_version=5.1
maven_group=me.retucio
archives_base_name=sputnik
@@ -24,7 +24,6 @@ import me.retucio.sputnik.ui.screen.UpdateScreen;
import me.retucio.sputnik.ui.widgets.buttons.settings.BindButton;
import me.retucio.sputnik.ui.widgets.buttons.SettingButton;
import me.retucio.sputnik.ui.widgets.buttons.settings.TextButton;
import me.retucio.sputnik.ui.widgets.misc.NotificationWidget;
import me.retucio.sputnik.ui.widgets.panels.settings.ClientSettingsPanel;
import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
import me.retucio.sputnik.ui.widgets.Button;
@@ -56,8 +55,9 @@ import org.lwjgl.glfw.GLFW;
public class Sputnik implements ClientModInitializer {
// cosas necesarias
public static final Sputnik INSTANCE = new Sputnik();
// cosas del mod
public static final EventBus EVENT_BUS = new EventBus();
public static final Logger LOGGER = LogManager.getLogger(Sputnik.class);
public static final long LAUNCH_TIME = System.currentTimeMillis();
@@ -85,7 +85,7 @@ public class Sputnik implements ClientModInitializer {
mc = Minecraft.getInstance();
ConfigManager.load();
VersionChecker.check();
VersionChecker.INSTANCE.check();
EVENT_BUS.subscribe(this);
@@ -250,9 +250,9 @@ public class Sputnik implements ClientModInitializer {
@EventListener
// notificar al usuario de que hay una actualización disponible, si la hay
public void onSetScreen(OpenScreenEvent event) {
if (VersionChecker.shouldShowScreen && event.getScreen() instanceof TitleScreen) {
if (VersionChecker.INSTANCE.shouldShowScreen && event.getScreen() instanceof TitleScreen) {
event.cancel();
VersionChecker.shouldShowScreen = false;
VersionChecker.INSTANCE.shouldShowScreen = false;
mc.execute(() -> mc.screen = new UpdateScreen());
}
}
@@ -100,7 +100,7 @@ public class ClientConfig {
extendablePanels.put(event.getPanel().category.toString(), new PanelData(
event.getPanel().getX(),
event.getPanel().getY(),
event.getPanel().extended));
event.getPanel().isExtended()));
ConfigManager.save();
}
@@ -109,7 +109,7 @@ public class ClientConfig {
extendablePanels.replace(event.getPanel().category.toString(), new PanelData(
event.getPanel().getX(),
event.getPanel().getY(),
event.getPanel().extended));
event.getPanel().isExtended()));
ConfigManager.save();
}
@@ -118,7 +118,7 @@ public class ClientConfig {
extendablePanels.put("ajustes", new PanelData(
ClickGui.INSTANCE.getClientSettingsPanel().getX(),
ClickGui.INSTANCE.getClientSettingsPanel().getY(),
ClickGui.INSTANCE.getClientSettingsPanel().extended));
ClickGui.INSTANCE.getClientSettingsPanel().isExtended()));
ConfigManager.save();
}
@@ -127,7 +127,7 @@ public class ClientConfig {
extendablePanels.replace("ajustes", new PanelData(
ClickGui.INSTANCE.getClientSettingsPanel().getX(),
ClickGui.INSTANCE.getClientSettingsPanel().getY(),
ClickGui.INSTANCE.getClientSettingsPanel().extended));
ClickGui.INSTANCE.getClientSettingsPanel().isExtended()));
ConfigManager.save();
}
@@ -136,7 +136,7 @@ public class ClientConfig {
extendablePanels.put("amigos", new PanelData(
ClickGui.INSTANCE.getFriendsPanel().getX(),
ClickGui.INSTANCE.getFriendsPanel().getY(),
ClickGui.INSTANCE.getFriendsPanel().extended));
ClickGui.INSTANCE.getFriendsPanel().isExtended()));
ConfigManager.save();
}
@@ -145,7 +145,7 @@ public class ClientConfig {
extendablePanels.replace("amigos", new PanelData(
ClickGui.INSTANCE.getFriendsPanel().getX(),
ClickGui.INSTANCE.getFriendsPanel().getY(),
ClickGui.INSTANCE.getFriendsPanel().extended));
ClickGui.INSTANCE.getFriendsPanel().isExtended()));
ConfigManager.save();
}
@@ -247,10 +247,10 @@ public class ConfigManager {
panelData = config.extendablePanels.get(mp.category.toString());
}
if (panel instanceof ClientSettingsPanel) {
panelData = config.extendablePanels.get("S");
panelData = config.extendablePanels.get("ajustes");
}
if (panel instanceof FriendsPanel) {
panelData = config.extendablePanels.get("F");
panelData = config.extendablePanels.get("amigos");
}
if (panelData != null) {
@@ -258,13 +258,13 @@ public class ConfigManager {
panel.setY(panelData.y());
if (panel instanceof ModulePanel mPanel) {
mPanel.extended = panelData.extended();
mPanel.setExtended(panelData.extended());
}
if (panel instanceof ClientSettingsPanel sPanel) {
sPanel.extended = panelData.extended();
sPanel.setExtended(panelData.extended());
}
if (panel instanceof FriendsPanel fPanel) {
fPanel.extended = panelData.extended();
fPanel.setExtended(panelData.extended());
}
}
}
@@ -5,7 +5,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
import me.retucio.sputnik.event.render.RenderHeldItemEvent;
import me.retucio.sputnik.event.render.RenderArmEvent;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.player.HandView;
import me.retucio.sputnik.module.modules.render.HandView;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.ItemInHandRenderer;
import net.minecraft.client.renderer.SubmitNodeCollector;
@@ -9,6 +9,7 @@ import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.module.setting.Setting;
import me.retucio.sputnik.ui.hud.HudRenderer;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.client.Minecraft;
import org.lwjgl.glfw.GLFW;
@@ -29,29 +30,52 @@ public class Module {
private boolean saveSettings = true;
private boolean searchMatch = true;
// ajustes que están en todos los módulos
protected KeySetting bind = new KeySetting(
"tecla",
"tecla asignada al módulo, ESC para desactivar",
GLFW.GLFW_KEY_UNKNOWN
);
// dejar al usuario elegir si el módulo debería apagarse tras soltar su tecla asignada, o si la tecla debería alternar su estado
protected EnumSetting<KeyModes> keyMode = new EnumSetting<>("modo de tecla", "cómo interpretar la tecla configurada", KeyModes.class, KeyModes.TOGGLE);
protected KeySetting bind = new KeySetting("tecla", "tecla asignada al módulo, ESC para desactivar", GLFW.GLFW_KEY_UNKNOWN);
protected BooleanSetting notify = new BooleanSetting("notificar", "notificar en el chat al activar / desactivar", true);
protected EnumSetting<KeyMode> keyMode = new EnumSetting<>(
"modo de tecla",
"cómo interpretar la tecla configurada",
KeyMode.class, KeyMode.TOGGLE
);
protected BooleanSetting notify = new BooleanSetting(
"notificar",
"notificar al activar / desactivar",
true
);
protected EnumSetting<NotifyMode> notifyMode = new EnumSetting<>(
"modo de notificación",
"cómo notificar cuando se activa / desactiva",
NotifyMode.class, NotifyMode.WIDGET
);
protected final List<SettingGroup> sgs = new ArrayList<>();
protected final SettingGroup sgModule = addSg(new SettingGroup("módulo", false));
protected final SettingGroup sgGeneral = addSg(new SettingGroup("general", true));
protected Minecraft mc = Minecraft.getInstance();
protected static final Minecraft mc = Minecraft.getInstance();
public Module(String name, String description, Category category) {
this.name = name;
this.description = description;
this.category = category;
sgGeneral.addAll(bind, keyMode, notify);
sgModule.addAll(bind, keyMode, notify, notifyMode);
}
public Module(String name, String description, Category category, int key) {
this.name = name;
this.description = description;
this.category = category;
sgGeneral.addAll(bind, keyMode, notify);
sgModule.addAll(bind, keyMode, notify, notifyMode);
this.bind.setDefaultValue(key);
// puto marcos
@@ -69,6 +93,10 @@ public class Module {
return sg;
}
public void removeSg(SettingGroup sg) {
sgs.remove(sg);
}
public List<SettingGroup> getSgs() {
return sgs;
}
@@ -86,6 +114,10 @@ public class Module {
return sgGeneral;
}
public SettingGroup getSgModule() {
return sgModule;
}
public List<Setting<?>> getSettings() {
List<Setting<?>> settings = new ArrayList<>();
sgs.forEach(sg -> sg.forEach(settings::add));
@@ -102,27 +134,33 @@ public class Module {
}
public void onEnable() {
if (notify.getValue()) ChatUtil.info(getName() + " fue activado");
for (Method method : getClass().getDeclaredMethods())
if (notify.getValue()) {
if (notifyMode.is(NotifyMode.CHAT)) ChatUtil.info(getName() + " fue activado");
else HudRenderer.pushNotification(getName() + " fue activado", getName() + "fue activado.");
}
for (Method method : getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(EventListener.class)) {
Sputnik.EVENT_BUS.subscribe(this);
break;
}
Sputnik.EVENT_BUS.post(new ToggleModuleEvent(this));
}
}
public void onDisable() {
if (notify.getValue()) ChatUtil.info(getName() + " fue desactivado");
if (Sputnik.EVENT_BUS.isSubscribed(this))
if (notifyMode.is(NotifyMode.CHAT)) ChatUtil.info(getName() + " fue desactivado");
else HudRenderer.pushNotification(getName() + " fue desactivado", getName() + "fue desactivado.");
if (Sputnik.EVENT_BUS.isSubscribed(this)) {
Sputnik.EVENT_BUS.unsubscribe(this);
Sputnik.EVENT_BUS.post(new ToggleModuleEvent(this));
}
}
// tick (ejecutado 20 veces por segundo)
public void onTick() {}
// getters y setters
public String getName() {
return name;
}
@@ -156,7 +194,7 @@ public class Module {
}
public boolean shouldToggleOnBindRelease() {
return keyMode.is(KeyModes.HOLD);
return keyMode.is(KeyMode.HOLD);
}
public boolean shouldSaveSettings() {
@@ -192,13 +230,22 @@ public class Module {
this.searchMatch = searchMatch;
}
public enum KeyModes {
public enum KeyMode {
HOLD("mantener"),
TOGGLE("alternar");
// ojalá hubiera una manera de evitar repetirse con esto pero no la hay (creo) ...
private final String name;
KeyModes(String name) { this.name = name; }
KeyMode(String name) { this.name = name; }
@Override public String toString() { return name; }
}
public enum NotifyMode {
CHAT("por chat"),
WIDGET("por widget");
private final String name;
NotifyMode(String name) { this.name = name; }
@Override public String toString() { return name; }
}
}
@@ -39,8 +39,8 @@ public class Freelook extends Module {
Category.CAMERA,
GLFW.GLFW_KEY_B);
keyMode.setDefaultValue(KeyModes.HOLD);
keyMode.setValue(KeyModes.HOLD);
keyMode.setDefaultValue(KeyMode.HOLD);
keyMode.setValue(KeyMode.HOLD);
notify.setDefaultValue(false);
notify.setValue(false);
@@ -51,8 +51,8 @@ public class Zoom extends Module {
Category.CAMERA,
GLFW.GLFW_KEY_F);
keyMode.setDefaultValue(KeyModes.HOLD);
keyMode.setValue(KeyModes.HOLD);
keyMode.setDefaultValue(KeyMode.HOLD);
keyMode.setValue(KeyMode.HOLD);
notify.setDefaultValue(false);
notify.setValue(false);
@@ -114,7 +114,7 @@ public class SpearKill extends Module {
mc.player.getBoundingBox().expandTowards(lookVec.scale(rayLength)),
e -> e instanceof LivingEntity
&& e.isAlive() && e != mc.player
&& (!ignoreFriends.getValue() || FriendManager.INSTANCE.isFriend(e)));
&& (!ignoreFriends.getValue() || !FriendManager.INSTANCE.isFriend(e)));
candidates.sort(Comparator.comparingDouble(e ->
eyePos.distanceToSqr(e.getBoundingBox().getCenter())));
@@ -20,7 +20,7 @@ public class HitboxDesync extends Module {
public HitboxDesync() {
super("desync de hitbox", "exploit chino", Category.MOVEMENT);
keyMode.setDefaultValue(KeyModes.HOLD);
keyMode.setDefaultValue(KeyMode.HOLD);
}
@Override
@@ -26,7 +26,7 @@ import org.lwjgl.glfw.GLFW;
public class AirPlace extends Module {
private final SettingGroup sgScroll = addSg(new SettingGroup("scrolleo", true));
private final SettingGroup sgRender = addSg(new SettingGroup("extractRenderState", true));
private final SettingGroup sgRender = addSg(new SettingGroup("renderizado", true));
// general
@@ -19,7 +19,7 @@ public class KeyPearl extends Module {
public KeyPearl() {
super("tecla de perla", "lanza una perla con una tecla", Category.PLAYER);
keyMode.setValue(KeyModes.HOLD);
keyMode.setValue(KeyMode.HOLD);
}
private int prevSlot = -1;
@@ -64,7 +64,7 @@ public class NoFall extends Module {
private final NumberSetting distance = sgGeneral.add(new NumberSetting(
"distancia",
"distancia mínima de caída para aplicar el amortiguamiento",
"distancia mínima de caída para aplicar la amortiguación",
3,
3,
23,
@@ -1,4 +1,4 @@
package me.retucio.sputnik.module.modules.player;
package me.retucio.sputnik.module.modules.render;
import com.github.retucio.neutrino.EventListener;
import com.mojang.blaze3d.vertex.PoseStack;
@@ -97,9 +97,11 @@ public class HandView extends Module {
0, -180, 180, 1));
public HandView() {
super("manos",
super(
"manos",
"modifica la manera en la que se renderizan las manos",
Category.PLAYER);
Category.RENDER
);
}
@EventListener
@@ -72,7 +72,7 @@ public abstract class Setting<T> {
}
public void setValue(T value) {
if (this.value != value) {
if (!this.value.equals(value)) {
this.value = value;
fireUpdateEvent();
@@ -12,7 +12,7 @@ import java.util.List;
public class SettingGroup implements Iterable<Setting<?>> {
private Module module;
private final String name;
private String name;
private boolean extended;
final List<Setting<?>> settings = new ArrayList<>(1);
@@ -56,6 +56,8 @@ public class SettingGroup implements Iterable<Setting<?>> {
return name;
}
public void setName(String name) { this.name = name; }
public boolean isExtended() {
return extended;
}
@@ -27,7 +27,6 @@ import me.retucio.sputnik.ui.widgets.Widget;
import me.retucio.sputnik.ui.widgets.misc.ScrollBarWidget;
import me.retucio.sputnik.ui.widgets.misc.SearchBarWidget;
import me.retucio.sputnik.ui.widgets.panels.settings.FriendSettingsPanel;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.KeyUtil;
import me.retucio.sputnik.util.MiscUtil;
@@ -43,7 +42,6 @@ import org.jspecify.annotations.NonNull;
import org.lwjgl.glfw.GLFW;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@@ -76,8 +74,6 @@ public class ClickGui extends Screen {
super(Component.literal("interfaz"));
Sputnik.EVENT_BUS.subscribe(this);
settingsPanels.add(clientSettingsPanel);
int x = 4;
for (Category category : Category.values()) {
modulePanels.add(new ModulePanel(category, x, 40, 100, 20));
@@ -99,6 +95,7 @@ public class ClickGui extends Screen {
// actualizar la posición de renderizado vertical de los paneles cada tick
friendsPanel.updateRenderY(scrollOffset);
clientSettingsPanel.updateRenderY(scrollOffset);
for (ModulePanel mp : modulePanels) {
mp.updateRenderY(scrollOffset);
}
@@ -125,6 +122,9 @@ public class ClickGui extends Screen {
friendsPanel.render(gui, mouseX, mouseY, delta);
friendsPanel.updatePosition(mouseX, mouseY);
clientSettingsPanel.render(gui, mouseX, mouseY, delta);
clientSettingsPanel.updatePosition(mouseX, mouseY);
filterSearchResults();
renderBottomGradient(gui, scrollOffset);
@@ -152,13 +152,25 @@ public class ClickGui extends Screen {
private int calculateContentHeight() {
int bottom = mc.getWindow().getGuiScaledHeight();
for (ModulePanel mp : modulePanels) {
bottom = mp.getY() + mp.getH() + mp.getTotalHeight();
int mpBottom = mp.getY() + mp.getH();
if (mp.isExtended()) mpBottom += mp.getTotalHeight();
bottom = Math.max(bottom, mpBottom);
}
for (SettingsPanel sp : settingsPanels) {
bottom = Math.max(bottom, sp.getY() + sp.getH() + sp.getTotalHeight());
}
int friendsBottom = friendsPanel.getY() + friendsPanel.getH()
+ (friendsPanel.isExtended() ? friendsPanel.getTotalHeight() : 0);
bottom = Math.max(bottom, friendsBottom);
int clientBottom = clientSettingsPanel.getY() + clientSettingsPanel.getH()
+ (clientSettingsPanel.isExtended() ? clientSettingsPanel.getTotalHeight() : 0);
bottom = Math.max(bottom, clientBottom);
return bottom + 20; // padding
}
@@ -167,15 +179,14 @@ public class ClickGui extends Screen {
int x = (int) click.x();
int y = (int) click.y();
ChatUtil.info(x + " " + y);
miscWidgets.forEach(w -> w.mouseClicked(
x, y, click.button()
));
// detectar clics sobre los marcos
// detectar clics sobre los paneles
friendsPanel.mouseClicked(x, y, click.button());
for (ModulePanel mp : new ArrayList<>(modulePanels)) {
clientSettingsPanel.mouseClicked(x, y, click.button());
for (ModulePanel mp : modulePanels.reversed()) {
mp.mouseClicked(x, y, click.button());
}
for (SettingsPanel sp : new ArrayList<>(settingsPanels)) {
@@ -193,9 +204,10 @@ public class ClickGui extends Screen {
miscWidgets.forEach(w -> w.mouseReleased(
x, y, click.button()));
// registrar cuándo se suelta el clic, en cada marco respectivamente
// registrar cuándo se suelta el clic, en cada panel respectivamente
friendsPanel.mouseReleased(x, y, click.button());
for (ModulePanel mp : new ArrayList<>(modulePanels)) {
clientSettingsPanel.mouseReleased(x, y, click.button());
for (ModulePanel mp : modulePanels.reversed()) {
mp.mouseReleased(x, y, click.button());
}
for (SettingsPanel sp : new ArrayList<>(settingsPanels)) {
@@ -211,6 +223,8 @@ public class ClickGui extends Screen {
(int) click.x(),
(int) click.y()));
// MPs?
for (SettingsPanel sp : new ArrayList<>(settingsPanels))
sp.mouseDragged((int) click.x(), (int) click.y());
@@ -230,7 +244,7 @@ public class ClickGui extends Screen {
@EventListener
public void onMouseMiddleButton(MouseClickEvent event) {
// mover todos los marcos a un punto visible al presionar shift + la rueda del ratón
// mover todos los paneles a un punto visible al presionar shift + la rueda del ratón
if (Sputnik.mc.screen != this || event.getButton() != 2 || !KeyUtil.isKeyDown(GLFW.GLFW_KEY_LEFT_SHIFT)) return;
int h = Sputnik.mc.getWindow().getGuiScaledHeight();
@@ -241,14 +255,17 @@ public class ClickGui extends Screen {
if (correction != 0) {
modulePanels.forEach(mp -> mp.setY(mp.getY() + correction));
settingsPanels.forEach(sp -> sp.setY(sp.getY() + correction));
friendsPanel.setY(friendsPanel.getY() + correction);
clientSettingsPanel.setY(clientSettingsPanel.getY() + correction);
}
}
public void filterSearchResults() {
if (!clientSettings.searchBar.getValue()) return;
String searchInput = searchBar.getSearchInput().trim();
if (!clientSettings.matchCase.getValue()) searchInput = searchInput.toLowerCase();
if (!clientSettings.matchCase.getValue()) {
searchInput = searchInput.toLowerCase();
}
for (ModulePanel mp : modulePanels) {
for (Button b : mp.getButtons()) {
@@ -319,6 +336,26 @@ public class ClickGui extends Screen {
friend.setSearchMatch(name.contains(searchInput) || uuid.contains(searchInput));
}
for (Button b : clientSettingsPanel.getButtons()) {
if (!(b instanceof SettingButton<?> sb)) continue;
Setting<?> setting = sb.getSetting();
if (searchInput.isEmpty()) {
setting.setSearchMatch(true);
continue;
}
String name = MiscUtil.removeAccentMarks(setting.getName());
String desc = MiscUtil.removeAccentMarks(setting.getDescription());
if (!clientSettings.matchCase.getValue()) {
name = name.toLowerCase();
desc = desc.toLowerCase();
}
setting.setSearchMatch(name.contains(searchInput) || desc.contains(searchInput));
}
}
public SettingsPanel getSettingsPanelOfModule(Module module) {
@@ -463,27 +500,12 @@ public class ClickGui extends Screen {
// getters y setters de widgets
public List<ModulePanel> getModulePanels() {
return modulePanels;
}
public ClientSettingsPanel getClientSettingsPanel() {
return clientSettingsPanel;
}
public FriendsPanel getFriendsPanel() {
return friendsPanel;
}
public List<Widget> getMiscWidgets() { return miscWidgets; }
public List<SettingsPanel> getSettingsPanels() {
return settingsPanels;
}
public SearchBarWidget getSearchBar() {
return searchBar;
}
public List<ModulePanel> getModulePanels() { return modulePanels; }
public List<SettingsPanel> getSettingsPanels() { return settingsPanels; }
public ClientSettingsPanel getClientSettingsPanel() { return clientSettingsPanel; }
public FriendsPanel getFriendsPanel() { return friendsPanel; }
public SearchBarWidget getSearchBar() { return searchBar; }
public ScrollBarWidget getScrollBar() { return scrollBar; }
public void setAnyFocused(boolean anyFocused) {
this.anyFocused = anyFocused;
@@ -31,7 +31,7 @@ public class UpdateScreen extends Screen {
);
private final Component outdatedText = Component.literal("version desactualizada: " + Sputnik.MOD_VERSION);
private final Component updateText = Component.literal("descarga la última versión (" + VersionChecker.getLatestVersion() + ") desde aquí:");
private final Component updateText = Component.literal("descarga la última versión (" + VersionChecker.INSTANCE.getLatestVersion() + ") desde aquí:");
private final Button idgafButton = Button.builder(
Component.literal("me la pela"),
@@ -2,6 +2,7 @@ package me.retucio.sputnik.ui.widgets.buttons.settings;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.OptionSetting;
import me.retucio.sputnik.ui.widgets.buttons.SettingButton;
@@ -67,6 +68,8 @@ public class ChooseButton<T> extends SettingButton<OptionSetting<T>> {
}
private void rebuildDummy() {
dummy.removeSg(dummy.getSgModule());
dummy.getSgGeneral().setName("opciones");
dummy.getSgGeneral().getSettings().clear();
optionButtons.clear();
@@ -83,7 +83,8 @@ public class ListButton<T> extends SettingButton<ListSetting<T>> {
}
private void rebuildDummy() {
dummy.getSettings().clear();
dummy.removeSg(dummy.getSgModule());
dummy.getSgGeneral().setName("opciones");
dummy.getSgGeneral().getSettings().clear();
optionButtons.clear();
@@ -0,0 +1,32 @@
package me.retucio.sputnik.ui.widgets.panels;
import me.retucio.sputnik.ui.widgets.Button;
import me.retucio.sputnik.ui.widgets.Panel;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component;
public abstract class CloseablePanel<B extends Button> extends Panel<B> {
protected static final int PADDING = 4;
public CloseablePanel(String title, int x, int y, int w, int h) {
super(title, x, y, w, h);
}
// dibujar la "x"
protected void drawCloseButton(GuiGraphicsExtractor gui, int mouseX, int mouseY, int color) {
gui.text(mc.font, Component.literal("×"),
x + w - mc.font.width("×") - 2 * PADDING,
renderY + (h / 2) - (mc.font.lineHeight / 2),
color, true);
}
protected boolean isCloseButtonHovered(int mouseX, int mouseY) {
int closeX = x + w - mc.font.width("×") - 2 * PADDING;
int closeY = renderY + (h / 2) - (mc.font.lineHeight / 2);
return mouseX >= closeX && mouseX <= closeX + mc.font.width("×") &&
mouseY >= closeY && mouseY <= closeY + mc.font.lineHeight;
}
public abstract void onClose();
}
@@ -0,0 +1,45 @@
package me.retucio.sputnik.ui.widgets.panels;
import me.retucio.sputnik.ui.widgets.Button;
import me.retucio.sputnik.ui.widgets.Panel;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component;
public abstract class ExtendablePanel<B extends Button> extends Panel<B> {
protected boolean extended;
public ExtendablePanel(String title, int x, int y, int w, int h) {
super(title, x, y, w, h);
this.extended = true;
}
protected void drawExpandCollapse(GuiGraphicsExtractor gui, int mouseX, int mouseY) {
String symbol = extended ? "-" : "+";
int textWidth = mc.font.width(symbol);
gui.text(mc.font, Component.literal(symbol),
x + w - textWidth - 8,
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
}
protected boolean isExpandButtonHovered(int mouseX, int mouseY) {
String symbol = extended ? "-" : "+";
int textWidth = mc.font.width(symbol);
int buttonX = x + w - textWidth - 8;
int buttonY = renderY + (h / 2) - (mc.font.lineHeight / 2);
return mouseX >= buttonX && mouseX <= buttonX + textWidth &&
mouseY >= buttonY && mouseY <= buttonY + mc.font.lineHeight;
}
public void toggleExtended() {
extended = !extended;
}
public boolean isExtended() {
return extended;
}
public void setExtended(boolean extended) {
this.extended = extended;
}
}
@@ -4,30 +4,24 @@ import com.github.retucio.neutrino.EventListener;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.sputnik.FriendEvent;
import me.retucio.sputnik.event.sputnik.FriendPanelEvent;
import me.retucio.sputnik.event.sputnik.ModulePanelEvent;
import me.retucio.sputnik.friend.Friend;
import me.retucio.sputnik.friend.FriendManager;
import me.retucio.sputnik.ui.screen.ClickGui;
import me.retucio.sputnik.ui.widgets.Panel;
import me.retucio.sputnik.ui.widgets.buttons.FriendButton;
import me.retucio.sputnik.ui.widgets.buttons.ModuleButton;
import me.retucio.sputnik.util.Colors;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component;
import java.util.List;
public class FriendsPanel extends Panel<FriendButton> {
public class FriendsPanel extends ExtendablePanel<FriendButton> {
public boolean extended;
private int offset;
public FriendsPanel(int x, int y, int w, int h) {
super("amigos", x, y, w, h);
dragging = false;
extended = true;
Sputnik.EVENT_BUS.subscribe(this);
@@ -40,12 +34,9 @@ public class FriendsPanel extends Panel<FriendButton> {
@Override
protected void updateWidth() {
// asegurarse de que todos los botones caben en el panel, haciendo
// que la anchura se ajuste al texto más largo
int maxWidth = mc.font.width(title) + mc.font.width(" +");
for (FriendButton button : buttons) {
String text = button.getFriend().getName();
int textWidth = mc.font.width(text);
int textWidth = mc.font.width(button.getFriend().getName());
maxWidth = Math.max(maxWidth, textWidth);
}
this.w = maxWidth + 22;
@@ -54,36 +45,27 @@ public class FriendsPanel extends Panel<FriendButton> {
@Override
public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) {
updateWidth();
gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); // cabeza del panel
gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
// título del panel
gui.text(mc.font, Component.literal(title),
x + 8,
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
gui.text(mc.font, extended ? "-" : "+",
x + w - mc.font.width("+") - 8, // '+' y '-' tienen la misma anchura, o sea que no importa cuál use
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
drawExpandCollapse(gui, mouseX, mouseY);
List<FriendButton> visibleButtons = buttons.stream()
.filter(fb -> fb.getFriend().isSearchMatch())
.toList();
// dibujar los botones solo si está extendido
if (extended) {
totalHeight = visibleButtons.size() * h + 3;
gui.fill( // fondo para los botones
x, renderY + h + 1,
x + w, renderY + h + totalHeight,
Colors.panelBgColor.getRGB());
gui.fill(x, renderY + h + 1, x + w, renderY + h + totalHeight, Colors.panelBgColor.getRGB());
// dibujar los botones para cada módulo
int buttonY = renderY + h + 1;
for (FriendButton moduleButton : visibleButtons) {
moduleButton.setOffset(buttonY - renderY);
moduleButton.render(gui, mouseX, mouseY, delta);
for (FriendButton friendButton : visibleButtons) {
friendButton.setOffset(buttonY - renderY);
friendButton.render(gui, mouseX, mouseY, delta);
buttonY += h;
}
} else {
@@ -93,19 +75,18 @@ public class FriendsPanel extends Panel<FriendButton> {
@Override
public void mouseClicked(int mouseX, int mouseY, int button) {
// registrar clics
if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) {
if (button == 0) { // clic izquierdo para arrastrarlo
if (button == 0) {
dragging = true;
dragX = mouseX - x;
dragY = mouseY - y;
} else if (button == 1) { // clic derecho para extenderlo
extended = !extended;
} else if (button == 1) {
toggleExtended();
Sputnik.EVENT_BUS.post(new FriendPanelEvent.Extend());
}
}
if (!extended) return; // solo dejar clicar en los botones si el marco está extendido
if (!extended) return;
List<FriendButton> visibleFriendButtons = buttons.stream()
.filter(fb -> fb.getFriend().isSearchMatch())
@@ -119,26 +100,21 @@ public class FriendsPanel extends Panel<FriendButton> {
@Override
public void mouseReleased(int mouseX, int mouseY, int button) {
ClickGui.INSTANCE.unselect(this);
if (button == 0 && dragging) {
dragging = false;
}
if (button == 0 && dragging) dragging = false;
List<FriendButton> visibleFriendButtons = buttons.stream()
.filter(fb -> fb.getFriend().isSearchMatch())
.toList();
for (FriendButton friendButton : visibleFriendButtons) {
if (friendButton.isHovered(mouseX, mouseY)) {
if (friendButton.isHovered(mouseX, mouseY))
friendButton.mouseReleased(mouseX, mouseY, button);
}
}
if (isHovered(mouseX, mouseY)) {
if (isHovered(mouseX, mouseY))
Sputnik.EVENT_BUS.post(new FriendPanelEvent.Move());
}
}
// actualizar la posición al arrastrar el panel
public void updatePosition(double mouseX, double mouseY) {
if (dragging) {
x = (int) (mouseX - dragX);
@@ -158,10 +134,9 @@ public class FriendsPanel extends Panel<FriendButton> {
public FriendButton getButtonOfFriend(Friend friend) {
for (FriendButton button : buttons) {
if (button.getFriend().getUuid().equals(friend.getUuid())) {
if (button.getFriend().getUuid().equals(friend.getUuid()))
return button;
}
}
return null;
}
}
@@ -7,10 +7,8 @@ import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.ui.screen.ClickGui;
import me.retucio.sputnik.ui.widgets.buttons.ModuleButton;
import me.retucio.sputnik.ui.widgets.Panel;
import me.retucio.sputnik.util.Colors;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.network.chat.Component;
@@ -18,18 +16,15 @@ import java.util.List;
// panel para los módulos
public class ModulePanel extends Panel<ModuleButton> {
public class ModulePanel extends ExtendablePanel<ModuleButton> {
public boolean extended;
public final Category category;
public ModulePanel(Category category, int x, int y, int w, int h) {
super(category.toString(), x, y, w, h);
this.category = category;
dragging = false;
extended = true;
// determinar el saliente para cada botón de módulo
int offset = h;
for (Module module : ModuleManager.INSTANCE.getModules()) {
if (!module.getCategory().equals(this.category)) continue;
@@ -40,12 +35,9 @@ public class ModulePanel extends Panel<ModuleButton> {
@Override
protected void updateWidth() {
// asegurarse de que todos los botones caben en el panel, haciendo
// que la anchura se ajuste al texto más largo
int maxWidth = mc.font.width(title);
for (ModuleButton button : buttons) {
String text = button.getModule().getName();
int textWidth = mc.font.width(text);
int textWidth = mc.font.width(button.getModule().getName());
maxWidth = Math.max(maxWidth, textWidth);
}
this.w = maxWidth + 22;
@@ -54,32 +46,23 @@ public class ModulePanel extends Panel<ModuleButton> {
@Override
public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) {
updateWidth();
gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB()); // cabeza del marco
gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
// título del marco
gui.text(mc.font, Component.literal(title),
x + 8,
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
gui.text(mc.font, extended ? "-" : "+",
x + w - mc.font.width("+") - 8, // '+' y '-' tienen la misma anchura, o sea que no importa cuál use
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
drawExpandCollapse(gui, mouseX, mouseY);
List<ModuleButton> visibleButtons = buttons.stream()
.filter(mb -> mb.getModule().isSearchMatch())
.toList();
// dibujar sus módulos solo si está extendido
if (extended) {
totalHeight = visibleButtons.size() * h + 3;
gui.fill( // fondo para los botones
x, renderY + h + 1,
x + w, renderY + h + totalHeight,
Colors.panelBgColor.getRGB());
gui.fill(x, renderY + h + 1, x + w, renderY + h + totalHeight, Colors.panelBgColor.getRGB());
// dibujar los botones para cada módulo
int buttonY = renderY + h + 1;
for (ModuleButton moduleButton : visibleButtons) {
moduleButton.setOffset(buttonY - renderY);
@@ -93,19 +76,18 @@ public class ModulePanel extends Panel<ModuleButton> {
@Override
public void mouseClicked(int mouseX, int mouseY, int button) {
// registrar clics
if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) {
if (button == 0) { // clic izquierdo para arrastrarlo
if (button == 0) {
dragging = true;
dragX = mouseX - x;
dragY = mouseY - y;
} else if (button == 1) { // clic derecho para extenderlo
extended = !extended;
} else if (button == 1) {
toggleExtended();
Sputnik.EVENT_BUS.post(new ModulePanelEvent.Extend(this));
}
}
if (!extended) return; // solo dejar clicar en los módulos si el marco está extendido
if (!extended) return;
List<ModuleButton> visibleModuleButtons = buttons.stream()
.filter(mb -> mb.getModule().isSearchMatch())
@@ -116,30 +98,24 @@ public class ModulePanel extends Panel<ModuleButton> {
}
}
// detectar cuándo se suelta el clic
@Override
public void mouseReleased(int mouseX, int mouseY, int button) {
ClickGui.INSTANCE.unselect(this);
if (button == 0 && dragging) {
dragging = false;
}
if (button == 0 && dragging) dragging = false;
List<ModuleButton> visibleModuleButtons = buttons.stream()
.filter(mb -> mb.getModule().isSearchMatch())
.toList();
for (ModuleButton moduleButton : visibleModuleButtons) {
if (moduleButton.isHovered(mouseX, mouseY)) {
if (moduleButton.isHovered(mouseX, mouseY))
moduleButton.mouseReleased(mouseX, mouseY, button);
}
}
if (isHovered(mouseX, mouseY)) {
if (isHovered(mouseX, mouseY))
Sputnik.EVENT_BUS.post(new ModulePanelEvent.Move(this));
}
}
// actualizar la posición al arrastrar el panel
public void updatePosition(double mouseX, double mouseY) {
if (dragging) {
x = (int) (mouseX - dragX);
@@ -18,15 +18,16 @@ import java.util.ArrayList;
import java.util.List;
// marco para los botones de los ajustes de cada módulo
public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
// panel para los botones de los ajustes de cada módulo
public class SettingsPanel extends CloseablePanel<SettingButton<? extends Setting<?>>> {
private Module module;
protected Module module;
protected List<SettingGroup> settingGroups;
protected static final int PADDING = 4; // para ser consistente
public boolean drawHeader = true;
public SettingsPanel(Module module, int x, int y, int w, int h) {
super("ajustes de " + module.getName(), x, y, w, h);
this.module = module;
this.settingGroups = module.getSgs();
@@ -41,9 +42,10 @@ public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) {
updateWidth();
// cabezal
int centerX = x + w / 2;
int centerY = renderY + h / 2;
if (drawHeader) {
int titleX = x + 2 * PADDING;
int titleY = centerY - mc.font.lineHeight / 2;
@@ -57,7 +59,8 @@ public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
gui.fill(x, renderY, x + w, renderY + h, headerColor);
gui.text(mc.font, title, titleX, titleY, -1, true);
gui.text(mc.font, "×", x + w - mc.font.width("×") - 2 * PADDING, titleY, closeButtonColor, true);
drawCloseButton(gui, mouseX, mouseY, closeButtonColor);
}
// filtrar botones visibles
visibleButtons = buttons.stream()
@@ -154,29 +157,23 @@ public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
}
}
@Override
public void drawTooltips(GuiGraphicsExtractor gui, int mouseX, int mouseY) {
for (SettingButton<?> sb : visibleButtons)
sb.drawTooltip(gui, mouseX, mouseY);
}
@Override
public void mouseClicked(int mouseX, int mouseY, int button) {
if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) {
if (isCloseButtonHovered(mouseX, mouseY)) {
ClickGui.INSTANCE.closeSettingsPanel(this.module);
onClose();
return;
}
if (isHovered(mouseX, mouseY) && ClickGui.INSTANCE.trySelect(this)) {
if (button == 0) {
dragging = true;
dragX = mouseX - x;
dragY = mouseY - y;
} else if (button == 1) {
ClickGui.INSTANCE.closeSettingsPanel(module);
onClose();
}
}
// al hacer clic en los cabezales de los grupos de ajustes
for (int i = 0; i < settingGroups.size(); i++) {
SettingGroup group = settingGroups.get(i);
if (hasVisibleSettingsInGroup(group) && isGroupHeaderHovered(mouseX, mouseY, i)) {
@@ -186,10 +183,9 @@ public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
}
}
for (SettingButton<?> sb : visibleButtons) {
for (SettingButton<?> sb : visibleButtons)
sb.mouseClicked(mouseX, mouseY, button);
}
}
@Override
public void mouseReleased(int mouseX, int mouseY, int button) {
@@ -395,4 +391,9 @@ public class SettingsPanel extends Panel<SettingButton<? extends Setting<?>>> {
public void setSettingGroups(List<SettingGroup> settingGroups) {
this.settingGroups = settingGroups;
}
@Override
public void onClose() {
ClickGui.INSTANCE.closeSettingsPanel(this.module);
}
}
@@ -3,45 +3,45 @@ package me.retucio.sputnik.ui.widgets.panels.settings;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.sputnik.ClientSettingsPanelEvent;
import me.retucio.sputnik.module.modules.client.ClientSettingsModule;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
import me.retucio.sputnik.ui.screen.ClickGui;
import me.retucio.sputnik.ui.widgets.buttons.SettingButton;
import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
import me.retucio.sputnik.util.Colors;
import net.minecraft.client.gui.GuiGraphicsExtractor;
public class ClientSettingsPanel extends SettingsPanel {
public static final ClientSettingsModule clientSettings = new ClientSettingsModule();
public boolean extended = false;
private boolean extended = false;
public ClientSettingsPanel(int x, int y, int w, int h) {
super(clientSettings, x, y, w, h);
title = "ajustes del mod";
this.title = "ajustes del mod";
this.drawHeader = false; // disable the original header
}
@Override
public void render(GuiGraphicsExtractor gui, int mouseX, int mouseY, float delta) {
updateWidth();
// botones, fondo, etc.
if (extended) {
super.render(gui, mouseX, mouseY, delta);
}
// cabezal
// Draw our own custom header (no close button, with +/-
gui.fill(x, renderY, x + w, renderY + h, Colors.mainColor.getRGB());
gui.text(mc.font, title,
x + 8,
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
gui.text(mc.font, extended ? "-" : "+",
x + w - mc.font.width("+") - 8,
String symbol = extended ? "-" : "+";
int textWidth = mc.font.width(symbol);
gui.text(mc.font, symbol,
x + w - textWidth - 8,
renderY + (h / 2) - (mc.font.lineHeight / 2),
-1, true);
// Only draw the rest of the panel (content) if extended
if (extended) {
// Call super.render() – but since drawHeader=false, it will only draw the content
super.render(gui, mouseX, mouseY, delta);
}
}
@Override
@@ -54,38 +54,53 @@ public class ClientSettingsPanel extends SettingsPanel {
} else if (button == 1) {
extended = !extended;
Sputnik.EVENT_BUS.post(new ClientSettingsPanelEvent.Extend());
}
}
// solo dejar clicar en los ajustes si el marco está extendido
if (!extended) return;
for (int i = 0; i < settingGroups.size(); i++) {
SettingGroup group = settingGroups.get(i);
if (hasVisibleSettingsInGroup(group) && isGroupHeaderHovered(mouseX, mouseY, i)) {
group.setExtended(!group.isExtended());
updateVisibleButtonsForGroup(group);
return;
}
}
for (SettingButton<?> sb : buttons) {
sb.mouseClicked(mouseX, mouseY, button);
if (extended) {
super.mouseClicked(mouseX, mouseY, button);
}
}
@Override
public void mouseReleased(int mouseX, int mouseY, int button) {
ClickGui.INSTANCE.unselect(this);
if (button == 0 && dragging)
if (button == 0 && dragging) {
dragging = false;
Sputnik.EVENT_BUS.post(new ClientSettingsPanelEvent.Move());
}
if (extended) {
super.mouseReleased(mouseX, mouseY, button);
}
}
@Override
public void drawTooltips(GuiGraphicsExtractor gui, int mouseX, int mouseY) {
if (!extended) return;
super.drawTooltips(gui, mouseX, mouseY);
public void mouseDragged(int mouseX, int mouseY) {
if (extended) {
super.mouseDragged(mouseX, mouseY);
}
}
@Override
public void mouseScrolled(double amount) {
if (extended) {
super.mouseScrolled(amount);
}
}
@Override
public void onKey(int key, int action) {
if (extended) {
super.onKey(key, action);
}
}
public boolean isExtended() {
return extended;
}
public void setExtended(boolean extended) {
this.extended = extended;
}
}
@@ -32,23 +32,22 @@ public class MiscUtil {
}
}
public static void copyVector(Vector3d destination, Vec3 source) {
destination.x = source.x;
destination.y = source.y;
destination.z = source.z;
public static void copyVector(Vector3d dst, Vec3 src) {
dst.x = src.x;
dst.y = src.y;
dst.z = src.z;
}
@SuppressWarnings("unchecked")
public static <T> T getHighest(List<T> list) {
if (list.getFirst() == null || !(list.getFirst() instanceof Number value)) return null;
Number maxValue = value;
public static <T extends Number> T getHighest(List<T> list) {
if (list.getFirst() == null) return null;
T maxValue = list.getFirst();
for (T t : list) {
if (((Number) t).doubleValue() > maxValue.doubleValue()) {
maxValue = (Number) t;
if (t.doubleValue() > maxValue.doubleValue()) {
maxValue = t;
}
}
return (T) maxValue;
return maxValue;
}
public static String getCurrentFormattedTime() {
@@ -11,15 +11,17 @@ import java.time.Duration;
public class VersionChecker {
private static final URI PROPERTIES_URL = getFileURI();
public static final VersionChecker INSTANCE = new VersionChecker();
public static boolean updateAvailable = false;
public static String latestRemoteVersion = null;
public static String currentVersion = Sputnik.MOD_VERSION;
private final URI PROPERTIES_URL = getFileURI();
private final String CURRENT_VERSION = Sputnik.MOD_VERSION;
public static boolean shouldShowScreen = false;
private boolean updateAvailable = false;
private String latestRemoteVersion = null;
public static void check() {
public boolean shouldShowScreen = false;
public void check() {
try {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
@@ -35,17 +37,17 @@ public class VersionChecker {
if (latestRemoteVersion != null) {
String remoteVersion = cleanVersion(latestRemoteVersion);
String localVersion = cleanVersion(currentVersion);
String localVersion = cleanVersion(CURRENT_VERSION);
if (compareVersions(localVersion, remoteVersion) == -1) {
updateAvailable = true;
Sputnik.LOGGER.info("actualización disponible. local: {}, más reciente: {}",
currentVersion, latestRemoteVersion);
CURRENT_VERSION, latestRemoteVersion);
shouldShowScreen = true;
} else if (compareVersions(localVersion, remoteVersion) == 0){
Sputnik.LOGGER.info("el mod está al día: v{}", currentVersion);
Sputnik.LOGGER.info("el mod está al día: v{}", CURRENT_VERSION);
} else {
Sputnik.LOGGER.info("mod en estado de desarrollo: v{}", currentVersion);
Sputnik.LOGGER.info("mod en estado de desarrollo: v{}", CURRENT_VERSION);
}
}
} else {
@@ -135,7 +137,11 @@ public class VersionChecker {
return null;
}
public static String getLatestVersion() {
public String getLatestVersion() {
return latestRemoteVersion;
}
public boolean isUpdateAvailable() {
return updateAvailable;
}
}
@@ -13,10 +13,10 @@ public class DrawUtil {
}
public static void drawCircle(GuiGraphicsExtractor gui, int x, int y, int radius, int color) {
for (int i = -radius; i <= radius; i++)
for (int j = -radius; j <= radius; j++)
if (i * i + j * j <= radius * radius)
gui.fill(x + i, y + j, x + i + 1, y + j + 1, color);
for (int dy = -radius; dy <= radius; dy++) {
int dx = (int) Math.sqrt(radius * radius - dy * dy);
gui.fill(x - dx, y + dy, x + dx + 1, y + dy + 1, color);
}
}
public static void drawCheckerBoard(GuiGraphicsExtractor gui, int x, int y, int width, int height, int checkerSize, int color1, int color2) {