Moved to Json Database for online plugins

This commit is contained in:
2024-02-26 23:36:19 +02:00
parent 196fb6d3d1
commit 14f280baef
16 changed files with 376 additions and 299 deletions

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PluginManager\PluginManager.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,68 @@
using System.Diagnostics;
using PluginManager;
using PluginManager.Online.Helpers;
using PluginManager.Others;
using PluginManager.Plugin;
if (args.Length == 1)
{
PluginOnlineInfo? result = await JsonManager.ConvertFromJson<PluginOnlineInfo>(args[0]);
// print all rows
Console.WriteLine($"Name: {result.Name}");
Console.WriteLine($"Version: {result.Version.ToShortString()}");
Console.WriteLine($"Description: {result.Description}");
Console.WriteLine($"Download link: {result.DownLoadLink}");
Console.WriteLine($"Supported OS: {((result.SupportedOS & OSType.WINDOWS) != 0 ? "Windows" : "")} {((result.SupportedOS & OSType.LINUX) != 0 ? "Linux" : "")} {((result.SupportedOS & OSType.MACOSX) != 0 ? "MacOSX" : "")}");
Console.WriteLine($"Has dependencies: {result.HasDependencies}");
Console.WriteLine($"Dependencies: {result.Dependencies.Count}");
return;
}
var _levelingSystem = new PluginOnlineInfo(
"Leveling System",
new PluginVersion(0, 0, 1),
"A simple leveling system for your server",
"https://github.com/andreitdr/SethPlugins/raw/releases/LevelingSystem/LevelingSystem.dll",
OSType.WINDOWS | OSType.LINUX
);
var _musicPlayerWindows = new PluginOnlineInfo(
"Music Player (Windows)", new PluginVersion(0, 0, 1),
"A simple music player for your server",
"https://github.com/andreitdr/SethPlugins/raw/releases/MusicPlayer/MusicPlayer.dll",
OSType.WINDOWS,
[
new OnlineDependencyInfo("https://github.com/andreitdr/SethPlugins/raw/releases/MusicPlayer/libs/windows/ffmpeg.exe", "ffmpeg.exe"),
new OnlineDependencyInfo("https://github.com/andreitdr/SethPlugins/raw/releases/MusicPlayer/libs/windows/libopus.dll", "libopus.dll"),
new OnlineDependencyInfo("https://github.com/andreitdr/SethPlugins/raw/releases/MusicPlayer/libs/windows/libsodium.dll", "libsodium.dll"),
new OnlineDependencyInfo("https://github.com/andreitdr/SethPlugins/raw/releases/MusicPlayer/libs/windows/opus.dll", "opus.dll"),
new OnlineDependencyInfo("https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_x86.exe", "yt-dlp.exe")
]
);
var _musicPlayerLINUX = new PluginOnlineInfo(
"Music Player (Linux)", new PluginVersion(0, 0, 1),
"A simple music player for your server",
"https://github.com/andreitdr/SethPlugins/raw/releases/MusicPlayer/MusicPlayer.dll",
OSType.LINUX,
[
new OnlineDependencyInfo("https://github.com/andreitdr/SethPlugins/raw/releases/MusicPlayer/libs/linux/ffmpeg", "ffmpeg"),
new OnlineDependencyInfo("https://github.com/andreitdr/SethPlugins/raw/releases/MusicPlayer/libs/linux/libopus.so", "libopus.so"),
new OnlineDependencyInfo("https://github.com/andreitdr/SethPlugins/raw/releases/MusicPlayer/libs/linux/libsodium.so", "libsodium.so"),
new OnlineDependencyInfo("https://github.com/yt-dlp/yt-dlp/releases/download/2023.10.13/yt-dlp", "yt-dlp")
]
);
List<PluginOnlineInfo> plugins =
[
_levelingSystem,
_musicPlayerWindows,
_musicPlayerLINUX
];
Directory.CreateDirectory("output");
await JsonManager.SaveToJsonFile("./output/PluginsList.json", plugins);
Process.Start("notepad.exe", "./output/PluginsList.json");

View File

