So the question is: how can I notify the client that the player joined a new room and send/receive messages from it?
Server side code for creating/joining a room based on the rank:
Code: Select all
public class SearchRankedGameHandler extends BaseClientRequestHandler {
private static final String ROOM_GROUP_ID = "ranked";
private static final int MAX_USERS = 2;
private static final int DEFAULT_RATING = 1200;
private static final String RANKED_EXTENSION = "RankedExtension";
@SneakyThrows
@Override
public void handleClientRequest(User user, ISFSObject params) {
trace(ExtensionLogLevel.DEBUG, "Searching ranked game for player: ", user);
int rating = getRoundedRating(user);
try {
trace("starting search for game");
try {
joinGameAndStart(user, rating);
} catch (IllegalArgumentException | SFSQuickJoinGameException e) {
trace("Join error", e.getMessage());
createNewGame(user, rating);
}
} catch (SFSJoinRoomException | SFSCreateRoomException e) {
sendError(ErrorMessageKeys.ROOM_JOIN_ERROR, user, true, e);
}
}
private void joinGameAndStart(User user, int rating) throws SFSJoinRoomException {
ISFSGameApi gameAPI = SmartFoxServer.getInstance().getAPIManager().getGameApi();
MatchExpression exp = new MatchExpression(RoomProperties.IS_GAME, BoolMatch.EQUALS, true)
.and(RoomProperties.HAS_FREE_PLAYER_SLOTS, BoolMatch.EQUALS, true)
.and(RoomProperties.MAX_USERS, NumberMatch.EQUALS, MAX_USERS)
.and(RoomProperties.GROUP_ID, StringMatch.EQUALS, ROOM_GROUP_ID)
.and(RankedBattleExtension.ROOMVAR_RANK, NumberMatch.EQUALS, rating)
.and(RankedBattleExtension.ROOMVAR_GAME_STARTED, BoolMatch.EQUALS, false);
Room rankedRoom = gameAPI.quickJoinGame(
user, exp, getParentExtension().getParentZone(), ROOM_GROUP_ID);
trace(ExtensionLogLevel.DEBUG, "Room found. Players: ", rankedRoom.getPlayersList());
}
private void createNewGame(User user, int rating) throws SFSCreateRoomException, SFSJoinRoomException {
trace("Creating Room. Player: ", user);
CreateSFSGameSettings cfg = new CreateSFSGameSettings();
cfg.setName(UUID.randomUUID().toString().substring(0, 10));
cfg.setGame(true);
cfg.setGroupId(ROOM_GROUP_ID);
cfg.setGamePublic(true);
cfg.setMinPlayersToStartGame(MAX_USERS);
cfg.setMaxUsers(MAX_USERS);
cfg.setDynamic(true);
cfg.setLeaveLastJoinedRoom(true);
cfg.setRoomVariables(Arrays.asList(
new SFSRoomVariable(RankedBattleExtension.ROOMVAR_RANK, rating, true, false, false),
new SFSRoomVariable(RankedBattleExtension.ROOMVAR_GAME_STARTED, false, true, false, false)));
cfg.setExtension(new CreateRoomSettings.RoomExtensionSettings(RANKED_EXTENSION,
RankedBattleExtension.class.getName()));
ISFSGameApi gameAPI = SmartFoxServer.getInstance().getAPIManager().getGameApi();
gameAPI.createGame(
getParentExtension().getParentZone(),
cfg, user);
trace(ExtensionLogLevel.DEBUG, "Room created. Player: ", user);
}
private int getRoundedRating(User user) {
int rating = DEFAULT_RATING;
if (user.getVariable("rating") == null) {
trace("Setting rating to player: ", user.getName());
try {
user.setVariable(new SFSUserVariable("rating", rating));
} catch (SFSVariableException e) {
sendError(ErrorMessageKeys.ROOM_JOIN_ERROR, user, true, e);
}
} else {
trace("Getting rating from player: ", user.getName());
rating = user.getVariable("rating").getIntValue();
}
int mod = rating % 100;
int hundreds = rating / 100 * 100;
if (mod >= 0 && mod <= 25) {
return hundreds;
} else if (mod > 25 && mod <= 75) {
return hundreds + 50;
} else {
return hundreds + 100;
}
}
}
Room extension:
Code: Select all
public class RankedBattleExtension extends BaseExtension<BattleController> {
@Override
public void init() {
addEventHandler(SFSEventType.USER_JOIN_ROOM, this::userJoined);
}
private void userJoined(ISFSEvent event) {
trace("User joined...");
Object object = ...;
send(Commands.Battle.S2C_START, SFSObjectUtils.getInstance().newSFSObjectFromObject(object), getParentRoom().getUserList());
}
}
I took off a lot of codes but basically the message, when the user successfully joined the room, doesn't get to the client side. Other messages sent later doesn't either.
Client side:
Code: Select all
void Awake() {
#if !UNITY_WEBGL
sfs = new SmartFox();
#else
sfs = new SmartFox(UseWebSocket.WS_BIN);
#endif
sfs.ThreadSafeMode = true;
ConfigData cfg = new ConfigData();
cfg.Host = HOST;
cfg.Port = PORT;
cfg.Zone = ZONE_NAME;
sfs.AddEventListener(SFSEvent.CONNECTION, OnConnection);
sfs.AddEventListener(SFSEvent.CONNECTION_LOST, OnConnectionLost);
sfs.AddEventListener(SFSEvent.LOGIN, OnLogin);
sfs.AddEventListener(SFSEvent.LOGIN_ERROR, OnLoginError);
sfs.AddEventListener(SFSEvent.EXTENSION_RESPONSE, OnExtensionResponse);
sfs.Connect(cfg);
}
void Start() {
if (instance != null) {
GameObject.Destroy(this.gameObject);
return;
}
instance = this;
}
void Update() {
if (sfs != null) {
sfs.ProcessEvents();
}
}
private void Reset() {\
sfs.RemoveAllEventListeners();
}
private void OnLogin(BaseEvent evt) {
// Remove SFS2X listeners and re-enable interface
Reset();
sfs.AddEventListener(SFSEvent.EXTENSION_RESPONSE, OnExtensionResponse);
Debug.Log("Sending C2S_SEARCH");
sfs.Send(new ExtensionRequest(Commands.RankedGame.C2S_SEARCH, new SFSObject(), sfs.LastJoinedRoom));
Debug.Log("C2S_SEARCH sent");
}
public void OnExtensionResponse(BaseEvent evt) {
Debug.Log("evt " + evt);
string cmd = (string)evt.Params["cmd"];
Debug.Log("Command received " + cmd);
messageFromOponent.text = "Command received " + cmd;
Canvas.ForceUpdateCanvases();
SFSObject dataObject = (SFSObject)evt.Params["params"];
switch ( cmd ) {
case Commands.Battle.S2C_START: // Search for game response
messageFromOponent.text = "game found = " + dataObject;
Canvas.ForceUpdateCanvases();
myPlayerID = sfs.MySelf.PlayerId;
break;
case "SRrn": // message received from oponent
messageFromOponent.text = dataObject.GetUtfString("m");
Canvas.ForceUpdateCanvases();
break;
}
}