Page 1 of 1

room.getCreator() from the client side?

Posted: 23 Nov 2010, 08:59
by mephi
Guys,
one day struggle and I couldn't figure out this problem, please help!

SFS PRO 1.6.9
Client api - AS2 v.1.6.3

Long story short, I have a task which could be easily done if there were such things as:
1. room.getCreator() from the client side.
2. roomVariablesUpdate - outside of the specific room which is updated. Which could be hard and unnecessary i guess.


Now the long story.
The goal is to make a table list of game rooms within a Lobby room, which contains field with the name of the room creator and various other variables got from the room creator user object.
If in a room there are 2 users and the creator leaves the room, then the one which is left present in the room becomes the creator.
Up to here everything is fine.
The problem is how to update the clients which are sitting in the Lobby room with this creator-change?


My solution tryouts.

1. Using room variables.
Let's put a "roomCreator" variable in every new game room. In zone's config there is roomListVars="true", so when a client in the Lobby gets the roomlist, this roomCreator variable is populated.
However, when the creator leaves the room and his successor becomes creator and this roomCreator variable is changed, the onRoomVariablesUpdate happens only in that specific room (which is reasonable of course) and the clients in the lobby room are not updated.
When a totally new client joins the Lobby it gets roomlist with updated variables and it can see the new roomCreator. But, the old clients which saw the initial room creation, with the initial roomCreator are never updated with the new one! No matter how the game list changes, or how many rooms they join and leave, the client API(or the serverside I dunno...) detects that they already got the info for this room, and do not update the variables!
The only way I found for an "old" client to update the room variable is to join this room, which is no option for a list update.
I tried to put this room variables from both serverside and client side without any difference.
So this didn't worked out for me.

2. Using user variables.
Let's put a "host" variable in every user to be used as a flag. By default it's set to false, but when a user creates a game room, it is set to true. If the host leaves the game room, the guest becomes host. When you cycle the game rooms to populate the room-list you can extract the users, get their variables, check who is host and put his name on the list, right?
Well, actually no! I couldn't get populated userList from room.getUserList() for a game room, from a client joined in a normal Lobby room!

Code: Select all

function traceRoom(roomObj:Room):Void
{
    var users = roomObj.getUserList();
    
    trace("room = "+roomObj.getName()+"; room.getUserCount() = "+ roomObj.getUserCount()+"; users = " + users);
    
    for (var vname in users) {
        trace("users[" + vname + "] =" + users[vname]);
        trace("users["+vname+"] = " + users[vname].getVariable("host"));
    }
}
If you do this traceRoom on onUserCountChange or onRoomListUpdate cycle you will see empty users object.

So this too didn't worked out.

Is there a way to get populated user list in a specific room, without being in this room?
I guess it can be done with custom serverside response, but for the purpose of such task as a game list, wouldn't that generate too much traffic?

Is there any easier solution than creating custom roomlists from the server side, or custom server responces for this room changes only?

Posted: 23 Nov 2010, 17:40
by BigFIsh
1. Using room variables.
Let's put a "roomCreator" variable in every new game room. In zone's config there is roomListVars="true", so when a client in the Lobby gets the roomlist, this roomCreator variable is populated.
However, when the creator leaves the room and his successor becomes creator and this roomCreator variable is changed, the onRoomVariablesUpdate happens only in that specific room (which is reasonable of course) and the clients in the lobby room are not updated.
When a totally new client joins the Lobby it gets roomlist with updated variables and it can see the new roomCreator. But, the old clients which saw the initial room creation, with the initial roomCreator are never updated with the new one! No matter how the game list changes, or how many rooms they join and leave, the client API(or the serverside I dunno...) detects that they already got the info for this room, and do not update the variables!
The only way I found for an "old" client to update the room variable is to join this room, which is no option for a list update.
I tried to put this room variables from both serverside and client side without any difference.
So this didn't worked out for me.
This is expected behavior. The reason for the prevention of onRoomVariablesUpdate outside the scope of the room is mainly due to the bandwidth considerations. Nevertheless, this can resolved by using sendResponse (from the server) to notify all other users in the lobby of the change. I use this workaround, and it works fine for me.
2. Using user variables.
Let's put a "host" variable in every user to be used as a flag. By default it's set to false, but when a user creates a game room, it is set to true. If the host leaves the game room, the guest becomes host. When you cycle the game rooms to populate the room-list you can extract the users, get their variables, check who is host and put his name on the list, right?
Well, actually no! I couldn't get populated userList from room.getUserList() for a game room, from a client joined in a normal Lobby room!
Yup, like you said - you can't get the user list of other rooms due for an obvious reason.

Posted: 23 Nov 2010, 19:04
by mephi
Thanks BigFIsh!
The reason for the prevention of onRoomVariablesUpdate outside the scope of the room is mainly due to the bandwidth considerations.
Yep, quite reasonable!
Nevertheless, this can resolved by using sendResponse (from the server) to notify all other users in the lobby of the change. I use this workaround, and it works fine for me.
I was kinda trying to avoid that.
How exactly you do this?
Totally new gamelist response?
Or Custom sendResponse like "change roomId owner to userId"?

If it is the latter it means you have to store this values in a local variable in the client, so whenever it got RoomListUpdate, and you repopulate the game-list-table, you check this local var for the changed rooms, or your client will get out of sync on his first RoomListUpdate.
Right?

Well, I guess it is a small price to pay for the sake of bandwidth saving :-)

Posted: 23 Nov 2010, 23:24
by BigFIsh
If it is the latter it means you have to store this values in a local variable in the client, so whenever it got RoomListUpdate, and you repopulate the game-list-table, you check this local var for the changed rooms, or your client will get out of sync on his first RoomListUpdate.
Right?
This is what I do:
1. Player A sends command to server to tell it to make player B host.
2. Server updates the hostId room variable
3. Then it sends a 'update hostId for roomId' via sendResponse
4. Clients in lobby will get onExtensionResponse, and then manually update the hostId variable for that room using room.setVariables() - this does not send any updates to the client. Note: To get all existing variables for that room, use room.getVariables()
5. The clients in that room where the command was sent from, will be notified of this via onRoomVariableUpdates().

Posted: 24 Nov 2010, 07:30
by mephi
Thanks again BigFIsh!

All is clear except this part:
4. Clients in lobby will get onExtensionResponse, and then manually update the hostId variable for that room using room.setVariables() - this does not send any updates to the client. Note: To get all existing variables for that room, use room.getVariables()
I am using AS2 API version 1.6.3 (I know I have to upgrade to AS3 but that's long story...) and there is no setVariables() method for the Room object!
I just looked at the AS3 API and there it is!

I will write my own cause it is pretty simple, but wouldn't it be great if GOTOANDPLAY team updates AS2 API too?
Or it's too old and the support for it has been stopped? :(

Anyway, thanks for the revelations! :)

Posted: 24 Nov 2010, 11:41
by mephi
3. Then it sends a 'update hostId for roomId' via sendResponse
Wait, how you do that with the hostId?
Do you really send only the UserId of the user, or his name as string?

Because, if you send only the id, when you try to get the user from the room with room.getUser(userId) - from the lobby's perspective it will return undefined user, cause the client does not have updated userlist for that room.

Or am I wrong?

Posted: 24 Nov 2010, 17:44
by BigFIsh
Because, if you send only the id, when you try to get the user from the room with room.getUser(userId) - from the lobby's perspective it will return undefined user, cause the client does not have updated userlist for that room.
What you're seeing is correct. You can't access the user list for rooms that is outside the scope of the room you are in. Why do you need to access that user's object from the lobby? Do you need to get the host name? If so, store the host name as a room variable instead of the id.

I use hostId to check which user within the scope of the room is the host

Posted: 25 Nov 2010, 07:54
by mephi
Do you need to get the host name? If so, store the host name as a room variable instead of the id.
Yes, exactly! I am doing it like this. Just I was puzzled when you mentioned the hostId and thought you are using it somehow to get the user object. But apparently no.

Thanks for the help! :)