// Path: src/main/java/org/projectnyx/module/ModuleManager.java
// public abstract class ModuleManager<T> {
//     private final Class<T> myClass;
//     @Getter(lazy = true) private final String moduleTypeName = moduleType();
//     @Getter private Map<String, T> modules = new HashMap<>();
// 
//     protected abstract String moduleType();
// 
//     protected ModuleManager(Class<T> myClass) {
//         this.myClass = myClass;
//         Nyx.getInstance().getModuleManagers().put(getModuleTypeName(), this);
//     }
// 
//     public void loadForClass(String name, String className) throws Exception {
//         Class<? extends T> aClass = Class.forName(className).asSubclass(myClass);
//         T instance = aClass.newInstance();
//         modules.put(name, instance);
//     }
// }
// 
// Path: src/main/java/org/projectnyx/network/ext/SessionHandler.java
// @RequiredArgsConstructor
// public abstract class SessionHandler {
//     @Getter private final InetSocketAddress address;
//     @Getter private final SharedServerSocket socket;
// 
//     public abstract void onReceive(PacketWithAddress pk);
// 
//     public abstract void send(ByteBuffer buffer);
// 
//     public abstract void close();
// 
//     public abstract Protocol getProtocol();
// 
//     public void tick() {
// 
//     }
// 
//     /**
//      * <p>Returns whether this session an orphan.</p>
//      *
//      * <p>An orphan session is a session that has not been recognized by any sessions yet.</p>
//      *
//      * @return whether this session is an orphan.
//      */
//     public abstract boolean isOrphan();
// }
// 
// Path: src/main/java/org/projectnyx/network/ext/SharedSocketPool.java
// public class SharedSocketPool {
//     @Getter private static SharedSocketPool instance;
// 
//     private Map<Identifier, SharedServerSocket> sockets = new HashMap<>();
// 
//     public SharedSocketPool() {
//         instance = this;
//     }
// 
//     @NonNull
//     public SharedServerSocket getOrCreate(Identifier identifier) {
//         if(!sockets.containsKey(identifier)) {
//             addSocket(identifier.create());
//         }
//         return sockets.get(identifier);
//     }
// 
//     void addSocket(SharedServerSocket socket) {
//         sockets.put(socket.getIdentifier(), socket);
//     }
// 
//     void removeSocket(SharedServerSocket socket) {
//         sockets.remove(socket.getIdentifier(), socket);
//     }
// 
//     public void tick() {
//         sockets.values().forEach(SharedServerSocket::tick);
//     }
// }


import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import org.projectnyx.module.ModuleManager;
import org.projectnyx.network.ext.SessionHandler;
import org.projectnyx.network.ext.SharedSocketPool;
/*
 * Nyx - Server software for Minecraft: PE and more
 * Copyright © boredphoton 2016
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.projectnyx.network;



public class NetworkManager extends ModuleManager<Protocol> {
    @Getter private static NetworkManager instance;

    @Getter @Setter @NotNull private QueryResponse queryResponse;
    private final SharedSocketPool sockets = new SharedSocketPool();

    private boolean running = true;

    public NetworkManager() {
        super(Protocol.class);
        instance = this;

        queryResponse = new QueryResponse();
        queryResponse.setName("Nyx rised.");
        queryResponse.setCountPlayers(1);
        queryResponse.setMaxPlayers(10);
    }

    public void start() {
        new Thread(() -> {
            while(running) {
                sockets.tick();
            }
        }).start();
    }

    @Override
    protected String moduleType() {
        return "Protocol";
    }

    /**
     * Requires a protocol to adopt this session.
     *
     * @param session
     * @return
     */
    public Client adoptSession(SessionHandler session) {
        for(Protocol protocol : getModules().values()) {
            Client client = protocol.acceptSession(session);
// Path: src/main/java/org/projectnyx/module/ModuleManager.java
// public abstract class ModuleManager<T> {
//     private final Class<T> myClass;
//     @Getter(lazy = true) private final String moduleTypeName = moduleType();
//     @Getter private Map<String, T> modules = new HashMap<>();
// 
//     protected abstract String moduleType();
// 
//     protected ModuleManager(Class<T> myClass) {
//         this.myClass = myClass;
//         Nyx.getInstance().getModuleManagers().put(getModuleTypeName(), this);
//     }
// 
//     public void loadForClass(String name, String className) throws Exception {
//         Class<? extends T> aClass = Class.forName(className).asSubclass(myClass);
//         T instance = aClass.newInstance();
//         modules.put(name, instance);
//     }
// }
// 
// Path: src/main/java/org/projectnyx/network/ext/SessionHandler.java
// @RequiredArgsConstructor
// public abstract class SessionHandler {
//     @Getter private final InetSocketAddress address;
//     @Getter private final SharedServerSocket socket;
// 
//     public abstract void onReceive(PacketWithAddress pk);
// 
//     public abstract void send(ByteBuffer buffer);
// 
//     public abstract void close();
// 
//     public abstract Protocol getProtocol();
// 
//     public void tick() {
// 
//     }
// 
//     /**
//      * <p>Returns whether this session an orphan.</p>
//      *
//      * <p>An orphan session is a session that has not been recognized by any sessions yet.</p>
//      *
//      * @return whether this session is an orphan.
//      */
//     public abstract boolean isOrphan();
// }
// 
// Path: src/main/java/org/projectnyx/network/ext/SharedSocketPool.java
// public class SharedSocketPool {
//     @Getter private static SharedSocketPool instance;
// 
//     private Map<Identifier, SharedServerSocket> sockets = new HashMap<>();
// 
//     public SharedSocketPool() {
//         instance = this;
//     }
// 
//     @NonNull
//     public SharedServerSocket getOrCreate(Identifier identifier) {
//         if(!sockets.containsKey(identifier)) {
//             addSocket(identifier.create());
//         }
//         return sockets.get(identifier);
//     }
// 
//     void addSocket(SharedServerSocket socket) {
//         sockets.put(socket.getIdentifier(), socket);
//     }
// 
//     void removeSocket(SharedServerSocket socket) {
//         sockets.remove(socket.getIdentifier(), socket);
//     }
// 
//     public void tick() {
//         sockets.values().forEach(SharedServerSocket::tick);
//     }
// }


// Path: src/main/java/org/projectnyx/network/NetworkManager.java
import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import org.projectnyx.module.ModuleManager;
import org.projectnyx.network.ext.SessionHandler;
import org.projectnyx.network.ext.SharedSocketPool;

/*
 * Nyx - Server software for Minecraft: PE and more
 * Copyright © boredphoton 2016
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.projectnyx.network;



public class NetworkManager extends ModuleManager<Protocol> {
    @Getter private static NetworkManager instance;

    @Getter @Setter @NotNull private QueryResponse queryResponse;
    private final SharedSocketPool sockets = new SharedSocketPool();

    private boolean running = true;

    public NetworkManager() {
        super(Protocol.class);
        instance = this;

        queryResponse = new QueryResponse();
        queryResponse.setName("Nyx rised.");
        queryResponse.setCountPlayers(1);
        queryResponse.setMaxPlayers(10);
    }

    public void start() {
        new Thread(() -> {
            while(running) {
                sockets.tick();
            }
        }).start();
    }

    @Override
    protected String moduleType() {
        return "Protocol";
    }

    /**
     * Requires a protocol to adopt this session.
     *
     * @param session
     * @return
     */
    public Client adoptSession(SessionHandler session) {
        for(Protocol protocol : getModules().values()) {
            Client client = protocol.acceptSession(session);
            if(client != null) {