mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #1772
1772: Remove all checking for the gametype in the game r=Learath2 a=heinrich5991 OK, maybe not actually remove because it is kept for fallback when the new method isn't available. The whole gametype parsing business had the same downsides as user agent parsing on the web, hence I removed it while keeping behavior the same. This allows servers to explicitly opt in or out of certain bug workarounds and other client behavior. This increases the complexity of different configurations that are available in the client (which is a bad thing). Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
This commit is contained in:
commit
f7861563e2
|
@ -198,7 +198,7 @@ class Flags:
|
|||
self.values = values
|
||||
|
||||
class NetObject:
|
||||
def __init__(self, name, variables, ex=None):
|
||||
def __init__(self, name, variables, ex=None, validate_size=True):
|
||||
l = name.split(":")
|
||||
self.name = l[0]
|
||||
self.base = ""
|
||||
|
@ -209,6 +209,7 @@ class NetObject:
|
|||
self.enum_name = "NETOBJTYPE_%s" % self.name.upper()
|
||||
self.variables = variables
|
||||
self.ex = ex
|
||||
self.validate_size = validate_size
|
||||
def emit_declaration(self):
|
||||
if self.base:
|
||||
lines = ["struct %s : public %s"%(self.struct_name,self.base_struct_name), "{"]
|
||||
|
@ -221,10 +222,14 @@ class NetObject:
|
|||
def emit_validate(self):
|
||||
lines = ["case %s:" % self.enum_name]
|
||||
lines += ["{"]
|
||||
lines += ["\t%s *pObj = (%s *)pData;"%(self.struct_name, self.struct_name)]
|
||||
lines += ["\tif((int)sizeof(*pObj) > Size) return -1;"]
|
||||
if self.validate_size:
|
||||
lines += ["\t%s *pObj = (%s *)pData;"%(self.struct_name, self.struct_name)]
|
||||
lines += ["\tif((int)sizeof(*pObj) > Size) return -1;"]
|
||||
prev_len = len(lines)
|
||||
for v in self.variables:
|
||||
lines += ["\t"+line for line in v.emit_validate()]
|
||||
if not self.validate_size and prev_len != len(lines):
|
||||
raise ValueError("Can't use members that need validation in a struct whose size isn't validated")
|
||||
lines += ["\treturn 0;"]
|
||||
lines += ["}"]
|
||||
return lines
|
||||
|
@ -273,8 +278,8 @@ class NetMessage(NetObject):
|
|||
return lines
|
||||
|
||||
class NetObjectEx(NetObject):
|
||||
def __init__(self, name, ex, variables):
|
||||
NetObject.__init__(self, name, variables, ex=ex)
|
||||
def __init__(self, name, ex, variables, validate_size=True):
|
||||
NetObject.__init__(self, name, variables, ex=ex, validate_size=validate_size)
|
||||
|
||||
class NetEventEx(NetEvent):
|
||||
def __init__(self, name, ex, variables):
|
||||
|
|
|
@ -5,10 +5,20 @@ PlayerFlags = ["PLAYING", "IN_MENU", "CHATTING", "SCOREBOARD", "AIM"]
|
|||
GameFlags = ["TEAMS", "FLAGS"]
|
||||
GameStateFlags = ["GAMEOVER", "SUDDENDEATH", "PAUSED", "RACETIME"]
|
||||
CharacterFlags = ["SOLO", "JETPACK", "NO_COLLISION", "ENDLESS_HOOK", "ENDLESS_JUMP", "SUPER",
|
||||
"NO_HAMMER_HIT", "NO_SHOTGUN_HIT", "NO_GRENADE_HIT", "NO_RIFLE_HIT", "NO_HOOK",
|
||||
"TELEGUN_GUN", "TELEGUN_GRENADE", "TELEGUN_LASER",
|
||||
"WEAPON_HAMMER", "WEAPON_GUN", "WEAPON_SHOTGUN", "WEAPON_GRENADE", "WEAPON_LASER", "WEAPON_NINJA"]
|
||||
GameInfoFlags = ["TIMESCORE"]
|
||||
"NO_HAMMER_HIT", "NO_SHOTGUN_HIT", "NO_GRENADE_HIT", "NO_RIFLE_HIT", "NO_HOOK",
|
||||
"TELEGUN_GUN", "TELEGUN_GRENADE", "TELEGUN_LASER",
|
||||
"WEAPON_HAMMER", "WEAPON_GUN", "WEAPON_SHOTGUN", "WEAPON_GRENADE", "WEAPON_LASER", "WEAPON_NINJA"]
|
||||
GameInfoFlags = [
|
||||
"TIMESCORE", "GAMETYPE_RACE", "GAMETYPE_FASTCAP", "GAMETYPE_FNG",
|
||||
"GAMETYPE_DDRACE", "GAMETYPE_DDNET", "GAMETYPE_BLOCK_WORLDS",
|
||||
"GAMETYPE_VANILLA", "GAMETYPE_PLUS", "FLAG_STARTS_RACE", "RACE",
|
||||
"UNLIMITED_AMMO", "DDRACE_RECORD_MESSAGE", "RACE_RECORD_MESSAGE",
|
||||
"ALLOW_EYE_WHEEL", "ALLOW_HOOK_COLL", "ALLOW_ZOOM", "BUG_DDRACE_GHOST",
|
||||
"BUG_DDRACE_INPUT", "BUG_FNG_LASER_RANGE", "BUG_VANILLA_BOUNCE",
|
||||
"PREDICT_FNG", "PREDICT_DDRACE", "PREDICT_DDRACE_TILES", "PREDICT_VANILLA",
|
||||
"ENTITIES_DDNET", "ENTITIES_DDRACE", "ENTITIES_RACE", "ENTITIES_FNG",
|
||||
"ENTITIES_VANILLA",
|
||||
]
|
||||
|
||||
Emoticons = ["OOP", "EXCLAMATION", "HEARTS", "DROP", "DOTDOT", "MUSIC", "SORRY", "GHOST", "SUSHI", "SPLATTEE", "DEVILTEE", "ZOMG", "ZZZ", "WTF", "EYES", "QUESTION"]
|
||||
|
||||
|
@ -38,6 +48,11 @@ enum
|
|||
SPEC_FREEVIEW=-1,
|
||||
SPEC_FOLLOW=-2,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GAMEINFO_CURVERSION=2,
|
||||
};
|
||||
'''
|
||||
|
||||
RawSource = '''
|
||||
|
@ -216,9 +231,10 @@ Objects = [
|
|||
NetIntRange("m_AuthLevel", "AUTHED_NO", "AUTHED_ADMIN"),
|
||||
]),
|
||||
|
||||
NetObjectEx("DDNetGameInfo", "gameinfo@netobj.ddnet.tw", [
|
||||
NetObjectEx("GameInfoEx", "gameinfo@netobj.ddnet.tw", [
|
||||
NetIntAny("m_Flags"),
|
||||
]),
|
||||
NetIntAny("m_Version"),
|
||||
], validate_size=False),
|
||||
|
||||
## Events
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@ public:
|
|||
virtual int SnapNumItems(int SnapID) = 0;
|
||||
virtual void *SnapFindItem(int SnapID, int Type, int ID) = 0;
|
||||
virtual void *SnapGetItem(int SnapID, int Index, CSnapItem *pItem) = 0;
|
||||
virtual int SnapItemSize(int SnapID, int Index) = 0;
|
||||
virtual void SnapInvalidateItem(int SnapID, int Index) = 0;
|
||||
|
||||
virtual void SnapSetStaticsize(int ItemType, int Size) = 0;
|
||||
|
|
|
@ -740,6 +740,8 @@ void CClient::DisconnectWithReason(const char *pReason)
|
|||
|
||||
//
|
||||
m_RconAuthed[0] = 0;
|
||||
m_CanReceiveServerCapabilities = true;
|
||||
m_ServerSentCapabilities = false;
|
||||
m_UseTempRconCommands = 0;
|
||||
m_pConsole->DeregisterTempAll();
|
||||
m_NetClient[0].Disconnect(pReason);
|
||||
|
@ -899,6 +901,12 @@ void *CClient::SnapGetItem(int SnapID, int Index, CSnapItem *pItem)
|
|||
return (void *)i->Data();
|
||||
}
|
||||
|
||||
int CClient::SnapItemSize(int SnapID, int Index)
|
||||
{
|
||||
dbg_assert(SnapID >= 0 && SnapID < NUM_SNAPSHOT_TYPES, "invalid SnapID");
|
||||
return m_aSnapshots[g_Config.m_ClDummy][SnapID]->m_pAltSnap->GetItemSize(Index);
|
||||
}
|
||||
|
||||
void CClient::SnapInvalidateItem(int SnapID, int Index)
|
||||
{
|
||||
CSnapshotItem *i;
|
||||
|
@ -1480,6 +1488,15 @@ void CClient::ProcessServerInfo(int RawType, NETADDR *pFrom, const void *pData,
|
|||
#undef GET_INT
|
||||
}
|
||||
|
||||
bool CClient::ShouldSendChatTimeoutCodeHeuristic()
|
||||
{
|
||||
if(m_ServerSentCapabilities)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return IsDDNet(&m_CurrentServerInfo);
|
||||
}
|
||||
|
||||
static void FormatMapDownloadFilename(const char *pName, SHA256_DIGEST *pSha256, int Crc, bool Temp, char *pBuffer, int BufferSize)
|
||||
{
|
||||
char aSha256[SHA256_MAXSTRSIZE + 1];
|
||||
|
@ -1497,6 +1514,22 @@ static void FormatMapDownloadFilename(const char *pName, SHA256_DIGEST *pSha256,
|
|||
Temp ? ".tmp" : "");
|
||||
}
|
||||
|
||||
static CServerCapabilities GetServerCapabilities(int Version, int Flags)
|
||||
{
|
||||
CServerCapabilities Result;
|
||||
bool DDNet = false;
|
||||
if(Version >= 1)
|
||||
{
|
||||
DDNet = Flags&SERVERCAPFLAG_DDNET;
|
||||
}
|
||||
Result.m_ChatTimeoutCode = DDNet;
|
||||
if(Version >= 1)
|
||||
{
|
||||
Result.m_ChatTimeoutCode = Flags&SERVERCAPFLAG_CHATTIMEOUTCODE;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
void CClient::ProcessServerPacket(CNetChunk *pPacket)
|
||||
{
|
||||
CUnpacker Unpacker;
|
||||
|
@ -1537,8 +1570,29 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
|
|||
m_MapDetailsSha256 = *pMapSha256;
|
||||
m_MapDetailsCrc = MapCrc;
|
||||
}
|
||||
else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_CAPABILITIES)
|
||||
{
|
||||
if(!m_CanReceiveServerCapabilities)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int Version = Unpacker.GetInt();
|
||||
int Flags = Unpacker.GetInt();
|
||||
if(Version <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_ServerCapabilities = GetServerCapabilities(Version, Flags);
|
||||
m_CanReceiveServerCapabilities = false;
|
||||
m_ServerSentCapabilities = true;
|
||||
}
|
||||
else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAP_CHANGE)
|
||||
{
|
||||
if(m_CanReceiveServerCapabilities)
|
||||
{
|
||||
m_ServerCapabilities = GetServerCapabilities(0, 0);
|
||||
m_CanReceiveServerCapabilities = false;
|
||||
}
|
||||
bool MapDetailsWerePresent = m_MapDetailsPresent;
|
||||
m_MapDetailsPresent = false;
|
||||
|
||||
|
@ -1923,7 +1977,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
|
|||
|
||||
if(m_ReceivedSnapshots[g_Config.m_ClDummy] > 50 && !m_aTimeoutCodeSent[g_Config.m_ClDummy])
|
||||
{
|
||||
if(IsDDNet(&m_CurrentServerInfo))
|
||||
if(m_ServerCapabilities.m_ChatTimeoutCode || ShouldSendChatTimeoutCodeHeuristic())
|
||||
{
|
||||
m_aTimeoutCodeSent[g_Config.m_ClDummy] = true;
|
||||
CNetMsg_Cl_Say Msg;
|
||||
|
|
|
@ -55,6 +55,12 @@ public:
|
|||
void Update(CGraph *pGraph, int64 Target, int TimeLeft, int AdjustDirection);
|
||||
};
|
||||
|
||||
class CServerCapabilities
|
||||
{
|
||||
public:
|
||||
bool m_ChatTimeoutCode;
|
||||
};
|
||||
|
||||
class CClient : public IClient, public CDemoPlayer::IListener
|
||||
{
|
||||
// needed interfaces
|
||||
|
@ -191,6 +197,12 @@ class CClient : public IClient, public CDemoPlayer::IListener
|
|||
std::list<std::shared_ptr<CDemoEdit>> m_EditJobs;
|
||||
|
||||
//
|
||||
bool m_CanReceiveServerCapabilities;
|
||||
bool m_ServerSentCapabilities;
|
||||
CServerCapabilities m_ServerCapabilities;
|
||||
|
||||
bool ShouldSendChatTimeoutCodeHeuristic();
|
||||
|
||||
class CServerInfo m_CurrentServerInfo;
|
||||
int64 m_CurrentServerInfoRequestTime; // >= 0 should request, == -1 got info
|
||||
|
||||
|
@ -285,6 +297,7 @@ public:
|
|||
|
||||
int GetPredictionTime();
|
||||
void *SnapGetItem(int SnapID, int Index, CSnapItem *pItem);
|
||||
int SnapItemSize(int SnapID, int Index);
|
||||
void SnapInvalidateItem(int SnapID, int Index);
|
||||
void *SnapFindItem(int SnapID, int Type, int ID);
|
||||
int SnapNumItems(int SnapID);
|
||||
|
|
|
@ -849,6 +849,7 @@ int CServer::NewClientNoAuthCallback(int ClientID, void *pUser)
|
|||
pThis->m_aClients[ClientID].m_ShowIps = false;
|
||||
pThis->m_aClients[ClientID].Reset();
|
||||
|
||||
pThis->SendCapabilities(ClientID);
|
||||
pThis->SendMap(ClientID);
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pThis->SendConnLoggingCommand(OPEN_SESSION, pThis->m_NetServer.ClientAddr(ClientID));
|
||||
|
@ -977,6 +978,14 @@ void CServer::GetMapInfo(char *pMapName, int MapNameSize, int *pMapSize, SHA256_
|
|||
*pMapCrc = m_CurrentMapCrc;
|
||||
}
|
||||
|
||||
void CServer::SendCapabilities(int ClientID)
|
||||
{
|
||||
CMsgPacker Msg(NETMSG_CAPABILITIES);
|
||||
Msg.AddInt(SERVERCAP_CURVERSION); // version
|
||||
Msg.AddInt(SERVERCAPFLAG_CHATTIMEOUTCODE); // flags
|
||||
SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true);
|
||||
}
|
||||
|
||||
void CServer::SendMap(int ClientID)
|
||||
{
|
||||
{
|
||||
|
@ -1202,6 +1211,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
|
||||
m_aClients[ClientID].m_State = CClient::STATE_CONNECTING;
|
||||
SendRconType(ClientID, m_AuthManager.NumNonDefaultKeys() > 0);
|
||||
SendCapabilities(ClientID);
|
||||
SendMap(ClientID);
|
||||
}
|
||||
}
|
||||
|
@ -1556,10 +1566,7 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
|
|||
p.AddString(GameServer()->GameType(), 16);
|
||||
|
||||
// flags
|
||||
int Flags = SERVER_FLAG_ISDDNET;
|
||||
if(g_Config.m_Password[0])
|
||||
Flags |= SERVER_FLAG_PASSWORD;
|
||||
ADD_INT(p, Flags);
|
||||
ADD_INT(p, g_Config.m_Password[0] ? SERVER_FLAG_PASSWORD : 0);
|
||||
|
||||
int MaxClients = m_NetServer.MaxClients();
|
||||
if(Type == SERVERINFO_VANILLA || Type == SERVERINFO_INGAME)
|
||||
|
|
|
@ -278,6 +278,7 @@ public:
|
|||
static int ClientRejoinCallback(int ClientID, void *pUser);
|
||||
|
||||
void SendRconType(int ClientID, bool UsernameReq);
|
||||
void SendCapabilities(int ClientID);
|
||||
void SendMap(int ClientID);
|
||||
void SendMapData(int ClientID, int Chunk);
|
||||
void SendConnectionReady(int ClientID);
|
||||
|
|
|
@ -79,7 +79,6 @@ enum
|
|||
{
|
||||
SERVER_TICK_SPEED=50,
|
||||
SERVER_FLAG_PASSWORD = 0x1,
|
||||
SERVER_FLAG_ISDDNET = 0x2,
|
||||
|
||||
MAX_CLIENTS=64,
|
||||
VANILLA_MAX_CLIENTS=16,
|
||||
|
|
|
@ -19,6 +19,10 @@ enum
|
|||
UNPACKMESSAGE_ERROR=0,
|
||||
UNPACKMESSAGE_OK,
|
||||
UNPACKMESSAGE_ANSWER,
|
||||
|
||||
SERVERCAP_CURVERSION=1,
|
||||
SERVERCAPFLAG_DDNET=1<<0,
|
||||
SERVERCAPFLAG_CHATTIMEOUTCODE=1<<1,
|
||||
};
|
||||
|
||||
void RegisterUuids(class CUuidManager *pManager);
|
||||
|
|
|
@ -25,3 +25,4 @@ UUID(NETMSG_IDONTKNOW, "i-dont-know@ddnet.tw")
|
|||
|
||||
UUID(NETMSG_RCONTYPE, "rcon-type@ddnet.tw")
|
||||
UUID(NETMSG_MAP_DETAILS, "map-details@ddnet.tw")
|
||||
UUID(NETMSG_CAPABILITIES, "capabilities@ddnet.tw")
|
||||
|
|
|
@ -60,8 +60,7 @@ bool IsBlockWorlds(const CServerInfo *pInfo)
|
|||
|
||||
bool IsDDNet(const CServerInfo *pInfo)
|
||||
{
|
||||
return (pInfo->m_Flags & SERVER_FLAG_ISDDNET
|
||||
|| str_find_nocase(pInfo->m_aGameType, "ddracenet")
|
||||
return (str_find_nocase(pInfo->m_aGameType, "ddracenet")
|
||||
|| str_find_nocase(pInfo->m_aGameType, "ddnet"))
|
||||
&& !IsBlockInfectionZ(pInfo);
|
||||
}
|
||||
|
|
|
@ -24,10 +24,7 @@ CCamera::CCamera()
|
|||
|
||||
void CCamera::OnRender()
|
||||
{
|
||||
CServerInfo Info;
|
||||
Client()->GetServerInfo(&Info);
|
||||
|
||||
if(!(m_pClient->m_Snap.m_SpecInfo.m_Active || IsRace(&Info) || IsBlockWorlds(&Info) || Client()->State() == IClient::STATE_DEMOPLAYBACK))
|
||||
if(!(m_pClient->m_Snap.m_SpecInfo.m_Active || GameClient()->m_GameInfo.m_AllowZoom || Client()->State() == IClient::STATE_DEMOPLAYBACK))
|
||||
{
|
||||
if(!Client()->DummyConnected() && !Client()->DummyConnecting())
|
||||
{
|
||||
|
@ -112,17 +109,13 @@ void CCamera::OnReset()
|
|||
void CCamera::ConZoomPlus(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CCamera *pSelf = (CCamera *)pUserData;
|
||||
CServerInfo Info;
|
||||
pSelf->Client()->GetServerInfo(&Info);
|
||||
if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_Active || IsRace(&Info) || IsBlockWorlds(&Info) || pSelf->Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
||||
if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_Active || pSelf->GameClient()->m_GameInfo.m_AllowZoom || pSelf->Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
||||
((CCamera *)pUserData)->m_Zoom *= ZoomStep;
|
||||
}
|
||||
void CCamera::ConZoomMinus(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CCamera *pSelf = (CCamera *)pUserData;
|
||||
CServerInfo Info;
|
||||
pSelf->Client()->GetServerInfo(&Info);
|
||||
if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_Active || IsRace(&Info) || IsBlockWorlds(&Info) || pSelf->Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
||||
if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_Active || pSelf->GameClient()->m_GameInfo.m_AllowZoom || pSelf->Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
||||
{
|
||||
if(((CCamera *)pUserData)->m_Zoom < 500.0f/ZoomStep)
|
||||
{
|
||||
|
@ -132,8 +125,5 @@ void CCamera::ConZoomMinus(IConsole::IResult *pResult, void *pUserData)
|
|||
}
|
||||
void CCamera::ConZoomReset(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CCamera *pSelf = (CCamera *)pUserData;
|
||||
CServerInfo Info;
|
||||
pSelf->Client()->GetServerInfo(&Info);
|
||||
((CCamera *)pUserData)->OnReset();
|
||||
}
|
||||
|
|
|
@ -110,10 +110,7 @@ static void ConKeyInputState(IConsole::IResult *pResult, void *pUserData)
|
|||
{
|
||||
CInputState *pState = (CInputState *)pUserData;
|
||||
|
||||
CServerInfo Info;
|
||||
pState->m_pControls->GameClient()->Client()->GetServerInfo(&Info);
|
||||
|
||||
if ((IsRace(&Info) || IsDDRace(&Info)) && pState->m_pControls->GameClient()->m_Snap.m_SpecInfo.m_Active)
|
||||
if(pState->m_pControls->GameClient()->m_GameInfo.m_BugDDRaceInput && pState->m_pControls->GameClient()->m_Snap.m_SpecInfo.m_Active)
|
||||
return;
|
||||
|
||||
if (g_Config.m_ClDummy)
|
||||
|
@ -126,10 +123,7 @@ static void ConKeyInputCounter(IConsole::IResult *pResult, void *pUserData)
|
|||
{
|
||||
CInputState *pState = (CInputState *)pUserData;
|
||||
|
||||
CServerInfo Info;
|
||||
pState->m_pControls->GameClient()->Client()->GetServerInfo(&Info);
|
||||
|
||||
if ((IsRace(&Info) || IsDDRace(&Info)) && pState->m_pControls->GameClient()->m_Snap.m_SpecInfo.m_Active)
|
||||
if(pState->m_pControls->GameClient()->m_GameInfo.m_BugDDRaceInput && pState->m_pControls->GameClient()->m_Snap.m_SpecInfo.m_Active)
|
||||
return;
|
||||
|
||||
int *v;
|
||||
|
@ -216,9 +210,7 @@ int CControls::SnapInput(int *pData)
|
|||
{
|
||||
if(m_InputData[g_Config.m_ClDummy].m_PlayerFlags == PLAYERFLAG_CHATTING)
|
||||
{
|
||||
CServerInfo Info;
|
||||
GameClient()->Client()->GetServerInfo(&Info);
|
||||
if(IsDDNet(&Info))
|
||||
if(GameClient()->m_GameInfo.m_BugDDRaceInput)
|
||||
ResetInput(g_Config.m_ClDummy);
|
||||
}
|
||||
m_InputData[g_Config.m_ClDummy].m_PlayerFlags = PLAYERFLAG_PLAYING;
|
||||
|
@ -241,9 +233,7 @@ int CControls::SnapInput(int *pData)
|
|||
// we freeze the input if chat or menu is activated
|
||||
if(!(m_InputData[g_Config.m_ClDummy].m_PlayerFlags&PLAYERFLAG_PLAYING))
|
||||
{
|
||||
CServerInfo Info;
|
||||
GameClient()->Client()->GetServerInfo(&Info);
|
||||
if(!IsDDNet(&Info))
|
||||
if(!GameClient()->m_GameInfo.m_BugDDRaceInput)
|
||||
ResetInput(g_Config.m_ClDummy);
|
||||
|
||||
mem_copy(pData, &m_InputData[g_Config.m_ClDummy], sizeof(m_InputData[0]));
|
||||
|
@ -456,10 +446,7 @@ void CControls::OnRender()
|
|||
}
|
||||
}
|
||||
|
||||
CServerInfo Info;
|
||||
GameClient()->Client()->GetServerInfo(&Info);
|
||||
|
||||
if( g_Config.m_ClAutoswitchWeaponsOutOfAmmo && !IsRace(&Info) && !IsDDRace(&Info) && m_pClient->m_Snap.m_pLocalCharacter )
|
||||
if(g_Config.m_ClAutoswitchWeaponsOutOfAmmo && !GameClient()->m_GameInfo.m_UnlimitedAmmo && m_pClient->m_Snap.m_pLocalCharacter)
|
||||
{
|
||||
// Keep track of ammo count, we know weapon ammo only when we switch to that weapon, this is tracked on server and protocol does not track that
|
||||
m_AmmoCount[m_pClient->m_Snap.m_pLocalCharacter->m_Weapon%NUM_WEAPONS] = m_pClient->m_Snap.m_pLocalCharacter->m_AmmoCount;
|
||||
|
|
|
@ -135,9 +135,7 @@ void CEmoticon::OnRender()
|
|||
|
||||
Graphics()->QuadsEnd();
|
||||
|
||||
CServerInfo pServerInfo;
|
||||
Client()->GetServerInfo(&pServerInfo);
|
||||
if((IsDDRace(&pServerInfo) || IsDDNet(&pServerInfo) || IsBlockWorlds(&pServerInfo) || IsPlus(&pServerInfo)) && g_Config.m_ClEyeWheel)
|
||||
if(GameClient()->m_GameInfo.m_AllowEyeWheel && g_Config.m_ClEyeWheel)
|
||||
{
|
||||
Graphics()->TextureSet(-1);
|
||||
Graphics()->QuadsBegin();
|
||||
|
|
|
@ -187,9 +187,7 @@ void CGhost::CheckStart()
|
|||
GhostRecorder()->Stop(0, -1);
|
||||
int StartTick = RaceTick;
|
||||
|
||||
CServerInfo ServerInfo;
|
||||
Client()->GetServerInfo(&ServerInfo);
|
||||
if(IsDDRace(&ServerInfo)) // the client recognizes the start one tick earlier than ddrace servers
|
||||
if(GameClient()->m_GameInfo.m_BugDDRaceGhost) // the client recognizes the start one tick earlier than ddrace servers
|
||||
StartTick--;
|
||||
StartRecord(StartTick);
|
||||
RenderTick = StartTick;
|
||||
|
@ -261,9 +259,7 @@ void CGhost::TryRenderStart(int Tick, bool ServerControl)
|
|||
|
||||
void CGhost::OnNewSnapshot()
|
||||
{
|
||||
CServerInfo ServerInfo;
|
||||
Client()->GetServerInfo(&ServerInfo);
|
||||
if(!IsRace(&ServerInfo) || Client()->State() != IClient::STATE_ONLINE)
|
||||
if(!GameClient()->m_GameInfo.m_Race || Client()->State() != IClient::STATE_ONLINE)
|
||||
return;
|
||||
if(!m_pClient->m_Snap.m_pGameInfoObj || m_pClient->m_Snap.m_SpecInfo.m_Active || !m_pClient->m_Snap.m_pLocalCharacter || !m_pClient->m_Snap.m_pLocalPrevCharacter)
|
||||
return;
|
||||
|
@ -289,9 +285,7 @@ void CGhost::OnNewSnapshot()
|
|||
|
||||
void CGhost::OnNewPredictedSnapshot()
|
||||
{
|
||||
CServerInfo ServerInfo;
|
||||
Client()->GetServerInfo(&ServerInfo);
|
||||
if(!IsRace(&ServerInfo) || !g_Config.m_ClRaceGhost || Client()->State() != IClient::STATE_ONLINE)
|
||||
if(!GameClient()->m_GameInfo.m_Race || !g_Config.m_ClRaceGhost || Client()->State() != IClient::STATE_ONLINE)
|
||||
return;
|
||||
if(!m_pClient->m_Snap.m_pGameInfoObj || m_pClient->m_Snap.m_SpecInfo.m_Active || !m_pClient->m_Snap.m_pLocalCharacter || !m_pClient->m_Snap.m_pLocalPrevCharacter)
|
||||
return;
|
||||
|
|
|
@ -105,7 +105,7 @@ void CHud::RenderGameTimer()
|
|||
|
||||
if(!(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_SUDDENDEATH))
|
||||
{
|
||||
char Buf[32];
|
||||
char aBuf[32];
|
||||
int Time = 0;
|
||||
if(m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit && (m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer <= 0))
|
||||
{
|
||||
|
@ -122,19 +122,16 @@ void CHud::RenderGameTimer()
|
|||
else
|
||||
Time = (Client()->GameTick()-m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick)/Client()->GameTickSpeed();
|
||||
|
||||
CServerInfo Info;
|
||||
Client()->GetServerInfo(&Info);
|
||||
|
||||
if(Time <= 0 && g_Config.m_ClShowDecisecs)
|
||||
str_format(Buf, sizeof(Buf), "00:00.0");
|
||||
str_format(aBuf, sizeof(aBuf), "00:00.0");
|
||||
else if(Time <= 0)
|
||||
str_format(Buf, sizeof(Buf), "00:00");
|
||||
else if(IsRace(&Info) && !IsDDRace(&Info) && m_ServerRecord >= 0)
|
||||
str_format(Buf, sizeof(Buf), "%02d:%02d", (int)(m_ServerRecord*100)/60, ((int)(m_ServerRecord*100)%60));
|
||||
str_format(aBuf, sizeof(aBuf), "00:00");
|
||||
else if(GameClient()->m_GameInfo.m_RaceRecordMessage && m_ServerRecord >= 0)
|
||||
str_format(aBuf, sizeof(aBuf), "%02d:%02d", (int)(m_ServerRecord*100)/60, ((int)(m_ServerRecord*100)%60));
|
||||
else if(g_Config.m_ClShowDecisecs)
|
||||
str_format(Buf, sizeof(Buf), "%02d:%02d.%d", Time/60, Time%60, m_DDRaceTick/10);
|
||||
str_format(aBuf, sizeof(aBuf), "%02d:%02d.%d", Time/60, Time%60, m_DDRaceTick/10);
|
||||
else
|
||||
str_format(Buf, sizeof(Buf), "%02d:%02d", Time/60, Time%60);
|
||||
str_format(aBuf, sizeof(aBuf), "%02d:%02d", Time/60, Time%60);
|
||||
float FontSize = 10.0f;
|
||||
float w;
|
||||
if(g_Config.m_ClShowDecisecs)
|
||||
|
@ -147,7 +144,7 @@ void CHud::RenderGameTimer()
|
|||
float Alpha = Time <= 10 && (2*time_get()/time_freq()) % 2 ? 0.5f : 1.0f;
|
||||
TextRender()->TextColor(1.0f, 0.25f, 0.25f, Alpha);
|
||||
}
|
||||
TextRender()->Text(0, Half-w/2, 2, FontSize, Buf, -1);
|
||||
TextRender()->Text(0, Half-w/2, 2, FontSize, aBuf, -1);
|
||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
@ -338,9 +335,7 @@ void CHud::RenderScoreHud()
|
|||
{
|
||||
if(apPlayerInfo[t])
|
||||
{
|
||||
CServerInfo Info;
|
||||
Client()->GetServerInfo(&Info);
|
||||
if(m_pClient->TimeScore() && g_Config.m_ClDDRaceScoreBoard)
|
||||
if(m_pClient->m_GameInfo.m_TimeScore && g_Config.m_ClDDRaceScoreBoard)
|
||||
{
|
||||
if(apPlayerInfo[t]->m_Score != -9999)
|
||||
str_format(aScore[t], sizeof(aScore[t]), "%02d:%02d", abs(apPlayerInfo[t]->m_Score)/60, abs(apPlayerInfo[t]->m_Score)%60);
|
||||
|
@ -869,13 +864,10 @@ void CHud::OnMessage(int MsgType, void *pRawMsg)
|
|||
}
|
||||
else if(MsgType == NETMSGTYPE_SV_RECORD)
|
||||
{
|
||||
CServerInfo Info;
|
||||
Client()->GetServerInfo(&Info);
|
||||
|
||||
CNetMsg_Sv_Record *pMsg = (CNetMsg_Sv_Record *)pRawMsg;
|
||||
|
||||
// NETMSGTYPE_SV_RACETIME on old race servers
|
||||
if(!IsDDRace(&Info) && IsRace(&Info))
|
||||
if(GameClient()->m_GameInfo.m_DDRaceRecordMessage)
|
||||
{
|
||||
m_DDRaceTimeReceived = true;
|
||||
|
||||
|
@ -890,7 +882,7 @@ void CHud::OnMessage(int MsgType, void *pRawMsg)
|
|||
m_CheckpointTick = Client()->GameTick();
|
||||
}
|
||||
}
|
||||
else
|
||||
else if(GameClient()->m_GameInfo.m_RaceRecordMessage)
|
||||
{
|
||||
m_ServerRecord = (float)pMsg->m_ServerTimeBest/100;
|
||||
m_PlayerRecord = (float)pMsg->m_PlayerTimeBest/100;
|
||||
|
|
|
@ -103,32 +103,29 @@ void CMapImages::LoadBackground(class IMap *pMap)
|
|||
|
||||
int CMapImages::GetEntities()
|
||||
{
|
||||
CServerInfo Info;
|
||||
Client()->GetServerInfo(&Info);
|
||||
|
||||
if(m_EntitiesTextures == -1 || str_comp(m_aEntitiesGameType, Info.m_aGameType))
|
||||
{
|
||||
// DDNet default to prevent delay in seeing entities
|
||||
char file[64] = "ddnet";
|
||||
if(IsDDNet(&Info))
|
||||
str_copy(file, "ddnet", sizeof(file));
|
||||
else if(IsDDRace(&Info))
|
||||
str_copy(file, "ddrace", sizeof(file));
|
||||
else if(IsRace(&Info))
|
||||
str_copy(file, "race", sizeof(file));
|
||||
else if(IsFNG(&Info))
|
||||
str_copy(file, "fng", sizeof(file));
|
||||
else if(IsVanilla(&Info))
|
||||
str_copy(file, "vanilla", sizeof(file));
|
||||
// DDNet default to prevent delay in seeing entities
|
||||
const char *pEntities = "ddnet";
|
||||
if(GameClient()->m_GameInfo.m_EntitiesDDNet)
|
||||
pEntities = "ddnet";
|
||||
else if(GameClient()->m_GameInfo.m_EntitiesDDRace)
|
||||
pEntities = "ddrace";
|
||||
else if(GameClient()->m_GameInfo.m_EntitiesRace)
|
||||
pEntities = "race";
|
||||
else if(GameClient()->m_GameInfo.m_EntitiesFNG)
|
||||
pEntities = "fng";
|
||||
else if(GameClient()->m_GameInfo.m_EntitiesVanilla)
|
||||
pEntities = "vanilla";
|
||||
|
||||
if(m_EntitiesTextures == -1 || m_pEntitiesGameType != pEntities)
|
||||
{
|
||||
char aPath[64];
|
||||
str_format(aPath, sizeof(aPath), "editor/entities_clear/%s.png", pEntities);
|
||||
|
||||
char path[64];
|
||||
str_format(path, sizeof(path), "editor/entities_clear/%s.png", file);
|
||||
|
||||
if(m_EntitiesTextures >= 0)
|
||||
Graphics()->UnloadTexture(m_EntitiesTextures);
|
||||
m_EntitiesTextures = Graphics()->LoadTexture(path, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
|
||||
m_EntitiesTextures = Graphics()->LoadTexture(aPath, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
|
||||
|
||||
str_copy(m_aEntitiesGameType, Info.m_aGameType, sizeof(m_aEntitiesGameType));
|
||||
m_pEntitiesGameType = pEntities;
|
||||
}
|
||||
return m_EntitiesTextures;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ class CMapImages : public CComponent
|
|||
int m_aTextures[64];
|
||||
int m_Count;
|
||||
|
||||
char m_aEntitiesGameType[16];
|
||||
const char *m_pEntitiesGameType;
|
||||
public:
|
||||
CMapImages();
|
||||
CMapImages(int ImageSize);
|
||||
|
|
|
@ -450,9 +450,6 @@ void CMapLayers::OnMapLoad()
|
|||
m_QuadLayerVisuals.clear();
|
||||
}
|
||||
|
||||
CServerInfo Info;
|
||||
Client()->GetServerInfo(&Info);
|
||||
|
||||
bool PassedGameLayer = false;
|
||||
//prepare all visuals for all tile layers
|
||||
std::vector<STmpTile> tmpTiles;
|
||||
|
@ -623,7 +620,7 @@ void CMapLayers::OnMapLoad()
|
|||
{
|
||||
Index = ((CTile*)pTiles)[y*pTMap->m_Width+x].m_Index;
|
||||
Flags = ((CTile*)pTiles)[y*pTMap->m_Width+x].m_Flags;
|
||||
if(IsDDNet(&Info) && !IsValidGameTile(Index))
|
||||
if(GameClient()->m_GameInfo.m_EntitiesDDNet && !IsValidGameTile(Index))
|
||||
Index = 0;
|
||||
}
|
||||
if(IsFrontLayer)
|
||||
|
|
|
@ -773,10 +773,8 @@ int CMenus::RenderMenubar(CUIRect r)
|
|||
NewPage = PAGE_NETWORK;
|
||||
|
||||
{
|
||||
CServerInfo Info;
|
||||
Client()->GetServerInfo(&Info);
|
||||
static int s_GhostButton=0;
|
||||
if(IsRace(&Info) || IsDDNet(&Info))
|
||||
if(GameClient()->m_GameInfo.m_Race)
|
||||
{
|
||||
Box.VSplitLeft(70.0f, &Button, &Box);
|
||||
if(DoButton_MenuTab(&s_GhostButton, Localize("Ghost"), m_ActivePage==PAGE_GHOST, &Button, 0))
|
||||
|
|
|
@ -294,9 +294,7 @@ void CPlayers::RenderPlayer(
|
|||
|
||||
// draw gun
|
||||
{
|
||||
CServerInfo Info;
|
||||
Client()->GetServerInfo(&Info);
|
||||
if(ClientID >= 0 && (((IsDDRace(&Info) || IsDDNet(&Info)) && g_Config.m_ClShowHookCollAlways) || (Player.m_PlayerFlags&PLAYERFLAG_AIM && ((!Local && g_Config.m_ClShowHookCollOther) || (Local && g_Config.m_ClShowHookCollOwn)))))
|
||||
if(ClientID >= 0 && ((GameClient()->m_GameInfo.m_AllowHookColl && g_Config.m_ClShowHookCollAlways) || (Player.m_PlayerFlags&PLAYERFLAG_AIM && ((!Local && g_Config.m_ClShowHookCollOther) || (Local && g_Config.m_ClShowHookCollOwn)))))
|
||||
{
|
||||
vec2 ExDirection = Direction;
|
||||
|
||||
|
|
|
@ -51,9 +51,7 @@ void CRaceDemo::OnStateChange(int NewState, int OldState)
|
|||
|
||||
void CRaceDemo::OnNewSnapshot()
|
||||
{
|
||||
CServerInfo ServerInfo;
|
||||
Client()->GetServerInfo(&ServerInfo);
|
||||
if(!IsRace(&ServerInfo) || !g_Config.m_ClAutoRaceRecord || Client()->State() != IClient::STATE_ONLINE)
|
||||
if(!GameClient()->m_GameInfo.m_Race || !g_Config.m_ClAutoRaceRecord || Client()->State() != IClient::STATE_ONLINE)
|
||||
return;
|
||||
|
||||
if(!m_pClient->m_Snap.m_pGameInfoObj || m_pClient->m_Snap.m_SpecInfo.m_Active || !m_pClient->m_Snap.m_pLocalCharacter || !m_pClient->m_Snap.m_pLocalPrevCharacter)
|
||||
|
|
|
@ -30,10 +30,6 @@ CScoreboard::CScoreboard()
|
|||
void CScoreboard::ConKeyScoreboard(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CScoreboard *pSelf = (CScoreboard *)pUserData;
|
||||
CServerInfo Info;
|
||||
|
||||
pSelf->Client()->GetServerInfo(&Info);
|
||||
pSelf->m_IsGameTypeRace = IsRace(&Info);
|
||||
pSelf->m_Active = pResult->GetInteger(0) != 0;
|
||||
}
|
||||
|
||||
|
@ -231,7 +227,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch
|
|||
}
|
||||
}
|
||||
|
||||
if(m_pClient->TimeScore() && g_Config.m_ClDDRaceScoreBoard)
|
||||
if(m_pClient->m_GameInfo.m_TimeScore && g_Config.m_ClDDRaceScoreBoard)
|
||||
{
|
||||
if (m_ServerRecord > 0)
|
||||
{
|
||||
|
@ -294,7 +290,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch
|
|||
// render headlines
|
||||
y += 50.0f;
|
||||
float HeadlineFontsize = 22.0f;
|
||||
const char *pScore = (m_pClient->TimeScore() && g_Config.m_ClDDRaceScoreBoard) ? Localize("Time") : Localize("Score");
|
||||
const char *pScore = (m_pClient->m_GameInfo.m_TimeScore && g_Config.m_ClDDRaceScoreBoard) ? Localize("Time") : Localize("Score");
|
||||
float ScoreWidth = TextRender()->TextWidth(0, HeadlineFontsize, pScore, -1);
|
||||
tw = ScoreLength > ScoreWidth ? ScoreLength : ScoreWidth;
|
||||
TextRender()->Text(0, ScoreOffset+ScoreLength-tw, y + (HeadlineFontsize * 2.f - HeadlineFontsize) / 2.f, HeadlineFontsize, pScore, -1);
|
||||
|
@ -414,7 +410,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch
|
|||
}
|
||||
|
||||
// score
|
||||
if(m_pClient->TimeScore() && g_Config.m_ClDDRaceScoreBoard)
|
||||
if(m_pClient->m_GameInfo.m_TimeScore && g_Config.m_ClDDRaceScoreBoard)
|
||||
{
|
||||
if (pInfo->m_Score == -9999)
|
||||
aBuf[0] = 0;
|
||||
|
|
|
@ -32,7 +32,6 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
bool m_IsGameTypeRace;
|
||||
float m_ServerRecord;
|
||||
};
|
||||
|
||||
|
|
|
@ -473,9 +473,6 @@ void CGameClient::OnConnected()
|
|||
m_All.m_paComponents[i]->OnReset();
|
||||
}
|
||||
|
||||
CServerInfo CurrentServerInfo;
|
||||
Client()->GetServerInfo(&CurrentServerInfo);
|
||||
|
||||
m_ServerMode = SERVERMODE_PURE;
|
||||
|
||||
// send the initial info
|
||||
|
@ -953,6 +950,110 @@ void CGameClient::ProcessEvents()
|
|||
}
|
||||
}
|
||||
|
||||
static CGameInfo GetGameInfo(const CNetObj_GameInfoEx *pInfoEx, int InfoExSize, CServerInfo *pFallbackServerInfo)
|
||||
{
|
||||
int Version = -1;
|
||||
if(InfoExSize >= 8)
|
||||
{
|
||||
Version = pInfoEx->m_Version;
|
||||
}
|
||||
else if(InfoExSize >= 4)
|
||||
{
|
||||
Version = 0;
|
||||
}
|
||||
int Flags = 0;
|
||||
if(Version >= 0)
|
||||
{
|
||||
Flags = pInfoEx->m_Flags;
|
||||
}
|
||||
bool Race;
|
||||
bool FastCap;
|
||||
bool FNG;
|
||||
bool DDRace;
|
||||
bool DDNet;
|
||||
bool BlockWorlds;
|
||||
bool Vanilla;
|
||||
bool Plus;
|
||||
if(Version < 1)
|
||||
{
|
||||
Race = IsRace(pFallbackServerInfo);
|
||||
FastCap = IsFastCap(pFallbackServerInfo);
|
||||
FNG = IsFNG(pFallbackServerInfo);
|
||||
DDRace = IsDDRace(pFallbackServerInfo);
|
||||
DDNet = IsDDNet(pFallbackServerInfo);
|
||||
BlockWorlds = IsBlockWorlds(pFallbackServerInfo);
|
||||
Vanilla = IsVanilla(pFallbackServerInfo);
|
||||
Plus = IsPlus(pFallbackServerInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
Race = Flags&GAMEINFOFLAG_GAMETYPE_RACE;
|
||||
FastCap = Flags&GAMEINFOFLAG_GAMETYPE_FASTCAP;
|
||||
FNG = Flags&GAMEINFOFLAG_GAMETYPE_FNG;
|
||||
DDRace = Flags&GAMEINFOFLAG_GAMETYPE_DDRACE;
|
||||
DDNet = Flags&GAMEINFOFLAG_GAMETYPE_DDNET;
|
||||
BlockWorlds = Flags&GAMEINFOFLAG_GAMETYPE_BLOCK_WORLDS;
|
||||
Vanilla = Flags&GAMEINFOFLAG_GAMETYPE_VANILLA;
|
||||
Plus = Flags&GAMEINFOFLAG_GAMETYPE_PLUS;
|
||||
|
||||
// Ensure invariants upheld by the server info parsing business.
|
||||
DDRace = DDRace || DDNet;
|
||||
Race = Race || FastCap || DDRace;
|
||||
}
|
||||
|
||||
CGameInfo Info;
|
||||
Info.m_FlagStartsRace = FastCap;
|
||||
Info.m_TimeScore = Race;
|
||||
Info.m_UnlimitedAmmo = Race;
|
||||
Info.m_DDRaceRecordMessage = DDRace;
|
||||
Info.m_RaceRecordMessage = Race && !DDRace;
|
||||
Info.m_AllowEyeWheel = DDRace || BlockWorlds || Plus;
|
||||
Info.m_AllowHookColl = DDRace;
|
||||
Info.m_AllowZoom = Race || BlockWorlds;
|
||||
Info.m_BugDDRaceGhost = DDRace;
|
||||
Info.m_BugDDRaceInput = DDRace;
|
||||
Info.m_BugFNGLaserRange = FNG;
|
||||
Info.m_BugVanillaBounce = Vanilla;
|
||||
Info.m_PredictFNG = FNG;
|
||||
Info.m_PredictDDRace = DDRace;
|
||||
Info.m_PredictDDRaceTiles = DDRace && !BlockWorlds;
|
||||
Info.m_PredictVanilla = Vanilla || FastCap;
|
||||
Info.m_EntitiesDDNet = DDNet;
|
||||
Info.m_EntitiesDDRace = DDRace;
|
||||
Info.m_EntitiesRace = Race;
|
||||
Info.m_EntitiesFNG = FNG;
|
||||
Info.m_EntitiesVanilla = Vanilla;
|
||||
|
||||
if(Version >= 0)
|
||||
{
|
||||
Info.m_TimeScore = Flags&GAMEINFOFLAG_TIMESCORE;
|
||||
}
|
||||
if(Version >= 2)
|
||||
{
|
||||
Info.m_FlagStartsRace = Flags&GAMEINFOFLAG_FLAG_STARTS_RACE;
|
||||
Info.m_UnlimitedAmmo = Flags&GAMEINFOFLAG_UNLIMITED_AMMO;
|
||||
Info.m_DDRaceRecordMessage = Flags&GAMEINFOFLAG_DDRACE_RECORD_MESSAGE;
|
||||
Info.m_RaceRecordMessage = Flags&GAMEINFOFLAG_RACE_RECORD_MESSAGE;
|
||||
Info.m_AllowEyeWheel = Flags&GAMEINFOFLAG_ALLOW_EYE_WHEEL;
|
||||
Info.m_AllowHookColl = Flags&GAMEINFOFLAG_ALLOW_HOOK_COLL;
|
||||
Info.m_AllowZoom = Flags&GAMEINFOFLAG_ALLOW_ZOOM;
|
||||
Info.m_BugDDRaceGhost = Flags&GAMEINFOFLAG_BUG_DDRACE_GHOST;
|
||||
Info.m_BugDDRaceInput = Flags&GAMEINFOFLAG_BUG_DDRACE_INPUT;
|
||||
Info.m_BugFNGLaserRange = Flags&GAMEINFOFLAG_BUG_FNG_LASER_RANGE;
|
||||
Info.m_BugVanillaBounce = Flags&GAMEINFOFLAG_BUG_VANILLA_BOUNCE;
|
||||
Info.m_PredictFNG = Flags&GAMEINFOFLAG_PREDICT_FNG;
|
||||
Info.m_PredictDDRace = Flags&GAMEINFOFLAG_PREDICT_DDRACE;
|
||||
Info.m_PredictDDRaceTiles = Flags&GAMEINFOFLAG_PREDICT_DDRACE_TILES;
|
||||
Info.m_PredictVanilla = Flags&GAMEINFOFLAG_PREDICT_VANILLA;
|
||||
Info.m_EntitiesDDNet = Flags&GAMEINFOFLAG_ENTITIES_DDNET;
|
||||
Info.m_EntitiesDDRace = Flags&GAMEINFOFLAG_ENTITIES_DDRACE;
|
||||
Info.m_EntitiesRace = Flags&GAMEINFOFLAG_ENTITIES_RACE;
|
||||
Info.m_EntitiesFNG = Flags&GAMEINFOFLAG_ENTITIES_FNG;
|
||||
Info.m_EntitiesVanilla = Flags&GAMEINFOFLAG_ENTITIES_VANILLA;
|
||||
}
|
||||
return Info;
|
||||
}
|
||||
|
||||
void CGameClient::OnNewSnapshot()
|
||||
{
|
||||
m_NewTick = true;
|
||||
|
@ -1002,6 +1103,8 @@ void CGameClient::OnNewSnapshot()
|
|||
}
|
||||
#endif
|
||||
|
||||
bool FoundGameInfoEx = false;
|
||||
|
||||
// go trough all the items in the snapshot and gather the info we want
|
||||
{
|
||||
m_Snap.m_aTeamSize[TEAM_RED] = m_Snap.m_aTeamSize[TEAM_BLUE] = 0;
|
||||
|
@ -1174,9 +1277,16 @@ void CGameClient::OnNewSnapshot()
|
|||
s_GameOver = CurrentTickGameOver;
|
||||
s_GamePaused = (bool)(m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED);
|
||||
}
|
||||
else if(Item.m_Type == NETOBJTYPE_DDNETGAMEINFO)
|
||||
else if(Item.m_Type == NETOBJTYPE_GAMEINFOEX)
|
||||
{
|
||||
m_Snap.m_pGameInfoEx = (const CNetObj_DDNetGameInfo *)pData;
|
||||
if(FoundGameInfoEx)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
FoundGameInfoEx = true;
|
||||
CServerInfo ServerInfo;
|
||||
Client()->GetServerInfo(&ServerInfo);
|
||||
m_GameInfo = GetGameInfo((const CNetObj_GameInfoEx *)pData, Client()->SnapItemSize(IClient::SNAP_CURRENT, i), &ServerInfo);
|
||||
}
|
||||
else if(Item.m_Type == NETOBJTYPE_GAMEDATA)
|
||||
{
|
||||
|
@ -1209,6 +1319,13 @@ void CGameClient::OnNewSnapshot()
|
|||
}
|
||||
}
|
||||
|
||||
if(!FoundGameInfoEx)
|
||||
{
|
||||
CServerInfo ServerInfo;
|
||||
Client()->GetServerInfo(&ServerInfo);
|
||||
m_GameInfo = GetGameInfo(0, 0, &ServerInfo);
|
||||
}
|
||||
|
||||
// setup local pointers
|
||||
if(m_Snap.m_LocalClientID >= 0)
|
||||
{
|
||||
|
@ -1276,21 +1393,19 @@ void CGameClient::OnNewSnapshot()
|
|||
return str_comp_nocase(m_aClients[p1->m_ClientID].m_aName, m_aClients[p2->m_ClientID].m_aName) < 0;
|
||||
});
|
||||
|
||||
CServerInfo CurrentServerInfo;
|
||||
Client()->GetServerInfo(&CurrentServerInfo);
|
||||
bool IsGameTypeRace = IsRace(&CurrentServerInfo);
|
||||
bool TimeScore = m_GameInfo.m_TimeScore;
|
||||
|
||||
// sort player infos by score
|
||||
mem_copy(m_Snap.m_paInfoByScore, m_Snap.m_paInfoByName, sizeof(m_Snap.m_paInfoByScore));
|
||||
std::stable_sort(m_Snap.m_paInfoByScore, m_Snap.m_paInfoByScore + MAX_CLIENTS,
|
||||
[IsGameTypeRace](const CNetObj_PlayerInfo* p1, const CNetObj_PlayerInfo* p2) -> bool
|
||||
[TimeScore](const CNetObj_PlayerInfo* p1, const CNetObj_PlayerInfo* p2) -> bool
|
||||
{
|
||||
if (!p2)
|
||||
return static_cast<bool>(p1);
|
||||
if (!p1)
|
||||
return false;
|
||||
return (((IsGameTypeRace && p1->m_Score == -9999) ? std::numeric_limits<int>::min() : p1->m_Score) >
|
||||
((IsGameTypeRace && p2->m_Score == -9999) ? std::numeric_limits<int>::min() : p2->m_Score));
|
||||
return (((TimeScore && p1->m_Score == -9999) ? std::numeric_limits<int>::min() : p1->m_Score) >
|
||||
((TimeScore && p2->m_Score == -9999) ? std::numeric_limits<int>::min() : p2->m_Score));
|
||||
});
|
||||
|
||||
// sort player infos by DDRace Team (and score between)
|
||||
|
@ -1304,6 +1419,8 @@ void CGameClient::OnNewSnapshot()
|
|||
}
|
||||
}
|
||||
|
||||
CServerInfo CurrentServerInfo;
|
||||
Client()->GetServerInfo(&CurrentServerInfo);
|
||||
CTuningParams StandardTuning;
|
||||
if(CurrentServerInfo.m_aGameType[0] != '0')
|
||||
{
|
||||
|
@ -1875,14 +1992,11 @@ void CGameClient::UpdatePrediction()
|
|||
|
||||
m_TeamsPredicted = m_Teams;
|
||||
|
||||
CServerInfo CurrentServerInfo;
|
||||
Client()->GetServerInfo(&CurrentServerInfo);
|
||||
|
||||
m_GameWorld.m_WorldConfig.m_IsVanilla = IsVanilla(&CurrentServerInfo) || IsFastCap(&CurrentServerInfo);
|
||||
m_GameWorld.m_WorldConfig.m_IsDDRace = IsDDRace(&CurrentServerInfo);
|
||||
m_GameWorld.m_WorldConfig.m_IsFNG = IsFNG(&CurrentServerInfo);
|
||||
m_GameWorld.m_WorldConfig.m_IsVanilla = m_GameInfo.m_PredictVanilla;
|
||||
m_GameWorld.m_WorldConfig.m_IsDDRace = m_GameInfo.m_PredictDDRace;
|
||||
m_GameWorld.m_WorldConfig.m_IsFNG = m_GameInfo.m_PredictFNG;
|
||||
m_GameWorld.m_WorldConfig.m_PredictDDRace = g_Config.m_ClPredictDDRace;
|
||||
m_GameWorld.m_WorldConfig.m_PredictTiles = g_Config.m_ClPredictDDRace && m_GameWorld.m_WorldConfig.m_IsDDRace && !IsBlockWorlds(&CurrentServerInfo);
|
||||
m_GameWorld.m_WorldConfig.m_PredictTiles = g_Config.m_ClPredictDDRace && m_GameInfo.m_PredictDDRaceTiles;
|
||||
m_GameWorld.m_WorldConfig.m_PredictFreeze = g_Config.m_ClPredictFreeze;
|
||||
m_GameWorld.m_WorldConfig.m_PredictWeapons = AntiPingWeapons();
|
||||
if(m_Snap.m_pLocalCharacter->m_AmmoCount > 0 && m_Snap.m_pLocalCharacter->m_Weapon != WEAPON_NINJA)
|
||||
|
@ -1984,13 +2098,6 @@ void CGameClient::UpdatePrediction()
|
|||
}
|
||||
}
|
||||
|
||||
bool CGameClient::TimeScore()
|
||||
{
|
||||
CServerInfo Info;
|
||||
Client()->GetServerInfo(&Info);
|
||||
return m_Snap.m_pGameInfoEx ? m_Snap.m_pGameInfoEx->m_Flags & GAMEINFOFLAG_TIMESCORE : IsRace(&Info);
|
||||
}
|
||||
|
||||
void CGameClient::UpdateRenderedCharacters()
|
||||
{
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
|
|
|
@ -59,6 +59,37 @@ public:
|
|||
void Deactivate() { m_Active = 0; }
|
||||
};
|
||||
|
||||
class CGameInfo
|
||||
{
|
||||
public:
|
||||
bool m_FlagStartsRace;
|
||||
bool m_TimeScore;
|
||||
bool m_Race;
|
||||
bool m_UnlimitedAmmo;
|
||||
bool m_DDRaceRecordMessage;
|
||||
bool m_RaceRecordMessage;
|
||||
|
||||
bool m_AllowEyeWheel;
|
||||
bool m_AllowHookColl;
|
||||
bool m_AllowZoom;
|
||||
|
||||
bool m_BugDDRaceGhost;
|
||||
bool m_BugDDRaceInput;
|
||||
bool m_BugFNGLaserRange;
|
||||
bool m_BugVanillaBounce;
|
||||
|
||||
bool m_PredictFNG;
|
||||
bool m_PredictDDRace;
|
||||
bool m_PredictDDRaceTiles;
|
||||
bool m_PredictVanilla;
|
||||
|
||||
bool m_EntitiesDDNet;
|
||||
bool m_EntitiesDDRace;
|
||||
bool m_EntitiesRace;
|
||||
bool m_EntitiesFNG;
|
||||
bool m_EntitiesVanilla;
|
||||
};
|
||||
|
||||
class CGameClient : public IGameClient
|
||||
{
|
||||
class CStack
|
||||
|
@ -164,6 +195,7 @@ public:
|
|||
SERVERMODE_PUREMOD,
|
||||
};
|
||||
int m_ServerMode;
|
||||
CGameInfo m_GameInfo;
|
||||
|
||||
int m_DemoSpecID;
|
||||
|
||||
|
@ -192,8 +224,6 @@ public:
|
|||
//const CNetObj_PlayerInfo *m_paInfoByTeam[MAX_CLIENTS];
|
||||
const CNetObj_PlayerInfo *m_paInfoByDDTeam[MAX_CLIENTS];
|
||||
|
||||
const CNetObj_DDNetGameInfo *m_pGameInfoEx;
|
||||
|
||||
int m_LocalClientID;
|
||||
int m_NumPlayers;
|
||||
int m_aTeamSize[2];
|
||||
|
@ -228,8 +258,6 @@ public:
|
|||
|
||||
CSnapState m_Snap;
|
||||
|
||||
bool TimeScore();
|
||||
|
||||
// client data
|
||||
struct CClientData
|
||||
{
|
||||
|
|
|
@ -70,12 +70,8 @@ int CRaceHelper::TimeFromFinishMessage(const char *pStr, char *pNameBuf, int Nam
|
|||
|
||||
bool CRaceHelper::IsStart(CGameClient *pClient, vec2 Prev, vec2 Pos)
|
||||
{
|
||||
CServerInfo ServerInfo;
|
||||
pClient->Client()->GetServerInfo(&ServerInfo);
|
||||
|
||||
|
||||
CCollision *pCollision = pClient->Collision();
|
||||
if(IsFastCap(&ServerInfo))
|
||||
if(pClient->m_GameInfo.m_FlagStartsRace)
|
||||
{
|
||||
int EnemyTeam = pClient->m_aClients[pClient->m_Snap.m_LocalClientID].m_Team ^ 1;
|
||||
return ms_aFlagIndex[EnemyTeam] != -1 && distance(Pos, pCollision->GetPos(ms_aFlagIndex[EnemyTeam])) < 32;
|
||||
|
|
|
@ -1257,7 +1257,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(g_Config.m_SvSpamprotection && str_comp_nocase_num(pMsg->m_pMessage+1, "timeout ", 8) != 0
|
||||
if(g_Config.m_SvSpamprotection && !str_startswith(pMsg->m_pMessage+1, "timeout ")
|
||||
&& pPlayer->m_LastCommands[0] && pPlayer->m_LastCommands[0]+Server()->TickSpeed() > Server()->Tick()
|
||||
&& pPlayer->m_LastCommands[1] && pPlayer->m_LastCommands[1]+Server()->TickSpeed() > Server()->Tick()
|
||||
&& pPlayer->m_LastCommands[2] && pPlayer->m_LastCommands[2]+Server()->TickSpeed() > Server()->Tick()
|
||||
|
|
|
@ -535,11 +535,28 @@ void IGameController::Snap(int SnappingClient)
|
|||
}
|
||||
}
|
||||
|
||||
CNetObj_DDNetGameInfo *pGameInfoEx = (CNetObj_DDNetGameInfo *)Server()->SnapNewItem(NETOBJTYPE_DDNETGAMEINFO, 0, sizeof(CNetObj_DDNetGameInfo));
|
||||
CNetObj_GameInfoEx *pGameInfoEx = (CNetObj_GameInfoEx *)Server()->SnapNewItem(NETOBJTYPE_GAMEINFOEX, 0, sizeof(CNetObj_GameInfoEx));
|
||||
if(!pGameInfoEx)
|
||||
return;
|
||||
|
||||
pGameInfoEx->m_Flags = GAMEINFOFLAG_TIMESCORE;
|
||||
pGameInfoEx->m_Flags = 0
|
||||
| GAMEINFOFLAG_TIMESCORE
|
||||
| GAMEINFOFLAG_GAMETYPE_RACE
|
||||
| GAMEINFOFLAG_GAMETYPE_DDRACE
|
||||
| GAMEINFOFLAG_GAMETYPE_DDNET
|
||||
| GAMEINFOFLAG_UNLIMITED_AMMO
|
||||
| GAMEINFOFLAG_DDRACE_RECORD_MESSAGE
|
||||
| GAMEINFOFLAG_ALLOW_EYE_WHEEL
|
||||
| GAMEINFOFLAG_ALLOW_HOOK_COLL
|
||||
| GAMEINFOFLAG_ALLOW_ZOOM
|
||||
| GAMEINFOFLAG_BUG_DDRACE_GHOST
|
||||
| GAMEINFOFLAG_BUG_DDRACE_INPUT
|
||||
| GAMEINFOFLAG_PREDICT_DDRACE
|
||||
| GAMEINFOFLAG_PREDICT_DDRACE_TILES
|
||||
| GAMEINFOFLAG_ENTITIES_DDNET
|
||||
| GAMEINFOFLAG_ENTITIES_DDRACE
|
||||
| GAMEINFOFLAG_ENTITIES_RACE;
|
||||
pGameInfoEx->m_Version = GAMEINFO_CURVERSION;
|
||||
}
|
||||
|
||||
int IGameController::GetAutoTeam(int NotThisID)
|
||||
|
|
Loading…
Reference in a new issue