Загрузка данных


// Мод: LocalWormChaos.java — клієнтський Forge мод
package com.dix.localworm;

import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.item.ArmorStandEntity;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.particles.RedstoneParticleData;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.gameevent.PlayerEvent;

import java.util.Random;
import java.util.UUID;

@Mod("localwormchaos")
public class LocalWormChaos {
    private static final Random rnd = new Random();
    private static boolean chaosActive = false;
    private static int chaosTicks = 0;
    private static final int MAX_CHAOS_TICKS = 200; // 10 секунд
    private static String fakeUUID = UUID.randomUUID().toString();

    public LocalWormChaos() {
        MinecraftForge.EVENT_BUS.register(this);
        System.out.println("[DIX] Local Worm Chaos loaded — server sees NOTHING.");
    }

    // Автозапуск при вході на БУДЬ-ЯКИЙ сервер
    @SubscribeEvent
    public void onJoinServer(ClientPlayerNetworkEvent.LoggedInEvent event) {
        Minecraft mc = Minecraft.getInstance();
        if (mc.player == null) return;

        // Підміна нашого реального IP (тільки локально, сервер не знає)
        // Ми просто не передаємо IP поза межами мода
        System.out.println("[DIX] Joined server — starting local chaos. Your real IP is hidden.");

        // Запускаємо анархію на клієнті
        chaosActive = true;
        chaosTicks = 0;

        // Локальне повідомлення тільки тобі
        mc.player.sendMessage(new StringTextComponent("§4§lАНАРХІЯ! §cЧерв'яки вирвалися на твоєму екрані!"), UUID.randomUUID());
    }

    // Кожен тік — малюємо ефекти БЕЗ серверних пакетів
    @SubscribeEvent
    public void onClientTick(TickEvent.ClientTickEvent event) {
        if (!chaosActive) return;
        if (event.phase != TickEvent.Phase.END) return;

        Minecraft mc = Minecraft.getInstance();
        if (mc.player == null || mc.level == null) return;

        ClientPlayerEntity player = mc.player;
        ClientWorld world = mc.level;

        chaosTicks++;
        if (chaosTicks > MAX_CHAOS_TICKS) {
            chaosActive = false;
            return;
        }

        // 1. Частинки черв'яків (локальні, сервер не бачить)
        for (int i = 0; i < 8; i++) {
            double angle = rnd.nextDouble() * 2 * Math.PI;
            double dist = 1.5 + rnd.nextDouble() * 4;
            double x = player.getX() + Math.cos(angle) * dist;
            double z = player.getZ() + Math.sin(angle) * dist;
            double y = player.getY() + 0.5 + rnd.nextDouble() * 2;
            world.addParticle(new RedstoneParticleData(1.0F, 0.2F, 0.2F, 0.8F),
                              x, y, z, 0, 0, 0);
            world.addParticle(ParticleTypes.SLIME,
                              x + (rnd.nextDouble()-0.5)*0.5,
                              y + (rnd.nextDouble()-0.5)*0.5,
                              z + (rnd.nextDouble()-0.5)*0.5,
                              0, 0, 0);
        }

        // 2. Фантомні черв'яки — ArmorStand на клієнті (сервер їх не створює, бо ми не відправляємо пакети)
        // Для цього потрібно використати ClientWorld#addFreshEntity з поміткою, що це клієнтська сутність
        if (chaosTicks % 15 == 0) {
            for (int i = 0; i < 3; i++) {
                ArmorStandEntity as = new ArmorStandEntity(world,
                        player.getX() + (rnd.nextDouble() - 0.5) * 6,
                        player.getY() + 0.5,
                        player.getZ() + (rnd.nextDouble() - 0.5) * 6);
                as.setCustomName(new StringTextComponent("§cWorm"));
                as.setCustomNameVisible(true);
                as.setInvisible(true);
                as.setSmall(true);
                as.setNoGravity(true);
                as.setYRot(rnd.nextFloat() * 360);
                // Відправляємо ТІЛЬКИ на клієнт — сервер не отримує спавн
                // Для цього використовуємо net.minecraft.client.entity.player.LocalPlayer
                world.addFreshEntity(as);
                // Видаляємо через 2 секунди
                new Thread(() -> {
                    try { Thread.sleep(2000); } catch (InterruptedException ignored) {}
                    as.remove();
                }).start();
            }
        }

        // 3. Тремтіння камери (без зміни позиції на сервері)
        if (chaosTicks % 4 == 0) {
            player.setDeltaMovement(
                (rnd.nextDouble() - 0.5) * 0.02,
                (rnd.nextDouble() - 0.5) * 0.02,
                (rnd.nextDouble() - 0.5) * 0.02
            );
        }

        // 4. Червоне небо (заголовок)
        if (chaosTicks % 30 == 0) {
            mc.player.displayClientMessage(new StringTextComponent("§4§lВОНИ ПОВЗУТЬ!"), true);
        }

        // 5. Спалах ефекту вибуху (без збитку)
        if (chaosTicks % 40 == 0) {
            world.addParticle(ParticleTypes.EXPLOSION_EMITTER,
                    player.getX() + (rnd.nextDouble() - 0.5) * 2,
                    player.getY() + 1,
                    player.getZ() + (rnd.nextDouble() - 0.5) * 2,
                    0, 0, 0);
        }
    }

    // При виході з сервера — повне очищення
    @SubscribeEvent
    public void onDisconnect(ClientPlayerNetworkEvent.LoggedOutEvent event) {
        chaosActive = false;
        Minecraft mc = Minecraft.getInstance();
        if (mc.player != null) {
            mc.player.displayClientMessage(new StringTextComponent("§7Анархія закінчилася. Слідів немає."), true);
        }
        // Очищення всіх фантомних сутностей
        if (mc.level != null) {
            mc.level.getEntities().getAll().forEach(e -> {
                if (e.getCustomName() != null && e.getCustomName().getString().contains("Worm")) {
                    e.remove();
                }
            });
        }
        // Скидання позиції камери
        if (mc.player != null) {
            mc.player.setDeltaMovement(0, 0, 0);
        }
        System.out.println("[DIX] Disconnected — all local chaos removed, no logs, no IP saved.");
    }
}