diff --git a/Application/Application.csproj b/Application/Application.csproj
index d06635524..997ef1fd9 100644
--- a/Application/Application.csproj
+++ b/Application/Application.csproj
@@ -5,7 +5,7 @@
netcoreapp2.1
false
RaidMax.IW4MAdmin.Application
- 2.1.9
+ 2.1.9.1
RaidMax
Forever None
IW4MAdmin
diff --git a/Application/DefaultSettings.json b/Application/DefaultSettings.json
index 109de7f23..7a235b6b4 100644
--- a/Application/DefaultSettings.json
+++ b/Application/DefaultSettings.json
@@ -171,7 +171,7 @@
},
{
- "Alias": "IW4 Credits",
+ "Alias": "Test map",
"Name": "iw4_credits"
},
@@ -190,6 +190,11 @@
"Name": "mp_cargoship_sh"
},
+ {
+ "Alias": "Cargoship",
+ "Name": "mp_cargoship"
+ },
+
{
"Alias": "Shipment",
"Name": "mp_shipment"
@@ -216,23 +221,43 @@
},
{
- "Alias": "Favela - Tropical",
+ "Alias": "Tropical Favela",
"Name": "mp_fav_tropical"
},
{
- "Alias": "Estate - Tropical",
+ "Alias": "Tropical Estate",
"Name": "mp_estate_tropical"
},
{
- "Alias": "Crash - Tropical",
+ "Alias": "Tropical Crash",
"Name": "mp_crash_tropical"
},
{
"Alias": "Forgotten City",
"Name": "mp_bloc_sh"
+ },
+
+ {
+ "Alias": "Crossfire",
+ "Name": "mp_cross_fire"
+ },
+
+ {
+ "Alias": "Bloc",
+ "Name": "mp_bloc"
+ },
+
+ {
+ "Alias": "Oilrig",
+ "Name": "oilrig"
+ },
+
+ {
+ "Name": "Village",
+ "Alias": "co_hunted"
}
]
},
diff --git a/Application/GameEventHandler.cs b/Application/GameEventHandler.cs
index dceb1b326..ef7cd695a 100644
--- a/Application/GameEventHandler.cs
+++ b/Application/GameEventHandler.cs
@@ -18,23 +18,23 @@ namespace IW4MAdmin.Application
{
Manager = mgr;
OutOfOrderEvents = new SortedList();
- IsProcessingEvent = new SemaphoreSlim(2, 2);
+ IsProcessingEvent = new SemaphoreSlim(1, 1);
}
public void AddEvent(GameEvent gameEvent)
{
- IsProcessingEvent.Wait();
+ // IsProcessingEvent.Wait();
((Manager as ApplicationManager).OnServerEvent)(this, new GameEventArgs(null, false, gameEvent));
- if (gameEvent.Type == GameEvent.EventType.Connect)
- {
- IsProcessingEvent.Wait();
- if (!gameEvent.OnProcessed.Wait(30 * 1000))
- {
- Manager.GetLogger().WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_COMMAND_TIMEOUT"]} [{gameEvent.Id}, {gameEvent.Type}]");
- }
- IsProcessingEvent.Release(1);
- }
- IsProcessingEvent.Release(1);
+ // IsProcessingEvent.Release(1);
+ //if (gameEvent.Type == GameEvent.EventType.Connect)
+ //{
+ // IsProcessingEvent.Wait();
+ // if (!gameEvent.OnProcessed.Wait(10 * 1000))
+ // {
+ // Manager.GetLogger().WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_COMMAND_TIMEOUT"]} [{gameEvent.Id}, {gameEvent.Type}]");
+ // }
+ // IsProcessingEvent.Release(1);
+ //}
return;
#if DEBUG
diff --git a/Application/Main.cs b/Application/Main.cs
index 1974292ab..550731de5 100644
--- a/Application/Main.cs
+++ b/Application/Main.cs
@@ -23,20 +23,16 @@ namespace IW4MAdmin.Application
public static void Main(string[] args)
{
AppDomain.CurrentDomain.SetData("DataDirectory", OperatingDirectory);
- //System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.BelowNormal;
Console.OutputEncoding = Encoding.UTF8;
Console.ForegroundColor = ConsoleColor.Gray;
- Version = Assembly.GetExecutingAssembly().GetName().Version.Major +
- Assembly.GetExecutingAssembly().GetName().Version.Minor / 10.0f +
- Assembly.GetExecutingAssembly().GetName().Version.Build / 100.0f;
- Version = Math.Round(Version, 3);
+ Version = Utilities.GetVersionAsDouble();
Console.WriteLine("=====================================================");
Console.WriteLine(" IW4M ADMIN");
Console.WriteLine(" by RaidMax ");
- Console.WriteLine($" Version {Version.ToString("0.00")}");
+ Console.WriteLine($" Version {Utilities.GetVersionAsString()}");
Console.WriteLine("=====================================================");
Index loc = null;
@@ -111,7 +107,7 @@ namespace IW4MAdmin.Application
var consoleTask = Task.Run(async () =>
{
String userInput;
- Player Origin = ServerManager.GetClientService().Get(1).Result.AsPlayer();
+ Player Origin = Utilities.IW4MAdminClient;
do
{
diff --git a/Application/Manager.cs b/Application/Manager.cs
index dfb188c6e..d60f81818 100644
--- a/Application/Manager.cs
+++ b/Application/Manager.cs
@@ -263,6 +263,7 @@ namespace IW4MAdmin.Application
await new ContextSeed(db).Seed();
}
+ // todo: optimize this
var ipList = (await ClientSvc.Find(c => c.Level > Player.Permission.Trusted))
.Select(c => new
{
diff --git a/Application/Server.cs b/Application/Server.cs
index 905e88740..585f60603 100644
--- a/Application/Server.cs
+++ b/Application/Server.cs
@@ -206,7 +206,7 @@ namespace IW4MAdmin
if (currentBan != null)
{
Logger.WriteInfo($"Banned client {player} trying to connect...");
- var autoKickClient = (await Manager.GetClientService().Get(1)).AsPlayer();
+ var autoKickClient = Utilities.IW4MAdminClient;
autoKickClient.CurrentServer = this;
// the player is permanently banned
@@ -847,7 +847,7 @@ namespace IW4MAdmin
{
if (Target.Warnings >= 4)
{
- await Target.Kick(loc["SERVER_WARNLIMT_REACHED"], (await Manager.GetClientService().Get(1)).AsPlayer());
+ await Target.Kick(loc["SERVER_WARNLIMT_REACHED"], Utilities.IW4MAdminClient);
return;
}
diff --git a/Plugins/ScriptPlugins/SharedGUIDKick.js b/Plugins/ScriptPlugins/SharedGUIDKick.js
index 48ad009a0..b82f0ac5b 100644
--- a/Plugins/ScriptPlugins/SharedGUIDKick.js
+++ b/Plugins/ScriptPlugins/SharedGUIDKick.js
@@ -4,9 +4,15 @@ var plugin = {
name: 'Shared GUID Kicker Plugin',
onEventAsync: function (gameEvent, server) {
- // connect event
+ // make sure we only check for IW4(x)
+ if (server.GameName !== 2) {
+ return false;
+ }
+
+ // connect or join event
if (gameEvent.Type === 3 ||
- gameEvent.Type === 4) {
+ gameEvent.Type === 4) {
+ // this GUID seems to have been packed in a IW4 torrent and results in an unreasonable amount of people using the same GUID
if (gameEvent.Origin.NetworkId === -805366929435212061) {
gameEvent.Origin.Kick('Your GUID is generic. Delete players/guids.dat and rejoin', _IW4MAdminClient);
}
diff --git a/SharedLibraryCore/Dtos/ClientInfo.cs b/SharedLibraryCore/Dtos/ClientInfo.cs
index ec9efa4e7..63594146c 100644
--- a/SharedLibraryCore/Dtos/ClientInfo.cs
+++ b/SharedLibraryCore/Dtos/ClientInfo.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using static SharedLibraryCore.Objects.Player;
namespace SharedLibraryCore.Dtos
{
@@ -10,5 +11,7 @@ namespace SharedLibraryCore.Dtos
{
public string Name { get; set; }
public int ClientId { get; set; }
+ public int LinkId { get; set; }
+ public Permission Level { get; set; }
}
}
diff --git a/SharedLibraryCore/Services/ClientService.cs b/SharedLibraryCore/Services/ClientService.cs
index a5726f384..8c0bbf5c8 100644
--- a/SharedLibraryCore/Services/ClientService.cs
+++ b/SharedLibraryCore/Services/ClientService.cs
@@ -9,6 +9,7 @@ using SharedLibraryCore.Database.Models;
using System.Linq.Expressions;
using SharedLibraryCore.Objects;
using Microsoft.EntityFrameworkCore;
+using SharedLibraryCore.Dtos;
namespace SharedLibraryCore.Services
{
@@ -94,10 +95,9 @@ namespace SharedLibraryCore.Services
{
return await Task.Run(() =>
{
- using (var context = new DatabaseContext())
+ using (var context = new DatabaseContext(true))
{
return context.Clients
- .AsNoTracking()
.Include(c => c.CurrentAlias)
.Include(c => c.AliasLink.Children)
.Where(e).ToList();
@@ -107,11 +107,8 @@ namespace SharedLibraryCore.Services
public async Task Get(int entityID)
{
- using (var context = new DatabaseContext())
+ using (var context = new DatabaseContext(true))
{
- context.ChangeTracker.AutoDetectChangesEnabled = false;
- context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
-
var iqClient = from client in context.Clients
.Include(c => c.CurrentAlias)
.Include(c => c.AliasLink.Children)
@@ -128,6 +125,9 @@ namespace SharedLibraryCore.Services
linkedClient.NetworkId
})
};
+#if DEBUG == true
+ var clientSql = iqClient.ToSql();
+#endif
var foundClient = await iqClient.FirstOrDefaultAsync();
if (foundClient == null)
@@ -143,15 +143,19 @@ namespace SharedLibraryCore.Services
}
}
+ private static readonly Func> _getUniqueQuery =
+ EF.CompileAsyncQuery((DatabaseContext context, long networkId) =>
+ context.Clients
+ .Include(c => c.CurrentAlias)
+ .Include(c => c.AliasLink.Children)
+ .FirstOrDefault(c => c.NetworkId == networkId)
+ );
+
public async Task GetUnique(long entityAttribute)
{
- using (var context = new DatabaseContext())
+ using (var context = new DatabaseContext(true))
{
- return await context.Clients
- .AsNoTracking()
- .Include(c => c.CurrentAlias)
- .Include(c => c.AliasLink.Children)
- .SingleOrDefaultAsync(c => c.NetworkId == entityAttribute);
+ return await _getUniqueQuery(context, entityAttribute);
}
}
@@ -219,7 +223,7 @@ namespace SharedLibraryCore.Services
}
}
- #region ServiceSpecific
+#region ServiceSpecific
public async Task> GetOwners()
{
using (var context = new DatabaseContext())
@@ -228,32 +232,24 @@ namespace SharedLibraryCore.Services
.ToListAsync();
}
- public async Task IsAuthenticated(int clientIP)
+ public async Task> GetPrivilegedClients()
{
- using (var context = new DatabaseContext())
+ using (var context = new DatabaseContext(disableTracking: true))
{
- var iqMatching = from alias in context.Aliases
- where alias.IPAddress == clientIP
- join client in context.Clients
- on alias.LinkId equals client.AliasLinkId
- where client.Level > Player.Permission.Trusted
- select client;
-
- return (await iqMatching.CountAsync()) > 0;
- }
- }
-
- public async Task> GetPrivilegedClients()
- {
- using (var context = new DatabaseContext())
- {
- context.ChangeTracker.AutoDetectChangesEnabled = false;
- context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
-
var iqClients = from client in context.Clients
- .Include(c => c.CurrentAlias)
where client.Level >= Player.Permission.Trusted
- select client;
+ where client.Active
+ select new ClientInfo()
+ {
+ ClientId = client.ClientId,
+ Name = client.CurrentAlias.Name,
+ LinkId = client.AliasLinkId,
+ Level = client.Level
+ };
+
+#if DEBUG == true
+ var clientsSql = iqClients.ToSql();
+#endif
return await iqClients.ToListAsync();
}
@@ -356,6 +352,6 @@ namespace SharedLibraryCore.Services
using (var context = new DatabaseContext())
return await context.Clients.SumAsync(c => c.TotalConnectionTime);
}
- #endregion
+#endregion
}
}
diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs
index 9ee978f7d..3ea5ab93a 100644
--- a/SharedLibraryCore/Utilities.cs
+++ b/SharedLibraryCore/Utilities.cs
@@ -507,6 +507,14 @@ namespace SharedLibraryCore
return response.FirstOrDefault(r => r[0] == '\\')?.DictionaryFromKeyValue();
}
+ public static double GetVersionAsDouble()
+ {
+ string version = Assembly.GetCallingAssembly().GetName().Version.ToString();
+ version = version.Replace(".", "");
+ return double.Parse(version) / 1000.0;
+ }
+
+ public static string GetVersionAsString() => Assembly.GetCallingAssembly().GetName().Version.ToString();
#if DEBUG == true
@@ -530,7 +538,7 @@ namespace SharedLibraryCore
var queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false);
var modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor();
modelVisitor.CreateQueryExecutor(queryModel);
- var sql = modelVisitor.Queries.First().ToString();
+ var sql = modelVisitor.Queries.First().ToString().Replace("\"", "`");
return sql;
}
diff --git a/WebfrontCore/Controllers/ClientController.cs b/WebfrontCore/Controllers/ClientController.cs
index 0824c5475..fe57d0a08 100644
--- a/WebfrontCore/Controllers/ClientController.cs
+++ b/WebfrontCore/Controllers/ClientController.cs
@@ -119,9 +119,8 @@ namespace WebfrontCore.Controllers
public async Task PrivilegedAsync()
{
var admins = (await Manager.GetClientService().GetPrivilegedClients())
- .Where(a => a.Active)
- .OrderByDescending(a => a.Level).ThenByDescending(a => a.LastConnection)
- .GroupBy(a => a.AliasLinkId).Select(a => a.First());
+ .OrderByDescending(a => a.Level)
+ .GroupBy(a => a.LinkId).Select(a => a.First());
var adminsDict = new Dictionary>();