Author Topic: Stand-alone Server DataNode Error  (Read 14010 times)

devomage

  • Sr. Member
  • ****
  • Thank You
  • -Given: 7
  • -Receive: 67
  • Posts: 250
    • View Profile
Stand-alone Server DataNode Error
« on: September 30, 2016, 12:38:14 AM »
i have other DateTime vars that i use - not sure what the deal is with this one.

server response to client:
  1. DataNode resptotarget = new DataNode("response", "friend_request");
  2.  
  3. resptotarget.AddChild("status", true);
  4. resptotarget.AddChild("errmsg", "");
  5.  
  6. resptotarget.AddChild("pid", p.id);
  7. resptotarget.AddChild("phpbb_id", ACCOUNT.phpbb_id);
  8. resptotarget.AddChild("phpbb_accountname", ACCOUNT.phpbb_accountname);
  9. resptotarget.AddChild("is_online", ACCOUNT.is_online);
  10. resptotarget.AddChild("last_active", DateTime.UtcNow);//hardcoded date for testing
  11. resptotarget.AddChild("last_charid", ACCOUNT.last_charid);
  12.  

client receives:
  1. response = "friend_request"
  2.         status = true
  3.         errmsg = ""
  4.         phpbb_id = 48
  5.         phpbb_accountname = "tester"
  6.         is_online = true
  7.         last_active = 636108099220000000
  8.         last_charid = 25
  9.  

causes error:
  1. Unable to convert System.UInt64 (636108099220000000) to System.DateTime
  2. UnityEngine.Debug:LogError(Object)
  3. TNet.Tools:LogError(String, String, Boolean) (at Assets/TNet/Common/TNTools.cs:1075)
  4. TNet.Serialization:ConvertObject(Object, Type, GameObject) (at Assets/TNet/Common/TNSerializer.cs:654)
  5. TNet.Serialization:Convert(Object) (at Assets/TNet/Common/TNSerializer.cs:546)
  6. TNet.DataNode:Get() (at Assets/TNet/Common/DataNode.cs:149)
  7. TNet.DataNode:GetChild(String) (at Assets/TNet/Common/DataNode.cs:434)
  8.  
  9. Server:Response(Packet, BinaryReader, IPEndPoint) (at Assets/.../Scripts/GAME.cs:922)
  10.  
  11. TNet.GameClient:ProcessPacket(Buffer, IPEndPoint) (at Assets/TNet/Client/TNGameClient.cs:967)
  12. TNet.GameClient:ProcessPackets() (at Assets/TNet/Client/TNGameClient.cs:918)
  13. TNet.TNManager:<ProcessPackets>m__17() (at Assets/TNet/Client/TNManager.cs:528)
  14. TNet.TNManager:Update() (at Assets/TNet/Client/TNManager.cs:1823)
  15.  

client receive code:
  1. int phpbb_id = data.GetChild<int>("phpbb_id");
  2. string phpbb_accountname = data.GetChild<string>("phpbb_accountname");
  3. bool is_online = data.GetChild<bool>("is_online");
  4. DateTime last_active = data.GetChild<DateTime>("last_active");//line #922 -- commenting out this line, of course - removes the error
  5. int last_charid = data.GetChild<int>("last_charid");
  6.  

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Stand-alone Server DataNode Error
« Reply #1 on: September 30, 2016, 10:38:59 AM »
Try this:
  1. // serializing
  2. resptotarget.AddChild("last_active", DateTime.UtcNow.Ticks);
  3. // deserializing
  4. DateTime last_active = new DateTime(data.GetChild<long>("last_active"), DateTimeKind.Utc);
  5.  

I'm not too familiar with the DataNode class, so perhaps there's a different way of doing this, but this should certainly fix the serialization error. The Ticks property returns a signed long (Int64) representing the DateTime object. The DateTime class has a constructor that accepts this value. Additionally, you specify that the ticks represent a UTC formatted object.

devomage

  • Sr. Member
  • ****
  • Thank You
  • -Given: 7
  • -Receive: 67
  • Posts: 250
    • View Profile
Re: Stand-alone Server DataNode Error
« Reply #2 on: September 30, 2016, 05:07:36 PM »
Try this:
  1. // serializing
  2. resptotarget.AddChild("last_active", DateTime.UtcNow.Ticks);
  3. // deserializing
  4. DateTime last_active = new DateTime(data.GetChild<long>("last_active"), DateTimeKind.Utc);
  5.  

