• 【转】两步实现超实用的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. }
  • 相关阅读:
    [已解决]报错:Failed to restart network.service: Unit network.service not found
    [已解决]PostgreSQL报错:cannot begin/end transactions in PL/pgSQL解决方法
    Navicat连接Hive
    [已解决]报错:The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
    [已解决]报错:Unknown system variable 'query_cache_size'
    [已解决]报错: Unable to load authentication plugin 'caching_sha2_password'.
    python小练习
    Oracle消除重复记录的几种方式
    Android支持ARM架构软件包安装Genymotion-ARM-Translation_for_8.0
    Centos7上安装DBDIFF
  • 原文地址:https://www.cnblogs.com/sbCat/p/4706181.html
Copyright © 2020-2023  润新知