From 82390340c9fdd4872d81494b36ea2bdadd69b1e6 Mon Sep 17 00:00:00 2001
From: RaidMax <raidmax@live.com>
Date: Sun, 9 Jun 2019 09:50:58 -0500
Subject: [PATCH] fix duplicate meta data when restarting fix issue with
 parsing anticheat info in non en-US culture fix rare issue with client spots
 "swapping" don't copy referenced shared library assemeblies from plugins

---
 Application/Application.csproj                |  6 ++---
 Application/IO/GameLogReaderHttp.cs           |  2 +-
 Application/IW4MServer.cs                     | 22 ++++++++++++++-----
 .../AutomessageFeed/AutomessageFeed.csproj    |  4 +++-
 .../IW4ScriptCommands.csproj                  |  8 +++++--
 Plugins/Login/Login.csproj                    |  4 +++-
 .../ProfanityDeterment.csproj                 |  4 +++-
 Plugins/Stats/Helpers/StatManager.cs          |  6 ++---
 Plugins/Stats/Stats.csproj                    |  8 +++++--
 Plugins/Web/StatsWeb/StatsWeb.csproj          |  4 +++-
 Plugins/Welcome/Welcome.csproj                |  4 +++-
 SharedLibraryCore/Commands/NativeCommands.cs  |  1 +
 SharedLibraryCore/Helpers/Vector3.cs          | 11 ++++++----
 SharedLibraryCore/Services/MetaService.cs     |  5 +++++
 SharedLibraryCore/Utilities.cs                |  1 +
 15 files changed, 64 insertions(+), 26 deletions(-)

diff --git a/Application/Application.csproj b/Application/Application.csproj
index e90c6608d..55733d0c6 100644
--- a/Application/Application.csproj
+++ b/Application/Application.csproj
@@ -6,7 +6,7 @@
     <RuntimeFrameworkVersion>2.2.2</RuntimeFrameworkVersion>
     <MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
     <PackageId>RaidMax.IW4MAdmin.Application</PackageId>
-    <Version>2.2.7.4</Version>
+    <Version>2.2.7.5</Version>
     <Authors>RaidMax</Authors>
     <Company>Forever None</Company>
     <Product>IW4MAdmin</Product>
@@ -32,8 +32,8 @@
   <PropertyGroup>
     <ServerGarbageCollection>true</ServerGarbageCollection>
     <TieredCompilation>true</TieredCompilation>
-    <AssemblyVersion>2.2.7.4</AssemblyVersion>
-    <FileVersion>2.2.7.4</FileVersion>
+    <AssemblyVersion>2.2.7.5</AssemblyVersion>
+    <FileVersion>2.2.7.5</FileVersion>
     <LangVersion>7.1</LangVersion>
   </PropertyGroup>
 
diff --git a/Application/IO/GameLogReaderHttp.cs b/Application/IO/GameLogReaderHttp.cs
index 6177e2893..33ea70885 100644
--- a/Application/IO/GameLogReaderHttp.cs
+++ b/Application/IO/GameLogReaderHttp.cs
@@ -30,7 +30,7 @@ namespace IW4MAdmin.Application.IO
 
         public long Length => -1;
 
-        public int UpdateInterval => 350;
+        public int UpdateInterval => 550;
 
         public async Task<ICollection<GameEvent>> ReadEventsFromLog(Server server, long fileSizeDiff, long startPosition)
         {
diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs
index dfd6c0682..d3ed94064 100644
--- a/Application/IW4MServer.cs
+++ b/Application/IW4MServer.cs
@@ -164,6 +164,10 @@ namespace IW4MAdmin
         /// <returns></returns>
         override protected async Task<bool> ProcessEvent(GameEvent E)
         {
+#if DEBUG
+            Logger.WriteDebug($"processing event of type {E.Type}");
+#endif
+
             if (E.Type == GameEvent.EventType.ConnectionLost)
             {
                 var exception = E.Extra as Exception;
@@ -204,13 +208,21 @@ namespace IW4MAdmin
                 var existingClient = GetClientsAsList().FirstOrDefault(_client => _client.Equals(E.Origin));
 
                 // they're already connected
-                if (existingClient != null && !E.Origin.IsBot)
+                if (existingClient != null && existingClient.ClientNumber == E.Origin.ClientNumber && !E.Origin.IsBot)
                 {
                     Logger.WriteWarning($"detected preconnect for {E.Origin}, but they are already connected");
                     return false;
                 }
 
-            //CONNECT:
+                // this happens for some reason rarely where the client spots get out of order
+                // possible a connect/reconnect game event before we get to process it here 
+                else if (existingClient != null && existingClient.ClientNumber != E.Origin.ClientNumber)
+                {
+                    Logger.WriteWarning($"client {E.Origin} is trying to connect in client slot {E.Origin.ClientNumber}, but they are already registed in client slot {existingClient.ClientNumber}, swapping...");
+                    // we need to remove them so the client spots can swap
+                    await OnClientDisconnected(Clients[existingClient.ClientNumber]);
+                }
+
                 if (Clients[E.Origin.ClientNumber] == null)
                 {
 #if DEBUG == true
@@ -249,8 +261,6 @@ namespace IW4MAdmin
                 else
                 {
                     Logger.WriteWarning($"{E.Origin} is connecting but {Clients[E.Origin.ClientNumber]} is currently in that client slot");
-                    //await OnClientDisconnected(Clients[E.Origin.ClientNumber]);
-                    //goto CONNECT;
                 }
             }
 
@@ -561,7 +571,7 @@ namespace IW4MAdmin
         {
             try
             {
-                #region SHUTDOWN
+#region SHUTDOWN
                 if (Manager.CancellationToken.IsCancellationRequested)
                 {
                     foreach (var client in GetClientsAsList())
@@ -584,7 +594,7 @@ namespace IW4MAdmin
 
                     return true;
                 }
-                #endregion
+#endregion
 
                 try
                 {
diff --git a/Plugins/AutomessageFeed/AutomessageFeed.csproj b/Plugins/AutomessageFeed/AutomessageFeed.csproj
index 07649de56..47d92a060 100644
--- a/Plugins/AutomessageFeed/AutomessageFeed.csproj
+++ b/Plugins/AutomessageFeed/AutomessageFeed.csproj
@@ -11,7 +11,9 @@
   </ItemGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj" />
+    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj">
+      <Private>false</Private>
+    </ProjectReference>
   </ItemGroup>
 
   <Target Name="PostBuild" AfterTargets="PostBuildEvent">
diff --git a/Plugins/IW4ScriptCommands/IW4ScriptCommands.csproj b/Plugins/IW4ScriptCommands/IW4ScriptCommands.csproj
index 000ead82c..ae9424209 100644
--- a/Plugins/IW4ScriptCommands/IW4ScriptCommands.csproj
+++ b/Plugins/IW4ScriptCommands/IW4ScriptCommands.csproj
@@ -15,8 +15,12 @@
   </Target>
 
   <ItemGroup>
-    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj" />
-    <ProjectReference Include="..\Stats\Stats.csproj" />
+    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj">
+      <Private>false</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\Stats\Stats.csproj">
+      <Private>false</Private>
+    </ProjectReference>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/Plugins/Login/Login.csproj b/Plugins/Login/Login.csproj
index ca3cfdcc0..12463fd10 100644
--- a/Plugins/Login/Login.csproj
+++ b/Plugins/Login/Login.csproj
@@ -19,7 +19,9 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj" />
+    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj">
+      <Private>false</Private>
+    </ProjectReference>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/Plugins/ProfanityDeterment/ProfanityDeterment.csproj b/Plugins/ProfanityDeterment/ProfanityDeterment.csproj
index 3c65ec079..6a36bd557 100644
--- a/Plugins/ProfanityDeterment/ProfanityDeterment.csproj
+++ b/Plugins/ProfanityDeterment/ProfanityDeterment.csproj
@@ -17,7 +17,9 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj" />
+    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj">
+      <Private>false</Private>
+    </ProjectReference>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/Plugins/Stats/Helpers/StatManager.cs b/Plugins/Stats/Helpers/StatManager.cs
index 4b23f8eb7..76924a968 100644
--- a/Plugins/Stats/Helpers/StatManager.cs
+++ b/Plugins/Stats/Helpers/StatManager.cs
@@ -509,9 +509,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
                 TimeOffset = Int64.Parse(offset),
                 When = time,
                 IsKillstreakKill = isKillstreakKill[0] != '0',
-                AdsPercent = float.Parse(Ads),
-                Fraction = double.Parse(fraction),
-                VisibilityPercentage = double.Parse(visibilityPercentage),
+                AdsPercent = float.Parse(Ads, System.Globalization.CultureInfo.InvariantCulture),
+                Fraction = double.Parse(fraction, System.Globalization.CultureInfo.InvariantCulture),
+                VisibilityPercentage = double.Parse(visibilityPercentage, System.Globalization.CultureInfo.InvariantCulture),
                 IsKill = !isDamage,
                 AnglesList = snapshotAngles
             };
diff --git a/Plugins/Stats/Stats.csproj b/Plugins/Stats/Stats.csproj
index 5f9a8c4dc..4f371e775 100644
--- a/Plugins/Stats/Stats.csproj
+++ b/Plugins/Stats/Stats.csproj
@@ -17,8 +17,12 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj" />
-    <ProjectReference Include="..\..\WebfrontCore\WebfrontCore.csproj" />
+    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj">
+      <Private>false</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\WebfrontCore\WebfrontCore.csproj">
+      <Private>false</Private>
+    </ProjectReference>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/Plugins/Web/StatsWeb/StatsWeb.csproj b/Plugins/Web/StatsWeb/StatsWeb.csproj
index 6113d0c51..e4550db72 100644
--- a/Plugins/Web/StatsWeb/StatsWeb.csproj
+++ b/Plugins/Web/StatsWeb/StatsWeb.csproj
@@ -12,7 +12,9 @@
   </ItemGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\..\Stats\Stats.csproj" />
+    <ProjectReference Include="..\..\Stats\Stats.csproj">
+      <Private>false</Private>
+    </ProjectReference>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/Plugins/Welcome/Welcome.csproj b/Plugins/Welcome/Welcome.csproj
index bf5a7fb8e..caefd0da7 100644
--- a/Plugins/Welcome/Welcome.csproj
+++ b/Plugins/Welcome/Welcome.csproj
@@ -17,7 +17,9 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj" />
+    <ProjectReference Include="..\..\SharedLibraryCore\SharedLibraryCore.csproj">
+      <Private>false</Private>
+    </ProjectReference>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/SharedLibraryCore/Commands/NativeCommands.cs b/SharedLibraryCore/Commands/NativeCommands.cs
index cc7caf9ab..bb712d1a1 100644
--- a/SharedLibraryCore/Commands/NativeCommands.cs
+++ b/SharedLibraryCore/Commands/NativeCommands.cs
@@ -36,6 +36,7 @@ namespace SharedLibraryCore.Commands
 
         public override Task ExecuteAsync(GameEvent E)
         {
+            MetaService.Clear();
             E.Owner.Manager.Restart();
             E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RESTART_SUCCESS"]);
             return Task.CompletedTask;
diff --git a/SharedLibraryCore/Helpers/Vector3.cs b/SharedLibraryCore/Helpers/Vector3.cs
index d38b6d86d..a0dae6eb8 100644
--- a/SharedLibraryCore/Helpers/Vector3.cs
+++ b/SharedLibraryCore/Helpers/Vector3.cs
@@ -38,11 +38,16 @@ namespace SharedLibraryCore.Helpers
         {
             bool valid = Regex.Match(s, @"\((-?[0-9]+\.?[0-9]*|-?[0-9]+\.?[0-9]*e-[0-9]+),\ (-?[0-9]+\.?[0-9]*|-?[0-9]+\.?[0-9]*e-[0-9]+),\ (-?[0-9]+\.?[0-9]*|-?[0-9]+\.?[0-9]*e-[0-9]+)\)").Success;
             if (!valid)
+            {
                 throw new FormatException("Vector3 is not in correct format");
+            }
 
             string removeParenthesis = s.Substring(1, s.Length - 2);
             string[] eachPoint = removeParenthesis.Split(',');
-            return new Vector3(float.Parse(eachPoint[0], System.Globalization.NumberStyles.Any), float.Parse(eachPoint[1], System.Globalization.NumberStyles.Any), float.Parse(eachPoint[2], System.Globalization.NumberStyles.Any));
+
+            return new Vector3(float.Parse(eachPoint[0], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture), 
+                float.Parse(eachPoint[1], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture), 
+                float.Parse(eachPoint[2], System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture));
         }
 
         public static double Distance(Vector3 a, Vector3 b)
@@ -54,14 +59,12 @@ namespace SharedLibraryCore.Helpers
         {
             double deltaX = Math.Abs(b.X -a.X);
             double deltaY = Math.Abs(b.Y - a.Y);
-           double deltaZ = Math.Abs(b.Z - a.Z);
 
             // this 'fixes' the roll-over angles
             double dx = deltaX < 360.0 / 2 ? deltaX : 360.0 - deltaX;
             double dy = deltaY < 360.0 / 2 ? deltaY : 360.0 - deltaY;
-            double dz = deltaZ < 360.0 / 2 ? deltaZ : 360.0 - deltaZ;
 
-            return Math.Sqrt((dx * dx) + (dy * dy) /*+ (dz * dz)*/);
+            return Math.Sqrt((dx * dx) + (dy * dy));
         }
 
         public static double ViewAngleDistance(Vector3 a, Vector3 b, Vector3 c)
diff --git a/SharedLibraryCore/Services/MetaService.cs b/SharedLibraryCore/Services/MetaService.cs
index 36a8bb907..dd2da0b63 100644
--- a/SharedLibraryCore/Services/MetaService.cs
+++ b/SharedLibraryCore/Services/MetaService.cs
@@ -56,6 +56,11 @@ namespace SharedLibraryCore.Services
             }
         }
 
+        internal static void Clear()
+        {
+            _metaActions.Clear();
+        }
+
         /// <summary>
         /// retrieves meta data for given client and key
         /// </summary>
diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs
index aec4af790..d10f5d296 100644
--- a/SharedLibraryCore/Utilities.cs
+++ b/SharedLibraryCore/Utilities.cs
@@ -31,6 +31,7 @@ namespace SharedLibraryCore
         public static Encoding EncodingType;
         public static Localization.Layout CurrentLocalization = new Localization.Layout(new Dictionary<string, string>());
         public static TimeSpan DefaultCommandTimeout = new TimeSpan(0, 0, 10);
+        public static CultureInfo BestCulture = CultureInfo.CreateSpecificCulture("en-US");
 
         public static EFClient IW4MAdminClient(Server server = null)
         {