Author Topic: Send list  (Read 6356 times)

GamerLE

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 4
    • View Profile
Send list
« on: March 01, 2014, 05:47:23 AM »
 Hello guys,
I've a problem when I create a list and I want to send it from host to client.
When client enter in channel, I do that host sends me its list Player.
But when there is excecution:


  1. tno.Send("ReceiveUpdate", TNet.Target.Others, id_require, players);
  2.  

I've this error:
  1. Unable to write type System.Collections.Generic.List`1[TNet.Player]
  2.  
  3. UnityEngine.Debug:LogError(Object)
  4. TNet.UnityTools:Write(BinaryWriter, Object[]) (at Assets/Library/TNet/Client/TNUnityTools.cs:282)
  5.  
  6. TNObject:SendRFC(Byte, String, Target, Boolean, Object[]) (at Assets/Library/TNet/Client/TNObject.cs:565)
  7.  
  8. TNObject:Send(String, Target, Object[]) (at Assets/Library/TNet/Client/TNObject.cs:435)
  9.  


Complete Code:
  1. using UnityEngine;
  2. using System.Collections;
  3. using TNet;
  4.  
  5. public class RoomPlayers : TNBehaviour {
  6.  
  7.         //
  8.         public System.Collections.Generic.List<Player> players;
  9.  
  10.         // Use this for initialization
  11.         void Start()
  12.         {
  13.                 //
  14.                 istance = this;
  15.  
  16.                 //
  17.                 players = new System.Collections.Generic.List<Player>();
  18.  
  19.                 //
  20.                 foreach(Player p in TNManager.players)
  21.                 {
  22.                         players.Add(p);
  23.                 }
  24.  
  25.                 players.Add(TNManager.player);
  26.  
  27.                 //
  28.                 if(!TNManager.isHosting)
  29.                         RequestUpdateToHost();
  30.         }
  31.         // [CLIENT] Request
  32.         void RequestUpdateToHost()
  33.         {
  34.                 tno.Send ("SendUpdateToPlayer", TNet.Target.Host, TNManager.player.id);
  35.         }
  36.         // [HOST]
  37.         [RFC]
  38.         void SendUpdateToPlayer(int id_require)
  39.         {
  40.                 tno.Send("ReceiveUpdate", TNet.Target.Others, id_require, players);
  41.         }
  42.         // [CLIENT]
  43.         [RFC]
  44.         void ReceiveUpdate(int id_require, System.Collections.Generic.List<Player> players_received)
  45.         {
  46.                 //
  47.                 if (id_require != TNManager.player.id)
  48.                         return;
  49.                 //
  50.                 Player player;
  51.                 foreach (Player player_i in players_received)
  52.                 {
  53.                         player = GetPlayer (player_i.id);
  54.                         player.data = player_i.data;
  55.                 }
  56.  
  57.                 Debug.Log("Completed");
  58.         }
  59. }
« Last Edit: March 01, 2014, 05:52:55 AM by GamerLE »

danfoo

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 2
  • Posts: 93
    • View Profile
Re: Send list
« Reply #1 on: March 01, 2014, 06:49:41 AM »
I am quite sure TNet will not serialize lists or player objects. What you likely want to do is to send an array of playerIDs to the joining player.
However, I am not sure that that is even needed as I would think that TNManager.players will be kept in sync automatically and you can simply use that after successfully joining. Not 100% sure though as I am still in the coding stage myself - have not run any of the net code yet. :)

GamerLE

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: Send list
« Reply #2 on: March 01, 2014, 08:39:51 AM »
The list that I send is not exactly the one that is present in TNManager.players.
I also need to pass other lists, and it is for this reason that I'm trying to pass them with TNET.

danfoo

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 2
  • Posts: 93
    • View Profile
Re: Send list
« Reply #3 on: March 01, 2014, 10:40:42 AM »
The list that I send is not exactly the one that is present in TNManager.players.
I also need to pass other lists, and it is for this reason that I'm trying to pass them with TNET.

And I explained that TNet will not serialize lists as far as I can tell. You need to send your information as an array of a type that is serializable. From TNUnityTools and the CanBeSerialized function:
  1. if (type == typeof(bool)) return true;
  2.                 if (type == typeof(byte)) return true;
  3.                 if (type == typeof(ushort)) return true;
  4.                 if (type == typeof(int)) return true;
  5.                 if (type == typeof(uint)) return true;
  6.                 if (type == typeof(float)) return true;
  7.                 if (type == typeof(string)) return true;
  8.                 if (type == typeof(Vector2)) return true;
  9.                 if (type == typeof(Vector3)) return true;
  10.                 if (type == typeof(Vector4)) return true;
  11.                 if (type == typeof(Quaternion)) return true;
  12.                 if (type == typeof(Color32)) return true;
  13.                 if (type == typeof(Color)) return true;
  14.                 if (type == typeof(DateTime)) return true;
  15.                 if (type == typeof(IPEndPoint)) return true;
  16.                 if (type == typeof(bool[])) return true;
  17.                 if (type == typeof(byte[])) return true;
  18.                 if (type == typeof(ushort[])) return true;
  19.                 if (type == typeof(int[])) return true;
  20.                 if (type == typeof(uint[])) return true;
  21.                 if (type == typeof(float[])) return true;
  22.                 if (type == typeof(string[])) return true;

So you have to repackage whatever info you need to send into one of the types above. If you want to send a list of players on a team or in a group, your best choice would be int[] of the player ids.

GamerLE

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: Send list
« Reply #4 on: March 01, 2014, 11:50:03 AM »
I don't understand how can I do

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Send list
« Reply #5 on: March 01, 2014, 09:19:22 PM »
You can't serialize a list of custom classes like that. You can only serialize arrays of simple types as danfoo mentioned in his post.

So if your player class contains data like an integer for team ID, string for a player title, and a float for his health, you would have to send 3 separate arrays -- and I mean arrays, as in int[], not List<int>.

GamerLE

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: Send list
« Reply #6 on: March 04, 2014, 06:56:01 AM »
Thank you for your reply. I've resolved.
Is it possible to send RFC to a specific player?
Actually I send everybody RFC and then client with a "IF" establishes if it is in adressee and it does RFC, even if it isn't it will reject. But in this case there will be waste of bandwith

danfoo

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 2
  • Posts: 93
    • View Profile
Re: Send list
« Reply #7 on: March 04, 2014, 08:19:18 AM »
Sure. TNObject.Send will take a TNet.Player as an argument. You can use TNManager.GetPlayer to get the player object for a player with a certain id.
So, let's say you get an RFC where a remote player passes his player id. You can then send stuff back to him by using the passed id to get his player object and then use that.