mirror of
https://github.com/Facepunch/sbox-public.git
synced 2025-12-23 22:48:07 -05:00
This commit imports the C# engine code and game files, excluding C++ source code. [Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
125 lines
3.2 KiB
C#
125 lines
3.2 KiB
C#
using Sandbox.Engine;
|
|
|
|
namespace Sandbox;
|
|
|
|
public static partial class MenuUtility
|
|
{
|
|
static CancellationTokenSource gameLoadingCts = new CancellationTokenSource();
|
|
|
|
/// <summary>
|
|
/// Close the current game.
|
|
/// </summary>
|
|
public static void CloseGame()
|
|
{
|
|
// Editor only: just exit playmode
|
|
if ( IToolsDll.Current is not null )
|
|
{
|
|
IToolsDll.Current.ExitPlaymode();
|
|
return;
|
|
}
|
|
|
|
gameLoadingCts?.Cancel();
|
|
|
|
if ( IGameInstance.Current is not null )
|
|
{
|
|
IGameInstance.Current?.Close();
|
|
}
|
|
else
|
|
{
|
|
// Conna: game instance will call disconnect. If we don't have a game instance then we
|
|
// need to call it ourselves.
|
|
Networking.Disconnect();
|
|
|
|
Application.ClearGame();
|
|
}
|
|
|
|
LaunchArguments.Reset();
|
|
}
|
|
|
|
/// <summary>
|
|
/// A game has been opened. Load the game. If allowLaunchOverride then special launch conditions will be obeyed.
|
|
/// For example, we might join a lobby instead of loading the game, or we might open the launcher.
|
|
/// </summary>
|
|
public static void OpenGame( string ident, bool allowLaunchOverride = true, Dictionary<string, string> gameSettings = null )
|
|
{
|
|
gameLoadingCts?.Cancel();
|
|
gameLoadingCts = new CancellationTokenSource();
|
|
|
|
if ( gameSettings is not null ) LaunchArguments.GameSettings = gameSettings;
|
|
_ = LoadAsync( ident, allowLaunchOverride, gameLoadingCts.Token );
|
|
}
|
|
|
|
/// <summary>
|
|
/// A game has been opened. Load the game.
|
|
/// </summary>
|
|
public static void OpenGameWithMap( string gameident, string mapName, Dictionary<string, string> gameSettings = null )
|
|
{
|
|
LaunchArguments.Map = mapName;
|
|
if ( gameSettings is not null ) LaunchArguments.GameSettings = gameSettings;
|
|
|
|
OpenGame( gameident, false );
|
|
}
|
|
|
|
static async Task LoadAsync( string ident, bool allowLaunchOverride, CancellationToken ct )
|
|
{
|
|
ThreadSafe.AssertIsMainThread();
|
|
LoadingScreen.IsVisible = true;
|
|
LoadingScreen.Media = null;
|
|
LoadingScreen.Title = "Loading Game..";
|
|
|
|
var package = await Package.FetchAsync( ident, false );
|
|
if ( package is not null )
|
|
{
|
|
LoadingScreen.Title = package.Title;
|
|
LoadingScreen.Media = package.LoadingScreen.MediaUrl;
|
|
}
|
|
|
|
var flags = GameLoadingFlags.Host | GameLoadingFlags.Reload;
|
|
if ( Application.IsEditor ) flags |= GameLoadingFlags.Developer; // todo - is the package we're loading a local package
|
|
|
|
await IGameInstanceDll.Current.LoadGamePackageAsync( ident, flags, ct );
|
|
}
|
|
|
|
static bool _isJoiningLobby;
|
|
|
|
/// <summary>
|
|
/// Try to join any lobby for this game.
|
|
/// </summary>
|
|
public static async Task<bool> TryJoinLobby( string ident )
|
|
{
|
|
if ( _isJoiningLobby )
|
|
return false;
|
|
|
|
try
|
|
{
|
|
_isJoiningLobby = true;
|
|
|
|
var lobbies = await Networking.QueryLobbies( ident );
|
|
|
|
var orderedLobbies = lobbies.OrderBy( lobby => lobby.ContainsFriends )
|
|
.ThenByDescending( lobby => lobby.Members );
|
|
|
|
foreach ( var lobby in orderedLobbies )
|
|
{
|
|
if ( lobby.IsFull ) continue;
|
|
|
|
// We might be in a game now
|
|
if ( Game.InGame ) return false;
|
|
|
|
Log.Info( $"Attempting to join available lobby {lobby.LobbyId}" );
|
|
|
|
// Try to join this one
|
|
if ( await Networking.TryConnectSteamId( lobby.LobbyId ) )
|
|
return true;
|
|
}
|
|
|
|
Log.Info( $"Couldn't join a lobby - making a game" );
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
_isJoiningLobby = false;
|
|
}
|
|
}
|
|
}
|