NPC Faction lists to new shared memory scheme

This commit is contained in:
KimLS 2013-02-23 13:45:19 -08:00
parent 8937c5be86
commit c31b2b65c1
47 changed files with 216 additions and 2459 deletions

View File

@ -123,7 +123,6 @@ ENDIF(UNIX)
ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL})
ADD_DEFINITIONS(-DSHAREMEM)
ADD_DEFINITIONS(-DINVERSEXY)
ADD_DEFINITIONS(-DFIELD_ITEMS)
ADD_DEFINITIONS(-DMAP_DIR="./Maps")
@ -138,7 +137,6 @@ IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
ADD_SUBDIRECTORY(common)
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(EMuShareMem)
ADD_SUBDIRECTORY(shared_memory)
ADD_SUBDIRECTORY(world)
ADD_SUBDIRECTORY(zone)

View File

@ -1,40 +0,0 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(sharedmem_src
DLLMain.cpp
Doors.cpp
Items.cpp
Loot.cpp
MMF.cpp
MMFMutex.cpp
NPCFactionLists.cpp
)
SET(sharedmem_headers
Doors.h
Items.h
Loot.h
MMF.h
MMFMutex.h
NPCFactionLists.h
)
SET(EQEMU_MAX_ITEMS 300000 CACHE STRING "Maxium number of items to load into memory. Make sure this is bigger than the total number of items in the server database")
SET(EQEMU_MAX_DOORS 30000 CACHE STRING "Maxium number of doors to load into memory. Make sure this is bigger than the total number of doors in the server database")
SET(EQEMU_MAX_FACTIONLIST_IDS 50000 CACHE STRING "Maxium number of FactionList IDs to load into memory. Make sure this is bigger than the total number of FactionList IDs in the server database")
ADD_DEFINITIONS(-DMMF_EQMAX_ITEMS=${EQEMU_MAX_ITEMS})
ADD_DEFINITIONS(-DMMF_MAX_Door_ID=${EQEMU_MAX_DOORS})
ADD_DEFINITIONS(-DMMF_MAX_NPCFactionList_ID=${EQEMU_MAX_FACTIONLIST_IDS})
ADD_LIBRARY(EMuShareMem SHARED ${sharedmem_src} ${sharedmem_headers})
TARGET_LINK_LIBRARIES(EMuShareMem Common)
IF(UNIX)
TARGET_LINK_LIBRARIES(EMuShareMem "dl")
TARGET_LINK_LIBRARIES(EMuShareMem "m")
TARGET_LINK_LIBRARIES(EMuShareMem "rt")
TARGET_LINK_LIBRARIES(EMuShareMem "pthread")
ENDIF(UNIX)
SET(LIBRARY_OUTPUT_PATH ../Bin)

View File

@ -1,37 +0,0 @@
/*
EMuShareMem.dll
by Quagmire
Released under GPL
This DLL's purpose it to hold a single shared copy of items, npctypes, spells, and other
stuff that's normally cached in memory, thus allowing all processes on the server to share
one copy of the data, greatly reducing the amount of RAM used.
*/
#ifdef _WINDOWS
#include <windows.h>
void CloseMemShare();
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH: {
break;
}
case DLL_THREAD_DETACH: {
break;
}
case DLL_PROCESS_DETACH: {
break;
}
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
#endif //WIN32

View File

@ -1,136 +0,0 @@
#include "../common/debug.h"
#ifdef _WINDOWS
#include <windows.h>
#else
#include "../common/unix.h"
#endif
#include <memory.h>
#include <iostream>
using namespace std;
#include "Doors.h"
#include "../common/timer.h"
#include "MMF.h"
MMF DoorsMMF;
const MMFDoors_Struct* MMFDoorsData = 0;
MMFDoors_Struct* MMFDoorsData_Writable = 0;
#ifdef _WINDOWS
extern "C" __declspec(dllexport) const Door* GetDoor(uint32 id) {
return pGetDoor(id);
};
extern "C" __declspec(dllexport) bool AddDoor(uint32 id, const Door* door) {
return pAddDoor(id, door);
};
extern "C" __declspec(dllexport) bool DLLLoadDoors(CALLBACK_DBLoadDoors cbDBLoadDoors, uint32 iDoorstructSize, int32* iDoorsCount, uint32* iMaxDoorID) {
return pDLLLoadDoors(cbDBLoadDoors, iDoorstructSize, iDoorsCount, iMaxDoorID);
};
#else
extern "C" const Door* GetDoor(uint32 id) {
return pGetDoor(id);
};
extern "C" bool AddDoor(uint32 id, const Door* door) {
return pAddDoor(id, door);
};
extern "C" bool DLLLoadDoors(CALLBACK_DBLoadDoors cbDBLoadDoors, uint32 iDoorstructSize, int32* iDoorsCount, uint32* iMaxDoorID) {
return pDLLLoadDoors(cbDBLoadDoors, iDoorstructSize, iDoorsCount, iMaxDoorID);
};
#endif
bool pAddDoor(uint32 id, const Door* door) {
if (!MMFDoorsData_Writable)
return false;
if (id > MMF_MAX_Door_ID || MMFDoorsData_Writable->NextFreeIndex >= MMFDoorsData_Writable->DoorCount)
return false;
if (MMFDoorsData_Writable->DoorIndex[id] != 0xFFFFFFFF)
return false;
MMFDoorsData_Writable->DoorIndex[id] = MMFDoorsData_Writable->NextFreeIndex++;
memcpy(&MMFDoorsData_Writable->Doors[MMFDoorsData_Writable->DoorIndex[id]], door, sizeof(Door));
return true;
}
bool pDLLLoadDoors(CALLBACK_DBLoadDoors cbDBLoadDoors, uint32 iDoorstructSize, int32* iDoorsCount, uint32* iMaxDoorID) {
if (iDoorstructSize != sizeof(Door)) {
cout << "Error: EMuShareMem: DLLLoadDoors: iDoorstructSize != sizeof(Door)" << endl;
cout << "Door struct has changed, EMuShareMem.dll needs to be recompiled." << endl;
return false;
}
if (*iMaxDoorID > MMF_MAX_Door_ID) {
cout << "Error: EMuShareMem: pDLLLoadDoors: iMaxDoorID > MMF_MAX_Door_ID" << endl;
cout << "You need to increase the define in Doors.h." << endl;
return false;
}
uint32 tmpMemSize = sizeof(MMFDoors_Struct) + 256 + (sizeof(Door) * (*iDoorsCount));
if (DoorsMMF.Open("EQEMuDoors", tmpMemSize)) {
if (DoorsMMF.CanWrite()) {
MMFDoorsData_Writable = (MMFDoors_Struct*) DoorsMMF.GetWriteableHandle();
if (!MMFDoorsData_Writable) {
cout << "Error: EMuShareMem: DLLLoadDoors: !MMFDoorsData_Writable" << endl;
return false;
}
memset(MMFDoorsData_Writable, 0, tmpMemSize);
for(int i=0; i<MMF_MAX_Door_ID; i++)
MMFDoorsData_Writable->DoorIndex[i] = 0xFFFFFFFF;
MMFDoorsData_Writable->MaxDoorID = *iMaxDoorID;
MMFDoorsData_Writable->DoorCount = *iDoorsCount;
// use a callback so the DB functions are done in the main exe
// this way the DLL doesnt have to open a connection to mysql
if (!cbDBLoadDoors(*iDoorsCount, *iMaxDoorID)) {
cout << "Error: EMuShareMem: DLLLoadDoors: !cbDBLoadDoors" << endl;
return false;
}
MMFDoorsData_Writable = 0;
DoorsMMF.SetLoaded();
MMFDoorsData = (const MMFDoors_Struct*) DoorsMMF.GetHandle();
if (!MMFDoorsData) {
cout << "Error: EMuShareMem: DLLLoadDoors: !MMFDoorsData (CanWrite=true)" << endl;
return false;
}
return true;
}
else {
if (!DoorsMMF.IsLoaded()) {
Timer::SetCurrentTime();
uint32 starttime = Timer::GetCurrentTime();
while ((!DoorsMMF.IsLoaded()) && ((Timer::GetCurrentTime() - starttime) < 300000)) {
Sleep(10);
Timer::SetCurrentTime();
}
if (!DoorsMMF.IsLoaded()) {
cout << "Error: EMuShareMem: DLLLoadDoors: !DoorsMMF.IsLoaded() (timeout)" << endl;
return false;
}
}
MMFDoorsData = (const MMFDoors_Struct*) DoorsMMF.GetHandle();
if (!MMFDoorsData) {
cout << "Error: EMuShareMem: DLLLoadDoors: !MMFDoorsData (CanWrite=false)" << endl;
return false;
}
*iMaxDoorID = MMFDoorsData->MaxDoorID;
*iDoorsCount = MMFDoorsData->DoorCount;
return true;
}
}
else {
cout << "Error Loading Doors: Doors.cpp: pDLLLoadDoors: ret == 0" << endl;
return false;
}
return false;
};
const Door* pGetDoor(uint32 id) {
if (MMFDoorsData == 0 || (!DoorsMMF.IsLoaded()) || id > MMF_MAX_Door_ID || MMFDoorsData->DoorIndex[id] == 0xFFFFFFFF)
return 0;
return &MMFDoorsData->Doors[MMFDoorsData->DoorIndex[id]];
}

View File

@ -1,22 +0,0 @@
#include "../common/types.h"
#include "../zone/zonedump.h"
#include "../common/EMuShareMem.h"
// MMF_MAX_Door_ID: Make sure this is bigger than the highest Door ID#
#ifndef MMF_MAX_Door_ID
#define MMF_MAX_Door_ID 30000
#endif
// MMF_MAX_Door_MEM: Maxium number of Doors to load into memory. Make sure this is bigger
// than the total number of Doors in the server's database!
struct MMFDoors_Struct {
uint32 MaxDoorID;
uint32 NextFreeIndex;
uint32 DoorCount;
uint32 DoorIndex[MMF_MAX_Door_ID+1];
Door Doors[0];
};
bool pDLLLoadDoors(CALLBACK_DBLoadDoors cbDBLoadDoors, uint32 iDoorstructSize, int32* iDoorsCount, uint32* iMaxDoorID);
bool pAddDoor(uint32 id, const Door* door);
const Door* pGetDoor(uint32 id);

View File

@ -1,152 +0,0 @@
/*
Note: Do NOT change this to load items on an as-needed basis. Since this memory is
accessed from multiple threads, you'd need mutex's all over the place if it was
ever to be modified/updated/added to. The overhead of the mutexes would be alot more
in the long run than the delay in loading.
-Quagmire
*/
#ifdef _WINDOWS
#include <winsock2.h>
#include <windows.h>
#else
#include "../common/unix.h"
#endif
#include <memory.h>
#include <iostream>
using namespace std;
#include "Items.h"
#include "../common/timer.h"
#include "MMF.h"
MMF ItemsMMF;
const MMFItems_Struct* MMFItemsData = 0;
MMFItems_Struct* MMFItemsData_Writable = 0;
DLLFUNC bool AddItem(uint32 id, const Item_Struct* item) {
if (!MMFItemsData_Writable) {
return false;
}
if (id > MMF_EQMAX_ITEMS || MMFItemsData_Writable->NextFreeIndex >= MMFItemsData_Writable->ItemCount) {
return false;
}
if (MMFItemsData_Writable->ItemIndex[id] != 0xFFFF) {
return false;
}
uint32 nextid = MMFItemsData_Writable->NextFreeIndex++;
MMFItemsData_Writable->ItemIndex[id] = nextid;
memcpy(&MMFItemsData_Writable->Items[nextid], item, sizeof(Item_Struct));
return true;
}
DLLFUNC bool DLLLoadItems(CALLBACK_DBLoadItems cbDBLoadItems, uint32 iItemStructSize, int32* iItemCount, uint32* iMaxItemID) {
if (iItemStructSize != sizeof(Item_Struct)) {
cout << "Error: EMuShareMem: DLLLoadItems: iItemStructSize != sizeof(Item_Struct)" << endl;
cout << "Item_Struct has changed, EMuShareMem.dll needs to be recompiled." << endl;
return false;
}
if (*iMaxItemID > MMF_EQMAX_ITEMS) {
cout << "Error: EMuShareMem: pDLLLoadItems: iMaxItemID > MMF_EQMAX_ITEMS" << endl;
cout << "You need to increase the define in Items.h." << endl;
return false;
}
MMFItemsData_Writable = 0;
//Allocate the shared memory for the item structures
uint32 tmpMemSize = sizeof(MMFItems_Struct) + 256 + (sizeof(Item_Struct) * (*iItemCount));
//cout << tmpMemSize << endl;
if (ItemsMMF.Open("EQEMuItems", tmpMemSize)) {
if (ItemsMMF.CanWrite()) {
MMFItemsData_Writable = (MMFItems_Struct*) ItemsMMF.GetWriteableHandle();
if (!MMFItemsData_Writable) {
cout << "Error: EMuShareMem: DLLLoadItems: !MMFItemsData_Writable" << endl;
return false;
}
memset(MMFItemsData_Writable, 0, tmpMemSize);
for(int i=0; i<MMF_EQMAX_ITEMS; i++)
MMFItemsData_Writable->ItemIndex[i] = 0xFFFF;
MMFItemsData_Writable->MaxItemID = *iMaxItemID;
MMFItemsData_Writable->ItemCount = *iItemCount;
//the writable handle has been created, do the load below after we have the
//serialization handle as well.
} else {
if (!ItemsMMF.IsLoaded()) {
Timer::SetCurrentTime();
uint32 starttime = Timer::GetCurrentTime();
while ((!ItemsMMF.IsLoaded()) && ((Timer::GetCurrentTime() - starttime) < 300000)) {
Sleep(10);
Timer::SetCurrentTime();
}
if (!ItemsMMF.IsLoaded()) {
cout << "Error: EMuShareMem: DLLLoadItems: !ItemsMMF.IsLoaded() (timeout)" << endl;
return false;
}
}
MMFItemsData = (const MMFItems_Struct*) ItemsMMF.GetHandle();
if (!MMFItemsData) {
cout << "Error: EMuShareMem: DLLLoadItems: !MMFItemsData (CanWrite=false)" << endl;
return false;
}
*iMaxItemID = MMFItemsData->MaxItemID;
*iItemCount = MMFItemsData->ItemCount;
return true;
}
} else {
cout << "Error Loading Items: Items.cpp: pDLLLoadItems: Open() == false" << endl;
return false;
}
/*
// use a callback so the DB functions are done in the main exe
// this way the DLL doesnt have to open a connection to mysql
if (!cbDBLoadItems(*iItemCount, *iMaxItemID)) {
cout << "Error: EMuShareMem: DLLLoadItems: !cbDBLoadItems" << endl;
return false;
}
*/
// use a callback so the DB functions are done in the main exe
// this way the DLL doesnt have to open a connection to mysql
if (!cbDBLoadItems(*iItemCount, *iMaxItemID)) {
cout << "Error: EMuShareMem: DLLLoadItems: !cbDBLoadItems" << endl;
return false;
}
//Now, Disable the write handle and get the read handle.
//do this for both item struct and serialization data
MMFItemsData_Writable = 0;
ItemsMMF.SetLoaded();
MMFItemsData = (const MMFItems_Struct*) ItemsMMF.GetHandle();
if (!MMFItemsData) {
cout << "Error: EMuShareMem: DLLLoadItems: !MMFItemsData (CanWrite=true)" << endl;
return false;
}
return true;
};
DLLFUNC const Item_Struct* GetItem(uint32 id) {
if (MMFItemsData == 0 || (!ItemsMMF.IsLoaded()) || id > MMF_EQMAX_ITEMS || MMFItemsData->ItemIndex[id] == 0xFFFF)
return 0;
return &MMFItemsData->Items[MMFItemsData->ItemIndex[id]];
}
DLLFUNC const Item_Struct* IterateItems(uint32* NextIndex) {
if (MMFItemsData == 0 || (!ItemsMMF.IsLoaded()) || (*NextIndex) > MMF_EQMAX_ITEMS)
return 0;
do {
if (MMFItemsData->ItemIndex[*NextIndex] != 0xFFFF)
return &MMFItemsData->Items[MMFItemsData->ItemIndex[(*NextIndex)++]];
} while (++(*NextIndex) < MMF_EQMAX_ITEMS);
return 0;
}

