ROOM_REMOVE fired before player joins?

Post here your questions about SFS2X. Here we discuss all server-side matters. For client API questions see the dedicated forums.

Moderators: Lapo, Bax

User avatar
moccha
Posts: 112
Joined: 13 Feb 2014, 16:09

ROOM_REMOVE fired before player joins?

Postby moccha » 04 Sep 2021, 21:28

This issue I'm having may be related to viewtopic.php?f=18&t=25544

My issue is that sometimes a room is removed immeditaely after creation. I have server code that creates a room when a user enters the zone and then joins a user in it:

Code: Select all

  try
            {
                room = getApi().createRoom(user.getZone(), lobbyConfig(user), user);
            }
            catch (SFSCreateRoomException e)
            {
                trace("Skipped lobby creation, room likely exists");
                room = user.getZone().getRoomByName(user.getName()+"Lobby");
            }
            finally
            {
                getApi().joinRoom(user, room, null, false, null);
            }


Here is the lobbyConfig() settings:

Code: Select all

public static CreateMMORoomSettings lobbyConfig(User user)
    {
        CreateMMORoomSettings cfg = new CreateMMORoomSettings();
       
        // Room variables
        List<RoomVariable> roomVars;
        ...

        cfg.setName(user.getName() + "Lobby");
        cfg.setHidden(true);
        cfg.setDefaultAOI(new Vec3D(100,100,0));
        cfg.setProximityListUpdateMillis(500);
        cfg.setSendAOIEntryPoint(true);
        cfg.setMaxVariablesAllowed(7);
        cfg.setMaxUsers(8);
        cfg.setDynamic(true);
        cfg.setAutoRemoveMode(SFSRoomRemoveMode.WHEN_EMPTY);
        cfg.setRoomVariables(roomVars);
       
        return cfg;
    }


When a user joins the server log usually looks like this:

Code: Select all

17:06:29,470 INFO  [SFSWorker:Ext:3] managers.SFSRoomManager     - Room created: { Zone: World }, [ MMORoom: PlayerLobby, Id: 160, Group: default, AOI: (100, 100, 0) ], type = MMORoom
17:06:29,470 INFO  [SFSWorker:Ext:3] api.SFSApi     - Room joined: [ MMORoom: PlayerLobby, Id: 160, Group: default, AOI: (100, 100, 0) ], { Zone: World }, ( User Name: Player, Id: 59, Priv: 1, Sess: 127.0.0.1:51195 ) , asSpect: false


However on some occasions, this happens instead:

Code: Select all

16:55:31,975 INFO  [SFSWorker:Ext:2] managers.SFSRoomManager     - Room created: { Zone: World }, [ MMORoom: PlayerLobby, Id: 158, Group: default, AOI: (100, 100, 0) ], type = MMORoom
16:55:31,975 INFO  [SFSWorker:Ext:2] api.SFSApi     - Room joined: [ MMORoom: PlayerLobby, Id: 158, Group: default, AOI: (100, 100, 0) ], { Zone: World }, ( User Name: Player, Id: 77, Priv: 1, Sess: 127.0.0.1:51146 ) , asSpect: false
16:55:31,977 INFO  [pool-1-thread-4] managers.SFSRoomManager     - Room removed: { Zone: World }, [ MMORoom: PlayerLobby, Id: 158, Group: default, AOI: (100, 100, 0) ], Duration: 2


Notice the room is removed almost right after creation. The "Duration" number is 2 (milliseconds?), which is extremely short. Is this possibly because the server is checking the room as WHEN_EMPTY and since no user is in the room at that moment it is removed?

My question is if there is a way to create and join a user in a room at the same time so the room doesn't evaluate as empty, or if there is an alternate way I can try to have them join the room without it being removed. I am assuming that is the issue, but if there may be something else causing this let me know.
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: ROOM_REMOVE fired before player joins?

Postby Lapo » 06 Sep 2021, 09:11

Hi,
what SFS2X version are you using?

Notice the room is removed almost right after creation. The "Duration" number is 2 (milliseconds?), which is extremely short. Is this possibly because the server is checking the room as WHEN_EMPTY and since no user is in the room at that moment it is removed?

The check is performed after a User leaves the Room. If no one ever joins the Room it will remain available.

My issue is that sometimes a room is removed immeditaely after creation.

Do you have any additional clues on how to reproduce the problem?

As regards the try/catch/finally block you have posted I am not sure this is the best way to code it.
You're assuming that the creation error is due to the Room already existing, but it could be something else. Why not actually checking that such Room exists?

Also the finally block is not needed, you could remove it (for clarity) and everything would work the same. I'd rewrite that section like this:

Code: Select all

String lobbyName = user.getName()+"Lobby";

Room targetRoom = user.getZone().getRoomByName(lobbyName);

if (targetRoom == null)
{
    try
    {
        targetRoom = getApi().createRoom(user.getZone(), lobbyConfig(user), user);
    }
    catch (SFSCreateRoomException e)
    {
        trace("Lobby creation failed: " + e.getMessage());
    }
}

if (targetRoom != null)
    getApi().joinRoom(user, room, null, false, null);


This way it's a bit clearer, room creation errors are clearly reported and it makes it easier to debug.
Lapo
--
gotoAndPlay()
...addicted to flash games
User avatar
moccha
Posts: 112
Joined: 13 Feb 2014, 16:09

Re: ROOM_REMOVE fired before player joins?

Postby moccha » 13 Sep 2021, 12:51

I am on 2.17.1. I'll try out your new code method and let you know if I encounter any problems or find a way to reproduce it.

EDIT: It happened again with the new code, and I think it may have something to do with joining two rooms back to back. I am joining a user in their own private lobby and also in a persistent "group", which other players can also be joined in.

Here's what the current code looks like:

Code: Select all

// Join user in their group
String roomName = user.getName()+"Group";

Room targetRoom = user.getZone().getRoomByName(roomName);

if (targetRoom == null)
{
    try
    {
        targetRoom = getApi().createRoom(user.getZone(), groupConfig(user), user);
    }
    catch (SFSCreateRoomException e)
    {
        trace("Group creation failed: " + e.getMessage());
    }
}

if (targetRoom != null)
    getApi().joinRoom(user, targetRoom);

// Now join user in their lobby
roomName = user.getName()+"Lobby";

targetRoom = user.getZone().getRoomByName(roomName);

if (targetRoom == null)
{
    try
    {
        targetRoom = getApi().createRoom(user.getZone(), lobbyConfig(user), user);
    }
    catch (SFSCreateRoomException e)
    {
        trace("Lobby creation failed: " + e.getMessage());
    }
}

if (targetRoom != null)
    getApi().joinRoom(user, targetRoom, null, false, null);


The error popped up, this time with a duration of "1".

Code: Select all

09:13:27,579 INFO  [SFSWorker:Ext:2] managers.SFSRoomManager     - Room created: { Zone: World }, [ SFSGame: PlayerGroup, Id: 11, Group: default, public: true, minPlayers: 0 ], type = SFSGame
09:13:27,580 INFO  [SFSWorker:Ext:2] api.SFSApi     - Room joined: [ SFSGame: PlayerGroup, Id: 11, Group: default, public: true, minPlayers: 0 ], { Zone: World }, ( User Name: Player, Id: 4, Priv: 1, Sess: 127.0.0.1:50253 ) , asSpect: false
09:13:27,580 INFO  [SFSWorker:Ext:2] managers.SFSRoomManager     - Room created: { Zone: World }, [ MMORoom: PlayerLobby, Id: 12, Group: default, AOI: (100, 100, 0) ], type = MMORoom
09:13:27,580 INFO  [SFSWorker:Ext:2] api.SFSApi     - Room joined: [ MMORoom: PlayerLobby, Id: 12, Group: default, AOI: (100, 100, 0) ], { Zone: World }, ( User Name: Player, Id: 4, Priv: 1, Sess: 127.0.0.1:50253 ) , asSpect: false
09:13:27,581 INFO  [pool-1-thread-3] managers.SFSRoomManager     - Room removed: { Zone: World }, [ MMORoom: PlayerLobby, Id: 12, Group: default, AOI: (100, 100, 0) ], Duration: 1


When I join the user into the Group room, I don't pass any extra arguments to the joinRoom API because it doesn't matter if they are leaving any rooms. In the second join attempt however I make sure to pass null rooms so that the server does not make them exit the previous room they were joined in.

I may try also passing null arguments to the first joinRoom() function to see if that makes any difference. This problem happens randomly when logging in, but if I find a way to reproduce I'll update this post.
User avatar
moccha
Posts: 112
Joined: 13 Feb 2014, 16:09

Re: ROOM_REMOVE fired before player joins?

Postby moccha » 19 Nov 2021, 21:08

Instead of creating another post I'll update this topic.

I created a client script that automatically joins the server after 0.6 seconds, waits 0.6 seconds after logging in and then disconnects, in a loop. When a user connects, the server joins two rooms back to back - a game room and a MMO room. I let the script run for about 10 minutes and sure enough, there were random errors (only a couple for about a 100+ runs or more). The issue is rare and seemingly random, but this error pops up during login:

Code: Select all

15:57:22,457 INFO  [SFSWorker:Ext:4] api.SFSApi     - User login: { Zone: MainZone }, ( User Name: User, Id: 26, Priv: 1, Sess: 127.0.0.1:52147 ) , Type: JavaScript
15:57:22,458 INFO  [SFSWorker:Ext:4] managers.SFSRoomManager     - Room created: { Zone: MainZone }, [ MMORoom: UserHome, Id: 53, Group: default, AOI: (100, 100, 0) ], type = MMORoom
15:57:22,458 INFO  [SFSWorker:Ext:4] api.SFSApi     - Room joined: [ MMORoom: UserHome, Id: 53, Group: default, AOI: (100, 100, 0) ], { Zone: MainZone }, ( User Name: User, Id: 26, Priv: 1, Sess: 127.0.0.1:52147 ) , asSpect: false
15:57:22,459 INFO  [SFSWorker:Ext:4] managers.SFSRoomManager     - Room created: { Zone: MainZone }, [ SFSGame: UserGame, Id: 54, Group: default, public: true, minPlayers: 0 ], type = SFSGame
15:57:22,459 INFO  [SFSWorker:Ext:4] api.SFSApi     - Room joined: [ SFSGame: UserGame, Id: 54, Group: default, public: true, minPlayers: 0 ], { Zone: MainZone }, ( User Name: User, Id: 26, Priv: 1, Sess: 127.0.0.1:52147 ) , asSpect: false
15:57:22,460 INFO  [pool-1-thread-4] managers.SFSRoomManager     - Room removed: { Zone: MainZone }, [ MMORoom: UserHome, Id: 53, Group: default, AOI: (100, 100, 0) ], Duration: 2
15:57:22,476 ERROR [SFSWorker:Ext:2] v290.ExtensionReqController     - com.smartfoxserver.v2.exceptions.SFSRuntimeException:
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Exception: com.smartfoxserver.v2.exceptions.SFSRuntimeException
Message: Room is not an MMORoom! null, ( User Name: User, Id: 26, Priv: 1, Sess: 127.0.0.1:52147 ) 
Description: Error while handling client request in extension: { Ext: DCZone, Type: JAVA, Lev: ZONE, { Zone: DC }, {} }
Extension Cmd: x


This error only ever happens with MMO rooms and happens directly after joining the game room. The room is removed after a very short duration, when it shouldn't be. As a note, I've never seen the room auto-remove itself when it's a game room (only mmo room), so maybe that's a clue. Is there a difference in between how MMO rooms and normal rooms are looked at by the server when it removes them?

Here is the code that I'm using within the SFSEventType.USER_JOIN_ZONE handler:

Code: Select all

public class JoinZoneHandler extends BaseServerEventHandler
{
   @Override
   public void handleServerEvent(ISFSEvent event) throws SFSException
   {   
       User user = (User) event.getParameter(SFSEventParam.USER);
       
       // User is not a guest
       if(user.getPrivilegeId() > 0)
       {
            // Global - Received by all clients
            UserVariable x = new SFSUserVariable("x", 160);
            UserVariable y = new SFSUserVariable("y", 16);

            // Update user variables
            getApi().setUserVariables(user, Arrays.asList(x, y));
           
            // Join user in home
            Room targetRoom = user.getZone().getRoomByName(user.getName() + "Home");
           
            if (targetRoom == null)
            {
                try
                {
                    // Create home and game room and add user
                    targetRoom = getApi().createRoom(user.getZone(), homeConfig(user), user);
                }
                catch (SFSCreateRoomException e)
                {
                    trace("Could not enter home for "+user.getName()+" - "+e.getMessage());
                }
            }
           
            if (targetRoom != null)
                getApi().joinRoom(user, targetRoom, null, false, null);
           
            // Join user in game
            targetRoom = user.getZone().getRoomByName(user.getName() + "Game");
           
            if (targetRoom == null)
            {
                try
                {
                    // Create game room and add
                    targetRoom = getApi().createRoom(user.getZone(), gameConfig(user), user);
                }
                catch (SFSCreateRoomException e)
                {
                    trace("Could not create game for "+user.getName()+" - "+e.getMessage());
                }
            }
           
            if (targetRoom != null)
                getApi().joinRoom(user, targetRoom, null, false, null);
           
       }
   }
   
   public static CreateMMORoomSettings homeConfig(User user)
    {
        CreateMMORoomSettings cfg = new CreateMMORoomSettings();

        cfg.setName(user.getName() + "Home");
        cfg.setHidden(true);
        cfg.setDefaultAOI(new Vec3D(100,100,0));
        cfg.setProximityListUpdateMillis(500);
        cfg.setSendAOIEntryPoint(true);
        cfg.setMaxUsers(4);
        cfg.setDynamic(true);
        cfg.setMaxVariablesAllowed(10);
        cfg.setAutoRemoveMode(SFSRoomRemoveMode.WHEN_EMPTY);
       
        return cfg;
    }
   
    // Battle room variables and setup
    public static CreateRoomSettings gameConfig(User user)
    {
        CreateRoomSettings cfg = new CreateSFSGameSettings();
       
        cfg.setName(user.getName() + "Game");
        cfg.setGame(true);
        cfg.setMaxVariablesAllowed(9);
        cfg.setMaxUsers(4);
        cfg.setDynamic(true);
        cfg.setAutoRemoveMode(SFSRoomRemoveMode.WHEN_EMPTY);
       
        return cfg;
    }


It looks like a thread think its needs to remove a room when it shouldn't? If you create a client to automatically login and logout, look for this message in the logs: "Message: Room is not an MMORoom! null," to find the error easily.
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: ROOM_REMOVE fired before player joins?

Postby Lapo » 22 Nov 2021, 08:54

Hi,
that error message is thrown by one of two MMOApi methods:

  • setUserPosition() or
  • setMMOItemPosition()

However I don't see any calls to either of those two in the code sample you have posted.
Where is it called?
Client side? If so can you also show the client side test you have built?

If you prefer to keep it private send us an email to our support@... email box with a reference to this discussion.

Thanks
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
moccha
Posts: 112
Joined: 13 Feb 2014, 16:09

Re: ROOM_REMOVE fired before player joins?

Postby moccha » 22 Nov 2021, 13:55

In this case, the client sends a generic BaseClientRequest and the server handles the setUserPosition with

Code: Select all

sfs.getAPIManager().getMMOApi().setUserPosition(user, pos, user.getCurrentMMORoom());


but the server log shows that the room is almost instantly removed, within a few milliseconds, so the room is "null". All further setUserPosition() commands give the same error because the room is dropped by the server and doesn't exist. The error is a result of the larger problem that the room is dropped.

There really seems like a bug where MMO rooms have a slight chance of being removed when back-to-back joining another room, in this case a generic game room.

If I change the code in the sample code I posted, getting rid of the "null, false, null":

Code: Select all

getApi().joinRoom(user, targetRoom);


it behaves exactly as it does with the bug. It deletes the room reference within 2-5 milliseconds, but this is expected because it naturally wants to remove the room when joining another. There has to be something going on with the room removal check.

It doesn't matter which order I join the user in the rooms either - the mmo room is always the one that gets instantly removed.

I put a trace statement and a listener for when a user leaves a room on the server:

Code: Select all

this.addEventHandler(SFSEventType.USER_LEAVE_ROOM, LeaveRoomHandler.class);

...

Code: Select all

public class LeaveRoomHandler extends BaseServerEventHandler
{
    @Override
    public void handleServerEvent(ISFSEvent event) throws SFSException
    {      
        trace("REMOVED ROOM");
    }
}


And whenever the bug occurs, this server traces out "REMOVED ROOM", even though it shouldn't be leaving a room. I do not call leave room requests from the client and have also disallowed the client from making room join/leave requests. Only the server calls a room join in this example, and the only when a user logs in, seen in my recent post.
User avatar
moccha
Posts: 112
Joined: 13 Feb 2014, 16:09

Re: ROOM_REMOVE fired before player joins?

Postby moccha » 22 Nov 2021, 17:41

Update- I sent a working example of the bug to the email. I tried to attach it but it said the 1.2MB size was too large.

The client is HTML5 and the server source is included. After adding the SFS2X files, simply open "index.html" in the HTML5 folders and then click Login. The client will repeatedly login and logout. Wait for about 5-10 minutes and then copy and paste and look through the log for "error" and you will find examples of the bug where the room being removed after a very short duration.
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: ROOM_REMOVE fired before player joins?

Postby Lapo » 24 Nov 2021, 08:29

Thanks. We'll get back to you, as soon as possible.
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: ROOM_REMOVE fired before player joins?

Postby Lapo » 29 Nov 2021, 09:56

Hi,
I think the problem is due to the server side code not setting the :

Code: Select all

CreateMMORoomSetting.setUserMaxLimboSeconds()

value when creating the MMORoom.

I've double checked that our API do not provide a default value for this parameter (something we will fix in the next release), so if you don't specify it either it will be set to zero. With this value the User is technically allowed 0 seconds to set his position in the MMORoom, before he/she is kicked out.

The solution is to simply set the value to something between 30-60 seconds.

Hope it helps
Lapo

--

gotoAndPlay()

...addicted to flash games
User avatar
moccha
Posts: 112
Joined: 13 Feb 2014, 16:09

Re: ROOM_REMOVE fired before player joins?

Postby moccha » 29 Nov 2021, 13:52

Ah, great to hear. In my tests this fixes the problem.

Do you know what the new default will be for the next release? Thanks once again for your help. :D
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: ROOM_REMOVE fired before player joins?

Postby Lapo » 29 Nov 2021, 16:44

The default is set to 50 seconds.

Cheers
Lapo

--

gotoAndPlay()

...addicted to flash games

Return to “SFS2X Questions”

Who is online

Users browsing this forum: No registered users and 58 guests