如何用+CC编写游戏修改器

发布网友 发布时间:2022-04-23 13:52

我来回答

2个回答

热心网友 时间:2023-10-16 17:10

构造函数:

template<class T>
CheckBinaryFile<T>::CheckBinaryFile():CharSize(sizeof (char)),CIN(cin)
{ InputIsOk=true; Input(); }
  CharSize 为sizeof(char),把cin 绑定到CIN。由于CharSize是常量,必须在构造函数的初始化列表中设定。

  预设输入状态,调用输入函数:

template<class T>
void CheckBinaryFile<T>::Input()
{
 cout<<"Binary file name:\t";
 CIN>>FileName;
 BinaryFile.open(FileName.c_str(),ios::in | ios::binary);
 if(!BinaryFile){
  InputIsOk=false;
  cerr<<"Open file failed.\n";
  return;
 }
 cout<<"The integer you want to search:\t";
 CIN>>OldData;
 cout<<"Byte number(1--"<<CheckBinaryFile<T>::MaxByte<<"):\t";
 CIN>>ByteNumber;
 if(ByteNumber<1 || ByteNumber>CheckBinaryFile<T>::MaxByte) {
  //字节数错误,调整为最大值
  ByteNumber=CheckBinaryFile<T>::MaxByte;
  cout<<"Byte number was amended to " << CheckBinaryFile<T>::ByteNumber<<’\n’;
 }
}
  提示用户输入二进制存档文件,用只读+二进制模式开启。如果失败,设置输入状态为false,直接退出。然后提示用户输入要查找的整数(OldData)以及多少个字节(ByteNumber)。如果字节数错误,调整为最大值。由于计算机系统的不同以及char,short,int,long之间存在
转换关系,对于某些整型的字节数是不可确定的。比如100,可以用char表示,那么只需要sizeof(char)个字节表示就够了,当然也可以用字节数更多的类型,比如int,来表示100。

template<class T>
int CheckBinaryFile<T>::Check() const{
 const char* P=reinterpret_cast<const char*>(&OldData);
 char Range[CheckBinaryFile<T>::MaxByte];
 int Occurs=0;
 AddressType Addr=0;
 //填充0
 memset(Range,0,CheckBinaryFile<T>::MaxByte*CharSize);
 BinaryFile.read(Range,CharSize*ByteNumber);//填满Range
 while(BinaryFile){
  if(memcmp(P,Range,CharSize*ByteNumber)==0){//匹配成功
   AddressList.push_back(Addr);
   ++Occurs;
  }
  //删除一个最旧的
  memcpy(Range,&Range[1],CharSize*(ByteNumber-1));
  //读入一个新的
  BinaryFile.read(&Range[ByteNumber-1],CharSize);
  ++Addr;
 }
 return Occurs;
}

  检查输入的二进制文件中有多少个OldData,并保存地址,用模拟二进制方式比较OldData。Range 是一个比较区域,这里不打算输出这个字符串,也不考虑用strcpy来拷贝内容,所以不必预留一个空间来保存结尾符号’\0’。填满Range 后,开始一个一个字符比较了:

  当Range和OldData完全相同就表示匹配成功(memcmp返回0 表示成功),一旦成功,就把该地址保存下来(AddressList)。不管是否成功,把Range去掉一个最早读取的,然后读入一个新的,继续匹配。函数返回匹配的个数。

  list是标准C++的一个容器,类似双向链表,在添加/删除节点方面表现优秀。我不打算使用排序,因为从头到尾遍历文件时保存下来的地址肯定是有序的;我也不需要随机读取这些地址,所以排除了vector以及deque这两种容器。至于没有采用内建的数组,咳,我不
知道能找到多少地址,或许一个都没有,或许成千上万。

  list有一个size()函数,望文生义就是大小的意思,的确如此。不过由于list是一种链表,不像数组那样只要把头尾指针相减就能得到大小,取得size的办法只有从头到尾走一遍,速度比较慢。既然这个函数很清楚取得了多少个地址,那就直接返回这个数目吧!

template<class T>
void CheckBinaryFile<T>::Run()
{
 if(InputIsOk==false) return;
 const int Occurs=Check();
 cout<<Occurs<<" different addresses were found.\n";
 if(Occurs==0) return;
 cout<<"Save address info to files(y/n)?\t";
 char YN;
 CIN>>YN;
 if(YN==’y’ || YN==’Y’){
  cout<<"Address file name:\t";
  string AddressFileName;
  CIN>>AddressFileName;
  ofstream Save(AddressFileName.c_str(),ios::out);
  if(!Save)
  { cerr<<"Create "<<AddressFileName<<" failed.\n";}
  else
  { SaveAddressToFile(Save);
  Save.close();
 }
}
cout<<"Modify binary file automatically(y/n)?\t";
CIN>>YN;
 if(YN==’y’ || YN==’Y’){
  cout<<"New value:\t";
  T NewValue;
  CIN>>NewValue;
  system("dir > @tmp");
  system("del @*/q");
  AutoModifySave(NewValue);
 }
}
  如果输入错误,则直接退出。显示匹配的个数并询问是否保存这些地址至文件。再询问是否自动修改。比如找到了10个地址,自动修改将产生10个新文件,每个文件与原文件相比都只修改了一个地址的数值。输入新的数值,将产生若干个新文件。新文件的格式是@+地址的十进制表示。产生新文件前先把旧的以@开头的文件删除。如果不存在@开头的文件,system("del @*/q");会说找不到文件,不大舒服,那我先制造一个@tmp(system("dir > @tmp");),这里使用了DOS的输出重定向,把原本显示到屏幕的内容输入到@tmp中。

template<class T>
void CheckBinaryFile<T>::SaveA

热心网友 时间:2023-10-16 17:10

