06-29-2022, 12:30 PM
15 hours ago, Andrein95 said:
Thank you for your share, I appreciate a lot! Like you also I have this passion xD
BTW: You would you like to achieve a reactive counter of current logged users? I explain my self better: If someone log-out or log-in after you got information chained Connector->gs-> client, the client should listen this change but with push logic or polling logic?
In principle we should be able to detect the disconnection of the client in the GameServer, at that point in the code put a trigger to the Connector->GameServer->All Clients to update the flag to -1
--- Update 29/06/2022 - 22:32:00 ---
I will share the code in this same post so as not to create unnecessary entries, as I refine it I will update it here as well
In nov source:
Server Side:
GameServer-> Descriptor.cpp Line 836
After this
DescManager::instance()->insert(this);
Add this (This is the first trigger, when Client connect to GameServer it send a request to Connector asking for Total players counted)
// NICOLASG MARK (SHOW ONLINE USERS)
{
CNetMsg::SP rmsg(new CNetMsg);
rmsg->Init(MSG_CONN_REQ);
RefMsg(rmsg) << (unsigned char) MSG_CONN_ONLINE_PLAYERS_REQ << gserver->m_serverno << gserver->m_subno; // Must define this message (Inside _tagMsgConnType)
SEND_Q(rmsg, gserver->m_connector);
}
// NICOLASG MARK (SHOW ONLINE USERS)
Connector-> Server.cpp Line 197
After this
case MSG_CONN_LOGOUT_REQ:
ConnLogout(d, msg);
break;
Add this (This decides what to do if the Connector receives the 'MSG_CONN_ONLINE_PLAYERS_REQ' packet (In this case execute the function 'ConnOnlinePlayersReq'))
// NICOLASG MARK (SHOW ONLINE USERS)
case MSG_CONN_ONLINE_PLAYERS_REQ:
int ServerNumber, ChannelNumber;
RefMsg(msg) >> ServerNumber;
RefMsg(msg) >> ChannelNumber;
ConnOnlinePlayersReq(d, msg, ServerNumber, ChannelNumber);
break;
// NICOLASG MARK (SHOW ONLINE USERS)
Connector-> ProcConnMsg.cpp Line 472
After function
bool WriteDB(const char* name)
Add this (In this function you could put the code of the following function to simplify the code a bit)
// NICOLASG MARK (SHOW ONLINE USERS)
void ConnOnlinePlayersReq(CDescriptor* d, CNetMsg::SP& msg, int ServerNumber, int ChannelNumber){
CNetMsg::SP rmsg(new CNetMsg);
OnlinePlayersReqMsg(rmsg, ServerNumber, ChannelNumber);
SEND_Q(rmsg, d);
}
// NICOLASG MARK (SHOW ONLINE USERS)
Connector-> CmdMsg.cpp Line 244
After function
void LimitCatalogMsg
Add this (This is the function in charge of obtaining the number of players online, adding +1 to it and returning a Response to GameServer)
// NICOLASG MARK (SHOW ONLINE USERS)
void OnlinePlayersReqMsg(CNetMsg::SP& msg, int ServerNumber, int ChannelNumber){
int s, getTotalOnline = 0;
for(s = 0; s < gserver.m_maxSubServer; s++){
if(s == ServerNumber-1){
getTotalOnline = gserver.m_user_list->getUserCountInChannel(ChannelNumber);
break;
}
}
msg->Init(MSG_CONN_REP);
RefMsg(msg) << (unsigned char)MSG_CONN_ONLINE_PLAYERS_RES << getTotalOnline;
}
// NICOLASG MARK (SHOW ONLINE USERS)
GameServer-> ProcConnMsg.cpp Line 113
After this
case MSG_CONN_MOVESERVER_OK:
OnMoveServerOK(msg);
break;
Add this (Here we define what happens on the GameServer side when the 'MSG_CONN_ONLINE_PLAYERS_RES' message is received from Connector (in this case execute the 'SendOnlinePlayersToClients' function))
// NICOLASG MARK (SHOW ONLINE USERS)
case MSG_CONN_ONLINE_PLAYERS_RES:
SendOnlinePlayersToClients(msg);
break;
// NICOLASG MARK (SHOW ONLINE USERS)
GameServer-> Descriptor.cpp Line 1251
After function
void CDescriptor:
endData_StartAndMoveZoneAdd this (This function is the one that sends the online players number to the Clients)
// NICOLASG MARK (SHOW ONLINE USERS)
void SendOnlinePlayersToClients(CNetMsg::SP& msg){
int getTotalOnline;
RefMsg(msg) >> getTotalOnline;
CNetMsg::SP rmsg(new CNetMsg);
UpdateClient::OnlinePlayersInfo* packet = reinterpret_cast<UpdateClient::OnlinePlayersInfo*>(rmsg->m_buf); // Must create this structure in ptype_char_status.h (inside of namespace UpdateClient) (BTW this is the structure: struct OnlinePlayersInfo : public pTypeBase{int PlayersOnline;}

packet->type = MSG_UPDATE_DATA_FOR_CLIENT;
packet->subType = MSG_SUB_UPDATE_ONLINE_PLAYERS; // Must define this in ptype_char_status.h (Above of 'MSG_SUB_UPDATE_FIRST_MONENY')
packet->PlayersOnline = getTotalOnline;
rmsg->setSize(sizeof(UpdateClient::OnlinePlayersInfo));
PCManager::instance()->sendToAll(rmsg);
}
// NICOLASG MARK (SHOW ONLINE USERS)
GameServer-> DBProcess_SaveChar.cpp Line 388
After this
LOG_INFO("send logout msg to Connector : user_index[%d] id[%s]", userIndex, id.c_str());
Add this (This is the trigger for when a user logs out)
// NICOLASG MARK (SHOW ONLINE USERS)
{
CNetMsg::SP rmsg(new CNetMsg);
rmsg->Init(MSG_CONN_REQ);
RefMsg(rmsg) << (unsigned char) MSG_CONN_ONLINE_PLAYERS_REQ << gserver->m_serverno << gserver->m_subno;
SEND_Q(rmsg, gserver->m_connector);
}
// NICOLASG MARK (SHOW ONLINE USERS)
Client Side:
CNetwork.h Line 748
After this
MyChaInfo MyCharacterInfo;
Add this (In this variable we will store the number of online users)
int PlayersCounter; // NICOLASG MARK (SHOW ONLINE USERS)
SessionStateInfo.cpp Line 91 / 137 / 141
After this
DECLARE_MSG_UPDATE(charHPMP);
Add this
DECLARE_MSG_UPDATE(OnlinePlayers); // NICOLASG MARK (SHOW ONLINE USERS)
After this
REG_PACKET_UPDATE(MSG_UPDATE_DATA_FOR_CLIENT, MSG_SUB_UPDATE_CHAR_HPMP, charHPMP);
Add this
REG_PACKET_UPDATE(MSG_UPDATE_DATA_FOR_CLIENT, MSG_SUB_UPDATE_ONLINE_PLAYERS, OnlinePlayers); // NICOLASG MARK (SHOW ONLINE USERS)
Finally a few lines later, when the brace closes, Add this (This function is responsible for storing the value received from the package 'MSG_UPDATE_DATA_FOR_CLIENT'/'MSG_SUB_UPDATE_ONLINE_PLAYERS' inside the variable 'PlayersCounter')
// NICOLASG MARK (SHOW ONLINE USERS)
IMPLEMENT_MSG_UPDATE(OnlinePlayers){
UpdateClient::OnlinePlayersInfo* pPack = reinterpret_cast<UpdateClient::OnlinePlayersInfo*>(istr->GetBuffer());
_pNetwork->PlayersCounter = (pPack->PlayersOnline);
}
// NICOLASG MARK (SHOW ONLINE USERS)
At this point you can call the variable where you want, for example I show the players online under the radar, the code would be the following:
UIRadar.cpp
Add this (This is to be able to get the variable 'iPlayerNum')
#include <Engine/Contents/Login/ServerSelect.h> // NICOLASG MARK (SHOW ONLINE USERS)
Inside of
void CUIRadar::OnUpdate
Add this (Clarification, this is horrible, it can be simplified using a monstrous oneliner, probably the conditions are unnecessary, so all this, I insist, can be simplified...)
// NICOLASG MARK (SHOW ONLINE USERS)
CTString strOnlinePlayers;
if(_pNetwork->PlayersCounter == NULL){
GameDataManager* pDataManager = GameDataManager::getSingleton();
if(pDataManager == NULL){
return;
}else{
CServerSelect* pServerData = pDataManager->GetServerData();
if(pServerData == NULL){
return;
}else{
sServerInfo* pServerInfo = pServerData->ServerListAt(pServerData->GetRecentServer()-1);
if(pServerInfo == NULL){
return;
}else{
sChannelInfo* pChannelInfo = pServerInfo->ChannelListAt(_pNetwork->m_iServerCh-1);
if(pChannelInfo == NULL){
strOnlinePlayers.PrintF("Online: -");
}else{
strOnlinePlayers.PrintF("Online: %d", pChannelInfo->iPlayerNum+1);// +1 because pChannelInfo->iPlayerNum doesn't bring up the current user
}
}
}
}
}else{
strOnlinePlayers.PrintF("Online: %d", _pNetwork->PlayersCounter);
}
m_pTxtOnlineInfo->SetText(strOnlinePlayers);
// NICOLASG MARK (SHOW ONLINE USERS)
Remember to create the UIText in the xml. And m_pTxtOnlineInfo in the .h & .cpp^^
The result (if I don't forget any code xD) should be this
p.s: I should clear the 'PlayersCounter' variable when I log out...

