14

Ok, i've seen many similar questions both on here and unity forums asking about converting from one format to another. I've got a (hopefully) simple question that i just can't find the answer for. I'm using the game-center plugin from Prime31 to handle a turn based multi-player game. Inside the plugin for Prime31 they ask you for a byte[] to send to the other players. (State data) So the question is, what would be a good way to convert a List to a byte array AND then convert them back from byte array?

for reference this is as complicated a class as i need, i might need to add more members later, but not any different types. ALSO the list of int's(cards in hand) could easily be 4 separate int if that makes converting the list of PokerPlayers to an byte[] any easier. Also at this list is not a set length but will always be 4-8.

public class PokerPlayer{   
    public string playerID;
    public string alias;
    public int wildCard;
    public List<int> cardsInHand;
    public int chips;   
}

I feel like the when i see the answer I'm going to smack myself for not seeing the answer sooner. Any pointers/ links to relevant materials would be sweet, i've searched google for a good 3 hours now with similar (SO similar) but not quite the same questions.

Grindz
  • 226
  • 1
  • 3
  • 12
  • Question, do you only need the list put into an array, or the whole PokerPlayer object should be transferred to somewhere else? – flohack Apr 09 '14 at 20:31
  • What i was doing was trying to convert a list of these PokerPlayers into a byte[] to send over the air thru gamecenter. – Grindz Apr 09 '14 at 20:34

3 Answers3

41

You may want to try serialization.

var binFormatter = new BinaryFormatter();
var mStream = new MemoryStream();
binFormatter.Serialize(mStream, myObjToSerialize);

//This gives you the byte array.
mStream.ToArray();

And then if you want to turn the byte array back into an object:

var mStream = new MemoryStream();
var binFormatter = new BinaryFormatter();

// Where 'objectBytes' is your byte array.
mStream.Write (objectBytes, 0, objectBytes.Length);
mStream.Position = 0;

var myObject = binFormatter.Deserialize(mStream) as YourObjectType;

Update:

Microsoft warns about using BinaryFormatter because it is "insecure and can't be made secure".

Please read aka.ms/binaryformatter for more details.

Preferred alternatives

.NET offers several in-box serializers that can handle untrusted data safely:

dbc
  • 104,963
  • 20
  • 228
  • 340
Timeout
  • 7,759
  • 26
  • 38
  • Awesome this was the way to go, i had to google getting the list back from the byte array, but it lead me to the right answer. So much thanks. – Grindz Apr 09 '14 at 20:30
  • Hi its dont work for me, u can help ? IConvertible. in System.Convert.ChangeType – Vdovin Daniil Jan 24 '20 at 13:50
  • Please check out https://aka.ms/binaryformatter. Microsoft's warning about using `BinaryFormatter` "The `BinaryFormatter.Deserialize` method is never safe when used with untrusted input.". – Galacticai Oct 22 '21 at 15:12
9

BinaryFormatter is now a security risk. If I find a good way to do this without using it I'll be back

https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/binaryformatter-serialization-obsolete

Edit: This is still the top result in Google so I'll show what I've done to move away from BinaryFormatter

You need Newtonsoft.Json

public static class ExtendedSerializerExtensions
{
    private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Auto,
    };

    public static byte[] Serialize<T>(this T source)
    {
        var asString = JsonConvert.SerializeObject(source, SerializerSettings);
        return Encoding.Unicode.GetBytes(asString);
    }

    public static T Deserialize<T>(this byte[] source)
    {
        var asString = Encoding.Unicode.GetString(source);
        return JsonConvert.DeserializeObject<T>(asString);
    }
}

It's not very far to go from here if you need a stream rather than a byte array

Carl
  • 1,782
  • 17
  • 24
1

Converting data into byte stream (and back) is called serialization (and deserialization).

You can use the BinaryFormatter class to do so.

nvoigt
  • 75,013
  • 26
  • 93
  • 142