Package pdp.scrabble.multiplayer.impl

Source Code of pdp.scrabble.multiplayer.impl.ServerImpl

package pdp.scrabble.multiplayer.impl;

import java.rmi.AlreadyBoundException;
import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import pdp.scrabble.game.Bag;
import pdp.scrabble.game.Letter;
import pdp.scrabble.utility.Display;
import pdp.scrabble.multiplayer.Client;
import pdp.scrabble.multiplayer.Server;
import static pdp.scrabble.Factory.FACTORY;
import static pdp.scrabble.Language.getGameLang;

/**
*/
public class ServerImpl extends UnicastRemoteObject implements Server {
    private static final long serialVersionUID = 1L;

    /** List of all client connected */
    private List<Client> clients = new ArrayList<Client>(4);

    /** Reference to clients' name */
    private HashMap<Client, String> clientsName = new HashMap<Client, String>(1);

    /** Reference to clients' id */
    private HashMap<Client, Integer> clientsID = new HashMap<Client, Integer>(1);

    /** Ready state. */
    private int playerReady = 0;

    /** Player's id to play */
    private int idTurn = 0;

    /** Bag reference. */
    private Bag bag = null;

    /** Openened state. */
    private boolean openServer = true;

    /** Running state. */
    private boolean runningServer = false;

    /** Server url. */
    private String url = null;

    /** Thread check */
    private Thread check = null;

    /** Thread check state. */
    private boolean threadCheck = false;

    /** Langue of game. */
    private String language = null;

    public ServerImpl(int port, String language)
      throws RemoteException, AlreadyBoundException {

  super();
  this.bag = FACTORY.createBag();
  this.threadCheck = false;
  this.language = language;
  this.initialize(port);
    }

    private void initialize(int port)
      throws RemoteException, AlreadyBoundException {

  this.url = "rmi://localhost:" + port + "/Scrabble";

  try {
      LocateRegistry.createRegistry(port);
  }
  catch (Exception e) {
  }

  try {
      Naming.rebind(this.url, this);
      this.threadCheck = true;
      this.check = new Thread() {
    @Override
    public void run() {
        setName("Clients alive check");
        while (threadCheck) {
      Client toRemove = null;
      try {
          sleep(TIMEOUT);
      }
      catch (InterruptedException e1) {
          //Display.error("Sleep", "Error");
      }
      for (Client client : clients) {
          try {
        client.ping();
          }
          catch (Exception e) {
        toRemove = client;
          }
      }
      if (toRemove != null) {
          try {
        disconnect(clientsID.get(toRemove));
          }
          catch (RemoteException ex) {
        Display.error("Disconnect", "Error RMI");
          }
      }
        }
    }
      };
      this.check.start();
  }
  catch (MalformedURLException ex) {
      Display.error("Server", "Bad URL !");
      this.url = null;
  }
    }

    @Override
    public Client connect(String nick, Client client) throws RemoteException {
  this.clients.add(client);
  this.clientsName.put(client, nick);
  this.clientsID.put(client, clientsID.size());
  if (this.clients.size() >= 4) {
      this.openServer = false;
  }
  this.sendMessage("<Game>", this.clientsName.get(client) + " "
           + getGameLang("connected."));

  this.updatePlayerTable();
  this.updateButton();
  this.playerReady = 0;
  return client;
    }

    @Override
    public void disconnect(int id) throws RemoteException {
  Client client = getClientById(id);

  if (!this.runningServer) {
      this.clients.remove(client);
      this.sendMessage(
        "<Game>", this.clientsName.get(client) + " "
            + getGameLang("disconnected."));

      this.clientsID.remove(client);
      this.removePlayerTable(id);
      this.updateButton();
      this.playerReady = 0;
      this.openServer = true;
  }
  else {
      this.clients.remove(client);
      this.sendMessage(
        "<Game>", this.clientsName.get(client) + " "
            + getGameLang("disconnected."));

      this.setPlayertable(id, null, getGameLang("Disconnect"), -1);
  }
    }

    @Override
    public void endServer()
      throws RemoteException, MalformedURLException, AccessException {

  this.sendMessage(
    "<Game>", "Server is closed,"
        + " Wait if server will come back or exit the Game");

  this.setPlayertable(0, null, getGameLang("Disconnect"), -1);
  UnicastRemoteObject.unexportObject(this, false);
  this.clients.clear();
  this.clientsID.clear();
  this.clientsName.clear();
  try {
      Naming.unbind(this.url);
      this.url = null;
  }
  catch (NotBoundException ex) {
      Display.error("Server", "Error Url Server");
  }

  this.threadCheck = false;
    }

