clean up publish folder output to have a less cluttered structure.

add migration class to perform the migration on update
This commit is contained in:
RaidMax 2018-10-05 22:10:39 -05:00
parent 9d946d1bad
commit c7547f1ad5
13 changed files with 176 additions and 73 deletions

View File

@ -92,6 +92,6 @@
</Target> </Target>
<Target Name="PostPublish" AfterTargets="Publish"> <Target Name="PostPublish" AfterTargets="Publish">
<Exec Command="call $(ProjectDir)BuildScripts\PostPublish.bat $(ProjectDir)..\ $(ProjectDir) $(TargetDir) $(OutDir)" /> <Exec Command="call $(ProjectDir)BuildScripts\PostPublish.bat $(ProjectDir)..\ $(ProjectDir) $(TargetDir) $(OutDir) $(CurrentConfiguration)" />
</Target> </Target>
</Project> </Project>

View File

@ -1,6 +1,8 @@
set SolutionDir=%1 set SolutionDir=%1
set ProjectDir=%2 set ProjectDir=%2
set TargetDir=%3 set TargetDir=%3
set CurrentConfiguration=%4
SET COPYCMD=/Y
echo Deleting extra language files 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" if exist "%SolutionDir%Publish\WindowsPrerelease\web.config" del "%SolutionDir%Publish\WindowsPrerelease\web.config"
del "%SolutionDir%Publish\WindowsPrerelease\*pdb" del "%SolutionDir%Publish\WindowsPrerelease\*pdb"
echo making start scripts echo setting up library folders
@echo dotnet IW4MAdmin.dll > "%SolutionDir%Publish\WindowsPrerelease\StartIW4MAdmin.cmd"
@echo dotnet IW4MAdmin.dll > "%SolutionDir%Publish\Windows\StartIW4MAdmin.cmd"
@(echo #!/bin/bash && echo dotnet IW4MAdmin.dll) > "%SolutionDir%Publish\WindowsPrerelease\StartIW4MAdmin.sh" echo PR-Config
@(echo #!/bin/bash && echo dotnet IW4MAdmin.dll) > "%SolutionDir%Publish\Windows\StartIW4MAdmin.sh" 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"

View File

@ -22,7 +22,7 @@ namespace IW4MAdmin.Application
public Logger(string fn) public Logger(string fn)
{ {
FileName = fn; FileName = Path.Join("Log", fn);
ThreadLock = new object(); ThreadLock = new object();
if (File.Exists(fn)) if (File.Exists(fn))
File.Delete(fn); File.Delete(fn);

View File

@ -16,13 +16,12 @@ namespace IW4MAdmin.Application
public class Program public class Program
{ {
static public double Version { get; private set; } static public double Version { get; private set; }
static public ApplicationManager ServerManager = ApplicationManager.GetInstance(); static public ApplicationManager ServerManager;
public static string OperatingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar;
private static ManualResetEventSlim OnShutdownComplete = new ManualResetEventSlim(); private static ManualResetEventSlim OnShutdownComplete = new ManualResetEventSlim();
public static void Main(string[] args) public static void Main(string[] args)
{ {
AppDomain.CurrentDomain.SetData("DataDirectory", OperatingDirectory); AppDomain.CurrentDomain.SetData("DataDirectory", Utilities.OperatingDirectory);
Console.OutputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8;
Console.ForegroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.Gray;
@ -169,15 +168,25 @@ namespace IW4MAdmin.Application
private static void OnCancelKey(object sender, ConsoleCancelEventArgs e) private static void OnCancelKey(object sender, ConsoleCancelEventArgs e)
{ {
ServerManager.Stop(); ServerManager.Stop();
OnShutdownComplete.Wait(5000); OnShutdownComplete.Wait();
} }
static void CheckDirectories() 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")) if (!Directory.Exists(Path.Join(Utilities.OperatingDirectory, "Database")))
Directory.CreateDirectory($"{curDirectory}Plugins"); {
Directory.CreateDirectory(Path.Join(Utilities.OperatingDirectory, "Database"));
}
if (!Directory.Exists(Path.Join(Utilities.OperatingDirectory, "Log")))
{
Directory.CreateDirectory(Path.Join(Utilities.OperatingDirectory, "Log"));
}
} }
} }
} }

View File

@ -18,6 +18,7 @@ using SharedLibraryCore.Database;
using SharedLibraryCore.Events; using SharedLibraryCore.Events;
using IW4MAdmin.Application.API.Master; using IW4MAdmin.Application.API.Master;
using IW4MAdmin.Application.Migration;
namespace IW4MAdmin.Application namespace IW4MAdmin.Application
{ {
@ -51,7 +52,9 @@ namespace IW4MAdmin.Application
private ApplicationManager() private ApplicationManager()
{ {
Logger = new Logger($@"{Utilities.OperatingDirectory}IW4MAdmin.log"); Logger = new Logger("IW4MAdmin.log");
// do any needed migrations
ConfigurationMigration.MoveConfigFolder10518(Logger);
_servers = new List<Server>(); _servers = new List<Server>();
Commands = new List<Command>(); Commands = new List<Command>();
TaskStatuses = new List<AsyncStatus>(); TaskStatuses = new List<AsyncStatus>();

View File

@ -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
{
/// <summary>
/// helps facilitate the migration of configs from one version and or location
/// to another
/// </summary>
class ConfigurationMigration
{
/// <summary>
/// moves existing configs from the root folder into a configs folder
/// </summary>
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);
}
}
}
}
}
}

View File

@ -252,7 +252,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
if (playerStats.ContainsKey(pl.ClientId)) if (playerStats.ContainsKey(pl.ClientId))
{ {
Log.WriteWarning($"Duplicate ClientId in stats {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 // 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 // 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(); await clientStatsSvc.SaveChangesAsync();
} }
else
{
if (!playerStats.TryAdd(clientStats.ClientId, clientStats))
{
Log.WriteWarning("Adding pre-existing client to stats failed");
}
}
// migration for previous existing stats // migration for previous existing stats
if (clientStats.HitLocations.Count == 0) if (clientStats.HitLocations.Count == 0)
{ {
clientStats.HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType<IW4Info.HitLocation>().Select(hl => new EFHitLocationCount() clientStats.HitLocations = Enum.GetValues(typeof(IW4Info.HitLocation)).OfType<IW4Info.HitLocation>()
{ .Select(hl => new EFHitLocationCount()
Active = true, {
HitCount = 0, Active = true,
Location = hl HitCount = 0,
}) Location = hl
.ToList(); })
.ToList();
await statsSvc.ClientStatSvc.SaveChangesAsync(); await statsSvc.ClientStatSvc.SaveChangesAsync();
} }
@ -315,14 +330,12 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
clientStats.SessionScore = pl.Score; clientStats.SessionScore = pl.Score;
clientStats.LastScore = 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))) 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; return clientStats;
} }
@ -473,7 +486,6 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
var clientStats = Servers[serverId].PlayerStats[attacker.ClientId]; var clientStats = Servers[serverId].PlayerStats[attacker.ClientId];
var clientStatsSvc = statsSvc.ClientStatSvc; var clientStatsSvc = statsSvc.ClientStatSvc;
clientStatsSvc.Update(clientStats); clientStatsSvc.Update(clientStats);
// increment their hit count // increment their hit count
if (hit.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET || if (hit.DeathType == IW4Info.MeansOfDeath.MOD_PISTOL_BULLET ||
@ -496,8 +508,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
if (Plugin.Config.Configuration().EnableAntiCheat) if (Plugin.Config.Configuration().EnableAntiCheat)
{ {
await ApplyPenalty(clientDetection.ProcessKill(hit, isDamage), clientDetection, attacker, ctx); ApplyPenalty(clientDetection.ProcessKill(hit, isDamage), clientDetection, attacker, ctx);
await ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx); ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx);
} }
ctx.Set<EFHitLocationCount>().UpdateRange(clientStats.HitLocations); ctx.Set<EFHitLocationCount>().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) 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}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" :
$"{penalty.Type}-{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) if (clientDetection.Tracker.HasChanges)
{ {
@ -558,30 +572,23 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
{ {
break; break;
} }
var e = new GameEvent()
{ string flagReason = penalty.Type == Cheat.Detection.DetectionType.Bone ?
Data = penalty.Type == Cheat.Detection.DetectionType.Bone ?
$"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" : $"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" :
$"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}", $"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}";
Origin = new Player()
{ attacker.Flag(flagReason, new Player()
ClientId = 1, {
Level = Player.Permission.Console, ClientId = 1,
ClientNumber = -1, Level = Player.Permission.Console,
CurrentServer = attacker.CurrentServer 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);
if (clientDetection.Tracker.HasChanges) if (clientDetection.Tracker.HasChanges)
{ {
SaveTrackedSnapshots(clientDetection, ctx); SaveTrackedSnapshots(clientDetection, ctx);
} }
break; break;
} }
} }

View File

@ -231,7 +231,8 @@ namespace IW4MAdmin.Plugins.Stats
new ProfileMeta() new ProfileMeta()
{ {
Key = "Hit Offset Average", 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 Sensitive = true
}, },
new ProfileMeta() new ProfileMeta()

View File

@ -24,7 +24,6 @@ namespace SharedLibraryCore.Database
public DbSet<EFMeta> EFMeta { get; set; } public DbSet<EFMeta> EFMeta { get; set; }
public DbSet<EFChangeHistory> EFChangeHistory { get; set; } public DbSet<EFChangeHistory> EFChangeHistory { get; set; }
static string _ConnectionString; static string _ConnectionString;
static string _provider; static string _provider;
@ -52,21 +51,17 @@ namespace SharedLibraryCore.Database
{ {
if (string.IsNullOrEmpty(_ConnectionString)) if (string.IsNullOrEmpty(_ConnectionString))
{ {
string currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase); string currentPath = Utilities.OperatingDirectory;
// allows the application to find the database file // allows the application to find the database file
currentPath = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? currentPath = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
$"{Path.DirectorySeparatorChar}{currentPath}" : $"{Path.DirectorySeparatorChar}{currentPath}" :
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 connectionString = connectionStringBuilder.ToString();
var connection = new SqliteConnection(connectionString); 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); optionsBuilder.UseSqlite(connection);
//#endif
} }
else else

View File

@ -25,7 +25,7 @@ namespace SharedLibraryCore.Configuration
public void Build() public void Build()
{ {
ConfigurationRoot = new ConfigurationBuilder() ConfigurationRoot = new ConfigurationBuilder()
.AddJsonFile($"{AppDomain.CurrentDomain.BaseDirectory}{Filename}.json", true) .AddJsonFile(Path.Join(Utilities.OperatingDirectory, "Configuration", $"{Filename}.json"), true)
.Build(); .Build();
_configuration = ConfigurationRoot.Get<T>(); _configuration = ConfigurationRoot.Get<T>();
@ -37,10 +37,7 @@ namespace SharedLibraryCore.Configuration
public Task Save() public Task Save()
{ {
var appConfigJSON = JsonConvert.SerializeObject(_configuration, Formatting.Indented); var appConfigJSON = JsonConvert.SerializeObject(_configuration, Formatting.Indented);
return Task.Factory.StartNew(() => return File.WriteAllTextAsync(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Configuration", $"{Filename}.json"), appConfigJSON);
{
File.WriteAllText($"{AppDomain.CurrentDomain.BaseDirectory}{Filename}.json", appConfigJSON);
});
} }
public T Configuration() => _configuration; public T Configuration() => _configuration;

View File

@ -23,9 +23,9 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Jint" Version="2.11.58" /> <PackageReference Include="Jint" Version="2.11.58" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.4" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="2.1.1" /> <PackageReference Include="Microsoft.Extensions.Localization" Version="2.1.1" />

View File

@ -20,7 +20,11 @@ namespace SharedLibraryCore
{ {
public static class Utilities 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 Encoding EncodingType;
public static Localization.Layout CurrentLocalization = new Localization.Layout(new Dictionary<string, string>()); public static Localization.Layout CurrentLocalization = new Localization.Layout(new Dictionary<string, string>());
public static Player IW4MAdminClient = new Player() { ClientId = 1, Level = Player.Permission.Console }; public static Player IW4MAdminClient = new Player() { ClientId = 1, Level = Player.Permission.Console };

View File

@ -30,7 +30,7 @@ namespace WebfrontCore
#if DEBUG #if DEBUG
.UseContentRoot(Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @"..\..\..\..\", "WebfrontCore"))) .UseContentRoot(Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), @"..\..\..\..\", "WebfrontCore")))
#else #else
.UseContentRoot(Directory.GetCurrentDirectory()) .UseContentRoot(Path.Join(Directory.GetCurrentDirectory(), "..\\"))
#endif #endif
.UseUrls(Manager.GetApplicationSettings().Configuration().WebfrontBindUrl) .UseUrls(Manager.GetApplicationSettings().Configuration().WebfrontBindUrl)
.UseKestrel() .UseKestrel()