diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index bc91e23ea..736885a22 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -936,6 +936,22 @@ void CGameContext::OnClientEnter(int ClientID) void CGameContext::OnClientConnected(int ClientID) { + { + bool Empty = true; + for(int i = 0; i < MAX_CLIENTS; i++) + { + if(m_apPlayers[i]) + { + Empty = false; + break; + } + } + if(Empty) + { + m_NonEmptySince = Server()->Tick(); + } + } + // Check which team the player should be on const int StartTeam = g_Config.m_SvTournamentMode ? TEAM_SPECTATORS : m_pController->GetAutoTeam(ClientID); @@ -1117,12 +1133,13 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) } else if(MsgID == NETMSGTYPE_CL_CALLVOTE) { - if(g_Config.m_SvSpamprotection && pPlayer->m_LastVoteTry && pPlayer->m_LastVoteTry+Server()->TickSpeed()*3 > Server()->Tick()) + int64 Now = Server()->Tick(); + int64 TickSpeed = Server()->TickSpeed(); + + if(g_Config.m_SvSpamprotection && pPlayer->m_LastVoteTry && pPlayer->m_LastVoteTry + TickSpeed * 3 > Now) return; - int64 Now = Server()->Tick(); pPlayer->m_LastVoteTry = Now; - //if(pPlayer->GetTeam() == TEAM_SPECTATORS) if(g_Config.m_SvSpectatorVotes == 0 && pPlayer->GetTeam() == TEAM_SPECTATORS) { SendChatTarget(ClientID, "Spectators aren't allowed to start a vote."); @@ -1135,11 +1152,19 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) return; } - int Timeleft = pPlayer->m_LastVoteCall + Server()->TickSpeed()*g_Config.m_SvVoteDelay - Now; - if(pPlayer->m_LastVoteCall && Timeleft > 0) + if(Now < pPlayer->m_FirstVoteTick) { - char aChatmsg[512] = {0}; - str_format(aChatmsg, sizeof(aChatmsg), "You must wait %d seconds before making another vote", (Timeleft/Server()->TickSpeed())+1); + char aBuf[64]; + str_format(aBuf, sizeof(aBuf), "You must wait %d seconds before making your first vote", ((pPlayer->m_FirstVoteTick - Now) / TickSpeed) + 1); + SendChatTarget(ClientID, aBuf); + return; + } + + int TimeLeft = pPlayer->m_LastVoteCall + TickSpeed * g_Config.m_SvVoteDelay - Now; + if(pPlayer->m_LastVoteCall && TimeLeft > 0) + { + char aChatmsg[64]; + str_format(aChatmsg, sizeof(aChatmsg), "You must wait %d seconds before making another vote", (TimeLeft/TickSpeed)+1); SendChatTarget(ClientID, aChatmsg); return; } diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index a306fafdd..a5f72ec96 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -223,6 +223,8 @@ public: int ProcessSpamProtection(int ClientID); int GetDDRaceTeam(int ClientID); + // Describes the time when the first player joined the server. + int64 m_NonEmptySince; int64 m_LastMapVote; private: diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index cae12a3f4..f49f6902d 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -125,6 +125,17 @@ void CPlayer::Reset() #if defined(CONF_SQL) m_LastSQLQuery = 0; #endif + + int64 Now = Server()->Tick(); + int64 TickSpeed = Server()->TickSpeed(); + if(Now > GameServer()->m_NonEmptySince + 10 * TickSpeed) + { + m_FirstVoteTick = Now + g_Config.m_SvJoinVoteDelay * TickSpeed; + } + else + { + m_FirstVoteTick = Now; + } } void CPlayer::Tick() diff --git a/src/game/server/player.h b/src/game/server/player.h index c403c7eb6..f904244a7 100644 --- a/src/game/server/player.h +++ b/src/game/server/player.h @@ -138,6 +138,7 @@ public: int m_Paused; bool m_DND; + int64 m_FirstVoteTick; int64 m_NextPauseTick; char m_TimeoutCode[64]; diff --git a/src/game/variables.h b/src/game/variables.h index d22144658..250c10c45 100644 --- a/src/game/variables.h +++ b/src/game/variables.h @@ -149,6 +149,7 @@ MACRO_CONFIG_INT(SvVoteSpectateRejoindelay, sv_vote_spectate_rejoindelay, 3, 0, MACRO_CONFIG_INT(SvVoteKick, sv_vote_kick, 1, 0, 1, CFGFLAG_SERVER, "Allow voting to kick players") MACRO_CONFIG_INT(SvVoteKickMin, sv_vote_kick_min, 0, 0, MAX_CLIENTS, CFGFLAG_SERVER, "Minimum number of players required to start a kick vote") MACRO_CONFIG_INT(SvVoteKickBantime, sv_vote_kick_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time in seconds to ban a player if kicked by vote. 0 makes it just use kick") +MACRO_CONFIG_INT(SvJoinVoteDelay, sv_join_vote_delay, 0, 0, 600, CFGFLAG_SERVER, "The time in seconds a player has to wait for calling a vote after joining") MACRO_CONFIG_INT(SvOldTeleportWeapons, sv_old_teleport_weapons, 0, 0, 1, CFGFLAG_SERVER|CFGFLAG_GAME, "Teleporting of all weapons (deprecated, use special entities instead)"); MACRO_CONFIG_INT(SvOldTeleportHook, sv_old_teleport_hook, 0, 0, 1, CFGFLAG_SERVER|CFGFLAG_GAME, "Hook through teleporter (deprecated, use special entities instead)"); MACRO_CONFIG_INT(SvTeleportHoldHook, sv_teleport_hold_hook, 0, 0, 1, CFGFLAG_SERVER|CFGFLAG_GAME, "Hold hook when teleported");