From ffd8a577828947b4822299be175487150d98710b Mon Sep 17 00:00:00 2001 From: TrueDoctor Date: Wed, 23 Aug 2017 18:36:33 +0200 Subject: Added Roll command added tyecorrection addeed spells gui overhaul --- DiscoBot/DiscoBot.csproj | 1 + 1 file changed, 1 insertion(+) (limited to 'DiscoBot/DiscoBot.csproj') diff --git a/DiscoBot/DiscoBot.csproj b/DiscoBot/DiscoBot.csproj index 9920f40..d4f3290 100644 --- a/DiscoBot/DiscoBot.csproj +++ b/DiscoBot/DiscoBot.csproj @@ -132,6 +132,7 @@ + -- cgit v1.2.3-70-g09d2 From 23d2ede6124b0a7b10a74058a396477d52941337 Mon Sep 17 00:00:00 2001 From: TrueDoctor Date: Sun, 8 Apr 2018 20:23:57 +0200 Subject: Did a lot of awsome stuff --- DiscoBot.sln | 6 +- DiscoBot/App.config | 16 ++ DiscoBot/Char.cs | 145 ------------- DiscoBot/Character.cs | 309 ++++++++++++++++++++++++++ DiscoBot/CommandExtension.cs | 47 ++++ DiscoBot/Commands.cs | 324 +++++++++++++++++++++++++--- DiscoBot/DSA.cs | 38 ++++ DiscoBot/DiscoBot.csproj | 90 +++++--- DiscoBot/ICharacter.cs | 23 ++ DiscoBot/Misc.cs | 162 ++++++++++++-- DiscoBot/NPC.cs | 107 +++++++++ DiscoBot/Program.cs | 2 +- DiscoBot/Properties/Settings.Designer.cs | 38 ++++ DiscoBot/Properties/Settings.settings | 9 + DiscoBot/packages.config | 38 ++-- UnitTestProject1/Properties/AssemblyInfo.cs | 20 ++ UnitTestProject1/UnitTest1.cs | 14 ++ UnitTestProject1/UnitTestProject1.csproj | 67 ++++++ UnitTestProject1/packages.config | 5 + Voice.cs | 21 ++ 20 files changed, 1236 insertions(+), 245 deletions(-) delete mode 100644 DiscoBot/Char.cs create mode 100644 DiscoBot/Character.cs create mode 100644 DiscoBot/CommandExtension.cs create mode 100644 DiscoBot/DSA.cs create mode 100644 DiscoBot/ICharacter.cs create mode 100644 DiscoBot/NPC.cs create mode 100644 DiscoBot/Properties/Settings.Designer.cs create mode 100644 DiscoBot/Properties/Settings.settings create mode 100644 UnitTestProject1/Properties/AssemblyInfo.cs create mode 100644 UnitTestProject1/UnitTest1.cs create mode 100644 UnitTestProject1/UnitTestProject1.csproj create mode 100644 UnitTestProject1/packages.config create mode 100644 Voice.cs (limited to 'DiscoBot/DiscoBot.csproj') diff --git a/DiscoBot.sln b/DiscoBot.sln index 7049ed0..0e88c59 100644 --- a/DiscoBot.sln +++ b/DiscoBot.sln @@ -1,11 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26430.16 +VisualStudioVersion = 15.0.27130.2003 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A6857735-6707-4A33-A7F8-3A06E354D7F3}" ProjectSection(SolutionItems) = preProject Felis.xml = Felis.xml + Voice.cs = Voice.cs EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscoBot", "DiscoBot\DiscoBot.csproj", "{1186AF1C-BC46-4B3D-BEE0-CE478B8AEAC7}" @@ -24,4 +25,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CADA01A3-B80B-4979-8397-7CB5B825CE34} + EndGlobalSection EndGlobal diff --git a/DiscoBot/App.config b/DiscoBot/App.config index f107529..5740218 100644 --- a/DiscoBot/App.config +++ b/DiscoBot/App.config @@ -1,5 +1,10 @@  + + +
+ + @@ -17,6 +22,17 @@ + + + + + + + + Mjk0NTU0MDU4Nzg4NzAwMTYx.DOzDcQ.J-nCikbZdZtdrug0E8TwwV_2ITw + + + diff --git a/DiscoBot/Char.cs b/DiscoBot/Char.cs deleted file mode 100644 index 45d975e..0000000 --- a/DiscoBot/Char.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml; - -namespace DiscoBot -{ - public class Char - { - - public string name; //charname - public Dictionary eigenschaften = new Dictionary(); //char porperties - public List talente = new List(); //ist of talent objects (talents and spells) - public List kampftalente = new List(); //list of combat objects - - public Dictionary Proptable = new Dictionary(); //KK -> Körperkraft - - - public Char(String path ) - { - - Load(path); //load - } - - private void Load(string path) - { - XmlTextReader reader = new XmlTextReader(path); - while (reader.Read()) //read until he hits keywords - { - if (reader.NodeType == XmlNodeType.Element) - switch (reader.Name) - { - case "held": - name = reader.GetAttribute("name"); //name - break; - case "eigenschaft": - eigenschaften.Add(reader.GetAttribute("name"), Convert.ToInt32(reader.GetAttribute("value")) + Convert.ToInt32(reader.GetAttribute("mod"))); - break; - case "talentliste": - reader.Read(); - while (reader.Name.Equals("talent")) - { - talente.Add(new Talent(reader.GetAttribute("name"), reader.GetAttribute("probe").Remove(0, 2).Trim(')'), Convert.ToInt32(reader.GetAttribute("value")))); - reader.Read(); - } - break; - case "zauberliste": - reader.Read(); - while (reader.Name.Equals("zauber")) - { - talente.Add(new Talent(reader.GetAttribute("name"), reader.GetAttribute("probe").Remove(0, 2).Trim(')'), Convert.ToInt32(reader.GetAttribute("value")))); - reader.Read(); - } - break; - case "kampfwerte": - string atname = reader.GetAttribute("name"); - reader.Read(); - int at = Convert.ToInt32(reader.GetAttribute("value")); - reader.Read(); - int pa = Convert.ToInt32(reader.GetAttribute("value")); - kampftalente.Add(new Kampf(atname, at, pa)); - break; - } - - - - } - Proptable.Add("MU", "Mut"); //routing - Proptable.Add("KL", "Klugheit"); - Proptable.Add("IN", "Intuition"); - Proptable.Add("CH", "Charisma"); - Proptable.Add("FF", "Fingerfertigkeit"); - Proptable.Add("GE", "Gewandtheit"); - Proptable.Add("KO", "Konstitution"); - Proptable.Add("KK", "Körperkraft"); - - } - public string TestTalent(string talent) //Talentprobe - { - var output = new StringBuilder(); - var ttalentlist = talente.Select(v => v.CheckName(talent)).ToList(); //find the talent - int error = ttalentlist.Min(); - var ttalent = talente[ttalentlist.IndexOf(error)]; - var props = ttalent.Test(); //get the required properties - int tap = ttalent.value; //get tap - List werte = new List(); - foreach (string p in props) - { - werte.Add(eigenschaften[Proptable[p]]); - } - output.AppendFormat("{0} würfelt: {1} \n{2} - {3} taw:{4} \n", this.name,ttalent.name,ttalent.probe,String.Join("/",werte),ttalent.value); - output.Append(" "); - for (int i = 0; i <= 2; i++) //foreach property, dice and tap - { - int temp = dice.Roll(); - int eigenschaft = eigenschaften[Proptable[props[i]]]; - if (eigenschaft < temp) - tap -= temp - eigenschaft; - output.Append("["+temp + "]"); //add to string - } - - output.AppendFormat(" tap: {0,20}",tap); - if (error == 100) - return talent + " nicht gefunden!"; - return output.ToString(); //return output - } - public string Angriff(string talent) //prety self explanetory - { - var output = new StringBuilder(); - var attack = kampftalente.Find(x => x.name.ToLower().Equals(talent.ToLower())); - int tap = attack.at; - output.AppendFormat("{0}-Angriff taw:{1} \n", attack.name, tap); - int temp = dice.Roll(); - output.Append(temp ); - return output.ToString(); - } - public string Parade(string talent) - { - var output = new StringBuilder(); - var attack = kampftalente.Find(x => x.name.ToLower().Equals(talent.ToLower())); - int tap = attack.pa; - output.AppendFormat("{0}-Parade taw:{1} \n", attack.name, tap); - int temp = dice.Roll(); - output.Append(temp); - return output.ToString(); - } - public string Fernkampf(string talent,int erschwernis=0) - { - var output = new StringBuilder(); - int fk = eigenschaften["fk"]; - var attack = talente.Find(v => v.name.ToLower().Equals(talent.ToLower())); - int tap = attack.value ; - output.AppendFormat("{0} taw:{1} erschwernis:{2} \n", attack.name, tap,erschwernis); - tap -= erschwernis; - int temp = dice.Roll(); - tap -= temp>fk?temp-fk:0; - output.Append(temp + " tap:" + tap); - return output.ToString(); - } - - } - -} diff --git a/DiscoBot/Character.cs b/DiscoBot/Character.cs new file mode 100644 index 0000000..18b6213 --- /dev/null +++ b/DiscoBot/Character.cs @@ -0,0 +1,309 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; + +namespace DiscoBot +{ + public class Character : ICharacter + { + public string Name { get; set; } //charname + public Dictionary Eigenschaften = new Dictionary(); //char porperties + public List Talente = new List(); //ist of talent objects (talents and spells) + public List Kampftalente = new List(); //list of combat objects + public List Vorteile = new List(); + + public Dictionary Proptable = new Dictionary(); //KK -> Körperkraft + + + public Character(String path) + { + Load(path); //load + Proptable.Add("MU", "Mut"); //routing + Proptable.Add("KL", "Klugheit"); + Proptable.Add("IN", "Intuition"); + Proptable.Add("CH", "Charisma"); + Proptable.Add("FF", "Fingerfertigkeit"); + Proptable.Add("GE", "Gewandtheit"); + Proptable.Add("KO", "Konstitution"); + Proptable.Add("KK", "Körperkraft"); + } + + public Character(Character c, string name, int stDv = 2) + { + Proptable.Add("MU", "Mut"); //routing + Proptable.Add("KL", "Klugheit"); + Proptable.Add("IN", "Intuition"); + Proptable.Add("CH", "Charisma"); + Proptable.Add("FF", "Fingerfertigkeit"); + Proptable.Add("GE", "Gewandtheit"); + Proptable.Add("KO", "Konstitution"); + Proptable.Add("KK", "Körperkraft"); + this.Proptable.Add("**", "Klugheit"); + + this.Name = name; + foreach (var i in c.Eigenschaften) + { + this.Eigenschaften.Add(i.Key, i.Value + (int)Math.Round(Misc.Random(stDv))); + } + + foreach (var i in c.Vorteile) + { + this.Vorteile.Add(new Vorteil(i.name, i.value + (int)Math.Round(Misc.Random(stDv)))); + } + + foreach (var i in c.Talente) + { + this.Talente.Add(new Talent(i.name, i.probe, i.value + (int)Math.Round(Misc.Random(stDv)))); + } + + foreach (var i in c.Kampftalente) + { + this.Kampftalente.Add(new Kampf(i.name, i.at + (int)Math.Round(Misc.Random(stDv)), i.pa + (int)Math.Round(Misc.Random(stDv)))); + } + } + + private void Load(string path) + { + XmlTextReader reader = new XmlTextReader(path); + while (reader.Read()) //read until he hits keywords + { + if (reader.NodeType == XmlNodeType.Element) + { + + switch (reader.Name) + { + case "Wesen": + reader.Skip(); + break; + case "held": + Name = reader.GetAttribute("name"); //name + break; + case "eigenschaft": + Eigenschaften.Add( + reader.GetAttribute("name"), + Convert.ToInt32(reader.GetAttribute("value")) + + Convert.ToInt32(reader.GetAttribute("mod"))); + break; + case "vt": + reader.Read(); + while (reader.Name.Equals("vorteil")) + { + try + { + this.Vorteile.Add(new Vorteil( + reader.GetAttribute("name"), + Convert.ToInt32(reader.GetAttribute("value")))); + } + catch + { + this.Vorteile.Add(new Vorteil(reader.GetAttribute("name"))); + } + reader.Read(); + } + + break; + case "talentliste": + reader.Read(); + while (reader.Name.Equals("talent")) + { + Talente.Add( + new Talent( + reader.GetAttribute("name"), + reader.GetAttribute("probe").Remove(0, 2).Trim(')'), + Convert.ToInt32(reader.GetAttribute("value")))); + reader.Read(); + } + break; + case "zauberliste": + reader.Read(); + while (reader.Name.Equals("zauber")) + { + Talente.Add( + new Talent( + reader.GetAttribute("name"), + reader.GetAttribute("probe").Remove(0, 2).Trim(')'), + Convert.ToInt32(reader.GetAttribute("value")))); + reader.Read(); + } + break; + case "kampfwerte": + string atname = reader.GetAttribute("name"); + reader.Read(); + int at = Convert.ToInt32(reader.GetAttribute("value")); + reader.Read(); + int pa = Convert.ToInt32(reader.GetAttribute("value")); + Kampftalente.Add(new Kampf(atname, at, pa)); + break; + } + } + } + + + } + + public string TestTalent(string talent, int erschwernis = 0) //Talentprobe + { + try + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + var ttalent = Talente.OrderBy(x => sc.Compare(talent, x.name)).First(); + + var deug = Talente.OrderBy(x => sc.Compare(talent, x.name)); + var fit = deug.Select(x => sc.Compare(talent, x.name)); + + if (sc.Compare(talent, ttalent.name) > 94100) throw new Exception(); + + var props = ttalent.Test(); //get the required properties + int tap = ttalent.value; //get tap + var werte = props.Select(p => this.Eigenschaften[this.Proptable[p]]).ToList(); + + output.AppendFormat( + "{0} würfelt: {1} \n{2} - {3} taw:{4} {5} \n", + this.Name, + ttalent.name, + ttalent.probe, + String.Join("/", werte), + ttalent.value, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + + output.Append(" "); + tap -= erschwernis; + int gesamt_erschwernis = tap; + if (gesamt_erschwernis < 0) + { + tap = 0; + for (int i = 0; i <= 2; i++) //foreach property, dice and tap + { + int temp = dice.Roll(); + int eigenschaft = Eigenschaften[Proptable[props[i]]]; + + if (eigenschaft - gesamt_erschwernis < temp) + { + tap -= temp - eigenschaft + gesamt_erschwernis; + } + + output.Append($"[{temp}]"); //add to string + } + + if (tap >= 0) + { + tap = 1; + } + } + else + { + for (int i = 0; i <= 2; i++) //foreach property, dice and tap + { + int temp = dice.Roll(); + int eigenschaft = Eigenschaften[Proptable[props[i]]]; + + if (eigenschaft < temp) + { + tap -= temp - eigenschaft; + } + output.Append($"[{temp}]"); //add to string + } + } + + tap = tap == 0 ? 1 : tap; + + output.AppendFormat(" tap: {0,2}", tap); + + return output.ToString(); //return output + } + catch (Exception) + { + throw new Exception( + $"{talent} nicht vorhanden! Besitzt {Name} {talent} nicht? \n Oder ist {talent} falsch geschrieben?"); + } + } + + public string TestEigenschaft(string eigenschaft, int erschwernis = 0) + { + var output = new StringBuilder(); + var prop = this.Proptable[eigenschaft.ToUpper()]; + int tap = this.Eigenschaften[prop]; + output.AppendFormat( + "{0}-Eigenschaftsprobe ew:{1} {2} \n", + prop, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + int roll = dice.Roll(); + output.Append($"Gewürfelt: {roll} übrig: {tap - roll - erschwernis}"); + return output.ToString(); + } + + public string Angriff(string talent, int erschwernis = 0) //prety self explanetory + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + var attack = Kampftalente.OrderBy(x => sc.Compare(talent, x.name)).First(); + if (sc.Compare(talent, attack.name) > 94) + { + return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; + } + + int tap = attack.at; + output.AppendFormat("{0}-Angriff taw:{1} {2} \n", + attack.name, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + + int temp = dice.Roll(); + output.Append(temp - erschwernis); + return output.ToString(); + } + public string Parade(string talent, int erschwernis = 0) + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + var attack = Kampftalente.OrderBy(x => sc.Compare(talent, x.name)).First(); + + if (sc.Compare(talent, attack.name) > 94) + { + return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; + } + + int tap = attack.pa; + output.AppendFormat( + "{0}-Parade taw:{1} {2}\n", + attack.name, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + + int temp = dice.Roll(); + output.Append(temp - erschwernis); + return output.ToString(); + } + + public string Fernkampf(string talent, int erschwernis = 0) + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + int fk = Eigenschaften["fk"]; + var attack = Talente.OrderBy(x => sc.Compare(talent, x.name)).First(); + if(sc.Compare(talent, attack.name) > 94) + { + return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; + } + + int tap = attack.value; + output.AppendFormat( + "{0} taw:{1} {2} \n", + attack.name, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + tap -= erschwernis; + int temp = dice.Roll(); + tap -= temp > fk ? temp - fk : 0; + output.Append($"W20: {temp} tap: {tap}"); + return output.ToString(); + } + + } + +} diff --git a/DiscoBot/CommandExtension.cs b/DiscoBot/CommandExtension.cs new file mode 100644 index 0000000..06eec92 --- /dev/null +++ b/DiscoBot/CommandExtension.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscoBot +{ + using System.ComponentModel; + using System.Threading; + using Discord; + using Discord.Commands; + + public static class CommandExtension + { + public static async Task ReplyTimed(this ModuleBase m, string message, TimeSpan time) + { + var token = message.GetHashCode(); + var send = m.Context.Channel.SendMessageAsync($"#{token}\n```xl\n{message}```", true); + + BackgroundWorker barInvoker = new BackgroundWorker(); + barInvoker.DoWork += delegate + { + Thread.Sleep(time); + delete(token, m); + }; + + await send; + barInvoker.RunWorkerAsync(); + } + + private static async void delete(int token, ModuleBase m) + { + var messagesAsync = m.Context.Channel.GetMessagesAsync(100); + Task.WaitAll(messagesAsync.ToArray()); + var list = messagesAsync.ToEnumerable().ToList(); + var messages = new List(); + foreach (var task in list) + { + messages.AddRange(task.ToList()); + } + + await m.Context.Channel.DeleteMessagesAsync(messages.Where(x => x.Content.StartsWith($"#{token}\n") && x.Author.IsBot)); + } + } + +} diff --git a/DiscoBot/Commands.cs b/DiscoBot/Commands.cs index 7459451..55ad530 100644 --- a/DiscoBot/Commands.cs +++ b/DiscoBot/Commands.cs @@ -10,32 +10,19 @@ using Discord.WebSocket; namespace DiscoBot { - public static class DSA - { - public static Dictionary relation = new Dictionary(); //dictionary to match the char - public static List chars = new List(); //list of all charackters - public static void Startup() - { - relation.Add("The Doctor", "Numeri Illuminus");//Relation - relation.Add("Tardis", "Numeri Illuminus"); - relation.Add("DSA Bot", "Felis Exodus Schattenwald"); - relation.Add("Papo","Gwendelson"); - relation.Add("Potus","Volant"); - chars.Add(new Char(@"helden\Felis.xml")); //Savefile - chars.Add(new Char(@"helden\Numeri.xml")); - chars.Add(new Char(@"helden\Volant.xml")); + using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; + using System.Threading; - } - } public class Info : ModuleBase { [Command("say"), Summary("Echos a message.")] + [Alias("s")] public async Task Say([Remainder, Summary("The text to echo")] string echo) { - var a = Context.User.Username; - + var a = Context.User.Username; + await ReplyAsync(echo); - } } @@ -45,31 +32,63 @@ namespace DiscoBot [Alias("R", "Roll", "roll", "Würfle")] public async Task Say([Remainder, Summary("Weapon")] string roll) { - await ReplyAsync("```xl\n" + Misc.Roll(roll) + "\n```"); + } + } + public class SetGeneral : ModuleBase + { + [Command("general"), Summary("Set General ")] + public async Task Say([Remainder, Summary("Set General")] int i = 0) + { + DSA.GeneralContext = this.Context; + await this.Context.Channel.SendMessageAsync($"```xl\n Der Dachs hat in '{this.Context.Channel.Name}' ein Zuhause gefunden. Gm Nachrichten werden nun auch in diesem Channel gepostet. \n```"); } } + [SuppressMessage("ReSharper", "PublicMembersMustHaveComments", Justification = "OK")] public class TestTalent : ModuleBase { [Command("t"), Summary("Würfelt ein Talent-/Zauberprobe")] - [Alias("T", "Talent", "talent","zauber","z", "versuche")] - public async Task Say([Remainder, Summary("Talent oder Zaubername")] string talent) + [Alias("T", "Talent", "talent", "zauber", "z", "versuche")] + public async Task Say([Summary("Talent oder Zaubername")] string talent, int erschwernis = 0) { + string res = Gm.CheckCommand(DSA.relation[Context.User.Username], Commands.Talent, talent, erschwernis); + await this.ReplyAsync("```xl\n" + res + "\n```"); + + var tmessages = this.Context.Channel.GetMessagesAsync(10); + Task.WaitAll(tmessages.ToArray()); + var list = tmessages.ToEnumerable().ToList(); + var messages = new List(); + foreach (var task in list) + { + messages.AddRange(task.ToList()); + } - await ReplyAsync("```xl\n" + DSA.chars.Find(x=>x.name.Equals(DSA.relation[Context.User.Username])).TestTalent(talent) + "\n```"); + //await this.Context.Channel.DeleteMessagesAsync(messages.Where(x => x.Content[0].Equals('!') && (x.Author as SocketGuildUser).Roles.ToList().Exists(v => v.Name.Equals("Meister")))); + } + } + + public class TestEigenschaft : ModuleBase + { + [Command("e"), Summary("Würfelt eine Eifenschaftsprobe")] + [Alias("E", "Eigenschaft", "eigenschaft", "eigen")] + public async Task Say([Summary("Eigenschafts kürzel und Erschwernis")] string talent, int erschwernis = 0) + { + var chr = DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])); + string res = chr.TestEigenschaft(talent, erschwernis); + await this.ReplyAsync("```xl\n" + res + "\n```"); } } + public class Angriff : ModuleBase { [Command("a"), Summary("Würfelt ein Angriff")] - [Alias("A", "Angriff", "angriff", "attackiere_mit","attacke","Attacke")] - public async Task Say([Remainder, Summary("Weapon")] string weapon) + [Alias("At", "at", "Angriff", "angriff", "attackiere_mit", "attacke", "Attacke")] + public async Task Say([Summary("Weapon")] string weapon, int erschwernis = 0) { - - await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.name.Equals(DSA.relation[Context.User.Username])).Angriff(weapon) + "\n```"); + await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])).Angriff(weapon, erschwernis) + "\n```"); } } @@ -77,10 +96,10 @@ namespace DiscoBot { // ~say hello -> hello [Command("p"), Summary("Würfelt eine Parade Probe")] - [Alias("P", "Parade", "parade","pariere_mit")] - public async Task Say([Remainder, Summary("Parade Weapon")] string talent) + [Alias("P", "Parade", "parade", "pariere_mit")] + public async Task Say([Summary("Parade Weapon")] string talent, int erschwernis = 0) { - await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.name.Equals(DSA.relation[Context.User.Username])).Parade(talent) + "\n```"); + await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])).Parade(talent, erschwernis) + "\n```"); } } @@ -89,16 +108,40 @@ namespace DiscoBot // ~say hello -> hello [Command("f"), Summary("Führt eine Fernkampfprobe aus")] [Alias("F", "fernkampf", "Fernkampf", "schieße", "schieße_mit")] - public async Task Say([Summary("Fernkampfwaffe")] string talent,int erschwernis=0) + public async Task Say([Summary("Fernkampfwaffe")] string waffe, int erschwernis = 0) { // ReplyAsync is a method on ModuleBase + await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])).Fernkampf(waffe, erschwernis) + "\n```"); + } + public async Task Say([Summary("Fernkampfwaffe")] string charName, string waffe, ICommandContext context, int erschwernis = 0) + { + // ReplyAsync is a method on ModuleBase + await context.Channel.SendMessageAsync("Hello World\n"); + await context.Channel.SendMessageAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(charName)).Fernkampf(waffe, erschwernis) + "\n```"); + } + } - await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.name.Equals(DSA.relation[Context.User.Username])).Fernkampf(talent,erschwernis) + "\n```"); + public class Voice : ModuleBase + { + [Command("join")] + public async Task JoinChannel(IVoiceChannel channel = null) + { + // Get the audio channel + channel = channel ?? (this.Context.User as IGuildUser)?.VoiceChannel; + if (channel == null) + { + await this.Context.Channel.SendMessageAsync( + "User must be in a voice channel, or a voice channel must be passed as an argument."); + return; + } + // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. + var audioClient = await channel.ConnectAsync(); + } } - [Group("sample")] + [Group("gmtr")] public class Sample : ModuleBase { // ~sample square 20 -> 400 @@ -108,7 +151,7 @@ namespace DiscoBot // We can also access the channel from the Command Context. await Context.Channel.SendMessageAsync($"{num}^2 = {Math.Pow(num, 2)}"); } - + [Command("userinfo"), Summary("Returns info about the current user, or the user parameter, if one passed.")] [Alias("user", "whois")] public async Task UserInfo([Summary("The (optional) user to get info for")] IUser user = null) @@ -118,4 +161,217 @@ namespace DiscoBot } } + public class List : ModuleBase + { + // ~say hello -> hello + [Command("list"), Summary("gibt eine Auflistung aus")] + public async Task Say([Summary("Aktion")] string prop) + { + var res = new List(); + switch (prop.ToLower()) + { + case "chars": + case "Chars": + res.AddRange(DSA.chars.Select(x => x.Name)); + break; + case "t": + case "ta": + case "talent": + case "zauber": + res.AddRange( + ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) + .Talente.Select(s => s.name + "\t " + s.value + "\t " + s.probe)); + break; + case "w": + case "waffe": + case "waffen": + res.AddRange( + ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) + .Kampftalente.Select(s => s.name)); + break; + case "fern": + res.AddRange( + ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) + .Talente.Select(s => s.name)); + break; + case "v": + case "vt": + case "vor": + case "vorteil": + res.AddRange( + ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) + .Vorteile + .Select(s => s.name + "\t " + (s.value == 0 ? "" : s.value.ToString()))); + break; + + default: + res.Add($"Kommando {prop} nicht gefunden"); + break; + } + + //await this.ReplyAsync(res.Aggregate((seed, next) => seed + "\n" + next)); + var sb = new StringBuilder(); + foreach (string re in res) + { + if (sb.Length + re.Length > 1798) + { + await this.ReplyTimed(sb.ToString(), TimeSpan.FromSeconds(90)); + sb.Clear(); + } + + sb.AppendLine(re); + } + + await this.ReplyTimed(sb.ToString(), TimeSpan.FromSeconds(90)); + } + + } + + public class Gm : ModuleBase + { + // ~say hello -> hello + [Command("gm"), Summary("Führt eine probe aus")] + [Alias("GM", "as", "As", "als")] + public async Task Say([Summary("Fernkampfwaffe")] string name, string command, string waffe, int erschwernis = 0) + { + if (!(this.Context.User as SocketGuildUser).Roles.ToList().Exists(v => v.Name.Equals("Meister"))) + { + await ReplyAsync("```xl\n Keine ausreichenden Berechtigunen\n```"); + return; + } + + command = command.ToLower(); + string res; + switch (command) + { + case "f": + case "fern": + case "fernkampf": + res = CheckCommand(name, Commands.Fernkampf, waffe, erschwernis); + break; + case "t": + case "ta": + case "talent": + res = CheckCommand(name, Commands.Talent, waffe, erschwernis); + break; + case "e": + case "ei": + case "eigenschaft": + res = CheckCommand(name, Commands.Eigenschaft, waffe, erschwernis); + break; + case "z": + case "za": + case "zauber": + case "magie": + case "m": + res = CheckCommand(name, Commands.Talent, waffe, erschwernis); + break; + case "a": + case "at": + case "an": + case "angrif": + case "angriff": + res = CheckCommand(name, Commands.Angriff, waffe, erschwernis); + break; + case "p": + case "pa": + case "parade": + res = CheckCommand(name, Commands.Parade, waffe, erschwernis); + break; + case "talente": + throw new NotImplementedException(); + default: + res = $"Kommando {command} nicht gefunden"; + break; + } + + if (DSA.GeneralContext != null) + { + if (DSA.GeneralContext.Channel.Id != Context.Channel.Id) + { + await DSA.GeneralContext.Channel.SendMessageAsync("```xl\n" + res + "\n```"); + } + + await ReplyAsync("```xl\n" + res + "\n```"); + } + else + { + await ReplyAsync("```xl\n" + res + "\n```"); + } + } + + public static string CheckCommand(string name, Commands command, string waffe, int erschwernis = 0) + { + var comp = new SpellCorrect(); + var chr = DSA.chars.OrderBy(x => comp.Compare(x.Name, name)).First(); + switch (command) + { + case Commands.Talent: + return chr.TestTalent(waffe, erschwernis); + case Commands.Eigenschaft: + return chr.TestEigenschaft(waffe, erschwernis); + case Commands.Angriff: + return chr.Angriff(waffe, erschwernis); + case Commands.Parade: + return chr.Parade(waffe, erschwernis); + case Commands.Fernkampf: + return chr.Fernkampf(waffe, erschwernis); + } + + return $"{name} verwendet {waffe}"; + } + } + + public class GenerateNpc : ModuleBase + { + // ~say hello -> hello + [Command("npc"), Summary("Erstellt ein NPC")] + [Alias("Npc", "NPc", "NPC", "nPC")] + public async Task Say([Summary("Create Random")] string npcName, int mean = 9, int stDv = 1) + { + DSA.chars.Add(new NPC(npcName, mean, stDv)); + await this.ReplyAsync($"{npcName} wurde zufällig generiert"); + } + } + + public class CopyNpc : ModuleBase + { + // ~say hello -> hello + [Command("npc"), Summary("Erstellt ein NPC")] + [Alias("Npc", "NPc", "NPC", "nPC")] + public async Task Say([Summary("Create Copy")] string npcName, string source, int stDv = 1) + { + if (DSA.chars.Exists(x => x.Name.Equals(npcName))) + { + throw new Exception("Char gibt es schon"); + } + + var comp = new SpellCorrect(); + var chr = DSA.chars.OrderBy(x => comp.Compare(x.Name, source)).First(); + DSA.chars.Add(new Character(chr as Character, npcName, stDv)); + await ReplyAsync($"{npcName} wurde als variierte Kopie von {source} erstellt"); + } + } + + public class NpcAction : ModuleBase + { + // ~say hello -> hello + [Command("npc"), Summary("Führt eine NPC-Probe aus")] + [Alias("Npc", "NPc", "NPC", "nPC")] + public async Task Say([Summary("Aktion")] string NpcName, string command, string Aktion, int erschwernis = 0) + { + string test = ""; + } + } + + + public enum Commands + { + Talent, + Eigenschaft, + Angriff, + Parade, + Fernkampf, + KeinChar + } } diff --git a/DiscoBot/DSA.cs b/DiscoBot/DSA.cs new file mode 100644 index 0000000..60b25ce --- /dev/null +++ b/DiscoBot/DSA.cs @@ -0,0 +1,38 @@ +namespace DiscoBot +{ + using System.Collections.Generic; + using System.IO; + using System.Linq; + + using Discord.Commands; + + public static class DSA + { + public static ICommandContext GeneralContext { get; set; } + public static Dictionary relation = new Dictionary(); //dictionary to match the char + public static List chars = new List(); //list of all charackters + + public static List Talente { get; set; } = new List(); + + public static void Startup() + { + relation.Add("The Doctor", "Numeri Illuminus");//Relation + relation.Add("Tardis", "Morla");//"Numeri Illuminus"); + relation.Add("DSA Bot", "Morla");//"Felis Exodus Schattenwald"); + relation.Add("Morla", "Morla"); + relation.Add("Rhoktar", "Rhoktar4"); + //relation.Add("Papo","Gwendelson"); + relation.Add("Papo", "Pump aus der Gosse"); + relation.Add("Potus", "Potus"); + //relation.Add("Papo", "Pump aus der Gosse"); + foreach (var filename in Directory.GetFiles("helden", "*.xml")) + { + chars.Add(new Character(filename)); + (chars.Last() as Character)?.Talente.Select(x => new Talent(x.name, x.probe, 0)) + .Where(c => !Talente.Exists(v => v.name.Equals(c.name))).ToList().ForEach(v => Talente.Add(v)); + } + + Talente = Talente.OrderBy(x => x.name).ToList(); + } + } +} \ No newline at end of file diff --git a/DiscoBot/DiscoBot.csproj b/DiscoBot/DiscoBot.csproj index d4f3290..91ce25e 100644 --- a/DiscoBot/DiscoBot.csproj +++ b/DiscoBot/DiscoBot.csproj @@ -12,6 +12,8 @@ 512 true + + AnyCPU @@ -33,51 +35,53 @@ 4 - - ..\packages\Discord.Net.Commands.1.0.1\lib\netstandard1.1\Discord.Net.Commands.dll + + ..\packages\Discord.Net.Commands.1.0.2\lib\netstandard1.1\Discord.Net.Commands.dll - - ..\packages\Discord.Net.Core.1.0.1\lib\net45\Discord.Net.Core.dll + + ..\packages\Discord.Net.Core.1.0.2\lib\net45\Discord.Net.Core.dll - - ..\packages\Discord.Net.Rest.1.0.1\lib\net45\Discord.Net.Rest.dll + + ..\packages\Discord.Net.Rest.1.0.2\lib\net45\Discord.Net.Rest.dll - - ..\packages\Discord.Net.Rpc.1.0.1\lib\net45\Discord.Net.Rpc.dll + + ..\packages\Discord.Net.Rpc.1.0.2\lib\net45\Discord.Net.Rpc.dll - - ..\packages\Discord.Net.Webhook.1.0.1\lib\netstandard1.1\Discord.Net.Webhook.dll + + ..\packages\Discord.Net.Webhook.1.0.2\lib\netstandard1.1\Discord.Net.Webhook.dll - - ..\packages\Discord.Net.WebSocket.1.0.1\lib\net45\Discord.Net.WebSocket.dll + + ..\packages\Discord.Net.WebSocket.1.0.2\lib\net45\Discord.Net.WebSocket.dll - - ..\packages\Microsoft.Extensions.DependencyInjection.1.1.1\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll + + ..\packages\Microsoft.Extensions.DependencyInjection.2.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.dll - - ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.1\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll ..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll - ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\libsodium-net.0.10.0\lib\Net40\Sodium.dll ..\packages\System.AppContext.4.3.0\lib\net46\System.AppContext.dll - - ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - True + + ..\packages\System.Collections.Immutable.1.4.0\lib\netstandard2.0\System.Collections.Immutable.dll ..\packages\System.Console.4.3.0\lib\net46\System.Console.dll - - ..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + + ..\packages\System.Diagnostics.DiagnosticSource.4.4.1\lib\net46\System.Diagnostics.DiagnosticSource.dll ..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll @@ -98,8 +102,9 @@ ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll - - ..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll + + ..\packages\System.Net.Http.4.3.3\lib\net46\System.Net.Http.dll + True ..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll @@ -109,7 +114,9 @@ ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll - ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll + False + ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll + True ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll @@ -117,8 +124,9 @@ ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll - - ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll + True @@ -126,19 +134,43 @@ - ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll + False + ..\packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll + True - + + + + + + + True + True + Settings.settings + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}". + + + + + \ No newline at end of file diff --git a/DiscoBot/ICharacter.cs b/DiscoBot/ICharacter.cs new file mode 100644 index 0000000..fbaabd3 --- /dev/null +++ b/DiscoBot/ICharacter.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscoBot +{ + public interface ICharacter + { + string Name { get; set; } + + string TestTalent(string talent, int erschwernis = 0); + + string TestEigenschaft(string eigenschaft, int erschwernis = 0); + + string Angriff(string talent, int erschwernis = 0); + + string Parade(string talent, int erschwernis = 0); + + string Fernkampf(string talent, int erschwernis = 0); + } +} diff --git a/DiscoBot/Misc.cs b/DiscoBot/Misc.cs index 3876321..9c9456c 100644 --- a/DiscoBot/Misc.cs +++ b/DiscoBot/Misc.cs @@ -8,9 +8,12 @@ namespace DiscoBot { public static class Misc { - public static string Roll(string input) + private static readonly Random Rand = new Random(); + + // use: 4w6 +4 + public static string Roll(string input) { - int count = 1, d,mod=0; + int count = 1, d ,mod=0; var Output = new StringBuilder(); List strings = input.Split('w','d').ToList(); count = Convert.ToInt32(strings[0]); @@ -31,7 +34,131 @@ namespace DiscoBot return Output.ToString(); } + + public static double Random(double stdDev = 1, double mean = 0) + { + double u1 = Rand.NextDouble(); // uniform(0,1) random doubles + double u2 = Rand.NextDouble(); + double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * + Math.Sin(2.0 * Math.PI * u2); // random normal(0,1) + double randNormal = + mean + stdDev * randStdNormal; // random normal(mean,stdDev^2) + return randNormal; + } + } + + public class SpellCorrect : StringComparer + { + public override int Compare(string x, string y) + { + if (x.Equals(y)) + return 0; + x=x.ToLower(); + y=y.ToLower(); + if (x.Equals(y)) + return 1; + var subs = y.Split(' ', '/'); + int score = subs.Count(); + foreach (string s in subs) + { + if (s.Equals(x)) + { + score--; + } + } + + if (score < subs.Count()) + { + return score + 1; + } + + return 100000 - (int)(compare_exact(x, y) * 1000.0); + /*if (y.Contains(x)) + return 6;*/ + + } + + public override bool Equals(string x, string y) + { + throw new NotImplementedException(); + } + + public override int GetHashCode(string obj) + { + throw new NotImplementedException(); + } + + public double compare_exact(string s, string q) + { + int i, j; + const double Match = 3.0; + const double Gap = -2.0; + const double Mismatch = -2.0; + + double decay = 0.0; + + double[,] matrix = new double[s.Length + 1, q.Length + 1]; + double max = 0.0; + matrix[0, 0] = 0.0; + + for (i = 1; i < s.Length; i++) + { + matrix[i, 0] = 0.0; + } + + for (i = 1; i < q.Length; i++) + { + matrix[0, i] = 0.0; + } + + for (i = 1; i <= s.Length; i++) + { + for (j = 1; j <= q.Length; j++) + { + decay = j / (double)(s.Length * 1000); + double add = s[i - 1] == q[j - 1] ? (Match - decay) : Mismatch; + double score = matrix[i - 1, j - 1] + add; + + if (score < (matrix[i - 1, j] + Gap)) + { + score = matrix[i - 1, j] + Gap; + } + + if (score < (matrix[i, j - 1] + Gap)) + { + score = matrix[i, j - 1] + Gap; + } + + if (i > 1 && j > 1) + { + if (s[i - 1] == q[j - 2] && s[i - 2] == q[j - 1]) + { + add = (3 / 2.0) * Match - decay; + if (score < matrix[i - 2, j - 2] + add) + { + score = matrix[i - 2, j - 2] + add; + } + } + } + + if (score < 0) + { + score = 0; + } + + if (max < score) + { + max = score; + } + + matrix[i, j] = score; + } + } + + return max; + } } + public static class dice//roll it! { static System.Random rnd = new System.Random(); @@ -40,6 +167,19 @@ namespace DiscoBot return rnd.Next(1, d+1); } } + + public class Vorteil //talent objekt + { + public string name; + public int value; + + public Vorteil(string name, int value = 0) + { + this.name = name; + this.value = value; + } + } + public class Talent //talent objekt { public string name, probe; @@ -55,24 +195,12 @@ namespace DiscoBot public int CheckName(string quary) { - if (quary.Equals(name)) - return 0; - if (String.Compare(name, quary, StringComparison.InvariantCultureIgnoreCase) == 0) - return 1; - var subs = name.Split(' ','/'); - int score = subs.Count(); - foreach (String s in subs) - if (String.Compare(name, quary, StringComparison.InvariantCultureIgnoreCase) == 0) - score--; - if (score != subs.Count()) - return score+1; - if (name.ToLowerInvariant().Contains(quary.ToLower())) - return 3; - - return 100; + var sc = (StringComparer)new SpellCorrect(); + return sc.Compare(quary, this.name); } } + public class Kampf { public string name; diff --git a/DiscoBot/NPC.cs b/DiscoBot/NPC.cs new file mode 100644 index 0000000..4104947 --- /dev/null +++ b/DiscoBot/NPC.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscoBot +{ + public class NPC : ICharacter + { + private int mean, stDv; + + public NPC(string name, int mean, int stDv) + { + this.mean = mean; + this.stDv = stDv; + this.Name = name; + } + + public string Name { get; set; } + + public string TestTalent(string talent, int tap = 3) + { + for (int i = 0; i <= 2; i++) //foreach property, dice and tap + { + int temp = dice.Roll(); + int eigenschaft = (int)Math.Round(Misc.Random(this.stDv, this.mean)); + + if (eigenschaft < temp) + { + tap -= temp - eigenschaft; + } + } + + if (tap >= 0) + { + return $"{this.Name} vollführt {talent} erfolgreich"; + } + + return $"{this.Name} scheitert an {talent}"; + } + + public string TestEigenschaft(string eigenschaft, int erschwernis = 0) + { + int temp = dice.Roll(); + int prop = (int)Math.Round(Misc.Random(this.stDv, this.stDv)); + + if (temp + erschwernis < prop) + { + return $"{this.Name} vollführt {eigenschaft} erfolgreich"; + } + + return $"{this.Name} scheitert an {eigenschaft}"; + } + + public string Angriff(string waffe, int erschwernis = 0) + { + int temp = dice.Roll(); + + if (temp == 1) + { + return $"{this.Name} greift kritisch mit {waffe} an"; + } + + if (temp < erschwernis) + { + return $"{this.Name} greift mit {waffe} an"; + } + + return $"{this.Name} haut mit {waffe} daneben"; + } + + public string Parade(string waffe, int erschwernis = 0) + { + int temp = dice.Roll(); + + if (temp == 1) + { + return $"{this.Name} pariert mit {waffe} meisterlich"; + } + + if (temp < erschwernis) + { + return $"{this.Name} pariert mit {waffe} an"; + } + + return $"{this.Name} schafft es nicht mit {waffe} zu parieren"; + } + + public string Fernkampf(string waffe, int erschwernis = 0) + { + int temp = dice.Roll(); + + if (temp == 1) + { + return $"{this.Name} trifft kritisch mit {waffe}"; + } + + if (temp < erschwernis) + { + return $"{this.Name} greift mit {waffe} an"; + } + + return $"{this.Name} schießt mit {waffe} daneben"; + } + } +} diff --git a/DiscoBot/Program.cs b/DiscoBot/Program.cs index a6e496c..b90ed54 100644 --- a/DiscoBot/Program.cs +++ b/DiscoBot/Program.cs @@ -28,7 +28,7 @@ namespace DiscoBot client = new DiscordSocketClient(); commands = new CommandService(); - string token = ""; + string token = Properties.Settings.Default.Token; services = new ServiceCollection() .BuildServiceProvider(); diff --git a/DiscoBot/Properties/Settings.Designer.cs b/DiscoBot/Properties/Settings.Designer.cs new file mode 100644 index 0000000..9813b8a --- /dev/null +++ b/DiscoBot/Properties/Settings.Designer.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 +// +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. +// +//------------------------------------------------------------------------------ + +namespace DiscoBot.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.6.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("Mjk0NTU0MDU4Nzg4NzAwMTYx.DOzDcQ.J-nCikbZdZtdrug0E8TwwV_2ITw")] + public string Token { + get { + return ((string)(this["Token"])); + } + set { + this["Token"] = value; + } + } + } +} diff --git a/DiscoBot/Properties/Settings.settings b/DiscoBot/Properties/Settings.settings new file mode 100644 index 0000000..f3be2b7 --- /dev/null +++ b/DiscoBot/Properties/Settings.settings @@ -0,0 +1,9 @@ + + + + + + Mjk0NTU0MDU4Nzg4NzAwMTYx.DOzDcQ.J-nCikbZdZtdrug0E8TwwV_2ITw + + + \ No newline at end of file diff --git a/DiscoBot/packages.config b/DiscoBot/packages.config index cf276c0..e3bca0f 100644 --- a/DiscoBot/packages.config +++ b/DiscoBot/packages.config @@ -1,26 +1,28 @@  - - - - - - - - - - + + + + + + + + + + + + - - + + - + - + @@ -33,7 +35,7 @@ - + @@ -47,16 +49,16 @@ - + - + - + \ No newline at end of file diff --git a/UnitTestProject1/Properties/AssemblyInfo.cs b/UnitTestProject1/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9dbb2a9 --- /dev/null +++ b/UnitTestProject1/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("UnitTestProject1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("UnitTestProject1")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("75b56398-a683-4b85-9ba3-b445d2b55527")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UnitTestProject1/UnitTest1.cs b/UnitTestProject1/UnitTest1.cs new file mode 100644 index 0000000..dbc289d --- /dev/null +++ b/UnitTestProject1/UnitTest1.cs @@ -0,0 +1,14 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace UnitTestProject1 +{ + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void TestMethod1() + { + } + } +} diff --git a/UnitTestProject1/UnitTestProject1.csproj b/UnitTestProject1/UnitTestProject1.csproj new file mode 100644 index 0000000..e887a0e --- /dev/null +++ b/UnitTestProject1/UnitTestProject1.csproj @@ -0,0 +1,67 @@ + + + + + Debug + AnyCPU + {75B56398-A683-4B85-9BA3-B445D2B55527} + Library + Properties + UnitTestProject1 + UnitTestProject1 + v4.7.1 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + + + Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}". + + + + + + \ No newline at end of file diff --git a/UnitTestProject1/packages.config b/UnitTestProject1/packages.config new file mode 100644 index 0000000..8819694 --- /dev/null +++ b/UnitTestProject1/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Voice.cs b/Voice.cs new file mode 100644 index 0000000..ea2f6d6 --- /dev/null +++ b/Voice.cs @@ -0,0 +1,21 @@ +using System; + +public class Voice +{ + public Voice(IAudioclient audi) + { + + } + + private Process CreateStream(string path) + { + var ffmpeg = new ProcessStartInfo + { + FileName = "ffmpeg", + Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 pipe:1", + UseShellExecute = false, + RedirectStandardOutput = true, + }; + return Process.Start(ffmpeg); + } +} -- cgit v1.2.3-70-g09d2 From cac1ade8763605c3cf09859a48358cab0e00027a Mon Sep 17 00:00:00 2001 From: TrueDoctor Date: Sun, 8 Apr 2018 23:06:21 +0200 Subject: Added Audio Support --- DiscoBot/Audio.cs | 27 +++++++++++++++ DiscoBot/AudioService.cs | 88 ++++++++++++++++++++++++++++++++++++++++++++++ DiscoBot/Commands.cs | 90 +++++++++++++++++++++++++++++++++++++++++++----- DiscoBot/DSA.cs | 3 +- DiscoBot/DiscoBot.csproj | 2 ++ DiscoBot/Program.cs | 9 ++++- Voice.cs | 19 +--------- 7 files changed, 209 insertions(+), 29 deletions(-) create mode 100644 DiscoBot/Audio.cs create mode 100644 DiscoBot/AudioService.cs (limited to 'DiscoBot/DiscoBot.csproj') diff --git a/DiscoBot/Audio.cs b/DiscoBot/Audio.cs new file mode 100644 index 0000000..68c860c --- /dev/null +++ b/DiscoBot/Audio.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DiscoBot +{ + using System.Diagnostics; + + class Audio + { + private Process CreateStream(string path) + { + var ffmpeg = new ProcessStartInfo + { + FileName = "ffmpeg", + Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 pipe:1", + UseShellExecute = false, + RedirectStandardOutput = true, + }; + return Process.Start(ffmpeg); + } + } + + +} diff --git a/DiscoBot/AudioService.cs b/DiscoBot/AudioService.cs new file mode 100644 index 0000000..bb4d21e --- /dev/null +++ b/DiscoBot/AudioService.cs @@ -0,0 +1,88 @@ +using System.Collections.Concurrent; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using Discord; +using Discord.Audio; + +namespace DiscoBot +{ + public class AudioService + { + private readonly ConcurrentDictionary ConnectedChannels = + new ConcurrentDictionary(); + + public async Task JoinAudio(IGuild guild, IVoiceChannel target) + { + IAudioClient client; + if (ConnectedChannels.TryGetValue(guild.Id, out client)) + { + return; + } + + if (target.Guild.Id != guild.Id) + { + return; + } + + var audioClient = await target.ConnectAsync(); + + if (ConnectedChannels.TryAdd(guild.Id, audioClient)) + { + // If you add a method to log happenings from this service, + // you can uncomment these commented lines to make use of that. + //await Log(LogSeverity.Info, $"Connected to voice on {guild.Name}."); + } + } + + public async Task LeaveAudio(IGuild guild) + { + IAudioClient client; + if (ConnectedChannels.TryRemove(guild.Id, out client)) + { + await client.StopAsync(); + //await Log(LogSeverity.Info, $"Disconnected from voice on {guild.Name}."); + } + } + + public async Task SendAudioAsync(IGuild guild, IMessageChannel channel, string path) + { + // Your task: Get a full path to the file if the value of 'path' is only a filename. + if (!File.Exists(path)) + { + await channel.SendMessageAsync("File does not exist."); + return; + } + + IAudioClient client; + if (ConnectedChannels.TryGetValue(guild.Id, out client)) + { + //await Log(LogSeverity.Debug, $"Starting playback of {path} in {guild.Name}"); + using (var ffmpeg = Process.Start(path)) + using (var stream = client.CreatePCMStream(AudioApplication.Music)) + { + try + { + await ffmpeg.StandardOutput.BaseStream.CopyToAsync(stream); + } + finally + { + await stream.FlushAsync(); + } + } + } + } + + private Process CreateStream(string path) + { + return Process.Start( + new ProcessStartInfo + { + FileName = "ffmpeg.exe", + Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1", + UseShellExecute = false, + RedirectStandardOutput = true + }); + } + } +} diff --git a/DiscoBot/Commands.cs b/DiscoBot/Commands.cs index 55ad530..6ba2b8a 100644 --- a/DiscoBot/Commands.cs +++ b/DiscoBot/Commands.cs @@ -11,9 +11,12 @@ using Discord.WebSocket; namespace DiscoBot { using System.ComponentModel; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Threading; + using Discord.Audio; + public class Info : ModuleBase { [Command("say"), Summary("Echos a message.")] @@ -123,24 +126,57 @@ namespace DiscoBot public class Voice : ModuleBase { - [Command("join")] + public static IAudioClient client { get; set; } + [Command("join", RunMode = RunMode.Async)] public async Task JoinChannel(IVoiceChannel channel = null) { + var msg = this.Context.Message; // Get the audio channel - channel = channel ?? (this.Context.User as IGuildUser)?.VoiceChannel; - if (channel == null) - { - await this.Context.Channel.SendMessageAsync( - "User must be in a voice channel, or a voice channel must be passed as an argument."); - return; - } + channel = channel ?? (msg.Author as IGuildUser)?.VoiceChannel; + if (channel == null) { await msg.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument."); return; } // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. var audioClient = await channel.ConnectAsync(); - + client = audioClient; + } + + [Command("leave", RunMode = RunMode.Async)] + public async Task LeaveChannel(IVoiceChannel channel = null) + { + // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. + client.StopAsync(); + } + + [Command("play")] + public async Task PlayAudio(string path) + { + SendAsync(client, path); + } + + private Process CreateStream(string path) + { + var ffmpeg = new ProcessStartInfo + { + FileName = "ffmpeg", + Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 -ab 620000 pipe:1", + UseShellExecute = false, + RedirectStandardOutput = true, + }; + return Process.Start(ffmpeg); + } + + private async Task SendAsync(IAudioClient client, string path) + { + // Create FFmpeg using the previous example + var ffmpeg = CreateStream(path); + var output = ffmpeg.StandardOutput.BaseStream; + var discord = client.CreatePCMStream(AudioApplication.Music); + await output.CopyToAsync(discord); + await discord.FlushAsync(); } } + [Group("gmtr")] public class Sample : ModuleBase { @@ -364,6 +400,42 @@ namespace DiscoBot } } + /*public class AudioModule : ModuleBase + { + // Scroll down further for the AudioService. + // Like, way down + private readonly AudioService _service; + + // Remember to add an instance of the AudioService + // to your IServiceCollection when you initialize your bot + public AudioModule(AudioService service) + { + _service = service; + } + + // You *MUST* mark these commands with 'RunMode.Async' + // otherwise the bot will not respond until the Task times out. + [Command("join", RunMode = RunMode.Async)] + public async Task JoinCmd() + { + await _service.JoinAudio(Context.Guild, (Context.User as IVoiceState).VoiceChannel); + } + + // Remember to add preconditions to your commands, + // this is merely the minimal amount necessary. + // Adding more commands of your own is also encouraged. + [Command("leave", RunMode = RunMode.Async)] + public async Task LeaveCmd() + { + await _service.LeaveAudio(Context.Guild); + } + + [Command("play", RunMode = RunMode.Async)] + public async Task PlayCmd([Remainder] string song) + { + await _service.SendAudioAsync(Context.Guild, Context.Channel, song); + } + }*/ public enum Commands { diff --git a/DiscoBot/DSA.cs b/DiscoBot/DSA.cs index 60b25ce..af02023 100644 --- a/DiscoBot/DSA.cs +++ b/DiscoBot/DSA.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; + using System.Threading.Tasks; using Discord.Commands; @@ -14,7 +15,7 @@ public static List Talente { get; set; } = new List(); - public static void Startup() + public static async Task Startup() { relation.Add("The Doctor", "Numeri Illuminus");//Relation relation.Add("Tardis", "Morla");//"Numeri Illuminus"); diff --git a/DiscoBot/DiscoBot.csproj b/DiscoBot/DiscoBot.csproj index 91ce25e..d0fc986 100644 --- a/DiscoBot/DiscoBot.csproj +++ b/DiscoBot/DiscoBot.csproj @@ -140,6 +140,8 @@ + + diff --git a/DiscoBot/Program.cs b/DiscoBot/Program.cs index b90ed54..7ae8244 100644 --- a/DiscoBot/Program.cs +++ b/DiscoBot/Program.cs @@ -24,7 +24,7 @@ namespace DiscoBot public async Task Start() { - DSA.Startup(); + var loading = DSA.Startup(); client = new DiscordSocketClient(); commands = new CommandService(); @@ -32,12 +32,14 @@ namespace DiscoBot services = new ServiceCollection() .BuildServiceProvider(); + AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit); await InstallCommands(); await client.LoginAsync(TokenType.Bot, token); await client.StartAsync(); + await loading; await Task.Delay(-1); } @@ -66,6 +68,11 @@ namespace DiscoBot if (!result.IsSuccess) await context.Channel.SendMessageAsync(result.ErrorReason); } + static void OnProcessExit(object sender, EventArgs e) + { + Console.WriteLine("I'm out of here"); + Voice.client.StopAsync(); + } } } diff --git a/Voice.cs b/Voice.cs index ea2f6d6..031c49e 100644 --- a/Voice.cs +++ b/Voice.cs @@ -1,21 +1,4 @@ using System; +using Discord; -public class Voice -{ - public Voice(IAudioclient audi) - { - } - - private Process CreateStream(string path) - { - var ffmpeg = new ProcessStartInfo - { - FileName = "ffmpeg", - Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 pipe:1", - UseShellExecute = false, - RedirectStandardOutput = true, - }; - return Process.Start(ffmpeg); - } -} -- cgit v1.2.3-70-g09d2 From 82f07c959dc7a87251b4617e462003471e3cc071 Mon Sep 17 00:00:00 2001 From: TrueDoctor Date: Mon, 9 Apr 2018 00:54:19 +0200 Subject: Refactoring and Cleanup --- DiscoBot/App.config | 4 - DiscoBot/Audio.cs | 27 -- DiscoBot/AudioService.cs | 88 ------- DiscoBot/Auxiliary/CommandExtension.cs | 46 ++++ DiscoBot/Auxiliary/Dice.cs | 12 + DiscoBot/Auxiliary/KampfTalent.cs | 18 ++ DiscoBot/Auxiliary/Misc.cs | 51 ++++ DiscoBot/Auxiliary/SpellCorrect.cs | 134 ++++++++++ DiscoBot/Auxiliary/Talent.cs | 37 +++ DiscoBot/Auxiliary/Vorteil.cs | 15 ++ DiscoBot/Character.cs | 309 ----------------------- DiscoBot/Characters/Character.cs | 312 +++++++++++++++++++++++ DiscoBot/Characters/ICharacter.cs | 17 ++ DiscoBot/Characters/NPC.cs | 106 ++++++++ DiscoBot/CommandExtension.cs | 47 ---- DiscoBot/Commands.cs | 449 --------------------------------- DiscoBot/Commands/CommandTypes.cs | 12 + DiscoBot/Commands/Gm.cs | 103 ++++++++ DiscoBot/Commands/List.cs | 76 ++++++ DiscoBot/Commands/NpcCommands.cs | 37 +++ DiscoBot/Commands/Test.cs | 47 ++++ DiscoBot/Commands/Utility.cs | 32 +++ DiscoBot/Commands/Voice.cs | 67 +++++ DiscoBot/DSA.cs | 44 ++-- DiscoBot/DiscoBot.csproj | 25 +- DiscoBot/ICharacter.cs | 23 -- DiscoBot/Misc.cs | 212 ---------------- DiscoBot/NPC.cs | 107 -------- DiscoBot/Program.cs | 73 +++--- 29 files changed, 1205 insertions(+), 1325 deletions(-) delete mode 100644 DiscoBot/Audio.cs delete mode 100644 DiscoBot/AudioService.cs create mode 100644 DiscoBot/Auxiliary/CommandExtension.cs create mode 100644 DiscoBot/Auxiliary/Dice.cs create mode 100644 DiscoBot/Auxiliary/KampfTalent.cs create mode 100644 DiscoBot/Auxiliary/Misc.cs create mode 100644 DiscoBot/Auxiliary/SpellCorrect.cs create mode 100644 DiscoBot/Auxiliary/Talent.cs create mode 100644 DiscoBot/Auxiliary/Vorteil.cs delete mode 100644 DiscoBot/Character.cs create mode 100644 DiscoBot/Characters/Character.cs create mode 100644 DiscoBot/Characters/ICharacter.cs create mode 100644 DiscoBot/Characters/NPC.cs delete mode 100644 DiscoBot/CommandExtension.cs delete mode 100644 DiscoBot/Commands.cs create mode 100644 DiscoBot/Commands/CommandTypes.cs create mode 100644 DiscoBot/Commands/Gm.cs create mode 100644 DiscoBot/Commands/List.cs create mode 100644 DiscoBot/Commands/NpcCommands.cs create mode 100644 DiscoBot/Commands/Test.cs create mode 100644 DiscoBot/Commands/Utility.cs create mode 100644 DiscoBot/Commands/Voice.cs delete mode 100644 DiscoBot/ICharacter.cs delete mode 100644 DiscoBot/Misc.cs delete mode 100644 DiscoBot/NPC.cs (limited to 'DiscoBot/DiscoBot.csproj') diff --git a/DiscoBot/App.config b/DiscoBot/App.config index 5740218..d08a333 100644 --- a/DiscoBot/App.config +++ b/DiscoBot/App.config @@ -14,10 +14,6 @@ - - - - diff --git a/DiscoBot/Audio.cs b/DiscoBot/Audio.cs deleted file mode 100644 index 68c860c..0000000 --- a/DiscoBot/Audio.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - using System.Diagnostics; - - class Audio - { - private Process CreateStream(string path) - { - var ffmpeg = new ProcessStartInfo - { - FileName = "ffmpeg", - Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 pipe:1", - UseShellExecute = false, - RedirectStandardOutput = true, - }; - return Process.Start(ffmpeg); - } - } - - -} diff --git a/DiscoBot/AudioService.cs b/DiscoBot/AudioService.cs deleted file mode 100644 index bb4d21e..0000000 --- a/DiscoBot/AudioService.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Collections.Concurrent; -using System.Diagnostics; -using System.IO; -using System.Threading.Tasks; -using Discord; -using Discord.Audio; - -namespace DiscoBot -{ - public class AudioService - { - private readonly ConcurrentDictionary ConnectedChannels = - new ConcurrentDictionary(); - - public async Task JoinAudio(IGuild guild, IVoiceChannel target) - { - IAudioClient client; - if (ConnectedChannels.TryGetValue(guild.Id, out client)) - { - return; - } - - if (target.Guild.Id != guild.Id) - { - return; - } - - var audioClient = await target.ConnectAsync(); - - if (ConnectedChannels.TryAdd(guild.Id, audioClient)) - { - // If you add a method to log happenings from this service, - // you can uncomment these commented lines to make use of that. - //await Log(LogSeverity.Info, $"Connected to voice on {guild.Name}."); - } - } - - public async Task LeaveAudio(IGuild guild) - { - IAudioClient client; - if (ConnectedChannels.TryRemove(guild.Id, out client)) - { - await client.StopAsync(); - //await Log(LogSeverity.Info, $"Disconnected from voice on {guild.Name}."); - } - } - - public async Task SendAudioAsync(IGuild guild, IMessageChannel channel, string path) - { - // Your task: Get a full path to the file if the value of 'path' is only a filename. - if (!File.Exists(path)) - { - await channel.SendMessageAsync("File does not exist."); - return; - } - - IAudioClient client; - if (ConnectedChannels.TryGetValue(guild.Id, out client)) - { - //await Log(LogSeverity.Debug, $"Starting playback of {path} in {guild.Name}"); - using (var ffmpeg = Process.Start(path)) - using (var stream = client.CreatePCMStream(AudioApplication.Music)) - { - try - { - await ffmpeg.StandardOutput.BaseStream.CopyToAsync(stream); - } - finally - { - await stream.FlushAsync(); - } - } - } - } - - private Process CreateStream(string path) - { - return Process.Start( - new ProcessStartInfo - { - FileName = "ffmpeg.exe", - Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1", - UseShellExecute = false, - RedirectStandardOutput = true - }); - } - } -} diff --git a/DiscoBot/Auxiliary/CommandExtension.cs b/DiscoBot/Auxiliary/CommandExtension.cs new file mode 100644 index 0000000..6690d03 --- /dev/null +++ b/DiscoBot/Auxiliary/CommandExtension.cs @@ -0,0 +1,46 @@ +namespace DiscoBot.Auxiliary +{ + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + using System.Threading; + using System.Threading.Tasks; + + using Discord; + using Discord.Commands; + + public static class CommandExtension + { + public static async Task ReplyTimedAsync(this ModuleBase m, string message, TimeSpan time) + { + var token = message.GetHashCode(); + var send = m.Context.Channel.SendMessageAsync($"#{token}\n```xl\n{message}```", true); + + var barInvoker = new BackgroundWorker(); + barInvoker.DoWork += delegate + { + Thread.Sleep(time); + Delete(token, m); + }; + + await send; + barInvoker.RunWorkerAsync(); + } + + private static void Delete(int token, ModuleBase m) + { + var messagesAsync = m.Context.Channel.GetMessagesAsync(); + Task.WaitAll(messagesAsync.ToArray()); + var list = messagesAsync.ToEnumerable().ToList(); + var messages = new List(); + foreach (var task in list) + { + messages.AddRange(task.ToList()); + } + + m.Context.Channel.DeleteMessagesAsync( + messages.Where(x => x.Content.StartsWith($"#{token}\n") && x.Author.IsBot)); + } + } +} diff --git a/DiscoBot/Auxiliary/Dice.cs b/DiscoBot/Auxiliary/Dice.cs new file mode 100644 index 0000000..16a8a77 --- /dev/null +++ b/DiscoBot/Auxiliary/Dice.cs @@ -0,0 +1,12 @@ +namespace DiscoBot.Auxiliary +{ + public static class Dice // roll it! + { + private static readonly System.Random Rnd = new System.Random(); + + public static int Roll(int d = 20) + { + return Rnd.Next(d) + 1; + } + } +} diff --git a/DiscoBot/Auxiliary/KampfTalent.cs b/DiscoBot/Auxiliary/KampfTalent.cs new file mode 100644 index 0000000..05b7c9e --- /dev/null +++ b/DiscoBot/Auxiliary/KampfTalent.cs @@ -0,0 +1,18 @@ +namespace DiscoBot.Auxiliary +{ + public class KampfTalent + { + public KampfTalent(string name, int at, int pa) + { + this.Name = name; + this.At = at; + this.Pa = pa; + } + + public string Name { get; set; } + + public int At { get; set; } + + public int Pa { get; set; } + } +} diff --git a/DiscoBot/Auxiliary/Misc.cs b/DiscoBot/Auxiliary/Misc.cs new file mode 100644 index 0000000..2531f12 --- /dev/null +++ b/DiscoBot/Auxiliary/Misc.cs @@ -0,0 +1,51 @@ +namespace DiscoBot.Auxiliary +{ + using System; + using System.Linq; + using System.Text; + + public static class Misc + { + private static readonly Random Rand = new Random(); + + // use: 4w6 +4 + public static string Roll(string input) + { + var output = new StringBuilder(); + var strings = input.Split('w', 'd').ToList(); + int count = Convert.ToInt32(strings[0]); + strings = strings[1].Split(' ').ToList(); + int d = Convert.ToInt32(strings[0]); + + if (strings.Count > 0) + { + } + + int sum = 0; + for (int i = 0; i < count; i++) + { + var roll = Dice.Roll(d); + sum += roll; + output.Append("[" + roll + "] "); + } + + if (count > 1) + { + output.Append("sum: " + sum); + } + + return output.ToString(); + } + + public static double Random(double stdDev = 1, double mean = 0) + { + double u1 = Rand.NextDouble(); // uniform(0,1) random doubles + double u2 = Rand.NextDouble(); + double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * + Math.Sin(2.0 * Math.PI * u2); // random normal(0,1) + double randNormal = + mean + stdDev * randStdNormal; // random normal(mean,stdDev^2) + return randNormal; + } + } +} diff --git a/DiscoBot/Auxiliary/SpellCorrect.cs b/DiscoBot/Auxiliary/SpellCorrect.cs new file mode 100644 index 0000000..8c5741b --- /dev/null +++ b/DiscoBot/Auxiliary/SpellCorrect.cs @@ -0,0 +1,134 @@ +namespace DiscoBot.Auxiliary +{ + using System; + using System.Diagnostics; + using System.Linq; + + public class SpellCorrect : StringComparer + { + public override int Compare(string x, string y) + { + if (string.IsNullOrEmpty(x)) + { + throw new ArgumentException("message", nameof(x)); + } + + if (string.IsNullOrEmpty(y)) + { + throw new ArgumentException("message", nameof(y)); + } + + if (x.Equals(y)) + { + return 0; + } + + x = x.ToLower(); + y = y.ToLower(); + if (x.Equals(y)) + { + return 1; + } + + var subs = y.Split(' ', '/'); + int score = subs.Count(); + foreach (string s in subs) + { + if (s.Equals(x)) + { + score--; + } + } + + if (score < subs.Count()) + { + return score + 1; + } + + return 100000 - (int)(this.CompareExact(x, y) * 1000.0); + /*if (y.Contains(x)) + return 6;*/ + } + + public override bool Equals(string x, string y) + { + Debug.Assert(x != null, nameof(x) + " != null"); + return x.Equals(y); + } + + public override int GetHashCode(string obj) + { + throw new NotImplementedException(); + } + + public double CompareExact(string s, string q) + { + int i, j; + const double Match = 3.0; + const double Gap = -2.0; + const double Mismatch = -2.0; + + double decay; + + double[,] matrix = new double[s.Length + 1, q.Length + 1]; + double max = 0.0; + matrix[0, 0] = 0.0; + + for (i = 1; i < s.Length; i++) + { + matrix[i, 0] = 0.0; + } + + for (i = 1; i < q.Length; i++) + { + matrix[0, i] = 0.0; + } + + for (i = 1; i <= s.Length; i++) + { + for (j = 1; j <= q.Length; j++) + { + decay = j / (double)(s.Length * 1000); + double add = s[i - 1] == q[j - 1] ? (Match - decay) : Mismatch; + double score = matrix[i - 1, j - 1] + add; + + if (score < (matrix[i - 1, j] + Gap)) + { + score = matrix[i - 1, j] + Gap; + } + + if (score < (matrix[i, j - 1] + Gap)) + { + score = matrix[i, j - 1] + Gap; + } + + if (i > 1 && j > 1) + { + if (s[i - 1] == q[j - 2] && s[i - 2] == q[j - 1]) + { + add = (3 / 2.0) * Match - decay; + if (score < matrix[i - 2, j - 2] + add) + { + score = matrix[i - 2, j - 2] + add; + } + } + } + + if (score < 0) + { + score = 0; + } + + if (max < score) + { + max = score; + } + + matrix[i, j] = score; + } + } + + return max; + } + } +} diff --git a/DiscoBot/Auxiliary/Talent.cs b/DiscoBot/Auxiliary/Talent.cs new file mode 100644 index 0000000..969304c --- /dev/null +++ b/DiscoBot/Auxiliary/Talent.cs @@ -0,0 +1,37 @@ +namespace DiscoBot.Auxiliary +{ + using System; + + public class Talent // talent objekt + { + public Talent(string name, string probe, int value) + { + this.Name = name; + this.Probe = probe; + this.Value = value; + } + + public string Name { get; set; } + + public string Probe { get; set; } + + public int Value { get; set; } + + public string[] Test() // turn XX/XX/XX into string[]{XX,XX,XX} + { + var temp = this.Probe.Split('/'); + for (var index = 0; index < temp.Length; index++) + { + temp[index] = temp[index].Replace("/", string.Empty); + } + + return temp; + } + + public int CheckName(string quarry) + { + var sc = (StringComparer)new SpellCorrect(); + return sc.Compare(quarry, this.Name); + } + } +} diff --git a/DiscoBot/Auxiliary/Vorteil.cs b/DiscoBot/Auxiliary/Vorteil.cs new file mode 100644 index 0000000..823305c --- /dev/null +++ b/DiscoBot/Auxiliary/Vorteil.cs @@ -0,0 +1,15 @@ +namespace DiscoBot.Auxiliary +{ + public class Vorteil // talent objekt + { + public Vorteil(string name, int value = 0) + { + this.Name = name; + this.Value = value; + } + + public string Name { get; set; } + + public int Value { get; set; } + } +} diff --git a/DiscoBot/Character.cs b/DiscoBot/Character.cs deleted file mode 100644 index 18b6213..0000000 --- a/DiscoBot/Character.cs +++ /dev/null @@ -1,309 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml; - -namespace DiscoBot -{ - public class Character : ICharacter - { - public string Name { get; set; } //charname - public Dictionary Eigenschaften = new Dictionary(); //char porperties - public List Talente = new List(); //ist of talent objects (talents and spells) - public List Kampftalente = new List(); //list of combat objects - public List Vorteile = new List(); - - public Dictionary Proptable = new Dictionary(); //KK -> Körperkraft - - - public Character(String path) - { - Load(path); //load - Proptable.Add("MU", "Mut"); //routing - Proptable.Add("KL", "Klugheit"); - Proptable.Add("IN", "Intuition"); - Proptable.Add("CH", "Charisma"); - Proptable.Add("FF", "Fingerfertigkeit"); - Proptable.Add("GE", "Gewandtheit"); - Proptable.Add("KO", "Konstitution"); - Proptable.Add("KK", "Körperkraft"); - } - - public Character(Character c, string name, int stDv = 2) - { - Proptable.Add("MU", "Mut"); //routing - Proptable.Add("KL", "Klugheit"); - Proptable.Add("IN", "Intuition"); - Proptable.Add("CH", "Charisma"); - Proptable.Add("FF", "Fingerfertigkeit"); - Proptable.Add("GE", "Gewandtheit"); - Proptable.Add("KO", "Konstitution"); - Proptable.Add("KK", "Körperkraft"); - this.Proptable.Add("**", "Klugheit"); - - this.Name = name; - foreach (var i in c.Eigenschaften) - { - this.Eigenschaften.Add(i.Key, i.Value + (int)Math.Round(Misc.Random(stDv))); - } - - foreach (var i in c.Vorteile) - { - this.Vorteile.Add(new Vorteil(i.name, i.value + (int)Math.Round(Misc.Random(stDv)))); - } - - foreach (var i in c.Talente) - { - this.Talente.Add(new Talent(i.name, i.probe, i.value + (int)Math.Round(Misc.Random(stDv)))); - } - - foreach (var i in c.Kampftalente) - { - this.Kampftalente.Add(new Kampf(i.name, i.at + (int)Math.Round(Misc.Random(stDv)), i.pa + (int)Math.Round(Misc.Random(stDv)))); - } - } - - private void Load(string path) - { - XmlTextReader reader = new XmlTextReader(path); - while (reader.Read()) //read until he hits keywords - { - if (reader.NodeType == XmlNodeType.Element) - { - - switch (reader.Name) - { - case "Wesen": - reader.Skip(); - break; - case "held": - Name = reader.GetAttribute("name"); //name - break; - case "eigenschaft": - Eigenschaften.Add( - reader.GetAttribute("name"), - Convert.ToInt32(reader.GetAttribute("value")) - + Convert.ToInt32(reader.GetAttribute("mod"))); - break; - case "vt": - reader.Read(); - while (reader.Name.Equals("vorteil")) - { - try - { - this.Vorteile.Add(new Vorteil( - reader.GetAttribute("name"), - Convert.ToInt32(reader.GetAttribute("value")))); - } - catch - { - this.Vorteile.Add(new Vorteil(reader.GetAttribute("name"))); - } - reader.Read(); - } - - break; - case "talentliste": - reader.Read(); - while (reader.Name.Equals("talent")) - { - Talente.Add( - new Talent( - reader.GetAttribute("name"), - reader.GetAttribute("probe").Remove(0, 2).Trim(')'), - Convert.ToInt32(reader.GetAttribute("value")))); - reader.Read(); - } - break; - case "zauberliste": - reader.Read(); - while (reader.Name.Equals("zauber")) - { - Talente.Add( - new Talent( - reader.GetAttribute("name"), - reader.GetAttribute("probe").Remove(0, 2).Trim(')'), - Convert.ToInt32(reader.GetAttribute("value")))); - reader.Read(); - } - break; - case "kampfwerte": - string atname = reader.GetAttribute("name"); - reader.Read(); - int at = Convert.ToInt32(reader.GetAttribute("value")); - reader.Read(); - int pa = Convert.ToInt32(reader.GetAttribute("value")); - Kampftalente.Add(new Kampf(atname, at, pa)); - break; - } - } - } - - - } - - public string TestTalent(string talent, int erschwernis = 0) //Talentprobe - { - try - { - var output = new StringBuilder(); - var sc = new SpellCorrect(); - var ttalent = Talente.OrderBy(x => sc.Compare(talent, x.name)).First(); - - var deug = Talente.OrderBy(x => sc.Compare(talent, x.name)); - var fit = deug.Select(x => sc.Compare(talent, x.name)); - - if (sc.Compare(talent, ttalent.name) > 94100) throw new Exception(); - - var props = ttalent.Test(); //get the required properties - int tap = ttalent.value; //get tap - var werte = props.Select(p => this.Eigenschaften[this.Proptable[p]]).ToList(); - - output.AppendFormat( - "{0} würfelt: {1} \n{2} - {3} taw:{4} {5} \n", - this.Name, - ttalent.name, - ttalent.probe, - String.Join("/", werte), - ttalent.value, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - - output.Append(" "); - tap -= erschwernis; - int gesamt_erschwernis = tap; - if (gesamt_erschwernis < 0) - { - tap = 0; - for (int i = 0; i <= 2; i++) //foreach property, dice and tap - { - int temp = dice.Roll(); - int eigenschaft = Eigenschaften[Proptable[props[i]]]; - - if (eigenschaft - gesamt_erschwernis < temp) - { - tap -= temp - eigenschaft + gesamt_erschwernis; - } - - output.Append($"[{temp}]"); //add to string - } - - if (tap >= 0) - { - tap = 1; - } - } - else - { - for (int i = 0; i <= 2; i++) //foreach property, dice and tap - { - int temp = dice.Roll(); - int eigenschaft = Eigenschaften[Proptable[props[i]]]; - - if (eigenschaft < temp) - { - tap -= temp - eigenschaft; - } - output.Append($"[{temp}]"); //add to string - } - } - - tap = tap == 0 ? 1 : tap; - - output.AppendFormat(" tap: {0,2}", tap); - - return output.ToString(); //return output - } - catch (Exception) - { - throw new Exception( - $"{talent} nicht vorhanden! Besitzt {Name} {talent} nicht? \n Oder ist {talent} falsch geschrieben?"); - } - } - - public string TestEigenschaft(string eigenschaft, int erschwernis = 0) - { - var output = new StringBuilder(); - var prop = this.Proptable[eigenschaft.ToUpper()]; - int tap = this.Eigenschaften[prop]; - output.AppendFormat( - "{0}-Eigenschaftsprobe ew:{1} {2} \n", - prop, - tap, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - int roll = dice.Roll(); - output.Append($"Gewürfelt: {roll} übrig: {tap - roll - erschwernis}"); - return output.ToString(); - } - - public string Angriff(string talent, int erschwernis = 0) //prety self explanetory - { - var output = new StringBuilder(); - var sc = new SpellCorrect(); - var attack = Kampftalente.OrderBy(x => sc.Compare(talent, x.name)).First(); - if (sc.Compare(talent, attack.name) > 94) - { - return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; - } - - int tap = attack.at; - output.AppendFormat("{0}-Angriff taw:{1} {2} \n", - attack.name, - tap, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - - int temp = dice.Roll(); - output.Append(temp - erschwernis); - return output.ToString(); - } - public string Parade(string talent, int erschwernis = 0) - { - var output = new StringBuilder(); - var sc = new SpellCorrect(); - var attack = Kampftalente.OrderBy(x => sc.Compare(talent, x.name)).First(); - - if (sc.Compare(talent, attack.name) > 94) - { - return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; - } - - int tap = attack.pa; - output.AppendFormat( - "{0}-Parade taw:{1} {2}\n", - attack.name, - tap, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - - int temp = dice.Roll(); - output.Append(temp - erschwernis); - return output.ToString(); - } - - public string Fernkampf(string talent, int erschwernis = 0) - { - var output = new StringBuilder(); - var sc = new SpellCorrect(); - int fk = Eigenschaften["fk"]; - var attack = Talente.OrderBy(x => sc.Compare(talent, x.name)).First(); - if(sc.Compare(talent, attack.name) > 94) - { - return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; - } - - int tap = attack.value; - output.AppendFormat( - "{0} taw:{1} {2} \n", - attack.name, - tap, - erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); - tap -= erschwernis; - int temp = dice.Roll(); - tap -= temp > fk ? temp - fk : 0; - output.Append($"W20: {temp} tap: {tap}"); - return output.ToString(); - } - - } - -} diff --git a/DiscoBot/Characters/Character.cs b/DiscoBot/Characters/Character.cs new file mode 100644 index 0000000..a78e613 --- /dev/null +++ b/DiscoBot/Characters/Character.cs @@ -0,0 +1,312 @@ +namespace DiscoBot.Characters +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Xml; + + using DiscoBot.Auxiliary; + + public class Character : ICharacter + { + public Character() + { + this.PropTable.Add("MU", "Mut"); // routing + this.PropTable.Add("KL", "Klugheit"); + this.PropTable.Add("IN", "Intuition"); + this.PropTable.Add("CH", "Charisma"); + this.PropTable.Add("FF", "Fingerfertigkeit"); + this.PropTable.Add("GE", "Gewandtheit"); + this.PropTable.Add("KO", "Konstitution"); + this.PropTable.Add("KK", "Körperkraft"); + } + + public Character(string path) : this() + { + this.Load(path); // load + } + + public Character(Character c, string name, int stDv = 2) : this() + { + this.Name = name; + foreach (var i in c.Eigenschaften) + { + this.Eigenschaften.Add(i.Key, i.Value + (int)Math.Round(Misc.Random(stDv))); + } + + foreach (var i in c.Vorteile) + { + this.Vorteile.Add(new Vorteil(i.Name, i.Value + (int)Math.Round(Misc.Random(stDv)))); + } + + foreach (var i in c.Talente) + { + this.Talente.Add(new Talent(i.Name, i.Probe, i.Value + (int)Math.Round(Misc.Random(stDv)))); + } + + foreach (var i in c.Kampftalente) + { + this.Kampftalente.Add(new KampfTalent(i.Name, i.At + (int)Math.Round(Misc.Random(stDv)), i.Pa + (int)Math.Round(Misc.Random(stDv)))); + } + } + + public string Name { get; set; } // char name + + public Dictionary Eigenschaften { get; set; } = new Dictionary(); // char properties + + public List Talente { get; set; } = new List(); // list of talent objects (talents and spells) + + public List Kampftalente { get; set; } = new List(); // list of combat objects + + public List Vorteile { get; set; } = new List(); + + public Dictionary PropTable { get; set; } = new Dictionary(); // -> Körperkraft + + public string TestTalent(string talent, int erschwernis = 0) // Talentprobe + { + try + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + var tTalent = this.Talente.OrderBy(x => sc.Compare(talent, x.Name)).First(); + + if (sc.Compare(talent, tTalent.Name) > 94100) + { + return $"{this.Name} kann nicht {talent}..."; + } + + var props = tTalent.Test(); // get the required properties + int tap = tTalent.Value; // get tap + var werte = props.Select(p => this.Eigenschaften[this.PropTable[p]]).ToList(); + + output.AppendFormat( + "{0} würfelt: {1} \n{2} - {3} taw:{4} {5} \n", + this.Name, + tTalent.Name, + tTalent.Probe, + string.Join("/", werte), + tTalent.Value, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + + output.Append(" "); + tap -= erschwernis; + int gesamtErschwernis = tap; + if (gesamtErschwernis < 0) + { + tap = 0; + for (int i = 0; i <= 2; i++) + { + // foreach property, dice and tap + int temp = Dice.Roll(); + int eigenschaft = this.Eigenschaften[this.PropTable[props[i]]]; + + if (eigenschaft - gesamtErschwernis < temp) + { + tap -= temp - eigenschaft + gesamtErschwernis; + } + + output.Append($"[{temp}]"); // add to string + } + + if (tap >= 0) + { + tap = 1; + } + } + else + { + for (int i = 0; i <= 2; i++) + { + // foreach property, dice and tap + int temp = Dice.Roll(); + int eigenschaft = this.Eigenschaften[this.PropTable[props[i]]]; + + if (eigenschaft < temp) + { + tap -= temp - eigenschaft; + } + + output.Append($"[{temp}]"); // add to string + } + } + + tap = tap == 0 ? 1 : tap; + + output.AppendFormat(" tap: {0,2}", tap); + + return output.ToString(); // return output + } + catch (Exception) + { + throw new Exception( + $"{talent} nicht vorhanden! Besitzt {this.Name} {talent} nicht? \n Oder ist {talent} falsch geschrieben?"); + } + } + + public string TestEigenschaft(string eigenschaft, int erschwernis = 0) + { + var output = new StringBuilder(); + var prop = this.PropTable[eigenschaft.ToUpper()]; + int tap = this.Eigenschaften[prop]; + output.AppendFormat( + "{0}-Eigenschaftsprobe ew:{1} {2} \n", + prop, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + int roll = Dice.Roll(); + output.Append($"Gewürfelt: {roll} übrig: {tap - roll - erschwernis}"); + return output.ToString(); + } + + public string Angriff(string talent, int erschwernis = 0) // pretty self explanatory + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + var attack = this.Kampftalente.OrderBy(x => sc.Compare(talent, x.Name)).First(); + if (sc.Compare(talent, attack.Name) > 94) + { + return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; + } + + int tap = attack.At; + output.AppendFormat( + "{0}-Angriff taw:{1} {2} \n", + attack.Name, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + + int temp = Dice.Roll(); + output.Append(temp - erschwernis); + return output.ToString(); + } + + public string Parade(string talent, int erschwernis = 0) + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + var attack = this.Kampftalente.OrderBy(x => sc.Compare(talent, x.Name)).First(); + + if (sc.Compare(talent, attack.Name) > 94) + { + return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; + } + + int tap = attack.Pa; + output.AppendFormat( + "{0}-Parade taw:{1} {2}\n", + attack.Name, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + + int temp = Dice.Roll(); + output.Append(temp - erschwernis); + return output.ToString(); + } + + public string Fernkampf(string talent, int erschwernis = 0) + { + var output = new StringBuilder(); + var sc = new SpellCorrect(); + int fk = this.Eigenschaften["fk"]; + var attack = this.Talente.OrderBy(x => sc.Compare(talent, x.Name)).First(); + if (sc.Compare(talent, attack.Name) > 94) + { + return $"{this.Name} kann nicht mit der Waffenart {talent} umgehen..."; + } + + int tap = attack.Value; + output.AppendFormat( + "{0} taw:{1} {2} \n", + attack.Name, + tap, + erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis); + tap -= erschwernis; + int temp = Dice.Roll(); + tap -= temp > fk ? temp - fk : 0; + output.Append($"W20: {temp} tap: {tap}"); + return output.ToString(); + } + + private void Load(string path) + { + var reader = new XmlTextReader(path); + while (reader.Read()) + { + // read until he hits keywords + if (reader.NodeType != XmlNodeType.Element) + { + continue; + } + + switch (reader.Name) + { + case "Wesen": + reader.Skip(); + break; + case "held": + this.Name = reader.GetAttribute("name"); // name + break; + case "eigenschaft": + this.Eigenschaften.Add( + reader.GetAttribute("name") ?? throw new InvalidOperationException(), + Convert.ToInt32(reader.GetAttribute("value")) + Convert.ToInt32(reader.GetAttribute("mod"))); + break; + case "vt": + reader.Read(); + while (reader.Name.Equals("vorteil")) + { + try + { + this.Vorteile.Add(new Vorteil( + reader.GetAttribute("name"), + Convert.ToInt32(reader.GetAttribute("value")))); + } + catch + { + this.Vorteile.Add(new Vorteil(reader.GetAttribute("name"))); + } + + reader.Read(); + } + + break; + case "talentliste": + reader.Read(); + while (reader.Name.Equals("talent")) + { + this.Talente.Add( + new Talent( + reader.GetAttribute("name"), + reader.GetAttribute("probe")?.Remove(0, 2).Trim(')'), + Convert.ToInt32(reader.GetAttribute("value")))); + reader.Read(); + } + + break; + case "zauberliste": + reader.Read(); + while (reader.Name.Equals("zauber")) + { + this.Talente.Add( + new Talent( + reader.GetAttribute("name"), + reader.GetAttribute("probe")?.Remove(0, 2).Trim(')'), + Convert.ToInt32(reader.GetAttribute("value")))); + reader.Read(); + } + + break; + case "kampfwerte": + string atName = reader.GetAttribute("name"); + reader.Read(); + int at = Convert.ToInt32(reader.GetAttribute("value")); + reader.Read(); + int pa = Convert.ToInt32(reader.GetAttribute("value")); + this.Kampftalente.Add(new KampfTalent(atName, at, pa)); + break; + } + } + } + } +} diff --git a/DiscoBot/Characters/ICharacter.cs b/DiscoBot/Characters/ICharacter.cs new file mode 100644 index 0000000..135243a --- /dev/null +++ b/DiscoBot/Characters/ICharacter.cs @@ -0,0 +1,17 @@ +namespace DiscoBot.Characters +{ + public interface ICharacter + { + string Name { get; set; } + + string TestTalent(string talent, int erschwernis = 0); + + string TestEigenschaft(string eigenschaft, int erschwernis = 0); + + string Angriff(string talent, int erschwernis = 0); + + string Parade(string talent, int erschwernis = 0); + + string Fernkampf(string talent, int erschwernis = 0); + } +} diff --git a/DiscoBot/Characters/NPC.cs b/DiscoBot/Characters/NPC.cs new file mode 100644 index 0000000..470d5ff --- /dev/null +++ b/DiscoBot/Characters/NPC.cs @@ -0,0 +1,106 @@ +namespace DiscoBot.Characters +{ + using System; + + using DiscoBot.Auxiliary; + + public class Npc : ICharacter + { + private readonly int mean, stDv; + + public Npc(string name, int mean, int stDv) + { + this.mean = mean; + this.stDv = stDv; + this.Name = name; + } + + public string Name { get; set; } + + public string TestTalent(string talent, int tap = 3) + { + for (int i = 0; i <= 2; i++) + { + // foreach property, dice and tap + int temp = Dice.Roll(); + int eigenschaft = (int)Math.Round(Misc.Random(this.stDv, this.mean)); + + if (eigenschaft < temp) + { + tap -= temp - eigenschaft; + } + } + + if (tap >= 0) + { + return $"{this.Name} vollführt {talent} erfolgreich"; + } + + return $"{this.Name} scheitert an {talent}"; + } + + public string TestEigenschaft(string eigenschaft, int erschwernis = 0) + { + int temp = Dice.Roll(); + int prop = (int)Math.Round(Misc.Random(this.stDv, this.stDv)); + + if (temp + erschwernis < prop) + { + return $"{this.Name} vollführt {eigenschaft} erfolgreich"; + } + + return $"{this.Name} scheitert an {eigenschaft}"; + } + + public string Angriff(string waffe, int erschwernis = 0) + { + int temp = Dice.Roll(); + + if (temp == 1) + { + return $"{this.Name} greift kritisch mit {waffe} an"; + } + + if (temp < erschwernis) + { + return $"{this.Name} greift mit {waffe} an"; + } + + return $"{this.Name} haut mit {waffe} daneben"; + } + + public string Parade(string waffe, int erschwernis = 0) + { + int temp = Dice.Roll(); + + if (temp == 1) + { + return $"{this.Name} pariert mit {waffe} meisterlich"; + } + + if (temp < erschwernis) + { + return $"{this.Name} pariert mit {waffe} an"; + } + + return $"{this.Name} schafft es nicht mit {waffe} zu parieren"; + } + + public string Fernkampf(string waffe, int erschwernis = 0) + { + int temp = Dice.Roll(); + + if (temp == 1) + { + return $"{this.Name} trifft kritisch mit {waffe}"; + } + + if (temp < erschwernis) + { + return $"{this.Name} greift mit {waffe} an"; + } + + return $"{this.Name} schießt mit {waffe} daneben"; + } + } +} diff --git a/DiscoBot/CommandExtension.cs b/DiscoBot/CommandExtension.cs deleted file mode 100644 index 06eec92..0000000 --- a/DiscoBot/CommandExtension.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - using System.ComponentModel; - using System.Threading; - using Discord; - using Discord.Commands; - - public static class CommandExtension - { - public static async Task ReplyTimed(this ModuleBase m, string message, TimeSpan time) - { - var token = message.GetHashCode(); - var send = m.Context.Channel.SendMessageAsync($"#{token}\n```xl\n{message}```", true); - - BackgroundWorker barInvoker = new BackgroundWorker(); - barInvoker.DoWork += delegate - { - Thread.Sleep(time); - delete(token, m); - }; - - await send; - barInvoker.RunWorkerAsync(); - } - - private static async void delete(int token, ModuleBase m) - { - var messagesAsync = m.Context.Channel.GetMessagesAsync(100); - Task.WaitAll(messagesAsync.ToArray()); - var list = messagesAsync.ToEnumerable().ToList(); - var messages = new List(); - foreach (var task in list) - { - messages.AddRange(task.ToList()); - } - - await m.Context.Channel.DeleteMessagesAsync(messages.Where(x => x.Content.StartsWith($"#{token}\n") && x.Author.IsBot)); - } - } - -} diff --git a/DiscoBot/Commands.cs b/DiscoBot/Commands.cs deleted file mode 100644 index 6ba2b8a..0000000 --- a/DiscoBot/Commands.cs +++ /dev/null @@ -1,449 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Discord; -using Discord.Commands; -using Discord.WebSocket; - - -namespace DiscoBot -{ - using System.ComponentModel; - using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; - using System.Threading; - - using Discord.Audio; - - public class Info : ModuleBase - { - [Command("say"), Summary("Echos a message.")] - [Alias("s")] - public async Task Say([Remainder, Summary("The text to echo")] string echo) - { - var a = Context.User.Username; - - await ReplyAsync(echo); - } - } - - public class Roll : ModuleBase - { - [Command("r"), Summary("Würfelt ")] - [Alias("R", "Roll", "roll", "Würfle")] - public async Task Say([Remainder, Summary("Weapon")] string roll) - { - await ReplyAsync("```xl\n" + Misc.Roll(roll) + "\n```"); - } - } - - public class SetGeneral : ModuleBase - { - [Command("general"), Summary("Set General ")] - public async Task Say([Remainder, Summary("Set General")] int i = 0) - { - DSA.GeneralContext = this.Context; - await this.Context.Channel.SendMessageAsync($"```xl\n Der Dachs hat in '{this.Context.Channel.Name}' ein Zuhause gefunden. Gm Nachrichten werden nun auch in diesem Channel gepostet. \n```"); - } - } - - [SuppressMessage("ReSharper", "PublicMembersMustHaveComments", Justification = "OK")] - public class TestTalent : ModuleBase - { - [Command("t"), Summary("Würfelt ein Talent-/Zauberprobe")] - [Alias("T", "Talent", "talent", "zauber", "z", "versuche")] - public async Task Say([Summary("Talent oder Zaubername")] string talent, int erschwernis = 0) - { - string res = Gm.CheckCommand(DSA.relation[Context.User.Username], Commands.Talent, talent, erschwernis); - await this.ReplyAsync("```xl\n" + res + "\n```"); - - var tmessages = this.Context.Channel.GetMessagesAsync(10); - Task.WaitAll(tmessages.ToArray()); - var list = tmessages.ToEnumerable().ToList(); - var messages = new List(); - foreach (var task in list) - { - messages.AddRange(task.ToList()); - } - - //await this.Context.Channel.DeleteMessagesAsync(messages.Where(x => x.Content[0].Equals('!') && (x.Author as SocketGuildUser).Roles.ToList().Exists(v => v.Name.Equals("Meister")))); - } - } - - public class TestEigenschaft : ModuleBase - { - [Command("e"), Summary("Würfelt eine Eifenschaftsprobe")] - [Alias("E", "Eigenschaft", "eigenschaft", "eigen")] - public async Task Say([Summary("Eigenschafts kürzel und Erschwernis")] string talent, int erschwernis = 0) - { - var chr = DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])); - string res = chr.TestEigenschaft(talent, erschwernis); - await this.ReplyAsync("```xl\n" + res + "\n```"); - - } - } - - public class Angriff : ModuleBase - { - [Command("a"), Summary("Würfelt ein Angriff")] - [Alias("At", "at", "Angriff", "angriff", "attackiere_mit", "attacke", "Attacke")] - public async Task Say([Summary("Weapon")] string weapon, int erschwernis = 0) - { - await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])).Angriff(weapon, erschwernis) + "\n```"); - - } - } - public class Parade : ModuleBase - { - // ~say hello -> hello - [Command("p"), Summary("Würfelt eine Parade Probe")] - [Alias("P", "Parade", "parade", "pariere_mit")] - public async Task Say([Summary("Parade Weapon")] string talent, int erschwernis = 0) - { - await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])).Parade(talent, erschwernis) + "\n```"); - - } - } - public class Fernkampf : ModuleBase - { - // ~say hello -> hello - [Command("f"), Summary("Führt eine Fernkampfprobe aus")] - [Alias("F", "fernkampf", "Fernkampf", "schieße", "schieße_mit")] - public async Task Say([Summary("Fernkampfwaffe")] string waffe, int erschwernis = 0) - { - // ReplyAsync is a method on ModuleBase - await ReplyAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(DSA.relation[Context.User.Username])).Fernkampf(waffe, erschwernis) + "\n```"); - } - public async Task Say([Summary("Fernkampfwaffe")] string charName, string waffe, ICommandContext context, int erschwernis = 0) - { - // ReplyAsync is a method on ModuleBase - await context.Channel.SendMessageAsync("Hello World\n"); - await context.Channel.SendMessageAsync("```xl\n" + DSA.chars.Find(x => x.Name.Equals(charName)).Fernkampf(waffe, erschwernis) + "\n```"); - } - } - - public class Voice : ModuleBase - { - public static IAudioClient client { get; set; } - [Command("join", RunMode = RunMode.Async)] - public async Task JoinChannel(IVoiceChannel channel = null) - { - var msg = this.Context.Message; - // Get the audio channel - channel = channel ?? (msg.Author as IGuildUser)?.VoiceChannel; - if (channel == null) { await msg.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument."); return; } - - // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. - var audioClient = await channel.ConnectAsync(); - client = audioClient; - } - - [Command("leave", RunMode = RunMode.Async)] - public async Task LeaveChannel(IVoiceChannel channel = null) - { - // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. - client.StopAsync(); - } - - [Command("play")] - public async Task PlayAudio(string path) - { - SendAsync(client, path); - } - - private Process CreateStream(string path) - { - var ffmpeg = new ProcessStartInfo - { - FileName = "ffmpeg", - Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 -ab 620000 pipe:1", - UseShellExecute = false, - RedirectStandardOutput = true, - }; - return Process.Start(ffmpeg); - } - - private async Task SendAsync(IAudioClient client, string path) - { - // Create FFmpeg using the previous example - var ffmpeg = CreateStream(path); - var output = ffmpeg.StandardOutput.BaseStream; - var discord = client.CreatePCMStream(AudioApplication.Music); - await output.CopyToAsync(discord); - await discord.FlushAsync(); - } - } - - - [Group("gmtr")] - public class Sample : ModuleBase - { - // ~sample square 20 -> 400 - [Command("square"), Summary("Squares a number.")] - public async Task Square([Summary("The number to square.")] int num) - { - // We can also access the channel from the Command Context. - await Context.Channel.SendMessageAsync($"{num}^2 = {Math.Pow(num, 2)}"); - } - - [Command("userinfo"), Summary("Returns info about the current user, or the user parameter, if one passed.")] - [Alias("user", "whois")] - public async Task UserInfo([Summary("The (optional) user to get info for")] IUser user = null) - { - var userInfo = user ?? Context.Client.CurrentUser; - await ReplyAsync($"{userInfo.Username}#{userInfo.Discriminator}"); - } - } - - public class List : ModuleBase - { - // ~say hello -> hello - [Command("list"), Summary("gibt eine Auflistung aus")] - public async Task Say([Summary("Aktion")] string prop) - { - var res = new List(); - switch (prop.ToLower()) - { - case "chars": - case "Chars": - res.AddRange(DSA.chars.Select(x => x.Name)); - break; - case "t": - case "ta": - case "talent": - case "zauber": - res.AddRange( - ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) - .Talente.Select(s => s.name + "\t " + s.value + "\t " + s.probe)); - break; - case "w": - case "waffe": - case "waffen": - res.AddRange( - ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) - .Kampftalente.Select(s => s.name)); - break; - case "fern": - res.AddRange( - ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) - .Talente.Select(s => s.name)); - break; - case "v": - case "vt": - case "vor": - case "vorteil": - res.AddRange( - ((Character)DSA.chars.Find(x => x.Name.Equals(DSA.relation[this.Context.User.Username]))) - .Vorteile - .Select(s => s.name + "\t " + (s.value == 0 ? "" : s.value.ToString()))); - break; - - default: - res.Add($"Kommando {prop} nicht gefunden"); - break; - } - - //await this.ReplyAsync(res.Aggregate((seed, next) => seed + "\n" + next)); - var sb = new StringBuilder(); - foreach (string re in res) - { - if (sb.Length + re.Length > 1798) - { - await this.ReplyTimed(sb.ToString(), TimeSpan.FromSeconds(90)); - sb.Clear(); - } - - sb.AppendLine(re); - } - - await this.ReplyTimed(sb.ToString(), TimeSpan.FromSeconds(90)); - } - - } - - public class Gm : ModuleBase - { - // ~say hello -> hello - [Command("gm"), Summary("Führt eine probe aus")] - [Alias("GM", "as", "As", "als")] - public async Task Say([Summary("Fernkampfwaffe")] string name, string command, string waffe, int erschwernis = 0) - { - if (!(this.Context.User as SocketGuildUser).Roles.ToList().Exists(v => v.Name.Equals("Meister"))) - { - await ReplyAsync("```xl\n Keine ausreichenden Berechtigunen\n```"); - return; - } - - command = command.ToLower(); - string res; - switch (command) - { - case "f": - case "fern": - case "fernkampf": - res = CheckCommand(name, Commands.Fernkampf, waffe, erschwernis); - break; - case "t": - case "ta": - case "talent": - res = CheckCommand(name, Commands.Talent, waffe, erschwernis); - break; - case "e": - case "ei": - case "eigenschaft": - res = CheckCommand(name, Commands.Eigenschaft, waffe, erschwernis); - break; - case "z": - case "za": - case "zauber": - case "magie": - case "m": - res = CheckCommand(name, Commands.Talent, waffe, erschwernis); - break; - case "a": - case "at": - case "an": - case "angrif": - case "angriff": - res = CheckCommand(name, Commands.Angriff, waffe, erschwernis); - break; - case "p": - case "pa": - case "parade": - res = CheckCommand(name, Commands.Parade, waffe, erschwernis); - break; - case "talente": - throw new NotImplementedException(); - default: - res = $"Kommando {command} nicht gefunden"; - break; - } - - if (DSA.GeneralContext != null) - { - if (DSA.GeneralContext.Channel.Id != Context.Channel.Id) - { - await DSA.GeneralContext.Channel.SendMessageAsync("```xl\n" + res + "\n```"); - } - - await ReplyAsync("```xl\n" + res + "\n```"); - } - else - { - await ReplyAsync("```xl\n" + res + "\n```"); - } - } - - public static string CheckCommand(string name, Commands command, string waffe, int erschwernis = 0) - { - var comp = new SpellCorrect(); - var chr = DSA.chars.OrderBy(x => comp.Compare(x.Name, name)).First(); - switch (command) - { - case Commands.Talent: - return chr.TestTalent(waffe, erschwernis); - case Commands.Eigenschaft: - return chr.TestEigenschaft(waffe, erschwernis); - case Commands.Angriff: - return chr.Angriff(waffe, erschwernis); - case Commands.Parade: - return chr.Parade(waffe, erschwernis); - case Commands.Fernkampf: - return chr.Fernkampf(waffe, erschwernis); - } - - return $"{name} verwendet {waffe}"; - } - } - - public class GenerateNpc : ModuleBase - { - // ~say hello -> hello - [Command("npc"), Summary("Erstellt ein NPC")] - [Alias("Npc", "NPc", "NPC", "nPC")] - public async Task Say([Summary("Create Random")] string npcName, int mean = 9, int stDv = 1) - { - DSA.chars.Add(new NPC(npcName, mean, stDv)); - await this.ReplyAsync($"{npcName} wurde zufällig generiert"); - } - } - - public class CopyNpc : ModuleBase - { - // ~say hello -> hello - [Command("npc"), Summary("Erstellt ein NPC")] - [Alias("Npc", "NPc", "NPC", "nPC")] - public async Task Say([Summary("Create Copy")] string npcName, string source, int stDv = 1) - { - if (DSA.chars.Exists(x => x.Name.Equals(npcName))) - { - throw new Exception("Char gibt es schon"); - } - - var comp = new SpellCorrect(); - var chr = DSA.chars.OrderBy(x => comp.Compare(x.Name, source)).First(); - DSA.chars.Add(new Character(chr as Character, npcName, stDv)); - await ReplyAsync($"{npcName} wurde als variierte Kopie von {source} erstellt"); - } - } - - public class NpcAction : ModuleBase - { - // ~say hello -> hello - [Command("npc"), Summary("Führt eine NPC-Probe aus")] - [Alias("Npc", "NPc", "NPC", "nPC")] - public async Task Say([Summary("Aktion")] string NpcName, string command, string Aktion, int erschwernis = 0) - { - string test = ""; - } - } - - /*public class AudioModule : ModuleBase - { - // Scroll down further for the AudioService. - // Like, way down - private readonly AudioService _service; - - // Remember to add an instance of the AudioService - // to your IServiceCollection when you initialize your bot - public AudioModule(AudioService service) - { - _service = service; - } - - // You *MUST* mark these commands with 'RunMode.Async' - // otherwise the bot will not respond until the Task times out. - [Command("join", RunMode = RunMode.Async)] - public async Task JoinCmd() - { - await _service.JoinAudio(Context.Guild, (Context.User as IVoiceState).VoiceChannel); - } - - // Remember to add preconditions to your commands, - // this is merely the minimal amount necessary. - // Adding more commands of your own is also encouraged. - [Command("leave", RunMode = RunMode.Async)] - public async Task LeaveCmd() - { - await _service.LeaveAudio(Context.Guild); - } - - [Command("play", RunMode = RunMode.Async)] - public async Task PlayCmd([Remainder] string song) - { - await _service.SendAudioAsync(Context.Guild, Context.Channel, song); - } - }*/ - - public enum Commands - { - Talent, - Eigenschaft, - Angriff, - Parade, - Fernkampf, - KeinChar - } -} diff --git a/DiscoBot/Commands/CommandTypes.cs b/DiscoBot/Commands/CommandTypes.cs new file mode 100644 index 0000000..4ff0814 --- /dev/null +++ b/DiscoBot/Commands/CommandTypes.cs @@ -0,0 +1,12 @@ +namespace DiscoBot.Commands +{ + public enum CommandTypes + { + Talent, + Eigenschaft, + Angriff, + Parade, + Fernkampf, + KeinChar + } +} diff --git a/DiscoBot/Commands/Gm.cs b/DiscoBot/Commands/Gm.cs new file mode 100644 index 0000000..60b82fb --- /dev/null +++ b/DiscoBot/Commands/Gm.cs @@ -0,0 +1,103 @@ +namespace DiscoBot.Commands +{ + using System.Linq; + using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + + using Discord.Commands; + using Discord.WebSocket; + + public class Gm : ModuleBase + { + public static string CheckCommand(string name, CommandTypes command, string waffe, int erschwernis = 0) + { + var comp = new SpellCorrect(); + var chr = Dsa.Chars.OrderBy(x => comp.Compare(x.Name, name)).First(); + switch (command) + { + case CommandTypes.Talent: + return chr.TestTalent(waffe, erschwernis); + case CommandTypes.Eigenschaft: + return chr.TestEigenschaft(waffe, erschwernis); + case CommandTypes.Angriff: + return chr.Angriff(waffe, erschwernis); + case CommandTypes.Parade: + return chr.Parade(waffe, erschwernis); + case CommandTypes.Fernkampf: + return chr.Fernkampf(waffe, erschwernis); + } + + return $"{name} verwendet {waffe}"; + } + + [Command("gm"), Summary("Führt eine probe aus")] + [Alias("GM", "as", "As", "als")] + public async Task ProbeAsync([Summary("Fernkampfwaffe")] string name, string command, string waffe, int erschwernis = 0) + { + if (!((SocketGuildUser)this.Context.User).Roles.ToList().Exists(v => v.Name.Equals("Meister"))) + { + await this.ReplyAsync("```xl\n Keine ausreichenden Berechtigunen\n```"); + return; + } + + command = command.ToLower(); + string res = this.Test(name, command, waffe, erschwernis); + + if (Dsa.GeneralContext != null && Dsa.GeneralContext.Channel.Id != this.Context.Channel.Id) + { + await Dsa.GeneralContext.Channel.SendMessageAsync("```xl\n" + res + "\n```"); + } + + await this.ReplyAsync("```xl\n" + res + "\n```"); + } + + private string Test(string name, string command, string waffe, int erschwernis = 0) + { + string res; + switch (command) + { + case "f": + case "fern": + case "fernkampf": + res = CheckCommand(name, CommandTypes.Fernkampf, waffe, erschwernis); + break; + case "t": + case "ta": + case "talent": + case "talente": + res = CheckCommand(name, CommandTypes.Talent, waffe, erschwernis); + break; + case "e": + case "ei": + case "eigenschaft": + res = CheckCommand(name, CommandTypes.Eigenschaft, waffe, erschwernis); + break; + case "z": + case "za": + case "zauber": + case "magie": + case "m": + res = CheckCommand(name, CommandTypes.Talent, waffe, erschwernis); + break; + case "a": + case "at": + case "an": + case "angrif": + case "angriff": + res = CheckCommand(name, CommandTypes.Angriff, waffe, erschwernis); + break; + case "p": + case "pa": + case "parade": + res = CheckCommand(name, CommandTypes.Parade, waffe, erschwernis); + break; + default: + res = $"Kommando {command} nicht gefunden"; + break; + } + + return res; + } + } +} diff --git a/DiscoBot/Commands/List.cs b/DiscoBot/Commands/List.cs new file mode 100644 index 0000000..9eac3a1 --- /dev/null +++ b/DiscoBot/Commands/List.cs @@ -0,0 +1,76 @@ +namespace DiscoBot.Commands +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + using DiscoBot.Characters; + + using Discord.Commands; + + public class List : ModuleBase + { + [Command("list"), Summary("gibt eine Auflistung aus")] + public async Task ListAsync([Summary("Aktion")] string prop) + { + var res = new List(); + switch (prop.ToLower()) + { + case "chars": + case "Chars": + res.AddRange(Dsa.Chars.Select(x => x.Name)); + break; + case "t": + case "ta": + case "talent": + case "zauber": + res.AddRange( + ((Character)Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username]))) + .Talente.Select(s => s.Name + "\t " + s.Value + "\t " + s.Probe)); + break; + case "w": + case "waffe": + case "waffen": + res.AddRange( + ((Character)Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username]))) + .Kampftalente.Select(s => s.Name)); + break; + case "fern": + res.AddRange( + ((Character)Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username]))) + .Talente.Select(s => s.Name)); + break; + case "v": + case "vt": + case "vor": + case "vorteil": + res.AddRange( + ((Character)Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username]))) + .Vorteile + .Select(s => s.Name + "\t " + (s.Value == 0 ? string.Empty : s.Value.ToString()))); + break; + + default: + res.Add($"Kommando {prop} nicht gefunden"); + break; + } + + var sb = new StringBuilder(); + foreach (string re in res) + { + if (sb.Length + re.Length > 1798) + { + await this.ReplyTimedAsync(sb.ToString(), TimeSpan.FromSeconds(90)); + sb.Clear(); + } + + sb.AppendLine(re); + } + + await this.ReplyTimedAsync(sb.ToString(), TimeSpan.FromSeconds(90)); + } + } +} diff --git a/DiscoBot/Commands/NpcCommands.cs b/DiscoBot/Commands/NpcCommands.cs new file mode 100644 index 0000000..f2b17b6 --- /dev/null +++ b/DiscoBot/Commands/NpcCommands.cs @@ -0,0 +1,37 @@ +namespace DiscoBot.Commands +{ + using System; + using System.Linq; + using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + using DiscoBot.Characters; + + using Discord.Commands; + + public class NpcCommands : ModuleBase + { + [Command("npc"), Summary("Erstellt ein NPC")] + [Alias("Npc", "NPc", "NPC", "nPC")] + public Task RandomAsync([Summary("Create Random")] string npcName, int mean = 9, int stDv = 1) + { + Dsa.Chars.Add(new Npc(npcName, mean, stDv)); + return this.ReplyAsync($"{npcName} wurde zufällig generiert"); + } + + [Command("npc"), Summary("Erstellt ein NPC")] + [Alias("Npc", "NPc", "NPC", "nPC")] + public Task CopyAsync([Summary("Create Copy")] string npcName, string source, int stDv = 1) + { + if (Dsa.Chars.Exists(x => x.Name.Equals(npcName))) + { + throw new Exception("Char gibt es schon"); + } + + var comp = new SpellCorrect(); + var chr = Dsa.Chars.OrderBy(x => comp.Compare(x.Name, source)).First(); + Dsa.Chars.Add(new Character(chr as Character, npcName, stDv)); + return this.ReplyAsync($"{npcName} wurde als variierte Kopie von {source} erstellt"); + } + } +} diff --git a/DiscoBot/Commands/Test.cs b/DiscoBot/Commands/Test.cs new file mode 100644 index 0000000..d56a43c --- /dev/null +++ b/DiscoBot/Commands/Test.cs @@ -0,0 +1,47 @@ +namespace DiscoBot.Commands +{ + using System.Threading.Tasks; + + using Discord.Commands; + + public class Test : ModuleBase + { + [Command("t"), Summary("Würfelt ein Talent-/Zauberprobe")] + [Alias("T", "Talent", "talent", "zauber", "z", "versuche")] + public Task TalentAsync([Summary("Talent oder Zaubername")] string talent, int erschwernis = 0) + { + string res = Gm.CheckCommand(Dsa.Relation[this.Context.User.Username], CommandTypes.Talent, talent, erschwernis); + return this.ReplyAsync("```xl\n" + res + "\n```"); + } + + [Command("e"), Summary("Würfelt eine Eigenschaftsprobe")] + [Alias("E", "Eigenschaft", "eigenschaft", "eigen")] + public Task EigenschaftAsync([Summary("Eigenschaftskürzel und Erschwernis")] string talent, int erschwernis = 0) + { + var chr = Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username])); + string res = chr.TestEigenschaft(talent, erschwernis); + return this.ReplyAsync("```xl\n" + res + "\n```"); + } + + [Command("a"), Summary("Würfelt ein Angriff")] + [Alias("At", "at", "Angriff", "angriff", "attackiere_mit", "attacke", "Attacke")] + public Task AngriffAsync([Summary("Weapon")] string weapon, int erschwernis = 0) + { + return this.ReplyAsync("```xl\n" + Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username])).Angriff(weapon, erschwernis) + "\n```"); + } + + [Command("p"), Summary("Würfelt eine Parade Probe")] + [Alias("P", "Parade", "parade", "pariere_mit")] + public Task ParadeAsync([Summary("Parade Weapon")] string talent, int erschwernis = 0) + { + return this.ReplyAsync("```xl\n" + Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username])).Parade(talent, erschwernis) + "\n```"); + } + + [Command("f"), Summary("Führt eine Fernkampfprobe aus")] + [Alias("F", "fernkampf", "Fernkampf", "schieße", "schieße_mit")] + public Task FernkampfAsync([Summary("Fernkampfwaffe")] string waffe, int erschwernis = 0) + { + return this.ReplyAsync("```xl\n" + Dsa.Chars.Find(x => x.Name.Equals(Dsa.Relation[this.Context.User.Username])).Fernkampf(waffe, erschwernis) + "\n```"); + } + } +} diff --git a/DiscoBot/Commands/Utility.cs b/DiscoBot/Commands/Utility.cs new file mode 100644 index 0000000..bbba1a1 --- /dev/null +++ b/DiscoBot/Commands/Utility.cs @@ -0,0 +1,32 @@ +namespace DiscoBot.Commands +{ + using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + + using Discord.Commands; + + public class Utility : ModuleBase + { + [Command("r"), Summary("Würfelt ")] + [Alias("R", "Roll", "roll", "Würfle")] + public Task RollAsync([Remainder, Summary("Weapon")] string roll) + { + return this.ReplyAsync("```xl\n" + Misc.Roll(roll) + "\n```"); + } + + [Command("general"), Summary("Set General ")] + public Task SetGeneralAsync([Remainder, Summary("Set General")] int i = 0) + { + Dsa.GeneralContext = this.Context; + return this.Context.Channel.SendMessageAsync($"```xl\n Der Dachs hat in '{this.Context.Channel.Name}' ein Zuhause gefunden. Gm Nachrichten werden nun auch in diesem Channel gepostet. \n```"); + } + + [Command("say"), Summary("Echos a message.")] + [Alias("s")] + public Task SayAsync([Remainder, Summary("The text to echo")] string echo) + { + return this.ReplyAsync(echo); + } + } +} diff --git a/DiscoBot/Commands/Voice.cs b/DiscoBot/Commands/Voice.cs new file mode 100644 index 0000000..72988d4 --- /dev/null +++ b/DiscoBot/Commands/Voice.cs @@ -0,0 +1,67 @@ +namespace DiscoBot.Commands +{ + using System.Diagnostics; + using System.Threading.Tasks; + + using Discord; + using Discord.Audio; + using Discord.Commands; + + public class Voice : ModuleBase + { + public static IAudioClient Client { get; set; } + [Command("join", RunMode = RunMode.Async)] + public async Task JoinChannelAsync(IVoiceChannel channel = null) + { + var msg = this.Context.Message; + + // Get the audio channel + channel = channel ?? (msg.Author as IGuildUser)?.VoiceChannel; + if (channel == null) + { + await msg.Channel.SendMessageAsync( + "User must be in a voice channel, or a voice channel must be passed as an argument."); + return; + } + + // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. + var audioClient = await channel.ConnectAsync(); + Client = audioClient; + } + + [Command("leave", RunMode = RunMode.Async)] + public Task LeaveChannelAsync(IVoiceChannel channel = null) + { + // For the next step with transmitting audio, you would want to pass this Audio Client in to a service. + return Client.StopAsync(); + } + + [Command("play")] + public Task PlayAudioAsync(string path) + { + return this.SendAsync(Client, path); + } + + private Process CreateStream(string path) + { + var ffmpeg = new ProcessStartInfo + { + FileName = "ffmpeg", + Arguments = $"-i {path} -ac 2 -f s16le -ar 48000 -ab 620000 pipe:1", + UseShellExecute = false, + RedirectStandardOutput = true, + }; + return Process.Start(ffmpeg); + } + + private async Task SendAsync(IAudioClient client, string path) + { + // Create FFmpeg using the previous example + var ffmpeg = this.CreateStream(path); + var output = ffmpeg.StandardOutput.BaseStream; + var discord = client.CreatePCMStream(AudioApplication.Music); + await output.CopyToAsync(discord); + await discord.FlushAsync(); + } + } +} diff --git a/DiscoBot/DSA.cs b/DiscoBot/DSA.cs index af02023..d9cefb2 100644 --- a/DiscoBot/DSA.cs +++ b/DiscoBot/DSA.cs @@ -3,37 +3,43 @@ using System.Collections.Generic; using System.IO; using System.Linq; - using System.Threading.Tasks; + + using DiscoBot.Auxiliary; + using DiscoBot.Characters; using Discord.Commands; - public static class DSA + public static class Dsa { public static ICommandContext GeneralContext { get; set; } - public static Dictionary relation = new Dictionary(); //dictionary to match the char - public static List chars = new List(); //list of all charackters - public static List Talente { get; set; } = new List(); + public static Dictionary Relation { get; set; } = new Dictionary(); // dictionary to match the char + + public static List Chars { get; set; } = new List(); // list of all characters - public static async Task Startup() + public static List Talente { get; set; } = new List(); + + public static void Startup() { - relation.Add("The Doctor", "Numeri Illuminus");//Relation - relation.Add("Tardis", "Morla");//"Numeri Illuminus"); - relation.Add("DSA Bot", "Morla");//"Felis Exodus Schattenwald"); - relation.Add("Morla", "Morla"); - relation.Add("Rhoktar", "Rhoktar4"); - //relation.Add("Papo","Gwendelson"); - relation.Add("Papo", "Pump aus der Gosse"); - relation.Add("Potus", "Potus"); - //relation.Add("Papo", "Pump aus der Gosse"); + Relation.Add("The Doctor", "Numeri Illuminus"); // Relation + Relation.Add("Tardis", "Morla"); // "Numeri Illuminus"); + Relation.Add("DSA Bot", "Morla"); // "Felis Exodus Schattenwald"); + Relation.Add("Morla", "Morla"); + Relation.Add("Rhoktar", "Rhoktar4"); + + // relation.Add("Papo","Gwendelson"); + Relation.Add("Papo", "Pump aus der Gosse"); + Relation.Add("Potus", "Potus"); + + // relation.Add("Papo", "Pump aus der Gosse"); foreach (var filename in Directory.GetFiles("helden", "*.xml")) { - chars.Add(new Character(filename)); - (chars.Last() as Character)?.Talente.Select(x => new Talent(x.name, x.probe, 0)) - .Where(c => !Talente.Exists(v => v.name.Equals(c.name))).ToList().ForEach(v => Talente.Add(v)); + Chars.Add(new Character(filename)); + (Chars.Last() as Character)?.Talente.Select(x => new Talent(x.Name, x.Probe, 0)) + .Where(c => !Talente.Exists(v => v.Name.Equals(c.Name))).ToList().ForEach(v => Talente.Add(v)); } - Talente = Talente.OrderBy(x => x.name).ToList(); + Talente = Talente.OrderBy(x => x.Name).ToList(); } } } \ No newline at end of file diff --git a/DiscoBot/DiscoBot.csproj b/DiscoBot/DiscoBot.csproj index d0fc986..2bf17e5 100644 --- a/DiscoBot/DiscoBot.csproj +++ b/DiscoBot/DiscoBot.csproj @@ -140,15 +140,24 @@ - - - - - + + + + + + + + + + + + + + - - - + + + diff --git a/DiscoBot/ICharacter.cs b/DiscoBot/ICharacter.cs deleted file mode 100644 index fbaabd3..0000000 --- a/DiscoBot/ICharacter.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - public interface ICharacter - { - string Name { get; set; } - - string TestTalent(string talent, int erschwernis = 0); - - string TestEigenschaft(string eigenschaft, int erschwernis = 0); - - string Angriff(string talent, int erschwernis = 0); - - string Parade(string talent, int erschwernis = 0); - - string Fernkampf(string talent, int erschwernis = 0); - } -} diff --git a/DiscoBot/Misc.cs b/DiscoBot/Misc.cs deleted file mode 100644 index 9c9456c..0000000 --- a/DiscoBot/Misc.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - public static class Misc - { - private static readonly Random Rand = new Random(); - - // use: 4w6 +4 - public static string Roll(string input) - { - int count = 1, d ,mod=0; - var Output = new StringBuilder(); - List strings = input.Split('w','d').ToList(); - count = Convert.ToInt32(strings[0]); - strings = strings[1].Split(' ').ToList(); - d = Convert.ToInt32(strings[0]); - - if (strings.Count > 0) - mod = Convert.ToInt32(strings.Last()); - int sum = 0; - for (int i = 0; i < count; i++) - { - var roll = dice.Roll(d); - sum += roll; - Output.Append("["+roll + "] "); - } - if (count > 1) - Output.Append("sum: " + (sum)); - - return Output.ToString(); - } - - public static double Random(double stdDev = 1, double mean = 0) - { - double u1 = Rand.NextDouble(); // uniform(0,1) random doubles - double u2 = Rand.NextDouble(); - double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * - Math.Sin(2.0 * Math.PI * u2); // random normal(0,1) - double randNormal = - mean + stdDev * randStdNormal; // random normal(mean,stdDev^2) - return randNormal; - } - } - - public class SpellCorrect : StringComparer - { - public override int Compare(string x, string y) - { - if (x.Equals(y)) - return 0; - x=x.ToLower(); - y=y.ToLower(); - if (x.Equals(y)) - return 1; - var subs = y.Split(' ', '/'); - int score = subs.Count(); - foreach (string s in subs) - { - if (s.Equals(x)) - { - score--; - } - } - - if (score < subs.Count()) - { - return score + 1; - } - - return 100000 - (int)(compare_exact(x, y) * 1000.0); - /*if (y.Contains(x)) - return 6;*/ - - } - - public override bool Equals(string x, string y) - { - throw new NotImplementedException(); - } - - public override int GetHashCode(string obj) - { - throw new NotImplementedException(); - } - - public double compare_exact(string s, string q) - { - int i, j; - const double Match = 3.0; - const double Gap = -2.0; - const double Mismatch = -2.0; - - double decay = 0.0; - - double[,] matrix = new double[s.Length + 1, q.Length + 1]; - double max = 0.0; - matrix[0, 0] = 0.0; - - for (i = 1; i < s.Length; i++) - { - matrix[i, 0] = 0.0; - } - - for (i = 1; i < q.Length; i++) - { - matrix[0, i] = 0.0; - } - - for (i = 1; i <= s.Length; i++) - { - for (j = 1; j <= q.Length; j++) - { - decay = j / (double)(s.Length * 1000); - double add = s[i - 1] == q[j - 1] ? (Match - decay) : Mismatch; - double score = matrix[i - 1, j - 1] + add; - - if (score < (matrix[i - 1, j] + Gap)) - { - score = matrix[i - 1, j] + Gap; - } - - if (score < (matrix[i, j - 1] + Gap)) - { - score = matrix[i, j - 1] + Gap; - } - - if (i > 1 && j > 1) - { - if (s[i - 1] == q[j - 2] && s[i - 2] == q[j - 1]) - { - add = (3 / 2.0) * Match - decay; - if (score < matrix[i - 2, j - 2] + add) - { - score = matrix[i - 2, j - 2] + add; - } - } - } - - if (score < 0) - { - score = 0; - } - - if (max < score) - { - max = score; - } - - matrix[i, j] = score; - } - } - - return max; - } - } - - public static class dice//roll it! - { - static System.Random rnd = new System.Random(); - public static int Roll(int d=20) - { - return rnd.Next(1, d+1); - } - } - - public class Vorteil //talent objekt - { - public string name; - public int value; - - public Vorteil(string name, int value = 0) - { - this.name = name; - this.value = value; - } - } - - public class Talent //talent objekt - { - public string name, probe; - public int value; - public Talent(string name, string probe, int value) { this.name = name; this.probe = probe; this.value = value; } - public string[] Test() //turn XX/XX/XX into string[]{XX,XX,XX} - { - var temp = probe.Split('/'); - foreach (string s in temp) - s.Replace("/", ""); - return temp; - } - - public int CheckName(string quary) - { - var sc = (StringComparer)new SpellCorrect(); - return sc.Compare(quary, this.name); - } - - } - - public class Kampf - { - public string name; - public int at, pa; - public Kampf(string name, int at, int pa) { this.name = name; this.at = at; this.pa = pa; } - void Test() { } - } - -} diff --git a/DiscoBot/NPC.cs b/DiscoBot/NPC.cs deleted file mode 100644 index 4104947..0000000 --- a/DiscoBot/NPC.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DiscoBot -{ - public class NPC : ICharacter - { - private int mean, stDv; - - public NPC(string name, int mean, int stDv) - { - this.mean = mean; - this.stDv = stDv; - this.Name = name; - } - - public string Name { get; set; } - - public string TestTalent(string talent, int tap = 3) - { - for (int i = 0; i <= 2; i++) //foreach property, dice and tap - { - int temp = dice.Roll(); - int eigenschaft = (int)Math.Round(Misc.Random(this.stDv, this.mean)); - - if (eigenschaft < temp) - { - tap -= temp - eigenschaft; - } - } - - if (tap >= 0) - { - return $"{this.Name} vollführt {talent} erfolgreich"; - } - - return $"{this.Name} scheitert an {talent}"; - } - - public string TestEigenschaft(string eigenschaft, int erschwernis = 0) - { - int temp = dice.Roll(); - int prop = (int)Math.Round(Misc.Random(this.stDv, this.stDv)); - - if (temp + erschwernis < prop) - { - return $"{this.Name} vollführt {eigenschaft} erfolgreich"; - } - - return $"{this.Name} scheitert an {eigenschaft}"; - } - - public string Angriff(string waffe, int erschwernis = 0) - { - int temp = dice.Roll(); - - if (temp == 1) - { - return $"{this.Name} greift kritisch mit {waffe} an"; - } - - if (temp < erschwernis) - { - return $"{this.Name} greift mit {waffe} an"; - } - - return $"{this.Name} haut mit {waffe} daneben"; - } - - public string Parade(string waffe, int erschwernis = 0) - { - int temp = dice.Roll(); - - if (temp == 1) - { - return $"{this.Name} pariert mit {waffe} meisterlich"; - } - - if (temp < erschwernis) - { - return $"{this.Name} pariert mit {waffe} an"; - } - - return $"{this.Name} schafft es nicht mit {waffe} zu parieren"; - } - - public string Fernkampf(string waffe, int erschwernis = 0) - { - int temp = dice.Roll(); - - if (temp == 1) - { - return $"{this.Name} trifft kritisch mit {waffe}"; - } - - if (temp < erschwernis) - { - return $"{this.Name} greift mit {waffe} an"; - } - - return $"{this.Name} schießt mit {waffe} daneben"; - } - } -} diff --git a/DiscoBot/Program.cs b/DiscoBot/Program.cs index 7ae8244..6bf870e 100644 --- a/DiscoBot/Program.cs +++ b/DiscoBot/Program.cs @@ -1,78 +1,87 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Reflection; +using System.Threading.Tasks; + using Discord; -using Discord.WebSocket; using Discord.Commands; -using Microsoft.Extensions.DependencyInjection; +using Discord.WebSocket; +using Microsoft.Extensions.DependencyInjection; namespace DiscoBot { + using DiscoBot.Commands; + public class Program { private CommandService commands; private DiscordSocketClient client; private IServiceProvider services; - + public static void Main(string[] args) => new Program().StartAsync().GetAwaiter().GetResult(); - static void Main(string[] args) => new Program().Start().GetAwaiter().GetResult(); - - public async Task Start() + public async Task StartAsync() { - var loading = DSA.Startup(); - client = new DiscordSocketClient(); - commands = new CommandService(); + Dsa.Startup(); + this.client = new DiscordSocketClient(); + this.commands = new CommandService(); string token = Properties.Settings.Default.Token; - services = new ServiceCollection() + this.services = new ServiceCollection() .BuildServiceProvider(); - AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit); - - await InstallCommands(); + AppDomain.CurrentDomain.ProcessExit += OnProcessExit; - await client.LoginAsync(TokenType.Bot, token); - await client.StartAsync(); + await this.InstallCommandsAsync(); - await loading; + await this.client.LoginAsync(TokenType.Bot, token); + await this.client.StartAsync(); + await Task.Delay(-1); } - public async Task InstallCommands() + public Task InstallCommandsAsync() { // Hook the MessageReceived Event into our Command Handler - client.MessageReceived += HandleCommand; + this.client.MessageReceived += this.HandleCommandAsync; + // Discover all of the commands in this assembly and load them. - await commands.AddModulesAsync(Assembly.GetEntryAssembly()); + return this.commands.AddModulesAsync(Assembly.GetEntryAssembly()); } - public async Task HandleCommand(SocketMessage messageParam) + public async Task HandleCommandAsync(SocketMessage messageParam) { // Don't process the command if it was a System Message - var message = messageParam as SocketUserMessage; - if (message == null) return; + if (!(messageParam is SocketUserMessage message)) + { + return; + } + // Create a number to track where the prefix ends and the command begins int argPos = 0; + // Determine if the message is a command, based on if it starts with '!' or a mention prefix - if (!(message.HasCharPrefix('!', ref argPos) || message.HasMentionPrefix(client.CurrentUser, ref argPos))) return; + if (!(message.HasCharPrefix('!', ref argPos) || message.HasMentionPrefix(this.client.CurrentUser, ref argPos))) + { + return; + } + // Create a Command Context - var context = new CommandContext(client, message); + var context = new CommandContext(this.client, message); + // Execute the command. (result does not indicate a return value, // rather an object stating if the command executed successfully) - var result = await commands.ExecuteAsync(context, argPos, services); + var result = await this.commands.ExecuteAsync(context, argPos, this.services); if (!result.IsSuccess) + { await context.Channel.SendMessageAsync(result.ErrorReason); + } } - static void OnProcessExit(object sender, EventArgs e) + + private static void OnProcessExit(object sender, EventArgs e) { Console.WriteLine("I'm out of here"); - Voice.client.StopAsync(); + Voice.Client.StopAsync(); } } - } -- cgit v1.2.3-70-g09d2 From 4ca7291ebee440d9f3ef2a1643d8d01b29006459 Mon Sep 17 00:00:00 2001 From: TrueDoctor Date: Mon, 9 Apr 2018 13:13:54 +0200 Subject: Added FileHandler to enable sending heros via Discord --- DiscoBot/Commands/FileHandler.cs | 43 ++++++++++++++++++ DiscoBot/Commands/Voice.cs | 10 ++--- DiscoBot/DiscoBot.csproj | 3 +- UnitTestProject1/Properties/AssemblyInfo.cs | 20 --------- UnitTestProject1/UnitTest1.cs | 14 ------ UnitTestProject1/UnitTestProject1.csproj | 67 ----------------------------- UnitTestProject1/packages.config | 5 --- Voice.cs | 4 -- 8 files changed, 50 insertions(+), 116 deletions(-) create mode 100644 DiscoBot/Commands/FileHandler.cs delete mode 100644 UnitTestProject1/Properties/AssemblyInfo.cs delete mode 100644 UnitTestProject1/UnitTest1.cs delete mode 100644 UnitTestProject1/UnitTestProject1.csproj delete mode 100644 UnitTestProject1/packages.config delete mode 100644 Voice.cs (limited to 'DiscoBot/DiscoBot.csproj') diff --git a/DiscoBot/Commands/FileHandler.cs b/DiscoBot/Commands/FileHandler.cs new file mode 100644 index 0000000..efebe3f --- /dev/null +++ b/DiscoBot/Commands/FileHandler.cs @@ -0,0 +1,43 @@ +namespace DiscoBot.Commands +{ + using System; + using System.Linq; + using System.Net; + + using DiscoBot.Auxiliary; + using DiscoBot.Characters; + + using Discord.Commands; + + public class FileHandler : ModuleBase + { + [Command("add"), Summary("fügt Helden hinzu")] + public void AddChar() + { + var msg = this.Context.Message; + if (msg.Attachments == null) + { + throw new ArgumentException("Es wurde keine Datei angehängt"); + } + + var attachments = msg.Attachments.ToList(); + + if (!attachments.Any(x => x.Filename.EndsWith(".xml"))) + { + throw new ArgumentException("Es wurde kein xml Held mitgeschickt"); + } + + foreach (var attachment in attachments.Where(x => x.Filename.EndsWith(".xml"))) + { + using (var client = new WebClient()) + { + client.DownloadFile(attachment.Url, "helden\\" + attachment.Filename); + } + + Dsa.Chars.Add(new Character("helden\\" + attachment.Filename)); + (Dsa.Chars.Last() as Character)?.Talente.Select(x => new Talent(x.Name, x.Probe, 0)) + .Where(c => !Dsa.Talente.Exists(v => v.Name.Equals(c.Name))).ToList().ForEach(v => Dsa.Talente.Add(v)); + } + } + } +} diff --git a/DiscoBot/Commands/Voice.cs b/DiscoBot/Commands/Voice.cs index 72988d4..02210e8 100644 --- a/DiscoBot/Commands/Voice.cs +++ b/DiscoBot/Commands/Voice.cs @@ -39,10 +39,10 @@ [Command("play")] public Task PlayAudioAsync(string path) { - return this.SendAsync(Client, path); + return SendAsync(path); } - private Process CreateStream(string path) + private static Process CreateStream(string path) { var ffmpeg = new ProcessStartInfo { @@ -54,12 +54,12 @@ return Process.Start(ffmpeg); } - private async Task SendAsync(IAudioClient client, string path) + private static async Task SendAsync(string path) { // Create FFmpeg using the previous example - var ffmpeg = this.CreateStream(path); + var ffmpeg = CreateStream(path); var output = ffmpeg.StandardOutput.BaseStream; - var discord = client.CreatePCMStream(AudioApplication.Music); + var discord = Client.CreatePCMStream(AudioApplication.Music); await output.CopyToAsync(discord); await discord.FlushAsync(); } diff --git a/DiscoBot/DiscoBot.csproj b/DiscoBot/DiscoBot.csproj index 2bf17e5..3955ef6 100644 --- a/DiscoBot/DiscoBot.csproj +++ b/DiscoBot/DiscoBot.csproj @@ -148,16 +148,17 @@ + - + diff --git a/UnitTestProject1/Properties/AssemblyInfo.cs b/UnitTestProject1/Properties/AssemblyInfo.cs deleted file mode 100644 index 9dbb2a9..0000000 --- a/UnitTestProject1/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("UnitTestProject1")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("UnitTestProject1")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -[assembly: ComVisible(false)] - -[assembly: Guid("75b56398-a683-4b85-9ba3-b445d2b55527")] - -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UnitTestProject1/UnitTest1.cs b/UnitTestProject1/UnitTest1.cs deleted file mode 100644 index dbc289d..0000000 --- a/UnitTestProject1/UnitTest1.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace UnitTestProject1 -{ - [TestClass] - public class UnitTest1 - { - [TestMethod] - public void TestMethod1() - { - } - } -} diff --git a/UnitTestProject1/UnitTestProject1.csproj b/UnitTestProject1/UnitTestProject1.csproj deleted file mode 100644 index e887a0e..0000000 --- a/UnitTestProject1/UnitTestProject1.csproj +++ /dev/null @@ -1,67 +0,0 @@ - - - - - Debug - AnyCPU - {75B56398-A683-4B85-9BA3-B445D2B55527} - Library - Properties - UnitTestProject1 - UnitTestProject1 - v4.7.1 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 15.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - - - ..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll - - - - - - - - - - - - - - - - Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}". - - - - - - \ No newline at end of file diff --git a/UnitTestProject1/packages.config b/UnitTestProject1/packages.config deleted file mode 100644 index 8819694..0000000 --- a/UnitTestProject1/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/Voice.cs b/Voice.cs deleted file mode 100644 index 031c49e..0000000 --- a/Voice.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System; -using Discord; - - -- cgit v1.2.3-70-g09d2