Ark Server API (ASE) - Wiki
Loading...
Searching...
No Matches
version.cpp
Go to the documentation of this file.
1#include <Windows.h>
2#include <tlhelp32.h>
3#include <cstdio>
4#include <filesystem>
5#include <fstream>
6#include <json.hpp>
7#include "Core/Private/Ark/ArkBaseApi.h"
8#include "Core/Private/Atlas/AtlasBaseApi.h"
9#include "Core/Public/Logger/Logger.h"
10#include "Core/Public/Tools.h"
11
12#pragma comment(lib, "Crypt32.lib")
13#pragma comment(lib, "Iphlpapi.lib")
14
15HINSTANCE m_hinst_dll = nullptr;
16extern "C" UINT_PTR mProcs[17]{ 0 };
17
18LPCSTR import_names[] = {
19 "GetFileVersionInfoA", "GetFileVersionInfoByHandle", "GetFileVersionInfoExA", "GetFileVersionInfoExW",
20 "GetFileVersionInfoSizeA", "GetFileVersionInfoSizeExA", "GetFileVersionInfoSizeExW", "GetFileVersionInfoSizeW",
21 "GetFileVersionInfoW", "VerFindFileA", "VerFindFileW", "VerInstallFileA", "VerInstallFileW", "VerLanguageNameA",
22 "VerLanguageNameW", "VerQueryValueA", "VerQueryValueW"
23};
24
26{
27 const DWORD InvalidParentProcessId = 0;
28
29 HANDLE Snapshot = 0;
30 PROCESSENTRY32 ProcessEntry;
31 DWORD PID = GetCurrentProcessId();
32
33 Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
34 if (Snapshot == INVALID_HANDLE_VALUE)
35 return InvalidParentProcessId;
36
37 ZeroMemory(&ProcessEntry, sizeof(ProcessEntry));
38 ProcessEntry.dwSize = sizeof(ProcessEntry);
39
40 if (!Process32First(Snapshot, &ProcessEntry))
41 return InvalidParentProcessId;
42
43 do
44 {
45 if (ProcessEntry.th32ProcessID == PID)
46 return ProcessEntry.th32ParentProcessID;
47 } while (Process32Next(Snapshot, &ProcessEntry));
48
49 return InvalidParentProcessId;
50}
51
53{
54 const std::string config_path = ArkApi::Tools::GetCurrentDir() + "/config.json";
55 std::ifstream file{ config_path };
56 if (!file.is_open())
57 return false;
58
59 nlohmann::json config;
60 file >> config;
61 file.close();
62
63 return config["settings"].value("AttachToParent", false);
64}
65
67{
68 DWORD parentProcessId = GetParentProcessId();
69 bool attachToParent = AttachToParent();
70 if (GetConsoleWindow())
71 return;
72 if (attachToParent && parentProcessId && AttachConsole(parentProcessId))
73 return;
74 AllocConsole();
75 FILE* p_cout;
76 freopen_s(&p_cout, "conout$", "w", stdout);
77 SetConsoleOutputCP(CP_UTF8);
78}
79
80std::time_t GetFileWriteTime(const std::filesystem::path& filename)
81{
82 struct _stat64 fileInfo {};
83 if (_wstati64(filename.wstring().c_str(), &fileInfo) != 0)
84 {
85 throw std::runtime_error("Failed to get last write time.");
86 }
87 return fileInfo.st_mtime;
88}
89
91{
92 namespace fs = std::filesystem;
93
94 const auto now = std::chrono::system_clock::now();
95
96 const std::string current_dir = API::Tools::GetCurrentDir();
97
98 for (const auto& file : fs::directory_iterator(current_dir + "/logs"))
99 {
100 const std::time_t ftime = GetFileWriteTime(file);
101
102 if (file.path().filename() == "ArkApi.log")
103 {
104 tm tm{};
105 localtime_s(&tm, &ftime);
106
107 char time_str[64];
108 strftime(time_str, 64, "%Y-%m-%d-%H-%M", &tm);
109
110 const std::string new_name = "ArkApi_" + std::string(time_str) + ".log";
111 std::rename(file.path().generic_string().data(), (current_dir + "/logs/" + new_name).data());
112 }
113
114 const auto time_point = std::chrono::system_clock::from_time_t(ftime);
115
116 auto diff = std::chrono::duration_cast<std::chrono::hours>(now - time_point);
117 if (diff.count() >= 24 * 14) // 14 days
118 {
119 fs::remove(file);
120 }
121 }
122}
123
125{
126 namespace fs = std::filesystem;
127
128 const std::string current_dir = API::Tools::GetCurrentDir();
129
130 for (const auto& directory_entry : fs::directory_iterator(current_dir))
131 {
132 const auto& path = directory_entry.path();
133 if (is_directory(path))
134 {
135 const auto name = path.filename().stem().generic_string();
136 if (name == "ArkApi")
137 {
138 return "Ark";
139 }
140 if (name == "AtlasApi")
141 {
142 return "Atlas";
143 }
144 }
145 }
146
147 return "";
148}
149
150void Init()
151{
152 namespace fs = std::filesystem;
153
155
156 const std::string current_dir = API::Tools::GetCurrentDir();
157
158 if (!fs::exists(current_dir + "/logs"))
159 {
160 fs::create_directory(current_dir + "/logs");
161 }
162
164
165 Log::Get().Init("API");
166
167 const std::string game_name = DetectGame();
168 if (game_name == "Ark")
169 API::game_api = std::make_unique<API::ArkBaseApi>();
170 else if (game_name == "Atlas")
171 API::game_api = std::make_unique<API::AtlasBaseApi>();
172 else
173 Log::GetLog()->critical("Failed to detect game");
174
175 API::game_api->Init();
176}
177
178BOOL WINAPI DllMain(HINSTANCE hinst_dll, DWORD fdw_reason, LPVOID /*unused*/)
179{
180 if (fdw_reason == DLL_PROCESS_ATTACH)
181 {
182 DisableThreadLibraryCalls(hinst_dll);
183
184 CHAR sys_dir[MAX_PATH];
185 GetSystemDirectoryA(sys_dir, MAX_PATH);
186
187 char buffer[MAX_PATH];
188 sprintf_s(buffer, "%s\\version.dll", sys_dir);
189
190 m_hinst_dll = LoadLibraryA(buffer);
191 if (m_hinst_dll == nullptr)
192 {
193 return FALSE;
194 }
195
196 for (int i = 0; i < 17; i++)
197 {
198 mProcs[i] = reinterpret_cast<UINT_PTR>(GetProcAddress(m_hinst_dll, import_names[i]));
199 }
200
201 Init();
202 }
203 else if (fdw_reason == DLL_PROCESS_DETACH)
204 {
205 FreeLibrary(m_hinst_dll);
206 }
207
208 return TRUE;
209}
210
220extern "C" void VerFindFileA_wrapper();
221extern "C" void VerFindFileW_wrapper();
222extern "C" void VerInstallFileA_wrapper();
223extern "C" void VerInstallFileW_wrapper();
224extern "C" void VerLanguageNameA_wrapper();
225extern "C" void VerLanguageNameW_wrapper();
226extern "C" void VerQueryValueA_wrapper();
227extern "C" void VerQueryValueW_wrapper();
Definition Logger.h:9
static std::shared_ptr< spdlog::logger > & GetLog()
Definition Logger.h:22
static Log & Get()
Definition Logger.h:16
Definition json.hpp:4518
bool AttachToParent()
Definition version.cpp:52
void OpenConsole()
Definition version.cpp:66
void GetFileVersionInfoSizeW_wrapper()
void Init()
Definition version.cpp:150
LPCSTR import_names[]
Definition version.cpp:18
HINSTANCE m_hinst_dll
Definition version.cpp:15
void VerQueryValueA_wrapper()
void GetFileVersionInfoExW_wrapper()
void VerLanguageNameA_wrapper()
BOOL WINAPI DllMain(HINSTANCE hinst_dll, DWORD fdw_reason, LPVOID)
Definition version.cpp:178
void GetFileVersionInfoSizeExW_wrapper()
std::string DetectGame()
Definition version.cpp:124
void GetFileVersionInfoA_wrapper()
void VerInstallFileW_wrapper()
void VerLanguageNameW_wrapper()
void VerFindFileW_wrapper()
void GetFileVersionInfoByHandle_wrapper()
UINT_PTR mProcs[17]
Definition version.cpp:16
void GetFileVersionInfoW_wrapper()
std::time_t GetFileWriteTime(const std::filesystem::path &filename)
Definition version.cpp:80
void PruneOldLogs()
Definition version.cpp:90
void VerInstallFileA_wrapper()
DWORD GetParentProcessId()
Definition version.cpp:25
void GetFileVersionInfoExA_wrapper()
void VerQueryValueW_wrapper()
void GetFileVersionInfoSizeExA_wrapper()
void VerFindFileA_wrapper()
void GetFileVersionInfoSizeA_wrapper()