查看: 632|回复: 0
打印 上一主题 下一主题

[其他] 两步实现超实用的XML存档

[复制链接]

9903

主题

126

听众

7万

积分

首席设计师

Rank: 8Rank: 8

纳金币
53456
精华
316

最佳新人 热心会员 灌水之王 活跃会员 突出贡献 荣誉管理 论坛元老

跳转到指定楼层
楼主
发表于 2015-9-29 00:57:07 |只看该作者 |倒序浏览
使用方法非常简单:

  把GameDataManager和XmlSaver两个脚本添加至工程后

  (1)新建一个GameObject,起名GameDataManager并将GameDataManager脚本拖到上面。

  (2)在GameDataManager里的GameData类中添加需要储存的数据

  OK,跨平台防破解防拷贝的存档就搞定了!之后每次存档调用GameDataManager的Save函数,读档调用GameDataManager的Load函数。每次启动后GameDataManager会自动调用Load读档。如果玩家拿外来存档来覆盖本地存档,则游戏启动后数据清零,任何一次存档后作弊档被自动覆盖。注意:请勿放入二维以上数组,一般一维数据,枚举,自定义类 等等数据类型可放心添加。

  【风宇冲】unity3D教程宝典之两步实现超实用的XML存档

  ps:风宇冲自己的U3D单机游戏和公司的单机游戏都用的这个XML存档,iOS,android,PC,MAC都使用过的。放心使用吧。密钥的设定根据平台而定。

 GameDataManager.cs的内容

//=========================================================================================================

//Note: Data Managing.

//Date Created: 2012/04/17 by 风宇冲

//Date Modified: 2012/12/14 by 风宇冲

//=========================================================================================================

using UnityEngine;

using System.Collections;

using System.IO;

using System.Collections.Generic;

using System;

using System.Text;

using System.Xml;

using System.Security.Cryptography;

//GameData,储存数据的类,把需要储存的数据定义在GameData之内就行//

public class GameData

{

//密钥,用于防止拷贝存档//

public string key;

//下面是添加需要储存的内容//

public string PlayerName;

public float MusicVolume;

public GameData()

{

PlayerName = “Player”;

MusicVolume = 0.6f;

}

}

//管理数据储存的类//

public class GameDataManager:MonoBehaviour

{

private string dataFileName =“tankyWarData.dat”;//存档文件的名称,自己定//

private  XmlSaver xs = new XmlSaver();

public  GameData gameData;

public void Awake()

{

gameData = new GameData();

//设定密钥,根据具体平台设定//

gameData.key = SystemInfo.deviceUniqueIdentifier;

Load();

}

//存档时调用的函数//

public  void Save()

{

string gameDataFile = GetDataPath() + “/”+dataFileName;

string dataString= xs.SerializeObject(gameData,typeof(GameData));

xs.CreateXML(gameDataFile,dataString);

}

//读档时调用的函数//

public  void Load()

{

string gameDataFile = GetDataPath() + “/”+dataFileName;

if(xs.hasFile(gameDataFile))

{

string dataString = xs.LoadXML(gameDataFile);

GameData gameDataFromXML = xs.DeserializeObject(dataString,typeof(GameData)) as GameData;

//是合法存档//

if(gameDataFromXML.key == gameData.key)

{

gameData = gameDataFromXML;

}

//是非法拷贝存档//

else

{

//留空:游戏启动后数据清零,存档后作弊档被自动覆盖//

}

}

else

{

if(gameData != null)

Save();

}

}

//获取路径//

private static string GetDataPath()

{

// Your game has read+write access to /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/Documents

// Application.dataPath returns ar/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/myappname.app/Data

// Strip “/Data” from path

if(Application.platform == RuntimePlatform.IPhonePlayer)

{

string path = Application.dataPath.Substring (0, Application.dataPath.Length - 5);

// Strip application name

path = path.Substring(0, path.LastIndexOf('/'));

return path + “/Documents”;

}

else

//    return Application.dataPath + “/Resources”;

return Application.dataPath;

}

}

XmlSaver.cs的内容

//=========================================================================================================

//Note: XML processcing,  can not save multiple-array!!!

//Date Created: 2012/04/17 by 风宇冲

//Date Modified: 2012/04/19 by 风宇冲

//=========================================================================================================

using UnityEngine;

using System.Collections;

using System.Xml;

using System.Xml.Serialization;

using System.IO;

using System.Text;

using System.Security.Cryptography;

using System;

public class XmlSaver

{

//内容加密

public string Encrypt(string toE)

{

//加密和解密采用相同的key,具体自己填,但是必须为32位//

byte[] keyArray = UTF8Encoding.UTF8.GetBytes(“12348578902223367877723456789012”);

RijndaelManaged rDel = new RijndaelManaged();

rDel.Key = keyArray;

rDel.Mode = CipherMode.ECB;

rDel.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = rDel.CreateEncryptor();

byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toE);

byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,0,toEncryptArray.Length);

return Convert.ToBase64String(resultArray,0,resultArray.Length);

}

//内容解密

public string Decrypt(string toD)

{

//加密和解密采用相同的key,具体值自己填,但是必须为32位//

byte[] keyArray = UTF8Encoding.UTF8.GetBytes(“12348578902223367877723456789012”);

RijndaelManaged rDel = new RijndaelManaged();

rDel.Key = keyArray;

rDel.Mode = CipherMode.ECB;

rDel.Padding = PaddingMode.PKCS7;

ICryptoTransform cTransform = rDel.CreateDecryptor();

byte[] toEncryptArray = Convert.FromBase64String(toD);

byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,0,toEncryptArray.Length);

return UTF8Encoding.UTF8.GetString(resultArray);

}

public string SerializeObject(object pObject,System.Type ty)

{

string XmlizedString   = null;

MemoryStream memoryStream  = new MemoryStream();

XmlSerializer xs  = new XmlSerializer(ty);

XmlTextWriter xmlTextWriter  = new XmlTextWriter(memoryStream, Encoding.UTF8);

xs.Serialize(xmlTextWriter, pObject);

memoryStream = (MemoryStream)xmlTextWriter.BaseStream;

XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());

return XmlizedString;

}

public object DeserializeObject(string pXmlizedString , System.Type ty)

{

XmlSerializer xs  = new XmlSerializer(ty);

MemoryStream memoryStream  = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));

XmlTextWriter xmlTextWriter   = new XmlTextWriter(memoryStream, Encoding.UTF8);

return xs.Deserialize(memoryStream);

}

//创建XML文件

public void CreateXML(string fileName,string thisData)

{

string xxx = Encrypt(thisData);

StreamWriter writer;

writer = File.CreateText(fileName);

writer.Write(xxx);

writer.Close();

}

//读取XML文件

public string LoadXML(string fileName)

{

StreamReader sReader = File.OpenText(fileName);

string dataString = sReader.ReadToEnd();

sReader.Close();

string xxx = Decrypt(dataString);

return xxx;

}

//判断是否存在文件

public bool hasFile(String fileName)

{

return File.Exists(fileName);

}

public string UTF8ByteArrayToString(byte[] characters  )

{

UTF8Encoding encoding  = new UTF8Encoding();

string constructedString  = encoding.GetString(characters);

return (constructedString);

}

public byte[] StringToUTF8ByteArray(String pXmlString )

{

UTF8Encoding encoding  = new UTF8Encoding();

byte[] byteArray  = encoding.GetBytes(pXmlString);

return byteArray;

}

}

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

关闭

站长推荐上一条 /1 下一条

手机版|纳金网 ( 闽ICP备08008928号

GMT+8, 2024-5-6 13:48 , Processed in 0.086871 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部