2022-11-08 20:02:07 +00:00
using System.Linq ;
2021-06-20 10:09:24 +02:00
using Content.Shared.GameTicking ;
2022-11-07 18:18:21 -08:00
using Content.Server.Station.Components ;
2021-06-20 10:09:24 +02:00
using Robust.Shared.Network ;
using Robust.Shared.Player ;
2022-11-07 18:18:21 -08:00
using System.Text ;
2024-01-28 18:37:24 +07:00
using Content.Shared._White ;
2021-06-20 10:09:24 +02:00
namespace Content.Server.GameTicking
{
2022-02-16 00:23:23 -07:00
public sealed partial class GameTicker
2021-06-20 10:09:24 +02:00
{
[ViewVariables]
2022-08-14 12:54:49 -07:00
private readonly Dictionary < NetUserId , PlayerGameStatus > _playerGameStatuses = new ( ) ;
2022-01-19 17:01:21 -06:00
2021-06-20 10:09:24 +02:00
[ViewVariables]
private TimeSpan _roundStartTime ;
2023-03-22 20:29:55 +11:00
/// <summary>
/// How long before RoundStartTime do we load maps.
/// </summary>
[ViewVariables]
public TimeSpan RoundPreloadTime { get ; } = TimeSpan . FromSeconds ( 15 ) ;
2021-06-20 10:09:24 +02:00
[ViewVariables]
private TimeSpan _pauseTime ;
[ViewVariables]
2022-01-21 01:38:35 -08:00
public new bool Paused { get ; set ; }
2021-06-20 10:09:24 +02:00
[ViewVariables]
private bool _roundStartCountdownHasNotStartedYetDueToNoPlayers ;
2022-08-14 12:54:49 -07:00
/// <summary>
/// The game status of a players user Id. May contain disconnected players
/// </summary>
public IReadOnlyDictionary < NetUserId , PlayerGameStatus > PlayerGameStatuses = > _playerGameStatuses ;
2021-09-23 13:00:28 +02:00
2022-04-15 13:55:38 -05:00
public void UpdateInfoText ( )
2021-06-20 10:09:24 +02:00
{
2022-08-14 12:54:49 -07:00
RaiseNetworkEvent ( GetInfoMsg ( ) , Filter . Empty ( ) . AddPlayers ( _playerManager . NetworkedSessions ) ) ;
2021-06-20 10:09:24 +02:00
}
private string GetInfoText ( )
{
2023-08-01 17:11:50 -04:00
var preset = CurrentPreset ? ? Preset ;
if ( preset = = null )
2021-06-20 10:09:24 +02:00
{
return string . Empty ;
}
2022-11-08 20:02:07 +00:00
2022-04-04 05:39:42 +00:00
var playerCount = $"{_playerManager.PlayerCount}" ;
2022-11-08 20:02:07 +00:00
var readyCount = _playerGameStatuses . Values . Count ( x = > x = = PlayerGameStatus . ReadyToPlay ) ;
2022-11-07 18:18:21 -08:00
2023-05-19 15:45:09 -05:00
var stationNames = new StringBuilder ( ) ;
var query =
EntityQueryEnumerator < StationJobsComponent , StationSpawningComponent , MetaDataComponent > ( ) ;
var foundOne = false ;
while ( query . MoveNext ( out _ , out _ , out var meta ) )
2022-11-07 18:18:21 -08:00
{
2023-05-19 15:45:09 -05:00
foundOne = true ;
if ( stationNames . Length > 0 )
stationNames . Append ( '\n' ) ;
stationNames . Append ( meta . EntityName ) ;
2022-11-07 18:18:21 -08:00
}
2023-05-19 15:45:09 -05:00
if ( ! foundOne )
2022-11-07 18:18:21 -08:00
{
2023-12-30 21:51:36 +04:00
stationNames . Append ( _gameMapManager . GetSelectedMap ( ) ? . MapName ? ?
Loc . GetString ( "game-ticker-no-map-selected" ) ) ;
2022-11-07 18:18:21 -08:00
}
2022-11-08 20:02:07 +00:00
2023-08-01 17:11:50 -04:00
var gmTitle = Loc . GetString ( preset . ModeTitle ) ;
var desc = Loc . GetString ( preset . Description ) ;
2023-12-30 21:51:36 +04:00
return Loc . GetString (
RunLevel = = GameRunLevel . PreRoundLobby
? "game-ticker-get-info-preround-text"
: "game-ticker-get-info-text" ,
( "roundId" , RoundId ) ,
( "playerCount" , playerCount ) ,
( "readyCount" , readyCount ) ,
( "mapName" , stationNames . ToString ( ) ) ,
( "gmTitle" , gmTitle ) ,
( "desc" , desc ) ) ;
2021-06-20 10:09:24 +02:00
}
2024-01-07 21:30:10 -03:00
private TickerConnectionStatusEvent GetConnectionStatusMsg ( )
{
return new TickerConnectionStatusEvent ( RoundStartTimeSpan ) ;
}
2023-10-28 09:59:53 +11:00
private TickerLobbyStatusEvent GetStatusMsg ( ICommonSession session )
2021-06-20 10:09:24 +02:00
{
2022-08-14 12:54:49 -07:00
_playerGameStatuses . TryGetValue ( session . UserId , out var status ) ;
2024-03-02 23:40:04 +03:00
return new TickerLobbyStatusEvent ( RunLevel ! = GameRunLevel . PreRoundLobby , LobbyBackground , status = = PlayerGameStatus . ReadyToPlay , _roundStartTime , RoundPreloadTime , RoundStartTimeSpan , Paused ) ;
2021-06-20 10:09:24 +02:00
}
private void SendStatusToAll ( )
{
2023-10-28 09:59:53 +11:00
foreach ( var player in _playerManager . Sessions )
2021-06-20 10:09:24 +02:00
{
2024-01-22 23:14:13 +01:00
RaiseNetworkEvent ( GetStatusMsg ( player ) , player . Channel ) ;
2021-06-20 10:09:24 +02:00
}
}
private TickerLobbyInfoEvent GetInfoMsg ( )
{
return new ( GetInfoText ( ) ) ;
}
private void UpdateLateJoinStatus ( )
{
RaiseNetworkEvent ( new TickerLateJoinStatusEvent ( DisallowLateJoin ) ) ;
}
public bool PauseStart ( bool pause = true )
{
if ( Paused = = pause )
{
return false ;
}
Paused = pause ;
if ( pause )
{
_pauseTime = _gameTiming . CurTime ;
}
else if ( _pauseTime ! = default )
{
_roundStartTime + = _gameTiming . CurTime - _pauseTime ;
}
RaiseNetworkEvent ( new TickerLobbyCountdownEvent ( _roundStartTime , Paused ) ) ;
2021-06-21 02:13:54 +02:00
_chatManager . DispatchServerAnnouncement ( Loc . GetString ( Paused
? "game-ticker-pause-start"
: "game-ticker-pause-start-resumed" ) ) ;
2021-06-20 10:09:24 +02:00
return true ;
}
public bool TogglePause ( )
{
PauseStart ( ! Paused ) ;
return Paused ;
}
2022-08-14 12:54:49 -07:00
public void ToggleReadyAll ( bool ready )
{
var status = ready ? PlayerGameStatus . ReadyToPlay : PlayerGameStatus . NotReadyToPlay ;
foreach ( var playerUserId in _playerGameStatuses . Keys )
{
_playerGameStatuses [ playerUserId ] = status ;
if ( ! _playerManager . TryGetSessionById ( playerUserId , out var playerSession ) )
continue ;
2024-01-22 23:14:13 +01:00
RaiseNetworkEvent ( GetStatusMsg ( playerSession ) , playerSession . Channel ) ;
2022-08-14 12:54:49 -07:00
}
}
2023-10-28 09:59:53 +11:00
public void ToggleReady ( ICommonSession player , bool ready )
2021-06-20 10:09:24 +02:00
{
2022-08-14 12:54:49 -07:00
if ( ! _playerGameStatuses . ContainsKey ( player . UserId ) )
2022-08-07 08:00:42 +02:00
return ;
2021-06-20 10:09:24 +02:00
2022-08-07 08:00:42 +02:00
if ( ! _userDb . IsLoadComplete ( player ) )
2021-06-20 10:09:24 +02:00
return ;
2023-04-28 22:47:26 +03:00
if ( RunLevel ! = GameRunLevel . PreRoundLobby )
{
return ;
}
2023-04-27 21:56:22 +06:00
if ( _configurationManager . GetCVar ( WhiteCVars . StalinEnabled ) )
{
_chatManager . DispatchServerMessage ( player , "Внимание, на сервере включен бункер. Если ваш аккаунт не был привязан к дискорду, то вы не сможете зайти в раунд. Для того чтобы привязать аккаунт - нажмите на кнопку ПРИВЯЗАТЬ А К К А У Н Т " ) ;
}
2022-08-14 12:54:49 -07:00
var status = ready ? PlayerGameStatus . ReadyToPlay : PlayerGameStatus . NotReadyToPlay ;
_playerGameStatuses [ player . UserId ] = ready ? PlayerGameStatus . ReadyToPlay : PlayerGameStatus . NotReadyToPlay ;
2024-01-22 23:14:13 +01:00
RaiseNetworkEvent ( GetStatusMsg ( player ) , player . Channel ) ;
2022-11-08 20:02:07 +00:00
// update server info to reflect new ready count
UpdateInfoText ( ) ;
2021-06-20 10:09:24 +02:00
}
}
}