Начинающий
- Статус
- Оффлайн
- Регистрация
- 8 Авг 2025
- Сообщения
- 41
- Реакции
- 0
- Выберите загрузчик игры
- Fabric
Салем YouGame!
Доделал тему https://yougame.biz/threads/371203/ (noad)
=============================================
Что было сделано(ChangeLog):
Перенёс на 1.21.4 exosware.
сделал 85монет/c
Добавил fast режим(улучшил)
Лучше работает с FastBreak(код тоже указал)
=============================================
Так ну а вот и сам код:
За чат джбт код не судите, если чёт надо будет докинуть - пишите.
Доделал тему https://yougame.biz/threads/371203/ (noad)
=============================================
Что было сделано(ChangeLog):
Перенёс на 1.21.4 exosware.
сделал 85монет/c
Добавил fast режим(улучшил)
Лучше работает с FastBreak(код тоже указал)
=============================================
Так ну а вот и сам код:
(AUTOLES)О великий Rastyshka спасибо тебе!!!:
package Spooky.fun.modules.player;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import Spooky.fun.events.Event;
import Spooky.fun.events.impl.EventUpdate;
import Spooky.fun.modules.Function;
import Spooky.fun.modules.FunctionAnnotation;
import Spooky.fun.modules.Type;
import Spooky.fun.modules.setting.BooleanSetting;
import Spooky.fun.modules.setting.ModeSetting;
import Spooky.fun.modules.setting.SliderSetting;
import Spooky.fun.modules.setting.TextSetting;
import Spooky.fun.util.player.TimerUtil;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* AutoLes
* Автоматически ломает брёвна вокруг игрока + авто /sellwood и /pay.
*/
@FunctionAnnotation(
name = "AutoLes",
type = Type.Player,
desc = "Автоматически ломает брёвна и сдаёт дерево"
)
public class AutoLes extends Function {
private BlockPos targetPos;
private final ModeSetting breakMode = new ModeSetting("Режим", "Default", "Default", "Fast");
// Здесь воспринимаем значение как ОПЕРАЦИИ В ТИК (а не пакеты/сек), поэтому можно ставить 50–150 для очень быстрого фарма
private final SliderSetting packetsPerSecond = new SliderSetting("Скорость (оп/тик)", 60.0f, 1.0f, 200.0f, 1.0f,
() -> breakMode.is("Fast"));
private final SliderSetting breakRadius = new SliderSetting("Радиус", 4.0f, 1.0f, 6.0f, 0.5f);
private final BooleanSetting inf = new BooleanSetting("Чудеса", false, "Для баг. дерева (ломает один и тот же блок)");
private final BooleanSetting swing = new BooleanSetting("Махать рукой", true);
private final BooleanSetting autoWood = new BooleanSetting("Авто-сдача", true);
private final BooleanSetting autoPay = new BooleanSetting("AutoPay", false);
private final TextSetting namePay = new TextSetting("Ник для перевода", "name", () -> autoPay.get());
private final SliderSetting valuePay = new SliderSetting("Кол-во монет для перевода", 1000, 500, 25000, 1000,
() -> autoPay.get());
private final SliderSetting timer = new SliderSetting("Расписание/c", 20, 1, 60, 1,
() -> autoPay.get() || autoWood.get());
private final TimerUtil sellTimer = new TimerUtil();
private final TimerUtil payTimer = new TimerUtil();
private final TimerUtil breakTimer = new TimerUtil();
public AutoLes() {
addSettings(breakMode, breakRadius, packetsPerSecond, inf, swing, autoWood, autoPay, namePay, valuePay, timer);
}
@Override
public void onEvent(Event event) {
if (!(event instanceof EventUpdate)) return;
updateNuker();
autoSell();
autoPay();
}
private void autoSell() {
if (!autoWood.get() || mc.player == null) return;
long intervalMs = (long) (timer.get().doubleValue() * 500L);
if (sellTimer.hasTimeElapsed(intervalMs)) {
mc.player.networkHandler.sendChatCommand("sellwood");
sellTimer.reset();
}
}
private void autoPay() {
if (!autoPay.get() || mc.player == null) return;
long intervalMs = (long) (timer.get().doubleValue() * 500L) + 200L;
if (payTimer.hasTimeElapsed(intervalMs)) {
String nick = namePay.getValue();
int amount = valuePay.get().intValue();
mc.player.networkHandler.sendChatCommand("pay " + nick + " " + amount);
payTimer.reset();
}
}
private void updateNuker() {
if (mc.player == null || mc.world == null || mc.interactionManager == null) {
targetPos = null;
return;
}
if (breakMode.is("Fast")) {
runFastMode();
} else {
runDefaultMode();
}
}
private void runDefaultMode() {
// инвалидируем текущую цель
if (targetPos != null &&
(!isLog(targetPos) || !isInRange(targetPos) || !isVisible(targetPos))) {
targetPos = null;
}
if (targetPos != null) {
breakBlockDefault();
} else {
findAndBreakNewTargetDefault();
}
}
private void findAndBreakNewTargetDefault() {
BlockPos playerPos = mc.player.getBlockPos();
int radius = (int) breakRadius.get().doubleValue();
BlockPos from = playerPos.add(-radius, -radius, -radius);
BlockPos to = playerPos.add(radius, radius, radius);
List<BlockPos> blocks = getAllInBox(from, to);
targetPos = blocks.stream()
.filter(this::isLog)
.filter(this::isInRange)
.filter(this::isVisible)
.min(Comparator.comparing(pos ->
mc.player.squaredDistanceTo(Vec3d.ofCenter(pos))
))
.orElse(null);
if (targetPos != null) {
breakBlockDefault();
}
}
private void breakBlockDefault() {
if (targetPos == null) return;
if (breakMode.is("Default")) {
if (breakTimer.hasTimeElapsed(3L)) {
mc.interactionManager.attackBlock(targetPos, Direction.UP);
mc.interactionManager.updateBlockBreakingProgress(targetPos, Direction.UP);
if (swing.get()) {
mc.player.swingHand(Hand.MAIN_HAND);
}
breakTimer.reset();
}
}
}
private boolean isInRange(BlockPos pos) {
if (mc.player == null) return false;
double distanceSq = mc.player.squaredDistanceTo(
pos.getX() + 0.5,
pos.getY() + 0.5,
pos.getZ() + 0.5
);
double r = breakRadius.get().doubleValue();
double maxSq = r * r;
return distanceSq <= maxSq;
}
private boolean isVisible(BlockPos pos) {
if (mc.world == null || mc.player == null) return false;
// В исходнике всегда true, здесь оставляем так же
return true;
}
private boolean isLog(BlockPos pos) {
if (mc.world == null) return false;
BlockState state = mc.world.getBlockState(pos);
if (state.isIn(BlockTags.LOGS)) return true;
String key = state.getBlock().getTranslationKey().toLowerCase();
return key.contains("log") || key.contains("wood") || key.contains("stem");
}
private List<BlockPos> getAllInBox(BlockPos from, BlockPos to) {
List<BlockPos> result = new ArrayList<>();
int minX = Math.min(from.getX(), to.getX());
int minY = Math.min(from.getY(), to.getY());
int minZ = Math.min(from.getZ(), to.getZ());
int maxX = Math.max(from.getX(), to.getX());
int maxY = Math.max(from.getY(), to.getY());
int maxZ = Math.max(from.getZ(), to.getZ());
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
result.add(new BlockPos(x, y, z));
}
}
}
return result;
}
// ------------ Fast режим (пакетный нукер) ------------
private void runFastMode() {
if (mc.player == null || mc.world == null || mc.player.networkHandler == null) return;
// В Fast режиме воспринимаем слайдер как количество операций за ТИК.
// Например, 60 = до 60 блоков за тик (до ~120 пакетов START/STOP).
int ops = Math.max(1, (int) packetsPerSecond.get().doubleValue());
boolean acted = false;
// инвалидируем текущую цель для inf-режима
if (targetPos != null && (!isLog(targetPos) || !isInRange(targetPos) || !isVisible(targetPos))) {
targetPos = null;
}
for (int i = 0; i < ops; i++) {
if (inf.get()) {
if (targetPos == null || !isInRange(targetPos) || !isLog(targetPos)) {
targetPos = findClosestLog();
}
if (targetPos != null) {
sendBreakPacket(targetPos);
acted = true;
}
} else {
BlockPos t = findClosestLog();
if (t != null) {
sendBreakPacket(t);
// визуально сразу очищаем блок
mc.world.setBlockState(t, Blocks.AIR.getDefaultState());
acted = true;
} else {
break;
}
}
}
if (acted && swing.get()) {
mc.player.swingHand(Hand.MAIN_HAND);
}
}
private BlockPos findClosestLog() {
BlockPos playerPos = mc.player.getBlockPos();
int radius = (int) breakRadius.get().doubleValue();
BlockPos from = playerPos.add(-radius, -radius, -radius);
BlockPos to = playerPos.add(radius, radius, radius);
List<BlockPos> blocks = getAllInBox(from, to);
return blocks.stream()
.filter(this::isLog)
.filter(this::isInRange)
.filter(this::isVisible)
.min(Comparator.comparing(pos ->
mc.player.squaredDistanceTo(Vec3d.ofCenter(pos))
))
.orElse(null);
}
private void sendBreakPacket(BlockPos pos) {
mc.player.networkHandler.sendPacket(
new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, Direction.UP)
);
mc.player.networkHandler.sendPacket(
new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.STOP_DESTROY_BLOCK, pos, Direction.UP)
);
}
@Override
protected void onDisable() {
targetPos = null;
super.onDisable();
}
}
(FastBreak)О великий Rastyshka спасибо тебе!!!:
package Spooky.fun.modules.player;
import net.minecraft.block.BlockState;
import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import Spooky.fun.events.Event;
import Spooky.fun.events.impl.EventUpdate;
import Spooky.fun.modules.Function;
import Spooky.fun.modules.FunctionAnnotation;
import Spooky.fun.modules.Type;
import Spooky.fun.modules.setting.SliderSetting;
/**
* FastBreak(CREDITS: @multipays)
* Ускоряет ломание блоков за счёт многократного вызова updateBlockBreakingProgress за тик.
*/
@FunctionAnnotation(name = "FastBreak", type = Type.Player, desc = "Ускоряет ломание блоков")
public class FastBreak extends Function {
// 0.3f–1.0f, по дефолту 0.7f — как в оригинале
public final SliderSetting speed = new SliderSetting("Ускорение", 0.7f, 0.3f, 1.0f, 0.1f);
public FastBreak() {
addSettings(speed);
}
@Override
public void onEvent(Event event) {
if (!(event instanceof EventUpdate)) return;
if (mc.player == null || mc.world == null || mc.interactionManager == null) return;
if (!(mc.crosshairTarget instanceof BlockHitResult)) return;
BlockHitResult hit = (BlockHitResult) mc.crosshairTarget;
BlockPos pos = hit.getBlockPos();
if (pos == null) return;
BlockState state = mc.world.getBlockState(pos);
if (state == null || state.isAir()) return;
// Ломаем только когда реально жмём ЛКМ
if (!mc.options.attackKey.isPressed()) return;
ClientPlayerInteractionManager im = mc.interactionManager;
Direction side = hit.getSide();
// Кол-во "дополнительных тиков" ломания за один реальный тик
// 0.3 → 1, 0.7 → ~2, 1.0 → ~3
float mul = speed.get().floatValue();
int extraTicks = Math.max(1, Math.round(mul / 0.35f));
for (int i = 0; i < extraTicks; i++) {
im.updateBlockBreakingProgress(pos, side);
}
// Лёгкая анимация удара (чтоб визуально было понятно, что мод работает)
mc.player.swingHand(Hand.MAIN_HAND);
}
}
За чат джбт код не судите, если чёт надо будет докинуть - пишите.