Package net.tacospice.stevenet

Source Code of net.tacospice.stevenet.NetServer

package net.tacospice.stevenet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.tacospice.stevenet.NetworkMessages.ChatMessage;
import net.tacospice.stevenet.NetworkMessages.CreateNode;
import net.tacospice.stevenet.NetworkMessages.DestroyNode;
import net.tacospice.stevenet.NetworkMessages.Disconnect;
import net.tacospice.stevenet.NetworkMessages.Disconnect.Reason;
import net.tacospice.stevenet.NetworkMessages.Login;
import net.tacospice.stevenet.NetworkMessages.UserConnect;
import net.tacospice.stevenet.NetworkMessages.UserDisconnect;

import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.FrameworkMessage.KeepAlive;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;

public class NetServer extends ClientServer
{
  private final Server kryoServer;
  private ServerEventHandler eventHandler = null;
  private int nextNodeId = 0;

  public NetServer()
  {
    super(true);

    kryoServer = new com.esotericsoftware.kryonet.Server()
    {
      @Override
      protected Connection newConnection()
      {
        return new NetConnection();
      }
    };

    NetworkMessages.registerBuiltInMessages(kryoServer);

    kryoServer.addListener(new Listener()
    {
      @Override
      public void received(Connection c, Object object)
      {
        NetConnection connection = (NetConnection) c;

        // Replicator update from client
        if (object instanceof ReplicatorMessage)
        {
          int nodeId = ((ReplicatorMessage) object).nodeId;
          int repId = ((ReplicatorMessage) object).replicatorId;

          Node n = nodes.get(nodeId);

          if (n != null && c.getID() == n.getOwner())
          {
            Replicator r = n.getReplicator(repId);

            if (r != null && r.getOwnerToServer())
              r.updateFromMessage((ReplicatorMessage) object);
          }

          return;
        }

        // Login request
        if (object instanceof Login)
        {
          // Already registered?
          if (connection.name != null)
          {
            logMessage("Discarded login from " + c.getID() + " (already logged in as " + connection.name + ")");

            Disconnect dc = new Disconnect();
            dc.reason = Reason.AlreadyLoggedIn;
            sendToTCP(connection.getID(), dc);

            connection.close();

            return;
          }

          // Invalid name?
          String name = ((Login) object).name;

          if (name == null)
          {
            logMessage("Discarded login from " + c.getRemoteAddressTCP() + " (name missing)");

            Disconnect dc = new Disconnect();
            dc.reason = Reason.NoName;
            sendToTCP(connection.getID(), dc);

            connection.close();

            return;
          }

          name = name.trim();
          if (name.length() == 0)
          {
            logMessage("Discarded login from " + c.getRemoteAddressTCP() + " (name has zero length)");

            Disconnect dc = new Disconnect();
            dc.reason = Reason.ZeroNameLength;
            sendToTCP(connection.getID(), dc);

            connection.close();

            return;
          }

          // Store the name on the connection
          connection.name = name;

          // TODO: verify connection with ServerEventHandler
          clientConnected(connection);

          // Replicate existing nodes
          replicateAllNodes(connection.getID());

          // Notify users
          UserConnect uc = new UserConnect();
          uc.name = connection.name;
          sendToAllTCP(uc);

          logMessage("Accepted login from " + c.getRemoteAddressTCP() + ": " + name);

          return;
        }

        // Ignore any other messages by unregistered users
        if (connection.name == null)
        {
          // TODO: disconnect user?
          logMessage("Disconnected " + c.getRemoteAddressTCP() + " (not registered)");

          Disconnect dc = new Disconnect();
          dc.reason = Reason.DidNotRegister;
          sendToTCP(connection.getID(), dc);

          connection.close();
          return;
        }

        if (object instanceof ChatMessage)
        {
          ChatMessage message = (ChatMessage) object;

          // Invalid text?
          String messageText = message.text;
          if (messageText == null)
            return;

          messageText = messageText.trim();
          if (messageText.length() == 0)
            return;

          // Prepend the connection's name and send to everyone.
          message.text = connection.name + ": " + message.text;

          sendToAllTCP(message);

          return;
        }

        if (object instanceof KeepAlive)
          return;

        unknownMessage(object);
      }

      @Override
      public void disconnected(Connection c)
      {
        NetConnection connection = (NetConnection) c;

        if (connection.name != null)
        {
          UserDisconnect uc = new UserDisconnect();
          uc.name = connection.name;
          sendToAllExceptTCP(connection.getID(), uc);

          clientDisconnected(connection);

          Iterator<Map.Entry<Integer, Node>> it = nodes.entrySet().iterator();
          while (it.hasNext())
          {
            Map.Entry<Integer, Node> entry = it.next();

            if (entry.getValue().getOwner() == connection.getID())
            {
              announceNodeRemoval(entry.getValue().getId(), entry.getValue().getOwner());

              it.remove();
            }
          }
        }
      }
    });

  }

  public void listen(int tcpPort, int udpPort) throws IOException
  {
    kryoServer.bind(tcpPort, udpPort);
    kryoServer.start();
  }

  public void close()
  {
    kryoServer.close();
    kryoServer.stop();
    clearNodes();
  }

  public Server getKryoServer()
  {
    return kryoServer;
  }

  public void setEventHandler(ServerEventHandler handler)
  {
    eventHandler = handler;
  }

  public Node createNode(int classId)
  {
    return new Node(nextNodeId++, classId, true);
  }

  private void replicateAllNodes(int connectionId)
  {
    for (Node n : nodes.values())
    {
      if (!n.wasBroadcast())
        continue;

      CreateNode cn = new CreateNode();
      cn.id = n.getId();
      cn.classId = n.getClassId();
      cn.owner = n.getOwner() == connectionId;

      sendToTCP(connectionId, cn);
    }
  }

  public List<Node> getNodesByOwner(int ownerId)
  {
    List<Node> result = new ArrayList<Node>();

    Iterator<Map.Entry<Integer, Node>> it = nodes.entrySet().iterator();
    while (it.hasNext())
    {
      Map.Entry<Integer, Node> entry = it.next();

      if (entry.getValue().getOwner() == ownerId)
        result.add(entry.getValue());
    }

    return result;
  }

  public void announceNodeRemoval(int nodeId, int except)
  {
    DestroyNode dn = new DestroyNode();
    dn.id = nodeId;
    sendToAllExceptTCP(except, dn);
  }

  /*
   * Event handler methods
   */
  private void logMessage(String message)
  {
    if (eventHandler != null)
      eventHandler.logMessage(message);
  }

  private void clientConnected(NetConnection connection)
  {
    if (eventHandler != null)
      eventHandler.clientConnected(connection);
  }

  private void clientDisconnected(NetConnection connection)
  {
    if (eventHandler != null)
      eventHandler.clientDisconnected(connection);
  }

  private void unknownMessage(Object message)
  {
    if (eventHandler != null)
      eventHandler.unknownMessage(message);
  }

  /*
   * NetEndpoint methods
   */
  @Override
  public void sendToAllTCP(Object message)
  {
    kryoServer.sendToAllTCP(message);
  }

  @Override
  public void sendToAllExceptTCP(int id, Object message)
  {
    kryoServer.sendToAllExceptTCP(id, message);
  }

  @Override
  public void sendToTCP(int id, Object message)
  {
    kryoServer.sendToTCP(id, message);
  }

  @Override
  public void sendToAllUDP(Object message)
  {
    kryoServer.sendToAllUDP(message);
  }

  @Override
  public void sendToAllExceptUDP(int id, Object message)
  {
    kryoServer.sendToAllExceptUDP(id, message);
  }

  @Override
  public void sendToUDP(int id, Object message)
  {
    kryoServer.sendToUDP(id, message);
  }

  /*
   * Unused methods
   */

  @Override
  public void sendTCP(Object message)
  {
  }

  @Override
  public void sendUDP(Object message)
  {
  }
}
TOP

Related Classes of net.tacospice.stevenet.NetServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.