feat(db): load achievement db

This commit is contained in:
fallenoak 2023-02-13 23:21:25 -06:00 committed by GitHub
parent 1575f6d83c
commit c00028c214
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 384 additions and 1 deletions

View File

@ -1,6 +1,7 @@
add_subdirectory(app)
add_subdirectory(async)
add_subdirectory(client)
add_subdirectory(db)
add_subdirectory(event)
add_subdirectory(glue)
add_subdirectory(gx)

View File

@ -12,6 +12,7 @@ target_include_directories(client
target_link_libraries(client
PRIVATE
async
db
event
gx
model

View File

@ -1,6 +1,7 @@
#include "client/Client.hpp"
#include "client/ClientServices.hpp"
#include "client/Console.hpp"
#include "db/Db.hpp"
#include "async/AsyncFile.hpp"
#include "glue/CGlueMgr.hpp"
#include "gx/Device.hpp"
@ -353,7 +354,9 @@ void WowClientInit() {
ClientMiscInitialize();
// sub_401B60();
// ClientDBInitialize();
ClientDBInitialize();
// LoadingScreenInitialize();
FrameScript_Initialize(0);

16
src/db/CMakeLists.txt Normal file
View File

@ -0,0 +1,16 @@
file(GLOB PRIVATE_SOURCES "*.cpp" "rec/*.cpp")
add_library(db STATIC
${PRIVATE_SOURCES}
)
target_include_directories(db
PRIVATE
${CMAKE_SOURCE_DIR}/src
)
target_link_libraries(db
PUBLIC
common
storm
)

20
src/db/Db.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "db/Db.hpp"
#include "db/WowClientDB_Base.hpp"
WowClientDB<AchievementRec> g_achievementDB;
void LoadDB(WowClientDB_Base* db, const char* filename, int32_t linenumber) {
db->Load(filename, linenumber);
};
void StaticDBLoadAll(void (*loadFn)(WowClientDB_Base*, const char*, int32_t)) {
loadFn(&g_achievementDB, __FILE__, __LINE__);
};
void ClientDBInitialize() {
// TODO
StaticDBLoadAll(LoadDB);
// TODO
}

11
src/db/Db.hpp Normal file
View File

@ -0,0 +1,11 @@
#ifndef DB_DB_HPP
#define DB_DB_HPP
#include "db/rec/AchievementRec.hpp"
#include "db/WowClientDB.hpp"
extern WowClientDB<AchievementRec> g_achievementDB;
void ClientDBInitialize();
#endif

15
src/db/IDatabase.hpp Normal file
View File

@ -0,0 +1,15 @@
#ifndef DB_I_DATABASE_HPP
#define DB_I_DATABASE_HPP
template <class T>
class IDatabase {
public:
// Member variables
T* m_records = nullptr;
T** m_recordsById = nullptr;
// Virtual member functions
virtual T* GetRecord(int32_t id) = 0;
};
#endif

157
src/db/WowClientDB.hpp Normal file
View File

@ -0,0 +1,157 @@
#ifndef DB_WOW_CLIENT_DB_HPP
#define DB_WOW_CLIENT_DB_HPP
#include "db/IDatabase.hpp"
#include "db/WowClientDB_Common.hpp"
#include <cstring>
#include <storm/Error.hpp>
#include <storm/Memory.hpp>
template <class T>
class WowClientDB : public WowClientDB_Common<T>, IDatabase<T> {
public:
// Virtual member functions
virtual void Load(const char* filename, int32_t linenumber);
virtual void LoadRecords(SFile* f, const char* filename, int32_t linenumber);
virtual int32_t GetRecordByIndex(int32_t index, void* ptr) const;
virtual T* GetRecord(int32_t id);
};
template <class T>
int32_t WowClientDB<T>::GetRecordByIndex(int32_t index, void* ptr) const {
STORM_ASSERT(this->m_numRecords >= 0);
if (index < 0 || index >= this->m_numRecords) {
return 0;
}
memcpy(ptr, &this->m_records[index], sizeof(T));
return 1;
}
template <class T>
T* WowClientDB<T>::GetRecord(int32_t id) {
STORM_ASSERT(this->m_numRecords >= 0);
if (id < this->m_minID || id > this->m_maxID) {
return nullptr;
}
return this->m_recordsById[id - this->m_minID];
}
template <class T>
void WowClientDB<T>::Load(const char* filename, int32_t linenumber) {
if (this->m_loaded) {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "%s already loaded! Aborting to prevent memory leak!", T::GetFilename());
return;
}
SFile* f;
if (!SFile::OpenEx(nullptr, T::GetFilename(), 0x20000, &f)) {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "Unable to open %s", T::GetFilename());
return;
}
uint32_t signature;
if (!SFile::Read(f, &signature, sizeof(signature), nullptr, nullptr, nullptr)) {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "Unable to read signature from %s", T::GetFilename());
return;
}
if (signature != 'CBDW') {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "Invalid signature 0x%x from %s", signature, T::GetFilename());
return;
}
if (!SFile::Read(f, &this->m_numRecords, sizeof(this->m_numRecords), nullptr, nullptr, nullptr)) {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "Unable to read record count from %s", T::GetFilename());
return;
}
if (!this->m_numRecords) {
SFile::Close(f);
return;
}
uint32_t columnCount;
if (!SFile::Read(f, &columnCount, sizeof(columnCount), nullptr, nullptr, nullptr)) {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "Unable to read column count from %s", T::GetFilename());
return;
}
if (columnCount != T::columnCount) {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "%s has wrong number of columns (found %i, expected %i)", T::GetFilename(), columnCount, T::columnCount);
return;
}
uint32_t rowSize;
if (!SFile::Read(f, &rowSize, sizeof(rowSize), nullptr, nullptr, nullptr)) {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "Unable to read row size from %s", T::GetFilename());
return;
}
if (rowSize != T::rowSize) {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "%s has wrong row size (found %i, expected %i)", T::GetFilename(), rowSize, T::rowSize);
return;
}
uint32_t stringSize;
if (!SFile::Read(f, &stringSize, sizeof(stringSize), nullptr, nullptr, nullptr)) {
// TODO
// SErrDisplayAppFatalCustom(0x85100079, "Unable to read string size from %s", T::GetFilename());
return;
}
auto stringBuffer = SMemAlloc(stringSize, filename, linenumber, 0x0);
this->m_strings = static_cast<const char*>(stringBuffer);
this->m_maxID = 0;
this->m_minID = 0xFFFFFFF;
this->LoadRecords(f, filename, linenumber);
if (!SFile::Read(f, const_cast<char*>(this->m_strings), stringSize, nullptr, nullptr, nullptr)) {
SErrDisplayAppFatal("%s: Cannot read string table", T::GetFilename());
}
SFile::Close(f);
this->m_loaded = 1;
}
template <class T>
void WowClientDB<T>::LoadRecords(SFile* f, const char* filename, int32_t linenumber) {
auto records = SMemAlloc(sizeof(T) * this->m_numRecords, filename, linenumber, 0x0);
this->m_records = static_cast<T*>(records);
for (uint32_t i = 0; i < this->m_numRecords; i++) {
auto record = &this->m_records[i];
record->Read(f, this->m_strings);
this->m_maxID = record->m_ID > this->m_maxID ? record->m_ID : this->m_maxID;
this->m_minID = record->m_ID < this->m_minID ? record->m_ID : this->m_minID;
}
auto recordsById = SMemAlloc(sizeof(void*) * (this->m_maxID - this->m_minID + 1), __FILE__, __LINE__, 0x0);
memset(recordsById, 0, sizeof(void*) * (this->m_maxID - this->m_minID + 1));
this->m_recordsById = static_cast<T**>(recordsById);
for (uint32_t i = 0; i < this->m_numRecords; i++) {
auto record = &this->m_records[i];
auto id = record->m_ID - this->m_minID;
this->m_recordsById[id] = record;
}
}
#endif

