Page 1 of 1

Dynamic Room Extension Issue

Posted: 06 Oct 2009, 06:57
by mistermind
Hello there my fellow sfs friends.
I've just ran into a pickle here regarding creating a dynamic room and loading an extension to it. This extension is not specified on my config.xml file (as it seems not to be needed according to sfsTris and maze examples), but instead, its only listed inside the sfsExtensions folder (and accessible by the admin tool). Lets skip the connections and go straight to the problem shall we?

Smartfox Version: 1.6.3 (if the problem is version please explain me why :D)

Client Code:

Code: Select all

var room:Object = {};
room.name = "gameDemo";
room.password = "";
room.isGame = true;
room.exitCurrentRoom = false;
room.maxUsers = 2;
                  
var xt:Object = {};
xt.name = "gameStats";
xt.script = "gameStats.as";
room.extension = xt;
                  
sfs.createRoom(room);


As far as creating the room, everything runs smoothly. The problem here is the simple fact that the server seems unable to load the extension (even thou the admin tool says its loaded, but again, if I write idontexist.as as the script name it will also say idontexist.as is loaded).

To clear things up even more, this is what I get from SFS Debug (code reorganized and filtered):

Sending

Code: Select all

[Sending]:
<msg t='sys'>
   <body action='createRoom' r='97'>
      <room tmp='1' gam='1' spec='0' exit='0' jas='0'>
         <name><![CDATA[gameDemo]]></name>
         <pwd><![CDATA[]]></pwd>
         <max>2</max>
         <xt n='gameStats' s='gameStats.as' />
         <vars></vars>
      </room>
   </body>
</msg>


Received

Code: Select all

[ RECEIVED ]:
<msg t='sys'>
   <body action='roomAdd' r='0'>
      <rm id='34660' priv='0' temp='1' game='1' max='2' spec='0' limbo='0'>
         <name><![CDATA[gameDemo]]></name>
         <vars />
      </rm>
   </body>
</msg>

[ RECEIVED ]:
<msg t='sys'>
   <body action='joinOK' r='34641'>
      <pid id='1'/>
      <vars />
      <uLs r='34641'>
         <u i='21281' m='1' s='0' p='1'>
            <n><![CDATA[Mistermind]]></n>
            <vars>
               <var n='a63' t='b'><![CDATA[1]]></var>
               <var n='a64' t='b'><![CDATA[1]]></var>
               <var n='a60' t='b'><![CDATA[1]]></var>
               <var n='a16' t='b'><![CDATA[1]]></var>
               <var n='a17' t='b'><![CDATA[1]]></var>
               <var n='rank' t='n'><![CDATA[201]]></var>
               <var n='a14' t='b'><![CDATA[1]]></var>
               <var n='a15' t='b'><![CDATA[1]]></var>
               <var n='a10' t='b'><![CDATA[1]]></var>
               <var n='a11' t='b'><![CDATA[1]]></var>
               <var n='cRank' t='s'><![CDATA[Shade]]></var>
               <var n='a57' t='b'><![CDATA[1]]></var>
               <var n='a56' t='b'><![CDATA[1]]></var>
               <var n='a72' t='b'><![CDATA[1]]></var>
               <var n='a73' t='b'><![CDATA[1]]></var>
               <var n='a74' t='b'><![CDATA[1]]></var>
               <var n='a70' t='b'><![CDATA[1]]></var>
               <var n='loc' t='s'><![CDATA[]]></var>
               <var n='a26' t='b'><![CDATA[1]]></var>
               <var n='a21' t='b'><![CDATA[1]]></var>
               <var n='a22' t='b'><![CDATA[1]]></var>
               <var n='a66' t='b'><![CDATA[1]]></var>
               <var n='a29' t='b'><![CDATA[1]]></var>
               <var n='a65' t='b'><![CDATA[1]]></var>
               <var n='a67' t='b'><![CDATA[1]]></var>
               <var n='a76' t='b'><![CDATA[1]]></var>
               <var n='a77' t='b'><![CDATA[1]]></var>
               <var n='a78' t='b'><![CDATA[1]]></var>
               <var n='rm' t='n'><![CDATA[0]]></var>
               <var n='a41' t='b'><![CDATA[1]]></var>
               <var n='a40' t='b'><![CDATA[1]]></var>
               <var n='rat' t='n'><![CDATA[8]]></var>
               <var n='id' t='n'><![CDATA[229]]></var>
               <var n='a1' t='b'><![CDATA[1]]></var>
               <var n='a35' t='b'><![CDATA[1]]></var>
               <var n='a2' t='b'><![CDATA[1]]></var>
               <var n='a34' t='b'><![CDATA[1]]></var>
               <var n='a3' t='b'><![CDATA[1]]></var>
               <var n='a4' t='b'><![CDATA[1]]></var>
               <var n='a39' t='b'><![CDATA[1]]></var>
               <var n='a38' t='b'><![CDATA[1]]></var>
               <var n='a7' t='b'><![CDATA[1]]></var>
               <var n='a86' t='b'><![CDATA[1]]></var>
               <var n='a8' t='b'><![CDATA[1]]></var>
               <var n='a85' t='b'><![CDATA[1]]></var>
               <var n='a89' t='b'><![CDATA[1]]></var>
               <var n='a88' t='b'><![CDATA[1]]></var>
               <var n='a50' t='b'><![CDATA[1]]></var>
               <var n='a51' t='b'><![CDATA[1]]></var>
               <var n='a52' t='b'><![CDATA[1]]></var>
               <var n='a53' t='b'><![CDATA[1]]></var>
               <var n='pic' t='s'><![CDATA[3]]></var>
               <var n='acc' t='s'><![CDATA[a]]></var>
               <var n='clan' t='s'><![CDATA[Darkness]]></var>
               <var n='a92' t='b'><![CDATA[1]]></var>
               <var n='a91' t='b'><![CDATA[1]]></var>
               <var n='a90' t='b'><![CDATA[1]]></var>
               <var n='a48' t='b'><![CDATA[1]]></var>
               <var n='a94' t='b'><![CDATA[1]]></var>
            </vars>
         </u>
      </uLs>
   </body>
</msg>


Also, to avoid making a new post on another problem, another thing bothers me:
As you can see I use A LOT of the server side user vars, and in most cases (as the aXX vars you see above) are only suppose to be on the server as a reference to validate achievements from the users when a package is sent. Is it possible to not have ALL the user variables sent everytime a user logs in? I know its possible from the server to use _server.setUserVariables(user, uVars, false) but that only works when you update them. They are still sent to new users when they first join a room.

And further more: Is it possible to convert SFS Protocol to JSON rather then XML (rather then replace my sfs events with extension responses)

Thanks in advance!
Dan 8)

Posted: 07 Oct 2009, 07:56
by Lapo
As regards creating the Room with attached extension there's no know problem even in version 1.6.3
In order to check what is the problem please do check the log files. There you will find more details if an error occurs. Maybe the extensions is loaded by it fires an exception in the init() method... just an idea.

As regards Room Variables. Any game/user data that is not needed on the client side should be kept away from Room Variables to avoid wasting bandwidth.
Each User object carries its own properties object which can be used to store any relevant User data. Use that instead of Room Variables for anything that doesn't need to be broadcasted.

And further more: Is it possible to convert SFS Protocol to JSON rather then XML (rather then replace my sfs events with extension responses)

No, custom protocols are available for extension calls.
On the positive side the next major version of SFS will include a fully binary, highly efficient protocol that will cut down bandwidth usage by orders of magnitude :)

Posted: 07 Oct 2009, 16:22
by mistermind
Hi Lapo and thanks for the answers :D

As regards Room Variables. Any game/user data that is not needed on the client side should be kept away from Room Variables to avoid wasting bandwidth.
Each User object carries its own properties object which can be used to store any relevant User data. Use that instead of Room Variables for anything that doesn't need to be broadcasted.


I'm actually using user vars, not room vars to store these elements (from an sfs extension, an example):

loadStatus.as (as the game loads):

Code: Select all

...
var achievs = "34,67,12" // Example. the real deal comes from db
if (achievs){
   achievsArray = achievs.split(",");
   for (var ac in achievsArray) {
      uVars["a"+achievsArray[ac]] = true;
   }
}
var uVars = {}
if (lvl >= 12  && !uVars.a56){
   uVars.a56 = true;
   dbase.executeCommand("insert into tbAchievs(id,idAchiev) values ("+ id +",56)")
}
if (acc == "adv" && !uVars.a77){
   uVars.a77 = true;
   dbase.executeCommand("insert into tbAchievs(id,idAchiev) values ("+ id +",77)")
}
_server.setUserVariables(user, uVars, false);


saveAchiev.as (whenever you receive a new achievement):

Code: Select all

...
var id = user.getVariable("id");
var achievId = user.getVariable("a"+params.acId);
var uVars = {};
var response = {};
      
if (!achievId){
   dbase.executeCommand("insert into tbAchievs (idAchiev,id) values ("+ params.acId +","+ id.getValue() +")");
}
      
uVars[a"+ params.acId] = true;
_server.setUserVariables(user, uVars, false);
...


What the user vars aXX do is simple: store the boolean context of every achievement already received as you load the initial extension on userVariables and test them out whenever you trigger the saveAchiev.as extension from the client (so basically you don't have to search the database again).
My problem is that userVariables are always automatically sent to a new user everytime they login, regardless of u not broadcasting them upon update from the server, and my real question, in a more simplified way is:
Is there a parameter from userVars (or any other property) form the user Object that can be used exclusively by the server without being broadcasted all the time?

Posted: 09 Oct 2009, 08:14
by Lapo
No, there isn't.
There is a simple rule however.

User data that needs to be broadcast to anyone goes into User Variables
User data that needs to stay server side only goes into User.properties

Posted: 09 Oct 2009, 13:55
by mistermind
Lapo wrote:User data that needs to stay server side only goes into User.properties


Awesome! That is exactly what I need! Thanks a bunch :D