Compare commits

...
18 Commits
Author SHA1 Message Date
retuci0 957fab15aa v5.2 2026-05-10 10:54:59 +02:00
retuci0 321505657c v5.1 2026-05-09 20:55:38 +02:00
retuci0 b2bc2b36ab v5.0 2026-05-07 22:51:36 +02:00
retuci0 09ed268576 v4.8 2026-05-07 16:27:24 +02:00
retuci0 531c3ef9aa v4.8 2026-05-06 21:15:59 +02:00
retuci0 67cc34a08c v4.7 2026-05-06 17:59:19 +02:00
retuci0 c7b8e96d68 v4.6 2026-05-04 19:12:16 +02:00
retuci0 65afbf6ae6 v4.5 2026-05-03 15:06:20 +02:00
retuci0 8933565e07 v4.4 2026-05-01 23:45:42 +02:00
retuci0 47ad2c67c5 v4.3 2026-04-30 22:24:33 +02:00
retucio e84382367e actualizar build.yml 2026-04-30 20:19:02 +02:00
retuci0 ac99a609a0 v4.2 2026-04-28 17:38:38 +02:00
retuci0 1d22ec5176 4.1 (broken) 2026-04-27 21:55:51 +02:00
retuci0 05c5300cd8 v4.0 2026-03-23 19:39:59 +01:00
retuci0 a879458b4a v3.9 2026-03-21 09:48:30 +01:00
retuci0 bab752c589 v3.8 2026-03-01 22:38:57 +01:00
retuci0 4d30a16a6a v3.7 2026-02-27 18:06:32 +01:00
retuci0 412fe93a89 v3.6 2026-02-22 12:01:00 +01:00
370 changed files with 10451 additions and 6594 deletions

No files matched your search

