diff --git a/Nebula.Launcher/Services/DecompilerService.cs b/Nebula.Launcher/Services/DecompilerService.cs index f818d0d..b0576af 100644 --- a/Nebula.Launcher/Services/DecompilerService.cs +++ b/Nebula.Launcher/Services/DecompilerService.cs @@ -1,13 +1,17 @@ +using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; +using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Nebula.Launcher.ViewModels.Popup; using Nebula.Shared; using Nebula.Shared.FileApis; using Nebula.Shared.FileApis.Interfaces; +using Nebula.Shared.Models; using Nebula.Shared.Services; namespace Nebula.Launcher.Services; @@ -18,21 +22,69 @@ public sealed partial class DecompilerService [GenerateProperty] private ConfigurationService ConfigurationService { get; } [GenerateProperty] private PopupMessageService PopupMessageService {get;} [GenerateProperty] private ViewHelperService ViewHelperService {get;} + [GenerateProperty] private ContentService ContentService {get;} + [GenerateProperty] private FileService FileService {get;} + [GenerateProperty] private CancellationService CancellationService {get;} + [GenerateProperty] private EngineService engineService {get;} + [GenerateProperty] private DebugService debugService {get;} private HttpClient _httpClient = new HttpClient(); private static string fullPath = Path.Join(FileService.RootPath,"ILSpy"); private static string executePath = Path.Join(fullPath, "ILSpy.exe"); - public async void OpenDecompiler(string path){ + public async void OpenDecompiler(string arguments){ await EnsureILSpy(); var startInfo = new ProcessStartInfo(){ FileName = executePath, - Arguments = path + Arguments = arguments }; Process.Start(startInfo); } + public async void OpenServerDecompiler(RobustUrl url) + { + var myTempDir = EnsureTempDir(out var tmpDir); + + ILoadingHandler loadingHandler = ViewHelperService.GetViewModel(); + + var buildInfo = + await ContentService.GetBuildInfo(url, CancellationService.Token); + var engine = await engineService.EnsureEngine(buildInfo.BuildInfo.Build.EngineVersion); + + if (engine is null) + throw new Exception("Engine version not found: " + buildInfo.BuildInfo.Build.EngineVersion); + + foreach (var file in engine.AllFiles) + { + if(!file.Contains(".dll") || !engine.TryOpen(file, out var stream)) continue; + myTempDir.Save(file, stream); + await stream.DisposeAsync(); + } + + var hashApi = await ContentService.EnsureItems(buildInfo.RobustManifestInfo, loadingHandler, CancellationService.Token); + + foreach (var (file, hash) in hashApi.Manifest) + { + if(!file.Contains(".dll") || !hashApi.TryOpen(hash, out var stream)) continue; + myTempDir.Save(Path.GetFileName(file), stream); + await stream.DisposeAsync(); + } + + ((IDisposable)loadingHandler).Dispose(); + + debugService.Log("File extracted. " + tmpDir); + + OpenDecompiler(string.Join(' ', myTempDir.AllFiles.Select(f=>Path.Join(tmpDir, f))) + " --newinstance"); + } + + private IReadWriteFileApi EnsureTempDir(out string path) + { + path = Path.Combine(Path.GetTempPath(), "tempDlls"+Path.GetRandomFileName()); + Directory.CreateDirectory(path); + return new FileApi(path); + } + private void Initialise(){} private void InitialiseInDesignMode(){} diff --git a/Nebula.Launcher/ViewModels/ContentView/ContentViewBase.cs b/Nebula.Launcher/ViewModels/ContentView/ContentViewBase.cs index f88fde7..f6f24b1 100644 --- a/Nebula.Launcher/ViewModels/ContentView/ContentViewBase.cs +++ b/Nebula.Launcher/ViewModels/ContentView/ContentViewBase.cs @@ -5,7 +5,7 @@ using Nebula.Launcher.ViewModels.Pages; namespace Nebula.Launcher.ViewModels.ContentView; public abstract class ContentViewBase : ViewModelBase, IDisposable { - public virtual void InitialiseWithData(ContentPath path, Stream stream) + public virtual void InitialiseWithData(ContentPath path, Stream stream, ContentEntry contentEntry) { } public virtual void Dispose() diff --git a/Nebula.Launcher/ViewModels/ContentView/DecompilerContentView.cs b/Nebula.Launcher/ViewModels/ContentView/DecompilerContentView.cs index 3180af6..74fbc4f 100644 --- a/Nebula.Launcher/ViewModels/ContentView/DecompilerContentView.cs +++ b/Nebula.Launcher/ViewModels/ContentView/DecompilerContentView.cs @@ -1,6 +1,7 @@ using System.IO; using Nebula.Launcher.Services; using Nebula.Launcher.ViewModels.Pages; +using Nebula.Shared.Utils; namespace Nebula.Launcher.ViewModels.ContentView; @@ -9,9 +10,14 @@ public sealed partial class DecompilerContentView: ContentViewBase { [GenerateProperty] private DecompilerService decompilerService {get;} - public override void InitialiseWithData(ContentPath path, Stream stream) + public override void InitialiseWithData(ContentPath path, Stream stream, ContentEntry contentEntry) + { + base.InitialiseWithData(path, stream, contentEntry); + decompilerService.OpenServerDecompiler(contentEntry.ServerName.ToRobustUrl()); + } + + private void unpackContent(Stream stream) { - base.InitialiseWithData(path, stream); var myTempFile = Path.Combine(Path.GetTempPath(), "tempie.dll"); var sw = new FileStream(myTempFile, FileMode.Create, FileAccess.Write, FileShare.None); diff --git a/Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs b/Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs index a66e25a..1c108f5 100644 --- a/Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs +++ b/Nebula.Launcher/ViewModels/Pages/ContentBrowserViewModel.cs @@ -70,7 +70,8 @@ public sealed partial class ContentBrowserViewModel : ViewModelBase , IViewModel if(TryGetContentViewer(ext, out var contentViewBase)){ DebugService.Debug($"Opening custom context:{item.Value.Path}"); - contentViewBase.InitialiseWithData(value.GetPath(), stream); + contentViewBase.InitialiseWithData(value.GetPath(), stream, value); + stream.Dispose(); ContentView = contentViewBase; return; }