mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Begin work on 0.7 support
This commit is contained in:
parent
e9ba23b53a
commit
442148a194
|
@ -114,6 +114,8 @@ public:
|
|||
|
||||
bool Translate(int& Target, int Client)
|
||||
{
|
||||
if(IsSixup(Client))
|
||||
return true;
|
||||
CClientInfo Info;
|
||||
GetClientInfo(Client, &Info);
|
||||
if (Info.m_DDNetVersion >= VERSION_DDNET_OLD)
|
||||
|
@ -134,6 +136,8 @@ public:
|
|||
|
||||
bool ReverseTranslate(int& Target, int Client)
|
||||
{
|
||||
if(IsSixup(Client))
|
||||
return true;
|
||||
CClientInfo Info;
|
||||
GetClientInfo(Client, &Info);
|
||||
if (Info.m_DDNetVersion >= VERSION_DDNET_OLD)
|
||||
|
@ -199,6 +203,8 @@ public:
|
|||
virtual void SendMsgRaw(int ClientID, const void *pData, int Size, int Flags) = 0;
|
||||
|
||||
virtual char *GetMapName() = 0;
|
||||
|
||||
virtual bool IsSixup(int ClientID) = 0;
|
||||
};
|
||||
|
||||
class IGameServer : public IInterface
|
||||
|
|
|
@ -259,6 +259,7 @@ void CServer::CClient::Reset()
|
|||
m_DDNetVersion = VERSION_NONE;
|
||||
m_GotDDNetVersionPacket = false;
|
||||
m_DDNetVersionSettled = false;
|
||||
m_Sixup = false;
|
||||
}
|
||||
|
||||
CServer::CServer()
|
||||
|
@ -758,7 +759,7 @@ void CServer::DoSnapshot()
|
|||
int DeltaTick = -1;
|
||||
int DeltaSize;
|
||||
|
||||
m_SnapshotBuilder.Init();
|
||||
m_SnapshotBuilder.Init(m_aClients[i].m_Sixup);
|
||||
|
||||
GameServer()->OnSnap(i);
|
||||
|
||||
|
@ -895,7 +896,7 @@ int CServer::NewClientNoAuthCallback(int ClientID, void *pUser)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CServer::NewClientCallback(int ClientID, void *pUser)
|
||||
int CServer::NewClientCallback(int ClientID, void *pUser, bool Sixup)
|
||||
{
|
||||
CServer *pThis = (CServer *)pUser;
|
||||
pThis->m_aClients[ClientID].m_State = CClient::STATE_PREAUTH;
|
||||
|
@ -917,6 +918,8 @@ int CServer::NewClientCallback(int ClientID, void *pUser)
|
|||
pThis->GameServer()->OnClientEngineJoin(ClientID);
|
||||
pThis->Antibot()->OnEngineClientJoin(ClientID);
|
||||
|
||||
pThis->m_aClients[ClientID].m_Sixup = Sixup;
|
||||
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pThis->SendConnLoggingCommand(OPEN_SESSION, pThis->m_NetServer.ClientAddr(ClientID));
|
||||
#endif
|
||||
|
@ -1042,7 +1045,13 @@ void CServer::SendMap(int ClientID)
|
|||
Msg.AddString(GetMapName(), 0);
|
||||
Msg.AddInt(m_CurrentMapCrc);
|
||||
Msg.AddInt(m_CurrentMapSize);
|
||||
SendMsg(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID);
|
||||
if(m_aClients[ClientID].m_Sixup)
|
||||
{
|
||||
Msg.AddInt(1);
|
||||
Msg.AddInt(1024-128);
|
||||
Msg.AddRaw(m_CurrentMapSha256.data, sizeof(m_CurrentMapSha256.data));
|
||||
}
|
||||
SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID, true);
|
||||
}
|
||||
|
||||
m_aClients[ClientID].m_NextMapChunk = 0;
|
||||
|
@ -1064,11 +1073,14 @@ void CServer::SendMapData(int ClientID, int Chunk)
|
|||
Last = 1;
|
||||
}
|
||||
|
||||
CMsgPacker Msg(NETMSG_MAP_DATA, true);
|
||||
Msg.AddInt(Last);
|
||||
Msg.AddInt(m_CurrentMapCrc);
|
||||
Msg.AddInt(Chunk);
|
||||
Msg.AddInt(ChunkSize);
|
||||
CMsgPacker Msg(NETMSG_MAP_DATA);
|
||||
if(!m_aClients[ClientID].m_Sixup)
|
||||
{
|
||||
Msg.AddInt(Last);
|
||||
Msg.AddInt(m_CurrentMapCrc);
|
||||
Msg.AddInt(Chunk);
|
||||
Msg.AddInt(ChunkSize);
|
||||
}
|
||||
Msg.AddRaw(&m_pCurrentMapData[Offset], ChunkSize);
|
||||
SendMsg(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID);
|
||||
|
||||
|
@ -1248,7 +1260,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
{
|
||||
return;
|
||||
}
|
||||
if(str_comp(pVersion, GameServer()->NetVersion()) != 0)
|
||||
if(str_comp(pVersion, GameServer()->NetVersion()) != 0 && str_comp(pVersion, "0.7 802f1be60a05665f") != 0)
|
||||
{
|
||||
// wrong version
|
||||
char aReason[256];
|
||||
|
@ -1287,6 +1299,13 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) == 0 || m_aClients[ClientID].m_State < CClient::STATE_CONNECTING)
|
||||
return;
|
||||
|
||||
if(m_aClients[ClientID].m_Sixup)
|
||||
{
|
||||
SendMapData(ClientID, m_aClients[ClientID].m_NextMapChunk);
|
||||
m_aClients[ClientID].m_NextMapChunk++;
|
||||
return;
|
||||
}
|
||||
|
||||
int Chunk = Unpacker.GetInt();
|
||||
if(Chunk != m_aClients[ClientID].m_NextMapChunk || !g_Config.m_SvFastDownload)
|
||||
{
|
||||
|
|
|
@ -200,6 +200,8 @@ public:
|
|||
// DNSBL
|
||||
int m_DnsblState;
|
||||
std::shared_ptr<CHostLookup> m_pDnsblLookup;
|
||||
|
||||
bool m_Sixup;
|
||||
};
|
||||
|
||||
CClient m_aClients[MAX_CLIENTS];
|
||||
|
@ -290,7 +292,7 @@ public:
|
|||
|
||||
void DoSnapshot();
|
||||
|
||||
static int NewClientCallback(int ClientID, void *pUser);
|
||||
static int NewClientCallback(int ClientID, void *pUser, bool Sixup);
|
||||
static int NewClientNoAuthCallback(int ClientID, void *pUser);
|
||||
static int DelClientCallback(int ClientID, const char *pReason, void *pUser);
|
||||
|
||||
|
@ -433,6 +435,8 @@ public:
|
|||
bool ErrorShutdown() const { return m_aErrorShutdownReason[0] != 0; }
|
||||
void SetErrorShutdown(const char *pReason);
|
||||
|
||||
bool IsSixup(int ClientID) { return m_aClients[ClientID].m_Sixup; }
|
||||
|
||||
#ifdef CONF_FAMILY_UNIX
|
||||
enum CONN_LOGGING_CMD
|
||||
{
|
||||
|
|
|
@ -41,12 +41,12 @@ int CNetRecvUnpacker::FetchChunk(CNetChunk *pChunk)
|
|||
// TODO: add checking here so we don't read too far
|
||||
for(int i = 0; i < m_CurrentChunk; i++)
|
||||
{
|
||||
pData = Header.Unpack(pData);
|
||||
pData = Header.Unpack(pData, (m_pConnection && m_pConnection->m_Sixup) ? 6 : 4);
|
||||
pData += Header.m_Size;
|
||||
}
|
||||
|
||||
// unpack the header
|
||||
pData = Header.Unpack(pData);
|
||||
pData = Header.Unpack(pData, (m_pConnection && m_pConnection->m_Sixup) ? 6 : 4);
|
||||
m_CurrentChunk++;
|
||||
|
||||
if(pData+Header.m_Size > pEnd)
|
||||
|
@ -110,7 +110,7 @@ void CNetBase::SendPacketConnless(NETSOCKET Socket, NETADDR *pAddr, const void *
|
|||
net_udp_send(Socket, pAddr, aBuffer, DataSize + DATA_OFFSET);
|
||||
}
|
||||
|
||||
void CNetBase::SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct *pPacket, SECURITY_TOKEN SecurityToken)
|
||||
void CNetBase::SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct *pPacket, SECURITY_TOKEN SecurityToken, bool Sixup)
|
||||
{
|
||||
unsigned char aBuffer[NET_MAX_PACKETSIZE];
|
||||
int CompressedSize = -1;
|
||||
|
@ -126,7 +126,13 @@ void CNetBase::SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct
|
|||
io_flush(ms_DataLogSent);
|
||||
}
|
||||
|
||||
if (SecurityToken != NET_SECURITY_TOKEN_UNSUPPORTED)
|
||||
int HeaderSize = NET_PACKETHEADERSIZE;
|
||||
if (Sixup)
|
||||
{
|
||||
HeaderSize += 4;
|
||||
mem_copy(&aBuffer[3], &SecurityToken, 4);
|
||||
}
|
||||
else if (SecurityToken != NET_SECURITY_TOKEN_UNSUPPORTED)
|
||||
{
|
||||
// append security token
|
||||
// if SecurityToken is NET_SECURITY_TOKEN_UNKNOWN we will still append it hoping to negotiate it
|
||||
|
@ -135,7 +141,7 @@ void CNetBase::SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct
|
|||
}
|
||||
|
||||
// compress
|
||||
CompressedSize = ms_Huffman.Compress(pPacket->m_aChunkData, pPacket->m_DataSize, &aBuffer[3], NET_MAX_PACKETSIZE-4);
|
||||
CompressedSize = ms_Huffman.Compress(pPacket->m_aChunkData, pPacket->m_DataSize, &aBuffer[HeaderSize], NET_MAX_PACKETSIZE-HeaderSize);
|
||||
|
||||
// check if the compression was enabled, successful and good enough
|
||||
#ifndef FUZZING
|
||||
|
@ -149,14 +155,23 @@ void CNetBase::SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct
|
|||
{
|
||||
// use uncompressed data
|
||||
FinalSize = pPacket->m_DataSize;
|
||||
mem_copy(&aBuffer[3], pPacket->m_aChunkData, pPacket->m_DataSize);
|
||||
mem_copy(&aBuffer[HeaderSize], pPacket->m_aChunkData, pPacket->m_DataSize);
|
||||
pPacket->m_Flags &= ~NET_PACKETFLAG_COMPRESSION;
|
||||
}
|
||||
|
||||
if(Sixup)
|
||||
{
|
||||
unsigned Flags = 0;
|
||||
if (pPacket->m_Flags&NET_PACKETFLAG_CONTROL) Flags |= 1;
|
||||
if (pPacket->m_Flags&NET_PACKETFLAG_RESEND) Flags |= 2;
|
||||
if (pPacket->m_Flags&NET_PACKETFLAG_COMPRESSION) Flags |= 4;
|
||||
pPacket->m_Flags = Flags;
|
||||
}
|
||||
|
||||
// set header and send the packet if all things are good
|
||||
if(FinalSize >= 0)
|
||||
{
|
||||
FinalSize += NET_PACKETHEADERSIZE;
|
||||
FinalSize += HeaderSize;
|
||||
aBuffer[0] = ((pPacket->m_Flags<<2)&0xfc)|((pPacket->m_Ack>>8)&0x3);
|
||||
aBuffer[1] = pPacket->m_Ack&0xff;
|
||||
aBuffer[2] = pPacket->m_NumChunks;
|
||||
|
@ -175,7 +190,7 @@ void CNetBase::SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct
|
|||
}
|
||||
|
||||
// TODO: rename this function
|
||||
int CNetBase::UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct *pPacket)
|
||||
int CNetBase::UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct *pPacket, SECURITY_TOKEN *SecurityToken, bool Sixup)
|
||||
{
|
||||
// check the size
|
||||
if(Size < NET_PACKETHEADERSIZE || Size > NET_MAX_PACKETSIZE)
|
||||
|
@ -200,6 +215,15 @@ int CNetBase::UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct
|
|||
pPacket->m_NumChunks = pBuffer[2];
|
||||
pPacket->m_DataSize = Size - NET_PACKETHEADERSIZE;
|
||||
|
||||
if(Sixup)
|
||||
{
|
||||
unsigned Flags = 0;
|
||||
if (pPacket->m_Flags&1) Flags |= NET_PACKETFLAG_CONTROL;
|
||||
if (pPacket->m_Flags&2) Flags |= NET_PACKETFLAG_RESEND;
|
||||
if (pPacket->m_Flags&4) Flags |= NET_PACKETFLAG_COMPRESSION;
|
||||
pPacket->m_Flags = Flags;
|
||||
}
|
||||
|
||||
if(pPacket->m_Flags&NET_PACKETFLAG_CONNLESS)
|
||||
{
|
||||
const int DATA_OFFSET = 6;
|
||||
|
@ -223,6 +247,15 @@ int CNetBase::UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct
|
|||
}
|
||||
else
|
||||
{
|
||||
int DataStart = NET_PACKETHEADERSIZE;
|
||||
if(Sixup)
|
||||
{
|
||||
if(Size < NET_PACKETHEADERSIZE+4)
|
||||
return -1;
|
||||
pPacket->m_DataSize -= 4;
|
||||
DataStart += 4;
|
||||
mem_copy(SecurityToken, &pBuffer[3], 4);
|
||||
}
|
||||
if(pPacket->m_Flags&NET_PACKETFLAG_COMPRESSION)
|
||||
{
|
||||
// Don't allow compressed control packets.
|
||||
|
@ -230,10 +263,10 @@ int CNetBase::UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct
|
|||
{
|
||||
return -1;
|
||||
}
|
||||
pPacket->m_DataSize = ms_Huffman.Decompress(&pBuffer[3], pPacket->m_DataSize, pPacket->m_aChunkData, sizeof(pPacket->m_aChunkData));
|
||||
pPacket->m_DataSize = ms_Huffman.Decompress(&pBuffer[DataStart], pPacket->m_DataSize, pPacket->m_aChunkData, sizeof(pPacket->m_aChunkData));
|
||||
}
|
||||
else
|
||||
mem_copy(pPacket->m_aChunkData, &pBuffer[3], pPacket->m_DataSize);
|
||||
mem_copy(pPacket->m_aChunkData, &pBuffer[DataStart], pPacket->m_DataSize);
|
||||
}
|
||||
|
||||
// check for errors
|
||||
|
@ -259,7 +292,7 @@ int CNetBase::UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct
|
|||
}
|
||||
|
||||
|
||||
void CNetBase::SendControlMsg(NETSOCKET Socket, NETADDR *pAddr, int Ack, int ControlMsg, const void *pExtra, int ExtraSize, SECURITY_TOKEN SecurityToken)
|
||||
void CNetBase::SendControlMsg(NETSOCKET Socket, NETADDR *pAddr, int Ack, int ControlMsg, const void *pExtra, int ExtraSize, SECURITY_TOKEN SecurityToken, bool Sixup)
|
||||
{
|
||||
CNetPacketConstruct Construct;
|
||||
Construct.m_Flags = NET_PACKETFLAG_CONTROL;
|
||||
|
@ -270,32 +303,31 @@ void CNetBase::SendControlMsg(NETSOCKET Socket, NETADDR *pAddr, int Ack, int Con
|
|||
mem_copy(&Construct.m_aChunkData[1], pExtra, ExtraSize);
|
||||
|
||||
// send the control message
|
||||
CNetBase::SendPacket(Socket, pAddr, &Construct, SecurityToken);
|
||||
CNetBase::SendPacket(Socket, pAddr, &Construct, SecurityToken, Sixup);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned char *CNetChunkHeader::Pack(unsigned char *pData)
|
||||
unsigned char *CNetChunkHeader::Pack(unsigned char *pData, int split)
|
||||
{
|
||||
pData[0] = ((m_Flags&3)<<6)|((m_Size>>4)&0x3f);
|
||||
pData[1] = (m_Size&0xf);
|
||||
pData[0] = ((m_Flags&3)<<6)|((m_Size>>split)&0x3f);
|
||||
pData[1] = (m_Size&((1<<split)-1));
|
||||
if(m_Flags&NET_CHUNKFLAG_VITAL)
|
||||
{
|
||||
pData[1] |= (m_Sequence>>2)&0xf0;
|
||||
pData[1] |= (m_Sequence>>2)&(~((1<<split)-1));
|
||||
pData[2] = m_Sequence&0xff;
|
||||
return pData + 3;
|
||||
}
|
||||
return pData + 2;
|
||||
}
|
||||
|
||||
unsigned char *CNetChunkHeader::Unpack(unsigned char *pData)
|
||||
unsigned char *CNetChunkHeader::Unpack(unsigned char *pData, int split)
|
||||
{
|
||||
m_Flags = (pData[0]>>6)&3;
|
||||
m_Size = ((pData[0]&0x3f)<<4) | (pData[1]&0xf);
|
||||
m_Size = ((pData[0]&0x3f)<<split) | (pData[1]&((1<<split)-1));
|
||||
m_Sequence = -1;
|
||||
if(m_Flags&NET_CHUNKFLAG_VITAL)
|
||||
{
|
||||
m_Sequence = ((pData[1]&0xf0)<<2) | pData[2];
|
||||
m_Sequence = ((pData[1]&(~((1<<split)-1)))<<2) | pData[2];
|
||||
return pData + 3;
|
||||
}
|
||||
return pData + 2;
|
||||
|
|
|
@ -106,7 +106,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_CON)(int ClientID, void *pUser);
|
||||
typedef int (*NETFUNC_NEWCLIENT)(int ClientID, void *pUser, bool Sixup);
|
||||
typedef int (*NETFUNC_NEWCLIENT_NOAUTH)(int ClientID, void *pUser);
|
||||
typedef int (*NETFUNC_CLIENTREJOIN)(int ClientID, void *pUser);
|
||||
|
||||
|
@ -130,8 +131,8 @@ public:
|
|||
int m_Size;
|
||||
int m_Sequence;
|
||||
|
||||
unsigned char *Pack(unsigned char *pData);
|
||||
unsigned char *Unpack(unsigned char *pData);
|
||||
unsigned char *Pack(unsigned char *pData, int split = 4);
|
||||
unsigned char *Unpack(unsigned char *pData, int split = 4);
|
||||
};
|
||||
|
||||
class CNetChunkResend
|
||||
|
@ -170,7 +171,6 @@ private:
|
|||
unsigned short m_PeerAck;
|
||||
unsigned m_State;
|
||||
|
||||
int m_Token;
|
||||
SECURITY_TOKEN m_SecurityToken;
|
||||
int m_RemoteClosed;
|
||||
bool m_BlockCloseMsg;
|
||||
|
@ -237,9 +237,12 @@ public:
|
|||
void SetTimedOut(const NETADDR *pAddr, int Sequence, int Ack, SECURITY_TOKEN SecurityToken, TStaticRingBuffer<CNetChunkResend, NET_CONN_BUFFERSIZE> *pResendBuffer);
|
||||
|
||||
// anti spoof
|
||||
void DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken);
|
||||
void DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken, SECURITY_TOKEN Token, bool Sixup);
|
||||
void SetUnknownSeq() { m_UnknownSeq = true; }
|
||||
void SetSequence(int Sequence) { m_Sequence = Sequence; }
|
||||
|
||||
bool m_Sixup;
|
||||
SECURITY_TOKEN m_Token;
|
||||
};
|
||||
|
||||
class CConsoleNetConnection
|
||||
|
@ -333,13 +336,14 @@ class CNetServer
|
|||
CNetRecvUnpacker m_RecvUnpacker;
|
||||
|
||||
void OnTokenCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet);
|
||||
void OnSixupCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet, SECURITY_TOKEN Token);
|
||||
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);
|
||||
|
||||
int TryAcceptClient(NETADDR &Addr, SECURITY_TOKEN SecurityToken, bool VanillaAuth=false);
|
||||
int TryAcceptClient(NETADDR &Addr, SECURITY_TOKEN SecurityToken, bool VanillaAuth=false, bool Sixup=false, SECURITY_TOKEN Token=0);
|
||||
int NumClientsWithAddr(NETADDR Addr);
|
||||
bool Connlimit(NETADDR Addr);
|
||||
void SendMsgs(NETADDR &Addr, const CMsgPacker *Msgs[], int num);
|
||||
|
@ -393,14 +397,14 @@ class CNetConsole
|
|||
class CNetBan *m_pNetBan;
|
||||
CSlot m_aSlots[NET_MAX_CONSOLE_CLIENTS];
|
||||
|
||||
NETFUNC_NEWCLIENT m_pfnNewClient;
|
||||
NETFUNC_NEWCLIENT_CON m_pfnNewClient;
|
||||
NETFUNC_DELCLIENT m_pfnDelClient;
|
||||
void *m_UserPtr;
|
||||
|
||||
CNetRecvUnpacker m_RecvUnpacker;
|
||||
|
||||
public:
|
||||
void SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser);
|
||||
void SetCallbacks(NETFUNC_NEWCLIENT_CON pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser);
|
||||
|
||||
//
|
||||
bool Open(NETADDR BindAddr, class CNetBan *pNetBan, int Flags);
|
||||
|
@ -472,11 +476,11 @@ public:
|
|||
static int Compress(const void *pData, int DataSize, void *pOutput, int OutputSize);
|
||||
static int Decompress(const void *pData, int DataSize, void *pOutput, int OutputSize);
|
||||
|
||||
static void SendControlMsg(NETSOCKET Socket, NETADDR *pAddr, int Ack, int ControlMsg, const void *pExtra, int ExtraSize, SECURITY_TOKEN SecurityToken);
|
||||
static void SendControlMsg(NETSOCKET Socket, NETADDR *pAddr, int Ack, int ControlMsg, const void *pExtra, int ExtraSize, SECURITY_TOKEN SecurityToken, bool Sixup = false);
|
||||
static void SendPacketConnless(NETSOCKET Socket, NETADDR *pAddr, const void *pData, int DataSize, bool Extended, unsigned char aExtra[4]);
|
||||
static void SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct *pPacket, SECURITY_TOKEN SecurityToken);
|
||||
static void SendPacket(NETSOCKET Socket, NETADDR *pAddr, CNetPacketConstruct *pPacket, SECURITY_TOKEN SecurityToken, bool Sixup = false);
|
||||
|
||||
static int UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct *pPacket);
|
||||
static int UnpackPacket(unsigned char *pBuffer, int Size, CNetPacketConstruct *pPacket, SECURITY_TOKEN *SecurityToken = 0, bool Sixup = false);
|
||||
|
||||
// The backroom is ack-NET_MAX_SEQUENCE/2. Used for knowing if we acked a packet or not
|
||||
static int IsSeqInBackroom(int Seq, int Ack);
|
||||
|
|
|
@ -31,6 +31,7 @@ void CNetConnection::Reset(bool Rejoin)
|
|||
m_State = NET_CONNSTATE_OFFLINE;
|
||||
m_Token = -1;
|
||||
m_SecurityToken = NET_SECURITY_TOKEN_UNKNOWN;
|
||||
m_Sixup = false;
|
||||
}
|
||||
|
||||
m_LastSendTime = 0;
|
||||
|
@ -93,7 +94,7 @@ int CNetConnection::Flush()
|
|||
|
||||
// send of the packets
|
||||
m_Construct.m_Ack = m_Ack;
|
||||
CNetBase::SendPacket(m_Socket, &m_PeerAddr, &m_Construct, m_SecurityToken);
|
||||
CNetBase::SendPacket(m_Socket, &m_PeerAddr, &m_Construct, m_SecurityToken, m_Sixup);
|
||||
|
||||
// update send times
|
||||
m_LastSendTime = time_get();
|
||||
|
@ -120,7 +121,7 @@ int CNetConnection::QueueChunkEx(int Flags, int DataSize, const void *pData, int
|
|||
Header.m_Size = DataSize;
|
||||
Header.m_Sequence = Sequence;
|
||||
pChunkData = &m_Construct.m_aChunkData[m_Construct.m_DataSize];
|
||||
pChunkData = Header.Pack(pChunkData);
|
||||
pChunkData = Header.Pack(pChunkData, m_Sixup ? 6 : 4);
|
||||
mem_copy(pChunkData, pData, DataSize);
|
||||
pChunkData += DataSize;
|
||||
|
||||
|
@ -165,7 +166,7 @@ void CNetConnection::SendControl(int ControlMsg, const void *pExtra, int ExtraSi
|
|||
{
|
||||
// send the control message
|
||||
m_LastSendTime = time_get();
|
||||
CNetBase::SendControlMsg(m_Socket, &m_PeerAddr, m_Ack, ControlMsg, pExtra, ExtraSize, m_SecurityToken);
|
||||
CNetBase::SendControlMsg(m_Socket, &m_PeerAddr, m_Ack, ControlMsg, pExtra, ExtraSize, m_SecurityToken, m_Sixup);
|
||||
}
|
||||
|
||||
void CNetConnection::ResendChunk(CNetChunkResend *pResend)
|
||||
|
@ -220,7 +221,7 @@ void CNetConnection::Disconnect(const char *pReason)
|
|||
Reset();
|
||||
}
|
||||
|
||||
void CNetConnection::DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken)
|
||||
void CNetConnection::DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken, SECURITY_TOKEN Token, bool Sixup)
|
||||
{
|
||||
Reset();
|
||||
|
||||
|
@ -235,11 +236,13 @@ void CNetConnection::DirectInit(NETADDR &Addr, SECURITY_TOKEN SecurityToken)
|
|||
m_LastUpdateTime = Now;
|
||||
|
||||
m_SecurityToken = SecurityToken;
|
||||
m_Token = Token;
|
||||
m_Sixup = Sixup;
|
||||
}
|
||||
|
||||
int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr, SECURITY_TOKEN SecurityToken)
|
||||
{
|
||||
if (State() != NET_CONNSTATE_OFFLINE && m_SecurityToken != NET_SECURITY_TOKEN_UNKNOWN && m_SecurityToken != NET_SECURITY_TOKEN_UNSUPPORTED)
|
||||
if (!m_Sixup && State() != NET_CONNSTATE_OFFLINE && m_SecurityToken != NET_SECURITY_TOKEN_UNKNOWN && m_SecurityToken != NET_SECURITY_TOKEN_UNSUPPORTED)
|
||||
{
|
||||
// supposed to have a valid token in this packet, check it
|
||||
if (pPacket->m_DataSize < (int)sizeof(m_SecurityToken))
|
||||
|
@ -253,6 +256,9 @@ int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr, SECURITY_
|
|||
}
|
||||
}
|
||||
|
||||
if(m_Sixup && SecurityToken != m_Token)
|
||||
return 0;
|
||||
|
||||
// check if actual ack value is valid(own sequence..latest peer ack)
|
||||
if(m_Sequence >= m_PeerAck)
|
||||
{
|
||||
|
@ -329,7 +335,7 @@ int CNetConnection::Feed(CNetPacketConstruct *pPacket, NETADDR *pAddr, SECURITY_
|
|||
&& pPacket->m_DataSize >= (int)(1 + sizeof(SECURITY_TOKEN_MAGIC) + sizeof(m_SecurityToken))
|
||||
&& !mem_comp(&pPacket->m_aChunkData[1], SECURITY_TOKEN_MAGIC, sizeof(SECURITY_TOKEN_MAGIC)))
|
||||
{
|
||||
m_SecurityToken = SecurityToken;
|
||||
m_SecurityToken = NET_SECURITY_TOKEN_UNSUPPORTED;
|
||||
if(g_Config.m_Debug)
|
||||
dbg_msg("security", "generated token %d", m_SecurityToken);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ bool CNetConsole::Open(NETADDR BindAddr, CNetBan *pNetBan, int Flags)
|
|||
return true;
|
||||
}
|
||||
|
||||
void CNetConsole::SetCallbacks(NETFUNC_NEWCLIENT pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser)
|
||||
void CNetConsole::SetCallbacks(NETFUNC_NEWCLIENT_CON pfnNewClient, NETFUNC_DELCLIENT pfnDelClient, void *pUser)
|
||||
{
|
||||
m_pfnNewClient = pfnNewClient;
|
||||
m_pfnDelClient = pfnDelClient;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "network.h"
|
||||
#include <engine/message.h>
|
||||
#include <engine/shared/protocol.h>
|
||||
#include <game/generated/protocol.h>
|
||||
|
||||
const int DummyMapCrc = 0x6c760ac4;
|
||||
unsigned char g_aDummyMapData[] = {
|
||||
|
@ -41,6 +42,83 @@ unsigned char g_aDummyMapData[] = {
|
|||
0xc2, 0x00, 0x00, 0x38, 0x00, 0x05
|
||||
};
|
||||
|
||||
static unsigned char MsgTypeFromSixup(unsigned char Byte)
|
||||
{
|
||||
unsigned char Six = Byte>>1;
|
||||
unsigned char Msg;
|
||||
if (Byte&1)
|
||||
{
|
||||
if(Six == 1)
|
||||
Msg = NETMSG_INFO;
|
||||
else if(Six >= 18 && Six <= 28)
|
||||
Msg = NETMSG_READY + Six - 18;
|
||||
else
|
||||
{
|
||||
dbg_msg("net", "DROP recv sys %d", Six);
|
||||
return 0;
|
||||
}
|
||||
//dbg_msg("net", "recv sys %d <- %d", Msg, Six);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Six >= 24 && Six <= 27)
|
||||
Msg = NETMSGTYPE_CL_SAY + Six - 24;
|
||||
else if(Six == 28)
|
||||
Msg = NETMSGTYPE_CL_KILL;
|
||||
else if(Six >= 30 && Six <= 32)
|
||||
Msg = NETMSGTYPE_CL_EMOTICON + Six - 30;
|
||||
else
|
||||
{
|
||||
dbg_msg("net", "DROP recv msg %d", Six);
|
||||
return 0;
|
||||
}
|
||||
//dbg_msg("net", "recv msg %d <- %d", Msg, Six);
|
||||
}
|
||||
return (Msg<<1) | (Byte&1);
|
||||
}
|
||||
|
||||
static unsigned char MsgTypeToSixup(unsigned char Byte)
|
||||
{
|
||||
unsigned char Msg = Byte>>1;
|
||||
unsigned char Six;
|
||||
if (Byte&1)
|
||||
{
|
||||
if(Msg >= NETMSG_MAP_CHANGE && Msg <= NETMSG_MAP_DATA)
|
||||
Six = Msg;
|
||||
else if(Msg >= NETMSG_CON_READY && Msg <= NETMSG_INPUTTIMING)
|
||||
Six = Msg + 1;
|
||||
else if(Msg >= NETMSG_AUTH_CHALLANGE && Msg <= NETMSG_AUTH_RESULT)
|
||||
Six = Msg + 4;
|
||||
else if(Msg >= NETMSG_PING && Msg <= NETMSG_ERROR)
|
||||
Six = Msg + 4;
|
||||
else if(Msg > 24)
|
||||
Six = Msg - 24;
|
||||
else
|
||||
{
|
||||
dbg_msg("net", "DROP send sys %d", Msg);
|
||||
return 0;
|
||||
}
|
||||
//dbg_msg("net", "send sys %d -> %d", Msg, Six);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Msg >= NETMSGTYPE_SV_MOTD && Msg <= NETMSGTYPE_SV_CHAT)
|
||||
Six = Msg;
|
||||
else if(Msg == NETMSGTYPE_SV_KILLMSG)
|
||||
Six = Msg + 1;
|
||||
else if(Msg >= NETMSGTYPE_SV_TUNEPARAMS && Msg <= NETMSGTYPE_SV_VOTESTATUS)
|
||||
Six = Msg;
|
||||
else if(Msg > 24)
|
||||
Six = Msg - 24;
|
||||
else
|
||||
{
|
||||
dbg_msg("net", "DROP send msg %d", Msg);
|
||||
return 0;
|
||||
}
|
||||
//dbg_msg("net", "send msg %d -> %d", Msg, Six);
|
||||
}
|
||||
return (Six<<1) | (Byte&1);
|
||||
}
|
||||
|
||||
static SECURITY_TOKEN ToSecurityToken(const unsigned char *pData)
|
||||
{
|
||||
|
@ -214,12 +292,12 @@ bool CNetServer::Connlimit(NETADDR Addr)
|
|||
return false;
|
||||
}
|
||||
|
||||
int CNetServer::TryAcceptClient(NETADDR &Addr, SECURITY_TOKEN SecurityToken, bool VanillaAuth)
|
||||
int CNetServer::TryAcceptClient(NETADDR &Addr, SECURITY_TOKEN SecurityToken, bool VanillaAuth, bool Sixup, SECURITY_TOKEN Token)
|
||||
{
|
||||
if (Connlimit(Addr))
|
||||
{
|
||||
const char Msg[] = "Too many connections in a short time";
|
||||
CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, Msg, sizeof(Msg), SecurityToken);
|
||||
CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, Msg, sizeof(Msg), SecurityToken, Sixup);
|
||||
return -1; // failed to add client
|
||||
}
|
||||
|
||||
|
@ -228,7 +306,7 @@ int CNetServer::TryAcceptClient(NETADDR &Addr, SECURITY_TOKEN SecurityToken, boo
|
|||
{
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf), "Only %d players with the same IP are allowed", m_MaxClientsPerIP);
|
||||
CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, aBuf, str_length(aBuf) + 1, SecurityToken);
|
||||
CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, aBuf, str_length(aBuf) + 1, SecurityToken, Sixup);
|
||||
return -1; // failed to add client
|
||||
}
|
||||
|
||||
|
@ -245,13 +323,13 @@ int CNetServer::TryAcceptClient(NETADDR &Addr, SECURITY_TOKEN SecurityToken, boo
|
|||
if (Slot == -1)
|
||||
{
|
||||
const char FullMsg[] = "This server is full";
|
||||
CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, FullMsg, sizeof(FullMsg), SecurityToken);
|
||||
CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, FullMsg, sizeof(FullMsg), SecurityToken, Sixup);
|
||||
|
||||
return -1; // failed to add client
|
||||
}
|
||||
|
||||
// init connection slot
|
||||
m_aSlots[Slot].m_Connection.DirectInit(Addr, SecurityToken);
|
||||
m_aSlots[Slot].m_Connection.DirectInit(Addr, SecurityToken, Token, Sixup);
|
||||
|
||||
if (VanillaAuth)
|
||||
{
|
||||
|
@ -273,7 +351,7 @@ int CNetServer::TryAcceptClient(NETADDR &Addr, SECURITY_TOKEN SecurityToken, boo
|
|||
if (VanillaAuth)
|
||||
m_pfnNewClientNoAuth(Slot, m_UserPtr);
|
||||
else
|
||||
m_pfnNewClient(Slot, m_UserPtr);
|
||||
m_pfnNewClient(Slot, m_UserPtr, Sixup);
|
||||
|
||||
return Slot; // done
|
||||
}
|
||||
|
@ -546,6 +624,30 @@ void CNetServer::OnTokenCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketC
|
|||
}
|
||||
}
|
||||
|
||||
void CNetServer::OnSixupCtrlMsg(NETADDR &Addr, int ControlMsg, const CNetPacketConstruct &Packet, SECURITY_TOKEN Token)
|
||||
{
|
||||
if(ClientExists(Addr))
|
||||
return; // silently ignore
|
||||
|
||||
SECURITY_TOKEN ResponseToken;
|
||||
mem_copy(&ResponseToken, Packet.m_aChunkData+1, 4);
|
||||
|
||||
SECURITY_TOKEN MyToken = GetToken(Addr);
|
||||
unsigned char aToken[4];
|
||||
mem_copy(aToken, &MyToken, 4);
|
||||
|
||||
if(ControlMsg == 5)
|
||||
{
|
||||
CNetBase::SendControlMsg(m_Socket, &Addr, 0, 5, aToken, sizeof(aToken), ResponseToken, true);
|
||||
}
|
||||
else if(ControlMsg == NET_CTRLMSG_CONNECT)
|
||||
{
|
||||
CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CONNECTACCEPT, aToken, sizeof(aToken), ResponseToken, true);
|
||||
if(Token == MyToken)
|
||||
TryAcceptClient(Addr, ResponseToken, false, true, Token);
|
||||
}
|
||||
}
|
||||
|
||||
int CNetServer::GetClientSlot(const NETADDR &Addr)
|
||||
{
|
||||
int Slot = -1;
|
||||
|
@ -598,7 +700,11 @@ int CNetServer::Recv(CNetChunk *pChunk)
|
|||
|
||||
// check for a chunk
|
||||
if(m_RecvUnpacker.FetchChunk(pChunk))
|
||||
{
|
||||
if(m_aSlots[pChunk->m_ClientID].m_Connection.m_Sixup)
|
||||
*(unsigned char*)pChunk->m_pData = MsgTypeFromSixup(*(unsigned char*)pChunk->m_pData);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO: empty the recvinfo
|
||||
unsigned char *pData;
|
||||
|
@ -643,6 +749,16 @@ int CNetServer::Recv(CNetChunk *pChunk)
|
|||
// normal packet, find matching slot
|
||||
int Slot = GetClientSlot(Addr);
|
||||
|
||||
bool Sixup = false;
|
||||
SECURITY_TOKEN Token;
|
||||
if((Slot == -1 && m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_UNUSED)
|
||||
|| (Slot != -1 && m_aSlots[Slot].m_Connection.m_Sixup))
|
||||
{
|
||||
Sixup = true;
|
||||
if(CNetBase::UnpackPacket(m_RecvUnpacker.m_aBuffer, Bytes, &m_RecvUnpacker.m_Data, &Token, Sixup))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Slot != -1)
|
||||
{
|
||||
// found
|
||||
|
@ -651,7 +767,7 @@ int CNetServer::Recv(CNetChunk *pChunk)
|
|||
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_aSlots[Slot].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr, Token))
|
||||
{
|
||||
if(m_RecvUnpacker.m_Data.m_DataSize)
|
||||
m_RecvUnpacker.Start(&Addr, &m_aSlots[Slot].m_Connection, Slot);
|
||||
|
@ -661,7 +777,10 @@ int CNetServer::Recv(CNetChunk *pChunk)
|
|||
{
|
||||
// not found, client that wants to connect
|
||||
|
||||
if(IsDDNetControlMsg(&m_RecvUnpacker.m_Data))
|
||||
if(Sixup)
|
||||
// got 0.7 control msg
|
||||
OnSixupCtrlMsg(Addr, m_RecvUnpacker.m_Data.m_aChunkData[0], m_RecvUnpacker.m_Data, Token);
|
||||
else if(IsDDNetControlMsg(&m_RecvUnpacker.m_Data))
|
||||
// got ddnet control msg
|
||||
OnTokenCtrlMsg(Addr, m_RecvUnpacker.m_Data.m_aChunkData[0], m_RecvUnpacker.m_Data);
|
||||
else
|
||||
|
@ -694,6 +813,13 @@ int CNetServer::Send(CNetChunk *pChunk)
|
|||
dbg_assert(pChunk->m_ClientID >= 0, "errornous client id");
|
||||
dbg_assert(pChunk->m_ClientID < MaxClients(), "errornous client id");
|
||||
|
||||
if(m_aSlots[pChunk->m_ClientID].m_Connection.m_Sixup)
|
||||
{
|
||||
unsigned int MsgType = MsgTypeToSixup(*(unsigned char*)pChunk->m_pData);
|
||||
if (MsgType == 0) return 0;
|
||||
*(unsigned char*)pChunk->m_pData = MsgType;
|
||||
}
|
||||
|
||||
if(pChunk->m_Flags&NETSENDFLAG_VITAL)
|
||||
Flags = NET_CHUNKFLAG_VITAL;
|
||||
|
||||
|
|
|
@ -4,6 +4,30 @@
|
|||
#include "compression.h"
|
||||
#include "uuid_manager.h"
|
||||
|
||||
#include <game/generated/protocol.h>
|
||||
|
||||
static int ObjTypeToSixup(int Type)
|
||||
{
|
||||
int Six;
|
||||
if(Type >= NETOBJTYPE_PLAYERINPUT && Type <= NETOBJTYPE_FLAG)
|
||||
Six = Type;
|
||||
else if(Type >= NETOBJTYPE_CHARACTERCORE && Type <= NETOBJTYPE_PLAYERINFO)
|
||||
Six = Type + 1;
|
||||
else if(Type >= NETEVENTTYPE_COMMON && Type <= NETEVENTTYPE_DEATH)
|
||||
Six = Type + 3;
|
||||
else if(Type == NETEVENTTYPE_SOUNDWORLD)
|
||||
Six = Type + 2;
|
||||
else if(Type > 24)
|
||||
Six = Type - 24;
|
||||
else
|
||||
{
|
||||
//dbg_msg("net", "DROP obj %d", Type);
|
||||
return -1;
|
||||
}
|
||||
//dbg_msg("net", "pack obj %d -> %d", Type, Six);
|
||||
return Six;
|
||||
}
|
||||
|
||||
// CSnapshot
|
||||
|
||||
CSnapshotItem *CSnapshot::GetItem(int Index)
|
||||
|
@ -529,10 +553,11 @@ CSnapshotBuilder::CSnapshotBuilder()
|
|||
m_NumExtendedItemTypes = 0;
|
||||
}
|
||||
|
||||
void CSnapshotBuilder::Init()
|
||||
void CSnapshotBuilder::Init(bool Sixup)
|
||||
{
|
||||
m_DataSize = 0;
|
||||
m_NumItems = 0;
|
||||
m_Sixup = Sixup;
|
||||
|
||||
for(int i = 0; i < m_NumExtendedItemTypes; i++)
|
||||
{
|
||||
|
@ -622,6 +647,12 @@ void *CSnapshotBuilder::NewItem(int Type, int ID, int Size)
|
|||
|
||||
CSnapshotItem *pObj = (CSnapshotItem *)(m_aData + m_DataSize);
|
||||
|
||||
if(m_Sixup)
|
||||
{
|
||||
Type = ObjTypeToSixup(Type);
|
||||
if(Type < 0) return pObj;
|
||||
}
|
||||
|
||||
mem_zero(pObj, sizeof(CSnapshotItem) + Size);
|
||||
pObj->m_TypeAndID = (Type<<16)|ID;
|
||||
m_aOffsets[m_NumItems] = m_DataSize;
|
||||
|
|
|
@ -139,10 +139,12 @@ class CSnapshotBuilder
|
|||
void AddExtendedItemType(int Index);
|
||||
int GetExtendedItemTypeIndex(int TypeID);
|
||||
|
||||
bool m_Sixup;
|
||||
|
||||
public:
|
||||
CSnapshotBuilder();
|
||||
|
||||
void Init();
|
||||
void Init(bool Sixup = false);
|
||||
|
||||
void *NewItem(int Type, int ID, int Size);
|
||||
|
||||
|
|
|
@ -1241,6 +1241,18 @@ void CCharacter::Snap(int SnappingClient)
|
|||
pDDNetCharacter->m_Jumps = m_Core.m_Jumps;
|
||||
pDDNetCharacter->m_TeleCheckpoint = m_TeleCheckpoint;
|
||||
pDDNetCharacter->m_StrongWeakID = m_StrongWeakID;
|
||||
|
||||
if(Server()->IsSixup(SnappingClient))
|
||||
{
|
||||
int Offset = sizeof(CNetObj_CharacterCore) / 4;
|
||||
((int*)pCharacter)[Offset+0] = pCharacter->m_Health;
|
||||
((int*)pCharacter)[Offset+1] = pCharacter->m_Armor;
|
||||
((int*)pCharacter)[Offset+2] = pCharacter->m_AmmoCount;
|
||||
((int*)pCharacter)[Offset+3] = pCharacter->m_Weapon;
|
||||
((int*)pCharacter)[Offset+4] = pCharacter->m_Emote;
|
||||
((int*)pCharacter)[Offset+5] = pCharacter->m_AttackTick;
|
||||
((int*)pCharacter)[Offset+6] = 0; // m_TriggeredEvents
|
||||
}
|
||||
}
|
||||
|
||||
int CCharacter::NetworkClipped(int SnappingClient)
|
||||
|
|
|
@ -162,14 +162,23 @@ void CPickup::Snap(int SnappingClient)
|
|||
&& (!Tick))
|
||||
return;
|
||||
|
||||
CNetObj_Pickup *pP = static_cast<CNetObj_Pickup *>(Server()->SnapNewItem(NETOBJTYPE_PICKUP, m_ID, sizeof(CNetObj_Pickup)));
|
||||
int Size = Server()->IsSixup(SnappingClient) ? 3*4 : sizeof(CNetObj_Pickup);
|
||||
CNetObj_Pickup *pP = static_cast<CNetObj_Pickup *>(Server()->SnapNewItem(NETOBJTYPE_PICKUP, m_ID, Size));
|
||||
if(!pP)
|
||||
return;
|
||||
|
||||
pP->m_X = (int)m_Pos.x;
|
||||
pP->m_Y = (int)m_Pos.y;
|
||||
pP->m_Type = m_Type;
|
||||
pP->m_Subtype = m_Subtype;
|
||||
if(Server()->IsSixup(SnappingClient))
|
||||
{
|
||||
if(m_Type == POWERUP_WEAPON)
|
||||
pP->m_Type = m_Subtype == WEAPON_SHOTGUN ? 3 : m_Subtype == WEAPON_GRENADE ? 2 : 4;
|
||||
else if(m_Type == POWERUP_NINJA)
|
||||
pP->m_Type = 5;
|
||||
}
|
||||
else
|
||||
pP->m_Subtype = m_Subtype;
|
||||
}
|
||||
|
||||
void CPickup::Move()
|
||||
|
|
|
@ -1109,6 +1109,72 @@ void CGameContext::OnClientEnter(int ClientID)
|
|||
SendVoteSet(ClientID);
|
||||
|
||||
Server()->ExpireServerInfo();
|
||||
|
||||
// update client infos (others before local)
|
||||
CMsgPacker NewClientInfoMsg(18 + 24);
|
||||
NewClientInfoMsg.AddInt(ClientID);
|
||||
NewClientInfoMsg.AddInt(0); // m_Local
|
||||
NewClientInfoMsg.AddInt(m_apPlayers[ClientID]->GetTeam());
|
||||
NewClientInfoMsg.AddString(Server()->ClientName(ClientID), -1);
|
||||
NewClientInfoMsg.AddString(Server()->ClientClan(ClientID), -1);
|
||||
NewClientInfoMsg.AddInt(Server()->ClientCountry(ClientID));
|
||||
for(int p = 0; p < 6; p++)
|
||||
{
|
||||
NewClientInfoMsg.AddString("", -1); // m_apSkinPartNames
|
||||
NewClientInfoMsg.AddInt(0); // m_aUseCustomColors
|
||||
NewClientInfoMsg.AddInt(0); // m_aSkinPartColors
|
||||
}
|
||||
NewClientInfoMsg.AddInt(0); // m_Silent
|
||||
|
||||
for(int i = 0; i < MAX_CLIENTS; ++i)
|
||||
{
|
||||
if(i == ClientID || !m_apPlayers[i] || !Server()->ClientIngame(i))
|
||||
continue;
|
||||
|
||||
// new info for others
|
||||
if(Server()->ClientIngame(i) && Server()->IsSixup(i))
|
||||
Server()->SendMsg(&NewClientInfoMsg, MSGFLAG_VITAL|MSGFLAG_NORECORD, i);
|
||||
|
||||
if(Server()->IsSixup(ClientID))
|
||||
{
|
||||
// existing infos for new player
|
||||
CMsgPacker ClientInfoMsg(18 + 24);
|
||||
ClientInfoMsg.AddInt(i);
|
||||
ClientInfoMsg.AddInt(0); // m_Local
|
||||
ClientInfoMsg.AddInt(m_apPlayers[i]->GetTeam());
|
||||
ClientInfoMsg.AddString(Server()->ClientName(i), -1);
|
||||
ClientInfoMsg.AddString(Server()->ClientClan(i), -1);
|
||||
ClientInfoMsg.AddInt(Server()->ClientCountry(i));
|
||||
for(int p = 0; p < 6; p++)
|
||||
{
|
||||
ClientInfoMsg.AddString("", -1); // m_apSkinPartNames
|
||||
ClientInfoMsg.AddInt(0); // m_aUseCustomColors
|
||||
ClientInfoMsg.AddInt(0); // m_aSkinPartColors
|
||||
}
|
||||
ClientInfoMsg.AddInt(0); // m_Silent
|
||||
Server()->SendMsg(&ClientInfoMsg, MSGFLAG_VITAL|MSGFLAG_NORECORD, ClientID);
|
||||
}
|
||||
}
|
||||
|
||||
// local info
|
||||
if(Server()->IsSixup(ClientID))
|
||||
{
|
||||
CMsgPacker SelfClientInfoMsg(18 + 24);
|
||||
SelfClientInfoMsg.AddInt(ClientID);
|
||||
SelfClientInfoMsg.AddInt(1); // m_Local
|
||||
SelfClientInfoMsg.AddInt(m_apPlayers[ClientID]->GetTeam());
|
||||
SelfClientInfoMsg.AddString(Server()->ClientName(ClientID), -1);
|
||||
SelfClientInfoMsg.AddString(Server()->ClientClan(ClientID), -1);
|
||||
SelfClientInfoMsg.AddInt(Server()->ClientCountry(ClientID));
|
||||
for(int p = 0; p < 6; p++)
|
||||
{
|
||||
SelfClientInfoMsg.AddString("", -1); // m_apSkinPartNames
|
||||
SelfClientInfoMsg.AddInt(0); // m_aUseCustomColors
|
||||
SelfClientInfoMsg.AddInt(0); // m_aSkinPartColors
|
||||
}
|
||||
SelfClientInfoMsg.AddInt(0); // m_Silent
|
||||
Server()->SendMsg(&SelfClientInfoMsg, MSGFLAG_VITAL|MSGFLAG_NORECORD, ClientID);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameContext::OnClientConnected(int ClientID)
|
||||
|
@ -1252,23 +1318,22 @@ void CGameContext::OnClientDDNetVersionKnown(int ClientID)
|
|||
|
||||
void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
|
||||
{
|
||||
void *pRawMsg = m_NetObjHandler.SecureUnpackMsg(MsgID, pUnpacker);
|
||||
void *pRawMsg = 0;
|
||||
CPlayer *pPlayer = m_apPlayers[ClientID];
|
||||
|
||||
if(m_TeeHistorianActive)
|
||||
if(MsgID != NETMSGTYPE_CL_STARTINFO)
|
||||
{
|
||||
if(m_NetObjHandler.TeeHistorianRecordMsg(MsgID))
|
||||
{
|
||||
m_TeeHistorian.RecordPlayerMessage(ClientID, pUnpacker->CompleteData(), pUnpacker->CompleteSize());
|
||||
}
|
||||
}
|
||||
pRawMsg = m_NetObjHandler.SecureUnpackMsg(MsgID, pUnpacker);
|
||||
if(!pRawMsg)
|
||||
return;
|
||||
|
||||
if(!pRawMsg)
|
||||
{
|
||||
//char aBuf[256];
|
||||
//str_format(aBuf, sizeof(aBuf), "dropped weird message '%s' (%d), failed on '%s'", m_NetObjHandler.GetMsgName(MsgID), MsgID, m_NetObjHandler.FailedMsgOn());
|
||||
//Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf);
|
||||
return;
|
||||
if(m_TeeHistorianActive)
|
||||
{
|
||||
if(m_NetObjHandler.TeeHistorianRecordMsg(MsgID))
|
||||
{
|
||||
m_TeeHistorian.RecordPlayerMessage(ClientID, pUnpacker->CompleteData(), pUnpacker->CompleteSize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(Server()->ClientIngame(ClientID))
|
||||
|
@ -1887,7 +1952,37 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
|
|||
if(pPlayer->m_IsReady)
|
||||
return;
|
||||
|
||||
CNetMsg_Cl_StartInfo *pMsg = (CNetMsg_Cl_StartInfo *)pRawMsg;
|
||||
CNetMsg_Cl_StartInfo Msg;
|
||||
const char *apSkinPartNames[6];
|
||||
int aUseCustomColors[6];
|
||||
int aSkinPartColors[6];
|
||||
|
||||
Msg.m_pName = pUnpacker->GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES);
|
||||
Msg.m_pClan = pUnpacker->GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES);
|
||||
Msg.m_Country = pUnpacker->GetInt();
|
||||
if(Server()->IsSixup(ClientID))
|
||||
{
|
||||
for(int p = 0; p < 6; p++) apSkinPartNames[p] = pUnpacker->GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES);
|
||||
for(int p = 0; p < 6; p++) aUseCustomColors[p] = pUnpacker->GetInt();
|
||||
for(int p = 0; p < 6; p++) aSkinPartColors[p] = pUnpacker->GetInt();
|
||||
Msg.m_pSkin = "default";
|
||||
Msg.m_UseCustomColor = 0;
|
||||
Msg.m_ColorBody = 0;
|
||||
Msg.m_ColorFeet = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg.m_pSkin = pUnpacker->GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES);
|
||||
Msg.m_UseCustomColor = pUnpacker->GetInt();
|
||||
Msg.m_ColorBody = pUnpacker->GetInt();
|
||||
Msg.m_ColorFeet = pUnpacker->GetInt();
|
||||
}
|
||||
|
||||
if(pUnpacker->Error())
|
||||
return;
|
||||
|
||||
CNetMsg_Cl_StartInfo *pMsg = &Msg;
|
||||
|
||||
if(!str_utf8_check(pMsg->m_pName)
|
||||
|| !str_utf8_check(pMsg->m_pClan)
|
||||
|| !str_utf8_check(pMsg->m_pSkin))
|
||||
|
|
|
@ -558,6 +558,19 @@ void IGameController::Snap(int SnappingClient)
|
|||
| GAMEINFOFLAG_ENTITIES_RACE
|
||||
| GAMEINFOFLAG_RACE;
|
||||
pGameInfoEx->m_Version = GAMEINFO_CURVERSION;
|
||||
|
||||
if(Server()->IsSixup(SnappingClient))
|
||||
{
|
||||
int *pGameData = (int*)Server()->SnapNewItem(6 + 24, 0, 3*4); // NETOBJTYPE_GAMEDATA
|
||||
if(!pGameData)
|
||||
return;
|
||||
|
||||
pGameData[0] = m_RoundStartTick;
|
||||
pGameData[1] = 0; // m_GameStateFlags
|
||||
pGameData[2] = 0; // m_GameStateEndTick
|
||||
}
|
||||
|
||||
SnapFlags(SnappingClient);
|
||||
}
|
||||
|
||||
int IGameController::GetAutoTeam(int NotThisID)
|
||||
|
|
|
@ -317,24 +317,38 @@ void CPlayer::Snap(int SnappingClient)
|
|||
pClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody;
|
||||
pClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet;
|
||||
|
||||
CNetObj_PlayerInfo *pPlayerInfo = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, id, sizeof(CNetObj_PlayerInfo)));
|
||||
int Size = Server()->IsSixup(SnappingClient) ? 3*4 : sizeof(CNetObj_PlayerInfo);
|
||||
CNetObj_PlayerInfo *pPlayerInfo = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, id, Size));
|
||||
if(!pPlayerInfo)
|
||||
return;
|
||||
|
||||
int ClientVersion = GetClientVersion();
|
||||
pPlayerInfo->m_Latency = SnappingClient == -1 ? m_Latency.m_Min : GameServer()->m_apPlayers[SnappingClient]->m_aActLatency[m_ClientID];
|
||||
pPlayerInfo->m_Local = (int)(m_ClientID == SnappingClient && (m_Paused != PAUSE_PAUSED || ClientVersion >= VERSION_DDNET_OLD));
|
||||
pPlayerInfo->m_ClientID = id;
|
||||
pPlayerInfo->m_Team = (ClientVersion < VERSION_DDNET_OLD || m_Paused != PAUSE_PAUSED || m_ClientID != SnappingClient) && m_Paused < PAUSE_SPEC ? m_Team : TEAM_SPECTATORS;
|
||||
|
||||
if(m_ClientID == SnappingClient && m_Paused == PAUSE_PAUSED && ClientVersion < VERSION_DDNET_OLD)
|
||||
pPlayerInfo->m_Team = TEAM_SPECTATORS;
|
||||
int Latency = SnappingClient == -1 ? m_Latency.m_Min : GameServer()->m_apPlayers[SnappingClient]->m_aActLatency[m_ClientID];
|
||||
int Score = abs(m_Score) * -1;
|
||||
|
||||
// send 0 if times of others are not shown
|
||||
if(SnappingClient != m_ClientID && g_Config.m_SvHideScore)
|
||||
pPlayerInfo->m_Score = -9999;
|
||||
Score = -9999;
|
||||
else
|
||||
pPlayerInfo->m_Score = abs(m_Score) * -1;
|
||||
Score = abs(m_Score) * -1;
|
||||
|
||||
if(!Server()->IsSixup(SnappingClient))
|
||||
{
|
||||
pPlayerInfo->m_Latency = Latency;
|
||||
pPlayerInfo->m_Score = Score;
|
||||
pPlayerInfo->m_Local = (int)(m_ClientID == SnappingClient && (m_Paused != PAUSE_PAUSED || ClientVersion >= VERSION_DDNET_OLD));
|
||||
pPlayerInfo->m_ClientID = id;
|
||||
pPlayerInfo->m_Team = (ClientVersion < VERSION_DDNET_OLD || m_Paused != PAUSE_PAUSED || m_ClientID != SnappingClient) && m_Paused < PAUSE_SPEC ? m_Team : TEAM_SPECTATORS;
|
||||
|
||||
if(m_ClientID == SnappingClient && m_Paused == PAUSE_PAUSED && ClientVersion < VERSION_DDNET_OLD)
|
||||
pPlayerInfo->m_Team = TEAM_SPECTATORS;
|
||||
}
|
||||
else
|
||||
{
|
||||
((int*)pPlayerInfo)[0] = 0; // m_PlayerFlags
|
||||
((int*)pPlayerInfo)[1] = Score;
|
||||
((int*)pPlayerInfo)[2] = Latency;
|
||||
}
|
||||
|
||||
if(m_ClientID == SnappingClient && (m_Team == TEAM_SPECTATORS || m_Paused))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue