From fdbf9651babf93241764cb9e495f642201926bc3 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sun, 13 Sep 2020 08:30:13 +0300 Subject: [PATCH 01/78] Added MTA interface --- Client/mods/deathmatch/StdInc.h | 1 + .../deathmatch/logic/CClientColManager.cpp | 1 + Client/mods/deathmatch/logic/CClientEntity.h | 4 +- Client/mods/deathmatch/logic/CClientIMG.cpp | 42 +++++++++++ Client/mods/deathmatch/logic/CClientIMG.h | 34 +++++++++ .../logic/lua/CLuaFunctionParseHelpers.h | 4 ++ Client/mods/deathmatch/logic/lua/LuaCommon.h | 1 + .../logic/luadefs/CLuaClassDefs.cpp | 2 + .../logic/luadefs/CLuaEngineDefs.cpp | 71 +++++++++++++++++++ .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 2 + 10 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 Client/mods/deathmatch/logic/CClientIMG.cpp create mode 100644 Client/mods/deathmatch/logic/CClientIMG.h diff --git a/Client/mods/deathmatch/StdInc.h b/Client/mods/deathmatch/StdInc.h index 242bead28d..7921f9f01f 100644 --- a/Client/mods/deathmatch/StdInc.h +++ b/Client/mods/deathmatch/StdInc.h @@ -78,6 +78,7 @@ #include #include #include +#include #include #include #include diff --git a/Client/mods/deathmatch/logic/CClientColManager.cpp b/Client/mods/deathmatch/logic/CClientColManager.cpp index bb1050b54b..5707d639f5 100644 --- a/Client/mods/deathmatch/logic/CClientColManager.cpp +++ b/Client/mods/deathmatch/logic/CClientColManager.cpp @@ -69,6 +69,7 @@ void CClientColManager::DoHitDetectionForColShape(CClientColShape* pShape) case CCLIENTDFF: case CCLIENTCOL: case CCLIENTTXD: + case CCLIENTIMG: case CCLIENTSOUND: break; default: diff --git a/Client/mods/deathmatch/logic/CClientEntity.h b/Client/mods/deathmatch/logic/CClientEntity.h index e737e876cb..e500de4916 100644 --- a/Client/mods/deathmatch/logic/CClientEntity.h +++ b/Client/mods/deathmatch/logic/CClientEntity.h @@ -78,6 +78,7 @@ enum eClientEntityType CCLIENTSEARCHLIGHT, CCLIENTIFP, CCLIENTUNKNOWN, + CCLIENTIMG, }; class CClientColShape; @@ -141,7 +142,8 @@ enum eCClientEntityClassTypes CLASS_CClientWeapon, CLASS_CClientEffect, CLASS_CClientPointLights, - CLASS_CClientSearchLight + CLASS_CClientSearchLight, + CLASS_CClientIMG, }; class CClientEntity : public CClientEntityBase diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp new file mode 100644 index 0000000000..2d88aa5371 --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -0,0 +1,42 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/CClientIMG.cpp + * PURPOSE: IMG manager class + * + *****************************************************************************/ + +#include + +CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID) +{ + // Init + m_pManager = pManager; + SetTypeName("img"); +} + +CClientIMG::~CClientIMG() +{ + +} + +bool CClientIMG::Load(SString sFilePath) +{ + if (sFilePath.empty()) + return false; + + m_strFilename = std::move(sFilePath); + +/* g_pClientGame->GetResourceManager()->ValidateResourceFile(m_strFilename, nullptr, 0); + if (!g_pCore->GetNetwork()->CheckFile("img", m_strFilename)) + return false; +*/ + return true; +} + +bool CClientIMG::Stream() +{ + return true; +} diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h new file mode 100644 index 0000000000..0da7c69436 --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -0,0 +1,34 @@ +/***************************************************************************** +* +* PROJECT: Multi Theft Auto v1.0 +* (Shared logic for modifications) +* LICENSE: See LICENSE in the top level directory +* FILE: mods/shared_logic/CClientIMG.h +* PURPOSE: IMG manager class header + +* +*****************************************************************************/ + +#pragma once + +#include "CClientEntity.h" + +class CClientIMG : public CClientEntity +{ + DECLARE_CLASS(CClientIMG, CClientEntity) +public: + CClientIMG(class CClientManager* pManager, ElementID ID); + ~CClientIMG(); + + void Unlink(){}; + void GetPosition(CVector& vecPosition) const {}; + void SetPosition(const CVector& vecPosition){}; + + eClientEntityType GetType() const { return CCLIENTIMG; } + bool Load(SString sFilePath); + bool Stream(); +private: + + SString m_strFilename; + SString m_FileData; +}; diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h index 352deb33e0..7df394dd17 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionParseHelpers.h @@ -255,6 +255,10 @@ inline SString GetClassTypeName(CClientTXD*) { return "txd"; } +inline SString GetClassTypeName(CClientIMG*) +{ + return "img"; +} inline SString GetClassTypeName(CClientSound*) { return "sound"; diff --git a/Client/mods/deathmatch/logic/lua/LuaCommon.h b/Client/mods/deathmatch/logic/lua/LuaCommon.h index b240a82cd7..9f678b43a4 100644 --- a/Client/mods/deathmatch/logic/lua/LuaCommon.h +++ b/Client/mods/deathmatch/logic/lua/LuaCommon.h @@ -37,6 +37,7 @@ class CClientPlayer; class CClientRadarMarker; class CClientTeam; class CClientTXD; +class CClientIMG; class CClientVehicle; class CClientWater; class CClientWeapon; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp index e37348e9d1..f68507bd5f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaClassDefs.cpp @@ -356,6 +356,8 @@ const char* CLuaClassDefs::GetEntityClass(CClientEntity* pEntity) return "EngineCOL"; case CCLIENTTXD: return "EngineTXD"; + case CCLIENTIMG: + return "EngineIMG"; case CCLIENTSOUND: return static_cast(pEntity)->IsSound3D() ? "Sound3D" : "Sound"; case CCLIENTWATER: diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index b8d8c2b41d..6cb0def378 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -15,6 +15,7 @@ void CLuaEngineDefs::LoadFunctions() { constexpr static const std::pair functions[]{ {"engineFreeModel", EngineFreeModel}, + {"engineLoadIMG", EngineLoadIMG}, {"engineLoadTXD", EngineLoadTXD}, {"engineLoadCOL", EngineLoadCOL}, {"engineLoadDFF", EngineLoadDFF}, @@ -112,6 +113,14 @@ void CLuaEngineDefs::AddEngineTxdClass(lua_State* luaVM) lua_registerclass(luaVM, "EngineTXD", "Element"); } +void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) +{ + lua_newclass(luaVM); + + lua_classfunction(luaVM, "create", "engineLoadIMG"); +} + + void CLuaEngineDefs::AddEngineDffClass(lua_State* luaVM) { lua_newclass(luaVM); @@ -122,6 +131,68 @@ void CLuaEngineDefs::AddEngineDffClass(lua_State* luaVM) lua_registerclass(luaVM, "EngineDFF", "Element"); } +int CLuaEngineDefs::EngineLoadIMG(lua_State* luaVM) +{ + SString input; + CScriptArgReader argStream(luaVM); + // Grab the IMG filename or data + argStream.ReadString(input); + + if (!argStream.HasErrors()) + { + // Grab the lua main and the resource belonging to this script + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (pLuaMain) + { + // Get the resource we belong to + CResource* pResource = pLuaMain->GetResource(); + if (pResource) + { + + SString filePath; + + // Is this a legal filepath? + if (CResourceManager::ParseResourcePathInput(input, pResource, &filePath)) + { + // Grab the resource root entity + // CClientEntity* pRoot = pResource->GetResourceIMGFilesRoot(); + + // Create the col model + CClientIMG* pImg = new CClientIMG(m_pManager, INVALID_ELEMENT_ID); + + // Attempt loading the file + if (pImg->Load(std::move(filePath))) + { + // Success. Make it a child of the resource img root + // pImg->SetParent(pRoot); + + lua_pushelement(luaVM, pImg); + return 1; + } + else + { + delete pImg; + argStream.SetCustomError(input, "Error loading IMG"); + } + } + else + { + argStream.SetCustomError(input, "Bad file path"); + } + } + } + } + + if (argStream.HasErrors()) + { + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + } + + lua_pushboolean(luaVM, false); + return 1; +} + + int CLuaEngineDefs::EngineLoadCOL(lua_State* luaVM) { SString input; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 1999e72d5d..c29acf6180 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -18,6 +18,7 @@ class CLuaEngineDefs : public CLuaDefs static void LoadFunctions(); static void AddClass(lua_State* luaVM); + LUA_DECLARE(EngineLoadIMG); LUA_DECLARE(EngineLoadDFF); LUA_DECLARE(EngineLoadTXD); LUA_DECLARE(EngineLoadCOL); @@ -62,4 +63,5 @@ class CLuaEngineDefs : public CLuaDefs static void AddEngineColClass(lua_State* luaVM); static void AddEngineTxdClass(lua_State* luaVM); static void AddEngineDffClass(lua_State* luaVM); + static void AddEngineImgClass(lua_State* luaVM); }; From 227f281aefc2b7f68bde39a332a5d62db25d748b Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Thu, 24 Sep 2020 20:10:51 +0300 Subject: [PATCH 02/78] Allow to load custom IMG --- Client/game_sa/CStreamingSA.cpp | 70 ++++++++++++++++++- Client/game_sa/CStreamingSA.h | 44 ++++++++++++ Client/mods/deathmatch/logic/CClientIMG.cpp | 3 + Client/mods/deathmatch/logic/CClientIMG.h | 1 + .../logic/luadefs/CLuaEngineDefs.cpp | 4 +- Client/sdk/game/CStreaming.h | 2 + 6 files changed, 121 insertions(+), 3 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index a51f089ac7..2d6e7d01f7 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -10,6 +10,7 @@ *****************************************************************************/ #include "StdInc.h" +#include "Fileapi.h" namespace { @@ -133,4 +134,71 @@ void CStreamingSA::RequestSpecialModel(DWORD model, const char* szTexture, DWORD call dwFunc add esp, 0xC } -} \ No newline at end of file +} + +CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) +{ + CStreamingInfo* pItemInfo = (CStreamingInfo*)(ARRAY_StreamModelInfo); + return pItemInfo + id; +} + +CStreamHandlerInfo* CStreamingSA::GetStreamingHandlerInfo(uint id) +{ + CStreamHandlerInfo* pHandlerInfo = (CStreamHandlerInfo*)(ARRAY_StreamHandlersInfo); + return pHandlerInfo + id; +} + + +unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) +{ + // Get internal IMG id + // By default gta sa has 8 IMG archives + uchar ucArchiveId = 0; + for (int i = 0; i < 8; i++) + { + CStreamHandlerInfo* info = GetStreamingHandlerInfo(i); + if (!info->uiStreamHandleId) + { + ucArchiveId = i; + break; + } + } + + if (ucArchiveId == 0) + return 0; + + // Get free stream handler id + HANDLE hFile = INVALID_HANDLE_VALUE; + unsigned char ucStreamID = 0; + + for (unsigned char ID = 0; ID < VAR_StreamHandlersMaxCount; ++ID) + { + HANDLE hFile = *(HANDLE*)(ARRAY_StreamHandlers + (ID * sizeof(HANDLE))); + if (!hFile) + { + ucStreamID = ID; + break; + } + }; + + if (ucStreamID == 0) + return 0; + + // Create new stream handler + DWORD dOpenFlags = *(DWORD*)(VAR_StreamHandlerCreateFlags) | FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS; + + hFile = CreateFileA(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dOpenFlags, NULL); + + if (hFile == INVALID_HANDLE_VALUE) + return 0; + + // Register stream handler + void* streamHandlerPos = (void*)(ARRAY_StreamHandlers + ucStreamID * sizeof(HANDLE)); + MemPutFast(streamHandlerPos, hFile); + + // Register archive data + CStreamHandlerInfo* pNewArchiveInfo = GetStreamingHandlerInfo(ucArchiveId); + pNewArchiveInfo->uiStreamHandleId = (ucStreamID << 24); + + return ucArchiveId; +} diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index ce9d7c87e9..08c14ba6e3 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -13,6 +13,18 @@ #include #include "Common.h" +#include "Fileapi.h" + +// Shoud be changed to interfaces +#define ARRAY_StreamHandlers 0x8E4010 // [32] +#define ARRAY_StreamHandlersNames 0x8E4098 // [32][64] +#define ARRAY_StreamHandlersInfo 0x8E48D8 // [8][0x30] + +#define ARRAY_StreamModelInfo 0x8E4CC0 // size = 26316 + +#define VAR_StreamHandlersMaxCount 32 +#define VAR_StreamHandlerCreateFlags 0x8E3FE0 +#define VAR_StreamHandlersMaxCount 32 #define FUNC_CStreaming__RequestModel 0x4087E0 #define FUNC_LoadAllRequestedModels 0x40EA10 @@ -20,11 +32,43 @@ #define FUNC_CStreaming_RequestAnimations 0x407120 #define FUNC_CStreaming_RequestSpecialModel 0x409d10 +#define FUNC_CStreaming_RequestFile 0x406A20 // (DWORD streamNum, int lpBuffer, int streamIndex, int sectorCount) + +#define FUNC_CStreaming_RemoveImages 0x4066B3 // Remove all IMG`s from streaming +#define FUNC_CStreaming_RemoveImage 0x4068A0 + +struct CStreamingInfo +{ + WORD prevId; + WORD nextId; + WORD nextInImg; + uchar flg; + uchar archiveId; + DWORD offsetInBlocks; + DWORD sizeInBlocks; + DWORD loadState; +}; + +struct CStreamHandlerInfo +{ + char szName[40]; + BYTE bUnknow = 1; // Only in player.img is 0. Maybe, it is DWORD value + BYTE bUnused[3]; + DWORD uiStreamHandleId; +}; + + class CStreamingSA : public CStreaming { +private: + CStreamHandlerInfo* GetStreamingHandlerInfo(uint id); public: void RequestModel(DWORD dwModelID, DWORD dwFlags); void LoadAllRequestedModels(BOOL bOnlyPriorityModels = 0, const char* szTag = NULL); BOOL HasModelLoaded(DWORD dwModelID); void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel); + + CStreamingInfo* GetStreamingInfoFromModelId(uint id); + unsigned char AddStreamHandler(const char* szFilePath); + //BOOL RemoveStreamHandler(DWORD dwStreamHandler); }; diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 2d88aa5371..05e22a162f 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -33,10 +33,13 @@ bool CClientIMG::Load(SString sFilePath) if (!g_pCore->GetNetwork()->CheckFile("img", m_strFilename)) return false; */ + + Stream(); return true; } bool CClientIMG::Stream() { + m_ucStreamID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); return true; } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 0da7c69436..e993afa7dd 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -31,4 +31,5 @@ class CClientIMG : public CClientEntity SString m_strFilename; SString m_FileData; + unsigned char m_ucStreamID; }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 6cb0def378..f87417c1ac 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -156,7 +156,7 @@ int CLuaEngineDefs::EngineLoadIMG(lua_State* luaVM) { // Grab the resource root entity // CClientEntity* pRoot = pResource->GetResourceIMGFilesRoot(); - + CClientEntity* pRoot = pResource->GetResourceDFFRoot(); // Create the col model CClientIMG* pImg = new CClientIMG(m_pManager, INVALID_ELEMENT_ID); @@ -164,7 +164,7 @@ int CLuaEngineDefs::EngineLoadIMG(lua_State* luaVM) if (pImg->Load(std::move(filePath))) { // Success. Make it a child of the resource img root - // pImg->SetParent(pRoot); + pImg->SetParent(pRoot); lua_pushelement(luaVM, pImg); return 1; diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 057b5818be..87439ed390 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -18,4 +18,6 @@ class CStreaming virtual void LoadAllRequestedModels(BOOL bOnlyPriorityModels = 0, const char* szTag = NULL) = 0; virtual BOOL HasModelLoaded(DWORD dwModelID) = 0; virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; + virtual unsigned char AddStreamHandler(const char* szFilePath) = 0; + //virtual BOOL RemoveStreamHandler(DWORD dwStreamHandler) = 0; }; From dadaec697be6d06a10c05e8f938615e7a4a4fb10 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 25 Sep 2020 14:07:45 +0300 Subject: [PATCH 03/78] Added resource IMG root --- Client/mods/deathmatch/logic/CResource.cpp | 9 +++++++++ Client/mods/deathmatch/logic/CResource.h | 2 ++ Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/CResource.cpp b/Client/mods/deathmatch/logic/CResource.cpp index ba6b55398d..683d9a6cc2 100644 --- a/Client/mods/deathmatch/logic/CResource.cpp +++ b/Client/mods/deathmatch/logic/CResource.cpp @@ -68,6 +68,11 @@ CResource::CResource(unsigned short usNetID, const char* szResourceName, CClient m_pResourceIFPRoot = new CClientDummy(g_pClientGame->GetManager(), INVALID_ELEMENT_ID, "ifproot"); m_pResourceIFPRoot->MakeSystemEntity(); + // Create our IMG root element. We set its parent when we're loaded. + // Make it a system entity so nothing but us can delete it. + m_pResourceIMGRoot = new CClientDummy(g_pClientGame->GetManager(), INVALID_ELEMENT_ID, "imgroot"); + m_pResourceIMGRoot->MakeSystemEntity(); + m_strResourceDirectoryPath = SString("%s/resources/%s", g_pClientGame->GetFileCacheRoot(), *m_strResourceName); m_strResourcePrivateDirectoryPath = PathJoin(CServerIdManager::GetSingleton()->GetConnectionPrivateDirectory(), m_strResourceName); @@ -109,6 +114,10 @@ CResource::~CResource() g_pClientGame->GetElementDeleter()->DeleteRecursive(m_pResourceIFPRoot); m_pResourceIFPRoot = NULL; + // Destroy the img root so all img elements are deleted except those moved out + g_pClientGame->GetElementDeleter()->DeleteRecursive(m_pResourceIMGRoot); + m_pResourceIMGRoot = NULL; + // Destroy the ddf root so all dff elements are deleted except those moved out g_pClientGame->GetElementDeleter()->DeleteRecursive(m_pResourceDFFEntity); m_pResourceDFFEntity = NULL; diff --git a/Client/mods/deathmatch/logic/CResource.h b/Client/mods/deathmatch/logic/CResource.h index 27ad30bbd8..b3a7f51cf5 100644 --- a/Client/mods/deathmatch/logic/CResource.h +++ b/Client/mods/deathmatch/logic/CResource.h @@ -87,6 +87,7 @@ class CResource CClientEntity* GetResourceDFFRoot() { return m_pResourceDFFEntity; }; CClientEntity* GetResourceTXDRoot() { return m_pResourceTXDRoot; }; CClientEntity* GetResourceIFPRoot() { return m_pResourceIFPRoot; }; + CClientEntity* GetResourceIMGRoot() { return m_pResourceIMGRoot; }; // This is to delete all the elements created in this resource that are created locally in this client void DeleteClientChildren(); @@ -127,6 +128,7 @@ class CResource class CClientEntity* m_pResourceGUIEntity; class CClientEntity* m_pResourceTXDRoot; class CClientEntity* m_pResourceIFPRoot; + class CClientEntity* m_pResourceIMGRoot; unsigned short m_usRemainingNoClientCacheScripts; bool m_bLoadAfterReceivingNoClientCacheScripts; CMtaVersion m_strMinServerReq; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index f87417c1ac..5ca257cd77 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -156,7 +156,7 @@ int CLuaEngineDefs::EngineLoadIMG(lua_State* luaVM) { // Grab the resource root entity // CClientEntity* pRoot = pResource->GetResourceIMGFilesRoot(); - CClientEntity* pRoot = pResource->GetResourceDFFRoot(); + CClientEntity* pRoot = pResource->GetResourceIMGRoot(); // Create the col model CClientIMG* pImg = new CClientIMG(m_pManager, INVALID_ELEMENT_ID); From 88b758e43362c15b4c6b0b55c01176438686dbdf Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 25 Sep 2020 16:06:18 +0300 Subject: [PATCH 04/78] Added engineSetModelIMG function --- Client/game_sa/CStreamingSA.cpp | 11 ++++++ Client/game_sa/CStreamingSA.h | 1 + Client/mods/deathmatch/logic/CClientIMG.cpp | 9 +++++ Client/mods/deathmatch/logic/CClientIMG.h | 2 ++ .../logic/luadefs/CLuaEngineDefs.cpp | 36 +++++++++++++++++-- .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 1 + Client/sdk/game/CStreaming.h | 1 + 7 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 2d6e7d01f7..84f1438ac0 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -142,6 +142,17 @@ CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) return pItemInfo + id; } +bool CStreamingSA::SetModelStreamInfo(ushort id, uchar ucArchiveId, ushort usOffestInBlocks, ushort usSizeInBlocks) +{ + CStreamingInfo* pItemInfo = GetStreamingInfoFromModelId(id); + pItemInfo->archiveId = ucArchiveId; + pItemInfo->offsetInBlocks = usOffestInBlocks; + pItemInfo->sizeInBlocks = usSizeInBlocks; + // TODO CHANGE THIS INFO FOR PREV MODEL + pItemInfo->nextInImg = -1; + return true; +} + CStreamHandlerInfo* CStreamingSA::GetStreamingHandlerInfo(uint id) { CStreamHandlerInfo* pHandlerInfo = (CStreamHandlerInfo*)(ARRAY_StreamHandlersInfo); diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 08c14ba6e3..28acaf05fb 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -63,6 +63,7 @@ class CStreamingSA : public CStreaming private: CStreamHandlerInfo* GetStreamingHandlerInfo(uint id); public: + bool SetModelStreamInfo(ushort id, uchar ucArchiveId, ushort usOffestInBlocks, ushort usSizeInBlocks); void RequestModel(DWORD dwModelID, DWORD dwFlags); void LoadAllRequestedModels(BOOL bOnlyPriorityModels = 0, const char* szTag = NULL); BOOL HasModelLoaded(DWORD dwModelID); diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 05e22a162f..9769f88b3a 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -43,3 +43,12 @@ bool CClientIMG::Stream() m_ucStreamID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); return true; } + +bool CClientIMG::LinkModel(unsigned short usModelID, unsigned short usOffestInBlocks, unsigned short usSizeInBlocks) +{ + if (!m_ucStreamID) + return false; + + g_pGame->GetStreaming()->SetModelStreamInfo(usModelID, m_ucStreamID, usOffestInBlocks, usSizeInBlocks); + return true; +} diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index e993afa7dd..92e7f4679d 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -27,6 +27,8 @@ class CClientIMG : public CClientEntity eClientEntityType GetType() const { return CCLIENTIMG; } bool Load(SString sFilePath); bool Stream(); + bool LinkModel(unsigned short usModelID, unsigned short usOffsetInBlocks, unsigned short usSizeInBlocks); + private: SString m_strFilename; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 5ca257cd77..7dea4442e9 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -23,6 +23,7 @@ void CLuaEngineDefs::LoadFunctions() {"engineImportTXD", EngineImportTXD}, {"engineReplaceCOL", EngineReplaceCOL}, {"engineRestoreCOL", EngineRestoreCOL}, + {"engineSetModelIMG", EngineSetModelIMG}, {"engineReplaceModel", EngineReplaceModel}, {"engineRestoreModel", EngineRestoreModel}, {"engineReplaceAnimation", EngineReplaceAnimation}, @@ -155,9 +156,8 @@ int CLuaEngineDefs::EngineLoadIMG(lua_State* luaVM) if (CResourceManager::ParseResourcePathInput(input, pResource, &filePath)) { // Grab the resource root entity - // CClientEntity* pRoot = pResource->GetResourceIMGFilesRoot(); CClientEntity* pRoot = pResource->GetResourceIMGRoot(); - // Create the col model + // Create the img handle CClientIMG* pImg = new CClientIMG(m_pManager, INVALID_ELEMENT_ID); // Attempt loading the file @@ -568,6 +568,38 @@ int CLuaEngineDefs::EngineImportTXD(lua_State* luaVM) return 1; } +int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) +{ + unsigned short usModelID; + CClientIMG* pIMG; + // TEMP + unsigned short usOffsetInBlock; + unsigned short usSizeInBlocks; + + CScriptArgReader argStream(luaVM); + argStream.ReadNumber(usModelID); + argStream.ReadUserData(pIMG); + + argStream.ReadNumber(usOffsetInBlock); + argStream.ReadNumber(usSizeInBlocks); + + if (!argStream.HasErrors()) + { + if (pIMG->LinkModel(usModelID, usOffsetInBlock, usSizeInBlocks)) + { + lua_pushboolean(luaVM, true); + return 1; + } + else + argStream.SetCustomError(SString("Model ID %d replace failed", usModelID)); + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaEngineDefs::EngineReplaceModel(lua_State* luaVM) { CClientDFF* pDFF; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index c29acf6180..a9a930a57c 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -26,6 +26,7 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineImportTXD); LUA_DECLARE(EngineReplaceCOL); LUA_DECLARE(EngineRestoreCOL); + LUA_DECLARE(EngineSetModelIMG); LUA_DECLARE(EngineReplaceModel); LUA_DECLARE(EngineRestoreModel); LUA_DECLARE(EngineRequestModel); diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 87439ed390..f5c5eaf9e9 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -20,4 +20,5 @@ class CStreaming virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; virtual unsigned char AddStreamHandler(const char* szFilePath) = 0; //virtual BOOL RemoveStreamHandler(DWORD dwStreamHandler) = 0; + virtual bool SetModelStreamInfo(unsigned short id, unsigned char ucArchiveId, unsigned short usOffestInBlocks, unsigned short usSizeInBlocks) = 0; }; From dff4812fc70fa35e7f8874a8c9a2134099954c81 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 26 Sep 2020 16:22:39 +0300 Subject: [PATCH 05/78] Added engineGetModelTXDID and EngineSetModelTXDID --- Client/game_sa/CRenderWareSA.cpp | 24 +++++++++ Client/game_sa/CRenderWareSA.h | 1 + .../logic/luadefs/CLuaEngineDefs.cpp | 52 +++++++++++++++++++ .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 2 + Client/sdk/game/CRenderWare.h | 2 + 5 files changed, 81 insertions(+) diff --git a/Client/game_sa/CRenderWareSA.cpp b/Client/game_sa/CRenderWareSA.cpp index ca761d4895..0c0310eeb7 100644 --- a/Client/game_sa/CRenderWareSA.cpp +++ b/Client/game_sa/CRenderWareSA.cpp @@ -703,6 +703,30 @@ ushort CRenderWareSA::GetTXDIDForModelID(ushort usModelID) } } +//////////////////////////////////////////////////////////////// +// +// CRenderWareSA::GetTXDIDForModelID +// +// Get a TXD ID associated with the model ID +// +//////////////////////////////////////////////////////////////// +bool CRenderWareSA::SetTXDIDForModelID(ushort usModelID, ushort usTXDID) +{ + if (usModelID >= 20000) + { + return false; + } + else + { + // Ensure valid + if (!((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]) + return false; + + ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]->usTextureDictionary = usTXDID; + return true; + } +} + //////////////////////////////////////////////////////////////// // // CRenderWareSA::GetModelTextureNames diff --git a/Client/game_sa/CRenderWareSA.h b/Client/game_sa/CRenderWareSA.h index d9df3477ae..8ab7d3cbb4 100644 --- a/Client/game_sa/CRenderWareSA.h +++ b/Client/game_sa/CRenderWareSA.h @@ -92,6 +92,7 @@ class CRenderWareSA : public CRenderWare bool ReplacePartModels(RpClump* pClump, RpAtomicContainer* pAtomics, unsigned int uiAtomics, const char* szName); ushort GetTXDIDForModelID(ushort usModelID); + bool SetTXDIDForModelID(ushort usModelID, ushort usTXDID); void PulseWorldTextureWatch(); void GetModelTextureNames(std::vector& outNameList, ushort usModelID); bool GetModelTextures(std::vector>& outTextureList, ushort usModelID, std::vector vTextureNames); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 7dea4442e9..310c6e7d39 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -35,6 +35,8 @@ void CLuaEngineDefs::LoadFunctions() {"engineSetAsynchronousLoading", EngineSetAsynchronousLoading}, {"engineApplyShaderToWorldTexture", EngineApplyShaderToWorldTexture}, {"engineRemoveShaderFromWorldTexture", EngineRemoveShaderFromWorldTexture}, + {"engineGetModelTXDID", EngineGetModelTXDID}, + {"engineSetModelTXDID", EngineSetModelTXDID}, {"engineGetModelNameFromID", EngineGetModelNameFromID}, {"engineGetModelIDFromName", EngineGetModelIDFromName}, {"engineGetModelTextureNames", EngineGetModelTextureNames}, @@ -1074,6 +1076,56 @@ int CLuaEngineDefs::EngineRemoveShaderFromWorldTexture(lua_State* luaVM) return 1; } +int CLuaEngineDefs::EngineGetModelTXDID(lua_State* luaVM) +{ + // int engineGetModelTXDID ( int modelID ) + unsigned short usModelID; + + CScriptArgReader argStream(luaVM); + argStream.ReadNumber(usModelID); + + if (!argStream.HasErrors()) + { + unsigned short usTXDID = g_pGame->GetRenderWare()->GetTXDIDForModelID(usModelID); + lua_pushinteger(luaVM, usTXDID); + return 1; + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // We failed + lua_pushboolean(luaVM, false); + return 1; +} + + +int CLuaEngineDefs::EngineSetModelTXDID(lua_State* luaVM) +{ + unsigned short usModelID; + unsigned short usTXDID; + + CScriptArgReader argStream(luaVM); + argStream.ReadNumber(usModelID); + argStream.ReadNumber(usTXDID); + + if (!argStream.HasErrors()) + { + bool bResult = g_pGame->GetRenderWare()->SetTXDIDForModelID(usModelID, usTXDID); + if (bResult) + { + lua_pushboolean(luaVM, bResult); + return 1; + } + argStream.SetCustomError("Expected valid model ID at argument 1"); + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // We failed + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaEngineDefs::EngineGetModelNameFromID(lua_State* luaVM) { // string engineGetModelNameFromID ( int modelID ) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index a9a930a57c..6c42d8f81b 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -45,6 +45,8 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineSetAsynchronousLoading); LUA_DECLARE(EngineApplyShaderToWorldTexture); LUA_DECLARE(EngineRemoveShaderFromWorldTexture); + LUA_DECLARE(EngineGetModelTXDID); + LUA_DECLARE(EngineSetModelTXDID); LUA_DECLARE(EngineGetModelNameFromID); LUA_DECLARE(EngineGetModelIDFromName); LUA_DECLARE(EngineGetModelTextureNames); diff --git a/Client/sdk/game/CRenderWare.h b/Client/sdk/game/CRenderWare.h index a12beb1513..8877b21315 100644 --- a/Client/sdk/game/CRenderWare.h +++ b/Client/sdk/game/CRenderWare.h @@ -91,6 +91,8 @@ class CRenderWare virtual void GetModelTextureNames(std::vector& outNameList, ushort usModelID) = 0; virtual bool GetModelTextures(std::vector>& outTextureList, ushort usModelID, std::vector vTextureNames) = 0; virtual const char* GetTextureName(CD3DDUMMY* pD3DData) = 0; + virtual ushort GetTXDIDForModelID(ushort usModelID) = 0; + virtual bool SetTXDIDForModelID(ushort usModelID, ushort usTXDID) = 0; virtual void SetRenderingClientEntity(CClientEntityBase* pClientEntity, ushort usModelId, int iTypeMask) = 0; virtual SShaderItemLayers* GetAppliedShaderForD3DData(CD3DDUMMY* pD3DData) = 0; From d7f42c6b1e32fcf1e78705cd3a4bd44b80818cbf Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 26 Sep 2020 17:33:54 +0300 Subject: [PATCH 06/78] Fix typos --- Client/game_sa/CRenderWareSA.cpp | 4 ++-- Client/game_sa/CStreamingSA.cpp | 2 +- Client/game_sa/CStreamingSA.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Client/game_sa/CRenderWareSA.cpp b/Client/game_sa/CRenderWareSA.cpp index 0c0310eeb7..b48e8f841d 100644 --- a/Client/game_sa/CRenderWareSA.cpp +++ b/Client/game_sa/CRenderWareSA.cpp @@ -705,9 +705,9 @@ ushort CRenderWareSA::GetTXDIDForModelID(ushort usModelID) //////////////////////////////////////////////////////////////// // -// CRenderWareSA::GetTXDIDForModelID +// CRenderWareSA::SetTXDIDForModelID // -// Get a TXD ID associated with the model ID +// Set a TXD ID associated with the model ID // //////////////////////////////////////////////////////////////// bool CRenderWareSA::SetTXDIDForModelID(ushort usModelID, ushort usTXDID) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 84f1438ac0..2bc1629fb2 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -136,7 +136,7 @@ void CStreamingSA::RequestSpecialModel(DWORD model, const char* szTexture, DWORD } } -CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) +CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(ushort id) { CStreamingInfo* pItemInfo = (CStreamingInfo*)(ARRAY_StreamModelInfo); return pItemInfo + id; diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 28acaf05fb..3750fe7da0 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -69,7 +69,7 @@ class CStreamingSA : public CStreaming BOOL HasModelLoaded(DWORD dwModelID); void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel); - CStreamingInfo* GetStreamingInfoFromModelId(uint id); + CStreamingInfo* GetStreamingInfoFromModelId(ushort id); unsigned char AddStreamHandler(const char* szFilePath); //BOOL RemoveStreamHandler(DWORD dwStreamHandler); }; From bfa404d3616802af7c788d091658f059f339e0ae Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 26 Sep 2020 22:34:35 +0300 Subject: [PATCH 07/78] Allow allocating new objects --- Client/game_sa/CModelInfoSA.cpp | 14 +++++++++++++ Client/game_sa/CModelInfoSA.h | 2 ++ Client/game_sa/CStreamingSA.h | 12 ----------- Client/mods/deathmatch/logic/CClientModel.cpp | 12 ++++++++++- Client/mods/deathmatch/logic/CClientModel.h | 3 ++- .../logic/luadefs/CLuaEngineDefs.cpp | 2 ++ .../CMultiplayerSA_CrashFixHacks.cpp | 21 ++----------------- Client/sdk/game/CModelInfo.h | 1 + Client/sdk/game/CStreaming.h | 13 ++++++++++++ 9 files changed, 47 insertions(+), 33 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 8c79424a7b..2856204139 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -1329,6 +1329,20 @@ void CModelInfoSA::MakePedModel(char* szTexture) pGame->GetStreaming()->RequestSpecialModel(m_dwModelID, szTexture, 0); } +void CModelInfoSA::MakeObjectModel(ushort usBaseID) +{ + ppModelInfo[m_dwModelID] = ppModelInfo[usBaseID]; + CStreamingInfo* pBaseModelStreamigInfo = pGame->GetStreaming()->GetStreamingInfoFromModelId(usBaseID); + CStreamingInfo* pTargetModelStreamigInfo = pGame->GetStreaming()->GetStreamingInfoFromModelId(m_dwModelID); + pTargetModelStreamigInfo->loadState = 0; + pTargetModelStreamigInfo->nextInImg = -1; + pTargetModelStreamigInfo->nextId = -1; + pTargetModelStreamigInfo->prevId = -1; + pTargetModelStreamigInfo->archiveId = pBaseModelStreamigInfo->archiveId; + pTargetModelStreamigInfo->offsetInBlocks = pBaseModelStreamigInfo->offsetInBlocks; + pTargetModelStreamigInfo->sizeInBlocks = pBaseModelStreamigInfo->sizeInBlocks; +} + void CModelInfoSA::DeallocateModel(void) { Remove(); diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index cef9c36e8a..3bc3866ecb 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -290,6 +290,7 @@ class CModelInfoSA : public CModelInfo CBaseModelInfoSAInterface* GetInterface(); CPedModelInfoSAInterface* GetPedModelInfoInterface() { return reinterpret_cast(GetInterface()); } + CObjectSAInterface* GetObjectInterface() { return reinterpret_cast(GetInterface()); } DWORD GetModel() { return m_dwModelID; } eModelInfoType GetModelType(); @@ -379,6 +380,7 @@ class CModelInfoSA : public CModelInfo // CModelInfoSA methods void MakePedModel(char* szTexture); + void MakeObjectModel(ushort usBaseModelID); void DeallocateModel(void); SVehicleSupportedUpgrades GetVehicleSupportedUpgrades() { return m_ModelSupportedUpgrades; } diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 3750fe7da0..9904b0c5d0 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -37,18 +37,6 @@ #define FUNC_CStreaming_RemoveImages 0x4066B3 // Remove all IMG`s from streaming #define FUNC_CStreaming_RemoveImage 0x4068A0 -struct CStreamingInfo -{ - WORD prevId; - WORD nextId; - WORD nextInImg; - uchar flg; - uchar archiveId; - DWORD offsetInBlocks; - DWORD sizeInBlocks; - DWORD loadState; -}; - struct CStreamHandlerInfo { char szName[40]; diff --git a/Client/mods/deathmatch/logic/CClientModel.cpp b/Client/mods/deathmatch/logic/CClientModel.cpp index 7aca127086..bab7566efd 100644 --- a/Client/mods/deathmatch/logic/CClientModel.cpp +++ b/Client/mods/deathmatch/logic/CClientModel.cpp @@ -37,7 +37,17 @@ bool CClientModel::Allocate(void) // Allocate only on free IDs if (!pModelInfo->IsValid()) { - pModelInfo->MakePedModel("PSYCHO"); + switch (m_eModelType) + { + case CCLIENTMODELPED: + pModelInfo->MakePedModel("PSYCHO"); + break; + case CCLIENTMODELOBJECT: + pModelInfo->MakeObjectModel(1337); + break; + default: + return false; + } return true; } return false; diff --git a/Client/mods/deathmatch/logic/CClientModel.h b/Client/mods/deathmatch/logic/CClientModel.h index a39d36f954..043ab77a92 100644 --- a/Client/mods/deathmatch/logic/CClientModel.h +++ b/Client/mods/deathmatch/logic/CClientModel.h @@ -17,7 +17,8 @@ class CClientModel; enum eClientModelType { - CCLIENTMODELPED + CCLIENTMODELPED, + CCLIENTMODELOBJECT, }; class CClientModel diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 310c6e7d39..6a51630816 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -684,6 +684,8 @@ int CLuaEngineDefs::EngineRequestModel(lua_State* luaVM) { eModelType = CCLIENTMODELPED; } + else if (strModelType == "object") + eModelType = CCLIENTMODELOBJECT; else { lua_pushboolean(luaVM, false); diff --git a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp index fd6aae5f29..be4f417351 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp @@ -998,23 +998,6 @@ void _declspec(naked) HOOK_CClumpModelInfo_GetFrameFromId() } } -struct CStreamingInfo -{ - DWORD gta_hash; - WORD chain_next; - uchar flg; - uchar archiveId; - DWORD offsetInBlocks; - DWORD sizeInBlocks; - DWORD reqload; -}; - -CStreamingInfo* GetStreamingInfoFromModelId(uint id) -{ - CStreamingInfo* pItemInfo = (CStreamingInfo*)(0x8E4CC0); - return pItemInfo + id; -} - ////////////////////////////////////////////////////////////////////////////////////////// // // CEntity::GetBoundRect @@ -1041,11 +1024,11 @@ void OnMY_CEntity_GetBoundRect(CEntitySAInterface* pEntity) if (!pColModel) { // Crash will occur at offset 00134134 - CStreamingInfo* pStreamingInfo = GetStreamingInfoFromModelId(usModelId); + CStreamingInfo* pStreamingInfo = pGameInterface->GetStreaming()->GetStreamingInfoFromModelId(usModelId); SString strDetails("refs:%d txd:%d RwObj:%08x bOwn:%d bColStr:%d flg:%d off:%d size:%d reqload:%d", pModelInfo->usNumberOfRefs, pModelInfo->usTextureDictionary, pModelInfo->pRwObject, pModelInfo->bDoWeOwnTheColModel, pModelInfo->bCollisionWasStreamedWithModel, pStreamingInfo->flg, pStreamingInfo->offsetInBlocks, pStreamingInfo->sizeInBlocks, - pStreamingInfo->reqload); + pStreamingInfo->loadState); LogEvent(815, "Model collision missing", "CEntity_GetBoundRect", SString("No collision for model:%d %s", usModelId, *strDetails), 5415); CArgMap argMap; argMap.Set("id", usModelId); diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index 9b8dc4908d..c5931c4035 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -177,6 +177,7 @@ class CModelInfo virtual void MakeCustomModel() = 0; virtual RwObject* GetRwObject() = 0; virtual void MakePedModel(char* szTexture) = 0; + virtual void MakeObjectModel(ushort usBaseID) = 0; virtual SVehicleSupportedUpgrades GetVehicleSupportedUpgrades() = 0; virtual void ResetSupportedUpgrades() = 0; diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index f5c5eaf9e9..7b688fca60 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -11,6 +11,18 @@ #pragma once +struct CStreamingInfo +{ + WORD prevId; + WORD nextId; + WORD nextInImg; + unsigned char flg; + unsigned char archiveId; + DWORD offsetInBlocks; + DWORD sizeInBlocks; + DWORD loadState; +}; + class CStreaming { public: @@ -20,5 +32,6 @@ class CStreaming virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; virtual unsigned char AddStreamHandler(const char* szFilePath) = 0; //virtual BOOL RemoveStreamHandler(DWORD dwStreamHandler) = 0; + virtual CStreamingInfo* GetStreamingInfoFromModelId(unsigned short id) = 0; virtual bool SetModelStreamInfo(unsigned short id, unsigned char ucArchiveId, unsigned short usOffestInBlocks, unsigned short usSizeInBlocks) = 0; }; From 24ec997bdd0e482a386afe0552261d783adeebfa Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Mon, 28 Sep 2020 20:16:58 +0300 Subject: [PATCH 08/78] Revert "Allow allocating new objects" This reverts commit bfa404d3616802af7c788d091658f059f339e0ae. --- Client/game_sa/CModelInfoSA.cpp | 14 ------------- Client/game_sa/CModelInfoSA.h | 2 -- Client/game_sa/CStreamingSA.h | 12 +++++++++++ Client/mods/deathmatch/logic/CClientModel.cpp | 12 +---------- Client/mods/deathmatch/logic/CClientModel.h | 3 +-- .../logic/luadefs/CLuaEngineDefs.cpp | 2 -- .../CMultiplayerSA_CrashFixHacks.cpp | 21 +++++++++++++++++-- Client/sdk/game/CModelInfo.h | 1 - Client/sdk/game/CStreaming.h | 13 ------------ 9 files changed, 33 insertions(+), 47 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 2856204139..8c79424a7b 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -1329,20 +1329,6 @@ void CModelInfoSA::MakePedModel(char* szTexture) pGame->GetStreaming()->RequestSpecialModel(m_dwModelID, szTexture, 0); } -void CModelInfoSA::MakeObjectModel(ushort usBaseID) -{ - ppModelInfo[m_dwModelID] = ppModelInfo[usBaseID]; - CStreamingInfo* pBaseModelStreamigInfo = pGame->GetStreaming()->GetStreamingInfoFromModelId(usBaseID); - CStreamingInfo* pTargetModelStreamigInfo = pGame->GetStreaming()->GetStreamingInfoFromModelId(m_dwModelID); - pTargetModelStreamigInfo->loadState = 0; - pTargetModelStreamigInfo->nextInImg = -1; - pTargetModelStreamigInfo->nextId = -1; - pTargetModelStreamigInfo->prevId = -1; - pTargetModelStreamigInfo->archiveId = pBaseModelStreamigInfo->archiveId; - pTargetModelStreamigInfo->offsetInBlocks = pBaseModelStreamigInfo->offsetInBlocks; - pTargetModelStreamigInfo->sizeInBlocks = pBaseModelStreamigInfo->sizeInBlocks; -} - void CModelInfoSA::DeallocateModel(void) { Remove(); diff --git a/Client/game_sa/CModelInfoSA.h b/Client/game_sa/CModelInfoSA.h index 3bc3866ecb..cef9c36e8a 100644 --- a/Client/game_sa/CModelInfoSA.h +++ b/Client/game_sa/CModelInfoSA.h @@ -290,7 +290,6 @@ class CModelInfoSA : public CModelInfo CBaseModelInfoSAInterface* GetInterface(); CPedModelInfoSAInterface* GetPedModelInfoInterface() { return reinterpret_cast(GetInterface()); } - CObjectSAInterface* GetObjectInterface() { return reinterpret_cast(GetInterface()); } DWORD GetModel() { return m_dwModelID; } eModelInfoType GetModelType(); @@ -380,7 +379,6 @@ class CModelInfoSA : public CModelInfo // CModelInfoSA methods void MakePedModel(char* szTexture); - void MakeObjectModel(ushort usBaseModelID); void DeallocateModel(void); SVehicleSupportedUpgrades GetVehicleSupportedUpgrades() { return m_ModelSupportedUpgrades; } diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 9904b0c5d0..3750fe7da0 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -37,6 +37,18 @@ #define FUNC_CStreaming_RemoveImages 0x4066B3 // Remove all IMG`s from streaming #define FUNC_CStreaming_RemoveImage 0x4068A0 +struct CStreamingInfo +{ + WORD prevId; + WORD nextId; + WORD nextInImg; + uchar flg; + uchar archiveId; + DWORD offsetInBlocks; + DWORD sizeInBlocks; + DWORD loadState; +}; + struct CStreamHandlerInfo { char szName[40]; diff --git a/Client/mods/deathmatch/logic/CClientModel.cpp b/Client/mods/deathmatch/logic/CClientModel.cpp index bab7566efd..7aca127086 100644 --- a/Client/mods/deathmatch/logic/CClientModel.cpp +++ b/Client/mods/deathmatch/logic/CClientModel.cpp @@ -37,17 +37,7 @@ bool CClientModel::Allocate(void) // Allocate only on free IDs if (!pModelInfo->IsValid()) { - switch (m_eModelType) - { - case CCLIENTMODELPED: - pModelInfo->MakePedModel("PSYCHO"); - break; - case CCLIENTMODELOBJECT: - pModelInfo->MakeObjectModel(1337); - break; - default: - return false; - } + pModelInfo->MakePedModel("PSYCHO"); return true; } return false; diff --git a/Client/mods/deathmatch/logic/CClientModel.h b/Client/mods/deathmatch/logic/CClientModel.h index 043ab77a92..a39d36f954 100644 --- a/Client/mods/deathmatch/logic/CClientModel.h +++ b/Client/mods/deathmatch/logic/CClientModel.h @@ -17,8 +17,7 @@ class CClientModel; enum eClientModelType { - CCLIENTMODELPED, - CCLIENTMODELOBJECT, + CCLIENTMODELPED }; class CClientModel diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 6a51630816..310c6e7d39 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -684,8 +684,6 @@ int CLuaEngineDefs::EngineRequestModel(lua_State* luaVM) { eModelType = CCLIENTMODELPED; } - else if (strModelType == "object") - eModelType = CCLIENTMODELOBJECT; else { lua_pushboolean(luaVM, false); diff --git a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp index be4f417351..fd6aae5f29 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp @@ -998,6 +998,23 @@ void _declspec(naked) HOOK_CClumpModelInfo_GetFrameFromId() } } +struct CStreamingInfo +{ + DWORD gta_hash; + WORD chain_next; + uchar flg; + uchar archiveId; + DWORD offsetInBlocks; + DWORD sizeInBlocks; + DWORD reqload; +}; + +CStreamingInfo* GetStreamingInfoFromModelId(uint id) +{ + CStreamingInfo* pItemInfo = (CStreamingInfo*)(0x8E4CC0); + return pItemInfo + id; +} + ////////////////////////////////////////////////////////////////////////////////////////// // // CEntity::GetBoundRect @@ -1024,11 +1041,11 @@ void OnMY_CEntity_GetBoundRect(CEntitySAInterface* pEntity) if (!pColModel) { // Crash will occur at offset 00134134 - CStreamingInfo* pStreamingInfo = pGameInterface->GetStreaming()->GetStreamingInfoFromModelId(usModelId); + CStreamingInfo* pStreamingInfo = GetStreamingInfoFromModelId(usModelId); SString strDetails("refs:%d txd:%d RwObj:%08x bOwn:%d bColStr:%d flg:%d off:%d size:%d reqload:%d", pModelInfo->usNumberOfRefs, pModelInfo->usTextureDictionary, pModelInfo->pRwObject, pModelInfo->bDoWeOwnTheColModel, pModelInfo->bCollisionWasStreamedWithModel, pStreamingInfo->flg, pStreamingInfo->offsetInBlocks, pStreamingInfo->sizeInBlocks, - pStreamingInfo->loadState); + pStreamingInfo->reqload); LogEvent(815, "Model collision missing", "CEntity_GetBoundRect", SString("No collision for model:%d %s", usModelId, *strDetails), 5415); CArgMap argMap; argMap.Set("id", usModelId); diff --git a/Client/sdk/game/CModelInfo.h b/Client/sdk/game/CModelInfo.h index c5931c4035..9b8dc4908d 100644 --- a/Client/sdk/game/CModelInfo.h +++ b/Client/sdk/game/CModelInfo.h @@ -177,7 +177,6 @@ class CModelInfo virtual void MakeCustomModel() = 0; virtual RwObject* GetRwObject() = 0; virtual void MakePedModel(char* szTexture) = 0; - virtual void MakeObjectModel(ushort usBaseID) = 0; virtual SVehicleSupportedUpgrades GetVehicleSupportedUpgrades() = 0; virtual void ResetSupportedUpgrades() = 0; diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 7b688fca60..f5c5eaf9e9 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -11,18 +11,6 @@ #pragma once -struct CStreamingInfo -{ - WORD prevId; - WORD nextId; - WORD nextInImg; - unsigned char flg; - unsigned char archiveId; - DWORD offsetInBlocks; - DWORD sizeInBlocks; - DWORD loadState; -}; - class CStreaming { public: @@ -32,6 +20,5 @@ class CStreaming virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; virtual unsigned char AddStreamHandler(const char* szFilePath) = 0; //virtual BOOL RemoveStreamHandler(DWORD dwStreamHandler) = 0; - virtual CStreamingInfo* GetStreamingInfoFromModelId(unsigned short id) = 0; virtual bool SetModelStreamInfo(unsigned short id, unsigned char ucArchiveId, unsigned short usOffestInBlocks, unsigned short usSizeInBlocks) = 0; }; From 74918895d3608739a9df1444c0f19e3d7a13b617 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Mon, 12 Oct 2020 03:20:29 +0300 Subject: [PATCH 09/78] Improved CClientIMG --- Client/mods/deathmatch/logic/CClientIMG.cpp | 35 +++++++++++++++++-- Client/mods/deathmatch/logic/CClientIMG.h | 22 ++++++++++-- .../logic/luadefs/CLuaEngineDefs.cpp | 8 ++--- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 9769f88b3a..38a5bbbfeb 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -13,13 +13,17 @@ CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID) { // Init + m_pContentInfo = NULL; + m_uiFilesCount = 0; m_pManager = pManager; + m_ucStreamID = -1; SetTypeName("img"); } CClientIMG::~CClientIMG() { - + if (m_ucStreamID) + Unlink(); } bool CClientIMG::Load(SString sFilePath) @@ -27,6 +31,9 @@ bool CClientIMG::Load(SString sFilePath) if (sFilePath.empty()) return false; + if (!FileExists(sFilePath)) + return false; + m_strFilename = std::move(sFilePath); /* g_pClientGame->GetResourceManager()->ValidateResourceFile(m_strFilename, nullptr, 0); @@ -34,21 +41,43 @@ bool CClientIMG::Load(SString sFilePath) return false; */ + tImgHeadrer fileHeadrer; + + SString buffer; + + FileLoad(m_strFilename, buffer, sizeof(tImgHeadrer), 0); + + if (fileHeadrer.szMagic != "VER2") + return false; + + m_uiFilesCount = fileHeadrer.uiFilesCount; + + m_pContentInfo = new tImgFileInfo[m_uiFilesCount]; + + FileLoad(m_strFilename, *(SString*)m_pContentInfo, m_uiFilesCount * sizeof(tImgFileInfo), 8); + Stream(); return true; } +tImgFileInfo* CClientIMG::GetFileInfo(unsigned short usFileID) +{ + return &m_pContentInfo[usFileID]; +} + bool CClientIMG::Stream() { m_ucStreamID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); return true; } -bool CClientIMG::LinkModel(unsigned short usModelID, unsigned short usOffestInBlocks, unsigned short usSizeInBlocks) +bool CClientIMG::LinkModel(unsigned short usModelID, unsigned short usFileID ) { if (!m_ucStreamID) return false; - g_pGame->GetStreaming()->SetModelStreamInfo(usModelID, m_ucStreamID, usOffestInBlocks, usSizeInBlocks); + tImgFileInfo* pFileInfo = GetFileInfo(usFileID); + + g_pGame->GetStreaming()->SetModelStreamInfo(usModelID, m_ucStreamID, pFileInfo->uiOffset, pFileInfo->usSize); return true; } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 92e7f4679d..5d0f9bf0c1 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -13,6 +13,20 @@ #include "CClientEntity.h" +struct tImgHeadrer +{ + char szMagic[4]; + unsigned int uiFilesCount; +}; + +struct tImgFileInfo +{ + unsigned int uiOffset; + unsigned short usSize; + unsigned short usUnpackedSize; + char szFileName[24]; +}; + class CClientIMG : public CClientEntity { DECLARE_CLASS(CClientIMG, CClientEntity) @@ -26,12 +40,14 @@ class CClientIMG : public CClientEntity eClientEntityType GetType() const { return CCLIENTIMG; } bool Load(SString sFilePath); - bool Stream(); - bool LinkModel(unsigned short usModelID, unsigned short usOffsetInBlocks, unsigned short usSizeInBlocks); + tImgFileInfo* GetFileInfo(unsigned short usFileID); + bool Stream(); + bool LinkModel(unsigned short usModelID, unsigned short usFileID); private: SString m_strFilename; - SString m_FileData; unsigned char m_ucStreamID; + unsigned int m_uiFilesCount; + tImgFileInfo* m_pContentInfo; }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 310c6e7d39..6a157906fb 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -575,19 +575,17 @@ int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) unsigned short usModelID; CClientIMG* pIMG; // TEMP - unsigned short usOffsetInBlock; - unsigned short usSizeInBlocks; + unsigned short fileID; CScriptArgReader argStream(luaVM); argStream.ReadNumber(usModelID); argStream.ReadUserData(pIMG); - argStream.ReadNumber(usOffsetInBlock); - argStream.ReadNumber(usSizeInBlocks); + argStream.ReadNumber(fileID); if (!argStream.HasErrors()) { - if (pIMG->LinkModel(usModelID, usOffsetInBlock, usSizeInBlocks)) + if (pIMG->LinkModel(usModelID, fileID)) { lua_pushboolean(luaVM, true); return 1; From 947e614f2b238b7f286d049c439c59a08c7d352c Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Tue, 13 Oct 2020 03:51:23 +0300 Subject: [PATCH 10/78] Improved load function --- Client/mods/deathmatch/logic/CClientIMG.cpp | 42 ++++++++++++++++----- Client/mods/deathmatch/logic/CClientIMG.h | 16 ++++---- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 38a5bbbfeb..1d16dce2ca 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -13,7 +13,6 @@ CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID) { // Init - m_pContentInfo = NULL; m_uiFilesCount = 0; m_pManager = pManager; m_ucStreamID = -1; @@ -34,6 +33,9 @@ bool CClientIMG::Load(SString sFilePath) if (!FileExists(sFilePath)) return false; + if (!m_pContentInfo.empty()) + return false; + m_strFilename = std::move(sFilePath); /* g_pClientGame->GetResourceManager()->ValidateResourceFile(m_strFilename, nullptr, 0); @@ -41,27 +43,47 @@ bool CClientIMG::Load(SString sFilePath) return false; */ - tImgHeadrer fileHeadrer; + // Open the file + FILE* pFile = File::Fopen(m_strFilename, "rb"); + if (!pFile) + return false; - SString buffer; + tImgHeader filerHeader; - FileLoad(m_strFilename, buffer, sizeof(tImgHeadrer), 0); + // Read header + int iReadCount = fread(&filerHeader, sizeof(filerHeader), 1, pFile); - if (fileHeadrer.szMagic != "VER2") + if (!iReadCount || memcmp(&filerHeader.szMagic, "VER2", 4)) + { + fclose(pFile); return false; + } - m_uiFilesCount = fileHeadrer.uiFilesCount; + m_uiFilesCount = filerHeader.uiFilesCount; - m_pContentInfo = new tImgFileInfo[m_uiFilesCount]; + // Read content info + + m_pContentInfo.resize(m_uiFilesCount); + + iReadCount = fread(&m_pContentInfo.at(0), sizeof(tImgFileInfo), m_uiFilesCount, pFile); + + if (iReadCount != m_uiFilesCount) + { + fclose(pFile); + m_pContentInfo.clear(); + return false; + } - FileLoad(m_strFilename, *(SString*)m_pContentInfo, m_uiFilesCount * sizeof(tImgFileInfo), 8); + //Stream(); - Stream(); + fclose(pFile); return true; } tImgFileInfo* CClientIMG::GetFileInfo(unsigned short usFileID) { + if (usFileID > m_uiFilesCount) + return NULL; return &m_pContentInfo[usFileID]; } @@ -78,6 +100,6 @@ bool CClientIMG::LinkModel(unsigned short usModelID, unsigned short usFileID ) tImgFileInfo* pFileInfo = GetFileInfo(usFileID); - g_pGame->GetStreaming()->SetModelStreamInfo(usModelID, m_ucStreamID, pFileInfo->uiOffset, pFileInfo->usSize); + //g_pGame->GetStreaming()->SetModelStreamInfo(usModelID, m_ucStreamID, pFileInfo->uiOffset, pFileInfo->usSize); return true; } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 5d0f9bf0c1..3395906766 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -13,10 +13,10 @@ #include "CClientEntity.h" -struct tImgHeadrer +struct tImgHeader { - char szMagic[4]; - unsigned int uiFilesCount; + char szMagic[4]; + unsigned int uiFilesCount; }; struct tImgFileInfo @@ -40,14 +40,16 @@ class CClientIMG : public CClientEntity eClientEntityType GetType() const { return CCLIENTIMG; } bool Load(SString sFilePath); + bool Unload(); tImgFileInfo* GetFileInfo(unsigned short usFileID); + unsigned int GetFileID(SString sFileName); bool Stream(); bool LinkModel(unsigned short usModelID, unsigned short usFileID); private: - SString m_strFilename; - unsigned char m_ucStreamID; - unsigned int m_uiFilesCount; - tImgFileInfo* m_pContentInfo; + SString m_strFilename; + unsigned char m_ucStreamID; + unsigned int m_uiFilesCount; + std::vector m_pContentInfo; }; From 2b3eac9c979d8dad02cc12b2f39505aa4ab5e8a1 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Tue, 13 Oct 2020 03:52:08 +0300 Subject: [PATCH 11/78] Changed value for fail case in CStreamingSA --- Client/game_sa/CStreamingSA.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 2bc1629fb2..e12e9385f6 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -176,7 +176,7 @@ unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) } if (ucArchiveId == 0) - return 0; + return -1; // Get free stream handler id HANDLE hFile = INVALID_HANDLE_VALUE; @@ -193,7 +193,7 @@ unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) }; if (ucStreamID == 0) - return 0; + return -1; // Create new stream handler DWORD dOpenFlags = *(DWORD*)(VAR_StreamHandlerCreateFlags) | FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS; @@ -201,7 +201,7 @@ unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) hFile = CreateFileA(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dOpenFlags, NULL); if (hFile == INVALID_HANDLE_VALUE) - return 0; + return -1; // Register stream handler void* streamHandlerPos = (void*)(ARRAY_StreamHandlers + ucStreamID * sizeof(HANDLE)); From aab81529893553d7020f0dcf269ff1ce30871645 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Tue, 13 Oct 2020 04:31:06 +0300 Subject: [PATCH 12/78] Improved Lua API for engineSetModelIMG --- Client/mods/deathmatch/logic/CClientIMG.cpp | 22 +++++++++++++++---- Client/mods/deathmatch/logic/CClientIMG.h | 4 ++-- .../logic/luadefs/CLuaEngineDefs.cpp | 14 ++++++++---- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 1d16dce2ca..0e066aca37 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -80,26 +80,40 @@ bool CClientIMG::Load(SString sFilePath) return true; } -tImgFileInfo* CClientIMG::GetFileInfo(unsigned short usFileID) +tImgFileInfo* CClientIMG::GetFileInfo(unsigned int usFileID) { if (usFileID > m_uiFilesCount) return NULL; return &m_pContentInfo[usFileID]; } +unsigned int CClientIMG::GetFileID(SString strFileName) +{ + strFileName.resize(24); + for (unsigned int i = 0; i < m_uiFilesCount; i++) + { + if (strFileName.compare(m_pContentInfo[i].szFileName)) + return i; + } + return -1; +} + bool CClientIMG::Stream() { m_ucStreamID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); return true; } -bool CClientIMG::LinkModel(unsigned short usModelID, unsigned short usFileID ) +bool CClientIMG::LinkModel(unsigned short usModelID, unsigned int uiFileID ) { if (!m_ucStreamID) return false; - tImgFileInfo* pFileInfo = GetFileInfo(usFileID); + if (uiFileID >= m_uiFilesCount) + return false; + + tImgFileInfo* pFileInfo = GetFileInfo(uiFileID); - //g_pGame->GetStreaming()->SetModelStreamInfo(usModelID, m_ucStreamID, pFileInfo->uiOffset, pFileInfo->usSize); + g_pGame->GetStreaming()->SetModelStreamInfo(usModelID, m_ucStreamID, pFileInfo->uiOffset, pFileInfo->usSize); return true; } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 3395906766..bb451cef04 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -41,11 +41,11 @@ class CClientIMG : public CClientEntity eClientEntityType GetType() const { return CCLIENTIMG; } bool Load(SString sFilePath); bool Unload(); - tImgFileInfo* GetFileInfo(unsigned short usFileID); + tImgFileInfo* GetFileInfo(unsigned int usFileID); unsigned int GetFileID(SString sFileName); bool Stream(); - bool LinkModel(unsigned short usModelID, unsigned short usFileID); + bool LinkModel(unsigned short usModelID, unsigned int usFileID); private: SString m_strFilename; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 6a157906fb..a3be7a9489 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -574,18 +574,24 @@ int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) { unsigned short usModelID; CClientIMG* pIMG; - // TEMP - unsigned short fileID; + unsigned int fileID = -1; + SString strFileName; CScriptArgReader argStream(luaVM); argStream.ReadNumber(usModelID); argStream.ReadUserData(pIMG); - argStream.ReadNumber(fileID); + if (argStream.NextIsNumber()) + argStream.ReadNumber(fileID); + else + argStream.ReadString(strFileName); if (!argStream.HasErrors()) { - if (pIMG->LinkModel(usModelID, fileID)) + if (fileID == -1) + fileID = pIMG->GetFileID(strFileName); + + if (fileID != -1 && pIMG->LinkModel(usModelID, fileID)) { lua_pushboolean(luaVM, true); return 1; From b52d9de996198282713a854f683f662fb4a50c86 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Tue, 13 Oct 2020 05:35:59 +0300 Subject: [PATCH 13/78] Added some unlink interface --- Client/mods/deathmatch/logic/CClientIMG.cpp | 50 ++++++++++++++++++--- Client/mods/deathmatch/logic/CClientIMG.h | 23 ++++++---- Client/sdk/game/CStreaming.h | 2 +- 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 0e066aca37..55cdb24818 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -10,6 +10,12 @@ #include +struct tImgHeader +{ + char szMagic[4]; + unsigned int uiFilesCount; +}; + CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID) { // Init @@ -21,8 +27,8 @@ CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit CClientIMG::~CClientIMG() { - if (m_ucStreamID) - Unlink(); + if (m_ucStreamID != -1) + StreamDisable(); } bool CClientIMG::Load(SString sFilePath) @@ -98,15 +104,35 @@ unsigned int CClientIMG::GetFileID(SString strFileName) return -1; } -bool CClientIMG::Stream() +bool CClientIMG::StreamEnable() { + if (!m_uiFilesCount) + return false; + + m_pRestoreData.resize(m_uiFilesCount); m_ucStreamID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); + return m_ucStreamID != -1; +} + +bool CClientIMG::StreamDisable() +{ + if (m_ucStreamID == -1) + return false; + + for (unsigned int i = 0; i < m_pRestoreData.size(); i++ ) + { + tLinkedModelRestoreInfo* pRestoreData = &m_pRestoreData[i]; + if (pRestoreData->uiOffset) + g_pGame->GetStreaming()->SetModelStreamInfo(pRestoreData->uiModelID, pRestoreData->ucStreamID, pRestoreData->uiOffset, pRestoreData->usSize); + } + + m_pRestoreData.clear(); return true; } -bool CClientIMG::LinkModel(unsigned short usModelID, unsigned int uiFileID ) +bool CClientIMG::LinkModel(unsigned int usModelID, unsigned int uiFileID ) { - if (!m_ucStreamID) + if (m_ucStreamID == -1) return false; if (uiFileID >= m_uiFilesCount) @@ -117,3 +143,17 @@ bool CClientIMG::LinkModel(unsigned short usModelID, unsigned int uiFileID ) g_pGame->GetStreaming()->SetModelStreamInfo(usModelID, m_ucStreamID, pFileInfo->uiOffset, pFileInfo->usSize); return true; } + +bool CClientIMG::UnlinkModel(unsigned int uiModelID) +{ + for (unsigned int i = 0; i < m_pRestoreData.size(); i++) + { + if (m_pRestoreData[i].uiModelID == uiModelID) + { + g_pGame->GetStreaming()->SetModelStreamInfo(uiModelID, m_pRestoreData[i].ucStreamID, m_pRestoreData[i].uiOffset, m_pRestoreData[i].usSize); + return true; + } + } + + return false; +} diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index bb451cef04..6d186ad65f 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -13,12 +13,6 @@ #include "CClientEntity.h" -struct tImgHeader -{ - char szMagic[4]; - unsigned int uiFilesCount; -}; - struct tImgFileInfo { unsigned int uiOffset; @@ -27,6 +21,14 @@ struct tImgFileInfo char szFileName[24]; }; +struct tLinkedModelRestoreInfo +{ + unsigned int uiModelID; + unsigned char ucStreamID; + unsigned int uiOffset; + unsigned short usSize; +}; + class CClientIMG : public CClientEntity { DECLARE_CLASS(CClientIMG, CClientEntity) @@ -44,12 +46,17 @@ class CClientIMG : public CClientEntity tImgFileInfo* GetFileInfo(unsigned int usFileID); unsigned int GetFileID(SString sFileName); - bool Stream(); - bool LinkModel(unsigned short usModelID, unsigned int usFileID); + bool StreamEnable(); + bool StreamDisable(); + bool LinkModel(unsigned int usModelID, unsigned int usFileID); + bool UnlinkModel(unsigned int usModelID); + private: SString m_strFilename; unsigned char m_ucStreamID; unsigned int m_uiFilesCount; std::vector m_pContentInfo; + + std::vector m_pRestoreData; }; diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index f5c5eaf9e9..ef63375a52 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -19,6 +19,6 @@ class CStreaming virtual BOOL HasModelLoaded(DWORD dwModelID) = 0; virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; virtual unsigned char AddStreamHandler(const char* szFilePath) = 0; - //virtual BOOL RemoveStreamHandler(DWORD dwStreamHandler) = 0; + virtual BOOL RemoveStreamHandler(unsigned char dwStreamHandler) = 0; virtual bool SetModelStreamInfo(unsigned short id, unsigned char ucArchiveId, unsigned short usOffestInBlocks, unsigned short usSizeInBlocks) = 0; }; From 719b273680be8decfc9c7be4e585d8781f3deaa4 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Tue, 13 Oct 2020 06:52:39 +0300 Subject: [PATCH 14/78] Improved unlink interface --- Client/game_sa/CStreamingSA.cpp | 32 ++++++++++++++++++ Client/game_sa/CStreamingSA.h | 5 +-- Client/mods/deathmatch/logic/CClientIMG.cpp | 36 ++++++++++++++++----- Client/mods/deathmatch/logic/CClientIMG.h | 2 +- Client/sdk/game/CStreaming.h | 30 +++++++++++++++-- 5 files changed, 92 insertions(+), 13 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index e12e9385f6..5560b80c26 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -136,6 +136,15 @@ void CStreamingSA::RequestSpecialModel(DWORD model, const char* szTexture, DWORD } } +void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg) +{ + CStreamingInfo* pItemInfo = GetStreamingInfoFromModelId(id); + pItemInfo->archiveId = usStreamID; + pItemInfo->offsetInBlocks = uiOffset; + pItemInfo->sizeInBlocks = usSize; + pItemInfo->nextInImg = uiNextInImg; +} + CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(ushort id) { CStreamingInfo* pItemInfo = (CStreamingInfo*)(ARRAY_StreamModelInfo); @@ -213,3 +222,26 @@ unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) return ucArchiveId; } + +bool CStreamingSA::SetModelStreamInfo(ushort id, uchar ucArchiveId, ushort usOffestInBlocks, ushort usSizeInBlocks) +{ + CStreamingInfo* pItemInfo = GetStreamingInfoFromModelId(id); + pItemInfo->archiveId = ucArchiveId; + pItemInfo->offsetInBlocks = usOffestInBlocks; + pItemInfo->sizeInBlocks = usSizeInBlocks; + // TODO CHANGE THIS INFO FOR PREV MODEL + pItemInfo->nextInImg = -1; + return true; +} + +CStreamHandlerInfo* CStreamingSA::GetStreamingHandlerInfo(uint id) +{ + CStreamHandlerInfo* pHandlerInfo = (CStreamHandlerInfo*)(ARRAY_StreamHandlersInfo); + return pHandlerInfo + id; +} + + +void CStreamingSA::RemoveStreamHandler(unsigned char ucArhiveID) +{ + return; +} diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 3750fe7da0..321a19464d 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -69,7 +69,8 @@ class CStreamingSA : public CStreaming BOOL HasModelLoaded(DWORD dwModelID); void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel); + void SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1); CStreamingInfo* GetStreamingInfoFromModelId(ushort id); - unsigned char AddStreamHandler(const char* szFilePath); - //BOOL RemoveStreamHandler(DWORD dwStreamHandler); + unsigned char AddStreamHandler(const char* szFilePath); + void RemoveStreamHandler(unsigned char ucStreamHandler); }; diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 55cdb24818..2b0cddce64 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -109,7 +109,7 @@ bool CClientIMG::StreamEnable() if (!m_uiFilesCount) return false; - m_pRestoreData.resize(m_uiFilesCount); + m_pRestoreData.reserve(m_uiFilesCount); m_ucStreamID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); return m_ucStreamID != -1; } @@ -121,16 +121,23 @@ bool CClientIMG::StreamDisable() for (unsigned int i = 0; i < m_pRestoreData.size(); i++ ) { - tLinkedModelRestoreInfo* pRestoreData = &m_pRestoreData[i]; - if (pRestoreData->uiOffset) - g_pGame->GetStreaming()->SetModelStreamInfo(pRestoreData->uiModelID, pRestoreData->ucStreamID, pRestoreData->uiOffset, pRestoreData->usSize); + tLinkedModelRestoreInfo* pRestoreData = m_pRestoreData[i]; + if (pRestoreData) + { + g_pGame->GetStreaming()->SetStreamingInfoForModelId(pRestoreData->uiModelID, pRestoreData->ucStreamID, pRestoreData->uiOffset, + pRestoreData->usSize); + delete pRestoreData; + } } m_pRestoreData.clear(); + + g_pGame->GetStreaming()->RemoveStreamHandler(m_ucStreamID); + m_ucStreamID = -1; return true; } -bool CClientIMG::LinkModel(unsigned int usModelID, unsigned int uiFileID ) +bool CClientIMG::LinkModel(unsigned int uiModelID, unsigned int uiFileID) { if (m_ucStreamID == -1) return false; @@ -140,7 +147,17 @@ bool CClientIMG::LinkModel(unsigned int usModelID, unsigned int uiFileID ) tImgFileInfo* pFileInfo = GetFileInfo(uiFileID); - g_pGame->GetStreaming()->SetModelStreamInfo(usModelID, m_ucStreamID, pFileInfo->uiOffset, pFileInfo->usSize); + CStreamingInfo* pCurrentStreamingInfo = g_pGame->GetStreaming()->GetStreamingInfoFromModelId(uiModelID); + + tLinkedModelRestoreInfo* pModelRestoreData = new tLinkedModelRestoreInfo(); + pModelRestoreData->uiModelID = uiModelID; + pModelRestoreData->ucStreamID = pCurrentStreamingInfo->archiveId; + pModelRestoreData->uiOffset = pCurrentStreamingInfo->offsetInBlocks; + pModelRestoreData->usSize = pCurrentStreamingInfo->sizeInBlocks; + + m_pRestoreData.push_back(pModelRestoreData); + + g_pGame->GetStreaming()->SetStreamingInfoForModelId(uiModelID, m_ucStreamID, pFileInfo->uiOffset, pFileInfo->usSize); return true; } @@ -148,9 +165,12 @@ bool CClientIMG::UnlinkModel(unsigned int uiModelID) { for (unsigned int i = 0; i < m_pRestoreData.size(); i++) { - if (m_pRestoreData[i].uiModelID == uiModelID) + if (m_pRestoreData[i]->uiModelID == uiModelID) { - g_pGame->GetStreaming()->SetModelStreamInfo(uiModelID, m_pRestoreData[i].ucStreamID, m_pRestoreData[i].uiOffset, m_pRestoreData[i].usSize); + tLinkedModelRestoreInfo* pRestoreData = m_pRestoreData[i]; + g_pGame->GetStreaming()->SetStreamingInfoForModelId(uiModelID, pRestoreData->ucStreamID, pRestoreData->uiOffset, pRestoreData->usSize); + delete pRestoreData; + m_pRestoreData.erase(m_pRestoreData.begin() + i); return true; } } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 6d186ad65f..aa0f7990c7 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -58,5 +58,5 @@ class CClientIMG : public CClientEntity unsigned int m_uiFilesCount; std::vector m_pContentInfo; - std::vector m_pRestoreData; + std::vector m_pRestoreData; }; diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index ef63375a52..1a488da7d3 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -11,6 +11,31 @@ #pragma once +struct CStreamingInfo +{ + WORD prevId; + WORD nextId; + WORD nextInImg; + BYTE flg; + BYTE archiveId; + DWORD offsetInBlocks; + DWORD sizeInBlocks; + DWORD loadState; + +public: + void Reset() + { + this->loadState = 0; + this->nextInImg = -1; + this->nextId = -1; + this->prevId = -1; + this->archiveId = 0; + this->flg = 0; + this->offsetInBlocks = 0; + this->sizeInBlocks = 0; + }; +}; + class CStreaming { public: @@ -19,6 +44,7 @@ class CStreaming virtual BOOL HasModelLoaded(DWORD dwModelID) = 0; virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; virtual unsigned char AddStreamHandler(const char* szFilePath) = 0; - virtual BOOL RemoveStreamHandler(unsigned char dwStreamHandler) = 0; - virtual bool SetModelStreamInfo(unsigned short id, unsigned char ucArchiveId, unsigned short usOffestInBlocks, unsigned short usSizeInBlocks) = 0; + virtual void RemoveStreamHandler(unsigned char dwStreamHandler) = 0; + virtual CStreamingInfo* GetStreamingInfoFromModelId(unsigned int id) = 0; + virtual void SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1) = 0; }; From acff78f9ea09b0a7dfc0b352a93abf2c3f73e74b Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Thu, 15 Oct 2020 23:21:17 +0300 Subject: [PATCH 15/78] Added IMG manager, fix build --- Client/game_sa/CStreamingSA.cpp | 20 +--- Client/game_sa/CStreamingSA.h | 14 +-- Client/mods/deathmatch/logic/CClientIMG.cpp | 18 +-- Client/mods/deathmatch/logic/CClientIMG.h | 5 +- .../deathmatch/logic/CClientIMGManager.cpp | 110 ++++++++++++++++++ .../mods/deathmatch/logic/CClientIMGManager.h | 44 +++++++ .../mods/deathmatch/logic/CClientManager.cpp | 4 + Client/mods/deathmatch/logic/CClientManager.h | 3 + .../deathmatch/logic/lua/CLuaFunctionDefs.cpp | 2 + .../deathmatch/logic/lua/CLuaFunctionDefs.h | 1 + .../deathmatch/logic/luadefs/CLuaDefs.cpp | 2 + .../mods/deathmatch/logic/luadefs/CLuaDefs.h | 1 + .../logic/luadefs/CLuaEngineDefs.cpp | 27 +++++ .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 1 + .../CMultiplayerSA_CrashFixHacks.cpp | 15 +-- Client/sdk/game/CStreaming.h | 2 +- 16 files changed, 212 insertions(+), 57 deletions(-) create mode 100644 Client/mods/deathmatch/logic/CClientIMGManager.cpp create mode 100644 Client/mods/deathmatch/logic/CClientIMGManager.h diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 5560b80c26..90ed4cef74 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -145,7 +145,7 @@ void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, pItemInfo->nextInImg = uiNextInImg; } -CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(ushort id) +CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) { CStreamingInfo* pItemInfo = (CStreamingInfo*)(ARRAY_StreamModelInfo); return pItemInfo + id; @@ -223,24 +223,6 @@ unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) return ucArchiveId; } -bool CStreamingSA::SetModelStreamInfo(ushort id, uchar ucArchiveId, ushort usOffestInBlocks, ushort usSizeInBlocks) -{ - CStreamingInfo* pItemInfo = GetStreamingInfoFromModelId(id); - pItemInfo->archiveId = ucArchiveId; - pItemInfo->offsetInBlocks = usOffestInBlocks; - pItemInfo->sizeInBlocks = usSizeInBlocks; - // TODO CHANGE THIS INFO FOR PREV MODEL - pItemInfo->nextInImg = -1; - return true; -} - -CStreamHandlerInfo* CStreamingSA::GetStreamingHandlerInfo(uint id) -{ - CStreamHandlerInfo* pHandlerInfo = (CStreamHandlerInfo*)(ARRAY_StreamHandlersInfo); - return pHandlerInfo + id; -} - - void CStreamingSA::RemoveStreamHandler(unsigned char ucArhiveID) { return; diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 321a19464d..61f90fd661 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -37,18 +37,6 @@ #define FUNC_CStreaming_RemoveImages 0x4066B3 // Remove all IMG`s from streaming #define FUNC_CStreaming_RemoveImage 0x4068A0 -struct CStreamingInfo -{ - WORD prevId; - WORD nextId; - WORD nextInImg; - uchar flg; - uchar archiveId; - DWORD offsetInBlocks; - DWORD sizeInBlocks; - DWORD loadState; -}; - struct CStreamHandlerInfo { char szName[40]; @@ -70,7 +58,7 @@ class CStreamingSA : public CStreaming void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel); void SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1); - CStreamingInfo* GetStreamingInfoFromModelId(ushort id); + CStreamingInfo* GetStreamingInfoFromModelId(uint id); unsigned char AddStreamHandler(const char* szFilePath); void RemoveStreamHandler(unsigned char ucStreamHandler); }; diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 2b0cddce64..3219251cb1 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -21,13 +21,13 @@ CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit // Init m_uiFilesCount = 0; m_pManager = pManager; - m_ucStreamID = -1; + m_ucArchiveID = -1; SetTypeName("img"); } CClientIMG::~CClientIMG() { - if (m_ucStreamID != -1) + if (m_ucArchiveID != -1) StreamDisable(); } @@ -110,13 +110,13 @@ bool CClientIMG::StreamEnable() return false; m_pRestoreData.reserve(m_uiFilesCount); - m_ucStreamID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); - return m_ucStreamID != -1; + m_ucArchiveID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); + return m_ucArchiveID != -1; } bool CClientIMG::StreamDisable() { - if (m_ucStreamID == -1) + if (m_ucArchiveID == -1) return false; for (unsigned int i = 0; i < m_pRestoreData.size(); i++ ) @@ -132,14 +132,14 @@ bool CClientIMG::StreamDisable() m_pRestoreData.clear(); - g_pGame->GetStreaming()->RemoveStreamHandler(m_ucStreamID); - m_ucStreamID = -1; + g_pGame->GetStreaming()->RemoveStreamHandler(m_ucArchiveID); + m_ucArchiveID = -1; return true; } bool CClientIMG::LinkModel(unsigned int uiModelID, unsigned int uiFileID) { - if (m_ucStreamID == -1) + if (m_ucArchiveID == -1) return false; if (uiFileID >= m_uiFilesCount) @@ -157,7 +157,7 @@ bool CClientIMG::LinkModel(unsigned int uiModelID, unsigned int uiFileID) m_pRestoreData.push_back(pModelRestoreData); - g_pGame->GetStreaming()->SetStreamingInfoForModelId(uiModelID, m_ucStreamID, pFileInfo->uiOffset, pFileInfo->usSize); + g_pGame->GetStreaming()->SetStreamingInfoForModelId(uiModelID, m_ucArchiveID, pFileInfo->uiOffset, pFileInfo->usSize); return true; } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index aa0f7990c7..08dc16a95a 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -40,7 +40,8 @@ class CClientIMG : public CClientEntity void GetPosition(CVector& vecPosition) const {}; void SetPosition(const CVector& vecPosition){}; - eClientEntityType GetType() const { return CCLIENTIMG; } + eClientEntityType GetType() const { return CCLIENTIMG; }; + unsigned char GetArchiveID() { return m_ucArchiveID; }; bool Load(SString sFilePath); bool Unload(); tImgFileInfo* GetFileInfo(unsigned int usFileID); @@ -54,7 +55,7 @@ class CClientIMG : public CClientEntity private: SString m_strFilename; - unsigned char m_ucStreamID; + unsigned char m_ucArchiveID; unsigned int m_uiFilesCount; std::vector m_pContentInfo; diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.cpp b/Client/mods/deathmatch/logic/CClientIMGManager.cpp new file mode 100644 index 0000000000..45207077cb --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientIMGManager.cpp @@ -0,0 +1,110 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/CClientIMGManager.cpp + * PURPOSE: .img container manager class + * + *****************************************************************************/ + +#include "StdInc.h" + +CClientIMGManager::CClientIMGManager(CClientManager* pManager) +{ + // Init + m_bRemoveFromList = true; +} + +CClientIMGManager::~CClientIMGManager() +{ + // Delete all our IMG's + RemoveAll(); +} + +CClientIMG* CClientIMGManager::GetElementFromArchiveID(unsigned char ucArchiveID) +{ + // By default GTA has 5 IMG's + if (ucArchiveID < 6) + return NULL; + + std::list::iterator iter = m_List.begin(); + for (; iter != m_List.end(); iter++) + { + CClientIMG* pIMG = *iter; + if (ucArchiveID == pIMG->GetArchiveID()) + { + return pIMG; + } + } + + return NULL; +} + +void CClientIMGManager::RemoveAll() +{ + // Make sure they don't remove themselves from our list + m_bRemoveFromList = false; + + // Run through our list deleting the IMG's + std::list::iterator iter = m_List.begin(); + for (; iter != m_List.end(); iter++) + { + delete *iter; + } + + // Allow list removal again + m_bRemoveFromList = true; +} + +bool CClientIMGManager::Exists(CClientIMG* pIMG) +{ + // Matches given IMG? + std::list::iterator iter = m_List.begin(); + for (; iter != m_List.end(); iter++) + { + // Match? + if (pIMG == *iter) + { + // It exists + return true; + } + } + + // It doesn't + return false; +} + +CClientIMG* CClientIMGManager::GetElementThatLinked(unsigned int uiModel) +{ + uchar ucArhiveID = g_pGame->GetStreaming()->GetStreamingInfoFromModelId(uiModel)->archiveId; + return GetElementFromArchiveID(ucArhiveID); +} + +bool CClientIMGManager::IsLinkableModel(unsigned int uiModel) +{ + return uiModel <= 26316; // StreamModelInfoSize +} + +bool CClientIMGManager::RestoreModel(unsigned int uiModel) +{ + // Get the DFF file that replaced it + CClientIMG* pIMG = GetElementThatLinked(uiModel); + if (pIMG) + { + // Restore it + return pIMG->UnlinkModel(uiModel); + } + + // Nothing to restore + return false; +} + +void CClientIMGManager::RemoveFromList(CClientIMG* pIMG) +{ + // Can we remove anything from the list? + if (m_bRemoveFromList) + { + m_List.remove(pIMG); + } +} diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.h b/Client/mods/deathmatch/logic/CClientIMGManager.h new file mode 100644 index 0000000000..3af4cad7b5 --- /dev/null +++ b/Client/mods/deathmatch/logic/CClientIMGManager.h @@ -0,0 +1,44 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * (Shared logic for modifications) + * LICENSE: See LICENSE in the top level directory + * FILE: mods/shared_logic/CClientIMGManager.h + * PURPOSE: .img container odel manager class + * + *****************************************************************************/ + +class CClientIMGManager; + +#pragma once + +#include +#include "CClientIMG.h" + +class CClientIMGManager +{ + friend class CClientIMG; + +public: + CClientIMGManager(class CClientManager* pManager); + ~CClientIMGManager(); + + void RemoveAll(); + bool Exists(CClientIMG* pIMG); + + CClientIMG* GetElementFromArchiveID(unsigned char ucStreamID); + CClientIMG* GetElementThatLinked(unsigned int uiModel); + + bool RestoreModel(unsigned int uiModel); + static bool IsLinkableModel(unsigned int uiModel); + + std::list::const_iterator IterBegin() { return m_List.begin(); } + std::list::const_iterator IterEnd() { return m_List.end(); } + +private: + void AddToList(CClientIMG* pIMG) { m_List.push_back(pIMG); } + void RemoveFromList(CClientIMG* pIMG); + + std::list m_List; + bool m_bRemoveFromList; +}; diff --git a/Client/mods/deathmatch/logic/CClientManager.cpp b/Client/mods/deathmatch/logic/CClientManager.cpp index 2f2683a758..7b49d398d1 100644 --- a/Client/mods/deathmatch/logic/CClientManager.cpp +++ b/Client/mods/deathmatch/logic/CClientManager.cpp @@ -54,6 +54,7 @@ CClientManager::CClientManager() m_pPointLightsManager = new CClientPointLightsManager(this); m_pModelManager = new CClientModelManager(this); m_pPacketRecorder = new CClientPacketRecorder(this); + m_pImgManager = new CClientIMGManager(this); m_bBeingDeleted = false; m_bGameUnloadedFlag = false; @@ -177,6 +178,9 @@ CClientManager::~CClientManager() delete m_pModelManager; m_pModelManager = nullptr; + + delete m_pImgManager; + m_pImgManager = nullptr; } // diff --git a/Client/mods/deathmatch/logic/CClientManager.h b/Client/mods/deathmatch/logic/CClientManager.h index 6cde4c247a..3bfa7cdd8f 100644 --- a/Client/mods/deathmatch/logic/CClientManager.h +++ b/Client/mods/deathmatch/logic/CClientManager.h @@ -43,6 +43,7 @@ class CClientManager; #include "CClientEffectManager.h" #include "CClientPointLightsManager.h" #include "CClientModelManager.h" +#include "CClientIMGManager.h" class CClientProjectileManager; class CClientExplosionManager; @@ -96,6 +97,7 @@ class CClientManager CClientWeaponManager* GetWeaponManager() { return m_pWeaponManager; } CClientEffectManager* GetEffectManager() { return m_pEffectManager; } CClientPointLightsManager* GetPointLightsManager() { return m_pPointLightsManager; } + CClientIMGManager* GetIMGManager() { return m_pImgManager; } bool IsGameLoaded() { return g_pGame->GetSystemState() == 9 && !m_bGameUnloadedFlag && g_pCore->GetNetwork()->GetServerBitStreamVersion(); } bool IsBeingDeleted() { return m_bBeingDeleted; } @@ -147,6 +149,7 @@ class CClientManager CClientEffectManager* m_pEffectManager; CClientPointLightsManager* m_pPointLightsManager; CClientModelManager* m_pModelManager; + CClientIMGManager* m_pImgManager; CClientPacketRecorder* m_pPacketRecorder; bool m_bBeingDeleted; bool m_bGameUnloadedFlag; diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.cpp b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.cpp index 856a4fadbf..912fd99f66 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.cpp +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.cpp @@ -30,6 +30,7 @@ CClientPickupManager* CLuaFunctionDefs::m_pPickupManager; CClientDFFManager* CLuaFunctionDefs::m_pDFFManager; CClientColModelManager* CLuaFunctionDefs::m_pColModelManager; CRegisteredCommands* CLuaFunctionDefs::m_pRegisteredCommands; +CClientIMGManager* CLuaFunctionDefs::m_pImgManager; void CLuaFunctionDefs::Initialize(CLuaManager* pLuaManager, CScriptDebugging* pScriptDebugging, CClientGame* pClientGame) { @@ -53,4 +54,5 @@ void CLuaFunctionDefs::Initialize(CLuaManager* pLuaManager, CScriptDebugging* pS m_pDFFManager = m_pManager->GetDFFManager(); m_pColModelManager = m_pManager->GetColModelManager(); m_pRegisteredCommands = m_pClientGame->GetRegisteredCommands(); + m_pImgManager = m_pManager->GetIMGManager(); } diff --git a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h index 93d18613df..bf3fa9b195 100644 --- a/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h +++ b/Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.h @@ -243,4 +243,5 @@ class CLuaFunctionDefs static CClientDFFManager* m_pDFFManager; static CClientColModelManager* m_pColModelManager; static CRegisteredCommands* m_pRegisteredCommands; + static CClientIMGManager* m_pImgManager; }; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.cpp index 97c2f67406..de07ea84a4 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.cpp @@ -30,6 +30,7 @@ CClientPickupManager* CLuaDefs::m_pPickupManager = NULL; CClientDFFManager* CLuaDefs::m_pDFFManager = NULL; CClientColModelManager* CLuaDefs::m_pColModelManager = NULL; CRegisteredCommands* CLuaDefs::m_pRegisteredCommands = NULL; +CClientIMGManager* CLuaDefs::m_pImgManager = NULL; bool ms_bRegisterdPostCallHook = false; void CLuaDefs::Initialize(CClientGame* pClientGame, CLuaManager* pLuaManager, CScriptDebugging* pScriptDebugging) @@ -54,6 +55,7 @@ void CLuaDefs::Initialize(CClientGame* pClientGame, CLuaManager* pLuaManager, CS m_pDFFManager = m_pManager->GetDFFManager(); m_pColModelManager = m_pManager->GetColModelManager(); m_pRegisteredCommands = pClientGame->GetRegisteredCommands(); + m_pImgManager = m_pManager->GetIMGManager(); } int CLuaDefs::CanUseFunction(lua_CFunction f, lua_State* luaVM) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h index de1a300220..2a864f3060 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaDefs.h @@ -64,6 +64,7 @@ class CLuaDefs static CClientDFFManager* m_pDFFManager; static CClientColModelManager* m_pColModelManager; static CRegisteredCommands* m_pRegisteredCommands; + static CClientIMGManager* m_pImgManager; protected: // Old style: Only warn on failure. This should diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index a3be7a9489..694bf473aa 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -24,6 +24,7 @@ void CLuaEngineDefs::LoadFunctions() {"engineReplaceCOL", EngineReplaceCOL}, {"engineRestoreCOL", EngineRestoreCOL}, {"engineSetModelIMG", EngineSetModelIMG}, + {"engineRestoreModelIMG", EngineRestoreModelIMG}, {"engineReplaceModel", EngineReplaceModel}, {"engineRestoreModel", EngineRestoreModel}, {"engineReplaceAnimation", EngineReplaceAnimation}, @@ -606,6 +607,32 @@ int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) return 1; } +int CLuaEngineDefs::EngineRestoreModelIMG(lua_State* luaVM) +{ + // Grab the model ID + unsigned int uiModelID = CModelNames::ResolveModelID(lua_tostring(luaVM, 1)); + + // Valid client DFF and model? + if (CClientIMGManager::IsLinkableModel(uiModelID)) + { + // Restore the model + if (m_pImgManager->RestoreModel(uiModelID)) + { + // Success + lua_pushboolean(luaVM, true); + return true; + } + } + else + { + m_pScriptDebugging->LogBadType(luaVM); + } + + // Failure + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaEngineDefs::EngineReplaceModel(lua_State* luaVM) { CClientDFF* pDFF; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 6c42d8f81b..fb3ca82a03 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -27,6 +27,7 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineReplaceCOL); LUA_DECLARE(EngineRestoreCOL); LUA_DECLARE(EngineSetModelIMG); + LUA_DECLARE(EngineRestoreModelIMG); LUA_DECLARE(EngineReplaceModel); LUA_DECLARE(EngineRestoreModel); LUA_DECLARE(EngineRequestModel); diff --git a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp index fd6aae5f29..f04d878533 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp @@ -998,17 +998,6 @@ void _declspec(naked) HOOK_CClumpModelInfo_GetFrameFromId() } } -struct CStreamingInfo -{ - DWORD gta_hash; - WORD chain_next; - uchar flg; - uchar archiveId; - DWORD offsetInBlocks; - DWORD sizeInBlocks; - DWORD reqload; -}; - CStreamingInfo* GetStreamingInfoFromModelId(uint id) { CStreamingInfo* pItemInfo = (CStreamingInfo*)(0x8E4CC0); @@ -1042,10 +1031,10 @@ void OnMY_CEntity_GetBoundRect(CEntitySAInterface* pEntity) { // Crash will occur at offset 00134134 CStreamingInfo* pStreamingInfo = GetStreamingInfoFromModelId(usModelId); - SString strDetails("refs:%d txd:%d RwObj:%08x bOwn:%d bColStr:%d flg:%d off:%d size:%d reqload:%d", pModelInfo->usNumberOfRefs, + SString strDetails("refs:%d txd:%d RwObj:%08x bOwn:%d bColStr:%d flg:%d off:%d size:%d loadState:%d", pModelInfo->usNumberOfRefs, pModelInfo->usTextureDictionary, pModelInfo->pRwObject, pModelInfo->bDoWeOwnTheColModel, pModelInfo->bCollisionWasStreamedWithModel, pStreamingInfo->flg, pStreamingInfo->offsetInBlocks, pStreamingInfo->sizeInBlocks, - pStreamingInfo->reqload); + pStreamingInfo->loadState); LogEvent(815, "Model collision missing", "CEntity_GetBoundRect", SString("No collision for model:%d %s", usModelId, *strDetails), 5415); CArgMap argMap; argMap.Set("id", usModelId); diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 1a488da7d3..88c8953c5b 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -46,5 +46,5 @@ class CStreaming virtual unsigned char AddStreamHandler(const char* szFilePath) = 0; virtual void RemoveStreamHandler(unsigned char dwStreamHandler) = 0; virtual CStreamingInfo* GetStreamingInfoFromModelId(unsigned int id) = 0; - virtual void SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1) = 0; + virtual void SetStreamingInfoForModelId(unsigned int id, unsigned char usStreamID, unsigned int uiOffset, unsigned short usSize, unsigned int uiNextInImg = -1) = 0; }; From ebf4cf1c7647a157f943decb48045e73170a94d0 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Thu, 15 Oct 2020 23:57:45 +0300 Subject: [PATCH 16/78] Add new IMG's to list --- Client/mods/deathmatch/logic/CClientIMG.cpp | 6 ++++++ Client/mods/deathmatch/logic/CClientIMG.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 3219251cb1..428a16659e 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -23,10 +23,16 @@ CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit m_pManager = pManager; m_ucArchiveID = -1; SetTypeName("img"); + + m_pImgManager = pManager->GetIMGManager(); + + m_pImgManager->AddToList(this); } CClientIMG::~CClientIMG() { + m_pImgManager->RemoveFromList(this); + if (m_ucArchiveID != -1) StreamDisable(); } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 08dc16a95a..2c3fae4c06 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -32,6 +32,7 @@ struct tLinkedModelRestoreInfo class CClientIMG : public CClientEntity { DECLARE_CLASS(CClientIMG, CClientEntity) + friend class CClientIMGManager; public: CClientIMG(class CClientManager* pManager, ElementID ID); ~CClientIMG(); @@ -53,6 +54,7 @@ class CClientIMG : public CClientEntity bool UnlinkModel(unsigned int usModelID); private: + class CClientIMGManager* m_pImgManager; SString m_strFilename; unsigned char m_ucArchiveID; From ae8185ce9b3931dbf9bcbbe96047187f3363115d Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 16 Oct 2020 21:14:36 +0300 Subject: [PATCH 17/78] Added CClientIMG::IsStreamed() --- Client/mods/deathmatch/logic/CClientIMG.cpp | 23 +++++++++++++++++---- Client/mods/deathmatch/logic/CClientIMG.h | 1 + 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 428a16659e..2fbc6c6a0d 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -33,8 +33,10 @@ CClientIMG::~CClientIMG() { m_pImgManager->RemoveFromList(this); - if (m_ucArchiveID != -1) + if (IsStreamed()) StreamDisable(); + + Unload(); } bool CClientIMG::Load(SString sFilePath) @@ -83,15 +85,20 @@ bool CClientIMG::Load(SString sFilePath) { fclose(pFile); m_pContentInfo.clear(); + m_uiFilesCount = 0; return false; } - //Stream(); - fclose(pFile); return true; } +bool CClientIMG::Unload() +{ + m_pContentInfo.clear(); + m_uiFilesCount = 0; +} + tImgFileInfo* CClientIMG::GetFileInfo(unsigned int usFileID) { if (usFileID > m_uiFilesCount) @@ -110,11 +117,19 @@ unsigned int CClientIMG::GetFileID(SString strFileName) return -1; } +bool CClientIMG::IsStreamed() +{ + return m_ucArchiveID != -1; +} + bool CClientIMG::StreamEnable() { if (!m_uiFilesCount) return false; + if (IsStreamed()) + return false; + m_pRestoreData.reserve(m_uiFilesCount); m_ucArchiveID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); return m_ucArchiveID != -1; @@ -122,7 +137,7 @@ bool CClientIMG::StreamEnable() bool CClientIMG::StreamDisable() { - if (m_ucArchiveID == -1) + if (!IsStreamed()) return false; for (unsigned int i = 0; i < m_pRestoreData.size(); i++ ) diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 2c3fae4c06..e1f4020113 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -50,6 +50,7 @@ class CClientIMG : public CClientEntity bool StreamEnable(); bool StreamDisable(); + bool IsStreamed(); bool LinkModel(unsigned int usModelID, unsigned int usFileID); bool UnlinkModel(unsigned int usModelID); From 646408182e4f8b8c85b01f24de840f388ff1be9b Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 16 Oct 2020 21:14:42 +0300 Subject: [PATCH 18/78] Fix typo --- Client/mods/deathmatch/logic/CClientIMG.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 2fbc6c6a0d..16543c4cdf 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -62,18 +62,18 @@ bool CClientIMG::Load(SString sFilePath) if (!pFile) return false; - tImgHeader filerHeader; + tImgHeader fileHeader; // Read header - int iReadCount = fread(&filerHeader, sizeof(filerHeader), 1, pFile); + int iReadCount = fread(&fileHeader, sizeof(fileHeader), 1, pFile); - if (!iReadCount || memcmp(&filerHeader.szMagic, "VER2", 4)) + if (!iReadCount || memcmp(&fileHeader.szMagic, "VER2", 4)) { fclose(pFile); return false; } - m_uiFilesCount = filerHeader.uiFilesCount; + m_uiFilesCount = fileHeader.uiFilesCount; // Read content info From 94a8ecd1f5da07df6fee1165431dbaf91e0c530b Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 16 Oct 2020 21:33:28 +0300 Subject: [PATCH 19/78] Added EngineAddImage and EngineRemoveImage --- Client/mods/deathmatch/logic/CClientIMG.cpp | 2 +- Client/mods/deathmatch/logic/CClientIMG.h | 2 +- .../logic/luadefs/CLuaEngineDefs.cpp | 44 ++++++++++++++++++- .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 2 + 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 16543c4cdf..20e8a51de8 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -93,7 +93,7 @@ bool CClientIMG::Load(SString sFilePath) return true; } -bool CClientIMG::Unload() +void CClientIMG::Unload() { m_pContentInfo.clear(); m_uiFilesCount = 0; diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index e1f4020113..9eba234356 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -44,7 +44,7 @@ class CClientIMG : public CClientEntity eClientEntityType GetType() const { return CCLIENTIMG; }; unsigned char GetArchiveID() { return m_ucArchiveID; }; bool Load(SString sFilePath); - bool Unload(); + void Unload(); tImgFileInfo* GetFileInfo(unsigned int usFileID); unsigned int GetFileID(SString sFileName); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 694bf473aa..4a223d6e14 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -51,7 +51,9 @@ void CLuaEngineDefs::LoadFunctions() {"engineRestoreModelPhysicalPropertiesGroup", EngineRestoreModelPhysicalPropertiesGroup}, {"engineSetObjectGroupPhysicalProperty", EngineSetObjectGroupPhysicalProperty}, {"engineGetObjectGroupPhysicalProperty", EngineGetObjectGroupPhysicalProperty}, - {"engineRestoreObjectGroupPhysicalProperties", EngineRestoreObjectGroupPhysicalProperties} + {"engineRestoreObjectGroupPhysicalProperties", EngineRestoreObjectGroupPhysicalProperties}, + {"engineAddImage", EngineAddImage}, + {"engineRemoveImage", EngineRemoveImage}, // CLuaCFunctions::AddFunction ( "engineReplaceMatchingAtomics", EngineReplaceMatchingAtomics ); // CLuaCFunctions::AddFunction ( "engineReplaceWheelAtomics", EngineReplaceWheelAtomics ); @@ -122,6 +124,8 @@ void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) lua_newclass(luaVM); lua_classfunction(luaVM, "create", "engineLoadIMG"); + lua_classfunction(luaVM, "add", "engineAddImage"); + lua_classfunction(luaVM, "remove", "engineRemoveImage"); } @@ -571,6 +575,44 @@ int CLuaEngineDefs::EngineImportTXD(lua_State* luaVM) return 1; } +int CLuaEngineDefs::EngineAddImage(lua_State* luaVM) +{ + CClientIMG* pIMG; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pIMG); + + if (!argStream.HasErrors()) + { + lua_pushboolean(luaVM, pIMG->StreamEnable()); + return 1; + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaEngineDefs::EngineRemoveImage(lua_State* luaVM) +{ + CClientIMG* pIMG; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pIMG); + + if (!argStream.HasErrors()) + { + lua_pushboolean(luaVM, pIMG->StreamDisable()); + return 1; + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) { unsigned short usModelID; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index fb3ca82a03..d5fa1f156a 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -62,6 +62,8 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineSetObjectGroupPhysicalProperty) LUA_DECLARE(EngineGetObjectGroupPhysicalProperty) LUA_DECLARE(EngineRestoreObjectGroupPhysicalProperties) + LUA_DECLARE(EngineAddImage) + LUA_DECLARE(EngineRemoveImage) private: static void AddEngineColClass(lua_State* luaVM); From 4de39c857fbd315b17ab96814e10b2803e89162e Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 16 Oct 2020 22:10:02 +0300 Subject: [PATCH 20/78] Added EngineImageGetFilesCount and EngineImageGetFileList --- Client/mods/deathmatch/logic/CClientIMG.h | 3 +- .../logic/luadefs/CLuaEngineDefs.cpp | 55 +++++++++++++++++++ .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 2 + 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 9eba234356..5f11637ab7 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -43,9 +43,10 @@ class CClientIMG : public CClientEntity eClientEntityType GetType() const { return CCLIENTIMG; }; unsigned char GetArchiveID() { return m_ucArchiveID; }; + unsigned int GetFilesCount() { return m_uiFilesCount; }; bool Load(SString sFilePath); void Unload(); - tImgFileInfo* GetFileInfo(unsigned int usFileID); + tImgFileInfo* GetFileInfo(unsigned int uiFileID); unsigned int GetFileID(SString sFileName); bool StreamEnable(); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 4a223d6e14..ad972de5fd 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -54,6 +54,8 @@ void CLuaEngineDefs::LoadFunctions() {"engineRestoreObjectGroupPhysicalProperties", EngineRestoreObjectGroupPhysicalProperties}, {"engineAddImage", EngineAddImage}, {"engineRemoveImage", EngineRemoveImage}, + {"engineImageGetFilesCount", EngineImageGetFilesCount}, + {"engineImageGetFileList", EngineImageGetFileList} // CLuaCFunctions::AddFunction ( "engineReplaceMatchingAtomics", EngineReplaceMatchingAtomics ); // CLuaCFunctions::AddFunction ( "engineReplaceWheelAtomics", EngineReplaceWheelAtomics ); @@ -126,6 +128,10 @@ void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) lua_classfunction(luaVM, "create", "engineLoadIMG"); lua_classfunction(luaVM, "add", "engineAddImage"); lua_classfunction(luaVM, "remove", "engineRemoveImage"); + + lua_classvariable(luaVM, "filesCount", nullptr, EngineImageGetFilesCount); + + lua_registerclass(luaVM, "EngineIMG", "Element"); } @@ -613,6 +619,55 @@ int CLuaEngineDefs::EngineRemoveImage(lua_State* luaVM) return 1; } +int CLuaEngineDefs::EngineImageGetFilesCount(lua_State* luaVM) +{ + CClientIMG* pIMG; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pIMG); + + if (!argStream.HasErrors()) + { + lua_pushnumber(luaVM, pIMG->GetFilesCount()); + return 1; + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + +int CLuaEngineDefs::EngineImageGetFileList(lua_State* luaVM) +{ + CClientIMG* pIMG; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pIMG); + + if (!argStream.HasErrors()) + { + lua_newtable(luaVM); + + for (unsigned int i = 0; i < pIMG->GetFilesCount(); i++) + { + tImgFileInfo* pFileInfo = pIMG->GetFileInfo(i); + + lua_pushnumber(luaVM, i); + lua_pushstring(luaVM, pFileInfo->szFileName); + lua_settable(luaVM, -3); + } + + return 1; + } + if (argStream.HasErrors()) + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + lua_pushboolean(luaVM, false); + return 1; +} + + int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) { unsigned short usModelID; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index d5fa1f156a..2483d6f88f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -64,6 +64,8 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineRestoreObjectGroupPhysicalProperties) LUA_DECLARE(EngineAddImage) LUA_DECLARE(EngineRemoveImage) + LUA_DECLARE(EngineImageGetFilesCount) + LUA_DECLARE(EngineImageGetFileList) private: static void AddEngineColClass(lua_State* luaVM); From f5a773aa48114002b271e90d091f955a73107d5d Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 00:24:13 +0300 Subject: [PATCH 21/78] Added img:getFile --- Client/mods/deathmatch/logic/CClientIMG.cpp | 56 ++++++++++++----- Client/mods/deathmatch/logic/CClientIMG.h | 2 + .../logic/luadefs/CLuaEngineDefs.cpp | 62 +++++++++++++++++-- .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 1 + 4 files changed, 101 insertions(+), 20 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 20e8a51de8..d47d72f21e 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -10,6 +10,8 @@ #include +#define INVALID_ARCHIVE_ID 0xFF + struct tImgHeader { char szMagic[4]; @@ -21,7 +23,8 @@ CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit // Init m_uiFilesCount = 0; m_pManager = pManager; - m_ucArchiveID = -1; + m_ucArchiveID = INVALID_ARCHIVE_ID; + m_pFile = nullptr; SetTypeName("img"); m_pImgManager = pManager->GetIMGManager(); @@ -58,18 +61,18 @@ bool CClientIMG::Load(SString sFilePath) */ // Open the file - FILE* pFile = File::Fopen(m_strFilename, "rb"); - if (!pFile) + m_pFile = File::Fopen(m_strFilename, "rb"); + if (!m_pFile) return false; tImgHeader fileHeader; // Read header - int iReadCount = fread(&fileHeader, sizeof(fileHeader), 1, pFile); + int iReadCount = fread(&fileHeader, sizeof(fileHeader), 1, m_pFile); if (!iReadCount || memcmp(&fileHeader.szMagic, "VER2", 4)) { - fclose(pFile); + fclose(m_pFile); return false; } @@ -79,17 +82,14 @@ bool CClientIMG::Load(SString sFilePath) m_pContentInfo.resize(m_uiFilesCount); - iReadCount = fread(&m_pContentInfo.at(0), sizeof(tImgFileInfo), m_uiFilesCount, pFile); + iReadCount = fread(&m_pContentInfo.at(0), sizeof(tImgFileInfo), m_uiFilesCount, m_pFile); if (iReadCount != m_uiFilesCount) { - fclose(pFile); - m_pContentInfo.clear(); - m_uiFilesCount = 0; + Unload(); return false; } - fclose(pFile); return true; } @@ -97,6 +97,34 @@ void CClientIMG::Unload() { m_pContentInfo.clear(); m_uiFilesCount = 0; + + if (m_pFile) + { + fclose(m_pFile); + m_pFile = nullptr; + } +} + +long CClientIMG::GetFile(unsigned int uiFileID, SString& buffer) +{ + tImgFileInfo* pFileInfo = GetFileInfo(uiFileID); + if (!pFileInfo) + return -1; + + unsigned long ulReadCount = pFileInfo->usSize * 2048; + + try + { + buffer.resize(ulReadCount); + } + catch (const std::bad_alloc&) + { + return -2; + } + + long iReadCount = fread(buffer.data(), 1, ulReadCount, m_pFile); + + return iReadCount; } tImgFileInfo* CClientIMG::GetFileInfo(unsigned int usFileID) @@ -119,7 +147,7 @@ unsigned int CClientIMG::GetFileID(SString strFileName) bool CClientIMG::IsStreamed() { - return m_ucArchiveID != -1; + return m_ucArchiveID != INVALID_ARCHIVE_ID; } bool CClientIMG::StreamEnable() @@ -132,7 +160,7 @@ bool CClientIMG::StreamEnable() m_pRestoreData.reserve(m_uiFilesCount); m_ucArchiveID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); - return m_ucArchiveID != -1; + return IsStreamed(); } bool CClientIMG::StreamDisable() @@ -154,13 +182,13 @@ bool CClientIMG::StreamDisable() m_pRestoreData.clear(); g_pGame->GetStreaming()->RemoveStreamHandler(m_ucArchiveID); - m_ucArchiveID = -1; + m_ucArchiveID = INVALID_ARCHIVE_ID; return true; } bool CClientIMG::LinkModel(unsigned int uiModelID, unsigned int uiFileID) { - if (m_ucArchiveID == -1) + if (!IsStreamed()) return false; if (uiFileID >= m_uiFilesCount) diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 5f11637ab7..f1d3495c3e 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -48,6 +48,7 @@ class CClientIMG : public CClientEntity void Unload(); tImgFileInfo* GetFileInfo(unsigned int uiFileID); unsigned int GetFileID(SString sFileName); + long GetFile(unsigned int uiFileID, SString& buffer); bool StreamEnable(); bool StreamDisable(); @@ -59,6 +60,7 @@ class CClientIMG : public CClientEntity class CClientIMGManager* m_pImgManager; SString m_strFilename; + FILE* m_pFile; unsigned char m_ucArchiveID; unsigned int m_uiFilesCount; std::vector m_pContentInfo; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index ad972de5fd..6109c042c1 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -15,7 +15,6 @@ void CLuaEngineDefs::LoadFunctions() { constexpr static const std::pair functions[]{ {"engineFreeModel", EngineFreeModel}, - {"engineLoadIMG", EngineLoadIMG}, {"engineLoadTXD", EngineLoadTXD}, {"engineLoadCOL", EngineLoadCOL}, {"engineLoadDFF", EngineLoadDFF}, @@ -23,8 +22,6 @@ void CLuaEngineDefs::LoadFunctions() {"engineImportTXD", EngineImportTXD}, {"engineReplaceCOL", EngineReplaceCOL}, {"engineRestoreCOL", EngineRestoreCOL}, - {"engineSetModelIMG", EngineSetModelIMG}, - {"engineRestoreModelIMG", EngineRestoreModelIMG}, {"engineReplaceModel", EngineReplaceModel}, {"engineRestoreModel", EngineRestoreModel}, {"engineReplaceAnimation", EngineReplaceAnimation}, @@ -36,8 +33,6 @@ void CLuaEngineDefs::LoadFunctions() {"engineSetAsynchronousLoading", EngineSetAsynchronousLoading}, {"engineApplyShaderToWorldTexture", EngineApplyShaderToWorldTexture}, {"engineRemoveShaderFromWorldTexture", EngineRemoveShaderFromWorldTexture}, - {"engineGetModelTXDID", EngineGetModelTXDID}, - {"engineSetModelTXDID", EngineSetModelTXDID}, {"engineGetModelNameFromID", EngineGetModelNameFromID}, {"engineGetModelIDFromName", EngineGetModelIDFromName}, {"engineGetModelTextureNames", EngineGetModelTextureNames}, @@ -52,10 +47,16 @@ void CLuaEngineDefs::LoadFunctions() {"engineSetObjectGroupPhysicalProperty", EngineSetObjectGroupPhysicalProperty}, {"engineGetObjectGroupPhysicalProperty", EngineGetObjectGroupPhysicalProperty}, {"engineRestoreObjectGroupPhysicalProperties", EngineRestoreObjectGroupPhysicalProperties}, + {"engineLoadIMG", EngineLoadIMG}, + {"engineSetModelIMG", EngineSetModelIMG}, + {"engineRestoreModelIMG", EngineRestoreModelIMG}, {"engineAddImage", EngineAddImage}, {"engineRemoveImage", EngineRemoveImage}, {"engineImageGetFilesCount", EngineImageGetFilesCount}, - {"engineImageGetFileList", EngineImageGetFileList} + {"engineImageGetFileList", EngineImageGetFileList}, + {"engineImageGetFile", EngineImageGetFile}, + {"engineGetModelTXDID", EngineGetModelTXDID}, + {"engineSetModelTXDID", EngineSetModelTXDID}, // CLuaCFunctions::AddFunction ( "engineReplaceMatchingAtomics", EngineReplaceMatchingAtomics ); // CLuaCFunctions::AddFunction ( "engineReplaceWheelAtomics", EngineReplaceWheelAtomics ); @@ -98,6 +99,7 @@ void CLuaEngineDefs::AddClass(lua_State* luaVM) AddEngineColClass(luaVM); AddEngineTxdClass(luaVM); AddEngineDffClass(luaVM); + AddEngineImgClass(luaVM); } void CLuaEngineDefs::AddEngineColClass(lua_State* luaVM) @@ -128,8 +130,10 @@ void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) lua_classfunction(luaVM, "create", "engineLoadIMG"); lua_classfunction(luaVM, "add", "engineAddImage"); lua_classfunction(luaVM, "remove", "engineRemoveImage"); + lua_classfunction(luaVM, "getFile", "engineImageGetFile"); lua_classvariable(luaVM, "filesCount", nullptr, EngineImageGetFilesCount); + lua_classvariable(luaVM, "files", nullptr, EngineImageGetFileList); lua_registerclass(luaVM, "EngineIMG", "Element"); } @@ -667,6 +671,52 @@ int CLuaEngineDefs::EngineImageGetFileList(lua_State* luaVM) return 1; } +int CLuaEngineDefs::EngineImageGetFile(lua_State* luaVM) +{ + CClientIMG* pIMG; + unsigned int fileID = -1; + SString strFileName; + + CScriptArgReader argStream(luaVM); + argStream.ReadUserData(pIMG); + + if (argStream.NextIsNumber()) + argStream.ReadNumber(fileID); + else + argStream.ReadString(strFileName); + + if (!argStream.HasErrors()) + { + if (fileID == -1) + fileID = pIMG->GetFileID(strFileName); + + SString buffer; + long lBytesRead = pIMG->GetFile(fileID, buffer); + + if (lBytesRead >= 0) + { + // Push the string onto the Lua stack. Use pushlstring so we are binary + // compatible. Normal push string takes zero terminated strings. + lua_pushlstring(luaVM, buffer.data(), lBytesRead); + return 1; + } + else if (lBytesRead == -2) + { + m_pScriptDebugging->LogWarning(luaVM, "out of memory"); + } + else + { + argStream.SetCustomWarning("File not found"); + } + } + else + m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + + // Error + lua_pushnil(luaVM); + return 1; +} + int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) { diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 2483d6f88f..0085d6a43d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -66,6 +66,7 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineRemoveImage) LUA_DECLARE(EngineImageGetFilesCount) LUA_DECLARE(EngineImageGetFileList) + LUA_DECLARE(EngineImageGetFile) private: static void AddEngineColClass(lua_State* luaVM); From d41e4918125f7652fdfc8a278a057d3a51edad24 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 00:34:03 +0300 Subject: [PATCH 22/78] Fix CClientIMG::GetFileID() --- Client/mods/deathmatch/logic/CClientIMG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index d47d72f21e..a6fb882e0c 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -139,7 +139,7 @@ unsigned int CClientIMG::GetFileID(SString strFileName) strFileName.resize(24); for (unsigned int i = 0; i < m_uiFilesCount; i++) { - if (strFileName.compare(m_pContentInfo[i].szFileName)) + if (strFileName.EqualsI(m_pContentInfo[i].szFileName)) return i; } return -1; From d7f69ebf83048c52c5736bf016e0e7164cf58837 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 01:12:24 +0300 Subject: [PATCH 23/78] Disable engineSetModelTXDID function --- .../logic/luadefs/CLuaEngineDefs.cpp | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 6109c042c1..8a91d5a1a4 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -56,7 +56,7 @@ void CLuaEngineDefs::LoadFunctions() {"engineImageGetFileList", EngineImageGetFileList}, {"engineImageGetFile", EngineImageGetFile}, {"engineGetModelTXDID", EngineGetModelTXDID}, - {"engineSetModelTXDID", EngineSetModelTXDID}, + //{"engineSetModelTXDID", EngineSetModelTXDID}, // CLuaCFunctions::AddFunction ( "engineReplaceMatchingAtomics", EngineReplaceMatchingAtomics ); // CLuaCFunctions::AddFunction ( "engineReplaceWheelAtomics", EngineReplaceWheelAtomics ); @@ -1277,32 +1277,32 @@ int CLuaEngineDefs::EngineGetModelTXDID(lua_State* luaVM) } -int CLuaEngineDefs::EngineSetModelTXDID(lua_State* luaVM) -{ - unsigned short usModelID; - unsigned short usTXDID; - - CScriptArgReader argStream(luaVM); - argStream.ReadNumber(usModelID); - argStream.ReadNumber(usTXDID); - - if (!argStream.HasErrors()) - { - bool bResult = g_pGame->GetRenderWare()->SetTXDIDForModelID(usModelID, usTXDID); - if (bResult) - { - lua_pushboolean(luaVM, bResult); - return 1; - } - argStream.SetCustomError("Expected valid model ID at argument 1"); - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // We failed - lua_pushboolean(luaVM, false); - return 1; -} +//int CLuaEngineDefs::EngineSetModelTXDID(lua_State* luaVM) +//{ +// unsigned short usModelID; +// unsigned short usTXDID; +// +// CScriptArgReader argStream(luaVM); +// argStream.ReadNumber(usModelID); +// argStream.ReadNumber(usTXDID); +// +// if (!argStream.HasErrors()) +// { +// bool bResult = g_pGame->GetRenderWare()->SetTXDIDForModelID(usModelID, usTXDID); +// if (bResult) +// { +// lua_pushboolean(luaVM, bResult); +// return 1; +// } +// argStream.SetCustomError("Expected valid model ID at argument 1"); +// } +// if (argStream.HasErrors()) +// m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); +// +// // We failed +// lua_pushboolean(luaVM, false); +// return 1; +//} int CLuaEngineDefs::EngineGetModelNameFromID(lua_State* luaVM) { From 7d26e07657e572bd3ebd840bbbe9fd3116d261ff Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 01:45:30 +0300 Subject: [PATCH 24/78] Small API changes --- .../mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 11 +++++------ Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 8a91d5a1a4..10c62d5a9d 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -48,8 +48,8 @@ void CLuaEngineDefs::LoadFunctions() {"engineGetObjectGroupPhysicalProperty", EngineGetObjectGroupPhysicalProperty}, {"engineRestoreObjectGroupPhysicalProperties", EngineRestoreObjectGroupPhysicalProperties}, {"engineLoadIMG", EngineLoadIMG}, - {"engineSetModelIMG", EngineSetModelIMG}, - {"engineRestoreModelIMG", EngineRestoreModelIMG}, + {"engineSetModelIMG", EngineImageLinkModel}, + {"engineRestoreModelIMG", EngineRestoreModelImage}, {"engineAddImage", EngineAddImage}, {"engineRemoveImage", EngineRemoveImage}, {"engineImageGetFilesCount", EngineImageGetFilesCount}, @@ -718,7 +718,7 @@ int CLuaEngineDefs::EngineImageGetFile(lua_State* luaVM) } -int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) +int CLuaEngineDefs::EngineImageLinkModel(lua_State* luaVM) { unsigned short usModelID; CClientIMG* pIMG; @@ -726,13 +726,12 @@ int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) SString strFileName; CScriptArgReader argStream(luaVM); - argStream.ReadNumber(usModelID); argStream.ReadUserData(pIMG); - if (argStream.NextIsNumber()) argStream.ReadNumber(fileID); else argStream.ReadString(strFileName); + argStream.ReadNumber(usModelID); if (!argStream.HasErrors()) { @@ -754,7 +753,7 @@ int CLuaEngineDefs::EngineSetModelIMG(lua_State* luaVM) return 1; } -int CLuaEngineDefs::EngineRestoreModelIMG(lua_State* luaVM) +int CLuaEngineDefs::EngineRestoreModelImage(lua_State* luaVM) { // Grab the model ID unsigned int uiModelID = CModelNames::ResolveModelID(lua_tostring(luaVM, 1)); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 0085d6a43d..97f7ab7269 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -26,8 +26,6 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineImportTXD); LUA_DECLARE(EngineReplaceCOL); LUA_DECLARE(EngineRestoreCOL); - LUA_DECLARE(EngineSetModelIMG); - LUA_DECLARE(EngineRestoreModelIMG); LUA_DECLARE(EngineReplaceModel); LUA_DECLARE(EngineRestoreModel); LUA_DECLARE(EngineRequestModel); @@ -67,6 +65,8 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineImageGetFilesCount) LUA_DECLARE(EngineImageGetFileList) LUA_DECLARE(EngineImageGetFile) + LUA_DECLARE(EngineImageLinkModel); + LUA_DECLARE(EngineRestoreModelImage); private: static void AddEngineColClass(lua_State* luaVM); From 4d63000f997c65400e4e1a65502f7e9af9f373e7 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 01:48:40 +0300 Subject: [PATCH 25/78] Added img:linkModel() --- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 10c62d5a9d..91a0b32c9e 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -48,8 +48,8 @@ void CLuaEngineDefs::LoadFunctions() {"engineGetObjectGroupPhysicalProperty", EngineGetObjectGroupPhysicalProperty}, {"engineRestoreObjectGroupPhysicalProperties", EngineRestoreObjectGroupPhysicalProperties}, {"engineLoadIMG", EngineLoadIMG}, - {"engineSetModelIMG", EngineImageLinkModel}, - {"engineRestoreModelIMG", EngineRestoreModelImage}, + {"engineImageLinkModel", EngineImageLinkModel}, + {"engineRestoreModelImage", EngineRestoreModelImage}, {"engineAddImage", EngineAddImage}, {"engineRemoveImage", EngineRemoveImage}, {"engineImageGetFilesCount", EngineImageGetFilesCount}, @@ -131,6 +131,7 @@ void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) lua_classfunction(luaVM, "add", "engineAddImage"); lua_classfunction(luaVM, "remove", "engineRemoveImage"); lua_classfunction(luaVM, "getFile", "engineImageGetFile"); + lua_classfunction(luaVM, "linkModel", "engineImageLinkModel"); lua_classvariable(luaVM, "filesCount", nullptr, EngineImageGetFilesCount); lua_classvariable(luaVM, "files", nullptr, EngineImageGetFileList); From fe0908c851de2eeb4d0467a7ea32a919fff29821 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 02:19:13 +0300 Subject: [PATCH 26/78] Fix missing API --- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 91a0b32c9e..4c34718963 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -80,6 +80,7 @@ void CLuaEngineDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setAsynchronousLoading", "engineSetAsynchronousLoading"); lua_classfunction(luaVM, "setModelLODDistance", "engineSetModelLODDistance"); lua_classfunction(luaVM, "resetModelLODDistance", "engineResetModelLODDistance"); + lua_classfunction(luaVM, "restoreModelImage", "engineRestoreModelImage"); lua_classfunction(luaVM, "getVisibleTextureNames", "engineGetVisibleTextureNames"); lua_classfunction(luaVM, "getModelLODDistance", "engineGetModelLODDistance"); @@ -131,6 +132,8 @@ void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) lua_classfunction(luaVM, "add", "engineAddImage"); lua_classfunction(luaVM, "remove", "engineRemoveImage"); lua_classfunction(luaVM, "getFile", "engineImageGetFile"); + lua_classfunction(luaVM, "getFileList", "engineImageGetFileList"); + lua_classfunction(luaVM, "getFilesCount", "engineImageGetFilesCount"); lua_classfunction(luaVM, "linkModel", "engineImageLinkModel"); lua_classvariable(luaVM, "filesCount", nullptr, EngineImageGetFilesCount); From aff0a1a40779e10cb27b9cd8716b404017d3f915 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 09:52:11 +0300 Subject: [PATCH 27/78] Refactor some code --- Client/game_sa/CStreamingSA.cpp | 58 +++++++++------------ Client/game_sa/CStreamingSA.h | 17 +++--- Client/mods/deathmatch/logic/CClientIMG.cpp | 4 +- Client/sdk/game/CStreaming.h | 4 +- 4 files changed, 40 insertions(+), 43 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 90ed4cef74..4e0d64a8fd 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -12,6 +12,10 @@ #include "StdInc.h" #include "Fileapi.h" +CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo(*)[26316])0x8E4CC0; +HANDLE (&CStreamingSA::m_aStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; +CArchiveInfo (&CStreamingSA::ms_aAchiveInfo)[8] = *(CArchiveInfo(*)[8])ARRAY_StreamHandlersInfo; + namespace { // @@ -143,40 +147,23 @@ void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, pItemInfo->offsetInBlocks = uiOffset; pItemInfo->sizeInBlocks = usSize; pItemInfo->nextInImg = uiNextInImg; -} - -CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) -{ - CStreamingInfo* pItemInfo = (CStreamingInfo*)(ARRAY_StreamModelInfo); - return pItemInfo + id; -} - -bool CStreamingSA::SetModelStreamInfo(ushort id, uchar ucArchiveId, ushort usOffestInBlocks, ushort usSizeInBlocks) -{ - CStreamingInfo* pItemInfo = GetStreamingInfoFromModelId(id); - pItemInfo->archiveId = ucArchiveId; - pItemInfo->offsetInBlocks = usOffestInBlocks; - pItemInfo->sizeInBlocks = usSizeInBlocks; // TODO CHANGE THIS INFO FOR PREV MODEL pItemInfo->nextInImg = -1; - return true; } -CStreamHandlerInfo* CStreamingSA::GetStreamingHandlerInfo(uint id) +CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) { - CStreamHandlerInfo* pHandlerInfo = (CStreamHandlerInfo*)(ARRAY_StreamHandlersInfo); - return pHandlerInfo + id; + return &ms_aInfoForModel[id]; } - -unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) +unsigned char CStreamingSA::AddArchive(const char* szFilePath) { // Get internal IMG id - // By default gta sa has 8 IMG archives - uchar ucArchiveId = 0; - for (int i = 0; i < 8; i++) + // By default gta sa uses 5 of 8 IMG archives + uchar ucArchiveId = -1; + for (int i = 6; i < 8; i++) { - CStreamHandlerInfo* info = GetStreamingHandlerInfo(i); + CArchiveInfo* info = GetArchiveInfo(i); if (!info->uiStreamHandleId) { ucArchiveId = i; @@ -184,7 +171,7 @@ unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) } } - if (ucArchiveId == 0) + if (ucArchiveId == -1) return -1; // Get free stream handler id @@ -193,7 +180,7 @@ unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) for (unsigned char ID = 0; ID < VAR_StreamHandlersMaxCount; ++ID) { - HANDLE hFile = *(HANDLE*)(ARRAY_StreamHandlers + (ID * sizeof(HANDLE))); + HANDLE hFile = m_aStreamingHandlers[ID]; if (!hFile) { ucStreamID = ID; @@ -213,17 +200,24 @@ unsigned char CStreamingSA::AddStreamHandler(const char* szFilePath) return -1; // Register stream handler - void* streamHandlerPos = (void*)(ARRAY_StreamHandlers + ucStreamID * sizeof(HANDLE)); - MemPutFast(streamHandlerPos, hFile); + m_aStreamingHandlers[ucStreamID] = hFile; // Register archive data - CStreamHandlerInfo* pNewArchiveInfo = GetStreamingHandlerInfo(ucArchiveId); - pNewArchiveInfo->uiStreamHandleId = (ucStreamID << 24); + GetArchiveInfo(ucArchiveId)->uiStreamHandleId = (ucStreamID << 24); return ucArchiveId; } -void CStreamingSA::RemoveStreamHandler(unsigned char ucArhiveID) +void CStreamingSA::RemoveArchive(unsigned char ucArhiveID) { - return; + CArchiveInfo* pArchiveInfo = GetArchiveInfo(ucArhiveID); + + unsigned int uiStreamHandlerID = pArchiveInfo->uiStreamHandleId; + if (!uiStreamHandlerID) + return; + + pArchiveInfo->uiStreamHandleId = 0; + + CloseHandle(m_aStreamingHandlers[uiStreamHandlerID]); + m_aStreamingHandlers[uiStreamHandlerID] = NULL; } diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 61f90fd661..103ced4638 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -13,10 +13,8 @@ #include #include "Common.h" -#include "Fileapi.h" // Shoud be changed to interfaces -#define ARRAY_StreamHandlers 0x8E4010 // [32] #define ARRAY_StreamHandlersNames 0x8E4098 // [32][64] #define ARRAY_StreamHandlersInfo 0x8E48D8 // [8][0x30] @@ -25,6 +23,7 @@ #define VAR_StreamHandlersMaxCount 32 #define VAR_StreamHandlerCreateFlags 0x8E3FE0 #define VAR_StreamHandlersMaxCount 32 +#define VAR_MaxArchives 8 #define FUNC_CStreaming__RequestModel 0x4087E0 #define FUNC_LoadAllRequestedModels 0x40EA10 @@ -37,7 +36,7 @@ #define FUNC_CStreaming_RemoveImages 0x4066B3 // Remove all IMG`s from streaming #define FUNC_CStreaming_RemoveImage 0x4068A0 -struct CStreamHandlerInfo +struct CArchiveInfo { char szName[40]; BYTE bUnknow = 1; // Only in player.img is 0. Maybe, it is DWORD value @@ -49,9 +48,8 @@ struct CStreamHandlerInfo class CStreamingSA : public CStreaming { private: - CStreamHandlerInfo* GetStreamingHandlerInfo(uint id); + static CArchiveInfo* GetArchiveInfo(uint id) { return ms_aAchiveInfo[id]; }; public: - bool SetModelStreamInfo(ushort id, uchar ucArchiveId, ushort usOffestInBlocks, ushort usSizeInBlocks); void RequestModel(DWORD dwModelID, DWORD dwFlags); void LoadAllRequestedModels(BOOL bOnlyPriorityModels = 0, const char* szTag = NULL); BOOL HasModelLoaded(DWORD dwModelID); @@ -59,6 +57,11 @@ class CStreamingSA : public CStreaming void SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1); CStreamingInfo* GetStreamingInfoFromModelId(uint id); - unsigned char AddStreamHandler(const char* szFilePath); - void RemoveStreamHandler(unsigned char ucStreamHandler); + unsigned char AddArchive(const char* szFilePath); + void RemoveArchive(unsigned char ucStreamHandler); + +private: + static CStreamingInfo (&ms_aInfoForModel)[26316]; + static HANDLE (&m_aStreamingHandlers)[32]; + static CArchiveInfo (&ms_aAchiveInfo)[8]; }; diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index a6fb882e0c..babddf4e9a 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -159,7 +159,7 @@ bool CClientIMG::StreamEnable() return false; m_pRestoreData.reserve(m_uiFilesCount); - m_ucArchiveID = g_pGame->GetStreaming()->AddStreamHandler(*m_strFilename); + m_ucArchiveID = g_pGame->GetStreaming()->AddArchive(*m_strFilename); return IsStreamed(); } @@ -181,7 +181,7 @@ bool CClientIMG::StreamDisable() m_pRestoreData.clear(); - g_pGame->GetStreaming()->RemoveStreamHandler(m_ucArchiveID); + g_pGame->GetStreaming()->RemoveArchive(m_ucArchiveID); m_ucArchiveID = INVALID_ARCHIVE_ID; return true; } diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 88c8953c5b..ab0c87718c 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -43,8 +43,8 @@ class CStreaming virtual void LoadAllRequestedModels(BOOL bOnlyPriorityModels = 0, const char* szTag = NULL) = 0; virtual BOOL HasModelLoaded(DWORD dwModelID) = 0; virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; - virtual unsigned char AddStreamHandler(const char* szFilePath) = 0; - virtual void RemoveStreamHandler(unsigned char dwStreamHandler) = 0; + virtual unsigned char AddArchive(const char* szFilePath) = 0; + virtual void RemoveArchive(unsigned char ucArchiveID) = 0; virtual CStreamingInfo* GetStreamingInfoFromModelId(unsigned int id) = 0; virtual void SetStreamingInfoForModelId(unsigned int id, unsigned char usStreamID, unsigned int uiOffset, unsigned short usSize, unsigned int uiNextInImg = -1) = 0; }; From d65d28f807a92eadbd329cbd74eb93edb1205262 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 10:06:07 +0300 Subject: [PATCH 28/78] Fix build --- Client/game_sa/CStreamingSA.cpp | 1 - Client/game_sa/CStreamingSA.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 4e0d64a8fd..43d9d5796a 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -148,7 +148,6 @@ void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, pItemInfo->sizeInBlocks = usSize; pItemInfo->nextInImg = uiNextInImg; // TODO CHANGE THIS INFO FOR PREV MODEL - pItemInfo->nextInImg = -1; } CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 103ced4638..f861c27836 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -48,7 +48,7 @@ struct CArchiveInfo class CStreamingSA : public CStreaming { private: - static CArchiveInfo* GetArchiveInfo(uint id) { return ms_aAchiveInfo[id]; }; + static CArchiveInfo* GetArchiveInfo(uint id) { return &ms_aAchiveInfo[id]; }; public: void RequestModel(DWORD dwModelID, DWORD dwFlags); void LoadAllRequestedModels(BOOL bOnlyPriorityModels = 0, const char* szTag = NULL); From 5f99829a170b81c72ea76cc2764f6088533118ef Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 23:10:05 +0300 Subject: [PATCH 29/78] Refactor CStreamingSA --- Client/game_sa/CStreamingSA.cpp | 25 +++++++++++++++++-------- Client/game_sa/CStreamingSA.h | 1 - 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 43d9d5796a..e63766f93a 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -13,8 +13,8 @@ #include "Fileapi.h" CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo(*)[26316])0x8E4CC0; -HANDLE (&CStreamingSA::m_aStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; -CArchiveInfo (&CStreamingSA::ms_aAchiveInfo)[8] = *(CArchiveInfo(*)[8])ARRAY_StreamHandlersInfo; +HANDLE (&CStreamingSA::m_aStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; // Contains open files +CArchiveInfo (&CStreamingSA::ms_aAchiveInfo)[8] = *(CArchiveInfo(*)[8])0x8E48D8; // [8][0x30] namespace { @@ -143,11 +143,22 @@ void CStreamingSA::RequestSpecialModel(DWORD model, const char* szTexture, DWORD void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg) { CStreamingInfo* pItemInfo = GetStreamingInfoFromModelId(id); + + // Change nextInImg filed for prev model + for ( unsigned int i = 0; i < 26316; i++) + { + if (ms_aInfoForModel[i].archiveId == pItemInfo->archiveId && + (ms_aInfoForModel[i].offsetInBlocks + ms_aInfoForModel[i].sizeInBlocks) == pItemInfo->offsetInBlocks) + { + ms_aInfoForModel[i].nextInImg = -1; + break; + } + } + pItemInfo->archiveId = usStreamID; pItemInfo->offsetInBlocks = uiOffset; pItemInfo->sizeInBlocks = usSize; pItemInfo->nextInImg = uiNextInImg; - // TODO CHANGE THIS INFO FOR PREV MODEL } CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) @@ -202,20 +213,18 @@ unsigned char CStreamingSA::AddArchive(const char* szFilePath) m_aStreamingHandlers[ucStreamID] = hFile; // Register archive data - GetArchiveInfo(ucArchiveId)->uiStreamHandleId = (ucStreamID << 24); + ms_aAchiveInfo[ucArchiveId].uiStreamHandleId = (ucStreamID << 24); return ucArchiveId; } void CStreamingSA::RemoveArchive(unsigned char ucArhiveID) { - CArchiveInfo* pArchiveInfo = GetArchiveInfo(ucArhiveID); - - unsigned int uiStreamHandlerID = pArchiveInfo->uiStreamHandleId; + unsigned int uiStreamHandlerID = ms_aAchiveInfo[ucArhiveID].uiStreamHandleId; if (!uiStreamHandlerID) return; - pArchiveInfo->uiStreamHandleId = 0; + ms_aAchiveInfo[ucArhiveID].uiStreamHandleId = 0; CloseHandle(m_aStreamingHandlers[uiStreamHandlerID]); m_aStreamingHandlers[uiStreamHandlerID] = NULL; diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index f861c27836..f065d4e698 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -16,7 +16,6 @@ // Shoud be changed to interfaces #define ARRAY_StreamHandlersNames 0x8E4098 // [32][64] -#define ARRAY_StreamHandlersInfo 0x8E48D8 // [8][0x30] #define ARRAY_StreamModelInfo 0x8E4CC0 // size = 26316 From 42097a7c2a89e2ca6308f51c447e7e60ad602767 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 23:14:42 +0300 Subject: [PATCH 30/78] Fix comment --- Client/game_sa/CStreamingSA.cpp | 2 +- Client/mods/deathmatch/logic/CClientIMG.cpp | 2 +- Client/mods/deathmatch/logic/CClientIMG.h | 2 +- Client/mods/deathmatch/logic/CClientIMGManager.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index e63766f93a..47690513e6 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -169,7 +169,7 @@ CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) unsigned char CStreamingSA::AddArchive(const char* szFilePath) { // Get internal IMG id - // By default gta sa uses 5 of 8 IMG archives + // By default gta sa uses 6 of 8 IMG archives uchar ucArchiveId = -1; for (int i = 6; i < 8; i++) { diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index babddf4e9a..d1adb4a54d 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -4,7 +4,7 @@ * (Shared logic for modifications) * LICENSE: See LICENSE in the top level directory * FILE: mods/shared_logic/CClientIMG.cpp - * PURPOSE: IMG manager class + * PURPOSE: IMG container class * *****************************************************************************/ diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index f1d3495c3e..f2dff9d1a7 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -4,7 +4,7 @@ * (Shared logic for modifications) * LICENSE: See LICENSE in the top level directory * FILE: mods/shared_logic/CClientIMG.h -* PURPOSE: IMG manager class header +* PURPOSE: IMG container class header * *****************************************************************************/ diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.h b/Client/mods/deathmatch/logic/CClientIMGManager.h index 3af4cad7b5..a32de1562d 100644 --- a/Client/mods/deathmatch/logic/CClientIMGManager.h +++ b/Client/mods/deathmatch/logic/CClientIMGManager.h @@ -4,7 +4,7 @@ * (Shared logic for modifications) * LICENSE: See LICENSE in the top level directory * FILE: mods/shared_logic/CClientIMGManager.h - * PURPOSE: .img container odel manager class + * PURPOSE: .img container manager class * *****************************************************************************/ From e43b294fef48f9911e2786ad019057964c0b3f23 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 23:50:51 +0300 Subject: [PATCH 31/78] Fix wrong uiStreamHandlerID --- Client/game_sa/CStreamingSA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 47690513e6..92a851aa8e 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -220,7 +220,7 @@ unsigned char CStreamingSA::AddArchive(const char* szFilePath) void CStreamingSA::RemoveArchive(unsigned char ucArhiveID) { - unsigned int uiStreamHandlerID = ms_aAchiveInfo[ucArhiveID].uiStreamHandleId; + unsigned int uiStreamHandlerID = ms_aAchiveInfo[ucArhiveID].uiStreamHandleId >> 24; if (!uiStreamHandlerID) return; From a8fe35d55604595bbb0884aab6ff8de33565d472 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sat, 17 Oct 2020 23:51:18 +0300 Subject: [PATCH 32/78] Refactror std::vector to std::list --- Client/mods/deathmatch/logic/CClientIMG.cpp | 27 +++++++++++---------- Client/mods/deathmatch/logic/CClientIMG.h | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index d1adb4a54d..b382a3d286 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -158,7 +158,6 @@ bool CClientIMG::StreamEnable() if (IsStreamed()) return false; - m_pRestoreData.reserve(m_uiFilesCount); m_ucArchiveID = g_pGame->GetStreaming()->AddArchive(*m_strFilename); return IsStreamed(); } @@ -168,19 +167,20 @@ bool CClientIMG::StreamDisable() if (!IsStreamed()) return false; - for (unsigned int i = 0; i < m_pRestoreData.size(); i++ ) + // Unlink all models + std::list::iterator inter = m_pRestoreData.begin(); + for (; inter != m_pRestoreData.end(); inter++) { - tLinkedModelRestoreInfo* pRestoreData = m_pRestoreData[i]; - if (pRestoreData) - { - g_pGame->GetStreaming()->SetStreamingInfoForModelId(pRestoreData->uiModelID, pRestoreData->ucStreamID, pRestoreData->uiOffset, - pRestoreData->usSize); - delete pRestoreData; - } + tLinkedModelRestoreInfo* pRestoreData = *inter; + + g_pGame->GetStreaming()->SetStreamingInfoForModelId(pRestoreData->uiModelID, pRestoreData->ucStreamID, pRestoreData->uiOffset, + pRestoreData->usSize); + delete pRestoreData; } m_pRestoreData.clear(); + // Remove archive from streaming g_pGame->GetStreaming()->RemoveArchive(m_ucArchiveID); m_ucArchiveID = INVALID_ARCHIVE_ID; return true; @@ -212,14 +212,15 @@ bool CClientIMG::LinkModel(unsigned int uiModelID, unsigned int uiFileID) bool CClientIMG::UnlinkModel(unsigned int uiModelID) { - for (unsigned int i = 0; i < m_pRestoreData.size(); i++) + std::list::iterator inter = m_pRestoreData.begin(); + for (; inter != m_pRestoreData.end(); inter++) { - if (m_pRestoreData[i]->uiModelID == uiModelID) + tLinkedModelRestoreInfo* pRestoreData = *inter; + if (pRestoreData->uiModelID == uiModelID) { - tLinkedModelRestoreInfo* pRestoreData = m_pRestoreData[i]; g_pGame->GetStreaming()->SetStreamingInfoForModelId(uiModelID, pRestoreData->ucStreamID, pRestoreData->uiOffset, pRestoreData->usSize); + m_pRestoreData.remove(pRestoreData); delete pRestoreData; - m_pRestoreData.erase(m_pRestoreData.begin() + i); return true; } } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index f2dff9d1a7..76596237de 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -65,5 +65,5 @@ class CClientIMG : public CClientEntity unsigned int m_uiFilesCount; std::vector m_pContentInfo; - std::vector m_pRestoreData; + std::list m_pRestoreData; }; From 38ad586b1791ea0e0f26056212777a08c47e1117 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 02:55:44 +0300 Subject: [PATCH 33/78] Fix build --- Client/game_sa/CStreamingSA.cpp | 7 ------- Client/sdk/game/CStreaming.h | 5 ++--- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 97a67ca076..79b6d82359 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -16,8 +16,6 @@ CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo(*)[26 HANDLE (&CStreamingSA::m_aStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; // Contains open files CArchiveInfo (&CStreamingSA::ms_aAchiveInfo)[8] = *(CArchiveInfo(*)[8])0x8E48D8; // [8][0x30] -CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo(*)[26316])0x8E4CC0; - namespace { // @@ -142,11 +140,6 @@ void CStreamingSA::RequestSpecialModel(DWORD model, const char* szTexture, DWORD } } -CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(ushort id) -{ - return &ms_aInfoForModel[id]; -} - void CStreamingSA::ReinitStreaming() { typedef int(__cdecl * Function_ReInitStreaming)(); diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 9b5e59cb66..048e3a5663 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -43,10 +43,9 @@ class CStreaming virtual void LoadAllRequestedModels(BOOL bOnlyPriorityModels = 0, const char* szTag = NULL) = 0; virtual BOOL HasModelLoaded(DWORD dwModelID) = 0; virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; - virtual CStreamingInfo* GetStreamingInfoFromModelId(unsigned short id) = 0; + virtual CStreamingInfo* GetStreamingInfoFromModelId(unsigned int uiID) = 0; virtual void ReinitStreaming() = 0; virtual unsigned char AddArchive(const char* szFilePath) = 0; virtual void RemoveArchive(unsigned char ucArchiveID) = 0; - virtual CStreamingInfo* GetStreamingInfoFromModelId(unsigned int id) = 0; - virtual void SetStreamingInfoForModelId(unsigned int id, unsigned char usStreamID, unsigned int uiOffset, unsigned short usSize, unsigned int uiNextInImg = -1) = 0; + virtual void SetStreamingInfoForModelId(unsigned int id, unsigned char usStreamID, unsigned int uiOffset, unsigned short usSize, unsigned int uiNextInImg = -1) = 0; }; From 9644902634c62e8c1b120043ae2b742570d06e31 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 09:50:49 +0300 Subject: [PATCH 34/78] Used new parser for engineImage* --- Client/mods/deathmatch/logic/CClientIMG.cpp | 6 +- Client/mods/deathmatch/logic/CClientIMG.h | 4 +- .../logic/luadefs/CLuaEngineDefs.cpp | 310 +++++------------- .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 16 +- 4 files changed, 98 insertions(+), 238 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index b382a3d286..0bb2f4bcda 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -105,7 +105,7 @@ void CClientIMG::Unload() } } -long CClientIMG::GetFile(unsigned int uiFileID, SString& buffer) +long CClientIMG::GetFile(unsigned int uiFileID, std::string& buffer) { tImgFileInfo* pFileInfo = GetFileInfo(uiFileID); if (!pFileInfo) @@ -134,12 +134,12 @@ tImgFileInfo* CClientIMG::GetFileInfo(unsigned int usFileID) return &m_pContentInfo[usFileID]; } -unsigned int CClientIMG::GetFileID(SString strFileName) +unsigned int CClientIMG::GetFileID(std::string &strFileName) { strFileName.resize(24); for (unsigned int i = 0; i < m_uiFilesCount; i++) { - if (strFileName.EqualsI(m_pContentInfo[i].szFileName)) + if (strFileName == m_pContentInfo[i].szFileName) return i; } return -1; diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 76596237de..b7a109ddc0 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -47,8 +47,8 @@ class CClientIMG : public CClientEntity bool Load(SString sFilePath); void Unload(); tImgFileInfo* GetFileInfo(unsigned int uiFileID); - unsigned int GetFileID(SString sFileName); - long GetFile(unsigned int uiFileID, SString& buffer); + unsigned int GetFileID(std::string &sFileName); + long GetFile(unsigned int uiFileID, std::string& buffer); bool StreamEnable(); bool StreamDisable(); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index f62afb9744..929b37e604 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -50,15 +50,15 @@ void CLuaEngineDefs::LoadFunctions() {"engineSetObjectGroupPhysicalProperty", EngineSetObjectGroupPhysicalProperty}, {"engineGetObjectGroupPhysicalProperty", EngineGetObjectGroupPhysicalProperty}, {"engineRestoreObjectGroupPhysicalProperties", EngineRestoreObjectGroupPhysicalProperties}, - {"engineLoadIMG", EngineLoadIMG}, - {"engineImageLinkModel", EngineImageLinkModel}, - {"engineRestoreModelImage", EngineRestoreModelImage}, - {"engineAddImage", EngineAddImage}, - {"engineRemoveImage", EngineRemoveImage}, - {"engineImageGetFilesCount", EngineImageGetFilesCount}, - {"engineImageGetFileList", EngineImageGetFileList}, - {"engineImageGetFile", EngineImageGetFile}, - {"engineGetModelTXDID", EngineGetModelTXDID}, + {"engineLoadIMG", ArgumentParser}, + {"engineImageLinkModel", ArgumentParser}, + {"engineRestoreModelImage", ArgumentParser}, + {"engineAddImage", ArgumentParser}, + {"engineRemoveImage", ArgumentParser}, + {"engineImageGetFilesCount", ArgumentParser}, + {"engineImageGetFileList", ArgumentParser}, + {"engineImageGetFile", ArgumentParser}, + {"engineGetModelTXDID", ArgumentParser}, //{"engineSetModelTXDID", EngineSetModelTXDID}, // CLuaCFunctions::AddFunction ( "engineReplaceMatchingAtomics", EngineReplaceMatchingAtomics ); @@ -141,8 +141,8 @@ void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) lua_classfunction(luaVM, "getFilesCount", "engineImageGetFilesCount"); lua_classfunction(luaVM, "linkModel", "engineImageLinkModel"); - lua_classvariable(luaVM, "filesCount", nullptr, EngineImageGetFilesCount); - lua_classvariable(luaVM, "files", nullptr, EngineImageGetFileList); + lua_classvariable(luaVM, "filesCount", nullptr, ArgumentParser); + lua_classvariable(luaVM, "files", nullptr, ArgumentParser); lua_registerclass(luaVM, "EngineIMG", "Element"); } @@ -158,67 +158,6 @@ void CLuaEngineDefs::AddEngineDffClass(lua_State* luaVM) lua_registerclass(luaVM, "EngineDFF", "Element"); } -int CLuaEngineDefs::EngineLoadIMG(lua_State* luaVM) -{ - SString input; - CScriptArgReader argStream(luaVM); - // Grab the IMG filename or data - argStream.ReadString(input); - - if (!argStream.HasErrors()) - { - // Grab the lua main and the resource belonging to this script - CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (pLuaMain) - { - // Get the resource we belong to - CResource* pResource = pLuaMain->GetResource(); - if (pResource) - { - - SString filePath; - - // Is this a legal filepath? - if (CResourceManager::ParseResourcePathInput(input, pResource, &filePath)) - { - // Grab the resource root entity - CClientEntity* pRoot = pResource->GetResourceIMGRoot(); - // Create the img handle - CClientIMG* pImg = new CClientIMG(m_pManager, INVALID_ELEMENT_ID); - - // Attempt loading the file - if (pImg->Load(std::move(filePath))) - { - // Success. Make it a child of the resource img root - pImg->SetParent(pRoot); - - lua_pushelement(luaVM, pImg); - return 1; - } - else - { - delete pImg; - argStream.SetCustomError(input, "Error loading IMG"); - } - } - else - { - argStream.SetCustomError(input, "Bad file path"); - } - } - } - } - - if (argStream.HasErrors()) - { - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - } - - lua_pushboolean(luaVM, false); - return 1; -} - - int CLuaEngineDefs::EngineLoadCOL(lua_State* luaVM) { SString input; @@ -594,198 +533,119 @@ int CLuaEngineDefs::EngineImportTXD(lua_State* luaVM) return 1; } -int CLuaEngineDefs::EngineAddImage(lua_State* luaVM) +CClientIMG* CLuaEngineDefs::EngineLoadIMG(lua_State* const luaVM, std::string strFilePath) { - CClientIMG* pIMG; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pIMG); + CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); + if (!pLuaMain) + return false; - if (!argStream.HasErrors()) - { - lua_pushboolean(luaVM, pIMG->StreamEnable()); - return 1; - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + // Get the resource we belong to + CResource* pResource = pLuaMain->GetResource(); + if (!pResource) + return false; - lua_pushboolean(luaVM, false); - return 1; -} + std::string strFullPath; -int CLuaEngineDefs::EngineRemoveImage(lua_State* luaVM) -{ - CClientIMG* pIMG; + if (CResourceManager::ParseResourcePathInput(strFilePath, pResource, &strFullPath)) + { + // Grab the resource root entity + CClientEntity* pRoot = pResource->GetResourceIMGRoot(); + // Create the img handle + CClientIMG* pImg = new CClientIMG(m_pManager, INVALID_ELEMENT_ID); - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pIMG); + // Attempt loading the file + if (pImg->Load(std::move(strFullPath))) + { + // Success. Make it a child of the resource img root + pImg->SetParent(pRoot); - if (!argStream.HasErrors()) + return pImg; + } + else + { + delete pImg; + std::invalid_argument("Error loading IMG"); + } + } + else { - lua_pushboolean(luaVM, pIMG->StreamDisable()); - return 1; + std::invalid_argument("Bad file path"); } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; } -int CLuaEngineDefs::EngineImageGetFilesCount(lua_State* luaVM) +bool CLuaEngineDefs::EngineAddImage(CClientIMG* pIMG) { - CClientIMG* pIMG; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pIMG); - - if (!argStream.HasErrors()) - { - lua_pushnumber(luaVM, pIMG->GetFilesCount()); - return 1; - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - lua_pushboolean(luaVM, false); - return 1; + return pIMG->StreamEnable(); } -int CLuaEngineDefs::EngineImageGetFileList(lua_State* luaVM) +bool CLuaEngineDefs::EngineRemoveImage(CClientIMG* pIMG) { - CClientIMG* pIMG; - - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pIMG); + return pIMG->StreamDisable(); +} - if (!argStream.HasErrors()) - { - lua_newtable(luaVM); +uint CLuaEngineDefs::EngineImageGetFilesCount(CClientIMG* pIMG) +{ + return pIMG->GetFilesCount(); +} - for (unsigned int i = 0; i < pIMG->GetFilesCount(); i++) - { - tImgFileInfo* pFileInfo = pIMG->GetFileInfo(i); +std::vector CLuaEngineDefs::EngineImageGetFileList(CClientIMG* pIMG) +{ + uint uiFilesCount = pIMG->GetFilesCount(); + std::vector aOutput; + aOutput.reserve(uiFilesCount); - lua_pushnumber(luaVM, i); - lua_pushstring(luaVM, pFileInfo->szFileName); - lua_settable(luaVM, -3); - } - - return 1; - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + for (unsigned int i = 0; i < uiFilesCount; i++) + aOutput.push_back(pIMG->GetFileInfo(i)->szFileName); - lua_pushboolean(luaVM, false); - return 1; + return aOutput; } -int CLuaEngineDefs::EngineImageGetFile(lua_State* luaVM) +std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file) { - CClientIMG* pIMG; - unsigned int fileID = -1; - SString strFileName; + uint uiFileID; + uint* pFileID = std::get_if(&file); - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pIMG); - - if (argStream.NextIsNumber()) - argStream.ReadNumber(fileID); + if (pFileID) + uiFileID = *pFileID - 1; else - argStream.ReadString(strFileName); + pIMG->GetFileID(std::get(file)); - if (!argStream.HasErrors()) - { - if (fileID == -1) - fileID = pIMG->GetFileID(strFileName); + if (uiFileID == -1) + std::invalid_argument("File not found"); - SString buffer; - long lBytesRead = pIMG->GetFile(fileID, buffer); + std::string strBuffer; + long lBytesRead = pIMG->GetFile(uiFileID, strBuffer); - if (lBytesRead >= 0) - { - // Push the string onto the Lua stack. Use pushlstring so we are binary - // compatible. Normal push string takes zero terminated strings. - lua_pushlstring(luaVM, buffer.data(), lBytesRead); - return 1; - } - else if (lBytesRead == -2) - { - m_pScriptDebugging->LogWarning(luaVM, "out of memory"); - } - else - { - argStream.SetCustomWarning("File not found"); - } - } + if (lBytesRead >= 0) + return strBuffer; + else if (lBytesRead == -2) + std::invalid_argument("Out of memory"); else - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // Error - lua_pushnil(luaVM); - return 1; + std::invalid_argument("File not found"); } - -int CLuaEngineDefs::EngineImageLinkModel(lua_State* luaVM) +bool CLuaEngineDefs::EngineImageLinkModel(CClientIMG* pIMG, std::variant file, uint uiModelID) { - unsigned short usModelID; - CClientIMG* pIMG; - unsigned int fileID = -1; - SString strFileName; + uint uiFileID; + uint* pFileID = std::get_if(&file); - CScriptArgReader argStream(luaVM); - argStream.ReadUserData(pIMG); - if (argStream.NextIsNumber()) - argStream.ReadNumber(fileID); + if (pFileID) + uiFileID = *pFileID - 1; else - argStream.ReadString(strFileName); - argStream.ReadNumber(usModelID); - - if (!argStream.HasErrors()) - { - if (fileID == -1) - fileID = pIMG->GetFileID(strFileName); + pIMG->GetFileID(std::get(file)); - if (fileID != -1 && pIMG->LinkModel(usModelID, fileID)) - { - lua_pushboolean(luaVM, true); - return 1; - } - else - argStream.SetCustomError(SString("Model ID %d replace failed", usModelID)); - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); + if (uiFileID == -1) + std::invalid_argument("File not found"); - lua_pushboolean(luaVM, false); - return 1; + return pIMG->LinkModel(uiModelID, uiFileID); } -int CLuaEngineDefs::EngineRestoreModelImage(lua_State* luaVM) +bool CLuaEngineDefs::EngineRestoreModelImage(uint uiModelID) { - // Grab the model ID - unsigned int uiModelID = CModelNames::ResolveModelID(lua_tostring(luaVM, 1)); - - // Valid client DFF and model? if (CClientIMGManager::IsLinkableModel(uiModelID)) - { - // Restore the model - if (m_pImgManager->RestoreModel(uiModelID)) - { - // Success - lua_pushboolean(luaVM, true); - return true; - } - } - else - { - m_pScriptDebugging->LogBadType(luaVM); - } + return m_pImgManager->RestoreModel(uiModelID); - // Failure - lua_pushboolean(luaVM, false); - return 1; + return false; } int CLuaEngineDefs::EngineReplaceModel(lua_State* luaVM) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index e97477bc68..64b0d35657 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -18,7 +18,6 @@ class CLuaEngineDefs : public CLuaDefs static void LoadFunctions(); static void AddClass(lua_State* luaVM); - LUA_DECLARE(EngineLoadIMG); LUA_DECLARE(EngineLoadDFF); LUA_DECLARE(EngineLoadTXD); LUA_DECLARE(EngineLoadCOL); @@ -60,13 +59,14 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineSetObjectGroupPhysicalProperty) LUA_DECLARE(EngineGetObjectGroupPhysicalProperty) LUA_DECLARE(EngineRestoreObjectGroupPhysicalProperties) - LUA_DECLARE(EngineAddImage) - LUA_DECLARE(EngineRemoveImage) - LUA_DECLARE(EngineImageGetFilesCount) - LUA_DECLARE(EngineImageGetFileList) - LUA_DECLARE(EngineImageGetFile) - LUA_DECLARE(EngineImageLinkModel); - LUA_DECLARE(EngineRestoreModelImage); + static CClientIMG* EngineLoadIMG(lua_State* const luaVM, std::string strFilePath); + static bool EngineAddImage(CClientIMG* pImg); + static bool EngineRemoveImage(CClientIMG* pImg); + static uint EngineImageGetFilesCount(CClientIMG* pImg); + static bool EngineImageLinkModel(CClientIMG* pImg, std::variant file, uint uiModelID); + static bool EngineRestoreModelImage(uint uiModelID); + static std::vector EngineImageGetFileList(CClientIMG* pImg); + static std::string EngineImageGetFile(CClientIMG* pImg, std::variant file); static bool CLuaEngineDefs::EngineRestreamWorld(lua_State* const luaVM); static bool EngineSetModelVisibleTime(std::string strModelId, char cHourOn, char cHourOff); static std::variant> EngineGetModelVisibleTime(std::string strModelId); From 4f958d734e8a0116f474ac0d78b0ffcd45011eae Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 10:42:21 +0300 Subject: [PATCH 35/78] Fix API --- Client/mods/deathmatch/logic/CClientIMG.cpp | 3 +-- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 0bb2f4bcda..626a0d1898 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -136,10 +136,9 @@ tImgFileInfo* CClientIMG::GetFileInfo(unsigned int usFileID) unsigned int CClientIMG::GetFileID(std::string &strFileName) { - strFileName.resize(24); for (unsigned int i = 0; i < m_uiFilesCount; i++) { - if (strFileName == m_pContentInfo[i].szFileName) + if (strFileName.compare(m_pContentInfo[i].szFileName) == 0) return i; } return -1; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 929b37e604..20a1f4b089 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -602,13 +602,13 @@ std::vector CLuaEngineDefs::EngineImageGetFileList(CClientIMG* pIMG std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file) { - uint uiFileID; + uint uiFileID = -1; uint* pFileID = std::get_if(&file); if (pFileID) uiFileID = *pFileID - 1; else - pIMG->GetFileID(std::get(file)); + uiFileID = pIMG->GetFileID(std::get(file)); if (uiFileID == -1) std::invalid_argument("File not found"); @@ -626,13 +626,13 @@ std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file, uint uiModelID) { - uint uiFileID; + uint uiFileID = -1; uint* pFileID = std::get_if(&file); if (pFileID) uiFileID = *pFileID - 1; else - pIMG->GetFileID(std::get(file)); + uiFileID = pIMG->GetFileID(std::get(file)); if (uiFileID == -1) std::invalid_argument("File not found"); From 3ff97d81f1b90295c968f60f941cbe5d2a0c6f70 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 10:45:39 +0300 Subject: [PATCH 36/78] Fix removed engineRestreamWorld --- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 20a1f4b089..33b95cd223 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -50,6 +50,7 @@ void CLuaEngineDefs::LoadFunctions() {"engineSetObjectGroupPhysicalProperty", EngineSetObjectGroupPhysicalProperty}, {"engineGetObjectGroupPhysicalProperty", EngineGetObjectGroupPhysicalProperty}, {"engineRestoreObjectGroupPhysicalProperties", EngineRestoreObjectGroupPhysicalProperties}, + {"engineRestreamWorld", ArgumentParser}, {"engineLoadIMG", ArgumentParser}, {"engineImageLinkModel", ArgumentParser}, {"engineRestoreModelImage", ArgumentParser}, From 4c3aceb9326556fad21f6ed3c1c6e99535eb5297 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 11:13:59 +0300 Subject: [PATCH 37/78] Removed unused TXD stuff --- Client/game_sa/CRenderWareSA.cpp | 24 --------- Client/game_sa/CRenderWareSA.h | 1 - .../logic/luadefs/CLuaEngineDefs.cpp | 50 +------------------ .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 3 +- 4 files changed, 3 insertions(+), 75 deletions(-) diff --git a/Client/game_sa/CRenderWareSA.cpp b/Client/game_sa/CRenderWareSA.cpp index 01354ebeff..21e5905642 100644 --- a/Client/game_sa/CRenderWareSA.cpp +++ b/Client/game_sa/CRenderWareSA.cpp @@ -703,30 +703,6 @@ ushort CRenderWareSA::GetTXDIDForModelID(ushort usModelID) } } -//////////////////////////////////////////////////////////////// -// -// CRenderWareSA::SetTXDIDForModelID -// -// Set a TXD ID associated with the model ID -// -//////////////////////////////////////////////////////////////// -bool CRenderWareSA::SetTXDIDForModelID(ushort usModelID, ushort usTXDID) -{ - if (usModelID >= 20000) - { - return false; - } - else - { - // Ensure valid - if (!((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]) - return false; - - ((CBaseModelInfoSAInterface**)ARRAY_ModelInfo)[usModelID]->usTextureDictionary = usTXDID; - return true; - } -} - //////////////////////////////////////////////////////////////// // // CRenderWareSA::GetModelTextureNames diff --git a/Client/game_sa/CRenderWareSA.h b/Client/game_sa/CRenderWareSA.h index 036294f24b..f887fb1d14 100644 --- a/Client/game_sa/CRenderWareSA.h +++ b/Client/game_sa/CRenderWareSA.h @@ -92,7 +92,6 @@ class CRenderWareSA : public CRenderWare bool ReplacePartModels(RpClump* pClump, RpAtomicContainer* pAtomics, unsigned int uiAtomics, const char* szName); ushort GetTXDIDForModelID(ushort usModelID); - bool SetTXDIDForModelID(ushort usModelID, ushort usTXDID); void PulseWorldTextureWatch(); void GetModelTextureNames(std::vector& outNameList, ushort usModelID); bool GetModelTextures(std::vector>& outTextureList, ushort usModelID, std::vector vTextureNames); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 33b95cd223..281e87e537 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -60,7 +60,6 @@ void CLuaEngineDefs::LoadFunctions() {"engineImageGetFileList", ArgumentParser}, {"engineImageGetFile", ArgumentParser}, {"engineGetModelTXDID", ArgumentParser}, - //{"engineSetModelTXDID", EngineSetModelTXDID}, // CLuaCFunctions::AddFunction ( "engineReplaceMatchingAtomics", EngineReplaceMatchingAtomics ); // CLuaCFunctions::AddFunction ( "engineReplaceWheelAtomics", EngineReplaceWheelAtomics ); @@ -1134,56 +1133,11 @@ int CLuaEngineDefs::EngineRemoveShaderFromWorldTexture(lua_State* luaVM) return 1; } -int CLuaEngineDefs::EngineGetModelTXDID(lua_State* luaVM) +uint CLuaEngineDefs::EngineGetModelTXDID(uint uiModelID) { - // int engineGetModelTXDID ( int modelID ) - unsigned short usModelID; - - CScriptArgReader argStream(luaVM); - argStream.ReadNumber(usModelID); - - if (!argStream.HasErrors()) - { - unsigned short usTXDID = g_pGame->GetRenderWare()->GetTXDIDForModelID(usModelID); - lua_pushinteger(luaVM, usTXDID); - return 1; - } - if (argStream.HasErrors()) - m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); - - // We failed - lua_pushboolean(luaVM, false); - return 1; + return g_pGame->GetRenderWare()->GetTXDIDForModelID(uiModelID); } - -//int CLuaEngineDefs::EngineSetModelTXDID(lua_State* luaVM) -//{ -// unsigned short usModelID; -// unsigned short usTXDID; -// -// CScriptArgReader argStream(luaVM); -// argStream.ReadNumber(usModelID); -// argStream.ReadNumber(usTXDID); -// -// if (!argStream.HasErrors()) -// { -// bool bResult = g_pGame->GetRenderWare()->SetTXDIDForModelID(usModelID, usTXDID); -// if (bResult) -// { -// lua_pushboolean(luaVM, bResult); -// return 1; -// } -// argStream.SetCustomError("Expected valid model ID at argument 1"); -// } -// if (argStream.HasErrors()) -// m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage()); -// -// // We failed -// lua_pushboolean(luaVM, false); -// return 1; -//} - int CLuaEngineDefs::EngineGetModelNameFromID(lua_State* luaVM) { // string engineGetModelNameFromID ( int modelID ) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 64b0d35657..699732abb0 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -43,8 +43,7 @@ class CLuaEngineDefs : public CLuaDefs LUA_DECLARE(EngineSetAsynchronousLoading); LUA_DECLARE(EngineApplyShaderToWorldTexture); LUA_DECLARE(EngineRemoveShaderFromWorldTexture); - LUA_DECLARE(EngineGetModelTXDID); - LUA_DECLARE(EngineSetModelTXDID); + static uint EngineGetModelTXDID(uint uiDffModelID); LUA_DECLARE(EngineGetModelNameFromID); LUA_DECLARE(EngineGetModelIDFromName); LUA_DECLARE(EngineGetModelTextureNames); From ef0a3eae9b1bd74db58df0d4c860bbdaa06c45fa Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 11:43:26 +0300 Subject: [PATCH 38/78] engineImageLinkModel replaced to engineImageLinkDFF and engineImageLinkTXD --- .../logic/luadefs/CLuaEngineDefs.cpp | 21 +++++++++++++++++-- .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 3 ++- Client/sdk/game/CRenderWare.h | 1 - 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 281e87e537..0c122ddc57 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -52,7 +52,8 @@ void CLuaEngineDefs::LoadFunctions() {"engineRestoreObjectGroupPhysicalProperties", EngineRestoreObjectGroupPhysicalProperties}, {"engineRestreamWorld", ArgumentParser}, {"engineLoadIMG", ArgumentParser}, - {"engineImageLinkModel", ArgumentParser}, + {"engineImageLinkDFF", ArgumentParser}, + {"engineImageLinkTXD", ArgumentParser}, {"engineRestoreModelImage", ArgumentParser}, {"engineAddImage", ArgumentParser}, {"engineRemoveImage", ArgumentParser}, @@ -624,7 +625,7 @@ std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file, uint uiModelID) +bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variant file, uint uiModelID) { uint uiFileID = -1; uint* pFileID = std::get_if(&file); @@ -640,6 +641,22 @@ bool CLuaEngineDefs::EngineImageLinkModel(CClientIMG* pIMG, std::variantLinkModel(uiModelID, uiFileID); } +bool CLuaEngineDefs::EngineImageLinkTXD(CClientIMG* pIMG, std::variant file, uint uiTxdID) +{ + uint uiFileID = -1; + uint* pFileID = std::get_if(&file); + + if (pFileID) + uiFileID = *pFileID - 1; + else + uiFileID = pIMG->GetFileID(std::get(file)); + + if (uiFileID == -1) + std::invalid_argument("File not found"); + + return pIMG->LinkModel(20000 + uiTxdID, uiFileID); +} + bool CLuaEngineDefs::EngineRestoreModelImage(uint uiModelID) { if (CClientIMGManager::IsLinkableModel(uiModelID)) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 699732abb0..16ceed9a26 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -62,7 +62,8 @@ class CLuaEngineDefs : public CLuaDefs static bool EngineAddImage(CClientIMG* pImg); static bool EngineRemoveImage(CClientIMG* pImg); static uint EngineImageGetFilesCount(CClientIMG* pImg); - static bool EngineImageLinkModel(CClientIMG* pImg, std::variant file, uint uiModelID); + static bool EngineImageLinkDFF(CClientIMG* pImg, std::variant file, uint uiModelID); + static bool EngineImageLinkTXD(CClientIMG* pImg, std::variant file, uint uiModelID); static bool EngineRestoreModelImage(uint uiModelID); static std::vector EngineImageGetFileList(CClientIMG* pImg); static std::string EngineImageGetFile(CClientIMG* pImg, std::variant file); diff --git a/Client/sdk/game/CRenderWare.h b/Client/sdk/game/CRenderWare.h index 80547d7c0c..92bbdc8253 100644 --- a/Client/sdk/game/CRenderWare.h +++ b/Client/sdk/game/CRenderWare.h @@ -92,7 +92,6 @@ class CRenderWare virtual bool GetModelTextures(std::vector>& outTextureList, ushort usModelID, std::vector vTextureNames) = 0; virtual const char* GetTextureName(CD3DDUMMY* pD3DData) = 0; virtual ushort GetTXDIDForModelID(ushort usModelID) = 0; - virtual bool SetTXDIDForModelID(ushort usModelID, ushort usTXDID) = 0; virtual void SetRenderingClientEntity(CClientEntityBase* pClientEntity, ushort usModelId, int iTypeMask) = 0; virtual SShaderItemLayers* GetAppliedShaderForD3DData(CD3DDUMMY* pD3DData) = 0; From f45931ef5295e00ee1ff487fefd29a5097742616 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 11:44:33 +0300 Subject: [PATCH 39/78] Fix OOP API --- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 0c122ddc57..cc8069450f 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -140,7 +140,8 @@ void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) lua_classfunction(luaVM, "getFile", "engineImageGetFile"); lua_classfunction(luaVM, "getFileList", "engineImageGetFileList"); lua_classfunction(luaVM, "getFilesCount", "engineImageGetFilesCount"); - lua_classfunction(luaVM, "linkModel", "engineImageLinkModel"); + lua_classfunction(luaVM, "linkTXD", "engineImageLinkDFF"); + lua_classfunction(luaVM, "linkDFF", "engineImageLinkTXD"); lua_classvariable(luaVM, "filesCount", nullptr, ArgumentParser); lua_classvariable(luaVM, "files", nullptr, ArgumentParser); From ba66c2979c3b09d92e0b9417927f63dc50110da8 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 11:59:47 +0300 Subject: [PATCH 40/78] Fix API --- .../logic/luadefs/CLuaEngineDefs.cpp | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index cc8069450f..5917c9e85a 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -140,8 +140,8 @@ void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) lua_classfunction(luaVM, "getFile", "engineImageGetFile"); lua_classfunction(luaVM, "getFileList", "engineImageGetFileList"); lua_classfunction(luaVM, "getFilesCount", "engineImageGetFilesCount"); - lua_classfunction(luaVM, "linkTXD", "engineImageLinkDFF"); - lua_classfunction(luaVM, "linkDFF", "engineImageLinkTXD"); + lua_classfunction(luaVM, "linkTXD", "engineImageLinkTXD"); + lua_classfunction(luaVM, "linkDFF", "engineImageLinkDFF"); lua_classvariable(luaVM, "filesCount", nullptr, ArgumentParser); lua_classvariable(luaVM, "files", nullptr, ArgumentParser); @@ -566,13 +566,11 @@ CClientIMG* CLuaEngineDefs::EngineLoadIMG(lua_State* const luaVM, std::string st else { delete pImg; - std::invalid_argument("Error loading IMG"); + throw std::invalid_argument("Error loading IMG"); } } - else - { - std::invalid_argument("Bad file path"); - } + + throw std::invalid_argument("Bad file path"); } bool CLuaEngineDefs::EngineAddImage(CClientIMG* pIMG) @@ -613,7 +611,7 @@ std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variantGetFileID(std::get(file)); if (uiFileID == -1) - std::invalid_argument("File not found"); + throw std::invalid_argument("File not found"); std::string strBuffer; long lBytesRead = pIMG->GetFile(uiFileID, strBuffer); @@ -621,9 +619,9 @@ std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant= 0) return strBuffer; else if (lBytesRead == -2) - std::invalid_argument("Out of memory"); + throw std::invalid_argument("Out of memory"); else - std::invalid_argument("File not found"); + throw std::invalid_argument("File not found"); } bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variant file, uint uiModelID) @@ -637,7 +635,7 @@ bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variantGetFileID(std::get(file)); if (uiFileID == -1) - std::invalid_argument("File not found"); + throw std::invalid_argument("File not found"); return pIMG->LinkModel(uiModelID, uiFileID); } @@ -653,7 +651,7 @@ bool CLuaEngineDefs::EngineImageLinkTXD(CClientIMG* pIMG, std::variantGetFileID(std::get(file)); if (uiFileID == -1) - std::invalid_argument("File not found"); + throw std::invalid_argument("File not found"); return pIMG->LinkModel(20000 + uiTxdID, uiFileID); } From c4fd582d877504e3ade007cb13bb9a241666994b Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 13:11:27 +0300 Subject: [PATCH 41/78] Fixed restore functions --- .../logic/luadefs/CLuaEngineDefs.cpp | 25 +++++++++++++++++-- .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 3 ++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 5917c9e85a..d0d4e21a93 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -54,7 +54,8 @@ void CLuaEngineDefs::LoadFunctions() {"engineLoadIMG", ArgumentParser}, {"engineImageLinkDFF", ArgumentParser}, {"engineImageLinkTXD", ArgumentParser}, - {"engineRestoreModelImage", ArgumentParser}, + {"engineRestoreDFFImage", ArgumentParser}, + {"engineRestoreTXDImage", ArgumentParser}, {"engineAddImage", ArgumentParser}, {"engineRemoveImage", ArgumentParser}, {"engineImageGetFilesCount", ArgumentParser}, @@ -626,6 +627,9 @@ std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file, uint uiModelID) { + if (uiModelID >= 20000) + throw std::invalid_argument("Expected model ID in range [0-19999] at argument 3"); + uint uiFileID = -1; uint* pFileID = std::get_if(&file); @@ -642,6 +646,9 @@ bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variant file, uint uiTxdID) { + if (uiTxdID >= 5000) + throw std::invalid_argument("Expected model ID in range [0-4999] at argument 3"); + uint uiFileID = -1; uint* pFileID = std::get_if(&file); @@ -656,14 +663,28 @@ bool CLuaEngineDefs::EngineImageLinkTXD(CClientIMG* pIMG, std::variantLinkModel(20000 + uiTxdID, uiFileID); } -bool CLuaEngineDefs::EngineRestoreModelImage(uint uiModelID) +bool CLuaEngineDefs::EngineRestoreDFFImage(uint uiModelID) { + if (uiModelID >= 20000) + throw std::invalid_argument("Expected model ID in range [0-19999] at argument 1"); + if (CClientIMGManager::IsLinkableModel(uiModelID)) return m_pImgManager->RestoreModel(uiModelID); return false; } +bool CLuaEngineDefs::EngineRestoreTXDImage(uint uiModelID) +{ + if (uiModelID >= 5000) + throw std::invalid_argument("Expected TXD ID in range [0-4999] at argument 1"); + + if (CClientIMGManager::IsLinkableModel(uiModelID)) + return m_pImgManager->RestoreModel(uiModelID + 20000); + + return false; +} + int CLuaEngineDefs::EngineReplaceModel(lua_State* luaVM) { CClientDFF* pDFF; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 16ceed9a26..dfe70ddc21 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -64,7 +64,8 @@ class CLuaEngineDefs : public CLuaDefs static uint EngineImageGetFilesCount(CClientIMG* pImg); static bool EngineImageLinkDFF(CClientIMG* pImg, std::variant file, uint uiModelID); static bool EngineImageLinkTXD(CClientIMG* pImg, std::variant file, uint uiModelID); - static bool EngineRestoreModelImage(uint uiModelID); + static bool EngineRestoreDFFImage(uint uiModelID); + static bool EngineRestoreTXDImage(uint uiModelID); static std::vector EngineImageGetFileList(CClientIMG* pImg); static std::string EngineImageGetFile(CClientIMG* pImg, std::variant file); static bool CLuaEngineDefs::EngineRestreamWorld(lua_State* const luaVM); From 771160fdb114747b74a9d4f2df7f42a9ec85aef5 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 13:17:16 +0300 Subject: [PATCH 42/78] Fix missing stuff --- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index d0d4e21a93..9d39c2e80a 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -86,7 +86,8 @@ void CLuaEngineDefs::AddClass(lua_State* luaVM) lua_classfunction(luaVM, "setModelLODDistance", "engineSetModelLODDistance"); lua_classfunction(luaVM, "resetModelLODDistance", "engineResetModelLODDistance"); lua_classfunction(luaVM, "setModelVisibleTime", "engineSetModelVisibleTime"); - lua_classfunction(luaVM, "restoreModelImage", "engineRestoreModelImage"); + lua_classfunction(luaVM, "restoreDFFImage", "engineRestoreDFFImage"); + lua_classfunction(luaVM, "restoreTXDImage", "engineRestoreTXDImage"); lua_classfunction(luaVM, "getVisibleTextureNames", "engineGetVisibleTextureNames"); lua_classfunction(luaVM, "getModelLODDistance", "engineGetModelLODDistance"); From 50aad93e2585f0ad133210266a07cf90d03a3a9c Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Fri, 13 Nov 2020 13:29:10 +0300 Subject: [PATCH 43/78] Removed unused stuff --- Client/game_sa/CStreamingSA.cpp | 3 ++- Client/game_sa/CStreamingSA.h | 11 ----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 79b6d82359..e76555fe4f 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -210,7 +210,8 @@ unsigned char CStreamingSA::AddArchive(const char* szFilePath) return -1; // Create new stream handler - DWORD dOpenFlags = *(DWORD*)(VAR_StreamHandlerCreateFlags) | FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS; + // Supported state stored in 0x8E3FE0 + DWORD dOpenFlags = *(DWORD*)(0x8E3FE0) | FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS; hFile = CreateFileA(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dOpenFlags, NULL); diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 91aefcfa7d..d53b18be86 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -14,13 +14,6 @@ #include #include "Common.h" -// Shoud be changed to interfaces -#define ARRAY_StreamHandlersNames 0x8E4098 // [32][64] - -#define ARRAY_StreamModelInfo 0x8E4CC0 // size = 26316 - -#define VAR_StreamHandlersMaxCount 32 -#define VAR_StreamHandlerCreateFlags 0x8E3FE0 #define VAR_StreamHandlersMaxCount 32 #define VAR_MaxArchives 8 @@ -30,10 +23,6 @@ #define FUNC_CStreaming_RequestAnimations 0x407120 #define FUNC_CStreaming_RequestSpecialModel 0x409d10 -#define FUNC_CStreaming_RequestFile 0x406A20 // (DWORD streamNum, int lpBuffer, int streamIndex, int sectorCount) - -#define FUNC_CStreaming_RemoveImages 0x4066B3 // Remove all IMG`s from streaming -#define FUNC_CStreaming_RemoveImage 0x4068A0 struct CArchiveInfo { From 79b6941da3359bd4e338a6c4838482d5382cf640 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 12:35:53 +0100 Subject: [PATCH 44/78] Refactor CClientIMG --- Client/mods/deathmatch/logic/CClientIMG.cpp | 188 ++++++++++---------- Client/mods/deathmatch/logic/CClientIMG.h | 67 ++++--- 2 files changed, 133 insertions(+), 122 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 626a0d1898..0c8d07f474 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -10,6 +10,7 @@ #include + #define INVALID_ARCHIVE_ID 0xFF struct tImgHeader @@ -18,42 +19,40 @@ struct tImgHeader unsigned int uiFilesCount; }; -CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID) +CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : + ClassInit(this), + CClientEntity(ID), + m_pImgManager(pManager->GetIMGManager()), + m_ucArchiveID(INVALID_ARCHIVE_ID) { - // Init - m_uiFilesCount = 0; m_pManager = pManager; - m_ucArchiveID = INVALID_ARCHIVE_ID; - m_pFile = nullptr; SetTypeName("img"); - - m_pImgManager = pManager->GetIMGManager(); - m_pImgManager->AddToList(this); } CClientIMG::~CClientIMG() { m_pImgManager->RemoveFromList(this); - if (IsStreamed()) StreamDisable(); - - Unload(); } -bool CClientIMG::Load(SString sFilePath) +bool CClientIMG::Load(fs::path filePath) { - if (sFilePath.empty()) + if (!m_fileInfos.empty()) return false; - if (!FileExists(sFilePath)) + if (m_ifs.is_open()) return false; - if (!m_pContentInfo.empty()) + if (filePath.empty()) return false; - m_strFilename = std::move(sFilePath); + if (!fs::exists(filePath)) + return false; + + m_filePath = filePath.string(); + m_ifs = std::ifstream(filePath, std::ios::binary); /* g_pClientGame->GetResourceManager()->ValidateResourceFile(m_strFilename, nullptr, 0); if (!g_pCore->GetNetwork()->CheckFile("img", m_strFilename)) @@ -61,32 +60,38 @@ bool CClientIMG::Load(SString sFilePath) */ // Open the file - m_pFile = File::Fopen(m_strFilename, "rb"); - if (!m_pFile) + if (m_ifs.fail()) + { + m_ifs.close(); return false; + } tImgHeader fileHeader; // Read header - int iReadCount = fread(&fileHeader, sizeof(fileHeader), 1, m_pFile); + m_ifs.read(reinterpret_cast(&fileHeader), sizeof(tImgHeader)); - if (!iReadCount || memcmp(&fileHeader.szMagic, "VER2", 4)) + if (m_ifs.fail() || m_ifs.eof() || memcmp(&fileHeader.szMagic, "VER2", 4) != 0) { - fclose(m_pFile); + m_ifs.close(); return false; } - m_uiFilesCount = fileHeader.uiFilesCount; - // Read content info + try + { + m_fileInfos.resize(fileHeader.uiFilesCount); + } + catch (const std::bad_alloc&) + { + m_ifs.close(); + return false; + } - m_pContentInfo.resize(m_uiFilesCount); - - iReadCount = fread(&m_pContentInfo.at(0), sizeof(tImgFileInfo), m_uiFilesCount, m_pFile); - - if (iReadCount != m_uiFilesCount) + m_ifs.read(reinterpret_cast(m_fileInfos.data()), { sizeof(tImgFileInfo) * (size_t)fileHeader.uiFilesCount }); + if (m_ifs.fail() || m_ifs.eof()) { - Unload(); + m_ifs.close(); return false; } @@ -95,53 +100,44 @@ bool CClientIMG::Load(SString sFilePath) void CClientIMG::Unload() { - m_pContentInfo.clear(); - m_uiFilesCount = 0; - - if (m_pFile) - { - fclose(m_pFile); - m_pFile = nullptr; - } + m_fileInfos.clear(); + m_fileInfos.shrink_to_fit(); + m_ifs.close(); } -long CClientIMG::GetFile(unsigned int uiFileID, std::string& buffer) +bool CClientIMG::GetFile(size_t fileID, std::string& buffer) { - tImgFileInfo* pFileInfo = GetFileInfo(uiFileID); + const tImgFileInfo* pFileInfo = GetFileInfo(fileID); if (!pFileInfo) - return -1; + throw std::invalid_argument("Invalid file id"); - unsigned long ulReadCount = pFileInfo->usSize * 2048; + const auto ulToReadSize = pFileInfo->usSize * 2048; + buffer.resize(ulToReadSize); // Might throw std::bad_alloc - try - { - buffer.resize(ulReadCount); - } - catch (const std::bad_alloc&) - { - return -2; - } + m_ifs.seekg({ pFileInfo->uiOffset * 2048 }); + m_ifs.read(buffer.data(), ulToReadSize); - long iReadCount = fread(buffer.data(), 1, ulReadCount, m_pFile); - - return iReadCount; + return !m_ifs.fail() && !m_ifs.eof(); } -tImgFileInfo* CClientIMG::GetFileInfo(unsigned int usFileID) +tImgFileInfo* CClientIMG::GetFileInfo(size_t fileID) { - if (usFileID > m_uiFilesCount) - return NULL; - return &m_pContentInfo[usFileID]; + if (fileID >= m_fileInfos.size()) + return nullptr; + return &m_fileInfos[fileID]; } -unsigned int CClientIMG::GetFileID(std::string &strFileName) +std::optional CClientIMG::GetFileID(std::string_view filename) { - for (unsigned int i = 0; i < m_uiFilesCount; i++) - { - if (strFileName.compare(m_pContentInfo[i].szFileName) == 0) - return i; - } - return -1; + const auto it = std::find_if(m_fileInfos.begin(), m_fileInfos.end(), + [filename](const auto& fileInfo) { + return filename.compare(fileInfo.szFileName) == 0; + } + ); + + if (it == m_fileInfos.end()) + return std::nullopt; + return std::distance(m_fileInfos.begin(), it); } bool CClientIMG::IsStreamed() @@ -151,13 +147,13 @@ bool CClientIMG::IsStreamed() bool CClientIMG::StreamEnable() { - if (!m_uiFilesCount) + if (m_fileInfos.empty()) return false; if (IsStreamed()) return false; - m_ucArchiveID = g_pGame->GetStreaming()->AddArchive(*m_strFilename); + m_ucArchiveID = g_pGame->GetStreaming()->AddArchive(m_filePath.c_str()); return IsStreamed(); } @@ -167,62 +163,60 @@ bool CClientIMG::StreamDisable() return false; // Unlink all models - std::list::iterator inter = m_pRestoreData.begin(); - for (; inter != m_pRestoreData.end(); inter++) + for (const auto& v : m_restoreInfo) { - tLinkedModelRestoreInfo* pRestoreData = *inter; - - g_pGame->GetStreaming()->SetStreamingInfoForModelId(pRestoreData->uiModelID, pRestoreData->ucStreamID, pRestoreData->uiOffset, - pRestoreData->usSize); - delete pRestoreData; + g_pGame->GetStreaming()->SetStreamingInfoForModelId( + v.uiModelID, v.ucStreamID, v.uiOffset, v.usSize + ); } - - m_pRestoreData.clear(); + m_restoreInfo.clear(); + m_restoreInfo.shrink_to_fit(); // Remove archive from streaming g_pGame->GetStreaming()->RemoveArchive(m_ucArchiveID); m_ucArchiveID = INVALID_ARCHIVE_ID; + return true; } -bool CClientIMG::LinkModel(unsigned int uiModelID, unsigned int uiFileID) +bool CClientIMG::LinkModel(unsigned int uiModelID, size_t uiFileID) { if (!IsStreamed()) return false; - if (uiFileID >= m_uiFilesCount) + tImgFileInfo* pFileInfo = GetFileInfo(uiFileID); + if (!pFileInfo) return false; - tImgFileInfo* pFileInfo = GetFileInfo(uiFileID); + CStreamingInfo* pCurrInfo = g_pGame->GetStreaming()->GetStreamingInfoFromModelId(uiModelID); - CStreamingInfo* pCurrentStreamingInfo = g_pGame->GetStreaming()->GetStreamingInfoFromModelId(uiModelID); + if (pCurrInfo->archiveId == m_ucArchiveID) + return true; // Already linked - tLinkedModelRestoreInfo* pModelRestoreData = new tLinkedModelRestoreInfo(); - pModelRestoreData->uiModelID = uiModelID; - pModelRestoreData->ucStreamID = pCurrentStreamingInfo->archiveId; - pModelRestoreData->uiOffset = pCurrentStreamingInfo->offsetInBlocks; - pModelRestoreData->usSize = pCurrentStreamingInfo->sizeInBlocks; + m_restoreInfo.emplace_back(uiModelID, + pCurrInfo->offsetInBlocks, pCurrInfo->sizeInBlocks, pCurrInfo->archiveId); - m_pRestoreData.push_back(pModelRestoreData); + g_pGame->GetStreaming()->SetStreamingInfoForModelId( + uiModelID, m_ucArchiveID, pFileInfo->uiOffset, pFileInfo->usSize); - g_pGame->GetStreaming()->SetStreamingInfoForModelId(uiModelID, m_ucArchiveID, pFileInfo->uiOffset, pFileInfo->usSize); return true; } bool CClientIMG::UnlinkModel(unsigned int uiModelID) { - std::list::iterator inter = m_pRestoreData.begin(); - for (; inter != m_pRestoreData.end(); inter++) - { - tLinkedModelRestoreInfo* pRestoreData = *inter; - if (pRestoreData->uiModelID == uiModelID) - { - g_pGame->GetStreaming()->SetStreamingInfoForModelId(uiModelID, pRestoreData->ucStreamID, pRestoreData->uiOffset, pRestoreData->usSize); - m_pRestoreData.remove(pRestoreData); - delete pRestoreData; - return true; + const auto it = std::find_if(m_restoreInfo.begin(), m_restoreInfo.end(), + [uiModelID](const auto& restoreInfo) { + return restoreInfo.uiModelID == uiModelID; } - } + ); + + if (it == m_restoreInfo.end()) + return false; - return false; + g_pGame->GetStreaming()->SetStreamingInfoForModelId( + uiModelID, it->ucStreamID, it->uiOffset, it->usSize); + + m_restoreInfo.erase(it); + + return true; } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index b7a109ddc0..4d85f68082 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -12,6 +12,12 @@ #pragma once #include "CClientEntity.h" +#include +#include +#include +#include +#include +namespace fs = std::filesystem; struct tImgFileInfo { @@ -23,10 +29,19 @@ struct tImgFileInfo struct tLinkedModelRestoreInfo { + constexpr tLinkedModelRestoreInfo(unsigned int uiModelID, unsigned int uiOffset, + unsigned short usSize, unsigned char ucStreamID) : + uiModelID(uiModelID), + uiOffset(uiOffset), + usSize(usSize), + ucStreamID(ucStreamID) + { + } + unsigned int uiModelID; - unsigned char ucStreamID; unsigned int uiOffset; unsigned short usSize; + unsigned char ucStreamID; }; class CClientIMG : public CClientEntity @@ -37,33 +52,35 @@ class CClientIMG : public CClientEntity CClientIMG(class CClientManager* pManager, ElementID ID); ~CClientIMG(); - void Unlink(){}; + void Unlink() {}; void GetPosition(CVector& vecPosition) const {}; - void SetPosition(const CVector& vecPosition){}; - - eClientEntityType GetType() const { return CCLIENTIMG; }; - unsigned char GetArchiveID() { return m_ucArchiveID; }; - unsigned int GetFilesCount() { return m_uiFilesCount; }; - bool Load(SString sFilePath); - void Unload(); - tImgFileInfo* GetFileInfo(unsigned int uiFileID); - unsigned int GetFileID(std::string &sFileName); - long GetFile(unsigned int uiFileID, std::string& buffer); - - bool StreamEnable(); - bool StreamDisable(); - bool IsStreamed(); - bool LinkModel(unsigned int usModelID, unsigned int usFileID); - bool UnlinkModel(unsigned int usModelID); + void SetPosition(const CVector& vecPosition) {}; + + eClientEntityType GetType() const { return CCLIENTIMG; } + unsigned char GetArchiveID() { return m_ucArchiveID; } + unsigned int GetFilesCount() { return m_fileInfos.size(); } + + bool Load(fs::path filePath); + void Unload(); + + tImgFileInfo* GetFileInfo(size_t fileID); + std::optional GetFileID(std::string_view filename); + bool GetFile(size_t uiFileID, std::string& buffer); + + bool StreamEnable(); + bool StreamDisable(); + bool IsStreamed(); + + bool LinkModel(unsigned int usModelID, size_t fileID); + bool UnlinkModel(unsigned int usModelID); private: - class CClientIMGManager* m_pImgManager; + class CClientIMGManager* m_pImgManager; - SString m_strFilename; - FILE* m_pFile; - unsigned char m_ucArchiveID; - unsigned int m_uiFilesCount; - std::vector m_pContentInfo; + std::ifstream m_ifs; + std::string m_filePath; + unsigned char m_ucArchiveID; + std::vector m_fileInfos; - std::list m_pRestoreData; + std::vector m_restoreInfo; }; From aafd0c80c475589467133f14ba4b6a16a5861553 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 13:20:15 +0100 Subject: [PATCH 45/78] Refactor Lua API for Images --- Client/mods/deathmatch/logic/CClientIMG.cpp | 10 ++- Client/mods/deathmatch/logic/CClientIMG.h | 2 + .../logic/luadefs/CLuaEngineDefs.cpp | 84 +++++++------------ .../deathmatch/logic/luadefs/CLuaEngineDefs.h | 8 +- 4 files changed, 44 insertions(+), 60 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 0c8d07f474..ea05e30bb1 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -112,7 +112,15 @@ bool CClientIMG::GetFile(size_t fileID, std::string& buffer) throw std::invalid_argument("Invalid file id"); const auto ulToReadSize = pFileInfo->usSize * 2048; - buffer.resize(ulToReadSize); // Might throw std::bad_alloc + + try + { + buffer.resize(ulToReadSize); + } + catch (const std::bad_alloc&) + { + throw std::invalid_argument("Out of memory"); + } m_ifs.seekg({ pFileInfo->uiOffset * 2048 }); m_ifs.read(buffer.data(), ulToReadSize); diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 4d85f68082..7d120126ac 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include namespace fs = std::filesystem; @@ -59,6 +60,7 @@ class CClientIMG : public CClientEntity eClientEntityType GetType() const { return CCLIENTIMG; } unsigned char GetArchiveID() { return m_ucArchiveID; } unsigned int GetFilesCount() { return m_fileInfos.size(); } + const auto& GetFileInfos() const noexcept { return m_fileInfos; } bool Load(fs::path filePath); void Unload(); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index aa190e15cc..97008baa14 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -590,78 +590,52 @@ uint CLuaEngineDefs::EngineImageGetFilesCount(CClientIMG* pIMG) return pIMG->GetFilesCount(); } -std::vector CLuaEngineDefs::EngineImageGetFileList(CClientIMG* pIMG) +std::vector CLuaEngineDefs::EngineImageGetFileList(CClientIMG* pIMG) { - uint uiFilesCount = pIMG->GetFilesCount(); - std::vector aOutput; - aOutput.reserve(uiFilesCount); + const auto& fileInfos = pIMG->GetFileInfos(); - for (unsigned int i = 0; i < uiFilesCount; i++) - aOutput.push_back(pIMG->GetFileInfo(i)->szFileName); + std::vector out; + out.reserve(fileInfos.size()); - return aOutput; + for (const auto& fileInfo : fileInfos) + out.emplace_back(fileInfo.szFileName); + + return out; } -std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file) +static size_t ResolveIMGFileID(CClientIMG* pIMG, std::variant file) { - uint uiFileID = -1; - uint* pFileID = std::get_if(&file); - - if (pFileID) - uiFileID = *pFileID - 1; + if (std::holds_alternative(file)) + return std::get(file); + + if (const auto id = pIMG->GetFileID(std::get(file))) + throw std::invalid_argument("Invalid file name specified"); else - uiFileID = pIMG->GetFileID(std::get(file)); + return id.value(); +} - if (uiFileID == -1) - throw std::invalid_argument("File not found"); +std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file) +{ + std::string buffer; - std::string strBuffer; - long lBytesRead = pIMG->GetFile(uiFileID, strBuffer); + if (!pIMG->GetFile(ResolveIMGFileID(pIMG, file), buffer)) // Get file might throw + throw std::exception("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); - if (lBytesRead >= 0) - return strBuffer; - else if (lBytesRead == -2) - throw std::invalid_argument("Out of memory"); - else - throw std::invalid_argument("File not found"); + return buffer; } -bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variant file, uint uiModelID) +bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variant file, uint uiModelID) { if (uiModelID >= 20000) - throw std::invalid_argument("Expected model ID in range [0-19999] at argument 3"); - - uint uiFileID = -1; - uint* pFileID = std::get_if(&file); - - if (pFileID) - uiFileID = *pFileID - 1; - else - uiFileID = pIMG->GetFileID(std::get(file)); - - if (uiFileID == -1) - throw std::invalid_argument("File not found"); - - return pIMG->LinkModel(uiModelID, uiFileID); + throw std::invalid_argument(SString("Expected modelid in range 0 - 19999, got %d", uiModelID)); + return pIMG->LinkModel(uiModelID, ResolveIMGFileID(pIMG, file)); } -bool CLuaEngineDefs::EngineImageLinkTXD(CClientIMG* pIMG, std::variant file, uint uiTxdID) +bool CLuaEngineDefs::EngineImageLinkTXD(CClientIMG* pIMG, std::variant file, uint uiTxdID) { if (uiTxdID >= 5000) - throw std::invalid_argument("Expected model ID in range [0-4999] at argument 3"); - - uint uiFileID = -1; - uint* pFileID = std::get_if(&file); - - if (pFileID) - uiFileID = *pFileID - 1; - else - uiFileID = pIMG->GetFileID(std::get(file)); - - if (uiFileID == -1) - throw std::invalid_argument("File not found"); - - return pIMG->LinkModel(20000 + uiTxdID, uiFileID); + throw std::invalid_argument(SString("Expected txdid in range 0 - 4999, got %d", uiTxdID)); + return pIMG->LinkModel(20000 + uiTxdID, ResolveIMGFileID(pIMG, file)); } bool CLuaEngineDefs::EngineRestoreDFFImage(uint uiModelID) @@ -681,7 +655,7 @@ bool CLuaEngineDefs::EngineRestoreTXDImage(uint uiModelID) throw std::invalid_argument("Expected TXD ID in range [0-4999] at argument 1"); if (CClientIMGManager::IsLinkableModel(uiModelID)) - return m_pImgManager->RestoreModel(uiModelID + 20000); + return m_pImgManager->RestoreModel(20000 + uiModelID); return false; } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index dfe70ddc21..9661a6fbad 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -62,12 +62,12 @@ class CLuaEngineDefs : public CLuaDefs static bool EngineAddImage(CClientIMG* pImg); static bool EngineRemoveImage(CClientIMG* pImg); static uint EngineImageGetFilesCount(CClientIMG* pImg); - static bool EngineImageLinkDFF(CClientIMG* pImg, std::variant file, uint uiModelID); - static bool EngineImageLinkTXD(CClientIMG* pImg, std::variant file, uint uiModelID); + static bool EngineImageLinkDFF(CClientIMG* pImg, std::variant file, uint uiModelID); + static bool EngineImageLinkTXD(CClientIMG* pImg, std::variant file, uint uiModelID); static bool EngineRestoreDFFImage(uint uiModelID); static bool EngineRestoreTXDImage(uint uiModelID); - static std::vector EngineImageGetFileList(CClientIMG* pImg); - static std::string EngineImageGetFile(CClientIMG* pImg, std::variant file); + static std::vector EngineImageGetFileList(CClientIMG* pImg); + static std::string EngineImageGetFile(CClientIMG* pImg, std::variant file); static bool CLuaEngineDefs::EngineRestreamWorld(lua_State* const luaVM); static bool EngineSetModelVisibleTime(std::string strModelId, char cHourOn, char cHourOff); static std::variant> EngineGetModelVisibleTime(std::string strModelId); From 2555c4d3e361ec237a8ed72ed53673a9db1d7f76 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 13:22:45 +0100 Subject: [PATCH 46/78] Fix warning in CClientIMG --- Client/mods/deathmatch/logic/CClientIMG.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index ea05e30bb1..5f560ad80e 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -88,7 +88,7 @@ bool CClientIMG::Load(fs::path filePath) return false; } - m_ifs.read(reinterpret_cast(m_fileInfos.data()), { sizeof(tImgFileInfo) * (size_t)fileHeader.uiFilesCount }); + m_ifs.read(reinterpret_cast(m_fileInfos.data()), sizeof(tImgFileInfo) * (std::streampos)fileHeader.uiFilesCount); if (m_ifs.fail() || m_ifs.eof()) { m_ifs.close(); @@ -122,7 +122,7 @@ bool CClientIMG::GetFile(size_t fileID, std::string& buffer) throw std::invalid_argument("Out of memory"); } - m_ifs.seekg({ pFileInfo->uiOffset * 2048 }); + m_ifs.seekg((std::streampos)pFileInfo->uiOffset * 2048); m_ifs.read(buffer.data(), ulToReadSize); return !m_ifs.fail() && !m_ifs.eof(); From 4ae02ca7d165e0a3f7329ad1ca090d34509eb5f6 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 13:46:35 +0100 Subject: [PATCH 47/78] Change lua::Push std::string to std::string_view, thus adding support for std::string_view. This fixes the compilation error --- Shared/mods/deathmatch/logic/lua/LuaBasic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Shared/mods/deathmatch/logic/lua/LuaBasic.h b/Shared/mods/deathmatch/logic/lua/LuaBasic.h index c0e5fddef9..5f05fda755 100644 --- a/Shared/mods/deathmatch/logic/lua/LuaBasic.h +++ b/Shared/mods/deathmatch/logic/lua/LuaBasic.h @@ -66,7 +66,7 @@ namespace lua return 1; } - inline int Push(lua_State* L, const std::string& value) + inline int Push(lua_State* L, std::string_view value) { lua_pushlstring(L, value.data(), value.length()); return 1; From 8180adc601dbca4c2c25111dd5f17857164814eb Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 14:33:51 +0100 Subject: [PATCH 48/78] Fix ms_aInfoForModel - address was invalid, and caused a crash after model 9364 --- Client/game_sa/CStreamingSA.cpp | 2 +- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 80124fea72..1227cd2943 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -13,7 +13,7 @@ #include "Fileapi.h" #include "CModelInfoSA.h" -CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo(*)[26316])CStreaming__ms_aInfoForModel; +CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo(*)[26316])0x8E4CC0; HANDLE (&CStreamingSA::m_aStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; // Contains open files CArchiveInfo (&CStreamingSA::ms_aAchiveInfo)[8] = *(CArchiveInfo(*)[8])0x8E48D8; // [8][0x30] diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 97008baa14..7ebf701c14 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -607,11 +607,11 @@ static size_t ResolveIMGFileID(CClientIMG* pIMG, std::variant(file)) return std::get(file); - - if (const auto id = pIMG->GetFileID(std::get(file))) - throw std::invalid_argument("Invalid file name specified"); - else + + const auto fileName = std::get(file); + if (const auto id = pIMG->GetFileID(fileName)) return id.value(); + throw std::invalid_argument(SString("Invalid file name specified (%*s)", (int)fileName.length(), fileName.data())); } std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file) From beef9ff52995e95c1dd235a1bccfc945ce54badd Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 14:43:51 +0100 Subject: [PATCH 49/78] Cleanup CStreamingSA::ReinitStreaming --- Client/game_sa/CStreamingSA.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 1227cd2943..46e00cf626 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -144,9 +144,7 @@ void CStreamingSA::RequestSpecialModel(DWORD model, const char* szTexture, DWORD void CStreamingSA::ReinitStreaming() { typedef int(__cdecl * Function_ReInitStreaming)(); - Function_ReInitStreaming reinitStreaming = (Function_ReInitStreaming)(0x40E560); - - reinitStreaming(); + ((Function_ReInitStreaming)(0x40E560))(); } void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg) From eca68ea0c98d03501efd37edd2f4d5548da9211e Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 14:47:41 +0100 Subject: [PATCH 50/78] Cleanup CStreamingSA::SetStreamingInfoForModelId and add a note --- Client/game_sa/CStreamingSA.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 46e00cf626..73fd9ff149 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -147,18 +147,24 @@ void CStreamingSA::ReinitStreaming() ((Function_ReInitStreaming)(0x40E560))(); } +// ReinitStreaming should be called after this. +// Otherwise the model wont be restreamed +// TODO: Somehow restream a single model instead of the whole world void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg) { CStreamingInfo* pItemInfo = GetStreamingInfoFromModelId(id); // Change nextInImg filed for prev model - for ( unsigned int i = 0; i < 26316; i++) + for (CStreamingInfo& info : ms_aInfoForModel) { - if (ms_aInfoForModel[i].archiveId == pItemInfo->archiveId && - (ms_aInfoForModel[i].offsetInBlocks + ms_aInfoForModel[i].sizeInBlocks) == pItemInfo->offsetInBlocks) + if (info.archiveId == pItemInfo->archiveId) { - ms_aInfoForModel[i].nextInImg = -1; - break; + // Check if the block after `info` is the beginning of `pItemInfo`'s block + if (info.offsetInBlocks + info.sizeInBlocks == pItemInfo->offsetInBlocks) + { + info.nextInImg = -1; + break; + } } } From 046b21e6b3ef56e2c1d53c4169cb2e13f41fa985 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 14:54:25 +0100 Subject: [PATCH 51/78] Add GetUnusedArchieve() --- Client/game_sa/CStreamingSA.cpp | 18 +++++++++--------- Client/game_sa/CStreamingSA.h | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 73fd9ff149..223ccba5f8 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -179,21 +179,21 @@ CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) return &ms_aInfoForModel[id]; } -unsigned char CStreamingSA::AddArchive(const char* szFilePath) +unsigned char CStreamingSA::GetUnusedArchive() { // Get internal IMG id // By default gta sa uses 6 of 8 IMG archives - uchar ucArchiveId = -1; - for (int i = 6; i < 8; i++) + for (size_t i = 6; i < 8; i++) { - CArchiveInfo* info = GetArchiveInfo(i); - if (!info->uiStreamHandleId) - { - ucArchiveId = i; - break; - } + if (!GetArchiveInfo(i)->uiStreamHandleId) + return i; } + return -1; +} +unsigned char CStreamingSA::AddArchive(const char* szFilePath) +{ + const auto ucArchiveId = GetUnusedArchive(); if (ucArchiveId == -1) return -1; diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index d53b18be86..ef966b7d4d 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -46,6 +46,7 @@ class CStreamingSA : public CStreaming void SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1); CStreamingInfo* GetStreamingInfoFromModelId(uint id); + unsigned char GetUnusedArchive(); unsigned char AddArchive(const char* szFilePath); void RemoveArchive(unsigned char ucStreamHandler); From eb11e40dba8887961d67f5a6682f28f07f2eaa77 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 14:57:59 +0100 Subject: [PATCH 52/78] Add GetUnusedStreamHandle() --- Client/game_sa/CStreamingSA.cpp | 24 ++++++++++++------------ Client/game_sa/CStreamingSA.h | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 223ccba5f8..29514699f6 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -191,6 +191,16 @@ unsigned char CStreamingSA::GetUnusedArchive() return -1; } +unsigned char CStreamingSA::GetUnusedStreamHandle() +{ + for (size_t i = 0; i < VAR_StreamHandlersMaxCount; i++) + { + if (m_aStreamingHandlers[i]) + return i; + } + return -1; +} + unsigned char CStreamingSA::AddArchive(const char* szFilePath) { const auto ucArchiveId = GetUnusedArchive(); @@ -199,19 +209,9 @@ unsigned char CStreamingSA::AddArchive(const char* szFilePath) // Get free stream handler id HANDLE hFile = INVALID_HANDLE_VALUE; - unsigned char ucStreamID = 0; - - for (unsigned char ID = 0; ID < VAR_StreamHandlersMaxCount; ++ID) - { - HANDLE hFile = m_aStreamingHandlers[ID]; - if (!hFile) - { - ucStreamID = ID; - break; - } - }; - if (ucStreamID == 0) + const auto ucStreamID = GetUnusedStreamHandle(); + if (ucStreamID == -1) return -1; // Create new stream handler diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index ef966b7d4d..450b71bcbb 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -47,6 +47,7 @@ class CStreamingSA : public CStreaming void SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1); CStreamingInfo* GetStreamingInfoFromModelId(uint id); unsigned char GetUnusedArchive(); + unsigned char GetUnusedStreamHandle(); unsigned char AddArchive(const char* szFilePath); void RemoveArchive(unsigned char ucStreamHandler); From 2b6e1d7fd38ef5551feb99347cb6fb90652ac14f Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 15:03:54 +0100 Subject: [PATCH 53/78] Refactor CStreamingSA::AddArchive --- Client/game_sa/CStreamingSA.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 29514699f6..1f0dec9a42 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -208,17 +208,21 @@ unsigned char CStreamingSA::AddArchive(const char* szFilePath) return -1; // Get free stream handler id - HANDLE hFile = INVALID_HANDLE_VALUE; - const auto ucStreamID = GetUnusedStreamHandle(); if (ucStreamID == -1) return -1; - // Create new stream handler - // Supported state stored in 0x8E3FE0 - DWORD dOpenFlags = *(DWORD*)(0x8E3FE0) | FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS; - - hFile = CreateFileA(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dOpenFlags, NULL); + // Create new stream handler + const auto streamCreateFlags = *(DWORD*)0x8E3FE0; + HANDLE hFile = CreateFileA( + szFilePath, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + streamCreateFlags | FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS, + NULL + ); if (hFile == INVALID_HANDLE_VALUE) return -1; From 987980bb3bd202c31d1626b702cd025dc7878738 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 15:05:54 +0100 Subject: [PATCH 54/78] Rename GetStreamingInfoFromModelID to GetStreamingInfo --- Client/game_sa/CModelInfoSA.cpp | 8 ++++---- Client/game_sa/CStreamingSA.cpp | 6 +++--- Client/game_sa/CStreamingSA.h | 2 +- Client/mods/deathmatch/logic/CClientIMG.cpp | 2 +- Client/mods/deathmatch/logic/CClientIMGManager.cpp | 2 +- Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp | 4 ++-- Client/sdk/game/CStreaming.h | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index cba89db077..53d041a95f 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -526,7 +526,7 @@ bool CModelInfoSA::IsValid() bool CModelInfoSA::IsAllocatedInArchive() { - return pGame->GetStreaming()->GetStreamingInfoFromModelId(m_dwModelID)->sizeInBlocks > 0; + return pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)->sizeInBlocks > 0; } float CModelInfoSA::GetDistanceFromCentreOfMassToBaseOfModel() @@ -1407,8 +1407,8 @@ void CModelInfoSA::SetVoice(const char* szVoiceType, const char* szVoice) void CModelInfoSA::CopyStreamingInfoFromModel(ushort usBaseModelID) { - CStreamingInfo* pBaseModelStreamingInfo = pGame->GetStreaming()->GetStreamingInfoFromModelId(usBaseModelID); - CStreamingInfo* pTargetModelStreamingInfo = pGame->GetStreaming()->GetStreamingInfoFromModelId(m_dwModelID); + CStreamingInfo* pBaseModelStreamingInfo = pGame->GetStreaming()->GetStreamingInfo(usBaseModelID); + CStreamingInfo* pTargetModelStreamingInfo = pGame->GetStreaming()->GetStreamingInfo(m_dwModelID); pTargetModelStreamingInfo->Reset(); pTargetModelStreamingInfo->archiveId = pBaseModelStreamingInfo->archiveId; @@ -1464,7 +1464,7 @@ void CModelInfoSA::DeallocateModel(void) { Remove(); ppModelInfo[m_dwModelID] = nullptr; - pGame->GetStreaming()->GetStreamingInfoFromModelId(m_dwModelID)->Reset(); + pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)->Reset(); } ////////////////////////////////////////////////////////////////////////////////////////// // diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 1f0dec9a42..c3d24e6af5 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -152,7 +152,7 @@ void CStreamingSA::ReinitStreaming() // TODO: Somehow restream a single model instead of the whole world void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg) { - CStreamingInfo* pItemInfo = GetStreamingInfoFromModelId(id); + CStreamingInfo* pItemInfo = GetStreamingInfo(id); // Change nextInImg filed for prev model for (CStreamingInfo& info : ms_aInfoForModel) @@ -174,9 +174,9 @@ void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, pItemInfo->nextInImg = uiNextInImg; } -CStreamingInfo* CStreamingSA::GetStreamingInfoFromModelId(uint id) +CStreamingInfo* CStreamingSA::GetStreamingInfo(uint modelid) { - return &ms_aInfoForModel[id]; + return &ms_aInfoForModel[modelid]; } unsigned char CStreamingSA::GetUnusedArchive() diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 450b71bcbb..587949b344 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -45,7 +45,7 @@ class CStreamingSA : public CStreaming void ReinitStreaming(); void SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1); - CStreamingInfo* GetStreamingInfoFromModelId(uint id); + CStreamingInfo* GetStreamingInfo(uint modelid); unsigned char GetUnusedArchive(); unsigned char GetUnusedStreamHandle(); unsigned char AddArchive(const char* szFilePath); diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 5f560ad80e..b3d70e7e4c 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -196,7 +196,7 @@ bool CClientIMG::LinkModel(unsigned int uiModelID, size_t uiFileID) if (!pFileInfo) return false; - CStreamingInfo* pCurrInfo = g_pGame->GetStreaming()->GetStreamingInfoFromModelId(uiModelID); + CStreamingInfo* pCurrInfo = g_pGame->GetStreaming()->GetStreamingInfo(uiModelID); if (pCurrInfo->archiveId == m_ucArchiveID) return true; // Already linked diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.cpp b/Client/mods/deathmatch/logic/CClientIMGManager.cpp index 45207077cb..48227116dc 100644 --- a/Client/mods/deathmatch/logic/CClientIMGManager.cpp +++ b/Client/mods/deathmatch/logic/CClientIMGManager.cpp @@ -77,7 +77,7 @@ bool CClientIMGManager::Exists(CClientIMG* pIMG) CClientIMG* CClientIMGManager::GetElementThatLinked(unsigned int uiModel) { - uchar ucArhiveID = g_pGame->GetStreaming()->GetStreamingInfoFromModelId(uiModel)->archiveId; + uchar ucArhiveID = g_pGame->GetStreaming()->GetStreamingInfo(uiModel)->archiveId; return GetElementFromArchiveID(ucArhiveID); } diff --git a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp index 6c56b97d9e..7c5b61dee1 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_CrashFixHacks.cpp @@ -1000,7 +1000,7 @@ void _declspec(naked) HOOK_CClumpModelInfo_GetFrameFromId() } } -CStreamingInfo* GetStreamingInfoFromModelId(uint id) +CStreamingInfo* GetStreamingInfo(uint id) { CStreamingInfo* pItemInfo = (CStreamingInfo*)(CStreaming__ms_aInfoForModel); return pItemInfo + id; @@ -1032,7 +1032,7 @@ void OnMY_CEntity_GetBoundRect(CEntitySAInterface* pEntity) if (!pColModel) { // Crash will occur at offset 00134134 - CStreamingInfo* pStreamingInfo = pGameInterface->GetStreaming()->GetStreamingInfoFromModelId(usModelId); + CStreamingInfo* pStreamingInfo = pGameInterface->GetStreaming()->GetStreamingInfo(usModelId); SString strDetails("refs:%d txd:%d RwObj:%08x bOwn:%d bColStr:%d flg:%d off:%d size:%d loadState:%d", pModelInfo->usNumberOfRefs, pModelInfo->usTextureDictionary, pModelInfo->pRwObject, pModelInfo->bDoWeOwnTheColModel, pModelInfo->bCollisionWasStreamedWithModel, pStreamingInfo->flg, pStreamingInfo->offsetInBlocks, pStreamingInfo->sizeInBlocks, diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index ee9664f57d..936a4fcbe8 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -46,7 +46,7 @@ class CStreaming virtual void LoadAllRequestedModels(BOOL bOnlyPriorityModels = 0, const char* szTag = NULL) = 0; virtual BOOL HasModelLoaded(DWORD dwModelID) = 0; virtual void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel) = 0; - virtual CStreamingInfo* GetStreamingInfoFromModelId(unsigned int uiID) = 0; + virtual CStreamingInfo* GetStreamingInfo(unsigned int uiID) = 0; virtual void ReinitStreaming() = 0; virtual unsigned char AddArchive(const char* szFilePath) = 0; virtual void RemoveArchive(unsigned char ucArchiveID) = 0; From 8be4de2f44139f06c88fec57b18084b79b91cfec Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 15:07:34 +0100 Subject: [PATCH 55/78] Rename SetStreamingInfoForModelId to SetStreamingInfo --- Client/game_sa/CStreamingSA.cpp | 4 ++-- Client/game_sa/CStreamingSA.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index c3d24e6af5..f1be4ff811 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -150,9 +150,9 @@ void CStreamingSA::ReinitStreaming() // ReinitStreaming should be called after this. // Otherwise the model wont be restreamed // TODO: Somehow restream a single model instead of the whole world -void CStreamingSA::SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg) +void CStreamingSA::SetStreamingInfo(uint modelid, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg) { - CStreamingInfo* pItemInfo = GetStreamingInfo(id); + CStreamingInfo* pItemInfo = GetStreamingInfo(modelid); // Change nextInImg filed for prev model for (CStreamingInfo& info : ms_aInfoForModel) diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 587949b344..6123f8b0f6 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -44,7 +44,7 @@ class CStreamingSA : public CStreaming void RequestSpecialModel(DWORD model, const char* szTexture, DWORD channel); void ReinitStreaming(); - void SetStreamingInfoForModelId(uint id, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1); + void SetStreamingInfo(uint modelid, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg = -1); CStreamingInfo* GetStreamingInfo(uint modelid); unsigned char GetUnusedArchive(); unsigned char GetUnusedStreamHandle(); From 3f927bb8eb046e4accb05632f1d307fe55882831 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 15:13:03 +0100 Subject: [PATCH 56/78] Addendum to SetStreamingInfo rename --- Client/mods/deathmatch/logic/CClientIMG.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index b3d70e7e4c..5cc985bd10 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -173,7 +173,7 @@ bool CClientIMG::StreamDisable() // Unlink all models for (const auto& v : m_restoreInfo) { - g_pGame->GetStreaming()->SetStreamingInfoForModelId( + g_pGame->GetStreaming()->SetStreamingInfo( v.uiModelID, v.ucStreamID, v.uiOffset, v.usSize ); } @@ -204,7 +204,7 @@ bool CClientIMG::LinkModel(unsigned int uiModelID, size_t uiFileID) m_restoreInfo.emplace_back(uiModelID, pCurrInfo->offsetInBlocks, pCurrInfo->sizeInBlocks, pCurrInfo->archiveId); - g_pGame->GetStreaming()->SetStreamingInfoForModelId( + g_pGame->GetStreaming()->SetStreamingInfo( uiModelID, m_ucArchiveID, pFileInfo->uiOffset, pFileInfo->usSize); return true; @@ -221,7 +221,7 @@ bool CClientIMG::UnlinkModel(unsigned int uiModelID) if (it == m_restoreInfo.end()) return false; - g_pGame->GetStreaming()->SetStreamingInfoForModelId( + g_pGame->GetStreaming()->SetStreamingInfo( uiModelID, it->ucStreamID, it->uiOffset, it->usSize); m_restoreInfo.erase(it); From a2ff05ec5f16fa1fb90e6ecad111608e5bd29192 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 18:50:31 +0100 Subject: [PATCH 57/78] Addendum to SetStreamingInfo rename.. --- Client/sdk/game/CStreaming.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 936a4fcbe8..41444c4063 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -50,5 +50,5 @@ class CStreaming virtual void ReinitStreaming() = 0; virtual unsigned char AddArchive(const char* szFilePath) = 0; virtual void RemoveArchive(unsigned char ucArchiveID) = 0; - virtual void SetStreamingInfoForModelId(unsigned int id, unsigned char usStreamID, unsigned int uiOffset, unsigned short usSize, unsigned int uiNextInImg = -1) = 0; + virtual void SetStreamingInfo(unsigned int id, unsigned char usStreamID, unsigned int uiOffset, unsigned short usSize, unsigned int uiNextInImg = -1) = 0; }; From 3d819ed71f2b7a9e3e618b56ff2bcdd7479bb0a4 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 18:57:29 +0100 Subject: [PATCH 58/78] Replace CStreamingInfo::Reset() with CStreamingInfo{} + default initalization --- Client/game_sa/CModelInfoSA.cpp | 4 ++-- Client/sdk/game/CStreaming.h | 29 ++++++++--------------------- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 53d041a95f..6178eae6dd 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -1410,7 +1410,7 @@ void CModelInfoSA::CopyStreamingInfoFromModel(ushort usBaseModelID) CStreamingInfo* pBaseModelStreamingInfo = pGame->GetStreaming()->GetStreamingInfo(usBaseModelID); CStreamingInfo* pTargetModelStreamingInfo = pGame->GetStreaming()->GetStreamingInfo(m_dwModelID); - pTargetModelStreamingInfo->Reset(); + *pTargetModelStreamingInfo = CStreamingInfo{}; pTargetModelStreamingInfo->archiveId = pBaseModelStreamingInfo->archiveId; pTargetModelStreamingInfo->offsetInBlocks = pBaseModelStreamingInfo->offsetInBlocks; pTargetModelStreamingInfo->sizeInBlocks = pBaseModelStreamingInfo->sizeInBlocks; @@ -1464,7 +1464,7 @@ void CModelInfoSA::DeallocateModel(void) { Remove(); ppModelInfo[m_dwModelID] = nullptr; - pGame->GetStreaming()->GetStreamingInfo(m_dwModelID)->Reset(); + *pGame->GetStreaming()->GetStreamingInfo(m_dwModelID) = CStreamingInfo{}; } ////////////////////////////////////////////////////////////////////////////////////////// // diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 41444c4063..d5fe99a3c0 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -15,27 +15,14 @@ struct CStreamingInfo { - uint16_t prevId; - uint16_t nextId; - uint16_t nextInImg; - uint8_t flg; - uint8_t archiveId; - uint32_t offsetInBlocks; - uint32_t sizeInBlocks; - uint32_t loadState; - -public: - void Reset() - { - this->loadState = 0; - this->nextInImg = -1; - this->nextId = -1; - this->prevId = -1; - this->archiveId = 0; - this->flg = 0; - this->offsetInBlocks = 0; - this->sizeInBlocks = 0; - }; + uint16_t prevId = -1; + uint16_t nextId = -1; + uint16_t nextInImg = -1; + uint8_t flg = 0; + uint8_t archiveId = 0; + uint32_t offsetInBlocks = 0; + uint32_t sizeInBlocks = 0; + uint32_t loadState = 0; }; static_assert(sizeof(CStreamingInfo) == 0x14, "Invalid size for CStreamingInfo"); From e76ed7a3da47f6e8c1721b45b339ac85430d74ae Mon Sep 17 00:00:00 2001 From: Pirulax Date: Sun, 6 Dec 2020 20:40:53 +0100 Subject: [PATCH 59/78] fix narrowing extension error in CStreaming.h --- Client/sdk/game/CStreaming.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index d5fe99a3c0..450ce85f03 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -15,14 +15,14 @@ struct CStreamingInfo { - uint16_t prevId = -1; - uint16_t nextId = -1; - uint16_t nextInImg = -1; - uint8_t flg = 0; - uint8_t archiveId = 0; - uint32_t offsetInBlocks = 0; - uint32_t sizeInBlocks = 0; - uint32_t loadState = 0; + uint16_t prevId = (uint16_t)-1; + uint16_t nextId = (uint16_t)-1; + uint16_t nextInImg = (uint16_t)-1; + uint8_t flg = 0u; + uint8_t archiveId = 0u; + uint32_t offsetInBlocks = 0u; + uint32_t sizeInBlocks = 0u; + uint32_t loadState = 0u; }; static_assert(sizeof(CStreamingInfo) == 0x14, "Invalid size for CStreamingInfo"); From af6cbe59259c969ef6b67407e174762a95fc905a Mon Sep 17 00:00:00 2001 From: Pirulax Date: Tue, 8 Dec 2020 11:41:26 +0100 Subject: [PATCH 60/78] Fix issues caused by argument parser - number on stack was converted to string, instead of read as an int --- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 8 ++++---- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 7ebf701c14..dff30209c4 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -603,7 +603,7 @@ std::vector CLuaEngineDefs::EngineImageGetFileList(CClientIMG* return out; } -static size_t ResolveIMGFileID(CClientIMG* pIMG, std::variant file) +static size_t ResolveIMGFileID(CClientIMG* pIMG, std::variant file) { if (std::holds_alternative(file)) return std::get(file); @@ -614,7 +614,7 @@ static size_t ResolveIMGFileID(CClientIMG* pIMG, std::variant file) +std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file) { std::string buffer; @@ -624,14 +624,14 @@ std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variant file, uint uiModelID) +bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variant file, uint uiModelID) { if (uiModelID >= 20000) throw std::invalid_argument(SString("Expected modelid in range 0 - 19999, got %d", uiModelID)); return pIMG->LinkModel(uiModelID, ResolveIMGFileID(pIMG, file)); } -bool CLuaEngineDefs::EngineImageLinkTXD(CClientIMG* pIMG, std::variant file, uint uiTxdID) +bool CLuaEngineDefs::EngineImageLinkTXD(CClientIMG* pIMG, std::variant file, uint uiTxdID) { if (uiTxdID >= 5000) throw std::invalid_argument(SString("Expected txdid in range 0 - 4999, got %d", uiTxdID)); diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h index 9661a6fbad..9f719cbebe 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.h @@ -62,12 +62,12 @@ class CLuaEngineDefs : public CLuaDefs static bool EngineAddImage(CClientIMG* pImg); static bool EngineRemoveImage(CClientIMG* pImg); static uint EngineImageGetFilesCount(CClientIMG* pImg); - static bool EngineImageLinkDFF(CClientIMG* pImg, std::variant file, uint uiModelID); - static bool EngineImageLinkTXD(CClientIMG* pImg, std::variant file, uint uiModelID); + static bool EngineImageLinkDFF(CClientIMG* pImg, std::variant file, uint uiModelID); + static bool EngineImageLinkTXD(CClientIMG* pImg, std::variant file, uint uiModelID); static bool EngineRestoreDFFImage(uint uiModelID); static bool EngineRestoreTXDImage(uint uiModelID); static std::vector EngineImageGetFileList(CClientIMG* pImg); - static std::string EngineImageGetFile(CClientIMG* pImg, std::variant file); + static std::string EngineImageGetFile(CClientIMG* pImg, std::variant file); static bool CLuaEngineDefs::EngineRestreamWorld(lua_State* const luaVM); static bool EngineSetModelVisibleTime(std::string strModelId, char cHourOn, char cHourOff); static std::variant> EngineGetModelVisibleTime(std::string strModelId); From 1aba45d03e32fd3d997d0110a1bf78800e376b87 Mon Sep 17 00:00:00 2001 From: Pirulax Date: Tue, 8 Dec 2020 11:45:10 +0100 Subject: [PATCH 61/78] Fix compiler warnings --- Client/game_sa/CStreamingSA.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index f1be4ff811..7208fcea41 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -186,7 +186,7 @@ unsigned char CStreamingSA::GetUnusedArchive() for (size_t i = 6; i < 8; i++) { if (!GetArchiveInfo(i)->uiStreamHandleId) - return i; + return (unsigned char)i; } return -1; } @@ -196,7 +196,7 @@ unsigned char CStreamingSA::GetUnusedStreamHandle() for (size_t i = 0; i < VAR_StreamHandlersMaxCount; i++) { if (m_aStreamingHandlers[i]) - return i; + return (unsigned char)i; } return -1; } From 0a2d9464f6f89a397d6bb656b68fdc74f4ad26fe Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sat, 10 Apr 2021 18:00:47 +0300 Subject: [PATCH 62/78] Fix conflicts --- Client/game_sa/CModelInfoSA.cpp | 2 +- Client/game_sa/CStreamingSA.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/game_sa/CModelInfoSA.cpp b/Client/game_sa/CModelInfoSA.cpp index 87faa00019..084b7a633a 100644 --- a/Client/game_sa/CModelInfoSA.cpp +++ b/Client/game_sa/CModelInfoSA.cpp @@ -784,7 +784,7 @@ void CModelInfoSA::StaticFlushPendingRestreamIPL() for (it = removedModels.begin(); it != removedModels.end(); it++) { ((void(__cdecl*)(unsigned short))FUNC_RemoveModel)(*it); - pGame->GetStreaming()->GetStreamingInfoFromModelId(*it)->loadState = 0; + pGame->GetStreaming()->GetStreamingInfo(*it)->loadState = 0; } } diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index e21cb6c1e4..7208fcea41 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -150,7 +150,7 @@ void CStreamingSA::ReinitStreaming() // ReinitStreaming should be called after this. // Otherwise the model wont be restreamed // TODO: Somehow restream a single model instead of the whole world -void CStreamingSA::SetStreamingInfo(uint modelid, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg +void CStreamingSA::SetStreamingInfo(uint modelid, unsigned char usStreamID, uint uiOffset, ushort usSize, uint uiNextInImg) { CStreamingInfo* pItemInfo = GetStreamingInfo(modelid); From c58038653e8959da93bb3d81c668a36e6a8678dd Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sat, 10 Apr 2021 18:36:32 +0300 Subject: [PATCH 63/78] fix typo --- Client/game_sa/CStreamingSA.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 7208fcea41..d4a878c53d 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -154,7 +154,7 @@ void CStreamingSA::SetStreamingInfo(uint modelid, unsigned char usStreamID, uint { CStreamingInfo* pItemInfo = GetStreamingInfo(modelid); - // Change nextInImg filed for prev model + // Change nextInImg field for prev model for (CStreamingInfo& info : ms_aInfoForModel) { if (info.archiveId == pItemInfo->archiveId) From 05c7c74b6ae1335b6142e870731e1d834ef7fd56 Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 11 Apr 2021 20:42:22 +0300 Subject: [PATCH 64/78] Added CStreamingSA::SetStreamingBufferSize --- Client/game_sa/CStreamingSA.cpp | 48 +++++++++++++++++++++++++++++++++ Client/game_sa/CStreamingSA.h | 18 +++++++++++++ Client/sdk/game/CStreaming.h | 1 + 3 files changed, 67 insertions(+) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index d4a878c53d..8693b7b26c 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -12,10 +12,14 @@ #include "StdInc.h" #include "Fileapi.h" #include "CModelInfoSA.h" +#include "processthreadsapi.h" CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo(*)[26316])0x8E4CC0; HANDLE (&CStreamingSA::m_aStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; // Contains open files CArchiveInfo (&CStreamingSA::ms_aAchiveInfo)[8] = *(CArchiveInfo(*)[8])0x8E48D8; // [8][0x30] +HANDLE* phStreamingThread = (HANDLE*)0x8E4008; +uint32 (&CStreamingSA::ms_streamingBufferSize) = *(uint32*)0x8E4CA8; +int (&CStreamingSA::ms_pStreamingBuffer)[2] = *(int (*)[2])0x8E4CAC; namespace { @@ -247,3 +251,47 @@ void CStreamingSA::RemoveArchive(unsigned char ucArhiveID) CloseHandle(m_aStreamingHandlers[uiStreamHandlerID]); m_aStreamingHandlers[uiStreamHandlerID] = NULL; } + +void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) +{ + if (uiBlockSize <= ms_streamingBufferSize * 2) + return; + + // Close old streaming handle + TerminateThread(*phStreamingThread, 0); + + // Create new buffer + if (uiBlockSize & 1) + uiBlockSize = uiBlockSize++ + 1; + + typedef int(__cdecl * Function_CMemoryMgr_MallocAlign)(uint32 uiCount, uint32 uiAlign); + int iPointer = ((Function_CMemoryMgr_MallocAlign)(0x72F4C0))(uiBlockSize << 11, 2048); + + // Copy data from old buffer to new buffer + MemCpyFast((void*)iPointer, (void*)ms_pStreamingBuffer[0], ms_streamingBufferSize); + MemCpyFast((void*)(iPointer + 1024 * uiBlockSize), (void*)ms_pStreamingBuffer[1], ms_streamingBufferSize); + + ms_streamingBufferSize = uiBlockSize / 2; + + ms_pStreamingBuffer[0] = iPointer; + ms_pStreamingBuffer[1] = iPointer + 2048 * ms_streamingBufferSize; + + int pointer = *(int*)0x8E3FFC; + SGtaStream(&streaming)[5] = *(SGtaStream(*)[5])(pointer); + + streaming[0].lpBuffer = ms_pStreamingBuffer[0]; + streaming[1].lpBuffer = ms_pStreamingBuffer[1]; + + free(reinterpret_cast(ms_pStreamingBuffer[0] - 1)); + + // Create new streming handle + auto pStreamingThreadId = *(LPDWORD)0x8E4000; + HANDLE hStreamingThread = CreateThread(0, 0x10000u, (LPTHREAD_START_ROUTINE)0x406560, 0, 4u, &pStreamingThreadId); + + HANDLE hCurrentThread = GetCurrentThread(); + int iPriority = GetThreadPriority(hCurrentThread); + SetThreadPriority(hStreamingThread, iPriority); + ResumeThread(hStreamingThread); + + phStreamingThread = &hStreamingThread; +} diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 6123f8b0f6..5edaf96d40 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -32,6 +32,21 @@ struct CArchiveInfo DWORD uiStreamHandleId; }; +struct SGtaStream +{ + uint32_t nSectorsOffset; + uint32_t nSectorsToRead; + uint32_t lpBuffer; + uint8_t bUnknow1; + uint8_t bLocked; + uint8_t bInUse; + uint8_t bUnknow2; + uint32_t uiStatus; + uint32_t handle; + uint32_t file; + uint8_t pad[20]; +}; +static_assert(sizeof(SGtaStream) == 0x30, "Invalid size for SGtaStream"); class CStreamingSA : public CStreaming { @@ -50,8 +65,11 @@ class CStreamingSA : public CStreaming unsigned char GetUnusedStreamHandle(); unsigned char AddArchive(const char* szFilePath); void RemoveArchive(unsigned char ucStreamHandler); + void SetStreamingBufferSize(uint32 uiSize); private: + static int (&ms_pStreamingBuffer)[2]; + static uint32 (&ms_streamingBufferSize); static CStreamingInfo (&ms_aInfoForModel)[26316]; static HANDLE (&m_aStreamingHandlers)[32]; static CArchiveInfo (&ms_aAchiveInfo)[8]; diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 450ce85f03..977ddba2d7 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -38,4 +38,5 @@ class CStreaming virtual unsigned char AddArchive(const char* szFilePath) = 0; virtual void RemoveArchive(unsigned char ucArchiveID) = 0; virtual void SetStreamingInfo(unsigned int id, unsigned char usStreamID, unsigned int uiOffset, unsigned short usSize, unsigned int uiNextInImg = -1) = 0; + virtual void SetStreamingBufferSize(uint32 uiSize) = 0; }; From d7b0a4ba181fee9be2dd713663cae34e64ea68f0 Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 11 Apr 2021 21:07:01 +0300 Subject: [PATCH 65/78] Increase buffer size for new streamed img archive --- Client/mods/deathmatch/logic/CClientIMG.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 5cc985bd10..8a0e3d51e5 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -161,6 +161,12 @@ bool CClientIMG::StreamEnable() if (IsStreamed()) return false; + ushort usRequestStreamSize = 0; + for (const auto& fileInfo : m_fileInfos) + usRequestStreamSize = Max(usRequestStreamSize, fileInfo.usSize); + + g_pGame->GetStreaming()->SetStreamingBufferSize(usRequestStreamSize); + m_ucArchiveID = g_pGame->GetStreaming()->AddArchive(m_filePath.c_str()); return IsStreamed(); } From a003e33104629f31175223d6204047bc5e405358 Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 11 Apr 2021 21:17:33 +0300 Subject: [PATCH 66/78] Replace variable name --- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 265c2ce206..9ba8b62dc5 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -537,7 +537,7 @@ int CLuaEngineDefs::EngineImportTXD(lua_State* luaVM) return 1; } -CClientIMG* CLuaEngineDefs::EngineLoadIMG(lua_State* const luaVM, std::string strFilePath) +CClientIMG* CLuaEngineDefs::EngineLoadIMG(lua_State* const luaVM, std::string strRelativeFilePath) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); if (!pLuaMain) @@ -550,7 +550,7 @@ CClientIMG* CLuaEngineDefs::EngineLoadIMG(lua_State* const luaVM, std::string st std::string strFullPath; - if (CResourceManager::ParseResourcePathInput(strFilePath, pResource, &strFullPath)) + if (CResourceManager::ParseResourcePathInput(strRelativeFilePath, pResource, &strFullPath)) { // Grab the resource root entity CClientEntity* pRoot = pResource->GetResourceIMGRoot(); From 93bb9165121be359e83296c3d04f97b9f366dc3c Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 11 Apr 2021 21:28:09 +0300 Subject: [PATCH 67/78] Remove unnecessary check --- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 9ba8b62dc5..b93e269ec7 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -540,8 +540,6 @@ int CLuaEngineDefs::EngineImportTXD(lua_State* luaVM) CClientIMG* CLuaEngineDefs::EngineLoadIMG(lua_State* const luaVM, std::string strRelativeFilePath) { CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM); - if (!pLuaMain) - return false; // Get the resource we belong to CResource* pResource = pLuaMain->GetResource(); From 55d69e25804c628297c1f2097f2a67d52d5070b5 Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 11 Apr 2021 21:35:38 +0300 Subject: [PATCH 68/78] Used std --- .../mods/deathmatch/logic/CClientIMGManager.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.cpp b/Client/mods/deathmatch/logic/CClientIMGManager.cpp index 48227116dc..6aa3624c77 100644 --- a/Client/mods/deathmatch/logic/CClientIMGManager.cpp +++ b/Client/mods/deathmatch/logic/CClientIMGManager.cpp @@ -59,20 +59,7 @@ void CClientIMGManager::RemoveAll() bool CClientIMGManager::Exists(CClientIMG* pIMG) { - // Matches given IMG? - std::list::iterator iter = m_List.begin(); - for (; iter != m_List.end(); iter++) - { - // Match? - if (pIMG == *iter) - { - // It exists - return true; - } - } - - // It doesn't - return false; + return std::find(m_List.begin(), m_List.end(), pIMG) != m_List.end(); } CClientIMG* CClientIMGManager::GetElementThatLinked(unsigned int uiModel) From 5160cc7b728bb26627cfb686413413e0bb7423d2 Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 11 Apr 2021 21:43:40 +0300 Subject: [PATCH 69/78] engineImageGetFileList to engineImageGetFiles --- Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index b93e269ec7..22dfdee9d9 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -59,7 +59,7 @@ void CLuaEngineDefs::LoadFunctions() {"engineAddImage", ArgumentParser}, {"engineRemoveImage", ArgumentParser}, {"engineImageGetFilesCount", ArgumentParser}, - {"engineImageGetFileList", ArgumentParser}, + {"engineImageGetFiles", ArgumentParser}, {"engineImageGetFile", ArgumentParser}, {"engineGetModelTXDID", ArgumentParser}, @@ -140,7 +140,7 @@ void CLuaEngineDefs::AddEngineImgClass(lua_State* luaVM) lua_classfunction(luaVM, "add", "engineAddImage"); lua_classfunction(luaVM, "remove", "engineRemoveImage"); lua_classfunction(luaVM, "getFile", "engineImageGetFile"); - lua_classfunction(luaVM, "getFileList", "engineImageGetFileList"); + lua_classfunction(luaVM, "getFiles", "engineImageGetFiles"); lua_classfunction(luaVM, "getFilesCount", "engineImageGetFilesCount"); lua_classfunction(luaVM, "linkTXD", "engineImageLinkTXD"); lua_classfunction(luaVM, "linkDFF", "engineImageLinkDFF"); From feb67b47770c60a39eb371cf40d52a535769073f Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 11 Apr 2021 21:51:07 +0300 Subject: [PATCH 70/78] Removed unnecessary headers content --- Client/mods/deathmatch/logic/CClientIMGManager.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.h b/Client/mods/deathmatch/logic/CClientIMGManager.h index a32de1562d..7daaa3bb20 100644 --- a/Client/mods/deathmatch/logic/CClientIMGManager.h +++ b/Client/mods/deathmatch/logic/CClientIMGManager.h @@ -32,9 +32,6 @@ class CClientIMGManager bool RestoreModel(unsigned int uiModel); static bool IsLinkableModel(unsigned int uiModel); - std::list::const_iterator IterBegin() { return m_List.begin(); } - std::list::const_iterator IterEnd() { return m_List.end(); } - private: void AddToList(CClientIMG* pIMG) { m_List.push_back(pIMG); } void RemoveFromList(CClientIMG* pIMG); From 26785d6c2c091a62ad21e427f55c91aad9d346b9 Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Mon, 12 Apr 2021 18:39:25 +0300 Subject: [PATCH 71/78] Used void* for buffers --- Client/game_sa/CStreamingSA.cpp | 25 +++++++++++++------------ Client/game_sa/CStreamingSA.h | 4 ++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 8693b7b26c..39f30de2fa 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -19,7 +19,7 @@ HANDLE (&CStreamingSA::m_aStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; // CArchiveInfo (&CStreamingSA::ms_aAchiveInfo)[8] = *(CArchiveInfo(*)[8])0x8E48D8; // [8][0x30] HANDLE* phStreamingThread = (HANDLE*)0x8E4008; uint32 (&CStreamingSA::ms_streamingBufferSize) = *(uint32*)0x8E4CA8; -int (&CStreamingSA::ms_pStreamingBuffer)[2] = *(int (*)[2])0x8E4CAC; +void* (&CStreamingSA::ms_pStreamingBuffer)[2] = *(void*(*)[2])0x8E4CAC; namespace { @@ -264,29 +264,30 @@ void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) if (uiBlockSize & 1) uiBlockSize = uiBlockSize++ + 1; - typedef int(__cdecl * Function_CMemoryMgr_MallocAlign)(uint32 uiCount, uint32 uiAlign); - int iPointer = ((Function_CMemoryMgr_MallocAlign)(0x72F4C0))(uiBlockSize << 11, 2048); + typedef void*(__cdecl * Function_CMemoryMgr_MallocAlign)(uint32 uiCount, uint32 uiAlign); + void* pNewBuffer = ((Function_CMemoryMgr_MallocAlign)(0x72F4C0))(uiBlockSize << 11, 2048); // Copy data from old buffer to new buffer - MemCpyFast((void*)iPointer, (void*)ms_pStreamingBuffer[0], ms_streamingBufferSize); - MemCpyFast((void*)(iPointer + 1024 * uiBlockSize), (void*)ms_pStreamingBuffer[1], ms_streamingBufferSize); + MemCpyFast(pNewBuffer, (void*)ms_pStreamingBuffer[0], ms_streamingBufferSize); + MemCpyFast((void*)(reinterpret_cast(pNewBuffer) + 1024 * uiBlockSize), (void*)ms_pStreamingBuffer[1], ms_streamingBufferSize); + + typedef void(__cdecl * Function_CMemoryMgr_FreeAlign)(void* pos); + ((Function_CMemoryMgr_FreeAlign)(0x72F4F0))(ms_pStreamingBuffer[0]); ms_streamingBufferSize = uiBlockSize / 2; - ms_pStreamingBuffer[0] = iPointer; - ms_pStreamingBuffer[1] = iPointer + 2048 * ms_streamingBufferSize; + ms_pStreamingBuffer[0] = pNewBuffer; + ms_pStreamingBuffer[1] = (void*)(reinterpret_cast(pNewBuffer) + 1024 * uiBlockSize); int pointer = *(int*)0x8E3FFC; SGtaStream(&streaming)[5] = *(SGtaStream(*)[5])(pointer); - streaming[0].lpBuffer = ms_pStreamingBuffer[0]; - streaming[1].lpBuffer = ms_pStreamingBuffer[1]; - - free(reinterpret_cast(ms_pStreamingBuffer[0] - 1)); + streaming[0].pBuffer = ms_pStreamingBuffer[0]; + streaming[1].pBuffer = ms_pStreamingBuffer[1]; // Create new streming handle auto pStreamingThreadId = *(LPDWORD)0x8E4000; - HANDLE hStreamingThread = CreateThread(0, 0x10000u, (LPTHREAD_START_ROUTINE)0x406560, 0, 4u, &pStreamingThreadId); + HANDLE hStreamingThread = CreateThread(0, 0x10000u, (LPTHREAD_START_ROUTINE)0x406560, 0, 4u, &pStreamingThreadId); HANDLE hCurrentThread = GetCurrentThread(); int iPriority = GetThreadPriority(hCurrentThread); diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index 5edaf96d40..b0280bd5d2 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -36,7 +36,7 @@ struct SGtaStream { uint32_t nSectorsOffset; uint32_t nSectorsToRead; - uint32_t lpBuffer; + void* pBuffer; uint8_t bUnknow1; uint8_t bLocked; uint8_t bInUse; @@ -68,7 +68,7 @@ class CStreamingSA : public CStreaming void SetStreamingBufferSize(uint32 uiSize); private: - static int (&ms_pStreamingBuffer)[2]; + static void* (&ms_pStreamingBuffer)[2]; static uint32 (&ms_streamingBufferSize); static CStreamingInfo (&ms_aInfoForModel)[26316]; static HANDLE (&m_aStreamingHandlers)[32]; From ff1f03c14efd4a638f20e942e1e1f38917a3667c Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 25 Apr 2021 01:41:43 +0300 Subject: [PATCH 72/78] Allow decrease buffer size --- Client/game_sa/CStreamingSA.cpp | 9 ++++--- Client/game_sa/CStreamingSA.h | 1 + Client/mods/deathmatch/logic/CClientGame.cpp | 3 +++ Client/mods/deathmatch/logic/CClientIMG.cpp | 25 +++++++++++++------ Client/mods/deathmatch/logic/CClientIMG.h | 2 ++ .../deathmatch/logic/CClientIMGManager.cpp | 20 +++++++++++++++ .../mods/deathmatch/logic/CClientIMGManager.h | 3 +++ Client/sdk/game/CStreaming.h | 1 + 8 files changed, 52 insertions(+), 12 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 39f30de2fa..f5e688777b 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -254,7 +254,7 @@ void CStreamingSA::RemoveArchive(unsigned char ucArhiveID) void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) { - if (uiBlockSize <= ms_streamingBufferSize * 2) + if (uiBlockSize == ms_streamingBufferSize * 2) return; // Close old streaming handle @@ -262,14 +262,15 @@ void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) // Create new buffer if (uiBlockSize & 1) - uiBlockSize = uiBlockSize++ + 1; + uiBlockSize++; typedef void*(__cdecl * Function_CMemoryMgr_MallocAlign)(uint32 uiCount, uint32 uiAlign); void* pNewBuffer = ((Function_CMemoryMgr_MallocAlign)(0x72F4C0))(uiBlockSize << 11, 2048); // Copy data from old buffer to new buffer - MemCpyFast(pNewBuffer, (void*)ms_pStreamingBuffer[0], ms_streamingBufferSize); - MemCpyFast((void*)(reinterpret_cast(pNewBuffer) + 1024 * uiBlockSize), (void*)ms_pStreamingBuffer[1], ms_streamingBufferSize); + uint uiCopySize = std::min(ms_streamingBufferSize, uiBlockSize / 2); + MemCpyFast(pNewBuffer, (void*)ms_pStreamingBuffer[0], uiCopySize); + MemCpyFast((void*)(reinterpret_cast(pNewBuffer) + 1024 * uiBlockSize), (void*)ms_pStreamingBuffer[1], uiCopySize); typedef void(__cdecl * Function_CMemoryMgr_FreeAlign)(void* pos); ((Function_CMemoryMgr_FreeAlign)(0x72F4F0))(ms_pStreamingBuffer[0]); diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index b0280bd5d2..f6abbd5d1b 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -66,6 +66,7 @@ class CStreamingSA : public CStreaming unsigned char AddArchive(const char* szFilePath); void RemoveArchive(unsigned char ucStreamHandler); void SetStreamingBufferSize(uint32 uiSize); + uint32 GetStreamingBufferSize() { return ms_streamingBufferSize * 2; }; private: static void* (&ms_pStreamingBuffer)[2]; diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index e5250402cd..e58f1bd00f 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -1183,6 +1183,9 @@ void CClientGame::DoPulses() // Initialize the game g_pCore->GetGame()->Initialize(); + + // Save default streamer buffer size in IMG manager + m_pManager->GetIMGManager()->InitDefaultBufferSize(); } unsigned char ucError = g_pNet->GetConnectionError(); diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 8a0e3d51e5..8e82092345 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -10,7 +10,6 @@ #include - #define INVALID_ARCHIVE_ID 0xFF struct tImgHeader @@ -23,7 +22,8 @@ CClientIMG::CClientIMG(class CClientManager* pManager, ElementID ID) : ClassInit(this), CClientEntity(ID), m_pImgManager(pManager->GetIMGManager()), - m_ucArchiveID(INVALID_ARCHIVE_ID) + m_ucArchiveID(INVALID_ARCHIVE_ID), + m_usRequiredBufferSize(0) { m_pManager = pManager; SetTypeName("img"); @@ -161,14 +161,20 @@ bool CClientIMG::StreamEnable() if (IsStreamed()) return false; - ushort usRequestStreamSize = 0; - for (const auto& fileInfo : m_fileInfos) - usRequestStreamSize = Max(usRequestStreamSize, fileInfo.usSize); - - g_pGame->GetStreaming()->SetStreamingBufferSize(usRequestStreamSize); + if (m_usRequiredBufferSize == 0) + { + for (const auto& fileInfo : m_fileInfos) + m_usRequiredBufferSize = Max(m_usRequiredBufferSize, fileInfo.usSize); + } m_ucArchiveID = g_pGame->GetStreaming()->AddArchive(m_filePath.c_str()); - return IsStreamed(); + + if (IsStreamed()) + { + m_pImgManager->UpdateStreamerBufferSize(); + return true; + } + return false; } bool CClientIMG::StreamDisable() @@ -190,6 +196,9 @@ bool CClientIMG::StreamDisable() g_pGame->GetStreaming()->RemoveArchive(m_ucArchiveID); m_ucArchiveID = INVALID_ARCHIVE_ID; + m_pImgManager->UpdateStreamerBufferSize(); + + g_pClientGame->RestreamWorld(); return true; } diff --git a/Client/mods/deathmatch/logic/CClientIMG.h b/Client/mods/deathmatch/logic/CClientIMG.h index 7d120126ac..e3260f9b4a 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.h +++ b/Client/mods/deathmatch/logic/CClientIMG.h @@ -61,6 +61,7 @@ class CClientIMG : public CClientEntity unsigned char GetArchiveID() { return m_ucArchiveID; } unsigned int GetFilesCount() { return m_fileInfos.size(); } const auto& GetFileInfos() const noexcept { return m_fileInfos; } + unsigned short GetRequiredBufferSize() { return m_usRequiredBufferSize; } bool Load(fs::path filePath); void Unload(); @@ -83,6 +84,7 @@ class CClientIMG : public CClientEntity std::string m_filePath; unsigned char m_ucArchiveID; std::vector m_fileInfos; + unsigned short m_usRequiredBufferSize; std::vector m_restoreInfo; }; diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.cpp b/Client/mods/deathmatch/logic/CClientIMGManager.cpp index 6aa3624c77..107aca16ea 100644 --- a/Client/mods/deathmatch/logic/CClientIMGManager.cpp +++ b/Client/mods/deathmatch/logic/CClientIMGManager.cpp @@ -22,6 +22,11 @@ CClientIMGManager::~CClientIMGManager() RemoveAll(); } +void CClientIMGManager::InitDefaultBufferSize() +{ + m_uiDefaultStreamerBufferSize = g_pGame->GetStreaming()->GetStreamingBufferSize(); +} + CClientIMG* CClientIMGManager::GetElementFromArchiveID(unsigned char ucArchiveID) { // By default GTA has 5 IMG's @@ -95,3 +100,18 @@ void CClientIMGManager::RemoveFromList(CClientIMG* pIMG) m_List.remove(pIMG); } } + +void CClientIMGManager::UpdateStreamerBufferSize() +{ + ushort usRequestStreamSize = m_uiDefaultStreamerBufferSize; + + for (const auto& pImg : m_List) + { + if (!pImg->IsStreamed()) + continue; + ushort usStreamSize = pImg->GetRequiredBufferSize(); + if (usStreamSize > usRequestStreamSize) + usRequestStreamSize = usStreamSize; + } + g_pGame->GetStreaming()->SetStreamingBufferSize(usRequestStreamSize); +} diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.h b/Client/mods/deathmatch/logic/CClientIMGManager.h index 7daaa3bb20..706b8476a2 100644 --- a/Client/mods/deathmatch/logic/CClientIMGManager.h +++ b/Client/mods/deathmatch/logic/CClientIMGManager.h @@ -23,6 +23,7 @@ class CClientIMGManager CClientIMGManager(class CClientManager* pManager); ~CClientIMGManager(); + void InitDefaultBufferSize(); void RemoveAll(); bool Exists(CClientIMG* pIMG); @@ -31,6 +32,7 @@ class CClientIMGManager bool RestoreModel(unsigned int uiModel); static bool IsLinkableModel(unsigned int uiModel); + void UpdateStreamerBufferSize(); private: void AddToList(CClientIMG* pIMG) { m_List.push_back(pIMG); } @@ -38,4 +40,5 @@ class CClientIMGManager std::list m_List; bool m_bRemoveFromList; + uint32 m_uiDefaultStreamerBufferSize; }; diff --git a/Client/sdk/game/CStreaming.h b/Client/sdk/game/CStreaming.h index 977ddba2d7..b2fc5407e1 100644 --- a/Client/sdk/game/CStreaming.h +++ b/Client/sdk/game/CStreaming.h @@ -39,4 +39,5 @@ class CStreaming virtual void RemoveArchive(unsigned char ucArchiveID) = 0; virtual void SetStreamingInfo(unsigned int id, unsigned char usStreamID, unsigned int uiOffset, unsigned short usSize, unsigned int uiNextInImg = -1) = 0; virtual void SetStreamingBufferSize(uint32 uiSize) = 0; + virtual uint32 GetStreamingBufferSize() = 0; }; From 0abd8ab735418d74e515982b48be5288fa9f2169 Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 25 Apr 2021 04:52:25 +0300 Subject: [PATCH 73/78] Don't close thread --- Client/game_sa/CStreamingSA.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index f5e688777b..9173484175 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -257,8 +257,8 @@ void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) if (uiBlockSize == ms_streamingBufferSize * 2) return; - // Close old streaming handle - TerminateThread(*phStreamingThread, 0); + // Suspend old streaming handle + SuspendThread(*phStreamingThread); // Create new buffer if (uiBlockSize & 1) @@ -286,14 +286,6 @@ void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) streaming[0].pBuffer = ms_pStreamingBuffer[0]; streaming[1].pBuffer = ms_pStreamingBuffer[1]; - // Create new streming handle - auto pStreamingThreadId = *(LPDWORD)0x8E4000; - HANDLE hStreamingThread = CreateThread(0, 0x10000u, (LPTHREAD_START_ROUTINE)0x406560, 0, 4u, &pStreamingThreadId); - - HANDLE hCurrentThread = GetCurrentThread(); - int iPriority = GetThreadPriority(hCurrentThread); - SetThreadPriority(hStreamingThread, iPriority); - ResumeThread(hStreamingThread); - - phStreamingThread = &hStreamingThread; + // Well done + ResumeThread(*phStreamingThread); } From ea11b4c6d6a8c27a31ada8cd0fc3d9238082a0cf Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 25 Apr 2021 12:46:18 +0300 Subject: [PATCH 74/78] Added additional check --- Client/game_sa/CStreamingSA.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index 9173484175..ae18bd2882 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -257,7 +257,13 @@ void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) if (uiBlockSize == ms_streamingBufferSize * 2) return; - // Suspend old streaming handle + int pointer = *(int*)0x8E3FFC; + SGtaStream(&streaming)[5] = *(SGtaStream(*)[5])(pointer); + + // Wait while streaming threads ends tasks + while (streaming[0].bInUse && streaming[1].bInUse) + + // Suspend streaming handle SuspendThread(*phStreamingThread); // Create new buffer @@ -280,9 +286,6 @@ void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) ms_pStreamingBuffer[0] = pNewBuffer; ms_pStreamingBuffer[1] = (void*)(reinterpret_cast(pNewBuffer) + 1024 * uiBlockSize); - int pointer = *(int*)0x8E3FFC; - SGtaStream(&streaming)[5] = *(SGtaStream(*)[5])(pointer); - streaming[0].pBuffer = ms_pStreamingBuffer[0]; streaming[1].pBuffer = ms_pStreamingBuffer[1]; From d6af906747afad14974f6816119c4a70a6ad27c4 Mon Sep 17 00:00:00 2001 From: Uladzislau Nikalayevich Date: Sun, 25 Apr 2021 13:00:22 +0300 Subject: [PATCH 75/78] Update Client/mods/deathmatch/logic/CClientIMGManager.cpp Co-authored-by: Pirulax --- Client/mods/deathmatch/logic/CClientIMGManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Client/mods/deathmatch/logic/CClientIMGManager.cpp b/Client/mods/deathmatch/logic/CClientIMGManager.cpp index 107aca16ea..d09ab523a1 100644 --- a/Client/mods/deathmatch/logic/CClientIMGManager.cpp +++ b/Client/mods/deathmatch/logic/CClientIMGManager.cpp @@ -105,7 +105,7 @@ void CClientIMGManager::UpdateStreamerBufferSize() { ushort usRequestStreamSize = m_uiDefaultStreamerBufferSize; - for (const auto& pImg : m_List) + for (CClientIMG* pImg : m_List) { if (!pImg->IsStreamed()) continue; From 5407b7e8177f734c93e8574a8b44e9a5680e8bf6 Mon Sep 17 00:00:00 2001 From: Vladislav Nikolaevich Date: Sun, 25 Apr 2021 13:24:24 +0300 Subject: [PATCH 76/78] Added security checks --- Client/mods/deathmatch/logic/CClientIMG.cpp | 5 ----- .../logic/luadefs/CLuaEngineDefs.cpp | 22 +++++++++++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Client/mods/deathmatch/logic/CClientIMG.cpp b/Client/mods/deathmatch/logic/CClientIMG.cpp index 8e82092345..2de63eb84d 100644 --- a/Client/mods/deathmatch/logic/CClientIMG.cpp +++ b/Client/mods/deathmatch/logic/CClientIMG.cpp @@ -54,11 +54,6 @@ bool CClientIMG::Load(fs::path filePath) m_filePath = filePath.string(); m_ifs = std::ifstream(filePath, std::ios::binary); -/* g_pClientGame->GetResourceManager()->ValidateResourceFile(m_strFilename, nullptr, 0); - if (!g_pCore->GetNetwork()->CheckFile("img", m_strFilename)) - return false; -*/ - // Open the file if (m_ifs.fail()) { diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index 22dfdee9d9..e3d3e7d303 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -626,14 +626,32 @@ bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variant= 20000) throw std::invalid_argument(SString("Expected modelid in range 0 - 19999, got %d", uiModelID)); - return pIMG->LinkModel(uiModelID, ResolveIMGFileID(pIMG, file)); + + size_t fileID = ResolveIMGFileID(pIMG, file); + std::string buffer; + if (!pIMG->GetFile(ResolveIMGFileID(pIMG, file), buffer)) + throw std::exception("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); + + if (!g_pCore->GetNetwork()->CheckFile("dff", "", buffer.data(), buffer.size())) + throw std::exception("Failed to link file. Make sure the archieve isn't corrupted."); + + return pIMG->LinkModel(uiModelID, fileID); } bool CLuaEngineDefs::EngineImageLinkTXD(CClientIMG* pIMG, std::variant file, uint uiTxdID) { if (uiTxdID >= 5000) throw std::invalid_argument(SString("Expected txdid in range 0 - 4999, got %d", uiTxdID)); - return pIMG->LinkModel(20000 + uiTxdID, ResolveIMGFileID(pIMG, file)); + + size_t fileID = ResolveIMGFileID(pIMG, file); + std::string buffer; + if (!pIMG->GetFile(ResolveIMGFileID(pIMG, file), buffer)) + throw std::exception("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); + + if (!g_pCore->GetNetwork()->CheckFile("txd", "", buffer.data(), buffer.size())) + throw std::exception("Failed to link file. Make sure the archieve isn't corrupted."); + + return pIMG->LinkModel(20000 + uiTxdID, fileID); } bool CLuaEngineDefs::EngineRestoreDFFImage(uint uiModelID) From e3efe9dbf8291c8b72a282922cdc04a496bab13e Mon Sep 17 00:00:00 2001 From: TheNormalnij Date: Sun, 25 Apr 2021 14:12:08 +0300 Subject: [PATCH 77/78] exception > invalid_argument --- .../mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index e3d3e7d303..eea594ba5c 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -617,7 +617,7 @@ std::string CLuaEngineDefs::EngineImageGetFile(CClientIMG* pIMG, std::variantGetFile(ResolveIMGFileID(pIMG, file), buffer)) // Get file might throw - throw std::exception("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); + throw std::invalid_argument("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); return buffer; } @@ -630,10 +630,10 @@ bool CLuaEngineDefs::EngineImageLinkDFF(CClientIMG* pIMG, std::variantGetFile(ResolveIMGFileID(pIMG, file), buffer)) - throw std::exception("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); + throw std::invalid_argument("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); if (!g_pCore->GetNetwork()->CheckFile("dff", "", buffer.data(), buffer.size())) - throw std::exception("Failed to link file. Make sure the archieve isn't corrupted."); + throw std::invalid_argument("Failed to link file. Make sure the archieve isn't corrupted."); return pIMG->LinkModel(uiModelID, fileID); } @@ -646,10 +646,10 @@ bool CLuaEngineDefs::EngineImageLinkTXD(CClientIMG* pIMG, std::variantGetFile(ResolveIMGFileID(pIMG, file), buffer)) - throw std::exception("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); + throw std::invalid_argument("Failed to read file. Probably EOF reached, make sure the archieve isn't corrupted."); if (!g_pCore->GetNetwork()->CheckFile("txd", "", buffer.data(), buffer.size())) - throw std::exception("Failed to link file. Make sure the archieve isn't corrupted."); + throw std::invalid_argument("Failed to link file. Make sure the archieve isn't corrupted."); return pIMG->LinkModel(20000 + uiTxdID, fileID); } From d390073fc5c4f926fdeb3149f0044ab4a3275c86 Mon Sep 17 00:00:00 2001 From: TheNormalnij Date: Sun, 25 Apr 2021 14:27:36 +0300 Subject: [PATCH 78/78] ms_streamingBufferSize > ms_streamingHalfOfBufferSize --- Client/game_sa/CStreamingSA.cpp | 8 ++++---- Client/game_sa/CStreamingSA.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Client/game_sa/CStreamingSA.cpp b/Client/game_sa/CStreamingSA.cpp index ae18bd2882..13c6bd1e14 100644 --- a/Client/game_sa/CStreamingSA.cpp +++ b/Client/game_sa/CStreamingSA.cpp @@ -18,7 +18,7 @@ CStreamingInfo (&CStreamingSA::ms_aInfoForModel)[26316] = *(CStreamingInfo(*)[26 HANDLE (&CStreamingSA::m_aStreamingHandlers)[32] = *(HANDLE(*)[32])0x8E4010; // Contains open files CArchiveInfo (&CStreamingSA::ms_aAchiveInfo)[8] = *(CArchiveInfo(*)[8])0x8E48D8; // [8][0x30] HANDLE* phStreamingThread = (HANDLE*)0x8E4008; -uint32 (&CStreamingSA::ms_streamingBufferSize) = *(uint32*)0x8E4CA8; +uint32 (&CStreamingSA::ms_streamingHalfOfBufferSize) = *(uint32*)0x8E4CA8; void* (&CStreamingSA::ms_pStreamingBuffer)[2] = *(void*(*)[2])0x8E4CAC; namespace @@ -254,7 +254,7 @@ void CStreamingSA::RemoveArchive(unsigned char ucArhiveID) void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) { - if (uiBlockSize == ms_streamingBufferSize * 2) + if (uiBlockSize == ms_streamingHalfOfBufferSize * 2) return; int pointer = *(int*)0x8E3FFC; @@ -274,14 +274,14 @@ void CStreamingSA::SetStreamingBufferSize(uint32 uiBlockSize) void* pNewBuffer = ((Function_CMemoryMgr_MallocAlign)(0x72F4C0))(uiBlockSize << 11, 2048); // Copy data from old buffer to new buffer - uint uiCopySize = std::min(ms_streamingBufferSize, uiBlockSize / 2); + uint uiCopySize = std::min(ms_streamingHalfOfBufferSize, uiBlockSize / 2); MemCpyFast(pNewBuffer, (void*)ms_pStreamingBuffer[0], uiCopySize); MemCpyFast((void*)(reinterpret_cast(pNewBuffer) + 1024 * uiBlockSize), (void*)ms_pStreamingBuffer[1], uiCopySize); typedef void(__cdecl * Function_CMemoryMgr_FreeAlign)(void* pos); ((Function_CMemoryMgr_FreeAlign)(0x72F4F0))(ms_pStreamingBuffer[0]); - ms_streamingBufferSize = uiBlockSize / 2; + ms_streamingHalfOfBufferSize = uiBlockSize / 2; ms_pStreamingBuffer[0] = pNewBuffer; ms_pStreamingBuffer[1] = (void*)(reinterpret_cast(pNewBuffer) + 1024 * uiBlockSize); diff --git a/Client/game_sa/CStreamingSA.h b/Client/game_sa/CStreamingSA.h index f6abbd5d1b..4db741fa5e 100644 --- a/Client/game_sa/CStreamingSA.h +++ b/Client/game_sa/CStreamingSA.h @@ -66,11 +66,11 @@ class CStreamingSA : public CStreaming unsigned char AddArchive(const char* szFilePath); void RemoveArchive(unsigned char ucStreamHandler); void SetStreamingBufferSize(uint32 uiSize); - uint32 GetStreamingBufferSize() { return ms_streamingBufferSize * 2; }; + uint32 GetStreamingBufferSize() { return ms_streamingHalfOfBufferSize * 2; }; private: static void* (&ms_pStreamingBuffer)[2]; - static uint32 (&ms_streamingBufferSize); + static uint32 (&ms_streamingHalfOfBufferSize); static CStreamingInfo (&ms_aInfoForModel)[26316]; static HANDLE (&m_aStreamingHandlers)[32]; static CArchiveInfo (&ms_aAchiveInfo)[8];