Skip to content

Commit

Permalink
新增 插件更新功能
Browse files Browse the repository at this point in the history
  • Loading branch information
MakesYT committed Aug 16, 2024
1 parent b924925 commit 6ff6ee8
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 43 deletions.
4 changes: 4 additions & 0 deletions Core/SDKs/Services/Plugin/PluginInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Drawing;
using System.Text.Json.Serialization;
using CommunityToolkit.Mvvm.ComponentModel;
using Bitmap = Avalonia.Media.Imaging.Bitmap;

Expand All @@ -25,12 +26,15 @@ public partial class PluginInfo
public string Main { set; get; }
public string FullPath { set; get; }
public string Path { set; get; }
[JsonIgnore]
[property:JsonIgnore]
[ObservableProperty] private Bitmap? _icon;

[ObservableProperty] public bool isEnabled;
[ObservableProperty] public bool unloadFailed;

[ObservableProperty] private bool canUpdata;
public int UpdateTargetVersion { set; get; }
public string ToPlgString() => $"{Id}_{AuthorId}_{NameSign}";

public override string ToString()
Expand Down
71 changes: 70 additions & 1 deletion Core/SDKs/Services/Plugin/PluginManager.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
#region

using System.Collections.ObjectModel;
using System.IO.Compression;
using System.Text;
using Core.SDKs.CustomScenario;
using Core.SDKs.Services.Config;
using Core.ViewModel.Pages;
using log4net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PluginCore;
using SixLabors.ImageSharp;
using JsonSerializer = System.Text.Json.JsonSerializer;

#endregion
Expand All @@ -21,6 +24,7 @@ public class PluginManager
public readonly static ObservableCollection<PluginInfo> AllPluginInfos = new();
public readonly static Dictionary<string, Plugin> EnablePlugin = new();

public static HttpClient _httpClient= new HttpClient();
public static void Init()
{
PluginCore.Kitopia.ISearchItemTool =
Expand Down Expand Up @@ -94,6 +98,14 @@ public static void Load()
serialize.FullPath= $"{directoryInfo.FullName}{Path.DirectorySeparatorChar}{serialize.Main}";
serialize.Path= $"{directoryInfo.FullName}{Path.DirectorySeparatorChar}";
serialize.IsEnabled = false;
if (serialize.UpdateTargetVersion==0)
{
serialize.UpdateTargetVersion = serialize.VersionId;
}
if (serialize.UpdateTargetVersion!=serialize.VersionId)
{
DownloadPluginOnline(serialize).Wait();
}
if (ConfigManger.Config.EnabledPluginInfos.Any(e => e.ToPlgString()==serialize.ToPlgString()))
{
serialize.IsEnabled = true;
Expand All @@ -114,7 +126,7 @@ public static void CheckUpdate()
{
try
{
var httpResponseMessage = MarketPageViewModel._httpClient.GetAsync($"https://www.ncserver.top:5111/api/plugin/{AllPluginInfos[i].Id}").Result;
var httpResponseMessage = PluginManager._httpClient.GetAsync($"https://www.ncserver.top:5111/api/plugin/{AllPluginInfos[i].Id}").Result;
var httpContent = httpResponseMessage.Content.ReadAsStringAsync().Result;
var deserializeObject = (JObject)JsonConvert.DeserializeObject(httpContent);
AllPluginInfos[i].CanUpdata= deserializeObject["data"]["lastVersionId"].ToObject<int>() > AllPluginInfos[i].VersionId;
Expand All @@ -125,4 +137,61 @@ public static void CheckUpdate()
}
}
}

public static async Task DownloadPluginOnline(OnlinePluginInfo plugin)
{
await DownloadPlugin(plugin.Id,plugin.LastVersionId,plugin.ToPlgString());
var pluginInfoEx = AllPluginInfos.FirstOrDefault(e=>e.ToPlgString()==plugin.ToPlgString());
if (pluginInfoEx is null)
{
return;
}
PluginManager.EnablePluginByInfo(pluginInfoEx);
plugin.Upadate();
}

private static async Task DownloadPlugin(int id,int versionId,string plugin)
{
try
{
var streamAsync =await _httpClient.GetStreamAsync($"https://www.ncserver.top:5111/api/plugin/download/1/{id}/{versionId}");
Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp"));
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp",$"{plugin}.zip");
using (var fs = new FileStream(path, FileMode.Create))
{
await streamAsync.CopyToAsync(fs);
}

var zipArchive = ZipFile.Open(path,ZipArchiveMode.Read);
zipArchive.ExtractToDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins",plugin),true);
zipArchive.Dispose();
File.Delete(path);

var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://www.ncserver.top:5111/api/plugin/avatar"),
Method = HttpMethod.Get,
};
request.Headers.Add("id", id.ToString());
var sendAsync =await _httpClient.SendAsync(request);
var stringAsync =await sendAsync.Content.ReadAsStringAsync();
var deserializeObject = (JObject)JsonConvert.DeserializeObject(stringAsync);
using var image = Image.Load(deserializeObject["data"].ToObject<byte[]>());
await image.SaveAsPngAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins",plugin,"avatar.png"));


Reload();
}
catch (Exception e)
{
Log.Error("错误",e);
return;
}
}

