Unity3D教程宝典之两步实现超实用的XML存档

原创文章如需转载请注明:转载自风宇冲Unity3D教程学院


                   两步实现超实用的XML存档

本套存档的优点:易使用,跨平台,防作弊(内容加密 + 防拷贝)

脚本下载地址

使用方法非常简单:
把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的内容
  1. //=========================================================================================================
  2. //Note: Data Managing.
  3. //Date Created: 2012/04/17 by 风宇冲
  4. //Date Modified: 2012/12/14 by 风宇冲
  5. //=========================================================================================================
  6. using UnityEngine;
  7. using System.Collections;
  8. using System.IO;
  9. using System.Collections.Generic;
  10. using System;
  11. using System.Text;
  12. using System.Xml;
  13. using System.Security.Cryptography;
  14. //GameData,储存数据的类,把需要储存的数据定义在GameData之内就行//
  15. public class GameData
  16. {
  17.     //密钥,用于防止拷贝存档//
  18.     public string key;
  19.    
  20.     //下面是添加需要储存的内容//
  21.     public string PlayerName;
  22.     public float MusicVolume;
  23.     public GameData()
  24.     {
  25.         PlayerName = "Player";
  26.         MusicVolume = 0.6f;
  27.     }
  28. }
  29. //管理数据储存的类//
  30. public class GameDataManager:MonoBehaviour
  31. {
  32.     private string dataFileName ="tankyWarData.dat";//存档文件的名称,自己定//
  33.     private  XmlSaver xs = new XmlSaver();
  34.    
  35.     public  GameData gameData;
  36.    
  37.     public void Awake()
  38.     {
  39.         gameData = new GameData();
  40.        
  41.         //设定密钥,根据具体平台设定//
  42.         gameData.key = SystemInfo.deviceUniqueIdentifier;
  43.         Load();
  44.     }
  45.    
  46.     //存档时调用的函数//
  47.     public  void Save()
  48.     {
  49.         string gameDataFile = GetDataPath() + "/"+dataFileName;
  50.         string dataString= xs.SerializeObject(gameData,typeof(GameData));
  51.         xs.CreateXML(gameDataFile,dataString);
  52.     }
  53.    
  54.     //读档时调用的函数//
  55.     public  void Load()
  56.     {
  57.         string gameDataFile = GetDataPath() + "/"+dataFileName;
  58.         if(xs.hasFile(gameDataFile))
  59.         {
  60.            string dataString = xs.LoadXML(gameDataFile);
  61.            GameData gameDataFromXML = xs.DeserializeObject(dataString,typeof(GameData)) as GameData;
  62.            
  63.             //是合法存档//
  64.              if(gameDataFromXML.key == gameData.key)
  65.             {
  66.                 gameData = gameDataFromXML;
  67.             }
  68.             //是非法拷贝存档//
  69.             else
  70.             {
  71.                 //留空:游戏启动后数据清零,存档后作弊档被自动覆盖//
  72.             }
  73.         }
  74.         else
  75.         {
  76.             if(gameData != null)
  77.             Save();
  78.         }
  79.     }
  80.    
  81.     //获取路径//
  82.     private static string GetDataPath()
  83.     {
  84.         // Your game has read+write access to /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/Documents
  85.         // Application.dataPath returns ar/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/myappname.app/Data             
  86.         // Strip "/Data" from path
  87.         if(Application.platform == RuntimePlatform.IPhonePlayer)
  88.         {
  89.             string path = Application.dataPath.Substring (0, Application.dataPath.Length - 5);
  90.             // Strip application name
  91.             path = path.Substring(0, path.LastIndexOf('/')); 
  92.             return path + "/Documents";
  93.         }
  94.         else
  95.         //    return Application.dataPath + "/Resources";
  96.             return Application.dataPath;
  97.     }
  98. }



                                                                                  XmlSaver.cs的内容
  1. //=========================================================================================================
  2. //Note: XML processcing,  can not save multiple-array!!!
  3. //Date Created: 2012/04/17 by 风宇冲
  4. //Date Modified: 2012/04/19 by 风宇冲
  5. //=========================================================================================================
  6. using UnityEngine;
  7. using System.Collections;
  8. using System.Xml;
  9. using System.Xml.Serialization;
  10. using System.IO;
  11. using System.Text;
  12. using System.Security.Cryptography;
  13. using System;
  14. public class XmlSaver
  15.   
  16.     //内容加密
  17.     public string Encrypt(string toE)
  18.     {
  19.         //加密和解密采用相同的key,具体自己填,但是必须为32位//
  20.         byte[] keyArray = UTF8Encoding.UTF8.GetBytes("12348578902223367877723456789012");
  21.         RijndaelManaged rDel = new RijndaelManaged();
  22.         rDel.Key = keyArray;
  23.         rDel.Mode = CipherMode.ECB;
  24.         rDel.Padding = PaddingMode.PKCS7;
  25.         ICryptoTransform cTransform = rDel.CreateEncryptor();
  26.        
  27.         byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toE);
  28.         byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,0,toEncryptArray.Length);
  29.    
  30.         return Convert.ToBase64String(resultArray,0,resultArray.Length);
  31.     }
  32.    
  33.     //内容解密
  34.     public string Decrypt(string toD)
  35.     {
  36.         //加密和解密采用相同的key,具体值自己填,但是必须为32位//
  37.         byte[] keyArray = UTF8Encoding.UTF8.GetBytes("12348578902223367877723456789012");
  38.        
  39.         RijndaelManaged rDel = new RijndaelManaged();
  40.         rDel.Key = keyArray;
  41.         rDel.Mode = CipherMode.ECB;
  42.         rDel.Padding = PaddingMode.PKCS7;
  43.         ICryptoTransform cTransform = rDel.CreateDecryptor();
  44.        
  45.         byte[] toEncryptArray = Convert.FromBase64String(toD);
  46.         byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,0,toEncryptArray.Length);
  47.        
  48.         return UTF8Encoding.UTF8.GetString(resultArray);
  49.     }
  50.    
  51.     public string SerializeObject(object pObject,System.Type ty)
  52.     {
  53.        string XmlizedString   = null;
  54.        MemoryStream memoryStream  = new MemoryStream();
  55.        XmlSerializer xs  = new XmlSerializer(ty);
  56.        XmlTextWriter xmlTextWriter  = new XmlTextWriter(memoryStream, Encoding.UTF8);
  57.        xs.Serialize(xmlTextWriter, pObject);
  58.        memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
  59.        XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
  60.        return XmlizedString;
  61.     }
  62.    
  63.     public object DeserializeObject(string pXmlizedString , System.Type ty)
  64.     {
  65.        XmlSerializer xs  = new XmlSerializer(ty);
  66.        MemoryStream memoryStream  = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));
  67.        XmlTextWriter xmlTextWriter   = new XmlTextWriter(memoryStream, Encoding.UTF8);
  68.        return xs.Deserialize(memoryStream);
  69.     }
  70.    
  71.     //创建XML文件
  72.     public void CreateXML(string fileName,string thisData)
  73.     {
  74.        string xxx = Encrypt(thisData);
  75.        StreamWriter writer;
  76.        writer = File.CreateText(fileName);
  77.        writer.Write(xxx);
  78.        writer.Close();
  79.     }
  80.    
  81.     //读取XML文件
  82.     public string LoadXML(string fileName)
  83.     {
  84.        StreamReader sReader = File.OpenText(fileName);
  85.        string dataString = sReader.ReadToEnd();
  86.        sReader.Close();
  87.        string xxx = Decrypt(dataString);
  88.        return xxx;
  89.     }
  90.    
  91.     //判断是否存在文件
  92.     public bool hasFile(String fileName)
  93.     {
  94.        return File.Exists(fileName);
  95.     }
  96.     public string UTF8ByteArrayToString(byte[] characters  )
  97.     {    
  98.        UTF8Encoding encoding  = new UTF8Encoding();
  99.        string constructedString  = encoding.GetString(characters);
  100.        return (constructedString);
  101.     }
  102.    
  103.     public byte[] StringToUTF8ByteArray(String pXmlString )
  104.     {
  105.        UTF8Encoding encoding  = new UTF8Encoding();
  106.        byte[] byteArray  = encoding.GetBytes(pXmlString);
  107.        return byteArray;
  108.     }
  109. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
xml加密(XML Encryption)是w3c加密xml的标准。这个加密过程包括加密xml文档的元素及其子元素,通过加密,xml的初始内容将被替换,但其xml格式仍然被完好的保留。 介绍 我们有3个加密xml的方法 1、仅仅使用对称加密的方法加密xml 这种加密方法只使用一个密钥,也就是说无论是加密xml还是解密xml都使用一个相同的密钥。因为这个密钥不会在被加密的xml中保存,所以我们需要在加密和解密的过程中加载这个密钥并保护它不被窃取。 2、使用对称加密和非对称加密相结合的方法来加密xml 这种方法需要一个用于加密数据的对称密钥和一个用于保护这个对称密钥的非对称密钥。被加密的对称密钥和被加密的数据一起保存在xml文档中。当用私有非对称密钥解密密钥的时候要用公开非对称密钥对密钥进行加密。 本文就将使用这种方法。想学到其他更多的方法请参看MSDN等到更多的信息。 (译者注:非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。) 3、使用X.509加密xml,这种方法是用X.509作为非对称密钥,它由诸如VeriSign之类的第三方提供。 方法 不管xml加密是如何完成的,保存加密数据总是用两种方法之一。 1、加密后所有的元素都被命名为 2、加密后只有数据被替换,而元素名称仍然是可读的,不会发生变化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值