package bomberman.gameserver;
import bomberman.PgBean;
import bomberman.RMISSLClientSocketFactory;
import bomberman.RMISSLServerSocketFactory;
import bomberman.client.MSUserClient;
import bomberman.login.Bootstrap;
import java.io.IOException;
import java.rmi.MarshalledObject;
import java.rmi.NoSuchObjectException;
import java.rmi.RemoteException;
import java.rmi.activation.Activatable;
import java.rmi.activation.ActivationException;
import java.rmi.activation.ActivationID;
import java.rmi.activation.UnknownObjectException;
import java.rmi.server.Unreferenced;
import java.util.ArrayList;
/**
* Implementazione del server di gioco di tipo Activatable.
*
* @author Federico Matera
*/
public class GameServerImpl extends Activatable implements UserGameServer, AdminGameServer, Unreferenced {
private ArrayList<Match> matches;
private Bootstrap authServer;
/**
* Costruttore del server di gioco.
* @param id L'id di attivazione.
* @param data Lo stub del server di autenticazione, permette di tenerne una referenza sul server di gioco.
*/
public GameServerImpl(ActivationID id, MarshalledObject data) throws ActivationException, IOException, ClassNotFoundException {
super(id, 10001, new RMISSLClientSocketFactory(), new RMISSLServerSocketFactory());
this.authServer = (Bootstrap) data.get();
this.matches = new ArrayList<Match>();
matches.add(new Match("match1", 2));
matches.add(new Match("match2", 2));
System.out.println("# UserGameServer è esportato come Activatable.");
}
/**
* {@inheritDoc}
*/
public void disconnect(String username) throws ActivationException, IOException, ClassNotFoundException {
authServer.logout(username);
System.out.println("> disconnetto " + username);
}
/**
* {@inheritDoc}
*/
public ArrayList<String> getMatches() throws ActivationException, IOException, ClassNotFoundException {
ArrayList<String> list = new ArrayList<String>();
for (Match mat:matches)
list.add(mat.mid);
return list;
}
/**
* {@inheritDoc}
*/
public void createMatch(String mid, int maxPlayers) throws ActivationException, IOException, ClassNotFoundException {
boolean exist = false;
for (Match mat:matches)
if (mid.compareTo(mat.mid) == 0)
exist = true;
if ((!exist) && (maxPlayers>=2) && (maxPlayers<=4)) {
matches.add(new Match(mid, maxPlayers));
System.out.println("> Creato match " + mid + ".");
}
}
/**
* {@inheritDoc}
*/
public void deleteMatch(String mid) throws ActivationException, IOException, ClassNotFoundException {
Match toDelete = null;
for (Match mat:matches)
if (mid.compareTo(mat.mid) == 0)
toDelete = mat;
matches.remove(toDelete);
System.out.println("> Eliminato match " + mid + ".");
}
/**
* {@inheritDoc}
*/
public ArrayList<Object> join(MSUserClient clientStub, String username) throws ActivationException, IOException, ClassNotFoundException {
ArrayList<Object> res = new ArrayList<Object>();
for (Match mat:matches) {
if (!mat.isFull()) {
PgBean newPlayer = mat.addPlayer(clientStub, username);
for (PgBean tempPlayer : mat.players)
if (newPlayer.getUid() != tempPlayer.getUid())
tempPlayer.getStub().joins(newPlayer);
res.add(mat.mid);
res.add(mat.map);
res.add(newPlayer);
res.add(mat.players);
System.out.println("> connetto " + username + " alla partita " + mat.mid);
return res;
}
}
System.out.println("> non ci sono partite libere, rifiuto " + username);
return null;
}
/**
* {@inheritDoc}
*/
public void leave(int uid, String mid) throws ActivationException, IOException, ClassNotFoundException {
String username = null;
Match m = null;
for (Match mat:matches) {
if (mat.mid.compareTo(mid) == 0) {
username = mat.getUsername(uid);
mat.removePlayer(uid);
m = mat;
for (int j = 0; j < mat.players.size(); j++)
mat.players.get(j).getStub().leaves(uid);
break;
}
}
/*se c'è solo un giocatore lo disconnetto e creo una nuova partita*/
try{
if (m.players.size() == 1) {
m.players.get(0).getStub().leaves(0);
matches.remove(m);
matches.add(new Match("match" + (int) (Math.random() * 20), 2));
}
}
catch(NullPointerException npe){
npe.printStackTrace();
}
System.out.println("> tolgo " + username + " con uid " + uid + " dalla partita " + mid);
}
/**
* Implementazione del metodo unreferenced.
* Si preoccupa di de-esportare il server quando inutilizzato e di lanciare il
* Garbage Collector locale.
*/
public void unreferenced() {
try {
System.out.println("# Metodo Unreferenced attivato.");
if (Activatable.unexportObject(this, true))
Activatable.inactive(this.getID());
System.out.println("# Server " + this + " de-esportato.");
//if (Activatable.unexport(this, true)
// Activatable.unregister(this.getID());
System.gc();
System.out.println("# Garbage Collector locale terminata.");
}
catch (NoSuchObjectException nsoe) {
System.out.println("unreferenced: "+ nsoe.getMessage());
nsoe.printStackTrace();
}
catch (UnknownObjectException uoe) {
System.out.println("unreferenced: "+ uoe.getMessage());
uoe.printStackTrace();
}
catch (ActivationException ae) {
System.out.println("unreferenced: "+ ae.getMessage());
ae.printStackTrace();
}
catch (RemoteException re) {
System.out.println("unreferenced: "+ re.getMessage());
re.printStackTrace();
}
}
}