Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 35 additions & 17 deletions Client/mods/deathmatch/logic/CSingularFileDownload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <StdInc.h>

CSingularFileDownload::CSingularFileDownload(CResource* pResource, const char* szName, const char* szNameShort, SString strHTTPURL, CResource* pRequestResource,
CChecksum serverChecksum)
CChecksum serverChecksum, std::uint32_t handlerId)
{
// Store the name
m_strName = szName;
Expand All @@ -21,23 +21,28 @@ CSingularFileDownload::CSingularFileDownload(CResource* pResource, const char* s
m_strNameShort = szNameShort;

// store resources
m_pResource = pResource;
m_pRequestResource = pRequestResource;
resource = pResource;
requestResource = pRequestResource;

// Store the server checksum
m_ServerChecksum = serverChecksum;

m_bBeingDeleted = false;
beingDeleted = false;
cancelled = false;
handlerId = handlerId;
httpManager = nullptr;
downloadMode = EDownloadMode::NONE;

GenerateClientChecksum();

if (!DoesClientAndServerChecksumMatch())
{
SHttpRequestOptions options;
options.bCheckContents = true;
CNetHTTPDownloadManagerInterface* pHTTP = g_pCore->GetNetwork()->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES);
pHTTP->QueueFile(strHTTPURL.c_str(), szName, this, DownloadFinishedCallBack, options);
m_bComplete = false;
httpManager = g_pCore->GetNetwork()->GetHTTPDownloadManager(EDownloadMode::RESOURCE_SINGULAR_FILES);
downloadMode = EDownloadMode::RESOURCE_SINGULAR_FILES;
httpManager->QueueFile(strHTTPURL.c_str(), szName, this, DownloadFinishedCallBack, options);
complete = false;
g_pClientGame->SetTransferringSingularFiles(true);
}
else
Expand All @@ -61,33 +66,46 @@ void CSingularFileDownload::CallFinished(bool bSuccess)
// Flag file as loadable
g_pClientGame->GetResourceManager()->OnDownloadedResourceFile(GetName());

if (!m_bBeingDeleted && m_pResource)
if (!beingDeleted && resource)
{
// Call the onClientbFileDownloadComplete event
// Call the onClientFileDownloadComplete event
CLuaArguments Arguments;
Arguments.PushString(GetShortName()); // file name
Arguments.PushBoolean(bSuccess); // Completed successfully?
if (m_pRequestResource)
if (requestResource)
{
Arguments.PushResource(m_pRequestResource); // Resource that called downloadFile
Arguments.PushResource(requestResource); // Resource that called downloadFile
}
else
{
Arguments.PushBoolean(false); // or false
}

m_pResource->GetResourceEntity()->CallEvent("onClientFileDownloadComplete", Arguments, false);
resource->GetResourceEntity()->CallEvent("onClientFileDownloadComplete", Arguments, false);
}
SetComplete();
}

void CSingularFileDownload::Cancel()
bool CSingularFileDownload::Cancel()
{
m_bBeingDeleted = true;
m_pResource = NULL;
m_pRequestResource = NULL;
if (cancelled || complete)
return false;

// TODO: Cancel also in Net
cancelled = true;
beingDeleted = true;
resource = nullptr;
requestResource = nullptr;

if (!httpManager || downloadMode == EDownloadMode::NONE)
return true;

const bool httpCancelSuccess = httpManager->CancelDownload(this, DownloadFinishedCallBack);
return httpCancelSuccess;
}

void CSingularFileDownload::MarkForDeletion()
{
beingDeleted = true;
}

bool CSingularFileDownload::DoesClientAndServerChecksumMatch()
Expand Down
32 changes: 21 additions & 11 deletions Client/mods/deathmatch/logic/CSingularFileDownload.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,40 +20,50 @@

#include <bochs_internal/bochs_crc32.h>
#include "CChecksum.h"
#include "net/CNetHTTPDownloadManagerInterface.h"
#include <cstdint>

class CSingularFileDownload
{
public:
CSingularFileDownload(CResource* pResource, const char* szName, const char* szNameShort, SString strHTTPURL, CResource* pRequestResource,
CChecksum serverChecksum);
CChecksum serverChecksum, std::uint32_t handlerId);
~CSingularFileDownload();

static void DownloadFinishedCallBack(const SHttpDownloadResult& result);

bool DoesClientAndServerChecksumMatch();

const char* GetName() { return m_strName; };
const char* GetShortName() { return m_strNameShort; };
const char* GetName() const noexcept { return m_strName; }
const char* GetShortName() const noexcept { return m_strNameShort; }

CResource* GetResource() { return m_pResource; };
CResource* GetResource() const noexcept { return resource; }
std::uint32_t GetHandlerId() const noexcept { return handlerId; }

void SetComplete() { m_bComplete = true; };
bool GetComplete() { return m_bComplete; };
void SetComplete() noexcept { complete = true; }
bool GetComplete() const noexcept { return complete; }
bool IsCancelled() const noexcept { return cancelled; }

