diff --git a/Runtimes/NET/BepisLoader/BepisLoader.cs b/Runtimes/NET/BepisLoader/BepisLoader.cs index 9e83cbb1..a243b9d7 100644 --- a/Runtimes/NET/BepisLoader/BepisLoader.cs +++ b/Runtimes/NET/BepisLoader/BepisLoader.cs @@ -1,4 +1,3 @@ -using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; using System.Runtime.Loader; @@ -11,10 +10,11 @@ public class BepisLoader internal static AssemblyLoadContext alc = null!; static void Main(string[] args) { + resoDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); #if DEBUG - File.WriteAllText("BepisLoader.log", "BepisLoader started\n"); + logPath = Path.Combine(resoDir, "BepisLoader.log"); + File.WriteAllText(logPath, "BepisLoader started\n"); #endif - resoDir = Directory.GetCurrentDirectory(); alc = new BepisLoadContext(); @@ -31,20 +31,6 @@ static void Main(string[] args) var asm = alc.LoadFromAssemblyPath(Path.Combine(bepinPath, "core", "BepInEx.NET.CoreCLR.dll")); - // Check if we're launching from outside the game directory - var exePath = Process.GetCurrentProcess().MainModule?.FileName; - if (exePath != null) - { - var exeDir = Path.GetDirectoryName(exePath); - if (exeDir != resoDir) - { - // Change working directory to the game directory for direct launches - Log($"Changing working directory from {resoDir} to {exeDir}"); - Directory.SetCurrentDirectory(exeDir); - resoDir = exeDir; - } - } - var resoDllPath = Path.Combine(resoDir, "Renderite.Host.dll"); if (!File.Exists(resoDllPath)) resoDllPath = Path.Combine(resoDir, "Resonite.dll"); @@ -54,18 +40,19 @@ static void Main(string[] args) // Find and load Resonite var resoAsm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.GetName().Name == "Renderite.Host"); - if (resoAsm == null && File.Exists(resoDllPath)) - { - resoAsm = alc.LoadFromAssemblyPath(resoDllPath); - } + try { + if (resoAsm == null) + { + resoAsm = alc.LoadFromAssemblyPath(resoDllPath); + } var result = resoAsm.EntryPoint!.Invoke(null, [args]); if (result is Task task) task.Wait(); } catch (Exception e) { - File.WriteAllLines("BepisCrash.log", [DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " - Resonite crashed", e.ToString()]); + File.WriteAllLines(Path.Combine(resoDir, "BepisCrash.log"), [DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " - Resonite crashed", e.ToString()]); } } @@ -167,6 +154,7 @@ private static string GetUnmanagedLibraryName(string name) } #if DEBUG + private static string logPath; private static object _lock = new object(); #endif public static void Log(string message) @@ -174,7 +162,7 @@ public static void Log(string message) #if DEBUG lock (_lock) { - File.AppendAllLines("BepisLoader.log", [message]); + File.AppendAllLines(logPath, [message]); } #endif } diff --git a/build/Program.cs b/build/Program.cs index 9dfad98a..21f51bcb 100644 --- a/build/Program.cs +++ b/build/Program.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.Versioning; using System.Text; using Cake.Common; using Cake.Common.IO; @@ -573,10 +574,74 @@ public override void Run(BuildContext ctx) } } +[TaskName("FixThunderstoreLinuxPermissions")] +[IsDependentOn(typeof(BuildThunderstorePackageTask))] +[SupportedOSPlatform("linux")] +public sealed class FixThunderstoreLinuxPermissionsTask : FrostingTask +{ + public override bool ShouldRun(BuildContext ctx) => + ctx.Distributions.Any(d => d.Runtime == "BepisLoader") && + System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux); + + [SupportedOSPlatform("linux")] + public override void Run(BuildContext ctx) + { + ctx.Log.Information("Fixing Linux permissions in Thunderstore package..."); + + var thunderstorePackageDir = ctx.DistributionDirectory.Combine("thunderstore-package"); + var packageFiles = ctx.GetFiles(thunderstorePackageDir.Combine("*.zip").FullPath); + + foreach (var packageFile in packageFiles) + { + ctx.Log.Information($"Fixing Linux permissions in {packageFile.GetFilename()}..."); + + var tempDir = ctx.DistributionDirectory.Combine("temp-thunderstore-fix"); + if (ctx.DirectoryExists(tempDir)) + { + ctx.CleanDirectory(tempDir); + } + else + { + ctx.CreateDirectory(tempDir); + } + + System.IO.Compression.ZipFile.ExtractToDirectory(packageFile.FullPath, tempDir.FullPath); + + var executablePermissions = System.IO.UnixFileMode.UserExecute | + System.IO.UnixFileMode.GroupExecute | + System.IO.UnixFileMode.OtherExecute; + + var executableFiles = new[] { "LinuxBootstrap.sh" }; + + foreach (var fileName in executableFiles) + { + var filePath = tempDir.CombineWithFilePath($"BepInExPack/{fileName}"); + if (ctx.FileExists(filePath)) + { + var fileInfo = new System.IO.FileInfo(filePath.FullPath); + var originalMode = fileInfo.UnixFileMode; + ctx.Log.Information($"Original permissions for {fileName}: {Convert.ToString((int)originalMode, 8).PadLeft(3, '0')} ({originalMode})"); + + fileInfo.UnixFileMode |= executablePermissions; + + var newMode = fileInfo.UnixFileMode; + ctx.Log.Information($"New permissions for {fileName}: {Convert.ToString((int)newMode, 8).PadLeft(3, '0')} ({newMode})"); + } + } + + ctx.DeleteFile(packageFile); + + System.IO.Compression.ZipFile.CreateFromDirectory(tempDir.FullPath, packageFile.FullPath); + + ctx.Log.Information($"Fixed Linux permissions in {packageFile.GetFilename()}"); + } + } +} + [TaskName("Publish")] [IsDependentOn(typeof(MakeDistTask))] [IsDependentOn(typeof(PushNuGetTask))] -[IsDependentOn(typeof(BuildThunderstorePackageTask))] +[IsDependentOn(typeof(FixThunderstoreLinuxPermissionsTask))] public sealed class PublishTask : FrostingTask { public override void Run(BuildContext ctx) @@ -587,9 +652,9 @@ public override void Run(BuildContext ctx) { var targetZipName = $"BepInEx-{dist.Target}-{ctx.BuildPackageVersion}.zip"; ctx.Log.Information($"Packing {targetZipName}"); - ctx.Zip(ctx.DistributionDirectory.Combine(dist.Target), - ctx.DistributionDirectory - .CombineWithFilePath(targetZipName)); + // https://github.com/cake-build/cake/issues/2592 + System.IO.Compression.ZipFile.CreateFromDirectory(ctx.DistributionDirectory.Combine(dist.Target).FullPath, + ctx.DistributionDirectory.CombineWithFilePath(targetZipName).FullPath); }