Skip to content

Commit

Permalink
add schema dumper
Browse files Browse the repository at this point in the history
  • Loading branch information
Poggicek committed Oct 3, 2024
1 parent 198b1ac commit 384c4b1
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 28 deletions.
67 changes: 53 additions & 14 deletions src/main/appframework.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,36 @@
#include "utils/module.h"
#include "modules.h"
#include "interfaces.h"
#include "application.h"
#include "globalvariables.h"
#include <schemasystem/schemasystem.h>
#include <fmt/format.h>
#include <map>

static DumperApplication g_Application;

struct AppSystemInfo
{
bool gameBin;
const char* moduleName;
std::string interfaceVersion;
bool connect = true;
};

std::vector<AppSystemInfo> g_appSystems{
{false, "filesystem_stdio", FILESYSTEM_INTERFACE_VERSION},
{false, "resourcesystem", RESOURCESYSTEM_INTERFACE_VERSION, true},
{true, "client", "Source2ClientConfig001"},
{false, "engine2", SOURCE2ENGINETOSERVER_INTERFACE_VERSION},
{true, "host", "Source2Host001" },
{true, "matchmaking", "MATCHFRAMEWORK_001"},
{true, "server", "Source2ServerConfig001"},
{false, "animationsystem", "AnimationSystem_001"},
{false, "materialsystem2", "TextLayout_001"},
{false, "meshsystem", "MeshSystem001", false},
};

std::map<std::string, IAppSystem*> g_factoryMap;

void* AppSystemFactory(const char* pName, int* pReturnCode)
{
Expand All @@ -32,6 +59,15 @@ void* AppSystemFactory(const char* pName, int* pReturnCode)

if (!strcmp(pName, SCHEMASYSTEM_INTERFACE_VERSION))
return Interfaces::schemaSystem;

if (!strcmp(pName, APPLICATION_INTERFACE_VERSION))
return &g_Application;

if (g_factoryMap.find(pName) != g_factoryMap.end())
{
printf("Connected %s\n", pName);
return g_factoryMap.at(pName);
}

return nullptr;
}
Expand All @@ -54,17 +90,6 @@ void InitializeCoreModules()
Interfaces::schemaSystem->Init();
}

struct AppSystemInfo
{
bool gameBin;
const char* moduleName;
const char* interfaceVersion;
};

std::vector<AppSystemInfo> g_appSystems{
{true, "client", "Source2ClientConfig001"}
};

void InitializeAppSystems()
{
for (const auto& appSystem : g_appSystems)
Expand All @@ -73,9 +98,23 @@ void InitializeAppSystems()

CModule module(path.c_str(), appSystem.moduleName);

auto interface = module.FindInterface<IAppSystem*>(appSystem.interfaceVersion);
auto interface = module.FindInterface<IAppSystem*>(appSystem.interfaceVersion.c_str());

g_factoryMap[appSystem.interfaceVersion] = interface;

if (appSystem.connect)
{

interface->Connect(&AppSystemFactory);
interface->Init();
}
else
{
// We can't connect this interface, let's at least dump schemas
typedef void* (*InstallSchemaBindings)(const char* interfaceName, void* pSchemaSystem);
InstallSchemaBindings fn = (InstallSchemaBindings)dlsym(module.m_hModule, "InstallSchemaBindings");

interface->Connect(&AppSystemFactory);
interface->Init();
fn(SCHEMASYSTEM_INTERFACE_VERSION, Interfaces::schemaSystem);
}
}
}
60 changes: 60 additions & 0 deletions src/main/application.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* =============================================================================
* DumpSource2
* Copyright (C) 2024 ValveResourceFormat Contributors
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once
#include "appframework/IAppSystem.h"

class DumperApplication : public CTier0AppSystem<IAppSystem>
{
virtual void Destructor() {};
#ifndef _WIN32
virtual void Destructor2() {};
#endif
virtual void PreShutdown() {};
virtual BuildType_t GetBuildType() { return kBuildTypeRelease; };
virtual void Reconnect(CreateInterfaceFn factory, const char* interfaceName) {};


virtual int AddSystem(IAppSystem* pAppSystem, const char* interfaceName, bool errorOut) { return 0; };
virtual int AddSystem(const char* unk, const char* interfaceName, bool errorOut) { return 0; };
virtual int AddSystem(IAppSystem* pAppSystem, const char* interfaceName) { return 0; };
virtual void RemoveSystem(IAppSystem* pAppSystem) { };
virtual int AddSystems(int count, void** pAppSystems) { return 0; };
virtual void* FindSystem(const char* interfaceName) { return nullptr; };
virtual void* GetGameInfo() {
printf("called getgameinfo\n");
return nullptr;
};
virtual unsigned int unk1() { return -1; };
virtual int GetUILanguage(int languageType) { return 0; };
virtual int GetAudioLanguage(int languageType) { return 0; };
virtual bool IsInToolsMode() { return false; };
virtual bool unk2() { return false; };
virtual bool unk3() { return false; };
virtual bool unk4() { return false; };
virtual void* unk5() { return nullptr; };
virtual void* unk6() { return nullptr; };
virtual void* unk7() { return nullptr; };
virtual void* unk8() { return nullptr; };
virtual void* unk9() { return nullptr; };
virtual void* unk10(void* a) { return a; };
virtual void* unk11() { return nullptr; };
virtual void* AddSystemDontLoadStartupManifests(const char* a, const char* b) { return nullptr; };
virtual void* unk12() { return nullptr; };
};
85 changes: 76 additions & 9 deletions src/main/dumpers/schemas/schemas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,99 @@
*/

