八门神器是安卓、iOS、塞班平台上通用的游戏修改工具,可以修改内存中的数值和参数,达到修改游戏HP、MP、金钱、等级等的作用。
也就是说,八门神器的运作方式是通过查找游戏运行内存满足条件的数值,并修改该数值,从而实现修改游戏内数值。
那么,我们如果想实现防止八门神器修改游戏数值,就要采用所见非所得的思想来做,通俗来说,拿游戏金币举例,玩家看到的金币数和 购买商品时操作的金币数非同一内存,且非同一值,即可避免。
这里有一种可行的方案 代码如下:
#ifndef __PROTECT_NUM_H_
#define __PROTECT_NUM_H_
#include <vector>
#include "cocos2d.h"
using namespace cocos2d;
using namespace std;
//设定一个枚举类型,便于区分不同的数值,同时用于查找
typedef enum{
eNumTag_gold,
eNumTag_Count
}eNumTag;
class CProtectNum
{
public:
CProtectNum(void);
~CProtectNum(void);
public:
//单例模式
static CProtectNum * sharedProtectNum();
//初始化 ,可以不调用,用于生成一个密码
void Init(int password);
//保存一个数值,传入数值的枚举 和数值
void SaveNum(eNumTag tag,int num);
//获取一个数值,传入数值的枚举
int GetNum(eNumTag tag);
//清除所有储存数值
void ClearNum();
private:
//结构体
struct sProtectNumInfo{
eNumTag numID; //数值ID 枚举类型
int safeNum;//加密后的数值
int normalNum;//加密前的数值
};
//存放结构体
vector<sProtectNumInfo> m_sProtectNumVec;
//密码
int m_iPassword;
};
#endif //__PROTECT_NUM_H_
#include "ProtectNum.h"
//唯一实例
static CProtectNum * m_pProtectNum =NULL;
//构造函数中给了一个默认密码
CProtectNum::CProtectNum(void)
{
m_iPassword=321;
}
CProtectNum::~CProtectNum(void)
{
}
//单例实现
CProtectNum * CProtectNum::sharedProtectNum()
{
if (m_pProtectNum==NULL)
{
m_pProtectNum =new CProtectNum;
}
return m_pProtectNum;
}
//初始化,设定一个密码
void CProtectNum::Init( int password )
{
m_iPassword=password;
}
//存入一个数值
void CProtectNum::SaveNum( eNumTag tag,int num )
{
//如果已经存入了改数值,则更新
for (int i=0;i<m_sProtectNumVec.size();++i)
{
if (m_sProtectNumVec[i].numID==tag)
{
m_sProtectNumVec[i].normalNum=num;
m_sProtectNumVec[i].safeNum=num+m_iPassword;
return;
}
}
//如果没有存入该数值,则存储
sProtectNumInfo info;
info.numID=tag;
info.normalNum=num;
info.safeNum=num+m_iPassword;
m_sProtectNumVec.push_back(info);
}
//获取一个数值
int CProtectNum::GetNum( eNumTag tag )
{
for (int i=0;i<m_sProtectNumVec.size();++i)
{
if (m_sProtectNumVec[i].numID==tag)
{
//如果加密数值不等于未加密数值加上密码,说明被修改,还原未加密数值
if (m_sProtectNumVec[i].safeNum!=m_sProtectNumVec[i].normalNum+m_iPassword)
{
m_sProtectNumVec[i].normalNum=m_sProtectNumVec[i].safeNum-m_iPassword;
}
return m_sProtectNumVec[i].normalNum;
}
}
}
//清空所有数值
void CProtectNum::ClearNum()
{
m_sProtectNumVec.clear();
}
使用,可以先调用初始化,使用需要保护的数值前,先用get方法获取,修改需要保护的数值前,先用get方法获取,然后操作,再safe方法存入。