package robombs.game.model;
import java.util.*;
import robombs.clientserver.*;
import robombs.game.*;
/**
* A manager class that handles local objects on the server identified by a combination of client- and objectID.
*/
public class ServerObjectManager {
private Map<ClientInfo, LocalObjectList> client2LocalObj=null;
/**
* Create a new manager.
*/
public ServerObjectManager() {
reset();
}
public void reset() {
NetLogger.log("Server: Resetting the server's object state!");
client2LocalObj=new HashMap<ClientInfo, LocalObjectList>();
}
/**
* Gets a local object stored on the server identified by the clientID and the objectID. The actual client don't know a thing
* about which local object ID their objects will get on the server which is why they can't transmit them. All they know is, how THEY
* identify their objects. This method maps between those two worlds.
* @param objID the objectID
* @param clientID the clientID
* @return LocalObject the corresponding local object
*/
public LocalObject getLocalObjectToIDs(int objID, int clientID) {
for (Iterator<LocalObjectList> itty=client2LocalObj.values().iterator(); itty.hasNext();) {
LocalObjectList entry=itty.next();
for (Iterator<LocalObject> itty2=entry.iterator(); itty2.hasNext();) {
LocalObject lo=itty2.next();
if (lo.getClientID()==clientID) {
if (lo.getObjectID() == objID) {
return lo;
}
} else {
break; // Wrong client!
}
}
}
return null;
}
/**
* Fills a data container with data from the all local objects on the server.
* @param dc the container to fill
*/
public void fill(ExtendedDataContainer dc, ClientInfo ci) {
Map<ClientInfo, LocalObjectList> copy=new HashMap<ClientInfo, LocalObjectList>(client2LocalObj);
if (ci!=null) {
copy.remove(ci);
}
for (Iterator<LocalObjectList> itty=copy.values().iterator(); itty.hasNext();) {
LocalObjectList lol=itty.next();
for (Iterator<LocalObject> itty2=lol.iterator(); itty2.hasNext();) {
LocalObject lo=itty2.next();
dc.add(lo);
}
}
}
/**
* Takes the input transmitted by a client and creates or updates the local instances that represent
* the objects on the client.
* @param ec the container with the client's objects
*/
public void setOrUpdate(ExtendedDataContainer ec) {
ClientInfo ci=ec.getClientInfo();
LocalObjectList lol=getLocalObjectList(ci);
LocalObject lo=new LocalObject(ci.getID(), true);
ec.fillLocalObject(lo);
boolean found=false;
for (Iterator<LocalObject> itty=lol.iterator(); itty.hasNext();) {
LocalObject lot=itty.next();
if (lot.equals(lo)) {
lot.copyFrom(lo);
found = true;
break;
}
}
if (!found) {
lol.add(lo);
NetLogger.log("Server: Added an object of client "+ci.getID()+"! Client's object count is now: "+lol.size());
}
}
/**
* Removes an object from the server's list, i.e. it doesn't exist on the client any longer.
* @param lo the object to remove
* @param ci the client info
*/
public void removeObject(LocalObject lo, ClientInfo ci) {
LocalObjectList lol=getLocalObjectList(ci);
boolean ok=lol.remove(lo);
if (ok) {
NetLogger.log("Server: Removed an object ("+lo.getObjectID()+") of client " + ci.getID() + "! Client's object count is now: " + lol.size());
} else {
NetLogger.log("Server: Failed to remove object of client " + ci);
}
}
/**
* Returns a list of all local objects for a specific client.
* @param ci the client for the client in question
* @return LocalObjectList the list of local objects for this client that the server knows of
*/
public LocalObjectList getLocalObjectList(ClientInfo ci) {
if (!client2LocalObj.containsKey(ci)) {
LocalObjectList lol=new LocalObjectList();
client2LocalObj.put(ci, lol);
}
return (LocalObjectList) client2LocalObj.get(ci);
}
/**
* Removes a client completely from the list, i.e. it kills all of its local objects on the server.
* @param ci the client
*/
public void remove(ClientInfo ci) {
client2LocalObj.remove(ci);
}
}