diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/hook_lib.sln b/hook_lib.sln index 8ae0a70..4f19910 100644 --- a/hook_lib.sln +++ b/hook_lib.sln @@ -1,31 +1,31 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.33130.400 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hook_lib", "hook_lib\hook_lib.vcxproj", "{D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Debug|x64.ActiveCfg = Debug|x64 - {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Debug|x64.Build.0 = Debug|x64 - {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Debug|x86.ActiveCfg = Debug|Win32 - {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Debug|x86.Build.0 = Debug|Win32 - {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Release|x64.ActiveCfg = Release|x64 - {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Release|x64.Build.0 = Release|x64 - {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Release|x86.ActiveCfg = Release|Win32 - {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {58937352-3EDA-4AEE-A7FD-C21D6955F38B} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.33130.400 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hook_lib", "hook_lib\hook_lib.vcxproj", "{D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Debug|x64.ActiveCfg = Debug|x64 + {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Debug|x64.Build.0 = Debug|x64 + {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Debug|x86.ActiveCfg = Debug|Win32 + {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Debug|x86.Build.0 = Debug|Win32 + {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Release|x64.ActiveCfg = Release|x64 + {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Release|x64.Build.0 = Release|x64 + {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Release|x86.ActiveCfg = Release|Win32 + {D84DCA02-7BEE-40E4-81D5-75EB0AA0A9D3}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {58937352-3EDA-4AEE-A7FD-C21D6955F38B} + EndGlobalSection +EndGlobal diff --git a/hook_lib/Main.cpp b/hook_lib/Main.cpp index 525d906..72283aa 100644 --- a/hook_lib/Main.cpp +++ b/hook_lib/Main.cpp @@ -1,1148 +1,1854 @@ -#include "Main.hpp" - -#include "csv.hpp" - -void* exception_handler; - -void backtrace(const char* func) { - const int trace_count = 15; - void* trace_back[trace_count]; - DWORD hash; - RtlCaptureStackBackTrace(1, trace_count, trace_back, &hash); - nlog("%s callstack: ", func); - printf("%s callstack: ", func); - for (int i = 0; i < trace_count; i++) { - if (i == trace_count - 1) { - nlog("%p\n", (uintptr_t)trace_back[i]); - printf("%p\n", (uintptr_t)trace_back[i]); - } - else { - nlog("%p:", (uintptr_t)trace_back[i]); - printf("%p:", (uintptr_t)trace_back[i]); - } - } -} - -int iTick = 0; -bool bFinished; -bool btoggle; - -uintptr_t xuid_generated; -int collision_ticker; -utils::hook::detour r_endframe; -void R_EndFrame_Detour() { - if (strcmp(Dvar_GetStringSafe("NSQLTTMRMP"), "mp_donetsk") == 0) { - *reinterpret_cast(0x14E385A68_g) = 80; - *reinterpret_cast(0x14E385A78_g) = 80; - if (collision_ticker == 60) { - btoggle = !btoggle; - *reinterpret_cast(0x145CC7555_g) = btoggle; // s_transientsCollisionMP_LobbyToGameStart - } - collision_ticker++; - } - else { - *reinterpret_cast(0x14E385A68_g) = 1000; - *reinterpret_cast(0x14E385A78_g) = 1000; - } - - if (!bFinished) { - if (iTick == 500) { - DWORD flOldProtect; - XUID xuid; - xuid.RandomXUID(); - utils::hook::set(0x144622BE0_g, 1); - - utils::hook::set(0x14E5C07C0_g, 0x11CB1243B8D7C31E | xuid.m_id * xuid.m_id); - utils::hook::set(0x14F05ACE8_g, 0x11CB1243B8D7C31E | xuid.m_id * xuid.m_id); - - utils::hook::set(0x14E5C07E8_g, 0x11CB1243B8D7C31E | (xuid.m_id * xuid.m_id) / 6); // s_presenceData - - utils::hook::set(0x14E371231_g, 1); - utils::hook::set(0x144622910_g, 2); - utils::hook::set(0x144622BE0_g, 1); - - utils::hook::set(*reinterpret_cast(0x14EE560B0_g) + 0x28, 0); - utils::hook::set(0x14E5C0730_g, 2); - - auto get_bnet_class = reinterpret_cast(0x141660280_g); - uintptr_t bnet_class = get_bnet_class(); - *(DWORD*)(bnet_class + 0x2F4) = 0x795230F0; - *(DWORD*)(bnet_class + 0x2FC) = 0; - *(BYTE*)(bnet_class + 0x2F8) = 31; - - printf("LOADED!\n"); - bFinished = true; - } - else { - iTick += 1; - } - } - - r_endframe.stub(); -} - -bool initiatedevgui; - -void CG_DrawWaterMark() { - float white[4] = { 1.0f, 1.0f, 1.0f, 0.2f }; - CL_DrawText(0x14EF2DEA0_g, "Fuck off activision you cunts", 0x7FFFFFFF, *reinterpret_cast(0x14EEB0C68_g), 0, 400.0f, 1, 1, 0.80000001, 0.80000001, white, 7); -} - -void CL_ScreenMP_DrawOverlay_Detour() { - auto DevGui_Draw = reinterpret_cast(0x1417E5CD0_g); - auto Con_DrawConsole = reinterpret_cast(0x1415AE0B0_g); - - Con_DrawConsole(0); - DevGui_Draw(0); - - if (show_watermark->current.enabled) { - CG_DrawWaterMark(); - } -} - -utils::hook::detour cl_createdevgui; -void CL_CreateDevGui_Detour(int fsMenuEntries, const char* modeCfg) { - auto DevGui_AddCommand = reinterpret_cast(0x1417E58B0_g); - auto DevGui_AddDvar = reinterpret_cast(0x1417E5940_g); - - cl_createdevgui.stub(fsMenuEntries, modeCfg); -} - -const char* username_Detour() { - if (player_name) { - return player_name->current.string; - } - else { - return "Unknown Name"; - } -} - -utils::hook::detour lui_cod_registerdvars; -void LUI_CoD_RegisterDvars_Detour() { - nlog("registering lui dvars\n"); - player_name = Dvar_RegisterString("player_name", "Player1", 0, "Sets the player name."); - sv_cheats = Dvar_RegisterBool("sv_cheats", false, 0, "Enables cheats to be used on a server"); - spawn_br_gas = Dvar_RegisterBool("spawn_br_gas", true, 0, "Disables gas in battle royale maps"); - show_watermark = Dvar_RegisterBool("show_watermark", false, 0, "Shows the watermark for codUPLOADER"); - - player_sustainammo = Dvar_RegisterBool("player_sustainAmmo", false, 0, "Firing weapon will not decrease clip ammo."); - - lui_cod_registerdvars.stub(); -} - -utils::hook::detour db_zones_performzoneload; -__int64 DB_Zones_PerformZoneLoad_Detour(bool processingPreloadedFiles, bool isBaseMap, bool wasPaused, int failureMode) { - failureMode = 1; - - return db_zones_performzoneload.stub<__int64>(processingPreloadedFiles, isBaseMap, wasPaused, failureMode); -} - -void CL_TransientsCollisionMP_SetTransientMode_Detour(int mode) { - if (strcmp(Dvar_GetStringSafe("NSQLTTMRMP"), "mp_donetsk") == 0) { - *reinterpret_cast(0x145CC7534_g) = 1; - } - else { - *reinterpret_cast(0x145CC7534_g) = mode; - } -} - -utils::hook::detour net_outofbanddata; -bool NET_OutOfBandData_Detour(int sock, netadr_t* adr, const unsigned __int8* format, int len) { - return net_outofbanddata.stub(sock, adr, format, len); -} - -utils::hook::detour g_cmdsmp_clientcommand; -void G_CmdsMP_ClientCommand_Detour(int clientNum) { - g_entities = *reinterpret_cast(0x14BC20F00_g); - - uintptr_t client = g_entities[clientNum].get(0x150); - - char command[1024]; - SV_Cmd_ArgvBuffer(0, command, 1024); - - if (client) { - if (strcmp(command, "noclip") == 0) { - if (CheatsOk(clientNum)) { - Cmd_Noclip_f(clientNum); - } - return; - } - if (strcmp(command, "give") == 0) { - if (CheatsOk(clientNum)) { - SV_Cmd_ArgvBuffer(1, command, 1024); - Weapon weap; - if (BG_Weapons_GetFullWeaponForName(command, &weap, BG_FindBaseWeaponForName)) { - if (SV_Cmd_Argc() == 3) { - SV_Cmd_ArgvBuffer(2, command, 1024); - weap.weaponCamo = atoi(command); - } - if (G_Weapon_GivePlayerWeapon(client, 0, &weap, 0, 0, 0)) { - G_Items_AddAmmo(client, &weap, 0, 9999, 1); - G_Weapon_SelectWeapon(clientNum, &weap); - } - } - } - } - if (strcmp(command, "ks_give") == 0) { - if (CheatsOk(clientNum)) { - SV_Cmd_ArgvBuffer(1, command, 1024); - scrContext_t* ctx = ScriptContext_Server(); - Scr_AddString(ctx, command); - - Scr_FreeThread(ctx, GScr_ExecEntThread(&g_entities[clientNum], 0x1B65FC, 1)); - } - } - if (strcmp(command, "bold_msg") == 0) { - char msgbuf[500]; - SV_Cmd_ArgvBuffer(1, command, 1024); - if (strlen(command) < 500) { - for (int i = 0; i < 30; i++) { - SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * i)); - if (ms_clients) { - snprintf(msgbuf, 500, "g \"%s\"", command); - ms_clients->SendServerCommand(1, msgbuf); - } - } - } - } - if (strcmp(command, "remove_barriers") == 0) { - if (CheatsOk(clientNum)) { - auto SL_ConvertToString = reinterpret_cast(0x14131AA20_g); - for (int i = 0; i < 1024; i++) { - int classname = g_entities[i].get(0x17C); - if (classname) { - if (strcmp(SL_ConvertToString(classname), "trigger_hurt") == 0 || - strcmp(SL_ConvertToString(classname), "trigger_multiple") == 0 || - strcmp(SL_ConvertToString(classname), "trigger_damage") == 0) { - auto G_SetOrigin = reinterpret_cast(0x140FD4CC0_g); - vec3_t gone = { 0, 0, -9999999 }; - G_SetOrigin(&g_entities[i], &gone, true, true); - } - } - } - for (int i = 0; i < 30; i++) { - SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * i)); - if (ms_clients) { - ms_clients->SendServerCommand(1, "g \"Death barriers removed!\""); - } - } - } - } - if (strcmp(command, "viewpos") == 0) { - if (CheatsOk(clientNum)) { - char msgbuf[500]; - SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * clientNum)); - if (ms_clients) { - snprintf(msgbuf, 500, "f \"viewpos: (%.2f, %.2f, %.2f)\"", g_entities[clientNum].r_currentOrigin[0], g_entities[clientNum].r_currentOrigin[1], g_entities[clientNum].r_currentOrigin[2]); - ms_clients->SendServerCommand(1, msgbuf); - } - } - } - } - - g_cmdsmp_clientcommand.stub(clientNum); -} - -utils::hook::detour cl_inputmp_execbinding; -void CL_InputMP_ExecBinding_Detour(int localClientNum, int kb, int key, int forceNotify) { - switch (key) { - case K_N: - CL_Main_AddReliableCommand("noclip"); - break; - } - - cl_inputmp_execbinding.stub(localClientNum, kb, key, forceNotify); -} - -void Cmd_Exec_Internal(bool isSuperUser) { - const char* cmdbuf; - const char* file; - auto DB_FindXAssetHeader = reinterpret_cast(0x1411AA890_g); - auto DB_ReadRawFile = reinterpret_cast(0x141297140_g); - auto Core_strcpy_truncate = reinterpret_cast(0x142036A90_g); - auto Com_DefaultExtension = reinterpret_cast(0x1413F1AE0_g); - char path[64]; - - if (cmd_args->argc[cmd_args->nesting] == 2) - { - Core_strcpy_truncate(path, 64, *(cmd_args->argv[cmd_args->nesting] + 1)); - Com_DefaultExtension(path, 64, ".cfg"); - if (DB_FindXAssetHeader(ASSET_TYPE_RAWFILE, path, 0)) - { - if (!DB_ReadRawFile(0, cmd_args->controllerIndex[cmd_args->nesting], path, isSuperUser)) - { - if (cmd_args->argc[cmd_args->nesting] <= 1) - file = ""; - else - file = *(cmd_args->argv[cmd_args->nesting] + 1); - printf("couldn't exec %s\n", file); - } - } - else - { - FS_ReadFile(path, &cmdbuf); - LUI_CoD_LuaCall_ExecNow(*reinterpret_cast(0x151868880_g), cmdbuf); - } - } - else - { - printf(0, "exec : execute a script file\n"); - } -} - -utils::hook::detour gscr_spawnbrcircle; -void GScr_SpawnBrCircle_Detour(uintptr_t scrContext) { - if (spawn_br_gas->current.enabled) { - gscr_spawnbrcircle.stub(scrContext); - } -} - -void entry_point() { - XUID xuid; - xuid.RandomXUID(); - - printf("%i\n", xuid.m_id); - - r_endframe.create(0x141966950_g, R_EndFrame_Detour); - utils::hook::jump(0x141297580_g, Cmd_Exec_Internal); - utils::hook::jump(0x1415E1340_g, CL_ScreenMP_DrawOverlay_Detour); - utils::hook::jump(0x1413FD3A0_g, username_Detour); - - db_zones_performzoneload.create(0x140F677A0_g, DB_Zones_PerformZoneLoad_Detour); - - g_cmdsmp_clientcommand.create(0x14120B6A0_g, G_CmdsMP_ClientCommand_Detour); - cl_inputmp_execbinding.create(0x1415E1AB0_g, CL_InputMP_ExecBinding_Detour); - gscr_spawnbrcircle.create(0x141243AB0_g, GScr_SpawnBrCircle_Detour); - - utils::hook::jump(0x140D6B7D0_g, CL_TransientsCollisionMP_SetTransientMode_Detour); - - printf("hooked!\n"); -} - -extern "C" __declspec(dllexport) int DiscordCreate() { - CreateThread(0, 0xA0, (LPTHREAD_START_ROUTINE)entry_point, 0, 0, 0); - return 1; -} - -utils::hook::detour cl_keys_event; -void CL_Keys_Event_Detour(int localClientNum, int key, bool down, unsigned int time, int virtualKey, int controllerIndex) { - auto Con_ToggleConsole = reinterpret_cast(0x1415B18C0_g); - auto DevGui_Toggle = reinterpret_cast(0x1417E9DA0_g); - - if (down) { - switch (key) { - case K_GRAVE: - Con_ToggleConsole(); - return; - break; - case K_F1: - DevGui_Toggle(); - return; - break; - } - } - - cl_keys_event.stub(localClientNum, key, down, time, virtualKey, controllerIndex); -} - -utils::hook::detour PM_WeaponUseAmmo; -void PM_WeaponUseAmmo_Detour(__int64 playerstate, Weapon* weapon, char a3, int a4, int hand) { - if (!player_sustainammo->current.enabled) { - PM_WeaponUseAmmo.stub(playerstate, weapon, a3, a4, hand); - } -} - -utils::hook::detour dvar_registerbool; -dvar_t* Dvar_RegisterBool_Detour(const char* dvarName, bool value, unsigned int flags, const char* description) { - if (strcmp(dvarName, "LSTQOKLTRN") == 0) { - nlog("dvar registered!\n"); - value = true; - } - if (strcmp(dvarName, "MPSSOTQQPM") == 0) { - nlog("dvar registered!\n"); - value = true; - } - dvar_t* ret = dvar_registerbool.stub(dvarName, value, flags, description); - return ret; -} - -utils::hook::detour dvar_registerstring; -dvar_t* Dvar_RegisterString_Detour(const char* dvarName, const char* value, unsigned int flags, const char* description) { - return dvar_registerstring.stub(dvarName, value, flags, description); -} - -utils::hook::detour seh_stringed_getstring; -const char* SEH_StringEd_GetString_Detour(const char* pszReference) { - const char* ret = seh_stringed_getstring.stub(pszReference); - - if (!pszReference[1]) - { - if ((*pszReference & 0x80) != 0) - return "t"; - return pszReference; - } - - if ( - strstr(pszReference, "LUA_MENU/MAPNAME_DEADZONE") || - strstr(pszReference, "LUA_MENU/MAPNAME_M_CAGE") || - strstr(pszReference, "LUA_MENU/MAPNAME_CAVE_AM") || - strstr(pszReference, "LUA_MENU/MAPNAME_CAVE") || - strstr(pszReference, "LUA_MENU/MAPNAME_M_CARGO") || - strstr(pszReference, "LUA_MENU/MAPNAME_CRASH2") || - strstr(pszReference, "LUA_MENU/MAPNAME_M_OVERUNDER") || - strstr(pszReference, "LUA_MENU/MAPNAME_EUPHRATES") || - strstr(pszReference, "LUA_MENU/MAPNAME_RAID") || - strstr(pszReference, "LUA_MENU/MAPNAME_M_SHOWERS") || - strstr(pszReference, "LUA_MENU/MAPNAME_RUNNER_AM") || - strstr(pszReference, "LUA_MENU/MAPNAME_RUNNER") || - strstr(pszReference, "LUA_MENU/MAPNAME_HACKNEY_AM") || - strstr(pszReference, "LUA_MENU/MAPNAME_HACKNEY_YARD") || - strstr(pszReference, "LUA_MENU/MAPNAME_M_HILL") || - strstr(pszReference, "LUA_MENU/MAPNAME_PICCADILLY") || - strstr(pszReference, "LUA_MENU/MAPNAME_M_PINE") || - strstr(pszReference, "LUA_MENU/MAPNAME_SPEAR_AM") || - strstr(pszReference, "LUA_MENU/MAPNAME_SPEAR") || - strstr(pszReference, "LUA_MENU/MAPNAME_PETROGRAD") || - strstr(pszReference, "LUA_MENU/MAPNAME_M_STACK") || - strstr(pszReference, "LUA_MENU/MAPNAME_VACANT")) { - return "^1no work"; - } - - return ret; -} - -char buffer[0x5000]; - -utils::hook::detour db_loadxfile; -int DB_LoadXFile_Detour(const char* zoneName, uintptr_t zoneMem, uintptr_t assetList, int zoneFlags, bool wasPaused, int failureMode, uintptr_t outSignature) { - return db_loadxfile.stub(zoneName, zoneMem, assetList, zoneFlags, wasPaused, failureMode, outSignature); -} - -utils::hook::detour CL_TransientsMP_ProcessLoadingQueue; -char CL_TransientsMP_ProcessLoadingQueue_Detour() { - return CL_TransientsMP_ProcessLoadingQueue.stub(); -} - -utils::hook::detour partyhost_startprivateparty; -void PartyHost_StartPrivateParty_Detour(int localClientNum, int localControllerIndex, bool currentlyActive, int hostType) { - Cbuf_AddText("exec autoexec.cfg"); - - partyhost_startprivateparty.stub(localClientNum, localControllerIndex, currentlyActive, hostType); -} - -bool Live_IsUserSignedInToDemonware_Detour() { - return true; -} - -int dwGetLogOnStatus_Detour() { - return 2; -} - -int LiveStorage_GetActiveStatsSource_Detour() { - return 1; -} - -void set_byte_f() { - char command[500]; - if (Cmd_Argc() == 3) { - Cmd_ArgvBuffer(1, command, 500); - uintptr_t address = atoll(command) + base; - Cmd_ArgvBuffer(2, command, 500); - utils::hook::set(address, atoi(command)); - } -} - -void set_short_f() { - char command[500]; - if (Cmd_Argc() == 3) { - Cmd_ArgvBuffer(1, command, 500); - uintptr_t address = atoll(command) + base; - Cmd_ArgvBuffer(2, command, 500); - utils::hook::set(address, atol(command)); - } -} - -void set_int_f() { - char command[500]; - if (Cmd_Argc() == 3) { - Cmd_ArgvBuffer(1, command, 500); - uintptr_t address = atoll(command) + base; - Cmd_ArgvBuffer(2, command, 500); - utils::hook::set(address, _atoi64(command)); - } -} - -void set_pointer_f() { - char command[500]; - if (Cmd_Argc() == 3) { - Cmd_ArgvBuffer(1, command, 500); - uintptr_t address = atoll(command) + base; - Cmd_ArgvBuffer(2, command, 500); - utils::hook::set(address, _atoi64(command)); - } -} - -void Cmd_Quit_f() { - ExitProcess(0x1); -} - -void Cmd_OpenMenu_f() { - char command[500]; - if (Cmd_Argc() == 2) { - auto LUI_OpenMenu = reinterpret_cast(0x141B9BDB0_g); - Cmd_ArgvBuffer(1, command, 500); - LUI_OpenMenu(0, command, true, false, false); - } -} - -void Cmd_AddBot_f() { - auto SV_ClientMP_AddTestClient = reinterpret_cast(0x14136E570_g); - SV_ClientMP_AddTestClient(); -} - -void Cmd_DDLDump_f() { - int cur = 0; - DDLFile* g_assets = *(DDLFile**)(0x14B8F5C48_g); - if (g_assets[cur].name) { - while (g_assets[cur].name != 0 && g_assets[cur].ddlDef != 0) { - nlog("%s\n", g_assets[cur].name); - for (int istruct = 0; istruct < g_assets[cur].ddlDef->structCount; istruct++) { - nlog("struct %s { //count: %i\n", g_assets[cur].ddlDef->structList[istruct].name, g_assets[cur].ddlDef->structList[istruct].memberCount); - for (int imember = 0; imember < g_assets[cur].ddlDef->structList[istruct].memberCount; imember++) { - if (g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize == 1) { - switch (g_assets[cur].ddlDef->structList[istruct].members[imember].type) { - case DDL_STRING_TYPE: nlog("\tconst char* %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_FIXEDPOINT_TYPE: - case DDL_FLOAT_TYPE: nlog("\tfloat %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_BYTE_TYPE: nlog("\tbyte %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_SHORT_TYPE: nlog("\tshort %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_INT_TYPE: nlog("\tint %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_UINT_TYPE: nlog("\tuint %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_PAD_TYPE: nlog("\tchar %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_HASH_TYPE: nlog("\thash %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_UINT64_TYPE: nlog("\tuint64_t %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_ENUM_TYPE: nlog("\t%s %s;\n", g_assets[cur].ddlDef->enumList[g_assets[cur].ddlDef->structList[istruct].members[imember].externalIndex].name, g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - case DDL_STRUCT_TYPE: nlog("\t%s %s;\n", g_assets[cur].ddlDef->structList[g_assets[cur].ddlDef->structList[istruct].members[imember].externalIndex].name, g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - default:nlog("\t%s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - } - } - else { - switch (g_assets[cur].ddlDef->structList[istruct].members[imember].type) { - case DDL_FIXEDPOINT_TYPE: - case DDL_FLOAT_TYPE: nlog("\tfloat %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_STRING_TYPE: nlog("\tconst char* %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_BYTE_TYPE: nlog("\tbyte %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_SHORT_TYPE: nlog("\tshort %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_INT_TYPE: nlog("\tint %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_UINT_TYPE: nlog("\tuint %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_PAD_TYPE: nlog("\tchar %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_HASH_TYPE: nlog("\thash %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_ENUM_TYPE: nlog("\t%s %s[%i];\n", g_assets[cur].ddlDef->enumList[g_assets[cur].ddlDef->structList[istruct].members[imember].externalIndex].name, g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_UINT64_TYPE: nlog("\tuint64_t %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - case DDL_STRUCT_TYPE: nlog("\t%s %s[%i];\n", g_assets[cur].ddlDef->structList[g_assets[cur].ddlDef->structList[istruct].members[imember].externalIndex].name, g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; - default:nlog("\t%s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; - } - } - } - nlog("}\n"); - } - for (int ienum = 0; ienum < g_assets[cur].ddlDef->enumCount; ienum++) { - nlog("enum %s { //count: %i\n", g_assets[cur].ddlDef->enumList[ienum].name, g_assets[cur].ddlDef->enumList[ienum].memberCount); - for (int imember = 0; imember < g_assets[cur].ddlDef->enumList[ienum].memberCount; imember++) { - nlog("\t%s,\n", g_assets[cur].ddlDef->enumList[ienum].members[imember]); - } - nlog("}\n\n\n\n"); - } - cur++; - } - } -} - -void Cmd_WeaponDefDump_f() { - //Globals - uintptr_t* bg_weaponCompleteDefs = reinterpret_cast(0x14C6EC870_g); - - nlog("DUMPING WEAPON DEFINITIONS!!! --- \n"); - - for (int i = 0; i < 550; i++) { - WeaponCompleteDef* weap = reinterpret_cast(bg_weaponCompleteDefs[i]); - - if (!weap) continue; - nlog("szInternalName: %s\n", weap->szInternalName); - nlog("szDisplayName: %s\n", weap->szDisplayName); - } - - nlog("FINISHED WEAPON DEFINITION DUMP YAY!!! --- \n"); -} - -void Cmd_ViewVehicleEnts_f() { - auto SL_ConvertToString = reinterpret_cast(0x14131AA20_g); - for (int i = 0; i < 1024; i++) { - int classname = g_entities[i].get(0x17C); - if (classname) { - const char* s_classname = SL_ConvertToString(classname); - if (g_entities[i].get(0x160)) { - nlog("vehicle %s\n", s_classname); - } - } - } -} - -void Cmd_LoadoutSave_f() { - auto Cmd_LocalControllerIndex = reinterpret_cast(0x141298040_g); - auto LiveStorage_GetActiveStatsSource = reinterpret_cast(0x1412A1EB0_g); - auto LiveStorage_CreateDDLContext = reinterpret_cast(0x1412A13C0_g); - auto DDL_MoveToPath = reinterpret_cast(0x1420524F0_g); - //auto Com_DDL_ConvertNavStringToHash = reinterpret_cast(0x14129EE80_g); - //auto LiveStorage_InitializeDDLStateForStatsGroup = reinterpret_cast(0x1410CAD70_g); - auto Com_PlayerData_GetStatsBlob = reinterpret_cast(0x1410CA7A0_g); - auto DDL_GetType = reinterpret_cast(0x142051DD0_g); - auto DDL_GetString = reinterpret_cast(0x142051CD0_g); - auto DDL_GetEnum = reinterpret_cast(0x1420519E0_g); - auto DDL_GetInt = reinterpret_cast(0x142051BF0_g); - auto DDL_GetRootState = reinterpret_cast(0x142051C70_g); - auto CL_PlayerData_GetDDLBuffer = reinterpret_cast(0x1415C7940_g); - auto Com_DDL_LoadAsset = reinterpret_cast(0x14129F3B0_g); - auto Com_ParseNavStrings = reinterpret_cast(0x1412A02E0_g); - auto Com_DDL_CreateContext = reinterpret_cast(0x14129EEC0_g); - - DDLContext context; - DDLState state; - char buffer[200]; - char* navStrings[32]{}; - int navStringCount; - if (CL_PlayerData_GetDDLBuffer(&context, 0, 1, 4)) { - DDL_GetRootState(&state, context.def); - sprintf_s(buffer, "loadouts.0.name"); - Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); - if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) { - printf("%s\n", DDL_GetString(&state, &context)); - } - } -} - -void SaveOperatorSkins() -{ - auto Cmd_LocalControllerIndex = reinterpret_cast(0x141298040_g); - auto LiveStorage_GetActiveStatsSource = reinterpret_cast(0x1412A1EB0_g); - auto LiveStorage_CreateDDLContext = reinterpret_cast(0x1412A13C0_g); - auto DDL_MoveToPath = reinterpret_cast(0x1420524F0_g); - //auto Com_DDL_ConvertNavStringToHash = reinterpret_cast(0x14129EE80_g); - //auto LiveStorage_InitializeDDLStateForStatsGroup = reinterpret_cast(0x1410CAD70_g); - auto Com_PlayerData_GetStatsBlob = reinterpret_cast(0x1410CA7A0_g); - auto DDL_GetType = reinterpret_cast(0x142051DD0_g); - auto DDL_GetString = reinterpret_cast(0x142051CD0_g); - auto DDL_GetEnum = reinterpret_cast(0x1420519E0_g); - auto DDL_GetInt = reinterpret_cast(0x142051BF0_g); - auto DDL_GetRootState = reinterpret_cast(0x142051C70_g); - auto CL_PlayerData_GetDDLBuffer = reinterpret_cast(0x1415C7940_g); - auto Com_DDL_LoadAsset = reinterpret_cast(0x14129F3B0_g); - auto Com_ParseNavStrings = reinterpret_cast(0x1412A02E0_g); - auto Com_DDL_CreateContext = reinterpret_cast(0x14129EEC0_g); - auto StringTable_GetColumnValueForRow = reinterpret_cast(0x1413E2B40_g); - - DDLContext context; - DDLState state; - char buffer[200]; - char* navStrings[32]{}; - int navStringCount; - char path[MAX_PATH + 1]; - strcpy(path, Dvar_GetStringSafe("LOOQOTRNTN")); - strcat(path, "\\players\\inventory.json"); - nlohmann::json inventoryJson; - if (CL_PlayerData_GetDDLBuffer(&context, 0, 1, 4)) { - auto operatorCsv = DB_FindXAssetHeader(ASSET_TYPE_STRINGTABLE, "operators.csv", 0).stringTable; - for (int i = 0; i < operatorCsv->rowCount; ++i) { - const char* operatorName = StringTable_GetColumnValueForRow(operatorCsv, i, 1); - DDL_GetRootState(&state, context.def); - sprintf_s(buffer, "customizationSetup.operatorCustomization.%s.skin", operatorName); - Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); - if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) - { - inventoryJson["Operator"]["OperatorSkin"][operatorName] = DDL_GetInt(&state, &context); - } - } - for (int i = 0; i < 2; ++i) - { - DDL_GetRootState(&state, context.def); - sprintf_s(buffer, "customizationSetup.operators.%d", i); - Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); - if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) - { - inventoryJson["Operator"]["SelectedOperator"][i] = DDL_GetEnum(&state, &context); - } - } - std::ofstream JsonOut(path); - JsonOut << inventoryJson; - } -} - -int LuaShared_LuaCall_IsDemoBuild_Detour(uintptr_t luaVM) { - lua_pushboolean(luaVM, 1); - return 1; -} - -utils::hook::detour dvar_findvarbyname; -dvar_t* Dvar_FindVarByName_Detour(const char* dvarName) { - dvar_t* ret = dvar_findvarbyname.stub(dvarName); - return ret; -} - -utils::hook::detour db_findxassetheader; -XAssetHeader DB_FindXAssetHeader_Detour(XAssetType type, const char* givenName, int allowCreateDefault) { - XAssetHeader temp = db_findxassetheader.stub(type, givenName, allowCreateDefault); - - //if (type == ASSET_TYPE_XMODEL) { - // if (strcmp(temp.model->name, "head_mp_western_ghost_1_1") == 0) { - // return db_findxassetheader.stub(type, "head_opforce_juggernaut", allowCreateDefault); - // } - // if (strcmp(temp.model->name, "mp_western_vm_arms_ghost_1_1") == 0) { - // return db_findxassetheader.stub(type, "viewhands_opforce_juggernaut", allowCreateDefault); - // } - // if (strcmp(temp.model->name, "body_mp_western_ghost_1_1_lod1") == 0) { - // return db_findxassetheader.stub(type, "body_opforce_juggernaut_mp_lod1", allowCreateDefault); - // } - // if (strcmp(temp.model->name, "military_carepackage_01_friendly") == 0) { - // return db_findxassetheader.stub(type, "opforce_juggernaut_prop_static", allowCreateDefault); - // } - // if (strstr(temp.model->name, "veh8_mil_air_")) { - // return db_findxassetheader.stub(type, "veh8_mil_air_acharlie130", allowCreateDefault); - // } - //} - - //if (type == ASSET_TYPE_STRINGTABLE) - //{ - // char path[MAX_PATH + 1]; - // memset(path, 0, MAX_PATH + 1); - // snprintf(path, MAX_PATH + 1, "%s\\players\\raw\\%s", Dvar_GetStringSafe("LOOQOTRNTN"), givenName); - // if (file_exists(path)) - // { - // printf("replacing file %s\n", givenName); - - // csv::CSVFileInfo info = csv::get_file_info(path); - // StringTable* table = temp.stringTable; - // table->rowCount = info.n_rows; - // table->columnCount = info.n_cols; - - // //table->name = - // } - //} - - return temp; -} - -utils::hook::detour db_getrawbufferinflate; -const char* DB_GetRawBufferInflate_Detour(const char* file, char* buffer, int length) { - char path[MAX_PATH + 1]; - memset(path, 0, MAX_PATH + 1); - std::string filecontents; - std::string curline; - snprintf(path, MAX_PATH + 1, "%s\\players\\raw\\%s", Dvar_GetStringSafe("LOOQOTRNTN"), file); - if (file_exists(path)) { - printf("replacing file %s\n", file); - std::ifstream myfile; - myfile.open(path); - filecontents = ""; - while (myfile) { - std::getline(myfile, curline); - filecontents += curline + "\n"; - } - myfile.close(); - strcpy(buffer, filecontents.c_str()); - return filecontents.c_str();; - } - printf("loading %s\n", file); - return db_getrawbufferinflate.stub(file, buffer, length); -} - -const char* _va(const char* format, ...) { - char _buf[2048]; - va_list ap; - - va_start(ap, format); - vsnprintf(_buf, 2048, format, ap); - _buf[2047] = 0; - return _buf; -} -SpawnPointEntityRecord* g_customSpawns; -char g_customEntityString[0xFFFFFFF]; -utils::hook::detour load_mapentsasset; -void Load_MapEntsAsset_Detour(XAssetHeader* mapEnts) { - auto Scr_AllocGlobalString = reinterpret_cast(0x14131B2C0_g); - char path[MAX_PATH + 1]; - snprintf(path, MAX_PATH + 1, "%s\\players\\raw\\%s", Dvar_GetStringSafe("LOOQOTRNTN"), mapEnts->image->name); - if (file_exists(path)) { - printf("loading %s\n", path); - HANDLE mapEntsFile = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); - int numberOfBytesRead = GetFileSize(mapEntsFile, NULL); - if (mapEntsFile != INVALID_HANDLE_VALUE) - { - memset(g_customEntityString, 0, 0xFFFFFFF); - ReadFile(mapEntsFile, g_customEntityString, numberOfBytesRead, (LPDWORD)&numberOfBytesRead, 0); - mapEnts->mapEnts->entityString = g_customEntityString; - mapEnts->mapEnts->numEntityChars = strlen(g_customEntityString) + 1; - CloseHandle(mapEntsFile); - memset(path, 0, MAX_PATH + 1); - snprintf(path, MAX_PATH + 1, "%s\\players\\raw\\%s.spawnlist", Dvar_GetStringSafe("LOOQOTRNTN"), mapEnts->image->name); - if (!file_exists(path)) { - } - else { - nlohmann::json json; - std::ifstream file(path); - file >> json; - file.close(); - mapEnts->mapEnts->spawnList.spawnsCount = json["spawnList"]["spawnsCount"]; - for (int i = 0; i < mapEnts->mapEnts->spawnList.spawnsCount; i++) { - mapEnts->mapEnts->spawnList.spawns[i].index = json["spawnList"][_va("spawns[%i]", i)]["index"]; - mapEnts->mapEnts->spawnList.spawns[i].name = Scr_AllocGlobalString(std::string(json["spawnList"][_va("spawns[%i]", i)]["name"]).c_str()); - mapEnts->mapEnts->spawnList.spawns[i].target = Scr_AllocGlobalString(std::string(json["spawnList"][_va("spawns[%i]", i)]["target"]).c_str()); - mapEnts->mapEnts->spawnList.spawns[i].script_noteworthy = Scr_AllocGlobalString(std::string(json["spawnList"][_va("spawns[%i]", i)]["script_noteworthy"]).c_str()); - - mapEnts->mapEnts->spawnList.spawns[i].origin.v[0] = json["spawnList"][_va("spawns[%i]", i)]["origin"][0]; - mapEnts->mapEnts->spawnList.spawns[i].origin.v[1] = json["spawnList"][_va("spawns[%i]", i)]["origin"][1]; - mapEnts->mapEnts->spawnList.spawns[i].origin.v[2] = json["spawnList"][_va("spawns[%i]", i)]["origin"][2]; - - mapEnts->mapEnts->spawnList.spawns[i].angles.v[0] = json["spawnList"][_va("spawns[%i]", i)]["angles"][0]; - mapEnts->mapEnts->spawnList.spawns[i].angles.v[1] = json["spawnList"][_va("spawns[%i]", i)]["angles"][1]; - mapEnts->mapEnts->spawnList.spawns[i].angles.v[2] = json["spawnList"][_va("spawns[%i]", i)]["angles"][2]; - } - } - } - } - - printf("%s\n", mapEnts->mapEnts->clientTrigger.triggerString); - - load_mapentsasset.stub(mapEnts); -} - -utils::hook::detour load_clipmapasset; -void Load_ClipMapAsset_Detour(XAssetHeader* clipMap) { - load_clipmapasset.stub(clipMap); -} -char g_customBuffer[0x18000]; -utils::hook::detour db_getrawbuffer; -void DB_GetRawBuffer_Detour(const RawFile* rawfile, char* buf, int size) { - char path[MAX_PATH + 1]; - snprintf(path, MAX_PATH + 1, "%s\\players\\raw\\%s", Dvar_GetStringSafe("LOOQOTRNTN"), rawfile->name); - if (file_exists(path)) { - HANDLE mapEntsFile = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); - int numberOfBytesRead = GetFileSize(mapEntsFile, NULL); - if (mapEntsFile != INVALID_HANDLE_VALUE) - { - ReadFile(mapEntsFile, g_customBuffer, numberOfBytesRead, (LPDWORD)&numberOfBytesRead, 0); - CloseHandle(mapEntsFile); - strcpy(buf, g_customBuffer); - printf("replacing %s\n", rawfile->name); - } - return; - } - printf("loading %s\n", rawfile->name); - - db_getrawbuffer.stub(rawfile, buf, size); -} - -utils::hook::detour db_pollfastfilestate; -int DB_PollFastfileState_Detour(const char* zoneName) { - if (strcmp(zoneName, "mp_donetsk_cg_ls_tr") == 0) { - return 2; - } - - //printf("%s\n", zoneName); - - return db_pollfastfilestate.stub(zoneName); -} - -utils::hook::detour load_xmodelasset; -void Load_XModelAsset_Detour(XAssetHeader* model) { - load_xmodelasset.stub(model); -} - -utils::hook::detour ddl_setuint; -bool DDL_SetUInt_Detour(const DDLState* state, DDLContext* ddlContext, unsigned int val) { - //ddlContext->obfuscated = false; - //printf("%p - %p\n", state->offset, (uintptr_t)(ddlContext->buff) + state->offset); - - return ddl_setuint.stub(state, ddlContext, val); -} - -void SV_CmdsMP_FastRestart_f() { - auto SV_CmdsMP_RequestMapRestart = reinterpret_cast(0x14136C310_g); - SV_CmdsMP_RequestMapRestart(1, 0); -} - -void* exception_handler_handle; -BOOL WINAPI DllMain(HMODULE hModule, DWORD Reason, LPVOID lpVoid) { - g_Addrs.ModuleBase = (uintptr_t)(GetModuleHandle(0)); - utils::hook::set(0x1403061A0_g, 0xC3); // Mystery function 1 - if (Reason == DLL_PROCESS_ATTACH) { - AllocConsole(); - FILE* Dummy; - freopen_s(&Dummy, "CONOUT$", "w", stdout); - freopen_s(&Dummy, "CONIN$", "r", stdin); - - utils::nt::library game{}; - utils::nt::library user32("user32.dll"); - utils::nt::library ntdll("ntdll.dll"); - utils::nt::library kernel32("kernel32.dll"); - - va = (const char* (*)(const char*, ...))0x1413F3010_g; //j_va - - nlog("Base Address: %p\n", base); - - cmd_args = (CmdArgs*)(0x14D20CBD0_g); - - //utils::hook::jump(0x141BD3360_g, sub_141BD3360_Detour); - - //sub_141BD3360.create(0x141BD3360_g, sub_141BD3360_Detour); - - utils::hook::copy(0x1530AD525_g, data_buf, 0x12856B); // Splash screen data - - Cmd_AddCommandInternal("set_byte", set_byte_f, &set_byte_f_VAR); - Cmd_AddCommandInternal("set_short", set_short_f, &set_short_f_VAR); - Cmd_AddCommandInternal("set_int", set_int_f, &set_int_f_VAR); - Cmd_AddCommandInternal("set_pointer", set_pointer_f, &set_pointer_f_VAR); - Cmd_AddCommandInternal("quit", Cmd_Quit_f, &quit_f_VAR); - Cmd_AddCommandInternal("openmenu", Cmd_OpenMenu_f, &openmenu_f_VAR); - //Cmd_AddCommandInternal("addbot", Cmd_AddBot_f, &addbot_f_VAR); - Cmd_AddCommandInternal("ddldump", Cmd_DDLDump_f, &ddldump_f_VAR); - Cmd_AddCommandInternal("weapondefdump", Cmd_WeaponDefDump_f, &weapondefdump_f_VAR); - //Cmd_AddCommandInternal("view_vehicle_ents", Cmd_ViewVehicleEnts_f, &view_vehicle_ents_f_VAR); - //Cmd_AddCommandInternal("loadout_save", Cmd_LoadoutSave_f, &loadout_save_f_VAR); - Cmd_AddCommandInternal("loadout_save", SaveOperatorSkins, &loadout_save_f_VAR); - Cmd_AddCommandInternal("fast_restart", SV_CmdsMP_FastRestart_f, &FastRestart_f_VAR); - - // patch ui_maxclients limit - utils::hook::nop(0x140F30210_g, 5); - utils::hook::nop(0x14119E51D_g, 5); - utils::hook::nop(0x14136B8F8_g, 5); - utils::hook::nop(0x1416029F0_g, 5); - utils::hook::nop(0x1419E19A3_g, 5); - - // patch party_maxplayers limit - utils::hook::nop(0x140F252EE_g, 5); - utils::hook::nop(0x14119D23F_g, 5); - utils::hook::nop(0x1410769B9_g, 5); - utils::hook::set(0x1410769B9_g, 0xC3); - utils::hook::nop(0x140F24B4B_g, 5); - utils::hook::set(0x140F24B4B_g, 0xC3); - utils::hook::nop(0x1416029E2_g, 5); - utils::hook::nop(0x14119E52B_g, 5); - utils::hook::nop(0x140f252EE_g, 5); - utils::hook::nop(0x14119F13A_g, 5); - utils::hook::nop(0x1410D32E2_g, 5); - - // Fix crash exploit - utils::hook::nop(0x14136D0EA_g, 5); - - db_findxassetheader.create(0x1411AA890_g, DB_FindXAssetHeader_Detour); - db_getrawbufferinflate.create(0x1412C2AE0_g, DB_GetRawBufferInflate_Detour); - ddl_setuint.create(0x1420529C0_g, DDL_SetUInt_Detour); - //db_pollfastfilestate.create(0x1411ADD00_g, DB_PollFastfileState_Detour); - - load_mapentsasset.create(0x140F61690_g, Load_MapEntsAsset_Detour); - load_clipmapasset.create(0x140F60F40_g, Load_ClipMapAsset_Detour); - load_xmodelasset.create(0x140F62290_g, Load_XModelAsset_Detour); - //load_ttfasset.create(0x140F61F40_g, Load_TTFAsset_Detour); - - db_getrawbuffer.create(0x1412C29A0_g, DB_GetRawBuffer_Detour); - - utils::hook::jump(0x141528490_g, Live_IsUserSignedInToDemonware_Detour); - utils::hook::jump(0x1417EC930_g, dwGetLogOnStatus_Detour); - utils::hook::jump(0x1412A1EB0_g, LiveStorage_GetActiveStatsSource_Detour); - //utils::hook::jump(0x1419B96A0_g, LuaShared_LuaCall_IsDemoBuild_Detour); - - dvar_findvarbyname.create(0x1413E63A0_g, Dvar_FindVarByName_Detour); - - db_loadxfile.create(0x1411A79F0_g, DB_LoadXFile_Detour); - CL_TransientsMP_ProcessLoadingQueue.create(0x1415F7BF0_g, CL_TransientsMP_ProcessLoadingQueue_Detour); - - lui_cod_registerdvars.create(0x1419D4500_g, LUI_CoD_RegisterDvars_Detour); - net_outofbanddata.create(0x1412BB350_g, NET_OutOfBandData_Detour); - cl_keys_event.create(0x1415BEB80_g, CL_Keys_Event_Detour); - dvar_registerbool.create(0x1413E7670_g, Dvar_RegisterBool_Detour); - dvar_registerstring.create(0x1413E7A70_g, Dvar_RegisterString_Detour); - seh_stringed_getstring.create(0x1413CC2A0_g, SEH_StringEd_GetString_Detour); - - cl_createdevgui.create(0x1415B2080_g, CL_CreateDevGui_Detour); - partyhost_startprivateparty.create(0x14119F0D0_g, PartyHost_StartPrivateParty_Detour); - - PM_WeaponUseAmmo.create(0x141155AF0_g, PM_WeaponUseAmmo_Detour); //TODO: add sv_cheat validation - - clientUIActives = (clientUIActive_t*)(0x14EEF1280_g); - } - - return TRUE; -} - -void nlog(const char* str, ...) { - va_list ap; - HWND notepad, edit; - char buf[256]; - - va_start(ap, str); - vsprintf(buf, str, ap); - va_end(ap); - strcat(buf, ""); - log(buf); -} -void nlog(const char* file, const char* str, ...) { - va_list ap; - HWND notepad, edit; - char buf[256]; - - va_start(ap, str); - vsprintf(buf, str, ap); - va_end(ap); - strcat(buf, ""); - log(file, buf); -} - -uintptr_t find_pattern(const char* module_name, const char* pattern) { - const auto get_module_size = [=](uintptr_t module_base) - { - return reinterpret_cast(module_base + reinterpret_cast(module_base)->e_lfanew)->OptionalHeader.SizeOfImage; - }; - const auto module_start = (uintptr_t)GetModuleHandle(module_name); - if (module_start != 0ULL) - { - const auto module_end = module_start + get_module_size(module_start); - - const char* pattern_current = pattern; - uintptr_t current_match = NULL; - - MEMORY_BASIC_INFORMATION64 page_information = {}; - for (auto current_page = reinterpret_cast(module_start); current_page < reinterpret_cast(module_end); current_page = reinterpret_cast(page_information.BaseAddress + page_information.RegionSize)) - { - VirtualQuery(reinterpret_cast(current_page), reinterpret_cast(&page_information), sizeof(MEMORY_BASIC_INFORMATION)); - if (page_information.Protect == PAGE_NOACCESS) - continue; - - if (page_information.State != MEM_COMMIT) - continue; - - if (page_information.Protect & PAGE_GUARD) - continue; - - for (auto current_address = reinterpret_cast(page_information.BaseAddress); current_address < reinterpret_cast(page_information.BaseAddress + page_information.RegionSize - 0x8); current_address++) - { - if (*current_address != GET_BYTE(pattern_current) && *pattern_current != '\?') { - current_match = 0ULL; - pattern_current = pattern; - continue; - } - - if (!current_match) - current_match = reinterpret_cast(current_address); - - pattern_current += 3; - if (pattern_current[-1] == NULL) - return current_match; - } - } - } - - return 0ULL; -} - -uintptr_t find_pattern(uintptr_t start, const char* module_name, const char* pattern) { - const auto get_module_size = [=](uintptr_t module_base) - { - return reinterpret_cast(module_base + reinterpret_cast(module_base)->e_lfanew)->OptionalHeader.SizeOfImage; - }; - const auto module_start = start; - if (module_start != 0ULL) - { - const auto module_end = module_start + get_module_size(module_start); - - const char* pattern_current = pattern; - uintptr_t current_match = NULL; - - MEMORY_BASIC_INFORMATION64 page_information = {}; - for (auto current_page = reinterpret_cast(module_start); current_page < reinterpret_cast(module_end); current_page = reinterpret_cast(page_information.BaseAddress + page_information.RegionSize)) - { - VirtualQuery(reinterpret_cast(current_page), reinterpret_cast(&page_information), sizeof(MEMORY_BASIC_INFORMATION)); - if (page_information.Protect == PAGE_NOACCESS) - continue; - - if (page_information.State != MEM_COMMIT) - continue; - - if (page_information.Protect & PAGE_GUARD) - continue; - - for (auto current_address = reinterpret_cast(page_information.BaseAddress); current_address < reinterpret_cast(page_information.BaseAddress + page_information.RegionSize - 0x8); current_address++) - { - if (*current_address != GET_BYTE(pattern_current) && *pattern_current != '\?') { - current_match = 0ULL; - pattern_current = pattern; - continue; - } - - if (!current_match) - current_match = reinterpret_cast(current_address); - - pattern_current += 3; - if (pattern_current[-1] == NULL) - return current_match; - } - } - } - - return 0ULL; -} -menu_variables vars; - -size_t operator"" _b(const size_t val) -{ - return base + val; -} - -size_t reverse_b(const size_t val) -{ - return val - base; -} - -size_t reverse_b(const void* val) -{ - return reverse_b(reinterpret_cast(val)); -} - -size_t operator"" _g(const size_t val) -{ - return base + (val - 0x140000000); -} - -size_t reverse_g(const size_t val) -{ - return (val - base) + 0x140000000; -} - -size_t reverse_g(const void* val) -{ - return reverse_g(reinterpret_cast(val)); -} - -void log(const char* str) { - std::ofstream outputFile("output.log", std::ios::app); - if (outputFile.is_open()) { - outputFile << str; - outputFile.close(); - } - else { - std::cout << "Failed to open file for appending." << std::endl; - } -} - -void log(const char* file, const char* str) { - try { - std::ofstream outputFile(file, std::ios::app); - if (!outputFile.is_open()) { - throw std::runtime_error("Failed to open file for appending."); - } - - outputFile << str; - } - catch (const std::exception& e) { - printf("%s\n", e.what()); - } +#include "Main.hpp" + +void* exception_handler; + +bool isSubStr(std::string str, std::string subStr) +{ + size_t pos = str.find(subStr); + if (pos != std::string::npos) + { + return true; + } + return false; +} + +float strToFloat(const std::string& str) +{ + float num = 0.0f; + float fraction = 0.1f; + bool isNegative = false; + + size_t i = 0; + if (str[i] == '-') + { + isNegative = true; + i++; + } + + for (; i < str.length(); i++) + { + if (str[i] >= '0' && str[i] <= '9') + { + num = num * 10.0f + static_cast(str[i] - '0'); + } + else if (str[i] == '.') + { + i++; + break; + } + else + { + break; + } + } + + for (; i < str.length(); i++) + { + if (str[i] >= '0' && str[i] <= '9') + { + num += (str[i] - '0') * fraction; + fraction *= 0.1f; + } + else + { + break; + } + } + + if (isNegative) + { + num = -num; + } + + return num; +} + +void backtrace(const char* func) { + const int trace_count = 15; + void* trace_back[trace_count]; + DWORD hash; + RtlCaptureStackBackTrace(1, trace_count, trace_back, &hash); + nlog("%s callstack: ", func); + printf("%s callstack: ", func); + for (int i = 0; i < trace_count; i++) { + if (i == trace_count - 1) { + nlog("%p\n", (uintptr_t)trace_back[i]); + printf("%p\n", (uintptr_t)trace_back[i]); + } + else { + nlog("%p:", (uintptr_t)trace_back[i]); + printf("%p:", (uintptr_t)trace_back[i]); + } + } +} + +int BG_Omnvar_GetType(OmnvarDef* ovDef); + +void DumpOmnvars() +{ + auto G_Omnvar_GetData = reinterpret_cast(0x140FC5110_g); + auto BG_Omnvar_GetTypeString = reinterpret_cast(0x140CD5900_g); + auto NetConstStrings_GetLuiStringIndex = reinterpret_cast(0x1410F0F40_g); + auto BG_Omnvar_GetValueString = reinterpret_cast(0x140CD5980_g); + + g_entities = *reinterpret_cast(0x14BC20F00_g); + + uintptr_t psHost = ((uintptr_t)(g_entities + 0x150)); + + int s_omnvarDefCount = *(int*)(0x145C48518_g); + OmnvarDef* OmnvarDefs = (OmnvarDef*)(0x145C48580_g); + for (int i = 0; i < s_omnvarDefCount; ++i) + { + OmnvarDef* omnvar = &OmnvarDefs[i]; + OmnvarData* data = G_Omnvar_GetData(i, 0, psHost); + const char* typeStr = BG_Omnvar_GetTypeString(omnvar); + int type = BG_Omnvar_GetType(omnvar); + + std::cout << "omnvar '" << omnvar->name << "' (" << typeStr << ") "; + if (type == OMNVAR_TYPE_BOOL) + { + std::cout << "value(" << data->current.enabled << ") "; + } + else if (type == OMNVAR_TYPE_FLOAT) + { + std::cout << "value(" << data->current.value << ") "; + } + else if (type == OMNVAR_TYPE_INT) + { + std::cout << "value(" << data->current.integer << ") "; + } + else if (type == OMNVAR_TYPE_UINT || type == OMNVAR_TYPE_TIME) + { + std::cout << "value(" << data->current.unsignedInteger << ") "; + } + else if (type == OMNVAR_TYPE_NCS_LUI) + { + char currentStr[100] = { NULL }; + BG_Omnvar_GetValueString(omnvar, data, currentStr, 100); + + std::cout << "value'" << currentStr << "' "; + } + else + { + std::cout << "value(" << data->current.unsignedInteger << ") "; + } + + std::cout << std::endl; + } +} + +int iTick = 0; +bool bFinished; +bool btoggle; + +uintptr_t xuid_generated; +int collision_ticker; +utils::hook::detour r_endframe; +void R_EndFrame_Detour() { + if (strcmp(Dvar_GetStringSafe("NSQLTTMRMP"), "mp_donetsk") == 0) { + *reinterpret_cast(0x14E385A68_g) = 80; + *reinterpret_cast(0x14E385A78_g) = 80; + if (collision_ticker == 60) { + btoggle = !btoggle; + *reinterpret_cast(0x145CC7555_g) = btoggle; // s_transientsCollisionMP_LobbyToGameStart + } + collision_ticker++; + } + else { + *reinterpret_cast(0x14E385A68_g) = 1000; + *reinterpret_cast(0x14E385A78_g) = 1000; + } + + if (!bFinished) { + if (iTick == 500) { + DWORD flOldProtect; + XUID xuid; + xuid.RandomXUID(); + utils::hook::set(0x144622BE0_g, 1); + + utils::hook::set(0x14E5C07C0_g, 0x11CB1243B8D7C31E | xuid.m_id * xuid.m_id); + utils::hook::set(0x14F05ACE8_g, 0x11CB1243B8D7C31E | xuid.m_id * xuid.m_id); + + utils::hook::set(0x14E5C07E8_g, 0x11CB1243B8D7C31E | (xuid.m_id * xuid.m_id) / 6); // s_presenceData + + utils::hook::set(0x14E371231_g, 1); + utils::hook::set(0x144622910_g, 2); + utils::hook::set(0x144622BE0_g, 1); + + utils::hook::set(*reinterpret_cast(0x14EE560B0_g) + 0x28, 0); + utils::hook::set(0x14E5C0730_g, 2); + + auto get_bnet_class = reinterpret_cast(0x141660280_g); + uintptr_t bnet_class = get_bnet_class(); + *(DWORD*)(bnet_class + 0x2F4) = 0x795230F0; + *(DWORD*)(bnet_class + 0x2FC) = 0; + *(BYTE*)(bnet_class + 0x2F8) = 31; + + printf("LOADED!\n"); + bFinished = true; + } + else { + iTick += 1; + } + } + + r_endframe.stub(); +} + +bool initiatedevgui; + +void CG_DrawWaterMark() { + float white[4] = { 1.0f, 1.0f, 1.0f, 0.2f }; + // CL_DrawText(0x14EF2DEA0_g, "Fuck off activision you cunts", 0x7FFFFFFF, *reinterpret_cast(0x14EEB0C68_g), 0, 400.0f, 1, 1, 0.80000001, 0.80000001, white, 7); +} + +void CL_ScreenMP_DrawOverlay_Detour() { + auto DevGui_Draw = reinterpret_cast(0x1417E5CD0_g); + auto Con_DrawConsole = reinterpret_cast(0x1415AE0B0_g); + + Con_DrawConsole(0); + DevGui_Draw(0); + + if (show_watermark->current.enabled) { + CG_DrawWaterMark(); + } +} + +utils::hook::detour cl_createdevgui; +void CL_CreateDevGui_Detour(int fsMenuEntries, const char* modeCfg) { + auto DevGui_AddCommand = reinterpret_cast(0x1417E58B0_g); + auto DevGui_AddDvar = reinterpret_cast(0x1417E5940_g); + + cl_createdevgui.stub(fsMenuEntries, modeCfg); +} + +const char* username_Detour() { + if (player_name) { + return player_name->current.string; + } + else { + return "Unknown Name"; + } +} + +utils::hook::detour lui_cod_registerdvars; +void LUI_CoD_RegisterDvars_Detour() { + nlog("registering lui dvars\n"); + player_name = Dvar_RegisterString("player_name", "Player1", 0, "Sets the player name."); + sv_cheats = Dvar_RegisterBool("sv_cheats", false, 0, "Enables cheats to be used on a server"); + spawn_br_gas = Dvar_RegisterBool("spawn_br_gas", true, 0, "Disables gas in battle royale maps"); + show_watermark = Dvar_RegisterBool("show_watermark", false, 0, "Shows the watermark for codUPLOADER"); + + player_sustainammo = Dvar_RegisterBool("player_sustainAmmo", false, 0, "Firing weapon will not decrease clip ammo."); + + lui_cod_registerdvars.stub(); +} + +utils::hook::detour db_zones_performzoneload; +__int64 DB_Zones_PerformZoneLoad_Detour(bool processingPreloadedFiles, bool isBaseMap, bool wasPaused, int failureMode) { + failureMode = 1; + + return db_zones_performzoneload.stub<__int64>(processingPreloadedFiles, isBaseMap, wasPaused, failureMode); +} + +void CL_TransientsCollisionMP_SetTransientMode_Detour(int mode) { + if (strcmp(Dvar_GetStringSafe("NSQLTTMRMP"), "mp_donetsk") == 0) { + *reinterpret_cast(0x145CC7534_g) = 1; + } + else { + *reinterpret_cast(0x145CC7534_g) = mode; + } +} + +utils::hook::detour net_outofbanddata; +bool NET_OutOfBandData_Detour(int sock, netadr_t* adr, const unsigned __int8* format, int len) { + return net_outofbanddata.stub(sock, adr, format, len); +} + +utils::hook::detour g_cmdsmp_clientcommand; +void G_CmdsMP_ClientCommand_Detour(int clientNum) { + g_entities = *reinterpret_cast(0x14BC20F00_g); + + uintptr_t client = g_entities[clientNum].get(0x150); + + char command[1024]; + SV_Cmd_ArgvBuffer(0, command, 1024); + + if (client) { + if (strcmp(command, "noclip") == 0) { + if (CheatsOk(clientNum)) { + Cmd_Noclip_f(clientNum); + } + return; + } + if (strcmp(command, "give") == 0) { + if (CheatsOk(clientNum)) { + SV_Cmd_ArgvBuffer(1, command, 1024); + Weapon weap; + if (BG_Weapons_GetFullWeaponForName(command, &weap, BG_FindBaseWeaponForName)) { + if (SV_Cmd_Argc() == 3) { + SV_Cmd_ArgvBuffer(2, command, 1024); + weap.weaponCamo = atoi(command); + } + if (G_Weapon_GivePlayerWeapon(client, 0, &weap, 0, 0, 0)) { + G_Items_AddAmmo(client, &weap, 0, 9999, 1); + G_Weapon_SelectWeapon(clientNum, &weap); + } + } + } + } + + if (strcmp(command, "give_akimbo") == 0) + { + if (CheatsOk(clientNum)) + { + SV_Cmd_ArgvBuffer(1, command, 1024); + Weapon weap; + if (BG_Weapons_GetFullWeaponForName(command, &weap, BG_FindBaseWeaponForName)) + { + if (SV_Cmd_Argc() == 3) + { + SV_Cmd_ArgvBuffer(2, command, 1024); + weap.weaponCamo = atoi(command); + } + if (G_Weapon_GivePlayerWeapon(client, 0, &weap, 1, 0, 0)) + { + G_Items_AddAmmo(client, &weap, 0, 9999, 1); + G_Weapon_SelectWeapon(clientNum, &weap); + } + } + } + } + + if (strcmp(command, "ks_give") == 0) { + if (CheatsOk(clientNum)) { + SV_Cmd_ArgvBuffer(1, command, 1024); + scrContext_t* ctx = ScriptContext_Server(); + Scr_AddString(ctx, command); + + Scr_FreeThread(ctx, GScr_ExecEntThread(&g_entities[clientNum], 0x1B65FC, 1)); + } + } + if (strcmp(command, "bold_msg") == 0) { + char msgbuf[500]; + SV_Cmd_ArgvBuffer(1, command, 1024); + if (strlen(command) < 500) { + for (int i = 0; i < 30; i++) { + SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * i)); + if (ms_clients) { + snprintf(msgbuf, 500, "g \"%s\"", command); + ms_clients->SendServerCommand(1, msgbuf); + } + } + } + } + if (strcmp(command, "remove_barriers") == 0) { + if (CheatsOk(clientNum)) { + auto SL_ConvertToString = reinterpret_cast(0x14131AA20_g); + for (int i = 0; i < 1024; i++) { + int classname = g_entities[i].get(0x17C); + if (classname) { + if (strcmp(SL_ConvertToString(classname), "trigger_hurt") == 0 || + strcmp(SL_ConvertToString(classname), "trigger_multiple") == 0 || + strcmp(SL_ConvertToString(classname), "trigger_damage") == 0) { + auto G_SetOrigin = reinterpret_cast(0x140FD4CC0_g); + vec3_t gone = { 0, 0, -9999999 }; + G_SetOrigin(&g_entities[i], &gone, true, true); + } + } + } + for (int i = 0; i < 30; i++) { + SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * i)); + if (ms_clients) { + ms_clients->SendServerCommand(1, "g \"Death barriers removed!\""); + } + } + } + } + + /*if (strcmp(command, "scmd") == 0) + { + if (CheatsOk(clientNum) && clientNum == 0) + { + char msgbuf[500]; + std::string cmdline = ""; + if (SV_Cmd_Argc() > 1) + { + for (int i = 0; i < SV_Cmd_Argc() - 1; i++) + { + SV_Cmd_ArgvBuffer(1 + i, msgbuf, 500); + if (i == 0) + { + cmdline = msgbuf; + } + else + { + cmdline = cmdline + " " + std::string(msgbuf); + } + std::cout << 1 + i << ": '" << msgbuf << "'" << std::endl; + memset(msgbuf, 0, 500); + } + + const char* cCmdLine = cmdline.c_str(); + memcpy(msgbuf, cCmdLine, cmdline.length() + 1); + std::cout << "msgbug: '" << msgbuf << "'" << std::endl; + + SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * clientNum)); + if (ms_clients) + { + ms_clients->SendServerCommand(1, msgbuf); + } + } + } + }*/ + + if (strcmp(command, "viewpos") == 0) { + if (CheatsOk(clientNum)) { + char msgbuf[500]; + SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * clientNum)); + if (ms_clients) { + snprintf(msgbuf, 500, "f \"viewpos: (%.2f, %.2f, %.2f)\"", g_entities[clientNum].r_currentOrigin[0], g_entities[clientNum].r_currentOrigin[1], g_entities[clientNum].r_currentOrigin[2]); + ms_clients->SendServerCommand(1, msgbuf); + } + } + } + + if (strcmp(command, "setpos") == 0) + { + if (CheatsOk(clientNum) && clientNum == 0) + { + if (SV_Cmd_Argc() == 4) + { + char xBuf[100]; + char yBuf[100]; + char zBuf[100]; + + SV_Cmd_ArgvBuffer(1, xBuf, 100); + SV_Cmd_ArgvBuffer(2, yBuf, 100); + SV_Cmd_ArgvBuffer(3, zBuf, 100); + + float x = strToFloat(xBuf); + float y = strToFloat(yBuf); + float z = strToFloat(zBuf); + + struct gclient_s + { + char __padding[0x30]; + float coords[3]; + }; + g_entities = *reinterpret_cast(0x14BC20F00_g); + + gclient_s* host = (gclient_s*)g_entities[0].client; + host->coords[0] = x; + host->coords[1] = y; + host->coords[2] = z; + } + } + } + } + + g_cmdsmp_clientcommand.stub(clientNum); +} + +utils::hook::detour cl_inputmp_execbinding; +void CL_InputMP_ExecBinding_Detour(int localClientNum, int kb, int key, int forceNotify) { + switch (key) { + case K_N: + CL_Main_AddReliableCommand("noclip"); + break; + } + + cl_inputmp_execbinding.stub(localClientNum, kb, key, forceNotify); +} + +void Cmd_Exec_Internal(bool isSuperUser) +{ + const char* cmdbuf; + const char* file; + auto DB_FindXAssetHeader = reinterpret_cast(0x1411AA890_g); + auto DB_ReadRawFile = reinterpret_cast(0x141297140_g); + auto Core_strcpy_truncate = reinterpret_cast(0x142036A90_g); + auto Com_DefaultExtension = reinterpret_cast(0x1413F1AE0_g); + char path[64]; + + if (cmd_args->argc[cmd_args->nesting] == 2) + { + Core_strcpy_truncate(path, 64, *(cmd_args->argv[cmd_args->nesting] + 1)); + Com_DefaultExtension(path, 64, ".cfg"); + if (DB_FindXAssetHeader(ASSET_TYPE_RAWFILE, path, 0)) + { + if (!DB_ReadRawFile(0, cmd_args->controllerIndex[cmd_args->nesting], path, isSuperUser)) + { + if (cmd_args->argc[cmd_args->nesting] <= 1) + file = ""; + else + file = *(cmd_args->argv[cmd_args->nesting] + 1); + printf("couldn't exec %s\n", file); + } + } + else + { + FS_ReadFile(path, &cmdbuf); + LUI_CoD_LuaCall_ExecNow(*reinterpret_cast(0x151868880_g), cmdbuf); + } + } + else + { + printf(0, "exec : execute a script file\n"); + } +} + +utils::hook::detour gscr_spawnbrcircle; +void GScr_SpawnBrCircle_Detour(uintptr_t scrContext) { + if (spawn_br_gas->current.enabled) { + gscr_spawnbrcircle.stub(scrContext); + } +} + +void entry_point() { + XUID xuid; + xuid.RandomXUID(); + + printf("%i\n", xuid.m_id); + + r_endframe.create(0x141966950_g, R_EndFrame_Detour); + utils::hook::jump(0x141297580_g, Cmd_Exec_Internal); + utils::hook::jump(0x1415E1340_g, CL_ScreenMP_DrawOverlay_Detour); + utils::hook::jump(0x1413FD3A0_g, username_Detour); + + db_zones_performzoneload.create(0x140F677A0_g, DB_Zones_PerformZoneLoad_Detour); + + g_cmdsmp_clientcommand.create(0x14120B6A0_g, G_CmdsMP_ClientCommand_Detour); + cl_inputmp_execbinding.create(0x1415E1AB0_g, CL_InputMP_ExecBinding_Detour); + gscr_spawnbrcircle.create(0x141243AB0_g, GScr_SpawnBrCircle_Detour); + + utils::hook::jump(0x140D6B7D0_g, CL_TransientsCollisionMP_SetTransientMode_Detour); + + printf("hooked!\n"); +} + +extern "C" __declspec(dllexport) int DiscordCreate() { + CreateThread(0, 0xA0, (LPTHREAD_START_ROUTINE)entry_point, 0, 0, 0); + return 1; +} + +void SaveInventory() +{ + auto DDL_MoveToPath = reinterpret_cast(0x142052430_g); + //auto Com_DDL_ConvertNavStringToHash = reinterpret_cast(0x14129EE80_g); + //auto LiveStorage_InitializeDDLStateForStatsGroup = reinterpret_cast(0x1410CAD70_g); + auto Com_PlayerData_GetStatsBlob = reinterpret_cast(0x1410CA7A0_g); + auto DDL_GetType = reinterpret_cast(0x142051DD0_g); + auto DDL_GetString = reinterpret_cast(0x142051CD0_g); + auto DDL_GetEnum = reinterpret_cast(0x1420519E0_g); + auto DDL_GetInt = reinterpret_cast(0x142051BF0_g); + auto DDL_GetRootState = reinterpret_cast(0x142051C70_g); + auto CL_PlayerData_GetDDLBuffer = reinterpret_cast(0x1415C7940_g); + auto Com_DDL_LoadAsset = reinterpret_cast(0x14129F3B0_g); + auto Com_ParseNavStrings = reinterpret_cast(0x1412A02E0_g); + auto Com_DDL_CreateContext = reinterpret_cast(0x14129EEC0_g); + + DDLContext context; + DDLDef* ddlDef; + DDLState state; + char buffer[200]; + char* navStrings[32]{}; + int navStringCount; + char path[MAX_PATH + 1]; + strcpy(path, Dvar_GetStringSafe("LOOQOTRNTN")); + strcat(path, "\\players\\inventory.json"); + nlohmann::json inventoryJson; + if (CL_PlayerData_GetDDLBuffer(&context, 0, STATS_OFFLINE, STATSGROUP_PRIVATELOADOUTS)) { + ddlDef = (DDLDef*)context.def; + // start of operator customization related + for (int i = 0; i < ddlDef->enumCount; ++i) + { + if (!strcmp(ddlDef->enumList[i].name, "Operator")) { + for (int j = 0; j < ddlDef->enumList[i].memberCount; ++j) + { + // get operator skins + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.operatorCustomization.%s.skin", ddlDef->enumList[i].members[j]); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + int OP_opSkin = DDL_GetInt(&state, &context); + inventoryJson["Operator"]["OperatorSkin"][ddlDef->enumList[i].members[j]] = OP_opSkin; + } + // execution ids + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.operatorCustomization.%s.execution", ddlDef->enumList[i].members[j]); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + inventoryJson["Operator"]["OperatorExecution"][ddlDef->enumList[i].members[j]] = DDL_GetInt(&state, &context); + } + } + } + } + // selected operator + for (int i = 0; i < 2; ++i) + { + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.operators.%d", i); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + inventoryJson["Operator"]["SelectedOperator"][i] = DDL_GetEnum(&state, &context); + } + } + // operator Index + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.selectedOperatorIndex"); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + inventoryJson["Operator"]["OperatorIndex"] = DDL_GetInt(&state, &context); + } + // operator watch + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.operatorWatch"); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + inventoryJson["Operator"]["OperatorWatch"] = DDL_GetInt(&state, &context); + } + // end of operator customization related + // start of weapon customization + + for (int i = 0; i < 10; ++i) { + // get weapon + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.name", i); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + // test by getting loadout names + inventoryJson["Loadouts"][i] = { {"name", DDL_GetString(&state, &context)} }; + } + for (int j = 0; j < 2; ++j) { + // get camos + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.camo", i, j); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + inventoryJson["Loadouts"][i]["weaponSetup"][j] = { {"camo", DDL_GetEnum(&state, &context)} }; + } + // get weapons + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.weapon", i, j); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + inventoryJson["Loadouts"][i]["weaponSetup"][j].push_back({ "weapon", DDL_GetEnum(&state, &context) }); + } + // get variant ids + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.variantID", i, j); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + inventoryJson["Loadouts"][i]["weaponSetup"][j].push_back({ "variantId", DDL_GetInt(&state, &context) }); + } + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.lootItemID", i, j); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + inventoryJson["Loadouts"][i]["weaponSetup"][j].push_back({ "lootItemID", DDL_GetInt(&state, &context) }); + } + for (int k = 0; k < 5; ++k) { + // get attachments & variants + std::string attachmentName; + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.attachmentSetup.%d.attachment", i, j, k); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + attachmentName = DDL_GetEnum(&state, &context); + } + + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.attachmentSetup.%d.variantID", i, j, k); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + inventoryJson["Loadouts"][i]["weaponSetup"][j]["attachments"][k] = { attachmentName.c_str(), DDL_GetInt(&state, &context) }; + } + } + } + + } + // printf("Saved Inventory!\n"); + } + else { + Com_SetErrorMessage("[DLL ERROR] Couldn't get DDLBuffer, called before initialized?"); + } + + std::ofstream JsonOut(path); + JsonOut << inventoryJson; + +} + +void LoadInventory() +{ + auto Cmd_LocalControllerIndex = reinterpret_cast(0x141298040_g); + auto LiveStorage_GetActiveStatsSource = reinterpret_cast(0x1412A1EB0_g); + auto LiveStorage_CreateDDLContext = reinterpret_cast(0x1412A13C0_g); + auto DDL_MoveToPath = reinterpret_cast(0x142052430_g); + //auto Com_DDL_ConvertNavStringToHash = reinterpret_cast(0x14129EE80_g); + //auto LiveStorage_InitializeDDLStateForStatsGroup = reinterpret_cast(0x1410CAD70_g); + auto Com_PlayerData_GetStatsBlob = reinterpret_cast(0x1410CA7A0_g); + auto DDL_GetType = reinterpret_cast(0x142051DD0_g); + auto DDL_GetString = reinterpret_cast(0x142051CD0_g); + auto DDL_GetEnum = reinterpret_cast(0x1420519E0_g); + auto DDL_GetInt = reinterpret_cast(0x142051BF0_g); + auto DDL_GetRootState = reinterpret_cast(0x142051C70_g); + auto CL_PlayerData_GetDDLBuffer = reinterpret_cast(0x1415C7940_g); + auto Com_DDL_LoadAsset = reinterpret_cast(0x14129F3B0_g); + auto Com_ParseNavStrings = reinterpret_cast(0x1412A02E0_g); + auto Com_DDL_CreateContext = reinterpret_cast(0x14129EEC0_g); + auto StringTable_GetColumnValueForRow = reinterpret_cast(0x1413E2B40_g); + auto DDL_SetInt = reinterpret_cast(0x142052820_g); + auto DDL_SetEnum = reinterpret_cast(0x142052710_g); + auto DDL_SetString = reinterpret_cast(0x1420528D0_g); + + DDLContext context; + DDLDef* ddlDef; + DDLState state; + char buffer[200]; + char* navStrings[32]{}; + int navStringCount; + char path[MAX_PATH + 1]; + strcpy(path, Dvar_GetStringSafe("LOOQOTRNTN")); + strcat(path, "\\players\\inventory.json"); + if (file_exists(path)) { + std::ifstream jsonPath(path); + nlohmann::json inventoryJson = nlohmann::json::parse(jsonPath); + if (CL_PlayerData_GetDDLBuffer(&context, 0, STATS_OFFLINE, STATSGROUP_PRIVATELOADOUTS)) { + ddlDef = (DDLDef*)context.def; + for (int i = 0; i < ddlDef->enumCount; ++i) + { + if (!strcmp(ddlDef->enumList[i].name, "Operator")) { + for (int j = 0; j < ddlDef->enumList[i].memberCount; ++j) + { + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.operatorCustomization.%s.skin", ddlDef->enumList[i].members[j]); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetInt(&state, &context, inventoryJson["Operator"]["OperatorSkin"][ddlDef->enumList[i].members[j]]); + } + // execution ids + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.operatorCustomization.%s.execution", ddlDef->enumList[i].members[j]); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetInt(&state, &context, inventoryJson["Operator"]["OperatorExecution"][ddlDef->enumList[i].members[j]]); + } + + } + } + } + for (int i = 0; i < 2; ++i) + { + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.operators.%d", i); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetEnum(&state, &context, inventoryJson["Operator"]["SelectedOperator"][i].get().c_str()); + } + } + // operator Index + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.selectedOperatorIndex"); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetInt(&state, &context, inventoryJson["Operator"]["OperatorIndex"]); + } + + // operator watch + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "customizationSetup.operatorWatch"); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetInt(&state, &context, inventoryJson["Operator"]["OperatorWatch"]); + } + // start of weapon customization + for (int i = 0; i < 10; ++i) { + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.name", i); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetString(&state, &context, inventoryJson["Loadouts"][i]["name"].get().c_str()); + } + for (int j = 0; j < 2; ++j) { + // set camo + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.camo", i, j); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetEnum(&state, &context, inventoryJson["Loadouts"][i]["weaponSetup"][j]["camo"].get().c_str()); + } + // set weapon + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.weapon", i, j); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetEnum(&state, &context, inventoryJson["Loadouts"][i]["weaponSetup"][j]["weapon"].get().c_str()); + } + // set variantid + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.variantID", i, j); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetInt(&state, &context, inventoryJson["Loadouts"][i]["weaponSetup"][j]["variantId"]); + } + // set lootItemId + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.lootItemID", i, j); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetInt(&state, &context, inventoryJson["Loadouts"][i]["weaponSetup"][j]["lootItemID"]); + } + for (int k = 0; k < 5; ++k) { + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.attachmentSetup.%d.attachment", i, j, k); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetEnum(&state, &context, inventoryJson["Loadouts"][i]["weaponSetup"][j]["attachments"][k][0].get().c_str()); + } + + DDL_GetRootState(&state, ddlDef); + sprintf_s(buffer, "squadMembers.loadouts.%d.weaponSetups.%d.attachmentSetup.%d.variantID", i, j, k); + Com_ParseNavStrings(buffer, (const char**)navStrings, 32, &navStringCount); + if (DDL_MoveToPath(&state, &state, navStringCount, (const char**)navStrings)) + { + DDL_SetInt(&state, &context, inventoryJson["Loadouts"][i]["weaponSetup"][j]["attachments"][k][1]); + } + } + } + } + + } + else { + Com_SetErrorMessage("[DLL ERROR] Couldn't get DDLBuffer, called before initialized?"); + } + printf("Loaded Inventory!\n"); + } + else { + // Com_SetErrorMessage("[DLL ERROR] Attempted to load inventory from \"players/inventory.json\" but file does not exist. Use 'saveinv' to save your inventory."); + printf("Attempted to load inventory from \"players/inventory.json\" but file does not exist\n"); + } +} + +utils::hook::detour cl_keys_event; +void CL_Keys_Event_Detour(int localClientNum, int key, bool down, unsigned int time, int virtualKey, int controllerIndex) +{ + auto Con_ToggleConsole = reinterpret_cast(0x1415B18C0_g); + auto Con_ToggleConsoleOutput = reinterpret_cast(0x1415B1930_g); + auto DevGui_Toggle = reinterpret_cast(0x1417E9DA0_g); + auto Con_IsActive = reinterpret_cast(0x1415b0EF0_g); + + if (down) + { + switch (key) + { + case K_GRAVE: + + if (GetAsyncKeyState(VK_SHIFT) & 0x8000) + { + if (Con_IsActive(localClientNum) == false) + { + Con_ToggleConsole(); + } + Con_ToggleConsoleOutput(); + } + else + { + Con_ToggleConsole(); + } + return; + break; + case K_F1: + DevGui_Toggle(); + return; + break; + } + } + + cl_keys_event.stub(localClientNum, key, down, time, virtualKey, controllerIndex); +} + +utils::hook::detour PM_WeaponUseAmmo; +void PM_WeaponUseAmmo_Detour(__int64 playerstate, Weapon* weapon, char a3, int a4, int hand) +{ + bool sv_cheats = Dvar_GetBoolSafe("NTPNRQTKNP"); + + if (!(player_sustainammo->current.enabled && sv_cheats)) + { + PM_WeaponUseAmmo.stub(playerstate, weapon, a3, a4, hand); + } +} + +utils::hook::detour dvar_registerbool; +dvar_t* Dvar_RegisterBool_Detour(const char* dvarName, bool value, unsigned int flags, const char* description) { + if (strcmp(dvarName, "LSTQOKLTRN") == 0) { + nlog("dvar registered!\n"); + value = true; + } + if (strcmp(dvarName, "MPSSOTQQPM") == 0) { + nlog("dvar registered!\n"); + value = true; + } + dvar_t* ret = dvar_registerbool.stub(dvarName, value, flags, description); + return ret; +} + +utils::hook::detour dvar_registerstring; +dvar_t* Dvar_RegisterString_Detour(const char* dvarName, const char* value, unsigned int flags, const char* description) { + return dvar_registerstring.stub(dvarName, value, flags, description); +} + +void GamerProfile_SetDataByName(unsigned int controllerIndex, const char* settingName, float settingValue) { + auto func = reinterpret_cast(0x1415D8BD0_g); + return func(controllerIndex, settingName, settingValue); +} + +utils::hook::detour seh_stringed_getstring; +const char* SEH_StringEd_GetString_Detour(const char* pszReference) { + const char* ret = seh_stringed_getstring.stub(pszReference); + + if (!pszReference[1]) + { + if ((*pszReference & 0x80) != 0) + return "t"; + return pszReference; + } + + GamerProfile_SetDataByName(0, "acceptedEULA", 1); + GamerProfile_SetDataByName(0, "hasEverPlayed_MainMenu", 1); + + if (strstr(pszReference, "LUA_MENU/MAPNAME_ANIYAH") || + strstr(pszReference, "LUA_MENU/MAPNAME_DEADZONE") || + strstr(pszReference, "LUA_MENU/MAPNAME_M_CAGE") || + strstr(pszReference, "LUA_MENU/MAPNAME_CAVE_AM") || + strstr(pszReference, "LUA_MENU/MAPNAME_CAVE") || + strstr(pszReference, "LUA_MENU/MAPNAME_M_CARGO") || + strstr(pszReference, "LUA_MENU/MAPNAME_CRASH2") || + strstr(pszReference, "LUA_MENU/MAPNAME_M_OVERUNDER") || + strstr(pszReference, "LUA_MENU/MAPNAME_EUPHRATES") || + strstr(pszReference, "LUA_MENU/MAPNAME_RAID") || + strstr(pszReference, "LUA_MENU/MAPNAME_M_SHOWERS") || + strstr(pszReference, "LUA_MENU/MAPNAME_RUNNER_AM") || + strstr(pszReference, "LUA_MENU/MAPNAME_RUNNER") || + strstr(pszReference, "LUA_MENU/MAPNAME_HACKNEY_AM") || + strstr(pszReference, "LUA_MENU/MAPNAME_HACKNEY_YARD") || + strstr(pszReference, "LUA_MENU/MAPNAME_M_HILL") || + strstr(pszReference, "LUA_MENU/MAPNAME_PICCADILLY") || + strstr(pszReference, "LUA_MENU/MAPNAME_M_PINE") || + strstr(pszReference, "LUA_MENU/MAPNAME_SPEAR_AM") || + strstr(pszReference, "LUA_MENU/MAPNAME_SPEAR") || + strstr(pszReference, "LUA_MENU/MAPNAME_PETROGRAD") || + strstr(pszReference, "LUA_MENU/MAPNAME_M_STACK") || + strstr(pszReference, "LUA_MENU/MAPNAME_VACANT")) { + return "^1no work"; + } + + if (strstr(pszReference, "MENU/CAMPAIGN")) + { + return "^3Campaign is not available in this build of the game."; + } + + if (strstr(pszReference, "LUA_MENU/LOCAL_COOP_DESC")) + { + return "^3CO-OP is not available in this build of the game."; + } + + if (strstr(pszReference, "LUA_MENU/LOCAL_MULTIPLAYER_CAPS")) + { + return "MULTIPLAYER"; + } + + if (strstr(pszReference, "MENU_SP/CAMPAIGN")) + { + return "^1CAMPAIGN"; + } + + if (strstr(pszReference, "LUA_MENU/LOCAL_COOP_CAPS")) + { + return "^1LOCAL CO-OP"; + } + + return ret; +} + +char buffer[0x5000]; + +utils::hook::detour db_loadxfile; +int DB_LoadXFile_Detour(const char* zoneName, uintptr_t zoneMem, uintptr_t assetList, int zoneFlags, bool wasPaused, int failureMode, uintptr_t outSignature) { + return db_loadxfile.stub(zoneName, zoneMem, assetList, zoneFlags, wasPaused, failureMode, outSignature); +} + +utils::hook::detour CL_TransientsMP_ProcessLoadingQueue; +char CL_TransientsMP_ProcessLoadingQueue_Detour() { + return CL_TransientsMP_ProcessLoadingQueue.stub(); +} + +utils::hook::detour partyhost_startprivateparty; +void PartyHost_StartPrivateParty_Detour(int localClientNum, int localControllerIndex, bool currentlyActive, int hostType) { + Cbuf_AddText("exec autoexec.cfg"); + + partyhost_startprivateparty.stub(localClientNum, localControllerIndex, currentlyActive, hostType); + + LoadInventory(); +} + +bool Live_IsUserSignedInToDemonware_Detour() { + return true; +} + +int dwGetLogOnStatus_Detour() { + return 2; +} + +int LiveStorage_GetActiveStatsSource_Detour() { + return 1; +} + +void set_byte_f() { + char command[500]; + if (Cmd_Argc() == 3) { + Cmd_ArgvBuffer(1, command, 500); + uintptr_t address = atoll(command) + base; + Cmd_ArgvBuffer(2, command, 500); + utils::hook::set(address, atoi(command)); + } +} + +void set_short_f() { + char command[500]; + if (Cmd_Argc() == 3) { + Cmd_ArgvBuffer(1, command, 500); + uintptr_t address = atoll(command) + base; + Cmd_ArgvBuffer(2, command, 500); + utils::hook::set(address, atol(command)); + } +} + +void set_int_f() { + char command[500]; + if (Cmd_Argc() == 3) { + Cmd_ArgvBuffer(1, command, 500); + uintptr_t address = atoll(command) + base; + Cmd_ArgvBuffer(2, command, 500); + utils::hook::set(address, _atoi64(command)); + } +} + +void set_float_f() +{ + char command[500]; + if (Cmd_Argc() == 3) { + Cmd_ArgvBuffer(1, command, 500); + uintptr_t address = atoll(command) + base; + Cmd_ArgvBuffer(2, command, 500); + utils::hook::set(address, strToFloat(command)); + } +} + +void set_pointer_f() { + char command[500]; + if (Cmd_Argc() == 3) { + Cmd_ArgvBuffer(1, command, 500); + uintptr_t address = atoll(command) + base; + Cmd_ArgvBuffer(2, command, 500); + utils::hook::set(address, _atoi64(command)); + } +} + +void Cmd_Quit_f() { + ExitProcess(0x1); +} + +void Cmd_OpenMenu_f() { + char command[500]; + if (Cmd_Argc() == 2) { + auto LUI_OpenMenu = reinterpret_cast(0x141B9BDB0_g); + Cmd_ArgvBuffer(1, command, 500); + LUI_OpenMenu(0, command, true, false, false); + } +} + +short* SV_ClientMP_AddTestClient() +{ + uintptr_t SV_ClientMP_AddTestClient_func_address = 0x14136e570_g; + short* (__cdecl * SV_ClientMP_AddTestClient_func)(void) = (short* (__cdecl*)(void))SV_ClientMP_AddTestClient_func_address; + + return SV_ClientMP_AddTestClient_func(); +} + +void GScr_AddEntity(short* entity) +{ + auto GScr_AddEntity_func = reinterpret_cast(0x1412578a0_g); + GScr_AddEntity_func(entity); +} + +void SV_ClientMP_SpawnBotOrTestClient(short* entity) +{ + auto SV_ClientMP_SpawnBotOrTestClient_func = reinterpret_cast(0x141373640_g); + SV_ClientMP_SpawnBotOrTestClient_func(entity); +} + +void Cmd_AddBot_f() +{ + auto ent = SV_ClientMP_AddTestClient(); + GScr_AddEntity(ent); + SV_ClientMP_SpawnBotOrTestClient(ent); +} + +void SV_CmdsMP_MapRestart_f() +{ + auto SV_CmdsMP_RequestMapRestart = reinterpret_cast(0x14136C310_g); + SV_CmdsMP_RequestMapRestart(1, 0); +} + +void SV_CmdsMP_FastRestart_f() +{ + auto SV_CmdsMP_RequestMapRestart = reinterpret_cast(0x14136C310_g); + auto CL_Screen_Update = reinterpret_cast(0x1415caa50_g); + SV_CmdsMP_RequestMapRestart(0, 0); + // CL_Screen_Update(); +} + +OmnvarDef* BG_Omnvar_GetDef(unsigned int index) +{ + auto BG_Omnvar_GetDef_func = reinterpret_cast(0x140CD5830_g); + return BG_Omnvar_GetDef_func(index); + + /*OmnvarDef* OmnvarDefs = (OmnvarDef*)(0x145C48580_g); + return OmnvarDefs + index;*/ +} + +uintptr_t G_GetEntityPlayerState(gentity_s* ent) +{ + uintptr_t cl = ent->client; + + // return &cl->ps; + return cl; // client + 0x0 = playerstate +} + +int G_Main_GetTime() +{ + return *(int*)0x14BC21730; +} + +int BG_Omnvar_GetType(OmnvarDef* ovDef) +{ + const char* type = (const char*)((char*)ovDef + 0x26); + return *type; +} + +void Cmd_Omnvar_Set_f() +{ + char ovName[100]; + char newValue[100]; + + auto BG_Omnvar_GetIndexByName = reinterpret_cast(0x140CD5870_g); + auto BG_Omnvar_GetDef = reinterpret_cast(0x140CD5830_g); + auto G_Omnvar_GetData = reinterpret_cast(0x140FC5110_g); + auto BG_Omnvar_GetTypeString = reinterpret_cast(0x140CD5900_g); + auto G_Omnvar_MarkChanged = reinterpret_cast(0x140FC51B0_g); + auto NetConstStrings_GetLuiStringIndex = reinterpret_cast(0x1410F0F40_g); + + g_entities = *reinterpret_cast(0x14BC20F00_g); + + if (Cmd_Argc() != 3) + { + printf("setOmnvar usage: setOmnvar \n"); + return; + } + + Cmd_ArgvBuffer(1, ovName, 100); + Cmd_ArgvBuffer(2, newValue, 100); + + unsigned int omnvarIndex = BG_Omnvar_GetIndexByName(ovName); + if (omnvarIndex == -1) + { + printf("Omnvar %s not found\n", ovName); + return; + } + OmnvarDef* ovDef = BG_Omnvar_GetDef(omnvarIndex); + uintptr_t psHost = ((uintptr_t)(g_entities + 0x150)); + OmnvarData* data = G_Omnvar_GetData(omnvarIndex, 0, psHost); + const char* typeStr = BG_Omnvar_GetTypeString(ovDef); + int type = BG_Omnvar_GetType(ovDef); + + if (type == OMNVAR_TYPE_BOOL) + { + char num = *newValue; + if (num == '0' || num == '1') + { + (data->current).enabled = num == '1'; + G_Omnvar_MarkChanged(data); + } + } + else if (type == OMNVAR_TYPE_FLOAT) + { + float value = strToFloat(newValue); + (data->current).value = value; + G_Omnvar_MarkChanged(data); + } + else if (type == OMNVAR_TYPE_INT) + { + int value = atoi(newValue); + (data->current).integer = value; + G_Omnvar_MarkChanged(data); + } + else if (type == OMNVAR_TYPE_UINT) + { + int value = atoi(newValue); + if ((ovDef->maxvalue > value) && (value > ovDef->minvalue)) + { + (data->current).unsignedInteger = value; + G_Omnvar_MarkChanged(data); + } + } + else if (type == OMNVAR_TYPE_TIME) + { + int value = atoi(newValue); + if (value < 0) + { + printf("Expected positive value for time omnvar %s\n", ovDef->name); + return; + } + (data->current).integer = value; + G_Omnvar_MarkChanged(data); + } + else if (type == OMNVAR_TYPE_NCS_LUI) + { + int ret = NetConstStrings_GetLuiStringIndex(newValue, &(data->current).ncsString); + if (ret == NULL) + { + printf("Invalid value '%s' for omnvar '%s'.\n", newValue, ovDef->name); + } + else + { + G_Omnvar_MarkChanged(data); + } + } +} + +void Cmd_Omnvars_Dump_f() +{ + DumpOmnvars(); +} + +void Cmd_DDLDump_f() { + int cur = 0; + DDLFile* g_assets = *(DDLFile**)(0x14B8F5C48_g); + if (g_assets[cur].name) { + while (g_assets[cur].name != 0 && g_assets[cur].ddlDef != 0) { + nlog("%s\n", g_assets[cur].name); + for (int istruct = 0; istruct < g_assets[cur].ddlDef->structCount; istruct++) { + nlog("struct %s { //count: %i\n", g_assets[cur].ddlDef->structList[istruct].name, g_assets[cur].ddlDef->structList[istruct].memberCount); + for (int imember = 0; imember < g_assets[cur].ddlDef->structList[istruct].memberCount; imember++) { + if (g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize == 1) { + switch (g_assets[cur].ddlDef->structList[istruct].members[imember].type) { + case DDL_STRING_TYPE: nlog("\tconst char* %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_FIXEDPOINT_TYPE: + case DDL_FLOAT_TYPE: nlog("\tfloat %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_BYTE_TYPE: nlog("\tbyte %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_SHORT_TYPE: nlog("\tshort %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_INT_TYPE: nlog("\tint %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_UINT_TYPE: nlog("\tuint %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_PAD_TYPE: nlog("\tchar %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_HASH_TYPE: nlog("\thash %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_UINT64_TYPE: nlog("\tuint64_t %s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_ENUM_TYPE: nlog("\t%s %s;\n", g_assets[cur].ddlDef->enumList[g_assets[cur].ddlDef->structList[istruct].members[imember].externalIndex].name, g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + case DDL_STRUCT_TYPE: nlog("\t%s %s;\n", g_assets[cur].ddlDef->structList[g_assets[cur].ddlDef->structList[istruct].members[imember].externalIndex].name, g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + default:nlog("\t%s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + } + } + else { + switch (g_assets[cur].ddlDef->structList[istruct].members[imember].type) { + case DDL_FIXEDPOINT_TYPE: + case DDL_FLOAT_TYPE: nlog("\tfloat %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_STRING_TYPE: nlog("\tconst char* %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_BYTE_TYPE: nlog("\tbyte %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_SHORT_TYPE: nlog("\tshort %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_INT_TYPE: nlog("\tint %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_UINT_TYPE: nlog("\tuint %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_PAD_TYPE: nlog("\tchar %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_HASH_TYPE: nlog("\thash %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_ENUM_TYPE: nlog("\t%s %s[%i];\n", g_assets[cur].ddlDef->enumList[g_assets[cur].ddlDef->structList[istruct].members[imember].externalIndex].name, g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_UINT64_TYPE: nlog("\tuint64_t %s[%i];\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + case DDL_STRUCT_TYPE: nlog("\t%s %s[%i];\n", g_assets[cur].ddlDef->structList[g_assets[cur].ddlDef->structList[istruct].members[imember].externalIndex].name, g_assets[cur].ddlDef->structList[istruct].members[imember].name, g_assets[cur].ddlDef->structList[istruct].members[imember].arraySize); break; + default:nlog("\t%s;\n", g_assets[cur].ddlDef->structList[istruct].members[imember].name); break; + } + } + } + nlog("}\n"); + } + for (int ienum = 0; ienum < g_assets[cur].ddlDef->enumCount; ienum++) { + nlog("enum %s { //count: %i\n", g_assets[cur].ddlDef->enumList[ienum].name, g_assets[cur].ddlDef->enumList[ienum].memberCount); + for (int imember = 0; imember < g_assets[cur].ddlDef->enumList[ienum].memberCount; imember++) { + nlog("\t%s,\n", g_assets[cur].ddlDef->enumList[ienum].members[imember]); + } + nlog("}\n\n\n\n"); + } + cur++; + } + } +} + +void Cmd_WeaponDefDump_f() { + //Globals + uintptr_t* bg_weaponCompleteDefs = reinterpret_cast(0x14C6EC870_g); + + nlog("DUMPING WEAPON DEFINITIONS!!! --- \n"); + + for (int i = 0; i < 550; i++) { + WeaponCompleteDef* weap = reinterpret_cast(bg_weaponCompleteDefs[i]); + + if (!weap) continue; + nlog("szInternalName: %s\n", weap->szInternalName); + nlog("szDisplayName: %s\n", weap->szDisplayName); + } + + nlog("FINISHED WEAPON DEFINITION DUMP YAY!!! --- \n"); +} + +void Cmd_ViewVehicleEnts_f() { + auto SL_ConvertToString = reinterpret_cast(0x14131AA20_g); + for (int i = 0; i < 1024; i++) { + int classname = g_entities[i].get(0x17C); + if (classname) { + const char* s_classname = SL_ConvertToString(classname); + if (g_entities[i].get(0x160)) { + nlog("vehicle %s\n", s_classname); + } + } + } +} + +void Cmd_LoadoutSave_f() { + SaveInventory(); +} +int LuaShared_LuaCall_IsDemoBuild_Detour(uintptr_t luaVM) { + lua_pushboolean(luaVM, 1); + return 1; +} + +utils::hook::detour dvar_findvarbyname; +dvar_t* Dvar_FindVarByName_Detour(const char* dvarName) { + dvar_t* ret = dvar_findvarbyname.stub(dvarName); + return ret; +} + +utils::hook::detour db_findxassetheader; +XAssetHeader DB_FindXAssetHeader_Detour(XAssetType type, const char* givenName, int allowCreateDefault) +{ + XAssetHeader temp = db_findxassetheader.stub(type, givenName, allowCreateDefault); + + //if (type == ASSET_TYPE_XMODEL) { + // if (strcmp(temp.model->name, "head_mp_western_ghost_1_1") == 0) { + // return db_findxassetheader.stub(type, "head_opforce_juggernaut", allowCreateDefault); + // } + // if (strcmp(temp.model->name, "mp_western_vm_arms_ghost_1_1") == 0) { + // return db_findxassetheader.stub(type, "viewhands_opforce_juggernaut", allowCreateDefault); + // } + // if (strcmp(temp.model->name, "body_mp_western_ghost_1_1_lod1") == 0) { + // return db_findxassetheader.stub(type, "body_opforce_juggernaut_mp_lod1", allowCreateDefault); + // } + // if (strcmp(temp.model->name, "military_carepackage_01_friendly") == 0) { + // return db_findxassetheader.stub(type, "opforce_juggernaut_prop_static", allowCreateDefault); + // } + // if (strstr(temp.model->name, "veh8_mil_air_")) { + // return db_findxassetheader.stub(type, "veh8_mil_air_acharlie130", allowCreateDefault); + // } + //} + + return temp; +} + +utils::hook::detour db_getrawbufferinflate; +const char* DB_GetRawBufferInflate_Detour(const char* file, char* buffer, int length) { + char path[MAX_PATH + 1]; + memset(path, 0, MAX_PATH + 1); + std::string filecontents; + std::string curline; + snprintf(path, MAX_PATH + 1, "%s\\players\\raw\\%s", Dvar_GetStringSafe("LOOQOTRNTN"), file); + if (file_exists(path)) { + printf("replacing file %s\n", file); + std::ifstream myfile; + myfile.open(path); + filecontents = ""; + while (myfile) { + std::getline(myfile, curline); + filecontents += curline + "\n"; + } + myfile.close(); + strcpy(buffer, filecontents.c_str()); + return filecontents.c_str();; + } + printf("loading %s\n", file); + return db_getrawbufferinflate.stub(file, buffer, length); +} + +const char* _va(const char* format, ...) { + char _buf[2048]; + va_list ap; + + va_start(ap, format); + vsnprintf(_buf, 2048, format, ap); + _buf[2047] = 0; + return _buf; +} +SpawnPointEntityRecord* g_customSpawns; +char g_customEntityString[0xFFFFFFF]; +utils::hook::detour load_mapentsasset; +void Load_MapEntsAsset_Detour(XAssetHeader* mapEnts) { + auto Scr_AllocGlobalString = reinterpret_cast(0x14131B2C0_g); + char path[MAX_PATH + 1]; + snprintf(path, MAX_PATH + 1, "%s\\players\\raw\\%s", Dvar_GetStringSafe("LOOQOTRNTN"), mapEnts->image->name); + if (file_exists(path)) { + printf("loading %s\n", path); + HANDLE mapEntsFile = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + int numberOfBytesRead = GetFileSize(mapEntsFile, NULL); + if (mapEntsFile != INVALID_HANDLE_VALUE) + { + memset(g_customEntityString, 0, 0xFFFFFFF); + ReadFile(mapEntsFile, g_customEntityString, numberOfBytesRead, (LPDWORD)&numberOfBytesRead, 0); + mapEnts->mapEnts->entityString = g_customEntityString; + mapEnts->mapEnts->numEntityChars = strlen(g_customEntityString) + 1; + CloseHandle(mapEntsFile); + memset(path, 0, MAX_PATH + 1); + snprintf(path, MAX_PATH + 1, "%s\\players\\raw\\%s.spawnlist", Dvar_GetStringSafe("LOOQOTRNTN"), mapEnts->image->name); + if (!file_exists(path)) { + } + else { + nlohmann::json json; + std::ifstream file(path); + file >> json; + file.close(); + mapEnts->mapEnts->spawnList.spawnsCount = json["spawnList"]["spawnsCount"]; + for (int i = 0; i < mapEnts->mapEnts->spawnList.spawnsCount; i++) { + mapEnts->mapEnts->spawnList.spawns[i].index = json["spawnList"][_va("spawns[%i]", i)]["index"]; + mapEnts->mapEnts->spawnList.spawns[i].name = Scr_AllocGlobalString(std::string(json["spawnList"][_va("spawns[%i]", i)]["name"]).c_str()); + mapEnts->mapEnts->spawnList.spawns[i].target = Scr_AllocGlobalString(std::string(json["spawnList"][_va("spawns[%i]", i)]["target"]).c_str()); + mapEnts->mapEnts->spawnList.spawns[i].script_noteworthy = Scr_AllocGlobalString(std::string(json["spawnList"][_va("spawns[%i]", i)]["script_noteworthy"]).c_str()); + + mapEnts->mapEnts->spawnList.spawns[i].origin.v[0] = json["spawnList"][_va("spawns[%i]", i)]["origin"][0]; + mapEnts->mapEnts->spawnList.spawns[i].origin.v[1] = json["spawnList"][_va("spawns[%i]", i)]["origin"][1]; + mapEnts->mapEnts->spawnList.spawns[i].origin.v[2] = json["spawnList"][_va("spawns[%i]", i)]["origin"][2]; + + mapEnts->mapEnts->spawnList.spawns[i].angles.v[0] = json["spawnList"][_va("spawns[%i]", i)]["angles"][0]; + mapEnts->mapEnts->spawnList.spawns[i].angles.v[1] = json["spawnList"][_va("spawns[%i]", i)]["angles"][1]; + mapEnts->mapEnts->spawnList.spawns[i].angles.v[2] = json["spawnList"][_va("spawns[%i]", i)]["angles"][2]; + } + } + } + } + + printf("%s\n", mapEnts->mapEnts->clientTrigger.triggerString); + + load_mapentsasset.stub(mapEnts); +} + +utils::hook::detour load_clipmapasset; +void Load_ClipMapAsset_Detour(XAssetHeader* clipMap) { + load_clipmapasset.stub(clipMap); +} +char g_customBuffer[0x18000]; +utils::hook::detour db_getrawbuffer; +void DB_GetRawBuffer_Detour(const RawFile* rawfile, char* buf, int size) { + char path[MAX_PATH + 1]; + snprintf(path, MAX_PATH + 1, "%s\\players\\raw\\%s", Dvar_GetStringSafe("LOOQOTRNTN"), rawfile->name); + if (file_exists(path)) { + HANDLE mapEntsFile = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + int numberOfBytesRead = GetFileSize(mapEntsFile, NULL); + if (mapEntsFile != INVALID_HANDLE_VALUE) + { + ReadFile(mapEntsFile, g_customBuffer, numberOfBytesRead, (LPDWORD)&numberOfBytesRead, 0); + CloseHandle(mapEntsFile); + strcpy(buf, g_customBuffer); + printf("replacing %s\n", rawfile->name); + } + return; + } + + db_getrawbuffer.stub(rawfile, buf, size); +} + +utils::hook::detour db_pollfastfilestate; +int DB_PollFastfileState_Detour(const char* zoneName) { + if (strcmp(zoneName, "mp_donetsk_cg_ls_tr") == 0) { + return 2; + } + + //printf("%s\n", zoneName); + + return db_pollfastfilestate.stub(zoneName); +} + +utils::hook::detour load_xmodelasset; +void Load_XModelAsset_Detour(XAssetHeader* model) { + load_xmodelasset.stub(model); +} + +utils::hook::detour ddl_setuint; +bool DDL_SetUInt_Detour(const DDLState* state, DDLContext* ddlContext, unsigned int val) { + //ddlContext->obfuscated = false; + //printf("%p - %p\n", state->offset, (uintptr_t)(ddlContext->buff) + state->offset); + + return ddl_setuint.stub(state, ddlContext, val); +} + +utils::hook::detour com_gamemode_supportsfeature; +bool Com_GameMode_SupportsFeature_Detour(unsigned int featureID) +{ + if (featureID == 70) // TIMESCALE_TWEAKING + { + return true; + } + + if (featureID == 33) // GRAVITY_CHANGE_ALLOWED + { + return true; + } + + return com_gamemode_supportsfeature.stub(featureID); +} + +utils::hook::detour sv_updateuserinfo_detour; +void SV_UpdateUserinfo_f(unsigned char* cl) +{ + auto SV_Cmd_Argv = reinterpret_cast(0x141298B10_g); + auto Info_ValueForKey = reinterpret_cast(0x1413F2A10_g); + // more checks can be added here (it's patched in current mw19, vanguard, and mwii, could probably find the actual fix there) + if (!strlen(Info_ValueForKey(SV_Cmd_Argv(1), "platform"))) + { + return; + } + sv_updateuserinfo_detour.stub(cl); +} + +utils::hook::detour lui_cod_luacall_getblueprintdata_impl; +int LUI_CoD_LuaCall_GetBlueprintData_impl_Detour(uintptr_t luaState) +{ + SaveInventory(); + return 0; +} + +void* exception_handler_handle; +BOOL WINAPI DllMain(HMODULE hModule, DWORD Reason, LPVOID lpVoid) { + g_Addrs.ModuleBase = (uintptr_t)(GetModuleHandle(0)); + utils::hook::set(0x1403061A0_g, 0xC3); // Mystery function 1 + if (Reason == DLL_PROCESS_ATTACH) { + AllocConsole(); + FILE* Dummy; + freopen_s(&Dummy, "CONOUT$", "w", stdout); + freopen_s(&Dummy, "CONIN$", "r", stdin); + + utils::nt::library game{}; + utils::nt::library user32("user32.dll"); + utils::nt::library ntdll("ntdll.dll"); + utils::nt::library kernel32("kernel32.dll"); + + va = (const char* (*)(const char*, ...))0x1413F3010_g; //j_va + + nlog("Base Address: %p\n", base); + + cmd_args = (CmdArgs*)(0x14D20CBD0_g); + + //utils::hook::jump(0x141BD3360_g, sub_141BD3360_Detour); + + //sub_141BD3360.create(0x141BD3360_g, sub_141BD3360_Detour); + + // utils::hook::copy(0x1530AD525_g, data_buf, 0x12856B); // Splash screen data + + Cmd_AddCommandInternal("set_byte", set_byte_f, &set_byte_f_VAR); + Cmd_AddCommandInternal("set_short", set_short_f, &set_short_f_VAR); + Cmd_AddCommandInternal("set_int", set_int_f, &set_int_f_VAR); + Cmd_AddCommandInternal("set_float", set_float_f, &set_float_f_VAR); + Cmd_AddCommandInternal("set_pointer", set_pointer_f, &set_pointer_f_VAR); + Cmd_AddCommandInternal("quit", Cmd_Quit_f, &quit_f_VAR); + Cmd_AddCommandInternal("openmenu", Cmd_OpenMenu_f, &openmenu_f_VAR); + Cmd_AddCommandInternal("addbot", Cmd_AddBot_f, &addbot_f_VAR); + Cmd_AddCommandInternal("ddldump", Cmd_DDLDump_f, &ddldump_f_VAR); + Cmd_AddCommandInternal("weapondefdump", Cmd_WeaponDefDump_f, &weapondefdump_f_VAR); + //Cmd_AddCommandInternal("view_vehicle_ents", Cmd_ViewVehicleEnts_f, &view_vehicle_ents_f_VAR); + // Cmd_AddCommandInternal("save_inventory", Cmd_LoadoutSave_f, &loadout_save_f_VAR); + Cmd_AddCommandInternal("map_restart", SV_CmdsMP_MapRestart_f, &MapRestart_f_VAR); + Cmd_AddCommandInternal("fast_restart", SV_CmdsMP_FastRestart_f, &FastRestart_f_VAR); + Cmd_AddCommandInternal("setOmnvar", Cmd_Omnvar_Set_f, &omnvar_set_f_VAR); + // Cmd_AddCommandInternal("dumpomnvars", Cmd_Omnvars_Dump_f, &omnvar_dump_f_VAR); + + // patch ui_maxclients limit + utils::hook::nop(0x140F30210_g, 5); + utils::hook::nop(0x14119E51D_g, 5); + utils::hook::nop(0x14136B8F8_g, 5); + utils::hook::nop(0x1416029F0_g, 5); + utils::hook::nop(0x1419E19A3_g, 5); + + // patch party_maxplayers limit + utils::hook::nop(0x140F252EE_g, 5); + utils::hook::nop(0x14119D23F_g, 5); + utils::hook::nop(0x1410769B9_g, 5); + utils::hook::set(0x1410769B9_g, 0xC3); + utils::hook::nop(0x140F24B4B_g, 5); + utils::hook::set(0x140F24B4B_g, 0xC3); + utils::hook::nop(0x1416029E2_g, 5); + utils::hook::nop(0x14119E52B_g, 5); + utils::hook::nop(0x140f252EE_g, 5); + utils::hook::nop(0x14119F13A_g, 5); + utils::hook::nop(0x1410D32E2_g, 5); + + // patch userinfo crash exploit + // utils::hook::nop(0x14136D0EA_g, 5); + sv_updateuserinfo_detour.create(0x14136d0c0_g, SV_UpdateUserinfo_f); + + db_findxassetheader.create(0x1411AA890_g, DB_FindXAssetHeader_Detour); + db_getrawbufferinflate.create(0x1412C2AE0_g, DB_GetRawBufferInflate_Detour); + ddl_setuint.create(0x1420529C0_g, DDL_SetUInt_Detour); + //db_pollfastfilestate.create(0x1411ADD00_g, DB_PollFastfileState_Detour); + + load_mapentsasset.create(0x140F61690_g, Load_MapEntsAsset_Detour); + load_clipmapasset.create(0x140F60F40_g, Load_ClipMapAsset_Detour); + load_xmodelasset.create(0x140F62290_g, Load_XModelAsset_Detour); + //load_ttfasset.create(0x140F61F40_g, Load_TTFAsset_Detour); + + db_getrawbuffer.create(0x1412C29A0_g, DB_GetRawBuffer_Detour); + + utils::hook::jump(0x141528490_g, Live_IsUserSignedInToDemonware_Detour); + utils::hook::jump(0x1417EC930_g, dwGetLogOnStatus_Detour); + utils::hook::jump(0x1412A1EB0_g, LiveStorage_GetActiveStatsSource_Detour); + utils::hook::jump(0x1419B96A0_g, LuaShared_LuaCall_IsDemoBuild_Detour); + + dvar_findvarbyname.create(0x1413E63A0_g, Dvar_FindVarByName_Detour); + + db_loadxfile.create(0x1411A79F0_g, DB_LoadXFile_Detour); + CL_TransientsMP_ProcessLoadingQueue.create(0x1415F7BF0_g, CL_TransientsMP_ProcessLoadingQueue_Detour); + + lui_cod_registerdvars.create(0x1419D4500_g, LUI_CoD_RegisterDvars_Detour); + net_outofbanddata.create(0x1412BB350_g, NET_OutOfBandData_Detour); + cl_keys_event.create(0x1415BEB80_g, CL_Keys_Event_Detour); + dvar_registerbool.create(0x1413E7670_g, Dvar_RegisterBool_Detour); + dvar_registerstring.create(0x1413E7A70_g, Dvar_RegisterString_Detour); + seh_stringed_getstring.create(0x1413CC2A0_g, SEH_StringEd_GetString_Detour); + + cl_createdevgui.create(0x1415B2080_g, CL_CreateDevGui_Detour); + partyhost_startprivateparty.create(0x14119F0D0_g, PartyHost_StartPrivateParty_Detour); + + PM_WeaponUseAmmo.create(0x141155AF0_g, PM_WeaponUseAmmo_Detour); + + com_gamemode_supportsfeature.create(0x1410C8980_g, Com_GameMode_SupportsFeature_Detour); + + lui_cod_luacall_getblueprintdata_impl.create(0x140F58A00_g, LUI_CoD_LuaCall_GetBlueprintData_impl_Detour); + + clientUIActives = (clientUIActive_t*)(0x14EEF1280_g); + + // removes "Services aren't ready yet." print + utils::hook::nop(0x141504374_g, 5); + + // enable tweaking of jump_slowdownEnable dvar + utils::hook::nop(0x1411014F5_g, 2); + utils::hook::nop(0x141101B12_g, 2); + utils::hook::nop(0x141101C6C_g, 2); + utils::hook::nop(0x141101D3C_g, 2); + utils::hook::nop(0x141101EE5_g, 2); + + // fixes lost connection issue? + utils::hook::nop(0x14165E97E_g, 5); + utils::hook::nop(0x14165E660_g, 5); + utils::hook::nop(0x141665289_g, 5); + utils::hook::nop(0x14166567D_g, 5); + } + + return TRUE; +} + +void nlog(const char* str, ...) { + va_list ap; + HWND notepad, edit; + char buf[256]; + + va_start(ap, str); + vsprintf(buf, str, ap); + va_end(ap); + strcat(buf, ""); + log(buf); +} +void nlog(const char* file, const char* str, ...) { + va_list ap; + HWND notepad, edit; + char buf[256]; + + va_start(ap, str); + vsprintf(buf, str, ap); + va_end(ap); + strcat(buf, ""); + log(file, buf); +} + +uintptr_t find_pattern(const char* module_name, const char* pattern) { + const auto get_module_size = [=](uintptr_t module_base) + { + return reinterpret_cast(module_base + reinterpret_cast(module_base)->e_lfanew)->OptionalHeader.SizeOfImage; + }; + const auto module_start = (uintptr_t)GetModuleHandle(module_name); + if (module_start != 0ULL) + { + const auto module_end = module_start + get_module_size(module_start); + + const char* pattern_current = pattern; + uintptr_t current_match = NULL; + + MEMORY_BASIC_INFORMATION64 page_information = {}; + for (auto current_page = reinterpret_cast(module_start); current_page < reinterpret_cast(module_end); current_page = reinterpret_cast(page_information.BaseAddress + page_information.RegionSize)) + { + VirtualQuery(reinterpret_cast(current_page), reinterpret_cast(&page_information), sizeof(MEMORY_BASIC_INFORMATION)); + if (page_information.Protect == PAGE_NOACCESS) + continue; + + if (page_information.State != MEM_COMMIT) + continue; + + if (page_information.Protect & PAGE_GUARD) + continue; + + for (auto current_address = reinterpret_cast(page_information.BaseAddress); current_address < reinterpret_cast(page_information.BaseAddress + page_information.RegionSize - 0x8); current_address++) + { + if (*current_address != GET_BYTE(pattern_current) && *pattern_current != '\?') { + current_match = 0ULL; + pattern_current = pattern; + continue; + } + + if (!current_match) + current_match = reinterpret_cast(current_address); + + pattern_current += 3; + if (pattern_current[-1] == NULL) + return current_match; + } + } + } + + return 0ULL; +} + +uintptr_t find_pattern(uintptr_t start, const char* module_name, const char* pattern) { + const auto get_module_size = [=](uintptr_t module_base) + { + return reinterpret_cast(module_base + reinterpret_cast(module_base)->e_lfanew)->OptionalHeader.SizeOfImage; + }; + const auto module_start = start; + if (module_start != 0ULL) + { + const auto module_end = module_start + get_module_size(module_start); + + const char* pattern_current = pattern; + uintptr_t current_match = NULL; + + MEMORY_BASIC_INFORMATION64 page_information = {}; + for (auto current_page = reinterpret_cast(module_start); current_page < reinterpret_cast(module_end); current_page = reinterpret_cast(page_information.BaseAddress + page_information.RegionSize)) + { + VirtualQuery(reinterpret_cast(current_page), reinterpret_cast(&page_information), sizeof(MEMORY_BASIC_INFORMATION)); + if (page_information.Protect == PAGE_NOACCESS) + continue; + + if (page_information.State != MEM_COMMIT) + continue; + + if (page_information.Protect & PAGE_GUARD) + continue; + + for (auto current_address = reinterpret_cast(page_information.BaseAddress); current_address < reinterpret_cast(page_information.BaseAddress + page_information.RegionSize - 0x8); current_address++) + { + if (*current_address != GET_BYTE(pattern_current) && *pattern_current != '\?') { + current_match = 0ULL; + pattern_current = pattern; + continue; + } + + if (!current_match) + current_match = reinterpret_cast(current_address); + + pattern_current += 3; + if (pattern_current[-1] == NULL) + return current_match; + } + } + } + + return 0ULL; +} +menu_variables vars; + +size_t operator"" _b(const size_t val) +{ + return base + val; +} + +size_t reverse_b(const size_t val) +{ + return val - base; +} + +size_t reverse_b(const void* val) +{ + return reverse_b(reinterpret_cast(val)); +} + +size_t operator"" _g(const size_t val) +{ + return base + (val - 0x140000000); +} + +size_t reverse_g(const size_t val) +{ + return (val - base) + 0x140000000; +} + +size_t reverse_g(const void* val) +{ + return reverse_g(reinterpret_cast(val)); +} + +void log(const char* str) { + std::ofstream outputFile("output.log", std::ios::app); + if (outputFile.is_open()) { + outputFile << str; + outputFile.close(); + } + else { + std::cout << "Failed to open file for appending." << std::endl; + } +} + +void log(const char* file, const char* str) { + try { + std::ofstream outputFile(file, std::ios::app); + if (!outputFile.is_open()) { + throw std::runtime_error("Failed to open file for appending."); + } + + outputFile << str; + } + catch (const std::exception& e) { + printf("%s\n", e.what()); + } } \ No newline at end of file diff --git a/hook_lib/Main.hpp b/hook_lib/Main.hpp index 0d1193e..7e9cfe5 100644 --- a/hook_lib/Main.hpp +++ b/hook_lib/Main.hpp @@ -1,117 +1,117 @@ -#pragma once -#include -#include -#include -#include -#include - -#include -#include -#include - -#pragma comment(lib, "ws2_32.lib") -#pragma comment(lib, "user32.lib") - -#include "common/utils/hook.hpp" -#include "common/utils/hardware_breakpoint.hpp" -#include "functions.hpp" -#include "structs.h" -#include "assets.h" - -#include "ini.h" -#include "json.hpp" -#include "splashscreen.hpp" - -extern void* exception_handler; - -#define base g_Addrs.ModuleBase - -#pragma warning(disable:4996) -#pragma comment(lib, "Gdi32.lib") - - - - -#define INRANGE(x, a, b) (x >= a && x <= b) -#define GET_BITS( x ) (INRANGE((x&(~0x20)),'A','F') ? ((x&(~0x20)) - 'A' + 0xa) : (INRANGE(x,'0','9') ? x - '0' : 0)) -#define GET_BYTE( x ) (GET_BITS(x[0]) << 4 | GET_BITS(x[1])) - -struct menu_variables { - bool bInitiateMenu; - bool bMenuOpen; - -}; -extern menu_variables vars; - -void nlog(const char* str, ...); -uintptr_t find_pattern(const char* module_name, const char* pattern); -uintptr_t find_pattern(uintptr_t start, const char* module_name, const char* pattern); - -size_t operator"" _b(size_t val); -size_t reverse_b(size_t val); -size_t reverse_b(const void* val); - -size_t operator"" _g(size_t val); -size_t reverse_g(size_t val); -size_t reverse_g(const void* val); - -void log(const char* str); -void log(const char* file, const char* str); - -struct DvarPair -{ - const char* m_key; - const char* m_value; -}; -inline bool IsBadPointer(uintptr_t* ptr) -{ - __try - { - volatile auto result = *ptr; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - return true; - } - return false; -} - -struct DvarMap -{ - DvarPair m_pairs[10000]; -}; -extern int g_dvarmapcount; -extern DvarPair g_dvarmap[6821]; - -struct shaderOverride_t -{ - float scrollRateX; - float scrollRateY; - float scrollRateR; - float tilingX; - float tilingY; - float rotation; - float alpha; - float emissive; - float atlasTime; -}; - -struct GfxSceneHudOutlineInfo -{ - unsigned int color; - float scopeStencil; - bool drawOccludedPixels; - bool drawNonOccludedPixels; - bool fill; - bool useAlternateColor; - bool forSpectator; - bool specialActive; - unsigned __int8 renderMode; - unsigned __int8 lineWidth; - unsigned __int8 temperatureSet; - unsigned int mapEntLookup; - float temperatureBase; - float temperatureScale; - float characterEVOffset; -}; - +#pragma once +#include +#include +#include +#include +#include + +#include +#include +#include + +#pragma comment(lib, "ws2_32.lib") +#pragma comment(lib, "user32.lib") + +#include "common/utils/hook.hpp" +#include "common/utils/hardware_breakpoint.hpp" +#include "functions.hpp" +#include "structs.h" +#include "assets.h" + +#include "ini.h" +#include "json.hpp" +#include "splashscreen.hpp" + +extern void* exception_handler; + +#define base g_Addrs.ModuleBase + +#pragma warning(disable:4996) +#pragma comment(lib, "Gdi32.lib") + + + + +#define INRANGE(x, a, b) (x >= a && x <= b) +#define GET_BITS( x ) (INRANGE((x&(~0x20)),'A','F') ? ((x&(~0x20)) - 'A' + 0xa) : (INRANGE(x,'0','9') ? x - '0' : 0)) +#define GET_BYTE( x ) (GET_BITS(x[0]) << 4 | GET_BITS(x[1])) + +struct menu_variables { + bool bInitiateMenu; + bool bMenuOpen; + +}; +extern menu_variables vars; + +void nlog(const char* str, ...); +uintptr_t find_pattern(const char* module_name, const char* pattern); +uintptr_t find_pattern(uintptr_t start, const char* module_name, const char* pattern); + +size_t operator"" _b(size_t val); +size_t reverse_b(size_t val); +size_t reverse_b(const void* val); + +size_t operator"" _g(size_t val); +size_t reverse_g(size_t val); +size_t reverse_g(const void* val); + +void log(const char* str); +void log(const char* file, const char* str); + +struct DvarPair +{ + const char* m_key; + const char* m_value; +}; +inline bool IsBadPointer(uintptr_t* ptr) +{ + __try + { + volatile auto result = *ptr; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return true; + } + return false; +} + +struct DvarMap +{ + DvarPair m_pairs[10000]; +}; +extern int g_dvarmapcount; +extern DvarPair g_dvarmap[6821]; + +struct shaderOverride_t +{ + float scrollRateX; + float scrollRateY; + float scrollRateR; + float tilingX; + float tilingY; + float rotation; + float alpha; + float emissive; + float atlasTime; +}; + +struct GfxSceneHudOutlineInfo +{ + unsigned int color; + float scopeStencil; + bool drawOccludedPixels; + bool drawNonOccludedPixels; + bool fill; + bool useAlternateColor; + bool forSpectator; + bool specialActive; + unsigned __int8 renderMode; + unsigned __int8 lineWidth; + unsigned __int8 temperatureSet; + unsigned int mapEntLookup; + float temperatureBase; + float temperatureScale; + float characterEVOffset; +}; + diff --git a/hook_lib/__game_dx12_ship_replay b/hook_lib/__game_dx12_ship_replay deleted file mode 100644 index 1f63f4c..0000000 Binary files a/hook_lib/__game_dx12_ship_replay and /dev/null differ diff --git a/hook_lib/assets.cpp b/hook_lib/assets.cpp index 0f8d2df..7d08aa2 100644 --- a/hook_lib/assets.cpp +++ b/hook_lib/assets.cpp @@ -1,6 +1,6 @@ -#include "assets.h" - - -void test() { - sizeof(VehicleDef); +#include "assets.h" + + +void test() { + sizeof(VehicleDef); } \ No newline at end of file diff --git a/hook_lib/assets.h b/hook_lib/assets.h index 6d77034..1aee26e 100644 --- a/hook_lib/assets.h +++ b/hook_lib/assets.h @@ -1,4383 +1,4383 @@ -#pragma once -#include "Main.hpp" - -struct RumbleGraph; -struct RumbleInfo; -struct CameraDef; -struct GfxImage; -struct Material; -struct Bounds; -struct FxCombinedDef; - -struct vec2_t -{ - float v[2]; -}; - -struct vec3_t -{ - float v[3]; -}; - -struct vec4_t -{ - float v[4]; -}; - -typedef int scr_string_t; - -struct Bounds -{ - vec3_t midPoint; - vec3_t halfSize; -}; - -struct GfxDrawSurfFields -{ - unsigned __int64 indirectArgsOffset : 10; - unsigned __int64 gpBatchIndex : 16; - unsigned __int64 objectId : 24; - unsigned __int64 hasGfxEntIndex : 1; - unsigned __int64 lightmapIndex : 9; - unsigned __int64 shadowcaster : 1; - unsigned __int64 materialSortedIndex : 16; - unsigned __int64 tessellation : 3; - unsigned __int64 prepass : 2; - unsigned __int64 viewModelRender : 1; - unsigned __int64 lowResShading : 1; - unsigned __int64 surfType : 4; - unsigned __int64 primarySortKey : 6; -}; - -struct EffectDefMap { - char name[64]; - char filename[256]; -}; - -struct Packed128 -{ - unsigned __int64 p0; - unsigned __int64 p1; -}; - -union GfxDrawSurf -{ - GfxDrawSurfFields fields; - Packed128 packed; -}; - -struct MaterialTextureDef -{ - unsigned __int8 index; - GfxImage* image; -}; - -struct MaterialConstantDef -{ - unsigned __int8 index; - vec4_t literal; -}; - -struct GfxDecalVolumeMaterial -{ - const char* name; - GfxImage* channels[6]; - unsigned int flags; - vec3_t colorTint; - float alphaDissolveParms; - float emissiveScale; - unsigned int packedDisplacementScaleAndBias; - float displacementCutoffDistance; - float displacementCutoffFalloff; - unsigned int packedTemperatureBaseAndScale; - unsigned __int8 textureAtlasRowCount; - unsigned __int8 textureAtlasColumnCount; - unsigned __int8 padding[6]; -}; - -struct PhysicsAssetUsageCounter -{ - int serverEnt; - int clientEnt; - int dynEnt; -}; - -struct __declspec(align(4)) PhysicsAsset -{ - const char* name; - char* havokData; - unsigned int havokDataSize; - int useCategory; - int numRigidBodies; - int numConstraints; - uintptr_t simulationCategories; - unsigned int* bodyContents; - int numSFXEventAssets; - int numVFXEventAssets; - uintptr_t sfxEventAssets; - uintptr_t vfxEventAssets; - PhysicsAssetUsageCounter usageCounter; - bool containsDynamicBodies; -}; - -struct Material -{ - const char* name; - unsigned int contents; - unsigned int surfaceFlags; - float maxDisplacement; - int /*MaterialGeometryType*/ materialType; - unsigned __int8 cameraRegion; - unsigned __int8 sortKey; - unsigned __int16 flags; - unsigned __int8 textureCount; - unsigned __int8 constantCount; - unsigned __int8 constantBufferCount; - unsigned __int8 layerCount; - unsigned __int16 packedAtlasDataSize; - unsigned __int8 textureAtlasRowCount; - unsigned __int8 textureAtlasColumnCount; - GfxDrawSurf drawSurf; - unsigned __int8* packedAtlasData; - void* /*MaterialTechniqueSet*/ techniqueSet; - MaterialTextureDef* textureTable; - MaterialConstantDef* constantTable; - GfxDecalVolumeMaterial* decalVolumeMaterial; - unsigned __int8* constantBufferIndex; - void* /*MaterialConstantBufferDef*/ constantBufferTable; - const char** subMaterials; -}; - -enum GfxTextureId : __int32 -{ - NULLID = 0x0, -}; - -enum GfxPixelFormat : __int32 -{ - GFX_PF_INVALID = 0x0, - GFX_PF_R8 = 0x1, - GFX_PF_A8 = 0x2, - GFX_PF_L8 = 0x3, - GFX_PF_R8G8 = 0x4, - GFX_PF_L8A8 = 0x5, - GFX_PF_R8G8B8A8 = 0x6, - GFX_PF_R8G8B8A8_SRGB = 0x7, - GFX_PF_R8_SNORM = 0x8, - GFX_PF_R8G8_SNORM = 0x9, - GFX_PF_R16 = 0xA, - GFX_PF_R16G16 = 0xB, - GFX_PF_R16G16B16A16 = 0xC, - GFX_PF_R16_SNORM = 0xD, - GFX_PF_R16F = 0xE, - GFX_PF_R16G16F = 0xF, - GFX_PF_R16G16B16A16F = 0x10, - GFX_PF_R32F = 0x11, - GFX_PF_R32G32F = 0x12, - GFX_PF_R32G32B32A32F = 0x13, - GFX_PF_D16 = 0x14, - GFX_PF_D32F = 0x15, - GFX_PF_D32F_S8 = 0x16, - GFX_PF_R8_UINT = 0x17, - GFX_PF_R16_UINT = 0x18, - GFX_PF_R32_UINT = 0x19, - GFX_PF_R32G32_UINT = 0x1A, - GFX_PF_R32G32B32A32_UINT = 0x1B, - GFX_PF_R10G10B10A2_UINT = 0x1C, - GFX_PF_R5G6B5 = 0x1D, - GFX_PF_R10G10B10A2 = 0x1E, - GFX_PF_R9G9B9E5_SHAREDEXP = 0x1F, - GFX_PF_R11G11B10F = 0x20, - GFX_PF_BC1 = 0x21, - GFX_PF_BC1_SRGB = 0x22, - GFX_PF_BC2 = 0x23, - GFX_PF_BC2_SRGB = 0x24, - GFX_PF_BC3 = 0x25, - GFX_PF_BC3_SRGB = 0x26, - GFX_PF_BC4 = 0x27, - GFX_PF_BC5 = 0x28, - GFX_PF_BC5S = 0x29, - GFX_PF_BC6H = 0x2A, - GFX_PF_BC6HS = 0x2B, - GFX_PF_BC7 = 0x2C, - GFX_PF_BC7_SRGB = 0x2D, - GFX_PF_R8G8B8A8_SNORM = 0x2E, - GFX_PF_R1 = 0x2F, - GFX_PF_R4G4 = 0x30, - GFX_PF_R10G10B10A2_SNORM = 0x31, - GFX_PF_COUNT = 0x32, -}; - -enum GfxImageFlags -{ - IMG_FLAG_NONE = 0x0, - IMG_DISK_FLAG_NOPICMIP = 0x1, - IMG_DISK_FLAG_NOMIPMAPS = 0x2, - IMG_DISK_FLAG_UNUSED = 0x4, - IMG_DISK_FLAG_NORMAL_OCCLUSON_GLOSS = 0x8, - IMG_DISK_FLAG_CLAMP_U = 0x10, - IMG_DISK_FLAG_CLAMP_V = 0x20, - IMG_DISK_FLAG_STREAMED = 0x40, - IMG_DISK_FLAG_USE_OODLE_COMPRESSION = 0x80, - IMG_DISK_FLAG_GAMMA_SRGB = 0x100, - IMG_DISK_FLAG_PACKED_ATLAS = 0x200, - IMG_CREATE_FLAG_UNTILED = 0x400, - IMG_CREATE_FLAG_CPU_READ = 0x800, - IMG_CREATE_FLAG_CPU_WRITE = 0x1000, - IMG_DISK_FLAG_AUTOMETALNESS = 0x2000, - IMG_DISK_FLAG_AUTODISPLACEMENT = 0x4000, - IMG_DISK_FLAG_MAPTYPE_2D = 0x0, - IMG_DISK_FLAG_MAPTYPE_CUBE = 0x8000, - IMG_DISK_FLAG_MAPTYPE_3D = 0x10000, - IMG_DISK_FLAG_MAPTYPE_1D = 0x18000, - IMG_DISK_FLAG_MAPTYPE_ARRAY = 0x20000, - IMG_DISK_FLAG_MAPTYPE_CUBE_ARRAY = 0x28000, - IMG_DISK_FLAG_INVERT_ALPHA = 0x40000, - IMG_DISK_FLAG_PREMUL_ALPHA = 0x80000, - IMG_DISK_FLAG_MIPGEN_ORIGINAL = 0x0, - IMG_DISK_FLAG_MIPGEN_LANCZOS3 = 0x100000, - IMG_DISK_FLAG_MIPGEN_CATMULL_ROM = 0x200000, - IMG_DISK_FLAG_MIPGEN_CUBIC_BSPLINE = 0x300000, - IMG_DISK_FLAG_MIPGEN_BOX = 0x400000, - IMG_DISK_FLAG_MIPGEN_COVERAGE_PRESERVING = 0x500000, - IMG_CREATE_FLAG_RW_VIEW = 0x800000, - IMG_CREATE_FLAG_DYNAMIC = 0x1000000, - IMG_DISK_FLAG_PREMUL_KEEP_ALPHA = 0x2000000, - IMG_DISK_FLAG_RTT = 0x4000000, - IMG_DISK_FLAG_EXTRACT_ALPHA = 0x8000000, - IMG_DISK_FLAG_OCTAHEDRON = 0x10000000, - IMG_CREATE_FLAG_STAGING = 0x20000000, - IMG_CREATE_FLAG_VOLUMETRIC_LAYOUT_OVERRIDE = 0x40000000, - IMG_CREATE_FLAG_TYPELESS = 0x80000000, -}; - -union GfxImageSemanticSpecific -{ - float atlasFps; - unsigned int albedoMapScaleBias; - unsigned int normalMapScaleBias; - unsigned int maxMipMap; -}; - -struct GfxImageAtlasSize -{ - unsigned __int8 rowCount; - unsigned __int8 colCount; -}; - -union GfxImageAtlasInfo -{ - GfxImageAtlasSize atlasSize; - unsigned __int16 packedAtlasDataSize; -}; - -enum TextureSemantic : __int8 -{ - TS_2D = 0x0, - TS_FUNCTION = 0x1, - TS_COLOR_MAP = 0x2, - TS_GRAY_MAP = 0x3, - TS_SIGNED_VELOCITY_MAP = 0x4, - TS_NORMAL_MAP = 0x5, - TS_METALNESS_MAP = 0x6, - TS_NORMAL_OCCLUSION_GLOSS_MAP = 0x7, - TS_SIGNED_DISTANCE_FIELD = 0x8, - TS_CARD_IMPOSTER_NORMAL = 0x9, - TS_COUNT = 0xA, -}; - -enum GfxImageCategory : __int8 -{ - IMG_CATEGORY_UNKNOWN = 0x0, - IMG_CATEGORY_AUTO_GENERATED = 0x1, - IMG_CATEGORY_LIGHTMAP = 0x2, - IMG_CATEGORY_LOAD_FROM_FILE = 0x3, - IMG_CATEGORY_RAW = 0x4, - IMG_CATEGORY_FIRST_UNMANAGED = 0x5, - IMG_CATEGORY_RENDERTARGET = 0x5, - IMG_CATEGORY_TEMP = 0x6, -}; - -struct XPakEntryInfo -{ - unsigned __int64 key; - __int64 offset; - unsigned __int64 size; - unsigned __int64 xpakIndex : 8; - unsigned __int64 compressed : 1; - unsigned __int64 valid : 1; - unsigned __int64 adjacentLeftType : 3; - unsigned __int64 adjacentRightType : 3; - unsigned __int64 adjacentLeft : 19; - unsigned __int64 adjacentRight : 19; - unsigned __int64 padding : 10; -}; - -enum GfxImageStreamLevelCountAndSize : __int32 -{ -}; - -struct GfxImageStreamData -{ - XPakEntryInfo xpakEntry; - GfxImageStreamLevelCountAndSize levelCountAndSize; - unsigned __int16 width; - unsigned __int16 height; -}; - -struct streamer_handle_t -{ - unsigned __int64 data; -}; - -struct GfxImageFallback -{ - unsigned __int8* pixels; - unsigned int size; - unsigned __int16 width; - unsigned __int16 height; -}; - -union GfxImagePixels -{ - streamer_handle_t streamedDataHandle; - unsigned __int8* residentData; -}; - - -struct GfxImage -{ - const char* name; - unsigned __int8* packedAtlasData; - GfxTextureId textureId; - GfxPixelFormat format; - GfxImageFlags flags; - unsigned int totalSize; - GfxImageSemanticSpecific semanticSpecific; - unsigned __int16 width; - unsigned __int16 height; - unsigned __int16 depth; - unsigned __int16 numElements; - GfxImageAtlasInfo atlasInfo; - TextureSemantic semantic; - GfxImageCategory category; - unsigned __int8 levelCount; - unsigned __int8 streamedPartCount; - unsigned __int8 decalAtlasIndex; - char freqDomainMetricBias; - GfxImageStreamData streams[4]; - GfxImageFallback* fallback; - GfxImagePixels pixels; -}; - -struct AttachmentList -{ - unsigned int attachmentCount; - void** /*WeaponAttachment*/ attachments; -}; - -struct __declspec(align(4)) SceneZoomSettings -{ - int adsZoomCount; - float adsZoomFov[3]; - float adsReloadFov[3]; - int adsZoomFovTransitionTime[3]; - int /*AdsOffsetInterpolationType*/ adsZoomFovLerpType; - float adsZoomInFrac; - float adsZoomOutFrac; - float adsFOVNVG; - float adsReloadFovNVG; - bool adsZoomLevelIndexResetOnToggle; -}; - -struct __declspec(align(4)) WeaponZoomSettings -{ - float adsZoomFov; - int /*AdsOffsetInterpolationType*/ adsZoomFovLerpType; - float adsZoomFovXOffset; - float adsReloadZoomFov; - float adsReloadZoomFovXOffset; - float adsNVGZoomFov; - float adsNVGZoomFovXOffset; - float adsNVGReloadZoomFov; - float adsNVGReloadZoomFovXOffset; - float adsZoomInFrac; - float adsZoomOutFrac; - bool adsZoomFovXOffsetOverride; - bool adsReloadFovXOffsetOverride; -}; - -struct ZoomSettings -{ - SceneZoomSettings scene; - WeaponZoomSettings weapon; -}; - - -struct WeaponEntityNotify -{ - int flags; - float radius; - float height; - float minSpeed; -}; - - - -struct XModelPhysicsUsageCounter { - int serverEnt; - int clientEnt; - int dynEnt; -}; - -struct DObjAnimMat { - float quat[4]; - float trans[3]; - float transWeight; -}; - -struct XModel { - const char* name; - unsigned __int16 numsurfs; - unsigned __int8 numLods; - unsigned __int8 collLod; - unsigned __int16 mdaoVolumeCount; - unsigned __int8 shadowCutoffLod; - int physicsUseCategory; - char characterCollBoundsType; - unsigned __int8 numAimAssistBones; - unsigned __int8 impactType; - unsigned __int8 mdaoType; - unsigned __int8 numBones; - unsigned __int8 numRootBones; - unsigned __int16 numClientBones; - unsigned __int8 numClothAssets; - unsigned int flags; - int contents; - float scale; - float radius; - Bounds bounds; - float edgeLength; - unsigned int lgvData; - XModelPhysicsUsageCounter physicsUsageCounter; - unsigned int noScalePartBits[8]; - void* scriptableMoverDef; - void* proceduralBones; - void* dynamicBones; - scr_string_t* aimAssistBones; - scr_string_t* boneNames; - unsigned __int8* parentList; - __int16* quats; - float* trans; - unsigned __int8* partClassification; - DObjAnimMat* baseMat; - vec3_t* ikHingeAxis; - uintptr_t reactiveMotionInfo; - uintptr_t materialHandles; -}; - -struct WeaponAnimPackage -{ - const char* name; - uintptr_t anims; - uintptr_t timers; - int meleeAnimPrimaryType; - int meleeAnimPrimaryCount; - unsigned __int8 meleeAnimPrimarySet; - bool meleeRandomizeAnims; - int meleeAnimAltType; - int meleeAnimAltCount; - unsigned __int8 meleeAnimAltSet; - bool altMeleeRandomizeAnims; - uintptr_t blendSpaces; - uintptr_t footstep; -}; - -union XAnimIndices -{ - unsigned __int8* _1; - unsigned __int16* _2; - void* data; -}; - -struct XAnimParts -{ - const char* name; - scr_string_t* names; - unsigned __int8* dataByte; - __int16* dataShort; - int* dataInt; - __int16* randomDataShort; - unsigned __int8* randomDataByte; - int* randomDataInt; - XAnimIndices indices; - uintptr_t notify; - uintptr_t deltaPart; - unsigned int randomDataShortCount; - unsigned int randomDataByteCount; - unsigned int indexCount; - float framerate; - float frequency; - unsigned int dataByteCount; - unsigned __int16 dataShortCount; - unsigned __int16 dataIntCount; - unsigned __int16 randomDataIntCount; - unsigned __int16 numframes; - unsigned __int8 flags; - unsigned __int8 boneCount[10]; - unsigned __int8 notifyCount; - unsigned __int8 assetType; - unsigned __int8 ikType; - unsigned __int8 fingerPoseType; - unsigned __int16 blendShapeWeightCount; - scr_string_t* blendShapeWeightNames; - unsigned __int16* blendShapeWeights; -}; - -struct WeaponDamageCommon -{ - int minDamage; - int mid1Damage; - int mid2Damage; - int mid3Damage; - int damage; - float maxDamageRange; - float mid1DamageRange; - float mid2DamageRange; - float mid3DamageRange; - float minDamageRange; -}; - -struct WeaponDamageInfo -{ - WeaponDamageCommon damageData[3]; - int deathAnimDamageType; - float terminateAtRange; -}; - -struct WeaponVFXPackage -{ - const char* name; - uintptr_t vfx; -}; - -struct __declspec(align(4)) TriggerDisconnectSoundData -{ - float analogTriggerValue; - bool enabledForFireType[6]; -}; - -struct __declspec(align(8)) WeaponSFXPackage -{ - const char* name; - uintptr_t sounds; - WeaponSFXPackage* transientFallbackPackage; - uintptr_t detailSoundBankNPC; - uintptr_t detailSoundBankPlayer; - unsigned __int8 rattleSoundType; - const char* szAdsrBaseSetting; - const char* szWeapSndReflectionClass; - const char* szWeapSndReflFrontOverride; - const char* szWeapSndReflDistantOverride; - float weapSndFireVolumeShot1; - float weapSndFireVolumeShot2; - float weapSndFireVolumeShot3; - float weapSndProneFireLFEVolume; - float weapSndMediumRangeStart; - float weapSndFarRangeStart; - float weapSndDistantRangeStart; - unsigned int projExplosionReflClass; - int sfxImpactType; - int sfxMeleeImpactType; - int sfxMaterialType; - const char* szMountEnterExitString; - const char* szMountImpactString; - unsigned int whizbyType; - unsigned int adsContextType; - unsigned int adsContextValue; - float speedOfSoundMult; - TriggerDisconnectSoundData triggerDisconnectSoundData; -}; - -struct __declspec(align(8)) ADSOverlay -{ - Material* shaderMat; - Material* shaderLowResMat; - Material* shaderEMPMat; - Material* shaderEMPLowResMat; - GfxImage* shaderImg; - GfxImage* shaderLowResImg; - GfxImage* shaderEMPImg; - GfxImage* shaderEMPLowResImg; - bool applyVisionSet; - int reticle; - float width; - float height; - float widthSplitscreen; - float heightSplitscreen; - const char* visionSetName; - float visionSetADSFraction; - int visionSetBlendInTimeMs; - int visionSetBlendOutTimeMs; -}; - -struct CommonSwaySettings -{ - float maxAngle; - float lerpSpeed; - float pitchScale; - float yawScale; - float horizScale; - float vertScale; - float gunAngleScale; -}; - -struct HipSwaySettings -{ - CommonSwaySettings common; - float maxAngleSteadyAim; -}; - -struct AdsSwaySettings -{ - CommonSwaySettings common; - float swayTransitionLerpSpeed; - float adsSwayScale[3]; -}; - -struct AdvancedHipSwaySettings -{ - bool enabled; - float torsoGoalSmoothSpeed; - int torsoGoalViewSmoothDurationMs; - vec2_t torsoGoalDeadzoneAdjustSpeed; - RumbleGraph* torsoGoalViewSpeedToMaxDeadzone_graph; - vec2_t torsoGoalViewSpeedToMaxDeadzone_viewspeed; - vec2_t torsoGoalViewSpeedToMaxDeadzone_maxDeadzone; - vec2_t torsoMass; - vec2_t torsoSpring; - vec2_t torsoDamper; - int gunGoalViewSmoothDurationMs; - RumbleGraph* gunGoalViewSpeedToOffset_graph; - vec2_t gunGoalViewSpeedToOffset_viewspeed; - vec2_t gunGoalViewSpeedToOffset_offset; - vec2_t gunMass; - vec2_t gunSpring; - vec2_t gunDamper; - vec3_t gunPivotPoint; - float gunYawToRollScale; - int fireDurationMs; - int fireStartBlendDurationMs; - int fireFinishBlendDurationMs; - float fireTorsoGoalSmoothSpeed; - float fireTorsoDeadzoneScale; - float fireTorsoToGunDirScale; -}; - -struct __declspec(align(4)) SwaySettings -{ - HipSwaySettings hip; - AdsSwaySettings ads; - AdvancedHipSwaySettings adv; - float shellShockScale; - bool overrideHip; - bool overrideAds; -}; - -struct WeaponOffsetCurveDescription -{ - float blendTime; - float decayTime; - float shotDecayFireTimeFrac; - float holdTime; - float adsFractionBegin; - float adsFractionEnd; - int interpType; - int interpTypeOut; -}; - -struct WeaponOffsetPatternDescription -{ - bool active; - scr_string_t patternKey; - int curveType; - int patternType; - int transformType; - float frequency; - float blendTime; - vec3_t magnitude; - float hipScale; - float rotationOffset; - float bulletDirScale; - float fullAutoScale; - int fullAutoBullets; - float fullAutoDecay; - int referenceIndex; - int kickOrSnapDecayIndex; -}; - -struct __declspec(align(4)) GestureWeaponSettings -{ - unsigned __int16 blendToStates; - bool hideReticle; - float fireDelay; - float sprintDelay; - bool useLeftIdleAkimbo; - bool splitAnimsAkimbo; - bool blendToDemeanorLoop; - bool blendOutRaise; - bool blendOutFingerPose; - bool blendOutAdditiveADS; -}; - -struct __declspec(align(2)) GestureDirectionalSettings -{ - float maxAngle; - float lerpAtMaxAngle; - float widthCushionAngle; - float lerpAtMinCushionAngle; - float lerpAtMaxCushionAngle; - float limitLeft; - float limitRight; - float limitUp; - float limitDown; - bool useTargetOffset; - float targetOffsetX; - float targetOffsetY; - float targetOffsetZ; - float targetOffsetYaw; - float targetOffsetPitch; - float targetOffsetRoll; - bool ignoreViewPitchForTargetOffset; - bool ignoreViewYawForTargetOffset; - bool ignoreViewRollForTargetOffset; -}; - -struct __declspec(align(4)) FootstepTime -{ - float time; - bool isLeft; -}; - -struct __declspec(align(4)) MovementTime -{ - float time; - bool isLeadIn; -}; - -struct FootstepAnim -{ - int leftCount; - FootstepTime step[32]; - MovementTime movement[32]; -}; - -struct GestureLookAroundSettings -{ - float yawLerpIn; - float yawLerpOut; - unsigned __int16 walkTime; - FootstepAnim walkFootStepAnim; -}; - -struct GestureIKTargetSettings -{ - scr_string_t targetEntityBoneName; -}; - -struct __declspec(align(8)) Gesture -{ - const char* name; - int type; - int priority; - bool looping; - uintptr_t anims; - GestureWeaponSettings weaponSettings; - GestureDirectionalSettings directionalSettings; - GestureLookAroundSettings lookAroundSettings; - GestureIKTargetSettings ikTargetSettings; -}; - -struct LaserSettings -{ - bool forceLaserOn; - bool localPlayerADSLaserEnabled; - bool localPlayerHipLaserEnabled; - bool localPlayerNVGADSLaserEnabled; - bool localPlayerNVGHipLaserEnabled; - bool remotePlayerADSLaserEnabled; - bool remotePlayerHipLaserEnabled; - bool remotePlayerNVGADSLaserEnabled; - bool remotePlayerNVGHipLaserEnabled; - bool laserViewCenterInAds; -}; - -struct __declspec(align(4)) GrenadeRotationParams -{ - float initialPitch; - float initialYaw; - float initialRoll; - int rotationPitchDir; - int rotationPitchMin; - int rotationPitchMax; - int rotationYawDir; - int rotationYawMin; - int rotationYawMax; - int rotationRollDir; - int rotationRollMin; - int rotationRollMax; - bool rotate; -}; - -struct AnimOverride -{ - unsigned int numBindings; - uintptr_t bindings; - uintptr_t overrides; - uintptr_t overridesAlt; -}; - -struct CarryAnimOverride -{ - int carryObjectType; - WeaponAnimPackage* animPackage; - WeaponAnimPackage* animPackageAlt; -}; - -struct SFXOverride -{ - unsigned int numBindings; - uintptr_t bindings; - uintptr_t overrides; - uintptr_t overridesAlt; -}; - -struct VFXOverride -{ - unsigned int numBindings; - uintptr_t bindings; - uintptr_t overrides; - uintptr_t overridesAlt; -}; - -struct WeaponOffsetPatternScaleInfo -{ - int numPatternScales; - uintptr_t patternScales; -}; - -struct AdvancedIdleSettings -{ - bool useAdvancedIdleSettings; - bool useRandomPointsAlgorithm; - float breathGaspScaleOverride; - float idleSwaySetting1_HipBulletDirScale; - float idleSwaySetting1_HipIdleSpeed; - float idleSwaySetting1_HipWeaponMagnitudeX; - float idleSwaySetting1_HipWeaponMagnitudeY; - float idleSwaySetting1_HipWeaponMagnitudeZ; - float idleSwaySetting1_HipWeaponMagnitudeF; - float idleSwaySetting1_HipWeaponRotationOffset; - float idleSwaySetting1_HipViewMagnitudeX; - float idleSwaySetting1_HipViewMagnitudeY; - float idleSwaySetting1_AdsBulletDirScale; - float idleSwaySetting1_AdsIdleSpeed; - float idleSwaySetting1_AdsWeaponMagnitudeX; - float idleSwaySetting1_AdsWeaponMagnitudeY; - float idleSwaySetting1_AdsWeaponMagnitudeZ; - float idleSwaySetting1_AdsWeaponMagnitudeF; - float idleSwaySetting1_AdsWeaponRotationOffset; - float idleSwaySetting1_AdsViewMagnitudeX; - float idleSwaySetting1_AdsViewMagnitudeY; - float idleSwaySetting2_HipBulletDirScale; - float idleSwaySetting2_HipIdleSpeed; - float idleSwaySetting2_HipWeaponMagnitudeX; - float idleSwaySetting2_HipWeaponMagnitudeY; - float idleSwaySetting2_HipWeaponMagnitudeZ; - float idleSwaySetting2_HipWeaponMagnitudeF; - float idleSwaySetting2_HipWeaponRotationOffset; - float idleSwaySetting2_HipViewMagnitudeX; - float idleSwaySetting2_HipViewMagnitudeY; - float idleSwaySetting2_AdsBulletDirScale; - float idleSwaySetting2_AdsIdleSpeed; - float idleSwaySetting2_AdsWeaponMagnitudeX; - float idleSwaySetting2_AdsWeaponMagnitudeY; - float idleSwaySetting2_AdsWeaponMagnitudeZ; - float idleSwaySetting2_AdsWeaponMagnitudeF; - float idleSwaySetting2_AdsWeaponRotationOffset; - float idleSwaySetting2_AdsViewMagnitudeX; - float idleSwaySetting2_AdsViewMagnitudeY; -}; - -struct BallisticInfoCalculated -{ - float* distances; - float zeroingAngle; - int numDistanceEntries; -}; - -struct BallisticInfo -{ - float muzzleVelocity; - float ballisticCoefficient; - float diameter; - float mass; - float gravityFactor; - float zeroingDistance; - BallisticInfoCalculated* calculated; - bool enableBallisticTrajectory; - int lifeTimeMs; -}; - -struct FxCombinedDef -{ - const void* /*ParticleSystemDef*/ particleSystemDef; -}; - -struct TracerDef -{ - const char* name; - FxCombinedDef effect; - FxCombinedDef viewmodelEffect; - unsigned int drawInterval; - float speed; - bool drawLegacyTracer; - bool fadeOverTime; - float fadeTime; - Material* material; - float beamLength; - float beamWidth; - float screwRadius; - float screwDist; - vec4_t colors[5]; -}; - -struct LaserDef -{ - const char* name; - Material* laserMaterial; - Material* laserLightMaterial; - bool ownerOnly; - bool nightvisionOnly; - float range; - float radius; - float endOffsetViewmodel; - float endOffsetOther; - float flarePct; - FxCombinedDef beamEffect; - FxCombinedDef laserEndEffect; - bool clientCollision; - vec4_t color; - vec4_t hdrColorScale; - bool laserLight; - bool laserLightNvgOnly; - float laserLightRadius; - float laserLightBeginOffset; - float laserLightEndOffset; - float laserLightBodyTweak; - vec4_t laserLightColor; - vec4_t laserLightHdrColorScale; - float range_alt; - float radius_alt; - float laserLightRadius_alt; - float flarePct_alt; -}; - - -struct SurfaceFxTable -{ - const char* name; - void* /*SurfaceFxEntry*/ table; - int numTableEntry; - unsigned __int8* mapPoolBuffer; - int mapPoolBufferSize; -}; - -struct RawFile -{ - const char* name; - unsigned int compressedLen; - unsigned int len; - const char* buffer; -}; - -struct ScriptFile -{ - const char* name; - int compressedLen; - int len; - int bytecodeLen; - const char* buffer; - unsigned __int8* bytecode; -}; - -struct ScriptDebugData -{ - const char* name; - unsigned int nameCRC; - unsigned int profileStringCount; - void* /*ScriptDebugDataProfileString*/ profileStrings; -}; - -struct StringTable -{ - const char* name; - int columnCount; - int rowCount; - int uniqueCellCount; - unsigned __int16* cellIndices; - int* hashes; - const char** strings; -}; - -struct LeaderboardDef -{ - const char* name; - int id; - int sourceLbId; - int sourceLbWidth; - int columnCount; - int xpColId; - int prestigeColId; - void* /*LbColumnDef*/ columns; - int /*LbUpdateType*/ updateType; - int trackTypes; - int rankColIdX; - int rankColIdY; -}; - -struct __declspec(align(8)) VirtualLeaderboardDef -{ - const char* name; - const char* sourceName; - int id; - int sourceId; - void* /*LbVrColumnDef*/ columns; - int columnCount; - int rankColIdX; - int rankColIdY; -}; - -struct DDLFile -{ - char* name; - struct DDLDef* ddlDef; -}; - -struct SndAliasLookup -{ - const char* name; -}; - -struct __declspec(align(8)) VehiclePhysicsSoundGroup -{ - SndAliasLookup alias; - float threshold; - float vmin; - float vmax; - float pmin; - float pmax; -}; - -struct __declspec(align(8)) VehiclePhysicsVfxGroup -{ - void* /*FootstepVFX*/ surfaceEffects; - float threshold; - float range0; - float range1; -}; - - -struct VehiclePhysicsDef -{ - int physicsEnabled; - int /*VehiclePhysicsNetcodeType*/ physics_netcodeType; - char /*VehiclePhysicsGameProfile*/ physics_gameProfile; - int /*VehiclePhysicsAnimProfile*/ physics_animProfile; - int physics_numWheels; - bool physics_axleRigidBodies; - float physics_axleBodyPadding; - int physics_axleBodySides; - scr_string_t physics_wheelBones[12]; - float physics_wheelRadius; - float physics_suspStiffness; - float physics_suspDamping; - float physics_suspNoiseAmp; - float physics_frontalSuspension; - float physics_ackermannRatio; - vec3_t physics_hardPointOffset; - vec3_t physics_comOffset; - vec4_t physics_massFactorContact; - vec4_t physics_inertiaDiagonal; - float physics_extraGravityFactor; - float physics_extraGravityFactorAir; - float physics_camFovDelta; - float physics_camPitchBase; - float physics_camPitchDynamic; - float physics_camRangeAdd; - float physics_steeringFactor; - float physics_steeringForce; - float physics_steeringMaxYawSpeed; - float physics_steeringOffsetPoint; - float physics_steeringOffsetPointUp; - float physics_steeringReturnSpeed; - float physics_steeringChangeDirSpeed; - float physics_steeringHandbrake; - float physics_steeringSpeed; - float physics_steeringSpeedIncrease; - float physics_engineOffsetPoint; - float physics_engineReductionOnHB; - float physics_rollingFriction; - float physics_lateralFriction; - float physics_frictionBase; - float physics_frictionRecoverSpeedTgt; - float physics_frictionFwRedirect; - float physics_frictionLost; - float physics_frictionHandbrake; - float physics_frictionSpeedToBlock; - float physics_decel; - float physics_minSpeed; - bool physics_stabilizeRoll; - bool physics_stabilizePitch; - bool physics_contentsAsMissile; - bool physics_pitchInversion; - unsigned int physics_controlMode; - float physics_timeAfterColl; - int physics_cycleCamButton; - int physics_boostButton; - float physics_boostSpeed; - float physics_rcpBoostAccel; - float physics_rcpBoostDecel; - bool physics_holdToBoost; - SndAliasLookup physics_rcpBoostSound; - vec3_t physics_rcpBoostShakeCam; - bool physics_rcpUseChangeDirLogic; - bool physics_rcpUseChangeDirLogicPitch; - bool physics_rcpUseRollForYawSpeed; - float physics_rcpOvershootProtection; - float physics_rcpPitchTurnSpeed; - float physics_rcpPitchChangeDirFactor; - float physics_rcpPitchLerpSpeed; - float physics_rcpPitchLerpSpeedChangeDir; - float physics_rcpPitchLerpSpeedReturning; - float physics_rcpPitchMaxAngle; - float physics_rcpYawTurnSpeed; - float physics_rcpYawChangeDirFactor; - float physics_rcpYawLerpSpeed; - float physics_rcpYawLerpSpeedChangeDir; - float physics_rcpYawLerpSpeedReturning; - float physics_rcpRollTurnSpeed; - float physics_rcpRollLerpSpeedSteering; - float physics_rcpRollLerpSpeedChangeDir; - float physics_rcpRollLerpSpeedReturning; - float physics_rcpRollMaxAngle; - float physics_rcpAccelGoingDown; - float physics_rcpDecelGoingUp; - float physics_rcpTraceAhead; - bool physics_rcpCam1stAttachToTagPlayer; - vec2_t physics_rcpCam1stNoiseScale; - float physics_rcpCam1stRollSpeed; - float physics_rcpCam1stRollPercentage; - float physics_comAdjustThreshold; - float physics_comAdjustVertDisp; - float physics_playersWeightFactor; - float physics_timeToAcceptInputOnStart; - float physics_viewDirectionHelp; - float physics_stabilizePitchSpeed; - float physics_stabilizeRollSpeed; - int /*VehicleWheelSpinBoneType*/ spinWheelBones; - float spinWheelAngleOffset; - int treads_enabled; - int treads_boneCount; - scr_string_t treads_firstBones[2]; - float frictionBraking; - float suspensionTravel; - float maxSteeringAngle; - float steeringLerp; - float minSteeringScale; - float minSteeringSpeed; - int disableWheelsTurning; - int disableWheelsSpinning; - float minimumWheelCastFraction; - float handbrakeThreshold; - float minimumJoltForNotify; - float pathConstraintStrengthFwd; - float pathConstraintStrengthSide; - float pathConstraintDampFwd; - float pathConstraintDampSide; - float crashPointOffsetFwd; - float crashPointOffsetUp; - float crashImpulseSide; - float crashImpulseUp; - float wreckedMassScale; - VehiclePhysicsSoundGroup sndImpactHard; - float sndImpactExp; - VehiclePhysicsSoundGroup sndImpactLight; - VehiclePhysicsSoundGroup sndDrivingFast; - VehiclePhysicsSoundGroup sndDrivingSlow; - VehiclePhysicsSoundGroup sndSuspension; - VehiclePhysicsSoundGroup sndBrakingHard; - VehiclePhysicsSoundGroup sndBrakingLight; - VehiclePhysicsSoundGroup sndDrifting; - VehiclePhysicsSoundGroup sndSkidding; - VehiclePhysicsSoundGroup sndDlc1; - VehiclePhysicsSoundGroup sndDlc2; - VehiclePhysicsSoundGroup sndDlc3; - VehiclePhysicsSoundGroup sndDlc4; - VehiclePhysicsVfxGroup vfxImpactHard; - VehiclePhysicsVfxGroup vfxImpactLight; - VehiclePhysicsVfxGroup vfxDrivingFast; - VehiclePhysicsVfxGroup vfxDrivingSlow; - VehiclePhysicsVfxGroup vfxBrakingHard; - VehiclePhysicsVfxGroup vfxBrakingLight; - VehiclePhysicsVfxGroup vfxDrifting; - VehiclePhysicsVfxGroup vfxSkidding; - VehiclePhysicsVfxGroup vfxDrivingFlatFast; - VehiclePhysicsVfxGroup vfxDrivingFlatSlow; - VehiclePhysicsVfxGroup vfxDlc3; - VehiclePhysicsVfxGroup vfxDlc4; -}; - -struct SpaceshipAnimParts -{ - void* /*XAnimParts*/ anim[2]; -}; - -struct VehiclePhysicsRevModifier -{ - float skidSndContrib; - float noiseAmpl; - float sinewaveFreq; - float sinewaveAmpl; - float rpmMax; - float rpmScale; - float rpmSpeedEmaSamples; - float inclinedThreshold; - int gearCount; - float inclContrib; - float maxSpinSpeedRPMFw; - float maxSpinSpeedRPMBw; -}; - -struct VehicleDef -{ - const char* name; - char type; - const char* useHintString; - int health; - int inputBindingSet; - int hitClientScriptables; - int hitRemoteControllers; - int accurateShapeOverlap; - int numDoors; - float maxDoorAngle; - scr_string_t doorBones[4]; - CameraDef* cameraDef; - CameraDef* killCamDef; - float texScrollScale; - float topSpeed; - float accel; - float rotRate; - float rotAccel; - float maxBodyPitch; - float maxBodyRoll; - float rangeForBoneControllers; - float fakeBodyAccelPitch; - float fakeBodyAccelRoll; - float fakeBodyVelPitch; - float fakeBodyVelRoll; - float fakeBodySideVelPitch; - float fakeBodyPitchStrength; - float fakeBodyRollStrength; - float fakeBodyPitchDampening; - float fakeBodyRollDampening; - float fakeBodyBoatRockingAmplitude; - float fakeBodyBoatRockingPeriod; - float fakeBodyBoatRockingRotationPeriod; - float fakeBodyBoatRockingFadeoutSpeed; - float boatBouncingMinForce; - float boatBouncingMaxForce; - float boatBouncingRate; - float boatBouncingFadeinSpeed; - float boatBouncingFadeoutSteeringAngle; - float collisionDamage; - float collisionSpeed; - bool collisionDamageIgnoresImpactAngle; - vec3_t killcamOffset; - int playerProtected; - int bulletDamage; - int armorPiercingDamage; - int grenadeDamage; - int projectileDamage; - int projectileSplashDamage; - int heavyExplosiveDamage; - VehiclePhysicsDef vehiclePhysicsDef; - int vehHelicopterLockAltitude; - int vehHelicopterOffsetFromMesh; - float vehHelicopterAltitudeOffset; - float vehHelicopterPitchOffset; - float vehHelicopterBoundsRadius; - float vehHelicopterMaxSpeed; - float vehHelicopterMaxSpeedVertical; - float vehHelicopterMaxAccel; - float vehHelicopterMaxAccelVertical; - float vehHelicopterDecelerationFwd; - float vehHelicopterDecelerationSide; - float vehHelicopterDecelerationUp; - float vehHelicopterMaxYawRate; - float vehHelicopterMaxYawAccel; - float vehHelicopterTiltFromVelocity; - float vehHelicopterTiltFromControllerAxes; - float vehHelicopterTiltFromAcceleration; - float vehHelicopterTiltFromDeceleration; - float vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt; - float vehHelicopterTiltFromFwdAndYaw; - float vehHelicopterTiltMomentum; - float vehHelicopterTiltSpeed; - float vehHelicopterMaxPitch; - float vehHelicopterMaxRoll; - float vehHelicopterHoverSpeedThreshold; - float vehHelicopterJitterJerkyness; - float vehHelicopterLookaheadTime; - int vehHelicopterSoftCollisions; - int vehHelicopterUseGroundFX; - FxCombinedDef vehHelicopterGroundFx; - FxCombinedDef vehHelicopterGroundWaterFx; - float vehHelicopterGroundFxDefaultRepeatRate; - float vehHelicopterGroundFxSlowestRepeatRate; - float vehHelicopterGroundFxFastestRepeatRate; - float vehHelicopterGroundFxMinGroundDist; - float vehHelicopterGroundFxMaxGroundDist; - float vehRotorMaxVelocity; - float vehRotorMaxAccel; - float vehRotorAccelTiltBlend; - float vehRotorMaxVehicleSpin; - float vehRotorMaxAngle; - float vehRotorSpinSpeed; - float vehRotorSpinVerticalSpeedThreshold; - float vehRotorMaxSpinAddition; - float ssWeaponSwitchDelaySeconds; - float ssWeaponRaiseDelaySeconds; - vec3_t ssFlyMaxSpeedMph; - vec3_t ssFlyMaxAccelerationMphps; - vec3_t ssFlyMaxCounterAccelerationMphps; - vec3_t ssFlyFrictionMphps; - vec3_t ssFlyJukeSpeedMph; - vec3_t ssHoverMaxSpeedMph; - vec3_t ssHoverMaxAccelerationMphps; - vec3_t ssHoverMaxCounterAccelerationMphps; - vec3_t ssHoverFrictionMphps; - vec3_t ssHoverJukeSpeedMph; - float ssFlyJukeRampTime; - float ssHoverJukeRampTime; - float ssBrakingFrictionMphps; - float ssFlyRedirectVelocityScale; - float ssFlySlowRedirectVelocityScale; - float ssHoverRedirectVelocityScale; - float ssFlyMinSpeedRatio; - bool ssProjectVelocityDesiresToXY; - bool ssEnforceMinGroundClearance; - float ssMinGroundClearanceHeight; - float ssMinGroundClearanceLiftForce; - bool ssTerrainModeMovement; - float ssTerrainModeGravity; - float ssTerrainModeFlyTime; - vec2_t ssAimOffsetClampDeg; - vec2_t ssPitchUpSoftLimitDeg; - vec2_t ssPitchDownSoftLimitDeg; - float ssClutchPitchSpeedScale; - vec2_t ssFlyAimSpeedDps; - vec2_t ssFlySlowAimSpeedDps; - vec2_t ssHoverAimSpeedDps; - vec2_t ssFlyAimDriftScale; - vec2_t ssFlySlowAimDriftScale; - vec2_t ssHoverAimDriftScale; - float ssMinSpringOscillation; - float ssMaxSpringOscillation; - float ssMinSpringStrength; - float ssMaxSpringStrength; - float ssMinSpringAngSpeed; - float ssMaxSpringAngSpeed; - float ssSpringControllerContribution; - float ssTiltSpringOscillation; - float ssTiltSpringStrength; - float ssTiltSpringAngleContribution; - int ssADSToLockOn; - float ssLockOnMinAngle; - float ssLockOnMaxAngle; - float ssPilotAssistNoLockAimScale; - float ssPilotAssistNoLockMinAngle; - float ssPilotAssistNoLockMaxAngle; - float ssPilotAssistAimScale; - float ssPilotAssistMinAngle; - float ssPilotAssistMaxAngle; - vec2_t ssAutoLevelStrengthHover; - vec2_t ssAutoLevelStrengthFly; - bool ssIsRollRightStick; - float ssRollMaxSpeedDps; - float ssBoostSpeedScale; - float ssBoostThrustScale; - bool ssEnableBoostToFly; - float ssBoostTime; - float ssBoostRegenTime; - float ssBoostRegenStallTime; - float ssBoostMinThresholdRatio; - float ssCollisionRadiusI; - float ssCylinderHeightI; - bool ssUseCylinder; - bool ssUsePlayerClip; - float ssCollisionOffsetI; - float ssCollisionHardThresholdMph; - float ssFOVFlyOffsetDeg; - float ssFOVFlyBoostOffsetDeg; - float ssFOVHoverOffsetDeg; - float ssZoomBlendSpeedDps; - float ssZoomMaxAngle; - float ssZoomMinDistI; - float ssZoomIdealDistI; - float ssZoomMaxDistI; - bool ssShowPilotViewmodel; - float ssCameraAnimScale; - vec2_t ssFlyTiltShipAngles; - float ssFlyTiltCameraScale; - vec2_t ssHoverTiltShipAngles; - float ssHoverTiltCameraScale; - float ssMotionIdleRateMinSpeed; - float ssMotionIdleRateMaxSpeed; - float ssMotionIdleMinRate; - float ssMotionIdleMaxRate; - scr_string_t ssAnimTree; - SpaceshipAnimParts ssAnimParts[33]; - FxCombinedDef ssThrustFxLoop; - FxCombinedDef ssJukeFx; - RumbleInfo* ssIdleRumble; - RumbleInfo* ssSmallRumble; - RumbleInfo* ssMedRumble; - RumbleInfo* ssLargeRumble; - SndAliasLookup rattleLoop; - float rattleLoopMinVolume; - float rattleLoopMaxVolume; - SndAliasLookup airLoop; - float airLoopMinVolume; - float airLoopMaxVolume; - SndAliasLookup engineLoop; - float engineLoopMinVolume; - float engineLoopMaxVolume; - float engineLoopMinPitch; - float engineLoopMaxPitch; - SndAliasLookup hoverLoop; - float hoverLoopMinVolume; - float hoverLoopMaxVolume; - float hoverLoopMinPitch; - float hoverLoopMaxPitch; - SndAliasLookup boostLoop; - float boostLoopMaxVolume; - float boostLoopMaxPitch; - SndAliasLookup ssThrustLoop; - float ssThrustLoopMaxVolume; - float ssThrustLoopMaxPitch; - SndAliasLookup boostStart; - SndAliasLookup boostStop; - SndAliasLookup boostDepleted; - SndAliasLookup boostUnavailable; - SndAliasLookup jukeLeft; - SndAliasLookup jukeRight; - SndAliasLookup jukeUpDown; - SndAliasLookup jukeBack; - SndAliasLookup jukeFront; - SndAliasLookup flightOn; - SndAliasLookup flightOff; - float flightOnTimer; - float flightOffTimer; - SndAliasLookup hardCollision; - SndAliasLookup softCollision; - int camLookEnabled; - int camRelativeControl; - int camRemoteDrive; - float camLerp; - float camHeight; - float camRadius; - float camPitchInfluence; - float camYawInfluence; - float camRollInfluence; - float camFovIncrease; - float camFovOffset; - float camFovSpeed; - float camReturnSpeed; - float camReturnLerp; - float camVehicleAnglePitchRate; - float camVehicleAngleYawRate; - float camVehicleAngleRollRate; - int vehCam_UseGDT; - float vehCam_anglesPitch; - float vehCam_anglesYaw; - float vehCam_anglesRoll; - float vehCam_offsetX; - float vehCam_offsetY; - float vehCam_offsetZ; - float vehCam_radius; - float vehCam_speedInfluence; - float vehCam_pitchTurnRate; - float vehCam_pitchClamp; - float vehCam_yawTurnRate; - float vehCam_yawClamp; - int /*VehCamZOffsetMode*/ vehCam_zOffsetMode; - float vehCam_anglesPitch3P; - float vehCam_anglesYaw3P; - float vehCam_anglesRoll3P; - float vehCam_offsetX3P; - float vehCam_offsetY3P; - float vehCam_offsetZ3P; - float vehCam_radius3P; - float vehCam_speedInfluence3P; - float vehCam_pitchTurnRate3P; - float vehCam_pitchClamp3P; - float vehCam_yawTurnRate3P; - float vehCam_yawClamp3P; - int /*VehCamZOffsetMode*/ vehCam_zOffsetMode3P; - const char* turretWeaponName; - void* /*WeaponCompleteDef*/ turretWeapon; - float turretHorizSpanLeft; - float turretHorizSpanRight; - float turretVertSpanUp; - float turretVertSpanDown; - float turretHorizResistLeft; - float turretHorizResistRight; - float turretVertResistUp; - float turretVertResistDown; - float turretRotRate; - int /*VehicleTurretFireType*/ turretFireType; - SndAliasLookup turretSpinSnd; - SndAliasLookup turretStopSnd; - int trophyEnabled; - float trophyRadius; - float trophyInactiveRadius; - int trophyAmmoCount; - float trophyReloadTime; - scr_string_t trophyTags[4]; - FxCombinedDef trophyExplodeFx; - FxCombinedDef trophyFlashFx; - Material* compassFriendlyIcon; - Material* compassEnemyIcon; - Material* compassFriendlyAltIcon; - Material* compassEnemyAltIcon; - int compassIconWidth; - int compassIconHeight; - void* /*SndBankTransient*/ detailSoundBankNPC; - void* /*SndBankTransient*/ detailSoundBankPlayer; - SndAliasLookup idleLowSnd; - SndAliasLookup idleHighSnd; - SndAliasLookup engineLowSnd; - SndAliasLookup engineHighSnd; - SndAliasLookup fallbackIdleLowSnd; - SndAliasLookup fallbackIdleHighSnd; - SndAliasLookup fallbackEngineLowSnd; - SndAliasLookup fallbackEngineHighSnd; - float engineSndSpeed; - scr_string_t audioOriginTag; - SndAliasLookup mainRotorLowRpmSnd; - SndAliasLookup mainRotorOperatingRpmSnd; - SndAliasLookup mainRotorOperatingEffortSnd; - SndAliasLookup tailRotorLowRpmSnd; - SndAliasLookup tailRotorOperatingRpmSnd; - SndAliasLookup tailRotorOperatingEffortSndLeft; - SndAliasLookup tailRotorOperatingEffortSndRight; - SndAliasLookup physicsHeliStartup; - SndAliasLookup physicsHeliShutdown; - SndAliasLookup turbineLowRpmSnd; - SndAliasLookup turbineOperatingRpmSnd; - bool useRevAudioSettings; - SndAliasLookup revLowFidelityMod; - SndAliasLookup revHighFidelityMod; - float revPlayerPriority; - VehiclePhysicsRevModifier revModifier; - SndAliasLookup engineStartUpSnd; - int engineStartUpLength; - SndAliasLookup engineShutdownSnd; - SndAliasLookup engineIdleSnd; - SndAliasLookup engineSustainSnd; - SndAliasLookup engineRampUpSnd; - int engineRampUpLength; - SndAliasLookup engineRampDownSnd; - int engineRampDownLength; - SndAliasLookup suspensionSoftSnd; - float suspensionSoftCompression; - SndAliasLookup suspensionHardSnd; - float suspensionHardCompression; - SndAliasLookup collisionSnd; - float collisionBlendSpeed; - SndAliasLookup speedSnd; - float speedSndBlendSpeed; - const char* surfaceSndName; - float surfaceSndBlendSpeed; - float slideVolume; - float slideBlendSpeed; - float inAirPitch; - const char* soundTriggerOverrideZone; - bool soundTriggerOverrideReverb; - bool soundTriggerOverrideMix; - bool soundTriggerOverrideFilter; - bool soundTriggerOverrideOcclusion; - bool soundTriggerOverrideAmbient; - bool soundTriggerOverrideAmbientEvents; - bool soundTriggerOverrideADSR; - int visionBlendTime; - const char* globalVisionSettings; - const char* mapVisionSettings; - const char* luiCrosshairWidget; - float dlcFloat[8]; -}; - -struct MapTriggers -{ - unsigned int count; - void* /*TriggerModel*/ models; - unsigned int hullCount; - void* /*TriggerHull*/ hulls; - unsigned int slabCount; - void* /*TriggerSlab*/ slabs; - unsigned int windingCount; - void* /*TriggerWinding*/ windings; - unsigned int windingPointCount; - void* /*TriggerWindingPoint*/ windingPoints; -}; - - -struct AddonMapEnts -{ - const char* name; - char* entityString; - int numEntityChars; - MapTriggers trigger; - unsigned int numSubModels; - void* /*cmodel_t*/ cmodels; - void* /*GfxBrushModel*/ models; -}; - -struct NetConstStrings -{ - const char* name; - int /*NetConstStringType*/ stringType; - int /*NetConstStringSource*/ sourceType; - unsigned int flags; - unsigned int entryCount; - const char** stringList; -}; - -struct LuaFile -{ - const char* name; - int len; - unsigned __int8 strippingType; - const unsigned __int8* buffer; -}; - - -struct __declspec(align(8)) ScriptableDef -{ - const char* name; - ScriptableDef* nextScriptableDef; - int flags; - unsigned int numParts; - void* /*ScriptablePartDef*/ parts; - unsigned int maxNumDynEntsRequired; - unsigned int partCount; - unsigned int serverInstancedPartCount; - unsigned int serverControlledPartCount; - unsigned int maxNumDynEntPartsBase; - unsigned int maxNumDynEntPartsForSpawning; - unsigned __int16 eventStreamSizeRequiredServer; - unsigned __int16 eventStreamSizeRequiredClient; - unsigned int usablePartCount; - unsigned int ffMemCost; - scr_string_t animationTreeName; - void* /*XAnim_s*/ animationTreeDef[2]; - float viewRadius; - bool networkLODRangeOverride; - float networkLODRangeOverrideDistance; - unsigned int numXModels; - XModel** models; - char /*DynEntitySpatialActivationMode*/ spatialActivationMode; -}; - -struct EquipSoundSetMoveTypes -{ - void* /*EquipmentSoundSet*/ soundSets; -}; - -struct EquipmentSoundSet -{ - void* /*SndAliasList*/ soundPLR; - void* /*SndAliasList*/ soundNPC; -}; - -struct EquipSoundSetMeleeWorld -{ - EquipmentSoundSet soundSets[8][3][2][4]; -}; - -struct EquipmentSoundTable -{ - const char* szName; - unsigned int numClothTypes; - unsigned int numWeaponRattleTypes; - unsigned int numMoveTypes; - unsigned int numStanceTypes; - void* /*EquipmentClothData*/ clothTypes; - void* /*EquipmentWeaponRattleData*/ weaponRattleTypes; - void* /*EquipmentChanceRattleTypes*/ chancesPLR; - void* /*EquipmentChanceRattleTypes*/ chancesNPC; - void* /*EquipSoundSetFootsteps*/ mvmtClothFootstepSoundSets; - void* /*EquipSoundSetFootsteps*/ mvmtClothFootstepCeilingSoundSets; - void* /*EquipSoundSetMoveLeadTypes*/ mvmtClothFoleySoundSets; - void* /*EquipSoundSetMoveTypes*/ mvmtRattleSoundSets; - EquipSoundSetMoveTypes mvmtAccentSoundSets; - void* /*EquipSoundSetMantleTypes*/ mvmtMantleSoundSets; - void* /*EquipSoundSetStanceTypes*/ mvmtStanceSoundSets; - void* /*EquipSoundSetMeleeVM*/ meleeAttackVMSoundSets; - void* /*EquipSoundSetMeleeWM*/ meleeAttackWMSoundSets; - void* /*EquipSoundSetMeleeWM*/ meleeCharacterSoundSets; - EquipSoundSetMeleeWorld meleeWorldSoundSets; -}; - -struct ExtentBounds -{ - vec3_t mins; - vec3_t maxs; -}; - -struct VectorField -{ - const char* name; - void* /*VectorSubField*/ subFields; - ExtentBounds worldBounds; - vec3_t localOrigin; - unsigned int numSubFields; - unsigned int pad[2]; -}; - -struct FxParticleSimAnimationHeader -{ - float playbackRate; - float duration; - unsigned int frameCount; - float minX; - float minY; - float minZ; - float boundsXDelta; - float boundsYDelta; - float boundsZDelta; - float maxWidth; - float maxHeight; - unsigned int colorTableSize; - unsigned int particleDataCount; - unsigned int maxActiveParticles; - bool evalVisStatePerParticle; - bool sortParticlesAtRuntime; - bool hasOrientation3D; - bool hasIndex; -}; - -struct FxParticleSimAnimation -{ - const char* name; - Material* material; - FxParticleSimAnimationHeader header; - void* /*FxParticleSimAnimationParticleData*/ particleData; - void* /*FxParticleSimAnimationParticleDataOrientation3D*/ particleDataOrientation3D; - void* /*FxParticleSimAnimationParticleDataIndex*/ particleDataIndex; - void* /*FxParticleSimAnimationFrame*/ frames; - vec4_t* colorTable; -}; - -struct StreamingInfo { - char __padding[0x48]; -}; - -struct TTFDef -{ - const char* name; - int fileLen; - const char* file; - void* ftFace; -}; - -struct SuitDef -{ - const char* name; - float cam_minVelocityForFovIncrease; - float cam_maxVelocityForFovIncrease; - float cam_velocityToDecreaseFov; - float cam_fovIncreaseAtMaxVelocity; - float cam_oneOverFovEaseInTimeMs; - float cam_oneOverFovEaseOutTimeMs; - CameraDef* cam_helmetCam; - bool cam_drawHelmet; - vec3_t cam_camtoHelmetOffsetOrigin; - vec3_t cam_camtoHelmetOffsetAngles; - bool enableIKOverride; - float player_globalAccelScale; - float player_crouchSpeedScale; - float player_proneSpeedScale; - float player_lastStandCrawlSpeedScale; - float player_sprintSpeedScale; - bool player_sprintUnlimited; - float player_viewBobScale; - bool jump_slowdownEnable; - float jump_height; - float sprintLeap_height; - float sprintLeap_forwardVelocityScale; - int sprintLeap_minSprintTimeMs; - float doubleJump_accel; - float doubleJump_speed; - float doubleJump_speedNoBoost; - float doubleJump_frictionMin; - float doubleJump_frictionMax; - float doubleJump_initialUpBoostAccel; - float doubleJump_standardUpBoostAccel; - float doubleJump_energyNeededForInitialUpBoost; - float doubleJump_energyNeededForStandardUpBoost; - float doubleJump_maxUpwardsVelocity; - bool doubleJump_enableMinZVelocity; - float doubleJump_minZVelocity; - float doubleJump_energyInitialCost; - float doubleJump_boostUpEnergyUseRate; - float doubleJump_energyUsePerButtonPress; - bool doubleJump_hoverOnly; - float doubleJump_maxViewPitchDip; - float doubleJump_maxViewBackwardsPitchDip; - float doubleJump_maxViewRoll; - float doubleJump_oneOverEaseInTime; - float doubleJump_oneOverEaseOutTimeMs; - bool doubleJump_alwaysDipView; - SndAliasLookup doubleJump_sound; - SndAliasLookup doubleJump_soundPlayer; - SndAliasLookup doubleJump_releaseSound; - SndAliasLookup doubleJump_releaseSoundPlayer; - float slide_strafe_speed_scale; - int slide_sprint_penalty_ms; - bool slide_allow_firing; - bool slide_allow_ads; - bool slide_allow_weapon_switch; - float slide_jump_speed_scale; - float slide_energy_cost_ratio; - int slide_max_time_ms; - int slide_max_time_reduced_ms; - int slide_max_time_base_ms; - int slide_inTimeMs; - float slide_inMaxSpeedScale; - float slide_inAcceleration; - float slide_frictionScaleNormal; - float slide_frictionScaleDownhill; - float slide_frictionScaleUphill; - float slide_frictionScaleBlocked; - int slide_gestureOutTimeForJumpMs; - int slide_sprintDelayMs; - bool slide_disableProneTransition; - int slide_proneDelayMs; - int slide_proneButtonCheckTimeMs; - int slide_outTimeMs; - float slide_outFrictionScaleStart; - float slide_outFrictionScaleFinish; - float slide_outSpeedScaleStart; - float slide_outSpeedScaleFinish; - int slide_inAirTimeMs; - float slide_inAirFrictionScaleStart; - float slide_inAirFrictionScaleFinish; - int slide_viewBlendInTimeMs; - int slide_viewBlendOutTimeMs; - float wallRun_minZVel; - float wallRun_minTriggerSpeed; - float wallRun_minMaintainSpeed; - int wallRun_delayPeriodMs; - float wallRun_minJumpHeight; - int wallRun_maxTimeMs; - int wallRun_fallStageTimeMs; - float wallRun_maxHeight; - float wallRun_jumpHeight; - float wallRun_jumpVelocity; - float wallRun_frictionScale; - float wallRun_speedScale; - float wallRun_speedScaleADS; - float wallRun_energyInitialCost; - float wallRun_energyChangePerSecond; - float ladder_anchorOffset; - float ladder_anchorOffsetWM; - float ladder_handDistance; - int /*SuitAnimType*/ suitAnimType; - bool isMovementCameraIndependent; - void* /*SuitAnimPackage*/ animPackage; - void* /*SuitAnimPackage*/ animPackageL; - void* /*SuitAnimPackage*/ animPackageR; - void* /*SuitAnimPackage*/ animPackageRelaxed; - void* /*SuitAnimPackage*/ animPackageSafe; - void* /*ASM*/ asmAsset; - void* /*Animset*/ animsetAsset; - unsigned __int8 facialAnimType; - int /*SuitBodyAnimType*/ bodyAnimType; - ScriptableDef* scriptableDef; - int viewheight_stand; - int viewheight_crouch; - int viewheight_prone; - int viewheight_laststand; - int viewheight_dead; - int viewheight_swim; - int viewheight_slide; - int viewheight_sprint; - int bounds_radius; - int bounds_height_stand; - int bounds_height_crouch; - int bounds_height_prone; - Bounds bounds_stand; - Bounds bounds_crouch; - Bounds bounds_prone; - int radialMotionBlur_interpTimeIn; - int radialMotionBlur_interpTimeOut; - float radialMotionBlur_sprintMinRadius; - float radialMotionBlur_sprintMaxRadius; - float radialMotionBlur_sprintMinStrength; - float radialMotionBlur_sprintMaxStrength; - float radialMotionBlur_slideMinRadius; - float radialMotionBlur_slideMaxRadius; - float radialMotionBlur_slideMinStrength; - float radialMotionBlur_slideMaxStrength; - float radialMotionBlur_doubleJumpMinRadius; - float radialMotionBlur_doubleJumpMaxRadius; - float radialMotionBlur_doubleJumpMinStrength; - float radialMotionBlur_doubleJumpMaxStrength; - float radialMotionBlur_wallRunMinRadius; - float radialMotionBlur_wallRunMaxRadius; - float radialMotionBlur_wallRunMinStrength; - float radialMotionBlur_wallRunMaxStrength; - float radialMotionBlur_groundPoundMinRadius; - float radialMotionBlur_groundPoundMaxRadius; - float radialMotionBlur_groundPoundMinStrength; - float radialMotionBlur_groundPoundMaxStrength; - float radialMotionBlur_rewindMinRadius; - float radialMotionBlur_rewindMaxRadius; - float radialMotionBlur_rewindMinStrength; - float radialMotionBlur_rewindMaxStrength; - float radialMotionBlur_dodgeMinRadius; - float radialMotionBlur_dodgeMaxRadius; - float radialMotionBlur_dodgeMinStrength; - float radialMotionBlur_dodgeMaxStrength; - float radialMotionBlur_skydiveMinRadius; - float radialMotionBlur_skydiveMaxRadius; - float radialMotionBlur_skydiveMinStrength; - float radialMotionBlur_skydiveMaxStrength; - RumbleInfo* groundPound_activationRumble; - SndAliasLookup groundPound_activationSound; - SndAliasLookup groundPound_activationSoundPlayer; - RumbleInfo* groundPound_landingRumble; - SndAliasLookup groundPound_landingSound; - SndAliasLookup groundPound_landingSoundPlayer; - RumbleInfo* landing_rumbleLowHeight; - RumbleInfo* landing_rumbleMediumHeight; - RumbleInfo* landing_rumbleHighHeight; - RumbleInfo* landing_rumbleExtremeHeight; - float landing_speedScale; - float footstep_shakeBroadcastRadiusInches; - int footstep_shakeDurationMs; - float footstep_shakeAmplitude; - RumbleInfo* footstep_rumble; - void* /*FootstepVFX*/ footstepvfx_slide; - void* /*FootstepVFX*/ footstepvfx_creep_left; - void* /*FootstepVFX*/ footstepvfx_creep_right; - void* /*FootstepVFX*/ footstepvfx_walk_left; - void* /*FootstepVFX*/ footstepvfx_walk_right; - void* /*FootstepVFX*/ footstepvfx_run_left; - void* /*FootstepVFX*/ footstepvfx_run_right; - void* /*FootstepVFX*/ footstepvfx_sprint_left; - void* /*FootstepVFX*/ footstepvfx_sprint_right; - float skydive_mass; - float skydive_gravitatationalAcceleration; - XModel* skydive_parachuteViewModel; - XModel* skydive_parachuteWorldModel; - float skydive_baseJumpMinimumHeight; - float skydive_baseJumpClearanceRadius; - float skydive_baseJumpAutoDeployHeight; - float skydive_baseJumpForceFreefallHeight; - float skydive_freefallSuperDiveCameraPitch; - float skydive_freefallSuperDiveStickInput; - float skydive_freefallSuperDiveFovAdjustDegrees; - int skydive_freefallSuperDiveFovAdjustInTime; - int skydive_freefallSuperDiveFovAdjustOutTime; - void* /*CinematicMotionDef*/ skydive_freefallCinematicMotion; - float skydive_freefallThrottleTrackSpeed; - float skydive_freefallAnimTrackSpeedThrottle; - float skydive_freefallAnimTrackSpeedStrafe; - float skydive_freefallAnimTrackSpeedYaw; - float skydive_freefallAnimTrackSpeedPitch; - float skydive_freefallAnimMinWeight; - float skydive_freefallAnimMaxWeight; - float skydive_freefallAnimMinPlayRate; - float skydive_freefallAnimMaxPlayRate; - float skydive_freefallAnimSpeedForMinWeight; - float skydive_freefallAnimSpeedForMaxWeight; - float skydive_freefallTopGroundSpeed; - float skydive_freefallMinPitch; - float skydive_freefallMaxPitch; - float skydive_freefallPitchSpeed; - float skydive_freefallYawSpeed; - float skydive_freefallCrossSectionalArea; - float skydive_freefallLookHorizForceMin; - float skydive_freefallLookHorizForceMax; - RumbleGraph* skydive_freefallLookHorizForceGraph; - float skydive_freefallStickHorizForceMin; - float skydive_freefallStickHorizForceMax; - RumbleGraph* skydive_freefallStickHorizForceGraph; - float skydive_freefallDragCoefHoriz; - float skydive_freefallLookHorizDragCoeff; - RumbleGraph* skydive_freefallLookHorizDragGraph; - float skydive_freefallStickHorizDragCoeff; - RumbleGraph* skydive_freefallStickHorizDragGraph; - float skydive_freefallDragCoefVert; - float skydive_freefallLookVertDragCoeff; - RumbleGraph* skydive_freefallLookVertDragGraph; - float skydive_freefallStickVertDragIncreasePerc; - RumbleGraph* skydive_freefallStickVertDragIncreaseGraph; - float skydive_freefallStickVertDragReductionPerc; - RumbleGraph* skydive_freefallStickVertDragReductionGraph; - float skydive_freefallStickSidewaysForce; - float skydive_freefallMaxBrakeForce; - float skydive_freefallMinTurnMultiplier; - float skydive_freefallMaxTurnMultiplier; - RumbleGraph* skydive_freefallTurnMultiplierGraph; - float skydive_freefallTurnMultiplierMinScale; - float skydive_freefallTurnMultiplierMaxScale; - RumbleGraph* skydive_freefallTurnMultiplierPitchGraph; - SndAliasLookup skydive_freefallAmbientSound; - float skydive_freefallAmbientSoundGroundSpeedWeight; - float skydive_freefallAmbientSoundMinVolume; - float skydive_freefallAmbientSoundMaxVolume; - float skydive_freefallAmbientSoundMinPitch; - float skydive_freefallAmbientSoundMaxPitch; - float skydive_freefallAmbientSoundMinGroundSpeed; - float skydive_freefallAmbientSoundMaxGroundSpeed; - float skydive_freefallAmbientSoundMinFallSpeed; - float skydive_freefallAmbientSoundMaxFallSpeed; - SndAliasLookup skydive_freefallHighSpeedSound; - float skydive_freefallHighSpeedSoundGroundSpeedWeight; - float skydive_freefallHighSpeedSoundMinVolume; - float skydive_freefallHighSpeedSoundMaxVolume; - float skydive_freefallHighSpeedSoundMinPitch; - float skydive_freefallHighSpeedSoundMaxPitch; - float skydive_freefallHighSpeedSoundMinGroundSpeed; - float skydive_freefallHighSpeedSoundMaxGroundSpeed; - float skydive_freefallHighSpeedSoundMinFallSpeed; - float skydive_freefallHighSpeedSoundMaxFallSpeed; - float skydive_deployHorizontalDrag; - float skydive_deployVerticalDrag; - void* /*CinematicMotionDef*/ skydive_canopyCinematicMotion; - float skydive_canopyThrottleTrackSpeed; - float skydive_canopyAnimTrackSpeedThrottle; - float skydive_canopyAnimTrackSpeedStrafe; - float skydive_canopyAnimTrackSpeedYaw; - float skydive_canopyAnimTrackSpeedPitch; - float skydive_canopyAnimMinWeight; - float skydive_canopyAnimMaxWeight; - float skydive_canopyAnimMinPlayRate; - float skydive_canopyAnimMaxPlayRate; - float skydive_canopyAnimSpeedForMinWeight; - float skydive_canopyAnimSpeedForMaxWeight; - float skydive_canopyTopGroundSpeed; - float skydive_canopyMinPitch; - float skydive_canopyMaxPitch; - float skydive_canopyPitchSpeed; - float skydive_canopyYawSpeed; - float skydive_canopyCrossSectionalArea; - float skydive_canopyLookHorizForceMin; - float skydive_canopyLookHorizForceMax; - RumbleGraph* skydive_canopyLookHorizForceGraph; - float skydive_canopyStickHorizForceMin; - float skydive_canopyStickHorizForceMax; - RumbleGraph* skydive_canopyStickHorizForceGraph; - float skydive_canopyDragCoefHoriz; - float skydive_canopyLookHorizDragCoeff; - RumbleGraph* skydive_canopyLookHorizDragGraph; - float skydive_canopyStickHorizDragCoeff; - RumbleGraph* skydive_canopyStickHorizDragGraph; - float skydive_canopyDragCoefVert; - float skydive_canopyLookVertDragCoeff; - RumbleGraph* skydive_canopyLookVertDragGraph; - float skydive_canopyStickVertDragIncreasePerc; - RumbleGraph* skydive_canopyStickVertDragIncreaseGraph; - float skydive_canopyStickVertDragReductionPerc; - RumbleGraph* skydive_canopyStickVertDragReductionGraph; - float skydive_canopyStickSidewaysForce; - float skydive_canopyMaxBrakeForce; - float skydive_canopyMinTurnMultiplier; - float skydive_canopyMaxTurnMultiplier; - RumbleGraph* skydive_canopyTurnMultiplierGraph; - float skydive_canopyTurnMultiplierMinScale; - float skydive_canopyTurnMultiplierMaxScale; - RumbleGraph* skydive_canopyTurnMultiplierPitchGraph; - SndAliasLookup skydive_canopyAmbientSound; - float skydive_canopyAmbientSoundGroundSpeedWeight; - float skydive_canopyAmbientSoundMinVolume; - float skydive_canopyAmbientSoundMaxVolume; - float skydive_canopyAmbientSoundMinPitch; - float skydive_canopyAmbientSoundMaxPitch; - float skydive_canopyAmbientSoundMinGroundSpeed; - float skydive_canopyAmbientSoundMaxGroundSpeed; - float skydive_canopyAmbientSoundMinFallSpeed; - float skydive_canopyAmbientSoundMaxFallSpeed; - SndAliasLookup skydive_canopyHighSpeedSound; - float skydive_canopyHighSpeedSoundGroundSpeedWeight; - float skydive_canopyHighSpeedSoundMinVolume; - float skydive_canopyHighSpeedSoundMaxVolume; - float skydive_canopyHighSpeedSoundMinPitch; - float skydive_canopyHighSpeedSoundMaxPitch; - float skydive_canopyHighSpeedSoundMinGroundSpeed; - float skydive_canopyHighSpeedSoundMaxGroundSpeed; - float skydive_canopyHighSpeedSoundMinFallSpeed; - float skydive_canopyHighSpeedSoundMaxFallSpeed; - float skydive_wmAnimFreefallPitchMin; - float skydive_wmAnimFreefallPitchMax; - float skydive_wmAnimFreefallPitchTrackSpeed; - float skydive_wmAnimFreefallRollTrackSpeed; - float skydive_wmAnimFreefallRollReturnSpeed; - RumbleGraph* skydive_wmAnimFreefallLeftStickXToRollGraph; - RumbleGraph* skydive_wmAnimFreefallRightStickXToRollGraph; - float skydive_camFreefallHeightOffset; - RumbleGraph* skydive_camFreefallPitchToDistanceGraph; - RumbleGraph* skydive_camFreefallPitchToForwardOffsetGraph; - float skydive_camParachuteHeightOffset; - RumbleGraph* skydive_camParachutePitchToDistanceGraph; - RumbleGraph* skydive_camParachutePitchToForwardOffsetGraph; - RumbleGraph* skydive_camParachutePitchToModelPitchForwardOffsetGraph; - RumbleGraph* skydive_camParachutePitchToModelRollSideOffsetGraph; - RumbleGraph* skydive_camParachutePitchToModelRollUpOffsetGraph; - float skydive_camParachuteBlendInTime; - SndAliasLookup nvg_blindSound; - float dlcFloat[8]; -}; - -struct SuitAnimPackage -{ - const char* name; - void* /*SuitAnimPerWeapClass*/ animOverrides; -}; - -struct CameraFirstPersonProfileDef -{ - bool applyOffset; - vec3_t offsetTranslation; - bool disableFOVWeaponOffset; - float cameraAnimationTransScale; - float cameraAnimationRotScale; - float handheldCameraTransScale; - float handheldCameraRotScale; - float handheldCameraImpulseTransScale; - float handheldCameraImpulseRotScale; -}; - -struct CameraOrbitProfileDef -{ - float lerpSpeed; - vec3_t pivotOffset; - float initialAzimuth; - float initialPolar; - float polarMin; - float polarMax; - float range; - float returnAzimuthSpeed; - float returnPolarSpeed; - float easeInFactor; - float returnTimeTo; - float turningSpeedPolar; - float turningSpeedAzimuth; - float traceCollRadius; - float mouseInputMultiplier; - float rollContrib; - float pitchContrib; - int buttonToggleReturn; - int buttonCyclePerspective; - int buttonRecenter; - bool initialReturn; - bool returnAzimuth; - bool returnPolar; - float alignToMovement; - bool interpolateFocus; - bool cameraReturnOnGas; - float cameraReturnOnSpeed; - float yawTurnAdjust; -}; - -struct CameraSentryDroneDef -{ - float range; - float thresHitToSpeedUp; - float speedUpFactor; - float lerpSpeedEye; - float lerpSpeedFocus; - float lerpSpeedUp; - float focusTraceLen; - float eyeHeight; - float horizontalOffset; - float upOffsetFactorIncl; -}; - -struct CameraKillCamVehicleDef -{ - float lookAtRadius; - float fov; - float distBack; - float distUp; - float distBackRadiusMod; - float distUpRadiusMod; - float fovRadiusMod; - float sideMag; - float traceCollRad; -}; - -struct CameraTransitionDef -{ - bool active; - float time; - float timewaitEyepos; - float timewaitAxis; - int /*CameraTransitionCurve*/ curveEyepos; - int /*CameraTransitionCurve*/ curveAxis; -}; - -struct CameraDef -{ - const char* name; - int /*CameraProfile*/ profile; - bool keepShakeCam; - bool serverFeedback; - bool behaveAsRemoteCont; - bool interpolateViewTransition; - bool overrideFOV; - float FOV; - int /*LensProfileMode*/ overrideLensProfile; - float lensFocalLength; - float lensFStop; - float lensScale; - float lensUVScale; - bool overrideRadialBlur; - float radialBlurRadius; - float radialBlurStrength; - bool overrideZPlanes; - float zPlaneVMNear; - float zPlaneSceneNear; - CameraFirstPersonProfileDef firstPerson; - CameraOrbitProfileDef orbit; - CameraSentryDroneDef sentryDrone; - CameraKillCamVehicleDef kcamVeh; - CameraTransitionDef transitionIn; - CameraTransitionDef transitionOut; - vec3_t fpveh_offsetLs; - float fpveh_offsetYaw; - float fpveh_offsetPitch; - float fpveh_rollContrib; - float fpveh_rollMax; - bool fpveh_freeLook; - bool fpveh_freeLookReturn; - bool dlcBool[1]; - bool fadeOutPlayerOnTransitionIn; -}; - -struct HudOutlineDef -{ - const char* name; - unsigned __int8 outlineType; - bool drawInStencil; - bool drawNonOccludedPixels; - bool drawOccludedPixels; - bool drawFill; - bool fadeOverTimeEnable; - bool fadeOverTimeLooping; - unsigned __int8 fadeOverTimeCurveType; - float fadeOverTimeMinAlpha; - float fadeOverTimeMaxAlphaTime; - float fadeOverTimeMinAlphaTime; - float fadeOverTimeInTime; - float fadeOverTimeOutTime; - bool distanceFadeEnable; - float distanceFadeMinAlpha; - float distanceFadeStartDistance; - float distanceFadeEndDistance; - unsigned int outlineColor; - int outlineWidth; - bool drawOnLocalPlayerCharacter; - bool drawOnVehicleOccupants; - bool drawOnLocalPlayerVehicleOccupants; - bool drawOnLocalPlayerVehicle; - bool dlcBool0; - bool dlcBool1; - bool dlcBool2; - bool dlcBool3; - bool dlcBool4; - bool dlcBool5; - float dlcFloat0; - float dlcFloat1; - float dlcFloat2; - float dlcFloat3; - float dlcFloat4; - float dlcFloat5; -}; - -struct SpaceshipTargetDef -{ - const char* name; - scr_string_t targetTag; - float annotationOffsetX; - float annotationOffsetY; - float annotationOffsetZ; - bool disableLeading; - float lock_minDistance; - float lock_maxDistance; - float lock_cutoffDistance; - float lock_minRate; - float lock_maxRate; - float lock_maxZoomFOV; - float lock_followDistance; - float lockCooldown_rate; - float aa_closeDistance; - float aa_farDistance; - float aa_closeMinAngle; - float aa_closeMaxAngle; - float aa_closeBlendMax; - float aa_farMinAngle; - float aa_farMaxAngle; - float aa_farBlendMax; - float aaLocked_closeDistance; - float aaLocked_farDistance; - float aaLocked_closeMinAngle; - float aaLocked_closeMaxAngle; - float aaLocked_closeBlendMax; - float aaLocked_farMinAngle; - float aaLocked_farMaxAngle; - float aaLocked_farBlendMax; - float pilotAssistScale; - float callout_maxDistance; - float callout_maxAngle; -}; - -struct __declspec(align(8)) RumbleInfo -{ - const char* name; - int duration; - float range; - RumbleGraph* highRumbleGraph; - RumbleGraph* lowRumbleGraph; - RumbleGraph* leftTriggerRumbleGraph; - RumbleGraph* rightTriggerRumbleGraph; - bool swapTriggerRumblesOnLefty; - bool panTriggerRumbles; - bool fadeWithDistance; - bool broadcast; -}; - -struct __declspec(align(8)) RumbleGraph -{ - const char* name; - vec2_t knots[16]; - unsigned __int16 knotCount; -}; - -struct LocalizeEntry -{ - const char* name; - const char* value; -}; - -struct StaticModelCollisionInstance -{ - vec3_t origin; - vec3_t angles; - float scale; -}; - -struct XModelDetailCollision -{ - const char* name; - unsigned int physicsLODDataSize; - char* physicsLODData; - unsigned int physicsLODDataNameCount; - scr_string_t* physicsLODDataNames; -}; - -struct StaticModelCollisionModel -{ - scr_string_t name; - PhysicsAsset* physicsAsset; - XModelDetailCollision* detailCollision; - unsigned int numInstances; - StaticModelCollisionInstance* instances; -}; - -struct __declspec(align(8)) StaticModelCollisionModelList -{ - unsigned int numModels; - StaticModelCollisionModel* models; - unsigned int structureMemoryCost; -}; - -struct PhysicsCapacities -{ - int maxNumRigidBodiesServer; - int maxNumDetailRigidBodiesServer; - int maxNumConstraintsServer; - int maxNumMotionsServer; - int maxNumRigidBodiesClient; - int maxNumDetailRigidBodiesClient; - int maxNumConstraintsClient; - int maxNumMotionsClient; -}; - -struct SpawnPointEntityRecord -{ - unsigned __int16 index; - scr_string_t name; - scr_string_t target; - scr_string_t script_noteworthy; - vec3_t origin; - vec3_t angles; -}; - -struct SpawnPointRecordList -{ - unsigned __int16 spawnsCount; - SpawnPointEntityRecord* spawns; -}; - -struct ClientMapTriggers -{ - unsigned int count; - uintptr_t models; - unsigned int hullCount; - uintptr_t hulls; - unsigned int slabCount; - uintptr_t slabs; -}; - -struct ClientTriggers -{ - ClientMapTriggers trigger; - unsigned int triggerStringLength; - char* triggerString; - __int16* visionSetTriggers; - unsigned __int16* triggerType; - vec3_t* origins; - float* scriptDelay; - float* priority; - __int16* audioTriggers; - __int16* blendLookup; - __int16* npcTriggers; - __int16* audioStateIds; - uintptr_t detailSoundBank; - uintptr_t audioRvbPanInfo; - __int16* parent; - uintptr_t linkTo; - uintptr_t spatialTree; -}; - -struct ClientTriggerBlend -{ - unsigned __int16 numClientTriggerBlendNodes; - uintptr_t blendNodes; -}; - -struct SplinePointEntityRecord -{ - int splineId; - int splineNodeId; - scr_string_t splineNodeLabel; - scr_string_t targetname; - scr_string_t target; - scr_string_t string; - float speed; - float splineNodeTension; - vec3_t origin; - vec3_t angles; - float throttle; - vec2_t corridorDims; - vec3_t tangent; - float distToNextNode; - vec3_t positionCubic[4]; - vec3_t tangentQuadratic[3]; -}; - -struct SplinePointRecordList -{ - unsigned __int16 splinePointCount; - float splineLength; - SplinePointEntityRecord* splinePoints; -}; - -struct SplineRecordList -{ - unsigned __int16 splineCount; - SplinePointRecordList* splines; -}; - -struct __declspec(align(8)) cmodel_t -{ - Bounds bounds; - float radius; - uintptr_t physicsAsset; - unsigned __int16 physicsShapeOverrideIdx; - unsigned __int16 navObstacleIdx; - unsigned int edgeFirstIndex; - unsigned int edgeTotalCount; -}; - -struct MapEdgeList -{ - const char* name; - vec3_t mins; - vec3_t maxs; - unsigned int transientIndex; - unsigned int dynamicQueryTypes; - unsigned int staticQueryTypes; - unsigned int numDynamicEdges; - unsigned int numStaticEdges; - bool valid; - unsigned int numEdges; - vec4_t(*edges)[2]; - uintptr_t edgeMetadata; - unsigned int numEdgeOctrees; - uintptr_t edgeOctrees; - unsigned int numEdgeOctreeNodeSet; - uintptr_t edgeOctreeNodeSets; - unsigned int numEdgeIndices; - unsigned int* edgeIndices; - unsigned int numEdgeAdjacencyMetadata; - uintptr_t edgeAdjacencyMetadata; - unsigned int numEdgeAdjacency; - uintptr_t edgeAdjacency; -}; - -struct __declspec(align(4)) CM_ClientModel -{ - vec3_t spawnOrigin; - vec3_t spawnAngles; - const XModel* model; - scr_string_t animationTreeName; - XAnimParts* animation; - scr_string_t name; - bool noPhysics; - bool noCloth; -}; - -struct __declspec(align(8)) MapEnts -{ - const char* name; - char* entityString; - int numEntityChars; - unsigned __int8 field_14; - unsigned __int8 field_15; - unsigned __int8 field_16; - unsigned __int8 field_17; - MapTriggers trigger; - ClientTriggers clientTrigger; - ClientTriggerBlend clientTriggerBlend; - SpawnPointRecordList spawnList; - SplineRecordList splineList; - unsigned int havokEntsShapeDataSize; - unsigned __int8 field_14C; - unsigned __int8 field_14D; - unsigned __int8 field_14E; - unsigned __int8 field_14F; - char* havokEntsShapeData; - int numSubModels; - unsigned __int8 field_15C; - unsigned __int8 field_15D; - unsigned __int8 field_15E; - unsigned __int8 field_15F; - cmodel_t* cmodels; - unsigned __int8 field_168; - unsigned __int8 field_169; - unsigned __int8 field_16A; - unsigned __int8 field_16B; - int numEdgeLists; - MapEdgeList** edgeLists; - uintptr_t edgeListSpatialTree; - int numClientModels; - unsigned __int8 field_184; - unsigned __int8 field_185; - unsigned __int8 field_186; - unsigned __int8 field_187; - CM_ClientModel* clientModels; - unsigned __int8 field_190; - unsigned __int8 field_191; - unsigned __int8 field_192; - unsigned __int8 field_193; - unsigned __int8 field_194; - unsigned __int8 field_195; - unsigned __int8 field_196; - unsigned __int8 field_197; - unsigned __int8 field_198; - unsigned __int8 field_199; - unsigned __int8 field_19A; - unsigned __int8 field_19B; - int dynEntityListsCount[2]; - __declspec(align(8)) unsigned __int8 field_1A8; - unsigned __int8 field_1A9; - unsigned __int8 field_1AA; - unsigned __int8 field_1AB; - unsigned __int8 field_1AC; - unsigned __int8 field_1AD; - unsigned __int8 field_1AE; - unsigned __int8 field_1AF; - unsigned __int8 field_1B0; - unsigned __int8 field_1B1; - unsigned __int8 field_1B2; - unsigned __int8 field_1B3; - unsigned __int8 field_1B4; - unsigned __int8 field_1B5; - unsigned __int8 field_1B6; - unsigned __int8 field_1B7; - unsigned __int8 field_1B8; - unsigned __int8 field_1B9; - unsigned __int8 field_1BA; - unsigned __int8 field_1BB; - unsigned __int8 field_1BC; - unsigned __int8 field_1BD; - unsigned __int8 field_1BE; - unsigned __int8 field_1BF; - unsigned __int8 field_1C0; - unsigned __int8 field_1C1; - unsigned __int8 field_1C2; - unsigned __int8 field_1C3; - unsigned __int8 field_1C4; - unsigned __int8 field_1C5; - unsigned __int8 field_1C6; - unsigned __int8 field_1C7; - uintptr_t dynEntSpatialPopulation[2]; - uintptr_t dynEntSpatialTransientMap[2]; - unsigned __int8 field_1E8; - unsigned __int8 field_1E9; - unsigned __int8 field_1EA; - unsigned __int8 field_1EB; - int clientEntAnchorCount; - uintptr_t clientEntAnchors; - unsigned __int8 scriptableMapEnts; - unsigned __int8 field_1F9; - unsigned __int8 field_1FA; - unsigned __int8 field_1FB; - unsigned __int8 field_1FC; - unsigned __int8 field_1FD; - unsigned __int8 field_1FE; - unsigned __int8 field_1FF; - unsigned __int8 field_200; - unsigned __int8 field_201; - unsigned __int8 field_202; - unsigned __int8 field_203; - unsigned __int8 field_204; - unsigned __int8 field_205; - unsigned __int8 field_206; - unsigned __int8 field_207; - unsigned __int8 field_208; - unsigned __int8 field_209; - unsigned __int8 field_20A; - unsigned __int8 field_20B; - unsigned __int8 field_20C; - unsigned __int8 field_20D; - unsigned __int8 field_20E; - unsigned __int8 field_20F; - unsigned __int8 field_210; - unsigned __int8 field_211; - unsigned __int8 field_212; - unsigned __int8 field_213; - unsigned __int8 field_214; - unsigned __int8 field_215; - unsigned __int8 field_216; - unsigned __int8 field_217; - unsigned __int8 field_218; - unsigned __int8 field_219; - unsigned __int8 field_21A; - unsigned __int8 field_21B; - unsigned __int8 field_21C; - unsigned __int8 field_21D; - unsigned __int8 field_21E; - unsigned __int8 field_21F; - unsigned __int8 field_220; - unsigned __int8 field_221; - unsigned __int8 field_222; - unsigned __int8 field_223; - unsigned __int8 field_224; - unsigned __int8 field_225; - unsigned __int8 field_226; - unsigned __int8 field_227; - unsigned __int8 field_228; - unsigned __int8 field_229; - unsigned __int8 field_22A; - unsigned __int8 field_22B; - unsigned __int8 field_22C; - unsigned __int8 field_22D; - unsigned __int8 field_22E; - unsigned __int8 field_22F; - unsigned __int8 field_230; - unsigned __int8 field_231; - unsigned __int8 field_232; - unsigned __int8 field_233; - unsigned __int8 field_234; - unsigned __int8 field_235; - unsigned __int8 field_236; - unsigned __int8 field_237; - unsigned __int8 field_238; - unsigned __int8 field_239; - unsigned __int8 field_23A; - unsigned __int8 field_23B; - unsigned __int8 field_23C; - unsigned __int8 field_23D; - unsigned __int8 field_23E; - unsigned __int8 field_23F; - unsigned __int8 field_240; - unsigned __int8 field_241; - unsigned __int8 field_242; - unsigned __int8 field_243; - unsigned __int8 field_244; - unsigned __int8 field_245; - unsigned __int8 field_246; - unsigned __int8 field_247; - unsigned __int8 field_248; - unsigned __int8 field_249; - unsigned __int8 field_24A; - unsigned __int8 field_24B; - unsigned __int8 field_24C; - unsigned __int8 field_24D; - unsigned __int8 field_24E; - unsigned __int8 field_24F; - unsigned __int8 field_250; - unsigned __int8 field_251; - unsigned __int8 field_252; - unsigned __int8 field_253; - unsigned __int8 field_254; - unsigned __int8 field_255; - unsigned __int8 field_256; - unsigned __int8 field_257; - unsigned __int8 field_258; - unsigned __int8 field_259; - unsigned __int8 field_25A; - unsigned __int8 field_25B; - unsigned __int8 field_25C; - unsigned __int8 field_25D; - unsigned __int8 field_25E; - unsigned __int8 field_25F; - unsigned __int8 field_260; - unsigned __int8 field_261; - unsigned __int8 field_262; - unsigned __int8 field_263; - unsigned __int8 field_264; - unsigned __int8 field_265; - unsigned __int8 field_266; - unsigned __int8 field_267; - unsigned __int8 field_268; - unsigned __int8 field_269; - unsigned __int8 field_26A; - unsigned __int8 field_26B; - unsigned __int8 field_26C; - unsigned __int8 field_26D; - unsigned __int8 field_26E; - unsigned __int8 field_26F; - unsigned __int8 field_270; - unsigned __int8 field_271; - unsigned __int8 field_272; - unsigned __int8 field_273; - unsigned __int8 field_274; - unsigned __int8 field_275; - unsigned __int8 field_276; - unsigned __int8 field_277; - unsigned __int8 field_278; - unsigned __int8 field_279; - unsigned __int8 field_27A; - unsigned __int8 field_27B; - unsigned __int8 field_27C; - unsigned __int8 field_27D; - unsigned __int8 field_27E; - unsigned __int8 field_27F; - unsigned __int8 field_280; - unsigned __int8 field_281; - unsigned __int8 field_282; - unsigned __int8 field_283; - unsigned __int8 field_284; - unsigned __int8 field_285; - unsigned __int8 field_286; - unsigned __int8 field_287; - unsigned __int8 field_288; - unsigned __int8 field_289; - unsigned __int8 field_28A; - unsigned __int8 field_28B; - unsigned __int8 field_28C; - unsigned __int8 field_28D; - unsigned __int8 field_28E; - unsigned __int8 field_28F; - unsigned __int8 field_290; - unsigned __int8 field_291; - unsigned __int8 field_292; - unsigned __int8 field_293; - unsigned __int8 field_294; - unsigned __int8 field_295; - unsigned __int8 field_296; - unsigned __int8 field_297; - unsigned __int8 field_298; - unsigned __int8 field_299; - unsigned __int8 field_29A; - unsigned __int8 field_29B; - unsigned __int8 field_29C; - unsigned __int8 field_29D; - unsigned __int8 field_29E; - unsigned __int8 field_29F; - unsigned __int8 field_2A0; - unsigned __int8 field_2A1; - unsigned __int8 field_2A2; - unsigned __int8 field_2A3; - unsigned __int8 field_2A4; - unsigned __int8 field_2A5; - unsigned __int8 field_2A6; - unsigned __int8 field_2A7; - unsigned __int8 field_2A8; - unsigned __int8 field_2A9; - unsigned __int8 field_2AA; - unsigned __int8 field_2AB; - unsigned __int8 field_2AC; - unsigned __int8 field_2AD; - unsigned __int8 field_2AE; - unsigned __int8 field_2AF; - unsigned __int8 field_2B0; - unsigned __int8 field_2B1; - unsigned __int8 field_2B2; - unsigned __int8 field_2B3; - unsigned __int8 field_2B4; - unsigned __int8 field_2B5; - unsigned __int8 field_2B6; - unsigned __int8 field_2B7; - unsigned __int8 field_2B8; - unsigned __int8 field_2B9; - unsigned __int8 field_2BA; - unsigned __int8 field_2BB; - unsigned __int8 field_2BC; - unsigned __int8 field_2BD; - unsigned __int8 field_2BE; - unsigned __int8 field_2BF; - unsigned __int8 field_2C0; - unsigned __int8 field_2C1; - unsigned __int8 field_2C2; - unsigned __int8 field_2C3; - unsigned __int8 field_2C4; - unsigned __int8 field_2C5; - unsigned __int8 field_2C6; - unsigned __int8 field_2C7; - unsigned __int8 field_2C8; - unsigned __int8 field_2C9; - unsigned __int8 field_2CA; - unsigned __int8 field_2CB; - unsigned __int8 field_2CC; - unsigned __int8 field_2CD; - unsigned __int8 field_2CE; - unsigned __int8 field_2CF; - unsigned __int8 field_2D0; - unsigned __int8 field_2D1; - unsigned __int8 field_2D2; - unsigned __int8 field_2D3; - unsigned __int8 field_2D4; - unsigned __int8 field_2D5; - unsigned __int8 field_2D6; - unsigned __int8 field_2D7; - unsigned __int8 field_2D8; - unsigned __int8 field_2D9; - unsigned __int8 field_2DA; - unsigned __int8 field_2DB; - unsigned __int8 field_2DC; - unsigned __int8 field_2DD; - unsigned __int8 field_2DE; - unsigned __int8 field_2DF; - unsigned __int8 field_2E0; - unsigned __int8 field_2E1; - unsigned __int8 field_2E2; - unsigned __int8 field_2E3; - unsigned __int8 field_2E4; - unsigned __int8 field_2E5; - unsigned __int8 field_2E6; - unsigned __int8 field_2E7; - unsigned __int8 field_2E8; - unsigned __int8 field_2E9; - unsigned __int8 field_2EA; - unsigned __int8 field_2EB; - unsigned __int8 field_2EC; - unsigned __int8 field_2ED; - unsigned __int8 field_2EE; - unsigned __int8 field_2EF; - unsigned __int8 field_2F0; - unsigned __int8 field_2F1; - unsigned __int8 field_2F2; - unsigned __int8 field_2F3; - unsigned __int8 field_2F4; - unsigned __int8 field_2F5; - unsigned __int8 field_2F6; - unsigned __int8 field_2F7; - unsigned __int8 field_2F8; - unsigned __int8 field_2F9; - unsigned __int8 field_2FA; - unsigned __int8 field_2FB; - unsigned __int8 field_2FC; - unsigned __int8 field_2FD; - unsigned __int8 field_2FE; - unsigned __int8 field_2FF; - unsigned __int8 field_300; - unsigned __int8 field_301; - unsigned __int8 field_302; - unsigned __int8 field_303; - unsigned __int8 field_304; - unsigned __int8 field_305; - unsigned __int8 field_306; - unsigned __int8 field_307; - unsigned __int8 field_308; - unsigned __int8 field_309; - unsigned __int8 field_30A; - unsigned __int8 field_30B; - unsigned __int8 field_30C; - unsigned __int8 field_30D; - unsigned __int8 field_30E; - unsigned __int8 field_30F; - unsigned __int8 field_310; - unsigned __int8 field_311; - unsigned __int8 field_312; - unsigned __int8 field_313; - unsigned __int8 field_314; - unsigned __int8 field_315; - unsigned __int8 field_316; - unsigned __int8 field_317; - unsigned __int8 field_318; - unsigned __int8 field_319; - unsigned __int8 field_31A; - unsigned __int8 field_31B; - unsigned __int8 field_31C; - unsigned __int8 field_31D; - unsigned __int8 field_31E; - unsigned __int8 field_31F; - unsigned __int8 field_320; - unsigned __int8 field_321; - unsigned __int8 field_322; - unsigned __int8 field_323; - unsigned __int8 field_324; - unsigned __int8 field_325; - unsigned __int8 field_326; - unsigned __int8 field_327; - unsigned __int8 field_328; - unsigned __int8 field_329; - unsigned __int8 field_32A; - unsigned __int8 field_32B; - unsigned __int8 field_32C; - unsigned __int8 field_32D; - unsigned __int8 field_32E; - unsigned __int8 field_32F; - unsigned __int8 field_330; - unsigned __int8 field_331; - unsigned __int8 field_332; - unsigned __int8 field_333; - unsigned __int8 field_334; - unsigned __int8 field_335; - unsigned __int8 field_336; - unsigned __int8 field_337; - unsigned __int8 field_338; - unsigned __int8 field_339; - unsigned __int8 field_33A; - unsigned __int8 field_33B; - unsigned __int8 field_33C; - unsigned __int8 field_33D; - unsigned __int8 field_33E; - unsigned __int8 field_33F; - unsigned __int8 field_340; - unsigned __int8 field_341; - unsigned __int8 field_342; - unsigned __int8 field_343; - unsigned __int8 field_344; - unsigned __int8 field_345; - unsigned __int8 field_346; - unsigned __int8 field_347; - unsigned __int8 field_348; - unsigned __int8 field_349; - unsigned __int8 field_34A; - unsigned __int8 field_34B; - unsigned __int8 field_34C; - unsigned __int8 field_34D; - unsigned __int8 field_34E; - unsigned __int8 field_34F; - unsigned __int8 field_350; - unsigned __int8 field_351; - unsigned __int8 field_352; - unsigned __int8 field_353; - unsigned __int8 field_354; - unsigned __int8 field_355; - unsigned __int8 field_356; - unsigned __int8 field_357; - unsigned __int8 field_358; - unsigned __int8 field_359; - unsigned __int8 field_35A; - unsigned __int8 field_35B; - unsigned __int8 field_35C; - unsigned __int8 field_35D; - unsigned __int8 field_35E; - unsigned __int8 field_35F; - unsigned __int8 field_360; - unsigned __int8 field_361; - unsigned __int8 field_362; - unsigned __int8 field_363; - unsigned __int8 field_364; - unsigned __int8 field_365; - unsigned __int8 field_366; - unsigned __int8 field_367; - unsigned __int8 field_368; - unsigned __int8 field_369; - unsigned __int8 field_36A; - unsigned __int8 field_36B; - unsigned __int8 field_36C; - unsigned __int8 field_36D; - unsigned __int8 field_36E; - unsigned __int8 field_36F; - unsigned __int8 field_370; - unsigned __int8 field_371; - unsigned __int8 field_372; - unsigned __int8 field_373; - unsigned __int8 field_374; - unsigned __int8 field_375; - unsigned __int8 field_376; - unsigned __int8 field_377; - unsigned __int8 field_378; - unsigned __int8 field_379; - unsigned __int8 field_37A; - unsigned __int8 field_37B; - unsigned __int8 field_37C; - unsigned __int8 field_37D; - unsigned __int8 field_37E; - unsigned __int8 field_37F; - unsigned __int8 field_380; - unsigned __int8 field_381; - unsigned __int8 field_382; - unsigned __int8 field_383; - unsigned __int8 field_384; - unsigned __int8 field_385; - unsigned __int8 field_386; - unsigned __int8 field_387; - unsigned __int8 field_388; - unsigned __int8 field_389; - unsigned __int8 field_38A; - unsigned __int8 field_38B; - unsigned __int8 field_38C; - unsigned __int8 field_38D; - unsigned __int8 field_38E; - unsigned __int8 field_38F; - unsigned __int8 field_390; - unsigned __int8 field_391; - unsigned __int8 field_392; - unsigned __int8 field_393; - unsigned __int8 field_394; - unsigned __int8 field_395; - unsigned __int8 field_396; - unsigned __int8 field_397; - unsigned __int8 field_398; - unsigned __int8 field_399; - unsigned __int8 field_39A; - unsigned __int8 field_39B; - unsigned __int8 field_39C; - unsigned __int8 field_39D; - unsigned __int8 field_39E; - unsigned __int8 field_39F; - unsigned __int8 field_3A0; - unsigned __int8 field_3A1; - unsigned __int8 field_3A2; - unsigned __int8 field_3A3; - unsigned __int8 field_3A4; - unsigned __int8 field_3A5; - unsigned __int8 field_3A6; - unsigned __int8 field_3A7; - unsigned __int8 field_3A8; - unsigned __int8 field_3A9; - unsigned __int8 field_3AA; - unsigned __int8 field_3AB; - unsigned __int8 field_3AC; - unsigned __int8 field_3AD; - unsigned __int8 field_3AE; - unsigned __int8 field_3AF; - unsigned __int8 field_3B0; - unsigned __int8 field_3B1; - unsigned __int8 field_3B2; - unsigned __int8 field_3B3; - unsigned __int8 field_3B4; - unsigned __int8 field_3B5; - unsigned __int8 field_3B6; - unsigned __int8 field_3B7; - unsigned __int8 field_3B8; - unsigned __int8 field_3B9; - unsigned __int8 field_3BA; - unsigned __int8 field_3BB; - unsigned __int8 field_3BC; - unsigned __int8 field_3BD; - unsigned __int8 field_3BE; - unsigned __int8 field_3BF; - unsigned __int8 field_3C0; - unsigned __int8 field_3C1; - unsigned __int8 field_3C2; - unsigned __int8 field_3C3; - unsigned __int8 field_3C4; - unsigned __int8 field_3C5; - unsigned __int8 field_3C6; - unsigned __int8 field_3C7; - unsigned __int8 field_3C8; - unsigned __int8 field_3C9; - unsigned __int8 field_3CA; - unsigned __int8 field_3CB; - unsigned __int8 field_3CC; - unsigned __int8 field_3CD; - unsigned __int8 field_3CE; - unsigned __int8 field_3CF; - unsigned __int8 field_3D0; - unsigned __int8 field_3D1; - unsigned __int8 field_3D2; - unsigned __int8 field_3D3; - unsigned __int8 field_3D4; - unsigned __int8 field_3D5; - unsigned __int8 field_3D6; - unsigned __int8 field_3D7; - unsigned __int8 field_3D8; - unsigned __int8 field_3D9; - unsigned __int8 field_3DA; - unsigned __int8 field_3DB; - unsigned __int8 field_3DC; - unsigned __int8 field_3DD; - unsigned __int8 field_3DE; - unsigned __int8 field_3DF; - unsigned __int8 field_3E0; - unsigned __int8 field_3E1; - unsigned __int8 field_3E2; - unsigned __int8 field_3E3; - unsigned __int8 field_3E4; - unsigned __int8 field_3E5; - unsigned __int8 field_3E6; - unsigned __int8 field_3E7; - unsigned __int8 field_3E8; - unsigned __int8 field_3E9; - unsigned __int8 field_3EA; - unsigned __int8 field_3EB; - unsigned __int8 field_3EC; - unsigned __int8 field_3ED; - unsigned __int8 field_3EE; - unsigned __int8 field_3EF; - unsigned __int8 field_3F0; - unsigned __int8 field_3F1; - unsigned __int8 field_3F2; - unsigned __int8 field_3F3; - unsigned __int8 field_3F4; - unsigned __int8 field_3F5; - unsigned __int8 field_3F6; - unsigned __int8 field_3F7; - unsigned __int8 field_3F8; - unsigned __int8 field_3F9; - unsigned __int8 field_3FA; - unsigned __int8 field_3FB; - unsigned __int8 field_3FC; - unsigned __int8 field_3FD; - unsigned __int8 field_3FE; - unsigned __int8 field_3FF; - unsigned __int8 field_400; - unsigned __int8 field_401; - unsigned __int8 field_402; - unsigned __int8 field_403; - unsigned __int8 field_404; - unsigned __int8 field_405; - unsigned __int8 field_406; - unsigned __int8 field_407; -}; - - -struct CollisionHeatmapEntry -{ - int vertexCount; - float vertexDensity; - vec3_t minExtent; - vec3_t maxExtent; -}; - -struct Stage -{ - const char* name; - vec3_t origin; - unsigned __int16 triggerIndex; - unsigned __int8 sunPrimaryLightIndex; - unsigned int entityUID; - vec3_t skyRotationAngles; -}; - -struct __declspec(align(8)) clipMap_t -{ - const char* name; - int isInUse; - unsigned int numStaticModelCollisionModelLists; - StaticModelCollisionModelList* staticModelCollisionModelLists; - MapEnts* mapEnts; - Stage* stages; - unsigned __int8 stageCount; - MapTriggers stageTrigger; - vec3_t broadphaseMin; - vec3_t broadphaseMax; - PhysicsCapacities physicsCapacities; - unsigned int havokWorldShapeDataSize; - char* havokWorldShapeData; - unsigned int numCollisionHeatmapEntries; - CollisionHeatmapEntry* collisionHeatmap; - unsigned int totalGlassInitPieceCount; - unsigned int totalGlassPieceLimit; - uintptr_t topDownMapData; - const char* visionSetName; - unsigned int checksum; -}; - -struct __declspec(align(8)) WeaponDef -{ - const char* szOverlayName; - XModel* gunXModel; - XModel* gunXModelLeftHand; - XModel* gunXModelRightHand; - XModel* defaultViewModel; - XModel* defaultWorldModelLeftHand; - XModel* defaultWorldModelRightHand; - XModel* worldModel; - XModel* worldXModelLeftHand; - XModel* worldXModelRightHand; - XModel* defaultWorldModel; - XModel* censorshipWorldModel; - XModel* censorshipWorldModelLeftHand; - XModel* censorshipWorldModelRightHand; - XModel* playerShadowModel; - XModel* playerShadowModelLeftHand; - XModel* playerShadowModelRightHand; - XModel* handXModel; - WeaponAnimPackage* szXAnims; - WeaponAnimPackage* szXAnimsRightHanded; - WeaponAnimPackage* szXAnimsLeftHanded; - XAnimParts* turretRaiseAnim; - XAnimParts* turretIdleAnim; - XAnimParts* turretFireAnim; - WeaponDamageInfo damageInfo; - int iFireTime; - int iFireDelay; - int iFireTimeAkimbo; - int iFireDelayAkimbo; - float sprintOutTimerScale; - const char* szModeName; - scr_string_t* notetrackRumbleMapKeys; - scr_string_t* notetrackRumbleMapValues; - scr_string_t* notetrackFXMapKeys; - FxCombinedDef* notetrackFXMapValues; - scr_string_t* notetrackFXMapTagValues; - int playerAnimType; - int scriptedAnimEvent; - int scriptedAnimType; - int weapType; - int weapClass; - int penetrateType; - int inventoryType; - int fireType; - int turretFireType; - int burstCount; - int targetAssistType; - int targetAssistBehavior; - float targetAssistRange; - float targetAssistAngle; - float targetAssistLosOffsetForward; - float targetAssistLosOffsetRight; - float targetAssistLosOffsetUp; - bool targetAssistOnlyAvailableInAds; - int reloadType; - float burstFireCooldown; - bool burstFireAuto; - float viewPitchMaxSpeed; - float viewYawMaxSpeed; - bool alignBarrelWithTurretBody; - bool keepOrientationOnExit; - float kickBackForceMultiplier; - bool autoAdjust; - bool networkLODRangeOverride; - float networkLODRangeOverrideDistance; - int offhandClass; - int stance; - WeaponVFXPackage* vfxPackage; - WeaponSFXPackage* sfxPackage; - bool disableBreathOffhand; - int reticleType; - int hitmarkerType; - Material* reticleCenter; - Material* reticleSide; - Material* reticleOnePiece; - int iReticleCenterSize; - int iReticleSideSize; - int iReticleMinOfs; - bool reticleCenterPulse; - int iReticleShakeDuration; - int iReticleSettleDuration; - int iReticleNumBulletsToRapidFire; - int activeReticleType; - bool useTurretViewmodelAnims; - bool useTurret3pIK; - int turret3pAnimType; - float turretFireAnimMinTime; - vec3_t vStandOfs; - vec3_t vStandOfsRot; - vec3_t vStandOfsRotPivot; - vec3_t vStandMove; - vec3_t vStandRot; - vec3_t strafeMove; - vec3_t strafeRot; - int hipOffsetLerpType; - vec3_t vDuckedOfs; - vec3_t vDuckedOfsRot; - vec3_t vDuckedOfsRotPivot; - vec3_t vDuckedMove; - vec3_t vDuckedRot; - vec3_t vProneOfs; - vec3_t vProneMove; - vec3_t vProneRot; - float adsForwardOffset; - float adsRoll; - float fPosMoveRate; - float fPosProneMoveRate; - float fStandMoveMinSpeed; - float fDuckedMoveMinSpeed; - float fProneMoveMinSpeed; - float fPosRotRate; - float fPosProneRotRate; - float fDuckedOfsRotRate; - float fStandRotMinSpeed; - float fDuckedRotMinSpeed; - float fProneRotMinSpeed; - float fReticleShakeMagnitude; - float fReticleRapidFireMultiplier; - XModel* worldClipModel; - XModel* rocketModel; - GfxImage* hudIcon; - GfxImage* pickupIcon; - GfxImage* dangerIconImg; - GfxImage* throwBackIconImg; - Material* dangerIconMat; - Material* throwBackIconMat; - bool hideWarningIcons; - float warningIconsDelay; - int ammoCounterClip; - int iStartAmmo; - int iPerkStartAmmo; - int iPerkMaxAmmo; - const char* szAmmoName; - int iAmmoIndex; - int iMaxAmmo; - int shotCount; - const char* szSharedAmmoCapName; - int iSharedAmmoCapIndex; - int iSharedAmmoCap; - int iAmmoUsedPerShot; - bool requireAmmoUsedPerShot; - bool disableNoAmmoWarning; - float lowAmmoWarningThreshold; - int lowAmmoWarningCount; - int iDamageType; - int iMeleeDamage; - int iMeleeCountToFinisher; - bool hasMeleeFinisher; - float autoAimRange; - float aimAssistRange; - float aimAssistRangeAds; - float aimAssistPitchSlowdown; - float aimAssistPitchSlowdownAds; - float aimAssistYawSlowdown; - float aimAssistYawSlowdownAds; - float aimAssistLockonStrength; - float aimPadding; - float enemyCrosshairRange; - float moveSpeedScale; - float adsMoveSpeedScale; - float sprintDurationScale; - float sprintRestoreDelay; - ADSOverlay overlay; - int overlayInterface; - float fAdsBobFactor; - float fAdsViewBobMult; - float fAdsGunBobPitchScale; - float fAdsGunBobYawScale; - float fAdsGunBobTiltPitchScale; - float fAdsGunBobTiltYawScale; - float fAdsGunBobTiltRollScale; - float fAdsGunBobTiltBulletDirScale; - float fAdsGunBobTiltOffset; - float fAdsGunBobCrouchFactor; - float adsCrouchViewKickFactor; - float adsCrouchGunKickFactor; - float adsProneViewKickFactor; - float adsProneGunKickFactor; - float fHipSpreadStandMin; - float fHipSpreadDuckedMin; - float fHipSpreadProneMin; - float hipSpreadSprintMin; - float hipSpreadInAirMin; - float hipSpreadStandMax; - float hipSpreadDuckedMax; - float hipSpreadProneMax; - float hipSpreadSprintMax; - float hipSpreadInAirMax; - float fHipSpreadDecayRate; - float fHipSpreadFireAdd; - float fHipSpreadTurnAdd; - float fHipSpreadMoveAdd; - float fHipSpreadDuckedDecay; - float fHipSpreadProneDecay; - float hipSpreadSprintDecay; - float hipSpreadInAirDecay; - float fHipReticleSidePos; - float fAdsIdleAmount; - float fHipIdleAmount; - float adsIdleSpeed; - float hipIdleSpeed; - float fIdleCrouchFactor; - float fIdleProneFactor; - float fGunMaxPitch; - float fGunMaxYaw; - float fViewMaxPitch; - float fViewMaxYaw; - float adsIdleLerpStartTime; - float adsIdleLerpTime; - bool useUninterruptedAdsIdleMotion; - bool disableInputDrivenViewReturnDampening; - float slideSpreadMin; - float slideSpreadMax; - float slideSpreadDecayRate; - float slideSpreadFireAdd; - float slideSpreadTurnAdd; - SwaySettings swaySettings; - float adsFireRateScale; - float adsDamageRangeScale; - float adsFireAnimFrac; - float fireTimerLerpToAdsScale; - bool alwaysFireAtMaxRangeInAds; - bool adsAlignEnabled; - bool disableTagAlignX; - vec3_t adsAlignOffset; - int adsAlignOffsetLerpType; - int adsAlignLerpType; - float adsMovementAnimLerpStart; - float adsMovementAnimLerpEnd; - float dualWieldViewModelOffset; - float fScopeDriftDelay; - float fScopeDriftLerpInTime; - float fScopeDriftSteadyTime; - float fScopeDriftLerpOutTime; - float fScopeDriftSteadyFactor; - float fScopeDriftUnsteadyFactor; - int killIconRatio; - int iReloadAmmoAdd; - int iReloadStartAdd; - bool reloadTwoRound; - int ammoDropStockMin; - int ammoDropClipPercentMin; - int ammoDropClipPercentMax; - float cameraShakeScale; - int cameraShakeDuration; - float cameraShakeRadius; - int iExplosionRadius; - int iExplosionRadiusMin; - int iExplosionForceRadius; - int iExplosionInnerDamage; - int iExplosionOuterDamage; - float explosionForceScalar; - float damageConeAngle; - float bulletExplDmgMultMin; - float bulletExplDmgMult; - float bulletExplRadiusMult; - int iProjectileSpeed; - int iProjectileSpeedUp; - int iProjectileSpeedForward; - int iProjectileActivateDist; - int iProjectileDetonationRadius; - float projLifetime; - float projLifetimeStdDeviation; - float timeToAccelerate; - float projectileCurvature; - XModel* projectileModel; - int projExplosion; - FxCombinedDef projExplosionEffect; - FxCombinedDef projDudEffect; - FxCombinedDef projTimeoutEffect; - int iExplosionSteppedRadiusInner; - int iExplosionSteppedRadiusMid; - int iExplosionSteppedRadiusOuter; - int iExplosionSteppedDamageInner; - int iExplosionSteppedDamageMid; - int iExplosionSteppedDamageOuter; - float* parallelBounce; - float* perpendicularBounce; - FxCombinedDef vmProjBodyEffect; - FxCombinedDef projBodyEffect; - FxCombinedDef projTrailEffect; - FxCombinedDef projBeaconEffect; - vec3_t vProjectileColor; - int guidedMissileType; - float maxSteeringAccel; - int projIgnitionDelay; - FxCombinedDef projIgnitionEffect; - float fAdsAimPitch; - float adsInCrosshairAlphaStart; - float adsInCrosshairAlphaEnd; - float adsOutCrosshairAlphaStart; - float adsOutCrosshairAlphaEnd; - bool adsShouldShowCrosshair; - float fAdsGunKickPitchMin; - float fAdsGunKickPitchMax; - float fAdsGunKickYawMin; - float fAdsGunKickYawMax; - float fAdsGunKickMagMin; - float fAdsGunKickAccel; - float fAdsGunKickSpeedMax; - float fAdsGunKickSpeedDecay; - float fAdsGunKickStaticDecay; - float fAdsViewKickPitchMin; - float fAdsViewKickPitchMax; - float fAdsViewKickYawMin; - float fAdsViewKickYawMax; - float fAdsViewKickMagMin; - float fAdsViewScatterMin; - float fAdsViewScatterMax; - float fAdsSpread; - float fAdsSpreadNVG; - float adsSpreadStartFrac; - float adsSpreadEndFrac; - int iVisibilityAxis; - float fVisibilityUpOffset; - float fHipGunKickPitchMin; - float fHipGunKickPitchMax; - float fHipGunKickYawMin; - float fHipGunKickYawMax; - float fHipGunKickMagMin; - float fHipGunKickAccel; - float fHipGunKickSpeedMax; - float fHipGunKickSpeedDecay; - float fHipGunKickStaticDecay; - float fHipViewKickPitchMin; - float fHipViewKickPitchMax; - float fHipViewKickYawMin; - float fHipViewKickYawMax; - float fHipViewKickMagMin; - float fHipViewScatterMin; - float fHipViewScatterMax; - float multipleReloadClipPercentage; - float hipStartingGunKickPercent; - float hipStartingViewKickPercent; - int adsStartingKickBullets; - float adsStartingGunKickPercent; - float adsStartingViewKickPercent; - float hipEndingGunKickPercent; - float hipEndingViewKickPercent; - int adsEndingKickBullets; - float adsEndingGunKickPercent; - float adsEndingViewKickPercent; - float kickAlignedInputScalar; - float kickOpposedInputScalar; - float viewKickMaintainFraction; - float adsGunTiltPitchFactor; - float adsGunTiltYawFactor; - float adsGunTiltRollFactor; - float adsGunTiltOffset; - float hipGunTiltPitchFactor; - float hipGunTiltYawFactor; - float hipGunTiltRollFactor; - float hipGunTiltOffset; - bool useNewViewKick; - bool useNewGunKick; - bool useAngularViewKick; - bool useAngularGunKick; - float hipAngularViewKickDir[6]; - float hipAngularViewKickDev[6]; - float hipAngularViewKickStrengthMin[6]; - float hipAngularViewKickStrengthMax[6]; - float hipAngularViewKickPitchScale[6]; - float adsAngularViewKickDir[6]; - float adsAngularViewKickDev[6]; - float adsAngularViewKickStrengthMin[6]; - float adsAngularViewKickStrengthMax[6]; - float adsAngularViewKickPitchScale[6]; - int adsAngularViewKickBullet[6]; - bool adsAngularViewKickUseSet[6]; - float hipAngularGunKickDir[6]; - float hipAngularGunKickDev[6]; - float hipAngularGunKickStrengthMin[6]; - float hipAngularGunKickStrengthMax[6]; - float hipAngularGunKickPitchScale[6]; - float adsAngularGunKickDir[6]; - float adsAngularGunKickDev[6]; - float adsAngularGunKickStrengthMin[6]; - float adsAngularGunKickStrengthMax[6]; - float adsAngularGunKickPitchScale[6]; - int adsAngularGunKickBullet[6]; - bool adsAngularGunKickUseSet[6]; - float hipViewKickReturnAccelScale; - float adsViewKickReturnAccelScale; - float hipViewKickReturnSpeedCurveScale; - float adsViewKickReturnSpeedCurveScale; - float hipGunKickReturnAccelScale; - float adsGunKickReturnAccelScale; - float hipGunKickReturnSpeedCurveScale; - float adsGunKickReturnSpeedCurveScale; - float hipSpreadStandMoveMax; - float hipSpreadDuckedMoveMax; - float hipSpreadProneMoveMax; - float hipSpreadSprintMoveMax; - float hipSpreadInAirMoveMax; - float slideSpreadMoveMax; - WeaponOffsetCurveDescription weaponOffsetCurveHoldFireSlow; - WeaponOffsetCurveDescription weaponOffsetCurveHoldFireFast; - WeaponOffsetCurveDescription weaponOffsetCurveAds; - WeaponOffsetCurveDescription weaponOffsetCurveAlwaysOn; - WeaponOffsetCurveDescription weaponOffsetCurveKick; - WeaponOffsetCurveDescription weaponOffsetCurveSnapDecay; - int numWeaponOffsetPatterns; - WeaponOffsetPatternDescription* weaponOffsetPatterns; - int numWeaponOffsetPatternsKickOrSnapDecay; - WeaponOffsetPatternDescription** weaponOffsetPatternsKickOrSnapDecay; - float fightDist; - float maxDist; - const char* accuracyGraphName[2]; - vec2_t* originalAccuracyGraphKnots[2]; - unsigned __int16 originalAccuracyGraphKnotCount[2]; - int iPositionReloadTransTime; - float leftArc; - float rightArc; - float topArc; - float bottomArc; - float visualPitchLimitTop; - float visualPitchLimitBottom; - bool softLeftRightArc; - float accuracy; - float aiSpread; - float playerSpread; - float minTurnSpeed[2]; - float maxTurnSpeed[2]; - float pitchConvergenceTime; - float yawConvergenceTime; - float suppressTime; - float suppressTimeTargetKilled; - float aiReturnToDefaultSpeed[2]; - float maxRange; - float fAnimHorRotateInc; - float fPlayerPositionDist; - const char* szUseHintString; - const char* dropHintString; - unsigned int iUseHintStringIndex; - unsigned int dropHintStringIndex; - float horizViewJitter; - float vertViewJitter; - bool enableViewBounceFire; - float viewBounceFireDecay; - float viewBounceFireFrequency; - float viewBounceFirePitchScale; - float viewBounceFireRollScale; - float scanSpeed; - float scanAccel; - int scanPauseTime; - const char* szScript; - float adsSpeedMs[2]; - float adsAccelSec[2]; - bool deferDamageToParentVehicle; - bool useSteppedExplosionDamage; - float destabilizationRateTime; - float destabilizationCurvatureMax; - int destabilizeDistance; - float robotechMaxPitch; - float robotechMaxYaw; - float robotechFrequency; - float robotechVariancePitch; - float robotechVarianceYaw; - float robotechVarianceFrequency; - float* locationDamageMultipliers; - unsigned __int8* hitLocPriorityMap; - float unittypeMultipliers[7]; - RumbleInfo* fireRumble; - RumbleInfo* meleeImpactRumble; - float heatAccumulationPerShot; - float heatDissipationPerSecond; - float heatSmokeStartThreshold; - float heatSmokeStopThreshold; - bool heatIsOpenBolt; - int tracerStyle; - TracerDef* tracerType; - TracerDef* overchargeTracerType; - LaserDef* laserTypeViewModel; - LaserDef* laserTypeViewModelAlt; - LaserDef* laserTypeFriendly; - LaserDef* laserTypeEnemy; - bool turretADSEnabled; - float turretADSTime; - float turretFov; - float turretFovADS; - float turretScopeZoomRate; - float turretScopeZoomMin; - float turretScopeZoomMax; - float turretOverheatPenalty; - SndAliasLookup turretOverheatSound; - FxCombinedDef turretOverheatEffect; - RumbleInfo* turretBarrelSpinRumble; - float turretBarrelSpinSpeed; - float turretBarrelSpinUpTime; - float turretBarrelSpinDownTime; - SndAliasLookup turretBarrelSpinMaxSnd; - SndAliasLookup turretBarrelSpinUpSnd[4]; - SndAliasLookup turretBarrelSpinDownSnd[4]; - SndAliasLookup missileConeSoundAlias; - SndAliasLookup missileConeSoundAliasAtBase; - float missileConeSoundRadiusAtTop; - float missileConeSoundRadiusAtBase; - float missileConeSoundHeight; - float missileConeSoundOriginOffset; - float missileConeSoundVolumescaleAtCore; - float missileConeSoundVolumescaleAtEdge; - float missileConeSoundVolumescaleCoreSize; - float missileConeSoundPitchAtTop; - float missileConeSoundPitchAtBottom; - float missileConeSoundPitchTopSize; - float missileConeSoundPitchBottomSize; - float missileConeSoundCrossfadeTopSize; - float missileConeSoundCrossfadeBottomSize; - bool meleeOverrideValues; - float aim_automelee_lerp; - float aim_automelee_region_height; - float aim_automelee_region_width; - float aim_automelee_maxPitchMovement; - float aim_automelee_maxYawMovement; - float player_meleeHeight; - float player_meleeWidth; - float playerMeleeRangeStanding; - float playerMeleeRangeCrouched; - float playerMeleeRangeProne; - float playerMeleeRangeChargeStanding; - float playerMeleeRangeChargeCrouched; - float playerMeleeChargeHeightTolerance; - bool shieldAllowFiring; - int shieldMaxSpeed; - bool shieldAlwaysDisplay; - Gesture* shieldDeployGesture; - Gesture* shieldFireWeapGesture; - Gesture* shieldDeployWhileFiring; - Gesture* shieldRetractWhileFiring; - Gesture* shieldBashGesture; - FxCombinedDef shieldMeleeFx; - float shieldMeleeFxDelay; - float HitEarthquakeScale; - float HitEarthquakeDuration; - float HitEarthquakeRadius; - RumbleInfo* shieldHitRumble; - float MissEarthquakeScale; - float MissEarthquakeDuration; - float MissEarthquakeRadius; - RumbleInfo* shieldMissRumble; - int shieldDeployButton; - bool shieldUsesEnergy; - float shieldMaxEnergy; - float shieldConsumptionRate; - float shieldMeleeEnergyCost; - float shieldMeleeHitEnergyCost; - float reactiveMotionRadiusScale; - float reactiveMotionFrequencyScale; - float reactiveMotionAmplitudeScale; - float reactiveMotionFalloff; - float reactiveMotionLifetime; - unsigned __int8 transientBaseViewFlags; - unsigned __int8 transientBaseWorldFlags; - bool hasAnyTransientModels; - bool blendFireAnimations; - bool sharedAmmo; - bool lockonSupported; - bool requireLockonToFire; - bool isAirburstWeapon; - bool bigExplosion; - bool noAdsWhenMagEmpty; - bool avoidDropCleanup; - bool allowGrenadeSwitching; - bool inheritsPerks; - bool forceUse; - bool ladderWeapon; - bool executionVictimHiddenWeapon; - bool crosshairColorChange; - bool bRifleBullet; - bool bEnergyBullet; - bool bIncendiaryBullet; - bool armorPiercing; - bool impaling; - bool bBoltAction; - bool aimDownSight; - bool canHoldBreath; - bool meleeOnly; - bool supportsAlternateMelee; - bool bRechamberWhileAds; - bool reloadWhileAds; - bool bBulletExplosiveDamage; - bool bCookOffHold; - bool overCookIsNotLethal; - bool reticleSpin45; - bool bClipOnly; - bool bDoesNotConsumeAmmo; - bool bRemoveWeaponOnEmpty; - bool noAmmoPickup; - bool adsFireOnly; - bool cancelAutoHolsterWhenEmpty; - bool disableSwitchToWhenEmpty; - bool suppressAmmoPrimaryDisplay; - bool suppressAmmoReserveDisplay; - LaserSettings laserSettings; - bool markableViewmodel; - bool isPredictedProjectile; - int clientTrajectoryBlendOutTime; - int serverTrajectoryBlendInTime; - int dualWieldType; - bool flipKillIcon; - bool bNoPartialReload; - bool reloadDisabled; - bool blocksProne; - bool silenced; - bool doNotSuppressAI; - bool isRollingGrenade; - bool dropGrenadeHeldOnDeath; - bool projExplosionEffectForceNormalUp; - bool projExplosionEffectInheritParentDirection; - bool bProjImpactExplode; - bool spawnProjAtMuzzle; - bool correctBulletTrajectory; - float maxCorrectionAngle; - bool disableProjectileCrumpleCheck; - bool bProjTrajectoryEvents; - bool bProjWhizByEnabled; - bool stickToPlayers; - bool stickToVehicles; - bool stickToTurrets; - bool stickToNonStick; - bool projEnableMissileStickiness; - bool enableMissileRicochet; - bool thrownSideways; - bool disableFiring; - bool firesOnWeaponSwitch; - bool disableHolding; - bool timedDetonation; - float missileRicochetMinAngleOfIncidence; - float missileCrumpleMinSpeed; - int detonateType; - XModel* detonatorWorldModel; - int explosiveDamageDelay; - int fuseTime; - int aiFuseTime; - int maxHoldTime; - GrenadeRotationParams rotationParams; - bool holdButtonToThrow; - bool autoHold; - bool infiniteHold; - bool freezeMovementWhenFiring; - bool offhandAllowsSprint; - bool thermalScope; - bool thermalToggle; - bool outlineEnemies; - bool outlineDepthTest; - bool outlineFill; - float enemyOutlineR; - float enemyOutlineG; - float enemyOutlineB; - float enemyOutlineA; - float allyOutlineR; - float allyOutlineG; - float allyOutlineB; - float allyOutlineA; - bool depthScan; - float depthScanThickness; - float depthScanR; - float depthScanG; - float depthScanB; - float depthScanA; - float depthScanOutlineThickness; - float depthScanOutlineR; - float depthScanOutlineG; - float depthScanOutlineB; - float depthScanOutlineA; - bool depthScanOverlay; - float depthScanOverlayStrength; - float depthScanOverlayXTiles; - float depthScanOverlayYTiles; - float depthScanOverlayXScroll; - float depthScanOverlayYScroll; - float blurSceneAdsInFraction; - float blurSceneAdsOutFraction; - bool altModeSameWeapon; - bool playAltGesturesForOffhandWeapons; - bool turretBarrelSpinEnabled; - bool missileConeSoundEnabled; - bool missileConeSoundPitchshiftEnabled; - bool missileConeSoundCrossfadeEnabled; - bool offhandHoldIsCancelable; - bool doNotAllowAttachmentsToOverrideSpread; - bool useScopeDrift; - bool alwaysShatterGlassOnImpact; - bool jumpSpread; - bool noFullViewmodelAnimations; - float killcamOffset; - bool useDualFOV; - bool showViewModelInDualFOV; - bool syncedFOVInDualFOV; - bool disableDrop; - bool preferredDrop; - Gesture* gestureAnimation; - float gestureFireStateTime; - Gesture* gesturePullback; - Gesture* gesturePullbackAlt; - float minPullbackTime; - float minPullbackToThrowBlendTime; - float maxPullbackToThrowBlendTime; - Gesture* gestureThrow; - Gesture* gestureThrowAlt; - float gestureFireTime; - Gesture* gestureDetonate; - Gesture* gestureDetonateAlt; - float gestureDetonationTime; - bool gesturesDisablePrimary; - FxCombinedDef cameraFireEffect; - float cameraFireEffectDurationSec; - float changedFireTime; - float changedFireTimeAkimbo; - int changedFireTimeNumBullets; - int chargeType; - float chargeGain; - float chargeCostPerShot; - float chargeLossWhenIdle; - float chargeEmptyCooldown; - float chargeFireAtMaxDamageMultiplier; - int chargeMeterEffectBoneCount; - FxCombinedDef chargeMeterEffect; - SndAliasLookup chargeUpSound; - SndAliasLookup chargeDownSound; - SndAliasLookup chargeUpSoundPlayer; - SndAliasLookup chargeDownSoundPlayer; - SndAliasLookup chargeDownToUpSound; - SndAliasLookup chargeDownToUpSoundPlayer; - SndAliasLookup chargeUpToDownSound; - SndAliasLookup chargeUpToDownSoundPlayer; - SndAliasLookup chargeMaxSound; - SndAliasLookup chargeMaxSoundPlayer; - bool chargeHudReveal; - RumbleInfo* chargeRumble; - scr_string_t stowTag; - XModel* stowOffsetModel; - scr_string_t stowOffsetAttachTag; - int slot; - float maxTargetAngle; - bool spaceshipSecondaryWeapon; - float impulseFieldRadius; - float impulseFieldInitialSpeed; - float impulseFieldMaxSpeed; - float impulseFieldAcceleration; - float impulseFieldInAirImpulseMultiplier; - float impulseFieldInAirImpulseMultiplierInterpTime; - float impulseFieldSlideMultiplier; - float impulseFieldSlideMultiplierInterpTime; - bool impulseFieldIsPush; - bool impulseFieldAffectsFriendlies; - bool impulseFieldAffectsSelf; - bool impulseFieldAffectsProne; - bool regenerationEnabled; - int regenerationTimeMs; - int regenerationAddTimeMs; - int regenerationAmount; - bool regenerationConsumeStock; - bool regenerationDisableWhileFiring; - int deployType; - bool deployRequireOnWalkableSurface; - bool deployRequireOnNavmesh; - bool deployRequireSkyAbove; - bool deployRequireNoOverhang; - bool deployAlwaysUpright; - bool deployEdgeSnap; - float deployCylinderRadius; - float deployCylinderHeight; - float deployMaxDistance; - float deployMaxHeightAboveEye; - float deployEffectHeightOffset; - float deployMaxSlope; - FxCombinedDef deployEffect; - int deployValidGroupId; - int deployIndoorGroupId; - int deployInvalidGroupId; - int deployOutOfRangeGroupId; - int numAnimOverrides; - AnimOverride* animOverrides; - CarryAnimOverride carryAnimOverrides[5]; - int numSfxOverrides; - SFXOverride* sfxOverrides; - int numVfxOverrides; - VFXOverride* vfxOverrides; - float reactiveEmitterDelay; - float grenadeDangerIconDistance; - float bulletDirGunAngleModifierIdleHip; - float bulletDirGunAngleModifierIdleAds; - float bulletDirGunAngleModifierGunKickHip; - float bulletDirGunAngleModifierGunKickAds; - float bulletDirGunAngleModifierGunTiltHip; - float bulletDirGunAngleModifierGunTiltAds; - float viewClampPitchCatchUpTimeSec; - float viewClampYawCatchUpTimeSec; - bool mountTopEnable; - bool mountTopYawClamp; - float mountTopYawMax; - float mountTopGunKickScale; - float mountTopGunCenterScale; - float mountTopViewKickScale; - float mountTopViewCenterScale; - float mountTopGunIdleMotionScale; - float mountTopViewIdleMotionScale; - int mountTopEnterDurationMs; - int mountTopExitDurationMs; - float mountTopEdgeToEyeDistanceForward; - float mountTopEdgeToEyeDistanceAbove; - bool mountSideEnable; - bool mountSideTransitionEnable; - float mountSideRoll; - float mountSideRollStartFrac; - float mountSideRollEndFrac; - float mountSideGunKickScale; - float mountSideGunCenterScale; - float mountSideViewKickScale; - float mountSideViewCenterScale; - float mountSideGunIdleMotionScale; - float mountSideViewIdleMotionScale; - int mountSideEnterDurationMs; - int mountSideExitDurationMs; - float mountSideEdgeToEyeDistanceForward; - float mountSideEdgeToEyeDistanceAbove; - float mountViewmodelOffset; - float mountFOVScale; - RumbleInfo* mountRumble; - WeaponOffsetPatternScaleInfo mountWeaponOffsetPatternScaleInfo; - float adsFireMotionBlur; - int adsFireMotionBlurDurationMs; - float adsFireMotionBlurDecayExponent; - float hipFireMotionBlur; - int hipFireMotionBlurDurationMs; - float hipFireMotionBlurDecayExponent; - float adsCameraShakeRotationScale; - float adsCameraShakeTranslationScale; - AdvancedIdleSettings advancedIdleSettings; - WeaponOffsetPatternScaleInfo crouchedWeaponOffsetPatternScaleInfo; - WeaponOffsetPatternScaleInfo proneWeaponOffsetPatternScaleInfo; - BallisticInfo ballisticInfo; - WeaponEntityNotify* notifyTypes[2]; - float dlcFloat[6]; - bool dlcBool[3]; - bool enableWeaponInspect; - bool stowedOcclusionTestEnabled; - bool ignoreMinTracerSpawnDistance; - bool tracerOverrideEnabled; - bool boltActionReloadIncludesRechamber; -}; - - -struct WeaponCompleteDef -{ - const char* szInternalName; - WeaponDef weapDef; - const char* szDisplayName; - const char* szLootTable; - scr_string_t* hideTags; - AttachmentList attachments[14]; - unsigned int numLootVariants; - unsigned int numNotetrackSoundMappings; - scr_string_t* notetrackSoundMapKeys; - scr_string_t* notetrackSoundMapValues; - unsigned int numNotetrackOverrides; - void* /*NoteTrackToSoundEntry*/ notetrackOverrides; - unsigned int numNotetrackSuitEntries; - void* /*NoteTrackToSuitSoundEntry*/ notetrackSuitEntries; - ZoomSettings zoomSettings; - int iAdsTransInTime; - int iAdsTransOutTime; - int iAdsTransInToOutTime; - int iAdsTransOutToInTime; - int iClipSize; - int vfxImpactType; - float penetrateMultiplier; - float fAdsViewKickCenterSpeed; - float fHipViewKickCenterSpeed; - Material* killIconMat; - Material* dpadIconMat; - Material* dpadIconInactiveMat; - GfxImage* killIconImg; - GfxImage* dpadIconImg; - GfxImage* dpadIconInactiveImg; - int ammoDropStockMax; - bool useSceneDof; - float adsDofPhysicalFstop; - float adsDofPhysicalFocusDistance; - bool adsDofPhysicalFocalTag; - float adsDofPhysicalReloadFstop; - float adsDofPhysicalReloadFocusDistance; - unsigned __int16 accuracyGraphKnotCount[2]; - vec2_t* accuracyGraphKnots[2]; - bool enhanced; - bool dpadIconShowsAmmo; - bool luiWeaponInfoWidgetUsesScopeStencil; - const char* szAltModeInactiveName; - const char* dynamicIconAnimationName; - bool isUsingDynamicIcon; - const char* szLUIWeaponInfoWidgetName; - const char* szLUIWeaponInfoWidgetTag; - const char* szLUICrosshairWidget; -}; - -union XAssetHeader -{ - //PhysicsLibrary* physicsLibrary; - //PhysicsSFXEventAsset* physicsSFXEventAsset; - //PhysicsVFXEventAsset* physicsVFXEventAsset; - PhysicsAsset* physicsAsset; - //PhysicsFXPipeline* physicsFXPipeline; - //PhysicsFXShape* physicsFXShape; - //PhysicsDebugData* physicsDebugData; - //XAnimParts* parts; - //XModelSurfs* modelSurfs; - XModel* model; - //MayhemData* mayhem; - Material* material; - //ComputeShader* computeShader; - //MaterialSerializedShader* serializedShader; - //MaterialTechniqueSet* techniqueSet; - GfxImage* image; - //SndGlobals* soundGlobals; - //SndBankResident* soundBankResident; - //SndBankTransient* soundBankTransient; - clipMap_t* clipMap; - //ComWorld* comWorld; - //GlassWorld* glassWorld; - //PathData* pathData; - //NavMeshData* navMeshData; - //TacticalGraphData* tacGraphData; - MapEnts* mapEnts; - //FxWorld* fxWorld; - //GfxWorld* gfxWorld; - //GfxWorldTransientZone* gfxWorldTransientZone; - //GfxIESProfile* iesProfile; - //GfxLightDef* lightDef; - //GfxGradingClut* gradingClut; - //GfxFogSpline* fogSpline; - //AnimationClass* animClass; - //PlayerAnimScript* playerAnim; - Gesture* gesture; - LocalizeEntry* localize; - //WeaponAttachment* attachment; - WeaponCompleteDef* weapon; - //ParticleSystemDef* vfx; - //FxImpactTable* impactFx; - SurfaceFxTable* surfaceFx; - RawFile* rawfile; - ScriptFile* scriptfile; - ScriptDebugData* scriptDebugData; - StringTable* stringTable; - LeaderboardDef* leaderboardDef; - VirtualLeaderboardDef* virtualLeaderboardDef; - DDLFile* ddlFile; - TracerDef* tracerDef; - VehicleDef* vehDef; - AddonMapEnts* addonMapEnts; - NetConstStrings* netConstStrings; - LuaFile* luaFile; - ScriptableDef* scriptable; - EquipmentSoundTable* equipSndTable; - VectorField* vectorField; - FxParticleSimAnimation* particleSimAnimation; - StreamingInfo* streamingInfo; - LaserDef* laserDef; - TTFDef* ttfDef; - SuitDef* suitDef; - SuitAnimPackage* suitAnimPackage; - CameraDef* cameraDef; - HudOutlineDef* hudOutlineDef; - SpaceshipTargetDef* spaceshipTargetDef; - RumbleInfo* rumble; - RumbleGraph* rumbleGraph; - //WeaponAnimPackage* weaponAnimPackage; - //WeaponSFXPackage* weaponSFXPackage; - //WeaponVFXPackage* weaponVFXPackage; - //FootstepVFX* footstepVFX; - //BehaviorTree* behaviorTree; - //Animset* animset; - //ASM* asmAsset; - //XAnimProceduralBones* proceduralBones; - //XAnimDynamicBones* dynamicBones; - //ReticleDef* reticleDef; - //XAnimCurve* xanimCurve; - //CoverSelector* coverSelector; - //EnemySelector* enemySelector; - //ClientCharacter* clientCharacter; - //ClothAsset* clothAsset; - //CinematicMotionDef* cinematicMotion; - //AccessoryDef* accessory; - //LocDmgTable* locDmgTable; - //BulletPenetration* bulletPenetration; - //ScriptBundle* scriptBundle; - //BlendSpace2DDef* blendSpace2DDef; - //XCam* xcam; - //Camo* camo; - //XCompositeModelDef* compositeModel; - //XModelDetailCollision* modelDetailCollision; - //StreamKey* streamKey; - //StreamTreeOverride* streamTreeOverride; - //KeyValuePairs* keyValuePairs; - //StTerrain* stTerrain; - //NativeScriptPatchFile* nativeScriptPatch; - //CollisionTile* collisionTile; - //ExecutionDef* executionDef; - //CarryObjectDef* carryObjectDef; - //SoundBankListDef* soundBankListDef; - //GfxDecalVolumeMaterial* decalVolumeMaterial; - //GfxDecalVolumeMask* decalVolumeMask; - //DynEntityList* dynEntityList; - void* data; - //FxWorldTransientZone* fxWorldTransientZone; - //DLogSchema* dlogSchema; - //MapEdgeList* mapEdgeList; -}; - -enum XAssetType -{ - ASSET_TYPE_PHYSICSLIBRARY = 0x0, - ASSET_TYPE_PHYSICSSFXEVENTASSET = 0x1, - ASSET_TYPE_PHYSICSVFXEVENTASSET = 0x2, - ASSET_TYPE_PHYSICSASSET = 0x3, - ASSET_TYPE_PHYSICSFXPIPELINE = 0x4, - ASSET_TYPE_PHYSICSFXSHAPE = 0x5, - ASSET_TYPE_PHYSICSDEBUGDATA = 0x6, - ASSET_TYPE_XANIM = 0x7, - ASSET_TYPE_XMODELSURFS = 0x8, - ASSET_TYPE_XMODEL = 0x9, - ASSET_TYPE_MAYHEM = 0xA, - ASSET_TYPE_MATERIAL = 0xB, - ASSET_TYPE_COMPUTESHADER = 0xC, - ASSET_TYPE_LIBSHADER = 0xD, - ASSET_TYPE_VERTEXSHADER = 0xE, - ASSET_TYPE_HULLSHADER = 0xF, - ASSET_TYPE_DOMAINSHADER = 0x10, - ASSET_TYPE_PIXELSHADER = 0x11, - ASSET_TYPE_TECHSET = 0x12, - ASSET_TYPE_IMAGE = 0x13, - ASSET_TYPE_SOUNDGLOBALS = 0x14, - ASSET_TYPE_SOUNDBANK = 0x15, - ASSET_TYPE_SOUNDBANKTRANSIENT = 0x16, - ASSET_TYPE_COL_MAP = 0x17, - ASSET_TYPE_COM_MAP = 0x18, - ASSET_TYPE_GLASS_MAP = 0x19, - ASSET_TYPE_AIPATHS = 0x1A, - ASSET_TYPE_NAVMESH = 0x1B, - ASSET_TYPE_TACGRAPH = 0x1C, - ASSET_TYPE_MAP_ENTS = 0x1D, - ASSET_TYPE_FX_MAP = 0x1E, - ASSET_TYPE_GFX_MAP = 0x1F, - ASSET_TYPE_GFX_MAP_TRZONE = 0x20, - ASSET_TYPE_IESPROFILE = 0x21, - ASSET_TYPE_LIGHTDEF = 0x22, - ASSET_TYPE_GRADINGCLUT = 0x23, - ASSET_TYPE_UI_MAP = 0x24, - ASSET_TYPE_FOGSPLINE = 0x25, - ASSET_TYPE_ANIMCLASS = 0x26, - ASSET_TYPE_PLAYERANIM = 0x27, - ASSET_TYPE_GESTURE = 0x28, - ASSET_TYPE_LOCALIZE = 0x29, - ASSET_TYPE_ATTACHMENT = 0x2A, - ASSET_TYPE_WEAPON = 0x2B, - ASSET_TYPE_VFX = 0x2C, - ASSET_TYPE_IMPACTFX = 0x2D, - ASSET_TYPE_SURFACEFX = 0x2E, - ASSET_TYPE_AITYPE = 0x2F, - ASSET_TYPE_MPTYPE = 0x30, - ASSET_TYPE_CHARACTER = 0x31, - ASSET_TYPE_XMODELALIAS = 0x32, - ASSET_TYPE_RAWFILE = 0x33, - ASSET_TYPE_SCRIPTFILE = 0x34, - ASSET_TYPE_SCRIPTDEBUGDATA = 0x35, - ASSET_TYPE_STRINGTABLE = 0x36, - ASSET_TYPE_LEADERBOARDDEF = 0x37, - ASSET_TYPE_VIRTUALLEADERBOARDDEF = 0x38, - ASSET_TYPE_DDL = 0x39, - ASSET_TYPE_TRACER = 0x3A, - ASSET_TYPE_VEHICLE = 0x3B, - ASSET_TYPE_ADDON_MAP_ENTS = 0x3C, - ASSET_TYPE_NETCONSTSTRINGS = 0x3D, - ASSET_TYPE_LUAFILE = 0x3E, - ASSET_TYPE_SCRIPTABLE = 0x3F, - ASSET_TYPE_EQUIPSNDTABLE = 0x40, - ASSET_TYPE_VECTORFIELD = 0x41, - ASSET_TYPE_PARTICLESIMANIMATION = 0x42, - ASSET_TYPE_STREAMINGINFO = 0x43, - ASSET_TYPE_LASER = 0x44, - ASSET_TYPE_TTF = 0x45, - ASSET_TYPE_SUIT = 0x46, - ASSET_TYPE_SUITANIMPACKAGE = 0x47, - ASSET_TYPE_CAMERA = 0x48, - ASSET_TYPE_HUDOUTLINE = 0x49, - ASSET_TYPE_SPACESHIPTARGET = 0x4A, - ASSET_TYPE_RUMBLE = 0x4B, - ASSET_TYPE_RUMBLEGRAPH = 0x4C, - ASSET_TYPE_ANIMPKG = 0x4D, - ASSET_TYPE_SFXPKG = 0x4E, - ASSET_TYPE_VFXPKG = 0x4F, - ASSET_TYPE_FOOTSTEPVFX = 0x50, - ASSET_TYPE_BEHAVIORTREE = 0x51, - ASSET_TYPE_AIANIMSET = 0x52, - ASSET_TYPE_AIASM = 0x53, - ASSET_TYPE_PROCEDURALBONES = 0x54, - ASSET_TYPE_DYNAMICBONES = 0x55, - ASSET_TYPE_RETICLE = 0x56, - ASSET_TYPE_XANIMCURVE = 0x57, - ASSET_TYPE_COVERSELECTOR = 0x58, - ASSET_TYPE_ENEMYSELECTOR = 0x59, - ASSET_TYPE_CLIENTCHARACTER = 0x5A, - ASSET_TYPE_CLOTHASSET = 0x5B, - ASSET_TYPE_CINEMATICMOTION = 0x5C, - ASSET_TYPE_ACCESSORY = 0x5D, - ASSET_TYPE_LOCDMGTABLE = 0x5E, - ASSET_TYPE_BULLETPENETRATION = 0x5F, - ASSET_TYPE_SCRIPTBUNDLE = 0x60, - ASSET_TYPE_BLENDSPACE2D = 0x61, - ASSET_TYPE_XCAM = 0x62, - ASSET_TYPE_CAMO = 0x63, - ASSET_TYPE_XCOMPOSITEMODEL = 0x64, - ASSET_TYPE_XMODELDETAILCOLLISION = 0x65, - ASSET_TYPE_STREAMKEY = 0x66, - ASSET_TYPE_STREAMTREEOVERRIDE = 0x67, - ASSET_TYPE_KEYVALUEPAIRS = 0x68, - ASSET_TYPE_STTERRAIN = 0x69, - ASSET_TYPE_NATIVESCRIPTPATCH = 0x6A, - ASSET_TYPE_COLLISIONTILE = 0x6B, - ASSET_TYPE_EXECUTION = 0x6C, - ASSET_TYPE_CARRYOBJECT = 0x6D, - ASSET_TYPE_SOUNDBANKLIST = 0x6E, - ASSET_TYPE_DECALVOLUMEMATERIAL = 0x6F, - ASSET_TYPE_DECALVOLUMEMASK = 0x70, - ASSET_TYPE_DYNENTITYLIST = 0x71, - ASSET_TYPE_FX_MAP_TRZONE = 0x72, - ASSET_TYPE_DLOGSCHEMA = 0x73, - ASSET_TYPE_EDGELIST = 0x74, -}; - -struct XAsset -{ - XAssetType type; - XAssetHeader header; -}; - -struct ScriptStringList -{ - int count; - bool loaded; - const char** strings; -}; - -struct XAssetList -{ - ScriptStringList stringList; - unsigned int assetCount; - unsigned int assetReadPos; - XAsset* assets; -}; - +#pragma once +#include "Main.hpp" + +struct RumbleGraph; +struct RumbleInfo; +struct CameraDef; +struct GfxImage; +struct Material; +struct Bounds; +struct FxCombinedDef; + +struct vec2_t +{ + float v[2]; +}; + +struct vec3_t +{ + float v[3]; +}; + +struct vec4_t +{ + float v[4]; +}; + +typedef int scr_string_t; + +struct Bounds +{ + vec3_t midPoint; + vec3_t halfSize; +}; + +struct GfxDrawSurfFields +{ + unsigned __int64 indirectArgsOffset : 10; + unsigned __int64 gpBatchIndex : 16; + unsigned __int64 objectId : 24; + unsigned __int64 hasGfxEntIndex : 1; + unsigned __int64 lightmapIndex : 9; + unsigned __int64 shadowcaster : 1; + unsigned __int64 materialSortedIndex : 16; + unsigned __int64 tessellation : 3; + unsigned __int64 prepass : 2; + unsigned __int64 viewModelRender : 1; + unsigned __int64 lowResShading : 1; + unsigned __int64 surfType : 4; + unsigned __int64 primarySortKey : 6; +}; + +struct EffectDefMap { + char name[64]; + char filename[256]; +}; + +struct Packed128 +{ + unsigned __int64 p0; + unsigned __int64 p1; +}; + +union GfxDrawSurf +{ + GfxDrawSurfFields fields; + Packed128 packed; +}; + +struct MaterialTextureDef +{ + unsigned __int8 index; + GfxImage* image; +}; + +struct MaterialConstantDef +{ + unsigned __int8 index; + vec4_t literal; +}; + +struct GfxDecalVolumeMaterial +{ + const char* name; + GfxImage* channels[6]; + unsigned int flags; + vec3_t colorTint; + float alphaDissolveParms; + float emissiveScale; + unsigned int packedDisplacementScaleAndBias; + float displacementCutoffDistance; + float displacementCutoffFalloff; + unsigned int packedTemperatureBaseAndScale; + unsigned __int8 textureAtlasRowCount; + unsigned __int8 textureAtlasColumnCount; + unsigned __int8 padding[6]; +}; + +struct PhysicsAssetUsageCounter +{ + int serverEnt; + int clientEnt; + int dynEnt; +}; + +struct __declspec(align(4)) PhysicsAsset +{ + const char* name; + char* havokData; + unsigned int havokDataSize; + int useCategory; + int numRigidBodies; + int numConstraints; + uintptr_t simulationCategories; + unsigned int* bodyContents; + int numSFXEventAssets; + int numVFXEventAssets; + uintptr_t sfxEventAssets; + uintptr_t vfxEventAssets; + PhysicsAssetUsageCounter usageCounter; + bool containsDynamicBodies; +}; + +struct Material +{ + const char* name; + unsigned int contents; + unsigned int surfaceFlags; + float maxDisplacement; + int /*MaterialGeometryType*/ materialType; + unsigned __int8 cameraRegion; + unsigned __int8 sortKey; + unsigned __int16 flags; + unsigned __int8 textureCount; + unsigned __int8 constantCount; + unsigned __int8 constantBufferCount; + unsigned __int8 layerCount; + unsigned __int16 packedAtlasDataSize; + unsigned __int8 textureAtlasRowCount; + unsigned __int8 textureAtlasColumnCount; + GfxDrawSurf drawSurf; + unsigned __int8* packedAtlasData; + void* /*MaterialTechniqueSet*/ techniqueSet; + MaterialTextureDef* textureTable; + MaterialConstantDef* constantTable; + GfxDecalVolumeMaterial* decalVolumeMaterial; + unsigned __int8* constantBufferIndex; + void* /*MaterialConstantBufferDef*/ constantBufferTable; + const char** subMaterials; +}; + +enum GfxTextureId : __int32 +{ + NULLID = 0x0, +}; + +enum GfxPixelFormat : __int32 +{ + GFX_PF_INVALID = 0x0, + GFX_PF_R8 = 0x1, + GFX_PF_A8 = 0x2, + GFX_PF_L8 = 0x3, + GFX_PF_R8G8 = 0x4, + GFX_PF_L8A8 = 0x5, + GFX_PF_R8G8B8A8 = 0x6, + GFX_PF_R8G8B8A8_SRGB = 0x7, + GFX_PF_R8_SNORM = 0x8, + GFX_PF_R8G8_SNORM = 0x9, + GFX_PF_R16 = 0xA, + GFX_PF_R16G16 = 0xB, + GFX_PF_R16G16B16A16 = 0xC, + GFX_PF_R16_SNORM = 0xD, + GFX_PF_R16F = 0xE, + GFX_PF_R16G16F = 0xF, + GFX_PF_R16G16B16A16F = 0x10, + GFX_PF_R32F = 0x11, + GFX_PF_R32G32F = 0x12, + GFX_PF_R32G32B32A32F = 0x13, + GFX_PF_D16 = 0x14, + GFX_PF_D32F = 0x15, + GFX_PF_D32F_S8 = 0x16, + GFX_PF_R8_UINT = 0x17, + GFX_PF_R16_UINT = 0x18, + GFX_PF_R32_UINT = 0x19, + GFX_PF_R32G32_UINT = 0x1A, + GFX_PF_R32G32B32A32_UINT = 0x1B, + GFX_PF_R10G10B10A2_UINT = 0x1C, + GFX_PF_R5G6B5 = 0x1D, + GFX_PF_R10G10B10A2 = 0x1E, + GFX_PF_R9G9B9E5_SHAREDEXP = 0x1F, + GFX_PF_R11G11B10F = 0x20, + GFX_PF_BC1 = 0x21, + GFX_PF_BC1_SRGB = 0x22, + GFX_PF_BC2 = 0x23, + GFX_PF_BC2_SRGB = 0x24, + GFX_PF_BC3 = 0x25, + GFX_PF_BC3_SRGB = 0x26, + GFX_PF_BC4 = 0x27, + GFX_PF_BC5 = 0x28, + GFX_PF_BC5S = 0x29, + GFX_PF_BC6H = 0x2A, + GFX_PF_BC6HS = 0x2B, + GFX_PF_BC7 = 0x2C, + GFX_PF_BC7_SRGB = 0x2D, + GFX_PF_R8G8B8A8_SNORM = 0x2E, + GFX_PF_R1 = 0x2F, + GFX_PF_R4G4 = 0x30, + GFX_PF_R10G10B10A2_SNORM = 0x31, + GFX_PF_COUNT = 0x32, +}; + +enum GfxImageFlags +{ + IMG_FLAG_NONE = 0x0, + IMG_DISK_FLAG_NOPICMIP = 0x1, + IMG_DISK_FLAG_NOMIPMAPS = 0x2, + IMG_DISK_FLAG_UNUSED = 0x4, + IMG_DISK_FLAG_NORMAL_OCCLUSON_GLOSS = 0x8, + IMG_DISK_FLAG_CLAMP_U = 0x10, + IMG_DISK_FLAG_CLAMP_V = 0x20, + IMG_DISK_FLAG_STREAMED = 0x40, + IMG_DISK_FLAG_USE_OODLE_COMPRESSION = 0x80, + IMG_DISK_FLAG_GAMMA_SRGB = 0x100, + IMG_DISK_FLAG_PACKED_ATLAS = 0x200, + IMG_CREATE_FLAG_UNTILED = 0x400, + IMG_CREATE_FLAG_CPU_READ = 0x800, + IMG_CREATE_FLAG_CPU_WRITE = 0x1000, + IMG_DISK_FLAG_AUTOMETALNESS = 0x2000, + IMG_DISK_FLAG_AUTODISPLACEMENT = 0x4000, + IMG_DISK_FLAG_MAPTYPE_2D = 0x0, + IMG_DISK_FLAG_MAPTYPE_CUBE = 0x8000, + IMG_DISK_FLAG_MAPTYPE_3D = 0x10000, + IMG_DISK_FLAG_MAPTYPE_1D = 0x18000, + IMG_DISK_FLAG_MAPTYPE_ARRAY = 0x20000, + IMG_DISK_FLAG_MAPTYPE_CUBE_ARRAY = 0x28000, + IMG_DISK_FLAG_INVERT_ALPHA = 0x40000, + IMG_DISK_FLAG_PREMUL_ALPHA = 0x80000, + IMG_DISK_FLAG_MIPGEN_ORIGINAL = 0x0, + IMG_DISK_FLAG_MIPGEN_LANCZOS3 = 0x100000, + IMG_DISK_FLAG_MIPGEN_CATMULL_ROM = 0x200000, + IMG_DISK_FLAG_MIPGEN_CUBIC_BSPLINE = 0x300000, + IMG_DISK_FLAG_MIPGEN_BOX = 0x400000, + IMG_DISK_FLAG_MIPGEN_COVERAGE_PRESERVING = 0x500000, + IMG_CREATE_FLAG_RW_VIEW = 0x800000, + IMG_CREATE_FLAG_DYNAMIC = 0x1000000, + IMG_DISK_FLAG_PREMUL_KEEP_ALPHA = 0x2000000, + IMG_DISK_FLAG_RTT = 0x4000000, + IMG_DISK_FLAG_EXTRACT_ALPHA = 0x8000000, + IMG_DISK_FLAG_OCTAHEDRON = 0x10000000, + IMG_CREATE_FLAG_STAGING = 0x20000000, + IMG_CREATE_FLAG_VOLUMETRIC_LAYOUT_OVERRIDE = 0x40000000, + IMG_CREATE_FLAG_TYPELESS = 0x80000000, +}; + +union GfxImageSemanticSpecific +{ + float atlasFps; + unsigned int albedoMapScaleBias; + unsigned int normalMapScaleBias; + unsigned int maxMipMap; +}; + +struct GfxImageAtlasSize +{ + unsigned __int8 rowCount; + unsigned __int8 colCount; +}; + +union GfxImageAtlasInfo +{ + GfxImageAtlasSize atlasSize; + unsigned __int16 packedAtlasDataSize; +}; + +enum TextureSemantic : __int8 +{ + TS_2D = 0x0, + TS_FUNCTION = 0x1, + TS_COLOR_MAP = 0x2, + TS_GRAY_MAP = 0x3, + TS_SIGNED_VELOCITY_MAP = 0x4, + TS_NORMAL_MAP = 0x5, + TS_METALNESS_MAP = 0x6, + TS_NORMAL_OCCLUSION_GLOSS_MAP = 0x7, + TS_SIGNED_DISTANCE_FIELD = 0x8, + TS_CARD_IMPOSTER_NORMAL = 0x9, + TS_COUNT = 0xA, +}; + +enum GfxImageCategory : __int8 +{ + IMG_CATEGORY_UNKNOWN = 0x0, + IMG_CATEGORY_AUTO_GENERATED = 0x1, + IMG_CATEGORY_LIGHTMAP = 0x2, + IMG_CATEGORY_LOAD_FROM_FILE = 0x3, + IMG_CATEGORY_RAW = 0x4, + IMG_CATEGORY_FIRST_UNMANAGED = 0x5, + IMG_CATEGORY_RENDERTARGET = 0x5, + IMG_CATEGORY_TEMP = 0x6, +}; + +struct XPakEntryInfo +{ + unsigned __int64 key; + __int64 offset; + unsigned __int64 size; + unsigned __int64 xpakIndex : 8; + unsigned __int64 compressed : 1; + unsigned __int64 valid : 1; + unsigned __int64 adjacentLeftType : 3; + unsigned __int64 adjacentRightType : 3; + unsigned __int64 adjacentLeft : 19; + unsigned __int64 adjacentRight : 19; + unsigned __int64 padding : 10; +}; + +enum GfxImageStreamLevelCountAndSize : __int32 +{ +}; + +struct GfxImageStreamData +{ + XPakEntryInfo xpakEntry; + GfxImageStreamLevelCountAndSize levelCountAndSize; + unsigned __int16 width; + unsigned __int16 height; +}; + +struct streamer_handle_t +{ + unsigned __int64 data; +}; + +struct GfxImageFallback +{ + unsigned __int8* pixels; + unsigned int size; + unsigned __int16 width; + unsigned __int16 height; +}; + +union GfxImagePixels +{ + streamer_handle_t streamedDataHandle; + unsigned __int8* residentData; +}; + + +struct GfxImage +{ + const char* name; + unsigned __int8* packedAtlasData; + GfxTextureId textureId; + GfxPixelFormat format; + GfxImageFlags flags; + unsigned int totalSize; + GfxImageSemanticSpecific semanticSpecific; + unsigned __int16 width; + unsigned __int16 height; + unsigned __int16 depth; + unsigned __int16 numElements; + GfxImageAtlasInfo atlasInfo; + TextureSemantic semantic; + GfxImageCategory category; + unsigned __int8 levelCount; + unsigned __int8 streamedPartCount; + unsigned __int8 decalAtlasIndex; + char freqDomainMetricBias; + GfxImageStreamData streams[4]; + GfxImageFallback* fallback; + GfxImagePixels pixels; +}; + +struct AttachmentList +{ + unsigned int attachmentCount; + void** /*WeaponAttachment*/ attachments; +}; + +struct __declspec(align(4)) SceneZoomSettings +{ + int adsZoomCount; + float adsZoomFov[3]; + float adsReloadFov[3]; + int adsZoomFovTransitionTime[3]; + int /*AdsOffsetInterpolationType*/ adsZoomFovLerpType; + float adsZoomInFrac; + float adsZoomOutFrac; + float adsFOVNVG; + float adsReloadFovNVG; + bool adsZoomLevelIndexResetOnToggle; +}; + +struct __declspec(align(4)) WeaponZoomSettings +{ + float adsZoomFov; + int /*AdsOffsetInterpolationType*/ adsZoomFovLerpType; + float adsZoomFovXOffset; + float adsReloadZoomFov; + float adsReloadZoomFovXOffset; + float adsNVGZoomFov; + float adsNVGZoomFovXOffset; + float adsNVGReloadZoomFov; + float adsNVGReloadZoomFovXOffset; + float adsZoomInFrac; + float adsZoomOutFrac; + bool adsZoomFovXOffsetOverride; + bool adsReloadFovXOffsetOverride; +}; + +struct ZoomSettings +{ + SceneZoomSettings scene; + WeaponZoomSettings weapon; +}; + + +struct WeaponEntityNotify +{ + int flags; + float radius; + float height; + float minSpeed; +}; + + + +struct XModelPhysicsUsageCounter { + int serverEnt; + int clientEnt; + int dynEnt; +}; + +struct DObjAnimMat { + float quat[4]; + float trans[3]; + float transWeight; +}; + +struct XModel { + const char* name; + unsigned __int16 numsurfs; + unsigned __int8 numLods; + unsigned __int8 collLod; + unsigned __int16 mdaoVolumeCount; + unsigned __int8 shadowCutoffLod; + int physicsUseCategory; + char characterCollBoundsType; + unsigned __int8 numAimAssistBones; + unsigned __int8 impactType; + unsigned __int8 mdaoType; + unsigned __int8 numBones; + unsigned __int8 numRootBones; + unsigned __int16 numClientBones; + unsigned __int8 numClothAssets; + unsigned int flags; + int contents; + float scale; + float radius; + Bounds bounds; + float edgeLength; + unsigned int lgvData; + XModelPhysicsUsageCounter physicsUsageCounter; + unsigned int noScalePartBits[8]; + void* scriptableMoverDef; + void* proceduralBones; + void* dynamicBones; + scr_string_t* aimAssistBones; + scr_string_t* boneNames; + unsigned __int8* parentList; + __int16* quats; + float* trans; + unsigned __int8* partClassification; + DObjAnimMat* baseMat; + vec3_t* ikHingeAxis; + uintptr_t reactiveMotionInfo; + uintptr_t materialHandles; +}; + +struct WeaponAnimPackage +{ + const char* name; + uintptr_t anims; + uintptr_t timers; + int meleeAnimPrimaryType; + int meleeAnimPrimaryCount; + unsigned __int8 meleeAnimPrimarySet; + bool meleeRandomizeAnims; + int meleeAnimAltType; + int meleeAnimAltCount; + unsigned __int8 meleeAnimAltSet; + bool altMeleeRandomizeAnims; + uintptr_t blendSpaces; + uintptr_t footstep; +}; + +union XAnimIndices +{ + unsigned __int8* _1; + unsigned __int16* _2; + void* data; +}; + +struct XAnimParts +{ + const char* name; + scr_string_t* names; + unsigned __int8* dataByte; + __int16* dataShort; + int* dataInt; + __int16* randomDataShort; + unsigned __int8* randomDataByte; + int* randomDataInt; + XAnimIndices indices; + uintptr_t notify; + uintptr_t deltaPart; + unsigned int randomDataShortCount; + unsigned int randomDataByteCount; + unsigned int indexCount; + float framerate; + float frequency; + unsigned int dataByteCount; + unsigned __int16 dataShortCount; + unsigned __int16 dataIntCount; + unsigned __int16 randomDataIntCount; + unsigned __int16 numframes; + unsigned __int8 flags; + unsigned __int8 boneCount[10]; + unsigned __int8 notifyCount; + unsigned __int8 assetType; + unsigned __int8 ikType; + unsigned __int8 fingerPoseType; + unsigned __int16 blendShapeWeightCount; + scr_string_t* blendShapeWeightNames; + unsigned __int16* blendShapeWeights; +}; + +struct WeaponDamageCommon +{ + int minDamage; + int mid1Damage; + int mid2Damage; + int mid3Damage; + int damage; + float maxDamageRange; + float mid1DamageRange; + float mid2DamageRange; + float mid3DamageRange; + float minDamageRange; +}; + +struct WeaponDamageInfo +{ + WeaponDamageCommon damageData[3]; + int deathAnimDamageType; + float terminateAtRange; +}; + +struct WeaponVFXPackage +{ + const char* name; + uintptr_t vfx; +}; + +struct __declspec(align(4)) TriggerDisconnectSoundData +{ + float analogTriggerValue; + bool enabledForFireType[6]; +}; + +struct __declspec(align(8)) WeaponSFXPackage +{ + const char* name; + uintptr_t sounds; + WeaponSFXPackage* transientFallbackPackage; + uintptr_t detailSoundBankNPC; + uintptr_t detailSoundBankPlayer; + unsigned __int8 rattleSoundType; + const char* szAdsrBaseSetting; + const char* szWeapSndReflectionClass; + const char* szWeapSndReflFrontOverride; + const char* szWeapSndReflDistantOverride; + float weapSndFireVolumeShot1; + float weapSndFireVolumeShot2; + float weapSndFireVolumeShot3; + float weapSndProneFireLFEVolume; + float weapSndMediumRangeStart; + float weapSndFarRangeStart; + float weapSndDistantRangeStart; + unsigned int projExplosionReflClass; + int sfxImpactType; + int sfxMeleeImpactType; + int sfxMaterialType; + const char* szMountEnterExitString; + const char* szMountImpactString; + unsigned int whizbyType; + unsigned int adsContextType; + unsigned int adsContextValue; + float speedOfSoundMult; + TriggerDisconnectSoundData triggerDisconnectSoundData; +}; + +struct __declspec(align(8)) ADSOverlay +{ + Material* shaderMat; + Material* shaderLowResMat; + Material* shaderEMPMat; + Material* shaderEMPLowResMat; + GfxImage* shaderImg; + GfxImage* shaderLowResImg; + GfxImage* shaderEMPImg; + GfxImage* shaderEMPLowResImg; + bool applyVisionSet; + int reticle; + float width; + float height; + float widthSplitscreen; + float heightSplitscreen; + const char* visionSetName; + float visionSetADSFraction; + int visionSetBlendInTimeMs; + int visionSetBlendOutTimeMs; +}; + +struct CommonSwaySettings +{ + float maxAngle; + float lerpSpeed; + float pitchScale; + float yawScale; + float horizScale; + float vertScale; + float gunAngleScale; +}; + +struct HipSwaySettings +{ + CommonSwaySettings common; + float maxAngleSteadyAim; +}; + +struct AdsSwaySettings +{ + CommonSwaySettings common; + float swayTransitionLerpSpeed; + float adsSwayScale[3]; +}; + +struct AdvancedHipSwaySettings +{ + bool enabled; + float torsoGoalSmoothSpeed; + int torsoGoalViewSmoothDurationMs; + vec2_t torsoGoalDeadzoneAdjustSpeed; + RumbleGraph* torsoGoalViewSpeedToMaxDeadzone_graph; + vec2_t torsoGoalViewSpeedToMaxDeadzone_viewspeed; + vec2_t torsoGoalViewSpeedToMaxDeadzone_maxDeadzone; + vec2_t torsoMass; + vec2_t torsoSpring; + vec2_t torsoDamper; + int gunGoalViewSmoothDurationMs; + RumbleGraph* gunGoalViewSpeedToOffset_graph; + vec2_t gunGoalViewSpeedToOffset_viewspeed; + vec2_t gunGoalViewSpeedToOffset_offset; + vec2_t gunMass; + vec2_t gunSpring; + vec2_t gunDamper; + vec3_t gunPivotPoint; + float gunYawToRollScale; + int fireDurationMs; + int fireStartBlendDurationMs; + int fireFinishBlendDurationMs; + float fireTorsoGoalSmoothSpeed; + float fireTorsoDeadzoneScale; + float fireTorsoToGunDirScale; +}; + +struct __declspec(align(4)) SwaySettings +{ + HipSwaySettings hip; + AdsSwaySettings ads; + AdvancedHipSwaySettings adv; + float shellShockScale; + bool overrideHip; + bool overrideAds; +}; + +struct WeaponOffsetCurveDescription +{ + float blendTime; + float decayTime; + float shotDecayFireTimeFrac; + float holdTime; + float adsFractionBegin; + float adsFractionEnd; + int interpType; + int interpTypeOut; +}; + +struct WeaponOffsetPatternDescription +{ + bool active; + scr_string_t patternKey; + int curveType; + int patternType; + int transformType; + float frequency; + float blendTime; + vec3_t magnitude; + float hipScale; + float rotationOffset; + float bulletDirScale; + float fullAutoScale; + int fullAutoBullets; + float fullAutoDecay; + int referenceIndex; + int kickOrSnapDecayIndex; +}; + +struct __declspec(align(4)) GestureWeaponSettings +{ + unsigned __int16 blendToStates; + bool hideReticle; + float fireDelay; + float sprintDelay; + bool useLeftIdleAkimbo; + bool splitAnimsAkimbo; + bool blendToDemeanorLoop; + bool blendOutRaise; + bool blendOutFingerPose; + bool blendOutAdditiveADS; +}; + +struct __declspec(align(2)) GestureDirectionalSettings +{ + float maxAngle; + float lerpAtMaxAngle; + float widthCushionAngle; + float lerpAtMinCushionAngle; + float lerpAtMaxCushionAngle; + float limitLeft; + float limitRight; + float limitUp; + float limitDown; + bool useTargetOffset; + float targetOffsetX; + float targetOffsetY; + float targetOffsetZ; + float targetOffsetYaw; + float targetOffsetPitch; + float targetOffsetRoll; + bool ignoreViewPitchForTargetOffset; + bool ignoreViewYawForTargetOffset; + bool ignoreViewRollForTargetOffset; +}; + +struct __declspec(align(4)) FootstepTime +{ + float time; + bool isLeft; +}; + +struct __declspec(align(4)) MovementTime +{ + float time; + bool isLeadIn; +}; + +struct FootstepAnim +{ + int leftCount; + FootstepTime step[32]; + MovementTime movement[32]; +}; + +struct GestureLookAroundSettings +{ + float yawLerpIn; + float yawLerpOut; + unsigned __int16 walkTime; + FootstepAnim walkFootStepAnim; +}; + +struct GestureIKTargetSettings +{ + scr_string_t targetEntityBoneName; +}; + +struct __declspec(align(8)) Gesture +{ + const char* name; + int type; + int priority; + bool looping; + uintptr_t anims; + GestureWeaponSettings weaponSettings; + GestureDirectionalSettings directionalSettings; + GestureLookAroundSettings lookAroundSettings; + GestureIKTargetSettings ikTargetSettings; +}; + +struct LaserSettings +{ + bool forceLaserOn; + bool localPlayerADSLaserEnabled; + bool localPlayerHipLaserEnabled; + bool localPlayerNVGADSLaserEnabled; + bool localPlayerNVGHipLaserEnabled; + bool remotePlayerADSLaserEnabled; + bool remotePlayerHipLaserEnabled; + bool remotePlayerNVGADSLaserEnabled; + bool remotePlayerNVGHipLaserEnabled; + bool laserViewCenterInAds; +}; + +struct __declspec(align(4)) GrenadeRotationParams +{ + float initialPitch; + float initialYaw; + float initialRoll; + int rotationPitchDir; + int rotationPitchMin; + int rotationPitchMax; + int rotationYawDir; + int rotationYawMin; + int rotationYawMax; + int rotationRollDir; + int rotationRollMin; + int rotationRollMax; + bool rotate; +}; + +struct AnimOverride +{ + unsigned int numBindings; + uintptr_t bindings; + uintptr_t overrides; + uintptr_t overridesAlt; +}; + +struct CarryAnimOverride +{ + int carryObjectType; + WeaponAnimPackage* animPackage; + WeaponAnimPackage* animPackageAlt; +}; + +struct SFXOverride +{ + unsigned int numBindings; + uintptr_t bindings; + uintptr_t overrides; + uintptr_t overridesAlt; +}; + +struct VFXOverride +{ + unsigned int numBindings; + uintptr_t bindings; + uintptr_t overrides; + uintptr_t overridesAlt; +}; + +struct WeaponOffsetPatternScaleInfo +{ + int numPatternScales; + uintptr_t patternScales; +}; + +struct AdvancedIdleSettings +{ + bool useAdvancedIdleSettings; + bool useRandomPointsAlgorithm; + float breathGaspScaleOverride; + float idleSwaySetting1_HipBulletDirScale; + float idleSwaySetting1_HipIdleSpeed; + float idleSwaySetting1_HipWeaponMagnitudeX; + float idleSwaySetting1_HipWeaponMagnitudeY; + float idleSwaySetting1_HipWeaponMagnitudeZ; + float idleSwaySetting1_HipWeaponMagnitudeF; + float idleSwaySetting1_HipWeaponRotationOffset; + float idleSwaySetting1_HipViewMagnitudeX; + float idleSwaySetting1_HipViewMagnitudeY; + float idleSwaySetting1_AdsBulletDirScale; + float idleSwaySetting1_AdsIdleSpeed; + float idleSwaySetting1_AdsWeaponMagnitudeX; + float idleSwaySetting1_AdsWeaponMagnitudeY; + float idleSwaySetting1_AdsWeaponMagnitudeZ; + float idleSwaySetting1_AdsWeaponMagnitudeF; + float idleSwaySetting1_AdsWeaponRotationOffset; + float idleSwaySetting1_AdsViewMagnitudeX; + float idleSwaySetting1_AdsViewMagnitudeY; + float idleSwaySetting2_HipBulletDirScale; + float idleSwaySetting2_HipIdleSpeed; + float idleSwaySetting2_HipWeaponMagnitudeX; + float idleSwaySetting2_HipWeaponMagnitudeY; + float idleSwaySetting2_HipWeaponMagnitudeZ; + float idleSwaySetting2_HipWeaponMagnitudeF; + float idleSwaySetting2_HipWeaponRotationOffset; + float idleSwaySetting2_HipViewMagnitudeX; + float idleSwaySetting2_HipViewMagnitudeY; + float idleSwaySetting2_AdsBulletDirScale; + float idleSwaySetting2_AdsIdleSpeed; + float idleSwaySetting2_AdsWeaponMagnitudeX; + float idleSwaySetting2_AdsWeaponMagnitudeY; + float idleSwaySetting2_AdsWeaponMagnitudeZ; + float idleSwaySetting2_AdsWeaponMagnitudeF; + float idleSwaySetting2_AdsWeaponRotationOffset; + float idleSwaySetting2_AdsViewMagnitudeX; + float idleSwaySetting2_AdsViewMagnitudeY; +}; + +struct BallisticInfoCalculated +{ + float* distances; + float zeroingAngle; + int numDistanceEntries; +}; + +struct BallisticInfo +{ + float muzzleVelocity; + float ballisticCoefficient; + float diameter; + float mass; + float gravityFactor; + float zeroingDistance; + BallisticInfoCalculated* calculated; + bool enableBallisticTrajectory; + int lifeTimeMs; +}; + +struct FxCombinedDef +{ + const void* /*ParticleSystemDef*/ particleSystemDef; +}; + +struct TracerDef +{ + const char* name; + FxCombinedDef effect; + FxCombinedDef viewmodelEffect; + unsigned int drawInterval; + float speed; + bool drawLegacyTracer; + bool fadeOverTime; + float fadeTime; + Material* material; + float beamLength; + float beamWidth; + float screwRadius; + float screwDist; + vec4_t colors[5]; +}; + +struct LaserDef +{ + const char* name; + Material* laserMaterial; + Material* laserLightMaterial; + bool ownerOnly; + bool nightvisionOnly; + float range; + float radius; + float endOffsetViewmodel; + float endOffsetOther; + float flarePct; + FxCombinedDef beamEffect; + FxCombinedDef laserEndEffect; + bool clientCollision; + vec4_t color; + vec4_t hdrColorScale; + bool laserLight; + bool laserLightNvgOnly; + float laserLightRadius; + float laserLightBeginOffset; + float laserLightEndOffset; + float laserLightBodyTweak; + vec4_t laserLightColor; + vec4_t laserLightHdrColorScale; + float range_alt; + float radius_alt; + float laserLightRadius_alt; + float flarePct_alt; +}; + + +struct SurfaceFxTable +{ + const char* name; + void* /*SurfaceFxEntry*/ table; + int numTableEntry; + unsigned __int8* mapPoolBuffer; + int mapPoolBufferSize; +}; + +struct RawFile +{ + const char* name; + unsigned int compressedLen; + unsigned int len; + const char* buffer; +}; + +struct ScriptFile +{ + const char* name; + int compressedLen; + int len; + int bytecodeLen; + const char* buffer; + unsigned __int8* bytecode; +}; + +struct ScriptDebugData +{ + const char* name; + unsigned int nameCRC; + unsigned int profileStringCount; + void* /*ScriptDebugDataProfileString*/ profileStrings; +}; + +struct StringTable +{ + const char* name; + int columnCount; + int rowCount; + int uniqueCellCount; + unsigned __int16* cellIndices; + int* hashes; + const char** strings; +}; + +struct LeaderboardDef +{ + const char* name; + int id; + int sourceLbId; + int sourceLbWidth; + int columnCount; + int xpColId; + int prestigeColId; + void* /*LbColumnDef*/ columns; + int /*LbUpdateType*/ updateType; + int trackTypes; + int rankColIdX; + int rankColIdY; +}; + +struct __declspec(align(8)) VirtualLeaderboardDef +{ + const char* name; + const char* sourceName; + int id; + int sourceId; + void* /*LbVrColumnDef*/ columns; + int columnCount; + int rankColIdX; + int rankColIdY; +}; + +struct DDLFile +{ + char* name; + struct DDLDef* ddlDef; +}; + +struct SndAliasLookup +{ + const char* name; +}; + +struct __declspec(align(8)) VehiclePhysicsSoundGroup +{ + SndAliasLookup alias; + float threshold; + float vmin; + float vmax; + float pmin; + float pmax; +}; + +struct __declspec(align(8)) VehiclePhysicsVfxGroup +{ + void* /*FootstepVFX*/ surfaceEffects; + float threshold; + float range0; + float range1; +}; + + +struct VehiclePhysicsDef +{ + int physicsEnabled; + int /*VehiclePhysicsNetcodeType*/ physics_netcodeType; + char /*VehiclePhysicsGameProfile*/ physics_gameProfile; + int /*VehiclePhysicsAnimProfile*/ physics_animProfile; + int physics_numWheels; + bool physics_axleRigidBodies; + float physics_axleBodyPadding; + int physics_axleBodySides; + scr_string_t physics_wheelBones[12]; + float physics_wheelRadius; + float physics_suspStiffness; + float physics_suspDamping; + float physics_suspNoiseAmp; + float physics_frontalSuspension; + float physics_ackermannRatio; + vec3_t physics_hardPointOffset; + vec3_t physics_comOffset; + vec4_t physics_massFactorContact; + vec4_t physics_inertiaDiagonal; + float physics_extraGravityFactor; + float physics_extraGravityFactorAir; + float physics_camFovDelta; + float physics_camPitchBase; + float physics_camPitchDynamic; + float physics_camRangeAdd; + float physics_steeringFactor; + float physics_steeringForce; + float physics_steeringMaxYawSpeed; + float physics_steeringOffsetPoint; + float physics_steeringOffsetPointUp; + float physics_steeringReturnSpeed; + float physics_steeringChangeDirSpeed; + float physics_steeringHandbrake; + float physics_steeringSpeed; + float physics_steeringSpeedIncrease; + float physics_engineOffsetPoint; + float physics_engineReductionOnHB; + float physics_rollingFriction; + float physics_lateralFriction; + float physics_frictionBase; + float physics_frictionRecoverSpeedTgt; + float physics_frictionFwRedirect; + float physics_frictionLost; + float physics_frictionHandbrake; + float physics_frictionSpeedToBlock; + float physics_decel; + float physics_minSpeed; + bool physics_stabilizeRoll; + bool physics_stabilizePitch; + bool physics_contentsAsMissile; + bool physics_pitchInversion; + unsigned int physics_controlMode; + float physics_timeAfterColl; + int physics_cycleCamButton; + int physics_boostButton; + float physics_boostSpeed; + float physics_rcpBoostAccel; + float physics_rcpBoostDecel; + bool physics_holdToBoost; + SndAliasLookup physics_rcpBoostSound; + vec3_t physics_rcpBoostShakeCam; + bool physics_rcpUseChangeDirLogic; + bool physics_rcpUseChangeDirLogicPitch; + bool physics_rcpUseRollForYawSpeed; + float physics_rcpOvershootProtection; + float physics_rcpPitchTurnSpeed; + float physics_rcpPitchChangeDirFactor; + float physics_rcpPitchLerpSpeed; + float physics_rcpPitchLerpSpeedChangeDir; + float physics_rcpPitchLerpSpeedReturning; + float physics_rcpPitchMaxAngle; + float physics_rcpYawTurnSpeed; + float physics_rcpYawChangeDirFactor; + float physics_rcpYawLerpSpeed; + float physics_rcpYawLerpSpeedChangeDir; + float physics_rcpYawLerpSpeedReturning; + float physics_rcpRollTurnSpeed; + float physics_rcpRollLerpSpeedSteering; + float physics_rcpRollLerpSpeedChangeDir; + float physics_rcpRollLerpSpeedReturning; + float physics_rcpRollMaxAngle; + float physics_rcpAccelGoingDown; + float physics_rcpDecelGoingUp; + float physics_rcpTraceAhead; + bool physics_rcpCam1stAttachToTagPlayer; + vec2_t physics_rcpCam1stNoiseScale; + float physics_rcpCam1stRollSpeed; + float physics_rcpCam1stRollPercentage; + float physics_comAdjustThreshold; + float physics_comAdjustVertDisp; + float physics_playersWeightFactor; + float physics_timeToAcceptInputOnStart; + float physics_viewDirectionHelp; + float physics_stabilizePitchSpeed; + float physics_stabilizeRollSpeed; + int /*VehicleWheelSpinBoneType*/ spinWheelBones; + float spinWheelAngleOffset; + int treads_enabled; + int treads_boneCount; + scr_string_t treads_firstBones[2]; + float frictionBraking; + float suspensionTravel; + float maxSteeringAngle; + float steeringLerp; + float minSteeringScale; + float minSteeringSpeed; + int disableWheelsTurning; + int disableWheelsSpinning; + float minimumWheelCastFraction; + float handbrakeThreshold; + float minimumJoltForNotify; + float pathConstraintStrengthFwd; + float pathConstraintStrengthSide; + float pathConstraintDampFwd; + float pathConstraintDampSide; + float crashPointOffsetFwd; + float crashPointOffsetUp; + float crashImpulseSide; + float crashImpulseUp; + float wreckedMassScale; + VehiclePhysicsSoundGroup sndImpactHard; + float sndImpactExp; + VehiclePhysicsSoundGroup sndImpactLight; + VehiclePhysicsSoundGroup sndDrivingFast; + VehiclePhysicsSoundGroup sndDrivingSlow; + VehiclePhysicsSoundGroup sndSuspension; + VehiclePhysicsSoundGroup sndBrakingHard; + VehiclePhysicsSoundGroup sndBrakingLight; + VehiclePhysicsSoundGroup sndDrifting; + VehiclePhysicsSoundGroup sndSkidding; + VehiclePhysicsSoundGroup sndDlc1; + VehiclePhysicsSoundGroup sndDlc2; + VehiclePhysicsSoundGroup sndDlc3; + VehiclePhysicsSoundGroup sndDlc4; + VehiclePhysicsVfxGroup vfxImpactHard; + VehiclePhysicsVfxGroup vfxImpactLight; + VehiclePhysicsVfxGroup vfxDrivingFast; + VehiclePhysicsVfxGroup vfxDrivingSlow; + VehiclePhysicsVfxGroup vfxBrakingHard; + VehiclePhysicsVfxGroup vfxBrakingLight; + VehiclePhysicsVfxGroup vfxDrifting; + VehiclePhysicsVfxGroup vfxSkidding; + VehiclePhysicsVfxGroup vfxDrivingFlatFast; + VehiclePhysicsVfxGroup vfxDrivingFlatSlow; + VehiclePhysicsVfxGroup vfxDlc3; + VehiclePhysicsVfxGroup vfxDlc4; +}; + +struct SpaceshipAnimParts +{ + void* /*XAnimParts*/ anim[2]; +}; + +struct VehiclePhysicsRevModifier +{ + float skidSndContrib; + float noiseAmpl; + float sinewaveFreq; + float sinewaveAmpl; + float rpmMax; + float rpmScale; + float rpmSpeedEmaSamples; + float inclinedThreshold; + int gearCount; + float inclContrib; + float maxSpinSpeedRPMFw; + float maxSpinSpeedRPMBw; +}; + +struct VehicleDef +{ + const char* name; + char type; + const char* useHintString; + int health; + int inputBindingSet; + int hitClientScriptables; + int hitRemoteControllers; + int accurateShapeOverlap; + int numDoors; + float maxDoorAngle; + scr_string_t doorBones[4]; + CameraDef* cameraDef; + CameraDef* killCamDef; + float texScrollScale; + float topSpeed; + float accel; + float rotRate; + float rotAccel; + float maxBodyPitch; + float maxBodyRoll; + float rangeForBoneControllers; + float fakeBodyAccelPitch; + float fakeBodyAccelRoll; + float fakeBodyVelPitch; + float fakeBodyVelRoll; + float fakeBodySideVelPitch; + float fakeBodyPitchStrength; + float fakeBodyRollStrength; + float fakeBodyPitchDampening; + float fakeBodyRollDampening; + float fakeBodyBoatRockingAmplitude; + float fakeBodyBoatRockingPeriod; + float fakeBodyBoatRockingRotationPeriod; + float fakeBodyBoatRockingFadeoutSpeed; + float boatBouncingMinForce; + float boatBouncingMaxForce; + float boatBouncingRate; + float boatBouncingFadeinSpeed; + float boatBouncingFadeoutSteeringAngle; + float collisionDamage; + float collisionSpeed; + bool collisionDamageIgnoresImpactAngle; + vec3_t killcamOffset; + int playerProtected; + int bulletDamage; + int armorPiercingDamage; + int grenadeDamage; + int projectileDamage; + int projectileSplashDamage; + int heavyExplosiveDamage; + VehiclePhysicsDef vehiclePhysicsDef; + int vehHelicopterLockAltitude; + int vehHelicopterOffsetFromMesh; + float vehHelicopterAltitudeOffset; + float vehHelicopterPitchOffset; + float vehHelicopterBoundsRadius; + float vehHelicopterMaxSpeed; + float vehHelicopterMaxSpeedVertical; + float vehHelicopterMaxAccel; + float vehHelicopterMaxAccelVertical; + float vehHelicopterDecelerationFwd; + float vehHelicopterDecelerationSide; + float vehHelicopterDecelerationUp; + float vehHelicopterMaxYawRate; + float vehHelicopterMaxYawAccel; + float vehHelicopterTiltFromVelocity; + float vehHelicopterTiltFromControllerAxes; + float vehHelicopterTiltFromAcceleration; + float vehHelicopterTiltFromDeceleration; + float vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt; + float vehHelicopterTiltFromFwdAndYaw; + float vehHelicopterTiltMomentum; + float vehHelicopterTiltSpeed; + float vehHelicopterMaxPitch; + float vehHelicopterMaxRoll; + float vehHelicopterHoverSpeedThreshold; + float vehHelicopterJitterJerkyness; + float vehHelicopterLookaheadTime; + int vehHelicopterSoftCollisions; + int vehHelicopterUseGroundFX; + FxCombinedDef vehHelicopterGroundFx; + FxCombinedDef vehHelicopterGroundWaterFx; + float vehHelicopterGroundFxDefaultRepeatRate; + float vehHelicopterGroundFxSlowestRepeatRate; + float vehHelicopterGroundFxFastestRepeatRate; + float vehHelicopterGroundFxMinGroundDist; + float vehHelicopterGroundFxMaxGroundDist; + float vehRotorMaxVelocity; + float vehRotorMaxAccel; + float vehRotorAccelTiltBlend; + float vehRotorMaxVehicleSpin; + float vehRotorMaxAngle; + float vehRotorSpinSpeed; + float vehRotorSpinVerticalSpeedThreshold; + float vehRotorMaxSpinAddition; + float ssWeaponSwitchDelaySeconds; + float ssWeaponRaiseDelaySeconds; + vec3_t ssFlyMaxSpeedMph; + vec3_t ssFlyMaxAccelerationMphps; + vec3_t ssFlyMaxCounterAccelerationMphps; + vec3_t ssFlyFrictionMphps; + vec3_t ssFlyJukeSpeedMph; + vec3_t ssHoverMaxSpeedMph; + vec3_t ssHoverMaxAccelerationMphps; + vec3_t ssHoverMaxCounterAccelerationMphps; + vec3_t ssHoverFrictionMphps; + vec3_t ssHoverJukeSpeedMph; + float ssFlyJukeRampTime; + float ssHoverJukeRampTime; + float ssBrakingFrictionMphps; + float ssFlyRedirectVelocityScale; + float ssFlySlowRedirectVelocityScale; + float ssHoverRedirectVelocityScale; + float ssFlyMinSpeedRatio; + bool ssProjectVelocityDesiresToXY; + bool ssEnforceMinGroundClearance; + float ssMinGroundClearanceHeight; + float ssMinGroundClearanceLiftForce; + bool ssTerrainModeMovement; + float ssTerrainModeGravity; + float ssTerrainModeFlyTime; + vec2_t ssAimOffsetClampDeg; + vec2_t ssPitchUpSoftLimitDeg; + vec2_t ssPitchDownSoftLimitDeg; + float ssClutchPitchSpeedScale; + vec2_t ssFlyAimSpeedDps; + vec2_t ssFlySlowAimSpeedDps; + vec2_t ssHoverAimSpeedDps; + vec2_t ssFlyAimDriftScale; + vec2_t ssFlySlowAimDriftScale; + vec2_t ssHoverAimDriftScale; + float ssMinSpringOscillation; + float ssMaxSpringOscillation; + float ssMinSpringStrength; + float ssMaxSpringStrength; + float ssMinSpringAngSpeed; + float ssMaxSpringAngSpeed; + float ssSpringControllerContribution; + float ssTiltSpringOscillation; + float ssTiltSpringStrength; + float ssTiltSpringAngleContribution; + int ssADSToLockOn; + float ssLockOnMinAngle; + float ssLockOnMaxAngle; + float ssPilotAssistNoLockAimScale; + float ssPilotAssistNoLockMinAngle; + float ssPilotAssistNoLockMaxAngle; + float ssPilotAssistAimScale; + float ssPilotAssistMinAngle; + float ssPilotAssistMaxAngle; + vec2_t ssAutoLevelStrengthHover; + vec2_t ssAutoLevelStrengthFly; + bool ssIsRollRightStick; + float ssRollMaxSpeedDps; + float ssBoostSpeedScale; + float ssBoostThrustScale; + bool ssEnableBoostToFly; + float ssBoostTime; + float ssBoostRegenTime; + float ssBoostRegenStallTime; + float ssBoostMinThresholdRatio; + float ssCollisionRadiusI; + float ssCylinderHeightI; + bool ssUseCylinder; + bool ssUsePlayerClip; + float ssCollisionOffsetI; + float ssCollisionHardThresholdMph; + float ssFOVFlyOffsetDeg; + float ssFOVFlyBoostOffsetDeg; + float ssFOVHoverOffsetDeg; + float ssZoomBlendSpeedDps; + float ssZoomMaxAngle; + float ssZoomMinDistI; + float ssZoomIdealDistI; + float ssZoomMaxDistI; + bool ssShowPilotViewmodel; + float ssCameraAnimScale; + vec2_t ssFlyTiltShipAngles; + float ssFlyTiltCameraScale; + vec2_t ssHoverTiltShipAngles; + float ssHoverTiltCameraScale; + float ssMotionIdleRateMinSpeed; + float ssMotionIdleRateMaxSpeed; + float ssMotionIdleMinRate; + float ssMotionIdleMaxRate; + scr_string_t ssAnimTree; + SpaceshipAnimParts ssAnimParts[33]; + FxCombinedDef ssThrustFxLoop; + FxCombinedDef ssJukeFx; + RumbleInfo* ssIdleRumble; + RumbleInfo* ssSmallRumble; + RumbleInfo* ssMedRumble; + RumbleInfo* ssLargeRumble; + SndAliasLookup rattleLoop; + float rattleLoopMinVolume; + float rattleLoopMaxVolume; + SndAliasLookup airLoop; + float airLoopMinVolume; + float airLoopMaxVolume; + SndAliasLookup engineLoop; + float engineLoopMinVolume; + float engineLoopMaxVolume; + float engineLoopMinPitch; + float engineLoopMaxPitch; + SndAliasLookup hoverLoop; + float hoverLoopMinVolume; + float hoverLoopMaxVolume; + float hoverLoopMinPitch; + float hoverLoopMaxPitch; + SndAliasLookup boostLoop; + float boostLoopMaxVolume; + float boostLoopMaxPitch; + SndAliasLookup ssThrustLoop; + float ssThrustLoopMaxVolume; + float ssThrustLoopMaxPitch; + SndAliasLookup boostStart; + SndAliasLookup boostStop; + SndAliasLookup boostDepleted; + SndAliasLookup boostUnavailable; + SndAliasLookup jukeLeft; + SndAliasLookup jukeRight; + SndAliasLookup jukeUpDown; + SndAliasLookup jukeBack; + SndAliasLookup jukeFront; + SndAliasLookup flightOn; + SndAliasLookup flightOff; + float flightOnTimer; + float flightOffTimer; + SndAliasLookup hardCollision; + SndAliasLookup softCollision; + int camLookEnabled; + int camRelativeControl; + int camRemoteDrive; + float camLerp; + float camHeight; + float camRadius; + float camPitchInfluence; + float camYawInfluence; + float camRollInfluence; + float camFovIncrease; + float camFovOffset; + float camFovSpeed; + float camReturnSpeed; + float camReturnLerp; + float camVehicleAnglePitchRate; + float camVehicleAngleYawRate; + float camVehicleAngleRollRate; + int vehCam_UseGDT; + float vehCam_anglesPitch; + float vehCam_anglesYaw; + float vehCam_anglesRoll; + float vehCam_offsetX; + float vehCam_offsetY; + float vehCam_offsetZ; + float vehCam_radius; + float vehCam_speedInfluence; + float vehCam_pitchTurnRate; + float vehCam_pitchClamp; + float vehCam_yawTurnRate; + float vehCam_yawClamp; + int /*VehCamZOffsetMode*/ vehCam_zOffsetMode; + float vehCam_anglesPitch3P; + float vehCam_anglesYaw3P; + float vehCam_anglesRoll3P; + float vehCam_offsetX3P; + float vehCam_offsetY3P; + float vehCam_offsetZ3P; + float vehCam_radius3P; + float vehCam_speedInfluence3P; + float vehCam_pitchTurnRate3P; + float vehCam_pitchClamp3P; + float vehCam_yawTurnRate3P; + float vehCam_yawClamp3P; + int /*VehCamZOffsetMode*/ vehCam_zOffsetMode3P; + const char* turretWeaponName; + void* /*WeaponCompleteDef*/ turretWeapon; + float turretHorizSpanLeft; + float turretHorizSpanRight; + float turretVertSpanUp; + float turretVertSpanDown; + float turretHorizResistLeft; + float turretHorizResistRight; + float turretVertResistUp; + float turretVertResistDown; + float turretRotRate; + int /*VehicleTurretFireType*/ turretFireType; + SndAliasLookup turretSpinSnd; + SndAliasLookup turretStopSnd; + int trophyEnabled; + float trophyRadius; + float trophyInactiveRadius; + int trophyAmmoCount; + float trophyReloadTime; + scr_string_t trophyTags[4]; + FxCombinedDef trophyExplodeFx; + FxCombinedDef trophyFlashFx; + Material* compassFriendlyIcon; + Material* compassEnemyIcon; + Material* compassFriendlyAltIcon; + Material* compassEnemyAltIcon; + int compassIconWidth; + int compassIconHeight; + void* /*SndBankTransient*/ detailSoundBankNPC; + void* /*SndBankTransient*/ detailSoundBankPlayer; + SndAliasLookup idleLowSnd; + SndAliasLookup idleHighSnd; + SndAliasLookup engineLowSnd; + SndAliasLookup engineHighSnd; + SndAliasLookup fallbackIdleLowSnd; + SndAliasLookup fallbackIdleHighSnd; + SndAliasLookup fallbackEngineLowSnd; + SndAliasLookup fallbackEngineHighSnd; + float engineSndSpeed; + scr_string_t audioOriginTag; + SndAliasLookup mainRotorLowRpmSnd; + SndAliasLookup mainRotorOperatingRpmSnd; + SndAliasLookup mainRotorOperatingEffortSnd; + SndAliasLookup tailRotorLowRpmSnd; + SndAliasLookup tailRotorOperatingRpmSnd; + SndAliasLookup tailRotorOperatingEffortSndLeft; + SndAliasLookup tailRotorOperatingEffortSndRight; + SndAliasLookup physicsHeliStartup; + SndAliasLookup physicsHeliShutdown; + SndAliasLookup turbineLowRpmSnd; + SndAliasLookup turbineOperatingRpmSnd; + bool useRevAudioSettings; + SndAliasLookup revLowFidelityMod; + SndAliasLookup revHighFidelityMod; + float revPlayerPriority; + VehiclePhysicsRevModifier revModifier; + SndAliasLookup engineStartUpSnd; + int engineStartUpLength; + SndAliasLookup engineShutdownSnd; + SndAliasLookup engineIdleSnd; + SndAliasLookup engineSustainSnd; + SndAliasLookup engineRampUpSnd; + int engineRampUpLength; + SndAliasLookup engineRampDownSnd; + int engineRampDownLength; + SndAliasLookup suspensionSoftSnd; + float suspensionSoftCompression; + SndAliasLookup suspensionHardSnd; + float suspensionHardCompression; + SndAliasLookup collisionSnd; + float collisionBlendSpeed; + SndAliasLookup speedSnd; + float speedSndBlendSpeed; + const char* surfaceSndName; + float surfaceSndBlendSpeed; + float slideVolume; + float slideBlendSpeed; + float inAirPitch; + const char* soundTriggerOverrideZone; + bool soundTriggerOverrideReverb; + bool soundTriggerOverrideMix; + bool soundTriggerOverrideFilter; + bool soundTriggerOverrideOcclusion; + bool soundTriggerOverrideAmbient; + bool soundTriggerOverrideAmbientEvents; + bool soundTriggerOverrideADSR; + int visionBlendTime; + const char* globalVisionSettings; + const char* mapVisionSettings; + const char* luiCrosshairWidget; + float dlcFloat[8]; +}; + +struct MapTriggers +{ + unsigned int count; + void* /*TriggerModel*/ models; + unsigned int hullCount; + void* /*TriggerHull*/ hulls; + unsigned int slabCount; + void* /*TriggerSlab*/ slabs; + unsigned int windingCount; + void* /*TriggerWinding*/ windings; + unsigned int windingPointCount; + void* /*TriggerWindingPoint*/ windingPoints; +}; + + +struct AddonMapEnts +{ + const char* name; + char* entityString; + int numEntityChars; + MapTriggers trigger; + unsigned int numSubModels; + void* /*cmodel_t*/ cmodels; + void* /*GfxBrushModel*/ models; +}; + +struct NetConstStrings +{ + const char* name; + int /*NetConstStringType*/ stringType; + int /*NetConstStringSource*/ sourceType; + unsigned int flags; + unsigned int entryCount; + const char** stringList; +}; + +struct LuaFile +{ + const char* name; + int len; + unsigned __int8 strippingType; + const unsigned __int8* buffer; +}; + + +struct __declspec(align(8)) ScriptableDef +{ + const char* name; + ScriptableDef* nextScriptableDef; + int flags; + unsigned int numParts; + void* /*ScriptablePartDef*/ parts; + unsigned int maxNumDynEntsRequired; + unsigned int partCount; + unsigned int serverInstancedPartCount; + unsigned int serverControlledPartCount; + unsigned int maxNumDynEntPartsBase; + unsigned int maxNumDynEntPartsForSpawning; + unsigned __int16 eventStreamSizeRequiredServer; + unsigned __int16 eventStreamSizeRequiredClient; + unsigned int usablePartCount; + unsigned int ffMemCost; + scr_string_t animationTreeName; + void* /*XAnim_s*/ animationTreeDef[2]; + float viewRadius; + bool networkLODRangeOverride; + float networkLODRangeOverrideDistance; + unsigned int numXModels; + XModel** models; + char /*DynEntitySpatialActivationMode*/ spatialActivationMode; +}; + +struct EquipSoundSetMoveTypes +{ + void* /*EquipmentSoundSet*/ soundSets; +}; + +struct EquipmentSoundSet +{ + void* /*SndAliasList*/ soundPLR; + void* /*SndAliasList*/ soundNPC; +}; + +struct EquipSoundSetMeleeWorld +{ + EquipmentSoundSet soundSets[8][3][2][4]; +}; + +struct EquipmentSoundTable +{ + const char* szName; + unsigned int numClothTypes; + unsigned int numWeaponRattleTypes; + unsigned int numMoveTypes; + unsigned int numStanceTypes; + void* /*EquipmentClothData*/ clothTypes; + void* /*EquipmentWeaponRattleData*/ weaponRattleTypes; + void* /*EquipmentChanceRattleTypes*/ chancesPLR; + void* /*EquipmentChanceRattleTypes*/ chancesNPC; + void* /*EquipSoundSetFootsteps*/ mvmtClothFootstepSoundSets; + void* /*EquipSoundSetFootsteps*/ mvmtClothFootstepCeilingSoundSets; + void* /*EquipSoundSetMoveLeadTypes*/ mvmtClothFoleySoundSets; + void* /*EquipSoundSetMoveTypes*/ mvmtRattleSoundSets; + EquipSoundSetMoveTypes mvmtAccentSoundSets; + void* /*EquipSoundSetMantleTypes*/ mvmtMantleSoundSets; + void* /*EquipSoundSetStanceTypes*/ mvmtStanceSoundSets; + void* /*EquipSoundSetMeleeVM*/ meleeAttackVMSoundSets; + void* /*EquipSoundSetMeleeWM*/ meleeAttackWMSoundSets; + void* /*EquipSoundSetMeleeWM*/ meleeCharacterSoundSets; + EquipSoundSetMeleeWorld meleeWorldSoundSets; +}; + +struct ExtentBounds +{ + vec3_t mins; + vec3_t maxs; +}; + +struct VectorField +{ + const char* name; + void* /*VectorSubField*/ subFields; + ExtentBounds worldBounds; + vec3_t localOrigin; + unsigned int numSubFields; + unsigned int pad[2]; +}; + +struct FxParticleSimAnimationHeader +{ + float playbackRate; + float duration; + unsigned int frameCount; + float minX; + float minY; + float minZ; + float boundsXDelta; + float boundsYDelta; + float boundsZDelta; + float maxWidth; + float maxHeight; + unsigned int colorTableSize; + unsigned int particleDataCount; + unsigned int maxActiveParticles; + bool evalVisStatePerParticle; + bool sortParticlesAtRuntime; + bool hasOrientation3D; + bool hasIndex; +}; + +struct FxParticleSimAnimation +{ + const char* name; + Material* material; + FxParticleSimAnimationHeader header; + void* /*FxParticleSimAnimationParticleData*/ particleData; + void* /*FxParticleSimAnimationParticleDataOrientation3D*/ particleDataOrientation3D; + void* /*FxParticleSimAnimationParticleDataIndex*/ particleDataIndex; + void* /*FxParticleSimAnimationFrame*/ frames; + vec4_t* colorTable; +}; + +struct StreamingInfo { + char __padding[0x48]; +}; + +struct TTFDef +{ + const char* name; + int fileLen; + const char* file; + void* ftFace; +}; + +struct SuitDef +{ + const char* name; + float cam_minVelocityForFovIncrease; + float cam_maxVelocityForFovIncrease; + float cam_velocityToDecreaseFov; + float cam_fovIncreaseAtMaxVelocity; + float cam_oneOverFovEaseInTimeMs; + float cam_oneOverFovEaseOutTimeMs; + CameraDef* cam_helmetCam; + bool cam_drawHelmet; + vec3_t cam_camtoHelmetOffsetOrigin; + vec3_t cam_camtoHelmetOffsetAngles; + bool enableIKOverride; + float player_globalAccelScale; + float player_crouchSpeedScale; + float player_proneSpeedScale; + float player_lastStandCrawlSpeedScale; + float player_sprintSpeedScale; + bool player_sprintUnlimited; + float player_viewBobScale; + bool jump_slowdownEnable; + float jump_height; + float sprintLeap_height; + float sprintLeap_forwardVelocityScale; + int sprintLeap_minSprintTimeMs; + float doubleJump_accel; + float doubleJump_speed; + float doubleJump_speedNoBoost; + float doubleJump_frictionMin; + float doubleJump_frictionMax; + float doubleJump_initialUpBoostAccel; + float doubleJump_standardUpBoostAccel; + float doubleJump_energyNeededForInitialUpBoost; + float doubleJump_energyNeededForStandardUpBoost; + float doubleJump_maxUpwardsVelocity; + bool doubleJump_enableMinZVelocity; + float doubleJump_minZVelocity; + float doubleJump_energyInitialCost; + float doubleJump_boostUpEnergyUseRate; + float doubleJump_energyUsePerButtonPress; + bool doubleJump_hoverOnly; + float doubleJump_maxViewPitchDip; + float doubleJump_maxViewBackwardsPitchDip; + float doubleJump_maxViewRoll; + float doubleJump_oneOverEaseInTime; + float doubleJump_oneOverEaseOutTimeMs; + bool doubleJump_alwaysDipView; + SndAliasLookup doubleJump_sound; + SndAliasLookup doubleJump_soundPlayer; + SndAliasLookup doubleJump_releaseSound; + SndAliasLookup doubleJump_releaseSoundPlayer; + float slide_strafe_speed_scale; + int slide_sprint_penalty_ms; + bool slide_allow_firing; + bool slide_allow_ads; + bool slide_allow_weapon_switch; + float slide_jump_speed_scale; + float slide_energy_cost_ratio; + int slide_max_time_ms; + int slide_max_time_reduced_ms; + int slide_max_time_base_ms; + int slide_inTimeMs; + float slide_inMaxSpeedScale; + float slide_inAcceleration; + float slide_frictionScaleNormal; + float slide_frictionScaleDownhill; + float slide_frictionScaleUphill; + float slide_frictionScaleBlocked; + int slide_gestureOutTimeForJumpMs; + int slide_sprintDelayMs; + bool slide_disableProneTransition; + int slide_proneDelayMs; + int slide_proneButtonCheckTimeMs; + int slide_outTimeMs; + float slide_outFrictionScaleStart; + float slide_outFrictionScaleFinish; + float slide_outSpeedScaleStart; + float slide_outSpeedScaleFinish; + int slide_inAirTimeMs; + float slide_inAirFrictionScaleStart; + float slide_inAirFrictionScaleFinish; + int slide_viewBlendInTimeMs; + int slide_viewBlendOutTimeMs; + float wallRun_minZVel; + float wallRun_minTriggerSpeed; + float wallRun_minMaintainSpeed; + int wallRun_delayPeriodMs; + float wallRun_minJumpHeight; + int wallRun_maxTimeMs; + int wallRun_fallStageTimeMs; + float wallRun_maxHeight; + float wallRun_jumpHeight; + float wallRun_jumpVelocity; + float wallRun_frictionScale; + float wallRun_speedScale; + float wallRun_speedScaleADS; + float wallRun_energyInitialCost; + float wallRun_energyChangePerSecond; + float ladder_anchorOffset; + float ladder_anchorOffsetWM; + float ladder_handDistance; + int /*SuitAnimType*/ suitAnimType; + bool isMovementCameraIndependent; + void* /*SuitAnimPackage*/ animPackage; + void* /*SuitAnimPackage*/ animPackageL; + void* /*SuitAnimPackage*/ animPackageR; + void* /*SuitAnimPackage*/ animPackageRelaxed; + void* /*SuitAnimPackage*/ animPackageSafe; + void* /*ASM*/ asmAsset; + void* /*Animset*/ animsetAsset; + unsigned __int8 facialAnimType; + int /*SuitBodyAnimType*/ bodyAnimType; + ScriptableDef* scriptableDef; + int viewheight_stand; + int viewheight_crouch; + int viewheight_prone; + int viewheight_laststand; + int viewheight_dead; + int viewheight_swim; + int viewheight_slide; + int viewheight_sprint; + int bounds_radius; + int bounds_height_stand; + int bounds_height_crouch; + int bounds_height_prone; + Bounds bounds_stand; + Bounds bounds_crouch; + Bounds bounds_prone; + int radialMotionBlur_interpTimeIn; + int radialMotionBlur_interpTimeOut; + float radialMotionBlur_sprintMinRadius; + float radialMotionBlur_sprintMaxRadius; + float radialMotionBlur_sprintMinStrength; + float radialMotionBlur_sprintMaxStrength; + float radialMotionBlur_slideMinRadius; + float radialMotionBlur_slideMaxRadius; + float radialMotionBlur_slideMinStrength; + float radialMotionBlur_slideMaxStrength; + float radialMotionBlur_doubleJumpMinRadius; + float radialMotionBlur_doubleJumpMaxRadius; + float radialMotionBlur_doubleJumpMinStrength; + float radialMotionBlur_doubleJumpMaxStrength; + float radialMotionBlur_wallRunMinRadius; + float radialMotionBlur_wallRunMaxRadius; + float radialMotionBlur_wallRunMinStrength; + float radialMotionBlur_wallRunMaxStrength; + float radialMotionBlur_groundPoundMinRadius; + float radialMotionBlur_groundPoundMaxRadius; + float radialMotionBlur_groundPoundMinStrength; + float radialMotionBlur_groundPoundMaxStrength; + float radialMotionBlur_rewindMinRadius; + float radialMotionBlur_rewindMaxRadius; + float radialMotionBlur_rewindMinStrength; + float radialMotionBlur_rewindMaxStrength; + float radialMotionBlur_dodgeMinRadius; + float radialMotionBlur_dodgeMaxRadius; + float radialMotionBlur_dodgeMinStrength; + float radialMotionBlur_dodgeMaxStrength; + float radialMotionBlur_skydiveMinRadius; + float radialMotionBlur_skydiveMaxRadius; + float radialMotionBlur_skydiveMinStrength; + float radialMotionBlur_skydiveMaxStrength; + RumbleInfo* groundPound_activationRumble; + SndAliasLookup groundPound_activationSound; + SndAliasLookup groundPound_activationSoundPlayer; + RumbleInfo* groundPound_landingRumble; + SndAliasLookup groundPound_landingSound; + SndAliasLookup groundPound_landingSoundPlayer; + RumbleInfo* landing_rumbleLowHeight; + RumbleInfo* landing_rumbleMediumHeight; + RumbleInfo* landing_rumbleHighHeight; + RumbleInfo* landing_rumbleExtremeHeight; + float landing_speedScale; + float footstep_shakeBroadcastRadiusInches; + int footstep_shakeDurationMs; + float footstep_shakeAmplitude; + RumbleInfo* footstep_rumble; + void* /*FootstepVFX*/ footstepvfx_slide; + void* /*FootstepVFX*/ footstepvfx_creep_left; + void* /*FootstepVFX*/ footstepvfx_creep_right; + void* /*FootstepVFX*/ footstepvfx_walk_left; + void* /*FootstepVFX*/ footstepvfx_walk_right; + void* /*FootstepVFX*/ footstepvfx_run_left; + void* /*FootstepVFX*/ footstepvfx_run_right; + void* /*FootstepVFX*/ footstepvfx_sprint_left; + void* /*FootstepVFX*/ footstepvfx_sprint_right; + float skydive_mass; + float skydive_gravitatationalAcceleration; + XModel* skydive_parachuteViewModel; + XModel* skydive_parachuteWorldModel; + float skydive_baseJumpMinimumHeight; + float skydive_baseJumpClearanceRadius; + float skydive_baseJumpAutoDeployHeight; + float skydive_baseJumpForceFreefallHeight; + float skydive_freefallSuperDiveCameraPitch; + float skydive_freefallSuperDiveStickInput; + float skydive_freefallSuperDiveFovAdjustDegrees; + int skydive_freefallSuperDiveFovAdjustInTime; + int skydive_freefallSuperDiveFovAdjustOutTime; + void* /*CinematicMotionDef*/ skydive_freefallCinematicMotion; + float skydive_freefallThrottleTrackSpeed; + float skydive_freefallAnimTrackSpeedThrottle; + float skydive_freefallAnimTrackSpeedStrafe; + float skydive_freefallAnimTrackSpeedYaw; + float skydive_freefallAnimTrackSpeedPitch; + float skydive_freefallAnimMinWeight; + float skydive_freefallAnimMaxWeight; + float skydive_freefallAnimMinPlayRate; + float skydive_freefallAnimMaxPlayRate; + float skydive_freefallAnimSpeedForMinWeight; + float skydive_freefallAnimSpeedForMaxWeight; + float skydive_freefallTopGroundSpeed; + float skydive_freefallMinPitch; + float skydive_freefallMaxPitch; + float skydive_freefallPitchSpeed; + float skydive_freefallYawSpeed; + float skydive_freefallCrossSectionalArea; + float skydive_freefallLookHorizForceMin; + float skydive_freefallLookHorizForceMax; + RumbleGraph* skydive_freefallLookHorizForceGraph; + float skydive_freefallStickHorizForceMin; + float skydive_freefallStickHorizForceMax; + RumbleGraph* skydive_freefallStickHorizForceGraph; + float skydive_freefallDragCoefHoriz; + float skydive_freefallLookHorizDragCoeff; + RumbleGraph* skydive_freefallLookHorizDragGraph; + float skydive_freefallStickHorizDragCoeff; + RumbleGraph* skydive_freefallStickHorizDragGraph; + float skydive_freefallDragCoefVert; + float skydive_freefallLookVertDragCoeff; + RumbleGraph* skydive_freefallLookVertDragGraph; + float skydive_freefallStickVertDragIncreasePerc; + RumbleGraph* skydive_freefallStickVertDragIncreaseGraph; + float skydive_freefallStickVertDragReductionPerc; + RumbleGraph* skydive_freefallStickVertDragReductionGraph; + float skydive_freefallStickSidewaysForce; + float skydive_freefallMaxBrakeForce; + float skydive_freefallMinTurnMultiplier; + float skydive_freefallMaxTurnMultiplier; + RumbleGraph* skydive_freefallTurnMultiplierGraph; + float skydive_freefallTurnMultiplierMinScale; + float skydive_freefallTurnMultiplierMaxScale; + RumbleGraph* skydive_freefallTurnMultiplierPitchGraph; + SndAliasLookup skydive_freefallAmbientSound; + float skydive_freefallAmbientSoundGroundSpeedWeight; + float skydive_freefallAmbientSoundMinVolume; + float skydive_freefallAmbientSoundMaxVolume; + float skydive_freefallAmbientSoundMinPitch; + float skydive_freefallAmbientSoundMaxPitch; + float skydive_freefallAmbientSoundMinGroundSpeed; + float skydive_freefallAmbientSoundMaxGroundSpeed; + float skydive_freefallAmbientSoundMinFallSpeed; + float skydive_freefallAmbientSoundMaxFallSpeed; + SndAliasLookup skydive_freefallHighSpeedSound; + float skydive_freefallHighSpeedSoundGroundSpeedWeight; + float skydive_freefallHighSpeedSoundMinVolume; + float skydive_freefallHighSpeedSoundMaxVolume; + float skydive_freefallHighSpeedSoundMinPitch; + float skydive_freefallHighSpeedSoundMaxPitch; + float skydive_freefallHighSpeedSoundMinGroundSpeed; + float skydive_freefallHighSpeedSoundMaxGroundSpeed; + float skydive_freefallHighSpeedSoundMinFallSpeed; + float skydive_freefallHighSpeedSoundMaxFallSpeed; + float skydive_deployHorizontalDrag; + float skydive_deployVerticalDrag; + void* /*CinematicMotionDef*/ skydive_canopyCinematicMotion; + float skydive_canopyThrottleTrackSpeed; + float skydive_canopyAnimTrackSpeedThrottle; + float skydive_canopyAnimTrackSpeedStrafe; + float skydive_canopyAnimTrackSpeedYaw; + float skydive_canopyAnimTrackSpeedPitch; + float skydive_canopyAnimMinWeight; + float skydive_canopyAnimMaxWeight; + float skydive_canopyAnimMinPlayRate; + float skydive_canopyAnimMaxPlayRate; + float skydive_canopyAnimSpeedForMinWeight; + float skydive_canopyAnimSpeedForMaxWeight; + float skydive_canopyTopGroundSpeed; + float skydive_canopyMinPitch; + float skydive_canopyMaxPitch; + float skydive_canopyPitchSpeed; + float skydive_canopyYawSpeed; + float skydive_canopyCrossSectionalArea; + float skydive_canopyLookHorizForceMin; + float skydive_canopyLookHorizForceMax; + RumbleGraph* skydive_canopyLookHorizForceGraph; + float skydive_canopyStickHorizForceMin; + float skydive_canopyStickHorizForceMax; + RumbleGraph* skydive_canopyStickHorizForceGraph; + float skydive_canopyDragCoefHoriz; + float skydive_canopyLookHorizDragCoeff; + RumbleGraph* skydive_canopyLookHorizDragGraph; + float skydive_canopyStickHorizDragCoeff; + RumbleGraph* skydive_canopyStickHorizDragGraph; + float skydive_canopyDragCoefVert; + float skydive_canopyLookVertDragCoeff; + RumbleGraph* skydive_canopyLookVertDragGraph; + float skydive_canopyStickVertDragIncreasePerc; + RumbleGraph* skydive_canopyStickVertDragIncreaseGraph; + float skydive_canopyStickVertDragReductionPerc; + RumbleGraph* skydive_canopyStickVertDragReductionGraph; + float skydive_canopyStickSidewaysForce; + float skydive_canopyMaxBrakeForce; + float skydive_canopyMinTurnMultiplier; + float skydive_canopyMaxTurnMultiplier; + RumbleGraph* skydive_canopyTurnMultiplierGraph; + float skydive_canopyTurnMultiplierMinScale; + float skydive_canopyTurnMultiplierMaxScale; + RumbleGraph* skydive_canopyTurnMultiplierPitchGraph; + SndAliasLookup skydive_canopyAmbientSound; + float skydive_canopyAmbientSoundGroundSpeedWeight; + float skydive_canopyAmbientSoundMinVolume; + float skydive_canopyAmbientSoundMaxVolume; + float skydive_canopyAmbientSoundMinPitch; + float skydive_canopyAmbientSoundMaxPitch; + float skydive_canopyAmbientSoundMinGroundSpeed; + float skydive_canopyAmbientSoundMaxGroundSpeed; + float skydive_canopyAmbientSoundMinFallSpeed; + float skydive_canopyAmbientSoundMaxFallSpeed; + SndAliasLookup skydive_canopyHighSpeedSound; + float skydive_canopyHighSpeedSoundGroundSpeedWeight; + float skydive_canopyHighSpeedSoundMinVolume; + float skydive_canopyHighSpeedSoundMaxVolume; + float skydive_canopyHighSpeedSoundMinPitch; + float skydive_canopyHighSpeedSoundMaxPitch; + float skydive_canopyHighSpeedSoundMinGroundSpeed; + float skydive_canopyHighSpeedSoundMaxGroundSpeed; + float skydive_canopyHighSpeedSoundMinFallSpeed; + float skydive_canopyHighSpeedSoundMaxFallSpeed; + float skydive_wmAnimFreefallPitchMin; + float skydive_wmAnimFreefallPitchMax; + float skydive_wmAnimFreefallPitchTrackSpeed; + float skydive_wmAnimFreefallRollTrackSpeed; + float skydive_wmAnimFreefallRollReturnSpeed; + RumbleGraph* skydive_wmAnimFreefallLeftStickXToRollGraph; + RumbleGraph* skydive_wmAnimFreefallRightStickXToRollGraph; + float skydive_camFreefallHeightOffset; + RumbleGraph* skydive_camFreefallPitchToDistanceGraph; + RumbleGraph* skydive_camFreefallPitchToForwardOffsetGraph; + float skydive_camParachuteHeightOffset; + RumbleGraph* skydive_camParachutePitchToDistanceGraph; + RumbleGraph* skydive_camParachutePitchToForwardOffsetGraph; + RumbleGraph* skydive_camParachutePitchToModelPitchForwardOffsetGraph; + RumbleGraph* skydive_camParachutePitchToModelRollSideOffsetGraph; + RumbleGraph* skydive_camParachutePitchToModelRollUpOffsetGraph; + float skydive_camParachuteBlendInTime; + SndAliasLookup nvg_blindSound; + float dlcFloat[8]; +}; + +struct SuitAnimPackage +{ + const char* name; + void* /*SuitAnimPerWeapClass*/ animOverrides; +}; + +struct CameraFirstPersonProfileDef +{ + bool applyOffset; + vec3_t offsetTranslation; + bool disableFOVWeaponOffset; + float cameraAnimationTransScale; + float cameraAnimationRotScale; + float handheldCameraTransScale; + float handheldCameraRotScale; + float handheldCameraImpulseTransScale; + float handheldCameraImpulseRotScale; +}; + +struct CameraOrbitProfileDef +{ + float lerpSpeed; + vec3_t pivotOffset; + float initialAzimuth; + float initialPolar; + float polarMin; + float polarMax; + float range; + float returnAzimuthSpeed; + float returnPolarSpeed; + float easeInFactor; + float returnTimeTo; + float turningSpeedPolar; + float turningSpeedAzimuth; + float traceCollRadius; + float mouseInputMultiplier; + float rollContrib; + float pitchContrib; + int buttonToggleReturn; + int buttonCyclePerspective; + int buttonRecenter; + bool initialReturn; + bool returnAzimuth; + bool returnPolar; + float alignToMovement; + bool interpolateFocus; + bool cameraReturnOnGas; + float cameraReturnOnSpeed; + float yawTurnAdjust; +}; + +struct CameraSentryDroneDef +{ + float range; + float thresHitToSpeedUp; + float speedUpFactor; + float lerpSpeedEye; + float lerpSpeedFocus; + float lerpSpeedUp; + float focusTraceLen; + float eyeHeight; + float horizontalOffset; + float upOffsetFactorIncl; +}; + +struct CameraKillCamVehicleDef +{ + float lookAtRadius; + float fov; + float distBack; + float distUp; + float distBackRadiusMod; + float distUpRadiusMod; + float fovRadiusMod; + float sideMag; + float traceCollRad; +}; + +struct CameraTransitionDef +{ + bool active; + float time; + float timewaitEyepos; + float timewaitAxis; + int /*CameraTransitionCurve*/ curveEyepos; + int /*CameraTransitionCurve*/ curveAxis; +}; + +struct CameraDef +{ + const char* name; + int /*CameraProfile*/ profile; + bool keepShakeCam; + bool serverFeedback; + bool behaveAsRemoteCont; + bool interpolateViewTransition; + bool overrideFOV; + float FOV; + int /*LensProfileMode*/ overrideLensProfile; + float lensFocalLength; + float lensFStop; + float lensScale; + float lensUVScale; + bool overrideRadialBlur; + float radialBlurRadius; + float radialBlurStrength; + bool overrideZPlanes; + float zPlaneVMNear; + float zPlaneSceneNear; + CameraFirstPersonProfileDef firstPerson; + CameraOrbitProfileDef orbit; + CameraSentryDroneDef sentryDrone; + CameraKillCamVehicleDef kcamVeh; + CameraTransitionDef transitionIn; + CameraTransitionDef transitionOut; + vec3_t fpveh_offsetLs; + float fpveh_offsetYaw; + float fpveh_offsetPitch; + float fpveh_rollContrib; + float fpveh_rollMax; + bool fpveh_freeLook; + bool fpveh_freeLookReturn; + bool dlcBool[1]; + bool fadeOutPlayerOnTransitionIn; +}; + +struct HudOutlineDef +{ + const char* name; + unsigned __int8 outlineType; + bool drawInStencil; + bool drawNonOccludedPixels; + bool drawOccludedPixels; + bool drawFill; + bool fadeOverTimeEnable; + bool fadeOverTimeLooping; + unsigned __int8 fadeOverTimeCurveType; + float fadeOverTimeMinAlpha; + float fadeOverTimeMaxAlphaTime; + float fadeOverTimeMinAlphaTime; + float fadeOverTimeInTime; + float fadeOverTimeOutTime; + bool distanceFadeEnable; + float distanceFadeMinAlpha; + float distanceFadeStartDistance; + float distanceFadeEndDistance; + unsigned int outlineColor; + int outlineWidth; + bool drawOnLocalPlayerCharacter; + bool drawOnVehicleOccupants; + bool drawOnLocalPlayerVehicleOccupants; + bool drawOnLocalPlayerVehicle; + bool dlcBool0; + bool dlcBool1; + bool dlcBool2; + bool dlcBool3; + bool dlcBool4; + bool dlcBool5; + float dlcFloat0; + float dlcFloat1; + float dlcFloat2; + float dlcFloat3; + float dlcFloat4; + float dlcFloat5; +}; + +struct SpaceshipTargetDef +{ + const char* name; + scr_string_t targetTag; + float annotationOffsetX; + float annotationOffsetY; + float annotationOffsetZ; + bool disableLeading; + float lock_minDistance; + float lock_maxDistance; + float lock_cutoffDistance; + float lock_minRate; + float lock_maxRate; + float lock_maxZoomFOV; + float lock_followDistance; + float lockCooldown_rate; + float aa_closeDistance; + float aa_farDistance; + float aa_closeMinAngle; + float aa_closeMaxAngle; + float aa_closeBlendMax; + float aa_farMinAngle; + float aa_farMaxAngle; + float aa_farBlendMax; + float aaLocked_closeDistance; + float aaLocked_farDistance; + float aaLocked_closeMinAngle; + float aaLocked_closeMaxAngle; + float aaLocked_closeBlendMax; + float aaLocked_farMinAngle; + float aaLocked_farMaxAngle; + float aaLocked_farBlendMax; + float pilotAssistScale; + float callout_maxDistance; + float callout_maxAngle; +}; + +struct __declspec(align(8)) RumbleInfo +{ + const char* name; + int duration; + float range; + RumbleGraph* highRumbleGraph; + RumbleGraph* lowRumbleGraph; + RumbleGraph* leftTriggerRumbleGraph; + RumbleGraph* rightTriggerRumbleGraph; + bool swapTriggerRumblesOnLefty; + bool panTriggerRumbles; + bool fadeWithDistance; + bool broadcast; +}; + +struct __declspec(align(8)) RumbleGraph +{ + const char* name; + vec2_t knots[16]; + unsigned __int16 knotCount; +}; + +struct LocalizeEntry +{ + const char* name; + const char* value; +}; + +struct StaticModelCollisionInstance +{ + vec3_t origin; + vec3_t angles; + float scale; +}; + +struct XModelDetailCollision +{ + const char* name; + unsigned int physicsLODDataSize; + char* physicsLODData; + unsigned int physicsLODDataNameCount; + scr_string_t* physicsLODDataNames; +}; + +struct StaticModelCollisionModel +{ + scr_string_t name; + PhysicsAsset* physicsAsset; + XModelDetailCollision* detailCollision; + unsigned int numInstances; + StaticModelCollisionInstance* instances; +}; + +struct __declspec(align(8)) StaticModelCollisionModelList +{ + unsigned int numModels; + StaticModelCollisionModel* models; + unsigned int structureMemoryCost; +}; + +struct PhysicsCapacities +{ + int maxNumRigidBodiesServer; + int maxNumDetailRigidBodiesServer; + int maxNumConstraintsServer; + int maxNumMotionsServer; + int maxNumRigidBodiesClient; + int maxNumDetailRigidBodiesClient; + int maxNumConstraintsClient; + int maxNumMotionsClient; +}; + +struct SpawnPointEntityRecord +{ + unsigned __int16 index; + scr_string_t name; + scr_string_t target; + scr_string_t script_noteworthy; + vec3_t origin; + vec3_t angles; +}; + +struct SpawnPointRecordList +{ + unsigned __int16 spawnsCount; + SpawnPointEntityRecord* spawns; +}; + +struct ClientMapTriggers +{ + unsigned int count; + uintptr_t models; + unsigned int hullCount; + uintptr_t hulls; + unsigned int slabCount; + uintptr_t slabs; +}; + +struct ClientTriggers +{ + ClientMapTriggers trigger; + unsigned int triggerStringLength; + char* triggerString; + __int16* visionSetTriggers; + unsigned __int16* triggerType; + vec3_t* origins; + float* scriptDelay; + float* priority; + __int16* audioTriggers; + __int16* blendLookup; + __int16* npcTriggers; + __int16* audioStateIds; + uintptr_t detailSoundBank; + uintptr_t audioRvbPanInfo; + __int16* parent; + uintptr_t linkTo; + uintptr_t spatialTree; +}; + +struct ClientTriggerBlend +{ + unsigned __int16 numClientTriggerBlendNodes; + uintptr_t blendNodes; +}; + +struct SplinePointEntityRecord +{ + int splineId; + int splineNodeId; + scr_string_t splineNodeLabel; + scr_string_t targetname; + scr_string_t target; + scr_string_t string; + float speed; + float splineNodeTension; + vec3_t origin; + vec3_t angles; + float throttle; + vec2_t corridorDims; + vec3_t tangent; + float distToNextNode; + vec3_t positionCubic[4]; + vec3_t tangentQuadratic[3]; +}; + +struct SplinePointRecordList +{ + unsigned __int16 splinePointCount; + float splineLength; + SplinePointEntityRecord* splinePoints; +}; + +struct SplineRecordList +{ + unsigned __int16 splineCount; + SplinePointRecordList* splines; +}; + +struct __declspec(align(8)) cmodel_t +{ + Bounds bounds; + float radius; + uintptr_t physicsAsset; + unsigned __int16 physicsShapeOverrideIdx; + unsigned __int16 navObstacleIdx; + unsigned int edgeFirstIndex; + unsigned int edgeTotalCount; +}; + +struct MapEdgeList +{ + const char* name; + vec3_t mins; + vec3_t maxs; + unsigned int transientIndex; + unsigned int dynamicQueryTypes; + unsigned int staticQueryTypes; + unsigned int numDynamicEdges; + unsigned int numStaticEdges; + bool valid; + unsigned int numEdges; + vec4_t(*edges)[2]; + uintptr_t edgeMetadata; + unsigned int numEdgeOctrees; + uintptr_t edgeOctrees; + unsigned int numEdgeOctreeNodeSet; + uintptr_t edgeOctreeNodeSets; + unsigned int numEdgeIndices; + unsigned int* edgeIndices; + unsigned int numEdgeAdjacencyMetadata; + uintptr_t edgeAdjacencyMetadata; + unsigned int numEdgeAdjacency; + uintptr_t edgeAdjacency; +}; + +struct __declspec(align(4)) CM_ClientModel +{ + vec3_t spawnOrigin; + vec3_t spawnAngles; + const XModel* model; + scr_string_t animationTreeName; + XAnimParts* animation; + scr_string_t name; + bool noPhysics; + bool noCloth; +}; + +struct __declspec(align(8)) MapEnts +{ + const char* name; + char* entityString; + int numEntityChars; + unsigned __int8 field_14; + unsigned __int8 field_15; + unsigned __int8 field_16; + unsigned __int8 field_17; + MapTriggers trigger; + ClientTriggers clientTrigger; + ClientTriggerBlend clientTriggerBlend; + SpawnPointRecordList spawnList; + SplineRecordList splineList; + unsigned int havokEntsShapeDataSize; + unsigned __int8 field_14C; + unsigned __int8 field_14D; + unsigned __int8 field_14E; + unsigned __int8 field_14F; + char* havokEntsShapeData; + int numSubModels; + unsigned __int8 field_15C; + unsigned __int8 field_15D; + unsigned __int8 field_15E; + unsigned __int8 field_15F; + cmodel_t* cmodels; + unsigned __int8 field_168; + unsigned __int8 field_169; + unsigned __int8 field_16A; + unsigned __int8 field_16B; + int numEdgeLists; + MapEdgeList** edgeLists; + uintptr_t edgeListSpatialTree; + int numClientModels; + unsigned __int8 field_184; + unsigned __int8 field_185; + unsigned __int8 field_186; + unsigned __int8 field_187; + CM_ClientModel* clientModels; + unsigned __int8 field_190; + unsigned __int8 field_191; + unsigned __int8 field_192; + unsigned __int8 field_193; + unsigned __int8 field_194; + unsigned __int8 field_195; + unsigned __int8 field_196; + unsigned __int8 field_197; + unsigned __int8 field_198; + unsigned __int8 field_199; + unsigned __int8 field_19A; + unsigned __int8 field_19B; + int dynEntityListsCount[2]; + __declspec(align(8)) unsigned __int8 field_1A8; + unsigned __int8 field_1A9; + unsigned __int8 field_1AA; + unsigned __int8 field_1AB; + unsigned __int8 field_1AC; + unsigned __int8 field_1AD; + unsigned __int8 field_1AE; + unsigned __int8 field_1AF; + unsigned __int8 field_1B0; + unsigned __int8 field_1B1; + unsigned __int8 field_1B2; + unsigned __int8 field_1B3; + unsigned __int8 field_1B4; + unsigned __int8 field_1B5; + unsigned __int8 field_1B6; + unsigned __int8 field_1B7; + unsigned __int8 field_1B8; + unsigned __int8 field_1B9; + unsigned __int8 field_1BA; + unsigned __int8 field_1BB; + unsigned __int8 field_1BC; + unsigned __int8 field_1BD; + unsigned __int8 field_1BE; + unsigned __int8 field_1BF; + unsigned __int8 field_1C0; + unsigned __int8 field_1C1; + unsigned __int8 field_1C2; + unsigned __int8 field_1C3; + unsigned __int8 field_1C4; + unsigned __int8 field_1C5; + unsigned __int8 field_1C6; + unsigned __int8 field_1C7; + uintptr_t dynEntSpatialPopulation[2]; + uintptr_t dynEntSpatialTransientMap[2]; + unsigned __int8 field_1E8; + unsigned __int8 field_1E9; + unsigned __int8 field_1EA; + unsigned __int8 field_1EB; + int clientEntAnchorCount; + uintptr_t clientEntAnchors; + unsigned __int8 scriptableMapEnts; + unsigned __int8 field_1F9; + unsigned __int8 field_1FA; + unsigned __int8 field_1FB; + unsigned __int8 field_1FC; + unsigned __int8 field_1FD; + unsigned __int8 field_1FE; + unsigned __int8 field_1FF; + unsigned __int8 field_200; + unsigned __int8 field_201; + unsigned __int8 field_202; + unsigned __int8 field_203; + unsigned __int8 field_204; + unsigned __int8 field_205; + unsigned __int8 field_206; + unsigned __int8 field_207; + unsigned __int8 field_208; + unsigned __int8 field_209; + unsigned __int8 field_20A; + unsigned __int8 field_20B; + unsigned __int8 field_20C; + unsigned __int8 field_20D; + unsigned __int8 field_20E; + unsigned __int8 field_20F; + unsigned __int8 field_210; + unsigned __int8 field_211; + unsigned __int8 field_212; + unsigned __int8 field_213; + unsigned __int8 field_214; + unsigned __int8 field_215; + unsigned __int8 field_216; + unsigned __int8 field_217; + unsigned __int8 field_218; + unsigned __int8 field_219; + unsigned __int8 field_21A; + unsigned __int8 field_21B; + unsigned __int8 field_21C; + unsigned __int8 field_21D; + unsigned __int8 field_21E; + unsigned __int8 field_21F; + unsigned __int8 field_220; + unsigned __int8 field_221; + unsigned __int8 field_222; + unsigned __int8 field_223; + unsigned __int8 field_224; + unsigned __int8 field_225; + unsigned __int8 field_226; + unsigned __int8 field_227; + unsigned __int8 field_228; + unsigned __int8 field_229; + unsigned __int8 field_22A; + unsigned __int8 field_22B; + unsigned __int8 field_22C; + unsigned __int8 field_22D; + unsigned __int8 field_22E; + unsigned __int8 field_22F; + unsigned __int8 field_230; + unsigned __int8 field_231; + unsigned __int8 field_232; + unsigned __int8 field_233; + unsigned __int8 field_234; + unsigned __int8 field_235; + unsigned __int8 field_236; + unsigned __int8 field_237; + unsigned __int8 field_238; + unsigned __int8 field_239; + unsigned __int8 field_23A; + unsigned __int8 field_23B; + unsigned __int8 field_23C; + unsigned __int8 field_23D; + unsigned __int8 field_23E; + unsigned __int8 field_23F; + unsigned __int8 field_240; + unsigned __int8 field_241; + unsigned __int8 field_242; + unsigned __int8 field_243; + unsigned __int8 field_244; + unsigned __int8 field_245; + unsigned __int8 field_246; + unsigned __int8 field_247; + unsigned __int8 field_248; + unsigned __int8 field_249; + unsigned __int8 field_24A; + unsigned __int8 field_24B; + unsigned __int8 field_24C; + unsigned __int8 field_24D; + unsigned __int8 field_24E; + unsigned __int8 field_24F; + unsigned __int8 field_250; + unsigned __int8 field_251; + unsigned __int8 field_252; + unsigned __int8 field_253; + unsigned __int8 field_254; + unsigned __int8 field_255; + unsigned __int8 field_256; + unsigned __int8 field_257; + unsigned __int8 field_258; + unsigned __int8 field_259; + unsigned __int8 field_25A; + unsigned __int8 field_25B; + unsigned __int8 field_25C; + unsigned __int8 field_25D; + unsigned __int8 field_25E; + unsigned __int8 field_25F; + unsigned __int8 field_260; + unsigned __int8 field_261; + unsigned __int8 field_262; + unsigned __int8 field_263; + unsigned __int8 field_264; + unsigned __int8 field_265; + unsigned __int8 field_266; + unsigned __int8 field_267; + unsigned __int8 field_268; + unsigned __int8 field_269; + unsigned __int8 field_26A; + unsigned __int8 field_26B; + unsigned __int8 field_26C; + unsigned __int8 field_26D; + unsigned __int8 field_26E; + unsigned __int8 field_26F; + unsigned __int8 field_270; + unsigned __int8 field_271; + unsigned __int8 field_272; + unsigned __int8 field_273; + unsigned __int8 field_274; + unsigned __int8 field_275; + unsigned __int8 field_276; + unsigned __int8 field_277; + unsigned __int8 field_278; + unsigned __int8 field_279; + unsigned __int8 field_27A; + unsigned __int8 field_27B; + unsigned __int8 field_27C; + unsigned __int8 field_27D; + unsigned __int8 field_27E; + unsigned __int8 field_27F; + unsigned __int8 field_280; + unsigned __int8 field_281; + unsigned __int8 field_282; + unsigned __int8 field_283; + unsigned __int8 field_284; + unsigned __int8 field_285; + unsigned __int8 field_286; + unsigned __int8 field_287; + unsigned __int8 field_288; + unsigned __int8 field_289; + unsigned __int8 field_28A; + unsigned __int8 field_28B; + unsigned __int8 field_28C; + unsigned __int8 field_28D; + unsigned __int8 field_28E; + unsigned __int8 field_28F; + unsigned __int8 field_290; + unsigned __int8 field_291; + unsigned __int8 field_292; + unsigned __int8 field_293; + unsigned __int8 field_294; + unsigned __int8 field_295; + unsigned __int8 field_296; + unsigned __int8 field_297; + unsigned __int8 field_298; + unsigned __int8 field_299; + unsigned __int8 field_29A; + unsigned __int8 field_29B; + unsigned __int8 field_29C; + unsigned __int8 field_29D; + unsigned __int8 field_29E; + unsigned __int8 field_29F; + unsigned __int8 field_2A0; + unsigned __int8 field_2A1; + unsigned __int8 field_2A2; + unsigned __int8 field_2A3; + unsigned __int8 field_2A4; + unsigned __int8 field_2A5; + unsigned __int8 field_2A6; + unsigned __int8 field_2A7; + unsigned __int8 field_2A8; + unsigned __int8 field_2A9; + unsigned __int8 field_2AA; + unsigned __int8 field_2AB; + unsigned __int8 field_2AC; + unsigned __int8 field_2AD; + unsigned __int8 field_2AE; + unsigned __int8 field_2AF; + unsigned __int8 field_2B0; + unsigned __int8 field_2B1; + unsigned __int8 field_2B2; + unsigned __int8 field_2B3; + unsigned __int8 field_2B4; + unsigned __int8 field_2B5; + unsigned __int8 field_2B6; + unsigned __int8 field_2B7; + unsigned __int8 field_2B8; + unsigned __int8 field_2B9; + unsigned __int8 field_2BA; + unsigned __int8 field_2BB; + unsigned __int8 field_2BC; + unsigned __int8 field_2BD; + unsigned __int8 field_2BE; + unsigned __int8 field_2BF; + unsigned __int8 field_2C0; + unsigned __int8 field_2C1; + unsigned __int8 field_2C2; + unsigned __int8 field_2C3; + unsigned __int8 field_2C4; + unsigned __int8 field_2C5; + unsigned __int8 field_2C6; + unsigned __int8 field_2C7; + unsigned __int8 field_2C8; + unsigned __int8 field_2C9; + unsigned __int8 field_2CA; + unsigned __int8 field_2CB; + unsigned __int8 field_2CC; + unsigned __int8 field_2CD; + unsigned __int8 field_2CE; + unsigned __int8 field_2CF; + unsigned __int8 field_2D0; + unsigned __int8 field_2D1; + unsigned __int8 field_2D2; + unsigned __int8 field_2D3; + unsigned __int8 field_2D4; + unsigned __int8 field_2D5; + unsigned __int8 field_2D6; + unsigned __int8 field_2D7; + unsigned __int8 field_2D8; + unsigned __int8 field_2D9; + unsigned __int8 field_2DA; + unsigned __int8 field_2DB; + unsigned __int8 field_2DC; + unsigned __int8 field_2DD; + unsigned __int8 field_2DE; + unsigned __int8 field_2DF; + unsigned __int8 field_2E0; + unsigned __int8 field_2E1; + unsigned __int8 field_2E2; + unsigned __int8 field_2E3; + unsigned __int8 field_2E4; + unsigned __int8 field_2E5; + unsigned __int8 field_2E6; + unsigned __int8 field_2E7; + unsigned __int8 field_2E8; + unsigned __int8 field_2E9; + unsigned __int8 field_2EA; + unsigned __int8 field_2EB; + unsigned __int8 field_2EC; + unsigned __int8 field_2ED; + unsigned __int8 field_2EE; + unsigned __int8 field_2EF; + unsigned __int8 field_2F0; + unsigned __int8 field_2F1; + unsigned __int8 field_2F2; + unsigned __int8 field_2F3; + unsigned __int8 field_2F4; + unsigned __int8 field_2F5; + unsigned __int8 field_2F6; + unsigned __int8 field_2F7; + unsigned __int8 field_2F8; + unsigned __int8 field_2F9; + unsigned __int8 field_2FA; + unsigned __int8 field_2FB; + unsigned __int8 field_2FC; + unsigned __int8 field_2FD; + unsigned __int8 field_2FE; + unsigned __int8 field_2FF; + unsigned __int8 field_300; + unsigned __int8 field_301; + unsigned __int8 field_302; + unsigned __int8 field_303; + unsigned __int8 field_304; + unsigned __int8 field_305; + unsigned __int8 field_306; + unsigned __int8 field_307; + unsigned __int8 field_308; + unsigned __int8 field_309; + unsigned __int8 field_30A; + unsigned __int8 field_30B; + unsigned __int8 field_30C; + unsigned __int8 field_30D; + unsigned __int8 field_30E; + unsigned __int8 field_30F; + unsigned __int8 field_310; + unsigned __int8 field_311; + unsigned __int8 field_312; + unsigned __int8 field_313; + unsigned __int8 field_314; + unsigned __int8 field_315; + unsigned __int8 field_316; + unsigned __int8 field_317; + unsigned __int8 field_318; + unsigned __int8 field_319; + unsigned __int8 field_31A; + unsigned __int8 field_31B; + unsigned __int8 field_31C; + unsigned __int8 field_31D; + unsigned __int8 field_31E; + unsigned __int8 field_31F; + unsigned __int8 field_320; + unsigned __int8 field_321; + unsigned __int8 field_322; + unsigned __int8 field_323; + unsigned __int8 field_324; + unsigned __int8 field_325; + unsigned __int8 field_326; + unsigned __int8 field_327; + unsigned __int8 field_328; + unsigned __int8 field_329; + unsigned __int8 field_32A; + unsigned __int8 field_32B; + unsigned __int8 field_32C; + unsigned __int8 field_32D; + unsigned __int8 field_32E; + unsigned __int8 field_32F; + unsigned __int8 field_330; + unsigned __int8 field_331; + unsigned __int8 field_332; + unsigned __int8 field_333; + unsigned __int8 field_334; + unsigned __int8 field_335; + unsigned __int8 field_336; + unsigned __int8 field_337; + unsigned __int8 field_338; + unsigned __int8 field_339; + unsigned __int8 field_33A; + unsigned __int8 field_33B; + unsigned __int8 field_33C; + unsigned __int8 field_33D; + unsigned __int8 field_33E; + unsigned __int8 field_33F; + unsigned __int8 field_340; + unsigned __int8 field_341; + unsigned __int8 field_342; + unsigned __int8 field_343; + unsigned __int8 field_344; + unsigned __int8 field_345; + unsigned __int8 field_346; + unsigned __int8 field_347; + unsigned __int8 field_348; + unsigned __int8 field_349; + unsigned __int8 field_34A; + unsigned __int8 field_34B; + unsigned __int8 field_34C; + unsigned __int8 field_34D; + unsigned __int8 field_34E; + unsigned __int8 field_34F; + unsigned __int8 field_350; + unsigned __int8 field_351; + unsigned __int8 field_352; + unsigned __int8 field_353; + unsigned __int8 field_354; + unsigned __int8 field_355; + unsigned __int8 field_356; + unsigned __int8 field_357; + unsigned __int8 field_358; + unsigned __int8 field_359; + unsigned __int8 field_35A; + unsigned __int8 field_35B; + unsigned __int8 field_35C; + unsigned __int8 field_35D; + unsigned __int8 field_35E; + unsigned __int8 field_35F; + unsigned __int8 field_360; + unsigned __int8 field_361; + unsigned __int8 field_362; + unsigned __int8 field_363; + unsigned __int8 field_364; + unsigned __int8 field_365; + unsigned __int8 field_366; + unsigned __int8 field_367; + unsigned __int8 field_368; + unsigned __int8 field_369; + unsigned __int8 field_36A; + unsigned __int8 field_36B; + unsigned __int8 field_36C; + unsigned __int8 field_36D; + unsigned __int8 field_36E; + unsigned __int8 field_36F; + unsigned __int8 field_370; + unsigned __int8 field_371; + unsigned __int8 field_372; + unsigned __int8 field_373; + unsigned __int8 field_374; + unsigned __int8 field_375; + unsigned __int8 field_376; + unsigned __int8 field_377; + unsigned __int8 field_378; + unsigned __int8 field_379; + unsigned __int8 field_37A; + unsigned __int8 field_37B; + unsigned __int8 field_37C; + unsigned __int8 field_37D; + unsigned __int8 field_37E; + unsigned __int8 field_37F; + unsigned __int8 field_380; + unsigned __int8 field_381; + unsigned __int8 field_382; + unsigned __int8 field_383; + unsigned __int8 field_384; + unsigned __int8 field_385; + unsigned __int8 field_386; + unsigned __int8 field_387; + unsigned __int8 field_388; + unsigned __int8 field_389; + unsigned __int8 field_38A; + unsigned __int8 field_38B; + unsigned __int8 field_38C; + unsigned __int8 field_38D; + unsigned __int8 field_38E; + unsigned __int8 field_38F; + unsigned __int8 field_390; + unsigned __int8 field_391; + unsigned __int8 field_392; + unsigned __int8 field_393; + unsigned __int8 field_394; + unsigned __int8 field_395; + unsigned __int8 field_396; + unsigned __int8 field_397; + unsigned __int8 field_398; + unsigned __int8 field_399; + unsigned __int8 field_39A; + unsigned __int8 field_39B; + unsigned __int8 field_39C; + unsigned __int8 field_39D; + unsigned __int8 field_39E; + unsigned __int8 field_39F; + unsigned __int8 field_3A0; + unsigned __int8 field_3A1; + unsigned __int8 field_3A2; + unsigned __int8 field_3A3; + unsigned __int8 field_3A4; + unsigned __int8 field_3A5; + unsigned __int8 field_3A6; + unsigned __int8 field_3A7; + unsigned __int8 field_3A8; + unsigned __int8 field_3A9; + unsigned __int8 field_3AA; + unsigned __int8 field_3AB; + unsigned __int8 field_3AC; + unsigned __int8 field_3AD; + unsigned __int8 field_3AE; + unsigned __int8 field_3AF; + unsigned __int8 field_3B0; + unsigned __int8 field_3B1; + unsigned __int8 field_3B2; + unsigned __int8 field_3B3; + unsigned __int8 field_3B4; + unsigned __int8 field_3B5; + unsigned __int8 field_3B6; + unsigned __int8 field_3B7; + unsigned __int8 field_3B8; + unsigned __int8 field_3B9; + unsigned __int8 field_3BA; + unsigned __int8 field_3BB; + unsigned __int8 field_3BC; + unsigned __int8 field_3BD; + unsigned __int8 field_3BE; + unsigned __int8 field_3BF; + unsigned __int8 field_3C0; + unsigned __int8 field_3C1; + unsigned __int8 field_3C2; + unsigned __int8 field_3C3; + unsigned __int8 field_3C4; + unsigned __int8 field_3C5; + unsigned __int8 field_3C6; + unsigned __int8 field_3C7; + unsigned __int8 field_3C8; + unsigned __int8 field_3C9; + unsigned __int8 field_3CA; + unsigned __int8 field_3CB; + unsigned __int8 field_3CC; + unsigned __int8 field_3CD; + unsigned __int8 field_3CE; + unsigned __int8 field_3CF; + unsigned __int8 field_3D0; + unsigned __int8 field_3D1; + unsigned __int8 field_3D2; + unsigned __int8 field_3D3; + unsigned __int8 field_3D4; + unsigned __int8 field_3D5; + unsigned __int8 field_3D6; + unsigned __int8 field_3D7; + unsigned __int8 field_3D8; + unsigned __int8 field_3D9; + unsigned __int8 field_3DA; + unsigned __int8 field_3DB; + unsigned __int8 field_3DC; + unsigned __int8 field_3DD; + unsigned __int8 field_3DE; + unsigned __int8 field_3DF; + unsigned __int8 field_3E0; + unsigned __int8 field_3E1; + unsigned __int8 field_3E2; + unsigned __int8 field_3E3; + unsigned __int8 field_3E4; + unsigned __int8 field_3E5; + unsigned __int8 field_3E6; + unsigned __int8 field_3E7; + unsigned __int8 field_3E8; + unsigned __int8 field_3E9; + unsigned __int8 field_3EA; + unsigned __int8 field_3EB; + unsigned __int8 field_3EC; + unsigned __int8 field_3ED; + unsigned __int8 field_3EE; + unsigned __int8 field_3EF; + unsigned __int8 field_3F0; + unsigned __int8 field_3F1; + unsigned __int8 field_3F2; + unsigned __int8 field_3F3; + unsigned __int8 field_3F4; + unsigned __int8 field_3F5; + unsigned __int8 field_3F6; + unsigned __int8 field_3F7; + unsigned __int8 field_3F8; + unsigned __int8 field_3F9; + unsigned __int8 field_3FA; + unsigned __int8 field_3FB; + unsigned __int8 field_3FC; + unsigned __int8 field_3FD; + unsigned __int8 field_3FE; + unsigned __int8 field_3FF; + unsigned __int8 field_400; + unsigned __int8 field_401; + unsigned __int8 field_402; + unsigned __int8 field_403; + unsigned __int8 field_404; + unsigned __int8 field_405; + unsigned __int8 field_406; + unsigned __int8 field_407; +}; + + +struct CollisionHeatmapEntry +{ + int vertexCount; + float vertexDensity; + vec3_t minExtent; + vec3_t maxExtent; +}; + +struct Stage +{ + const char* name; + vec3_t origin; + unsigned __int16 triggerIndex; + unsigned __int8 sunPrimaryLightIndex; + unsigned int entityUID; + vec3_t skyRotationAngles; +}; + +struct __declspec(align(8)) clipMap_t +{ + const char* name; + int isInUse; + unsigned int numStaticModelCollisionModelLists; + StaticModelCollisionModelList* staticModelCollisionModelLists; + MapEnts* mapEnts; + Stage* stages; + unsigned __int8 stageCount; + MapTriggers stageTrigger; + vec3_t broadphaseMin; + vec3_t broadphaseMax; + PhysicsCapacities physicsCapacities; + unsigned int havokWorldShapeDataSize; + char* havokWorldShapeData; + unsigned int numCollisionHeatmapEntries; + CollisionHeatmapEntry* collisionHeatmap; + unsigned int totalGlassInitPieceCount; + unsigned int totalGlassPieceLimit; + uintptr_t topDownMapData; + const char* visionSetName; + unsigned int checksum; +}; + +struct __declspec(align(8)) WeaponDef +{ + const char* szOverlayName; + XModel* gunXModel; + XModel* gunXModelLeftHand; + XModel* gunXModelRightHand; + XModel* defaultViewModel; + XModel* defaultWorldModelLeftHand; + XModel* defaultWorldModelRightHand; + XModel* worldModel; + XModel* worldXModelLeftHand; + XModel* worldXModelRightHand; + XModel* defaultWorldModel; + XModel* censorshipWorldModel; + XModel* censorshipWorldModelLeftHand; + XModel* censorshipWorldModelRightHand; + XModel* playerShadowModel; + XModel* playerShadowModelLeftHand; + XModel* playerShadowModelRightHand; + XModel* handXModel; + WeaponAnimPackage* szXAnims; + WeaponAnimPackage* szXAnimsRightHanded; + WeaponAnimPackage* szXAnimsLeftHanded; + XAnimParts* turretRaiseAnim; + XAnimParts* turretIdleAnim; + XAnimParts* turretFireAnim; + WeaponDamageInfo damageInfo; + int iFireTime; + int iFireDelay; + int iFireTimeAkimbo; + int iFireDelayAkimbo; + float sprintOutTimerScale; + const char* szModeName; + scr_string_t* notetrackRumbleMapKeys; + scr_string_t* notetrackRumbleMapValues; + scr_string_t* notetrackFXMapKeys; + FxCombinedDef* notetrackFXMapValues; + scr_string_t* notetrackFXMapTagValues; + int playerAnimType; + int scriptedAnimEvent; + int scriptedAnimType; + int weapType; + int weapClass; + int penetrateType; + int inventoryType; + int fireType; + int turretFireType; + int burstCount; + int targetAssistType; + int targetAssistBehavior; + float targetAssistRange; + float targetAssistAngle; + float targetAssistLosOffsetForward; + float targetAssistLosOffsetRight; + float targetAssistLosOffsetUp; + bool targetAssistOnlyAvailableInAds; + int reloadType; + float burstFireCooldown; + bool burstFireAuto; + float viewPitchMaxSpeed; + float viewYawMaxSpeed; + bool alignBarrelWithTurretBody; + bool keepOrientationOnExit; + float kickBackForceMultiplier; + bool autoAdjust; + bool networkLODRangeOverride; + float networkLODRangeOverrideDistance; + int offhandClass; + int stance; + WeaponVFXPackage* vfxPackage; + WeaponSFXPackage* sfxPackage; + bool disableBreathOffhand; + int reticleType; + int hitmarkerType; + Material* reticleCenter; + Material* reticleSide; + Material* reticleOnePiece; + int iReticleCenterSize; + int iReticleSideSize; + int iReticleMinOfs; + bool reticleCenterPulse; + int iReticleShakeDuration; + int iReticleSettleDuration; + int iReticleNumBulletsToRapidFire; + int activeReticleType; + bool useTurretViewmodelAnims; + bool useTurret3pIK; + int turret3pAnimType; + float turretFireAnimMinTime; + vec3_t vStandOfs; + vec3_t vStandOfsRot; + vec3_t vStandOfsRotPivot; + vec3_t vStandMove; + vec3_t vStandRot; + vec3_t strafeMove; + vec3_t strafeRot; + int hipOffsetLerpType; + vec3_t vDuckedOfs; + vec3_t vDuckedOfsRot; + vec3_t vDuckedOfsRotPivot; + vec3_t vDuckedMove; + vec3_t vDuckedRot; + vec3_t vProneOfs; + vec3_t vProneMove; + vec3_t vProneRot; + float adsForwardOffset; + float adsRoll; + float fPosMoveRate; + float fPosProneMoveRate; + float fStandMoveMinSpeed; + float fDuckedMoveMinSpeed; + float fProneMoveMinSpeed; + float fPosRotRate; + float fPosProneRotRate; + float fDuckedOfsRotRate; + float fStandRotMinSpeed; + float fDuckedRotMinSpeed; + float fProneRotMinSpeed; + float fReticleShakeMagnitude; + float fReticleRapidFireMultiplier; + XModel* worldClipModel; + XModel* rocketModel; + GfxImage* hudIcon; + GfxImage* pickupIcon; + GfxImage* dangerIconImg; + GfxImage* throwBackIconImg; + Material* dangerIconMat; + Material* throwBackIconMat; + bool hideWarningIcons; + float warningIconsDelay; + int ammoCounterClip; + int iStartAmmo; + int iPerkStartAmmo; + int iPerkMaxAmmo; + const char* szAmmoName; + int iAmmoIndex; + int iMaxAmmo; + int shotCount; + const char* szSharedAmmoCapName; + int iSharedAmmoCapIndex; + int iSharedAmmoCap; + int iAmmoUsedPerShot; + bool requireAmmoUsedPerShot; + bool disableNoAmmoWarning; + float lowAmmoWarningThreshold; + int lowAmmoWarningCount; + int iDamageType; + int iMeleeDamage; + int iMeleeCountToFinisher; + bool hasMeleeFinisher; + float autoAimRange; + float aimAssistRange; + float aimAssistRangeAds; + float aimAssistPitchSlowdown; + float aimAssistPitchSlowdownAds; + float aimAssistYawSlowdown; + float aimAssistYawSlowdownAds; + float aimAssistLockonStrength; + float aimPadding; + float enemyCrosshairRange; + float moveSpeedScale; + float adsMoveSpeedScale; + float sprintDurationScale; + float sprintRestoreDelay; + ADSOverlay overlay; + int overlayInterface; + float fAdsBobFactor; + float fAdsViewBobMult; + float fAdsGunBobPitchScale; + float fAdsGunBobYawScale; + float fAdsGunBobTiltPitchScale; + float fAdsGunBobTiltYawScale; + float fAdsGunBobTiltRollScale; + float fAdsGunBobTiltBulletDirScale; + float fAdsGunBobTiltOffset; + float fAdsGunBobCrouchFactor; + float adsCrouchViewKickFactor; + float adsCrouchGunKickFactor; + float adsProneViewKickFactor; + float adsProneGunKickFactor; + float fHipSpreadStandMin; + float fHipSpreadDuckedMin; + float fHipSpreadProneMin; + float hipSpreadSprintMin; + float hipSpreadInAirMin; + float hipSpreadStandMax; + float hipSpreadDuckedMax; + float hipSpreadProneMax; + float hipSpreadSprintMax; + float hipSpreadInAirMax; + float fHipSpreadDecayRate; + float fHipSpreadFireAdd; + float fHipSpreadTurnAdd; + float fHipSpreadMoveAdd; + float fHipSpreadDuckedDecay; + float fHipSpreadProneDecay; + float hipSpreadSprintDecay; + float hipSpreadInAirDecay; + float fHipReticleSidePos; + float fAdsIdleAmount; + float fHipIdleAmount; + float adsIdleSpeed; + float hipIdleSpeed; + float fIdleCrouchFactor; + float fIdleProneFactor; + float fGunMaxPitch; + float fGunMaxYaw; + float fViewMaxPitch; + float fViewMaxYaw; + float adsIdleLerpStartTime; + float adsIdleLerpTime; + bool useUninterruptedAdsIdleMotion; + bool disableInputDrivenViewReturnDampening; + float slideSpreadMin; + float slideSpreadMax; + float slideSpreadDecayRate; + float slideSpreadFireAdd; + float slideSpreadTurnAdd; + SwaySettings swaySettings; + float adsFireRateScale; + float adsDamageRangeScale; + float adsFireAnimFrac; + float fireTimerLerpToAdsScale; + bool alwaysFireAtMaxRangeInAds; + bool adsAlignEnabled; + bool disableTagAlignX; + vec3_t adsAlignOffset; + int adsAlignOffsetLerpType; + int adsAlignLerpType; + float adsMovementAnimLerpStart; + float adsMovementAnimLerpEnd; + float dualWieldViewModelOffset; + float fScopeDriftDelay; + float fScopeDriftLerpInTime; + float fScopeDriftSteadyTime; + float fScopeDriftLerpOutTime; + float fScopeDriftSteadyFactor; + float fScopeDriftUnsteadyFactor; + int killIconRatio; + int iReloadAmmoAdd; + int iReloadStartAdd; + bool reloadTwoRound; + int ammoDropStockMin; + int ammoDropClipPercentMin; + int ammoDropClipPercentMax; + float cameraShakeScale; + int cameraShakeDuration; + float cameraShakeRadius; + int iExplosionRadius; + int iExplosionRadiusMin; + int iExplosionForceRadius; + int iExplosionInnerDamage; + int iExplosionOuterDamage; + float explosionForceScalar; + float damageConeAngle; + float bulletExplDmgMultMin; + float bulletExplDmgMult; + float bulletExplRadiusMult; + int iProjectileSpeed; + int iProjectileSpeedUp; + int iProjectileSpeedForward; + int iProjectileActivateDist; + int iProjectileDetonationRadius; + float projLifetime; + float projLifetimeStdDeviation; + float timeToAccelerate; + float projectileCurvature; + XModel* projectileModel; + int projExplosion; + FxCombinedDef projExplosionEffect; + FxCombinedDef projDudEffect; + FxCombinedDef projTimeoutEffect; + int iExplosionSteppedRadiusInner; + int iExplosionSteppedRadiusMid; + int iExplosionSteppedRadiusOuter; + int iExplosionSteppedDamageInner; + int iExplosionSteppedDamageMid; + int iExplosionSteppedDamageOuter; + float* parallelBounce; + float* perpendicularBounce; + FxCombinedDef vmProjBodyEffect; + FxCombinedDef projBodyEffect; + FxCombinedDef projTrailEffect; + FxCombinedDef projBeaconEffect; + vec3_t vProjectileColor; + int guidedMissileType; + float maxSteeringAccel; + int projIgnitionDelay; + FxCombinedDef projIgnitionEffect; + float fAdsAimPitch; + float adsInCrosshairAlphaStart; + float adsInCrosshairAlphaEnd; + float adsOutCrosshairAlphaStart; + float adsOutCrosshairAlphaEnd; + bool adsShouldShowCrosshair; + float fAdsGunKickPitchMin; + float fAdsGunKickPitchMax; + float fAdsGunKickYawMin; + float fAdsGunKickYawMax; + float fAdsGunKickMagMin; + float fAdsGunKickAccel; + float fAdsGunKickSpeedMax; + float fAdsGunKickSpeedDecay; + float fAdsGunKickStaticDecay; + float fAdsViewKickPitchMin; + float fAdsViewKickPitchMax; + float fAdsViewKickYawMin; + float fAdsViewKickYawMax; + float fAdsViewKickMagMin; + float fAdsViewScatterMin; + float fAdsViewScatterMax; + float fAdsSpread; + float fAdsSpreadNVG; + float adsSpreadStartFrac; + float adsSpreadEndFrac; + int iVisibilityAxis; + float fVisibilityUpOffset; + float fHipGunKickPitchMin; + float fHipGunKickPitchMax; + float fHipGunKickYawMin; + float fHipGunKickYawMax; + float fHipGunKickMagMin; + float fHipGunKickAccel; + float fHipGunKickSpeedMax; + float fHipGunKickSpeedDecay; + float fHipGunKickStaticDecay; + float fHipViewKickPitchMin; + float fHipViewKickPitchMax; + float fHipViewKickYawMin; + float fHipViewKickYawMax; + float fHipViewKickMagMin; + float fHipViewScatterMin; + float fHipViewScatterMax; + float multipleReloadClipPercentage; + float hipStartingGunKickPercent; + float hipStartingViewKickPercent; + int adsStartingKickBullets; + float adsStartingGunKickPercent; + float adsStartingViewKickPercent; + float hipEndingGunKickPercent; + float hipEndingViewKickPercent; + int adsEndingKickBullets; + float adsEndingGunKickPercent; + float adsEndingViewKickPercent; + float kickAlignedInputScalar; + float kickOpposedInputScalar; + float viewKickMaintainFraction; + float adsGunTiltPitchFactor; + float adsGunTiltYawFactor; + float adsGunTiltRollFactor; + float adsGunTiltOffset; + float hipGunTiltPitchFactor; + float hipGunTiltYawFactor; + float hipGunTiltRollFactor; + float hipGunTiltOffset; + bool useNewViewKick; + bool useNewGunKick; + bool useAngularViewKick; + bool useAngularGunKick; + float hipAngularViewKickDir[6]; + float hipAngularViewKickDev[6]; + float hipAngularViewKickStrengthMin[6]; + float hipAngularViewKickStrengthMax[6]; + float hipAngularViewKickPitchScale[6]; + float adsAngularViewKickDir[6]; + float adsAngularViewKickDev[6]; + float adsAngularViewKickStrengthMin[6]; + float adsAngularViewKickStrengthMax[6]; + float adsAngularViewKickPitchScale[6]; + int adsAngularViewKickBullet[6]; + bool adsAngularViewKickUseSet[6]; + float hipAngularGunKickDir[6]; + float hipAngularGunKickDev[6]; + float hipAngularGunKickStrengthMin[6]; + float hipAngularGunKickStrengthMax[6]; + float hipAngularGunKickPitchScale[6]; + float adsAngularGunKickDir[6]; + float adsAngularGunKickDev[6]; + float adsAngularGunKickStrengthMin[6]; + float adsAngularGunKickStrengthMax[6]; + float adsAngularGunKickPitchScale[6]; + int adsAngularGunKickBullet[6]; + bool adsAngularGunKickUseSet[6]; + float hipViewKickReturnAccelScale; + float adsViewKickReturnAccelScale; + float hipViewKickReturnSpeedCurveScale; + float adsViewKickReturnSpeedCurveScale; + float hipGunKickReturnAccelScale; + float adsGunKickReturnAccelScale; + float hipGunKickReturnSpeedCurveScale; + float adsGunKickReturnSpeedCurveScale; + float hipSpreadStandMoveMax; + float hipSpreadDuckedMoveMax; + float hipSpreadProneMoveMax; + float hipSpreadSprintMoveMax; + float hipSpreadInAirMoveMax; + float slideSpreadMoveMax; + WeaponOffsetCurveDescription weaponOffsetCurveHoldFireSlow; + WeaponOffsetCurveDescription weaponOffsetCurveHoldFireFast; + WeaponOffsetCurveDescription weaponOffsetCurveAds; + WeaponOffsetCurveDescription weaponOffsetCurveAlwaysOn; + WeaponOffsetCurveDescription weaponOffsetCurveKick; + WeaponOffsetCurveDescription weaponOffsetCurveSnapDecay; + int numWeaponOffsetPatterns; + WeaponOffsetPatternDescription* weaponOffsetPatterns; + int numWeaponOffsetPatternsKickOrSnapDecay; + WeaponOffsetPatternDescription** weaponOffsetPatternsKickOrSnapDecay; + float fightDist; + float maxDist; + const char* accuracyGraphName[2]; + vec2_t* originalAccuracyGraphKnots[2]; + unsigned __int16 originalAccuracyGraphKnotCount[2]; + int iPositionReloadTransTime; + float leftArc; + float rightArc; + float topArc; + float bottomArc; + float visualPitchLimitTop; + float visualPitchLimitBottom; + bool softLeftRightArc; + float accuracy; + float aiSpread; + float playerSpread; + float minTurnSpeed[2]; + float maxTurnSpeed[2]; + float pitchConvergenceTime; + float yawConvergenceTime; + float suppressTime; + float suppressTimeTargetKilled; + float aiReturnToDefaultSpeed[2]; + float maxRange; + float fAnimHorRotateInc; + float fPlayerPositionDist; + const char* szUseHintString; + const char* dropHintString; + unsigned int iUseHintStringIndex; + unsigned int dropHintStringIndex; + float horizViewJitter; + float vertViewJitter; + bool enableViewBounceFire; + float viewBounceFireDecay; + float viewBounceFireFrequency; + float viewBounceFirePitchScale; + float viewBounceFireRollScale; + float scanSpeed; + float scanAccel; + int scanPauseTime; + const char* szScript; + float adsSpeedMs[2]; + float adsAccelSec[2]; + bool deferDamageToParentVehicle; + bool useSteppedExplosionDamage; + float destabilizationRateTime; + float destabilizationCurvatureMax; + int destabilizeDistance; + float robotechMaxPitch; + float robotechMaxYaw; + float robotechFrequency; + float robotechVariancePitch; + float robotechVarianceYaw; + float robotechVarianceFrequency; + float* locationDamageMultipliers; + unsigned __int8* hitLocPriorityMap; + float unittypeMultipliers[7]; + RumbleInfo* fireRumble; + RumbleInfo* meleeImpactRumble; + float heatAccumulationPerShot; + float heatDissipationPerSecond; + float heatSmokeStartThreshold; + float heatSmokeStopThreshold; + bool heatIsOpenBolt; + int tracerStyle; + TracerDef* tracerType; + TracerDef* overchargeTracerType; + LaserDef* laserTypeViewModel; + LaserDef* laserTypeViewModelAlt; + LaserDef* laserTypeFriendly; + LaserDef* laserTypeEnemy; + bool turretADSEnabled; + float turretADSTime; + float turretFov; + float turretFovADS; + float turretScopeZoomRate; + float turretScopeZoomMin; + float turretScopeZoomMax; + float turretOverheatPenalty; + SndAliasLookup turretOverheatSound; + FxCombinedDef turretOverheatEffect; + RumbleInfo* turretBarrelSpinRumble; + float turretBarrelSpinSpeed; + float turretBarrelSpinUpTime; + float turretBarrelSpinDownTime; + SndAliasLookup turretBarrelSpinMaxSnd; + SndAliasLookup turretBarrelSpinUpSnd[4]; + SndAliasLookup turretBarrelSpinDownSnd[4]; + SndAliasLookup missileConeSoundAlias; + SndAliasLookup missileConeSoundAliasAtBase; + float missileConeSoundRadiusAtTop; + float missileConeSoundRadiusAtBase; + float missileConeSoundHeight; + float missileConeSoundOriginOffset; + float missileConeSoundVolumescaleAtCore; + float missileConeSoundVolumescaleAtEdge; + float missileConeSoundVolumescaleCoreSize; + float missileConeSoundPitchAtTop; + float missileConeSoundPitchAtBottom; + float missileConeSoundPitchTopSize; + float missileConeSoundPitchBottomSize; + float missileConeSoundCrossfadeTopSize; + float missileConeSoundCrossfadeBottomSize; + bool meleeOverrideValues; + float aim_automelee_lerp; + float aim_automelee_region_height; + float aim_automelee_region_width; + float aim_automelee_maxPitchMovement; + float aim_automelee_maxYawMovement; + float player_meleeHeight; + float player_meleeWidth; + float playerMeleeRangeStanding; + float playerMeleeRangeCrouched; + float playerMeleeRangeProne; + float playerMeleeRangeChargeStanding; + float playerMeleeRangeChargeCrouched; + float playerMeleeChargeHeightTolerance; + bool shieldAllowFiring; + int shieldMaxSpeed; + bool shieldAlwaysDisplay; + Gesture* shieldDeployGesture; + Gesture* shieldFireWeapGesture; + Gesture* shieldDeployWhileFiring; + Gesture* shieldRetractWhileFiring; + Gesture* shieldBashGesture; + FxCombinedDef shieldMeleeFx; + float shieldMeleeFxDelay; + float HitEarthquakeScale; + float HitEarthquakeDuration; + float HitEarthquakeRadius; + RumbleInfo* shieldHitRumble; + float MissEarthquakeScale; + float MissEarthquakeDuration; + float MissEarthquakeRadius; + RumbleInfo* shieldMissRumble; + int shieldDeployButton; + bool shieldUsesEnergy; + float shieldMaxEnergy; + float shieldConsumptionRate; + float shieldMeleeEnergyCost; + float shieldMeleeHitEnergyCost; + float reactiveMotionRadiusScale; + float reactiveMotionFrequencyScale; + float reactiveMotionAmplitudeScale; + float reactiveMotionFalloff; + float reactiveMotionLifetime; + unsigned __int8 transientBaseViewFlags; + unsigned __int8 transientBaseWorldFlags; + bool hasAnyTransientModels; + bool blendFireAnimations; + bool sharedAmmo; + bool lockonSupported; + bool requireLockonToFire; + bool isAirburstWeapon; + bool bigExplosion; + bool noAdsWhenMagEmpty; + bool avoidDropCleanup; + bool allowGrenadeSwitching; + bool inheritsPerks; + bool forceUse; + bool ladderWeapon; + bool executionVictimHiddenWeapon; + bool crosshairColorChange; + bool bRifleBullet; + bool bEnergyBullet; + bool bIncendiaryBullet; + bool armorPiercing; + bool impaling; + bool bBoltAction; + bool aimDownSight; + bool canHoldBreath; + bool meleeOnly; + bool supportsAlternateMelee; + bool bRechamberWhileAds; + bool reloadWhileAds; + bool bBulletExplosiveDamage; + bool bCookOffHold; + bool overCookIsNotLethal; + bool reticleSpin45; + bool bClipOnly; + bool bDoesNotConsumeAmmo; + bool bRemoveWeaponOnEmpty; + bool noAmmoPickup; + bool adsFireOnly; + bool cancelAutoHolsterWhenEmpty; + bool disableSwitchToWhenEmpty; + bool suppressAmmoPrimaryDisplay; + bool suppressAmmoReserveDisplay; + LaserSettings laserSettings; + bool markableViewmodel; + bool isPredictedProjectile; + int clientTrajectoryBlendOutTime; + int serverTrajectoryBlendInTime; + int dualWieldType; + bool flipKillIcon; + bool bNoPartialReload; + bool reloadDisabled; + bool blocksProne; + bool silenced; + bool doNotSuppressAI; + bool isRollingGrenade; + bool dropGrenadeHeldOnDeath; + bool projExplosionEffectForceNormalUp; + bool projExplosionEffectInheritParentDirection; + bool bProjImpactExplode; + bool spawnProjAtMuzzle; + bool correctBulletTrajectory; + float maxCorrectionAngle; + bool disableProjectileCrumpleCheck; + bool bProjTrajectoryEvents; + bool bProjWhizByEnabled; + bool stickToPlayers; + bool stickToVehicles; + bool stickToTurrets; + bool stickToNonStick; + bool projEnableMissileStickiness; + bool enableMissileRicochet; + bool thrownSideways; + bool disableFiring; + bool firesOnWeaponSwitch; + bool disableHolding; + bool timedDetonation; + float missileRicochetMinAngleOfIncidence; + float missileCrumpleMinSpeed; + int detonateType; + XModel* detonatorWorldModel; + int explosiveDamageDelay; + int fuseTime; + int aiFuseTime; + int maxHoldTime; + GrenadeRotationParams rotationParams; + bool holdButtonToThrow; + bool autoHold; + bool infiniteHold; + bool freezeMovementWhenFiring; + bool offhandAllowsSprint; + bool thermalScope; + bool thermalToggle; + bool outlineEnemies; + bool outlineDepthTest; + bool outlineFill; + float enemyOutlineR; + float enemyOutlineG; + float enemyOutlineB; + float enemyOutlineA; + float allyOutlineR; + float allyOutlineG; + float allyOutlineB; + float allyOutlineA; + bool depthScan; + float depthScanThickness; + float depthScanR; + float depthScanG; + float depthScanB; + float depthScanA; + float depthScanOutlineThickness; + float depthScanOutlineR; + float depthScanOutlineG; + float depthScanOutlineB; + float depthScanOutlineA; + bool depthScanOverlay; + float depthScanOverlayStrength; + float depthScanOverlayXTiles; + float depthScanOverlayYTiles; + float depthScanOverlayXScroll; + float depthScanOverlayYScroll; + float blurSceneAdsInFraction; + float blurSceneAdsOutFraction; + bool altModeSameWeapon; + bool playAltGesturesForOffhandWeapons; + bool turretBarrelSpinEnabled; + bool missileConeSoundEnabled; + bool missileConeSoundPitchshiftEnabled; + bool missileConeSoundCrossfadeEnabled; + bool offhandHoldIsCancelable; + bool doNotAllowAttachmentsToOverrideSpread; + bool useScopeDrift; + bool alwaysShatterGlassOnImpact; + bool jumpSpread; + bool noFullViewmodelAnimations; + float killcamOffset; + bool useDualFOV; + bool showViewModelInDualFOV; + bool syncedFOVInDualFOV; + bool disableDrop; + bool preferredDrop; + Gesture* gestureAnimation; + float gestureFireStateTime; + Gesture* gesturePullback; + Gesture* gesturePullbackAlt; + float minPullbackTime; + float minPullbackToThrowBlendTime; + float maxPullbackToThrowBlendTime; + Gesture* gestureThrow; + Gesture* gestureThrowAlt; + float gestureFireTime; + Gesture* gestureDetonate; + Gesture* gestureDetonateAlt; + float gestureDetonationTime; + bool gesturesDisablePrimary; + FxCombinedDef cameraFireEffect; + float cameraFireEffectDurationSec; + float changedFireTime; + float changedFireTimeAkimbo; + int changedFireTimeNumBullets; + int chargeType; + float chargeGain; + float chargeCostPerShot; + float chargeLossWhenIdle; + float chargeEmptyCooldown; + float chargeFireAtMaxDamageMultiplier; + int chargeMeterEffectBoneCount; + FxCombinedDef chargeMeterEffect; + SndAliasLookup chargeUpSound; + SndAliasLookup chargeDownSound; + SndAliasLookup chargeUpSoundPlayer; + SndAliasLookup chargeDownSoundPlayer; + SndAliasLookup chargeDownToUpSound; + SndAliasLookup chargeDownToUpSoundPlayer; + SndAliasLookup chargeUpToDownSound; + SndAliasLookup chargeUpToDownSoundPlayer; + SndAliasLookup chargeMaxSound; + SndAliasLookup chargeMaxSoundPlayer; + bool chargeHudReveal; + RumbleInfo* chargeRumble; + scr_string_t stowTag; + XModel* stowOffsetModel; + scr_string_t stowOffsetAttachTag; + int slot; + float maxTargetAngle; + bool spaceshipSecondaryWeapon; + float impulseFieldRadius; + float impulseFieldInitialSpeed; + float impulseFieldMaxSpeed; + float impulseFieldAcceleration; + float impulseFieldInAirImpulseMultiplier; + float impulseFieldInAirImpulseMultiplierInterpTime; + float impulseFieldSlideMultiplier; + float impulseFieldSlideMultiplierInterpTime; + bool impulseFieldIsPush; + bool impulseFieldAffectsFriendlies; + bool impulseFieldAffectsSelf; + bool impulseFieldAffectsProne; + bool regenerationEnabled; + int regenerationTimeMs; + int regenerationAddTimeMs; + int regenerationAmount; + bool regenerationConsumeStock; + bool regenerationDisableWhileFiring; + int deployType; + bool deployRequireOnWalkableSurface; + bool deployRequireOnNavmesh; + bool deployRequireSkyAbove; + bool deployRequireNoOverhang; + bool deployAlwaysUpright; + bool deployEdgeSnap; + float deployCylinderRadius; + float deployCylinderHeight; + float deployMaxDistance; + float deployMaxHeightAboveEye; + float deployEffectHeightOffset; + float deployMaxSlope; + FxCombinedDef deployEffect; + int deployValidGroupId; + int deployIndoorGroupId; + int deployInvalidGroupId; + int deployOutOfRangeGroupId; + int numAnimOverrides; + AnimOverride* animOverrides; + CarryAnimOverride carryAnimOverrides[5]; + int numSfxOverrides; + SFXOverride* sfxOverrides; + int numVfxOverrides; + VFXOverride* vfxOverrides; + float reactiveEmitterDelay; + float grenadeDangerIconDistance; + float bulletDirGunAngleModifierIdleHip; + float bulletDirGunAngleModifierIdleAds; + float bulletDirGunAngleModifierGunKickHip; + float bulletDirGunAngleModifierGunKickAds; + float bulletDirGunAngleModifierGunTiltHip; + float bulletDirGunAngleModifierGunTiltAds; + float viewClampPitchCatchUpTimeSec; + float viewClampYawCatchUpTimeSec; + bool mountTopEnable; + bool mountTopYawClamp; + float mountTopYawMax; + float mountTopGunKickScale; + float mountTopGunCenterScale; + float mountTopViewKickScale; + float mountTopViewCenterScale; + float mountTopGunIdleMotionScale; + float mountTopViewIdleMotionScale; + int mountTopEnterDurationMs; + int mountTopExitDurationMs; + float mountTopEdgeToEyeDistanceForward; + float mountTopEdgeToEyeDistanceAbove; + bool mountSideEnable; + bool mountSideTransitionEnable; + float mountSideRoll; + float mountSideRollStartFrac; + float mountSideRollEndFrac; + float mountSideGunKickScale; + float mountSideGunCenterScale; + float mountSideViewKickScale; + float mountSideViewCenterScale; + float mountSideGunIdleMotionScale; + float mountSideViewIdleMotionScale; + int mountSideEnterDurationMs; + int mountSideExitDurationMs; + float mountSideEdgeToEyeDistanceForward; + float mountSideEdgeToEyeDistanceAbove; + float mountViewmodelOffset; + float mountFOVScale; + RumbleInfo* mountRumble; + WeaponOffsetPatternScaleInfo mountWeaponOffsetPatternScaleInfo; + float adsFireMotionBlur; + int adsFireMotionBlurDurationMs; + float adsFireMotionBlurDecayExponent; + float hipFireMotionBlur; + int hipFireMotionBlurDurationMs; + float hipFireMotionBlurDecayExponent; + float adsCameraShakeRotationScale; + float adsCameraShakeTranslationScale; + AdvancedIdleSettings advancedIdleSettings; + WeaponOffsetPatternScaleInfo crouchedWeaponOffsetPatternScaleInfo; + WeaponOffsetPatternScaleInfo proneWeaponOffsetPatternScaleInfo; + BallisticInfo ballisticInfo; + WeaponEntityNotify* notifyTypes[2]; + float dlcFloat[6]; + bool dlcBool[3]; + bool enableWeaponInspect; + bool stowedOcclusionTestEnabled; + bool ignoreMinTracerSpawnDistance; + bool tracerOverrideEnabled; + bool boltActionReloadIncludesRechamber; +}; + + +struct WeaponCompleteDef +{ + const char* szInternalName; + WeaponDef weapDef; + const char* szDisplayName; + const char* szLootTable; + scr_string_t* hideTags; + AttachmentList attachments[14]; + unsigned int numLootVariants; + unsigned int numNotetrackSoundMappings; + scr_string_t* notetrackSoundMapKeys; + scr_string_t* notetrackSoundMapValues; + unsigned int numNotetrackOverrides; + void* /*NoteTrackToSoundEntry*/ notetrackOverrides; + unsigned int numNotetrackSuitEntries; + void* /*NoteTrackToSuitSoundEntry*/ notetrackSuitEntries; + ZoomSettings zoomSettings; + int iAdsTransInTime; + int iAdsTransOutTime; + int iAdsTransInToOutTime; + int iAdsTransOutToInTime; + int iClipSize; + int vfxImpactType; + float penetrateMultiplier; + float fAdsViewKickCenterSpeed; + float fHipViewKickCenterSpeed; + Material* killIconMat; + Material* dpadIconMat; + Material* dpadIconInactiveMat; + GfxImage* killIconImg; + GfxImage* dpadIconImg; + GfxImage* dpadIconInactiveImg; + int ammoDropStockMax; + bool useSceneDof; + float adsDofPhysicalFstop; + float adsDofPhysicalFocusDistance; + bool adsDofPhysicalFocalTag; + float adsDofPhysicalReloadFstop; + float adsDofPhysicalReloadFocusDistance; + unsigned __int16 accuracyGraphKnotCount[2]; + vec2_t* accuracyGraphKnots[2]; + bool enhanced; + bool dpadIconShowsAmmo; + bool luiWeaponInfoWidgetUsesScopeStencil; + const char* szAltModeInactiveName; + const char* dynamicIconAnimationName; + bool isUsingDynamicIcon; + const char* szLUIWeaponInfoWidgetName; + const char* szLUIWeaponInfoWidgetTag; + const char* szLUICrosshairWidget; +}; + +union XAssetHeader +{ + //PhysicsLibrary* physicsLibrary; + //PhysicsSFXEventAsset* physicsSFXEventAsset; + //PhysicsVFXEventAsset* physicsVFXEventAsset; + PhysicsAsset* physicsAsset; + //PhysicsFXPipeline* physicsFXPipeline; + //PhysicsFXShape* physicsFXShape; + //PhysicsDebugData* physicsDebugData; + //XAnimParts* parts; + //XModelSurfs* modelSurfs; + XModel* model; + //MayhemData* mayhem; + Material* material; + //ComputeShader* computeShader; + //MaterialSerializedShader* serializedShader; + //MaterialTechniqueSet* techniqueSet; + GfxImage* image; + //SndGlobals* soundGlobals; + //SndBankResident* soundBankResident; + //SndBankTransient* soundBankTransient; + clipMap_t* clipMap; + //ComWorld* comWorld; + //GlassWorld* glassWorld; + //PathData* pathData; + //NavMeshData* navMeshData; + //TacticalGraphData* tacGraphData; + MapEnts* mapEnts; + //FxWorld* fxWorld; + //GfxWorld* gfxWorld; + //GfxWorldTransientZone* gfxWorldTransientZone; + //GfxIESProfile* iesProfile; + //GfxLightDef* lightDef; + //GfxGradingClut* gradingClut; + //GfxFogSpline* fogSpline; + //AnimationClass* animClass; + //PlayerAnimScript* playerAnim; + Gesture* gesture; + LocalizeEntry* localize; + //WeaponAttachment* attachment; + WeaponCompleteDef* weapon; + //ParticleSystemDef* vfx; + //FxImpactTable* impactFx; + SurfaceFxTable* surfaceFx; + RawFile* rawfile; + ScriptFile* scriptfile; + ScriptDebugData* scriptDebugData; + StringTable* stringTable; + LeaderboardDef* leaderboardDef; + VirtualLeaderboardDef* virtualLeaderboardDef; + DDLFile* ddlFile; + TracerDef* tracerDef; + VehicleDef* vehDef; + AddonMapEnts* addonMapEnts; + NetConstStrings* netConstStrings; + LuaFile* luaFile; + ScriptableDef* scriptable; + EquipmentSoundTable* equipSndTable; + VectorField* vectorField; + FxParticleSimAnimation* particleSimAnimation; + StreamingInfo* streamingInfo; + LaserDef* laserDef; + TTFDef* ttfDef; + SuitDef* suitDef; + SuitAnimPackage* suitAnimPackage; + CameraDef* cameraDef; + HudOutlineDef* hudOutlineDef; + SpaceshipTargetDef* spaceshipTargetDef; + RumbleInfo* rumble; + RumbleGraph* rumbleGraph; + //WeaponAnimPackage* weaponAnimPackage; + //WeaponSFXPackage* weaponSFXPackage; + //WeaponVFXPackage* weaponVFXPackage; + //FootstepVFX* footstepVFX; + //BehaviorTree* behaviorTree; + //Animset* animset; + //ASM* asmAsset; + //XAnimProceduralBones* proceduralBones; + //XAnimDynamicBones* dynamicBones; + //ReticleDef* reticleDef; + //XAnimCurve* xanimCurve; + //CoverSelector* coverSelector; + //EnemySelector* enemySelector; + //ClientCharacter* clientCharacter; + //ClothAsset* clothAsset; + //CinematicMotionDef* cinematicMotion; + //AccessoryDef* accessory; + //LocDmgTable* locDmgTable; + //BulletPenetration* bulletPenetration; + //ScriptBundle* scriptBundle; + //BlendSpace2DDef* blendSpace2DDef; + //XCam* xcam; + //Camo* camo; + //XCompositeModelDef* compositeModel; + //XModelDetailCollision* modelDetailCollision; + //StreamKey* streamKey; + //StreamTreeOverride* streamTreeOverride; + //KeyValuePairs* keyValuePairs; + //StTerrain* stTerrain; + //NativeScriptPatchFile* nativeScriptPatch; + //CollisionTile* collisionTile; + //ExecutionDef* executionDef; + //CarryObjectDef* carryObjectDef; + //SoundBankListDef* soundBankListDef; + //GfxDecalVolumeMaterial* decalVolumeMaterial; + //GfxDecalVolumeMask* decalVolumeMask; + //DynEntityList* dynEntityList; + void* data; + //FxWorldTransientZone* fxWorldTransientZone; + //DLogSchema* dlogSchema; + //MapEdgeList* mapEdgeList; +}; + +enum XAssetType +{ + ASSET_TYPE_PHYSICSLIBRARY = 0x0, + ASSET_TYPE_PHYSICSSFXEVENTASSET = 0x1, + ASSET_TYPE_PHYSICSVFXEVENTASSET = 0x2, + ASSET_TYPE_PHYSICSASSET = 0x3, + ASSET_TYPE_PHYSICSFXPIPELINE = 0x4, + ASSET_TYPE_PHYSICSFXSHAPE = 0x5, + ASSET_TYPE_PHYSICSDEBUGDATA = 0x6, + ASSET_TYPE_XANIM = 0x7, + ASSET_TYPE_XMODELSURFS = 0x8, + ASSET_TYPE_XMODEL = 0x9, + ASSET_TYPE_MAYHEM = 0xA, + ASSET_TYPE_MATERIAL = 0xB, + ASSET_TYPE_COMPUTESHADER = 0xC, + ASSET_TYPE_LIBSHADER = 0xD, + ASSET_TYPE_VERTEXSHADER = 0xE, + ASSET_TYPE_HULLSHADER = 0xF, + ASSET_TYPE_DOMAINSHADER = 0x10, + ASSET_TYPE_PIXELSHADER = 0x11, + ASSET_TYPE_TECHSET = 0x12, + ASSET_TYPE_IMAGE = 0x13, + ASSET_TYPE_SOUNDGLOBALS = 0x14, + ASSET_TYPE_SOUNDBANK = 0x15, + ASSET_TYPE_SOUNDBANKTRANSIENT = 0x16, + ASSET_TYPE_COL_MAP = 0x17, + ASSET_TYPE_COM_MAP = 0x18, + ASSET_TYPE_GLASS_MAP = 0x19, + ASSET_TYPE_AIPATHS = 0x1A, + ASSET_TYPE_NAVMESH = 0x1B, + ASSET_TYPE_TACGRAPH = 0x1C, + ASSET_TYPE_MAP_ENTS = 0x1D, + ASSET_TYPE_FX_MAP = 0x1E, + ASSET_TYPE_GFX_MAP = 0x1F, + ASSET_TYPE_GFX_MAP_TRZONE = 0x20, + ASSET_TYPE_IESPROFILE = 0x21, + ASSET_TYPE_LIGHTDEF = 0x22, + ASSET_TYPE_GRADINGCLUT = 0x23, + ASSET_TYPE_UI_MAP = 0x24, + ASSET_TYPE_FOGSPLINE = 0x25, + ASSET_TYPE_ANIMCLASS = 0x26, + ASSET_TYPE_PLAYERANIM = 0x27, + ASSET_TYPE_GESTURE = 0x28, + ASSET_TYPE_LOCALIZE = 0x29, + ASSET_TYPE_ATTACHMENT = 0x2A, + ASSET_TYPE_WEAPON = 0x2B, + ASSET_TYPE_VFX = 0x2C, + ASSET_TYPE_IMPACTFX = 0x2D, + ASSET_TYPE_SURFACEFX = 0x2E, + ASSET_TYPE_AITYPE = 0x2F, + ASSET_TYPE_MPTYPE = 0x30, + ASSET_TYPE_CHARACTER = 0x31, + ASSET_TYPE_XMODELALIAS = 0x32, + ASSET_TYPE_RAWFILE = 0x33, + ASSET_TYPE_SCRIPTFILE = 0x34, + ASSET_TYPE_SCRIPTDEBUGDATA = 0x35, + ASSET_TYPE_STRINGTABLE = 0x36, + ASSET_TYPE_LEADERBOARDDEF = 0x37, + ASSET_TYPE_VIRTUALLEADERBOARDDEF = 0x38, + ASSET_TYPE_DDL = 0x39, + ASSET_TYPE_TRACER = 0x3A, + ASSET_TYPE_VEHICLE = 0x3B, + ASSET_TYPE_ADDON_MAP_ENTS = 0x3C, + ASSET_TYPE_NETCONSTSTRINGS = 0x3D, + ASSET_TYPE_LUAFILE = 0x3E, + ASSET_TYPE_SCRIPTABLE = 0x3F, + ASSET_TYPE_EQUIPSNDTABLE = 0x40, + ASSET_TYPE_VECTORFIELD = 0x41, + ASSET_TYPE_PARTICLESIMANIMATION = 0x42, + ASSET_TYPE_STREAMINGINFO = 0x43, + ASSET_TYPE_LASER = 0x44, + ASSET_TYPE_TTF = 0x45, + ASSET_TYPE_SUIT = 0x46, + ASSET_TYPE_SUITANIMPACKAGE = 0x47, + ASSET_TYPE_CAMERA = 0x48, + ASSET_TYPE_HUDOUTLINE = 0x49, + ASSET_TYPE_SPACESHIPTARGET = 0x4A, + ASSET_TYPE_RUMBLE = 0x4B, + ASSET_TYPE_RUMBLEGRAPH = 0x4C, + ASSET_TYPE_ANIMPKG = 0x4D, + ASSET_TYPE_SFXPKG = 0x4E, + ASSET_TYPE_VFXPKG = 0x4F, + ASSET_TYPE_FOOTSTEPVFX = 0x50, + ASSET_TYPE_BEHAVIORTREE = 0x51, + ASSET_TYPE_AIANIMSET = 0x52, + ASSET_TYPE_AIASM = 0x53, + ASSET_TYPE_PROCEDURALBONES = 0x54, + ASSET_TYPE_DYNAMICBONES = 0x55, + ASSET_TYPE_RETICLE = 0x56, + ASSET_TYPE_XANIMCURVE = 0x57, + ASSET_TYPE_COVERSELECTOR = 0x58, + ASSET_TYPE_ENEMYSELECTOR = 0x59, + ASSET_TYPE_CLIENTCHARACTER = 0x5A, + ASSET_TYPE_CLOTHASSET = 0x5B, + ASSET_TYPE_CINEMATICMOTION = 0x5C, + ASSET_TYPE_ACCESSORY = 0x5D, + ASSET_TYPE_LOCDMGTABLE = 0x5E, + ASSET_TYPE_BULLETPENETRATION = 0x5F, + ASSET_TYPE_SCRIPTBUNDLE = 0x60, + ASSET_TYPE_BLENDSPACE2D = 0x61, + ASSET_TYPE_XCAM = 0x62, + ASSET_TYPE_CAMO = 0x63, + ASSET_TYPE_XCOMPOSITEMODEL = 0x64, + ASSET_TYPE_XMODELDETAILCOLLISION = 0x65, + ASSET_TYPE_STREAMKEY = 0x66, + ASSET_TYPE_STREAMTREEOVERRIDE = 0x67, + ASSET_TYPE_KEYVALUEPAIRS = 0x68, + ASSET_TYPE_STTERRAIN = 0x69, + ASSET_TYPE_NATIVESCRIPTPATCH = 0x6A, + ASSET_TYPE_COLLISIONTILE = 0x6B, + ASSET_TYPE_EXECUTION = 0x6C, + ASSET_TYPE_CARRYOBJECT = 0x6D, + ASSET_TYPE_SOUNDBANKLIST = 0x6E, + ASSET_TYPE_DECALVOLUMEMATERIAL = 0x6F, + ASSET_TYPE_DECALVOLUMEMASK = 0x70, + ASSET_TYPE_DYNENTITYLIST = 0x71, + ASSET_TYPE_FX_MAP_TRZONE = 0x72, + ASSET_TYPE_DLOGSCHEMA = 0x73, + ASSET_TYPE_EDGELIST = 0x74, +}; + +struct XAsset +{ + XAssetType type; + XAssetHeader header; +}; + +struct ScriptStringList +{ + int count; + bool loaded; + const char** strings; +}; + +struct XAssetList +{ + ScriptStringList stringList; + unsigned int assetCount; + unsigned int assetReadPos; + XAsset* assets; +}; + diff --git a/hook_lib/common/exception/minidump.cpp b/hook_lib/common/exception/minidump.cpp index 41acbc3..a55d290 100644 --- a/hook_lib/common/exception/minidump.cpp +++ b/hook_lib/common/exception/minidump.cpp @@ -1,85 +1,85 @@ -#include "minidump.hpp" - -#include -#pragma comment(lib, "dbghelp.lib") - -namespace exception -{ - namespace - { - constexpr MINIDUMP_TYPE get_minidump_type() - { - constexpr auto type = MiniDumpIgnoreInaccessibleMemory // - | MiniDumpWithHandleData // - | MiniDumpScanMemory // - | MiniDumpWithProcessThreadData // - | MiniDumpWithFullMemoryInfo // - | MiniDumpWithThreadInfo // - | MiniDumpWithUnloadedModules; - - return static_cast(type); - } - - std::string get_temp_filename() - { - char filename[MAX_PATH] = {0}; - char pathname[MAX_PATH] = {0}; - - GetTempPathA(sizeof(pathname), pathname); - GetTempFileNameA(pathname, "boiii-", 0, filename); - return filename; - } - - HANDLE write_dump_to_temp_file(const LPEXCEPTION_POINTERS exceptioninfo) - { - MINIDUMP_EXCEPTION_INFORMATION minidump_exception_info = {GetCurrentThreadId(), exceptioninfo, FALSE}; - - auto* const file_handle = CreateFileA(get_temp_filename().data(), GENERIC_WRITE | GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, - FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, - nullptr); - - if (!MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file_handle, get_minidump_type(), - &minidump_exception_info, - nullptr, - nullptr)) - { - MessageBoxA(nullptr, "There was an error creating the minidump! Hit OK to close the program.", - "Minidump Error", MB_OK | MB_ICONERROR); - TerminateProcess(GetCurrentProcess(), 123); - } - - return file_handle; - } - - std::string read_file(const HANDLE file_handle) - { - FlushFileBuffers(file_handle); - SetFilePointer(file_handle, 0, nullptr, FILE_BEGIN); - - std::string buffer{}; - - DWORD bytes_read = 0; - char temp_bytes[0x2000]; - - do - { - if (!ReadFile(file_handle, temp_bytes, sizeof(temp_bytes), &bytes_read, nullptr)) - { - return {}; - } - - buffer.append(temp_bytes, bytes_read); - } - while (bytes_read == sizeof(temp_bytes)); - - return buffer; - } - } - - std::string create_minidump(const LPEXCEPTION_POINTERS exceptioninfo) - { - const utils::nt::handle file_handle = write_dump_to_temp_file(exceptioninfo); - return read_file(file_handle); - } -} +#include "minidump.hpp" + +#include +#pragma comment(lib, "dbghelp.lib") + +namespace exception +{ + namespace + { + constexpr MINIDUMP_TYPE get_minidump_type() + { + constexpr auto type = MiniDumpIgnoreInaccessibleMemory // + | MiniDumpWithHandleData // + | MiniDumpScanMemory // + | MiniDumpWithProcessThreadData // + | MiniDumpWithFullMemoryInfo // + | MiniDumpWithThreadInfo // + | MiniDumpWithUnloadedModules; + + return static_cast(type); + } + + std::string get_temp_filename() + { + char filename[MAX_PATH] = {0}; + char pathname[MAX_PATH] = {0}; + + GetTempPathA(sizeof(pathname), pathname); + GetTempFileNameA(pathname, "boiii-", 0, filename); + return filename; + } + + HANDLE write_dump_to_temp_file(const LPEXCEPTION_POINTERS exceptioninfo) + { + MINIDUMP_EXCEPTION_INFORMATION minidump_exception_info = {GetCurrentThreadId(), exceptioninfo, FALSE}; + + auto* const file_handle = CreateFileA(get_temp_filename().data(), GENERIC_WRITE | GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, + FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, + nullptr); + + if (!MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), file_handle, get_minidump_type(), + &minidump_exception_info, + nullptr, + nullptr)) + { + MessageBoxA(nullptr, "There was an error creating the minidump! Hit OK to close the program.", + "Minidump Error", MB_OK | MB_ICONERROR); + TerminateProcess(GetCurrentProcess(), 123); + } + + return file_handle; + } + + std::string read_file(const HANDLE file_handle) + { + FlushFileBuffers(file_handle); + SetFilePointer(file_handle, 0, nullptr, FILE_BEGIN); + + std::string buffer{}; + + DWORD bytes_read = 0; + char temp_bytes[0x2000]; + + do + { + if (!ReadFile(file_handle, temp_bytes, sizeof(temp_bytes), &bytes_read, nullptr)) + { + return {}; + } + + buffer.append(temp_bytes, bytes_read); + } + while (bytes_read == sizeof(temp_bytes)); + + return buffer; + } + } + + std::string create_minidump(const LPEXCEPTION_POINTERS exceptioninfo) + { + const utils::nt::handle file_handle = write_dump_to_temp_file(exceptioninfo); + return read_file(file_handle); + } +} diff --git a/hook_lib/common/exception/minidump.hpp b/hook_lib/common/exception/minidump.hpp index 0fa5c34..42b3a46 100644 --- a/hook_lib/common/exception/minidump.hpp +++ b/hook_lib/common/exception/minidump.hpp @@ -1,8 +1,8 @@ -#pragma once - -#include "../utils/nt.hpp" - -namespace exception -{ - std::string create_minidump(LPEXCEPTION_POINTERS exceptioninfo); -} +#pragma once + +#include "../utils/nt.hpp" + +namespace exception +{ + std::string create_minidump(LPEXCEPTION_POINTERS exceptioninfo); +} diff --git a/hook_lib/common/utils/MinHook.hpp b/hook_lib/common/utils/MinHook.hpp index deb22d1..492d83f 100644 --- a/hook_lib/common/utils/MinHook.hpp +++ b/hook_lib/common/utils/MinHook.hpp @@ -1,185 +1,185 @@ -/* - * MinHook - The Minimalistic API Hooking Library for x64/x86 - * Copyright (C) 2009-2017 Tsuda Kageyu. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) - #error MinHook supports only x86 and x64 systems. -#endif - -#include - -// MinHook Error Codes. -typedef enum MH_STATUS -{ - // Unknown error. Should not be returned. - MH_UNKNOWN = -1, - - // Successful. - MH_OK = 0, - - // MinHook is already initialized. - MH_ERROR_ALREADY_INITIALIZED, - - // MinHook is not initialized yet, or already uninitialized. - MH_ERROR_NOT_INITIALIZED, - - // The hook for the specified target function is already created. - MH_ERROR_ALREADY_CREATED, - - // The hook for the specified target function is not created yet. - MH_ERROR_NOT_CREATED, - - // The hook for the specified target function is already enabled. - MH_ERROR_ENABLED, - - // The hook for the specified target function is not enabled yet, or already - // disabled. - MH_ERROR_DISABLED, - - // The specified pointer is invalid. It points the address of non-allocated - // and/or non-executable region. - MH_ERROR_NOT_EXECUTABLE, - - // The specified target function cannot be hooked. - MH_ERROR_UNSUPPORTED_FUNCTION, - - // Failed to allocate memory. - MH_ERROR_MEMORY_ALLOC, - - // Failed to change the memory protection. - MH_ERROR_MEMORY_PROTECT, - - // The specified module is not loaded. - MH_ERROR_MODULE_NOT_FOUND, - - // The specified function is not found. - MH_ERROR_FUNCTION_NOT_FOUND -} -MH_STATUS; - -// Can be passed as a parameter to MH_EnableHook, MH_DisableHook, -// MH_QueueEnableHook or MH_QueueDisableHook. -#define MH_ALL_HOOKS NULL - -#ifdef __cplusplus -extern "C" { -#endif - - // Initialize the MinHook library. You must call this function EXACTLY ONCE - // at the beginning of your program. - MH_STATUS WINAPI MH_Initialize(VOID); - - // Uninitialize the MinHook library. You must call this function EXACTLY - // ONCE at the end of your program. - MH_STATUS WINAPI MH_Uninitialize(VOID); - - // Creates a hook for the specified target function, in disabled state. - // Parameters: - // pTarget [in] A pointer to the target function, which will be - // overridden by the detour function. - // pDetour [in] A pointer to the detour function, which will override - // the target function. - // ppOriginal [out] A pointer to the trampoline function, which will be - // used to call the original target function. - // This parameter can be NULL. - MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); - - // Creates a hook for the specified API function, in disabled state. - // Parameters: - // pszModule [in] A pointer to the loaded module name which contains the - // target function. - // pszProcName [in] A pointer to the target function name, which will be - // overridden by the detour function. - // pDetour [in] A pointer to the detour function, which will override - // the target function. - // ppOriginal [out] A pointer to the trampoline function, which will be - // used to call the original target function. - // This parameter can be NULL. - MH_STATUS WINAPI MH_CreateHookApi( - LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); - - // Creates a hook for the specified API function, in disabled state. - // Parameters: - // pszModule [in] A pointer to the loaded module name which contains the - // target function. - // pszProcName [in] A pointer to the target function name, which will be - // overridden by the detour function. - // pDetour [in] A pointer to the detour function, which will override - // the target function. - // ppOriginal [out] A pointer to the trampoline function, which will be - // used to call the original target function. - // This parameter can be NULL. - // ppTarget [out] A pointer to the target function, which will be used - // with other functions. - // This parameter can be NULL. - MH_STATUS WINAPI MH_CreateHookApiEx( - LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget); - - // Removes an already created hook. - // Parameters: - // pTarget [in] A pointer to the target function. - MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); - - // Enables an already created hook. - // Parameters: - // pTarget [in] A pointer to the target function. - // If this parameter is MH_ALL_HOOKS, all created hooks are - // enabled in one go. - MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); - - // Disables an already created hook. - // Parameters: - // pTarget [in] A pointer to the target function. - // If this parameter is MH_ALL_HOOKS, all created hooks are - // disabled in one go. - MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); - - // Queues to enable an already created hook. - // Parameters: - // pTarget [in] A pointer to the target function. - // If this parameter is MH_ALL_HOOKS, all created hooks are - // queued to be enabled. - MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); - - // Queues to disable an already created hook. - // Parameters: - // pTarget [in] A pointer to the target function. - // If this parameter is MH_ALL_HOOKS, all created hooks are - // queued to be disabled. - MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); - - // Applies all queued changes in one go. - MH_STATUS WINAPI MH_ApplyQueued(VOID); - - // Translates the MH_STATUS to its name as a string. - const char * WINAPI MH_StatusToString(MH_STATUS status); - -#ifdef __cplusplus -} -#endif +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__) + #error MinHook supports only x86 and x64 systems. +#endif + +#include + +// MinHook Error Codes. +typedef enum MH_STATUS +{ + // Unknown error. Should not be returned. + MH_UNKNOWN = -1, + + // Successful. + MH_OK = 0, + + // MinHook is already initialized. + MH_ERROR_ALREADY_INITIALIZED, + + // MinHook is not initialized yet, or already uninitialized. + MH_ERROR_NOT_INITIALIZED, + + // The hook for the specified target function is already created. + MH_ERROR_ALREADY_CREATED, + + // The hook for the specified target function is not created yet. + MH_ERROR_NOT_CREATED, + + // The hook for the specified target function is already enabled. + MH_ERROR_ENABLED, + + // The hook for the specified target function is not enabled yet, or already + // disabled. + MH_ERROR_DISABLED, + + // The specified pointer is invalid. It points the address of non-allocated + // and/or non-executable region. + MH_ERROR_NOT_EXECUTABLE, + + // The specified target function cannot be hooked. + MH_ERROR_UNSUPPORTED_FUNCTION, + + // Failed to allocate memory. + MH_ERROR_MEMORY_ALLOC, + + // Failed to change the memory protection. + MH_ERROR_MEMORY_PROTECT, + + // The specified module is not loaded. + MH_ERROR_MODULE_NOT_FOUND, + + // The specified function is not found. + MH_ERROR_FUNCTION_NOT_FOUND +} +MH_STATUS; + +// Can be passed as a parameter to MH_EnableHook, MH_DisableHook, +// MH_QueueEnableHook or MH_QueueDisableHook. +#define MH_ALL_HOOKS NULL + +#ifdef __cplusplus +extern "C" { +#endif + + // Initialize the MinHook library. You must call this function EXACTLY ONCE + // at the beginning of your program. + MH_STATUS WINAPI MH_Initialize(VOID); + + // Uninitialize the MinHook library. You must call this function EXACTLY + // ONCE at the end of your program. + MH_STATUS WINAPI MH_Uninitialize(VOID); + + // Creates a hook for the specified target function, in disabled state. + // Parameters: + // pTarget [in] A pointer to the target function, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszProcName [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApi( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal); + + // Creates a hook for the specified API function, in disabled state. + // Parameters: + // pszModule [in] A pointer to the loaded module name which contains the + // target function. + // pszProcName [in] A pointer to the target function name, which will be + // overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override + // the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be + // used to call the original target function. + // This parameter can be NULL. + // ppTarget [out] A pointer to the target function, which will be used + // with other functions. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget); + + // Removes an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); + + // Enables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // enabled in one go. + MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget); + + // Disables an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // disabled in one go. + MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget); + + // Queues to enable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be enabled. + MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget); + + // Queues to disable an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are + // queued to be disabled. + MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget); + + // Applies all queued changes in one go. + MH_STATUS WINAPI MH_ApplyQueued(VOID); + + // Translates the MH_STATUS to its name as a string. + const char * WINAPI MH_StatusToString(MH_STATUS status); + +#ifdef __cplusplus +} +#endif diff --git a/hook_lib/common/utils/binary_resource.cpp b/hook_lib/common/utils/binary_resource.cpp index 7282df4..eed83b0 100644 --- a/hook_lib/common/utils/binary_resource.cpp +++ b/hook_lib/common/utils/binary_resource.cpp @@ -1,75 +1,75 @@ -#include "binary_resource.hpp" - -#include -#include "nt.hpp" -#include "io.hpp" - -namespace utils -{ - namespace - { - std::string get_temp_folder() - { - char path[MAX_PATH] = {0}; - if (!GetTempPathA(sizeof(path), path)) - { - throw std::runtime_error("Unable to get temp path"); - } - - return path; - } - - std::string write_existing_temp_file(const std::string& file, const std::string& data, - const bool fatal_if_overwrite_fails) - { - const auto temp = get_temp_folder(); - auto file_path = temp + file; - - std::string current_data; - if (!io::read_file(file_path, ¤t_data)) - { - if (!io::write_file(file_path, data)) - { - throw std::runtime_error("Failed to write file: " + file_path); - } - - return file_path; - } - - if (current_data == data || io::write_file(file_path, data) || !fatal_if_overwrite_fails) - { - return file_path; - } - - throw std::runtime_error( - "Temporary file was already written, but differs. It can't be overwritten as it's still in use: " + - file_path); - } - } - - binary_resource::binary_resource(const int id, std::string file) - : filename_(std::move(file)) - { - this->resource_ = nt::load_resource(id); - - if (this->resource_.empty()) - { - throw std::runtime_error("Unable to load resource: " + std::to_string(id)); - } - } - - std::string binary_resource::get_extracted_file(const bool fatal_if_overwrite_fails) - { - if (this->path_.empty()) - { - this->path_ = write_existing_temp_file(this->filename_, this->resource_, fatal_if_overwrite_fails); - } - - return this->path_; - } - - const std::string& binary_resource::get_data() const - { - return this->resource_; - } -} +#include "binary_resource.hpp" + +#include +#include "nt.hpp" +#include "io.hpp" + +namespace utils +{ + namespace + { + std::string get_temp_folder() + { + char path[MAX_PATH] = {0}; + if (!GetTempPathA(sizeof(path), path)) + { + throw std::runtime_error("Unable to get temp path"); + } + + return path; + } + + std::string write_existing_temp_file(const std::string& file, const std::string& data, + const bool fatal_if_overwrite_fails) + { + const auto temp = get_temp_folder(); + auto file_path = temp + file; + + std::string current_data; + if (!io::read_file(file_path, ¤t_data)) + { + if (!io::write_file(file_path, data)) + { + throw std::runtime_error("Failed to write file: " + file_path); + } + + return file_path; + } + + if (current_data == data || io::write_file(file_path, data) || !fatal_if_overwrite_fails) + { + return file_path; + } + + throw std::runtime_error( + "Temporary file was already written, but differs. It can't be overwritten as it's still in use: " + + file_path); + } + } + + binary_resource::binary_resource(const int id, std::string file) + : filename_(std::move(file)) + { + this->resource_ = nt::load_resource(id); + + if (this->resource_.empty()) + { + throw std::runtime_error("Unable to load resource: " + std::to_string(id)); + } + } + + std::string binary_resource::get_extracted_file(const bool fatal_if_overwrite_fails) + { + if (this->path_.empty()) + { + this->path_ = write_existing_temp_file(this->filename_, this->resource_, fatal_if_overwrite_fails); + } + + return this->path_; + } + + const std::string& binary_resource::get_data() const + { + return this->resource_; + } +} diff --git a/hook_lib/common/utils/binary_resource.hpp b/hook_lib/common/utils/binary_resource.hpp index 74f9d54..da19af1 100644 --- a/hook_lib/common/utils/binary_resource.hpp +++ b/hook_lib/common/utils/binary_resource.hpp @@ -1,20 +1,20 @@ -#pragma once - -#include - -namespace utils -{ - class binary_resource - { - public: - binary_resource(int id, std::string file); - - std::string get_extracted_file(bool fatal_if_overwrite_fails = false); - const std::string& get_data() const; - - private: - std::string resource_; - std::string filename_; - std::string path_; - }; -} +#pragma once + +#include + +namespace utils +{ + class binary_resource + { + public: + binary_resource(int id, std::string file); + + std::string get_extracted_file(bool fatal_if_overwrite_fails = false); + const std::string& get_data() const; + + private: + std::string resource_; + std::string filename_; + std::string path_; + }; +} diff --git a/hook_lib/common/utils/concurrency.hpp b/hook_lib/common/utils/concurrency.hpp index ffb322d..05c5d3a 100644 --- a/hook_lib/common/utils/concurrency.hpp +++ b/hook_lib/common/utils/concurrency.hpp @@ -1,46 +1,46 @@ -#pragma once - -#include - -namespace utils::concurrency -{ - template - class container - { - public: - template - R access(F&& accessor) const - { - std::lock_guard _{mutex_}; - return accessor(object_); - } - - template - R access(F&& accessor) - { - std::lock_guard _{mutex_}; - return accessor(object_); - } - - template - R access_with_lock(F&& accessor) const - { - std::unique_lock lock{mutex_}; - return accessor(object_, lock); - } - - template - R access_with_lock(F&& accessor) - { - std::unique_lock lock{mutex_}; - return accessor(object_, lock); - } - - T& get_raw() { return object_; } - const T& get_raw() const { return object_; } - - private: - mutable MutexType mutex_{}; - T object_{}; - }; -} +#pragma once + +#include + +namespace utils::concurrency +{ + template + class container + { + public: + template + R access(F&& accessor) const + { + std::lock_guard _{mutex_}; + return accessor(object_); + } + + template + R access(F&& accessor) + { + std::lock_guard _{mutex_}; + return accessor(object_); + } + + template + R access_with_lock(F&& accessor) const + { + std::unique_lock lock{mutex_}; + return accessor(object_, lock); + } + + template + R access_with_lock(F&& accessor) + { + std::unique_lock lock{mutex_}; + return accessor(object_, lock); + } + + T& get_raw() { return object_; } + const T& get_raw() const { return object_; } + + private: + mutable MutexType mutex_{}; + T object_{}; + }; +} diff --git a/hook_lib/common/utils/finally.hpp b/hook_lib/common/utils/finally.hpp index 3ed5cf5..2e4b6ba 100644 --- a/hook_lib/common/utils/finally.hpp +++ b/hook_lib/common/utils/finally.hpp @@ -1,54 +1,54 @@ -#pragma once -#include - -namespace utils -{ - /* - * Copied from here: https://github.com/microsoft/GSL/blob/e0880931ae5885eb988d1a8a57acf8bc2b8dacda/include/gsl/util#L57 - */ - - template - class final_action - { - public: - static_assert(!std::is_reference::value && !std::is_const::value && - !std::is_volatile::value, - "Final_action should store its callable by value"); - - explicit final_action(F f) noexcept : f_(std::move(f)) - { - } - - final_action(final_action&& other) noexcept - : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false)) - { - } - - final_action(const final_action&) = delete; - final_action& operator=(const final_action&) = delete; - final_action& operator=(final_action&&) = delete; - - ~final_action() noexcept - { - if (invoke_) f_(); - } - - // Added by momo5502 - void cancel() - { - invoke_ = false; - } - - private: - F f_; - bool invoke_{true}; - }; - - template - final_action::type>::type> - finally(F&& f) noexcept - { - return final_action::type>::type>( - std::forward(f)); - } +#pragma once +#include + +namespace utils +{ + /* + * Copied from here: https://github.com/microsoft/GSL/blob/e0880931ae5885eb988d1a8a57acf8bc2b8dacda/include/gsl/util#L57 + */ + + template + class final_action + { + public: + static_assert(!std::is_reference::value && !std::is_const::value && + !std::is_volatile::value, + "Final_action should store its callable by value"); + + explicit final_action(F f) noexcept : f_(std::move(f)) + { + } + + final_action(final_action&& other) noexcept + : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false)) + { + } + + final_action(const final_action&) = delete; + final_action& operator=(const final_action&) = delete; + final_action& operator=(final_action&&) = delete; + + ~final_action() noexcept + { + if (invoke_) f_(); + } + + // Added by momo5502 + void cancel() + { + invoke_ = false; + } + + private: + F f_; + bool invoke_{true}; + }; + + template + final_action::type>::type> + finally(F&& f) noexcept + { + return final_action::type>::type>( + std::forward(f)); + } } \ No newline at end of file diff --git a/hook_lib/common/utils/hardware_breakpoint.cpp b/hook_lib/common/utils/hardware_breakpoint.cpp index 94ba9c9..441c149 100644 --- a/hook_lib/common/utils/hardware_breakpoint.cpp +++ b/hook_lib/common/utils/hardware_breakpoint.cpp @@ -1,173 +1,173 @@ -#include "hardware_breakpoint.hpp" -#include "thread.hpp" - - -namespace utils::hardware_breakpoint -{ - namespace - { - void set_bits(uintptr_t& value, const uint32_t bit_index, const uint32_t bits, const uintptr_t new_value) - { - const uintptr_t range_mask = (1ull << bits) - 1ull; - const uintptr_t full_mask = ~(range_mask << bit_index); - value = (value & full_mask) | (new_value << bit_index); - } - - void validate_index(const uint32_t index) - { - if (index >= 4) - { - throw std::runtime_error("Invalid index"); - } - } - - uint32_t translate_length(const uint32_t length) - { - if (length != 1 && length != 2 && length != 4) - { - throw std::runtime_error("Invalid length"); - } - - return length - 1; - } - - class debug_context - { - public: - debug_context(uint32_t thread_id) - : handle_(thread_id, THREAD_SET_CONTEXT | THREAD_GET_CONTEXT) - { - if (!this->handle_) - { - throw std::runtime_error("Unable to access thread"); - } - - this->context_.ContextFlags = CONTEXT_DEBUG_REGISTERS; - - if (!GetThreadContext(this->handle_, &this->context_)) - { - throw std::runtime_error("Unable to get thread context"); - } - } - - ~debug_context() - { - SetThreadContext(this->handle_, &this->context_); - } - - debug_context(const debug_context&) = delete; - debug_context& operator=(const debug_context&) = delete; - - debug_context(debug_context&& obj) noexcept = delete; - debug_context& operator=(debug_context&& obj) noexcept = delete; - - CONTEXT* operator->() - { - return &this->context_; - } - - operator CONTEXT&() - { - return this->context_; - } - - private: - thread::handle handle_; - CONTEXT context_{}; - }; - - uint32_t find_free_index(const CONTEXT& context) - { - for (uint32_t i = 0; i < 4; ++i) - { - if ((context.Dr7 & (1ull << (i << 1ull))) == 0) - { - return i; - } - } - - throw std::runtime_error("No free index"); - } - } - - void set_branch_tracing(const bool enabled, CONTEXT& context) - { - set_bits(context.Dr7, 8, 1, enabled ? 1 : 0); - } - - void set_branch_tracing(const bool enabled, const uint32_t thread_id) - { - debug_context context(thread_id); - set_branch_tracing(enabled, context); - } - - uint32_t activate(const uintptr_t address, uint32_t length, const condition cond, CONTEXT& context) - { - const auto index = find_free_index(context); - length = translate_length(length); - - (&context.Dr0)[index] = address; - set_bits(context.Dr7, 16 + (index << 2ull), 2, cond); - set_bits(context.Dr7, 18 + (index << 2ull), 2, length); - set_bits(context.Dr7, index << 1ull, 1, 1); - - return index; - } - - uint32_t activate(void* address, const uint32_t length, const condition cond, const uint32_t thread_id) - { - return activate(reinterpret_cast(address), length, cond, thread_id); - } - - uint32_t activate(const uint64_t address, const uint32_t length, const condition cond, const uint32_t thread_id) - { - debug_context context(thread_id); - return activate(address, length, cond, context); - } - - void deactivate_address(const uint64_t address, CONTEXT& context) - { - for (auto i = 0; i < 4; ++i) - { - if ((&context.Dr0)[i] == address) - { - deactivate(i, context); - } - } - } - - void deactivate_address(void* address, const uint32_t thread_id) - { - return deactivate_address(reinterpret_cast(address), thread_id); - } - - void deactivate_address(const uint64_t address, const uint32_t thread_id) - { - debug_context context(thread_id); - deactivate_address(address, context); - } - - void deactivate(const uint32_t index, CONTEXT& context) - { - validate_index(index); - set_bits(context.Dr7, index << 1ull, 1, 0); - } - - void deactivate(const uint32_t index, const uint32_t thread_id) - { - debug_context context(thread_id); - deactivate(index, context); - } - - void deactivate_all(CONTEXT& context) - { - context.Dr7 = 0; - } - - void deactivate_all(const uint32_t thread_id) - { - debug_context context(thread_id); - deactivate_all(context); - } -} - +#include "hardware_breakpoint.hpp" +#include "thread.hpp" + + +namespace utils::hardware_breakpoint +{ + namespace + { + void set_bits(uintptr_t& value, const uint32_t bit_index, const uint32_t bits, const uintptr_t new_value) + { + const uintptr_t range_mask = (1ull << bits) - 1ull; + const uintptr_t full_mask = ~(range_mask << bit_index); + value = (value & full_mask) | (new_value << bit_index); + } + + void validate_index(const uint32_t index) + { + if (index >= 4) + { + throw std::runtime_error("Invalid index"); + } + } + + uint32_t translate_length(const uint32_t length) + { + if (length != 1 && length != 2 && length != 4) + { + throw std::runtime_error("Invalid length"); + } + + return length - 1; + } + + class debug_context + { + public: + debug_context(uint32_t thread_id) + : handle_(thread_id, THREAD_SET_CONTEXT | THREAD_GET_CONTEXT) + { + if (!this->handle_) + { + throw std::runtime_error("Unable to access thread"); + } + + this->context_.ContextFlags = CONTEXT_DEBUG_REGISTERS; + + if (!GetThreadContext(this->handle_, &this->context_)) + { + throw std::runtime_error("Unable to get thread context"); + } + } + + ~debug_context() + { + SetThreadContext(this->handle_, &this->context_); + } + + debug_context(const debug_context&) = delete; + debug_context& operator=(const debug_context&) = delete; + + debug_context(debug_context&& obj) noexcept = delete; + debug_context& operator=(debug_context&& obj) noexcept = delete; + + CONTEXT* operator->() + { + return &this->context_; + } + + operator CONTEXT&() + { + return this->context_; + } + + private: + thread::handle handle_; + CONTEXT context_{}; + }; + + uint32_t find_free_index(const CONTEXT& context) + { + for (uint32_t i = 0; i < 4; ++i) + { + if ((context.Dr7 & (1ull << (i << 1ull))) == 0) + { + return i; + } + } + + throw std::runtime_error("No free index"); + } + } + + void set_branch_tracing(const bool enabled, CONTEXT& context) + { + set_bits(context.Dr7, 8, 1, enabled ? 1 : 0); + } + + void set_branch_tracing(const bool enabled, const uint32_t thread_id) + { + debug_context context(thread_id); + set_branch_tracing(enabled, context); + } + + uint32_t activate(const uintptr_t address, uint32_t length, const condition cond, CONTEXT& context) + { + const auto index = find_free_index(context); + length = translate_length(length); + + (&context.Dr0)[index] = address; + set_bits(context.Dr7, 16 + (index << 2ull), 2, cond); + set_bits(context.Dr7, 18 + (index << 2ull), 2, length); + set_bits(context.Dr7, index << 1ull, 1, 1); + + return index; + } + + uint32_t activate(void* address, const uint32_t length, const condition cond, const uint32_t thread_id) + { + return activate(reinterpret_cast(address), length, cond, thread_id); + } + + uint32_t activate(const uint64_t address, const uint32_t length, const condition cond, const uint32_t thread_id) + { + debug_context context(thread_id); + return activate(address, length, cond, context); + } + + void deactivate_address(const uint64_t address, CONTEXT& context) + { + for (auto i = 0; i < 4; ++i) + { + if ((&context.Dr0)[i] == address) + { + deactivate(i, context); + } + } + } + + void deactivate_address(void* address, const uint32_t thread_id) + { + return deactivate_address(reinterpret_cast(address), thread_id); + } + + void deactivate_address(const uint64_t address, const uint32_t thread_id) + { + debug_context context(thread_id); + deactivate_address(address, context); + } + + void deactivate(const uint32_t index, CONTEXT& context) + { + validate_index(index); + set_bits(context.Dr7, index << 1ull, 1, 0); + } + + void deactivate(const uint32_t index, const uint32_t thread_id) + { + debug_context context(thread_id); + deactivate(index, context); + } + + void deactivate_all(CONTEXT& context) + { + context.Dr7 = 0; + } + + void deactivate_all(const uint32_t thread_id) + { + debug_context context(thread_id); + deactivate_all(context); + } +} + diff --git a/hook_lib/common/utils/hardware_breakpoint.hpp b/hook_lib/common/utils/hardware_breakpoint.hpp index f215698..869b955 100644 --- a/hook_lib/common/utils/hardware_breakpoint.hpp +++ b/hook_lib/common/utils/hardware_breakpoint.hpp @@ -1,32 +1,32 @@ -#pragma once -#include -#include "nt.hpp" - - -namespace utils::hardware_breakpoint -{ - enum condition - { - execute = 0, - write = 1, - read_write = 3 - }; - - - void set_branch_tracing(bool enabled, CONTEXT& context); - void set_branch_tracing(bool enabled, uint32_t thread_id = GetCurrentThreadId()); - - uint32_t activate(uint64_t address, uint32_t length, condition cond, CONTEXT& context); - uint32_t activate(void* address, uint32_t length, condition cond, uint32_t thread_id = GetCurrentThreadId()); - uint32_t activate(uint64_t address, uint32_t length, condition cond, uint32_t thread_id = GetCurrentThreadId()); - - void deactivate_address(uint64_t address, CONTEXT& context); - void deactivate_address(void* address, uint32_t thread_id = GetCurrentThreadId()); - void deactivate_address(uint64_t address, uint32_t thread_id = GetCurrentThreadId()); - - void deactivate(uint32_t index, CONTEXT& context); - void deactivate(uint32_t index, uint32_t thread_id = GetCurrentThreadId()); - - void deactivate_all(CONTEXT& context); - void deactivate_all(uint32_t thread_id = GetCurrentThreadId()); -} +#pragma once +#include +#include "nt.hpp" + + +namespace utils::hardware_breakpoint +{ + enum condition + { + execute = 0, + write = 1, + read_write = 3 + }; + + + void set_branch_tracing(bool enabled, CONTEXT& context); + void set_branch_tracing(bool enabled, uint32_t thread_id = GetCurrentThreadId()); + + uint32_t activate(uint64_t address, uint32_t length, condition cond, CONTEXT& context); + uint32_t activate(void* address, uint32_t length, condition cond, uint32_t thread_id = GetCurrentThreadId()); + uint32_t activate(uint64_t address, uint32_t length, condition cond, uint32_t thread_id = GetCurrentThreadId()); + + void deactivate_address(uint64_t address, CONTEXT& context); + void deactivate_address(void* address, uint32_t thread_id = GetCurrentThreadId()); + void deactivate_address(uint64_t address, uint32_t thread_id = GetCurrentThreadId()); + + void deactivate(uint32_t index, CONTEXT& context); + void deactivate(uint32_t index, uint32_t thread_id = GetCurrentThreadId()); + + void deactivate_all(CONTEXT& context); + void deactivate_all(uint32_t thread_id = GetCurrentThreadId()); +} diff --git a/hook_lib/common/utils/hook.cpp b/hook_lib/common/utils/hook.cpp index caa036a..0b1b86e 100644 --- a/hook_lib/common/utils/hook.cpp +++ b/hook_lib/common/utils/hook.cpp @@ -1,484 +1,484 @@ -#include "hook.hpp" - -#include - -#include "MinHook.hpp" - -#include "concurrency.hpp" -#include "string.hpp" -#include "nt.hpp" - -#ifdef max -#undef max -#endif - -#ifdef min -#undef min -#endif - -namespace utils::hook -{ - namespace - { - uint8_t* allocate_somewhere_near(const void* base_address, const size_t size) - { - size_t offset = 0; - while (true) - { - offset += size; - auto* target_address = static_cast(base_address) - offset; - if (is_relatively_far(base_address, target_address)) - { - return nullptr; - } - - const auto res = VirtualAlloc(const_cast(target_address), size, MEM_RESERVE | MEM_COMMIT, - PAGE_EXECUTE_READWRITE); - if (res) - { - if (is_relatively_far(base_address, target_address)) - { - VirtualFree(res, 0, MEM_RELEASE); - return nullptr; - } - - return static_cast(res); - } - } - } - - class memory - { - public: - memory() = default; - - memory(const void* ptr) - : memory() - { - this->length_ = 0x1000; - this->buffer_ = allocate_somewhere_near(ptr, this->length_); - if (!this->buffer_) - { - throw std::runtime_error("Failed to allocate"); - } - } - - ~memory() - { - if (this->buffer_) - { - VirtualFree(this->buffer_, 0, MEM_RELEASE); - } - } - - memory(memory&& obj) noexcept - : memory() - { - this->operator=(std::move(obj)); - } - - memory& operator=(memory&& obj) noexcept - { - if (this != &obj) - { - this->~memory(); - this->buffer_ = obj.buffer_; - this->length_ = obj.length_; - this->offset_ = obj.offset_; - - obj.buffer_ = nullptr; - obj.length_ = 0; - obj.offset_ = 0; - } - - return *this; - } - - void* allocate(const size_t length) - { - if (!this->buffer_) - { - return nullptr; - } - - if (this->offset_ + length > this->length_) - { - return nullptr; - } - - const auto ptr = this->get_ptr(); - this->offset_ += length; - return ptr; - } - - void* get_ptr() const - { - return this->buffer_ + this->offset_; - } - - private: - uint8_t* buffer_{}; - size_t length_{}; - size_t offset_{}; - }; - - void* get_memory_near(const void* address, const size_t size) - { - static concurrency::container> memory_container{}; - - return memory_container.access([&](std::vector& memories) - { - for (auto& memory : memories) - { - if (!is_relatively_far(address, memory.get_ptr())) - { - const auto buffer = memory.allocate(size); - if (buffer) - { - return buffer; - } - } - } - - memories.emplace_back(address); - return memories.back().allocate(size); - }); - } - - void* initialize_min_hook() - { - static class min_hook_init - { - public: - min_hook_init() - { - if (MH_Initialize() != MH_OK) - { - throw std::runtime_error("Failed to initialize MinHook"); - } - } - - ~min_hook_init() - { - MH_Uninitialize(); - } - } min_hook_init; - return &min_hook_init; - } - } - - - detour::detour() - { - (void)initialize_min_hook(); - } - - detour::detour(const size_t place, void* target) - : detour(reinterpret_cast(place), target) - { - } - - detour::detour(void* place, void* target) - : detour() - { - this->create(place, target); - } - - detour::~detour() - { - this->clear(); - } - - void detour::enable() - { - MH_EnableHook(this->place_); - if (!this->moved_data_.empty()) - { - this->move(); - } - } - - void detour::disable() - { - this->un_move(); - MH_DisableHook(this->place_); - } - - void detour::create(void* place, void* target) - { - this->clear(); - this->place_ = place; - - if (MH_CreateHook(this->place_, target, &this->original_) != MH_OK) - { - //throw std::runtime_error(string::va("Unable to create hook at location: %p", this->place_)); - } - - this->enable(); - } - - void detour::create(const size_t place, void* target) - { - MH_Initialize(); - this->create(reinterpret_cast(place), target); - } - - void detour::clear() - { - if (this->place_) - { - this->un_move(); - MH_RemoveHook(this->place_); - } - - this->place_ = nullptr; - this->original_ = nullptr; - this->moved_data_ = {}; - } - - void detour::move() - { - this->moved_data_ = move_hook(this->place_); - } - - void* detour::get_place() const - { - return this->place_; - } - - void* detour::get_original() const - { - return this->original_; - } - - void detour::un_move() - { - if (!this->moved_data_.empty()) - { - copy(this->place_, this->moved_data_.data(), this->moved_data_.size()); - } - } - - std::optional> iat(const nt::library& library, const std::string& target_library, const std::string& process, void* stub) - { - if (!library.is_valid()) return {}; - - auto* const ptr = library.get_iat_entry(target_library, process); - if (!ptr) return {}; - - DWORD protect; - VirtualProtect(ptr, sizeof(*ptr), PAGE_EXECUTE_READWRITE, &protect); - - std::swap(*ptr, stub); - - VirtualProtect(ptr, sizeof(*ptr), protect, &protect); - return {{ptr, stub}}; - } - - void nop(void* place, const size_t length) - { - DWORD old_protect{}; - VirtualProtect(place, length, PAGE_EXECUTE_READWRITE, &old_protect); - - std::memset(place, 0x90, length); - - VirtualProtect(place, length, old_protect, &old_protect); - FlushInstructionCache(GetCurrentProcess(), place, length); - } - - void nop(const size_t place, const size_t length) - { - nop(reinterpret_cast(place), length); - } - - void copy(void* place, const void* data, const size_t length) - { - DWORD old_protect{}; - VirtualProtect(place, length, PAGE_EXECUTE_READWRITE, &old_protect); - - std::memmove(place, data, length); - - VirtualProtect(place, length, old_protect, &old_protect); - FlushInstructionCache(GetCurrentProcess(), place, length); - } - - void copy(const size_t place, const void* data, const size_t length) - { - copy(reinterpret_cast(place), data, length); - } - - void copy_string(void* place, const char* str) - { - copy(reinterpret_cast(place), str, strlen(str) + 1); - } - - void copy_string(const size_t place, const char* str) - { - copy_string(reinterpret_cast(place), str); - } - - bool is_relatively_far(const void* pointer, const void* data, const int offset) - { - const int64_t diff = size_t(data) - (size_t(pointer) + offset); - const auto small_diff = int32_t(diff); - return diff != int64_t(small_diff); - } - - void call(void* pointer, void* data) - { - if (is_relatively_far(pointer, data)) - { - auto* trampoline = get_memory_near(pointer, 14); - if (!trampoline) - { - throw std::runtime_error("Too far away to create 32bit relative branch"); - } - - call(pointer, trampoline); - jump(trampoline, data, true, true); - return; - } - - uint8_t copy_data[5]; - copy_data[0] = 0xE8; - *reinterpret_cast(©_data[1]) = int32_t(size_t(data) - (size_t(pointer) + 5)); - - auto* patch_pointer = PBYTE(pointer); - copy(patch_pointer, copy_data, sizeof(copy_data)); - } - - void call(const size_t pointer, void* data) - { - return call(reinterpret_cast(pointer), data); - } - - void call(const size_t pointer, const size_t data) - { - return call(pointer, reinterpret_cast(data)); - } - - void jump(void* pointer, void* data, const bool use_far, const bool use_safe) - { - static const unsigned char jump_data[] = { - 0x48, 0xb8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0xff, 0xe0 - }; - - static const unsigned char jump_data_safe[] = { - 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 - }; - - if (!use_far && is_relatively_far(pointer, data)) - { - auto* trampoline = get_memory_near(pointer, 14); - if (!trampoline) - { - throw std::runtime_error("Too far away to create 32bit relative branch"); - } - jump(pointer, trampoline, false, false); - jump(trampoline, data, true, true); - return; - } - - auto* patch_pointer = PBYTE(pointer); - - if (use_far) - { - if (use_safe) - { - uint8_t copy_data[sizeof(jump_data_safe) + sizeof(data)]; - memcpy(copy_data, jump_data_safe, sizeof(jump_data_safe)); - memcpy(copy_data + sizeof(jump_data_safe), &data, sizeof(data)); - - copy(patch_pointer, copy_data, sizeof(copy_data)); - } - else - { - uint8_t copy_data[sizeof(jump_data)]; - memcpy(copy_data, jump_data, sizeof(jump_data)); - memcpy(copy_data + 2, &data, sizeof(data)); - - copy(patch_pointer, copy_data, sizeof(copy_data)); - } - } - else - { - uint8_t copy_data[5]; - copy_data[0] = 0xE9; - *reinterpret_cast(©_data[1]) = int32_t(size_t(data) - (size_t(pointer) + 5)); - - copy(patch_pointer, copy_data, sizeof(copy_data)); - } - } - - void jump(const size_t pointer, void* data, const bool use_far, const bool use_safe) - { - return jump(reinterpret_cast(pointer), data, use_far, use_safe); - } - - void jump(const size_t pointer, const size_t data, const bool use_far, const bool use_safe) - { - return jump(pointer, reinterpret_cast(data), use_far, use_safe); - } - - - void inject(void* pointer, const void* data) - { - if (is_relatively_far(pointer, data, 4)) - { - throw std::runtime_error("Too far away to create 32bit relative branch"); - } - - set(pointer, int32_t(size_t(data) - (size_t(pointer) + 4))); - } - - void inject(const size_t pointer, const void* data) - { - return inject(reinterpret_cast(pointer), data); - } - - std::vector move_hook(void* pointer) - { - std::vector original_data{}; - - auto* data_ptr = static_cast(pointer); - if (data_ptr[0] == 0xE9) - { - original_data.resize(6); - memmove(original_data.data(), pointer, original_data.size()); - - auto* target = follow_branch(data_ptr); - nop(data_ptr, 1); - jump(data_ptr + 1, target); - } - else if (data_ptr[0] == 0xFF && data_ptr[1] == 0x25) - { - original_data.resize(15); - memmove(original_data.data(), pointer, original_data.size()); - - copy(data_ptr + 1, data_ptr, 14); - nop(data_ptr, 1); - } - else - { - throw std::runtime_error("No branch instruction found"); - } - - return original_data; - } - - std::vector move_hook(const size_t pointer) - { - return move_hook(reinterpret_cast(pointer)); - } - - void* follow_branch(void* address) - { - auto* const data = static_cast(address); - if (*data != 0xE8 && *data != 0xE9) - { - throw std::runtime_error("No branch instruction found"); - } - - return extract(data + 1); - } -} +#include "hook.hpp" + +#include + +#include "MinHook.hpp" + +#include "concurrency.hpp" +#include "string.hpp" +#include "nt.hpp" + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +namespace utils::hook +{ + namespace + { + uint8_t* allocate_somewhere_near(const void* base_address, const size_t size) + { + size_t offset = 0; + while (true) + { + offset += size; + auto* target_address = static_cast(base_address) - offset; + if (is_relatively_far(base_address, target_address)) + { + return nullptr; + } + + const auto res = VirtualAlloc(const_cast(target_address), size, MEM_RESERVE | MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + if (res) + { + if (is_relatively_far(base_address, target_address)) + { + VirtualFree(res, 0, MEM_RELEASE); + return nullptr; + } + + return static_cast(res); + } + } + } + + class memory + { + public: + memory() = default; + + memory(const void* ptr) + : memory() + { + this->length_ = 0x1000; + this->buffer_ = allocate_somewhere_near(ptr, this->length_); + if (!this->buffer_) + { + throw std::runtime_error("Failed to allocate"); + } + } + + ~memory() + { + if (this->buffer_) + { + VirtualFree(this->buffer_, 0, MEM_RELEASE); + } + } + + memory(memory&& obj) noexcept + : memory() + { + this->operator=(std::move(obj)); + } + + memory& operator=(memory&& obj) noexcept + { + if (this != &obj) + { + this->~memory(); + this->buffer_ = obj.buffer_; + this->length_ = obj.length_; + this->offset_ = obj.offset_; + + obj.buffer_ = nullptr; + obj.length_ = 0; + obj.offset_ = 0; + } + + return *this; + } + + void* allocate(const size_t length) + { + if (!this->buffer_) + { + return nullptr; + } + + if (this->offset_ + length > this->length_) + { + return nullptr; + } + + const auto ptr = this->get_ptr(); + this->offset_ += length; + return ptr; + } + + void* get_ptr() const + { + return this->buffer_ + this->offset_; + } + + private: + uint8_t* buffer_{}; + size_t length_{}; + size_t offset_{}; + }; + + void* get_memory_near(const void* address, const size_t size) + { + static concurrency::container> memory_container{}; + + return memory_container.access([&](std::vector& memories) + { + for (auto& memory : memories) + { + if (!is_relatively_far(address, memory.get_ptr())) + { + const auto buffer = memory.allocate(size); + if (buffer) + { + return buffer; + } + } + } + + memories.emplace_back(address); + return memories.back().allocate(size); + }); + } + + void* initialize_min_hook() + { + static class min_hook_init + { + public: + min_hook_init() + { + if (MH_Initialize() != MH_OK) + { + throw std::runtime_error("Failed to initialize MinHook"); + } + } + + ~min_hook_init() + { + MH_Uninitialize(); + } + } min_hook_init; + return &min_hook_init; + } + } + + + detour::detour() + { + (void)initialize_min_hook(); + } + + detour::detour(const size_t place, void* target) + : detour(reinterpret_cast(place), target) + { + } + + detour::detour(void* place, void* target) + : detour() + { + this->create(place, target); + } + + detour::~detour() + { + this->clear(); + } + + void detour::enable() + { + MH_EnableHook(this->place_); + if (!this->moved_data_.empty()) + { + this->move(); + } + } + + void detour::disable() + { + this->un_move(); + MH_DisableHook(this->place_); + } + + void detour::create(void* place, void* target) + { + this->clear(); + this->place_ = place; + + if (MH_CreateHook(this->place_, target, &this->original_) != MH_OK) + { + //throw std::runtime_error(string::va("Unable to create hook at location: %p", this->place_)); + } + + this->enable(); + } + + void detour::create(const size_t place, void* target) + { + MH_Initialize(); + this->create(reinterpret_cast(place), target); + } + + void detour::clear() + { + if (this->place_) + { + this->un_move(); + MH_RemoveHook(this->place_); + } + + this->place_ = nullptr; + this->original_ = nullptr; + this->moved_data_ = {}; + } + + void detour::move() + { + this->moved_data_ = move_hook(this->place_); + } + + void* detour::get_place() const + { + return this->place_; + } + + void* detour::get_original() const + { + return this->original_; + } + + void detour::un_move() + { + if (!this->moved_data_.empty()) + { + copy(this->place_, this->moved_data_.data(), this->moved_data_.size()); + } + } + + std::optional> iat(const nt::library& library, const std::string& target_library, const std::string& process, void* stub) + { + if (!library.is_valid()) return {}; + + auto* const ptr = library.get_iat_entry(target_library, process); + if (!ptr) return {}; + + DWORD protect; + VirtualProtect(ptr, sizeof(*ptr), PAGE_EXECUTE_READWRITE, &protect); + + std::swap(*ptr, stub); + + VirtualProtect(ptr, sizeof(*ptr), protect, &protect); + return {{ptr, stub}}; + } + + void nop(void* place, const size_t length) + { + DWORD old_protect{}; + VirtualProtect(place, length, PAGE_EXECUTE_READWRITE, &old_protect); + + std::memset(place, 0x90, length); + + VirtualProtect(place, length, old_protect, &old_protect); + FlushInstructionCache(GetCurrentProcess(), place, length); + } + + void nop(const size_t place, const size_t length) + { + nop(reinterpret_cast(place), length); + } + + void copy(void* place, const void* data, const size_t length) + { + DWORD old_protect{}; + VirtualProtect(place, length, PAGE_EXECUTE_READWRITE, &old_protect); + + std::memmove(place, data, length); + + VirtualProtect(place, length, old_protect, &old_protect); + FlushInstructionCache(GetCurrentProcess(), place, length); + } + + void copy(const size_t place, const void* data, const size_t length) + { + copy(reinterpret_cast(place), data, length); + } + + void copy_string(void* place, const char* str) + { + copy(reinterpret_cast(place), str, strlen(str) + 1); + } + + void copy_string(const size_t place, const char* str) + { + copy_string(reinterpret_cast(place), str); + } + + bool is_relatively_far(const void* pointer, const void* data, const int offset) + { + const int64_t diff = size_t(data) - (size_t(pointer) + offset); + const auto small_diff = int32_t(diff); + return diff != int64_t(small_diff); + } + + void call(void* pointer, void* data) + { + if (is_relatively_far(pointer, data)) + { + auto* trampoline = get_memory_near(pointer, 14); + if (!trampoline) + { + throw std::runtime_error("Too far away to create 32bit relative branch"); + } + + call(pointer, trampoline); + jump(trampoline, data, true, true); + return; + } + + uint8_t copy_data[5]; + copy_data[0] = 0xE8; + *reinterpret_cast(©_data[1]) = int32_t(size_t(data) - (size_t(pointer) + 5)); + + auto* patch_pointer = PBYTE(pointer); + copy(patch_pointer, copy_data, sizeof(copy_data)); + } + + void call(const size_t pointer, void* data) + { + return call(reinterpret_cast(pointer), data); + } + + void call(const size_t pointer, const size_t data) + { + return call(pointer, reinterpret_cast(data)); + } + + void jump(void* pointer, void* data, const bool use_far, const bool use_safe) + { + static const unsigned char jump_data[] = { + 0x48, 0xb8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0xff, 0xe0 + }; + + static const unsigned char jump_data_safe[] = { + 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 + }; + + if (!use_far && is_relatively_far(pointer, data)) + { + auto* trampoline = get_memory_near(pointer, 14); + if (!trampoline) + { + throw std::runtime_error("Too far away to create 32bit relative branch"); + } + jump(pointer, trampoline, false, false); + jump(trampoline, data, true, true); + return; + } + + auto* patch_pointer = PBYTE(pointer); + + if (use_far) + { + if (use_safe) + { + uint8_t copy_data[sizeof(jump_data_safe) + sizeof(data)]; + memcpy(copy_data, jump_data_safe, sizeof(jump_data_safe)); + memcpy(copy_data + sizeof(jump_data_safe), &data, sizeof(data)); + + copy(patch_pointer, copy_data, sizeof(copy_data)); + } + else + { + uint8_t copy_data[sizeof(jump_data)]; + memcpy(copy_data, jump_data, sizeof(jump_data)); + memcpy(copy_data + 2, &data, sizeof(data)); + + copy(patch_pointer, copy_data, sizeof(copy_data)); + } + } + else + { + uint8_t copy_data[5]; + copy_data[0] = 0xE9; + *reinterpret_cast(©_data[1]) = int32_t(size_t(data) - (size_t(pointer) + 5)); + + copy(patch_pointer, copy_data, sizeof(copy_data)); + } + } + + void jump(const size_t pointer, void* data, const bool use_far, const bool use_safe) + { + return jump(reinterpret_cast(pointer), data, use_far, use_safe); + } + + void jump(const size_t pointer, const size_t data, const bool use_far, const bool use_safe) + { + return jump(pointer, reinterpret_cast(data), use_far, use_safe); + } + + + void inject(void* pointer, const void* data) + { + if (is_relatively_far(pointer, data, 4)) + { + throw std::runtime_error("Too far away to create 32bit relative branch"); + } + + set(pointer, int32_t(size_t(data) - (size_t(pointer) + 4))); + } + + void inject(const size_t pointer, const void* data) + { + return inject(reinterpret_cast(pointer), data); + } + + std::vector move_hook(void* pointer) + { + std::vector original_data{}; + + auto* data_ptr = static_cast(pointer); + if (data_ptr[0] == 0xE9) + { + original_data.resize(6); + memmove(original_data.data(), pointer, original_data.size()); + + auto* target = follow_branch(data_ptr); + nop(data_ptr, 1); + jump(data_ptr + 1, target); + } + else if (data_ptr[0] == 0xFF && data_ptr[1] == 0x25) + { + original_data.resize(15); + memmove(original_data.data(), pointer, original_data.size()); + + copy(data_ptr + 1, data_ptr, 14); + nop(data_ptr, 1); + } + else + { + throw std::runtime_error("No branch instruction found"); + } + + return original_data; + } + + std::vector move_hook(const size_t pointer) + { + return move_hook(reinterpret_cast(pointer)); + } + + void* follow_branch(void* address) + { + auto* const data = static_cast(address); + if (*data != 0xE8 && *data != 0xE9) + { + throw std::runtime_error("No branch instruction found"); + } + + return extract(data + 1); + } +} diff --git a/hook_lib/common/utils/hook.hpp b/hook_lib/common/utils/hook.hpp index 12bc5b4..81883c0 100644 --- a/hook_lib/common/utils/hook.hpp +++ b/hook_lib/common/utils/hook.hpp @@ -1,186 +1,186 @@ -#pragma once -#include "signature.hpp" - -#pragma comment(lib, "minhook.lib") - -namespace utils::hook -{ - namespace detail - { - template - std::vector get_iota_functions() - { - if constexpr (Entries == 0) - { - std::vector functions; - return functions; - } - else - { - auto functions = get_iota_functions(); - functions.emplace_back([]() - { - return Entries - 1; - }); - return functions; - } - } - } - - // Gets the pointer to the entry in the v-table. - // It seems otherwise impossible to get this. - // This is ugly as fuck and only safely works on x64 - // Example: - // ID3D11Device* device = ... - // auto entry = get_vtable_entry(device, &ID3D11Device::CreateTexture2D); - template - void** get_vtable_entry(Class* obj, T (Class::* entry)(Args ...)) - { - union - { - decltype(entry) func; - void* pointer; - }; - - func = entry; - - auto iota_functions = detail::get_iota_functions(); - auto* object = iota_functions.data(); - - using fake_func = size_t(__thiscall*)(void* self); - auto index = static_cast(pointer)(&object); - - void** obj_v_table = *reinterpret_cast(obj); - return &obj_v_table[index]; - } - - - class detour - { - public: - detour(); - detour(void* place, void* target); - detour(size_t place, void* target); - ~detour(); - - detour(detour&& other) noexcept - { - this->operator=(std::move(other)); - } - - detour& operator=(detour&& other) noexcept - { - if (this != &other) - { - this->clear(); - - this->place_ = other.place_; - this->original_ = other.original_; - this->moved_data_ = other.moved_data_; - - other.place_ = nullptr; - other.original_ = nullptr; - other.moved_data_ = {}; - } - - return *this; - } - - detour(const detour&) = delete; - detour& operator=(const detour&) = delete; - - void enable(); - void disable(); - - void create(void* place, void* target); - void create(size_t place, void* target); - void clear(); - - void move(); - - void* get_place() const; - - template - T* get() const - { - return static_cast(this->get_original()); - } - - template - T stub(Args ... args) - { - return static_cast(this->get_original())(args...); - } - - [[nodiscard]] void* get_original() const; - - private: - std::vector moved_data_{}; - void* place_{}; - void* original_{}; - - void un_move(); - }; - - std::optional> iat(const nt::library& library, const std::string& target_library, - const std::string& process, void* stub); - - void nop(void* place, size_t length); - void nop(size_t place, size_t length); - - void copy(void* place, const void* data, size_t length); - void copy(size_t place, const void* data, size_t length); - - void copy_string(void* place, const char* str); - void copy_string(size_t place, const char* str); - - bool is_relatively_far(const void* pointer, const void* data, int offset = 5); - - void call(void* pointer, void* data); - void call(size_t pointer, void* data); - void call(size_t pointer, size_t data); - - void jump(void* pointer, void* data, bool use_far = false, bool use_safe = false); - void jump(size_t pointer, void* data, bool use_far = false, bool use_safe = false); - void jump(size_t pointer, size_t data, bool use_far = false, bool use_safe = false); - - void inject(void* pointer, const void* data); - void inject(size_t pointer, const void* data); - - std::vector move_hook(void* pointer); - std::vector move_hook(size_t pointer); - - template - T extract(void* address) - { - auto* const data = static_cast(address); - const auto offset = *reinterpret_cast(data); - return reinterpret_cast(data + offset + 4); - } - - void* follow_branch(void* address); - - template - static void set(void* place, T value = false) - { - copy(place, &value, sizeof(value)); - } - - template - static void set(const size_t place, T value = false) - { - return set(reinterpret_cast(place), value); - } - - template - static T invoke(size_t func, Args ... args) - { - return reinterpret_cast(func)(args...); - } - - template - static T invoke(void* func, Args ... args) - { - return static_cast(func)(args...); - } -} +#pragma once +#include "signature.hpp" + +#pragma comment(lib, "minhook.lib") + +namespace utils::hook +{ + namespace detail + { + template + std::vector get_iota_functions() + { + if constexpr (Entries == 0) + { + std::vector functions; + return functions; + } + else + { + auto functions = get_iota_functions(); + functions.emplace_back([]() + { + return Entries - 1; + }); + return functions; + } + } + } + + // Gets the pointer to the entry in the v-table. + // It seems otherwise impossible to get this. + // This is ugly as fuck and only safely works on x64 + // Example: + // ID3D11Device* device = ... + // auto entry = get_vtable_entry(device, &ID3D11Device::CreateTexture2D); + template + void** get_vtable_entry(Class* obj, T (Class::* entry)(Args ...)) + { + union + { + decltype(entry) func; + void* pointer; + }; + + func = entry; + + auto iota_functions = detail::get_iota_functions(); + auto* object = iota_functions.data(); + + using fake_func = size_t(__thiscall*)(void* self); + auto index = static_cast(pointer)(&object); + + void** obj_v_table = *reinterpret_cast(obj); + return &obj_v_table[index]; + } + + + class detour + { + public: + detour(); + detour(void* place, void* target); + detour(size_t place, void* target); + ~detour(); + + detour(detour&& other) noexcept + { + this->operator=(std::move(other)); + } + + detour& operator=(detour&& other) noexcept + { + if (this != &other) + { + this->clear(); + + this->place_ = other.place_; + this->original_ = other.original_; + this->moved_data_ = other.moved_data_; + + other.place_ = nullptr; + other.original_ = nullptr; + other.moved_data_ = {}; + } + + return *this; + } + + detour(const detour&) = delete; + detour& operator=(const detour&) = delete; + + void enable(); + void disable(); + + void create(void* place, void* target); + void create(size_t place, void* target); + void clear(); + + void move(); + + void* get_place() const; + + template + T* get() const + { + return static_cast(this->get_original()); + } + + template + T stub(Args ... args) + { + return static_cast(this->get_original())(args...); + } + + [[nodiscard]] void* get_original() const; + + private: + std::vector moved_data_{}; + void* place_{}; + void* original_{}; + + void un_move(); + }; + + std::optional> iat(const nt::library& library, const std::string& target_library, + const std::string& process, void* stub); + + void nop(void* place, size_t length); + void nop(size_t place, size_t length); + + void copy(void* place, const void* data, size_t length); + void copy(size_t place, const void* data, size_t length); + + void copy_string(void* place, const char* str); + void copy_string(size_t place, const char* str); + + bool is_relatively_far(const void* pointer, const void* data, int offset = 5); + + void call(void* pointer, void* data); + void call(size_t pointer, void* data); + void call(size_t pointer, size_t data); + + void jump(void* pointer, void* data, bool use_far = false, bool use_safe = false); + void jump(size_t pointer, void* data, bool use_far = false, bool use_safe = false); + void jump(size_t pointer, size_t data, bool use_far = false, bool use_safe = false); + + void inject(void* pointer, const void* data); + void inject(size_t pointer, const void* data); + + std::vector move_hook(void* pointer); + std::vector move_hook(size_t pointer); + + template + T extract(void* address) + { + auto* const data = static_cast(address); + const auto offset = *reinterpret_cast(data); + return reinterpret_cast(data + offset + 4); + } + + void* follow_branch(void* address); + + template + static void set(void* place, T value = false) + { + copy(place, &value, sizeof(value)); + } + + template + static void set(const size_t place, T value = false) + { + return set(reinterpret_cast(place), value); + } + + template + static T invoke(size_t func, Args ... args) + { + return reinterpret_cast(func)(args...); + } + + template + static T invoke(void* func, Args ... args) + { + return static_cast(func)(args...); + } +} diff --git a/hook_lib/common/utils/http.cpp b/hook_lib/common/utils/http.cpp index 9b7f73e..3cb5999 100644 --- a/hook_lib/common/utils/http.cpp +++ b/hook_lib/common/utils/http.cpp @@ -1,48 +1,48 @@ -#include "http.hpp" -#include "nt.hpp" -#include - -namespace utils::http -{ - std::optional get_data(const std::string& url) - { - CComPtr stream; - - if (FAILED(URLOpenBlockingStreamA(nullptr, url.data(), &stream, 0, nullptr))) - { - return {}; - } - - char buffer[0x1000]; - std::string result; - - HRESULT status{}; - - do - { - DWORD bytes_read = 0; - status = stream->Read(buffer, sizeof(buffer), &bytes_read); - - if (bytes_read > 0) - { - result.append(buffer, bytes_read); - } - } - while (SUCCEEDED(status) && status != S_FALSE); - - if (FAILED(status)) - { - return {}; - } - - return {result}; - } - - std::future> get_data_async(const std::string& url) - { - return std::async(std::launch::async, [url]() - { - return get_data(url); - }); - } -} +#include "http.hpp" +#include "nt.hpp" +#include + +namespace utils::http +{ + std::optional get_data(const std::string& url) + { + CComPtr stream; + + if (FAILED(URLOpenBlockingStreamA(nullptr, url.data(), &stream, 0, nullptr))) + { + return {}; + } + + char buffer[0x1000]; + std::string result; + + HRESULT status{}; + + do + { + DWORD bytes_read = 0; + status = stream->Read(buffer, sizeof(buffer), &bytes_read); + + if (bytes_read > 0) + { + result.append(buffer, bytes_read); + } + } + while (SUCCEEDED(status) && status != S_FALSE); + + if (FAILED(status)) + { + return {}; + } + + return {result}; + } + + std::future> get_data_async(const std::string& url) + { + return std::async(std::launch::async, [url]() + { + return get_data(url); + }); + } +} diff --git a/hook_lib/common/utils/http.hpp b/hook_lib/common/utils/http.hpp index cd4aba4..cdfb79c 100644 --- a/hook_lib/common/utils/http.hpp +++ b/hook_lib/common/utils/http.hpp @@ -1,13 +1,13 @@ -#pragma once - -#include -#include -#include - -#pragma comment(lib, "Urlmon.lib") - -namespace utils::http -{ - std::optional get_data(const std::string& url); - std::future> get_data_async(const std::string& url); -} +#pragma once + +#include +#include +#include + +#pragma comment(lib, "Urlmon.lib") + +namespace utils::http +{ + std::optional get_data(const std::string& url); + std::future> get_data_async(const std::string& url); +} diff --git a/hook_lib/common/utils/io.cpp b/hook_lib/common/utils/io.cpp index 163d205..45f2ab9 100644 --- a/hook_lib/common/utils/io.cpp +++ b/hook_lib/common/utils/io.cpp @@ -1,130 +1,130 @@ -#include "io.hpp" -#include "nt.hpp" -#include - -namespace utils::io -{ - bool remove_file(const std::filesystem::path& file) - { - if(DeleteFileW(file.wstring().data()) != FALSE) - { - return true; - } - - return GetLastError() == ERROR_FILE_NOT_FOUND; - } - - bool move_file(const std::filesystem::path& src, const std::filesystem::path& target) - { - return MoveFileW(src.wstring().data(), target.wstring().data()) == TRUE; - } - - bool file_exists(const std::string& file) - { - return std::ifstream(file).good(); - } - - bool write_file(const std::string& file, const std::string& data, const bool append) - { - const auto pos = file.find_last_of("/\\"); - if (pos != std::string::npos) - { - create_directory(file.substr(0, pos)); - } - - std::ofstream stream( - file, std::ios::binary | std::ofstream::out | (append ? std::ofstream::app : 0)); - - if (stream.is_open()) - { - stream.write(data.data(), static_cast(data.size())); - stream.close(); - return true; - } - - return false; - } - - std::string read_file(const std::string& file) - { - std::string data; - read_file(file, &data); - return data; - } - - bool read_file(const std::string& file, std::string* data) - { - if (!data) return false; - data->clear(); - - if (file_exists(file)) - { - std::ifstream stream(file, std::ios::binary); - if (!stream.is_open()) return false; - - stream.seekg(0, std::ios::end); - const std::streamsize size = stream.tellg(); - stream.seekg(0, std::ios::beg); - - if (size > -1) - { - data->resize(static_cast(size)); - stream.read(data->data(), size); - stream.close(); - return true; - } - } - - return false; - } - - std::size_t file_size(const std::string& file) - { - if (file_exists(file)) - { - std::ifstream stream(file, std::ios::binary); - - if (stream.good()) - { - stream.seekg(0, std::ios::end); - return static_cast(stream.tellg()); - } - } - - return 0; - } - - bool create_directory(const std::filesystem::path& directory) - { - return std::filesystem::create_directories(directory); - } - - bool directory_exists(const std::filesystem::path& directory) - { - return std::filesystem::is_directory(directory); - } - - bool directory_is_empty(const std::filesystem::path& directory) - { - return std::filesystem::is_empty(directory); - } - - std::vector list_files(const std::filesystem::path& directory) - { - std::vector files; - - for (auto& file : std::filesystem::directory_iterator(directory)) - { - files.push_back(file.path().generic_string()); - } - - return files; - } - - void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target) - { - std::filesystem::copy(src, target, - std::filesystem::copy_options::overwrite_existing | - std::filesystem::copy_options::recursive); - } -} +#include "io.hpp" +#include "nt.hpp" +#include + +namespace utils::io +{ + bool remove_file(const std::filesystem::path& file) + { + if(DeleteFileW(file.wstring().data()) != FALSE) + { + return true; + } + + return GetLastError() == ERROR_FILE_NOT_FOUND; + } + + bool move_file(const std::filesystem::path& src, const std::filesystem::path& target) + { + return MoveFileW(src.wstring().data(), target.wstring().data()) == TRUE; + } + + bool file_exists(const std::string& file) + { + return std::ifstream(file).good(); + } + + bool write_file(const std::string& file, const std::string& data, const bool append) + { + const auto pos = file.find_last_of("/\\"); + if (pos != std::string::npos) + { + create_directory(file.substr(0, pos)); + } + + std::ofstream stream( + file, std::ios::binary | std::ofstream::out | (append ? std::ofstream::app : 0)); + + if (stream.is_open()) + { + stream.write(data.data(), static_cast(data.size())); + stream.close(); + return true; + } + + return false; + } + + std::string read_file(const std::string& file) + { + std::string data; + read_file(file, &data); + return data; + } + + bool read_file(const std::string& file, std::string* data) + { + if (!data) return false; + data->clear(); + + if (file_exists(file)) + { + std::ifstream stream(file, std::ios::binary); + if (!stream.is_open()) return false; + + stream.seekg(0, std::ios::end); + const std::streamsize size = stream.tellg(); + stream.seekg(0, std::ios::beg); + + if (size > -1) + { + data->resize(static_cast(size)); + stream.read(data->data(), size); + stream.close(); + return true; + } + } + + return false; + } + + std::size_t file_size(const std::string& file) + { + if (file_exists(file)) + { + std::ifstream stream(file, std::ios::binary); + + if (stream.good()) + { + stream.seekg(0, std::ios::end); + return static_cast(stream.tellg()); + } + } + + return 0; + } + + bool create_directory(const std::filesystem::path& directory) + { + return std::filesystem::create_directories(directory); + } + + bool directory_exists(const std::filesystem::path& directory) + { + return std::filesystem::is_directory(directory); + } + + bool directory_is_empty(const std::filesystem::path& directory) + { + return std::filesystem::is_empty(directory); + } + + std::vector list_files(const std::filesystem::path& directory) + { + std::vector files; + + for (auto& file : std::filesystem::directory_iterator(directory)) + { + files.push_back(file.path().generic_string()); + } + + return files; + } + + void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target) + { + std::filesystem::copy(src, target, + std::filesystem::copy_options::overwrite_existing | + std::filesystem::copy_options::recursive); + } +} diff --git a/hook_lib/common/utils/io.hpp b/hook_lib/common/utils/io.hpp index 1bf1b19..5247683 100644 --- a/hook_lib/common/utils/io.hpp +++ b/hook_lib/common/utils/io.hpp @@ -1,21 +1,21 @@ -#pragma once - -#include -#include -#include - -namespace utils::io -{ - bool remove_file(const std::filesystem::path& file); - bool move_file(const std::filesystem::path& src, const std::filesystem::path& target); - bool file_exists(const std::string& file); - bool write_file(const std::string& file, const std::string& data, bool append = false); - bool read_file(const std::string& file, std::string* data); - std::string read_file(const std::string& file); - size_t file_size(const std::string& file); - bool create_directory(const std::filesystem::path& directory); - bool directory_exists(const std::filesystem::path& directory); - bool directory_is_empty(const std::filesystem::path& directory); - std::vector list_files(const std::filesystem::path& directory); - void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target); -} +#pragma once + +#include +#include +#include + +namespace utils::io +{ + bool remove_file(const std::filesystem::path& file); + bool move_file(const std::filesystem::path& src, const std::filesystem::path& target); + bool file_exists(const std::string& file); + bool write_file(const std::string& file, const std::string& data, bool append = false); + bool read_file(const std::string& file, std::string* data); + std::string read_file(const std::string& file); + size_t file_size(const std::string& file); + bool create_directory(const std::filesystem::path& directory); + bool directory_exists(const std::filesystem::path& directory); + bool directory_is_empty(const std::filesystem::path& directory); + std::vector list_files(const std::filesystem::path& directory); + void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target); +} diff --git a/hook_lib/common/utils/memory.cpp b/hook_lib/common/utils/memory.cpp index 1ac255e..5fdbd80 100644 --- a/hook_lib/common/utils/memory.cpp +++ b/hook_lib/common/utils/memory.cpp @@ -1,170 +1,170 @@ -#include "memory.hpp" -#include "nt.hpp" - -namespace utils -{ - memory::allocator memory::mem_allocator_; - - memory::allocator::~allocator() - { - this->clear(); - } - - void memory::allocator::clear() - { - std::lock_guard _(this->mutex_); - - for (auto& data : this->pool_) - { - memory::free(data); - } - - this->pool_.clear(); - } - - void memory::allocator::free(void* data) - { - std::lock_guard _(this->mutex_); - - const auto j = std::find(this->pool_.begin(), this->pool_.end(), data); - if (j != this->pool_.end()) - { - memory::free(data); - this->pool_.erase(j); - } - } - - void memory::allocator::free(const void* data) - { - this->free(const_cast(data)); - } - - void* memory::allocator::allocate(const size_t length) - { - std::lock_guard _(this->mutex_); - - const auto data = memory::allocate(length); - this->pool_.push_back(data); - return data; - } - - bool memory::allocator::empty() const - { - return this->pool_.empty(); - } - - char* memory::allocator::duplicate_string(const std::string& string) - { - std::lock_guard _(this->mutex_); - - const auto data = memory::duplicate_string(string); - this->pool_.push_back(data); - return data; - } - - bool memory::allocator::find(const void* data) - { - std::lock_guard _(this->mutex_); - - const auto j = std::find(this->pool_.begin(), this->pool_.end(), data); - return j != this->pool_.end(); - } - - void* memory::allocate(const size_t length) - { - return std::calloc(length, 1); - } - - char* memory::duplicate_string(const std::string& string) - { - const auto new_string = allocate_array(string.size() + 1); - std::memcpy(new_string, string.data(), string.size()); - return new_string; - } - - void memory::free(void* data) - { - std::free(data); - } - - void memory::free(const void* data) - { - free(const_cast(data)); - } - - bool memory::is_set(const void* mem, const char chr, const size_t length) - { - const auto mem_arr = static_cast(mem); - - for (size_t i = 0; i < length; ++i) - { - if (mem_arr[i] != chr) - { - return false; - } - } - - return true; - } - - bool memory::is_bad_read_ptr(const void* ptr) - { - MEMORY_BASIC_INFORMATION mbi = {}; - if (VirtualQuery(ptr, &mbi, sizeof(mbi))) - { - const DWORD mask = (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | - PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); - auto b = !(mbi.Protect & mask); - // check the page is not a guard page - if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) b = true; - - return b; - } - return true; - } - - bool memory::is_bad_code_ptr(const void* ptr) - { - MEMORY_BASIC_INFORMATION mbi = {}; - if (VirtualQuery(ptr, &mbi, sizeof(mbi))) - { - const DWORD mask = (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); - auto b = !(mbi.Protect & mask); - // check the page is not a guard page - if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) b = true; - - return b; - } - return true; - } - - bool memory::is_rdata_ptr(void* pointer) - { - const std::string rdata = ".rdata"; - const auto pointer_lib = utils::nt::library::get_by_address(pointer); - - for (const auto& section : pointer_lib.get_section_headers()) - { - const auto size = sizeof(section->Name); - char name[size + 1]; - name[size] = 0; - std::memcpy(name, section->Name, size); - - if (name == rdata) - { - const auto target = size_t(pointer); - const size_t source_start = size_t(pointer_lib.get_ptr()) + section->PointerToRawData; - const size_t source_end = source_start + section->SizeOfRawData; - - return target >= source_start && target <= source_end; - } - } - - return false; - } - - memory::allocator* memory::get_allocator() - { - return &memory::mem_allocator_; - } -} +#include "memory.hpp" +#include "nt.hpp" + +namespace utils +{ + memory::allocator memory::mem_allocator_; + + memory::allocator::~allocator() + { + this->clear(); + } + + void memory::allocator::clear() + { + std::lock_guard _(this->mutex_); + + for (auto& data : this->pool_) + { + memory::free(data); + } + + this->pool_.clear(); + } + + void memory::allocator::free(void* data) + { + std::lock_guard _(this->mutex_); + + const auto j = std::find(this->pool_.begin(), this->pool_.end(), data); + if (j != this->pool_.end()) + { + memory::free(data); + this->pool_.erase(j); + } + } + + void memory::allocator::free(const void* data) + { + this->free(const_cast(data)); + } + + void* memory::allocator::allocate(const size_t length) + { + std::lock_guard _(this->mutex_); + + const auto data = memory::allocate(length); + this->pool_.push_back(data); + return data; + } + + bool memory::allocator::empty() const + { + return this->pool_.empty(); + } + + char* memory::allocator::duplicate_string(const std::string& string) + { + std::lock_guard _(this->mutex_); + + const auto data = memory::duplicate_string(string); + this->pool_.push_back(data); + return data; + } + + bool memory::allocator::find(const void* data) + { + std::lock_guard _(this->mutex_); + + const auto j = std::find(this->pool_.begin(), this->pool_.end(), data); + return j != this->pool_.end(); + } + + void* memory::allocate(const size_t length) + { + return std::calloc(length, 1); + } + + char* memory::duplicate_string(const std::string& string) + { + const auto new_string = allocate_array(string.size() + 1); + std::memcpy(new_string, string.data(), string.size()); + return new_string; + } + + void memory::free(void* data) + { + std::free(data); + } + + void memory::free(const void* data) + { + free(const_cast(data)); + } + + bool memory::is_set(const void* mem, const char chr, const size_t length) + { + const auto mem_arr = static_cast(mem); + + for (size_t i = 0; i < length; ++i) + { + if (mem_arr[i] != chr) + { + return false; + } + } + + return true; + } + + bool memory::is_bad_read_ptr(const void* ptr) + { + MEMORY_BASIC_INFORMATION mbi = {}; + if (VirtualQuery(ptr, &mbi, sizeof(mbi))) + { + const DWORD mask = (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | + PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); + auto b = !(mbi.Protect & mask); + // check the page is not a guard page + if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) b = true; + + return b; + } + return true; + } + + bool memory::is_bad_code_ptr(const void* ptr) + { + MEMORY_BASIC_INFORMATION mbi = {}; + if (VirtualQuery(ptr, &mbi, sizeof(mbi))) + { + const DWORD mask = (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); + auto b = !(mbi.Protect & mask); + // check the page is not a guard page + if (mbi.Protect & (PAGE_GUARD | PAGE_NOACCESS)) b = true; + + return b; + } + return true; + } + + bool memory::is_rdata_ptr(void* pointer) + { + const std::string rdata = ".rdata"; + const auto pointer_lib = utils::nt::library::get_by_address(pointer); + + for (const auto& section : pointer_lib.get_section_headers()) + { + const auto size = sizeof(section->Name); + char name[size + 1]; + name[size] = 0; + std::memcpy(name, section->Name, size); + + if (name == rdata) + { + const auto target = size_t(pointer); + const size_t source_start = size_t(pointer_lib.get_ptr()) + section->PointerToRawData; + const size_t source_end = source_start + section->SizeOfRawData; + + return target >= source_start && target <= source_end; + } + } + + return false; + } + + memory::allocator* memory::get_allocator() + { + return &memory::mem_allocator_; + } +} diff --git a/hook_lib/common/utils/memory.hpp b/hook_lib/common/utils/memory.hpp index e449c45..6c8455c 100644 --- a/hook_lib/common/utils/memory.hpp +++ b/hook_lib/common/utils/memory.hpp @@ -1,77 +1,77 @@ -#pragma once - -#include -#include - -namespace utils -{ - class memory final - { - public: - class allocator final - { - public: - ~allocator(); - - void clear(); - - void free(void* data); - - void free(const void* data); - - void* allocate(size_t length); - - template - T* allocate() - { - return this->allocate_array(1); - } - - template - T* allocate_array(const size_t count = 1) - { - return static_cast(this->allocate(count * sizeof(T))); - } - - bool empty() const; - - char* duplicate_string(const std::string& string); - - bool find(const void* data); - - private: - std::mutex mutex_; - std::vector pool_; - }; - - static void* allocate(size_t length); - - template - static T* allocate() - { - return allocate_array(1); - } - - template - static T* allocate_array(const size_t count = 1) - { - return static_cast(allocate(count * sizeof(T))); - } - - static char* duplicate_string(const std::string& string); - - static void free(void* data); - static void free(const void* data); - - static bool is_set(const void* mem, char chr, size_t length); - - static bool is_bad_read_ptr(const void* ptr); - static bool is_bad_code_ptr(const void* ptr); - static bool is_rdata_ptr(void* ptr); - - static allocator* get_allocator(); - - private: - static allocator mem_allocator_; - }; -} +#pragma once + +#include +#include + +namespace utils +{ + class memory final + { + public: + class allocator final + { + public: + ~allocator(); + + void clear(); + + void free(void* data); + + void free(const void* data); + + void* allocate(size_t length); + + template + T* allocate() + { + return this->allocate_array(1); + } + + template + T* allocate_array(const size_t count = 1) + { + return static_cast(this->allocate(count * sizeof(T))); + } + + bool empty() const; + + char* duplicate_string(const std::string& string); + + bool find(const void* data); + + private: + std::mutex mutex_; + std::vector pool_; + }; + + static void* allocate(size_t length); + + template + static T* allocate() + { + return allocate_array(1); + } + + template + static T* allocate_array(const size_t count = 1) + { + return static_cast(allocate(count * sizeof(T))); + } + + static char* duplicate_string(const std::string& string); + + static void free(void* data); + static void free(const void* data); + + static bool is_set(const void* mem, char chr, size_t length); + + static bool is_bad_read_ptr(const void* ptr); + static bool is_bad_code_ptr(const void* ptr); + static bool is_rdata_ptr(void* ptr); + + static allocator* get_allocator(); + + private: + static allocator mem_allocator_; + }; +} diff --git a/hook_lib/common/utils/nt.cpp b/hook_lib/common/utils/nt.cpp index 713a03a..f6b07ad 100644 --- a/hook_lib/common/utils/nt.cpp +++ b/hook_lib/common/utils/nt.cpp @@ -1,291 +1,291 @@ -#include "nt.hpp" - -namespace utils::nt -{ - library library::load(const char* name) - { - return library(LoadLibraryA(name)); - } - - library library::load(const std::string& name) - { - return library::load(name.data()); - } - - library library::load(const std::filesystem::path& path) - { - return library::load(path.generic_string()); - } - - library library::get_by_address(const void* address) - { - HMODULE handle = nullptr; - GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - static_cast(address), &handle); - return library(handle); - } - - library::library() - : module_(GetModuleHandleA(nullptr)) - { - } - - library::library(const std::string& name) - : module_(GetModuleHandleA(name.data())) - { - } - - library::library(const HMODULE handle) - : module_(handle) - { - } - - bool library::operator==(const library& obj) const - { - return this->module_ == obj.module_; - } - - library::operator bool() const - { - return this->is_valid(); - } - - library::operator HMODULE() const - { - return this->get_handle(); - } - - PIMAGE_NT_HEADERS library::get_nt_headers() const - { - if (!this->is_valid()) return nullptr; - return reinterpret_cast(this->get_ptr() + this->get_dos_header()->e_lfanew); - } - - PIMAGE_DOS_HEADER library::get_dos_header() const - { - return reinterpret_cast(this->get_ptr()); - } - - PIMAGE_OPTIONAL_HEADER library::get_optional_header() const - { - if (!this->is_valid()) return nullptr; - return &this->get_nt_headers()->OptionalHeader; - } - - std::vector library::get_section_headers() const - { - std::vector headers; - - auto nt_headers = this->get_nt_headers(); - auto section = IMAGE_FIRST_SECTION(nt_headers); - - for (uint16_t i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i, ++section) - { - if (section) headers.push_back(section); - else OutputDebugStringA("There was an invalid section :O"); - } - - return headers; - } - - std::uint8_t* library::get_ptr() const - { - return reinterpret_cast(this->module_); - } - - void library::unprotect() const - { - if (!this->is_valid()) return; - - DWORD protection; - VirtualProtect(this->get_ptr(), this->get_optional_header()->SizeOfImage, PAGE_EXECUTE_READWRITE, - &protection); - } - - size_t library::get_relative_entry_point() const - { - if (!this->is_valid()) return 0; - return this->get_nt_headers()->OptionalHeader.AddressOfEntryPoint; - } - - void* library::get_entry_point() const - { - if (!this->is_valid()) return nullptr; - return this->get_ptr() + this->get_relative_entry_point(); - } - - bool library::is_valid() const - { - return this->module_ != nullptr && this->get_dos_header()->e_magic == IMAGE_DOS_SIGNATURE; - } - - std::string library::get_name() const - { - if (!this->is_valid()) return {}; - - const auto path = this->get_path(); - const auto pos = path.generic_string().find_last_of("/\\"); - if (pos == std::string::npos) return path.generic_string(); - - return path.generic_string().substr(pos + 1); - } - - std::filesystem::path library::get_path() const - { - if (!this->is_valid()) return {}; - - wchar_t name[MAX_PATH] = {0}; - GetModuleFileNameW(this->module_, name, MAX_PATH); - - return {name}; - } - - std::filesystem::path library::get_folder() const - { - if (!this->is_valid()) return {}; - - const auto path = std::filesystem::path(this->get_path()); - return path.parent_path().generic_string(); - } - - void library::free() - { - if (this->is_valid()) - { - FreeLibrary(this->module_); - this->module_ = nullptr; - } - } - - HMODULE library::get_handle() const - { - return this->module_; - } - - void** library::get_iat_entry(const std::string& module_name, const std::string& proc_name) const - { - if (!this->is_valid()) return nullptr; - - const library other_module(module_name); - if (!other_module.is_valid()) return nullptr; - - auto* const target_function = other_module.get_proc(proc_name); - if (!target_function) return nullptr; - - auto* header = this->get_optional_header(); - if (!header) return nullptr; - - auto* import_descriptor = reinterpret_cast(this->get_ptr() + header->DataDirectory - [IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); - - while (import_descriptor->Name) - { - if (!_stricmp(reinterpret_cast(this->get_ptr() + import_descriptor->Name), module_name.data())) - { - auto* original_thunk_data = reinterpret_cast(import_descriptor-> - OriginalFirstThunk + this->get_ptr()); - auto* thunk_data = reinterpret_cast(import_descriptor->FirstThunk + this-> - get_ptr()); - - while (original_thunk_data->u1.AddressOfData) - { - if (thunk_data->u1.Function == reinterpret_cast(target_function)) - { - return reinterpret_cast(&thunk_data->u1.Function); - } - - const size_t ordinal_number = original_thunk_data->u1.AddressOfData & 0xFFFFFFF; - - if (ordinal_number <= 0xFFFF) - { - auto* proc = GetProcAddress(other_module.module_, reinterpret_cast(ordinal_number)); - if (reinterpret_cast(proc) == target_function) - { - return reinterpret_cast(&thunk_data->u1.Function); - } - } - - ++original_thunk_data; - ++thunk_data; - } - - //break; - } - - ++import_descriptor; - } - - return nullptr; - } - - bool is_wine() - { - static const auto has_wine_export = []() -> bool - { - const library ntdll("ntdll.dll"); - return ntdll.get_proc("wine_get_version"); - }(); - - return has_wine_export; - } - - bool is_shutdown_in_progress() - { - static auto* shutdown_in_progress = [] - { - const library ntdll("ntdll.dll"); - return ntdll.get_proc("RtlDllShutdownInProgress"); - }(); - - return shutdown_in_progress(); - } - - void raise_hard_exception() - { - int data = false; - const library ntdll("ntdll.dll"); - ntdll.invoke_pascal("RtlAdjustPrivilege", 19, true, false, &data); - ntdll.invoke_pascal("NtRaiseHardError", 0xC000007B, 0, nullptr, nullptr, 6, &data); - _Exit(0); - } - - std::string load_resource(const int id) - { - const auto lib = library::get_by_address(load_resource); - auto* const res = FindResource(lib, MAKEINTRESOURCE(id), RT_RCDATA); - if (!res) return {}; - - auto* const handle = LoadResource(lib, res); - if (!handle) return {}; - - return std::string(LPSTR(LockResource(handle)), SizeofResource(lib, res)); - } - - void relaunch_self() - { - const auto self = utils::nt::library::get_by_address(relaunch_self); - - STARTUPINFOA startup_info; - PROCESS_INFORMATION process_info; - - ZeroMemory(&startup_info, sizeof(startup_info)); - ZeroMemory(&process_info, sizeof(process_info)); - startup_info.cb = sizeof(startup_info); - - char current_dir[MAX_PATH]; - GetCurrentDirectoryA(sizeof(current_dir), current_dir); - auto* const command_line = GetCommandLineA(); - - CreateProcessA(self.get_path().generic_string().data(), command_line, nullptr, nullptr, false, NULL, nullptr, current_dir, - &startup_info, &process_info); - - if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread); - if (process_info.hProcess && process_info.hProcess != INVALID_HANDLE_VALUE) CloseHandle(process_info.hProcess); - } - - void terminate(const uint32_t code) - { - TerminateProcess(GetCurrentProcess(), code); - _Exit(code); - } -} +#include "nt.hpp" + +namespace utils::nt +{ + library library::load(const char* name) + { + return library(LoadLibraryA(name)); + } + + library library::load(const std::string& name) + { + return library::load(name.data()); + } + + library library::load(const std::filesystem::path& path) + { + return library::load(path.generic_string()); + } + + library library::get_by_address(const void* address) + { + HMODULE handle = nullptr; + GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + static_cast(address), &handle); + return library(handle); + } + + library::library() + : module_(GetModuleHandleA(nullptr)) + { + } + + library::library(const std::string& name) + : module_(GetModuleHandleA(name.data())) + { + } + + library::library(const HMODULE handle) + : module_(handle) + { + } + + bool library::operator==(const library& obj) const + { + return this->module_ == obj.module_; + } + + library::operator bool() const + { + return this->is_valid(); + } + + library::operator HMODULE() const + { + return this->get_handle(); + } + + PIMAGE_NT_HEADERS library::get_nt_headers() const + { + if (!this->is_valid()) return nullptr; + return reinterpret_cast(this->get_ptr() + this->get_dos_header()->e_lfanew); + } + + PIMAGE_DOS_HEADER library::get_dos_header() const + { + return reinterpret_cast(this->get_ptr()); + } + + PIMAGE_OPTIONAL_HEADER library::get_optional_header() const + { + if (!this->is_valid()) return nullptr; + return &this->get_nt_headers()->OptionalHeader; + } + + std::vector library::get_section_headers() const + { + std::vector headers; + + auto nt_headers = this->get_nt_headers(); + auto section = IMAGE_FIRST_SECTION(nt_headers); + + for (uint16_t i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i, ++section) + { + if (section) headers.push_back(section); + else OutputDebugStringA("There was an invalid section :O"); + } + + return headers; + } + + std::uint8_t* library::get_ptr() const + { + return reinterpret_cast(this->module_); + } + + void library::unprotect() const + { + if (!this->is_valid()) return; + + DWORD protection; + VirtualProtect(this->get_ptr(), this->get_optional_header()->SizeOfImage, PAGE_EXECUTE_READWRITE, + &protection); + } + + size_t library::get_relative_entry_point() const + { + if (!this->is_valid()) return 0; + return this->get_nt_headers()->OptionalHeader.AddressOfEntryPoint; + } + + void* library::get_entry_point() const + { + if (!this->is_valid()) return nullptr; + return this->get_ptr() + this->get_relative_entry_point(); + } + + bool library::is_valid() const + { + return this->module_ != nullptr && this->get_dos_header()->e_magic == IMAGE_DOS_SIGNATURE; + } + + std::string library::get_name() const + { + if (!this->is_valid()) return {}; + + const auto path = this->get_path(); + const auto pos = path.generic_string().find_last_of("/\\"); + if (pos == std::string::npos) return path.generic_string(); + + return path.generic_string().substr(pos + 1); + } + + std::filesystem::path library::get_path() const + { + if (!this->is_valid()) return {}; + + wchar_t name[MAX_PATH] = {0}; + GetModuleFileNameW(this->module_, name, MAX_PATH); + + return {name}; + } + + std::filesystem::path library::get_folder() const + { + if (!this->is_valid()) return {}; + + const auto path = std::filesystem::path(this->get_path()); + return path.parent_path().generic_string(); + } + + void library::free() + { + if (this->is_valid()) + { + FreeLibrary(this->module_); + this->module_ = nullptr; + } + } + + HMODULE library::get_handle() const + { + return this->module_; + } + + void** library::get_iat_entry(const std::string& module_name, const std::string& proc_name) const + { + if (!this->is_valid()) return nullptr; + + const library other_module(module_name); + if (!other_module.is_valid()) return nullptr; + + auto* const target_function = other_module.get_proc(proc_name); + if (!target_function) return nullptr; + + auto* header = this->get_optional_header(); + if (!header) return nullptr; + + auto* import_descriptor = reinterpret_cast(this->get_ptr() + header->DataDirectory + [IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + + while (import_descriptor->Name) + { + if (!_stricmp(reinterpret_cast(this->get_ptr() + import_descriptor->Name), module_name.data())) + { + auto* original_thunk_data = reinterpret_cast(import_descriptor-> + OriginalFirstThunk + this->get_ptr()); + auto* thunk_data = reinterpret_cast(import_descriptor->FirstThunk + this-> + get_ptr()); + + while (original_thunk_data->u1.AddressOfData) + { + if (thunk_data->u1.Function == reinterpret_cast(target_function)) + { + return reinterpret_cast(&thunk_data->u1.Function); + } + + const size_t ordinal_number = original_thunk_data->u1.AddressOfData & 0xFFFFFFF; + + if (ordinal_number <= 0xFFFF) + { + auto* proc = GetProcAddress(other_module.module_, reinterpret_cast(ordinal_number)); + if (reinterpret_cast(proc) == target_function) + { + return reinterpret_cast(&thunk_data->u1.Function); + } + } + + ++original_thunk_data; + ++thunk_data; + } + + //break; + } + + ++import_descriptor; + } + + return nullptr; + } + + bool is_wine() + { + static const auto has_wine_export = []() -> bool + { + const library ntdll("ntdll.dll"); + return ntdll.get_proc("wine_get_version"); + }(); + + return has_wine_export; + } + + bool is_shutdown_in_progress() + { + static auto* shutdown_in_progress = [] + { + const library ntdll("ntdll.dll"); + return ntdll.get_proc("RtlDllShutdownInProgress"); + }(); + + return shutdown_in_progress(); + } + + void raise_hard_exception() + { + int data = false; + const library ntdll("ntdll.dll"); + ntdll.invoke_pascal("RtlAdjustPrivilege", 19, true, false, &data); + ntdll.invoke_pascal("NtRaiseHardError", 0xC000007B, 0, nullptr, nullptr, 6, &data); + _Exit(0); + } + + std::string load_resource(const int id) + { + const auto lib = library::get_by_address(load_resource); + auto* const res = FindResource(lib, MAKEINTRESOURCE(id), RT_RCDATA); + if (!res) return {}; + + auto* const handle = LoadResource(lib, res); + if (!handle) return {}; + + return std::string(LPSTR(LockResource(handle)), SizeofResource(lib, res)); + } + + void relaunch_self() + { + const auto self = utils::nt::library::get_by_address(relaunch_self); + + STARTUPINFOA startup_info; + PROCESS_INFORMATION process_info; + + ZeroMemory(&startup_info, sizeof(startup_info)); + ZeroMemory(&process_info, sizeof(process_info)); + startup_info.cb = sizeof(startup_info); + + char current_dir[MAX_PATH]; + GetCurrentDirectoryA(sizeof(current_dir), current_dir); + auto* const command_line = GetCommandLineA(); + + CreateProcessA(self.get_path().generic_string().data(), command_line, nullptr, nullptr, false, NULL, nullptr, current_dir, + &startup_info, &process_info); + + if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread); + if (process_info.hProcess && process_info.hProcess != INVALID_HANDLE_VALUE) CloseHandle(process_info.hProcess); + } + + void terminate(const uint32_t code) + { + TerminateProcess(GetCurrentProcess(), code); + _Exit(code); + } +} diff --git a/hook_lib/common/utils/nt.hpp b/hook_lib/common/utils/nt.hpp index ae7a886..962ed6d 100644 --- a/hook_lib/common/utils/nt.hpp +++ b/hook_lib/common/utils/nt.hpp @@ -1,177 +1,177 @@ -#pragma once - -#define WIN32_LEAN_AND_MEAN -#include - -// min and max is required by gdi, therefore NOMINMAX won't work -#ifdef max -#undef max -#endif - -#ifdef min -#undef min -#endif - -#include -#include -#include - -namespace utils::nt -{ - class library final - { - public: - static library load(const char* name); - static library load(const std::string& name); - static library load(const std::filesystem::path& path); - static library get_by_address(const void* address); - - library(); - explicit library(const std::string& name); - explicit library(HMODULE handle); - - library(const library& a) : module_(a.module_) - { - } - - bool operator!=(const library& obj) const { return !(*this == obj); }; - bool operator==(const library& obj) const; - - operator bool() const; - operator HMODULE() const; - - void unprotect() const; - [[nodiscard]] void* get_entry_point() const; - [[nodiscard]] size_t get_relative_entry_point() const; - - [[nodiscard]] bool is_valid() const; - [[nodiscard]] std::string get_name() const; - [[nodiscard]] std::filesystem::path get_path() const; - [[nodiscard]] std::filesystem::path get_folder() const; - [[nodiscard]] std::uint8_t* get_ptr() const; - void free(); - - [[nodiscard]] HMODULE get_handle() const; - - template - [[nodiscard]] T get_proc(const std::string& process) const - { - if (!this->is_valid()) T{}; - return reinterpret_cast(GetProcAddress(this->module_, process.data())); - } - - template - [[nodiscard]] std::function get(const std::string& process) const - { - if (!this->is_valid()) return std::function(); - return static_cast(this->get_proc(process)); - } - - template - T invoke(const std::string& process, Args ... args) const - { - auto method = this->get(process); - if (method) return method(args...); - return T(); - } - - template - T invoke_pascal(const std::string& process, Args ... args) const - { - auto method = this->get(process); - if (method) return method(args...); - return T(); - } - - template - T invoke_this(const std::string& process, void* this_ptr, Args ... args) const - { - auto method = this->get(this_ptr, process); - if (method) return method(args...); - return T(); - } - - [[nodiscard]] std::vector get_section_headers() const; - - [[nodiscard]] PIMAGE_NT_HEADERS get_nt_headers() const; - [[nodiscard]] PIMAGE_DOS_HEADER get_dos_header() const; - [[nodiscard]] PIMAGE_OPTIONAL_HEADER get_optional_header() const; - - [[nodiscard]] void** get_iat_entry(const std::string& module_name, const std::string& proc_name) const; - - private: - HMODULE module_; - }; - - template - class handle - { - public: - handle() = default; - - handle(const HANDLE h) - : handle_(h) - { - } - - ~handle() - { - if (*this) - { - CloseHandle(this->handle_); - this->handle_ = InvalidHandle; - } - } - - handle(const handle&) = delete; - handle& operator=(const handle&) = delete; - - handle(handle&& obj) noexcept - : handle() - { - this->operator=(std::move(obj)); - } - - handle& operator=(handle&& obj) noexcept - { - if (this != &obj) - { - this->~handle(); - this->handle_ = obj.handle_; - obj.handle_ = InvalidHandle; - } - - return *this; - } - - handle& operator=(HANDLE h) noexcept - { - this->~handle(); - this->handle_ = h; - - return *this; - } - - operator bool() const - { - return this->handle_ != InvalidHandle; - } - - operator HANDLE() const - { - return this->handle_; - } - - private: - HANDLE handle_{InvalidHandle}; - }; - - bool is_wine(); - bool is_shutdown_in_progress(); - - __declspec(noreturn) void raise_hard_exception(); - std::string load_resource(int id); - - void relaunch_self(); - __declspec(noreturn) void terminate(uint32_t code = 0); -} +#pragma once + +#define WIN32_LEAN_AND_MEAN +#include + +// min and max is required by gdi, therefore NOMINMAX won't work +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +#include +#include +#include + +namespace utils::nt +{ + class library final + { + public: + static library load(const char* name); + static library load(const std::string& name); + static library load(const std::filesystem::path& path); + static library get_by_address(const void* address); + + library(); + explicit library(const std::string& name); + explicit library(HMODULE handle); + + library(const library& a) : module_(a.module_) + { + } + + bool operator!=(const library& obj) const { return !(*this == obj); }; + bool operator==(const library& obj) const; + + operator bool() const; + operator HMODULE() const; + + void unprotect() const; + [[nodiscard]] void* get_entry_point() const; + [[nodiscard]] size_t get_relative_entry_point() const; + + [[nodiscard]] bool is_valid() const; + [[nodiscard]] std::string get_name() const; + [[nodiscard]] std::filesystem::path get_path() const; + [[nodiscard]] std::filesystem::path get_folder() const; + [[nodiscard]] std::uint8_t* get_ptr() const; + void free(); + + [[nodiscard]] HMODULE get_handle() const; + + template + [[nodiscard]] T get_proc(const std::string& process) const + { + if (!this->is_valid()) T{}; + return reinterpret_cast(GetProcAddress(this->module_, process.data())); + } + + template + [[nodiscard]] std::function get(const std::string& process) const + { + if (!this->is_valid()) return std::function(); + return static_cast(this->get_proc(process)); + } + + template + T invoke(const std::string& process, Args ... args) const + { + auto method = this->get(process); + if (method) return method(args...); + return T(); + } + + template + T invoke_pascal(const std::string& process, Args ... args) const + { + auto method = this->get(process); + if (method) return method(args...); + return T(); + } + + template + T invoke_this(const std::string& process, void* this_ptr, Args ... args) const + { + auto method = this->get(this_ptr, process); + if (method) return method(args...); + return T(); + } + + [[nodiscard]] std::vector get_section_headers() const; + + [[nodiscard]] PIMAGE_NT_HEADERS get_nt_headers() const; + [[nodiscard]] PIMAGE_DOS_HEADER get_dos_header() const; + [[nodiscard]] PIMAGE_OPTIONAL_HEADER get_optional_header() const; + + [[nodiscard]] void** get_iat_entry(const std::string& module_name, const std::string& proc_name) const; + + private: + HMODULE module_; + }; + + template + class handle + { + public: + handle() = default; + + handle(const HANDLE h) + : handle_(h) + { + } + + ~handle() + { + if (*this) + { + CloseHandle(this->handle_); + this->handle_ = InvalidHandle; + } + } + + handle(const handle&) = delete; + handle& operator=(const handle&) = delete; + + handle(handle&& obj) noexcept + : handle() + { + this->operator=(std::move(obj)); + } + + handle& operator=(handle&& obj) noexcept + { + if (this != &obj) + { + this->~handle(); + this->handle_ = obj.handle_; + obj.handle_ = InvalidHandle; + } + + return *this; + } + + handle& operator=(HANDLE h) noexcept + { + this->~handle(); + this->handle_ = h; + + return *this; + } + + operator bool() const + { + return this->handle_ != InvalidHandle; + } + + operator HANDLE() const + { + return this->handle_; + } + + private: + HANDLE handle_{InvalidHandle}; + }; + + bool is_wine(); + bool is_shutdown_in_progress(); + + __declspec(noreturn) void raise_hard_exception(); + std::string load_resource(int id); + + void relaunch_self(); + __declspec(noreturn) void terminate(uint32_t code = 0); +} diff --git a/hook_lib/common/utils/signature.cpp b/hook_lib/common/utils/signature.cpp index 3e0602a..90cf7d1 100644 --- a/hook_lib/common/utils/signature.cpp +++ b/hook_lib/common/utils/signature.cpp @@ -1,220 +1,220 @@ -#include "signature.hpp" -#include -#include - -#include - -#ifdef max -#undef max -#endif - -#ifdef min -#undef min -#endif - -namespace utils::hook -{ - void signature::load_pattern(const std::string& pattern) - { - this->mask_.clear(); - this->pattern_.clear(); - - uint8_t nibble = 0; - auto has_nibble = false; - - for (auto val : pattern) - { - if (val == ' ') continue; - if (val == '?') - { - this->mask_.push_back(val); - this->pattern_.push_back(0); - } - else - { - if ((val < '0' || val > '9') && (val < 'A' || val > 'F') && (val < 'a' || val > 'f')) - { - throw std::runtime_error("Invalid pattern"); - } - - char str[] = {val, 0}; - const auto current_nibble = static_cast(strtol(str, nullptr, 16)); - - if (!has_nibble) - { - has_nibble = true; - nibble = current_nibble; - } - else - { - has_nibble = false; - const uint8_t byte = current_nibble | (nibble << 4); - - this->mask_.push_back('x'); - this->pattern_.push_back(byte); - } - } - } - - while (!this->mask_.empty() && this->mask_.back() == '?') - { - this->mask_.pop_back(); - this->pattern_.pop_back(); - } - - if (this->has_sse_support()) - { - while (this->pattern_.size() < 16) - { - this->pattern_.push_back(0); - } - } - - if (has_nibble) - { - throw std::runtime_error("Invalid pattern"); - } - } - - signature::signature_result signature::process_range(uint8_t* start, const size_t length) const - { - if (this->has_sse_support()) return this->process_range_vectorized(start, length); - return this->process_range_linear(start, length); - } - - signature::signature_result signature::process_range_linear(uint8_t* start, const size_t length) const - { - std::vector result; - - for (size_t i = 0; i < length; ++i) - { - const auto address = start + i; - - size_t j = 0; - for (; j < this->mask_.size(); ++j) - { - if (this->mask_[j] != '?' && this->pattern_[j] != address[j]) - { - break; - } - } - - if (j == this->mask_.size()) - { - result.push_back(address); - } - } - - return result; - } - - signature::signature_result signature::process_range_vectorized(uint8_t* start, const size_t length) const - { - std::vector result; - __declspec(align(16)) char desired_mask[16] = {0}; - - for (size_t i = 0; i < this->mask_.size(); i++) - { - desired_mask[i / 8] |= (this->mask_[i] == '?' ? 0 : 1) << i % 8; - } - - const auto mask = _mm_load_si128(reinterpret_cast(desired_mask)); - const auto comparand = _mm_loadu_si128(reinterpret_cast(this->pattern_.data())); - - for (size_t i = 0; i < length; ++i) - { - const auto address = start + i; - const auto value = _mm_loadu_si128(reinterpret_cast(address)); - const auto comparison = _mm_cmpestrm(value, 16, comparand, static_cast(this->mask_.size()), - _SIDD_CMP_EQUAL_EACH); - - const auto matches = _mm_and_si128(mask, comparison); - const auto equivalence = _mm_xor_si128(mask, matches); - - if (_mm_test_all_zeros(equivalence, equivalence)) - { - result.push_back(address); - } - } - - return result; - } - - signature::signature_result signature::process() const - { - const auto range = this->length_ - this->mask_.size(); - const auto cores = std::max(1u, std::thread::hardware_concurrency()); - - if (range <= cores * 10ull) return this->process_serial(); - return this->process_parallel(); - } - - signature::signature_result signature::process_serial() const - { - const auto sub = this->has_sse_support() ? 16 : this->mask_.size(); - return {this->process_range(this->start_, this->length_ - sub)}; - } - - signature::signature_result signature::process_parallel() const - { - const auto sub = this->has_sse_support() ? 16 : this->mask_.size(); - const auto range = this->length_ - sub; - const auto cores = std::max(1u, std::thread::hardware_concurrency() / 2); - // Only use half of the available cores - const auto grid = range / cores; - - std::mutex mutex; - std::vector result; - std::vector threads; - - for (auto i = 0u; i < cores; ++i) - { - const auto start = this->start_ + (grid * i); - const auto length = (i + 1 == cores) ? (this->start_ + this->length_ - sub) - start : grid; - threads.emplace_back([&, start, length]() - { - const auto local_result = this->process_range(start, length); - if (local_result.empty()) return; - - std::lock_guard _(mutex); - for (const auto& address : local_result) - { - result.push_back(address); - } - }); - } - - for (auto& t : threads) - { - if (t.joinable()) - { - t.join(); - } - } - - std::sort(result.begin(), result.end()); - return {std::move(result)}; - } - - bool signature::has_sse_support() const - { - if (this->mask_.size() <= 16) - { - int cpu_id[4]; - __cpuid(cpu_id, 0); - - if (cpu_id[0] >= 1) - { - __cpuidex(cpu_id, 1, 0); - return (cpu_id[2] & (1 << 20)) != 0; - } - } - - return false; - } -} - -utils::hook::signature::signature_result operator"" _sig(const char* str, const size_t len) -{ - return utils::hook::signature(std::string(str, len)).process(); -} +#include "signature.hpp" +#include +#include + +#include + +#ifdef max +#undef max +#endif + +#ifdef min +#undef min +#endif + +namespace utils::hook +{ + void signature::load_pattern(const std::string& pattern) + { + this->mask_.clear(); + this->pattern_.clear(); + + uint8_t nibble = 0; + auto has_nibble = false; + + for (auto val : pattern) + { + if (val == ' ') continue; + if (val == '?') + { + this->mask_.push_back(val); + this->pattern_.push_back(0); + } + else + { + if ((val < '0' || val > '9') && (val < 'A' || val > 'F') && (val < 'a' || val > 'f')) + { + throw std::runtime_error("Invalid pattern"); + } + + char str[] = {val, 0}; + const auto current_nibble = static_cast(strtol(str, nullptr, 16)); + + if (!has_nibble) + { + has_nibble = true; + nibble = current_nibble; + } + else + { + has_nibble = false; + const uint8_t byte = current_nibble | (nibble << 4); + + this->mask_.push_back('x'); + this->pattern_.push_back(byte); + } + } + } + + while (!this->mask_.empty() && this->mask_.back() == '?') + { + this->mask_.pop_back(); + this->pattern_.pop_back(); + } + + if (this->has_sse_support()) + { + while (this->pattern_.size() < 16) + { + this->pattern_.push_back(0); + } + } + + if (has_nibble) + { + throw std::runtime_error("Invalid pattern"); + } + } + + signature::signature_result signature::process_range(uint8_t* start, const size_t length) const + { + if (this->has_sse_support()) return this->process_range_vectorized(start, length); + return this->process_range_linear(start, length); + } + + signature::signature_result signature::process_range_linear(uint8_t* start, const size_t length) const + { + std::vector result; + + for (size_t i = 0; i < length; ++i) + { + const auto address = start + i; + + size_t j = 0; + for (; j < this->mask_.size(); ++j) + { + if (this->mask_[j] != '?' && this->pattern_[j] != address[j]) + { + break; + } + } + + if (j == this->mask_.size()) + { + result.push_back(address); + } + } + + return result; + } + + signature::signature_result signature::process_range_vectorized(uint8_t* start, const size_t length) const + { + std::vector result; + __declspec(align(16)) char desired_mask[16] = {0}; + + for (size_t i = 0; i < this->mask_.size(); i++) + { + desired_mask[i / 8] |= (this->mask_[i] == '?' ? 0 : 1) << i % 8; + } + + const auto mask = _mm_load_si128(reinterpret_cast(desired_mask)); + const auto comparand = _mm_loadu_si128(reinterpret_cast(this->pattern_.data())); + + for (size_t i = 0; i < length; ++i) + { + const auto address = start + i; + const auto value = _mm_loadu_si128(reinterpret_cast(address)); + const auto comparison = _mm_cmpestrm(value, 16, comparand, static_cast(this->mask_.size()), + _SIDD_CMP_EQUAL_EACH); + + const auto matches = _mm_and_si128(mask, comparison); + const auto equivalence = _mm_xor_si128(mask, matches); + + if (_mm_test_all_zeros(equivalence, equivalence)) + { + result.push_back(address); + } + } + + return result; + } + + signature::signature_result signature::process() const + { + const auto range = this->length_ - this->mask_.size(); + const auto cores = std::max(1u, std::thread::hardware_concurrency()); + + if (range <= cores * 10ull) return this->process_serial(); + return this->process_parallel(); + } + + signature::signature_result signature::process_serial() const + { + const auto sub = this->has_sse_support() ? 16 : this->mask_.size(); + return {this->process_range(this->start_, this->length_ - sub)}; + } + + signature::signature_result signature::process_parallel() const + { + const auto sub = this->has_sse_support() ? 16 : this->mask_.size(); + const auto range = this->length_ - sub; + const auto cores = std::max(1u, std::thread::hardware_concurrency() / 2); + // Only use half of the available cores + const auto grid = range / cores; + + std::mutex mutex; + std::vector result; + std::vector threads; + + for (auto i = 0u; i < cores; ++i) + { + const auto start = this->start_ + (grid * i); + const auto length = (i + 1 == cores) ? (this->start_ + this->length_ - sub) - start : grid; + threads.emplace_back([&, start, length]() + { + const auto local_result = this->process_range(start, length); + if (local_result.empty()) return; + + std::lock_guard _(mutex); + for (const auto& address : local_result) + { + result.push_back(address); + } + }); + } + + for (auto& t : threads) + { + if (t.joinable()) + { + t.join(); + } + } + + std::sort(result.begin(), result.end()); + return {std::move(result)}; + } + + bool signature::has_sse_support() const + { + if (this->mask_.size() <= 16) + { + int cpu_id[4]; + __cpuid(cpu_id, 0); + + if (cpu_id[0] >= 1) + { + __cpuidex(cpu_id, 1, 0); + return (cpu_id[2] & (1 << 20)) != 0; + } + } + + return false; + } +} + +utils::hook::signature::signature_result operator"" _sig(const char* str, const size_t len) +{ + return utils::hook::signature(std::string(str, len)).process(); +} diff --git a/hook_lib/common/utils/signature.hpp b/hook_lib/common/utils/signature.hpp index ade80b4..054e6b4 100644 --- a/hook_lib/common/utils/signature.hpp +++ b/hook_lib/common/utils/signature.hpp @@ -1,49 +1,49 @@ -#pragma once -#include "nt.hpp" -#include - -namespace utils::hook -{ - class signature final - { - public: - using signature_result = std::vector; - - explicit signature(const std::string& pattern, const nt::library& library = {}) - : signature(pattern, library.get_ptr(), library.get_optional_header()->SizeOfImage) - { - } - - signature(const std::string& pattern, void* start, void* end) - : signature(pattern, start, size_t(end) - size_t(start)) - { - } - - signature(const std::string& pattern, void* start, const size_t length) - : start_(static_cast(start)), length_(length) - { - this->load_pattern(pattern); - } - - signature_result process() const; - - private: - std::string mask_; - std::basic_string pattern_; - - uint8_t* start_; - size_t length_; - - void load_pattern(const std::string& pattern); - - signature_result process_parallel() const; - signature_result process_serial() const; - signature_result process_range(uint8_t* start, size_t length) const; - signature_result process_range_linear(uint8_t* start, size_t length) const; - signature_result process_range_vectorized(uint8_t* start, size_t length) const; - - bool has_sse_support() const; - }; -} - -utils::hook::signature::signature_result operator"" _sig(const char* str, size_t len); +#pragma once +#include "nt.hpp" +#include + +namespace utils::hook +{ + class signature final + { + public: + using signature_result = std::vector; + + explicit signature(const std::string& pattern, const nt::library& library = {}) + : signature(pattern, library.get_ptr(), library.get_optional_header()->SizeOfImage) + { + } + + signature(const std::string& pattern, void* start, void* end) + : signature(pattern, start, size_t(end) - size_t(start)) + { + } + + signature(const std::string& pattern, void* start, const size_t length) + : start_(static_cast(start)), length_(length) + { + this->load_pattern(pattern); + } + + signature_result process() const; + + private: + std::string mask_; + std::basic_string pattern_; + + uint8_t* start_; + size_t length_; + + void load_pattern(const std::string& pattern); + + signature_result process_parallel() const; + signature_result process_serial() const; + signature_result process_range(uint8_t* start, size_t length) const; + signature_result process_range_linear(uint8_t* start, size_t length) const; + signature_result process_range_vectorized(uint8_t* start, size_t length) const; + + bool has_sse_support() const; + }; +} + +utils::hook::signature::signature_result operator"" _sig(const char* str, size_t len); diff --git a/hook_lib/common/utils/smbios.cpp b/hook_lib/common/utils/smbios.cpp index 84de22c..a3282c2 100644 --- a/hook_lib/common/utils/smbios.cpp +++ b/hook_lib/common/utils/smbios.cpp @@ -1,94 +1,94 @@ -#include "smbios.hpp" -#include "memory.hpp" - -#define WIN32_LEAN_AND_MEAN -#include -#include - -namespace utils::smbios -{ - namespace - { -#pragma warning(push) -#pragma warning(disable: 4200) - struct RawSMBIOSData - { - BYTE Used20CallingMethod; - BYTE SMBIOSMajorVersion; - BYTE SMBIOSMinorVersion; - BYTE DmiRevision; - DWORD Length; - BYTE SMBIOSTableData[]; - }; - - typedef struct - { - BYTE type; - BYTE length; - WORD handle; - } dmi_header; -#pragma warning(pop) - - std::vector get_smbios_data() - { - DWORD size = 0; - std::vector data{}; - - size = GetSystemFirmwareTable('RSMB', 0, nullptr, size); - data.resize(size); - GetSystemFirmwareTable('RSMB', 0, data.data(), size); - - return data; - } - - std::string parse_uuid(const uint8_t* data) - { - if (utils::memory::is_set(data, 0, 16) || utils::memory::is_set(data, -1, 16)) - { - return {}; - } - - char uuid[16] = {0}; - *reinterpret_cast(uuid + 0) = - _byteswap_ulong(*reinterpret_cast(data + 0)); - *reinterpret_cast(uuid + 4) = - _byteswap_ushort(*reinterpret_cast(data + 4)); - *reinterpret_cast(uuid + 6) = - _byteswap_ushort(*reinterpret_cast(data + 6)); - memcpy(uuid + 8, data + 8, 8); - - return std::string(uuid, sizeof(uuid)); - } - } - - std::string get_uuid() - { - auto smbios_data = get_smbios_data(); - auto* raw_data = reinterpret_cast(smbios_data.data()); - - auto* data = raw_data->SMBIOSTableData; - for (DWORD i = 0; i + sizeof(dmi_header) < raw_data->Length;) - { - auto* header = reinterpret_cast(data + i); - if (header->length < 4) - { - return {}; - } - - if (header->type == 0x01 && header->length >= 0x19) - { - return parse_uuid(data + i + 0x8); - } - - i += header->length; - while ((i + 1) < raw_data->Length && *reinterpret_cast(data + i) != 0) - { - ++i; - } - - i += 2; - } - - return {}; - } -} +#include "smbios.hpp" +#include "memory.hpp" + +#define WIN32_LEAN_AND_MEAN +#include +#include + +namespace utils::smbios +{ + namespace + { +#pragma warning(push) +#pragma warning(disable: 4200) + struct RawSMBIOSData + { + BYTE Used20CallingMethod; + BYTE SMBIOSMajorVersion; + BYTE SMBIOSMinorVersion; + BYTE DmiRevision; + DWORD Length; + BYTE SMBIOSTableData[]; + }; + + typedef struct + { + BYTE type; + BYTE length; + WORD handle; + } dmi_header; +#pragma warning(pop) + + std::vector get_smbios_data() + { + DWORD size = 0; + std::vector data{}; + + size = GetSystemFirmwareTable('RSMB', 0, nullptr, size); + data.resize(size); + GetSystemFirmwareTable('RSMB', 0, data.data(), size); + + return data; + } + + std::string parse_uuid(const uint8_t* data) + { + if (utils::memory::is_set(data, 0, 16) || utils::memory::is_set(data, -1, 16)) + { + return {}; + } + + char uuid[16] = {0}; + *reinterpret_cast(uuid + 0) = + _byteswap_ulong(*reinterpret_cast(data + 0)); + *reinterpret_cast(uuid + 4) = + _byteswap_ushort(*reinterpret_cast(data + 4)); + *reinterpret_cast(uuid + 6) = + _byteswap_ushort(*reinterpret_cast(data + 6)); + memcpy(uuid + 8, data + 8, 8); + + return std::string(uuid, sizeof(uuid)); + } + } + + std::string get_uuid() + { + auto smbios_data = get_smbios_data(); + auto* raw_data = reinterpret_cast(smbios_data.data()); + + auto* data = raw_data->SMBIOSTableData; + for (DWORD i = 0; i + sizeof(dmi_header) < raw_data->Length;) + { + auto* header = reinterpret_cast(data + i); + if (header->length < 4) + { + return {}; + } + + if (header->type == 0x01 && header->length >= 0x19) + { + return parse_uuid(data + i + 0x8); + } + + i += header->length; + while ((i + 1) < raw_data->Length && *reinterpret_cast(data + i) != 0) + { + ++i; + } + + i += 2; + } + + return {}; + } +} diff --git a/hook_lib/common/utils/smbios.hpp b/hook_lib/common/utils/smbios.hpp index 62e8c0e..bbd1939 100644 --- a/hook_lib/common/utils/smbios.hpp +++ b/hook_lib/common/utils/smbios.hpp @@ -1,8 +1,8 @@ -#pragma once - -#include - -namespace utils::smbios -{ - std::string get_uuid(); -} +#pragma once + +#include + +namespace utils::smbios +{ + std::string get_uuid(); +} diff --git a/hook_lib/common/utils/string.cpp b/hook_lib/common/utils/string.cpp index f2de62b..3313eca 100644 --- a/hook_lib/common/utils/string.cpp +++ b/hook_lib/common/utils/string.cpp @@ -1,177 +1,177 @@ -#include "string.hpp" -#include -#include -#include - -#include "nt.hpp" - -namespace utils::string -{ - const char* va(const char* fmt, ...) - { - static thread_local va_provider<8, 256> provider; - - va_list ap; - va_start(ap, fmt); - - const char* result = provider.get(fmt, ap); - - va_end(ap); - return result; - } - - std::vector split(const std::string& s, const char delim) - { - std::stringstream ss(s); - std::string item; - std::vector elems; - - while (std::getline(ss, item, delim)) - { - elems.push_back(item); // elems.push_back(std::move(item)); // if C++11 (based on comment from @mchiasson) - } - - return elems; - } - - std::string to_lower(std::string text) - { - std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input) - { - return static_cast(std::tolower(input)); - }); - - return text; - } - - std::string to_upper(std::string text) - { - std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input) - { - return static_cast(std::toupper(input)); - }); - - return text; - } - - bool starts_with(const std::string& text, const std::string& substring) - { - return text.find(substring) == 0; - } - - bool ends_with(const std::string& text, const std::string& substring) - { - if (substring.size() > text.size()) return false; - return std::equal(substring.rbegin(), substring.rend(), text.rbegin()); - } - - std::string dump_hex(const std::string& data, const std::string& separator) - { - std::string result; - - for (unsigned int i = 0; i < data.size(); ++i) - { - if (i > 0) - { - result.append(separator); - } - - result.append(va("%02X", data[i] & 0xFF)); - } - - return result; - } - - std::string get_clipboard_data() - { - if (OpenClipboard(nullptr)) - { - std::string data; - - auto* const clipboard_data = GetClipboardData(1u); - if (clipboard_data) - { - auto* const cliptext = static_cast(GlobalLock(clipboard_data)); - if (cliptext) - { - data.append(cliptext); - GlobalUnlock(clipboard_data); - } - } - CloseClipboard(); - - return data; - } - return {}; - } - - void strip(const char* in, char* out, size_t max) - { - if (!in || !out) return; - - max--; - size_t current = 0; - while (*in != 0 && current < max) - { - const auto color_index = (*(in + 1) - 48) >= 0xC ? 7 : (*(in + 1) - 48); - - if (*in == '^' && (color_index != 7 || *(in + 1) == '7')) - { - ++in; - } - else - { - *out = *in; - ++out; - ++current; - } - - ++in; - } - - *out = '\0'; - } - - std::string convert(const std::wstring& wstr) - { - std::string result; - result.reserve(wstr.size()); - - for (const auto& chr : wstr) - { - result.push_back(static_cast(chr)); - } - - return result; - } - - std::wstring convert(const std::string& str) - { - std::wstring result; - result.reserve(str.size()); - - for (const auto& chr : str) - { - result.push_back(static_cast(chr)); - } - - return result; - } - - std::string replace(std::string str, const std::string& from, const std::string& to) - { - if (from.empty()) - { - return str; - } - - size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != std::string::npos) - { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); - } - - return str; - } -} +#include "string.hpp" +#include +#include +#include + +#include "nt.hpp" + +namespace utils::string +{ + const char* va(const char* fmt, ...) + { + static thread_local va_provider<8, 256> provider; + + va_list ap; + va_start(ap, fmt); + + const char* result = provider.get(fmt, ap); + + va_end(ap); + return result; + } + + std::vector split(const std::string& s, const char delim) + { + std::stringstream ss(s); + std::string item; + std::vector elems; + + while (std::getline(ss, item, delim)) + { + elems.push_back(item); // elems.push_back(std::move(item)); // if C++11 (based on comment from @mchiasson) + } + + return elems; + } + + std::string to_lower(std::string text) + { + std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input) + { + return static_cast(std::tolower(input)); + }); + + return text; + } + + std::string to_upper(std::string text) + { + std::transform(text.begin(), text.end(), text.begin(), [](const unsigned char input) + { + return static_cast(std::toupper(input)); + }); + + return text; + } + + bool starts_with(const std::string& text, const std::string& substring) + { + return text.find(substring) == 0; + } + + bool ends_with(const std::string& text, const std::string& substring) + { + if (substring.size() > text.size()) return false; + return std::equal(substring.rbegin(), substring.rend(), text.rbegin()); + } + + std::string dump_hex(const std::string& data, const std::string& separator) + { + std::string result; + + for (unsigned int i = 0; i < data.size(); ++i) + { + if (i > 0) + { + result.append(separator); + } + + result.append(va("%02X", data[i] & 0xFF)); + } + + return result; + } + + std::string get_clipboard_data() + { + if (OpenClipboard(nullptr)) + { + std::string data; + + auto* const clipboard_data = GetClipboardData(1u); + if (clipboard_data) + { + auto* const cliptext = static_cast(GlobalLock(clipboard_data)); + if (cliptext) + { + data.append(cliptext); + GlobalUnlock(clipboard_data); + } + } + CloseClipboard(); + + return data; + } + return {}; + } + + void strip(const char* in, char* out, size_t max) + { + if (!in || !out) return; + + max--; + size_t current = 0; + while (*in != 0 && current < max) + { + const auto color_index = (*(in + 1) - 48) >= 0xC ? 7 : (*(in + 1) - 48); + + if (*in == '^' && (color_index != 7 || *(in + 1) == '7')) + { + ++in; + } + else + { + *out = *in; + ++out; + ++current; + } + + ++in; + } + + *out = '\0'; + } + + std::string convert(const std::wstring& wstr) + { + std::string result; + result.reserve(wstr.size()); + + for (const auto& chr : wstr) + { + result.push_back(static_cast(chr)); + } + + return result; + } + + std::wstring convert(const std::string& str) + { + std::wstring result; + result.reserve(str.size()); + + for (const auto& chr : str) + { + result.push_back(static_cast(chr)); + } + + return result; + } + + std::string replace(std::string str, const std::string& from, const std::string& to) + { + if (from.empty()) + { + return str; + } + + size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::string::npos) + { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); + } + + return str; + } +} diff --git a/hook_lib/common/utils/string.hpp b/hook_lib/common/utils/string.hpp index 292bca9..edc5cc1 100644 --- a/hook_lib/common/utils/string.hpp +++ b/hook_lib/common/utils/string.hpp @@ -1,97 +1,97 @@ -#pragma once -#include "memory.hpp" - -template -constexpr auto ARRAY_COUNT(Type (&)[n]) { return n; } - -namespace utils::string -{ - template - class va_provider final - { - public: - static_assert(Buffers != 0 && MinBufferSize != 0, "Buffers and MinBufferSize mustn't be 0"); - - va_provider() : current_buffer_(0) - { - } - - char* get(const char* format, const va_list ap) - { - ++this->current_buffer_ %= ARRAY_COUNT(this->string_pool_); - auto entry = &this->string_pool_[this->current_buffer_]; - - if (!entry->size || !entry->buffer) - { - throw std::runtime_error("String pool not initialized"); - } - - while (true) - { - const int res = vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap); - if (res > 0) break; // Success - if (res == 0) return nullptr; // Error - - entry->double_size(); - } - - return entry->buffer; - } - - private: - class entry final - { - public: - entry(const size_t _size = MinBufferSize) : size(_size), buffer(nullptr) - { - if (this->size < MinBufferSize) this->size = MinBufferSize; - this->allocate(); - } - - ~entry() - { - if (this->buffer) memory::get_allocator()->free(this->buffer); - this->size = 0; - this->buffer = nullptr; - } - - void allocate() - { - if (this->buffer) memory::get_allocator()->free(this->buffer); - this->buffer = memory::get_allocator()->allocate_array(this->size + 1); - } - - void double_size() - { - this->size *= 2; - this->allocate(); - } - - size_t size{}; - char* buffer{nullptr}; - }; - - size_t current_buffer_{}; - entry string_pool_[Buffers]{}; - }; - - const char* va(const char* fmt, ...); - - std::vector split(const std::string& s, char delim); - - std::string to_lower(std::string text); - std::string to_upper(std::string text); - bool starts_with(const std::string& text, const std::string& substring); - bool ends_with(const std::string& text, const std::string& substring); - - std::string dump_hex(const std::string& data, const std::string& separator = " "); - - std::string get_clipboard_data(); - - void strip(const char* in, char* out, size_t max); - - std::string convert(const std::wstring& wstr); - std::wstring convert(const std::string& str); - - std::string replace(std::string str, const std::string& from, const std::string& to); -} +#pragma once +#include "memory.hpp" + +template +constexpr auto ARRAY_COUNT(Type (&)[n]) { return n; } + +namespace utils::string +{ + template + class va_provider final + { + public: + static_assert(Buffers != 0 && MinBufferSize != 0, "Buffers and MinBufferSize mustn't be 0"); + + va_provider() : current_buffer_(0) + { + } + + char* get(const char* format, const va_list ap) + { + ++this->current_buffer_ %= ARRAY_COUNT(this->string_pool_); + auto entry = &this->string_pool_[this->current_buffer_]; + + if (!entry->size || !entry->buffer) + { + throw std::runtime_error("String pool not initialized"); + } + + while (true) + { + const int res = vsnprintf_s(entry->buffer, entry->size, _TRUNCATE, format, ap); + if (res > 0) break; // Success + if (res == 0) return nullptr; // Error + + entry->double_size(); + } + + return entry->buffer; + } + + private: + class entry final + { + public: + entry(const size_t _size = MinBufferSize) : size(_size), buffer(nullptr) + { + if (this->size < MinBufferSize) this->size = MinBufferSize; + this->allocate(); + } + + ~entry() + { + if (this->buffer) memory::get_allocator()->free(this->buffer); + this->size = 0; + this->buffer = nullptr; + } + + void allocate() + { + if (this->buffer) memory::get_allocator()->free(this->buffer); + this->buffer = memory::get_allocator()->allocate_array(this->size + 1); + } + + void double_size() + { + this->size *= 2; + this->allocate(); + } + + size_t size{}; + char* buffer{nullptr}; + }; + + size_t current_buffer_{}; + entry string_pool_[Buffers]{}; + }; + + const char* va(const char* fmt, ...); + + std::vector split(const std::string& s, char delim); + + std::string to_lower(std::string text); + std::string to_upper(std::string text); + bool starts_with(const std::string& text, const std::string& substring); + bool ends_with(const std::string& text, const std::string& substring); + + std::string dump_hex(const std::string& data, const std::string& separator = " "); + + std::string get_clipboard_data(); + + void strip(const char* in, char* out, size_t max); + + std::string convert(const std::wstring& wstr); + std::wstring convert(const std::string& str); + + std::string replace(std::string str, const std::string& from, const std::string& to); +} diff --git a/hook_lib/common/utils/thread.cpp b/hook_lib/common/utils/thread.cpp index 7649c65..582ed5c 100644 --- a/hook_lib/common/utils/thread.cpp +++ b/hook_lib/common/utils/thread.cpp @@ -1,116 +1,116 @@ -#include "thread.hpp" -#include "string.hpp" -#include "finally.hpp" - -#include - -namespace utils::thread -{ - /*bool set_name(const HANDLE t, const std::string& name) - { - const nt::library kernel32("kernel32.dll"); - if (!kernel32) - { - return false; - } - - const auto set_description = kernel32.get_proc("SetThreadDescription"); - if (!set_description) - { - return false; - } - - return SUCCEEDED(set_description(t, string::convert(name).data())); - } - - bool set_name(const DWORD id, const std::string& name) - { - auto* const t = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, id); - if (!t) return false; - - const auto _ = utils::finally([t]() - { - CloseHandle(t); - }); - - return set_name(t, name); - } - - bool set_name(std::thread& t, const std::string& name) - { - return set_name(t.native_handle(), name); - } - - bool set_name(const std::string& name) - { - return set_name(GetCurrentThread(), name); - } - */ - std::vector get_thread_ids() - { - nt::handle h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId()); - if (!h) - { - return {}; - } - - THREADENTRY32 entry{}; - entry.dwSize = sizeof(entry); - if (!Thread32First(h, &entry)) - { - return {}; - } - - std::vector ids{}; - - do - { - const auto check_size = entry.dwSize < FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) - + sizeof(entry.th32OwnerProcessID); - entry.dwSize = sizeof(entry); - - if (check_size && entry.th32OwnerProcessID == GetCurrentProcessId()) - { - ids.emplace_back(entry.th32ThreadID); - } - } while (Thread32Next(h, &entry)); - - return ids; - } - - void for_each_thread(const std::function& callback, const DWORD access) - { - const auto ids = get_thread_ids(); - - for (const auto& id : ids) - { - handle thread(id, access); - if (thread) - { - callback(thread); - } - } - } - - void suspend_other_threads() - { - for_each_thread([](const HANDLE thread) - { - if (GetThreadId(thread) != GetCurrentThreadId()) - { - SuspendThread(thread); - } - }); - } - - void resume_other_threads() - { - for_each_thread([](const HANDLE thread) - { - if (GetThreadId(thread) != GetCurrentThreadId()) - { - ResumeThread(thread); - } - }); - } -} +#include "thread.hpp" +#include "string.hpp" +#include "finally.hpp" + +#include + +namespace utils::thread +{ + /*bool set_name(const HANDLE t, const std::string& name) + { + const nt::library kernel32("kernel32.dll"); + if (!kernel32) + { + return false; + } + + const auto set_description = kernel32.get_proc("SetThreadDescription"); + if (!set_description) + { + return false; + } + + return SUCCEEDED(set_description(t, string::convert(name).data())); + } + + bool set_name(const DWORD id, const std::string& name) + { + auto* const t = OpenThread(THREAD_SET_LIMITED_INFORMATION, FALSE, id); + if (!t) return false; + + const auto _ = utils::finally([t]() + { + CloseHandle(t); + }); + + return set_name(t, name); + } + + bool set_name(std::thread& t, const std::string& name) + { + return set_name(t.native_handle(), name); + } + + bool set_name(const std::string& name) + { + return set_name(GetCurrentThread(), name); + } + */ + std::vector get_thread_ids() + { + nt::handle h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId()); + if (!h) + { + return {}; + } + + THREADENTRY32 entry{}; + entry.dwSize = sizeof(entry); + if (!Thread32First(h, &entry)) + { + return {}; + } + + std::vector ids{}; + + do + { + const auto check_size = entry.dwSize < FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + + sizeof(entry.th32OwnerProcessID); + entry.dwSize = sizeof(entry); + + if (check_size && entry.th32OwnerProcessID == GetCurrentProcessId()) + { + ids.emplace_back(entry.th32ThreadID); + } + } while (Thread32Next(h, &entry)); + + return ids; + } + + void for_each_thread(const std::function& callback, const DWORD access) + { + const auto ids = get_thread_ids(); + + for (const auto& id : ids) + { + handle thread(id, access); + if (thread) + { + callback(thread); + } + } + } + + void suspend_other_threads() + { + for_each_thread([](const HANDLE thread) + { + if (GetThreadId(thread) != GetCurrentThreadId()) + { + SuspendThread(thread); + } + }); + } + + void resume_other_threads() + { + for_each_thread([](const HANDLE thread) + { + if (GetThreadId(thread) != GetCurrentThreadId()) + { + ResumeThread(thread); + } + }); + } +} diff --git a/hook_lib/common/utils/thread.hpp b/hook_lib/common/utils/thread.hpp index f1365c1..b656226 100644 --- a/hook_lib/common/utils/thread.hpp +++ b/hook_lib/common/utils/thread.hpp @@ -1,47 +1,47 @@ -#pragma once -#include -#include "nt.hpp" - -namespace utils::thread -{ - //bool set_name(HANDLE t, const std::string& name); - //bool set_name(DWORD id, const std::string& name); - //bool set_name(std::thread& t, const std::string& name); - //bool set_name(const std::string& name); - - template - std::thread create_named_thread(const std::string& name, Args&&... args) - { - auto t = std::thread(std::forward(args)...); - set_name(t, name); - return t; - } - - class handle - { - public: - handle(const DWORD thread_id, const DWORD access = THREAD_ALL_ACCESS) - : handle_(OpenThread(access, FALSE, thread_id)) - { - } - - operator bool() const - { - return this->handle_; - } - - operator HANDLE() const - { - return this->handle_; - } - - private: - nt::handle<> handle_{}; - }; - - std::vector get_thread_ids(); - void for_each_thread(const std::function& callback, DWORD access = THREAD_ALL_ACCESS); - - void suspend_other_threads(); - void resume_other_threads(); -} +#pragma once +#include +#include "nt.hpp" + +namespace utils::thread +{ + //bool set_name(HANDLE t, const std::string& name); + //bool set_name(DWORD id, const std::string& name); + //bool set_name(std::thread& t, const std::string& name); + //bool set_name(const std::string& name); + + template + std::thread create_named_thread(const std::string& name, Args&&... args) + { + auto t = std::thread(std::forward(args)...); + set_name(t, name); + return t; + } + + class handle + { + public: + handle(const DWORD thread_id, const DWORD access = THREAD_ALL_ACCESS) + : handle_(OpenThread(access, FALSE, thread_id)) + { + } + + operator bool() const + { + return this->handle_; + } + + operator HANDLE() const + { + return this->handle_; + } + + private: + nt::handle<> handle_{}; + }; + + std::vector get_thread_ids(); + void for_each_thread(const std::function& callback, DWORD access = THREAD_ALL_ACCESS); + + void suspend_other_threads(); + void resume_other_threads(); +} diff --git a/hook_lib/csv.hpp b/hook_lib/csv.hpp deleted file mode 100644 index 9cebfc2..0000000 --- a/hook_lib/csv.hpp +++ /dev/null @@ -1,8486 +0,0 @@ -#pragma once -/* -CSV for C++, version 2.1.3 -https://github.com/vincentlaucsb/csv-parser - -MIT License - -Copyright (c) 2017-2020 Vincent La - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#ifndef CSV_HPP -#define CSV_HPP - -/** @file - * @brief Defines functionality needed for basic CSV parsing - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Copyright 2017 https://github.com/mandreyel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the "Software"), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be included in all copies - * or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MIO_MMAP_HEADER -#define MIO_MMAP_HEADER - -// #include "mio/page.hpp" -/* Copyright 2017 https://github.com/mandreyel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the "Software"), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be included in all copies - * or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MIO_PAGE_HEADER -#define MIO_PAGE_HEADER - -#ifdef _WIN32 -# include -#else -# include -#endif - -namespace mio { - -/** - * This is used by `basic_mmap` to determine whether to create a read-only or - * a read-write memory mapping. - */ -enum class access_mode -{ - read, - write -}; - -/** - * Determines the operating system's page allocation granularity. - * - * On the first call to this function, it invokes the operating system specific syscall - * to determine the page size, caches the value, and returns it. Any subsequent call to - * this function serves the cached value, so no further syscalls are made. - */ -inline size_t page_size() -{ - static const size_t page_size = [] - { -#ifdef _WIN32 - SYSTEM_INFO SystemInfo; - GetSystemInfo(&SystemInfo); - return SystemInfo.dwAllocationGranularity; -#else - return sysconf(_SC_PAGE_SIZE); -#endif - }(); - return page_size; -} - -/** - * Alligns `offset` to the operating's system page size such that it subtracts the - * difference until the nearest page boundary before `offset`, or does nothing if - * `offset` is already page aligned. - */ -inline size_t make_offset_page_aligned(size_t offset) noexcept -{ - const size_t page_size_ = page_size(); - // Use integer division to round down to the nearest page alignment. - return offset / page_size_ * page_size_; -} - -} // namespace mio - -#endif // MIO_PAGE_HEADER - - -#include -#include -#include -#include - -#ifdef _WIN32 -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif // WIN32_LEAN_AND_MEAN -# include -#else // ifdef _WIN32 -# define INVALID_HANDLE_VALUE -1 -#endif // ifdef _WIN32 - -namespace mio { - -// This value may be provided as the `length` parameter to the constructor or -// `map`, in which case a memory mapping of the entire file is created. -enum { map_entire_file = 0 }; - -#ifdef _WIN32 -using file_handle_type = HANDLE; -#else -using file_handle_type = int; -#endif - -// This value represents an invalid file handle type. This can be used to -// determine whether `basic_mmap::file_handle` is valid, for example. -const static file_handle_type invalid_handle = INVALID_HANDLE_VALUE; - -template -struct basic_mmap -{ - using value_type = ByteT; - using size_type = size_t; - using reference = value_type&; - using const_reference = const value_type&; - using pointer = value_type*; - using const_pointer = const value_type*; - using difference_type = std::ptrdiff_t; - using iterator = pointer; - using const_iterator = const_pointer; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - using iterator_category = std::random_access_iterator_tag; - using handle_type = file_handle_type; - - static_assert(sizeof(ByteT) == sizeof(char), "ByteT must be the same size as char."); - -private: - // Points to the first requested byte, and not to the actual start of the mapping. - pointer data_ = nullptr; - - // Length--in bytes--requested by user (which may not be the length of the - // full mapping) and the length of the full mapping. - size_type length_ = 0; - size_type mapped_length_ = 0; - - // Letting user map a file using both an existing file handle and a path - // introcudes some complexity (see `is_handle_internal_`). - // On POSIX, we only need a file handle to create a mapping, while on - // Windows systems the file handle is necessary to retrieve a file mapping - // handle, but any subsequent operations on the mapped region must be done - // through the latter. - handle_type file_handle_ = INVALID_HANDLE_VALUE; -#ifdef _WIN32 - handle_type file_mapping_handle_ = INVALID_HANDLE_VALUE; -#endif - - // Letting user map a file using both an existing file handle and a path - // introcudes some complexity in that we must not close the file handle if - // user provided it, but we must close it if we obtained it using the - // provided path. For this reason, this flag is used to determine when to - // close `file_handle_`. - bool is_handle_internal_; - -public: - /** - * The default constructed mmap object is in a non-mapped state, that is, - * any operation that attempts to access nonexistent underlying data will - * result in undefined behaviour/segmentation faults. - */ - basic_mmap() = default; - -#ifdef __cpp_exceptions - /** - * The same as invoking the `map` function, except any error that may occur - * while establishing the mapping is wrapped in a `std::system_error` and is - * thrown. - */ - template - basic_mmap(const String& path, const size_type offset = 0, const size_type length = map_entire_file) - { - std::error_code error; - map(path, offset, length, error); - if(error) { throw std::system_error(error); } - } - - /** - * The same as invoking the `map` function, except any error that may occur - * while establishing the mapping is wrapped in a `std::system_error` and is - * thrown. - */ - basic_mmap(const handle_type handle, const size_type offset = 0, const size_type length = map_entire_file) - { - std::error_code error; - map(handle, offset, length, error); - if(error) { throw std::system_error(error); } - } -#endif // __cpp_exceptions - - /** - * `basic_mmap` has single-ownership semantics, so transferring ownership - * may only be accomplished by moving the object. - */ - basic_mmap(const basic_mmap&) = delete; - basic_mmap(basic_mmap&&); - basic_mmap& operator=(const basic_mmap&) = delete; - basic_mmap& operator=(basic_mmap&&); - - /** - * If this is a read-write mapping, the destructor invokes sync. Regardless - * of the access mode, unmap is invoked as a final step. - */ - ~basic_mmap(); - - /** - * On UNIX systems 'file_handle' and 'mapping_handle' are the same. On Windows, - * however, a mapped region of a file gets its own handle, which is returned by - * 'mapping_handle'. - */ - handle_type file_handle() const noexcept { return file_handle_; } - handle_type mapping_handle() const noexcept; - - /** Returns whether a valid memory mapping has been created. */ - bool is_open() const noexcept { return file_handle_ != invalid_handle; } - - /** - * Returns true if no mapping was established, that is, conceptually the - * same as though the length that was mapped was 0. This function is - * provided so that this class has Container semantics. - */ - bool empty() const noexcept { return length() == 0; } - - /** Returns true if a mapping was established. */ - bool is_mapped() const noexcept; - - /** - * `size` and `length` both return the logical length, i.e. the number of bytes - * user requested to be mapped, while `mapped_length` returns the actual number of - * bytes that were mapped which is a multiple of the underlying operating system's - * page allocation granularity. - */ - size_type size() const noexcept { return length(); } - size_type length() const noexcept { return length_; } - size_type mapped_length() const noexcept { return mapped_length_; } - - /** Returns the offset relative to the start of the mapping. */ - size_type mapping_offset() const noexcept - { - return mapped_length_ - length_; - } - - /** - * Returns a pointer to the first requested byte, or `nullptr` if no memory mapping - * exists. - */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > pointer data() noexcept { return data_; } - const_pointer data() const noexcept { return data_; } - - /** - * Returns an iterator to the first requested byte, if a valid memory mapping - * exists, otherwise this function call is undefined behaviour. - */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > iterator begin() noexcept { return data(); } - const_iterator begin() const noexcept { return data(); } - const_iterator cbegin() const noexcept { return data(); } - - /** - * Returns an iterator one past the last requested byte, if a valid memory mapping - * exists, otherwise this function call is undefined behaviour. - */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > iterator end() noexcept { return data() + length(); } - const_iterator end() const noexcept { return data() + length(); } - const_iterator cend() const noexcept { return data() + length(); } - - /** - * Returns a reverse iterator to the last memory mapped byte, if a valid - * memory mapping exists, otherwise this function call is undefined - * behaviour. - */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } - const_reverse_iterator rbegin() const noexcept - { return const_reverse_iterator(end()); } - const_reverse_iterator crbegin() const noexcept - { return const_reverse_iterator(end()); } - - /** - * Returns a reverse iterator past the first mapped byte, if a valid memory - * mapping exists, otherwise this function call is undefined behaviour. - */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > reverse_iterator rend() noexcept { return reverse_iterator(begin()); } - const_reverse_iterator rend() const noexcept - { return const_reverse_iterator(begin()); } - const_reverse_iterator crend() const noexcept - { return const_reverse_iterator(begin()); } - - /** - * Returns a reference to the `i`th byte from the first requested byte (as returned - * by `data`). If this is invoked when no valid memory mapping has been created - * prior to this call, undefined behaviour ensues. - */ - reference operator[](const size_type i) noexcept { return data_[i]; } - const_reference operator[](const size_type i) const noexcept { return data_[i]; } - - /** - * Establishes a memory mapping with AccessMode. If the mapping is unsuccesful, the - * reason is reported via `error` and the object remains in a state as if this - * function hadn't been called. - * - * `path`, which must be a path to an existing file, is used to retrieve a file - * handle (which is closed when the object destructs or `unmap` is called), which is - * then used to memory map the requested region. Upon failure, `error` is set to - * indicate the reason and the object remains in an unmapped state. - * - * `offset` is the number of bytes, relative to the start of the file, where the - * mapping should begin. When specifying it, there is no need to worry about - * providing a value that is aligned with the operating system's page allocation - * granularity. This is adjusted by the implementation such that the first requested - * byte (as returned by `data` or `begin`), so long as `offset` is valid, will be at - * `offset` from the start of the file. - * - * `length` is the number of bytes to map. It may be `map_entire_file`, in which - * case a mapping of the entire file is created. - */ - template - void map(const String& path, const size_type offset, - const size_type length, std::error_code& error); - - /** - * Establishes a memory mapping with AccessMode. If the mapping is unsuccesful, the - * reason is reported via `error` and the object remains in a state as if this - * function hadn't been called. - * - * `path`, which must be a path to an existing file, is used to retrieve a file - * handle (which is closed when the object destructs or `unmap` is called), which is - * then used to memory map the requested region. Upon failure, `error` is set to - * indicate the reason and the object remains in an unmapped state. - * - * The entire file is mapped. - */ - template - void map(const String& path, std::error_code& error) - { - map(path, 0, map_entire_file, error); - } - - /** - * Establishes a memory mapping with AccessMode. If the mapping is - * unsuccesful, the reason is reported via `error` and the object remains in - * a state as if this function hadn't been called. - * - * `handle`, which must be a valid file handle, which is used to memory map the - * requested region. Upon failure, `error` is set to indicate the reason and the - * object remains in an unmapped state. - * - * `offset` is the number of bytes, relative to the start of the file, where the - * mapping should begin. When specifying it, there is no need to worry about - * providing a value that is aligned with the operating system's page allocation - * granularity. This is adjusted by the implementation such that the first requested - * byte (as returned by `data` or `begin`), so long as `offset` is valid, will be at - * `offset` from the start of the file. - * - * `length` is the number of bytes to map. It may be `map_entire_file`, in which - * case a mapping of the entire file is created. - */ - void map(const handle_type handle, const size_type offset, - const size_type length, std::error_code& error); - - /** - * Establishes a memory mapping with AccessMode. If the mapping is - * unsuccesful, the reason is reported via `error` and the object remains in - * a state as if this function hadn't been called. - * - * `handle`, which must be a valid file handle, which is used to memory map the - * requested region. Upon failure, `error` is set to indicate the reason and the - * object remains in an unmapped state. - * - * The entire file is mapped. - */ - void map(const handle_type handle, std::error_code& error) - { - map(handle, 0, map_entire_file, error); - } - - /** - * If a valid memory mapping has been created prior to this call, this call - * instructs the kernel to unmap the memory region and disassociate this object - * from the file. - * - * The file handle associated with the file that is mapped is only closed if the - * mapping was created using a file path. If, on the other hand, an existing - * file handle was used to create the mapping, the file handle is not closed. - */ - void unmap(); - - void swap(basic_mmap& other); - - /** Flushes the memory mapped page to disk. Errors are reported via `error`. */ - template - typename std::enable_if::type - sync(std::error_code& error); - - /** - * All operators compare the address of the first byte and size of the two mapped - * regions. - */ - -private: - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > pointer get_mapping_start() noexcept - { - return !data() ? nullptr : data() - mapping_offset(); - } - - const_pointer get_mapping_start() const noexcept - { - return !data() ? nullptr : data() - mapping_offset(); - } - - /** - * The destructor syncs changes to disk if `AccessMode` is `write`, but not - * if it's `read`, but since the destructor cannot be templated, we need to - * do SFINAE in a dedicated function, where one syncs and the other is a noop. - */ - template - typename std::enable_if::type - conditional_sync(); - template - typename std::enable_if::type conditional_sync(); -}; - -template -bool operator==(const basic_mmap& a, - const basic_mmap& b); - -template -bool operator!=(const basic_mmap& a, - const basic_mmap& b); - -template -bool operator<(const basic_mmap& a, - const basic_mmap& b); - -template -bool operator<=(const basic_mmap& a, - const basic_mmap& b); - -template -bool operator>(const basic_mmap& a, - const basic_mmap& b); - -template -bool operator>=(const basic_mmap& a, - const basic_mmap& b); - -/** - * This is the basis for all read-only mmap objects and should be preferred over - * directly using `basic_mmap`. - */ -template -using basic_mmap_source = basic_mmap; - -/** - * This is the basis for all read-write mmap objects and should be preferred over - * directly using `basic_mmap`. - */ -template -using basic_mmap_sink = basic_mmap; - -/** - * These aliases cover the most common use cases, both representing a raw byte stream - * (either with a char or an unsigned char/uint8_t). - */ -using mmap_source = basic_mmap_source; -using ummap_source = basic_mmap_source; - -using mmap_sink = basic_mmap_sink; -using ummap_sink = basic_mmap_sink; - -/** - * Convenience factory method that constructs a mapping for any `basic_mmap` or - * `basic_mmap` type. - */ -template< - typename MMap, - typename MappingToken -> MMap make_mmap(const MappingToken& token, - int64_t offset, int64_t length, std::error_code& error) -{ - MMap mmap; - mmap.map(token, offset, length, error); - return mmap; -} - -/** - * Convenience factory method. - * - * MappingToken may be a String (`std::string`, `std::string_view`, `const char*`, - * `std::filesystem::path`, `std::vector`, or similar), or a - * `mmap_source::handle_type`. - */ -template -mmap_source make_mmap_source(const MappingToken& token, mmap_source::size_type offset, - mmap_source::size_type length, std::error_code& error) -{ - return make_mmap(token, offset, length, error); -} - -template -mmap_source make_mmap_source(const MappingToken& token, std::error_code& error) -{ - return make_mmap_source(token, 0, map_entire_file, error); -} - -/** - * Convenience factory method. - * - * MappingToken may be a String (`std::string`, `std::string_view`, `const char*`, - * `std::filesystem::path`, `std::vector`, or similar), or a - * `mmap_sink::handle_type`. - */ -template -mmap_sink make_mmap_sink(const MappingToken& token, mmap_sink::size_type offset, - mmap_sink::size_type length, std::error_code& error) -{ - return make_mmap(token, offset, length, error); -} - -template -mmap_sink make_mmap_sink(const MappingToken& token, std::error_code& error) -{ - return make_mmap_sink(token, 0, map_entire_file, error); -} - -} // namespace mio - -// #include "detail/mmap.ipp" -/* Copyright 2017 https://github.com/mandreyel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the "Software"), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be included in all copies - * or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MIO_BASIC_MMAP_IMPL -#define MIO_BASIC_MMAP_IMPL - -// #include "mio/mmap.hpp" - -// #include "mio/page.hpp" - -// #include "mio/detail/string_util.hpp" -/* Copyright 2017 https://github.com/mandreyel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the "Software"), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be included in all copies - * or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MIO_STRING_UTIL_HEADER -#define MIO_STRING_UTIL_HEADER - -#include - -namespace mio { -namespace detail { - -template< - typename S, - typename C = typename std::decay::type, - typename = decltype(std::declval().data()), - typename = typename std::enable_if< - std::is_same::value -#ifdef _WIN32 - || std::is_same::value -#endif - >::type -> struct char_type_helper { - using type = typename C::value_type; -}; - -template -struct char_type { - using type = typename char_type_helper::type; -}; - -// TODO: can we avoid this brute force approach? -template<> -struct char_type { - using type = char; -}; - -template<> -struct char_type { - using type = char; -}; - -template -struct char_type { - using type = char; -}; - -template -struct char_type { - using type = char; -}; - -#ifdef _WIN32 -template<> -struct char_type { - using type = wchar_t; -}; - -template<> -struct char_type { - using type = wchar_t; -}; - -template -struct char_type { - using type = wchar_t; -}; - -template -struct char_type { - using type = wchar_t; -}; -#endif // _WIN32 - -template -struct is_c_str_helper -{ - static constexpr bool value = std::is_same< - CharT*, - // TODO: I'm so sorry for this... Can this be made cleaner? - typename std::add_pointer< - typename std::remove_cv< - typename std::remove_pointer< - typename std::decay< - S - >::type - >::type - >::type - >::type - >::value; -}; - -template -struct is_c_str -{ - static constexpr bool value = is_c_str_helper::value; -}; - -#ifdef _WIN32 -template -struct is_c_wstr -{ - static constexpr bool value = is_c_str_helper::value; -}; -#endif // _WIN32 - -template -struct is_c_str_or_c_wstr -{ - static constexpr bool value = is_c_str::value -#ifdef _WIN32 - || is_c_wstr::value -#endif - ; -}; - -template< - typename String, - typename = decltype(std::declval().data()), - typename = typename std::enable_if::value>::type -> const typename char_type::type* c_str(const String& path) -{ - return path.data(); -} - -template< - typename String, - typename = decltype(std::declval().empty()), - typename = typename std::enable_if::value>::type -> bool empty(const String& path) -{ - return path.empty(); -} - -template< - typename String, - typename = typename std::enable_if::value>::type -> const typename char_type::type* c_str(String path) -{ - return path; -} - -template< - typename String, - typename = typename std::enable_if::value>::type -> bool empty(String path) -{ - return !path || (*path == 0); -} - -} // namespace detail -} // namespace mio - -#endif // MIO_STRING_UTIL_HEADER - - -#include - -#ifndef _WIN32 -# include -# include -# include -# include -#endif - -namespace mio { -namespace detail { - -#ifdef _WIN32 -namespace win { - -/** Returns the 4 upper bytes of an 8-byte integer. */ -inline DWORD int64_high(int64_t n) noexcept -{ - return n >> 32; -} - -/** Returns the 4 lower bytes of an 8-byte integer. */ -inline DWORD int64_low(int64_t n) noexcept -{ - return n & 0xffffffff; -} - -template< - typename String, - typename = typename std::enable_if< - std::is_same::type, char>::value - >::type -> file_handle_type open_file_helper(const String& path, const access_mode mode) -{ - return ::CreateFileA(c_str(path), - mode == access_mode::read ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - 0); -} - -template -typename std::enable_if< - std::is_same::type, wchar_t>::value, - file_handle_type ->::type open_file_helper(const String& path, const access_mode mode) -{ - return ::CreateFileW(c_str(path), - mode == access_mode::read ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - 0, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - 0); -} - -} // win -#endif // _WIN32 - -/** - * Returns the last platform specific system error (errno on POSIX and - * GetLastError on Win) as a `std::error_code`. - */ -inline std::error_code last_error() noexcept -{ - std::error_code error; -#ifdef _WIN32 - error.assign(GetLastError(), std::system_category()); -#else - error.assign(errno, std::system_category()); -#endif - return error; -} - -template -file_handle_type open_file(const String& path, const access_mode mode, - std::error_code& error) -{ - error.clear(); - if(detail::empty(path)) - { - error = std::make_error_code(std::errc::invalid_argument); - return invalid_handle; - } -#ifdef _WIN32 - const auto handle = win::open_file_helper(path, mode); -#else // POSIX - const auto handle = ::open(c_str(path), - mode == access_mode::read ? O_RDONLY : O_RDWR); -#endif - if(handle == invalid_handle) - { - error = detail::last_error(); - } - return handle; -} - -inline size_t query_file_size(file_handle_type handle, std::error_code& error) -{ - error.clear(); -#ifdef _WIN32 - LARGE_INTEGER file_size; - if(::GetFileSizeEx(handle, &file_size) == 0) - { - error = detail::last_error(); - return 0; - } - return static_cast(file_size.QuadPart); -#else // POSIX - struct stat sbuf; - if(::fstat(handle, &sbuf) == -1) - { - error = detail::last_error(); - return 0; - } - return sbuf.st_size; -#endif -} - -struct mmap_context -{ - char* data; - int64_t length; - int64_t mapped_length; -#ifdef _WIN32 - file_handle_type file_mapping_handle; -#endif -}; - -inline mmap_context memory_map(const file_handle_type file_handle, const int64_t offset, - const int64_t length, const access_mode mode, std::error_code& error) -{ - const int64_t aligned_offset = make_offset_page_aligned(offset); - const int64_t length_to_map = offset - aligned_offset + length; -#ifdef _WIN32 - const int64_t max_file_size = offset + length; - const auto file_mapping_handle = ::CreateFileMapping( - file_handle, - 0, - mode == access_mode::read ? PAGE_READONLY : PAGE_READWRITE, - win::int64_high(max_file_size), - win::int64_low(max_file_size), - 0); - if(file_mapping_handle == invalid_handle) - { - error = detail::last_error(); - return {}; - } - char* mapping_start = static_cast(::MapViewOfFile( - file_mapping_handle, - mode == access_mode::read ? FILE_MAP_READ : FILE_MAP_WRITE, - win::int64_high(aligned_offset), - win::int64_low(aligned_offset), - length_to_map)); - if(mapping_start == nullptr) - { - // Close file handle if mapping it failed. - ::CloseHandle(file_mapping_handle); - error = detail::last_error(); - return {}; - } -#else // POSIX - char* mapping_start = static_cast(::mmap( - 0, // Don't give hint as to where to map. - length_to_map, - mode == access_mode::read ? PROT_READ : PROT_WRITE, - MAP_SHARED, - file_handle, - aligned_offset)); - if(mapping_start == MAP_FAILED) - { - error = detail::last_error(); - return {}; - } -#endif - mmap_context ctx; - ctx.data = mapping_start + offset - aligned_offset; - ctx.length = length; - ctx.mapped_length = length_to_map; -#ifdef _WIN32 - ctx.file_mapping_handle = file_mapping_handle; -#endif - return ctx; -} - -} // namespace detail - -// -- basic_mmap -- - -template -basic_mmap::~basic_mmap() -{ - conditional_sync(); - unmap(); -} - -template -basic_mmap::basic_mmap(basic_mmap&& other) - : data_(std::move(other.data_)) - , length_(std::move(other.length_)) - , mapped_length_(std::move(other.mapped_length_)) - , file_handle_(std::move(other.file_handle_)) -#ifdef _WIN32 - , file_mapping_handle_(std::move(other.file_mapping_handle_)) -#endif - , is_handle_internal_(std::move(other.is_handle_internal_)) -{ - other.data_ = nullptr; - other.length_ = other.mapped_length_ = 0; - other.file_handle_ = invalid_handle; -#ifdef _WIN32 - other.file_mapping_handle_ = invalid_handle; -#endif -} - -template -basic_mmap& -basic_mmap::operator=(basic_mmap&& other) -{ - if(this != &other) - { - // First the existing mapping needs to be removed. - unmap(); - data_ = std::move(other.data_); - length_ = std::move(other.length_); - mapped_length_ = std::move(other.mapped_length_); - file_handle_ = std::move(other.file_handle_); -#ifdef _WIN32 - file_mapping_handle_ = std::move(other.file_mapping_handle_); -#endif - is_handle_internal_ = std::move(other.is_handle_internal_); - - // The moved from basic_mmap's fields need to be reset, because - // otherwise other's destructor will unmap the same mapping that was - // just moved into this. - other.data_ = nullptr; - other.length_ = other.mapped_length_ = 0; - other.file_handle_ = invalid_handle; -#ifdef _WIN32 - other.file_mapping_handle_ = invalid_handle; -#endif - other.is_handle_internal_ = false; - } - return *this; -} - -template -typename basic_mmap::handle_type -basic_mmap::mapping_handle() const noexcept -{ -#ifdef _WIN32 - return file_mapping_handle_; -#else - return file_handle_; -#endif -} - -template -template -void basic_mmap::map(const String& path, const size_type offset, - const size_type length, std::error_code& error) -{ - error.clear(); - if(detail::empty(path)) - { - error = std::make_error_code(std::errc::invalid_argument); - return; - } - const auto handle = detail::open_file(path, AccessMode, error); - if(error) - { - return; - } - - map(handle, offset, length, error); - // This MUST be after the call to map, as that sets this to true. - if(!error) - { - is_handle_internal_ = true; - } -} - -template -void basic_mmap::map(const handle_type handle, - const size_type offset, const size_type length, std::error_code& error) -{ - error.clear(); - if(handle == invalid_handle) - { - error = std::make_error_code(std::errc::bad_file_descriptor); - return; - } - - const auto file_size = detail::query_file_size(handle, error); - if(error) - { - return; - } - - if(offset + length > file_size) - { - error = std::make_error_code(std::errc::invalid_argument); - return; - } - - const auto ctx = detail::memory_map(handle, offset, - length == map_entire_file ? (file_size - offset) : length, - AccessMode, error); - if(!error) - { - // We must unmap the previous mapping that may have existed prior to this call. - // Note that this must only be invoked after a new mapping has been created in - // order to provide the strong guarantee that, should the new mapping fail, the - // `map` function leaves this instance in a state as though the function had - // never been invoked. - unmap(); - file_handle_ = handle; - is_handle_internal_ = false; - data_ = reinterpret_cast(ctx.data); - length_ = ctx.length; - mapped_length_ = ctx.mapped_length; -#ifdef _WIN32 - file_mapping_handle_ = ctx.file_mapping_handle; -#endif - } -} - -template -template -typename std::enable_if::type -basic_mmap::sync(std::error_code& error) -{ - error.clear(); - if(!is_open()) - { - error = std::make_error_code(std::errc::bad_file_descriptor); - return; - } - - if(data()) - { -#ifdef _WIN32 - if(::FlushViewOfFile(get_mapping_start(), mapped_length_) == 0 - || ::FlushFileBuffers(file_handle_) == 0) -#else // POSIX - if(::msync(get_mapping_start(), mapped_length_, MS_SYNC) != 0) -#endif - { - error = detail::last_error(); - return; - } - } -#ifdef _WIN32 - if(::FlushFileBuffers(file_handle_) == 0) - { - error = detail::last_error(); - } -#endif -} - -template -void basic_mmap::unmap() -{ - if(!is_open()) { return; } - // TODO do we care about errors here? -#ifdef _WIN32 - if(is_mapped()) - { - ::UnmapViewOfFile(get_mapping_start()); - ::CloseHandle(file_mapping_handle_); - } -#else // POSIX - if(data_) { ::munmap(const_cast(get_mapping_start()), mapped_length_); } -#endif - - // If `file_handle_` was obtained by our opening it (when map is called with - // a path, rather than an existing file handle), we need to close it, - // otherwise it must not be closed as it may still be used outside this - // instance. - if(is_handle_internal_) - { -#ifdef _WIN32 - ::CloseHandle(file_handle_); -#else // POSIX - ::close(file_handle_); -#endif - } - - // Reset fields to their default values. - data_ = nullptr; - length_ = mapped_length_ = 0; - file_handle_ = invalid_handle; -#ifdef _WIN32 - file_mapping_handle_ = invalid_handle; -#endif -} - -template -bool basic_mmap::is_mapped() const noexcept -{ -#ifdef _WIN32 - return file_mapping_handle_ != invalid_handle; -#else // POSIX - return is_open(); -#endif -} - -template -void basic_mmap::swap(basic_mmap& other) -{ - if(this != &other) - { - using std::swap; - swap(data_, other.data_); - swap(file_handle_, other.file_handle_); -#ifdef _WIN32 - swap(file_mapping_handle_, other.file_mapping_handle_); -#endif - swap(length_, other.length_); - swap(mapped_length_, other.mapped_length_); - swap(is_handle_internal_, other.is_handle_internal_); - } -} - -template -template -typename std::enable_if::type -basic_mmap::conditional_sync() -{ - // This is invoked from the destructor, so not much we can do about - // failures here. - std::error_code ec; - sync(ec); -} - -template -template -typename std::enable_if::type -basic_mmap::conditional_sync() -{ - // noop -} - -template -bool operator==(const basic_mmap& a, - const basic_mmap& b) -{ - return a.data() == b.data() - && a.size() == b.size(); -} - -template -bool operator!=(const basic_mmap& a, - const basic_mmap& b) -{ - return !(a == b); -} - -template -bool operator<(const basic_mmap& a, - const basic_mmap& b) -{ - if(a.data() == b.data()) { return a.size() < b.size(); } - return a.data() < b.data(); -} - -template -bool operator<=(const basic_mmap& a, - const basic_mmap& b) -{ - return !(a > b); -} - -template -bool operator>(const basic_mmap& a, - const basic_mmap& b) -{ - if(a.data() == b.data()) { return a.size() > b.size(); } - return a.data() > b.data(); -} - -template -bool operator>=(const basic_mmap& a, - const basic_mmap& b) -{ - return !(a < b); -} - -} // namespace mio - -#endif // MIO_BASIC_MMAP_IMPL - - -#endif // MIO_MMAP_HEADER -/* Copyright 2017 https://github.com/mandreyel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the "Software"), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be included in all copies - * or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MIO_PAGE_HEADER -#define MIO_PAGE_HEADER - -#ifdef _WIN32 -# include -#else -# include -#endif - -namespace mio { - -/** - * This is used by `basic_mmap` to determine whether to create a read-only or - * a read-write memory mapping. - */ -enum class access_mode -{ - read, - write -}; - -/** - * Determines the operating system's page allocation granularity. - * - * On the first call to this function, it invokes the operating system specific syscall - * to determine the page size, caches the value, and returns it. Any subsequent call to - * this function serves the cached value, so no further syscalls are made. - */ -inline size_t page_size() -{ - static const size_t page_size = [] - { -#ifdef _WIN32 - SYSTEM_INFO SystemInfo; - GetSystemInfo(&SystemInfo); - return SystemInfo.dwAllocationGranularity; -#else - return sysconf(_SC_PAGE_SIZE); -#endif - }(); - return page_size; -} - -/** - * Alligns `offset` to the operating's system page size such that it subtracts the - * difference until the nearest page boundary before `offset`, or does nothing if - * `offset` is already page aligned. - */ -inline size_t make_offset_page_aligned(size_t offset) noexcept -{ - const size_t page_size_ = page_size(); - // Use integer division to round down to the nearest page alignment. - return offset / page_size_ * page_size_; -} - -} // namespace mio - -#endif // MIO_PAGE_HEADER -/* Copyright 2017 https://github.com/mandreyel - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this - * software and associated documentation files (the "Software"), to deal in the Software - * without restriction, including without limitation the rights to use, copy, modify, - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be included in all copies - * or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MIO_SHARED_MMAP_HEADER -#define MIO_SHARED_MMAP_HEADER - -// #include "mio/mmap.hpp" - - -#include // std::error_code -#include // std::shared_ptr - -namespace mio { - -/** - * Exposes (nearly) the same interface as `basic_mmap`, but endowes it with - * `std::shared_ptr` semantics. - * - * This is not the default behaviour of `basic_mmap` to avoid allocating on the heap if - * shared semantics are not required. - */ -template< - access_mode AccessMode, - typename ByteT -> class basic_shared_mmap -{ - using impl_type = basic_mmap; - std::shared_ptr pimpl_; - -public: - using value_type = typename impl_type::value_type; - using size_type = typename impl_type::size_type; - using reference = typename impl_type::reference; - using const_reference = typename impl_type::const_reference; - using pointer = typename impl_type::pointer; - using const_pointer = typename impl_type::const_pointer; - using difference_type = typename impl_type::difference_type; - using iterator = typename impl_type::iterator; - using const_iterator = typename impl_type::const_iterator; - using reverse_iterator = typename impl_type::reverse_iterator; - using const_reverse_iterator = typename impl_type::const_reverse_iterator; - using iterator_category = typename impl_type::iterator_category; - using handle_type = typename impl_type::handle_type; - using mmap_type = impl_type; - - basic_shared_mmap() = default; - basic_shared_mmap(const basic_shared_mmap&) = default; - basic_shared_mmap& operator=(const basic_shared_mmap&) = default; - basic_shared_mmap(basic_shared_mmap&&) = default; - basic_shared_mmap& operator=(basic_shared_mmap&&) = default; - - /** Takes ownership of an existing mmap object. */ - basic_shared_mmap(mmap_type&& mmap) - : pimpl_(std::make_shared(std::move(mmap))) - {} - - /** Takes ownership of an existing mmap object. */ - basic_shared_mmap& operator=(mmap_type&& mmap) - { - pimpl_ = std::make_shared(std::move(mmap)); - return *this; - } - - /** Initializes this object with an already established shared mmap. */ - basic_shared_mmap(std::shared_ptr mmap) : pimpl_(std::move(mmap)) {} - - /** Initializes this object with an already established shared mmap. */ - basic_shared_mmap& operator=(std::shared_ptr mmap) - { - pimpl_ = std::move(mmap); - return *this; - } - -#ifdef __cpp_exceptions - /** - * The same as invoking the `map` function, except any error that may occur - * while establishing the mapping is wrapped in a `std::system_error` and is - * thrown. - */ - template - basic_shared_mmap(const String& path, const size_type offset = 0, const size_type length = map_entire_file) - { - std::error_code error; - map(path, offset, length, error); - if(error) { throw std::system_error(error); } - } - - /** - * The same as invoking the `map` function, except any error that may occur - * while establishing the mapping is wrapped in a `std::system_error` and is - * thrown. - */ - basic_shared_mmap(const handle_type handle, const size_type offset = 0, const size_type length = map_entire_file) - { - std::error_code error; - map(handle, offset, length, error); - if(error) { throw std::system_error(error); } - } -#endif // __cpp_exceptions - - /** - * If this is a read-write mapping and the last reference to the mapping, - * the destructor invokes sync. Regardless of the access mode, unmap is - * invoked as a final step. - */ - ~basic_shared_mmap() = default; - - /** Returns the underlying `std::shared_ptr` instance that holds the mmap. */ - std::shared_ptr get_shared_ptr() { return pimpl_; } - - /** - * On UNIX systems 'file_handle' and 'mapping_handle' are the same. On Windows, - * however, a mapped region of a file gets its own handle, which is returned by - * 'mapping_handle'. - */ - handle_type file_handle() const noexcept - { - return pimpl_ ? pimpl_->file_handle() : invalid_handle; - } - - handle_type mapping_handle() const noexcept - { - return pimpl_ ? pimpl_->mapping_handle() : invalid_handle; - } - - /** Returns whether a valid memory mapping has been created. */ - bool is_open() const noexcept { return pimpl_ && pimpl_->is_open(); } - - /** - * Returns true if no mapping was established, that is, conceptually the - * same as though the length that was mapped was 0. This function is - * provided so that this class has Container semantics. - */ - bool empty() const noexcept { return !pimpl_ || pimpl_->empty(); } - - /** - * `size` and `length` both return the logical length, i.e. the number of bytes - * user requested to be mapped, while `mapped_length` returns the actual number of - * bytes that were mapped which is a multiple of the underlying operating system's - * page allocation granularity. - */ - size_type size() const noexcept { return pimpl_ ? pimpl_->length() : 0; } - size_type length() const noexcept { return pimpl_ ? pimpl_->length() : 0; } - size_type mapped_length() const noexcept - { - return pimpl_ ? pimpl_->mapped_length() : 0; - } - - /** - * Returns a pointer to the first requested byte, or `nullptr` if no memory mapping - * exists. - */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > pointer data() noexcept { return pimpl_->data(); } - const_pointer data() const noexcept { return pimpl_ ? pimpl_->data() : nullptr; } - - /** - * Returns an iterator to the first requested byte, if a valid memory mapping - * exists, otherwise this function call is undefined behaviour. - */ - iterator begin() noexcept { return pimpl_->begin(); } - const_iterator begin() const noexcept { return pimpl_->begin(); } - const_iterator cbegin() const noexcept { return pimpl_->cbegin(); } - - /** - * Returns an iterator one past the last requested byte, if a valid memory mapping - * exists, otherwise this function call is undefined behaviour. - */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > iterator end() noexcept { return pimpl_->end(); } - const_iterator end() const noexcept { return pimpl_->end(); } - const_iterator cend() const noexcept { return pimpl_->cend(); } - - /** - * Returns a reverse iterator to the last memory mapped byte, if a valid - * memory mapping exists, otherwise this function call is undefined - * behaviour. - */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > reverse_iterator rbegin() noexcept { return pimpl_->rbegin(); } - const_reverse_iterator rbegin() const noexcept { return pimpl_->rbegin(); } - const_reverse_iterator crbegin() const noexcept { return pimpl_->crbegin(); } - - /** - * Returns a reverse iterator past the first mapped byte, if a valid memory - * mapping exists, otherwise this function call is undefined behaviour. - */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > reverse_iterator rend() noexcept { return pimpl_->rend(); } - const_reverse_iterator rend() const noexcept { return pimpl_->rend(); } - const_reverse_iterator crend() const noexcept { return pimpl_->crend(); } - - /** - * Returns a reference to the `i`th byte from the first requested byte (as returned - * by `data`). If this is invoked when no valid memory mapping has been created - * prior to this call, undefined behaviour ensues. - */ - reference operator[](const size_type i) noexcept { return (*pimpl_)[i]; } - const_reference operator[](const size_type i) const noexcept { return (*pimpl_)[i]; } - - /** - * Establishes a memory mapping with AccessMode. If the mapping is unsuccesful, the - * reason is reported via `error` and the object remains in a state as if this - * function hadn't been called. - * - * `path`, which must be a path to an existing file, is used to retrieve a file - * handle (which is closed when the object destructs or `unmap` is called), which is - * then used to memory map the requested region. Upon failure, `error` is set to - * indicate the reason and the object remains in an unmapped state. - * - * `offset` is the number of bytes, relative to the start of the file, where the - * mapping should begin. When specifying it, there is no need to worry about - * providing a value that is aligned with the operating system's page allocation - * granularity. This is adjusted by the implementation such that the first requested - * byte (as returned by `data` or `begin`), so long as `offset` is valid, will be at - * `offset` from the start of the file. - * - * `length` is the number of bytes to map. It may be `map_entire_file`, in which - * case a mapping of the entire file is created. - */ - template - void map(const String& path, const size_type offset, - const size_type length, std::error_code& error) - { - map_impl(path, offset, length, error); - } - - /** - * Establishes a memory mapping with AccessMode. If the mapping is unsuccesful, the - * reason is reported via `error` and the object remains in a state as if this - * function hadn't been called. - * - * `path`, which must be a path to an existing file, is used to retrieve a file - * handle (which is closed when the object destructs or `unmap` is called), which is - * then used to memory map the requested region. Upon failure, `error` is set to - * indicate the reason and the object remains in an unmapped state. - * - * The entire file is mapped. - */ - template - void map(const String& path, std::error_code& error) - { - map_impl(path, 0, map_entire_file, error); - } - - /** - * Establishes a memory mapping with AccessMode. If the mapping is unsuccesful, the - * reason is reported via `error` and the object remains in a state as if this - * function hadn't been called. - * - * `handle`, which must be a valid file handle, which is used to memory map the - * requested region. Upon failure, `error` is set to indicate the reason and the - * object remains in an unmapped state. - * - * `offset` is the number of bytes, relative to the start of the file, where the - * mapping should begin. When specifying it, there is no need to worry about - * providing a value that is aligned with the operating system's page allocation - * granularity. This is adjusted by the implementation such that the first requested - * byte (as returned by `data` or `begin`), so long as `offset` is valid, will be at - * `offset` from the start of the file. - * - * `length` is the number of bytes to map. It may be `map_entire_file`, in which - * case a mapping of the entire file is created. - */ - void map(const handle_type handle, const size_type offset, - const size_type length, std::error_code& error) - { - map_impl(handle, offset, length, error); - } - - /** - * Establishes a memory mapping with AccessMode. If the mapping is unsuccesful, the - * reason is reported via `error` and the object remains in a state as if this - * function hadn't been called. - * - * `handle`, which must be a valid file handle, which is used to memory map the - * requested region. Upon failure, `error` is set to indicate the reason and the - * object remains in an unmapped state. - * - * The entire file is mapped. - */ - void map(const handle_type handle, std::error_code& error) - { - map_impl(handle, 0, map_entire_file, error); - } - - /** - * If a valid memory mapping has been created prior to this call, this call - * instructs the kernel to unmap the memory region and disassociate this object - * from the file. - * - * The file handle associated with the file that is mapped is only closed if the - * mapping was created using a file path. If, on the other hand, an existing - * file handle was used to create the mapping, the file handle is not closed. - */ - void unmap() { if(pimpl_) pimpl_->unmap(); } - - void swap(basic_shared_mmap& other) { pimpl_.swap(other.pimpl_); } - - /** Flushes the memory mapped page to disk. Errors are reported via `error`. */ - template< - access_mode A = AccessMode, - typename = typename std::enable_if::type - > void sync(std::error_code& error) { if(pimpl_) pimpl_->sync(error); } - - /** All operators compare the underlying `basic_mmap`'s addresses. */ - - friend bool operator==(const basic_shared_mmap& a, const basic_shared_mmap& b) - { - return a.pimpl_ == b.pimpl_; - } - - friend bool operator!=(const basic_shared_mmap& a, const basic_shared_mmap& b) - { - return !(a == b); - } - - friend bool operator<(const basic_shared_mmap& a, const basic_shared_mmap& b) - { - return a.pimpl_ < b.pimpl_; - } - - friend bool operator<=(const basic_shared_mmap& a, const basic_shared_mmap& b) - { - return a.pimpl_ <= b.pimpl_; - } - - friend bool operator>(const basic_shared_mmap& a, const basic_shared_mmap& b) - { - return a.pimpl_ > b.pimpl_; - } - - friend bool operator>=(const basic_shared_mmap& a, const basic_shared_mmap& b) - { - return a.pimpl_ >= b.pimpl_; - } - -private: - template - void map_impl(const MappingToken& token, const size_type offset, - const size_type length, std::error_code& error) - { - if(!pimpl_) - { - mmap_type mmap = make_mmap(token, offset, length, error); - if(error) { return; } - pimpl_ = std::make_shared(std::move(mmap)); - } - else - { - pimpl_->map(token, offset, length, error); - } - } -}; - -/** - * This is the basis for all read-only mmap objects and should be preferred over - * directly using basic_shared_mmap. - */ -template -using basic_shared_mmap_source = basic_shared_mmap; - -/** - * This is the basis for all read-write mmap objects and should be preferred over - * directly using basic_shared_mmap. - */ -template -using basic_shared_mmap_sink = basic_shared_mmap; - -/** - * These aliases cover the most common use cases, both representing a raw byte stream - * (either with a char or an unsigned char/uint8_t). - */ -using shared_mmap_source = basic_shared_mmap_source; -using shared_ummap_source = basic_shared_mmap_source; - -using shared_mmap_sink = basic_shared_mmap_sink; -using shared_ummap_sink = basic_shared_mmap_sink; - -} // namespace mio - -#endif // MIO_SHARED_MMAP_HEADER - -/** @file - * @brief Contains the main CSV parsing algorithm and various utility functions - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/** @file - * A standalone header file containing shared code - */ - -#include -#include -#include -#include -#include - -#if defined(_WIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# undef max -# undef min -#elif defined(__linux__) -# include -#endif - - /** Helper macro which should be #defined as "inline" - * in the single header version - */ -#define CSV_INLINE inline - -#include - -// Copyright 2017-2019 by Martin Moene -// -// string-view lite, a C++17-like string_view for C++98 and later. -// For more information see https://github.com/martinmoene/string-view-lite -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef NONSTD_SV_LITE_H_INCLUDED -#define NONSTD_SV_LITE_H_INCLUDED - -#define string_view_lite_MAJOR 1 -#define string_view_lite_MINOR 1 -#define string_view_lite_PATCH 0 - -#define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH) - -#define nssv_STRINGIFY( x ) nssv_STRINGIFY_( x ) -#define nssv_STRINGIFY_( x ) #x - -// string-view lite configuration: - -#define nssv_STRING_VIEW_DEFAULT 0 -#define nssv_STRING_VIEW_NONSTD 1 -#define nssv_STRING_VIEW_STD 2 - -#if !defined( nssv_CONFIG_SELECT_STRING_VIEW ) -# define nssv_CONFIG_SELECT_STRING_VIEW ( nssv_HAVE_STD_STRING_VIEW ? nssv_STRING_VIEW_STD : nssv_STRING_VIEW_NONSTD ) -#endif - -#if defined( nssv_CONFIG_SELECT_STD_STRING_VIEW ) || defined( nssv_CONFIG_SELECT_NONSTD_STRING_VIEW ) -# error nssv_CONFIG_SELECT_STD_STRING_VIEW and nssv_CONFIG_SELECT_NONSTD_STRING_VIEW are deprecated and removed, please use nssv_CONFIG_SELECT_STRING_VIEW=nssv_STRING_VIEW_... -#endif - -#ifndef nssv_CONFIG_STD_SV_OPERATOR -# define nssv_CONFIG_STD_SV_OPERATOR 0 -#endif - -#ifndef nssv_CONFIG_USR_SV_OPERATOR -# define nssv_CONFIG_USR_SV_OPERATOR 1 -#endif - -#ifdef nssv_CONFIG_CONVERSION_STD_STRING -# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS nssv_CONFIG_CONVERSION_STD_STRING -# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS nssv_CONFIG_CONVERSION_STD_STRING -#endif - -#ifndef nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS -# define nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS 1 -#endif - -#ifndef nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS -# define nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS 1 -#endif - -// Control presence of exception handling (try and auto discover): - -#ifndef nssv_CONFIG_NO_EXCEPTIONS -# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND) -# define nssv_CONFIG_NO_EXCEPTIONS 0 -# else -# define nssv_CONFIG_NO_EXCEPTIONS 1 -# endif -#endif - -// C++ language version detection (C++20 is speculative): -// Note: VC14.0/1900 (VS2015) lacks too much from C++14. - -#ifndef nssv_CPLUSPLUS -# if defined(_MSVC_LANG ) && !defined(__clang__) -# define nssv_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) -# else -# define nssv_CPLUSPLUS __cplusplus -# endif -#endif - -#define nssv_CPP98_OR_GREATER ( nssv_CPLUSPLUS >= 199711L ) -#define nssv_CPP11_OR_GREATER ( nssv_CPLUSPLUS >= 201103L ) -#define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L ) -#define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L ) -#define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L ) -#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202000L ) - -// use C++17 std::string_view if available and requested: - -#if nssv_CPP17_OR_GREATER && defined(__has_include ) -# if __has_include( ) -# define nssv_HAVE_STD_STRING_VIEW 1 -# else -# define nssv_HAVE_STD_STRING_VIEW 0 -# endif -#else -# define nssv_HAVE_STD_STRING_VIEW 0 -#endif - -#define nssv_USES_STD_STRING_VIEW ( (nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_STD) || ((nssv_CONFIG_SELECT_STRING_VIEW == nssv_STRING_VIEW_DEFAULT) && nssv_HAVE_STD_STRING_VIEW) ) - -#define nssv_HAVE_STARTS_WITH ( nssv_CPP20_OR_GREATER || !nssv_USES_STD_STRING_VIEW ) -#define nssv_HAVE_ENDS_WITH nssv_HAVE_STARTS_WITH - -// -// Use C++17 std::string_view: -// - -#if nssv_USES_STD_STRING_VIEW - -#include - -// Extensions for std::string: - -#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS - -namespace nonstd { - -template< class CharT, class Traits, class Allocator = std::allocator > -std::basic_string -to_string( std::basic_string_view v, Allocator const & a = Allocator() ) -{ - return std::basic_string( v.begin(), v.end(), a ); -} - -template< class CharT, class Traits, class Allocator > -std::basic_string_view -to_string_view( std::basic_string const & s ) -{ - return std::basic_string_view( s.data(), s.size() ); -} - -// Literal operators sv and _sv: - -#if nssv_CONFIG_STD_SV_OPERATOR - -using namespace std::literals::string_view_literals; - -#endif - -#if nssv_CONFIG_USR_SV_OPERATOR - -inline namespace literals { -inline namespace string_view_literals { - - -constexpr std::string_view operator "" _sv( const char* str, size_t len ) noexcept // (1) -{ - return std::string_view{ str, len }; -} - -constexpr std::u16string_view operator "" _sv( const char16_t* str, size_t len ) noexcept // (2) -{ - return std::u16string_view{ str, len }; -} - -constexpr std::u32string_view operator "" _sv( const char32_t* str, size_t len ) noexcept // (3) -{ - return std::u32string_view{ str, len }; -} - -constexpr std::wstring_view operator "" _sv( const wchar_t* str, size_t len ) noexcept // (4) -{ - return std::wstring_view{ str, len }; -} - -}} // namespace literals::string_view_literals - -#endif // nssv_CONFIG_USR_SV_OPERATOR - -} // namespace nonstd - -#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS - -namespace nonstd { - -using std::string_view; -using std::wstring_view; -using std::u16string_view; -using std::u32string_view; -using std::basic_string_view; - -// literal "sv" and "_sv", see above - -using std::operator==; -using std::operator!=; -using std::operator<; -using std::operator<=; -using std::operator>; -using std::operator>=; - -using std::operator<<; - -} // namespace nonstd - -#else // nssv_HAVE_STD_STRING_VIEW - -// -// Before C++17: use string_view lite: -// - -// Compiler versions: -// -// MSVC++ 6.0 _MSC_VER == 1200 (Visual Studio 6.0) -// MSVC++ 7.0 _MSC_VER == 1300 (Visual Studio .NET 2002) -// MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio .NET 2003) -// MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005) -// MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008) -// MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010) -// MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012) -// MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013) -// MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) -// MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017) - -#if defined(_MSC_VER ) && !defined(__clang__) -# define nssv_COMPILER_MSVC_VER (_MSC_VER ) -# define nssv_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) ) -#else -# define nssv_COMPILER_MSVC_VER 0 -# define nssv_COMPILER_MSVC_VERSION 0 -#endif - -#define nssv_COMPILER_VERSION( major, minor, patch ) (10 * ( 10 * major + minor) + patch) - -#if defined(__clang__) -# define nssv_COMPILER_CLANG_VERSION nssv_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) -#else -# define nssv_COMPILER_CLANG_VERSION 0 -#endif - -#if defined(__GNUC__) && !defined(__clang__) -# define nssv_COMPILER_GNUC_VERSION nssv_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#else -# define nssv_COMPILER_GNUC_VERSION 0 -#endif - -// half-open range [lo..hi): -#define nssv_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) - -// Presence of language and library features: - -#ifdef _HAS_CPP0X -# define nssv_HAS_CPP0X _HAS_CPP0X -#else -# define nssv_HAS_CPP0X 0 -#endif - -// Unless defined otherwise below, consider VC14 as C++11 for variant-lite: - -#if nssv_COMPILER_MSVC_VER >= 1900 -# undef nssv_CPP11_OR_GREATER -# define nssv_CPP11_OR_GREATER 1 -#endif - -#define nssv_CPP11_90 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1500) -#define nssv_CPP11_100 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1600) -#define nssv_CPP11_110 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1700) -#define nssv_CPP11_120 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1800) -#define nssv_CPP11_140 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1900) -#define nssv_CPP11_141 (nssv_CPP11_OR_GREATER_ || nssv_COMPILER_MSVC_VER >= 1910) - -#define nssv_CPP14_000 (nssv_CPP14_OR_GREATER) -#define nssv_CPP17_000 (nssv_CPP17_OR_GREATER) - -// Presence of C++11 language features: - -#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140 -#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140 -#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140 -#define nssv_HAVE_NOEXCEPT nssv_CPP11_140 -#define nssv_HAVE_NULLPTR nssv_CPP11_100 -#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140 -#define nssv_HAVE_UNICODE_LITERALS nssv_CPP11_140 -#define nssv_HAVE_USER_DEFINED_LITERALS nssv_CPP11_140 -#define nssv_HAVE_WCHAR16_T nssv_CPP11_100 -#define nssv_HAVE_WCHAR32_T nssv_CPP11_100 - -#if ! ( ( nssv_CPP11 && nssv_COMPILER_CLANG_VERSION ) || nssv_BETWEEN( nssv_COMPILER_CLANG_VERSION, 300, 400 ) ) -# define nssv_HAVE_STD_DEFINED_LITERALS nssv_CPP11_140 -#endif - -// Presence of C++14 language features: - -#define nssv_HAVE_CONSTEXPR_14 nssv_CPP14_000 - -// Presence of C++17 language features: - -#define nssv_HAVE_NODISCARD nssv_CPP17_000 - -// Presence of C++ library features: - -#define nssv_HAVE_STD_HASH nssv_CPP11_120 - -// C++ feature usage: - -#if nssv_HAVE_CONSTEXPR_11 -# define nssv_constexpr constexpr -#else -# define nssv_constexpr /*constexpr*/ -#endif - -#if nssv_HAVE_CONSTEXPR_14 -# define nssv_constexpr14 constexpr -#else -# define nssv_constexpr14 /*constexpr*/ -#endif - -#if nssv_HAVE_EXPLICIT_CONVERSION -# define nssv_explicit explicit -#else -# define nssv_explicit /*explicit*/ -#endif - -#if nssv_HAVE_INLINE_NAMESPACE -# define nssv_inline_ns inline -#else -# define nssv_inline_ns /*inline*/ -#endif - -#if nssv_HAVE_NOEXCEPT -# define nssv_noexcept noexcept -#else -# define nssv_noexcept /*noexcept*/ -#endif - -//#if nssv_HAVE_REF_QUALIFIER -//# define nssv_ref_qual & -//# define nssv_refref_qual && -//#else -//# define nssv_ref_qual /*&*/ -//# define nssv_refref_qual /*&&*/ -//#endif - -#if nssv_HAVE_NULLPTR -# define nssv_nullptr nullptr -#else -# define nssv_nullptr NULL -#endif - -#if nssv_HAVE_NODISCARD -# define nssv_nodiscard [[nodiscard]] -#else -# define nssv_nodiscard /*[[nodiscard]]*/ -#endif - -// Additional includes: - -#include -#include -#include -#include -#include -#include // std::char_traits<> - -#if ! nssv_CONFIG_NO_EXCEPTIONS -# include -#endif - -#if nssv_CPP11_OR_GREATER -# include -#endif - -// Clang, GNUC, MSVC warning suppression macros: - -#if defined(__clang__) -# pragma clang diagnostic ignored "-Wreserved-user-defined-literal" -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wuser-defined-literals" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wliteral-suffix" -#endif // __clang__ - -#if nssv_COMPILER_MSVC_VERSION >= 140 -# define nssv_SUPPRESS_MSGSL_WARNING(expr) [[gsl::suppress(expr)]] -# define nssv_SUPPRESS_MSVC_WARNING(code, descr) __pragma(warning(suppress: code) ) -# define nssv_DISABLE_MSVC_WARNINGS(codes) __pragma(warning(push)) __pragma(warning(disable: codes)) -#else -# define nssv_SUPPRESS_MSGSL_WARNING(expr) -# define nssv_SUPPRESS_MSVC_WARNING(code, descr) -# define nssv_DISABLE_MSVC_WARNINGS(codes) -#endif - -#if defined(__clang__) -# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop") -#elif defined(__GNUC__) -# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop") -#elif nssv_COMPILER_MSVC_VERSION >= 140 -# define nssv_RESTORE_WARNINGS() __pragma(warning(pop )) -#else -# define nssv_RESTORE_WARNINGS() -#endif - -// Suppress the following MSVC (GSL) warnings: -// - C4455, non-gsl : 'operator ""sv': literal suffix identifiers that do not -// start with an underscore are reserved -// - C26472, gsl::t.1 : don't use a static_cast for arithmetic conversions; -// use brace initialization, gsl::narrow_cast or gsl::narow -// - C26481: gsl::b.1 : don't use pointer arithmetic. Use span instead - -nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 ) -//nssv_DISABLE_CLANG_WARNINGS( "-Wuser-defined-literals" ) -//nssv_DISABLE_GNUC_WARNINGS( -Wliteral-suffix ) - -namespace nonstd { namespace sv_lite { - -template -< - class CharT, - class Traits = std::char_traits -> -class basic_string_view; - -// -// basic_string_view: -// - -template -< - class CharT, - class Traits /* = std::char_traits */ -> -class basic_string_view -{ -public: - // Member types: - - typedef Traits traits_type; - typedef CharT value_type; - - typedef CharT * pointer; - typedef CharT const * const_pointer; - typedef CharT & reference; - typedef CharT const & const_reference; - - typedef const_pointer iterator; - typedef const_pointer const_iterator; - typedef std::reverse_iterator< const_iterator > reverse_iterator; - typedef std::reverse_iterator< const_iterator > const_reverse_iterator; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - // 24.4.2.1 Construction and assignment: - - nssv_constexpr basic_string_view() nssv_noexcept - : data_( nssv_nullptr ) - , size_( 0 ) - {} - -#if nssv_CPP11_OR_GREATER - nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept = default; -#else - nssv_constexpr basic_string_view( basic_string_view const & other ) nssv_noexcept - : data_( other.data_) - , size_( other.size_) - {} -#endif - - nssv_constexpr basic_string_view( CharT const * s, size_type count ) - : data_( s ) - , size_( count ) - {} - - nssv_constexpr basic_string_view( CharT const * s) - : data_( s ) - , size_( Traits::length(s) ) - {} - - // Assignment: - -#if nssv_CPP11_OR_GREATER - nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept = default; -#else - nssv_constexpr14 basic_string_view & operator=( basic_string_view const & other ) nssv_noexcept - { - data_ = other.data_; - size_ = other.size_; - return *this; - } -#endif - - // 24.4.2.2 Iterator support: - - nssv_constexpr const_iterator begin() const nssv_noexcept { return data_; } - nssv_constexpr const_iterator end() const nssv_noexcept { return data_ + size_; } - - nssv_constexpr const_iterator cbegin() const nssv_noexcept { return begin(); } - nssv_constexpr const_iterator cend() const nssv_noexcept { return end(); } - - nssv_constexpr const_reverse_iterator rbegin() const nssv_noexcept { return const_reverse_iterator( end() ); } - nssv_constexpr const_reverse_iterator rend() const nssv_noexcept { return const_reverse_iterator( begin() ); } - - nssv_constexpr const_reverse_iterator crbegin() const nssv_noexcept { return rbegin(); } - nssv_constexpr const_reverse_iterator crend() const nssv_noexcept { return rend(); } - - // 24.4.2.3 Capacity: - - nssv_constexpr size_type size() const nssv_noexcept { return size_; } - nssv_constexpr size_type length() const nssv_noexcept { return size_; } - nssv_constexpr size_type max_size() const nssv_noexcept { return (std::numeric_limits< size_type >::max)(); } - - // since C++20 - nssv_nodiscard nssv_constexpr bool empty() const nssv_noexcept - { - return 0 == size_; - } - - // 24.4.2.4 Element access: - - nssv_constexpr const_reference operator[]( size_type pos ) const - { - return data_at( pos ); - } - - nssv_constexpr14 const_reference at( size_type pos ) const - { -#if nssv_CONFIG_NO_EXCEPTIONS - assert( pos < size() ); -#else - if ( pos >= size() ) - { - throw std::out_of_range("nonst::string_view::at()"); - } -#endif - return data_at( pos ); - } - - nssv_constexpr const_reference front() const { return data_at( 0 ); } - nssv_constexpr const_reference back() const { return data_at( size() - 1 ); } - - nssv_constexpr const_pointer data() const nssv_noexcept { return data_; } - - // 24.4.2.5 Modifiers: - - nssv_constexpr14 void remove_prefix( size_type n ) - { - assert( n <= size() ); - data_ += n; - size_ -= n; - } - - nssv_constexpr14 void remove_suffix( size_type n ) - { - assert( n <= size() ); - size_ -= n; - } - - nssv_constexpr14 void swap( basic_string_view & other ) nssv_noexcept - { - using std::swap; - swap( data_, other.data_ ); - swap( size_, other.size_ ); - } - - // 24.4.2.6 String operations: - - size_type copy( CharT * dest, size_type n, size_type pos = 0 ) const - { -#if nssv_CONFIG_NO_EXCEPTIONS - assert( pos <= size() ); -#else - if ( pos > size() ) - { - throw std::out_of_range("nonst::string_view::copy()"); - } -#endif - const size_type rlen = (std::min)( n, size() - pos ); - - (void) Traits::copy( dest, data() + pos, rlen ); - - return rlen; - } - - nssv_constexpr14 basic_string_view substr( size_type pos = 0, size_type n = npos ) const - { -#if nssv_CONFIG_NO_EXCEPTIONS - assert( pos <= size() ); -#else - if ( pos > size() ) - { - throw std::out_of_range("nonst::string_view::substr()"); - } -#endif - return basic_string_view( data() + pos, (std::min)( n, size() - pos ) ); - } - - // compare(), 6x: - - nssv_constexpr14 int compare( basic_string_view other ) const nssv_noexcept // (1) - { - if ( const int result = Traits::compare( data(), other.data(), (std::min)( size(), other.size() ) ) ) - return result; - - return size() == other.size() ? 0 : size() < other.size() ? -1 : 1; - } - - nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other ) const // (2) - { - return substr( pos1, n1 ).compare( other ); - } - - nssv_constexpr int compare( size_type pos1, size_type n1, basic_string_view other, size_type pos2, size_type n2 ) const // (3) - { - return substr( pos1, n1 ).compare( other.substr( pos2, n2 ) ); - } - - nssv_constexpr int compare( CharT const * s ) const // (4) - { - return compare( basic_string_view( s ) ); - } - - nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s ) const // (5) - { - return substr( pos1, n1 ).compare( basic_string_view( s ) ); - } - - nssv_constexpr int compare( size_type pos1, size_type n1, CharT const * s, size_type n2 ) const // (6) - { - return substr( pos1, n1 ).compare( basic_string_view( s, n2 ) ); - } - - // 24.4.2.7 Searching: - - // starts_with(), 3x, since C++20: - - nssv_constexpr bool starts_with( basic_string_view v ) const nssv_noexcept // (1) - { - return size() >= v.size() && compare( 0, v.size(), v ) == 0; - } - - nssv_constexpr bool starts_with( CharT c ) const nssv_noexcept // (2) - { - return starts_with( basic_string_view( &c, 1 ) ); - } - - nssv_constexpr bool starts_with( CharT const * s ) const // (3) - { - return starts_with( basic_string_view( s ) ); - } - - // ends_with(), 3x, since C++20: - - nssv_constexpr bool ends_with( basic_string_view v ) const nssv_noexcept // (1) - { - return size() >= v.size() && compare( size() - v.size(), npos, v ) == 0; - } - - nssv_constexpr bool ends_with( CharT c ) const nssv_noexcept // (2) - { - return ends_with( basic_string_view( &c, 1 ) ); - } - - nssv_constexpr bool ends_with( CharT const * s ) const // (3) - { - return ends_with( basic_string_view( s ) ); - } - - // find(), 4x: - - nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) - { - return assert( v.size() == 0 || v.data() != nssv_nullptr ) - , pos >= size() - ? npos - : to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) ); - } - - nssv_constexpr14 size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) - { - return find( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr14 size_type find( CharT const * s, size_type pos, size_type n ) const // (3) - { - return find( basic_string_view( s, n ), pos ); - } - - nssv_constexpr14 size_type find( CharT const * s, size_type pos = 0 ) const // (4) - { - return find( basic_string_view( s ), pos ); - } - - // rfind(), 4x: - - nssv_constexpr14 size_type rfind( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) - { - if ( size() < v.size() ) - return npos; - - if ( v.empty() ) - return (std::min)( size(), pos ); - - const_iterator last = cbegin() + (std::min)( size() - v.size(), pos ) + v.size(); - const_iterator result = std::find_end( cbegin(), last, v.cbegin(), v.cend(), Traits::eq ); - - return result != last ? size_type( result - cbegin() ) : npos; - } - - nssv_constexpr14 size_type rfind( CharT c, size_type pos = npos ) const nssv_noexcept // (2) - { - return rfind( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr14 size_type rfind( CharT const * s, size_type pos, size_type n ) const // (3) - { - return rfind( basic_string_view( s, n ), pos ); - } - - nssv_constexpr14 size_type rfind( CharT const * s, size_type pos = npos ) const // (4) - { - return rfind( basic_string_view( s ), pos ); - } - - // find_first_of(), 4x: - - nssv_constexpr size_type find_first_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) - { - return pos >= size() - ? npos - : to_pos( std::find_first_of( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) ); - } - - nssv_constexpr size_type find_first_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) - { - return find_first_of( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr size_type find_first_of( CharT const * s, size_type pos, size_type n ) const // (3) - { - return find_first_of( basic_string_view( s, n ), pos ); - } - - nssv_constexpr size_type find_first_of( CharT const * s, size_type pos = 0 ) const // (4) - { - return find_first_of( basic_string_view( s ), pos ); - } - - // find_last_of(), 4x: - - nssv_constexpr size_type find_last_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) - { - return empty() - ? npos - : pos >= size() - ? find_last_of( v, size() - 1 ) - : to_pos( std::find_first_of( const_reverse_iterator( cbegin() + pos + 1 ), crend(), v.cbegin(), v.cend(), Traits::eq ) ); - } - - nssv_constexpr size_type find_last_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2) - { - return find_last_of( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr size_type find_last_of( CharT const * s, size_type pos, size_type count ) const // (3) - { - return find_last_of( basic_string_view( s, count ), pos ); - } - - nssv_constexpr size_type find_last_of( CharT const * s, size_type pos = npos ) const // (4) - { - return find_last_of( basic_string_view( s ), pos ); - } - - // find_first_not_of(), 4x: - - nssv_constexpr size_type find_first_not_of( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1) - { - return pos >= size() - ? npos - : to_pos( std::find_if( cbegin() + pos, cend(), not_in_view( v ) ) ); - } - - nssv_constexpr size_type find_first_not_of( CharT c, size_type pos = 0 ) const nssv_noexcept // (2) - { - return find_first_not_of( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos, size_type count ) const // (3) - { - return find_first_not_of( basic_string_view( s, count ), pos ); - } - - nssv_constexpr size_type find_first_not_of( CharT const * s, size_type pos = 0 ) const // (4) - { - return find_first_not_of( basic_string_view( s ), pos ); - } - - // find_last_not_of(), 4x: - - nssv_constexpr size_type find_last_not_of( basic_string_view v, size_type pos = npos ) const nssv_noexcept // (1) - { - return empty() - ? npos - : pos >= size() - ? find_last_not_of( v, size() - 1 ) - : to_pos( std::find_if( const_reverse_iterator( cbegin() + pos + 1 ), crend(), not_in_view( v ) ) ); - } - - nssv_constexpr size_type find_last_not_of( CharT c, size_type pos = npos ) const nssv_noexcept // (2) - { - return find_last_not_of( basic_string_view( &c, 1 ), pos ); - } - - nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos, size_type count ) const // (3) - { - return find_last_not_of( basic_string_view( s, count ), pos ); - } - - nssv_constexpr size_type find_last_not_of( CharT const * s, size_type pos = npos ) const // (4) - { - return find_last_not_of( basic_string_view( s ), pos ); - } - - // Constants: - -#if nssv_CPP17_OR_GREATER - static nssv_constexpr size_type npos = size_type(-1); -#elif nssv_CPP11_OR_GREATER - enum : size_type { npos = size_type(-1) }; -#else - enum { npos = size_type(-1) }; -#endif - -private: - struct not_in_view - { - const basic_string_view v; - - nssv_constexpr not_in_view( basic_string_view v ) : v( v ) {} - - nssv_constexpr bool operator()( CharT c ) const - { - return npos == v.find_first_of( c ); - } - }; - - nssv_constexpr size_type to_pos( const_iterator it ) const - { - return it == cend() ? npos : size_type( it - cbegin() ); - } - - nssv_constexpr size_type to_pos( const_reverse_iterator it ) const - { - return it == crend() ? npos : size_type( crend() - it - 1 ); - } - - nssv_constexpr const_reference data_at( size_type pos ) const - { -#if nssv_BETWEEN( nssv_COMPILER_GNUC_VERSION, 1, 500 ) - return data_[pos]; -#else - return assert( pos < size() ), data_[pos]; -#endif - } - -private: - const_pointer data_; - size_type size_; - -public: -#if nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS - - template< class Allocator > - basic_string_view( std::basic_string const & s ) nssv_noexcept - : data_( s.data() ) - , size_( s.size() ) - {} - -#if nssv_HAVE_EXPLICIT_CONVERSION - - template< class Allocator > - explicit operator std::basic_string() const - { - return to_string( Allocator() ); - } - -#endif // nssv_HAVE_EXPLICIT_CONVERSION - -#if nssv_CPP11_OR_GREATER - - template< class Allocator = std::allocator > - std::basic_string - to_string( Allocator const & a = Allocator() ) const - { - return std::basic_string( begin(), end(), a ); - } - -#else - - std::basic_string - to_string() const - { - return std::basic_string( begin(), end() ); - } - - template< class Allocator > - std::basic_string - to_string( Allocator const & a ) const - { - return std::basic_string( begin(), end(), a ); - } - -#endif // nssv_CPP11_OR_GREATER - -#endif // nssv_CONFIG_CONVERSION_STD_STRING_CLASS_METHODS -}; - -// -// Non-member functions: -// - -// 24.4.3 Non-member comparison functions: -// lexicographically compare two string views (function template): - -template< class CharT, class Traits > -nssv_constexpr bool operator== ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) == 0 ; } - -template< class CharT, class Traits > -nssv_constexpr bool operator!= ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) != 0 ; } - -template< class CharT, class Traits > -nssv_constexpr bool operator< ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0 ; } - -template< class CharT, class Traits > -nssv_constexpr bool operator<= ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0 ; } - -template< class CharT, class Traits > -nssv_constexpr bool operator> ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0 ; } - -template< class CharT, class Traits > -nssv_constexpr bool operator>= ( - basic_string_view lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0 ; } - -// Let S be basic_string_view, and sv be an instance of S. -// Implementations shall provide sufficient additional overloads marked -// constexpr and noexcept so that an object t with an implicit conversion -// to S can be compared according to Table 67. - -#if nssv_CPP11_OR_GREATER && ! nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 100, 141 ) - -#define nssv_BASIC_STRING_VIEW_I(T,U) typename std::decay< basic_string_view >::type - -#if nssv_BETWEEN( nssv_COMPILER_MSVC_VERSION, 140, 150 ) -# define nssv_MSVC_ORDER(x) , int=x -#else -# define nssv_MSVC_ORDER(x) /*, int=x*/ -#endif - -// == - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator==( - basic_string_view lhs, - nssv_BASIC_STRING_VIEW_I(CharT, Traits) rhs ) nssv_noexcept -{ return lhs.compare( rhs ) == 0; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator==( - nssv_BASIC_STRING_VIEW_I(CharT, Traits) lhs, - basic_string_view rhs ) nssv_noexcept -{ return lhs.size() == rhs.size() && lhs.compare( rhs ) == 0; } - -// != - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator!= ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return lhs.size() != rhs.size() || lhs.compare( rhs ) != 0 ; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator!= ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return lhs.compare( rhs ) != 0 ; } - -// < - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator< ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0 ; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator< ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return lhs.compare( rhs ) < 0 ; } - -// <= - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator<= ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0 ; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator<= ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return lhs.compare( rhs ) <= 0 ; } - -// > - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator> ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0 ; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator> ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return lhs.compare( rhs ) > 0 ; } - -// >= - -template< class CharT, class Traits nssv_MSVC_ORDER(1) > -nssv_constexpr bool operator>= ( - basic_string_view < CharT, Traits > lhs, - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0 ; } - -template< class CharT, class Traits nssv_MSVC_ORDER(2) > -nssv_constexpr bool operator>= ( - nssv_BASIC_STRING_VIEW_I( CharT, Traits ) lhs, - basic_string_view < CharT, Traits > rhs ) nssv_noexcept -{ return lhs.compare( rhs ) >= 0 ; } - -#undef nssv_MSVC_ORDER -#undef nssv_BASIC_STRING_VIEW_I - -#endif // nssv_CPP11_OR_GREATER - -// 24.4.4 Inserters and extractors: - -namespace detail { - -template< class Stream > -void write_padding( Stream & os, std::streamsize n ) -{ - for ( std::streamsize i = 0; i < n; ++i ) - os.rdbuf()->sputc( os.fill() ); -} - -template< class Stream, class View > -Stream & write_to_stream( Stream & os, View const & sv ) -{ - typename Stream::sentry sentry( os ); - - if ( !os ) - return os; - - const std::streamsize length = static_cast( sv.length() ); - - // Whether, and how, to pad: - const bool pad = ( length < os.width() ); - const bool left_pad = pad && ( os.flags() & std::ios_base::adjustfield ) == std::ios_base::right; - - if ( left_pad ) - write_padding( os, os.width() - length ); - - // Write span characters: - os.rdbuf()->sputn( sv.begin(), length ); - - if ( pad && !left_pad ) - write_padding( os, os.width() - length ); - - // Reset output stream width: - os.width( 0 ); - - return os; -} - -} // namespace detail - -template< class CharT, class Traits > -std::basic_ostream & -operator<<( - std::basic_ostream& os, - basic_string_view sv ) -{ - return detail::write_to_stream( os, sv ); -} - -// Several typedefs for common character types are provided: - -typedef basic_string_view string_view; -typedef basic_string_view wstring_view; -#if nssv_HAVE_WCHAR16_T -typedef basic_string_view u16string_view; -typedef basic_string_view u32string_view; -#endif - -}} // namespace nonstd::sv_lite - -// -// 24.4.6 Suffix for basic_string_view literals: -// - -#if nssv_HAVE_USER_DEFINED_LITERALS - -namespace nonstd { -nssv_inline_ns namespace literals { -nssv_inline_ns namespace string_view_literals { - -#if nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS - -nssv_constexpr nonstd::sv_lite::string_view operator "" sv( const char* str, size_t len ) nssv_noexcept // (1) -{ - return nonstd::sv_lite::string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::u16string_view operator "" sv( const char16_t* str, size_t len ) nssv_noexcept // (2) -{ - return nonstd::sv_lite::u16string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::u32string_view operator "" sv( const char32_t* str, size_t len ) nssv_noexcept // (3) -{ - return nonstd::sv_lite::u32string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::wstring_view operator "" sv( const wchar_t* str, size_t len ) nssv_noexcept // (4) -{ - return nonstd::sv_lite::wstring_view{ str, len }; -} - -#endif // nssv_CONFIG_STD_SV_OPERATOR && nssv_HAVE_STD_DEFINED_LITERALS - -#if nssv_CONFIG_USR_SV_OPERATOR - -nssv_constexpr nonstd::sv_lite::string_view operator "" _sv( const char* str, size_t len ) nssv_noexcept // (1) -{ - return nonstd::sv_lite::string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::u16string_view operator "" _sv( const char16_t* str, size_t len ) nssv_noexcept // (2) -{ - return nonstd::sv_lite::u16string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::u32string_view operator "" _sv( const char32_t* str, size_t len ) nssv_noexcept // (3) -{ - return nonstd::sv_lite::u32string_view{ str, len }; -} - -nssv_constexpr nonstd::sv_lite::wstring_view operator "" _sv( const wchar_t* str, size_t len ) nssv_noexcept // (4) -{ - return nonstd::sv_lite::wstring_view{ str, len }; -} - -#endif // nssv_CONFIG_USR_SV_OPERATOR - -}}} // namespace nonstd::literals::string_view_literals - -#endif - -// -// Extensions for std::string: -// - -#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS - -namespace nonstd { -namespace sv_lite { - -// Exclude MSVC 14 (19.00): it yields ambiguous to_string(): - -#if nssv_CPP11_OR_GREATER && nssv_COMPILER_MSVC_VERSION != 140 - -template< class CharT, class Traits, class Allocator = std::allocator > -std::basic_string -to_string( basic_string_view v, Allocator const & a = Allocator() ) -{ - return std::basic_string( v.begin(), v.end(), a ); -} - -#else - -template< class CharT, class Traits > -std::basic_string -to_string( basic_string_view v ) -{ - return std::basic_string( v.begin(), v.end() ); -} - -template< class CharT, class Traits, class Allocator > -std::basic_string -to_string( basic_string_view v, Allocator const & a ) -{ - return std::basic_string( v.begin(), v.end(), a ); -} - -#endif // nssv_CPP11_OR_GREATER - -template< class CharT, class Traits, class Allocator > -basic_string_view -to_string_view( std::basic_string const & s ) -{ - return basic_string_view( s.data(), s.size() ); -} - -}} // namespace nonstd::sv_lite - -#endif // nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS - -// -// make types and algorithms available in namespace nonstd: -// - -namespace nonstd { - -using sv_lite::basic_string_view; -using sv_lite::string_view; -using sv_lite::wstring_view; - -#if nssv_HAVE_WCHAR16_T -using sv_lite::u16string_view; -#endif -#if nssv_HAVE_WCHAR32_T -using sv_lite::u32string_view; -#endif - -// literal "sv" - -using sv_lite::operator==; -using sv_lite::operator!=; -using sv_lite::operator<; -using sv_lite::operator<=; -using sv_lite::operator>; -using sv_lite::operator>=; - -using sv_lite::operator<<; - -#if nssv_CONFIG_CONVERSION_STD_STRING_FREE_FUNCTIONS -using sv_lite::to_string; -using sv_lite::to_string_view; -#endif - -} // namespace nonstd - -// 24.4.5 Hash support (C++11): - -// Note: The hash value of a string view object is equal to the hash value of -// the corresponding string object. - -#if nssv_HAVE_STD_HASH - -#include - -namespace std { - -template<> -struct hash< nonstd::string_view > -{ -public: - std::size_t operator()( nonstd::string_view v ) const nssv_noexcept - { - return std::hash()( std::string( v.data(), v.size() ) ); - } -}; - -template<> -struct hash< nonstd::wstring_view > -{ -public: - std::size_t operator()( nonstd::wstring_view v ) const nssv_noexcept - { - return std::hash()( std::wstring( v.data(), v.size() ) ); - } -}; - -template<> -struct hash< nonstd::u16string_view > -{ -public: - std::size_t operator()( nonstd::u16string_view v ) const nssv_noexcept - { - return std::hash()( std::u16string( v.data(), v.size() ) ); - } -}; - -template<> -struct hash< nonstd::u32string_view > -{ -public: - std::size_t operator()( nonstd::u32string_view v ) const nssv_noexcept - { - return std::hash()( std::u32string( v.data(), v.size() ) ); - } -}; - -} // namespace std - -#endif // nssv_HAVE_STD_HASH - -nssv_RESTORE_WARNINGS() - -#endif // nssv_HAVE_STD_STRING_VIEW -#endif // NONSTD_SV_LITE_H_INCLUDED - - - // If there is another version of Hedley, then the newer one - // takes precedence. - // See: https://github.com/nemequ/hedley -/* Hedley - https://nemequ.github.io/hedley - * Created by Evan Nemerson - * - * To the extent possible under law, the author(s) have dedicated all - * copyright and related and neighboring rights to this software to - * the public domain worldwide. This software is distributed without - * any warranty. - * - * For details, see . - * SPDX-License-Identifier: CC0-1.0 - */ - -#if !defined(HEDLEY_VERSION) || (HEDLEY_VERSION < 9) -#if defined(HEDLEY_VERSION) -# undef HEDLEY_VERSION -#endif -#define HEDLEY_VERSION 9 - -#if defined(HEDLEY_STRINGIFY_EX) -# undef HEDLEY_STRINGIFY_EX -#endif -#define HEDLEY_STRINGIFY_EX(x) #x - -#if defined(HEDLEY_STRINGIFY) -# undef HEDLEY_STRINGIFY -#endif -#define HEDLEY_STRINGIFY(x) HEDLEY_STRINGIFY_EX(x) - -#if defined(HEDLEY_CONCAT_EX) -# undef HEDLEY_CONCAT_EX -#endif -#define HEDLEY_CONCAT_EX(a,b) a##b - -#if defined(HEDLEY_CONCAT) -# undef HEDLEY_CONCAT -#endif -#define HEDLEY_CONCAT(a,b) HEDLEY_CONCAT_EX(a,b) - -#if defined(HEDLEY_VERSION_ENCODE) -# undef HEDLEY_VERSION_ENCODE -#endif -#define HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) - -#if defined(HEDLEY_VERSION_DECODE_MAJOR) -# undef HEDLEY_VERSION_DECODE_MAJOR -#endif -#define HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) - -#if defined(HEDLEY_VERSION_DECODE_MINOR) -# undef HEDLEY_VERSION_DECODE_MINOR -#endif -#define HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) - -#if defined(HEDLEY_VERSION_DECODE_REVISION) -# undef HEDLEY_VERSION_DECODE_REVISION -#endif -#define HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) - -#if defined(HEDLEY_GNUC_VERSION) -# undef HEDLEY_GNUC_VERSION -#endif -#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) -# define HEDLEY_GNUC_VERSION HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#elif defined(__GNUC__) -# define HEDLEY_GNUC_VERSION HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) -#endif - -#if defined(HEDLEY_GNUC_VERSION_CHECK) -# undef HEDLEY_GNUC_VERSION_CHECK -#endif -#if defined(HEDLEY_GNUC_VERSION) -# define HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (HEDLEY_GNUC_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_MSVC_VERSION) -# undef HEDLEY_MSVC_VERSION -#endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) -# define HEDLEY_MSVC_VERSION HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) -# define HEDLEY_MSVC_VERSION HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) -# define HEDLEY_MSVC_VERSION HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) -#endif - -#if defined(HEDLEY_MSVC_VERSION_CHECK) -# undef HEDLEY_MSVC_VERSION_CHECK -#endif -#if !defined(_MSC_VER) -# define HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) -# define HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) -# define HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) -#else -# define HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) -#endif - -#if defined(HEDLEY_INTEL_VERSION) -# undef HEDLEY_INTEL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) -# define HEDLEY_INTEL_VERSION HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) -# define HEDLEY_INTEL_VERSION HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) -#endif - -#if defined(HEDLEY_INTEL_VERSION_CHECK) -# undef HEDLEY_INTEL_VERSION_CHECK -#endif -#if defined(HEDLEY_INTEL_VERSION) -# define HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (HEDLEY_INTEL_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_PGI_VERSION) -# undef HEDLEY_PGI_VERSION -#endif -#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) -# define HEDLEY_PGI_VERSION HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) -#endif - -#if defined(HEDLEY_PGI_VERSION_CHECK) -# undef HEDLEY_PGI_VERSION_CHECK -#endif -#if defined(HEDLEY_PGI_VERSION) -# define HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (HEDLEY_PGI_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_SUNPRO_VERSION) -# undef HEDLEY_SUNPRO_VERSION -#endif -#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) -# define HEDLEY_SUNPRO_VERSION HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) -#elif defined(__SUNPRO_C) -# define HEDLEY_SUNPRO_VERSION HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) -#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) -# define HEDLEY_SUNPRO_VERSION HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) -#elif defined(__SUNPRO_CC) -# define HEDLEY_SUNPRO_VERSION HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) -#endif - -#if defined(HEDLEY_SUNPRO_VERSION_CHECK) -# undef HEDLEY_SUNPRO_VERSION_CHECK -#endif -#if defined(HEDLEY_SUNPRO_VERSION) -# define HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (HEDLEY_SUNPRO_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_EMSCRIPTEN_VERSION) -# undef HEDLEY_EMSCRIPTEN_VERSION -#endif -#if defined(__EMSCRIPTEN__) -# define HEDLEY_EMSCRIPTEN_VERSION HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) -#endif - -#if defined(HEDLEY_EMSCRIPTEN_VERSION_CHECK) -# undef HEDLEY_EMSCRIPTEN_VERSION_CHECK -#endif -#if defined(HEDLEY_EMSCRIPTEN_VERSION) -# define HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (HEDLEY_EMSCRIPTEN_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_ARM_VERSION) -# undef HEDLEY_ARM_VERSION -#endif -#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) -# define HEDLEY_ARM_VERSION HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) -#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) -# define HEDLEY_ARM_VERSION HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) -#endif - -#if defined(HEDLEY_ARM_VERSION_CHECK) -# undef HEDLEY_ARM_VERSION_CHECK -#endif -#if defined(HEDLEY_ARM_VERSION) -# define HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (HEDLEY_ARM_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_IBM_VERSION) -# undef HEDLEY_IBM_VERSION -#endif -#if defined(__ibmxl__) -# define HEDLEY_IBM_VERSION HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) -#elif defined(__xlC__) && defined(__xlC_ver__) -# define HEDLEY_IBM_VERSION HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) -#elif defined(__xlC__) -# define HEDLEY_IBM_VERSION HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) -#endif - -#if defined(HEDLEY_IBM_VERSION_CHECK) -# undef HEDLEY_IBM_VERSION_CHECK -#endif -#if defined(HEDLEY_IBM_VERSION) -# define HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (HEDLEY_IBM_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_TI_VERSION) -# undef HEDLEY_TI_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) -# define HEDLEY_TI_VERSION HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(HEDLEY_TI_VERSION_CHECK) -# undef HEDLEY_TI_VERSION_CHECK -#endif -#if defined(HEDLEY_TI_VERSION) -# define HEDLEY_TI_VERSION_CHECK(major,minor,patch) (HEDLEY_TI_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_CRAY_VERSION) -# undef HEDLEY_CRAY_VERSION -#endif -#if defined(_CRAYC) -# if defined(_RELEASE_PATCHLEVEL) -# define HEDLEY_CRAY_VERSION HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) -# else -# define HEDLEY_CRAY_VERSION HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) -# endif -#endif - -#if defined(HEDLEY_CRAY_VERSION_CHECK) -# undef HEDLEY_CRAY_VERSION_CHECK -#endif -#if defined(HEDLEY_CRAY_VERSION) -# define HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (HEDLEY_CRAY_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_IAR_VERSION) -# undef HEDLEY_IAR_VERSION -#endif -#if defined(__IAR_SYSTEMS_ICC__) -# if __VER__ > 1000 -# define HEDLEY_IAR_VERSION HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) -# else -# define HEDLEY_IAR_VERSION HEDLEY_VERSION_ENCODE(VER / 100, __VER__ % 100, 0) -# endif -#endif - -#if defined(HEDLEY_IAR_VERSION_CHECK) -# undef HEDLEY_IAR_VERSION_CHECK -#endif -#if defined(HEDLEY_IAR_VERSION) -# define HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (HEDLEY_IAR_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_TINYC_VERSION) -# undef HEDLEY_TINYC_VERSION -#endif -#if defined(__TINYC__) -# define HEDLEY_TINYC_VERSION HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) -#endif - -#if defined(HEDLEY_TINYC_VERSION_CHECK) -# undef HEDLEY_TINYC_VERSION_CHECK -#endif -#if defined(HEDLEY_TINYC_VERSION) -# define HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (HEDLEY_TINYC_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_DMC_VERSION) -# undef HEDLEY_DMC_VERSION -#endif -#if defined(__DMC__) -# define HEDLEY_DMC_VERSION HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) -#endif - -#if defined(HEDLEY_DMC_VERSION_CHECK) -# undef HEDLEY_DMC_VERSION_CHECK -#endif -#if defined(HEDLEY_DMC_VERSION) -# define HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (HEDLEY_DMC_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_COMPCERT_VERSION) -# undef HEDLEY_COMPCERT_VERSION -#endif -#if defined(__COMPCERT_VERSION__) -# define HEDLEY_COMPCERT_VERSION HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) -#endif - -#if defined(HEDLEY_COMPCERT_VERSION_CHECK) -# undef HEDLEY_COMPCERT_VERSION_CHECK -#endif -#if defined(HEDLEY_COMPCERT_VERSION) -# define HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (HEDLEY_COMPCERT_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_PELLES_VERSION) -# undef HEDLEY_PELLES_VERSION -#endif -#if defined(__POCC__) -# define HEDLEY_PELLES_VERSION HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) -#endif - -#if defined(HEDLEY_PELLES_VERSION_CHECK) -# undef HEDLEY_PELLES_VERSION_CHECK -#endif -#if defined(HEDLEY_PELLES_VERSION) -# define HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (HEDLEY_PELLES_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_GCC_VERSION) -# undef HEDLEY_GCC_VERSION -#endif -#if \ - defined(HEDLEY_GNUC_VERSION) && \ - !defined(__clang__) && \ - !defined(HEDLEY_INTEL_VERSION) && \ - !defined(HEDLEY_PGI_VERSION) && \ - !defined(HEDLEY_ARM_VERSION) && \ - !defined(HEDLEY_TI_VERSION) && \ - !defined(__COMPCERT__) -# define HEDLEY_GCC_VERSION HEDLEY_GNUC_VERSION -#endif - -#if defined(HEDLEY_GCC_VERSION_CHECK) -# undef HEDLEY_GCC_VERSION_CHECK -#endif -#if defined(HEDLEY_GCC_VERSION) -# define HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (HEDLEY_GCC_VERSION >= HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -# define HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(HEDLEY_HAS_ATTRIBUTE) -# undef HEDLEY_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) -# define HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) -#else -# define HEDLEY_HAS_ATTRIBUTE(attribute) (0) -#endif - -#if defined(HEDLEY_GNUC_HAS_ATTRIBUTE) -# undef HEDLEY_GNUC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) -# define HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute) -#else -# define HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_GCC_HAS_ATTRIBUTE) -# undef HEDLEY_GCC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) -# define HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) __has_attribute(attribute) -#else -# define HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_HAS_CPP_ATTRIBUTE) -# undef HEDLEY_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) -# define HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) -#else -# define HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) -#endif - -#if defined(HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) -# undef HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) -# define HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else -# define HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_GCC_HAS_CPP_ATTRIBUTE) -# undef HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) -# define HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else -# define HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_HAS_BUILTIN) -# undef HEDLEY_HAS_BUILTIN -#endif -#if defined(__has_builtin) -# define HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) -#else -# define HEDLEY_HAS_BUILTIN(builtin) (0) -#endif - -#if defined(HEDLEY_GNUC_HAS_BUILTIN) -# undef HEDLEY_GNUC_HAS_BUILTIN -#endif -#if defined(__has_builtin) -# define HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else -# define HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_GCC_HAS_BUILTIN) -# undef HEDLEY_GCC_HAS_BUILTIN -#endif -#if defined(__has_builtin) -# define HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else -# define HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_HAS_FEATURE) -# undef HEDLEY_HAS_FEATURE -#endif -#if defined(__has_feature) -# define HEDLEY_HAS_FEATURE(feature) __has_feature(feature) -#else -# define HEDLEY_HAS_FEATURE(feature) (0) -#endif - -#if defined(HEDLEY_GNUC_HAS_FEATURE) -# undef HEDLEY_GNUC_HAS_FEATURE -#endif -#if defined(__has_feature) -# define HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else -# define HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_GCC_HAS_FEATURE) -# undef HEDLEY_GCC_HAS_FEATURE -#endif -#if defined(__has_feature) -# define HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else -# define HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_HAS_EXTENSION) -# undef HEDLEY_HAS_EXTENSION -#endif -#if defined(__has_extension) -# define HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) -#else -# define HEDLEY_HAS_EXTENSION(extension) (0) -#endif - -#if defined(HEDLEY_GNUC_HAS_EXTENSION) -# undef HEDLEY_GNUC_HAS_EXTENSION -#endif -#if defined(__has_extension) -# define HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else -# define HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_GCC_HAS_EXTENSION) -# undef HEDLEY_GCC_HAS_EXTENSION -#endif -#if defined(__has_extension) -# define HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else -# define HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_HAS_DECLSPEC_ATTRIBUTE) -# undef HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) -# define HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) -#else -# define HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) -#endif - -#if defined(HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) -# undef HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) -# define HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else -# define HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) -# undef HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) -# define HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else -# define HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_HAS_WARNING) -# undef HEDLEY_HAS_WARNING -#endif -#if defined(__has_warning) -# define HEDLEY_HAS_WARNING(warning) __has_warning(warning) -#else -# define HEDLEY_HAS_WARNING(warning) (0) -#endif - -#if defined(HEDLEY_GNUC_HAS_WARNING) -# undef HEDLEY_GNUC_HAS_WARNING -#endif -#if defined(__has_warning) -# define HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else -# define HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_GCC_HAS_WARNING) -# undef HEDLEY_GCC_HAS_WARNING -#endif -#if defined(__has_warning) -# define HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else -# define HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(__clang__) || \ - HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_TI_VERSION_CHECK(6,0,0) || \ - HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ - HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ - HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ - (HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) -# define HEDLEY_PRAGMA(value) _Pragma(#value) -#elif HEDLEY_MSVC_VERSION_CHECK(15,0,0) -# define HEDLEY_PRAGMA(value) __pragma(value) -#else -# define HEDLEY_PRAGMA(value) -#endif - -#if defined(HEDLEY_DIAGNOSTIC_PUSH) -# undef HEDLEY_DIAGNOSTIC_PUSH -#endif -#if defined(HEDLEY_DIAGNOSTIC_POP) -# undef HEDLEY_DIAGNOSTIC_POP -#endif -#if defined(__clang__) -# define HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") -# define HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -#elif HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") -# define HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#elif HEDLEY_GCC_VERSION_CHECK(4,6,0) -# define HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") -# define HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif HEDLEY_MSVC_VERSION_CHECK(15,0,0) -# define HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) -# define HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) -#elif HEDLEY_ARM_VERSION_CHECK(5,6,0) -# define HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") -# define HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif HEDLEY_TI_VERSION_CHECK(8,1,0) -# define HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") -# define HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") -#elif HEDLEY_PELLES_VERSION_CHECK(2,90,0) -# define HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") -# define HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#else -# define HEDLEY_DIAGNOSTIC_PUSH -# define HEDLEY_DIAGNOSTIC_POP -#endif - -#if defined(HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) -# undef HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif -#if HEDLEY_HAS_WARNING("-Wdeprecated-declarations") -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#elif HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") -#elif HEDLEY_PGI_VERSION_CHECK(17,10,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif HEDLEY_GCC_VERSION_CHECK(4,3,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif HEDLEY_MSVC_VERSION_CHECK(15,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif HEDLEY_TI_VERSION_CHECK(8,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") -#elif HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") -#elif HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") -#elif HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") -#elif HEDLEY_PELLES_VERSION_CHECK(2,90,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") -#else -# define HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif - -#if defined(HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) -# undef HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif -#if HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") -#elif HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") -#elif HEDLEY_PGI_VERSION_CHECK(17,10,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") -#elif HEDLEY_GCC_VERSION_CHECK(4,3,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") -#elif HEDLEY_MSVC_VERSION_CHECK(15,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif HEDLEY_TI_VERSION_CHECK(8,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") -#else -# define HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif - -#if defined(HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) -# undef HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif -#if HEDLEY_HAS_WARNING("-Wcast-qual") -# define HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") -#elif HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") -#elif HEDLEY_GCC_VERSION_CHECK(3,0,0) -# define HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") -#else -# define HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif - -#if defined(HEDLEY_DEPRECATED) -# undef HEDLEY_DEPRECATED -#endif -#if defined(HEDLEY_DEPRECATED_FOR) -# undef HEDLEY_DEPRECATED_FOR -#endif -#if defined(__cplusplus) && (__cplusplus >= 201402L) -# define HEDLEY_DEPRECATED(since) [[deprecated("Since " #since)]] -# define HEDLEY_DEPRECATED_FOR(since, replacement) [[deprecated("Since " #since "; use " #replacement)]] -#elif \ - HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) || \ - HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ - HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - HEDLEY_TI_VERSION_CHECK(8,3,0) -# define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) -# define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) -#elif \ - HEDLEY_HAS_ATTRIBUTE(deprecated) || \ - HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) -# define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) -# define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif HEDLEY_MSVC_VERSION_CHECK(14,0,0) -# define HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) -# define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) -#elif \ - HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - HEDLEY_PELLES_VERSION_CHECK(6,50,0) -# define HEDLEY_DEPRECATED(since) _declspec(deprecated) -# define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) -#elif HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define HEDLEY_DEPRECATED(since) _Pragma("deprecated") -# define HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") -#else -# define HEDLEY_DEPRECATED(since) -# define HEDLEY_DEPRECATED_FOR(since, replacement) -#endif - -#if defined(HEDLEY_UNAVAILABLE) -# undef HEDLEY_UNAVAILABLE -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(warning) || \ - HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) -#else -# define HEDLEY_UNAVAILABLE(available_since) -#endif - -#if defined(HEDLEY_WARN_UNUSED_RESULT) -# undef HEDLEY_WARN_UNUSED_RESULT -#endif -#if defined(__cplusplus) && (__cplusplus >= 201703L) -# define HEDLEY_WARN_UNUSED_RESULT [[nodiscard]] -#elif \ - HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ - HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - (HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - HEDLEY_PGI_VERSION_CHECK(17,10,0) -# define HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) -#elif defined(_Check_return_) /* SAL */ -# define HEDLEY_WARN_UNUSED_RESULT _Check_return_ -#else -# define HEDLEY_WARN_UNUSED_RESULT -#endif - -#if defined(HEDLEY_SENTINEL) -# undef HEDLEY_SENTINEL -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(sentinel) || \ - HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_ARM_VERSION_CHECK(5,4,0) -# define HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) -#else -# define HEDLEY_SENTINEL(position) -#endif - -#if defined(HEDLEY_NO_RETURN) -# undef HEDLEY_NO_RETURN -#endif -#if HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define HEDLEY_NO_RETURN __noreturn -#elif HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -# define HEDLEY_NO_RETURN _Noreturn -#elif defined(__cplusplus) && (__cplusplus >= 201103L) -# define HEDLEY_NO_RETURN [[noreturn]] -#elif \ - HEDLEY_HAS_ATTRIBUTE(noreturn) || \ - HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ - HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - HEDLEY_TI_VERSION_CHECK(18,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(17,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) -# define HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0) -# define HEDLEY_NO_RETURN __declspec(noreturn) -#elif HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) -# define HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") -#elif HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) -# define HEDLEY_NO_RETURN __attribute((noreturn)) -#elif HEDLEY_PELLES_VERSION_CHECK(9,0,0) -# define HEDLEY_NO_RETURN __declspec(noreturn) -#else -# define HEDLEY_NO_RETURN -#endif - -#if defined(HEDLEY_UNREACHABLE) -# undef HEDLEY_UNREACHABLE -#endif -#if defined(HEDLEY_UNREACHABLE_RETURN) -# undef HEDLEY_UNREACHABLE_RETURN -#endif -#if \ - (HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(HEDLEY_ARM_VERSION))) || \ - HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_IBM_VERSION_CHECK(13,1,5) -# define HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0) -# define HEDLEY_UNREACHABLE() __assume(0) -#elif HEDLEY_TI_VERSION_CHECK(6,0,0) -# if defined(__cplusplus) -# define HEDLEY_UNREACHABLE() std::_nassert(0) -# else -# define HEDLEY_UNREACHABLE() _nassert(0) -# endif -# define HEDLEY_UNREACHABLE_RETURN(value) return value -#elif defined(EXIT_FAILURE) -# define HEDLEY_UNREACHABLE() abort() -#else -# define HEDLEY_UNREACHABLE() -# define HEDLEY_UNREACHABLE_RETURN(value) return value -#endif -#if !defined(HEDLEY_UNREACHABLE_RETURN) -# define HEDLEY_UNREACHABLE_RETURN(value) HEDLEY_UNREACHABLE() -#endif - -#if defined(HEDLEY_ASSUME) -# undef HEDLEY_ASSUME -#endif -#if \ - HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_ASSUME(expr) __assume(expr) -#elif HEDLEY_HAS_BUILTIN(__builtin_assume) -# define HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif HEDLEY_TI_VERSION_CHECK(6,0,0) -# if defined(__cplusplus) -# define HEDLEY_ASSUME(expr) std::_nassert(expr) -# else -# define HEDLEY_ASSUME(expr) _nassert(expr) -# endif -#elif \ - (HEDLEY_HAS_BUILTIN(__builtin_unreachable) && !defined(HEDLEY_ARM_VERSION)) || \ - HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_IBM_VERSION_CHECK(13,1,5) -# define HEDLEY_ASSUME(expr) ((void) ((expr) ? 1 : (__builtin_unreachable(), 1))) -#else -# define HEDLEY_ASSUME(expr) ((void) (expr)) -#endif - - -HEDLEY_DIAGNOSTIC_PUSH -#if \ - HEDLEY_HAS_WARNING("-Wvariadic-macros") || \ - HEDLEY_GCC_VERSION_CHECK(4,0,0) -# if defined(__clang__) -# pragma clang diagnostic ignored "-Wvariadic-macros" -# elif defined(HEDLEY_GCC_VERSION) -# pragma GCC diagnostic ignored "-Wvariadic-macros" -# endif -#endif -#if defined(HEDLEY_NON_NULL) -# undef HEDLEY_NON_NULL -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(nonnull) || \ - HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) -# define HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else -# define HEDLEY_NON_NULL(...) -#endif -HEDLEY_DIAGNOSTIC_POP - -#if defined(HEDLEY_PRINTF_FORMAT) -# undef HEDLEY_PRINTF_FORMAT -#endif -#if defined(__MINGW32__) && HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) -# define HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) -#elif defined(__MINGW32__) && HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) -# define HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) -#elif \ - HEDLEY_HAS_ATTRIBUTE(format) || \ - HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) -# define HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) -#elif HEDLEY_PELLES_VERSION_CHECK(6,0,0) -# define HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) -#else -# define HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) -#endif - -#if defined(HEDLEY_CONSTEXPR) -# undef HEDLEY_CONSTEXPR -#endif -#if defined(__cplusplus) -# if __cplusplus >= 201103L -# define HEDLEY_CONSTEXPR constexpr -# endif -#endif -#if !defined(HEDLEY_CONSTEXPR) -# define HEDLEY_CONSTEXPR -#endif - -#if defined(HEDLEY_PREDICT) -# undef HEDLEY_PREDICT -#endif -#if defined(HEDLEY_LIKELY) -# undef HEDLEY_LIKELY -#endif -#if defined(HEDLEY_UNLIKELY) -# undef HEDLEY_UNLIKELY -#endif -#if defined(HEDLEY_UNPREDICTABLE) -# undef HEDLEY_UNPREDICTABLE -#endif -#if HEDLEY_HAS_BUILTIN(__builtin_unpredictable) -# define HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable(!!(expr)) -#endif -#if \ - HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) || \ - HEDLEY_GCC_VERSION_CHECK(9,0,0) -# define HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability(expr, value, probability) -# define HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1, probability) -# define HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0, probability) -# define HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -# if !defined(HEDLEY_BUILTIN_UNPREDICTABLE) -# define HEDLEY_BUILTIN_UNPREDICTABLE(expr) __builtin_expect_with_probability(!!(expr), 1, 0.5) -# endif -#elif \ - HEDLEY_HAS_BUILTIN(__builtin_expect) || \ - HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - (HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - HEDLEY_TI_VERSION_CHECK(6,1,0) || \ - HEDLEY_TINYC_VERSION_CHECK(0,9,27) -# define HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect(!!(expr), (expected)) : (((void) (expected)), !!(expr))) -# define HEDLEY_PREDICT_TRUE(expr, probability) \ - (__extension__ ({ \ - HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ - })) -# define HEDLEY_PREDICT_FALSE(expr, probability) \ - (__extension__ ({ \ - HEDLEY_CONSTEXPR double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ - })) -# define HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define HEDLEY_PREDICT(expr, expected, probability) (((void) (expected)), !!(expr)) -# define HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) -# define HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) -# define HEDLEY_LIKELY(expr) (!!(expr)) -# define HEDLEY_UNLIKELY(expr) (!!(expr)) -#endif -#if !defined(HEDLEY_UNPREDICTABLE) -# define HEDLEY_UNPREDICTABLE(expr) HEDLEY_PREDICT(expr, 1, 0.5) -#endif - -#if defined(HEDLEY_MALLOC) -# undef HEDLEY_MALLOC -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(malloc) || \ - HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) -# define HEDLEY_MALLOC __attribute__((__malloc__)) -#elif HEDLEY_MSVC_VERSION_CHECK(14, 0, 0) -# define HEDLEY_MALLOC __declspec(restrict) -#else -# define HEDLEY_MALLOC -#endif - -#if defined(HEDLEY_PURE) -# undef HEDLEY_PURE -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(pure) || \ - HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - HEDLEY_PGI_VERSION_CHECK(17,10,0) -# define HEDLEY_PURE __attribute__((__pure__)) -#elif HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) -# define HEDLEY_PURE _Pragma("FUNC_IS_PURE;") -#else -# define HEDLEY_PURE -#endif - -#if defined(HEDLEY_CONST) -# undef HEDLEY_CONST -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(const) || \ - HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - HEDLEY_PGI_VERSION_CHECK(17,10,0) -# define HEDLEY_CONST __attribute__((__const__)) -#else -# define HEDLEY_CONST HEDLEY_PURE -#endif - -#if defined(HEDLEY_RESTRICT) -# undef HEDLEY_RESTRICT -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) -# define HEDLEY_RESTRICT restrict -#elif \ - HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ - HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) -# define HEDLEY_RESTRICT __restrict -#elif HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) -# define HEDLEY_RESTRICT _Restrict -#else -# define HEDLEY_RESTRICT -#endif - -#if defined(HEDLEY_INLINE) -# undef HEDLEY_INLINE -#endif -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 199711L)) -# define HEDLEY_INLINE inline -#elif \ - defined(HEDLEY_GCC_VERSION) || \ - HEDLEY_ARM_VERSION_CHECK(6,2,0) -# define HEDLEY_INLINE __inline__ -#elif \ - HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) -# define HEDLEY_INLINE __inline -#else -# define HEDLEY_INLINE -#endif - -#if defined(HEDLEY_ALWAYS_INLINE) -# undef HEDLEY_ALWAYS_INLINE -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) -# define HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) HEDLEY_INLINE -#elif HEDLEY_MSVC_VERSION_CHECK(12,0,0) -# define HEDLEY_ALWAYS_INLINE __forceinline -#elif HEDLEY_TI_VERSION_CHECK(7,0,0) && defined(__cplusplus) -# define HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") -#elif HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") -#else -# define HEDLEY_ALWAYS_INLINE HEDLEY_INLINE -#endif - -#if defined(HEDLEY_NEVER_INLINE) -# undef HEDLEY_NEVER_INLINE -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(noinline) || \ - HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) -# define HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0) -# define HEDLEY_NEVER_INLINE __declspec(noinline) -#elif HEDLEY_PGI_VERSION_CHECK(10,2,0) -# define HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus) -# define HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") -#elif HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define HEDLEY_NEVER_INLINE _Pragma("inline=never") -#elif HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) -# define HEDLEY_NEVER_INLINE __attribute((noinline)) -#elif HEDLEY_PELLES_VERSION_CHECK(9,0,0) -# define HEDLEY_NEVER_INLINE __declspec(noinline) -#else -# define HEDLEY_NEVER_INLINE -#endif - -#if defined(HEDLEY_PRIVATE) -# undef HEDLEY_PRIVATE -#endif -#if defined(HEDLEY_PUBLIC) -# undef HEDLEY_PUBLIC -#endif -#if defined(HEDLEY_IMPORT) -# undef HEDLEY_IMPORT -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define HEDLEY_PRIVATE -# define HEDLEY_PUBLIC __declspec(dllexport) -# define HEDLEY_IMPORT __declspec(dllimport) -#else -# if \ - HEDLEY_HAS_ATTRIBUTE(visibility) || \ - HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - HEDLEY_TI_VERSION_CHECK(8,0,0) || \ - (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_EABI__) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) -# define HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) -# define HEDLEY_PUBLIC __attribute__((__visibility__("default"))) -# else -# define HEDLEY_PRIVATE -# define HEDLEY_PUBLIC -# endif -# define HEDLEY_IMPORT extern -#endif - -#if defined(HEDLEY_NO_THROW) -# undef HEDLEY_NO_THROW -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(nothrow) || \ - HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_NO_THROW __attribute__((__nothrow__)) -#elif \ - HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) -# define HEDLEY_NO_THROW __declspec(nothrow) -#else -# define HEDLEY_NO_THROW -#endif - -#if defined(HEDLEY_FALL_THROUGH) -# undef HEDLEY_FALL_THROUGH -#endif -#if \ - defined(__cplusplus) && \ - (!defined(HEDLEY_SUNPRO_VERSION) || HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ - !defined(HEDLEY_PGI_VERSION) -# if \ - (__cplusplus >= 201703L) || \ - ((__cplusplus >= 201103L) && HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough)) -# define HEDLEY_FALL_THROUGH [[fallthrough]] -# elif (__cplusplus >= 201103L) && HEDLEY_HAS_CPP_ATTRIBUTE(clang::fallthrough) -# define HEDLEY_FALL_THROUGH [[clang::fallthrough]] -# elif (__cplusplus >= 201103L) && HEDLEY_GCC_VERSION_CHECK(7,0,0) -# define HEDLEY_FALL_THROUGH [[gnu::fallthrough]] -# endif -#endif -#if !defined(HEDLEY_FALL_THROUGH) -# if HEDLEY_GNUC_HAS_ATTRIBUTE(fallthrough,7,0,0) && !defined(HEDLEY_PGI_VERSION) -# define HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) -# elif defined(__fallthrough) /* SAL */ -# define HEDLEY_FALL_THROUGH __fallthrough -# else -# define HEDLEY_FALL_THROUGH -# endif -#endif - -#if defined(HEDLEY_RETURNS_NON_NULL) -# undef HEDLEY_RETURNS_NON_NULL -#endif -#if \ - HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - HEDLEY_GCC_VERSION_CHECK(4,9,0) -# define HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) -#elif defined(_Ret_notnull_) /* SAL */ -# define HEDLEY_RETURNS_NON_NULL _Ret_notnull_ -#else -# define HEDLEY_RETURNS_NON_NULL -#endif - -#if defined(HEDLEY_ARRAY_PARAM) -# undef HEDLEY_ARRAY_PARAM -#endif -#if \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__STDC_NO_VLA__) && \ - !defined(__cplusplus) && \ - !defined(HEDLEY_PGI_VERSION) && \ - !defined(HEDLEY_TINYC_VERSION) -# define HEDLEY_ARRAY_PARAM(name) (name) -#else -# define HEDLEY_ARRAY_PARAM(name) -#endif - -#if defined(HEDLEY_IS_CONSTANT) -# undef HEDLEY_IS_CONSTANT -#endif -#if defined(HEDLEY_REQUIRE_CONSTEXPR) -# undef HEDLEY_REQUIRE_CONSTEXPR -#endif -/* Note the double-underscore. For internal use only; no API - * guarantees! */ -#if defined(HEDLEY__IS_CONSTEXPR) -# undef HEDLEY__IS_CONSTEXPR -#endif - -#if \ - HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ - HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ - HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - HEDLEY_TI_VERSION_CHECK(6,1,0) || \ - HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) || \ - HEDLEY_CRAY_VERSION_CHECK(8,1,0) -# define HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) -#endif -#if !defined(__cplusplus) -# if \ - HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ - HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - HEDLEY_TINYC_VERSION_CHECK(0,9,24) -# if defined(__INTPTR_TYPE__) -# define HEDLEY__IS_CONSTEXPR(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) -# else -# include -# define HEDLEY__IS_CONSTEXPR(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) -# endif -# elif \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && !defined(HEDLEY_SUNPRO_VERSION) && !defined(HEDLEY_PGI_VERSION)) || \ - HEDLEY_HAS_EXTENSION(c_generic_selections) || \ - HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ - HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - HEDLEY_ARM_VERSION_CHECK(5,3,0) -# if defined(__INTPTR_TYPE__) -# define HEDLEY__IS_CONSTEXPR(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) -# else -# include -# define HEDLEY__IS_CONSTEXPR(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) -# endif -# elif \ - defined(HEDLEY_GCC_VERSION) || \ - defined(HEDLEY_INTEL_VERSION) || \ - defined(HEDLEY_TINYC_VERSION) || \ - defined(HEDLEY_TI_VERSION) || \ - defined(__clang__) -# define HEDLEY__IS_CONSTEXPR(expr) ( \ - sizeof(void) != \ - sizeof(*( \ - 1 ? \ - ((void*) ((expr) * 0L) ) : \ - ((struct { char v[sizeof(void) * 2]; } *) 1) \ - ) \ - ) \ - ) -# endif -#endif -#if defined(HEDLEY__IS_CONSTEXPR) -# if !defined(HEDLEY_IS_CONSTANT) -# define HEDLEY_IS_CONSTANT(expr) HEDLEY__IS_CONSTEXPR(expr) -# endif -# define HEDLEY_REQUIRE_CONSTEXPR(expr) (HEDLEY__IS_CONSTEXPR(expr) ? (expr) : (-1)) -#else -# if !defined(HEDLEY_IS_CONSTANT) -# define HEDLEY_IS_CONSTANT(expr) (0) -# endif -# define HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) -#endif - -#if defined(HEDLEY_BEGIN_C_DECLS) -# undef HEDLEY_BEGIN_C_DECLS -#endif -#if defined(HEDLEY_END_C_DECLS) -# undef HEDLEY_END_C_DECLS -#endif -#if defined(HEDLEY_C_DECL) -# undef HEDLEY_C_DECL -#endif -#if defined(__cplusplus) -# define HEDLEY_BEGIN_C_DECLS extern "C" { -# define HEDLEY_END_C_DECLS } -# define HEDLEY_C_DECL extern "C" -#else -# define HEDLEY_BEGIN_C_DECLS -# define HEDLEY_END_C_DECLS -# define HEDLEY_C_DECL -#endif - -#if defined(HEDLEY_STATIC_ASSERT) -# undef HEDLEY_STATIC_ASSERT -#endif -#if \ - !defined(__cplusplus) && ( \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - HEDLEY_HAS_FEATURE(c_static_assert) || \ - HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - defined(_Static_assert) \ - ) -# define HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) -#elif \ - (defined(__cplusplus) && (__cplusplus >= 201703L)) || \ - HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ - (defined(__cplusplus) && HEDLEY_TI_VERSION_CHECK(8,3,0)) -# define HEDLEY_STATIC_ASSERT(expr, message) static_assert(expr, message) -#elif defined(__cplusplus) && (__cplusplus >= 201103L) -# define HEDLEY_STATIC_ASSERT(expr, message) static_assert(expr) -#else -# define HEDLEY_STATIC_ASSERT(expr, message) -#endif - -#if defined(HEDLEY_CONST_CAST) -# undef HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) -#elif \ - HEDLEY_HAS_WARNING("-Wcast-qual") || \ - HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - HEDLEY_DIAGNOSTIC_PUSH \ - HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(HEDLEY_REINTERPRET_CAST) -# undef HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) -# define HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) -#else -# define HEDLEY_REINTERPRET_CAST(T, expr) (*((T*) &(expr))) -#endif - -#if defined(HEDLEY_STATIC_CAST) -# undef HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) -# define HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) -#else -# define HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(HEDLEY_CPP_CAST) -# undef HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) -# define HEDLEY_CPP_CAST(T, expr) static_cast(expr) -#else -# define HEDLEY_CPP_CAST(T, expr) (expr) -#endif - -#if defined(HEDLEY_MESSAGE) -# undef HEDLEY_MESSAGE -#endif -#if HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define HEDLEY_MESSAGE(msg) \ - HEDLEY_DIAGNOSTIC_PUSH \ - HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - HEDLEY_PRAGMA(message msg) \ - HEDLEY_DIAGNOSTIC_POP -#elif \ - HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ - HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(message msg) -#elif HEDLEY_CRAY_VERSION_CHECK(5,0,0) -# define HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(_CRI message msg) -#elif HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(message(msg)) -#elif HEDLEY_PELLES_VERSION_CHECK(2,0,0) -# define HEDLEY_MESSAGE(msg) HEDLEY_PRAGMA(message(msg)) -#else -# define HEDLEY_MESSAGE(msg) -#endif - -#if defined(HEDLEY_WARNING) -# undef HEDLEY_WARNING -#endif -#if HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define HEDLEY_WARNING(msg) \ - HEDLEY_DIAGNOSTIC_PUSH \ - HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - HEDLEY_PRAGMA(clang warning msg) \ - HEDLEY_DIAGNOSTIC_POP -#elif \ - HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - HEDLEY_PGI_VERSION_CHECK(18,4,0) -# define HEDLEY_WARNING(msg) HEDLEY_PRAGMA(GCC warning msg) -#elif HEDLEY_MSVC_VERSION_CHECK(15,0,0) -# define HEDLEY_WARNING(msg) HEDLEY_PRAGMA(message(msg)) -#else -# define HEDLEY_WARNING(msg) HEDLEY_MESSAGE(msg) -#endif - -#if defined(HEDLEY_REQUIRE_MSG) -# undef HEDLEY_REQUIRE_MSG -#endif -#if HEDLEY_HAS_ATTRIBUTE(diagnose_if) -# if HEDLEY_HAS_WARNING("-Wgcc-compat") -# define HEDLEY_REQUIRE_MSG(expr, msg) \ - HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((__diagnose_if__(!(expr), msg, "error"))) \ - HEDLEY_DIAGNOSTIC_POP -# else -# define HEDLEY_REQUIRE_MSG(expr, msg) __attribute__((__diagnose_if__(!(expr), msg, "error"))) -# endif -#else -# define HEDLEY_REQUIRE_MSG(expr, msg) -#endif - -#if defined(HEDLEY_REQUIRE) -# undef HEDLEY_REQUIRE -#endif -#define HEDLEY_REQUIRE(expr) HEDLEY_REQUIRE_MSG(expr, #expr) - -#if defined(HEDLEY_FLAGS) -# undef HEDLEY_FLAGS -#endif -#if HEDLEY_HAS_ATTRIBUTE(flag_enum) -# define HEDLEY_FLAGS __attribute__((__flag_enum__)) -#endif - -#if defined(HEDLEY_FLAGS_CAST) -# undef HEDLEY_FLAGS_CAST -#endif -#if HEDLEY_INTEL_VERSION_CHECK(19,0,0) -# define HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ - HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("warning(disable:188)") \ - ((T) (expr)); \ - HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define HEDLEY_FLAGS_CAST(T, expr) HEDLEY_STATIC_CAST(T, expr) -#endif - -/* Remaining macros are deprecated. */ - -#if defined(HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) -# undef HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#endif -#if defined(__clang__) -# define HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) -#else -# define HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(HEDLEY_CLANG_HAS_ATTRIBUTE) -# undef HEDLEY_CLANG_HAS_ATTRIBUTE -#endif -#define HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) HEDLEY_HAS_ATTRIBUTE(attribute) - -#if defined(HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) -# undef HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#endif -#define HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) HEDLEY_HAS_CPP_ATTRIBUTE(attribute) - -#if defined(HEDLEY_CLANG_HAS_BUILTIN) -# undef HEDLEY_CLANG_HAS_BUILTIN -#endif -#define HEDLEY_CLANG_HAS_BUILTIN(builtin) HEDLEY_HAS_BUILTIN(builtin) - -#if defined(HEDLEY_CLANG_HAS_FEATURE) -# undef HEDLEY_CLANG_HAS_FEATURE -#endif -#define HEDLEY_CLANG_HAS_FEATURE(feature) HEDLEY_HAS_FEATURE(feature) - -#if defined(HEDLEY_CLANG_HAS_EXTENSION) -# undef HEDLEY_CLANG_HAS_EXTENSION -#endif -#define HEDLEY_CLANG_HAS_EXTENSION(extension) HEDLEY_HAS_EXTENSION(extension) - -#if defined(HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) -# undef HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#endif -#define HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) - -#if defined(HEDLEY_CLANG_HAS_WARNING) -# undef HEDLEY_CLANG_HAS_WARNING -#endif -#define HEDLEY_CLANG_HAS_WARNING(warning) HEDLEY_HAS_WARNING(warning) - -#endif /* !defined(HEDLEY_VERSION) || (HEDLEY_VERSION < X) */ - - -namespace csv { -#ifdef _MSC_VER -#pragma region Compatibility Macros -#endif - /** - * @def IF_CONSTEXPR - * Expands to `if constexpr` in C++17 and `if` otherwise - * - * @def CONSTEXPR_VALUE - * Expands to `constexpr` in C++17 and `const` otherwise. - * Mainly used for global variables. - * - * @def CONSTEXPR - * Expands to `constexpr` in decent compilers and `inline` otherwise. - * Intended for functions and methods. - */ - -#define STATIC_ASSERT(x) static_assert(x, "Assertion failed") - -#if CMAKE_CXX_STANDARD == 17 || __cplusplus >= 201703L -#define CSV_HAS_CXX17 -#endif - -#if CMAKE_CXX_STANDARD >= 14 || __cplusplus >= 201402L -#define CSV_HAS_CXX14 -#endif - -#ifdef CSV_HAS_CXX17 -#include - /** @typedef string_view - * The string_view class used by this library. - */ - using string_view = std::string_view; -#else - /** @typedef string_view - * The string_view class used by this library. - */ - using string_view = nonstd::string_view; -#endif - -#ifdef CSV_HAS_CXX17 - #define IF_CONSTEXPR if constexpr - #define CONSTEXPR_VALUE constexpr - - #define CONSTEXPR_17 constexpr -#else - #define IF_CONSTEXPR if - #define CONSTEXPR_VALUE const - - #define CONSTEXPR_17 inline -#endif - -#ifdef CSV_HAS_CXX14 - template - using enable_if_t = std::enable_if_t; - - #define CONSTEXPR_14 constexpr - #define CONSTEXPR_VALUE_14 constexpr -#else - template - using enable_if_t = typename std::enable_if::type; - - #define CONSTEXPR_14 inline - #define CONSTEXPR_VALUE_14 const -#endif - - // Resolves g++ bug with regard to constexpr methods - // See: https://stackoverflow.com/questions/36489369/constexpr-non-static-member-function-with-non-constexpr-constructor-gcc-clang-d -#if defined __GNUC__ && !defined __clang__ - #if (__GNUC__ >= 7 &&__GNUC_MINOR__ >= 2) || (__GNUC__ >= 8) - #define CONSTEXPR constexpr - #endif - #else - #ifdef CSV_HAS_CXX17 - #define CONSTEXPR constexpr - #endif -#endif - -#ifndef CONSTEXPR -#define CONSTEXPR inline -#endif - -#ifdef _MSC_VER -#pragma endregion -#endif - - namespace internals { - // PAGE_SIZE macro could be already defined by the host system. -#if defined(PAGE_SIZE) -#undef PAGE_SIZE -#endif - -// Get operating system specific details -#if defined(_WIN32) - inline int getpagesize() { - _SYSTEM_INFO sys_info = {}; - GetSystemInfo(&sys_info); - return std::max(sys_info.dwPageSize, sys_info.dwAllocationGranularity); - } - - const int PAGE_SIZE = getpagesize(); -#elif defined(__linux__) - const int PAGE_SIZE = getpagesize(); -#else - /** Size of a memory page in bytes. Used by - * csv::internals::CSVFieldArray when allocating blocks. - */ - const int PAGE_SIZE = 4096; -#endif - - /** For functions that lazy load a large CSV, this determines how - * many bytes are read at a time - */ - constexpr size_t ITERATION_CHUNK_SIZE = 10000000; // 10MB - - template - inline bool is_equal(T a, T b, T epsilon = 0.001) { - /** Returns true if two floating point values are about the same */ - static_assert(std::is_floating_point::value, "T must be a floating point type."); - return std::abs(a - b) < epsilon; - } - - /** @typedef ParseFlags - * An enum used for describing the significance of each character - * with respect to CSV parsing - * - * @see quote_escape_flag - */ - enum class ParseFlags { - QUOTE_ESCAPE_QUOTE = 0, /**< A quote inside or terminating a quote_escaped field */ - QUOTE = 2 | 1, /**< Characters which may signify a quote escape */ - NOT_SPECIAL = 4, /**< Characters with no special meaning or escaped delimiters and newlines */ - DELIMITER = 4 | 2, /**< Characters which signify a new field */ - NEWLINE = 4 | 2 | 1 /**< Characters which signify a new row */ - }; - - /** Transform the ParseFlags given the context of whether or not the current - * field is quote escaped */ - constexpr ParseFlags quote_escape_flag(ParseFlags flag, bool quote_escape) noexcept { - return (ParseFlags)((int)flag & ~((int)ParseFlags::QUOTE * quote_escape)); - } - - // Assumed to be true by parsing functions: allows for testing - // if an item is DELIMITER or NEWLINE with a >= statement - STATIC_ASSERT(ParseFlags::DELIMITER < ParseFlags::NEWLINE); - - /** Optimizations for reducing branching in parsing loop - * - * Idea: The meaning of all non-quote characters changes depending - * on whether or not the parser is in a quote-escaped mode (0 or 1) - */ - STATIC_ASSERT(quote_escape_flag(ParseFlags::NOT_SPECIAL, false) == ParseFlags::NOT_SPECIAL); - STATIC_ASSERT(quote_escape_flag(ParseFlags::QUOTE, false) == ParseFlags::QUOTE); - STATIC_ASSERT(quote_escape_flag(ParseFlags::DELIMITER, false) == ParseFlags::DELIMITER); - STATIC_ASSERT(quote_escape_flag(ParseFlags::NEWLINE, false) == ParseFlags::NEWLINE); - - STATIC_ASSERT(quote_escape_flag(ParseFlags::NOT_SPECIAL, true) == ParseFlags::NOT_SPECIAL); - STATIC_ASSERT(quote_escape_flag(ParseFlags::QUOTE, true) == ParseFlags::QUOTE_ESCAPE_QUOTE); - STATIC_ASSERT(quote_escape_flag(ParseFlags::DELIMITER, true) == ParseFlags::NOT_SPECIAL); - STATIC_ASSERT(quote_escape_flag(ParseFlags::NEWLINE, true) == ParseFlags::NOT_SPECIAL); - - /** An array which maps ASCII chars to a parsing flag */ - using ParseFlagMap = std::array; - - /** An array which maps ASCII chars to a flag indicating if it is whitespace */ - using WhitespaceMap = std::array; - } - - /** Integer indicating a requested column wasn't found. */ - constexpr int CSV_NOT_FOUND = -1; -} - - -namespace csv { - namespace internals { - struct ColNames; - using ColNamesPtr = std::shared_ptr; - - /** @struct ColNames - * A data structure for handling column name information. - * - * These are created by CSVReader and passed (via smart pointer) - * to CSVRow objects it creates, thus - * allowing for indexing by column name. - */ - struct ColNames { - public: - ColNames() = default; - ColNames(const std::vector& names) { - set_col_names(names); - } - - std::vector get_col_names() const; - void set_col_names(const std::vector&); - int index_of(csv::string_view) const; - - bool empty() const noexcept { return this->col_names.empty(); } - size_t size() const noexcept; - - private: - std::vector col_names; - std::unordered_map col_pos; - }; - } -} -/** @file - * Defines an object used to store CSV format settings - */ - -#include -#include -#include -#include - - -namespace csv { - namespace internals { - class IBasicCSVParser; - } - - class CSVReader; - - /** Determines how to handle rows that are shorter or longer than the majority */ - enum class VariableColumnPolicy { - THROW = -1, - IGNORE_ROW = 0, - KEEP = 1 - }; - - /** Stores the inferred format of a CSV file. */ - struct CSVGuessResult { - char delim; - int header_row; - }; - - /** Stores information about how to parse a CSV file. - * Can be used to construct a csv::CSVReader. - */ - class CSVFormat { - public: - /** Settings for parsing a RFC 4180 CSV file */ - CSVFormat() = default; - - /** Sets the delimiter of the CSV file - * - * @throws `std::runtime_error` thrown if trim, quote, or possible delimiting characters overlap - */ - CSVFormat& delimiter(char delim); - - /** Sets a list of potential delimiters - * - * @throws `std::runtime_error` thrown if trim, quote, or possible delimiting characters overlap - * @param[in] delim An array of possible delimiters to try parsing the CSV with - */ - CSVFormat& delimiter(const std::vector & delim); - - /** Sets the whitespace characters to be trimmed - * - * @throws `std::runtime_error` thrown if trim, quote, or possible delimiting characters overlap - * @param[in] ws An array of whitespace characters that should be trimmed - */ - CSVFormat& trim(const std::vector & ws); - - /** Sets the quote character - * - * @throws `std::runtime_error` thrown if trim, quote, or possible delimiting characters overlap - */ - CSVFormat& quote(char quote); - - /** Sets the column names. - * - * @note Unsets any values set by header_row() - */ - CSVFormat& column_names(const std::vector& names); - - /** Sets the header row - * - * @note Unsets any values set by column_names() - */ - CSVFormat& header_row(int row); - - /** Tells the parser that this CSV has no header row - * - * @note Equivalent to `header_row(-1)` - * - */ - CSVFormat& no_header() { - this->header_row(-1); - return *this; - } - - /** Turn quoting on or off */ - CSVFormat& quote(bool use_quote) { - this->no_quote = !use_quote; - return *this; - } - - /** Tells the parser how to handle columns of a different length than the others */ - CONSTEXPR_14 CSVFormat& variable_columns(VariableColumnPolicy policy = VariableColumnPolicy::IGNORE_ROW) { - this->variable_column_policy = policy; - return *this; - } - - /** Tells the parser how to handle columns of a different length than the others */ - CONSTEXPR_14 CSVFormat& variable_columns(bool policy) { - this->variable_column_policy = (VariableColumnPolicy)policy; - return *this; - } - - #ifndef DOXYGEN_SHOULD_SKIP_THIS - char get_delim() const { - // This error should never be received by end users. - if (this->possible_delimiters.size() > 1) { - throw std::runtime_error("There is more than one possible delimiter."); - } - - return this->possible_delimiters.at(0); - } - - CONSTEXPR bool is_quoting_enabled() const { return !this->no_quote; } - CONSTEXPR char get_quote_char() const { return this->quote_char; } - CONSTEXPR int get_header() const { return this->header; } - std::vector get_possible_delims() const { return this->possible_delimiters; } - std::vector get_trim_chars() const { return this->trim_chars; } - CONSTEXPR VariableColumnPolicy get_variable_column_policy() const { return this->variable_column_policy; } - #endif - - /** CSVFormat for guessing the delimiter */ - CSV_INLINE static CSVFormat guess_csv() { - CSVFormat format; - format.delimiter({ ',', '|', '\t', ';', '^' }) - .quote('"') - .header_row(0); - - return format; - } - - bool guess_delim() { - return this->possible_delimiters.size() > 1; - } - - friend CSVReader; - friend internals::IBasicCSVParser; - - private: - /**< Throws an error if delimiters and trim characters overlap */ - void assert_no_char_overlap(); - - /**< Set of possible delimiters */ - std::vector possible_delimiters = { ',' }; - - /**< Set of whitespace characters to trim */ - std::vector trim_chars = {}; - - /**< Row number with columns (ignored if col_names is non-empty) */ - int header = 0; - - /**< Whether or not to use quoting */ - bool no_quote = false; - - /**< Quote character */ - char quote_char = '"'; - - /**< Should be left empty unless file doesn't include header */ - std::vector col_names = {}; - - /**< Allow variable length columns? */ - VariableColumnPolicy variable_column_policy = VariableColumnPolicy::IGNORE_ROW; - }; -} -/** @file - * Defines the data type used for storing information about a CSV row - */ - -#include -#include -#include // For CSVField -#include // For CSVField -#include -#include -#include -#include -#include - -/** @file - * @brief Implements data type parsing functionality - */ - -#include -#include -#include -#include - - -namespace csv { - /** Enumerates the different CSV field types that are - * recognized by this library - * - * @note Overflowing integers will be stored and classified as doubles. - * @note Unlike previous releases, integer enums here are platform agnostic. - */ - enum class DataType { - UNKNOWN = -1, - CSV_NULL, /**< Empty string */ - CSV_STRING, /**< Non-numeric string */ - CSV_INT8, /**< 8-bit integer */ - CSV_INT16, /**< 16-bit integer (short on MSVC/GCC) */ - CSV_INT32, /**< 32-bit integer (int on MSVC/GCC) */ - CSV_INT64, /**< 64-bit integer (long long on MSVC/GCC) */ - CSV_DOUBLE /**< Floating point value */ - }; - - static_assert(DataType::CSV_STRING < DataType::CSV_INT8, "String type should come before numeric types."); - static_assert(DataType::CSV_INT8 < DataType::CSV_INT64, "Smaller integer types should come before larger integer types."); - static_assert(DataType::CSV_INT64 < DataType::CSV_DOUBLE, "Integer types should come before floating point value types."); - - namespace internals { - /** Compute 10 to the power of n */ - template - HEDLEY_CONST CONSTEXPR_14 - long double pow10(const T& n) noexcept { - long double multiplicand = n > 0 ? 10 : 0.1, - ret = 1; - - // Make all numbers positive - T iterations = n > 0 ? n : -n; - - for (T i = 0; i < iterations; i++) { - ret *= multiplicand; - } - - return ret; - } - - /** Compute 10 to the power of n */ - template<> - HEDLEY_CONST CONSTEXPR_14 - long double pow10(const unsigned& n) noexcept { - long double multiplicand = n > 0 ? 10 : 0.1, - ret = 1; - - for (unsigned i = 0; i < n; i++) { - ret *= multiplicand; - } - - return ret; - } - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - /** Private site-indexed array mapping byte sizes to an integer size enum */ - constexpr DataType int_type_arr[8] = { - DataType::CSV_INT8, // 1 - DataType::CSV_INT16, // 2 - DataType::UNKNOWN, - DataType::CSV_INT32, // 4 - DataType::UNKNOWN, - DataType::UNKNOWN, - DataType::UNKNOWN, - DataType::CSV_INT64 // 8 - }; - - template - inline DataType type_num() { - static_assert(std::is_integral::value, "T should be an integral type."); - static_assert(sizeof(T) <= 8, "Byte size must be no greater than 8."); - return int_type_arr[sizeof(T) - 1]; - } - - template<> inline DataType type_num() { return DataType::CSV_DOUBLE; } - template<> inline DataType type_num() { return DataType::CSV_DOUBLE; } - template<> inline DataType type_num() { return DataType::CSV_DOUBLE; } - template<> inline DataType type_num() { return DataType::CSV_NULL; } - template<> inline DataType type_num() { return DataType::CSV_STRING; } - - CONSTEXPR_14 DataType data_type(csv::string_view in, long double* const out = nullptr); -#endif - - /** Given a byte size, return the largest number than can be stored in - * an integer of that size - * - * Note: Provides a platform-agnostic way of mapping names like "long int" to - * byte sizes - */ - template - CONSTEXPR_14 long double get_int_max() { - static_assert(Bytes == 1 || Bytes == 2 || Bytes == 4 || Bytes == 8, - "Bytes must be a power of 2 below 8."); - - IF_CONSTEXPR (sizeof(signed char) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - IF_CONSTEXPR (sizeof(short) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - IF_CONSTEXPR (sizeof(int) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - IF_CONSTEXPR (sizeof(long int) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - IF_CONSTEXPR (sizeof(long long int) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - HEDLEY_UNREACHABLE(); - } - - /** Given a byte size, return the largest number than can be stored in - * an unsigned integer of that size - */ - template - CONSTEXPR_14 long double get_uint_max() { - static_assert(Bytes == 1 || Bytes == 2 || Bytes == 4 || Bytes == 8, - "Bytes must be a power of 2 below 8."); - - IF_CONSTEXPR(sizeof(unsigned char) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - IF_CONSTEXPR(sizeof(unsigned short) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - IF_CONSTEXPR(sizeof(unsigned int) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - IF_CONSTEXPR(sizeof(unsigned long int) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - IF_CONSTEXPR(sizeof(unsigned long long int) == Bytes) { - return (long double)std::numeric_limits::max(); - } - - HEDLEY_UNREACHABLE(); - } - - /** Largest number that can be stored in a 8-bit integer */ - CONSTEXPR_VALUE_14 long double CSV_INT8_MAX = get_int_max<1>(); - - /** Largest number that can be stored in a 16-bit integer */ - CONSTEXPR_VALUE_14 long double CSV_INT16_MAX = get_int_max<2>(); - - /** Largest number that can be stored in a 32-bit integer */ - CONSTEXPR_VALUE_14 long double CSV_INT32_MAX = get_int_max<4>(); - - /** Largest number that can be stored in a 64-bit integer */ - CONSTEXPR_VALUE_14 long double CSV_INT64_MAX = get_int_max<8>(); - - /** Largest number that can be stored in a 8-bit ungisned integer */ - CONSTEXPR_VALUE_14 long double CSV_UINT8_MAX = get_uint_max<1>(); - - /** Largest number that can be stored in a 16-bit unsigned integer */ - CONSTEXPR_VALUE_14 long double CSV_UINT16_MAX = get_uint_max<2>(); - - /** Largest number that can be stored in a 32-bit unsigned integer */ - CONSTEXPR_VALUE_14 long double CSV_UINT32_MAX = get_uint_max<4>(); - - /** Largest number that can be stored in a 64-bit unsigned integer */ - CONSTEXPR_VALUE_14 long double CSV_UINT64_MAX = get_uint_max<8>(); - - /** Given a pointer to the start of what is start of - * the exponential part of a number written (possibly) in scientific notation - * parse the exponent - */ - HEDLEY_PRIVATE CONSTEXPR_14 - DataType _process_potential_exponential( - csv::string_view exponential_part, - const long double& coeff, - long double * const out) { - long double exponent = 0; - auto result = data_type(exponential_part, &exponent); - - // Exponents in scientific notation should not be decimal numbers - if (result >= DataType::CSV_INT8 && result < DataType::CSV_DOUBLE) { - if (out) *out = coeff * pow10(exponent); - return DataType::CSV_DOUBLE; - } - - return DataType::CSV_STRING; - } - - /** Given the absolute value of an integer, determine what numeric type - * it fits in - */ - HEDLEY_PRIVATE HEDLEY_PURE CONSTEXPR_14 - DataType _determine_integral_type(const long double& number) noexcept { - // We can assume number is always non-negative - assert(number >= 0); - - if (number <= internals::CSV_INT8_MAX) - return DataType::CSV_INT8; - else if (number <= internals::CSV_INT16_MAX) - return DataType::CSV_INT16; - else if (number <= internals::CSV_INT32_MAX) - return DataType::CSV_INT32; - else if (number <= internals::CSV_INT64_MAX) - return DataType::CSV_INT64; - else // Conversion to long long will cause an overflow - return DataType::CSV_DOUBLE; - } - - /** Distinguishes numeric from other text values. Used by various - * type casting functions, like csv_parser::CSVReader::read_row() - * - * #### Rules - * - Leading and trailing whitespace ("padding") ignored - * - A string of just whitespace is NULL - * - * @param[in] in String value to be examined - * @param[out] out Pointer to long double where results of numeric parsing - * get stored - */ - CONSTEXPR_14 - DataType data_type(csv::string_view in, long double* const out) { - // Empty string --> NULL - if (in.size() == 0) - return DataType::CSV_NULL; - - bool ws_allowed = true, - neg_allowed = true, - dot_allowed = true, - digit_allowed = true, - has_digit = false, - prob_float = false; - - unsigned places_after_decimal = 0; - long double integral_part = 0, - decimal_part = 0; - - for (size_t i = 0, ilen = in.size(); i < ilen; i++) { - const char& current = in[i]; - - switch (current) { - case ' ': - if (!ws_allowed) { - if (isdigit(in[i - 1])) { - digit_allowed = false; - ws_allowed = true; - } - else { - // Ex: '510 123 4567' - return DataType::CSV_STRING; - } - } - break; - case '-': - if (!neg_allowed) { - // Ex: '510-123-4567' - return DataType::CSV_STRING; - } - - neg_allowed = false; - break; - case '.': - if (!dot_allowed) { - return DataType::CSV_STRING; - } - - dot_allowed = false; - prob_float = true; - break; - case 'e': - case 'E': - // Process scientific notation - if (prob_float || (i && i + 1 < ilen && isdigit(in[i - 1]))) { - size_t exponent_start_idx = i + 1; - prob_float = true; - - // Strip out plus sign - if (in[i + 1] == '+') { - exponent_start_idx++; - } - - return _process_potential_exponential( - in.substr(exponent_start_idx), - neg_allowed ? integral_part + decimal_part : -(integral_part + decimal_part), - out - ); - } - - return DataType::CSV_STRING; - break; - default: - short digit = static_cast(current - '0'); - if (digit >= 0 && digit <= 9) { - // Process digit - has_digit = true; - - if (!digit_allowed) - return DataType::CSV_STRING; - else if (ws_allowed) // Ex: '510 456' - ws_allowed = false; - - // Build current number - if (prob_float) - decimal_part += digit / pow10(++places_after_decimal); - else - integral_part = (integral_part * 10) + digit; - } - else { - return DataType::CSV_STRING; - } - } - } - - // No non-numeric/non-whitespace characters found - if (has_digit) { - long double number = integral_part + decimal_part; - if (out) { - *out = neg_allowed ? number : -number; - } - - return prob_float ? DataType::CSV_DOUBLE : _determine_integral_type(number); - } - - // Just whitespace - return DataType::CSV_NULL; - } - } -} - -namespace csv { - namespace internals { - class IBasicCSVParser; - - static const std::string ERROR_NAN = "Not a number."; - static const std::string ERROR_OVERFLOW = "Overflow error."; - static const std::string ERROR_FLOAT_TO_INT = - "Attempted to convert a floating point value to an integral type."; - static const std::string ERROR_NEG_TO_UNSIGNED = "Negative numbers cannot be converted to unsigned types."; - - std::string json_escape_string(csv::string_view s) noexcept; - - /** A barebones class used for describing CSV fields */ - struct RawCSVField { - RawCSVField() = default; - RawCSVField(size_t _start, size_t _length, bool _double_quote = false) { - start = _start; - length = _length; - has_double_quote = _double_quote; - } - - /** The start of the field, relative to the beginning of the row */ - size_t start; - - /** The length of the row, ignoring quote escape characters */ - size_t length; - - /** Whether or not the field contains an escaped quote */ - bool has_double_quote; - }; - - /** A class used for efficiently storing RawCSVField objects and expanding as necessary - * - * @par Implementation - * This data structure stores RawCSVField in continguous blocks. When more capacity - * is needed, a new block is allocated, but previous data stays put. - * - * @par Thread Safety - * This class may be safely read from multiple threads and written to from one, - * as long as the writing thread does not actively touch fields which are being - * read. - */ - class CSVFieldList { - public: - /** Construct a CSVFieldList which allocates blocks of a certain size */ - CSVFieldList(size_t single_buffer_capacity = (size_t)(internals::PAGE_SIZE / sizeof(RawCSVField))) : - _single_buffer_capacity(single_buffer_capacity) { - this->allocate(); - } - - // No copy constructor - CSVFieldList(const CSVFieldList& other) = delete; - - // CSVFieldArrays may be moved - CSVFieldList(CSVFieldList&& other) : - _single_buffer_capacity(other._single_buffer_capacity) { - buffers = std::move(other.buffers); - _current_buffer_size = other._current_buffer_size; - _back = other._back; - } - - ~CSVFieldList() { - for (auto& buffer : buffers) - delete[] buffer; - } - - template - void emplace_back(Args&&... args) { - if (this->_current_buffer_size == this->_single_buffer_capacity) { - this->allocate(); - } - - *(_back++) = RawCSVField(std::forward(args)...); - _current_buffer_size++; - } - - size_t size() const noexcept { - return this->_current_buffer_size + ((this->buffers.size() - 1) * this->_single_buffer_capacity); - } - - RawCSVField& operator[](size_t n) const; - - private: - const size_t _single_buffer_capacity; - - std::vector buffers = {}; - - /** Number of items in the current buffer */ - size_t _current_buffer_size = 0; - - /** Pointer to the current empty field */ - RawCSVField* _back = nullptr; - - /** Allocate a new page of memory */ - void allocate(); - }; - - - /** A class for storing raw CSV data and associated metadata */ - struct RawCSVData { - std::shared_ptr _data = nullptr; - csv::string_view data = ""; - - internals::CSVFieldList fields; - - std::unordered_set has_double_quotes = {}; - - // TODO: Consider replacing with a more thread-safe structure - std::unordered_map double_quote_fields = {}; - - internals::ColNamesPtr col_names = nullptr; - internals::ParseFlagMap parse_flags; - internals::WhitespaceMap ws_flags; - }; - - using RawCSVDataPtr = std::shared_ptr; - } - - /** - * @class CSVField - * @brief Data type representing individual CSV values. - * CSVFields can be obtained by using CSVRow::operator[] - */ - class CSVField { - public: - /** Constructs a CSVField from a string_view */ - constexpr explicit CSVField(csv::string_view _sv) noexcept : sv(_sv) { }; - - operator std::string() const { - return std::string(" ") + std::string(this->sv); - } - - /** Returns the value casted to the requested type, performing type checking before. - * - * \par Valid options for T - * - std::string or csv::string_view - * - signed integral types (signed char, short, int, long int, long long int) - * - floating point types (float, double, long double) - * - unsigned integers are not supported at this time, but may be in a later release - * - * \par Invalid conversions - * - Converting non-numeric values to any numeric type - * - Converting floating point values to integers - * - Converting a large integer to a smaller type that will not hold it - * - * @note This method is capable of parsing scientific E-notation. - * See [this page](md_docs_source_scientific_notation.html) - * for more details. - * - * @throws std::runtime_error Thrown if an invalid conversion is performed. - * - * @warning Currently, conversions to floating point types are not - * checked for loss of precision - * - * @warning Any string_views returned are only guaranteed to be valid - * if the parent CSVRow is still alive. If you are concerned - * about object lifetimes, then grab a std::string or a - * numeric value. - * - */ - template T get() { - IF_CONSTEXPR(std::is_arithmetic::value) { - // Note: this->type() also converts the CSV value to float - if (this->type() <= DataType::CSV_STRING) { - throw std::runtime_error(internals::ERROR_NAN); - } - } - - IF_CONSTEXPR(std::is_integral::value) { - // Note: this->is_float() also converts the CSV value to float - if (this->is_float()) { - throw std::runtime_error(internals::ERROR_FLOAT_TO_INT); - } - - IF_CONSTEXPR(std::is_unsigned::value) { - if (this->value < 0) { - throw std::runtime_error(internals::ERROR_NEG_TO_UNSIGNED); - } - } - } - - // Allow fallthrough from previous if branch - IF_CONSTEXPR(!std::is_floating_point::value) { - IF_CONSTEXPR(std::is_unsigned::value) { - // Quick hack to perform correct unsigned integer boundary checks - if (this->value > internals::get_uint_max()) { - throw std::runtime_error(internals::ERROR_OVERFLOW); - } - } - else if (internals::type_num() < this->_type) { - throw std::runtime_error(internals::ERROR_OVERFLOW); - } - } - - return static_cast(this->value); - } - - /** Parse a hexadecimal value, returning false if the value is not hex. */ - bool try_parse_hex(int& parsedValue); - - /** Compares the contents of this field to a numeric value. If this - * field does not contain a numeric value, then all comparisons return - * false. - * - * @note Floating point values are considered equal if they are within - * `0.000001` of each other. - * - * @warning Multiple numeric comparisons involving the same field can - * be done more efficiently by calling the CSVField::get<>() method. - * - * @sa csv::CSVField::operator==(const char * other) - * @sa csv::CSVField::operator==(csv::string_view other) - */ - template - CONSTEXPR_14 bool operator==(T other) const noexcept - { - static_assert(std::is_arithmetic::value, - "T should be a numeric value."); - - if (this->_type != DataType::UNKNOWN) { - if (this->_type == DataType::CSV_STRING) { - return false; - } - - return internals::is_equal(value, static_cast(other), 0.000001L); - } - - long double out = 0; - if (internals::data_type(this->sv, &out) == DataType::CSV_STRING) { - return false; - } - - return internals::is_equal(out, static_cast(other), 0.000001L); - } - - /** Return a string view over the field's contents */ - CONSTEXPR csv::string_view get_sv() const noexcept { return this->sv; } - - /** Returns true if field is an empty string or string of whitespace characters */ - CONSTEXPR_14 bool is_null() noexcept { return type() == DataType::CSV_NULL; } - - /** Returns true if field is a non-numeric, non-empty string */ - CONSTEXPR_14 bool is_str() noexcept { return type() == DataType::CSV_STRING; } - - /** Returns true if field is an integer or float */ - CONSTEXPR_14 bool is_num() noexcept { return type() >= DataType::CSV_INT8; } - - /** Returns true if field is an integer */ - CONSTEXPR_14 bool is_int() noexcept { - return (type() >= DataType::CSV_INT8) && (type() <= DataType::CSV_INT64); - } - - /** Returns true if field is a floating point value */ - CONSTEXPR_14 bool is_float() noexcept { return type() == DataType::CSV_DOUBLE; }; - - /** Return the type of the underlying CSV data */ - CONSTEXPR_14 DataType type() noexcept { - this->get_value(); - return _type; - } - - private: - long double value = 0; /**< Cached numeric value */ - csv::string_view sv = ""; /**< A pointer to this field's text */ - DataType _type = DataType::UNKNOWN; /**< Cached data type value */ - CONSTEXPR_14 void get_value() noexcept { - /* Check to see if value has been cached previously, if not - * evaluate it - */ - if ((int)_type < 0) { - this->_type = internals::data_type(this->sv, &this->value); - } - } - }; - - /** Data structure for representing CSV rows */ - class CSVRow { - public: - friend internals::IBasicCSVParser; - - CSVRow() = default; - - /** Construct a CSVRow from a RawCSVDataPtr */ - CSVRow(internals::RawCSVDataPtr _data) : data(_data) {} - CSVRow(internals::RawCSVDataPtr _data, size_t _data_start, size_t _field_bounds) - : data(_data), data_start(_data_start), fields_start(_field_bounds) {} - - /** Indicates whether row is empty or not */ - CONSTEXPR bool empty() const noexcept { return this->size() == 0; } - - /** Return the number of fields in this row */ - CONSTEXPR size_t size() const noexcept { return row_length; } - - /** @name Value Retrieval */ - ///@{ - CSVField operator[](size_t n) const; - CSVField operator[](const std::string&) const; - std::string to_json(const std::vector& subset = {}) const; - std::string to_json_array(const std::vector& subset = {}) const; - - /** Retrieve this row's associated column names */ - std::vector get_col_names() const { - return this->data->col_names->get_col_names(); - } - - /** Convert this CSVRow into a vector of strings. - * **Note**: This is a less efficient method of - * accessing data than using the [] operator. - */ - operator std::vector() const; - ///@} - - /** A random access iterator over the contents of a CSV row. - * Each iterator points to a CSVField. - */ - class iterator { - public: -#ifndef DOXYGEN_SHOULD_SKIP_THIS - using value_type = CSVField; - using difference_type = int; - - // Using CSVField * as pointer type causes segfaults in MSVC debug builds - // but using shared_ptr as pointer type won't compile in g++ -#ifdef _MSC_BUILD - using pointer = std::shared_ptr; -#else - using pointer = CSVField * ; -#endif - - using reference = CSVField & ; - using iterator_category = std::random_access_iterator_tag; -#endif - iterator(const CSVRow*, int i); - - reference operator*() const; - pointer operator->() const; - - iterator operator++(int); - iterator& operator++(); - iterator operator--(int); - iterator& operator--(); - iterator operator+(difference_type n) const; - iterator operator-(difference_type n) const; - - /** Two iterators are equal if they point to the same field */ - CONSTEXPR bool operator==(const iterator& other) const noexcept { - return this->i == other.i; - }; - - CONSTEXPR bool operator!=(const iterator& other) const noexcept { return !operator==(other); } - -#ifndef NDEBUG - friend CSVRow; -#endif - - private: - const CSVRow * daddy = nullptr; // Pointer to parent - std::shared_ptr field = nullptr; // Current field pointed at - int i = 0; // Index of current field - }; - - /** A reverse iterator over the contents of a CSVRow. */ - using reverse_iterator = std::reverse_iterator; - - /** @name Iterators - * @brief Each iterator points to a CSVField object. - */ - ///@{ - iterator begin() const; - iterator end() const noexcept; - reverse_iterator rbegin() const noexcept; - reverse_iterator rend() const; - ///@} - - private: - /** Retrieve a string view corresponding to the specified index */ - csv::string_view get_field(size_t index) const; - - internals::RawCSVDataPtr data; - - /** Where in RawCSVData.data we start */ - size_t data_start = 0; - - /** Where in the RawCSVDataPtr.fields array we start */ - size_t fields_start = 0; - - /** How many columns this row spans */ - size_t row_length = 0; - }; - -#ifdef _MSC_VER -#pragma region CSVField::get Specializations -#endif - /** Retrieve this field's original string */ - template<> - inline std::string CSVField::get() { - return std::string(this->sv); - } - - /** Retrieve a view over this field's string - * - * @warning This string_view is only guaranteed to be valid as long as this - * CSVRow is still alive. - */ - template<> - CONSTEXPR_14 csv::string_view CSVField::get() { - return this->sv; - } - - /** Retrieve this field's value as a long double */ - template<> - CONSTEXPR_14 long double CSVField::get() { - if (!is_num()) - throw std::runtime_error(internals::ERROR_NAN); - - return this->value; - } -#ifdef _MSC_VER -#pragma endregion CSVField::get Specializations -#endif - - /** Compares the contents of this field to a string */ - template<> - CONSTEXPR bool CSVField::operator==(const char * other) const noexcept - { - return this->sv == other; - } - - /** Compares the contents of this field to a string */ - template<> - CONSTEXPR bool CSVField::operator==(csv::string_view other) const noexcept - { - return this->sv == other; - } -} - -inline std::ostream& operator << (std::ostream& os, csv::CSVField const& value) { - os << std::string(value); - return os; -} - - -namespace csv { - namespace internals { - /** Create a vector v where each index i corresponds to the - * ASCII number for a character and, v[i + 128] labels it according to - * the CSVReader::ParseFlags enum - */ - HEDLEY_CONST CONSTEXPR_17 ParseFlagMap make_parse_flags(char delimiter) { - std::array ret = {}; - for (int i = -128; i < 128; i++) { - const int arr_idx = i + 128; - char ch = char(i); - - if (ch == delimiter) - ret[arr_idx] = ParseFlags::DELIMITER; - else if (ch == '\r' || ch == '\n') - ret[arr_idx] = ParseFlags::NEWLINE; - else - ret[arr_idx] = ParseFlags::NOT_SPECIAL; - } - - return ret; - } - - /** Create a vector v where each index i corresponds to the - * ASCII number for a character and, v[i + 128] labels it according to - * the CSVReader::ParseFlags enum - */ - HEDLEY_CONST CONSTEXPR_17 ParseFlagMap make_parse_flags(char delimiter, char quote_char) { - std::array ret = make_parse_flags(delimiter); - ret[(size_t)quote_char + 128] = ParseFlags::QUOTE; - return ret; - } - - /** Create a vector v where each index i corresponds to the - * ASCII number for a character c and, v[i + 128] is true if - * c is a whitespace character - */ - HEDLEY_CONST CONSTEXPR_17 WhitespaceMap make_ws_flags(const char* ws_chars, size_t n_chars) { - std::array ret = {}; - for (int i = -128; i < 128; i++) { - const int arr_idx = i + 128; - char ch = char(i); - ret[arr_idx] = false; - - for (size_t j = 0; j < n_chars; j++) { - if (ws_chars[j] == ch) { - ret[arr_idx] = true; - } - } - } - - return ret; - } - - inline WhitespaceMap make_ws_flags(const std::vector& flags) { - return make_ws_flags(flags.data(), flags.size()); - } - - CSV_INLINE size_t get_file_size(csv::string_view filename); - - CSV_INLINE std::string get_csv_head(csv::string_view filename); - - /** Read the first 500KB of a CSV file */ - CSV_INLINE std::string get_csv_head(csv::string_view filename, size_t file_size); - - /** A std::deque wrapper which allows multiple read and write threads to concurrently - * access it along with providing read threads the ability to wait for the deque - * to become populated - */ - template - class ThreadSafeDeque { - public: - ThreadSafeDeque(size_t notify_size = 100) : _notify_size(notify_size) {}; - ThreadSafeDeque(const ThreadSafeDeque& other) { - this->data = other.data; - this->_notify_size = other._notify_size; - } - - ThreadSafeDeque(const std::deque& source) : ThreadSafeDeque() { - this->data = source; - } - - void clear() noexcept { this->data.clear(); } - - bool empty() const noexcept { - return this->data.empty(); - } - - T& front() noexcept { - return this->data.front(); - } - - T& operator[](size_t n) { - return this->data[n]; - } - - void push_back(T&& item) { - std::lock_guard lock{ this->_lock }; - this->data.push_back(std::move(item)); - - if (this->size() >= _notify_size) { - this->_cond.notify_all(); - } - } - - T pop_front() noexcept { - std::lock_guard lock{ this->_lock }; - T item = std::move(data.front()); - data.pop_front(); - return item; - } - - size_t size() const noexcept { return this->data.size(); } - - /** Returns true if a thread is actively pushing items to this deque */ - constexpr bool is_waitable() const noexcept { return this->_is_waitable; } - - /** Wait for an item to become available */ - void wait() { - if (!is_waitable()) { - return; - } - - std::unique_lock lock{ this->_lock }; - this->_cond.wait(lock, [this] { return this->size() >= _notify_size || !this->is_waitable(); }); - lock.unlock(); - } - - typename std::deque::iterator begin() noexcept { - return this->data.begin(); - } - - typename std::deque::iterator end() noexcept { - return this->data.end(); - } - - /** Tell listeners that this deque is actively being pushed to */ - void notify_all() { - std::unique_lock lock{ this->_lock }; - this->_is_waitable = true; - this->_cond.notify_all(); - } - - /** Tell all listeners to stop */ - void kill_all() { - std::unique_lock lock{ this->_lock }; - this->_is_waitable = false; - this->_cond.notify_all(); - } - - private: - bool _is_waitable = false; - size_t _notify_size; - std::mutex _lock; - std::condition_variable _cond; - std::deque data; - }; - - constexpr const int UNINITIALIZED_FIELD = -1; - } - - /** Standard type for storing collection of rows */ - using RowCollection = internals::ThreadSafeDeque; - - namespace internals { - /** Abstract base class which provides CSV parsing logic. - * - * Concrete implementations may customize this logic across - * different input sources, such as memory mapped files, stringstreams, - * etc... - */ - class IBasicCSVParser { - public: - IBasicCSVParser() = default; - IBasicCSVParser(const CSVFormat&, const ColNamesPtr&); - IBasicCSVParser(const ParseFlagMap& parse_flags, const WhitespaceMap& ws_flags - ) : _parse_flags(parse_flags), _ws_flags(ws_flags) {}; - - virtual ~IBasicCSVParser() {} - - /** Whether or not we have reached the end of source */ - bool eof() { return this->_eof; } - - /** Parse the next block of data */ - virtual void next(size_t bytes) = 0; - - /** Indicate the last block of data has been parsed */ - void end_feed(); - - CONSTEXPR_17 ParseFlags parse_flag(const char ch) const noexcept { - return _parse_flags.data()[ch + 128]; - } - - CONSTEXPR_17 ParseFlags compound_parse_flag(const char ch) const noexcept { - return quote_escape_flag(parse_flag(ch), this->quote_escape); - } - - /** Whether or not this CSV has a UTF-8 byte order mark */ - CONSTEXPR bool utf8_bom() const { return this->_utf8_bom; } - - void set_output(RowCollection& rows) { this->_records = &rows; } - - protected: - /** @name Current Parser State */ - ///@{ - CSVRow current_row; - RawCSVDataPtr data_ptr = nullptr; - ColNamesPtr _col_names = nullptr; - CSVFieldList* fields = nullptr; - int field_start = UNINITIALIZED_FIELD; - size_t field_length = 0; - - /** An array where the (i + 128)th slot gives the ParseFlags for ASCII character i */ - ParseFlagMap _parse_flags; - ///@} - - /** @name Current Stream/File State */ - ///@{ - bool _eof = false; - - /** The size of the incoming CSV */ - size_t source_size = 0; - ///@} - - /** Whether or not source needs to be read in chunks */ - CONSTEXPR bool no_chunk() const { return this->source_size < ITERATION_CHUNK_SIZE; } - - /** Parse the current chunk of data * - * - * @returns How many character were read that are part of complete rows - */ - size_t parse(); - - /** Create a new RawCSVDataPtr for a new chunk of data */ - void reset_data_ptr(); - private: - /** An array where the (i + 128)th slot determines whether ASCII character i should - * be trimmed - */ - WhitespaceMap _ws_flags; - bool quote_escape = false; - bool field_has_double_quote = false; - - /** Where we are in the current data block */ - size_t data_pos = 0; - - /** Whether or not an attempt to find Unicode BOM has been made */ - bool unicode_bom_scan = false; - bool _utf8_bom = false; - - /** Where complete rows should be pushed to */ - RowCollection* _records = nullptr; - - CONSTEXPR_17 bool ws_flag(const char ch) const noexcept { - return _ws_flags.data()[ch + 128]; - } - - size_t& current_row_start() { - return this->current_row.data_start; - } - - void parse_field() noexcept; - - /** Finish parsing the current field */ - void push_field(); - - /** Finish parsing the current row */ - void push_row(); - - /** Handle possible Unicode byte order mark */ - void trim_utf8_bom(); - }; - - /** A class for parsing CSV data from a `std::stringstream` - * or an `std::ifstream` - */ - template - class StreamParser: public IBasicCSVParser { - using RowCollection = ThreadSafeDeque; - - public: - StreamParser(TStream& source, - const CSVFormat& format, - const ColNamesPtr& col_names = nullptr - ) : IBasicCSVParser(format, col_names), _source(std::move(source)) {}; - - StreamParser( - TStream& source, - internals::ParseFlagMap parse_flags, - internals::WhitespaceMap ws_flags) : - IBasicCSVParser(parse_flags, ws_flags), - _source(std::move(source)) - {}; - - ~StreamParser() {} - - void next(size_t bytes = ITERATION_CHUNK_SIZE) override { - if (this->eof()) return; - - this->reset_data_ptr(); - this->data_ptr->_data = std::make_shared(); - - if (source_size == 0) { - const auto start = _source.tellg(); - _source.seekg(0, std::ios::end); - const auto end = _source.tellg(); - _source.seekg(0, std::ios::beg); - - source_size = end - start; - } - - // Read data into buffer - size_t length = std::min(source_size - stream_pos, bytes); - std::unique_ptr buff(new char[length]); - _source.seekg(stream_pos, std::ios::beg); - _source.read(buff.get(), length); - stream_pos = _source.tellg(); - ((std::string*)(this->data_ptr->_data.get()))->assign(buff.get(), length); - - // Create string_view - this->data_ptr->data = *((std::string*)this->data_ptr->_data.get()); - - // Parse - this->current_row = CSVRow(this->data_ptr); - size_t remainder = this->parse(); - - if (stream_pos == source_size || no_chunk()) { - this->_eof = true; - this->end_feed(); - } - else { - this->stream_pos -= (length - remainder); - } - } - - private: - TStream _source; - size_t stream_pos = 0; - }; - - /** Parser for memory-mapped files - * - * @par Implementation - * This class constructs moving windows over a file to avoid - * creating massive memory maps which may require more RAM - * than the user has available. It contains logic to automatically - * re-align each memory map to the beginning of a CSV row. - * - */ - class MmapParser : public IBasicCSVParser { - public: - MmapParser(csv::string_view filename, - const CSVFormat& format, - const ColNamesPtr& col_names = nullptr - ) : IBasicCSVParser(format, col_names) { - this->_filename = filename.data(); - this->source_size = get_file_size(filename); - }; - - ~MmapParser() {} - - void next(size_t bytes) override; - - private: - std::string _filename; - size_t mmap_pos = 0; - }; - } -} - - -/** The all encompassing namespace */ -namespace csv { - /** Stuff that is generally not of interest to end-users */ - namespace internals { - std::string format_row(const std::vector& row, csv::string_view delim = ", "); - - std::vector _get_col_names( csv::string_view head, const CSVFormat format = CSVFormat::guess_csv()); - - struct GuessScore { - double score; - size_t header; - }; - - CSV_INLINE GuessScore calculate_score(csv::string_view head, CSVFormat format); - - CSVGuessResult _guess_format(csv::string_view head, const std::vector& delims = { ',', '|', '\t', ';', '^', '~' }); - } - - std::vector get_col_names( - csv::string_view filename, - const CSVFormat format = CSVFormat::guess_csv()); - - /** Guess the delimiter used by a delimiter-separated values file */ - CSVGuessResult guess_format(csv::string_view filename, - const std::vector& delims = { ',', '|', '\t', ';', '^', '~' }); - - /** @class CSVReader - * @brief Main class for parsing CSVs from files and in-memory sources - * - * All rows are compared to the column names for length consistency - * - By default, rows that are too short or too long are dropped - * - Custom behavior can be defined by overriding bad_row_handler in a subclass - */ - class CSVReader { - public: - /** - * An input iterator capable of handling large files. - * @note Created by CSVReader::begin() and CSVReader::end(). - * - * @par Iterating over a file - * @snippet tests/test_csv_iterator.cpp CSVReader Iterator 1 - * - * @par Using with `` library - * @snippet tests/test_csv_iterator.cpp CSVReader Iterator 2 - */ - class iterator { - public: - #ifndef DOXYGEN_SHOULD_SKIP_THIS - using value_type = CSVRow; - using difference_type = std::ptrdiff_t; - using pointer = CSVRow * ; - using reference = CSVRow & ; - using iterator_category = std::input_iterator_tag; - #endif - - iterator() = default; - iterator(CSVReader* reader) : daddy(reader) {}; - iterator(CSVReader*, CSVRow&&); - - /** Access the CSVRow held by the iterator */ - CONSTEXPR_14 reference operator*() { return this->row; } - - /** Return a pointer to the CSVRow the iterator has stopped at */ - CONSTEXPR_14 pointer operator->() { return &(this->row); } - - iterator& operator++(); /**< Pre-increment iterator */ - iterator operator++(int); /**< Post-increment ierator */ - iterator& operator--(); - - /** Returns true if iterators were constructed from the same CSVReader - * and point to the same row - */ - CONSTEXPR bool operator==(const iterator& other) const noexcept { - return (this->daddy == other.daddy) && (this->i == other.i); - } - - CONSTEXPR bool operator!=(const iterator& other) const noexcept { return !operator==(other); } - private: - CSVReader * daddy = nullptr; // Pointer to parent - CSVRow row; // Current row - size_t i = 0; // Index of current row - }; - - /** @name Constructors - * Constructors for iterating over large files and parsing in-memory sources. - */ - ///@{ - CSVReader(csv::string_view filename, CSVFormat format = CSVFormat::guess_csv()); - - /** Allows parsing stream sources such as `std::stringstream` or `std::ifstream` - * - * @tparam TStream An input stream deriving from `std::istream` - * @note Currently this constructor requires special CSV dialects to be manually - * specified. - */ - template::value, int> = 0> - CSVReader(TStream& source, CSVFormat format = CSVFormat()) : _format(format) { - using Parser = internals::StreamParser; - - if (!format.col_names.empty()) - this->set_col_names(format.col_names); - - this->parser = std::unique_ptr( - new Parser(source, format, col_names)); // For C++11 - this->initial_read(); - } - ///@} - - CSVReader(const CSVReader&) = delete; // No copy constructor - CSVReader(CSVReader&&) = default; // Move constructor - CSVReader& operator=(const CSVReader&) = delete; // No copy assignment - CSVReader& operator=(CSVReader&& other) = default; - ~CSVReader() { - if (this->read_csv_worker.joinable()) { - this->read_csv_worker.join(); - } - } - - /** @name Retrieving CSV Rows */ - ///@{ - bool read_row(CSVRow &row); - iterator begin(); - HEDLEY_CONST iterator end() const noexcept; - - /** Returns true if we have reached end of file */ - bool eof() const noexcept { return this->parser->eof(); }; - ///@} - - /** @name CSV Metadata */ - ///@{ - CSVFormat get_format() const; - std::vector get_col_names() const; - int index_of(csv::string_view col_name) const; - ///@} - - /** @name CSV Metadata: Attributes */ - ///@{ - /** Whether or not the file or stream contains valid CSV rows, - * not including the header. - * - * @note Gives an accurate answer regardless of when it is called. - * - */ - CONSTEXPR bool empty() const noexcept { return this->n_rows() == 0; } - - /** Retrieves the number of rows that have been read so far */ - CONSTEXPR size_t n_rows() const noexcept { return this->_n_rows; } - - /** Whether or not CSV was prefixed with a UTF-8 bom */ - bool utf8_bom() const noexcept { return this->parser->utf8_bom(); } - ///@} - - protected: - /** - * \defgroup csv_internal CSV Parser Internals - * @brief Internals of CSVReader. Only maintainers and those looking to - * extend the parser should read this. - * @{ - */ - - /** Sets this reader's column names and associated data */ - void set_col_names(const std::vector&); - - /** @name CSV Settings **/ - ///@{ - CSVFormat _format; - ///@} - - /** @name Parser State */ - ///@{ - /** Pointer to a object containing column information */ - internals::ColNamesPtr col_names = std::make_shared(); - - /** Helper class which actually does the parsing */ - std::unique_ptr parser = nullptr; - - /** Queue of parsed CSV rows */ - std::unique_ptr records{new RowCollection(100)}; - - size_t n_cols = 0; /**< The number of columns in this CSV */ - size_t _n_rows = 0; /**< How many rows (minus header) have been read so far */ - - /** @name Multi-Threaded File Reading Functions */ - ///@{ - bool read_csv(size_t bytes = internals::ITERATION_CHUNK_SIZE); - ///@} - - /**@}*/ - - private: - /** Whether or not rows before header were trimmed */ - bool header_trimmed = false; - - /** @name Multi-Threaded File Reading: Flags and State */ - ///@{ - std::thread read_csv_worker; /**< Worker thread for read_csv() */ - ///@} - - /** Read initial chunk to get metadata */ - void initial_read() { - this->read_csv_worker = std::thread(&CSVReader::read_csv, this, internals::ITERATION_CHUNK_SIZE); - this->read_csv_worker.join(); - } - - void trim_header(); - }; -} - -/** @file - * Calculates statistics from CSV files - */ - -#include -#include -#include - -namespace csv { - /** Class for calculating statistics from CSV files and in-memory sources - * - * **Example** - * \include programs/csv_stats.cpp - * - */ - class CSVStat { - public: - using FreqCount = std::unordered_map; - using TypeCount = std::unordered_map; - - std::vector get_mean() const; - std::vector get_variance() const; - std::vector get_mins() const; - std::vector get_maxes() const; - std::vector get_counts() const; - std::vector get_dtypes() const; - - std::vector get_col_names() const { - return this->reader.get_col_names(); - } - - CSVStat(csv::string_view filename, CSVFormat format = CSVFormat::guess_csv()); - CSVStat(std::stringstream& source, CSVFormat format = CSVFormat()); - private: - // An array of rolling averages - // Each index corresponds to the rolling mean for the column at said index - std::vector rolling_means; - std::vector rolling_vars; - std::vector mins; - std::vector maxes; - std::vector counts; - std::vector dtypes; - std::vector n; - - // Statistic calculators - void variance(const long double&, const size_t&); - void count(CSVField&, const size_t&); - void min_max(const long double&, const size_t&); - void dtype(CSVField&, const size_t&); - - void calc(); - void calc_chunk(); - void calc_worker(const size_t&); - - CSVReader reader; - std::deque records = {}; - }; -} - -#include -#include -#include - -namespace csv { - /** Returned by get_file_info() */ - struct CSVFileInfo { - std::string filename; /**< Filename */ - std::vector col_names; /**< CSV column names */ - char delim; /**< Delimiting character */ - size_t n_rows; /**< Number of rows in a file */ - size_t n_cols; /**< Number of columns in a CSV */ - }; - - /** @name Shorthand Parsing Functions - * @brief Convienience functions for parsing small strings - */ - ///@{ - CSVReader operator ""_csv(const char*, size_t); - CSVReader operator ""_csv_no_header(const char*, size_t); - CSVReader parse(csv::string_view in, CSVFormat format = CSVFormat()); - CSVReader parse_no_header(csv::string_view in); - ///@} - - /** @name Utility Functions */ - ///@{ - std::unordered_map csv_data_types(const std::string&); - CSVFileInfo get_file_info(const std::string& filename); - int get_col_pos(csv::string_view filename, csv::string_view col_name, - const CSVFormat& format = CSVFormat::guess_csv()); - ///@} -} -/** @file - * A standalone header file for writing delimiter-separated files - */ - -#include -#include -#include -#include -#include -#include - - -namespace csv { - namespace internals { - static int DECIMAL_PLACES = 5; - - /** to_string() for unsigned integers */ - template::value, int> = 0> - inline std::string to_string(T value) { - std::string digits_reverse = ""; - - if (value == 0) return "0"; - - while (value > 0) { - digits_reverse += (char)('0' + (value % 10)); - value /= 10; - } - - return std::string(digits_reverse.rbegin(), digits_reverse.rend()); - } - - /** to_string() for signed integers */ - template< - typename T, - csv::enable_if_t::value && std::is_signed::value, int> = 0 - > - inline std::string to_string(T value) { - if (value >= 0) - return to_string((size_t)value); - - return "-" + to_string((size_t)(value * -1)); - } - - /** to_string() for floating point numbers */ - template< - typename T, - csv::enable_if_t::value, int> = 0 - > - inline std::string to_string(T value) { - std::string result; - - T integral_part; - T fractional_part = std::abs(std::modf(value, &integral_part)); - integral_part = std::abs(integral_part); - - // Integral part - if (value < 0) result = "-"; - - if (integral_part == 0) { - result = "0"; - } - else { - for (int n_digits = (int)(std::log(integral_part) / std::log(10)); - n_digits + 1 > 0; n_digits --) { - int digit = (int)(std::fmod(integral_part, pow10(n_digits + 1)) / pow10(n_digits)); - result += (char)('0' + digit); - } - } - - // Decimal part - result += "."; - - if (fractional_part > 0) { - fractional_part *= (T)(pow10(DECIMAL_PLACES)); - for (int n_digits = DECIMAL_PLACES; n_digits > 0; n_digits--) { - int digit = (int)(std::fmod(fractional_part, pow10(n_digits)) / pow10(n_digits - 1)); - result += (char)('0' + digit); - } - } - else { - result += "0"; - } - - return result; - } - } - - /** Sets how many places after the decimal will be written for floating point numbers - * - * @param precision Number of decimal places - */ - inline static void set_decimal_places(int precision) { - internals::DECIMAL_PLACES = precision; - } - - /** @name CSV Writing */ - ///@{ - /** - * Class for writing delimiter separated values files - * - * To write formatted strings, one should - * -# Initialize a DelimWriter with respect to some output stream - * -# Call write_row() on std::vectors of unformatted text - * - * @tparam OutputStream The output stream, e.g. `std::ofstream`, `std::stringstream` - * @tparam Delim The delimiter character - * @tparam Quote The quote character - * @tparam Flush True: flush after every writing function, - * false: you need to flush explicitly if needed. - * In both cases the destructor will flush. - * - * @par Hint - * Use the aliases csv::CSVWriter to write CSV - * formatted strings and csv::TSVWriter - * to write tab separated strings - * - * @par Example w/ std::vector, std::deque, std::list - * @snippet test_write_csv.cpp CSV Writer Example - * - * @par Example w/ std::tuple - * @snippet test_write_csv.cpp CSV Writer Tuple Example - */ - template - class DelimWriter { - public: - /** Construct a DelimWriter over the specified output stream - * - * @param _out Stream to write to - * @param _quote_minimal Limit field quoting to only when necessary - */ - - DelimWriter(OutputStream& _out, bool _quote_minimal = true) - : out(_out), quote_minimal(_quote_minimal) {}; - - /** Construct a DelimWriter over the file - * - * @param[out] filename File to write to - */ - DelimWriter(const std::string& filename) : DelimWriter(std::ifstream(filename)) {}; - - /** Destructor will flush remaining data - * - */ - ~DelimWriter() { - out.flush(); - } - - /** Format a sequence of strings and write to CSV according to RFC 4180 - * - * @warning This does not check to make sure row lengths are consistent - * - * @param[in] record Sequence of strings to be formatted - * - * @return The current DelimWriter instance (allowing for operator chaining) - */ - template - DelimWriter& operator<<(const std::array& record) { - for (size_t i = 0; i < Size; i++) { - out << csv_escape(record[i]); - if (i + 1 != Size) out << Delim; - } - - end_out(); - return *this; - } - - /** @copydoc operator<< */ - template - DelimWriter& operator<<(const std::tuple& record) { - this->write_tuple<0, T...>(record); - return *this; - } - - /** - * @tparam T A container such as std::vector, std::deque, or std::list - * - * @copydoc operator<< - */ - template< - typename T, typename Alloc, template class Container, - - // Avoid conflicting with tuples with two elements - csv::enable_if_t::value, int> = 0 - > - DelimWriter& operator<<(const Container& record) { - const size_t ilen = record.size(); - size_t i = 0; - for (const auto& field : record) { - out << csv_escape(field); - if (i + 1 != ilen) out << Delim; - i++; - } - - end_out(); - return *this; - } - - /** Flushes the written data - * - */ - void flush() { - out.flush(); - } - - private: - template< - typename T, - csv::enable_if_t< - !std::is_convertible::value - && !std::is_convertible::value - , int> = 0 - > - std::string csv_escape(T in) { - return internals::to_string(in); - } - - template< - typename T, - csv::enable_if_t< - std::is_convertible::value - || std::is_convertible::value - , int> = 0 - > - std::string csv_escape(T in) { - IF_CONSTEXPR(std::is_convertible::value) { - return _csv_escape(in); - } - - return _csv_escape(std::string(in)); - } - - std::string _csv_escape(csv::string_view in) { - /** Format a string to be RFC 4180-compliant - * @param[in] in String to be CSV-formatted - * @param[out] quote_minimal Only quote fields if necessary. - * If False, everything is quoted. - */ - - // Do we need a quote escape - bool quote_escape = false; - - for (auto ch : in) { - if (ch == Quote || ch == Delim || ch == '\r' || ch == '\n') { - quote_escape = true; - break; - } - } - - if (!quote_escape) { - if (quote_minimal) return std::string(in); - else { - std::string ret(1, Quote); - ret += in.data(); - ret += Quote; - return ret; - } - } - - // Start initial quote escape sequence - std::string ret(1, Quote); - for (auto ch: in) { - if (ch == Quote) ret += std::string(2, Quote); - else ret += ch; - } - - // Finish off quote escape - ret += Quote; - return ret; - } - - /** Recurisve template for writing std::tuples */ - template - typename std::enable_if::type write_tuple(const std::tuple& record) { - out << csv_escape(std::get(record)); - - IF_CONSTEXPR (Index + 1 < sizeof...(T)) out << Delim; - - this->write_tuple(record); - } - - /** Base case for writing std::tuples */ - template - typename std::enable_if::type write_tuple(const std::tuple& record) { - (void)record; - end_out(); - } - - /** Ends a line in 'out' and flushes, if Flush is true.*/ - void end_out() { - out << '\n'; - IF_CONSTEXPR(Flush) out.flush(); - } - - OutputStream & out; - bool quote_minimal; - }; - - /** An alias for csv::DelimWriter for writing standard CSV files - * - * @sa csv::DelimWriter::operator<<() - * - * @note Use `csv::make_csv_writer()` to in instatiate this class over - * an actual output stream. - */ - template - using CSVWriter = DelimWriter; - - /** Class for writing tab-separated values files - * - * @sa csv::DelimWriter::write_row() - * @sa csv::DelimWriter::operator<<() - * - * @note Use `csv::make_tsv_writer()` to in instatiate this class over - * an actual output stream. - */ - template - using TSVWriter = DelimWriter; - - /** Return a csv::CSVWriter over the output stream */ - template - inline CSVWriter make_csv_writer(OutputStream& out, bool quote_minimal=true) { - return CSVWriter(out, quote_minimal); - } - - /** Return a buffered csv::CSVWriter over the output stream (does not auto flush) */ - template - inline CSVWriter make_csv_writer_buffered(OutputStream& out, bool quote_minimal=true) { - return CSVWriter(out, quote_minimal); - } - - /** Return a csv::TSVWriter over the output stream */ - template - inline TSVWriter make_tsv_writer(OutputStream& out, bool quote_minimal=true) { - return TSVWriter(out, quote_minimal); - } - - /** Return a buffered csv::TSVWriter over the output stream (does not auto flush) */ - template - inline TSVWriter make_tsv_writer_buffered(OutputStream& out, bool quote_minimal=true) { - return TSVWriter(out, quote_minimal); - } - ///@} -} - - -namespace csv { - namespace internals { - CSV_INLINE size_t get_file_size(csv::string_view filename) { - std::ifstream infile(std::string(filename), std::ios::binary); - const auto start = infile.tellg(); - infile.seekg(0, std::ios::end); - const auto end = infile.tellg(); - - return end - start; - } - - CSV_INLINE std::string get_csv_head(csv::string_view filename) { - return get_csv_head(filename, get_file_size(filename)); - } - - CSV_INLINE std::string get_csv_head(csv::string_view filename, size_t file_size) { - const size_t bytes = 500000; - - std::error_code error; - size_t length = std::min((size_t)file_size, bytes); - auto mmap = mio::make_mmap_source(std::string(filename), 0, length, error); - - if (error) { - throw std::runtime_error("Cannot open file " + std::string(filename)); - } - - return std::string(mmap.begin(), mmap.end()); - } - -#ifdef _MSC_VER -#pragma region IBasicCVParser -#endif - CSV_INLINE IBasicCSVParser::IBasicCSVParser( - const CSVFormat& format, - const ColNamesPtr& col_names - ) : _col_names(col_names) { - if (format.no_quote) { - _parse_flags = internals::make_parse_flags(format.get_delim()); - } - else { - _parse_flags = internals::make_parse_flags(format.get_delim(), format.quote_char); - } - - _ws_flags = internals::make_ws_flags( - format.trim_chars.data(), format.trim_chars.size() - ); - } - - CSV_INLINE void IBasicCSVParser::end_feed() { - using internals::ParseFlags; - - bool empty_last_field = this->data_ptr - && this->data_ptr->_data - && !this->data_ptr->data.empty() - && parse_flag(this->data_ptr->data.back()) == ParseFlags::DELIMITER; - - // Push field - if (this->field_length > 0 || empty_last_field) { - this->push_field(); - } - - // Push row - if (this->current_row.size() > 0) - this->push_row(); - } - - CSV_INLINE void IBasicCSVParser::parse_field() noexcept { - using internals::ParseFlags; - auto& in = this->data_ptr->data; - - // Trim off leading whitespace - while (data_pos < in.size() && ws_flag(in[data_pos])) - data_pos++; - - if (field_start == UNINITIALIZED_FIELD) - field_start = (int)(data_pos - current_row_start()); - - // Optimization: Since NOT_SPECIAL characters tend to occur in contiguous - // sequences, use the loop below to avoid having to go through the outer - // switch statement as much as possible - while (data_pos < in.size() && compound_parse_flag(in[data_pos]) == ParseFlags::NOT_SPECIAL) - data_pos++; - - field_length = data_pos - (field_start + current_row_start()); - - // Trim off trailing whitespace, this->field_length constraint matters - // when field is entirely whitespace - for (size_t j = data_pos - 1; ws_flag(in[j]) && this->field_length > 0; j--) - this->field_length--; - } - - CSV_INLINE void IBasicCSVParser::push_field() - { - // Update - if (field_has_double_quote) { - fields->emplace_back( - field_start == UNINITIALIZED_FIELD ? 0 : (unsigned int)field_start, - field_length, - true - ); - field_has_double_quote = false; - - } - else { - fields->emplace_back( - field_start == UNINITIALIZED_FIELD ? 0 : (unsigned int)field_start, - field_length - ); - } - - current_row.row_length++; - - // Reset field state - field_start = UNINITIALIZED_FIELD; - field_length = 0; - } - - /** @return The number of characters parsed that belong to complete rows */ - CSV_INLINE size_t IBasicCSVParser::parse() - { - using internals::ParseFlags; - - this->quote_escape = false; - this->data_pos = 0; - this->current_row_start() = 0; - this->trim_utf8_bom(); - - auto& in = this->data_ptr->data; - while (this->data_pos < in.size()) { - switch (compound_parse_flag(in[this->data_pos])) { - case ParseFlags::DELIMITER: - this->push_field(); - this->data_pos++; - break; - - case ParseFlags::NEWLINE: - this->data_pos++; - - // Catches CRLF (or LFLF) - if (this->data_pos < in.size() && parse_flag(in[this->data_pos]) == ParseFlags::NEWLINE) - this->data_pos++; - - // End of record -> Write record - this->push_field(); - this->push_row(); - - // Reset - this->current_row = CSVRow(data_ptr, this->data_pos, fields->size()); - break; - - case ParseFlags::NOT_SPECIAL: - this->parse_field(); - break; - - case ParseFlags::QUOTE_ESCAPE_QUOTE: - if (data_pos + 1 == in.size()) return this->current_row_start(); - else if (data_pos + 1 < in.size()) { - auto next_ch = parse_flag(in[data_pos + 1]); - if (next_ch >= ParseFlags::DELIMITER) { - quote_escape = false; - data_pos++; - break; - } - else if (next_ch == ParseFlags::QUOTE) { - // Case: Escaped quote - data_pos += 2; - this->field_length += 2; - this->field_has_double_quote = true; - break; - } - } - - // Case: Unescaped single quote => not strictly valid but we'll keep it - this->field_length++; - data_pos++; - - break; - - default: // Quote (currently not quote escaped) - if (this->field_length == 0) { - quote_escape = true; - data_pos++; - if (field_start == UNINITIALIZED_FIELD && data_pos < in.size() && !ws_flag(in[data_pos])) - field_start = (int)(data_pos - current_row_start()); - break; - } - - // Case: Unescaped quote - this->field_length++; - data_pos++; - - break; - } - } - - return this->current_row_start(); - } - - CSV_INLINE void IBasicCSVParser::push_row() { - current_row.row_length = fields->size() - current_row.fields_start; - this->_records->push_back(std::move(current_row)); - } - - CSV_INLINE void IBasicCSVParser::reset_data_ptr() { - this->data_ptr = std::make_shared(); - this->data_ptr->parse_flags = this->_parse_flags; - this->data_ptr->col_names = this->_col_names; - this->fields = &(this->data_ptr->fields); - } - - CSV_INLINE void IBasicCSVParser::trim_utf8_bom() { - auto& data = this->data_ptr->data; - - if (!this->unicode_bom_scan && data.size() >= 3) { - if (data[0] == '\xEF' && data[1] == '\xBB' && data[2] == '\xBF') { - this->data_pos += 3; // Remove BOM from input string - this->_utf8_bom = true; - } - - this->unicode_bom_scan = true; - } - } -#ifdef _MSC_VER -#pragma endregion -#endif - -#ifdef _MSC_VER -#pragma region Specializations -#endif - CSV_INLINE void MmapParser::next(size_t bytes = ITERATION_CHUNK_SIZE) { - // Reset parser state - this->field_start = UNINITIALIZED_FIELD; - this->field_length = 0; - this->reset_data_ptr(); - - // Create memory map - size_t length = std::min(this->source_size - this->mmap_pos, bytes); - std::error_code error; - this->data_ptr->_data = std::make_shared>(mio::make_mmap_source(this->_filename, this->mmap_pos, length, error)); - this->mmap_pos += length; - if (error) throw error; - - auto mmap_ptr = (mio::basic_mmap_source*)(this->data_ptr->_data.get()); - - // Create string view - this->data_ptr->data = csv::string_view(mmap_ptr->data(), mmap_ptr->length()); - - // Parse - this->current_row = CSVRow(this->data_ptr); - size_t remainder = this->parse(); - - if (this->mmap_pos == this->source_size || no_chunk()) { - this->_eof = true; - this->end_feed(); - } - - this->mmap_pos -= (length - remainder); - } -#ifdef _MSC_VER -#pragma endregion -#endif - } -} - - -namespace csv { - namespace internals { - CSV_INLINE std::vector ColNames::get_col_names() const { - return this->col_names; - } - - CSV_INLINE void ColNames::set_col_names(const std::vector& cnames) { - this->col_names = cnames; - - for (size_t i = 0; i < cnames.size(); i++) { - this->col_pos[cnames[i]] = i; - } - } - - CSV_INLINE int ColNames::index_of(csv::string_view col_name) const { - auto pos = this->col_pos.find(col_name.data()); - if (pos != this->col_pos.end()) - return (int)pos->second; - - return CSV_NOT_FOUND; - } - - CSV_INLINE size_t ColNames::size() const noexcept { - return this->col_names.size(); - } - - } -} -/** @file - * Defines an object used to store CSV format settings - */ - -#include -#include - - -namespace csv { - CSV_INLINE CSVFormat& CSVFormat::delimiter(char delim) { - this->possible_delimiters = { delim }; - this->assert_no_char_overlap(); - return *this; - } - - CSV_INLINE CSVFormat& CSVFormat::delimiter(const std::vector & delim) { - this->possible_delimiters = delim; - this->assert_no_char_overlap(); - return *this; - } - - CSV_INLINE CSVFormat& CSVFormat::quote(char quote) { - this->no_quote = false; - this->quote_char = quote; - this->assert_no_char_overlap(); - return *this; - } - - CSV_INLINE CSVFormat& CSVFormat::trim(const std::vector & chars) { - this->trim_chars = chars; - this->assert_no_char_overlap(); - return *this; - } - - CSV_INLINE CSVFormat& CSVFormat::column_names(const std::vector& names) { - this->col_names = names; - this->header = -1; - return *this; - } - - CSV_INLINE CSVFormat& CSVFormat::header_row(int row) { - if (row < 0) this->variable_column_policy = VariableColumnPolicy::KEEP; - - this->header = row; - this->col_names = {}; - return *this; - } - - CSV_INLINE void CSVFormat::assert_no_char_overlap() - { - auto delims = std::set( - this->possible_delimiters.begin(), this->possible_delimiters.end()), - trims = std::set( - this->trim_chars.begin(), this->trim_chars.end()); - - // Stores intersection of possible delimiters and trim characters - std::vector intersection = {}; - - // Find which characters overlap, if any - std::set_intersection( - delims.begin(), delims.end(), - trims.begin(), trims.end(), - std::back_inserter(intersection)); - - // Make sure quote character is not contained in possible delimiters - // or whitespace characters - if (delims.find(this->quote_char) != delims.end() || - trims.find(this->quote_char) != trims.end()) { - intersection.push_back(this->quote_char); - } - - if (!intersection.empty()) { - std::string err_msg = "There should be no overlap between the quote character, " - "the set of possible delimiters " - "and the set of whitespace characters. Offending characters: "; - - // Create a pretty error message with the list of overlapping - // characters - for (size_t i = 0; i < intersection.size(); i++) { - err_msg += "'"; - err_msg += intersection[i]; - err_msg += "'"; - - if (i + 1 < intersection.size()) - err_msg += ", "; - } - - throw std::runtime_error(err_msg + '.'); - } - } -} -/** @file - * @brief Defines functionality needed for basic CSV parsing - */ - - -namespace csv { - namespace internals { - CSV_INLINE std::string format_row(const std::vector& row, csv::string_view delim) { - /** Print a CSV row */ - std::stringstream ret; - for (size_t i = 0; i < row.size(); i++) { - ret << row[i]; - if (i + 1 < row.size()) ret << delim; - else ret << '\n'; - } - ret.flush(); - - return ret.str(); - } - - /** Return a CSV's column names - * - * @param[in] filename Path to CSV file - * @param[in] format Format of the CSV file - * - */ - CSV_INLINE std::vector _get_col_names(csv::string_view head, CSVFormat format) { - // Parse the CSV - auto trim_chars = format.get_trim_chars(); - std::stringstream source(head.data()); - RowCollection rows; - - StreamParser parser(source, format); - parser.set_output(rows); - parser.next(); - - return CSVRow(std::move(rows[format.get_header()])); - } - - CSV_INLINE GuessScore calculate_score(csv::string_view head, CSVFormat format) { - // Frequency counter of row length - std::unordered_map row_tally = { { 0, 0 } }; - - // Map row lengths to row num where they first occurred - std::unordered_map row_when = { { 0, 0 } }; - - // Parse the CSV - std::stringstream source(head.data()); - RowCollection rows; - - StreamParser parser(source, format); - parser.set_output(rows); - parser.next(); - - for (size_t i = 0; i < rows.size(); i++) { - auto& row = rows[i]; - - // Ignore zero-length rows - if (row.size() > 0) { - if (row_tally.find(row.size()) != row_tally.end()) { - row_tally[row.size()]++; - } - else { - row_tally[row.size()] = 1; - row_when[row.size()] = i; - } - } - } - - double final_score = 0; - size_t header_row = 0; - - // Final score is equal to the largest - // row size times rows of that size - for (auto& pair : row_tally) { - auto row_size = pair.first; - auto row_count = pair.second; - double score = (double)(row_size * row_count); - if (score > final_score) { - final_score = score; - header_row = row_when[row_size]; - } - } - - return { - final_score, - header_row - }; - } - - /** Guess the delimiter used by a delimiter-separated values file */ - CSV_INLINE CSVGuessResult _guess_format(csv::string_view head, const std::vector& delims) { - /** For each delimiter, find out which row length was most common. - * The delimiter with the longest mode row length wins. - * Then, the line number of the header row is the first row with - * the mode row length. - */ - - CSVFormat format; - size_t max_score = 0, - header = 0; - char current_delim = delims[0]; - - for (char cand_delim : delims) { - auto result = calculate_score(head, format.delimiter(cand_delim)); - - if ((size_t)result.score > max_score) { - max_score = (size_t)result.score; - current_delim = cand_delim; - header = result.header; - } - } - - return { current_delim, (int)header }; - } - } - - /** Return a CSV's column names - * - * @param[in] filename Path to CSV file - * @param[in] format Format of the CSV file - * - */ - CSV_INLINE std::vector get_col_names(csv::string_view filename, CSVFormat format) { - auto head = internals::get_csv_head(filename); - - /** Guess delimiter and header row */ - if (format.guess_delim()) { - auto guess_result = guess_format(filename, format.get_possible_delims()); - format.delimiter(guess_result.delim).header_row(guess_result.header_row); - } - - return internals::_get_col_names(head, format); - } - - /** Guess the delimiter used by a delimiter-separated values file */ - CSV_INLINE CSVGuessResult guess_format(csv::string_view filename, const std::vector& delims) { - auto head = internals::get_csv_head(filename); - return internals::_guess_format(head, delims); - } - - /** Reads an arbitrarily large CSV file using memory-mapped IO. - * - * **Details:** Reads the first block of a CSV file synchronously to get information - * such as column names and delimiting character. - * - * @param[in] filename Path to CSV file - * @param[in] format Format of the CSV file - * - * \snippet tests/test_read_csv.cpp CSVField Example - * - */ - CSV_INLINE CSVReader::CSVReader(csv::string_view filename, CSVFormat format) : _format(format) { - auto head = internals::get_csv_head(filename); - using Parser = internals::MmapParser; - - /** Guess delimiter and header row */ - if (format.guess_delim()) { - auto guess_result = internals::_guess_format(head, format.possible_delimiters); - format.delimiter(guess_result.delim); - format.header = guess_result.header_row; - this->_format = format; - } - - if (!format.col_names.empty()) - this->set_col_names(format.col_names); - - this->parser = std::unique_ptr(new Parser(filename, format, this->col_names)); // For C++11 - this->initial_read(); - } - - /** Return the format of the original raw CSV */ - CSV_INLINE CSVFormat CSVReader::get_format() const { - CSVFormat new_format = this->_format; - - // Since users are normally not allowed to set - // column names and header row simulatenously, - // we will set the backing variables directly here - new_format.col_names = this->col_names->get_col_names(); - new_format.header = this->_format.header; - - return new_format; - } - - /** Return the CSV's column names as a vector of strings. */ - CSV_INLINE std::vector CSVReader::get_col_names() const { - if (this->col_names) { - return this->col_names->get_col_names(); - } - - return std::vector(); - } - - /** Return the index of the column name if found or - * csv::CSV_NOT_FOUND otherwise. - */ - CSV_INLINE int CSVReader::index_of(csv::string_view col_name) const { - auto _col_names = this->get_col_names(); - for (size_t i = 0; i < _col_names.size(); i++) - if (_col_names[i] == col_name) return (int)i; - - return CSV_NOT_FOUND; - } - - CSV_INLINE void CSVReader::trim_header() { - if (!this->header_trimmed) { - for (int i = 0; i <= this->_format.header && !this->records->empty(); i++) { - if (i == this->_format.header && this->col_names->empty()) { - this->set_col_names(this->records->pop_front()); - } - else { - this->records->pop_front(); - } - } - - this->header_trimmed = true; - } - } - - /** - * @param[in] names Column names - */ - CSV_INLINE void CSVReader::set_col_names(const std::vector& names) - { - this->col_names->set_col_names(names); - this->n_cols = names.size(); - } - - /** - * Read a chunk of CSV data. - * - * @note This method is meant to be run on its own thread. Only one `read_csv()` thread - * should be active at a time. - * - * @param[in] bytes Number of bytes to read. - * - * @see CSVReader::read_csv_worker - * @see CSVReader::read_row() - */ - CSV_INLINE bool CSVReader::read_csv(size_t bytes) { - // Tell read_row() to listen for CSV rows - this->records->notify_all(); - - this->parser->set_output(*this->records); - this->parser->next(bytes); - - if (!this->header_trimmed) { - this->trim_header(); - } - - // Tell read_row() to stop waiting - this->records->kill_all(); - - return true; - } - - /** - * Retrieve rows as CSVRow objects, returning true if more rows are available. - * - * @par Performance Notes - * - Reads chunks of data that are csv::internals::ITERATION_CHUNK_SIZE bytes large at a time - * - For performance details, read the documentation for CSVRow and CSVField. - * - * @param[out] row The variable where the parsed row will be stored - * @see CSVRow, CSVField - * - * **Example:** - * \snippet tests/test_read_csv.cpp CSVField Example - * - */ - CSV_INLINE bool CSVReader::read_row(CSVRow &row) { - while (true) { - if (this->records->empty()) { - if (this->records->is_waitable()) - // Reading thread is currently active => wait for it to populate records - this->records->wait(); - else if (this->parser->eof()) - // End of file and no more records - return false; - else { - // Reading thread is not active => start another one - if (this->read_csv_worker.joinable()) - this->read_csv_worker.join(); - - this->read_csv_worker = std::thread(&CSVReader::read_csv, this, internals::ITERATION_CHUNK_SIZE); - } - } - else if (this->records->front().size() != this->n_cols && - this->_format.variable_column_policy != VariableColumnPolicy::KEEP) { - auto errored_row = this->records->pop_front(); - - if (this->_format.variable_column_policy == VariableColumnPolicy::THROW) { - if (errored_row.size() < this->n_cols) - throw std::runtime_error("Line too short " + internals::format_row(errored_row)); - - throw std::runtime_error("Line too long " + internals::format_row(errored_row)); - } - } - else { - row = this->records->pop_front(); - this->_n_rows++; - return true; - } - } - - return false; - } -} - -/** @file - * Defines an input iterator for csv::CSVReader - */ - - -namespace csv { - /** Return an iterator to the first row in the reader */ - CSV_INLINE CSVReader::iterator CSVReader::begin() { - if (this->records->empty()) { - this->read_csv_worker = std::thread(&CSVReader::read_csv, this, internals::ITERATION_CHUNK_SIZE); - this->read_csv_worker.join(); - - // Still empty => return end iterator - if (this->records->empty()) return this->end(); - } - - CSVReader::iterator ret(this, this->records->pop_front()); - return ret; - } - - /** A placeholder for the imaginary past the end row in a CSV. - * Attempting to deference this will lead to bad things. - */ - CSV_INLINE HEDLEY_CONST CSVReader::iterator CSVReader::end() const noexcept { - return CSVReader::iterator(); - } - - ///////////////////////// - // CSVReader::iterator // - ///////////////////////// - - CSV_INLINE CSVReader::iterator::iterator(CSVReader* _daddy, CSVRow&& _row) : - daddy(_daddy) { - row = std::move(_row); - } - - /** Advance the iterator by one row. If this CSVReader has an - * associated file, then the iterator will lazily pull more data from - * that file until the end of file is reached. - * - * @note This iterator does **not** block the thread responsible for parsing CSV. - * - */ - CSV_INLINE CSVReader::iterator& CSVReader::iterator::operator++() { - if (!daddy->read_row(this->row)) { - this->daddy = nullptr; // this == end() - } - - return *this; - } - - /** Post-increment iterator */ - CSV_INLINE CSVReader::iterator CSVReader::iterator::operator++(int) { - auto temp = *this; - if (!daddy->read_row(this->row)) { - this->daddy = nullptr; // this == end() - } - - return temp; - } -} - -/** @file - * Defines the data type used for storing information about a CSV row - */ - -#include -#include - -namespace csv { - namespace internals { - CSV_INLINE RawCSVField& CSVFieldList::operator[](size_t n) const { - const size_t page_no = n / _single_buffer_capacity; - const size_t buffer_idx = (page_no < 1) ? n : n % _single_buffer_capacity; - return this->buffers[page_no][buffer_idx]; - } - - CSV_INLINE void CSVFieldList::allocate() { - RawCSVField * buffer = new RawCSVField[_single_buffer_capacity]; - buffers.push_back(buffer); - _current_buffer_size = 0; - _back = &(buffers.back()[0]); - } - } - - /** Return a CSVField object corrsponding to the nth value in the row. - * - * @note This method performs bounds checking, and will throw an - * `std::runtime_error` if n is invalid. - * - * @complexity - * Constant, by calling csv::CSVRow::get_csv::string_view() - * - */ - CSV_INLINE CSVField CSVRow::operator[](size_t n) const { - return CSVField(this->get_field(n)); - } - - /** Retrieve a value by its associated column name. If the column - * specified can't be round, a runtime error is thrown. - * - * @complexity - * Constant. This calls the other CSVRow::operator[]() after - * converting column names into indices using a hash table. - * - * @param[in] col_name The column to look for - */ - CSV_INLINE CSVField CSVRow::operator[](const std::string& col_name) const { - auto & col_names = this->data->col_names; - auto col_pos = col_names->index_of(col_name); - if (col_pos > -1) { - return this->operator[](col_pos); - } - - throw std::runtime_error("Can't find a column named " + col_name); - } - - CSV_INLINE CSVRow::operator std::vector() const { - std::vector ret; - for (size_t i = 0; i < size(); i++) - ret.push_back(std::string(this->get_field(i))); - - return ret; - } - - CSV_INLINE csv::string_view CSVRow::get_field(size_t index) const - { - using internals::ParseFlags; - - if (index >= this->size()) - throw std::runtime_error("Index out of bounds."); - - const size_t field_index = this->fields_start + index; - auto& field = this->data->fields[field_index]; - auto field_str = csv::string_view(this->data->data).substr(this->data_start + field.start); - - if (field.has_double_quote) { - auto& value = this->data->double_quote_fields[field_index]; - if (value.empty()) { - bool prev_ch_quote = false; - for (size_t i = 0; i < field.length; i++) { - if (this->data->parse_flags[field_str[i] + 128] == ParseFlags::QUOTE) { - if (prev_ch_quote) { - prev_ch_quote = false; - continue; - } - else { - prev_ch_quote = true; - } - } - - value += field_str[i]; - } - } - - return csv::string_view(value); - } - - return field_str.substr(0, field.length); - } - - CSV_INLINE bool CSVField::try_parse_hex(int& parsedValue) { - size_t start = 0, end = 0; - - // Trim out whitespace chars - for (; start < this->sv.size() && this->sv[start] == ' '; start++); - for (end = start; end < this->sv.size() && this->sv[end] != ' '; end++); - - unsigned long long int value = 0; - - size_t digits = (end - start); - size_t base16_exponent = digits - 1; - - if (digits == 0) return false; - - for (const auto& ch : this->sv.substr(start, digits)) { - int digit = 0; - - switch (ch) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - digit = static_cast(ch - '0'); - break; - case 'a': - case 'A': - digit = 10; - break; - case 'b': - case 'B': - digit = 11; - break; - case 'c': - case 'C': - digit = 12; - break; - case 'd': - case 'D': - digit = 13; - break; - case 'e': - case 'E': - digit = 14; - break; - case 'f': - case 'F': - digit = 15; - break; - default: - return false; - } - - value += digit * pow(16, base16_exponent); - base16_exponent--; - } - - parsedValue = value; - return true; - } - -#ifdef _MSC_VER -#pragma region CSVRow Iterator -#endif - /** Return an iterator pointing to the first field. */ - CSV_INLINE CSVRow::iterator CSVRow::begin() const { - return CSVRow::iterator(this, 0); - } - - /** Return an iterator pointing to just after the end of the CSVRow. - * - * @warning Attempting to dereference the end iterator results - * in dereferencing a null pointer. - */ - CSV_INLINE CSVRow::iterator CSVRow::end() const noexcept { - return CSVRow::iterator(this, (int)this->size()); - } - - CSV_INLINE CSVRow::reverse_iterator CSVRow::rbegin() const noexcept { - return std::reverse_iterator(this->end()); - } - - CSV_INLINE CSVRow::reverse_iterator CSVRow::rend() const { - return std::reverse_iterator(this->begin()); - } - - CSV_INLINE HEDLEY_NON_NULL(2) - CSVRow::iterator::iterator(const CSVRow* _reader, int _i) - : daddy(_reader), i(_i) { - if (_i < (int)this->daddy->size()) - this->field = std::make_shared( - this->daddy->operator[](_i)); - else - this->field = nullptr; - } - - CSV_INLINE CSVRow::iterator::reference CSVRow::iterator::operator*() const { - return *(this->field.get()); - } - - CSV_INLINE CSVRow::iterator::pointer CSVRow::iterator::operator->() const { - // Using CSVField * as pointer type causes segfaults in MSVC debug builds - #ifdef _MSC_BUILD - return this->field; - #else - return this->field.get(); - #endif - } - - CSV_INLINE CSVRow::iterator& CSVRow::iterator::operator++() { - // Pre-increment operator - this->i++; - if (this->i < (int)this->daddy->size()) - this->field = std::make_shared( - this->daddy->operator[](i)); - else // Reached the end of row - this->field = nullptr; - return *this; - } - - CSV_INLINE CSVRow::iterator CSVRow::iterator::operator++(int) { - // Post-increment operator - auto temp = *this; - this->operator++(); - return temp; - } - - CSV_INLINE CSVRow::iterator& CSVRow::iterator::operator--() { - // Pre-decrement operator - this->i--; - this->field = std::make_shared( - this->daddy->operator[](this->i)); - return *this; - } - - CSV_INLINE CSVRow::iterator CSVRow::iterator::operator--(int) { - // Post-decrement operator - auto temp = *this; - this->operator--(); - return temp; - } - - CSV_INLINE CSVRow::iterator CSVRow::iterator::operator+(difference_type n) const { - // Allows for iterator arithmetic - return CSVRow::iterator(this->daddy, i + (int)n); - } - - CSV_INLINE CSVRow::iterator CSVRow::iterator::operator-(difference_type n) const { - // Allows for iterator arithmetic - return CSVRow::iterator::operator+(-n); - } -#ifdef _MSC_VER -#pragma endregion CSVRow Iterator -#endif -} - -/** @file - * Implements JSON serialization abilities - */ - - -namespace csv { - /* - The implementations for json_extra_space() and json_escape_string() - were modified from source code for JSON for Modern C++. - - The respective license is below: - - The code is licensed under the [MIT - License](http://opensource.org/licenses/MIT): - - Copyright © 2013-2015 Niels Lohmann. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation files - (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - */ - - namespace internals { - /*! - @brief calculates the extra space to escape a JSON string - - @param[in] s the string to escape - @return the number of characters required to escape string @a s - - @complexity Linear in the length of string @a s. - */ - static std::size_t json_extra_space(csv::string_view& s) noexcept - { - std::size_t result = 0; - - - for (const auto& c : s) - { - switch (c) - { - case '"': - case '\\': - case '\b': - case '\f': - case '\n': - case '\r': - case '\t': - { - // from c (1 byte) to \x (2 bytes) - result += 1; - break; - } - - - default: - { - if (c >= 0x00 && c <= 0x1f) - { - // from c (1 byte) to \uxxxx (6 bytes) - result += 5; - } - break; - } - } - } - - - return result; - } - - CSV_INLINE std::string json_escape_string(csv::string_view s) noexcept - { - const auto space = json_extra_space(s); - if (space == 0) - { - return std::string(s); - } - - // create a result string of necessary size - std::string result(s.size() + space, '\\'); - std::size_t pos = 0; - - for (const auto& c : s) - { - switch (c) - { - // quotation mark (0x22) - case '"': - { - result[pos + 1] = '"'; - pos += 2; - break; - } - - - // reverse solidus (0x5c) - case '\\': - { - // nothing to change - pos += 2; - break; - } - - - // backspace (0x08) - case '\b': - { - result[pos + 1] = 'b'; - pos += 2; - break; - } - - - // formfeed (0x0c) - case '\f': - { - result[pos + 1] = 'f'; - pos += 2; - break; - } - - - // newline (0x0a) - case '\n': - { - result[pos + 1] = 'n'; - pos += 2; - break; - } - - - // carriage return (0x0d) - case '\r': - { - result[pos + 1] = 'r'; - pos += 2; - break; - } - - - // horizontal tab (0x09) - case '\t': - { - result[pos + 1] = 't'; - pos += 2; - break; - } - - - default: - { - if (c >= 0x00 && c <= 0x1f) - { - // print character c as \uxxxx - sprintf(&result[pos + 1], "u%04x", int(c)); - pos += 6; - // overwrite trailing null character - result[pos] = '\\'; - } - else - { - // all other characters are added as-is - result[pos++] = c; - } - break; - } - } - } - - return result; - } - } - - /** Convert a CSV row to a JSON object, i.e. - * `{"col1":"value1","col2":"value2"}` - * - * @note All strings are properly escaped. Numeric values are not quoted. - * @param[in] subset A subset of columns to contain in the JSON. - * Leave empty for original columns. - */ - CSV_INLINE std::string CSVRow::to_json(const std::vector& subset) const { - std::vector col_names = subset; - if (subset.empty()) { - col_names = this->data ? this->get_col_names() : std::vector({}); - } - - const size_t _n_cols = col_names.size(); - std::string ret = "{"; - - for (size_t i = 0; i < _n_cols; i++) { - auto& col = col_names[i]; - auto field = this->operator[](col); - - // TODO: Possible performance enhancements by caching escaped column names - ret += '"' + internals::json_escape_string(col) + "\":"; - - // Add quotes around strings but not numbers - if (field.is_num()) - ret += internals::json_escape_string(field.get()); - else - ret += '"' + internals::json_escape_string(field.get()) + '"'; - - // Do not add comma after last string - if (i + 1 < _n_cols) - ret += ','; - } - - ret += '}'; - return ret; - } - - /** Convert a CSV row to a JSON array, i.e. - * `["value1","value2",...]` - * - * @note All strings are properly escaped. Numeric values are not quoted. - * @param[in] subset A subset of columns to contain in the JSON. - * Leave empty for all columns. - */ - CSV_INLINE std::string CSVRow::to_json_array(const std::vector& subset) const { - std::vector col_names = subset; - if (subset.empty()) - col_names = this->data ? this->get_col_names() : std::vector({}); - - const size_t _n_cols = col_names.size(); - std::string ret = "["; - - for (size_t i = 0; i < _n_cols; i++) { - auto field = this->operator[](col_names[i]); - - // Add quotes around strings but not numbers - if (field.is_num()) - ret += internals::json_escape_string(field.get()); - else - ret += '"' + internals::json_escape_string(field.get()) + '"'; - - // Do not add comma after last string - if (i + 1 < _n_cols) - ret += ','; - } - - ret += ']'; - return ret; - } -} -/** @file - * Calculates statistics from CSV files - */ - -#include - -namespace csv { - /** Calculate statistics for an arbitrarily large file. When this constructor - * is called, CSVStat will process the entire file iteratively. Once finished, - * methods like get_mean(), get_counts(), etc... can be used to retrieve statistics. - */ - CSV_INLINE CSVStat::CSVStat(csv::string_view filename, CSVFormat format) : - reader(filename, format) { - this->calc(); - } - - /** Calculate statistics for a CSV stored in a std::stringstream */ - CSV_INLINE CSVStat::CSVStat(std::stringstream& stream, CSVFormat format) : - reader(stream, format) { - this->calc(); - } - - /** Return current means */ - CSV_INLINE std::vector CSVStat::get_mean() const { - std::vector ret; - for (size_t i = 0; i < this->get_col_names().size(); i++) { - ret.push_back(this->rolling_means[i]); - } - return ret; - } - - /** Return current variances */ - CSV_INLINE std::vector CSVStat::get_variance() const { - std::vector ret; - for (size_t i = 0; i < this->get_col_names().size(); i++) { - ret.push_back(this->rolling_vars[i]/(this->n[i] - 1)); - } - return ret; - } - - /** Return current mins */ - CSV_INLINE std::vector CSVStat::get_mins() const { - std::vector ret; - for (size_t i = 0; i < this->get_col_names().size(); i++) { - ret.push_back(this->mins[i]); - } - return ret; - } - - /** Return current maxes */ - CSV_INLINE std::vector CSVStat::get_maxes() const { - std::vector ret; - for (size_t i = 0; i < this->get_col_names().size(); i++) { - ret.push_back(this->maxes[i]); - } - return ret; - } - - /** Get counts for each column */ - CSV_INLINE std::vector CSVStat::get_counts() const { - std::vector ret; - for (size_t i = 0; i < this->get_col_names().size(); i++) { - ret.push_back(this->counts[i]); - } - return ret; - } - - /** Get data type counts for each column */ - CSV_INLINE std::vector CSVStat::get_dtypes() const { - std::vector ret; - for (size_t i = 0; i < this->get_col_names().size(); i++) { - ret.push_back(this->dtypes[i]); - } - return ret; - } - - CSV_INLINE void CSVStat::calc_chunk() { - /** Only create stats counters the first time **/ - if (dtypes.empty()) { - /** Go through all records and calculate specified statistics */ - for (size_t i = 0; i < this->get_col_names().size(); i++) { - dtypes.push_back({}); - counts.push_back({}); - rolling_means.push_back(0); - rolling_vars.push_back(0); - mins.push_back(NAN); - maxes.push_back(NAN); - n.push_back(0); - } - } - - // Start threads - std::vector pool; - for (size_t i = 0; i < this->get_col_names().size(); i++) - pool.push_back(std::thread(&CSVStat::calc_worker, this, i)); - - // Block until done - for (auto& th : pool) - th.join(); - - this->records.clear(); - } - - CSV_INLINE void CSVStat::calc() { - constexpr size_t CALC_CHUNK_SIZE = 5000; - - for (auto& row : reader) { - this->records.push_back(std::move(row)); - - /** Chunk rows */ - if (this->records.size() == CALC_CHUNK_SIZE) { - calc_chunk(); - } - } - - if (!this->records.empty()) { - calc_chunk(); - } - } - - CSV_INLINE void CSVStat::calc_worker(const size_t &i) { - /** Worker thread for CSVStat::calc() which calculates statistics for one column. - * - * @param[in] i Column index - */ - - auto current_record = this->records.begin(); - - for (size_t processed = 0; current_record != this->records.end(); processed++) { - if (current_record->size() == this->get_col_names().size()) { - auto current_field = (*current_record)[i]; - - // Optimization: Don't count() if there's too many distinct values in the first 1000 rows - if (processed < 1000 || this->counts[i].size() <= 500) - this->count(current_field, i); - - this->dtype(current_field, i); - - // Numeric Stuff - if (current_field.is_num()) { - long double x_n = current_field.get(); - - // This actually calculates mean AND variance - this->variance(x_n, i); - this->min_max(x_n, i); - } - } - else if (this->reader.get_format().get_variable_column_policy() == VariableColumnPolicy::THROW) { - throw std::runtime_error("Line has different length than the others " + internals::format_row(*current_record)); - } - - ++current_record; - } - } - - CSV_INLINE void CSVStat::dtype(CSVField& data, const size_t &i) { - /** Given a record update the type counter - * @param[in] record Data observation - * @param[out] i The column index that should be updated - */ - - auto type = data.type(); - if (this->dtypes[i].find(type) != - this->dtypes[i].end()) { - // Increment count - this->dtypes[i][type]++; - } else { - // Initialize count - this->dtypes[i].insert(std::make_pair(type, 1)); - } - } - - CSV_INLINE void CSVStat::count(CSVField& data, const size_t &i) { - /** Given a record update the frequency counter - * @param[in] record Data observation - * @param[out] i The column index that should be updated - */ - - auto item = data.get(); - - if (this->counts[i].find(item) != - this->counts[i].end()) { - // Increment count - this->counts[i][item]++; - } else { - // Initialize count - this->counts[i].insert(std::make_pair(item, 1)); - } - } - - CSV_INLINE void CSVStat::min_max(const long double &x_n, const size_t &i) { - /** Update current minimum and maximum - * @param[in] x_n Data observation - * @param[out] i The column index that should be updated - */ - if (std::isnan(this->mins[i])) - this->mins[i] = x_n; - if (std::isnan(this->maxes[i])) - this->maxes[i] = x_n; - - if (x_n < this->mins[i]) - this->mins[i] = x_n; - else if (x_n > this->maxes[i]) - this->maxes[i] = x_n; - } - - CSV_INLINE void CSVStat::variance(const long double &x_n, const size_t &i) { - /** Given a record update rolling mean and variance for all columns - * using Welford's Algorithm - * @param[in] x_n Data observation - * @param[out] i The column index that should be updated - */ - long double& current_rolling_mean = this->rolling_means[i]; - long double& current_rolling_var = this->rolling_vars[i]; - long double& current_n = this->n[i]; - long double delta; - long double delta2; - - current_n++; - - if (current_n == 1) { - current_rolling_mean = x_n; - } else { - delta = x_n - current_rolling_mean; - current_rolling_mean += delta/current_n; - delta2 = x_n - current_rolling_mean; - current_rolling_var += delta*delta2; - } - } - - /** Useful for uploading CSV files to SQL databases. - * - * Return a data type for each column such that every value in a column can be - * converted to the corresponding data type without data loss. - * @param[in] filename The CSV file - * - * \return A mapping of column names to csv::DataType enums - */ - CSV_INLINE std::unordered_map csv_data_types(const std::string& filename) { - CSVStat stat(filename); - std::unordered_map csv_dtypes; - - auto col_names = stat.get_col_names(); - auto temp = stat.get_dtypes(); - - for (size_t i = 0; i < stat.get_col_names().size(); i++) { - auto& col = temp[i]; - auto& col_name = col_names[i]; - - if (col[DataType::CSV_STRING]) - csv_dtypes[col_name] = DataType::CSV_STRING; - else if (col[DataType::CSV_INT64]) - csv_dtypes[col_name] = DataType::CSV_INT64; - else if (col[DataType::CSV_INT32]) - csv_dtypes[col_name] = DataType::CSV_INT32; - else if (col[DataType::CSV_INT16]) - csv_dtypes[col_name] = DataType::CSV_INT16; - else if (col[DataType::CSV_INT8]) - csv_dtypes[col_name] = DataType::CSV_INT8; - else - csv_dtypes[col_name] = DataType::CSV_DOUBLE; - } - - return csv_dtypes; - } -} -#include -#include - - -namespace csv { - /** Shorthand function for parsing an in-memory CSV string - * - * @return A collection of CSVRow objects - * - * @par Example - * @snippet tests/test_read_csv.cpp Parse Example - */ - CSV_INLINE CSVReader parse(csv::string_view in, CSVFormat format) { - std::stringstream stream(in.data()); - return CSVReader(stream, format); - } - - /** Parses a CSV string with no headers - * - * @return A collection of CSVRow objects - */ - CSV_INLINE CSVReader parse_no_header(csv::string_view in) { - CSVFormat format; - format.header_row(-1); - - return parse(in, format); - } - - /** Parse a RFC 4180 CSV string, returning a collection - * of CSVRow objects - * - * @par Example - * @snippet tests/test_read_csv.cpp Escaped Comma - * - */ - CSV_INLINE CSVReader operator ""_csv(const char* in, size_t n) { - return parse(csv::string_view(in, n)); - } - - /** A shorthand for csv::parse_no_header() */ - CSV_INLINE CSVReader operator ""_csv_no_header(const char* in, size_t n) { - return parse_no_header(csv::string_view(in, n)); - } - - /** - * Find the position of a column in a CSV file or CSV_NOT_FOUND otherwise - * - * @param[in] filename Path to CSV file - * @param[in] col_name Column whose position we should resolve - * @param[in] format Format of the CSV file - */ - CSV_INLINE int get_col_pos( - csv::string_view filename, - csv::string_view col_name, - const CSVFormat& format) { - CSVReader reader(filename, format); - return reader.index_of(col_name); - } - - /** Get basic information about a CSV file - * @include programs/csv_info.cpp - */ - CSV_INLINE CSVFileInfo get_file_info(const std::string& filename) { - CSVReader reader(filename); - CSVFormat format = reader.get_format(); - for (auto it = reader.begin(); it != reader.end(); ++it); - - CSVFileInfo info = { - filename, - reader.get_col_names(), - format.get_delim(), - reader.n_rows(), - reader.get_col_names().size() - }; - - return info; - } -} - - -#endif diff --git a/hook_lib/functions.cpp b/hook_lib/functions.cpp index be31eb9..53f627d 100644 --- a/hook_lib/functions.cpp +++ b/hook_lib/functions.cpp @@ -1,379 +1,406 @@ -#include "functions.hpp" - -void* RtlAddVectoredExceptionHandler(LONG First, PVECTORED_EXCEPTION_HANDLER Handler) { - utils::nt::library ntdll("ntdll.dll"); - ntdll.invoke("RtlAddVectoredExceptionHandler", First, Handler); - return nullptr; -} - -NTSTATUS NtContinue(PCONTEXT threadContext, BOOLEAN raiseAlert) { - utils::nt::library ntdll("ntdll.dll"); - return ntdll.invoke("NtContinue", threadContext, raiseAlert); -} - -#pragma region //game functions - -const char* (*va)(const char* fmt, ...); - -void Live_FakeUserSignIn(int controllerIndex, const char* gamertag) { - auto func = reinterpret_cast(0x1413FDA40_g); - func(controllerIndex, gamertag); -} - -void R_AddCmdDrawText(const char* text, int maxChars, void /* GfxFont */* font, int fontHeight, float x, float y, float xScale, float yScale, float rotation, const float* color, const void /* FontGlowStyle */* glowStyle, bool usePost) { - auto func = reinterpret_cast(0x00000001419653E0_g); - func(text, maxChars, font, fontHeight, x, y, xScale, yScale, rotation, color, glowStyle, usePost); -} - -bool CG_WorldPosToScreenPosReal(int localClientNum, const uintptr_t scrPlace, const float* worldPos, float* outScreenPos) { - auto func = reinterpret_cast(0x141696AA0_g); - return func(localClientNum, scrPlace, worldPos, outScreenPos); -} - -void CG_DrawRotatedPicPhysical(uintptr_t scrPlace, float x, float y, float width, float height, float angle, const float* color, uintptr_t material) { - auto func = reinterpret_cast(0x141695B20_g); - func(scrPlace, x, y, width, height, angle, color, material); -} - -uintptr_t FS_ReadFile(const char* qpath, const char** buffer) { - auto func = reinterpret_cast(0x1413DA530_g); - return func(qpath, buffer); -} - -const char* Dvar_GetStringSafe(const char* dvar) { - auto func = reinterpret_cast(0x1413E69B0_g); - return func(dvar); -} - -unsigned int* GetRandSeed() { - auto func = reinterpret_cast(0x1413DD630_g); - return func(); -} - -unsigned __int64 Sys_Microseconds() { - auto func = reinterpret_cast(0x14148FC10_g); - return func(); -} - -int I_irand(int min, int max) { - auto func = reinterpret_cast(0x1413DD8B0_g); - return func(min, max); -} - -unsigned __int64 I_atoui64_hex(const char* str) { - auto func = reinterpret_cast(0x1413F3310_g); - return func(str); -} - -unsigned __int64 I_atoui64(const char* str) { - auto func = reinterpret_cast(0x1413F3300_g); - return func(str); -} - -uintptr_t Dvar_FindVarByName(const char* dvarName) { - auto func = reinterpret_cast(0x1413E63A0_g); - return func(dvarName); -} - -void CL_DrawText(const uintptr_t scrPlace, const char* text, int maxChars, uintptr_t font, float x, float y, int horzAlign, int vertAlign, float xScale, float yScale, const float* color, int style) { - auto func = reinterpret_cast(0x1415AAAA0_g); - func(scrPlace, text, maxChars, font, x, y, horzAlign, vertAlign, xScale, yScale, color, style); -} - -dvar_t* Dvar_RegisterString(const char* dvarName, const char* value, unsigned int flags, const char* description) { - auto func = reinterpret_cast(0x1413E7A70_g); - return func(dvarName, value, flags, description); -} - -dvar_t* Dvar_RegisterBool(const char* dvarName, bool value, unsigned int flags, const char* description) { - auto func = reinterpret_cast(0x1413E7670_g); - return func(dvarName, value, flags, description); -} - -void LUI_CoD_LuaCall_ExecNow(uintptr_t luaVM, const char* str) { - lua_getfield(luaVM, -10002, "Engine"); - lua_getfield(luaVM, -1, "DAGFFDGFII"); - lua_remove(luaVM, -2); - lua_pushstring(luaVM, str); - LuaShared_PCall(luaVM, 1, 1); -} - -bool LUI_LuaCall_Game_IsEntityAlive(uintptr_t luaVM, int entityNum) { - lua_getfield(luaVM, -10002, "Game"); - lua_getfield(luaVM, -1, "JDAIJCDEB"); - lua_remove(luaVM, -2); - lua_pushinteger(luaVM, 0); - lua_pushinteger(luaVM, entityNum); - LuaShared_PCall(luaVM, 2, 1); - return lua_toboolean(luaVM, 0); -} - -void Cbuf_AddText(const char* cmd) { - uintptr_t luaVM = *reinterpret_cast(0x151868880_g); - if (luaVM) { - LUI_CoD_LuaCall_ExecNow(luaVM, cmd); - } -} - -bool lua_toboolean(uintptr_t L, int idx) { - auto func = reinterpret_cast(0x1420848D0_g); - return func(L, idx); -} - -void lua_pushboolean(uintptr_t L, int b) { - auto func = reinterpret_cast(0x142083E80_g); - func(L, b); -} - -void lua_remove(uintptr_t L, int idx) { - auto func = reinterpret_cast(0x142084420_g); - func(L, idx); -} - -void lua_call(uintptr_t L, int nargs, int nresults) { - auto func = reinterpret_cast(0x1420831D0_g); - func(L, nargs, nresults); -} - -void lua_getfield(uintptr_t L, int idx, const char* k) { - auto func = reinterpret_cast(0x1420836E0_g); - func(L, idx, k); -} - -void lua_pushvalue(uintptr_t L, int idx) { - auto func = reinterpret_cast(0x142084200_g); - func(L, idx); -} - -void lua_pushstring(uintptr_t L, const char* str) { - auto func = reinterpret_cast(0x142084120_g); - func(L, str); -} - -void lua_pushinteger(uintptr_t L, int n) { - auto func = reinterpret_cast(0x142083FE0_g); - func(L, n); -} - -void lua_settop(uintptr_t L, int idx) { - auto func = reinterpret_cast(0x142084790_g); - func(L, idx); -} - -int LuaShared_PCall(uintptr_t luaVM, int nargs, int nresults) { - auto func = reinterpret_cast(0x1419B7570_g); - return func(luaVM, nargs, nresults); -} - -bool CG_DObjGetWorldBoneMatrix(uintptr_t pose, uintptr_t obj, int boneIndex, uintptr_t outTagMat, float* outOrigin) { - auto func = reinterpret_cast(0x1416A59D0_g); - return func(pose, obj, boneIndex, outTagMat, outOrigin); -} - -void CG_DrawLine(float X1, float Y1, float X2, float Y2, const float* color, float Width) { - float X, Y, Angle, L1, L2, H1; - H1 = Y2 - Y1; - L1 = X2 - X1; - L2 = sqrtf(L1 * L1 + H1 * H1); - X = X1 + ((L1 - L2) / 2); - Y = Y1 + (H1 / 2); - Angle = atan(H1 / L1) * (180 / 3.14159265358979323846); - CG_DrawRotatedPicPhysical(0x14EF2DEA0_g, X, Y, L2, Width, Angle, color, *reinterpret_cast(0x152C465A0_g)); -} - -void CG_DrawBone(int entIndex, uintptr_t ent, int from, int to, const float* color) { - float bone1[3], bone2[3]; - float fromPos[2], toPos[2]; - char tmat33[0x24]; - short* clientObjMap = (short*)(0x14D45EC60_g); - uintptr_t s_objBuf = *reinterpret_cast(0x14D45EC50_g); - uintptr_t dobj = s_objBuf + (0x150 * clientObjMap[entIndex]); - if (CG_DObjGetWorldBoneMatrix(ent, dobj, from, (uintptr_t)&tmat33, bone1) && CG_DObjGetWorldBoneMatrix(ent, dobj, to, (uintptr_t)&tmat33, bone2)) { - if (CG_WorldPosToScreenPosReal(0, 0x14EF2DEA0_g, bone1, fromPos) && CG_WorldPosToScreenPosReal(0, 0x14EF2DEA0_g, bone2, toPos)) { - CG_DrawLine(fromPos[0], fromPos[1], toPos[0], toPos[1], color, 1); - } - } -} - -void CG_DrawBones(int entIndex, uintptr_t ent, const float* color) { - //spine - CG_DrawBone(entIndex, ent, 41, 35, color); - CG_DrawBone(entIndex, ent, 35, 7, color); - CG_DrawBone(entIndex, ent, 7, 6, color); - CG_DrawBone(entIndex, ent, 6, 30, color); - CG_DrawBone(entIndex, ent, 30, 55, color); - CG_DrawBone(entIndex, ent, 55, 54, color); - CG_DrawBone(entIndex, ent, 54, 53, color); - CG_DrawBone(entIndex, ent, 53, 2, color); - - //hips - CG_DrawBone(entIndex, ent, 2, 63, color); - CG_DrawBone(entIndex, ent, 2, 64, color); -} - -bool CheatsOk(int entNum) { - SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * entNum)); - uintptr_t client = g_entities[entNum].get(0x150); - if (sv_cheats->current.enabled) { - return true; - } - else { - ms_clients->SendServerCommand(1, "f \"Cheats are not enabled on this server!\""); - return false; - } -} - -//ingame removed functions -void Cmd_Noclip_f(int entNum) -{ - SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * entNum)); - uintptr_t client = g_entities[entNum].get(0x150); - if (client) { - int v6 = *reinterpret_cast(client + 0x5DD0); - if ((*reinterpret_cast(client + 0x5DD0) & 1) != 0) { - v6 = *reinterpret_cast(client + 0x5DD0) & 0xFFFFFFFE; - ms_clients->SendServerCommand(1, "f \"Noclip: ^1OFF\""); - } - else { - v6 = *reinterpret_cast(client + 0x5DD0) | 1; - ms_clients->SendServerCommand(1, "f \"Noclip: ^2ON\""); - } - *reinterpret_cast(client + 0x5DD0) = v6; - } -} - -void SV_Cmd_ArgvBuffer(int arg, char* buffer, unsigned __int64 bufferLength) { - auto func = reinterpret_cast(0x141298B40_g); - func(arg, buffer, bufferLength); -} - -void Cmd_ArgvBuffer(int arg, char* buffer, int bufferLength) { - if (arg >= cmd_args->argc[cmd_args->nesting]) - strcpy_s(buffer, bufferLength, ""); - else - strcpy_s(buffer, bufferLength, cmd_args->argv[cmd_args->nesting][arg]); -} - -int Cmd_Argc() { - return cmd_args->argc[cmd_args->nesting]; -} - -int SV_Cmd_Argc() { - auto func = reinterpret_cast(0x141298AF0_g); - return func(); -} - -void Cmd_AddCommandInternal(const char* cmdName, void(__fastcall* function)(), cmd_function_s* allocedCmd) { - auto func = reinterpret_cast(0x1412965F0_g); - func(cmdName, function, allocedCmd); -} - -ClActiveClient* GetClActiveClient() { - ms_activeClients = *reinterpret_cast(0x14EE854F8_g); - return ms_activeClients; -} - -int ClActiveClient_GetCmdNumber(ClActiveClient* activeClient) { - return activeClient->cmdNumber ^ ((activeClient->get(0x8700) ^ (activeClient->cmdNumber) * ((activeClient->get(0x8700) ^ activeClient->cmdNumber) + 2))); -} - -usercmd_s* CL_GetUserCmd(int cmdNumber) { - ms_activeClients = *reinterpret_cast(0x14EE854F8_g); - return &ms_activeClients->cmds[cmdNumber & 0x7F]; -} - -void AddReliableCommand(uintptr_t _this, const char* commandBuffer, const int reliableCmdSize, int type) { - auto func = reinterpret_cast(0x1415E0440_g); - func(_this, commandBuffer, reliableCmdSize, type); -} - -unsigned int MSG_WriteReliableCommandToBuffer(const char* pszCommand, char* pszBuffer, unsigned int iBufferSize) { - auto func = reinterpret_cast(0x1412DDBF0_g); - return func(pszCommand, pszBuffer, iBufferSize); -} - -void CL_Main_AddReliableCommand(const char* cmd) { - uintptr_t ms_connections = *reinterpret_cast(0x14EE85570_g); - char buf[1024]; - int cmdSize = MSG_WriteReliableCommandToBuffer(cmd, buf, 1024); - AddReliableCommand(ms_connections, buf, cmdSize, 0); -} - -bool BG_Weapons_GetFullWeaponForName(const char* name, Weapon* outWeapon, Weapon* (*getWeaponFunc)(Weapon* result, const char*)) { - auto func = reinterpret_cast(0x141158130_g); - return func(name, outWeapon, getWeaponFunc); -} - -void Scr_AddString(scrContext_t* scrContext, const char* value) { - auto func = reinterpret_cast(0x141322D90_g); - func(scrContext, value); -} - -unsigned int GScr_ExecEntThread(gentity_s* ent, int handle, unsigned int paramcount) { - auto func = reinterpret_cast(0x141257D70_g); - return func(ent, handle, paramcount); -} - -void Scr_FreeThread(scrContext_t* scrContext, unsigned int handle) { - auto func = reinterpret_cast(0x1413242E0_g); - func(scrContext, handle); -} - -int G_Weapon_GivePlayerWeapon(uintptr_t ps, uintptr_t scrContext, Weapon* weapon, int dualWield, int startInAltMode, int usedBefore) { - auto func = reinterpret_cast(0x14127C8B0_g); - return func(ps, scrContext, weapon, dualWield, startInAltMode, usedBefore); -} - -void G_Items_AddAmmo(uintptr_t ps, Weapon* weapon, bool isAlternate, int count, int fillClip) { - auto func = reinterpret_cast(0x141216860_g); - func(ps, weapon, isAlternate, count, fillClip); -} - -void G_Weapon_SelectWeapon(int clientNum, Weapon* weapon) { - auto func = reinterpret_cast(0x14127F840_g); -} - -Weapon* BG_FindBaseWeaponForName(Weapon* result, const char* name) { - auto func = reinterpret_cast(0x1411570F0_g); - return func(result, name); -} - -scrContext_t* ScriptContext_Server() { - auto func = reinterpret_cast(0x1412E0E70_g); - return func(); -} - -const char* SL_ConvertToString(int id) { - auto func = reinterpret_cast(0x14131AA20_g); - return func(id); -} - -XAssetHeader DB_FindXAssetHeader(XAssetType type, const char* givenName, int allowCreateDefault) { - auto func = reinterpret_cast(0x1411AA890_g); - return func(type, givenName, allowCreateDefault); -} - -#pragma endregion - -dvar_t* player_name; -dvar_t* sv_cheats; -dvar_t* spawn_br_gas; -dvar_t* show_watermark; -dvar_t* player_sustainammo; - -cmd_function_s set_byte_f_VAR; -cmd_function_s set_short_f_VAR; -cmd_function_s set_int_f_VAR; -cmd_function_s set_pointer_f_VAR; -cmd_function_s quit_f_VAR; -cmd_function_s openmenu_f_VAR; -cmd_function_s addbot_f_VAR; -cmd_function_s ddldump_f_VAR; -cmd_function_s weapondefdump_f_VAR; -cmd_function_s view_vehicle_ents_f_VAR; -cmd_function_s loadout_save_f_VAR; -cmd_function_s FastRestart_f_VAR; - -CmdArgs* cmd_args; - +#include "functions.hpp" + +void* RtlAddVectoredExceptionHandler(LONG First, PVECTORED_EXCEPTION_HANDLER Handler) { + utils::nt::library ntdll("ntdll.dll"); + ntdll.invoke("RtlAddVectoredExceptionHandler", First, Handler); + return nullptr; +} + +NTSTATUS NtContinue(PCONTEXT threadContext, BOOLEAN raiseAlert) { + utils::nt::library ntdll("ntdll.dll"); + return ntdll.invoke("NtContinue", threadContext, raiseAlert); +} + +#pragma region //game functions + +const char* (*va)(const char* fmt, ...); + +void Live_FakeUserSignIn(int controllerIndex, const char* gamertag) { + auto func = reinterpret_cast(0x1413FDA40_g); + func(controllerIndex, gamertag); +} + +void R_AddCmdDrawText(const char* text, int maxChars, void /* GfxFont */* font, int fontHeight, float x, float y, float xScale, float yScale, float rotation, const float* color, const void /* FontGlowStyle */* glowStyle, bool usePost) { + auto func = reinterpret_cast(0x00000001419653E0_g); + func(text, maxChars, font, fontHeight, x, y, xScale, yScale, rotation, color, glowStyle, usePost); +} + +bool CG_WorldPosToScreenPosReal(int localClientNum, const uintptr_t scrPlace, const float* worldPos, float* outScreenPos) { + auto func = reinterpret_cast(0x141696AA0_g); + return func(localClientNum, scrPlace, worldPos, outScreenPos); +} + +void CG_DrawRotatedPicPhysical(uintptr_t scrPlace, float x, float y, float width, float height, float angle, const float* color, uintptr_t material) { + auto func = reinterpret_cast(0x141695B20_g); + func(scrPlace, x, y, width, height, angle, color, material); +} + +uintptr_t FS_ReadFile(const char* qpath, const char** buffer) { + auto func = reinterpret_cast(0x1413DA530_g); + return func(qpath, buffer); +} + +const char* Dvar_GetStringSafe(const char* dvar) { + auto func = reinterpret_cast(0x1413E69B0_g); + return func(dvar); +} + +bool Dvar_GetBoolSafe(const char* dvar) +{ + auto func = reinterpret_cast(0x1413E6820_g); + return func(dvar); +} + +int Dvar_GetIntSafe(const char* dvar) +{ + auto func = reinterpret_cast(0x1413E6960_g); + return func(dvar); +} + +unsigned int* GetRandSeed() { + auto func = reinterpret_cast(0x1413DD630_g); + return func(); +} + +unsigned __int64 Sys_Microseconds() { + auto func = reinterpret_cast(0x14148FC10_g); + return func(); +} + +int I_irand(int min, int max) { + auto func = reinterpret_cast(0x1413DD8B0_g); + return func(min, max); +} + +unsigned __int64 I_atoui64_hex(const char* str) { + auto func = reinterpret_cast(0x1413F3310_g); + return func(str); +} + +unsigned __int64 I_atoui64(const char* str) { + auto func = reinterpret_cast(0x1413F3300_g); + return func(str); +} + +uintptr_t Dvar_FindVarByName(const char* dvarName) { + auto func = reinterpret_cast(0x1413E63A0_g); + return func(dvarName); +} + +void CL_DrawText(const uintptr_t scrPlace, const char* text, int maxChars, uintptr_t font, float x, float y, int horzAlign, int vertAlign, float xScale, float yScale, const float* color, int style) { + auto func = reinterpret_cast(0x1415AAAA0_g); + func(scrPlace, text, maxChars, font, x, y, horzAlign, vertAlign, xScale, yScale, color, style); +} + +dvar_t* Dvar_RegisterString(const char* dvarName, const char* value, unsigned int flags, const char* description) { + auto func = reinterpret_cast(0x1413E7A70_g); + return func(dvarName, value, flags, description); +} + +dvar_t* Dvar_RegisterBool(const char* dvarName, bool value, unsigned int flags, const char* description) { + auto func = reinterpret_cast(0x1413E7670_g); + return func(dvarName, value, flags, description); +} + +void LUI_CoD_LuaCall_ExecNow(uintptr_t luaVM, const char* str) { + lua_getfield(luaVM, -10002, "Engine"); + lua_getfield(luaVM, -1, "DAGFFDGFII"); + lua_remove(luaVM, -2); + lua_pushstring(luaVM, str); + LuaShared_PCall(luaVM, 1, 1); +} + +bool LUI_LuaCall_Game_IsEntityAlive(uintptr_t luaVM, int entityNum) { + lua_getfield(luaVM, -10002, "Game"); + lua_getfield(luaVM, -1, "JDAIJCDEB"); + lua_remove(luaVM, -2); + lua_pushinteger(luaVM, 0); + lua_pushinteger(luaVM, entityNum); + LuaShared_PCall(luaVM, 2, 1); + return lua_toboolean(luaVM, 0); +} + +void Cbuf_AddText(const char* cmd) { + uintptr_t luaVM = *reinterpret_cast(0x151868880_g); + if (luaVM) { + LUI_CoD_LuaCall_ExecNow(luaVM, cmd); + } +} + +bool lua_toboolean(uintptr_t L, int idx) { + auto func = reinterpret_cast(0x1420848D0_g); + return func(L, idx); +} + +void lua_pushboolean(uintptr_t L, int b) { + auto func = reinterpret_cast(0x142083E80_g); + func(L, b); +} + +void lua_remove(uintptr_t L, int idx) { + auto func = reinterpret_cast(0x142084420_g); + func(L, idx); +} + +void lua_call(uintptr_t L, int nargs, int nresults) { + auto func = reinterpret_cast(0x1420831D0_g); + func(L, nargs, nresults); +} + +void lua_getfield(uintptr_t L, int idx, const char* k) { + auto func = reinterpret_cast(0x1420836E0_g); + func(L, idx, k); +} + +void lua_pushvalue(uintptr_t L, int idx) { + auto func = reinterpret_cast(0x142084200_g); + func(L, idx); +} + +void lua_pushstring(uintptr_t L, const char* str) { + auto func = reinterpret_cast(0x142084120_g); + func(L, str); +} + +void lua_pushinteger(uintptr_t L, int n) { + auto func = reinterpret_cast(0x142083FE0_g); + func(L, n); +} + +void lua_settop(uintptr_t L, int idx) { + auto func = reinterpret_cast(0x142084790_g); + func(L, idx); +} + +int LuaShared_PCall(uintptr_t luaVM, int nargs, int nresults) { + auto func = reinterpret_cast(0x1419B7570_g); + return func(luaVM, nargs, nresults); +} + +bool CG_DObjGetWorldBoneMatrix(uintptr_t pose, uintptr_t obj, int boneIndex, uintptr_t outTagMat, float* outOrigin) { + auto func = reinterpret_cast(0x1416A59D0_g); + return func(pose, obj, boneIndex, outTagMat, outOrigin); +} + +void CG_DrawLine(float X1, float Y1, float X2, float Y2, const float* color, float Width) { + float X, Y, Angle, L1, L2, H1; + H1 = Y2 - Y1; + L1 = X2 - X1; + L2 = sqrtf(L1 * L1 + H1 * H1); + X = X1 + ((L1 - L2) / 2); + Y = Y1 + (H1 / 2); + Angle = atan(H1 / L1) * (180 / 3.14159265358979323846); + CG_DrawRotatedPicPhysical(0x14EF2DEA0_g, X, Y, L2, Width, Angle, color, *reinterpret_cast(0x152C465A0_g)); +} + +void CG_DrawBone(int entIndex, uintptr_t ent, int from, int to, const float* color) { + float bone1[3], bone2[3]; + float fromPos[2], toPos[2]; + char tmat33[0x24]; + short* clientObjMap = (short*)(0x14D45EC60_g); + uintptr_t s_objBuf = *reinterpret_cast(0x14D45EC50_g); + uintptr_t dobj = s_objBuf + (0x150 * clientObjMap[entIndex]); + if (CG_DObjGetWorldBoneMatrix(ent, dobj, from, (uintptr_t)&tmat33, bone1) && CG_DObjGetWorldBoneMatrix(ent, dobj, to, (uintptr_t)&tmat33, bone2)) { + if (CG_WorldPosToScreenPosReal(0, 0x14EF2DEA0_g, bone1, fromPos) && CG_WorldPosToScreenPosReal(0, 0x14EF2DEA0_g, bone2, toPos)) { + CG_DrawLine(fromPos[0], fromPos[1], toPos[0], toPos[1], color, 1); + } + } +} + +void CG_DrawBones(int entIndex, uintptr_t ent, const float* color) { + //spine + CG_DrawBone(entIndex, ent, 41, 35, color); + CG_DrawBone(entIndex, ent, 35, 7, color); + CG_DrawBone(entIndex, ent, 7, 6, color); + CG_DrawBone(entIndex, ent, 6, 30, color); + CG_DrawBone(entIndex, ent, 30, 55, color); + CG_DrawBone(entIndex, ent, 55, 54, color); + CG_DrawBone(entIndex, ent, 54, 53, color); + CG_DrawBone(entIndex, ent, 53, 2, color); + + //hips + CG_DrawBone(entIndex, ent, 2, 63, color); + CG_DrawBone(entIndex, ent, 2, 64, color); +} + +bool CheatsOk(int entNum) { + SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * entNum)); + uintptr_t client = g_entities[entNum].get(0x150); + if (sv_cheats->current.enabled) { + return true; + } + else { + ms_clients->SendServerCommand(1, "f \"Cheats are not enabled on this server!\""); + return false; + } +} + +//ingame removed functions +void Cmd_Noclip_f(int entNum) +{ + SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * entNum)); + uintptr_t client = g_entities[entNum].get(0x150); + if (client) { + int v6 = *reinterpret_cast(client + 0x5DD0); + if ((*reinterpret_cast(client + 0x5DD0) & 1) != 0) { + v6 = *reinterpret_cast(client + 0x5DD0) & 0xFFFFFFFE; + ms_clients->SendServerCommand(1, "f \"Noclip: ^1OFF\""); + } + else { + v6 = *reinterpret_cast(client + 0x5DD0) | 1; + ms_clients->SendServerCommand(1, "f \"Noclip: ^2ON\""); + } + *reinterpret_cast(client + 0x5DD0) = v6; + } +} + +void Cmd_God_f(int entNum) +{ + SvClient* ms_clients = *reinterpret_cast(0x14E17F690_g + (8 * entNum)); + gentity_s ent = g_entities[entNum]; +} + +void SV_Cmd_ArgvBuffer(int arg, char* buffer, unsigned __int64 bufferLength) { + auto func = reinterpret_cast(0x141298B40_g); + func(arg, buffer, bufferLength); +} + +void Cmd_ArgvBuffer(int arg, char* buffer, int bufferLength) { + if (arg >= cmd_args->argc[cmd_args->nesting]) + strcpy_s(buffer, bufferLength, ""); + else + strcpy_s(buffer, bufferLength, cmd_args->argv[cmd_args->nesting][arg]); +} + +int Cmd_Argc() { + return cmd_args->argc[cmd_args->nesting]; +} + +int SV_Cmd_Argc() { + auto func = reinterpret_cast(0x141298AF0_g); + return func(); +} + +void Cmd_AddCommandInternal(const char* cmdName, void(__fastcall* function)(), cmd_function_s* allocedCmd) { + auto func = reinterpret_cast(0x1412965F0_g); + func(cmdName, function, allocedCmd); +} + +ClActiveClient* GetClActiveClient() { + ms_activeClients = *reinterpret_cast(0x14EE854F8_g); + return ms_activeClients; +} + +int ClActiveClient_GetCmdNumber(ClActiveClient* activeClient) { + return activeClient->cmdNumber ^ ((activeClient->get(0x8700) ^ (activeClient->cmdNumber) * ((activeClient->get(0x8700) ^ activeClient->cmdNumber) + 2))); +} + +usercmd_s* CL_GetUserCmd(int cmdNumber) { + ms_activeClients = *reinterpret_cast(0x14EE854F8_g); + return &ms_activeClients->cmds[cmdNumber & 0x7F]; +} + +void AddReliableCommand(uintptr_t _this, const char* commandBuffer, const int reliableCmdSize, int type) { + auto func = reinterpret_cast(0x1415E0440_g); + func(_this, commandBuffer, reliableCmdSize, type); +} + +unsigned int MSG_WriteReliableCommandToBuffer(const char* pszCommand, char* pszBuffer, unsigned int iBufferSize) { + auto func = reinterpret_cast(0x1412DDBF0_g); + return func(pszCommand, pszBuffer, iBufferSize); +} + +void CL_Main_AddReliableCommand(const char* cmd) { + uintptr_t ms_connections = *reinterpret_cast(0x14EE85570_g); + char buf[1024]; + int cmdSize = MSG_WriteReliableCommandToBuffer(cmd, buf, 1024); + AddReliableCommand(ms_connections, buf, cmdSize, 0); +} + +bool BG_Weapons_GetFullWeaponForName(const char* name, Weapon* outWeapon, Weapon* (*getWeaponFunc)(Weapon* result, const char*)) { + auto func = reinterpret_cast(0x141158130_g); + return func(name, outWeapon, getWeaponFunc); +} + +void Scr_AddString(scrContext_t* scrContext, const char* value) { + auto func = reinterpret_cast(0x141322D90_g); + func(scrContext, value); +} + +unsigned int GScr_ExecEntThread(gentity_s* ent, int handle, unsigned int paramcount) { + auto func = reinterpret_cast(0x141257D70_g); + return func(ent, handle, paramcount); +} + +void Scr_FreeThread(scrContext_t* scrContext, unsigned int handle) { + auto func = reinterpret_cast(0x1413242E0_g); + func(scrContext, handle); +} + +int G_Weapon_GivePlayerWeapon(uintptr_t ps, uintptr_t scrContext, Weapon* weapon, int dualWield, int startInAltMode, int usedBefore) { + auto func = reinterpret_cast(0x14127C8B0_g); + return func(ps, scrContext, weapon, dualWield, startInAltMode, usedBefore); +} + +void G_Items_AddAmmo(uintptr_t ps, Weapon* weapon, bool isAlternate, int count, int fillClip) { + auto func = reinterpret_cast(0x141216860_g); + func(ps, weapon, isAlternate, count, fillClip); +} + +void G_Weapon_SelectWeapon(int clientNum, Weapon* weapon) { + auto func = reinterpret_cast(0x14127F840_g); +} + +Weapon* BG_FindBaseWeaponForName(Weapon* result, const char* name) { + auto func = reinterpret_cast(0x1411570F0_g); + return func(result, name); +} + +scrContext_t* ScriptContext_Server() { + auto func = reinterpret_cast(0x1412E0E70_g); + return func(); +} + +const char* SL_ConvertToString(int id) { + auto func = reinterpret_cast(0x14131AA20_g); + return func(id); +} + +XAssetHeader DB_FindXAssetHeader(XAssetType type, const char* givenName, int allowCreateDefault) { + auto func = reinterpret_cast(0x1411AA890_g); + return func(type, givenName, allowCreateDefault); +} + +void Com_SetErrorMessage(const char* errorMessage) { + auto func = reinterpret_cast(0x1412B3710_g); + return func(errorMessage); +} + +#pragma endregion + +dvar_t* player_name; +dvar_t* sv_cheats; +dvar_t* spawn_br_gas; +dvar_t* show_watermark; +dvar_t* player_sustainammo; + +cmd_function_s set_byte_f_VAR; +cmd_function_s set_short_f_VAR; +cmd_function_s set_int_f_VAR; +cmd_function_s set_float_f_VAR; +cmd_function_s set_pointer_f_VAR; +cmd_function_s quit_f_VAR; +cmd_function_s openmenu_f_VAR; +cmd_function_s addbot_f_VAR; +cmd_function_s ddldump_f_VAR; +cmd_function_s weapondefdump_f_VAR; +cmd_function_s view_vehicle_ents_f_VAR; +cmd_function_s loadout_save_f_VAR; +cmd_function_s FastRestart_f_VAR; +cmd_function_s MapRestart_f_VAR; +cmd_function_s omnvar_set_f_VAR; +cmd_function_s omnvar_dump_f_VAR; + +CmdArgs* cmd_args; + Addresses g_Addrs; \ No newline at end of file diff --git a/hook_lib/functions.hpp b/hook_lib/functions.hpp index 9eca864..9d646c7 100644 --- a/hook_lib/functions.hpp +++ b/hook_lib/functions.hpp @@ -1,224 +1,234 @@ -#pragma once -#include "Main.hpp" - -struct gentity_s; - -struct CmdArgs; - -struct Addresses { - uintptr_t ModuleBase; - uintptr_t jmp_rbx; -}; - -union DvarValue -{ - bool enabled; - int integer; - unsigned int unsignedInt; - __int64 integer64; - unsigned __int64 unsignedInt64; - float value; - float vector[4]; - const char* string; - unsigned __int8 color[4]; -}; - -struct BbConstUsageFlags -{ - bool initialized; - DvarValue codeValue; -}; - -struct netadr_t; - -struct dvar_t -{ - const char* name; - unsigned int checksum; - const char* description; - unsigned int flags; - char level[1]; - unsigned __int8 type; - bool modified; - unsigned __int16 hashNext; - DvarValue current; - DvarValue latched; - DvarValue reset; - char domain[0x10]; - BbConstUsageFlags BbConstUsageFlags; -}; - -struct EncryptionHeader -{ - unsigned int isEncrypted; - unsigned __int8 IV[16]; -}; - -struct __declspec(align(8)) XFile -{ - unsigned __int64 size; - unsigned __int64 preloadWalkSize; - unsigned __int64 blockSize[11]; - EncryptionHeader encryption; -}; - -struct DB_FFHeader -{ - unsigned __int64 magic; - unsigned int headerVersion; - unsigned int xfileVersion; - bool dashCompressBuild; - bool dashEncryptBuild; - unsigned __int8 transientFileType[1]; - unsigned int residentPartSize; - unsigned int residentHash; - unsigned int alwaysLoadedPartSize; - XFile xfileHeader; -}; - -struct EncryptionInfo -{ - EncryptionHeader header; - unsigned __int8 privateKey[32]; -}; - -struct DBFileHandle -{ - unsigned __int8 fileID[4]; - unsigned __int64 dcacheFileID; -}; - -struct cmd_function_s -{ - cmd_function_s* next; - const char* name; - const char** autoCompleteList; - unsigned int autoCompleteListCount; - void(__fastcall* function)(); -}; - -struct DBFile -{ - char name[64]; - DBFileHandle dbFileHandle; - bool isSecured; - EncryptionInfo encryption; -}; - -struct Weapon; -struct scrContext_t; - -extern dvar_t* player_name; -extern dvar_t* sv_cheats; -extern dvar_t* spawn_br_gas; -extern dvar_t* show_watermark; -extern dvar_t* player_sustainammo; - -extern cmd_function_s set_byte_f_VAR; -extern cmd_function_s set_short_f_VAR; -extern cmd_function_s set_int_f_VAR; -extern cmd_function_s set_pointer_f_VAR; -extern cmd_function_s quit_f_VAR; -extern cmd_function_s openmenu_f_VAR; -extern cmd_function_s addbot_f_VAR; -extern cmd_function_s ddldump_f_VAR; -extern cmd_function_s weapondefdump_f_VAR; -extern cmd_function_s view_vehicle_ents_f_VAR; -extern cmd_function_s loadout_save_f_VAR; -extern cmd_function_s FastRestart_f_VAR; -extern CmdArgs* cmd_args; - -void* RtlAddVectoredExceptionHandler(LONG First, PVECTORED_EXCEPTION_HANDLER Handler); -NTSTATUS NtContinue(PCONTEXT threadContext, BOOLEAN raiseAlert); - -#pragma region //game functions - -extern const char* (*va)(const char* fmt, ...); - -void Live_FakeUserSignIn(int controllerIndex, const char* gamertag); - -void R_AddCmdDrawText(const char* text, int maxChars, void /* GfxFont */* font, int fontHeight, float x, float y, float xScale, float yScale, float rotation, const float* color, const void /* FontGlowStyle */* glowStyle, bool usePost); - -bool CG_WorldPosToScreenPosReal(int localClientNum, const uintptr_t scrPlace, const float* worldPos, float* outScreenPos); - -void CG_DrawRotatedPicPhysical(uintptr_t scrPlace, float x, float y, float width, float height, float angle, const float* color, uintptr_t material); - -inline bool file_exists(const char* name) { - struct stat buffer; - return (stat(name, &buffer) == 0); -} - -uintptr_t FS_ReadFile(const char* qpath, const char** buffer); -const char* Dvar_GetStringSafe(const char* dvar); - -unsigned int* GetRandSeed(); -unsigned __int64 Sys_Microseconds(); -int I_irand(int min, int max); -unsigned __int64 I_atoui64_hex(const char* str); -unsigned __int64 I_atoui64(const char* str); -uintptr_t Dvar_FindVarByName(const char* dvarName); - -void CL_DrawText(const uintptr_t scrPlace, const char* text, int maxChars, uintptr_t font, float x, float y, int horzAlign, int vertAlign, float xScale, float yScale, const float* color, int style); -dvar_t* Dvar_RegisterString(const char* dvarName, const char* value, unsigned int flags, const char* description); -dvar_t* Dvar_RegisterBool(const char* dvarName, bool value, unsigned int flags, const char* description); - -void LUI_CoD_LuaCall_ExecNow(uintptr_t luaVM, const char* str); -bool LUI_LuaCall_Game_IsEntityAlive(uintptr_t luaVM, int entityNum); - -void Cbuf_AddText(const char* cmd); - -bool lua_toboolean(uintptr_t L, int idx); - -void lua_pushboolean(uintptr_t L, int b); -void lua_remove(uintptr_t L, int idx); -void lua_call(uintptr_t L, int nargs, int nresults); -void lua_getfield(uintptr_t L, int idx, const char* k); -void lua_pushvalue(uintptr_t L, int idx); -void lua_pushstring(uintptr_t L, const char* str); -void lua_pushinteger(uintptr_t L, int n); -void lua_settop(uintptr_t L, int idx); -int LuaShared_PCall(uintptr_t luaVM, int nargs, int nresults); - -bool CG_DObjGetWorldBoneMatrix(uintptr_t pose, uintptr_t obj, int boneIndex, uintptr_t outTagMat, float* outOrigin); - -void CG_DrawLine(float X1, float Y1, float X2, float Y2, const float* color, float Width); -void CG_DrawBone(int entIndex, uintptr_t ent, int from, int to, const float* color); -void CG_DrawBones(int entIndex, uintptr_t ent, const float* color); - -bool CheatsOk(int entNum); - -void Cmd_Noclip_f(int entNum); - -void SV_Cmd_ArgvBuffer(int arg, char* buffer, unsigned __int64 bufferLength); -void Cmd_ArgvBuffer(int arg, char* buffer, int bufferLength); -int Cmd_Argc(); -int SV_Cmd_Argc(); - -void Cmd_AddCommandInternal(const char* cmdName, void(__fastcall* function)(), cmd_function_s* allocedCmd); - -void AddReliableCommand(uintptr_t _this, const char* commandBuffer, const int reliableCmdSize, int type); -unsigned int MSG_WriteReliableCommandToBuffer(const char* pszCommand, char* pszBuffer, unsigned int iBufferSize); - -void CL_Main_AddReliableCommand(const char* cmd); - -bool BG_Weapons_GetFullWeaponForName(const char* name, Weapon* outWeapon, Weapon* (__fastcall* getWeaponFunc)(Weapon* result, const char*)); - -void Scr_AddString(scrContext_t* scrContext, const char* value); -unsigned int GScr_ExecEntThread(gentity_s* ent, int handle, unsigned int paramcount); -void Scr_FreeThread(scrContext_t* scrContext, unsigned int handle); - -int G_Weapon_GivePlayerWeapon(uintptr_t ps, uintptr_t scrContext, Weapon* weapon, int dualWield, int startInAltMode, int usedBefore); -void G_Items_AddAmmo(uintptr_t ps, Weapon* weapon, bool isAlternate, int count, int fillClip); - -void G_Weapon_SelectWeapon(int clientNum, Weapon* weapon); -Weapon* BG_FindBaseWeaponForName(Weapon* result, const char* name); - -scrContext_t* ScriptContext_Server(); - -const char* SL_ConvertToString(int id); - -union XAssetHeader DB_FindXAssetHeader(enum XAssetType type, const char* givenName, int allowCreateDefault); - -#pragma endregion - +#pragma once +#include "Main.hpp" + +struct gentity_s; + +struct CmdArgs; + +struct Addresses { + uintptr_t ModuleBase; + uintptr_t jmp_rbx; +}; + +union DvarValue +{ + bool enabled; + int integer; + unsigned int unsignedInt; + __int64 integer64; + unsigned __int64 unsignedInt64; + float value; + float vector[4]; + const char* string; + unsigned __int8 color[4]; +}; + +struct BbConstUsageFlags +{ + bool initialized; + DvarValue codeValue; +}; + +struct netadr_t; + +struct dvar_t +{ + const char* name; + unsigned int checksum; + const char* description; + unsigned int flags; + char level[1]; + unsigned __int8 type; + bool modified; + unsigned __int16 hashNext; + DvarValue current; + DvarValue latched; + DvarValue reset; + char domain[0x10]; + BbConstUsageFlags BbConstUsageFlags; +}; + +struct EncryptionHeader +{ + unsigned int isEncrypted; + unsigned __int8 IV[16]; +}; + +struct __declspec(align(8)) XFile +{ + unsigned __int64 size; + unsigned __int64 preloadWalkSize; + unsigned __int64 blockSize[11]; + EncryptionHeader encryption; +}; + +struct DB_FFHeader +{ + unsigned __int64 magic; + unsigned int headerVersion; + unsigned int xfileVersion; + bool dashCompressBuild; + bool dashEncryptBuild; + unsigned __int8 transientFileType[1]; + unsigned int residentPartSize; + unsigned int residentHash; + unsigned int alwaysLoadedPartSize; + XFile xfileHeader; +}; + +struct EncryptionInfo +{ + EncryptionHeader header; + unsigned __int8 privateKey[32]; +}; + +struct DBFileHandle +{ + unsigned __int8 fileID[4]; + unsigned __int64 dcacheFileID; +}; + +struct cmd_function_s +{ + cmd_function_s* next; + const char* name; + const char** autoCompleteList; + unsigned int autoCompleteListCount; + void(__fastcall* function)(); +}; + +struct DBFile +{ + char name[64]; + DBFileHandle dbFileHandle; + bool isSecured; + EncryptionInfo encryption; +}; + +struct Weapon; +struct scrContext_t; + +extern dvar_t* player_name; +extern dvar_t* sv_cheats; +extern dvar_t* spawn_br_gas; +extern dvar_t* show_watermark; +extern dvar_t* player_sustainammo; + +extern cmd_function_s set_byte_f_VAR; +extern cmd_function_s set_short_f_VAR; +extern cmd_function_s set_int_f_VAR; +extern cmd_function_s set_float_f_VAR; +extern cmd_function_s set_pointer_f_VAR; +extern cmd_function_s quit_f_VAR; +extern cmd_function_s openmenu_f_VAR; +extern cmd_function_s addbot_f_VAR; +extern cmd_function_s ddldump_f_VAR; +extern cmd_function_s weapondefdump_f_VAR; +extern cmd_function_s view_vehicle_ents_f_VAR; +extern cmd_function_s loadout_save_f_VAR; +extern cmd_function_s FastRestart_f_VAR; +extern cmd_function_s MapRestart_f_VAR; +extern cmd_function_s omnvar_set_f_VAR; +extern cmd_function_s omnvar_dump_f_VAR; +extern CmdArgs* cmd_args; + +void* RtlAddVectoredExceptionHandler(LONG First, PVECTORED_EXCEPTION_HANDLER Handler); +NTSTATUS NtContinue(PCONTEXT threadContext, BOOLEAN raiseAlert); + +#pragma region //game functions + +extern const char* (*va)(const char* fmt, ...); + +void Live_FakeUserSignIn(int controllerIndex, const char* gamertag); + +void R_AddCmdDrawText(const char* text, int maxChars, void /* GfxFont */* font, int fontHeight, float x, float y, float xScale, float yScale, float rotation, const float* color, const void /* FontGlowStyle */* glowStyle, bool usePost); + +bool CG_WorldPosToScreenPosReal(int localClientNum, const uintptr_t scrPlace, const float* worldPos, float* outScreenPos); + +void CG_DrawRotatedPicPhysical(uintptr_t scrPlace, float x, float y, float width, float height, float angle, const float* color, uintptr_t material); + +inline bool file_exists(const char* name) { + struct stat buffer; + return (stat(name, &buffer) == 0); +} + +uintptr_t FS_ReadFile(const char* qpath, const char** buffer); +const char* Dvar_GetStringSafe(const char* dvar); +bool Dvar_GetBoolSafe(const char* dvar); +int Dvar_GetIntSafe(const char* dvar); + +unsigned int* GetRandSeed(); +unsigned __int64 Sys_Microseconds(); +int I_irand(int min, int max); +unsigned __int64 I_atoui64_hex(const char* str); +unsigned __int64 I_atoui64(const char* str); +uintptr_t Dvar_FindVarByName(const char* dvarName); + +void CL_DrawText(const uintptr_t scrPlace, const char* text, int maxChars, uintptr_t font, float x, float y, int horzAlign, int vertAlign, float xScale, float yScale, const float* color, int style); +dvar_t* Dvar_RegisterString(const char* dvarName, const char* value, unsigned int flags, const char* description); +dvar_t* Dvar_RegisterBool(const char* dvarName, bool value, unsigned int flags, const char* description); + +void LUI_CoD_LuaCall_ExecNow(uintptr_t luaVM, const char* str); +bool LUI_LuaCall_Game_IsEntityAlive(uintptr_t luaVM, int entityNum); + +void Cbuf_AddText(const char* cmd); + +bool lua_toboolean(uintptr_t L, int idx); + +void lua_pushboolean(uintptr_t L, int b); +void lua_remove(uintptr_t L, int idx); +void lua_call(uintptr_t L, int nargs, int nresults); +void lua_getfield(uintptr_t L, int idx, const char* k); +void lua_pushvalue(uintptr_t L, int idx); +void lua_pushstring(uintptr_t L, const char* str); +void lua_pushinteger(uintptr_t L, int n); +void lua_settop(uintptr_t L, int idx); +int LuaShared_PCall(uintptr_t luaVM, int nargs, int nresults); + +bool CG_DObjGetWorldBoneMatrix(uintptr_t pose, uintptr_t obj, int boneIndex, uintptr_t outTagMat, float* outOrigin); + +void CG_DrawLine(float X1, float Y1, float X2, float Y2, const float* color, float Width); +void CG_DrawBone(int entIndex, uintptr_t ent, int from, int to, const float* color); +void CG_DrawBones(int entIndex, uintptr_t ent, const float* color); + +bool CheatsOk(int entNum); + +void Cmd_Noclip_f(int entNum); + +void Cmd_God_f(int entNum); + +void SV_Cmd_ArgvBuffer(int arg, char* buffer, unsigned __int64 bufferLength); +void Cmd_ArgvBuffer(int arg, char* buffer, int bufferLength); +int Cmd_Argc(); +int SV_Cmd_Argc(); + +void Cmd_AddCommandInternal(const char* cmdName, void(__fastcall* function)(), cmd_function_s* allocedCmd); + +void AddReliableCommand(uintptr_t _this, const char* commandBuffer, const int reliableCmdSize, int type); +unsigned int MSG_WriteReliableCommandToBuffer(const char* pszCommand, char* pszBuffer, unsigned int iBufferSize); + +void CL_Main_AddReliableCommand(const char* cmd); + +bool BG_Weapons_GetFullWeaponForName(const char* name, Weapon* outWeapon, Weapon* (__fastcall* getWeaponFunc)(Weapon* result, const char*)); + +void Scr_AddString(scrContext_t* scrContext, const char* value); +unsigned int GScr_ExecEntThread(gentity_s* ent, int handle, unsigned int paramcount); +void Scr_FreeThread(scrContext_t* scrContext, unsigned int handle); + +int G_Weapon_GivePlayerWeapon(uintptr_t ps, uintptr_t scrContext, Weapon* weapon, int dualWield, int startInAltMode, int usedBefore); +void G_Items_AddAmmo(uintptr_t ps, Weapon* weapon, bool isAlternate, int count, int fillClip); + +void G_Weapon_SelectWeapon(int clientNum, Weapon* weapon); +Weapon* BG_FindBaseWeaponForName(Weapon* result, const char* name); + +scrContext_t* ScriptContext_Server(); + +const char* SL_ConvertToString(int id); + +union XAssetHeader DB_FindXAssetHeader(enum XAssetType type, const char* givenName, int allowCreateDefault); + +void Com_SetErrorMessage(const char* errorMessage); + +#pragma endregion + extern Addresses g_Addrs; \ No newline at end of file diff --git a/hook_lib/hook_lib.vcxproj b/hook_lib/hook_lib.vcxproj index 7d7f092..6ac3836 100644 --- a/hook_lib/hook_lib.vcxproj +++ b/hook_lib/hook_lib.vcxproj @@ -48,7 +48,7 @@ DynamicLibrary false - v143 + v142 true MultiByte false @@ -81,10 +81,12 @@ true discord_game_sdk + D:\Dokumente\CoDMW19\codUPLOADER\mw19-of-main\lib;$(LibraryPath) false discord_game_sdk + D:\Dokumente\CoDMW19\codUPLOADER\mw19-of-main\lib;$(LibraryPath) @@ -136,13 +138,13 @@ true NOMINMAX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true - stdcpplatest + stdcpp20 Console true true - true + false minhook.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) @@ -181,7 +183,6 @@ - diff --git a/hook_lib/hook_lib.vcxproj.filters b/hook_lib/hook_lib.vcxproj.filters index 5b68d98..81664c9 100644 --- a/hook_lib/hook_lib.vcxproj.filters +++ b/hook_lib/hook_lib.vcxproj.filters @@ -1,143 +1,142 @@ - - - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {9ba1aab7-3c29-4043-88a2-0733bdba52af} - - - {67571f10-529c-4ebd-94b6-2cebbbb62a35} - - - {03fd645c-a59f-4d26-950c-b411df71f725} - - - {997a4fac-6cde-43a6-84df-2e0e58b4b7fc} - - - {0999b80b-b47c-4d8e-8776-f5c778bcac9f} - - - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\exception - - - hook_lib - - - hook_lib\game - - - common\utils - - - hook_lib\game - - - hook_lib\game - - - hook_lib\game - - - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\utils - - - common\exception - - - hook_lib - - - common\utils - - - hook_lib\game - - - common\utils - - - hook_lib\game - - - hook_lib\game - - - hook_lib\game - - - hook_lib\game - - - + + + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {9ba1aab7-3c29-4043-88a2-0733bdba52af} + + + {67571f10-529c-4ebd-94b6-2cebbbb62a35} + + + {03fd645c-a59f-4d26-950c-b411df71f725} + + + {997a4fac-6cde-43a6-84df-2e0e58b4b7fc} + + + {0999b80b-b47c-4d8e-8776-f5c778bcac9f} + + + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\exception + + + hook_lib + + + hook_lib\game + + + common\utils + + + hook_lib\game + + + hook_lib\game + + + hook_lib\game + + + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\utils + + + common\exception + + + hook_lib + + + common\utils + + + hook_lib\game + + + common\utils + + + hook_lib\game + + + hook_lib\game + + + hook_lib\game + + + hook_lib\game + + \ No newline at end of file diff --git a/hook_lib/hook_lib.vcxproj.user b/hook_lib/hook_lib.vcxproj.user index bf444be..0f14913 100644 --- a/hook_lib/hook_lib.vcxproj.user +++ b/hook_lib/hook_lib.vcxproj.user @@ -1,15 +1,4 @@  - - true - - - D:\Games\CODMWDebug\Call of Duty Modern Warfare %282019%29\game_dx12_ship_replay.exe - WindowsLocalDebugger - - - D:\Games\CODMWDebug\Call of Duty Modern Warfare %282019%29\game_dx12_ship_replay.exe - WindowsLocalDebugger - ..\..\..\..\Games\CODMWDebug\Call of Duty Modern Warfare %282019%29 - + \ No newline at end of file diff --git a/hook_lib/ini.h b/hook_lib/ini.h index bf759f7..cb0b801 100644 --- a/hook_lib/ini.h +++ b/hook_lib/ini.h @@ -1,789 +1,789 @@ -/* - * The MIT License (MIT) - * Copyright (c) 2018 Danijel Durakovic - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - - /////////////////////////////////////////////////////////////////////////////// - // - // /mINI/ v0.9.14 - // An INI file reader and writer for the modern age. - // - /////////////////////////////////////////////////////////////////////////////// - // - // A tiny utility library for manipulating INI files with a straightforward - // API and a minimal footprint. It conforms to the (somewhat) standard INI - // format - sections and keys are case insensitive and all leading and - // trailing whitespace is ignored. Comments are lines that begin with a - // semicolon. Trailing comments are allowed on section lines. - // - // Files are read on demand, upon which data is kept in memory and the file - // is closed. This utility supports lazy writing, which only writes changes - // and updates to a file and preserves custom formatting and comments. A lazy - // write invoked by a write() call will read the output file, find what - // changes have been made and update the file accordingly. If you only need to - // generate files, use generate() instead. Section and key order is preserved - // on read, write and insert. - // - /////////////////////////////////////////////////////////////////////////////// - // - // /* BASIC USAGE EXAMPLE: */ - // - // /* read from file */ - // mINI::INIFile file("myfile.ini"); - // mINI::INIStructure ini; - // file.read(ini); - // - // /* read value; gets a reference to actual value in the structure. - // if key or section don't exist, a new empty value will be created */ - // std::string& value = ini["section"]["key"]; - // - // /* read value safely; gets a copy of value in the structure. - // does not alter the structure */ - // std::string value = ini.get("section").get("key"); - // - // /* set or update values */ - // ini["section"]["key"] = "value"; - // - // /* set multiple values */ - // ini["section2"].set({ - // {"key1", "value1"}, - // {"key2", "value2"} - // }); - // - // /* write updates back to file, preserving comments and formatting */ - // file.write(ini); - // - // /* or generate a file (overwrites the original) */ - // file.generate(ini); - // - /////////////////////////////////////////////////////////////////////////////// - // - // Long live the INI file!!! - // - /////////////////////////////////////////////////////////////////////////////// - -#ifndef MINI_INI_H_ -#define MINI_INI_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mINI -{ - namespace INIStringUtil - { - const char* const whitespaceDelimiters = " \t\n\r\f\v"; - inline void trim(std::string& str) - { - str.erase(str.find_last_not_of(whitespaceDelimiters) + 1); - str.erase(0, str.find_first_not_of(whitespaceDelimiters)); - } -#ifndef MINI_CASE_SENSITIVE - inline void toLower(std::string& str) - { - std::transform(str.begin(), str.end(), str.begin(), [](const char c) { - return static_cast(std::tolower(c)); - }); - } -#endif - inline void replace(std::string& str, std::string const& a, std::string const& b) - { - if (!a.empty()) - { - std::size_t pos = 0; - while ((pos = str.find(a, pos)) != std::string::npos) - { - str.replace(pos, a.size(), b); - pos += b.size(); - } - } - } -#ifdef _WIN32 - const char* const endl = "\r\n"; -#else - const char* const endl = "\n"; -#endif - } - - template - class INIMap - { - private: - using T_DataIndexMap = std::unordered_map; - using T_DataItem = std::pair; - using T_DataContainer = std::vector; - using T_MultiArgs = typename std::vector>; - - T_DataIndexMap dataIndexMap; - T_DataContainer data; - - inline std::size_t setEmpty(std::string& key) - { - std::size_t index = data.size(); - dataIndexMap[key] = index; - data.emplace_back(key, T()); - return index; - } - - public: - using const_iterator = typename T_DataContainer::const_iterator; - - INIMap() { } - - INIMap(INIMap const& other) - { - std::size_t data_size = other.data.size(); - for (std::size_t i = 0; i < data_size; ++i) - { - auto const& key = other.data[i].first; - auto const& obj = other.data[i].second; - data.emplace_back(key, obj); - } - dataIndexMap = T_DataIndexMap(other.dataIndexMap); - } - - T& operator[](std::string key) - { - INIStringUtil::trim(key); -#ifndef MINI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - auto it = dataIndexMap.find(key); - bool hasIt = (it != dataIndexMap.end()); - std::size_t index = (hasIt) ? it->second : setEmpty(key); - return data[index].second; - } - T get(std::string key) const - { - INIStringUtil::trim(key); -#ifndef MINI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - auto it = dataIndexMap.find(key); - if (it == dataIndexMap.end()) - { - return T(); - } - return T(data[it->second].second); - } - bool has(std::string key) const - { - INIStringUtil::trim(key); -#ifndef MINI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - return (dataIndexMap.count(key) == 1); - } - void set(std::string key, T obj) - { - INIStringUtil::trim(key); -#ifndef MINI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - auto it = dataIndexMap.find(key); - if (it != dataIndexMap.end()) - { - data[it->second].second = obj; - } - else - { - dataIndexMap[key] = data.size(); - data.emplace_back(key, obj); - } - } - void set(T_MultiArgs const& multiArgs) - { - for (auto const& it : multiArgs) - { - auto const& key = it.first; - auto const& obj = it.second; - set(key, obj); - } - } - bool remove(std::string key) - { - INIStringUtil::trim(key); -#ifndef MINI_CASE_SENSITIVE - INIStringUtil::toLower(key); -#endif - auto it = dataIndexMap.find(key); - if (it != dataIndexMap.end()) - { - std::size_t index = it->second; - data.erase(data.begin() + index); - dataIndexMap.erase(it); - for (auto& it2 : dataIndexMap) - { - auto& vi = it2.second; - if (vi > index) - { - vi--; - } - } - return true; - } - return false; - } - void clear() - { - data.clear(); - dataIndexMap.clear(); - } - std::size_t size() const - { - return data.size(); - } - const_iterator begin() const { return data.begin(); } - const_iterator end() const { return data.end(); } - }; - - using INIStructure = INIMap>; - - namespace INIParser - { - using T_ParseValues = std::pair; - - enum class PDataType : char - { - PDATA_NONE, - PDATA_COMMENT, - PDATA_SECTION, - PDATA_KEYVALUE, - PDATA_UNKNOWN - }; - - inline PDataType parseLine(std::string line, T_ParseValues& parseData) - { - parseData.first.clear(); - parseData.second.clear(); - INIStringUtil::trim(line); - if (line.empty()) - { - return PDataType::PDATA_NONE; - } - char firstCharacter = line[0]; - if (firstCharacter == ';') - { - return PDataType::PDATA_COMMENT; - } - if (firstCharacter == '[') - { - auto commentAt = line.find_first_of(';'); - if (commentAt != std::string::npos) - { - line = line.substr(0, commentAt); - } - auto closingBracketAt = line.find_last_of(']'); - if (closingBracketAt != std::string::npos) - { - auto section = line.substr(1, closingBracketAt - 1); - INIStringUtil::trim(section); - parseData.first = section; - return PDataType::PDATA_SECTION; - } - } - auto lineNorm = line; - INIStringUtil::replace(lineNorm, "\\=", " "); - auto equalsAt = lineNorm.find_first_of('='); - if (equalsAt != std::string::npos) - { - auto key = line.substr(0, equalsAt); - INIStringUtil::trim(key); - INIStringUtil::replace(key, "\\=", "="); - auto value = line.substr(equalsAt + 1); - INIStringUtil::trim(value); - parseData.first = key; - parseData.second = value; - return PDataType::PDATA_KEYVALUE; - } - return PDataType::PDATA_UNKNOWN; - } - } - - class INIReader - { - public: - using T_LineData = std::vector; - using T_LineDataPtr = std::shared_ptr; - - bool isBOM = false; - - private: - std::ifstream fileReadStream; - T_LineDataPtr lineData; - - T_LineData readFile() - { - fileReadStream.seekg(0, std::ios::end); - const std::size_t fileSize = static_cast(fileReadStream.tellg()); - fileReadStream.seekg(0, std::ios::beg); - if (fileSize >= 3) { - const char header[3] = { - static_cast(fileReadStream.get()), - static_cast(fileReadStream.get()), - static_cast(fileReadStream.get()) - }; - isBOM = ( - header[0] == static_cast(0xEF) && - header[1] == static_cast(0xBB) && - header[2] == static_cast(0xBF) - ); - } - else { - isBOM = false; - } - std::string fileContents; - fileContents.resize(fileSize); - fileReadStream.seekg(isBOM ? 3 : 0, std::ios::beg); - fileReadStream.read(&fileContents[0], fileSize); - fileReadStream.close(); - T_LineData output; - if (fileSize == 0) - { - return output; - } - std::string buffer; - buffer.reserve(50); - for (std::size_t i = 0; i < fileSize; ++i) - { - char& c = fileContents[i]; - if (c == '\n') - { - output.emplace_back(buffer); - buffer.clear(); - continue; - } - if (c != '\0' && c != '\r') - { - buffer += c; - } - } - output.emplace_back(buffer); - return output; - } - - public: - INIReader(std::string const& filename, bool keepLineData = false) - { - fileReadStream.open(filename, std::ios::in | std::ios::binary); - if (keepLineData) - { - lineData = std::make_shared(); - } - } - ~INIReader() { } - - bool operator>>(INIStructure& data) - { - if (!fileReadStream.is_open()) - { - return false; - } - T_LineData fileLines = readFile(); - std::string section; - bool inSection = false; - INIParser::T_ParseValues parseData; - for (auto const& line : fileLines) - { - auto parseResult = INIParser::parseLine(line, parseData); - if (parseResult == INIParser::PDataType::PDATA_SECTION) - { - inSection = true; - data[section = parseData.first]; - } - else if (inSection && parseResult == INIParser::PDataType::PDATA_KEYVALUE) - { - auto const& key = parseData.first; - auto const& value = parseData.second; - data[section][key] = value; - } - if (lineData && parseResult != INIParser::PDataType::PDATA_UNKNOWN) - { - if (parseResult == INIParser::PDataType::PDATA_KEYVALUE && !inSection) - { - continue; - } - lineData->emplace_back(line); - } - } - return true; - } - T_LineDataPtr getLines() - { - return lineData; - } - }; - - class INIGenerator - { - private: - std::ofstream fileWriteStream; - - public: - bool prettyPrint = false; - - INIGenerator(std::string const& filename) - { - fileWriteStream.open(filename, std::ios::out | std::ios::binary); - } - ~INIGenerator() { } - - bool operator<<(INIStructure const& data) - { - if (!fileWriteStream.is_open()) - { - return false; - } - if (!data.size()) - { - return true; - } - auto it = data.begin(); - for (;;) - { - auto const& section = it->first; - auto const& collection = it->second; - fileWriteStream - << "[" - << section - << "]"; - if (collection.size()) - { - fileWriteStream << INIStringUtil::endl; - auto it2 = collection.begin(); - for (;;) - { - auto key = it2->first; - INIStringUtil::replace(key, "=", "\\="); - auto value = it2->second; - INIStringUtil::trim(value); - fileWriteStream - << key - << ((prettyPrint) ? " = " : "=") - << value; - if (++it2 == collection.end()) - { - break; - } - fileWriteStream << INIStringUtil::endl; - } - } - if (++it == data.end()) - { - break; - } - fileWriteStream << INIStringUtil::endl; - if (prettyPrint) - { - fileWriteStream << INIStringUtil::endl; - } - } - return true; - } - }; - - class INIWriter - { - private: - using T_LineData = std::vector; - using T_LineDataPtr = std::shared_ptr; - - std::string filename; - - T_LineData getLazyOutput(T_LineDataPtr const& lineData, INIStructure& data, INIStructure& original) - { - T_LineData output; - INIParser::T_ParseValues parseData; - std::string sectionCurrent; - bool parsingSection = false; - bool continueToNextSection = false; - bool discardNextEmpty = false; - bool writeNewKeys = false; - std::size_t lastKeyLine = 0; - for (auto line = lineData->begin(); line != lineData->end(); ++line) - { - if (!writeNewKeys) - { - auto parseResult = INIParser::parseLine(*line, parseData); - if (parseResult == INIParser::PDataType::PDATA_SECTION) - { - if (parsingSection) - { - writeNewKeys = true; - parsingSection = false; - --line; - continue; - } - sectionCurrent = parseData.first; - if (data.has(sectionCurrent)) - { - parsingSection = true; - continueToNextSection = false; - discardNextEmpty = false; - output.emplace_back(*line); - lastKeyLine = output.size(); - } - else - { - continueToNextSection = true; - discardNextEmpty = true; - continue; - } - } - else if (parseResult == INIParser::PDataType::PDATA_KEYVALUE) - { - if (continueToNextSection) - { - continue; - } - if (data.has(sectionCurrent)) - { - auto& collection = data[sectionCurrent]; - auto const& key = parseData.first; - auto const& value = parseData.second; - if (collection.has(key)) - { - auto outputValue = collection[key]; - if (value == outputValue) - { - output.emplace_back(*line); - } - else - { - INIStringUtil::trim(outputValue); - auto lineNorm = *line; - INIStringUtil::replace(lineNorm, "\\=", " "); - auto equalsAt = lineNorm.find_first_of('='); - auto valueAt = lineNorm.find_first_not_of( - INIStringUtil::whitespaceDelimiters, - equalsAt + 1 - ); - std::string outputLine = line->substr(0, valueAt); - if (prettyPrint && equalsAt + 1 == valueAt) - { - outputLine += " "; - } - outputLine += outputValue; - output.emplace_back(outputLine); - } - lastKeyLine = output.size(); - } - } - } - else - { - if (discardNextEmpty && line->empty()) - { - discardNextEmpty = false; - } - else if (parseResult != INIParser::PDataType::PDATA_UNKNOWN) - { - output.emplace_back(*line); - } - } - } - if (writeNewKeys || std::next(line) == lineData->end()) - { - T_LineData linesToAdd; - if (data.has(sectionCurrent) && original.has(sectionCurrent)) - { - auto const& collection = data[sectionCurrent]; - auto const& collectionOriginal = original[sectionCurrent]; - for (auto const& it : collection) - { - auto key = it.first; - if (collectionOriginal.has(key)) - { - continue; - } - auto value = it.second; - INIStringUtil::replace(key, "=", "\\="); - INIStringUtil::trim(value); - linesToAdd.emplace_back( - key + ((prettyPrint) ? " = " : "=") + value - ); - } - } - if (!linesToAdd.empty()) - { - output.insert( - output.begin() + lastKeyLine, - linesToAdd.begin(), - linesToAdd.end() - ); - } - if (writeNewKeys) - { - writeNewKeys = false; - --line; - } - } - } - for (auto const& it : data) - { - auto const& section = it.first; - if (original.has(section)) - { - continue; - } - if (prettyPrint && output.size() > 0 && !output.back().empty()) - { - output.emplace_back(); - } - output.emplace_back("[" + section + "]"); - auto const& collection = it.second; - for (auto const& it2 : collection) - { - auto key = it2.first; - auto value = it2.second; - INIStringUtil::replace(key, "=", "\\="); - INIStringUtil::trim(value); - output.emplace_back( - key + ((prettyPrint) ? " = " : "=") + value - ); - } - } - return output; - } - - public: - bool prettyPrint = false; - - INIWriter(std::string const& filename) - : filename(filename) - { - } - ~INIWriter() { } - - bool operator<<(INIStructure& data) - { - struct stat buf; - bool fileExists = (stat(filename.c_str(), &buf) == 0); - if (!fileExists) - { - INIGenerator generator(filename); - generator.prettyPrint = prettyPrint; - return generator << data; - } - INIStructure originalData; - T_LineDataPtr lineData; - bool readSuccess = false; - bool fileIsBOM = false; - { - INIReader reader(filename, true); - if ((readSuccess = reader >> originalData)) - { - lineData = reader.getLines(); - fileIsBOM = reader.isBOM; - } - } - if (!readSuccess) - { - return false; - } - T_LineData output = getLazyOutput(lineData, data, originalData); - std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary); - if (fileWriteStream.is_open()) - { - if (fileIsBOM) { - const char utf8_BOM[3] = { - static_cast(0xEF), - static_cast(0xBB), - static_cast(0xBF) - }; - fileWriteStream.write(utf8_BOM, 3); - } - if (output.size()) - { - auto line = output.begin(); - for (;;) - { - fileWriteStream << *line; - if (++line == output.end()) - { - break; - } - fileWriteStream << INIStringUtil::endl; - } - } - return true; - } - return false; - } - }; - - class INIFile - { - private: - std::string filename; - - public: - INIFile(std::string const& filename) - : filename(filename) - { } - - ~INIFile() { } - - bool read(INIStructure& data) const - { - if (data.size()) - { - data.clear(); - } - if (filename.empty()) - { - return false; - } - INIReader reader(filename); - return reader >> data; - } - bool generate(INIStructure const& data, bool pretty = false) const - { - if (filename.empty()) - { - return false; - } - INIGenerator generator(filename); - generator.prettyPrint = pretty; - return generator << data; - } - bool write(INIStructure& data, bool pretty = false) const - { - if (filename.empty()) - { - return false; - } - INIWriter writer(filename); - writer.prettyPrint = pretty; - return writer << data; - } - }; -} - +/* + * The MIT License (MIT) + * Copyright (c) 2018 Danijel Durakovic + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + + /////////////////////////////////////////////////////////////////////////////// + // + // /mINI/ v0.9.14 + // An INI file reader and writer for the modern age. + // + /////////////////////////////////////////////////////////////////////////////// + // + // A tiny utility library for manipulating INI files with a straightforward + // API and a minimal footprint. It conforms to the (somewhat) standard INI + // format - sections and keys are case insensitive and all leading and + // trailing whitespace is ignored. Comments are lines that begin with a + // semicolon. Trailing comments are allowed on section lines. + // + // Files are read on demand, upon which data is kept in memory and the file + // is closed. This utility supports lazy writing, which only writes changes + // and updates to a file and preserves custom formatting and comments. A lazy + // write invoked by a write() call will read the output file, find what + // changes have been made and update the file accordingly. If you only need to + // generate files, use generate() instead. Section and key order is preserved + // on read, write and insert. + // + /////////////////////////////////////////////////////////////////////////////// + // + // /* BASIC USAGE EXAMPLE: */ + // + // /* read from file */ + // mINI::INIFile file("myfile.ini"); + // mINI::INIStructure ini; + // file.read(ini); + // + // /* read value; gets a reference to actual value in the structure. + // if key or section don't exist, a new empty value will be created */ + // std::string& value = ini["section"]["key"]; + // + // /* read value safely; gets a copy of value in the structure. + // does not alter the structure */ + // std::string value = ini.get("section").get("key"); + // + // /* set or update values */ + // ini["section"]["key"] = "value"; + // + // /* set multiple values */ + // ini["section2"].set({ + // {"key1", "value1"}, + // {"key2", "value2"} + // }); + // + // /* write updates back to file, preserving comments and formatting */ + // file.write(ini); + // + // /* or generate a file (overwrites the original) */ + // file.generate(ini); + // + /////////////////////////////////////////////////////////////////////////////// + // + // Long live the INI file!!! + // + /////////////////////////////////////////////////////////////////////////////// + +#ifndef MINI_INI_H_ +#define MINI_INI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mINI +{ + namespace INIStringUtil + { + const char* const whitespaceDelimiters = " \t\n\r\f\v"; + inline void trim(std::string& str) + { + str.erase(str.find_last_not_of(whitespaceDelimiters) + 1); + str.erase(0, str.find_first_not_of(whitespaceDelimiters)); + } +#ifndef MINI_CASE_SENSITIVE + inline void toLower(std::string& str) + { + std::transform(str.begin(), str.end(), str.begin(), [](const char c) { + return static_cast(std::tolower(c)); + }); + } +#endif + inline void replace(std::string& str, std::string const& a, std::string const& b) + { + if (!a.empty()) + { + std::size_t pos = 0; + while ((pos = str.find(a, pos)) != std::string::npos) + { + str.replace(pos, a.size(), b); + pos += b.size(); + } + } + } +#ifdef _WIN32 + const char* const endl = "\r\n"; +#else + const char* const endl = "\n"; +#endif + } + + template + class INIMap + { + private: + using T_DataIndexMap = std::unordered_map; + using T_DataItem = std::pair; + using T_DataContainer = std::vector; + using T_MultiArgs = typename std::vector>; + + T_DataIndexMap dataIndexMap; + T_DataContainer data; + + inline std::size_t setEmpty(std::string& key) + { + std::size_t index = data.size(); + dataIndexMap[key] = index; + data.emplace_back(key, T()); + return index; + } + + public: + using const_iterator = typename T_DataContainer::const_iterator; + + INIMap() { } + + INIMap(INIMap const& other) + { + std::size_t data_size = other.data.size(); + for (std::size_t i = 0; i < data_size; ++i) + { + auto const& key = other.data[i].first; + auto const& obj = other.data[i].second; + data.emplace_back(key, obj); + } + dataIndexMap = T_DataIndexMap(other.dataIndexMap); + } + + T& operator[](std::string key) + { + INIStringUtil::trim(key); +#ifndef MINI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + auto it = dataIndexMap.find(key); + bool hasIt = (it != dataIndexMap.end()); + std::size_t index = (hasIt) ? it->second : setEmpty(key); + return data[index].second; + } + T get(std::string key) const + { + INIStringUtil::trim(key); +#ifndef MINI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + auto it = dataIndexMap.find(key); + if (it == dataIndexMap.end()) + { + return T(); + } + return T(data[it->second].second); + } + bool has(std::string key) const + { + INIStringUtil::trim(key); +#ifndef MINI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + return (dataIndexMap.count(key) == 1); + } + void set(std::string key, T obj) + { + INIStringUtil::trim(key); +#ifndef MINI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + auto it = dataIndexMap.find(key); + if (it != dataIndexMap.end()) + { + data[it->second].second = obj; + } + else + { + dataIndexMap[key] = data.size(); + data.emplace_back(key, obj); + } + } + void set(T_MultiArgs const& multiArgs) + { + for (auto const& it : multiArgs) + { + auto const& key = it.first; + auto const& obj = it.second; + set(key, obj); + } + } + bool remove(std::string key) + { + INIStringUtil::trim(key); +#ifndef MINI_CASE_SENSITIVE + INIStringUtil::toLower(key); +#endif + auto it = dataIndexMap.find(key); + if (it != dataIndexMap.end()) + { + std::size_t index = it->second; + data.erase(data.begin() + index); + dataIndexMap.erase(it); + for (auto& it2 : dataIndexMap) + { + auto& vi = it2.second; + if (vi > index) + { + vi--; + } + } + return true; + } + return false; + } + void clear() + { + data.clear(); + dataIndexMap.clear(); + } + std::size_t size() const + { + return data.size(); + } + const_iterator begin() const { return data.begin(); } + const_iterator end() const { return data.end(); } + }; + + using INIStructure = INIMap>; + + namespace INIParser + { + using T_ParseValues = std::pair; + + enum class PDataType : char + { + PDATA_NONE, + PDATA_COMMENT, + PDATA_SECTION, + PDATA_KEYVALUE, + PDATA_UNKNOWN + }; + + inline PDataType parseLine(std::string line, T_ParseValues& parseData) + { + parseData.first.clear(); + parseData.second.clear(); + INIStringUtil::trim(line); + if (line.empty()) + { + return PDataType::PDATA_NONE; + } + char firstCharacter = line[0]; + if (firstCharacter == ';') + { + return PDataType::PDATA_COMMENT; + } + if (firstCharacter == '[') + { + auto commentAt = line.find_first_of(';'); + if (commentAt != std::string::npos) + { + line = line.substr(0, commentAt); + } + auto closingBracketAt = line.find_last_of(']'); + if (closingBracketAt != std::string::npos) + { + auto section = line.substr(1, closingBracketAt - 1); + INIStringUtil::trim(section); + parseData.first = section; + return PDataType::PDATA_SECTION; + } + } + auto lineNorm = line; + INIStringUtil::replace(lineNorm, "\\=", " "); + auto equalsAt = lineNorm.find_first_of('='); + if (equalsAt != std::string::npos) + { + auto key = line.substr(0, equalsAt); + INIStringUtil::trim(key); + INIStringUtil::replace(key, "\\=", "="); + auto value = line.substr(equalsAt + 1); + INIStringUtil::trim(value); + parseData.first = key; + parseData.second = value; + return PDataType::PDATA_KEYVALUE; + } + return PDataType::PDATA_UNKNOWN; + } + } + + class INIReader + { + public: + using T_LineData = std::vector; + using T_LineDataPtr = std::shared_ptr; + + bool isBOM = false; + + private: + std::ifstream fileReadStream; + T_LineDataPtr lineData; + + T_LineData readFile() + { + fileReadStream.seekg(0, std::ios::end); + const std::size_t fileSize = static_cast(fileReadStream.tellg()); + fileReadStream.seekg(0, std::ios::beg); + if (fileSize >= 3) { + const char header[3] = { + static_cast(fileReadStream.get()), + static_cast(fileReadStream.get()), + static_cast(fileReadStream.get()) + }; + isBOM = ( + header[0] == static_cast(0xEF) && + header[1] == static_cast(0xBB) && + header[2] == static_cast(0xBF) + ); + } + else { + isBOM = false; + } + std::string fileContents; + fileContents.resize(fileSize); + fileReadStream.seekg(isBOM ? 3 : 0, std::ios::beg); + fileReadStream.read(&fileContents[0], fileSize); + fileReadStream.close(); + T_LineData output; + if (fileSize == 0) + { + return output; + } + std::string buffer; + buffer.reserve(50); + for (std::size_t i = 0; i < fileSize; ++i) + { + char& c = fileContents[i]; + if (c == '\n') + { + output.emplace_back(buffer); + buffer.clear(); + continue; + } + if (c != '\0' && c != '\r') + { + buffer += c; + } + } + output.emplace_back(buffer); + return output; + } + + public: + INIReader(std::string const& filename, bool keepLineData = false) + { + fileReadStream.open(filename, std::ios::in | std::ios::binary); + if (keepLineData) + { + lineData = std::make_shared(); + } + } + ~INIReader() { } + + bool operator>>(INIStructure& data) + { + if (!fileReadStream.is_open()) + { + return false; + } + T_LineData fileLines = readFile(); + std::string section; + bool inSection = false; + INIParser::T_ParseValues parseData; + for (auto const& line : fileLines) + { + auto parseResult = INIParser::parseLine(line, parseData); + if (parseResult == INIParser::PDataType::PDATA_SECTION) + { + inSection = true; + data[section = parseData.first]; + } + else if (inSection && parseResult == INIParser::PDataType::PDATA_KEYVALUE) + { + auto const& key = parseData.first; + auto const& value = parseData.second; + data[section][key] = value; + } + if (lineData && parseResult != INIParser::PDataType::PDATA_UNKNOWN) + { + if (parseResult == INIParser::PDataType::PDATA_KEYVALUE && !inSection) + { + continue; + } + lineData->emplace_back(line); + } + } + return true; + } + T_LineDataPtr getLines() + { + return lineData; + } + }; + + class INIGenerator + { + private: + std::ofstream fileWriteStream; + + public: + bool prettyPrint = false; + + INIGenerator(std::string const& filename) + { + fileWriteStream.open(filename, std::ios::out | std::ios::binary); + } + ~INIGenerator() { } + + bool operator<<(INIStructure const& data) + { + if (!fileWriteStream.is_open()) + { + return false; + } + if (!data.size()) + { + return true; + } + auto it = data.begin(); + for (;;) + { + auto const& section = it->first; + auto const& collection = it->second; + fileWriteStream + << "[" + << section + << "]"; + if (collection.size()) + { + fileWriteStream << INIStringUtil::endl; + auto it2 = collection.begin(); + for (;;) + { + auto key = it2->first; + INIStringUtil::replace(key, "=", "\\="); + auto value = it2->second; + INIStringUtil::trim(value); + fileWriteStream + << key + << ((prettyPrint) ? " = " : "=") + << value; + if (++it2 == collection.end()) + { + break; + } + fileWriteStream << INIStringUtil::endl; + } + } + if (++it == data.end()) + { + break; + } + fileWriteStream << INIStringUtil::endl; + if (prettyPrint) + { + fileWriteStream << INIStringUtil::endl; + } + } + return true; + } + }; + + class INIWriter + { + private: + using T_LineData = std::vector; + using T_LineDataPtr = std::shared_ptr; + + std::string filename; + + T_LineData getLazyOutput(T_LineDataPtr const& lineData, INIStructure& data, INIStructure& original) + { + T_LineData output; + INIParser::T_ParseValues parseData; + std::string sectionCurrent; + bool parsingSection = false; + bool continueToNextSection = false; + bool discardNextEmpty = false; + bool writeNewKeys = false; + std::size_t lastKeyLine = 0; + for (auto line = lineData->begin(); line != lineData->end(); ++line) + { + if (!writeNewKeys) + { + auto parseResult = INIParser::parseLine(*line, parseData); + if (parseResult == INIParser::PDataType::PDATA_SECTION) + { + if (parsingSection) + { + writeNewKeys = true; + parsingSection = false; + --line; + continue; + } + sectionCurrent = parseData.first; + if (data.has(sectionCurrent)) + { + parsingSection = true; + continueToNextSection = false; + discardNextEmpty = false; + output.emplace_back(*line); + lastKeyLine = output.size(); + } + else + { + continueToNextSection = true; + discardNextEmpty = true; + continue; + } + } + else if (parseResult == INIParser::PDataType::PDATA_KEYVALUE) + { + if (continueToNextSection) + { + continue; + } + if (data.has(sectionCurrent)) + { + auto& collection = data[sectionCurrent]; + auto const& key = parseData.first; + auto const& value = parseData.second; + if (collection.has(key)) + { + auto outputValue = collection[key]; + if (value == outputValue) + { + output.emplace_back(*line); + } + else + { + INIStringUtil::trim(outputValue); + auto lineNorm = *line; + INIStringUtil::replace(lineNorm, "\\=", " "); + auto equalsAt = lineNorm.find_first_of('='); + auto valueAt = lineNorm.find_first_not_of( + INIStringUtil::whitespaceDelimiters, + equalsAt + 1 + ); + std::string outputLine = line->substr(0, valueAt); + if (prettyPrint && equalsAt + 1 == valueAt) + { + outputLine += " "; + } + outputLine += outputValue; + output.emplace_back(outputLine); + } + lastKeyLine = output.size(); + } + } + } + else + { + if (discardNextEmpty && line->empty()) + { + discardNextEmpty = false; + } + else if (parseResult != INIParser::PDataType::PDATA_UNKNOWN) + { + output.emplace_back(*line); + } + } + } + if (writeNewKeys || std::next(line) == lineData->end()) + { + T_LineData linesToAdd; + if (data.has(sectionCurrent) && original.has(sectionCurrent)) + { + auto const& collection = data[sectionCurrent]; + auto const& collectionOriginal = original[sectionCurrent]; + for (auto const& it : collection) + { + auto key = it.first; + if (collectionOriginal.has(key)) + { + continue; + } + auto value = it.second; + INIStringUtil::replace(key, "=", "\\="); + INIStringUtil::trim(value); + linesToAdd.emplace_back( + key + ((prettyPrint) ? " = " : "=") + value + ); + } + } + if (!linesToAdd.empty()) + { + output.insert( + output.begin() + lastKeyLine, + linesToAdd.begin(), + linesToAdd.end() + ); + } + if (writeNewKeys) + { + writeNewKeys = false; + --line; + } + } + } + for (auto const& it : data) + { + auto const& section = it.first; + if (original.has(section)) + { + continue; + } + if (prettyPrint && output.size() > 0 && !output.back().empty()) + { + output.emplace_back(); + } + output.emplace_back("[" + section + "]"); + auto const& collection = it.second; + for (auto const& it2 : collection) + { + auto key = it2.first; + auto value = it2.second; + INIStringUtil::replace(key, "=", "\\="); + INIStringUtil::trim(value); + output.emplace_back( + key + ((prettyPrint) ? " = " : "=") + value + ); + } + } + return output; + } + + public: + bool prettyPrint = false; + + INIWriter(std::string const& filename) + : filename(filename) + { + } + ~INIWriter() { } + + bool operator<<(INIStructure& data) + { + struct stat buf; + bool fileExists = (stat(filename.c_str(), &buf) == 0); + if (!fileExists) + { + INIGenerator generator(filename); + generator.prettyPrint = prettyPrint; + return generator << data; + } + INIStructure originalData; + T_LineDataPtr lineData; + bool readSuccess = false; + bool fileIsBOM = false; + { + INIReader reader(filename, true); + if ((readSuccess = reader >> originalData)) + { + lineData = reader.getLines(); + fileIsBOM = reader.isBOM; + } + } + if (!readSuccess) + { + return false; + } + T_LineData output = getLazyOutput(lineData, data, originalData); + std::ofstream fileWriteStream(filename, std::ios::out | std::ios::binary); + if (fileWriteStream.is_open()) + { + if (fileIsBOM) { + const char utf8_BOM[3] = { + static_cast(0xEF), + static_cast(0xBB), + static_cast(0xBF) + }; + fileWriteStream.write(utf8_BOM, 3); + } + if (output.size()) + { + auto line = output.begin(); + for (;;) + { + fileWriteStream << *line; + if (++line == output.end()) + { + break; + } + fileWriteStream << INIStringUtil::endl; + } + } + return true; + } + return false; + } + }; + + class INIFile + { + private: + std::string filename; + + public: + INIFile(std::string const& filename) + : filename(filename) + { } + + ~INIFile() { } + + bool read(INIStructure& data) const + { + if (data.size()) + { + data.clear(); + } + if (filename.empty()) + { + return false; + } + INIReader reader(filename); + return reader >> data; + } + bool generate(INIStructure const& data, bool pretty = false) const + { + if (filename.empty()) + { + return false; + } + INIGenerator generator(filename); + generator.prettyPrint = pretty; + return generator << data; + } + bool write(INIStructure& data, bool pretty = false) const + { + if (filename.empty()) + { + return false; + } + INIWriter writer(filename); + writer.prettyPrint = pretty; + return writer << data; + } + }; +} + #endif // MINI_INI_H_ \ No newline at end of file diff --git a/hook_lib/json.hpp b/hook_lib/json.hpp index 5292177..0457c72 100644 --- a/hook_lib/json.hpp +++ b/hook_lib/json.hpp @@ -1,24673 +1,24673 @@ -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - -/****************************************************************************\ - * Note on documentation: The source files contain links to the online * - * documentation of the public API at https://json.nlohmann.me. This URL * - * contains the most recent documentation and should also be applicable to * - * previous versions; documentation for deprecated functions is not * - * removed, but marked deprecated. See "Generate documentation" section in * - * file docs/README.md. * -\****************************************************************************/ - -#ifndef INCLUDE_NLOHMANN_JSON_HPP_ -#define INCLUDE_NLOHMANN_JSON_HPP_ - -#include // all_of, find, for_each -#include // nullptr_t, ptrdiff_t, size_t -#include // hash, less -#include // initializer_list -#ifndef JSON_NO_IO -#include // istream, ostream -#endif // JSON_NO_IO -#include // random_access_iterator_tag -#include // unique_ptr -#include // string, stoi, to_string -#include // declval, forward, move, pair, swap -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// This file contains all macro definitions affecting or depending on the ABI - -#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK -#if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) -#if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 2 -#warning "Already included a different version of the library!" -#endif -#endif -#endif - -#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_PATCH 2 // NOLINT(modernize-macro-to-enum) - -#ifndef JSON_DIAGNOSTICS -#define JSON_DIAGNOSTICS 0 -#endif - -#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON -#define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 -#endif - -#if JSON_DIAGNOSTICS -#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag -#else -#define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS -#endif - -#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON -#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp -#else -#define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION -#define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 -#endif - -// Construct the namespace ABI tags component -#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b -#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ - NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) - -#define NLOHMANN_JSON_ABI_TAGS \ - NLOHMANN_JSON_ABI_TAGS_CONCAT( \ - NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ - NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) - -// Construct the namespace version component -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ - _v ## major ## _ ## minor ## _ ## patch -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) - -#if NLOHMANN_JSON_NAMESPACE_NO_VERSION -#define NLOHMANN_JSON_NAMESPACE_VERSION -#else -#define NLOHMANN_JSON_NAMESPACE_VERSION \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ - NLOHMANN_JSON_VERSION_MINOR, \ - NLOHMANN_JSON_VERSION_PATCH) -#endif - -// Combine namespace components -#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b -#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ - NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) - -#ifndef NLOHMANN_JSON_NAMESPACE -#define NLOHMANN_JSON_NAMESPACE \ - nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN -#define NLOHMANN_JSON_NAMESPACE_BEGIN \ - namespace nlohmann \ - { \ - inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) \ - { -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_END -#define NLOHMANN_JSON_NAMESPACE_END \ - } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ - } // namespace nlohmann -#endif - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // transform -#include // array -#include // forward_list -#include // inserter, front_inserter, end -#include // map -#include // string -#include // tuple, make_tuple -#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible -#include // unordered_map -#include // pair, declval -#include // valarray - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // nullptr_t -#include // exception -#if JSON_DIAGNOSTICS -#include // accumulate -#endif -#include // runtime_error -#include // to_string -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // uint8_t -#include // string - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // declval, pair -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - - template struct make_void - { - using type = void; - }; - template using void_t = typename make_void::type; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - - // https://en.cppreference.com/w/cpp/experimental/is_detected - struct nonesuch - { - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; - }; - - template class Op, - class... Args> - struct detector - { - using value_t = std::false_type; - using type = Default; - }; - - template class Op, class... Args> - struct detector>, Op, Args...> - { - using value_t = std::true_type; - using type = Op; - }; - - template class Op, class... Args> - using is_detected = typename detector::value_t; - - template class Op, class... Args> - struct is_detected_lazy : is_detected { }; - - template class Op, class... Args> - using detected_t = typename detector::type; - - template class Op, class... Args> - using detected_or = detector; - - template class Op, class... Args> - using detected_or_t = typename detected_or::type; - - template class Op, class... Args> - using is_detected_exact = std::is_same>; - - template class Op, class... Args> - using is_detected_convertible = - std::is_convertible, To>; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - - -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson -// SPDX-License-Identifier: MIT - -/* Hedley - https://nemequ.github.io/hedley - * Created by Evan Nemerson - */ - -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) -#if defined(JSON_HEDLEY_VERSION) -#undef JSON_HEDLEY_VERSION -#endif -#define JSON_HEDLEY_VERSION 15 - -#if defined(JSON_HEDLEY_STRINGIFY_EX) -#undef JSON_HEDLEY_STRINGIFY_EX -#endif -#define JSON_HEDLEY_STRINGIFY_EX(x) #x - -#if defined(JSON_HEDLEY_STRINGIFY) -#undef JSON_HEDLEY_STRINGIFY -#endif -#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) - -#if defined(JSON_HEDLEY_CONCAT_EX) -#undef JSON_HEDLEY_CONCAT_EX -#endif -#define JSON_HEDLEY_CONCAT_EX(a,b) a##b - -#if defined(JSON_HEDLEY_CONCAT) -#undef JSON_HEDLEY_CONCAT -#endif -#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) - -#if defined(JSON_HEDLEY_CONCAT3_EX) -#undef JSON_HEDLEY_CONCAT3_EX -#endif -#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c - -#if defined(JSON_HEDLEY_CONCAT3) -#undef JSON_HEDLEY_CONCAT3 -#endif -#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) - -#if defined(JSON_HEDLEY_VERSION_ENCODE) -#undef JSON_HEDLEY_VERSION_ENCODE -#endif -#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) -#undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) -#undef JSON_HEDLEY_VERSION_DECODE_MINOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) -#undef JSON_HEDLEY_VERSION_DECODE_REVISION -#endif -#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) - -#if defined(JSON_HEDLEY_GNUC_VERSION) -#undef JSON_HEDLEY_GNUC_VERSION -#endif -#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) -#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#elif defined(__GNUC__) -#define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) -#endif - -#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) -#undef JSON_HEDLEY_GNUC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GNUC_VERSION) -#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION) -#undef JSON_HEDLEY_MSVC_VERSION -#endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) -#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) && !defined(__ICL) -#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) && !defined(__ICL) -#define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) -#undef JSON_HEDLEY_MSVC_VERSION_CHECK -#endif -#if !defined(JSON_HEDLEY_MSVC_VERSION) -#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) -#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) -#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) -#else -#define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION) -#undef JSON_HEDLEY_INTEL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) -#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) && !defined(__ICL) -#define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) -#undef JSON_HEDLEY_INTEL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_VERSION) -#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) -#undef JSON_HEDLEY_INTEL_CL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) -#define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) -#undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) -#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION) -#undef JSON_HEDLEY_PGI_VERSION -#endif -#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) -#define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) -#undef JSON_HEDLEY_PGI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PGI_VERSION) -#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION) -#undef JSON_HEDLEY_SUNPRO_VERSION -#endif -#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) -#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) -#elif defined(__SUNPRO_C) -#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) -#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) -#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) -#elif defined(__SUNPRO_CC) -#define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) -#undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_SUNPRO_VERSION) -#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) -#undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#endif -#if defined(__EMSCRIPTEN__) -#define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) -#undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) -#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION) -#undef JSON_HEDLEY_ARM_VERSION -#endif -#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) -#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) -#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) -#define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) -#undef JSON_HEDLEY_ARM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_ARM_VERSION) -#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION) -#undef JSON_HEDLEY_IBM_VERSION -#endif -#if defined(__ibmxl__) -#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) -#elif defined(__xlC__) && defined(__xlC_ver__) -#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) -#elif defined(__xlC__) -#define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) -#undef JSON_HEDLEY_IBM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IBM_VERSION) -#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_VERSION) -#undef JSON_HEDLEY_TI_VERSION -#endif -#if \ - defined(__TI_COMPILER_VERSION__) && \ - ( \ - defined(__TMS470__) || defined(__TI_ARM__) || \ - defined(__MSP430__) || \ - defined(__TMS320C2000__) \ - ) -#if (__TI_COMPILER_VERSION__ >= 16000000) -#define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif -#endif - -#if defined(JSON_HEDLEY_TI_VERSION_CHECK) -#undef JSON_HEDLEY_TI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_VERSION) -#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) -#undef JSON_HEDLEY_TI_CL2000_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) -#define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) -#undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) -#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION) -#undef JSON_HEDLEY_TI_CL430_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) -#define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) -#undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL430_VERSION) -#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) -#undef JSON_HEDLEY_TI_ARMCL_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) -#define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) -#undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) -#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) -#undef JSON_HEDLEY_TI_CL6X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) -#define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) -#undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) -#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) -#undef JSON_HEDLEY_TI_CL7X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) -#define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) -#undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) -#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) -#undef JSON_HEDLEY_TI_CLPRU_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) -#define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) -#undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) -#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION) -#undef JSON_HEDLEY_CRAY_VERSION -#endif -#if defined(_CRAYC) -#if defined(_RELEASE_PATCHLEVEL) -#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) -#else -#define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) -#endif -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) -#undef JSON_HEDLEY_CRAY_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_CRAY_VERSION) -#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION) -#undef JSON_HEDLEY_IAR_VERSION -#endif -#if defined(__IAR_SYSTEMS_ICC__) -#if __VER__ > 1000 -#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) -#else -#define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) -#endif -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) -#undef JSON_HEDLEY_IAR_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IAR_VERSION) -#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION) -#undef JSON_HEDLEY_TINYC_VERSION -#endif -#if defined(__TINYC__) -#define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) -#undef JSON_HEDLEY_TINYC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TINYC_VERSION) -#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION) -#undef JSON_HEDLEY_DMC_VERSION -#endif -#if defined(__DMC__) -#define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) -#undef JSON_HEDLEY_DMC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_DMC_VERSION) -#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION) -#undef JSON_HEDLEY_COMPCERT_VERSION -#endif -#if defined(__COMPCERT_VERSION__) -#define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) -#undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_COMPCERT_VERSION) -#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION) -#undef JSON_HEDLEY_PELLES_VERSION -#endif -#if defined(__POCC__) -#define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) -#undef JSON_HEDLEY_PELLES_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PELLES_VERSION) -#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) -#undef JSON_HEDLEY_MCST_LCC_VERSION -#endif -#if defined(__LCC__) && defined(__LCC_MINOR__) -#define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) -#undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) -#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION) -#undef JSON_HEDLEY_GCC_VERSION -#endif -#if \ - defined(JSON_HEDLEY_GNUC_VERSION) && \ - !defined(__clang__) && \ - !defined(JSON_HEDLEY_INTEL_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_ARM_VERSION) && \ - !defined(JSON_HEDLEY_CRAY_VERSION) && \ - !defined(JSON_HEDLEY_TI_VERSION) && \ - !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ - !defined(__COMPCERT__) && \ - !defined(JSON_HEDLEY_MCST_LCC_VERSION) -#define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) -#undef JSON_HEDLEY_GCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GCC_VERSION) -#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else -#define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) -#undef JSON_HEDLEY_HAS_ATTRIBUTE -#endif -#if \ - defined(__has_attribute) && \ - ( \ - (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ - ) -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) -#else -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) -#undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) -#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else -#define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) -#undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) -#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else -#define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) -#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#endif -#if \ - defined(__has_cpp_attribute) && \ - defined(__cplusplus) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) -#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) -#else -#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) -#undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#endif -#if !defined(__cplusplus) || !defined(__has_cpp_attribute) -#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#elif \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ - (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) -#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) -#else -#define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) -#undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) -#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else -#define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) -#undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) -#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else -#define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_BUILTIN) -#undef JSON_HEDLEY_HAS_BUILTIN -#endif -#if defined(__has_builtin) -#define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) -#else -#define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) -#undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#endif -#if defined(__has_builtin) -#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else -#define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) -#undef JSON_HEDLEY_GCC_HAS_BUILTIN -#endif -#if defined(__has_builtin) -#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else -#define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_FEATURE) -#undef JSON_HEDLEY_HAS_FEATURE -#endif -#if defined(__has_feature) -#define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) -#else -#define JSON_HEDLEY_HAS_FEATURE(feature) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) -#undef JSON_HEDLEY_GNUC_HAS_FEATURE -#endif -#if defined(__has_feature) -#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else -#define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) -#undef JSON_HEDLEY_GCC_HAS_FEATURE -#endif -#if defined(__has_feature) -#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else -#define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_EXTENSION) -#undef JSON_HEDLEY_HAS_EXTENSION -#endif -#if defined(__has_extension) -#define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) -#else -#define JSON_HEDLEY_HAS_EXTENSION(extension) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) -#undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#endif -#if defined(__has_extension) -#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else -#define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) -#undef JSON_HEDLEY_GCC_HAS_EXTENSION -#endif -#if defined(__has_extension) -#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else -#define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) -#undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) -#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) -#else -#define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) -#undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) -#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else -#define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) -#undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) -#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else -#define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_WARNING) -#undef JSON_HEDLEY_HAS_WARNING -#endif -#if defined(__has_warning) -#define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) -#else -#define JSON_HEDLEY_HAS_WARNING(warning) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) -#undef JSON_HEDLEY_GNUC_HAS_WARNING -#endif -#if defined(__has_warning) -#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else -#define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_WARNING) -#undef JSON_HEDLEY_GCC_HAS_WARNING -#endif -#if defined(__has_warning) -#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else -#define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(__clang__) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) -#define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) -#define JSON_HEDLEY_PRAGMA(value) __pragma(value) -#else -#define JSON_HEDLEY_PRAGMA(value) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) -#undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#endif -#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) -#undef JSON_HEDLEY_DIAGNOSTIC_POP -#endif -#if defined(__clang__) -#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") -#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") -#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) -#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") -#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) -#define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) -#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) -#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") -#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) -#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") -#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) -#define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") -#define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#else -#define JSON_HEDLEY_DIAGNOSTIC_PUSH -#define JSON_HEDLEY_DIAGNOSTIC_POP -#endif - - /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") -# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") -# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# endif -#endif -#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x -#endif - -#if defined(JSON_HEDLEY_CONST_CAST) -#undef JSON_HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) -#elif \ - JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_REINTERPRET_CAST) -#undef JSON_HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) -#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) -#else -#define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_STATIC_CAST) -#undef JSON_HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) -#define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) -#else -#define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_CPP_CAST) -#undef JSON_HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ - ((T) (expr)) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("diag_suppress=Pe137") \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) -# endif -#else -# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") -#else -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") -#else -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#else -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") -#else -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) -#undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") -#else -#define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif - -#if defined(JSON_HEDLEY_DEPRECATED) -#undef JSON_HEDLEY_DEPRECATED -#endif -#if defined(JSON_HEDLEY_DEPRECATED_FOR) -#undef JSON_HEDLEY_DEPRECATED_FOR -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) -#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) -#elif \ - (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) -#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) -#elif defined(__cplusplus) && (__cplusplus >= 201402L) -#define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) -#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -#define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) -#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) -#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -#define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") -#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") -#else -#define JSON_HEDLEY_DEPRECATED(since) -#define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) -#endif - -#if defined(JSON_HEDLEY_UNAVAILABLE) -#undef JSON_HEDLEY_UNAVAILABLE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) -#else -#define JSON_HEDLEY_UNAVAILABLE(available_since) -#endif - -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) -#undef JSON_HEDLEY_WARN_UNUSED_RESULT -#endif -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) -#undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) -#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) -#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) -#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) -#define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#elif defined(_Check_return_) /* SAL */ -#define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ -#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ -#else -#define JSON_HEDLEY_WARN_UNUSED_RESULT -#define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) -#endif - -#if defined(JSON_HEDLEY_SENTINEL) -#undef JSON_HEDLEY_SENTINEL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) -#else -#define JSON_HEDLEY_SENTINEL(position) -#endif - -#if defined(JSON_HEDLEY_NO_RETURN) -#undef JSON_HEDLEY_NO_RETURN -#endif -#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -#define JSON_HEDLEY_NO_RETURN __noreturn -#elif \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -#define JSON_HEDLEY_NO_RETURN _Noreturn -#elif defined(__cplusplus) && (__cplusplus >= 201103L) -#define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -#define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -#define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) -#define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) -#define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) -#define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#else -#define JSON_HEDLEY_NO_RETURN -#endif - -#if defined(JSON_HEDLEY_NO_ESCAPE) -#undef JSON_HEDLEY_NO_ESCAPE -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) -#define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) -#else -#define JSON_HEDLEY_NO_ESCAPE -#endif - -#if defined(JSON_HEDLEY_UNREACHABLE) -#undef JSON_HEDLEY_UNREACHABLE -#endif -#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) -#undef JSON_HEDLEY_UNREACHABLE_RETURN -#endif -#if defined(JSON_HEDLEY_ASSUME) -#undef JSON_HEDLEY_ASSUME -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_ASSUME(expr) __assume(expr) -#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) -#define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) -#if defined(__cplusplus) -#define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) -#else -#define JSON_HEDLEY_ASSUME(expr) _nassert(expr) -#endif -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif defined(JSON_HEDLEY_ASSUME) -#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif -#if !defined(JSON_HEDLEY_ASSUME) -#if defined(JSON_HEDLEY_UNREACHABLE) -#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) -#else -#define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) -#endif -#endif -#if defined(JSON_HEDLEY_UNREACHABLE) -#if \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) -#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) -#else -#define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() -#endif -#else -#define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) -#endif -#if !defined(JSON_HEDLEY_UNREACHABLE) -#define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif - - JSON_HEDLEY_DIAGNOSTIC_PUSH -#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") -#pragma clang diagnostic ignored "-Wpedantic" -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) -#pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif -#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) -#if defined(__clang__) -#pragma clang diagnostic ignored "-Wvariadic-macros" -#elif defined(JSON_HEDLEY_GCC_VERSION) -#pragma GCC diagnostic ignored "-Wvariadic-macros" -#endif -#endif -#if defined(JSON_HEDLEY_NON_NULL) -#undef JSON_HEDLEY_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) -#define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else -#define JSON_HEDLEY_NON_NULL(...) -#endif - JSON_HEDLEY_DIAGNOSTIC_POP - -#if defined(JSON_HEDLEY_PRINTF_FORMAT) -#undef JSON_HEDLEY_PRINTF_FORMAT -#endif -#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) -#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) -#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) -#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) -#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) -#else -#define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) -#endif - -#if defined(JSON_HEDLEY_CONSTEXPR) -#undef JSON_HEDLEY_CONSTEXPR -#endif -#if defined(__cplusplus) -#if __cplusplus >= 201103L -#define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) -#endif -#endif -#if !defined(JSON_HEDLEY_CONSTEXPR) -#define JSON_HEDLEY_CONSTEXPR -#endif - -#if defined(JSON_HEDLEY_PREDICT) -#undef JSON_HEDLEY_PREDICT -#endif -#if defined(JSON_HEDLEY_LIKELY) -#undef JSON_HEDLEY_LIKELY -#endif -#if defined(JSON_HEDLEY_UNLIKELY) -#undef JSON_HEDLEY_UNLIKELY -#endif -#if defined(JSON_HEDLEY_UNPREDICTABLE) -#undef JSON_HEDLEY_UNPREDICTABLE -#endif -#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) -#define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) -#elif \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ - })) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ - })) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) -# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) -#endif -#if !defined(JSON_HEDLEY_UNPREDICTABLE) -#define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) -#endif - -#if defined(JSON_HEDLEY_MALLOC) -#undef JSON_HEDLEY_MALLOC -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -#define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_MALLOC __declspec(restrict) -#else -#define JSON_HEDLEY_MALLOC -#endif - -#if defined(JSON_HEDLEY_PURE) -#undef JSON_HEDLEY_PURE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PURE __attribute__((__pure__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ - ) -# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") -#else -# define JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_CONST) -#undef JSON_HEDLEY_CONST -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_CONST __attribute__((__const__)) -#elif \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -#define JSON_HEDLEY_CONST _Pragma("no_side_effect") -#else -#define JSON_HEDLEY_CONST JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_RESTRICT) -#undef JSON_HEDLEY_RESTRICT -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) -#define JSON_HEDLEY_RESTRICT restrict -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_RESTRICT __restrict -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) -#define JSON_HEDLEY_RESTRICT _Restrict -#else -#define JSON_HEDLEY_RESTRICT -#endif - -#if defined(JSON_HEDLEY_INLINE) -#undef JSON_HEDLEY_INLINE -#endif -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 199711L)) -#define JSON_HEDLEY_INLINE inline -#elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) -#define JSON_HEDLEY_INLINE __inline__ -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_INLINE __inline -#else -#define JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_ALWAYS_INLINE) -#undef JSON_HEDLEY_ALWAYS_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_ALWAYS_INLINE __forceinline -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ - ) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") -#else -# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_NEVER_INLINE) -#undef JSON_HEDLEY_NEVER_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -#define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) -#define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) -#define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -#define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) -#define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) -#define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#else -#define JSON_HEDLEY_NEVER_INLINE -#endif - -#if defined(JSON_HEDLEY_PRIVATE) -#undef JSON_HEDLEY_PRIVATE -#endif -#if defined(JSON_HEDLEY_PUBLIC) -#undef JSON_HEDLEY_PUBLIC -#endif -#if defined(JSON_HEDLEY_IMPORT) -#undef JSON_HEDLEY_IMPORT -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC __declspec(dllexport) -# define JSON_HEDLEY_IMPORT __declspec(dllimport) -#else -# if \ - JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - ( \ - defined(__TI_EABI__) && \ - ( \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ - ) \ - ) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) -# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) -# else -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC -# endif -# define JSON_HEDLEY_IMPORT extern -#endif - -#if defined(JSON_HEDLEY_NO_THROW) -#undef JSON_HEDLEY_NO_THROW -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) -#define JSON_HEDLEY_NO_THROW __declspec(nothrow) -#else -#define JSON_HEDLEY_NO_THROW -#endif - -#if defined(JSON_HEDLEY_FALL_THROUGH) -#undef JSON_HEDLEY_FALL_THROUGH -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) -#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) -#define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) -#elif defined(__fallthrough) /* SAL */ -#define JSON_HEDLEY_FALL_THROUGH __fallthrough -#else -#define JSON_HEDLEY_FALL_THROUGH -#endif - -#if defined(JSON_HEDLEY_RETURNS_NON_NULL) -#undef JSON_HEDLEY_RETURNS_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) -#elif defined(_Ret_notnull_) /* SAL */ -#define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ -#else -#define JSON_HEDLEY_RETURNS_NON_NULL -#endif - -#if defined(JSON_HEDLEY_ARRAY_PARAM) -#undef JSON_HEDLEY_ARRAY_PARAM -#endif -#if \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__STDC_NO_VLA__) && \ - !defined(__cplusplus) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_TINYC_VERSION) -#define JSON_HEDLEY_ARRAY_PARAM(name) (name) -#else -#define JSON_HEDLEY_ARRAY_PARAM(name) -#endif - -#if defined(JSON_HEDLEY_IS_CONSTANT) -#undef JSON_HEDLEY_IS_CONSTANT -#endif -#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) -#undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#endif - /* JSON_HEDLEY_IS_CONSTEXPR_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) -#undef JSON_HEDLEY_IS_CONSTEXPR_ -#endif -#if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -#define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) -#endif -#if !defined(__cplusplus) -# if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) -#if defined(__INTPTR_TYPE__) -#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) -#else -#include -#define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) -#endif -# elif \ - ( \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ - !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION)) || \ - (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) -#if defined(__INTPTR_TYPE__) -#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) -#else -#include -#define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) -#endif -# elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - defined(JSON_HEDLEY_INTEL_VERSION) || \ - defined(JSON_HEDLEY_TINYC_VERSION) || \ - defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ - defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ - defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ - defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ - defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ - defined(__clang__) -# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ - sizeof(void) != \ - sizeof(*( \ - 1 ? \ - ((void*) ((expr) * 0L) ) : \ -((struct { char v[sizeof(void) * 2]; } *) 1) \ - ) \ - ) \ - ) -# endif -#endif -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) -#if !defined(JSON_HEDLEY_IS_CONSTANT) -#define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) -#endif -#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) -#else -#if !defined(JSON_HEDLEY_IS_CONSTANT) -#define JSON_HEDLEY_IS_CONSTANT(expr) (0) -#endif -#define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) -#endif - -#if defined(JSON_HEDLEY_BEGIN_C_DECLS) -#undef JSON_HEDLEY_BEGIN_C_DECLS -#endif -#if defined(JSON_HEDLEY_END_C_DECLS) -#undef JSON_HEDLEY_END_C_DECLS -#endif -#if defined(JSON_HEDLEY_C_DECL) -#undef JSON_HEDLEY_C_DECL -#endif -#if defined(__cplusplus) -#define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { -#define JSON_HEDLEY_END_C_DECLS } -#define JSON_HEDLEY_C_DECL extern "C" -#else -#define JSON_HEDLEY_BEGIN_C_DECLS -#define JSON_HEDLEY_END_C_DECLS -#define JSON_HEDLEY_C_DECL -#endif - -#if defined(JSON_HEDLEY_STATIC_ASSERT) -#undef JSON_HEDLEY_STATIC_ASSERT -#endif -#if \ - !defined(__cplusplus) && ( \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - defined(_Static_assert) \ - ) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) -#elif \ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) -#else -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) -#endif - -#if defined(JSON_HEDLEY_NULL) -#undef JSON_HEDLEY_NULL -#endif -#if defined(__cplusplus) -#if __cplusplus >= 201103L -#define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) -#elif defined(NULL) -#define JSON_HEDLEY_NULL NULL -#else -#define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) -#endif -#elif defined(NULL) -#define JSON_HEDLEY_NULL NULL -#else -#define JSON_HEDLEY_NULL ((void*) 0) -#endif - -#if defined(JSON_HEDLEY_MESSAGE) -#undef JSON_HEDLEY_MESSAGE -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_MESSAGE(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(message msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) -#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_WARNING) -#undef JSON_HEDLEY_WARNING -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_WARNING(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(clang warning msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_REQUIRE) -#undef JSON_HEDLEY_REQUIRE -#endif -#if defined(JSON_HEDLEY_REQUIRE_MSG) -#undef JSON_HEDLEY_REQUIRE_MSG -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) -# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") -# define JSON_HEDLEY_REQUIRE(expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), #expr, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), msg, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) -# endif -#else -# define JSON_HEDLEY_REQUIRE(expr) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) -#endif - -#if defined(JSON_HEDLEY_FLAGS) -#undef JSON_HEDLEY_FLAGS -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) -#define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) -#else -#define JSON_HEDLEY_FLAGS -#endif - -#if defined(JSON_HEDLEY_FLAGS_CAST) -#undef JSON_HEDLEY_FLAGS_CAST -#endif -#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) -# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("warning(disable:188)") \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) -#endif - -#if defined(JSON_HEDLEY_EMPTY_BASES) -#undef JSON_HEDLEY_EMPTY_BASES -#endif -#if \ - (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -#define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) -#else -#define JSON_HEDLEY_EMPTY_BASES -#endif - - /* Remaining macros are deprecated. */ - -#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) -#undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#endif -#if defined(__clang__) -#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) -#else -#define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) -#undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) -#undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) -#undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#endif -#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) - -#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) -#undef JSON_HEDLEY_CLANG_HAS_FEATURE -#endif -#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) - -#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) -#undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#endif -#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) - -#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) -#undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) -#undef JSON_HEDLEY_CLANG_HAS_WARNING -#endif -#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) - -#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ - - -// This file contains all internal macro definitions (except those affecting ABI) -// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them - -// #include - - -// exclude unsupported compilers -#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) -#if defined(__clang__) -#if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 -#error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" -#endif -#elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) -#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 -#error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" -#endif -#endif -#endif - -// C++ language standard detection -// if the user manually specified the used c++ version this is skipped -#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) -#if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) -#define JSON_HAS_CPP_20 -#define JSON_HAS_CPP_17 -#define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 -#define JSON_HAS_CPP_17 -#define JSON_HAS_CPP_14 -#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) -#define JSON_HAS_CPP_14 -#endif -// the cpp 11 flag is always specified because it is the minimal required version -#define JSON_HAS_CPP_11 -#endif - -#ifdef __has_include -#if __has_include() -#include -#endif -#endif - -#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) -#ifdef JSON_HAS_CPP_17 -#if defined(__cpp_lib_filesystem) -#define JSON_HAS_FILESYSTEM 1 -#elif defined(__cpp_lib_experimental_filesystem) -#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 -#elif !defined(__has_include) -#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 -#elif __has_include() -#define JSON_HAS_FILESYSTEM 1 -#elif __has_include() -#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 -#endif - -// std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ -#if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 -#undef JSON_HAS_FILESYSTEM -#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM -#endif - -// no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support -#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 -#undef JSON_HAS_FILESYSTEM -#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM -#endif - -// no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support -#if defined(__clang_major__) && __clang_major__ < 7 -#undef JSON_HAS_FILESYSTEM -#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM -#endif - -// no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support -#if defined(_MSC_VER) && _MSC_VER < 1914 -#undef JSON_HAS_FILESYSTEM -#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM -#endif - -// no filesystem support before iOS 13 -#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 -#undef JSON_HAS_FILESYSTEM -#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM -#endif - -// no filesystem support before macOS Catalina -#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 -#undef JSON_HAS_FILESYSTEM -#undef JSON_HAS_EXPERIMENTAL_FILESYSTEM -#endif -#endif -#endif - -#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM -#define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_FILESYSTEM -#define JSON_HAS_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_THREE_WAY_COMPARISON -#if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ - && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L -#define JSON_HAS_THREE_WAY_COMPARISON 1 -#else -#define JSON_HAS_THREE_WAY_COMPARISON 0 -#endif -#endif - -#ifndef JSON_HAS_RANGES - // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error -#if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 -#define JSON_HAS_RANGES 0 -#elif defined(__cpp_lib_ranges) -#define JSON_HAS_RANGES 1 -#else -#define JSON_HAS_RANGES 0 -#endif -#endif - -#ifdef JSON_HAS_CPP_17 -#define JSON_INLINE_VARIABLE inline -#else -#define JSON_INLINE_VARIABLE -#endif - -#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) -#define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] -#else -#define JSON_NO_UNIQUE_ADDRESS -#endif - -// disable documentation warnings on clang -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdocumentation" -#pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -#endif - -// allow disabling exceptions -#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) -#define JSON_THROW(exception) throw exception -#define JSON_TRY try -#define JSON_CATCH(exception) catch(exception) -#define JSON_INTERNAL_CATCH(exception) catch(exception) -#else -#include -#define JSON_THROW(exception) std::abort() -#define JSON_TRY if(true) -#define JSON_CATCH(exception) if(false) -#define JSON_INTERNAL_CATCH(exception) if(false) -#endif - -// override exception macros -#if defined(JSON_THROW_USER) -#undef JSON_THROW -#define JSON_THROW JSON_THROW_USER -#endif -#if defined(JSON_TRY_USER) -#undef JSON_TRY -#define JSON_TRY JSON_TRY_USER -#endif -#if defined(JSON_CATCH_USER) -#undef JSON_CATCH -#define JSON_CATCH JSON_CATCH_USER -#undef JSON_INTERNAL_CATCH -#define JSON_INTERNAL_CATCH JSON_CATCH_USER -#endif -#if defined(JSON_INTERNAL_CATCH_USER) -#undef JSON_INTERNAL_CATCH -#define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER -#endif - -// allow overriding assert -#if !defined(JSON_ASSERT) -#include // assert -#define JSON_ASSERT(x) assert(x) -#endif - -// allow to access some private functions (needed by the test suite) -#if defined(JSON_TESTS_PRIVATE) -#define JSON_PRIVATE_UNLESS_TESTED public -#else -#define JSON_PRIVATE_UNLESS_TESTED private -#endif - -/*! -@brief macro to briefly define a mapping between an enum and JSON -@def NLOHMANN_JSON_SERIALIZE_ENUM -@since version 3.4.0 -*/ -#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template \ - inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.first == e; \ - }); \ - j = ((it != std::end(m)) ? it : std::begin(m))->second; \ - } \ - template \ - inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [&j](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.second == j; \ - }); \ - e = ((it != std::end(m)) ? it : std::begin(m))->first; \ - } - -// Ugly macros to avoid uglier copy-paste when specializing basic_json. They -// may be removed in the future once the class is split. - -#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ - template class ObjectType, \ - template class ArrayType, \ - class StringType, class BooleanType, class NumberIntegerType, \ - class NumberUnsignedType, class NumberFloatType, \ - template class AllocatorType, \ - template class JSONSerializer, \ - class BinaryType, \ - class CustomBaseClass> - -#define NLOHMANN_BASIC_JSON_TPL \ - basic_json - -// Macros to simplify conversion from/to types - -#define NLOHMANN_JSON_EXPAND( x ) x -#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME -#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ - NLOHMANN_JSON_PASTE64, \ - NLOHMANN_JSON_PASTE63, \ - NLOHMANN_JSON_PASTE62, \ - NLOHMANN_JSON_PASTE61, \ - NLOHMANN_JSON_PASTE60, \ - NLOHMANN_JSON_PASTE59, \ - NLOHMANN_JSON_PASTE58, \ - NLOHMANN_JSON_PASTE57, \ - NLOHMANN_JSON_PASTE56, \ - NLOHMANN_JSON_PASTE55, \ - NLOHMANN_JSON_PASTE54, \ - NLOHMANN_JSON_PASTE53, \ - NLOHMANN_JSON_PASTE52, \ - NLOHMANN_JSON_PASTE51, \ - NLOHMANN_JSON_PASTE50, \ - NLOHMANN_JSON_PASTE49, \ - NLOHMANN_JSON_PASTE48, \ - NLOHMANN_JSON_PASTE47, \ - NLOHMANN_JSON_PASTE46, \ - NLOHMANN_JSON_PASTE45, \ - NLOHMANN_JSON_PASTE44, \ - NLOHMANN_JSON_PASTE43, \ - NLOHMANN_JSON_PASTE42, \ - NLOHMANN_JSON_PASTE41, \ - NLOHMANN_JSON_PASTE40, \ - NLOHMANN_JSON_PASTE39, \ - NLOHMANN_JSON_PASTE38, \ - NLOHMANN_JSON_PASTE37, \ - NLOHMANN_JSON_PASTE36, \ - NLOHMANN_JSON_PASTE35, \ - NLOHMANN_JSON_PASTE34, \ - NLOHMANN_JSON_PASTE33, \ - NLOHMANN_JSON_PASTE32, \ - NLOHMANN_JSON_PASTE31, \ - NLOHMANN_JSON_PASTE30, \ - NLOHMANN_JSON_PASTE29, \ - NLOHMANN_JSON_PASTE28, \ - NLOHMANN_JSON_PASTE27, \ - NLOHMANN_JSON_PASTE26, \ - NLOHMANN_JSON_PASTE25, \ - NLOHMANN_JSON_PASTE24, \ - NLOHMANN_JSON_PASTE23, \ - NLOHMANN_JSON_PASTE22, \ - NLOHMANN_JSON_PASTE21, \ - NLOHMANN_JSON_PASTE20, \ - NLOHMANN_JSON_PASTE19, \ - NLOHMANN_JSON_PASTE18, \ - NLOHMANN_JSON_PASTE17, \ - NLOHMANN_JSON_PASTE16, \ - NLOHMANN_JSON_PASTE15, \ - NLOHMANN_JSON_PASTE14, \ - NLOHMANN_JSON_PASTE13, \ - NLOHMANN_JSON_PASTE12, \ - NLOHMANN_JSON_PASTE11, \ - NLOHMANN_JSON_PASTE10, \ - NLOHMANN_JSON_PASTE9, \ - NLOHMANN_JSON_PASTE8, \ - NLOHMANN_JSON_PASTE7, \ - NLOHMANN_JSON_PASTE6, \ - NLOHMANN_JSON_PASTE5, \ - NLOHMANN_JSON_PASTE4, \ - NLOHMANN_JSON_PASTE3, \ - NLOHMANN_JSON_PASTE2, \ - NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) -#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) -#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) -#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) -#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) -#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) -#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) -#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) -#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) -#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) -#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) -#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) -#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) -#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) -#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) -#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) -#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) -#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) -#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) -#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) -#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) -#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) -#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) -#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) -#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) -#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) -#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) -#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) -#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) -#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) -#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) -#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) -#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) -#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) -#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) -#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) -#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) -#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) -#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) -#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) -#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) -#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) -#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) -#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) -#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) -#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) -#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) -#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) -#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) -#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) -#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) -#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) -#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) -#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) -#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) -#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) -#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) - -#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; -#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); -#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - - -// inspired from https://stackoverflow.com/a/26745591 -// allows to call any std function as if (e.g. with begin): -// using std::begin; begin(x); -// -// it allows using the detected idiom to retrieve the return type -// of such an expression -#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ - namespace detail { \ - using std::std_name; \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - } \ - \ - namespace detail2 { \ - struct std_name##_tag \ - { \ - }; \ - \ - template \ - std_name##_tag std_name(T&&...); \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - \ - template \ - struct would_call_std_##std_name \ - { \ - static constexpr auto const value = ::nlohmann::detail:: \ - is_detected_exact::value; \ - }; \ - } /* namespace detail2 */ \ - \ - template \ - struct would_call_std_##std_name : detail2::would_call_std_##std_name \ - { \ - } - -#ifndef JSON_USE_IMPLICIT_CONVERSIONS -#define JSON_USE_IMPLICIT_CONVERSIONS 1 -#endif - -#if JSON_USE_IMPLICIT_CONVERSIONS -#define JSON_EXPLICIT -#else -#define JSON_EXPLICIT explicit -#endif - -#ifndef JSON_DISABLE_ENUM_SERIALIZATION -#define JSON_DISABLE_ENUM_SERIALIZATION 0 -#endif - -#ifndef JSON_USE_GLOBAL_UDLS -#define JSON_USE_GLOBAL_UDLS 1 -#endif - -#if JSON_HAS_THREE_WAY_COMPARISON -#include // partial_ordering -#endif - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - - /////////////////////////// - // JSON type enumeration // - /////////////////////////// - - /*! - @brief the JSON type enumeration - - This enumeration collects the different JSON types. It is internally used to - distinguish the stored values, and the functions @ref basic_json::is_null(), - @ref basic_json::is_object(), @ref basic_json::is_array(), - @ref basic_json::is_string(), @ref basic_json::is_boolean(), - @ref basic_json::is_number() (with @ref basic_json::is_number_integer(), - @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), - @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and - @ref basic_json::is_structured() rely on it. - - @note There are three enumeration entries (number_integer, number_unsigned, and - number_float), because the library distinguishes these three types for numbers: - @ref basic_json::number_unsigned_t is used for unsigned integers, - @ref basic_json::number_integer_t is used for signed integers, and - @ref basic_json::number_float_t is used for floating-point numbers or to - approximate integers which do not fit in the limits of their respective type. - - @sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON - value with the default value for a given type - - @since version 1.0.0 - */ - enum class value_t : std::uint8_t - { - null, ///< null value - object, ///< object (unordered set of name/value pairs) - array, ///< array (ordered collection of values) - string, ///< string value - boolean, ///< boolean value - number_integer, ///< number value (signed integer) - number_unsigned, ///< number value (unsigned integer) - number_float, ///< number value (floating-point) - binary, ///< binary array (ordered collection of bytes) - discarded ///< discarded by the parser callback function - }; - - /*! - @brief comparison operator for JSON types - - Returns an ordering that is similar to Python: - - order: null < boolean < number < object < array < string < binary - - furthermore, each type is not smaller than itself - - discarded values are not comparable - - binary is represented as a b"" string in python and directly comparable to a - string; however, making a binary array directly comparable with a string would - be surprising behavior in a JSON file. - - @since version 1.0.0 - */ -#if JSON_HAS_THREE_WAY_COMPARISON - inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* -#else - inline bool operator<(const value_t lhs, const value_t rhs) noexcept -#endif - { - static constexpr std::array order = { { - 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, - 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, - 6 /* binary */ - } - }; - - const auto l_index = static_cast(lhs); - const auto r_index = static_cast(rhs); -#if JSON_HAS_THREE_WAY_COMPARISON - if (l_index < order.size() && r_index < order.size()) - { - return order[l_index] <=> order[r_index]; // *NOPAD* - } - return std::partial_ordering::unordered; -#else - return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; -#endif - } - - // GCC selects the built-in operator< over an operator rewritten from - // a user-defined spaceship operator - // Clang, MSVC, and ICC select the rewritten candidate - // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) -#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) - inline bool operator<(const value_t lhs, const value_t rhs) noexcept - { - return std::is_lt(lhs <=> rhs); // *NOPAD* - } -#endif - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - - /*! - @brief replace all occurrences of a substring by another string - - @param[in,out] s the string to manipulate; changed so that all - occurrences of @a f are replaced with @a t - @param[in] f the substring to replace with @a t - @param[in] t the string to replace @a f - - @pre The search string @a f must not be empty. **This precondition is - enforced with an assertion.** - - @since version 2.0.0 - */ - template - inline void replace_substring(StringType& s, const StringType& f, - const StringType& t) - { - JSON_ASSERT(!f.empty()); - for (auto pos = s.find(f); // find first occurrence of f - pos != StringType::npos; // make sure f was found - s.replace(pos, f.size(), t), // replace with t, and - pos = s.find(f, pos + t.size())) // find next occurrence of f - { - } - } - - /*! - * @brief string escaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to escape - * @return escaped string - * - * Note the order of escaping "~" to "~0" and "/" to "~1" is important. - */ - template - inline StringType escape(StringType s) - { - replace_substring(s, StringType{ "~" }, StringType{ "~0" }); - replace_substring(s, StringType{ "/" }, StringType{ "~1" }); - return s; - } - - /*! - * @brief string unescaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to unescape - * @return unescaped string - * - * Note the order of escaping "~1" to "/" and "~0" to "~" is important. - */ - template - static void unescape(StringType& s) - { - replace_substring(s, StringType{ "~1" }, StringType{ "/" }); - replace_substring(s, StringType{ "~0" }, StringType{ "~" }); - } - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // size_t - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - - /// struct to capture the start position of the current token - struct position_t - { - /// the total number of characters read - std::size_t chars_read_total = 0; - /// the number of characters read in the current line - std::size_t chars_read_current_line = 0; - /// the number of lines read - std::size_t lines_read = 0; - - /// conversion to size_t to preserve SAX interface - constexpr operator size_t() const - { - return chars_read_total; - } - }; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-FileCopyrightText: 2018 The Abseil Authors -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type -#include // index_sequence, make_index_sequence, index_sequence_for - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - - template - using uncvref_t = typename std::remove_cv::type>::type; - -#ifdef JSON_HAS_CPP_14 - - // the following utilities are natively available in C++14 - using std::enable_if_t; - using std::index_sequence; - using std::make_index_sequence; - using std::index_sequence_for; - -#else - - // alias templates to reduce boilerplate - template - using enable_if_t = typename std::enable_if::type; - - // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h - // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. - - //// START OF CODE FROM GOOGLE ABSEIL - - // integer_sequence - // - // Class template representing a compile-time integer sequence. An instantiation - // of `integer_sequence` has a sequence of integers encoded in its - // type through its template arguments (which is a common need when - // working with C++11 variadic templates). `absl::integer_sequence` is designed - // to be a drop-in replacement for C++14's `std::integer_sequence`. - // - // Example: - // - // template< class T, T... Ints > - // void user_function(integer_sequence); - // - // int main() - // { - // // user_function's `T` will be deduced to `int` and `Ints...` - // // will be deduced to `0, 1, 2, 3, 4`. - // user_function(make_integer_sequence()); - // } - template - struct integer_sequence - { - using value_type = T; - static constexpr std::size_t size() noexcept - { - return sizeof...(Ints); - } - }; - - // index_sequence - // - // A helper template for an `integer_sequence` of `size_t`, - // `absl::index_sequence` is designed to be a drop-in replacement for C++14's - // `std::index_sequence`. - template - using index_sequence = integer_sequence; - - namespace utility_internal - { - - template - struct Extend; - - // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. - template - struct Extend, SeqSize, 0> - { - using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; - }; - - template - struct Extend, SeqSize, 1> - { - using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; - }; - - // Recursion helper for 'make_integer_sequence'. - // 'Gen::type' is an alias for 'integer_sequence'. - template - struct Gen - { - using type = - typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; - }; - - template - struct Gen - { - using type = integer_sequence; - }; - - } // namespace utility_internal - - // Compile-time sequences of integers - - // make_integer_sequence - // - // This template alias is equivalent to - // `integer_sequence`, and is designed to be a drop-in - // replacement for C++14's `std::make_integer_sequence`. - template - using make_integer_sequence = typename utility_internal::Gen::type; - - // make_index_sequence - // - // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, - // and is designed to be a drop-in replacement for C++14's - // `std::make_index_sequence`. - template - using make_index_sequence = make_integer_sequence; - - // index_sequence_for - // - // Converts a typename pack into an index sequence of the same length, and - // is designed to be a drop-in replacement for C++14's - // `std::index_sequence_for()` - template - using index_sequence_for = make_index_sequence; - - //// END OF CODE FROM GOOGLE ABSEIL - -#endif - -// dispatch utility (taken from ranges-v3) - template struct priority_tag : priority_tag < N - 1 > {}; - template<> struct priority_tag<0> {}; - - // taken from ranges-v3 - template - struct static_const - { - static JSON_INLINE_VARIABLE constexpr T value{}; - }; - -#ifndef JSON_HAS_CPP_17 - template - constexpr T static_const::value; -#endif - - template - inline constexpr std::array make_array(Args&& ... args) - { - return std::array { {static_cast(std::forward(args))...}}; - } - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // numeric_limits -#include // false_type, is_constructible, is_integral, is_same, true_type -#include // declval -#include // tuple - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // random_access_iterator_tag - -// #include - -// #include - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - - template - struct iterator_types {}; - - template - struct iterator_types < - It, - void_t> - { - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; - }; - - // This is required as some compilers implement std::iterator_traits in a way that - // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. - template - struct iterator_traits - { - }; - - template - struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> - : iterator_types - { - }; - - template - struct iterator_traits::value>> - { - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; - }; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); - -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); - -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.2 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann -// SPDX-License-Identifier: MIT - -#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ -#define INCLUDE_NLOHMANN_JSON_FWD_HPP_ - -#include // int64_t, uint64_t -#include // map -#include // allocator -#include // string -#include // vector - -// #include - - -/*! -@brief namespace for Niels Lohmann -@see https://github.com/nlohmann -@since version 1.0.0 -*/ -NLOHMANN_JSON_NAMESPACE_BEGIN - -/*! -@brief default JSONSerializer template argument - -This serializer ignores the template arguments and uses ADL -([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) -for serialization. -*/ -template -struct adl_serializer; - -/// a class to store JSON values -/// @sa https://json.nlohmann.me/api/basic_json/ -template class ObjectType = - std::map, - template class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template class AllocatorType = std::allocator, - template class JSONSerializer = - adl_serializer, - class BinaryType = std::vector, // cppcheck-suppress syntaxError - class CustomBaseClass = void> - class basic_json; - -/// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document -/// @sa https://json.nlohmann.me/api/json_pointer/ -template -class json_pointer; - -/*! -@brief default specialization -@sa https://json.nlohmann.me/api/json/ -*/ -using json = basic_json<>; - -/// @brief a minimal map-like container that preserves insertion order -/// @sa https://json.nlohmann.me/api/ordered_map/ -template -struct ordered_map; - -/// @brief specialization that maintains the insertion order of object keys -/// @sa https://json.nlohmann.me/api/ordered_json/ -using ordered_json = basic_json; - -NLOHMANN_JSON_NAMESPACE_END - -#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - -NLOHMANN_JSON_NAMESPACE_BEGIN -/*! -@brief detail namespace with internal helper functions - -This namespace collects functions that should not be exposed, -implementations of some @ref basic_json methods, and meta-programming helpers. - -@since version 2.1.0 -*/ -namespace detail -{ - - ///////////// - // helpers // - ///////////// - - // Note to maintainers: - // - // Every trait in this file expects a non CV-qualified type. - // The only exceptions are in the 'aliases for detected' section - // (i.e. those of the form: decltype(T::member_function(std::declval()))) - // - // In this case, T has to be properly CV-qualified to constraint the function arguments - // (e.g. to_json(BasicJsonType&, const T&)) - - template struct is_basic_json : std::false_type {}; - - NLOHMANN_BASIC_JSON_TPL_DECLARATION - struct is_basic_json : std::true_type {}; - - // used by exceptions create() member functions - // true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t - // false_type otherwise - template - struct is_basic_json_context : - std::integral_constant < bool, - is_basic_json::type>::type>::value - || std::is_same::value > - {}; - - ////////////////////// - // json_ref helpers // - ////////////////////// - - template - class json_ref; - - template - struct is_json_ref : std::false_type {}; - - template - struct is_json_ref> : std::true_type {}; - - ////////////////////////// - // aliases for detected // - ////////////////////////// - - template - using mapped_type_t = typename T::mapped_type; - - template - using key_type_t = typename T::key_type; - - template - using value_type_t = typename T::value_type; - - template - using difference_type_t = typename T::difference_type; - - template - using pointer_t = typename T::pointer; - - template - using reference_t = typename T::reference; - - template - using iterator_category_t = typename T::iterator_category; - - template - using to_json_function = decltype(T::to_json(std::declval()...)); - - template - using from_json_function = decltype(T::from_json(std::declval()...)); - - template - using get_template_function = decltype(std::declval().template get()); - - // trait checking if JSONSerializer::from_json(json const&, udt&) exists - template - struct has_from_json : std::false_type {}; - - // trait checking if j.get is valid - // use this trait instead of std::is_constructible or std::is_convertible, - // both rely on, or make use of implicit conversions, and thus fail when T - // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) - template - struct is_getable - { - static constexpr bool value = is_detected::value; - }; - - template - struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> - { - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; - }; - - // This trait checks if JSONSerializer::from_json(json const&) exists - // this overload is used for non-default-constructible user-defined-types - template - struct has_non_default_from_json : std::false_type {}; - - template - struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> - { - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; - }; - - // This trait checks if BasicJsonType::json_serializer::to_json exists - // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. - template - struct has_to_json : std::false_type {}; - - template - struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> - { - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; - }; - - template - using detect_key_compare = typename T::key_compare; - - template - struct has_key_compare : std::integral_constant::value> {}; - - // obtains the actual object key comparator - template - struct actual_object_comparator - { - using object_t = typename BasicJsonType::object_t; - using object_comparator_t = typename BasicJsonType::default_object_comparator_t; - using type = typename std::conditional < has_key_compare::value, - typename object_t::key_compare, object_comparator_t>::type; - }; - - template - using actual_object_comparator_t = typename actual_object_comparator::type; - - /////////////////// - // is_ functions // - /////////////////// - - // https://en.cppreference.com/w/cpp/types/conjunction - template struct conjunction : std::true_type { }; - template struct conjunction : B { }; - template - struct conjunction - : std::conditional(B::value), conjunction, B>::type {}; - - // https://en.cppreference.com/w/cpp/types/negation - template struct negation : std::integral_constant < bool, !B::value > { }; - - // Reimplementation of is_constructible and is_default_constructible, due to them being broken for - // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). - // This causes compile errors in e.g. clang 3.5 or gcc 4.9. - template - struct is_default_constructible : std::is_default_constructible {}; - - template - struct is_default_constructible> - : conjunction, is_default_constructible> {}; - - template - struct is_default_constructible> - : conjunction, is_default_constructible> {}; - - template - struct is_default_constructible> - : conjunction...> {}; - - template - struct is_default_constructible> - : conjunction...> {}; - - - template - struct is_constructible : std::is_constructible {}; - - template - struct is_constructible> : is_default_constructible> {}; - - template - struct is_constructible> : is_default_constructible> {}; - - template - struct is_constructible> : is_default_constructible> {}; - - template - struct is_constructible> : is_default_constructible> {}; - - - template - struct is_iterator_traits : std::false_type {}; - - template - struct is_iterator_traits> - { - private: - using traits = iterator_traits; - - public: - static constexpr auto value = - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value; - }; - - template - struct is_range - { - private: - using t_ref = typename std::add_lvalue_reference::type; - - using iterator = detected_t; - using sentinel = detected_t; - - // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator - // and https://en.cppreference.com/w/cpp/iterator/sentinel_for - // but reimplementing these would be too much work, as a lot of other concepts are used underneath - static constexpr auto is_iterator_begin = - is_iterator_traits>::value; - - public: - static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; - }; - - template - using iterator_t = enable_if_t::value, result_of_begin())>>; - - template - using range_value_t = value_type_t>>; - - // The following implementation of is_complete_type is taken from - // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ - // and is written by Xiang Fan who agreed to using it in this library. - - template - struct is_complete_type : std::false_type {}; - - template - struct is_complete_type : std::true_type {}; - - template - struct is_compatible_object_type_impl : std::false_type {}; - - template - struct is_compatible_object_type_impl < - BasicJsonType, CompatibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> - { - using object_t = typename BasicJsonType::object_t; - - // macOS's is_constructible does not play well with nonesuch... - static constexpr bool value = - is_constructible::value && - is_constructible::value; - }; - - template - struct is_compatible_object_type - : is_compatible_object_type_impl {}; - - template - struct is_constructible_object_type_impl : std::false_type {}; - - template - struct is_constructible_object_type_impl < - BasicJsonType, ConstructibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> - { - using object_t = typename BasicJsonType::object_t; - - static constexpr bool value = - (is_default_constructible::value && - (std::is_move_assignable::value || - std::is_copy_assignable::value) && - (is_constructible::value && - std::is_same < - typename object_t::mapped_type, - typename ConstructibleObjectType::mapped_type >::value)) || - (has_from_json::value || - has_non_default_from_json < - BasicJsonType, - typename ConstructibleObjectType::mapped_type >::value); - }; - - template - struct is_constructible_object_type - : is_constructible_object_type_impl {}; - - template - struct is_compatible_string_type - { - static constexpr auto value = - is_constructible::value; - }; - - template - struct is_constructible_string_type - { - // launder type through decltype() to fix compilation failure on ICPC -#ifdef __INTEL_COMPILER - using laundered_type = decltype(std::declval()); -#else - using laundered_type = ConstructibleStringType; -#endif - - static constexpr auto value = - conjunction < - is_constructible, - is_detected_exact>::value; - }; - - template - struct is_compatible_array_type_impl : std::false_type {}; - - template - struct is_compatible_array_type_impl < - BasicJsonType, CompatibleArrayType, - enable_if_t < - is_detected::value&& - is_iterator_traits>>::value && - // special case for types like std::filesystem::path whose iterator's value_type are themselves - // c.f. https://github.com/nlohmann/json/pull/3073 - !std::is_same>::value >> - { - static constexpr bool value = - is_constructible>::value; - }; - - template - struct is_compatible_array_type - : is_compatible_array_type_impl {}; - - template - struct is_constructible_array_type_impl : std::false_type {}; - - template - struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t::value >> - : std::true_type {}; - - template - struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t < !std::is_same::value && - !is_compatible_string_type::value&& - is_default_constructible::value && - (std::is_move_assignable::value || - std::is_copy_assignable::value) && - is_detected::value&& - is_iterator_traits>>::value&& - is_detected::value && - // special case for types like std::filesystem::path whose iterator's value_type are themselves - // c.f. https://github.com/nlohmann/json/pull/3073 - !std::is_same>::value&& - is_complete_type < - detected_t>::value >> - { - using value_type = range_value_t; - - static constexpr bool value = - std::is_same::value || - has_from_json::value || - has_non_default_from_json < - BasicJsonType, - value_type >::value; - }; - - template - struct is_constructible_array_type - : is_constructible_array_type_impl {}; - - template - struct is_compatible_integer_type_impl : std::false_type {}; - - template - struct is_compatible_integer_type_impl < - RealIntegerType, CompatibleNumberIntegerType, - enable_if_t < std::is_integral::value&& - std::is_integral::value && - !std::is_same::value >> - { - // is there an assert somewhere on overflows? - using RealLimits = std::numeric_limits; - using CompatibleLimits = std::numeric_limits; - - static constexpr auto value = - is_constructible::value && - CompatibleLimits::is_integer && - RealLimits::is_signed == CompatibleLimits::is_signed; - }; - - template - struct is_compatible_integer_type - : is_compatible_integer_type_impl {}; - - template - struct is_compatible_type_impl : std::false_type {}; - - template - struct is_compatible_type_impl < - BasicJsonType, CompatibleType, - enable_if_t::value >> - { - static constexpr bool value = - has_to_json::value; - }; - - template - struct is_compatible_type - : is_compatible_type_impl {}; - - template - struct is_constructible_tuple : std::false_type {}; - - template - struct is_constructible_tuple> : conjunction...> {}; - - template - struct is_json_iterator_of : std::false_type {}; - - template - struct is_json_iterator_of : std::true_type {}; - - template - struct is_json_iterator_of : std::true_type - {}; - - // checks if a given type T is a template specialization of Primary - template