Refactored a bunch of things
Added Notes Module + Data Structure Added Config Module + Data Structure Added Role Buttons Module + Data Structure
This commit is contained in:
parent
aab1fad4e2
commit
7f08d72ef8
23 changed files with 638 additions and 83 deletions
31
SMSModLogOutputAnalyzer/Data/Config.cs
Normal file
31
SMSModLogOutputAnalyzer/Data/Config.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using Discord.Interactions;
|
||||
using Discord;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using Orpticon.Wrappers;
|
||||
using SMSModLogOutputAnalyzer.Modules;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Data
|
||||
{
|
||||
public partial class Config
|
||||
{
|
||||
public static ITextChannel NotesLogChannel { get => (ITextChannel)Program.Client.GetChannel(Instance.notesLogChannel); set => Instance.notesLogChannel = value.Id; }
|
||||
[XmlAttribute] public ulong notesLogChannel { get; set; }
|
||||
|
||||
|
||||
|
||||
public static void Load()
|
||||
{
|
||||
Instance = SerializerXML.DeserializeFromFileOrDefault<Config>("Config.xml");
|
||||
}
|
||||
public static void Save()
|
||||
{
|
||||
SerializerXML.SerializeToFile(Instance, "Config.xml");
|
||||
}
|
||||
public static Config Instance { get; set; }
|
||||
}
|
||||
}
|
||||
24
SMSModLogOutputAnalyzer/Data/NotesDataObject.Note.cs
Normal file
24
SMSModLogOutputAnalyzer/Data/NotesDataObject.Note.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
using Discord;
|
||||
using System.Reactive;
|
||||
using System.Xml.Serialization;
|
||||
using static SMSModLogOutputAnalyzer.Data.NotesDataObject;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Data
|
||||
{
|
||||
public partial class NotesDataObject
|
||||
{
|
||||
public class Note
|
||||
{
|
||||
[XmlAttribute] public string Text { get; set; }
|
||||
[XmlAttribute] public ulong CreatorID { get; set; }
|
||||
[XmlAttribute] public DateTime CreationTime { get; set; }
|
||||
[XmlAttribute] public int Id { get; set; }
|
||||
public EmbedFieldBuilder ToField()
|
||||
{
|
||||
var unix = ((DateTimeOffset)CreationTime).ToUnixTimeSeconds();
|
||||
// "Note " + Id, "`" + Text + "`\nCreated by <@" + CreatorID + "> at <t:" + unix + ":f>"
|
||||
return new EmbedFieldBuilder().WithName(Text).WithValue("ID: `" + Id + "`\nCreated by <@" + CreatorID + "> at <t:" + unix + ":f>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
SMSModLogOutputAnalyzer/Data/NotesDataObject.UserNotes.cs
Normal file
14
SMSModLogOutputAnalyzer/Data/NotesDataObject.UserNotes.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System.Xml.Serialization;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Data
|
||||
{
|
||||
public partial class NotesDataObject
|
||||
{
|
||||
public class UserNotes
|
||||
{
|
||||
[XmlAttribute] public ulong Id { get; set; }
|
||||
[XmlAttribute] public int Counter { get; set; } = 0;
|
||||
[XmlElement("Note")] public List<Note> Notes { get; set; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
42
SMSModLogOutputAnalyzer/Data/NotesDataObject.cs
Normal file
42
SMSModLogOutputAnalyzer/Data/NotesDataObject.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using Discord;
|
||||
using Orpticon.Custom;
|
||||
using Orpticon.Wrappers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Data
|
||||
{
|
||||
public partial class NotesDataObject
|
||||
{
|
||||
[XmlElement("Notes")] public List<UserNotes> List { get; set; } = new();
|
||||
[XmlIgnore] public UserNotes this[IUser user] => this[user.Id];
|
||||
[XmlIgnore]
|
||||
public UserNotes this[ulong id]
|
||||
{
|
||||
get
|
||||
{
|
||||
var notes = List.Find(x => x.Id == id);
|
||||
if(notes == null)
|
||||
{
|
||||
notes = new() { Id = id };
|
||||
List.Add(notes);
|
||||
}
|
||||
return notes;
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
SerializerXML.SerializeToFile(this, "NotesData.xml");
|
||||
}
|
||||
public static NotesDataObject Load()
|
||||
{
|
||||
var obj = SerializerXML.DeserializeFromFileOrDefault<NotesDataObject>("NotesData.xml");
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System.Xml.Serialization;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Data
|
||||
{
|
||||
public partial class RoleButtonsDataObject
|
||||
{
|
||||
public class RoleButton
|
||||
{
|
||||
[XmlAttribute] public int Id { get; set; }
|
||||
[XmlAttribute] public ulong Role { get; set; }
|
||||
[XmlAttribute] public ulong RequiredRole { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
27
SMSModLogOutputAnalyzer/Data/RoleButtonsDataObject.cs
Normal file
27
SMSModLogOutputAnalyzer/Data/RoleButtonsDataObject.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static SMSModLogOutputAnalyzer.Data.NotesDataObject;
|
||||
using System.Xml.Serialization;
|
||||
using Orpticon.Wrappers;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Data
|
||||
{
|
||||
public partial class RoleButtonsDataObject
|
||||
{
|
||||
public void Save()
|
||||
{
|
||||
SerializerXML.SerializeToFile(this, "RoleButtons.xml");
|
||||
}
|
||||
public static RoleButtonsDataObject Load()
|
||||
{
|
||||
var obj = SerializerXML.DeserializeFromFileOrDefault<RoleButtonsDataObject>("RoleButtons.xml");
|
||||
return obj;
|
||||
}
|
||||
[XmlElement("Button")] public List<RoleButton> List { get; set; } = new();
|
||||
[XmlAttribute] public int Counter { get; set; }
|
||||
public RoleButton this[int id] => List.Find(x => x.Id == id);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
using Discord;
|
||||
using Discord.Interactions;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public class AskForLogFileModule : InteractionModuleBase
|
||||
{
|
||||
[MessageCommand("Ask for Log file")]
|
||||
public async Task AskForLog(IMessage message)
|
||||
{
|
||||
string title = "Please submit Log File";
|
||||
string descr = "In order to assist you further, we are going to need your `BepInEx/LogOutput.log` file.";
|
||||
if (message.Channel.Id == 1220431757266915400)
|
||||
{
|
||||
title = "Merci d'envoyer le fichier journal";
|
||||
descr = "Afin de t'aider davantage, nous allons avoir besoin de ton fichier `BepInEx/LogOutput.log`.";
|
||||
}
|
||||
if (message.Channel.Id == 1220476339883216977)
|
||||
{
|
||||
title = "Bitte schick uns deine Log-Datei.";
|
||||
descr = "Um dir weiterhelfen zu können, benötigen wir deine `BepInEx/LogOutput.log` Datei.";
|
||||
}
|
||||
if (message.Channel.Id == 1220488093124005909)
|
||||
{
|
||||
title = "Envía el archivo de registro";
|
||||
descr = "Para poder ayudarte mejor, vamos a necesitar tu archivo `BepInEx/LogOutput.log`.";
|
||||
}
|
||||
if (message.Channel.Id == 1221180784598188082)
|
||||
{
|
||||
title = "Prześlij plik dziennika";
|
||||
descr = "Aby pomóc Ci dalej, będziemy potrzebować Twojego pliku `BepInEx/LogOutput.log`.";
|
||||
}
|
||||
if (message.Channel.Id == 1225150931306549330)
|
||||
{
|
||||
title = "Por favor, envia o ficheiro de registo";
|
||||
descr = "Para te podermos ajudar mais, vamos precisar do teu ficheiro `BepInEx/LogOutput.log`.";
|
||||
}
|
||||
var stream = new MemoryStream(Properties.Resources.LogOutput);
|
||||
await RespondWithFileAsync(new FileAttachment(stream, "LogOutput.jpg"), "<@" + message.Author.Id + ">", embed: new EmbedBuilder().WithTitle(title).WithDescription(descr).WithImageUrl("attachment://LogOutput.jpg").WithDefaults().Build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using Discord;
|
||||
using Discord.Interactions;
|
||||
using SMSModLogOutputAnalyzer.Data;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class ConfigModule
|
||||
{
|
||||
public partial class Commands
|
||||
{
|
||||
[Group("set", "Setter Commands")]
|
||||
public class Setters : InteractionModuleBase
|
||||
{
|
||||
[SlashCommand("notes_log_channel", "What channel to log note creations into.")]
|
||||
[RequireUserPermission(ChannelPermission.ManageChannels)]
|
||||
public async Task NotesLogChannel(ITextChannel channel)
|
||||
{
|
||||
Config.NotesLogChannel = channel;
|
||||
Config.Save();
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDescription("Config value `NotesLogChannel` set to `" + channel.Id + "`.").WithDefaults().Build());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
using Discord.Interactions;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class ConfigModule
|
||||
{
|
||||
[Group("config", "Config Commands")]
|
||||
public partial class Commands : InteractionModuleBase
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
14
SMSModLogOutputAnalyzer/Modules/Config/ConfigModule.cs
Normal file
14
SMSModLogOutputAnalyzer/Modules/Config/ConfigModule.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using Discord.Interactions;
|
||||
using Orpticon.Wrappers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class ConfigModule : InteractionModuleBase
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
namespace SMSModLogOutputAnalyzer
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class CommandModule
|
||||
public partial class LogAnalyzeModule
|
||||
{
|
||||
public struct FoundLine
|
||||
{
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
using Discord.Interactions;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class CommandModule : InteractionModuleBase
|
||||
public partial class LogAnalyzeModule : InteractionModuleBase
|
||||
{
|
||||
public static List<string> KnownMelonLoaderMods = new List<string>
|
||||
{
|
||||
|
|
@ -35,39 +35,6 @@ namespace SMSModLogOutputAnalyzer
|
|||
{
|
||||
Console.WriteLine("Building module");
|
||||
}
|
||||
[MessageCommand("Ask for Log file")]
|
||||
public async Task AskForLog(IMessage message)
|
||||
{
|
||||
string title = "Please submit Log File";
|
||||
string descr = "In order to assist you further, we are going to need your `BepInEx/LogOutput.log` file.";
|
||||
if(message.Channel.Id == 1220431757266915400)
|
||||
{
|
||||
title = "Merci d'envoyer le fichier journal";
|
||||
descr = "Afin de t'aider davantage, nous allons avoir besoin de ton fichier `BepInEx/LogOutput.log`.";
|
||||
}
|
||||
if(message.Channel.Id == 1220476339883216977)
|
||||
{
|
||||
title = "Bitte schick uns deine Log-Datei.";
|
||||
descr = "Um dir weiterhelfen zu können, benötigen wir deine `BepInEx/LogOutput.log` Datei.";
|
||||
}
|
||||
if (message.Channel.Id == 1220488093124005909)
|
||||
{
|
||||
title = "Envía el archivo de registro";
|
||||
descr = "Para poder ayudarte mejor, vamos a necesitar tu archivo `BepInEx/LogOutput.log`.";
|
||||
}
|
||||
if (message.Channel.Id == 1221180784598188082)
|
||||
{
|
||||
title = "Prześlij plik dziennika";
|
||||
descr = "Aby pomóc Ci dalej, będziemy potrzebować Twojego pliku `BepInEx/LogOutput.log`.";
|
||||
}
|
||||
if (message.Channel.Id == 1225150931306549330)
|
||||
{
|
||||
title = "Por favor, envia o ficheiro de registo";
|
||||
descr = "Para te podermos ajudar mais, vamos precisar do teu ficheiro `BepInEx/LogOutput.log`.";
|
||||
}
|
||||
var stream = new MemoryStream(Properties.Resources.LogOutput);
|
||||
await RespondWithFileAsync(new FileAttachment(stream, "LogOutput.jpg"), "<@" + message.Author.Id + ">", embed: new EmbedBuilder().WithTitle(title).WithDescription(descr).WithImageUrl("attachment://LogOutput.jpg").Build());
|
||||
}
|
||||
[MessageCommand("Analyze Log")]
|
||||
public async Task Analyze(IMessage message)
|
||||
{
|
||||
|
|
@ -76,7 +43,7 @@ namespace SMSModLogOutputAnalyzer
|
|||
await Upload((Attachment)message.Attachments.First());
|
||||
} else
|
||||
{
|
||||
await RespondAsync("Message has no attachment.", ephemeral: true);
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDescription("Message has no attachment.").WithDefaults().Build(), ephemeral: true);
|
||||
}
|
||||
}
|
||||
[SlashCommand("upload", "Upload a LogOutput.log file for analysis.")]
|
||||
|
|
@ -89,7 +56,7 @@ namespace SMSModLogOutputAnalyzer
|
|||
var text = await http.GetStringAsync(file.Url);
|
||||
if(Program.AnalysisCache.ContainsKey(text))
|
||||
{
|
||||
await RespondAsync(ephemeral: true, text: "This log file has already been analysed [here](" + Program.AnalysisCache[text].GetJumpUrl() + ").");
|
||||
await RespondAsync(ephemeral: true, embed: new EmbedBuilder().WithDescription("This log file has already been analysed [here](" + Program.AnalysisCache[text].GetJumpUrl() + ").").WithDefaults().Build());
|
||||
return;
|
||||
}
|
||||
await DeferAsync();
|
||||
|
|
@ -97,7 +64,6 @@ namespace SMSModLogOutputAnalyzer
|
|||
var textLines = text.Split('\n').Select(x => x.Trim()).ToArray();
|
||||
var embedBuilder = new EmbedBuilder();
|
||||
embedBuilder.WithAuthor(Context.User);
|
||||
embedBuilder.WithFooter(Program.Footer);
|
||||
|
||||
Dictionary<string, List<string>> values = new();
|
||||
var lines = FindLines(textLines,
|
||||
|
|
@ -209,7 +175,7 @@ namespace SMSModLogOutputAnalyzer
|
|||
foreach (var field in fields) Log(field.Name + ", " + field.Value);
|
||||
embedBuilder.WithFields(fields);
|
||||
|
||||
embedBuilder.WithColor(Color.DarkBlue);
|
||||
embedBuilder.WithDefaults();
|
||||
var embed = embedBuilder.Build();
|
||||
var message = await ModifyOriginalResponseAsync(func => { func.Embeds = new[] { embed }; func.Components = downloadButton.Build(); });
|
||||
Program.AnalysisCache.Add(text, message);
|
||||
|
|
@ -236,33 +202,5 @@ namespace SMSModLogOutputAnalyzer
|
|||
}
|
||||
return results;
|
||||
}
|
||||
[SlashCommand("troubleshoot", "Starts the troubleshooting assistant.")]
|
||||
[RequireUserPermission(GuildPermission.ManageChannels)]
|
||||
public async Task Troubleshoot()
|
||||
{
|
||||
await RespondAsync("Posting", ephemeral: true);
|
||||
await Context.Channel.SendMessageAsync(embed: new EmbedBuilder()
|
||||
.WithTitle("Troubleshooting Assistant")
|
||||
.WithDescription("Press the button below to be guided through our troubleshooting assistant. Hopefully it can help you with getting mods working.")
|
||||
.WithFooter(Program.Footer)
|
||||
.Build(),
|
||||
components: new ComponentBuilder()
|
||||
.WithButton("Start", "troubleshoot:root", ButtonStyle.Success)
|
||||
.Build());
|
||||
}
|
||||
[ComponentInteraction("troubleshoot:*")]
|
||||
public async Task TroubleshootButton(string node)
|
||||
{
|
||||
Flowchart.FlowchartNode fcnode = Program.Troubleshooting.Nodes.Find(x => x.Name == node);
|
||||
if (fcnode == null) return;
|
||||
var connections = Program.Troubleshooting.Connections.Where(x => x.FromName == node);
|
||||
var cmpb = new ComponentBuilder();
|
||||
foreach (var conn in connections) cmpb.WithButton(conn.Text, "troubleshoot:" + conn.ToName, conn.Text == "Yes" ? ButtonStyle.Success : conn.Text == "No" ? ButtonStyle.Danger : ButtonStyle.Primary);
|
||||
await RespondAsync(embed: new EmbedBuilder()
|
||||
.WithTitle(fcnode.Text)
|
||||
.WithDescription(fcnode.Description)
|
||||
.WithFooter(Program.Footer)
|
||||
.Build(), components: cmpb.Build(), ephemeral: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using Discord;
|
||||
using Discord.Interactions;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class NotesModule
|
||||
{
|
||||
public partial class Commands
|
||||
{
|
||||
/// <summary>
|
||||
/// Currently unused because I can't figure out how to get modals to work
|
||||
/// </summary>
|
||||
public class AddNoteModal : IModal
|
||||
{
|
||||
public string Title => "Add Note";
|
||||
[RequiredInput(true)]
|
||||
[InputLabel("Note Text")]
|
||||
[ModalTextInput("note_text", TextInputStyle.Paragraph, "stinky")]
|
||||
public string Note { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
108
SMSModLogOutputAnalyzer/Modules/Notes/NotesModule.Commands.cs
Normal file
108
SMSModLogOutputAnalyzer/Modules/Notes/NotesModule.Commands.cs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
using Discord;
|
||||
using Discord.Interactions;
|
||||
using SMSModLogOutputAnalyzer.Data;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class NotesModule
|
||||
{
|
||||
[Group("notes", "Various commands related to notes.")]
|
||||
public partial class Commands : InteractionModuleBase
|
||||
{
|
||||
[SlashCommand("view", "View notes that have been added to a user.")]
|
||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||
public async Task View(IUser user, [Summary(description: "How many notes to skip (used for pagination)")] int offset = 0)
|
||||
{
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||
|
||||
var notes = Data[user].Notes.Skip(offset).Take(25).ToArray();
|
||||
bool addNextPageButton = Data[user].Notes.Count > offset + 25;
|
||||
if (notes.Length == 0)
|
||||
{
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDefaults().WithDescription("No " + (offset > 0 ? "more " : "") + "notes have been added to this user.").Build(), ephemeral: true);
|
||||
return;
|
||||
}
|
||||
|
||||
embedBuilder.WithAuthor(user);
|
||||
embedBuilder.WithDefaults();
|
||||
|
||||
foreach (var note in notes)
|
||||
{
|
||||
embedBuilder.AddField(note.ToField());
|
||||
}
|
||||
|
||||
var embed = embedBuilder.Build();
|
||||
var button = new ComponentBuilder().WithButton("Next Page", "view_notes:" + user.Id + ":" + (offset + 25)).Build();
|
||||
|
||||
if (addNextPageButton)
|
||||
{
|
||||
await RespondAsync(embed: embed, components: button, ephemeral: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
await RespondAsync(embed: embed, ephemeral: true);
|
||||
}
|
||||
}
|
||||
[SlashCommand("add", "Add a note to a user.")]
|
||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||
public async Task Add(IUser user, [Summary("note")] string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
Console.WriteLine("Sending modal");
|
||||
await Context.Interaction.RespondWithModalAsync<AddNoteModal>("add_note:" + user.Id);
|
||||
return;
|
||||
}
|
||||
NotesDataObject.Note note = new();
|
||||
|
||||
note.Text = text;
|
||||
note.CreatorID = Context.User.Id;
|
||||
note.CreationTime = DateTime.Now;
|
||||
note.Id = ++Data[user].Counter;
|
||||
|
||||
Data[user].Notes.Add(note);
|
||||
Data.Save();
|
||||
|
||||
string error = "";
|
||||
|
||||
var field = note.ToField();
|
||||
try
|
||||
{
|
||||
await Config.NotesLogChannel.SendMessageAsync(embed: new EmbedBuilder().WithDefaults().WithAuthor(user.Username + " - New Note", user.GetDisplayAvatarUrl()).WithTitle(field.Name).WithDescription((string)field.Value).Build());
|
||||
} catch (Exception e)
|
||||
{
|
||||
error = "\n\n:x: Logging failed";
|
||||
}
|
||||
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDescription("Note **" + note.Id + "** added." + error).WithDefaults().Build(), ephemeral: true);
|
||||
}
|
||||
[SlashCommand("remove", "Removes a note from a user.")]
|
||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||
public async Task Remove(IUser user, int note_id)
|
||||
{
|
||||
int num = Data[user].Notes.RemoveAll(x => x.Id == note_id);
|
||||
Data.Save();
|
||||
if (num > 0) await RespondAsync(embed: new EmbedBuilder().WithDescription("Note **" + note_id + "** removed.").WithDefaults().Build(), ephemeral: true);
|
||||
else await RespondAsync(embed: new EmbedBuilder().WithDescription("Note **" + note_id + "** was not found.").WithDefaults().Build(), ephemeral: true);
|
||||
}
|
||||
[SlashCommand("clear", "Removes all notes from a user.")]
|
||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||
public async Task Clear(IUser user)
|
||||
{
|
||||
int num = Data[user].Notes.RemoveAll(x => true);
|
||||
Data.Save();
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDescription("**" + num + "** notes were removed.").WithDefaults().Build(), ephemeral: true);
|
||||
}
|
||||
|
||||
[ModalInteraction("add_note:*", true)]
|
||||
[RequireUserPermission(ChannelPermission.ManageRoles)]
|
||||
public async Task AddModal(AddNoteModal modal, string user) => await Add(await Context.Client.GetUserAsync(ulong.Parse(user)), modal.Note);
|
||||
[ComponentInteraction("view_notes:*:*", true)]
|
||||
[RequireUserPermission(ChannelPermission.ManageRoles)]
|
||||
public async Task ViewButton(string user, string offset) => await View(await Context.Client.GetUserAsync(ulong.Parse(user)), int.Parse(offset));
|
||||
[MessageCommand("View Notes")]
|
||||
[RequireUserPermission(ChannelPermission.ManageRoles)]
|
||||
public async Task UserView(IMessage message) => await View(message.Author);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
SMSModLogOutputAnalyzer/Modules/Notes/NotesModule.cs
Normal file
15
SMSModLogOutputAnalyzer/Modules/Notes/NotesModule.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using Discord.Interactions;
|
||||
using SMSModLogOutputAnalyzer.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class NotesModule : InteractionModuleBase
|
||||
{
|
||||
public static NotesDataObject Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
using Discord;
|
||||
using Discord.Interactions;
|
||||
using Discord.WebSocket;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using static SMSModLogOutputAnalyzer.Data.RoleButtonsDataObject;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class RoleButtonModule
|
||||
{
|
||||
[Group("role", "Role Button Commands")]
|
||||
public class Commands : InteractionModuleBase
|
||||
{
|
||||
[Group("button", "Role Button Commands")]
|
||||
public class Subcommands : InteractionModuleBase
|
||||
{
|
||||
[SlashCommand("create", "Creates a new role button.")]
|
||||
[RequireUserPermission(ChannelPermission.ManageRoles)]
|
||||
public async Task Create([Summary(description: "What role the button should give")] IRole role,
|
||||
[Summary(description: "What title the embed should have")] string title,
|
||||
[Summary(description: "What description the embed should have")] string description,
|
||||
[Summary(description: "What text the button should have")] string button_text,
|
||||
[Summary(description: "What emote the button should have")] string button_emote = "",
|
||||
[Summary(description: "What style the button should have")] ButtonStyle style = ButtonStyle.Primary,
|
||||
[Summary(description: "What role should the user already need to have")] IRole required_role = null,
|
||||
[Summary(description: "Embed color (hex code)")] string embed_color = "206694")
|
||||
{
|
||||
try
|
||||
{
|
||||
RoleButton button = new RoleButton();
|
||||
button.Id = Data.Counter++;
|
||||
button.Role = role.Id;
|
||||
if (required_role != null) button.RequiredRole = required_role.Id;
|
||||
Data.List.Add(button);
|
||||
Data.Save();
|
||||
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||
embedBuilder.WithTitle(title);
|
||||
embedBuilder.WithDescription(description);
|
||||
embedBuilder.WithColor(Program.ConvertColor(embed_color));
|
||||
|
||||
ComponentBuilder componentBuilder = new ComponentBuilder();
|
||||
var buttonBuilder = new ButtonBuilder().WithLabel(button_text).WithStyle(style).WithCustomId("role_button:" + button.Id);
|
||||
if (Emote.TryParse(button_emote, out Emote emote))
|
||||
{
|
||||
buttonBuilder.WithEmote(emote);
|
||||
}
|
||||
if (Emoji.TryParse(button_emote, out Emoji emote2))
|
||||
{
|
||||
buttonBuilder.WithEmote(emote2);
|
||||
}
|
||||
componentBuilder.WithButton(buttonBuilder);
|
||||
|
||||
try
|
||||
{
|
||||
await Context.Channel.SendMessageAsync(embed: embedBuilder.Build(), components: componentBuilder.Build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDefaults().WithDescription(":x: Message Sending failed. Ensure the bot has sufficient permissions to send in this channel.").Build(), ephemeral: true);
|
||||
return;
|
||||
}
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDefaults().WithDescription(":white_check_mark: Role Button Created").Build(), ephemeral: true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
[ComponentInteraction("role_button:*", true)]
|
||||
public async Task RoleButton(string id)
|
||||
{
|
||||
var button = Data[int.Parse(id)];
|
||||
|
||||
if (Context.User is SocketGuildUser user)
|
||||
{
|
||||
if (user.Roles.Any(x => x.Id == button.Role))
|
||||
{
|
||||
await RemoveRole(button.Role);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (button.RequiredRole == 0)
|
||||
{
|
||||
await AddRole(button.Role);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (user.Roles.Any(x => x.Id == button.RequiredRole))
|
||||
{
|
||||
await AddRole(button.Role);
|
||||
}
|
||||
else
|
||||
{
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDefaults().WithDescription("You need the role <@&" + button.RequiredRole + "> to be allowed to get this role.").Build(), ephemeral: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AddRole(ulong role)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Context.User is SocketGuildUser user)
|
||||
{
|
||||
await user.AddRoleAsync(role);
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDefaults().WithDescription(":white_check_mark: Role Added: <@&" + role + ">").Build(), ephemeral: true);
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RemoveRole(ulong role)
|
||||
{
|
||||
if (Context.User is SocketGuildUser user)
|
||||
{
|
||||
await user.RemoveRoleAsync(role);
|
||||
await RespondAsync(embed: new EmbedBuilder().WithDefaults().WithDescription(":x: Role Removed: <@&" + role + ">").Build(), ephemeral: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using Discord.Interactions;
|
||||
using SMSModLogOutputAnalyzer.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public partial class RoleButtonModule : InteractionModuleBase
|
||||
{
|
||||
public static RoleButtonsDataObject Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
using Discord;
|
||||
using Discord.Interactions;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer.Modules
|
||||
{
|
||||
public class TroubleshootingModule : InteractionModuleBase
|
||||
{
|
||||
[SlashCommand("troubleshoot", "Starts the troubleshooting assistant.")]
|
||||
[RequireUserPermission(GuildPermission.ManageChannels)]
|
||||
public async Task Troubleshoot()
|
||||
{
|
||||
await RespondAsync("Posting", ephemeral: true);
|
||||
await Context.Channel.SendMessageAsync(embed: new EmbedBuilder()
|
||||
.WithTitle("Troubleshooting Assistant")
|
||||
.WithDescription("Press the button below to be guided through our troubleshooting assistant. Hopefully it can help you with getting mods working.")
|
||||
.WithFooter(Program.Footer)
|
||||
.Build(),
|
||||
components: new ComponentBuilder()
|
||||
.WithButton("Start", "troubleshoot:root", ButtonStyle.Success)
|
||||
.Build());
|
||||
}
|
||||
[ComponentInteraction("troubleshoot:*")]
|
||||
public async Task TroubleshootButton(string node)
|
||||
{
|
||||
Flowchart.FlowchartNode fcnode = Program.Troubleshooting.Nodes.Find(x => x.Name == node);
|
||||
if (fcnode == null) return;
|
||||
var connections = Program.Troubleshooting.Connections.Where(x => x.FromName == node);
|
||||
var cmpb = new ComponentBuilder();
|
||||
foreach (var conn in connections) cmpb.WithButton(conn.Text, "troubleshoot:" + conn.ToName, conn.Text == "Yes" ? ButtonStyle.Success : conn.Text == "No" ? ButtonStyle.Danger : ButtonStyle.Primary);
|
||||
await RespondAsync(embed: new EmbedBuilder()
|
||||
.WithTitle(fcnode.Text)
|
||||
.WithDescription(fcnode.Description)
|
||||
.WithFooter(Program.Footer)
|
||||
.Build(), components: cmpb.Build(), ephemeral: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,37 +1,60 @@
|
|||
using Discord.WebSocket;
|
||||
using Discord;
|
||||
using Discord.Interactions;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using SMSModLogOutputAnalyzer.Modules;
|
||||
using SMSModLogOutputAnalyzer.Data;
|
||||
using SMSModLogOutputAnalyzer.Modules;
|
||||
using System.Globalization;
|
||||
|
||||
namespace SMSModLogOutputAnalyzer
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
private static DiscordSocketClient _client;
|
||||
public static DiscordSocketClient Client;
|
||||
public static Flowchart Troubleshooting;
|
||||
public const string Footer = "SMS Mods Bot • Made by BratPfanneTV, for Modded Supermarket Simulator (Unofficial)";
|
||||
public static Color Color = Color.DarkBlue;
|
||||
public static Dictionary<string, IMessage> AnalysisCache = new();
|
||||
public static EmbedBuilder WithDefaults(this EmbedBuilder builder)
|
||||
{
|
||||
return builder.WithFooter(Footer).WithColor(Color);
|
||||
}
|
||||
public static Color ConvertColor(string hex)
|
||||
{
|
||||
string colorcode = hex;
|
||||
colorcode = colorcode.TrimStart('#');
|
||||
return new Color(
|
||||
int.Parse(colorcode.Substring(0, 2), NumberStyles.HexNumber),
|
||||
int.Parse(colorcode.Substring(2, 2), NumberStyles.HexNumber),
|
||||
int.Parse(colorcode.Substring(4, 2), NumberStyles.HexNumber));
|
||||
}
|
||||
public static bool TryParseEmote(string str, out IEmote iemote)
|
||||
{
|
||||
if (Emote.TryParse(str, out Emote emote)) iemote = emote;
|
||||
else if (Emoji.TryParse(str, out Emoji emoji)) iemote = emoji;
|
||||
else iemote = null;
|
||||
return iemote != null;
|
||||
}
|
||||
public static async Task Main()
|
||||
{
|
||||
Troubleshooting = Flowchart.Parse(Properties.Resources.Flowchart);
|
||||
|
||||
_client = new DiscordSocketClient(new DiscordSocketConfig { LogLevel = LogSeverity.Debug });
|
||||
Client = new DiscordSocketClient(new DiscordSocketConfig { LogLevel = LogSeverity.Debug });
|
||||
|
||||
_client.Log += Log;
|
||||
Client.Log += Log;
|
||||
|
||||
// You can assign your bot token to a string, and pass that in to connect.
|
||||
// This is, however, insecure, particularly if you plan to have your code hosted in a public repository.
|
||||
var token = File.ReadAllText("token.txt");
|
||||
_client.Ready += _client_Ready;
|
||||
Client.Ready += _client_Ready;
|
||||
|
||||
// Some alternative options would be to keep your token in an Environment Variable or a standalone file.
|
||||
// var token = Environment.GetEnvironmentVariable("NameOfYourEnvironmentVariable");
|
||||
// var token = File.ReadAllText("token.txt");
|
||||
// var token = JsonConvert.DeserializeObject<AConfigurationClass>(File.ReadAllText("config.json")).Token;
|
||||
|
||||
await _client.LoginAsync(TokenType.Bot, token);
|
||||
await _client.StartAsync();
|
||||
await Client.LoginAsync(TokenType.Bot, token);
|
||||
await Client.StartAsync();
|
||||
|
||||
// Block this task until the program is closed.
|
||||
await Task.Delay(-1);
|
||||
|
|
@ -39,14 +62,22 @@ namespace SMSModLogOutputAnalyzer
|
|||
|
||||
private static async Task _client_Ready()
|
||||
{
|
||||
var server = (ulong)652484929950842881;
|
||||
var _interactionService = new InteractionService(_client.Rest);
|
||||
var module = await _interactionService.AddModuleAsync<CommandModule>(null);
|
||||
await _interactionService.AddModulesGloballyAsync(true, module);
|
||||
NotesModule.Data = NotesDataObject.Load();
|
||||
RoleButtonModule.Data = RoleButtonsDataObject.Load();
|
||||
Config.Load();
|
||||
|
||||
_client.InteractionCreated += async (x) =>
|
||||
var _interactionService = new InteractionService(Client.Rest);
|
||||
await _interactionService.AddModulesGloballyAsync(true,
|
||||
await _interactionService.AddModuleAsync<AskForLogFileModule>(null),
|
||||
await _interactionService.AddModuleAsync<ConfigModule>(null),
|
||||
await _interactionService.AddModuleAsync<RoleButtonModule>(null),
|
||||
await _interactionService.AddModuleAsync<LogAnalyzeModule>(null),
|
||||
await _interactionService.AddModuleAsync<NotesModule>(null),
|
||||
await _interactionService.AddModuleAsync<TroubleshootingModule>(null));
|
||||
|
||||
Client.InteractionCreated += async (x) =>
|
||||
{
|
||||
var ctx = new SocketInteractionContext(_client, x);
|
||||
var ctx = new SocketInteractionContext(Client, x);
|
||||
await _interactionService.ExecuteCommandAsync(ctx, null);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,22 @@
|
|||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Modules\NewFolder\**" />
|
||||
<EmbeddedResource Remove="Modules\NewFolder\**" />
|
||||
<None Remove="Modules\NewFolder\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Discord.Net" Version="3.14.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Orpticon">
|
||||
<HintPath>..\..\OrpticonDLL\bin\Debug\Orpticon.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue