Author Topic: Stand-alone Server - set channel and player datanode  (Read 3248 times)

devomage

  • Sr. Member
  • ****
  • Thank You
  • -Given: 7
  • -Receive: 67
  • Posts: 250
    • View Profile
Stand-alone Server - set channel and player datanode
« on: September 14, 2016, 06:02:41 PM »
what is the correct way to set channel and player datanode values from the server?

currently, i send a packet to the channel host and the host sets values via TNManager.  i would rather omit this step and set values directly from the server.

im assuming follow the "Packet.RequestSetPlayerData" case?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Stand-alone Server - set channel and player datanode
« Reply #1 on: September 17, 2016, 12:35:00 AM »
Player values can only be set by the player in question. You can't set other players' data.

Channel values should be set by the host, although it's up to you how to handle that. Easiest approach is to simply check for TNManager.isHosting in your code.

For anything custom, if you want simplicity, I suggest handling it the same way I have TNObject.Set work:
  1.         public void Set (string name, object val)
  2.         {
  3.                 if (isMine) OnSet(name, val);
  4.                 else Send("OnSet", ownerID, name, val);
  5.         }
  6.  
  7.         [RFC]
  8.         void OnSet (string name, object val)
  9.         {
  10.                 if (mData == null) mData = new DataNode("ObjectData");
  11.                 mData.SetHierarchy(name, val);
  12.                 OnSetData(mData);
  13.                 Send("OnSetData", Target.OthersSaved, mData);
  14.         }
  15.  
  16.         [RFC]
  17.         void OnSetData (DataNode data)
  18.         {
  19.                 mData = data;
  20.                 if (onDataChanged != null) onDataChanged(data);
  21.         }
In other words, if this is the player that should be doing this sort of thing, set it directly. Otherwise send an RFC to the player that should be doing this to perform the action. In the first RFC you update the data, then send the updated value to everyone else.

This approach ensures simplicity, while forcing all data to go through one player, thus eliminating race conditions.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Stand-alone Server - set channel and player datanode
« Reply #2 on: September 17, 2016, 12:38:23 AM »
If your question was about modifying the server to be able to set data directly without going through clients, then I don't understand the question as there is no complexity to it as you can just skip the request part altogether.

devomage

  • Sr. Member
  • ****
  • Thank You
  • -Given: 7
  • -Receive: 67
  • Posts: 250
    • View Profile
Re: Stand-alone Server - set channel and player datanode
« Reply #3 on: September 17, 2016, 03:55:18 AM »
the question is setting player/channel data exclusively from the server.  the couple times ive tried -- data was overwritten or not set at all.. and needless to say, no events firing.

i have no problems with the client, but would like to omit unnecessary packets when the server could set the data initially.

for example, i have the client-host send a packet to the server:  give player #3 x amount of experience.  the server updates the mysql table and responds to the host.  the host then tells the player:  you received x amount of experience.  the player adds the new experience to their datanode.  i think (?) it would be better if the server simply sets the players datanode and the player deals with it accordingly via the OnSetPlayerData event.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Stand-alone Server - set channel and player datanode
« Reply #4 on: September 17, 2016, 04:05:59 AM »
Search for references to RequestSetPlayerData. One of them will be on line 1405 of TNGameServer.cs. That's where the server processes the request packet. What you want instead is a response packet, which is what the server sends out afterwards:
  1. Buffer buff = Buffer.Create();
  2. BinaryWriter writer = buff.BeginPacket(Packet.ResponseSetPlayerData);
  3. writer.Write(player.id);
  4. writer.Write("");
  5. writer.WriteObject(player.dataNode);
  6. buff.EndPacket();
  7. SendToOthers(buff, player, player, true);
  8. buff.Recycle();
The "" string is the path. "" means setting the entire data node. If you want to set a specific part of it, you would specify an actual path like "Stats/xp". The object is the data node in question. In this case, it's the root data node, matching the path. SendToOthers sends this buffer to other players that know this 'player'.

devomage

  • Sr. Member
  • ****
  • Thank You
  • -Given: 7
  • -Receive: 67
  • Posts: 250
    • View Profile
Re: Stand-alone Server - set channel and player datanode
« Reply #5 on: September 17, 2016, 03:17:34 PM »
perfect.  thanks!