【发布时间】:2018-12-23 04:48:13
【问题描述】:
我在 Unity 中编写了一个实际的游戏,并且我想使用此代码保护 GameData。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System;
using System.Text;
using System.Security.Cryptography;
using System.Linq;
public class Data : MonoBehaviour {
static readonly string PasswordHash = "P@@Sw0rd";
static readonly string SaltKey = "S@LT&KEY";
static readonly string VIKey = "@1B2c3D4e5F6g7H8";
public GameObject dirtBlock;
public void Save(){
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/playerData.dat",FileMode.Open);
PlayerData data = new PlayerData();
data.dirtCount = dirtBlock.GetComponent<BlockHandler>().blockCount;
data.stoneCount = 0;
data.ironCount = 0;
bf.Serialize(file,Encrypt(ToByteArray(data)));
file.Close();
}
public void Load(){
if(File.Exists(Application.persistentDataPath + "/playerData.dat")){
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/playerData.dat",FileMode.Open);
PlayerData data = FromByteArray<PlayerData>(Decrypt(bf.Deserialize(file).ToString()));
file.Close();
dirtBlock.GetComponent<BlockHandler>().blockCount = data.dirtCount;
} else {
FileStream file = File.Create(Application.persistentDataPath + "/playerData.dat");
file.Close();
this.Save();
this.Load();
}
}
public static string Encrypt(byte[] plainTextBytes){
byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
var encryptor = symmetricKey.CreateEncryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
byte[] cipherTextBytes;
using (var memoryStream = new MemoryStream()){
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)){
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
cipherTextBytes = memoryStream.ToArray();
cryptoStream.Close();
}
memoryStream.Close();
}
return Convert.ToBase64String(cipherTextBytes);
}
public static byte[] Decrypt(string encryptedText){
byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash, Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };
var decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(VIKey));
var memoryStream = new MemoryStream(cipherTextBytes);
var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
byte[] plainTextBytes = new byte[cipherTextBytes.Length];
memoryStream.Close();
cryptoStream.Close();
return plainTextBytes;
}
public byte[] ToByteArray<T>(T obj){
if(obj == null){
return null;
}
BinaryFormatter bf = new BinaryFormatter();
using(MemoryStream ms = new MemoryStream()){
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
public T FromByteArray<T>(byte[] data){
if(data == null){
return default(T);
}
BinaryFormatter bf = new BinaryFormatter();
using(MemoryStream ms = new MemoryStream(data)){
object obj = bf.Deserialize(ms);
return (T)obj;
}
}
}
[System.Serializable]
public class PlayerData {
public float dirtCount;
public float stoneCount;
public float ironCount;
}
昨天还好好的,今天不知道为什么,我收到了这个错误信息
SerializationException:意外的二进制元素:0 System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject(BinaryElement 元素,System.IO.BinaryReader 阅读器,System.Int64& objectId,System.Object& 值,System.Runtime.Serialization.SerializationInfo& 信息)(在 /Users/builduser/ buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:254) System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject(BinaryElement 元素,System.IO.BinaryReader 阅读器)(位于 /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters .Binary/ObjectReader.cs:130) System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph (BinaryElement elem, System.IO.BinaryReader reader, Boolean readHeaders, System.Object& result, System.Runtime.Remoting.Messaging.Header[]& headers) (在 /Users /builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectReader.cs:104) System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize(System.IO.Stream serializationStream,System.Runtime.Remoting.Messaging.HeaderHandler 处理程序)(在 /Users/builduser/buildslave/mono/build/mcs/class/corlib /System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:179) System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (在/Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ BinaryFormatter.cs:136) Data.FromByteArray[PlayerData] (System.Byte[] 数据) (在 Assets/Scripts/Player/Data.cs:119) Data.Load()(在 Assets/Scripts/Player/Data.cs:40)
我在网上搜索了 4 个小时,但我找不到解决此问题的方法。我希望任何人都可以帮助我。
【问题讨论】:
-
这个确切的加载代码昨天工作了吗?
-
是的,这段代码昨天工作了
-
您是编写序列化/反序列化和加密代码还是从一些教程中获得的?如果您从教程中获得它,请链接到该教程,因为这可能有助于解决问题。
-
我将它用于加密“social.msdn.microsoft.com/Forums/vstudio/en-US/…”并将其用于游戏对象保存 (44:40):unity3d.com/de/learn/tutorials/topics/scripting/…