diff --git a/Application/EventParsers/IW4EventParser.cs b/Application/EventParsers/IW4EventParser.cs
index e6f3c424e..3225514fe 100644
--- a/Application/EventParsers/IW4EventParser.cs
+++ b/Application/EventParsers/IW4EventParser.cs
@@ -12,7 +12,7 @@ namespace Application.EventParsers
public GameEvent GetEvent(Server server, string logLine)
{
string[] lineSplit = logLine.Split(';');
- string cleanedEventLine = Regex.Replace(lineSplit[0], @"[0-9]+:[0-9]+\ ", "");
+ string cleanedEventLine = Regex.Replace(lineSplit[0], @"[0-9]+:[0-9]+\ ", "").Trim();
if (cleanedEventLine[0] == 'K')
{
@@ -29,7 +29,7 @@ namespace Application.EventParsers
}
}
- if (lineSplit[0].Substring(lineSplit[0].Length - 3).Trim() == "say")
+ if (cleanedEventLine == "say" || cleanedEventLine == "sayteam")
{
return new GameEvent()
{
@@ -37,7 +37,7 @@ namespace Application.EventParsers
Data = lineSplit[4].Replace("\x15", ""),
Origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2)),
Owner = server,
- Message = lineSplit[4]
+ Message = lineSplit[4].Replace("\x15", "")
};
}
diff --git a/Application/EventParsers/T6MEventParser.cs b/Application/EventParsers/T6MEventParser.cs
index 3b42c3043..050cf87ca 100644
--- a/Application/EventParsers/T6MEventParser.cs
+++ b/Application/EventParsers/T6MEventParser.cs
@@ -39,7 +39,7 @@ namespace Application.EventParsers
};
}
- if (lineSplit[0] == "say")
+ if (lineSplit[0] == "say" || lineSplit[0] == "sayteam")
{
return new GameEvent()
{
diff --git a/Application/Server.cs b/Application/Server.cs
index d029a1172..8283f4cf3 100644
--- a/Application/Server.cs
+++ b/Application/Server.cs
@@ -648,7 +648,7 @@ namespace IW4MAdmin
CustomCallback = await ScriptLoaded();
string mainPath = EventParser.GetGameDir();
#if DEBUG
- basepath.Value = @"\\192.168.88.253\Call of Duty Black Ops II";
+ basepath.Value = @"D:\";
#endif
string logPath = game.Value == string.Empty ?
$"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile.Value}" :
diff --git a/IW4MAdmin.sln b/IW4MAdmin.sln
index 28473b105..652f08792 100644
--- a/IW4MAdmin.sln
+++ b/IW4MAdmin.sln
@@ -12,8 +12,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
version.txt = version.txt
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Plugins\Tests\Tests.csproj", "{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedLibraryCore", "SharedLibraryCore\SharedLibraryCore.csproj", "{AA0541A2-8D51-4AD9-B0AC-3D1F5B162481}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebfrontCore", "WebfrontCore\WebfrontCore.csproj", "{D59AC1F1-2FB9-4BE7-813E-0CCCC4FE9067}"
@@ -30,6 +28,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Login", "Plugins\Login\Logi
EndProject
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "Master", "Master\Master.pyproj", "{F5051A32-6BD0-4128-ABBA-C202EE15FC5C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Plugins\Tests\Tests.csproj", "{B72DEBFB-9D48-4076-8FF5-1FD72A830845}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -46,26 +46,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x64.ActiveCfg = Debug|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x64.Build.0 = Debug|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x86.ActiveCfg = Debug|x86
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x86.Build.0 = Debug|x86
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Prerelease|Any CPU.ActiveCfg = Release-Stable|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Prerelease|Mixed Platforms.ActiveCfg = Release-Stable|x86
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Prerelease|x64.ActiveCfg = Release-Stable|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Prerelease|x86.ActiveCfg = Release-Stable|x86
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x64.ActiveCfg = Release-Stable|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x64.Build.0 = Release-Stable|Any CPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x86.ActiveCfg = Release-Stable|x86
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x86.Build.0 = Release-Stable|x86
{AA0541A2-8D51-4AD9-B0AC-3D1F5B162481}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA0541A2-8D51-4AD9-B0AC-3D1F5B162481}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA0541A2-8D51-4AD9-B0AC-3D1F5B162481}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -258,16 +238,38 @@ Global
{F5051A32-6BD0-4128-ABBA-C202EE15FC5C}.Release|x64.Build.0 = Release|Any CPU
{F5051A32-6BD0-4128-ABBA-C202EE15FC5C}.Release|x86.ActiveCfg = Release|Any CPU
{F5051A32-6BD0-4128-ABBA-C202EE15FC5C}.Release|x86.Build.0 = Release|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Debug|x64.Build.0 = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Debug|x86.Build.0 = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Prerelease|Any CPU.ActiveCfg = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Prerelease|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Prerelease|Mixed Platforms.Build.0 = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Prerelease|x64.ActiveCfg = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Prerelease|x64.Build.0 = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Prerelease|x86.ActiveCfg = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Prerelease|x86.Build.0 = Debug|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Release|x64.ActiveCfg = Release|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Release|x64.Build.0 = Release|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Release|x86.ActiveCfg = Release|Any CPU
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1} = {26E8B310-269E-46D4-A612-24601F16065F}
{98BE4A81-8AFD-4957-83F7-009D353C6BCB} = {26E8B310-269E-46D4-A612-24601F16065F}
{179140D3-97AA-4CB4-8BF6-A0C73CA75701} = {26E8B310-269E-46D4-A612-24601F16065F}
{958FF7EC-0226-4E85-A85B-B84EC768197D} = {26E8B310-269E-46D4-A612-24601F16065F}
{D9F2ED28-6FA5-40CA-9912-E7A849147AB1} = {26E8B310-269E-46D4-A612-24601F16065F}
+ {B72DEBFB-9D48-4076-8FF5-1FD72A830845} = {26E8B310-269E-46D4-A612-24601F16065F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {84F8F8E0-1F73-41E0-BD8D-BB6676E2EE87}
diff --git a/Plugins/Login/Login.csproj b/Plugins/Login/Login.csproj
index 90f8afe2e..ce7503adb 100644
--- a/Plugins/Login/Login.csproj
+++ b/Plugins/Login/Login.csproj
@@ -12,6 +12,10 @@
Debug;Release;Prerelease
+
+ TRACE;DEBUG;NETCOREAPP2_0
+
+
diff --git a/Plugins/Tests/Plugin.cs b/Plugins/Tests/Plugin.cs
index bfb9a1526..a6210dd50 100644
--- a/Plugins/Tests/Plugin.cs
+++ b/Plugins/Tests/Plugin.cs
@@ -1,20 +1,11 @@
#if DEBUG
using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
using System.Threading.Tasks;
-using System.IO;
-using SharedLibrary;
-using SharedLibrary.Interfaces;
-using SharedLibrary.Helpers;
-using SharedLibrary.Objects;
-using System.Text.RegularExpressions;
-using StatsPlugin.Models;
-using SharedLibrary.Services;
-using SharedLibrary.Database.Models;
-using SharedLibrary.Database;
+using SharedLibraryCore;
+using SharedLibraryCore.Interfaces;
+using SharedLibraryCore.Helpers;
namespace IW4MAdmin.Plugins
{
@@ -26,12 +17,9 @@ namespace IW4MAdmin.Plugins
public string Author => "RaidMax";
- private DateTime Interval;
-
- public async Task OnEventAsync(Event E, Server S)
+ public async Task OnEventAsync(GameEvent E, Server S)
{
- return;
- if (E.Type == Event.GType.Start)
+ if (E.Type == GameEvent.EventType.Start)
{
#region PLAYER_HISTORY
var rand = new Random(GetHashCode());
@@ -61,361 +49,11 @@ namespace IW4MAdmin.Plugins
}
}
- public async Task OnLoadAsync(IManager manager)
- {
- // #if DO_IMPORT
- var svc = new GenericRepository();
- svc.Insert(new EFServer()
- {
- Active = true,
- Port = 28960,
- ServerId = Math.Abs("127.0.0.1:28960".GetHashCode()),
- });
-
- svc.Insert(new EFServer()
- {
- Active = true,
- Port = 28965,
- ServerId = Math.Abs("127.0.0.1:28965".GetHashCode()),
- });
-
- svc.Insert(new EFServer()
- {
- Active = true,
- Port = 28970,
- ServerId = Math.Abs("127.0.0.1:28970".GetHashCode()),
- });
-
- svc.SaveChanges();
- // #endif
- Interval = DateTime.Now;
- var clients = new List();
- var oldClients = new Dictionary();
- #region CLIENTS
- if (File.Exists("import_clients.csv"))
- {
- manager.GetLogger().WriteVerbose("Beginning import of existing clients");
-
- var lines = File.ReadAllLines("import_clients.csv").Skip(1);
- foreach (string line in lines)
- {
- string[] fields = Regex.Replace(line, "\".*\"", "").Split(',');
- fields.All(f =>
- {
- f = f.StripColors().Trim();
- return true;
- });
-
- if (fields.Length != 11)
- {
- manager.GetLogger().WriteError("Invalid client import file... aborting import");
- return;
- }
-
- if (fields[1].Substring(0, 5) == "01100" || fields[0] == string.Empty || fields[1] == string.Empty || fields[6] == string.Empty)
- continue;
-
- if (!Regex.Match(fields[6], @"^\d+\.\d+\.\d+.\d+$").Success)
- fields[6] = "0";
-
- var client = new Player()
- {
- Name = fields[0],
- NetworkId = fields[1].ConvertLong(),
- IPAddress = fields[6].ConvertToIP(),
- Level = (Player.Permission)Convert.ToInt32(fields[3]),
- Connections = Convert.ToInt32(fields[5]),
- LastConnection = DateTime.Parse(fields[7]),
- };
-
- clients.Add(client);
- oldClients.Add(Convert.ToInt32(fields[2]), client);
- }
- clients = clients.Distinct().ToList();
- // #if DO_IMPORT
-
- /*clients = clients
- .GroupBy(c => new { c.Name, c.IPAddress })
- .Select(c => c.FirstOrDefault())
- .ToList();*/
-
- //newClients = clients.ToList();
- //newClients.ForEach(c => c.ClientId = 0);
-
- manager.GetLogger().WriteVerbose($"Read {clients.Count} clients for import");
-
- try
- {
- SharedLibrary.Database.Importer.ImportClients(clients);
- }
-
- catch (Exception e)
- {
- manager.GetLogger().WriteError("Saving imported clients failed");
- }
- // #endif
- }
-#endregion
- // load the entire database lol
- var ctx = new DatabaseContext();
- ctx.Configuration.ProxyCreationEnabled = false;
- var cls = ctx.Clients.Include("AliasLink.Children").ToList(); //manager.GetClientService().Find(c => c.Active).Result;
- ctx.Dispose();
-
-#region ALIASES
- if (File.Exists("import_aliases.csv"))
- {
- manager.GetLogger().WriteVerbose("Beginning import of existing aliases");
-
- var aliases = new List();
-
- var lines = File.ReadAllLines("import_aliases.csv").Skip(1);
- foreach (string line in lines)
- {
- string[] fields = Regex.Replace(line, "\".*\"", "").Split(',');
- fields.All(f =>
- {
- f = f.StripColors().Trim();
- return true;
- });
-
- if (fields.Length != 3)
- {
- manager.GetLogger().WriteError("Invalid alias import file... aborting import");
- return;
- }
- try
- {
- int number = Int32.Parse(fields[0]);
- var names = fields[1].Split(';').Where(n => n != String.Empty && n.Length > 2);
-
- var oldClient = oldClients[number];
- var newClient = cls.FirstOrDefault(c => c.NetworkId == oldClient.NetworkId);
-
- foreach (string name in names)
- {
- // this is slow :D
- if (newClient.AliasLink.Children.FirstOrDefault(n => n.Name == name) != null) continue;
- var alias = new EFAlias()
- {
- Active = true,
- DateAdded = DateTime.UtcNow,
- Name = name,
- LinkId = newClient.AliasLinkId,
- IPAddress = newClient.IPAddress
- };
-
- aliases.Add(alias);
- }
- }
- catch (KeyNotFoundException)
- {
- continue;
- }
-
- catch (Exception)
- {
- manager.GetLogger().WriteVerbose($"Could not import alias with line {line}");
- }
- }
-
- SharedLibrary.Database.Importer.ImportSQLite(aliases);
- }
-#endregion
-#region PENALTIES
- if (File.Exists("import_penalties.csv"))
- {
- var penalties = new List();
- manager.GetLogger().WriteVerbose("Beginning import of existing penalties");
- foreach (string line in File.ReadAllLines("import_penalties.csv").Skip(1))
- {
- string comma = Regex.Match(line, "\".*,.*\"").Value.Replace(",", "");
- string[] fields = Regex.Replace(line, "\".*,.*\"", comma).Split(',');
-
- fields.All(f =>
- {
- f = f.StripColors().Trim();
- return true;
- });
-
- if (fields.Length != 7)
- {
- manager.GetLogger().WriteError("Invalid penalty import file... aborting import");
- return;
- }
-
- if (fields[2].Substring(0, 5) == "01100" || fields[2].Contains("0000000"))
- continue;
- try
- {
-
- var expires = DateTime.Parse(fields[6]);
- var when = DateTime.Parse(fields[5]);
-
- var penaltyType = (Penalty.PenaltyType)Int32.Parse(fields[0]);
- if (penaltyType == Penalty.PenaltyType.Ban)
- expires = DateTime.MaxValue;
-
- var penalty = new Penalty()
- {
- Type = penaltyType,
- Expires = expires == DateTime.MinValue ? when : expires,
- Punisher = new SharedLibrary.Database.Models.EFClient() { NetworkId = fields[3].ConvertLong() },
- Offender = new SharedLibrary.Database.Models.EFClient() { NetworkId = fields[2].ConvertLong() },
- Offense = fields[1].Replace("\"", "").Trim(),
- Active = true,
- When = when,
- };
-
-
- penalties.Add(penalty);
- }
-
- catch (Exception e)
- {
- manager.GetLogger().WriteVerbose($"Could not import penalty with line {line}");
- }
- }
- //#if DO_IMPORT
- SharedLibrary.Database.Importer.ImportPenalties(penalties);
- manager.GetLogger().WriteVerbose($"Imported {penalties.Count} penalties");
- //#endif
- }
-#endregion
-#region CHATHISTORY
-
- if (File.Exists("import_chathistory.csv"))
- {
- var chatHistory = new List();
- manager.GetLogger().WriteVerbose("Beginning import of existing messages");
- foreach (string line in File.ReadAllLines("import_chathistory.csv").Skip(1))
- {
- string comma = Regex.Match(line, "\".*,.*\"").Value.Replace(",", "");
- string[] fields = Regex.Replace(line, "\".*,.*\"", comma).Split(',');
-
- fields.All(f =>
- {
- f = f.StripColors().Trim();
- return true;
- });
-
- if (fields.Length != 4)
- {
- manager.GetLogger().WriteError("Invalid chat history import file... aborting import");
- return;
- }
- try
- {
- int cId = Convert.ToInt32(fields[0]);
- var linkedClient = oldClients[cId];
-
- var newcl = cls.FirstOrDefault(c => c.NetworkId == linkedClient.NetworkId);
- if (newcl == null)
- newcl = cls.FirstOrDefault(c => c.Name == linkedClient.Name && c.IPAddress == linkedClient.IPAddress);
- int newCId = newcl.ClientId;
-
- var chatMessage = new EFClientMessage()
- {
- Active = true,
- ClientId = newCId,
- Message = fields[1],
- TimeSent = DateTime.Parse(fields[3]),
- ServerId = Math.Abs($"127.0.0.1:{Convert.ToInt32(fields[2]).ToString()}".GetHashCode())
- };
-
- chatHistory.Add(chatMessage);
- }
-
- catch (Exception e)
- {
- manager.GetLogger().WriteVerbose($"Could not import chatmessage with line {line}");
- }
- }
- manager.GetLogger().WriteVerbose($"Read {chatHistory.Count} messages for import");
- SharedLibrary.Database.Importer.ImportSQLite(chatHistory);
- }
-#endregion
-#region STATS
- foreach (string file in Directory.GetFiles(Environment.CurrentDirectory))
- {
- if (Regex.Match(file, @"import_stats_[0-9]+.csv").Success)
- {
- int port = Int32.Parse(Regex.Match(file, "[0-9]{5}").Value);
- var stats = new List();
- manager.GetLogger().WriteVerbose("Beginning import of existing client stats");
-
- var lines = File.ReadAllLines(file).Skip(1);
- foreach (string line in lines)
- {
- string[] fields = line.Split(',');
-
- if (fields.Length != 9)
- {
- manager.GetLogger().WriteError("Invalid client import file... aborting import");
- return;
- }
-
- try
- {
- if (fields[0].Substring(0, 5) == "01100")
- continue;
-
- long id = fields[0].ConvertLong();
- var client = cls.Single(c => c.NetworkId == id);
-
- var time = Convert.ToInt32(fields[8]);
- double spm = time < 60 ? 0 : Math.Round(Convert.ToInt32(fields[1]) * 100.0 / time, 3);
- if (spm > 1000)
- spm = 0;
-
- var st = new EFClientStatistics()
- {
- Active = true,
- ClientId = client.ClientId,
- ServerId = Math.Abs($"127.0.0.1:{port}".GetHashCode()),
- Kills = Convert.ToInt32(fields[1]),
- Deaths = Convert.ToInt32(fields[2]),
- SPM = spm,
- Skill = 0,
- TimePlayed = time * 60
- };
- // client.TotalConnectionTime += time;
- stats.Add(st);
- stats = stats.AsEnumerable()
- .GroupBy(c => new { c.ClientId })
- .Select(c => c.FirstOrDefault()).ToList();
-
- var cl = await manager.GetClientService().Get(st.ClientId);
- cl.TotalConnectionTime += time * 60;
- await manager.GetClientService().Update(cl);
- }
- catch (Exception e)
- {
- continue;
- }
-
- }
-
-
- manager.GetLogger().WriteVerbose($"Read {stats.Count} clients stats for import");
-
- try
- {
- SharedLibrary.Database.Importer.ImportSQLite(stats);
- }
-
- catch (Exception e)
- {
- manager.GetLogger().WriteError("Saving imported stats failed");
- }
- }
- }
-#endregion
- }
+ public Task OnLoadAsync(IManager manager) => Task.CompletedTask;
public async Task OnTickAsync(Server S)
{
- return;
+ /*
if ((DateTime.Now - Interval).TotalSeconds > 1)
{
var rand = new Random();
@@ -492,13 +130,10 @@ namespace IW4MAdmin.Plugins
}
}
}
-
+ */
}
- public async Task OnUnloadAsync()
- {
-
- }
+ public Task OnUnloadAsync() => Task.CompletedTask;
}
}
#endif
\ No newline at end of file
diff --git a/Plugins/Tests/Properties/AssemblyInfo.cs b/Plugins/Tests/Properties/AssemblyInfo.cs
deleted file mode 100644
index 1d901a309..000000000
--- a/Plugins/Tests/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Tests")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Tests")]
-[assembly: AssemblyCopyright("Copyright © 2017")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("b8c2a759-8663-4f6f-9ba4-19595f5e12c1")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Plugins/Tests/Tests.csproj b/Plugins/Tests/Tests.csproj
index 3091f3ad7..db6807dd8 100644
--- a/Plugins/Tests/Tests.csproj
+++ b/Plugins/Tests/Tests.csproj
@@ -1,97 +1,22 @@
-
-
-
+
+
- Debug
- AnyCPU
- {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}
Library
- Properties
- Tests
- Tests
- v4.5
- 512
+ netcoreapp2.0
+
+
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
- true
- bin\x86\Debug\
- DEBUG;TRACE
- full
- x86
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\x86\Release\
- TRACE
- true
- pdbonly
- x86
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\Release-Stable\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\x86\Release-Stable\
- TRACE
- true
- pdbonly
- x86
- prompt
- MinimumRecommendedRules.ruleset
+
+
+ TRACE;DEBUG;NETCOREAPP2_0
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
- {d51eeceb-438a-47da-870f-7d7b41bc24d6}
- SharedLibrary
-
-
- {4785ab75-66f3-4391-985d-63a5a049a0fa}
- StatsPlugin
-
-
-
-
- if $(ConfigurationName) == Debug (copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)BUILD\plugins\")
-
-
\ No newline at end of file
+
+
diff --git a/README.md b/README.md
index 8aab5216c..22c340e36 100644
--- a/README.md
+++ b/README.md
@@ -1,111 +1,155 @@
-# IW4MAdmin
-### Quick Start Guide
-### Version 1.5
+
+# IW4MAdmin
+### Quick Start Guide
+### Version 2.0
_______
+### About
+**IW4MAdmin** is an administration tool for [IW4x](https://iw4xcachep26muba.onion.link/), [T6M](https://plutonium.pw/), and most Call of Duty® dedicated servers. It allows complete control of your server; from changing maps, to banning players, **IW4MAdmin** monitors and records activity on your server(s). With plugin support, extending its functionality is a breeze.
### Setup
-IW4MAdmin requires minimal configuration to run. There is only one prerequisite.
-1. [.NET Framework 4.5](https://www.microsoft.com/en-us/download/details.aspx?id=30653) *or newer*
+**IW4MAdmin** requires minimal configuration to run. There is only one prerequisite.
+* [.NET Core 2.0 Runtime](https://www.microsoft.com/net/download/dotnet-core/runtime-2.0.5) *or newer*
-Extract `IW4MAdmin.zip`
-Run `IW4MAdmin.exe`
+1. Extract `IW4MAdmin-.zip`
+2. Open command prompt or terminal in the extracted folder
+3. Run `>dotnet IW4MAdmin.dll`
___
### Configuration
-_If you wish to customize your experience of IW4MAdmin, the following configuration files will allow you to changes core options._
+#### Initial Configuration
+When **IW4MAdmin** is launched for the _first time_, you will be prompted to setup your configuration.
-`maps.cfg`
- * This is the configuration file that links an IW4 map file name to its common/in-game name
- * This can be safely modified to add additional SP/DLC maps
+`Enable webfront`
+* Enables you to monitor and control your server(s) through a web interface [defaults to `http://127.0.0.1:1624`]
-`messages.cfg`
- * This is the configuration file that broadcasts messages to your server at a set time
- * The _first line_ specifies the amount of time between messages (in seconds)
- * Every new line is interpreted as a new message
- * Color codes are allowed in the messages
- * Tokens are denoted by double braces: {{TOKEN}}
+`Enable multiple owners`
+* Enables more than one client to be promoted to level of `Owner`
-`rules.cfg`
- * This is the configuration file that sets the server's rules.
- * Every new line is interpreted as a new rule
- * All rules are _global_ across servers
+`Enable stepped privilege hierarchy`
+* Allows privileged clients to promote other clients to the level below their current level
-`web.cfg`
- * This is the configuration file that specifies the web front bindings
- * The first line specifies the `IP` or `Hostname` to bind to
- * The second line specifies the `port` to bind to
+`Enable custom say name`
+* Shows a prefix to every message send by **IW4MAdmin** -- `[Admin] message`
+* _This feature requires you specify a custom say name_
+`Enable client VPNs`
+* Allow clients to use a [VPN](https://en.wikipedia.org/wiki/Virtual_private_network)
+* _This feature requires an active api key on [iphub.info](https://iphub.info/)_
+
+`Enable discord link`
+* Shows a link to your server's discord on the webfront
+* _This feature requires an invite link to your discord server_
+
+#### Advanced Configuration
+If you wish to further customize your experience of **IW4MAdmin**, the following configuration file(s) will allow you to changes core options using any text-editor.
+
+#### `IW4MAdminSettings.json`-- _this file is created after initial setup_
+* This file uses the [JSON](https://en.wikipedia.org/wiki/JSON#JSON_sample) specification, so please validate it before running **IW4MAdmin**
+
+`WebfrontBindUrl`
+* Specifies the address and port the webfront will listen on.
+* The value can be an [IP Address](https://en.wikipedia.org/wiki/IP_address):port or [Domain Name](https://en.wikipedia.org/wiki/Domain_name):port
+
+`Servers`
+* Specifies the list of servers **IW4MAdmin** will monitor
+* `IPAddress`
+ * Specifies the IP Address of the particular server
+* `Port`
+ * Specifies the port of the particular server
+* `Password`
+ * Specifies the `rcon_password` of the particular server
+* `AutoMessages`
+ * Specifies the list of messages that are broadcasted to the particular server
+* `Rules`
+ * Specifies the list of rules that apply to the particular server
+
+`AutoMessagePeriod`
+* Specifies (in seconds) how often messages should be broadcasted to the server(s)
+
+`AutoMessages`
+* Specifies the list of messages that are broadcasted to **all** servers
+
+`GlobalRules`
+* Specifies the list of rules that apply to **all** servers`
+
+`Maps`
+* Specifies the list of maps for each supported game
+* `Name`
+ * Specifies the name of the map as returned by the game
+* `Alias`
+ * Specifies the display name of the map (as seen while loading in)
___
+
### Commands
|Name |Alias|Description |Requires Target|Syntax |Required Level|
|--------------| -----| --------------------------------------------------------| -----------------| -------------| ----------------|
-|disabletrusted|dt|disable trusted player group for the server|False|!dt |Owner|
-|enabletrusted|et|enable trusted player group for the server|False|!et |Owner|
-|prune|p|demote any admins that have not connected recently (defaults to 30 days)|False|!p \|Owner|
+|prune|pa|demote any admins that have not connected recently (defaults to 30 days)|False|!pa \|Owner|
|quit|q|quit IW4MAdmin|False|!q |Owner|
|rcon|rcon|send rcon command to server|False|!rcon \|Owner|
-|reload|rl|reload configuration files|False|!rl |Owner|
-|setlevel|sl|set player to specified administration level|True|!sl \ \|Owner|
|ban|b|permanently ban a player from the server|True|!b \ \|SeniorAdmin|
-|fredisable|frd|disable fast restarting at the end of a map|False|!frd |SeniorAdmin|
-|frenable|fre|enable fast restarting at the end of a map|False|!fre |SeniorAdmin|
-|unban|ub|unban player by database id|True|!ub \|SeniorAdmin|
+|unban|ub|unban player by database id|True|!ub \ \|SeniorAdmin|
|find|f|find player in database|False|!f \|Administrator|
-|findall|fa|find a player by their aliase(s)|False|!fa \|Administrator|
+|killserver|kill|kill the game server|False|!kill |Administrator|
|map|m|change to specified map|False|!m \