This commit is contained in:
retuci0 committed 2026-04-28 17:38:38 +02:00
1 parent 1d22ec5176
commit ac99a609a0
16 files changed
+206 -105

No files matched your search

+13 -5
View File
@@ -31,7 +31,7 @@ dependencies {
include(implementation "com.github.retuci0:neutrino:${project.neutrino_version}")
// rpc de discord
include(implementation "dev.firstdark.discordrpc:discord-rpc:1.0.3")
include(implementation "dev.firstdark.discordrpc:discord-rpc:${project.discord_rpc_version}")
}
loom {
@@ -40,19 +40,27 @@ loom {
processResources {
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
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 = 25
it.options.release = jdk_version.toInteger()
}
java {
sourceCompatibility = JavaVersion.VERSION_25
targetCompatibility = JavaVersion.VERSION_25
sourceCompatibility = JavaVersion.toVersion(jdk_version)
targetCompatibility = JavaVersion.toVersion(jdk_version)
}
jar {
+4 -7
View File
@@ -1,19 +1,16 @@
# v4.1
# v4.2
## novedades
- actualizado a 26.1
### adiciones
#### módulos nuevos:
- autopechera: equipa una pechera antes de atacar con el mazo
### arreglos / mejoras
- arreglado el cálculo de anchura de los marcos de ajustes para tener en cuenta los botones de los ajustes de colores
- freecam ya no crashea, pero el movimiento se siente laggy
## problemas reconocidos
- lo de siempre
- brilli brilli (modo gamma) solo funciona al cambiar el modo de poción a gamma, y no al activarlo sin más
- lo de siempre, pero más
+3 -2
View File
@@ -6,9 +6,10 @@ 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=4.1
mod_version=4.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-9.4.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
@@ -4,12 +4,12 @@ import me.retucio.sputnik.Sputnik;
import net.minecraft.client.Minecraft;
import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.ReloadableTexture;
import net.minecraft.resources.Identifier;
import java.io.IOException;
import java.io.InputStream;
public class Cape {
private final Minecraft mc = Minecraft.getInstance();
@@ -25,6 +25,7 @@ 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;
@@ -66,52 +67,6 @@ public abstract class EntityMixin {
rotations = ModuleManager.INSTANCE.getModuleByClass(Rotations.class);
}
@Inject(method = "pick", at = @At("HEAD"), cancellable = true)
private void updateTargetedEntityInvoke(double range, float a, boolean withLiquids, CallbackInfoReturnable<HitResult> cir) {
Minecraft mc = Minecraft.getInstance();
if ((freecam.isEnabled()) && mc.getCameraEntity() != null && !freecamDone) {
cir.cancel();
Entity cameraEntity = mc.getCameraEntity();
Vector3d pos = freecam.getPos();
Vector3d prevPos = freecam.getPrevPos();
double x = cameraEntity.getX();
double y = cameraEntity.getY();
double z = cameraEntity.getZ();
double lastX = cameraEntity.xo;
double lastY = cameraEntity.yo;
double lastZ = cameraEntity.zo;
float yaw = cameraEntity.getYRot();
float pitch = cameraEntity.getXRot();
float lastYaw = cameraEntity.yRotO;
float lastPitch = cameraEntity.xRotO;
((IVec3) cameraEntity.position()).sputnik$set(pos.x, pos.y - cameraEntity.getEyeHeight(cameraEntity.getPose()), pos.z);
cameraEntity.xo = prevPos.x;
cameraEntity.yo = prevPos.y - cameraEntity.getEyeHeight(cameraEntity.getPose());
cameraEntity.zo = prevPos.z;
cameraEntity.setYRot(freecam.getYaw());
cameraEntity.setXRot(freecam.getPitch());
cameraEntity.yRotO = freecam.getPrevYaw();
cameraEntity.xRotO = freecam.getPrevPitch();
freecamDone = true;
pick(range, a, withLiquids);
freecamDone = false;
((IVec3) cameraEntity.position()).sputnik$set(x, y, z);
cameraEntity.xo = lastX;
cameraEntity.yo = lastY;
cameraEntity.zo = lastZ;
cameraEntity.setYRot(yaw);
cameraEntity.setXRot(pitch);
cameraEntity.yRotO = lastYaw;
cameraEntity.xRotO = lastPitch;
}
}
// cámara libre & perspectiva libre
@SuppressWarnings("ConstantConditions")
@@ -120,7 +75,7 @@ public abstract class EntityMixin {
if ((Object) this != Sputnik.mc.player) return;
if (freecam.isEnabled()) {
freecam.changeLookDirection(xo * 0.15, yo * 0.15);
freecam.changeLookDirection(xo * 0.15f, yo * 0.15f);
ci.cancel();
} else if (freelook.isEnabled() && freelook.mode.is(Freelook.CameraMode.CAMERA)) {
@@ -19,7 +19,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Gui.class)
public abstract class InGameHudMixin {
public abstract class GuiMixin {
@Unique
NoRender noRender;
@@ -8,11 +8,14 @@ import me.retucio.sputnik.event.ShutdownEvent;
import me.retucio.sputnik.event.TickEvent;
import me.retucio.sputnik.event.interact.UseItemEvent;
import me.retucio.sputnik.module.ModuleManager;
import me.retucio.sputnik.module.modules.camera.Freecam;
import me.retucio.sputnik.module.modules.player.FastUse;
import me.retucio.sputnik.util.interfaces.IVec3;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.*;
@@ -30,12 +33,20 @@ public abstract class MinecraftMixin {
@Shadow
private static Minecraft instance;
@Unique
private boolean freecamSet = false;
// eventos
@Shadow @Nullable
public Screen screen;
@Shadow
public abstract @Nullable Entity getCameraEntity();
@Shadow
protected abstract void pick(float partialTicks);
@Inject(method = "tick", at = @At("HEAD"))
private void onTickPre(CallbackInfo ci) {
Sputnik.INSTANCE.onTick();
@@ -87,4 +98,55 @@ public abstract class MinecraftMixin {
if (!fastUse.isEnabled()) return;
rightClickDelay = fastUse.getCooldown(stack);
}
// cámara libre
@Inject(method = "pick", at = @At("HEAD"), cancellable = true)
private void updateTargetedEntityInvoke(float partialTicks, CallbackInfo ci) {
Freecam freecam = ModuleManager.INSTANCE.getModuleByClass(Freecam.class);
if ((freecam.isEnabled()) && this.getCameraEntity() != null && !freecamSet) {
ci.cancel();
Entity cameraEntity = this.getCameraEntity();
double x = cameraEntity.getX();
double y = cameraEntity.getY();
double z = cameraEntity.getZ();
double lastX = cameraEntity.xo;
double lastY = cameraEntity.yo;
double lastZ = cameraEntity.zo;
float yaw = cameraEntity.getYRot();
float pitch = cameraEntity.getXRot();
float lastYaw = cameraEntity.yRotO;
float lastPitch = cameraEntity.xRotO;
((IVec3) cameraEntity.position()).sputnik$set(
freecam.getPos().x,
freecam.getPos().y - cameraEntity.getEyeHeight(cameraEntity.getPose()),
freecam.getPos().z
);
cameraEntity.xo = freecam.getPrevPos().x;
cameraEntity.yo = freecam.getPrevPos().y - cameraEntity.getEyeHeight(cameraEntity.getPose());
cameraEntity.zo = freecam.getPrevPos().z;
cameraEntity.setYRot(freecam.getYaw());
cameraEntity.setXRot(freecam.getPitch());
cameraEntity.yRotO = freecam.getPrevYaw();
cameraEntity.xRotO = freecam.getPrevPitch();
freecamSet = true;
pick(partialTicks);
freecamSet = false;
((IVec3) cameraEntity.position()).sputnik$set(x, y, z);
cameraEntity.xo = lastX;
cameraEntity.yo = lastY;
cameraEntity.zo = lastZ;
cameraEntity.setYRot(yaw);
cameraEntity.setXRot(pitch);
cameraEntity.yRotO = lastYaw;
cameraEntity.xRotO = lastPitch;
}
}
}
@@ -48,24 +48,69 @@ import org.lwjgl.glfw.GLFW;
public class Freecam extends Module {
// ajustes
private final SettingGroup sgSpeed = addSg(new SettingGroup("velocidad", true));
private final BooleanSetting toggleOnDamage = sgGeneral.add(new BooleanSetting("desactivar al recibir daño", "desactiva el módulo tras recibir daño", true));
private final BooleanSetting reloadChunks = sgGeneral.add(new BooleanSetting("recargar chunks", "recargar chunks para arreglar el culling de las cuevas", true));
public final BooleanSetting renderHands = sgGeneral.add(new BooleanSetting("manos visibles", "decide si se renderizan las manos mientras la cámara esté libre", true));
public final BooleanSetting stayCrouching = sgGeneral.add(new BooleanSetting("mantenerse agachado", "mantener al jugador agachado tras entrar en el modo de cámara libre", false));
private final BooleanSetting staticView = sgGeneral.add(new BooleanSetting("visión estática", "desactiva ajustes que muevan la cámara", true));
private final BooleanSetting cancelActionPackets = sgGeneral.add(new BooleanSetting("cancelar paquetes", "evita flaggear el anticheat al interactuar con bloques / entidades", true));
public final BooleanSetting blockOutlines = sgGeneral.add(new BooleanSetting("contorno de bloques", "mostrar el contorno de los bloques estando en el modo de cámara libre", true));
private final BooleanSetting toggleOnDamage = sgGeneral.add(new BooleanSetting(
"desactivar al recibir daño",
"desactiva el módulo tras recibir daño",
true
));
private final BooleanSetting reloadChunks = sgGeneral.add(new BooleanSetting(
"recargar chunks",
"recargar chunks para arreglar el culling de las cuevas",
true
));
public final BooleanSetting renderHands = sgGeneral.add(new BooleanSetting(
"manos visibles",
"decide si se renderizan las manos mientras la cámara esté libre",
true
));
public final BooleanSetting stayCrouching = sgGeneral.add(new BooleanSetting(
"mantenerse agachado",
"mantener al jugador agachado tras entrar en el modo de cámara libre",
false
));
private final BooleanSetting staticView = sgGeneral.add(new BooleanSetting(
"visión estática",
"desactiva ajustes que muevan la cámara",
true
));
private final BooleanSetting cancelActionPackets = sgGeneral.add(new BooleanSetting(
"cancelar paquetes",
"evita flaggear el anticheat al interactuar con bloques / entidades",
true
));
public final BooleanSetting blockOutlines = sgGeneral.add(new BooleanSetting(
"contorno de bloques",
"mostrar el contorno de los bloques estando en el modo de cámara libre",
true
));
private final NumberSetting speedSetting = sgSpeed.add(new NumberSetting(
"velocidad", "velocidad de movimiento de la cámara",
1, 0, 10, 0.2));
"velocidad",
"velocidad de movimiento de la cámara",
1, 0, 10, 0.2
));
private final KeySetting scrollKey = sgSpeed.add(new KeySetting(
"tecla del scroll",
"tecla a mantener pulsada para cambiar velocidad con el scroll",
GLFW.GLFW_KEY_LEFT_CONTROL
));
private final KeySetting scrollKey = sgSpeed.add(new KeySetting("tecla del scroll", "tecla a mantener pulsada para cambiar velocidad con el scroll", GLFW.GLFW_KEY_LEFT_CONTROL));
private final NumberSetting scrollSens = sgSpeed.add(new NumberSetting(
"sensibilidad del scroll", "sensibilidad de la rueda del ratón para modificar la velocidad, 0 para desactivar",
1, 0, 2, 0.1));
"sensibilidad del scroll",
"sensibilidad de la rueda del ratón para modificar la velocidad, 0 para desactivar",
1, 0, 2, 0.1
));
private final Vector3d prevPos = new Vector3d();
@@ -74,7 +119,8 @@ public class Freecam extends Module {
private final Vector3d pos = new Vector3d();
private CameraType perspective;
private double fovScale, speed;
private boolean forward, backward, right, left, up, down, crouching, viewBobbing;
private boolean forward, backward, right,
left, up, down, crouching, viewBobbing;
private float yaw, pitch;
public Freecam() {
@@ -34,6 +34,7 @@ public class Fullbright extends Module {
false
)).visibility(() -> mode.is(Modes.GAMMA));
public Fullbright() {
super("brilli brilli",
"deshabilita la oscuridad (y aplica colores a los shaders)",
@@ -41,10 +42,6 @@ public class Fullbright extends Module {
GLFW.GLFW_KEY_K);
mode.onUpdate(mode -> { if (mode != Modes.POTION) disableNightVision(); });
mode.onUpdate(mode -> {
boolean v = mode.equals(Modes.GAMMA);
if (v) disableNightVision();
});
}
@Override
@@ -67,9 +64,10 @@ public class Fullbright extends Module {
private void disableNightVision() {
if (mc.player == null) return;
if (mc.player.hasEffect(BuiltInRegistries.MOB_EFFECT.wrapAsHolder(MobEffects.NIGHT_VISION.value())))
if (mc.player.hasEffect(BuiltInRegistries.MOB_EFFECT.wrapAsHolder(MobEffects.NIGHT_VISION.value()))) {
mc.player.removeEffect(BuiltInRegistries.MOB_EFFECT.wrapAsHolder(MobEffects.NIGHT_VISION.value()));
}
}
public enum Modes {
@@ -10,7 +10,7 @@ import me.retucio.sputnik.event.input.ClientClickEvent;
import me.retucio.sputnik.event.network.ReceiveMessageEvent;
import me.retucio.sputnik.event.network.SendMessageEvent;
import me.retucio.sputnik.mixin.mixins.hud.ChatComponentMixin;
import me.retucio.sputnik.mixin.mixins.hud.InGameHudMixin;
import me.retucio.sputnik.mixin.mixins.hud.GuiMixin;
import me.retucio.sputnik.mixin.mixins.misc.StringUtilMixin;
import me.retucio.sputnik.mixin.mixins.screen.ChatScreenMixin;
import me.retucio.sputnik.module.Category;
@@ -45,7 +45,7 @@ import java.util.regex.Pattern;
/** continúa en:
* @see ChatComponentMixin
* @see ChatScreenMixin
* @see InGameHudMixin
* @see GuiMixin
* @see StringUtilMixin
*/
@@ -186,6 +186,12 @@ public class Scaffold extends Module {
0.1
)).visibility(showLastPlaced::getValue);
private final BooleanSetting swingHand = sgRender.add(new BooleanSetting(
"mover mano",
"mover la mano al colocar bloques",
true
));
private final BlockPos.MutableBlockPos bp = new BlockPos.MutableBlockPos();
private final List<PlacedBlock> lastPlacedBlocks = new ArrayList<>();
@@ -330,7 +336,8 @@ public class Scaffold extends Module {
pos, InteractionHand.MAIN_HAND,
mc.player.getInventory().getSelectedSlot(),
rotate.getValue(),
false,
rotate.getValue(),
swingHand.getValue(),
true,
true
)) {
@@ -1,6 +1,6 @@
package me.retucio.sputnik.module.modules.render;
import me.retucio.sputnik.mixin.mixins.hud.InGameHudMixin;
import me.retucio.sputnik.mixin.mixins.hud.GuiMixin;
import me.retucio.sputnik.mixin.mixins.network.ClientPacketListenerMixin;
import me.retucio.sputnik.mixin.mixins.render.*;
import me.retucio.sputnik.mixin.mixins.world.ParticleEngineMixin;
@@ -18,7 +18,7 @@ import net.minecraft.core.particles.ParticleType;
* @see ClientPacketListenerMixin
* @see FogRendererMixin
* @see GameRendererMixin
* @see InGameHudMixin
* @see GuiMixin
* @see ScreenEffectRendererMixin
* @see ParticleEngineMixin
* @see MobEffectFogEnvironmentMixin
@@ -16,12 +16,12 @@ import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import java.util.ArrayList;
import java.util.List;
@@ -31,7 +31,9 @@ public class NetworkUtil {
private static final Minecraft mc = Minecraft.getInstance();
// tps
private static final List<Float> tpsHistory = new ArrayList<>();
private static float estimatedTPS = 20f;
private static long lastWorldTime = -1L;
@@ -75,6 +77,7 @@ public class NetworkUtil {
}
public static void sendPacketNoEvent(Packet<?> packet) {
mc.getConnection().getConnection().sendPacket(packet, null, true);
}
@@ -87,6 +90,8 @@ public class NetworkUtil {
Connection.genericsFtw(packet, listener);
}
// interactuar con un bloque mediante MultiPlayerGameMode
public static void interactBlock(BlockHitResult blockHitResult, InteractionHand hand, boolean swing) {
boolean wasSneaking = mc.player.isCrouching();
mc.player.setShiftKeyDown(false);
@@ -101,19 +106,22 @@ public class NetworkUtil {
mc.player.setShiftKeyDown(wasSneaking);
}
public static boolean placeBlock(BlockPos blockPos, InteractionHand hand, int slot, boolean rotate,
boolean swingHand, boolean checkEntities, boolean swapBack) {
if (slot < 0 || slot > 8) return false;
// colocar un bloque
public static boolean placeBlock(BlockPos blockPos, InteractionHand hand, int slot,
boolean rotateClient, boolean rotateServer, boolean swingHand,
boolean checkEntities, boolean swapBack)
{
if (slot < 0 || slot > 8 || mc.player == null) return false;
Block toPlace = Blocks.OBSIDIAN;
ItemStack i = hand == InteractionHand.MAIN_HAND ? mc.player.getInventory().getItem(slot) : mc.player.getOffhandItem();
if (i.getItem() instanceof BlockItem blockItem) toPlace = blockItem.getBlock();
ItemStack stack = hand == InteractionHand.MAIN_HAND ? mc.player.getInventory().getItem(slot) : mc.player.getOffhandItem();
if (stack.getItem() instanceof BlockItem blockItem) toPlace = blockItem.getBlock();
if (!canPlaceBlock(blockPos, checkEntities, toPlace)) return false;
Vec3 hitPos = Vec3.atCenterOf(blockPos);
BlockPos neighbour;
Direction side = getClosestSide(blockPos);
Direction side = getPlaceSide(blockPos);
if (side == null) {
side = Direction.UP;
@@ -124,12 +132,10 @@ public class NetworkUtil {
}
BlockHitResult bhr = new BlockHitResult(hitPos, side.getOpposite(), neighbour, false);
int prevSlot = mc.player.getInventory().getSelectedSlot();
if (rotate) {
EntityUtil.lookAtServer(hitPos);
}
if (rotateClient) EntityUtil.lookAtClient(hitPos);
if (rotateServer) EntityUtil.lookAtServer(hitPos);
InventoryUtil.swapWithHotbar(mc.player.getInventory().getSelectedSlot(), slot);
interactBlock(bhr, hand, swingHand);
@@ -141,6 +147,7 @@ public class NetworkUtil {
return true;
}
// retorna verdadero si puede colocar un bloque de tipo `block` en `blockPos`
public static boolean canPlaceBlock(BlockPos blockPos, boolean checkEntities, Block block) {
if (blockPos == null) return false;
if (!Level.isInSpawnableBounds(blockPos)) return false;
@@ -148,7 +155,9 @@ public class NetworkUtil {
return !checkEntities || mc.level.isUnobstructed(block.defaultBlockState(), blockPos, CollisionContext.empty());
}
public static Direction getClosestSide(BlockPos blockPos) {
// retorna la dirección desde la que el jugador colocará bloques
public static Direction getPlaceSide(BlockPos blockPos) {
Vec3 lookVec = blockPos.getCenter().subtract(mc.player.getEyePosition());
double bestRelevancy = -Double.MAX_VALUE;
Direction bestSide = null;
@@ -157,7 +166,7 @@ public class NetworkUtil {
BlockPos neighbor = blockPos.relative(side);
BlockState state = mc.level.getBlockState(neighbor);
if (state.isAir()) continue;
if (state.isAir() || isInteractableBlock(state.getBlock())) continue;
if (!state.getFluidState().isEmpty()) continue;
@@ -170,4 +179,22 @@ public class NetworkUtil {
return bestSide;
}
// retorna verdadero si es un bloque interactuable
public static boolean isInteractableBlock(Block block) {
return block instanceof CraftingTableBlock
|| block instanceof AnvilBlock
|| block instanceof LoomBlock
|| block instanceof CartographyTableBlock
|| block instanceof GrindstoneBlock
|| block instanceof StonecutterBlock
|| block instanceof ButtonBlock
|| block instanceof BasePressurePlateBlock
|| block instanceof BaseEntityBlock
|| block instanceof BedBlock
|| block instanceof FenceGateBlock
|| block instanceof DoorBlock
|| block instanceof NoteBlock
|| block instanceof TrapDoorBlock;
}
}
+3 -3
View File
@@ -25,9 +25,9 @@
],
"accessWidener": "sputnik.accesswidener",
"depends": {
"fabricloader": ">=0.19.2",
"minecraft": "~26.1.2",
"java": ">=25",
"fabricloader": ">=${loader_version}",
"minecraft": "~${minecraft_version}",
"java": ">=${jdk_version}",
"fabric-api": "*"
},
"suggests": {}
+1 -1
View File
@@ -49,7 +49,7 @@
"mixins.hud.DrawingFocusedGraphicsAccessMixin",
"mixins.hud.GuiMessageLineMixin",
"mixins.hud.GuiMessageMixin",
"mixins.hud.InGameHudMixin",
"mixins.hud.GuiMixin",
"mixins.io.KeyboardHandlerMixin",
"mixins.io.MouseHandlerMixin",
"mixins.io.ScreenshotMixin",