Our server consists of a single zone. This zone contains one (auto join) room (we call it the main lobby) in which all users are joined and serves for general tasks such as private chat between users, private messages, ... Beside this room we have several other rooms. These rooms are represented as lobbies for each game. So for example if we have 10 games, we will have 11 rooms - 10 rooms for each game lobby and 1 room for general tasks. I hope I made myself clear up till now
So the basic idea is that user is always joined in main lobby room. He can also be joined in only one game lobby room. Here is an excerpt from our code, that handles expected behavior.
First the main lobby extension (zone extension):
Code: Select all
public class MainLobby extends AbstractExtension
{
private SmartFoxServer sfs;
private ExtensionHelper eh;
private Zone zone;
private HashMap<String, Lobby> lobbies;
@Override
public void init()
{
sfs = SmartFoxServer.getInstance();
eh = ExtensionHelper.instance();
zone = sfs.getZone(getOwnerZone());
lobbies = new HashMap<String, Lobby>();
lobbies.put("game1", new Lobby("game1",zone,eh));
lobbies.put("game2", new Lobby("game2",zone,eh));
}
@Override
public void handleRequest(String cmd, String params[], User u, int fromRoom)
{
JSONObject jso = getJSON(params[0]); // this method is not essential for this example, so it's not included in the code
String command = jso.getString("c");
JSONObject data = jso.getJSONObject("o");
if(command.equals("joinLobby"))
{
String name = data.getString("name");
Lobby lobby = lobbies.get(name);
responseObj = lobby.addUser(u);
}
else if(command.equals("leaveLobby"))
{
String name = data.getString("name");
Lobby lobby = lobbies.get(name);
responseObj = lobby.removeUser(u);
}
}
@Override
public void handleInternalEvent(InternalEventObject ieo)
{
String eventName = ieo.getEventName();
System.out.println("[MainLobby] :: internal event:" + eventName);
if(eventName.equals(InternalEventObject.EVENT_LOGIN))
{
User user = null;
try
{
user = sfs.canLogin(nick, pass, chan, zone);
}
catch(LoginException e)
{
e.printStackTrace();
}
// Auto join room
if(user != null)
{
try
{
eh.joinRoom(user, -1, this.zone.getAutoJoinRoom(), false, null, false, false);
}
catch(ExtensionHelperException e)
{
e.printStackTrace();
}
}
}
}
}Code: Select all
public class Lobby
{
private String name;
private Zone zone;
private Room room;
private ExtensionHelper eh;
public Lobby(String name, Zone zone, ExtensionHelper eh)
{
this.name = name;
this.zone = zone;
this.eh = eh;
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("name", name);
params.put("maxU", "1000000");
params.put("isGame", "false");
params.put("isLimbo", "true");
params.put("xtName", name+"Ex");
params.put("xtClass", "lobby.extensions.LobbyExtension");
try
{
room = this.eh.createRoom(zone, params, null, true, true);
}
catch(ExtensionHelperException e)
{
e.printStackTrace();
}
}
public void addUser(User u)
{
try
{
eh.joinRoom(u, u.getRoom(), room.getId(), false, null, false, true);
}
catch(ExtensionHelperException e)
{
e.printStackTrace();
}
}
public void removeUser(User u)
{
eh.leaveRoom(u, room.getId(), true);
}
}Code: Select all
public class LobbyExtension extends AbstractExtension
{
@Override
public void init()
{
}
@Override
public void handleRequest(String cmd, ActionscriptObject ao, User u, int fromRoom)
{
System.out.println("[LobbyExtension] :: handleRequest(XML)");
}
@Override
public void handleRequest(String cmd, String params[], User u, int fromRoom)
{
System.out.println("[LobbyExtension] :: handleRequest(RAW)");
}
@Override
public void handleInternalEvent(InternalEventObject ieo)
{
String eventName = ieo.getEventName();
System.out.println("[LobbyExtension] :: internal event:" + eventName);
}
}I would expect that if user is removed from the room in Lobby class, userExit event would be dispatched only in LobbyExtension class and not in MainLobby class. So can someone please help me with this problem and how to solve it so that SFS would behave as expected?
Kind regards!