View File

@ -1,23 +0,0 @@
#include "../common/types.h"
#include "../common/eq_packet_structs.h"
#include "../common/EMuShareMem.h"
// MMF_EQMAX_ITEMS: Make sure this is bigger than the highest item ID#
#ifndef MMF_EQMAX_ITEMS
#define MMF_EQMAX_ITEMS 300000
#endif
// MMF_MEMMAX_ITEMS: Maxium number of items to load into memory. Make sure this is bigger
// than the total number of items in the server's database!
struct MMFItems_Struct {
uint32 MaxItemID;
uint32 NextFreeIndex;
uint32 ItemCount;
uint32 ItemIndex[MMF_EQMAX_ITEMS+1];
Item_Struct Items[0];
};
//#define MMF_MAX_ITEMS_MEMSIZE sizeof(MMFItems_Struct) + 256

View File

@ -1,214 +0,0 @@
#include "../common/debug.h"
#include <memory.h>
#include <iostream>
using namespace std;
#include "Loot.h"
#include "../common/timer.h"
#include "MMF.h"
MMF LootMMF;
const MMFLoot_Struct* MMFLootData = 0;
MMFLoot_Struct* MMFLootData_Writable = 0;
uint32* LootTable;
uint32* LootDrop;
#ifdef _WINDOWS
#define exportfunc extern "C" __declspec(dllexport)
#else
#define exportfunc extern "C"
#endif
exportfunc const LootTable_Struct* GetLootTable(uint32 id) {
return pGetLootTable(id);
};
exportfunc const LootDrop_Struct* GetLootDrop(uint32 id) {
return pGetLootDrop(id);
};
exportfunc bool AddLootTable(uint32 id, const LootTable_Struct* lts) {
return pAddLootTable(id, lts);
};
exportfunc bool AddLootDrop(uint32 id, const LootDrop_Struct* lds) {
return pAddLootDrop(id, lds);
};
exportfunc bool DLLLoadLoot(CALLBACK_DBLoadLoot cbDBLoadLoot,
uint32 iLootTableStructsize, uint32 iLootTableCount, uint32 iMaxLootTable,
uint32 iLootTableEntryStructsize, uint32 iLootTableEntryCount,
uint32 iLootDropStructsize, uint32 iLootDropCount, uint32 iMaxLootDrop,
uint32 iLootDropEntryStructsize, uint32 iLootDropEntryCount
) {
return pDLLLoadLoot(cbDBLoadLoot,
iLootTableStructsize, iLootTableCount, iMaxLootTable,
iLootTableEntryStructsize, iLootTableEntryCount,
iLootDropStructsize, iLootDropCount, iMaxLootDrop,
iLootDropEntryStructsize, iLootDropEntryCount);
};
bool pAddLootTable(uint32 id, const LootTable_Struct* lts) {
if (!MMFLootData_Writable)
return false;
if (id > MMFLootData_Writable->MaxLootTableID)
return false;
if (!LootTable || LootTable[id] != 0)
return false;
uint32 tmp = sizeof(LootTable_Struct) + (sizeof(LootTableEntries_Struct) * lts->NumEntries);
if (MMFLootData_Writable->dataindex + tmp >= MMFLootData_Writable->datamax)
return false;
LootTable[id] = MMFLootData_Writable->dataindex;
memcpy(&MMFLootData_Writable->data[MMFLootData_Writable->dataindex], lts, tmp);
MMFLootData_Writable->dataindex += tmp;
return true;
}
bool pAddLootDrop(uint32 id, const LootDrop_Struct* lds) {
if (!MMFLootData_Writable)
return false;
if (id > MMFLootData_Writable->MaxLootDropID)
return false;
if (!LootDrop || LootDrop[id] != 0)
return false;
uint32 tmp = sizeof(LootDrop_Struct) + (sizeof(LootDropEntries_Struct) * lds->NumEntries);
if (MMFLootData_Writable->dataindex + tmp >= MMFLootData_Writable->datamax)
return false;
LootDrop[id] = MMFLootData_Writable->dataindex;
memcpy(&MMFLootData_Writable->data[MMFLootData_Writable->dataindex], lds, tmp);
MMFLootData_Writable->dataindex += tmp;
return true;
}
bool pDLLLoadLoot(CALLBACK_DBLoadLoot cbDBLoadLoot,
uint32 iLootTableStructsize, uint32 iLootTableCount, uint32 iMaxLootTable,
uint32 iLootTableEntryStructsize, uint32 iLootTableEntryCount,
uint32 iLootDropStructsize, uint32 iLootDropCount, uint32 iMaxLootDrop,
uint32 iLootDropEntryStructsize, uint32 iLootDropEntryCount
) {
#if 0
cout << "iLootTableCount: " << iLootTableCount << endl;
cout << "iMaxLootTable: " << iMaxLootTable << endl;
cout << "iLootTableEntryCount: " << iLootTableEntryCount << endl;
cout << "iLootDropCount: " << iLootDropCount << endl;
cout << "iMaxLootDrop: " << iMaxLootDrop << endl;
cout << "iLootDropEntryCount: " << iLootDropEntryCount << endl;
#endif
if (iLootTableStructsize != sizeof(LootTable_Struct)) {
cout << "Error: EMuShareMem: DLLLoadLoot: iLootTableStructsize != sizeof(LootTable_Struct)" << endl;
cout << "Item_Struct has changed, EMuShareMem.dll needs to be recompiled." << endl;
return false;
}
if (iLootTableEntryStructsize != sizeof(LootTableEntries_Struct)) {
cout << "Error: EMuShareMem: DLLLoadLoot: iLootTableEntryStructsize != sizeof(LootTableEntries_Struct)" << endl;
cout << "Item_Struct has changed, EMuShareMem.dll needs to be recompiled." << endl;
return false;
}
if (iLootDropStructsize != sizeof(LootDrop_Struct)) {
cout << "Error: EMuShareMem: DLLLoadLoot: iLootDropStructsize != sizeof(LootDrop_Struct)" << endl;
cout << "Item_Struct has changed, EMuShareMem.dll needs to be recompiled." << endl;
return false;
}
if (iLootDropEntryStructsize != sizeof(LootDropEntries_Struct)) {
cout << "Error: EMuShareMem: DLLLoadLoot: iLootDropEntryStructsize != sizeof(LootDropEntries_Struct)" << endl;
cout << "Item_Struct has changed, EMuShareMem.dll needs to be recompiled." << endl;
return false;
}
uint32 tmpMemSize = sizeof(MMFLoot_Struct) + 256
+ (sizeof(uint32) * (iMaxLootTable+1))
+ (sizeof(LootTable_Struct) * iLootTableCount) + (sizeof(LootTableEntries_Struct) * iLootTableEntryCount)
+ (sizeof(uint32) * (iMaxLootDrop+1))
+ (sizeof(LootDrop_Struct) * iLootDropCount) + (sizeof(LootDropEntries_Struct) * iLootDropEntryCount)
;
if (LootMMF.Open("EQEMuLoot", tmpMemSize)) {
if (LootMMF.CanWrite()) {
MMFLootData_Writable = (MMFLoot_Struct*) LootMMF.GetWriteableHandle();
if (!MMFLootData_Writable) {
cout << "Error: EMuShareMem: DLLLoadLoot: !MMFLootData_Writable" << endl;
return false;
}
memset(MMFLootData_Writable, 0, tmpMemSize);
MMFLootData_Writable->LootTableCount = iLootTableCount;
MMFLootData_Writable->MaxLootTableID = iMaxLootTable;
MMFLootData_Writable->LootDropCount = iLootDropCount;
MMFLootData_Writable->MaxLootDropID = iMaxLootDrop;
MMFLootData_Writable->datamax = tmpMemSize - sizeof(MMFLoot_Struct);
MMFLootData_Writable->dataindex = 0;
MMFLootData_Writable->LootTableOffset = MMFLootData_Writable->dataindex;
MMFLootData_Writable->dataindex += (sizeof(uint32) * (iMaxLootTable+1));
MMFLootData_Writable->LootDropOffset = MMFLootData_Writable->dataindex;
MMFLootData_Writable->dataindex += (sizeof(uint32) * (iMaxLootDrop+1));
LootTable = (uint32*) &MMFLootData_Writable->data[MMFLootData_Writable->LootTableOffset];
LootDrop = (uint32*) &MMFLootData_Writable->data[MMFLootData_Writable->LootDropOffset];
// use a callback so the DB functions are done in the main exe
// this way the DLL doesnt have to open a connection to mysql
if (!cbDBLoadLoot()) {
cout << "Error: EMuShareMem: DLLLoadLoot: !cbDBLoadLoot" << endl;
return false;
}
MMFLootData_Writable = 0;
LootMMF.SetLoaded();
}
else {
if (!LootMMF.IsLoaded()) {
Timer::SetCurrentTime();
uint32 starttime = Timer::GetCurrentTime();
while ((!LootMMF.IsLoaded()) && ((Timer::GetCurrentTime() - starttime) < 300000)) {
Sleep(10);
Timer::SetCurrentTime();
}
if (!LootMMF.IsLoaded()) {
cout << "Error: EMuShareMem: DLLLoadLoot: !LootMMF.IsLoaded() (timeout)" << endl;
return false;
}
}
}
}
else {
cout << "Error Loading Loot: Loot.cpp: pDLLLoadLoot: Open() == false" << endl;
return false;
}
MMFLootData = (const MMFLoot_Struct*) LootMMF.GetHandle();
if (!MMFLootData) {
cout << "Error: EMuShareMem: DLLLoadLoot: !MMFLootData" << endl;
MMFLootData = 0;
return false;
}
if (MMFLootData->LootTableCount != iLootTableCount
|| MMFLootData->MaxLootTableID != iMaxLootTable
|| MMFLootData->LootDropCount != iLootDropCount
|| MMFLootData->MaxLootDropID != iMaxLootDrop) {
cout << "Error: EMuShareMem: DLLLoadLoot: Count/Max mismatch" << endl;
MMFLootData = 0;
return false;
}
LootTable = (uint32*) &MMFLootData->data[MMFLootData->LootTableOffset];
LootDrop = (uint32*) &MMFLootData->data[MMFLootData->LootDropOffset];
return true;
};
const LootTable_Struct* pGetLootTable(uint32 id) {
if (MMFLootData == 0 || !LootMMF.IsLoaded())
return 0;
if (id > MMFLootData->MaxLootTableID || LootTable[id] == 0)
return 0;
return (LootTable_Struct*) &MMFLootData->data[LootTable[id]];
}
const LootDrop_Struct* pGetLootDrop(uint32 id) {
if (MMFLootData == 0 || !LootMMF.IsLoaded())
return 0;
if (id > MMFLootData->MaxLootDropID || LootDrop[id] == 0)
return 0;
return (LootDrop_Struct*) &MMFLootData->data[LootDrop[id]];
}

View File

@ -1,29 +0,0 @@
#include "../common/types.h"
#include "../common/eq_packet_structs.h"
#include "../common/EMuShareMem.h"
#pragma pack(1)
struct MMFLoot_Struct {
bool Loaded;
uint32 MaxLootTableID;
uint32 LootTableCount;
uint32 LootTableOffset;
uint32 MaxLootDropID;
uint32 LootDropCount;
uint32 LootDropOffset;
uint32 datamax;
uint32 dataindex;
uint8 data[0];
};
#pragma pack()
bool pDLLLoadLoot(CALLBACK_DBLoadLoot cbDBLoadLoot,
uint32 iLootTableStructsize, uint32 iLootTableCount, uint32 iMaxLootTable,
uint32 iLootTableEntryStructsize, uint32 iLootTableEntryCount,
uint32 iLootDropStructsize, uint32 iLootDropCount, uint32 iMaxLootDrop,
uint32 iLootDropEntryStructsize, uint32 iLootDropEntryCount
);
bool pAddLootTable(uint32 id, const LootTable_Struct* lts);
bool pAddLootDrop(uint32, const LootDrop_Struct* lds);
const LootTable_Struct* pGetLootTable(uint32 id);
const LootDrop_Struct* pGetLootDrop(uint32 id);

View File

@ -1,348 +0,0 @@
// start mingw
#ifdef __MINGW32__
#define __try
#define __finally
#endif
// end mingw
#include "MMF.h"
#include <iostream>
using namespace std;
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#ifdef _WINDOWS
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
#else
#include "MMFMutex.h"
#include "../common/unix.h"
#endif
MMF::MMF() {
SharedMemory = 0;
pCanWrite = false;
#ifdef _WINDOWS
hMapObject = NULL;
lpvMem = 0;
#else
lpvMem = 0;
pMMFMutex = 0;
m_alloc = false;
#endif
}
MMF::~MMF() {
Close();
}
bool MMF::Open(const char* iName, uint32 iSize) {
if (iSize < 1) {
cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: iSize < 1" << endl;
return false;
}
if (strlen(iName) < 2) {
cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: strlen(iName) < 2" << endl;
return false;
}
char MMFname[200];
memset(MMFname, 0, sizeof(MMFname));
snprintf(MMFname, sizeof(MMFname), "memfilemap_%s", iName);
uint32 tmpSize = sizeof(MMF_Struct) + iSize;
#ifdef _WINDOWS
char MMFMutexName[200];
memset(MMFMutexName, 0, sizeof(MMFMutexName));
snprintf(MMFMutexName, sizeof(MMFMutexName), "MutexToProtectOpenMMF_%s", iName);
HANDLE hMutex;
hMutex = CreateMutex(
NULL, // no security attributes
FALSE, // initially not owned
MMFMutexName); // name of mutex
if (hMutex == NULL) {
cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: hMutex == Null" << endl;
return false;
}
DWORD dwWaitResult;
// Request ownership of mutex.
dwWaitResult = WaitForSingleObject(
hMutex, // handle to mutex
2000L); // two-second time-out interval
if (dwWaitResult != WAIT_OBJECT_0) {
// Mutex not aquired, crap out
cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: dwWaitResult != WAIT_OBJECT_0" << endl;
return false;
}
// Finally, ready to rock.
bool fInit = false;
__try {
hMapObject = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security attributes
PAGE_READWRITE, // read/write access
0, // size: high 32-bits
tmpSize, // size: low 32-bits
MMFname); // name of map object
if (hMapObject == NULL) {
cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: hMapObject == Null" << endl;
return false;
}
// The first process to attach initializes memory.
fInit = (bool) (GetLastError() != ERROR_ALREADY_EXISTS);
// Get a pointer to the file-mapped shared memory.
lpvMem = MapViewOfFile(
hMapObject, // object to map view of
FILE_MAP_WRITE, // read/write access
0, // high offset: map from
0, // low offset: beginning
0); // default: map entire file
if (lpvMem == NULL) {
cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: lpvMem == Null" << endl;
Close();
return false;
}
SharedMemory = (MMF_Struct*) lpvMem;
// Initialize memory if this is the first process.
if (fInit) {
memset(lpvMem, 0, sizeof(MMF_Struct));
pCanWrite = true;
SharedMemory->Loaded = false;
SharedMemory->datasize = iSize;
}
else {
pCanWrite = false;
if (SharedMemory->datasize != iSize) {
cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: SharedMemory->datasize != iSize" << endl;
Close();
return false;
}
}
} // end of try block
__finally {
// Clean up the Mutex stuff
if (!ReleaseMutex(hMutex)) {
cout << "Error Loading MMF: " << __FILE__ << ":" << __LINE__ << " OpenMMF: !ReleaseMutex(hMutex)" << endl;
Close();
return false;
}
}
CloseHandle(hMutex);
return true;
#else //else, NOT WINDOWS
int load_share;
//int max_share = 7;
key_t share_key;
switch (MMFname[16]) {
case 'I': load_share = 0; break;
case 'N': load_share = 1; break;
case 'D': load_share = 2; break;
case 'S': load_share = 3; break;
case 'F': load_share = 4; break;
case 'L': load_share = 5; break;
case 'M': load_share = 6; break;
case 'O': load_share = 7; break;
case 'Z': load_share = 8; break;
case 'K': load_share = 9; break;
default:
cerr << "FATAL=" << (char)MMFname[16] << endl;
return false;
break;
}
switch (load_share) {
// Item
case 0: share_key = ftok(".", 'I'); break;
// Npctype
case 1: share_key = ftok(".", 'N'); break;
// Door
case 2: share_key = ftok(".", 'D'); break;
// Spell
case 3: share_key = ftok(".", 'S'); break;
// Faction
case 4: share_key = ftok(".", 'F'); break;
// Loot
case 5: share_key = ftok(".", 'L'); break;
// ??
case 6: share_key = ftok(".", 'M'); break;
// Opcodes
case 7: share_key = ftok(".", 'O'); break;
// Item Serialization
case 8: share_key = ftok(".", 'Z'); break;
// Skills
case 9: share_key = ftok(".", 'K'); break;
// ERROR Fatal
default: cerr<<"Opps!"<<endl; share_key = 0xFF; break;
}
pMMFMutex = new MMFMutex(share_key);
if (!pMMFMutex){
assert(false);
}
//if (!tmpSize) {
int share_id = shmget(share_key, tmpSize, IPC_CREAT|IPC_EXCL|SHM_R|SHM_W);
if ( share_id <= 0) {
share_id = shmget(share_key, tmpSize, IPC_CREAT|IPC_NOWAIT);
if (share_id <= 0) {
shmid_ds mem_size;
share_id = shmget(share_key, 1, IPC_CREAT|IPC_NOWAIT|SHM_R|SHM_W);
if(share_id == -1) {
cerr << "failed to get 0-length shared mem: " << strerror(errno) << endl;
}
if ((lpvMem = shmat(share_id, NULL,SHM_RDONLY)) == (void *)-1) {
cerr << "shmat failed! " << strerror(errno) << endl;
}
if( (shmctl(share_id, IPC_STAT, &mem_size)) == 0){
if (mem_size.shm_segsz != int(tmpSize)){ //comparison between signed and unsigned integer expressions
cout<<"[Warning] requested shared memory of size:"<<tmpSize<<" but that Key is already in use with size:"<< mem_size.shm_segsz<<endl;
shmid_ds mem_users;
if( (shmctl(share_id, IPC_STAT, &mem_users)) == 0 && mem_users.shm_nattch == 1){
cout<<"[Warning] Attempting resize"<<endl;
shmctl(share_id, IPC_RMID, 0);
shmdt(lpvMem);
if ((share_id = shmget(share_key, tmpSize, IPC_CREAT|IPC_EXCL|SHM_R|SHM_W)) <= 0) {
// Failed proceed on malloc
cerr<<"[Error] Failed to resize" << strerror(errno) <<endl;
}
else{
cerr<<"[Error] Resize successful." << endl;
// Success
lpvMem = shmat(share_id, NULL, SHM_R|SHM_W);
memset(lpvMem, 0, sizeof(MMF_Struct));
pCanWrite = true;
SharedMemory = (MMF_Struct*) lpvMem;
SharedMemory->Loaded = false;
SharedMemory->datasize = iSize;
pMMFMutex->Release(this);
delete pMMFMutex;
return true;
}
}
else{
cout<<"[Warning] Resize not possible"<<endl;
}
}
}
// Can not attatch to shared memory we'll malloc it here
if ((lpvMem == 0 || lpvMem == (void *)-1) && (lpvMem = malloc(tmpSize))) {
cout<<"[Warning] Could not attach to shared memory proceeding on isolated memory (share_id <= 0)"<<endl;
// Success!
m_alloc = true;
memset(lpvMem, 0, sizeof(MMF_Struct));
pCanWrite = true;
SharedMemory = (MMF_Struct*) lpvMem;
SharedMemory->datasize = iSize;
SharedMemory->Loaded = false;
pMMFMutex->Release(this);
delete pMMFMutex;
return true;
} else if (!lpvMem){
//LogFile->write(EQEMuLog::Error, "Could not connect to shared memory and allocation of isolated memory failed.");
cout<<"Could not connect to shared memory and allocation of isolated memory failed."<<endl;
pMMFMutex->Release(this);
delete pMMFMutex;
exit(1);
}
pCanWrite = false;
SharedMemory = (MMF_Struct*) lpvMem;
if (SharedMemory->datasize != iSize) {
cerr<<"SharedMemory->datasize("<<SharedMemory->datasize<<") != iSize("<<iSize<<"), We can rebuild him faster better STRONGER!"<<endl;
cerr<<"Or not.. restart all servers on this machine"<<endl;
shmctl(share_id, IPC_RMID, 0);
pMMFMutex->Release(this);
exit(1);
}
pMMFMutex->Release(this);
delete pMMFMutex;
return true;
}
shmid_ds mem_users;
if ((shmctl(share_id, IPC_STAT, &mem_users)) != 0) {
if ((lpvMem = malloc(tmpSize))) {
// Success!
cout<<"[Warning] Could not attach to shared memory proceeding on isolated memory"<<endl;
m_alloc = true;
memset(lpvMem, 0, sizeof(MMF_Struct));
pCanWrite = true;
SharedMemory = (MMF_Struct*) lpvMem;
SharedMemory->datasize = iSize;
SharedMemory->Loaded = false;
pMMFMutex->Release(this);
delete pMMFMutex;
return true;
} else {
//LogFile->write(EQEMuLog::Error, "Could not connect to shared memory and allocation of isolated memory failed.");
cout<<"Could not connect to shared memory and allocation of isolated memory failed."<<endl;
pMMFMutex->Release(this);
delete pMMFMutex;
exit(1);
}
}
lpvMem = shmat(share_id, NULL,SHM_RDONLY);
pCanWrite = false;
SharedMemory = (MMF_Struct*) lpvMem;
//cerr << "lpvMem=" << (int)lpvMem << endl;
if (lpvMem==(void *)-1 || SharedMemory->datasize != iSize) {
cerr<<"SharedMemory->datasize("<<SharedMemory->datasize<<") != iSize("<<iSize<<"), or "<<((void *)lpvMem)<<"==-1, We can rebuild him faster better STRONGER!"<<endl;
cerr<<"Or not.. restart all servers on this machine"<<endl;
shmctl(share_id, IPC_RMID, 0);
pMMFMutex->Release(this);
exit(1);
}
pMMFMutex->Release(this);
delete pMMFMutex;
return true;
}
lpvMem = shmat(share_id, NULL, SHM_R|SHM_W);
memset(lpvMem, 0, sizeof(MMF_Struct));
pCanWrite = true;
SharedMemory = (MMF_Struct*) lpvMem;
SharedMemory->Loaded = false;
SharedMemory->datasize = iSize;
//}
pMMFMutex->Release(this);
delete pMMFMutex;
return true;
#endif //end NOT WINDOWS
}
void MMF::Close() {
SharedMemory = 0;
pCanWrite = false;
#ifdef _WINDOWS
if (lpvMem) {
// Unmap shared memory from the process's address space.
UnmapViewOfFile(lpvMem);
lpvMem = 0;
}
if (hMapObject) {
// Close the process's handle to the file-mapping object.
CloseHandle(hMapObject);
hMapObject = NULL;
}
#else
if (lpvMem) {
if (m_alloc == true)
free(lpvMem);
else
if (shmdt(lpvMem) == -1)
//LogFile->write(EQEMuLog::Error, "Warning something odd happened freeing shared memory");
cout<<"Warning something odd happened freeing shared memory"<<endl;
lpvMem = 0;
}
#endif
}

View File

@ -1,46 +0,0 @@
#ifndef MMF_H
#define MMF_H
#include "../common/types.h"
#ifdef _WINDOWS
#include <windows.h>
#else
//#include "MMFMutex.h"
class MMFMutex;
#endif
class MMF {
public:
struct MMF_Struct {
bool Loaded;
uint32 datasize;
uint8 data[0];
};
MMF();
virtual ~MMF();
bool Open(const char* iName, uint32 iSize);
void Close();
const void* GetHandle() { if (IsLoaded()) { return SharedMemory->data; } return 0; }
void* GetWriteableHandle() { if (!IsLoaded() && CanWrite()) { return SharedMemory->data; } return 0; }
inline bool IsOpen() { return (bool) (SharedMemory != 0); }
inline bool IsLoaded() { if (SharedMemory) { return SharedMemory->Loaded; } return false; }
bool SetLoaded() { if (SharedMemory && CanWrite()) { SharedMemory->Loaded = true; return true; } return false; }
inline bool CanWrite() { if (SharedMemory) { return pCanWrite; } return false; }
#ifndef WIN32
bool m_alloc;
#endif
private:
bool pCanWrite;
MMF_Struct* SharedMemory;
#ifdef _WINDOWS
HANDLE hMapObject;
LPVOID lpvMem;
#else
void* lpvMem;
MMFMutex* pMMFMutex;
#endif
};
#endif

View File

