Reconstruct readable C++ and organize cohesive source subsystems
Administrative source import: native x86 compilation passed for 423 authored units. Source placement and submission states are migrated separately; this commit does not imply peer acceptance.
Previous head: 35d2a8cb36
Payload SHA256: 592f016d2730c5593bb653aa054c1e5f76a6df72c8f5a09e66f74876e2e33dee
This commit is contained in:
parent
35d2a8cb36
commit
a47d20f8be
890 changed files with 11796 additions and 16664 deletions
127
Source/Contents/Emblems/EmblemCache.cpp
Normal file
127
Source/Contents/Emblems/EmblemCache.cpp
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
#include "Contents/Emblems/EmblemCache.h"
|
||||
#include "UI/Window/UIWindow.h"
|
||||
#include "UI/Window/WindowManagerWindows.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <sys/stat.h>
|
||||
#include <windows.h>
|
||||
#include <zlib.h>
|
||||
|
||||
namespace {
|
||||
std::string Basename(std::string path) {
|
||||
const auto separator = path.rfind('\\');
|
||||
|
||||
if (separator != std::string::npos) {
|
||||
return path.substr(separator + 1);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x0065ED00
|
||||
// FUNCTION: fn_05178
|
||||
std::string EmblemCache::Filename(std::uint32_t guild, std::uint32_t revision) const {
|
||||
std::ostringstream name;
|
||||
name << this->accountName << '_' << guild << '_' << (revision + 0x7FFFFFFFu) << ".ebm";
|
||||
return name.str();
|
||||
}
|
||||
|
||||
// OFFSET: 0x0065E6F0
|
||||
// FUNCTION: fn_05176
|
||||
bool EmblemCache::IsInvalid(std::string path) const {
|
||||
return this->invalid.contains(Basename(path));
|
||||
}
|
||||
|
||||
// OFFSET: 0x0065DFB0
|
||||
// FUNCTION: fn_05171
|
||||
void EmblemCache::MarkInvalid(std::string path) {
|
||||
this->invalid.insert(Basename(path));
|
||||
}
|
||||
|
||||
// OFFSET: 0x0065E890
|
||||
// FUNCTION: fn_05177
|
||||
void EmblemCache::Store(const void* bytes, std::uint32_t size, std::uint32_t guild, std::uint32_t revision) {
|
||||
const std::string directory = std::string(this->rootDirectory) + "\\_tmpEmblem\\";
|
||||
const std::string filename = this->Filename(guild, revision);
|
||||
uLongf compressedSize = compressBound(size);
|
||||
std::unique_ptr<unsigned char[]> compressed(new unsigned char[compressedSize]);
|
||||
|
||||
if (compress(compressed.get(), &compressedSize, static_cast<const Bytef*>(bytes), size) != Z_OK) {
|
||||
this->MarkInvalid(filename);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_access(directory.c_str(), 0) != 0 && _mkdir(directory.c_str()) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream pattern;
|
||||
pattern << this->accountName << '_' << guild << "_*.ebm";
|
||||
WIN32_FIND_DATAA found{};
|
||||
const HANDLE search = FindFirstFileA((directory + pattern.str()).c_str(), &found);
|
||||
std::list<std::string> names;
|
||||
|
||||
if (search != INVALID_HANDLE_VALUE) {
|
||||
do {
|
||||
if (std::strcmp(found.cFileName, ".") != 0 && std::strcmp(found.cFileName, "..") != 0) {
|
||||
names.emplace_back(found.cFileName);
|
||||
}
|
||||
} while (FindNextFileA(search, &found));
|
||||
}
|
||||
|
||||
FindClose(search);
|
||||
|
||||
for (const std::string& name : names) {
|
||||
const std::string path = directory + name;
|
||||
_chmod(path.c_str(), _S_IWRITE);
|
||||
_unlink(path.c_str());
|
||||
}
|
||||
|
||||
const std::string path = directory + filename;
|
||||
FILE* file = std::fopen(path.c_str(), "wb");
|
||||
|
||||
if (file) {
|
||||
std::fwrite(compressed.get(), compressedSize, 1, file);
|
||||
std::fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00D588E0
|
||||
// FUNCTION: fn_21954
|
||||
void EmblemCache::Receive(std::uint16_t state, std::uint32_t guild, std::uint32_t revision, const unsigned char* bytes, int size) {
|
||||
if (state == 0) {
|
||||
this->guildId = guild;
|
||||
this->version = revision;
|
||||
this->data.clear();
|
||||
} else if (state == 1) {
|
||||
if (guild == this->guildId && revision == this->version) {
|
||||
this->data.insert(this->data.end(), bytes, bytes + size);
|
||||
}
|
||||
} else if (state == 2 && guild == this->guildId && revision == this->version) {
|
||||
this->Store(this->data.data(), static_cast<std::uint32_t>(this->data.size()), guild, revision);
|
||||
this->Refresh(guild);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x0065EE50
|
||||
// FUNCTION: fn_05180
|
||||
void EmblemCache::Refresh(std::uint32_t guild) {
|
||||
if (this->modeWindows) {
|
||||
for (UIWindow* window : *this->modeWindows) {
|
||||
window->SendMsg(nullptr, 60, guild, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
UIWindow* window = this->windows.LookupWindow(60);
|
||||
|
||||
if (window) {
|
||||
window->Invalidate();
|
||||
}
|
||||
}
|
||||
31
Source/Contents/Emblems/EmblemCache.h
Normal file
31
Source/Contents/Emblems/EmblemCache.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMCACHE_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMCACHE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class UIWindow;
|
||||
class WindowManagerWindows;
|
||||
|
||||
struct EmblemCache {
|
||||
std::uint32_t& guildId;
|
||||
std::uint32_t& version;
|
||||
std::vector<unsigned char>& data;
|
||||
std::set<std::string>& invalid;
|
||||
const std::string& accountName;
|
||||
const char* rootDirectory;
|
||||
const std::list<UIWindow*>* const& modeWindows;
|
||||
WindowManagerWindows& windows;
|
||||
|
||||
std::string Filename(std::uint32_t guild, std::uint32_t revision) const;
|
||||
bool IsInvalid(std::string path) const;
|
||||
void MarkInvalid(std::string path);
|
||||
void Store(const void* bytes, std::uint32_t size, std::uint32_t guild, std::uint32_t revision);
|
||||
void Receive(std::uint16_t state, std::uint32_t guild, std::uint32_t revision, const unsigned char* bytes, int size);
|
||||
void Refresh(std::uint32_t guild);
|
||||
};
|
||||
|
||||
#endif
|
||||
86
Source/Contents/Emblems/EmblemDataDownloadAsyncWork.cpp
Normal file
86
Source/Contents/Emblems/EmblemDataDownloadAsyncWork.cpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#include "Contents/Emblems/EmblemDataDownloadAsyncWork.h"
|
||||
#include "Contents/Emblems/EmblemDownload.h"
|
||||
#include "Network/Http/CURLPostHander.h"
|
||||
#include "Network/TextEncoding.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <windows.h>
|
||||
#include <timeapi.h>
|
||||
|
||||
namespace {
|
||||
constexpr char sourceFile[] = "C:\\repositories\\RagnarokClient\\RagnarokClient\\Contents\\Emblem\\CEmblemDataDownloadAsyncWork.cpp";
|
||||
|
||||
AsyncDiagnostic Diagnostic(bool success, const char* text, std::uint32_t line) {
|
||||
std::string message = text;
|
||||
return AsyncDiagnostic(&success, &message, sourceFile, &line);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x005E9C00
|
||||
// FUNCTION: fn_03963
|
||||
CEmblemDataDownloadAsyncWork::CEmblemDataDownloadAsyncWork()
|
||||
: NAsyncWork("Emblem_Download"), m_accountId(0), m_guildId(0), m_version(0), m_responseCode(500), m_diagnostic(Diagnostic(false, "unknwon", 29)),
|
||||
m_connection(nullptr) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x005E9FE0
|
||||
// FUNCTION: fn_03964
|
||||
CEmblemDataDownloadAsyncWork::~CEmblemDataDownloadAsyncWork() = default;
|
||||
|
||||
// OFFSET: 0x005EA350
|
||||
// FUNCTION: fn_03966
|
||||
void CEmblemDataDownloadAsyncWork::Reset() {
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EA0D0
|
||||
// FUNCTION: fn_03965
|
||||
void CEmblemDataDownloadAsyncWork::Bind(
|
||||
std::string url, std::uint32_t accountId, std::string token, std::string accountName, std::uint32_t guildId, std::uint32_t version, CConnection& connection
|
||||
) {
|
||||
this->m_group = timeGetTime();
|
||||
this->m_key = 0;
|
||||
this->m_url = url;
|
||||
this->m_accountId = accountId;
|
||||
this->m_token = token;
|
||||
this->m_accountName = accountName;
|
||||
this->m_guildId = guildId;
|
||||
this->m_version = version;
|
||||
AsyncDiagnostic diagnostic = Diagnostic(false, "unknwon", 57);
|
||||
this->m_diagnostic.MoveFrom(diagnostic);
|
||||
this->m_connection = &connection;
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EA430
|
||||
// FUNCTION: fn_03968
|
||||
bool CEmblemDataDownloadAsyncWork::Execute() {
|
||||
char account[64] = {}, guild[64] = {}, version[10] = {};
|
||||
_snprintf_s(account, sizeof(account), _TRUNCATE, "%d", static_cast<std::int32_t>(this->m_accountId));
|
||||
_snprintf_s(guild, sizeof(guild), _TRUNCATE, "%d", static_cast<std::int32_t>(this->m_guildId));
|
||||
_snprintf_s(version, sizeof(version), _TRUNCATE, "%d", static_cast<std::int32_t>(this->m_version));
|
||||
std::string name = ToUtf8(this->m_accountName);
|
||||
|
||||
CCURLPostHander handler(this->m_url);
|
||||
handler.AddField("AID", account, 4);
|
||||
handler.AddField("AuthToken", this->m_token, 4);
|
||||
handler.AddField("WorldName", name, 4);
|
||||
handler.AddField("GDID", guild, 4);
|
||||
handler.AddField("Version", version, 4);
|
||||
|
||||
if (handler.Perform() == 0) {
|
||||
this->m_responseCode = static_cast<int>(handler.ResponseCode());
|
||||
this->m_response = handler.Response();
|
||||
AsyncDiagnostic diagnostic = Diagnostic(true, "good", 96);
|
||||
this->m_diagnostic.MoveFrom(diagnostic);
|
||||
} else {
|
||||
AsyncDiagnostic diagnostic = Diagnostic(false, "fail", 105);
|
||||
this->m_diagnostic.MoveFrom(diagnostic);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EA360
|
||||
// FUNCTION: fn_03967
|
||||
void CEmblemDataDownloadAsyncWork::Complete() {
|
||||
CompleteEmblemDownload(this->m_diagnostic, this->m_responseCode, this->m_response, this->m_guildId, this->m_version, *this->m_connection);
|
||||
}
|
||||
37
Source/Contents/Emblems/EmblemDataDownloadAsyncWork.h
Normal file
37
Source/Contents/Emblems/EmblemDataDownloadAsyncWork.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMDATADOWNLOADASYNCWORK_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMDATADOWNLOADASYNCWORK_H
|
||||
|
||||
#include "Utility/Async/AsyncDiagnostic.h"
|
||||
#include "Utility/Async/NAsyncWork.h"
|
||||
|
||||
class CConnection;
|
||||
|
||||
class CEmblemDataDownloadAsyncWork : public NAsyncWork {
|
||||
public:
|
||||
CEmblemDataDownloadAsyncWork();
|
||||
~CEmblemDataDownloadAsyncWork() override;
|
||||
void Reset() override;
|
||||
bool Execute() override;
|
||||
void Complete() override;
|
||||
void Bind(
|
||||
std::string url, std::uint32_t accountId, std::string token, std::string accountName, std::uint32_t guildId, std::uint32_t version, CConnection& connection
|
||||
);
|
||||
|
||||
protected:
|
||||
/* 0028 */ std::string m_url;
|
||||
/* 0040 */ std::uint32_t m_accountId;
|
||||
/* 0044 */ std::string m_token;
|
||||
/* 005C */ std::string m_accountName;
|
||||
/* 0074 */ std::uint32_t m_guildId;
|
||||
/* 0078 */ std::uint32_t m_version;
|
||||
/* 007C */ std::string m_response;
|
||||
/* 0094 */ int m_responseCode;
|
||||
/* 0098 */ AsyncDiagnostic m_diagnostic;
|
||||
CConnection* m_connection;
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(sizeof(CEmblemDataDownloadAsyncWork) == 212);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
86
Source/Contents/Emblems/EmblemDataMgr.cpp
Normal file
86
Source/Contents/Emblems/EmblemDataMgr.cpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#include "Contents/UserData/AccountService.h"
|
||||
#include "Contents/Async/AsyncWorkMgr.h"
|
||||
#include "Contents/Emblems/EmblemDataMgr.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
// STATIC: 0x013898D4
|
||||
// GLOBAL: gl_24355
|
||||
CEmblemDataMgr* g_emblemDataMgr;
|
||||
|
||||
// OFFSET: 0x005EB150
|
||||
// FUNCTION: fn_03970
|
||||
CEmblemDataMgr::CEmblemDataMgr() : m_enabled(true), m_uploading(false) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EB0D0
|
||||
// FUNCTION: fn_03969
|
||||
CEmblemDataMgr::~CEmblemDataMgr() = default;
|
||||
|
||||
// OFFSET: 0x005EB150
|
||||
// FUNCTION: fn_03970
|
||||
bool CEmblemDataMgr::Initialize() {
|
||||
if (g_emblemDataMgr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
g_emblemDataMgr = new (std::nothrow) CEmblemDataMgr;
|
||||
|
||||
if (!g_emblemDataMgr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!g_emblemDataMgr->m_enabled) {
|
||||
delete g_emblemDataMgr;
|
||||
g_emblemDataMgr = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EB240
|
||||
// FUNCTION: fn_03971
|
||||
void CEmblemDataMgr::Shutdown() {
|
||||
if (g_emblemDataMgr) {
|
||||
delete g_emblemDataMgr;
|
||||
g_emblemDataMgr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EB580
|
||||
// FUNCTION: fn_03974
|
||||
void CEmblemDataMgr::RefreshUrls(LuaScript& settings, LuaScript& tables, const char* host, const char* port, const char* overrideKey) {
|
||||
const std::string base = ResolveAccountServiceBase(settings, tables, host, port, overrideKey);
|
||||
|
||||
if (!base.empty()) {
|
||||
this->m_uploadUrl = base + "/emblem/upload";
|
||||
this->m_downloadUrl = base + "/emblem/download";
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EB260
|
||||
// FUNCTION: fn_03972
|
||||
void CEmblemDataMgr::Download(
|
||||
std::uint32_t guildId, std::uint32_t version, std::uint32_t accountId, const std::string& accountName, const char* token16, CConnection& connection,
|
||||
CAsyncWorkMgr& manager
|
||||
) {
|
||||
const std::string token(token16, 16);
|
||||
manager.DownloadEmblem(this->m_downloadUrl, accountId, token, accountName, guildId, version, connection);
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EB410
|
||||
// FUNCTION: fn_03973
|
||||
bool CEmblemDataMgr::Upload(
|
||||
std::uint32_t guildId, std::string path, std::uint32_t accountId, const std::string& accountName, const char* token16, EmblemUploadContext& context,
|
||||
CAsyncWorkMgr& manager
|
||||
) {
|
||||
if (this->m_uploading) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string token(token16, 16);
|
||||
manager.UploadEmblem(this->m_uploadUrl, accountId, token, accountName, guildId, path, *this, context);
|
||||
|
||||
return true;
|
||||
}
|
||||
45
Source/Contents/Emblems/EmblemDataMgr.h
Normal file
45
Source/Contents/Emblems/EmblemDataMgr.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMDATAMGR_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMDATAMGR_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
class LuaScript;
|
||||
class CConnection;
|
||||
class CAsyncWorkMgr;
|
||||
struct AsyncDiagnostic;
|
||||
struct EmblemUploadContext;
|
||||
|
||||
class CEmblemDataMgr {
|
||||
public:
|
||||
CEmblemDataMgr();
|
||||
virtual ~CEmblemDataMgr();
|
||||
static bool Initialize();
|
||||
static void Shutdown();
|
||||
void RefreshUrls(LuaScript& settings, LuaScript& tables, const char* host, const char* port, const char* overrideKey);
|
||||
void Download(
|
||||
std::uint32_t guildId, std::uint32_t version, std::uint32_t accountId, const std::string& accountName, const char* token16, CConnection& connection,
|
||||
CAsyncWorkMgr& manager
|
||||
);
|
||||
bool Upload(
|
||||
std::uint32_t guildId, std::string path, std::uint32_t accountId, const std::string& accountName, const char* token16, EmblemUploadContext& context,
|
||||
CAsyncWorkMgr& manager
|
||||
);
|
||||
void CompleteUpload(AsyncDiagnostic diagnostic, std::string response, std::uint32_t guildId, EmblemUploadContext& context);
|
||||
|
||||
protected:
|
||||
/* 0004 */ bool m_enabled;
|
||||
/* 0008 */ std::string m_uploadUrl;
|
||||
/* 0020 */ std::string m_downloadUrl;
|
||||
/* 0038 */ bool m_uploading;
|
||||
};
|
||||
|
||||
// STATIC: 0x013898D4
|
||||
// GLOBAL: gl_24355
|
||||
extern CEmblemDataMgr* g_emblemDataMgr;
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(sizeof(CEmblemDataMgr) == 60);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
94
Source/Contents/Emblems/EmblemDataUploadAsyncWork.cpp
Normal file
94
Source/Contents/Emblems/EmblemDataUploadAsyncWork.cpp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#include "Contents/Emblems/EmblemDataMgr.h"
|
||||
#include "Contents/Emblems/EmblemDataUploadAsyncWork.h"
|
||||
#include "Network/Http/CURLPostHander.h"
|
||||
#include "Network/TextEncoding.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <windows.h>
|
||||
#include <timeapi.h>
|
||||
|
||||
namespace {
|
||||
constexpr char sourceFile[] = "C:\\repositories\\RagnarokClient\\RagnarokClient\\Contents\\Emblem\\CEmblemDataUploadAsyncWork.cpp";
|
||||
|
||||
AsyncDiagnostic Diagnostic(bool success, const char* text, std::uint32_t line) {
|
||||
std::string message = text;
|
||||
return AsyncDiagnostic(&success, &message, sourceFile, &line);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EBF50
|
||||
// FUNCTION: fn_03978
|
||||
CEmblemDataUploadAsyncWork::CEmblemDataUploadAsyncWork()
|
||||
: NAsyncWork("Emblem_Upload"), m_accountId(0), m_guildId(0), m_diagnostic(Diagnostic(false, "unknwon", 27)), m_owner(nullptr), m_context(nullptr) {
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EC350
|
||||
// FUNCTION: fn_03979
|
||||
CEmblemDataUploadAsyncWork::~CEmblemDataUploadAsyncWork() = default;
|
||||
|
||||
// OFFSET: 0x005EC6F0
|
||||
// FUNCTION: fn_03981
|
||||
void CEmblemDataUploadAsyncWork::Reset() {
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EC450
|
||||
// FUNCTION: fn_03980
|
||||
void CEmblemDataUploadAsyncWork::Bind(
|
||||
std::string url, std::uint32_t accountId, std::string token, std::string accountName, std::uint32_t guildId, std::string path, CEmblemDataMgr& owner,
|
||||
EmblemUploadContext& context
|
||||
) {
|
||||
this->m_group = timeGetTime();
|
||||
this->m_key = 0;
|
||||
this->m_url = url;
|
||||
this->m_accountId = accountId;
|
||||
this->m_token = token;
|
||||
this->m_accountName = accountName;
|
||||
this->m_guildId = guildId;
|
||||
this->m_path = path;
|
||||
AsyncDiagnostic diagnostic = Diagnostic(false, "unknwon", 54);
|
||||
this->m_diagnostic.MoveFrom(diagnostic);
|
||||
this->m_owner = &owner;
|
||||
this->m_context = &context;
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EC7C0
|
||||
// FUNCTION: fn_03983
|
||||
bool CEmblemDataUploadAsyncWork::Execute() {
|
||||
char account[64] = {}, guild[64] = {};
|
||||
_snprintf_s(account, sizeof(account), _TRUNCATE, "%d", static_cast<std::int32_t>(this->m_accountId));
|
||||
_snprintf_s(guild, sizeof(guild), _TRUNCATE, "%d", static_cast<std::int32_t>(this->m_guildId));
|
||||
std::string name = ToUtf8(this->m_accountName);
|
||||
std::string path = ToUtf8(this->m_path);
|
||||
std::string extension = this->m_path.substr(this->m_path.size() - 3, this->m_path.size());
|
||||
|
||||
for (char& value : extension) {
|
||||
value = static_cast<char>(std::toupper(static_cast<unsigned char>(value)));
|
||||
}
|
||||
|
||||
extension = ToUtf8(extension);
|
||||
CCURLPostHander handler(this->m_url);
|
||||
handler.AddField("AID", account, 4);
|
||||
handler.AddField("AuthToken", this->m_token, 4);
|
||||
handler.AddField("WorldName", name, 4);
|
||||
handler.AddField("GDID", guild, 4);
|
||||
handler.AddField("ImgType", extension, 4);
|
||||
handler.AddField("Img", path, 10);
|
||||
|
||||
if (handler.Perform() == 0) {
|
||||
this->m_response = FromUtf8(handler.Response());
|
||||
AsyncDiagnostic diagnostic = Diagnostic(true, "good", 100);
|
||||
this->m_diagnostic.MoveFrom(diagnostic);
|
||||
} else {
|
||||
AsyncDiagnostic diagnostic = Diagnostic(false, "fail", 109);
|
||||
this->m_diagnostic.MoveFrom(diagnostic);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EC700
|
||||
// FUNCTION: fn_03982
|
||||
void CEmblemDataUploadAsyncWork::Complete() {
|
||||
this->m_owner->CompleteUpload(this->m_diagnostic, this->m_response, this->m_guildId, *this->m_context);
|
||||
}
|
||||
39
Source/Contents/Emblems/EmblemDataUploadAsyncWork.h
Normal file
39
Source/Contents/Emblems/EmblemDataUploadAsyncWork.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMDATAUPLOADASYNCWORK_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMDATAUPLOADASYNCWORK_H
|
||||
|
||||
#include "Utility/Async/AsyncDiagnostic.h"
|
||||
#include "Utility/Async/NAsyncWork.h"
|
||||
|
||||
class CEmblemDataMgr;
|
||||
struct EmblemUploadContext;
|
||||
|
||||
class CEmblemDataUploadAsyncWork : public NAsyncWork {
|
||||
public:
|
||||
CEmblemDataUploadAsyncWork();
|
||||
~CEmblemDataUploadAsyncWork() override;
|
||||
void Reset() override;
|
||||
bool Execute() override;
|
||||
void Complete() override;
|
||||
void Bind(
|
||||
std::string url, std::uint32_t accountId, std::string token, std::string accountName, std::uint32_t guildId, std::string path, CEmblemDataMgr& owner,
|
||||
EmblemUploadContext& context
|
||||
);
|
||||
|
||||
protected:
|
||||
/* 0028 */ std::string m_url;
|
||||
/* 0040 */ std::uint32_t m_accountId;
|
||||
/* 0044 */ std::string m_token;
|
||||
/* 005C */ std::string m_accountName;
|
||||
/* 0074 */ std::uint32_t m_guildId;
|
||||
/* 0078 */ std::string m_path;
|
||||
/* 0090 */ std::string m_response;
|
||||
/* 00A8 */ AsyncDiagnostic m_diagnostic;
|
||||
CEmblemDataMgr* m_owner;
|
||||
EmblemUploadContext* m_context;
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(sizeof(CEmblemDataUploadAsyncWork) == 232);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
78
Source/Contents/Emblems/EmblemDownload.cpp
Normal file
78
Source/Contents/Emblems/EmblemDownload.cpp
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#include "Contents/Emblems/EmblemDownload.h"
|
||||
#include "Network/Connection/Connection.h"
|
||||
#include "Utility/Async/AsyncDiagnostic.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace {
|
||||
#pragma pack(push, 1)
|
||||
struct EmblemPacket {
|
||||
std::uint16_t id;
|
||||
std::uint16_t bytes;
|
||||
std::uint16_t state;
|
||||
std::uint32_t guildId;
|
||||
std::uint32_t version;
|
||||
unsigned char data[1010];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(sizeof(EmblemPacket) == 1024);
|
||||
|
||||
struct EmblemPacketAllocation {
|
||||
std::uint32_t marker;
|
||||
std::uint32_t unused;
|
||||
EmblemPacket packet;
|
||||
};
|
||||
static_assert(sizeof(EmblemPacketAllocation) == 1032);
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EB800
|
||||
// FUNCTION: fn_03975
|
||||
void CompleteEmblemDownload(
|
||||
AsyncDiagnostic diagnostic, int responseCode, std::string response, std::uint32_t guildId, std::uint32_t version, CConnection& connection
|
||||
) {
|
||||
if (!diagnostic.success || responseCode != 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* storage = static_cast<EmblemPacketAllocation*>(std::malloc(sizeof(EmblemPacketAllocation)));
|
||||
|
||||
if (!storage) {
|
||||
return;
|
||||
}
|
||||
|
||||
storage->marker = 0xDDDD;
|
||||
EmblemPacket& packet = storage->packet;
|
||||
packet.id = 0x0B36;
|
||||
packet.bytes = 14;
|
||||
packet.state = 2;
|
||||
packet.guildId = guildId;
|
||||
packet.version = version;
|
||||
connection.Prepend(packet.bytes, &packet);
|
||||
int remaining = static_cast<int>(response.size());
|
||||
|
||||
while (remaining > 0) {
|
||||
const int bytes = std::min(remaining, 1010);
|
||||
remaining -= bytes;
|
||||
packet.id = 0x0B36;
|
||||
packet.bytes = static_cast<std::uint16_t>(bytes + 14);
|
||||
packet.state = 1;
|
||||
packet.guildId = guildId;
|
||||
packet.version = version;
|
||||
|
||||
std::memcpy(packet.data, response.data() + remaining, bytes);
|
||||
connection.Prepend(packet.bytes, &packet);
|
||||
}
|
||||
|
||||
packet.id = 0x0B36;
|
||||
packet.bytes = 14;
|
||||
packet.state = 0;
|
||||
packet.guildId = guildId;
|
||||
packet.version = version;
|
||||
connection.Prepend(packet.bytes, &packet);
|
||||
|
||||
if (storage->marker == 0xDDDD) {
|
||||
std::free(storage);
|
||||
}
|
||||
}
|
||||
14
Source/Contents/Emblems/EmblemDownload.h
Normal file
14
Source/Contents/Emblems/EmblemDownload.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMDOWNLOAD_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMDOWNLOAD_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
class CConnection;
|
||||
struct AsyncDiagnostic;
|
||||
|
||||
void CompleteEmblemDownload(
|
||||
AsyncDiagnostic diagnostic, int responseCode, std::string response, std::uint32_t guildId, std::uint32_t version, CConnection& connection
|
||||
);
|
||||
|
||||
#endif
|
||||
56
Source/Contents/Emblems/EmblemUpload.cpp
Normal file
56
Source/Contents/Emblems/EmblemUpload.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include "Contents/Emblems/EmblemDataMgr.h"
|
||||
#include "Contents/Emblems/EmblemUpload.h"
|
||||
#include "Contents/MessageTable.h"
|
||||
#include "Network/Connection/Connection.h"
|
||||
#include "Network/Packets/PacketLengths.h"
|
||||
#include "UI/Window/WindowDialogs.h"
|
||||
#include "Utility/Async/AsyncDiagnostic.h"
|
||||
|
||||
#include <json/reader.h>
|
||||
#include <json/value.h>
|
||||
|
||||
namespace {
|
||||
#pragma pack(push, 1)
|
||||
struct EmblemVersionPacket {
|
||||
std::uint16_t id;
|
||||
std::uint32_t guildId;
|
||||
std::int32_t version;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(sizeof(EmblemVersionPacket) == 10);
|
||||
}
|
||||
|
||||
// OFFSET: 0x005EBAD0
|
||||
// FUNCTION: fn_03976
|
||||
void CEmblemDataMgr::CompleteUpload(AsyncDiagnostic diagnostic, std::string response, std::uint32_t guildId, EmblemUploadContext& context) {
|
||||
if (!diagnostic.success) {
|
||||
return;
|
||||
}
|
||||
|
||||
Json::Value root;
|
||||
Json::Reader reader;
|
||||
const std::string document(response.c_str());
|
||||
|
||||
if (!reader.parse(document, root, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (root["Type"].asInt()) {
|
||||
case 1: {
|
||||
EmblemVersionPacket packet{0x0B46, guildId, root["version"].asInt()};
|
||||
context.connection.Send(context.lengths.FixedLength(packet.id), &packet);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
case 3:
|
||||
case 4: {
|
||||
const char* message = LookupMessage(3586, context.languagePrefix, context.serviceType, context.language);
|
||||
context.dialogs.Confirm(message, 0, true, false, 0, "Message", 280, 120, 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this->m_uploading = false;
|
||||
}
|
||||
19
Source/Contents/Emblems/EmblemUpload.h
Normal file
19
Source/Contents/Emblems/EmblemUpload.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMUPLOAD_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_EMBLEMS_EMBLEMUPLOAD_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CConnection;
|
||||
struct PacketLengths;
|
||||
struct WindowDialogs;
|
||||
|
||||
struct EmblemUploadContext {
|
||||
CConnection& connection;
|
||||
const PacketLengths& lengths;
|
||||
WindowDialogs& dialogs;
|
||||
const bool& languagePrefix;
|
||||
const int& serviceType;
|
||||
const std::uint16_t& language;
|
||||
};
|
||||
|
||||
#endif
|
||||
56
Source/Contents/Emblems/GuildEmblemReqBundle.cpp
Normal file
56
Source/Contents/Emblems/GuildEmblemReqBundle.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include "Contents/Emblems/EmblemDataMgr.h"
|
||||
#include "Contents/Emblems/GuildEmblemReqBundle.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <windows.h>
|
||||
#include <timeapi.h>
|
||||
|
||||
// OFFSET: 0x0065C5F0
|
||||
CGuildEmblemReqBundle::CGuildEmblemReqBundle() = default;
|
||||
|
||||
// OFFSET: 0x0065C8C0
|
||||
// FUNCTION: fn_05153
|
||||
CGuildEmblemReqBundle::~CGuildEmblemReqBundle() = default;
|
||||
|
||||
// OFFSET: 0x0065CA90
|
||||
// FUNCTION: fn_05154
|
||||
void CGuildEmblemReqBundle::Add(std::uint32_t guildId, std::uint32_t version) {
|
||||
const auto request = std::pair{guildId, version};
|
||||
|
||||
if (std::find(this->m_pending.begin(), this->m_pending.end(), request) == this->m_pending.end()) {
|
||||
this->m_pending.push_back(request);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x0065CB90
|
||||
// FUNCTION: fn_05155
|
||||
void CGuildEmblemReqBundle::Update(
|
||||
CEmblemDataMgr& emblems, std::uint32_t accountId, const std::string& accountName, const char* token16, CConnection& connection, CAsyncWorkMgr& manager
|
||||
) {
|
||||
while (!this->m_recent.empty()) {
|
||||
if (timeGetTime() < this->m_recent.front().tick + 60000u) {
|
||||
break;
|
||||
}
|
||||
|
||||
this->m_recent.pop_front();
|
||||
}
|
||||
|
||||
while (!this->m_pending.empty()) {
|
||||
const auto request = this->m_pending.front();
|
||||
const bool recent = std::any_of(this->m_recent.begin(), this->m_recent.end(), [&](const Recent& value) {
|
||||
return value.guildId == request.first && value.version == request.second;
|
||||
});
|
||||
this->m_pending.pop_front();
|
||||
|
||||
if (recent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (request.first != 0) {
|
||||
emblems.Download(request.first, request.second, accountId, accountName, token16, connection, manager);
|
||||
this->m_recent.push_back({request.first, request.second, timeGetTime()});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
36
Source/Contents/Emblems/GuildEmblemReqBundle.h
Normal file
36
Source/Contents/Emblems/GuildEmblemReqBundle.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef RAGNAROK_SOURCE_CONTENTS_EMBLEMS_GUILDEMBLEMREQBUNDLE_H
|
||||
#define RAGNAROK_SOURCE_CONTENTS_EMBLEMS_GUILDEMBLEMREQBUNDLE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
class CEmblemDataMgr;
|
||||
class CConnection;
|
||||
class CAsyncWorkMgr;
|
||||
|
||||
class CGuildEmblemReqBundle {
|
||||
public:
|
||||
CGuildEmblemReqBundle();
|
||||
virtual ~CGuildEmblemReqBundle();
|
||||
void Add(std::uint32_t guildId, std::uint32_t version);
|
||||
void Update(
|
||||
CEmblemDataMgr& emblems, std::uint32_t accountId, const std::string& accountName, const char* token16, CConnection& connection, CAsyncWorkMgr& manager
|
||||
);
|
||||
|
||||
protected:
|
||||
struct Recent {
|
||||
std::uint32_t guildId;
|
||||
std::uint32_t version;
|
||||
std::uint32_t tick;
|
||||
};
|
||||
/* 0004 */ std::deque<std::pair<std::uint32_t, std::uint32_t>> m_pending;
|
||||
/* 0018 */ std::deque<Recent> m_recent;
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && !defined(_WIN64)
|
||||
static_assert(sizeof(CGuildEmblemReqBundle) == 44);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue