// Path: src/main/java/me/pascoej/ajario/node/FoodNode.java
// public class FoodNode extends Node {
//     public FoodNode(int nodeId) {
//         super(nodeId, NodeType.FOOD);
//     }
// }
// 
// Path: src/main/java/me/pascoej/ajario/node/Node.java
// public class Node {
//     private final int nodeId;
//     private final NodeType nodeType;
//     private long lastUpdate;
//     private short x, y, size;
//     double vX, vY;
// 
//     Node(int nodeId, NodeType nodeType) {
//         this.nodeId = nodeId;
//         this.nodeType = nodeType;
//     }
// 
//     List<Double> errors = new ArrayList<>();
// 
//     public void updatePositionSize(short x, short y, short size) {
//         long currentTime = System.currentTimeMillis();
//         this.x = x;
//         this.y = y;
//         this.size = size;
//         lastUpdate = currentTime;
//     }
// 
//     public NodeType getNodeType() {
//         return nodeType;
//     }
// 
//     public int getNodeId() {
//         return nodeId;
//     }
// 
//     public double getLastUpdate() {
//         return lastUpdate;
//     }
// 
//     public short getX() {
//         return x;
//     }
// 
//     public short getY() {
//         return y;
//     }
// 
//     public short getSize() {
//         return size;
//     }
// 
//     public double distanceSquared(Node node1) {
//         double xDiff = node1.getX() - this.getX();
//         double yDiff = node1.getY() - this.getY();
//         return (xDiff * xDiff) + (yDiff * yDiff);
//     }
// }
// 
// Path: src/main/java/me/pascoej/ajario/node/PlayerNode.java
// public class PlayerNode extends Node {
//     private String name;
//     private boolean mine;
// 
//     public PlayerNode(int nodeId) {
//         super(nodeId, NodeType.PLAYER);
//     }
// 
//     public String getName() {
//         if (name == null) {
//             return "";
//         }
//         return name;
//     }
// 
//     public boolean isMine() {
//         return mine;
//     }
// 
//     public void setMine() {
//         this.mine = true;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// }
// 
// Path: src/main/java/me/pascoej/ajario/node/VirusNode.java
// public class VirusNode extends Node {
//     public VirusNode(int nodeId) {
//         super(nodeId, NodeType.VIRUS);
//     }
// }
// 
// Path: src/main/java/me/pascoej/ajario/protocol/PacketListener.java
// public interface PacketListener {
//     void onRecvPacket(ClientBoundPacket agarPacket);
// }
// 
// Path: src/main/java/me/pascoej/ajario/protocol/Session.java
// public class Session {
//     private WebSocketHandler webSocketHandler;
//     private URI uri;
//     public Session(URI uri) {
//         this.uri = uri;
//         webSocketHandler = new WebSocketHandler(uri,this);
//     }
// 
//     public void connect() {
//         Set<PacketListener> packetListenerList = webSocketHandler.getPacketListeners();
//         webSocketHandler = new WebSocketHandler(uri,this);
//         webSocketHandler.getPacketListeners().addAll(packetListenerList);
//         webSocketHandler.connect();
//     }
// 
//     public void sendPacket(AgarPacket agarPacket) {
//         if (!webSocketHandler.isOpen())
//             return;
//         try {
//             webSocketHandler.sendPacket(agarPacket);
//         } catch (Exception e) {
//             e.printStackTrace();
//         }
//     }
// 
//     public void close() {
//         webSocketHandler.close();
//         webSocketHandler.clearPacketListeners();
//     }
// 
//     public void registerPacketListener(PacketListener packetListener) {
//         webSocketHandler.registerPacketListener(packetListener);
//     }
// 
//     public void unregisterPacketListener(PacketListener packetListener) {
//         webSocketHandler.unregisterPacketListener(packetListener);
//     }
// 
//     public boolean isReady() {
//         return webSocketHandler.isOpen();
//     }
// }


import me.pascoej.ajario.node.FoodNode;
import me.pascoej.ajario.node.Node;
import me.pascoej.ajario.node.PlayerNode;
import me.pascoej.ajario.node.VirusNode;
import me.pascoej.ajario.packet.clientbound.*;
import me.pascoej.ajario.packet.serverbound.*;
import me.pascoej.ajario.protocol.PacketListener;
import me.pascoej.ajario.protocol.Session;
import java.net.URI;
    public void serverResetPacket() {
        session.sendPacket(new ConnectionResetPacket());
    }

    public boolean isDead() {
        return world.getClientNodes().isEmpty();
    }
    private static final int RECALCULATE_INTERVAL = 50;
    private int updatePackets = 0;
    private long lastUpdateNodeTime = System.currentTimeMillis();
    private double updatePerSecond = 0;

    public int getUpdatePerSecond() {
        return (int) updatePerSecond;
    }

    private void handleUpdateNodes(UpdateNodes updateNodes) {
        updatePackets += 1;
        if (updatePackets >= RECALCULATE_INTERVAL) {
            long currentTime = System.currentTimeMillis();
            long elapsed = currentTime - lastUpdateNodeTime;
            updatePerSecond = (double) updatePackets/((double)elapsed/1000.0);
        }
        for (UpdateNodes.NodeData nodeData : updateNodes.getNodeDataList()) {
            int id = nodeData.getNodeId();
            Node node = world.getNode(id);
            if (node == null) {
                if (nodeData.isVirus()) {
                    node = new VirusNode(id);
                } else if (nodeData.getSize() < 20 && nodeData.getName().equals("")) {
// Path: src/main/java/me/pascoej/ajario/node/FoodNode.java
// public class FoodNode extends Node {
//     public FoodNode(int nodeId) {
//         super(nodeId, NodeType.FOOD);
//     }
// }
// 
// Path: src/main/java/me/pascoej/ajario/node/Node.java
// public class Node {
//     private final int nodeId;
//     private final NodeType nodeType;
//     private long lastUpdate;
//     private short x, y, size;
//     double vX, vY;
// 
//     Node(int nodeId, NodeType nodeType) {
//         this.nodeId = nodeId;
//         this.nodeType = nodeType;
//     }
// 
//     List<Double> errors = new ArrayList<>();
// 
//     public void updatePositionSize(short x, short y, short size) {
//         long currentTime = System.currentTimeMillis();
//         this.x = x;
//         this.y = y;
//         this.size = size;
//         lastUpdate = currentTime;
//     }
// 
//     public NodeType getNodeType() {
//         return nodeType;
//     }
// 
//     public int getNodeId() {
//         return nodeId;
//     }
// 
//     public double getLastUpdate() {
//         return lastUpdate;
//     }
// 
//     public short getX() {
//         return x;
//     }
// 
//     public short getY() {
//         return y;
//     }
// 
//     public short getSize() {
//         return size;
//     }
// 
//     public double distanceSquared(Node node1) {
//         double xDiff = node1.getX() - this.getX();
//         double yDiff = node1.getY() - this.getY();
//         return (xDiff * xDiff) + (yDiff * yDiff);
//     }
// }
// 
// Path: src/main/java/me/pascoej/ajario/node/PlayerNode.java
// public class PlayerNode extends Node {
//     private String name;
//     private boolean mine;
// 
//     public PlayerNode(int nodeId) {
//         super(nodeId, NodeType.PLAYER);
//     }
// 
//     public String getName() {
//         if (name == null) {
//             return "";
//         }
//         return name;
//     }
// 
//     public boolean isMine() {
//         return mine;
//     }
// 
//     public void setMine() {
//         this.mine = true;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// }
// 
// Path: src/main/java/me/pascoej/ajario/node/VirusNode.java
// public class VirusNode extends Node {
//     public VirusNode(int nodeId) {
//         super(nodeId, NodeType.VIRUS);
//     }
// }
// 
// Path: src/main/java/me/pascoej/ajario/protocol/PacketListener.java
// public interface PacketListener {
//     void onRecvPacket(ClientBoundPacket agarPacket);
// }
// 
// Path: src/main/java/me/pascoej/ajario/protocol/Session.java
// public class Session {
//     private WebSocketHandler webSocketHandler;
//     private URI uri;
//     public Session(URI uri) {
//         this.uri = uri;
//         webSocketHandler = new WebSocketHandler(uri,this);
//     }
// 
//     public void connect() {
//         Set<PacketListener> packetListenerList = webSocketHandler.getPacketListeners();
//         webSocketHandler = new WebSocketHandler(uri,this);
//         webSocketHandler.getPacketListeners().addAll(packetListenerList);
//         webSocketHandler.connect();
//     }
// 
//     public void sendPacket(AgarPacket agarPacket) {
//         if (!webSocketHandler.isOpen())
//             return;
//         try {
//             webSocketHandler.sendPacket(agarPacket);
//         } catch (Exception e) {
//             e.printStackTrace();
//         }
//     }
// 
//     public void close() {
//         webSocketHandler.close();
//         webSocketHandler.clearPacketListeners();
//     }
// 
//     public void registerPacketListener(PacketListener packetListener) {
//         webSocketHandler.registerPacketListener(packetListener);
//     }
// 
//     public void unregisterPacketListener(PacketListener packetListener) {
//         webSocketHandler.unregisterPacketListener(packetListener);
//     }
// 
//     public boolean isReady() {
//         return webSocketHandler.isOpen();
//     }
// }


// Path: src/main/java/me/pascoej/ajario/AgarClient.java
import me.pascoej.ajario.node.FoodNode;
import me.pascoej.ajario.node.Node;
import me.pascoej.ajario.node.PlayerNode;
import me.pascoej.ajario.node.VirusNode;
import me.pascoej.ajario.packet.clientbound.*;
import me.pascoej.ajario.packet.serverbound.*;
import me.pascoej.ajario.protocol.PacketListener;
import me.pascoej.ajario.protocol.Session;
import java.net.URI;

    public void serverResetPacket() {
        session.sendPacket(new ConnectionResetPacket());
    }

    public boolean isDead() {
        return world.getClientNodes().isEmpty();
    }
    private static final int RECALCULATE_INTERVAL = 50;
    private int updatePackets = 0;
    private long lastUpdateNodeTime = System.currentTimeMillis();
    private double updatePerSecond = 0;

    public int getUpdatePerSecond() {
        return (int) updatePerSecond;
    }

    private void handleUpdateNodes(UpdateNodes updateNodes) {
        updatePackets += 1;
        if (updatePackets >= RECALCULATE_INTERVAL) {
            long currentTime = System.currentTimeMillis();
            long elapsed = currentTime - lastUpdateNodeTime;
            updatePerSecond = (double) updatePackets/((double)elapsed/1000.0);
        }
        for (UpdateNodes.NodeData nodeData : updateNodes.getNodeDataList()) {
            int id = nodeData.getNodeId();
            Node node = world.getNode(id);
            if (node == null) {
                if (nodeData.isVirus()) {
                    node = new VirusNode(id);
                } else if (nodeData.getSize() < 20 && nodeData.getName().equals("")) {
                    node = new FoodNode(id);