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]
375 lines
9.3 KiB
C#
375 lines
9.3 KiB
C#
using Sandbox.Engine;
|
|
using Sandbox.Engine.Settings;
|
|
using Sandbox.Modals;
|
|
using Sandbox.Services;
|
|
using System;
|
|
using System.Net;
|
|
|
|
namespace Sandbox;
|
|
|
|
|
|
[Hide]
|
|
public static partial class MenuUtility
|
|
{
|
|
public static Action Tick { get; set; }
|
|
|
|
public static void SetModalSystem( IModalSystem system )
|
|
{
|
|
IModalSystem.Current = system;
|
|
}
|
|
|
|
public static void AddLogger( Action<LogEvent> logger )
|
|
{
|
|
Sandbox.Diagnostics.Logging.OnMessage += logger;
|
|
}
|
|
|
|
public static void RemoveLogger( Action<LogEvent> logger )
|
|
{
|
|
Sandbox.Diagnostics.Logging.OnMessage -= logger;
|
|
}
|
|
|
|
public static ConCmdAttribute.AutoCompleteResult[] AutoComplete( string text, int maxCount )
|
|
{
|
|
return ConVarSystem.GetAutoComplete( text, maxCount );
|
|
}
|
|
|
|
public static void SkipAllTransitions()
|
|
{
|
|
IMenuDll.Current?.RunEvent( "ui.skiptransitions" );
|
|
}
|
|
|
|
/// <summary>
|
|
/// If current game is active, return the package
|
|
/// </summary>
|
|
public static Package GamePackage => Application.GamePackage;
|
|
|
|
/// <summary>
|
|
/// Init a stream service
|
|
/// </summary>
|
|
public static async Task<bool> ConnectStream( StreamService service )
|
|
{
|
|
return await Sandbox.Engine.Streamer.Init( service );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Init a stream service
|
|
/// </summary>
|
|
public static void DisconnectStream()
|
|
{
|
|
Sandbox.Engine.Streamer.Shutdown();
|
|
}
|
|
|
|
public static SceneWorld CreateSceneWorld()
|
|
{
|
|
return new SceneWorld { IsTransient = false };
|
|
}
|
|
|
|
#nullable enable
|
|
/// <summary>
|
|
/// Open an 'open file' dialog
|
|
/// </summary>
|
|
public static string? OpenFileDialog()
|
|
{
|
|
var r = NativeEngine.WindowsGlue.FindFile();
|
|
if ( string.IsNullOrEmpty( r ) ) return null;
|
|
return r;
|
|
}
|
|
#nullable disable
|
|
|
|
/// <summary>
|
|
/// Open a folder
|
|
/// </summary>
|
|
public static void OpenFolder( string path )
|
|
{
|
|
System.Diagnostics.Process.Start( new System.Diagnostics.ProcessStartInfo()
|
|
{
|
|
FileName = path,
|
|
UseShellExecute = true,
|
|
Verb = "open"
|
|
} );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Open a url
|
|
/// </summary>
|
|
public static void OpenUrl( string path )
|
|
{
|
|
System.Diagnostics.Process.Start( new System.Diagnostics.ProcessStartInfo()
|
|
{
|
|
FileName = path,
|
|
UseShellExecute = true,
|
|
Verb = "open"
|
|
} );
|
|
}
|
|
|
|
static List<Friend> _friendList;
|
|
|
|
/// <summary>
|
|
/// Get all friends.
|
|
/// </summary>
|
|
public static IEnumerable<Friend> Friends
|
|
{
|
|
get
|
|
{
|
|
//
|
|
// querying this once should be enough, unless they add a new friend or something
|
|
//
|
|
if ( _friendList is null )
|
|
{
|
|
_friendList = Steamworks.SteamFriends.GetFriends().Select( x => new Friend( x ) ).ToList();
|
|
}
|
|
|
|
return _friendList;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Number of seconds escape has been held down
|
|
/// </summary>
|
|
public static float EscapeTime => InputRouter.EscapeTime;
|
|
|
|
/// <summary>
|
|
/// Join the game a friend is in
|
|
/// </summary>
|
|
public static void JoinFriendGame( Friend friend )
|
|
{
|
|
var connectString = friend.GetRichPresence( "connect" );
|
|
if ( string.IsNullOrWhiteSpace( connectString ) ) return;
|
|
|
|
connectString = connectString.Replace( "+connect", "" );
|
|
connectString = connectString.Replace( " ", "" );
|
|
|
|
// Should be left with a Steam Id but otherwise try connecting by IP.
|
|
if ( ulong.TryParse( connectString, out ulong lobbySteamId ) )
|
|
{
|
|
ConsoleSystem.Run( $"connect {lobbySteamId}" );
|
|
}
|
|
else
|
|
{
|
|
var ipAddress = IPEndPoint.Parse( connectString );
|
|
ConsoleSystem.Run( $"connect {ipAddress}" );
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// We might be running the game from sbox.game, so we want the menu system to open the game immediately
|
|
/// </summary>
|
|
public static string StartupGameIdent => Utility.CommandLine.GetSwitch( "-rungame", null );
|
|
|
|
/// <summary>
|
|
/// This is called when the cancel button is pressed when loading.
|
|
/// We should disconnect and leave the game.
|
|
/// </summary>
|
|
public static void CancelLoading()
|
|
{
|
|
// Close the game
|
|
CloseGame();
|
|
|
|
// Close the loading screen
|
|
LoadingScreen.IsVisible = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Set a console variable. Unlike ConsoleSystem.*, this is unprotected and allows any console variable to be changed.
|
|
/// </summary>
|
|
public static void SetConsoleVariable( string name, object value )
|
|
{
|
|
ConVarSystem.SetValue( name, value?.ToString(), true );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Access to the client's render settings
|
|
/// </summary>
|
|
public static RenderSettings RenderSettings => Sandbox.Engine.Settings.RenderSettings.Instance;
|
|
|
|
/// <summary>
|
|
/// Listen to the voice
|
|
/// </summary>
|
|
public static void SetVoiceListen( bool b )
|
|
{
|
|
if ( b )
|
|
{
|
|
PartyRoom.Current?.SetBroadcastVoice();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Close every open modal
|
|
/// </summary>
|
|
public static void CloseAllModals()
|
|
{
|
|
IModalSystem.Current?.CloseAll();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the player's friend activity feed
|
|
/// </summary>
|
|
public static Task<Feed[]> GetPlayerFeed( int take = 20 ) => Feed.GetFeed( take );
|
|
|
|
/// <summary>
|
|
/// How many notifications does the player have?
|
|
/// </summary>
|
|
public static Task<int> GetNotificationCount() => Notification.GetCount();
|
|
|
|
/// <summary>
|
|
/// Mark the player's notifications as all read. Call when viewing notifications.
|
|
/// </summary>
|
|
public static Task<int> MarkNotificationsRead() => Notification.MarkRead();
|
|
|
|
/// <summary>
|
|
/// Get a list of notifications
|
|
/// </summary>
|
|
public static Task<Notification[]> GetNotifications( int count ) => Notification.Get( count );
|
|
|
|
/// <summary>
|
|
/// Get a list of recent achievement progress
|
|
/// </summary>
|
|
public static Task<AchievementOverview[]> GetAchievementOverviews( int count ) => AchievementOverview.GetFeed( count );
|
|
|
|
/// <summary>
|
|
/// Get a list of recent achievement progress
|
|
/// </summary>
|
|
public static Task SaveAvatar( ClothingContainer container, bool isActive, int slot ) => container.Store( isActive, slot );
|
|
|
|
/// <summary>
|
|
/// Delete avatar in slot x
|
|
/// </summary>
|
|
public static Task DeleteAvatar( int slot )
|
|
{
|
|
return Backend.Storage.Delete( (long)Utility.Steam.SteamId, "facepunch.avatar", "avatar", $"{slot}" );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete all avatars, return to default
|
|
/// </summary>
|
|
public static async Task DeleteAvatars()
|
|
{
|
|
await Backend.Storage.Drop( (long)Utility.Steam.SteamId, "facepunch.avatar", "avatar" );
|
|
await Backend.Storage.Drop( (long)Utility.Steam.SteamId, "facepunch.avatar", "avatar.active" );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invite someone to the current party. If one exists
|
|
/// </summary>
|
|
public static void InviteToParty( SteamId steamid )
|
|
{
|
|
PartyRoom.Current?.InviteFriend( steamid );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opens the invite overlay
|
|
/// </summary>
|
|
public static void InviteOverlayToParty()
|
|
{
|
|
PartyRoom.Current?.InviteFriend();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Post a review for a package
|
|
/// </summary>
|
|
public static Task PostReview( string packageIdent, Sandbox.Services.Review.ReviewScore score, string content )
|
|
{
|
|
return Sandbox.Services.Review.Post( packageIdent, score, content );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Allows async tasks to wait to be executed in the menu context
|
|
/// </summary>
|
|
public static void RunTask( Func<Task> func )
|
|
{
|
|
if ( Application.IsEditor ) func();
|
|
|
|
// Post the *whole* function into the target context
|
|
MenuDll.AsyncContext.Post( async _ =>
|
|
{
|
|
await func().ConfigureAwait( true );
|
|
|
|
}, null );
|
|
}
|
|
|
|
}
|
|
|
|
public class StoragePublish
|
|
{
|
|
Ugc.UgcPublisher item;
|
|
|
|
public ulong ItemId => item?.ItemId ?? 0;
|
|
|
|
public string Title { get; set; }
|
|
public string Description { get; set; }
|
|
public string Metadata { get; set; }
|
|
public Storage.Visibility Visibility { get; set; } = Storage.Visibility.Public;
|
|
public Dictionary<string, string> KeyValues { get; set; }
|
|
public HashSet<string> Tags { get; set; }
|
|
public Bitmap Thumbnail { get; set; }
|
|
public BaseFileSystem FileSystem { get; set; }
|
|
|
|
public async Task Submit()
|
|
{
|
|
item = await Sandbox.Services.Ugc.CreateCommunityItem();
|
|
|
|
string _imagePath = null;
|
|
string _dataPath = null;
|
|
|
|
item.SetTitle( Title );
|
|
item.SetDescription( Description );
|
|
item.SetMetaData( Metadata );
|
|
item.SetVisibility( Visibility );
|
|
|
|
if ( KeyValues != null )
|
|
{
|
|
foreach ( var kv in KeyValues )
|
|
{
|
|
item.SetKeyValue( kv.Key, kv.Value );
|
|
}
|
|
}
|
|
|
|
if ( Tags != null )
|
|
{
|
|
foreach ( var tag in Tags )
|
|
{
|
|
item.SetTag( tag );
|
|
}
|
|
}
|
|
|
|
// Save thumbnail to a temp file
|
|
if ( Thumbnail != null )
|
|
{
|
|
_imagePath = System.IO.Path.GetTempFileName() + ".png";
|
|
System.IO.File.WriteAllBytes( _imagePath, Thumbnail.ToPng() );
|
|
item.SetPreviewImage( _imagePath );
|
|
}
|
|
|
|
// Copy files from virtual filesystem to a temp folder
|
|
if ( FileSystem != null )
|
|
{
|
|
_dataPath = System.IO.Path.GetTempPath() + "/" + System.Guid.NewGuid().ToString();
|
|
var files = FileSystem.FindFile( "/", "*", true );
|
|
|
|
foreach ( var file in files )
|
|
{
|
|
var srcPath = System.IO.Path.Combine( "/", file );
|
|
var destPath = System.IO.Path.Combine( _dataPath, file );
|
|
|
|
System.IO.Directory.CreateDirectory( System.IO.Path.GetDirectoryName( destPath ) );
|
|
System.IO.File.WriteAllBytes( destPath, FileSystem.ReadAllBytes( srcPath ) );
|
|
}
|
|
|
|
item.SetContentFile( _dataPath );
|
|
}
|
|
|
|
item.SetKeyValue( "package", Game.Ident ); // TODO - walk the stack to determine what called it?
|
|
item.SetKeyValue( "version", Application.Version );
|
|
|
|
await item.Submit();
|
|
|
|
if ( _imagePath != null ) System.IO.File.Delete( _imagePath );
|
|
if ( _dataPath != null ) System.IO.Directory.Delete( _dataPath, true );
|
|
}
|
|
|
|
public float PercentComplete => item?.PercentComplete ?? 0f;
|
|
public bool IsPublishing => item?.IsPublishing ?? false;
|
|
public bool IsFinished => item?.IsFinished ?? false;
|
|
}
|