Compare commits

..
3 Commits
Author SHA1 Message Date
retuci0 f074f05c51 v2.8 2026-01-17 17:12:54 +01:00
retuci0 436b79fd2b v2.7 2026-01-17 00:33:24 +01:00
retuci0 9afaa4e0c8 v2.6 2026-01-11 11:12:44 +01:00
141 changed files with 2873 additions and 900 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
# jenny's mod 2 100% real # jenny's mod 2 100% real
mod para Minecraft Fabric 1.21.10 que añade algunas cosas QOL, mayormente relacionadas a la cámara. mod para Minecraft Fabric 1.21.11 que añade algunas cosas QOL, mayormente relacionadas a la cámara.
## instalación ## instalación
+12 -22
View File
@@ -11,21 +11,21 @@ base {
} }
repositories { repositories {
// Add repositories to retrieve artifacts from in here. maven {
// You should only use this when depending on other mods because name = "FDD Maven"
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically. url = "https://maven.firstdark.dev/releases"
// See https://docs.gradle.org/current/userguide/declaring_repositories.html }
// for more information about repositories.
} }
dependencies { dependencies {
// To change the versions see the gradle.properties file // mc
minecraft "com.mojang:minecraft:${project.minecraft_version}" minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
// otros
include(modImplementation "dev.firstdark.discordrpc:discord-rpc:1.0.3")
} }
loom { loom {
@@ -45,11 +45,6 @@ tasks.withType(JavaCompile).configureEach {
} }
java { java {
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_21 sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21
} }
@@ -58,11 +53,12 @@ jar {
inputs.property "archivesName", project.base.archivesName inputs.property "archivesName", project.base.archivesName
from("LICENSE") { from("LICENSE") {
rename { "${it}_${inputs.properties.archivesName}"} rename {
"${it}_${inputs.properties.archivesName}"
}
} }
} }
// configure the maven publication
publishing { publishing {
publications { publications {
create("mavenJava", MavenPublication) { create("mavenJava", MavenPublication) {
@@ -71,11 +67,5 @@ publishing {
} }
} }
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. repositories {}
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
} }
+13 -3
View File
@@ -1,15 +1,25 @@
# v2.5 # v2.8
## novedades ## novedades
- grupos de ajustes, para mayor orden, y arreglo de algún que otro bug
### adiciones ### adiciones
#### módulos nuevos: #### módulos nuevos:
### arreglos / mejoras ### arreglos / mejoras
- arreglado el gradiente del selector de colores
- ahora el marco del preview del color en el botón del ajuste de color será el color complementario (rgb, no ryb) del color seleccionado
- ahora puedes borrar palabras enteras con ctrl + borrar
- mejoras al HUD:
- movimiento axial: centra los elementos más fácilmente
- movimiento con flechas: mueve el elemento seleccionado con las flechas
- ahora se puede abrir y usar el editor aun sin estar en un mundo
- más previews de elementos coinciden con su valor actual
- al parecer he arreglado sin querer un problema que había que no te dejaba seleccionar correctamente elementos del hud
## problemas reconocidos ## problemas reconocidos
- muchos, pero repórtalos en la página de problemas si quieres para que queden bien registrados - muchos, pero repórtalos en la página de problemas si quieres para que queden bien registrados
+1 -1
View File
@@ -8,6 +8,6 @@ loom_version=1.13-SNAPSHOT
fabric_api_version=0.140.2+1.21.11 fabric_api_version=0.140.2+1.21.11
mod_version=2.5 mod_version=2.8
maven_group=me.retucio maven_group=me.retucio
archives_base_name=sputnik archives_base_name=sputnik
+13 -1
View File
@@ -19,6 +19,7 @@ import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.client.HUD; import me.retucio.sputnik.module.modules.client.HUD;
import me.retucio.sputnik.ui.hud.HudRenderer;
import me.retucio.sputnik.ui.screen.ClickGUI; import me.retucio.sputnik.ui.screen.ClickGUI;
import me.retucio.sputnik.ui.hud.HudEditorScreen; import me.retucio.sputnik.ui.hud.HudEditorScreen;
import me.retucio.sputnik.ui.widgets.buttons.settings.BindButton; import me.retucio.sputnik.ui.widgets.buttons.settings.BindButton;
@@ -29,9 +30,11 @@ import me.retucio.sputnik.ui.widgets.frames.SettingsFrame;
import me.retucio.sputnik.ui.widgets.Button; import me.retucio.sputnik.ui.widgets.Button;
import me.retucio.sputnik.util.*; import me.retucio.sputnik.util.*;
import me.retucio.sputnik.util.KeyUtil;
import me.retucio.sputnik.util.render.DrawUtil; import me.retucio.sputnik.util.render.DrawUtil;
import me.retucio.sputnik.util.render.RenderUtil; import me.retucio.sputnik.util.render.RenderUtil;
import me.retucio.sputnik.util.render.Textures;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
@@ -69,6 +72,11 @@ public class Sputnik implements ClientModInitializer {
private Screen prevScreen; private Screen prevScreen;
public static boolean settingsApplied = false; public static boolean settingsApplied = false;
static {
// puta vida
System.setProperty("java.awt.headless", "false");
}
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
mc = MinecraftClient.getInstance(); mc = MinecraftClient.getInstance();
@@ -86,6 +94,8 @@ public class Sputnik implements ClientModInitializer {
Lists.init(); Lists.init();
Textures.registerAll();
CapeManager.INSTANCE = new CapeManager(); CapeManager.INSTANCE = new CapeManager();
EVENT_BUS.post(new LoadCapeManagerEvent()); EVENT_BUS.post(new LoadCapeManagerEvent());
@@ -99,6 +109,8 @@ public class Sputnik implements ClientModInitializer {
HudEditorScreen.INSTANCE = new HudEditorScreen(); HudEditorScreen.INSTANCE = new HudEditorScreen();
EVENT_BUS.post(new LoadClickGUIEvent()); EVENT_BUS.post(new LoadClickGUIEvent());
mc.execute(HudRenderer::init);
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> {
EVENT_BUS.post(new ShutdownEvent()); EVENT_BUS.post(new ShutdownEvent());
})); }));
@@ -189,7 +201,7 @@ public class Sputnik implements ClientModInitializer {
// manejar la lógica de apertura del editor de elementos del hud, con la misma lógica que handleClickGUIKey() // manejar la lógica de apertura del editor de elementos del hud, con la misma lógica que handleClickGUIKey()
private void handleHudEditorKey(int key, boolean anyFocused) { private void handleHudEditorKey(int key, boolean anyFocused) {
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class); HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
if (key != hud.editorKey.getKey() || anyFocused || isOnTypingScreen()) return; if (key != hud.editorKey.getValue() || anyFocused || isOnTypingScreen()) return;
if (mc.currentScreen != HudEditorScreen.INSTANCE) { if (mc.currentScreen != HudEditorScreen.INSTANCE) {
if (!hud.isEnabled()) { if (!hud.isEnabled()) {
@@ -32,6 +32,7 @@ public class CommandManager {
public static void registerCommands() { public static void registerCommands() {
addCommand(new BindCommand()); addCommand(new BindCommand());
addCommand(new ConfigCommand());
addCommand(new CopyScreenshotCommand()); addCommand(new CopyScreenshotCommand());
addCommand(new EnderChestCommand()); addCommand(new EnderChestCommand());
addCommand(new GarbageCleanerCommand()); addCommand(new GarbageCleanerCommand());
@@ -9,6 +9,7 @@ import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder; import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.util.MiscUtil;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@@ -19,6 +20,7 @@ import java.util.concurrent.CompletableFuture;
public class ModuleArgumentType implements ArgumentType<Module> { public class ModuleArgumentType implements ArgumentType<Module> {
public static final ModuleArgumentType INSTANCE = new ModuleArgumentType(); public static final ModuleArgumentType INSTANCE = new ModuleArgumentType();
private static final DynamicCommandExceptionType UNKNOWN_MODULE = new DynamicCommandExceptionType( private static final DynamicCommandExceptionType UNKNOWN_MODULE = new DynamicCommandExceptionType(
name -> Text.literal("módulo \"" + name + "\" no encontrado")); name -> Text.literal("módulo \"" + name + "\" no encontrado"));
@@ -35,7 +37,8 @@ public class ModuleArgumentType implements ArgumentType<Module> {
@Override @Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) { public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return CommandSource.suggestMatching(ModuleManager.INSTANCE.getModules().stream().map(module -> module.getName().replace(" ", "_")), builder); return CommandSource.suggestMatching(ModuleManager.INSTANCE.getModules()
.stream().map(module -> MiscUtil.removeAccentMarks(module.getName().replace(" ", "_"))), builder);
} }
@Override @Override
@@ -42,7 +42,7 @@ public class BindCommand extends Command {
public static boolean onKeyPress(int key) { public static boolean onKeyPress(int key) {
if (listeningModule == null) return false; if (listeningModule == null) return false;
KeySetting bind = listeningModule.getBind(); KeySetting bind = listeningModule.getBind();
if (bind != null) bind.setKey(key); if (bind != null) bind.setValue(key);
ChatUtil.info( ChatUtil.info(
Text.of("la tecla " + Formatting.AQUA + KeyUtil.getKeyName(key) + Formatting.RESET + Text.of("la tecla " + Formatting.AQUA + KeyUtil.getKeyName(key) + Formatting.RESET +
@@ -0,0 +1,66 @@
package me.retucio.sputnik.command.commands;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.command.args.ModuleArgumentType;
import me.retucio.sputnik.ui.screen.ClickGUI;
import me.retucio.sputnik.ui.widgets.frames.SettingsFrame;
import net.minecraft.command.CommandSource;
import me.retucio.sputnik.module.Module;
public class ConfigCommand extends Command {
public ConfigCommand() {
super("config", "abre el marco de ajustes de un módulo", "ajustes", "settings");
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
builder
.then(argument("módulo", ModuleArgumentType.INSTANCE)
.executes(ctx -> {
mc.execute(() -> openSf(ctx));
return SUCCESS;
})
.then(argument("x", IntegerArgumentType.integer())
.then(argument("y", IntegerArgumentType.integer())
.executes(ctx -> {
mc.execute(() -> openSfWithPos(ctx,
ctx.getArgument("x", Integer.class),
ctx.getArgument("y", Integer.class)));
return SUCCESS;
})
)
)
);
}
private void openSf(CommandContext<CommandSource> ctx) {
Module module = ctx.getArgument("módulo", Module.class);
mc.setScreen(ClickGUI.INSTANCE);
if (ClickGUI.INSTANCE.isSettingsFrameOpen(module)) return;
SettingsFrame sf = ClickGUI.INSTANCE.getSfOfModule(module);
int x = mc.getWindow().getScaledWidth() / 2 - sf.getW() / 2;
int y = 67;
ClickGUI.INSTANCE.openSettingsFrame(module, x, y);
}
private void openSfWithPos(CommandContext<CommandSource> ctx, int x, int y) {
Module module = ctx.getArgument("módulo", Module.class);
mc.setScreen(ClickGUI.INSTANCE);
if (ClickGUI.INSTANCE.isSettingsFrameOpen(module)) {
SettingsFrame sf = ClickGUI.INSTANCE.getSfOfModule(module);
sf.setX(x);
sf.setY(y);
}
ClickGUI.INSTANCE.openSettingsFrame(module, x, y);
}
}
@@ -57,9 +57,9 @@ public class ClientConfig {
// guardar ajustes con su respectivo tipo de valor, en formato "nombreMódulo:nombreAjuste" // guardar ajustes con su respectivo tipo de valor, en formato "nombreMódulo:nombreAjuste"
Object value = null; Object value = null;
switch (event.getSetting()) { switch (event.getSetting()) {
case BooleanSetting b: value = b.isEnabled(); break; case BooleanSetting b: value = b.getValue(); break;
case EnumSetting e: value = e.getIndex(); break; case EnumSetting e: value = e.getIndex(); break;
case KeySetting k: value = k.getKey(); break; case KeySetting k: value = k.getValue(); break;
case NumberSetting n: value = n.getValue(); break; case NumberSetting n: value = n.getValue(); break;
case StringSetting s: value = s.getValue(); break; case StringSetting s: value = s.getValue(); break;
case ListSetting l: value = l.getConfigValues(); break; case ListSetting l: value = l.getConfigValues(); break;
@@ -107,7 +107,7 @@ public class ConfigManager {
save(); save();
} }
public static void setSetting(Setting setting, Object value) { public static void setSetting(Setting<?> setting, Object value) {
ensureConfig(); ensureConfig();
config.settings.put(getSettingKey(setting), value); config.settings.put(getSettingKey(setting), value);
save(); save();
@@ -150,7 +150,7 @@ public class ConfigManager {
// ------------------ APLICAR AJUSTES ------------------ // ------------------ APLICAR AJUSTES ------------------
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public static void applySetting(Module parent, Setting setting) { public static void applySetting(Module parent, Setting<?> setting) {
String key = getSettingKey(setting); String key = getSettingKey(setting);
if (!config.settings.containsKey(key)) return; if (!config.settings.containsKey(key)) return;
@@ -189,8 +189,15 @@ public class ConfigManager {
private static void applySettingsFrames() { private static void applySettingsFrames() {
config.settingsFrames.forEach((moduleName, position) -> { config.settingsFrames.forEach((moduleName, position) -> {
Module module = ModuleManager.INSTANCE.getModuleByName(moduleName); Module module = ModuleManager.INSTANCE.getModuleByName(moduleName);
if (module == null) {
Sputnik.LOGGER.warn("\"null\" como módulo (\"{}\")", moduleName);
return;
}
ClickGUI.INSTANCE.openSettingsFrame(module, position[0], position[1]); ClickGUI.INSTANCE.openSettingsFrame(module, position[0], position[1]);
}); });
Sputnik.LOGGER.info("estados de marcos de ajustes aplicados"); Sputnik.LOGGER.info("estados de marcos de ajustes aplicados");
} }
@@ -242,7 +249,7 @@ public class ConfigManager {
private static void applyBooleanSetting(BooleanSetting setting, Object value) { private static void applyBooleanSetting(BooleanSetting setting, Object value) {
if (value instanceof Boolean) { if (value instanceof Boolean) {
setting.setEnabled((Boolean) value); setting.setValue((Boolean) value);
} }
} }
@@ -268,9 +275,9 @@ public class ConfigManager {
private static void applyKeySetting(KeySetting setting, Object value) { private static void applyKeySetting(KeySetting setting, Object value) {
if (value instanceof Double) { if (value instanceof Double) {
setting.setKey(((Double) value).intValue()); setting.setValue(((Double) value).intValue());
} else if (value instanceof Integer) { } else if (value instanceof Integer) {
setting.setKey((Integer) value); setting.setValue((Integer) value);
} }
} }
@@ -284,7 +291,7 @@ public class ConfigManager {
convertedValues.put(option, booleanValue instanceof Boolean && (Boolean) booleanValue); convertedValues.put(option, booleanValue instanceof Boolean && (Boolean) booleanValue);
} }
setting.setValues(convertedValues); setting.setValue(convertedValues);
} }
} }
@@ -335,7 +342,7 @@ public class ConfigManager {
if (config == null) config = new ClientConfig(); if (config == null) config = new ClientConfig();
} }
private static String getSettingKey(Setting setting) { private static String getSettingKey(Setting<?> setting) {
return setting.getSg().getModule().getName() + ":" + setting.getName(); return setting.getSg().getModule().getName() + ":" + setting.getName();
} }
@@ -6,15 +6,15 @@ import me.retucio.sputnik.module.setting.Setting;
// se genera cada que se cambia el valor de un ajuste // se genera cada que se cambia el valor de un ajuste
public class UpdateSettingEvent extends Event { public class UpdateSettingEvent extends Event {
private final Setting setting; private final Setting<?> setting;
private boolean shouldSave; private boolean shouldSave;
public UpdateSettingEvent(Setting setting, boolean shouldSave) { public UpdateSettingEvent(Setting<?> setting, boolean shouldSave) {
this.setting = setting; this.setting = setting;
this.shouldSave = shouldSave; this.shouldSave = shouldSave;
} }
public Setting getSetting() { public Setting<?> getSetting() {
return setting; return setting;
} }
@@ -15,7 +15,8 @@ import java.util.Iterator;
import static me.retucio.sputnik.Sputnik.EVENT_BUS; import static me.retucio.sputnik.Sputnik.EVENT_BUS;
@Mixin(BossBarHud.class)
@Mixin(value = BossBarHud.class)
public abstract class BossBarHudMixin { public abstract class BossBarHudMixin {
@ModifyExpressionValue(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/Collection;iterator()Ljava/util/Iterator;")) @ModifyExpressionValue(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/Collection;iterator()Ljava/util/Iterator;"))
@@ -30,7 +31,8 @@ public abstract class BossBarHudMixin {
return event.getName(); return event.getName();
} }
@ModifyConstant(method = "render", constant = @Constant(intValue = 9, ordinal = 1)) // require = 0 para meteor
@ModifyConstant(method = "render", constant = @Constant(intValue = 9, ordinal = 1), require = 0)
public int modifySpacingConstant(int constant) { public int modifySpacingConstant(int constant) {
RenderBossbarEvent.BossSpacing event = EVENT_BUS.post(new RenderBossbarEvent.BossSpacing(constant)); RenderBossbarEvent.BossSpacing event = EVENT_BUS.post(new RenderBossbarEvent.BossSpacing(constant));
return event.getSpacing(); return event.getSpacing();
@@ -59,7 +59,7 @@ public abstract class CameraMixin {
@Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true) @Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true)
private void onClipToSpace(float distance, CallbackInfoReturnable<Float> cir) { private void onClipToSpace(float distance, CallbackInfoReturnable<Float> cir) {
if (perspectivePlus.isEnabled() && perspectivePlus.clip.isEnabled()) if (perspectivePlus.isEnabled() && perspectivePlus.clip.getValue())
cir.setReturnValue(distance); cir.setReturnValue(distance);
} }
@@ -143,7 +143,7 @@ public abstract class ChatHudMixin implements IChatHud {
@ModifyExpressionValue(method = "render(Lnet/minecraft/client/gui/hud/ChatHud$Backend;IIZ)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;ceil(F)I")) @ModifyExpressionValue(method = "render(Lnet/minecraft/client/gui/hud/ChatHud$Backend;IIZ)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;ceil(F)I"))
private int onRender_modifyWidth(int width) { private int onRender_modifyWidth(int width) {
return (chatPlus.isEnabled() && chatPlus.showHeads.isEnabled()) ? width + 10 : width; return (chatPlus.isEnabled() && chatPlus.showHeads.getValue()) ? width + 10 : width;
} }
@@ -19,6 +19,6 @@ public abstract class ChatScreenMixin {
@Inject(method = "init", at = @At(value = "RETURN")) @Inject(method = "init", at = @At(value = "RETURN"))
private void onInit(CallbackInfo info) { private void onInit(CallbackInfo info) {
ChatPlus chatPlus = ModuleManager.INSTANCE.getModuleByClass(ChatPlus.class); ChatPlus chatPlus = ModuleManager.INSTANCE.getModuleByClass(ChatPlus.class);
if (chatPlus.isEnabled() && chatPlus.noCharLimit.isEnabled()) chatField.setMaxLength(Integer.MAX_VALUE); if (chatPlus.isEnabled() && chatPlus.noCharLimit.getValue()) chatField.setMaxLength(Integer.MAX_VALUE);
} }
} }
@@ -55,7 +55,7 @@ public abstract class ClientPlayNetworkHandlerMixin {
@Redirect(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;showFloatingItem(Lnet/minecraft/item/ItemStack;)V")) @Redirect(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/GameRenderer;showFloatingItem(Lnet/minecraft/item/ItemStack;)V"))
private void noRenderTotemPop(GameRenderer instance, ItemStack floatingItem) { private void noRenderTotemPop(GameRenderer instance, ItemStack floatingItem) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class); NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (!noRender.isEnabled() || noRender.totemPop.isEnabled()) if (!noRender.isEnabled() || noRender.totemPop.getValue())
mc.gameRenderer.showFloatingItem(floatingItem); mc.gameRenderer.showFloatingItem(floatingItem);
} }
} }
@@ -6,6 +6,7 @@ import me.retucio.sputnik.event.events.InteractEntityEvent;
import me.retucio.sputnik.event.events.PlaceBlockEvent; import me.retucio.sputnik.event.events.PlaceBlockEvent;
import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.camera.Freecam; import me.retucio.sputnik.module.modules.camera.Freecam;
import me.retucio.sputnik.module.modules.player.FastUse;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
@@ -16,7 +17,7 @@ import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Final; import net.minecraft.util.math.Direction;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
@@ -31,8 +32,8 @@ import static me.retucio.sputnik.Sputnik.mc;
@Mixin(ClientPlayerInteractionManager.class) @Mixin(ClientPlayerInteractionManager.class)
public abstract class ClientPlayerInteractionManagerMixin { public abstract class ClientPlayerInteractionManagerMixin {
@Shadow @Final @Shadow
private MinecraftClient client; private int blockBreakingCooldown;
@Unique @Unique
Freecam freecam; Freecam freecam;
@@ -69,4 +70,13 @@ public abstract class ClientPlayerInteractionManagerMixin {
AttackEntityEvent event = EVENT_BUS.post(new AttackEntityEvent(target)); AttackEntityEvent event = EVENT_BUS.post(new AttackEntityEvent(target));
if (event.isCancelled()) ci.cancel(); if (event.isCancelled()) ci.cancel();
} }
@Inject(method = "updateBlockBreakingProgress", at = @At(value = "FIELD", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;blockBreakingCooldown:I"))
private void modifyBlockBreakingCooldown(BlockPos pos, Direction direction, CallbackInfoReturnable<Boolean> cir) {
FastUse fastUse = ModuleManager.INSTANCE.getModuleByClass(FastUse.class);
if (!fastUse.isEnabled() || !fastUse.mining.getValue()) return;
blockBreakingCooldown = fastUse.miningCooldown.getIntValue();
}
} }
@@ -41,7 +41,7 @@ abstract class DamageParticleFactoryMixin {
original.velocityMultiplier *= crits.velocityMultipler.getFloatValue(); original.velocityMultiplier *= crits.velocityMultipler.getFloatValue();
original.gravityStrength *= crits.gravity.getFloatValue(); original.gravityStrength *= crits.gravity.getFloatValue();
original.setMaxAge(crits.maxAge.getIntValue()); original.setMaxAge(crits.maxAge.getIntValue());
original.collidesWithWorld = crits.collide.isEnabled(); original.collidesWithWorld = crits.collide.getValue();
return original; return original;
} }
@@ -88,7 +88,7 @@ public abstract class EntityMixin {
@ModifyReturnValue(method = "getName", at = @At("RETURN")) @ModifyReturnValue(method = "getName", at = @At("RETURN"))
private Text showProjectileDamage(Text original) { private Text showProjectileDamage(Text original) {
if (!nametags.isEnabled() || !nametags.showProjectileDamage.isEnabled()) return original; if (!nametags.isEnabled() || !nametags.showProjectileDamage.getValue()) return original;
if ((Object) this instanceof PersistentProjectileEntity arrow) { // aunque lo llame "arrow", también cubre flechas espectrales y tridentes if ((Object) this instanceof PersistentProjectileEntity arrow) { // aunque lo llame "arrow", también cubre flechas espectrales y tridentes
String damage = nametags.getArrowDamage(arrow); String damage = nametags.getArrowDamage(arrow);
@@ -101,7 +101,7 @@ public abstract class EntityMixin {
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
@ModifyReturnValue(method = "getCustomName", at = @At("RETURN")) @ModifyReturnValue(method = "getCustomName", at = @At("RETURN"))
private Text displayEntityOwner(Text original) { private Text displayEntityOwner(Text original) {
if (!nametags.isEnabled() || !nametags.petOwner.isEnabled()) return original; if (!nametags.isEnabled() || !nametags.petOwner.getValue()) return original;
if ((Object) this instanceof TameableEntity entity && entity.getOwnerReference() != null) { if ((Object) this instanceof TameableEntity entity && entity.getOwnerReference() != null) {
if (original != null) return original.copy().append(" (de " + nametags.getOwnerName(entity.getOwnerReference()) + ")"); if (original != null) return original.copy().append(" (de " + nametags.getOwnerName(entity.getOwnerReference()) + ")");
else return Text.of(nametags.getOwnerName(entity.getOwnerReference())); else return Text.of(nametags.getOwnerName(entity.getOwnerReference()));
@@ -113,7 +113,7 @@ public abstract class EntityMixin {
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
@ModifyReturnValue(method = "getName", at = @At("RETURN")) @ModifyReturnValue(method = "getName", at = @At("RETURN"))
private Text showBabies(Text original) { private Text showBabies(Text original) {
if (!nametags.isEnabled() || !nametags.distinguishBabies.isEnabled()) return original; if (!nametags.isEnabled() || !nametags.distinguishBabies.getValue()) return original;
if ((Object) this instanceof LivingEntity entity && entity.isBaby()) return original.copy().append(" (baby)"); if ((Object) this instanceof LivingEntity entity && entity.isBaby()) return original.copy().append(" (baby)");
return original; return original;
} }
@@ -33,10 +33,10 @@ public abstract class FogRendererMixin {
if (!noRender.isEnabled()) return instance.shouldApply(cameraSubmersionType, entity); if (!noRender.isEnabled()) return instance.shouldApply(cameraSubmersionType, entity);
String className = instance.getClass().getSimpleName(); String className = instance.getClass().getSimpleName();
if ((className.equals("BlindnessEffectFogModifier") && !noRender.blindnessEffect.isEnabled()) if ((className.equals("BlindnessEffectFogModifier") && !noRender.blindnessEffect.getValue())
|| (className.equals("DarknessEffectFogModifier") && !noRender.darknessEffect.isEnabled()) || (className.equals("DarknessEffectFogModifier") && !noRender.darknessEffect.getValue())
|| ((className.equals("LavaFogModifier") || className.equals("WaterFogModifier") || ((className.equals("LavaFogModifier") || className.equals("WaterFogModifier")
|| className.equals("PowederSnowFogModifier")) && !noRender.fluidOverlay.isEnabled())) || className.equals("PowederSnowFogModifier")) && !noRender.fluidOverlay.getValue()))
return false; return false;
return instance.shouldApply(cameraSubmersionType, entity); return instance.shouldApply(cameraSubmersionType, entity);
@@ -44,7 +44,7 @@ public abstract class FogRendererMixin {
@ModifyReturnValue(method = "getFogColor", at = @At("RETURN")) @ModifyReturnValue(method = "getFogColor", at = @At("RETURN"))
private Vector4f modifyLavaFog(Vector4f original, Camera camera) { private Vector4f modifyLavaFog(Vector4f original, Camera camera) {
if (noRender.isEnabled() && !noRender.fluidOverlay.isEnabled() && if (noRender.isEnabled() && !noRender.fluidOverlay.getValue() &&
(camera.getSubmersionType() == CameraSubmersionType.LAVA (camera.getSubmersionType() == CameraSubmersionType.LAVA
|| camera.getSubmersionType() == CameraSubmersionType.WATER)) || camera.getSubmersionType() == CameraSubmersionType.WATER))
return new Vector4f(original.x, original.y, original.z, 0f); return new Vector4f(original.x, original.y, original.z, 0f);
@@ -54,6 +54,6 @@ public abstract class FogRendererMixin {
@ModifyExpressionValue(method = "getFogColor", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getUnderwaterVisibility()F")) @ModifyExpressionValue(method = "getFogColor", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getUnderwaterVisibility()F"))
private float noRenderUnderwaterFog(float original) { private float noRenderUnderwaterFog(float original) {
return (noRender.isEnabled() && !noRender.fluidOverlay.isEnabled()) ? 0 : original; return (noRender.isEnabled() && !noRender.fluidOverlay.getValue()) ? 0 : original;
} }
} }
@@ -0,0 +1,38 @@
package me.retucio.sputnik.mixin;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.render.Fonts;
import net.minecraft.client.font.FontManager;
import net.minecraft.client.font.FontStorage;
import net.minecraft.text.StyleSpriteSource;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(FontManager.class)
public abstract class FontManagerMixin {
@Shadow
public abstract FontStorage getStorageInternal(Identifier id);
@Inject(method = "getStorageInternal", at = @At("HEAD"), cancellable = true)
private void onGetStorageInternal(Identifier id, CallbackInfoReturnable<FontStorage> cir) {
Fonts fonts = ModuleManager.INSTANCE.getModuleByClass(Fonts.class);
if (!fonts.isEnabled()) return;
if (id.equals(StyleSpriteSource.Font.DEFAULT.id())) {
cir.setReturnValue(getStorageInternal(
Identifier.of(
Sputnik.MOD_ID,
fonts.font.getValue())
));
}
}
}
@@ -110,13 +110,13 @@ public abstract class GameRendererMixin {
@Inject(method = "renderHand", at = @At("HEAD"), cancellable = true) @Inject(method = "renderHand", at = @At("HEAD"), cancellable = true)
private void renderHand(float tickProgress, boolean sleeping, Matrix4f positionMatrix, CallbackInfo ci) { private void renderHand(float tickProgress, boolean sleeping, Matrix4f positionMatrix, CallbackInfo ci) {
if ((zoom.isEnabled() && !zoom.showHands.isEnabled()) if ((zoom.isEnabled() && !zoom.showHands.getValue())
|| (freecam.isEnabled() && !freecam.renderHands.isEnabled())) || (freecam.isEnabled() && !freecam.renderHands.getValue()))
ci.cancel(); ci.cancel();
} }
@ModifyVariable(method = "renderWorld", ordinal = 6, at = @At(value = "STORE")) @ModifyVariable(method = "renderWorld", ordinal = 6, at = @At(value = "STORE"))
private float noRenderNauseaDistortion(float scaledNauseaEffectFactor) { private float noRenderNauseaDistortion(float scaledNauseaEffectFactor) {
return (noRender.isEnabled() && !noRender.nauseaEffect.isEnabled()) ? 0 : scaledNauseaEffectFactor; return (noRender.isEnabled() && !noRender.nauseaEffect.getValue()) ? 0 : scaledNauseaEffectFactor;
} }
} }
@@ -65,19 +65,19 @@ public abstract class HeldItemRendererMixin {
@ModifyReturnValue(method = "shouldSkipHandAnimationOnSwap", at = @At("RETURN")) @ModifyReturnValue(method = "shouldSkipHandAnimationOnSwap", at = @At("RETURN"))
private boolean modifySkipSwapAnimation(boolean original) { private boolean modifySkipSwapAnimation(boolean original) {
return original || (handView.isEnabled() && handView.skipSwapping.isEnabled()); return original || (handView.isEnabled() && handView.skipSwapping.getValue());
} }
@Inject(method = "applyEatOrDrinkTransformation", at = @At(value = "INVOKE", target = "Ljava/lang/Math;pow(DD)D", shift = At.Shift.BEFORE), cancellable = true) @Inject(method = "applyEatOrDrinkTransformation", at = @At(value = "INVOKE", target = "Ljava/lang/Math;pow(DD)D", shift = At.Shift.BEFORE), cancellable = true)
private void cancelTransformations(MatrixStack matrices, float tickDelta, Arm arm, ItemStack stack, PlayerEntity player, CallbackInfo ci) { private void cancelTransformations(MatrixStack matrices, float tickDelta, Arm arm, ItemStack stack, PlayerEntity player, CallbackInfo ci) {
if (handView.isEnabled() && handView.noFood.isEnabled()) ci.cancel(); if (handView.isEnabled() && handView.noFood.getValue()) ci.cancel();
} }
@ModifyArg(method = "updateHeldItems", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;clamp(FFF)F", ordinal = 2), index = 0) @ModifyArg(method = "updateHeldItems", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;clamp(FFF)F", ordinal = 2), index = 0)
private float modifyEquipProgressMainhand(float value) { private float modifyEquipProgressMainhand(float value) {
if (mc.player == null) return value; if (mc.player == null) return value;
float progress = mc.player.getAttackCooldownProgress(1); float progress = mc.player.getAttackCooldownProgress(1);
float modified = handView.isEnabled() && handView.oldAnimations.isEnabled() ? 1 : (float) Math.pow(progress, 3); float modified = handView.isEnabled() && handView.oldAnimations.getValue() ? 1 : (float) Math.pow(progress, 3);
return (shouldSkipHandAnimationOnSwap(mainHand, mc.player.getMainHandStack()) ? modified : 0) - equipProgressMainHand; return (shouldSkipHandAnimationOnSwap(mainHand, mc.player.getMainHandStack()) ? modified : 0) - equipProgressMainHand;
} }
@@ -40,32 +40,32 @@ public abstract class InGameHudMixin {
@Inject(method = "renderScoreboardSidebar*", at = @At("HEAD"), cancellable = true) @Inject(method = "renderScoreboardSidebar*", at = @At("HEAD"), cancellable = true)
private void noRenderScoreboard(CallbackInfo ci) { private void noRenderScoreboard(CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.scoreboard.isEnabled()) ci.cancel(); if (noRender.isEnabled() && !noRender.scoreboard.getValue()) ci.cancel();
} }
@Inject(method = "renderTitleAndSubtitle", at = @At("HEAD"), cancellable = true) @Inject(method = "renderTitleAndSubtitle", at = @At("HEAD"), cancellable = true)
private void noRenderTitles(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) { private void noRenderTitles(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.titles.isEnabled()) ci.cancel(); if (noRender.isEnabled() && !noRender.titles.getValue()) ci.cancel();
} }
@Inject(method = "renderNauseaOverlay", at = @At("HEAD"), cancellable = true) @Inject(method = "renderNauseaOverlay", at = @At("HEAD"), cancellable = true)
private void noRenderNausea(DrawContext context, float nauseaStrength, CallbackInfo ci) { private void noRenderNausea(DrawContext context, float nauseaStrength, CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.nauseaEffect.isEnabled()) ci.cancel(); if (noRender.isEnabled() && !noRender.nauseaEffect.getValue()) ci.cancel();
} }
@Inject(method = "renderSpyglassOverlay", at = @At("HEAD"), cancellable = true) @Inject(method = "renderSpyglassOverlay", at = @At("HEAD"), cancellable = true)
private void noRenderSpyglass(DrawContext context, float scale, CallbackInfo ci) { private void noRenderSpyglass(DrawContext context, float scale, CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.spyglassOverlay.isEnabled()) ci.cancel(); if (noRender.isEnabled() && !noRender.spyglassOverlay.getValue()) ci.cancel();
} }
@Inject(method = "renderPortalOverlay", at = @At("HEAD"), cancellable = true) @Inject(method = "renderPortalOverlay", at = @At("HEAD"), cancellable = true)
private void noRenderPortal(DrawContext context, float nauseaStrength, CallbackInfo ci) { private void noRenderPortal(DrawContext context, float nauseaStrength, CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.portalOverlay.isEnabled()) ci.cancel(); if (noRender.isEnabled() && !noRender.portalOverlay.getValue()) ci.cancel();
} }
@Inject(method = "renderOverlay", at = @At("HEAD"), cancellable = true) @Inject(method = "renderOverlay", at = @At("HEAD"), cancellable = true)
private void noRenderPumpkinBlur(DrawContext context, Identifier texture, float opacity, CallbackInfo ci) { private void noRenderPumpkinBlur(DrawContext context, Identifier texture, float opacity, CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.pumpkinOverlay.isEnabled() && texture.getPath().equals("textures/misc/pumpkinblur.png")) ci.cancel(); if (noRender.isEnabled() && !noRender.pumpkinOverlay.getValue() && texture.getPath().equals("textures/misc/pumpkinblur.png")) ci.cancel();
} }
@@ -84,6 +84,6 @@ public abstract class InGameHudMixin {
@Inject(method = "clear", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;clear(Z)V"), cancellable = true) @Inject(method = "clear", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/ChatHud;clear(Z)V"), cancellable = true)
private void onClear(CallbackInfo ci) { private void onClear(CallbackInfo ci) {
ChatPlus chatPlus = ModuleManager.INSTANCE.getModuleByClass(ChatPlus.class); ChatPlus chatPlus = ModuleManager.INSTANCE.getModuleByClass(ChatPlus.class);
if (chatPlus.isEnabled() && chatPlus.keepHistory.isEnabled()) ci.cancel(); if (chatPlus.isEnabled() && chatPlus.keepHistory.getValue()) ci.cancel();
} }
} }
@@ -27,11 +27,11 @@ public abstract class InGameOverlayRendererMixin {
@Inject(method = "renderFireOverlay", at = @At("HEAD"), cancellable = true) @Inject(method = "renderFireOverlay", at = @At("HEAD"), cancellable = true)
private static void noRenderFireOverlay(MatrixStack matrices, VertexConsumerProvider vertexConsumers, Sprite sprite, CallbackInfo ci) { private static void noRenderFireOverlay(MatrixStack matrices, VertexConsumerProvider vertexConsumers, Sprite sprite, CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.fireOverlay.isEnabled()) ci.cancel(); if (noRender.isEnabled() && !noRender.fireOverlay.getValue()) ci.cancel();
} }
@Inject(method = "renderUnderwaterOverlay", at = @At("HEAD"), cancellable = true) @Inject(method = "renderUnderwaterOverlay", at = @At("HEAD"), cancellable = true)
private static void noRenderUnderwaterOverlay(MinecraftClient client, MatrixStack matrices, VertexConsumerProvider vertexConsumers, CallbackInfo ci) { private static void noRenderUnderwaterOverlay(MinecraftClient client, MatrixStack matrices, VertexConsumerProvider vertexConsumers, CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.fluidOverlay.isEnabled()) ci.cancel(); if (noRender.isEnabled() && !noRender.fluidOverlay.getValue()) ci.cancel();
} }
} }
@@ -28,7 +28,7 @@ public abstract class ItemEntityMixin {
if (!name.equals(original)) name = name.formatted(Formatting.ITALIC); if (!name.equals(original)) name = name.formatted(Formatting.ITALIC);
if (nametags.countItems.isEnabled()) { if (nametags.countItems.getValue()) {
if (count > 1) return name.copy().append(" x" + count); if (count > 1) return name.copy().append(" x" + count);
return name; return name;
} }
@@ -23,7 +23,7 @@ public abstract class ItemMixin {
@Inject(method = "appendTooltip", at = @At("HEAD")) @Inject(method = "appendTooltip", at = @At("HEAD"))
private void onAppendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer<Text> textConsumer, TooltipType type, CallbackInfo ci) { private void onAppendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer<Text> textConsumer, TooltipType type, CallbackInfo ci) {
ShulkerPeek shulkerPeek = ModuleManager.INSTANCE.getModuleByClass(ShulkerPeek.class); ShulkerPeek shulkerPeek = ModuleManager.INSTANCE.getModuleByClass(ShulkerPeek.class);
if (!shulkerPeek.isEnabled() || !shulkerPeek.showTooltips.isEnabled()) return; if (!shulkerPeek.isEnabled() || !shulkerPeek.showTooltips.getValue()) return;
if (stack.getItem() instanceof BlockItem blockItem && blockItem.getBlock() instanceof ShulkerBoxBlock) { if (stack.getItem() instanceof BlockItem blockItem && blockItem.getBlock() instanceof ShulkerBoxBlock) {
if (ShulkerPeek.isShulkerEmpty(stack)) { if (ShulkerPeek.isShulkerEmpty(stack)) {
@@ -16,7 +16,7 @@ public abstract class KeyInputMixin extends Input {
@Inject(method = "tick", at = @At("TAIL")) @Inject(method = "tick", at = @At("TAIL"))
private void isPressed(CallbackInfo ci) { private void isPressed(CallbackInfo ci) {
Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class); Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
if (freecam.isEnabled() && freecam.stayCrouching.isEnabled() && freecam.isCrouching()) if (freecam.isEnabled() && freecam.stayCrouching.getValue() && freecam.isCrouching())
playerInput = new PlayerInput( playerInput = new PlayerInput(
false, false, false, false,
false, false, false, false,
@@ -55,6 +55,6 @@ public abstract class LightmapTextureManagerMixin {
@Inject(method = "getDarkness", at = @At("HEAD"), cancellable = true) @Inject(method = "getDarkness", at = @At("HEAD"), cancellable = true)
private void noRenderDarkness(LivingEntity entity, float factor, float tickProgress, CallbackInfoReturnable<Float> cir) { private void noRenderDarkness(LivingEntity entity, float factor, float tickProgress, CallbackInfoReturnable<Float> cir) {
if (noRender.isEnabled() && !noRender.darknessEffect.isEnabled()) cir.setReturnValue(0f); if (noRender.isEnabled() && !noRender.darknessEffect.getValue()) cir.setReturnValue(0f);
} }
} }
@@ -2,6 +2,7 @@ package me.retucio.sputnik.mixin;
import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.player.ElytraBounce; import me.retucio.sputnik.module.modules.player.ElytraBounce;
import me.retucio.sputnik.module.modules.player.Step;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
@@ -12,6 +13,7 @@ import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import static me.retucio.sputnik.Sputnik.mc; import static me.retucio.sputnik.Sputnik.mc;
@@ -26,7 +28,7 @@ public abstract class LivingEntityMixin {
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
@Inject(method = "tickMovement", at = @At("TAIL")) @Inject(method = "tickMovement", at = @At("TAIL"))
public void recastIfLanded(CallbackInfo ci) { private void recastIfLanded(CallbackInfo ci) {
ElytraBounce bounce = ModuleManager.INSTANCE.getModuleByClass(ElytraBounce.class); ElytraBounce bounce = ModuleManager.INSTANCE.getModuleByClass(ElytraBounce.class);
if (!((Object) this instanceof ClientPlayerEntity) if (!((Object) this instanceof ClientPlayerEntity)
@@ -47,4 +49,11 @@ public abstract class LivingEntityMixin {
prevElytra = elytra; prevElytra = elytra;
} }
@Inject(method = "getStepHeight", at = @At("RETURN"), cancellable = true)
private void step(CallbackInfoReturnable<Float> cir) {
Step step = ModuleManager.INSTANCE.getModuleByClass(Step.class);
if (step.isEnabled()) cir.setReturnValue(step.height.getFloatValue());
}
} }
@@ -40,12 +40,12 @@ public abstract class LivingEntityRendererMixin<T extends LivingEntity> {
@ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isSneaky()Z")) @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isSneaky()Z"))
private boolean renderSneakingPlayerNametags(boolean original) { private boolean renderSneakingPlayerNametags(boolean original) {
return (nametags.isEnabled() && nametags.alwaysVisible.isEnabled()) || original; return (nametags.isEnabled() && nametags.alwaysVisible.getValue()) || original;
} }
@ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isInvisibleTo(Lnet/minecraft/entity/player/PlayerEntity;)Z")) @ModifyExpressionValue(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;isInvisibleTo(Lnet/minecraft/entity/player/PlayerEntity;)Z"))
private boolean renderInvisPlayerNametags(boolean original) { private boolean renderInvisPlayerNametags(boolean original) {
if (nametags.isEnabled() && nametags.alwaysVisible.isEnabled()) return false; if (nametags.isEnabled() && nametags.alwaysVisible.getValue()) return false;
else return original; else return original;
} }
@@ -58,7 +58,7 @@ public abstract class LivingEntityRendererMixin<T extends LivingEntity> {
@Inject(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At("RETURN"), cancellable = true) @Inject(method = "hasLabel(Lnet/minecraft/entity/LivingEntity;D)Z", at = @At("RETURN"), cancellable = true)
private void renderSelfNametag(T livingEntity, double d, CallbackInfoReturnable<Boolean> cir) { private void renderSelfNametag(T livingEntity, double d, CallbackInfoReturnable<Boolean> cir) {
if (livingEntity instanceof PlayerEntity player) { if (livingEntity instanceof PlayerEntity player) {
if (player == mc.player && nametags.showSelf.isEnabled()) { if (player == mc.player && nametags.showSelf.getValue()) {
cir.setReturnValue(true); cir.setReturnValue(true);
cir.cancel(); cir.cancel();
} }
@@ -14,9 +14,9 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -27,6 +27,12 @@ public abstract class MinecraftClientMixin {
@Shadow @Shadow
private int itemUseCooldown; private int itemUseCooldown;
@Shadow
public int attackCooldown;
// eventos
@Inject(method = "tick", at = @At("HEAD")) @Inject(method = "tick", at = @At("HEAD"))
private void onTickPre(CallbackInfo ci) { private void onTickPre(CallbackInfo ci) {
Sputnik.INSTANCE.onTick(); Sputnik.INSTANCE.onTick();
@@ -49,9 +55,10 @@ public abstract class MinecraftClientMixin {
if (event.isCancelled()) ci.cancel(); if (event.isCancelled()) ci.cancel();
} }
@Inject(method = "isTelemetryEnabledByApi", at = @At("RETURN"), cancellable = true) @Inject(method = "joinWorld", at = @At("HEAD"), cancellable = true)
private void disableMicropenisTelemetryShi(CallbackInfoReturnable<Boolean> cir) { private void onJoinWorld(ClientWorld world, CallbackInfo ci) {
cir.setReturnValue(false); JoinWorldEvent event = Sputnik.EVENT_BUS.post(new JoinWorldEvent(world));
if (event.isCancelled()) ci.cancel();
} }
@Inject(method = "doItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getStackInHand(Lnet/minecraft/util/Hand;)Lnet/minecraft/item/ItemStack;"), cancellable = true) @Inject(method = "doItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getStackInHand(Lnet/minecraft/util/Hand;)Lnet/minecraft/item/ItemStack;"), cancellable = true)
@@ -61,16 +68,21 @@ public abstract class MinecraftClientMixin {
if (event.isCancelled()) ci.cancel(); if (event.isCancelled()) ci.cancel();
} }
// telemetría
@Inject(method = "isTelemetryEnabledByApi", at = @At("RETURN"), cancellable = true)
private void disableMicropenisTelemetryShi(CallbackInfoReturnable<Boolean> cir) {
cir.setReturnValue(false);
}
// precoz
@Inject(method = "doItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isItemEnabled(Lnet/minecraft/resource/featuretoggle/FeatureSet;)Z")) @Inject(method = "doItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isItemEnabled(Lnet/minecraft/resource/featuretoggle/FeatureSet;)Z"))
private void modifyItemUseCooldown(CallbackInfo ci, @Local ItemStack stack) { private void modifyItemUseCooldown(CallbackInfo ci, @Local ItemStack stack) {
FastUse fastUse = ModuleManager.INSTANCE.getModuleByClass(FastUse.class); FastUse fastUse = ModuleManager.INSTANCE.getModuleByClass(FastUse.class);
if (!fastUse.isEnabled()) return; if (!fastUse.isEnabled()) return;
itemUseCooldown = fastUse.getCooldown(stack); itemUseCooldown = fastUse.getCooldown(stack);
} }
@Inject(method = "joinWorld", at = @At("HEAD"), cancellable = true)
private void onJoinWorld(ClientWorld world, CallbackInfo ci) {
JoinWorldEvent event = Sputnik.EVENT_BUS.post(new JoinWorldEvent(world));
if (event.isCancelled()) ci.cancel();
}
} }
@@ -26,7 +26,7 @@ public abstract class PlayerEntityMixin extends LivingEntity {
@ModifyReturnValue(method = "getDisplayName", at = @At("RETURN")) @ModifyReturnValue(method = "getDisplayName", at = @At("RETURN"))
private Text addHealthIndicator(Text original) { private Text addHealthIndicator(Text original) {
Nametags nametags = ModuleManager.INSTANCE.getModuleByClass(Nametags.class); Nametags nametags = ModuleManager.INSTANCE.getModuleByClass(Nametags.class);
if (!nametags.isEnabled() || !nametags.health.isEnabled()) return original; if (!nametags.isEnabled() || !nametags.health.getValue()) return original;
float health = getHealth(); float health = getHealth();
float absorption = getAbsorptionAmount(); float absorption = getAbsorptionAmount();
@@ -26,13 +26,13 @@ public abstract class SkyRendererMixin {
@Inject(method = "renderSun", at = @At("HEAD"), cancellable = true) @Inject(method = "renderSun", at = @At("HEAD"), cancellable = true)
private void onRenderSun(float alpha, MatrixStack matrices, CallbackInfo ci) { private void onRenderSun(float alpha, MatrixStack matrices, CallbackInfo ci) {
if (timeChanger.isEnabled() && !timeChanger.renderSun.isEnabled()) ci.cancel(); if (timeChanger.isEnabled() && !timeChanger.renderSun.getValue()) ci.cancel();
} }
@Inject(method = "renderMoon", at = @At("HEAD"), cancellable = true) @Inject(method = "renderMoon", at = @At("HEAD"), cancellable = true)
private void onRenderMoon(MoonPhase moonPhase, float alpha, MatrixStack matrices, CallbackInfo ci) { private void onRenderMoon(MoonPhase moonPhase, float alpha, MatrixStack matrices, CallbackInfo ci) {
if (!timeChanger.isEnabled()) return; if (!timeChanger.isEnabled()) return;
if (!timeChanger.renderMoon.isEnabled()) ci.cancel(); if (!timeChanger.renderMoon.getValue()) ci.cancel();
} }
@ModifyArg(method = "renderCelestialBodies", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/SkyRendering;renderMoon(Lnet/minecraft/world/MoonPhase;FLnet/minecraft/client/util/math/MatrixStack;)V")) @ModifyArg(method = "renderCelestialBodies", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/SkyRendering;renderMoon(Lnet/minecraft/world/MoonPhase;FLnet/minecraft/client/util/math/MatrixStack;)V"))
@@ -45,12 +45,12 @@ public abstract class SkyRendererMixin {
@Inject(method = "renderStars", at = @At("HEAD"), cancellable = true) @Inject(method = "renderStars", at = @At("HEAD"), cancellable = true)
private void onRenderStars(float brightness, MatrixStack matrices, CallbackInfo ci) { private void onRenderStars(float brightness, MatrixStack matrices, CallbackInfo ci) {
if (timeChanger.isEnabled() && !timeChanger.renderStars.isEnabled()) ci.cancel(); if (timeChanger.isEnabled() && !timeChanger.renderStars.getValue()) ci.cancel();
} }
@Inject(method = "drawEndLightFlash", at = @At("HEAD"), cancellable = true) @Inject(method = "drawEndLightFlash", at = @At("HEAD"), cancellable = true)
private void onEndFlash(MatrixStack matrixStack, float f, float skyFactor, float pitch, CallbackInfo ci) { private void onEndFlash(MatrixStack matrixStack, float f, float skyFactor, float pitch, CallbackInfo ci) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class); NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (noRender.isEnabled() && !noRender.endFlashes.isEnabled()) ci.cancel(); if (noRender.isEnabled() && !noRender.endFlashes.getValue()) ci.cancel();
} }
} }
@@ -21,8 +21,8 @@ public abstract class StatusEffectFogModifierMixin {
public boolean noRenderBadEffects(boolean original) { public boolean noRenderBadEffects(boolean original) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class); NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (!noRender.isEnabled()) return original; if (!noRender.isEnabled()) return original;
if (getStatusEffect() == StatusEffects.BLINDNESS && !noRender.blindnessEffect.isEnabled()) return false; if (getStatusEffect() == StatusEffects.BLINDNESS && !noRender.blindnessEffect.getValue()) return false;
if (getStatusEffect() == StatusEffects.DARKNESS && !noRender.darknessEffect.isEnabled()) return false; if (getStatusEffect() == StatusEffects.DARKNESS && !noRender.darknessEffect.getValue()) return false;
return original; return original;
} }
} }
@@ -13,6 +13,6 @@ public abstract class StringHelperMixin {
@ModifyArg(method = "truncateChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/StringHelper;truncate(Ljava/lang/String;IZ)Ljava/lang/String;"), index = 1) @ModifyArg(method = "truncateChat", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/StringHelper;truncate(Ljava/lang/String;IZ)Ljava/lang/String;"), index = 1)
private static int onTruncate(int maxLength) { private static int onTruncate(int maxLength) {
ChatPlus chatPlus = ModuleManager.INSTANCE.getModuleByClass(ChatPlus.class); ChatPlus chatPlus = ModuleManager.INSTANCE.getModuleByClass(ChatPlus.class);
return ((chatPlus.isEnabled() && chatPlus.noCharLimit.isEnabled()) ? Integer.MAX_VALUE : maxLength); return ((chatPlus.isEnabled() && chatPlus.noCharLimit.getValue()) ? Integer.MAX_VALUE : maxLength);
} }
} }
@@ -13,7 +13,7 @@ public abstract class StuckArrowsFeatureRendererMixin {
@ModifyReturnValue(method = "getObjectCount", at = @At("RETURN")) @ModifyReturnValue(method = "getObjectCount", at = @At("RETURN"))
private int noRenderStuckArrows(int original) { private int noRenderStuckArrows(int original) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class); NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (noRender.isEnabled() && !noRender.stuckArrows.isEnabled()) return 0; if (noRender.isEnabled() && !noRender.stuckArrows.getValue()) return 0;
return original; return original;
} }
} }
@@ -24,17 +24,17 @@ public abstract class TextRendererDrawerMixin {
@Redirect(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isBold()Z")) @Redirect(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isBold()Z"))
private boolean noRenderBold(Style style) { private boolean noRenderBold(Style style) {
return !(noRender.isEnabled() && !noRender.bold.isEnabled()) && style.isBold(); return !(noRender.isEnabled() && !noRender.bold.getValue()) && style.isBold();
} }
@Redirect(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isUnderlined()Z")) @Redirect(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isUnderlined()Z"))
private boolean noRenderUnderlined(Style style) { private boolean noRenderUnderlined(Style style) {
return !(noRender.isEnabled() && !noRender.underlined.isEnabled()) && style.isUnderlined(); return !(noRender.isEnabled() && !noRender.underlined.getValue()) && style.isUnderlined();
} }
@Redirect(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isStrikethrough()Z")) @Redirect(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isStrikethrough()Z"))
private boolean noRenderStrikethrough(Style style) { private boolean noRenderStrikethrough(Style style) {
return !(noRender.isEnabled() && !noRender.strikethrough.isEnabled()) && style.isStrikethrough(); return !(noRender.isEnabled() && !noRender.strikethrough.getValue()) && style.isStrikethrough();
} }
@ModifyArg(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer$Drawer;getRenderColor(Lnet/minecraft/text/TextColor;)I")) @ModifyArg(method = "accept(ILnet/minecraft/text/Style;Lnet/minecraft/client/font/BakedGlyph;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer$Drawer;getRenderColor(Lnet/minecraft/text/TextColor;)I"))
@@ -13,6 +13,6 @@ public abstract class TextRendererMixin {
@ModifyExpressionValue(method = "getGlyph", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isObfuscated()Z")) @ModifyExpressionValue(method = "getGlyph", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isObfuscated()Z"))
private boolean noRenderMTS(boolean original) { private boolean noRenderMTS(boolean original) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class); NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
return (!noRender.isEnabled() || noRender.scrambledText.isEnabled()) && original; return (!noRender.isEnabled() || noRender.scrambledText.getValue()) && original;
} }
} }
@@ -29,14 +29,14 @@ public abstract class WeatherRenderingMixin {
@Inject(method = "addParticlesAndSound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;addParticleClient(Lnet/minecraft/particle/ParticleEffect;DDDDDD)V"), cancellable = true) @Inject(method = "addParticlesAndSound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;addParticleClient(Lnet/minecraft/particle/ParticleEffect;DDDDDD)V"), cancellable = true)
private void noRainParticles(ClientWorld world, Camera camera, int ticks, ParticlesMode particlesMode, int weatherRadius, CallbackInfo ci) { private void noRainParticles(ClientWorld world, Camera camera, int ticks, ParticlesMode particlesMode, int weatherRadius, CallbackInfo ci) {
if (noRender.isEnabled() && !noRender.rain.isEnabled()) ci.cancel(); if (noRender.isEnabled() && !noRender.rain.getValue()) ci.cancel();
} }
@Inject(method = "renderPrecipitation", at = @At("HEAD")) @Inject(method = "renderPrecipitation", at = @At("HEAD"))
private void noRenderRainAndSnow(VertexConsumerProvider vertexConsumers, Vec3d pos, WeatherRenderState weatherRenderState, CallbackInfo ci) { private void noRenderRainAndSnow(VertexConsumerProvider vertexConsumers, Vec3d pos, WeatherRenderState weatherRenderState, CallbackInfo ci) {
if (noRender.isEnabled()) { if (noRender.isEnabled()) {
if (!noRender.rain.isEnabled()) weatherRenderState.rainPieces.clear(); if (!noRender.rain.getValue()) weatherRenderState.rainPieces.clear();
if (!noRender.snow.isEnabled()) weatherRenderState.snowPieces.clear(); if (!noRender.snow.getValue()) weatherRenderState.snowPieces.clear();
} }
} }
} }
@@ -12,16 +12,12 @@ import net.minecraft.client.render.*;
import net.minecraft.client.render.state.WorldRenderState; import net.minecraft.client.render.state.WorldRenderState;
import net.minecraft.client.util.ObjectAllocator; import net.minecraft.client.util.ObjectAllocator;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.ColorHelper;
import net.minecraft.util.math.RotationAxis; import net.minecraft.util.math.RotationAxis;
import net.minecraft.util.profiler.Profiler; import net.minecraft.util.profiler.Profiler;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.joml.Vector4f; import org.joml.Vector4f;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -56,21 +52,28 @@ public abstract class WorldRendererMixin {
@Inject(method = "renderTargetBlockOutline", at = @At("HEAD"), cancellable = true) @Inject(method = "renderTargetBlockOutline", at = @At("HEAD"), cancellable = true)
private void noRenderBlockOutlinesFreecam(VertexConsumerProvider.Immediate immediate, MatrixStack matrices, boolean renderBlockOutline, WorldRenderState renderStates, CallbackInfo ci) { private void noRenderBlockOutlinesFreecam(VertexConsumerProvider.Immediate immediate, MatrixStack matrices, boolean renderBlockOutline, WorldRenderState renderStates, CallbackInfo ci) {
Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class); Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
if (freecam.isEnabled() && !freecam.blockOutlines.isEnabled()) ci.cancel(); if (freecam.isEnabled() && !freecam.blockOutlines.getValue()) ci.cancel();
} }
@Inject(method = "hasBlindnessOrDarkness(Lnet/minecraft/client/render/Camera;)Z", at = @At("HEAD"), cancellable = true) @Inject(method = "hasBlindnessOrDarkness(Lnet/minecraft/client/render/Camera;)Z", at = @At("HEAD"), cancellable = true)
private void hasBlindnessOrDarkness(Camera camera, CallbackInfoReturnable<Boolean> cir) { private void hasBlindnessOrDarkness(Camera camera, CallbackInfoReturnable<Boolean> cir) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class); NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (!noRender.isEnabled()) return; if (!noRender.isEnabled()) return;
if (!noRender.blindnessEffect.isEnabled() || !noRender.darknessEffect.isEnabled()) cir.setReturnValue(null); if (!noRender.blindnessEffect.getValue() || !noRender.darknessEffect.getValue()) cir.setReturnValue(null);
} }
@Redirect(method = "renderTargetBlockOutline", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/ColorHelper;toAlpha(I)I"))
private int modifyBlockOutlineColor(int alpha) {
BlockOutline outline = ModuleManager.INSTANCE.getModuleByClass(BlockOutline.class);
if (!outline.isEnabled()) return ColorHelper.toAlpha(alpha);
@ModifyArg(method = "renderTargetBlockOutline", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;drawBlockOutline(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;DDDLnet/minecraft/client/render/state/OutlineRenderState;IF)V"))
private int modifyBlockOutlineColor(int original) {
BlockOutline outline = ModuleManager.INSTANCE.getModuleByClass(BlockOutline.class);
if (!outline.isEnabled()) return original;
return outline.color.getRGB(); return outline.color.getRGB();
} }
@ModifyArg(method = "renderTargetBlockOutline", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;drawBlockOutline(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;DDDLnet/minecraft/client/render/state/OutlineRenderState;IF)V"))
private float modifyBlockOutlineLineWidth(float original) {
BlockOutline outline = ModuleManager.INSTANCE.getModuleByClass(BlockOutline.class);
if (!outline.isEnabled()) return original;
return outline.lineWidth.getFloatValue();
}
} }
@@ -11,7 +11,9 @@ public enum Category {
NETWORK("red"), NETWORK("red"),
CLIENT("cliente"), CLIENT("cliente"),
MISC("misc."); MISC("misc."),
ALL("todos");
private final String name; private final String name;
Category(String name) { this.name = name; } Category(String name) { this.name = name; }
@@ -16,7 +16,6 @@ import org.lwjgl.glfw.GLFW;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
// clase base para los módulos // clase base para los módulos
public class Module { public class Module {
@@ -53,12 +52,12 @@ public class Module {
this.description = description; this.description = description;
this.category = category; this.category = category;
sgGeneral.addAll(bind, keyMode, notify); sgGeneral.addAll(bind, keyMode, notify);
this.bind.setDefaultKey(key); this.bind.setDefaultValue(key);
// puto marcos // puto marcos
if (ConfigManager.getConfig().settings if (ConfigManager.getConfig().settings
.get(this.getName() + ":" + bind.getName()) == null) .get(this.getName() + ":" + bind.getName()) == null)
this.bind.setKey(key); this.bind.setValue(key);
} }
@@ -83,8 +82,12 @@ public class Module {
return null; return null;
} }
public List<Setting> getSettings() { public SettingGroup getSgGeneral() {
List<Setting> settings = new ArrayList<>(); return sgGeneral;
}
public List<Setting<?>> getSettings() {
List<Setting<?>> settings = new ArrayList<>();
sgs.forEach(sg -> sg.forEach(settings::add)); sgs.forEach(sg -> sg.forEach(settings::add));
return settings; return settings;
} }
@@ -99,7 +102,7 @@ public class Module {
} }
public void onEnable() { public void onEnable() {
if (notify.isEnabled()) ChatUtil.info(getName() + " fue activado"); if (notify.getValue()) ChatUtil.info(getName() + " fue activado");
for (Method method : getClass().getDeclaredMethods()) for (Method method : getClass().getDeclaredMethods())
if (method.isAnnotationPresent(SubscribeEvent.class)) { if (method.isAnnotationPresent(SubscribeEvent.class)) {
Sputnik.EVENT_BUS.register(this); Sputnik.EVENT_BUS.register(this);
@@ -109,7 +112,7 @@ public class Module {
} }
public void onDisable() { public void onDisable() {
if (notify.isEnabled()) ChatUtil.info(getName() + " fue desactivado"); if (notify.getValue()) ChatUtil.info(getName() + " fue desactivado");
if (Sputnik.EVENT_BUS.isRegistered(this)) if (Sputnik.EVENT_BUS.isRegistered(this))
Sputnik.EVENT_BUS.unregister(this); Sputnik.EVENT_BUS.unregister(this);
Sputnik.EVENT_BUS.post(new ToggleModuleEvent(this)); Sputnik.EVENT_BUS.post(new ToggleModuleEvent(this));
@@ -165,16 +168,16 @@ public class Module {
} }
public int getKey() { public int getKey() {
return bind.getKey(); return bind.getValue();
} }
public void setKey(int key) { public void setKey(int key) {
bind.setKey(key); bind.setValue(key);
} }
public void assignKey(int key) { public void assignKey(int key) {
bind.setDefaultKey(key); bind.setDefaultValue(key);
bind.setKey(key); bind.setValue(key);
} }
public KeySetting getBind() { public KeySetting getBind() {
@@ -2,6 +2,7 @@ package me.retucio.sputnik.module;
import me.retucio.sputnik.Sputnik; import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.SubscribeEvent; import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.module.modules.client.DiscordRPC;
import me.retucio.sputnik.module.modules.client.HUD; import me.retucio.sputnik.module.modules.client.HUD;
import me.retucio.sputnik.module.modules.camera.*; import me.retucio.sputnik.module.modules.camera.*;
import me.retucio.sputnik.module.modules.misc.*; import me.retucio.sputnik.module.modules.misc.*;
@@ -10,6 +11,7 @@ import me.retucio.sputnik.module.modules.player.*;
import me.retucio.sputnik.module.modules.render.*; import me.retucio.sputnik.module.modules.render.*;
import me.retucio.sputnik.module.modules.render.CritsPlus; import me.retucio.sputnik.module.modules.render.CritsPlus;
import me.retucio.sputnik.module.modules.world.*; import me.retucio.sputnik.module.modules.world.*;
import me.retucio.sputnik.util.MiscUtil;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
@@ -44,9 +46,11 @@ public class ModuleManager {
modules.add(new ColoredSigns()); modules.add(new ColoredSigns());
modules.add(new CritsPlus()); modules.add(new CritsPlus());
modules.add(new DamageOverlay()); modules.add(new DamageOverlay());
modules.add(new DiscordRPC());
modules.add(new ElytraBounce()); modules.add(new ElytraBounce());
modules.add(new FakePlayer()); modules.add(new FakePlayer());
modules.add(new FastUse()); modules.add(new FastUse());
modules.add(new Fonts());
modules.add(new Freecam()); modules.add(new Freecam());
modules.add(new Freelook()); modules.add(new Freelook());
modules.add(new Fullbright()); modules.add(new Fullbright());
@@ -54,6 +58,7 @@ public class ModuleManager {
modules.add(new HandView()); modules.add(new HandView());
modules.add(new Headhitters()); modules.add(new Headhitters());
modules.add(new HUD()); modules.add(new HUD());
modules.add(new InfiniteElytra());
modules.add(new InventoryPlus()); modules.add(new InventoryPlus());
modules.add(new LightOverlay()); modules.add(new LightOverlay());
modules.add(new LogoutSpots()); modules.add(new LogoutSpots());
@@ -62,21 +67,25 @@ public class ModuleManager {
modules.add(new NoRender()); modules.add(new NoRender());
modules.add(new Offhand()); modules.add(new Offhand());
modules.add(new PacketDelay()); modules.add(new PacketDelay());
modules.add(new Particles());
modules.add(new PerspectivePlus()); modules.add(new PerspectivePlus());
modules.add(new PortalGUI()); modules.add(new PortalGUI());
modules.add(new Racist()); modules.add(new Racist());
modules.add(new Reconnect()); modules.add(new Reconnect());
modules.add(new ReverseStep());
modules.add(new Rotations()); modules.add(new Rotations());
modules.add(new RPackBypass()); modules.add(new RPackBypass());
modules.add(new SafeWalk()); modules.add(new SafeWalk());
modules.add(new ScreenshotPlus()); modules.add(new ScreenshotPlus());
modules.add(new ShulkerPeek()); modules.add(new ShulkerPeek());
modules.add(new Step());
modules.add(new StrongholdTriangulator());
modules.add(new TimeChanger()); modules.add(new TimeChanger());
modules.add(new UIMove()); modules.add(new UIMove());
modules.add(new WarnLowDurability()); modules.add(new WarnLowDurability());
modules.add(new Zoom()); modules.add(new Zoom());
modules.sort(Comparator.comparing(module -> module.getName().toLowerCase())); modules.sort(Comparator.comparing(module -> MiscUtil.removeAccentMarks(module.getName().toLowerCase())));
// registrar los "listeners" necesarios // registrar los "listeners" necesarios
for (Module module : getEnabledModules()) { for (Module module : getEnabledModules()) {
@@ -105,7 +114,8 @@ public class ModuleManager {
public Module getModuleByName(String name) { public Module getModuleByName(String name) {
for (Module module : modules) for (Module module : modules)
if (module.getName().equalsIgnoreCase(name)) return module; if (MiscUtil.removeAccentMarks(module.getName()).equalsIgnoreCase(name))
return module;
return null; return null;
} }
@@ -87,7 +87,7 @@ public class Freecam extends Module {
fovScale = mc.options.getFovEffectScale().getValue(); fovScale = mc.options.getFovEffectScale().getValue();
viewBobbing = mc.options.getBobView().getValue(); viewBobbing = mc.options.getBobView().getValue();
if (staticView.isEnabled()) { if (staticView.getValue()) {
mc.options.getFovEffectScale().setValue(0D); mc.options.getFovEffectScale().setValue(0D);
mc.options.getBobView().setValue(false); mc.options.getBobView().setValue(false);
} }
@@ -119,25 +119,25 @@ public class Freecam extends Module {
down = KeyUtil.isKeyDown(mc.options.sneakKey); down = KeyUtil.isKeyDown(mc.options.sneakKey);
unpress(); unpress();
if (reloadChunks.isEnabled()) mc.worldRenderer.reload(); if (reloadChunks.getValue()) mc.worldRenderer.reload();
super.onEnable(); super.onEnable();
} }
@Override @Override
public void onDisable() { public void onDisable() {
if (reloadChunks.isEnabled()) mc.execute(mc.worldRenderer::reload); if (reloadChunks.getValue()) mc.execute(mc.worldRenderer::reload);
mc.options.setPerspective(perspective); mc.options.setPerspective(perspective);
crouching = false; crouching = false;
if (staticView.isEnabled()) { if (staticView.getValue()) {
mc.options.getFovEffectScale().setValue(fovScale); mc.options.getFovEffectScale().setValue(fovScale);
mc.options.getBobView().setValue(viewBobbing); mc.options.getBobView().setValue(viewBobbing);
} }
// para no flaggear el anticheat, cancelar cualquier acción dejada a medias estando en modo libre // para no flaggear el anticheat, cancelar cualquier acción dejada a medias estando en modo libre
if (cancelActionPackets.isEnabled()) { if (cancelActionPackets.getValue()) {
if (mc.interactionManager != null) if (mc.interactionManager != null)
mc.interactionManager.cancelBlockBreaking(); mc.interactionManager.cancelBlockBreaking();
@@ -199,7 +199,7 @@ public class Freecam extends Module {
@SubscribeEvent @SubscribeEvent
public void onSendPacket(PacketEvent.Send event) { public void onSendPacket(PacketEvent.Send event) {
if (!isEnabled() || !cancelActionPackets.isEnabled()) return; if (!isEnabled() || !cancelActionPackets.getValue()) return;
if (event.getStage() != Stage.PRE) return; if (event.getStage() != Stage.PRE) return;
Packet<?> packet = event.getPacket(); Packet<?> packet = event.getPacket();
@@ -279,7 +279,7 @@ public class Freecam extends Module {
@SubscribeEvent @SubscribeEvent
private void onMouseScroll(MouseScrollEvent event) { private void onMouseScroll(MouseScrollEvent event) {
if (scrollSens.getValue() > 0 && mc.currentScreen == null && KeyUtil.isKeyDown(scrollKey.getKey())) { if (scrollSens.getValue() > 0 && mc.currentScreen == null && KeyUtil.isKeyDown(scrollKey.getValue())) {
speed += event.getVertical() / 4 * (scrollSens.getValue() * speed); speed += event.getVertical() / 4 * (scrollSens.getValue() * speed);
if (speed < 0.1) speed = 0.1; if (speed < 0.1) speed = 0.1;
event.cancel(); event.cancel();
@@ -304,7 +304,7 @@ public class Freecam extends Module {
if (mc.player.getId() == packet.playerId()) if (mc.player.getId() == packet.playerId())
toggle(); toggle();
} else if (event.getPacket() instanceof HealthUpdateS2CPacket packet) { } else if (event.getPacket() instanceof HealthUpdateS2CPacket packet) {
if (mc.player.getHealth() - packet.getHealth() > 0 && toggleOnDamage.isEnabled()) { if (mc.player.getHealth() - packet.getHealth() > 0 && toggleOnDamage.getValue()) {
ChatUtil.info("cámara libre se ha desactivado porque has recibido daño"); ChatUtil.info("cámara libre se ha desactivado porque has recibido daño");
toggle(); toggle();
} }
@@ -324,22 +324,22 @@ public class Freecam extends Module {
@SubscribeEvent @SubscribeEvent
public void onBreakBlock(BreakBlockEvent event) { public void onBreakBlock(BreakBlockEvent event) {
if (cancelActionPackets.isEnabled()) event.cancel(); if (cancelActionPackets.getValue()) event.cancel();
} }
@SubscribeEvent @SubscribeEvent
public void onPlaceBlock(PlaceBlockEvent event) { public void onPlaceBlock(PlaceBlockEvent event) {
if (cancelActionPackets.isEnabled()) event.cancel(); if (cancelActionPackets.getValue()) event.cancel();
} }
@SubscribeEvent @SubscribeEvent
public void onInteractEntity(InteractEntityEvent event) { public void onInteractEntity(InteractEntityEvent event) {
if (cancelActionPackets.isEnabled()) event.cancel(); if (cancelActionPackets.getValue()) event.cancel();
} }
@SubscribeEvent @SubscribeEvent
public void onAttack(AttackEntityEvent event) { public void onAttack(AttackEntityEvent event) {
if (cancelActionPackets.isEnabled()) event.cancel(); if (cancelActionPackets.getValue()) event.cancel();
} }
public void changeLookDirection(double deltaX, double deltaY) { public void changeLookDirection(double deltaX, double deltaY) {
@@ -39,7 +39,7 @@ public class Freelook extends Module {
keyMode.setValue(KeyModes.HOLD); keyMode.setValue(KeyModes.HOLD);
notify.setDefaultValue(false); notify.setDefaultValue(false);
notify.setEnabled(false); notify.setValue(false);
} }
@Override @Override
@@ -57,7 +57,7 @@ public class PerspectivePlus extends Module {
if (mc.options.getPerspective() == net.minecraft.client.option.Perspective.FIRST_PERSON if (mc.options.getPerspective() == net.minecraft.client.option.Perspective.FIRST_PERSON
|| mc.currentScreen != null || scrollSens.getValue() <= 0) return; || mc.currentScreen != null || scrollSens.getValue() <= 0) return;
if (KeyUtil.isKeyDown(scrollKey.getKey())) { if (KeyUtil.isKeyDown(scrollKey.getValue())) {
distance -= event.getVertical() / 4 * (scrollSens.getValue() * distance); distance -= event.getVertical() / 4 * (scrollSens.getValue() * distance);
event.cancel(); event.cancel();
} }
@@ -29,14 +29,14 @@ public class Rotations extends Module {
mc.player.setYaw(yaw.getFloatValue()); mc.player.setYaw(yaw.getFloatValue());
mc.player.setPitch(pitch.getFloatValue()); mc.player.setPitch(pitch.getFloatValue());
if (serverSide.isEnabled()) if (serverSide.getValue())
mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.LookAndOnGround( mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.LookAndOnGround(
yaw.getFloatValue(), pitch.getFloatValue(), mc.player.isOnGround(), mc.player.horizontalCollision)); yaw.getFloatValue(), pitch.getFloatValue(), mc.player.isOnGround(), mc.player.horizontalCollision));
} }
@SubscribeEvent @SubscribeEvent
public void onChangeRotation(ChangeRotationEvent event) { public void onChangeRotation(ChangeRotationEvent event) {
if (smooth.isEnabled() if (smooth.getValue()
&& (event.getYaw() != yaw.getFloatValue() || event.getPitch() != pitch.getFloatValue())){ && (event.getYaw() != yaw.getFloatValue() || event.getPitch() != pitch.getFloatValue())){
event.cancel(); event.cancel();
}} }}
@@ -50,7 +50,7 @@ public class Zoom extends Module {
keyMode.setValue(KeyModes.HOLD); keyMode.setValue(KeyModes.HOLD);
notify.setDefaultValue(false); notify.setDefaultValue(false);
notify.setEnabled(false); notify.setValue(false);
} }
@Override @Override
@@ -61,7 +61,7 @@ public class Zoom extends Module {
prevMouseSens = mc.options.getMouseSensitivity().getValue(); prevMouseSens = mc.options.getMouseSensitivity().getValue();
prevFov = mc.options.getFov().getValue(); prevFov = mc.options.getFov().getValue();
prevHUD = mc.options.hudHidden; prevHUD = mc.options.hudHidden;
mc.options.hudHidden = !showHUD.isEnabled(); mc.options.hudHidden = !showHUD.getValue();
value = defaultZoom.getValue(); value = defaultZoom.getValue();
@@ -83,14 +83,14 @@ public class Zoom extends Module {
@Override @Override
public void onTick() { public void onTick() {
mc.options.smoothCameraEnabled = smoothCam.isEnabled(); mc.options.smoothCameraEnabled = smoothCam.getValue();
if (!smoothCam.isEnabled()) if (!smoothCam.getValue())
mc.options.getMouseSensitivity().setValue(prevMouseSens * mouseSensMultiplier.getValue()); mc.options.getMouseSensitivity().setValue(prevMouseSens * mouseSensMultiplier.getValue());
} }
@SubscribeEvent @SubscribeEvent
private void onMouseScroll(MouseScrollEvent event) { private void onMouseScroll(MouseScrollEvent event) {
boolean key = scrollKey.getKey() == GLFW.GLFW_KEY_UNKNOWN || KeyUtil.isKeyDown(scrollKey.getKey()); boolean key = scrollKey.getValue() == GLFW.GLFW_KEY_UNKNOWN || KeyUtil.isKeyDown(scrollKey.getValue());
if (isEnabled() && scrollSens.getValue() > 0 && key) { if (isEnabled() && scrollSens.getValue() > 0 && key) {
value += event.getVertical() * 0.25 * (scrollSens.getValue() * value); value += event.getVertical() * 0.25 * (scrollSens.getValue() * value);
if (value < 1) value = 1; if (value < 1) value = 1;
@@ -0,0 +1,235 @@
package me.retucio.sputnik.module.modules.client;
import dev.firstdark.rpc.DiscordRpc;
import dev.firstdark.rpc.enums.ActivityType;
import dev.firstdark.rpc.enums.ErrorCode;
import dev.firstdark.rpc.exceptions.UnsupportedOsType;
import dev.firstdark.rpc.handlers.RPCEventHandler;
import dev.firstdark.rpc.models.DiscordRichPresence;
import dev.firstdark.rpc.models.User;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.Setting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.StringSetting;
import me.retucio.sputnik.util.ChatUtil;
public class DiscordRPC extends Module {
SettingGroup sgImage = addSg(new SettingGroup("imágenes", false));
SettingGroup sgButton = addSg(new SettingGroup("botón", false));
// general
public StringSetting details = sgGeneral.add(new StringSetting(
"detalles", "título",
"usando el mod de putas de retucio",
40
));
public StringSetting state = sgGeneral.add(new StringSetting(
"estado", "subtítulo",
"(se lo está pasando en grande)",
40
));
public StringSetting startTimestamp = sgGeneral.add(new StringSetting(
"sello de tiempo", "sello de tiempo del comienzo de la actividad, siguiendo el unix epoch (dejar vacío para ahora)",
"",
20
));
public EnumSetting<ActivityTypes> activityType = sgGeneral.add(new EnumSetting<>(
"tipo de actividad", "qué tipo de actividad se está llevando a cabo",
ActivityTypes.class, ActivityTypes.PLAYING
));
public StringSetting appId = sgGeneral.add(new StringSetting(
"id del bot", "id del bot a usar (obtener de discord.dev)",
"1314254766150258729", 20
));
// imágenes
public StringSetting largeImageKey = sgImage.add(new StringSetting(
"imagen grande", "clave de la imagen grande",
"pengiun",
40
));
public StringSetting largeImageText = sgImage.add(new StringSetting(
"texto de la imagen grande", "texto mostrado junto a la imagen grande",
"pengüino",
40
));
public StringSetting smallImageKey = sgImage.add(new StringSetting(
"imagen pequeña", "clave de la imagen pequeña",
"pengiun",
40
));
public StringSetting smallImageText = sgImage.add(new StringSetting(
"texto de la imagen pequeña", "texto mostrado junto a la imagen pequeña",
"pengüino",
40
));
// botón
public StringSetting buttonText = sgButton.add(new StringSetting(
"texto del botón", "texto a mostrar en el botón",
"hola",
20
));
public StringSetting buttonUrl = sgButton.add(new StringSetting(
"url del botón", "rickroll en gran 26 :wilted_rose:",
"https://www.youtube.com/watch?v=dQw4w9WgXcQ",
20
));
// crear el rpc
private boolean initialized;
DiscordRpc rpc = new DiscordRpc();
RPCEventHandler handler = new RPCEventHandler() {
@Override
public void ready(User user) {
rpc.updatePresence(getPresence());
}
@Override
public void disconnected(ErrorCode errorCode, String message) {
ChatUtil.warn("desconectado: " + errorCode + " - " + message);
toggle();
}
@Override
public void errored(ErrorCode errorCode, String message) {
ChatUtil.error("error: " + errorCode + " - " + message);
toggle();
}
};
public DiscordRPC() {
super("discordRPC",
"personaliza la actividad de tu perfil en dishkor",
Category.CLIENT);
rpc.setDebugMode(false);
for (Setting<?> s : getSettings()) {
s.onUpdate(v -> update());
}
appId.onUpdate(v -> reload());
}
@Override
public void onEnable() {
String token = appId.getValue();
if (token == null || token.trim().isEmpty()) {
ChatUtil.error("configura el token del bot primero");
toggle();
return;
}
try {
rpc.init(token, handler, false);
initialized = true;
} catch (UnsupportedOsType e) {
ChatUtil.error("sistema operativo no soportado");
toggle();
} catch (Exception e) {
ChatUtil.error("error al inicializar rpc: " + e.getMessage());
toggle();
}
super.onEnable();
}
@Override
public void onDisable() {
if (initialized) {
rpc.shutdown();
initialized = false;
}
super.onDisable();
}
private DiscordRichPresence getPresence() {
return DiscordRichPresence.builder()
.details(details.getValue())
.state(state.getValue())
.largeImageKey(largeImageKey.getValue())
.largeImageText(largeImageText.getValue())
.smallImageKey(smallImageKey.getValue())
.smallImageText(smallImageText.getValue())
.startTimestamp(getTimestamp())
.activityType(activityType.getValue().getActivityType())
.button(DiscordRichPresence.RPCButton.of(
buttonText.getValue(),
buttonUrl.getValue())
).build();
}
private void update() {
if (initialized && isEnabled()) {
try {
rpc.updatePresence(getPresence());
} catch (Exception e) {
ChatUtil.error("error al actualizar rpc: " + e.getMessage());
}
}
}
public void reload() {
if (initialized && isEnabled()) {
rpc.shutdown();
try {
rpc.init(appId.getValue(), handler, false);
} catch (UnsupportedOsType e) {
ChatUtil.error(e.getMessage());
}
}
}
private long getTimestamp() {
long timestamp;
if (startTimestamp.getValue().trim().isEmpty()) {
timestamp = System.currentTimeMillis();
} else {
try {
timestamp = Long.parseLong(startTimestamp.getValue());
} catch (NumberFormatException e) {
ChatUtil.error("introduce un NÚMERO (o déjalo vacío)");
timestamp = System.currentTimeMillis();
}
}
return timestamp / 1000;
}
public enum ActivityTypes {
PLAYING("jugando"),
STREAMING("streameando"),
LISTENING("escuchando"),
WATCHING("viendo"),
CUSTOM("custom"),
COMPETING("compitiendo");
private final String name;
ActivityTypes(String name) { this.name = name; }
@Override public String toString() { return name; }
private ActivityType getActivityType() { return ActivityType.values()[ordinal()]; }
}
}
@@ -25,21 +25,92 @@ public class HUD extends Module {
SettingGroup sgElements = addSg(new SettingGroup("elementos", false)); SettingGroup sgElements = addSg(new SettingGroup("elementos", false));
// editor // editor
public KeySetting editorKey = sgEditor.add(new KeySetting("tecla del editor", "tecla asignada al editor de elementos del hud", GLFW.GLFW_KEY_PAGE_UP)); public KeySetting editorKey = sgEditor.add(new KeySetting(
"tecla del editor",
"tecla asignada al editor de elementos del hud",
GLFW.GLFW_KEY_PAGE_UP
));
public BooleanSetting axialMovement = sgEditor.add(new BooleanSetting(
"movimiento axial",
"te permite mover los elementos sobre los ejes más fácilmente",
true
));
public NumberSetting axisOffset = sgEditor.add(new NumberSetting(
"offset de los ejes",
"offset a tener en cuenta al usar el movimiento axial",
10,
0,
50,
1
));
public BooleanSetting arrowMovement = sgEditor.add(new BooleanSetting(
"movimiento con flechas",
"te permite mover el elemento seleccionado con las teclas de las flechas",
true
));
public NumberSetting arrowOffset = sgEditor.add(new NumberSetting(
"cuánto mover con las flechas",
"cuántos píxeles mover el elemento seleccionado al usar las flechas",
2,
1,
20,
1
));
// ajustes // renderizado
public ColorSetting color = sgDisplay.add(new ColorSetting("color", "color del texto de los elementos del HUD", public ColorSetting color = sgDisplay.add(new ColorSetting(
new Color(255, 255, 255, 255), false)); "color",
public BooleanSetting shadow = sgDisplay.add(new BooleanSetting("sombra", "texto con sombra", true)); "color del texto de los elementos del HUD",
public BooleanSetting showOnF3 = sgDisplay.add(new BooleanSetting("mostrar en F3", "renderizar HUD en el menú de debug", false)); new Color(255, 255, 255, 255), false)
public BooleanSetting showOnChat = sgDisplay.add(new BooleanSetting("mostrar en chat", "renderizar HUD en la pantalla del chat", false)); );
public BooleanSetting shadow = sgDisplay.add(new BooleanSetting(
"sombra",
"texto con sombra",
true
));
public BooleanSetting showOnF3 = sgDisplay.add(new BooleanSetting(
"mostrar en F3",
"renderizar HUD en el menú de debug",
false
));
public BooleanSetting showOnChat = sgDisplay.add(new BooleanSetting(
"mostrar en chat",
"renderizar HUD en la pantalla del chat",
false
));
public NumberSetting timezone = sgElements.add(new NumberSetting("zona horaria", "zona horaria en UTC+n", 1, -6, 6, 1)); // elementos
public EnumSetting<TimeFormat> timeFormat = sgElements.add(new EnumSetting<>("formato de la hora", "12h o 24h", TimeFormat.class, TimeFormat.TWENTY_FOUR_HOUR)); public NumberSetting timezone = sgElements.add(new NumberSetting(
public StringSetting customText = sgElements.add(new StringSetting("texto custom", "marca de agua (dejar vacío para quitar)", "adolf jitler inshtagram feishbuc twiter", 40)); "zona horaria",
public EnumSetting<CoordsMode> coordsMode = sgElements.add(new EnumSetting<>("modo de coordenadas", "qué coordenadas mostrar", CoordsMode.class, CoordsMode.OVERWORLD)); "zona horaria en UTC+n",
public EnumSetting<Dynosaurs> dyno = sgElements.add(new EnumSetting<>("dinosaurio", "qué dinosaurio mostrar", 1,
Dynosaurs.class, Dynosaurs.SPINOSAURUS)); -6,
6,
1
));
public EnumSetting<TimeFormat> timeFormat = sgElements.add(new EnumSetting<>(
"formato de la hora",
"12h o 24h",
TimeFormat.class,
TimeFormat.TWENTY_FOUR_HOUR
));
public StringSetting customText = sgElements.add(new StringSetting(
"texto custom",
"marca de agua (dejar vacío para quitar)",
"adolf jitler inshtagram feishbuc twiter",
40
));
public EnumSetting<CoordsMode> coordsMode = sgElements.add(new EnumSetting<>(
"modo de coordenadas",
"qué coordenadas mostrar",
CoordsMode.class,
CoordsMode.OVERWORLD
));
public EnumSetting<Dynosaurs> dyno = sgElements.add(new EnumSetting<>(
"dinosaurio",
"qué dinosaurio mostrar",
Dynosaurs.class, Dynosaurs.SPINOSAURUS
));
public HUD() { public HUD() {
super("HUD", super("HUD",
@@ -48,6 +119,9 @@ public class HUD extends Module {
GLFW.GLFW_KEY_F12 GLFW.GLFW_KEY_F12
); );
axialMovement.onUpdate(v -> axisOffset.setVisible(v));
arrowMovement.onUpdate(v -> arrowOffset.setVisible(v));
dyno.onUpdate(v -> { dyno.onUpdate(v -> {
DynoElement element = (DynoElement) HudRenderer.getElement(DynoElement.class); DynoElement element = (DynoElement) HudRenderer.getElement(DynoElement.class);
if (element != null) element.reloadTexture(); if (element != null) element.reloadTexture();
@@ -15,10 +15,25 @@ import java.util.WeakHashMap;
public class BossbarStack extends Module { public class BossbarStack extends Module {
public BooleanSetting stackBars = sgGeneral.add(new BooleanSetting("apilar barras", "apilar las bossbars", true)); public BooleanSetting stackBars = sgGeneral.add(new BooleanSetting(
public BooleanSetting hideNames = sgGeneral.add(new BooleanSetting("esconder nombres", "no renderiza el nombre de los bosses", false)); "apilar barras", "apilar las bossbars",
public NumberSetting spaceReduction = sgGeneral.add(new NumberSetting("reducción de espacio", "cuánto reducir el espacio entre bossbars", true
0, 0, 10, 0.1)); ));
public BooleanSetting hideNames = sgGeneral.add(new BooleanSetting(
"esconder nombres", "no renderiza el nombre de los bosses",
false
));
public NumberSetting spaceReduction = sgGeneral.add(new NumberSetting(
"reducción de espacio",
"cuánto reducir el espacio entre bossbars",
0,
0,
10,
0.1
));
private final Map<ClientBossBar, Integer> bossBarMap = new WeakHashMap<>(); private final Map<ClientBossBar, Integer> bossBarMap = new WeakHashMap<>();
@@ -30,16 +45,16 @@ public class BossbarStack extends Module {
@SubscribeEvent @SubscribeEvent
private void onRenderBossText(RenderBossbarEvent.BossText event) { private void onRenderBossText(RenderBossbarEvent.BossText event) {
if (hideNames.isEnabled()) { if (hideNames.getValue()) {
event.setName(Text.empty()); event.setName(Text.empty());
return; return;
} else if (bossBarMap.isEmpty() || !stackBars.isEnabled()) return; } else if (bossBarMap.isEmpty() || !stackBars.getValue()) return;
ClientBossBar bar = event.getBossBar(); ClientBossBar bar = event.getBossBar();
Integer amount = bossBarMap.get(bar); Integer amount = bossBarMap.get(bar);
bossBarMap.remove(bar); bossBarMap.remove(bar);
if (amount != null && !hideNames.isEnabled()) if (amount != null && !hideNames.getValue())
event.setName(event.getName().copy().append(" x" + amount)); event.setName(event.getName().copy().append(" x" + amount));
} }
@@ -50,7 +65,7 @@ public class BossbarStack extends Module {
@SubscribeEvent @SubscribeEvent
private void onRenderBossBars(RenderBossbarEvent.BossIterator event) { private void onRenderBossBars(RenderBossbarEvent.BossIterator event) {
if (stackBars.isEnabled()) { if (stackBars.getValue()) {
HashMap<String, ClientBossBar> chosenBarMap = new HashMap<>(); HashMap<String, ClientBossBar> chosenBarMap = new HashMap<>();
event.getIterator().forEachRemaining(bar -> { event.getIterator().forEachRemaining(bar -> {
String name = bar.getName().getString(); String name = bar.getName().getString();
@@ -82,7 +82,7 @@ public class ChatPlus extends Module {
Text message = event.getMessage(); Text message = event.getMessage();
// registrar mensajes para evitar su eliminación // registrar mensajes para evitar su eliminación
if (logger.isEnabled()) { if (logger.getValue()) {
String messageString = message.getString(); String messageString = message.getString();
if (loggerRegex.matcher(messageString).find()) { if (loggerRegex.matcher(messageString).find()) {
MutableText newMessage = Text.empty(); MutableText newMessage = Text.empty();
@@ -100,7 +100,7 @@ public class ChatPlus extends Module {
} }
// agregar sellos de tiempo a los mensajes // agregar sellos de tiempo a los mensajes
if (timestamps.isEnabled()) { if (timestamps.getValue()) {
Text timestamp = Text.literal("[" + dateFormat.format(new Date()) + "] ").formatted(Formatting.GRAY); Text timestamp = Text.literal("[" + dateFormat.format(new Date()) + "] ").formatted(Formatting.GRAY);
message = Text.empty().append(timestamp).append(message); message = Text.empty().append(timestamp).append(message);
} }
@@ -112,7 +112,7 @@ public class ChatPlus extends Module {
@SubscribeEvent @SubscribeEvent
private void onSendMessage(SendMessageEvent event) { private void onSendMessage(SendMessageEvent event) {
// evitar mandar coordenadas por el chat // evitar mandar coordenadas por el chat
if (coordsProtection.isEnabled() && containsCoordinates(event.getMessage())) { if (coordsProtection.getValue() && containsCoordinates(event.getMessage())) {
ChatUtil.warn(Text.literal("cuidadito con las coordenadas chavalín").append( ChatUtil.warn(Text.literal("cuidadito con las coordenadas chavalín").append(
getSendButton(event.getMessage()))); getSendButton(event.getMessage())));
@@ -127,7 +127,7 @@ public class ChatPlus extends Module {
@SuppressWarnings("DataFlowIssue") @SuppressWarnings("DataFlowIssue")
public void beforeDrawMessage(DrawContext context, ChatHudLine.Visible line, int y, int color) { public void beforeDrawMessage(DrawContext context, ChatHudLine.Visible line, int y, int color) {
if (!isEnabled() || !showHeads.isEnabled()) return; if (!isEnabled() || !showHeads.getValue()) return;
// dibujar la cabeza al principio del mensaje // dibujar la cabeza al principio del mensaje
if (((IChatHudLineVisible) (Object) line).sputnik$isStartOfEntry()) if (((IChatHudLineVisible) (Object) line).sputnik$isStartOfEntry())
@@ -139,7 +139,7 @@ public class ChatPlus extends Module {
public void afterDrawMessage(DrawContext context) { public void afterDrawMessage(DrawContext context) {
// finalizar renderizado de la cabeza // finalizar renderizado de la cabeza
if (!isEnabled() || !showHeads.isEnabled()) return; if (!isEnabled() || !showHeads.getValue()) return;
context.getMatrices().popMatrix(); context.getMatrices().popMatrix();
} }
@@ -218,7 +218,7 @@ public class ChatPlus extends Module {
} }
private void updateDateFormat() { private void updateDateFormat() {
dateFormat = new SimpleDateFormat(timestampSecs.isEnabled() ? "HH:mm:ss" : "HH:mm"); dateFormat = new SimpleDateFormat(timestampSecs.getValue() ? "HH:mm:ss" : "HH:mm");
} }
private boolean containsCoordinates(String message) { private boolean containsCoordinates(String message) {
@@ -52,10 +52,10 @@ public class ScreenshotPlus extends Module {
public void sendScreenshotMessage() { public void sendScreenshotMessage() {
MutableText baseText = Text.literal("captura de pantalla tomada\n"); MutableText baseText = Text.literal("captura de pantalla tomada\n");
if (saveButton.isEnabled() && !defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getSaveButton().append(" ")); if (saveButton.getValue() && !defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getSaveButton().append(" "));
if (copyButton.isEnabled()) baseText.append(getCopyButton().append(" ")); if (copyButton.getValue()) baseText.append(getCopyButton().append(" "));
if (openButton.isEnabled() && defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getOpenButton().append(" ")); if (openButton.getValue() && defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getOpenButton().append(" "));
if (discardButton.isEnabled() && !defaultAction.is(ScreenshotActions.NONE)) baseText.append(getDiscardButton().append(" ")); if (discardButton.getValue() && !defaultAction.is(ScreenshotActions.NONE)) baseText.append(getDiscardButton().append(" "));
ChatUtil.info(baseText); ChatUtil.info(baseText);
} }
@@ -62,7 +62,7 @@ public class ShulkerPeek extends Module {
@SubscribeEvent @SubscribeEvent
public void onKey(KeyEvent event) { public void onKey(KeyEvent event) {
if (mc.player == null) return; if (mc.player == null) return;
if (event.getKey() != previewKey.getKey()) return; if (event.getKey() != previewKey.getValue()) return;
if (event.getAction() == GLFW.GLFW_PRESS) { if (event.getAction() == GLFW.GLFW_PRESS) {
openPreviewScreen(); openPreviewScreen();
@@ -61,12 +61,12 @@ public class LogoutSpots extends Module {
outlines.onUpdate(v -> { outlines.onUpdate(v -> {
outlineColor.setVisible(v); outlineColor.setVisible(v);
fullHeight.setVisible(v || filling.isEnabled()); fullHeight.setVisible(v || filling.getValue());
}); });
filling.onUpdate(v -> { filling.onUpdate(v -> {
fillingColor.setVisible(v); fillingColor.setVisible(v);
fullHeight.setVisible(v || outlines.isEnabled()); fullHeight.setVisible(v || outlines.getValue());
}); });
dummy.onUpdate(v -> { dummy.onUpdate(v -> {
@@ -116,7 +116,7 @@ public class LogoutSpots extends Module {
if (player.getUuid().equals(entry.getProfile().id())) { if (player.getUuid().equals(entry.getProfile().id())) {
LogoutEntry logoutEntry = new LogoutEntry(player); LogoutEntry logoutEntry = new LogoutEntry(player);
if (mc.world != null && !mc.world.hasEntity(logoutEntry.dummy) && dummy.isEnabled()) if (mc.world != null && !mc.world.hasEntity(logoutEntry.dummy) && dummy.getValue())
mc.world.addEntity(logoutEntry.dummy); mc.world.addEntity(logoutEntry.dummy);
addLogoutSpot(logoutEntry); addLogoutSpot(logoutEntry);
@@ -248,21 +248,21 @@ public class LogoutSpots extends Module {
} }
public void renderBox(MatrixStack matrices) { public void renderBox(MatrixStack matrices) {
if (fullHeight.isEnabled()) { if (fullHeight.getValue()) {
if (outlines.isEnabled()) if (outlines.getValue())
RenderUtil.drawOutlineBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), outlineColor.getColor(), lineWidth.getFloatValue(), true); RenderUtil.drawOutlineBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), outlineColor.getValue(), lineWidth.getFloatValue(), true);
if (filling.isEnabled()) if (filling.getValue())
RenderUtil.drawFilledBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), fillingColor.getColor(), true); RenderUtil.drawFilledBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), fillingColor.getValue(), true);
} else { } else {
if (outlines.isEnabled()) { if (outlines.getValue()) {
RenderUtil.drawBlockFaceOutlines(matrices, RenderUtil.drawBlockFaceOutlines(matrices,
BlockPos.ofFloored(x + halfWidth, y, z + halfWidth), BlockPos.ofFloored(x + halfWidth, y, z + halfWidth),
Direction.UP, outlineColor.getColor(), lineWidth.getFloatValue(), true); Direction.UP, outlineColor.getValue(), lineWidth.getFloatValue(), true);
} }
if (filling.isEnabled()) { if (filling.getValue()) {
RenderUtil.drawBlockFaceFilled(matrices, RenderUtil.drawBlockFaceFilled(matrices,
BlockPos.ofFloored(x + halfWidth, y, z + halfWidth), BlockPos.ofFloored(x + halfWidth, y, z + halfWidth),
Direction.UP, fillingColor.getColor(), 0.001f, true); Direction.UP, fillingColor.getValue(), 0.001f, true);
} }
} }
} }
@@ -24,7 +24,7 @@ public class AttributeSwapper extends Module {
@Override @Override
public void onTick() { public void onTick() {
if (mc.player == null || !swap.isEnabled()) return; if (mc.player == null || !swap.getValue()) return;
if (delay < swapDelay.getIntValue()) delay++; if (delay < swapDelay.getIntValue()) delay++;
if (delay >= swapDelay.getIntValue() && prevSlot != -1) { if (delay >= swapDelay.getIntValue() && prevSlot != -1) {
mc.player.getInventory().setSelectedSlot(prevSlot); mc.player.getInventory().setSelectedSlot(prevSlot);
@@ -6,27 +6,68 @@ import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting; import me.retucio.sputnik.module.setting.settings.NumberSetting;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import org.lwjgl.glfw.GLFW;
public class FastUse extends Module { public class FastUse extends Module {
public BooleanSetting items = sgGeneral.add(new BooleanSetting("items", "usar items precozmente", true)); public BooleanSetting items = sgGeneral.add(new BooleanSetting(
public NumberSetting itemCooldown = sgGeneral.add(new NumberSetting("cooldown de items", "cooldown para usar items en ticks", 0, 0, 4, 1)); "items",
"usar items precozmente",
true
));
public NumberSetting itemCooldown = sgGeneral.add(new NumberSetting(
"cooldown de items",
"cooldown para usar items en ticks",
0,
0,
4,
1
));
public BooleanSetting blocks = sgGeneral.add(new BooleanSetting(
"bloques",
"colocar bloques precozmente",
true
));
public NumberSetting blockCooldown = sgGeneral.add(new NumberSetting(
"cooldown de bloques",
"cooldown para colocar bloques en ticks",
0,
0,
4,
1
));
public BooleanSetting mining = sgGeneral.add(new BooleanSetting(
"minar",
"minar precozmente",
true
));
public NumberSetting miningCooldown = sgGeneral.add(new NumberSetting(
"cooldown al minar",
"cooldown entre rotura de bloques en ticks",
5, 0, 20, 1
));
public BooleanSetting blocks = sgGeneral.add(new BooleanSetting("bloques", "colocar bloques precozmente", true));
public NumberSetting blockCooldown = sgGeneral.add(new NumberSetting("cooldown de bloques", "cooldown para colocar bloques en ticks", 0, 0, 4, 1));
public FastUse() { public FastUse() {
super("precoz", super("precoz",
"hace cosas como usar items o colocar bloques más rápido", "hace cosas como usar items o colocar bloques más rápido",
Category.PLAYER); Category.PLAYER,
GLFW.GLFW_KEY_F6);
items.onUpdate(v -> itemCooldown.setVisible(v)); items.onUpdate(v -> itemCooldown.setVisible(v));
blocks.onUpdate(v -> blockCooldown.setVisible(v)); blocks.onUpdate(v -> blockCooldown.setVisible(v));
} }
public int getCooldown(ItemStack stack) { public int getCooldown(ItemStack stack) {
if (stack.getItem() instanceof BlockItem && blocks.isEnabled()) return blockCooldown.getIntValue(); if (stack.getItem() instanceof BlockItem && blocks.getValue()) return blockCooldown.getIntValue();
if (items.isEnabled() && !(stack.getItem() instanceof BlockItem)) return itemCooldown.getIntValue(); if (items.getValue() && !(stack.getItem() instanceof BlockItem)) return itemCooldown.getIntValue();
else return 4; // cooldown por defecto, 4 ticks else return 4; // cooldown por defecto, 4 ticks
} }
} }
@@ -0,0 +1,133 @@
package me.retucio.sputnik.module.modules.player;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.UseItemEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import net.minecraft.item.Items;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
// "pedido prestado" de: https://github.com/meanwhile131/elytra-infinite
public class InfiniteElytra extends Module {
private FlyState state;
private float pitch;
private double lowestY;
public NumberSetting pitchDown = sgGeneral.add(new NumberSetting(
"cabeceo (abajo)",
"cabeceo al ir hacia abajo",
30,
-90,
90,
1
));
public NumberSetting pitchUp = sgGeneral.add(new NumberSetting(
"cabeceo (arriba)",
"cabeceo al ir hacia arriba",
-48,
-90,
90,
1
));
public NumberSetting pitchDownSpeed = sgGeneral.add(new NumberSetting(
"velocidad de cabeceo (abajo)",
"velocidad del cabeceo al ir hacia abajo",
0.5,
0.01,
5,
0.1
));
public NumberSetting pitchUpVelocity = sgGeneral.add(new NumberSetting(
"velocidad de cabeceo (arriba)",
"velocidad del cabeceo al ir hacia arriba",
2,
0.01,
5,
0.1
));
public NumberSetting ticksCollisionLookAhead = sgGeneral.add(new NumberSetting(
"precaución de colisión",
"precaución de colisión en ticks",
10,
0,
20,
1
));
public InfiniteElytra() {
super("avioneta",
"vuela infinitamente, aprovechándose el sistema defectuoso que hizo mojang (hace falta tirarse de unos 50 bloques de altura)",
Category.PLAYER);
}
@Override
public void onTick() {
if (mc.player == null || mc.world == null || !mc.player.isGliding()) {
state = FlyState.NOT_FLYING;
return;
}
if (state == FlyState.NOT_FLYING) {
state = FlyState.GLIDING_DOWN;
pitch = pitchDown.getFloatValue();
} else if (state == FlyState.PITCHING_DOWN) {
pitch += Math.min(pitchDown.getFloatValue() - pitch, pitchDownSpeed.getFloatValue());
boolean movingDownwards = mc.player.getVelocity().y <= 0 && mc.player.getY() > lowestY;
if (pitch >= pitchDown.getFloatValue() || movingDownwards) {
pitch = pitchDown.getFloatValue();
state = FlyState.GLIDING_DOWN;
}
} else if (state == FlyState.GLIDING_DOWN) {
boolean willCollide = willCollideWhileGliding(ticksCollisionLookAhead.getIntValue());
if (willCollide || mc.player.getVelocity().horizontalLengthSquared() > Math.pow(pitchUpVelocity.getFloatValue(), 2)) {
pitch = pitchUp.getFloatValue();
state = FlyState.PITCHING_DOWN;
lowestY = mc.player.getY();
}
}
mc.player.setPitch(pitch);
}
@SubscribeEvent
public void onUseItem(UseItemEvent event) {
if (mc.player == null) return;
if (mc.player.getStackInHand(event.getHand()).getItem() == Items.FIREWORK_ROCKET && !mc.player.isSpectator() && mc.player.isGliding()) {
pitch = pitchUp.getFloatValue();
mc.player.setPitch(pitch);
state = FlyState.PITCHING_DOWN;
lowestY = mc.player.getY();
}
}
private boolean willCollideWhileGliding(int ticks) {
Vec3d velocity = mc.player.getVelocity();
Box boundingBox = mc.player.getBoundingBox();
for (int i = 0; i < ticks; i++) {
velocity = mc.player.calcGlidingVelocity(velocity);
boundingBox = boundingBox.offset(velocity);
if (!mc.world.isSpaceEmpty(null, boundingBox, true)) {
return true;
}
}
return false;
}
public enum FlyState {
NOT_FLYING,
GLIDING_DOWN,
PITCHING_DOWN;
}
}
@@ -50,15 +50,15 @@ public class InventoryPlus extends Module {
int rowOffset = InventoryUtil.getRowOffset(screen); int rowOffset = InventoryUtil.getRowOffset(screen);
if (KeyUtil.isKeyDown(row1key.getKey())) { if (KeyUtil.isKeyDown(row1key.getValue())) {
event.cancel(); event.cancel();
swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset); swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset);
} }
else if (KeyUtil.isKeyDown(row2key.getKey())) { else if (KeyUtil.isKeyDown(row2key.getValue())) {
event.cancel(); event.cancel();
swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset + 9); swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset + 9);
} }
else if (KeyUtil.isKeyDown(row3key.getKey())) { else if (KeyUtil.isKeyDown(row3key.getValue())) {
event.cancel(); event.cancel();
swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset + 18); swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset + 18);
} }
@@ -46,7 +46,7 @@ public class Offhand extends Module {
} }
if (holdingItem || (!mc.player.getOffHandStack().isEmpty() if (holdingItem || (!mc.player.getOffHandStack().isEmpty()
&& !override.isEnabled())) && !override.getValue()))
return; return;
if (mc.player.playerScreenHandler == mc.player.currentScreenHandler) { if (mc.player.playerScreenHandler == mc.player.currentScreenHandler) {
@@ -0,0 +1,84 @@
package me.retucio.sputnik.module.modules.player;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext;
public class ReverseStep extends Module {
public NumberSetting height = sgGeneral.add(new NumberSetting(
"altura", "altura máxima a bajar",
1, 0, 20, 0.1
));
public NumberSetting velocity = sgGeneral.add(new NumberSetting(
"velocidad", "velocidad a la que caer en bps",
1, 0, 10, 0.1
));
public BooleanSetting jumping = sgGeneral.add(new BooleanSetting(
"saltar", "permitir saltar",
true
));
public BooleanSetting disableInWater = sgGeneral.add(new BooleanSetting(
"desactivar en agua", ".",
true
));
public ReverseStep() {
super("escalones inversos",
"escalones pero pabajo",
Category.PLAYER
);
}
@Override
public void onTick() {
if (mc.player == null || mc.world == null) return;
if (!mc.player.isOnGround()) {
if (jumping.getValue()) return;
}
if ((mc.player.isTouchingWater() || mc.player.isInLava())) {
if (disableInWater.getValue()) return;
}
double dropHeight = getHeight();
if (dropHeight > 0 && dropHeight <= height.getValue()) {
mc.player.addVelocity(0, -height.getValue() + mc.player.getVelocity().getY(), 0);
}
}
private double getHeight() {
Vec3d start = new Vec3d(mc.player.getX(), mc.player.getY() - 0.1, mc.player.getZ());
Vec3d end = new Vec3d(mc.player.getX(), mc.player.getY() - height.getValue() - 1, mc.player.getZ());
RaycastContext context = new RaycastContext(
start, end,
RaycastContext.ShapeType.COLLIDER,
RaycastContext.FluidHandling.ANY,
mc.player
);
HitResult hit = mc.world.raycast(context);
if (hit != null && hit.getType() == HitResult.Type.BLOCK) {
BlockPos hitPos = new BlockPos(
(int) hit.getPos().x,
(int) hit.getPos().y,
(int) hit.getPos().z
);
return mc.player.getY() - (hitPos.getY());
}
return -1;
}
}
@@ -0,0 +1,17 @@
package me.retucio.sputnik.module.modules.player;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
public class Step extends Module {
public NumberSetting height = sgGeneral.add(new NumberSetting(
"altura", "altura máxima a subir",
1, 0, 3, 0.1
));
public Step() {
super("escalones", "hace que el bloque de subida de escalón sea la distancia deseada", Category.PLAYER);
}
}
@@ -60,7 +60,7 @@ public class WarnLowDurability extends Module {
float percentage = (1 - (float) stack.getDamage() / stack.getMaxDamage()) * 100; float percentage = (1 - (float) stack.getDamage() / stack.getMaxDamage()) * 100;
if (percentage <= limitPercentage.getValue() && percentage < prevPercentage) { if (percentage <= limitPercentage.getValue() && percentage < prevPercentage) {
if (playSound.isEnabled()) if (playSound.getValue())
mc.world.playSound(mc.player, mc.player.getBlockPos(), mc.world.playSound(mc.player, mc.player.getBlockPos(),
sound.getValue(), sound.getValue(),
SoundCategory.AMBIENT, SoundCategory.AMBIENT,
@@ -68,7 +68,7 @@ public class WarnLowDurability extends Module {
toExponential(pitch) toExponential(pitch)
); );
if (message.isEnabled()) { if (message.getValue()) {
String customName = stack.getCustomName() == null ? "" : " \"" + stack.getCustomName().getString() + "\""; String customName = stack.getCustomName() == null ? "" : " \"" + stack.getCustomName().getString() + "\"";
Text text = Text.literal(Formatting.AQUA + stack.getItemName().getString() Text text = Text.literal(Formatting.AQUA + stack.getItemName().getString()
+ Formatting.GREEN + customName + Formatting.RESET + Formatting.GREEN + customName + Formatting.RESET
@@ -14,30 +14,96 @@ import me.retucio.sputnik.util.Lists;
import me.retucio.sputnik.util.render.RenderUtil; import me.retucio.sputnik.util.render.RenderUtil;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.concurrent.ConcurrentHashMap;
public class BlockESP extends Module { public class BlockESP extends Module {
SettingGroup sgSearch = addSg(new SettingGroup("búsqueda", true));
SettingGroup sgOulines = addSg(new SettingGroup("contorno", true)); SettingGroup sgOulines = addSg(new SettingGroup("contorno", true));
SettingGroup sgFilling = addSg(new SettingGroup("relleno", true)); SettingGroup sgFilling = addSg(new SettingGroup("relleno", true));
public ListSetting<Block> blocks = sgGeneral.add(new ListSetting<>("bloques", "bloques a resaltar",
Lists.blockList, Lists.allFalse(Lists.blockList), Lists.blockNames));
public NumberSetting radius = sgGeneral.add(new NumberSetting("radio", "radio de búsqueda de bloques",
24, 2, 128, 1));
public BooleanSetting outlines = sgOulines.add(new BooleanSetting("contorno", "renderizar contorno de bloques", true)); // bloques
public ColorSetting outlineColor = sgOulines.add(new ColorSetting("color del contorno", "color del contorno", Colors.CELESTE, false));
public NumberSetting lineWidth = sgOulines.add(new NumberSetting("grosor del contorno", "grosor de las líneas del contorno", 1, 1, 5, 0.2));
public BooleanSetting fillings = sgFilling.add(new BooleanSetting("relleno", "renderizar relleno de bloques", true)); public ListSetting<Block> blocks = sgGeneral.add(new ListSetting<>(
public ColorSetting fillingColor = sgFilling.add(new ColorSetting("color del relleno", "color del relleno", new Color(57, 177, 215, 67), false)); "bloques", "bloques a resaltar",
Lists.blockList,
Lists.allFalse(Lists.blockList),
Lists.blockNames
));
public NumberSetting maxBlocks = sgGeneral.add(new NumberSetting(
"máx. bloques", "número máximo de bloques a resaltar",
500, 1, 2000, 1
));
// búsqueda
public NumberSetting radius = sgSearch.add(new NumberSetting(
"radio", "radio de búsqueda de bloques",
24, 2, 128, 1
));
public NumberSetting searchInterval = sgSearch.add(new NumberSetting(
"intervalo", "intervalo de búsqueda en ticks",
10, 1, 40, 1
));
public BooleanSetting asyncSearch = sgSearch.add(new BooleanSetting(
"búsqueda asíncrona", "busca los bloques en un hilo separado (optimización)",
true
));
public NumberSetting distanceToMove = sgSearch.add(new NumberSetting(
"distancia a moverse", "distancia a moverse antes de actualizar los bloques",
3, 0, 10, 0.1
));
// contorno
public BooleanSetting outlines = sgOulines.add(new BooleanSetting(
"contorno", "renderizar contorno de bloques",
true
));
public ColorSetting outlineColor = sgOulines.add(new ColorSetting(
"color del contorno", "color del contorno",
Colors.CELESTE, false
));
public NumberSetting lineWidth = sgOulines.add(new NumberSetting(
"grosor del contorno", "grosor de las líneas del contorno",
1, 1, 5, 0.2
));
// relleno
public BooleanSetting fillings = sgFilling.add(new BooleanSetting(
"relleno", "renderizar relleno de bloques",
true
));
public ColorSetting fillingColor = sgFilling.add(new ColorSetting(
"color del relleno", "color del relleno",
new Color(57, 177, 215, 67), false
));
// caché
private final Map<BlockPos, VoxelShape> cachedBlocks = new ConcurrentHashMap<>();
private final Set<Block> enabledBlocks = Collections.newSetFromMap(new ConcurrentHashMap<>());
private BlockPos lastPlayerPos = null;
private int lastRadius = -1;
private int searchTimer = 0;
private boolean isSearching = false;
public BlockESP() { public BlockESP() {
@@ -45,61 +111,166 @@ public class BlockESP extends Module {
"te muestra la posición de cierto tipo de bloque renderizando una caja con su forma", "te muestra la posición de cierto tipo de bloque renderizando una caja con su forma",
Category.RENDER); Category.RENDER);
blocks.onUpdate(v ->
updateEnabledBlocks()
);
outlines.onUpdate(v -> { outlines.onUpdate(v -> {
outlineColor.setVisible(v); outlineColor.setVisible(v);
lineWidth.setVisible(v); lineWidth.setVisible(v);
}); });
fillings.onUpdate(v -> fillingColor.setVisible(v)); fillings.onUpdate(v ->
fillingColor.setVisible(v)
);
}
@Override
public void onEnable() {
cachedBlocks.clear();
enabledBlocks.clear();
updateEnabledBlocks();
searchTimer = 0;
super.onEnable();
}
@Override
public void onDisable() {
cachedBlocks.clear();
enabledBlocks.clear();
super.onDisable();
} }
@SubscribeEvent @SubscribeEvent
public void onRenderWorld(Render3DEvent event) { public void onRenderWorld(Render3DEvent event) {
if (mc.player == null || mc.world == null) return; if (mc.player == null || mc.world == null) return;
for (Block block : blocks.getOptions()) { // aplicar el intervalo
if (blocks.isEnabled(block)) { if (searchTimer++ >= searchInterval.getIntValue()) {
List<BlockPos> blocksToHighlight = getNearbyBlocks(block); searchTimer = 0;
for (BlockPos pos : blocksToHighlight) { searchBlocks();
if (outlines.isEnabled()) { }
RenderUtil.drawVoxelShapeOutline(
event.getMatrices(), Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
getVoxelShape(pos),
pos, int rendered = 0;
outlineColor.getColor(), Iterator<Map.Entry<BlockPos, VoxelShape>> iterator = cachedBlocks.entrySet().iterator();
lineWidth.getFloatValue(),
false); while (iterator.hasNext() && rendered < maxBlocks.getIntValue()) {
} Map.Entry<BlockPos, VoxelShape> entry = iterator.next();
if (fillings.isEnabled()) { BlockPos pos = entry.getKey();
RenderUtil.drawVoxelShapeFilled( VoxelShape shape = entry.getValue();
event.getMatrices(),
getVoxelShape(pos), if (!isValidBlock(pos)) {
pos, iterator.remove();
fillingColor.getColor(), continue;
false); }
// validación de distancia
double distance = Math.sqrt(pos.getSquaredDistance(cameraPos));
if (distance > radius.getIntValue()) {
iterator.remove();
continue;
}
// renderizado
if (outlines.getValue()) {
Color color = outlineColor.getValue();
RenderUtil.drawVoxelShapeOutline(
event.getMatrices(),
shape,
pos,
color,
lineWidth.getFloatValue(),
false);
}
if (fillings.getValue()) {
Color color = fillingColor.getValue();
RenderUtil.drawVoxelShapeFilled(
event.getMatrices(),
shape,
pos,
color,
false);
}
rendered++;
}
}
private void updateEnabledBlocks() {
enabledBlocks.clear();
enabledBlocks.addAll(blocks.getEnabledOptions());
}
private void searchBlocks() {
if (mc.player == null || mc.world == null || enabledBlocks.isEmpty()) return;
BlockPos playerPos = mc.player.getBlockPos();
int currentRadius = radius.getIntValue();
// si el jugador no se ha movido mucho, omitir la búsqueda
if (lastPlayerPos != null && lastRadius == currentRadius &&
playerPos.getSquaredDistance(lastPlayerPos) < (distanceToMove.getValue() * distanceToMove.getIntValue())) {
return;
}
lastPlayerPos = playerPos;
lastRadius = currentRadius;
// multithreading
if (asyncSearch.getValue()) {
if (isSearching) return;
isSearching = true;
new Thread(() -> {
try {
performBlockSearch(playerPos, currentRadius);
} finally {
isSearching = false;
}
}, "sputnik-blockESP-search").start();
} else {
performBlockSearch(playerPos, currentRadius);
}
}
// buscar los bloques
private void performBlockSearch(BlockPos center, int radius) {
Map<BlockPos, VoxelShape> newBlocks = new HashMap<>();
int radiusSq = radius * radius;
for (int x = -radius; x <= radius; x++) {
for (int y = -radius; y <= radius; y++) {
for (int z = -radius; z <= radius; z++) {
if (x*x + y*y + z*z > radiusSq) continue;
BlockPos pos = center.add(x, y, z);
Block block = mc.world.getBlockState(pos).getBlock();
if (enabledBlocks.contains(block)) {
VoxelShape shape = mc.world.getBlockState(pos).getOutlineShape(mc.world, pos);
if (!shape.isEmpty()) {
newBlocks.put(pos.toImmutable(), shape);
}
} }
} }
} }
} }
// actualizar caché
cachedBlocks.keySet().retainAll(newBlocks.keySet());
cachedBlocks.putAll(newBlocks);
} }
private List<BlockPos> getNearbyBlocks(Block block) { // verificar que el bloque sea válido
List<BlockPos> blockPosList = new ArrayList<>(); @SuppressWarnings("deprecation")
private boolean isValidBlock(BlockPos pos) {
for (int i = -radius.getIntValue(); i < radius.getIntValue(); i++) { if (mc.world == null || !mc.world.isChunkLoaded(pos)) return false;
for (int j = -radius.getIntValue(); j < radius.getIntValue(); j++) { Block block = mc.world.getBlockState(pos).getBlock();
for (int k = -radius.getIntValue(); k < radius.getIntValue(); k++) { return enabledBlocks.contains(block);
BlockPos pos = mc.player.getBlockPos().add(new Vec3i(i, j, k));
if (mc.world.getBlockState(pos).getBlock() == block) {
blockPosList.add(pos);
}
}
}
}
return blockPosList;
}
private VoxelShape getVoxelShape(BlockPos pos) {
return mc.world.getBlockState(pos).getOutlineShape(mc.world, pos);
} }
} }
@@ -3,6 +3,8 @@ package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.module.Category; import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.settings.ColorSetting; import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.Colors;
import java.awt.*; import java.awt.*;
@@ -12,8 +14,21 @@ import java.awt.*;
public class BlockOutline extends Module { public class BlockOutline extends Module {
public ColorSetting color = sgGeneral.add(new ColorSetting("color", "color del contorno de los bloques", public ColorSetting color = sgGeneral.add(new ColorSetting(
new Color(0, 0, 0, 102), true)); "color",
"color del contorno de los bloques",
Colors.mainColor,
true)
);
public NumberSetting lineWidth = sgGeneral.add(new NumberSetting(
"grosor",
"grosor de las líneas",
0.5,
0.1,
10,
0.1
));
public BlockOutline() { public BlockOutline() {
super("contorno", super("contorno",
@@ -73,8 +73,8 @@ public class BreakingProgress extends Module {
centerX + shrunkX, centerY + shrunkZ, centerZ + shrunkZ centerX + shrunkX, centerY + shrunkZ, centerZ + shrunkZ
); );
if (outlines.isEnabled()) RenderUtil.drawOutlineBox(event.getMatrices(), scaledBox, outlineColor.getColor(), lineWidth.getFloatValue(), false); if (outlines.getValue()) RenderUtil.drawOutlineBox(event.getMatrices(), scaledBox, outlineColor.getValue(), lineWidth.getFloatValue(), false);
if (fillings.isEnabled()) RenderUtil.drawFilledBox(event.getMatrices(), scaledBox, fillingColor.getColor(), false); if (fillings.getValue()) RenderUtil.drawFilledBox(event.getMatrices(), scaledBox, fillingColor.getValue(), false);
} }
public enum BreakMode { public enum BreakMode {
@@ -6,6 +6,7 @@ import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting; import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.ColorSetting; import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting; import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.Colors;
import java.awt.*; import java.awt.*;
@@ -19,7 +20,7 @@ public class CritsPlus extends Module {
SettingGroup sgAppearance = addSg(new SettingGroup("aspecto", true)); SettingGroup sgAppearance = addSg(new SettingGroup("aspecto", true));
SettingGroup sgBehaviour = addSg(new SettingGroup("funcionamiento", true)); SettingGroup sgBehaviour = addSg(new SettingGroup("funcionamiento", true));
public ColorSetting color = sgAppearance.add(new ColorSetting("color", "color de las partículas", new Color(0, 0, 255, 255), false)); public ColorSetting color = sgAppearance.add(new ColorSetting("color", "color de las partículas", Colors.mainColor, false));
public NumberSetting scale = sgAppearance.add(new NumberSetting("escala", "tamaño", 1, 0, 2, 0.05)); public NumberSetting scale = sgAppearance.add(new NumberSetting("escala", "tamaño", 1, 0, 2, 0.05));
public NumberSetting multiplier = sgAppearance.add(new NumberSetting("múltiplo", "número por el que multiplicar la cantidad de partículas generadas", 1, 0, 10, 0.1)); public NumberSetting multiplier = sgAppearance.add(new NumberSetting("múltiplo", "número por el que multiplicar la cantidad de partículas generadas", 1, 0, 10, 0.1));
@@ -5,6 +5,7 @@ import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.settings.ColorSetting; import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.util.Colors;
import net.minecraft.client.texture.NativeImage; import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture; import net.minecraft.client.texture.NativeImageBackedTexture;
@@ -16,7 +17,12 @@ import java.awt.*;
public class DamageOverlay extends Module { public class DamageOverlay extends Module {
public ColorSetting colorSetting = sgGeneral.add(new ColorSetting("color", "color", new Color(255, 0, 0, 77), false)); public ColorSetting colorSetting = sgGeneral.add(new ColorSetting(
"color",
"color",
Colors.mainColor,
false
));
private NativeImageBackedTexture texture = null; private NativeImageBackedTexture texture = null;
@@ -0,0 +1,45 @@
package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.OptionSetting;
import me.retucio.sputnik.util.Lists;
public class Fonts extends Module {
public OptionSetting<String> font = sgGeneral.add(new OptionSetting<>(
"fuente", "fuente a emplear",
Lists.fontList, "ubuntu")
);
public BooleanSetting reload = sgGeneral.add(new BooleanSetting(
"recargar", "recargar automáticamente",
false
));
public Fonts() {
super("fuentes",
"modifica el tipo de letra utilizado al renderizar texto",
Category.RENDER);
font.onUpdate(v -> reload());
}
@Override
public void onEnable() {
reload();
}
@Override
public void onDisable() {
reload();
}
private void reload() {
if (mc.getResourceManager() != null && reload.getValue()) {
mc.reloadResources();
}
}
}
@@ -17,9 +17,24 @@ import net.minecraft.util.DyeColor;
public class GlintPlus extends Module { public class GlintPlus extends Module {
public BooleanSetting items = sgGeneral.add(new BooleanSetting("items", "modificar el destello de encantamiento de los items", true)); public BooleanSetting items = sgGeneral.add(new BooleanSetting(
public BooleanSetting armor = sgGeneral.add(new BooleanSetting("armadura", "modificar el destello de encantamiento de la armadura", true)); "items",
public EnumSetting<GlintColors> glintColor = sgGeneral.add(new EnumSetting<>("colores", "color del glint", GlintColors.class, GlintColors.PURPLE)); "modificar el destello de encantamiento de los items",
true
));
public BooleanSetting armor = sgGeneral.add(new BooleanSetting(
"armadura",
"modificar el destello de encantamiento de la armadura",
true
));
public EnumSetting<GlintColors> glintColor = sgGeneral.add(new EnumSetting<>(
"colores",
"color del glint",
GlintColors.class,
GlintColors.PURPLE
));
public GlintPlus() { public GlintPlus() {
super("destello de enchants.", super("destello de enchants.",
@@ -29,19 +44,19 @@ public class GlintPlus extends Module {
public RenderLayer getGlint() { public RenderLayer getGlint() {
int color = getColor(); int color = getColor();
if (!isEnabled() || !items.isEnabled()) return RenderLayers.glint(); if (!isEnabled() || !items.getValue()) return RenderLayers.glint();
return GlintRenderLayer.glintColor.get(color); return GlintRenderLayer.glintColor.get(color);
} }
public RenderLayer getEntityGlint() { public RenderLayer getEntityGlint() {
int color = getColor(); int color = getColor();
if (!isEnabled() || !items.isEnabled()) return RenderLayers.entityGlint(); if (!isEnabled() || !items.getValue()) return RenderLayers.entityGlint();
return GlintRenderLayer.entityGlintColor.get(color); return GlintRenderLayer.entityGlintColor.get(color);
} }
public RenderLayer getArmorEntityGlint() { public RenderLayer getArmorEntityGlint() {
int color = getColor(); int color = getColor();
if (!isEnabled() || !armor.isEnabled()) return RenderLayers.armorEntityGlint(); if (!isEnabled() || !armor.getValue()) return RenderLayers.armorEntityGlint();
return GlintRenderLayer.armorEntityGlintColor.get(color); return GlintRenderLayer.armorEntityGlintColor.get(color);
} }
@@ -73,7 +73,7 @@ public class Nametags extends Module {
defaultEntities.replace(EntityType.ARROW, true); defaultEntities.replace(EntityType.ARROW, true);
defaultEntities.replace(EntityType.SPECTRAL_ARROW, true); defaultEntities.replace(EntityType.SPECTRAL_ARROW, true);
defaultEntities.replace(EntityType.TRIDENT, true); defaultEntities.replace(EntityType.TRIDENT, true);
entities.setDefaultValues(defaultEntities); entities.setDefaultValue(defaultEntities);
health.onUpdate(v -> healthMode.setVisible(v)); health.onUpdate(v -> healthMode.setVisible(v));
@@ -0,0 +1,189 @@
package me.retucio.sputnik.module.modules.render;
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.ListSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.Lists;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.registry.Registries;
import net.minecraft.text.Text;
import net.minecraft.util.math.Vec3d;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class Particles extends Module {
SettingGroup sgDispersion = addSg(new SettingGroup("dispersión", true));
SettingGroup sgOffset = addSg(new SettingGroup("desplazamiento", true));
List<SimpleParticleType> particleList = Lists.particleList.stream()
.filter(particleType -> particleType instanceof SimpleParticleType)
.map(particleType -> (SimpleParticleType) particleType)
.toList();
Map<SimpleParticleType, String> particleNames = Lists.getMapOfLists(particleList,
particleList.stream().map(particle -> Text.translatable(
Registries.PARTICLE_TYPE.getId(particle).toShortTranslationKey()).getString()
).toList());
public ListSetting<SimpleParticleType> particles = sgGeneral.add(new ListSetting<>(
"partículas",
"partículas a generar",
particleList,
Lists.allFalse(particleList),
particleNames
));
public NumberSetting spawnInterval = sgGeneral.add(new NumberSetting(
"intervalo",
"intervalo entre generaciones (en ticks)",
4, 1, 100, 1
));
public NumberSetting particleCount = sgGeneral.add(new NumberSetting(
"cantidad",
"partículas por generación",
10, 1, 100, 1
));
public NumberSetting velocity = sgDispersion.add(new NumberSetting(
"velocidad",
"multiplicador de la velocidad de dispersión",
0.2, 0, 2, 0.05
));
public NumberSetting spreadX = sgDispersion.add(new NumberSetting(
"dispersión X",
"dispersión horizontal de posición",
0.5, 0, 5, 0.1
));
public NumberSetting spreadY = sgDispersion.add(new NumberSetting(
"dispersión Y",
"dispersión vertical de posición",
0.5, 0, 5, 0.1
));
public NumberSetting spreadZ = sgDispersion.add(new NumberSetting(
"dispersión Z",
"dispersión de profundidad de posición",
0.5, 0, 5, 0.1
));
public NumberSetting velocityRandomness = sgDispersion.add(new NumberSetting(
"aleatoriedad velocidad",
"variación aleatoria en la velocidad",
0.3, 0, 1, 0.05
));
public NumberSetting positionRandomness = sgDispersion.add(new NumberSetting(
"aleatoriedad posición",
"variación aleatoria en la posición",
0.2, 0, 1, 0.05
));
public NumberSetting offsetX = sgOffset.add(new NumberSetting(
"desplazamiento pos. X",
"desplazamiento en el eje X respecto al jugador",
0, -1, 1, 0.01
));
public NumberSetting offsetY = sgOffset.add(new NumberSetting(
"desplazamiento pos. Y",
"desplazamiento en el eje Y respecto al jugador",
0, -1, 1, 0.01
));
public NumberSetting offsetZ = sgOffset.add(new NumberSetting(
"desplazamiento pos. Z",
"desplazamiento en el eje Z respecto al jugador",
-0.8, -1, 1, 0.01
));
private final Random random = new Random();
private int tickCounter = 0;
public Particles() {
super("partículas", "emite particulas artificiales", Category.RENDER);
}
@Override
public void onEnable() {
tickCounter = 0;
super.onEnable();
}
@Override
public void onTick() {
if (mc.player == null || mc.world == null) return;
tickCounter++;
if (tickCounter < spawnInterval.getIntValue()) {
return;
}
tickCounter = 0;
List<SimpleParticleType> enabledParticles = particles.getEnabledOptions();
if (enabledParticles.isEmpty()) return;
Vec3d basePos = new Vec3d(
mc.player.getX(),
mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose()),
mc.player.getZ()
);
for (int i = 0; i < particleCount.getIntValue(); i++) {
SimpleParticleType particle = enabledParticles.get(
random.nextInt(enabledParticles.size())
);
Vec3d pos = getPos(basePos);
Vec3d vel = getVel();
double yaw = Math.toRadians(mc.player.getYaw());
double offX = offsetX.getValue() * Math.cos(yaw) - offsetZ.getValue() * Math.sin(yaw);
double offZ = offsetX.getValue() * Math.sin(yaw) + offsetZ.getValue() * Math.cos(yaw);
mc.world.addParticleClient(
particle,
pos.x + offX,
pos.y + offsetY.getValue(),
pos.z + offZ,
vel.x, vel.y, vel.z
);
}
}
private Vec3d getPos(Vec3d basePos) {
double randX = (random.nextDouble() - 0.5) * 2 * positionRandomness.getValue();
double randY = (random.nextDouble() - 0.5) * 2 * positionRandomness.getValue();
double randZ = (random.nextDouble() - 0.5) * 2 * positionRandomness.getValue();
return new Vec3d(
basePos.x + (random.nextDouble() - 0.5) * spreadX.getValue() + randX,
basePos.y + (random.nextDouble() - 0.5) * spreadY.getValue() + randY,
basePos.z + (random.nextDouble() - 0.5) * spreadZ.getValue() + randZ
);
}
private Vec3d getVel() {
double randX = (random.nextDouble() - 0.5) * 2 * velocityRandomness.getValue();
double randY = (random.nextDouble() - 0.5) * 2 * velocityRandomness.getValue();
double randZ = (random.nextDouble() - 0.5) * 2 * velocityRandomness.getValue();
return new Vec3d(
(random.nextDouble() - 0.5) * velocity.getValue() + randX,
(random.nextDouble() - 0.5) * velocity.getValue() + randY,
(random.nextDouble() - 0.5) * velocity.getValue() + randZ
);
}
}
@@ -10,140 +10,350 @@ import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting; import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.render.RenderUtil; import me.retucio.sputnik.util.render.RenderUtil;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.Blocks;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.Heightmap;
import net.minecraft.world.LightType; import net.minecraft.world.LightType;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.*;
import java.util.List; import java.util.concurrent.ConcurrentHashMap;
public class LightOverlay extends Module { public class LightOverlay extends Module {
SettingGroup sgDetection = addSg(new SettingGroup("detección", true)); SettingGroup sgDetection = addSg(new SettingGroup("detección", true));
SettingGroup sgColors = addSg(new SettingGroup("colores", true)); SettingGroup sgColors = addSg(new SettingGroup("colores", true));
SettingGroup sgOptimization = addSg(new SettingGroup("optimización", true));
public NumberSetting radius = sgDetection.add(new NumberSetting("radio", "radio a tener en cuenta al renderizar superposición", // detección
public NumberSetting radius = sgDetection.add(new NumberSetting(
"radio",
"radio a tener en cuenta al renderizar superposición",
16, 5, 128, 1)); 16, 5, 128, 1));
public NumberSetting yRadius = sgDetection.add(new NumberSetting("rango vertical", "distancia vertical a tener en cuenta",
public NumberSetting yRadius = sgDetection.add(new NumberSetting(
"rango vertical",
"distancia vertical a tener en cuenta",
4, 1, 16, 1)); 4, 1, 16, 1));
public NumberSetting interval = sgDetection.add(new NumberSetting("intervalo", "cada cuántos ticks comprobar el nivel de luz", public BooleanSetting onWater = sgDetection.add(new BooleanSetting(
"en agua",
"mostrar también bloques cubiertos en agua", true));
public BooleanSetting dontCullWater = sgDetection.add(new BooleanSetting(
"evitar culling en agua",
"mostrar superposición a través de bloques para poder verla desde fuera del agua", false));
// optimización, porque iba como la mierda
public NumberSetting updateInterval = sgOptimization.add(new NumberSetting(
"intervalo de búsqueda",
"cada cuántos ticks actualizar la búsqueda de bloques",
10, 1, 80, 1)); 10, 1, 80, 1));
public BooleanSetting onWater = sgDetection.add(new BooleanSetting("en agua", "mostrar también bloques cubiertos en agua", true)); public NumberSetting movementThreshold = sgOptimization.add(new NumberSetting(
public BooleanSetting dontCullWater = sgDetection.add(new BooleanSetting("evitar culling en agua", "mostrar superposición a través de bloques para poder verla desde fuera del agua", false)); "umbral de movimiento",
"distancia que debe moverse el jugador antes de forzar una actualización",
3.0, 0.5, 10.0, 0.5));
public ColorSetting lightColor = sgColors.add(new ColorSetting("color de la luz", "color de los bloques con luz", public BooleanSetting asyncSearch = sgOptimization.add(new BooleanSetting(
"búsqueda asíncrona",
"buscar bloques en un hilo separado (reduce lag)",
true));
public BooleanSetting incrementalUpdates = sgOptimization.add(new BooleanSetting(
"actualizaciones incrementales",
"actualizar solo los bloques nuevos / eliminados en lugar de recalcular todo",
true));
// colores
public ColorSetting lightColor = sgColors.add(new ColorSetting(
"color de la luz",
"color de los bloques con luz",
new Color(0, 255, 0, 67), false)); new Color(0, 255, 0, 67), false));
public ColorSetting darknessColor = sgColors.add(new ColorSetting("color de oscuridad", "color de bloques con 0 luz",
public ColorSetting darknessColor = sgColors.add(new ColorSetting(
"color de oscuridad",
"color de bloques con 0 luz",
new Color(255, 0, 0, 67), false)); new Color(255, 0, 0, 67), false));
List<BlockPos> blocks = new ArrayList<>(); // caché y estado
private final Set<BlockPos> cachedBlocks = Collections.newSetFromMap(new ConcurrentHashMap<>());
private final Set<BlockPos> blocksToRender = Collections.newSetFromMap(new ConcurrentHashMap<>());
private BlockPos lastPlayerPos = null;
private int lastRadius = -1;
private int lastYRadius = -1;
private int updateTimer = 0;
private boolean isSearching = false;
// para actualizaciones incrementales
private int incrementalLayer = 0;
private boolean fullRescanNeeded = false;
public LightOverlay() { public LightOverlay() {
super("superposición de luz", super("superposición de luz",
"te muestra el nivel de luz en bloques, para prevenir mob spawns", "te muestra el nivel de luz en bloques, para prevenir mob spawns",
Category.WORLD); Category.WORLD);
onWater.onUpdate(v -> dontCullWater.setVisible(v));
}
@Override
public void onEnable() {
cachedBlocks.clear();
blocksToRender.clear();
lastPlayerPos = null;
lastRadius = -1;
lastYRadius = -1;
updateTimer = 0;
incrementalLayer = 0;
fullRescanNeeded = true;
super.onEnable();
}
@Override
public void onDisable() {
cachedBlocks.clear();
blocksToRender.clear();
super.onDisable();
} }
@SubscribeEvent @SubscribeEvent
@SuppressWarnings("deprecation")
public void onRenderWorld(Render3DEvent event) { public void onRenderWorld(Render3DEvent event) {
if (mc.player == null || mc.world == null) return; if (mc.player == null || mc.world == null) return;
if (mc.player.age % interval.getIntValue() == 0) {
blocks = findExposedBlocks( // actualización periódica
radius.getIntValue(), if (updateTimer++ >= updateInterval.getIntValue()) {
yRadius.getIntValue() updateTimer = 0;
); updateBlocks();
} }
for (BlockPos block : blocks) { // renderizado
if (mc.world.getBlockState(block).isAir() || !canSpawnOn(block)) continue; Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
if (!mc.world.getBlockState(block).isOpaque()) continue; int radiusValue = radius.getIntValue();
double radiusSq = radiusValue * radiusValue;
// actualizar lista de renderizado basado en distancia
blocksToRender.clear();
for (BlockPos pos : cachedBlocks) {
double distanceSq = pos.getSquaredDistance(cameraPos);
if (distanceSq <= radiusSq) {
blocksToRender.add(pos);
}
}
// renderizar bloques visibles
for (BlockPos block : blocksToRender) {
if (!mc.world.isChunkLoaded(block)) continue;
BlockState state = mc.world.getBlockState(block);
BlockState aboveState = mc.world.getBlockState(block.up());
if (!isValidSpawnSurface(block, state, aboveState)) continue;
// nivel de luz
int light = mc.world.getLightLevel(LightType.BLOCK, block.up()); int light = mc.world.getLightLevel(LightType.BLOCK, block.up());
Color color = light == 0 ? darknessColor.getColor() // color
: new Color( Color color;
(lightColor.getR() / 15) * light, if (light == 0) {
(lightColor.getG() / 15) * light, color = darknessColor.getValue();
(lightColor.getB() / 15) * light, } else {
lightColor.getA()); float ratio = light / 15.0f;
color = new Color(
(int)(lightColor.getR() * ratio),
(int)(lightColor.getG() * ratio),
(int)(lightColor.getB() * ratio),
lightColor.getA()
);
}
boolean shouldCull = !(onWater.isEnabled() && mc.world.getBlockState(block.up()).isOf(Blocks.WATER) && dontCullWater.isEnabled()); // renderizar
boolean shouldCull = !(onWater.getValue() && aboveState.isOf(Blocks.WATER) && dontCullWater.getValue());
RenderUtil.drawBlockFaceFilled(event.getMatrices(), block, Direction.UP, color, 0.001f, shouldCull); RenderUtil.drawBlockFaceFilled(event.getMatrices(), block, Direction.UP, color, 0.001f, shouldCull);
} }
} }
private List<BlockPos> findExposedBlocks(int radius, int yRadius) { private void updateBlocks() {
List<BlockPos> results = new ArrayList<>(); if (mc.player == null || mc.world == null) return;
BlockPos pos = mc.player.getBlockPos(); BlockPos playerPos = mc.player.getBlockPos();
int currentRadius = radius.getIntValue();
int currentYRadius = yRadius.getIntValue();
int minX = pos.getX() - radius; // verificar si hace falta actualizar
int maxX = pos.getX() + radius; boolean needsUpdate = fullRescanNeeded ||
int minY = Math.max(mc.world.getDimension().minY(), pos.getY() - yRadius); lastRadius != currentRadius ||
int maxY = Math.min(mc.world.getDimension().height() - 1, pos.getY() + yRadius); lastYRadius != currentYRadius ||
int minZ = pos.getZ() - radius; (lastPlayerPos != null &&
int maxZ = pos.getZ() + radius; playerPos.getSquaredDistance(lastPlayerPos) > (movementThreshold.getValue() * movementThreshold.getValue()));
maxY = Math.min(maxY, mc.world.getDimension().height() - 2); if (!needsUpdate && incrementalUpdates.getValue() && incrementalLayer >= 0) {
// actualización incremental de una sola capa
performIncrementalUpdate(playerPos, currentRadius, currentYRadius);
return;
}
if (!needsUpdate) {
return;
}
lastPlayerPos = playerPos;
lastRadius = currentRadius;
lastYRadius = currentYRadius;
fullRescanNeeded = false;
incrementalLayer = 0;
// búsqueda
if (asyncSearch.getValue()) {
if (isSearching) return;
isSearching = true;
new Thread(() -> {
try {
performFullBlockSearch(playerPos, currentRadius, currentYRadius);
} finally {
isSearching = false;
}
}, "sputnik-lightoverlay-search").start();
} else {
performFullBlockSearch(playerPos, currentRadius, currentYRadius);
}
}
@SuppressWarnings("deprecation")
private void performFullBlockSearch(BlockPos center, int radius, int yRadius) {
Set<BlockPos> newBlocks = new HashSet<>();
int radiusSq = radius * radius;
int minY = Math.max(mc.world.getBottomY(), center.getY() - yRadius);
int maxY = Math.min(mc.world.getTopY(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, mc.player.getBlockPos()) - 1, center.getY() + yRadius);
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
if (x*x + z*z > radiusSq) continue;
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
for (int y = minY; y <= maxY; y++) { for (int y = minY; y <= maxY; y++) {
BlockPos current = new BlockPos(x, y, z); BlockPos pos = center.add(x, y - center.getY(), z);
if (!mc.world.isAir(current) && canSpawnOn(current)) // nuh uh si el chunk no está cargado
results.add(current); if (!mc.world.isChunkLoaded(pos)) continue;
BlockState state = mc.world.getBlockState(pos);
BlockState aboveState = mc.world.getBlockState(pos.up());
if (isValidSpawnSurface(pos, state, aboveState)) {
newBlocks.add(pos.toImmutable());
}
} }
} }
} }
return results; // actualizar caché
cachedBlocks.clear();
cachedBlocks.addAll(newBlocks);
} }
private boolean canSpawnOn(BlockPos pos) { @SuppressWarnings("deprecation")
BlockState aboveState = mc.world.getBlockState(pos.up()); private void performIncrementalUpdate(BlockPos center, int radius, int yRadius) {
if (incrementalLayer > radius * 2) {
incrementalLayer = -radius;
}
int currentX = center.getX() - radius + incrementalLayer;
int radiusSq = radius * radius;
int minY = Math.max(mc.world.getBottomY(), center.getY() - yRadius);
int maxY = Math.min(mc.world.getTopY(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, mc.player.getBlockPos()) - 1, center.getY() + yRadius);
// buscar en una columna específica (x fijo, variar z)
for (int z = -radius; z <= radius; z++) {
int xDist = incrementalLayer;
if (xDist*xDist + z*z > radiusSq) continue;
for (int y = minY; y <= maxY; y++) {
BlockPos pos = new BlockPos(currentX, y, center.getZ() + z);
if (!mc.world.isChunkLoaded(pos)) continue;
BlockState state = mc.world.getBlockState(pos);
BlockState aboveState = mc.world.getBlockState(pos.up());
boolean isValid = isValidSpawnSurface(pos, state, aboveState);
if (isValid) {
cachedBlocks.add(pos.toImmutable());
} else {
cachedBlocks.remove(pos);
}
}
}
incrementalLayer++;
// cada 10 actualizaciones incrementales, hacer una limpieza de bloques lejanos
if (incrementalLayer % 10 == 0) {
cleanupDistantBlocks(center, radius);
}
}
private void cleanupDistantBlocks(BlockPos center, int radius) {
int radiusSq = radius * radius * 2;
Iterator<BlockPos> iterator = cachedBlocks.iterator();
while (iterator.hasNext()) {
BlockPos pos = iterator.next();
int dx = pos.getX() - center.getX();
int dz = pos.getZ() - center.getZ();
if (dx * dx + dz * dz > radiusSq) {
iterator.remove();
}
}
}
private boolean isValidSpawnSurface(BlockPos pos, BlockState state, BlockState aboveState) {
if (state.isAir() || !state.isOpaque() || !state.isFullCube(mc.world, pos)) {
return false;
}
Block aboveBlock = aboveState.getBlock(); Block aboveBlock = aboveState.getBlock();
if (aboveState.isAir()) return true; if (aboveState.isAir()) return true;
if (aboveBlock == Blocks.WATER && onWater.isEnabled()) return true; if (aboveBlock == Blocks.WATER && onWater.getValue()) return true;
if (aboveBlock instanceof PlantBlock) return true; if (aboveBlock instanceof PlantBlock) return true;
if (!aboveState.isOpaque() && !aboveState.isFullCube(mc.world, pos.up())) { if (aboveBlock instanceof SlabBlock ||
aboveBlock instanceof StairsBlock ||
if (aboveBlock instanceof SlabBlock aboveBlock instanceof ButtonBlock ||
|| aboveBlock instanceof StairsBlock aboveBlock instanceof CarpetBlock ||
|| aboveBlock instanceof ButtonBlock aboveBlock instanceof PressurePlateBlock ||
|| aboveBlock instanceof CarpetBlock aboveBlock instanceof PaneBlock ||
|| aboveBlock instanceof PressurePlateBlock aboveBlock instanceof TrapdoorBlock ||
|| aboveBlock instanceof PaneBlock aboveBlock instanceof FenceBlock ||
|| aboveBlock instanceof TrapdoorBlock aboveBlock instanceof WallBlock ||
|| aboveBlock instanceof FenceBlock aboveBlock instanceof AnvilBlock ||
|| aboveBlock instanceof WallBlock aboveBlock instanceof BedBlock) {
|| aboveBlock instanceof AnvilBlock return false;
|| aboveBlock instanceof BedBlock) {
return false;
}
if (aboveBlock == Blocks.CHEST ||
aboveBlock == Blocks.ENDER_CHEST ||
aboveBlock == Blocks.BARREL ||
aboveBlock == Blocks.TRAPPED_CHEST) {
return false;
}
return aboveBlock != Blocks.ENCHANTING_TABLE
&& aboveBlock != Blocks.GRINDSTONE
&& aboveBlock != Blocks.STONECUTTER
&& aboveBlock != Blocks.LOOM
&& aboveBlock != Blocks.COMPOSTER
&& aboveBlock != Blocks.CAKE;
} }
return true; if (aboveBlock == Blocks.CHEST ||
aboveBlock == Blocks.ENDER_CHEST ||
aboveBlock == Blocks.BARREL ||
aboveBlock == Blocks.TRAPPED_CHEST ||
aboveBlock == Blocks.ENCHANTING_TABLE ||
aboveBlock == Blocks.GRINDSTONE ||
aboveBlock == Blocks.STONECUTTER ||
aboveBlock == Blocks.LOOM ||
aboveBlock == Blocks.COMPOSTER ||
aboveBlock == Blocks.CAKE) {
return false;
}
return !aboveState.isOpaque() || !aboveState.isFullCube(mc.world, pos.up());
} }
} }
@@ -25,7 +25,7 @@ public class NoMiningInterruptions extends Module {
if (entity == null || !isEnabled() || mc.player == null) return false; if (entity == null || !isEnabled() || mc.player == null) return false;
boolean pickaxe = true; boolean pickaxe = true;
if (withPickaxeOnly.isEnabled()) if (withPickaxeOnly.getValue())
pickaxe = (mc.player.getMainHandStack().isIn(ItemTags.PICKAXES) pickaxe = (mc.player.getMainHandStack().isIn(ItemTags.PICKAXES)
|| mc.player.getOffHandStack().isIn(ItemTags.PICKAXES)); || mc.player.getOffHandStack().isIn(ItemTags.PICKAXES));
@@ -0,0 +1,167 @@
package me.retucio.sputnik.module.modules.world;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.AddEntityEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.EntityUtil;
import net.minecraft.entity.EyeOfEnderEntity;
import net.minecraft.item.Items;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Hand;
import net.minecraft.util.math.Vec3d;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
// https://benwoodworth.com/minecraft/stronghold-calculator/index.js
public class StrongholdTriangulator extends Module {
public StrongholdTriangulator() {
super("triangulador de strongholds",
"usa josecadas para calcular la posición de la stronghold más cercana",
Category.WORLD);
}
private boolean firstEyeThrown;
private boolean secondEyeThrown;
private Vec3d a;
private Vec3d b;
private float alpha;
private float beta;
// usar un ejecutor retrasado para esperar a que el ojo de ender adquiera su ángulo
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
@Override
public void onEnable() {
super.onEnable();
ChatUtil.info("para empezar, lanza un ojo de ender");
ChatUtil.info("al lanzar los ojos, quédate quieto, o puede que la posición calculada salga errónea");
}
@Override
public void onDisable() {
reset();
scheduler.shutdown();
super.onDisable();
}
@Override
public void onTick() {
if (mc.player == null || mc.world == null) return;
if (firstEyeThrown && secondEyeThrown) {
StrongholdResult result = getIntersection();
if (result != null) {
if (result.errorMessage == null) {
ChatUtil.info(Text.literal("stronghold aproximadamente en: "
+ Formatting.GREEN
+ String.format("%.2f, %.2f", result.x, result.z)
+ Formatting.RESET
));
} else {
ChatUtil.error(result.errorMessage);
}
} else {
ChatUtil.error("upsi");
}
reset();
}
}
@SubscribeEvent
public void onAddEntity(AddEntityEvent event) {
if (mc.player == null || mc.world == null) return;
if (mc.player.getStackInHand(Hand.MAIN_HAND).getItem() != Items.ENDER_EYE) return;
if (event.getEntity() instanceof EyeOfEnderEntity eye) {
Vec3d throwPos = mc.player.getEntityPos();
int entityId = eye.getId();
scheduler.schedule(() -> {
// ejecutar en el hilo principal
mc.execute(() -> {
EyeOfEnderEntity currentEye = findEyeEntity(entityId);
if (currentEye != null) {
Vec3d eyeTargetPos = eye.getEntityPos();
if (eyeTargetPos != null) {
float yaw = (float) EntityUtil.getYaw(eyeTargetPos);
if (!firstEyeThrown) {
a = throwPos;
alpha = yaw;
firstEyeThrown = true;
ChatUtil.info("primer ojo registrado: "
+ String.format("%.1f, %.1f (%.1f°)", a.x, a.z, alpha));
ChatUtil.info("ahora muévete unos 200 bloques en una dirección distinta a la del ojo para lanzar el segundo");
ChatUtil.info("cuanta más distancia te separes, más preciso será el resultado");
} else if (!secondEyeThrown) {
b = throwPos;
beta = yaw;
secondEyeThrown = true;
ChatUtil.info("segundo ojo registrado: " +
String.format("%.1f, %.1f (%.1f°)", b.x, b.z, beta));
}
} else {
ChatUtil.error("upsi dupsi");
}
}
});
}, 1000, TimeUnit.MILLISECONDS); // esperar un segundo, a que el ojo adquiera velocidad
}
}
private EyeOfEnderEntity findEyeEntity(int entityId) {
if (mc.world == null) return null;
return (EyeOfEnderEntity) mc.world.getEntityById(entityId);
}
private StrongholdResult getIntersection() {
if (a == null || b == null) return null;
// obtener coordenadas y ángulos
double x0 = a.x;
double x1 = b.x;
double z0 = a.z;
double z1 = b.z;
double yaw0 = alpha / 180 * Math.PI;
double yaw1 = beta / 180 * Math.PI;
// distancia
double d0 = ((x1 - x0) + (z1 - z0) * Math.tan(yaw1)) / (Math.cos(yaw0) * Math.tan(yaw1) - Math.sin(yaw0));
double d1 = (d0 * Math.cos(yaw0) - (z1 - z0)) / Math.cos(yaw1);
// posición de la stronghold
double x = x0 - d0 * Math.sin(yaw0);
double z = z0 + d0 * Math.cos(yaw0);
// posibles casos
if (x0 == x1 && z0 == z1) { // ambos ojos lanzados desde la misma pos.
return new StrongholdResult(null, null, "pero muévete");
} else if (Double.isNaN(d0)) {
return new StrongholdResult(null, null, "los ojos forman líneas paralelas o coincidentes");
} else if (d0 < 0 || d1 < 0) {
return new StrongholdResult(null, null, "los ojos apuntan a strongholds distintas");
} else {
return new StrongholdResult(x, z, null);
}
}
private void reset() {
firstEyeThrown = false;
secondEyeThrown = false;
a = null;
b = null;
}
public record StrongholdResult(Double x, Double z, String errorMessage) {}
}
@@ -4,20 +4,29 @@ import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.events.sputnik.UpdateSettingEvent; import me.retucio.sputnik.event.events.sputnik.UpdateSettingEvent;
import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.Module;
import java.util.function.Consumer;
// base para los tipos de ajustes // base para los tipos de ajustes
public abstract class Setting { public abstract class Setting<T> {
private final String name; protected final String name;
private final String description; protected final String description;
private boolean visible = true; protected T value;
private boolean searchMatch = true; protected T defaultValue;
private SettingGroup sg; protected Consumer<T> updateListener;
protected Setting(String name, String description) { protected boolean visible = true;
protected boolean searchMatch = true;
protected SettingGroup sg;
protected Setting(String name, String description, T defaultValue) {
this.name = name; this.name = name;
this.description = description; this.description = description;
this.value = defaultValue;
this.defaultValue = defaultValue;
} }
public boolean isVisible() { public boolean isVisible() {
@@ -44,6 +53,35 @@ public abstract class Setting {
return description; return description;
} }
public T getValue() {
return value;
}
public void setValue(T value) {
if (this.value != value) {
this.value = value;
fireUpdateEvent();
if (updateListener != null) {
updateListener.accept(value);
}
}
}
public T getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(T value) {
if (this.defaultValue != value) {
this.defaultValue = value;
}
}
public void reset() {
setValue(defaultValue);
}
public SettingGroup getSg() { public SettingGroup getSg() {
return sg; return sg;
} }
@@ -52,13 +90,17 @@ public abstract class Setting {
this.sg = sg; this.sg = sg;
} }
public Module getModule() {
return this.sg.getModule();
}
public void fireUpdateEvent() { public void fireUpdateEvent() {
Sputnik.EVENT_BUS.post( Sputnik.EVENT_BUS.post(
new UpdateSettingEvent( new UpdateSettingEvent(this, getModule().shouldSaveSettings()));
this, }
sg.getModule()
.shouldSaveSettings() public void onUpdate(Consumer<T> listener) {
) this.updateListener = listener;
); if (updateListener != null) updateListener.accept(value); // actualizar por primera vez
} }
} }
@@ -5,18 +5,17 @@ import me.retucio.sputnik.module.Module;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
public class SettingGroup implements Iterable<Setting> { public class SettingGroup implements Iterable<Setting<?>> {
private Module module; private Module module;
private final String name; private final String name;
private boolean extended; private boolean extended;
final List<Setting> settings = new ArrayList<>(1); final List<Setting<?>> settings = new ArrayList<>(1);
public SettingGroup(String name, boolean extended) { public SettingGroup(String name, boolean extended) {
this.name = name; this.name = name;
@@ -24,31 +23,35 @@ public class SettingGroup implements Iterable<Setting> {
} }
@Override @Override
public @NotNull Iterator<Setting> iterator() { public @NotNull Iterator<Setting<?>> iterator() {
return settings.iterator(); return settings.iterator();
} }
public <S extends Setting> S add(S setting) { public <S extends Setting<?>> S add(S setting) {
setting.setSg(this); setting.setSg(this);
settings.add(setting); settings.add(setting);
return setting; return setting;
} }
@SafeVarargs @SafeVarargs
public final <S extends Setting> void addAll(S... ss) { public final <S extends Setting<?>> void addAll(S... ss) {
for (S s : ss) { for (S s : ss) {
add(s); add(s);
} }
} }
public Setting getSetting(String name) { public Setting<?> getSetting(String name) {
for (Setting setting : this) for (Setting<?> setting : this)
if (setting.getName().equals(name)) if (setting.getName().equals(name))
return setting; return setting;
return null; return null;
} }
public List<Setting<?>> getSettings() {
return settings;
}
public String getName() { public String getName() {
return name; return name;
} }
@@ -2,53 +2,15 @@ package me.retucio.sputnik.module.setting.settings;
import me.retucio.sputnik.module.setting.Setting; import me.retucio.sputnik.module.setting.Setting;
import java.util.function.Consumer;
// ajuste booleano, es decir, o se encuentra encencido o apagado (similar a un interruptor) // ajuste booleano, es decir, o se encuentra encencido o apagado (similar a un interruptor)
public class BooleanSetting extends Setting { public class BooleanSetting extends Setting<Boolean> {
private boolean defaultValue;
private boolean enabled;
private Consumer<Boolean> updateListener;
public BooleanSetting(String name, String description, boolean defaultValue) { public BooleanSetting(String name, String description, boolean defaultValue) {
super(name, description); super(name, description, defaultValue);
this.enabled = defaultValue;
this.defaultValue = defaultValue;
} }
public void toggle() { public void toggle() {
setEnabled(!enabled); setValue(!value);
if (updateListener != null) updateListener.accept(enabled); if (updateListener != null) updateListener.accept(value);
} }
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
if (this.enabled != enabled) {
this.enabled = enabled;
fireUpdateEvent();
if (updateListener != null) updateListener.accept(enabled);
}
}
public boolean getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(boolean value) {
defaultValue = value;
}
public void reset() {
setEnabled(defaultValue);
}
public void onUpdate(Consumer<Boolean> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(enabled); // actualizar por primera vez
}
}
@@ -7,16 +7,11 @@ import net.minecraft.text.Text;
import java.awt.*; import java.awt.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer;
public class ColorSetting extends Setting { public class ColorSetting extends Setting<Color> {
private Color color; private final boolean defaultRainbow;
private Consumer<Color> updateListener; private final int defaultRainbowSpeed;
private Color defaultColor;
private boolean defaultRainbow;
private int defaultRainbowSpeed;
private int r, g, b, a; private int r, g, b, a;
@@ -25,14 +20,13 @@ public class ColorSetting extends Setting {
private float saturation; private float saturation;
private float brightness; private float brightness;
public ColorSetting(String name, String description, Color defaultColor, boolean rainbow) { public ColorSetting(String name, String description, Color defaultValue, boolean rainbow) {
super(name, description); super(name, description, defaultValue);
this.color = this.defaultColor = defaultColor;
this.r = defaultColor.getRed(); this.r = defaultValue.getRed();
this.g = defaultColor.getGreen(); this.g = defaultValue.getGreen();
this.b = defaultColor.getBlue(); this.b = defaultValue.getBlue();
this.a = defaultColor.getAlpha(); this.a = defaultValue.getAlpha();
this.rainbow = rainbow; this.rainbow = rainbow;
this.defaultRainbow = rainbow; this.defaultRainbow = rainbow;
@@ -43,13 +37,8 @@ public class ColorSetting extends Setting {
this.brightness = 1f; this.brightness = 1f;
} }
public Color getColor() {
if (rainbow) return Colors.rainbowColor(rainbowSpeed, a, saturation, brightness);
return color;
}
public int getR() { public int getR() {
return getColor().getRed(); return getValue().getRed();
} }
public void setR(int r) { public void setR(int r) {
@@ -57,12 +46,12 @@ public class ColorSetting extends Setting {
this.r = Math.clamp(r, 0, 255); this.r = Math.clamp(r, 0, 255);
updateColorFromRGB(); updateColorFromRGB();
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null) updateListener.accept(color); if (updateListener != null) updateListener.accept(value);
} }
} }
public int getG() { public int getG() {
return getColor().getGreen(); return getValue().getGreen();
} }
public void setG(int g) { public void setG(int g) {
@@ -70,12 +59,12 @@ public class ColorSetting extends Setting {
this.g = Math.clamp(g, 0, 255); this.g = Math.clamp(g, 0, 255);
updateColorFromRGB(); updateColorFromRGB();
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null) updateListener.accept(color); if (updateListener != null) updateListener.accept(value);
} }
} }
public int getB() { public int getB() {
return getColor().getBlue(); return getValue().getBlue();
} }
public void setB(int b) { public void setB(int b) {
@@ -83,7 +72,7 @@ public class ColorSetting extends Setting {
this.b = Math.clamp(b, 0, 255); this.b = Math.clamp(b, 0, 255);
updateColorFromRGB(); updateColorFromRGB();
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null) updateListener.accept(color); if (updateListener != null) updateListener.accept(value);
} }
} }
@@ -96,24 +85,31 @@ public class ColorSetting extends Setting {
this.a = Math.clamp(a, 0, 255); this.a = Math.clamp(a, 0, 255);
updateColorFromRGB(); updateColorFromRGB();
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null) updateListener.accept(color); if (updateListener != null) updateListener.accept(value);
} }
} }
private void updateColorFromRGB() { private void updateColorFromRGB() {
this.color = new Color(r, g, b, a); this.value = new Color(r, g, b, a);
} }
public void setColor(Color color) { @Override
if (!this.color.equals(color)) { public Color getValue() {
this.color = color; if (rainbow) return Colors.rainbowColor(rainbowSpeed, a, saturation, brightness);
this.r = color.getRed(); return super.getValue();
this.g = color.getGreen(); }
this.b = color.getBlue();
this.a = color.getAlpha(); @Override
fireUpdateEvent(); public void setValue(Color value) {
if (updateListener != null) updateListener.accept(color); if (!this.value.equals(value)) {
this.value = value;
this.r = value.getRed();
this.g = value.getGreen();
this.b = value.getBlue();
this.a = value.getAlpha();
} }
super.setValue(value);
} }
public void setRGB(int r, int g, int b) { public void setRGB(int r, int g, int b) {
@@ -143,7 +139,7 @@ public class ColorSetting extends Setting {
if (changed) { if (changed) {
updateColorFromRGB(); updateColorFromRGB();
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null) updateListener.accept(color); if (updateListener != null) updateListener.accept(value);
} }
} }
@@ -155,7 +151,7 @@ public class ColorSetting extends Setting {
if (this.rainbow != rainbow) { if (this.rainbow != rainbow) {
this.rainbow = rainbow; this.rainbow = rainbow;
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null) updateListener.accept(getColor()); if (updateListener != null) updateListener.accept(getValue());
} }
} }
@@ -167,7 +163,7 @@ public class ColorSetting extends Setting {
if (this.rainbowSpeed != rainbowSpeed) { if (this.rainbowSpeed != rainbowSpeed) {
this.rainbowSpeed = rainbowSpeed; this.rainbowSpeed = rainbowSpeed;
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null && rainbow) updateListener.accept(getColor()); if (updateListener != null && rainbow) updateListener.accept(getValue());
} }
} }
@@ -179,7 +175,7 @@ public class ColorSetting extends Setting {
if (this.saturation != saturation) { if (this.saturation != saturation) {
this.saturation = Math.clamp(saturation, 0f, 1f); this.saturation = Math.clamp(saturation, 0f, 1f);
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null && rainbow) updateListener.accept(getColor()); if (updateListener != null && rainbow) updateListener.accept(getValue());
} }
} }
@@ -191,32 +187,24 @@ public class ColorSetting extends Setting {
if (this.brightness != brightness) { if (this.brightness != brightness) {
this.brightness = Math.clamp(brightness, 0f, 1f); this.brightness = Math.clamp(brightness, 0f, 1f);
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null && rainbow) updateListener.accept(getColor()); if (updateListener != null && rainbow) updateListener.accept(getValue());
} }
} }
public Color getDefaultColor() {
return defaultColor;
}
public void setDefaultColor(Color defaultColor) {
this.defaultColor = defaultColor;
}
public int getDefaultR() { public int getDefaultR() {
return defaultColor.getRed(); return defaultValue.getRed();
} }
public int getDefaultG() { public int getDefaultG() {
return defaultColor.getGreen(); return defaultValue.getGreen();
} }
public int getDefaultB() { public int getDefaultB() {
return defaultColor.getBlue(); return defaultValue.getBlue();
} }
public int getDefaultA() { public int getDefaultA() {
return defaultColor.getAlpha(); return defaultValue.getAlpha();
} }
public float getDefaultSaturation() { public float getDefaultSaturation() {
@@ -236,31 +224,24 @@ public class ColorSetting extends Setting {
} }
public int getRGB() { public int getRGB() {
return getColor().getRGB(); return getValue().getRGB();
} }
public Text getTooltipText() { public Text getTooltipText() {
if (rainbow) return Text.literal("arcoíris"); if (rainbow) return Text.literal("arcoíris");
return Text.literal(Colors.getFormatting(color) + Colors.ARGBtoHex(a, r, g, b)); return Text.literal(Colors.getFormatting(value) + Colors.ARGBtoHex(a, r, g, b));
} }
public void reset() { public void reset() {
this.color = defaultColor; this.r = defaultValue.getRed();
this.r = defaultColor.getRed(); this.g = defaultValue.getGreen();
this.g = defaultColor.getGreen(); this.b = defaultValue.getBlue();
this.b = defaultColor.getBlue(); this.a = defaultValue.getAlpha();
this.a = defaultColor.getAlpha();
this.rainbow = false; this.rainbow = false;
this.rainbowSpeed = 2; this.rainbowSpeed = 2;
this.saturation = 1f; this.saturation = 1f;
this.brightness = 1f; this.brightness = 1f;
fireUpdateEvent(); super.reset();
if (updateListener != null) updateListener.accept(color);
}
public void onUpdate(Consumer<Color> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(getColor());
} }
public Map<String, ?> getConfigValue() { public Map<String, ?> getConfigValue() {
@@ -275,4 +256,4 @@ public class ColorSetting extends Setting {
map.put("bri", (double) brightness); map.put("bri", (double) brightness);
return map; return map;
} }
} }
@@ -7,35 +7,23 @@ import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
// ajuste que te deja elegir entre distintas opciones definidas, dentro de un Enum // ajuste que te deja elegir entre distintas opciones definidas, dentro de un Enum
public class EnumSetting<E extends Enum<E>> extends Setting { public class EnumSetting<E extends Enum<E>> extends Setting<E> {
private final List<E> values; private final List<E> values;
private E defaultValue;
private E value;
private int index; private int index;
private Consumer<E> updateListener;
public EnumSetting(String name, String description, Class<E> enumClass, E defaultValue) { public EnumSetting(String name, String description, Class<E> enumClass, E defaultValue) {
super(name, description); super(name, description, defaultValue);
this.values = Arrays.asList(enumClass.getEnumConstants()); this.values = Arrays.asList(enumClass.getEnumConstants());
this.defaultValue = defaultValue;
this.value = defaultValue;
this.index = values.indexOf(defaultValue); this.index = values.indexOf(defaultValue);
} }
public E getValue() {
return value;
}
public void setValue(E value) { public void setValue(E value) {
if (this.value != value) { if (this.value != value) {
this.value = value;
this.index = values.indexOf(value); this.index = values.indexOf(value);
fireUpdateEvent();
if (updateListener != null) updateListener.accept(value);
} }
super.setValue(value);
} }
public List<E> getValues() { public List<E> getValues() {
@@ -69,21 +57,4 @@ public class EnumSetting<E extends Enum<E>> extends Setting {
else else
setIndex(values.size() - 1); setIndex(values.size() - 1);
} }
public void setDefaultValue(E value) {
defaultValue = value;
}
public E getDefaultValue() {
return defaultValue;
}
public void reset() {
setValue(defaultValue);
}
public void onUpdate(Consumer<E> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(value);
}
} }
@@ -8,66 +8,40 @@ import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.KeyUtil; import me.retucio.sputnik.util.KeyUtil;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
public class KeySetting extends Setting { public class KeySetting extends Setting<Integer> {
private int key;
private int defaultKey;
private Consumer<Integer> updateListener;
public KeySetting(String name, String description, int defaultKey) { public KeySetting(String name, String description, int defaultKey) {
super(name, description); super(name, description, defaultKey);
this.key = defaultKey; this.value = defaultKey;
this.defaultKey = defaultKey; this.defaultValue = defaultKey;
} }
public int getKey() { @Override
return key; public void setValue(Integer value) {
} if (this.value.equals(value)) return;
public void setKey(int key) { if (value == GLFW.GLFW_KEY_ESCAPE) {
if (this.key == key) return; this.value = GLFW.GLFW_KEY_UNKNOWN; // asignar la tecla ESC a deshabilitar la tecla
if (key == GLFW.GLFW_KEY_ESCAPE) {
this.key = GLFW.GLFW_KEY_UNKNOWN; // asignar la tecla ESC a deshabilitar la tecla
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null) updateListener.accept(key); if (updateListener != null) updateListener.accept(value);
return; return;
} }
if (ModuleManager.INSTANCE != null) { if (ModuleManager.INSTANCE != null) {
for (Module module : ModuleManager.INSTANCE.getModules()) for (Module module : ModuleManager.INSTANCE.getModules())
if (module.getKey() == key && !ClientSettingsFrame.guiSettings.multipleKeybinds.isEnabled() && key != -1) { if (module.getKey() == value && !ClientSettingsFrame.guiSettings.multipleKeybinds.getValue() && value != -1) {
module.setKey(-1); module.setKey(-1);
ChatUtil.info("tecla del módulo " + module.getName() + " restablecida"); ChatUtil.info("tecla del módulo " + module.getName() + " restablecida");
} }
} }
this.key = key;
fireUpdateEvent(); super.setValue(value);
if (updateListener != null) updateListener.accept(key);
}
public int getDefaultKey() {
return defaultKey;
}
public void setDefaultKey(int key) {
this.defaultKey = key;
} }
public String getKeyName() { public String getKeyName() {
return KeyUtil.getKeyName(key); return KeyUtil.getKeyName(value);
}
public void reset() {
setKey(defaultKey);
}
public void onUpdate(Consumer<Integer> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(key);
} }
} }
@@ -2,31 +2,24 @@ package me.retucio.sputnik.module.setting.settings;
import me.retucio.sputnik.module.setting.Setting; import me.retucio.sputnik.module.setting.Setting;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
public class ListSetting<T> extends Setting { public class ListSetting<T> extends Setting<Map<T, Boolean>> {
private List<T> options; private final List<T> options;
private Map<T, Boolean> values;
private Map<T, Boolean> defaultValues;
private Map<T, String> displayNames = null; private Map<T, String> displayNames = null;
private Consumer<Map<T, Boolean>> updateListener;
public ListSetting(String name, String description, List<T> options, Map<T, Boolean> initialValues) { public ListSetting(String name, String description, List<T> options, Map<T, Boolean> initialValues) {
super(name, description); super(name, description, initialValues);
this.options = new ArrayList<>(options); this.options = new ArrayList<>(options);
this.defaultValues = new HashMap<>(); this.defaultValue = new HashMap<>();
for (T option : options) { for (T option : options) {
boolean enabled = initialValues != null && initialValues.getOrDefault(option, false); boolean enabled = initialValues != null && initialValues.getOrDefault(option, false);
defaultValues.put(option, enabled); defaultValue.put(option, enabled);
} }
this.values = new HashMap<>(defaultValues);
this.value = new HashMap<>(defaultValue);
} }
public ListSetting(String name, String description, List<T> options, Map<T, Boolean> initialValues, Map<T, String> displayNames) { public ListSetting(String name, String description, List<T> options, Map<T, Boolean> initialValues, Map<T, String> displayNames) {
@@ -35,14 +28,14 @@ public class ListSetting<T> extends Setting {
} }
public boolean isEnabled(T option) { public boolean isEnabled(T option) {
return values.getOrDefault(option, false); return value.getOrDefault(option, false);
} }
public void setEnabled(T option, boolean enabled) { public void setEnabled(T option, boolean enabled) {
if (values.containsKey(option) && values.get(option) != enabled) { if (value.containsKey(option) && value.get(option) != enabled) {
values.put(option, enabled); value.put(option, enabled);
fireUpdateEvent(); fireUpdateEvent();
if (updateListener != null) updateListener.accept(new HashMap<>(values)); if (updateListener != null) updateListener.accept(new HashMap<>(value));
} }
} }
@@ -51,66 +44,69 @@ public class ListSetting<T> extends Setting {
} }
public Map<T, Boolean> getValues() { public Map<T, Boolean> getValues() {
return new HashMap<>(values); return new HashMap<>(value);
} }
public void setValues(Map<T, Boolean> values) { @Override
this.values = new HashMap<>(values); public void setValue(Map<T, Boolean> values) {
if (!this.value.equals(values)) {
super.setValue(values);
}
} }
public Map<T, Boolean> getDefaultValues() { public void setDefaultValue(Map<T, Boolean> values) {
return new HashMap<>(defaultValues); defaultValue.clear();
} defaultValue.putAll(values);
public void setDefaultValues(Map<T, Boolean> values) {
defaultValues = values;
} }
public Map<String, Boolean> getConfigValues() { public Map<String, Boolean> getConfigValues() {
Map<String, Boolean> configValues = new HashMap<>(); Map<String, Boolean> configValues = new HashMap<>();
for (int i = 0; i < values.size(); i++) for (T option : options) {
configValues.put(getDisplayName(options.get(i)), values.get(options.get(i))); configValues.put(getDisplayName(option), value.getOrDefault(option, false));
}
return configValues; return configValues;
} }
public void addOption(T option, boolean value, String displayName) { public void addOption(T option, boolean isDefault, String displayName) {
if (!(this.options instanceof ArrayList)) options.add(option);
this.options = new ArrayList<>(this.options); defaultValue.put(option, isDefault);
value.put(option, isDefault);
this.options.add(option); if (this.displayNames != null) {
this.values.put(option, value);
this.defaultValues.put(option, value);
if (this.displayNames != null)
this.displayNames.put(option, displayName); this.displayNames.put(option, displayName);
} }
public void reset() {
values.clear();
values.putAll(defaultValues);
fireUpdateEvent();
if (updateListener != null) updateListener.accept(new HashMap<>(values));
} }
public void setAll(boolean enabled) { public void setAll(boolean enabled) {
for (T option : options) values.put(option, enabled); for (T option : options) {
} value.put(option, enabled);
}
public void onUpdate(Consumer<Map<T, Boolean>> listener) { fireUpdateEvent();
this.updateListener = listener; if (updateListener != null) updateListener.accept(new HashMap<>(value));
if (updateListener != null) updateListener.accept(new HashMap<>(values));
} }
public List<T> getOptions() { public List<T> getOptions() {
return options; return Collections.unmodifiableList(options);
}
public List<T> getEnabledOptions() {
List<T> enabledOptions = new ArrayList<>();
for (T option : options) {
if (isEnabled(option)) {
enabledOptions.add(option);
}
}
return enabledOptions;
} }
public Map<T, String> getDisplayNames() { public Map<T, String> getDisplayNames() {
return displayNames; return displayNames != null ? new HashMap<>(displayNames) : null;
} }
public String getDisplayName(T key) { public String getDisplayName(T key) {
if (displayNames != null) return displayNames.get(key); if (displayNames != null && displayNames.containsKey(key)) {
return key.toString(); return displayNames.get(key);
}
return key != null ? key.toString() : "?";
} }
} }
@@ -5,20 +5,16 @@ import me.retucio.sputnik.module.setting.Setting;
import java.util.function.Consumer; import java.util.function.Consumer;
// ajuste numérico, es decir, que eliges un valor númerico entre el mínimo y el máximo disponibles // ajuste numérico, es decir, que eliges un valor númerico entre el mínimo y el máximo disponibles
public class NumberSetting extends Setting { public class NumberSetting extends Setting<Double> {
private double value;
private double defaultValue;
private boolean locked;
private final double min; private final double min;
private final double max; private final double max;
private final double increment; // el "increment" es el salto que hay entre valores disponibles private final double increment; // el "increment" es el salto que hay entre valores disponibles
private Consumer<Double> updateListener; private boolean locked;
public NumberSetting(String name, String description, double defaultValue, double min, double max, double increment) { public NumberSetting(String name, String description, double defaultValue, double min, double max, double increment) {
super(name, description); super(name, description, defaultValue);
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
this.value = defaultValue; this.value = defaultValue;
this.min = min; this.min = min;
@@ -41,40 +37,31 @@ public class NumberSetting extends Setting {
} }
public double getValue() {
return value;
}
public float getFloatValue() { public float getFloatValue() {
return (float) value; // en "float" por conveniencia return value.floatValue(); // en "float" por conveniencia
} }
public int getIntValue() { public int getIntValue() {
return (int) value; // en "int" (número entero) por conveniencia return value.intValue(); // en "int" (número entero) por conveniencia
} }
public long getLongValue() { public long getLongValue() {
return (long) value; // lo mismo para "longs" return value.longValue(); // lo mismo para "longs"
}
public long getShortValue() {
return value.shortValue();
}
public long getByteValue() {
return value.byteValue();
} }
public void setValue(double value) { public void setValue(double value) {
if (this.value == value || this.locked) return; if (this.value == value || this.locked) return;
double clamped = clamp(value, min, max); double clamped = clamp(value, min, max);
this.value = Math.round(clamped / increment) * increment; value = Math.round(clamped / increment) * increment;
fireUpdateEvent(); super.setValue(value);
if (updateListener != null) updateListener.accept(this.value);
}
public double getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(double value) {
defaultValue = value;
}
public void reset() {
setValue(defaultValue);
} }
public double getMin() { public double getMin() {
@@ -96,9 +83,4 @@ public class NumberSetting extends Setting {
public void setLocked(boolean locked) { public void setLocked(boolean locked) {
this.locked = locked; this.locked = locked;
} }
public void onUpdate(Consumer<Double> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(value);
}
} }
@@ -6,38 +6,24 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
public class OptionSetting<T> extends Setting { public class OptionSetting<T> extends Setting<T> {
private final List<T> options; private final List<T> options;
private Map<T, String> displayNames; private Map<T, String> displayNames;
private T option;
private final T defaultOption;
private Consumer<T> updateListener;
public OptionSetting(String name, String description, List<T> options, T defaultOption) { public OptionSetting(String name, String description, List<T> options, T defaultOption) {
super(name, description); super(name, description, defaultOption);
this.options = options; this.options = options;
this.option = defaultOption;
this.defaultOption = defaultOption;
} }
public OptionSetting(String name, String description, List<T> options, T defaultOption, Map<T, String> displayNames) { public OptionSetting(String name, String description, List<T> options, T defaultOption, Map<T, String> displayNames) {
super(name, description); super(name, description, defaultOption);
this.options = options; this.options = options;
this.option = defaultOption;
this.defaultOption = defaultOption;
this.displayNames = displayNames; this.displayNames = displayNames;
} }
public T getValue() {
return option;
}
public void setValue(T option) { public void setValue(T option) {
if (options.contains(option)) this.option = option; if (options.contains(option)) super.setValue(option);
fireUpdateEvent();
if (updateListener != null) updateListener.accept(option);
} }
public void setValueByName(String name) { public void setValueByName(String name) {
@@ -62,10 +48,6 @@ public class OptionSetting<T> extends Setting {
return options.get(index); return options.get(index);
} }
public T getDefaultValue() {
return defaultOption;
}
public int getSize() { public int getSize() {
return options.size(); return options.size();
} }
@@ -73,7 +55,7 @@ public class OptionSetting<T> extends Setting {
public int getIndex() { public int getIndex() {
int index = 0; int index = 0;
for (T option : options) { for (T option : options) {
if (this.option == option) break; if (this.value == option) break;
index += 1; index += 1;
} }
return index; return index;
@@ -96,15 +78,6 @@ public class OptionSetting<T> extends Setting {
return index; return index;
} }
public void reset() {
setValue(defaultOption);
}
public void onUpdate(Consumer<T> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(option);
}
public Map<T, String> getDisplayNames() { public Map<T, String> getDisplayNames() {
return displayNames; return displayNames;
} }
@@ -115,6 +88,6 @@ public class OptionSetting<T> extends Setting {
} }
public String getDisplayName() { public String getDisplayName() {
return getDisplayName(option); return getDisplayName(value);
} }
} }
@@ -4,50 +4,24 @@ import me.retucio.sputnik.module.setting.Setting;
import java.util.function.Consumer; import java.util.function.Consumer;
public class StringSetting extends Setting { public class StringSetting extends Setting<String> {
private String value;
private String defaultValue;
private final int maxLength; private final int maxLength;
private Consumer<String> updateListener;
public StringSetting(String name, String description, String defaultValue, int maxLength) { public StringSetting(String name, String description, String defaultValue, int maxLength) {
super(name, description); super(name, description, defaultValue);
this.value = defaultValue; this.value = defaultValue;
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
this.maxLength = maxLength; this.maxLength = maxLength;
} }
public String getValue() {
return value;
}
public void setValue(String value) { public void setValue(String value) {
if (this.value.equals(value)) return; if (this.value.equals(value)) return;
this.value = value.length() > maxLength ? value.substring(0, maxLength) : value; value = value.length() > maxLength ? value.substring(0, maxLength) : value;
fireUpdateEvent(); super.setValue(value);
if (updateListener != null) updateListener.accept(this.value);
}
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
public void reset() {
setValue(defaultValue);
} }
public int getMaxLength() { public int getMaxLength() {
return maxLength; return maxLength;
} }
public void onUpdate(Consumer<String> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(value);
}
} }
@@ -1,13 +1,17 @@
package me.retucio.sputnik.ui.hud; package me.retucio.sputnik.ui.hud;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.config.ConfigManager; import me.retucio.sputnik.config.ConfigManager;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.KeyEvent;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.client.HUD;
import me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame; import me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame;
import me.retucio.sputnik.util.Colors; import me.retucio.sputnik.util.Colors;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Click; import net.minecraft.client.gui.Click;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.input.KeyInput;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
@@ -19,15 +23,17 @@ public class HudEditorScreen extends Screen {
public static HudEditorScreen INSTANCE; public static HudEditorScreen INSTANCE;
private final MinecraftClient mc = MinecraftClient.getInstance(); private final MinecraftClient mc = MinecraftClient.getInstance();
private final HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
private final List<HudElement> elements = new ArrayList<>(); private final List<HudElement> elements = new ArrayList<>();
@Nullable private HudElement selected = null; @Nullable private HudElement selected = null;
private boolean dragging = false; private boolean dragging = false;
private int dragOffsetX, dragOffsetY; private int dragX, dragY;
public HudEditorScreen() { public HudEditorScreen() {
super(Text.literal("editor del HUD")); super(Text.literal("editor del HUD"));
Sputnik.EVENT_BUS.subscribe(this);
} }
public void setElements(List<HudElement> elements) { public void setElements(List<HudElement> elements) {
@@ -40,15 +46,30 @@ public class HudEditorScreen extends Screen {
ctx.fill(0, 0, this.width, this.height, Colors.hudEditorScreenBackgroundColor.getRGB()); ctx.fill(0, 0, this.width, this.height, Colors.hudEditorScreenBackgroundColor.getRGB());
// instrucciones // instrucciones
ctx.drawCenteredTextWithShadow(mc.textRenderer, "editor del HUD", ctx.drawCenteredTextWithShadow(mc.textRenderer, title,
this.width / 2, this.height / 2 - mc.textRenderer.fontHeight, -1); this.width / 2, this.height / 2 - mc.textRenderer.fontHeight, -1);
ctx.drawCenteredTextWithShadow(mc.textRenderer, ctx.drawCenteredTextWithShadow(mc.textRenderer,
Text.literal("arrastrar para mover · clic derecho para visibilidad · ESC para guardar y salir · shift + clic derecho para restablecer"), Text.literal("arrastrar para mover · clic derecho para visibilidad · ESC para guardar y salir · shift + clic derecho para restablecer"),
this.width / 2, this.height / 2 + mc.textRenderer.fontHeight, Colors.instructionsTextColor.getRGB()); this.width / 2, this.height / 2 + mc.textRenderer.fontHeight, Colors.instructionsTextColor.getRGB());
// movimiento axial
if (hud.axialMovement.getValue()) {
int centerX = mc.getWindow().getScaledWidth() / 2;
if (dragging && selected != null && Math.abs(centerX - mouseX) < hud.axisOffset.getValue()) {
dragX = mouseX - centerX + selected.getW() / 2;
ctx.drawVerticalLine(centerX, 0, mc.getWindow().getScaledHeight(), Colors.CELESTE.getRGB());
}
int centerY = mc.getWindow().getScaledHeight() / 2;
if (dragging && selected != null && Math.abs(centerY - mouseY) < hud.axisOffset.getValue()) {
dragY = mouseY - centerY + selected.getH() / 2;
ctx.drawHorizontalLine(0, mc.getWindow().getScaledWidth(), centerY, Colors.CELESTE.getRGB());
}
}
// elementos // elementos
for (HudElement element : elements) for (HudElement element : elements)
element.renderInEditor(ctx, null); element.renderInEditor(ctx, hud);
// tooltips // tooltips
if (!dragging) { if (!dragging) {
@@ -72,17 +93,16 @@ public class HudEditorScreen extends Screen {
int mouseX = (int) click.x(); int mouseX = (int) click.x();
int mouseY = (int) click.y(); int mouseY = (int) click.y();
for (int i = elements.size() - 1; i >= 0; i--) { for (HudElement element : elements) {
HudElement element = elements.get(i);
if (element.isHovered(mouseX, mouseY)) { if (element.isHovered(mouseX, mouseY)) {
selected = element; selected = element;
if (click.button() == 0) { if (click.button() == 0) {
dragging = true; dragging = true;
dragOffsetX = mouseX - element.getX(); dragX = mouseX - element.getX();
dragOffsetY = mouseY - element.getY(); dragY = mouseY - element.getY();
elements.remove(i); elements.remove(element);
elements.add(element); elements.add(element);
return true; return true;
@@ -109,8 +129,8 @@ public class HudEditorScreen extends Screen {
int mouseX = (int) click.x(); int mouseX = (int) click.x();
int mouseY = (int) click.y(); int mouseY = (int) click.y();
int newX = mouseX - dragOffsetX; int newX = mouseX - dragX;
int newY = mouseY - dragOffsetY; int newY = mouseY - dragY;
newX = Math.max(1, Math.min(newX, width - selected.getW() - 1)); newX = Math.max(1, Math.min(newX, width - selected.getW() - 1));
newY = Math.max(1, Math.min(newY, height - selected.getH() - 1)); newY = Math.max(1, Math.min(newY, height - selected.getH() - 1));
@@ -132,15 +152,36 @@ public class HudEditorScreen extends Screen {
return super.mouseReleased(click); return super.mouseReleased(click);
} }
@Override @SubscribeEvent
public boolean keyPressed(KeyInput input) { // he sustituído el método del súper por un evento para ver si así se podían
if (input.key() == GLFW.GLFW_KEY_ESCAPE) { // registrar dos teclas a la vez, pero resulta que no :P
public void onKey(KeyEvent event) {
if (!(mc.currentScreen == INSTANCE)) return;
if (event.getAction() == GLFW.GLFW_RELEASE) return;
event.cancel();
// guardar y salir
if (event.getKey() == GLFW.GLFW_KEY_ESCAPE) {
saveAllElementsToConfig(); saveAllElementsToConfig();
selected = null; selected = null;
mc.setScreen(null); mc.setScreen(null);
return true;
} }
return super.keyPressed(input); // movimiento de los elementos con las teclas de las flechas
else if (hud.arrowMovement.getValue() && selected != null) {
int offset = hud.arrowOffset.getIntValue();
if (event.getKey() == GLFW.GLFW_KEY_UP) {
selected.setY(Math.max(1, selected.getY() - offset));
}
if (event.getKey() == GLFW.GLFW_KEY_DOWN) {
selected.setY(Math.min(mc.getWindow().getScaledHeight() - selected.getH() + 1, selected.getY() + offset));
}
if (event.getKey() == GLFW.GLFW_KEY_LEFT) {
selected.setX(Math.max(1, selected.getX() - offset));
}
if (event.getKey() == GLFW.GLFW_KEY_RIGHT) {
selected.setX(Math.min(mc.getWindow().getScaledWidth() - selected.getW() + 1, selected.getX() + offset));
}
}
} }
private void saveElementToConfig(HudElement element) { private void saveElementToConfig(HudElement element) {
@@ -157,7 +198,7 @@ public class HudEditorScreen extends Screen {
@Override @Override
protected void applyBlur(DrawContext ctx) { protected void applyBlur(DrawContext ctx) {
if (ClientSettingsFrame.guiSettings.blur.isEnabled()) { if (ClientSettingsFrame.guiSettings.blur.getValue()) {
super.applyBlur(ctx); super.applyBlur(ctx);
} }
} }
@@ -25,11 +25,6 @@ public abstract class HudElement extends Widget {
public abstract void renderInEditor(DrawContext ctx, HUD hud); public abstract void renderInEditor(DrawContext ctx, HUD hud);
public abstract List<Text> getTooltip(); public abstract List<Text> getTooltip();
public boolean isHovered(int mouseX, int mouseY) {
return mouseX >= x && mouseX <= x + w
&& mouseY >= y && mouseY <= y + w;
}
public String getId() { return id; } public String getId() { return id; }
public boolean isVisible() { return visible; } public boolean isVisible() { return visible; }
@@ -36,6 +36,7 @@ public class HudRenderer {
addElement(new CustomTextElement(), positions, visibilities); addElement(new CustomTextElement(), positions, visibilities);
addElement(new TimeElement(), positions, visibilities); addElement(new TimeElement(), positions, visibilities);
addElement(new PingElement(), positions, visibilities); addElement(new PingElement(), positions, visibilities);
addElement(new RotationElement(), positions, visibilities);
addElement(new DynoElement(), positions, visibilities); addElement(new DynoElement(), positions, visibilities);
addElement(new EchestElement(), positions, visibilities); addElement(new EchestElement(), positions, visibilities);
@@ -74,7 +75,7 @@ public class HudRenderer {
public static Color getColor(HUD hud) { public static Color getColor(HUD hud) {
return hud.color.getColor(); return hud.color.getValue();
} }
public static void drawSnappedText(DrawContext ctx, String text, int x, int y, int color, boolean shadow) { public static void drawSnappedText(DrawContext ctx, String text, int x, int y, int color, boolean shadow) {
@@ -92,31 +93,26 @@ public class HudRenderer {
} }
public static void render(DrawContext ctx, RenderTickCounter tickCounter) { public static void render(DrawContext ctx, RenderTickCounter tickCounter) {
if (shouldSkipRendering()) return;
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class); HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
if (!hud.isEnabled()) return;
if (mc.debugHudEntryList.isF3Enabled() && !hud.showOnF3.isEnabled()) return;
if (mc.currentScreen instanceof ChatScreen && !hud.showOnChat.isEnabled()) return;
init();
if (mc.currentScreen instanceof HudEditorScreen) return;
float delta = tickCounter.getDynamicDeltaTicks();
for (HudElement element : elements) { for (HudElement element : elements) {
if (element.isVisible()) { if (element.isVisible() && !shouldSkipRendering()) {
element.renderInGame(ctx, delta, hud); element.renderInGame(ctx, tickCounter.getDynamicDeltaTicks(), hud);
} }
} }
} }
private static boolean shouldSkipRendering() { private static boolean shouldSkipRendering() {
HUD hud = ModuleManager.INSTANCE.getModuleByClass(HUD.class);
return ModuleManager.INSTANCE == null return ModuleManager.INSTANCE == null
|| mc.player == null || mc.player == null
|| mc.getCameraEntity() == null || mc.getCameraEntity() == null
|| mc.currentScreen instanceof TitleScreen || mc.currentScreen instanceof TitleScreen
|| mc.options.hudHidden; || mc.options.hudHidden
|| !hud.isEnabled()
|| (mc.debugHudEntryList.isF3Enabled() && !hud.showOnF3.getValue())
|| (mc.currentScreen instanceof ChatScreen && !hud.showOnChat.getValue())
|| mc.currentScreen instanceof HudEditorScreen;
} }
public static List<HudElement> getElements() { public static List<HudElement> getElements() {
@@ -17,8 +17,8 @@ public abstract class TextHudElement extends HudElement {
@Override @Override
public void renderInGame(DrawContext ctx, float delta, HUD hud) { public void renderInGame(DrawContext ctx, float delta, HUD hud) {
String text = getText(delta, hud); String text = getText(delta, hud);
int color = hud != null ? hud.color.getColor().getRGB() : -1; int color = hud != null ? hud.color.getValue().getRGB() : -1;
boolean shadow = hud != null && hud.shadow.isEnabled(); boolean shadow = hud != null && hud.shadow.getValue();
HudRenderer.drawSnappedText(ctx, text, x, y, color, shadow); HudRenderer.drawSnappedText(ctx, text, x, y, color, shadow);
} }
@@ -30,8 +30,8 @@ public abstract class TextHudElement extends HudElement {
drawEditorBackground(ctx); drawEditorBackground(ctx);
int color = hud != null ? hud.color.getColor().getRGB() : -1; int color = hud != null ? hud.color.getValue().getRGB() : -1;
boolean shadow = hud != null && hud.shadow.isEnabled(); boolean shadow = hud != null && hud.shadow.getValue();
HudRenderer.drawSnappedText(ctx, previewText, x, y, color, shadow); HudRenderer.drawSnappedText(ctx, previewText, x, y, color, shadow);
} }
@@ -20,7 +20,9 @@ public class CoordsElement extends TextHudElement {
Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class); Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
Vec3d pos = freecam != null && freecam.isEnabled() Vec3d pos = freecam != null && freecam.isEnabled()
? new Vec3d(freecam.getX(delta), freecam.getY(delta), freecam.getZ(delta)) ? new Vec3d(freecam.getX(delta), freecam.getY(delta), freecam.getZ(delta))
: mc.player.getEntityPos(); : mc.player == null
? new Vec3d(67, 67, 67)
: mc.player.getEntityPos();
String overworldCoords = (int) pos.x + " " + (int) pos.y + " " + (int) pos.z; String overworldCoords = (int) pos.x + " " + (int) pos.y + " " + (int) pos.z;
String netherCoords = (int) pos.x / 8 + " " + (int) pos.y / 8 + " " + (int) pos.z / 8; String netherCoords = (int) pos.x / 8 + " " + (int) pos.y / 8 + " " + (int) pos.z / 8;
@@ -20,7 +20,7 @@ public class FpsElement extends TextHudElement {
@Override @Override
public String getPreviewText() { public String getPreviewText() {
return "FPS: 67"; return "FPS: " + mc.getCurrentFps();
} }
@Override @Override
@@ -0,0 +1,43 @@
package me.retucio.sputnik.ui.hud.elements;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.client.HUD;
import me.retucio.sputnik.ui.hud.TextHudElement;
import net.minecraft.text.Text;
import java.util.List;
public class RotationElement extends TextHudElement {
public RotationElement() {
super("rotation", mc.getWindow().getScaledWidth() - mc.textRenderer.getWidth("180º 180º (N)"), mc.getWindow().getScaledHeight() - mc.textRenderer.fontHeight);
}
@Override
public String getText(float delta, HUD hud) {
if (mc.player == null) return getPreviewText();
return String.format("%.2f", mc.player.getYaw() % 360) + "º " + String.format("%.2f", mc.player.getPitch()) + "º (" + getDirection() + ")";
}
@Override
public String getPreviewText() {
if (mc.player == null)
return "69º 69º (W)";
return getText(mc.getRenderTickCounter().getDynamicDeltaTicks(), ModuleManager.INSTANCE.getModuleByClass(HUD.class));
}
@Override
public List<Text> getTooltip() {
return List.of();
}
private String getDirection() {
return switch (mc.player.getHorizontalFacing()) {
case NORTH -> "N";
case SOUTH -> "S";
case EAST -> "E";
case WEST -> "O";
default -> "?";
};
}
}
@@ -20,7 +20,7 @@ public class TimeElement extends TextHudElement {
@Override @Override
public String getPreviewText() { public String getPreviewText() {
return "04:20 PM"; return MiscUtil.getCurrentFormattedTime();
} }
@Override @Override
@@ -33,10 +33,35 @@ public class TotemsElement extends ImageHudElement {
if (stack.getItem() == Items.TOTEM_OF_UNDYING) if (stack.getItem() == Items.TOTEM_OF_UNDYING)
count++; count++;
} }
} else {
count = 69;
} }
ItemStack stack = new ItemStack(Items.TOTEM_OF_UNDYING, Math.max(1, count)); drawItem(ctx, new ItemStack(Items.TOTEM_OF_UNDYING, Math.max(1, count)), count);
}
@Override
public void renderInEditor(DrawContext ctx, HUD hud) {
int count = 0;
if (mc.player != null) {
for (ItemStack stack : mc.player.getInventory()) {
if (stack.getItem() == Items.TOTEM_OF_UNDYING)
count++;
}
} else {
count = 69;
}
drawEditorBackground(ctx);
drawItem(ctx, new ItemStack(Items.TOTEM_OF_UNDYING, Math.max(1, count)), count);
}
@Override
public List<Text> getTooltip() {
return List.of(Text.of("totems disponibles"));
}
private void drawItem(DrawContext ctx, ItemStack stack, int count) {
ctx.drawItem(stack, x, y); ctx.drawItem(stack, x, y);
if (count > 1) { if (count > 1) {
ctx.drawStackOverlay(mc.textRenderer, stack, x, y); ctx.drawStackOverlay(mc.textRenderer, stack, x, y);
@@ -54,24 +79,4 @@ public class TotemsElement extends ImageHudElement {
); );
} }
} }
@Override
public void renderInEditor(DrawContext ctx, HUD hud) {
int count = 0;
if (mc.player != null) {
for (ItemStack stack : mc.player.getInventory()) {
if (stack.getItem() == Items.TOTEM_OF_UNDYING)
count++;
}
}
drawEditorBackground(ctx);
ctx.drawItem(new ItemStack(Items.TOTEM_OF_UNDYING, count), x, y);
}
@Override
public List<Text> getTooltip() {
return List.of(Text.of("totems disponibles"));
}
} }
@@ -6,6 +6,7 @@ import me.retucio.sputnik.event.events.KeyEvent;
import me.retucio.sputnik.event.events.MouseClickEvent; import me.retucio.sputnik.event.events.MouseClickEvent;
import me.retucio.sputnik.event.events.MouseScrollEvent; import me.retucio.sputnik.event.events.MouseScrollEvent;
import me.retucio.sputnik.event.events.sputnik.SettingsFrameEvent; import me.retucio.sputnik.event.events.sputnik.SettingsFrameEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.Setting; import me.retucio.sputnik.module.setting.Setting;
import me.retucio.sputnik.module.setting.settings.ColorSetting; import me.retucio.sputnik.module.setting.settings.ColorSetting;
@@ -30,11 +31,13 @@ import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional;
import static me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame.guiSettings; import static me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame.guiSettings;
@@ -45,14 +48,16 @@ public class ClickGUI extends Screen {
public static ClickGUI INSTANCE; public static ClickGUI INSTANCE;
private boolean anyFocused; private boolean anyFocused;
private Widget selected = null; private @Nullable Widget selected = null;
private Category categoryFilter = Category.ALL;
private final ModuleFrame modulesFrame = new ModuleFrame(20, 30, 100, 20); private final ModuleFrame modulesFrame = new ModuleFrame(20, 30, 100, 20);
private final List<SettingsFrame> settingsFrames = new ArrayList<>(); private final List<SettingsFrame> settingsFrames = new ArrayList<>();
private final ClientSettingsFrame guiSettingsFrame = new ClientSettingsFrame(200, 30, 100, 20); private final ClientSettingsFrame guiSettingsFrame = new ClientSettingsFrame(200, 30, 100, 20);
private final ScrollBarWidget scrollBar = new ScrollBarWidget(); private final ScrollBarWidget scrollBar = new ScrollBarWidget();
private final SearchBarWidget searchBar = new SearchBarWidget(340, 16, 300, 20); private final SearchBarWidget searchBar = new SearchBarWidget(340, 16, 320, 20);
private final List<Widget> miscWidgets = Arrays.asList(scrollBar, searchBar); private final List<Widget> miscWidgets = Arrays.asList(scrollBar, searchBar);
public ClickGUI() { public ClickGUI() {
@@ -124,12 +129,13 @@ public class ClickGUI extends Screen {
return bottom + 20; // padding return bottom + 20; // padding
} }
@Override
public boolean mouseClicked(Click click, boolean doubled) { public boolean mouseClicked(Click click, boolean doubled) {
miscWidgets.forEach(w -> w.mouseClicked( miscWidgets.forEach(w -> w.mouseClicked(
(int) click.x(), (int) click.x(),
(int) click.y(), (int) click.y(),
click.button())); click.button()
));
// detectar clics sobre los marcos // detectar clics sobre los marcos
modulesFrame.mouseClicked((int) click.x(), (int) click.y(), click.button()); modulesFrame.mouseClicked((int) click.x(), (int) click.y(), click.button());
@@ -194,16 +200,21 @@ public class ClickGUI extends Screen {
} }
public void filterSearchResults() { public void filterSearchResults() {
if (!guiSettings.searchBar.isEnabled()) return; if (!guiSettings.searchBar.getValue()) return;
String searchInput = searchBar.getSearchInput().trim(); String searchInput = searchBar.getSearchInput().trim();
if (!guiSettings.matchCase.isEnabled()) searchInput = searchInput.toLowerCase(); if (!guiSettings.matchCase.getValue()) searchInput = searchInput.toLowerCase();
for (Button b : modulesFrame.getButtons()) { for (Button b : modulesFrame.getButtons()) {
if (!(b instanceof ModuleButton mb)) return; if (!(b instanceof ModuleButton mb)) return;
Module module = mb.getModule(); Module module = mb.getModule();
if (searchInput.isEmpty()) { if (getCategoryFilter() != Category.ALL) {
module.setSearchMatch(getCategoryFilter() == module.getCategory());
} else {
module.setSearchMatch(true); module.setSearchMatch(true);
}
if (searchInput.isEmpty()) {
continue; continue;
} }
@@ -211,7 +222,7 @@ public class ClickGUI extends Screen {
String description = MiscUtil.removeAccentMarks(module.getDescription()); String description = MiscUtil.removeAccentMarks(module.getDescription());
String category = MiscUtil.removeAccentMarks(module.getCategory().toString()); String category = MiscUtil.removeAccentMarks(module.getCategory().toString());
if (!guiSettings.matchCase.isEnabled()) { if (!guiSettings.matchCase.getValue()) {
name = name.toLowerCase(); name = name.toLowerCase();
description = description.toLowerCase(); description = description.toLowerCase();
category = category.toLowerCase(); category = category.toLowerCase();
@@ -226,7 +237,7 @@ public class ClickGUI extends Screen {
for (SettingsFrame sf : settingsFrames) { for (SettingsFrame sf : settingsFrames) {
for (Button b : sf.getButtons()) { for (Button b : sf.getButtons()) {
if (!(b instanceof SettingButton<?> sb)) return; if (!(b instanceof SettingButton<?> sb)) return;
Setting setting = sb.getSetting(); Setting<?> setting = sb.getSetting();
if (searchInput.isEmpty()) { if (searchInput.isEmpty()) {
setting.setSearchMatch(true); setting.setSearchMatch(true);
@@ -237,7 +248,7 @@ public class ClickGUI extends Screen {
String description = MiscUtil.removeAccentMarks(setting.getDescription()); String description = MiscUtil.removeAccentMarks(setting.getDescription());
String sgName = MiscUtil.removeAccentMarks(setting.getSg().getName()); String sgName = MiscUtil.removeAccentMarks(setting.getSg().getName());
if (!guiSettings.matchCase.isEnabled()) { if (!guiSettings.matchCase.getValue()) {
name = name.toLowerCase(); name = name.toLowerCase();
description = description.toLowerCase(); description = description.toLowerCase();
sgName = sgName.toLowerCase(); sgName = sgName.toLowerCase();
@@ -248,15 +259,21 @@ public class ClickGUI extends Screen {
} }
} }
public SettingsFrame getSfOfModule(Module module) {
Optional<SettingsFrame> frame = settingsFrames.stream()
.filter(sf -> sf.getModule().equals(module))
.findFirst();
return frame.orElseGet(() ->
new SettingsFrame(module, 0, 0, 100, 20)
);
}
// abrir un marco donde se encuentran los ajustes del módulo deseado // abrir un marco donde se encuentran los ajustes del módulo deseado
public void openSettingsFrame(Module module, int x, int y) { public void openSettingsFrame(Module module, int x, int y) {
for (SettingsFrame frame : settingsFrames) { // asegurarse de que no se sale de la pantalla
if (frame.getModule() == module) { x = Math.clamp(x, 0, mc.getWindow().getScaledWidth() - 80);
frame.setX(x); y = Math.clamp(y, 0, mc.getWindow().getScaledHeight() - 120);
frame.setY(y);
return;
}
}
SettingsFrame frame = new SettingsFrame(module, x, y, 100, 20); SettingsFrame frame = new SettingsFrame(module, x, y, 100, 20);
settingsFrames.add(frame); settingsFrames.add(frame);
@@ -289,8 +306,8 @@ public class ClickGUI extends Screen {
// verificar si un módulo tiene su marco de ajustes abierto // verificar si un módulo tiene su marco de ajustes abierto
public boolean isSettingsFrameOpen(Module module) { public boolean isSettingsFrameOpen(Module module) {
return settingsFrames.stream() return settingsFrames.stream().anyMatch(
.anyMatch(sf -> sf.getModule().getName().equals(module.getName())); sf -> sf.getModule().equals(module));
} }
public boolean isColorPickerFrameOpen(ColorSetting setting) { public boolean isColorPickerFrameOpen(ColorSetting setting) {
@@ -326,6 +343,13 @@ public class ClickGUI extends Screen {
lb.refreshDummy(); lb.refreshDummy();
} }
public void setCategoryFilter(Category category) {
this.categoryFilter = category;
}
public Category getCategoryFilter() {
return categoryFilter;
}
// métodos del súper // métodos del súper
@@ -353,7 +377,7 @@ public class ClickGUI extends Screen {
@Override @Override
protected void applyBlur(DrawContext ctx) { protected void applyBlur(DrawContext ctx) {
if (guiSettings.blur.isEnabled()) super.applyBlur(ctx); if (guiSettings.blur.getValue()) super.applyBlur(ctx);
} }
@@ -120,7 +120,7 @@ public class PreviewScreen extends Screen {
@Override @Override
public void applyBlur(DrawContext ctx) { public void applyBlur(DrawContext ctx) {
if (ClientSettingsFrame.guiSettings.blur.isEnabled()) super.applyBlur(ctx); if (ClientSettingsFrame.guiSettings.blur.getValue()) super.applyBlur(ctx);
} }
@Override @Override
@@ -23,4 +23,8 @@ public abstract class Button extends Widget {
public void setOffset(int offset) { public void setOffset(int offset) {
this.offset = offset; this.offset = offset;
} }
public Frame<?> getParent() {
return parent;
}
} }
@@ -43,7 +43,7 @@ public class ModuleButton extends Button {
@Override @Override
public void mouseClicked(int mouseX, int mouseY, int button) { public void mouseClicked(int mouseX, int mouseY, int button) {
if (isHovered((int) mouseX, (int) mouseY) && ClickGUI.INSTANCE.trySelect(this)) { if (isHovered(mouseX, mouseY) && ClickGUI.INSTANCE.trySelect(this)) {
if (button == 0) { // clic izquierdo para activar / desactivar el módulo if (button == 0) { // clic izquierdo para activar / desactivar el módulo
module.toggle(); module.toggle();
} else if (button == 1) { // clic derecho para el marco de ajustes (también lo cierra si está abierto) } else if (button == 1) { // clic derecho para el marco de ajustes (también lo cierra si está abierto)
@@ -56,12 +56,6 @@ public class ModuleButton extends Button {
} }
} }
@Override
public void mouseDragged(int mouseX, int mouseY) {}
@Override
public void onKey(int key, int action) {}
// verifica si el puntero del ratón se encuentra sobre el botón del módulo // verifica si el puntero del ratón se encuentra sobre el botón del módulo
@Override @Override
public boolean isHovered(int mouseX, int mouseY) { public boolean isHovered(int mouseX, int mouseY) {
Loaded 100 of 141 files, more files were not shown because too many files have changed in this diff. Show more