@ -1,126 +0,0 @@
#include "MMFMutex.h"
#ifndef WIN32
MMFMutex::MMFMutex( int key )
{
m_key = key;
if( m_key == 0 )
{
// initialize POSIX semaphore
sem_init( &m_semaphore, 0, 1);
}
else
{
// currently, this thread does not own the semaphore
m_owner = 0;
m_recursive_count = 0;
// try to get an existing semaphore. the access permissions are "full access for everyone"
m_id = semget(m_key, 1, 0x1b6);
if( m_id == -1 )
{
// it doesn't exist yet, try to create a new one
m_id = semget(m_key, 1, IPC_CREAT | 0x1b6);
if( m_id != -1 )
{
// initialize it to 1
semun data;
data.val = 1;
semctl(m_id, 0, SETVAL, data);
}
}
}
}
MMFMutex::~MMFMutex()
{
if( m_key == 0 )
{
sem_destroy(&m_semaphore);
}
else
{
semctl(m_id, 0, IPC_RMID, 0);
}
}
bool MMFMutex::Lock( uint32 dwTimeout )
{
if( m_owner == pthread_self() )
{
m_recursive_count++;
return true;
}
bool bUseTimeout = (dwTimeout != 0);
while(true) {
bool bGotSemaphore = false;
if( m_key == 0 )
{
bGotSemaphore = (sem_trywait(&m_semaphore) == 0);
}
else
{
struct sembuf operations[1];
operations[0].sem_num = 0;
operations[0].sem_op = -1;
operations[0].sem_flg = SEM_UNDO|IPC_NOWAIT;
bGotSemaphore = (semop(m_id, operations, 1) >= 0);
}
if( bGotSemaphore )
{
m_owner = pthread_self();
m_recursive_count = 1;
return true;
}
sleep(1);
if( bUseTimeout )
{
if( dwTimeout > 1000 )
dwTimeout -= 1000;
else
dwTimeout = 0;
if( dwTimeout == 0 )
return false;
}
}
}
void MMFMutex::Release(const MMF* pMMF)
{
if( m_owner != pthread_self() && pMMF->m_alloc != true )
{
//We're supposed to explode here with an assert
//assert(false);
}
else if ( pMMF->m_alloc == true ){
// Just do it nothing is useing but us
return;
}
else if( m_recursive_count > 1 )
{
m_recursive_count--;
}
else
{
if( m_key == 0 )
{
sem_post(&m_semaphore);
}
else
{
struct sembuf operations[1];
operations[0].sem_num = 0;
operations[0].sem_op = 1;
operations[0].sem_flg = SEM_UNDO;
semop(m_id, operations, 1);
}
m_recursive_count = 0;
m_owner = 0;
}
}
#endif //!WIN32

View File

@ -1,43 +0,0 @@
#ifndef MMFMUTEX_H
#define MMFMUTEX_H
#ifndef WIN32
#include <sys/types.h> // moved before sys/shm.h for freeBSD
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
#include "../common/types.h"
#include "MMF.h"
// the manuals say you have to define this struct your self.
#if !defined FREEBSD || defined __NetBSD__ // for BSDs
union semun
{
int val;
struct semid_ds* buf;
unsigned short int *array;
struct seminfo *__buf;
};
#endif // for freeBSD
class MMFMutex
{
public:
MMFMutex(int iIndex);
virtual ~MMFMutex();
bool Lock( uint32 dwTimeout = 0 );
void Release(const MMF*);
protected:
int m_id;
key_t m_key;
pthread_t m_owner;
sem_t m_semaphore;
int m_recursive_count;
};
#endif //!WIN32
#endif

View File

@ -1,178 +0,0 @@
#include "../common/debug.h"
#ifdef _WINDOWS
#include <windows.h>
#else
#include "../common/unix.h"
#endif
#include <memory.h>
#include <iostream>
using namespace std;
#include "NPCFactionLists.h"
#include "../common/timer.h"
#include "MMF.h"
MMF NPCFactionListsMMF;
const MMFNPCFactionLists_Struct* MMFNPCFactionListsData = 0;
MMFNPCFactionLists_Struct* MMFNPCFactionListsData_Writable = 0;
#ifdef _WINDOWS
extern "C" __declspec(dllexport) const NPCFactionList* GetNPCFactionList(uint32 id) {
return pGetNPCFactionList(id);
};
extern "C" __declspec(dllexport) bool AddNPCFactionList(uint32 id, const NPCFactionList* nfl) {
return pAddNPCFactionList(id, nfl);
};
extern "C" __declspec(dllexport) bool DLLLoadNPCFactionLists(CALLBACK_DBLoadNPCFactionLists cbDBLoadNPCFactionLists, uint32 iNPCFactionListStructSize, int32* iNPCFactionListsCount, uint32* iMaxNPCFactionListID, uint8 iMaxNPCFactions) {
return pDLLLoadNPCFactionLists(cbDBLoadNPCFactionLists, iNPCFactionListStructSize, iNPCFactionListsCount, iMaxNPCFactionListID, iMaxNPCFactions);
};
extern "C" __declspec(dllexport) bool SetNPCFaction(uint32 id, uint32* factionid, int32* factionvalue, int8 *factionnpcvalue, uint8 *factiontemp) {
return pSetNPCFaction(id, factionid, factionvalue, factionnpcvalue, factiontemp);
}
#else
extern "C" const NPCFactionList* GetNPCFactionList(uint32 id) {
return pGetNPCFactionList(id);
};
extern "C" bool AddNPCFactionList(uint32 id, const NPCFactionList* nfl) {
return pAddNPCFactionList(id, nfl);
};
extern "C" bool DLLLoadNPCFactionLists(CALLBACK_DBLoadNPCFactionLists cbDBLoadNPCFactionLists, uint32 iNPCFactionListStructSize, int32* iNPCFactionListsCount, uint32* iMaxNPCFactionListID, uint8 iMaxNPCFactions) {
return pDLLLoadNPCFactionLists(cbDBLoadNPCFactionLists, iNPCFactionListStructSize, iNPCFactionListsCount, iMaxNPCFactionListID, iMaxNPCFactions);
};
extern "C" bool SetNPCFaction(uint32 id, uint32* factionid, int32* factionvalue, int8 *factionnpcvalue, uint8 *factiontemp) {
return pSetNPCFaction(id, factionid, factionvalue, factionnpcvalue, factiontemp);
}
#endif
bool pAddNPCFactionList(uint32 id, const NPCFactionList* nfl) {
if (!MMFNPCFactionListsData_Writable){
if (EQDEBUG>=1) cout<<"[Debug] !MMFNPCFactionListsData_Writable"<<endl;
return false;
}
if (id > MMF_MAX_NPCFactionList_ID || MMFNPCFactionListsData_Writable->NextFreeIndex >= MMFNPCFactionListsData_Writable->NPCFactionListCount){
if (EQDEBUG>=1) cout<<"[Debug] id > MMF_MAX_NPCFactionList_ID || MMFNPCFactionListsData_Writable->NextFreeIndex >= MMFNPCFactionListsData_Writable->NPCFactionListCount"<<endl;
return false;
}
if (MMFNPCFactionListsData_Writable->NPCFactionListIndex[id] != 0xFFFFFFFF){
if (EQDEBUG>=1) cout<<"[Debug] MMFNPCFactionListsData_Writable->NPCFactionListIndex[id] != 0xFFFFFFFF"<<endl;
return false;
}
MMFNPCFactionListsData_Writable->NPCFactionListIndex[id] = MMFNPCFactionListsData_Writable->NextFreeIndex++;
memcpy(&MMFNPCFactionListsData_Writable->NPCFactionLists[MMFNPCFactionListsData_Writable->NPCFactionListIndex[id]], nfl, sizeof(NPCFactionList));
return true;
}
bool pSetNPCFaction(uint32 id, uint32* factionid, int32* factionvalue, int8 *factionnpcvalue, uint8 *factiontemp) {
if (!MMFNPCFactionListsData_Writable) {
if(EQDEBUG>=1) cout<<"[Debug] !MMFNPCFactionListsData_Writable"<<endl;
return false;
}
if (id > MMF_MAX_NPCFactionList_ID) {
if(EQDEBUG>=1) cout<<"[Debug] id > MMF_MAX_NPCFactionList_ID"<<endl;
return false;
}
if (MMFNPCFactionListsData_Writable->NPCFactionListIndex[id] == 0xFFFFFFFF) {
if(EQDEBUG>=1) cout<<"[Debug] MMFNPCFactionListsData_Writable->NPCFactionListIndex[id="<<id<<"] == 0xFFFFFFFF"<<endl;
return false;
}
for (int i=0; i<MAX_NPC_FACTIONS; i++) {
MMFNPCFactionListsData_Writable->NPCFactionLists[MMFNPCFactionListsData_Writable->NPCFactionListIndex[id]].factionid[i] = factionid[i];
MMFNPCFactionListsData_Writable->NPCFactionLists[MMFNPCFactionListsData_Writable->NPCFactionListIndex[id]].factionvalue[i] = factionvalue[i];
MMFNPCFactionListsData_Writable->NPCFactionLists[MMFNPCFactionListsData_Writable->NPCFactionListIndex[id]].factionnpcvalue[i] = factionnpcvalue[i];
MMFNPCFactionListsData_Writable->NPCFactionLists[MMFNPCFactionListsData_Writable->NPCFactionListIndex[id]].factiontemp[i] = factiontemp[i];
}
return true;
}
bool pDLLLoadNPCFactionLists(CALLBACK_DBLoadNPCFactionLists cbDBLoadNPCFactionLists, uint32 iNPCFactionListStructSize, int32* iNPCFactionListsCount, uint32* iMaxNPCFactionListID, uint8 iMaxNPCFactions) {
if (iNPCFactionListStructSize != sizeof(NPCFactionList)) {
cout << "Error: EMuShareMem: DLLLoadNPCFactionLists: iNPCFactionListStructSize != sizeof(NPCFactionList)" << endl;
cout << "NPCFactionList struct has changed, EMuShareMem.dll needs to be recompiled." << endl;
return false;
}
if (iMaxNPCFactions != MAX_NPC_FACTIONS) {
cout << "Error: EMuShareMem: DLLLoadNPCFactionLists: iMaxNPCFactions != MAX_NPC_FACTIONS" << endl;
cout << "NPCFactionList struct has changed, EMuShareMem.dll needs to be recompiled." << endl;
return false;
}
if (*iMaxNPCFactionListID > MMF_MAX_NPCFactionList_ID) {
cout << "Error: EMuShareMem: DLLLoadNPCFactionLists: iMaxNPCFactions > MMF_MAX_NPCFactionList_ID" << endl;
cout << "You need to increase the define in NPCFactionList.h." << endl;
return false;
}
uint32 tmpMemSize = sizeof(MMFNPCFactionLists_Struct) + 256 + (sizeof(NPCFactionList) * (*iNPCFactionListsCount));
if (NPCFactionListsMMF.Open("EQEMuFactionLists", tmpMemSize)) {
// MMFNPCFactionListsData = (const MMFNPCFactionLists_Struct*) NPCFactionListsMMF.GetHandle();
if (NPCFactionListsMMF.CanWrite()) {
MMFNPCFactionListsData_Writable = (MMFNPCFactionLists_Struct*) NPCFactionListsMMF.GetWriteableHandle();
if (!MMFNPCFactionListsData_Writable) {
cout << "Error: EMuShareMem: DLLLoadNPCFactionLists: !MMFNPCFactionListsData_Writable" << endl;
return false;
}
memset(MMFNPCFactionListsData_Writable, 0, tmpMemSize);
for(int i=0; i<MMF_MAX_NPCFactionList_ID; i++)
MMFNPCFactionListsData_Writable->NPCFactionListIndex[i] = 0xFFFFFFFF;
MMFNPCFactionListsData_Writable->MaxNPCFactionListID = *iMaxNPCFactionListID;
MMFNPCFactionListsData_Writable->NPCFactionListCount = *iNPCFactionListsCount;
// use a callback so the DB functions are done in the main exe
// this way the DLL doesnt have to open a connection to mysql
if (!cbDBLoadNPCFactionLists(MMFNPCFactionListsData_Writable->NPCFactionListCount, MMFNPCFactionListsData_Writable->MaxNPCFactionListID)) {
cout << "Error: EMuShareMem: DLLLoadNPCFactionLists: !cbDBLoadNPCFactionLists" << endl;
return false;
}
MMFNPCFactionListsData_Writable = 0;
NPCFactionListsMMF.SetLoaded();
MMFNPCFactionListsData = (const MMFNPCFactionLists_Struct*) NPCFactionListsMMF.GetHandle();
if (!MMFNPCFactionListsData) {
cout << "Error: EMuShareMem: DLLLoadNPCFactionLists: !MMFNPCFactionListsData (CanWrite=true)" << endl;
return false;
}
return true;
}
else {
if (!NPCFactionListsMMF.IsLoaded()) {
Timer::SetCurrentTime();
uint32 starttime = Timer::GetCurrentTime();
while ((!NPCFactionListsMMF.IsLoaded()) && ((Timer::GetCurrentTime() - starttime) < 300000)) {
Sleep(100);
Timer::SetCurrentTime();
}
if (!NPCFactionListsMMF.IsLoaded()) {
cout << "Error: EMuShareMem: DLLLoadNPCFactionLists: !NPCFactionListsMMF.IsLoaded() (timeout)" << endl;
return false;
}
}
MMFNPCFactionListsData = (const MMFNPCFactionLists_Struct*) NPCFactionListsMMF.GetHandle();
if (!MMFNPCFactionListsData) {
cout << "Error: EMuShareMem: DLLLoadNPCFactionLists: !MMFNPCFactionListsData (CanWrite=false)" << endl;
return false;
}
*iMaxNPCFactionListID = MMFNPCFactionListsData->MaxNPCFactionListID;
*iNPCFactionListsCount = MMFNPCFactionListsData->NPCFactionListCount;
return true;
}
}
else {
cout << "Error Loading NPCFactionLists: NPCFactionLists.cpp: pDLLLoadNPCFactionLists: Open() == false" << endl;
return false;
}
return false;
};
const NPCFactionList* pGetNPCFactionList(uint32 id) {
if (MMFNPCFactionListsData == 0 || (!NPCFactionListsMMF.IsLoaded()) || id > MMF_MAX_NPCFactionList_ID || MMFNPCFactionListsData->NPCFactionListIndex[id] == 0xFFFFFFFF)
return 0;
return &MMFNPCFactionListsData->NPCFactionLists[MMFNPCFactionListsData->NPCFactionListIndex[id]];
}

View File

