This commit is contained in:
retuci0 committed 2026-03-23 19:39:59 +01:00
1 parent a879458b4a
commit 05c5300cd8
11 files changed
+480 -17

No files matched your search

+4 -4
View File
@@ -1,4 +1,4 @@
# v3.9
# v4.0
## novedades
@@ -6,12 +6,12 @@
#### módulos nuevos:
- escaleras veloces: sube escaleras más rápido
- parkour: salta automáticamente
- confetti: cambia el color de las partículas del pop del tótem
- aura de cristales: hace cpvp por ti (muy mejorable, estoy en ello)
### arreglos / mejoras
- `$echest` ya funciona y tal
## problemas reconocidos
- lo de siempre
+1 -1
View File
@@ -10,6 +10,6 @@ fabric_api_version=0.140.2+1.21.11
neutrino_version=1.1.0
mod_version=3.9
mod_version=4.0
maven_group=me.retucio
archives_base_name=sputnik
@@ -96,6 +96,8 @@ public class Sputnik implements ClientModInitializer {
EVENT_BUS.subscribe(NetworkUtil.class);
EVENT_BUS.subscribe(RenderUtil.class);
EVENT_BUS.subscribe(BlockIterator.class);
Lists.init();
Textures.init();
@@ -5,10 +5,7 @@ import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.module.modules.client.DiscordRPC;
import me.retucio.sputnik.module.modules.client.HUD;
import me.retucio.sputnik.module.modules.camera.*;
import me.retucio.sputnik.module.modules.combat.AttributeSwapper;
import me.retucio.sputnik.module.modules.combat.MaceKill;
import me.retucio.sputnik.module.modules.combat.ProjectileTrajectories;
import me.retucio.sputnik.module.modules.combat.SpearKill;
import me.retucio.sputnik.module.modules.combat.*;
import me.retucio.sputnik.module.modules.inventory.*;
import me.retucio.sputnik.module.modules.misc.*;
import me.retucio.sputnik.module.modules.movement.*;
@@ -40,6 +37,7 @@ public class ModuleManager {
// añadir los módulos
addCamera();
addClient();
addCombat();
addInventory();
addMisc();
addMovement();
@@ -67,7 +65,6 @@ public class ModuleManager {
private void addCamera() {
add(new Autism());
add(new Freecam());
@@ -83,6 +80,14 @@ public class ModuleManager {
add(new HUD());
}
private void addCombat() {
add(new AttributeSwapper());
add(new CrystalAura());
add(new MaceKill());
add(new ProjectileTrajectories());
add(new SpearKill());
}
private void addMisc() {
add(new AntiInvis());
add(new AnvilFont());
@@ -138,15 +143,12 @@ public class ModuleManager {
private void addPlayer() {
add(new AirPlace());
add(new AntiHunger());
add(new AttributeSwapper());
add(new AutoFish());
add(new Capes());
add(new FastUse());
add(new HandView());
add(new KeyPearl());
add(new MaceKill());
add(new NoFall());
add(new SpearKill());
add(new WarnLowDurability());
}
@@ -175,7 +177,6 @@ public class ModuleManager {
add(new ColoredSigns());
add(new LightOverlay());
add(new NoMiningInterruptions());
add(new ProjectileTrajectories());
add(new Racist());
add(new StrongholdTriangulator());
add(new TimeChanger());
@@ -0,0 +1,295 @@
package me.retucio.sputnik.module.modules.combat;
import com.github.retucio.neutrino.EventListener;
import me.retucio.sputnik.event.render.Render3DEvent;
import me.retucio.sputnik.module.Category;
import me.retucio.sputnik.module.Module;
import me.retucio.sputnik.module.setting.SettingGroup;
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
import me.retucio.sputnik.module.setting.settings.ColorSetting;
import me.retucio.sputnik.module.setting.settings.ListSetting;
import me.retucio.sputnik.module.setting.settings.NumberSetting;
import me.retucio.sputnik.util.*;
import me.retucio.sputnik.util.render.RenderUtil;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.decoration.EndCrystalEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.Items;
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext;
import java.util.ArrayList;
import java.util.List;
/**
* @author retucio
*/
public class CrystalAura extends Module {
private final SettingGroup sgPlace = addSg(new SettingGroup("colocar", false));
private final SettingGroup sgBreak = addSg(new SettingGroup("reventar", false));
private final SettingGroup sgRender = addSg(new SettingGroup("renderizado", false));
private final ListSetting<EntityType<?>> entities = sgGeneral.add(new ListSetting<>(
"entidades", "entidades a las que atacar",
Lists.entityList, Lists.allFalseExcept(Lists.entityList, EntityType.PLAYER), Lists.entityNames
));
private final NumberSetting targetRange = sgGeneral.add(new NumberSetting(
"rango",
"rango de detección de blancos",
5, 0, 12, 0.1
));
// ajustes al colocar los cristales
private final BooleanSetting placeCrystals = sgPlace.add(new BooleanSetting(
"colocar", "colocar los cristales", true
));
private final NumberSetting placeDelay = sgPlace.add(new NumberSetting(
"delay", "delay entre cristal y cristal",
0, 0, 20, 1
)).visibility(placeCrystals::getValue);
private final NumberSetting placeRange = sgPlace.add(new NumberSetting(
"rango ", "rango máximo para colocar cristales",
4.5, 0, 6, 0.1
)).visibility(placeCrystals::getValue);
private final BooleanSetting rotateToPlace = sgPlace.add(new BooleanSetting(
"rotar", "rotar para colocar cristales", false
)).visibility(placeCrystals::getValue);
private final BooleanSetting autoSelect = sgPlace.add(new BooleanSetting(
"autoseleccionar", "seleccionar cristales automáticamente", true
));
// ajustes al reventar los cristales
private final BooleanSetting breakCrystals = sgBreak.add(new BooleanSetting(
"reventar", "reventar los cristales", true
));
private final NumberSetting breakDelay = sgBreak.add(new NumberSetting(
"delay ", "delay entre cristal y cristal",
0, 0, 20, 1
)).visibility(breakCrystals::getValue);
private final BooleanSetting rotateToBreak = sgBreak.add(new BooleanSetting(
"rotar", "rotar para reventar cristales", false
)).visibility(breakCrystals::getValue);
// ajustes de renderizado
private final BooleanSetting outlines = sgRender.add(new BooleanSetting(
"contorno", "renderizar contorno del bloque donde se colocan los cristales", true
));
private final ColorSetting outlineColor = sgRender.add(new ColorSetting(
"color del contorno", "color del contorno",
Colors.mainColor, false
)).visibility(outlines::getValue);
private final NumberSetting outlineWidth = sgRender.add(new NumberSetting(
"grosor del contorno", "grosor del contorno",
2, 0, 15, 0.1
)).visibility(outlines::getValue);
private final BooleanSetting fillings = sgRender.add(new BooleanSetting(
"relleno", "renderizar relleno del bloque donde se colocan los cristales", false
));
private final ColorSetting fillingColor = sgRender.add(new ColorSetting(
"color del relleno", "color del relleno",
Colors.withAlpha(Colors.mainColor, 70), false
)).visibility(fillings::getValue);
private final List<LivingEntity> targets = new ArrayList<>();
private BlockPos bp = null;
private int placeTimer = placeDelay.getIntValue();
private int breakTimer = breakDelay.getIntValue();
public CrystalAura() {
super("aura de cristales",
"coloca y revienta cristales del end por ti", Category.COMBAT);
}
@Override
public void onTick() {
if (mc.player == null || mc.interactionManager == null || mc.world == null || mc.getCameraEntity() == null) return;
if (placeTimer > 0) placeTimer--;
if (breakTimer > 0) breakTimer--;
findTargets();
if (!targets.isEmpty()) {
if (placeCrystals.getValue()) doPlace();
if (breakCrystals.getValue()) doBreak();
} else {
bp = null;
}
}
// colocar cristal
private void doPlace() {
if (placeTimer > 0) return;
if (!canPlaceCrystal()) {
bp = null;
return;
}
// elegir como blanco primario la entidad más cercana
LivingEntity primaryTarget = null;
double closestTargetDist = Double.MAX_VALUE;
for (LivingEntity target : targets) {
double dist = mc.player.squaredDistanceTo(target);
if (dist < closestTargetDist) {
closestTargetDist = dist;
primaryTarget = target;
}
}
if (primaryTarget == null) {
bp = null;
return;
}
final Vec3d targetPos = primaryTarget.getEntityPos();
final BlockPos.Mutable[] bestPos = new BlockPos.Mutable[1];
final double[] bestDist = { Double.MAX_VALUE };
BlockIterator.register((int) Math.ceil(placeRange.getValue()), (int) Math.ceil(placeRange.getValue()), (pos, state) -> {
if (!state.isOf(Blocks.OBSIDIAN) && !state.isOf(Blocks.BEDROCK)) return;
if (!mc.world.isAir(pos.add(0, 1, 0))) return;
// cálculo de mejor distancia
double dist = targetPos.squaredDistanceTo(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
if (dist < bestDist[0]) {
bestDist[0] = dist;
if (bestPos[0] == null) bestPos[0] = new BlockPos.Mutable();
bestPos[0].set(pos);
}
});
BlockIterator.after(() -> {
if (bestPos[0] != null) {
BlockHitResult result = getBlockInfo(bestPos[0]);
placeCrystal(result);
bp = bestPos[0].toImmutable(); // guardar para el renderizado
} else {
bp = null;
}
});
placeTimer = placeDelay.getIntValue();
}
private void doBreak() {
if (breakTimer > 0) return;
for (Entity entity : mc.world.getEntities()) {
if (!(entity instanceof EndCrystalEntity) || entity.distanceTo(mc.player) > mc.player.getEntityInteractionRange()) continue;
if (rotateToBreak.getValue()) EntityUtil.lookAt(entity.getEyePos());
mc.interactionManager.attackEntity(mc.player, entity);
}
breakTimer = breakDelay.getIntValue();
}
private void placeCrystal(BlockHitResult result) {
if (autoSelect.getValue()) {
int slot = InventoryUtil.findSlot(stack -> stack.isOf(Items.END_CRYSTAL));
if (slot != InventoryUtil.OFFHAND_SLOT) {
if (!PlayerInventory.isValidHotbarIndex(slot)) {
InventoryUtil.swapWithHotbar(slot, mc.player.getInventory().getSelectedSlot());
} else {
mc.player.getInventory().setSelectedSlot(slot);
}
}
}
Hand hand;
if (mc.player.getMainHandStack().isOf(Items.END_CRYSTAL)) {
hand = Hand.MAIN_HAND;
} else if (mc.player.getOffHandStack().isOf(Items.END_CRYSTAL)) {
hand = Hand.OFF_HAND;
} else {
return;
}
if (rotateToPlace.getValue()) EntityUtil.lookAt(result.getBlockPos().toCenterPos());
mc.interactionManager.sendSequencedPacket(mc.world, (sequence) -> new PlayerInteractBlockC2SPacket(hand, result, sequence));
}
// encontrar blancos
private void findTargets() {
targets.clear();
for (Entity e : mc.world.getEntities()) {
if (!(e instanceof LivingEntity entity)) continue;
if (!entity.isAlive() || entity.isInCreativeMode() || entity.equals(mc.player)) continue;
if (!entities.isEnabled(entity.getType())) continue;
if (entity.squaredDistanceTo(mc.player) > targetRange.getValue() * targetRange.getValue()) continue;
targets.add(entity);
}
}
private BlockHitResult getBlockInfo(BlockPos pos) {
Vec3d start = new Vec3d(mc.player.getX(), mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose()), mc.player.getZ());
Vec3d end;
for (Direction side : Direction.values()) {
end = new Vec3d(
pos.getX() + 0.5 + side.getVector().getX() * 0.5,
pos.getY() + 0.5 + side.getVector().getY() * 0.5,
pos.getZ() + 0.5 + side.getVector().getZ() * 0.5
);
BlockHitResult result = mc.world.raycast(new RaycastContext(
start, end, RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player
));
if (result != null && result.getType() == HitResult.Type.BLOCK && result.getBlockPos().equals(pos)) {
return result;
}
}
Direction side = pos.getY() > start.y ? Direction.DOWN : Direction.UP;
return new BlockHitResult(start, side, pos, false);
}
private boolean canPlaceCrystal() {
if (autoSelect.getValue()) {
return InventoryUtil.findSlot(stack -> stack.isOf(Items.END_CRYSTAL)) != -1;
} else {
return InventoryUtil.hasInHotbar(Items.END_CRYSTAL);
}
}
@EventListener
private void onRenderWorld(Render3DEvent event) {
if (bp != null) {
if (outlines.getValue()) {
RenderUtil.drawBlockOutline(event.getMatrices(), bp, outlineColor.getValue(), outlineWidth.getFloatValue(), false);
}
if (fillings.getValue()) {
RenderUtil.drawBlockFilled(event.getMatrices(), bp, fillingColor.getValue(), false);
}
}
}
}
@@ -52,7 +52,7 @@ public class AutoFish extends Module {
0,
64,
1
));
)).visibility(onlyRecastIfLookingAtWater::getValue);
private final BooleanSetting dontBreak = sgGeneral.add(new BooleanSetting(
"evitar romper",
@@ -71,8 +71,6 @@ public class AutoFish extends Module {
onlyRecastIfLookingAtWater.visibility(v);
recastRaycastDistance.visibility(v);
});
onlyRecastIfLookingAtWater.onUpdate(v -> recastRaycastDistance.visibility(v));
}
@Override
@@ -0,0 +1,102 @@
/*
* This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client).
* Copyright (c) Meteor Development.
*/
package me.retucio.sputnik.util;
import com.github.retucio.neutrino.EventListener;
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
import me.retucio.sputnik.Sputnik;
import me.retucio.sputnik.event.TickEvent;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.math.BlockPos;
import java.util.List;
import java.util.function.BiConsumer;
// https://github.com/MeteorDevelopment/meteor-client/blob/master/src/main/java/meteordevelopment/meteorclient/utils/world/BlockIterator.java
public class BlockIterator {
private static final Pool<Callback> callbackPool = new Pool<>(Callback::new);
private static final List<Callback> callbacks = new ReferenceArrayList<>();
private static final List<Runnable> afterCallbacks = new ReferenceArrayList<>();
private static final BlockPos.Mutable blockPos = new BlockPos.Mutable();
private static int hRadius, vRadius;
private static boolean disableCurrent;
private BlockIterator() {}
@EventListener()
private static void onTick(TickEvent.Pre event) {
MinecraftClient mc = MinecraftClient.getInstance();
if (mc.player == null) return;
int px = mc.player.getBlockX();
int py = mc.player.getBlockY();
int pz = mc.player.getBlockZ();
for (int x = px - hRadius; x <= px + hRadius; x++) {
for (int z = pz - hRadius; z <= pz + hRadius; z++) {
for (int y = Math.max(mc.world.getBottomY(), py - vRadius); y <= py + vRadius; y++) {
if (y > mc.world.getHeight()) break;
blockPos.set(x, y, z);
BlockState blockState = mc.world.getBlockState(blockPos);
int dx = Math.abs(x - px);
int dy = Math.abs(y - py);
int dz = Math.abs(z - pz);
callbacks.removeIf(callback -> {
if (dx <= callback.hRadius && dy <= callback.vRadius && dz <= callback.hRadius) {
disableCurrent = false;
callback.function.accept(blockPos, blockState);
return disableCurrent;
}
return false;
});
}
}
}
hRadius = 0;
vRadius = 0;
callbackPool.freeAll(callbacks);
callbacks.clear();
for (Runnable callback : afterCallbacks) callback.run();
afterCallbacks.clear();
}
public static void register(int horizontalRadius, int verticalRadius, BiConsumer<BlockPos, BlockState> function) {
hRadius = Math.max(hRadius, horizontalRadius);
vRadius = Math.max(vRadius, verticalRadius);
Callback callback = callbackPool.get();
callback.function = function;
callback.hRadius = horizontalRadius;
callback.vRadius = verticalRadius;
callbacks.add(callback);
}
public static void disableCurrent() {
disableCurrent = true;
}
public static void after(Runnable callback) {
afterCallbacks.add(callback);
}
private static class Callback {
public BiConsumer<BlockPos, BlockState> function;
public int hRadius, vRadius;
}
}
@@ -1,5 +1,7 @@
package me.retucio.sputnik.util;
import com.github.retucio.neutrino.EventListener;
import com.google.common.eventbus.Subscribe;
import me.retucio.sputnik.event.network.DisconnectEvent;
import me.retucio.sputnik.event.interact.OpenScreenEvent;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
@@ -332,6 +334,18 @@ public class InventoryUtil {
return -1;
}
public static boolean hasInHotbar(Item item) {
List<ItemStack> stacks = findAll(stack -> stack.isOf(item));
for (ItemStack stack : stacks) {
int slot = mc.player.getInventory().getSlotWithStack(stack);
if (slot < HOTBAR_END || slot == OFFHAND_SLOT) {
return true;
}
}
return false;
}
@EventListener
public static void onOpenScreen(OpenScreenEvent event) {
if (mc.player == null
|| event.getScreen() == null
@@ -343,6 +357,7 @@ public class InventoryUtil {
echestInv = handler.getInventory();
}
@EventListener
public void onDisconnect(DisconnectEvent event) {
echestInv = null;
}
@@ -87,12 +87,26 @@ public class Lists {
return map;
}
@SafeVarargs
public static <T> Map<T, Boolean> allTrueExcept(List<T> options, T... exceptions) {
Map<T, Boolean> map = allFalse(options);
for (T exception : exceptions) map.replace(exception, false);
return map;
}
public static <T> Map<T, Boolean> allFalse(List<T> options) {
Map<T, Boolean> map = new HashMap<>();
for (T option : options) map.put(option, false);
return map;
}
@SafeVarargs
public static <T> Map<T, Boolean> allFalseExcept(List<T> options, T... exceptions) {
Map<T, Boolean> map = allFalse(options);
for (T exception : exceptions) map.replace(exception, true);
return map;
}
public static <T> Map<T, String> getMapOfLists(List<T> options, List<String> names) {
Map<T, String> result = new HashMap<>();
@@ -0,0 +1,34 @@
package me.retucio.sputnik.util;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Queue;
import java.util.function.Supplier;
// https://github.com/MeteorDevelopment/meteor-client/blob/master/src/main/java/meteordevelopment/meteorclient/utils/misc/Pool.java
public final class Pool<T> {
private final Queue<T> items = new ArrayDeque<>();
private final Supplier<T> producer;
public Pool(Supplier<T> producer) {
this.producer = producer;
}
public synchronized T get() {
if (!items.isEmpty()) return items.poll();
return producer.get();
}
public synchronized void free(T obj) {
items.offer(obj);
}
public synchronized void freeAll(Iterable<T> objects) {
if (objects instanceof Collection<T> collection) {
items.addAll(collection);
} else {
objects.forEach(items::add);
}
}
}
@@ -94,6 +94,7 @@ public class RenderUtil {
}
public static void drawBlockFaceOutlines(MatrixStack matrices, BlockPos pos, Direction face, Color color, float lineWidth, boolean cull) {
if (lineWidth <= 0) return;
Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
float minX = (float) (pos.getX() - cameraPos.x);
@@ -295,6 +296,7 @@ public class RenderUtil {
// cajas
public static void drawOutlineBox(MatrixStack matrices, Box box, Color color, float lineWidth, boolean cull) {
if (lineWidth <= 0) return;
Vec3d cameraPos = mc.gameRenderer.getCamera().getCameraPos();
float minX = (float) (box.minX - cameraPos.x);