281 lines
9.1 KiB
C++
281 lines
9.1 KiB
C++
#include <Common/path.h>
|
|
#include <Common/IniFileClass.h>
|
|
#include <Common/StdString.h>
|
|
#include <algorithm>
|
|
#include <set>
|
|
#include <windows.h>
|
|
|
|
struct compareKeyValueItem
|
|
{
|
|
inline bool operator() (CIniFileBase::KeyValueItem & struct1, const CIniFileBase::KeyValueItem & struct2)
|
|
{
|
|
std::string a = *struct1.first;
|
|
std::string b = *struct2.first;
|
|
if (_stricmp(a.c_str(), "Name") == 0)
|
|
{
|
|
return true;
|
|
}
|
|
if (_stricmp(b.c_str(), "Name") == 0)
|
|
{
|
|
return false;
|
|
}
|
|
if (a.length() > 5 && _strnicmp(a.c_str(), "cheat", 5) == 0 &&
|
|
b.length() > 5 && _strnicmp(b.c_str(), "cheat", 5) == 0)
|
|
{
|
|
int i1 = atoi(&(*struct1.first)[5]);
|
|
int i2 = atoi(&(*struct2.first)[5]);
|
|
if (i1 != i2)
|
|
{
|
|
return i1 < i2;
|
|
}
|
|
char Buffer[40];
|
|
int number_len = strlen(_itoa(i1, Buffer, 10));
|
|
if (strlen(&a[5 + number_len]) == 0)
|
|
{
|
|
return true;
|
|
}
|
|
if (strlen(&b[5 + number_len]) == 0)
|
|
{
|
|
return false;
|
|
}
|
|
return _stricmp(&a[5 + number_len], &b[5 + number_len]) <= 0;
|
|
}
|
|
return _stricmp(a.c_str(), b.c_str()) <= 0;
|
|
}
|
|
};
|
|
|
|
void CustomSortData(CIniFileBase::KeyValueVector & data)
|
|
{
|
|
std::sort(data.begin(), data.end(), compareKeyValueItem());
|
|
}
|
|
|
|
void SplitFile(const char * FileName, const char * Target)
|
|
{
|
|
if (!CPath(Target,"").DirectoryCreate())
|
|
{
|
|
return;
|
|
}
|
|
|
|
CPath SearchDir(Target, "*.*");
|
|
if (SearchDir.FindFirst())
|
|
{
|
|
do
|
|
{
|
|
SearchDir.Delete();
|
|
} while (SearchDir.FindNext());
|
|
}
|
|
|
|
CIniFile::SectionList Sections;
|
|
CIniFile CheatIniFile(FileName);
|
|
CheatIniFile.GetVectorOfSections(Sections);
|
|
|
|
for (size_t i = 0, n = Sections.size(); i < n; i++)
|
|
{
|
|
const char * Section = Sections[i].c_str();
|
|
|
|
CIniFile::KeyValueData data;
|
|
CheatIniFile.GetKeyValueData(Section, data);
|
|
|
|
stdstr Name = CheatIniFile.GetString(Section, "Name", "");
|
|
Name.Trim("\t =");
|
|
if (Name.length() == 0)
|
|
{
|
|
Name = CheatIniFile.GetString(Section, "Good Name", Section);
|
|
Name.Trim("\t =");
|
|
}
|
|
Name.Replace("\\", "-");
|
|
Name.Replace("/", "-");
|
|
if (Name.length() == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
CPath GameFileName(Target, stdstr_f("%s.%s", Name.c_str(), CPath(FileName).GetExtension().c_str()).c_str());
|
|
CIniFile GameIniFile(GameFileName);
|
|
if (!GameIniFile.IsFileOpen())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
GameIniFile.SetAutoFlush(false);
|
|
GameIniFile.SetCustomSort(CustomSortData);
|
|
|
|
for (CIniFile::KeyValueData::const_iterator itr = data.begin(); itr != data.end(); itr++)
|
|
{
|
|
stdstr DataLine(itr->second);
|
|
DataLine.Trim("\t =");
|
|
if (strcmp(itr->first.c_str(), "Good Name") == 0)
|
|
{
|
|
GameIniFile.SaveString(Section, "Name", DataLine.c_str());
|
|
}
|
|
else
|
|
{
|
|
GameIniFile.SaveString(Section, itr->first.c_str(), DataLine.c_str());
|
|
}
|
|
}
|
|
GameIniFile.FlushChanges();
|
|
}
|
|
}
|
|
|
|
typedef std::map<std::string, std::string> Files;
|
|
|
|
void RegionSection(CFile &TargetIniFile, Files &files, const char * Region, const char * RegionCode)
|
|
{
|
|
stdstr_f LineData = stdstr_f("//--------------- %s Region Cheat Codes ---------------\r\n\r\n", Region);
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
|
|
bool first = true;
|
|
for (Files::const_iterator itr = files.begin(); itr != files.end(); itr++)
|
|
{
|
|
CIniFile GameIniFile(itr->second.c_str());
|
|
GameIniFile.SetCustomSort(CustomSortData);
|
|
CIniFile::SectionList Sections;
|
|
GameIniFile.GetVectorOfSections(Sections);
|
|
|
|
bool found = false;
|
|
stdstr_f searchStr(":%s", RegionCode);
|
|
for (size_t i = 0, n = Sections.size(); i < n; i++)
|
|
{
|
|
const char * Section = Sections[i].c_str();
|
|
const char * pos = strstr(Section, searchStr.c_str());
|
|
if (pos == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
found = true;
|
|
break;
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for (size_t i = 0, n = Sections.size(); i < n; i++)
|
|
{
|
|
const char * Section = Sections[i].c_str();
|
|
|
|
CIniFile::KeyValueData data;
|
|
GameIniFile.GetKeyValueData(Section, data);
|
|
|
|
CIniFile::KeyValueVector data2;
|
|
for (CIniFile::KeyValueData::const_iterator DataItr = data.begin(); DataItr != data.end(); DataItr++)
|
|
{
|
|
data2.push_back(CIniFile::KeyValueItem(&DataItr->first, &DataItr->second));
|
|
}
|
|
std::sort(data2.begin(), data2.end(), compareKeyValueItem());
|
|
|
|
if (first)
|
|
{
|
|
first = false;
|
|
}
|
|
else
|
|
{
|
|
LineData = stdstr_f("\r\n//----\r\n\r\n");
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
}
|
|
LineData = stdstr_f("[%s]\r\n", Section);
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
|
|
for (CIniFile::KeyValueVector::const_iterator DataItr = data2.begin(); DataItr != data2.end(); DataItr++)
|
|
{
|
|
LineData = stdstr_f("%s=%s\r\n", DataItr->first->c_str(), DataItr->second->c_str());
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void JoinFile(const char * Directory, const char * Target)
|
|
{
|
|
Files files;
|
|
CPath SearchDir(Directory, "*.*");
|
|
if (SearchDir.FindFirst())
|
|
{
|
|
do
|
|
{
|
|
CIniFile GameIniFile(SearchDir);
|
|
|
|
CIniFile::SectionList Sections;
|
|
GameIniFile.GetVectorOfSections(Sections);
|
|
for (size_t i = 0, n = Sections.size(); i < n; i++)
|
|
{
|
|
const char * Section = Sections[i].c_str();
|
|
stdstr Name = GameIniFile.GetString(Section, "Name", Section);
|
|
Name.Trim("\t =");
|
|
if (Name.size() > 0)
|
|
{
|
|
files.insert(Files::value_type(Name, SearchDir));
|
|
}
|
|
break;
|
|
}
|
|
} while (SearchDir.FindNext());
|
|
}
|
|
|
|
if (CPath(Target).Exists())
|
|
{
|
|
CPath(Target).Delete();
|
|
};
|
|
|
|
CFile TargetIniFile;
|
|
if (!TargetIniFile.Open(Target, CFileBase::modeReadWrite | CFileBase::modeCreate | CFileBase::shareDenyWrite))
|
|
{
|
|
return;
|
|
}
|
|
if (strcmp(CPath(Target).GetExtension().c_str(), "cht") == 0)
|
|
{
|
|
stdstr_f LineData = stdstr_f("// Project64 Official Cheats Database\r\n");
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
LineData = stdstr_f("// Not for use with PJ64 v1.6 or previous\r\n");
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
LineData = stdstr_f("// ----------------------------------------------------\r\n\r\n");
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
|
|
CPath MetaFileName(Directory, "Meta.cht");
|
|
CIniFile MetaIniFile(MetaFileName);
|
|
if (MetaIniFile.IsFileOpen())
|
|
{
|
|
CIniFile::KeyValueData data;
|
|
MetaIniFile.GetKeyValueData("Meta", data);
|
|
|
|
LineData = stdstr_f("[Meta]\r\n");
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
for (CIniFile::KeyValueData::const_iterator itr = data.begin(); itr != data.end(); itr++)
|
|
{
|
|
stdstr DataLine(itr->second);
|
|
DataLine.Trim("\t =");
|
|
LineData = stdstr_f("%s=%s\r\n",itr->first.c_str(), DataLine.c_str());
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
}
|
|
LineData = stdstr_f("\r\n");
|
|
TargetIniFile.Write(LineData.c_str(), (int)LineData.length());
|
|
}
|
|
}
|
|
|
|
|
|
RegionSection(TargetIniFile, files, "(J)", "4A");
|
|
RegionSection(TargetIniFile, files, "(JU)", "41");
|
|
RegionSection(TargetIniFile, files, "(U)", "45");
|
|
RegionSection(TargetIniFile, files, "PAL (E)", "50");
|
|
RegionSection(TargetIniFile, files, "PAL (A)", "55");
|
|
RegionSection(TargetIniFile, files, "PAL (F)", "46");
|
|
RegionSection(TargetIniFile, files, "PAL (G)", "44");
|
|
RegionSection(TargetIniFile, files, "PAL (I)", "49");
|
|
RegionSection(TargetIniFile, files, "PAL (S)", "53");
|
|
RegionSection(TargetIniFile, files, "PAL(FGD)", "58");
|
|
RegionSection(TargetIniFile, files, "Demo", "0");
|
|
}
|
|
|
|
int WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR /*lpszArgs*/, int /*nWinMode*/)
|
|
{
|
|
if (__argc == 4 && strcmp(__argv[1], "-split") == 0 && CPath(__argv[2]).Exists())
|
|
{
|
|
SplitFile(__argv[2], __argv[3]);
|
|
}
|
|
if (__argc == 4 && strcmp(__argv[1], "-join") == 0 && CPath(__argv[2],"").DirectoryExists())
|
|
{
|
|
JoinFile(__argv[2], __argv[3]);
|
|
}
|
|
return 0;
|
|
}
|