diff --git a/.gitattributes b/.gitattributes
index dfe0770..249ceff 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,35 @@
# Auto detect text files and perform LF normalization
* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
+
+# Binary files
+*.class binary
+*.dll binary
+*.ear binary
+*.gif binary
+*.ico binary
+*.jar binary
+*.jpg binary
+*.jpeg binary
+*.png binary
+*.so binary
+*.war binary
diff --git a/NerdyAion/NerdyAion.sln b/NerdyAion/NerdyAion.sln
new file mode 100644
index 0000000..0085ad6
--- /dev/null
+++ b/NerdyAion/NerdyAion.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26430.6
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NerdyAion", "NerdyAion\NerdyAion.csproj", "{A7DA8196-45F9-4D64-AB0D-9160D50A585D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A7DA8196-45F9-4D64-AB0D-9160D50A585D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A7DA8196-45F9-4D64-AB0D-9160D50A585D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A7DA8196-45F9-4D64-AB0D-9160D50A585D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A7DA8196-45F9-4D64-AB0D-9160D50A585D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/NerdyAion/NerdyAion/AnalysisTemplate.cs b/NerdyAion/NerdyAion/AnalysisTemplate.cs
new file mode 100644
index 0000000..ed75314
--- /dev/null
+++ b/NerdyAion/NerdyAion/AnalysisTemplate.cs
@@ -0,0 +1,143 @@
+// Copyright (C) 2019 Sebastian Lühnen
+//
+//
+// This file is part of NerdyAion.
+//
+// NerdyAion is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// NerdyAion is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with NerdyAion. If not, see .
+//
+//
+// Created By: Sebastian Lühnen
+// Created On: 19.02.2019
+// Last Edited On: 18.03.2019
+// Language: C#
+//
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NerdyAion
+{
+ public class AnalysisTemplate
+ {
+ private String strucktor;
+ private String template;
+ /*
+ * Supported variables:
+ * eventSource
+ * eventTarget
+ * eventEffect
+ * eventName
+ * eventEffectExtra
+ * eventTarget_eventEffect
+ * eventName_eventEffect
+ */
+ private Dictionary variables;
+ private Boolean damageEvent;
+
+ public String Strucktor
+ {
+ get { return strucktor; }
+ set { strucktor = value; }
+ }
+ public String Template
+ {
+ get { return template; }
+ set { template = value; }
+ }
+ public Dictionary Variables
+ {
+ get { return variables; }
+ set { variables = value; }
+ }
+ public Boolean DamageEvent
+ {
+ get { return damageEvent; }
+ set { damageEvent = value; }
+ }
+
+ public AnalysisTemplate()
+ {
+ Strucktor = "";
+ Template = "";
+ Variables = new Dictionary();
+ DamageEvent = false;
+ }
+
+ public void AddVariable(String variable)
+ {
+ Variables.Add(variable, variable);
+ }
+
+ public String GetEventSource(Match result)
+ {
+ return result.Groups[Variables["eventSource"]].Value;
+ }
+
+ public String GetEventTarget(Match result)
+ {
+ if (Variables.ContainsKey("eventTarget_eventEffect"))
+ {
+ return SplitEventTargetAndEventEffect(result)[0];
+ }
+ return result.Groups[Variables["eventTarget"]].Value;
+ }
+
+ public String GetEventName(Match result)
+ {
+ if (Variables.ContainsKey("eventName_eventEffect"))
+ {
+ return SplitEventNameAndEventEffect(result)[0];
+ }
+ return result.Groups[Variables["eventName"]].Value;
+ }
+
+ public long GetEventEffect(Match result)
+ {
+ if (Variables.ContainsKey("eventTarget_eventEffect"))
+ {
+ return Convert.ToInt64(SplitEventTargetAndEventEffect(result)[1].Replace(".", ""));
+ }
+ else if (Variables.ContainsKey("eventName_eventEffect"))
+ {
+ return Convert.ToInt64(SplitEventNameAndEventEffect(result)[1].Replace(".", ""));
+ }
+
+ return Convert.ToInt64(result.Groups[Variables["eventEffect"]].Value.Replace(".", ""));
+ }
+
+ public String GetEventEffectExtra(Match result)
+ {
+ return result.Groups[Variables["eventEffectExtra"]].Value;
+ }
+
+ private String[] SplitEventTargetAndEventEffect(Match result)
+ {
+ Regex pattern = new Regex(@"(?[^,]+) (?[.0-9]+)");
+ Match match = pattern.Match(result.Groups[variables["eventTarget_eventEffect"]].Value);
+
+ return new String[] { match.Groups["eventTarget"].Value, match.Groups["eventEffect"].Value };
+ }
+
+ private String[] SplitEventNameAndEventEffect(Match result)
+ {
+ Regex pattern = new Regex(@"(?[^,]+) (?[.0-9]+)");
+ Match match = pattern.Match(result.Groups[variables["eventName_eventEffect"]].Value);
+
+ return new String[] { match.Groups["eventName"].Value, match.Groups["eventEffect"].Value };
+ }
+ }
+}
diff --git a/NerdyAion/NerdyAion/App.config b/NerdyAion/NerdyAion/App.config
new file mode 100644
index 0000000..88fa402
--- /dev/null
+++ b/NerdyAion/NerdyAion/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NerdyAion/NerdyAion/Commands.cs b/NerdyAion/NerdyAion/Commands.cs
new file mode 100644
index 0000000..98d9c23
--- /dev/null
+++ b/NerdyAion/NerdyAion/Commands.cs
@@ -0,0 +1,328 @@
+// Copyright (C) 2019 Sebastian Lühnen
+//
+//
+// This file is part of NerdyAion.
+//
+// NerdyAion is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// NerdyAion is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with NerdyAion. If not, see .
+//
+//
+// Created By: Sebastian Lühnen
+// Created On: 19.02.2019
+// Last Edited On: 18.03.2019
+// Language: C#
+//
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace NerdyAion
+{
+ public static class Commands
+ {
+ private static String activCommantLevel;
+ private static Dictionary analyzer;
+ private static SettingsController settings;
+
+ public static String ActivCommantLevel
+ {
+ get { return activCommantLevel; }
+ set { activCommantLevel = value; }
+ }
+ public static Dictionary Analyzer
+ {
+ get { return analyzer; }
+ set { analyzer = value; }
+ }
+ public static SettingsController Settings
+ {
+ get { return settings; }
+ set { settings = value; }
+ }
+
+ public static void Execut(String command)
+ {
+ String[] commandParts = command.Split(' ');
+
+ if (commandParts.Length < 1)
+ {
+ commandParts = new String[1];
+ commandParts[0] = command;
+ }
+
+ switch (ActivCommantLevel)
+ {
+ case CommantLevel.BaseLevel:
+ Commands.BaseCommands(commandParts, command);
+ break;
+ case CommantLevel.SettingsLevel:
+ Commands.SettingsCommands(commandParts, command);
+ break;
+ case CommantLevel.DmgLevel:
+ Commands.DmgCommands(commandParts, command);
+ break;
+ default:
+ Commands.BaseCommands(commandParts, command);
+ break;
+ }
+ }
+
+ private static void BaseCommands(String[] command, String usedCommand)
+ {
+ switch (command[0])
+ {
+ case "info":
+ Console.WriteLine();
+ Console.WriteLine("###########################################################");
+ Console.WriteLine("NerdyAion [" + Settings.GetSetting("version") + "]");
+ Console.WriteLine("Author: SCHREDDO");
+ Console.WriteLine("Repository: https://github.com/SCHREDDO/NerdyAion-Aion-Tool-Manager");
+ Console.WriteLine("###########################################################");
+ Console.WriteLine();
+ break;
+ case "clear":
+ Console.Clear();
+ break;
+ case "goto":
+ if (command.Length < 2)
+ {
+ Commands.ShowError("unknown command \"" + usedCommand + "\"");
+ }
+ else
+ {
+ switch (command[1])
+ {
+ case "dmg":
+ ActivCommantLevel = CommantLevel.DmgLevel;
+ break;
+ case "settings":
+ ActivCommantLevel = CommantLevel.SettingsLevel;
+ break;
+ default:
+ Commands.ShowError("unknown path \"" + command[1] + "\"");
+ break;
+ }
+ }
+ break;
+ case "back":
+ ActivCommantLevel = CommantLevel.BaseLevel;
+ break;
+ case "help":
+ if (command.Length < 2)
+ {
+ Console.WriteLine("Commands: info, clear, goto, back, help, bye\nPaths: dmg, settings");
+ }
+ else
+ {
+ switch (command[1])
+ {
+ case "info":
+ Console.WriteLine("Infos about NerdyAion.");
+ break;
+ case "bye":
+ Console.WriteLine("Close NerdyAion.");
+ break;
+ case "clear":
+ Console.WriteLine("Cleared the console");
+ break;
+ case "goto":
+ Console.WriteLine("Go to path x. | goto path");
+ break;
+ case "back":
+ Console.WriteLine("Go back to main path.");
+ break;
+ case "help":
+ Console.WriteLine("Shows commands and paths.");
+ break;
+ case "dmg":
+ Console.WriteLine("Path for dmg analyzing.\nCommands:\ncreate: Create a pointer (start point) for the analyzing with the given name ``. | create \nlist: Shows all pointer.\nshow: hows dmg informations from pointer ``. | show \ncopy: Cpy the dmg informations from pointer ``. | copy ");
+ break;
+ case "settings":
+ Console.WriteLine("Path for handling settings.\nCommands:\nsave: Saved changes from settings\nshow: List of settings\nedit: Edit a setting | edit \nundo: Reset the last changes.");
+ break;
+ default:
+ Console.WriteLine("Commands: clear, goto, back, help, bye\nPaths: settings");
+ break;
+ }
+ }
+ Console.WriteLine();
+ break;
+ default:
+ Commands.ShowError("unknown command \"" + usedCommand + "\"");
+ break;
+ }
+ }
+
+ private static void DmgCommands(String[] command, String usedCommand)
+ {
+ switch (command[0])
+ {
+ case "create":
+ if (command.Length < 2)
+ {
+ Commands.ShowError("unknown command \"" + usedCommand + "\"");
+ }
+ else
+ {
+ if (!Analyzer.ContainsKey(command[1]))
+ {
+ Analyzer.Add(command[1], new LogAnalyzer(Settings.GetSetting("log")));
+ }
+ else
+ {
+ Commands.ShowError("pointer \"" + command[1] + "\" already exists");
+ }
+ }
+ break;
+ case "list":
+ Console.WriteLine("=== POINTER LIST ===");
+ foreach (KeyValuePair item in Analyzer)
+ {
+ Console.WriteLine(item.Key);
+ }
+ Console.WriteLine("=====================");
+ Console.WriteLine("");
+ break;
+ case "show":
+ if (command.Length < 2)
+ {
+ Commands.ShowError("unknown command \"" + usedCommand + "\"");
+ }
+ else
+ {
+ if (Analyzer.ContainsKey(command[1]))
+ {
+ Console.WriteLine("==== PLAYER LIST ====");
+
+ Analyzer[command[1]].AnalyzeLog();
+
+ foreach (KeyValuePair item in Analyzer[command[1]].PlayerList)
+ {
+ if (!item.Key.Equals(""))
+ {
+ Console.WriteLine(item.Key + ": " + item.Value.CalculateSkillDmg());
+ }
+ }
+ Console.WriteLine("=====================");
+ Console.WriteLine("");
+ }
+ else
+ {
+ Commands.ShowError("pointer \"" + command[1] + "\" don't exists");
+ }
+ }
+ break;
+ case "copy":
+ if (command.Length < 2)
+ {
+ Commands.ShowError("unknown command \"" + usedCommand + "\"");
+ }
+ else
+ {
+ if (Analyzer.ContainsKey(command[1]))
+ {
+ Analyzer[command[1]].AnalyzeLog();
+
+ String dmgData = "| ";
+ foreach (KeyValuePair item in Analyzer[command[1]].PlayerList)
+ {
+ if (!item.Key.Equals(""))
+ {
+ dmgData = item.Key + ": " + item.Value.CalculateSkillDmg() + " | ";
+ }
+ }
+
+ Thread thread = new Thread(() => Clipboard.SetText(dmgData));
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+ thread.Join();
+ }
+ else
+ {
+ Commands.ShowError("pointer \"" + command[1] + "\" don't exists");
+ }
+ }
+ break;
+ default:
+ Commands.BaseCommands(command, usedCommand);
+ break;
+ }
+ }
+
+ private static void SettingsCommands(String[] command, String usedCommand)
+ {
+ switch (command[0])
+ {
+ case "save":
+ Console.WriteLine("Saving Settings...");
+ Settings.SaveSettings();
+ break;
+ case "show":
+ Settings.LoudSettings();
+ List settingList = Settings.GetAllSettings();
+
+ Console.WriteLine("=== Settzings ===");
+ for (int i = 0; i < settingList.Count; i++)
+ {
+ String saved = "";
+
+ if (!settingList[i].Saved)
+ {
+ saved = "[NOT SAVED] ";
+ }
+
+ Console.WriteLine(saved + settingList[i].Name + ": " + settingList[i].Value);
+ }
+ Console.WriteLine("");
+ break;
+ case "edit":
+ if (command.Length < 3)
+ {
+ Commands.ShowError("unknown command \"" + usedCommand + "\"");
+ }
+ else
+ {
+ if (command.Length > 3)
+ {
+ for (int i = 3; i < command.Length; i++)
+ {
+ command[2] += " " + command[i];
+ }
+ }
+
+ if (!settings.SetSetting(command[1], command[2]))
+ {
+ Commands.ShowError("unknown setting \"" + command[1] + "\"");
+ }
+ }
+ break;
+ case "undo":
+ Settings.CanselEdits();
+ break;
+ default:
+ Commands.BaseCommands(command, usedCommand);
+ break;
+ }
+ }
+
+ public static void ShowError(String error)
+ {
+ Console.WriteLine("[ERROR] " + error);
+ Console.WriteLine();
+ }
+ }
+}
diff --git a/NerdyAion/NerdyAion/CommantLevel.cs b/NerdyAion/NerdyAion/CommantLevel.cs
new file mode 100644
index 0000000..2ffdea2
--- /dev/null
+++ b/NerdyAion/NerdyAion/CommantLevel.cs
@@ -0,0 +1,39 @@
+// Copyright (C) 2019 Sebastian Lühnen
+//
+//
+// This file is part of NerdyAion.
+//
+// NerdyAion is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// NerdyAion is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with NerdyAion. If not, see .
+//
+//
+// Created By: Sebastian Lühnen
+// Created On: 19.02.2019
+// Last Edited On: 18.03.2019
+// Language: C#
+//
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NerdyAion
+{
+ public static class CommantLevel
+ {
+ public const String BaseLevel = @">";
+ public const String DmgLevel = @"dmg>";
+ public const String SettingsLevel = @"settings>";
+ }
+}
diff --git a/NerdyAion/NerdyAion/LogAnalyzer.cs b/NerdyAion/NerdyAion/LogAnalyzer.cs
new file mode 100644
index 0000000..2f804d1
--- /dev/null
+++ b/NerdyAion/NerdyAion/LogAnalyzer.cs
@@ -0,0 +1,281 @@
+// Copyright (C) 2019 Sebastian Lühnen
+//
+//
+// This file is part of NerdyAion.
+//
+// NerdyAion is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// NerdyAion is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with NerdyAion. If not, see .
+//
+//
+// Created By: Sebastian Lühnen
+// Created On: 19.02.2019
+// Last Edited On: 18.03.2019
+// Language: C#
+//
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Text.RegularExpressions;
+
+namespace NerdyAion
+{
+ public class LogAnalyzer
+ {
+ private LogReader log;
+ private List analysisTemplates;
+
+ private Dictionary playerList;
+ private Dictionary skillList;
+
+ public LogReader Log
+ {
+ get { return log; }
+ set { log = value; }
+ }
+ public List AnalysisTemplates
+ {
+ get { return analysisTemplates; }
+ set { analysisTemplates = value; }
+ }
+
+ public Dictionary PlayerList
+ {
+ get { return playerList; }
+ set { playerList = value; }
+ }
+ public Dictionary SkillList
+ {
+ get { return skillList; }
+ set { skillList = value; }
+ }
+
+ public LogAnalyzer(String logFilePath)
+ {
+ Log = new LogReader(logFilePath);
+ AnalysisTemplates = new List();
+ PlayerList = new Dictionary();
+ SkillList = new Dictionary();
+
+ SetAnalysisTemplates();
+ }
+
+ public void AnalyzeLog()
+ {
+ byte[] logData = Log.ReadLogChanges();
+ String[] lines = new String[0];
+ String[] stringSeparators = new String[] { "\r\n" };
+ Regex pattern = null;
+ Match match = null;
+ String logText = "";
+
+ String eventSource = "";
+ String eventTarget = "";
+ String eventName = "";
+ long eventEffectDamage = 0;
+
+ logText = ByteArrayToString(logData);
+ logData = new byte[0];
+ lines = logText.Split(stringSeparators, StringSplitOptions.None);
+ logText = "";
+
+ foreach (String temp in lines)
+ {
+ String line = temp.Replace("\r\n", "");
+ foreach (AnalysisTemplate template in AnalysisTemplates)
+ {
+ if (Regex.IsMatch(line, template.Strucktor))
+ {
+ pattern = new Regex(template.Template);
+ match = pattern.Match(line);
+
+ foreach (KeyValuePair variable in template.Variables)
+ {
+ switch (variable.Value)
+ {
+ case "eventSource":
+ eventSource = template.GetEventSource(match);
+ break;
+ case "eventTarget":
+ eventTarget = template.GetEventTarget(match);
+ break;
+ case "eventEffect":
+ if (template.DamageEvent)
+ {
+ eventEffectDamage = template.GetEventEffect(match);
+ }
+ break;
+ case "eventName":
+ eventName = template.GetEventName(match);
+ break;
+ case "eventEffectExtra":
+ break;
+ case "eventTarget_eventEffect":
+ eventTarget = template.GetEventTarget(match);
+ if (template.DamageEvent)
+ {
+ eventEffectDamage = template.GetEventEffect(match);
+ }
+ break;
+ case "eventName_eventEffect":
+ eventName = template.GetEventName(match);
+ if (template.DamageEvent)
+ {
+ eventEffectDamage = template.GetEventEffect(match);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (!PlayerList.ContainsKey(eventSource))
+ {
+ PlayerList.Add(eventSource, new Player(eventSource));
+ }
+
+ PlayerList[eventSource].AddSkill(new Skill(eventName, eventEffectDamage, false));
+
+ eventSource = "";
+ eventTarget = "";
+ eventName = "";
+ eventEffectDamage = 0;
+ }
+ }
+ }
+
+ private String ByteArrayToString(byte[] data)
+ {
+ String text = "";
+
+ foreach (byte item in data)
+ {
+ text += (char)item;
+ }
+
+ return text;
+ }
+
+ private void SetAnalysisTemplates()
+ {
+ AnalysisTemplate temp = null;
+
+ //2019.03.16 17:09:04 : Ihr habt Wilder Sumpf-Oculis durch Benutzung von Seelenraub 24.876 Schaden zugefügt.
+ temp = new AnalysisTemplate();
+ temp.DamageEvent = true;
+ temp.Strucktor = ".* : .* habt .* durch Benutzung von .* Schaden zugefügt.";
+ temp.Template = @"(?