2015-06-19 4 views
1

Я начал создавать игру Unity как проект Visual Studio. Я создал побочный проект (WinForms) для тестирования, поскольку я не знаю модульного тестирования. Там весь мой код работает отлично, класс сериализации работает безупречно, даже когда используемая протобуф-сеть DLL является единственной для Unity. Теперь, когда я начал работать в Unity, я скопировал все свои коды и DLL для protobuf-net и MySQL.Data. По какой-то причине я не могу заставить (в принципе) использовать тот же код. Я всегда получаю исключение при десериализацией, в основном это:не удалось де-сериализовать данные

Недопустимое поле в источнике данных: 0

И это

Неожиданный конец группы в исходных данных; это обычно означает, что источник данных поврежден

Это трассировки стека для последнего исключения:

ProtoBuf.ProtoException: Неожиданный конец группы в исходных данных; это обычно означает, что источник данные повреждены на ProtoBuf.ProtoReader.ReadFieldHeader() при (оберточной динамической-методе) NeohumanSoftware.AoN.UserInformation.User.proto_2 (объект, ProtoBuf.ProtoReader) в ProtoBuf.Serializers.CompiledSerializer.ProtoBuf .Serializers.IProtoSerializer.Read (объект, ProtoBuf.ProtoReader) at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (int, object, ProtoBuf.ProtoReader) at ProtoBuf.Meta.TypeModel.DeserializeCore (ProtoBuf.ProtoReader, System.Type, object , bool) at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream, object, System.Type, ProtoBuf.SerializationContext) at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream, object, System.Type) на ProtoBuf.Serializer.Deserialize (System.IO.Stream) < 0x000ae> в NeohumanSoftware.AoN.Storage.SerializationHandler.DeSerialize (строка) < 0x00140> в NeohumanSoftware.AoN.Storage.DataHandler.DeserializeUser (строка)

Я опустил последнюю часть трассировки стека как это не имеет значения. Я не понимаю, почему он работает в Visual Studio, но не в Unity. Это сериализатор:

using (MemoryStream ms = new MemoryStream()) 
{ 
    Serializer.Serialize(ms, ToSerialize); 
    return ms.ToArray(); 
} 

И это де-сериализатор:

using (MemoryStream ms = new MemoryStream(ToDeSerialize)) 
{ 
    return Serializer.Deserialize<T>(ms); 
} 

И это объект для сериализации, который является «сердцем» игр, как все идет от User.user :

[ProtoContract] 
internal class User 
{ 
    internal static User user { get; set; } 

    [ProtoMember(1)] 
    internal Something uSomething { get; private set; } 
    [ProtoMember(2)] 
    internal bool uSomething2 { get; set; } 
    [ProtoMember(3)] 
    internal Something3 uSomething3 { get; set; } 
    [ProtoMember(4)] 
    internal Something4 uSomething4 { get; private set; } 
    [ProtoMember(5)] 
    internal Something5 uSomething5 { get; private set; } 

Все эти пользовательские классы имеют [ProtoContract] атрибут вместе с, по меньшей мере, один [ProtoMember], и я не использую любой другой атрибут, кроме этих 2. это поток игры:

  1. Данные создаются.
  2. Данные сериализованы.
  3. Сериализованные данные передаются для шифрования (RijndaelManaged).
  4. Зашифрованные и сериализованные данные записываются в файл.
  5. Окончание игр
  6. Данные загружаются из файла.
  7. Данные не зашифрованы с использованием тех же ключей и IV (случайно сгенерированных и сохраненных)
  8. Данные де-сериализованы.
  9. Игра начинается

EDIT: Попытка использовать проект Visual Studio для десериализации данных Юнити делает НЕ работы. Попытка использовать Unity для де-сериализации данных Visual Studio делает NOT работы. Похоже, что Unity не нравится Protobuf-сеть на всех ...

EDIT2: Я изменил метод сериализатора на:

byte[] b; 
using (MemoryStream ms = new MemoryStream()) 
{ 
    Serializer.Serialize(ms, toXML); 
    b = new byte[ms.Position]; 
    var fullB = ms.GetBuffer(); 
    Array.Copy(fullB, b, b.Length); 
} 

И это то, что я получил:

Protobuf .ProtoException: недопустимый тип проводки; это обычно означает, что вы переписан файл без усечения или установки длины; см Using Protobuf-net, I suddenly got an exception about an unknown wire-type на ProtoBuf.ProtoReader.SkipField() при (оберточной динамической-методе) NeohumanSoftware.AoN.UserInformation.User.proto_2 (объект, ProtoBuf.ProtoReader) в ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read (объект, ProtoBuf.ProtoReader) в ProtoBuf.Meta.RuntimeTypeModel.Deserialize (INT, объект, ProtoBuf.ProtoReader) в ProtoBuf.Meta.TypeModel.DeserializeCore (ProtoBuf.ProtoReader, System.Type, объект, BOOL) в Protobuf .TypeModel.Deserialize (System.IO.Stream, object, System.Type, ProtoBuf.SerializationContext) на ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream, object, System.Type) на ProtoBuf.Serializer .Deserialize (System.IO.Stream) < 0x000ae>

Если это помогает, это чтение и запись в файл методы:

internal static void SaveUser(string userSerialized) 
{ 
    File.WriteAllText(SomePath, userSerialized); 
} 

internal static void LoadUser(string userSerialized) 
{ 
    File.ReadAllText(SomePath); 
} 

EDIT 3: В проекте Unity, я имел это, что у меня не было в проекте Visual Studio,:

internal static Coordinates FromVector3(Vector3 vector) 
{ 
    return new Coordinates(vector.x, vector.y, vector.z); 
} 
internal static Vector3 ToVector3(Coordinates c) 
{ 
    return new Vector3(c.X, c.Y, c.Z); 
} 

Они находятся в классе Координаты, который имеет [ProtoContract] и [ProtoMember] для X, Y и Z. Комментирование этих двух методов не позволяет мне получать исключения, но сериализация все еще не работает (Пользователь свойства являются «новыми»)

+0

Вы уверены, что не используете 'GetBuffer()' где-нибудь? Ведущей причиной «Недопустимое поле в исходных данных: 0» является 'GetBuffer()' (обратите внимание: в 'GetBuffer()' ничего не происходит неправильно, если вы помните только о первых байтах 'Length') –

+0

@MarcGravell да, я абсолютно уверен, что не использую GetBuffer(). Я использовал его, но изменил его на ToArray(), когда я впервые получил эту проблему несколько недель назад. –

ответ

0

решаемыми

Дав всякую надежду на Protobuf-сети я переключился на DataCotractSerializer, который как-то работал на Unity. У меня все еще много проблем, поэтому я решил отключить шифрование и прочитать XML с помощью Visual Studio; Файл был в порядке. У меня все еще было много проблем с моими 3 обработчиками событий (2 были подключены к началу игры, а другой каждый раз, когда был создан специальный объект), поэтому мне пришлось удалить обработчики событий и выполнить операции вручную (какая боль в a $$). После всего этого мне удалось добавить Protobuf-net назад, и все работает так, как должно (обратите внимание, что protobuf-net дает мне 89-байтовый файл с DCS '3.5 KB файл)

Таким образом, окончательное решение этой чрезвычайно странный вопрос был:

  1. Отключение полнофункциональную RijndaelManaged реализации
  2. Отключить все обработчики событий

Если кто-то может мне помочь понять, почему RijdnaelManaged работал над Visual Studio, но не Unity, пожалуйста, оставьте комментарий.

Смежные вопросы