[Factions] Remove from shared memory and simplify (#3999)

* [Factions] Remove from shared memory and simplify

- Removes factions from shared memory and moves to zone based storage of repositories and changes the NPC `faction_list` to also use repositories.
- This affects NPC Factions and Faction Associations.

* Bug fixes.

* Update client.cpp

* Update client.cpp

* Update client.cpp

* Cleanup

* Update client.cpp

* Update client.cpp

* Update client.cpp

* Final push

* Update CMakeLists.txt

* Consolidate reloading.

* [Cleanup] PR # 3999 (#4039)

* [Fixes for PR # 3999

* [Reload actual in game factions, not just the umbrella data.

* syntax

* Fix typo

* Foix bug where primary_faction not filled in when no hits

* Fix typos

* Fix splash factions for kills.

* Fix typo

* Fix more variable names to be accurate

* Fix Loads to load new ones as they come in.

* Load npc_factions without primary (tasks) and support old task faction

* Rename to make way for new LoadFactionAssocition (by faction_id)

* Fix some review comments

* Add code to load factions for splash tasks and quests.

* Fix issue with sign and RewardFaction, fix Log Message

---------

Co-authored-by: Paul Coene <noudess@gmail.com>
This commit is contained in:
Alex King
2024-02-04 10:38:38 -05:00
committed by GitHub
parent 029581772d
commit 297e358c02
31 changed files with 568 additions and 597 deletions
+8 -27
View File
@@ -24,17 +24,15 @@
#include <string>
enum FACTION_VALUE {
FACTION_ALLY = 1,
FACTION_WARMLY = 2,
FACTION_KINDLY = 3,
FACTION_AMIABLY = 4,
FACTION_INDIFFERENTLY = 5,
FACTION_ALLY = 1,
FACTION_WARMLY = 2,
FACTION_KINDLY = 3,
FACTION_AMIABLY = 4,
FACTION_INDIFFERENTLY = 5,
FACTION_APPREHENSIVELY = 6,
FACTION_DUBIOUSLY = 7,
FACTION_THREATENINGLY = 8,
FACTION_SCOWLS = 9
FACTION_DUBIOUSLY = 7,
FACTION_THREATENINGLY = 8,
FACTION_SCOWLS = 9
};
struct NPCFactionList {
@@ -75,23 +73,6 @@ struct NPCFaction
uint8 temp;
};
// Faction Associations give a much more live like faction system
// Basically the primary faction and magnitude of a faction hit will generate the rest of them
// Largest faction I could find quickly was Lord Inquisitor Seru with 9 total hits (8 associations) so 8 + 2 for max for now
#define MAX_FACTION_ASSOC 10
// this is the ID of a faction association and it's multiplier
struct FactionAssociationHit {
int id;
float multiplier;
};
struct FactionAssociations {
// maybe there should be more data here, fine for now
FactionAssociationHit hits[MAX_FACTION_ASSOC];
};
const char *FactionValueToString(FACTION_VALUE faction_value);
FACTION_VALUE CalculateFaction(FactionMods* fm, int32 tmpCharacter_value);
#endif
+1
View File
@@ -251,6 +251,7 @@
#define ServerOP_ReloadDzTemplates 0x4123
#define ServerOP_ReloadZoneData 0x4124
#define ServerOP_ReloadDataBucketsCache 0x4125
#define ServerOP_ReloadFactions 0x4126
#define ServerOP_CZDialogueWindow 0x4500
#define ServerOP_CZLDoNUpdate 0x4501
-180
View File
@@ -1371,186 +1371,6 @@ std::string SharedDatabase::GetBook(const char *txtfile, int16 *language)
return txtout;
}
void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) {
list_count = 0;
max_lists = 0;
const std::string query = "SELECT COUNT(*), MAX(id) FROM npc_faction";
auto results = QueryDatabase(query);
if (!results.Success()) {
return;
}
if (results.RowCount() == 0)
return;
auto& row = results.begin();
list_count = Strings::ToUnsignedInt(row[0]);
max_lists = Strings::ToUnsignedInt(row[1] ? row[1] : "0");
}
const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) const
{
if(!faction_hash) {
return nullptr;
}
if(faction_hash->exists(id)) {
return &(faction_hash->at(id));
}
return nullptr;
}
void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists) {
EQ::FixedMemoryHashSet<NPCFactionList> hash(static_cast<uint8*>(data), size, list_count, max_lists);
NPCFactionList faction;
const std::string query = "SELECT npc_faction.id, npc_faction.primaryfaction, npc_faction.ignore_primary_assist, "
"npc_faction_entries.faction_id, npc_faction_entries.value, npc_faction_entries.npc_value, "
"npc_faction_entries.temp FROM npc_faction LEFT JOIN npc_faction_entries "
"ON npc_faction.id = npc_faction_entries.npc_faction_id ORDER BY npc_faction.id;";
auto results = QueryDatabase(query);
if (!results.Success()) {
return;
}
uint32 current_id = 0;
uint32 current_entry = 0;
for(auto& row = results.begin(); row != results.end(); ++row) {
const uint32 id = Strings::ToUnsignedInt(row[0]);
if(id != current_id) {
if(current_id != 0) {
hash.insert(current_id, faction);
}
memset(&faction, 0, sizeof(faction));
current_entry = 0;
current_id = id;
faction.id = id;
faction.primaryfaction = Strings::ToUnsignedInt(row[1]);
faction.assistprimaryfaction = (Strings::ToInt(row[2]) == 0);
}
if(!row[3])
continue;
if(current_entry >= MAX_NPC_FACTIONS)
continue;
faction.factionid[current_entry] = Strings::ToUnsignedInt(row[3]);
faction.factionvalue[current_entry] = Strings::ToInt(row[4]);
faction.factionnpcvalue[current_entry] = static_cast<int8>(Strings::ToInt(row[5]));
faction.factiontemp[current_entry] = static_cast<uint8>(Strings::ToUnsignedInt(row[6]));
++current_entry;
}
if(current_id != 0)
hash.insert(current_id, faction);
}
bool SharedDatabase::LoadNPCFactionLists(const std::string &prefix) {
faction_mmf.reset(nullptr);
faction_hash.reset(nullptr);
try {
const auto Config = EQEmuConfig::get();
EQ::IPCMutex mutex("faction");
mutex.Lock();
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("faction"));
LogInfo("Loading [{}]", file_name);
faction_mmf = std::make_unique<EQ::MemoryMappedFile>(file_name);
faction_hash = std::make_unique<EQ::FixedMemoryHashSet<NPCFactionList>>(static_cast<uint8*>(faction_mmf->Get()), faction_mmf->Size());
mutex.Unlock();
LogInfo("Loaded faction lists via shared memory");
} catch(std::exception& ex) {
LogError("Error Loading npc factions: {}", ex.what());
return false;
}
return true;
}
void SharedDatabase::GetFactionAssociationInfo(uint32 &list_count, uint32 &max_lists)
{
list_count = static_cast<uint32>(FactionAssociationRepository::Count(*this));
max_lists = static_cast<uint32>(FactionAssociationRepository::GetMaxId(*this));
}
const FactionAssociations *SharedDatabase::GetFactionAssociationHit(int id)
{
if (!faction_associations_hash) {
return nullptr;
}
if (faction_associations_hash->exists(id)) {
return &(faction_associations_hash->at(id));
}
return nullptr;
}
void SharedDatabase::LoadFactionAssociation(void *data, uint32 size, uint32 list_count, uint32 max_lists)
{
EQ::FixedMemoryHashSet<FactionAssociations> hash(reinterpret_cast<uint8 *>(data), size, list_count, max_lists);
FactionAssociations faction{};
auto results = FactionAssociationRepository::All(*this);
for (auto &row : results) {
faction.hits[0].id = row.id_1;
faction.hits[0].multiplier = row.mod_1;
faction.hits[1].id = row.id_2;
faction.hits[1].multiplier = row.mod_2;
faction.hits[2].id = row.id_3;
faction.hits[2].multiplier = row.mod_3;
faction.hits[3].id = row.id_4;
faction.hits[3].multiplier = row.mod_4;
faction.hits[4].id = row.id_5;
faction.hits[4].multiplier = row.mod_5;
faction.hits[5].id = row.id_6;
faction.hits[5].multiplier = row.mod_6;
faction.hits[6].id = row.id_7;
faction.hits[6].multiplier = row.mod_7;
faction.hits[7].id = row.id_8;
faction.hits[7].multiplier = row.mod_8;
faction.hits[8].id = row.id_9;
faction.hits[8].multiplier = row.mod_9;
faction.hits[9].id = row.id_10;
faction.hits[9].multiplier = row.mod_10;
hash.insert(row.id, faction);
}
}
bool SharedDatabase::LoadFactionAssociation(const std::string &prefix)
{
faction_associations_mmf.reset(nullptr);
faction_associations_hash.reset(nullptr);
try {
auto Config = EQEmuConfig::get();
EQ::IPCMutex mutex("factionassociations");
mutex.Lock();
std::string file_name = fmt::format("{}/{}{}", path.GetSharedMemoryPath(), prefix, std::string("factionassociations"));
faction_associations_mmf = std::unique_ptr<EQ::MemoryMappedFile>(new EQ::MemoryMappedFile(file_name));
faction_associations_hash = std::unique_ptr<EQ::FixedMemoryHashSet<FactionAssociations>>(
new EQ::FixedMemoryHashSet<FactionAssociations>(reinterpret_cast<uint8 *>(faction_associations_mmf->Get()),
faction_associations_mmf->Size()));
mutex.Unlock();
LogInfo("Loaded faction associations via shared memory");
} catch (std::exception &ex) {
LogError("Error Loading faction associations: {}", ex.what());
return false;
}
return true;
}
// Create appropriate EQ::ItemInstance class
EQ::ItemInstance* SharedDatabase::CreateItem(
uint32 item_id,
-16
View File
@@ -164,22 +164,6 @@ public:
uint32 GetSharedItemsCount() { return m_shared_items_count; }
uint32 GetItemsCount();
/**
* faction
*/
void GetFactionListInfo(uint32 &list_count, uint32 &max_lists);
const NPCFactionList *GetNPCFactionEntry(uint32 id) const;
void LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists);
bool LoadNPCFactionLists(const std::string &prefix);
/**
* faction associations
*/
void GetFactionAssociationInfo(uint32 &list_count, uint32 &max_lists);
const FactionAssociations *GetFactionAssociationHit(int id);
void LoadFactionAssociation(void *data, uint32 size, uint32 list_count, uint32 max_lists);
bool LoadFactionAssociation(const std::string &prefix);
/**
* loot
*/