diff --git a/Application/Application.csproj b/Application/Application.csproj
index e46d20c11..8ef18759a 100644
--- a/Application/Application.csproj
+++ b/Application/Application.csproj
@@ -92,6 +92,6 @@
-
+
diff --git a/Application/BuildScripts/PostPublish.bat b/Application/BuildScripts/PostPublish.bat
index a8d975aad..807ee448c 100644
--- a/Application/BuildScripts/PostPublish.bat
+++ b/Application/BuildScripts/PostPublish.bat
@@ -1,6 +1,8 @@
set SolutionDir=%1
set ProjectDir=%2
set TargetDir=%3
+set CurrentConfiguration=%4
+SET COPYCMD=/Y
echo Deleting extra language files
@@ -54,9 +56,41 @@ del "%SolutionDir%Publish\Windows\*pdb"
if exist "%SolutionDir%Publish\WindowsPrerelease\web.config" del "%SolutionDir%Publish\WindowsPrerelease\web.config"
del "%SolutionDir%Publish\WindowsPrerelease\*pdb"
-echo making start scripts
-@echo dotnet IW4MAdmin.dll > "%SolutionDir%Publish\WindowsPrerelease\StartIW4MAdmin.cmd"
-@echo dotnet IW4MAdmin.dll > "%SolutionDir%Publish\Windows\StartIW4MAdmin.cmd"
+echo setting up library folders
-@(echo #!/bin/bash && echo dotnet IW4MAdmin.dll) > "%SolutionDir%Publish\WindowsPrerelease\StartIW4MAdmin.sh"
-@(echo #!/bin/bash && echo dotnet IW4MAdmin.dll) > "%SolutionDir%Publish\Windows\StartIW4MAdmin.sh"
+echo PR-Config
+if not exist "%SolutionDir%Publish\WindowsPrerelease\Configuration" md "%SolutionDir%Publish\WindowsPrerelease\Configuration"
+move "%SolutionDir%Publish\WindowsPrerelease\DefaultSettings.json" "%SolutionDir%Publish\WindowsPrerelease\Configuration\"
+
+if "%CurrentConfiguration" == "Release" (
+ echo R-Config
+ if not exist "%SolutionDir%Publish\Windows\Configuration" md "%SolutionDir%Publish\Windows\Configuration"
+ if exist "%SolutionDir%Publish\Windows\DefaultSettings.json" move "%SolutionDir%Publish\Windows\DefaultSettings.json" "%SolutionDir%Publish\Windows\Configuration\DefaultSettings.json"
+)
+
+echo PR-LIB
+if not exist "%SolutionDir%Publish\WindowsPrerelease\Lib\" md "%SolutionDir%Publish\WindowsPrerelease\Lib\"
+move "%SolutionDir%Publish\WindowsPrerelease\*.dll" "%SolutionDir%Publish\WindowsPrerelease\Lib\"
+move "%SolutionDir%Publish\WindowsPrerelease\*.json" "%SolutionDir%Publish\WindowsPrerelease\Lib\"
+
+if "%CurrentConfiguration" == "Release" (
+ echo R-LIB
+ if not exist "%SolutionDir%Publish\Windows\Lib\" md "%SolutionDir%Publish\Windows\Lib\"
+ move "%SolutionDir%Publish\Windows\*.dll" "%SolutionDir%Publish\Windows\Lib\"
+ move "%SolutionDir%Publish\Windows\*.json" "%SolutionDir%Publish\Windows\Lib\"
+)
+
+echo PR-RT
+move "%SolutionDir%Publish\WindowsPrerelease\runtimes" "%SolutionDir%Publish\WindowsPrerelease\Lib\runtimes"
+
+if "%CurrentConfiguration" == "Release" (
+ echo R-RT
+ rem move "%SolutionDir%Publish\Windows\runtimes" "%SolutionDir%Publish\Windows\Lib\runtimes"
+)
+
+echo making start scripts
+@echo dotnet Lib/IW4MAdmin.dll > "%SolutionDir%Publish\WindowsPrerelease\StartIW4MAdmin.cmd"
+@echo dotnet Lib/IW4MAdmin.dll > "%SolutionDir%Publish\Windows\StartIW4MAdmin.cmd"
+
+@(echo #!/bin/bash && echo dotnet Lib\IW4MAdmin.dll) > "%SolutionDir%Publish\WindowsPrerelease\StartIW4MAdmin.sh"
+@(echo #!/bin/bash && echo dotnet Lib\IW4MAdmin.dll) > "%SolutionDir%Publish\Windows\StartIW4MAdmin.sh"
diff --git a/Application/Logger.cs b/Application/Logger.cs
index d11a8b56e..0f3597f1e 100644
--- a/Application/Logger.cs
+++ b/Application/Logger.cs
@@ -22,7 +22,7 @@ namespace IW4MAdmin.Application
public Logger(string fn)
{
- FileName = fn;
+ FileName = Path.Join("Log", fn);
ThreadLock = new object();
if (File.Exists(fn))
File.Delete(fn);
diff --git a/Application/Main.cs b/Application/Main.cs
index 550731de5..6b945d875 100644
--- a/Application/Main.cs
+++ b/Application/Main.cs
@@ -16,13 +16,12 @@ namespace IW4MAdmin.Application
public class Program
{
static public double Version { get; private set; }
- static public ApplicationManager ServerManager = ApplicationManager.GetInstance();
- public static string OperatingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar;
+ static public ApplicationManager ServerManager;
private static ManualResetEventSlim OnShutdownComplete = new ManualResetEventSlim();
public static void Main(string[] args)
{
- AppDomain.CurrentDomain.SetData("DataDirectory", OperatingDirectory);
+ AppDomain.CurrentDomain.SetData("DataDirectory", Utilities.OperatingDirectory);
Console.OutputEncoding = Encoding.UTF8;
Console.ForegroundColor = ConsoleColor.Gray;
@@ -169,15 +168,25 @@ namespace IW4MAdmin.Application
private static void OnCancelKey(object sender, ConsoleCancelEventArgs e)
{
ServerManager.Stop();
- OnShutdownComplete.Wait(5000);
+ OnShutdownComplete.Wait();
}
static void CheckDirectories()
{
- string curDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar;
+ if (!Directory.Exists(Path.Join(Utilities.OperatingDirectory, "Plugins")))
+ {
+ Directory.CreateDirectory(Path.Join(Utilities.OperatingDirectory, "Plugins"));
+ }
- if (!Directory.Exists($"{curDirectory}Plugins"))
- Directory.CreateDirectory($"{curDirectory}Plugins");
+ if (!Directory.Exists(Path.Join(Utilities.OperatingDirectory, "Database")))
+ {
+ Directory.CreateDirectory(Path.Join(Utilities.OperatingDirectory, "Database"));
+ }
+
+ if (!Directory.Exists(Path.Join(Utilities.OperatingDirectory, "Log")))
+ {
+ Directory.CreateDirectory(Path.Join(Utilities.OperatingDirectory, "Log"));
+ }
}
}
}
diff --git a/Application/Manager.cs b/Application/Manager.cs
index fccaf38de..d81cf80b9 100644
--- a/Application/Manager.cs
+++ b/Application/Manager.cs
@@ -18,6 +18,7 @@ using SharedLibraryCore.Database;
using SharedLibraryCore.Events;
using IW4MAdmin.Application.API.Master;
+using IW4MAdmin.Application.Migration;
namespace IW4MAdmin.Application
{
@@ -51,7 +52,9 @@ namespace IW4MAdmin.Application
private ApplicationManager()
{
- Logger = new Logger($@"{Utilities.OperatingDirectory}IW4MAdmin.log");
+ Logger = new Logger("IW4MAdmin.log");
+ // do any needed migrations
+ ConfigurationMigration.MoveConfigFolder10518(Logger);
_servers = new List();
Commands = new List();
TaskStatuses = new List();
diff --git a/Application/Migration/ConfigurationMigration.cs b/Application/Migration/ConfigurationMigration.cs
new file mode 100644
index 000000000..2745d1d13
--- /dev/null
+++ b/Application/Migration/ConfigurationMigration.cs
@@ -0,0 +1,53 @@
+using SharedLibraryCore;
+using SharedLibraryCore.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace IW4MAdmin.Application.Migration
+{
+ ///
+ /// helps facilitate the migration of configs from one version and or location
+ /// to another
+ ///
+ class ConfigurationMigration
+ {
+ ///
+ /// moves existing configs from the root folder into a configs folder
+ ///
+ public static void MoveConfigFolder10518(ILogger log)
+ {
+ string currentDirectory = Utilities.OperatingDirectory;
+
+ // we don't want to do this for migrations or tests where the
+ // property isn't initialized or it's wrong
+ if (currentDirectory != null)
+ {
+ string configDirectory = Path.Join(currentDirectory, "Configuration");
+
+ if (!Directory.Exists(configDirectory))
+ {
+ log.WriteDebug($"Creating directory for configs {configDirectory}");
+ Directory.CreateDirectory(configDirectory);
+ }
+
+ var configurationFiles = Directory.EnumerateFiles(currentDirectory, "*.json")
+ .Select(f => f.Split(Path.DirectorySeparatorChar).Last())
+ .Where(f => f.Count(c => c == '.') == 1);
+
+ foreach (var configFile in configurationFiles)
+ {
+ log.WriteDebug($"Moving config file {configFile}");
+ string destinationPath = Path.Join("Configuration", configFile);
+ if (!File.Exists(destinationPath))
+ {
+ File.Move(configFile, destinationPath);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Plugins/Stats/Helpers/StatManager.cs b/Plugins/Stats/Helpers/StatManager.cs
index 3966672ac..ad7f01501 100644
--- a/Plugins/Stats/Helpers/StatManager.cs
+++ b/Plugins/Stats/Helpers/StatManager.cs
@@ -252,7 +252,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
if (playerStats.ContainsKey(pl.ClientId))
{
Log.WriteWarning($"Duplicate ClientId in stats {pl.ClientId}");
- return null;
+ return playerStats[pl.ClientId];
}
// get the client's stats from the database if it exists, otherwise create and attach a new one
@@ -281,20 +281,35 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
};
// insert if they've not been added
- clientStatsSvc.Insert(clientStats);
+ clientStats = clientStatsSvc.Insert(clientStats);
+
+ if (!playerStats.TryAdd(clientStats.ClientId, clientStats))
+ {
+ Log.WriteWarning("Adding new client to stats failed");
+ }
+
await clientStatsSvc.SaveChangesAsync();
}
+ else
+ {
+ if (!playerStats.TryAdd(clientStats.ClientId, clientStats))
+ {
+ Log.WriteWarning("Adding pre-existing client to stats failed");
+ }
+ }
+
// migration for previous existing stats
if (clientStats.HitLocations.Count == 0)
{
- clientStats.HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType().Select(hl => new EFHitLocationCount()
- {
- Active = true,
- HitCount = 0,
- Location = hl
- })
- .ToList();
+ clientStats.HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType()
+ .Select(hl => new EFHitLocationCount()
+ {
+ Active = true,
+ HitCount = 0,
+ Location = hl
+ })
+ .ToList();
await statsSvc.ClientStatSvc.SaveChangesAsync();
}
@@ -315,14 +330,12 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
clientStats.SessionScore = pl.Score;
clientStats.LastScore = pl.Score;
- Log.WriteInfo($"Adding {pl} to stats");
-
- if (!playerStats.TryAdd(pl.ClientId, clientStats))
- Log.WriteDebug($"Could not add client to stats {pl}");
-
if (!detectionStats.TryAdd(pl.ClientId, new Cheat.Detection(Log, clientStats)))
- Log.WriteDebug("Could not add client to detection");
+ {
+ Log.WriteWarning("Could not add client to detection");
+ }
+ Log.WriteInfo($"Adding {pl} to stats");
return clientStats;
}
@@ -473,7 +486,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
var clientStats = Servers[serverId].PlayerStats[attacker.ClientId];
var clientStatsSvc = statsSvc.ClientStatSvc;
clientStatsSvc.Update(clientStats);
-
// increment their hit count
if (hit.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET ||
@@ -496,8 +508,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
if (Plugin.Config.Configuration().EnableAntiCheat)
{
- await ApplyPenalty(clientDetection.ProcessKill(hit, isDamage), clientDetection, attacker, ctx);
- await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx);
+ ApplyPenalty(clientDetection.ProcessKill(hit, isDamage), clientDetection, attacker, ctx);
+ ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx);
}
ctx.Set().UpdateRange(clientStats.HitLocations);
@@ -526,7 +538,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
}
}
- async Task ApplyPenalty(Cheat.DetectionPenaltyResult penalty, Cheat.Detection clientDetection, Player attacker, DatabaseContext ctx)
+ void ApplyPenalty(Cheat.DetectionPenaltyResult penalty, Cheat.Detection clientDetection, Player attacker, DatabaseContext ctx)
{
switch (penalty.ClientPenalty)
{
@@ -546,7 +558,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
$"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" :
$"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}",
}
- }
+ },
+ Level = Player.Permission.Console,
+ CurrentServer = attacker.CurrentServer
});
if (clientDetection.Tracker.HasChanges)
{
@@ -558,30 +572,23 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
{
break;
}
- var e = new GameEvent()
- {
- Data = penalty.Type == Cheat.Detection.DetectionType.Bone ?
+
+ string flagReason = penalty.Type == Cheat.Detection.DetectionType.Bone ?
$"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" :
- $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}",
- Origin = new Player()
- {
- ClientId = 1,
- Level = Player.Permission.Console,
- ClientNumber = -1,
- CurrentServer = attacker.CurrentServer
- },
- Target = attacker,
- Owner = attacker.CurrentServer,
- Type = GameEvent.EventType.Flag
- };
- // because we created an event it must be processed by the manager
- // even if it didn't really do anything
- Manager.GetEventHandler().AddEvent(e);
- await new CFlag().ExecuteAsync(e);
+ $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}";
+
+ attacker.Flag(flagReason, new Player()
+ {
+ ClientId = 1,
+ Level = Player.Permission.Console,
+ CurrentServer = attacker.CurrentServer,
+ });
+
if (clientDetection.Tracker.HasChanges)
{
SaveTrackedSnapshots(clientDetection, ctx);
}
+
break;
}
}
diff --git a/Plugins/Stats/Plugin.cs b/Plugins/Stats/Plugin.cs
index 6b473c6dc..88132ad67 100644
--- a/Plugins/Stats/Plugin.cs
+++ b/Plugins/Stats/Plugin.cs
@@ -231,7 +231,8 @@ namespace IW4MAdmin.Plugins.Stats
new ProfileMeta()
{
Key = "Hit Offset Average",
- Value = $"{Math.Round(((float)hitOffsetAverage), 4)}°",
+ // todo: make sure this is wrapped somewhere else
+ Value = $"{Math.Round(((float)hitOffsetAverage), 4).ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName))}°",
Sensitive = true
},
new ProfileMeta()
diff --git a/SharedLibraryCore/Database/DatabaseContext.cs b/SharedLibraryCore/Database/DatabaseContext.cs
index ca63ae56b..8739bb525 100644
--- a/SharedLibraryCore/Database/DatabaseContext.cs
+++ b/SharedLibraryCore/Database/DatabaseContext.cs
@@ -24,7 +24,6 @@ namespace SharedLibraryCore.Database
public DbSet EFMeta { get; set; }
public DbSet EFChangeHistory { get; set; }
-
static string _ConnectionString;
static string _provider;
@@ -52,21 +51,17 @@ namespace SharedLibraryCore.Database
{
if (string.IsNullOrEmpty(_ConnectionString))
{
- string currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
+ string currentPath = Utilities.OperatingDirectory;
// allows the application to find the database file
currentPath = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
$"{Path.DirectorySeparatorChar}{currentPath}" :
currentPath;
- var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = $"{currentPath}{Path.DirectorySeparatorChar}Database.db".Substring(6) };
+ var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = $"{currentPath}{Path.DirectorySeparatorChar}Database{Path.DirectorySeparatorChar}Database.db" };
var connectionString = connectionStringBuilder.ToString();
var connection = new SqliteConnection(connectionString);
- //#if DEBUG == true
- //optionsBuilder.UseMySql("UserId=root;Password=dev;Host=127.0.0.1;port=3306;Database=IW4MAdmin");
- // optionsBuilder.UseNpgsql("UserId=dev;Password=dev;Host=127.0.0.1;port=5432;Database=IW4MAdmin");
- //#else
+
optionsBuilder.UseSqlite(connection);
- //#endif
}
else
diff --git a/SharedLibraryCore/Helpers/BaseConfigurationHandler.cs b/SharedLibraryCore/Helpers/BaseConfigurationHandler.cs
index ba49667b4..3780f1572 100644
--- a/SharedLibraryCore/Helpers/BaseConfigurationHandler.cs
+++ b/SharedLibraryCore/Helpers/BaseConfigurationHandler.cs
@@ -25,7 +25,7 @@ namespace SharedLibraryCore.Configuration
public void Build()
{
ConfigurationRoot = new ConfigurationBuilder()
- .AddJsonFile($"{AppDomain.CurrentDomain.BaseDirectory}{Filename}.json", true)
+ .AddJsonFile(Path.Join(Utilities.OperatingDirectory, "Configuration", $"{Filename}.json"), true)
.Build();
_configuration = ConfigurationRoot.Get();
@@ -37,10 +37,7 @@ namespace SharedLibraryCore.Configuration
public Task Save()
{
var appConfigJSON = JsonConvert.SerializeObject(_configuration, Formatting.Indented);
- return Task.Factory.StartNew(() =>
- {
- File.WriteAllText($"{AppDomain.CurrentDomain.BaseDirectory}{Filename}.json", appConfigJSON);
- });
+ return File.WriteAllTextAsync(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Configuration", $"{Filename}.json"), appConfigJSON);
}
public T Configuration() => _configuration;
diff --git a/SharedLibraryCore/SharedLibraryCore.csproj b/SharedLibraryCore/SharedLibraryCore.csproj
index 6e1126566..489c781d4 100644
--- a/SharedLibraryCore/SharedLibraryCore.csproj
+++ b/SharedLibraryCore/SharedLibraryCore.csproj
@@ -23,9 +23,9 @@
-
-
-
+
+
+
diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs
index 9655ea9f7..82ce9ad0e 100644
--- a/SharedLibraryCore/Utilities.cs
+++ b/SharedLibraryCore/Utilities.cs
@@ -20,7 +20,11 @@ namespace SharedLibraryCore
{
public static class Utilities
{
- public static string OperatingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar;
+#if DEBUG == true
+ public static string OperatingDirectory => $"{Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)}{Path.DirectorySeparatorChar}";
+#else
+ public static string OperatingDirectory => $"{Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)}{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}";
+#endif
public static Encoding EncodingType;
public static Localization.Layout CurrentLocalization = new Localization.Layout(new Dictionary());
public static Player IW4MAdminClient = new Player() { ClientId = 1, Level = Player.Permission.Console };
diff --git a/WebfrontCore/Program.cs b/WebfrontCore/Program.cs
index 05f537396..661538ba6 100644
--- a/WebfrontCore/Program.cs
+++ b/WebfrontCore/Program.cs
@@ -30,7 +30,7 @@ namespace WebfrontCore
#if DEBUG
.UseContentRoot(Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @"..\..\..\..\", "WebfrontCore")))
#else
- .UseContentRoot(Directory.GetCurrentDirectory())
+ .UseContentRoot(Path.Join(Directory.GetCurrentDirectory(), "..\\"))
#endif
.UseUrls(Manager.GetApplicationSettings().Configuration().WebfrontBindUrl)
.UseKestrel()