你也学C+啊一起研究了啊

热心网友 时间:2023-10-16 17:10

构造函数:

template<class T>
CheckBinaryFile<T>::CheckBinaryFile():CharSize(sizeof (char)),CIN(cin)
{ InputIsOk=true; Input(); }
  CharSize 为sizeof(char),把cin 绑定到CIN。由于CharSize是常量,必须在构造函数的初始化列表中设定。

  预设输入状态,调用输入函数:

template<class T>
void CheckBinaryFile<T>::Input()
{
 cout<<"Binary file name:\t";
 CIN>>FileName;
 BinaryFile.open(FileName.c_str(),ios::in | ios::binary);
 if(!BinaryFile){
  InputIsOk=false;
  cerr<<"Open file failed.\n";
  return;
 }
 cout<<"The integer you want to search:\t";
 CIN>>OldData;
 cout<<"Byte number(1--"<<CheckBinaryFile<T>::MaxByte<<"):\t";
 CIN>>ByteNumber;
 if(ByteNumber<1 || ByteNumber>CheckBinaryFile<T>::MaxByte) {
  //字节数错误,调整为最大值
  ByteNumber=CheckBinaryFile<T>::MaxByte;
  cout<<"Byte number was amended to " << CheckBinaryFile<T>::ByteNumber<<’\n’;
 }
}
  提示用户输入二进制存档文件,用只读+二进制模式开启。如果失败,设置输入状态为false,直接退出。然后提示用户输入要查找的整数(OldData)以及多少个字节(ByteNumber)。如果字节数错误,调整为最大值。由于计算机系统的不同以及char,short,int,long之间存在
转换关系,对于某些整型的字节数是不可确定的。比如100,可以用char表示,那么只需要sizeof(char)个字节表示就够了,当然也可以用字节数更多的类型,比如int,来表示100。

template<class T>
int CheckBinaryFile<T>::Check() const{
 const char* P=reinterpret_cast<const char*>(&OldData);
 char Range[CheckBinaryFile<T>::MaxByte];
 int Occurs=0;
 AddressType Addr=0;
 //填充0
 memset(Range,0,CheckBinaryFile<T>::MaxByte*CharSize);
 BinaryFile.read(Range,CharSize*ByteNumber);//填满Range
 while(BinaryFile){
  if(memcmp(P,Range,CharSize*ByteNumber)==0){//匹配成功
   AddressList.push_back(Addr);
   ++Occurs;
  }
  //删除一个最旧的
  memcpy(Range,&Range[1],CharSize*(ByteNumber-1));
  //读入一个新的
  BinaryFile.read(&Range[ByteNumber-1],CharSize);
  ++Addr;
 }
 return Occurs;
}

  检查输入的二进制文件中有多少个OldData,并保存地址,用模拟二进制方式比较OldData。Range 是一个比较区域,这里不打算输出这个字符串,也不考虑用strcpy来拷贝内容,所以不必预留一个空间来保存结尾符号’\0’。填满Range 后,开始一个一个字符比较了:

  当Range和OldData完全相同就表示匹配成功(memcmp返回0 表示成功),一旦成功,就把该地址保存下来(AddressList)。不管是否成功,把Range去掉一个最早读取的,然后读入一个新的,继续匹配。函数返回匹配的个数。

  list是标准C++的一个容器,类似双向链表,在添加/删除节点方面表现优秀。我不打算使用排序,因为从头到尾遍历文件时保存下来的地址肯定是有序的;我也不需要随机读取这些地址,所以排除了vector以及deque这两种容器。至于没有采用内建的数组,咳,我不
知道能找到多少地址,或许一个都没有,或许成千上万。

  list有一个size()函数,望文生义就是大小的意思,的确如此。不过由于list是一种链表,不像数组那样只要把头尾指针相减就能得到大小,取得size的办法只有从头到尾走一遍,速度比较慢。既然这个函数很清楚取得了多少个地址,那就直接返回这个数目吧!

template<class T>
void CheckBinaryFile<T>::Run()
{
 if(InputIsOk==false) return;
 const int Occurs=Check();
 cout<<Occurs<<" different addresses were found.\n";
 if(Occurs==0) return;
 cout<<"Save address info to files(y/n)?\t";
 char YN;
 CIN>>YN;
 if(YN==’y’ || YN==’Y’){
  cout<<"Address file name:\t";
  string AddressFileName;
  CIN>>AddressFileName;
  ofstream Save(AddressFileName.c_str(),ios::out);
  if(!Save)
  { cerr<<"Create "<<AddressFileName<<" failed.\n";}
  else
  { SaveAddressToFile(Save);
  Save.close();
 }
}
cout<<"Modify binary file automatically(y/n)?\t";
CIN>>YN;
 if(YN==’y’ || YN==’Y’){
  cout<<"New value:\t";
  T NewValue;
  CIN>>NewValue;
  system("dir > @tmp");
  system("del @*/q");
  AutoModifySave(NewValue);
 }
}
  如果输入错误,则直接退出。显示匹配的个数并询问是否保存这些地址至文件。再询问是否自动修改。比如找到了10个地址,自动修改将产生10个新文件,每个文件与原文件相比都只修改了一个地址的数值。输入新的数值,将产生若干个新文件。新文件的格式是@+地址的十进制表示。产生新文件前先把旧的以@开头的文件删除。如果不存在@开头的文件,system("del @*/q");会说找不到文件,不大舒服,那我先制造一个@tmp(system("dir > @tmp");),这里使用了DOS的输出重定向,把原本显示到屏幕的内容输入到@tmp中。

template<class T>
void CheckBinaryFile<T>::SaveA

热心网友 时间:2023-10-16 17:10

你也学C+啊一起研究了啊

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com