1+ /* *
2+ * =============================================================================
3+ * DumpSource2
4+ * Copyright (C) 2026 ValveResourceFormat Contributors
5+ * =============================================================================
6+ *
7+ * This program is free software; you can redistribute it and/or modify it under
8+ * the terms of the GNU General Public License, version 3.0, as published by the
9+ * Free Software Foundation.
10+ *
11+ * This program is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14+ * details.
15+ *
16+ * You should have received a copy of the GNU General Public License along with
17+ * this program. If not, see <http://www.gnu.org/licenses/>.
18+ */
19+
20+ #include " module_metadata.h"
21+ #include < spdlog/spdlog.h>
22+ #include " modules.h"
23+ #include " utils/module.h"
24+ #include " utils/common.h"
25+ #include " globalvariables.h"
26+ #include " keyvalues3.h"
27+ #include < unordered_set>
28+
29+ namespace Dumpers ::ModuleMetadata
30+ {
31+
32+ void GetModuleMetadata (const CModule& module , SimpleCUtlString& err, SimpleCUtlString& buf)
33+ {
34+ spdlog::info (" Dumping metadata for {}" , module .m_pszModule );
35+
36+ typedef void * (*ExtractModuleMetadata)(SimpleCUtlString& str);
37+ auto extractModuleMetadataFn = module .GetSymbol <ExtractModuleMetadata>(" ExtractModuleMetadata" );
38+
39+ SimpleCUtlString additional_info;
40+ auto kv3 = extractModuleMetadataFn (additional_info);
41+
42+ typedef int (*SaveKV3Text_ToString)(KV3ID_t const &, void * kv3, SimpleCUtlString& err, SimpleCUtlString& str);
43+ #ifdef WIN32
44+ static auto saveKV3Text_ToStringFn = Modules::tier0->GetSymbol <SaveKV3Text_ToString>(" ?SaveKV3Text_ToString@@YA_NAEBUKV3ID_t@@PEBVKeyValues3@@PEAVCUtlString@@2I@Z" );
45+ #else
46+ static auto saveKV3Text_ToStringFn = Modules::tier0->GetSymbol <SaveKV3Text_ToString>(" _Z20SaveKV3Text_ToStringRK7KV3ID_tPK10KeyValues3P10CUtlStringS6_j" );
47+ #endif
48+
49+ saveKV3Text_ToStringFn (g_KV3Encoding_Text, kv3, err, buf);
50+
51+ if (additional_info.Get ())
52+ spdlog::warn (" {} has additional_info {}" , module .m_pszModule , additional_info.Get ());
53+ }
54+
55+ void Dump ()
56+ {
57+ spdlog::info (" Dumping module metadata" );
58+ std::unordered_set<std::string> foundModules;
59+ const auto outputPath = Globals::outputPath / " module_metadata" ;
60+
61+ for (const auto & module : Modules::allModules)
62+ {
63+ SimpleCUtlString err, buf;
64+ GetModuleMetadata (module , err, buf);
65+
66+ if (buf.Get ())
67+ {
68+ auto sanitizedModuleName = std::string (module .m_pszModule );
69+ std::replace (sanitizedModuleName.begin (), sanitizedModuleName.end (), ' /' , ' _' );
70+ foundModules.insert (sanitizedModuleName);
71+
72+
73+ if (!std::filesystem::is_directory (outputPath) && !std::filesystem::create_directory (outputPath))
74+ {
75+ spdlog::error (" Failed to create module_metadata directory" );
76+ return ;
77+ }
78+
79+ std::ofstream output ((outputPath / sanitizedModuleName).replace_extension (" .kv3" ));
80+ output << buf.Get () << std::endl;
81+ }
82+ }
83+
84+ for (const auto & typeScopePath : std::filesystem::directory_iterator (outputPath))
85+ {
86+ if (foundModules.find (typeScopePath.path ().stem ().string ()) == foundModules.end ())
87+ {
88+ spdlog::info (" Removing orphan metadata file {}" , typeScopePath.path ().generic_string ());
89+ std::filesystem::remove (typeScopePath.path ());
90+ }
91+ }
92+ }
93+
94+ } // namespace Dumpers::ModuleMetadata
0 commit comments