+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
- name: setup jdk
uses: actions/setup-java@v4
with:
java-version: '21'
java-version: '25'
distribution: 'microsoft'
- name: make gradle wrapper executable
run: chmod +x ./gradlew
+3 -3
View File
@@ -1,6 +1,6 @@
# jenny's mod 2 100% real
mod para Minecraft Fabric 1.21.11 que añade algunas cosas QOL, mayormente relacionadas a la cámara.
mod para Minecraft Fabric 26.1.2 que añade algunas cosas QOL, mayormente relacionadas a la cámara.
## instalación
@@ -10,7 +10,7 @@ mod para Minecraft Fabric 1.21.11 que añade algunas cosas QOL, mayormente relac
3. descargar el .jar
4. moverlo a tu directorio de mods (probablemente `%appdata%/.minecraft/mods`)
asegúrate de tener una version de Minecraft y Fabric compatibles con el mod (MC `1.21.11`; Fabric `0.17.3`)
asegúrate de tener una version de Minecraft y Fabric compatibles con el mod (MC `26.1.2`; Fabric `0.19.2`)
es posible que haya problemas al usarlo junto a otros mods, especialmente junto a otros clientes, pues pueden conflictar entre ellos.
### para frikis de 200 de iq
@@ -23,7 +23,7 @@ es posible que haya problemas al usarlo junto a otros mods, especialmente junto
`shift derecho` por defecto para abrir la interfaz
`pág. arriba` por defecto para abrir el editor del hud
`insertar` por defecto para abrir el editor del hud
`$` como prefijo por defecto para comandos (se autocompletan)
+42 -37
View File
@@ -1,5 +1,5 @@
plugins {
id 'fabric-loom' version "${loom_version}"
id "net.fabricmc.fabric-loom" version "${loom_version}"
id 'maven-publish'
}
@@ -7,74 +7,79 @@ version = project.mod_version
group = project.maven_group
base {
archivesName = project.archives_base_name
archivesName = project.archives_base_name
}
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
maven {
name = "FDD Maven"
url = "https://maven.firstdark.dev/releases"
}
mavenCentral()
maven { url 'https://jitpack.io' }
maven {
name = "FDD Maven"
url = "https://maven.firstdark.dev/releases"
}
}
dependencies {
// mc
minecraft "com.mojang:minecraft:${project.minecraft_version}"
minecraft "com.mojang:minecraft:${project.minecraft_version}"
// mappings
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
// fabric & su api
implementation "net.fabricmc:fabric-loader:${project.loader_version}"
implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
// fabric & su api
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
// sistema de eventos
include(modImplementation "com.github.retuci0:neutrino:${project.neutrino_version}")
// sistema de eventos
include(implementation "com.github.retuci0:neutrino:${project.neutrino_version}")
// rpc de discord
include(modImplementation "dev.firstdark.discordrpc:discord-rpc:1.0.3")
include(implementation "dev.firstdark.discordrpc:discord-rpc:${project.discord_rpc_version}")
}
loom {
accessWidenerPath = file("src/main/resources/sputnik.accesswidener")
accessWidenerPath = file("src/main/resources/sputnik.accesswidener")
}
processResources {
inputs.property "version", project.version
inputs.property "version", project.version
inputs.property "loader_version", project.loader_version
inputs.property "minecraft_version", project.minecraft_version
inputs.property "jdk_version", project.jdk_version
filesMatching("fabric.mod.json") {
expand "version": inputs.properties.version
}
filesMatching("fabric.mod.json") {
expand(
"version": project.version,
"loader_version": project.loader_version,
"minecraft_version": project.minecraft_version,
"jdk_version": project.jdk_version
)
}
}
tasks.withType(JavaCompile).configureEach {
it.options.release = 21
it.options.release = jdk_version.toInteger()
}
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
sourceCompatibility = JavaVersion.toVersion(jdk_version)
targetCompatibility = JavaVersion.toVersion(jdk_version)
}
jar {
inputs.property "archivesName", project.base.archivesName
inputs.property "archivesName", project.base.archivesName
from("LICENSE") {
rename {
from("LICENSE") {
rename {
"${it}_${inputs.properties.archivesName}"
}
}
}
}
publishing {
publications {
create("mavenJava", MavenPublication) {
artifactId = project.archives_base_name
from components.java
}
}
publications {
create("mavenJava", MavenPublication) {
artifactId = project.archives_base_name
from components.java
}
}
repositories {}
repositories {}
}
+7 -7
View File
@@ -1,18 +1,18 @@
# v3.5
# v5.2
## novedades
### adiciones
#### módulos nuevos:
### arreglos / mejoras
- arreglado el crash por no incluir el sistema de eventos en el mod (soy gilipollas)
- mejoras varias al módulo tobillos fuertes
- ahora el módulo de interfaces en portales funciona correctamente
- reponer ya no está repe
- `andamios` ya funciona correctamente
- autoguardado cada cierto intervalo de tiempo en vez de guardar inmediatamente tras cada cambio en los ajustes, por optimización
- el guardado se realiza desde otro hilo ahora, para evitar que el I/O bloque el hilo principal
## problemas reconocidos
- lo de siempre.
- el ítem del tótem no se renderiza en el editor del HUD si es abierto en la pantalla de inicio
+2 -2
View File
@@ -1,4 +1,4 @@
Meteor Client: https://github.com/MeteorDevelopment/meteor-client | https://meteorclient.com
Meteor Client: https://github.com/MeteorDevelopment/meteor-client | https://meteorclient.com
OyVey Port: https://github.com/mioclient/oyvey-ported/
Lenny Boi: https://www.youtube.com/@lennyboi7195
Shotify: https://modrinth.com/mod/shotify
@@ -9,7 +9,7 @@ bypass-resource-pack: https://github.com/emilyy-dev/bypass-resource-pack
elytra-recast: https://github.com/InLieuOfLuna/elytra-recast/
SpearHax: https://github.com/etianl/spearHax/
ProjectileTrajectoryPreview: https://github.com/maDU59/ProjectilesTrajectoryPreview
DupersUnited public addon: https://discord.gg/dupes | https://dupers.wtf
DupersUnited public addon: https://discord.gg/dupes | https://dupers.wtf
probablemente más pero como tengo demencia se me olvida
si quieres que te acredite o quite tu código de mi mod, mándame un mensaje en discord (username: retucio) y sin problemas :)
+7 -7
View File
@@ -1,15 +1,15 @@
org.gradle.jvmargs=-Xmx2G
org.gradle.parallel=true
minecraft_version=1.21.11
yarn_mappings=1.21.11+build.3
loader_version=0.18.4
loom_version=1.13-SNAPSHOT
fabric_api_version=0.140.2+1.21.11
minecraft_version=26.1.2
loader_version=0.19.2
loom_version=1.16-SNAPSHOT
fabric_api_version=0.146.0+26.1.2
discord_rpc_version=1.0.3
neutrino_version=1.1.0
jdk_version=25
mod_version=3.5
mod_version=5.2
maven_group=me.retucio
archives_base_name=sputnik
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+76 -55
View File
@@ -1,6 +1,7 @@
package me.retucio.sputnik;
import com.github.retucio.neutrino.EventBus;
import com.github.retucio.neutrino.EventListener;
import me.retucio.sputnik.cape.CapeManager;
import me.retucio.sputnik.command.CommandManager;
import me.retucio.sputnik.command.commands.BindCommand;
@@ -9,28 +10,28 @@ import me.retucio.sputnik.config.ConfigManager;
import me.retucio.sputnik.event.ShutdownEvent;
import me.retucio.sputnik.event.interact.OpenScreenEvent;
import me.retucio.sputnik.event.sputnik.LoadCapeManagerEvent;
import me.retucio.sputnik.event.sputnik.LoadClickGUIEvent;
import me.retucio.sputnik.event.sputnik.LoadCommandManagerEvent;
import me.retucio.sputnik.event.sputnik.LoadModuleManagerEvent;
import me.retucio.sputnik.event.sputnik.*;
import me.retucio.sputnik.friend.FriendManager;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.client.HUD;
import me.retucio.sputnik.module.modules.client.Hud;
import me.retucio.sputnik.ui.hud.HudRenderer;
import me.retucio.sputnik.ui.screen.ClickGUI;
import me.retucio.sputnik.ui.screen.ClickGui;
import me.retucio.sputnik.ui.hud.HudEditorScreen;
import me.retucio.sputnik.ui.screen.UpdateScreen;
import me.retucio.sputnik.ui.widgets.buttons.settings.BindButton;
import me.retucio.sputnik.ui.widgets.buttons.SettingButton;
import me.retucio.sputnik.ui.widgets.buttons.settings.TextButton;
import me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame;
import me.retucio.sputnik.ui.widgets.frames.SettingsFrame;
import me.retucio.sputnik.ui.widgets.panels.settings.ClientSettingsPanel;
import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
import me.retucio.sputnik.ui.widgets.Button;
import me.retucio.sputnik.util.*;
import me.retucio.sputnik.util.KeyUtil;
import me.retucio.sputnik.util.misc.BlockIterator;
import me.retucio.sputnik.util.misc.VersionChecker;
import me.retucio.sputnik.util.render.DrawUtil;
import me.retucio.sputnik.util.render.RenderUtil;
@@ -39,13 +40,13 @@ import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.SharedConstants;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.gui.screen.ingame.AbstractCommandBlockScreen;
import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen;
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.ChatScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.client.gui.screens.inventory.AbstractCommandBlockEditScreen;
import net.minecraft.client.gui.screens.inventory.AbstractSignEditScreen;
import net.minecraft.client.gui.screens.inventory.AnvilScreen;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -54,11 +55,13 @@ import org.lwjgl.glfw.GLFW;
public class Sputnik implements ClientModInitializer {
// cosas necesarias
public static final Sputnik INSTANCE = new Sputnik();
// cosas del mod
public static final EventBus EVENT_BUS = new EventBus();
public static final Logger LOGGER = LogManager.getLogger(Sputnik.class);
public static MinecraftClient mc;
public static final long LAUNCH_TIME = System.currentTimeMillis();
public static Minecraft mc;
// id y versión
public static final String MOD_ID = "sputnik";
@@ -79,10 +82,12 @@ public class Sputnik implements ClientModInitializer {
@Override
public void onInitializeClient() {
mc = MinecraftClient.getInstance();
ConfigManager.load();
mc = Minecraft.getInstance();
VersionChecker.check();
ConfigManager.INSTANCE = new ConfigManager();
ConfigManager.INSTANCE.load();
VersionChecker.INSTANCE.check();
EVENT_BUS.subscribe(this);
@@ -94,8 +99,11 @@ public class Sputnik implements ClientModInitializer {
EVENT_BUS.subscribe(NetworkUtil.class);
EVENT_BUS.subscribe(RenderUtil.class);
EVENT_BUS.subscribe(BlockIterator.class);
Lists.init();
Textures.init();
HudRenderer.INSTANCE = new HudRenderer();
CapeManager.INSTANCE = new CapeManager();
EVENT_BUS.post(new LoadCapeManagerEvent());
@@ -106,11 +114,18 @@ public class Sputnik implements ClientModInitializer {
CommandManager.INSTANCE = new CommandManager();
EVENT_BUS.post(new LoadCommandManagerEvent());
ClickGUI.INSTANCE = new ClickGUI();
HudEditorScreen.INSTANCE = new HudEditorScreen();
EVENT_BUS.post(new LoadClickGUIEvent());
FriendManager.INSTANCE = new FriendManager();
EVENT_BUS.post(new LoadFriendManagerEvent());
mc.execute(HudRenderer::init);
mc.execute(() -> {
Textures.init();
ClickGui.INSTANCE = new ClickGui();
HudEditorScreen.INSTANCE = new HudEditorScreen();
EVENT_BUS.post(new LoadClickGuiEvent());
HudRenderer.INSTANCE.init();
});
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
EVENT_BUS.post(new ShutdownEvent());
@@ -120,23 +135,26 @@ public class Sputnik implements ClientModInitializer {
// se ejecuta cada tick, es decir, 20 veces por segundo
public void onTick() {
if (!settingsApplied
&& ConfigManager.getConfig() != null
&& !ConfigManager.hasLoaded()) {
ConfigManager.applyConfig();
&& ConfigManager.INSTANCE.getConfig() != null
&& !ConfigManager.INSTANCE.hasLoaded()) {
ConfigManager.INSTANCE.applyConfig();
settingsApplied = true;
}
ModuleManager.INSTANCE.getEnabledModules().forEach(Module::onTick);
mc.getWindow().setTitle(ClientSettingsFrame.guiSettings.windowTitle.getValue());
mc.getWindow().setTitle(ClientSettingsPanel.clientSettings.windowTitle.getValue());
ConfigManager.INSTANCE.tickAutosave();
}
// se ejecuta cada vez que se presiona una tecla
public void onInput(int key, int action) {
if (key == GLFW.GLFW_KEY_F3) return; // prevenir interrumpir combos de F3
// prevenir interrumpir combos de F3
if (key == GLFW.GLFW_KEY_F3) return;
boolean anyFocused = isAnySettingButtonFocused() || ClickGUI.INSTANCE.getSearchBar().isFocused();
ClickGUI.INSTANCE.setAnyFocused(anyFocused);
boolean anyFocused = isAnySettingButtonFocused() || ClickGui.INSTANCE.getSearchBar().isFocused();
ClickGui.INSTANCE.setAnyFocused(anyFocused);
if (action != GLFW.GLFW_RELEASE) {
if (BindCommand.onKeyPress(key)) return;
@@ -156,7 +174,7 @@ public class Sputnik implements ClientModInitializer {
// verifica si algún botón de ajustes está escuchando
private boolean isAnySettingButtonFocused() {
for (SettingsFrame sf : ClickGUI.INSTANCE.getSettingsFrames())
for (SettingsPanel sf : ClickGui.INSTANCE.getSettingsPanels())
for (Button sb : sf.getButtons())
if ((sb instanceof BindButton b && b.isFocused()) || (sb instanceof TextButton t && t.isFocused()))
return true;
@@ -165,10 +183,11 @@ public class Sputnik implements ClientModInitializer {
// se ocupa de la lógica de encendido y apagado de los módulos
private void handleModuleToggle(int key, boolean anyFocused) {
if (mc.currentScreen != null && mc.currentScreen != ClickGUI.INSTANCE) return;
if (mc.screen != null && mc.screen != ClickGui.INSTANCE) return;
for (Module module : ModuleManager.INSTANCE.getModules()) {
if (key != module.getKey() || anyFocused || KeyUtil.isKeyDown(GLFW.GLFW_KEY_F3)) continue; // evitar interrumpir combinaciones de teclas del F3
// evitar interrumpir combinaciones de teclas del F3
if (key != module.getKey() || anyFocused || KeyUtil.isKeyDown(GLFW.GLFW_KEY_F3)) continue;
if (module.shouldToggleOnBindRelease() && !module.isEnabled())
module.setEnabled(true);
@@ -179,7 +198,7 @@ public class Sputnik implements ClientModInitializer {
// se ocupa de hacer los botones de ajustes que lo necesiten escuchar teclas
private void handleSettingButtonsKey(int key, int action) {
for (SettingsFrame sf : ClickGUI.INSTANCE.getSettingsFrames()) {
for (SettingsPanel sf : ClickGui.INSTANCE.getSettingsPanels()) {
for (SettingButton<?> sb : sf.getButtons()) {
if (sb instanceof BindButton bb) bb.onKey(key, action);
if (sb instanceof TextButton tb) tb.onKey(key, action);
@@ -189,39 +208,39 @@ public class Sputnik implements ClientModInitializer {
// maneja la lógica de apertura de la interfaz
private void handleClickGUIKey(int key, boolean anyFocused) {
if (key != ClientSettingsFrame.guiSettings.getKey() || anyFocused || isOnTypingScreen())
if (key != ClientSettingsPanel.clientSettings.getKey() || anyFocused || isOnTypingScreen())
return;
if (mc.currentScreen != ClickGUI.INSTANCE) {
prevScreen = mc.currentScreen;
mc.setScreen(ClickGUI.INSTANCE);
if (mc.screen != ClickGui.INSTANCE) {
prevScreen = mc.screen;
mc.setScreen(ClickGui.INSTANCE);
} else {
ClickGUI.INSTANCE.close();
ClickGui.INSTANCE.onClose();
mc.setScreen(prevScreen);
}
}
// 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);
Hud hud = ModuleManager.INSTANCE.getModuleByClass(Hud.class);
if (key != hud.editorKey.getValue() || anyFocused || isOnTypingScreen()) return;
if (mc.currentScreen != HudEditorScreen.INSTANCE) {
if (mc.screen != HudEditorScreen.INSTANCE) {
if (!hud.isEnabled()) {
ChatUtil.warn("HUD está desactivado, lumbreras");
return;
}
prevScreen = mc.currentScreen;
prevScreen = mc.screen;
mc.setScreen(HudEditorScreen.INSTANCE);
} else {
HudEditorScreen.INSTANCE.close();
HudEditorScreen.INSTANCE.onClose();
mc.setScreen(prevScreen);
}
}
// se ocupa de apagar los módulos que tengan configurado hacerlo tras soltar su tecla
private void handleModuleRelease(int key) {
if (mc.currentScreen != null && mc.currentScreen != ClickGUI.INSTANCE) return;
if (mc.screen != null && mc.screen != ClickGui.INSTANCE) return;
for (Module module : ModuleManager.INSTANCE.getEnabledModules())
if (module.shouldToggleOnBindRelease() && key == module.getKey())
@@ -229,26 +248,28 @@ public class Sputnik implements ClientModInitializer {
}
private boolean isOnTypingScreen() {
return mc.currentScreen instanceof ChatScreen
|| mc.currentScreen instanceof AnvilScreen
|| mc.currentScreen instanceof AbstractSignEditScreen
|| mc.currentScreen instanceof AbstractCommandBlockScreen;
return mc.screen instanceof ChatScreen
|| mc.screen instanceof AnvilScreen
|| mc.screen instanceof AbstractSignEditScreen
|| mc.screen instanceof AbstractCommandBlockEditScreen;
}
@EventListener
// notificar al usuario de que hay una actualización disponible, si la hay
public void onSetScreen(OpenScreenEvent event) {
if (VersionChecker.shouldShowScreen && event.getScreen() instanceof TitleScreen) {
if (VersionChecker.INSTANCE.shouldShowScreen && event.getScreen() instanceof TitleScreen) {
event.cancel();
VersionChecker.shouldShowScreen = false;
mc.execute(() -> mc.currentScreen = new UpdateScreen());
VersionChecker.INSTANCE.shouldShowScreen = false;
mc.execute(() -> mc.screen = new UpdateScreen());
}
}
@EventListener
public void onStop(ShutdownEvent event) {
ConfigManager.save();
ConfigManager.INSTANCE.saveOnShutdown();
}
public static String getVersionName() {
return MOD_ID + "_v" + MOD_VERSION + "_" + SharedConstants.getGameVersion().name();
return MOD_ID + "_v" + MOD_VERSION + "_" + SharedConstants.getCurrentVersion().name();
}
}
+12 -11
View File
@@ -1,26 +1,27 @@
package me.retucio.sputnik.cape;
import me.retucio.sputnik.Sputnik;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.util.Identifier;
import net.minecraft.client.Minecraft;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.resources.Identifier;
import java.io.IOException;
import java.io.InputStream;
public class Cape {
private final MinecraftClient mc = MinecraftClient.getInstance();
private final Minecraft mc = Minecraft.getInstance();
private final String name;
private final Identifier id;
private NativeImage img;
private NativeImageBackedTexture texture;
private DynamicTexture texture;
public Cape(String name) {
this.name = name;
this.id = Identifier.of(Sputnik.MOD_ID, "textures/capes/" + name + ".png");
this.id = Identifier.fromNamespaceAndPath(Sputnik.MOD_ID, "textures/capes/" + name + ".png");
}
public void load() {
@@ -28,7 +29,7 @@ public class Cape {
}
public NativeImage loadTexture(Identifier id) {
try (InputStream inputStream = mc.getResourceManager().getResource(id).get().getInputStream()) {
try (InputStream inputStream = mc.getResourceManager().getResource(id).get().open()) {
return NativeImage.read(inputStream);
} catch (IOException e) {
Sputnik.LOGGER.error("ups: {}", e.getMessage());
@@ -37,8 +38,8 @@ public class Cape {
}
public void register() {
texture = new NativeImageBackedTexture(null, img);
mc.getTextureManager().registerTexture(id, texture);
texture = new DynamicTexture(null, img);
mc.getTextureManager().register(id, texture);
img = null;
}
@@ -50,7 +51,7 @@ public class Cape {
return id;
}
public NativeImageBackedTexture getTexture() {
public DynamicTexture getTexture() {
return texture;
}
@@ -4,21 +4,21 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import net.minecraft.client.MinecraftClient;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.command.CommandSource;
import net.minecraft.registry.BuiltinRegistries;
import net.minecraft.server.command.CommandManager;
import net.minecraft.client.Minecraft;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.Commands;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.data.registries.VanillaRegistries;
import java.util.List;
public abstract class Command {
// utilizar los "registries" ya existentes de Brigadier para el autocompletado
protected static final CommandRegistryAccess REGISTRY_ACCESS = CommandManager.createRegistryAccess(BuiltinRegistries.createWrapperLookup());
protected static final CommandBuildContext REGISTRY_ACCESS = Commands.createValidationContext(VanillaRegistries.createLookup());
protected static final int SUCCESS = com.mojang.brigadier.Command.SINGLE_SUCCESS;
protected static final MinecraftClient mc = MinecraftClient.getInstance();
protected static final Minecraft mc = Minecraft.getInstance();
private final String name, description;
private final List<String> aliases;
@@ -30,27 +30,27 @@ public abstract class Command {
}
// métodos "helper" para reducir el "boilerplate"
protected static <T> RequiredArgumentBuilder<CommandSource, T> argument(final String name, final ArgumentType<T> type) {
protected static <T> RequiredArgumentBuilder<SharedSuggestionProvider, T> argument(final String name, final ArgumentType<T> type) {
return RequiredArgumentBuilder.argument(name, type);
}
protected static LiteralArgumentBuilder<CommandSource> literal(final String name) {
protected static LiteralArgumentBuilder<SharedSuggestionProvider> literal(final String name) {
return LiteralArgumentBuilder.literal(name);
}
// para registrar comandos
public final void registerTo(CommandDispatcher<CommandSource> dispatcher) {
public final void registerTo(CommandDispatcher<SharedSuggestionProvider> dispatcher) {
register(dispatcher, name);
for (String alias : aliases) register(dispatcher, alias);
}
public void register(CommandDispatcher<CommandSource> dispatcher, String name) {
LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder.literal(name);
public void register(CommandDispatcher<SharedSuggestionProvider> dispatcher, String name) {
LiteralArgumentBuilder<SharedSuggestionProvider> builder = LiteralArgumentBuilder.literal(name);
build(builder);
dispatcher.register(builder);
}
public abstract void build(LiteralArgumentBuilder<CommandSource> builder);
public abstract void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder);
public String getName() {
return name;
@@ -5,8 +5,8 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.command.commands.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.command.CommandSource;
import net.minecraft.client.Minecraft;
import net.minecraft.commands.SharedSuggestionProvider;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -22,9 +22,9 @@ public class CommandManager {
private String prefix = "$";
public static final List<Command> commands = new ArrayList<>();
public static final CommandDispatcher<CommandSource> dispatcher = new CommandDispatcher<>();
public static final CommandDispatcher<SharedSuggestionProvider> dispatcher = new CommandDispatcher<>();
private static final MinecraftClient mc = MinecraftClient.getInstance();
private static final Minecraft mc = Minecraft.getInstance();
public CommandManager() {
registerCommands();
@@ -36,12 +36,14 @@ public class CommandManager {
addCommand(new ConfigCommand());
addCommand(new CopyScreenshotCommand());
addCommand(new EnderChestCommand());
addCommand(new FriendCommand());
addCommand(new GarbageCleanerCommand());
addCommand(new PeekCommand());
addCommand(new PluginsCommand());
addCommand(new PrefixCommand());
addCommand(new PurgeCommand());
addCommand(new RepeatCommand());
addCommand(new RepeatWaitCommand());
addCommand(new SaveScreenshotCommand());
addCommand(new SendCommand());
addCommand(new SpectateCommand());
@@ -67,7 +69,7 @@ public class CommandManager {
}
public static void dispatch(String message) throws CommandSyntaxException {
dispatcher.execute(message, Objects.requireNonNull(mc.getNetworkHandler()).getCommandSource());
dispatcher.execute(message, Objects.requireNonNull(mc.getConnection()).getSuggestionsProvider());
}
public static Command getCommandByName(String name) {
@@ -9,9 +9,9 @@ import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.retucio.sputnik.util.EntityUtil;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import java.util.*;
import java.util.concurrent.CompletableFuture;
@@ -25,7 +25,7 @@ public class EntityArgumentType implements ArgumentType<Entity> {
public static final EntityArgumentType INSTANCE = new EntityArgumentType();
private static final DynamicCommandExceptionType NO_SUCH_ENTITY = new DynamicCommandExceptionType(
name -> Text.literal("Entidad \"" + name + "\" no encontrada"));
name -> Component.literal("Entidad \"" + name + "\" no encontrada"));
private static final Collection<String> EXAMPLES = List.of(
"AdlerHitdolf",
@@ -42,7 +42,7 @@ public class EntityArgumentType implements ArgumentType<Entity> {
public Entity parse(StringReader reader) throws CommandSyntaxException {
String argument = reader.readString();
if (mc.world == null)
if (mc.level == null)
throw NO_SUCH_ENTITY.create(argument);
if (argument.startsWith("@"))
@@ -83,13 +83,13 @@ public class EntityArgumentType implements ArgumentType<Entity> {
}
private Entity findNearestPlayer() throws CommandSyntaxException {
PlayerEntity nearest = null;
Player nearest = null;
double nearestDistance = Double.MAX_VALUE;
for (PlayerEntity player : mc.world.getPlayers()) {
for (Player player : mc.level.players()) {
if (player == mc.player) continue;
double distance = mc.player.squaredDistanceTo(player);
double distance = mc.player.distanceToSqr(player);
if (distance < nearestDistance) {
nearestDistance = distance;
nearest = player;
@@ -103,7 +103,7 @@ public class EntityArgumentType implements ArgumentType<Entity> {
}
private Entity findRandomPlayer() throws CommandSyntaxException {
List<PlayerEntity> players = new ArrayList<>(mc.world.getPlayers());
List<Player> players = new ArrayList<>(mc.level.players());
if (players.isEmpty()) throw NO_SUCH_ENTITY.create("@r");
players.remove(mc.player);
@@ -116,8 +116,8 @@ public class EntityArgumentType implements ArgumentType<Entity> {
private Entity parseEntitySelector(String selector) throws CommandSyntaxException {
if (selector.equals("@e")) {
List<Entity> entities = new ArrayList<>();
for (Entity entity : mc.world.getEntities())
if (!(entity instanceof PlayerEntity))
for (Entity entity : mc.level.getEntities().getAll())
if (!(entity instanceof Player))
entities.add(entity);
if (entities.isEmpty()) throw NO_SUCH_ENTITY.create(selector);
@@ -141,8 +141,8 @@ public class EntityArgumentType implements ArgumentType<Entity> {
private Entity findEntityByType(String type) throws CommandSyntaxException {
List<Entity> matchingEntities = new ArrayList<>();
for (Entity entity : mc.world.getEntities()) {
String entityType = entity.getType().getTranslationKey();
for (Entity entity : mc.level.getEntities().getAll()) {
String entityType = entity.getType().getDescriptionId();
if (entityType.contains(type.toLowerCase().replace("minecraft:", "")))
matchingEntities.add(entity);
}
@@ -153,7 +153,7 @@ public class EntityArgumentType implements ArgumentType<Entity> {
double nearestDistance = Double.MAX_VALUE;
for (Entity entity : matchingEntities) {
double distance = mc.player.squaredDistanceTo(entity);
double distance = mc.player.distanceToSqr(entity);
if (distance < nearestDistance) {
nearestDistance = distance;
nearest = entity;
@@ -164,15 +164,15 @@ public class EntityArgumentType implements ArgumentType<Entity> {
}
private Entity findEntityByUUID(UUID uuid) throws CommandSyntaxException {
for (Entity entity : mc.world.getEntities())
if (entity.getUuid().equals(uuid))
for (Entity entity : mc.level.getEntities().getAll())
if (entity.getUUID().equals(uuid))
return entity;
throw NO_SUCH_ENTITY.create(uuid.toString());
}
private PlayerEntity findPlayerByName(String name) throws CommandSyntaxException {
for (PlayerEntity player : mc.world.getPlayers())
private Player findPlayerByName(String name) throws CommandSyntaxException {
for (Player player : mc.level.players())
if (player.getName().getString().equalsIgnoreCase(name))
return player;
@@ -181,8 +181,8 @@ public class EntityArgumentType implements ArgumentType<Entity> {
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
if (mc.world != null)
for (PlayerEntity player : mc.world.getPlayers())
if (mc.level != null)
for (Player player : mc.level.players())
builder.suggest(player.getName().getString());
@@ -192,7 +192,7 @@ public class EntityArgumentType implements ArgumentType<Entity> {
Entity lookingAt = EntityUtil.getEntityPlayerIsLookingAt();
if (lookingAt != null)
builder.suggest(lookingAt.getUuid().toString());
builder.suggest(lookingAt.getUUID().toString());
return builder.buildFuture();
}
@@ -7,15 +7,15 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.command.CommandSource;
import net.minecraft.text.Text;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.chat.Component;
import java.util.Arrays;
import java.util.concurrent.CompletableFuture;
public class EnumArgumentType<T extends Enum<T>> implements ArgumentType<T> {
private static final DynamicCommandExceptionType NO_SUCH_TYPE = new DynamicCommandExceptionType((value) -> Text.of(" argumento inválido: " + value));
private static final DynamicCommandExceptionType NO_SUCH_TYPE = new DynamicCommandExceptionType((value) -> Component.nullToEmpty(" argumento inválido: " + value));
private final T[] values;
@@ -41,6 +41,6 @@ public class EnumArgumentType<T extends Enum<T>> implements ArgumentType<T> {
}
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return CommandSource.suggestMatching(Arrays.stream(this.values).map(e -> e.toString().toLowerCase()), builder);
return SharedSuggestionProvider.suggest(Arrays.stream(this.values).map(e -> e.toString().toLowerCase()), builder);
}
}
@@ -10,8 +10,8 @@ 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;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.chat.Component;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
@@ -22,7 +22,7 @@ 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"));
name -> Component.literal("módulo \"" + name + "\" no encontrado"));
private static final Collection<String> examples = ModuleManager.INSTANCE.getModules()
.stream().limit(3).map(module -> module.getName().replace(" ", "_")).toList();
@@ -37,7 +37,7 @@ public class ModuleArgumentType implements ArgumentType<Module> {
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return CommandSource.suggestMatching(ModuleManager.INSTANCE.getModules()
return SharedSuggestionProvider.suggest(ModuleManager.INSTANCE.getModules()
.stream().map(module -> MiscUtil.removeAccentMarks(module.getName().replace(" ", "_"))), builder);
}
@@ -46,7 +46,7 @@ public class ModuleArgumentType implements ArgumentType<Module> {
return examples;
}
public static Module get(CommandContext<CommandSource> ctx) {
public static Module get(CommandContext<SharedSuggestionProvider> ctx) {
return ctx.getArgument("módulo", Module.class);
}
}
@@ -7,9 +7,9 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;
import java.util.Collection;
import java.util.List;
@@ -18,21 +18,21 @@ import java.util.concurrent.CompletableFuture;
import static me.retucio.sputnik.Sputnik.mc;
// para autocompletar nombres de jugadores
public class PlayerArgumentType implements ArgumentType<PlayerEntity> {
public class PlayerArgumentType implements ArgumentType<Player> {
public static final PlayerArgumentType INSTANCE = new PlayerArgumentType();
private static final DynamicCommandExceptionType NO_SUCH_PLAYER = new DynamicCommandExceptionType(name -> Text.literal("Player with name " + name + " doesn't exist."));
private static final DynamicCommandExceptionType NO_SUCH_PLAYER = new DynamicCommandExceptionType(name -> Component.literal("Player with name " + name + " doesn't exist."));
private static final Collection<String> EXAMPLES = List.of("retucio", "prepucio", "postpucio", "pucio", "adler hitdolf");
private PlayerArgumentType() {}
@Override
public PlayerEntity parse(StringReader reader) throws CommandSyntaxException {
public Player parse(StringReader reader) throws CommandSyntaxException {
String argument = reader.readString();
PlayerEntity playerEntity = null;
Player playerEntity = null;
for (PlayerEntity p : mc.world.getPlayers())
for (Player p : mc.level.players())
if (p.getName().getString().equalsIgnoreCase(argument)) {
playerEntity = p;
break;
@@ -45,7 +45,7 @@ public class PlayerArgumentType implements ArgumentType<PlayerEntity> {
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
return CommandSource.suggestMatching(mc.world.getPlayers().stream().map(
return SharedSuggestionProvider.suggest(mc.level.players().stream().map(
abstractClientPlayerEntity -> abstractClientPlayerEntity.getName().getString()), builder);
}
@@ -54,8 +54,8 @@ public class PlayerArgumentType implements ArgumentType<PlayerEntity> {
return EXAMPLES;
}
public static PlayerEntity get(CommandContext<?> context) {
return context.getArgument("jugador", PlayerEntity.class);
public static Player get(CommandContext<?> context) {
return context.getArgument("jugador", Player.class);
}
}
@@ -5,17 +5,16 @@ import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.command.args.ModuleArgumentType;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.settings.KeySetting;
import me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame;
import me.retucio.sputnik.ui.widgets.panels.settings.ClientSettingsPanel;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.KeyUtil;
import net.minecraft.client.input.KeyInput;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.command.CommandSource;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.ChatFormatting;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.chat.Component;
import javax.swing.text.JTextComponent;
import java.util.ArrayList;
import java.util.List;
@@ -29,19 +28,20 @@ public class BindCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder
.then(argument("módulo", ModuleArgumentType.INSTANCE)
.executes(ctx -> {
Module module = ctx.getArgument("módulo", Module.class);
listeningModule = module;
ChatUtil.info("presiona una tecla para asignarla al módulo " + Formatting.GREEN + module.getName());
ChatUtil.info("presiona una tecla para asignarla al módulo " + ChatFormatting.GREEN + module.getName());
return SUCCESS;
})
.then(literal("reset").executes(ctx -> {
Module module = ctx.getArgument("módulo", Module.class);
module.getBind().reset();
ChatUtil.info("tecla para el módulo " + Formatting.GREEN + module.getName() + " restablecida a " + Formatting.AQUA + KeyUtil.getKeyName(module.getKey()));
ChatUtil.info("tecla para el módulo " + ChatFormatting.GREEN + module.getName()
+ " restablecida a " + ChatFormatting.AQUA + KeyUtil.getKeyName(module.getKey()));
return SUCCESS;
}))
);
@@ -51,17 +51,17 @@ public class BindCommand extends Command {
if (listeningModule == null) return false;
KeySetting bind = listeningModule.getBind();
if (ClientSettingsFrame.guiSettings.multipleKeybinds.getValue()) {
List<KeyBinding> keys = new ArrayList<>(List.of(mc.options.allKeys));
if (ClientSettingsPanel.clientSettings.multipleKeybinds.getValue()) {
List<KeyMapping> keys = new ArrayList<>(List.of(mc.options.keyMappings));
keys.removeAll(List.of(mc.options.debugKeys));
for (KeyBinding kb : keys) {
boolean keyAlreadyBound = kb.matchesKey(new KeyInput(key, 0, 0));
boolean allowMultiple = ClientSettingsFrame.guiSettings.multipleKeybinds.getValue();
for (KeyMapping kb : keys) {
boolean keyAlreadyBound = kb.matches(new KeyEvent(key, 0, 0));
boolean allowMultiple = ClientSettingsPanel.clientSettings.multipleKeybinds.getValue();
if (keyAlreadyBound && !allowMultiple) {
ChatUtil.warn("esa tecla ya está cogida por "
+ Formatting.GREEN + "\"" + I18n.translate(kb.getId()) + "\"");
+ ChatFormatting.GREEN + "\"" + I18n.get(kb.getName() + "\""));
listeningModule = null;
return true;
}
@@ -71,8 +71,8 @@ public class BindCommand extends Command {
if (bind != null) bind.setValue(key);
ChatUtil.info(
Text.of("la tecla " + Formatting.AQUA + KeyUtil.getKeyName(key) + Formatting.RESET +
" ha sido asignada al módulo " + Formatting.GREEN + listeningModule.getName())
Component.nullToEmpty("la tecla " + ChatFormatting.AQUA + KeyUtil.getKeyName(key) + ChatFormatting.RESET +
" ha sido asignada al módulo " + ChatFormatting.GREEN + listeningModule.getName())
);
listeningModule = null;
@@ -4,10 +4,10 @@ import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.command.args.EnumArgumentType;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
import net.minecraft.command.CommandSource;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.ContainerScreen;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.world.inventory.ContainerInput;
// https://cdn.discordapp.com/attachments/1456079799045980400/1457154232737206375/dupersunited-public-addon-1.21.11-3.1.3.jar?ex=69735be1&is=69720a61&hm=77fb6faee49762e0a812661f0d98931e89cb725db711c45722249d0efe3b91e4&
public class ClickSlotCommand extends Command {
@@ -16,16 +16,17 @@ public class ClickSlotCommand extends Command {
super("clickslot", "simula un clic a un slot");
}
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder.then(argument("slot", IntegerArgumentType.integer())
.then(argument("botón", IntegerArgumentType.integer())
.then(argument("acción", EnumArgumentType.enumArgument(SlotActionType.SWAP))
.then(argument("acción", EnumArgumentType.enumArgument(ContainerInput.SWAP))
.executes(context -> {
int slot = context.getArgument("slot", Integer.class), button = context.getArgument("botón", Integer.class);
SlotActionType action = context.getArgument("acción", SlotActionType.class);
Screen screen = mc.currentScreen;
int syncId = (screen instanceof GenericContainerScreen gcScreen) ? gcScreen.getScreenHandler().syncId : 0;
mc.interactionManager.clickSlot(syncId, slot, button, action, mc.player);
ContainerInput action = context.getArgument("acción", ContainerInput.class);
Screen screen = mc.screen;
int syncId = (screen instanceof ContainerScreen cScreen) ? cScreen.getMenu().containerId : 0;
if (mc.gameMode == null) return 0;
mc.gameMode.handleContainerInput(syncId, slot, button, action, mc.player);
return SUCCESS;
})
)
@@ -5,9 +5,9 @@ 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.ui.screen.ClickGui;
import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
import net.minecraft.commands.SharedSuggestionProvider;
import me.retucio.sputnik.module.Module;
public class ConfigCommand extends Command {
@@ -17,7 +17,7 @@ public class ConfigCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder
.then(argument("módulo", ModuleArgumentType.INSTANCE)
.executes(ctx -> {
@@ -38,29 +38,29 @@ public class ConfigCommand extends Command {
}
private void openSf(CommandContext<CommandSource> ctx) {
private void openSf(CommandContext<SharedSuggestionProvider> ctx) {
Module module = ctx.getArgument("módulo", Module.class);
mc.setScreen(ClickGUI.INSTANCE);
mc.setScreen(ClickGui.INSTANCE);
if (ClickGUI.INSTANCE.isSettingsFrameOpen(module)) return;
if (ClickGui.INSTANCE.isSettingsPanelOpen(module)) return;
SettingsFrame sf = ClickGUI.INSTANCE.getSfOfModule(module);
int x = mc.getWindow().getScaledWidth() / 2 - sf.getW() / 2;
SettingsPanel sf = ClickGui.INSTANCE.getSettingsPanelOfModule(module);
int x = mc.getWindow().getGuiScaledWidth() / 2 - sf.getW() / 2;
int y = 67;
ClickGUI.INSTANCE.openSettingsFrame(module, x, y);
ClickGui.INSTANCE.openSettingsPanel(module, x, y);
}
private void openSfWithPos(CommandContext<CommandSource> ctx, int x, int y) {
private void openSfWithPos(CommandContext<SharedSuggestionProvider> ctx, int x, int y) {
Module module = ctx.getArgument("módulo", Module.class);
mc.setScreen(ClickGUI.INSTANCE);
mc.setScreen(ClickGui.INSTANCE);
if (ClickGUI.INSTANCE.isSettingsFrameOpen(module)) {
SettingsFrame sf = ClickGUI.INSTANCE.getSfOfModule(module);
if (ClickGui.INSTANCE.isSettingsPanelOpen(module)) {
SettingsPanel sf = ClickGui.INSTANCE.getSettingsPanelOfModule(module);
sf.setX(x);
sf.setY(y);
}
ClickGUI.INSTANCE.openSettingsFrame(module, x, y);
ClickGui.INSTANCE.openSettingsPanel(module, x, y);
}
}
@@ -4,7 +4,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.misc.ScreenshotPlus;
import net.minecraft.command.CommandSource;
import net.minecraft.commands.SharedSuggestionProvider;
// se usa principalmente para el módulo ScreenshotPlus, pero también se puede usar sin él supongo
public class CopyScreenshotCommand extends Command {
@@ -14,7 +14,7 @@ public class CopyScreenshotCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder.executes(ctx -> {
ScreenshotPlus screenshotPlus = ModuleManager.INSTANCE.getModuleByClass(ScreenshotPlus.class);
@@ -1,12 +1,13 @@
package me.retucio.sputnik.command.commands;
import com.github.retucio.neutrino.EventListener;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.event.TickEvent;
import me.retucio.sputnik.ui.screen.PreviewScreen;
import me.retucio.sputnik.util.ChatUtil;
import me.retucio.sputnik.util.InventoryUtil;
import net.minecraft.command.CommandSource;
import net.minecraft.commands.SharedSuggestionProvider;
// accede a los contenidos de tu enderchest
public class EnderChestCommand extends Command {
@@ -18,7 +19,7 @@ public class EnderChestCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder.executes(ctx -> {
mc.execute(() -> {
if (mc.player == null) return;
@@ -34,6 +35,7 @@ public class EnderChestCommand extends Command {
});
}
@EventListener
public void onTick(TickEvent.Post event) {
if (shouldOpenEchest) {
shouldOpenEchest = false;
@@ -0,0 +1,52 @@
package me.retucio.sputnik.command.commands;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.command.args.PlayerArgumentType;
import me.retucio.sputnik.friend.Friend;
import me.retucio.sputnik.friend.FriendManager;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.world.entity.player.Player;
public class FriendCommand extends Command {
public FriendCommand() {
super("friend", "gestión de amigos", "amigo", "f");
}
@Override
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder
.then(literal("add")
.then(argument("amigo", PlayerArgumentType.INSTANCE)
.executes(ctx -> {
Player friend = ctx.getArgument("amigo", Player.class);
FriendManager.INSTANCE.add(friend.getUUID());
ChatUtil.info(ChatFormatting.GREEN + friend.getName().getString() + ChatFormatting.RESET + " ahora es tu amigo :)");
return SUCCESS;
})
)
)
.then(literal("remove")
.then(argument("amigo", PlayerArgumentType.INSTANCE)
.executes(ctx -> {
Player friend = ctx.getArgument("amigo", Player.class);
FriendManager.INSTANCE.remove(friend.getUUID());
ChatUtil.info(ChatFormatting.GREEN + friend.getName().getString() + ChatFormatting.RESET + " ya no es tu amigo :(");
return SUCCESS;
})
)
)
.then(literal("list")
.executes(ctx -> {
ChatUtil.info(ChatFormatting.GOLD + "amigos:");
for (Friend friend : FriendManager.INSTANCE.getFriends()) {
ChatUtil.info("- " + friend.getName());
}
return SUCCESS;
})
);
}
}
@@ -3,8 +3,8 @@ package me.retucio.sputnik.command.commands;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.command.CommandSource;
import net.minecraft.text.Text;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.chat.Component;
public class GarbageCleanerCommand extends Command {
@@ -13,10 +13,10 @@ public class GarbageCleanerCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder.executes(context -> {
System.gc();
ChatUtil.info(Text.of("basura recolectada"));
ChatUtil.info(Component.nullToEmpty("basura recolectada"));
return SUCCESS;
});
}
@@ -4,8 +4,8 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.command.args.PlayerArgumentType;
import me.retucio.sputnik.util.MiscUtil;
import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.command.CommandSource;
import net.minecraft.client.gui.screens.inventory.InventoryScreen;
import net.minecraft.commands.SharedSuggestionProvider;
// comando que debería de mostrar el inventario de un jugador, pero por cómo funcionan los servers, solo te deja ver el ítem que tenga en la mano
public class PeekCommand extends Command {
@@ -15,7 +15,7 @@ public class PeekCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder
.then(argument("jugador", PlayerArgumentType.INSTANCE)
.executes(ctx -> {
@@ -9,10 +9,10 @@ import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.event.network.PacketEvent;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.client.network.ClientCommandSource;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.command.CommandSource;
import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.multiplayer.ClientSuggestionProvider;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.protocol.game.ClientboundCommandsPacket;
import java.util.HashSet;
import java.util.Set;
@@ -28,9 +28,9 @@ public class PluginsCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder.executes(context -> {
if (mc.isIntegratedServerRunning()) {
if (mc.hasSingleplayerServer()) {
ChatUtil.error("estás en un solo jugador");
return SUCCESS;
}
@@ -51,12 +51,12 @@ public class PluginsCommand extends Command {
private void findNamespaces() {
try {
ClientPlayNetworkHandler networkHandler = mc.getNetworkHandler();
if (networkHandler == null || networkHandler.getCommandDispatcher() == null) {
ClientPacketListener networkHandler = mc.getConnection();
if (networkHandler == null) {
return;
}
RootCommandNode<ClientCommandSource> root = networkHandler.getCommandDispatcher().getRoot();
RootCommandNode<ClientSuggestionProvider> root = networkHandler.getCommands().getRoot();
root.getChildren().forEach(this::checkNodeForPlugins);
if (!plugins.isEmpty()) {
@@ -73,7 +73,7 @@ public class PluginsCommand extends Command {
}
}
private void checkNodeForPlugins(CommandNode<ClientCommandSource> node) {
private void checkNodeForPlugins(CommandNode<ClientSuggestionProvider> node) {
String name = node.getName();
if (name.contains(":")) {
@@ -92,7 +92,7 @@ public class PluginsCommand extends Command {
private void onPacketReceive(PacketEvent.Receive event) {
if (!scanning) return;
if (event.getPacket() instanceof CommandTreeS2CPacket) {
if (event.getPacket() instanceof ClientboundCommandsPacket) {
findNamespaces();
}
}
@@ -3,11 +3,11 @@ package me.retucio.sputnik.command.commands;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame;
import me.retucio.sputnik.ui.widgets.panels.settings.ClientSettingsPanel;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.command.CommandSource;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.chat.Component;
// también se puede hacer desde los ajustes de la interfaz
public class PrefixCommand extends Command {
@@ -17,12 +17,12 @@ public class PrefixCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder
.then(argument("prefijo", StringArgumentType.word()).executes(ctx -> {
String prefix = ctx.getArgument("prefijo", String.class);
ClientSettingsFrame.guiSettings.commandPrefix.setValue(prefix);
ChatUtil.info(Text.literal("prefijo cambiado a " + Formatting.AQUA + prefix));
ClientSettingsPanel.clientSettings.commandPrefix.setValue(prefix);
ChatUtil.info(Component.literal("prefijo cambiado a " + ChatFormatting.AQUA + prefix));
return SUCCESS;
}));
}
@@ -3,10 +3,10 @@ package me.retucio.sputnik.command.commands;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.util.interfaces.IChatHud;
import net.minecraft.client.gui.hud.ChatHud;
import net.minecraft.client.gui.hud.ChatHudLine;
import net.minecraft.command.CommandSource;
import me.retucio.sputnik.util.interfaces.IChatComponent;
import net.minecraft.client.gui.components.ChatComponent;
import net.minecraft.client.multiplayer.chat.GuiMessage;
import net.minecraft.commands.SharedSuggestionProvider;
import java.util.List;
@@ -17,7 +17,7 @@ public class PurgeCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder.then(argument("cantidad", IntegerArgumentType.integer(1))
.executes(context -> {
int amount = IntegerArgumentType.getInteger(context, "cantidad");
@@ -28,10 +28,10 @@ public class PurgeCommand extends Command {
}
private void purgeMessages(int amount) {
ChatHud chatHud = mc.inGameHud.getChatHud();
ChatComponent chatHud = mc.gui.getChat();
synchronized (chatHud) {
List<ChatHudLine.Visible> visibleMessages = ((IChatHud) chatHud).sputnik$getVisibleMessages();
List<GuiMessage.Line> visibleMessages = ((IChatComponent) chatHud).sputnik$getVisibleMessages();
int toRemove = Math.min(amount, visibleMessages.size());
for (int i = 0; i < toRemove; i++)
visibleMessages.removeFirst();
@@ -5,7 +5,7 @@ import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.command.CommandSource;
import net.minecraft.commands.SharedSuggestionProvider;
public class RepeatCommand extends Command {
@@ -14,7 +14,7 @@ public class RepeatCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder
.then(argument("veces", IntegerArgumentType.integer(1))
.then(argument("comando", StringArgumentType.greedyString())
@@ -0,0 +1,46 @@
package me.retucio.sputnik.command.commands;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.commands.SharedSuggestionProvider;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class RepeatWaitCommand extends Command {
public RepeatWaitCommand() {
super("repesperar", "combinación de $repetir y $esperar");
}
@Override
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder.then(argument("ms", IntegerArgumentType.integer(1))
.then(argument("veces", IntegerArgumentType.integer(1))
.then(argument("comando", StringArgumentType.greedyString())
.executes((context) -> {
int ms = context.getArgument("ms", Integer.class);
int times = context.getArgument("veces", Integer.class);
String cmd = context.getArgument("comando", String.class);
for (int i = 0; i < times; i++) {
int delay = i * ms;
int finalI = i;
new ScheduledThreadPoolExecutor(2).schedule(
() -> ChatUtil.info(
cmd.replaceAll("(?i)%index%",
String.valueOf(finalI))),
delay,
TimeUnit.MILLISECONDS
);
}
return SUCCESS;
})
)
)
);
}
}
@@ -5,7 +5,7 @@ import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.misc.ScreenshotPlus;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.command.CommandSource;
import net.minecraft.commands.SharedSuggestionProvider;
import java.io.IOException;
@@ -17,7 +17,7 @@ public class SaveScreenshotCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder.executes(ctx -> {
ScreenshotPlus screenshotPlus = ModuleManager.INSTANCE.getModuleByClass(ScreenshotPlus.class);
@@ -3,18 +3,18 @@ package me.retucio.sputnik.command.commands;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.mixin.accessors.ClientPlayNetworkHandlerAccessor;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.command.CommandSource;
import net.minecraft.network.encryption.NetworkEncryptionUtils;
import net.minecraft.network.message.LastSeenMessagesCollector;
import net.minecraft.network.message.MessageBody;
import net.minecraft.network.message.MessageSignatureData;
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
import me.retucio.sputnik.mixin.accessors.ClientPacketListenerAccessor;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.network.chat.LastSeenMessagesTracker;
import net.minecraft.network.chat.MessageSignature;
import net.minecraft.network.chat.SignedMessageBody;
import net.minecraft.network.protocol.game.ServerboundChatPacket;
import net.minecraft.util.Crypt;
import java.time.Instant;
// uso principal: protección de coordenadas de ChatPlus, que ni siquiera funciona
// uso principal: protección de coordenadas de ChatPlus
public class SendCommand extends Command {
public SendCommand() {
@@ -22,31 +22,35 @@ public class SendCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder.then(argument("message", StringArgumentType.greedyString()).executes(context -> {
String message = context.getArgument("message", String.class);
if (message != null && !message.isEmpty()) {
Instant instant = Instant.now();
long salt = NetworkEncryptionUtils.SecureRandomUtil.nextLong();
ClientPlayNetworkHandler handler = mc.getNetworkHandler();
long salt = Crypt.SaltSupplier.getLong();
ClientPacketListener handler = mc.getConnection();
// obtener últimos mensajes vistos para la firma
LastSeenMessagesCollector.LastSeenMessages lastSeenMessages =
((ClientPlayNetworkHandlerAccessor) handler).getLastSeenMessagesCollector().collect();
ClientPacketListenerAccessor listener = ((ClientPacketListenerAccessor) handler);
if (listener == null) return 0;
LastSeenMessagesTracker tracker = ((ClientPacketListenerAccessor) handler).getLastSeenMessagesTracker();
LastSeenMessagesTracker.Update lastSeenMessages = tracker.generateAndApplyUpdate();
// empacar firma para un chat seguro
MessageSignatureData messageSignatureData =
((ClientPlayNetworkHandlerAccessor) handler).getMessagePacker().pack(
new MessageBody(message, instant, salt, lastSeenMessages.lastSeen())
);
MessageSignature messageSignature = ((ClientPacketListenerAccessor) handler)
.getSignedMessageEncoder()
.pack(new SignedMessageBody(
message, instant, salt, lastSeenMessages.lastSeen()
)
);
// enviar paquete para enviar mensaje
handler.sendPacket(new ChatMessageC2SPacket(
handler.send(new ServerboundChatPacket(
message,
instant,
salt,
messageSignatureData,
messageSignature,
lastSeenMessages.update()
));
}
@@ -1,12 +1,13 @@
package me.retucio.sputnik.command.commands;
import com.github.retucio.neutrino.EventListener;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.command.args.EntityArgumentType;
import me.retucio.sputnik.event.input.KeyEvent;
import me.retucio.sputnik.util.EntityUtil;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.world.entity.Entity;
import org.lwjgl.glfw.GLFW;
public class SpectateCommand extends Command {
@@ -16,7 +17,7 @@ public class SpectateCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder
.executes(ctx -> { // If no argument, use the entity player is looking at
mc.execute(() -> {
@@ -37,8 +38,9 @@ public class SpectateCommand extends Command {
);
}
@EventListener
public void onKey(KeyEvent event) {
if (mc.getCameraEntity() != mc.player && mc.currentScreen == null
if (mc.getCameraEntity() != mc.player && mc.screen == null
&& event.getKey() == GLFW.GLFW_KEY_ESCAPE && event.getAction() != GLFW.GLFW_RELEASE ) {
event.cancel();
mc.setCameraEntity(mc.player);
@@ -5,7 +5,7 @@ import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.command.args.ModuleArgumentType;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
import net.minecraft.command.CommandSource;
import net.minecraft.commands.SharedSuggestionProvider;
// porque usar el ratón es más lento que escribir, a menos que tengas toque con el teclado como yo
public class ToggleCommand extends Command {
@@ -15,7 +15,7 @@ public class ToggleCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder
.then(literal("todos")
.then(literal("on")
@@ -3,12 +3,9 @@ package me.retucio.sputnik.command.commands;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import me.retucio.sputnik.command.Command;
import me.retucio.sputnik.command.CommandManager;
import me.retucio.sputnik.ui.widgets.frames.settings.ClientSettingsFrame;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.command.CommandSource;
import net.minecraft.commands.SharedSuggestionProvider;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -23,18 +20,18 @@ public class WaitCommand extends Command {
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder) {
public void build(LiteralArgumentBuilder<SharedSuggestionProvider> builder) {
builder
.then(argument("delay", IntegerArgumentType.integer(0))
.then(argument("comando", StringArgumentType.greedyString())
.executes(ctx -> {
int delay = ctx.getArgument("delay", Integer.class);
String command = ctx.getArgument("comando", String.class);
.then(argument("delay", IntegerArgumentType.integer(0))
.then(argument("comando", StringArgumentType.greedyString())
.executes(ctx -> {
int delay = ctx.getArgument("delay", Integer.class);
String command = ctx.getArgument("comando", String.class);
DELAYED_EXECUTOR.schedule(() -> ChatUtil.simulateChatMessage(command), delay, TimeUnit.MILLISECONDS);
return SUCCESS;
})
)
);
DELAYED_EXECUTOR.schedule(() -> ChatUtil.simulateChatMessage(command), delay, TimeUnit.MILLISECONDS);
return SUCCESS;
})
)
);
}
}
@@ -2,13 +2,17 @@ package me.retucio.sputnik.config;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BinarySerializer {
private static final int MAGIC_NUMBER = 0x53505554; // "SPUT"
private static final int VERSION = 1;
private static final int MAGIC_NUMBER = 0x53505554; // "SPUT"
private static final int VERSION = 2;
private static final byte TYPE_NULL = 0;
private static final byte TYPE_BOOLEAN = 1;
@@ -19,32 +23,60 @@ public class BinarySerializer {
private static final byte TYPE_INT_ARRAY = 6;
private static final byte TYPE_FRAME_DATA = 7;
public static void writeConfig(ClientConfig config, File file)
throws IOException {
try (DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(file)))) {
public static void writeConfig(ClientConfig config, File file) throws IOException {
byte[] bytes = toBytes(config);
writeBytes(bytes, file);
}
// cabezal
out.writeInt(MAGIC_NUMBER);
out.writeInt(VERSION);
// serializar a bytes en memoria
public static byte[] toBytes(ClientConfig config) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (DataOutputStream out = new DataOutputStream(baos)) {
writeConfigTo(config, out);
}
return baos.toByteArray();
}
// mapas
writeStringBooleanMap(out, config.moduleStates);
writeSettingsMap(out, config.settings);
writeStringIntArrayMap(out, config.settingsFrames);
writeExtendableFrames(out, config.extendableFrames);
writeStringIntArrayMap(out, config.hudPositions);
writeStringBooleanMap(out, config.hudVisibilities);
writeStringStringMap(out, config.hudImagePaths);
// escribir bytes a disco (puede llamarse desde un hilo de fondo)
public static void writeBytes(byte[] bytes, File file) throws IOException {
// escribir a archivo temporal primero para evitar corrupción si el proceso muere a mitad
File temp = new File(file.getParent(), file.getName() + ".tmp");
try (FileOutputStream fos = new FileOutputStream(temp);
BufferedOutputStream out = new BufferedOutputStream(fos)) {
out.write(bytes);
out.flush();
fos.getFD().sync(); // forzar flush al disco antes de renombrar
}
// posición de la barra de búsqueda
if (config.searchBarPosition != null) {
out.writeBoolean(true);
out.writeInt(config.searchBarPosition[0]);
out.writeInt(config.searchBarPosition[1]);
} else {
out.writeBoolean(false);
}
// renombrar atómicamente
if (!temp.renameTo(file)) {
// renameTo puede fallar entre sistemas de archivos distintos
Files.move(temp.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
// lógica de serialización compartida
private static void writeConfigTo(ClientConfig config, DataOutputStream out) throws IOException {
// cabezal
out.writeInt(MAGIC_NUMBER);
out.writeInt(VERSION);
// el resto
writeStringBooleanMap(out, config.moduleStates);
writeSettingsMap(out, config.settings);
writeStringIntArrayMap(out, config.settingsPanels);
writeExtendableFrames(out, config.extendablePanels);
writeStringIntArrayMap(out, config.hudPositions);
writeStringBooleanMap(out, config.hudVisibilities);
writeStringStringMap(out, config.hudImagePaths);
writeStringStringMap(out, config.friends);
if (config.searchBarPosition != null) {
out.writeBoolean(true);
out.writeInt(config.searchBarPosition[0]);
out.writeInt(config.searchBarPosition[1]);
} else {
out.writeBoolean(false);
}
}
@@ -77,11 +109,12 @@ public class BinarySerializer {
// leer mapas
config.moduleStates = readStringBooleanMap(in);
config.settings = readSettingsMap(in);
config.settingsFrames = readStringIntArrayMap(in);
config.extendableFrames = readExtendableFrames(in);
config.settingsPanels = readStringIntArrayMap(in);
config.extendablePanels = readExtendablePanels(in);
config.hudPositions = readStringIntArrayMap(in);
config.hudVisibilities = readStringBooleanMap(in);
config.hudImagePaths = readStringStringMap(in);
config.friends = readStringStringMap(in);
// leer pos. de la barra de búsqueda
if (in.readBoolean()) {
@@ -281,32 +314,31 @@ public class BinarySerializer {
return map;
}
private static void writeExtendableFrames(DataOutputStream out, Map<String, ClientConfig.FrameData> map)
private static void writeExtendableFrames(DataOutputStream out, Map<String, ClientConfig.PanelData> map)
throws IOException {
if (map == null) {
out.writeInt(0);
return;
}
out.writeInt(map.size());
for (Map.Entry<String, ClientConfig.FrameData> entry : map.entrySet()) {
for (Map.Entry<String, ClientConfig.PanelData> entry : map.entrySet()) {
writeString(out, entry.getKey());
ClientConfig.FrameData data = entry.getValue();
ClientConfig.PanelData data = entry.getValue();
out.writeInt(data.x());
out.writeInt(data.y());
out.writeBoolean(data.extended());
}
}
private static Map<String, ClientConfig.FrameData> readExtendableFrames(DataInputStream in)
throws IOException {
private static Map<String, ClientConfig.PanelData> readExtendablePanels(DataInputStream in) throws IOException {
int size = in.readInt();
Map<String, ClientConfig.FrameData> map = new HashMap<>(size);
Map<String, ClientConfig.PanelData> map = new HashMap<>(size);
for (int i = 0; i < size; i++) {
String key = readString(in);
int x = in.readInt();
int y = in.readInt();
boolean extended = in.readBoolean();
map.put(key, new ClientConfig.FrameData(x, y, extended));
map.put(key, new ClientConfig.PanelData(x, y, extended));
}
return map;
}
@@ -336,7 +368,6 @@ public class BinarySerializer {
return map;
}
// Optimized string writing (UTF-8 with length prefix)
private static void writeString(DataOutputStream out, String str) throws IOException {
if (str == null) {
out.writeInt(-1);
@@ -352,6 +383,6 @@ public class BinarySerializer {
if (length == -1) return null;
byte[] bytes = new byte[length];
in.readFully(bytes);
return new String(bytes, "UTF-8");
return new String(bytes, StandardCharsets.UTF_8);
}
}
@@ -1,12 +1,17 @@
package me.retucio.sputnik.config;
import com.github.retucio.neutrino.EventListener;
import me.retucio.sputnik.event.sputnik.*;
import me.retucio.sputnik.module.setting.settings.*;
import me.retucio.sputnik.ui.screen.ClickGUI;
import me.retucio.sputnik.ui.screen.ClickGui;
import me.retucio.sputnik.ui.widgets.panels.FriendsPanel;
import me.retucio.sputnik.util.ChatUtil;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static me.retucio.sputnik.Sputnik.EVENT_BUS;
@@ -22,10 +27,10 @@ public class ClientConfig {
public Map<String, Object> settings = new HashMap<>();
// nombre del módulo -> posición (x, y)
public Map<String, int[]> settingsFrames = new HashMap<>();
public Map<String, int[]> settingsPanels = new HashMap<>();
// nombre del frame -> FrameData (que contiene extended, x & y)
public Map<String, FrameData> extendableFrames = new HashMap<>();
public Map<String, PanelData> extendablePanels = new HashMap<>();
// id del elemento del hud -> posición (x, y)
public Map<String, int[]> hudPositions = new HashMap<>();
@@ -33,21 +38,26 @@ public class ClientConfig {
// id del elemento del hud -> true: visible / false: no visible
public Map<String, Boolean> hudVisibilities = new HashMap<>();
// id del elemento del hud -> ruta de la imagen (NEW)
// id del elemento del hud -> ruta de la imagen
public Map<String, String> hudImagePaths = new HashMap<>();
// posición de la barra de búsqueda (x, y)
public int[] searchBarPosition = new int[] { 340, 16 };
// amigos: uuid -> nombre
public Map<String, String> friends = new HashMap<>();
public ClientConfig() {
EVENT_BUS.subscribe(this);
}
@EventListener
public void onToggleModule(ToggleModuleEvent event) {
ConfigManager.setModuleState(event.getModule());
ConfigManager.INSTANCE.setModuleState(event.getModule());
}
@SuppressWarnings("rawtypes")
@EventListener
public void onUpdateSetting(UpdateSettingEvent event) {
if (mc == null || !event.shouldSave()) return;
@@ -65,52 +75,97 @@ public class ClientConfig {
default: break;
}
ConfigManager.setSetting(event.getSetting(), value);
ConfigManager.INSTANCE.setSetting(event.getSetting(), value);
}
public void onOpenSettingsFrame(SettingsFrameEvent.Open event) {
ConfigManager.setFramePosition(event.getFrame());
@EventListener
public void onOpenSettingsPanel(SettingsPanelEvent.Open event) {
ConfigManager.INSTANCE.setPanelPosition(event.getPanel());
}
public void onCloseSettingsFrame(SettingsFrameEvent.Close event) {
settingsFrames.remove(event.getFrame().getModule().getName());
ConfigManager.save();
@EventListener
public void onCloseSettingsPanel(SettingsPanelEvent.Close event) {
settingsPanels.remove(event.getPanel().getModule().getName());
ConfigManager.INSTANCE.markDirty();
}
public void onMoveSettingsFrame(SettingsFrameEvent.Move event) {
settingsFrames.replace(event.getFrame().getModule().getName(), new int[]{event.getFrame().getX(), event.getFrame().getY()});
ConfigManager.save();
@EventListener
public void onMoveSettingsPanel(SettingsPanelEvent.Move event) {
settingsPanels.replace(event.getPanel().getModule().getName(), new int[]{event.getPanel().getX(), event.getPanel().getY()});
ConfigManager.INSTANCE.markDirty();
}
public void onExtendModuleFrame(ModuleFrameEvent.Extend event) {
extendableFrames.put("M", new FrameData(
ClickGUI.INSTANCE.getModulesFrame().getX(),
ClickGUI.INSTANCE.getModulesFrame().getY(),
ClickGUI.INSTANCE.getModulesFrame().extended));
@EventListener
public void onExtendModulePanel(ModulePanelEvent.Extend event) {
extendablePanels.put(event.getPanel().category.toString(), new PanelData(
event.getPanel().getX(),
event.getPanel().getY(),
event.getPanel().isExtended()));
ConfigManager.INSTANCE.markDirty();
}
public void onMoveModuleFrame(ModuleFrameEvent.Move event) {
extendableFrames.replace("M", new FrameData(
ClickGUI.INSTANCE.getModulesFrame().getX(),
ClickGUI.INSTANCE.getModulesFrame().getY(),
ClickGUI.INSTANCE.getModulesFrame().extended));
@EventListener
public void onMoveModulePanel(ModulePanelEvent.Move event) {
extendablePanels.replace(event.getPanel().category.toString(), new PanelData(
event.getPanel().getX(),
event.getPanel().getY(),
event.getPanel().isExtended()));
ConfigManager.INSTANCE.markDirty();
}
public void onExtendGUISettingsFrame(GUISettingsFrameEvent.Extend event) {
extendableFrames.put("S", new FrameData(
ClickGUI.INSTANCE.getGuiSettingsFrame().getX(),
ClickGUI.INSTANCE.getGuiSettingsFrame().getY(),
ClickGUI.INSTANCE.getGuiSettingsFrame().extended));
@EventListener
public void onExtendClientSettingsPanel(ClientSettingsPanelEvent.Extend event) {
extendablePanels.put("ajustes", new PanelData(
ClickGui.INSTANCE.getClientSettingsPanel().getX(),
ClickGui.INSTANCE.getClientSettingsPanel().getY(),
ClickGui.INSTANCE.getClientSettingsPanel().isExtended()));
ConfigManager.INSTANCE.markDirty();
}
public void onMoveGUISettingsFrame(GUISettingsFrameEvent.Move event) {
extendableFrames.replace("S", new FrameData(
ClickGUI.INSTANCE.getGuiSettingsFrame().getX(),
ClickGUI.INSTANCE.getGuiSettingsFrame().getY(),
ClickGUI.INSTANCE.getGuiSettingsFrame().extended));
@EventListener
public void onMoveClientSettingsPanel(ClientSettingsPanelEvent.Move event) {
extendablePanels.replace("ajustes", new PanelData(
ClickGui.INSTANCE.getClientSettingsPanel().getX(),
ClickGui.INSTANCE.getClientSettingsPanel().getY(),
ClickGui.INSTANCE.getClientSettingsPanel().isExtended()));
ConfigManager.INSTANCE.markDirty();
}
public record FrameData(int x, int y, boolean extended) implements Serializable {
@EventListener
public void onExtendFriendsPanel(FriendPanelEvent.Extend event) {
extendablePanels.put("amigos", new PanelData(
ClickGui.INSTANCE.getFriendsPanel().getX(),
ClickGui.INSTANCE.getFriendsPanel().getY(),
ClickGui.INSTANCE.getFriendsPanel().isExtended()));
ConfigManager.INSTANCE.markDirty();
}
@EventListener
public void onMoveFriendsPanel(FriendPanelEvent.Move event) {
extendablePanels.replace("amigos", new PanelData(
ClickGui.INSTANCE.getFriendsPanel().getX(),
ClickGui.INSTANCE.getFriendsPanel().getY(),
ClickGui.INSTANCE.getFriendsPanel().isExtended()));
ConfigManager.INSTANCE.markDirty();
}
@EventListener
public void onAddFriend(FriendEvent.Add event) {
String uuid = event.getFriend().getUuid().toString();
String name = event.getFriend().getName();
if (!friends.containsKey(uuid)) {
friends.put(uuid, name);
}
ConfigManager.INSTANCE.markDirty();
}
@EventListener
public void onRemoveFriend(FriendEvent.Remove event) {
friends.remove(event.getFriend().getUuid().toString());
ConfigManager.INSTANCE.markDirty();
}
public record PanelData(int x, int y, boolean extended) implements Serializable {
@Serial private static final long serialVersionUID = 1L;
}
}
@@ -3,21 +3,32 @@ package me.retucio.sputnik.config;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.friend.Friend;
import me.retucio.sputnik.friend.FriendManager;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.client.ClientSettingsModule;
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.ui.hud.HudRenderer;
import me.retucio.sputnik.ui.widgets.Panel;
import me.retucio.sputnik.ui.widgets.panels.FriendsPanel;
import me.retucio.sputnik.ui.widgets.panels.ModulePanel;
import me.retucio.sputnik.ui.screen.ClickGui;
import me.retucio.sputnik.ui.widgets.panels.settings.ClientSettingsPanel;
import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
import me.retucio.sputnik.util.ChatUtil;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
// se ocupa de guardar, cargar y aplicar ajustes
@@ -26,26 +37,70 @@ public class ConfigManager {
private static final File CONFIG_FILE = new File("sputnik.dat");
private static final File LEGACY_JSON_FILE = new File("sputnik.json");
private static boolean loaded = false;
private static ClientConfig config = null;
public static ConfigManager INSTANCE;
private boolean loaded = false;
private boolean dirty = false;
private long lastDirtyTime = 0L;
private ClientConfig config = null;
private final ExecutorService saveExecutor = Executors.newSingleThreadExecutor(r -> {
Thread t = new Thread(r, "sputnik-config-save");
t.setDaemon(true); // no bloquear el cierre de la JVM
return t;
});
private final AtomicBoolean saveQueued = new AtomicBoolean(false);
// ------------------ MÉTODOS PRINCIPALES ------------------
// guardar configuraciones
public static void save() {
public void save() {
if (!loaded) return;
ensureConfig();
// serializar a bytes en el hilo principal (snapshot inmediato, evita race conditions)
final byte[] snapshot;
try {
BinarySerializer.writeConfig(config, CONFIG_FILE);
Sputnik.LOGGER.info("ajustes guardados");
snapshot = BinarySerializer.toBytes(config);
} catch (IOException e) {
Sputnik.LOGGER.error("error al guardar ajustes", e);
Sputnik.LOGGER.error("error al serializar ajustes", e);
return;
}
// si ya hay un guardado en cola, no añadir otro
if (!saveQueued.compareAndSet(false, true)) return;
saveExecutor.execute(() -> {
try {
BinarySerializer.writeBytes(snapshot, CONFIG_FILE);
Sputnik.LOGGER.info("ajustes guardados");
} catch (IOException e) {
Sputnik.LOGGER.error("error al guardar ajustes", e);
} finally {
saveQueued.set(false);
}
});
}
public static void load() {
public void saveOnShutdown() {
// esperar a que termine cualquier guardado en curso, luego guardar síncronamente
saveExecutor.shutdown();
try {
// dar hasta 5 segundos para que termine el guardado en curso
if (!saveExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
Sputnik.LOGGER.warn("el hilo de guardado no terminó a tiempo");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// guardado final sincrónico por si había cambios pendientes no guardados
if (dirty) save();
}
public void load() {
Sputnik.LOGGER.info("cargando ajustes...");
if (CONFIG_FILE.exists()) {
@@ -58,7 +113,7 @@ public class ConfigManager {
}
}
// Fallback to legacy JSON
// fallback to legacy JSON
if (LEGACY_JSON_FILE.exists()) {
try (FileReader reader = new FileReader(LEGACY_JSON_FILE)) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
@@ -78,22 +133,23 @@ public class ConfigManager {
}
// aplicar configuraciones cargadas
public static void applyConfig() {
public void applyConfig() {
if (!shouldApply()) return;
applyModuleStates();
applyModuleSettings();
applySettingsFrames();
applySettingsPanels();
applySearchBarPosition();
applyGuiSettings();
applyExtendableFrames();
applyClientSettings();
applyExtendablePanels();
applyFriends();
loaded = true;
Sputnik.LOGGER.info("ajustes aplicados");
}
// obtener configuración actual
public static ClientConfig getConfig() {
public ClientConfig getConfig() {
ensureConfig();
return config;
}
@@ -101,56 +157,65 @@ public class ConfigManager {
// ------------------ GUARDAR VALORES INDIVIDUALES EN LA CONFIG. ------------------
public static void setModuleState(Module module) {
public void setModuleState(Module module) {
ensureConfig();
config.moduleStates.put(module.getName(), module.isEnabled());
save();
markDirty();
}
public static void setSetting(Setting<?> setting, Object value) {
public void setSetting(Setting<?> setting, Object value) {
ensureConfig();
config.settings.put(getSettingKey(setting), value);
save();
markDirty();
}
public static void setFramePosition(SettingsFrame frame) {
public void setPanelPosition(SettingsPanel panel) {
ensureConfig();
if (!config.settingsFrames.containsKey(frame.getModule().getName()))
config.settingsFrames.put(frame.getModule().getName(), new int[] {frame.getX(), frame.getY()});
if (!config.settingsPanels.containsKey(panel.getModule().getName()))
config.settingsPanels.put(panel.getModule().getName(), new int[] {panel.getX(), panel.getY()});
else
config.settingsFrames.replace(frame.getModule().getName(), new int[] {frame.getX(), frame.getY()});
save();
config.settingsPanels.replace(panel.getModule().getName(), new int[] {panel.getX(), panel.getY()});
markDirty();
}
public static void setExtendableFrame(String key, ClientConfig.FrameData data) {
public void setExtendablePanel(String key, ClientConfig.PanelData data) {
ensureConfig();
config.extendableFrames.put(key, data);
save();
config.extendablePanels.put(key, data);
markDirty();
}
public static void setHudPosition(String id, int x, int y) {
public void setHudPosition(String id, int x, int y) {
ensureConfig();
config.hudPositions.put(id, new int[] {x, y});
save();
markDirty();
}
public static void setHudVisibility(String id, Boolean visible) {
public void setHudVisibility(String id, Boolean visible) {
ensureConfig();
config.hudVisibilities.put(id, visible);
save();
markDirty();
}
public static void setSearchBarPosition(int x, int y) {
public void setSearchBarPosition(int x, int y) {
ensureConfig();
config.searchBarPosition = new int[] {x, y};
save();
markDirty();
}
// ------------------ APLICAR AJUSTES ------------------
public void applyFriends() {
config.friends.forEach((uuid, name) -> {
Friend friend = new Friend(UUID.fromString(uuid));
friend.setName(name);
FriendManager.INSTANCE.add(friend);
});
Sputnik.LOGGER.info("amigos aplicados");
}
@SuppressWarnings({"rawtypes", "unchecked"})
public static void applySetting(Module parent, Setting<?> setting) {
public void applySetting(Setting<?> setting) {
String key = getSettingKey(setting);
if (!config.settings.containsKey(key)) return;
@@ -170,7 +235,7 @@ public class ConfigManager {
}
}
private static void applyModuleStates() {
private void applyModuleStates() {
ModuleManager.INSTANCE.getModules().forEach(module -> {
if (config.moduleStates.containsKey(module.getName())) {
module.setEnabled(config.moduleStates.get(module.getName()));
@@ -179,15 +244,15 @@ public class ConfigManager {
Sputnik.LOGGER.info("estados de módulos aplicados");
}
private static void applyModuleSettings() {
private void applyModuleSettings() {
ModuleManager.INSTANCE.getModules().forEach(module -> {
module.getSettings().forEach(setting -> applySetting(module, setting));
module.getSettings().forEach(this::applySetting);
});
Sputnik.LOGGER.info("ajustes de módulos aplicados");
}
private static void applySettingsFrames() {
config.settingsFrames.forEach((moduleName, position) -> {
private void applySettingsPanels() {
config.settingsPanels.forEach((moduleName, position) -> {
Module module = ModuleManager.INSTANCE.getModuleByName(moduleName);
if (module == null) {
@@ -195,52 +260,63 @@ public class ConfigManager {
return;
}
ClickGUI.INSTANCE.openSettingsFrame(module, position[0], position[1]);
ClickGui.INSTANCE.openSettingsPanel(module, position[0], position[1]);
});
Sputnik.LOGGER.info("estados de marcos de ajustes aplicados");
}
private static void applySearchBarPosition() {
private void applySearchBarPosition() {
if (config.searchBarPosition != null && config.searchBarPosition.length == 2) {
ClickGUI.INSTANCE.getSearchBar().setX(config.searchBarPosition[0]);
ClickGUI.INSTANCE.getSearchBar().setY(config.searchBarPosition[1]);
ClickGui.INSTANCE.getSearchBar().setX(config.searchBarPosition[0]);
ClickGui.INSTANCE.getSearchBar().setY(config.searchBarPosition[1]);
}
Sputnik.LOGGER.info("posición de la barra de búsqueda aplicada");
}
private static void applyGuiSettings() {
ClientSettingsFrame.guiSettings.setEnabled(true);
ClientSettingsFrame.guiSettings.getSettings().forEach(setting -> {
applySetting(ClientSettingsFrame.guiSettings, setting);
});
private void applyClientSettings() {
ClientSettingsPanel.clientSettings.setEnabled(true);
ClientSettingsPanel.clientSettings.getSettings().forEach(this::applySetting);
Sputnik.LOGGER.info("ajustes del cliente aplicados");
}
private static void applyExtendableFrames() {
applyExtendableFrame(ClickGUI.INSTANCE.getModulesFrame());
applyExtendableFrame(ClickGUI.INSTANCE.getGuiSettingsFrame());
private void applyExtendablePanels() {
for (ModulePanel panel : ClickGui.INSTANCE.getModulePanels()) {
applyExtendablePanel(panel);
}
applyExtendablePanel(ClickGui.INSTANCE.getClientSettingsPanel());
applyExtendablePanel(ClickGui.INSTANCE.getFriendsPanel());
Sputnik.LOGGER.info("posiciones de marcos extendibles aplicadas");
ClickGUI.INSTANCE.refreshListButtons();
ClickGui.INSTANCE.refreshListButtons();
}
private static void applyExtendableFrame(Frame<?> frame) {
ClientConfig.FrameData frameData = null;
if (frame instanceof ModuleFrame)
frameData = config.extendableFrames.get("M");
private void applyExtendablePanel(Panel<?> panel) {
ClientConfig.PanelData panelData = null;
if (frame instanceof ClientSettingsFrame)
frameData = config.extendableFrames.get("S");
if (panel instanceof ModulePanel mp) {
panelData = config.extendablePanels.get(mp.category.toString());
}
if (panel instanceof ClientSettingsPanel) {
panelData = config.extendablePanels.get("ajustes");
}
if (panel instanceof FriendsPanel) {
panelData = config.extendablePanels.get("amigos");
}
if (frameData != null) {
frame.setX(frameData.x());
frame.setY(frameData.y());
if (panelData != null) {
panel.setX(panelData.x());
panel.setY(panelData.y());
if (frame instanceof ModuleFrame mFrame)
mFrame.extended = frameData.extended();
if (frame instanceof ClientSettingsFrame sFrame)
sFrame.extended = frameData.extended();
if (panel instanceof ModulePanel mPanel) {
mPanel.setExtended(panelData.extended());
}
if (panel instanceof ClientSettingsPanel sPanel) {
sPanel.setExtended(panelData.extended());
}
if (panel instanceof FriendsPanel fPanel) {
fPanel.setExtended(panelData.extended());
}
}
}
@@ -334,19 +410,42 @@ public class ConfigManager {
// ------------------ MÉTODOS DE AYUDA ------------------
private static boolean shouldApply() {
return Sputnik.mc != null && ModuleManager.INSTANCE != null && config != null;
}
private static void ensureConfig() {
if (config == null) config = new ClientConfig();
}
private static String getSettingKey(Setting<?> setting) {
return setting.getSg().getModule().getName() + ":" + setting.getTrueName();
}
public static boolean hasLoaded() {
private boolean shouldApply() {
return Sputnik.mc != null && ModuleManager.INSTANCE != null && config != null;
}
private void ensureConfig() {
if (config == null) config = new ClientConfig();
}
public boolean hasLoaded() {
return loaded;
}
public void markDirty() {
this.dirty = true;
this.lastDirtyTime = System.currentTimeMillis();
}
public boolean isDirty() {
return dirty;
}
public void tickAutosave() {
if (!loaded || !dirty) return;
ClientSettingsModule settings = ClientSettingsPanel.clientSettings;
if (!settings.autosave.getValue()) return;
long intervalMs = (long) (settings.autosaveInterval.getValue() * 1000);
if (System.currentTimeMillis() - lastDirtyTime < intervalMs) return;
HudRenderer.INSTANCE.pushNotification("autoguardando...", "guardando configuración...");
save();
dirty = false;
}
}
@@ -1,11 +1,11 @@
package me.retucio.sputnik.event;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftClientMixin;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftMixin;
/**
* @see MinecraftClientMixin#onStop
* @see MinecraftMixin#onStop
*/
public class ShutdownEvent extends Event {
@@ -1,12 +1,12 @@
package me.retucio.sputnik.event;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftClientMixin;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftMixin;
/**
* @see MinecraftClientMixin#onTickPre
* @see MinecraftClientMixin#onTickPost
* @see MinecraftMixin#onTickPre
* @see MinecraftMixin#onTickPost
*/
public class TickEvent {
@@ -1,12 +1,14 @@
package me.retucio.sputnik.event.input;
import me.retucio.sputnik.module.modules.misc.ChatPlus;
import net.minecraft.text.ClickEvent;
import net.minecraft.network.chat.ClickEvent;
import org.jspecify.annotations.NonNull;
/** este evento es solo para asegurarse de que comandos del mod se puedan ejecutar solo desde el lado del cliente
* @see ChatPlus#getSendButton
*/
public class ClientClickEvent implements ClickEvent {
private final String value;
@@ -20,7 +22,7 @@ public class ClientClickEvent implements ClickEvent {
}
@Override
public Action getAction() {
public @NonNull Action action() {
return Action.RUN_COMMAND;
}
@@ -1,11 +1,11 @@
package me.retucio.sputnik.event.input;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.io.KeyboardMixin;
import me.retucio.sputnik.mixin.mixins.io.KeyboardHandlerMixin;
/**
* @see KeyboardMixin#onKeyPress
* @see KeyboardHandlerMixin#onKeyPress
*/
public class KeyEvent extends Event {
@@ -1,11 +1,11 @@
package me.retucio.sputnik.event.input;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.io.MouseMixin;
import me.retucio.sputnik.mixin.mixins.io.MouseHandlerMixin;
/**
* @see MouseMixin#onMouseButton
* @see MouseHandlerMixin#onMouseButton
*/
public class MouseClickEvent extends Event {
@@ -1,11 +1,11 @@
package me.retucio.sputnik.event.input;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.io.MouseMixin;
import me.retucio.sputnik.mixin.mixins.io.MouseHandlerMixin;
/**
* @see MouseMixin#onMouseScroll
* @see MouseHandlerMixin#onMouseScroll
*/
public class MouseScrollEvent extends Event {
@@ -0,0 +1,5 @@
package me.retucio.sputnik.event.input;
import com.github.retucio.neutrino.Event;
public class SneakEvent extends Event {}
@@ -1,8 +1,8 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
public class AttackBlockEvent extends Event {
@@ -1,13 +1,14 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.player.ClientPlayerInteractionManagerMixin;
import net.minecraft.entity.Entity;
import me.retucio.sputnik.mixin.mixins.player.MultiPlayerGameModeMixin;
import net.minecraft.world.entity.Entity;
/**
* @see ClientPlayerInteractionManagerMixin#onAttackEntity
* @see MultiPlayerGameModeMixin#onAttackEntity
*/
public class AttackEntityEvent extends Event {
private final Entity entity;
@@ -1,9 +1,9 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.VoxelShape;
public class BlockShapeEvent extends Event {
@@ -1,28 +1,28 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import net.minecraft.entity.vehicle.AbstractBoatEntity;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.entity.vehicle.boat.AbstractBoat;
import net.minecraft.world.phys.Vec3;
public class BoatMoveEvent extends Event {
private final AbstractBoatEntity boat;
private Vec3d pos;
private final AbstractBoat boat;
private Vec3 pos;
public BoatMoveEvent(AbstractBoatEntity boat, Vec3d pos) {
public BoatMoveEvent(AbstractBoat boat, Vec3 pos) {
this.boat = boat;
this.pos = pos;
}
public AbstractBoatEntity getBoat() {
public AbstractBoat getBoat() {
return boat;
}
public Vec3d getPos() {
public Vec3 getPos() {
return pos;
}
public void setPos(Vec3d pos) {
public void setPos(Vec3 pos) {
this.pos = pos;
}
}
@@ -1,13 +1,14 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.player.ClientPlayerInteractionManagerMixin;
import net.minecraft.util.math.BlockPos;
import me.retucio.sputnik.mixin.mixins.player.MultiPlayerGameModeMixin;
import net.minecraft.core.BlockPos;
/**
* @see ClientPlayerInteractionManagerMixin#onBlockBreak
* @see MultiPlayerGameModeMixin#onBlockBreak
*/
public class BreakBlockEvent extends Event {
private BlockPos pos;
@@ -2,7 +2,7 @@ package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.item.ItemStackMixin;
import net.minecraft.item.ItemStack;
import net.minecraft.world.item.ItemStack;
/**
@@ -1,20 +1,21 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.player.ClientPlayerInteractionManagerMixin;
import net.minecraft.entity.Entity;
import net.minecraft.util.Hand;
import me.retucio.sputnik.mixin.mixins.player.MultiPlayerGameModeMixin;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
/**
* @see ClientPlayerInteractionManagerMixin#onEntityInteract
* @see MultiPlayerGameModeMixin#onEntityInteract
*/
public class InteractEntityEvent extends Event {
private final Entity entity;
private Hand hand;
private InteractionHand hand;
public InteractEntityEvent(Entity entity, Hand hand) {
public InteractEntityEvent(Entity entity, InteractionHand hand) {
this.entity = entity;
this.hand = hand;
}
@@ -23,11 +24,11 @@ public class InteractEntityEvent extends Event {
return entity;
}
public Hand getHand() {
public InteractionHand getHand() {
return hand;
}
public void setHand(Hand hand) {
public void setHand(InteractionHand hand) {
this.hand = hand;
}
}
@@ -0,0 +1,46 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import net.minecraft.world.entity.LivingEntity;
public class KnockbackEvent extends Event {
private double strength;
private double x, z;
private final LivingEntity target;
public KnockbackEvent(LivingEntity target, double z, double x, double strength) {
this.target = target;
this.z = z;
this.x = x;
this.strength = strength;
}
public double getStrength() {
return strength;
}
public void setStrength(double strength) {
this.strength = strength;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getZ() {
return z;
}
public void setZ(double z) {
this.z = z;
}
public LivingEntity getTarget() {
return target;
}
}
@@ -1,12 +1,12 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftClientMixin;
import net.minecraft.client.gui.screen.Screen;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftMixin;
import net.minecraft.client.gui.screens.Screen;
/**
* @see MinecraftClientMixin#onOpenScreen
* @see MinecraftMixin#onOpenScreen
*/
public class OpenScreenEvent extends Event {
@@ -1,29 +1,29 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.player.ClientPlayerInteractionManagerMixin;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import me.retucio.sputnik.mixin.mixins.player.MultiPlayerGameModeMixin;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.phys.BlockHitResult;
/**
* @see ClientPlayerInteractionManagerMixin#onBlockPlace
* @see MultiPlayerGameModeMixin#onBlockPlace
*/
public class PlaceBlockEvent extends Event {
private Hand hand;
private InteractionHand hand;
private BlockHitResult result;
public PlaceBlockEvent(Hand hand, BlockHitResult result) {
public PlaceBlockEvent(InteractionHand hand, BlockHitResult result) {
this.hand = hand;
this.result = result;
}
public Hand getHand() {
public InteractionHand getHand() {
return hand;
}
public void setHand(Hand hand) {
public void setHand(InteractionHand hand) {
this.hand = hand;
}
@@ -1,20 +1,21 @@
package me.retucio.sputnik.event.interact;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftClientMixin;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftMixin;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
/**
* @see MinecraftClientMixin#onUseItem
* @see MinecraftMixin#onUseItem
*/
public class UseItemEvent extends Event {
private ItemStack stack;
private Hand hand;
private InteractionHand hand;
public UseItemEvent(ItemStack stack, Hand hand) {
public UseItemEvent(ItemStack stack, InteractionHand hand) {
this.stack = stack;
this.hand = hand;
}
@@ -27,11 +28,15 @@ public class UseItemEvent extends Event {
this.stack = stack;
}
public Hand getHand() {
public Item getItem() {
return stack.getItem();
}
public InteractionHand getHand() {
return hand;
}
public void setHand(Hand hand) {
public void setHand(InteractionHand hand) {
this.hand = hand;
}
}
@@ -1,12 +1,12 @@
package me.retucio.sputnik.event.network;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.world.ClientWorldMixin;
import net.minecraft.entity.Entity;
import me.retucio.sputnik.mixin.mixins.world.ClientLevelMixin;
import net.minecraft.world.entity.Entity;
/**
* @see ClientWorldMixin#onAddEntity
* @see ClientLevelMixin#onAddEntity
*/
public class AddEntityEvent extends Event {
@@ -1,10 +1,10 @@
package me.retucio.sputnik.event.network;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.world.ChunkOcclusionDataBuilderMixin;
import me.retucio.sputnik.mixin.mixins.world.VisGraphMixin;
/**
* @see ChunkOcclusionDataBuilderMixin#onChunkOcclusion
* @see VisGraphMixin#onChunkOcclusion
*/
public class ChunkOcclusionEvent extends Event {}
@@ -1,29 +1,29 @@
package me.retucio.sputnik.event.network;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.network.ClientConnectionMixin;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.DisconnectionInfo;
import me.retucio.sputnik.mixin.mixins.network.ConnectionMixin;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.network.DisconnectionDetails;
/**
* @see ClientConnectionMixin#onDisconnect
* @see ConnectionMixin#onDisconnect
*/
public class DisconnectEvent extends Event {
private final DisconnectionInfo info;
private final ServerInfo server;
private final DisconnectionDetails details;
private final ServerData server;
public DisconnectEvent(DisconnectionInfo info, ServerInfo server) {
this.info = info;
public DisconnectEvent(DisconnectionDetails details, ServerData server) {
this.details = details;
this.server = server;
}
public DisconnectionInfo getInfo() {
return info;
public DisconnectionDetails getDetails() {
return details;
}
public ServerInfo getServer() {
public ServerData getServer() {
return server;
}
}
@@ -1,22 +1,23 @@
package me.retucio.sputnik.event.network;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftClientMixin;
import net.minecraft.client.world.ClientWorld;
import me.retucio.sputnik.mixin.mixins.misc.MinecraftMixin;
import net.minecraft.client.multiplayer.ClientLevel;
/**
* @see MinecraftClientMixin#onJoinWorld
* @see MinecraftMixin#onJoinWorld
*/
public class JoinWorldEvent extends Event {
private final ClientWorld world;
private final ClientLevel world;
public JoinWorldEvent(ClientWorld world) {
public JoinWorldEvent(ClientLevel world) {
this.world = world;
}
public ClientWorld getWorld() {
public ClientLevel getWorld() {
return world;
}
}
@@ -1,14 +1,14 @@
package me.retucio.sputnik.event.network;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.network.ClientConnectionMixin;
import net.minecraft.network.packet.Packet;
import me.retucio.sputnik.mixin.mixins.network.ConnectionMixin;
import net.minecraft.network.protocol.Packet;
/**
* @see ClientConnectionMixin#onSendPacketPre
* @see ClientConnectionMixin#onSendPacketPost
* @see ClientConnectionMixin#onReceivePacket
* @see ConnectionMixin#onSendPacketPre
* @see ConnectionMixin#onSendPacketPost
* @see ConnectionMixin#onReceivePacket
*/
public class PacketEvent {
@@ -1,41 +1,43 @@
package me.retucio.sputnik.event.network;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.hud.ChatHudMixin;
import net.minecraft.client.gui.hud.MessageIndicator;
import net.minecraft.text.Text;
import me.retucio.sputnik.mixin.mixins.hud.ChatComponentMixin;
import net.minecraft.client.multiplayer.chat.GuiMessageTag;
import net.minecraft.network.chat.Component;
/**
* @see ChatHudMixin#onAddMessage
* @see ChatComponentMixin#onAddMessage
*/
public class ReceiveMessageEvent extends Event {
private Text text;
private MessageIndicator indicator;
private Component text;
private GuiMessageTag tag;
private final int id;
private boolean modified = false;
public ReceiveMessageEvent(Text text, MessageIndicator indicator, int id) {
public ReceiveMessageEvent(Component text, GuiMessageTag tag, int id) {
this.text = text;
this.indicator = indicator;
this.tag = tag;
this.id = id;
}
public Text getMessage() {
public Component getMessage() {
return text;
}
public MessageIndicator getIndicator() {
return indicator;
public GuiMessageTag getTag() {
return tag;
}
public void setMessage(Text message) {
public void setMessage(Component message) {
this.text = message;
this.modified = true;
}
public void setIndicator(MessageIndicator indicator) {
this.indicator = indicator;
public void setTag(GuiMessageTag tag) {
this.tag = tag;
this.modified = true;
}
@@ -1,12 +1,12 @@
package me.retucio.sputnik.event.network;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.world.ClientWorldMixin;
import net.minecraft.entity.Entity;
import me.retucio.sputnik.mixin.mixins.world.ClientLevelMixin;
import net.minecraft.world.entity.Entity;
/**
* @see ClientWorldMixin#onRemoveEntity
* @see ClientLevelMixin#onRemoveEntity
*/
public class RemoveEntityEvent extends Event {
@@ -1,11 +1,11 @@
package me.retucio.sputnik.event.network;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.network.ClientPlayNetworkHandlerMixin;
import me.retucio.sputnik.mixin.mixins.network.ClientPacketListenerMixin;
/**
* @see ClientPlayNetworkHandlerMixin#onSendMessage
* @see ClientPacketListenerMixin#onSendMessage
*/
public class SendMessageEvent extends Event {
@@ -1,26 +1,26 @@
package me.retucio.sputnik.event.render;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.misc.GameOptionsMixin;
import net.minecraft.client.option.Perspective;
import me.retucio.sputnik.mixin.mixins.misc.OptionsMixin;
import net.minecraft.client.CameraType;
/**
* @see GameOptionsMixin#changePerspective
* @see OptionsMixin#changePerspective
*/
public class PerspectiveChangeEvent extends Event {
private Perspective perspective;
private CameraType perspective;
public PerspectiveChangeEvent(Perspective perspective) {
public PerspectiveChangeEvent(CameraType perspective) {
this.perspective = perspective;
}
public Perspective getPerspective() {
public CameraType getPerspective() {
return perspective;
}
public void setPerspective(Perspective perspective) {
public void setPerspective(CameraType perspective) {
this.perspective = perspective;
}
}
@@ -1,24 +1,26 @@
package me.retucio.sputnik.event.render;
import com.github.retucio.neutrino.Event;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.gui.GuiGraphicsExtractor;
public class Render2DEvent extends Event {
private final DrawContext ctx;
private final RenderTickCounter tc;
private final GuiGraphicsExtractor gui;
private final DeltaTracker dt;
public Render2DEvent(DrawContext ctx, RenderTickCounter tc) {
this.ctx = ctx;
this.tc = tc;
public Render2DEvent(GuiGraphicsExtractor gui, DeltaTracker dt) {
this.gui = gui;
this.dt = dt;
}
public DrawContext getCtx() {
return ctx;
public GuiGraphicsExtractor getGui() {
return gui;
}
public RenderTickCounter getTc() {
return tc;
public DeltaTracker getDt() {
return dt;
}
}
@@ -1,40 +1,42 @@
package me.retucio.sputnik.event.render;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.render.WorldRendererMixin;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.util.math.MatrixStack;
import com.mojang.blaze3d.vertex.PoseStack;
import me.retucio.sputnik.mixin.mixins.render.LevelRendererMixin;
import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.renderer.state.level.CameraRenderState;
/**
* @see WorldRendererMixin#render
* @see LevelRendererMixin#renderLevel
*/
public class Render3DEvent extends Event {
private final MatrixStack matrices;
private final RenderTickCounter tc;
private final Camera camera;
private final PoseStack matrices;
private final DeltaTracker dt;
private final CameraRenderState cameraState;
public Render3DEvent(MatrixStack matrices, RenderTickCounter tc, Camera camera) {
public Render3DEvent(PoseStack matrices, DeltaTracker dt, CameraRenderState cameraState) {
this.matrices = matrices;
this.tc = tc;
this.camera = camera;
this.dt = dt;
this.cameraState = cameraState;
}
public MatrixStack getMatrices() {
public PoseStack getMatrices() {
return matrices;
}
public RenderTickCounter getTickCounter() {
return tc;
public DeltaTracker getDeltaTracker() {
return dt;
}
public Camera getCamera() {
return camera;
public CameraRenderState getCamera() {
return cameraState;
}
public float getTickDelta() {
return tc.getDynamicDeltaTicks();
return dt.getGameTimeDeltaTicks();
}
}
@@ -1,37 +1,37 @@
package me.retucio.sputnik.event.render;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.render.HeldItemRendererMixin;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Hand;
import com.mojang.blaze3d.vertex.PoseStack;
import me.retucio.sputnik.mixin.mixins.render.ItemInHandRendererMixin;
import net.minecraft.world.InteractionHand;
/**
* @see HeldItemRendererMixin#onRenderArm
* @see ItemInHandRendererMixin#onRenderArm
*/
public class RenderArmEvent extends Event {
private MatrixStack matrices;
private Hand hand;
private PoseStack matrices;
private InteractionHand hand;
public RenderArmEvent(MatrixStack matrices, Hand hand) {
public RenderArmEvent(PoseStack matrices, InteractionHand hand) {
this.matrices = matrices;
this.hand = hand;
}
public MatrixStack getMatrices() {
public PoseStack getMatrices() {
return matrices;
}
public void setMatrices(MatrixStack matrices) {
public void setMatrices(PoseStack matrices) {
this.matrices = matrices;
}
public Hand getHand() {
public InteractionHand getHand() {
return hand;
}
public void setHand(Hand hand) {
public void setHand(InteractionHand hand) {
this.hand = hand;
}
}
@@ -2,9 +2,10 @@ package me.retucio.sputnik.event.render;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.hud.BossBarHudMixin;
import net.minecraft.client.gui.hud.ClientBossBar;
import net.minecraft.text.Text;
import net.minecraft.client.gui.components.LerpingBossEvent;
import net.minecraft.network.chat.MutableComponent;
import java.awt.*;
import java.util.Iterator;
@@ -17,27 +18,27 @@ public class RenderBossbarEvent {
public static class BossText extends Event {
private ClientBossBar bossBar;
private Text name;
private LerpingBossEvent bossBar;
private MutableComponent name;
public BossText(ClientBossBar bossBar, Text name) {
public BossText(LerpingBossEvent bossBar, MutableComponent name) {
this.bossBar = bossBar;
this.name = name;
}
public ClientBossBar getBossBar() {
public LerpingBossEvent getBossBar() {
return bossBar;
}
public void setBossBar(ClientBossBar bossBar) {
public void setBossBar(LerpingBossEvent bossBar) {
this.bossBar = bossBar;
}
public Text getName() {
public MutableComponent getName() {
return name;
}
public void setName(Text name) {
public void setName(MutableComponent name) {
this.name = name;
}
}
@@ -61,17 +62,17 @@ public class RenderBossbarEvent {
public static class BossIterator extends Event {
private Iterator<ClientBossBar> iterator;
private Iterator<LerpingBossEvent> iterator;
public BossIterator(Iterator<ClientBossBar> iterator) {
public BossIterator(Iterator<LerpingBossEvent> iterator) {
this.iterator = iterator;
}
public Iterator<ClientBossBar> getIterator() {
public Iterator<LerpingBossEvent> getIterator() {
return iterator;
}
public void setIterator(Iterator<ClientBossBar> iterator) {
public void setIterator(Iterator<LerpingBossEvent> iterator) {
this.iterator = iterator;
}
}
@@ -1,37 +1,38 @@
package me.retucio.sputnik.event.render;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.mixin.mixins.render.HeldItemRendererMixin;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Hand;
import com.mojang.blaze3d.vertex.PoseStack;
import me.retucio.sputnik.mixin.mixins.render.ItemInHandRendererMixin;
import net.minecraft.world.InteractionHand;
/**
* @see HeldItemRendererMixin#onRenderItem
* @see ItemInHandRendererMixin#onRenderItem
*/
public class RenderHeldItemEvent extends Event {
private MatrixStack matrices;
private Hand hand;
private PoseStack matrices;
private InteractionHand hand;
public RenderHeldItemEvent(MatrixStack matrices, Hand hand) {
public RenderHeldItemEvent(PoseStack matrices, InteractionHand hand) {
this.matrices = matrices;
this.hand = hand;
}
public MatrixStack getMatrices() {
public PoseStack getMatrices() {
return matrices;
}
public void setMatrices(MatrixStack matrices) {
public void setMatrices(PoseStack matrices) {
this.matrices = matrices;
}
public Hand getHand() {
public InteractionHand getHand() {
return hand;
}
public void setHand(Hand hand) {
public void setHand(InteractionHand hand) {
this.hand = hand;
}
}
@@ -3,7 +3,7 @@ package me.retucio.sputnik.event.sputnik;
import com.github.retucio.neutrino.Event;
// se genera cada que se interactúa con el marco de ajustes de la interfaz
public class GUISettingsFrameEvent {
public class ClientSettingsPanelEvent {
public static class Extend extends Event {} // al extenderlo / contraerlo
public static class Move extends Event {} // al cambiarlo de posición
@@ -0,0 +1,26 @@
package me.retucio.sputnik.event.sputnik;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.friend.Friend;
// evento lanzado cuando se agrega o se elimina un amigo
public class FriendEvent extends Event {
private final Friend friend;
public FriendEvent(Friend friend) {
this.friend = friend;
}
public Friend getFriend() {
return friend;
}
public static class Add extends FriendEvent {
public Add(Friend friend) { super(friend); }
}
public static class Remove extends FriendEvent {
public Remove(Friend friend) { super(friend); }
}
}
@@ -2,8 +2,7 @@ package me.retucio.sputnik.event.sputnik;
import com.github.retucio.neutrino.Event;
// se genera cada que se interactúa con el marco de módulos
public class ModuleFrameEvent {
public class FriendPanelEvent {
public static class Extend extends Event {} // al extenderlo / contraerlo
public static class Move extends Event {} // al cambiarlo de posición
@@ -3,4 +3,4 @@ package me.retucio.sputnik.event.sputnik;
import com.github.retucio.neutrino.Event;
// se genera cuando carga la interfaz del mod
public class LoadClickGUIEvent extends Event {}
public class LoadClickGuiEvent extends Event {}
@@ -0,0 +1,5 @@
package me.retucio.sputnik.event.sputnik;
import com.github.retucio.neutrino.Event;
public class LoadFriendManagerEvent extends Event {}
@@ -0,0 +1,28 @@
package me.retucio.sputnik.event.sputnik;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.ui.widgets.panels.ModulePanel;
// se genera cada que se interactúa con un panel de módulos
public class ModulePanelEvent extends Event {
protected ModulePanel panel;
public ModulePanel getPanel() {
return panel;
}
// al extenderlo / contraerlo
public static class Extend extends ModulePanelEvent {
public Extend(ModulePanel panel) {
this.panel = panel;
}
}
// al cambiarlo de posición
public static class Move extends ModulePanelEvent {
public Move(ModulePanel panel) {
this.panel = panel;
}
}
}
@@ -1,27 +0,0 @@
package me.retucio.sputnik.event.sputnik;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.ui.widgets.frames.SettingsFrame;
// se genera cada que se interactúa con un marco de ajustes de un módulo
public class SettingsFrameEvent {
public static class Open extends Event { // al abrirlo
private final SettingsFrame frame;
public Open(SettingsFrame frame) { this.frame = frame; }
public SettingsFrame getFrame() { return frame; }
}
public static class Close extends Event { // al cerrarlo
private final SettingsFrame frame;
public Close(SettingsFrame frame) { this.frame = frame; }
public SettingsFrame getFrame() { return frame; }
}
public static class Move extends Event { // al cambiarlo de posición
private final SettingsFrame frame;
public Move(SettingsFrame frame) { this.frame = frame; }
public SettingsFrame getFrame() { return frame; }
}
}
@@ -0,0 +1,27 @@
package me.retucio.sputnik.event.sputnik;
import com.github.retucio.neutrino.Event;
import me.retucio.sputnik.ui.widgets.panels.SettingsPanel;
// se genera cada que se interactúa con un marco de ajustes de un módulo
public class SettingsPanelEvent {
public static class Open extends Event { // al abrirlo
private final SettingsPanel panel;
public Open(SettingsPanel panel) { this.panel = panel; }
public SettingsPanel getPanel() { return panel; }
}
public static class Close extends Event { // al cerrarlo
private final SettingsPanel panel;
public Close(SettingsPanel panel) { this.panel = panel; }
public SettingsPanel getPanel() { return panel; }
}
public static class Move extends Event { // al cambiarlo de posición
private final SettingsPanel panel;
public Move(SettingsPanel panel) { this.panel = panel; }
public SettingsPanel getPanel() { return panel; }
}
}
@@ -0,0 +1,59 @@
package me.retucio.sputnik.friend;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public class Friend {
private static final Minecraft mc = Minecraft.getInstance();
private String name;
private final UUID uuid;
private boolean searchMatch;
public Friend(UUID uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UUID getUuid() {
return uuid;
}
public @Nullable Player getPlayer() {
if (mc.level == null) return null;
Entity entity = mc.level.getEntity(uuid);
if (!(entity instanceof Player player)) return null;
return player;
}
public boolean isSearchMatch() {
return searchMatch;
}
public void setSearchMatch(boolean searchMatch) {
this.searchMatch = searchMatch;
}
public enum Status {
SUCCESS,
ALREADY_BEFRIENDED,
NOT_PLAYER,
NOT_BEFRIENDED,
NO_FRIENDS; // :(
}
}
@@ -0,0 +1,89 @@
package me.retucio.sputnik.friend;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.sputnik.FriendEvent;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.misc.FakePlayer;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class FriendManager {
public static FriendManager INSTANCE;
private final Minecraft mc = Minecraft.getInstance();
private final List<Friend> friends = new ArrayList<>();
public void add(Friend friend) {
friends.add(friend);
Sputnik.EVENT_BUS.post(new FriendEvent.Add(friend));
}
public void add(UUID uuid) {
Friend friend = new Friend(uuid);
friend.setName(friend.getPlayer().getName().getString());
add(friend);
}
public void remove(Friend friend) {
friends.remove(friend);
Sputnik.EVENT_BUS.post(new FriendEvent.Remove(friend));
}
public void remove(UUID uuid) {
Friend friend = get(uuid);
remove(friend);
}
public Friend.Status add(Entity entity) {
if (!(entity instanceof Player) || entity == ModuleManager.INSTANCE.getModuleByClass(FakePlayer.class).getPlayer()) {
return Friend.Status.NOT_PLAYER;
}
if (isFriend(entity)) return Friend.Status.ALREADY_BEFRIENDED;
add(entity.getUUID());
return Friend.Status.SUCCESS;
}
public Friend.Status remove(Entity entity) {
if (!(entity instanceof Player)) return Friend.Status.NOT_PLAYER;
if (friends.isEmpty()) return Friend.Status.NO_FRIENDS;
if (!isFriend(entity)) return Friend.Status.NOT_BEFRIENDED;
remove(entity.getUUID());
return Friend.Status.SUCCESS;
}
public Friend get(UUID uuid) {
for (Friend friend : friends) {
if (friend.getUuid().equals(uuid)) {
return friend;
}
}
return null;
}
public Friend fromName(String name) {
for (Friend friend : friends) {
if (friend.getName().equals(name)) {
return friend;
}
}
return null;
}
public boolean isFriend(Entity entity) {
return get(entity.getUUID()) != null;
}
public List<Friend> getFriends() {
return new ArrayList<>(friends);
}
}
@@ -0,0 +1,16 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.world.inventory.Slot;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(AbstractContainerScreen.class)
public interface AbstractContainerScreenAccessor {
@Accessor("hoveredSlot")
Slot getHoveredSlot();
@Accessor("doubleclick")
void setDoubleClicking(boolean doubleClicking);
}
@@ -1,13 +1,13 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.block.entity.SignBlockEntity;
import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen;
import net.minecraft.client.gui.screens.inventory.AbstractSignEditScreen;
import net.minecraft.world.level.block.entity.SignBlockEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(AbstractSignEditScreen.class)
public interface AbstractSignEditScreenAccessor {
@Accessor("blockEntity")
@Accessor("sign")
SignBlockEntity getBlockEntity();
}
@@ -1,16 +1,16 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.inventory.AnvilScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(AnvilScreen.class)
public interface AnvilScreenAccessor {
@Accessor("nameField")
TextFieldWidget getNameField();
@Accessor("name")
EditBox getNameField();
@Accessor("nameField")
void setNameField(TextFieldWidget nameField);
@Accessor("name")
void setNameField(EditBox nameField);
}
@@ -1,13 +1,13 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.block.AbstractBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(AbstractBlock.class)
public interface AbstractBlockAccessor {
@Mixin(BlockBehaviour.class)
public interface BlockBehaviourAccessor {
@Mutable @Accessor("slipperiness")
@Mutable @Accessor("friction")
void setSlipperiness(float slipperiness);
}
@@ -0,0 +1,17 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.network.chat.LastSeenMessagesTracker;
import net.minecraft.network.chat.SignedMessageChain;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientPacketListener.class)
public interface ClientPacketListenerAccessor {
@Accessor("lastSeenMessages")
LastSeenMessagesTracker getLastSeenMessagesTracker();
@Accessor("signedMessageEncoder")
SignedMessageChain.Encoder getSignedMessageEncoder();
}
@@ -1,17 +0,0 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.message.LastSeenMessagesCollector;
import net.minecraft.network.message.MessageChain;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientPlayNetworkHandler.class)
public interface ClientPlayNetworkHandlerAccessor {
@Accessor("lastSeenMessagesCollector")
LastSeenMessagesCollector getLastSeenMessagesCollector();
@Accessor("messagePacker")
MessageChain.Packer getMessagePacker();
}
@@ -0,0 +1,16 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.Optional;
@Mixin(ClientboundExplodePacket.class)
public interface ClientboundExplodePacketAccessor {
@Mutable @Accessor("playerKnockback")
void setKnockback(Optional<Vec3> kb);
}
@@ -0,0 +1,15 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientboundSetEntityMotionPacket.class)
public interface ClientboundSetEntityMotionPacketAccessor {
@Mutable @Accessor("movement")
void setVelocity(Vec3 velocity);
}
@@ -1,18 +0,0 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.network.ClientCommonNetworkHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Mixin(ClientCommonNetworkHandler.ConfirmServerResourcePackScreen.class)
public interface ConfirmServerResourcePackScreenAccessor {
@Accessor("parent")
Screen getParentScreen();
@Accessor("packs")
List<? extends PackAccessor> getRequests();
}
@@ -1,15 +0,0 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.entity.projectile.FishingBobberEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(FishingBobberEntity.class)
public interface FishingBobberEntityAccessor {
@Accessor("caughtFish")
boolean caughtFish();
@Accessor("state")
FishingBobberEntity.State getState();
}
@@ -0,0 +1,16 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.world.entity.projectile.FishingHook;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(FishingHook.class)
public interface FishingHookAccessor {
@Accessor("biting")
boolean caughtFish();
@Accessor("currentState")
FishingHook.FishHookState getState();
}
@@ -1,16 +0,0 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.screen.slot.Slot;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(HandledScreen.class)
public interface HandledScreenAccessor {
@Accessor("focusedSlot")
Slot getFocusedSlot();
@Accessor("doubleClicking")
void setDoubleClicking(boolean doubleClicking);
}
@@ -1,13 +1,13 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.KeyMapping;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(KeyBinding.class)
@Mixin(KeyMapping.class)
public interface KeyBindingAccessor {
@Accessor("boundKey")
InputUtil.Key getBoundKey();
@Accessor("key")
InputConstants.Key getKey();
}
@@ -1,11 +1,12 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.world.effect.MobEffectInstance;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(StatusEffectInstance.class)
public interface StatusEffectInstanceAccessor {
@Mixin(MobEffectInstance.class)
public interface MobEffectInstanceAccessor {
@Accessor("duration")
void setDuration(int duration);
@@ -1,7 +1,7 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.OverlayTexture;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@@ -10,5 +10,5 @@ import org.spongepowered.asm.mixin.gen.Accessor;
public interface OverlayTextureAccessor {
@Mutable @Accessor("texture")
void setTexture(NativeImageBackedTexture texture);
void setTexture(DynamicTexture texture);
}
@@ -0,0 +1,19 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.List;
@Mixin(ClientCommonPacketListenerImpl.PackConfirmScreen.class)
public interface PackConfirmScreenAccessor {
@Accessor("parentScreen")
Screen getParentScreen();
@Accessor("requests")
List<? extends PendingRequestAccessor> getRequests();
}
@@ -1,13 +1,14 @@
package me.retucio.sputnik.mixin.accessors;
import net.minecraft.client.network.ClientCommonNetworkHandler;
import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
import java.util.UUID;
@Mixin(ClientCommonNetworkHandler.ConfirmServerResourcePackScreen.Pack.class)
public interface PackAccessor {
@Mixin(ClientCommonPacketListenerImpl.PackConfirmScreen.PendingRequest.class)
public interface PendingRequestAccessor {
@Invoker
UUID callId();
@@ -4,25 +4,25 @@ import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.interact.BoatMoveEvent;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.movement.BoatFly;
import net.minecraft.entity.MovementType;
import net.minecraft.entity.vehicle.AbstractBoatEntity;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.entity.MoverType;
import net.minecraft.world.entity.vehicle.boat.AbstractBoat;
import net.minecraft.world.phys.Vec3;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(AbstractBoatEntity.class)
public abstract class AbstractBoatEntityMixin {
@Mixin(AbstractBoat.class)
public abstract class AbstractBoatMixin {
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/vehicle/AbstractBoatEntity;move(Lnet/minecraft/entity/MovementType;Lnet/minecraft/util/math/Vec3d;)V"))
private void onMove(AbstractBoatEntity instance, MovementType movementType, Vec3d vec3d) {
BoatMoveEvent event = Sputnik.EVENT_BUS.post(new BoatMoveEvent(instance, vec3d));
if(!event.isCancelled()) instance.move(movementType, event.getPos());
@Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/vehicle/boat/AbstractBoat;move(Lnet/minecraft/world/entity/MoverType;Lnet/minecraft/world/phys/Vec3;)V"))
private void onMove(AbstractBoat instance, MoverType moverType, Vec3 vec3) {
BoatMoveEvent event = Sputnik.EVENT_BUS.post(new BoatMoveEvent(instance, vec3));
if (!event.isCancelled()) instance.move(moverType, event.getPos());
}
@Inject(method = "updatePaddles", at = @At("HEAD"), cancellable = true)
@Inject(method = "controlBoat", at = @At("HEAD"), cancellable = true)
private void onPaddle(CallbackInfo ci) {
if (ModuleManager.INSTANCE.getModuleByClass(BoatFly.class).isEnabled()) {
ci.cancel();
@@ -1,6 +1,7 @@
package me.retucio.sputnik.mixin.mixins.entity;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.render.ChangeRotationEvent;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.camera.Freecam;
@@ -8,15 +9,24 @@ import me.retucio.sputnik.module.modules.camera.Freelook;
import me.retucio.sputnik.module.modules.camera.Rotations;
import me.retucio.sputnik.module.modules.misc.AntiInvis;
import me.retucio.sputnik.module.modules.movement.BoatFly;
import me.retucio.sputnik.module.modules.movement.Velocity;
import me.retucio.sputnik.module.modules.render.Nametags;
import net.minecraft.entity.*;
import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.PersistentProjectileEntity;
import net.minecraft.entity.vehicle.AbstractBoatEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.world.World;
import me.retucio.sputnik.util.interfaces.IVec3;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.TamableAnimal;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.item.PrimedTnt;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.arrow.AbstractArrow;
import net.minecraft.world.entity.vehicle.boat.AbstractBoat;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import org.joml.Vector3d;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@@ -25,17 +35,20 @@ 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.EVENT_BUS;
import static me.retucio.sputnik.Sputnik.mc;
@Mixin(Entity.class)
public abstract class EntityMixin {
@Shadow public abstract Text getName();
@Unique boolean freecamDone;
@Shadow public abstract Component getName();
@Shadow public abstract EntityType<?> getType();
@Shadow private float yaw;
@Shadow private float pitch;
@Shadow private float yRot;
@Shadow private float xRot;
@Shadow
public abstract HitResult pick(double range, float a, boolean withLiquids);
@Unique
Freecam freecam;
@@ -46,30 +59,28 @@ public abstract class EntityMixin {
@Unique
Rotations rotations;
@SuppressWarnings("rawtypes")
@Inject(method = "<init>", at = @At("TAIL"))
private void getModules(EntityType type, World world, CallbackInfo ci) {
private void getModules(CallbackInfo ci) {
freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
freelook = ModuleManager.INSTANCE.getModuleByClass(Freelook.class);
nametags = ModuleManager.INSTANCE.getModuleByClass(Nametags.class);
rotations = ModuleManager.INSTANCE.getModuleByClass(Rotations.class);
}
// cámara libre & perspectiva libre
@SuppressWarnings("ConstantConditions")
@Inject(method = "changeLookDirection", at = @At("HEAD"), cancellable = true)
private void onChangeLookDirection(double cursorDeltaX, double cursorDeltaY, CallbackInfo ci) {
if ((Object) this != mc.player) return;
@Inject(method = "turn", at = @At("HEAD"), cancellable = true)
private void onChangeLookDirection(double xo, double yo, CallbackInfo ci) {
if ((Object) this != Sputnik.mc.player) return;
if (freecam.isEnabled()) {
freecam.changeLookDirection(cursorDeltaX * 0.15, cursorDeltaY * 0.15);
freecam.changeLookDirection(xo * 0.15f, yo * 0.15f);
ci.cancel();
} else if (freelook.isEnabled() && freelook.mode.is(Freelook.CameraMode.CAMERA)) {
freelook.setYaw(freelook.getYaw() + (float) (cursorDeltaX * freelook.mouseSens.getFloatValue()));
freelook.setPitch(freelook.getPitch() + (float) (cursorDeltaY * freelook.mouseSens.getFloatValue()));
freelook.setYaw(freelook.getYaw() + (float) (xo * freelook.mouseSens.getFloatValue()));
freelook.setPitch(freelook.getPitch() + (float) (yo * freelook.mouseSens.getFloatValue()));
if (Math.abs(freelook.getPitch()) > 90) freelook.setPitch(freelook.getPitch() > 0 ? 90 : -90);
ci.cancel();
@@ -83,39 +94,39 @@ public abstract class EntityMixin {
@ModifyReturnValue(method = "isCustomNameVisible", at = @At("RETURN"))
private boolean renderEntityNametags(boolean original) {
if (!nametags.isEnabled()) return original;
if ((Object) this instanceof PersistentProjectileEntity p && p.isOnGround()) return false;
if ((Object) this instanceof ItemEntity i && !nametags.items.isEnabled(i.getStack().getItem())) return false;
if ((Object) this instanceof AbstractArrow p && p.onGround()) return false;
if ((Object) this instanceof ItemEntity i && !nametags.items.isEnabled(i.getItem().getItem())) return false;
return nametags.entities.isEnabled((this.getType()));
}
@ModifyReturnValue(method = "getName", at = @At("RETURN"))
private Text showProjectileDamage(Text original) {
private Component showProjectileDamage(Component original) {
if (!nametags.isEnabled() || !nametags.showProjectileDamage.getValue()) return original;
if ((Object) this instanceof PersistentProjectileEntity arrow) { // aunque lo llame "arrow", también cubre flechas espectrales y tridentes
if ((Object) this instanceof AbstractArrow arrow) { // aunque se llame "arrow", también cubre flechas espectrales y tridentes
String damage = nametags.getArrowDamage(arrow);
if (!damage.equals("0")) return original.copy().append(Text.literal(" (" + damage + ")").formatted(Formatting.RED));
if (!damage.equals("0")) return original.copy().append(Component.literal(" (" + damage + ")").withStyle(ChatFormatting.RED));
}
return original;
}
@ModifyReturnValue(method = "getName", at = @At("RETURN"))
private Text showTntPrimeTime(Text original) {
private Component showTntPrimeTime(Component original) {
if (!nametags.isEnabled() || !nametags.tntPrime.getValue()) return original;
if ((Object) this instanceof TntEntity tnt) {
return Text.of(nametags.getTntPrimeTime(tnt));
if ((Object) this instanceof PrimedTnt tnt) {
return Component.nullToEmpty(nametags.getTntPrimeTime(tnt));
}
return original;
}
@SuppressWarnings("ConstantConditions")
@ModifyReturnValue(method = "getCustomName", at = @At("RETURN"))
private Text displayEntityOwner(Text original) {
private Component displayEntityOwner(Component original) {
if (!nametags.isEnabled() || !nametags.petOwner.getValue()) return original;
if ((Object) this instanceof TameableEntity entity && entity.getOwnerReference() != null) {
if ((Object) this instanceof TamableAnimal entity && entity.getOwnerReference() != null) {
if (original != null) return original.copy().append(" (de " + nametags.getOwnerName(entity.getOwnerReference()) + ")");
else return Text.of(nametags.getOwnerName(entity.getOwnerReference()));
else return Component.nullToEmpty(nametags.getOwnerName(entity.getOwnerReference()));
}
return original;
}
@@ -123,7 +134,7 @@ public abstract class EntityMixin {
@SuppressWarnings("ConstantConditions")
@ModifyReturnValue(method = "getName", at = @At("RETURN"))
private Text showBabies(Text original) {
private Component showBabies(Component original) {
if (!nametags.isEnabled() || !nametags.distinguishBabies.getValue()) return original;
if ((Object) this instanceof LivingEntity entity && entity.isBaby()) return original.copy().append(" (baby)");
return original;
@@ -132,24 +143,24 @@ public abstract class EntityMixin {
// rotaciones
@Inject(method = "setRotation", at = @At("HEAD"), cancellable = true)
@Inject(method = "setRot", at = @At("HEAD"), cancellable = true)
private void onRotation(float yaw, float pitch, CallbackInfo ci) {
if ((Object) this != mc.player) return;
ChangeRotationEvent event = EVENT_BUS.post(new ChangeRotationEvent(yaw, pitch));
if ((Object) this != Sputnik.mc.player) return;
ChangeRotationEvent event = Sputnik.EVENT_BUS.post(new ChangeRotationEvent(yaw, pitch));
if (event.isCancelled()) ci.cancel();
}
@Inject(method = "setYaw", at = @At("HEAD"), cancellable = true)
@Inject(method = "setYRot", at = @At("HEAD"), cancellable = true)
private void onChangeYaw(float yaw, CallbackInfo ci) {
if ((Object) this != mc.player) return;
ChangeRotationEvent event = EVENT_BUS.post(new ChangeRotationEvent(yaw, this.pitch));
if ((Object) this != Sputnik.mc.player) return;
ChangeRotationEvent event = Sputnik.EVENT_BUS.post(new ChangeRotationEvent(yaw, this.xRot));
if (event.isCancelled()) ci.cancel();
}
@Inject(method = "setPitch", at = @At("HEAD"), cancellable = true)
@Inject(method = "setXRot", at = @At("HEAD"), cancellable = true)
private void onChangePitch(float pitch, CallbackInfo ci) {
if ((Object) this != mc.player) return;
ChangeRotationEvent event = EVENT_BUS.post(new ChangeRotationEvent(this.yaw, pitch));
if ((Object) this != Sputnik.mc.player) return;
ChangeRotationEvent event = Sputnik.EVENT_BUS.post(new ChangeRotationEvent(this.yRot, pitch));
if (event.isCancelled()) ci.cancel();
}
@@ -157,16 +168,23 @@ public abstract class EntityMixin {
// otros
@Inject(method = "isInvisibleTo", at = @At("RETURN"), cancellable = true)
private void renderInvisPlayers(PlayerEntity player, CallbackInfoReturnable<Boolean> cir) {
private void renderInvisPlayers(Player player, CallbackInfoReturnable<Boolean> cir) {
if (ModuleManager.INSTANCE.getModuleByClass(AntiInvis.class).isEnabled()) cir.setReturnValue(false);
}
@SuppressWarnings("ConstantConditions")
@Inject(method = "getStepHeight", at = @At("RETURN"), cancellable = true)
@Inject(method = "maxUpStep", at = @At("RETURN"), cancellable = true)
private void modifyBoatStepHeight(CallbackInfoReturnable<Float> cir) {
BoatFly boatFly = ModuleManager.INSTANCE.getModuleByClass(BoatFly.class);
if (((Object) this) instanceof AbstractBoatEntity && boatFly.isEnabled()) {
if (((Object) this) instanceof AbstractBoat && boatFly.isEnabled()) {
cir.setReturnValue(boatFly.stepHeight.getFloatValue());
}
}
@SuppressWarnings("ConstantConditions")
@Inject(method = "push(Lnet/minecraft/world/entity/Entity;)V", at = @At("HEAD"), cancellable = true)
private void onPushed(Entity entity, CallbackInfo ci) {
Velocity velocity = ModuleManager.INSTANCE.getModuleByClass(Velocity.class);
if (velocity.isEnabled() && !velocity.push.getValue() && (Object) this == Sputnik.mc.player) ci.cancel();
}
}
@@ -4,15 +4,15 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.sugar.Local;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.render.EntityESP;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.entity.Entity;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
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;
@Mixin(EntityRenderer.class)
public abstract class EntityRendererMixin {
@@ -20,16 +20,16 @@ public abstract class EntityRendererMixin {
private EntityESP esp;
@Inject(method = "<init>", at = @At("TAIL"))
private void getModules(EntityRendererFactory.Context context, CallbackInfo ci) {
private void getModules(CallbackInfo ci) {
esp = ModuleManager.INSTANCE.getModuleByClass(EntityESP.class);
}
@ModifyExpressionValue(method = "updateRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z"))
@ModifyExpressionValue(method = "extractRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;shouldEntityAppearGlowing(Lnet/minecraft/world/entity/Entity;)Z"))
private boolean renderGlowESP(boolean original, @Local(argsOnly = true) Entity entity) {
return (esp.isEnabled() && esp.mode.is(EntityESP.ESPMode.GLOW) && esp.entities.isEnabled(entity.getType())) || original;
}
@ModifyExpressionValue(method = "updateRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getTeamColorValue()I"))
@ModifyExpressionValue(method = "extractRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getTeamColor()I"))
private int setGlowESPColor(int original, @Local(argsOnly = true) Entity entity) {
if (esp.isEnabled() && esp.mode.is(EntityESP.ESPMode.GLOW) && esp.entities.isEnabled(entity.getType())) return esp.glowColor.getRGB();
return original;
@@ -3,11 +3,11 @@ package me.retucio.sputnik.mixin.mixins.entity;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.render.Nametags;
import net.minecraft.entity.ItemEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@@ -16,17 +16,17 @@ import org.spongepowered.asm.mixin.injection.At;
public abstract class ItemEntityMixin {
@Shadow
public abstract ItemStack getStack();
public abstract ItemStack getItem();
@ModifyReturnValue(method = "getName", at = @At("RETURN"))
private Text showItemCount(Text original) {
private Component showItemCount(Component original) {
Nametags nametags = ModuleManager.INSTANCE.getModuleByClass(Nametags.class);
if (!nametags.isEnabled()) return original;
int count = this.getStack().getCount();
MutableText name = this.getStack().getCustomName() != null ? this.getStack().getCustomName().copyContentOnly() : original.copyContentOnly();
int count = this.getItem().getCount();
MutableComponent name = this.getItem().getCustomName() != null ? this.getItem().getCustomName().plainCopy() : original.plainCopy();
if (!name.equals(original)) name = name.formatted(Formatting.ITALIC);
if (!name.equals(original)) name = name.withStyle(ChatFormatting.ITALIC);
if (nametags.countItems.getValue()) {
if (count > 1) return name.copy().append(" x" + count);
@@ -1,12 +1,16 @@
package me.retucio.sputnik.mixin.mixins.entity;
import com.llamalad7.mixinextras.sugar.Local;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.movement.ElytraBounce;
import me.retucio.sputnik.module.modules.movement.Step;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import me.retucio.sputnik.module.modules.movement.Velocity;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.phys.Vec3;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@@ -17,6 +21,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import static me.retucio.sputnik.Sputnik.mc;
@Mixin(LivingEntity.class)
public abstract class LivingEntityMixin {
@@ -24,36 +29,49 @@ public abstract class LivingEntityMixin {
@Unique private boolean awaitingElytra = false;
@Shadow
public abstract boolean isGliding();
public abstract boolean isFallFlying();
@SuppressWarnings("ConstantConditions")
@Inject(method = "tickMovement", at = @At("TAIL"))
@Inject(method = "aiStep", at = @At("TAIL"))
private void recastIfLanded(CallbackInfo ci) {
ElytraBounce bounce = ModuleManager.INSTANCE.getModuleByClass(ElytraBounce.class);
ElytraBounce ebounce = ModuleManager.INSTANCE.getModuleByClass(ElytraBounce.class);
if (!((Object) this instanceof ClientPlayerEntity)
if (!((Object) this instanceof LocalPlayer)
|| mc.player == null
|| bounce == null)
|| ebounce == null)
return;
boolean elytra = isGliding();
boolean elytra = isFallFlying();
if (awaitingElytra) {
if (elytra) awaitingElytra = false;
} else if (!elytra && prevElytra) {
mc.getSoundManager().stopSounds(SoundEvents.ITEM_ELYTRA_FLYING.id(), SoundCategory.PLAYERS);
bounce.bounce();
awaitingElytra = bounce.canUseElytra();
mc.getSoundManager().stop(SoundEvents.ELYTRA_FLYING.location(), SoundSource.PLAYERS); // armor equip elytra??
ebounce.bounce();
awaitingElytra = ebounce.canUseElytra();
}
prevElytra = elytra;
}
@Inject(method = "getStepHeight", at = @At("RETURN"), cancellable = true)
@Inject(method = "maxUpStep", 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());
}
@Inject(method = "knockback", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;setDeltaMovement(DDD)V"), cancellable = true)
private void onTakeKb(double strength, double x, double z, CallbackInfo ci, @Local(name = "deltaMovement") Vec3 dm, @Local(name = "deltaVector") Vec3 dv) {
Velocity velocity = ModuleManager.INSTANCE.getModuleByClass(Velocity.class);
if (!velocity.isEnabled() || velocity.hits.getValue()) return;
boolean onGround = ((LivingEntity) (Object) this).onGround();
double kbX = (velocity.xPercentage.getValue() / 100) * (dm.x / 2 - dv.x);
double kbY = (velocity.yPercentage.getValue() / 100) * ((onGround ? Math.min(0.4, dm.y / 2 + strength) : dm.y));
double kbZ = (velocity.zPercentage.getValue() / 100) * (dm.z / 2 - dv.z);
ci.cancel();
((Entity) (Object) this).addDeltaMovement(new Vec3(kbX, kbY, kbZ));
}
}
Loaded 100 of 370 files, more files were not shown because too many files have changed in this diff. Show more