U3D教程宝典之两步实现超实用的XML存档
两步实现超实用的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存档的更多相关文章
- IntelliJ IDEA热部署教程,只要两步!
一.开启idea自动build功能1.File -> Settings -> Build,Execution,Deployment -> Compiler -> Build p ...
- Google 推出全新的两步验证机制
近日 Google 在官方的 Apps Updates 博客公布了全新的两步验证功能--Google 提示,新的功能通过与 Google App 联动,进一步将验证确认工作缩减到仅有两步,同时支持 A ...
- 两步验证杀手锏:Java 接入 Google 身份验证器实战
两步验证 大家应该对两步验证都熟悉吧?如苹果有自带的两步验证策略,防止用户账号密码被盗而锁定手机进行敲诈,这种例子屡见不鲜,所以苹果都建议大家开启两步验证的. Google 的身份验证器一般也是用于登 ...
- Ubuntu18.04两步纯小白傻瓜无脑式安装Caffe
前言 Ubuntu16安装caffe过于繁琐,然而Ubuntu18安装起来却仅仅两步而已 附上官方安装教程:http://caffe.berkeleyvision.org/install_apt.ht ...
- 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法
转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...
- 每次Xcode 升级之后 插件失效,两步解决
以下内容来源:http://www.cocoachina.com/bbs/read.php?tid=296269 每次Xcode 升级之后 插件失效,两步解决 1.打开终端,输入以下代码获取到DVTP ...
- 两步验证Authy时间同步问题
Authy是我常用的软件之一,通常用于Google的两步验证,或者是其他基于Google两步验证的原理的衍生程序.比如Namesilo.印象笔记等均有使用. 先说说什么是两步验证. 两步验证 两步验证 ...
- Github两步认证
获取密钥:ssh-keygen -t rsa 切换到公钥所在路径:cd .ssh 查看该路径下的所有文件:ls 查看公钥:cat id_rsa.pub 获取密钥之后,去https://github. ...
- 只需两步!Eclipse+Maven快速构建第一个Spring Boot项目
随着使用Spring进行开发的个人和企业越来越多,Spring从一个单一简介的框架变成了一个大而全的开源软件,最直观的变化就是Spring需要引入的配置也越来越多.配置繁琐,容易出错,让人无比头疼, ...
随机推荐
- ubuntu/debian安装mysql遇到的问题及解决方法_1.dpkg中mysql-server-5.5 (configure)时出错 mysql-server-5.5 E: Sub-process /usr/bin/dpkg returned an error code (1)
我的debian7之前安装了mysql-server,是通过apt安装的,后来我卸载掉, 然后用whereis mysql查找, 把所有关于mysql的目录删除掉,包括带mysqld的目录及文件. 重 ...
- 浅谈C++中对象的复制与对象之间的相互赋值
C++对象的复制 有时需要用到多个完全相同的对象,例如,同一型号的每一个产品从外表到内部属性都是一样的,如果要对每一个产品分别进行处理,就需要建立多个同样的对象,并要进行相同的初始化,用以前的办法定义 ...
- OSPF中 hello报文的 内容
邻居关系通过hello报文来建立.Hello报文中包含如下一些内容: 1.始发路由器的router-id 2.始发路由器接口的area-id 3.始发路由器接口的地址掩码 4.始发路由器接口的auth ...
- ViewPager自定义选项卡
转自:http://www.open-open.com/lib/view/open1352621601262.html
- 【WPF】鼠标拖拽功能DragOver和Drop
在Winform里面实现拖入功能只要设置控件AllowDrop=true; 然后实现方法 //拖入 private void txtInputPath_DragOver(object sender, ...
- Tomcat 的 DefaultServlet
问题描述: 群里有人测试 Spring MVC,没有配置任何Controller,只配置了一个view resolver,指定了前缀后缀. 然后,他问的是 当访问 localhost:8080/tes ...
- Json---Linux下使用Jsoncpp
一.安装 scons 下载地址:http://sourceforge.net/projects/scons/files/scons/2.1.0/scons-2.1.0.tar.gz/download ...
- Python中的base64模块
本文介绍Python 2.7中的base64模块,该模块提供了基于rfc3548的Base16, 32, 64编解码的接口.官方文档,参考这里. 该模块提供两套接口,传统接口基于rfc1521的Bas ...
- 运行 Shell 脚本有两种方法:
1.作为可执行程序 将上面的代码保存为 test.sh,并 cd 到相应目录: chmod +x ./test.sh #使脚本具有执行权限 ./test.sh #执行脚本 注意,一定要写成 ./tes ...
- unity3d Matrix4x4列为主序
unity3d的矩阵一直用,但是之前都是测试着用的,效果虽然正确,但是一直没搞清楚它是行矩阵还是列矩阵 今天测试了下 Matrix4x4 mat4 = Matrix4x4.Perspective(30 ...