diff --git a/src/game/ddracecommands.h b/src/game/ddracecommands.h index bf3dc60cc..7d5b4b85b 100644 --- a/src/game/ddracecommands.h +++ b/src/game/ddracecommands.h @@ -40,6 +40,8 @@ CONSOLE_COMMAND("help", "?r", CFGFLAG_SERVER, ConHelp, this, "Shows help to comm CONSOLE_COMMAND("info", "", CFGFLAG_SERVER, ConInfo, this, "Shows info about this server", IConsole::CONSOLELEVEL_USER) CONSOLE_COMMAND("me", "r", CFGFLAG_SERVER, ConMe, this, "Like the famous irc command '/me says hi' will display ' says hi'", IConsole::CONSOLELEVEL_USER) CONSOLE_COMMAND("pause", "", CFGFLAG_SERVER, ConTogglePause, this, "Toggles pause on/off (if activated on server)", IConsole::CONSOLELEVEL_USER) +CONSOLE_COMMAND("force_pause", "v?i", CFGFLAG_SERVER, ConForcePause, this, "Force v to pause for i seconds", IConsole::CONSOLELEVEL_ADMIN) +CONSOLE_COMMAND("force_unpause", "v", CFGFLAG_SERVER, ConForceUnpause, this, "Force v to unpause", IConsole::CONSOLELEVEL_ADMIN) CONSOLE_COMMAND("rank", "?r", CFGFLAG_SERVER, ConRank, this, "Shows the rank of player with name r (your rank by default)", IConsole::CONSOLELEVEL_USER) CONSOLE_COMMAND("rules", "", CFGFLAG_SERVER, ConRules, this, "Shows the server rules", IConsole::CONSOLELEVEL_USER) CONSOLE_COMMAND("team", "?i", CFGFLAG_SERVER, ConJoinTeam, this, "Lets you join team i (shows your team if left blank)", IConsole::CONSOLELEVEL_USER) diff --git a/src/game/server/ddracecommands.cpp b/src/game/server/ddracecommands.cpp index 6645b4501..8576d1b17 100644 --- a/src/game/server/ddracecommands.cpp +++ b/src/game/server/ddracecommands.cpp @@ -458,6 +458,7 @@ void CGameContext::ConKill(IConsole::IResult *pResult, void *pUserData, int Clie void CGameContext::ConTogglePause(IConsole::IResult *pResult, void *pUserData, int ClientID) { CGameContext *pSelf = (CGameContext *)pUserData; + char aBuf[128]; CPlayer *pPlayer = pSelf->m_apPlayers[ClientID]; if(!pPlayer) @@ -477,7 +478,7 @@ void CGameContext::ConTogglePause(IConsole::IResult *pResult, void *pUserData, i else pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You can\'t pause that often."); } - else if(pPlayer->GetTeam()==TEAM_SPECTATORS && pPlayer->m_InfoSaved) + else if(pPlayer->GetTeam()==TEAM_SPECTATORS && pPlayer->m_InfoSaved && pPlayer->m_ForcePauseTime==0) { pPlayer->m_PauseInfo.m_Respawn = true; pPlayer->SetTeam(TEAM_RED); @@ -486,6 +487,15 @@ void CGameContext::ConTogglePause(IConsole::IResult *pResult, void *pUserData, i } else if(pChr) pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", pChr->GetWeaponGot(WEAPON_NINJA)?"You can't use /pause while you are a ninja":(!pChr->IsGrounded())?"You can't use /pause while you are a in air":"You can't use /pause while you are moving"); + else if(pPlayer->m_ForcePauseTime > 0) + { + str_format(aBuf, sizeof(aBuf), "You have been force-paused. %ds left.", pPlayer->m_ForcePauseTime/pSelf->Server()->TickSpeed()); + pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", aBuf); + } + else if(pPlayer->m_ForcePauseTime < 0) + { + pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You have been force-paused."); + } else pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "No pause data saved."); } @@ -493,6 +503,72 @@ void CGameContext::ConTogglePause(IConsole::IResult *pResult, void *pUserData, i pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "Pause isn't allowed on this server."); } +void CGameContext::ConForcePause(IConsole::IResult *pResult, void *pUserData, int ClientID) +{ + CGameContext *pSelf = (CGameContext *)pUserData; + CServer* pServ = (CServer*)pSelf->Server(); + int Victim = pResult->GetVictim(); + int Seconds; + char aBuf[128]; + + if(pResult->NumArguments() > 0) + Seconds = pResult->GetInteger(0); + else + Seconds = g_Config.m_SvVotePauseTime; + + CPlayer *pPlayer = pSelf->m_apPlayers[Victim]; + if(!pPlayer) + return; + + CCharacter* pChr = pPlayer->GetCharacter(); + if(!pPlayer->GetTeam() && pChr && !pPlayer->m_InfoSaved) + { + pPlayer->SaveCharacter(); + pPlayer->m_InfoSaved = true; + pPlayer->SetTeam(TEAM_SPECTATORS); + pPlayer->m_ForcePauseTime = Seconds*pServ->TickSpeed(); + } + else + { + pPlayer->m_ForcePauseTime = Seconds*pServ->TickSpeed(); + } + if(ClientID < 0) + str_format(aBuf, sizeof(aBuf), "'%s' has been force-paused for %d seconds", pServ->ClientName(Victim), Seconds); + else + str_format(aBuf, sizeof(aBuf), "'%s' has been force-paused for %d seconds by '%s'", pServ->ClientName(Victim), Seconds, pServ->ClientName(ClientID)); + pSelf->SendChat(-1, CHAT_ALL, aBuf); +} + +void CGameContext::ConForceUnpause(IConsole::IResult *pResult, void *pUserData, int ClientID) +{ + CGameContext *pSelf = (CGameContext *)pUserData; + CServer* pServ = (CServer*)pSelf->Server(); + int Victim = pResult->GetVictim(); + char aBuf[128]; + + CPlayer *pPlayer = pSelf->m_apPlayers[Victim]; + if(!pPlayer) + return; + + if(pPlayer->GetTeam()==TEAM_SPECTATORS && pPlayer->m_InfoSaved) + { + pPlayer->m_PauseInfo.m_Respawn = true; + pPlayer->SetTeam(TEAM_RED); + pPlayer->m_InfoSaved = false; + //pPlayer->LoadCharacter();//TODO:Check if this system Works + pPlayer->m_ForcePauseTime = 0; + } + else // Shouldn't be reached + { + pPlayer->m_ForcePauseTime = 0; + } + if(ClientID < 0) + str_format(aBuf, sizeof(aBuf), "'%s' has been force-unpaused", pServ->ClientName(Victim)); + else + str_format(aBuf, sizeof(aBuf), "'%s' has been force-unpaused by '%s'", pServ->ClientName(Victim), pServ->ClientName(ClientID)); + pSelf->SendChat(-1, CHAT_ALL, aBuf); +} + void CGameContext::ConTop5(IConsole::IResult *pResult, void *pUserData, int ClientID) { CGameContext *pSelf = (CGameContext *)pUserData; diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index e9a983e50..7dd0ff614 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -942,9 +942,18 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) return; } - str_format(aChatmsg, sizeof(aChatmsg), "'%s' called for vote to move '%s' to spectators (%s)", Server()->ClientName(ClientID), Server()->ClientName(SpectateID), pReason); - str_format(aDesc, sizeof(aDesc), "move '%s' to spectators", Server()->ClientName(SpectateID)); - str_format(aCmd, sizeof(aCmd), "set_team %d -1", SpectateID); + if(g_Config.m_SvPauseable && g_Config.m_SvVotePause) + { + str_format(aChatmsg, sizeof(aChatmsg), "'%s' called for vote to pause '%s' for %d seconds (%s)", Server()->ClientName(ClientID), Server()->ClientName(SpectateID), g_Config.m_SvVotePauseTime, pReason); + str_format(aDesc, sizeof(aDesc), "Pause '%s' (%ds)", Server()->ClientName(SpectateID), g_Config.m_SvVotePauseTime); + str_format(aCmd, sizeof(aCmd), "force_pause %d", SpectateID); + } + else + { + str_format(aChatmsg, sizeof(aChatmsg), "'%s' called for vote to move '%s' to spectators (%s)", Server()->ClientName(ClientID), Server()->ClientName(SpectateID), pReason); + str_format(aDesc, sizeof(aDesc), "move '%s' to spectators", Server()->ClientName(SpectateID)); + str_format(aCmd, sizeof(aCmd), "set_team %d -1", SpectateID); + } } if(aCmd[0]) diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index 6d5775606..6be95466e 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -218,6 +218,8 @@ private: static void ConRules(IConsole::IResult *pResult, void *pUserData, int ClientID); static void ConKill(IConsole::IResult *pResult, void *pUserData, int ClientID); static void ConTogglePause(IConsole::IResult *pResult, void *pUserData, int ClientID); + static void ConForcePause(IConsole::IResult *pResult, void *pUserData, int ClientID); + static void ConForceUnpause(IConsole::IResult *pResult, void *pUserData, int ClientID); static void ConTop5(IConsole::IResult *pResult, void *pUserData, int ClientID); #if defined(CONF_SQL) static void ConTimes(IConsole::IResult *pResult, void *pUserData, int ClientID); diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index 2510b5528..6b9bf5002 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -64,6 +64,16 @@ void CPlayer::Tick() if (m_ChatScore > 0) m_ChatScore--; + if (g_Config.m_SvVotePauseAuto && m_ForcePauseTime==1 && GetTeam()==TEAM_SPECTATORS && m_InfoSaved) + { + m_InfoSaved = false; + m_PauseInfo.m_Respawn = true; + SetTeam(TEAM_RED); + } + + if (m_ForcePauseTime > 0) + m_ForcePauseTime--; + Server()->SetClientScore(m_ClientID, m_Score); // do latency stuff diff --git a/src/game/server/player.h b/src/game/server/player.h index 26ce411ab..db40cbc9b 100644 --- a/src/game/server/player.h +++ b/src/game/server/player.h @@ -134,6 +134,7 @@ public: int m_CpActive; float m_CpCurrent[25]; } m_PauseInfo; + int m_ForcePauseTime; bool m_InfoSaved; bool IsPlaying(); void LoadCharacter(); diff --git a/src/game/variables.h b/src/game/variables.h index 31dbd973b..072cf7953 100644 --- a/src/game/variables.h +++ b/src/game/variables.h @@ -78,6 +78,9 @@ MACRO_CONFIG_INT(SvVoteKick, sv_vote_kick, 1, 0, 1, CFGFLAG_SERVER, "Allow votin MACRO_CONFIG_INT(SvVoteKickMin, sv_vote_kick_min, 0, 0, MAX_CLIENTS, CFGFLAG_SERVER, "Minimum number of players required to start a kick vote", IConsole::CONSOLELEVEL_ADMIN) MACRO_CONFIG_INT(SvVoteKickBantime, sv_vote_kick_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time to ban a player if kicked by vote. 0 makes it just use kick", IConsole::CONSOLELEVEL_ADMIN) +MACRO_CONFIG_INT(SvVotePause, sv_vote_pause, 1, 0, 1, CFGFLAG_SERVER, "Allow voting to pause players (instead of moving to spectators)", IConsole::CONSOLELEVEL_ADMIN) +MACRO_CONFIG_INT(SvVotePauseTime, sv_vote_pause_time, 60, 0, 3600, CFGFLAG_SERVER, "The time (in seconds) players have to wait in pause when paused by vote", IConsole::CONSOLELEVEL_ADMIN) +MACRO_CONFIG_INT(SvVotePauseAuto, sv_vote_pause_auto, 0, 0, 1, CFGFLAG_SERVER, "Automatically unpaused players after the force-pause delay or not", IConsole::CONSOLELEVEL_ADMIN) // debug #ifdef CONF_DEBUG // this one can crash the server if not used correctly MACRO_CONFIG_INT(DbgDummies, dbg_dummies, 0, 0, 15, CFGFLAG_SERVER, "", IConsole::CONSOLELEVEL_ADMIN)