Created
October 31, 2016 10:26
-
-
Save Biendeo/2bfe127cf56e9d41475194f305275d49 to your computer and use it in GitHub Desktop.
BlendoBot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Discord; | |
| using Newtonsoft.Json; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.IO; | |
| using System.Linq; | |
| using System.Text; | |
| using System.Threading.Tasks; | |
| using System.Xml.Serialization; | |
| namespace BlendoBot { | |
| [System.Serializable] | |
| [System.Xml.Serialization.XmlRoot] | |
| [System.Xml.Serialization.XmlInclude(typeof(string))] | |
| public class FileManagerEntry { | |
| [System.Xml.Serialization.XmlElement] | |
| public string name { get; set; } | |
| [System.Xml.Serialization.XmlElement] | |
| public ulong authorId { get; set; } | |
| [System.Xml.Serialization.XmlArray] | |
| [System.Xml.Serialization.XmlArrayItem] | |
| public List<string> files { get; set; } | |
| public FileManagerEntry() : this(null, 0) {} | |
| public FileManagerEntry(string name, ulong authorId) { | |
| this.name = name; | |
| this.authorId = authorId; | |
| files = new List<string>(); | |
| } | |
| public bool AddFile(string file) { | |
| if (!files.Contains(file)) { | |
| files.Add(file); | |
| files = files.OrderBy(o=>o).ToList(); | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| public bool RemoveFile(string file) { | |
| if (files.Contains(file)) { | |
| files.Remove(file); | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| public bool RemoveFile(int index) { | |
| if (index >= files.Count) { | |
| return false; | |
| } else { | |
| return RemoveFile(files.ElementAt(index)); | |
| } | |
| } | |
| } | |
| class FileManager { | |
| private string filePath; | |
| private SortedList<string, FileManagerEntry> entries; | |
| public FileManager(string filePath) { | |
| this.filePath = filePath; | |
| entries = new SortedList<string, FileManagerEntry>(); | |
| if (File.Exists(filePath)) { | |
| Load(); | |
| } | |
| } | |
| public void Load() { | |
| var serializer = new XmlSerializer(typeof(List<FileManagerEntry>)); | |
| TextReader reader = new StreamReader(filePath); | |
| List<FileManagerEntry> temp = (List<FileManagerEntry>)serializer.Deserialize(reader); | |
| foreach (var o in temp) { | |
| entries.Add(o.name, o); | |
| } | |
| reader.Close(); | |
| } | |
| public void Save() { | |
| var serializer = new XmlSerializer(typeof(List<FileManagerEntry>)); | |
| TextWriter writer = new StreamWriter(filePath); | |
| List<FileManagerEntry> lists = new List<FileManagerEntry>(entries.Values); | |
| serializer.Serialize(writer, lists); | |
| writer.Close(); | |
| } | |
| public bool NewEntry(string name, User author) { | |
| if (entries.ContainsKey(name)) { | |
| return false; | |
| } else { | |
| entries.Add(name, new FileManagerEntry(name, author.Id)); | |
| return true; | |
| } | |
| } | |
| public bool RemoveEntry(string name, User author) { | |
| if (Owns(name, author)) { | |
| entries.Remove(name); | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| public bool RemoveEntry(int index, User author) { | |
| if (index >= entries.Count) { | |
| return false; | |
| } else { | |
| return RemoveEntry(entries.ElementAt(index).Key, author); | |
| } | |
| } | |
| public bool Owns(string name, User author) { | |
| if (entries.ContainsKey(name) && entries[name].authorId == author.Id) { | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| public bool AddToEntry(string name, User author, string item) { | |
| if (Owns(name, author)) { | |
| FileManagerEntry entry; | |
| entries.TryGetValue(name, out entry); | |
| entry.AddFile(item); | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| public bool AddToEntry(int index, User author, string item) { | |
| if (index >= entries.Count) { | |
| return false; | |
| } else { | |
| return AddToEntry(entries.ElementAt(index).Key, author, item); | |
| } | |
| } | |
| public bool RemoveFromEntry(string name, User author, string item) { | |
| if (Owns(name, author)) { | |
| FileManagerEntry entry; | |
| entries.TryGetValue(name, out entry); | |
| return entry.RemoveFile(item); | |
| } else { | |
| return false; | |
| } | |
| } | |
| public bool RemoveFromEntry(int index, User author, string item) { | |
| if (index >= entries.Count) { | |
| return false; | |
| } else { | |
| return RemoveFromEntry(entries.ElementAt(index).Key, author, item); | |
| } | |
| } | |
| public bool RemoveFromEntry(string name, User author, int itemIndex) { | |
| if (Owns(name, author)) { | |
| FileManagerEntry entry; | |
| entries.TryGetValue(name, out entry); | |
| return entry.RemoveFile(itemIndex); | |
| } else { | |
| return false; | |
| } | |
| } | |
| public bool RemoveFromEntry(int index, User author, int itemIndex) { | |
| if (index >= entries.Count) { | |
| return false; | |
| } else { | |
| return RemoveFromEntry(entries.ElementAt(index).Key, author, itemIndex); | |
| } | |
| } | |
| public bool Rename(string file, User author, string newName) { | |
| if (Owns(file, author)) { | |
| FileManagerEntry entry; | |
| entries.TryGetValue(file, out entry); | |
| entries.Remove(file); | |
| entry.name = newName; | |
| entries.Add(newName, entry); | |
| return true; | |
| } else { | |
| return false; | |
| } | |
| } | |
| public bool Rename(int index, User author, string newName) { | |
| if (index >= entries.Count) { | |
| return false; | |
| } else { | |
| return Rename(entries.ElementAt(index).Key, author, newName); | |
| } | |
| } | |
| public bool QuickAdd(string file, User author) { | |
| if (entries.ContainsKey(file)) { | |
| return false; | |
| } else { | |
| FileManagerEntry entry = new FileManagerEntry(file, author.Id); | |
| entry.AddFile(file); | |
| entries.Add(file, entry); | |
| return true; | |
| } | |
| } | |
| public List<string> GetEntries() { | |
| return new List<string>(entries.Keys); | |
| } | |
| public List<string> GetFiles(string file) { | |
| if (entries.ContainsKey(file)) { | |
| FileManagerEntry entry; | |
| entries.TryGetValue(file, out entry); | |
| return entry.files; | |
| } else { | |
| return null; | |
| } | |
| } | |
| public List<string> GetFiles(int index) { | |
| if (index >= entries.Count) { | |
| return null; | |
| } else { | |
| return GetFiles(entries.ElementAt(index).Key); | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <Window x:Class="BlendoBot.MainWindow" | |
| xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
| xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
| xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
| xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
| xmlns:local="clr-namespace:BlendoBot" | |
| mc:Ignorable="d" | |
| Title="BlendoBot Console" Height="350" Width="525" | |
| Icon="https://cdn.discordapp.com/attachments/239933234216042496/242426431118901259/7bd38548ba5955410698a312ee4662cc.jpg" | |
| Closing="Window_Closing"> | |
| <Grid> | |
| <TextBox x:Name="inputBox" TextWrapping="NoWrap" Text="" Height="23" VerticalAlignment="Bottom" KeyDown="inputBox_KeyDown" MaxLength="2000"/> | |
| <ScrollViewer Margin="0,0,0,23"> | |
| <TextBox x:Name="consoleBox" TextWrapping="Wrap" Text="" IsReadOnly="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/> | |
| </ScrollViewer> | |
| </Grid> | |
| </Window> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Discord; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Text; | |
| using System.Text.RegularExpressions; | |
| using System.Threading.Tasks; | |
| using System.Windows; | |
| using System.Windows.Controls; | |
| using System.Windows.Data; | |
| using System.Windows.Documents; | |
| using System.Windows.Input; | |
| using System.Windows.Media; | |
| using System.Windows.Media.Imaging; | |
| using System.Windows.Navigation; | |
| using System.Windows.Shapes; | |
| namespace BlendoBot { | |
| /// <summary> | |
| /// Interaction logic for MainWindow.xaml | |
| /// </summary> | |
| public partial class MainWindow : Window { | |
| private DiscordClient client; | |
| private Channel lastChannelReceived; | |
| private FileManager fileManager; | |
| public MainWindow() { | |
| fileManager = new FileManager("Files.xml"); | |
| InitializeComponent(); | |
| StartDiscordClient(); | |
| } | |
| /// <summary> | |
| /// This is the start of the Discord client program. It attaches all of the actions, then | |
| /// commences a connection. | |
| /// </summary> | |
| public void StartDiscordClient() { | |
| client = new DiscordClient(); | |
| client.Log.Message += (s, e) => { | |
| Dispatcher.Invoke(() => { | |
| if (consoleBox.Text != "") { | |
| consoleBox.Text += "\n"; | |
| } | |
| consoleBox.Text += $"({DateTime.Now.ToString("hh:mm:ss tt")}) [{e.Severity.ToString()}] {e.Source}: {e.Message}"; | |
| }); | |
| Console.WriteLine($"[{e.Severity}] {e.Source}: {e.Message}"); | |
| }; | |
| client.MessageReceived += (s, e) => { | |
| lastChannelReceived = e.Channel; | |
| if (!e.Message.IsAuthor) { | |
| client.Log.Log(LogSeverity.Info, e.Message.User.Nickname, e.Message.Text); | |
| if (DoesTextMentionMe(e.Message)) { | |
| ParseMessage(e.Message); | |
| } | |
| } | |
| }; | |
| client.ServerUnavailable += (s, e) => { | |
| PrintInfo("Server unavailable"); | |
| }; | |
| client.JoinedServer += (s, e) => { | |
| }; | |
| client.Ready += (s, e) => { | |
| client.SetGame(new Game("Bastion Main")); | |
| PrintInfo("Connected as: " + client.CurrentUser.Name); | |
| }; | |
| // Finish the setup by commencing a connection. | |
| client.Connect("PUT YOUR KEY HERE", TokenType.Bot); | |
| } | |
| private void PrintInfo(string message) { | |
| client.Log.Info("Program", message); | |
| } | |
| private bool DoesTextMentionMe(Message message) { | |
| foreach (User u in message.MentionedUsers) { | |
| if (u.Id == client.CurrentUser.Id) return true; | |
| } | |
| return false; | |
| } | |
| private void ParseMessage(Message message) { | |
| if (Regex.IsMatch(message.Text, "!help")) { | |
| PrintHelp(message.Channel); | |
| } else if (Regex.IsMatch(message.Text, "!file")) { | |
| ParseFileMessage(message); | |
| } | |
| } | |
| private async void ParseFileMessage(Message message) { | |
| List<string> splitString = Regex.Matches(message.Text, @"[\""].+?[\""]|[^ ]+").Cast<Match>().Select(m => m.Value).ToList(); | |
| splitString.RemoveAt(0); // @-tag | |
| splitString.RemoveAt(0); // !file | |
| bool success; | |
| try { | |
| if (splitString[0] == "new") { | |
| success = fileManager.NewEntry(splitString[1], message.User); | |
| if (success) { | |
| await SendMessage(lastChannelReceived, "New entry: " + splitString[1]); | |
| } else { | |
| await SendMessage(lastChannelReceived, "I couldn't make a new entry"); | |
| } | |
| } else if (splitString[0] == "delete") { | |
| int index; | |
| bool indexSuccess = int.TryParse(splitString[1], out index); | |
| if (indexSuccess) { | |
| success = fileManager.RemoveEntry(index, message.User); | |
| } else { | |
| success = fileManager.RemoveEntry(splitString[1], message.User); | |
| } | |
| if (success) { | |
| await SendMessage(lastChannelReceived, "Entry removed"); | |
| } else { | |
| await SendMessage(lastChannelReceived, "I couldn't remove an entry"); | |
| } | |
| } else if (splitString[0] == "add") { | |
| if (splitString.Count >= 3) { | |
| int index; | |
| bool indexSuccess = int.TryParse(splitString[1], out index); | |
| if (indexSuccess) { | |
| success = fileManager.AddToEntry(index, message.User, splitString[2]); | |
| } else { | |
| success = fileManager.AddToEntry(splitString[1], message.User, splitString[2]); | |
| } | |
| if (success) { | |
| await SendMessage(lastChannelReceived, "Inserted " + splitString[2] + " into " + splitString[1]); | |
| } else { | |
| await SendMessage(lastChannelReceived, "I couldn't add a file"); | |
| } | |
| } else { | |
| await SendMessage(lastChannelReceived, "Invalid arguments"); | |
| } | |
| } else if (splitString[0] == "remove") { | |
| if (splitString.Count >= 3) { | |
| int index; | |
| bool indexSuccess = int.TryParse(splitString[1], out index); | |
| List<string> files; | |
| if (indexSuccess) { | |
| files = fileManager.GetFiles(index); | |
| } else { | |
| files = fileManager.GetFiles(splitString[1]); | |
| } | |
| if (files != null) { | |
| int itemIndex; | |
| bool itemIndexSuccess = int.TryParse(splitString[2], out itemIndex); | |
| if (indexSuccess && itemIndexSuccess) { | |
| success = fileManager.RemoveFromEntry(index, message.User, itemIndex); | |
| } else if (!indexSuccess && itemIndexSuccess) { | |
| success = fileManager.RemoveFromEntry(splitString[1], message.User, itemIndex); | |
| } else if (indexSuccess && !itemIndexSuccess) { | |
| success = fileManager.RemoveFromEntry(index, message.User, splitString[2]); | |
| } else { | |
| success = fileManager.RemoveFromEntry(splitString[1], message.User, splitString[2]); | |
| } | |
| if (success) { | |
| await SendMessage(lastChannelReceived, "Removed " + splitString[2] + " from " + splitString[1]); | |
| } else { | |
| await SendMessage(lastChannelReceived, "I couldn't remove that file"); | |
| } | |
| } else { | |
| await SendMessage(lastChannelReceived, "That entry doesn't exist"); | |
| } | |
| } else { | |
| await SendMessage(lastChannelReceived, "Invalid arguments"); | |
| } | |
| } else if (splitString[0] == "rename") { | |
| if (splitString.Count >= 3) { | |
| int index; | |
| bool indexSuccess = int.TryParse(splitString[1], out index); | |
| if (indexSuccess) { | |
| success = fileManager.Rename(index, message.User, splitString[2]); | |
| } else { | |
| success = fileManager.Rename(splitString[1], message.User, splitString[2]); | |
| } | |
| if (success) { | |
| await SendMessage(lastChannelReceived, "Renamed " + splitString[1] + " to " + splitString[2]); | |
| } else { | |
| await SendMessage(lastChannelReceived, "I couldn't add a file"); | |
| } | |
| } else { | |
| await SendMessage(lastChannelReceived, "Invalid arguments"); | |
| } | |
| } else if (splitString[0] == "quickadd") { | |
| success = fileManager.QuickAdd(splitString[1], message.User); | |
| if (success) { | |
| await SendMessage(lastChannelReceived, "Quickly added new entry: " + splitString[1]); | |
| } else { | |
| await SendMessage(lastChannelReceived, "I couldn't make a new entry"); | |
| } | |
| } else if (splitString[0] == "list") { | |
| List<string> entries = fileManager.GetEntries(); | |
| string outputMessage = $"{entries.Count} entries total:\n"; | |
| if (entries.Count == 0) { | |
| outputMessage = "No entries"; | |
| } | |
| for (int i = 0; i < entries.Count; ++i) { | |
| outputMessage += $"{i.ToString().PadLeft(3, ' ')}. {entries.ElementAt(i)}"; | |
| if (i != entries.Count && i % 10 == 9) { | |
| await SendMessage(lastChannelReceived, outputMessage); | |
| outputMessage = ""; | |
| } else { | |
| if (i != entries.Count) { | |
| outputMessage += "\n"; | |
| } | |
| } | |
| } | |
| await SendMessage(lastChannelReceived, outputMessage); | |
| } else if (splitString[0] == "view") { | |
| List<string> files; | |
| int index; | |
| bool indexSuccess = int.TryParse(splitString[1], out index); | |
| if (indexSuccess) { | |
| files = fileManager.GetFiles(index); | |
| } else { | |
| files = fileManager.GetFiles(splitString[1]); | |
| } | |
| if (files != null) { | |
| string outputMessage = $"{files.Count} files total:\n"; | |
| for (int i = 0; i < files.Count; ++i) { | |
| outputMessage += $"{i.ToString().PadLeft(3, ' ')}. {files.ElementAt(i)}"; | |
| if (i != files.Count && i % 10 == 9) { | |
| await SendMessage(lastChannelReceived, outputMessage); | |
| outputMessage = ""; | |
| } else { | |
| if (i != files.Count) { | |
| outputMessage += "\n"; | |
| } | |
| } | |
| } | |
| await SendMessage(lastChannelReceived, outputMessage); | |
| } else { | |
| await SendMessage(lastChannelReceived, "I couldn't find an entry"); | |
| } | |
| } else if (splitString[0] == "help") { | |
| await PrintFileHelp(lastChannelReceived); | |
| } | |
| } catch (Exception e) { | |
| client.Log.Error("Program", e); | |
| await PrintFileHelp(lastChannelReceived); | |
| } | |
| } | |
| private async Task SendMessage(Channel channel, string message) { | |
| await channel.SendMessage(message); | |
| client.Log.Log(LogSeverity.Info, client.CurrentUser.Name, message); | |
| } | |
| private async Task PrintHelp(Channel channel) { | |
| string helpMessage = ""; | |
| helpMessage += "The following commands are available:\n"; | |
| helpMessage += "**!file** - Accesses the file management system"; | |
| helpMessage += "\n"; | |
| helpMessage += "Thanks for using Blendo Bot. Your call is important to us."; | |
| await SendMessage(channel, helpMessage); | |
| } | |
| private async Task PrintFileHelp(Channel channel) { | |
| string helpMessage = ""; | |
| helpMessage += "The following commands are available:\n"; | |
| helpMessage += "**!file help** - Shows this prompt\n"; | |
| helpMessage += "**!file list** - Displays all available entries\n"; | |
| helpMessage += "**!file view [index / name]** - Displays all files in a given entry\n"; | |
| helpMessage += "**!file new [name]** - Creates a new entry with the given name\n"; | |
| helpMessage += "**!file delete [index / name]** - Deletes this entry\n"; | |
| helpMessage += "**!file add [index / name] [filePath]** - Creates a new file in the given entry\n"; | |
| helpMessage += "**!file remove [index / name] [fileIndex / fileName]** - Removes a file in the given entry\n"; | |
| helpMessage += "**!file quickadd [filePath]** - Quickly makes an entry, with the file as the only file\n"; | |
| helpMessage += "**!file rename [index / name] [newName]** - Renames an entry\n"; | |
| helpMessage += "~~**!file bulkadd [name]** - Creates a new entry, and all future posts (by you) will be added~~\n"; | |
| helpMessage += "~~**!file bulkstop** - Stops the current bulkadd~~"; | |
| await SendMessage(lastChannelReceived, helpMessage); | |
| } | |
| private async void SendInputBoxMessage() { | |
| if (lastChannelReceived != null) { | |
| await SendMessage(lastChannelReceived, inputBox.Text); | |
| ClearInputBox(); | |
| } | |
| } | |
| private void ClearInputBox() { | |
| Dispatcher.Invoke(() => { | |
| inputBox.Text = ""; | |
| }); | |
| } | |
| private void inputBox_KeyDown(object sender, KeyEventArgs e) { | |
| if (e.Key == Key.Return) { | |
| SendInputBoxMessage(); | |
| } | |
| } | |
| private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { | |
| fileManager.Save(); | |
| client.Disconnect(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment