Page 1 of 1

SetUserVariables() Sending back wrong types (all bools)

Posted: 06 May 2009, 21:23
by dlong

Looks like something is wrong with the Hashtable being sent back from the server using the c# client api for the OnUserVariablesUpdate event.

Client-side code:

Code: Select all

 Hashtable uVars = new Hashtable();
 uVars.Add("avatarName", "Homer");
 uVars.Add("posx", 100);
 uVars.Add("posy", 200);

Debug statement (xml being sent):

Code: Select all

Debug - 5/6/2009 3:39:02 PM: [Sending]: <msg t='sys'><body action='setUvars' r='
1'><vars><var n='avatarName' t='s'><![CDATA[Homer]]></var><var n='posy' t='n'><!
[CDATA[200]]></var><var n='posx' t='n'><![CDATA[100]]></var></vars></body></msg>

The xml being sent across appears correct... the types are correct (n and s).

However, on the receiving side (I have another client window open that handles the OnUserVariablesUpdate event) the Hashtable I get back is all bools

Here is a debug statement I have in the event handler:

Code: Select all

foreach (object key in updatedVariables.Keys)
                sb.AppendFormat("key {0}: value {1} || ", key.ToString(), updatedVariables[key].ToString());

Which outputs this:

Code: Select all

UserVariablesUpdate - 5/6/2009 3:39:04 PM: user david_633772211073615456 updated
 these variables key avatarName: value True || key posy: value True || key posx:
 value True ||

Can you confirm if this is a bug, known issue, or configuration issue (on my server side).


I think so.

Posted: 06 May 2009, 23:39
by matrix211v1
I too am having issuse with this.

Posted: 07 May 2009, 05:10
by ThomasLund

Could you paste the XML that the second client receives? To see if its the server that has a bugger, or if its sent allright and its the API that parses it wrong?



Posted: 08 May 2009, 01:05
by dlong
Hi Thomas!

Thanks for the quick response... Looks like you're the main man for the Unity/C# integration! My email updates for this thread are not working so I'm a bit behind.

I attached my debugger in SmartFoxClient.cs on the XmlReceived(string msg) method (line 3382). Here is the xml coming back:

Code: Select all

<msg t='sys'><body action='uVarsUpdate' r='1'><user id='3' /><vars><var n='avatarName' t='s'><![CDATA[Homer]]></var><var n='posy' t='n'><![CDATA[200]]></var><var n='posx' t='n'><![CDATA[100]]></var></vars></body></msg>

For some reason I totally overlooked this yesterday... I traced it through to PopulateVariables() in SysHandler.cs (line 1074) and I think I see where the issue is (at least in the 1.1 API code I have, which could be old).

Check out line 1085:

Code: Select all

changedVars.Add(vName, true);

Looks like something is getting mixed up with Hashtables here being passed back up to HandleUserVarsUpdate() in SysHandler.cs (line 634)

Let me know if you need any more info and thanks for looking into this!


Posted: 08 May 2009, 01:10
by dlong
Ah, check out SmartFoxClient.cs (line 4114):

Code: Select all

SFSEvent.onUserVariablesUpdate((User)evt.GetParameter("user"), (Hashtable)evt.GetParameter("changedVars"));

Looks like it's digging out the "changedVars" parameter rather than the user.variables Hashtable buried a few levels down in the evt.parameters Hashtable.

Hope this helps!


Posted: 08 May 2009, 04:02
by ThomasLund
Hi dlong

Yes - the API calls back with the signature:

public delegate void OnUserVariablesUpdateDelegate(User user, Hashtable changedVars);

with the description:

Code: Select all

         * <summary>
         * Dispatched when a user in the current room updates his/her User Variables.
         * </summary>
         * <param name="user">the <see cref="User"/> object representing the user who updated his/her variables.</param>
         * <param name="changedVars">a Hashtable with the names of the changed variables as keys.</param>

So that last part at least is not an error.

The XML you sent seems to have all variables correctly labeled with their types. So if you can see these.

Might it be, that you misread the description of the API? It calls into code with the changed variables only - not their values. Those can be fetched subsequent from the user variables.

This is intended behaviour (to keep compatibility with the actionscript API).

The actual "chop" code is in the SysHandler.cs - all the way down in the bottom.

Code: Select all

      private void PopulateVariables(Hashtable variables, XmlNode xmlData, Hashtable changedVars) {
         foreach ( XmlNode v in XmlUtil.GetNodeList(xmlData, "vars/var") ) {
            string vName = XmlUtil.GetString(v, "./@n");
            string vType = XmlUtil.GetString(v, "./@t");
            string vValue = XmlUtil.GetString(v, "./node()");

            // Add the vName to the list of changed vars
            // The changed List is an array that can contains all the
            // var names changed with numeric indexes but also contains
            // the var names as keys for faster search
            if ( changedVars != null ) {
               changedVars.Add(vName, true);

            if ( vType == "b" )
               variables[vName] = (string)vValue == "1" ? true : false;

            else if ( vType == "n" )
               variables[vName] = double.Parse(vValue);

            else if ( vType == "s" )
               variables[vName] = (string)vValue;

            else if ( vType == "x" )


Each changed variable gets set as "changed"=true in the changesVars.

Hope that explains it all :-)

And no matter what - thanks for reporting!!! I value every bugreport - we are all in here for one reason - to make this work as good as possible.


Posted: 08 May 2009, 16:46
by dlong
LOL, my bad! I get it now and I'm able to get the values out of the user object.


Posted: 08 May 2009, 21:29
by ThomasLund
Super - perfect!!!

Happy to help

Posted: 29 Sep 2009, 23:32
by pankajnagarkoti74
Thanks for the quick response... Looks like you're the main man for the Unity/C# integration! My email updates for this thread are not working so I'm a bit behind.