Package org.jpokemon.server

Source Code of org.jpokemon.server.PlayerManager

package org.jpokemon.server;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import org.jpokemon.activity.Activity;
import org.jpokemon.battle.lobby.LobbyService;
import org.jpokemon.extra.FriendsService;
import org.jpokemon.extra.PartyService;
import org.jpokemon.overworld.OverworldService;
import org.jpokemon.trainer.Player;
import org.json.JSONException;
import org.json.JSONObject;
import org.zachtaylor.jnodalxml.XmlParser;

public class PlayerManager {
  public static boolean playerIsLoggedIn(String name) {
    boolean result;

    synchronized (players) {
      result = players.containsKey(name);
    }

    return result;
  }

  public static boolean playerExists(String name) {
    if (playerIsLoggedIn(name)) {
      return true;
    }

    String filename = name + ".jpkmn";

    File file = new File(JPokemonServer.savepath, filename);
    if (!file.exists() || !file.getName().equals(filename)) {
      return false;
    }

    return true;
  }

  public static Player getPlayer(String name) {
    Player player;

    synchronized (players) {
      player = players.get(name);
    }

    return player;
  }

  public static List<String> getOnlinePlayerNames() {
    List<String> playerNames = null;

    synchronized (players) {
      playerNames = Collections.unmodifiableList(new ArrayList<String>(players.keySet()));
    }

    return playerNames;
  }

  public static void bootstrapServices() {
    services = new HashMap<String, JPokemonService>();
    services.put("overworld", new OverworldService());
    services.put("lobby", new LobbyService());
    services.put("friends", new FriendsService());
    services.put("party", new PartyService());
  }

  public static JPokemonService getService(String name) {
    return services.get(name);
  }

  public static boolean hasActivity(Player player) {
    return !activities.get(player.id()).isEmpty();
  }

  public static Activity getActivity(Player player) {
    Stack<Activity> stack = activities.get(player.id());
    return stack.peek();
  }

  public static void addActivity(Player player, Activity a) {
    try {
      activities.get(player.id()).add(a);
      a.onAdd(player);
    }
    catch (ServiceException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  public static void popActivity(Player player, Activity a) {
    if (getActivity(player) != a) {
      throw new IllegalStateException("Popped activity is not most recent");
    }

    activities.get(player.id()).pop();

    if (hasActivity(player)) {
      getActivity(player).onReturn(a, player);
    }
  }

  public static void pushMessage(Player player, Message message) {
    pushJson(player, message.toJson());
  }

  public static void pushJson(Player player, JSONObject json) {
    if (json == null) {
      return;
    }

    JPokemonWebSocket webSocket;

    synchronized (players) {
      webSocket = sockets.get(player.id());
    }

    webSocket.sendJson(json);
  }

  public static void dispatch(JPokemonWebSocket socket, JSONObject request) throws JSONException, ServiceException {
    String playerId;
    synchronized (players) {
      playerId = sessions.get(socket);
    }

    if (playerId == null) {
      login(socket, request);
      return;
    }

    Player player = getPlayer(playerId);

    if (request.has("load")) {
      String serviceName = request.getString("load");
      JPokemonService service = services.get(serviceName);

      PlayerManager.pushJson(player, service.load(request, player));
    }
    else if (hasActivity(player)) {
      Activity a = getActivity(player);

      a.serve(request, player);
    }
    else if (request.has("service")) {
      String serviceName = request.getString("service");
      JPokemonService service = services.get(serviceName);

      service.serve(request, player);
    }
  }

  public static void close(JPokemonWebSocket socket) {
    String playerId;
    synchronized (players) {
      playerId = sessions.get(socket);
    }

    if (playerId == null) {
      return;
    }

    Player player = getPlayer(playerId);

    System.out.println(player + " session closed");

    File file = new File(JPokemonServer.savepath, playerId + ".jpkmn");

    try {
      Writer writer = new BufferedWriter(new PrintWriter(file));
      writer.write(player.toXml().printToString(0, "\t"));
      writer.close();
    }
    catch (IOException e) {
      e.printStackTrace();
    }

    for (JPokemonService service : services.values()) {
      service.logout(player);
    }

    while (hasActivity(player)) {
      activities.get(player.id()).pop().logout(player);
    }
    activities.remove(playerId);

    synchronized (players) {
      sessions.remove(socket);
      sockets.remove(playerId);
      players.remove(playerId);
    }
  }

  private static void login(JPokemonWebSocket socket, JSONObject request) throws JSONException, ServiceException {
    if (!request.has("login")) {
      throw new ServiceException("No credentials found");
    }

    String name = request.getString("login");

    if (playerIsLoggedIn(name)) {
      Message message = new Message("error", "Player '" + name + "' is already logged in!");
      socket.sendJson(message.toJson());
      return;
    }
    if (!playerExists(name)) {
      Message message = new Message("error", "Player '" + name + "' save not found!");
      socket.sendJson(message.toJson());
      return;
    }

    Player player = new Player(name);

    System.out.println(player + " session opened");

    String filename = name + ".jpkmn";
    File file = new File(JPokemonServer.savepath, filename);

    try {
      player.loadXML(XmlParser.parse(file).get(0));
    }
    catch (FileNotFoundException e) {
    }

    synchronized (players) {
      players.put(name, player);
      sockets.put(name, socket);
      sessions.put(socket, name);
    }

    for (JPokemonService service : services.values()) {
      service.login(player);
    }

    activities.put(name, new Stack<Activity>());

    JSONObject closeLoginJson = new JSONObject();
    try {
      closeLoginJson.put("action", "login:accept");
    }
    catch (JSONException e) {
    }
    pushJson(player, closeLoginJson);
  }

  private static Map<String, JPokemonService> services;

  /** Lock on players for players, connections, reverseConnections */
  private static volatile Map<String, Player> players = new HashMap<String, Player>();
  private static volatile Map<String, JPokemonWebSocket> sockets = new HashMap<String, JPokemonWebSocket>();
  private static volatile Map<JPokemonWebSocket, String> sessions = new HashMap<JPokemonWebSocket, String>();

  private static Map<String, Stack<Activity>> activities = new HashMap<String, Stack<Activity>>();
}
TOP

Related Classes of org.jpokemon.server.PlayerManager

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.