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; using Nebula.Shared.Services.Logging; namespace Nebula.Launcher.Services; [ConstructGenerator, ServiceRegister] 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 ILogger _logger; private static string fullPath = Path.Join(FileService.RootPath,"ILSpy"); private static string executePath = Path.Join(fullPath, "ILSpy.exe"); public async void OpenDecompiler(string arguments){ await EnsureILSpy(); var startInfo = new ProcessStartInfo(){ FileName = executePath, Arguments = arguments }; Process.Start(startInfo); } public async void OpenServerDecompiler(RobustUrl url) { var myTempDir = FileService.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(); _logger.Log("File extracted. " + tmpDir); OpenDecompiler(string.Join(' ', myTempDir.AllFiles.Select(f=>Path.Join(tmpDir, f))) + " --newinstance"); } private void Initialise() { _logger = DebugService.GetLogger(this); } private void InitialiseInDesignMode(){} private async Task EnsureILSpy(){ if(!Directory.Exists(fullPath)) await Download(); } private async Task Download(){ using var loading = ViewHelperService.GetViewModel(); loading.LoadingName = "Download ILSpy"; loading.SetJobsCount(1); PopupMessageService.Popup(loading); using var response = await _httpClient.GetAsync(ConfigurationService.GetConfigValue(LauncherConVar.ILSpyUrl)); using var zipArchive = new ZipArchive(await response.Content.ReadAsStreamAsync()); Directory.CreateDirectory(fullPath); zipArchive.ExtractToDirectory(fullPath); } }