@@ -10,6 +10,7 @@ using PluginManager.Interfaces;
using PluginManager.Loaders; using PluginManager.Loaders;
using PluginManager.Online; using PluginManager.Online;
using PluginManager.Others; using PluginManager.Others;
using PluginManager.Plugin;
using Spectre.Console; using Spectre.Console;
namespace DiscordBot.Bot.Actions.Extra; namespace DiscordBot.Bot.Actions.Extra;
@@ -18,10 +19,10 @@ internal static class PluginMethods
{ {
internal static async Task List(PluginsManager manager) internal static async Task List(PluginsManager manager)
{ {
var data = await ConsoleUtilities.ExecuteWithProgressBar(manager.GetAvailablePlugins(), "Loading plugins..."); var data = await ConsoleUtilities.ExecuteWithProgressBar(manager.GetPluginsList(), "Loading plugins...");
TableData tableData = new(new List<string> { "Name", "Description", "Type", "Version" }); TableData tableData = new(new List<string> { "Name", "Description", "Version", "Has Dependencies" });
foreach (var plugin in data) tableData.AddRow(plugin); foreach (var plugin in data) tableData.AddRow([plugin.Name, plugin.Description, plugin.Version.ToString(), plugin.HasDependencies ? "Yes" : "No"]);
tableData.HasRoundBorders = false; tableData.HasRoundBorders = false;
tableData.PrintAsTable(); tableData.PrintAsTable();
@@ -35,16 +36,14 @@ internal static class PluginMethods
internal static async Task DownloadPlugin(PluginsManager manager, string pluginName) internal static async Task DownloadPlugin(PluginsManager manager, string pluginName)
{ {
var pluginData = await manager.GetPluginLinkByName(pluginName); var pluginData = await manager.GetPluginDataByName(pluginName);
if (pluginData.Length == 0) if (pluginData is null)
{ {
Console.WriteLine($"Plugin {pluginName} not found. Please check the spelling and try again."); Console.WriteLine($"Plugin {pluginName} not found. Please check the spelling and try again.");
return; return;
} }
var pluginType = pluginData[0]; var pluginLink = pluginData.DownLoadLink;
var pluginLink = pluginData[1];
var pluginRequirements = pluginData[2];
await AnsiConsole.Progress() await AnsiConsole.Progress()
@@ -61,7 +60,7 @@ internal static class PluginMethods
IProgress<float> progress = new Progress<float>(p => { downloadTask.Value = p; }); IProgress<float> progress = new Progress<float>(p => { downloadTask.Value = p; });
await ServerCom.DownloadFileAsync(pluginLink, $"./Data/{pluginType}s/{pluginName}.dll", progress); await ServerCom.DownloadFileAsync(pluginLink, $"{Config.AppSettings["PluginFolder"]}/{pluginName}.dll", progress);
downloadTask.Increment(100); downloadTask.Increment(100);
@@ -69,32 +68,13 @@ internal static class PluginMethods
} }
); );
if (pluginRequirements == string.Empty) if (!pluginData.HasDependencies)
{ {
Console.WriteLine("Finished installing " + pluginName + " successfully"); Console.WriteLine("Finished installing " + pluginName + " successfully");
await RefreshPlugins(false); await RefreshPlugins(false);
return; return;
} }
List<string> requirementsUrLs = new();
await AnsiConsole.Progress()
.Columns(new ProgressColumn[]
{
new TaskDescriptionColumn(),
new ProgressBarColumn(),
new PercentageColumn()
}
)
.StartAsync(async ctx =>
{
var gatherInformationTask = ctx.AddTask("Gathering info...");
gatherInformationTask.IsIndeterminate = true;
requirementsUrLs = await ServerCom.ReadTextFromURL(pluginRequirements);
gatherInformationTask.Increment(100);
}
);
List<Tuple<ProgressTask, IProgress<float>, string, string>> downloadTasks = new(); List<Tuple<ProgressTask, IProgress<float>, string, string>> downloadTasks = new();
await AnsiConsole.Progress() await AnsiConsole.Progress()
.Columns(new ProgressColumn[] .Columns(new ProgressColumn[]
@@ -108,14 +88,9 @@ internal static class PluginMethods
{ {
foreach (var info in requirementsUrLs) foreach (OnlineDependencyInfo dependency in pluginData.Dependencies)
{ {
if (info.Length < 2) continue; var task = ctx.AddTask($"Downloading {dependency.DownloadLocation}: ");
string[] data = info.Split(',');
string url = data[0];
string fileName = data[1];
var task = ctx.AddTask($"Downloading {fileName}: ");
IProgress<float> progress = new Progress<float>(p => IProgress<float> progress = new Progress<float>(p =>
{ {
task.Value = p; task.Value = p;
@@ -123,7 +98,7 @@ internal static class PluginMethods
); );
task.IsIndeterminate = true; task.IsIndeterminate = true;
downloadTasks.Add(new Tuple<ProgressTask, IProgress<float>, string, string>(task, progress, url, fileName)); downloadTasks.Add(new Tuple<ProgressTask, IProgress<float>, string, string>(task, progress, dependency.DownloadLink, dependency.DownloadLocation));
} }
if (!int.TryParse(Config.AppSettings["MaxParallelDownloads"], out int maxParallelDownloads)) if (!int.TryParse(Config.AppSettings["MaxParallelDownloads"], out int maxParallelDownloads))

View File

@@ -30,6 +30,8 @@ public class Config
AppSettings = new SettingsDictionary<string, string>("./Data/Resources/config.json"); AppSettings = new SettingsDictionary<string, string>("./Data/Resources/config.json");
AppSettings["LogFolder"] = "./Data/Logs"; AppSettings["LogFolder"] = "./Data/Logs";
AppSettings["PluginFolder"] = "./Data/Plugins";
AppSettings["ArchiveFolder"] = "./Data/Archives";
if (OperatingSystem.IsLinux()) if (OperatingSystem.IsLinux())
{ {

View File

@@ -0,0 +1,14 @@
namespace PluginManager.Interfaces.Updater;
public interface IVersion
{
public int Major { get; }
public int Minor { get; }
public int Patch { get; }
public bool IsNewerThan(IVersion version);
public bool IsOlderThan(IVersion version);
public bool IsEqualTo(IVersion version);
public string ToShortString();
}

View File

@@ -0,0 +1,71 @@
using System;
namespace PluginManager.Interfaces.Updater;
public abstract class Version : IVersion
{
public int Major { get; }
public int Minor { get; }
public int Patch { get; }
protected readonly char _Separator = '.';
protected Version(int major, int minor, int patch)
{
this.Major = major;
this.Minor = minor;
this.Patch = patch;
}
protected Version(string versionAsString)
{
string[] versionParts = versionAsString.Split(_Separator);
if (versionParts.Length != 3)
{
throw new ArgumentException("Invalid version string");
}
this.Major = int.Parse(versionParts[0]);
this.Minor = int.Parse(versionParts[1]);
this.Patch = int.Parse(versionParts[2]);
}
public bool IsNewerThan(IVersion version)
{
if (this.Major > version.Major)
return true;
if (this.Major == version.Major && this.Minor > version.Minor)
return true;
if (this.Major == version.Major && this.Minor == version.Minor && this.Patch > version.Patch)
return true;
return false;
}
public bool IsOlderThan(IVersion version)
{
if (this.Major < version.Major)
return true;
if (this.Major == version.Major && this.Minor < version.Minor)
return true;
if (this.Major == version.Major && this.Minor == version.Minor && this.Patch < version.Patch)
return true;
return false;
}
public bool IsEqualTo(IVersion version)
{
return this.Major == version.Major && this.Minor == version.Minor && this.Patch == version.Patch;
}
public string ToShortString()
{
return $"{Major}.{Minor}.{Patch}";
}
}

View File

@@ -0,0 +1,16 @@
using PluginManager.Interfaces.Updater;
namespace PluginManager.Online.Helpers;
public class ApplicationVersion : Version
{
public ApplicationVersion(int major, int minor, int patch): base(major, minor, patch)
{
}
public ApplicationVersion(string versionAsString): base(versionAsString)
{
}
}

View File

@@ -0,0 +1,20 @@
using System.Text.Json.Serialization;
using PluginManager.Interfaces.Updater;
namespace PluginManager.Online.Helpers;
public class PluginVersion : Version
{
[JsonConstructor]
public PluginVersion(int major, int minor, int patch): base(major, minor, patch)
{
}
public PluginVersion(string versionAsString): base(versionAsString)
{
}
public override string ToString()
{
return ToShortString();
}
}

View File

@@ -1,117 +0,0 @@
using System;
namespace PluginManager.Online.Helpers;
public class VersionString
{
public int PackageCheckVersion;
public int PackageMainVersion;
public int PackageVersionID;
public VersionString(string version)
{
var data = version.Split('.');
try
{
if (data.Length == 3)
{
PackageVersionID = int.Parse(data[0]);
PackageMainVersion = int.Parse(data[1]);
PackageCheckVersion = int.Parse(data[2]);
}
else if (data.Length == 4)
{
// ignore the first item data[0]
PackageVersionID = int.Parse(data[1]);
PackageMainVersion = int.Parse(data[2]);
PackageCheckVersion = int.Parse(data[3]);
}
else
{
throw new Exception("Invalid version string");
}
}
catch (Exception ex)
{
Console.WriteLine(version);
throw new Exception("Failed to write Version", ex);
}
}
private bool Equals(VersionString other)
{
return PackageCheckVersion == other.PackageCheckVersion && PackageMainVersion == other.PackageMainVersion &&
PackageVersionID == other.PackageVersionID;
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((VersionString)obj);
}
public override int GetHashCode()
{
return HashCode.Combine(PackageCheckVersion, PackageMainVersion, PackageVersionID);
}
public override string ToString()
{
return "{PackageID: " + PackageVersionID + ", PackageVersion: " + PackageMainVersion +
", PackageCheckVersion: " + PackageCheckVersion + "}";
}
public string ToShortString()
{
if (PackageVersionID == 0 && PackageCheckVersion == 0 && PackageMainVersion == 0)
return "Unknown";
return $"{PackageVersionID}.{PackageMainVersion}.{PackageCheckVersion}";
}
#region operators
public static bool operator >(VersionString s1, VersionString s2)
{
if (s1.PackageVersionID > s2.PackageVersionID) return true;
if (s1.PackageVersionID == s2.PackageVersionID)
{
if (s1.PackageMainVersion > s2.PackageMainVersion) return true;
if (s1.PackageMainVersion == s2.PackageMainVersion &&
s1.PackageCheckVersion > s2.PackageCheckVersion) return true;
}
return false;
}
public static bool operator <(VersionString s1, VersionString s2)
{
return !(s1 > s2) && s1 != s2;
}
public static bool operator ==(VersionString s1, VersionString s2)
{
if (s1.PackageVersionID == s2.PackageVersionID && s1.PackageMainVersion == s2.PackageMainVersion &&
s1.PackageCheckVersion == s2.PackageCheckVersion) return true;
return false;
}
public static bool operator !=(VersionString s1, VersionString s2)
{
return !(s1 == s2);
}
public static bool operator <=(VersionString s1, VersionString s2)
{
return s1 < s2 || s1 == s2;
}
public static bool operator >=(VersionString s1, VersionString s2)
{
return s1 > s2 || s1 == s2;
}
#endregion
}

View File

@@ -3,161 +3,59 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using PluginManager.Online.Helpers; using PluginManager.Online.Helpers;
using PluginManager.Others; using PluginManager.Others;
using PluginManager.Plugin;
namespace PluginManager.Online; namespace PluginManager.Online;
public class PluginsManager public class PluginsManager
{ {
/// <summary> private static readonly string _DefaultBranch = "releases";
/// The Plugin Manager constructor. It uses the default links and the default branch. private static readonly string _DefaultBaseUrl = "https://raw.githubusercontent.com/andreitdr/SethPlugins";
/// </summary>
/// <param name="branch">The main branch from where the plugin manager gets its info</param> private static readonly string _DefaultPluginsLink = "PluginsList.json";
public PluginsManager(string? branch)
public string Branch { get; init; }
public string BaseUrl { get; init; }
private string PluginsLink => $"{BaseUrl}/{Branch}/{_DefaultPluginsLink}";
public PluginsManager(Uri baseUrl, string branch)
{ {
PluginsLink = $"https://raw.githubusercontent.com/andreitdr/SethPlugins/{branch}/PluginsList"; this.BaseUrl = baseUrl.ToString();
VersionsLink = $"https://raw.githubusercontent.com/andreitdr/SethPlugins/{branch}/Versions"; this.Branch = branch;
} }
/// <summary> public PluginsManager(string branch)
/// The URL of the server
/// </summary>
public string PluginsLink { get; }
public string VersionsLink { get; }
/// <summary>
/// The method to load all plugins
/// </summary>
/// <returns></returns>
public async Task<List<string[]>> GetAvailablePlugins()
{ {
// Config.Logger.Log("Got data from " + VersionsLink, this, LogLevel.INFO); this.BaseUrl = _DefaultBaseUrl;
try this.Branch = branch;
{
var list = await ServerCom.ReadTextFromURL(PluginsLink);
var lines = list.ToArray();
var data = new List<string[]>();
var len = lines.Length;
for (var i = 0; i < len; i++)
{
if (lines[i].Length <= 2)
continue;
var content = lines[i].Split(',');
var display = new string[4]; // 4 columns
if (System.OperatingSystem.IsWindows())
{
if (content[4].Contains("Windows"))
{
display[0] = content[0];
display[1] = content[1];
display[2] = content[2];
display[3] =
(await GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0"))
.ToShortString();
data.Add(display);
}
}
else if (System.OperatingSystem.IsLinux())
{
if (content[4].Contains("Linux"))
{
display[0] = content[0];
display[1] = content[1];
display[2] = content[2];
display[3] =
(await GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0"))
.ToShortString();
data.Add(display);
}
}
}
return data;
}
catch (Exception exception)
{
Config.Logger.Log(message: "Failed to execute command: listplugs\nReason: " + exception.Message, source: typeof(PluginsManager), type: LogType.ERROR);
}
return null;
} }
private async Task<VersionString?> GetVersionOfPackageFromWeb(string pakName) public PluginsManager()
{ {
var data = await ServerCom.ReadTextFromURL(VersionsLink); this.BaseUrl = _DefaultBaseUrl;
foreach (var item in data) this.Branch = _DefaultBranch;
{
if (item.StartsWith("#"))
continue;
var split = item.Split(',');
if (split[0] == pakName)
{
// Config.Logger.Log("Searched for " + pakName + " and found " + split[1] + " as version.", LogLevel.INFO);
return new VersionString(split[1]);
}
}
return null;
} }
/// <summary> public async Task<List<PluginOnlineInfo?>> GetPluginsList()
/// The method to get plugin information by its name
/// </summary>
/// <param name="name">The plugin name</param>
/// <returns></returns>
public async Task<string[]> GetPluginLinkByName(string name)
{ {
try string jsonText = await ServerCom.GetAllTextFromUrl(PluginsLink);
{ List<PluginOnlineInfo?> result = await JsonManager.ConvertFromJson<List<PluginOnlineInfo?>>(jsonText);
var list = await ServerCom.ReadTextFromURL(PluginsLink);
var lines = list.ToArray();
var len = lines.Length;
for (var i = 0; i < len; i++)
{
var contents = lines[i].Split(',');
if (contents[0].ToLowerInvariant() == name.ToLowerInvariant())
{
if (System.OperatingSystem.IsWindows() && contents[4].Contains("Windows"))
{
if (contents.Length == 6)
return new[]
{
contents[2], contents[3], contents[5]
};
if (contents.Length == 5)
return new[]
{
contents[2], contents[3], string.Empty
};
throw new Exception("Failed to download plugin. Invalid Argument Length");
} OSType currentOS = OperatingSystem.IsWindows() ? OSType.WINDOWS : OperatingSystem.IsLinux() ? OSType.LINUX : OSType.MACOSX;
if (System.OperatingSystem.IsLinux() && contents[4].Contains("Linux")) return result.FindAll(pl => (pl.SupportedOS & currentOS) != 0);
{
if (contents.Length == 6)
return new[]
{
contents[2], contents[3], contents[5]
};
if (contents.Length == 5)
return new[]
{
contents[2], contents[3], string.Empty
};
throw new Exception("Failed to download plugin. Invalid Argument Length");
}
}
}
}
catch (Exception exception)
{
Config.Logger.Log("Failed to execute command: plugin list\nReason: " + exception.Message, source: typeof(PluginsManager), type: LogType.ERROR);
}
return null;
} }
public async Task<PluginOnlineInfo?> GetPluginDataByName(string pluginName)
{
List<PluginOnlineInfo?> plugins = await GetPluginsList();
PluginOnlineInfo? result = plugins.Find(p => p.Name == pluginName);
return result;
}
} }

View File

@@ -22,6 +22,17 @@ public static class ServerCom
return lines.ToList(); return lines.ToList();
} }
/// <summary>
/// Get all text from a file async
/// </summary>
/// <param name="link">The link of the file</param>
/// <returns></returns>
public static async Task<string> GetAllTextFromUrl(string link)
{
var response = await OnlineFunctions.DownloadStringAsync(link);
return response;
}
/// <summary> /// <summary>
/// Download file from url /// Download file from url
/// </summary> /// </summary>

View File

@@ -1,4 +1,6 @@
namespace PluginManager.Others; using System;
namespace PluginManager.Others;
/// <summary> /// <summary>
/// The output log type /// The output log type
@@ -28,3 +30,12 @@ public enum InternalActionRunType
ON_STARTUP, ON_STARTUP,
ON_CALL ON_CALL
} }
[Flags]
public enum OSType : byte
{
NONE = 0,
WINDOWS = 1 << 0,
LINUX = 2 << 1,
MACOSX = 3 << 2,
}

View File

@@ -0,0 +1,13 @@
namespace PluginManager.Plugin;
public class OnlineDependencyInfo
{
public string DownloadLink { get; private set; }
public string DownloadLocation { get; private set; }
public OnlineDependencyInfo(string downloadLink, string downloadLocation)
{
DownloadLink = downloadLink;
DownloadLocation = downloadLocation;
}
}

View File

@@ -0,0 +1,24 @@
using System.IO;
using PluginManager.Interfaces.Updater;
namespace PluginManager.Plugin;
public class PluginInfo
{
public string PluginName { get; private set; }
public IVersion PluginVersion { get; private set; }
public FileInfo FileData { get; private set; }
public PluginInfo(string pluginName, IVersion pluginVersion)
{
PluginName = pluginName;
PluginVersion = pluginVersion;
FileData = new FileInfo($"{Config.AppSettings["PluginFolder"]}/{pluginName}.dll");
}
public static PluginInfo FromOnlineInfo(PluginOnlineInfo onlineInfo)
{
return new PluginInfo(onlineInfo.Name, onlineInfo.Version);
}
}

View File

@@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using PluginManager.Online.Helpers;
using PluginManager.Others;
namespace PluginManager.Plugin;
public class PluginOnlineInfo
{
public string Name { get; private set; }
public PluginVersion Version { get; private set; }
public string DownLoadLink { get; private set; }
public string Description { get; private set; }
public List<OnlineDependencyInfo> Dependencies { get; private set; }
public OSType SupportedOS { get; private set; }
public bool HasDependencies { get; init; }
[JsonConstructor]
public PluginOnlineInfo(string name, PluginVersion version, string description, string downLoadLink, OSType supportedOS, List<OnlineDependencyInfo> dependencies)
{
Name = name;
Version = version;
Description = description;
DownLoadLink = downLoadLink;
SupportedOS = supportedOS;
Dependencies = dependencies;
HasDependencies = dependencies.Count > 0;
}
public PluginOnlineInfo(string name, PluginVersion version, string description, string downLoadLink, OSType supportedOS)
{
Name = name;
Version = version;
Description = description;
DownLoadLink = downLoadLink;
SupportedOS = supportedOS;
Dependencies = new List<OnlineDependencyInfo>();
HasDependencies = false;
}
public static async Task<PluginOnlineInfo> FromRawData(string jsonText)
{
return await JsonManager.ConvertFromJson<PluginOnlineInfo>(jsonText);
}
public override string ToString()
{
return $"{Name} - {Version} ({Description})";
}
}

View File

@@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LevelingSystem", "..\SethPl
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PythonCompatibilityLayer", "..\SethPlugins\PythonCompatibilityLayer\PythonCompatibilityLayer.csproj", "{81ED4953-13E5-4950-96A8-8CEF5FD59559}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PythonCompatibilityLayer", "..\SethPlugins\PythonCompatibilityLayer\PythonCompatibilityLayer.csproj", "{81ED4953-13E5-4950-96A8-8CEF5FD59559}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseCreator", "DatabaseCreator\DatabaseCreator.csproj", "{D9BC7451-74A4-4FB3-86CC-A59F6DB889B4}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -41,6 +43,10 @@ Global
{81ED4953-13E5-4950-96A8-8CEF5FD59559}.Debug|Any CPU.Build.0 = Debug|Any CPU {81ED4953-13E5-4950-96A8-8CEF5FD59559}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81ED4953-13E5-4950-96A8-8CEF5FD59559}.Release|Any CPU.ActiveCfg = Release|Any CPU {81ED4953-13E5-4950-96A8-8CEF5FD59559}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81ED4953-13E5-4950-96A8-8CEF5FD59559}.Release|Any CPU.Build.0 = Release|Any CPU {81ED4953-13E5-4950-96A8-8CEF5FD59559}.Release|Any CPU.Build.0 = Release|Any CPU
{D9BC7451-74A4-4FB3-86CC-A59F6DB889B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9BC7451-74A4-4FB3-86CC-A59F6DB889B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9BC7451-74A4-4FB3-86CC-A59F6DB889B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9BC7451-74A4-4FB3-86CC-A59F6DB889B4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE