mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge pull request #301 from east/session_rejoin
Make rejoining session possible before timeout protection triggers
This commit is contained in:
commit
22860fbaa7
|
@ -760,16 +760,13 @@ void CServer::DoSnapshot()
|
|||
GameServer()->OnPostSnap();
|
||||
}
|
||||
|
||||
int CServer::NewClientNoAuthCallback(int ClientID, void *pUser)
|
||||
int CServer::ClientRejoinCallback(int ClientID, void *pUser)
|
||||
{
|
||||
CServer *pThis = (CServer *)pUser;
|
||||
pThis->m_aClients[ClientID].m_State = CClient::STATE_CONNECTING;
|
||||
pThis->m_aClients[ClientID].m_aName[0] = 0;
|
||||
pThis->m_aClients[ClientID].m_aClan[0] = 0;
|
||||
pThis->m_aClients[ClientID].m_Country = -1;
|
||||
|
||||
pThis->m_aClients[ClientID].m_Authed = AUTHED_NO;
|
||||
pThis->m_aClients[ClientID].m_AuthTries = 0;
|
||||
pThis->m_aClients[ClientID].m_pRconCmdToSend = 0;
|
||||
|
||||
pThis->m_aClients[ClientID].Reset();
|
||||
|
||||
pThis->SendMap(ClientID);
|
||||
|
@ -777,6 +774,26 @@ int CServer::NewClientNoAuthCallback(int ClientID, void *pUser)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CServer::NewClientNoAuthCallback(int ClientID, bool Reset, void *pUser)
|
||||
{
|
||||
CServer *pThis = (CServer *)pUser;
|
||||
if (Reset)
|
||||
{
|
||||
pThis->m_aClients[ClientID].m_State = CClient::STATE_CONNECTING;
|
||||
pThis->m_aClients[ClientID].m_aName[0] = 0;
|
||||
pThis->m_aClients[ClientID].m_aClan[0] = 0;
|
||||
pThis->m_aClients[ClientID].m_Country = -1;
|
||||
pThis->m_aClients[ClientID].m_Authed = AUTHED_NO;
|
||||
pThis->m_aClients[ClientID].m_AuthTries = 0;
|
||||
pThis->m_aClients[ClientID].m_pRconCmdToSend = 0;
|
||||
pThis->m_aClients[ClientID].Reset();
|
||||
}
|
||||
|
||||
pThis->SendMap(ClientID);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CServer::NewClientCallback(int ClientID, void *pUser)
|
||||
{
|
||||
CServer *pThis = (CServer *)pUser;
|
||||
|
@ -1028,8 +1045,9 @@ 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);
|
||||
}
|
||||
|
||||
SendConnectionReady(ClientID);
|
||||
}
|
||||
else if(Msg == NETMSG_ENTERGAME)
|
||||
{
|
||||
|
@ -1555,7 +1573,7 @@ int CServer::Run()
|
|||
return -1;
|
||||
}
|
||||
|
||||
m_NetServer.SetCallbacks(NewClientCallback, NewClientNoAuthCallback, DelClientCallback, this);
|
||||
m_NetServer.SetCallbacks(NewClientCallback, NewClientNoAuthCallback, ClientRejoinCallback, DelClientCallback, this);
|
||||
|
||||
m_Econ.Init(Console(), &m_ServerBan);
|
||||
|
||||
|
|
|
@ -220,9 +220,11 @@ public:
|
|||
void DoSnapshot();
|
||||
|
||||
static int NewClientCallback(int ClientID, void *pUser);
|
||||
static int NewClientNoAuthCallback(int ClientID, void *pUser);
|
||||
static int NewClientNoAuthCallback(int ClientID, bool Reset, void *pUser);
|
||||
static int DelClientCallback(int ClientID, const char *pReason, void *pUser);
|
||||
|
||||
static int ClientRejoinCallback(int ClientID, void *pUser);
|
||||
|
||||
void SendMap(int ClientID);
|
||||
void SendConnectionReady(int ClientID);
|
||||
void SendRconLine(int ClientID, const char *pLine);
|
||||
|
|
|
@ -96,7 +96,8 @@ enum
|
|||
|
||||
typedef int (*NETFUNC_DELCLIENT)(int ClientID, const char* pReason, void *pUser);
|
||||
typedef int (*NETFUNC_NEWCLIENT)(int ClientID, void *pUser);
|
||||
typedef int (*NETFUNC_NEWCLIENT_NOAUTH)(int ClientID, void *pUser);
|
||||
typedef int (*NETFUNC_NEWCLIENT_NOAUTH)(int ClientID, bool Reset, void *pUser);
|
||||
typedef int (*NETFUNC_CLIENTREJOIN)(int ClientID, void *pUser);
|
||||
|
||||
struct CNetChunk
|
||||
{
|
||||
|
@ -190,7 +191,7 @@ public:
|
|||
bool m_TimeoutProtected;
|
||||
bool m_TimeoutSituation;
|
||||
|
||||
void Reset();
|
||||
void Reset(bool Rejoin=false);
|
||||
void Init(NETSOCKET Socket, bool BlockCloseMsg);
|
||||
int Connect(NETADDR *pAddr);
|
||||
void Disconnect(const char *pReason);
|
||||
|
@ -290,6 +291,7 @@ class CNetServer
|
|||
NETFUNC_NEWCLIENT m_pfnNewClient;
|
||||
NETFUNC_NEWCLIENT_NOAUTH m_pfnNewClientNoAuth;
|
||||
NETFUNC_DELCLIENT m_pfnDelClient;
|
||||
NETFUNC_CLIENTREJOIN m_pfnClientRejoin;
|
||||
void *m_UserPtr;
|
||||
|
||||
|
||||
|
@ -301,6 +303,7 @@ class CNetServer
|
|||
|
||||
void OnTokenCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet);
|
||||
void OnPreConnMsg(NETADDR &Addr, CNetPacketConstruct &Packet);
|
||||
void OnConnCtrlMsg(NETADDR &Addr, int ClientID, int ControlMsg, const CNetPacketConstruct &Packet);
|
||||
bool ClientExists(const NETADDR &Addr) { return GetClientSlot(Addr) != -1; };
|
||||
int GetClientSlot(const NETADDR &Addr);
|
||||
void SendControl(NETADDR &Addr, int ControlMsg, const void *pExtra, int ExtraSize, SECURITY_TOKEN SecurityToken);
|
||||
|
@ -311,7 +314,7 @@ class CNetServer
|
|||
|
||||
public:
|
||||
int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser);
|
||||
int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_NEWCLIENT_NOAUTH pfnNewClientNoAuth, NETFUNC_DELCLIENT pfnDelClient, void *pUser);
|
||||
int SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_NEWCLIENT_NOAUTH pfnNewClientNoAuth, NETFUNC_CLIENTREJOIN pfnClientRejoin, NETFUNC_DELCLIENT pfnDelClient, void *pUser);
|
||||
|
||||
//
|
||||
bool Open(NETADDR BindAddr, class CNetBan *pNetBan, int MaxClients, int MaxClientsPerIP, int Flags);
|
||||
|
|
|
@ -16,7 +16,7 @@ void CNetConnection::ResetStats()
|
|||
m_LastUpdateTime = 0;
|
||||
}
|
||||
|
||||
void CNetConnection::Reset()
|
||||
void CNetConnection::Reset(bool Rejoin)
|
||||
{
|
||||
m_Sequence = 0;
|
||||
m_Ack = 0;
|
||||
|
@ -24,12 +24,17 @@ void CNetConnection::Reset()
|
|||
m_TimeoutProtected = false;
|
||||
m_TimeoutSituation = false;
|
||||
|
||||
m_State = NET_CONNSTATE_OFFLINE;
|
||||
if (!Rejoin)
|
||||
{
|
||||
m_State = NET_CONNSTATE_OFFLINE;
|
||||
m_Token = -1;
|
||||
m_SecurityToken = NET_SECURITY_TOKEN_UNKNOWN;
|
||||
}
|
||||
|
||||
m_LastSendTime = 0;
|
||||
m_LastRecvTime = 0;
|
||||
//m_LastUpdateTime = 0;
|
||||
m_Token = -1;
|
||||
m_SecurityToken = NET_SECURITY_TOKEN_UNKNOWN;
|
||||
|
||||
//mem_zero(&m_PeerAddr, sizeof(m_PeerAddr));
|
||||
m_UnknownSeq = false;
|
||||
|
||||
|
|
|
@ -60,10 +60,11 @@ int CNetServer::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT p
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CNetServer::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_NEWCLIENT_NOAUTH pfnNewClientNoAuth, NETFUNC_DELCLIENT pfnDelClient, void *pUser)
|
||||
int CNetServer::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_NEWCLIENT_NOAUTH pfnNewClientNoAuth, NETFUNC_CLIENTREJOIN pfnClientRejoin, NETFUNC_DELCLIENT pfnDelClient, void *pUser)
|
||||
{
|
||||
m_pfnNewClient = pfnNewClient;
|
||||
m_pfnNewClientNoAuth = pfnNewClientNoAuth;
|
||||
m_pfnClientRejoin = pfnClientRejoin;
|
||||
m_pfnDelClient = pfnDelClient;
|
||||
m_UserPtr = pUser;
|
||||
return 0;
|
||||
|
@ -207,7 +208,7 @@ int CNetServer::TryAcceptClient(NETADDR &Addr, SECURITY_TOKEN SecurityToken, boo
|
|||
|
||||
|
||||
if (VanillaAuth)
|
||||
m_pfnNewClientNoAuth(Slot, m_UserPtr);
|
||||
m_pfnNewClientNoAuth(Slot, true, m_UserPtr);
|
||||
else
|
||||
m_pfnNewClient(Slot, m_UserPtr);
|
||||
|
||||
|
@ -359,6 +360,43 @@ void CNetServer::OnPreConnMsg(NETADDR &Addr, CNetPacketConstruct &Packet)
|
|||
}
|
||||
}
|
||||
|
||||
void CNetServer::OnConnCtrlMsg(NETADDR &Addr, int ClientID, int ControlMsg, const CNetPacketConstruct &Packet)
|
||||
{
|
||||
if (ControlMsg == NET_CTRLMSG_CONNECT)
|
||||
{
|
||||
// got connection attempt inside of valid session
|
||||
// the client probably wants to reconnect
|
||||
bool SupportsToken = Packet.m_DataSize >=
|
||||
(int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(SECURITY_TOKEN)) &&
|
||||
!mem_comp(&Packet.m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC));
|
||||
|
||||
if (SupportsToken)
|
||||
{
|
||||
// response connection request with token
|
||||
SECURITY_TOKEN Token = GetToken(Addr);
|
||||
SendControl(Addr, NET_CTRLMSG_CONNECTACCEPT, SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC), Token);
|
||||
}
|
||||
|
||||
if (g_Config.m_Debug)
|
||||
dbg_msg("security", "client %d wants to reconnect", ClientID);
|
||||
}
|
||||
else if (ControlMsg == NET_CTRLMSG_ACCEPT && Packet.m_DataSize == 1 + sizeof(SECURITY_TOKEN))
|
||||
{
|
||||
SECURITY_TOKEN Token = ToSecurityToken(&Packet.m_aChunkData[1]);
|
||||
if (Token == GetToken(Addr))
|
||||
{
|
||||
// correct token
|
||||
// try to accept client
|
||||
if (g_Config.m_Debug)
|
||||
dbg_msg("security", "client %d reconnect");
|
||||
|
||||
// reset netconn and process rejoin
|
||||
m_aSlots[ClientID].m_Connection.Reset(true);
|
||||
m_pfnClientRejoin(ClientID, m_UserPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CNetServer::OnTokenCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet)
|
||||
{
|
||||
if (ClientExists(Addr))
|
||||
|
@ -471,6 +509,11 @@ int CNetServer::Recv(CNetChunk *pChunk)
|
|||
if (Slot != -1)
|
||||
{
|
||||
// found
|
||||
|
||||
// control
|
||||
if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONTROL)
|
||||
OnConnCtrlMsg(Addr, Slot, m_RecvUnpacker.m_Data.m_aChunkData[0], m_RecvUnpacker.m_Data);
|
||||
|
||||
if(m_aSlots[Slot].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr))
|
||||
{
|
||||
if(m_RecvUnpacker.m_Data.m_DataSize)
|
||||
|
|
Loading…
Reference in a new issue