Package com.esotericsoftware.kryonet.examples.position

Source Code of com.esotericsoftware.kryonet.examples.position.PositionServer

package com.esotericsoftware.kryonet.examples.position;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;

import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
import com.esotericsoftware.kryonet.examples.position.Network.AddCharacter;
import com.esotericsoftware.kryonet.examples.position.Network.RegistrationRequired;
import com.esotericsoftware.kryonet.examples.position.Network.Login;
import com.esotericsoftware.kryonet.examples.position.Network.MoveCharacter;
import com.esotericsoftware.kryonet.examples.position.Network.Register;
import com.esotericsoftware.kryonet.examples.position.Network.RemoveCharacter;
import com.esotericsoftware.kryonet.examples.position.Network.UpdateCharacter;
import com.esotericsoftware.minlog.Log;

public class PositionServer {
  Server server;
  HashSet<Character> loggedIn = new HashSet();

  public PositionServer () throws IOException {
    server = new Server() {
      protected Connection newConnection () {
        // By providing our own connection implementation, we can store per
        // connection state without a connection ID to state look up.
        return new CharacterConnection();
      }
    };

    // For consistency, the classes to be sent over the network are
    // registered by the same method for both the client and server.
    Network.register(server);

    server.addListener(new Listener() {
      public void received (Connection c, Object object) {
        // We know all connections for this server are actually CharacterConnections.
        CharacterConnection connection = (CharacterConnection)c;
        Character character = connection.character;

        if (object instanceof Login) {
          // Ignore if already logged in.
          if (character != null) return;

          // Reject if the name is invalid.
          String name = ((Login)object).name;
          if (!isValid(name)) {
            c.close();
            return;
          }

          // Reject if already logged in.
          for (Character other : loggedIn) {
            if (other.name.equals(name)) {
              c.close();
              return;
            }
          }

          character = loadCharacter(name);

          // Reject if couldn't load character.
          if (character == null) {
            c.sendTCP(new RegistrationRequired());
            return;
          }

          loggedIn(connection, character);
          return;
        }

        if (object instanceof Register) {
          // Ignore if already logged in.
          if (character != null) return;

          Register register = (Register)object;

          // Reject if the login is invalid.
          if (!isValid(register.name)) {
            c.close();
            return;
          }
          if (!isValid(register.otherStuff)) {
            c.close();
            return;
          }

          // Reject if character alread exists.
          if (loadCharacter(register.name) != null) {
            c.close();
            return;
          }

          character = new Character();
          character.name = register.name;
          character.otherStuff = register.otherStuff;
          character.x = 0;
          character.y = 0;
          if (!saveCharacter(character)) {
            c.close();
            return;
          }

          loggedIn(connection, character);
          return;
        }

        if (object instanceof MoveCharacter) {
          // Ignore if not logged in.
          if (character == null) return;

          MoveCharacter msg = (MoveCharacter)object;

          // Ignore if invalid move.
          if (Math.abs(msg.x) != 1 && Math.abs(msg.y) != 1) return;

          character.x += msg.x;
          character.y += msg.y;
          if (!saveCharacter(character)) {
            connection.close();
            return;
          }

          UpdateCharacter update = new UpdateCharacter();
          update.id = character.id;
          update.x = character.x;
          update.y = character.y;
          server.sendToAllTCP(update);
          return;
        }
      }

      private boolean isValid (String value) {
        if (value == null) return false;
        value = value.trim();
        if (value.length() == 0) return false;
        return true;
      }

      public void disconnected (Connection c) {
        CharacterConnection connection = (CharacterConnection)c;
        if (connection.character != null) {
          loggedIn.remove(connection.character);

          RemoveCharacter removeCharacter = new RemoveCharacter();
          removeCharacter.id = connection.character.id;
          server.sendToAllTCP(removeCharacter);
        }
      }
    });
    server.bind(Network.port);
    server.start();
  }

  void loggedIn (CharacterConnection c, Character character) {
    c.character = character;

    // Add existing characters to new logged in connection.
    for (Character other : loggedIn) {
      AddCharacter addCharacter = new AddCharacter();
      addCharacter.character = other;
      c.sendTCP(addCharacter);
    }

    loggedIn.add(character);

    // Add logged in character to all connections.
    AddCharacter addCharacter = new AddCharacter();
    addCharacter.character = character;
    server.sendToAllTCP(addCharacter);
  }

  boolean saveCharacter (Character character) {
    File file = new File("characters", character.name.toLowerCase());
    file.getParentFile().mkdirs();

    if (character.id == 0) {
      String[] children = file.getParentFile().list();
      if (children == null) return false;
      character.id = children.length + 1;
    }

    DataOutputStream output = null;
    try {
      output = new DataOutputStream(new FileOutputStream(file));
      output.writeInt(character.id);
      output.writeUTF(character.otherStuff);
      output.writeInt(character.x);
      output.writeInt(character.y);
      return true;
    } catch (IOException ex) {
      ex.printStackTrace();
      return false;
    } finally {
      try {
        output.close();
      } catch (IOException ignored) {
      }
    }
  }

  Character loadCharacter (String name) {
    File file = new File("characters", name.toLowerCase());
    DataInputStream input = null;
    try {
      input = new DataInputStream(new FileInputStream(file));
      Character character = new Character();
      character.id = input.readInt();
      character.name = name;
      character.otherStuff = input.readUTF();
      character.x = input.readInt();
      character.y = input.readInt();
      input.close();
      return character;
    } catch (IOException ex) {
      ex.printStackTrace();
      return null;
    } finally {
      try {
        if (input != null) input.close();
      } catch (IOException ignored) {
      }
    }
  }

  // This holds per connection state.
  static class CharacterConnection extends Connection {
    public Character character;
  }

  public static void main (String[] args) throws IOException {
    Log.set(Log.LEVEL_DEBUG);
    new PositionServer();
  }
}
TOP

Related Classes of com.esotericsoftware.kryonet.examples.position.PositionServer

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.