两步实现超实用的XML存档

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

脚本下载地址

使用方法非常简单:
把GameDataManager和XmlSaver两个脚本添加至工程后
(1)新建一个GameObject,起名GameDataManager并将GameDataManager脚本拖到上面。
(2)在GameDataManager里的GameData类中添加需要储存的数据
OK,跨平台防破解防拷贝的存档就搞定了!之后每次存档调用GameDataManager的Save函数,读档调用GameDataManager的Load函数。每次启动后GameDataManager会自动调用Load读档。如果玩家拿外来存档来覆盖本地存档,则游戏启动后数据清零,任何一次存档后作弊档被自动覆盖。注意:请勿放入二维以上数组,一般一维数据,枚举,自定义类等等数据类型可放心添加。

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 (, Application.dataPath.Length - );
// Strip application name
path = path.Substring(, 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("");
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,,toEncryptArray.Length); return Convert.ToBase64String(resultArray,,resultArray.Length);
} //内容解密
public string Decrypt(string toD)
{
//加密和解密采用相同的key,具体值自己填,但是必须为32位//
byte[] keyArray = UTF8Encoding.UTF8.GetBytes(""); 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,,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;
}
}

转载:http://blog.sina.com.cn/s/blog_471132920101d3kh.html

U3D教程宝典之两步实现超实用的XML存档的更多相关文章

  1. IntelliJ IDEA热部署教程,只要两步!

    一.开启idea自动build功能1.File -> Settings -> Build,Execution,Deployment -> Compiler -> Build p ...

  2. Google 推出全新的两步验证机制

    近日 Google 在官方的 Apps Updates 博客公布了全新的两步验证功能--Google 提示,新的功能通过与 Google App 联动,进一步将验证确认工作缩减到仅有两步,同时支持 A ...

  3. 两步验证杀手锏:Java 接入 Google 身份验证器实战

    两步验证 大家应该对两步验证都熟悉吧?如苹果有自带的两步验证策略,防止用户账号密码被盗而锁定手机进行敲诈,这种例子屡见不鲜,所以苹果都建议大家开启两步验证的. Google 的身份验证器一般也是用于登 ...

  4. Ubuntu18.04两步纯小白傻瓜无脑式安装Caffe

    前言 Ubuntu16安装caffe过于繁琐,然而Ubuntu18安装起来却仅仅两步而已 附上官方安装教程:http://caffe.berkeleyvision.org/install_apt.ht ...

  5. 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法

    转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...

  6. 每次Xcode 升级之后 插件失效,两步解决

    以下内容来源:http://www.cocoachina.com/bbs/read.php?tid=296269 每次Xcode 升级之后 插件失效,两步解决 1.打开终端,输入以下代码获取到DVTP ...

  7. 两步验证Authy时间同步问题

    Authy是我常用的软件之一,通常用于Google的两步验证,或者是其他基于Google两步验证的原理的衍生程序.比如Namesilo.印象笔记等均有使用. 先说说什么是两步验证. 两步验证 两步验证 ...

  8. Github两步认证

    获取密钥:ssh-keygen -t rsa  切换到公钥所在路径:cd .ssh 查看该路径下的所有文件:ls 查看公钥:cat id_rsa.pub 获取密钥之后,去https://github. ...

  9. 只需两步!Eclipse+Maven快速构建第一个Spring Boot项目

     随着使用Spring进行开发的个人和企业越来越多,Spring从一个单一简介的框架变成了一个大而全的开源软件,最直观的变化就是Spring需要引入的配置也越来越多.配置繁琐,容易出错,让人无比头疼, ...

随机推荐

  1. backup & restore On Ubuntu

    详见:https://help.ubuntu.com/community/BackupYourSystem/TAR 在 使用Ubuntu之前,相信很多人都有过使用Windows系统的经历.如果你备份过 ...

  2. 2、TestNG+Maven+IDEA环境搭建

    前言: 主要进行TestNG测试环境的搭建 所需环境: 1.IDEA UItimate 2.JDK 3.Maven 一.创建工程 File –>new –>Project–>next ...

  3. python 读写二进制文件实例

    本程序,首先写入一个矩阵到二进制文件中,然后读取二进制文件恢复到另外一个矩阵中. #coding:utf--8 #https://www.cnblogs.com/cmnz/p/6986979.html ...

  4. 数据规整化:pandas 求合并数据集(交集并集等)

    数据集的合并或连接运算是通过一个或多个键将行链接起来的.这些运算是关系型数据库的核心.pandas的merge函数是对数据应用这些算法的这样切入点. 默认是交集, inner连接 列名不同可以分别指定 ...

  5. (笔记)Linux下查看CPU使用率的命令

    1.top 使用权限:所有使用者 使用方式:top [-] [d delay] [q] [c] [S] [s] [i] [n] [b] 说明:即时显示process的动态 d :改变显示的更新速度,或 ...

  6. Android WiFi 日志记录(ASSOC_REJECT)

    记录Android N关联拒绝之后的相关的log. 10-26 20:35:35.844 2215 2215 D wpa_supplicant: * bssid_hint=44:48:c1:d6:57 ...

  7. JUnit注解

    在本节中,我们将提到支持在JUnit4基本注释,下表列出了这些注释的概括: 注解 描述 @Testpublic void method() 测试注释指示该公共无效方法它所附着可以作为一个测试用例. @ ...

  8. e800. 监听JSlider的数值变化

    // Create horizontal slider JSlider slider = new JSlider(); // Register a change listener slider.add ...

  9. PD 15.1 安装 破解 , 简单使用 (一对多,多对多关系生成sql脚本) , CDM 和 PDM 的区别;PD15.1 生成sql2008 无FK外键约束的解决方法

    CDM是概念模型,在概念模型上没有具体数据库产品的概念,反映的是实体和联系.PDM是物理模型,是依赖具体数据库产品的模型,比如可以指定具体的数据类型和约束等等.在PowerDesigner中两个模型之 ...

  10. kubeadm init 卡在 Created API client, waiting for the control plane to become ready

    执行 kubeadm init 时出现卡在了 [apiclient] Created API client, waiting for the control plane to become ready ...