summaryrefslogtreecommitdiff
path: root/dsa/DSALib
diff options
context:
space:
mode:
authorDennis Kobert <d-kobert@web.de>2019-06-11 23:38:13 +0200
committerDennis Kobert <d-kobert@web.de>2019-06-11 23:38:13 +0200
commit2fa4a0e50ebfc97059c8b84dbd17e79f9afc8a8d (patch)
treec3b34ccb2737e347a73768536895cbbaab13cc01 /dsa/DSALib
parentec991104f56e90d7bb2878da2fe6ed4e585dfc46 (diff)
parentaf74efccf8d21e6151022b71f3cacd3fa83024ee (diff)
Merge branch 'rework-backend'
Diffstat (limited to 'dsa/DSALib')
-rw-r--r--dsa/DSALib/Auxiliary/Calculator/Argument.cs35
-rw-r--r--dsa/DSALib/Auxiliary/Calculator/ISolvable.cs10
-rw-r--r--dsa/DSALib/Auxiliary/Calculator/Operator.cs51
-rw-r--r--dsa/DSALib/Auxiliary/Calculator/Ops.cs13
-rw-r--r--dsa/DSALib/Auxiliary/Calculator/StringSolver.cs183
-rw-r--r--dsa/DSALib/Auxiliary/CommandInfo.cs28
-rw-r--r--dsa/DSALib/Auxiliary/Dice.cs45
-rw-r--r--dsa/DSALib/Auxiliary/Extensions.cs25
-rw-r--r--dsa/DSALib/Auxiliary/IDataObjectEnumerableExtension.cs25
-rw-r--r--dsa/DSALib/Auxiliary/RandomMisc.cs52
-rw-r--r--dsa/DSALib/Auxiliary/SpellCorrect.cs61
-rw-r--r--dsa/DSALib/Auxiliary/TalentEnumerableExtension.cs74
-rw-r--r--dsa/DSALib/Auxiliary/WeaponImporter.cs175
-rw-r--r--dsa/DSALib/Characters/Being.cs17
-rw-r--r--dsa/DSALib/Characters/Critter.cs88
-rw-r--r--dsa/DSALib/Characters/Entity.cs12
-rw-r--r--dsa/DSALib/Characters/ICharacter.cs15
-rw-r--r--dsa/DSALib/Characters/ICombatant.cs20
-rw-r--r--dsa/DSALib/Commands/CommandHandler.cs135
-rw-r--r--dsa/DSALib/Commands/CommandTypes.cs13
-rw-r--r--dsa/DSALib/Commands/FileHandler.cs32
-rw-r--r--dsa/DSALib/Commands/Gm.cs176
-rw-r--r--dsa/DSALib/Commands/HeldList.cs174
-rw-r--r--dsa/DSALib/Commands/Help.cs54
-rw-r--r--dsa/DSALib/Commands/LebenUndAstral.cs172
-rw-r--r--dsa/DSALib/Commands/List.cs39
-rw-r--r--dsa/DSALib/Commands/MiscCommands.cs219
-rw-r--r--dsa/DSALib/Commands/NpcCommands.cs35
-rw-r--r--dsa/DSALib/Commands/ProbenTest.cs85
-rw-r--r--dsa/DSALib/DSALib.csproj11
-rw-r--r--dsa/DSALib/DSA_Game/Characters/Character.cs269
-rw-r--r--dsa/DSALib/DSA_Game/Characters/NPC.cs83
-rw-r--r--dsa/DSALib/DSA_Game/Characters/SaveChar.cs38
-rw-r--r--dsa/DSALib/DSA_Game/Dsa.cs95
-rw-r--r--dsa/DSALib/DSA_Game/Save/Properties.cs74
-rw-r--r--dsa/DSALib/DSA_Game/Save/SaveCommand.cs66
-rw-r--r--dsa/DSALib/DSA_Game/Save/Session.cs51
-rw-r--r--dsa/DSALib/FireBase/Database.cs270
-rw-r--r--dsa/DSALib/Models/Database/DataObject.cs13
-rw-r--r--dsa/DSALib/Models/Database/Dsa/Advantage.cs16
-rw-r--r--dsa/DSALib/Models/Database/Dsa/CharSpell.cs16
-rw-r--r--dsa/DSALib/Models/Database/Dsa/DatabaseChar.cs63
-rw-r--r--dsa/DSALib/Models/Database/Dsa/Field.cs16
-rw-r--r--dsa/DSALib/Models/Database/Dsa/GeneralSpell.cs20
-rw-r--r--dsa/DSALib/Models/Database/Dsa/GroupChar.cs13
-rw-r--r--dsa/DSALib/Models/Database/Dsa/Inventory.cs12
-rw-r--r--dsa/DSALib/Models/Database/Dsa/Talent.cs24
-rw-r--r--dsa/DSALib/Models/Database/Dsa/Weapon.cs52
-rw-r--r--dsa/DSALib/Models/Database/Dsa/WeaponTalent.cs18
-rw-r--r--dsa/DSALib/Models/Database/Groups/DSAGroup.cs10
-rw-r--r--dsa/DSALib/Models/Database/Groups/Group.cs9
-rw-r--r--dsa/DSALib/Models/Database/IDataObject.cs7
-rw-r--r--dsa/DSALib/Models/Dsa/CritterAttack.cs19
-rw-r--r--dsa/DSALib/Models/Dsa/KampfTalent.cs16
-rw-r--r--dsa/DSALib/Models/Dsa/Talent.cs43
-rw-r--r--dsa/DSALib/Models/Dsa/Vorteil.cs16
-rw-r--r--dsa/DSALib/Models/Dsa/Zauber.cs16
-rw-r--r--dsa/DSALib/Models/Network/Command.cs18
-rw-r--r--dsa/DSALib/Models/Network/CommandResponse.cs28
-rw-r--r--dsa/DSALib/Properties-DSACore-Auxiliary-CommandInfo.json101
-rw-r--r--dsa/DSALib/Properties-DSACore-DSA_Game-Characters-Character.json290
-rw-r--r--dsa/DSALib/PropertiesNewtonsoft-Json-Linq-JProperty.json30
62 files changed, 3886 insertions, 0 deletions
diff --git a/dsa/DSALib/Auxiliary/Calculator/Argument.cs b/dsa/DSALib/Auxiliary/Calculator/Argument.cs
new file mode 100644
index 0000000..e681377
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/Calculator/Argument.cs
@@ -0,0 +1,35 @@
+using System;
+
+namespace DSALib.Auxiliary.Calculator
+{
+ /// <summary>
+ /// Provides an ISolvable class to save numbers. The class handles Argument checking and conversion from string to int.
+ /// </summary>
+ public class Argument : ISolvable
+ {
+ private readonly int value;
+
+ public Argument(string value)
+ {
+ // check whether the value given is an empty string
+ if (string.IsNullOrEmpty(value))
+ throw new ArgumentException("Argument kann nicht mit einem leeren string instanziert werden. ",
+ nameof(value));
+
+ if (!int.TryParse(value, out var result))
+ throw new ArgumentException($"Kann {value} nicht in Integer konvertieren");
+
+ this.value = result;
+ }
+
+ public int Solve()
+ {
+ return value;
+ }
+
+ public override string ToString()
+ {
+ return value.ToString();
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/Calculator/ISolvable.cs b/dsa/DSALib/Auxiliary/Calculator/ISolvable.cs
new file mode 100644
index 0000000..844e9b3
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/Calculator/ISolvable.cs
@@ -0,0 +1,10 @@
+namespace DSALib.Auxiliary.Calculator
+{
+ /// <summary>
+ /// Object has to be able to return an integer as it's value
+ /// </summary>
+ public interface ISolvable
+ {
+ int Solve();
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/Calculator/Operator.cs b/dsa/DSALib/Auxiliary/Calculator/Operator.cs
new file mode 100644
index 0000000..e6aeec6
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/Calculator/Operator.cs
@@ -0,0 +1,51 @@
+using System;
+using DSALibv.Auxiliary.Calculator;
+
+namespace DSALib.Auxiliary.Calculator
+{
+ /// <summary>
+ /// The Operator Class represents a binary operator with tow Arguments and an Operation type
+ /// </summary>
+ public class Operator : ISolvable
+ {
+ private readonly ISolvable arg1, arg2;
+
+ public Operator(ISolvable arg1, ISolvable arg2, Ops operatorType)
+ {
+ this.arg1 = arg1;
+ this.arg2 = arg2;
+ OperatorType = operatorType;
+ }
+
+ public Ops OperatorType { get; set; }
+
+ public int Solve()
+ {
+ int result;
+ switch (OperatorType)
+ {
+ case Ops.Dice:
+ result = Dice.Roll(arg1.Solve(), arg2.Solve());
+ break;
+ case Ops.Multiply:
+ result = arg1.Solve() * arg2.Solve();
+ break;
+ case Ops.Add:
+ result = arg1.Solve() + arg2.Solve();
+ break;
+ case Ops.Subtract:
+ result = arg1.Solve() - arg2.Solve();
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return result;
+ }
+
+ public override string ToString()
+ {
+ return $"({arg1} {OperatorType} {arg2})";
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/Calculator/Ops.cs b/dsa/DSALib/Auxiliary/Calculator/Ops.cs
new file mode 100644
index 0000000..93046d0
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/Calculator/Ops.cs
@@ -0,0 +1,13 @@
+namespace DSALibv.Auxiliary.Calculator
+{
+ /// <summary>
+ /// The Different Operations, witch can be performed in execution-order
+ /// </summary>
+ public enum Ops
+ {
+ Dice,
+ Multiply,
+ Subtract,
+ Add
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/Calculator/StringSolver.cs b/dsa/DSALib/Auxiliary/Calculator/StringSolver.cs
new file mode 100644
index 0000000..45d6a54
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/Calculator/StringSolver.cs
@@ -0,0 +1,183 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using DSALibv.Auxiliary.Calculator;
+
+namespace DSALib.Auxiliary.Calculator
+{
+ /// <summary>
+ /// The StringSolver divides the calculation string into operations and SubStringSolvers if the string contains
+ /// parentheses
+ /// </summary>
+ public class StringSolver : ISolvable
+ {
+ private readonly List<object> arguments = new List<object>();
+ private readonly string input;
+
+ public StringSolver(string input)
+ {
+ this.input = input;
+ }
+
+ public int Solve()
+ {
+ var workInput = "0+" + input.Replace(" ", string.Empty).ToLower();
+ workInput = ExpandParentheses(workInput);
+
+ // Create a List of the different parts of the calculation, e.g.:{"0", "+", "(5+6)", "d", "3"}.
+ AtomizeOperations(workInput);
+
+ // traverse the List in order of Operation to Create the binary operation tree .
+ NestOperations();
+
+ // the List now contains only the top operation node, witch can be solved recursively,
+ return ((ISolvable) arguments.First()).Solve();
+ }
+
+ public override string ToString()
+ {
+ return "(0+" + input.Replace(" ", string.Empty).ToLower() + ")";
+ }
+
+ private static string
+ GetInner(ref string input) // extract the inner bracket an remove the section from the input string
+ {
+ var depth = 0;
+ for (var index = 1; index < input.Length; index++)
+ {
+ var c = input[index];
+ switch (c)
+ {
+ case '(':
+ depth++;
+ break;
+ case ')':
+ if (depth == 0)
+ {
+ var split = input.Substring(1, index - 1);
+ input = input.Substring(index + 1);
+ return split.Equals(string.Empty) ? "0" : split;
+ }
+ else
+ {
+ depth--;
+ }
+
+ break;
+ }
+ }
+
+ throw new ArgumentException("Invalid brace sequence");
+ }
+
+ private static Ops GetOps(char c)
+ {
+ switch (c)
+ {
+ case 'd':
+ case 'w':
+ return Ops.Dice;
+ case '+':
+ return Ops.Add;
+ case '-':
+ return Ops.Subtract;
+ case '*':
+ return Ops.Multiply;
+ default:
+ return Ops.Multiply;
+ }
+ }
+
+ private static string ExpandParentheses(string input) // insert * between Parentheses and digits
+ {
+ for (var i = 0; i < input.Length - 1; i++)
+ if (input[i + 1] == '(' && char.IsNumber(input[i]))
+ input = input.Insert(i + 1, "*");
+
+ for (var i = 1; i < input.Length; i++)
+ if (input[i - 1] == ')' && char.IsNumber(input[i]))
+ input = input.Insert(i, "*");
+
+ return input;
+ }
+
+ private void AtomizeOperations(string workInput)
+ {
+ for (var index = 0; index < workInput.Length; index++)
+ {
+ var c = workInput[index];
+
+ if (char.IsNumber(c))
+ {
+ // if char number, check if at end of string, else continue looping
+ if (index == workInput.Length - 1)
+ // if at end of string; add remaining number to arguments
+ arguments.Add(new Argument(workInput.Substring(0, index + 1)));
+
+ continue;
+ }
+
+ switch (c)
+ {
+ case ')':
+ throw new ArgumentException("Invalid brace sequence");
+ case '(':
+ arguments.Add(new StringSolver(GetInner(ref workInput)));
+ index = -1;
+ break;
+ default:
+ if (index > 0) arguments.Add(new Argument(workInput.Substring(0, index)));
+
+ arguments.Add(GetOps(c));
+ workInput = workInput.Remove(0, index + 1);
+ index = -1;
+ break;
+ }
+ }
+ }
+
+ private void NestOperations()
+ {
+ foreach (Ops currentOp in Enum.GetValues(typeof(Ops)))
+ // cycle through operators in operational order
+ for (var index = 0; index < arguments.Count; index++)
+ {
+ var arg = arguments[index];
+
+ if (arg.GetType() != typeof(Ops)) continue;
+
+ // arg is of type Ops
+ var op = (Ops) arg;
+
+ if (op != currentOp) continue;
+
+ // arg describes the current operation
+ HandleSpecialFormatting(ref index, op); // Deal with special needs...
+
+ // replace the previous current and next Element in the List with one Operation object
+ var temp = new Operator((ISolvable) arguments[index - 1], (ISolvable) arguments[index + 1], op);
+ arguments[index - 1] = temp;
+ arguments.RemoveRange(index, 2);
+ index--;
+ }
+ }
+
+ private void HandleSpecialFormatting(ref int index, Ops op)
+ {
+ var arg1 = arguments[index - 1];
+ if (arg1.GetType() == typeof(Ops))
+ {
+ if (op == Ops.Dice) arguments.Insert(index++, new Argument("1")); // w6 -> 1w6
+
+ if (op == Ops.Subtract) arguments.Insert(index++, new Argument("0")); // +-3 -> +0-3
+ }
+
+ var arg2 = arguments[index + 1]; // 3+-5 -> 3+(0-5)
+ if (arg2.GetType() == typeof(Ops))
+ {
+ arguments[index + 1] = new Operator(new Argument("0"), (ISolvable) arguments[index + 2], (Ops) arg2);
+ arguments.RemoveAt(index + 2);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/CommandInfo.cs b/dsa/DSALib/Auxiliary/CommandInfo.cs
new file mode 100644
index 0000000..d8e2188
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/CommandInfo.cs
@@ -0,0 +1,28 @@
+using System.Linq;
+
+namespace DSALib.Auxiliary
+{
+ public struct CommandInfo
+ {
+ public CommandInfo(string name, string brief, string[] description, string scope)
+ {
+ Name = name;
+ Scope = scope;
+ Brief = brief;
+ Description = description;
+ }
+
+ public string Name { get; }
+
+ public string Scope { get; }
+
+ public string Brief { get; }
+
+ public string[] Description { get; }
+
+ public string GetDescription()
+ {
+ return Description.Aggregate((s, c) => s + c);
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/Dice.cs b/dsa/DSALib/Auxiliary/Dice.cs
new file mode 100644
index 0000000..0bfabeb
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/Dice.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Linq;
+
+namespace DSALib.Auxiliary
+{
+ public static class Dice // roll it!
+ {
+ private static readonly Random Rnd = new Random();
+
+ public static int Roll(int d = 20)
+ {
+ return Rnd.Next(d) + 1;
+ }
+
+ public static int Roll(string input)
+ {
+ var strings = input.ToLower().Split(new[] {'w', 'd'}, 2, StringSplitOptions.RemoveEmptyEntries).ToList();
+
+
+ if (strings.Count != 2)
+ throw new ArgumentException($"{input}: does not satisfy the format requirements( dice count (d|w) die size)");
+
+ var count = Convert.ToInt32(strings[0]);
+ var d = Convert.ToInt32(strings[0]);
+
+ return Roll(count, d);
+ }
+
+ public static int Roll(int count, int d)
+ {
+ if (d <= 0 || count <= 0) return 0;
+
+ var sum = 0;
+ for (var i = 0; i < Math.Abs(count); i++)
+ {
+ var roll = Roll(d);
+ sum += roll;
+ }
+
+ sum *= Math.Abs(count) / count;
+
+ return sum;
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/Extensions.cs b/dsa/DSALib/Auxiliary/Extensions.cs
new file mode 100644
index 0000000..7d367a5
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/Extensions.cs
@@ -0,0 +1,25 @@
+namespace DSALib.Auxiliary
+{
+ public static class StringExtension
+ {
+ //This mehod extends string. It adds spaces until a fixed length is reached.
+ //If the original string is already longer, it is returner unmodified.
+ public static string AddSpaces(this string str, int length)
+ {
+ var temp = str;
+ for (var i = str.Length; i < length; i++) temp += " ";
+ return temp;
+ }
+
+
+ //This mehod extends string.
+ //It adds spaces at the HEAD of a string until a fixed length is reached.
+ //If the original string is already longer, it is returner unmodified.
+ public static string AddSpacesAtHead(this string str, int length)
+ {
+ var temp = "";
+ for (var i = str.Length; i < length; i++) temp += " ";
+ return temp + str;
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/IDataObjectEnumerableExtension.cs b/dsa/DSALib/Auxiliary/IDataObjectEnumerableExtension.cs
new file mode 100644
index 0000000..b8a6067
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/IDataObjectEnumerableExtension.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using DSALib.Auxiliary;
+using DSALib.Models.Database;
+
+namespace DSACore.Auxiliary
+{
+ public static class DataObjectEnumerableExtension
+ {
+ public static IDataObject Match(this IEnumerable<IDataObject> dataObjects, string name)
+ {
+ return (dataObjects as IOrderedEnumerable<IDataObject> ?? throw new InvalidOperationException()).OrderBy(x => SpellCorrect.Compare(name,x.Name)).Last();
+ }
+
+ public static bool TryMatch(this IEnumerable<IDataObject> dataObjects,out IDataObject data, string name)
+ {
+ data = (dataObjects as IOrderedEnumerable<IDataObject> ?? throw new InvalidOperationException()).OrderBy(x => SpellCorrect.Compare(name,x.Name)).Last();
+
+ return SpellCorrect.IsMatch(name, data.Name);
+ }
+ }
+}
diff --git a/dsa/DSALib/Auxiliary/RandomMisc.cs b/dsa/DSALib/Auxiliary/RandomMisc.cs
new file mode 100644
index 0000000..2723930
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/RandomMisc.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Linq;
+using System.Text;
+
+namespace DSALib.Auxiliary
+{
+ public static class RandomMisc
+ {
+ 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();
+ var count = Convert.ToInt32(strings[0]);
+ strings = strings[1].Split(' ').ToList();
+ var d = Convert.ToInt32(strings[0]);
+
+ if (strings.Count > 0)
+ {
+ }
+
+ var sum = 0;
+ for (var i = 0; i < count; i++)
+ {
+ var roll = Dice.Roll(d);
+ sum += roll;
+ output.Append("[" + roll + "] ");
+ }
+
+ if (strings.Count > 1)
+ {
+ sum += Convert.ToInt32(strings[1]);
+ output.Append("sum: " + sum);
+ }
+
+ return output.ToString();
+ }
+
+ public static double Random(double stdDev = 1, double mean = 0)
+ {
+ var u1 = Rand.NextDouble(); // uniform(0,1) random doubles
+ var u2 = Rand.NextDouble();
+ var randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
+ Math.Sin(2.0 * Math.PI * u2); // random normal(0,1)
+ var randNormal =
+ mean + stdDev * randStdNormal; // random normal(mean,stdDev^2)
+ return randNormal;
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/SpellCorrect.cs b/dsa/DSALib/Auxiliary/SpellCorrect.cs
new file mode 100644
index 0000000..79908c4
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/SpellCorrect.cs
@@ -0,0 +1,61 @@
+using System;
+
+namespace DSALib.Auxiliary
+{
+ public class SpellCorrect
+ {
+ public const double ErrorThreshold = 1 / 3.0;
+ private const double Match = 3.0;
+ private const double Gap = -1.5;
+ private const double Mismatch = -2.0;
+
+ public static double Compare(string s, string q)
+ {
+ s = s.ToLower();
+ q = q.ToLower();
+
+ int i, j;
+
+ var matrix = new double[s.Length + 1, q.Length + 1];
+ var max = 0.0;
+ matrix[0, 0] = 0.0;
+
+ for (i = 1; i < s.Length; i++)
+ matrix[i, 0] = i * Gap;
+
+ 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++)
+ {
+ double decay = j / (s.Length * 1000.0);
+ var add = s[i - 1] == q[j - 1] ? Match - decay : Mismatch;
+ var 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 (max < score && i == s.Length) max = score;
+
+ matrix[i, j] = score;
+ }
+
+ return max;
+ }
+
+ public static bool IsMatch(string s1, string s2)
+ {
+ var score = Compare(s1, s2);
+ return score > ErrorThreshold * s1.Length;
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/TalentEnumerableExtension.cs b/dsa/DSALib/Auxiliary/TalentEnumerableExtension.cs
new file mode 100644
index 0000000..6ec7fcc
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/TalentEnumerableExtension.cs
@@ -0,0 +1,74 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using DSACore.Auxiliary;
+using DSALib.DSA_Game.Characters;
+using DSALib.Models.Dsa;
+
+namespace DSALib.Auxiliary
+{
+ public static class TalentEnumerableExtension
+ {
+ public static string ProbenTest(this IEnumerable<Talent> List, Character c, string talentName, int erschwernis = 0)
+ {
+ var output = new StringBuilder();
+ var sc = new SpellCorrect();
+
+ if (!List.TryMatch(out var iTalent, talentName))
+ return $"{c.Name} kann nicht {talentName}...";
+
+ var talent = (Talent) iTalent;
+ var props = talent.GetEigenschaften(); // get the required properties
+ var tap = talent.Value; // get taw
+ var werte = props.Select(p => c.Eigenschaften[c.PropTable[p]]).ToArray();
+
+ output.AppendFormat(
+ "{0} würfelt: {1} \n{2} - {3} taw:{4} {5} \n",
+ c.Name,
+ talent.Name,
+ talent.Probe,
+ string.Join("/", werte),
+ talent.Value,
+ erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis);
+
+ output.Append(" ");
+ tap -= erschwernis;
+ var gesamtErschwernis = tap;
+ if (gesamtErschwernis < 0)
+ {
+ tap = 0;
+ for (var i = 0; i <= 2; i++)
+ {
+ // foreach property, dice and tap
+ var temp = Dice.Roll();
+ var eigenschaft = c.Eigenschaften[c.PropTable[props[i]]];
+
+ if (eigenschaft + gesamtErschwernis < temp) tap -= temp - (eigenschaft + gesamtErschwernis);
+
+ output.Append($"[{temp}]"); // add to string
+ }
+
+ if (tap >= 0) tap = 1;
+ }
+ else
+ {
+ for (var i = 0; i <= 2; i++)
+ {
+ // foreach property, dice and tap
+ var temp = Dice.Roll();
+ var eigenschaft = c.Eigenschaften[c.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
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Auxiliary/WeaponImporter.cs b/dsa/DSALib/Auxiliary/WeaponImporter.cs
new file mode 100644
index 0000000..61eb33e
--- /dev/null
+++ b/dsa/DSALib/Auxiliary/WeaponImporter.cs
@@ -0,0 +1,175 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using DSALib.FireBase;
+using DSALib.Models.Database.Dsa;
+
+namespace DSALib.Auxiliary
+{
+ public class WeaponImporter
+ {
+ private readonly List<RangedWeapon> Range = new List<RangedWeapon>();
+ private readonly List<MeleeWeapon> Weapons = new List<MeleeWeapon>();
+
+ public async Task DownloadWeapons()
+ {
+ var client = new HttpClient();
+
+
+ for (var i = 1; i <= 25; i++)
+ {
+ var responseString =
+ await client.GetStringAsync("http://diarium.eu/dsa4-forge/ajax/categoryChanged/" + i);
+
+ var talentRegex = new Regex(@"(?<=<option value="")([0-9]*)("">)(.*?)(?=<)");
+ //Regex idsRegex = new Regex(@"(?<=<option value=\"")([0-9]*)");
+
+
+ var talentMatch = talentRegex.Matches(responseString);
+ //var idMatch = idsRegex.Matches(responseString);
+
+ var lines = new List<string>();
+ var ids = new List<int>();
+
+ foreach (var matchGroup in talentMatch.ToList())
+ if (matchGroup.Success)
+ {
+ lines.Add(matchGroup.Groups[3].Value);
+ ids.Add(int.Parse(matchGroup.Groups[1].Value));
+ }
+
+
+ for (var j = 0; j < lines.Count; j++)
+ {
+ var talent = lines[j];
+
+ var values = await client.GetStringAsync("http://diarium.eu/dsa4-forge/ajax/calculate/" + i + "/" +
+ ids[j] + "/0/0/0/0/0/10/0/0/0");
+
+ values = Regex.Unescape(values.Replace(@"\t", ""));
+ // ... Use named group in regular expression.
+ var expression =
+ new Regex(
+ @"(((?<=(<td>))|(?<=(<td style=\""padding:2px\"">))).*?(?=<\/td>))|((?<=<span style=\""font-weight:bold;text-decoration:underline;\"">).*?(?=<\/span>))");
+
+ // ... See if we matched.
+ var matches = expression.Matches(values).Select(x => x.ToString()).ToList();
+
+ // ... Get group by name.
+ await AddMelee(i, talent, matches);
+ Console.Write(j + ",");
+ //await Task.Delay(TimeSpan.FromSeconds(5));
+ }
+
+ Console.WriteLine($"{i}: {ids.Count} => {Weapons.Count}");
+ //await Task.Delay(TimeSpan.FromSeconds(5));
+ }
+
+ Console.ReadLine();
+ }
+
+ private async Task AddMelee(int i, string talent, List<string> matches)
+ {
+ var name = talent.Replace(' ', '_').Replace(".", "");
+ if (!matches[1].Equals(string.Empty))
+ {
+ var temp = new MeleeWeapon(
+ name,
+ matches[1],
+ int.TryParse(matches[10], out var weight) ? weight : 0,
+ matches[0].Split(':', StringSplitOptions.RemoveEmptyEntries).First(),
+ matches[11])
+ {
+ INI = int.TryParse(matches[3], out var ini) ? ini : 0,
+ MW = matches[4],
+ TpKK = matches[2]
+ };
+
+ Weapons.Add(temp);
+ await Database.AddWeapon(temp);
+ }
+
+ /*if (i > 23)
+ {
+ var range = new RangedWeapon(
+ name,
+ matches[13],
+ int.TryParse(matches[10], out int weight) ? weight : 0,
+ matches[0].Split(':', StringSplitOptions.RemoveEmptyEntries).First(),
+ matches[11])
+ {
+ AtMod = int.TryParse(matches[10], out int atMod) ? atMod : 0,
+ KKMod = int.TryParse(matches[11], out int kkMod) ? kkMod : 0,
+ AtReach = matches[3],
+ TpReach = matches[4],
+ LoadTime = int.TryParse(matches[5], out int loadTime) ? loadTime : 0
+ };
+ Range.Add(range);
+ await Database.AddWeapon(range);
+ return;
+ }*/
+ if (i > 18)
+ {
+ var range = new RangedWeapon(
+ name,
+ matches[13].Replace(' ', '+'),
+ int.TryParse(matches[10], out var weight) ? weight : 0,
+ matches[0].Split(':', StringSplitOptions.RemoveEmptyEntries).First(),
+ matches[11])
+ {
+ AtMod = int.TryParse(matches[18], out var atMod) ? atMod : 0,
+ KKMod = int.TryParse(matches[17], out var kkMod) ? kkMod : 0,
+ AtReach = matches[14],
+ TpReach = matches[15],
+ LoadTime = int.TryParse(matches[18], out var loadTime) ? loadTime : 0
+ };
+ Range.Add(range);
+ await Database.AddWeapon(range);
+ }
+ }
+
+ private async Task AddRanged(int i, string talent, List<string> matches)
+ {
+ var name = talent.Replace(' ', '_').Replace(".", "");
+ if (!matches[1].Equals(string.Empty))
+ {
+ var temp = new MeleeWeapon(
+ name,
+ matches[1],
+ int.TryParse(matches[10], out var weight) ? weight : 0,
+ matches[0].Split(':', StringSplitOptions.RemoveEmptyEntries).First(),
+ matches[11])
+ {
+ INI = int.TryParse(matches[3], out var ini) ? ini : 0,
+ MW = matches[4],
+ TpKK = matches[2]
+ };
+
+ Weapons.Add(temp);
+ await Database.AddWeapon(temp);
+ }
+
+ if (i > 18)
+ {
+ var range = new RangedWeapon(
+ name,
+ matches[13].Replace(' ', '+'),
+ int.TryParse(matches[10], out var weight) ? weight : 0,
+ matches[0].Split(':', StringSplitOptions.RemoveEmptyEntries).First(),
+ matches[11])
+ {
+ AtMod = int.TryParse(matches[18], out var atMod) ? atMod : 0,
+ KKMod = int.TryParse(matches[17], out var kkMod) ? kkMod : 0,
+ AtReach = matches[14],
+ TpReach = matches[15],
+ LoadTime = int.TryParse(matches[18], out var loadTime) ? loadTime : 0
+ };
+ Range.Add(range);
+ await Database.AddWeapon(range);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Characters/Being.cs b/dsa/DSALib/Characters/Being.cs
new file mode 100644
index 0000000..27879a1
--- /dev/null
+++ b/dsa/DSALib/Characters/Being.cs
@@ -0,0 +1,17 @@
+namespace DSALib.Characters
+{
+ public class Being : Entity
+ {
+ public int Lebenspunkte_Basis { get; set; } = 30;
+
+ public int Lebenspunkte_Aktuell { get; set; } = 30;
+
+ public int Ausdauer_Basis { get; set; } = 30;
+
+ public int Ausdauer_Aktuell { get; set; } = 30;
+
+ public int Astralpunkte_Basis { get; set; } = 0;
+
+ public int Astralpunkte_Aktuell { get; set; } = 0;
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Characters/Critter.cs b/dsa/DSALib/Characters/Critter.cs
new file mode 100644
index 0000000..dcedccb
--- /dev/null
+++ b/dsa/DSALib/Characters/Critter.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using DiscoBot.DSA_Game.Characters;
+using DSALib.Models.Dsa;
+using Newtonsoft.Json;
+
+namespace DSALib.Characters
+{
+ public class Critter : Being, ICombatant
+ {
+ public CritterAttack lastAttack;
+
+ public Critter(int gw, int gs, int rs, int mr, int ko, int pa, string ini, List<CritterAttack> critterAttacks)
+ {
+ Gw = gw;
+ Gs = gs;
+ Rs = rs;
+ Mr = mr;
+ Ko = ko;
+ Pa = pa;
+ Ini = ini;
+ CritterAttacks = critterAttacks;
+ lastAttack = CritterAttacks[new Random().Next(critterAttacks.Count)];
+ }
+
+ public Critter()
+ {
+ }
+
+ public int Rs { get; set; }
+
+ public int Mr { get; set; }
+
+ public int Ko { get; set; }
+
+ public int Pa { get; set; }
+
+ public int Gs { get; set; }
+
+ public int Gw { get; set; }
+
+ public string Ini { get; set; }
+
+ public string Comment { get; set; }
+
+ public List<CritterAttack> CritterAttacks { get; set; }
+
+ public string Angriff(string talent, int erschwernis = 0)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string Parade(string talent, int erschwernis = 0)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static Critter Load(string path)
+ {
+ try
+ {
+ return
+ JsonConvert.DeserializeObject<Critter>(
+ File.ReadAllText(path)); // Deserialize Data and create Session Object
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Laden von Save-File {path} fehlgeschlagen." + e);
+ return null;
+ }
+ }
+
+ public void Save(string path = @"..\..\Critters\")
+ {
+ try
+ {
+ File.WriteAllText(path + Name + ".json",
+ JsonConvert.SerializeObject(this,
+ Formatting.Indented)); // Deserialize Data and create CommandInfo Struct
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Speichern von Save-File {path} fehlgeschlagen." + e);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Characters/Entity.cs b/dsa/DSALib/Characters/Entity.cs
new file mode 100644
index 0000000..a8a5e81
--- /dev/null
+++ b/dsa/DSALib/Characters/Entity.cs
@@ -0,0 +1,12 @@
+namespace DSALib.Characters
+{
+ public class Entity
+ {
+ public string Name { get; set; }
+
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Characters/ICharacter.cs b/dsa/DSALib/Characters/ICharacter.cs
new file mode 100644
index 0000000..256fecd
--- /dev/null
+++ b/dsa/DSALib/Characters/ICharacter.cs
@@ -0,0 +1,15 @@
+using DiscoBot.DSA_Game.Characters;
+
+namespace DSALib.Characters
+{
+ public interface ICharacter : ICombatant
+ {
+ string TestTalent(string talent, int erschwernis = 0);
+
+ string TestEigenschaft(string eigenschaft, int erschwernis = 0);
+
+ string Fernkampf(string talent, int erschwernis = 0);
+
+ string TestZauber(string waffe, int erschwernis);
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Characters/ICombatant.cs b/dsa/DSALib/Characters/ICombatant.cs
new file mode 100644
index 0000000..a4ce601
--- /dev/null
+++ b/dsa/DSALib/Characters/ICombatant.cs
@@ -0,0 +1,20 @@
+namespace DiscoBot.DSA_Game.Characters
+{
+ public interface ICombatant
+ {
+ string Name { get; set; }
+
+ int Lebenspunkte_Basis { get; set; }
+ int Lebenspunkte_Aktuell { get; set; }
+
+ int Ausdauer_Basis { get; set; }
+ int Ausdauer_Aktuell { get; set; }
+
+ int Astralpunkte_Basis { get; set; }
+ int Astralpunkte_Aktuell { get; set; }
+
+ string Angriff(string talent, int erschwernis = 0);
+
+ string Parade(string talent, int erschwernis = 0);
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/CommandHandler.cs b/dsa/DSALib/Commands/CommandHandler.cs
new file mode 100644
index 0000000..e63d7b8
--- /dev/null
+++ b/dsa/DSALib/Commands/CommandHandler.cs
@@ -0,0 +1,135 @@
+using System;
+using DSALib.Auxiliary;
+using DSALib.Auxiliary.Calculator;
+using DSALib.Commands;
+using DSALib.DSA_Game;
+using DSALib.Models.Network;
+
+namespace DSALib.Commands
+{
+ public class CommandHandler
+ {
+ public static CommandResponse ExecuteCommand(Command cmd)
+ {
+ var res = string.Empty;
+ var type = ResponseType.Broadcast;
+ switch (cmd.CmdIdentifier.ToLower())
+ {
+ case "addChar":
+ res = FileHandler.AddChar(cmd.CharId, cmd.CmdText);
+ break;
+ case "held":
+ case "wert":
+ case "werte":
+ case "char":
+ res = HeldList.ListAsync(cmd.CharId, cmd.CmdText);
+ break;
+ case "help":
+ case "man":
+ case "hilfe":
+ case "h":
+ res = Help.ShowHelp(cmd.CmdTexts.ToArray());
+ type = ResponseType.Caller;
+ break;
+ case "le":
+ case "leben":
+ case "lp":
+ res = LE.LEAsync(cmd.CharId, cmd.CmdText);
+ break;
+ case "ae":
+ case "astral":
+ case "asp":
+ res = AE.AEAsync(cmd.CharId, cmd.CmdText);
+ break;
+ case "list":
+ res = List.ListAsync(cmd.CmdText);
+ type = ResponseType.Caller;
+ break;
+ case "r":
+ case "roll":
+ res = RandomMisc.Roll(cmd.CmdText + " " + cmd.Cmdmodifier);
+ break;
+ case "solve":
+ res = new StringSolver(cmd.CmdText + cmd.Cmdmodifier).Solve().ToString();
+ break;
+ case "npc":
+ res = NpcCommands.CreateNpc(cmd.CharId, cmd.CmdTexts, cmd.Cmdmodifier);
+ break;
+ }
+
+ if (res == string.Empty) res = Proben(cmd.Name, cmd.CmdIdentifier, cmd.CmdText, cmd.Cmdmodifier);
+ if (res != string.Empty) return new CommandResponse(res, type);
+ return new CommandResponse($"Kommando {cmd.CmdIdentifier} nicht gefunden", ResponseType.Error);
+ }
+
+ private static string Proben(string name, string command, string waffe, int erschwernis = 0)
+ {
+ var res = string.Empty;
+ switch (command.ToLower())
+ {
+ 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;
+ }
+
+ return res;
+ }
+
+ private static string CheckCommand(string name, CommandTypes command, string waffe, int erschwernis = 0)
+ {
+ var chr = Dsa.GetCharacter(0);
+
+ 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);
+ case CommandTypes.Zauber:
+ return chr.TestZauber(waffe, erschwernis);
+ }
+
+ return $"{name} verwendet {waffe}";
+
+ throw new NotImplementedException("access char by id ore name and group id");
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/CommandTypes.cs b/dsa/DSALib/Commands/CommandTypes.cs
new file mode 100644
index 0000000..62b8b0f
--- /dev/null
+++ b/dsa/DSALib/Commands/CommandTypes.cs
@@ -0,0 +1,13 @@
+namespace DSALib.Commands
+{
+ public enum CommandTypes
+ {
+ Talent,
+ Eigenschaft,
+ Angriff,
+ Parade,
+ Fernkampf,
+ KeinChar,
+ Zauber
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/FileHandler.cs b/dsa/DSALib/Commands/FileHandler.cs
new file mode 100644
index 0000000..d117040
--- /dev/null
+++ b/dsa/DSALib/Commands/FileHandler.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Linq;
+using System.Net;
+using DSALib.DSA_Game;
+using DSALib.DSA_Game.Characters;
+using DSALib;
+using DSALib.Models.Dsa;
+
+namespace DSALib.Commands
+{
+ public class FileHandler
+ {
+ public static string AddChar(ulong id, string url)
+ {
+ if (url == string.Empty) throw new ArgumentException("Es wurde keine Datei angehängt");
+
+
+ if (!url.EndsWith(".xml")) throw new ArgumentException("Es wurde kein xml Held mitgeschickt");
+
+ using (var client = new WebClient())
+ {
+ client.DownloadFile(url, "helden\\" + url.Split("/").Last());
+ }
+
+ Dsa.Chars.Add(new Character("helden\\" + url.Split("/").Last()));
+ (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));
+
+ return $"{url.Split("/").Last()} wurde erfolgreich gespeichert";
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/Gm.cs b/dsa/DSALib/Commands/Gm.cs
new file mode 100644
index 0000000..74fd673
--- /dev/null
+++ b/dsa/DSALib/Commands/Gm.cs
@@ -0,0 +1,176 @@
+namespace DSALib.Commands
+{
+ /*public class Iam
+ {
+
+ [Command("Iam"), Summary("Wechselt den Character")]
+ [Alias("iam", "I_am", "i_am", "IchBin", "ichbin", "Ichbin", "Ich_bin", "ich_bin", "Ich", "ich", "I", "i")]
+ public Task Change_Character(params string[] givenName) // use fancy parameters
+ {
+ string res;
+ string name;
+
+ if (givenName.Length == 0 || (givenName.Length == 1 && (givenName[0].ToLower().Equals("bin") || givenName[0].ToLower().Equals("am"))))
+ {
+ res = " \nDu bist " + Dsa.Session.Relation[this.Context.User.Username] + "!\n \n";
+
+ return this.ReplyAsync("```xl\n" + res + "\n```");
+ }
+
+ if (givenName.Length > 1 && (givenName[0].ToLower().Equals("bin") || givenName[0].ToLower().Equals("am")) )
+ {
+ name = givenName.Skip(1).Aggregate((s, c) => s + c); // (Skip(1)) don't use the first element; Aggregate: take source s and do operation s = s+c for all elements
+ }
+ else
+ {
+ name = givenName.Aggregate((s, c) => s + c);
+ }
+
+ if (name.ToLower().Equals("man") || name.ToLower().Equals("help"))
+ {
+ return this.ReplyAsync("```xl\n" + Help.Get_Specific_Help("ich bin") + "\n```");
+
+ }
+
+ var character = Dsa.Chars.OrderBy(x => SpellCorrect.CompareEasy(name, x.Name)).First(); // usage of compareEasy
+
+ Dsa.Session.Relation[this.Context.User.Username] = character.Name;
+ res = " \nWillkommen " + character.Name + "!\n \n";
+
+
+ return this.ReplyAsync("```xl\n" + res + "\n```");
+ }
+ }
+
+
+ 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(name, x.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);
+ case CommandTypes.Zauber:
+ return chr.TestZauber(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 cmdText = "", int modifier = 0)
+ {
+ if (!Permissions.Test(this.Context, "Meister")) return;
+
+ command = command.ToLower();
+
+ string res;
+ string temp = string.Empty;
+ ICharacter cha = Dsa.Chars.OrderBy(x =>
+ SpellCorrect.CompareEasy(name, x.Name)).First();
+ switch (command)
+ {
+ case "le":
+ case "leben":
+ case "lp":
+ LE le = new LE();
+ temp = string.Empty;
+
+ if (modifier != 0)
+ {
+ temp = modifier.ToString();
+ }
+
+ res = cha.get_LE_Text(cmdText.Trim() + temp);
+
+ break;
+ case "ae":
+ case "asp":
+ case "astral":
+ AE ae = new AE();
+ temp = string.Empty;
+
+ if (modifier != 0)
+ {
+ temp = modifier.ToString();
+ }
+
+ res = cha.get_AE_Text(cmdText.Trim() + temp);
+
+ break;
+ default:
+ res = this.Test(name, command, cmdText, modifier);
+ break;
+ }
+
+
+ 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.ToLower())
+ {
+ 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;
+ }
+ }*/
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/HeldList.cs b/dsa/DSALib/Commands/HeldList.cs
new file mode 100644
index 0000000..ef29a14
--- /dev/null
+++ b/dsa/DSALib/Commands/HeldList.cs
@@ -0,0 +1,174 @@
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using DSALib.Auxiliary;
+using DSALib.DSA_Game;
+using DSALib.DSA_Game.Characters;
+
+namespace DSALib.Commands
+{
+ public class HeldList
+ {
+ public static string ListAsync(ulong id, params string[] prop_list)
+ {
+ var res = new List<string>();
+
+ var character = Dsa.GetCharacter(id) as Character;
+
+ var first_column_width = 18;
+
+
+ if (prop_list.Length == 0 || prop_list[0].ToLower().StartsWith("all") ||
+ prop_list[0].ToLower().StartsWith("brief") || prop_list[0].ToLower().StartsWith("zettel"))
+ {
+ res.Add(character.Name + ":\n");
+ //Eigenschaften
+ res.AddRange(
+ character.Eigenschaften.Take(9).Select(s => s.Key + ":\t " + s.Value));
+ res.Add("");
+ //LE/AE
+ res.Add("LE:\t " + character.Lebenspunkte_Aktuell + "/" + character.Lebenspunkte_Basis);
+ if (character.Astralpunkte_Basis > 0)
+ res.Add("AE:\t " + character.Astralpunkte_Aktuell + "/" + character.Astralpunkte_Basis);
+ res.Add("");
+ //Kampfwerte
+ res.Add("".AddSpaces(first_column_width) + " AT/PA");
+ res.AddRange(
+ character.Kampftalente.Select(s =>
+ s.Name.AddSpaces(first_column_width) + " " + s.At.ToString().AddSpacesAtHead(2) + "/" +
+ s.Pa.ToString().AddSpacesAtHead(2)));
+ res.Add("");
+ //Fernkampf
+ res.Add("".AddSpaces(first_column_width) + " FK");
+ res.AddRange(
+ character.Talente.Where(x => x.IstFernkampftalent()).Select(s =>
+ s.Name.AddSpaces(first_column_width) + " " +
+ (character.Eigenschaften["fk"] + s.Value).ToString().AddSpacesAtHead(2)));
+ res.Add("");
+ //Vorteile
+ res.AddRange(
+ character.Vorteile
+ .Select(s => s.Name + "\t " + s.Value));
+ res.Add("");
+ //Talente
+ res.AddRange(
+ character.Talente.Select(s =>
+ (s.Name.AddSpaces(first_column_width) + " " + s.Value).AddSpaces(first_column_width + 5) + " " +
+ s.Probe));
+ res.Add("");
+ //evtl Zauber
+ if (character.Zauber.Count > 0)
+ res.AddRange(
+ character.Zauber.Select(s =>
+ (s.Name.AddSpaces(first_column_width) + " " + s.Value).AddSpaces(first_column_width + 5) +
+ " " + s.Probe));
+ }
+ else if (prop_list[0].ToLower().StartsWith("man") || prop_list[0].ToLower().StartsWith("help") ||
+ prop_list[0].ToLower().StartsWith("hilf"))
+ {
+ return "```xl\n" + Help.Get_Specific_Help("Held") + "\n```";
+ }
+ else
+ {
+ res.Add(character.Name + ":\n");
+
+ foreach (var prop in prop_list)
+ {
+ switch (prop.ToLower())
+ {
+ case "e":
+ case "eig":
+ case "eigenschaft":
+ case "eigenschaften":
+ res.AddRange(
+ character.Eigenschaften.Take(8).Select(s => s.Key + ":\t " + s.Value));
+ break;
+ case "stat":
+ case "stats":
+ res.AddRange(
+ character.Eigenschaften.Take(9).Select(s => s.Key + ":\t " + s.Value));
+ res.Add("");
+ res.Add("LE:\t " + character.Lebenspunkte_Aktuell + "/" + character.Lebenspunkte_Basis);
+ if (character.Astralpunkte_Basis > 0)
+ res.Add("AE:\t " + character.Astralpunkte_Aktuell + "/" + character.Astralpunkte_Basis);
+ break;
+ case "le":
+ res.Add("LE:\t " + character.Lebenspunkte_Aktuell + "/" + character.Lebenspunkte_Basis);
+ break;
+ case "ae":
+ res.Add("AE:\t " + character.Astralpunkte_Aktuell + "/" + character.Astralpunkte_Basis);
+ break;
+ case "t":
+ case "ta":
+ case "talent":
+ case "talente":
+ res.AddRange(
+ character.Talente.Select(s =>
+ (s.Name.AddSpaces(first_column_width) + " " + s.Value).AddSpaces(
+ first_column_width + 5) + " " + s.Probe));
+ break;
+ case "zauber":
+ case "z":
+ res.AddRange(
+ character.Zauber.Select(s =>
+ (s.Name.AddSpaces(first_column_width) + " " + s.Value).AddSpaces(
+ first_column_width + 5) + " " + s.Probe));
+ break;
+ case "w":
+ case "waffe":
+ case "waffen":
+ case "kampf":
+ case "kampfwert":
+ case "kampfwerte":
+ res.Add("".AddSpaces(first_column_width) + " AT/PA");
+ res.AddRange(
+ character.Kampftalente.Select(s =>
+ s.Name.AddSpaces(first_column_width) + " " + s.At.ToString().AddSpacesAtHead(2) +
+ "/" + s.Pa.ToString().AddSpacesAtHead(2)));
+ break;
+ case "f":
+ case "fern":
+ res.Add("".AddSpaces(first_column_width) + " FK");
+ res.AddRange(
+ character.Talente.Where(x => x.IstFernkampftalent()).Select(s =>
+ s.Name.AddSpaces(first_column_width) + " " +
+ (character.Eigenschaften["fk"] + s.Value).ToString().AddSpacesAtHead(2)));
+ break;
+ case "v":
+ case "vt":
+ case "vor":
+ case "vorteil":
+ case "vorteile":
+ case "nachteil":
+ case "nachteile":
+ res.AddRange(
+ character.Vorteile
+ .Select(s => s.Name + "\t " + s.Value));
+ break;
+
+ default:
+ res.Add($"Kommando {prop} nicht gefunden");
+ break;
+ }
+
+ res.Add("");
+ }
+ }
+
+
+ var sb = new StringBuilder();
+ foreach (var re in res) sb.AppendLine(re);
+
+ return sb.ToString();
+ /*
+ if (persist == 1)
+ {
+ await this.ReplyAsync(res, true);
+ }
+ else
+ {
+ await this.ReplyAsync(res, TimeSpan.FromSeconds(90));
+ }*/
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/Help.cs b/dsa/DSALib/Commands/Help.cs
new file mode 100644
index 0000000..4506821
--- /dev/null
+++ b/dsa/DSALib/Commands/Help.cs
@@ -0,0 +1,54 @@
+using System.Linq;
+using DSALib.Auxiliary;
+using DSALib.DSA_Game.Save;
+
+namespace DSALib.Commands
+{
+ public class Help
+ {
+ //public static List<CommandInfo> Commands { get; } = new List<CommandInfo>();
+
+
+ public static string Get_Specific_Help(string command)
+ {
+ // return command specific help
+ var com = Properties.CommandInfos
+ .OrderBy(x => SpellCorrect.Compare(x.Name, command.ToLower())).Last(); // get best fit command
+ return com.GetDescription();
+ }
+
+ public static string Get_Generic_Help()
+ {
+ var res = "";
+ foreach (var com in Properties.CommandInfos)
+ {
+ var first_column_width = 8;
+ res += ("!" + com.Name + ": ").AddSpaces(first_column_width) + com.Brief;
+
+ if (com.Description.Length > 1)
+ res += "\n" + "".AddSpaces(first_column_width) + "(\"!man " + com.Name +
+ "\" gibt genauere Informationen)";
+
+ res += "\n\n";
+ }
+
+ return res;
+ }
+
+ public static string ShowHelp(params string[] commandList)
+ {
+ var command = "";
+ if (commandList.Length > 0) command = commandList.Aggregate((s, c) => s + " " + c);
+
+ if (command.Equals(string.Empty)) // return generic Help
+ {
+ var res = Get_Generic_Help();
+
+ return res;
+ }
+
+
+ return Get_Specific_Help(command);
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/LebenUndAstral.cs b/dsa/DSALib/Commands/LebenUndAstral.cs
new file mode 100644
index 0000000..ac11c91
--- /dev/null
+++ b/dsa/DSALib/Commands/LebenUndAstral.cs
@@ -0,0 +1,172 @@
+using System;
+using DSALib.Auxiliary;
+using DSALib.DSA_Game;
+using DSALib.Characters;
+
+namespace DSALib.Commands
+{
+ public class LE
+ {
+ public static string LEAsync(ulong id, string modifier)
+ {
+ //This is the string that will be printed
+ var res = "";
+
+
+ //Get the actual text
+ res += Dsa.GetCharacter(id).get_LE_Text(modifier);
+
+
+ return res;
+ }
+ }
+
+ public class AE
+ {
+ public static string AEAsync(ulong id, string modifier)
+ {
+ //This is the string that will be printed
+ var res = "";
+
+
+ //Get the actual text
+ res += Dsa.GetCharacter(id).get_AE_Text(modifier);
+
+ return res;
+ }
+ }
+
+ public static class StatExtension
+ {
+ public static string get_LE_Text(this ICharacter c, string prop)
+ {
+ var res = "";
+ var comp = new SpellCorrect();
+ var character = c;
+
+ res += character.Name + ":\n";
+
+ //If there is actual input we process it
+ if (prop.Length > 0)
+ {
+ res += "LE: ";
+ res += character.Lebenspunkte_Aktuell + "/" + character.Lebenspunkte_Basis + " -> ";
+
+ // Apply a change to current value
+ if (prop.StartsWith("+") || prop.StartsWith("-"))
+ {
+ //Allow overflowing the max
+ if (prop.StartsWith("++"))
+ {
+ character.Lebenspunkte_Aktuell = character.Lebenspunkte_Aktuell +
+ Convert.ToInt32(prop.Substring(1, prop.Length - 1));
+ }
+ else
+ {
+ var temp = character.Lebenspunkte_Aktuell + Convert.ToInt32(prop) -
+ character.Lebenspunkte_Basis;
+ //Stop from overflow overflow
+ if (temp > 0 && prop.StartsWith("+"))
+ {
+ character.Lebenspunkte_Aktuell =
+ character.Lebenspunkte_Basis > character.Lebenspunkte_Aktuell
+ ? character.Lebenspunkte_Basis
+ : character.Lebenspunkte_Aktuell;
+ res += " Maximale Lebenspunkte sind erreicht ";
+ }
+ //Simply apply change
+ else
+ {
+ character.Lebenspunkte_Aktuell = character.Lebenspunkte_Aktuell + Convert.ToInt32(prop);
+ }
+ }
+
+ res += character.Lebenspunkte_Aktuell + "/" + character.Lebenspunkte_Basis;
+ }
+ else
+ {
+ // Set to new value regardless of original
+ character.Lebenspunkte_Aktuell = Convert.ToInt32(prop);
+
+ res += character.Lebenspunkte_Aktuell + "/" + character.Lebenspunkte_Basis;
+ }
+ }
+ //If no value is passed, the curent value is displayed
+ else
+ {
+ res += "LE: " + character.Lebenspunkte_Aktuell + "/" + character.Lebenspunkte_Basis;
+ }
+
+ return res;
+ }
+
+ public static string get_AE_Text(this ICharacter c, string prop)
+ {
+ var res = "";
+ var comp = new SpellCorrect();
+ var character = c;
+
+ res += character.Name + ":\n";
+
+ //If there is actual input we process it
+ if (prop.Length > 0)
+ {
+ res += "AE: ";
+ res += character.Astralpunkte_Aktuell + "/" + character.Astralpunkte_Basis + " -> ";
+
+ // Apply a change to current value
+ if (prop.StartsWith("+") || prop.StartsWith("-"))
+ {
+ //Allow overflowing the max
+ if (prop.StartsWith("++"))
+ {
+ character.Astralpunkte_Aktuell = character.Astralpunkte_Aktuell +
+ Convert.ToInt32(prop.Substring(1, prop.Length - 1));
+ }
+ else
+ {
+ var temp = character.Astralpunkte_Aktuell + Convert.ToInt32(prop) -
+ character.Astralpunkte_Basis;
+ //Stop from overflow overflow
+ if (temp > 0 && prop.StartsWith("+"))
+ {
+ character.Astralpunkte_Aktuell =
+ character.Astralpunkte_Basis > character.Astralpunkte_Aktuell
+ ? character.Astralpunkte_Basis
+ : character.Astralpunkte_Aktuell;
+ res += " Maximale Astralpunkte sind erreicht ";
+ }
+ //Simply apply change
+ else
+ {
+ character.Astralpunkte_Aktuell = character.Astralpunkte_Aktuell + Convert.ToInt32(prop);
+ }
+ }
+
+ if (character.Astralpunkte_Aktuell < 0)
+ {
+ res += "Nicht genügend Astralpunkte! ";
+ character.Astralpunkte_Aktuell = 0;
+ }
+
+ res += character.Astralpunkte_Aktuell + "/" + character.Astralpunkte_Basis;
+ }
+ //Set to new value regardless of original
+ else
+ {
+ character.Astralpunkte_Aktuell = Convert.ToInt32(prop);
+
+ res += character.Astralpunkte_Aktuell + "/" + character.Astralpunkte_Basis;
+ }
+ }
+ //If no value is passed, the curent value is displayed
+ else
+ {
+ res += "AE: " + character.Astralpunkte_Aktuell + "/" + character.Astralpunkte_Basis;
+ }
+
+
+ return res;
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/List.cs b/dsa/DSALib/Commands/List.cs
new file mode 100644
index 0000000..1213f85
--- /dev/null
+++ b/dsa/DSALib/Commands/List.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using DSALib.DSA_Game;
+
+namespace DSALib.Commands
+{
+ public class List
+ {
+ public static string ListAsync(string prop)
+ {
+ var res = new List<string>();
+
+ //int persist = 0;
+
+ switch (prop.ToLower())
+ {
+ case "man":
+ case "help":
+ return Help.Get_Specific_Help("List");
+ // break;
+ case "chars":
+ res.AddRange(Dsa.Chars.Select(x => x.Name));
+ break;
+ case "commands":
+ // res.AddRange(Help.Commands.Select(x => x.Name));
+ res.Add(Help.Get_Generic_Help());
+ break;
+
+ default:
+ res.Add($"Kommando {prop} nicht gefunden");
+ break;
+ }
+
+
+ return res.ToString();
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/MiscCommands.cs b/dsa/DSALib/Commands/MiscCommands.cs
new file mode 100644
index 0000000..69b2ffe
--- /dev/null
+++ b/dsa/DSALib/Commands/MiscCommands.cs
@@ -0,0 +1,219 @@
+namespace DSALib.Commands
+{
+ public class MiscCommands
+ {
+ /*[Command("r"), Summary("Würfelt ")]
+ [Alias("R", "Roll", "roll", "Würfle")]
+ public Task RollAsync([Remainder, Summary("Weapon")] string roll)
+ {
+ //return this.ReplyAsync("```xl\n" + new Auxiliary.Calculator.StringSolver(roll).Solve() + "\n```");
+ return this.ReplyAsync("```xl\n" + RandomMisc.Roll(roll) + "\n```");
+ }
+
+ [Command("rd"), Summary("Würfel Dennis ")]
+ public Task RollDennisAsync([Remainder, Summary("Weapon")] string roll)
+ {
+ return this.ReplyAsync("```xl\n" + new DSALib.Auxiliary.Calculator.StringSolver(roll).Solve() + "\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);
+ }
+
+ [Command("liebe"), Summary("Echos a message.")]
+ [Alias("Liebe", "<3", "love")]
+ public async Task LoveAsync()
+ {
+ Random rand = new Random();
+ var user = HostingApplication.Context.Channel.GetUsersAsync().ToList().Result.ToList().First().Where(x=>x.Status!= UserStatus.Offline).OrderBy(x => rand.Next()).First();
+ await this.ReplyAsync(":heart: :heart: :heart: Verteilt die Liebe! :heart: :heart: :heart: \n Besondere Liebe geht an " + user.Username);
+ //await this.ReplyAsync("!liebe");
+ }
+
+ [Command("maul"), Summary("Echos a message.")]
+ public Task MaulAsync()
+ {
+ return this.ReplyAsync("Maul...? Du meintest doch sicher Maulwürfe oder? \n:heart: :heart: :heart: \nGanz viel Liebe für Maulwürfe !\n:heart: :heart: :heart:");
+
+ }
+
+ [Command("report"), Summary("Report a Tweet")]
+ public async Task ReportAsync([Remainder, Summary("Link")] string link)
+ {
+ var content = new System.Net.Http.StringContent(link);
+
+ using (HttpClient client = new HttpClient())
+ {
+ var response = await client.PostAsync("http://www.example.com/recepticle.aspx", content);
+ }
+
+ await this.ReplyAsync($"Dein report wurde hinzugefügt");
+ }
+
+ [Command("match"), Summary("Tinder.")]
+ [Alias("mach","pass", "passt")]
+ public Task TinderAsync(string s1, string s2)
+ {
+
+ var sc = new SpellCorrect();
+ var rand = new System.Random((s1+s2).GetHashCode());
+
+ var wert = Math.Log10(Math.Floor(1000.0 * (SpellCorrect.CompareExact(s1, s2) + rand.NextDouble() * 10.0)) / 1000.0);
+ wert = ((wert * 100.0) < 100.0 ? wert * 100.0 : 100.0 - wert);
+ wert = wert < 0 ? -wert : wert;
+ return this.ReplyAsync($"Ihr passt zu {Math.Floor(100.0 * wert )/ 100.0}% zusammen");
+
+ }
+
+ [Command("reddit"), Summary("Reddit.")]
+ public Task RedditAsync()
+ {
+ return this.ReplyAsync($"Ein Archiv der Vergangenen Aktionen findet man hier: https://www.reddit.com/r/ReconquistaInternet/");
+
+ }
+
+ [Command("compare"), Summary("Echos a message.")]
+ public async Task KickAsync()
+ {
+ //await this.Context.Guild.DownloadUsersAsync();
+ var users = HostingApplication.Context.Guild.GetUsersAsync(CacheMode.AllowDownload);
+ var test = File.ReadAllLines("RG.txt");
+ await users;
+ var us = users.Result.Select(x => x.Username);
+
+ var lines = test.Where(x => !x.Equals(string.Empty)).ToList();
+
+
+ var sc = new SpellCorrect();
+
+ var res = new List<string>();
+
+ foreach (string line in lines)
+ {
+ var best = us.OrderBy(user => sc.Compare(user, line)).First();
+
+ double fit = sc.Compare(best, line);
+
+ if (fit < SpellCorrect.ErrorThreshold - 20000)
+ {
+ if (fit.Equals(0))
+ {
+ res.Add($"@\t{best} !!! => {line}");
+ }
+ else
+ {
+ res.Add($"-\t{best} hat Ähnlichkeit mit: {line}");
+ }
+ }
+ }
+
+ 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);
+ }
+
+ if(Permissions.Check(this.Context, new []{"Admin", "Mod"}))
+ await this.ReplyTimedAsync(sb.ToString(), TimeSpan.FromSeconds(90));
+
+ //await this.ReplyAsync($"{count} Duplikate gefunden");
+
+ }
+
+
+ [Command("clear"), Summary("Cleans up messages.")]
+ public async Task DeleteAsync(int count)
+ {
+ var messagesAsync = HostingApplication.Context.Channel.GetMessagesAsync(count);
+ Task.WaitAll(messagesAsync.ToArray());
+ var list = messagesAsync.ToEnumerable().ToList();
+ var messages = new List<IMessage>();
+ foreach (var task in list)
+ {
+ messages.AddRange(task.ToList());
+ }
+
+ if (Permissions.Check(HostingApplication.Context, new[] { "Admin", "Mod", "Meister" }))
+ {
+
+ var waiters = new List<Task>();
+ foreach (var message in messages)
+ {
+ waiters.Add((message as IUserMessage).DeleteAsync());
+ }
+
+ Task.WaitAll(waiters.ToArray());
+ }
+
+ }
+
+ [Command("check"), Summary("Echos a message.")]
+ [Alias("Check")]
+ public async Task CheckAsync(string quarry)
+ {
+ var perm = new List<string> { "Admin", "Mod", "Privatpolizei" };
+
+ Permissions.Test(this.Context, perm.ToArray());
+
+ var test = File.ReadAllLines("RG.txt");
+
+ var lines = test.Where(x => !x.Equals(string.Empty)).ToList();
+
+
+ var sc = new SpellCorrect();
+ var count = lines.OrderBy(line => sc.Compare(quarry, line)).First();
+
+ var fit = sc.Compare(count, quarry);
+
+ string Antwort;
+
+ if (fit < SpellCorrect.ErrorThreshold - 20000)
+ {
+ Antwort= $"```xl\nAuf anderem Server Match gefunden: {count}";
+ }
+ else
+ {
+ Antwort = $"```xl\nAuf anderem Server Kein Match gefunden: {quarry}";
+ }
+
+
+ var users = HostingApplication.Context.Guild.GetUsersAsync(CacheMode.AllowDownload);
+ await users;
+ var us = users.Result.Select(x => x.Username);
+
+ sc = new SpellCorrect();
+ count = us.OrderBy(line => sc.Compare(quarry, line)).First();
+
+ fit = sc.Compare(count, quarry);
+
+ if (fit < SpellCorrect.ErrorThreshold - 20000)
+ {
+ Antwort = Antwort + $"\nAuf unserem Server Match gefunden: {count}\n```";
+ }
+ else
+ {
+ Antwort = Antwort + $"\nAuf unserem Server Kein Match gefunden: {quarry} \n```";
+ }
+
+ await ReplyAsync(Antwort);
+
+ }*/
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/NpcCommands.cs b/dsa/DSALib/Commands/NpcCommands.cs
new file mode 100644
index 0000000..510b78b
--- /dev/null
+++ b/dsa/DSALib/Commands/NpcCommands.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using DSALib.Characters;
+using DSALib.DSA_Game;
+using DSALib.DSA_Game.Characters;
+
+namespace DSALib.Commands
+{
+ public class NpcCommands
+ {
+ public static string CreateNpc(ulong id, IEnumerable<string> props, int modifier)
+ {
+ if (int.TryParse(props.Last(), out var mean)) return Random(id, props.First(), mean, modifier);
+
+ return Copy(id, props.First(), props.Last(), modifier);
+ }
+
+ private static string Random(ulong id, string npcName, int mean = 9, int stDv = 1)
+ {
+ throw new NotImplementedException();
+ //Dsa.Chars.Add(new Npc(npcName, mean, stDv));
+ //return $"{npcName} wurde zufällig generiert";
+ }
+
+ private static string Copy(ulong id, string npcName, string source, int stDv = 1)
+ {
+ if (Dsa.Chars.Exists(x => x.Name.Equals(npcName))) throw new Exception("Char gibt es schon");
+ throw new NotImplementedException();
+ //var chr = Dsa.GetCharacter(id);
+ //Dsa.Chars.Add(new Character(chr as Character, npcName, stDv));
+ //return $"{npcName} wurde als variierte Kopie von {source} erstellt";
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Commands/ProbenTest.cs b/dsa/DSALib/Commands/ProbenTest.cs
new file mode 100644
index 0000000..7c88480
--- /dev/null
+++ b/dsa/DSALib/Commands/ProbenTest.cs
@@ -0,0 +1,85 @@
+namespace DSALib.Commands
+{
+ public class ProbenTest
+ {
+ /*[Command("t"), Summary("Würfelt ein Talent-/Zauberprobe")]
+ [Alias("T", "Talent", "talent", "versuche")]
+ public Task TalentAsync([Summary("Talent oder Zaubername")] string talent, int erschwernis = 0)
+ {
+ string res;
+ try
+ {
+ res = Gm.CheckCommand(
+ Dsa.Session.Relation[this.Context.User.Username],
+ CommandTypes.Talent,
+ talent,
+ erschwernis);
+ }
+ catch
+ {
+ res = Gm.CheckCommand(
+ Dsa.Session.Relation["Tardis"],
+ CommandTypes.Talent,
+ talent,
+ erschwernis);
+ }
+
+ return this.ReplyAsync("```xl\n" + res + "\n```");
+ }
+
+ [Command("Zauber"), Summary("Würfelt ein Zauberprobe")]
+ [Alias("Z", "zauber", "z")]
+ public Task ZauberAsync([Summary("Zaubername")] string zauber, int erschwernis = 0)
+ {
+ string res;
+ try
+ {
+ res = Gm.CheckCommand(
+ Dsa.Session.Relation[this.Context.User.Username],
+ CommandTypes.Zauber,
+ zauber,
+ erschwernis);
+ }
+ catch
+ {
+ res = Gm.CheckCommand(
+ Dsa.Session.Relation["Tardis"],
+ CommandTypes.Zauber,
+ zauber,
+ 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.Session.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("A", "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.Session.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.Session.Relation[this.Context.User.Username])).Parade(talent, erschwernis) + "\n```");
+ }
+
+ [Command("f"), Summary("Führt eine Fernkampfprobe aus")]
+ [Alias("F", "fern", "Fern", "Schuss", "schuss", "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.Session.Relation[this.Context.User.Username])).Fernkampf(waffe, erschwernis) + "\n```");
+ }*/
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/DSALib.csproj b/dsa/DSALib/DSALib.csproj
new file mode 100644
index 0000000..2281bd6
--- /dev/null
+++ b/dsa/DSALib/DSALib.csproj
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.2</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\FireBase\FireBase.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/dsa/DSALib/DSA_Game/Characters/Character.cs b/dsa/DSALib/DSA_Game/Characters/Character.cs
new file mode 100644
index 0000000..aea5671
--- /dev/null
+++ b/dsa/DSALib/DSA_Game/Characters/Character.cs
@@ -0,0 +1,269 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using DSACore.Auxiliary;
+using DSALib.Auxiliary;
+using DSALib.Characters;
+using DSALib.Models.Dsa;
+
+namespace DSALib.DSA_Game.Characters
+{
+ public class Character : Being, ICharacter
+ {
+ public Character()
+ {
+ 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(string path) : this()
+ {
+ Load(new MemoryStream(File.ReadAllBytes(path))); // load
+ Post_process(); // calculate derived values
+ }
+
+ public Character(MemoryStream stream) : this()
+ {
+ Load(stream); // load
+ Post_process(); // calculate derived values
+ }
+
+ public Character(Character c, string name, int stDv = 2) : this()
+ {
+ Name = name;
+ foreach (var i in c.Eigenschaften)
+ Eigenschaften.Add(i.Key, i.Value + (int) Math.Round(RandomMisc.Random(stDv)));
+
+ foreach (var i in c.Vorteile)
+ Vorteile.Add(new Vorteil(i.Name, i.Value + (int) Math.Round(RandomMisc.Random(stDv))));
+
+ foreach (var i in c.Talente)
+ Talente.Add(new Talent(i.Name, i.Probe, i.Value + (int) Math.Round(RandomMisc.Random(stDv))));
+
+ foreach (var i in c.Zauber)
+ Zauber.Add(new Zauber(i.Name, i.Probe, i.Value + (int) Math.Round(RandomMisc.Random(stDv)),
+ i.Complexity, i.Representation));
+
+ foreach (var i in c.Kampftalente)
+ Kampftalente.Add(new KampfTalent(i.Name, i.At + (int) Math.Round(RandomMisc.Random(stDv)),
+ i.Pa + (int) Math.Round(RandomMisc.Random(stDv))));
+
+ Post_process(); // calculate derived values
+ }
+
+ public Dictionary<string, int> Eigenschaften { get; set; } = new Dictionary<string, int>(); // char properties
+
+ public List<Talent> Talente { get; set; } = new List<Talent>(); // list of talent objects (talents)
+
+ public List<Zauber> Zauber { get; set; } = new List<Zauber>(); // list of spell objects
+
+ public List<KampfTalent> Kampftalente { get; set; } = new List<KampfTalent>(); // list of combat objects
+
+ public List<Vorteil> Vorteile { get; set; } = new List<Vorteil>();
+
+ public Dictionary<string, string> PropTable { get; set; } = new Dictionary<string, string>(); // -> Körperkraft
+
+ public string TestTalent(string talent, int erschwernis = 0) // Talentprobe
+ {
+ return Talente.ProbenTest(this, talent, erschwernis);
+ }
+
+ public string TestZauber(string zauber, int erschwernis = 0) // Talentprobe
+ {
+ return Zauber.ProbenTest(this, zauber, erschwernis);
+ }
+
+ public string TestEigenschaft(string eigenschaft, int erschwernis = 0)
+ {
+ var output = new StringBuilder();
+ var prop = PropTable[eigenschaft.ToUpper()];
+ var tap = Eigenschaften[prop];
+ output.AppendFormat(
+ "{0}-Eigenschaftsprobe ew:{1} {2} \n",
+ prop,
+ tap,
+ erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis);
+ var 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();
+ if (!Kampftalente.TryMatch(out var iattack, talent))
+ return $"{Name} kann nicht mit der Waffenart {talent} umgehen...";
+ var attack = (KampfTalent) iattack;
+ var tap = attack.At;
+ output.AppendFormat(
+ "{0}-Angriff taw:{1} {2} \n",
+ attack.Name,
+ tap,
+ erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis);
+
+ var temp = Dice.Roll();
+ output.Append(temp - erschwernis);
+ return output.ToString();
+ }
+
+ public string Parade(string talent, int erschwernis = 0)
+ {
+ var output = new StringBuilder();
+
+ if (Kampftalente.TryMatch(out var iAttack , talent))
+ return $"{Name} kann nicht mit der Waffenart {talent} umgehen...";
+
+
+ var attack = (KampfTalent) iAttack;
+ var tap = attack.Pa;
+ output.AppendFormat(
+ "{0}-Parade taw:{1} {2}\n",
+ attack.Name,
+ tap,
+ erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis);
+
+ var temp = Dice.Roll();
+ output.Append(temp - erschwernis);
+ return output.ToString();
+ }
+
+ public string Fernkampf(string talent, int erschwernis = 0)
+ {
+ var output = new StringBuilder();
+ var fk = Eigenschaften["fk"];
+ if (! Talente.TryMatch(out var iAttack, talent))
+ return $"{Name} kann nicht mit der Waffenart {talent} umgehen...";
+
+ var attack = (Talent) iAttack;
+ var tap = attack.Value;
+ output.AppendFormat(
+ "{0} taw:{1} {2} \n",
+ attack.Name,
+ tap,
+ erschwernis.Equals(0) ? string.Empty : "Erschwernis: " + erschwernis);
+ tap -= erschwernis;
+ var temp = Dice.Roll();
+ tap -= temp > fk ? temp - fk : 0;
+ output.Append($"W20: {temp} tap: {tap}");
+ return output.ToString();
+ }
+
+ private void Post_process()
+ {
+ var LE_Wert = Eigenschaften["Lebensenergie"];
+ var AE_Wert = Eigenschaften.First(s => s.Key.Contains("Astralenergie")).Value;
+
+ //var KL_Wert = this.Eigenschaften.First(s => s.Key.Contains("Klugheit")).Value;
+ var MU_Wert = Eigenschaften.First(s => s.Key.Contains("Mut")).Value;
+ var IN_Wert = Eigenschaften.First(s => s.Key.Contains("Intuition")).Value;
+ var CH_Wert = Eigenschaften.First(s => s.Key.Contains("Charisma")).Value;
+ var KK_Wert = Eigenschaften["Körperkraft"];
+ var KO__Wert = Eigenschaften["Konstitution"];
+
+ Astralpunkte_Basis = 0;
+
+ Ausdauer_Basis = 0;
+
+ Lebenspunkte_Basis = LE_Wert + (int) (KO__Wert + KK_Wert / 2.0 + 0.5);
+
+ if (Vorteile.Exists(x => x.Name.ToLower().Contains("zauberer")))
+ Astralpunkte_Basis = AE_Wert + (int) ((MU_Wert + IN_Wert + CH_Wert) / 2.0 + 0.5);
+
+ Lebenspunkte_Aktuell = Lebenspunkte_Basis;
+ Astralpunkte_Aktuell = Astralpunkte_Basis;
+ Ausdauer_Aktuell = Ausdauer_Basis;
+ }
+
+
+ private void Load(MemoryStream stream)
+ {
+ var reader = new XmlTextReader(stream);
+ while (reader.Read())
+ {
+ // read until he hits keywords
+ if (reader.NodeType != XmlNodeType.Element) continue;
+
+ switch (reader.Name)
+ {
+ case "Wesen":
+ reader.Skip();
+ break;
+ case "held":
+ Name = reader.GetAttribute("name"); // name
+ break;
+ case "eigenschaft":
+ 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
+ {
+ Vorteile.Add(new Vorteil(
+ reader.GetAttribute("name"),
+ // Convert.ToInt32(reader.GetAttribute("value"))));
+ reader.GetAttribute("value")));
+ }
+ catch
+ {
+ 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"))
+ {
+ Zauber.Add(
+ new Zauber(
+ reader.GetAttribute("name"),
+ reader.GetAttribute("probe")?.Remove(0, 2).Trim(')'),
+ Convert.ToInt32(reader.GetAttribute("value")),
+ reader.GetAttribute("k").ToCharArray()[0],
+ reader.GetAttribute("repraesentation")));
+ reader.Read();
+ }
+
+ break;
+ case "kampfwerte":
+ var atName = reader.GetAttribute("name");
+ reader.Read();
+ var at = Convert.ToInt32(reader.GetAttribute("value"));
+ reader.Read();
+ var pa = Convert.ToInt32(reader.GetAttribute("value"));
+ Kampftalente.Add(new KampfTalent(atName, at, pa));
+ break;
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/DSA_Game/Characters/NPC.cs b/dsa/DSALib/DSA_Game/Characters/NPC.cs
new file mode 100644
index 0000000..105adda
--- /dev/null
+++ b/dsa/DSALib/DSA_Game/Characters/NPC.cs
@@ -0,0 +1,83 @@
+using System;
+using DSALib.Auxiliary;
+using DSALib.Characters;
+
+namespace DSALib.Characters
+{
+ public class Npc : Being, ICharacter
+ {
+ private readonly int mean, stDv;
+
+ public Npc(string name, int mean, int stDv)
+ {
+ this.mean = mean;
+ this.stDv = stDv;
+ Name = name;
+ }
+
+ public string TestTalent(string talent, int tap = 3)
+ {
+ for (var i = 0; i <= 2; i++)
+ {
+ // foreach property, dice and tap
+ var temp = Dice.Roll();
+ var eigenschaft = (int) Math.Round(RandomMisc.Random(stDv, mean));
+
+ if (eigenschaft < temp) tap -= temp - eigenschaft;
+ }
+
+ if (tap >= 0) return $"{Name} vollführt {talent} erfolgreich";
+
+
+ return $"{Name} scheitert an {talent}";
+ }
+
+ public string TestEigenschaft(string eigenschaft, int erschwernis = 0)
+ {
+ var temp = Dice.Roll();
+ var prop = (int) Math.Round(RandomMisc.Random(stDv, stDv));
+
+ if (temp + erschwernis < prop) return $"{Name} vollführt {eigenschaft} erfolgreich";
+
+ return $"{Name} scheitert an {eigenschaft}";
+ }
+
+ public string Angriff(string waffe, int erschwernis = 0)
+ {
+ var temp = Dice.Roll();
+
+ if (temp == 1) return $"{Name} greift kritisch mit {waffe} an";
+
+ if (temp < erschwernis) return $"{Name} greift mit {waffe} an";
+
+ return $"{Name} haut mit {waffe} daneben";
+ }
+
+ public string Parade(string waffe, int erschwernis = 0)
+ {
+ var temp = Dice.Roll();
+
+ if (temp == 1) return $"{Name} pariert mit {waffe} meisterlich";
+
+ if (temp < erschwernis) return $"{Name} pariert mit {waffe} an";
+
+ return $"{Name} schafft es nicht mit {waffe} zu parieren";
+ }
+
+ public string Fernkampf(string waffe, int erschwernis = 0)
+ {
+ var temp = Dice.Roll();
+
+ if (temp == 1) return $"{Name} trifft kritisch mit {waffe}";
+
+ if (temp < erschwernis) return $"{Name} greift mit {waffe} an";
+
+ return $"{Name} schießt mit {waffe} daneben";
+ }
+
+ public string TestZauber(string zauber, int erschwernis)
+ {
+ return TestTalent(zauber, erschwernis);
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/DSA_Game/Characters/SaveChar.cs b/dsa/DSALib/DSA_Game/Characters/SaveChar.cs
new file mode 100644
index 0000000..00e2f86
--- /dev/null
+++ b/dsa/DSALib/DSA_Game/Characters/SaveChar.cs
@@ -0,0 +1,38 @@
+using DSALib.Characters;
+
+namespace DSALib.DSA_Game.Characters
+{
+ public class SaveChar
+ {
+ public string Name { get; set; }
+
+ public int Lebenspunkte_Aktuell { get; set; }
+
+ public int Ausdauer_Aktuell { get; set; }
+
+ public int Astralpunkte_Aktuell { get; set; }
+
+ public static SaveChar FromICharacter(ICharacter c)
+ {
+ return new SaveChar
+ {
+ Astralpunkte_Aktuell = c.Astralpunkte_Aktuell,
+ Ausdauer_Aktuell = c.Ausdauer_Aktuell,
+ Lebenspunkte_Aktuell = c.Lebenspunkte_Aktuell,
+ Name = c.Name
+ };
+ }
+ }
+
+
+ public static class ICharExtension
+ {
+ public static void Update(this ICharacter c, SaveChar s)
+ {
+ c.Astralpunkte_Aktuell = s.Astralpunkte_Aktuell;
+ c.Ausdauer_Aktuell = s.Ausdauer_Aktuell;
+ c.Lebenspunkte_Aktuell = s.Lebenspunkte_Aktuell;
+ c.Name = s.Name;
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/DSA_Game/Dsa.cs b/dsa/DSALib/DSA_Game/Dsa.cs
new file mode 100644
index 0000000..bcd8951
--- /dev/null
+++ b/dsa/DSALib/DSA_Game/Dsa.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using DSALib.DSA_Game.Characters;
+using DSALib.DSA_Game.Save;
+using DSALib;
+using DSALib.Characters;
+using DSALib.Models.Dsa;
+
+namespace DSALib.DSA_Game
+{
+ public static class Dsa
+ {
+#if DEBUG
+ public const string
+ rootPath = ""; //"C:\\Users\\Dennis\\Source\\Repos\\DiscoBot\\DSALib\\";//"DiscoBot\\DSALib\\";
+#else
+ public const string rootPath = "";//"DiscoBot\\DSALib\\";
+#endif
+ private static Session s_session;
+
+ public static List<ICharacter> Chars { get; set; } = new List<ICharacter>(); // list of all characters
+
+ public static List<Talent> Talente { get; set; } = new List<Talent>();
+
+ public static List<Zauber> Zauber { get; set; } = new List<Zauber>();
+
+ public static Session Session
+ {
+ get
+ {
+ s_session.Chars = Chars.Select(x => SaveChar.FromICharacter(x)).ToList();
+ return s_session;
+ }
+
+ set
+ {
+ s_session = value;
+ foreach (var x in value.Chars) Chars.Find(c => c.Name.Equals(x.Name)).Update(x);
+ }
+ }
+
+ public static void Startup()
+ {
+ //new .Auxiliary.Calculator.StringSolver("1d100 - (1d200 + 1) * -50000").Solve();
+ /*Session = new Session();*/
+ // relation.Add("Papo", "Pump aus der Gosse");
+ /*foreach (var filename in Directory.GetFiles(rootPath + "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.Last() as Character)?.Zauber.Select(x => new Zauber(x.Name, x.Probe, 0, x.Complexity))
+ .Where(c => !Zauber.Exists(v => v.Name.Equals(c.Name))).ToList().ForEach(v => Zauber.Add(v));
+ }
+*/
+
+ Properties.Deserialize();
+ Properties.Serialize(rootPath + "Properties");
+
+
+ Talente = Talente.OrderBy(x => x.Name).ToList();
+ Zauber = Zauber.OrderBy(x => x.Name).ToList();
+
+ /*foreach (var talent in Talente)
+ {
+ Database.AddTalent(new Models.Database.Talent(talent.Name, talent.Probe));
+ }
+
+ foreach (var talent in Zauber)
+ {
+ Database.AddSpell(new Models.Database.GeneralSpell(talent.Name, talent.Probe, talent.Complexity));
+ }*/
+
+ //new WeaponImporter().DownloadWeapons().Wait();
+
+
+ Session = new Session
+ {
+ Chars = Chars.Select(SaveChar.FromICharacter).ToList()
+ };
+ //Session.Save();
+ }
+
+ public static ICharacter GetCharacter(ulong id)
+ {
+ throw new NotImplementedException();
+ }
+
+ public static ICharacter GetCharacter(string name, ulong groupId)
+ {
+ throw new NotImplementedException();
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/DSA_Game/Save/Properties.cs b/dsa/DSALib/DSA_Game/Save/Properties.cs
new file mode 100644
index 0000000..2312af0
--- /dev/null
+++ b/dsa/DSALib/DSA_Game/Save/Properties.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using DSALib.Auxiliary;
+using Newtonsoft.Json;
+
+namespace DSALib.DSA_Game.Save
+{
+ public static class Properties
+ {
+ public static Dictionary<string, object> objects;
+
+ static Properties()
+ {
+ objects = new Dictionary<string, object>();
+ /*this.objects.Add("Sounds", new List<Sound>());
+ this.objects.Add("CommandInfos", new List<CommandInfo>());*/
+ }
+
+ public static List<CommandInfo> CommandInfos
+ {
+ get => objects["CommandInfo"] as List<CommandInfo>;
+ set => objects["CommandInfo"] = value;
+ } // use Properties.Commandinfos to access the abstract Object array
+
+
+ public static void Deserialize(string path = @"Properties")
+ {
+ var files = Directory.GetFiles(path, "*.json");
+
+ foreach (var file in files)
+ try
+ {
+ var name = file.Split('\\').Last().Split('.')[0].Replace('-', '.');
+ var data = File.ReadAllText(file);
+ var type = Type.GetType(name);
+ if (data.StartsWith("[")) type = typeof(List<>).MakeGenericType(type);
+
+ var o = JsonConvert.DeserializeObject(data, type);
+ objects.Add(name.Split('.').Last(), o);
+ }
+ catch (Exception e)
+ {
+ // ignored
+ Console.WriteLine($"Laden von Save-File {file} fehlgeschlagen." + e);
+ }
+ }
+
+ public static void Serialize(string path = @"..\..\Properties\")
+ {
+ try
+ {
+ foreach (var o in objects)
+ {
+ var assembly = o.Value is IList list
+ ? list[0]?.GetType().FullName
+ : o.Value.GetType().FullName;
+
+ var name = path + assembly.Replace('.', '-') + ".json";
+ File.WriteAllText(name,
+ JsonConvert.SerializeObject(o.Value,
+ Formatting.Indented)); // Deserialize Data and create CommandInfo Struct
+ }
+ }
+ catch (Exception e)
+ {
+ // ignored
+ Console.WriteLine("Speichern von Save-File fehlgeschlagen." + e);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/DSA_Game/Save/SaveCommand.cs b/dsa/DSALib/DSA_Game/Save/SaveCommand.cs
new file mode 100644
index 0000000..c5a1bb4
--- /dev/null
+++ b/dsa/DSALib/DSA_Game/Save/SaveCommand.cs
@@ -0,0 +1,66 @@
+using System;
+using System.IO;
+using System.Linq;
+
+namespace DSALib.DSA_Game.Save
+{
+ public class SaveCommand
+ {
+ public void LoadSession(string name = "")
+ {
+ if (name.Equals("?") || name.Equals(string.Empty))
+ {
+ Console.WriteLine("Gespeicherte Sessions:");
+ Console.WriteLine(ListSessions());
+ return;
+ }
+
+ var path = Session.DirectoryPath + @"\" + name;
+
+ var files = Directory.GetFiles(path);
+ var session = files.OrderByDescending(x => Convert.ToInt32(x.Split('-').Last().Split('.').First())).First();
+ Dsa.Session = Session.Load(session);
+
+ Console.WriteLine($"{name} wurde geladen");
+ }
+
+ public void SessionSave(string name = "")
+ {
+ //var sendFile = this.Context.Channel.SendWebFile("https://cdn.discordapp.com/attachments/377123019673567232/465615882048110603/giphy.gif");
+
+ if (name.Equals("?") || name.Equals(string.Empty))
+ {
+ Console.WriteLine("Gespeicherte Sessions:");
+ Console.WriteLine(ListSessions());
+ return;
+ }
+
+ var path = Session.DirectoryPath + @"\" + name;
+ if (Directory.Exists(path))
+ {
+ var files = Directory.GetFiles(path);
+ var current = files.Max(x => Convert.ToInt32(x.Split('-').Last().Split('.').First()));
+ Dsa.Session.SessionName = name;
+ Dsa.Session.Save(path + "\\" + name + $"-{++current}.json");
+ }
+ else
+ {
+ Directory.CreateDirectory(path);
+ Dsa.Session.SessionName = name;
+ Dsa.Session.Save(path + "\\" + name + "-0.json");
+ }
+
+ Console.WriteLine($"{name} wurde gespeichert");
+ //await sendFile;
+ }
+
+ private string[] ListSessions()
+ {
+ var dirs = Directory.GetDirectories(Session.DirectoryPath)
+ .OrderByDescending(x => new DirectoryInfo(x).LastAccessTime.Ticks).ToArray();
+ for (var i = 0; i < dirs.Length; i++) dirs[i] += "; " + new DirectoryInfo(dirs[i]).LastAccessTime;
+
+ return dirs;
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/DSA_Game/Save/Session.cs b/dsa/DSALib/DSA_Game/Save/Session.cs
new file mode 100644
index 0000000..62aa8f6
--- /dev/null
+++ b/dsa/DSALib/DSA_Game/Save/Session.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using DSALib.DSA_Game.Characters;
+using Newtonsoft.Json;
+
+namespace DSALib.DSA_Game.Save
+{
+ public class Session
+ {
+ public static string DirectoryPath { get; set; } = Dsa.rootPath + @"sessions";
+
+ public Dictionary<string, string> Relation { get; set; } =
+ new Dictionary<string, string>(); // dictionary to match the char
+
+ public List<SaveChar> Chars { get; set; } = new List<SaveChar>(); // list of all characters
+
+ public string SessionName { get; set; }
+
+ public static Session Load(string path)
+ {
+ try
+ {
+ return
+ JsonConvert.DeserializeObject<Session>(
+ File.ReadAllText(path)); // Deserialize Data and create Session Object
+ }
+ catch (Exception e)
+ {
+ // ignored
+ Console.WriteLine($"Laden von Save-File {path} fehlgeschlagen." + e);
+ return null;
+ }
+ }
+
+ public void Save(string path)
+ {
+ try
+ {
+ File.WriteAllText(path,
+ JsonConvert.SerializeObject(this,
+ Formatting.Indented)); // Deserialize Data and create CommandInfo Struct
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Speichern von Save-File {path} fehlgeschlagen.\n" + e);
+ // ignored
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/FireBase/Database.cs b/dsa/DSALib/FireBase/Database.cs
new file mode 100644
index 0000000..1edd699
--- /dev/null
+++ b/dsa/DSALib/FireBase/Database.cs
@@ -0,0 +1,270 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using DSALib.DSA_Game;
+using DSALib.DSA_Game.Characters;
+using DSALib.Models.Database.Dsa;
+using Firebase.Database;
+using Firebase.Database.Query;
+
+namespace DSALib.FireBase
+{
+ public static class Database
+ {
+ public static FirebaseClient Firebase;
+
+ public static Dictionary<string, DatabaseChar> Chars = new Dictionary<string, DatabaseChar>();
+
+ public static Dictionary<string, MeleeWeapon> MeleeList = new Dictionary<string, MeleeWeapon>();
+
+ public static Dictionary<string, RangedWeapon> RangedWeapons = new Dictionary<string, RangedWeapon>();
+
+ public static Dictionary<string, DSALib.Models.Database.Dsa.Talent> Talents = new Dictionary<string, DSALib.Models.Database.Dsa.Talent>();
+
+ public static Dictionary<string, GeneralSpell> Spells = new Dictionary<string, GeneralSpell>();
+
+ static Database()
+ {
+ var auth = File.ReadAllText(Dsa.rootPath + "Token"); // your app secret
+ Firebase = new FirebaseClient(
+ "https://heldenonline-4d828.firebaseio.com/",
+ new FirebaseOptions
+ {
+ AuthTokenAsyncFactory = () => Task.FromResult(auth)
+ });
+
+ Task.Run(Initialize);
+ }
+
+ private static void Initialize() {
+ var waiting = new[] {
+ // ToDo IntializeCollection("Chars", Chars),
+ IntializeCollection("MeleeWeapons", MeleeList),
+ IntializeCollection("RangedWeapons", RangedWeapons),
+ IntializeCollection("Talents", Talents),
+ IntializeCollection("Spells", Spells),
+ };
+ Task.WaitAll(waiting);
+ }
+
+ private static async Task IntializeCollection<T>(string path, Dictionary<string, T> list)
+ {
+ var temp = await Firebase
+ .Child(path)
+ .OrderByKey()
+ .OnceAsync<T>();
+
+ foreach (var firebaseObject in temp) list.Add(firebaseObject.Key, firebaseObject.Object);
+ }
+
+ public static async Task<int> AddChar(Character file, string group)
+ {
+ DatabaseChar.LoadChar(file, out var groupChar, out var data);
+
+ var lastChar = await Firebase
+ .Child("Chars")
+ .OrderByKey()
+ .LimitToLast(1)
+ .OnceAsync<DatabaseChar>();
+ var id = groupChar.Id = data.Id = lastChar.First().Object.Id + 1;
+
+ await Firebase //TODO Reomve await Operators
+ .Child("Groups")
+ .Child("Char" + id)
+ .PutAsync(groupChar);
+
+ await Firebase
+ .Child("Chars")
+ .Child("Char" + id)
+ .PutAsync(data);
+
+ Chars["Char" + id] = data;
+
+ await Firebase
+ .Child("Inventories")
+ .Child("Inventory" + id)
+ .PutAsync(new Inventory());
+
+ return id + 1;
+ }
+
+ public static async Task RemoveChar(int id)
+ {
+ await Firebase
+ .Child("Groups")
+ .Child("Char" + id)
+ .DeleteAsync();
+
+ await Firebase
+ .Child("Chars")
+ .Child("Char" + id)
+ .DeleteAsync();
+
+ Chars.Remove("Char" + id);
+
+ await Firebase
+ .Child("Inventories")
+ .Child("Inventory" + id)
+ .DeleteAsync();
+ }
+
+ public static DatabaseChar GetChar(int id)
+ {
+ /*var chr = await firebase
+ .Child("Chars")
+ .Child("Char" + id)
+ .OnceSingleAsync<DatabaseChar>();
+ return chr;*/
+ return Chars["Char" + id];
+ }
+
+ public static async Task<Inventory> GetInventory(int id)
+ {
+ var inv = await Firebase
+ .Child("Inventories")
+ .Child("Inventory" + id)
+ .OnceSingleAsync<Inventory>();
+ return inv;
+ }
+
+ public static async Task SetInventory(int id, Inventory inv)
+ {
+ await Firebase
+ .Child("Inventories")
+ .Child("Inventory" + id)
+ .PutAsync(inv);
+ }
+
+ public static async Task AddTalent(DSALib.Models.Database.Dsa.Talent tal)
+ {
+ await Firebase
+ .Child("Talents")
+ .Child(tal.Name)
+ .PutAsync(tal);
+ }
+
+ public static async Task RemoveTalent(string talent)
+ {
+ await Firebase
+ .Child("Talents")
+ .Child(talent)
+ .DeleteAsync();
+ }
+
+ public static DSALib.Models.Database.Dsa.Talent GetTalent(string talent)
+ {
+ /*
+ return await firebase
+ .Child("Talents")
+ .Child(talent)
+ .OnceSingleAsync<Talent>();*/
+ return Talents[talent];
+ }
+
+ public static async Task AddSpell(GeneralSpell tal)
+ {
+ await Firebase
+ .Child("Spells")
+ .Child(tal.Name)
+ .PutAsync(tal);
+ }
+
+ public static async Task RemoveSpell(string spell)
+ {
+ await Firebase
+ .Child("Spells")
+ .Child(spell)
+ .DeleteAsync();
+ }
+
+ public static GeneralSpell GetSpell(string spell)
+ {
+ return Spells[spell];
+ }
+
+
+ public static async Task AddWeapon(Weapon wep)
+ {
+ var collection = wep.GetType() == typeof(MeleeWeapon) ? "MeleeWeapons" : "RangedWeapons";
+ await Firebase
+ .Child(collection)
+ .Child(wep.Name)
+ .PutAsync(wep);
+ }
+
+ public static async Task RemoveWeapon(string weapon, bool ranged = false)
+ {
+ var collection = ranged ? "RangedWeapons" : "MeleeWeapons";
+ await Firebase
+ .Child(collection)
+ .Child(weapon)
+ .DeleteAsync();
+ }
+
+ public static async Task<Weapon> GetWeapon(string weapon, bool ranged = false)
+ {
+ var collection = ranged ? "RangedWeapons" : "MeleeWeapons";
+ return await Firebase
+ .Child(collection)
+ .Child(weapon)
+ .OnceSingleAsync<Weapon>();
+ }
+
+ public static async Task<List<Tuple<string, string>>> GetGroups()
+ {
+ var groups = await Firebase
+ .Child("Groups")
+ .OrderByKey()
+ .OnceAsync<DSALib.Models.Database.Groups.Group>();
+ var ret = new List<Tuple<string, string>>();
+
+ foreach (var firebaseObject in groups)
+ ret.Add(new Tuple<string, string>(firebaseObject.Object.Name, firebaseObject.Object.Password));
+
+ return ret;
+ }
+
+ public static async Task<DSALib.Models.Database.Groups.Group> GetGroup(int id)
+ {
+ var group = await Firebase
+ .Child("Groups")
+ .Child("Group" + id)
+ .OnceSingleAsync<DSALib.Models.Database.Groups.Group>();
+ return group;
+ }
+
+ public static async Task AddGroup(DSALib.Models.Database.Groups.Group group)
+ {
+ var lastChar = await Firebase
+ .Child("Groups")
+ .OrderByKey()
+ .LimitToLast(1)
+ .OnceAsync<DSALib.Models.Database.Groups.Group>();
+ var id = group.Id = lastChar.First().Object.Id + 1;
+
+ await Firebase
+ .Child("Groups")
+ .Child("Group" + id)
+ .PutAsync(group);
+ }
+
+ public static async void SetGroup(DSALib.Models.Database.Groups.Group group)
+ {
+ await Firebase
+ .Child("Groups")
+ .Child("Group" + group.Id)
+ .PutAsync(group);
+ }
+
+ public static async void DeleteGroup(int id)
+ {
+ await Firebase
+ .Child("Groups")
+ .Child("Group" + id)
+ .DeleteAsync();
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/DataObject.cs b/dsa/DSALib/Models/Database/DataObject.cs
new file mode 100644
index 0000000..59cfdf2
--- /dev/null
+++ b/dsa/DSALib/Models/Database/DataObject.cs
@@ -0,0 +1,13 @@
+namespace DSALib.Models.Database
+{
+ public class DataObject : IDataObject
+ {
+
+ public override string ToString()
+ {
+ return Name;
+ }
+
+ public string Name { get; set; }
+ }
+}
diff --git a/dsa/DSALib/Models/Database/Dsa/Advantage.cs b/dsa/DSALib/Models/Database/Dsa/Advantage.cs
new file mode 100644
index 0000000..2ed0bf9
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/Advantage.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace DSALib.Models.Database.Dsa
+{
+ public class Advantage
+ {
+ public Advantage(string name, string value = "")
+ {
+ Name = name ?? throw new ArgumentNullException(nameof(name));
+ Value = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
+ public string Name { get; set; }
+ public string Value { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Dsa/CharSpell.cs b/dsa/DSALib/Models/Database/Dsa/CharSpell.cs
new file mode 100644
index 0000000..d08bc74
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/CharSpell.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace DSALib.Models.Database.Dsa
+{
+ public class CharSpell
+ {
+ public CharSpell(string representation, int value)
+ {
+ this.representation = representation ?? throw new ArgumentNullException(nameof(representation));
+ this.value = value;
+ }
+
+ public string representation { get; set; }
+ public int value { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Dsa/DatabaseChar.cs b/dsa/DSALib/Models/Database/Dsa/DatabaseChar.cs
new file mode 100644
index 0000000..1312f95
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/DatabaseChar.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using DSALib.DSA_Game.Characters;
+
+namespace DSALib.Models.Database.Dsa
+{
+ public class DatabaseChar
+ {
+ public DatabaseChar()
+ {
+ }
+
+ public DatabaseChar(int id, string name, string rasse, List<Field> skills, List<Field> talents,
+ List<Advantage> advantages, List<CharSpell> spells, List<WeaponTalent> weaponTalents)
+ {
+ Id = id;
+ Name = name ?? throw new ArgumentNullException(nameof(name));
+ Race = rasse ?? throw new ArgumentNullException(nameof(rasse));
+ Skills = skills ?? throw new ArgumentNullException(nameof(skills));
+ Talents = talents ?? throw new ArgumentNullException(nameof(talents));
+ Advantages = advantages ?? throw new ArgumentNullException(nameof(advantages));
+ Spells = spells ?? throw new ArgumentNullException(nameof(spells));
+ WeaponTalents = weaponTalents ?? throw new ArgumentNullException(nameof(weaponTalents));
+ }
+
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+
+ public string Race { get; set; }
+
+ public List<Field> Skills { get; set; } = new List<Field>();
+
+ public List<Field> Talents { get; set; } = new List<Field>();
+
+ public List<Advantage> Advantages { get; set; } = new List<Advantage>();
+
+ public List<CharSpell> Spells { get; set; } = new List<CharSpell>();
+
+ public List<WeaponTalent> WeaponTalents { get; set; } = new List<WeaponTalent>();
+
+
+ public static void LoadChar(Character file, out GroupChar group, out DatabaseChar data)
+ {
+ group = new GroupChar();
+ data = new DatabaseChar();
+
+ group.Name = file.Name.Split(' ').First();
+ group.Weapon = new Weapon();
+ group.Lp = group.LpMax = file.Lebenspunkte_Basis;
+ group.As = group.AsMax = file.Astralpunkte_Basis;
+ group.Weapon = new Weapon();
+
+ data.Name = file.Name;
+ data.Advantages = file.Vorteile.Select(x => new Advantage(x.Name, x.Value)).ToList();
+ data.Skills = file.Eigenschaften.Select(x => new Field(x.Key, x.Value)).ToList();
+ data.Spells = file.Zauber.Select(x => new CharSpell(x.Representation, x.Value)).ToList();
+ data.Talents = file.Talente.Select(x => new Field(x.Name, x.Value)).ToList();
+ data.WeaponTalents = file.Kampftalente.Select(x => new WeaponTalent(x.Name, x.At, x.Pa)).ToList();
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Dsa/Field.cs b/dsa/DSALib/Models/Database/Dsa/Field.cs
new file mode 100644
index 0000000..6d1b82e
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/Field.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace DSALib.Models.Database.Dsa
+{
+ public class Field
+ {
+ public Field(string name, int value = 0)
+ {
+ Name = name ?? throw new ArgumentNullException(nameof(name));
+ Value = value;
+ }
+
+ public string Name { get; set; }
+ public int Value { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Dsa/GeneralSpell.cs b/dsa/DSALib/Models/Database/Dsa/GeneralSpell.cs
new file mode 100644
index 0000000..964c38e
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/GeneralSpell.cs
@@ -0,0 +1,20 @@
+namespace DSALib.Models.Database.Dsa
+{
+ public class GeneralSpell : Talent
+ {
+ public char Comlexity = 'A';
+
+ public GeneralSpell(string name, string roll, char comlexity = 'A') : base(name, roll)
+ {
+ Comlexity = comlexity;
+ }
+
+ public GeneralSpell(string name, string roll) : base(name, roll)
+ {
+ }
+
+ public GeneralSpell()
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Dsa/GroupChar.cs b/dsa/DSALib/Models/Database/Dsa/GroupChar.cs
new file mode 100644
index 0000000..a0115cd
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/GroupChar.cs
@@ -0,0 +1,13 @@
+namespace DSALib.Models.Database.Dsa
+{
+ public class GroupChar
+ {
+ public string Name { get; set; }
+ public int Id { get; set; }
+ public int Lp { get; set; }
+ public int LpMax { get; set; }
+ public int As { get; set; }
+ public int AsMax { get; set; }
+ public Weapon Weapon { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Dsa/Inventory.cs b/dsa/DSALib/Models/Database/Dsa/Inventory.cs
new file mode 100644
index 0000000..f3f5d7a
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/Inventory.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+
+namespace DSALib.Models.Database.Dsa
+{
+ public class Inventory
+ {
+ public int Id { get; set; }
+ public Dictionary<string, bool> Items { get; set; } = new Dictionary<string, bool>();
+ public Dictionary<string, bool> Food { get; set; } = new Dictionary<string, bool>();
+ public List<Weapon> Weapons { get; set; } = new List<Weapon>();
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Dsa/Talent.cs b/dsa/DSALib/Models/Database/Dsa/Talent.cs
new file mode 100644
index 0000000..214aecc
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/Talent.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace DSALib.Models.Database.Dsa
+{
+ public class Talent : DSALib.Models.Database.DataObject
+ {
+ public Talent()
+ {
+ }
+
+ public Talent(string name)
+ {
+ Name = name ?? throw new ArgumentNullException(nameof(name));
+ }
+
+ public Talent(string name, string roll)
+ {
+ Name = name ?? throw new ArgumentNullException(nameof(name));
+ Roll = roll.Split('/');
+ }
+
+ public string[] Roll { get; set; } = new string[3];
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Dsa/Weapon.cs b/dsa/DSALib/Models/Database/Dsa/Weapon.cs
new file mode 100644
index 0000000..308c6c5
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/Weapon.cs
@@ -0,0 +1,52 @@
+using System;
+
+namespace DSALib.Models.Database.Dsa
+{
+ public class Weapon
+ {
+ public Weapon()
+ {
+ }
+
+ public Weapon(string name, string damage, int weight, string weaponTalent, string price)
+ {
+ Name = name ?? throw new ArgumentNullException(nameof(name));
+ Damage = damage ?? throw new ArgumentNullException(nameof(damage));
+ Weight = weight;
+ WeaponTalent = weaponTalent ?? throw new ArgumentNullException(nameof(weaponTalent));
+ Price = price;
+ }
+
+ public string Name { get; set; }
+ public string Damage { get; set; }
+ public int Weight { get; set; }
+ public string WeaponTalent { get; set; }
+ public string Price { get; set; }
+ }
+
+ public class MeleeWeapon : Weapon
+ {
+ public MeleeWeapon(string name, string damage, int weight, string weaponTalent, string price) : base(name,
+ damage, weight, weaponTalent, price)
+ {
+ }
+
+ public string TpKK { get; set; }
+ public int INI { get; set; }
+ public string MW { get; set; }
+ }
+
+ public class RangedWeapon : Weapon
+ {
+ public RangedWeapon(string name, string damage, int weight, string weaponTalent, string price) : base(name,
+ damage, weight, weaponTalent, price)
+ {
+ }
+
+ public int AtMod { get; set; }
+ public int KKMod { get; set; }
+ public string AtReach { get; set; }
+ public string TpReach { get; set; }
+ public int LoadTime { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Dsa/WeaponTalent.cs b/dsa/DSALib/Models/Database/Dsa/WeaponTalent.cs
new file mode 100644
index 0000000..2ab921b
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Dsa/WeaponTalent.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace DSALib.Models.Database.Dsa
+{
+ public class WeaponTalent
+ {
+ public WeaponTalent(string name, int at, int pa)
+ {
+ Name = name ?? throw new ArgumentNullException(nameof(name));
+ At = at;
+ Pa = pa;
+ }
+
+ public string Name { get; set; }
+ public int At { get; set; }
+ public int Pa { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Groups/DSAGroup.cs b/dsa/DSALib/Models/Database/Groups/DSAGroup.cs
new file mode 100644
index 0000000..adbd0ac
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Groups/DSAGroup.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+using DSALib.Models.Database.Dsa;
+
+namespace DSALib.Models.Database.Groups
+{
+ public class DsaGroup : Group
+ {
+ public List<GroupChar> Chars { get; set; } = new List<GroupChar>();
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/Groups/Group.cs b/dsa/DSALib/Models/Database/Groups/Group.cs
new file mode 100644
index 0000000..096f2be
--- /dev/null
+++ b/dsa/DSALib/Models/Database/Groups/Group.cs
@@ -0,0 +1,9 @@
+namespace DSALib.Models.Database.Groups
+{
+ public class Group
+ {
+ public string Name { get; set; }
+ public string Password { get; set; }
+ public int Id { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Database/IDataObject.cs b/dsa/DSALib/Models/Database/IDataObject.cs
new file mode 100644
index 0000000..bdc88b7
--- /dev/null
+++ b/dsa/DSALib/Models/Database/IDataObject.cs
@@ -0,0 +1,7 @@
+namespace DSALib.Models.Database
+{
+ public interface IDataObject
+ {
+ string Name { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Dsa/CritterAttack.cs b/dsa/DSALib/Models/Dsa/CritterAttack.cs
new file mode 100644
index 0000000..8cd8b09
--- /dev/null
+++ b/dsa/DSALib/Models/Dsa/CritterAttack.cs
@@ -0,0 +1,19 @@
+namespace DSALib.Models.Dsa
+{
+ public class CritterAttack : Database.DataObject
+ {
+ public CritterAttack(string name, int at, string tp, string comment = "")
+ {
+ Name = name;
+ At = at;
+ Tp = tp;
+ Comment = comment;
+ }
+
+ public int At { get; set; }
+
+ public string Tp { get; set; }
+
+ public string Comment { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Dsa/KampfTalent.cs b/dsa/DSALib/Models/Dsa/KampfTalent.cs
new file mode 100644
index 0000000..51ad255
--- /dev/null
+++ b/dsa/DSALib/Models/Dsa/KampfTalent.cs
@@ -0,0 +1,16 @@
+namespace DSALib.Models.Dsa
+{
+ public class KampfTalent : Database.DataObject
+ {
+ public KampfTalent(string name, int at, int pa)
+ {
+ Name = name;
+ At = at;
+ Pa = pa;
+ }
+
+ public int At { get; set; }
+
+ public int Pa { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Dsa/Talent.cs b/dsa/DSALib/Models/Dsa/Talent.cs
new file mode 100644
index 0000000..5771a74
--- /dev/null
+++ b/dsa/DSALib/Models/Dsa/Talent.cs
@@ -0,0 +1,43 @@
+namespace DSALib.Models.Dsa
+{
+ public class Talent : Database.DataObject // talent objekt
+ {
+ public Talent(string name, string probe, int value)
+ {
+ Name = name;
+ Probe = probe;
+ Value = value;
+ }
+
+ public string Probe { get; set; }
+
+ public int Value { get; set; }
+
+ public string[] GetEigenschaften() // turn XX/XX/XX into string[]{XX,XX,XX}
+ {
+ var temp = Probe.Split('/');
+ for (var index = 0; index < temp.Length; index++) temp[index] = temp[index].Replace("/", string.Empty);
+
+ return temp;
+ }
+
+ public bool IstFernkampftalent()
+ {
+ switch (Name)
+ {
+ case "Armbrust":
+ case "Belagerungswaffen":
+ case "Blasrohr":
+ case "Bogen":
+ case "Diskus":
+ case "Schleuder":
+ case "Wurfbeile":
+ case "Wurfmesser":
+ case "Wurfspeere":
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Dsa/Vorteil.cs b/dsa/DSALib/Models/Dsa/Vorteil.cs
new file mode 100644
index 0000000..e37af20
--- /dev/null
+++ b/dsa/DSALib/Models/Dsa/Vorteil.cs
@@ -0,0 +1,16 @@
+namespace DSALib.Models.Dsa
+{
+ public class Vorteil : Database.DataObject // talent objekt
+ {
+ public Vorteil(string name, string value = "")
+ {
+ Name = name;
+ Value = value;
+ // this.Choice = choice;
+ }
+
+ public string Value { get; set; }
+
+ //public string Choice { get; set; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Dsa/Zauber.cs b/dsa/DSALib/Models/Dsa/Zauber.cs
new file mode 100644
index 0000000..e4387bf
--- /dev/null
+++ b/dsa/DSALib/Models/Dsa/Zauber.cs
@@ -0,0 +1,16 @@
+namespace DSALib.Models.Dsa
+{
+ public class Zauber : Talent
+ {
+ public Zauber(string name, string probe, int value, char complexity = 'A', string representation = "Magier")
+ : base(name, probe, value)
+ {
+ Complexity = complexity;
+ Representation = Representation;
+ }
+
+ public char Complexity { get; }
+
+ public string Representation { get; }
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Network/Command.cs b/dsa/DSALib/Models/Network/Command.cs
new file mode 100644
index 0000000..5a97e88
--- /dev/null
+++ b/dsa/DSALib/Models/Network/Command.cs
@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace DSALib.Models.Network
+{
+ public class Command
+ {
+ public ulong GroupId { get; set; } = 0;
+ public ulong CharId { get; set; }
+ public string Name { get; set; }
+ public string CmdIdentifier { get; set; }
+ public List<string> CmdTexts { get; set; }
+ public string CmdText => CmdTexts.Count != 0 ? CmdTexts.First() : "";
+
+ public int Cmdmodifier => CmdTexts.Count != 0 && int.TryParse(CmdTexts.Last(), out var mod) ? mod : 0;
+ public bool IsDm { get; set; } = false;
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Models/Network/CommandResponse.cs b/dsa/DSALib/Models/Network/CommandResponse.cs
new file mode 100644
index 0000000..0816e4a
--- /dev/null
+++ b/dsa/DSALib/Models/Network/CommandResponse.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace DSALib.Models.Network
+{
+ public class CommandResponse
+ {
+ public CommandResponse(string message, ResponseType responseType = ResponseType.Broadcast)
+ {
+ this.message = message ?? throw new ArgumentNullException(nameof(message));
+ ResponseType = responseType;
+ }
+
+ public string message { get; }
+ public ResponseType ResponseType { get; }
+
+ public override string ToString()
+ {
+ return message;
+ }
+ }
+
+ public enum ResponseType
+ {
+ Broadcast,
+ Caller,
+ Error
+ }
+} \ No newline at end of file
diff --git a/dsa/DSALib/Properties-DSACore-Auxiliary-CommandInfo.json b/dsa/DSALib/Properties-DSACore-Auxiliary-CommandInfo.json
new file mode 100644
index 0000000..b9941f2
--- /dev/null
+++ b/dsa/DSALib/Properties-DSACore-Auxiliary-CommandInfo.json
@@ -0,0 +1,101 @@
+[
+ {
+ "Name": "ich bin",
+ "Scope": "All",
+ "Brief": "Setzt den gespielten Charakter fest",
+ "Description": [
+ "Mit \"!Ich bin\" kann der gespielte Charakter definiert, bzw. gewechselt werden.\n",
+ " Die Charaktere müssen als *.xml Dateien hinterlegt sein.\n\n",
+ " !ich Zeigt an welcher Charakter zur Zeit gespielt wird\n",
+ " !ich bin Zalibius Wechsel zum Helden Zalibius\n",
+ " !ich Rhoktar Orkische Variante von !ich bin.\n",
+ " Wechselt zu Rhoktar.\n\n",
+ " !list chars Zeigt die Liste verfügbarer Charaktere.\n",
+ " \n"
+ ]
+ },
+ {
+ "Name": "List",
+ "Scope": "All",
+ "Brief": "Anzeige vonSpielrelevanten Listen",
+ "Description": [
+ "Mit \"!list\" lassen sich spielrelevante Listen ausgeben. Die Angezeigte Liste wird nach einiger Zeit wieder gelöscht.\n",
+ "\n",
+ " !list chars Liste aller verfügbaren Helden (eingelesen per *.xml)\n",
+ " und NSCs.\n",
+ " (Mit \"!ich bin\" kann der Held ausgewählt werden.)\n",
+ " !list commands Liste aller verwendbaren Bot-Kommandos.\n",
+ " !list sounds Liste der Soundeffekte."
+ ]
+ },
+ {
+ "Name": "Held",
+ "Scope": "All",
+ "Brief": "Anzeige von Heldenwerten",
+ "Description": [
+ "Mit \"!Held\" lassen sich Heldenwerte ausgeben. Mehrere Werte können gleichzeitig angefordert werde. \"!Held LE Waffen\" liefert so z.B. Informationen zur Lebensenergie und den Kampfwerten.\n Bis auf wenige Ausnahmen wird die Angezeigte Liste nach einiger Zeit wieder gelöscht.\n",
+ "\n",
+ " !Held Zeigt den Heldenbrief an.\n",
+ " (Diese Liste wird nicht automatisch gelöscht)\n",
+ " !Held Eigenschaften Zeigt die Eigenschaften MU/KL/CH/IN/KK/GE/FF/KO.\n",
+ " !Held e Kurzform von \"!Held Eigenschaften\".\n",
+ " !Held LE Zeigt LE an.\n",
+ " !Held AE Zeigt AE an.\n",
+ " !Held stats Zeigt Eigenschaften und zusätzlich SO/LE/AE.\n",
+ " !Held Kampfwerte Zeigt AT/PA für aktivierte Waffentalente.\n",
+ " !Held Waffe/!list w Kurzformen von \"!Held Kampfwerte\".\n",
+ " !Held Vorteile Zeigt Vor- und Nachteile an.\n",
+ " !Held v Kurzform von \"!Held Vorteile\".\n",
+ " !Held Talente Zeigt die Liste aller aktivierten Talente, deren TaW,\n",
+ " sowie die Probe.\n",
+ " !Held t Kurzform von \"!Held Talente\".\n",
+ " !Held Zauber Zeigt die Liste aller aktivierten Zauber, deren ZaW,\n",
+ " sowie die Probe.\n",
+ " !Held z Kurzform von \"!Held Zauber\".\n"
+ ]
+ },
+ {
+ "Name": "LE",
+ "Scope": "All",
+ "Brief": "Ändert dein Leben - im wahrsten Sinne des Wortes",
+ "Description": [
+ "Mit !LE zeigt man die Lebensenergie an, ändert sie, oder setzt sie auf einen neuen Wert\n\n",
+ " !LE Zeigt Lebensenergie an\n",
+ " !LE 30 Setzt LE auf 30\n",
+ " !LE +5 Erhöht LE um 5 (bis zum Maximum)\n",
+ " !LE ++5 Erhöht LE um 5 (ignoriert Maximum)\n",
+ " !LE -5 Verringert LE um 5\n \n"
+ ]
+ },
+ {
+ "Name": "AE",
+ "Scope": "All",
+ "Brief": "Ändert Astralenergie",
+ "Description": [
+ "Mit !AE (oder !Asp) zeigt man die Astralenergie an, ändert sie, oder setzt sie auf einen neuen Wert\n\n",
+ " !AE Zeigt Astralenergie an\n",
+ " !AE 30 Setzt Asp auf 30\n",
+ " !AE +5 Erhöht Asp um 5 (bis zum Maximum)\n",
+ " !AE ++5 Erhöht Asp um 5 (ignoriert Maximum)\n",
+ " !AE -5 Verringert Asp um 5 (Minimum 0)\n"
+ ]
+ },
+ {
+ "Name": "Gm",
+ "Scope": "Meister",
+ "Brief": "Kontrolliere andere Charaktere",
+ "Description": [
+ "Mit !GM fürhrt man commands als eine andere Person aus.",
+ " !GM [charaktername] [command] [commandattribut] [mofifier]",
+ " Unterstützte [commands]'s:",
+ " !GM [name] LE",
+ " !GM [name] AE",
+ " !GM [name] Talent",
+ " !GM [name] Fernkampf",
+ " !GM [name] Eigenschaft",
+ " !GM [name] Zauber",
+ " !GM [name] Angriff",
+ " !GM [name] Parade"
+ ]
+ }
+] \ No newline at end of file
diff --git a/dsa/DSALib/Properties-DSACore-DSA_Game-Characters-Character.json b/dsa/DSALib/Properties-DSACore-DSA_Game-Characters-Character.json
new file mode 100644
index 0000000..fd387f5
--- /dev/null
+++ b/dsa/DSALib/Properties-DSACore-DSA_Game-Characters-Character.json
@@ -0,0 +1,290 @@
+[
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 30,
+ "Lebenspunkte_Aktuell": 30,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 20,
+ "Astralpunkte_Aktuell": 20,
+ "Name": "Felis Exodus Schattenwald"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 29,
+ "Lebenspunkte_Aktuell": 29,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 0,
+ "Astralpunkte_Aktuell": 0,
+ "Name": "Gardist"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 31,
+ "Lebenspunkte_Aktuell": 31,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 0,
+ "Astralpunkte_Aktuell": 0,
+ "Name": "Hartmut Reiher"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 21,
+ "Lebenspunkte_Aktuell": 21,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 35,
+ "Astralpunkte_Aktuell": 35,
+ "Name": "Helga vom Drachenei, Tausendsasserin"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 25,
+ "Lebenspunkte_Aktuell": 25,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 0,
+ "Astralpunkte_Aktuell": 0,
+ "Name": "Krenko"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 39,
+ "Lebenspunkte_Aktuell": 39,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 0,
+ "Astralpunkte_Aktuell": 0,
+ "Name": "Ledur Torfinson"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 26,
+ "Lebenspunkte_Aktuell": 26,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 13,
+ "Astralpunkte_Aktuell": 13,
+ "Name": "Morla"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 28,
+ "Lebenspunkte_Aktuell": 28,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 40,
+ "Astralpunkte_Aktuell": 40,
+ "Name": "Numeri Illuminus"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 39,
+ "Lebenspunkte_Aktuell": 39,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 16,
+ "Astralpunkte_Aktuell": 16,
+ "Name": "Potus"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 18,
+ "Lebenspunkte_Aktuell": 18,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 13,
+ "Astralpunkte_Aktuell": 13,
+ "Name": "Pump aus der Gosse"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 34,
+ "Lebenspunkte_Aktuell": 34,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 17,
+ "Astralpunkte_Aktuell": 17,
+ "Name": "Rhoktar4"
+ },
+ {
+ "Eigenschaften": {},
+ "Talente": [],
+ "Zauber": [],
+ "Kampftalente": [],
+ "Vorteile": [],
+ "PropTable": {
+ "MU": "Mut",
+ "KL": "Klugheit",
+ "IN": "Intuition",
+ "CH": "Charisma",
+ "FF": "Fingerfertigkeit",
+ "GE": "Gewandtheit",
+ "KO": "Konstitution",
+ "KK": "Körperkraft"
+ },
+ "Lebenspunkte_Basis": 28,
+ "Lebenspunkte_Aktuell": 28,
+ "Ausdauer_Basis": 0,
+ "Ausdauer_Aktuell": 0,
+ "Astralpunkte_Basis": 43,
+ "Astralpunkte_Aktuell": 43,
+ "Name": "Volant"
+ }
+] \ No newline at end of file
diff --git a/dsa/DSALib/PropertiesNewtonsoft-Json-Linq-JProperty.json b/dsa/DSALib/PropertiesNewtonsoft-Json-Linq-JProperty.json
new file mode 100644
index 0000000..2544397
--- /dev/null
+++ b/dsa/DSALib/PropertiesNewtonsoft-Json-Linq-JProperty.json
@@ -0,0 +1,30 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:2170",
+ "sslPort": 44365
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "api/commands",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "DSALib": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "api/commands",
+ "applicationUrl": "https://0.0.0.0:5001;http://0.0.0.0:5000",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+} \ No newline at end of file