@ -1,22 +0,0 @@
#include "../common/types.h"
#include "../common/features.h"
#include "../zone/faction.h"
#include "../common/EMuShareMem.h"
// MMF_MAX_NPCFactionList_ID: Make sure this is bigger than the highest NPCFactionList ID#
#ifndef MMF_MAX_NPCFactionList_ID
#define MMF_MAX_NPCFactionList_ID 50000
#endif
struct MMFNPCFactionLists_Struct {
uint32 MaxNPCFactionListID;
uint32 NextFreeIndex;
uint32 NPCFactionListCount;
uint32 NPCFactionListIndex[MMF_MAX_NPCFactionList_ID+1];
NPCFactionList NPCFactionLists[0];
};
bool pDLLLoadNPCFactionLists(CALLBACK_DBLoadNPCFactionLists cbDBLoadNPCFactionLists, uint32 iNPCFactionListStructSize, int32* iNPCFactionListCount, uint32* iMaxNPCFactionListID, uint8 iMaxNPCFactions);
bool pAddNPCFactionList(uint32 id, const NPCFactionList* nfl);
bool pSetNPCFaction(uint32 id, uint32* factionid, int32* factionvalue, int8 *factionnpcvalue, uint8 *factiontemp);
const NPCFactionList* pGetNPCFactionList(uint32 id);

View File

@ -1,137 +0,0 @@
#include "../common/debug.h"
#ifdef _WINDOWS
#include <windows.h>
#else
#include "../common/unix.h"
#endif
#include <memory.h>
#include <iostream>
using namespace std;
#include "NPCTypes.h"
#include "../common/timer.h"
#include "MMF.h"
MMF NPCTypesMMF;
const MMFNPCTypes_Struct* MMFNPCTypesData = 0;
MMFNPCTypes_Struct* MMFNPCTypesData_Writable = 0;
#ifdef _WINDOWS
extern "C" __declspec(dllexport) const NPCType* GetNPCType(uint32 id) {
return pGetNPCType(id);
};
extern "C" __declspec(dllexport) bool AddNPCType(uint32 id, const NPCType* npctype) {
return pAddNPCType(id, npctype);
};
/*extern "C" __declspec(dllexport) bool DLLLoadNPCTypes(CALLBACK_DBLoadNPCTypes cbDBLoadNPCTypes, uint32 iNPCTypeStructSize, int32* iNPCTypesCount, uint32* iMaxNPCTypeID) {
return pDLLLoadNPCTypes(cbDBLoadNPCTypes, iNPCTypeStructSize, iNPCTypesCount, iMaxNPCTypeID);
};*/
#else
extern "C" const NPCType* GetNPCType(uint32 id) {
return pGetNPCType(id);
};
extern "C" bool AddNPCType(uint32 id, const NPCType* npctype) {
return pAddNPCType(id, npctype);
};
extern "C" bool DLLLoadNPCTypes(CALLBACK_DBLoadNPCTypes cbDBLoadNPCTypes, uint32 iNPCTypeStructSize, int32* iNPCTypesCount, uint32* iMaxNPCTypeID) {
return pDLLLoadNPCTypes(cbDBLoadNPCTypes, iNPCTypeStructSize, iNPCTypesCount, iMaxNPCTypeID);
};
#endif
bool pAddNPCType(uint32 id, const NPCType* npctype) {
if (!MMFNPCTypesData_Writable)
return false;
if (id > MMF_MAX_NPCTYPE_ID || MMFNPCTypesData_Writable->NextFreeIndex >= MMFNPCTypesData_Writable->NPCTypeCount)
return false;
if (MMFNPCTypesData_Writable->NPCTypeIndex[id] != 0xFFFFFFFF)
return false;
MMFNPCTypesData_Writable->NPCTypeIndex[id] = MMFNPCTypesData_Writable->NextFreeIndex++;
memcpy(&MMFNPCTypesData_Writable->NPCTypes[MMFNPCTypesData_Writable->NPCTypeIndex[id]], npctype, sizeof(NPCType));
return true;
}
/*bool pDLLLoadNPCTypes(CALLBACK_DBLoadNPCTypes cbDBLoadNPCTypes, uint32 iNPCTypeStructSize, int32* iNPCTypesCount, uint32* iMaxNPCTypeID) {
if (iNPCTypeStructSize != sizeof(NPCType)) {
cout << "Error: EMuShareMem: DLLLoadNPCTypes: iNPCTypeStructSize != sizeof(NPCType)" << endl;
cout << "NPCType struct has changed, EMuShareMem.dll needs to be recompiled." << endl;
return false;
}
if (*iMaxNPCTypeID > MMF_MAX_NPCTYPE_ID) {
cout << "Error: EMuShareMem: pDLLLoadNPCTypes: iMaxNPCTypeID > MMF_MAX_NPCTYPE_ID" << endl;
cout << "You need to increase the define in NPCTypes.h." << endl;
return false;
}
uint32 tmpMemSize = sizeof(MMFNPCTypes_Struct) + 256 + (sizeof(NPCType) * (*iNPCTypesCount));
if (NPCTypesMMF.Open("EQEMuNPCTypes", tmpMemSize)) {
// MMFNPCTypesData = (const MMFNPCTypes_Struct*) NPCTypesMMF.GetHandle();
if (NPCTypesMMF.CanWrite()) {
MMFNPCTypesData_Writable = (MMFNPCTypes_Struct*) NPCTypesMMF.GetWriteableHandle();
if (!MMFNPCTypesData_Writable) {
cout << "Error: EMuShareMem: DLLLoadNPCTypes: !MMFNPCTypesData_Writable" << endl;
return false;
}
memset(MMFNPCTypesData_Writable, 0, tmpMemSize);
for(int i=0; i<MMF_MAX_NPCTYPE_ID; i++)
MMFNPCTypesData_Writable->NPCTypeIndex[i] = 0xFFFFFFFF;
MMFNPCTypesData_Writable->MaxNPCTypeID = *iMaxNPCTypeID;
MMFNPCTypesData_Writable->NPCTypeCount = *iNPCTypesCount;
// use a callback so the DB functions are done in the main exe
// this way the DLL doesnt have to open a connection to mysql
if (!cbDBLoadNPCTypes(MMFNPCTypesData_Writable->NPCTypeCount, MMFNPCTypesData_Writable->MaxNPCTypeID)) {
cout << "Error: EMuShareMem: DLLLoadNPCTypes: !cbDBLoadNPCTypes" << endl;
return false;
}
MMFNPCTypesData_Writable = 0;
NPCTypesMMF.SetLoaded();
MMFNPCTypesData = (const MMFNPCTypes_Struct*) NPCTypesMMF.GetHandle();
if (!MMFNPCTypesData) {
cout << "Error: EMuShareMem: DLLLoadNPCTypes: !MMFNPCTypesData (CanWrite=true)" << endl;
return false;
}
return true;
}
else {
if (!NPCTypesMMF.IsLoaded()) {
Timer::SetCurrentTime();
uint32 starttime = Timer::GetCurrentTime();
while ((!NPCTypesMMF.IsLoaded()) && ((Timer::GetCurrentTime() - starttime) < 300000)) {
Sleep(100);
Timer::SetCurrentTime();
}
if (!NPCTypesMMF.IsLoaded()) {
cout << "Error: EMuShareMem: DLLLoadNPCTypes: !NPCTypesMMF.IsLoaded() (timeout)" << endl;
return false;
}
}
MMFNPCTypesData = (const MMFNPCTypes_Struct*) NPCTypesMMF.GetHandle();
if (!MMFNPCTypesData) {
cout << "Error: EMuShareMem: DLLLoadNPCTypes: !MMFNPCTypesData (CanWrite=false)" << endl;
return false;
}
*iMaxNPCTypeID = MMFNPCTypesData->MaxNPCTypeID;
*iNPCTypesCount = MMFNPCTypesData->NPCTypeCount;
return true;
}
}
else {
cout << "Error Loading NPCTypes: NPCTypes.cpp: pDLLLoadNPCTypes: Open() == false" << endl;
return false;
}
return false;
};*/
const NPCType* pGetNPCType(uint32 id) {
if (MMFNPCTypesData == 0 || (!NPCTypesMMF.IsLoaded()) || id > MMF_MAX_NPCTYPE_ID || MMFNPCTypesData->NPCTypeIndex[id] == 0xFFFFFFFF)
return 0;
return &MMFNPCTypesData->NPCTypes[MMFNPCTypesData->NPCTypeIndex[id]];
}

View File

@ -1,18 +0,0 @@
#include "../common/types.h"
#include "../zone/zonedump.h"
#include "../common/EMuShareMem.h"
// MMF_MAX_NPCTYPE_ID: Make sure this is bigger than the highest NPCType ID#
#define MMF_MAX_NPCTYPE_ID 400000
struct MMFNPCTypes_Struct {
uint32 MaxNPCTypeID;
uint32 NextFreeIndex;
uint32 NPCTypeCount;
uint32 NPCTypeIndex[MMF_MAX_NPCTYPE_ID+1];
NPCType NPCTypes[0];
};
//bool pDLLLoadNPCTypes(CALLBACK_DBLoadNPCTypes cbDBLoadNPCTypes, uint32 iNPCTypeStructSize, int32* iNPCTypesCount, uint32* iMaxNPCTypeID);
bool pAddNPCType(uint32 id, const NPCType* npctype);
const NPCType* pGetNPCType(uint32 id);

View File

