From f2599368744f7ecda791f86c27b7cfce19da755e Mon Sep 17 00:00:00 2001 From: zznty <94796179+zznty@users.noreply.github.com> Date: Sun, 17 Dec 2023 02:20:50 +0700 Subject: [PATCH] luck perms discord initial --- Kits/Config.cs | 2 +- Kits/Kits.csproj | 2 +- Kits/manifest.xml | 2 +- .../LuckPerms.Torch.Api.nuspec | 4 +- .../Abstractions/ILinkManager.cs | 11 + .../LuckPerms.Torch.Discord.csproj | 51 +++ .../Managers/ConfigManager.cs | 37 ++ .../Managers/DiscordManager.cs | 143 ++++++ .../Managers/InternalLinkManager.cs | 126 ++++++ .../Managers/LinkSteamDiscordClientManager.cs | 100 ++++ .../Managers/LinkSteamDiscordLinkManager.cs | 29 ++ .../Managers/LuckPermsCalculatorManager.cs | 94 ++++ LuckPerms.Torch.Discord/Plugin.cs | 73 +++ LuckPerms.Torch.Discord/Resources/config.yml | 16 + LuckPerms.Torch.Discord/Utils/SedbGetters.cs | 27 ++ .../Utils/TaskExtensions.cs | 136 ++++++ LuckPerms.Torch.Discord/manifest.xml | 6 + LuckPerms.Torch.Discord/packages.lock.json | 428 ++++++++++++++++++ .../LuckPerms.Torch.Utils.csproj | 3 +- .../Utils/Extensions/DelegateExtensions.cs | 8 +- LuckPerms.Torch/Impl/LpTorchBootstrap.cs | 7 +- LuckPerms.Torch/LuckPerms.Torch.csproj | 6 +- LuckPerms.Torch/manifest.xml | 2 +- LuckPerms.Torch/packages.lock.json | 24 +- Maintenance/Maintenance.csproj | 2 +- Maintenance/manifest.xml | 2 +- Maintenance/packages.lock.json | 36 +- TorchPlugins.sln | 7 + 28 files changed, 1337 insertions(+), 47 deletions(-) create mode 100644 LuckPerms.Torch.Discord/Abstractions/ILinkManager.cs create mode 100644 LuckPerms.Torch.Discord/LuckPerms.Torch.Discord.csproj create mode 100644 LuckPerms.Torch.Discord/Managers/ConfigManager.cs create mode 100644 LuckPerms.Torch.Discord/Managers/DiscordManager.cs create mode 100644 LuckPerms.Torch.Discord/Managers/InternalLinkManager.cs create mode 100644 LuckPerms.Torch.Discord/Managers/LinkSteamDiscordClientManager.cs create mode 100644 LuckPerms.Torch.Discord/Managers/LinkSteamDiscordLinkManager.cs create mode 100644 LuckPerms.Torch.Discord/Managers/LuckPermsCalculatorManager.cs create mode 100644 LuckPerms.Torch.Discord/Plugin.cs create mode 100644 LuckPerms.Torch.Discord/Resources/config.yml create mode 100644 LuckPerms.Torch.Discord/Utils/SedbGetters.cs create mode 100644 LuckPerms.Torch.Discord/Utils/TaskExtensions.cs create mode 100644 LuckPerms.Torch.Discord/manifest.xml create mode 100644 LuckPerms.Torch.Discord/packages.lock.json diff --git a/Kits/Config.cs b/Kits/Config.cs index 418d13d..d1ae0f8 100644 --- a/Kits/Config.cs +++ b/Kits/Config.cs @@ -16,5 +16,5 @@ public class Config : ViewModel [XmlAttribute(Form = XmlSchemaForm.Qualified, Namespace = "http://www.w3.org/2001/XMLSchema-instance")] // ReSharper disable once InconsistentNaming - public string noNamespaceSchemaLocation = "Kits.v1.1.0.xsd"; + public string noNamespaceSchemaLocation = "Kits.v1.1.2.xsd"; } diff --git a/Kits/Kits.csproj b/Kits/Kits.csproj index e54fa36..9add3d3 100644 --- a/Kits/Kits.csproj +++ b/Kits/Kits.csproj @@ -14,7 +14,7 @@ - + diff --git a/Kits/manifest.xml b/Kits/manifest.xml index 2c65099..ecf5132 100644 --- a/Kits/manifest.xml +++ b/Kits/manifest.xml @@ -2,5 +2,5 @@ Kits d095391d-b5ec-43a9-8ba4-6c4909227e6e - v1.1.1 + v1.1.2 \ No newline at end of file diff --git a/LuckPerms.Torch.Api/LuckPerms.Torch.Api.nuspec b/LuckPerms.Torch.Api/LuckPerms.Torch.Api.nuspec index f2ef436..1cb076e 100644 --- a/LuckPerms.Torch.Api/LuckPerms.Torch.Api.nuspec +++ b/LuckPerms.Torch.Api/LuckPerms.Torch.Api.nuspec @@ -2,13 +2,13 @@ LuckPerms.Torch.Api - 5.4.2 + 5.4.4 LuckPerms.Torch.Api Package Description - + diff --git a/LuckPerms.Torch.Discord/Abstractions/ILinkManager.cs b/LuckPerms.Torch.Discord/Abstractions/ILinkManager.cs new file mode 100644 index 0000000..93bbc07 --- /dev/null +++ b/LuckPerms.Torch.Discord/Abstractions/ILinkManager.cs @@ -0,0 +1,11 @@ +using Torch.API; +using Torch.API.Managers; + +namespace LuckPerms.Torch.Discord.Abstractions; + +public interface ILinkManager : IManager +{ + bool IsSteamIdLinked(IPlayer player); + + long? ResolveDiscordId(IPlayer player); +} \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/LuckPerms.Torch.Discord.csproj b/LuckPerms.Torch.Discord/LuckPerms.Torch.Discord.csproj new file mode 100644 index 0000000..f65ea79 --- /dev/null +++ b/LuckPerms.Torch.Discord/LuckPerms.Torch.Discord.csproj @@ -0,0 +1,51 @@ + + + + net48 + enable + enable + x64 + 12 + true + https://nuget.storage.yandexcloud.net/index.json + + + + none + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + PreserveNewest + + + + + + + + diff --git a/LuckPerms.Torch.Discord/Managers/ConfigManager.cs b/LuckPerms.Torch.Discord/Managers/ConfigManager.cs new file mode 100644 index 0000000..74b8c5d --- /dev/null +++ b/LuckPerms.Torch.Discord/Managers/ConfigManager.cs @@ -0,0 +1,37 @@ +using Microsoft.Extensions.Configuration; +using Torch.API.Managers; + +namespace LuckPerms.Torch.Discord.Managers; + +public class ConfigManager(string storagePath) : IManager +{ + private IConfigurationRoot? _configurationRoot; + + public IConfiguration Configuration => _configurationRoot ?? throw new InvalidOperationException("Manager is not attached"); + + public void Attach() + { + var configPath = Path.Combine(storagePath, "config.yml"); + + if (!File.Exists(configPath)) + ExtractDefault(configPath); + + _configurationRoot = new ConfigurationBuilder() + .AddYamlFile(configPath, false, true) + .Build(); + } + + private void ExtractDefault(string path) + { + var name = path[storagePath.Length..].TrimStart(Path.GetInvalidFileNameChars()).Replace('\\', '.'); + + using var stream = typeof(ConfigManager).Assembly.GetManifestResourceStream(name)!; + using var file = File.Create(path); + + stream.CopyTo(file); + } + + public void Detach() + { + } +} \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/Managers/DiscordManager.cs b/LuckPerms.Torch.Discord/Managers/DiscordManager.cs new file mode 100644 index 0000000..db5d4fb --- /dev/null +++ b/LuckPerms.Torch.Discord/Managers/DiscordManager.cs @@ -0,0 +1,143 @@ +using java.lang; +using java.util; +using java.util.concurrent; +using LuckPerms.Torch.Discord.Utils; +using LuckPerms.Torch.Utils.Extensions; +using net.dv8tion.jda.api; +using net.dv8tion.jda.api.hooks; +using net.dv8tion.jda.api.requests; +using net.dv8tion.jda.api.utils.cache; +using NLog; +using Torch.API; +using Torch.Managers; + +namespace LuckPerms.Torch.Discord.Managers; + +public class DiscordManager(ITorchBase torch, string token, long mainGuildId) : Manager(torch) +{ + public long MainGuildId { get; } = mainGuildId; + private static readonly ILogger Log = LogManager.GetCurrentClassLogger(); + + public JDA Client { get; private set; } = null!; + + public override void Attach() + { + var builder = JDABuilder.create(GatewayIntent.GUILD_MEMBERS) + .setToken(token) + .setEventPool(new TorchExecutor(Torch)) + .disableCache(CacheFlag.ACTIVITY, CacheFlag.VOICE_STATE, CacheFlag.EMOJI, CacheFlag.STICKER, + CacheFlag.CLIENT_STATUS, CacheFlag.ONLINE_STATUS, CacheFlag.SCHEDULED_EVENTS); + + foreach (var listenerAdapter in Torch.CurrentSession.Managers.AttachOrder.OfType()) + { + builder.addEventListeners(listenerAdapter); + } + + Client = builder.build(); + + Log.Info("Initializing Discord client..."); + + Client.awaitReady(); + } + + private class TorchExecutor(ITorchBase torch) : ExecutorService + { + private bool _shutdown; + + public void execute(Runnable command) => + torch.Invoke(command.run); + + public void shutdown() + { + _shutdown = true; + } + + public List shutdownNow() + { + shutdown(); + return com.sun.tools.javac.util.List.nil(); + } + + public bool isShutdown() => _shutdown; + + public bool isTerminated() => _shutdown; + + public bool awaitTermination(long timeout, TimeUnit unit) + { + return true; + } + + public Future submit(Callable task) + { + return torch.InvokeAsync(task.call).AsFuture(); + } + + public Future submit(Runnable task, object result) + { + return torch.InvokeAsync(() => + { + task.run(); + return result; + }).AsFuture(); + } + + public Future submit(Runnable task) + { + return torch.InvokeAsync(task.run).AsFuture(); + } + + public List invokeAll(Collection tasks) + { + var array = tasks.iterator().AsEnumerable().Select(b => torch.InvokeAsync(b.call)).ToArray(); + + try + { + Task.WaitAll(array); + } + catch + { + // we don't care + } + + return (List)array.Select(b => ((Task)b).AsFuture()).ToCollection(); + } + + public List invokeAll(Collection tasks, long timeout, TimeUnit unit) + { + var array = tasks.iterator().AsEnumerable().Select(b => torch.InvokeAsync(b.call)).ToArray(); + + try + { + Task.WaitAll(array, TimeSpan.FromMilliseconds(unit.toMillis(timeout))); + } + catch (AggregateException e) when (e.InnerExceptions is [OperationCanceledException canceledException]) + { + throw new InterruptedException(canceledException.Message); + } + catch + { + // we don't care + } + + return (List)array.Select(b => ((Task)b).AsFuture()).ToCollection(); + } + + public object invokeAny(Collection tasks) + { + var array = tasks.iterator().AsEnumerable().Select(b => torch.InvokeAsync(b.call)).ToArray(); + + var idx = Task.WaitAny(array); + + return ((Task)array[idx]).Result; + } + + public object invokeAny(Collection tasks, long timeout, TimeUnit unit) + { + var array = tasks.iterator().AsEnumerable().Select(b => torch.InvokeAsync(b.call)).ToArray(); + + var idx = Task.WaitAny(array, TimeSpan.FromMilliseconds(unit.toMillis(timeout))); + + return ((Task)array[idx]).Result; + } + } +} \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/Managers/InternalLinkManager.cs b/LuckPerms.Torch.Discord/Managers/InternalLinkManager.cs new file mode 100644 index 0000000..1833a78 --- /dev/null +++ b/LuckPerms.Torch.Discord/Managers/InternalLinkManager.cs @@ -0,0 +1,126 @@ +using System.Collections.Concurrent; +using LuckPerms.Torch.Api.Managers; +using LuckPerms.Torch.Discord.Abstractions; +using LuckPerms.Torch.Utils.Extensions; +using net.dv8tion.jda.api.events.interaction.command; +using net.dv8tion.jda.api.hooks; +using net.dv8tion.jda.api.interactions.commands; +using net.dv8tion.jda.api.interactions.commands.build; +using net.dv8tion.jda.@internal.interactions.command; +using net.luckperms.api.model.user; +using net.luckperms.api.node; +using net.luckperms.api.node.types; +using NLog; +using Sandbox.Game.World; +using Torch.API; +using Torch.API.Plugins; +using Torch.Commands; +using Torch.Managers; +using Torch.Server.Managers; +using VRage.Game.ModAPI; +using VRage.Library.Utils; + +namespace LuckPerms.Torch.Discord.Managers; + +public class InternalLinkManager(ITorchPlugin plugin) : ListenerAdapter, ILinkManager +{ + private static readonly ILogger Log = LogManager.GetCurrentClassLogger(); + + private const string DiscordIdNode = "luckperms.discord.userid"; + + [Manager.Dependency] + private readonly CommandManager _commandManager = null!; + + [Manager.Dependency] + private readonly DiscordManager _discordManager = null!; + + [Manager.Dependency] + private readonly ILuckPermsPlatformManager _luckPermsPlatformManager = null!; + + [Manager.Dependency] + private readonly MultiplayerManagerDedicated _multiplayerManager = null!; + + private readonly ConcurrentDictionary _pendingLinks = []; + + public void Attach() + { + _commandManager.Commands.AddCommand(new("link", "Links your Discord account to your Steam account", Link, + plugin, MyPromoteLevel.None)); + + _discordManager.Client.updateCommands().addCommands( + Commands.slash("link", "Links your Discord account to your Steam account") + .setGuildOnly(true) + .addOption(OptionType.INTEGER, "code", "The link code", true) + ).queue(); + } + + public override void onSlashCommandInteraction(SlashCommandInteractionEvent args) + { + var name = CommandInteractionPayloadMixin.__DefaultMethods.getName((CommandInteractionPayloadMixin)args.getInteraction()); + if (name != "link") + return; + + var code = CommandInteractionPayloadMixin.__DefaultMethods + .getOptions((CommandInteractionPayloadMixin)args.getInteraction()).iterator().AsEnumerable() + .First(b => b.getName() == "code").getAsInt(); + + if (!_pendingLinks.TryRemove(code, out var steamId)) + { + args.reply("Invalid code").setEphemeral(true).queue(); + return; + } + + var discordId = args.getUser().getId(); + + var consumer = (User user) => + { + user.data().add(MetaNode.builder(DiscordIdNode, discordId).build()); + }; + + _luckPermsPlatformManager.Api.getUserManager().modifyUser(steamId.GetUuid(), consumer.ToConsumer()); + + if (_multiplayerManager.Players.TryGetValue(steamId, out var player)) + _luckPermsPlatformManager.Api.getContextManager().signalContextUpdate(player); + + args.reply("Successfully linked").setEphemeral(true).queue(); + } + + private void Link(CommandContext context, object[] arguments) + { + if (context.Player is not MyPlayer player) + { + context.Respond("You must be in the game to link your Discord account"); + return; + } + + if (IsSteamIdLinked(_multiplayerManager.Players[player.Id.SteamId])) + { + context.Respond("You are already linked"); + return; + } + + var code = MyRandom.Instance.Next(1000, 99999); + + context.Respond(_pendingLinks.TryAdd(code, player.Id.SteamId) + ? $"Please enter command `/link {code}` on the discord server to link your Discord and Steam accounts" + : "An error occurred while trying to link your Discord and Steam accounts"); + } + + public void Detach() + { + } + + public bool IsSteamIdLinked(IPlayer player) + { + return _luckPermsPlatformManager.Api.getPlayerAdapter(typeof(IPlayer)).getUser(player).getNodes(NodeType.META) + .iterator().AsEnumerable().Any(b => b.getMetaKey() == DiscordIdNode); + } + + public long? ResolveDiscordId(IPlayer player) + { + var idValue = _luckPermsPlatformManager.Api.getPlayerAdapter(typeof(IPlayer)).getUser(player) + .getNodes(NodeType.META) + .iterator().AsEnumerable().FirstOrDefault(b => b.getMetaKey() == DiscordIdNode)?.getMetaValue(); + return idValue is null ? null : long.Parse(idValue); + } +} \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/Managers/LinkSteamDiscordClientManager.cs b/LuckPerms.Torch.Discord/Managers/LinkSteamDiscordClientManager.cs new file mode 100644 index 0000000..74565c9 --- /dev/null +++ b/LuckPerms.Torch.Discord/Managers/LinkSteamDiscordClientManager.cs @@ -0,0 +1,100 @@ +using System.Net; +using System.Net.Http; +using Microsoft.Extensions.Configuration; +using NLog; +using Torch.API.Managers; + +namespace LuckPerms.Torch.Discord.Managers; + +public class LinkSteamDiscordClientManager(IConfiguration configuration) : IManager +{ + private static readonly ILogger Log = LogManager.GetCurrentClassLogger(); + + public string ApiUrl => _client.BaseAddress!.ToString(); + + private readonly HttpClient _client = new() + { + BaseAddress = new(configuration.GetValue("backendUrl") ?? + throw new ArgumentNullException(nameof(configuration), "backendUrl is null")), + DefaultRequestHeaders = + { + { + "X-API-Key", + configuration.GetValue("apiKey") ?? + throw new ArgumentNullException(nameof(configuration), "apiKey is null") + } + } + }; + + public void Attach() + { + } + + public void Detach() + { + _client.Dispose(); + } + + /// + /// Checks if a Steam ID is linked. + /// + /// The Steam ID to check. + /// + /// A boolean value indicating whether the Steam ID is linked. + /// + /// Thrown when an HTTP request to the check API fails. + public async Task IsSteamIdLinkedAsync(ulong steamId) + { + using var response = await _client.GetAsync($"steam/check/{steamId}"); + + if (response.IsSuccessStatusCode) return true; + + if (response.StatusCode is HttpStatusCode.NotFound) return false; + + Log.Warn("Failed to check steam id {0}\n{1}", steamId, response); + + response.EnsureSuccessStatusCode(); + + return false; // should never happen + } + + /// + /// Retrieves the Steam ID associated with the given Discord ID asynchronously. + /// + /// The Discord ID to lookup the associated Steam ID for. + /// The associated Steam ID if found, otherwise null. + /// Thrown when an HTTP request to the lookup API fails. + public async Task LookupSteamIdAsync(ulong discordId) + { + using var response = await _client.GetAsync($"lookup/discord/{discordId}"); + + if (response.IsSuccessStatusCode) return ulong.Parse(await response.Content.ReadAsStringAsync()); + + if (response.StatusCode is HttpStatusCode.NotFound) return null; + + Log.Warn("Failed to lookup discord id {0}\n{1}", discordId, response); + response.EnsureSuccessStatusCode(); + + return null; // should never happen + } + + /// + /// Retrieves the Discord ID associated with a given Steam ID asynchronously. + /// + /// The Steam ID to look up. + /// The associated Discord ID, or null if no association exists. + /// Thrown when an HTTP request to the lookup API fails. + public async Task LookupDiscordIdAsync(ulong steamId) + { + using var response = await _client.GetAsync($"lookup/steam/{steamId}"); + + if (response.IsSuccessStatusCode) return ulong.Parse(await response.Content.ReadAsStringAsync()); + + if (response.StatusCode is HttpStatusCode.NotFound) return null; + + Log.Warn("Failed to lookup steam id {0}\n{1}", steamId, response); + response.EnsureSuccessStatusCode(); + + return null; // should never happen + } +} \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/Managers/LinkSteamDiscordLinkManager.cs b/LuckPerms.Torch.Discord/Managers/LinkSteamDiscordLinkManager.cs new file mode 100644 index 0000000..a6be4a4 --- /dev/null +++ b/LuckPerms.Torch.Discord/Managers/LinkSteamDiscordLinkManager.cs @@ -0,0 +1,29 @@ +using LuckPerms.Torch.Discord.Abstractions; +using Torch.Managers; + +namespace LuckPerms.Torch.Discord.Managers; + +#if false +public class LinkSteamDiscordLinkManager : ILinkManager +{ + [Manager.Dependency] + private readonly LinkSteamDiscordClientManager _apiManager = null!; + + public void Attach() + { + } + + public void Detach() + { + } + + public Task IsSteamIdLinkedAsync(ulong steamId) => _apiManager.IsSteamIdLinkedAsync(steamId); + + public async Task IsDiscordIdLinkedAsync(ulong discordId) => + await _apiManager.LookupSteamIdAsync(discordId) is not null; + + public Task ResolveSteamIdAsync(ulong discordId) => _apiManager.LookupSteamIdAsync(discordId); + + public Task ResolveDiscordIdAsync(ulong steamId) => _apiManager.LookupSteamIdAsync(steamId); +} +#endif \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/Managers/LuckPermsCalculatorManager.cs b/LuckPerms.Torch.Discord/Managers/LuckPermsCalculatorManager.cs new file mode 100644 index 0000000..a41a63c --- /dev/null +++ b/LuckPerms.Torch.Discord/Managers/LuckPermsCalculatorManager.cs @@ -0,0 +1,94 @@ +using LuckPerms.Torch.Api.Managers; +using LuckPerms.Torch.Discord.Abstractions; +using LuckPerms.Torch.Utils.Extensions; +using net.dv8tion.jda.api.entities; +using net.luckperms.api.context; +using Torch.API; +using Torch.API.Managers; +using Torch.Managers; + +namespace LuckPerms.Torch.Discord.Managers; + +public class LuckPermsCalculatorManager : IManager, ContextCalculator +{ + private const string ContextLinked = "discordsrv:linked"; + private const string ContextBoosting = "discordsrv:boosting"; + private const string ContextRole = "discordsrv:role"; + private const string ContextRoleId = "discordsrv:role_id"; + private const string ContextServerId = "discordsrv:server_id"; + + [Manager.Dependency] + private readonly DiscordManager _discordManager = null!; + + [Manager.Dependency] + private readonly ILinkManager _linkManager = null!; + + [Manager.Dependency] + private readonly ILuckPermsPlatformManager _platformManager = null!; + + public void Attach() + { + _platformManager.Api.getContextManager().registerCalculator(this); + } + + public void Detach() + { + _platformManager.Api.getContextManager().unregisterCalculator(this); + } + + public void calculate(object obj, ContextConsumer consumer) + { + var player = (IPlayer)obj; + + var discordId = _linkManager.ResolveDiscordId(player); + + consumer.accept(ContextLinked, discordId.HasValue ? "true" : "false"); + + if (!discordId.HasValue) + return; + + var member = _discordManager.Client.getGuildById(_discordManager.MainGuildId) + .getMemberById(discordId.Value); + + consumer.accept(ContextBoosting, member?.isBoosting() is true ? "true" : "false"); + + if (member is null) + return; + + consumer.accept(ContextServerId, member.getGuild().getId()); + + foreach (var role in member.getRoles().iterator().AsEnumerable()) + { + if (string.IsNullOrEmpty(role.getName())) + continue; + + consumer.accept(ContextRoleId, role.getId()); + consumer.accept(ContextRole, role.getName()); + } + } + + public ContextSet estimatePotentialContexts() + { + var builder = ImmutableContextSet.builder(); + + builder.add(ContextLinked, "true"); + builder.add(ContextLinked, "false"); + + builder.add(ContextBoosting, "true"); + builder.add(ContextBoosting, "false"); + + foreach (var role in _discordManager.Client.getGuildById(_discordManager.MainGuildId).getRoles() + .iterator().AsEnumerable()) + { + if (string.IsNullOrEmpty(role.getName())) + continue; + + builder.add(ContextRoleId, role.getId()); + builder.add(ContextRole, role.getName()); + } + + builder.add(ContextServerId, _discordManager.MainGuildId.ToString()); + + return builder.build(); + } +} \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/Plugin.cs b/LuckPerms.Torch.Discord/Plugin.cs new file mode 100644 index 0000000..371b670 --- /dev/null +++ b/LuckPerms.Torch.Discord/Plugin.cs @@ -0,0 +1,73 @@ +using LuckPerms.Torch.Discord.Managers; +using LuckPerms.Torch.Discord.Utils; +using Microsoft.Extensions.Configuration; +using Torch; +using Torch.API; +using Torch.API.Managers; +using Torch.API.Session; + +namespace LuckPerms.Torch.Discord; + +public class Plugin : TorchPluginBase +{ + public override void Init(ITorchBase torch) + { + var storagePath = Directory.CreateDirectory(Path.Combine(StoragePath, "luckperms.discord")).FullName; + + var configManager = new ConfigManager(storagePath); + torch.Managers.AddManager(configManager); + + var sessionManager = torch.Managers.GetManager(); + + sessionManager.AddFactory(_ => new LuckPermsCalculatorManager()); + + sessionManager.AddFactory(s => + { + var mode = configManager.Configuration["discord-api-mode"] ?? "internal"; + + if (mode == "sedb" && !s.Torch.Managers.GetManager().IsSedbInstalled()) + throw new InvalidOperationException("Sedb not installed"); + + var token = mode switch + { + "internal" => configManager.Configuration["internal-discord-api:token"], + "sedb" => s.Torch.Managers.GetManager().GetSedbToken(), + _ => throw new InvalidOperationException("Invalid discord api mode") + }; + + return new DiscordManager(s.Torch, token ?? throw new InvalidOperationException("Missing discord token"), + configManager.Configuration.GetValue("discord-api:main-guild-id") ?? + throw new InvalidOperationException("Missing main guild id")); + }); + + sessionManager.AddFactory(_ => new InternalLinkManager(this)); + + /*torch.GameStateChanged += (_, state) => + { + if (state != TorchGameState.Created) + return; + + var mode = configManager.Configuration["link-mode"] ?? "internal"; + + switch (mode) + { + case "link-steam-discord": + { + sessionManager.AddFactory(_ => new LinkSteamDiscordClientManager(configManager.Configuration)); + sessionManager.AddFactory(_ => new LinkSteamDiscordLinkManager()); + break; + } + case "internal": + { + sessionManager.AddFactory(_ => new InternalLinkManager(this, + Path.Combine(storagePath, + configManager.Configuration["internal-link:db-path"] ?? + throw new InvalidOperationException("Missing internal link db path")), + configManager.Configuration.GetValue("internal-link:application-id") ?? + throw new InvalidOperationException("Missing internal link application id"))); + break; + } + } + };*/ + } +} \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/Resources/config.yml b/LuckPerms.Torch.Discord/Resources/config.yml new file mode 100644 index 0000000..6ae8da0 --- /dev/null +++ b/LuckPerms.Torch.Discord/Resources/config.yml @@ -0,0 +1,16 @@ +# Discord API used for interacting with discord: +# Available integrations: +# internal (Using internal discord api manager, you must provide bot token down below) +# sedb (Using SE-DiscordBridge plugin from Bishbash777 https://torchapi.com/plugins/view/3cd3ba7f-c47c-4efe-8cf1-bd3f618f5b9c) +discord-api-mode: internal + +# Configuration options for discord api manager (regardless of discord-api-mode): +discord-api: +# Id of a discord server where the plugin will work +# main-guild-id: 12345 + +# Configuration options for internal discord api manager (if discord-api-mode is set to internal): +internal-discord-api: +# Discord bot token (can be obtained from https://discord.com/developers/applications) make sure to enable ALL intents +# token: token here + \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/Utils/SedbGetters.cs b/LuckPerms.Torch.Discord/Utils/SedbGetters.cs new file mode 100644 index 0000000..6aae145 --- /dev/null +++ b/LuckPerms.Torch.Discord/Utils/SedbGetters.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using Torch.API.Managers; +using Torch.API.Plugins; + +namespace LuckPerms.Torch.Discord.Utils; + +public static class SedbGetters +{ + private static readonly Guid SedbId = new("3cd3ba7f-c47c-4efe-8cf1-bd3f618f5b9c"); + + public static bool IsSedbInstalled(this IPluginManager pluginManager) => pluginManager.Plugins.ContainsKey(SedbId); + + public static string? GetSedbToken(this IPluginManager pluginManager) + { + var instance = GetConfigProp(pluginManager, out var configProp); + var tokenProp = configProp.PropertyType.GetProperty("BotToken") ?? throw new InvalidOperationException("BotToken property not found"); + + return tokenProp.GetValue(configProp.GetValue(instance)) as string; + } + + private static ITorchPlugin GetConfigProp(IPluginManager pluginManager, out PropertyInfo configProp) + { + var instance = pluginManager.Plugins[SedbId]; + configProp = instance.GetType().GetProperty("Config") ?? throw new InvalidOperationException("Config property not found"); + return instance; + } +} \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/Utils/TaskExtensions.cs b/LuckPerms.Torch.Discord/Utils/TaskExtensions.cs new file mode 100644 index 0000000..5b56e40 --- /dev/null +++ b/LuckPerms.Torch.Discord/Utils/TaskExtensions.cs @@ -0,0 +1,136 @@ +using java.util.concurrent; + +namespace LuckPerms.Torch.Discord.Utils; + +public static class TaskExtensions +{ + public static Future AsFuture(this Task task) + { + return new FutureAdapter(task); + } + + public static Future AsFuture(this Task task) + { + return new FutureAdapter(task); + } +} + +public class FutureAdapter(Task task) : Future +{ + public bool cancel(bool mayInterruptIfRunning) + { + throw new InvalidOperationException("Task is not cancellable"); + } + + public bool isCancelled() => task.IsCanceled; + + public bool isDone() => task.Status is TaskStatus.RanToCompletion or TaskStatus.Faulted or TaskStatus.Canceled; + + public object? get() + { + if (!isDone()) + try + { + task.Wait(); + } + catch (AggregateException e) when (e.InnerExceptions is [ TaskCanceledException canceledException ]) + { + throw new CancellationException(canceledException.Message); + } + catch (AggregateException e) + { + throw new ExecutionException(e); + } + + if (task.IsCanceled) + throw new CancellationException(); + if (task.IsFaulted) + throw new ExecutionException(task.Exception); + + return task.Result; + } + + public object? get(long timeout, TimeUnit unit) + { + if (!isDone()) + try + { + task.Wait(TimeSpan.FromMilliseconds(unit.toMillis(timeout))); + } // TODO: InterruptedException and TimeoutException + catch (AggregateException e) when (e.InnerExceptions is [ TaskCanceledException canceledException ]) + { + throw new CancellationException(canceledException.Message); + } + catch (AggregateException e) + { + throw new ExecutionException(e); + } + + if (task.IsCanceled) + throw new CancellationException(); + if (task.IsFaulted) + throw new ExecutionException(task.Exception); + + return task.Result; + } +} + +public class FutureAdapter(Task task) : Future +{ + public bool cancel(bool mayInterruptIfRunning) + { + throw new InvalidOperationException("Task is not cancellable"); + } + + public bool isCancelled() => task.IsCanceled; + + public bool isDone() => task.Status is TaskStatus.RanToCompletion or TaskStatus.Faulted or TaskStatus.Canceled; + + public object? get() + { + if (!isDone()) + try + { + task.Wait(); + } + catch (AggregateException e) when (e.InnerExceptions is [ TaskCanceledException canceledException ]) + { + throw new CancellationException(canceledException.Message); + } + catch (AggregateException e) + { + throw new ExecutionException(e); + } + + if (task.IsCanceled) + throw new CancellationException(); + if (task.IsFaulted) + throw new ExecutionException(task.Exception); + + return null; + } + + public object? get(long timeout, TimeUnit unit) + { + if (!isDone()) + try + { + task.Wait(TimeSpan.FromMilliseconds(unit.toMillis(timeout))); + } // TODO: InterruptedException and TimeoutException + catch (AggregateException e) when (e.InnerExceptions is [ TaskCanceledException canceledException ]) + { + throw new CancellationException(canceledException.Message); + } + catch (AggregateException e) + { + throw new ExecutionException(e); + } + + if (task.IsCanceled) + throw new CancellationException(); + if (task.IsFaulted) + throw new ExecutionException(task.Exception); + + return null; + } +} \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/manifest.xml b/LuckPerms.Torch.Discord/manifest.xml new file mode 100644 index 0000000..fe86c28 --- /dev/null +++ b/LuckPerms.Torch.Discord/manifest.xml @@ -0,0 +1,6 @@ + + + LuckPerms.Torch.Discord + 8E87A61E-A243-4227-88DD-AD3E2ECD9D62 + v1.0.0 + \ No newline at end of file diff --git a/LuckPerms.Torch.Discord/packages.lock.json b/LuckPerms.Torch.Discord/packages.lock.json new file mode 100644 index 0000000..fae5393 --- /dev/null +++ b/LuckPerms.Torch.Discord/packages.lock.json @@ -0,0 +1,428 @@ +{ + "version": 1, + "dependencies": { + ".NETFramework,Version=v4.8": { + "Alexinea.Extensions.Configuration.Yaml": { + "type": "Direct", + "requested": "[7.0.0, )", + "resolved": "7.0.0", + "contentHash": "gIeecqFF2YeDrGxRulJvyYCRbQcvmowNnQt5qDg2FUS3bzjtwgahHFioD+yWFGxBYR/vWGbP3h6PGoCUxOzTqA==", + "dependencies": { + "Microsoft.Extensions.Configuration": "7.0.0", + "Microsoft.Extensions.Configuration.FileExtensions": "7.0.0", + "YamlDotNet": "12.1.0" + } + }, + "LuckPerms.Torch.Api": { + "type": "Direct", + "requested": "[5.4.4, )", + "resolved": "5.4.4", + "contentHash": "T3vg3xZcjSdB/Fmok9CkNms/KYP6QH9tpYyjBRq2ZNCRgQSZQBfqPx0VJPIJwXwip55SPm/rSKDWcmo4O5qIFg==", + "dependencies": { + "IKVM.Maven.Sdk": "1.6.2", + "LuckPerms.Torch.Utils": "1.0.3", + "Torch.Loader": "1.0.0" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "mBMoXLsr5s1y2zOHWmKsE9veDcx8h1x/c3rz4baEdQKTeDcmQAPNbB54Pi/lhFO3K431eEq6PFbMgLaa6PHFfA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "8.0.0" + } + }, + "Microsoft.Extensions.Configuration.FileExtensions": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "McP+Lz/EKwvtCv48z0YImw+L1gi1gy5rHhNaNIY2CrjloV+XY8gydT8DjMR6zWeL13AFK+DioVpppwAuO1Gi1w==", + "dependencies": { + "Microsoft.Extensions.Configuration": "8.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "8.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "8.0.0", + "Microsoft.Extensions.FileProviders.Physical": "8.0.0", + "Microsoft.Extensions.Primitives": "8.0.0" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net48": "1.0.3" + } + }, + "PolySharp": { + "type": "Direct", + "requested": "[1.14.0, )", + "resolved": "1.14.0", + "contentHash": "3K6beiIeVO0hOlHCHv2jgGW7UH3OXsOIiEW60CHpqGvbrHyy4iQfGkCOBtI92PDCaA8XC4ZM3+02g2qenRnHOA==" + }, + "Torch.Server.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.3.1.260-master, )", + "resolved": "1.3.1.260-master", + "contentHash": "p9fHBwPI2BZDLO2PiSPvJxHQ7lksYf/20BZ0uUxMlSnJk/AvFUpjT6CMxJWow4UuAFG+NcPEI4VhxZ5x9jhGGA==", + "dependencies": { + "NLog": "4.4.12", + "Newtonsoft.Json": "12.0.2", + "SpaceEngineersDedicated.ReferenceAssemblies": "1.203.505" + } + }, + "IKVM": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "2s1yFo67hGmm0ooimR9kbOcyDKK77n/Hrm9aJ25EfHMSp5VTvlS46SCOP8vQpxpxXJ8eGQTSrYJsQ7asDAtlzQ==", + "dependencies": { + "IKVM.Image": "8.7.3", + "IKVM.MSBuild": "8.7.3", + "Mono.Posix": "7.1.0-final.1.21458.1", + "Mono.Unix": "7.1.0-final.1.21458.1", + "System.Buffers": "4.5.1", + "System.IO.Pipelines": "6.0.3", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Text.Json": "6.0.6", + "System.ValueTuple": "4.5.0" + } + }, + "IKVM.Image": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "KvXDegE7+6Z42to5LxVyINvq0/V8ubStlaA9dwz+QxI2qLBK2JS8MTAXlRVmWGDJ0XKWvycBHP8XZl250ZT1iQ==", + "dependencies": { + "IKVM.Image.runtime.linux-arm": "8.7.3", + "IKVM.Image.runtime.linux-arm64": "8.7.3", + "IKVM.Image.runtime.linux-musl-arm": "8.7.3", + "IKVM.Image.runtime.linux-musl-arm64": "8.7.3", + "IKVM.Image.runtime.linux-musl-x64": "8.7.3", + "IKVM.Image.runtime.linux-x64": "8.7.3", + "IKVM.Image.runtime.osx-arm64": "8.7.3", + "IKVM.Image.runtime.osx-x64": "8.7.3", + "IKVM.Image.runtime.win-arm64": "8.7.3", + "IKVM.Image.runtime.win-x64": "8.7.3", + "IKVM.Image.runtime.win-x86": "8.7.3" + } + }, + "IKVM.Image.runtime.linux-arm": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "T47oi+517kbZgBn2OBjBYaZBwBRqwsHFuqzisDNhr7KA3f+YZSCCK26UOOPwwbZSCjyK0SNxQlfuLymWryUqHA==" + }, + "IKVM.Image.runtime.linux-arm64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "BZa78XMayX8eQTv9SZocdY+25ulDwscgPTPuT366M7ptO5A72yud5NtCuOCb9P4HXbJnvuRjaDLr7RPqD9BBOQ==" + }, + "IKVM.Image.runtime.linux-musl-arm": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "/dGnoJBdsXpw3KU1SfbSoVDWMCJihClQAjjJXe7WlICgAHwM1h/jApgVUTDLtUkAp/8p9m+M6bS+kzXbEC2DUw==" + }, + "IKVM.Image.runtime.linux-musl-arm64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "jmlE6CcPVy64CmsiUq4ETJFey3vt8ruVn8i/bnyYRCqRJEbIZcmNWh1Cr6TGKqb1D9trhiaiJk6beULXVqsLsQ==" + }, + "IKVM.Image.runtime.linux-musl-x64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "RsiiPjsea/vWY0E6gV5sUyWwkdoYumBORHt/eew8C9ykcWEdvQ0YE6MNvgpjzvI0MA2VBP9+aGCBPJtlA3Fupw==" + }, + "IKVM.Image.runtime.linux-x64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "0qM5ISDfmNVaD6ujCa8/hTU/ZZPmOv7VwSXY9k/15E27hajY0Jwz1FnhenvY87ShUMUX6VL5f+1v/C8o1JjAZg==" + }, + "IKVM.Image.runtime.osx-arm64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "sktbKiIvp8JhZOCR5HY2+L13VGKpVm83LNKYXKv9oWb0eFeLASguJZ24pk3NMD4f6u0EaCDz6ltDiy1ydYChHg==" + }, + "IKVM.Image.runtime.osx-x64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "Gt9xTUZoVzYzHrJXsOECbgppeeuzNwws4dbmDE6I7/jL/exk1993VIbyhe1/YIPPIkx3enrBmOYIVMbx6sNOUg==" + }, + "IKVM.Image.runtime.win-arm64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "nLUWfNrqgePz+4FL5AIAM6xNf9v/hviO0OZhVMMRNPIAHL7qq4yVath1xqpGIB8C3x5Bn8VnUZ8Qrla9yupSCQ==" + }, + "IKVM.Image.runtime.win-x64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "G7j8+tyL055K5KCGfdg5lsk+rdvIri66VXtgZYweh5eVAO4wKteC+gOBku2KpHxD/9mqE6qQKZLDlOcmyBvnuw==" + }, + "IKVM.Image.runtime.win-x86": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "0njpqRJhZ/UTvM5q7vKEAh2ITNar2jPMMEYX2IDMEnOM2zBaEd6e3KIlUWFIYS4d2MamnpNjMDmeOTwLzaF+/g==" + }, + "IKVM.Maven.Sdk": { + "type": "Transitive", + "resolved": "1.6.2", + "contentHash": "RbUpfun4wU5PxBEJ1STAe8wGcZ090oyf2NoyWdwkoKewm3pQFCtU9jN54uo9pZfC/Or9sArrK/7XvC4InTPmzg==", + "dependencies": { + "IKVM": "8.7.1" + } + }, + "IKVM.MSBuild": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "/ScKw7jNT+VCKHjaFtOAn8sA3uplNaqBYZsOhn4cHml8bPGoiaHpf6b/kxjQbkc3BNFu4waBP/lVeqW8SuSsPw==", + "dependencies": { + "IKVM.MSBuild.Tools": "8.7.3" + } + }, + "IKVM.MSBuild.Tools": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "kpkHdpJU8ZQctyBt7A2qtosWFQ7Hvf+ctxyOvSmiVJUoKtEMporEAOOvnlVutkC/HG3QVQzRY7BcVmHQ7kmwgA==", + "dependencies": { + "IKVM.MSBuild.Tools.runtime.linux-arm": "8.7.3", + "IKVM.MSBuild.Tools.runtime.linux-arm64": "8.7.3", + "IKVM.MSBuild.Tools.runtime.linux-x64": "8.7.3", + "IKVM.MSBuild.Tools.runtime.osx-arm64": "8.7.3", + "IKVM.MSBuild.Tools.runtime.osx-x64": "8.7.3", + "IKVM.MSBuild.Tools.runtime.win-arm64": "8.7.3", + "IKVM.MSBuild.Tools.runtime.win-x64": "8.7.3" + } + }, + "IKVM.MSBuild.Tools.runtime.linux-arm": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "wqu9X/6X0JW3JXnGAqWZOt5owcSqmg56tZFMnrinPVgwaL0PdsLtqLp63NbdwLZX9HKyVJocsaLLTBR+G599KQ==" + }, + "IKVM.MSBuild.Tools.runtime.linux-arm64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "ZZMwSRZqFMw6x75ttKjy2LDjKWWvD2um86+orsgO8SPPB9pt2ZS1qy3QKuGLV3hwfxgFB1VfFwMZpQ1+zfzKLg==" + }, + "IKVM.MSBuild.Tools.runtime.linux-x64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "ZhNb+reE+XdSXJRiVnKeg9FBAWf5OuRhkReuavFUkZbtvKhAgvGLOUoG6VHYhAfUZ3rtN7q3S0ntdZsp09pIqA==" + }, + "IKVM.MSBuild.Tools.runtime.osx-arm64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "iRu99QK3Pyxiu/M9vbF6K0HhGhCYD+SaB5Lp0JgvQeHF/94m2f5CtF7r6hxcAq7VtmOi72OJ+oZzdGGpSnnWtA==" + }, + "IKVM.MSBuild.Tools.runtime.osx-x64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "l6PIfFARkis06hjVqMSQf2uDl6uRkNJXm4e0mUehaLrALeq8eteWIA1FhQEROguLgVEGU8OWelPWb1uuYtJWag==" + }, + "IKVM.MSBuild.Tools.runtime.win-arm64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "/6Rf3+2s8P89HrDqFE6GEEUfs6orygQEokS0hAQr2CqhfA6HqsEieO4RlYCDes7Zgwu5LNMTbNWuAEIJNNj1XA==" + }, + "IKVM.MSBuild.Tools.runtime.win-x64": { + "type": "Transitive", + "resolved": "8.7.3", + "contentHash": "HUIKfpngT9uPcOZzzBCZlqUBZaz23VVOWem2vFl61JeCL/2RpVa3UQtC9ZZfxGknhF5wjzkLbsnnzU4lFUREww==" + }, + "LuckPerms.Torch.Utils": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "rM7VY70oeBJdogtCtXAlCAxd5uWtkDVtV3BnvgpgWkqMMdIS+YBCUCyaglTMURTvcP6EcxrkckieHKis4oRM+A==", + "dependencies": { + "IKVM": "8.7.3", + "System.Text.Json": "8.0.0" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "0J/9YNXTMWSZP2p2+nvl8p71zpSwokZXZuJW+VjdErkegAnFdO1XlqtA62SJtgVYHdKu3uPxJHcMR/r35HwFBA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "8.0.0", + "Microsoft.Extensions.Primitives": "8.0.0" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==", + "dependencies": { + "Microsoft.Extensions.Primitives": "8.0.0", + "System.ValueTuple": "4.5.0" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "ZbaMlhJlpisjuWbvXr4LdAst/1XxH3vZ6A0BsgTphZ2L4PGuxRLz7Jr/S7mkAAnOn78Vu0fKhEgNF5JO3zfjqQ==", + "dependencies": { + "Microsoft.Extensions.Primitives": "8.0.0" + } + }, + "Microsoft.Extensions.FileProviders.Physical": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "UboiXxpPUpwulHvIAVE36Knq0VSHaAmfrFkegLyBZeaADuKezJ/AIXYAW8F5GBlGk/VaibN2k/Zn1ca8YAfVdA==", + "dependencies": { + "Microsoft.Extensions.FileProviders.Abstractions": "8.0.0", + "Microsoft.Extensions.FileSystemGlobbing": "8.0.0", + "Microsoft.Extensions.Primitives": "8.0.0" + } + }, + "Microsoft.Extensions.FileSystemGlobbing": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OK+670i7esqlQrPjdIKRbsyMCe9g5kSLpRRQGSr4Q58AOYEe/hCnfLZprh7viNisSUUQZmMrbbuDaIrP+V1ebQ==" + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net48": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "zMk4D+9zyiEWByyQ7oPImPN/Jhpj166Ky0Nlla4eXlNL8hI/BtSJsgR8Inldd4NNpIAH3oh8yym0W2DrhXdSLQ==" + }, + "Mono.Posix": { + "type": "Transitive", + "resolved": "7.1.0-final.1.21458.1", + "contentHash": "xhil/0zRkA2MrkyMZXC3dPSDWOhq6YD0vYGl1VnBbjsEZfLQCu7+mJZ/ftnOd0r4qmeHVeNuW6Pt33NoxO671A==", + "dependencies": { + "Mono.Unix": "7.1.0-final.1.21458.1" + } + }, + "Mono.Unix": { + "type": "Transitive", + "resolved": "7.1.0-final.1.21458.1", + "contentHash": "Rhxz4A7By8Q0wEgDqR+mioDsYXGrcYMYPiWE9bSaUKMpG8yAGArhetEQV5Ms6KhKCLdQTlPYLBKPZYoKbAvT/g==" + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "12.0.2", + "contentHash": "rTK0s2EKlfHsQsH6Yx2smvcTCeyoDNgCW7FEYyV01drPlh2T243PR2DiDXqtC5N4GDm4Ma/lkxfW5a/4793vbA==" + }, + "NLog": { + "type": "Transitive", + "resolved": "4.4.12", + "contentHash": "fODew3BFT2XhAuqhGo2ZYT9OJE0ciGEBfvKXOmAAvaDsP/3ROIf083p8QUnmwKKw4jCkVW06ObX6gn/eFi2Skg==" + }, + "protobuf-net": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "kTGOK0E87473sOImOjgZOnz3kTC2aMLffoRWQLYNuBLJnwNNmjanF9IkevZ9Q7yYLeABQfcF3BpeepuMntMVNw==" + }, + "SpaceEngineersDedicated.ReferenceAssemblies": { + "type": "Transitive", + "resolved": "1.203.505", + "contentHash": "Wq4GIn2ilHyFdLdVKdVhC7iGQ+1FdVsChKY6hyQluFYSSV7oe8bDc9aTZC8XgxNMKCZoQBSVyaYHxQD+74BySQ==", + "dependencies": { + "protobuf-net": "1.0.0" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "6.0.3", + "contentHash": "ryTgF+iFkpGZY1vRQhfCzX0xTdlV3pyaTTqRu2ETbEv+HlV7O6y7hyQURnghNIXvctl5DuZ//Dpks6HdL/Txgw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4", + "System.ValueTuple": "4.5.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.ValueTuple": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, + "Torch.Loader": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "HkuAujKa9IqPPqoA1205teUPBxuNOC9z0xZJkrMlFT0htH02X0ieZ5qh4onwyV10qVKiRBCSLkc5tA8lp1l5ig==" + }, + "YamlDotNet": { + "type": "Transitive", + "resolved": "12.1.0", + "contentHash": "iP6tzi3DJ16wyTtEClbG8W6epvc+MvKSBdNcpllzhal40C94WzjWxF2aszcoOSjbESsWXsLY+NoRewgfo8ah6Q==" + } + } + } +} \ No newline at end of file diff --git a/LuckPerms.Torch.Utils/LuckPerms.Torch.Utils.csproj b/LuckPerms.Torch.Utils/LuckPerms.Torch.Utils.csproj index 8112330..519ec0c 100644 --- a/LuckPerms.Torch.Utils/LuckPerms.Torch.Utils.csproj +++ b/LuckPerms.Torch.Utils/LuckPerms.Torch.Utils.csproj @@ -6,7 +6,7 @@ 12 enable enable - 1.0.2 + 1.0.4 @@ -23,6 +23,7 @@ + diff --git a/LuckPerms.Torch.Utils/Utils/Extensions/DelegateExtensions.cs b/LuckPerms.Torch.Utils/Utils/Extensions/DelegateExtensions.cs index 9470c51..1303a6b 100644 --- a/LuckPerms.Torch.Utils/Utils/Extensions/DelegateExtensions.cs +++ b/LuckPerms.Torch.Utils/Utils/Extensions/DelegateExtensions.cs @@ -10,19 +10,19 @@ public static class DelegateExtensions { private static readonly Func AndThenDefault = (Func)typeof(Consumer).GetMethod("andThen", - BindingFlags.Static | BindingFlags.NonPublic)!.CreateDelegate(typeof(Func)); + BindingFlags.Static | BindingFlags.Public)!.CreateDelegate(typeof(Func)); private static readonly Func AndDefault = (Func)typeof(Predicate).GetMethod("and", - BindingFlags.Static | BindingFlags.NonPublic)!.CreateDelegate(typeof(Func)); + BindingFlags.Static | BindingFlags.Public)!.CreateDelegate(typeof(Func)); private static readonly Func NegateDefault = (Func)typeof(Predicate).GetMethod("negate", - BindingFlags.Static | BindingFlags.NonPublic)!.CreateDelegate(typeof(Func)); + BindingFlags.Static | BindingFlags.Public)!.CreateDelegate(typeof(Func)); private static readonly Func OrDefault = (Func)typeof(Predicate).GetMethod("or", - BindingFlags.Static | BindingFlags.NonPublic)!.CreateDelegate(typeof(Func)); + BindingFlags.Static | BindingFlags.Public)!.CreateDelegate(typeof(Func)); public static Runnable ToRunnable(this Action action) => new DelegateRunnable(action); diff --git a/LuckPerms.Torch/Impl/LpTorchBootstrap.cs b/LuckPerms.Torch/Impl/LpTorchBootstrap.cs index b0de7fb..58f062a 100644 --- a/LuckPerms.Torch/Impl/LpTorchBootstrap.cs +++ b/LuckPerms.Torch/Impl/LpTorchBootstrap.cs @@ -68,7 +68,12 @@ public class LpTorchBootstrap : LuckPermsBootstrap _torch.CurrentSession?.Managers.GetManager().Players .ContainsKey(uuid.GetSteamId()) ?? false; - public string getVersion() => _torchPlugin.Version.TrimStart('v'); + public string getVersion() + { + // has to be 3 component for web editor to work + var version = Version.Parse(_torchPlugin.Version.TrimStart('v')); + return $"{version.Major}.{version.Minor}.{version.Build}"; + } public string getServerBrand() => "Torch"; diff --git a/LuckPerms.Torch/LuckPerms.Torch.csproj b/LuckPerms.Torch/LuckPerms.Torch.csproj index 74cbaba..51862fe 100644 --- a/LuckPerms.Torch/LuckPerms.Torch.csproj +++ b/LuckPerms.Torch/LuckPerms.Torch.csproj @@ -210,13 +210,13 @@ $(ExaminationApiPath);$(ExaminationStringPath);$(AdventureKeyPath);$(AnnotationsPath) - $(AdventureApiPath);$(AnnotationsPath);$(ExaminationApiPath) + $(AdventureApiPath);$(AnnotationsPath);$(ExaminationApiPath);$(AdventureKeyPath) - $(AdventureApiPath);$(ExaminationApiPath) + $(AdventureApiPath);$(ExaminationApiPath);$(AdventureKeyPath) - $(AdventureApiPath);$(ExaminationApiPath) + $(AdventureApiPath);$(ExaminationApiPath);$(AdventureKeyPath) diff --git a/LuckPerms.Torch/manifest.xml b/LuckPerms.Torch/manifest.xml index 24d033f..883635f 100644 --- a/LuckPerms.Torch/manifest.xml +++ b/LuckPerms.Torch/manifest.xml @@ -2,5 +2,5 @@ LuckPerms.Torch 7E4B3CC8-64FA-416E-8910-AACDF2DA5E2C - v5.4.106.7 + v5.4.106.9 \ No newline at end of file diff --git a/LuckPerms.Torch/packages.lock.json b/LuckPerms.Torch/packages.lock.json index 2052190..b4ef324 100644 --- a/LuckPerms.Torch/packages.lock.json +++ b/LuckPerms.Torch/packages.lock.json @@ -194,8 +194,8 @@ }, "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg==", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", "dependencies": { "System.Threading.Tasks.Extensions": "4.5.4" } @@ -322,25 +322,24 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", "dependencies": { "System.Buffers": "4.5.1", - "System.Memory": "4.5.4", + "System.Memory": "4.5.5", "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.6", - "contentHash": "GZ+62pLOr544jwSvyXv5ezSfzlFBTjLuPhgOS2dnKuknAA8dPNUGXLKTHf9XdsudU9JpbtweXnE4oEiKEB2T1Q==", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", "dependencies": { - "Microsoft.Bcl.AsyncInterfaces": "6.0.0", + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", "System.Buffers": "4.5.1", - "System.Memory": "4.5.4", - "System.Numerics.Vectors": "4.5.0", + "System.Memory": "4.5.5", "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encodings.Web": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", "System.Threading.Tasks.Extensions": "4.5.4", "System.ValueTuple": "4.5.0" } @@ -361,7 +360,8 @@ "luckperms.torch.utils": { "type": "Project", "dependencies": { - "IKVM": "[8.7.3, )" + "IKVM": "[8.7.3, )", + "System.Text.Json": "[8.0.0, )" } } }, diff --git a/Maintenance/Maintenance.csproj b/Maintenance/Maintenance.csproj index 272f440..6fd0e7b 100644 --- a/Maintenance/Maintenance.csproj +++ b/Maintenance/Maintenance.csproj @@ -16,7 +16,7 @@ - + diff --git a/Maintenance/manifest.xml b/Maintenance/manifest.xml index 54ce52b..e59b4ac 100644 --- a/Maintenance/manifest.xml +++ b/Maintenance/manifest.xml @@ -2,5 +2,5 @@ Maintenance 42AF9955-AAA7-442F-9BF4-AAC4FA4A923F - v1.0.1 + v1.0.2 \ No newline at end of file diff --git a/Maintenance/packages.lock.json b/Maintenance/packages.lock.json index 7bb91a7..9a02ad1 100644 --- a/Maintenance/packages.lock.json +++ b/Maintenance/packages.lock.json @@ -15,12 +15,12 @@ }, "LuckPerms.Torch.Api": { "type": "Direct", - "requested": "[5.4.2, )", - "resolved": "5.4.2", - "contentHash": "zX3mA9fVR2YVWbbKRqGaDAp2yTjyNw2SK1wwZbx1WLsJb1D3MoPxUqOJACaJI+kAp7vRLMcxDCzPKzXJ127Xzw==", + "requested": "[5.4.4, )", + "resolved": "5.4.4", + "contentHash": "T3vg3xZcjSdB/Fmok9CkNms/KYP6QH9tpYyjBRq2ZNCRgQSZQBfqPx0VJPIJwXwip55SPm/rSKDWcmo4O5qIFg==", "dependencies": { "IKVM.Maven.Sdk": "1.6.2", - "LuckPerms.Torch.Utils": "1.0.2", + "LuckPerms.Torch.Utils": "1.0.3", "Torch.Loader": "1.0.0" } }, @@ -240,16 +240,17 @@ }, "LuckPerms.Torch.Utils": { "type": "Transitive", - "resolved": "1.0.2", - "contentHash": "MzOJpLqYn+CDrr+mKAJKYyCQy89QEdKJyC4ESJ+YyFMF0T1cDZEqFE72aFaGQcdCKATZgFaedpT0ULUbIZZEXQ==", + "resolved": "1.0.3", + "contentHash": "rM7VY70oeBJdogtCtXAlCAxd5uWtkDVtV3BnvgpgWkqMMdIS+YBCUCyaglTMURTvcP6EcxrkckieHKis4oRM+A==", "dependencies": { - "IKVM": "8.7.3" + "IKVM": "8.7.3", + "System.Text.Json": "8.0.0" } }, "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg==", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", "dependencies": { "System.Threading.Tasks.Extensions": "4.5.4" } @@ -387,25 +388,24 @@ }, "System.Text.Encodings.Web": { "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", "dependencies": { "System.Buffers": "4.5.1", - "System.Memory": "4.5.4", + "System.Memory": "4.5.5", "System.Runtime.CompilerServices.Unsafe": "6.0.0" } }, "System.Text.Json": { "type": "Transitive", - "resolved": "6.0.6", - "contentHash": "GZ+62pLOr544jwSvyXv5ezSfzlFBTjLuPhgOS2dnKuknAA8dPNUGXLKTHf9XdsudU9JpbtweXnE4oEiKEB2T1Q==", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", "dependencies": { - "Microsoft.Bcl.AsyncInterfaces": "6.0.0", + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", "System.Buffers": "4.5.1", - "System.Memory": "4.5.4", - "System.Numerics.Vectors": "4.5.0", + "System.Memory": "4.5.5", "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encodings.Web": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", "System.Threading.Tasks.Extensions": "4.5.4", "System.ValueTuple": "4.5.0" } diff --git a/TorchPlugins.sln b/TorchPlugins.sln index 2963931..946c6f4 100644 --- a/TorchPlugins.sln +++ b/TorchPlugins.sln @@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maintenance", "Maintenance\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuckPerms.Torch.Utils", "LuckPerms.Torch.Utils\LuckPerms.Torch.Utils.csproj", "{615FD610-A3E6-457F-B8B9-C9D1235A4B2C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuckPerms.Torch.Discord", "LuckPerms.Torch.Discord\LuckPerms.Torch.Discord.csproj", "{5A72795F-3BBD-4205-814B-8B68F57EB7C9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -77,6 +79,10 @@ Global {615FD610-A3E6-457F-B8B9-C9D1235A4B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU {615FD610-A3E6-457F-B8B9-C9D1235A4B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU {615FD610-A3E6-457F-B8B9-C9D1235A4B2C}.Release|Any CPU.Build.0 = Release|Any CPU + {5A72795F-3BBD-4205-814B-8B68F57EB7C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A72795F-3BBD-4205-814B-8B68F57EB7C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A72795F-3BBD-4205-814B-8B68F57EB7C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A72795F-3BBD-4205-814B-8B68F57EB7C9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {AD9B7D1E-386A-4EF2-B475-BCB770537035} = {06CD2354-307D-4A1C-B46B-1D9EB3AAE742} @@ -89,5 +95,6 @@ Global {927CB303-E699-4716-A62E-232AE1125159} = {862C7244-258E-4BFD-B271-9AA2D3FBE916} {66F3BF72-D663-44E0-B54C-5193E39839B9} = {2C911BD8-8B11-460E-AB7E-16552949A6FC} {615FD610-A3E6-457F-B8B9-C9D1235A4B2C} = {862C7244-258E-4BFD-B271-9AA2D3FBE916} + {5A72795F-3BBD-4205-814B-8B68F57EB7C9} = {2C911BD8-8B11-460E-AB7E-16552949A6FC} EndGlobalSection EndGlobal