void CallFinished(bool bSuccess);
void Cancel();
bool Cancel();
void MarkForDeletion();

CChecksum GenerateClientChecksum();

protected:
SString m_strName;
SString m_strNameShort;

CResource* m_pResource;
CResource* m_pRequestResource;
CResource* resource;
CResource* requestResource;

bool m_bComplete;
bool m_bBeingDeleted;
bool complete;
bool beingDeleted;
bool cancelled;

std::uint32_t handlerId;
CNetHTTPDownloadManagerInterface* httpManager;
EDownloadMode::EDownloadModeType downloadMode;

CChecksum m_LastClientChecksum;
CChecksum m_ServerChecksum;
Expand Down
56 changes: 43 additions & 13 deletions Client/mods/deathmatch/logic/CSingularFileDownloadManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <StdInc.h>
using std::list;

CSingularFileDownloadManager::CSingularFileDownloadManager()
CSingularFileDownloadManager::CSingularFileDownloadManager() : m_nextHandlerId(1)
{
}

Expand All @@ -25,38 +25,68 @@ CSingularFileDownloadManager::~CSingularFileDownloadManager()
CSingularFileDownload* CSingularFileDownloadManager::AddFile(CResource* pResource, const char* szName, const char* szNameShort, SString strHTTPURL,
CResource* pRequestResource, CChecksum checksum)
{
CSingularFileDownload* pFile = new CSingularFileDownload(pResource, szName, szNameShort, strHTTPURL, pRequestResource, checksum);
const std::uint32_t handlerId = m_nextHandlerId++;
auto* pFile = new CSingularFileDownload(pResource, szName, szNameShort, strHTTPURL, pRequestResource, checksum, handlerId);
m_Downloads.push_back(pFile);
return NULL;
m_HandlerMap[handlerId] = pFile;
return pFile;
}

void CSingularFileDownloadManager::CancelResourceDownloads(CResource* pResource)
{
list<CSingularFileDownload*>::const_iterator iter = m_Downloads.begin();
for (; iter != m_Downloads.end(); ++iter)
for (const auto& pDownload : m_Downloads)
{
if ((*iter)->GetResource() == pResource)
(*iter)->Cancel();
if (pDownload->GetResource() == pResource)
pDownload->Cancel();
}
}

void CSingularFileDownloadManager::ClearList()
{
list<CSingularFileDownload*>::const_iterator iter = m_Downloads.begin();
for (; iter != m_Downloads.end(); ++iter)
for (const auto& pDownload : m_Downloads)
{
delete *iter;
delete pDownload;
}
m_Downloads.clear();
m_HandlerMap.clear();
}

bool CSingularFileDownloadManager::AllComplete()
{
list<CSingularFileDownload*>::const_iterator iter = m_Downloads.begin();
for (; iter != m_Downloads.end(); ++iter)
for (const auto& pDownload : m_Downloads)
{
if (!(*iter)->GetComplete())
if (!pDownload->GetComplete())
return false;
}
return true;
}

CSingularFileDownload* CSingularFileDownloadManager::FindDownloadByHandler(std::uint32_t handlerId) const
{
const auto it = m_HandlerMap.find(handlerId);
return (it != m_HandlerMap.end()) ? it->second : nullptr;
}

bool CSingularFileDownloadManager::AbortDownload(std::uint32_t handlerId)
{
auto* pDownload = FindDownloadByHandler(handlerId);
if (!pDownload)
return false;

if (pDownload->GetComplete() || pDownload->IsCancelled())
return false;

const bool success = pDownload->Cancel();
RemoveDownload(pDownload);
return success;
}

void CSingularFileDownloadManager::RemoveDownload(CSingularFileDownload* pDownload)
{
if (!pDownload)
return;

m_HandlerMap.erase(pDownload->GetHandlerId());
m_Downloads.remove(pDownload);
pDownload->MarkForDeletion();
}
8 changes: 8 additions & 0 deletions Client/mods/deathmatch/logic/CSingularFileDownloadManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <bochs_internal/bochs_crc32.h>
#include "CChecksum.h"
#include "CSingularFileDownload.h"
#include <map>
#include <cstdint>

class CSingularFileDownloadManager
{
Expand All @@ -36,6 +38,12 @@ class CSingularFileDownloadManager

bool AllComplete();

CSingularFileDownload* FindDownloadByHandler(std::uint32_t handlerId) const;
bool AbortDownload(std::uint32_t handlerId);
void RemoveDownload(CSingularFileDownload* pDownload);

protected:
std::list<CSingularFileDownload*> m_Downloads;
std::map<std::uint32_t, CSingularFileDownload*> m_HandlerMap;
std::uint32_t m_nextHandlerId;
};
7 changes: 3 additions & 4 deletions Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,18 +233,17 @@ bool CStaticFunctionDefinitions::WasEventCancelled()
return m_pEvents->WasEventCancelled();
}

bool CStaticFunctionDefinitions::DownloadFile(CResource* pResource, const char* szFile, CResource* pRequestResource, CChecksum checksum)
CSingularFileDownload* CStaticFunctionDefinitions::DownloadFile(CResource* pResource, const char* szFile, CResource* pRequestResource, CChecksum checksum)
{
SString strHTTPDownloadURLFull("%s/%s/%s", g_pClientGame->GetHTTPURL().c_str(), pResource->GetName(), szFile);
SString strPath("%s\\resources\\%s\\%s", g_pClientGame->GetFileCacheRoot(), pResource->GetName(), szFile);

// Call SingularFileDownloadManager
if (g_pClientGame->GetSingularFileDownloadManager())
{
g_pClientGame->GetSingularFileDownloadManager()->AddFile(pResource, strPath.c_str(), szFile, strHTTPDownloadURLFull, pRequestResource, checksum);
return true;
return g_pClientGame->GetSingularFileDownloadManager()->AddFile(pResource, strPath.c_str(), szFile, strHTTPDownloadURLFull, pRequestResource, checksum);
}
return false;
return nullptr;
}

bool CStaticFunctionDefinitions::OutputConsole(const char* szText)
Expand Down
5 changes: 4 additions & 1 deletion Client/mods/deathmatch/logic/CStaticFunctionDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class CStaticFunctionDefinitions;
#include "enums/WeaponProperty.h"
#include "enums/ObjectProperty.h"

// Forward declarations
class CSingularFileDownload;

class CStaticFunctionDefinitions
{
public:
Expand All @@ -39,7 +42,7 @@ class CStaticFunctionDefinitions
static bool WasEventCancelled();

// Misc funcs
static bool DownloadFile(CResource* pResource, const char* szFile, CResource* pRequestResource, CChecksum checksum = CChecksum());
static CSingularFileDownload* DownloadFile(CResource* pResource, const char* szFile, CResource* pRequestResource, CChecksum checksum = CChecksum());

// Output funcs
static bool OutputConsole(const char* szText);
Expand Down
58 changes: 55 additions & 3 deletions Client/mods/deathmatch/logic/lua/CLuaFunctionDefs.Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,14 @@ int CLuaFunctionDefs::DownloadFile(lua_State* luaVM)

if (!argStream.HasErrors())
{
// Validate that the file input is not empty
if (strFileInput.empty())
{
m_pScriptDebugging->LogCustom(luaVM, "Expected non-empty string, got empty string");
lua_pushboolean(luaVM, false);
return 1;
}

// Grab our VM
CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM);
if (pLuaMain)
Expand All @@ -390,10 +398,12 @@ int CLuaFunctionDefs::DownloadFile(lua_State* luaVM)
{
if (strcmp(strMetaPath, (*iter)->GetShortName()) == 0)
{
if (CStaticFunctionDefinitions::DownloadFile(pOtherResource, strMetaPath, pThisResource, (*iter)->GetServerChecksum()))
CSingularFileDownload* pDownload = CStaticFunctionDefinitions::DownloadFile(pOtherResource, strMetaPath, pThisResource, (*iter)->GetServerChecksum());
if (pDownload)
{
lua_pushboolean(luaVM, true);
return 1;
lua_pushuserdata(luaVM, pDownload);
lua_pushnumber(luaVM, pDownload->GetHandlerId());
return 2;
}
}
}
Expand All @@ -409,6 +419,48 @@ int CLuaFunctionDefs::DownloadFile(lua_State* luaVM)
return 1;
}

int CLuaFunctionDefs::AbortDownload(lua_State* luaVM)
{
// bool abortDownload(number handlerId)
std::uint32_t handlerId = 0;
CScriptArgReader argStream(luaVM);

// Check if argument is a number first
if (!argStream.NextIsNumber())
{
m_pScriptDebugging->LogCustom(luaVM, SString("Expected number, got %s", lua_typename(luaVM, lua_type(luaVM, 1))));
lua_pushboolean(luaVM, false);
return 1;
}

argStream.ReadNumber(handlerId);

if (!argStream.HasErrors())
{
// Validate that handlerId is positive
if (handlerId <= 0)
{
m_pScriptDebugging->LogCustom(luaVM, SString("Expected positive value, got %d", handlerId));
lua_pushboolean(luaVM, false);
return 1;
}

if (g_pClientGame->GetSingularFileDownloadManager())
{
const bool success = g_pClientGame->GetSingularFileDownloadManager()->AbortDownload(handlerId);
lua_pushboolean(luaVM, success);
return 1;
}
}
else
{
m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage());
}

lua_pushboolean(luaVM, false);
return 1;
}

int CLuaFunctionDefs::AddDebugHook(lua_State* luaVM)
{
// bool AddDebugHook ( string hookType, function callback[, table allowedNames ] )
Expand Down
Loading