    @Override
    public void endTurnMulti() throws RemoteException {
  int idSrc = this.idTurn;

  if (this.idTurn + 1 < this.clients.size()) {
      this.idTurn++;
  }
  else {
      this.idTurn = 0;
  }

  // Need to check if client disconnected while playing
  if (!this.clientsID.containsValue(this.idTurn)) {
      if (this.idTurn + 1 < this.clients.size()) {
    this.idTurn++;
      }
      else {
    this.idTurn = 0;
      }
  }

  Client client = getClientById(this.idTurn);
  String name = this.clientsName.get(client);
  client.getTurn(name);
  this.setPlayertable(idSrc, null, getGameLang("Thinking"), -1);
  this.setPlayertable(this.idTurn, null, getGameLang("Playing"), -1);
  this.sendMessage("<Game>", client.getName() + " " + getGameLang("turn."));
    }

    @Override
    public void sendReadyMulti(int id) throws RemoteException {
  this.playerReady++;

  if (this.playerReady == this.clients.size()) {
      this.openServer = false;
      this.runningServer = true;
      this.bag.initWithLanguage(this.language);
      this.bag.fill();

      //we put all client in state ready
      for (Client client : this.clients) {
    client.launchGameMulti();
      }
  }
    }

    @Override
    public void sendMessage(String src, String msg) throws RemoteException {
  for (Client client : this.clients) {
      if (client != null) {
    client.getMessage(src, msg);
      }
  }
    }

    @Override
    public void sendLetter(Client client, Letter letter, int v, int h)
      throws RemoteException {

  for (Client cl : clients) {
      if (client != cl) {
    cl.getLetter(letter, v, h);
      }
      else {
    //local client already have letters on his board
      }
  }
    }

    @Override
    public Letter pickLetter() throws RemoteException {
  return this.bag.getRandomLetter();
    }

    /** Return client with the player's id ID.
     * @param ID player id.
     * @return client corresponding to id.
     */
    private Client getClientById(int ID) {
  Client client = null;
  for (Client cl : clients) {
      if (clientsID.get(cl) == ID) {
    client = cl;
      }
  }
  return client;
    }

    @Override
    public boolean isOpen() throws RemoteException {
  return this.openServer;
    }

    @Override
    public boolean existName(String name) throws RemoteException {
  return this.clientsName.containsValue(name);
    }

    @Override
    public int getWordValueServer(String str) throws RemoteException {
  return this.bag.getWordValue(str);
    }

    @Override
    public int getSizePlayers() throws RemoteException {
  return this.clients.size();
    }

    @Override
    public Letter exchangeLetter(Letter letter) throws RemoteException {
  this.bag.addLetter(letter);
  return this.bag.getRandomLetter();
    }

    @Override
    public void sendStats(int turn, String name, int points, String words)
      throws RemoteException {

  for (Client client : this.clients) {
      client.getStats(turn, name, points, words);
  }
    }

    private void updatePlayerTable() throws RemoteException {
  for (Client client : this.clients) {
      client.clearTable();
      for (Client user : this.clients) {
    client.getAddPlayerTable(this.clientsName.get(user), getGameLang("Wait"), 0);
      }
  }
    }

    private void removePlayerTable(int id) throws RemoteException {
  for (Client client : this.clients) {
      client.getRemovePlayerTable(id);
  }
    }

    @Override
    public void setPlayertable(int id, String name, String status, int score)
      throws RemoteException {

  for (Client client : this.clients) {
      if (client != null) {
    client.getSetPlayerTable(id, name, status, score);
      }
  }
    }

    private void showDialog(String head, String message) throws RemoteException {
  for (Client client : this.clients) {
      client.showDialog(head, message);
  }
    }

    @Override
    public boolean ping() throws RemoteException {
  return true;
    }

    private void updateButton() throws RemoteException {
  for (Client client : this.clients) {
      client.updateButton();
      for (int i = 0; i < clients.size(); i++) {
    client.getSetPlayerTable(i, null, getGameLang("Wait"), -1);
      }
  }
    }

    @Override
    public String getLanguage() throws RemoteException{
  return this.language;
    }
}
TOP

Related Classes of pdp.scrabble.multiplayer.impl.ServerImpl

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.