#include "schemas.h"
#include "globalvariables.h"
#include "interfaces.h"
#include "schemasystem/schemasystem.h"
#include <filesystem>
#include <fstream>
#include <map>
#include <unordered_set>

namespace Dumpers::Schemas
{

void DumpTypeScope(CSchemaSystemTypeScope* typeScope, std::filesystem::path schemaPath, std::map<std::string, std::unordered_set<std::string>>& foundFiles)
{
const auto& classes = typeScope->m_ClassBindings;

UtlTSHashHandle_t* handles = new UtlTSHashHandle_t[classes.Count()];
classes.GetElements(0, classes.Count(), handles);

for (int j = 0; j < classes.Count(); ++j) {
const auto classInfo = classes[handles[j]];

if (!std::filesystem::is_directory(schemaPath / classInfo->m_pszProjectName))
if (!std::filesystem::create_directory(schemaPath / classInfo->m_pszProjectName))
return;

// Some classes have :: in them which we can't save.
auto sanitizedFileName = std::string(classInfo->m_pszName);
std::replace(sanitizedFileName.begin(), sanitizedFileName.end(), ':', '_');

// We save the file in a map so that we know which files are outdated and should be removed
foundFiles[classInfo->m_pszProjectName].insert(sanitizedFileName);

std::ofstream output((schemaPath / classInfo->m_pszProjectName / sanitizedFileName).replace_extension(".h"));

output << "class " << classInfo->m_pszName;

if (classInfo->m_nBaseClassCount > 0)
output << " : public " << classInfo->m_pBaseClasses[0].m_pClass->m_pszName;

output << "\n{\n";

for (uint16_t k = 0; k < classInfo->m_nFieldCount; k++)
{
const auto& field = classInfo->m_pFields[k];

output << "\t" << field.m_pType->m_sTypeName.String() << " " << field.m_pszName << ";\n";
}

output << "}\n";
}
}

void Dump()
{
auto schemaSystem = Interfaces::schemaSystem;

const auto& typeScopes = schemaSystem->m_TypeScopes;
const auto schemaPath = Globals::outputPath / "schemas";

if (!std::filesystem::is_directory(schemaPath))
if (!std::filesystem::create_directory(schemaPath))
return;

std::map<std::string, std::unordered_set<std::string>> foundFiles;

for (auto i = 0; i < typeScopes.GetNumStrings(); ++i)
{
const auto& typeScope = typeScopes[i];
printf("Type scope: %s\n", typeScope->m_szScopeName);
DumpTypeScope(typeScopes[i], schemaPath, foundFiles);

const auto& classes = typeScope->m_ClassBindings;
DumpTypeScope(schemaSystem->GlobalTypeScope(), schemaPath, foundFiles);

UtlTSHashHandle_t* handles = new UtlTSHashHandle_t[classes.Count()];
classes.GetElements(0, classes.Count(), handles);
for (const auto& entry : std::filesystem::directory_iterator(schemaPath))
{
auto projectName = entry.path().filename().string();
bool isInMap = foundFiles.find(projectName) != foundFiles.end();

if (entry.is_directory() && !isInMap)
{
printf("Removing %ls\n", entry.path().c_str());
std::filesystem::remove_all(entry.path());
}
else if (isInMap)
{

for (int j = 0; j < classes.Count(); ++j) {
auto class_info = classes[handles[j]];
for (const auto& typeScopePath : std::filesystem::directory_iterator(entry.path()))
{
auto& filesSet = foundFiles[projectName];

printf("\t - %s\n", class_info->m_pszName);
if (filesSet.find(typeScopePath.path().stem().string()) == filesSet.end())
{
printf("Removing %ls\n", typeScopePath.path().c_str());
std::filesystem::remove(typeScopePath.path());
}
}
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ int main(int argc, char** argv)
InitializeCoreModules();
InitializeAppSystems();

printf("Dumping\n");

Dumpers::ConCommands::Dump();
//Dumpers::Schemas::Dump();
Dumpers::Schemas::Dump();
}
4 changes: 0 additions & 4 deletions src/main/utils/oslink.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@ inline bool _IsPathSepChar(char c) { return (c == '/' || c == '\\'); }
#include <sys/types.h>
#include <dirent.h>
typedef void* HINSTANCE;
#ifdef META_IS_SOURCE2
#define dlmount(x) dlopen(x,RTLD_NOW | RTLD_DEEPBIND)
#else
#define dlmount(x) dlopen(x,RTLD_NOW)
#endif
#define abspath(x, s) realpath(s, x)
#define PATH_SEP_STR "/"
#define PATH_SEP_CHAR '/'
Expand Down

0 comments on commit 384c4b1

Please sign in to comment.