using Sandbox.Engine;
using Sandbox.Tasks;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace Sandbox;
///
/// Used to create standalone tools that can still interop to the engine
///
public class ToolAppSystem : AppSystem, IDisposable
{
public static BaseFileSystem Content => EngineFileSystem.CoreContent;
public void Dispose()
{
Shutdown();
}
public ToolAppSystem()
{
InitEnginePaths();
Init();
}
public override void Init()
{
TestSystemRequirements();
base.Init();
// CreateGame();
// CreateMenu();
var createInfo = new AppSystemCreateInfo()
{
WindowTitle = "s&box tool",
Flags = AppSystemFlags.IsConsoleApp | AppSystemFlags.IsEditor
};
InitTool( createInfo );
AddSearchPaths( System.Environment.GetCommandLineArgs() );
}
protected void InitTool( AppSystemCreateInfo createInfo )
{
var commandLine = System.Environment.CommandLine;
commandLine = commandLine.Replace( ".dll", ".exe" ); // uck
_appSystem = CMaterialSystem2AppSystemDict.Create( createInfo.ToMaterialSystem2AppSystemDictCreateInfo() );
_appSystem.SetModGameSubdir( "core" );
_appSystem.SetInToolsMode();
_appSystem.SetSteamAppId( (uint)Application.AppId );
//_appSystem.Init();
if ( !NativeEngine.EngineGlobal.SourceEnginePreInit( commandLine, _appSystem ) )
{
throw new System.Exception( "SourceEnginePreInit failed" );
}
_appSystem.AddSystem( "resourcecompiler", "ResourceCompilerSystem001" );
Bootstrap.PreInit( _appSystem );
//Bootstrap.Init();
}
static void AddSearchPaths( string[] args )
{
var i = Array.IndexOf( args, "-searchpaths" );
if ( i < 0 ) return;
var paths = args[i + 1];
foreach ( var path in paths.Split( ";" ) )
{
var parts = path.Split( "|" );
EngineFileSystem.AddContentPath( parts[1] );
}
}
///
/// We want to set current dir to /game/
/// and add the native dll paths to the path
///
void InitEnginePaths()
{
var exePath = Environment.GetCommandLineArgs()[0];
exePath = System.IO.Path.GetDirectoryName( exePath );
// we're in the managed folder, we can set this shit up
if ( exePath.EndsWith( "bin\\managed", StringComparison.OrdinalIgnoreCase ) )
{
var dirInfo = new DirectoryInfo( exePath );
var gameRoot = dirInfo.Parent.Parent;
Environment.CurrentDirectory = gameRoot.FullName;
var nativeDllPath = $"{gameRoot.FullName}\\bin\\win64";
//
// If we don't load sentry specifically from this directly, it'll
// try to load the one from the managed folder
//
NativeLibrary.TryLoad( $"{nativeDllPath}\\sentry.dll", out _ );
//NativeLibrary.TryLoad( $"{nativeDllPath}\\tier0.dll", out _ );
//NativeLibrary.TryLoad( $"{nativeDllPath}\\engine2.dll", out _ );
//
// Put our native dll path first so that when looking up native dlls we'll
// always use the ones from our folder first
//
var path = System.Environment.GetEnvironmentVariable( "PATH" );
path = $"{nativeDllPath};{path}";
System.Environment.SetEnvironmentVariable( "PATH", path );
return;
}
throw new Exception( "Unknown Location" );
}
}