public static async Task DownloadPluginOnline(PluginInfo plugin)
{
await DownloadPlugin(plugin.Id,plugin.UpdateTargetVersion,plugin.ToPlgString());

}
}
43 changes: 5 additions & 38 deletions Core/ViewModel/Pages/MarketPageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public string AuthorName
Method = HttpMethod.Get,
};
request.Headers.Add("id",AuthorId.ToString());
var async = MarketPageViewModel._httpClient.SendAsync(request).GetAwaiter().GetResult();
var async = PluginManager._httpClient.SendAsync(request).GetAwaiter().GetResult();
var stringAsync = async.Content.ReadAsStringAsync().Result;
var deserializeObject = (JObject)JsonConvert.DeserializeObject(stringAsync);

Expand Down Expand Up @@ -74,12 +74,11 @@ public override string ToString()
}
public partial class MarketPageViewModel : ObservableObject
{
public static HttpClient _httpClient;

[ObservableProperty] private ObservableCollection<OnlinePluginInfo> _plugins = new();

public MarketPageViewModel()
{
_httpClient = new HttpClient();
LoadPlugins();
}

Expand All @@ -92,7 +91,7 @@ public MarketPageViewModel()
}
private async Task LoadPlugins()
{
var async =await MarketPageViewModel._httpClient.GetAsync("https://www.ncserver.top:5111/api/plugin/all");
var async =await PluginManager._httpClient.GetAsync("https://www.ncserver.top:5111/api/plugin/all");
var stringAsync = await async.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions
{
Expand All @@ -111,40 +110,8 @@ private async Task LoadPlugins()
[RelayCommand]
private async Task DownloadPlugin(OnlinePluginInfo plugin)
{
var streamAsync =await _httpClient.GetStreamAsync($"https://www.ncserver.top:5111/api/plugin/download/1/{plugin.Id}/{plugin.LastVersionId}");
Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp"));
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp",$"{plugin}.zip");
using (var fs = new FileStream(path, FileMode.Create))
{
await streamAsync.CopyToAsync(fs);
}

var zipArchive = ZipFile.Open(path,ZipArchiveMode.Read);
zipArchive.ExtractToDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins",plugin.ToPlgString()));
zipArchive.Dispose();
File.Delete(path);

var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://www.ncserver.top:5111/api/plugin/avatar"),
Method = HttpMethod.Get,
};
request.Headers.Add("id", plugin.Id.ToString());
var sendAsync =await MarketPageViewModel._httpClient.SendAsync(request);
var stringAsync =await sendAsync.Content.ReadAsStringAsync();
var deserializeObject = (JObject)JsonConvert.DeserializeObject(stringAsync);
using var image = Image.Load(deserializeObject["data"].ToObject<byte[]>());
await image.SaveAsPngAsync(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins",plugin.ToPlgString(),"avatar.png"));


PluginManager.Reload();
var pluginInfoEx = PluginManager.AllPluginInfos.FirstOrDefault(e=>e.ToPlgString()==plugin.ToPlgString());
if (pluginInfoEx is null)
{
return;
}
PluginManager.EnablePluginByInfo(pluginInfoEx);
plugin.Upadate();
await PluginManager.DownloadPluginOnline(plugin);
}


}
25 changes: 24 additions & 1 deletion Core/ViewModel/Pages/plugin/PluginManagerPageViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
using Core.SDKs.Services.Plugin;
using log4net;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PluginCore;

#endregion
Expand Down Expand Up @@ -78,7 +80,28 @@ public void Switch(PluginInfo pluginInfoEx)
}
}