View File

@ -0,0 +1,22 @@
#ifndef DB_WOW_CLIENT_DB_BASE_HPP
#define DB_WOW_CLIENT_DB_BASE_HPP
#include "util/SFile.hpp"
#include <cstdint>
class WowClientDB_Base {
public:
// Member variables
int32_t m_loaded = 0;
int32_t m_numRecords = 0;
int32_t m_maxID = -1;
int32_t m_minID = 0xFFFFFFF;
const char* m_strings = nullptr;
// Virtual member functions
virtual void Load(const char* filename, int32_t linenumber) = 0;
virtual void LoadRecords(SFile* f, const char* filename, int32_t linenumber) = 0;
virtual int32_t GetRecordByIndex(int32_t index, void* ptr) const = 0;
};
#endif

View File

@ -0,0 +1,11 @@
#ifndef DB_WOW_CLIENT_DB_COMMON_HPP
#define DB_WOW_CLIENT_DB_COMMON_HPP
#include "db/WowClientDB_Base.hpp"
template <class T>
class WowClientDB_Common : public WowClientDB_Base {
public:
};
#endif

View File

@ -0,0 +1,94 @@
#include "db/rec/AchievementRec.hpp"
#include "util/SFile.hpp"
const char* AchievementRec::GetFilename() {
return "DBFilesClient\\Achievement.dbc";
}
bool AchievementRec::Read(SFile* f, const char* stringBuffer) {
uint32_t titleOfs[16];
uint32_t titleMask;
uint32_t descriptionOfs[16];
uint32_t descriptionMask;
uint32_t rewardOfs[16];
uint32_t rewardMask;
if (
!SFile::Read(f, &this->m_ID, sizeof(this->m_ID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_faction, sizeof(this->m_faction), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_instanceID, sizeof(this->m_instanceID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_supercedes, sizeof(this->m_supercedes), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[0], sizeof(titleOfs[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[1], sizeof(titleOfs[1]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[2], sizeof(titleOfs[2]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[3], sizeof(titleOfs[3]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[4], sizeof(titleOfs[4]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[5], sizeof(titleOfs[5]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[6], sizeof(titleOfs[6]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[7], sizeof(titleOfs[7]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[8], sizeof(titleOfs[8]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[9], sizeof(titleOfs[9]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[10], sizeof(titleOfs[10]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[11], sizeof(titleOfs[11]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[12], sizeof(titleOfs[12]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[13], sizeof(titleOfs[13]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[14], sizeof(titleOfs[14]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleOfs[15], sizeof(titleOfs[15]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &titleMask, sizeof(titleMask), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[0], sizeof(descriptionOfs[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[1], sizeof(descriptionOfs[1]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[2], sizeof(descriptionOfs[2]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[3], sizeof(descriptionOfs[3]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[4], sizeof(descriptionOfs[4]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[5], sizeof(descriptionOfs[5]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[6], sizeof(descriptionOfs[6]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[7], sizeof(descriptionOfs[7]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[8], sizeof(descriptionOfs[8]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[9], sizeof(descriptionOfs[9]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[10], sizeof(descriptionOfs[10]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[11], sizeof(descriptionOfs[11]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[12], sizeof(descriptionOfs[12]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[13], sizeof(descriptionOfs[13]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[14], sizeof(descriptionOfs[14]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionOfs[15], sizeof(descriptionOfs[15]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &descriptionMask, sizeof(descriptionMask), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_category, sizeof(this->m_category), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_points, sizeof(this->m_points), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_uiOrder, sizeof(this->m_uiOrder), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_flags, sizeof(this->m_flags), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_iconID, sizeof(this->m_iconID), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[0], sizeof(rewardOfs[0]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[1], sizeof(rewardOfs[1]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[2], sizeof(rewardOfs[2]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[3], sizeof(rewardOfs[3]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[4], sizeof(rewardOfs[4]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[5], sizeof(rewardOfs[5]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[6], sizeof(rewardOfs[6]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[7], sizeof(rewardOfs[7]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[8], sizeof(rewardOfs[8]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[9], sizeof(rewardOfs[9]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[10], sizeof(rewardOfs[10]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[11], sizeof(rewardOfs[11]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[12], sizeof(rewardOfs[12]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[13], sizeof(rewardOfs[13]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[14], sizeof(rewardOfs[14]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardOfs[15], sizeof(rewardOfs[15]), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &rewardMask, sizeof(rewardMask), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_minimumCriteria, sizeof(this->m_minimumCriteria), nullptr, nullptr, nullptr)
|| !SFile::Read(f, &this->m_sharesCriteria, sizeof(this->m_sharesCriteria), nullptr, nullptr, nullptr)
) {
return false;
}
if (stringBuffer) {
this->m_title = &stringBuffer[titleOfs[0]];
this->m_description = &stringBuffer[descriptionOfs[0]];
this->m_reward = &stringBuffer[rewardOfs[0]];
} else {
this->m_title = "";
this->m_description = "";
this->m_reward = "";
}
return true;
}

View File

@ -0,0 +1,32 @@
#ifndef DB_REC_ACHIEVEMENT_REC_HPP
#define DB_REC_ACHIEVEMENT_REC_HPP
#include <cstdint>
class SFile;
class AchievementRec {
public:
static constexpr uint32_t columnCount = 62;
static constexpr uint32_t rowSize = 248;
int32_t m_ID;
int32_t m_faction;
int32_t m_instanceID;
int32_t m_supercedes;
const char* m_title;
const char* m_description;
int32_t m_category;
int32_t m_points;
int32_t m_uiOrder;
int32_t m_flags;
uint32_t m_iconID;
const char* m_reward;
int32_t m_minimumCriteria;
int32_t m_sharesCriteria;
static const char* GetFilename();
bool Read(SFile* f, const char* stringBuffer);
};
#endif