I'm not too familiar with the DataNode class, so perhaps there's a different way of doing this, but this should certainly fix the serialization error. The Ticks property returns a signed long (Int64) representing the DateTime object. The DateTime class has a constructor that accepts this value. Additionally, you specify that the ticks represent a UTC formatted object.

the server is UTC (a valid DateTime) and - ticks is how i used to do DateTime.  no longer should necessary with the addition of DateTime to serialization.  the error is an anomaly and why i posted this.  i have many other DateTime vars (from server to client) that work fine.

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Stand-alone Server DataNode Error
« Reply #3 on: September 30, 2016, 06:21:01 PM »
Well the error seems to be because the serializer thinks it's an unsigned long instead of a signed long. I don't have code so I can't give line numbers, but I'm sure you can make the appropriate fixes (or wait for Aren to weigh in).

Regardless, though, why rely on TNet serialization when the class you're working with has built-in serialization? ;)

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Stand-alone Server DataNode Error
« Reply #4 on: September 30, 2016, 07:42:48 PM »
Yeah not sue why you're getting a ulong there. DateTime.UtcNow.Ticks is a long, not a ulong.

In any case you can make TNet convert ulong to long to DateTime by adding this line in TNSerializer's CastValue function:
  1.                 else if (valueType == typeof(ulong))
  2.                 {
  3.                         if (desiredType == typeof(int)) return (int)(ulong)value;
  4.                         if (desiredType == typeof(long)) return (long)(ulong)value;
  5.                         if (desiredType == typeof(DateTime)) return new DateTime((long)(ulong)value, DateTimeKind.Utc); // <---
  6.                 }

devomage

  • Sr. Member
  • ****
  • Thank You
  • -Given: 7
  • -Receive: 67
  • Posts: 250
    • View Profile
Re: Stand-alone Server DataNode Error
« Reply #5 on: September 30, 2016, 08:05:57 PM »
Regardless, though, why rely on TNet serialization when the class you're working with has built-in serialization? ;)

the response im going with - aethstetics   ???

thanks for the feedback cmifwdll/ArenMook!

devomage

  • Sr. Member
  • ****
  • Thank You
  • -Given: 7
  • -Receive: 67
  • Posts: 250
    • View Profile
Re: Stand-alone Server DataNode Error
« Reply #6 on: November 18, 2016, 12:44:47 AM »
finally tracked this down! 

i'm encrypting/decrypting data sent and received to/from the server.  everything works great while not encrypted.

this line seems to be the culprit:

  1. DataNode data = DataNode.Read(Encoding.ASCII.GetBytes(s));

is there a better way to restore the DataNode - where the DateTime returns to a long rather than a ulong?  the ulong snippet should still fix the problem - but its kinda cheezy...


  1. public static void Request(DataNode data)
  2. {
  3.         BinaryWriter writer = TNManager.client.BeginSend(Packet.WEPP_RequestPacket);
  4.  
  5.         writer.Write(Utilities.Encryption.AESEncryption.Encrypt(data.ToString(), "strongpassword"));
  6.  
  7.         TNManager.client.EndSend();
  8. }
  9.  
  10.  
  11. private static void WEPP_OnCustomPacket(TcpPlayer player, TNet.Buffer buffer, BinaryReader reader, Packet request, bool reliable)
  12. {
  13.      string encryptedstring = reader.ReadString();
  14.      string s = Utilities.Encryption.AESEncryption.Decrypt(encryptedstring, "strongpassword");
  15.      DataNode data = DataNode.Read(Encoding.ASCII.GetBytes(s));
  16. }
  17.  

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Stand-alone Server DataNode Error
« Reply #7 on: November 20, 2016, 11:57:45 AM »
I'm pretty sure I added the ulong part to TNet's pro repository when I made that last post... Reminds me to release this update some time soon.

If you want to send something that others can't read across the network, consider using DataNode's ability to write itself to a binary stream in a compressed format. It's not going to be obvious what is being sent, and it will result in much smaller data to boot.

devomage

  • Sr. Member
  • ****
  • Thank You
  • -Given: 7
  • -Receive: 67
  • Posts: 250
    • View Profile
Re: Stand-alone Server DataNode Error
« Reply #8 on: November 20, 2016, 07:36:33 PM »
i'll be looking for that update thanks!