[RelayCommand]
public async Task Update(PluginInfo pluginInfoEx)
{
var httpResponseMessage = PluginManager._httpClient.GetAsync($"https://www.ncserver.top:5111/api/plugin/{pluginInfoEx.Id}").Result;
var httpContent = httpResponseMessage.Content.ReadAsStringAsync().Result;
var deserializeObject = (JObject)JsonConvert.DeserializeObject(httpContent);
pluginInfoEx.UpdateTargetVersion = deserializeObject["data"]["lastVersionId"].ToObject<int>();

PluginManager.UnloadPlugin(pluginInfoEx);

if (!pluginInfoEx.UnloadFailed)
{
await PluginManager.DownloadPluginOnline(pluginInfoEx);
var pluginInfoEx2 = PluginManager.AllPluginInfos.FirstOrDefault(e=>e.ToPlgString()==pluginInfoEx.ToPlgString());
if (pluginInfoEx2 is null)
{
return;
}
PluginManager.EnablePluginByInfo(pluginInfoEx);
}

}



Expand Down
3 changes: 2 additions & 1 deletion KitopiaAvalonia/Converter/MarketPage/IconCtr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Avalonia.Data.Converters;
using Avalonia.Markup.Xaml.MarkupExtensions;
using Avalonia.Media.Imaging;
using Core.SDKs.Services.Plugin;
using Core.ViewModel.Pages;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
Expand Down Expand Up @@ -40,7 +41,7 @@ public class IconCtr : IValueConverter
Method = HttpMethod.Get,
};
request.Headers.Add("id", onlinePluginInfo.Id.ToString());
var sendAsync =await MarketPageViewModel._httpClient.SendAsync(request);
var sendAsync =await PluginManager._httpClient.SendAsync(request);
var stringAsync =await sendAsync.Content.ReadAsStringAsync();
var deserializeObject = (JObject)JsonConvert.DeserializeObject(stringAsync);
onlinePluginInfo.Icon = new Bitmap(new MemoryStream(deserializeObject["data"].ToObject<byte[]>()));
Expand Down
5 changes: 3 additions & 2 deletions KitopiaAvalonia/Pages/PluginManagerPage.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,16 @@
<Button Classes="Danger" Content="删除"
Command="{Binding Path=$parent[ItemsControl].((plugin:PluginManagerPageViewModel)DataContext).DeleteCommand}"
CommandParameter="{Binding }"></Button>
<Button Content="更新" IsVisible="{Binding CanUpdata}"></Button>
<Button Content="更新" IsVisible="{Binding CanUpdata}" Command="{Binding Path=$parent[ItemsControl].((plugin:PluginManagerPageViewModel)DataContext).UpdateCommand}"
CommandParameter="{Binding }"></Button>
</StackPanel>

</Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" ZIndex="1" IsVisible="{Binding UnloadFailed}">
<StackPanel.Background>
<SolidColorBrush Color="{DynamicResource SemiBackground0Color}" Opacity="0.4"></SolidColorBrush>
</StackPanel.Background>
<TextBlock Text="插件动态卸载失败,重启后完成卸载"></TextBlock>
<TextBlock Text="插件动态卸载失败,重启后完成卸载/更新"></TextBlock>
<Button Content="重启" Command="{Binding Path=$parent[ItemsControl].((plugin:PluginManagerPageViewModel)DataContext).RestartAppCommand}"></Button>
</StackPanel>
</Panel>
Expand Down

0 comments on commit 6ff6ee8

Please sign in to comment.