问题 游戏序列化

攻壳机动队

新成员
已加入
2020年11月21日
留言内容
2
编程经验
1-3
你好。
我想序列化游戏中的数据以保存到磁盘并通过网络发送,还需要支持旧版本(如果添加了不在序列化中的新属性,请设置默认值)。通过BinaryFormatter发送数据并不安全。 xml很重,json如何不支持引用类型(如果对一个对象有多个引用,那么在反序列化之后它将是不同的对象)
我不想为每个对象编写序列化和反序列化方法,因为它很难支持。使用System.Reflection获取元数据不能保证相同的顺序。向所有属性添加属性似乎也是错误的。如何解决呢?
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
我想序列化游戏中的数据以保存到磁盘并通过网络发送,还需要支持旧版本(如果添加了不在序列化中的新属性,请设置默认值)。
要求任何人阅读,看看他们是否理解您的描述。因为我不知道

您进入句子中间,开始说话,就像我们已经知道您在做什么一样。

我不想为每个对象编写序列化和反序列化方法,因为它很难支持。使用System.Reflection获取元数据不能保证相同的顺序。向所有属性添加属性似乎也是错误的。如何解决呢?
Ehh jee Bob,也许向我们展示一些您正在使用的代码,并以更加详尽和精确的细节来说明您所遇到的问题,而在您处理该问题时,请说明您所拥有的代码以及您将面临的挑衅性问题序列化和反序列化比较困难。

根据我的理论,此时您已经编写了一些丑陋的类,并且很可能违反了SRP规则,因此使自己对序列对象进行序列化和反序列化变得很复杂。
 

攻壳机动队

新成员
已加入
2020年11月21日
留言内容
2
编程经验
1-3
C#:
void Serialize(BinaryWriter writer)
{
    writer.Write(property1);
    writer.Write(property2);
    writer.Write(property3);
    writer.Write(refProperty.Id);
}

void Deserialize(BinaryReader reader)
{
    property1 = reader.ReadInt32();
    property2 = reader.ReadShort();
    property3 = reader.ReadBool();
    refProperty = GetObjectById(reader.ReadInt32());
}

根据我的理论,此时您已经编写了一些丑陋的类,并且很可能违反了SRP规则,因此使自己对序列对象进行序列化和反序列化变得很复杂。
是的。它违反了SRP,因此是不这样写的另外一个原因。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,530
地点
弗吉尼亚州切萨皮克
编程经验
10+
通过BinaryFormatter发送数据并不安全。
您能解释一下二进制格式化程序存在哪些安全问题吗?您是在谈论对象的典型Java(和C#)盲实例化吗?"untrusted"来源?如果是这样,则必须确保它是受信任的源:端到端保护流;添加某种信封,以帮助您验证流中的数据是否未被篡改;对可以从流中序列化和反序列化哪些对象进行一些基本的白名单;等等。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
那并没有给我们太多有关你的困境的信息。一切都归结于构造良好的结构良好的类来满足您的目的和满足您的需求。不要使事情复杂化。您在上面的代码中的哪个位置验证数据以确保数据未被篡改?您的客户端如何与服务器/其他数据流通信,这是什么意思?由于跳伞运动员会提出信封建议,因此您可以将信封视为对数据进行加密。最后,如果您希望数据"untampered"-考虑改用防篡改库,因为没有必要重新发明轮子。另外,您在这里是什么意思,特别是括号中的部分:
xml很重,json如何不支持引用类型(如果对一个对象有多个引用,那么在反序列化之后它将是不同的对象)
对象有什么不同?对象是最初定义的对象。每个实例可能具有不同的值,但是它们都具有与它们相同的结构。听起来您似乎想完成的工作都过于复杂。
 
最佳 底部