made clients sending startinfo a requirement to prevent empty player infos

This commit is contained in:
oy 2011-03-15 09:58:57 +01:00
parent 7b91ebd01c
commit 27e5a6af0d
8 changed files with 293 additions and 273 deletions

View file

@ -518,8 +518,6 @@ void CClient::SendInfo()
{
CMsgPacker Msg(NETMSG_INFO);
Msg.AddString(GameClient()->NetVersion(), 128);
Msg.AddString(g_Config.m_PlayerName, 128);
Msg.AddString(g_Config.m_ClanName, 128);
Msg.AddString(g_Config.m_Password, 128);
SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH);
}
@ -1175,7 +1173,6 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
{
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "loading done");
SendReady();
GameClient()->OnConnected();
}
else
{
@ -1239,7 +1236,6 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
{
m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "loading done");
SendReady();
GameClient()->OnConnected();
}
else
DisconnectWithReason(pError);
@ -1261,6 +1257,10 @@ void CClient::ProcessPacket(CNetChunk *pPacket)
}
}
}
else if(Msg == NETMSG_CON_READY)
{
GameClient()->OnConnected();
}
else if(Msg == NETMSG_PING)
{
CMsgPacker Msg(NETMSG_PING_REPLY);

View file

@ -77,6 +77,8 @@ public:
virtual void OnClientDirectInput(int ClientID, void *pInput) = 0;
virtual void OnClientPredictedInput(int ClientID, void *pInput) = 0;
virtual bool IsClientReady(int ClientID) = 0;
virtual const char *GameType() = 0;
virtual const char *Version() = 0;
virtual const char *NetVersion() = 0;

View file

@ -572,6 +572,12 @@ void CServer::SendMap(int ClientID)
SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID, true);
}
void CServer::SendConnectionReady(int ClientID)
{
CMsgPacker Msg(NETMSG_CON_READY);
SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID, true);
}
void CServer::SendRconLine(int ClientID, const char *pLine)
{
CMsgPacker Msg(NETMSG_RCON_LINE);
@ -612,26 +618,24 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
if(Unpacker.Error())
return;
if(Sys)
{
// system message
if(Msg == NETMSG_INFO)
{
if(m_aClients[ClientID].m_State == CClient::STATE_AUTH)
{
if(Sys && Msg == NETMSG_INFO)
const char *pVersion = Unpacker.GetString(CUnpacker::SANITIZE_CC);
if(str_comp(pVersion, GameServer()->NetVersion()) != 0)
{
char aVersion[64];
const char *pPassword;
str_copy(aVersion, Unpacker.GetString(CUnpacker::SANITIZE_CC), 64);
if(str_comp(aVersion, GameServer()->NetVersion()) != 0)
{
// OH FUCK! wrong version, drop him
// wrong version
char aReason[256];
str_format(aReason, sizeof(aReason), "Wrong version. Server is running '%s' and client '%s'", GameServer()->NetVersion(), aVersion);
str_format(aReason, sizeof(aReason), "Wrong version. Server is running '%s' and client '%s'", GameServer()->NetVersion(), pVersion);
m_NetServer.Drop(ClientID, aReason);
return;
}
str_copy(m_aClients[ClientID].m_aName, Unpacker.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), MAX_NAME_LENGTH);
str_copy(m_aClients[ClientID].m_aClan, Unpacker.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), MAX_CLANNAME_LENGTH);
pPassword = Unpacker.GetString(CUnpacker::SANITIZE_CC);
const char *pPassword = Unpacker.GetString(CUnpacker::SANITIZE_CC);
if(g_Config.m_Password[0] != 0 && str_comp(g_Config.m_Password, pPassword) != 0)
{
// wrong password
@ -643,12 +647,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
SendMap(ClientID);
}
}
else
{
if(Sys)
{
// system message
if(Msg == NETMSG_REQUEST_MAP_DATA)
else if(Msg == NETMSG_REQUEST_MAP_DATA)
{
int Chunk = Unpacker.GetInt();
int ChunkSize = 1024-128;
@ -694,11 +693,12 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
m_aClients[ClientID].m_State = CClient::STATE_READY;
GameServer()->OnClientConnected(ClientID);
SendConnectionReady(ClientID);
}
}
else if(Msg == NETMSG_ENTERGAME)
{
if(m_aClients[ClientID].m_State == CClient::STATE_READY)
if(m_aClients[ClientID].m_State == CClient::STATE_READY && GameServer()->IsClientReady(ClientID))
{
Addr = m_NetServer.ClientAddr(ClientID);
@ -856,7 +856,6 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
if(m_aClients[ClientID].m_State >= CClient::STATE_READY)
GameServer()->OnMessage(Msg, &Unpacker, ClientID);
}
}
}
void CServer::SendServerInfo(NETADDR *pAddr, int Token)

View file

@ -153,6 +153,7 @@ public:
static int DelClientCallback(int ClientID, const char *pReason, void *pUser);
void SendMap(int ClientID);
void SendConnectionReady(int ClientID);
void SendRconLine(int ClientID, const char *pLine);
static void SendRconLineAuthed(const char *pLine, void *pUser);

View file

@ -39,6 +39,7 @@ enum
// sent by server
NETMSG_MAP_CHANGE, // sent when client should switch map
NETMSG_MAP_DATA, // map transfer, contains a chunk of the map file
NETMSG_CON_READY, // connection is ready, client should send start info
NETMSG_SNAP, // normal snapshot, multiple parts
NETMSG_SNAPEMPTY, // empty snapshot
NETMSG_SNAPSINGLE, // ?

View file

@ -786,38 +786,22 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
else
pPlayer->m_SpectatorID = pMsg->m_SpectatorID;
}
else if (MsgID == NETMSGTYPE_CL_CHANGEINFO || MsgID == NETMSGTYPE_CL_STARTINFO)
else if (MsgID == NETMSGTYPE_CL_STARTINFO)
{
CNetMsg_Cl_ChangeInfo *pMsg = (CNetMsg_Cl_ChangeInfo *)pRawMsg;
if(g_Config.m_SvSpamprotection && pPlayer->m_LastChangeInfo && pPlayer->m_LastChangeInfo+Server()->TickSpeed()*5 > Server()->Tick())
if(pPlayer->m_IsReady)
return;
CNetMsg_Cl_StartInfo *pMsg = (CNetMsg_Cl_StartInfo *)pRawMsg;
pPlayer->m_LastChangeInfo = Server()->Tick();
// set start infos
Server()->SetClientName(ClientID, pMsg->m_pName);
str_copy(pPlayer->m_TeeInfos.m_SkinName, pMsg->m_pSkin, sizeof(pPlayer->m_TeeInfos.m_SkinName));
pPlayer->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor;
pPlayer->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody;
pPlayer->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet;
// copy old name
char aOldName[MAX_NAME_LENGTH];
str_copy(aOldName, Server()->ClientName(ClientID), MAX_NAME_LENGTH);
Server()->SetClientName(ClientID, pMsg->m_pName);
if(MsgID == NETMSGTYPE_CL_CHANGEINFO && str_comp(aOldName, Server()->ClientName(ClientID)) != 0)
{
char aChatText[256];
str_format(aChatText, sizeof(aChatText), "'%s' changed name to '%s'", aOldName, Server()->ClientName(ClientID));
SendChat(-1, CGameContext::CHAT_ALL, aChatText);
}
// set skin
str_copy(pPlayer->m_TeeInfos.m_SkinName, pMsg->m_pSkin, sizeof(pPlayer->m_TeeInfos.m_SkinName));
m_pController->OnPlayerInfoChange(pPlayer);
if(MsgID == NETMSGTYPE_CL_STARTINFO)
{
// send vote options
CNetMsg_Sv_VoteClearOptions ClearMsg;
Server()->SendPackMsg(&ClearMsg, MSGFLAG_VITAL, ClientID);
@ -833,10 +817,34 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
// send tuning parameters to client
SendTuningParams(ClientID);
//
// client is ready to enter
pPlayer->m_IsReady = true;
CNetMsg_Sv_ReadyToEnter m;
Server()->SendPackMsg(&m, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID);
}
else if (MsgID == NETMSGTYPE_CL_CHANGEINFO)
{
if(g_Config.m_SvSpamprotection && pPlayer->m_LastChangeInfo && pPlayer->m_LastChangeInfo+Server()->TickSpeed()*5 > Server()->Tick())
return;
CNetMsg_Cl_ChangeInfo *pMsg = (CNetMsg_Cl_ChangeInfo *)pRawMsg;
pPlayer->m_LastChangeInfo = Server()->Tick();
// set infos
char aOldName[MAX_NAME_LENGTH];
str_copy(aOldName, Server()->ClientName(ClientID), sizeof(aOldName));
Server()->SetClientName(ClientID, pMsg->m_pName);
if(str_comp(aOldName, Server()->ClientName(ClientID)) != 0)
{
char aChatText[256];
str_format(aChatText, sizeof(aChatText), "'%s' changed name to '%s'", aOldName, Server()->ClientName(ClientID));
SendChat(-1, CGameContext::CHAT_ALL, aChatText);
}
str_copy(pPlayer->m_TeeInfos.m_SkinName, pMsg->m_pSkin, sizeof(pPlayer->m_TeeInfos.m_SkinName));
pPlayer->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor;
pPlayer->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody;
pPlayer->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet;
m_pController->OnPlayerInfoChange(pPlayer);
}
else if (MsgID == NETMSGTYPE_CL_EMOTICON && !m_World.m_Paused)
{
@ -1167,6 +1175,11 @@ void CGameContext::OnPostSnap()
m_Events.Clear();
}
bool CGameContext::IsClientReady(int ClientID)
{
return m_apPlayers[ClientID] && m_apPlayers[ClientID]->m_IsReady ? true : false;
}
const char *CGameContext::GameType() { return m_pController && m_pController->m_pGameType ? m_pController->m_pGameType : ""; }
const char *CGameContext::Version() { return GAME_VERSION; }
const char *CGameContext::NetVersion() { return GAME_NETVERSION; }

View file

@ -161,6 +161,8 @@ public:
virtual void OnClientDirectInput(int ClientID, void *pInput);
virtual void OnClientPredictedInput(int ClientID, void *pInput);
virtual bool IsClientReady(int ClientID);
virtual const char *GameType();
virtual const char *Version();
virtual const char *NetVersion();

View file

@ -48,6 +48,8 @@ public:
// used for spectator mode
int m_SpectatorID;
bool m_IsReady;
//
int m_Vote;
int m_VotePos;