Files
Sun1602/Tools/WiseClient/Information/Manipulater.cpp
T
2022-10-26 12:25:11 +08:00

418 lines
12 KiB
C++

#include "stdafx.h"
//
#include "Manipulater.h"
//
#include <IOCPServer.h>
#include <ScriptDataLoader.h>
//
#include <Information/Account/AccountInfo.h>
// [ScriptLogic.dll]
#include <ScriptLogic/ScriptLogic.Interfaces.h>
using namespace util;
//////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////
// <TYPE DEFINTION>
// <MODULE DATA>
typedef STLX_LIST<sACCOUNT*> ACCOUNT_LIST;
typedef STLX_MAP<DWORD, sACCOUNT*> ACCOUNT_MAP;
typedef ACCOUNT_MAP::iterator ACCOUNT_MAP_IT;
//static struct sDATA_CONTAINER
//{
// IOCPServer* m_pIOCPServer;
// LOGIC_FLOW_WORKLOAD_CONTAINER* m_pWorkLoadContainer;
// sLINKEDLIST_NODE m_LogicFlowUsedListEntry;
// sAUTO_ACTION::eACTION_TYPE m_ACTION_TYPE;
// //////////////////////////////////////////////////////////////////////////
// EngineInstances m_Engine;
// //////////////////////////////////////////////////////////////////////////
// DWORD m_WiseMode; // 계정 + 기타 WiseMode; bitset으로 바꾸자.
// DWORD m_WiseMaxUserCount; // 멀티유저모드일 때 최대 유저 수
// ACCOUNT_ID_T m_AccountMaxID;
// ACCOUNT_MAP m_AccountMap;
// ACCOUNT_LIST m_AccountFreeList;
// //////////////////////////////////////////////////////////////////////////
// sConfigureNetwork m_ConfigureNetwork;
//} s_DATA_CONTAINER;
struct sDATA_CONTAINER
{
IOCPServer* m_pIOCPServer;
LOGIC_FLOW_WORKLOAD_CONTAINER* m_pWorkLoadContainer;
sLINKEDLIST_NODE m_LogicFlowUsedListEntry;
sAUTO_ACTION::eACTION_TYPE m_ACTION_TYPE;
//////////////////////////////////////////////////////////////////////////
EngineInstances m_Engine;
//////////////////////////////////////////////////////////////////////////
DWORD m_WiseMode; // 계정 + 기타 WiseMode; bitset으로 바꾸자.
DWORD m_WiseMaxUserCount; // 멀티유저모드일 때 최대 유저 수
ACCOUNT_ID_T m_AccountMaxID;
ACCOUNT_MAP m_AccountMap;
ACCOUNT_LIST m_AccountFreeList;
//////////////////////////////////////////////////////////////////////////
ScriptLogicInterface m_ScriptLogicInterface;
//////////////////////////////////////////////////////////////////////////
sConfigureNetwork m_ConfigureNetwork;
};
//////////////////////////////////////////////////////////////////////////
//
sSIGNAL_BUFFER::sSIGNAL_BUFFER_DATA sSIGNAL_BUFFER::BUFFER;
const CHAR* Manipulater::CONFIG_NETWORK_FILENAME = "./WiseClientV2.ini";
const CHAR* Manipulater::CONFIG_ACCOUNT_INFO_FILENAME = "./WiseClient.Accounts.ini";
#ifdef _DEV_TAIYO_PATHENGINE_CODE
# ifdef _DEBUG
const CHAR* Manipulater::CONFIG_ENGINE_3DENGINE_TERRAIN = "3DTerrainPE_sd.dll";
const CHAR* Manipulater::CONFIG_ENGINE_NUMERIC = "Numeric_d.dll";
# else //
const CHAR* Manipulater::CONFIG_ENGINE_3DENGINE_TERRAIN = "3DTerrainPE_s.dll";
const CHAR* Manipulater::CONFIG_ENGINE_NUMERIC = "Numeric.dll";
# endif //
#else //< DEV_TAIYO_PATHENGINE_CODE
//# ifdef _DEBUG
//const CHAR* Manipulater::CONFIG_ENGINE_3DENGINE_TERRAIN = "3DTerrain_sd.dll";
//const CHAR* Manipulater::CONFIG_ENGINE_NUMERIC = "Numeric_d.dll";
//# else //
const CHAR* Manipulater::CONFIG_ENGINE_3DENGINE_TERRAIN = "3DTerrain_s.dll";
const CHAR* Manipulater::CONFIG_ENGINE_NUMERIC = "Numeric.dll";
//# endif //
#endif //< DEV_TAIYO_PATHENGINE_CODE
//
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
Manipulater* Manipulater::ms_pInstance = NULL;
static sDATA_CONTAINER* s_pDATA_CONTAINER = NULL;
//////////////////////////////////////////////////////////////////////////
Manipulater::Manipulater()
{
s_pDATA_CONTAINER = new sDATA_CONTAINER;
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
//ZeroMemory(&ms_DATA_CONTAINER, sizeof(ms_DATA_CONTAINER));
// 초기화
rDATA.m_pIOCPServer = NULL;
rDATA.m_pWorkLoadContainer = NULL;
LList::Init(&rDATA.m_LogicFlowUsedListEntry);
ZeroMemory(&rDATA.m_ConfigureNetwork, sizeof(rDATA.m_ConfigureNetwork));
rDATA.m_ACTION_TYPE = sAUTO_ACTION::AT_MOVING;
// 초기 할당
rDATA.m_pWorkLoadContainer = new LOGIC_FLOW_WORKLOAD_CONTAINER();
rDATA.m_WiseMode = 0; // 계정 + 기타 WiseMode;
do { // 계정 관련
rDATA.m_AccountMaxID = 0;
_Initalize_AccountInfo();
} while(0);
ZeroMemory(&rDATA.m_ScriptLogicInterface, sizeof(rDATA.m_ScriptLogicInterface));
}
Manipulater::~Manipulater()
{
//ZeroMemory(&s_DATA_CONTAINER, sizeof(s_DATA_CONTAINER));
//SAFE_DELETE(s_pDATA_CONTAINER);
DEBUGGING_CODE_L1("");
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
SAFE_DELETE(rDATA.m_pWorkLoadContainer);
SAFE_DELETE(s_pDATA_CONTAINER);
}
EngineInstances& EngineInterface::RegisterInstance(HINSTANCE hDll3DTerrain, CLoadHelper* pCLoadHelper, FUNC_ContactTerrain fnContactTerrain)
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
EngineInstances& rENGINE = rDATA.m_Engine;
rENGINE.HANDLEofENGINE() = hDll3DTerrain;
rENGINE.HANDLEofLOADHELPER() = pCLoadHelper;
rENGINE.HANDLEofTERRAIN() = fnContactTerrain;
return rENGINE;
}
//BOOL Manipulater::Register3DEngine_Terrain(HINSTANCE hDLL, FUNC_ContactTerrain fn, CLoadHelper* pLoadHelper)
//{
// sDATA_CONTAINER& rDATA = s_DATA_CONTAINER;
// rDATA.m_hDll3DTerrain = hDLL;
// rDATA.m_fnContactTerrain = fn;
// rDATA.m_pCLoadHelper = pLoadHelper;
//
// return TRUE;
//}
//
//FUNC_ContactTerrain Manipulater::InterfaceOf3DTerrain()
//{
// sDATA_CONTAINER& rDATA = s_DATA_CONTAINER;
// return rDATA.m_fnContactTerrain;
//}
//
//CLoadHelper* Manipulater::InterfaceOfLoadHelper()
//{
// sDATA_CONTAINER& rDATA = s_DATA_CONTAINER;
// return rDATA.m_pCLoadHelper;
//}
IOCPServer*& Manipulater::IOCPServerREF()
{
return (*s_pDATA_CONTAINER).m_pIOCPServer;
}
sConfigureNetwork* Manipulater::GetNetworkArguments()
{
sConfigureNetwork& rINFO = (*s_pDATA_CONTAINER).m_ConfigureNetwork;
rINFO.dwVClientCount = 1;
return &rINFO;
}
//////////////////////////////////////////////////////////////////////////
// <CreateLogicFlowByWiseMode>
// - 유저 플로우 객체 생성
LogicFlowController* Manipulater::AllocLogicFlowController()
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
ObjectPoolRouter* pRouter = ObjectPoolRouter::Instance();
sLINKEDLIST_NODE* pLinkedList = (sLINKEDLIST_NODE*)pRouter->Alloc(OBJTYPE_LINKEDLIST);
LogicFlowController* pLogic = new LogicFlowController;
WORK_KEY wkKEY = WorkLoadManager::RegisterTask(pLogic);
pLinkedList->pREF = pLogic;
pLinkedList->dwExtra = wkKEY;
pLogic->SetParentContainer(pLinkedList);
// 이거 상당히 꼬이는데... 좀더 나은 방법을 찾거나 관리 쉬운 방법을 강구해보자.
rDATA.m_pWorkLoadContainer->RegisterWork(wkKEY, (DWORD)(__int64)pLogic);
LList::Init(pLinkedList);
LList::AddPrev(pLinkedList, &rDATA.m_LogicFlowUsedListEntry);
return pLogic;
}
void Manipulater::FreeLogicFlowController(LogicFlowController* pLogic)
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
LOGIC_FLOW_WORKLOAD_CONTAINER& rCONTAINER = *rDATA.m_pWorkLoadContainer;
WORK_KEY wkKEY = rCONTAINER.FindWorkKey((DWORD)(__int64)pLogic);
}
//////////////////////////////////////////////////////////////////////////
// <CreateLogicFlowByWiseMode>
// - 'WiseClient.Accounts.ini'의 정보에 따른 유저 플로우 객체 생성 모드
void Manipulater::CreateLogicFlowByWiseMode()
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
ACCOUNT_LIST& rLIST = rDATA.m_AccountFreeList;
DWORD& dwMaxCount = rDATA.m_WiseMaxUserCount;
DWORD dwMode = rDATA.m_WiseMode;
switch(dwMode)
{
case 0:
{
dwMaxCount = 1;
}
break;
case 1:
{
DWORD dwPoolCount = (DWORD)rLIST.size();
dwMaxCount = !(dwPoolCount < dwMaxCount) ? dwMaxCount : dwPoolCount;
}
break;
case 2:
{
// Real -or- Mirror Client Routing Mode
};
default:
DEBUGGING_CODE_L1("INVALID WISE MODE");
return;
};
for(DWORD dwI=0 ; dwI<dwMaxCount ; ++dwI)
{
AllocLogicFlowController();
}
}
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
//
//
ACCOUNT_ID_T Manipulater::AllocNewAccount()
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
ACCOUNT_MAP& rMAP = rDATA.m_AccountMap;
ACCOUNT_LIST& rLIST = rDATA.m_AccountFreeList;
ACCOUNT_ID_T retID = INVALID_ACCOUNT_ID;
if(rLIST.size())
{
sACCOUNT* pNode = *rLIST.begin();
retID = pNode->LOCAL_IDX;
if(INVALID_ACCOUNT_ID != retID)
{
rMAP.insert(make_pair(retID, pNode));
rLIST.pop_front();
if(rDATA.m_AccountMaxID < retID)
rDATA.m_AccountMaxID = retID;
return retID;
}
}
return retID;
}
BOOL Manipulater::FreeAccount(ACCOUNT_ID_T accountID)
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
ACCOUNT_MAP& rMAP = rDATA.m_AccountMap;
ACCOUNT_LIST& rLIST = rDATA.m_AccountFreeList;
if(!(rDATA.m_AccountMaxID < accountID))
{
ACCOUNT_MAP_IT itFIND = rMAP.find(accountID);
if(itFIND != rMAP.end())
{
sACCOUNT* pNode = itFIND->second;
rLIST.push_back(pNode);
rMAP.erase(itFIND);
return TRUE;
}
DEBUGGING_CODE_L1("CASE 2");
DEBUG_INTERRUPT();
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////////
//
BOOL AccountInfo::GetAccountInfo(sACCOUNT& OUT rACCOUNT)
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
ACCOUNT_MAP& rMAP = rDATA.m_AccountMap;
if(rDATA.m_AccountMaxID < m_ID)
return FALSE;
ACCOUNT_MAP_IT itFIND = rMAP.find(m_ID);
if(itFIND == rMAP.end())
return FALSE;
sACCOUNT* pNode = itFIND->second;
if(!pNode)
return FALSE;
CopyMemory(&rACCOUNT, pNode, sizeof(rACCOUNT));
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
//
static BOOL __AccountInfoParseInfoSectionData(PVOID pPassingPtr, SDAttrValueName tagValueName, SDAttrValue tagValue);
void Manipulater::_Initalize_AccountInfo()
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
ACCOUNT_LIST& rLIST = rDATA.m_AccountFreeList;
ScriptDataLoader loader;
//loader.SectionCallbackAlloc(&ParseInfoSection, NULL);
loader.SectionDataCallbackAlloc(&__AccountInfoParseInfoSectionData, NULL);
if(!loader.Load(Manipulater::CONFIG_ACCOUNT_INFO_FILENAME, FALSE))
{
DEBUGGING_CODE_L1("Can't Load ConfigFile");
DEBUG_INTERRUPT();
}
ObjectPoolRouter* pROUTER = ObjectPoolRouter::Instance();
BOOL bSuccess = TRUE;
do
{
sACCOUNT* pACCOUNT = (sACCOUNT*)pROUTER->Alloc(OBJTYPE_ACCOUNT_INFO);
sACCOUNT& rACCOUNT = *pACCOUNT;
ZeroMemory(pACCOUNT, sizeof(*pACCOUNT));
BOOL bCompleteSentence = FALSE;
if(bSuccess = loader.ReadValue(pACCOUNT->LOCAL_IDX))
if(bCompleteSentence = loader.ReadString(rACCOUNT.ID.GetBUFFER(), rACCOUNT.ID.GetBUFFER_LENGTH()))
if(bCompleteSentence = loader.ReadString(rACCOUNT.PASSWORD.GetBUFFER(), rACCOUNT.PASSWORD.GetBUFFER_LENGTH()))
{
rACCOUNT.ID.MakeSafeString();
rACCOUNT.PASSWORD.MakeSafeString();
loader.ReadValue(rACCOUNT.SELECT_GROUP);
loader.ReadValue(rACCOUNT.SELECT_SERVER);
loader.ReadValue(rACCOUNT.SELECT_CHAR);
}
if(bCompleteSentence)
{
rLIST.push_back(pACCOUNT);
}
else
{
bSuccess = FALSE;
pROUTER->Free(OBJTYPE_ACCOUNT_INFO, pACCOUNT);
}
} while(bSuccess);
}
static BOOL __AccountInfoParseInfoSectionData(PVOID pPassingPtr, SDAttrValueName tagValueName, SDAttrValue tagValue)
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
DWORD dwValue = 0;
if(tagValueName.IsMatch("WISE_MULTI_MODE"))
{
// MODE에 대한 정의가 필요하다.
tagValue.GetValue(dwValue);
rDATA.m_WiseMode = dwValue;
return TRUE;
}
else if(tagValueName.IsMatch("IF_MULTIUSER_COUNT"))
{
tagValue.GetValue(dwValue);
rDATA.m_WiseMaxUserCount = dwValue;
return TRUE;
}
return FALSE;
}
ScriptLogicInterface* Manipulater::GetScriptLogicInterface()
{
sDATA_CONTAINER& rDATA = *s_pDATA_CONTAINER;
return &rDATA.m_ScriptLogicInterface;
}
//////////////////////////////////////////////////////////////////////////
//