2021-10-19 12:47:32 +02:00
|
|
|
#include <iostream>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <filesystem>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <regex>
|
|
|
|
|
|
|
|
|
|
namespace fs = std::filesystem;
|
|
|
|
|
|
|
|
|
|
#define INIT_SCRIPTS_NAME "__init_scripts"
|
|
|
|
|
|
|
|
|
|
struct Registry {
|
2021-10-23 12:09:38 +02:00
|
|
|
std::string m_name;
|
|
|
|
|
std::string m_macroIdentifier;
|
|
|
|
|
std::string m_suffix;
|
|
|
|
|
std::vector<std::string> m_values;
|
2021-10-19 12:47:32 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::vector<Registry> registries = {
|
2021-10-23 12:09:38 +02:00
|
|
|
// do NOT change this without also refactoring the macro in ClientDetours.h
|
|
|
|
|
{ "CLIENT_DETOUR" ,"__detour_name" ,"__Result" }
|
2021-10-19 12:47:32 +02:00
|
|
|
|
2021-10-23 12:09:38 +02:00
|
|
|
// do NOT change this without also refactoring the macro in ClientLua.h
|
|
|
|
|
, { "LUA_FUNCTION" , "__lua_function_name", "__Result" }
|
2021-10-25 11:00:48 +02:00
|
|
|
|
|
|
|
|
// do NOT change this without also refactoring the macro in ClientNetwork.h
|
|
|
|
|
, { "ON_CUSTOM_PACKET" , "__listener_name", "__Result" }
|
2021-10-19 12:47:32 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> cppSourceFiles = {
|
2021-10-23 12:09:38 +02:00
|
|
|
".c", ".cc", ".cpp", ".cxx", ".cp", ".c++"
|
2021-10-19 12:47:32 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static bool endsWith(const std::string& str, const std::string& suffix)
|
|
|
|
|
{
|
2021-10-23 12:09:38 +02:00
|
|
|
return str.size() >= suffix.size() && 0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix);
|
2021-10-19 12:47:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
{
|
2021-10-23 12:09:38 +02:00
|
|
|
std::vector<std::string> luaFiles;
|
|
|
|
|
|
|
|
|
|
for (auto& p : fs::recursive_directory_iterator(fs::current_path()))
|
|
|
|
|
{
|
|
|
|
|
std::string path = p.path().string();
|
|
|
|
|
auto itr = std::find_if(cppSourceFiles.begin(), cppSourceFiles.end(), [&path](auto cur) {
|
|
|
|
|
return endsWith(path, cur);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Generate cpp scripts
|
|
|
|
|
if (itr != cppSourceFiles.end())
|
|
|
|
|
{
|
|
|
|
|
std::string sourceFile = (std::stringstream() << std::ifstream(path).rdbuf()).str();
|
|
|
|
|
|
2021-10-25 10:56:24 +02:00
|
|
|
std::vector<std::pair<size_t, size_t>> invalidRanges;
|
|
|
|
|
enum class State {
|
|
|
|
|
IN_COMMENT,
|
|
|
|
|
IN_ML_COMMENT,
|
|
|
|
|
IN_STRING,
|
|
|
|
|
STRING_ESCAPE,
|
|
|
|
|
OUTSIDE
|
|
|
|
|
};
|
|
|
|
|
State cur = State::OUTSIDE;
|
|
|
|
|
size_t curStart = 0;
|
|
|
|
|
for (size_t i = 0; i < sourceFile.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
switch (cur)
|
|
|
|
|
{
|
|
|
|
|
case State::OUTSIDE:
|
|
|
|
|
if (i < sourceFile.size() - 1 && sourceFile[i] == '/' && sourceFile[i + 1] == '/')
|
|
|
|
|
{
|
|
|
|
|
cur = State::IN_COMMENT;
|
|
|
|
|
curStart = i;
|
|
|
|
|
}
|
|
|
|
|
else if (i < sourceFile.size() - 1 && sourceFile[i] == '/' && sourceFile[i + 1] == '*')
|
|
|
|
|
{
|
|
|
|
|
cur = State::IN_ML_COMMENT;
|
|
|
|
|
curStart = i;
|
|
|
|
|
}
|
|
|
|
|
else if (sourceFile[i] == '"')
|
|
|
|
|
{
|
|
|
|
|
cur = State::IN_STRING;
|
|
|
|
|
curStart = i;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case State::STRING_ESCAPE:
|
|
|
|
|
cur = State::IN_STRING;
|
|
|
|
|
break;
|
|
|
|
|
case State::IN_STRING:
|
|
|
|
|
if (sourceFile[i] == '\\')
|
|
|
|
|
{
|
|
|
|
|
cur = State::STRING_ESCAPE;
|
|
|
|
|
}
|
|
|
|
|
else if (sourceFile[i] == '"')
|
|
|
|
|
{
|
|
|
|
|
invalidRanges.push_back({ curStart,i });
|
|
|
|
|
cur = State::OUTSIDE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case State::IN_COMMENT:
|
|
|
|
|
if (sourceFile[i] == '\n')
|
|
|
|
|
{
|
|
|
|
|
invalidRanges.push_back({ curStart, i });
|
|
|
|
|
cur = State::OUTSIDE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case State::IN_ML_COMMENT:
|
|
|
|
|
if (i < sourceFile.size() - 1 && sourceFile[i] == '*' && sourceFile[i + 1] == '/')
|
|
|
|
|
{
|
|
|
|
|
invalidRanges.push_back({ curStart, i });
|
|
|
|
|
cur = State::OUTSIDE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-23 12:09:38 +02:00
|
|
|
for (Registry& reg : registries)
|
|
|
|
|
{
|
2021-10-25 10:56:24 +02:00
|
|
|
std::string cur = sourceFile;
|
2021-10-24 12:40:14 +02:00
|
|
|
std::regex exp(reg.m_name + "[ \t\n\r]*\\([ \t\n\r]*(.+?)[ \t\n\r]*,");
|
2021-10-23 12:09:38 +02:00
|
|
|
std::smatch res;
|
2021-10-25 10:56:24 +02:00
|
|
|
size_t totalPos = 0;
|
|
|
|
|
while (std::regex_search(cur, res, exp))
|
2021-10-23 12:09:38 +02:00
|
|
|
{
|
|
|
|
|
std::string r1 = res[1];
|
2021-10-25 10:56:24 +02:00
|
|
|
auto find = std::find_if(invalidRanges.begin(), invalidRanges.end(), [&](std::pair<size_t, size_t> const& v) {
|
|
|
|
|
return v.first <= totalPos+res.position() && v.second >= totalPos+res.position();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (find == invalidRanges.end())
|
2021-10-23 12:09:38 +02:00
|
|
|
{
|
2021-10-25 10:56:24 +02:00
|
|
|
if (r1.compare(reg.m_macroIdentifier))
|
|
|
|
|
{
|
|
|
|
|
reg.m_values.push_back(r1 + reg.m_suffix);
|
|
|
|
|
}
|
2021-10-23 12:09:38 +02:00
|
|
|
}
|
2021-10-25 10:56:24 +02:00
|
|
|
// i just gave up, position() just won't work with iterators
|
|
|
|
|
size_t offset = res.position() + res[0].length();
|
|
|
|
|
totalPos += offset;
|
|
|
|
|
cur = cur.substr(offset);
|
2021-10-23 12:09:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate lua scripts
|
|
|
|
|
if (endsWith(path, ".lua"))
|
|
|
|
|
{
|
|
|
|
|
luaFiles.push_back(path);
|
|
|
|
|
std::ifstream luafile = std::ifstream(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::sort(luaFiles.begin(), luaFiles.end(), [](auto const& a, auto const& b) {
|
|
|
|
|
size_t aDirs = std::count(
|
|
|
|
|
a.begin()
|
|
|
|
|
, a.end(), '\\') + std::count(a.begin(), a.end(), '/'
|
|
|
|
|
);
|
|
|
|
|
size_t bDirs = std::count(
|
|
|
|
|
b.begin()
|
|
|
|
|
, b.end(), '\\') + std::count(b.begin(), b.end(), '/'
|
|
|
|
|
);
|
|
|
|
|
return (aDirs != bDirs) ? aDirs < bDirs : a < b;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
std::ofstream luafilesGenerated("luafiles.generated.h");
|
|
|
|
|
luafilesGenerated << "#include <vector>\n";
|
|
|
|
|
luafilesGenerated << "std::vector<std::pair<std::string,std::string>> LUA_FILES = {\n";
|
|
|
|
|
for (std::string const& path : luaFiles)
|
|
|
|
|
{
|
|
|
|
|
std::ifstream luafile = std::ifstream(path);
|
|
|
|
|
luafilesGenerated << " {\"";
|
|
|
|
|
auto relPath = std::filesystem::relative
|
|
|
|
|
(path,std::filesystem::path(__FILE__).parent_path()).string();
|
|
|
|
|
for (char c : relPath)
|
|
|
|
|
{
|
|
|
|
|
if (c == '\\')
|
|
|
|
|
{
|
|
|
|
|
luafilesGenerated << "\\\\";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
luafilesGenerated << c;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
luafilesGenerated << "\", {";
|
|
|
|
|
|
|
|
|
|
char byte;
|
|
|
|
|
while (luafile.get(byte))
|
|
|
|
|
{
|
|
|
|
|
luafilesGenerated << "0x" << std::hex << uint32_t(byte) << ",";
|
|
|
|
|
}
|
|
|
|
|
luafilesGenerated << "}},\n";
|
|
|
|
|
}
|
|
|
|
|
luafilesGenerated << "};";
|
|
|
|
|
|
|
|
|
|
// Generate scripts header
|
|
|
|
|
std::ofstream scriptsGenerated("scripts.generated.h");
|
|
|
|
|
scriptsGenerated << "#include <iostream>\n";
|
|
|
|
|
for (Registry const& reg : registries)
|
|
|
|
|
{
|
|
|
|
|
for (std::string const& id : reg.m_values)
|
|
|
|
|
{
|
|
|
|
|
scriptsGenerated << "extern int " << id << ";\n";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// there's likely a better way to force the compiler to not optimize this,
|
|
|
|
|
// but this should be very safe.
|
|
|
|
|
scriptsGenerated << "inline void " INIT_SCRIPTS_NAME "()\n{\n";
|
|
|
|
|
for (Registry const& reg : registries)
|
|
|
|
|
{
|
|
|
|
|
if (reg.m_values.size() == 0) continue;
|
|
|
|
|
scriptsGenerated << " std::cout << \" Generated \" << (";
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < reg.m_values.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
scriptsGenerated << reg.m_values[i];
|
|
|
|
|
if (i < reg.m_values.size() - 1)
|
|
|
|
|
{
|
|
|
|
|
scriptsGenerated << " + ";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
scriptsGenerated << ") << \"" << reg.m_name << "s\\n\";\n";
|
|
|
|
|
}
|
|
|
|
|
scriptsGenerated << "}";
|
|
|
|
|
return 0;
|
2021-10-19 12:47:32 +02:00
|
|
|
}
|