📄 worldkernel.cpp
字号:
{
CMsgQueryFee_A::MSG_Info msg;
msg.unMsgSize = sizeof(msg);
msg.unMsgType = _MSG_QUERYFEE_A;
msg.idAccount = idAccount;
msg.dwData = dwData;
msg.nTime = nTime;
msg.ucType = ucType;
return m_sock.SendPacket((LPCTSTR)&msg, msg.unMsgSize, true);
}
///////////////////////////////////////////////////////////////////////////////////////
void CWorldKernel::ProcessAccountNetMsg()
{
bool bGetData = true;
while(true)
{
int nNetSize = 0;
LPCTSTR pMsg = m_sock.GetPacket(&nNetSize, bGetData);
if(!pMsg || nNetSize == 0)
break;
int nMsgSize = *((unsigned short*)pMsg);
if(nNetSize < nMsgSize)
break;
// 服务器登录 ////////////////////////////////////////
CMsgLogin_A::MSG_Info* pMsgLogin = (CMsgLogin_A::MSG_Info*)pMsg;
if(pMsgLogin->unMsgType == _MSG_LOGIN_A)
{
CHECK(pMsgLogin->unMsgSize == sizeof(CMsgLogin_A::MSG_Info));
ProcessLogin(pMsgLogin->idAccount, pMsgLogin->dwCheckData, pMsgLogin->usVersion, pMsgLogin->szUserName);
m_sock.ClearPacket(nMsgSize);
continue;
}
// 玩家部分 ////////////////////////////////////////
CMsgConnect_A::MSG_Info* pMsgConnect = (CMsgConnect_A::MSG_Info*)pMsg;
if(pMsgConnect->unMsgType == _MSG_CONNECT)
{
CHECK(pMsgConnect->unMsgSize == sizeof(CMsgConnect_A::MSG_Info));
if(ProcessConnect(pMsgConnect->idAccount, pMsgConnect->dwData, pMsgConnect->szInfo))
{
CPlayer* pPlayer = g_UserList.GetPlayerByAccountID(pMsgConnect->idAccount);
ASSERT(pPlayer);
if(pPlayer)
UserList()->LoginToMapGroup(pPlayer);
}
m_sock.ClearPacket(nMsgSize);
continue;
}
CMsgFee_A::MSG_Info* pMsgFee = (CMsgFee_A::MSG_Info*)pMsg;
if(pMsgFee->unMsgType == _MSG_FEE_A)
{
CHECK(pMsgFee->unMsgSize == sizeof(CMsgFee_A::MSG_Info));
ProcessFee(pMsgFee->idAccount, pMsgFee->ucType);
m_sock.ClearPacket(nMsgSize);
continue;
}
CMsgQueryFee_A::MSG_Info* pMsgQFee = (CMsgQueryFee_A::MSG_Info*)pMsg;
if(pMsgQFee->unMsgType == _MSG_QUERYFEE_A)
{
CHECK(pMsgQFee->unMsgSize == sizeof(CMsgQueryFee_A::MSG_Info));
ProcessQueryFee(pMsgQFee->idAccount, pMsgQFee->dwData, pMsgQFee->nTime, pMsgQFee->ucType);
m_sock.ClearPacket(nMsgSize);
continue;
}
bGetData = false;
} // for
}
///////////////////////////////////////////////////////////////////////////////////////
void CWorldKernel::ProcessLogin(OBJID idAccount, DWORD dwCheckData, int usVersion, LPCTSTR szUserName)
{
if(idAccount == ID_NONE)
{
PrintText("Account server login failed!");
return;
}
//??? 未检查版本号
m_idServer = idAccount;
PrintText("Account server login OK。");
SendLogin(idAccount, dwCheckData, usVersion, szUserName);
m_nState = STATE_NORMAL;
}
///////////////////////////////////////////////////////////////////////////////////////
bool CWorldKernel::ProcessConnect(OBJID idAccount, DWORD dwData, LPCTSTR szInfo) // return true: pass barrier
{
extern DWORD g_dwMaxPlayer;
if(GameWorld()->QueryUserList()->GetUserAmount() > g_dwMaxPlayer && idAccount > MAX_GM_ID)
{
GameWorld()->SendFee(idAccount, CMsgFee_A::SERVER_FULL); // 未上传SERVER_BUSY
return false;
}
CConnectUser* pConnect = m_setConnectClient->GetObj(idAccount);
if(pConnect)
{
if(pConnect->IsValid() && pConnect->CheckData(dwData)) // same id, same chkdata
{
SOCKET_ID idSocket = pConnect->GetSocketID();
m_setConnectClient->DelObj(idAccount);
// check repeat user_id
if(UserList()->GetPlayerByAccountID(idAccount))
{
LOGMSG("DEBUG:帐号[%u]重复登录,踢前一人下线 !", idAccount);
UserList()->KickOutAccount(idAccount, STR_LOGIN_AGAIN);
return false;
}
// OK
int ret = UserList()->LoginUser(idAccount, idSocket, szInfo); // enum { LOGIN_OK, LOGIN_NEW, LOGIN_BAN };
if (ret == LOGIN_OK)
return true;
else if(ret == LOGIN_BAN)
{
CMsgTalk msg;
if(msg.Create(SYSTEM_NAME, ALLUSERS_NAME, "错误:余额不足,请及时充值!", NULL, _COLOR_WHITE, _TXTATR_ENTRANCE))
SendClientMsg(idSocket, &msg);
return false;
}
else // LOGIN_NEW new account, no player created
{
CMsgTalk msg;
if (msg.Create(SYSTEM_NAME, ALLUSERS_NAME, NEW_ROLE_STR, NULL, _COLOR_WHITE, _TXTATR_ENTRANCE))
{
SendClientMsg(idSocket, &msg);
}
}
}
else // same id, but wrong chkdata
{
m_setConnectClient->DelObj(idAccount);
}
}
pConnect = CConnectUser::CreateNew();
CHECKF(pConnect->Create(idAccount, dwData, szInfo));
m_setConnectAccount->DelObj(idAccount); // 冲掉,防止WARNING输出
m_setConnectAccount->AddObj(pConnect);
return false;
}
///////////////////////////////////////////////////////////////////////////////////////
bool CWorldKernel::ClientConnect(OBJID idAccount, DWORD dwData, LPCTSTR szInfo, SOCKET_ID idSocket) // return true: pass barrier
{
CHECKF(idSocket != SOCKET_NONE);
CConnectUser* pConnect = m_setConnectAccount->GetObj(idAccount);
if(pConnect)
{
NAMESTR info;
SafeCopy(info, pConnect->GetInfo(), _MAX_NAMESIZE);
if(pConnect->IsValid() && pConnect->CheckData(dwData)) // same id, same chkdata
{
m_setConnectAccount->DelObj(idAccount);
// check repeat user_id
if(UserList()->GetPlayerByAccountID(idAccount))
{
LOGMSG("DEBUG:帐号[%u]重复登录,踢前一人下线!", idAccount);
UserList()->KickOutAccount(idAccount, STR_LOGIN_AGAIN);
return false;
}
// OK
int ret = UserList()->LoginUser(idAccount, idSocket, info); // enum { LOGIN_OK, LOGIN_NEW, LOGIN_BAN };
if (ret == LOGIN_OK)
return true;
else if(ret == LOGIN_BAN)
{
CMsgTalk msg;
if(msg.Create(SYSTEM_NAME, ALLUSERS_NAME, "错误:余额不足,请及时充值!", NULL, _COLOR_WHITE, _TXTATR_ENTRANCE))
SendClientMsg(idSocket, &msg);
return false;
}
else // LOGIN_NEW new account, no player created
{
CMsgTalk msg;
if (msg.Create(SYSTEM_NAME, ALLUSERS_NAME, NEW_ROLE_STR, NULL, _COLOR_WHITE, _TXTATR_ENTRANCE))
{
SendClientMsg(idSocket, &msg);
}
}
}
else
{
m_setConnectAccount->DelObj(idAccount);
}
}
pConnect = CConnectUser::CreateNew();
CHECKF(pConnect->Create(idAccount, dwData, szInfo, idSocket));
m_setConnectClient->DelObj(idAccount); // 防止WARNING
m_setConnectClient->AddObj(pConnect);
return false;
}
///////////////////////////////////////////////////////////////////////////////////////
void CWorldKernel::ProcessFee(OBJID idAccount, int nType)
{
switch(nType)
{
case CMsgFee_A::HEARTBEAT:
SendFee(idAccount, CMsgFee_A::HEARTBEAT);
break;
case CMsgFee_A::FEE_KICKOUT:
LOGMSG("DEBUG:帐号服务器踢出帐号[%u]", idAccount);
if(!UserList()->KickOutAccount(idAccount, STR_LOGIN_ANOTHER)) // 不在线
SendFee(idAccount, CMsgFee_A::FEE_OFFLINE);
break;
default:
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////
enum { c_typeNone = 0, c_typePoint, c_typeTime, c_typeNetBarPoint, c_typeNetBarTime, c_typeISP, c_typeFree, c_typeAll };
void CWorldKernel::ProcessQueryFee(OBJID idAccount, DWORD dwData, int nTime, int ucType)
{
CPlayer* pUser =UserList()->GetPlayerByAccountID(idAccount);
if(pUser)
{
char szMsg[1024] = STR_FEETYPE_KNOWN;
switch(ucType)
{
case c_typePoint:
sprintf(szMsg, STR_FEETYPE_HOUR, dwData/20, (dwData/2)%10);
break;
case c_typeTime:
sprintf(szMsg, STR_FEETYPE_MONTH, nTime/10000, (nTime/100) % 100, nTime % 100);
break;
case c_typeNetBarPoint:
sprintf(szMsg, STR_FEETYPE_BARHOUR, dwData);
break;
case c_typeNetBarTime:
sprintf(szMsg, STR_FEETYPE_BARMONTH, dwData);
break;
case c_typeISP:
sprintf(szMsg, STR_FEETYPE_ISP, dwData);
break;
case c_typeFree:
sprintf(szMsg, STR_FEETYPE_FREE, dwData);
break;
}
CMsgTalk msg;
IF_OK(msg.Create(SYSTEM_NAME, pUser->szName, szMsg))
pUser->SendMsg(&msg);
szMsg[0] = 0;
if(strcmp(pUser->szNotify, FLAG_ISP_TO_NORMAL) == 0) // ★注意:该字符串必须与帐号服务器同步
SafeCopy(szMsg, STR_LOGIN_ISP_FAIL);
else if(strcmp(pUser->szNotify, FLAG_NO_POINT) == 0)
SafeCopy(szMsg, STR_ACCOUNT_NOFEE);
else if(pUser->szNotify[0] >= '0' && pUser->szNotify[0] <= '9')
sprintf(szMsg, STR_FEW_FEE_NOTIFY, pUser->szNotify);
else
SafeCopy(szMsg, pUser->szNotify, _MAX_NAMESIZE);
if(strlen(szMsg) > 0)
{
CMsgTalk msg;
IF_OK(msg.Create(SYSTEM_NAME, pUser->szName, szMsg))
pUser->SendMsg(&msg);
}
}
else
LOGERROR("帐号服务器返回了未登录玩家的查询计费消息");
}
///////////////////////////////////////////////////////////////////////////////////////
// global entry
///////////////////////////////////////////////////////////////////////////////////////
IWorld* IWorld::CreateNew()
{
return new CWorldKernel;
}
//////////////////////////////////////////////////////////////////////
// syndicate
//////////////////////////////////////////////////////////////////////
bool CWorldKernel::CreateSyndicate (const CreateSyndicateInfo* pInfo)
{
for(int i = MSGPORT_MAPGROUP_FIRST; i < GameWorld()->GetMsgPort()->GetSize(); i++)
{
m_pMsgPort->Send(i, KERNEL_CREATESYNDICATE, STRUCT_TYPE(CreateSyndicateInfo), pInfo);
}
return true;
}
//////////////////////////////////////////////////////////////////////
bool CWorldKernel::DestroySyndicate (OBJID idSyn, OBJID idTarget)
{
OBJID setID[2];
setID[0] = idSyn;
setID[1] = idTarget;
for(int i = MSGPORT_MAPGROUP_FIRST; i < GameWorld()->GetMsgPort()->GetSize(); i++)
{
m_pMsgPort->Send(i, KERNEL_DESTROYSYNDICATE, STRUCT_TYPE(setID), &setID);
}
return true;
}
//////////////////////////////////////////////////////////////////////
bool CWorldKernel::CombineSyndicate(OBJID idSyn, OBJID idTarget)
{
OBJID setID[2];
setID[0] = idSyn;
setID[1] = idTarget;
for(int i = MSGPORT_MAPGROUP_FIRST; i < GameWorld()->GetMsgPort()->GetSize(); i++)
{
m_pMsgPort->Send(i, KERNEL_COMBINESYNDICATE, STRUCT_TYPE(setID), &setID);
}
return true;
}
//////////////////////////////////////////////////////////////////////
bool CWorldKernel::ChangeSyndicate (const SynFuncInfo0* pFuncInfo)
{
for(int i = MSGPORT_MAPGROUP_FIRST; i < GameWorld()->GetMsgPort()->GetSize(); i++)
{
m_pMsgPort->Send(i, KERNEL_CHANGESYNDICATE, BUFFER_TYPE(pFuncInfo->nSize), pFuncInfo);
}
return true;
}
//////////////////////////////////////////////////////////////////////
enum { CONFIGDATA_NAME=1, CONFIGDATA_DATA, CONFIGDATA_STRING };
bool CWorldKernel::LoadConfig(IDatabase *pDb)
{
extern long g_sKickoutCheat;
char szSQL[1024];
sprintf(szSQL, "SELECT * FROM %s", _TBL_CONFIG);
CAutoPtr<IRecordset> pRes = pDb->CreateNewRecordset(szSQL, false);
CHECKF(pRes);
for(int i = 0; i < pRes->RecordCount(); i++, pRes->MoveNext())
{
if(stricmp(pRes->GetStr(CONFIGDATA_NAME), "kickoutcheat") == 0)
InterlockedExchange(&g_sKickoutCheat, pRes->GetInt(CONFIGDATA_DATA));
}
return true;
}
bool CWorldKernel::SendMapGroupMsgForChatRoom(int nMapGroup,SOCKET_ID idSocket,CNetMsg *pMsg)
{
ASSERT(idSocket != SOCKET_NONE);
MESSAGESTR buf;
TRANSMSG_PACKET0* pPacket = (TRANSMSG_PACKET0*)buf;
pPacket->idSocket = idSocket;
pPacket->idNpc = ID_NONE;
pPacket->idPacket = pMsg->GetType();
memcpy(pPacket->buf, pMsg->GetBuf(), pMsg->GetSize());
pPacket->nSize = pMsg->GetSize();
pPacket->nTrans = pMsg->GetTransData();
CHECKF( nMapGroup >= MSGPORT_MAPGROUP_FIRST && nMapGroup < m_pMsgPort->GetSize());
m_pMsgPort->Send(nMapGroup, MAPGROUP_TRANSMITMSG_FORCHATROOM, STRUCT_TYPE(buf), pPacket);
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -