using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Text; using Cysharp.Threading.Tasks; using Newtonsoft.Json; using Unity.SharpZipLib.Utils; using UnityEngine; using UnityEngine.Experimental.Audio; using UnityEngine.Networking; namespace BITKit.Mod { public class DotNetSdkRoslynService { private const string _InstalledFilesKey = "DotNetSdkRoslyn_InstalledFiles"; public static string DownloadUrl => "http://server.bitfall.icu:3000/root/BITKit.DotNetSdkRoslyn.Unity/archive/main.zip"; public static bool Installed=>File.Exists(CSCPath); public static string CSCPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(BITKit),"DotnetSdkRoslyn","csc.dll"); public static string FolderPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(BITKit),"DotnetSdkRoslyn"); public static event Action OnInstall; public static event Action OnInstalled; public static event Action OnUnInstalled; public static event Action OnInstallFailed; public static event Action OnDownloadProgress; private static string[] _InstalledFiles { get { if (!PlayerPrefs.HasKey(_InstalledFilesKey)) return Array.Empty(); var json = PlayerPrefs.GetString(_InstalledFilesKey); try { return JsonConvert.DeserializeObject(json); } catch (Exception e) { BIT4Log.LogException(e); } return Array.Empty(); } set { PlayerPrefs.SetString(_InstalledFilesKey, JsonConvert.SerializeObject(value)); PlayerPrefs.Save(); } } public static async UniTask Install() { await UniTask.SwitchToMainThread(); OnInstall?.Invoke(); var request = UnityWebRequest.Get(DownloadUrl); try { await request.SendWebRequest(); while (request.isDone is false) { await UniTask.SwitchToMainThread(); OnDownloadProgress?.Invoke(request.downloadProgress); await UniTask.NextFrame(); } OnDownloadProgress?.Invoke(1); using var ms = new MemoryStream(request.downloadHandler.data); request.Dispose(); await UniTask.SwitchToTaskPool(); var zipArchive = new ZipArchive(ms); PathHelper.EnsureDirectoryCreated(FolderPath); List installedFiles = new(); var reportBuilder =new StringBuilder(); reportBuilder.AppendLine($"正在安装文件到:{FolderPath}"); var entryFolder = zipArchive.Entries[0].FullName; foreach (var zipArchiveEntry in zipArchive.Entries) { var entryPath = Path.Combine(FolderPath, zipArchiveEntry.FullName.Replace(entryFolder,string.Empty)); if (zipArchiveEntry.Name is "") { reportBuilder.AppendLine($"正在创建目录:{entryPath}"); PathHelper.EnsureDirectoryCreated(entryPath); } else { reportBuilder.AppendLine($"正在解压文件:{entryPath}"); await using var entryStream = zipArchiveEntry.Open(); await using var fs = System.IO.File.Create(entryPath); await entryStream.CopyToAsync(fs); installedFiles.Add(entryPath); } } await UniTask.SwitchToMainThread(); _InstalledFiles = installedFiles.ToArray(); installedFiles.Clear(); } catch (Exception e) { await UniTask.SwitchToMainThread(); request.Dispose(); OnInstallFailed?.Invoke(e); return; } OnInstalled?.Invoke(); } public static async UniTask UnInstall() { if (Installed is false) { BIT4Log.Warning("未安装,无法卸载"); return; } await UniTask.SwitchToMainThread(); var files = _InstalledFiles; await UniTask.SwitchToTaskPool(); foreach (var path in files) { File.Delete(path); } await UniTask.SwitchToMainThread(); PlayerPrefs.DeleteKey(_InstalledFilesKey); PlayerPrefs.Save(); OnUnInstalled?.Invoke(); } } }