@ -13,7 +13,6 @@ SET(common_sources
DBMemLeak.cpp
debug.cpp
emu_opcodes.cpp
EMuShareMem.cpp
EmuTCPConnection.cpp
EmuTCPServer.cpp
EQDB.cpp
@ -54,7 +53,6 @@ SET(common_sources
rulesys.cpp
serverinfo.cpp
shareddb.cpp
SharedLibrary.cpp
spdat.cpp
StructStrategy.cpp
TCPConnection.cpp
@ -108,7 +106,6 @@ SET(common_headers
deity.h
emu_opcodes.h
emu_oplist.h
EMuShareMem.h
EmuTCPConnection.h
EmuTCPServer.h
eq_constants.h
@ -130,6 +127,7 @@ SET(common_headers
eqtime.h
errmsg.h
extprofile.h
faction.h
features.h
fixed_memory_hash_set.h
fixed_memory_variable_hash_set.h
@ -169,7 +167,6 @@ SET(common_headers
serverinfo.h
servertalk.h
shareddb.h
SharedLibrary.h
skills.h
spdat.h
StructStrategy.h

View File

@ -1,213 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "../common/debug.h"
#include <iostream>
using namespace std;
#include "../common/types.h"
#include "EMuShareMem.h"
#ifdef _WINDOWS
#define snprintf _snprintf
#if (_MSC_VER < 1500)
#define vsnprintf _vsnprintf
#endif
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
#define EmuLibName "EMuShareMem"
#else
#define EmuLibName "libEMuShareMem.so"
#endif
LoadEMuShareMemDLL EMuShareMemDLL;
#ifndef WIN32
uint32 LoadEMuShareMemDLL::refCount = 0;
#endif
LoadEMuShareMemDLL::LoadEMuShareMemDLL() {
ClearFunc();
#ifndef WIN32
refCountU();
#endif
}
LoadEMuShareMemDLL::~LoadEMuShareMemDLL() {
#ifndef WIN32
if (refCountD() <= 0) {
#endif
Unload();
#ifndef WIN32
}
#endif
}
bool LoadEMuShareMemDLL::Load() {
if(loaded)
return(true);
if(!SharedLibrary::Load(EmuLibName))
return(false);
if (Loaded()) {
Items.GetItem = (DLLFUNC_GetItem) GetSym("GetItem");
Items.IterateItems = (DLLFUNC_IterateItems) GetSym("IterateItems");
Items.cbAddItem = (DLLFUNC_AddItem) GetSym("AddItem");
Items.DLLLoadItems = (DLLFUNC_DLLLoadItems) GetSym("DLLLoadItems");
Doors.GetDoor = (DLLFUNC_GetDoor) GetSym("GetDoor");
Doors.cbAddDoor = (DLLFUNC_AddDoor) GetSym("AddDoor");
Doors.DLLLoadDoors = (DLLFUNC_DLLLoadDoors) GetSym("DLLLoadDoors");
NPCFactionList.DLLLoadNPCFactionLists = (DLLFUNC_DLLLoadNPCFactionLists) GetSym("DLLLoadNPCFactionLists");
NPCFactionList.GetNPCFactionList = (DLLFUNC_GetNPCFactionList) GetSym("GetNPCFactionList");
NPCFactionList.cbAddNPCFactionList = (DLLFUNC_AddNPCFactionList) GetSym("AddNPCFactionList");
NPCFactionList.cbSetFaction = (DLLFUNC_SetFaction) GetSym("SetNPCFaction");
Loot.DLLLoadLoot = (DLLFUNC_DLLLoadLoot) GetSym("DLLLoadLoot");
Loot.cbAddLootTable = (DLLFUNC_AddLootTable) GetSym("AddLootTable");
Loot.cbAddLootDrop = (DLLFUNC_AddLootDrop) GetSym("AddLootDrop");
Loot.GetLootTable = (DLLFUNC_GetLootTable) GetSym("GetLootTable");
Loot.GetLootDrop = (DLLFUNC_GetLootDrop) GetSym("GetLootDrop");
if(Items.GetItem == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Items.GetItem");
return(false);
}
if(Items.IterateItems == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Items.IterateItems");
return(false);
}
if(Items.cbAddItem == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Items.cbAddItem");
return(false);
}
if(Items.DLLLoadItems == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Items.DLLLoadItems");
return(false);
}
if(Doors.GetDoor == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Doors.GetDoor");
return(false);
}
if(Doors.cbAddDoor == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Doors.cbAddDoor");
return(false);
}
if(Doors.DLLLoadDoors == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Doors.DLLLoadDoors");
return(false);
}
if(NPCFactionList.DLLLoadNPCFactionLists == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach NPCFactionList.DLLLoadNPCFactionLists");
return(false);
}
if(NPCFactionList.GetNPCFactionList == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach NPCFactionList.GetNPCFactionList");
return(false);
}
if(NPCFactionList.cbAddNPCFactionList == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach NPCFactionList.cbAddNPCFactionList");
return(false);
}
if(NPCFactionList.cbSetFaction == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach NPCFactionList.cbSetFaction");
return(false);
}
if(Loot.DLLLoadLoot == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Loot.DLLLoadLoot");
return(false);
}
if(Loot.cbAddLootTable == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Loot.cbAddLootTable");
return(false);
}
if(Loot.cbAddLootDrop == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Loot.cbAddLootDrop");
return(false);
}
if(Loot.GetLootTable == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Loot.GetLootTable");
return(false);
}
if(Loot.GetLootDrop == NULL) {
Unload();
LogFile->write(EQEMuLog::Error, "LoadEMuShareMemDLL::Load() failed to attach Loot.GetLootDrop");
return(false);
}
LogFile->write(EQEMuLog::Status, "%s loaded", EmuLibName);
loaded = true;
return true;
}
else {
LogFile->write(EQEMuLog::Error, "%s was not loaded, but did not report an error.", EmuLibName);
}
return false;
}
void LoadEMuShareMemDLL::Unload() {
ClearFunc();
SharedLibrary::Unload();
}
void LoadEMuShareMemDLL::ClearFunc() {
Items.GetItem = 0;
Items.IterateItems = 0;
Items.cbAddItem = 0;
Items.DLLLoadItems = 0;
Doors.GetDoor = 0;
Doors.cbAddDoor = 0;
Doors.DLLLoadDoors = 0;
NPCFactionList.DLLLoadNPCFactionLists = 0;
NPCFactionList.GetNPCFactionList = 0;
NPCFactionList.cbAddNPCFactionList = 0;
NPCFactionList.cbSetFaction = 0;
Loot.DLLLoadLoot = 0;
Loot.cbAddLootTable = 0;
Loot.cbAddLootDrop = 0;
Loot.GetLootTable = 0;
Loot.GetLootDrop = 0;
loaded = false;
}

View File

@ -1,121 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EMuShareMem_H
#define EMuShareMem_H
#ifdef _WINDOWS
#include <windows.h>
#else
#include "../common/unix.h"
#endif
#include "../common/eq_packet_structs.h"
#include "../zone/zonedump.h"
#include "../common/loottable.h"
#include "SharedLibrary.h"
////////////
// Items //
///////////
typedef bool(*CALLBACK_DBLoadItems)(int32, uint32);
typedef bool(*DLLFUNC_DLLLoadItems)(const CALLBACK_DBLoadItems, uint32, int32*, uint32*);
typedef const Item_Struct*(*DLLFUNC_GetItem)(uint32);
typedef const Item_Struct*(*DLLFUNC_IterateItems)(uint32*);
typedef bool(*DLLFUNC_AddItem)(uint32, const Item_Struct*);
struct ItemsDLLFunc_Struct {
DLLFUNC_DLLLoadItems DLLLoadItems;
DLLFUNC_GetItem GetItem;
DLLFUNC_IterateItems IterateItems;
DLLFUNC_AddItem cbAddItem;
};
////////////
// Doors ///
////////////
typedef bool(*CALLBACK_DBLoadDoors)(int32, uint32);
typedef bool(*DLLFUNC_DLLLoadDoors)(const CALLBACK_DBLoadDoors, uint32, int32*, uint32*);
typedef const Door*(*DLLFUNC_GetDoor)(uint32);
typedef bool(*DLLFUNC_AddDoor)(uint32, const Door*);
struct DoorsDLLFunc_Struct {
DLLFUNC_DLLLoadDoors DLLLoadDoors;
DLLFUNC_GetDoor GetDoor;
DLLFUNC_AddDoor cbAddDoor;
};
//////////////
// Factions //
//////////////
typedef bool(*CALLBACK_DBLoadNPCFactionLists)(int32, uint32);
typedef bool(*DLLFUNC_DLLLoadNPCFactionLists)(const CALLBACK_DBLoadNPCFactionLists, uint32, int32*, uint32*, uint8);
typedef const NPCFactionList*(*DLLFUNC_GetNPCFactionList)(uint32);
typedef bool(*DLLFUNC_AddNPCFactionList)(uint32, const NPCFactionList*);
typedef bool(*DLLFUNC_SetFaction)(uint32, uint32*, int32*, int8*, uint8*);
struct NPCFactionListDLLFunc_Struct {
DLLFUNC_DLLLoadNPCFactionLists DLLLoadNPCFactionLists;
DLLFUNC_GetNPCFactionList GetNPCFactionList;
DLLFUNC_AddNPCFactionList cbAddNPCFactionList;
DLLFUNC_SetFaction cbSetFaction;
};
////////////
// Loot //
///////////
typedef bool(*CALLBACK_DBLoadLoot)();
typedef bool(*DLLFUNC_DLLLoadLoot)(const CALLBACK_DBLoadLoot, uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32, uint32);
typedef bool(*DLLFUNC_AddLootTable)(uint32, const LootTable_Struct*);
typedef bool(*DLLFUNC_AddLootDrop)(uint32, const LootDrop_Struct*);
typedef const LootTable_Struct*(*DLLFUNC_GetLootTable)(uint32);
typedef const LootDrop_Struct*(*DLLFUNC_GetLootDrop)(uint32);
struct LootDLLFunc_Struct {
DLLFUNC_DLLLoadLoot DLLLoadLoot;
DLLFUNC_AddLootTable cbAddLootTable;
DLLFUNC_AddLootDrop cbAddLootDrop;
DLLFUNC_GetLootTable GetLootTable;
DLLFUNC_GetLootDrop GetLootDrop;
};
class LoadEMuShareMemDLL : public SharedLibrary {
public:
LoadEMuShareMemDLL();
~LoadEMuShareMemDLL();
bool Load();
void Unload();
ItemsDLLFunc_Struct Items;
DoorsDLLFunc_Struct Doors;
NPCFactionListDLLFunc_Struct NPCFactionList;
LootDLLFunc_Struct Loot;
private:
void ClearFunc();
bool loaded;
#ifdef _WINDOWS
#else
static uint32 refCount;
static uint32 refCountU() { return ++refCount; };
static uint32 refCountD() { return --refCount; };
#endif
};
#endif

View File

@ -1,117 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "SharedLibrary.h"
#include <stdio.h>
#ifdef _WINDOWS
#define snprintf _snprintf
#if (_MSC_VER < 1500)
#define vsnprintf _vsnprintf
#endif
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
#define EmuLibName "EMuShareMem"
#else
#define EmuLibName "libEMuShareMem.so"
#include "../common/unix.h"
#include <dlfcn.h>
#define GetProcAddress(a,b) dlsym(a,b)
#define LoadLibrary(a) dlopen(a, RTLD_NOW)
#define FreeLibrary(a) dlclose(a)
#define GetLastError() dlerror()
#endif
SharedLibrary::SharedLibrary() {
hDLL = NULL;
}
SharedLibrary::~SharedLibrary() {
Unload();
}
bool SharedLibrary::Load(const char *name)
{
#ifdef _WINDOWS
SetLastError(0);
#endif
hDLL = LoadLibrary(name);
if(!hDLL) {
const char *load_error = GetError();
fprintf(stderr, "[Error] Load Shared Library '%s' failed. Error=%s\n", name, load_error?load_error:"Null Return, no error");
return false;
}
#ifdef _WINDOWS
else { SetLastError(0); } // Clear the win9x error
#endif
return(true);
}
void SharedLibrary::Unload() {
if (hDLL != NULL) {
FreeLibrary(hDLL);
#ifndef WIN32
const char* error;
if ((error = GetError()) != NULL)
fprintf(stderr, "FreeLibrary() error = %s", error);
#endif
hDLL = NULL;
}
}
void *SharedLibrary::GetSym(const char *name) {
if (!Loaded())
return(NULL);
void *r = GetProcAddress(hDLL, name);
if(GetError() != NULL)
r = NULL;
return(r);
}
bool SharedLibrary::GetSym(const char *name, void **sym)
{
bool result=false;
if (Loaded()) {
*sym = GetProcAddress(hDLL, name);
result= (GetError() == NULL);
}
return result;
}
const char *SharedLibrary::GetError()
{
#ifdef _WINDOWS
//not thread safe, dont care.
static char ErrBuf[128];
unsigned long err = GetLastError();
if(err == 0)
return(NULL);
sprintf(ErrBuf, "Error #%lu", (unsigned long)err);
return(ErrBuf);
#else
return GetLastError();
#endif
}

View File

@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemu.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -15,11 +15,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef FACTION_H
#define FACTION_H
#ifndef _EQEMU_FACTION_H
#define _EQEMU_FACTION_H
#include "../common/types.h"
#include "../common/features.h"
#include "types.h"
#include "features.h"
#include <map>
#include <string>
@ -64,11 +64,10 @@ typedef map<uint32, int16> faction_map;
struct NPCFaction
{
uint32 factionID;
int32 value_mod;
int8 npc_value;
uint8 temp;
//bool primary;
uint32 factionID;
int32 value_mod;
int8 npc_value;
uint8 temp;
};
const char *FactionValueToString(FACTION_VALUE fv);

View File

@ -186,7 +186,6 @@ namespace EQEmu {
void MemoryMappedFile::ZeroFile() {
memset(reinterpret_cast<void*>(memory_), 0, sizeof(shared_memory_struct));
memset(memory_->data, 0, size_);
memory_->loaded = false;
memory_->size = size_;
}
} // EQEmu

View File

@ -35,7 +35,6 @@ namespace EQEmu {
//! Underlying data structure.
struct shared_memory_struct {
bool loaded;
uint32 size;
unsigned char data[1];
};
@ -66,13 +65,7 @@ namespace EQEmu {
//! Get Size Function
inline uint32 Size() const { return memory_->size; }
//! Returns whether this memory is loaded or not
inline bool Loaded() const { return memory_->loaded; }
//! Sets the memory to be loaded
inline void SetLoaded() { memory_->loaded = true; }
//! Zeros all the memory in the file, and set it to be unloaded
void ZeroFile();
private:

View File

@ -23,19 +23,10 @@
#include <cstdlib>
#include <cstring>
#ifdef SHARED_OPCODES
#include "EMuShareMem.h"
extern LoadEMuShareMemDLL EMuShareMemDLL;
#endif
#include <map>
#include <string>
using namespace std;
//#define DEBUG_TRANSLATE
OpcodeManager::OpcodeManager() {
loaded = false;
}
@ -141,80 +132,6 @@ EmuOpcode OpcodeManager::NameSearch(const char *name) {
return(OP_Unknown);
}
#ifdef SHARED_OPCODES
bool SharedOpcodeManager::LoadOpcodes(const char *filename, bool report_errors) {
if (!EMuShareMemDLL.Load()) {
printf("Unable to load EMuShareMem for opcodes.\n");
return false;
}
MOpcodes.lock();
loaded = true;
bool ret = EMuShareMemDLL.Opcodes.DLLLoadOpcodes(DLLLoadOpcodesCallback, sizeof(uint16), MAX_EQ_OPCODE, _maxEmuOpcode, filename);
MOpcodes.unlock();
return ret;
}
bool SharedOpcodeManager::DLLLoadOpcodesCallback(const char *filename) {
SharedMemStrategy s;
return(LoadOpcodesFile(filename, &s, true));
}
bool SharedOpcodeManager::ReloadOpcodes(const char *filename, bool report_errors) {
/* if(!loaded)
return(LoadOpcodes(filename));
MOpcodes.lock();
EMuShareMemDLL.Opcodes.ClearEQOpcodes();
SharedMemStrategy s;
bool ret = LoadOpcodesFile(filename, &s);
MOpcodes.unlock();
return(ret);*/
//shared memory is read only right now, cant reload it
return(false);
}
uint16 SharedOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
//opcode is checked for validity in GetEQOpcode
uint16 res;
MOpcodes.lock();
res = EMuShareMemDLL.Opcodes.GetEQOpcode((uint16)emu_op);
MOpcodes.unlock();
#ifdef DEBUG_TRANSLATE
fprintf(stderr, "S Translate Emu %s (%d) to EQ 0x%.4x\n", OpcodeNames[emu_op], emu_op, res);
#endif
return(res);
}
EmuOpcode SharedOpcodeManager::EQToEmu(const uint16 eq_op) {
//opcode is checked for validity in GetEmuOpcode
//Disabled since current live EQ uses the entire uint16 bitspace for opcodes
// if(eq_op > MAX_EQ_OPCODE)
// return(OP_Unknown);
uint16 res;
MOpcodes.lock();
res = EMuShareMemDLL.Opcodes.GetEmuOpcode(eq_op);
MOpcodes.unlock();
#ifdef DEBUG_TRANSLATE
fprintf(stderr, "S Translate EQ 0x%.4x to Emu %s (%d)\n", eq_op, OpcodeNames[res], res);
#endif
return((EmuOpcode)res);
}
void SharedOpcodeManager::SharedMemStrategy::Set(EmuOpcode emu_op, uint16 eq_op) {
EMuShareMemDLL.Opcodes.SetOpcodePair((uint16)emu_op, eq_op);
}
#endif
RegularOpcodeManager::RegularOpcodeManager()
: MutableOpcodeManager()
{

View File

@ -4,7 +4,6 @@
#include <cstring>
#include <cstdlib>
#include "Item.h"
#include "EMuShareMem.h"
#include "classes.h"
#include "rulesys.h"
#include "seperator.h"
@ -15,20 +14,22 @@
#include "memory_mapped_file.h"
#include "ipc_mutex.h"
#include "eqemu_exception.h"
#include "loottable.h"
#include "faction.h"
#include "features.h"
using namespace std;
extern LoadEMuShareMemDLL EMuShareMemDLL;
SharedDatabase::SharedDatabase()
: Database(), skill_caps_mmf(NULL), items_mmf(NULL), items_hash(NULL), faction_mmf(NULL),
: Database(), skill_caps_mmf(NULL), items_mmf(NULL), items_hash(NULL), faction_mmf(NULL), faction_hash(NULL),
loot_table_mmf(NULL), loot_drop_mmf(NULL), loot_table_hash(NULL), loot_drop_hash(NULL)
{
}
SharedDatabase::SharedDatabase(const char* host, const char* user, const char* passwd, const char* database, uint32 port)
: Database(host, user, passwd, database, port), skill_caps_mmf(NULL), items_mmf(NULL), items_hash(NULL),
faction_mmf(NULL), loot_table_mmf(NULL), loot_drop_mmf(NULL), loot_table_hash(NULL), loot_drop_hash(NULL)
faction_mmf(NULL), faction_hash(NULL), loot_table_mmf(NULL), loot_drop_mmf(NULL), loot_table_hash(NULL),
loot_drop_hash(NULL)
{
}
@ -37,6 +38,7 @@ SharedDatabase::~SharedDatabase() {
safe_delete(items_mmf);
safe_delete(items_hash);
safe_delete(faction_mmf);
safe_delete(faction_hash);
safe_delete(loot_table_mmf);
safe_delete(loot_drop_mmf);
safe_delete(loot_table_hash);
@ -715,31 +717,26 @@ bool SharedDatabase::GetInventory(uint32 account_id, char* name, Inventory* inv)
}
int32 SharedDatabase::GetItemsCount(uint32* max_id) {
void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id) {
char errbuf[MYSQL_ERRMSG_SIZE];
MYSQL_RES *result;
MYSQL_ROW row;
int32 ret = -1;
item_count = -1;
max_id = 0;
char query[] = "SELECT MAX(id), count(*) FROM items";
if (RunQuery(query, static_cast<uint32>(strlen(query)), errbuf, &result)) {
row = mysql_fetch_row(result);
if (row != NULL && row[1] != 0) {
ret = atoi(row[1]);
if (max_id) {
if (row[0])
*max_id = atoi(row[0]);
else
*max_id = 0;
}
item_count = atoi(row[1]);
if(row[0])
max_id = atoi(row[0]);
}
mysql_free_result(result);
}
else {
LogFile->write(EQEMuLog::Error, "Error in GetItemsCount '%s': '%s'", query, errbuf);
}
return ret;
}
bool SharedDatabase::LoadItems() {
@ -752,8 +749,9 @@ bool SharedDatabase::LoadItems() {
mutex.Lock();
items_mmf = new EQEmu::MemoryMappedFile("shared/items");
int32 items = -1;
uint32 max_item = 0;
int32 items = GetItemsCount(&max_item);
GetItemsCount(items, max_item);
if(items == -1) {
EQ_EXCEPT("SharedDatabase", "Database returned no result");
}
@ -1085,151 +1083,120 @@ string SharedDatabase::GetBook(const char *txtfile)
}
}
void SharedDatabase::GetFactionListInfo(uint32 &list_count, uint32 &max_lists) {
list_count = 0;
max_lists = 0;
const char *query = "SELECT COUNT(*), MAX(id) FROM npc_faction";
char errbuf[MYSQL_ERRMSG_SIZE];
MYSQL_RES *result;
MYSQL_ROW row;
bool SharedDatabase::extDBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID) {
return false;
//return s_usedb->DBLoadNPCFactionLists(iNPCFactionListCount, iMaxNPCFactionListID);
if(RunQuery(query, strlen(query), errbuf, &result)) {
if(row = mysql_fetch_row(result)) {
list_count = static_cast<uint32>(atoul(row[0]));
max_lists = static_cast<uint32>(atoul(row[1]));
}
mysql_free_result(result);
} else {
LogFile->write(EQEMuLog::Error, "Error getting npc faction info from database: %s, %s", query, errbuf);
}
}
const NPCFactionList* SharedDatabase::GetNPCFactionEntry(uint32 id) {
return NULL;
//return EMuShareMemDLL.NPCFactionList.GetNPCFactionList(id);
if(!faction_hash) {
return NULL;
}
if(faction_hash->exists(id)) {
return &(faction_hash->at(id));
}
return NULL;
}
void SharedDatabase::LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists) {
EQEmu::FixedMemoryHashSet<NPCFactionList> hash(reinterpret_cast<uint8*>(data), size, list_count, max_lists);
const char *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 JOIN npc_faction_entries ON npc_faction.id = npc_faction_entries.npc_faction_id ORDER BY "
"npc_faction.id;";
char errbuf[MYSQL_ERRMSG_SIZE];
MYSQL_RES *result;
MYSQL_ROW row;
NPCFactionList faction;
if(RunQuery(query, strlen(query), errbuf, &result)) {
uint32 current_id = 0;
uint32 current_entry = 0;
while(row = mysql_fetch_row(result)) {
uint32 id = static_cast<uint32>(atoul(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 = static_cast<uint32>(atoul(row[1]));
faction.assistprimaryfaction = (atoi(row[2]) == 0);
}
if(current_entry >= MAX_NPC_FACTIONS) {
continue;
}
faction.factionid[current_entry] = static_cast<uint32>(atoul(row[3]));
faction.factionvalue[current_entry] = static_cast<int32>(atoi(row[4]));
faction.factionnpcvalue[current_entry] = static_cast<int8>(atoi(row[5]));
faction.factiontemp[current_entry] = static_cast<uint8>(atoi(row[6]));
}
if(current_id != 0) {
hash.insert(current_id, faction);
}
mysql_free_result(result);
} else {
LogFile->write(EQEMuLog::Error, "Error getting npc faction info from database: %s, %s", query, errbuf);
}
}
bool SharedDatabase::LoadNPCFactionLists() {
//if (!EMuShareMemDLL.Load())
// return false;
//int32 tmp = -1;
//uint32 tmp_npcfactionlist_max;
//tmp = GetNPCFactionListsCount(&tmp_npcfactionlist_max);
//if (tmp < 0) {
// cout << "Error: SharedDatabase::LoadNPCFactionLists-ShareMem: GetNPCFactionListsCount() returned < 0" << endl;
// return false;
//}
//bool ret = EMuShareMemDLL.NPCFactionList.DLLLoadNPCFactionLists(&extDBLoadNPCFactionLists, sizeof(NPCFactionList), &tmp, &tmp_npcfactionlist_max, MAX_NPC_FACTIONS);
//return ret;
if(faction_hash) {
return true;
}
try {
EQEmu::IPCMutex mutex("faction");
mutex.Lock();
faction_mmf = new EQEmu::MemoryMappedFile("shared/faction");
uint32 list_count = 0;
uint32 max_lists = 0;
GetFactionListInfo(list_count, max_lists);
if(list_count == 0) {
EQ_EXCEPT("SharedDatabase", "Database returned no result");
}
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<NPCFactionList>::estimated_size(
list_count, max_lists));
if(faction_mmf->Size() != size) {
EQ_EXCEPT("SharedDatabase", "Couldn't load npc factions because faction_mmf->Size() != size");
}
faction_hash = new EQEmu::FixedMemoryHashSet<NPCFactionList>(reinterpret_cast<uint8*>(faction_mmf->Get()), size);
mutex.Unlock();
} catch(std::exception& ex) {
LogFile->write(EQEMuLog::Error, "Error Loading npc factions: %s", ex.what());
return false;
}
return true;
}
bool SharedDatabase::DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID) {
_CP(Database_DBLoadNPCFactionLists);
LogFile->write(EQEMuLog::Status, "Loading NPC Faction Lists from database...");
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
query = new char[256];
strcpy(query, "SELECT MAX(id), Count(*) FROM npc_faction");
if (RunQuery(query, strlen(query), errbuf, &result)) {
safe_delete_array(query);
row = mysql_fetch_row(result);
if (row && row[0]) {
if ((uint32)atoi(row[0]) > iMaxNPCFactionListID) {
cout << "Error: Insufficient shared memory to load NPC Faction Lists." << endl;
cout << "Max(id): " << atoi(row[0]) << ", iMaxNPCFactionListID: " << iMaxNPCFactionListID << endl;
cout << "Fix this by increasing the MMF_MAX_NPCFactionList_ID define statement" << endl;
mysql_free_result(result);
return false;
}
if (atoi(row[1]) != iNPCFactionListCount) {
cout << "Error: number of NPCFactionLists in memshare doesnt match database." << endl;
cout << "Count(*): " << atoi(row[1]) << ", iNPCFactionListCount: " << iNPCFactionListCount << endl;
mysql_free_result(result);
return false;
}
//npcfactionlist_max = atoi(row[0]);
mysql_free_result(result);
NPCFactionList tmpnfl;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, primaryfaction, ignore_primary_assist from npc_faction"), errbuf, &result)) {
safe_delete_array(query);
while((row = mysql_fetch_row(result))) {
memset(&tmpnfl, 0, sizeof(NPCFactionList));
tmpnfl.id = atoi(row[0]);
tmpnfl.primaryfaction = atoi(row[1]);
//if we have ignore_primary_assist set to non-zero then we will not assist our own faction
//else we will assist (this is the default)
tmpnfl.assistprimaryfaction = (atoi(row[2]) == 0) ? true : false;
if (!EMuShareMemDLL.NPCFactionList.cbAddNPCFactionList(tmpnfl.id, &tmpnfl)) {
mysql_free_result(result);
cout << "Error: SharedDatabase::DBLoadNPCFactionLists: !EMuShareMemDLL.NPCFactionList.cbAddNPCFactionList" << endl;
return false;
}
Sleep(0);
}
mysql_free_result(result);
}
else {
cerr << "Error in DBLoadNPCFactionLists query2 '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
if (RunQuery(query, MakeAnyLenString(&query, "SELECT npc_faction_id, faction_id, value, npc_value, temp FROM npc_faction_entries order by npc_faction_id"), errbuf, &result)) {
safe_delete_array(query);
int8 i = 0;
uint32 curflid = 0;
uint32 tmpflid = 0;
uint32 tmpfactionid[MAX_NPC_FACTIONS];
int32 tmpfactionvalue[MAX_NPC_FACTIONS];
int8 tmpfactionnpcvalue[MAX_NPC_FACTIONS];
uint8 tmpfactiontemp[MAX_NPC_FACTIONS];
memset(tmpfactionid, 0, sizeof(tmpfactionid));
memset(tmpfactionvalue, 0, sizeof(tmpfactionvalue));
memset(tmpfactionnpcvalue, 0, sizeof(tmpfactionnpcvalue));
memset(tmpfactiontemp, 0, sizeof(tmpfactiontemp));
while((row = mysql_fetch_row(result))) {
tmpflid = atoi(row[0]);
if (curflid != tmpflid && curflid != 0) {
if (!EMuShareMemDLL.NPCFactionList.cbSetFaction(curflid, tmpfactionid, tmpfactionvalue, tmpfactionnpcvalue, tmpfactiontemp)) {
mysql_free_result(result);
cout << "Error: SharedDatabase::DBLoadNPCFactionLists: !EMuShareMemDLL.NPCFactionList.cbSetFaction" << endl;
return false;
}
memset(tmpfactionid, 0, sizeof(tmpfactionid));
memset(tmpfactionvalue, 0, sizeof(tmpfactionvalue));
memset(tmpfactionnpcvalue, 0, sizeof(tmpfactionnpcvalue));
memset(tmpfactiontemp, 0, sizeof(tmpfactiontemp));
i = 0;
}
curflid = tmpflid;
tmpfactionid[i] = atoi(row[1]);
tmpfactionvalue[i] = atoi(row[2]);
tmpfactionnpcvalue[i] = atoi(row[3]);
tmpfactiontemp[i] = atoi(row[4]);
i++;
if (i >= MAX_NPC_FACTIONS) {
cerr << "Error in DBLoadNPCFactionLists: More than MAX_NPC_FACTIONS factions returned, flid=" << tmpflid << endl;
break;
}
Sleep(0);
}
if (tmpflid) {
EMuShareMemDLL.NPCFactionList.cbSetFaction(curflid, tmpfactionid, tmpfactionvalue, tmpfactionnpcvalue, tmpfactiontemp);
}
mysql_free_result(result);
}
else {
cerr << "Error in DBLoadNPCFactionLists query3 '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
}
else {
mysql_free_result(result);
//return false;
}
}
else {
cerr << "Error in DBLoadNPCFactionLists query1 '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
return true;
}
// Get the player profile and inventory for the given account "account_id" and
// character name "name". Return true if the character was found, otherwise false.
// False will also be returned if there is a database error.
@ -1428,37 +1395,6 @@ int32 SharedDatabase::DeleteStalePlayerBackups() {
return affected_rows;
}
int32 SharedDatabase::GetNPCFactionListsCount(uint32* oMaxID) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
query = new char[256];
strcpy(query, "SELECT MAX(id), count(*) FROM npc_faction");
if (RunQuery(query, strlen(query), errbuf, &result)) {
safe_delete_array(query);
row = mysql_fetch_row(result);
if (row != NULL && row[1] != 0) {
int32 ret = atoi(row[1]);
if (oMaxID) {
if (row[0])
*oMaxID = atoi(row[0]);
else
*oMaxID = 0;
}
mysql_free_result(result);
return ret;
}
}
else {
cerr << "Error in GetNPCFactionListsCount query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return -1;
}
return -1;
}
bool SharedDatabase::GetCommandSettings(map<string,uint8> &commands) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
@ -1894,6 +1830,11 @@ void SharedDatabase::LoadLootTables(void *data, uint32 size) {
++(lt->NumEntries);
++current_entry;
}
if(current_id != 0) {
hash.insert(current_id, loot_table, (sizeof(LootTable_Struct) +
(sizeof(LootTableEntries_Struct) * lt->NumEntries)));
}
mysql_free_result(result);
} else {
LogFile->write(EQEMuLog::Error, "Error getting loot table info from database: %s, %s", query, errbuf);

View File

@ -79,17 +79,19 @@ public:
*/
//items
int32 GetItemsCount(uint32* max_id = 0);
void GetItemsCount(int32 &item_count, uint32 &max_id);
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
bool LoadItems();
const Item_Struct* IterateItems(uint32* id);
const Item_Struct* GetItem(uint32 id);
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
//faction lists
void GetFactionListInfo(uint32 &list_count, uint32 &max_lists);
const NPCFactionList* GetNPCFactionEntry(uint32 id);
void LoadNPCFactionLists(void *data, uint32 size, uint32 list_count, uint32 max_lists);
bool LoadNPCFactionLists();
bool DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
//bool DBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
//loot
void GetLootTableInfo(uint32 &loot_table_count, uint32 &max_loot_table, uint32 &loot_table_entries);
@ -111,15 +113,10 @@ public:
protected:
/*
* Private shared mem stuff
*/
int32 GetNPCFactionListsCount(uint32* oMaxID = 0);
static bool extDBLoadNPCFactionLists(int32 iNPCFactionListCount, uint32 iMaxNPCFactionListID);
EQEmu::MemoryMappedFile *items_mmf;
EQEmu::FixedMemoryHashSet<Item_Struct> *items_hash;
EQEmu::MemoryMappedFile *faction_mmf;
EQEmu::FixedMemoryHashSet<NPCFactionList> *faction_hash;
EQEmu::MemoryMappedFile *loot_table_mmf;
EQEmu::FixedMemoryVariableHashSet<LootTable_Struct> *loot_table_hash;
EQEmu::MemoryMappedFile *loot_drop_mmf;

View File

@ -4,6 +4,7 @@ SET(shared_memory_sources
items.cpp
loot.cpp
main.cpp
npc_faction.cpp
spells.cpp
skill_caps.cpp
)
@ -11,6 +12,7 @@ SET(shared_memory_sources
SET(shared_memory_headers
items.h
loot.h
npc_faction.h
spells.h
skill_caps.h
)

View File

@ -28,8 +28,9 @@ void LoadItems(SharedDatabase *database) {
EQEmu::IPCMutex mutex("items");
mutex.Lock();
int32 items = -1;
uint32 max_item = 0;
int32 items = database->GetItemsCount(&max_item);
database->GetItemsCount(items, max_item);
if(items == -1) {
EQ_EXCEPT("Shared Memory", "Unable to get any items from the database.");
}
@ -39,8 +40,6 @@ void LoadItems(SharedDatabase *database) {
mmf.ZeroFile();
void *ptr = mmf.Get();
database->LoadItems(ptr, size, items, max_item);
mmf.SetLoaded();
database->LoadItems(ptr, size, items, max_item);
mutex.Unlock();
}

View File

@ -57,8 +57,5 @@ void LoadLoot(SharedDatabase *database) {
database->LoadLootTables(mmf_loot_table.Get(), loot_table_max);
database->LoadLootDrops(mmf_loot_drop.Get(), loot_drop_max);
mmf_loot_table.SetLoaded();
mmf_loot_drop.SetLoaded();
mutex.Unlock();
}

View File

@ -25,6 +25,7 @@
#include "../common/rulesys.h"
#include "../common/eqemu_exception.h"
#include "items.h"
#include "npc_faction.h"
#include "loot.h"
#include "skill_caps.h"
#include "spells.h"
@ -55,6 +56,7 @@ int main(int argc, char **argv) {
bool load_all = true;
bool load_items = true;
bool load_factions = true;
bool load_loot = true;
bool load_skill_caps = true;
bool load_spells = true;
@ -68,6 +70,16 @@ int main(int argc, char **argv) {
}
}
if(load_all || load_factions) {
LogFile->write(EQEMuLog::Status, "Loading factions...");
try {
LoadFactions(&database);
} catch(std::exception &ex) {
LogFile->write(EQEMuLog::Error, "%s", ex.what());
return 0;
}
}
if(load_all || load_loot) {
LogFile->write(EQEMuLog::Status, "Loading loot...");
try {

View File

@ -0,0 +1,45 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "npc_faction.h"
#include "../common/debug.h"
#include "../common/shareddb.h"
#include "../common/ipc_mutex.h"
#include "../common/memory_mapped_file.h"
#include "../common/eqemu_exception.h"
#include "../common/faction.h"
void LoadFactions(SharedDatabase *database) {
EQEmu::IPCMutex mutex("faction");
mutex.Lock();
uint32 lists = 0;
uint32 max_list = 0;
database->GetFactionListInfo(lists, max_list);
if(lists == 0) {
EQ_EXCEPT("Shared Memory", "Unable to get any factions from the database.");
}
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<NPCFactionList>::estimated_size(lists, max_list));
EQEmu::MemoryMappedFile mmf("shared/faction", size);
mmf.ZeroFile();
void *ptr = mmf.Get();
database->LoadNPCFactionLists(ptr, size, lists, max_list);
mutex.Unlock();
}

View File

@ -1,5 +1,5 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net)
Copyright (C) 2001-2013 EQEMu Development Team (http://eqemulator.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -15,35 +15,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _SHAREDLIBRARY_H
#define _SHAREDLIBRARY_H
#ifdef _WINDOWS
#include <windows.h>
#endif
#ifndef __EQEMU_SHARED_MEMORY_NPC_FACTION_H
#define __EQEMU_SHARED_MEMORY_NPC_FACTION_H
class SharedLibrary {
public:
SharedLibrary();
virtual ~SharedLibrary();
//two call styles for GetSym, one returns bool, other NULL for fail
bool GetSym(const char *name, void **sym);
void *GetSym(const char *name);
const char *GetError();
virtual bool Load(const char *file);
virtual void Unload();
inline bool Loaded() { return (hDLL != 0); }
protected:
#ifdef _WINDOWS
HINSTANCE hDLL;
#else
void* hDLL;
#endif
};
class SharedDatabase;
void LoadFactions(SharedDatabase *database);
#endif

View File

@ -37,8 +37,6 @@ void LoadSkillCaps(SharedDatabase *database) {
mmf.ZeroFile();
void *ptr = mmf.Get();
database->LoadSkillCaps(ptr);
mmf.SetLoaded();
database->LoadSkillCaps(ptr);
mutex.Unlock();
}

View File

@ -38,8 +38,5 @@ void LoadSpells(SharedDatabase *database) {
void *ptr = mmf.Get();
database->LoadSpells(ptr, records);
mmf.SetLoaded();
//Mutex will unlock on destruction because it's RAII but still.
mutex.Unlock();
}

View File

@ -38,22 +38,17 @@ public:
void LoadAndZeroMMF() {
EQEmu::MemoryMappedFile mmf("testfile.txt", 512);
mmf.ZeroFile();
TEST_ASSERT(!mmf.Loaded());
TEST_ASSERT(mmf.Size() == 512);
unsigned char *data = reinterpret_cast<unsigned char*>(mmf.Get());
TEST_ASSERT(data != NULL);
*reinterpret_cast<uint32*>(data) = 562;
mmf.SetLoaded();
TEST_ASSERT(mmf.Loaded());
}
void LoadExistingMMF() {
EQEmu::MemoryMappedFile mmf("testfile.txt");
TEST_ASSERT(mmf.Size() == 512);
TEST_ASSERT(mmf.Loaded());
unsigned char *data = reinterpret_cast<unsigned char*>(mmf.Get());
TEST_ASSERT(data != NULL);

View File

@ -72,9 +72,6 @@ using namespace std;
#endif
#include "../common/EMuShareMem.h"
extern LoadEMuShareMemDLL EMuShareMemDLL;
/*
Zone only right now.
#ifdef EQPROFILE
@ -496,50 +493,6 @@ int main(int argc, char** argv) {
eqsf.Close();
_log(WORLD__SHUTDOWN,"Signaling HTTP service to stop...");
http_server.Stop();
#if 0
#if defined(SHAREMEM) && !defined(WIN32)
for (int ipc_files = 0; ipc_files <= 4; ipc_files++) {
key_t share_key;
switch (ipc_files) {
// Item
case 0: share_key = ftok(".", 'I'); break;
// Npctype
case 1: share_key = ftok(".", 'N'); break;
// Door
case 2: share_key = ftok(".", 'D'); break;
// Spell
case 3: share_key = ftok(".", 'S'); break;
// Faction
case 4: share_key = ftok(".", 'F'); break;
// ERROR Fatal
default: cerr<<"Opps!"<<endl; share_key = 0xFF; break;
}
int share_id = shmget(share_key, 0, IPC_NOWAIT|0400);
if (share_id <= 0) {
cerr<<"exiting could not check user count on shared memory ipcs mem leak!!!!!!!! id="<<share_id<<" key:"<<share_key<<endl;
exit(1);
}
struct shmid_ds mem_users;
if ((shmctl(share_id, IPC_STAT, &mem_users)) != 0) {
cerr<<"exiting error checking user count on shared memory, marking for deletion!!!!!id="<<share_id<<" key:"<<share_key<<endl;
shmctl(share_id, IPC_RMID, 0);
exit(1);
}
if (mem_users.shm_nattch == 0) {
//cerr<<"exiting stale share marked for deletion!id="<<share_id<<" key:"<<share_key<<endl;
shmctl(share_id, IPC_RMID, 0);
}
else if (mem_users.shm_nattch == 1) {
//cerr<<"mem_users = 1"<<endl;
// Detatch and delete shared mem here
EMuShareMemDLL.Unload();
shmctl(share_id, IPC_RMID, 0);
}
}
#endif
#endif
CheckEQEMuErrorAndPause();
return 0;

View File

@ -105,7 +105,6 @@ SET(zone_headers
entity.h
errmsg.h
event_codes.h
faction.h
forage.h
groups.h
guild_mgr.h

View File

@ -19,7 +19,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
#include <stdlib.h>
#include <math.h>
#include "masterentity.h"
#include "faction.h"
#include "../common/faction.h"
#include "map.h"
#include "../common/spdat.h"
#include "../common/skills.h"

View File

@ -59,7 +59,7 @@
#include "forage.h"
#include "zone.h"
#include "event_codes.h"
#include "faction.h"
#include "../common/faction.h"
#include "../common/crc32.h"
#include "StringIDs.h"
#include "map.h"

View File

@ -58,7 +58,7 @@
#include "forage.h"
#include "zone.h"
#include "event_codes.h"
#include "faction.h"
#include "../common/faction.h"
#include "../common/crc32.h"
#include "../common/rulesys.h"
#include "StringIDs.h"

View File

@ -157,7 +157,6 @@ int command_init(void) {
command_add("incstat","- Increases or Decreases a client's stats permanently.",200,command_incstat) ||
command_add("help","[search term] - List available commands and their description, specify partial command as argument to search",0,command_help) ||
command_add("version","- Display current version of EQEmu server",0,command_version) ||
command_add("eitem","- Changes item stats",200,command_eitem) ||
command_add("setfaction","[faction number] - Sets targeted NPC's faction in the database",170,command_setfaction) ||
command_add("serversidename","- Prints target's server side name",0,command_serversidename) ||
command_add("testspawn","[memloc] [value] - spawns a NPC for you only, with the specified values set in the spawn struct",200,command_testspawn) ||
@ -947,20 +946,6 @@ void command_version(Client *c, const Seperator *sep)
c->Message(0, " Last modified on: %s", LAST_MODIFIED);
}
void command_eitem(Client *c, const Seperator *sep)
{
#ifdef SHAREMEM
c->Message(0, "Error: Function doesnt work in ShareMem mode");
#else
char hehe[255];
if(strstr(sep->arg[2],"classes"))
snprintf(hehe,255,"%s %s",sep->arg[3],strstr(sep->argplus[0],sep->arg[3]));
else
strcpy(hehe,sep->arg[3]);
database.SetItemAtt(sep->arg[2],hehe,atoi(sep->arg[1]));
#endif
}
void command_setfaction(Client *c, const Seperator *sep)
{
if((sep->arg[1][0] == 0 || strcasecmp(sep->arg[1],"*")==0) || ((c->GetTarget()==0) || (c->GetTarget()->IsClient())))

View File

@ -72,7 +72,6 @@ void command_setstat(Client *c, const Seperator *sep);
void command_incstat(Client *c, const Seperator *sep);
void command_help(Client *c, const Seperator *sep);
void command_version(Client *c, const Seperator *sep);
void command_eitem(Client *c, const Seperator *sep);
void command_setfaction(Client *c, const Seperator *sep);
void command_serversidename(Client *c, const Seperator *sep);
void command_testspawnkill(Client *c, const Seperator *sep);

View File

@ -24,7 +24,7 @@ using namespace std;
#ifndef WIN32
#include <pthread.h>
#endif
#include "faction.h"
#include "../common/faction.h"
#include "zonedb.h"
#include "masterentity.h"
#include "zone.h"
@ -32,6 +32,7 @@ using namespace std;
extern Zone* zone;
//TODO: This file is terrible: half of it needs to be in common and half in zone
#ifdef _WINDOWS
#define snprintf _snprintf

View File

@ -45,26 +45,6 @@ using namespace std;
volatile bool RunLoops = true;
extern volatile bool ZoneLoaded;
#ifdef SHAREMEM
#include "../common/EMuShareMem.h"
extern LoadEMuShareMemDLL EMuShareMemDLL;
#ifndef WIN32
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#ifndef FREEBSD
union semun {
int val;
struct semid_ds *buf;
ushort *array;
struct seminfo *__buf;
void *__pad;
};
#endif
#endif
#endif
#include "../common/queue.h"
#include "../common/timer.h"

View File

@ -5,7 +5,7 @@
#include "../common/eq_packet_structs.h"
#include "../common/loottable.h"
#include "zonedump.h"
#include "faction.h"
#include "../common/faction.h"
//#include "doors.h"
struct wplist {

View File

@ -26,7 +26,7 @@ spawn2 mediumblob, npcs mediumblob, npc_loot mediumblob, gmspawntype mediumblob,
#ifndef ZONEDUMP_H
#define ZONEDUMP_H
#include "faction.h"
#include "../common/faction.h"
#include "../common/eq_packet_structs.h"
#include "../common/Item.h"