This commit is contained in:
retuci0 committed 2026-05-06 17:59:19 +02:00
1 parent c7b8e96d68
commit 67cc34a08c
24 files changed
+467 -104

No files matched your search

+7 -7
View File
@@ -1,22 +1,22 @@
# v4.6 # v4.7
## novedades ## novedades
### adiciones ### adiciones
- sistema de amigos
#### módulos nuevos: #### módulos nuevos:
- amigos: añade o elimina amigos con la rueda del ratón, para evitar atacarles por accidente
### arreglos / mejoras ### arreglos / mejoras
- el editor del hud por defecto ahora se abre con `insertar` (no confundir con `enter`) - `destello de enchants.` ya funciona en items 2d
- renombrado todos los `frame`s a `panel`s
- `colocar en aire` ya funciona correctamente
- `delay de paquetes` no _debería_ de crashear el juego ya
## problemas reconocidos ## problemas reconocidos
- lo de siempre, además de: - lo de siempre, además de:
- `delay de paquetes` puede crashear el juego
- `inventario plus` no funciona en creativo - `inventario plus` no funciona en creativo
- `RPC de Discord` no funciona e incluso puede provocar crashes - `RPC de Discord` no funciona e incluso puede provocar crashes
- `destello de enchants.` no funciona, solamente lo hace en la armadura equipada y en ítems translúcidos. - las cajas `puntos de desconexión` están mal renderizadas
+1 -1
View File
@@ -10,6 +10,6 @@ discord_rpc_version=1.0.3
neutrino_version=1.1.0 neutrino_version=1.1.0
jdk_version=25 jdk_version=25
mod_version=4.6 mod_version=4.7
maven_group=me.retucio maven_group=me.retucio
archives_base_name=sputnik archives_base_name=sputnik
@@ -10,11 +10,9 @@ import me.retucio.sputnik.config.ConfigManager;
import me.retucio.sputnik.event.ShutdownEvent; import me.retucio.sputnik.event.ShutdownEvent;
import me.retucio.sputnik.event.interact.OpenScreenEvent; import me.retucio.sputnik.event.interact.OpenScreenEvent;
import me.retucio.sputnik.event.sputnik.LoadCapeManagerEvent; import me.retucio.sputnik.event.sputnik.*;
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.friend.FriendManager;
import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.client.Hud; import me.retucio.sputnik.module.modules.client.Hud;
@@ -111,11 +109,16 @@ public class Sputnik implements ClientModInitializer {
CommandManager.INSTANCE = new CommandManager(); CommandManager.INSTANCE = new CommandManager();
EVENT_BUS.post(new LoadCommandManagerEvent()); EVENT_BUS.post(new LoadCommandManagerEvent());
FriendManager.INSTANCE = new FriendManager();
EVENT_BUS.post(new LoadFriendManagerEvent());
mc.execute(() -> { mc.execute(() -> {
Textures.init(); Textures.init();
ClickGui.INSTANCE = new ClickGui(); ClickGui.INSTANCE = new ClickGui();
HudEditorScreen.INSTANCE = new HudEditorScreen(); HudEditorScreen.INSTANCE = new HudEditorScreen();
EVENT_BUS.post(new LoadClickGuiEvent()); EVENT_BUS.post(new LoadClickGuiEvent());
HudRenderer.init(); HudRenderer.init();
}); });
@@ -36,6 +36,7 @@ public class CommandManager {
addCommand(new ConfigCommand()); addCommand(new ConfigCommand());
addCommand(new CopyScreenshotCommand()); addCommand(new CopyScreenshotCommand());
addCommand(new EnderChestCommand()); addCommand(new EnderChestCommand());
addCommand(new FriendCommand());
addCommand(new GarbageCleanerCommand()); addCommand(new GarbageCleanerCommand());
addCommand(new PeekCommand()); addCommand(new PeekCommand());
addCommand(new PluginsCommand()); addCommand(new PluginsCommand());
@@ -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;
})
);
}
}
@@ -2,13 +2,15 @@ package me.retucio.sputnik.config;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public class BinarySerializer { public class BinarySerializer {
private static final int MAGIC_NUMBER = 0x53505554; // "SPUT" private static final int MAGIC_NUMBER = 0x53505554; // "SPUT"
private static final int VERSION = 1; private static final int VERSION = 2;
private static final byte TYPE_NULL = 0; private static final byte TYPE_NULL = 0;
private static final byte TYPE_BOOLEAN = 1; private static final byte TYPE_BOOLEAN = 1;
@@ -36,6 +38,7 @@ public class BinarySerializer {
writeStringIntArrayMap(out, config.hudPositions); writeStringIntArrayMap(out, config.hudPositions);
writeStringBooleanMap(out, config.hudVisibilities); writeStringBooleanMap(out, config.hudVisibilities);
writeStringStringMap(out, config.hudImagePaths); writeStringStringMap(out, config.hudImagePaths);
writeStringStringMap(out, config.friends);
// posición de la barra de búsqueda // posición de la barra de búsqueda
if (config.searchBarPosition != null) { if (config.searchBarPosition != null) {
@@ -82,6 +85,7 @@ public class BinarySerializer {
config.hudPositions = readStringIntArrayMap(in); config.hudPositions = readStringIntArrayMap(in);
config.hudVisibilities = readStringBooleanMap(in); config.hudVisibilities = readStringBooleanMap(in);
config.hudImagePaths = readStringStringMap(in); config.hudImagePaths = readStringStringMap(in);
config.friends = readStringStringMap(in);
// leer pos. de la barra de búsqueda // leer pos. de la barra de búsqueda
if (in.readBoolean()) { if (in.readBoolean()) {
@@ -297,8 +301,7 @@ public class BinarySerializer {
} }
} }
private static Map<String, ClientConfig.PanelData> readExtendablePanels(DataInputStream in) private static Map<String, ClientConfig.PanelData> readExtendablePanels(DataInputStream in) throws IOException {
throws IOException {
int size = in.readInt(); int size = in.readInt();
Map<String, ClientConfig.PanelData> map = new HashMap<>(size); Map<String, ClientConfig.PanelData> map = new HashMap<>(size);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@@ -336,7 +339,6 @@ public class BinarySerializer {
return map; return map;
} }
// Optimized string writing (UTF-8 with length prefix)
private static void writeString(DataOutputStream out, String str) throws IOException { private static void writeString(DataOutputStream out, String str) throws IOException {
if (str == null) { if (str == null) {
out.writeInt(-1); out.writeInt(-1);
@@ -352,6 +354,6 @@ public class BinarySerializer {
if (length == -1) return null; if (length == -1) return null;
byte[] bytes = new byte[length]; byte[] bytes = new byte[length];
in.readFully(bytes); in.readFully(bytes);
return new String(bytes, "UTF-8"); return new String(bytes, StandardCharsets.UTF_8);
} }
} }
@@ -4,10 +4,13 @@ import com.github.retucio.neutrino.EventListener;
import me.retucio.sputnik.event.sputnik.*; import me.retucio.sputnik.event.sputnik.*;
import me.retucio.sputnik.module.setting.settings.*; 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.util.ChatUtil;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import static me.retucio.sputnik.Sputnik.EVENT_BUS; import static me.retucio.sputnik.Sputnik.EVENT_BUS;
@@ -40,6 +43,9 @@ public class ClientConfig {
// posición de la barra de búsqueda (x, y) // posición de la barra de búsqueda (x, y)
public int[] searchBarPosition = new int[] { 340, 16 }; public int[] searchBarPosition = new int[] { 340, 16 };
// amigos: uuid -> nombre
public Map<String, String> friends = new HashMap<>();
public ClientConfig() { public ClientConfig() {
EVENT_BUS.subscribe(this); EVENT_BUS.subscribe(this);
} }
@@ -94,6 +100,7 @@ public class ClientConfig {
ClickGui.INSTANCE.getModulesPanel().getX(), ClickGui.INSTANCE.getModulesPanel().getX(),
ClickGui.INSTANCE.getModulesPanel().getY(), ClickGui.INSTANCE.getModulesPanel().getY(),
ClickGui.INSTANCE.getModulesPanel().extended)); ClickGui.INSTANCE.getModulesPanel().extended));
ConfigManager.save();
} }
@EventListener @EventListener
@@ -102,6 +109,7 @@ public class ClientConfig {
ClickGui.INSTANCE.getModulesPanel().getX(), ClickGui.INSTANCE.getModulesPanel().getX(),
ClickGui.INSTANCE.getModulesPanel().getY(), ClickGui.INSTANCE.getModulesPanel().getY(),
ClickGui.INSTANCE.getModulesPanel().extended)); ClickGui.INSTANCE.getModulesPanel().extended));
ConfigManager.save();
} }
@EventListener @EventListener
@@ -110,6 +118,7 @@ public class ClientConfig {
ClickGui.INSTANCE.getClientSettingsPanel().getX(), ClickGui.INSTANCE.getClientSettingsPanel().getX(),
ClickGui.INSTANCE.getClientSettingsPanel().getY(), ClickGui.INSTANCE.getClientSettingsPanel().getY(),
ClickGui.INSTANCE.getClientSettingsPanel().extended)); ClickGui.INSTANCE.getClientSettingsPanel().extended));
ConfigManager.save();
} }
@EventListener @EventListener
@@ -118,6 +127,22 @@ public class ClientConfig {
ClickGui.INSTANCE.getClientSettingsPanel().getX(), ClickGui.INSTANCE.getClientSettingsPanel().getX(),
ClickGui.INSTANCE.getClientSettingsPanel().getY(), ClickGui.INSTANCE.getClientSettingsPanel().getY(),
ClickGui.INSTANCE.getClientSettingsPanel().extended)); ClickGui.INSTANCE.getClientSettingsPanel().extended));
ConfigManager.save();
}
@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.save();
}
@EventListener
public void onRemoveFriend(FriendEvent.Remove event) {
friends.remove(event.getFriend().getUuid().toString());
ConfigManager.save();
} }
public record PanelData(int x, int y, boolean extended) implements Serializable { public record PanelData(int x, int y, boolean extended) implements Serializable {
@@ -3,6 +3,8 @@ package me.retucio.sputnik.config;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import me.retucio.sputnik.Sputnik; 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.Module;
import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.setting.*; import me.retucio.sputnik.module.setting.*;
@@ -18,6 +20,7 @@ import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
// se ocupa de guardar, cargar y aplicar ajustes // se ocupa de guardar, cargar y aplicar ajustes
@@ -58,7 +61,7 @@ public class ConfigManager {
} }
} }
// Fallback to legacy JSON // fallback to legacy JSON
if (LEGACY_JSON_FILE.exists()) { if (LEGACY_JSON_FILE.exists()) {
try (FileReader reader = new FileReader(LEGACY_JSON_FILE)) { try (FileReader reader = new FileReader(LEGACY_JSON_FILE)) {
Gson gson = new GsonBuilder().setPrettyPrinting().create(); Gson gson = new GsonBuilder().setPrettyPrinting().create();
@@ -87,6 +90,7 @@ public class ConfigManager {
applySearchBarPosition(); applySearchBarPosition();
applyClientSettings(); applyClientSettings();
applyExtendablePanels(); applyExtendablePanels();
applyFriends();
loaded = true; loaded = true;
Sputnik.LOGGER.info("ajustes aplicados"); Sputnik.LOGGER.info("ajustes aplicados");
@@ -149,8 +153,17 @@ public class ConfigManager {
// ------------------ APLICAR AJUSTES ------------------ // ------------------ APLICAR AJUSTES ------------------
public static void applyFriends() {
Sputnik.LOGGER.info("aplicando amigos: {}", config.friends);
config.friends.forEach((uuid, name) -> {
Friend friend = new Friend(UUID.fromString(uuid));
friend.setName(name);
FriendManager.INSTANCE.add(friend);
});
}
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
public static void applySetting(Module parent, Setting<?> setting) { public static void applySetting(Setting<?> setting) {
String key = getSettingKey(setting); String key = getSettingKey(setting);
if (!config.settings.containsKey(key)) return; if (!config.settings.containsKey(key)) return;
@@ -181,7 +194,7 @@ public class ConfigManager {
private static void applyModuleSettings() { private static void applyModuleSettings() {
ModuleManager.INSTANCE.getModules().forEach(module -> { ModuleManager.INSTANCE.getModules().forEach(module -> {
module.getSettings().forEach(setting -> applySetting(module, setting)); module.getSettings().forEach(ConfigManager::applySetting);
}); });
Sputnik.LOGGER.info("ajustes de módulos aplicados"); Sputnik.LOGGER.info("ajustes de módulos aplicados");
} }
@@ -211,9 +224,7 @@ public class ConfigManager {
private static void applyClientSettings() { private static void applyClientSettings() {
ClientSettingsPanel.clientSettings.setEnabled(true); ClientSettingsPanel.clientSettings.setEnabled(true);
ClientSettingsPanel.clientSettings.getSettings().forEach(setting -> { ClientSettingsPanel.clientSettings.getSettings().forEach(ConfigManager::applySetting);
applySetting(ClientSettingsPanel.clientSettings, setting);
});
Sputnik.LOGGER.info("ajustes del cliente aplicados"); Sputnik.LOGGER.info("ajustes del cliente aplicados");
} }
@@ -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); }
}
}
@@ -0,0 +1,5 @@
package me.retucio.sputnik.event.sputnik;
import com.github.retucio.neutrino.Event;
public class LoadFriendManagerEvent extends Event {}
@@ -0,0 +1,49 @@
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;
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 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);
}
}
@@ -1,7 +1,10 @@
package me.retucio.sputnik.mixin.mixins.item; package me.retucio.sputnik.mixin.mixins.item;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.retucio.sputnik.Sputnik; import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.interact.DamageItemEvent; import me.retucio.sputnik.event.interact.DamageItemEvent;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.render.GlintPlus;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
@@ -6,6 +6,7 @@ import net.minecraft.client.renderer.entity.layers.EquipmentLayerRenderer;
import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.client.renderer.rendertype.RenderType;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(EquipmentLayerRenderer.class) @Mixin(EquipmentLayerRenderer.class)
@@ -6,41 +6,27 @@ import net.minecraft.client.renderer.feature.ItemFeatureRenderer;
import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.client.renderer.rendertype.RenderType;
import net.minecraft.client.renderer.rendertype.RenderTypes; import net.minecraft.client.renderer.rendertype.RenderTypes;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ItemFeatureRenderer.class) @Mixin(ItemFeatureRenderer.class)
public abstract class ItemFeatureRendererMixin { public abstract class ItemFeatureRendererMixin {
// obtener módulo en cada redirect, ya que tiene un inicializador estático // obtener módulo en cada redirect, ya que tiene un inicializador estático
@Shadow
private static boolean useTransparentGlint(RenderType renderType) {
throw new UnsupportedOperationException("implemented via mixin");
}
@Redirect(method = "getFoilRenderType", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/feature/ItemFeatureRenderer;useTransparentGlint(Lnet/minecraft/client/renderer/rendertype/RenderType;)Z"))
private static boolean alwaysUseTranslucentGlint(RenderType renderType) {
GlintPlus glintPlus = ModuleManager.INSTANCE.getModuleByClass(GlintPlus.class);
if (!glintPlus.isEnabled()) {
useTransparentGlint(renderType);
}
return true;
}
@Redirect(method = "getFoilRenderType", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/rendertype/RenderTypes;glint()Lnet/minecraft/client/renderer/rendertype/RenderType;")) @Redirect(method = "getFoilRenderType", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/rendertype/RenderTypes;glint()Lnet/minecraft/client/renderer/rendertype/RenderType;"))
private static RenderType redirectGlint() { private static RenderType redirectGlint() {
GlintPlus glintPlus = ModuleManager.INSTANCE.getModuleByClass(GlintPlus.class); GlintPlus glintPlus = ModuleManager.INSTANCE.getModuleByClass(GlintPlus.class);
if (glintPlus == null) return RenderTypes.glint(); if (glintPlus == null) return RenderTypes.glint();
return glintPlus.getGlintTranslucent(); return glintPlus.getGlint();
} }
@Redirect(method = "getFoilRenderType", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/rendertype/RenderTypes;entityGlint()Lnet/minecraft/client/renderer/rendertype/RenderType;")) @Redirect(method = "getFoilRenderType", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/rendertype/RenderTypes;entityGlint()Lnet/minecraft/client/renderer/rendertype/RenderType;"))
private static RenderType redirectEntityGlint() { private static RenderType redirectEntityGlint() {
GlintPlus glintPlus = ModuleManager.INSTANCE.getModuleByClass(GlintPlus.class); GlintPlus glintPlus = ModuleManager.INSTANCE.getModuleByClass(GlintPlus.class);
if (glintPlus == null) return RenderTypes.entityGlint(); if (glintPlus == null) return RenderTypes.entityGlint();
return glintPlus.getGlintTranslucent(); return glintPlus.getEntityGlint();
} }
@Redirect(method = "getFoilRenderType", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/rendertype/RenderTypes;glintTranslucent()Lnet/minecraft/client/renderer/rendertype/RenderType;")) @Redirect(method = "getFoilRenderType", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/rendertype/RenderTypes;glintTranslucent()Lnet/minecraft/client/renderer/rendertype/RenderType;"))
@@ -10,7 +10,6 @@ import me.retucio.sputnik.event.render.Render3DEvent;
import me.retucio.sputnik.event.render.RenderBlockOutlineEvent; import me.retucio.sputnik.event.render.RenderBlockOutlineEvent;
import me.retucio.sputnik.module.ModuleManager; import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.camera.Freecam; import me.retucio.sputnik.module.modules.camera.Freecam;
import me.retucio.sputnik.module.modules.render.NoRender;
import net.minecraft.client.DeltaTracker; import net.minecraft.client.DeltaTracker;
import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
@@ -23,7 +22,6 @@ import org.joml.Vector4f;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.*; import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.invoke.arg.Args; import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
import static me.retucio.sputnik.Sputnik.EVENT_BUS; import static me.retucio.sputnik.Sputnik.EVENT_BUS;
@@ -3,20 +3,23 @@ package me.retucio.sputnik.mixin.mixins.render;
import com.mojang.blaze3d.vertex.ByteBufferBuilder; import com.mojang.blaze3d.vertex.ByteBufferBuilder;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import me.retucio.sputnik.util.render.GlintRenderType; import me.retucio.sputnik.util.render.GlintRenderType;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderBuffers; import net.minecraft.client.renderer.RenderBuffers;
import net.minecraft.client.renderer.rendertype.RenderType; import net.minecraft.client.renderer.rendertype.RenderType;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.SequencedMap;
@Mixin(RenderBuffers.class) @Mixin(RenderBuffers.class)
public abstract class RenderBuffersMixin { public abstract class RenderBuffersMixin {
@Inject(method = "put", at = @At("HEAD")) @Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/MultiBufferSource;immediateWithBuffers(Ljava/util/SequencedMap;Lcom/mojang/blaze3d/vertex/ByteBufferBuilder;)Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;", ordinal = 0))
private static void addGlintTypes(Object2ObjectLinkedOpenHashMap<RenderType, ByteBufferBuilder> map, RenderType type, CallbackInfo ci) { private MultiBufferSource.BufferSource injectGlintBuffers(SequencedMap<RenderType, ByteBufferBuilder> fixedBuffers, ByteBufferBuilder sharedBuffer) {
GlintRenderType.addGlintTypes(map); if (fixedBuffers instanceof Object2ObjectLinkedOpenHashMap<RenderType, ByteBufferBuilder> map) {
GlintRenderType.addGlintTypes(map);
}
return MultiBufferSource.immediateWithBuffers(fixedBuffers, sharedBuffer);
} }
} }
@@ -3,6 +3,7 @@ package me.retucio.sputnik.module;
import com.github.retucio.neutrino.EventListener; import com.github.retucio.neutrino.EventListener;
import me.retucio.sputnik.Sputnik; import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.module.modules.client.DiscordRPC; import me.retucio.sputnik.module.modules.client.DiscordRPC;
import me.retucio.sputnik.module.modules.client.Friends;
import me.retucio.sputnik.module.modules.client.Hud; import me.retucio.sputnik.module.modules.client.Hud;
import me.retucio.sputnik.module.modules.camera.*; import me.retucio.sputnik.module.modules.camera.*;
import me.retucio.sputnik.module.modules.combat.*; import me.retucio.sputnik.module.modules.combat.*;
@@ -78,6 +79,7 @@ public class ModuleManager {
private void addClient() { private void addClient() {
add(new DiscordRPC()); add(new DiscordRPC());
add(new Friends());
add(new Hud()); add(new Hud());
} }
@@ -0,0 +1,64 @@
package me.retucio.sputnik.module.modules.client;
import com.github.retucio.neutrino.EventListener;
import me.retucio.sputnik.event.input.MouseClickEvent;
import me.retucio.sputnik.event.interact.AttackEntityEvent;
import me.retucio.sputnik.friend.FriendManager;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.util.ChatUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.world.entity.Entity;
import org.lwjgl.glfw.GLFW;
public class Friends extends Module {
public BooleanSetting middleClick = sgGeneral.add(new BooleanSetting(
"ruedita para añadir amigo",
"pulsara la ruedita del ratón para (des)marcar a un jugador como amigo",
true
));
public BooleanSetting preventAttack = sgGeneral.add(new BooleanSetting(
"prevenir ataques",
"no dejar que les ataques manualmente",
true
));
public Friends() {
super("amigos", "sistema de amigos para evitar atacar a ciertos jugadores con módulos de combate", Category.CLIENT);
}
@EventListener
public void onMouseClick(MouseClickEvent event) {
if (event.getButton() == GLFW.GLFW_MOUSE_BUTTON_MIDDLE
&& event.getAction() == GLFW.GLFW_PRESS
&& middleClick.getValue())
{
Entity target = mc.crosshairPickEntity;
if (target == null) return;
if (FriendManager.INSTANCE.isFriend(target)) {
FriendManager.INSTANCE.remove(target);
ChatUtil.info(ChatFormatting.GREEN + target.getName().getString() + ChatFormatting.RESET + " ya no es tu amigo :(");
} else {
switch (FriendManager.INSTANCE.add(target)) {
case SUCCESS -> ChatUtil.info(ChatFormatting.GREEN + target.getName().getString() + ChatFormatting.RESET + " agregado como amigo :)");
case ALREADY_BEFRIENDED -> ChatUtil.warn(ChatFormatting.GREEN + target.getName().getString() + ChatFormatting.RESET + " ya es tu amigo");
case NOT_PLAYER -> ChatUtil.error("no se pudo añadir a " + ChatFormatting.GREEN + target.getName().getString() + ChatFormatting.RESET + " como amigo");
}
}
}
}
@EventListener
public void onAttack(AttackEntityEvent event) {
if (FriendManager.INSTANCE.isFriend(event.getEntity())
&& preventAttack.getValue())
{
event.cancel();
}
}
}
@@ -2,6 +2,7 @@ package me.retucio.sputnik.module.modules.combat;
import com.github.retucio.neutrino.EventListener; import com.github.retucio.neutrino.EventListener;
import me.retucio.sputnik.event.render.Render3DEvent; import me.retucio.sputnik.event.render.Render3DEvent;
import me.retucio.sputnik.friend.FriendManager;
import me.retucio.sputnik.module.Category; import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.SettingGroup; import me.retucio.sputnik.module.setting.SettingGroup;
@@ -55,6 +56,12 @@ public class CrystalAura extends Module {
5, 0, 12, 0.1 5, 0, 12, 0.1
)); ));
private final BooleanSetting ignoreFriends = sgGeneral.add(new BooleanSetting(
"ignorar amigos",
"no targetear amigos",
true
));
// ajustes al colocar los cristales // ajustes al colocar los cristales
@@ -296,6 +303,7 @@ public class CrystalAura extends Module {
if (!entity.isAlive() || entity.hasInfiniteMaterials() || entity.equals(mc.player)) continue; if (!entity.isAlive() || entity.hasInfiniteMaterials() || entity.equals(mc.player)) continue;
if (!entities.isEnabled(entity.getType())) continue; if (!entities.isEnabled(entity.getType())) continue;
if (entity.distanceToSqr(mc.player) > targetRange.getValue() * targetRange.getValue()) continue; if (entity.distanceToSqr(mc.player) > targetRange.getValue() * targetRange.getValue()) continue;
if (ignoreFriends.getValue() && FriendManager.INSTANCE.isFriend(entity)) continue;
targets.add(entity); targets.add(entity);
} }
} }
@@ -1,5 +1,6 @@
package me.retucio.sputnik.module.modules.combat; package me.retucio.sputnik.module.modules.combat;
import me.retucio.sputnik.friend.FriendManager;
import me.retucio.sputnik.module.Category; import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module; import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.settings.BooleanSetting; import me.retucio.sputnik.module.setting.settings.BooleanSetting;
@@ -30,7 +31,6 @@ public class SpearKill extends Module {
true true
)); ));
private final NumberSetting speed = sgGeneral.add(new NumberSetting( private final NumberSetting speed = sgGeneral.add(new NumberSetting(
"velocidad", "velocidad",
"velocidad del impulso", "velocidad del impulso",
@@ -40,6 +40,12 @@ public class SpearKill extends Module {
0.2 0.2
)); ));
private final BooleanSetting ignoreFriends = sgGeneral.add(new BooleanSetting(
"ignorar amigos",
"no targetear amigos",
true
));
private int heldTicks = 0; private int heldTicks = 0;
private Entity crosshairTarget; private Entity crosshairTarget;
@@ -106,18 +112,20 @@ public class SpearKill extends Module {
List<Entity> candidates = mc.level.getEntities(mc.player, List<Entity> candidates = mc.level.getEntities(mc.player,
mc.player.getBoundingBox().expandTowards(lookVec.scale(rayLength)), mc.player.getBoundingBox().expandTowards(lookVec.scale(rayLength)),
e -> e instanceof LivingEntity && e.isAlive() && e != mc.player); e -> e instanceof LivingEntity
&& e.isAlive() && e != mc.player
&& (!ignoreFriends.getValue() || FriendManager.INSTANCE.isFriend(e)));
candidates.sort(Comparator.comparingDouble(e -> candidates.sort(Comparator.comparingDouble(e ->
eyePos.distanceToSqr(e.getBoundingBox().getCenter()))); eyePos.distanceToSqr(e.getBoundingBox().getCenter())));
double coneAngle = 0.999; double coneAngle = 0.999;
for (Entity e : candidates) { for (Entity entity : candidates) {
if (eyePos.distanceTo(e.getBoundingBox().getCenter()) > rayLength) break; if (eyePos.distanceTo(entity.getBoundingBox().getCenter()) > rayLength) break;
Vec3 toEntity = e.getBoundingBox().getCenter().subtract(eyePos).normalize(); Vec3 toEntity = entity.getBoundingBox().getCenter().subtract(eyePos).normalize();
if (lookVec.dot(toEntity) > coneAngle && if (lookVec.dot(toEntity) > coneAngle &&
(!onlyPlayers.getValue() || e instanceof Player)) { (!onlyPlayers.getValue() || entity instanceof Player)) {
return e; return entity;
} }
} }
@@ -58,4 +58,8 @@ public class FakePlayer extends Module {
player.onClientRemoval(); player.onClientRemoval();
player = null; player = null;
} }
public RemotePlayer getPlayer() {
return player;
}
} }
@@ -108,6 +108,47 @@ public class EntityUtil {
)); ));
} }
public static Vec3 getHorizontalVelocity(double bps) {
float yaw = mc.player.getYRot();
Vec3 forward = Vec3.directionFromRotation(0, yaw);
Vec3 right = Vec3.directionFromRotation(0, yaw + 90);
double velX = 0;
double velZ = 0;
boolean x = false;
if (mc.player.input.keyPresses.right()) {
velX += right.x / 20 * bps;
velZ += right.z / 20 * bps;
x = true;
}
if (mc.player.input.keyPresses.left()) {
velX -= right.x / 20 * bps;
velZ -= right.z / 20 * bps;
x = true;
}
boolean z = false;
if (mc.player.input.keyPresses.forward()) {
velX += forward.x / 20 * bps;
velZ += forward.z / 20 * bps;
z = true;
}
if (mc.player.input.keyPresses.backward()) {
velX -= forward.x / 20 * bps;
velZ -= forward.z / 20 * bps;
z = true;
}
if (x && z) {
velX /= Mth.SQRT_OF_TWO;
velZ /= Mth.SQRT_OF_TWO;
}
return new Vec3(velX, 0, velZ);
}
public enum Target { public enum Target {
HEAD, HEAD,
BODY, BODY,
@@ -1,8 +1,6 @@
package me.retucio.sputnik.util.render; package me.retucio.sputnik.util.render;
import com.mojang.blaze3d.vertex.ByteBufferBuilder; import com.mojang.blaze3d.vertex.ByteBufferBuilder;
import com.mojang.blaze3d.vertex.MeshData;
import com.mojang.blaze3d.vertex.VertexFormat;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import me.retucio.sputnik.Sputnik; import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.module.modules.render.GlintPlus; import me.retucio.sputnik.module.modules.render.GlintPlus;
@@ -10,25 +8,24 @@ import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.client.renderer.rendertype.*; import net.minecraft.client.renderer.rendertype.*;
import net.minecraft.resources.Identifier; import net.minecraft.resources.Identifier;
import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.DyeColor;
import org.jspecify.annotations.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
/** clase modificada de RenderType para modificar el color del destello de encantamientos /** utilidad para crear RenderTypes de glint con color personalizado
* @see GlintPlus * @see GlintPlus
* yoinkeado de: https://github.com/Pepperoni-Jabroni/NoMorePurple/blob/main/src/main/java/pepjebs/no_more_purple/client/GlintRenderLayer.java * yoinkeado de: https://github.com/Pepperoni-Jabroni/NoMorePurple/blob/main/src/main/java/pepjebs/no_more_purple/client/GlintRenderLayer.java
* (y actualizado) * (y actualizado)
*/ */
public class GlintRenderType extends RenderType { public class GlintRenderType {
public static List<RenderType> glintColor = newRenderList(GlintRenderType::buildGlintRenderType); public static final List<RenderType> glintColor = newRenderList(GlintRenderType::buildGlintRenderType);
public static List<RenderType> entityGlintColor = newRenderList(GlintRenderType::buildEntityGlintRenderType); public static final List<RenderType> entityGlintColor = newRenderList(GlintRenderType::buildEntityGlintRenderType);
public static List<RenderType> armorEntityGlintColor = newRenderList(GlintRenderType::buildArmorEntityGlintRenderType); public static final List<RenderType> armorEntityGlintColor = newRenderList(GlintRenderType::buildArmorEntityGlintRenderType);
public static List<RenderType> glintTranslucentColor = newRenderList(GlintRenderType::buildGlintTranslucentRenderType); public static final List<RenderType> glintTranslucentColor = newRenderList(GlintRenderType::buildGlintTranslucentRenderType);
public static void addGlintTypes(Object2ObjectLinkedOpenHashMap<RenderType, ByteBufferBuilder> map) { public static void addGlintTypes(Object2ObjectLinkedOpenHashMap<RenderType, ByteBufferBuilder> map) {
addGlintTypes(map, glintColor); addGlintTypes(map, glintColor);
@@ -37,12 +34,8 @@ public class GlintRenderType extends RenderType {
addGlintTypes(map, armorEntityGlintColor); addGlintTypes(map, armorEntityGlintColor);
} }
public GlintRenderType(String name) {
super(name, RenderSetup.builder(RenderPipelines.GLINT).createRenderSetup());
}
private static List<RenderType> newRenderList(Function<String, RenderType> func) { private static List<RenderType> newRenderList(Function<String, RenderType> func) {
ArrayList<RenderType> list = new ArrayList<>(DyeColor.values().length); ArrayList<RenderType> list = new ArrayList<>(DyeColor.values().length + 2);
for (DyeColor color : DyeColor.values()) for (DyeColor color : DyeColor.values())
list.add(func.apply(color.name())); list.add(func.apply(color.name()));
@@ -54,65 +47,54 @@ public class GlintRenderType extends RenderType {
} }
public static void addGlintTypes(Object2ObjectLinkedOpenHashMap<RenderType, ByteBufferBuilder> map, List<RenderType> typeList) { public static void addGlintTypes(Object2ObjectLinkedOpenHashMap<RenderType, ByteBufferBuilder> map, List<RenderType> typeList) {
for(RenderType renderType : typeList) for (RenderType renderType : typeList)
if (!map.containsKey(renderType)) if (!map.containsKey(renderType))
map.put(renderType, new ByteBufferBuilder(renderType.bufferSize())); map.put(renderType, new ByteBufferBuilder(renderType.bufferSize()));
} }
private static RenderType buildGlintRenderType(String name) { private static RenderType buildGlintRenderType(String name) {
final Identifier res = Identifier.fromNamespaceAndPath(Sputnik.MOD_ID, "textures/misc/glint_" + name.toLowerCase() + ".png"); final Identifier res = Identifier.fromNamespaceAndPath(Sputnik.MOD_ID, "textures/misc/glint_" + name.toLowerCase() + ".png");
return RenderType.create( return RenderType.create(
"glint_" + name, "glint_" + name,
RenderSetup.builder(RenderPipelines.GLINT) RenderSetup.builder(RenderPipelines.GLINT)
.withTexture("Sampler0", res) .withTexture("Sampler0", res)
.setTextureTransform(TextureTransform.GLINT_TEXTURING) .setTextureTransform(TextureTransform.GLINT_TEXTURING)
.setOutputTarget(OutputTarget.ITEM_ENTITY_TARGET) .createRenderSetup()
.createRenderSetup()
); );
} }
private static RenderType buildGlintTranslucentRenderType(String name) { private static RenderType buildGlintTranslucentRenderType(String name) {
final Identifier res = Identifier.fromNamespaceAndPath(Sputnik.MOD_ID, "textures/misc/glint_" + name.toLowerCase() + ".png"); final Identifier res = Identifier.fromNamespaceAndPath(Sputnik.MOD_ID, "textures/misc/glint_" + name.toLowerCase() + ".png");
return RenderType.create( return RenderType.create(
"glint_translucent_" + name, "glint_translucent_" + name,
RenderSetup.builder(RenderPipelines.GLINT) RenderSetup.builder(RenderPipelines.GLINT)
.withTexture("Sampler0", res) .withTexture("Sampler0", res)
.setTextureTransform(TextureTransform.GLINT_TEXTURING) .setTextureTransform(TextureTransform.GLINT_TEXTURING)
.setOutputTarget(OutputTarget.ITEM_ENTITY_TARGET) .setOutputTarget(OutputTarget.ITEM_ENTITY_TARGET)
.createRenderSetup() .createRenderSetup()
); );
} }
private static RenderType buildEntityGlintRenderType(String name) { private static RenderType buildEntityGlintRenderType(String name) {
final Identifier res = Identifier.fromNamespaceAndPath(Sputnik.MOD_ID, "textures/misc/glint_" + name.toLowerCase() + ".png"); final Identifier res = Identifier.fromNamespaceAndPath(Sputnik.MOD_ID, "textures/misc/glint_" + name.toLowerCase() + ".png");
return RenderType.create( return RenderType.create(
"entity_glint_" + name, "entity_glint_" + name,
RenderSetup.builder(RenderPipelines.GLINT) RenderSetup.builder(RenderPipelines.GLINT)
.withTexture("Sampler0", res) .withTexture("Sampler0", res)
.setTextureTransform(TextureTransform.ENTITY_GLINT_TEXTURING) .setTextureTransform(TextureTransform.ENTITY_GLINT_TEXTURING)
.createRenderSetup() .createRenderSetup()
); );
} }
private static RenderType buildArmorEntityGlintRenderType(String name) { private static RenderType buildArmorEntityGlintRenderType(String name) {
final Identifier res = Identifier.fromNamespaceAndPath(Sputnik.MOD_ID, "textures/misc/glint_" + name.toLowerCase() + ".png"); final Identifier res = Identifier.fromNamespaceAndPath(Sputnik.MOD_ID, "textures/misc/glint_" + name.toLowerCase() + ".png");
return RenderType.create( return RenderType.create(
"armor_glint_" + name, "armor_glint_" + name,
RenderSetup.builder(RenderPipelines.GLINT) RenderSetup.builder(RenderPipelines.GLINT)
.withTexture("Sampler0", res) .withTexture("Sampler0", res)
.setTextureTransform(TextureTransform.ARMOR_ENTITY_GLINT_TEXTURING) .setTextureTransform(TextureTransform.ARMOR_ENTITY_GLINT_TEXTURING)
.setLayeringTransform(LayeringTransform.VIEW_OFFSET_Z_LAYERING) .setLayeringTransform(LayeringTransform.VIEW_OFFSET_Z_LAYERING)
.createRenderSetup() .createRenderSetup()
); );
} }
@Override
public void draw(@NonNull MeshData buffer) {}
@Override
public @NonNull VertexFormat format() { return VertexFormat.builder().build(); }
} }