Compare commits

...
4 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
retuci0 f794457538 v2.5 2026-01-06 18:09:52 +01:00
165 changed files with 3846 additions and 1505 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
# 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
+12 -22
View File
@@ -11,21 +11,21 @@ base {
}
repositories {
// Add repositories to retrieve artifacts from in here.
// You should only use this when depending on other mods because
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
// for more information about repositories.
maven {
name = "FDD Maven"
url = "https://maven.firstdark.dev/releases"
}
}
dependencies {
// To change the versions see the gradle.properties file
// mc
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
// otros
include(modImplementation "dev.firstdark.discordrpc:discord-rpc:1.0.3")
}
loom {
@@ -45,11 +45,6 @@ tasks.withType(JavaCompile).configureEach {
}
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
targetCompatibility = JavaVersion.VERSION_21
}
@@ -58,11 +53,12 @@ jar {
inputs.property "archivesName", project.base.archivesName
from("LICENSE") {
rename { "${it}_${inputs.properties.archivesName}"}
rename {
"${it}_${inputs.properties.archivesName}"
}
}
}
// configure the maven publication
publishing {
publications {
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 {
// 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.
}
repositories {}
}
+12 -6
View File
@@ -1,18 +1,24 @@
# v2.4
# v2.8
## novedades
ahora se usa el formato binario (.dat) en vez de .json para guardar ajustes, lo que los hace más rápidos, y el archivo más liviano
### adiciones
#### módulos nuevos:
- capas: cambia (solo visualmente, para ti) la capa que usas a una custom de las disponibles
### arreglos / mejoras
- renombrado bien todo que lo hice con prisa
- 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
+1 -1
View File
@@ -8,6 +8,6 @@ loom_version=1.13-SNAPSHOT
fabric_api_version=0.140.2+1.21.11
mod_version=2.4
mod_version=2.8
maven_group=me.retucio
archives_base_name=sputnik
+13 -2
View File
@@ -19,6 +19,7 @@ import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
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.hud.HudEditorScreen;
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.util.*;
import me.retucio.sputnik.util.KeyUtil;
import me.retucio.sputnik.util.render.DrawUtil;
import me.retucio.sputnik.util.render.RenderUtil;
import me.retucio.sputnik.util.render.Textures;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.loader.api.FabricLoader;
@@ -69,6 +72,11 @@ public class Sputnik implements ClientModInitializer {
private Screen prevScreen;
public static boolean settingsApplied = false;
static {
// puta vida
System.setProperty("java.awt.headless", "false");
}
@Override
public void onInitializeClient() {
mc = MinecraftClient.getInstance();
@@ -86,6 +94,8 @@ public class Sputnik implements ClientModInitializer {
Lists.init();
Textures.registerAll();
CapeManager.INSTANCE = new CapeManager();
EVENT_BUS.post(new LoadCapeManagerEvent());
@@ -99,6 +109,8 @@ public class Sputnik implements ClientModInitializer {
HudEditorScreen.INSTANCE = new HudEditorScreen();
EVENT_BUS.post(new LoadClickGUIEvent());
mc.execute(HudRenderer::init);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
EVENT_BUS.post(new ShutdownEvent());
}));
@@ -120,7 +132,6 @@ public class Sputnik implements ClientModInitializer {
// se ejecuta cada vez que se presiona una tecla
public void onKey(int key, int action) {
if (key == GLFW.GLFW_KEY_F3) return; // prevenir activación de módulos al usar combinaciones de F3
ModuleManager.INSTANCE.getEnabledModules().forEach(module -> module.onKey(key, action));
boolean anyFocused = isAnySettingButtonFocused() || ClickGUI.INSTANCE.getSearchBar().isFocused();
ClickGUI.INSTANCE.setAnyFocused(anyFocused);
@@ -190,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()
private void handleHudEditorKey(int key, boolean anyFocused) {
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 (!hud.isEnabled()) {
@@ -32,6 +32,7 @@ public class CommandManager {
public static void registerCommands() {
addCommand(new BindCommand());
addCommand(new ConfigCommand());
addCommand(new CopyScreenshotCommand());
addCommand(new EnderChestCommand());
addCommand(new GarbageCleanerCommand());
@@ -9,6 +9,7 @@ import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.util.MiscUtil;
import net.minecraft.command.CommandSource;
import net.minecraft.text.Text;
@@ -19,6 +20,7 @@ import java.util.concurrent.CompletableFuture;
public class ModuleArgumentType implements ArgumentType<Module> {
public static final ModuleArgumentType INSTANCE = new ModuleArgumentType();
private static final DynamicCommandExceptionType UNKNOWN_MODULE = new DynamicCommandExceptionType(
name -> Text.literal("módulo \"" + name + "\" no encontrado"));
@@ -35,7 +37,8 @@ public class ModuleArgumentType implements ArgumentType<Module> {
@Override
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
@@ -4,7 +4,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.command.args.ModuleArgumentType;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.KeySetting;
import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.KeyUtil;
import net.minecraft.command.CommandSource;
@@ -42,7 +42,7 @@ public class BindCommand extends Command {
public static boolean onKeyPress(int key) {
if (listeningModule == null) return false;
KeySetting bind = listeningModule.getBind();
if (bind != null) bind.setKey(key);
if (bind != null) bind.setValue(key);
ChatUtil.info(
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);
}
}
@@ -2,7 +2,7 @@ package me.retucio.sputnik.config;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.sputnik.*;
import me.retucio.sputnik.module.settings.*;
import me.retucio.sputnik.module.setting.settings.*;
import me.retucio.sputnik.ui.screen.ClickGUI;
import java.io.Serial;
@@ -57,9 +57,9 @@ public class ClientConfig {
// guardar ajustes con su respectivo tipo de valor, en formato "nombreMódulo:nombreAjuste"
Object value = null;
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 KeySetting k: value = k.getKey(); break;
case KeySetting k: value = k.getValue(); break;
case NumberSetting n: value = n.getValue(); break;
case StringSetting s: value = s.getValue(); break;
case ListSetting l: value = l.getConfigValues(); break;
@@ -78,13 +78,13 @@ public class ClientConfig {
@SubscribeEvent
public void onCloseSettingsFrame(SettingsFrameEvent.Close event) {
settingsFrames.remove(event.getFrame().module.getName());
settingsFrames.remove(event.getFrame().getModule().getName());
ConfigManager.save();
}
@SubscribeEvent
public void onMoveSettingsFrame(SettingsFrameEvent.Move event) {
settingsFrames.replace(event.getFrame().module.getName(), new int[]{event.getFrame().getX(), event.getFrame().getY()});
settingsFrames.replace(event.getFrame().getModule().getName(), new int[]{event.getFrame().getX(), event.getFrame().getY()});
ConfigManager.save();
}
@@ -5,20 +5,20 @@ import com.google.gson.GsonBuilder;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.settings.*;
import me.retucio.sputnik.module.setting.*;
import me.retucio.sputnik.module.setting.settings.*;
import me.retucio.sputnik.ui.widgets.Frame;
import me.retucio.sputnik.ui.widgets.frames.ModuleFrame;
import me.retucio.sputnik.ui.screen.ClickGUI;
import me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame;
import me.retucio.sputnik.ui.widgets.frames.SettingsFrame;
import me.retucio.sputnik.util.ChatUtil;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
// se ocupa de guardar, cargar y aplicar ajustes
public class ConfigManager {
@@ -107,7 +107,7 @@ public class ConfigManager {
save();
}
public static void setSetting(Setting setting, Object value) {
public static void setSetting(Setting<?> setting, Object value) {
ensureConfig();
config.settings.put(getSettingKey(setting), value);
save();
@@ -115,10 +115,10 @@ public class ConfigManager {
public static void setFramePosition(SettingsFrame frame) {
ensureConfig();
if (!config.settingsFrames.containsKey(frame.module.getName()))
config.settingsFrames.put(frame.module.getName(), new int[] {frame.getX(), frame.getY()});
if (!config.settingsFrames.containsKey(frame.getModule().getName()))
config.settingsFrames.put(frame.getModule().getName(), new int[] {frame.getX(), frame.getY()});
else
config.settingsFrames.replace(frame.module.getName(), new int[] {frame.getX(), frame.getY()});
config.settingsFrames.replace(frame.getModule().getName(), new int[] {frame.getX(), frame.getY()});
save();
}
@@ -140,17 +140,6 @@ public class ConfigManager {
save();
}
public static void setHudImagePath(String id, String imagePath) {
ensureConfig();
config.hudImagePaths.put(id, imagePath);
save();
}
public static String getHudImagePath(String id) {
ensureConfig();
return config.hudImagePaths.getOrDefault(id, "");
}
public static void setSearchBarPosition(int x, int y) {
ensureConfig();
config.searchBarPosition = new int[] {x, y};
@@ -161,7 +150,7 @@ public class ConfigManager {
// ------------------ APLICAR AJUSTES ------------------
@SuppressWarnings({"rawtypes", "unchecked"})
public static void applySetting(Module parent, Setting setting) {
public static void applySetting(Module parent, Setting<?> setting) {
String key = getSettingKey(setting);
if (!config.settings.containsKey(key)) return;
@@ -200,8 +189,15 @@ public class ConfigManager {
private static void applySettingsFrames() {
config.settingsFrames.forEach((moduleName, position) -> {
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]);
});
Sputnik.LOGGER.info("estados de marcos de ajustes aplicados");
}
@@ -248,11 +244,12 @@ public class ConfigManager {
}
}
// ajustes de módulos
private static void applyBooleanSetting(BooleanSetting setting, Object value) {
if (value instanceof Boolean) {
setting.setEnabled((Boolean) value);
setting.setValue((Boolean) value);
}
}
@@ -278,9 +275,9 @@ public class ConfigManager {
private static void applyKeySetting(KeySetting setting, Object value) {
if (value instanceof Double) {
setting.setKey(((Double) value).intValue());
setting.setValue(((Double) value).intValue());
} else if (value instanceof Integer) {
setting.setKey((Integer) value);
setting.setValue((Integer) value);
}
}
@@ -294,7 +291,7 @@ public class ConfigManager {
convertedValues.put(option, booleanValue instanceof Boolean && (Boolean) booleanValue);
}
setting.setValues(convertedValues);
setting.setValue(convertedValues);
}
}
@@ -306,8 +303,14 @@ public class ConfigManager {
Number b = (Number) map.get("b");
Number a = (Number) map.get("a");
if (r != null && g != null && b != null && a != null)
setting.setRGB(r.intValue(), g.intValue(), b.intValue(), a.intValue());
if (r != null && g != null && b != null && a != null) {
setting.setRGB(
r.intValue(),
g.intValue(),
b.intValue(),
a.intValue()
);
}
applyOptionalProperty(map, "rb", Boolean.class, setting::setRainbow);
applyOptionalProperty(map, "rs", Number.class, val -> setting.setRainbowSpeed(val.intValue()));
@@ -321,7 +324,7 @@ public class ConfigManager {
}
}
private static <T> void applyOptionalProperty(Map<?, ?> map, String key, Class<T> type, java.util.function.Consumer<T> setter) {
private static <T> void applyOptionalProperty(Map<?, ?> map, String key, Class<T> type, Consumer<T> setter) {
Object value = map.get(key);
if (type.isInstance(value)) {
setter.accept(type.cast(value));
@@ -339,8 +342,8 @@ public class ConfigManager {
if (config == null) config = new ClientConfig();
}
private static String getSettingKey(Setting setting) {
return setting.getModule().getName() + ":" + setting.getName();
private static String getSettingKey(Setting<?> setting) {
return setting.getSg().getModule().getName() + ":" + setting.getName();
}
public static boolean hasLoaded() {
@@ -0,0 +1,24 @@
package me.retucio.sputnik.event.events;
import me.retucio.sputnik.event.Event;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderTickCounter;
public class Render2DEvent extends Event {
private final DrawContext ctx;
private final RenderTickCounter tc;
public Render2DEvent(DrawContext ctx, RenderTickCounter tc) {
this.ctx = ctx;
this.tc = tc;
}
public DrawContext getCtx() {
return ctx;
}
public RenderTickCounter getTc() {
return tc;
}
}
@@ -9,13 +9,13 @@ import net.minecraft.client.util.math.MatrixStack;
/**
* @see me.retucio.sputnik.mixin.WorldRendererMixin#render
*/
public class RenderWorldEvent extends Event {
public class Render3DEvent extends Event {
private final MatrixStack matrices;
private final RenderTickCounter tc;
private final Camera camera;
public RenderWorldEvent(MatrixStack matrices, RenderTickCounter tc, Camera camera) {
public Render3DEvent(MatrixStack matrices, RenderTickCounter tc, Camera camera) {
this.matrices = matrices;
this.tc = tc;
this.camera = camera;
@@ -1,20 +1,20 @@
package me.retucio.sputnik.event.events.sputnik;
import me.retucio.sputnik.event.Event;
import me.retucio.sputnik.module.settings.Setting;
import me.retucio.sputnik.module.setting.Setting;
// se genera cada que se cambia el valor de un ajuste
public class UpdateSettingEvent extends Event {
private final Setting setting;
private final Setting<?> setting;
private boolean shouldSave;
public UpdateSettingEvent(Setting setting, boolean shouldSave) {
public UpdateSettingEvent(Setting<?> setting, boolean shouldSave) {
this.setting = setting;
this.shouldSave = shouldSave;
}
public Setting getSetting() {
public Setting<?> getSetting() {
return setting;
}
@@ -15,7 +15,8 @@ import java.util.Iterator;
import static me.retucio.sputnik.Sputnik.EVENT_BUS;
@Mixin(BossBarHud.class)
@Mixin(value = BossBarHud.class)
public abstract class BossBarHudMixin {
@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();
}
@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) {
RenderBossbarEvent.BossSpacing event = EVENT_BUS.post(new RenderBossbarEvent.BossSpacing(constant));
return event.getSpacing();
@@ -59,7 +59,7 @@ public abstract class CameraMixin {
@Inject(method = "clipToSpace", at = @At("HEAD"), cancellable = true)
private void onClipToSpace(float distance, CallbackInfoReturnable<Float> cir) {
if (perspectivePlus.isEnabled() && perspectivePlus.clip.isEnabled())
if (perspectivePlus.isEnabled() && perspectivePlus.clip.getValue())
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"))
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"))
private void onInit(CallbackInfo info) {
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"))
private void noRenderTotemPop(GameRenderer instance, ItemStack floatingItem) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (!noRender.isEnabled() || noRender.totemPop.isEnabled())
if (!noRender.isEnabled() || noRender.totemPop.getValue())
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.module.ModuleManager;
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.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
@@ -16,7 +17,7 @@ import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
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.Shadow;
import org.spongepowered.asm.mixin.Unique;
@@ -31,8 +32,8 @@ import static me.retucio.sputnik.Sputnik.mc;
@Mixin(ClientPlayerInteractionManager.class)
public abstract class ClientPlayerInteractionManagerMixin {
@Shadow @Final
private MinecraftClient client;
@Shadow
private int blockBreakingCooldown;
@Unique
Freecam freecam;
@@ -69,4 +70,13 @@ public abstract class ClientPlayerInteractionManagerMixin {
AttackEntityEvent event = EVENT_BUS.post(new AttackEntityEvent(target));
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.gravityStrength *= crits.gravity.getFloatValue();
original.setMaxAge(crits.maxAge.getIntValue());
original.collidesWithWorld = crits.collide.isEnabled();
original.collidesWithWorld = crits.collide.getValue();
return original;
}
@@ -88,7 +88,7 @@ public abstract class EntityMixin {
@ModifyReturnValue(method = "getName", at = @At("RETURN"))
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
String damage = nametags.getArrowDamage(arrow);
@@ -101,7 +101,7 @@ public abstract class EntityMixin {
@SuppressWarnings("ConstantConditions")
@ModifyReturnValue(method = "getCustomName", at = @At("RETURN"))
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 (original != null) return original.copy().append(" (de " + nametags.getOwnerName(entity.getOwnerReference()) + ")");
else return Text.of(nametags.getOwnerName(entity.getOwnerReference()));
@@ -113,7 +113,7 @@ public abstract class EntityMixin {
@SuppressWarnings("ConstantConditions")
@ModifyReturnValue(method = "getName", at = @At("RETURN"))
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)");
return original;
}
@@ -33,10 +33,10 @@ public abstract class FogRendererMixin {
if (!noRender.isEnabled()) return instance.shouldApply(cameraSubmersionType, entity);
String className = instance.getClass().getSimpleName();
if ((className.equals("BlindnessEffectFogModifier") && !noRender.blindnessEffect.isEnabled())
|| (className.equals("DarknessEffectFogModifier") && !noRender.darknessEffect.isEnabled())
if ((className.equals("BlindnessEffectFogModifier") && !noRender.blindnessEffect.getValue())
|| (className.equals("DarknessEffectFogModifier") && !noRender.darknessEffect.getValue())
|| ((className.equals("LavaFogModifier") || className.equals("WaterFogModifier")
|| className.equals("PowederSnowFogModifier")) && !noRender.fluidOverlay.isEnabled()))
|| className.equals("PowederSnowFogModifier")) && !noRender.fluidOverlay.getValue()))
return false;
return instance.shouldApply(cameraSubmersionType, entity);
@@ -44,7 +44,7 @@ public abstract class FogRendererMixin {
@ModifyReturnValue(method = "getFogColor", at = @At("RETURN"))
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.WATER))
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"))
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)
private void renderHand(float tickProgress, boolean sleeping, Matrix4f positionMatrix, CallbackInfo ci) {
if ((zoom.isEnabled() && !zoom.showHands.isEnabled())
|| (freecam.isEnabled() && !freecam.renderHands.isEnabled()))
if ((zoom.isEnabled() && !zoom.showHands.getValue())
|| (freecam.isEnabled() && !freecam.renderHands.getValue()))
ci.cancel();
}
@ModifyVariable(method = "renderWorld", ordinal = 6, at = @At(value = "STORE"))
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"))
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)
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)
private float modifyEquipProgressMainhand(float value) {
if (mc.player == null) return value;
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;
}
@@ -1,6 +1,8 @@
package me.retucio.sputnik.mixin;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.events.Render2DEvent;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.misc.ChatPlus;
import me.retucio.sputnik.module.modules.camera.Freecam;
@@ -28,37 +30,42 @@ public abstract class InGameHudMixin {
noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
}
@Inject(method = "render", at = @At("TAIL"))
private void onRenderHud(DrawContext ctx, RenderTickCounter tc, CallbackInfo ci) {
Sputnik.EVENT_BUS.post(new Render2DEvent(ctx, tc));
}
// norender
@Inject(method = "renderScoreboardSidebar*", at = @At("HEAD"), cancellable = true)
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)
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)
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)
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)
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)
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();
}
@@ -77,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)
private void onClear(CallbackInfo ci) {
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)
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)
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 (nametags.countItems.isEnabled()) {
if (nametags.countItems.getValue()) {
if (count > 1) return name.copy().append(" x" + count);
return name;
}
@@ -23,7 +23,7 @@ public abstract class ItemMixin {
@Inject(method = "appendTooltip", at = @At("HEAD"))
private void onAppendTooltip(ItemStack stack, Item.TooltipContext context, TooltipDisplayComponent displayComponent, Consumer<Text> textConsumer, TooltipType type, CallbackInfo ci) {
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 (ShulkerPeek.isShulkerEmpty(stack)) {
@@ -16,7 +16,7 @@ public abstract class KeyInputMixin extends Input {
@Inject(method = "tick", at = @At("TAIL"))
private void isPressed(CallbackInfo ci) {
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(
false, false,
false, false,
@@ -55,6 +55,6 @@ public abstract class LightmapTextureManagerMixin {
@Inject(method = "getDarkness", at = @At("HEAD"), cancellable = true)
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.modules.player.ElytraBounce;
import me.retucio.sputnik.module.modules.player.Step;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.LivingEntity;
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.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import static me.retucio.sputnik.Sputnik.mc;
@@ -26,7 +28,7 @@ public abstract class LivingEntityMixin {
@SuppressWarnings("ConstantConditions")
@Inject(method = "tickMovement", at = @At("TAIL"))
public void recastIfLanded(CallbackInfo ci) {
private void recastIfLanded(CallbackInfo ci) {
ElytraBounce bounce = ModuleManager.INSTANCE.getModuleByClass(ElytraBounce.class);
if (!((Object) this instanceof ClientPlayerEntity)
@@ -47,4 +49,11 @@ public abstract class LivingEntityMixin {
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"))
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"))
private boolean renderInvisPlayerNametags(boolean original) {
if (nametags.isEnabled() && nametags.alwaysVisible.isEnabled()) return false;
if (nametags.isEnabled() && nametags.alwaysVisible.getValue()) return false;
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)
private void renderSelfNametag(T livingEntity, double d, CallbackInfoReturnable<Boolean> cir) {
if (livingEntity instanceof PlayerEntity player) {
if (player == mc.player && nametags.showSelf.isEnabled()) {
if (player == mc.player && nametags.showSelf.getValue()) {
cir.setReturnValue(true);
cir.cancel();
}
@@ -14,10 +14,9 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
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.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -28,6 +27,12 @@ public abstract class MinecraftClientMixin {
@Shadow
private int itemUseCooldown;
@Shadow
public int attackCooldown;
// eventos
@Inject(method = "tick", at = @At("HEAD"))
private void onTickPre(CallbackInfo ci) {
Sputnik.INSTANCE.onTick();
@@ -50,9 +55,10 @@ public abstract class MinecraftClientMixin {
if (event.isCancelled()) ci.cancel();
}
@Inject(method = "isTelemetryEnabledByApi", at = @At("RETURN"), cancellable = true)
private void disableMicropenisTelemetryShi(CallbackInfoReturnable<Boolean> cir) {
cir.setReturnValue(false);
@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();
}
@Inject(method = "doItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getStackInHand(Lnet/minecraft/util/Hand;)Lnet/minecraft/item/ItemStack;"), cancellable = true)
@@ -62,16 +68,21 @@ public abstract class MinecraftClientMixin {
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"))
private void modifyItemUseCooldown(CallbackInfo ci, @Local ItemStack stack) {
FastUse fastUse = ModuleManager.INSTANCE.getModuleByClass(FastUse.class);
if (!fastUse.isEnabled()) return;
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"))
private Text addHealthIndicator(Text original) {
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 absorption = getAbsorptionAmount();
@@ -26,13 +26,13 @@ public abstract class SkyRendererMixin {
@Inject(method = "renderSun", at = @At("HEAD"), cancellable = true)
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)
private void onRenderMoon(MoonPhase moonPhase, float alpha, MatrixStack matrices, CallbackInfo ci) {
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"))
@@ -45,12 +45,12 @@ public abstract class SkyRendererMixin {
@Inject(method = "renderStars", at = @At("HEAD"), cancellable = true)
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)
private void onEndFlash(MatrixStack matrixStack, float f, float skyFactor, float pitch, CallbackInfo ci) {
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) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
if (!noRender.isEnabled()) return original;
if (getStatusEffect() == StatusEffects.BLINDNESS && !noRender.blindnessEffect.isEnabled()) return false;
if (getStatusEffect() == StatusEffects.DARKNESS && !noRender.darknessEffect.isEnabled()) return false;
if (getStatusEffect() == StatusEffects.BLINDNESS && !noRender.blindnessEffect.getValue()) return false;
if (getStatusEffect() == StatusEffects.DARKNESS && !noRender.darknessEffect.getValue()) return false;
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)
private static int onTruncate(int maxLength) {
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"))
private int noRenderStuckArrows(int original) {
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;
}
}
@@ -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"))
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"))
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"))
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"))
@@ -13,6 +13,6 @@ public abstract class TextRendererMixin {
@ModifyExpressionValue(method = "getGlyph", at = @At(value = "INVOKE", target = "Lnet/minecraft/text/Style;isObfuscated()Z"))
private boolean noRenderMTS(boolean original) {
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)
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"))
private void noRenderRainAndSnow(VertexConsumerProvider vertexConsumers, Vec3d pos, WeatherRenderState weatherRenderState, CallbackInfo ci) {
if (noRender.isEnabled()) {
if (!noRender.rain.isEnabled()) weatherRenderState.rainPieces.clear();
if (!noRender.snow.isEnabled()) weatherRenderState.snowPieces.clear();
if (!noRender.rain.getValue()) weatherRenderState.rainPieces.clear();
if (!noRender.snow.getValue()) weatherRenderState.snowPieces.clear();
}
}
}
@@ -3,7 +3,7 @@ package me.retucio.sputnik.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.buffers.GpuBufferSlice;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.events.RenderWorldEvent;
import me.retucio.sputnik.event.events.Render3DEvent;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.render.BlockOutline;
import me.retucio.sputnik.module.modules.camera.Freecam;
@@ -12,16 +12,12 @@ import net.minecraft.client.render.*;
import net.minecraft.client.render.state.WorldRenderState;
import net.minecraft.client.util.ObjectAllocator;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.ColorHelper;
import net.minecraft.util.math.RotationAxis;
import net.minecraft.util.profiler.Profiler;
import org.joml.Matrix4f;
import org.joml.Vector4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -47,7 +43,7 @@ public abstract class WorldRendererMixin {
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(camera.getYaw() + 180f));
profiler.push(Sputnik.MOD_ID + "-3d");
EVENT_BUS.post(new RenderWorldEvent(matrices, tickCounter, camera));
EVENT_BUS.post(new Render3DEvent(matrices, tickCounter, camera));
profiler.pop();
matrices.pop();
@@ -56,21 +52,28 @@ public abstract class WorldRendererMixin {
@Inject(method = "renderTargetBlockOutline", at = @At("HEAD"), cancellable = true)
private void noRenderBlockOutlinesFreecam(VertexConsumerProvider.Immediate immediate, MatrixStack matrices, boolean renderBlockOutline, WorldRenderState renderStates, CallbackInfo ci) {
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)
private void hasBlindnessOrDarkness(Camera camera, CallbackInfoReturnable<Boolean> cir) {
NoRender noRender = ModuleManager.INSTANCE.getModuleByClass(NoRender.class);
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();
}
@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"),
CLIENT("cliente"),
MISC("misc.");
MISC("misc."),
ALL("todos");
private final String name;
Category(String name) { this.name = name; }
@@ -4,10 +4,11 @@ import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.config.ConfigManager;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.sputnik.ToggleModuleEvent;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.settings.KeySetting;
import me.retucio.sputnik.module.settings.Setting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.module.setting.Setting;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.client.MinecraftClient;
import org.lwjgl.glfw.GLFW;
@@ -33,46 +34,64 @@ public class Module {
protected KeySetting bind = new KeySetting("tecla", "tecla asignada al módulo, ESC para desactivar", GLFW.GLFW_KEY_UNKNOWN);
protected BooleanSetting notify = new BooleanSetting("notificar", "notificar en el chat al activar / desactivar", true);
private final List<Setting> settings = new ArrayList<>();
protected final List<SettingGroup> sgs = new ArrayList<>();
protected final SettingGroup sgGeneral = addSg(new SettingGroup("general", true));
protected MinecraftClient mc = MinecraftClient.getInstance();
public Module(String name, String description, Category category) {
this.name = name;
this.description = description;
this.category = category;
addSettings(bind, keyMode, notify);
sgGeneral.addAll(bind, keyMode, notify);
}
public Module(String name, String description, Category category, int key) {
this.name = name;
this.description = description;
this.category = category;
addSettings(bind, keyMode, notify);
this.bind.setDefaultKey(key);
sgGeneral.addAll(bind, keyMode, notify);
this.bind.setDefaultValue(key);
// puto marcos
if (ConfigManager.getConfig().settings
.get(this.getName() + ":" + bind.getName()) == null)
this.bind.setKey(key);
this.bind.setValue(key);
}
// ajustes
public List<Setting> getSettings() {
public SettingGroup addSg(SettingGroup sg) {
sgs.add(sg);
sg.setModule(this);
return sg;
}
public List<SettingGroup> getSgs() {
return sgs;
}
public SettingGroup getSg(String name) {
for (SettingGroup sg : sgs) {
if (sg.getName().equals(name)) {
return sg;
}
}
return null;
}
public SettingGroup getSgGeneral() {
return sgGeneral;
}
public List<Setting<?>> getSettings() {
List<Setting<?>> settings = new ArrayList<>();
sgs.forEach(sg -> sg.forEach(settings::add));
return settings;
}
@SuppressWarnings("unchecked")
public <S extends Setting> S addSetting(Setting setting) {
settings.add(setting);
setting.setModule(this);
return (S) setting; // por conveniencia
}
public void addSettings(Setting... settings) {
for (Setting setting : settings) addSetting(setting);
}
// encendido y apagado del módulo
public void toggle() {
@@ -83,7 +102,7 @@ public class Module {
}
public void onEnable() {
if (notify.isEnabled()) ChatUtil.info(getName() + " fue activado");
if (notify.getValue()) ChatUtil.info(getName() + " fue activado");
for (Method method : getClass().getDeclaredMethods())
if (method.isAnnotationPresent(SubscribeEvent.class)) {
Sputnik.EVENT_BUS.register(this);
@@ -93,16 +112,15 @@ public class Module {
}
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))
Sputnik.EVENT_BUS.unregister(this);
Sputnik.EVENT_BUS.post(new ToggleModuleEvent(this));
}
// otros métodos
// tick (ejecutado 20 veces por segundo)
public void onTick() {}
public void onKey(int key, int action) {}
// getters y setters
public String getName() {
@@ -150,16 +168,16 @@ public class Module {
}
public int getKey() {
return bind.getKey();
return bind.getValue();
}
public void setKey(int key) {
bind.setKey(key);
bind.setValue(key);
}
public void assignKey(int key) {
bind.setDefaultKey(key);
bind.setKey(key);
bind.setDefaultValue(key);
bind.setValue(key);
}
public KeySetting getBind() {
@@ -2,14 +2,16 @@ package me.retucio.sputnik.module;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.module.modules.camera.*;
import me.retucio.sputnik.module.modules.client.DiscordRPC;
import me.retucio.sputnik.module.modules.client.HUD;
import me.retucio.sputnik.module.modules.camera.*;
import me.retucio.sputnik.module.modules.misc.*;
import me.retucio.sputnik.module.modules.network.*;
import me.retucio.sputnik.module.modules.player.*;
import me.retucio.sputnik.module.modules.render.*;
import me.retucio.sputnik.module.modules.render.CritsPlus;
import me.retucio.sputnik.module.modules.world.*;
import me.retucio.sputnik.util.MiscUtil;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -44,9 +46,11 @@ public class ModuleManager {
modules.add(new ColoredSigns());
modules.add(new CritsPlus());
modules.add(new DamageOverlay());
modules.add(new DiscordRPC());
modules.add(new ElytraBounce());
modules.add(new FakePlayer());
modules.add(new FastUse());
modules.add(new Fonts());
modules.add(new Freecam());
modules.add(new Freelook());
modules.add(new Fullbright());
@@ -54,6 +58,7 @@ public class ModuleManager {
modules.add(new HandView());
modules.add(new Headhitters());
modules.add(new HUD());
modules.add(new InfiniteElytra());
modules.add(new InventoryPlus());
modules.add(new LightOverlay());
modules.add(new LogoutSpots());
@@ -62,21 +67,25 @@ public class ModuleManager {
modules.add(new NoRender());
modules.add(new Offhand());
modules.add(new PacketDelay());
modules.add(new Particles());
modules.add(new PerspectivePlus());
modules.add(new PortalGUI());
modules.add(new Racist());
modules.add(new Reconnect());
modules.add(new ReverseStep());
modules.add(new Rotations());
modules.add(new RPackBypass());
modules.add(new SafeWalk());
modules.add(new ScreenshotPlus());
modules.add(new ShulkerPeek());
modules.add(new Step());
modules.add(new StrongholdTriangulator());
modules.add(new TimeChanger());
modules.add(new UIMove());
modules.add(new WarnLowDurability());
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
for (Module module : getEnabledModules()) {
@@ -105,7 +114,8 @@ public class ModuleManager {
public Module getModuleByName(String name) {
for (Module module : modules)
if (module.getName().equalsIgnoreCase(name)) return module;
if (MiscUtil.removeAccentMarks(module.getName()).equalsIgnoreCase(name))
return module;
return null;
}
@@ -5,9 +5,10 @@ import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.*;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.KeySetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.KeyUtil;
import me.retucio.sputnik.util.MiscUtil;
@@ -41,21 +42,22 @@ import org.lwjgl.glfw.GLFW;
public class Freecam extends Module {
// ajustes
SettingGroup sgSpeed = addSg(new SettingGroup("velocidad", true));
public BooleanSetting toggleOnDamage = addSetting(new BooleanSetting("desactivar al recibir daño", "desactiva el módulo tras recibir daño", true));
public BooleanSetting reloadChunks = addSetting(new BooleanSetting("recargar chunks", "recargar chunks para arreglar el culling de las cuevas", true));
public BooleanSetting renderHands = addSetting(new BooleanSetting("manos visibles", "decide si se renderizan las manos mientras la cámara esté libre", true));
public BooleanSetting stayCrouching = addSetting(new BooleanSetting("mantenerse agachado", "mantener al jugador agachado tras entrar en el modo de cámara libre", false));
public BooleanSetting staticView = addSetting(new BooleanSetting("visión estática", "desactiva ajustes que muevan la cámara", true));
public BooleanSetting cancelActionPackets = addSetting(new BooleanSetting("cancelar paquetes", "evita flaggear el anticheat al interactuar con bloques / entidades", true));
public BooleanSetting blockOutlines = addSetting(new BooleanSetting("contorno de bloques", "mostrar el contorno de los bloques estando en el modo de cámara libre", true));
public BooleanSetting toggleOnDamage = sgGeneral.add(new BooleanSetting("desactivar al recibir daño", "desactiva el módulo tras recibir daño", true));
public BooleanSetting reloadChunks = sgGeneral.add(new BooleanSetting("recargar chunks", "recargar chunks para arreglar el culling de las cuevas", true));
public BooleanSetting renderHands = sgGeneral.add(new BooleanSetting("manos visibles", "decide si se renderizan las manos mientras la cámara esté libre", true));
public BooleanSetting stayCrouching = sgGeneral.add(new BooleanSetting("mantenerse agachado", "mantener al jugador agachado tras entrar en el modo de cámara libre", false));
public BooleanSetting staticView = sgGeneral.add(new BooleanSetting("visión estática", "desactiva ajustes que muevan la cámara", true));
public BooleanSetting cancelActionPackets = sgGeneral.add(new BooleanSetting("cancelar paquetes", "evita flaggear el anticheat al interactuar con bloques / entidades", true));
public BooleanSetting blockOutlines = sgGeneral.add(new BooleanSetting("contorno de bloques", "mostrar el contorno de los bloques estando en el modo de cámara libre", true));
public NumberSetting speedSetting = addSetting(new NumberSetting(
public NumberSetting speedSetting = sgSpeed.add(new NumberSetting(
"velocidad", "velocidad de movimiento de la cámara",
1, 0, 10, 0.2));
public KeySetting scrollKey = addSetting(new KeySetting("tecla del scroll", "tecla a mantener pulsada para cambiar velocidad con el scroll", GLFW.GLFW_KEY_LEFT_CONTROL));
public NumberSetting scrollSens = addSetting(new NumberSetting(
public KeySetting scrollKey = sgSpeed.add(new KeySetting("tecla del scroll", "tecla a mantener pulsada para cambiar velocidad con el scroll", GLFW.GLFW_KEY_LEFT_CONTROL));
public NumberSetting scrollSens = sgSpeed.add(new NumberSetting(
"sensibilidad del scroll", "sensibilidad de la rueda del ratón para modificar la velocidad, 0 para desactivar",
1, 0, 2, 0.1));
@@ -85,7 +87,7 @@ public class Freecam extends Module {
fovScale = mc.options.getFovEffectScale().getValue();
viewBobbing = mc.options.getBobView().getValue();
if (staticView.isEnabled()) {
if (staticView.getValue()) {
mc.options.getFovEffectScale().setValue(0D);
mc.options.getBobView().setValue(false);
}
@@ -117,25 +119,25 @@ public class Freecam extends Module {
down = KeyUtil.isKeyDown(mc.options.sneakKey);
unpress();
if (reloadChunks.isEnabled()) mc.worldRenderer.reload();
if (reloadChunks.getValue()) mc.worldRenderer.reload();
super.onEnable();
}
@Override
public void onDisable() {
if (reloadChunks.isEnabled()) mc.execute(mc.worldRenderer::reload);
if (reloadChunks.getValue()) mc.execute(mc.worldRenderer::reload);
mc.options.setPerspective(perspective);
crouching = false;
if (staticView.isEnabled()) {
if (staticView.getValue()) {
mc.options.getFovEffectScale().setValue(fovScale);
mc.options.getBobView().setValue(viewBobbing);
}
// 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)
mc.interactionManager.cancelBlockBreaking();
@@ -197,7 +199,7 @@ public class Freecam extends Module {
@SubscribeEvent
public void onSendPacket(PacketEvent.Send event) {
if (!isEnabled() || !cancelActionPackets.isEnabled()) return;
if (!isEnabled() || !cancelActionPackets.getValue()) return;
if (event.getStage() != Stage.PRE) return;
Packet<?> packet = event.getPacket();
@@ -277,7 +279,7 @@ public class Freecam extends Module {
@SubscribeEvent
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);
if (speed < 0.1) speed = 0.1;
event.cancel();
@@ -302,7 +304,7 @@ public class Freecam extends Module {
if (mc.player.getId() == packet.playerId())
toggle();
} 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");
toggle();
}
@@ -322,22 +324,22 @@ public class Freecam extends Module {
@SubscribeEvent
public void onBreakBlock(BreakBlockEvent event) {
if (cancelActionPackets.isEnabled()) event.cancel();
if (cancelActionPackets.getValue()) event.cancel();
}
@SubscribeEvent
public void onPlaceBlock(PlaceBlockEvent event) {
if (cancelActionPackets.isEnabled()) event.cancel();
if (cancelActionPackets.getValue()) event.cancel();
}
@SubscribeEvent
public void onInteractEntity(InteractEntityEvent event) {
if (cancelActionPackets.isEnabled()) event.cancel();
if (cancelActionPackets.getValue()) event.cancel();
}
@SubscribeEvent
public void onAttack(AttackEntityEvent event) {
if (cancelActionPackets.isEnabled()) event.cancel();
if (cancelActionPackets.getValue()) event.cancel();
}
public void changeLookDirection(double deltaX, double deltaY) {
@@ -2,8 +2,8 @@ package me.retucio.sputnik.module.modules.camera;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.KeyUtil;
import net.minecraft.client.option.Perspective;
import net.minecraft.util.math.MathHelper;
@@ -16,13 +16,13 @@ import org.lwjgl.glfw.GLFW;
public class Freelook extends Module {
public EnumSetting<CameraMode> mode = addSetting(new EnumSetting<>("cámara a mover", "elige cual cámara mover con el ratón y cuál se queda estática",
public EnumSetting<CameraMode> mode = sgGeneral.add(new EnumSetting<>("cámara a mover", "elige cual cámara mover con el ratón y cuál se queda estática",
CameraMode.class, CameraMode.CAMERA));
public NumberSetting arrowSens = addSetting(new NumberSetting("sensibilidad de las flechas", "cuánto rotan la cámara estática las flechas (0 para desactivar)",
public NumberSetting arrowSens = sgGeneral.add(new NumberSetting("sensibilidad de las flechas", "cuánto rotan la cámara estática las flechas (0 para desactivar)",
4, 0, 10, 0.1));
public NumberSetting mouseSens = addSetting(new NumberSetting("sensibilidad del ratón", ".",
public NumberSetting mouseSens = sgGeneral.add(new NumberSetting("sensibilidad del ratón", ".",
0.1, 0, 2, 0.05));
private float yaw;
@@ -39,7 +39,7 @@ public class Freelook extends Module {
keyMode.setValue(KeyModes.HOLD);
notify.setDefaultValue(false);
notify.setEnabled(false);
notify.setValue(false);
}
@Override
@@ -3,8 +3,8 @@ package me.retucio.sputnik.module.modules.camera;
import me.retucio.sputnik.mixin.accessor.StatusEffectInstanceAccessor;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.ColorSetting;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.registry.Registries;
@@ -18,9 +18,9 @@ import java.awt.*;
public class Fullbright extends Module {
public EnumSetting<Modes> mode = addSetting(new EnumSetting<>("modo", "qué modo de iluminación emplear (usar poción con shaders)", Modes.class, Modes.GAMMA));
public EnumSetting<Modes> mode = sgGeneral.add(new EnumSetting<>("modo", "qué modo de iluminación emplear (usar poción con shaders)", Modes.class, Modes.GAMMA));
public ColorSetting color = addSetting(new ColorSetting("filtro", "filtro de color", new Color(255, 255, 255, 255), false));
public ColorSetting color = sgGeneral.add(new ColorSetting("filtro", "filtro de color", new Color(255, 255, 255, 255), false));
public Fullbright() {
super("brilli brilli",
@@ -5,28 +5,35 @@ import me.retucio.sputnik.event.events.MouseScrollEvent;
import me.retucio.sputnik.event.events.PerspectiveChangeEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.*;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.KeyUtil;
import org.lwjgl.glfw.GLFW;
// continúa en CameraMixin
public class PerspectivePlus extends Module {
private double distance;
// ajustes
public BooleanSetting clip = addSetting(new BooleanSetting(
SettingGroup sgScroll = addSg(new SettingGroup("scrolleo", true));
public BooleanSetting clip = sgGeneral.add(new BooleanSetting(
"clip", "atravesar bloques con la cámara", true));
public NumberSetting defaultDistance = addSetting(new NumberSetting(
public NumberSetting defaultDistance = sgGeneral.add(new NumberSetting(
"distancia", "distancia a la que está la cámara del jugador por defecto",
4, 1, 20, 0.2));
public NumberSetting scrollSens = addSetting(new NumberSetting(
public NumberSetting scrollSens = sgScroll.add(new NumberSetting(
"sensibilidad del scroll", "sensibilidad de la rueda del ratón (0 para desactivar)",
1, 0, 8, 0.1));
public KeySetting scrollKey = addSetting(new KeySetting("tecla del scroll", "qué tecla mantener para usar la rueda del ratón", GLFW.GLFW_KEY_LEFT_ALT));
public KeySetting scrollKey = sgScroll.add(new KeySetting("tecla del scroll", "qué tecla mantener para usar la rueda del ratón",
GLFW.GLFW_KEY_LEFT_ALT));
private double distance;
public PerspectivePlus() {
super("perspectiva plus",
@@ -50,7 +57,7 @@ public class PerspectivePlus extends Module {
if (mc.options.getPerspective() == net.minecraft.client.option.Perspective.FIRST_PERSON
|| mc.currentScreen != null || scrollSens.getValue() <= 0) return;
if (KeyUtil.isKeyDown(scrollKey.getKey())) {
if (KeyUtil.isKeyDown(scrollKey.getValue())) {
distance -= event.getVertical() / 4 * (scrollSens.getValue() * distance);
event.cancel();
}
@@ -4,17 +4,17 @@ import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.ChangeRotationEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
public class Rotations extends Module {
public NumberSetting yaw = addSetting(new NumberSetting("guiñada", "eje vertical - giro horizontal (yaw)", 0, -180, 180, 1));
public NumberSetting pitch = addSetting(new NumberSetting("cabeceo", "eje horizontal - giro vertical (pitch)", 0, -90, 90, 1));
public NumberSetting yaw = sgGeneral.add(new NumberSetting("guiñada", "eje vertical - giro horizontal (yaw)", 0, -180, 180, 1));
public NumberSetting pitch = sgGeneral.add(new NumberSetting("cabeceo", "eje horizontal - giro vertical (pitch)", 0, -90, 90, 1));
public BooleanSetting smooth = addSetting(new BooleanSetting("evitar movimiento", "cancela todo movimiento de la cámara", false));
public BooleanSetting serverSide = addSetting(new BooleanSetting("serverside", "espamea paquetes de rotación al servidor", false));
public BooleanSetting smooth = sgGeneral.add(new BooleanSetting("evitar movimiento", "cancela todo movimiento de la cámara", false));
public BooleanSetting serverSide = sgGeneral.add(new BooleanSetting("serverside", "espamea paquetes de rotación al servidor", false));
public Rotations() {
super("rotaciones",
@@ -29,14 +29,14 @@ public class Rotations extends Module {
mc.player.setYaw(yaw.getFloatValue());
mc.player.setPitch(pitch.getFloatValue());
if (serverSide.isEnabled())
if (serverSide.getValue())
mc.player.networkHandler.sendPacket(new PlayerMoveC2SPacket.LookAndOnGround(
yaw.getFloatValue(), pitch.getFloatValue(), mc.player.isOnGround(), mc.player.horizontalCollision));
}
@SubscribeEvent
public void onChangeRotation(ChangeRotationEvent event) {
if (smooth.isEnabled()
if (smooth.getValue()
&& (event.getYaw() != yaw.getFloatValue() || event.getPitch() != pitch.getFloatValue())){
event.cancel();
}}
@@ -5,30 +5,34 @@ import me.retucio.sputnik.event.events.GetFOVEvent;
import me.retucio.sputnik.event.events.MouseScrollEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.KeySetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.KeyUtil;
import org.lwjgl.glfw.GLFW;
// continúa en GameRendererMixin
public class Zoom extends Module {
public BooleanSetting showHands = addSetting(new BooleanSetting("mostrar manos", "esconde o muestra las manos al hacer zoom", true));
public BooleanSetting showHUD = addSetting(new BooleanSetting("mostrar HUD", "esconde o muestra los indicadores en pantalla", true));
SettingGroup sgVisual = addSg(new SettingGroup("visual", true));
SettingGroup sgScroll = addSg(new SettingGroup("scrolleo", true));
SettingGroup sgCam = addSg(new SettingGroup("cámara", true));
public NumberSetting scrollSens = addSetting(new NumberSetting("sensibilidad del scroll", "sensibilidad de la rueda del ratón (0 para desactivar)",
0.4, 0, 8, 0.1));
public KeySetting scrollKey = addSetting(new KeySetting("tecla del scroll", "qué tecla mantener para usar la rueda del ratón", GLFW.GLFW_KEY_LEFT_CONTROL));
public NumberSetting defaultZoom = addSetting(new NumberSetting("zoom", "cantidad de zoom",
public NumberSetting defaultZoom = sgGeneral.add(new NumberSetting("zoom", "cantidad de zoom",
6, 1, 10, 0.1));
public NumberSetting mouseSensMultiplier = addSetting(new NumberSetting("sensibilidad", "multiplicador de la sensibilidad del ratón",
0.4, 0, 1, 0.05));
public BooleanSetting showHands = sgVisual.add(new BooleanSetting("mostrar manos", "esconde o muestra las manos al hacer zoom", true));
public BooleanSetting showHUD = sgVisual.add(new BooleanSetting("mostrar HUD", "esconde o muestra los indicadores en pantalla", true));
public BooleanSetting smoothCam = addSetting(new BooleanSetting("cámara cinemática", "usa la cámara cinemática mientras hagas zoom", false));
public NumberSetting scrollSens = sgScroll.add(new NumberSetting("sensibilidad del scroll", "sensibilidad de la rueda del ratón (0 para desactivar)",
0.4, 0, 8, 0.1));
public KeySetting scrollKey = sgScroll.add(new KeySetting("tecla del scroll", "qué tecla mantener para usar la rueda del ratón",
GLFW.GLFW_KEY_LEFT_CONTROL));
public NumberSetting mouseSensMultiplier = sgCam.add(new NumberSetting("sensibilidad", "multiplicador de la sensibilidad del ratón",
0.4, 0, 1, 0.05));
public BooleanSetting smoothCam = sgCam.add(new BooleanSetting("cámara cinemática", "usa la cámara cinemática mientras hagas zoom", false));
private boolean prevSmoothCam;
private double prevMouseSens;
@@ -46,7 +50,7 @@ public class Zoom extends Module {
keyMode.setValue(KeyModes.HOLD);
notify.setDefaultValue(false);
notify.setEnabled(false);
notify.setValue(false);
}
@Override
@@ -57,7 +61,7 @@ public class Zoom extends Module {
prevMouseSens = mc.options.getMouseSensitivity().getValue();
prevFov = mc.options.getFov().getValue();
prevHUD = mc.options.hudHidden;
mc.options.hudHidden = !showHUD.isEnabled();
mc.options.hudHidden = !showHUD.getValue();
value = defaultZoom.getValue();
@@ -79,14 +83,14 @@ public class Zoom extends Module {
@Override
public void onTick() {
mc.options.smoothCameraEnabled = smoothCam.isEnabled();
if (!smoothCam.isEnabled())
mc.options.smoothCameraEnabled = smoothCam.getValue();
if (!smoothCam.getValue())
mc.options.getMouseSensitivity().setValue(prevMouseSens * mouseSensMultiplier.getValue());
}
@SubscribeEvent
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) {
value += event.getVertical() * 0.25 * (scrollSens.getValue() * value);
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()]; }
}
}
@@ -9,10 +9,11 @@ import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.misc.ChatPlus;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.ColorSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.settings.StringSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.StringSetting;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.Colors;
import org.lwjgl.glfw.GLFW;
@@ -22,25 +23,30 @@ import java.awt.*;
// módulo no visible solo para los ajustes de la interfaz (y del cliente en general)
public class GUI extends Module {
public ColorSetting color = addSetting(new ColorSetting("color", "color principal de la interfaz y el mod",
SettingGroup sgWidgets = addSg(new SettingGroup("widgets", true));
SettingGroup sgUi = addSg(new SettingGroup("interfaz", true));
SettingGroup sgChat = addSg(new SettingGroup("chat", true));
SettingGroup sgMisc = addSg(new SettingGroup("misc.", true));
public ColorSetting color = sgGeneral.add(new ColorSetting("color", "color principal de la interfaz y el mod",
new Color(70, 20, 210, 230), false));
// números negativos para deslizamiento inverso, 0 para desactivar
public NumberSetting scrollSens = addSetting(new NumberSetting("sensibilidad del scroll", "qué tan sensible es la interfaz a la rueda del ratón",
public NumberSetting scrollSens = sgWidgets.add(new NumberSetting("sensibilidad del scroll", "qué tan sensible es la interfaz a la rueda del ratón",
5, -15, 15, 0.5));
public BooleanSetting scrollBar = addSetting(new BooleanSetting("barra de desplazamiento", "renderizar una barra de desplazamiento a la derecha de la interfaz", true));
public BooleanSetting scrollBar = sgWidgets.add(new BooleanSetting("barra de desplazamiento", "renderizar una barra de desplazamiento a la derecha de la interfaz", true));
public BooleanSetting searchBar = addSetting(new BooleanSetting("barra de búsqueda", "renderizar una barra de búsqueda que filtra resultados en todos los marcos abiertos", true));
public BooleanSetting matchCase = addSetting(new BooleanSetting("distinguir mayúsculas", "la búsqueda es sensible a mayúsculas y minúsculas", false));
public BooleanSetting searchBar = sgWidgets.add(new BooleanSetting("barra de búsqueda", "renderizar una barra de búsqueda que filtra resultados en todos los marcos abiertos", true));
public BooleanSetting matchCase = sgWidgets.add(new BooleanSetting("distinguir mayúsculas", "la búsqueda es sensible a mayúsculas y minúsculas", false));
// ^^^ no sé de qué sirve porque está todo en minúsculas pero bueno
public BooleanSetting blur = addSetting(new BooleanSetting("desenfoque", "desenfocar el fondo mientras la interfaz está abierta", true));
public StringSetting watermark = addSetting(new StringSetting("marca de agua", "marca de agua para interfaces (dejar vacío para desactivar)", me.retucio.sputnik.Sputnik.getVersionName(), 40));
public BooleanSetting blur = sgUi.add(new BooleanSetting("desenfoque", "desenfocar el fondo mientras la interfaz está abierta", true));
public StringSetting watermark = sgUi.add(new StringSetting("marca de agua", "marca de agua para interfaces (dejar vacío para desactivar)", me.retucio.sputnik.Sputnik.getVersionName(), 40));
public StringSetting commandPrefix = addSetting(new StringSetting("prefijo", "prefijo de los comandos", "$", 10));
public StringSetting chatName = addSetting(new StringSetting("nombre", "qué nombre usar en notificaciones por el chat", "smegma", 20));
public StringSetting commandPrefix = sgChat.add(new StringSetting("prefijo", "prefijo de los comandos", "$", 10));
public StringSetting chatName = sgChat.add(new StringSetting("nombre", "qué nombre usar en notificaciones por el chat", "smegma", 20));
public BooleanSetting multipleKeybinds = addSetting(new BooleanSetting("teclas multimódulo", "permitir asignar la misma tecla a más de un módulo", false));
public BooleanSetting multipleKeybinds = sgMisc.add(new BooleanSetting("teclas multimódulo", "permitir asignar la misma tecla a más de un módulo", false));
public GUI() {
super("interfaz",
@@ -2,7 +2,8 @@ package me.retucio.sputnik.module.modules.client;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.*;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.*;
import me.retucio.sputnik.ui.hud.HudElement;
import me.retucio.sputnik.ui.hud.HudRenderer;
import me.retucio.sputnik.ui.hud.HudEditorScreen;
@@ -19,22 +20,97 @@ import java.awt.*;
public class HUD extends Module {
SettingGroup sgEditor = addSg(new SettingGroup("editor", true));
SettingGroup sgDisplay = addSg(new SettingGroup("visualización", true));
SettingGroup sgElements = addSg(new SettingGroup("elementos", false));
// editor
public KeySetting editorKey = addSetting(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
public ColorSetting color = addSetting(new ColorSetting("color", "color del texto de los elementos del HUD",
new Color(255, 255, 255, 255), false));
public BooleanSetting showOnF3 = addSetting(new BooleanSetting("mostrar en F3", "renderizar HUD en el menú de debug", false));
public BooleanSetting showOnChat = addSetting(new BooleanSetting("mostrar en chat", "renderizar HUD en la pantalla del chat", false));
// renderizado
public ColorSetting color = sgDisplay.add(new ColorSetting(
"color",
"color del texto de los elementos del HUD",
new Color(255, 255, 255, 255), 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 BooleanSetting shadow = addSetting(new BooleanSetting("sombra", "texto con sombra", true));
public NumberSetting timezone = addSetting(new NumberSetting("zona horaria", "zona horaria en UTC+n", 1, -6, 6, 1));
public EnumSetting<TimeFormat> timeFormat = addSetting(new EnumSetting<>("formato de la hora", "12h o 24h", TimeFormat.class, TimeFormat.TWENTY_FOUR_HOUR));
public StringSetting customText = addSetting(new StringSetting("texto custom", "marca de agua (dejar vacío para quitar)", "adolf jitler inshtagram feishbuc twiter", 40));
public EnumSetting<CoordsMode> coordsMode = addSetting(new EnumSetting<>("modo de coordenadas", "qué coordenadas mostrar", CoordsMode.class, CoordsMode.OVERWORLD));
public EnumSetting<Dynosaurs> dyno = addSetting(new EnumSetting<>("dinosaurio", "qué dinosaurio mostrar",
Dynosaurs.class, Dynosaurs.SPINOSAURUS));
// elementos
public NumberSetting timezone = sgElements.add(new NumberSetting(
"zona horaria",
"zona horaria en UTC+n",
1,
-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() {
super("HUD",
@@ -43,6 +119,9 @@ public class HUD extends Module {
GLFW.GLFW_KEY_F12
);
axialMovement.onUpdate(v -> axisOffset.setVisible(v));
arrowMovement.onUpdate(v -> arrowOffset.setVisible(v));
dyno.onUpdate(v -> {
DynoElement element = (DynoElement) HudRenderer.getElement(DynoElement.class);
if (element != null) element.reloadTexture();
@@ -3,7 +3,7 @@ package me.retucio.sputnik.module.modules.misc;
import me.retucio.sputnik.mixin.accessor.AnvilScreenAccessor;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
import net.minecraft.client.gui.widget.TextFieldWidget;
@@ -17,7 +17,7 @@ import java.util.Map;
public class AnvilFont extends Module {
public EnumSetting<FontMode> fontMode = addSetting(new EnumSetting<>("tipografía", "qué tipografía utilizar",
public EnumSetting<FontMode> fontMode = sgGeneral.add(new EnumSetting<>("tipografía", "qué tipografía utilizar",
FontMode.class, FontMode.NORMAL));
String text;
@@ -4,8 +4,8 @@ import me.retucio.sputnik.event.events.RenderBossbarEvent;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import net.minecraft.client.gui.hud.ClientBossBar;
import net.minecraft.text.Text;
@@ -15,10 +15,25 @@ import java.util.WeakHashMap;
public class BossbarStack extends Module {
public BooleanSetting stackBars = addSetting(new BooleanSetting("apilar barras", "apilar las bossbars", true));
public BooleanSetting hideNames = addSetting(new BooleanSetting("esconder nombres", "no renderiza el nombre de los bosses", false));
public NumberSetting spaceReduction = addSetting(new NumberSetting("reducción de espacio", "cuánto reducir el espacio entre bossbars",
0, 0, 10, 0.1));
public BooleanSetting stackBars = sgGeneral.add(new BooleanSetting(
"apilar barras", "apilar las bossbars",
true
));
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<>();
@@ -30,16 +45,16 @@ public class BossbarStack extends Module {
@SubscribeEvent
private void onRenderBossText(RenderBossbarEvent.BossText event) {
if (hideNames.isEnabled()) {
if (hideNames.getValue()) {
event.setName(Text.empty());
return;
} else if (bossBarMap.isEmpty() || !stackBars.isEnabled()) return;
} else if (bossBarMap.isEmpty() || !stackBars.getValue()) return;
ClientBossBar bar = event.getBossBar();
Integer amount = bossBarMap.get(bar);
bossBarMap.remove(bar);
if (amount != null && !hideNames.isEnabled())
if (amount != null && !hideNames.getValue())
event.setName(event.getName().copy().append(" x" + amount));
}
@@ -50,7 +65,7 @@ public class BossbarStack extends Module {
@SubscribeEvent
private void onRenderBossBars(RenderBossbarEvent.BossIterator event) {
if (stackBars.isEnabled()) {
if (stackBars.getValue()) {
HashMap<String, ClientBossBar> chosenBarMap = new HashMap<>();
event.getIterator().forEachRemaining(bar -> {
String name = bar.getName().getString();
@@ -10,8 +10,9 @@ import me.retucio.sputnik.event.events.ReceiveMessageEvent;
import me.retucio.sputnik.event.events.SendMessageEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.interfaces.IChatHudLine;
import me.retucio.sputnik.util.interfaces.IChatHudLineVisible;
@@ -43,15 +44,17 @@ import java.util.regex.Pattern;
public class ChatPlus extends Module {
// ajustes
public BooleanSetting timestamps = addSetting(new BooleanSetting("sello de tiempo", "muestra a qué hora se ha enviado un mensaje", true));
public BooleanSetting timestampSecs = addSetting(new BooleanSetting("mostrar segundos", "muestra segundos también en el sello de tiempo", false));
public BooleanSetting showHeads = addSetting(new BooleanSetting("cabezas", "muestra la cabeza del jugador junto a su mensaje", true));
public BooleanSetting coordsProtection = addSetting(new BooleanSetting("proteger coordenadas", "evitar enviar coordenadas por el chat", true));
SettingGroup sgChat = addSg(new SettingGroup("funcionamiento del chat", true));
public BooleanSetting keepHistory = addSetting(new BooleanSetting("no borrar chat", "no borrar el chat tras desconectarse", true));
public BooleanSetting logger = addSetting(new BooleanSetting("registro", "evita que se borre el chat de un server", true));
public BooleanSetting noCharLimit = addSetting(new BooleanSetting("quitar límite de caracteres", "te deja escribir mensajes tan largos como desees", false));
public NumberSetting chatHistoryExtraLength = addSetting(new NumberSetting("expandir chat", "cuántas líneas añadir al historial del chat",
public BooleanSetting timestamps = sgGeneral.add(new BooleanSetting("sello de tiempo", "muestra a qué hora se ha enviado un mensaje", true));
public BooleanSetting timestampSecs = sgGeneral.add(new BooleanSetting("mostrar segundos", "muestra segundos también en el sello de tiempo", false));
public BooleanSetting showHeads = sgGeneral.add(new BooleanSetting("cabezas", "muestra la cabeza del jugador junto a su mensaje", true));
public BooleanSetting coordsProtection = sgChat.add(new BooleanSetting("proteger coordenadas", "evitar enviar coordenadas por el chat", true));
public BooleanSetting keepHistory = sgChat.add(new BooleanSetting("no borrar chat", "no borrar el chat tras desconectarse", true));
public BooleanSetting logger = sgChat.add(new BooleanSetting("registro", "evita que se borre el chat de un server", true));
public BooleanSetting noCharLimit = sgChat.add(new BooleanSetting("quitar límite de caracteres", "te deja escribir mensajes tan largos como desees", false));
public NumberSetting chatHistoryExtraLength = sgChat.add(new NumberSetting("expandir chat", "cuántas líneas añadir al historial del chat",
0, 0, 1000, 1));
public ChatPlus() {
@@ -79,7 +82,7 @@ public class ChatPlus extends Module {
Text message = event.getMessage();
// registrar mensajes para evitar su eliminación
if (logger.isEnabled()) {
if (logger.getValue()) {
String messageString = message.getString();
if (loggerRegex.matcher(messageString).find()) {
MutableText newMessage = Text.empty();
@@ -97,7 +100,7 @@ public class ChatPlus extends Module {
}
// agregar sellos de tiempo a los mensajes
if (timestamps.isEnabled()) {
if (timestamps.getValue()) {
Text timestamp = Text.literal("[" + dateFormat.format(new Date()) + "] ").formatted(Formatting.GRAY);
message = Text.empty().append(timestamp).append(message);
}
@@ -109,7 +112,7 @@ public class ChatPlus extends Module {
@SubscribeEvent
private void onSendMessage(SendMessageEvent event) {
// 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(
getSendButton(event.getMessage())));
@@ -124,7 +127,7 @@ public class ChatPlus extends Module {
@SuppressWarnings("DataFlowIssue")
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
if (((IChatHudLineVisible) (Object) line).sputnik$isStartOfEntry())
@@ -136,7 +139,7 @@ public class ChatPlus extends Module {
public void afterDrawMessage(DrawContext context) {
// finalizar renderizado de la cabeza
if (!isEnabled() || !showHeads.isEnabled()) return;
if (!isEnabled() || !showHeads.getValue()) return;
context.getMatrices().popMatrix();
}
@@ -215,7 +218,7 @@ public class ChatPlus extends Module {
}
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) {
@@ -3,7 +3,7 @@ package me.retucio.sputnik.module.modules.misc;
import com.mojang.authlib.GameProfile;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.StringSetting;
import me.retucio.sputnik.module.setting.settings.StringSetting;
import net.minecraft.client.network.OtherClientPlayerEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
@@ -12,7 +12,7 @@ import java.util.UUID;
public class FakePlayer extends Module {
public StringSetting name = addSetting(new StringSetting("nombre", "qué nombre asignarle al jugador", "apio boy", 22));
public StringSetting name = sgGeneral.add(new StringSetting("nombre", "qué nombre asignarle al jugador", "apio boy", 22));
private OtherClientPlayerEntity player = null;
@@ -4,8 +4,9 @@ import me.retucio.sputnik.command.CommandManager;
import me.retucio.sputnik.event.events.ClientClickEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.text.ClickEvent;
@@ -30,14 +31,16 @@ import java.io.IOException;
public class ScreenshotPlus extends Module {
public BooleanSetting saveButton = addSetting(new BooleanSetting("botón de guardar", "mostrar botón para guardar la captura localmente", true));
public BooleanSetting copyButton = addSetting(new BooleanSetting("botón de copiar", "mostrar botón para copiar la captura al portapapeles", true));
public BooleanSetting openButton = addSetting(new BooleanSetting("botón de abrir", "mostrar botón para abrir el archivo de la captura", true));
public BooleanSetting discardButton = addSetting(new BooleanSetting("botón de descartar", "mostrar botón para descartar la captura", true));
SettingGroup sgButtons = addSg(new SettingGroup("botones", true));
public EnumSetting<ScreenshotActions> defaultAction = addSetting(new EnumSetting<>("por defecto", "qué acción tomar por defecto",
public EnumSetting<ScreenshotActions> defaultAction = sgGeneral.add(new EnumSetting<>("por defecto", "qué acción tomar por defecto",
ScreenshotActions.class, ScreenshotActions.NONE));
public BooleanSetting saveButton = sgButtons.add(new BooleanSetting("botón de guardar", "mostrar botón para guardar la captura localmente", true));
public BooleanSetting copyButton = sgButtons.add(new BooleanSetting("botón de copiar", "mostrar botón para copiar la captura al portapapeles", true));
public BooleanSetting openButton = sgButtons.add(new BooleanSetting("botón de abrir", "mostrar botón para abrir el archivo de la captura", true));
public BooleanSetting discardButton = sgButtons.add(new BooleanSetting("botón de descartar", "mostrar botón para descartar la captura", true));
private NativeImage screenshot;
private File screenshotFile;
@@ -49,10 +52,10 @@ public class ScreenshotPlus extends Module {
public void sendScreenshotMessage() {
MutableText baseText = Text.literal("captura de pantalla tomada\n");
if (saveButton.isEnabled() && !defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getSaveButton().append(" "));
if (copyButton.isEnabled()) baseText.append(getCopyButton().append(" "));
if (openButton.isEnabled() && defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getOpenButton().append(" "));
if (discardButton.isEnabled() && !defaultAction.is(ScreenshotActions.NONE)) baseText.append(getDiscardButton().append(" "));
if (saveButton.getValue() && !defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getSaveButton().append(" "));
if (copyButton.getValue()) baseText.append(getCopyButton().append(" "));
if (openButton.getValue() && defaultAction.is(ScreenshotActions.SAVE)) baseText.append(getOpenButton().append(" "));
if (discardButton.getValue() && !defaultAction.is(ScreenshotActions.NONE)) baseText.append(getDiscardButton().append(" "));
ChatUtil.info(baseText);
}
@@ -5,8 +5,8 @@ import me.retucio.sputnik.event.events.KeyEvent;
import me.retucio.sputnik.mixin.accessor.HandledScreenAccessor;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.KeySetting;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.ui.screen.PreviewScreen;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.Colors;
@@ -29,8 +29,8 @@ import java.util.HashMap;
public class ShulkerPeek extends Module {
public KeySetting previewKey = addSetting(new KeySetting("tecla de previsualización", "tecla a mantener para previsualizar", GLFW.GLFW_KEY_LEFT_ALT));
public BooleanSetting showTooltips = addSetting(new BooleanSetting("mostrar tooltips", "añadir texto a los tooltips (cajas de texto) de los shulkers", true));
public KeySetting previewKey = sgGeneral.add(new KeySetting("tecla de previsualización", "tecla a mantener para previsualizar", GLFW.GLFW_KEY_LEFT_ALT));
public BooleanSetting showTooltips = sgGeneral.add(new BooleanSetting("mostrar tooltips", "añadir texto a los tooltips (cajas de texto) de los shulkers", true));
public static final HashMap<Item, Color> SHULKER_COLORS = new HashMap<>();
@@ -62,7 +62,7 @@ public class ShulkerPeek extends Module {
@SubscribeEvent
public void onKey(KeyEvent event) {
if (mc.player == null) return;
if (event.getKey() != previewKey.getKey()) return;
if (event.getKey() != previewKey.getValue()) return;
if (event.getAction() == GLFW.GLFW_PRESS) {
openPreviewScreen();
@@ -2,12 +2,12 @@ package me.retucio.sputnik.module.modules.network;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.StringSetting;
import me.retucio.sputnik.module.setting.settings.StringSetting;
import me.retucio.sputnik.util.ChatUtil;
public class BungeecordSpoofer extends Module {
public StringSetting address = addSetting(new StringSetting("dirección", "la dirección IP que será enviada al server", "127.0.0.1", 15));
public StringSetting address = sgGeneral.add(new StringSetting("dirección", "la dirección IP que será enviada al server", "127.0.0.1", 15));
public BungeecordSpoofer() {
super("spoofer de bungeecord",
@@ -2,14 +2,15 @@ package me.retucio.sputnik.module.modules.network;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.AddEntityEvent;
import me.retucio.sputnik.event.events.RenderWorldEvent;
import me.retucio.sputnik.event.events.Render3DEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.misc.FakePlayer;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.ColorSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.MiscUtil;
import me.retucio.sputnik.util.render.RenderUtil;
import net.minecraft.client.network.OtherClientPlayerEntity;
@@ -31,16 +32,20 @@ import java.util.UUID;
// lógica sutilmente robada de MeteorClient porque la mía era una mierda
public class LogoutSpots extends Module {
public BooleanSetting outlines = addSetting(new BooleanSetting("contorno", "renderizar contorno de la caja (lados)", true));
public ColorSetting outlineColor = addSetting(new ColorSetting("color del contorno", "Color de las líneas", new Color(255, 0, 0, 230), false));
public NumberSetting lineWidth = addSetting(new NumberSetting("grosor de línea", "grosor de las líneas del contorno", 1.5, 0.5, 5, 0.1));
SettingGroup sgOutlines = addSg(new SettingGroup("contorno", true));
SettingGroup sgFilling = addSg(new SettingGroup("relleno", true));
SettingGroup sgMisc = addSg(new SettingGroup("misc.", true));
public BooleanSetting filling = addSetting(new BooleanSetting("relleno", "renderizar relleno de la caja (caras)", true));
public ColorSetting fillingColor = addSetting(new ColorSetting("color del relleno", "Color de los lados", new Color(230, 0, 0, 55), false));
public BooleanSetting outlines = sgOutlines.add(new BooleanSetting("contorno", "renderizar contorno de la caja (lados)", true));
public ColorSetting outlineColor = sgOutlines.add(new ColorSetting("color del contorno", "Color de las líneas", new Color(255, 0, 0, 230), false));
public NumberSetting lineWidth = sgOutlines.add(new NumberSetting("grosor de línea", "grosor de las líneas del contorno", 1.5, 0.5, 5, 0.1));
public BooleanSetting fullHeight = addSetting(new BooleanSetting("hitbox completa", "renderizar la caja completa de la hitbox, o solo marcar la posición", true));
public BooleanSetting filling = sgFilling.add(new BooleanSetting("relleno", "renderizar relleno de la caja (caras)", true));
public ColorSetting fillingColor = sgFilling.add(new ColorSetting("color del relleno", "Color de los lados", new Color(230, 0, 0, 55), false));
public BooleanSetting dummy = addSetting(new BooleanSetting("monigote", "spawnear un monigote para marcar la posición", true));
public BooleanSetting fullHeight = sgMisc.add(new BooleanSetting("hitbox completa", "renderizar la caja completa de la hitbox, o solo marcar la posición", true));
public BooleanSetting dummy = sgMisc.add(new BooleanSetting("monigote", "spawnear un monigote para marcar la posición", true));
private final List<LogoutEntry> players = new ArrayList<>();
private final List<PlayerListEntry> lastPlayerList = new ArrayList<>();
@@ -56,12 +61,12 @@ public class LogoutSpots extends Module {
outlines.onUpdate(v -> {
outlineColor.setVisible(v);
fullHeight.setVisible(v || filling.isEnabled());
fullHeight.setVisible(v || filling.getValue());
});
filling.onUpdate(v -> {
fillingColor.setVisible(v);
fullHeight.setVisible(v || outlines.isEnabled());
fullHeight.setVisible(v || outlines.getValue());
});
dummy.onUpdate(v -> {
@@ -111,7 +116,7 @@ public class LogoutSpots extends Module {
if (player.getUuid().equals(entry.getProfile().id())) {
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);
addLogoutSpot(logoutEntry);
@@ -165,7 +170,7 @@ public class LogoutSpots extends Module {
}
@SubscribeEvent
public void onWorldRender(RenderWorldEvent event) {
public void onWorldRender(Render3DEvent event) {
if (mc.player == null || mc.world == null) return;
for (LogoutEntry entry : players)
@@ -243,21 +248,21 @@ public class LogoutSpots extends Module {
}
public void renderBox(MatrixStack matrices) {
if (fullHeight.isEnabled()) {
if (outlines.isEnabled())
RenderUtil.drawOutlineBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), outlineColor.getColor(), lineWidth.getFloatValue(), true);
if (filling.isEnabled())
RenderUtil.drawFilledBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), fillingColor.getColor(), true);
if (fullHeight.getValue()) {
if (outlines.getValue())
RenderUtil.drawOutlineBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), outlineColor.getValue(), lineWidth.getFloatValue(), true);
if (filling.getValue())
RenderUtil.drawFilledBox(matrices, new Box(x, y, z, x + xWidth, y + height, z + zWidth), fillingColor.getValue(), true);
} else {
if (outlines.isEnabled()) {
if (outlines.getValue()) {
RenderUtil.drawBlockFaceOutlines(matrices,
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,
BlockPos.ofFloored(x + halfWidth, y, z + halfWidth),
Direction.UP, fillingColor.getColor(), 0.001f, true);
Direction.UP, fillingColor.getValue(), 0.001f, true);
}
}
}
@@ -5,8 +5,8 @@ import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.PacketEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.NetworkUtil;
@@ -22,10 +22,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class PacketDelay extends Module {
public NumberSetting delay = addSetting(new NumberSetting("delay", "delay a añadir a los paquetes, en milisegundos", 1500, 0, 3000, 5));
public EnumSetting<Directions> directions = addSetting(new EnumSetting<>("dirección", "dirección de los paquetes a los que añadir delay",
public NumberSetting delay = sgGeneral.add(new NumberSetting("delay", "delay a añadir a los paquetes, en milisegundos", 1500, 0, 3000, 5));
public EnumSetting<Directions> directions = sgGeneral.add(new EnumSetting<>("dirección", "dirección de los paquetes a los que añadir delay",
Directions.class, Directions.BOTH));
public EnumSetting<Packets> packets = addSetting(new EnumSetting<>("paquetes", "paquetes a los que aplicar el delay",
public EnumSetting<Packets> packets = sgGeneral.add(new EnumSetting<>("paquetes", "paquetes a los que aplicar el delay",
Packets.class, Packets.ALL));
private final List<DelayedPacket> delayedPackets = new CopyOnWriteArrayList<>();
@@ -4,14 +4,14 @@ import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.AttackEntityEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
public class AttributeSwapper extends Module {
public NumberSetting slot = addSetting(new NumberSetting("slot", "slot al que cambiar", 1, 1, 9, 1));
public BooleanSetting swap = addSetting(new BooleanSetting("cambiar de vuelta", "volver al slot inicial tras haber aplicado el swapping", true));
public NumberSetting swapDelay = addSetting(new NumberSetting("delay de cambio de vuelta", "tiempo que se tarda en volver al slot inicial", 1, 1, 20, 1));
public NumberSetting slot = sgGeneral.add(new NumberSetting("slot", "slot al que cambiar", 1, 1, 9, 1));
public BooleanSetting swap = sgGeneral.add(new BooleanSetting("cambiar de vuelta", "volver al slot inicial tras haber aplicado el swapping", true));
public NumberSetting swapDelay = sgGeneral.add(new NumberSetting("delay de cambio de vuelta", "tiempo que se tarda en volver al slot inicial", 1, 1, 20, 1));
private int delay = 0;
private int prevSlot = -1;
@@ -24,7 +24,7 @@ public class AttributeSwapper extends Module {
@Override
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() && prevSlot != -1) {
mc.player.getInventory().setSelectedSlot(prevSlot);
@@ -4,11 +4,11 @@ import me.retucio.sputnik.cape.Cape;
import me.retucio.sputnik.cape.CapeManager;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.OptionSetting;
import me.retucio.sputnik.module.setting.settings.OptionSetting;
public class Capes extends Module {
public OptionSetting<Cape> cape = addSetting(new OptionSetting<>("capa", "qué capa llevar puesta",
public OptionSetting<Cape> cape = sgGeneral.add(new OptionSetting<>("capa", "qué capa llevar puesta",
CapeManager.INSTANCE.getCapes(), CapeManager.INSTANCE.getCape("hollow-knight")));
public Capes() {
@@ -2,31 +2,72 @@ package me.retucio.sputnik.module.modules.player;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import org.lwjgl.glfw.GLFW;
public class FastUse extends Module {
public BooleanSetting items = addSetting(new BooleanSetting("items", "usar items precozmente", true));
public NumberSetting itemCooldown = addSetting(new NumberSetting("cooldown de items", "cooldown para usar items en ticks", 0, 0, 4, 1));
public BooleanSetting items = sgGeneral.add(new BooleanSetting(
"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 = addSetting(new BooleanSetting("bloques", "colocar bloques precozmente", true));
public NumberSetting blockCooldown = addSetting(new NumberSetting("cooldown de bloques", "cooldown para colocar bloques en ticks", 0, 0, 4, 1));
public FastUse() {
super("precoz",
"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));
blocks.onUpdate(v -> blockCooldown.setVisible(v));
}
public int getCooldown(ItemStack stack) {
if (stack.getItem() instanceof BlockItem && blocks.isEnabled()) return blockCooldown.getIntValue();
if (items.isEnabled() && !(stack.getItem() instanceof BlockItem)) return itemCooldown.getIntValue();
if (stack.getItem() instanceof BlockItem && blocks.getValue()) return blockCooldown.getIntValue();
if (items.getValue() && !(stack.getItem() instanceof BlockItem)) return itemCooldown.getIntValue();
else return 4; // cooldown por defecto, 4 ticks
}
}
@@ -5,8 +5,9 @@ import me.retucio.sputnik.event.events.RenderHeldItemEvent;
import me.retucio.sputnik.event.events.RenderArmEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Hand;
import net.minecraft.util.math.RotationAxis;
@@ -18,75 +19,80 @@ import org.joml.Vector3d;
public class HandView extends Module {
SettingGroup sgAnimations = addSg(new SettingGroup("animaciones", false));
SettingGroup sgMainHand = addSg(new SettingGroup("mano principal", false));
SettingGroup sgOffhand = addSg(new SettingGroup("mano secundaria", false));
SettingGroup sgArm = addSg(new SettingGroup("brazo", false));
// ajustes de animaciones
public BooleanSetting oldAnimations = addSetting(new BooleanSetting("animaciones viejas", "como las de la 1.8, al pegar", false));
public BooleanSetting skipSwapping = addSetting(new BooleanSetting("no swap", "se salta la animación de cambiar items de mano", false));
public BooleanSetting noFood = addSetting(new BooleanSetting("no comer", "no renderiza la animación de comer", false));
public BooleanSetting oldAnimations = sgAnimations.add(new BooleanSetting("animaciones viejas", "como las de la 1.8, al pegar", false));
public BooleanSetting skipSwapping = sgAnimations.add(new BooleanSetting("no swap", "se salta la animación de cambiar items de mano", false));
public BooleanSetting noFood = sgAnimations.add(new BooleanSetting("no comer", "no renderiza la animación de comer", false));
// ajustes de mano principal
public NumberSetting scaleMainX = addSetting(new NumberSetting("escala de la mano principal (X)", ".",
public NumberSetting scaleMainX = sgMainHand.add(new NumberSetting("escala de la mano principal (X)", ".",
1, 0.01, 5, 0.1));
public NumberSetting scaleMainY = addSetting(new NumberSetting("escala de la mano principal (Y)", ".",
public NumberSetting scaleMainY = sgMainHand.add(new NumberSetting("escala de la mano principal (Y)", ".",
1, 0.01, 5, 0.1));
public NumberSetting scaleMainZ = addSetting(new NumberSetting("escala de la mano principal (Z)", ".",
public NumberSetting scaleMainZ = sgMainHand.add(new NumberSetting("escala de la mano principal (Z)", ".",
1, 0.01, 5, 0.1));
public NumberSetting posMainX = addSetting(new NumberSetting("posición de la mano principal (X)", ".",
public NumberSetting posMainX = sgMainHand.add(new NumberSetting("posición de la mano principal (X)", ".",
0, -3, 3, 0.1));
public NumberSetting posMainY = addSetting(new NumberSetting("posición de la mano principal (Y)", ".",
public NumberSetting posMainY = sgMainHand.add(new NumberSetting("posición de la mano principal (Y)", ".",
0, -3, 3, 0.1));
public NumberSetting posMainZ = addSetting(new NumberSetting("posición de la mano principal (Z)", ".",
public NumberSetting posMainZ = sgMainHand.add(new NumberSetting("posición de la mano principal (Z)", ".",
0, -3, 3, 0.1));
public NumberSetting rotMainX = addSetting(new NumberSetting("rotación de la mano principal (X)", ".",
public NumberSetting rotMainX = sgMainHand.add(new NumberSetting("rotación de la mano principal (X)", ".",
0, -180, 180, 1));
public NumberSetting rotMainY = addSetting(new NumberSetting("rotación de la mano principal (Y)", ".",
public NumberSetting rotMainY = sgMainHand.add(new NumberSetting("rotación de la mano principal (Y)", ".",
0, -180, 180, 1));
public NumberSetting rotMainZ = addSetting(new NumberSetting("rotación de la mano principal (Z)", ".",
public NumberSetting rotMainZ = sgMainHand.add(new NumberSetting("rotación de la mano principal (Z)", ".",
0, -180, 180, 1));
// ajustes de mano secundaria
public NumberSetting scaleOffX = addSetting(new NumberSetting("escala de la mano secundaria (X)", ".",
public NumberSetting scaleOffX = sgOffhand.add(new NumberSetting("escala de la mano secundaria (X)", ".",
1, 0.01, 5, 0.1));
public NumberSetting scaleOffY = addSetting(new NumberSetting("escala de la mano secundaria (Y)", ".",
public NumberSetting scaleOffY = sgOffhand.add(new NumberSetting("escala de la mano secundaria (Y)", ".",
1, 0.01, 5, 0.1));
public NumberSetting scaleOffZ = addSetting(new NumberSetting("escala de la mano secundaria (Z)", ".",
public NumberSetting scaleOffZ = sgOffhand.add(new NumberSetting("escala de la mano secundaria (Z)", ".",
1, 0.01, 5, 0.1));
public NumberSetting posOffX = addSetting(new NumberSetting("posición de la mano secundaria (X)", ".",
public NumberSetting posOffX = sgOffhand.add(new NumberSetting("posición de la mano secundaria (X)", ".",
0, -3, 3, 0.1));
public NumberSetting posOffY = addSetting(new NumberSetting("posición de la mano secundaria (Y)", ".",
public NumberSetting posOffY = sgOffhand.add(new NumberSetting("posición de la mano secundaria (Y)", ".",
0, -3, 3, 0.1));
public NumberSetting posOffZ = addSetting(new NumberSetting("posición de la mano secundaria (Z)", ".",
public NumberSetting posOffZ = sgOffhand.add(new NumberSetting("posición de la mano secundaria (Z)", ".",
0, -3, 3, 0.1));
public NumberSetting rotOffX = addSetting(new NumberSetting("rotación de la mano secundaria (X)", ".",
public NumberSetting rotOffX = sgOffhand.add(new NumberSetting("rotación de la mano secundaria (X)", ".",
0, -180, 180, 1));
public NumberSetting rotOffY = addSetting(new NumberSetting("rotación de la mano secundaria (Y)", ".",
public NumberSetting rotOffY = sgOffhand.add(new NumberSetting("rotación de la mano secundaria (Y)", ".",
0, -180, 180, 1));
public NumberSetting rotOffZ = addSetting(new NumberSetting("rotación de la mano secundaria (Z)", ".",
public NumberSetting rotOffZ = sgOffhand.add(new NumberSetting("rotación de la mano secundaria (Z)", ".",
0, -180, 180, 1));
// brazo
public NumberSetting scaleArmX = addSetting(new NumberSetting("escala del brazo (X)", ".",
public NumberSetting scaleArmX = sgArm.add(new NumberSetting("escala del brazo (X)", ".",
1, 0.01, 5, 0.1));
public NumberSetting scaleArmY = addSetting(new NumberSetting("escala del brazo (Y)", ".",
public NumberSetting scaleArmY = sgArm.add(new NumberSetting("escala del brazo (Y)", ".",
1, 0.01, 5, 0.1));
public NumberSetting scaleArmZ = addSetting(new NumberSetting("escala del brazo (Z)", ".",
public NumberSetting scaleArmZ = sgArm.add(new NumberSetting("escala del brazo (Z)", ".",
1, 0.01, 5, 0.1));
public NumberSetting posArmX = addSetting(new NumberSetting("posición del brazo (X)", ".",
public NumberSetting posArmX = sgArm.add(new NumberSetting("posición del brazo (X)", ".",
0, -3, 3, 0.1));
public NumberSetting posArmY = addSetting(new NumberSetting("posición del brazo (Y)", ".",
public NumberSetting posArmY = sgArm.add(new NumberSetting("posición del brazo (Y)", ".",
0, -3, 3, 0.1));
public NumberSetting posArmZ = addSetting(new NumberSetting("posición del brazo (Z)", ".",
public NumberSetting posArmZ = sgArm.add(new NumberSetting("posición del brazo (Z)", ".",
0, -3, 3, 0.1));
public NumberSetting rotArmX = addSetting(new NumberSetting("rotación del brazo (X)", ".",
public NumberSetting rotArmX = sgArm.add(new NumberSetting("rotación del brazo (X)", ".",
0, -180, 180, 1));
public NumberSetting rotArmY = addSetting(new NumberSetting("rotación del brazo (Y)", ".",
public NumberSetting rotArmY = sgArm.add(new NumberSetting("rotación del brazo (Y)", ".",
0, -180, 180, 1));
public NumberSetting rotArmZ = addSetting(new NumberSetting("rotación del brazo (Z)", ".",
public NumberSetting rotArmZ = sgArm.add(new NumberSetting("rotación del brazo (Z)", ".",
0, -180, 180, 1));
public HandView() {
@@ -2,11 +2,11 @@ package me.retucio.sputnik.module.modules.player;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
public class Headhitters extends Module {
public NumberSetting delay = addSetting(new NumberSetting("delay", "delay de saltos", 0, 0, 20, 1));
public NumberSetting delay = sgGeneral.add(new NumberSetting("delay", "delay de saltos", 0, 0, 20, 1));
public Headhitters() {
super("headhitters",
@@ -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;
}
}
@@ -7,7 +7,7 @@ import me.retucio.sputnik.event.events.MouseClickEvent;
import me.retucio.sputnik.mixin.accessor.HandledScreenAccessor;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.KeySetting;
import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.util.InventoryUtil;
import me.retucio.sputnik.util.KeyUtil;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
@@ -16,9 +16,9 @@ import org.lwjgl.glfw.GLFW;
public class InventoryPlus extends Module {
public KeySetting row1key = addSetting(new KeySetting("fila 1", "tecla para mover items a la primera fila", GLFW.GLFW_KEY_A));
public KeySetting row2key = addSetting(new KeySetting("fila 2", "tecla para mover items a la segunda fila", GLFW.GLFW_KEY_S));
public KeySetting row3key = addSetting(new KeySetting("fila 3", "tecla para mover items a la tercera fila", GLFW.GLFW_KEY_D));
public KeySetting row1key = sgGeneral.add(new KeySetting("fila 1", "tecla para mover items a la primera fila", GLFW.GLFW_KEY_A));
public KeySetting row2key = sgGeneral.add(new KeySetting("fila 2", "tecla para mover items a la segunda fila", GLFW.GLFW_KEY_S));
public KeySetting row3key = sgGeneral.add(new KeySetting("fila 3", "tecla para mover items a la tercera fila", GLFW.GLFW_KEY_D));
public InventoryPlus() {
super("inventario plus",
@@ -50,15 +50,15 @@ public class InventoryPlus extends Module {
int rowOffset = InventoryUtil.getRowOffset(screen);
if (KeyUtil.isKeyDown(row1key.getKey())) {
if (KeyUtil.isKeyDown(row1key.getValue())) {
event.cancel();
swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset);
}
else if (KeyUtil.isKeyDown(row2key.getKey())) {
else if (KeyUtil.isKeyDown(row2key.getValue())) {
event.cancel();
swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset + 9);
}
else if (KeyUtil.isKeyDown(row3key.getKey())) {
else if (KeyUtil.isKeyDown(row3key.getValue())) {
event.cancel();
swapWithRow(screen, containerSlot, hotbarKeyIndex, rowOffset + 18);
}
@@ -2,9 +2,9 @@ package me.retucio.sputnik.module.modules.player;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.settings.OptionSetting;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.OptionSetting;
import me.retucio.sputnik.util.Lists;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
@@ -16,10 +16,10 @@ import net.minecraft.util.math.Direction;
public class Offhand extends Module {
public OptionSetting<Item> item = addSetting(new OptionSetting<>("ítem", "ítem a equipar",
public OptionSetting<Item> item = sgGeneral.add(new OptionSetting<>("ítem", "ítem a equipar",
Lists.itemList, Items.TOTEM_OF_UNDYING, Lists.itemNames));
public NumberSetting delaySetting = addSetting(new NumberSetting("delay", "delay del cambiazo (en ticks)", 0, 0, 20, 1));
public BooleanSetting override = addSetting(new BooleanSetting("anular", "ignora que ya haya un ítem en la mano secundaria", true));
public NumberSetting delaySetting = sgGeneral.add(new NumberSetting("delay", "delay del cambiazo (en ticks)", 0, 0, 20, 1));
public BooleanSetting override = sgGeneral.add(new BooleanSetting("anular", "ignora que ya haya un ítem en la mano secundaria", true));
private int delay;
@@ -46,7 +46,7 @@ public class Offhand extends Module {
}
if (holdingItem || (!mc.player.getOffHandStack().isEmpty()
&& !override.isEnabled()))
&& !override.getValue()))
return;
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;
}
}
@@ -4,7 +4,7 @@ import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.ClipAtLedgeEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Vec3d;
@@ -13,7 +13,7 @@ import net.minecraft.world.RaycastContext;
public class SafeWalk extends Module {
public NumberSetting fallDistance = addSetting(new NumberSetting("distancia de caída", "distancia de caída máxima permitida", 1, 0, 10, 0.1));
public NumberSetting fallDistance = sgGeneral.add(new NumberSetting("distancia de caída", "distancia de caída máxima permitida", 1, 0, 10, 0.1));
public SafeWalk() {
super("muletas",
@@ -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);
}
}
@@ -3,7 +3,7 @@ package me.retucio.sputnik.module.modules.player;
import me.retucio.sputnik.mixin.accessor.KeyBindingAccessor;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.ListSetting;
import me.retucio.sputnik.module.setting.settings.ListSetting;
import me.retucio.sputnik.ui.screen.ClickGUI;
import me.retucio.sputnik.util.KeyUtil;
import me.retucio.sputnik.util.Lists;
@@ -19,7 +19,7 @@ import java.util.List;
public class UIMove extends Module {
public ListSetting<ScreenHandlerType<?>> screens = addSetting(new ListSetting<>("interfaces", "interfaces en las que te podrás mover",
public ListSetting<ScreenHandlerType<?>> screens = sgGeneral.add(new ListSetting<>("interfaces", "interfaces en las que te podrás mover",
Lists.screenList, Lists.allTrue(Lists.screenList), Lists.screenNames));
private List<KeyBinding> movementKeys;
@@ -2,9 +2,10 @@ package me.retucio.sputnik.module.modules.player;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.settings.OptionSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.module.setting.settings.OptionSetting;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.Lists;
import net.minecraft.item.ItemStack;
@@ -21,16 +22,19 @@ import java.util.List;
public class WarnLowDurability extends Module {
public NumberSetting limitPercentage = addSetting(new NumberSetting("porcentaje", "porcentaje de durabilidad restante a la que se te avisa",
SettingGroup sgWarn = addSg(new SettingGroup("aviso", true));
SettingGroup sgSound = addSg(new SettingGroup("sonido", true));
public NumberSetting limitPercentage = sgGeneral.add(new NumberSetting("porcentaje", "porcentaje de durabilidad restante a la que se te avisa",
5, 1, 100, 1));
public BooleanSetting message = addSetting(new BooleanSetting("enviar mensaje", "enviar un mensaje para alertar al usuario", true));
public BooleanSetting message = sgWarn.add(new BooleanSetting("enviar mensaje", "enviar un mensaje para alertar al usuario", true));
public BooleanSetting playSound = sgWarn.add(new BooleanSetting("reproducir sonido", "reproducir un sonido para alertar al usuario", true));
public BooleanSetting playSound = addSetting(new BooleanSetting("reproducir sonido", "reproducir un sonido para alertar al usuario", true));
public OptionSetting<SoundEvent> sound = addSetting(new OptionSetting<>("sonido", "qué sonido reproducir",
public OptionSetting<SoundEvent> sound = sgSound.add(new OptionSetting<>("sonido", "qué sonido reproducir",
Lists.soundList, SoundEvents.BLOCK_NOTE_BLOCK_BELL.value(), Lists.soundNames));
public NumberSetting volume = addSetting(new NumberSetting("volumen", "volumen del sonido", 70, 0, 125, 1));
public NumberSetting pitch = addSetting(new NumberSetting("frecuencia", "altura del sonido", 70, 0, 125, 1));
public NumberSetting volume = sgSound.add(new NumberSetting("volumen", "volumen del sonido", 70, 0, 125, 1));
public NumberSetting pitch = sgSound.add(new NumberSetting("frecuencia", "altura del sonido", 70, 0, 125, 1));
private final List<ItemStack> warned = new ArrayList<>();
private float prevPercentage = -1;
@@ -56,7 +60,7 @@ public class WarnLowDurability extends Module {
float percentage = (1 - (float) stack.getDamage() / stack.getMaxDamage()) * 100;
if (percentage <= limitPercentage.getValue() && percentage < prevPercentage) {
if (playSound.isEnabled())
if (playSound.getValue())
mc.world.playSound(mc.player, mc.player.getBlockPos(),
sound.getValue(),
SoundCategory.AMBIENT,
@@ -64,7 +68,7 @@ public class WarnLowDurability extends Module {
toExponential(pitch)
);
if (message.isEnabled()) {
if (message.getValue()) {
String customName = stack.getCustomName() == null ? "" : " \"" + stack.getCustomName().getString() + "\"";
Text text = Text.literal(Formatting.AQUA + stack.getItemName().getString()
+ Formatting.GREEN + customName + Formatting.RESET
@@ -1,39 +1,109 @@
package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.RenderWorldEvent;
import me.retucio.sputnik.event.events.Render3DEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.ColorSetting;
import me.retucio.sputnik.module.settings.ListSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.ListSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.Colors;
import me.retucio.sputnik.util.Lists;
import me.retucio.sputnik.util.render.RenderUtil;
import net.minecraft.block.Block;
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 java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class BlockESP extends Module {
public ListSetting<Block> blocks = addSetting(new ListSetting<>("bloques", "bloques a resaltar",
Lists.blockList, Lists.allFalse(Lists.blockList), Lists.blockNames));
SettingGroup sgSearch = addSg(new SettingGroup("búsqueda", true));
SettingGroup sgOulines = addSg(new SettingGroup("contorno", true));
SettingGroup sgFilling = addSg(new SettingGroup("relleno", true));
public NumberSetting radius = addSetting(new NumberSetting("radio", "radio de búsqueda de bloques", 24, 2, 128, 1));
public BooleanSetting outlines = addSetting(new BooleanSetting("contorno", "renderizar contorno de bloques", true));
public ColorSetting outlineColor = addSetting(new ColorSetting("color del contorno", "color del contorno", Colors.CELESTE, false));
public NumberSetting lineWidth = addSetting(new NumberSetting("grosor del contorno", "grosor de las líneas del contorno", 1, 1, 5, 0.2));
// bloques
public BooleanSetting fillings = addSetting(new BooleanSetting("relleno", "renderizar relleno de bloques", true));
public ColorSetting fillingColor = addSetting(new ColorSetting("color del relleno", "color del relleno", new Color(57, 177, 215, 67), false));
public ListSetting<Block> blocks = sgGeneral.add(new ListSetting<>(
"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() {
@@ -41,61 +111,166 @@ public class BlockESP extends Module {
"te muestra la posición de cierto tipo de bloque renderizando una caja con su forma",
Category.RENDER);
blocks.onUpdate(v ->
updateEnabledBlocks()
);
outlines.onUpdate(v -> {
outlineColor.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
public void onRenderWorld(RenderWorldEvent event) {
public void onRenderWorld(Render3DEvent event) {
if (mc.player == null || mc.world == null) return;
for (Block block : blocks.getOptions()) {
if (blocks.isEnabled(block)) {
List<BlockPos> blocksToHighlight = getNearbyBlocks(block);
for (BlockPos pos : blocksToHighlight) {
if (outlines.isEnabled()) {
RenderUtil.drawVoxelShapeOutline(
event.getMatrices(),
getVoxelShape(pos),
pos,
outlineColor.getColor(),
lineWidth.getFloatValue(),
false);
}
if (fillings.isEnabled()) {
RenderUtil.drawVoxelShapeFilled(
event.getMatrices(),
getVoxelShape(pos),
pos,
fillingColor.getColor(),
false);
// aplicar el intervalo
if (searchTimer++ >= searchInterval.getIntValue()) {
searchTimer = 0;
searchBlocks();
}
Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
int rendered = 0;
Iterator<Map.Entry<BlockPos, VoxelShape>> iterator = cachedBlocks.entrySet().iterator();
while (iterator.hasNext() && rendered < maxBlocks.getIntValue()) {
Map.Entry<BlockPos, VoxelShape> entry = iterator.next();
BlockPos pos = entry.getKey();
VoxelShape shape = entry.getValue();
if (!isValidBlock(pos)) {
iterator.remove();
continue;
}
// 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) {
List<BlockPos> blockPosList = new ArrayList<>();
for (int i = -radius.getIntValue(); i < radius.getIntValue(); i++) {
for (int j = -radius.getIntValue(); j < radius.getIntValue(); j++) {
for (int k = -radius.getIntValue(); k < radius.getIntValue(); k++) {
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);
// verificar que el bloque sea válido
@SuppressWarnings("deprecation")
private boolean isValidBlock(BlockPos pos) {
if (mc.world == null || !mc.world.isChunkLoaded(pos)) return false;
Block block = mc.world.getBlockState(pos).getBlock();
return enabledBlocks.contains(block);
}
}
@@ -2,7 +2,9 @@ package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.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.*;
@@ -12,8 +14,21 @@ import java.awt.*;
public class BlockOutline extends Module {
public ColorSetting color = addSetting(new ColorSetting("color", "color del contorno de los bloques",
new Color(0, 0, 0, 102), true));
public ColorSetting color = sgGeneral.add(new ColorSetting(
"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() {
super("contorno",
@@ -1,13 +1,14 @@
package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.RenderWorldEvent;
import me.retucio.sputnik.event.events.Render3DEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.ColorSetting;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.render.RenderUtil;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
@@ -18,18 +19,22 @@ import java.awt.*;
public class BreakingProgress extends Module {
public EnumSetting<BreakMode> breakMode = addSetting(new EnumSetting<>("modo de minado", "elige si el cubo se encoge o se dilata",
SettingGroup sgOulines = addSg(new SettingGroup("contorno", true));
SettingGroup sgFilling = addSg(new SettingGroup("relleno", true));
public EnumSetting<BreakMode> breakMode = sgGeneral.add(new EnumSetting<>("modo de minado", "elige si el cubo se encoge o se dilata",
BreakMode.class, BreakMode.INWARDS));
public BooleanSetting outlines = addSetting(new BooleanSetting("contorno", "renderizar contorno", true));
public ColorSetting outlineColor = addSetting(new ColorSetting("color del contorno", "color del contorno",
public BooleanSetting outlines = sgOulines.add(new BooleanSetting("contorno", "renderizar contorno", true));
public ColorSetting outlineColor = sgOulines.add(new ColorSetting("color del contorno", "color del contorno",
new Color(0, 255, 0, 200), false));
public NumberSetting lineWidth = addSetting(new NumberSetting("grosor de línea", "grosor de las líneas del contorno", 1, 1, 5, 0.1));
public NumberSetting lineWidth = sgOulines.add(new NumberSetting("grosor de línea", "grosor de las líneas del contorno", 1, 1, 5, 0.1));
public BooleanSetting fillings = addSetting(new BooleanSetting("relleno", "renderizar relleno", true));
public ColorSetting fillingColor = addSetting(new ColorSetting("color del relleno", "color del relleno",
public BooleanSetting fillings = sgFilling.add(new BooleanSetting("relleno", "renderizar relleno", true));
public ColorSetting fillingColor = sgFilling.add(new ColorSetting("color del relleno", "color del relleno",
new Color(0, 255, 0, 60), false));
public BreakingProgress() {
super("progreso de minado",
"te muestra el progreso de minado de un bloque de manera más visible",
@@ -37,7 +42,7 @@ public class BreakingProgress extends Module {
}
@SubscribeEvent
public void onRenderWorld(RenderWorldEvent event) {
public void onRenderWorld(Render3DEvent event) {
if (mc.interactionManager == null || mc.world == null) return;
if (!(mc.crosshairTarget instanceof BlockHitResult hitResult)) return;
BlockPos pos = hitResult.getBlockPos();
@@ -68,8 +73,8 @@ public class BreakingProgress extends Module {
centerX + shrunkX, centerY + shrunkZ, centerZ + shrunkZ
);
if (outlines.isEnabled()) RenderUtil.drawOutlineBox(event.getMatrices(), scaledBox, outlineColor.getColor(), lineWidth.getFloatValue(), false);
if (fillings.isEnabled()) RenderUtil.drawFilledBox(event.getMatrices(), scaledBox, fillingColor.getColor(), false);
if (outlines.getValue()) RenderUtil.drawOutlineBox(event.getMatrices(), scaledBox, outlineColor.getValue(), lineWidth.getFloatValue(), false);
if (fillings.getValue()) RenderUtil.drawFilledBox(event.getMatrices(), scaledBox, fillingColor.getValue(), false);
}
public enum BreakMode {
@@ -2,9 +2,11 @@ package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.ColorSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
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.*;
@@ -15,14 +17,17 @@ import java.awt.*;
public class CritsPlus extends Module {
public ColorSetting color = addSetting(new ColorSetting("color", "color de las partículas", new Color(0, 0, 255, 255), false));
SettingGroup sgAppearance = addSg(new SettingGroup("aspecto", true));
SettingGroup sgBehaviour = addSg(new SettingGroup("funcionamiento", true));
public NumberSetting scale = addSetting(new NumberSetting("escala", "tamaño", 1, 0, 2, 0.05));
public NumberSetting multiplier = addSetting(new NumberSetting("múltiplo", "número por el que multiplicar la cantidad de partículas generadas", 1, 0, 10, 0.1));
public NumberSetting velocityMultipler = addSetting(new NumberSetting("dispersión", "multiplicador de la velocidad de dispersión", 1, 0, 10, 0.1));
public NumberSetting gravity = addSetting(new NumberSetting("gravedad", "multiplicador de fuerza de gravedad", 1, 0, 10, 0.1));
public NumberSetting maxAge = addSetting(new NumberSetting("vida máxima", "cuánto persiste la partícula", 10, 0, 50, 1));
public BooleanSetting collide = addSetting(new BooleanSetting("colisionar", "colisionar con bloques", 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 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 velocityMultipler = sgBehaviour.add(new NumberSetting("dispersión", "multiplicador de la velocidad de dispersión", 1, 0, 10, 0.1));
public NumberSetting gravity = sgBehaviour.add(new NumberSetting("gravedad", "multiplicador de fuerza de gravedad", 1, 0, 10, 0.1));
public NumberSetting maxAge = sgBehaviour.add(new NumberSetting("vida máxima", "cuánto persiste la partícula", 10, 0, 50, 1));
public BooleanSetting collide = sgBehaviour.add(new BooleanSetting("colisionar", "colisionar con bloques", false));
public CritsPlus() {
super("críticos",
@@ -3,8 +3,9 @@ package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.mixin.accessor.OverlayTextureAccessor;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.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.NativeImageBackedTexture;
@@ -16,7 +17,12 @@ import java.awt.*;
public class DamageOverlay extends Module {
public ColorSetting colorSetting = addSetting(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;
@@ -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();
}
}
}
@@ -2,8 +2,8 @@ package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.util.render.GlintRenderLayer;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderLayers;
@@ -17,9 +17,24 @@ import net.minecraft.util.DyeColor;
public class GlintPlus extends Module {
public BooleanSetting items = addSetting(new BooleanSetting("items", "modificar el destello de encantamiento de los items", true));
public BooleanSetting armor = addSetting(new BooleanSetting("armadura", "modificar el destello de encantamiento de la armadura", true));
public EnumSetting<GlintColors> glintColor = addSetting(new EnumSetting<>("colores", "color del glint", GlintColors.class, GlintColors.PURPLE));
public BooleanSetting items = sgGeneral.add(new BooleanSetting(
"items",
"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() {
super("destello de enchants.",
@@ -29,19 +44,19 @@ public class GlintPlus extends Module {
public RenderLayer getGlint() {
int color = getColor();
if (!isEnabled() || !items.isEnabled()) return RenderLayers.glint();
if (!isEnabled() || !items.getValue()) return RenderLayers.glint();
return GlintRenderLayer.glintColor.get(color);
}
public RenderLayer getEntityGlint() {
int color = getColor();
if (!isEnabled() || !items.isEnabled()) return RenderLayers.entityGlint();
if (!isEnabled() || !items.getValue()) return RenderLayers.entityGlint();
return GlintRenderLayer.entityGlintColor.get(color);
}
public RenderLayer getArmorEntityGlint() {
int color = getColor();
if (!isEnabled() || !armor.isEnabled()) return RenderLayers.armorEntityGlint();
if (!isEnabled() || !armor.getValue()) return RenderLayers.armorEntityGlint();
return GlintRenderLayer.armorEntityGlintColor.get(color);
}
@@ -4,9 +4,10 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.settings.ListSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.ListSetting;
import me.retucio.sputnik.util.Lists;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EntityType;
@@ -38,22 +39,25 @@ import java.util.concurrent.Executors;
public class Nametags extends Module {
SettingGroup sgInfo = addSg(new SettingGroup("info. adicional", true));
Map<EntityType<?>, Boolean> defaultEntities = Lists.allFalse(Lists.entityList);
public ListSetting<EntityType<?>> entities = addSetting(new ListSetting<>("entidades", "entidades cuyo nametag será visible",
public ListSetting<EntityType<?>> entities = sgGeneral.add(new ListSetting<>("entidades", "entidades cuyo nametag será visible",
Lists.entityList, defaultEntities, Lists.entityNames));
public BooleanSetting alwaysVisible = addSetting(new BooleanSetting("siempre mostrar nametags", "mostrar nametag cuando el jugador está agachado o es invisible", false));
public BooleanSetting health = addSetting(new BooleanSetting("mostrar vida", "muestra la vida de una entidad en su nametag", true));
public EnumSetting<HealthMode> healthMode = addSetting(new EnumSetting<>("mostrar vida en", "de qué manera mostrar la vida", HealthMode.class, HealthMode.POINTS));
public BooleanSetting countItems = addSetting(new BooleanSetting("contar items", "muestra cuánto de un item hay en un stack dropeado", true));
public ListSetting<Item> items = addSetting(new ListSetting<>("items", "te permite elegir cuáles items tienen su nombre visible",
public ListSetting<Item> items = sgGeneral.add(new ListSetting<>("items", "te permite elegir cuáles items tienen su nombre visible",
Lists.itemList, Lists.allTrue(Lists.itemList), Lists.itemNames));
public BooleanSetting showProjectileDamage = addSetting(new BooleanSetting("daño del proyectil", "muestra cuánto daño hace un proyectil en su nametag", true));
public BooleanSetting showSelf = addSetting(new BooleanSetting("mostrar propio", "mostrar nametag propio", false));
public BooleanSetting distinguishBabies = addSetting(new BooleanSetting("distinguir bebés", "cambia el nametag cuando una entidad está en su fase bebé", false));
public BooleanSetting petOwner = addSetting(new BooleanSetting("mostrar dueño", "muestra el dueño de una mascota (no funciona en servers no premium)", false));
public BooleanSetting health = sgGeneral.add(new BooleanSetting("mostrar vida", "muestra la vida de una entidad en su nametag", true));
public EnumSetting<HealthMode> healthMode = sgGeneral.add(new EnumSetting<>("mostrar vida en", "de qué manera mostrar la vida", HealthMode.class, HealthMode.POINTS));
public BooleanSetting alwaysVisible = sgGeneral.add(new BooleanSetting("siempre mostrar nametags", "mostrar nametag cuando el jugador está agachado o es invisible", false));
public BooleanSetting showSelf = sgGeneral.add(new BooleanSetting("mostrar propio", "mostrar nametag propio", false));
public BooleanSetting countItems = sgInfo.add(new BooleanSetting("contar items", "muestra cuánto de un item hay en un stack dropeado", true));
public BooleanSetting showProjectileDamage = sgInfo.add(new BooleanSetting("daño del proyectil", "muestra cuánto daño hace un proyectil en su nametag", true));
public BooleanSetting distinguishBabies = sgInfo.add(new BooleanSetting("distinguir bebés", "cambia el nametag cuando una entidad está en su fase bebé", false));
public BooleanSetting petOwner = sgInfo.add(new BooleanSetting("mostrar dueño", "muestra el dueño de una mascota (no funciona en servers no premium)", false));
private final Map<UUID, String> cache = new ConcurrentHashMap<>();
private static final ExecutorService executor = Executors.newCachedThreadPool();
@@ -69,7 +73,7 @@ public class Nametags extends Module {
defaultEntities.replace(EntityType.ARROW, true);
defaultEntities.replace(EntityType.SPECTRAL_ARROW, true);
defaultEntities.replace(EntityType.TRIDENT, true);
entities.setDefaultValues(defaultEntities);
entities.setDefaultValue(defaultEntities);
health.onUpdate(v -> healthMode.setVisible(v));
@@ -2,9 +2,10 @@ package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.settings.ListSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.ListSetting;
import me.retucio.sputnik.util.Lists;
import net.minecraft.particle.ParticleType;
import net.minecraft.util.Formatting;
@@ -24,35 +25,41 @@ import net.minecraft.util.Formatting;
public class NoRender extends Module {
public BooleanSetting spyglassOverlay = addSetting(new BooleanSetting("catalejo", "renderizar overlay del catalejo", false));
public BooleanSetting fluidOverlay = addSetting(new BooleanSetting("fluídos", "renderizar fluídos sobre la cámara como el agua, lava o nieve en polvo (aunque no sea un fluído)", false));
public BooleanSetting pumpkinOverlay = addSetting(new BooleanSetting("calabaza", "renderiza el overlay de la calabaza tallada", false));
public BooleanSetting fireOverlay = addSetting(new BooleanSetting("fuego", "renderizar llamas sobre la cámara", false));
public BooleanSetting portalOverlay = addSetting(new BooleanSetting("portal", "renderizar el overlay del portal del nether", false));
SettingGroup sgOverlays = addSg(new SettingGroup("overlays", true));
SettingGroup sgAmbient = addSg(new SettingGroup("ambiente", true));
SettingGroup sgEffects = addSg(new SettingGroup("efectos", true));
SettingGroup sgUi = addSg(new SettingGroup("interfaz", true));
SettingGroup sgText = addSg(new SettingGroup("texto", true));
SettingGroup sgMisc = addSg(new SettingGroup("misc.", true));
public BooleanSetting rain = addSetting(new BooleanSetting("lluvia", "l l u v i a", true));
public BooleanSetting snow = addSetting(new BooleanSetting("nieve", "n i e v e", true));
public BooleanSetting endFlashes = addSetting(new BooleanSetting("flashes del end", "renderizar los recientemente añadidos flashes en el end", true));
public BooleanSetting spyglassOverlay = sgOverlays.add(new BooleanSetting("catalejo", "renderizar overlay del catalejo", false));
public BooleanSetting fluidOverlay = sgOverlays.add(new BooleanSetting("fluídos", "renderizar fluídos sobre la cámara como el agua, lava o nieve en polvo (aunque no sea un fluído)", false));
public BooleanSetting pumpkinOverlay = sgOverlays.add(new BooleanSetting("calabaza", "renderiza el overlay de la calabaza tallada", false));
public BooleanSetting fireOverlay = sgOverlays.add(new BooleanSetting("fuego", "renderizar llamas sobre la cámara", false));
public BooleanSetting portalOverlay = sgOverlays.add(new BooleanSetting("portal", "renderizar el overlay del portal del nether", false));
public ListSetting<ParticleType<?>> particles = addSetting(new ListSetting<>("partículas", "lista de partículas que se renderizan",
public BooleanSetting rain = sgAmbient.add(new BooleanSetting("lluvia", "l l u v i a", true));
public BooleanSetting snow = sgAmbient.add(new BooleanSetting("nieve", "n i e v e", true));
public BooleanSetting endFlashes = sgAmbient.add(new BooleanSetting("flashes del end", "renderizar los recientemente añadidos flashes en el end", true));
public ListSetting<ParticleType<?>> particles = sgAmbient.add(new ListSetting<>("partículas", "lista de partículas que se renderizan",
Lists.particleList, Lists.allTrue(Lists.particleList), Lists.particleNames));
public BooleanSetting nauseaEffect = addSetting(new BooleanSetting("náusea", "renderizar borrachera", false));
public BooleanSetting blindnessEffect = addSetting(new BooleanSetting("ceguera", "renderizar miopía", false));
public BooleanSetting darknessEffect = addSetting(new BooleanSetting("oscuridad", "renderizar miedo a la oscuridad", false));
public BooleanSetting nauseaEffect = sgEffects.add(new BooleanSetting("náusea", "renderizar borrachera", false));
public BooleanSetting blindnessEffect = sgEffects.add(new BooleanSetting("ceguera", "renderizar miopía", false));
public BooleanSetting darknessEffect = sgEffects.add(new BooleanSetting("oscuridad", "renderizar miedo a la oscuridad", false));
public BooleanSetting scoreboard = addSetting(new BooleanSetting("marcador", "mostrar marcador a la derecha", false));
public BooleanSetting titles = addSetting(new BooleanSetting("títulos", "mostrar títulos (del comando /title)", false));
public BooleanSetting totemPop = addSetting(new BooleanSetting("tótem", "renderizar el pop del tótem", true));
public BooleanSetting scoreboard = sgUi.add(new BooleanSetting("marcador", "mostrar marcador a la derecha", false));
public BooleanSetting titles = sgUi.add(new BooleanSetting("títulos", "mostrar títulos (del comando /title)", false));
public BooleanSetting totemPop = sgUi.add(new BooleanSetting("tótem", "renderizar el pop del tótem", true));
public BooleanSetting stuckArrows = addSetting(new BooleanSetting("flechas clavadas", "renderizar flechas clavadas en jugadores", false));
public BooleanSetting bold = addSetting(new BooleanSetting("negrita", "letra pero §lgorda", true));
public BooleanSetting bold = sgText.add(new BooleanSetting("negrita", "letra pero §lgorda", true));
// public BooleanSetting italics = addSetting(new BooleanSetting("cursiva", "letra pero §otorcida", true));
public BooleanSetting underlined = addSetting(new BooleanSetting("subrayado", "letra pero §nen el suelo", true));
public BooleanSetting strikethrough = addSetting(new BooleanSetting("tachado", "letra pero §mdiscriminada", true));
public EnumSetting<Colors> color = addSetting(new EnumSetting<>("colores", "§co§4r§6g§eu§al§2l§9o §1g§5a§dy", Colors.class, Colors.DEFAULT));
public BooleanSetting scrambledText = addSetting(new BooleanSetting("garabato", "engarabatar texto (o como se diga) (§kasí§r)", false));
public BooleanSetting underlined = sgText.add(new BooleanSetting("subrayado", "letra pero §nen el suelo", true));
public BooleanSetting strikethrough = sgText.add(new BooleanSetting("tachado", "letra pero §mdiscriminada", true));
public EnumSetting<Colors> color = sgText.add(new EnumSetting<>("colores", "§co§4r§6g§eu§al§2l§9o §1g§5a§dy", Colors.class, Colors.DEFAULT));
public BooleanSetting scrambledText = sgText.add(new BooleanSetting("garabato", "engarabatar texto (o como se diga) (§kasí§r)", false));
public BooleanSetting stuckArrows = sgMisc.add(new BooleanSetting("flechas clavadas", "renderizar flechas clavadas en jugadores", false));
public NoRender() {
super("no render",
@@ -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
);
}
}
@@ -4,12 +4,12 @@ import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.PacketEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.StringSetting;
import me.retucio.sputnik.module.setting.settings.StringSetting;
import net.minecraft.network.packet.c2s.play.UpdateSignC2SPacket;
public class ColoredSigns extends Module {
public StringSetting symbol = addSetting(new StringSetting("símbolo", "símbolo a reemplazar por \"§\"", "&", 5));
public StringSetting symbol = sgGeneral.add(new StringSetting("símbolo", "símbolo a reemplazar por \"§\"", "&", 5));
public ColoredSigns() {
super("carteles gays",
@@ -1,142 +1,359 @@
package me.retucio.sputnik.module.modules.world;
import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.RenderWorldEvent;
import me.retucio.sputnik.event.events.Render3DEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.ColorSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.render.RenderUtil;
import net.minecraft.block.*;
import net.minecraft.block.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.Heightmap;
import net.minecraft.world.LightType;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class LightOverlay extends Module {
public NumberSetting radius = addSetting(new NumberSetting("radio", "radio a tener en cuenta al renderizar superposición",
SettingGroup sgDetection = addSg(new SettingGroup("detección", true));
SettingGroup sgColors = addSg(new SettingGroup("colores", true));
SettingGroup sgOptimization = addSg(new SettingGroup("optimización", true));
// detección
public NumberSetting radius = sgDetection.add(new NumberSetting(
"radio",
"radio a tener en cuenta al renderizar superposición",
16, 5, 128, 1));
public NumberSetting yRadius = addSetting(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));
public NumberSetting interval = addSetting(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));
public ColorSetting lightColor = addSetting(new ColorSetting("color de la luz", "color de los bloques con luz",
public NumberSetting movementThreshold = sgOptimization.add(new NumberSetting(
"umbral de movimiento",
"distancia que debe moverse el jugador antes de forzar una actualización",
3.0, 0.5, 10.0, 0.5));
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));
public ColorSetting darknessColor = addSetting(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));
public BooleanSetting onWater = addSetting(new BooleanSetting("en agua", "mostrar también bloques cubiertos en agua", true));
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() {
super("superposición de luz",
"te muestra el nivel de luz en bloques, para prevenir mob spawns",
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
public void onRenderWorld(RenderWorldEvent event) {
@SuppressWarnings("deprecation")
public void onRenderWorld(Render3DEvent event) {
if (mc.player == null || mc.world == null) return;
if (mc.player.age % interval.getIntValue() == 0) {
blocks = findExposedBlocks(
radius.getIntValue(),
yRadius.getIntValue()
);
// actualización periódica
if (updateTimer++ >= updateInterval.getIntValue()) {
updateTimer = 0;
updateBlocks();
}
for (BlockPos block : blocks) {
if (mc.world.getBlockState(block).isAir() || !canSpawnOn(block)) continue;
if (!mc.world.getBlockState(block).isOpaque()) continue;
// renderizado
Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
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());
Color color = light == 0 ? darknessColor.getColor()
: new Color(
(lightColor.getR() / 15) * light,
(lightColor.getG() / 15) * light,
(lightColor.getB() / 15) * light,
lightColor.getA());
// color
Color color;
if (light == 0) {
color = darknessColor.getValue();
} else {
float ratio = light / 15.0f;
color = new Color(
(int)(lightColor.getR() * ratio),
(int)(lightColor.getG() * ratio),
(int)(lightColor.getB() * ratio),
lightColor.getA()
);
}
RenderUtil.drawBlockFaceFilled(event.getMatrices(), block, Direction.UP, color, 0.001f, true);
// renderizar
boolean shouldCull = !(onWater.getValue() && aboveState.isOf(Blocks.WATER) && dontCullWater.getValue());
RenderUtil.drawBlockFaceFilled(event.getMatrices(), block, Direction.UP, color, 0.001f, shouldCull);
}
}
private List<BlockPos> findExposedBlocks(int radius, int yRadius) {
List<BlockPos> results = new ArrayList<>();
private void updateBlocks() {
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;
int maxX = pos.getX() + radius;
int minY = Math.max(mc.world.getDimension().minY(), pos.getY() - yRadius);
int maxY = Math.min(mc.world.getDimension().height() - 1, pos.getY() + yRadius);
int minZ = pos.getZ() - radius;
int maxZ = pos.getZ() + radius;
// verificar si hace falta actualizar
boolean needsUpdate = fullRescanNeeded ||
lastRadius != currentRadius ||
lastYRadius != currentYRadius ||
(lastPlayerPos != null &&
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++) {
BlockPos current = new BlockPos(x, y, z);
BlockPos pos = center.add(x, y - center.getY(), z);
if (!mc.world.isAir(current) && canSpawnOn(current))
results.add(current);
// nuh uh si el chunk no está cargado
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) {
BlockState aboveState = mc.world.getBlockState(pos.up());
@SuppressWarnings("deprecation")
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();
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 (!aboveState.isOpaque() && !aboveState.isFullCube(mc.world, pos.up())) {
if (aboveBlock instanceof SlabBlock
|| aboveBlock instanceof StairsBlock
|| aboveBlock instanceof ButtonBlock
|| aboveBlock instanceof CarpetBlock
|| aboveBlock instanceof PressurePlateBlock
|| aboveBlock instanceof PaneBlock
|| aboveBlock instanceof TrapdoorBlock
|| aboveBlock instanceof FenceBlock
|| aboveBlock instanceof WallBlock
|| aboveBlock instanceof AnvilBlock
|| 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;
if (aboveBlock instanceof SlabBlock ||
aboveBlock instanceof StairsBlock ||
aboveBlock instanceof ButtonBlock ||
aboveBlock instanceof CarpetBlock ||
aboveBlock instanceof PressurePlateBlock ||
aboveBlock instanceof PaneBlock ||
aboveBlock instanceof TrapdoorBlock ||
aboveBlock instanceof FenceBlock ||
aboveBlock instanceof WallBlock ||
aboveBlock instanceof AnvilBlock ||
aboveBlock instanceof BedBlock) {
return false;
}
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());
}
}
}
@@ -2,8 +2,8 @@ package me.retucio.sputnik.module.modules.world;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.ListSetting;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.ListSetting;
import me.retucio.sputnik.util.Lists;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
@@ -11,8 +11,8 @@ import net.minecraft.registry.tag.ItemTags;
public class NoMiningInterruptions extends Module {
public BooleanSetting withPickaxeOnly = addSetting(new BooleanSetting("solo con pico", "ignorar entidades solamente cuando se sujeta un pico", false));
public ListSetting<EntityType<?>> entities = addSetting(new ListSetting<>("entidades", "entidades a ignorar",
public BooleanSetting withPickaxeOnly = sgGeneral.add(new BooleanSetting("solo con pico", "ignorar entidades solamente cuando se sujeta un pico", false));
public ListSetting<EntityType<?>> entities = sgGeneral.add(new ListSetting<>("entidades", "entidades a ignorar",
Lists.entityList, Lists.allTrue(Lists.entityList), Lists.entityNames));
public NoMiningInterruptions() {
@@ -25,7 +25,7 @@ public class NoMiningInterruptions extends Module {
if (entity == null || !isEnabled() || mc.player == null) return false;
boolean pickaxe = true;
if (withPickaxeOnly.isEnabled())
if (withPickaxeOnly.getValue())
pickaxe = (mc.player.getMainHandStack().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,24 @@ import me.retucio.sputnik.event.SubscribeEvent;
import me.retucio.sputnik.event.events.PacketEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.settings.BooleanSetting;
import me.retucio.sputnik.module.settings.EnumSetting;
import me.retucio.sputnik.module.settings.NumberSetting;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.EnumSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import net.minecraft.network.packet.s2c.play.WorldTimeUpdateS2CPacket;
// continúa en ClientWorldPropertiesMixin, DimensionTypeMixin,
public class TimeChanger extends Module {
public BooleanSetting renderSun = addSetting(new BooleanSetting("sol", "que haya sol o no", true));
public BooleanSetting renderMoon = addSetting(new BooleanSetting("luna", "que haya luna o no", true));
public BooleanSetting renderStars = addSetting(new BooleanSetting("estrellas", "que hayan estrellas o no", true));
SettingGroup sgCelestialBodies = addSg(new SettingGroup("cuerpos celeste", false));
public EnumSetting<MoonPhases> moonPhase = addSetting(new EnumSetting<>("fase lunar", "fase lunar actual", MoonPhases.class, MoonPhases.DEFAULT));
public NumberSetting time = addSetting(new NumberSetting("hora", "hora del juego", 0, -20000, 20000, 1));
public NumberSetting time = sgGeneral.add(new NumberSetting("hora", "hora del juego", 0, -20000, 20000, 1));
public BooleanSetting renderSun = sgCelestialBodies.add(new BooleanSetting("sol", "que haya sol o no", true));
public BooleanSetting renderMoon = sgCelestialBodies.add(new BooleanSetting("luna", "que haya luna o no", true));
public BooleanSetting renderStars = sgCelestialBodies.add(new BooleanSetting("estrellas", "que hayan estrellas o no", true));
public EnumSetting<MoonPhases> moonPhase = sgCelestialBodies.add(new EnumSetting<>("fase lunar", "fase lunar actual", MoonPhases.class, MoonPhases.DEFAULT));
public TimeChanger() {
super("cielo custom",
@@ -0,0 +1,106 @@
package me.retucio.sputnik.module.setting;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.events.sputnik.UpdateSettingEvent;
import me.retucio.sputnik.module.Module;
import java.util.function.Consumer;
// base para los tipos de ajustes
public abstract class Setting<T> {
protected final String name;
protected final String description;
protected T value;
protected T defaultValue;
protected Consumer<T> updateListener;
protected boolean visible = true;
protected boolean searchMatch = true;
protected SettingGroup sg;
protected Setting(String name, String description, T defaultValue) {
this.name = name;
this.description = description;
this.value = defaultValue;
this.defaultValue = defaultValue;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public boolean isSearchMatch() {
return searchMatch;
}
public void setSearchMatch(boolean searchMatch) {
this.searchMatch = searchMatch;
}
public String getName() {
return name;
}
public String getDescription() {
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() {
return sg;
}
public void setSg(SettingGroup sg) {
this.sg = sg;
}
public Module getModule() {
return this.sg.getModule();
}
public void fireUpdateEvent() {
Sputnik.EVENT_BUS.post(
new UpdateSettingEvent(this, getModule().shouldSaveSettings()));
}
public void onUpdate(Consumer<T> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(value); // actualizar por primera vez
}
}
@@ -0,0 +1,74 @@
package me.retucio.sputnik.module.setting;
import me.retucio.sputnik.module.Module;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class SettingGroup implements Iterable<Setting<?>> {
private Module module;
private final String name;
private boolean extended;
final List<Setting<?>> settings = new ArrayList<>(1);
public SettingGroup(String name, boolean extended) {
this.name = name;
this.extended = extended;
}
@Override
public @NotNull Iterator<Setting<?>> iterator() {
return settings.iterator();
}
public <S extends Setting<?>> S add(S setting) {
setting.setSg(this);
settings.add(setting);
return setting;
}
@SafeVarargs
public final <S extends Setting<?>> void addAll(S... ss) {
for (S s : ss) {
add(s);
}
}
public Setting<?> getSetting(String name) {
for (Setting<?> setting : this)
if (setting.getName().equals(name))
return setting;
return null;
}
public List<Setting<?>> getSettings() {
return settings;
}
public String getName() {
return name;
}
public boolean isExtended() {
return extended;
}
public void setExtended(boolean extended) {
this.extended = extended;
}
public Module getModule() {
return module;
}
public void setModule(Module module) {
this.module = module;
}
}
@@ -0,0 +1,16 @@
package me.retucio.sputnik.module.setting.settings;
import me.retucio.sputnik.module.setting.Setting;
// ajuste booleano, es decir, o se encuentra encencido o apagado (similar a un interruptor)
public class BooleanSetting extends Setting<Boolean> {
public BooleanSetting(String name, String description, boolean defaultValue) {
super(name, description, defaultValue);
}
public void toggle() {
setValue(!value);
if (updateListener != null) updateListener.accept(value);
}
}
@@ -1,21 +1,17 @@
package me.retucio.sputnik.module.settings;
package me.retucio.sputnik.module.setting.settings;
import me.retucio.sputnik.module.setting.Setting;
import me.retucio.sputnik.util.Colors;
import net.minecraft.text.Text;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
public class ColorSetting extends Setting {
public class ColorSetting extends Setting<Color> {
private Color color;
private Consumer<Color> updateListener;
private Color defaultColor;
private boolean defaultRainbow;
private int defaultRainbowSpeed;
private final boolean defaultRainbow;
private final int defaultRainbowSpeed;
private int r, g, b, a;
@@ -24,14 +20,13 @@ public class ColorSetting extends Setting {
private float saturation;
private float brightness;
public ColorSetting(String name, String description, Color defaultColor, boolean rainbow) {
super(name, description);
this.color = this.defaultColor = defaultColor;
public ColorSetting(String name, String description, Color defaultValue, boolean rainbow) {
super(name, description, defaultValue);
this.r = defaultColor.getRed();
this.g = defaultColor.getGreen();
this.b = defaultColor.getBlue();
this.a = defaultColor.getAlpha();
this.r = defaultValue.getRed();
this.g = defaultValue.getGreen();
this.b = defaultValue.getBlue();
this.a = defaultValue.getAlpha();
this.rainbow = rainbow;
this.defaultRainbow = rainbow;
@@ -42,13 +37,8 @@ public class ColorSetting extends Setting {
this.brightness = 1f;
}
public Color getColor() {
if (rainbow) return Colors.rainbowColor(rainbowSpeed, a, saturation, brightness);
return color;
}
public int getR() {
return getColor().getRed();
return getValue().getRed();
}
public void setR(int r) {
@@ -56,12 +46,12 @@ public class ColorSetting extends Setting {
this.r = Math.clamp(r, 0, 255);
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
if (updateListener != null) updateListener.accept(value);
}
}
public int getG() {
return getColor().getGreen();
return getValue().getGreen();
}
public void setG(int g) {
@@ -69,12 +59,12 @@ public class ColorSetting extends Setting {
this.g = Math.clamp(g, 0, 255);
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
if (updateListener != null) updateListener.accept(value);
}
}
public int getB() {
return getColor().getBlue();
return getValue().getBlue();
}
public void setB(int b) {
@@ -82,7 +72,7 @@ public class ColorSetting extends Setting {
this.b = Math.clamp(b, 0, 255);
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
if (updateListener != null) updateListener.accept(value);
}
}
@@ -95,24 +85,31 @@ public class ColorSetting extends Setting {
this.a = Math.clamp(a, 0, 255);
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
if (updateListener != null) updateListener.accept(value);
}
}
private void updateColorFromRGB() {
this.color = new Color(r, g, b, a);
this.value = new Color(r, g, b, a);
}
public void setColor(Color color) {
if (!this.color.equals(color)) {
this.color = color;
this.r = color.getRed();
this.g = color.getGreen();
this.b = color.getBlue();
this.a = color.getAlpha();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
@Override
public Color getValue() {
if (rainbow) return Colors.rainbowColor(rainbowSpeed, a, saturation, brightness);
return super.getValue();
}
@Override
public void setValue(Color value) {
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) {
@@ -142,7 +139,7 @@ public class ColorSetting extends Setting {
if (changed) {
updateColorFromRGB();
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
if (updateListener != null) updateListener.accept(value);
}
}
@@ -154,7 +151,7 @@ public class ColorSetting extends Setting {
if (this.rainbow != rainbow) {
this.rainbow = rainbow;
fireUpdateEvent();
if (updateListener != null) updateListener.accept(getColor());
if (updateListener != null) updateListener.accept(getValue());
}
}
@@ -166,7 +163,7 @@ public class ColorSetting extends Setting {
if (this.rainbowSpeed != rainbowSpeed) {
this.rainbowSpeed = rainbowSpeed;
fireUpdateEvent();
if (updateListener != null && rainbow) updateListener.accept(getColor());
if (updateListener != null && rainbow) updateListener.accept(getValue());
}
}
@@ -178,7 +175,7 @@ public class ColorSetting extends Setting {
if (this.saturation != saturation) {
this.saturation = Math.clamp(saturation, 0f, 1f);
fireUpdateEvent();
if (updateListener != null && rainbow) updateListener.accept(getColor());
if (updateListener != null && rainbow) updateListener.accept(getValue());
}
}
@@ -190,32 +187,24 @@ public class ColorSetting extends Setting {
if (this.brightness != brightness) {
this.brightness = Math.clamp(brightness, 0f, 1f);
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() {
return defaultColor.getRed();
return defaultValue.getRed();
}
public int getDefaultG() {
return defaultColor.getGreen();
return defaultValue.getGreen();
}
public int getDefaultB() {
return defaultColor.getBlue();
return defaultValue.getBlue();
}
public int getDefaultA() {
return defaultColor.getAlpha();
return defaultValue.getAlpha();
}
public float getDefaultSaturation() {
@@ -235,31 +224,24 @@ public class ColorSetting extends Setting {
}
public int getRGB() {
return getColor().getRGB();
return getValue().getRGB();
}
public Text getTooltipText() {
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() {
this.color = defaultColor;
this.r = defaultColor.getRed();
this.g = defaultColor.getGreen();
this.b = defaultColor.getBlue();
this.a = defaultColor.getAlpha();
this.r = defaultValue.getRed();
this.g = defaultValue.getGreen();
this.b = defaultValue.getBlue();
this.a = defaultValue.getAlpha();
this.rainbow = false;
this.rainbowSpeed = 2;
this.saturation = 1f;
this.brightness = 1f;
fireUpdateEvent();
if (updateListener != null) updateListener.accept(color);
}
public void onUpdate(Consumer<Color> listener) {
this.updateListener = listener;
if (updateListener != null) updateListener.accept(getColor());
super.reset();
}
public Map<String, ?> getConfigValue() {
@@ -274,4 +256,4 @@ public class ColorSetting extends Setting {
map.put("bri", (double) brightness);
return map;
}
}
}
@@ -1,39 +1,29 @@
package me.retucio.sputnik.module.settings;
package me.retucio.sputnik.module.setting.settings;
import me.retucio.sputnik.module.setting.Setting;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
// 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 E defaultValue;
private E value;
private int index;
private Consumer<E> updateListener;
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.defaultValue = defaultValue;
this.value = defaultValue;
this.index = values.indexOf(defaultValue);
}
public E getValue() {
return value;
}
public void setValue(E value) {
if (this.value != value) {
this.value = value;
this.index = values.indexOf(value);
fireUpdateEvent();
if (updateListener != null) updateListener.accept(value);
}
super.setValue(value);
}
public List<E> getValues() {
@@ -67,21 +57,4 @@ public class EnumSetting<E extends Enum<E>> extends Setting {
else
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);
}
}
@@ -0,0 +1,47 @@
package me.retucio.sputnik.module.setting.settings;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.setting.Setting;
import me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.KeyUtil;
import org.lwjgl.glfw.GLFW;
import java.util.Objects;
import java.util.function.Consumer;
public class KeySetting extends Setting<Integer> {
public KeySetting(String name, String description, int defaultKey) {
super(name, description, defaultKey);
this.value = defaultKey;
this.defaultValue = defaultKey;
}
@Override
public void setValue(Integer value) {
if (this.value.equals(value)) return;
if (value == GLFW.GLFW_KEY_ESCAPE) {
this.value = GLFW.GLFW_KEY_UNKNOWN; // asignar la tecla ESC a deshabilitar la tecla
fireUpdateEvent();
if (updateListener != null) updateListener.accept(value);
return;
}
if (ModuleManager.INSTANCE != null) {
for (Module module : ModuleManager.INSTANCE.getModules())
if (module.getKey() == value && !ClientSettingsFrame.guiSettings.multipleKeybinds.getValue() && value != -1) {
module.setKey(-1);
ChatUtil.info("tecla del módulo " + module.getName() + " restablecida");
}
}
super.setValue(value);
}
public String getKeyName() {
return KeyUtil.getKeyName(value);
}
}
@@ -0,0 +1,112 @@
package me.retucio.sputnik.module.setting.settings;
import me.retucio.sputnik.module.setting.Setting;
import java.util.*;
public class ListSetting<T> extends Setting<Map<T, Boolean>> {
private final List<T> options;
private Map<T, String> displayNames = null;
public ListSetting(String name, String description, List<T> options, Map<T, Boolean> initialValues) {
super(name, description, initialValues);
this.options = new ArrayList<>(options);
this.defaultValue = new HashMap<>();
for (T option : options) {
boolean enabled = initialValues != null && initialValues.getOrDefault(option, false);
defaultValue.put(option, enabled);
}
this.value = new HashMap<>(defaultValue);
}
public ListSetting(String name, String description, List<T> options, Map<T, Boolean> initialValues, Map<T, String> displayNames) {
this(name, description, options, initialValues);
this.displayNames = displayNames;
}
public boolean isEnabled(T option) {
return value.getOrDefault(option, false);
}
public void setEnabled(T option, boolean enabled) {
if (value.containsKey(option) && value.get(option) != enabled) {
value.put(option, enabled);
fireUpdateEvent();
if (updateListener != null) updateListener.accept(new HashMap<>(value));
}
}
public void toggle(T option) {
setEnabled(option, !isEnabled(option));
}
public Map<T, Boolean> getValues() {
return new HashMap<>(value);
}
@Override
public void setValue(Map<T, Boolean> values) {
if (!this.value.equals(values)) {
super.setValue(values);
}
}
public void setDefaultValue(Map<T, Boolean> values) {
defaultValue.clear();
defaultValue.putAll(values);
}
public Map<String, Boolean> getConfigValues() {
Map<String, Boolean> configValues = new HashMap<>();
for (T option : options) {
configValues.put(getDisplayName(option), value.getOrDefault(option, false));
}
return configValues;
}
public void addOption(T option, boolean isDefault, String displayName) {
options.add(option);
defaultValue.put(option, isDefault);
value.put(option, isDefault);
if (this.displayNames != null) {
this.displayNames.put(option, displayName);
}
}
public void setAll(boolean enabled) {
for (T option : options) {
value.put(option, enabled);
}
fireUpdateEvent();
if (updateListener != null) updateListener.accept(new HashMap<>(value));
}
public List<T> getOptions() {
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() {
return displayNames != null ? new HashMap<>(displayNames) : null;
}
public String getDisplayName(T key) {
if (displayNames != null && displayNames.containsKey(key)) {
return displayNames.get(key);
}
return key != null ? key.toString() : "?";
}
}
Loaded 100 of 165 files, more files were not shown because too many files have changed in this diff. Show more