started work on getting the restart functionality in the gamelogserver
fix bug with unbanned players still showing as banned via lock icon move player based stuff into client class finally renamed Player to EFClient via partial class don't try to run this build because it's in between stages
This commit is contained in:
parent
d9d548ea18
commit
ed83c4c011
4
.gitignore
vendored
4
.gitignore
vendored
@ -229,4 +229,6 @@ bootstrap-custom.min.css
|
|||||||
/DiscordWebhook/env
|
/DiscordWebhook/env
|
||||||
/DiscordWebhook/config.dev.json
|
/DiscordWebhook/config.dev.json
|
||||||
/GameLogServer/env
|
/GameLogServer/env
|
||||||
launchSettings.json
|
launchSettings.json
|
||||||
|
/VpnDetectionPrivate.js
|
||||||
|
/Plugins/ScriptPlugins/VpnDetectionPrivate.js
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
||||||
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
||||||
<Version>2.2.1.0</Version>
|
<Version>2.2.2.0</Version>
|
||||||
<Authors>RaidMax</Authors>
|
<Authors>RaidMax</Authors>
|
||||||
<Company>Forever None</Company>
|
<Company>Forever None</Company>
|
||||||
<Product>IW4MAdmin</Product>
|
<Product>IW4MAdmin</Product>
|
||||||
@ -31,8 +31,8 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||||
<TieredCompilation>true</TieredCompilation>
|
<TieredCompilation>true</TieredCompilation>
|
||||||
<AssemblyVersion>2.2.1.0</AssemblyVersion>
|
<AssemblyVersion>2.2.2.0</AssemblyVersion>
|
||||||
<FileVersion>2.2.1.0</FileVersion>
|
<FileVersion>2.2.2.0</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -9,16 +10,16 @@ namespace IW4MAdmin.Application.Core
|
|||||||
{
|
{
|
||||||
class ClientAuthentication : IClientAuthentication
|
class ClientAuthentication : IClientAuthentication
|
||||||
{
|
{
|
||||||
private Queue<Player> ClientAuthenticationQueue;
|
private Queue<EFClient> ClientAuthenticationQueue;
|
||||||
private Dictionary<long, Player> AuthenticatedClients;
|
private Dictionary<long, EFClient> AuthenticatedClients;
|
||||||
|
|
||||||
public ClientAuthentication()
|
public ClientAuthentication()
|
||||||
{
|
{
|
||||||
ClientAuthenticationQueue = new Queue<Player>();
|
ClientAuthenticationQueue = new Queue<EFClient>();
|
||||||
AuthenticatedClients = new Dictionary<long, Player>();
|
AuthenticatedClients = new Dictionary<long, EFClient>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AuthenticateClients(IList<Player> clients)
|
public void AuthenticateClients(IList<EFClient> clients)
|
||||||
{
|
{
|
||||||
// we need to un-auth all the clients that have disconnected
|
// we need to un-auth all the clients that have disconnected
|
||||||
var clientNetworkIds = clients.Select(c => c.NetworkId);
|
var clientNetworkIds = clients.Select(c => c.NetworkId);
|
||||||
@ -33,10 +34,10 @@ namespace IW4MAdmin.Application.Core
|
|||||||
foreach (var client in clients)
|
foreach (var client in clients)
|
||||||
{
|
{
|
||||||
// they've not been authenticated
|
// they've not been authenticated
|
||||||
if (!AuthenticatedClients.TryGetValue(client.NetworkId, out Player value))
|
if (!AuthenticatedClients.TryGetValue(client.NetworkId, out EFClient value))
|
||||||
{
|
{
|
||||||
// authenticate them
|
// authenticate them
|
||||||
client.State = Player.ClientState.Authenticated;
|
client.State = EFClient.ClientState.Authenticated;
|
||||||
AuthenticatedClients.Add(client.NetworkId, client);
|
AuthenticatedClients.Add(client.NetworkId, client);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -54,16 +55,16 @@ namespace IW4MAdmin.Application.Core
|
|||||||
// grab each client that's connected via log
|
// grab each client that's connected via log
|
||||||
var clientToAuthenticate = ClientAuthenticationQueue.Dequeue();
|
var clientToAuthenticate = ClientAuthenticationQueue.Dequeue();
|
||||||
// if they're not already authed, auth them
|
// if they're not already authed, auth them
|
||||||
if (!AuthenticatedClients.TryGetValue(clientToAuthenticate.NetworkId, out Player value))
|
if (!AuthenticatedClients.TryGetValue(clientToAuthenticate.NetworkId, out EFClient value))
|
||||||
{
|
{
|
||||||
// authenticate them
|
// authenticate them
|
||||||
clientToAuthenticate.State = Player.ClientState.Authenticated;
|
clientToAuthenticate.State = EFClient.ClientState.Authenticated;
|
||||||
AuthenticatedClients.Add(clientToAuthenticate.NetworkId, clientToAuthenticate);
|
AuthenticatedClients.Add(clientToAuthenticate.NetworkId, clientToAuthenticate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<Player> GetAuthenticatedClients()
|
public IList<EFClient> GetAuthenticatedClients()
|
||||||
{
|
{
|
||||||
if (AuthenticatedClients.Values.Count > 18)
|
if (AuthenticatedClients.Values.Count > 18)
|
||||||
{
|
{
|
||||||
@ -74,7 +75,7 @@ namespace IW4MAdmin.Application.Core
|
|||||||
return AuthenticatedClients.Values.ToList();
|
return AuthenticatedClients.Values.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestClientAuthentication(Player client)
|
public void RequestClientAuthentication(EFClient client)
|
||||||
{
|
{
|
||||||
ClientAuthenticationQueue.Enqueue(client);
|
ClientAuthenticationQueue.Enqueue(client);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
|
|
||||||
if (eventType == "JoinTeam")
|
if (eventType == "JoinTeam")
|
||||||
{
|
{
|
||||||
var origin = server.GetPlayersAsList().FirstOrDefault(c => c.NetworkId == lineSplit[1].ConvertLong());
|
var origin = server.GetClientsAsList().FirstOrDefault(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
@ -41,7 +42,7 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
.Replace("\x15", "")
|
.Replace("\x15", "")
|
||||||
.Trim();
|
.Trim();
|
||||||
|
|
||||||
var origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2));
|
var origin = server.GetClientsAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2));
|
||||||
|
|
||||||
if (message[0] == '!' || message[0] == '@')
|
if (message[0] == '!' || message[0] == '@')
|
||||||
{
|
{
|
||||||
@ -70,8 +71,8 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
{
|
{
|
||||||
if (!server.CustomCallback)
|
if (!server.CustomCallback)
|
||||||
{
|
{
|
||||||
var origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 6));
|
var origin = server.GetClientsAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 6));
|
||||||
var target = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2));
|
var target = server.GetClientsAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2));
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
@ -86,8 +87,8 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
|
|
||||||
if (eventType == "ScriptKill")
|
if (eventType == "ScriptKill")
|
||||||
{
|
{
|
||||||
var origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
var origin = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||||
var target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
var target = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.ScriptKill,
|
Type = GameEvent.EventType.ScriptKill,
|
||||||
@ -100,8 +101,8 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
|
|
||||||
if (eventType == "ScriptDamage")
|
if (eventType == "ScriptDamage")
|
||||||
{
|
{
|
||||||
var origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
var origin = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||||
var target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
var target = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
@ -120,8 +121,8 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
{
|
{
|
||||||
if (Regex.Match(eventType, @"^(D);((?:bot[0-9]+)|(?:[A-Z]|[0-9])+);([0-9]+);(axis|allies);(.+);((?:[A-Z]|[0-9])+);([0-9]+);(axis|allies);(.+);((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$").Success)
|
if (Regex.Match(eventType, @"^(D);((?:bot[0-9]+)|(?:[A-Z]|[0-9])+);([0-9]+);(axis|allies);(.+);((?:[A-Z]|[0-9])+);([0-9]+);(axis|allies);(.+);((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$").Success)
|
||||||
{
|
{
|
||||||
var origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[5].ConvertLong());
|
var origin = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[5].ConvertLong());
|
||||||
var target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
var target = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
@ -146,12 +147,12 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
Type = GameEvent.EventType.Join,
|
Type = GameEvent.EventType.Join,
|
||||||
Data = logLine,
|
Data = logLine,
|
||||||
Owner = server,
|
Owner = server,
|
||||||
Origin = new Player()
|
Origin = new EFClient()
|
||||||
{
|
{
|
||||||
Name = regexMatch.Groups[4].ToString().StripColors(),
|
Name = regexMatch.Groups[4].ToString().StripColors(),
|
||||||
NetworkId = regexMatch.Groups[2].ToString().ConvertLong(),
|
NetworkId = regexMatch.Groups[2].ToString().ConvertLong(),
|
||||||
ClientNumber = Convert.ToInt32(regexMatch.Groups[3].ToString()),
|
ClientNumber = Convert.ToInt32(regexMatch.Groups[3].ToString()),
|
||||||
State = Player.ClientState.Connecting,
|
State = EFClient.ClientState.Connecting,
|
||||||
CurrentServer = server
|
CurrentServer = server
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -185,11 +186,11 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
{
|
{
|
||||||
Type = GameEvent.EventType.MapEnd,
|
Type = GameEvent.EventType.MapEnd,
|
||||||
Data = lineSplit[0],
|
Data = lineSplit[0],
|
||||||
Origin = new Player()
|
Origin = new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1
|
ClientId = 1
|
||||||
},
|
},
|
||||||
Target = new Player()
|
Target = new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1
|
ClientId = 1
|
||||||
},
|
},
|
||||||
@ -205,14 +206,8 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
{
|
{
|
||||||
Type = GameEvent.EventType.MapChange,
|
Type = GameEvent.EventType.MapChange,
|
||||||
Data = lineSplit[0],
|
Data = lineSplit[0],
|
||||||
Origin = new Player()
|
Origin = Utilities.IW4MAdminClient(server),
|
||||||
{
|
Target = Utilities.IW4MAdminClient(server),
|
||||||
ClientId = 1
|
|
||||||
},
|
|
||||||
Target = new Player()
|
|
||||||
{
|
|
||||||
ClientId = 1
|
|
||||||
},
|
|
||||||
Owner = server,
|
Owner = server,
|
||||||
Extra = dump.DictionaryFromKeyValue()
|
Extra = dump.DictionaryFromKeyValue()
|
||||||
};
|
};
|
||||||
@ -221,14 +216,8 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Unknown,
|
Type = GameEvent.EventType.Unknown,
|
||||||
Origin = new Player()
|
Origin = Utilities.IW4MAdminClient(server),
|
||||||
{
|
Target = Utilities.IW4MAdminClient(server),
|
||||||
ClientId = 1
|
|
||||||
},
|
|
||||||
Target = new Player()
|
|
||||||
{
|
|
||||||
ClientId = 1
|
|
||||||
},
|
|
||||||
Owner = server
|
Owner = server
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
@ -23,7 +24,7 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
|
|
||||||
int clientNum = Int32.Parse(lineSplit[2]);
|
int clientNum = Int32.Parse(lineSplit[2]);
|
||||||
|
|
||||||
var player = new Player()
|
var player = new EFClient()
|
||||||
{
|
{
|
||||||
NetworkId = lineSplit[1].ConvertLong(),
|
NetworkId = lineSplit[1].ConvertLong(),
|
||||||
ClientNumber = clientNum,
|
ClientNumber = clientNum,
|
||||||
@ -33,11 +34,11 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Join,
|
Type = GameEvent.EventType.Join,
|
||||||
Origin = new Player()
|
Origin = new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1
|
ClientId = 1
|
||||||
},
|
},
|
||||||
Target = new Player()
|
Target = new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1
|
ClientId = 1
|
||||||
},
|
},
|
||||||
|
@ -110,7 +110,7 @@ namespace IW4MAdmin.Application
|
|||||||
var consoleTask = Task.Run(async () =>
|
var consoleTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
String userInput;
|
String userInput;
|
||||||
Player Origin = Utilities.IW4MAdminClient(ServerManager.Servers[0]);
|
var Origin = Utilities.IW4MAdminClient(ServerManager.Servers[0]);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@ using SharedLibraryCore.Events;
|
|||||||
|
|
||||||
using IW4MAdmin.Application.API.Master;
|
using IW4MAdmin.Application.API.Master;
|
||||||
using IW4MAdmin.Application.Migration;
|
using IW4MAdmin.Application.Migration;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace IW4MAdmin.Application
|
namespace IW4MAdmin.Application
|
||||||
{
|
{
|
||||||
@ -26,7 +27,7 @@ namespace IW4MAdmin.Application
|
|||||||
{
|
{
|
||||||
private List<Server> _servers;
|
private List<Server> _servers;
|
||||||
public List<Server> Servers => _servers.OrderByDescending(s => s.ClientNum).ToList();
|
public List<Server> Servers => _servers.OrderByDescending(s => s.ClientNum).ToList();
|
||||||
public Dictionary<int, Player> PrivilegedClients { get; set; }
|
public Dictionary<int, EFClient> PrivilegedClients { get; set; }
|
||||||
public ILogger Logger => GetLogger(0);
|
public ILogger Logger => GetLogger(0);
|
||||||
public bool Running { get; private set; }
|
public bool Running { get; private set; }
|
||||||
public bool IsInitialized { get; private set; }
|
public bool IsInitialized { get; private set; }
|
||||||
@ -60,7 +61,7 @@ namespace IW4MAdmin.Application
|
|||||||
ClientSvc = new ClientService();
|
ClientSvc = new ClientService();
|
||||||
AliasSvc = new AliasService();
|
AliasSvc = new AliasService();
|
||||||
PenaltySvc = new PenaltyService();
|
PenaltySvc = new PenaltyService();
|
||||||
PrivilegedClients = new Dictionary<int, Player>();
|
PrivilegedClients = new Dictionary<int, EFClient>();
|
||||||
ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings");
|
ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings");
|
||||||
StartTime = DateTime.UtcNow;
|
StartTime = DateTime.UtcNow;
|
||||||
OnQuit = new ManualResetEventSlim();
|
OnQuit = new ManualResetEventSlim();
|
||||||
@ -144,7 +145,7 @@ namespace IW4MAdmin.Application
|
|||||||
if (e.Target != null)
|
if (e.Target != null)
|
||||||
{
|
{
|
||||||
// update the target incase they left or have newer info
|
// update the target incase they left or have newer info
|
||||||
e.Target = newEvent.Owner.GetPlayersAsList()
|
e.Target = newEvent.Owner.GetClientsAsList()
|
||||||
.FirstOrDefault(p => p.NetworkId == e.Target.NetworkId);
|
.FirstOrDefault(p => p.NetworkId == e.Target.NetworkId);
|
||||||
// we have to throw out the event because they left
|
// we have to throw out the event because they left
|
||||||
if (e.Target == null)
|
if (e.Target == null)
|
||||||
@ -285,7 +286,7 @@ namespace IW4MAdmin.Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
// todo: optimize this (or replace it)
|
// todo: optimize this (or replace it)
|
||||||
var ipList = (await ClientSvc.Find(c => c.Level > Player.Permission.Trusted))
|
var ipList = (await ClientSvc.Find(c => c.Level > EFClient.Permission.Trusted))
|
||||||
.Select(c => new
|
.Select(c => new
|
||||||
{
|
{
|
||||||
c.Password,
|
c.Password,
|
||||||
@ -299,7 +300,7 @@ namespace IW4MAdmin.Application
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PrivilegedClients.Add(a.ClientId, new Player()
|
PrivilegedClients.Add(a.ClientId, new EFClient()
|
||||||
{
|
{
|
||||||
Name = a.Name,
|
Name = a.Name,
|
||||||
ClientId = a.ClientId,
|
ClientId = a.ClientId,
|
||||||
@ -593,13 +594,13 @@ namespace IW4MAdmin.Application
|
|||||||
return MessageTokens;
|
return MessageTokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<Player> GetActiveClients() => _servers.SelectMany(s => s.Players).Where(p => p != null).ToList();
|
public IList<EFClient> GetActiveClients() => _servers.SelectMany(s => s.Clients).Where(p => p != null).ToList();
|
||||||
|
|
||||||
public ClientService GetClientService() => ClientSvc;
|
public ClientService GetClientService() => ClientSvc;
|
||||||
public AliasService GetAliasService() => AliasSvc;
|
public AliasService GetAliasService() => AliasSvc;
|
||||||
public PenaltyService GetPenaltyService() => PenaltySvc;
|
public PenaltyService GetPenaltyService() => PenaltySvc;
|
||||||
public IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings() => ConfigHandler;
|
public IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings() => ConfigHandler;
|
||||||
public IDictionary<int, Player> GetPrivilegedClients() => PrivilegedClients;
|
public IDictionary<int, EFClient> GetPrivilegedClients() => PrivilegedClients;
|
||||||
public bool ShutdownRequested() => !Running;
|
public bool ShutdownRequested() => !Running;
|
||||||
public IEventHandler GetEventHandler() => Handler;
|
public IEventHandler GetEventHandler() => Handler;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Objects;
|
|||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.RCon;
|
using SharedLibraryCore.RCon;
|
||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore.Exceptions;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace IW4MAdmin.Application.RconParsers
|
namespace IW4MAdmin.Application.RconParsers
|
||||||
{
|
{
|
||||||
@ -61,7 +62,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Player>> GetStatusAsync(Connection connection)
|
public async Task<List<EFClient>> GetStatusAsync(Connection connection)
|
||||||
{
|
{
|
||||||
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
||||||
return ClientsFromStatus(response);
|
return ClientsFromStatus(response);
|
||||||
@ -74,9 +75,9 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
|
|
||||||
public virtual CommandPrefix GetCommandPrefixes() => Prefixes;
|
public virtual CommandPrefix GetCommandPrefixes() => Prefixes;
|
||||||
|
|
||||||
private List<Player> ClientsFromStatus(string[] Status)
|
private List<EFClient> ClientsFromStatus(string[] Status)
|
||||||
{
|
{
|
||||||
List<Player> StatusPlayers = new List<Player>();
|
List<EFClient> StatusPlayers = new List<EFClient>();
|
||||||
|
|
||||||
if (Status.Length < 4)
|
if (Status.Length < 4)
|
||||||
throw new ServerException("Unexpected status response received");
|
throw new ServerException("Unexpected status response received");
|
||||||
@ -106,7 +107,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
string name = regex.Groups[5].Value.StripColors().Trim();
|
string name = regex.Groups[5].Value.StripColors().Trim();
|
||||||
int ip = regex.Groups[7].Value.Split(':')[0].ConvertToIP();
|
int ip = regex.Groups[7].Value.Split(':')[0].ConvertToIP();
|
||||||
|
|
||||||
Player P = new Player()
|
var P = new EFClient()
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = name,
|
||||||
NetworkId = networkId,
|
NetworkId = networkId,
|
||||||
@ -115,7 +116,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
Ping = ping,
|
Ping = ping,
|
||||||
Score = score,
|
Score = score,
|
||||||
IsBot = ip == 0,
|
IsBot = ip == 0,
|
||||||
State = Player.ClientState.Connecting
|
State = EFClient.ClientState.Connecting
|
||||||
};
|
};
|
||||||
StatusPlayers.Add(P);
|
StatusPlayers.Add(P);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Interfaces;
|
|||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using SharedLibraryCore.RCon;
|
using SharedLibraryCore.RCon;
|
||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore.Exceptions;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace IW4MAdmin.Application.RconParsers
|
namespace IW4MAdmin.Application.RconParsers
|
||||||
{
|
{
|
||||||
@ -105,7 +106,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Player>> GetStatusAsync(Connection connection)
|
public async Task<List<EFClient>> GetStatusAsync(Connection connection)
|
||||||
{
|
{
|
||||||
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
||||||
return ClientsFromStatus(response);
|
return ClientsFromStatus(response);
|
||||||
@ -118,9 +119,9 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Player> ClientsFromStatus(string[] status)
|
private List<EFClient> ClientsFromStatus(string[] status)
|
||||||
{
|
{
|
||||||
List<Player> StatusPlayers = new List<Player>();
|
List<EFClient> StatusPlayers = new List<EFClient>();
|
||||||
|
|
||||||
foreach (string statusLine in status)
|
foreach (string statusLine in status)
|
||||||
{
|
{
|
||||||
@ -145,7 +146,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
regex = Regex.Match(responseLine, @" +(\d+ +){3}");
|
regex = Regex.Match(responseLine, @" +(\d+ +){3}");
|
||||||
int score = Int32.Parse(regex.Value.Split(' ', StringSplitOptions.RemoveEmptyEntries)[0]);
|
int score = Int32.Parse(regex.Value.Split(' ', StringSplitOptions.RemoveEmptyEntries)[0]);
|
||||||
|
|
||||||
var p = new Player()
|
var p = new EFClient()
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = name,
|
||||||
NetworkId = networkId,
|
NetworkId = networkId,
|
||||||
@ -154,7 +155,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
Ping = Ping,
|
Ping = Ping,
|
||||||
Score = score,
|
Score = score,
|
||||||
IsBot = false,
|
IsBot = false,
|
||||||
State = Player.ClientState.Connecting
|
State = EFClient.ClientState.Connecting
|
||||||
};
|
};
|
||||||
|
|
||||||
StatusPlayers.Add(p);
|
StatusPlayers.Add(p);
|
||||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Objects;
|
|||||||
using SharedLibraryCore.RCon;
|
using SharedLibraryCore.RCon;
|
||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore.Exceptions;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace IW4MAdmin.Application.RconParsers
|
namespace IW4MAdmin.Application.RconParsers
|
||||||
{
|
{
|
||||||
@ -60,7 +61,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Player>> GetStatusAsync(Connection connection)
|
public async Task<List<EFClient>> GetStatusAsync(Connection connection)
|
||||||
{
|
{
|
||||||
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
string[] response = await connection.SendQueryAsync(StaticHelpers.QueryType.COMMAND, "status");
|
||||||
return ClientsFromStatus(response);
|
return ClientsFromStatus(response);
|
||||||
@ -73,9 +74,9 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Player> ClientsFromStatus(string[] status)
|
private List<EFClient> ClientsFromStatus(string[] status)
|
||||||
{
|
{
|
||||||
List<Player> StatusPlayers = new List<Player>();
|
List<EFClient> StatusPlayers = new List<EFClient>();
|
||||||
|
|
||||||
foreach (string statusLine in status)
|
foreach (string statusLine in status)
|
||||||
{
|
{
|
||||||
@ -98,7 +99,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
#endif
|
#endif
|
||||||
int ipAddress = regex.Value.Split(':')[0].ConvertToIP();
|
int ipAddress = regex.Value.Split(':')[0].ConvertToIP();
|
||||||
regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+");
|
regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+");
|
||||||
var p = new Player()
|
var p = new EFClient()
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = name,
|
||||||
NetworkId = networkId,
|
NetworkId = networkId,
|
||||||
@ -106,7 +107,7 @@ namespace IW4MAdmin.Application.RconParsers
|
|||||||
IPAddress = ipAddress,
|
IPAddress = ipAddress,
|
||||||
Ping = Ping,
|
Ping = Ping,
|
||||||
Score = 0,
|
Score = 0,
|
||||||
State = Player.ClientState.Connecting,
|
State = EFClient.ClientState.Connecting,
|
||||||
IsBot = networkId == 0
|
IsBot = networkId == 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,24 +1,22 @@
|
|||||||
using System;
|
using IW4MAdmin.Application.EventParsers;
|
||||||
using System.Collections.Generic;
|
using IW4MAdmin.Application.IO;
|
||||||
using System.Threading;
|
using IW4MAdmin.Application.RconParsers;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Configuration;
|
||||||
using SharedLibraryCore.Objects;
|
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
using SharedLibraryCore.Configuration;
|
|
||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore.Exceptions;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Localization;
|
using SharedLibraryCore.Localization;
|
||||||
|
using SharedLibraryCore.Objects;
|
||||||
using IW4MAdmin.Application.RconParsers;
|
using System;
|
||||||
using IW4MAdmin.Application.EventParsers;
|
using System.Collections.Generic;
|
||||||
using IW4MAdmin.Application.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace IW4MAdmin
|
namespace IW4MAdmin
|
||||||
{
|
{
|
||||||
@ -58,234 +56,101 @@ namespace IW4MAdmin
|
|||||||
return Id;
|
return Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OnPlayerJoined(Player logClient)
|
public async Task OnClientJoined(EFClient polledClient)
|
||||||
{
|
{
|
||||||
var existingClient = Players[logClient.ClientNumber];
|
var existingClient = Clients[polledClient.ClientNumber];
|
||||||
|
|
||||||
if (existingClient == null ||
|
if (existingClient != null)
|
||||||
(existingClient.NetworkId != logClient.NetworkId &&
|
|
||||||
existingClient.State != Player.ClientState.Connected))
|
|
||||||
{
|
{
|
||||||
Logger.WriteDebug($"Log detected {logClient} joining");
|
await existingClient.OnJoin(polledClient.IPAddress);
|
||||||
Players[logClient.ClientNumber] = logClient;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override public async Task<bool> AddPlayer(Player polledPlayer)
|
override public async Task OnClientConnected(EFClient clientFromLog)
|
||||||
{
|
{
|
||||||
if ((polledPlayer.Ping == 999 && !polledPlayer.IsBot) ||
|
Logger.WriteDebug($"Client slot #{clientFromLog.ClientNumber} now reserved");
|
||||||
polledPlayer.Ping < 1 ||
|
|
||||||
polledPlayer.ClientNumber < 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set this when they are waiting for authentication
|
|
||||||
if (Players[polledPlayer.ClientNumber] == null &&
|
|
||||||
polledPlayer.State == Player.ClientState.Connecting)
|
|
||||||
{
|
|
||||||
Players[polledPlayer.ClientNumber] = polledPlayer;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !DEBUG
|
|
||||||
if (polledPlayer.Name.Length < 3)
|
|
||||||
{
|
|
||||||
Logger.WriteDebug($"Kicking {polledPlayer} because their name is too short");
|
|
||||||
string formattedKick = String.Format(RconParser.GetCommandPrefixes().Kick, polledPlayer.ClientNumber, loc["SERVER_KICK_MINNAME"]);
|
|
||||||
await this.ExecuteCommandAsync(formattedKick);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Players.FirstOrDefault(p => p != null && p.Name == polledPlayer.Name && p.NetworkId != polledPlayer.NetworkId) != null)
|
|
||||||
{
|
|
||||||
Logger.WriteDebug($"Kicking {polledPlayer} because their name is already in use");
|
|
||||||
string formattedKick = String.Format(RconParser.GetCommandPrefixes().Kick, polledPlayer.ClientNumber, loc["SERVER_KICK_NAME_INUSE"]);
|
|
||||||
await this.ExecuteCommandAsync(formattedKick);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (polledPlayer.Name == "Unknown Soldier" ||
|
|
||||||
polledPlayer.Name == "UnknownSoldier" ||
|
|
||||||
polledPlayer.Name == "CHEATER")
|
|
||||||
{
|
|
||||||
Logger.WriteDebug($"Kicking {polledPlayer} because their name is generic");
|
|
||||||
string formattedKick = String.Format(RconParser.GetCommandPrefixes().Kick, polledPlayer.ClientNumber, loc["SERVER_KICK_GENERICNAME"]);
|
|
||||||
await this.ExecuteCommandAsync(formattedKick);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (polledPlayer.Name.Where(c => Char.IsControl(c)).Count() > 0)
|
|
||||||
{
|
|
||||||
Logger.WriteDebug($"Kicking {polledPlayer} because their name contains control characters");
|
|
||||||
string formattedKick = String.Format(RconParser.GetCommandPrefixes().Kick, polledPlayer.ClientNumber, loc["SERVER_KICK_CONTROLCHARS"]);
|
|
||||||
await this.ExecuteCommandAsync(formattedKick);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Logger.WriteDebug($"Client slot #{polledPlayer.ClientNumber} now reserved");
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Player player = null;
|
EFClient client = await Manager.GetClientService().GetUnique(clientFromLog.NetworkId);
|
||||||
var client = await Manager.GetClientService().GetUnique(polledPlayer.NetworkId);
|
|
||||||
|
|
||||||
// first time client is connecting to server
|
// first time client is connecting to server
|
||||||
if (client == null)
|
if (client == null)
|
||||||
{
|
{
|
||||||
Logger.WriteDebug($"Client {polledPlayer} first time connecting");
|
Logger.WriteDebug($"Client {clientFromLog} first time connecting");
|
||||||
player = (await Manager.GetClientService().Create(polledPlayer)).AsPlayer();
|
client = await Manager.GetClientService().Create(clientFromLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
// client has connected in the past
|
// client has connected in the past
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
client.LastConnection = DateTime.UtcNow;
|
|
||||||
client.Connections += 1;
|
|
||||||
|
|
||||||
var existingAlias = client.AliasLink.Children
|
var existingAlias = client.AliasLink.Children
|
||||||
.FirstOrDefault(a => a.Name == polledPlayer.Name && a.IPAddress == polledPlayer.IPAddress);
|
.FirstOrDefault(a => a.Name == clientFromLog.Name);
|
||||||
|
|
||||||
if (existingAlias == null)
|
if (existingAlias == null)
|
||||||
{
|
{
|
||||||
Logger.WriteDebug($"Client {polledPlayer} has connected previously under a different ip/name");
|
Logger.WriteDebug($"Client {clientFromLog} has connected previously under a different ip/name");
|
||||||
client.CurrentAlias = new EFAlias()
|
client.CurrentAlias = new EFAlias()
|
||||||
{
|
{
|
||||||
IPAddress = polledPlayer.IPAddress,
|
// this gets updated on client join
|
||||||
Name = polledPlayer.Name,
|
IPAddress = clientFromLog.IPAddress,
|
||||||
|
Name = clientFromLog.Name,
|
||||||
};
|
};
|
||||||
// we need to update their new ip and name to the virtual property
|
|
||||||
client.Name = polledPlayer.Name;
|
|
||||||
client.IPAddress = polledPlayer.IPAddress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
client.CurrentAlias = existingAlias;
|
client.CurrentAlias = existingAlias;
|
||||||
client.CurrentAliasId = existingAlias.AliasId;
|
client.CurrentAliasId = existingAlias.AliasId;
|
||||||
client.Name = existingAlias.Name;
|
|
||||||
client.IPAddress = existingAlias.IPAddress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await Manager.GetClientService().Update(client);
|
await Manager.GetClientService().Update(client);
|
||||||
player = client.AsPlayer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reserved slots stuff
|
Logger.WriteInfo($"Client {client} connected...");
|
||||||
if ((MaxClients - ClientNum) < ServerConfig.ReservedSlotNumber &&
|
|
||||||
!player.IsPrivileged())
|
|
||||||
{
|
|
||||||
Logger.WriteDebug($"Kicking {polledPlayer} their spot is reserved");
|
|
||||||
string formattedKick = String.Format(RconParser.GetCommandPrefixes().Kick, polledPlayer.ClientNumber, loc["SERVER_KICK_SLOT_IS_RESERVED"]);
|
|
||||||
await this.ExecuteCommandAsync(formattedKick);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.WriteInfo($"Client {player} connected...");
|
|
||||||
|
|
||||||
// Do the player specific stuff
|
// Do the player specific stuff
|
||||||
player.ClientNumber = polledPlayer.ClientNumber;
|
client.ClientNumber = clientFromLog.ClientNumber;
|
||||||
player.IsBot = polledPlayer.IsBot;
|
client.IsBot = clientFromLog.IsBot;
|
||||||
player.Score = polledPlayer.Score;
|
client.Score = clientFromLog.Score;
|
||||||
player.CurrentServer = this;
|
client.Ping = clientFromLog.Ping;
|
||||||
|
client.CurrentServer = this;
|
||||||
|
|
||||||
player.DelayedEvents = (Players[player.ClientNumber]?.DelayedEvents) ?? new Queue<GameEvent>();
|
Clients[client.ClientNumber] = client;
|
||||||
Players[player.ClientNumber] = player;
|
client.OnConnect();
|
||||||
|
|
||||||
var activePenalties = await Manager.GetPenaltyService().GetActivePenaltiesAsync(player.AliasLinkId, player.IPAddress);
|
client.State = EFClient.ClientState.Connected;
|
||||||
var currentBan = activePenalties.FirstOrDefault(p => p.Type == Penalty.PenaltyType.Ban || p.Type == Penalty.PenaltyType.TempBan);
|
|
||||||
|
|
||||||
var currentAutoFlag = activePenalties.Where(p => p.Type == Penalty.PenaltyType.Flag && p.PunisherId == 1)
|
|
||||||
.Where(p => p.Active)
|
|
||||||
.OrderByDescending(p => p.When)
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
// remove their auto flag status after a week
|
|
||||||
if (player.Level == Player.Permission.Flagged &&
|
|
||||||
currentAutoFlag != null &&
|
|
||||||
(DateTime.Now - currentAutoFlag.When).TotalDays > 7)
|
|
||||||
{
|
|
||||||
player.Level = Player.Permission.User;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentBan != null)
|
|
||||||
{
|
|
||||||
Logger.WriteInfo($"Banned client {player} trying to connect...");
|
|
||||||
var autoKickClient = Utilities.IW4MAdminClient(this);
|
|
||||||
|
|
||||||
// the player is permanently banned
|
|
||||||
if (currentBan.Type == Penalty.PenaltyType.Ban)
|
|
||||||
{
|
|
||||||
// don't store the kick message
|
|
||||||
string formattedKick = String.Format(
|
|
||||||
RconParser.GetCommandPrefixes().Kick,
|
|
||||||
polledPlayer.ClientNumber,
|
|
||||||
$"{loc["SERVER_BAN_PREV"]} {currentBan.Offense} ({loc["SERVER_BAN_APPEAL"]} {Website})");
|
|
||||||
await this.ExecuteCommandAsync(formattedKick);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string formattedKick = String.Format(
|
|
||||||
RconParser.GetCommandPrefixes().Kick,
|
|
||||||
polledPlayer.ClientNumber,
|
|
||||||
$"{loc["SERVER_TB_REMAIN"]} ({(currentBan.Expires.Value - DateTime.UtcNow).TimeSpanText()} {loc["WEBFRONT_PENALTY_TEMPLATE_REMAINING"]})");
|
|
||||||
await this.ExecuteCommandAsync(formattedKick);
|
|
||||||
}
|
|
||||||
|
|
||||||
// reban the "evading" guid
|
|
||||||
if (player.Level != Player.Permission.Banned && currentBan.Type == Penalty.PenaltyType.Ban)
|
|
||||||
{
|
|
||||||
// hack: re apply the automated offense to the reban
|
|
||||||
if (currentBan.AutomatedOffense != null)
|
|
||||||
{
|
|
||||||
autoKickClient.AdministeredPenalties.Add(new EFPenalty() { AutomatedOffense = currentBan.AutomatedOffense });
|
|
||||||
}
|
|
||||||
player.Ban($"{currentBan.Offense}", autoKickClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
// they didn't fully connect so empty their slot
|
|
||||||
Players[player.ClientNumber] = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
player.State = Player.ClientState.Connected;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.WriteError($"{loc["SERVER_ERROR_ADDPLAYER"]} {polledPlayer.Name}::{polledPlayer.NetworkId}");
|
Logger.WriteError($"{loc["SERVER_ERROR_ADDPLAYER"]} {clientFromLog.Name}::{clientFromLog.NetworkId}");
|
||||||
Logger.WriteDebug(ex.Message);
|
Logger.WriteDebug(ex.Message);
|
||||||
Logger.WriteDebug(ex.StackTrace);
|
Logger.WriteDebug(ex.StackTrace);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove player by CLIENT NUMBER
|
//Remove player by CLIENT NUMBER
|
||||||
override public async Task RemovePlayer(int cNum)
|
override public async Task RemoveClient(int cNum)
|
||||||
{
|
{
|
||||||
if (cNum >= 0 && Players[cNum] != null)
|
if (cNum >= 0 && Clients[cNum] != null)
|
||||||
{
|
{
|
||||||
Player Leaving = Players[cNum];
|
EFClient Leaving = Clients[cNum];
|
||||||
|
|
||||||
// occurs when the player disconnects via log before being authenticated by RCon
|
// occurs when the player disconnects via log before being authenticated by RCon
|
||||||
if (Leaving.State != Player.ClientState.Connected)
|
if (Leaving.State != EFClient.ClientState.Connected)
|
||||||
{
|
{
|
||||||
Players[cNum] = null;
|
Clients[cNum] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.WriteInfo($"Client {Leaving} [{Leaving.State.ToString().ToLower()}] disconnecting...");
|
Logger.WriteInfo($"Client {Leaving} [{Leaving.State.ToString().ToLower()}] disconnecting...");
|
||||||
Leaving.State = Player.ClientState.Disconnecting;
|
Leaving.State = EFClient.ClientState.Disconnecting;
|
||||||
Leaving.TotalConnectionTime += Leaving.ConnectionLength;
|
Leaving.TotalConnectionTime += Leaving.ConnectionLength;
|
||||||
Leaving.LastConnection = DateTime.UtcNow;
|
Leaving.LastConnection = DateTime.UtcNow;
|
||||||
await Manager.GetClientService().Update(Leaving);
|
await Manager.GetClientService().Update(Leaving);
|
||||||
Players[cNum] = null;
|
Clients[cNum] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,7 +205,7 @@ namespace IW4MAdmin
|
|||||||
if (E.Type == GameEvent.EventType.Command &&
|
if (E.Type == GameEvent.EventType.Command &&
|
||||||
E.Extra != null &&
|
E.Extra != null &&
|
||||||
(canExecuteCommand ||
|
(canExecuteCommand ||
|
||||||
E.Origin?.Level == Player.Permission.Console))
|
E.Origin?.Level == EFClient.Permission.Console))
|
||||||
{
|
{
|
||||||
await (((Command)E.Extra).ExecuteAsync(E));
|
await (((Command)E.Extra).ExecuteAsync(E));
|
||||||
}
|
}
|
||||||
@ -355,25 +220,17 @@ namespace IW4MAdmin
|
|||||||
{
|
{
|
||||||
if (E.Type == GameEvent.EventType.Connect)
|
if (E.Type == GameEvent.EventType.Connect)
|
||||||
{
|
{
|
||||||
E.Origin.State = Player.ClientState.Authenticated;
|
E.Origin.State = EFClient.ClientState.Authenticated;
|
||||||
// add them to the server
|
await OnClientConnected(E.Origin);
|
||||||
if (!await AddPlayer(E.Origin))
|
|
||||||
{
|
|
||||||
E.Origin.State = Player.ClientState.Connecting;
|
|
||||||
Logger.WriteDebug("client didn't pass authentication, so we are discontinuing event");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// hack: makes the event propgate with the correct info
|
|
||||||
E.Origin = Players[E.Origin.ClientNumber];
|
|
||||||
|
|
||||||
ChatHistory.Add(new ChatInfo()
|
ChatHistory.Add(new ChatInfo()
|
||||||
{
|
{
|
||||||
Name = E.Origin?.Name ?? "ERROR!",
|
Name = E.Origin.Name,
|
||||||
Message = "CONNECTED",
|
Message = "CONNECTED",
|
||||||
Time = DateTime.UtcNow
|
Time = DateTime.UtcNow
|
||||||
});
|
});
|
||||||
|
|
||||||
if (E.Origin.Level > Player.Permission.Moderator)
|
if (E.Origin.Level > EFClient.Permission.Moderator)
|
||||||
{
|
{
|
||||||
E.Origin.Tell(string.Format(loc["SERVER_REPORT_COUNT"], E.Owner.Reports.Count));
|
E.Origin.Tell(string.Format(loc["SERVER_REPORT_COUNT"], E.Owner.Reports.Count));
|
||||||
}
|
}
|
||||||
@ -381,7 +238,7 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.Join)
|
else if (E.Type == GameEvent.EventType.Join)
|
||||||
{
|
{
|
||||||
await OnPlayerJoined(E.Origin);
|
await OnClientJoined(E.Origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.Flag)
|
else if (E.Type == GameEvent.EventType.Flag)
|
||||||
@ -446,11 +303,11 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.Quit)
|
else if (E.Type == GameEvent.EventType.Quit)
|
||||||
{
|
{
|
||||||
var origin = Players.FirstOrDefault(p => p != null && p.NetworkId == E.Origin.NetworkId);
|
var origin = Clients.FirstOrDefault(p => p != null && p.NetworkId == E.Origin.NetworkId);
|
||||||
|
|
||||||
if (origin != null &&
|
if (origin != null &&
|
||||||
// we only want to forward the event if they are connected.
|
// we only want to forward the event if they are connected.
|
||||||
origin.State == Player.ClientState.Connected &&
|
origin.State == EFClient.ClientState.Connected &&
|
||||||
// make sure we don't get the disconnect event from every time the game ends
|
// make sure we don't get the disconnect event from every time the game ends
|
||||||
origin.ConnectionLength < Manager.GetApplicationSettings().Configuration().RConPollRate)
|
origin.ConnectionLength < Manager.GetApplicationSettings().Configuration().RConPollRate)
|
||||||
{
|
{
|
||||||
@ -465,9 +322,9 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (origin != null &&
|
else if (origin != null &&
|
||||||
origin.State != Player.ClientState.Connected)
|
origin.State != EFClient.ClientState.Connected)
|
||||||
{
|
{
|
||||||
await RemovePlayer(origin.ClientNumber);
|
await RemoveClient(origin.ClientNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,9 +338,9 @@ namespace IW4MAdmin
|
|||||||
});
|
});
|
||||||
|
|
||||||
var currentState = E.Origin.State;
|
var currentState = E.Origin.State;
|
||||||
await RemovePlayer(E.Origin.ClientNumber);
|
await RemoveClient(E.Origin.ClientNumber);
|
||||||
|
|
||||||
if (currentState != Player.ClientState.Connected)
|
if (currentState != EFClient.ClientState.Connected)
|
||||||
{
|
{
|
||||||
throw new ServerException("Disconnecting player was not in a connected state");
|
throw new ServerException("Disconnecting player was not in a connected state");
|
||||||
}
|
}
|
||||||
@ -569,12 +426,16 @@ namespace IW4MAdmin
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (ChatHistory.Count > Math.Ceiling((double)ClientNum / 2))
|
while (ChatHistory.Count > Math.Ceiling((double)ClientNum / 2))
|
||||||
|
{
|
||||||
ChatHistory.RemoveAt(0);
|
ChatHistory.RemoveAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
// the last client hasn't fully disconnected yet
|
// the last client hasn't fully disconnected yet
|
||||||
// so there will still be at least 1 client left
|
// so there will still be at least 1 client left
|
||||||
if (ClientNum < 2)
|
if (ClientNum < 2)
|
||||||
|
{
|
||||||
ChatHistory.Clear();
|
ChatHistory.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -585,12 +446,12 @@ namespace IW4MAdmin
|
|||||||
/// array index 1 = disconnecting clients
|
/// array index 1 = disconnecting clients
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
async Task<IList<Player>[]> PollPlayersAsync()
|
async Task<IList<EFClient>[]> PollPlayersAsync()
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var now = DateTime.Now;
|
var now = DateTime.Now;
|
||||||
#endif
|
#endif
|
||||||
var currentClients = GetPlayersAsList();
|
var currentClients = GetClientsAsList();
|
||||||
var polledClients = (await this.GetStatusAsync()).AsEnumerable();
|
var polledClients = (await this.GetStatusAsync()).AsEnumerable();
|
||||||
if (this.Manager.GetApplicationSettings().Configuration().IgnoreBots)
|
if (this.Manager.GetApplicationSettings().Configuration().IgnoreBots)
|
||||||
{
|
{
|
||||||
@ -604,15 +465,15 @@ namespace IW4MAdmin
|
|||||||
foreach (var client in polledClients)
|
foreach (var client in polledClients)
|
||||||
{
|
{
|
||||||
// todo: move out somehwere
|
// todo: move out somehwere
|
||||||
var existingClient = Players[client.ClientNumber] ?? client;
|
var existingClient = Clients[client.ClientNumber] ?? client;
|
||||||
existingClient.Ping = client.Ping;
|
existingClient.Ping = client.Ping;
|
||||||
existingClient.Score = client.Score;
|
existingClient.Score = client.Score;
|
||||||
}
|
}
|
||||||
|
|
||||||
var disconnectingClients = currentClients.Except(polledClients);
|
var disconnectingClients = currentClients.Except(polledClients);
|
||||||
var connectingClients = polledClients.Except(currentClients.Where(c => c.State == Player.ClientState.Connected));
|
var connectingClients = polledClients.Except(currentClients.Where(c => c.State == EFClient.ClientState.Connected));
|
||||||
|
|
||||||
return new List<Player>[] { connectingClients.ToList(), disconnectingClients.ToList() };
|
return new List<EFClient>[] { connectingClients.ToList(), disconnectingClients.ToList() };
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime start = DateTime.Now;
|
DateTime start = DateTime.Now;
|
||||||
@ -626,11 +487,13 @@ namespace IW4MAdmin
|
|||||||
if (Manager.ShutdownRequested())
|
if (Manager.ShutdownRequested())
|
||||||
{
|
{
|
||||||
// todo: fix up disconnect
|
// todo: fix up disconnect
|
||||||
//for (int i = 0; i < Players.Count; i++)
|
//for (int i = 0; i < EFClients.Count; i++)
|
||||||
// await RemovePlayer(i);
|
// await RemoveClient(i);
|
||||||
|
|
||||||
foreach (var plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins)
|
foreach (var plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins)
|
||||||
|
{
|
||||||
await plugin.OnUnloadAsync();
|
await plugin.OnUnloadAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// only check every 2 minutes if the server doesn't seem to be responding
|
// only check every 2 minutes if the server doesn't seem to be responding
|
||||||
@ -644,7 +507,7 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
foreach (var disconnectingClient in polledClients[1])
|
foreach (var disconnectingClient in polledClients[1])
|
||||||
{
|
{
|
||||||
if (disconnectingClient.State == Player.ClientState.Disconnecting)
|
if (disconnectingClient.State == EFClient.ClientState.Disconnecting)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -669,8 +532,8 @@ namespace IW4MAdmin
|
|||||||
foreach (var client in polledClients[0])
|
foreach (var client in polledClients[0])
|
||||||
{
|
{
|
||||||
// this prevents duplicate events from being sent to the event api
|
// this prevents duplicate events from being sent to the event api
|
||||||
if (GetPlayersAsList().Count(c => c.NetworkId == client.NetworkId &&
|
if (GetClientsAsList().Count(c => c.NetworkId == client.NetworkId &&
|
||||||
c.State == Player.ClientState.Connected) != 0)
|
c.State == EFClient.ClientState.Connected) != 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -730,9 +593,12 @@ namespace IW4MAdmin
|
|||||||
// update the player history
|
// update the player history
|
||||||
if ((lastCount - playerCountStart).TotalMinutes >= SharedLibraryCore.Helpers.PlayerHistory.UpdateInterval)
|
if ((lastCount - playerCountStart).TotalMinutes >= SharedLibraryCore.Helpers.PlayerHistory.UpdateInterval)
|
||||||
{
|
{
|
||||||
while (PlayerHistory.Count > ((60 / SharedLibraryCore.Helpers.PlayerHistory.UpdateInterval) * 12)) // 12 times a hour for 12 hours
|
while (ClientHistory.Count > ((60 / SharedLibraryCore.Helpers.PlayerHistory.UpdateInterval) * 12)) // 12 times a hour for 12 hours
|
||||||
PlayerHistory.Dequeue();
|
{
|
||||||
PlayerHistory.Enqueue(new SharedLibraryCore.Helpers.PlayerHistory(ClientNum));
|
ClientHistory.Dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientHistory.Enqueue(new SharedLibraryCore.Helpers.PlayerHistory(ClientNum));
|
||||||
playerCountStart = DateTime.Now;
|
playerCountStart = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,7 +648,9 @@ namespace IW4MAdmin
|
|||||||
new IW3RConParser();
|
new IW3RConParser();
|
||||||
|
|
||||||
if (ServerConfig.UseIW5MParser)
|
if (ServerConfig.UseIW5MParser)
|
||||||
|
{
|
||||||
RconParser = new IW5MRConParser();
|
RconParser = new IW5MRConParser();
|
||||||
|
}
|
||||||
|
|
||||||
var version = await this.GetDvarAsync<string>("version");
|
var version = await this.GetDvarAsync<string>("version");
|
||||||
GameName = Utilities.GetGame(version.Value);
|
GameName = Utilities.GetGame(version.Value);
|
||||||
@ -793,16 +661,26 @@ namespace IW4MAdmin
|
|||||||
RconParser = new IW4RConParser();
|
RconParser = new IW4RConParser();
|
||||||
}
|
}
|
||||||
else if (GameName == Game.IW5)
|
else if (GameName == Game.IW5)
|
||||||
|
{
|
||||||
EventParser = new IW5EventParser();
|
EventParser = new IW5EventParser();
|
||||||
|
}
|
||||||
else if (GameName == Game.T5M)
|
else if (GameName == Game.T5M)
|
||||||
|
{
|
||||||
EventParser = new T5MEventParser();
|
EventParser = new T5MEventParser();
|
||||||
|
}
|
||||||
else if (GameName == Game.T6M)
|
else if (GameName == Game.T6M)
|
||||||
|
{
|
||||||
EventParser = new T6MEventParser();
|
EventParser = new T6MEventParser();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
EventParser = new IW3EventParser(); // this uses the 'main' folder for log paths
|
EventParser = new IW3EventParser(); // this uses the 'main' folder for log paths
|
||||||
|
}
|
||||||
|
|
||||||
if (GameName == Game.UKN)
|
if (GameName == Game.UKN)
|
||||||
|
{
|
||||||
Logger.WriteWarning($"Game name not recognized: {version}");
|
Logger.WriteWarning($"Game name not recognized: {version}");
|
||||||
|
}
|
||||||
|
|
||||||
var infoResponse = await this.GetInfoAsync();
|
var infoResponse = await this.GetInfoAsync();
|
||||||
// this is normally slow, but I'm only doing it because different games have different prefixes
|
// this is normally slow, but I'm only doing it because different games have different prefixes
|
||||||
@ -906,7 +784,7 @@ namespace IW4MAdmin
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task Warn(String Reason, Player Target, Player Origin)
|
protected override async Task Warn(String Reason, EFClient Target, EFClient Origin)
|
||||||
{
|
{
|
||||||
// ensure player gets warned if command not performed on them in game
|
// ensure player gets warned if command not performed on them in game
|
||||||
if (Target.ClientNumber < 0)
|
if (Target.ClientNumber < 0)
|
||||||
@ -948,7 +826,7 @@ namespace IW4MAdmin
|
|||||||
await Manager.GetPenaltyService().Create(newPenalty);
|
await Manager.GetPenaltyService().Create(newPenalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task Kick(String Reason, Player Target, Player Origin)
|
protected override async Task Kick(String Reason, EFClient Target, EFClient Origin)
|
||||||
{
|
{
|
||||||
// ensure player gets kicked if command not performed on them in game
|
// ensure player gets kicked if command not performed on them in game
|
||||||
if (Target.ClientNumber < 0)
|
if (Target.ClientNumber < 0)
|
||||||
@ -971,7 +849,7 @@ namespace IW4MAdmin
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
await Target.CurrentServer.RemovePlayer(Target.ClientNumber);
|
await Target.CurrentServer.RemoveClient(Target.ClientNumber);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var newPenalty = new Penalty()
|
var newPenalty = new Penalty()
|
||||||
@ -988,7 +866,7 @@ namespace IW4MAdmin
|
|||||||
await Manager.GetPenaltyService().Create(newPenalty);
|
await Manager.GetPenaltyService().Create(newPenalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin)
|
protected override async Task TempBan(String Reason, TimeSpan length, EFClient Target, EFClient Origin)
|
||||||
{
|
{
|
||||||
// ensure player gets banned if command not performed on them in game
|
// ensure player gets banned if command not performed on them in game
|
||||||
if (Target.ClientNumber < 0)
|
if (Target.ClientNumber < 0)
|
||||||
@ -1009,7 +887,7 @@ namespace IW4MAdmin
|
|||||||
await Target.CurrentServer.ExecuteCommandAsync(formattedKick);
|
await Target.CurrentServer.ExecuteCommandAsync(formattedKick);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
await Target.CurrentServer.RemovePlayer(Target.ClientNumber);
|
await Target.CurrentServer.RemoveClient(Target.ClientNumber);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Penalty newPenalty = new Penalty()
|
Penalty newPenalty = new Penalty()
|
||||||
@ -1027,15 +905,15 @@ namespace IW4MAdmin
|
|||||||
await Manager.GetPenaltyService().Create(newPenalty);
|
await Manager.GetPenaltyService().Create(newPenalty);
|
||||||
}
|
}
|
||||||
|
|
||||||
override protected async Task Ban(String Message, Player Target, Player Origin)
|
override protected async Task Ban(String Message, EFClient Target, EFClient Origin)
|
||||||
{
|
{
|
||||||
// ensure player gets banned if command not performed on them in game
|
// ensure player gets banned if command not performed on them in game
|
||||||
if (Target.ClientNumber < 0)
|
if (Target.ClientNumber < 0)
|
||||||
{
|
{
|
||||||
Player ingameClient = null;
|
EFClient ingameClient = null;
|
||||||
|
|
||||||
ingameClient = Manager.GetServers()
|
ingameClient = Manager.GetServers()
|
||||||
.Select(s => s.GetPlayersAsList())
|
.Select(s => s.GetClientsAsList())
|
||||||
.FirstOrDefault(l => l.FirstOrDefault(c => c.ClientId == Target.ClientId) != null)
|
.FirstOrDefault(l => l.FirstOrDefault(c => c.ClientId == Target.ClientId) != null)
|
||||||
?.First(c => c.ClientId == Target.ClientId);
|
?.First(c => c.ClientId == Target.ClientId);
|
||||||
|
|
||||||
@ -1049,13 +927,13 @@ namespace IW4MAdmin
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// this is set only because they're still in the server.
|
// this is set only because they're still in the server.
|
||||||
Target.Level = Player.Permission.Banned;
|
Target.Level = EFClient.Permission.Banned;
|
||||||
|
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
string formattedString = String.Format(RconParser.GetCommandPrefixes().Kick, Target.ClientNumber, $"{loc["SERVER_BAN_TEXT"]} - ^5{Message} ^7({loc["SERVER_BAN_APPEAL"]} {Website})^7");
|
string formattedString = String.Format(RconParser.GetCommandPrefixes().Kick, Target.ClientNumber, $"{loc["SERVER_BAN_TEXT"]} - ^5{Message} ^7({loc["SERVER_BAN_APPEAL"]} {Website})^7");
|
||||||
await Target.CurrentServer.ExecuteCommandAsync(formattedString);
|
await Target.CurrentServer.ExecuteCommandAsync(formattedString);
|
||||||
#else
|
#else
|
||||||
await Target.CurrentServer.RemovePlayer(Target.ClientNumber);
|
await Target.CurrentServer.RemoveClient(Target.ClientNumber);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1077,7 +955,7 @@ namespace IW4MAdmin
|
|||||||
Manager.GetPrivilegedClients().Remove(Target.ClientId);
|
Manager.GetPrivilegedClients().Remove(Target.ClientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
override public async Task Unban(string reason, Player Target, Player Origin)
|
override public async Task Unban(string reason, EFClient Target, EFClient Origin)
|
||||||
{
|
{
|
||||||
var unbanPenalty = new Penalty()
|
var unbanPenalty = new Penalty()
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,11 @@
|
|||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Prerelease' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
|
<OutputPath>bin\Prerelease\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="DiscordWebhook.py" />
|
<Compile Include="DiscordWebhook.py" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -50,7 +55,7 @@
|
|||||||
<Publish>True</Publish>
|
<Publish>True</Publish>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.Web.targets" />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.Web.targets" />
|
||||||
<!-- Uncomment the CoreCompile target to enable the Build command in
|
<!-- Uncomment the CoreCompile target to enable the Build command in
|
||||||
Visual Studio and specify your pre- and post-build commands in
|
Visual Studio and specify your pre- and post-build commands in
|
||||||
the BeforeBuild and AfterBuild targets below. -->
|
the BeforeBuild and AfterBuild targets below. -->
|
||||||
@ -59,7 +64,7 @@
|
|||||||
</Target>
|
</Target>
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio>
|
<VisualStudio>
|
||||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||||
<WebProjectProperties>
|
<WebProjectProperties>
|
||||||
|
@ -27,10 +27,16 @@
|
|||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Prerelease' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||||
|
<OutputPath>bin\Prerelease\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="GameLogServer\log_reader.py">
|
<Compile Include="GameLogServer\log_reader.py">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="GameLogServer\restart_resource.py" />
|
||||||
<Compile Include="GameLogServer\server.py">
|
<Compile Include="GameLogServer\server.py">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
29
GameLogServer/GameLogServer/restart_resource.py
Normal file
29
GameLogServer/GameLogServer/restart_resource.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
from flask_restful import Resource
|
||||||
|
from flask import request
|
||||||
|
import requests
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
|
||||||
|
def get_pid_of_server_windows(port):
|
||||||
|
process = subprocess.Popen('netstat -aon', shell=True, stdout=subprocess.PIPE)
|
||||||
|
output = process.communicate()[0]
|
||||||
|
matches = re.search(' *(UDP) +([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}):'+ str(port) + ' +[^\w]*([0-9]+)', output.decode('utf-8'))
|
||||||
|
if matches is not None:
|
||||||
|
return matches.group(3)
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
class RestartResource(Resource):
|
||||||
|
def get(self):
|
||||||
|
try:
|
||||||
|
response = requests.get('http://' + request.remote_addr + ':1624/api/restartapproved')
|
||||||
|
if response.status_code == 200:
|
||||||
|
pid = get_pid_of_server_windows(response.json()['port'])
|
||||||
|
subprocess.check_output("Taskkill /PID %s /F" % pid)
|
||||||
|
else:
|
||||||
|
return {}, 400
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return {}, 500
|
||||||
|
return {}, 200
|
@ -1,9 +1,11 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask_restful import Api
|
from flask_restful import Api
|
||||||
from .log_resource import LogResource
|
from .log_resource import LogResource
|
||||||
|
from .restart_resource import RestartResource
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
api = Api(app)
|
api = Api(app)
|
||||||
api.add_resource(LogResource, '/log/<string:path>')
|
api.add_resource(LogResource, '/log/<string:path>')
|
||||||
|
api.add_resource(RestartResource, '/restart')
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
VisualStudioVersion = 15.0.26730.16
|
VisualStudioVersion = 15.0.26730.16
|
||||||
@ -41,6 +40,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ScriptPlugins", "ScriptPlug
|
|||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
Plugins\ScriptPlugins\SharedGUIDKick.js = Plugins\ScriptPlugins\SharedGUIDKick.js
|
Plugins\ScriptPlugins\SharedGUIDKick.js = Plugins\ScriptPlugins\SharedGUIDKick.js
|
||||||
Plugins\ScriptPlugins\VPNDetection.js = Plugins\ScriptPlugins\VPNDetection.js
|
Plugins\ScriptPlugins\VPNDetection.js = Plugins\ScriptPlugins\VPNDetection.js
|
||||||
|
Plugins\ScriptPlugins\VpnDetectionPrivate.js = Plugins\ScriptPlugins\VpnDetectionPrivate.js
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "GameLogServer", "GameLogServer\GameLogServer.pyproj", "{42EFDA12-10D3-4C40-A210-9483520116BC}"
|
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "GameLogServer", "GameLogServer\GameLogServer.pyproj", "{42EFDA12-10D3-4C40-A210-9483520116BC}"
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<SuppressCollectPythonCloudServiceFiles>true</SuppressCollectPythonCloudServiceFiles>
|
<SuppressCollectPythonCloudServiceFiles>true</SuppressCollectPythonCloudServiceFiles>
|
||||||
<Name>Master</Name>
|
<Name>Master</Name>
|
||||||
<RootNamespace>Master</RootNamespace>
|
<RootNamespace>Master</RootNamespace>
|
||||||
<InterpreterId>MSBuild|dev_env|$(MSBuildProjectFullPath)</InterpreterId>
|
<InterpreterId>MSBuild|env|X:\IW4MAdmin\GameLogServer\GameLogServer.pyproj</InterpreterId>
|
||||||
<IsWindowsApplication>False</IsWindowsApplication>
|
<IsWindowsApplication>False</IsWindowsApplication>
|
||||||
<PythonRunWebServerCommand>
|
<PythonRunWebServerCommand>
|
||||||
</PythonRunWebServerCommand>
|
</PythonRunWebServerCommand>
|
||||||
@ -111,23 +111,15 @@
|
|||||||
<Folder Include="master\templates\" />
|
<Folder Include="master\templates\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="FolderProfile.pubxml" />
|
|
||||||
<Content Include="master\config\master.json" />
|
<Content Include="master\config\master.json" />
|
||||||
<Content Include="master\templates\serverlist.html" />
|
<Content Include="master\templates\serverlist.html" />
|
||||||
|
<None Include="Release.pubxml" />
|
||||||
<Content Include="requirements.txt" />
|
<Content Include="requirements.txt" />
|
||||||
<Content Include="master\templates\index.html" />
|
<Content Include="master\templates\index.html" />
|
||||||
<Content Include="master\templates\layout.html" />
|
<Content Include="master\templates\layout.html" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Interpreter Include="dev_env\">
|
<InterpreterReference Include="MSBuild|env|X:\IW4MAdmin\GameLogServer\GameLogServer.pyproj" />
|
||||||
<Id>dev_env</Id>
|
|
||||||
<Version>3.6</Version>
|
|
||||||
<Description>dev_env (Python 3.6 (64-bit))</Description>
|
|
||||||
<InterpreterPath>Scripts\python.exe</InterpreterPath>
|
|
||||||
<WindowsInterpreterPath>Scripts\pythonw.exe</WindowsInterpreterPath>
|
|
||||||
<PathEnvironmentVariable>PYTHONPATH</PathEnvironmentVariable>
|
|
||||||
<Architecture>X64</Architecture>
|
|
||||||
</Interpreter>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.Web.targets" />
|
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.Web.targets" />
|
||||||
<!-- Specify pre- and post-build commands in the BeforeBuild and
|
<!-- Specify pre- and post-build commands in the BeforeBuild and
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
aniso8601==3.0.0
|
aniso8601==3.0.2
|
||||||
click==6.7
|
click==6.7
|
||||||
Flask==0.12.2
|
Flask==1.0.2
|
||||||
Flask-JWT==0.3.2
|
Flask-JWT==0.3.2
|
||||||
Flask-JWT-Extended==3.8.1
|
Flask-JWT-Extended==3.8.1
|
||||||
Flask-RESTful==0.3.6
|
Flask-RESTful==0.3.6
|
||||||
@ -8,9 +8,15 @@ itsdangerous==0.24
|
|||||||
Jinja2==2.10
|
Jinja2==2.10
|
||||||
MarkupSafe==1.0
|
MarkupSafe==1.0
|
||||||
marshmallow==3.0.0b8
|
marshmallow==3.0.0b8
|
||||||
pip==9.0.1
|
pip==9.0.3
|
||||||
PyJWT==1.4.2
|
PyJWT==1.4.2
|
||||||
pytz==2018.4
|
pytz==2018.5
|
||||||
setuptools==39.0.1
|
setuptools==39.0.1
|
||||||
six==1.11.0
|
six==1.11.0
|
||||||
Werkzeug==0.14.1
|
Werkzeug==0.14.1
|
||||||
|
certifi==2018.10.15
|
||||||
|
chardet==3.0.4
|
||||||
|
idna==2.7
|
||||||
|
psutil==5.4.8
|
||||||
|
requests==2.20.0
|
||||||
|
urllib3==1.24
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -17,15 +18,15 @@ namespace IW4ScriptCommands.Commands
|
|||||||
public IW4MAdmin.Plugins.Stats.Models.EFClientStatistics Stats { get; set; }
|
public IW4MAdmin.Plugins.Stats.Models.EFClientStatistics Stats { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetTeamAssignments(Player client, bool isDisconnect, Server server, string teamsString = "")
|
public static string GetTeamAssignments(EFClient client, bool isDisconnect, Server server, string teamsString = "")
|
||||||
{
|
{
|
||||||
var scriptClientTeams = teamsString.Split(';', StringSplitOptions.RemoveEmptyEntries)
|
var scriptClientTeams = teamsString.Split(';', StringSplitOptions.RemoveEmptyEntries)
|
||||||
.Select(c => c.Split(','))
|
.Select(c => c.Split(','))
|
||||||
.Select(c => new TeamAssignment()
|
.Select(c => new TeamAssignment()
|
||||||
{
|
{
|
||||||
CurrentTeam = (IW4MAdmin.Plugins.Stats.IW4Info.Team)Enum.Parse(typeof(IW4MAdmin.Plugins.Stats.IW4Info.Team), c[1]),
|
CurrentTeam = (IW4MAdmin.Plugins.Stats.IW4Info.Team)Enum.Parse(typeof(IW4MAdmin.Plugins.Stats.IW4Info.Team), c[1]),
|
||||||
Num = server.GetPlayersAsList().FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0]))?.ClientNumber ?? -1,
|
Num = server.GetClientsAsList().FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0]))?.ClientNumber ?? -1,
|
||||||
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(server.Players.FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0])).ClientId, server.GetHashCode())
|
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(server.Clients.FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0])).ClientId, server.GetHashCode())
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ namespace IW4ScriptCommands.Commands
|
|||||||
|
|
||||||
List<string> teamAssignments = new List<string>();
|
List<string> teamAssignments = new List<string>();
|
||||||
|
|
||||||
var _c = server.GetPlayersAsList();
|
var _c = server.GetClientsAsList();
|
||||||
if (isDisconnect && client != null)
|
if (isDisconnect && client != null)
|
||||||
{
|
{
|
||||||
_c = _c.Where(c => c.ClientNumber != client.ClientNumber).ToList();
|
_c = _c.Where(c => c.ClientNumber != client.ClientNumber).ToList();
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||||
<ApplicationIcon />
|
<ApplicationIcon />
|
||||||
<StartupObject />
|
<StartupObject />
|
||||||
|
<Configurations>Debug;Release;Prerelease</Configurations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -8,7 +9,7 @@ namespace IW4MAdmin.Plugins.Login.Commands
|
|||||||
{
|
{
|
||||||
public class CLogin : Command
|
public class CLogin : Command
|
||||||
{
|
{
|
||||||
public CLogin() : base("login", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_LOGIN_COMMANDS_LOGIN_DESC"], "li", Player.Permission.Trusted, false, new CommandArgument[]
|
public CLogin() : base("login", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_LOGIN_COMMANDS_LOGIN_DESC"], "li", EFClient.Permission.Trusted, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@ using System.Reflection;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore.Exceptions;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
@ -38,11 +39,11 @@ namespace IW4MAdmin.Plugins.Login
|
|||||||
|
|
||||||
if (E.Type == GameEvent.EventType.Command)
|
if (E.Type == GameEvent.EventType.Command)
|
||||||
{
|
{
|
||||||
if (E.Origin.Level < Player.Permission.Moderator ||
|
if (E.Origin.Level < EFClient.Permission.Moderator ||
|
||||||
E.Origin.Level == Player.Permission.Console)
|
E.Origin.Level == EFClient.Permission.Console)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
E.Owner.Manager.GetPrivilegedClients().TryGetValue(E.Origin.ClientId, out Player client);
|
E.Owner.Manager.GetPrivilegedClients().TryGetValue(E.Origin.ClientId, out EFClient client);
|
||||||
|
|
||||||
if (((Command)E.Extra).Name == new SharedLibraryCore.Commands.CSetPassword().Name &&
|
if (((Command)E.Extra).Name == new SharedLibraryCore.Commands.CSetPassword().Name &&
|
||||||
client?.Password == null)
|
client?.Password == null)
|
||||||
|
@ -5,6 +5,7 @@ using System.Text.RegularExpressions;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
|||||||
|
|
||||||
if (containsObjectionalWord)
|
if (containsObjectionalWord)
|
||||||
{
|
{
|
||||||
E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, new Player()
|
E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1,
|
ClientId = 1,
|
||||||
CurrentServer = E.Owner
|
CurrentServer = E.Owner
|
||||||
@ -85,7 +86,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
|||||||
var clientProfanity = ProfanityCounts[E.Origin.ClientId];
|
var clientProfanity = ProfanityCounts[E.Origin.ClientId];
|
||||||
if (clientProfanity.Infringements >= Settings.Configuration().KickAfterInfringementCount)
|
if (clientProfanity.Infringements >= Settings.Configuration().KickAfterInfringementCount)
|
||||||
{
|
{
|
||||||
clientProfanity.Client.Kick(Settings.Configuration().ProfanityKickMessage, new Player()
|
clientProfanity.Client.Kick(Settings.Configuration().ProfanityKickMessage, new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1,
|
ClientId = 1,
|
||||||
CurrentServer = E.Owner
|
CurrentServer = E.Owner
|
||||||
@ -96,7 +97,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
|||||||
{
|
{
|
||||||
clientProfanity.Infringements++;
|
clientProfanity.Infringements++;
|
||||||
|
|
||||||
clientProfanity.Client.Warn(Settings.Configuration().ProfanityWarningMessage, new Player()
|
clientProfanity.Client.Warn(Settings.Configuration().ProfanityWarningMessage, new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1,
|
ClientId = 1,
|
||||||
CurrentServer = E.Owner
|
CurrentServer = E.Owner
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.ProfanityDeterment
|
namespace IW4MAdmin.Plugins.ProfanityDeterment
|
||||||
{
|
{
|
||||||
class Tracking
|
class Tracking
|
||||||
{
|
{
|
||||||
public Player Client { get; private set; }
|
public EFClient Client { get; private set; }
|
||||||
public int Infringements { get; set; }
|
public int Infringements { get; set; }
|
||||||
|
|
||||||
public Tracking(Player client)
|
public Tracking(EFClient client)
|
||||||
{
|
{
|
||||||
Client = client;
|
Client = client;
|
||||||
Infringements = 0;
|
Infringements = 0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using SharedLibraryCore.Helpers;
|
using IW4MAdmin.Plugins.Stats.Models;
|
||||||
|
using SharedLibraryCore.Helpers;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using IW4MAdmin.Plugins.Stats.Models;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -20,7 +20,9 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
};
|
};
|
||||||
|
|
||||||
public ChangeTracking<EFACSnapshot> Tracker { get; private set; }
|
public ChangeTracking<EFACSnapshot> Tracker { get; private set; }
|
||||||
|
public const int QUEUE_COUNT = 10;
|
||||||
|
|
||||||
|
public List<EFClientKill> QueuedHits { get; set; }
|
||||||
int Kills;
|
int Kills;
|
||||||
int HitCount;
|
int HitCount;
|
||||||
Dictionary<IW4Info.HitLocation, int> HitLocationCount;
|
Dictionary<IW4Info.HitLocation, int> HitLocationCount;
|
||||||
@ -37,10 +39,14 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
Log = log;
|
Log = log;
|
||||||
HitLocationCount = new Dictionary<IW4Info.HitLocation, int>();
|
HitLocationCount = new Dictionary<IW4Info.HitLocation, int>();
|
||||||
foreach (var loc in Enum.GetValues(typeof(IW4Info.HitLocation)))
|
foreach (var loc in Enum.GetValues(typeof(IW4Info.HitLocation)))
|
||||||
|
{
|
||||||
HitLocationCount.Add((IW4Info.HitLocation)loc, 0);
|
HitLocationCount.Add((IW4Info.HitLocation)loc, 0);
|
||||||
|
}
|
||||||
|
|
||||||
ClientStats = clientStats;
|
ClientStats = clientStats;
|
||||||
Strain = new Strain();
|
Strain = new Strain();
|
||||||
Tracker = new ChangeTracking<EFACSnapshot>();
|
Tracker = new ChangeTracking<EFACSnapshot>();
|
||||||
|
QueuedHits = new List<EFClientKill>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -56,10 +62,12 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
hit.HitLoc == IW4Info.HitLocation.none || hit.TimeOffset - LastOffset < 0 ||
|
hit.HitLoc == IW4Info.HitLocation.none || hit.TimeOffset - LastOffset < 0 ||
|
||||||
// hack: prevents false positives
|
// hack: prevents false positives
|
||||||
(LastWeapon != hit.Weapon && (hit.TimeOffset - LastOffset) == 50))
|
(LastWeapon != hit.Weapon && (hit.TimeOffset - LastOffset) == 50))
|
||||||
|
{
|
||||||
return new DetectionPenaltyResult()
|
return new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
ClientPenalty = Penalty.PenaltyType.Any,
|
ClientPenalty = Penalty.PenaltyType.Any,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
DetectionPenaltyResult result = null;
|
DetectionPenaltyResult result = null;
|
||||||
LastWeapon = hit.Weapon;
|
LastWeapon = hit.Weapon;
|
||||||
@ -141,7 +149,6 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
ClientStats.MaxStrain = currentStrain;
|
ClientStats.MaxStrain = currentStrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// flag
|
// flag
|
||||||
if (currentStrain > Thresholds.MaxStrainFlag)
|
if (currentStrain > Thresholds.MaxStrainFlag)
|
||||||
{
|
{
|
||||||
@ -201,7 +208,10 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
foreach (var kvp in HitLocationCount)
|
foreach (var kvp in HitLocationCount)
|
||||||
|
{
|
||||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
Log.WriteDebug(sb.ToString());
|
Log.WriteDebug(sb.ToString());
|
||||||
|
|
||||||
result = new DetectionPenaltyResult()
|
result = new DetectionPenaltyResult()
|
||||||
@ -222,7 +232,10 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
foreach (var kvp in HitLocationCount)
|
foreach (var kvp in HitLocationCount)
|
||||||
|
{
|
||||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
Log.WriteDebug(sb.ToString());
|
Log.WriteDebug(sb.ToString());
|
||||||
|
|
||||||
result = new DetectionPenaltyResult()
|
result = new DetectionPenaltyResult()
|
||||||
@ -251,7 +264,10 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
Log.WriteDebug($"**MaxRatio {maxBoneRatioLerpValueForBan}");
|
Log.WriteDebug($"**MaxRatio {maxBoneRatioLerpValueForBan}");
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
foreach (var kvp in HitLocationCount)
|
foreach (var kvp in HitLocationCount)
|
||||||
|
{
|
||||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
Log.WriteDebug(sb.ToString());
|
Log.WriteDebug(sb.ToString());
|
||||||
|
|
||||||
result = new DetectionPenaltyResult()
|
result = new DetectionPenaltyResult()
|
||||||
@ -272,7 +288,10 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
Log.WriteDebug($"**MaxRatio {maxBoneRatioLerpValueForFlag}");
|
Log.WriteDebug($"**MaxRatio {maxBoneRatioLerpValueForFlag}");
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
foreach (var kvp in HitLocationCount)
|
foreach (var kvp in HitLocationCount)
|
||||||
|
{
|
||||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
Log.WriteDebug(sb.ToString());
|
Log.WriteDebug(sb.ToString());
|
||||||
|
|
||||||
result = new DetectionPenaltyResult()
|
result = new DetectionPenaltyResult()
|
||||||
@ -306,15 +325,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
|
|
||||||
if (currentChestAbdomenRatio > chestAbdomenLerpValueForBan && chestHits >= Thresholds.MediumSampleMinKills + 30)
|
if (currentChestAbdomenRatio > chestAbdomenLerpValueForBan && chestHits >= Thresholds.MediumSampleMinKills + 30)
|
||||||
{
|
{
|
||||||
Log.WriteDebug("**Maximum Chest/Abdomen Ratio Reached For Ban**");
|
//Log.WriteDebug("**Maximum Chest/Abdomen Ratio Reached For Ban**");
|
||||||
Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
//Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
||||||
Log.WriteDebug($"**Chest Hits: {chestHits}");
|
//Log.WriteDebug($"**Chest Hits: {chestHits}");
|
||||||
Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
//Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||||
Log.WriteDebug($"**MaxRatio {chestAbdomenLerpValueForBan}");
|
//Log.WriteDebug($"**MaxRatio {chestAbdomenLerpValueForBan}");
|
||||||
var sb = new StringBuilder();
|
//var sb = new StringBuilder();
|
||||||
foreach (var kvp in HitLocationCount)
|
//foreach (var kvp in HitLocationCount)
|
||||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
// sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||||
Log.WriteDebug(sb.ToString());
|
//Log.WriteDebug(sb.ToString());
|
||||||
|
|
||||||
result = new DetectionPenaltyResult()
|
result = new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
@ -327,16 +346,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.WriteDebug("**Maximum Chest/Abdomen Ratio Reached For Flag**");
|
//Log.WriteDebug("**Maximum Chest/Abdomen Ratio Reached For Flag**");
|
||||||
Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
//Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
||||||
Log.WriteDebug($"**Chest Hits: {chestHits}");
|
//Log.WriteDebug($"**Chest Hits: {chestHits}");
|
||||||
Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
//Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||||
Log.WriteDebug($"**MaxRatio {chestAbdomenRatioLerpValueForFlag}");
|
//Log.WriteDebug($"**MaxRatio {chestAbdomenRatioLerpValueForFlag}");
|
||||||
var sb = new StringBuilder();
|
//var sb = new StringBuilder();
|
||||||
foreach (var kvp in HitLocationCount)
|
//foreach (var kvp in HitLocationCount)
|
||||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
// sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||||
Log.WriteDebug(sb.ToString());
|
//Log.WriteDebug(sb.ToString());
|
||||||
// Log.WriteDebug($"ThresholdReached: {AboveThresholdCount}");
|
|
||||||
|
|
||||||
result = new DetectionPenaltyResult()
|
result = new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
@ -407,15 +425,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
|
|
||||||
if (currentChestAbdomenRatio > chestAbdomenLerpValueForBan)
|
if (currentChestAbdomenRatio > chestAbdomenLerpValueForBan)
|
||||||
{
|
{
|
||||||
Log.WriteDebug("**Maximum Lifetime Chest/Abdomen Ratio Reached For Ban**");
|
//Log.WriteDebug("**Maximum Lifetime Chest/Abdomen Ratio Reached For Ban**");
|
||||||
Log.WriteDebug($"ClientId: {stats.ClientId}");
|
//Log.WriteDebug($"ClientId: {stats.ClientId}");
|
||||||
Log.WriteDebug($"**Total Chest Hits: {totalChestHits}");
|
//Log.WriteDebug($"**Total Chest Hits: {totalChestHits}");
|
||||||
Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
//Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||||
Log.WriteDebug($"**MaxRatio {chestAbdomenLerpValueForBan}");
|
//Log.WriteDebug($"**MaxRatio {chestAbdomenLerpValueForBan}");
|
||||||
var sb = new StringBuilder();
|
//var sb = new StringBuilder();
|
||||||
foreach (var location in stats.HitLocations)
|
//foreach (var location in stats.HitLocations)
|
||||||
sb.Append($"HitLocation: {location.Location} -> {location.HitCount}\r\n");
|
// sb.Append($"HitLocation: {location.Location} -> {location.HitCount}\r\n");
|
||||||
Log.WriteDebug(sb.ToString());
|
//Log.WriteDebug(sb.ToString());
|
||||||
|
|
||||||
return new DetectionPenaltyResult()
|
return new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
@ -428,15 +446,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.WriteDebug("**Maximum Lifetime Chest/Abdomen Ratio Reached For Flag**");
|
//Log.WriteDebug("**Maximum Lifetime Chest/Abdomen Ratio Reached For Flag**");
|
||||||
Log.WriteDebug($"ClientId: {stats.ClientId}");
|
//Log.WriteDebug($"ClientId: {stats.ClientId}");
|
||||||
Log.WriteDebug($"**Total Chest Hits: {totalChestHits}");
|
//Log.WriteDebug($"**Total Chest Hits: {totalChestHits}");
|
||||||
Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
//Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||||
Log.WriteDebug($"**MaxRatio {chestAbdomenRatioLerpValueForFlag}");
|
//Log.WriteDebug($"**MaxRatio {chestAbdomenRatioLerpValueForFlag}");
|
||||||
var sb = new StringBuilder();
|
//var sb = new StringBuilder();
|
||||||
foreach (var location in stats.HitLocations)
|
//foreach (var location in stats.HitLocations)
|
||||||
sb.Append($"HitLocation: {location.Location} -> {location.HitCount}\r\n");
|
// sb.Append($"HitLocation: {location.Location} -> {location.HitCount}\r\n");
|
||||||
Log.WriteDebug(sb.ToString());
|
//Log.WriteDebug(sb.ToString());
|
||||||
|
|
||||||
return new DetectionPenaltyResult()
|
return new DetectionPenaltyResult()
|
||||||
{
|
{
|
||||||
|
@ -23,18 +23,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
|||||||
|
|
||||||
double decayFactor = GetDecay(deltaTime);
|
double decayFactor = GetDecay(deltaTime);
|
||||||
CurrentStrain *= decayFactor;
|
CurrentStrain *= decayFactor;
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
Console.WriteLine($"Decay Factor = {decayFactor} ");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
double[] distance = Helpers.Extensions.AngleStuff(newAngle, LastAngle);
|
double[] distance = Helpers.Extensions.AngleStuff(newAngle, LastAngle);
|
||||||
LastDistance = distance[0] + distance[1];
|
LastDistance = distance[0] + distance[1];
|
||||||
|
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
Console.WriteLine($"Last Distance = {LastDistance}");
|
Console.WriteLine($"Angle Between = {LastDistance}");
|
||||||
|
Console.WriteLine($"Distance From Target = {killDistance}");
|
||||||
|
Console.WriteLine($"Time Offset = {deltaTime}");
|
||||||
|
Console.WriteLine($"Decay Factor = {decayFactor} ");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// this happens on first kill
|
// this happens on first kill
|
||||||
if ((distance[0] == 0 && distance[1] == 0) ||
|
if ((distance[0] == 0 && distance[1] == 0) ||
|
||||||
deltaTime == 0 ||
|
deltaTime == 0 ||
|
||||||
|
@ -8,6 +8,7 @@ using SharedLibraryCore.Objects;
|
|||||||
using IW4MAdmin.Plugins.Stats.Models;
|
using IW4MAdmin.Plugins.Stats.Models;
|
||||||
using SharedLibraryCore.Database;
|
using SharedLibraryCore.Database;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||||
{
|
{
|
||||||
@ -34,7 +35,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
join alias in db.Aliases
|
join alias in db.Aliases
|
||||||
on client.CurrentAliasId equals alias.AliasId
|
on client.CurrentAliasId equals alias.AliasId
|
||||||
where stats.ServerId == serverId
|
where stats.ServerId == serverId
|
||||||
where client.Level != Player.Permission.Banned
|
where client.Level != EFClient.Permission.Banned
|
||||||
where client.LastConnection >= thirtyDaysAgo
|
where client.LastConnection >= thirtyDaysAgo
|
||||||
orderby stats.Kills descending
|
orderby stats.Kills descending
|
||||||
select new
|
select new
|
||||||
@ -55,7 +56,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
return mostPlayed;
|
return mostPlayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MostPlayed() : base("mostplayed", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_MOSTPLAYED_DESC"], "mp", Player.Permission.User, false) { }
|
public MostPlayed() : base("mostplayed", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_MOSTPLAYED_DESC"], "mp", EFClient.Permission.User, false) { }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
|
@ -8,12 +8,13 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using SharedLibraryCore.Database;
|
using SharedLibraryCore.Database;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||||
{
|
{
|
||||||
public class ResetStats : Command
|
public class ResetStats : Command
|
||||||
{
|
{
|
||||||
public ResetStats() : base("resetstats", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_RESET_DESC"], "rs", Player.Permission.User, false) { }
|
public ResetStats() : base("resetstats", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_RESET_DESC"], "rs", EFClient.Permission.User, false) { }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Services;
|
|||||||
using IW4MAdmin.Plugins.Stats.Models;
|
using IW4MAdmin.Plugins.Stats.Models;
|
||||||
using SharedLibraryCore.Database;
|
using SharedLibraryCore.Database;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||||
{
|
{
|
||||||
@ -33,7 +34,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
on client.CurrentAliasId equals alias.AliasId
|
on client.CurrentAliasId equals alias.AliasId
|
||||||
where stats.ServerId == serverId
|
where stats.ServerId == serverId
|
||||||
where stats.TimePlayed >= Plugin.Config.Configuration().TopPlayersMinPlayTime
|
where stats.TimePlayed >= Plugin.Config.Configuration().TopPlayersMinPlayTime
|
||||||
where client.Level != Player.Permission.Banned
|
where client.Level != EFClient.Permission.Banned
|
||||||
where client.LastConnection >= fifteenDaysAgo
|
where client.LastConnection >= fifteenDaysAgo
|
||||||
orderby stats.Performance descending
|
orderby stats.Performance descending
|
||||||
select new
|
select new
|
||||||
@ -66,7 +67,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
return topStatsText;
|
return topStatsText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TopStats() : base("topstats", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_TOP_DESC"], "ts", Player.Permission.User, false) { }
|
public TopStats() : base("topstats", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_TOP_DESC"], "ts", EFClient.Permission.User, false) { }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
|
@ -10,12 +10,13 @@ using System.Threading.Tasks;
|
|||||||
using SharedLibraryCore.Database;
|
using SharedLibraryCore.Database;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using IW4MAdmin.Plugins.Stats.Helpers;
|
using IW4MAdmin.Plugins.Stats.Helpers;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||||
{
|
{
|
||||||
public class CViewStats : Command
|
public class CViewStats : Command
|
||||||
{
|
{
|
||||||
public CViewStats() : base("stats", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_VIEW_DESC"], "xlrstats", Player.Permission.User, false, new CommandArgument[]
|
public CViewStats() : base("stats", Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_VIEW_DESC"], "xlrstats", EFClient.Permission.User, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
|
@ -1,23 +1,21 @@
|
|||||||
using System;
|
using IW4MAdmin.Plugins.Stats.Cheat;
|
||||||
using System.Collections.Concurrent;
|
using IW4MAdmin.Plugins.Stats.Models;
|
||||||
using System.Collections.Generic;
|
using IW4MAdmin.Plugins.Stats.Web.Dtos;
|
||||||
using System.Linq;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Helpers;
|
using SharedLibraryCore.Helpers;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using SharedLibraryCore.Commands;
|
using System;
|
||||||
using IW4MAdmin.Plugins.Stats.Models;
|
using System.Collections.Concurrent;
|
||||||
using System.Text.RegularExpressions;
|
using System.Collections.Generic;
|
||||||
using IW4MAdmin.Plugins.Stats.Web.Dtos;
|
using System.Linq;
|
||||||
using SharedLibraryCore.Database;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using SharedLibraryCore.Database.Models;
|
|
||||||
using SharedLibraryCore.Services;
|
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats.Helpers
|
namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||||
{
|
{
|
||||||
@ -40,14 +38,17 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
OnProcessingSensitive = new SemaphoreSlim(1, 1);
|
OnProcessingSensitive = new SemaphoreSlim(1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EFClientStatistics GetClientStats(int clientId, int serverId) => Servers[serverId].PlayerStats[clientId];
|
public EFClientStatistics GetClientStats(int clientId, int serverId)
|
||||||
|
{
|
||||||
|
return Servers[serverId].PlayerStats[clientId];
|
||||||
|
}
|
||||||
|
|
||||||
public static Expression<Func<EFRating, bool>> GetRankingFunc(int? serverId = null)
|
public static Expression<Func<EFRating, bool>> GetRankingFunc(int? serverId = null)
|
||||||
{
|
{
|
||||||
var fifteenDaysAgo = DateTime.UtcNow.AddDays(-15);
|
var fifteenDaysAgo = DateTime.UtcNow.AddDays(-15);
|
||||||
return (r) => r.ServerId == serverId &&
|
return (r) => r.ServerId == serverId &&
|
||||||
r.When > fifteenDaysAgo &&
|
r.When > fifteenDaysAgo &&
|
||||||
r.RatingHistory.Client.Level != Player.Permission.Banned &&
|
r.RatingHistory.Client.Level != EFClient.Permission.Banned &&
|
||||||
r.Newest &&
|
r.Newest &&
|
||||||
r.ActivityAmount >= Plugin.Config.Configuration().TopPlayersMinPlayTime;
|
r.ActivityAmount >= Plugin.Config.Configuration().TopPlayersMinPlayTime;
|
||||||
}
|
}
|
||||||
@ -235,7 +236,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pl">Player to add/retrieve stats for</param>
|
/// <param name="pl">Player to add/retrieve stats for</param>
|
||||||
/// <returns>EFClientStatistic of specified player</returns>
|
/// <returns>EFClientStatistic of specified player</returns>
|
||||||
public async Task<EFClientStatistics> AddPlayer(Player pl)
|
public async Task<EFClientStatistics> AddPlayer(EFClient pl)
|
||||||
{
|
{
|
||||||
await OnProcessingSensitive.WaitAsync();
|
await OnProcessingSensitive.WaitAsync();
|
||||||
|
|
||||||
@ -373,7 +374,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pl">Disconnecting client</param>
|
/// <param name="pl">Disconnecting client</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task RemovePlayer(Player pl)
|
public async Task RemovePlayer(EFClient pl)
|
||||||
{
|
{
|
||||||
Log.WriteInfo($"Removing {pl} from stats");
|
Log.WriteInfo($"Removing {pl} from stats");
|
||||||
|
|
||||||
@ -432,7 +433,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
/// Process stats for kill event
|
/// Process stats for kill event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task AddScriptHit(bool isDamage, DateTime time, Player attacker, Player victim, int serverId, string map, string hitLoc, string type,
|
public async Task AddScriptHit(bool isDamage, DateTime time, EFClient attacker, EFClient victim, int serverId, string map, string hitLoc, string type,
|
||||||
string damage, string weapon, string killOrigin, string deathOrigin, string viewAngles, string offset, string isKillstreakKill, string Ads,
|
string damage, string weapon, string killOrigin, string deathOrigin, string viewAngles, string offset, string isKillstreakKill, string Ads,
|
||||||
string fraction, string visibilityPercentage, string snapAngles)
|
string fraction, string visibilityPercentage, string snapAngles)
|
||||||
{
|
{
|
||||||
@ -548,7 +549,22 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
|
|
||||||
if (Plugin.Config.Configuration().EnableAntiCheat)
|
if (Plugin.Config.Configuration().EnableAntiCheat)
|
||||||
{
|
{
|
||||||
ApplyPenalty(clientDetection.ProcessHit(hit, isDamage), clientDetection, attacker, ctx);
|
if (clientDetection.QueuedHits.Count > Detection.QUEUE_COUNT)
|
||||||
|
{
|
||||||
|
while (clientDetection.QueuedHits.Count > 0)
|
||||||
|
{
|
||||||
|
clientDetection.QueuedHits = clientDetection.QueuedHits.OrderBy(_hits => _hits.TimeOffset).ToList();
|
||||||
|
var oldestHit = clientDetection.QueuedHits.First();
|
||||||
|
clientDetection.QueuedHits.RemoveAt(0);
|
||||||
|
ApplyPenalty(clientDetection.ProcessHit(oldestHit, isDamage), clientDetection, attacker, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clientDetection.QueuedHits.Add(hit);
|
||||||
|
}
|
||||||
|
|
||||||
ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx);
|
ApplyPenalty(clientDetection.ProcessTotalRatio(clientStats), clientDetection, attacker, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,16 +583,16 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyPenalty(Cheat.DetectionPenaltyResult penalty, Cheat.Detection clientDetection, Player attacker, DatabaseContext ctx)
|
void ApplyPenalty(Cheat.DetectionPenaltyResult penalty, Cheat.Detection clientDetection, EFClient attacker, DatabaseContext ctx)
|
||||||
{
|
{
|
||||||
switch (penalty.ClientPenalty)
|
switch (penalty.ClientPenalty)
|
||||||
{
|
{
|
||||||
case Penalty.PenaltyType.Ban:
|
case Penalty.PenaltyType.Ban:
|
||||||
if (attacker.Level == Player.Permission.Banned)
|
if (attacker.Level == EFClient.Permission.Banned)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], new Player()
|
attacker.Ban(Utilities.CurrentLocalization.LocalizationIndex["PLUGIN_STATS_CHEAT_DETECTED"], new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1,
|
ClientId = 1,
|
||||||
AdministeredPenalties = new List<EFPenalty>()
|
AdministeredPenalties = new List<EFPenalty>()
|
||||||
@ -588,7 +604,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
$"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}",
|
$"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Level = Player.Permission.Console,
|
Level = EFClient.Permission.Console,
|
||||||
CurrentServer = attacker.CurrentServer
|
CurrentServer = attacker.CurrentServer
|
||||||
});
|
});
|
||||||
if (clientDetection.Tracker.HasChanges)
|
if (clientDetection.Tracker.HasChanges)
|
||||||
@ -597,7 +613,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Penalty.PenaltyType.Flag:
|
case Penalty.PenaltyType.Flag:
|
||||||
if (attacker.Level != Player.Permission.User)
|
if (attacker.Level != EFClient.Permission.User)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -606,10 +622,10 @@ 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}";
|
||||||
|
|
||||||
attacker.Flag(flagReason, new Player()
|
attacker.Flag(flagReason, new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1,
|
ClientId = 1,
|
||||||
Level = Player.Permission.Console,
|
Level = EFClient.Permission.Console,
|
||||||
CurrentServer = attacker.CurrentServer,
|
CurrentServer = attacker.CurrentServer,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -677,7 +693,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddStandardKill(Player attacker, Player victim)
|
public async Task AddStandardKill(EFClient attacker, EFClient victim)
|
||||||
{
|
{
|
||||||
int serverId = attacker.CurrentServer.GetHashCode();
|
int serverId = attacker.CurrentServer.GetHashCode();
|
||||||
|
|
||||||
@ -712,10 +728,14 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
|
|
||||||
// this happens when the round has changed
|
// this happens when the round has changed
|
||||||
if (attackerStats.SessionScore == 0)
|
if (attackerStats.SessionScore == 0)
|
||||||
|
{
|
||||||
attackerStats.LastScore = 0;
|
attackerStats.LastScore = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (victimStats.SessionScore == 0)
|
if (victimStats.SessionScore == 0)
|
||||||
|
{
|
||||||
victimStats.LastScore = 0;
|
victimStats.LastScore = 0;
|
||||||
|
}
|
||||||
|
|
||||||
attackerStats.SessionScore = attacker.Score;
|
attackerStats.SessionScore = attacker.Score;
|
||||||
victimStats.SessionScore = victim.Score;
|
victimStats.SessionScore = victim.Score;
|
||||||
@ -780,7 +800,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
/// <param name="client">client to update</param>
|
/// <param name="client">client to update</param>
|
||||||
/// <param name="clientStats">stats of client that is being updated</param>
|
/// <param name="clientStats">stats of client that is being updated</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task UpdateStatHistory(Player client, EFClientStatistics clientStats)
|
private async Task UpdateStatHistory(EFClient client, EFClientStatistics clientStats)
|
||||||
{
|
{
|
||||||
int currentSessionTime = (int)(DateTime.UtcNow - client.LastConnection).TotalSeconds;
|
int currentSessionTime = (int)(DateTime.UtcNow - client.LastConnection).TotalSeconds;
|
||||||
|
|
||||||
@ -1158,7 +1178,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
{
|
{
|
||||||
// the web users can have no account
|
// the web users can have no account
|
||||||
if (clientId < 1)
|
if (clientId < 1)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
using (var ctx = new DatabaseContext(disableTracking: true))
|
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using IW4MAdmin.Application;
|
using IW4MAdmin.Application;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Commands;
|
using SharedLibraryCore.Commands;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -25,7 +26,7 @@ namespace Tests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void SetAdditionalPropertyShouldSucceed()
|
public void SetAdditionalPropertyShouldSucceed()
|
||||||
{
|
{
|
||||||
var client = new Player();
|
var client = new EFClient();
|
||||||
int newProp = 5;
|
int newProp = 5;
|
||||||
client.SetAdditionalProperty("NewProp", newProp);
|
client.SetAdditionalProperty("NewProp", newProp);
|
||||||
}
|
}
|
||||||
@ -33,7 +34,7 @@ namespace Tests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void GetAdditionalPropertyShouldSucceed()
|
public void GetAdditionalPropertyShouldSucceed()
|
||||||
{
|
{
|
||||||
var client = new Player();
|
var client = new EFClient();
|
||||||
int newProp = 5;
|
int newProp = 5;
|
||||||
client.SetAdditionalProperty("NewProp", newProp);
|
client.SetAdditionalProperty("NewProp", newProp);
|
||||||
|
|
||||||
@ -48,11 +49,11 @@ namespace Tests
|
|||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
|
||||||
|
|
||||||
Assert.False(client == null, "no client found to warn");
|
Assert.False(client == null, "no client found to warn");
|
||||||
|
|
||||||
var warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
var warnEvent = client.Warn("test warn", new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
warnEvent.OnProcessed.Wait();
|
warnEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
Assert.True((client.Warnings == 1 ||
|
Assert.True((client.Warnings == 1 ||
|
||||||
@ -60,19 +61,19 @@ namespace Tests
|
|||||||
Manager.GetPenaltyService().GetClientPenaltiesAsync(client.ClientId).Result.Count(p => p.Type == Penalty.PenaltyType.Warning) == 1,
|
Manager.GetPenaltyService().GetClientPenaltiesAsync(client.ClientId).Result.Count(p => p.Type == Penalty.PenaltyType.Warning) == 1,
|
||||||
"warning did not get applied");
|
"warning did not get applied");
|
||||||
|
|
||||||
warnEvent = client.Warn("test warn", new Player() { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
warnEvent = client.Warn("test warn", new EFClient() { ClientId = 1, Level = EFClient.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
warnEvent.OnProcessed.Wait();
|
warnEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
Assert.True(warnEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
Assert.True(warnEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
||||||
client.Warnings == 1, "warning was applied without proper permissions");
|
client.Warnings == 1, "warning was applied without proper permissions");
|
||||||
|
|
||||||
// warn clear
|
// warn clear
|
||||||
var warnClearEvent = client.WarnClear(new Player { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
var warnClearEvent = client.WarnClear(new EFClient { ClientId = 1, Level = EFClient.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
|
|
||||||
Assert.True(warnClearEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
Assert.True(warnClearEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
||||||
client.Warnings == 1, "warning was removed without proper permissions");
|
client.Warnings == 1, "warning was removed without proper permissions");
|
||||||
|
|
||||||
warnClearEvent = client.WarnClear(new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
warnClearEvent = client.WarnClear(new EFClient { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
|
|
||||||
Assert.True(!warnClearEvent.Failed && client.Warnings == 0, "warning was not cleared");
|
Assert.True(!warnClearEvent.Failed && client.Warnings == 0, "warning was not cleared");
|
||||||
}
|
}
|
||||||
@ -85,11 +86,11 @@ namespace Tests
|
|||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
|
||||||
Assert.False(client == null, "no client found to report");
|
Assert.False(client == null, "no client found to report");
|
||||||
|
|
||||||
// fail
|
// fail
|
||||||
var player = new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer };
|
var player = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer };
|
||||||
player.SetAdditionalProperty("_reportCount", 3);
|
player.SetAdditionalProperty("_reportCount", 3);
|
||||||
var reportEvent = client.Report("test report", player);
|
var reportEvent = client.Report("test report", player);
|
||||||
reportEvent.OnProcessed.Wait(TestTimeout);
|
reportEvent.OnProcessed.Wait(TestTimeout);
|
||||||
@ -98,14 +99,14 @@ namespace Tests
|
|||||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 0, $"too many reports were applied [{reportEvent.FailReason.ToString()}]");
|
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 0, $"too many reports were applied [{reportEvent.FailReason.ToString()}]");
|
||||||
|
|
||||||
// succeed
|
// succeed
|
||||||
reportEvent = client.Report("test report", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
reportEvent = client.Report("test report", new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
reportEvent.OnProcessed.Wait(TestTimeout);
|
reportEvent.OnProcessed.Wait(TestTimeout);
|
||||||
|
|
||||||
Assert.True(!reportEvent.Failed &&
|
Assert.True(!reportEvent.Failed &&
|
||||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was not applied [{reportEvent.FailReason.ToString()}]");
|
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was not applied [{reportEvent.FailReason.ToString()}]");
|
||||||
|
|
||||||
// fail
|
// fail
|
||||||
reportEvent = client.Report("test report", new Player() { ClientId = 1, NetworkId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
reportEvent = client.Report("test report", new EFClient() { ClientId = 1, NetworkId = 1, Level = EFClient.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
|
|
||||||
Assert.True(reportEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
Assert.True(reportEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
||||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1,
|
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1,
|
||||||
@ -118,7 +119,7 @@ namespace Tests
|
|||||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was applied to self");
|
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was applied to self");
|
||||||
|
|
||||||
// fail
|
// fail
|
||||||
reportEvent = client.Report("test report", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
reportEvent = client.Report("test report", new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
|
|
||||||
Assert.True(reportEvent.FailReason == GameEvent.EventFailReason.Exception &&
|
Assert.True(reportEvent.FailReason == GameEvent.EventFailReason.Exception &&
|
||||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"duplicate report was applied");
|
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"duplicate report was applied");
|
||||||
@ -132,42 +133,42 @@ namespace Tests
|
|||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
|
||||||
Assert.False(client == null, "no client found to flag");
|
Assert.False(client == null, "no client found to flag");
|
||||||
|
|
||||||
var flagEvent = client.Flag("test flag", new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
var flagEvent = client.Flag("test flag", new EFClient { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
flagEvent.OnProcessed.Wait();
|
flagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
// succeed
|
// succeed
|
||||||
Assert.True(!flagEvent.Failed &&
|
Assert.True(!flagEvent.Failed &&
|
||||||
client.Level == Player.Permission.Flagged, $"player is not flagged [{flagEvent.FailReason.ToString()}]");
|
client.Level == EFClient.Permission.Flagged, $"player is not flagged [{flagEvent.FailReason.ToString()}]");
|
||||||
Assert.False(client.ReceivedPenalties.FirstOrDefault(p => p.Offense == "test flag") == null, "flag was not applied");
|
Assert.False(client.ReceivedPenalties.FirstOrDefault(p => p.Offense == "test flag") == null, "flag was not applied");
|
||||||
|
|
||||||
flagEvent = client.Flag("test flag", new Player { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
flagEvent = client.Flag("test flag", new EFClient { ClientId = 1, Level = EFClient.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
flagEvent.OnProcessed.Wait();
|
flagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
// fail
|
// fail
|
||||||
Assert.True(client.ReceivedPenalties.Count == 1, "flag was applied without permisions");
|
Assert.True(client.ReceivedPenalties.Count == 1, "flag was applied without permisions");
|
||||||
|
|
||||||
flagEvent = client.Flag("test flag", new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
flagEvent = client.Flag("test flag", new EFClient { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
flagEvent.OnProcessed.Wait();
|
flagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
// fail
|
// fail
|
||||||
Assert.True(client.ReceivedPenalties.Count == 1, "duplicate flag was applied");
|
Assert.True(client.ReceivedPenalties.Count == 1, "duplicate flag was applied");
|
||||||
|
|
||||||
var unflagEvent = client.Unflag("test unflag", new Player { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
var unflagEvent = client.Unflag("test unflag", new EFClient { ClientId = 1, Level = EFClient.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
unflagEvent.OnProcessed.Wait();
|
unflagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
// fail
|
// fail
|
||||||
Assert.False(client.Level == Player.Permission.User, "user was unflagged without permissions");
|
Assert.False(client.Level == EFClient.Permission.User, "user was unflagged without permissions");
|
||||||
|
|
||||||
unflagEvent = client.Unflag("test unflag", new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
unflagEvent = client.Unflag("test unflag", new EFClient { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
unflagEvent.OnProcessed.Wait();
|
unflagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
// succeed
|
// succeed
|
||||||
Assert.True(client.Level == Player.Permission.User, "user was not unflagged");
|
Assert.True(client.Level == EFClient.Permission.User, "user was not unflagged");
|
||||||
|
|
||||||
unflagEvent = client.Unflag("test unflag", new Player { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
unflagEvent = client.Unflag("test unflag", new EFClient { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
unflagEvent.OnProcessed.Wait();
|
unflagEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
// succeed
|
// succeed
|
||||||
@ -182,18 +183,18 @@ namespace Tests
|
|||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
|
||||||
Assert.False(client == null, "no client found to kick");
|
Assert.False(client == null, "no client found to kick");
|
||||||
|
|
||||||
var kickEvent = client.Kick("test kick", new Player() { ClientId = 1, Level = Player.Permission.Banned, CurrentServer = client.CurrentServer });
|
var kickEvent = client.Kick("test kick", new EFClient() { ClientId = 1, Level = EFClient.Permission.Banned, CurrentServer = client.CurrentServer });
|
||||||
kickEvent.OnProcessed.Wait();
|
kickEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
Assert.True(kickEvent.FailReason == GameEvent.EventFailReason.Permission, "client was kicked without permission");
|
Assert.True(kickEvent.FailReason == GameEvent.EventFailReason.Permission, "client was kicked without permission");
|
||||||
|
|
||||||
kickEvent = client.Kick("test kick", new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer });
|
kickEvent = client.Kick("test kick", new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer });
|
||||||
kickEvent.OnProcessed.Wait();
|
kickEvent.OnProcessed.Wait();
|
||||||
|
|
||||||
Assert.True(Manager.Servers.First().GetPlayersAsList().FirstOrDefault(c => c.NetworkId == client.NetworkId) == null, "client was not kicked");
|
Assert.True(Manager.Servers.First().GetClientsAsList().FirstOrDefault(c => c.NetworkId == client.NetworkId) == null, "client was not kicked");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@ -204,13 +205,13 @@ namespace Tests
|
|||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
|
||||||
Assert.False(client == null, "no client found to tempban");
|
Assert.False(client == null, "no client found to tempban");
|
||||||
|
|
||||||
var tbCommand = new CTempBan();
|
var tbCommand = new CTempBan();
|
||||||
tbCommand.ExecuteAsync(new GameEvent()
|
tbCommand.ExecuteAsync(new GameEvent()
|
||||||
{
|
{
|
||||||
Origin = new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer },
|
Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer },
|
||||||
Target = client,
|
Target = client,
|
||||||
Data = "5days test tempban",
|
Data = "5days test tempban",
|
||||||
Type = GameEvent.EventType.Command,
|
Type = GameEvent.EventType.Command,
|
||||||
@ -229,13 +230,13 @@ namespace Tests
|
|||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
var client = Manager.Servers.First().GetPlayersAsList().FirstOrDefault();
|
var client = Manager.Servers.First().GetClientsAsList().FirstOrDefault();
|
||||||
Assert.False(client == null, "no client found to ban");
|
Assert.False(client == null, "no client found to ban");
|
||||||
|
|
||||||
var banCommand = new CBan();
|
var banCommand = new CBan();
|
||||||
banCommand.ExecuteAsync(new GameEvent()
|
banCommand.ExecuteAsync(new GameEvent()
|
||||||
{
|
{
|
||||||
Origin = new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer },
|
Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer },
|
||||||
Target = client,
|
Target = client,
|
||||||
Data = "test ban",
|
Data = "test ban",
|
||||||
Type = GameEvent.EventType.Command,
|
Type = GameEvent.EventType.Command,
|
||||||
@ -248,8 +249,8 @@ namespace Tests
|
|||||||
var unbanCommand = new CUnban();
|
var unbanCommand = new CUnban();
|
||||||
unbanCommand.ExecuteAsync(new GameEvent()
|
unbanCommand.ExecuteAsync(new GameEvent()
|
||||||
{
|
{
|
||||||
Origin = new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer },
|
Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer },
|
||||||
Target = Manager.GetClientService().Find(c => c.NetworkId == client.NetworkId).Result.First().AsPlayer(),
|
Target = Manager.GetClientService().Find(c => c.NetworkId == client.NetworkId).Result.First().AsEFClient(),
|
||||||
Data = "test unban",
|
Data = "test unban",
|
||||||
Type = GameEvent.EventType.Command,
|
Type = GameEvent.EventType.Command,
|
||||||
Owner = client.CurrentServer
|
Owner = client.CurrentServer
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using IW4MAdmin.Application;
|
using IW4MAdmin.Application;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
@ -53,7 +54,7 @@ namespace Tests
|
|||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Join,
|
Type = GameEvent.EventType.Join,
|
||||||
Origin = new Player()
|
Origin = new EFClient()
|
||||||
{
|
{
|
||||||
Name = $"Player{i}",
|
Name = $"Player{i}",
|
||||||
NetworkId = i,
|
NetworkId = i,
|
||||||
@ -78,7 +79,7 @@ namespace Tests
|
|||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Disconnect,
|
Type = GameEvent.EventType.Disconnect,
|
||||||
Origin = new Player()
|
Origin = new EFClient()
|
||||||
{
|
{
|
||||||
Name = $"Player{i}",
|
Name = $"Player{i}",
|
||||||
NetworkId = i,
|
NetworkId = i,
|
||||||
@ -113,7 +114,7 @@ namespace Tests
|
|||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Connect,
|
Type = GameEvent.EventType.Connect,
|
||||||
Origin = new Player()
|
Origin = new EFClient()
|
||||||
{
|
{
|
||||||
Name = $"Player{i}",
|
Name = $"Player{i}",
|
||||||
NetworkId = i,
|
NetworkId = i,
|
||||||
@ -134,7 +135,7 @@ namespace Tests
|
|||||||
waiters.Dequeue().OnProcessed.Wait();
|
waiters.Dequeue().OnProcessed.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
int actualClientNum = server.GetPlayersAsList().Count(p => p.State == Player.ClientState.Connected);
|
int actualClientNum = server.GetClientsAsList().Count(p => p.State == EFClient.ClientState.Connected);
|
||||||
Assert.True(actualClientNum == clientNum, $"client connected states don't match [{actualClientNum}:{clientNum}");
|
Assert.True(actualClientNum == clientNum, $"client connected states don't match [{actualClientNum}:{clientNum}");
|
||||||
|
|
||||||
for (int i = clientIndexStart; i < clientNum + clientIndexStart; i++)
|
for (int i = clientIndexStart; i < clientNum + clientIndexStart; i++)
|
||||||
@ -142,7 +143,7 @@ namespace Tests
|
|||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Disconnect,
|
Type = GameEvent.EventType.Disconnect,
|
||||||
Origin = new Player()
|
Origin = new EFClient()
|
||||||
{
|
{
|
||||||
Name = $"Player{i}",
|
Name = $"Player{i}",
|
||||||
NetworkId = i,
|
NetworkId = i,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using IW4MAdmin.Application;
|
using IW4MAdmin.Application;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
@ -21,7 +22,7 @@ namespace Tests
|
|||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Connect,
|
Type = GameEvent.EventType.Connect,
|
||||||
Origin = new Player()
|
Origin = new EFClient()
|
||||||
{
|
{
|
||||||
Name = $"Player1",
|
Name = $"Player1",
|
||||||
NetworkId = 1,
|
NetworkId = 1,
|
||||||
@ -33,7 +34,7 @@ namespace Tests
|
|||||||
Manager.GetEventHandler().AddEvent(e);
|
Manager.GetEventHandler().AddEvent(e);
|
||||||
e.OnProcessed.Wait();
|
e.OnProcessed.Wait();
|
||||||
|
|
||||||
var client = Manager.GetServers()[0].Players[0];
|
var client = Manager.GetServers()[0].Clients[0];
|
||||||
|
|
||||||
e = new GameEvent()
|
e = new GameEvent()
|
||||||
{
|
{
|
||||||
|
@ -13,12 +13,13 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using static SharedLibraryCore.Database.Models.EFClient;
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Welcome
|
namespace IW4MAdmin.Plugins.Welcome
|
||||||
{
|
{
|
||||||
public class Plugin : IPlugin
|
public class Plugin : IPlugin
|
||||||
{
|
{
|
||||||
String TimesConnected(Player P)
|
String TimesConnected(EFClient P)
|
||||||
{
|
{
|
||||||
int connection = P.Connections;
|
int connection = P.Connections;
|
||||||
String Prefix = String.Empty;
|
String Prefix = String.Empty;
|
||||||
@ -85,13 +86,13 @@ namespace IW4MAdmin.Plugins.Welcome
|
|||||||
{
|
{
|
||||||
if (E.Type == GameEvent.EventType.Connect)
|
if (E.Type == GameEvent.EventType.Connect)
|
||||||
{
|
{
|
||||||
Player newPlayer = E.Origin;
|
EFClient newPlayer = E.Origin;
|
||||||
if (newPlayer.Level >= Player.Permission.Trusted && !E.Origin.Masked)
|
if (newPlayer.Level >= Permission.Trusted && !E.Origin.Masked)
|
||||||
E.Owner.Broadcast(await ProcessAnnouncement(Config.Configuration().PrivilegedAnnouncementMessage, newPlayer));
|
E.Owner.Broadcast(await ProcessAnnouncement(Config.Configuration().PrivilegedAnnouncementMessage, newPlayer));
|
||||||
|
|
||||||
newPlayer.Tell(await ProcessAnnouncement(Config.Configuration().UserWelcomeMessage, newPlayer));
|
newPlayer.Tell(await ProcessAnnouncement(Config.Configuration().UserWelcomeMessage, newPlayer));
|
||||||
|
|
||||||
if (newPlayer.Level == Player.Permission.Flagged)
|
if (newPlayer.Level == Permission.Flagged)
|
||||||
{
|
{
|
||||||
string penaltyReason;
|
string penaltyReason;
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ namespace IW4MAdmin.Plugins.Welcome
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ProcessAnnouncement(string msg, Player joining)
|
private async Task<string> ProcessAnnouncement(string msg, EFClient joining)
|
||||||
{
|
{
|
||||||
msg = msg.Replace("{{ClientName}}", joining.Name);
|
msg = msg.Replace("{{ClientName}}", joining.Name);
|
||||||
msg = msg.Replace("{{ClientLevel}}", Utilities.ConvertLevelToColor(joining.Level, joining.ClientPermission.Name));
|
msg = msg.Replace("{{ClientLevel}}", Utilities.ConvertLevelToColor(joining.Level, joining.ClientPermission.Name));
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
dotnet publish WebfrontCore/WebfrontCore.csproj -c Prerelease -o C:\Projects\IW4M-Admin\Publish\WindowsPrerelease
|
dotnet publish WebfrontCore/WebfrontCore.csproj -c Prerelease -o X:\IW4MAdmin\Publish\WindowsPrerelease
|
||||||
dotnet publish Application/Application.csproj -c Prerelease -o C:\Projects\IW4M-Admin\Publish\WindowsPrerelease
|
dotnet publish Application/Application.csproj -c Prerelease -o X:\IW4MAdmin\Publish\WindowsPrerelease
|
||||||
dotnet publish GameLogServer/GameLogServer.pyproj -c Release -o C:\Projects\IW4M-Admin\Publish\WindowsPrerelease\GameLogServer
|
dotnet publish GameLogServer/GameLogServer.pyproj -c Release -o X:\IW4MAdmin\Publish\WindowsPrerelease\GameLogServer
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat"
|
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat"
|
||||||
msbuild GameLogServer/GameLogServer.pyproj /p:PublishProfile=FolderProfile /p:DeployOnBuild=true /p:PublishProfileRootFolder=C:\Projects\IW4M-Admin\GameLogServer\
|
msbuild GameLogServer/GameLogServer.pyproj /p:PublishProfile=FolderProfile /p:DeployOnBuild=true /p:PublishProfileRootFolder=X:\IW4MAdmin\GameLogServer\
|
||||||
msbuild DiscordWebhook/DiscordWebhook.pyproj /p:PublishProfile=FolderProfile /p:DeployOnBuild=true /p:PublishProfileRootFolder=C:\Projects\IW4M-Admin\DiscordWebhook\
|
msbuild DiscordWebhook/DiscordWebhook.pyproj /p:PublishProfile=FolderProfile /p:DeployOnBuild=true /p:PublishProfileRootFolder=X:\IW4MAdmin\DiscordWebhook\
|
||||||
cd "C:\Projects\IW4M-Admin\DEPLOY\"
|
cd "X:\IW4MAdmin\DEPLOY\"
|
||||||
PowerShell ".\upload_prerelease.ps1"
|
PowerShell ".\upload_prerelease.ps1"
|
@ -1,8 +1,8 @@
|
|||||||
dotnet publish WebfrontCore/WebfrontCore.csproj -c Release -o C:\Projects\IW4M-Admin\Publish\Windows
|
dotnet publish WebfrontCore/WebfrontCore.csproj -c Release -o X:\IW4MAdmin\Publish\Windows
|
||||||
dotnet publish Application/Application.csproj -c Release -o C:\Projects\IW4M-Admin\Publish\Windows
|
dotnet publish Application/Application.csproj -c Release -o X:\IW4MAdmin\Publish\Windows
|
||||||
dotnet publish GameLogServer/GameLogServer.pyproj -c Release -o C:\Projects\IW4M-Admin\Publish\Windows\GameLogServer
|
dotnet publish GameLogServer/GameLogServer.pyproj -c Release -o X:\IW4MAdmin\Publish\Windows\GameLogServer
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat"
|
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\VsDevCmd.bat"
|
||||||
msbuild GameLogServer/GameLogServer.pyproj /p:PublishProfile=Stable /p:DeployOnBuild=true /p:PublishProfileRootFolder=C:\Projects\IW4M-Admin\GameLogServer\
|
msbuild GameLogServer/GameLogServer.pyproj /p:PublishProfile=Stable /p:DeployOnBuild=true /p:PublishProfileRootFolder=X:\IW4MAdmin\GameLogServer\
|
||||||
msbuild DiscordWebhook/DiscordWebhook.pyproj /p:PublishProfile=Stable /p:DeployOnBuild=true /p:PublishProfileRootFolder=C:\Projects\IW4M-Admin\DiscordWebhook\
|
msbuild DiscordWebhook/DiscordWebhook.pyproj /p:PublishProfile=Stable /p:DeployOnBuild=true /p:PublishProfileRootFolder=X:\IW4MAdmin\DiscordWebhook\
|
||||||
cd "C:\Projects\IW4M-Admin\DEPLOY\"
|
cd "X:\IW4MAdmin\DEPLOY\"
|
||||||
PowerShell ".\upload_release.ps1"
|
PowerShell ".\upload_release.ps1"
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
|
|
||||||
namespace SharedLibraryCore
|
namespace SharedLibraryCore
|
||||||
@ -14,7 +14,7 @@ namespace SharedLibraryCore
|
|||||||
|
|
||||||
public abstract class Command
|
public abstract class Command
|
||||||
{
|
{
|
||||||
public Command(String commandName, String commandDescription, String commandAlias, Player.Permission requiredPermission, bool requiresTarget, CommandArgument[] param = null)
|
public Command(String commandName, String commandDescription, String commandAlias, EFClient.Permission requiredPermission, bool requiresTarget, CommandArgument[] param = null)
|
||||||
{
|
{
|
||||||
Name = commandName;
|
Name = commandName;
|
||||||
Description = commandDescription;
|
Description = commandDescription;
|
||||||
@ -33,7 +33,7 @@ namespace SharedLibraryCore
|
|||||||
public String Alias { get; private set; }
|
public String Alias { get; private set; }
|
||||||
public int RequiredArgumentCount => Arguments.Count(c => c.Required);
|
public int RequiredArgumentCount => Arguments.Count(c => c.Required);
|
||||||
public bool RequiresTarget { get; private set; }
|
public bool RequiresTarget { get; private set; }
|
||||||
public Player.Permission Permission { get; private set; }
|
public EFClient.Permission Permission { get; private set; }
|
||||||
public CommandArgument[] Arguments { get; private set; }
|
public CommandArgument[] Arguments { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using SharedLibraryCore.Exceptions;
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using SharedLibraryCore.Exceptions;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -60,7 +61,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
var found = await Manager.GetClientService().Get(dbID);
|
var found = await Manager.GetClientService().Get(dbID);
|
||||||
if (found != null)
|
if (found != null)
|
||||||
{
|
{
|
||||||
E.Target = found.AsPlayer();
|
E.Target = found;
|
||||||
E.Target.CurrentServer = E.Owner;
|
E.Target.CurrentServer = E.Owner;
|
||||||
E.Data = String.Join(" ", Args.Skip(1));
|
E.Data = String.Join(" ", Args.Skip(1));
|
||||||
}
|
}
|
||||||
@ -68,14 +69,14 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
else if (Args[0].Length < 3 && cNum > -1 && cNum < E.Owner.MaxClients) // user specifying target by client num
|
else if (Args[0].Length < 3 && cNum > -1 && cNum < E.Owner.MaxClients) // user specifying target by client num
|
||||||
{
|
{
|
||||||
if (E.Owner.Players[cNum] != null)
|
if (E.Owner.Clients[cNum] != null)
|
||||||
{
|
{
|
||||||
E.Target = E.Owner.Players[cNum];
|
E.Target = E.Owner.Clients[cNum];
|
||||||
E.Data = String.Join(" ", Args.Skip(1));
|
E.Data = String.Join(" ", Args.Skip(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Player> matchingPlayers;
|
List<EFClient> matchingPlayers;
|
||||||
|
|
||||||
if (E.Target == null && C.RequiresTarget) // Find active player including quotes (multiple words)
|
if (E.Target == null && C.RequiresTarget) // Find active player including quotes (multiple words)
|
||||||
{
|
{
|
||||||
|
@ -12,14 +12,13 @@ using System.Security.Cryptography;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using static SharedLibraryCore.RCon.StaticHelpers;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Commands
|
namespace SharedLibraryCore.Commands
|
||||||
{
|
{
|
||||||
public class CQuit : Command
|
public class CQuit : Command
|
||||||
{
|
{
|
||||||
public CQuit() :
|
public CQuit() :
|
||||||
base("quit", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_QUIT_DESC"], "q", Player.Permission.Owner, false)
|
base("quit", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_QUIT_DESC"], "q", EFClient.Permission.Owner, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
@ -31,14 +30,14 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class COwner : Command
|
public class COwner : Command
|
||||||
{
|
{
|
||||||
public COwner() :
|
public COwner() :
|
||||||
base("owner", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_OWNER_DESC"], "iamgod", Player.Permission.User, false)
|
base("owner", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_OWNER_DESC"], "iamgod", EFClient.Permission.User, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
if ((await (E.Owner.Manager.GetClientService() as ClientService).GetOwners()).Count == 0)
|
if ((await (E.Owner.Manager.GetClientService() as ClientService).GetOwners()).Count == 0)
|
||||||
{
|
{
|
||||||
E.Origin.Level = Player.Permission.Owner;
|
E.Origin.Level = EFClient.Permission.Owner;
|
||||||
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_OWNER_SUCCESS"]);
|
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_OWNER_SUCCESS"]);
|
||||||
// so setpassword/login works
|
// so setpassword/login works
|
||||||
E.Owner.Manager.GetPrivilegedClients().Add(E.Origin.ClientId, E.Origin);
|
E.Owner.Manager.GetPrivilegedClients().Add(E.Origin.ClientId, E.Origin);
|
||||||
@ -54,7 +53,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CWarn : Command
|
public class CWarn : Command
|
||||||
{
|
{
|
||||||
public CWarn() :
|
public CWarn() :
|
||||||
base("warn", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_WARN_DESC"], "w", Player.Permission.Trusted, true, new CommandArgument[]
|
base("warn", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_WARN_DESC"], "w", EFClient.Permission.Trusted, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -83,7 +82,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CWarnClear : Command
|
public class CWarnClear : Command
|
||||||
{
|
{
|
||||||
public CWarnClear() :
|
public CWarnClear() :
|
||||||
base("warnclear", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_WARNCLEAR_DESC"], "wc", Player.Permission.Trusted, true, new CommandArgument[]
|
base("warnclear", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_WARNCLEAR_DESC"], "wc", EFClient.Permission.Trusted, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -107,7 +106,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CKick : Command
|
public class CKick : Command
|
||||||
{
|
{
|
||||||
public CKick() :
|
public CKick() :
|
||||||
base("kick", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_KICK_DESC"], "k", Player.Permission.Moderator, true, new CommandArgument[]
|
base("kick", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_KICK_DESC"], "k", EFClient.Permission.Moderator, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -133,7 +132,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CSay : Command
|
public class CSay : Command
|
||||||
{
|
{
|
||||||
public CSay() :
|
public CSay() :
|
||||||
base("say", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SAY_DESC"], "s", Player.Permission.Moderator, false, new CommandArgument[]
|
base("say", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SAY_DESC"], "s", EFClient.Permission.Moderator, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -153,7 +152,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CTempBan : Command
|
public class CTempBan : Command
|
||||||
{
|
{
|
||||||
public CTempBan() :
|
public CTempBan() :
|
||||||
base("tempban", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_TEMPBAN_DESC"], "tb", Player.Permission.Administrator, true, new CommandArgument[]
|
base("tempban", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_TEMPBAN_DESC"], "tb", EFClient.Permission.Administrator, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -201,7 +200,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CBan : Command
|
public class CBan : Command
|
||||||
{
|
{
|
||||||
public CBan() :
|
public CBan() :
|
||||||
base("ban", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BAN_DESC"], "b", Player.Permission.SeniorAdmin, true, new CommandArgument[]
|
base("ban", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BAN_DESC"], "b", EFClient.Permission.SeniorAdmin, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -227,7 +226,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CUnban : Command
|
public class CUnban : Command
|
||||||
{
|
{
|
||||||
public CUnban() :
|
public CUnban() :
|
||||||
base("unban", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UNBAN_DESC"], "ub", Player.Permission.SeniorAdmin, true, new CommandArgument[]
|
base("unban", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UNBAN_DESC"], "ub", EFClient.Permission.SeniorAdmin, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -260,7 +259,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CWhoAmI : Command
|
public class CWhoAmI : Command
|
||||||
{
|
{
|
||||||
public CWhoAmI() :
|
public CWhoAmI() :
|
||||||
base("whoami", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_WHO_DESC"], "who", Player.Permission.User, false)
|
base("whoami", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_WHO_DESC"], "who", EFClient.Permission.User, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
@ -275,27 +274,33 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CList : Command
|
public class CList : Command
|
||||||
{
|
{
|
||||||
public CList() :
|
public CList() :
|
||||||
base("list", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_LIST_DESC"], "l", Player.Permission.Moderator, false)
|
base("list", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_LIST_DESC"], "l", EFClient.Permission.Moderator, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
StringBuilder playerList = new StringBuilder();
|
StringBuilder playerList = new StringBuilder();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < E.Owner.Players.Count; i++)
|
for (int i = 0; i < E.Owner.Clients.Count; i++)
|
||||||
{
|
{
|
||||||
var P = E.Owner.Players[i];
|
var P = E.Owner.Clients[i];
|
||||||
|
|
||||||
if (P == null)
|
if (P == null)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
// todo: fix spacing
|
// todo: fix spacing
|
||||||
// todo: make this better :)
|
// todo: make this better :)
|
||||||
if (P.Masked)
|
if (P.Masked)
|
||||||
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(Player.Permission.User, P.ClientPermission.Name), P.ClientNumber, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - Player.Permission.User.ToString().Length));
|
{
|
||||||
|
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor( EFClient.Permission.User, P.ClientPermission.Name), P.ClientNumber, P.Name, Utilities.GetSpaces( EFClient.Permission.SeniorAdmin.ToString().Length - EFClient.Permission.User.ToString().Length));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(P.Level, P.ClientPermission.Name), P.ClientNumber, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length));
|
{
|
||||||
|
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(P.Level, P.ClientPermission.Name), P.ClientNumber, P.Name, Utilities.GetSpaces( EFClient.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length));
|
||||||
|
}
|
||||||
|
|
||||||
if (count == 2 || E.Owner.GetPlayersAsList().Count == 1)
|
if (count == 2 || E.Owner.GetClientsAsList().Count == 1)
|
||||||
{
|
{
|
||||||
E.Origin.Tell(playerList.ToString());
|
E.Origin.Tell(playerList.ToString());
|
||||||
count = 0;
|
count = 0;
|
||||||
@ -320,7 +325,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CHelp : Command
|
public class CHelp : Command
|
||||||
{
|
{
|
||||||
public CHelp() :
|
public CHelp() :
|
||||||
base("help", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_HELP_DESC"], "h", Player.Permission.User, false, new CommandArgument[]
|
base("help", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_HELP_DESC"], "h", EFClient.Permission.User, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -385,7 +390,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CFastRestart : Command
|
public class CFastRestart : Command
|
||||||
{
|
{
|
||||||
public CFastRestart() :
|
public CFastRestart() :
|
||||||
base("fastrestart", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FASTRESTART_DESC"], "fr", Player.Permission.Moderator, false)
|
base("fastrestart", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FASTRESTART_DESC"], "fr", EFClient.Permission.Moderator, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
@ -401,7 +406,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CMapRotate : Command
|
public class CMapRotate : Command
|
||||||
{
|
{
|
||||||
public CMapRotate() :
|
public CMapRotate() :
|
||||||
base("maprotate", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_MAPROTATE_DESC"], "mr", Player.Permission.Administrator, false)
|
base("maprotate", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_MAPROTATE_DESC"], "mr", EFClient.Permission.Administrator, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
@ -418,7 +423,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CSetLevel : Command
|
public class CSetLevel : Command
|
||||||
{
|
{
|
||||||
public CSetLevel() :
|
public CSetLevel() :
|
||||||
base("setlevel", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_DESC"], "sl", Player.Permission.Moderator, true, new CommandArgument[]
|
base("setlevel", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_DESC"], "sl", EFClient.Permission.Moderator, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -441,17 +446,17 @@ namespace SharedLibraryCore.Commands
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player.Permission oldPerm = E.Target.Level;
|
EFClient.Permission oldPerm = E.Target.Level;
|
||||||
Player.Permission newPerm = Utilities.MatchPermission(E.Data);
|
EFClient.Permission newPerm = Utilities.MatchPermission(E.Data);
|
||||||
|
|
||||||
if (newPerm == Player.Permission.Owner &&
|
if (newPerm == EFClient.Permission.Owner &&
|
||||||
!E.Owner.Manager.GetApplicationSettings().Configuration().EnableMultipleOwners)
|
!E.Owner.Manager.GetApplicationSettings().Configuration().EnableMultipleOwners)
|
||||||
{
|
{
|
||||||
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_OWNER"]);
|
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_OWNER"]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (E.Origin.Level < Player.Permission.Owner &&
|
if (E.Origin.Level < EFClient.Permission.Owner &&
|
||||||
!E.Owner.Manager.GetApplicationSettings().Configuration().EnableSteppedHierarchy)
|
!E.Owner.Manager.GetApplicationSettings().Configuration().EnableSteppedHierarchy)
|
||||||
{
|
{
|
||||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_STEPPEDDISABLED"]} ^5{E.Target.Name}");
|
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_STEPPEDDISABLED"]} ^5{E.Target.Name}");
|
||||||
@ -460,14 +465,14 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
if (newPerm >= E.Origin.Level)
|
if (newPerm >= E.Origin.Level)
|
||||||
{
|
{
|
||||||
if (E.Origin.Level < Player.Permission.Owner)
|
if (E.Origin.Level < EFClient.Permission.Owner)
|
||||||
{
|
{
|
||||||
E.Origin.Tell(string.Format(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_LEVELTOOHIGH"], E.Target.Name, (E.Origin.Level - 1).ToString()));
|
E.Origin.Tell(string.Format(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_LEVELTOOHIGH"], E.Target.Name, (E.Origin.Level - 1).ToString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (newPerm > Player.Permission.Banned)
|
else if (newPerm > EFClient.Permission.Banned)
|
||||||
{
|
{
|
||||||
var ActiveClient = E.Owner.Manager.GetActiveClients()
|
var ActiveClient = E.Owner.Manager.GetActiveClients()
|
||||||
.FirstOrDefault(p => p.NetworkId == E.Target.NetworkId);
|
.FirstOrDefault(p => p.NetworkId == E.Target.NetworkId);
|
||||||
@ -530,7 +535,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CUsage : Command
|
public class CUsage : Command
|
||||||
{
|
{
|
||||||
public CUsage() :
|
public CUsage() :
|
||||||
base("usage", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_USAGE_DESC"], "us", Player.Permission.Moderator, false)
|
base("usage", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_USAGE_DESC"], "us", EFClient.Permission.Moderator, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
@ -543,7 +548,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CUptime : Command
|
public class CUptime : Command
|
||||||
{
|
{
|
||||||
public CUptime() :
|
public CUptime() :
|
||||||
base("uptime", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UPTIME_DESC"], "up", Player.Permission.Moderator, false)
|
base("uptime", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UPTIME_DESC"], "up", EFClient.Permission.Moderator, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
@ -558,13 +563,13 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CListAdmins : Command
|
public class CListAdmins : Command
|
||||||
{
|
{
|
||||||
public CListAdmins() :
|
public CListAdmins() :
|
||||||
base("admins", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_ADMINS_DESC"], "a", Player.Permission.User, false)
|
base("admins", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_ADMINS_DESC"], "a", EFClient.Permission.User, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public static string OnlineAdmins(Server S)
|
public static string OnlineAdmins(Server S)
|
||||||
{
|
{
|
||||||
var onlineAdmins = S.GetPlayersAsList()
|
var onlineAdmins = S.GetClientsAsList()
|
||||||
.Where(p => p.Level > Player.Permission.Flagged)
|
.Where(p => p.Level > EFClient.Permission.Flagged)
|
||||||
.Where(p => !p.Masked)
|
.Where(p => !p.Masked)
|
||||||
.Select(p => $"[^3{Utilities.ConvertLevelToColor(p.Level, p.ClientPermission.Name)}^7] {p.Name}");
|
.Select(p => $"[^3{Utilities.ConvertLevelToColor(p.Level, p.ClientPermission.Name)}^7] {p.Name}");
|
||||||
|
|
||||||
@ -587,7 +592,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CLoadMap : Command
|
public class CLoadMap : Command
|
||||||
{
|
{
|
||||||
public CLoadMap() :
|
public CLoadMap() :
|
||||||
base("map", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_MAP_DESC"], "m", Player.Permission.Administrator, false, new CommandArgument[]
|
base("map", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_MAP_DESC"], "m", EFClient.Permission.Administrator, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -620,7 +625,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CFindPlayer : Command
|
public class CFindPlayer : Command
|
||||||
{
|
{
|
||||||
public CFindPlayer() :
|
public CFindPlayer() :
|
||||||
base("find", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FIND_DESC"], "f", Player.Permission.Administrator, false, new CommandArgument[]
|
base("find", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FIND_DESC"], "f", EFClient.Permission.Administrator, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -664,7 +669,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CListRules : Command
|
public class CListRules : Command
|
||||||
{
|
{
|
||||||
public CListRules() :
|
public CListRules() :
|
||||||
base("rules", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RULES_DESC"], "r", Player.Permission.User, false)
|
base("rules", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RULES_DESC"], "r", EFClient.Permission.User, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
@ -682,7 +687,9 @@ namespace SharedLibraryCore.Commands
|
|||||||
var rules = new List<string>();
|
var rules = new List<string>();
|
||||||
rules.AddRange(E.Owner.Manager.GetApplicationSettings().Configuration().GlobalRules);
|
rules.AddRange(E.Owner.Manager.GetApplicationSettings().Configuration().GlobalRules);
|
||||||
if (E.Owner.ServerConfig.Rules != null)
|
if (E.Owner.ServerConfig.Rules != null)
|
||||||
|
{
|
||||||
rules.AddRange(E.Owner.ServerConfig.Rules);
|
rules.AddRange(E.Owner.ServerConfig.Rules);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (string r in rules)
|
foreach (string r in rules)
|
||||||
{
|
{
|
||||||
@ -697,7 +704,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CPrivateMessage : Command
|
public class CPrivateMessage : Command
|
||||||
{
|
{
|
||||||
public CPrivateMessage() :
|
public CPrivateMessage() :
|
||||||
base("privatemessage", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PM_DESC"], "pm", Player.Permission.User, true, new CommandArgument[]
|
base("privatemessage", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PM_DESC"], "pm", EFClient.Permission.User, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -724,7 +731,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CFlag : Command
|
public class CFlag : Command
|
||||||
{
|
{
|
||||||
public CFlag() :
|
public CFlag() :
|
||||||
base("flag", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FLAG_DESC"], "fp", Player.Permission.Moderator, true, new CommandArgument[]
|
base("flag", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_FLAG_DESC"], "fp", EFClient.Permission.Moderator, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -766,7 +773,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CUnflag : Command
|
public class CUnflag : Command
|
||||||
{
|
{
|
||||||
public CUnflag() :
|
public CUnflag() :
|
||||||
base("unflag", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UNFLAG_DESC"], "uf", Player.Permission.Moderator, true, new CommandArgument[]
|
base("unflag", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_UNFLAG_DESC"], "uf", EFClient.Permission.Moderator, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -804,7 +811,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CReport : Command
|
public class CReport : Command
|
||||||
{
|
{
|
||||||
public CReport() :
|
public CReport() :
|
||||||
base("report", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_REPORT_DESC"], "rep", Player.Permission.User, true, new CommandArgument[]
|
base("report", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_REPORT_DESC"], "rep", EFClient.Permission.User, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -875,7 +882,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CListReports : Command
|
public class CListReports : Command
|
||||||
{
|
{
|
||||||
public CListReports() :
|
public CListReports() :
|
||||||
base("reports", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_REPORTS_DESC"], "reps", Player.Permission.Moderator, false, new CommandArgument[]
|
base("reports", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_REPORTS_DESC"], "reps", EFClient.Permission.Moderator, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -912,7 +919,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CMask : Command
|
public class CMask : Command
|
||||||
{
|
{
|
||||||
public CMask() :
|
public CMask() :
|
||||||
base("mask", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_MASK_DESC"], "hide", Player.Permission.Moderator, false)
|
base("mask", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_MASK_DESC"], "hide", EFClient.Permission.Moderator, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
@ -935,7 +942,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CListBanInfo : Command
|
public class CListBanInfo : Command
|
||||||
{
|
{
|
||||||
public CListBanInfo() :
|
public CListBanInfo() :
|
||||||
base("baninfo", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BANINFO_DESC"], "bi", Player.Permission.Moderator, true, new CommandArgument[]
|
base("baninfo", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_BANINFO_DESC"], "bi", EFClient.Permission.Moderator, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -968,7 +975,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CListAlias : Command
|
public class CListAlias : Command
|
||||||
{
|
{
|
||||||
public CListAlias() :
|
public CListAlias() :
|
||||||
base("alias", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_ALIAS_DESC"], "known", Player.Permission.Moderator, true, new CommandArgument[]
|
base("alias", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_ALIAS_DESC"], "known", EFClient.Permission.Moderator, true, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -1002,7 +1009,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CExecuteRCON : Command
|
public class CExecuteRCON : Command
|
||||||
{
|
{
|
||||||
public CExecuteRCON() :
|
public CExecuteRCON() :
|
||||||
base("rcon", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RCON_DESC"], "rcon", Player.Permission.Owner, false, new CommandArgument[]
|
base("rcon", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RCON_DESC"], "rcon", EFClient.Permission.Owner, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -1016,16 +1023,21 @@ namespace SharedLibraryCore.Commands
|
|||||||
{
|
{
|
||||||
var Response = await E.Owner.ExecuteCommandAsync(E.Data.Trim());
|
var Response = await E.Owner.ExecuteCommandAsync(E.Data.Trim());
|
||||||
foreach (string S in Response)
|
foreach (string S in Response)
|
||||||
|
{
|
||||||
E.Origin.Tell(S.StripColors());
|
E.Origin.Tell(S.StripColors());
|
||||||
|
}
|
||||||
|
|
||||||
if (Response.Length == 0)
|
if (Response.Length == 0)
|
||||||
|
{
|
||||||
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RCON_SUCCESS"]);
|
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RCON_SUCCESS"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CPlugins : Command
|
public class CPlugins : Command
|
||||||
{
|
{
|
||||||
public CPlugins() :
|
public CPlugins() :
|
||||||
base("plugins", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PLUGINS_DESC"], "p", Player.Permission.Administrator, false)
|
base("plugins", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PLUGINS_DESC"], "p", EFClient.Permission.Administrator, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
@ -1042,7 +1054,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
public class CIP : Command
|
public class CIP : Command
|
||||||
{
|
{
|
||||||
public CIP() :
|
public CIP() :
|
||||||
base("getexternalip", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_IP_DESC"], "ip", Player.Permission.User, false)
|
base("getexternalip", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_IP_DESC"], "ip", EFClient.Permission.User, false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
public override Task ExecuteAsync(GameEvent E)
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
@ -1054,7 +1066,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
public class CPruneAdmins : Command
|
public class CPruneAdmins : Command
|
||||||
{
|
{
|
||||||
public CPruneAdmins() : base("prune", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PRUNE_DESC"], "pa", Player.Permission.Owner, false, new CommandArgument[]
|
public CPruneAdmins() : base("prune", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PRUNE_DESC"], "pa", EFClient.Permission.Owner, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -1074,7 +1086,9 @@ namespace SharedLibraryCore.Commands
|
|||||||
{
|
{
|
||||||
inactiveDays = Int32.Parse(E.Data);
|
inactiveDays = Int32.Parse(E.Data);
|
||||||
if (inactiveDays < 1)
|
if (inactiveDays < 1)
|
||||||
|
{
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1091,10 +1105,10 @@ namespace SharedLibraryCore.Commands
|
|||||||
{
|
{
|
||||||
var lastActive = DateTime.UtcNow.AddDays(-inactiveDays);
|
var lastActive = DateTime.UtcNow.AddDays(-inactiveDays);
|
||||||
inactiveUsers = await context.Clients
|
inactiveUsers = await context.Clients
|
||||||
.Where(c => c.Level > Player.Permission.Flagged && c.Level <= Player.Permission.Moderator)
|
.Where(c => c.Level > EFClient.Permission.Flagged && c.Level <= EFClient.Permission.Moderator)
|
||||||
.Where(c => c.LastConnection < lastActive)
|
.Where(c => c.LastConnection < lastActive)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
inactiveUsers.ForEach(c => c.Level = Player.Permission.User);
|
inactiveUsers.ForEach(c => c.Level = EFClient.Permission.User);
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
E.Origin.Tell($"^5{inactiveUsers.Count} ^7{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PRUNE_SUCCESS"]}");
|
E.Origin.Tell($"^5{inactiveUsers.Count} ^7{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PRUNE_SUCCESS"]}");
|
||||||
@ -1103,7 +1117,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
public class CSetPassword : Command
|
public class CSetPassword : Command
|
||||||
{
|
{
|
||||||
public CSetPassword() : base("setpassword", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETPASSWORD_DESC"], "sp", Player.Permission.Moderator, false, new CommandArgument[]
|
public CSetPassword() : base("setpassword", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETPASSWORD_DESC"], "sp", EFClient.Permission.Moderator, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -1137,77 +1151,89 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
public class CKillServer : Command
|
public class CKillServer : Command
|
||||||
{
|
{
|
||||||
public CKillServer() : base("killserver", "kill the game server", "kill", Player.Permission.Administrator, false)
|
public CKillServer() : base("killserver", "kill the game server", "kill", EFClient.Permission.Administrator, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
{
|
{
|
||||||
var gameserverProcesses = System.Diagnostics.Process.GetProcessesByName("iw4x");
|
if (E.Owner.ServerConfig.ManualLogPath != null)
|
||||||
|
|
||||||
System.Diagnostics.Process currentProcess = null;
|
|
||||||
|
|
||||||
foreach (var p in gameserverProcesses)
|
|
||||||
{
|
{
|
||||||
string cmdLine = Utilities.GetCommandLine(p.Id);
|
using (var wc = new WebClient())
|
||||||
|
|
||||||
var regex = Regex.Match(cmdLine, @".*((?:\+set|\+) net_port) +([0-9]+).*");
|
|
||||||
|
|
||||||
if (regex.Success && Int32.Parse(regex.Groups[2].Value) == E.Owner.GetPort())
|
|
||||||
{
|
{
|
||||||
currentProcess = p;
|
E.Owner.RestartRequested = true;
|
||||||
|
var response = await wc.DownloadStringTaskAsync(new Uri($"{E.Owner.ServerConfig.ManualLogPath}/restart"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (currentProcess == null)
|
|
||||||
{
|
|
||||||
E.Origin.Tell("Could not find running/stalled instance of IW4x");
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// attempt to kill it natively
|
var gameserverProcesses = System.Diagnostics.Process.GetProcessesByName("iw4x");
|
||||||
try
|
|
||||||
|
System.Diagnostics.Process currentProcess = null;
|
||||||
|
|
||||||
|
foreach (var p in gameserverProcesses)
|
||||||
{
|
{
|
||||||
if (!E.Owner.Throttled)
|
string cmdLine = Utilities.GetCommandLine(p.Id);
|
||||||
|
|
||||||
|
var regex = Regex.Match(cmdLine, @".*((?:\+set|\+) net_port) +([0-9]+).*");
|
||||||
|
|
||||||
|
if (regex.Success && Int32.Parse(regex.Groups[2].Value) == E.Owner.GetPort())
|
||||||
{
|
{
|
||||||
|
currentProcess = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (currentProcess == null)
|
||||||
|
{
|
||||||
|
E.Origin.Tell("Could not find running/stalled instance of IW4x");
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// attempt to kill it natively
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!E.Owner.Throttled)
|
||||||
|
{
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
await E.Owner.ExecuteCommandAsync("quit");
|
await E.Owner.ExecuteCommandAsync("quit");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exceptions.NetworkException)
|
||||||
|
{
|
||||||
|
E.Origin.Tell("Unable to cleanly shutdown server, forcing");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentProcess.HasExited)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
currentProcess.Kill();
|
||||||
|
E.Origin.Tell("Successfully killed server process");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
E.Origin.Tell("Could not kill server process");
|
||||||
|
E.Owner.Logger.WriteDebug("Unable to kill process");
|
||||||
|
E.Owner.Logger.WriteDebug($"Exception: {e.Message}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exceptions.NetworkException)
|
return;
|
||||||
{
|
|
||||||
E.Origin.Tell("Unable to cleanly shutdown server, forcing");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currentProcess.HasExited)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
currentProcess.Kill();
|
|
||||||
E.Origin.Tell("Successfully killed server process");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
E.Origin.Tell("Could not kill server process");
|
|
||||||
E.Owner.Logger.WriteDebug("Unable to kill process");
|
|
||||||
E.Owner.Logger.WriteDebug($"Exception: {e.Message}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class CPing : Command
|
public class CPing : Command
|
||||||
{
|
{
|
||||||
public CPing() : base("ping", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_DESC"], "pi", Player.Permission.User, false, new CommandArgument[]
|
public CPing() : base("ping", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_DESC"], "pi", EFClient.Permission.User, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -1222,16 +1248,24 @@ namespace SharedLibraryCore.Commands
|
|||||||
if (E.Message.IsBroadcastCommand())
|
if (E.Message.IsBroadcastCommand())
|
||||||
{
|
{
|
||||||
if (E.Target == null)
|
if (E.Target == null)
|
||||||
|
{
|
||||||
E.Owner.Broadcast($"{E.Origin.Name}'s {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_TARGET"]} ^5{E.Origin.Ping}^7ms");
|
E.Owner.Broadcast($"{E.Origin.Name}'s {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_TARGET"]} ^5{E.Origin.Ping}^7ms");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
E.Owner.Broadcast($"{E.Target.Name}'s {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_TARGET"]} ^5{E.Target.Ping}^7ms");
|
E.Owner.Broadcast($"{E.Target.Name}'s {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_TARGET"]} ^5{E.Target.Ping}^7ms");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (E.Target == null)
|
if (E.Target == null)
|
||||||
|
{
|
||||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_SELF"]} ^5{E.Origin.Ping}^7ms");
|
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_SELF"]} ^5{E.Origin.Ping}^7ms");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
E.Origin.Tell($"{E.Target.Name}'s {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_TARGET"]} ^5{E.Target.Ping}^7ms");
|
E.Origin.Tell($"{E.Target.Name}'s {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_TARGET"]} ^5{E.Target.Ping}^7ms");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@ -1240,7 +1274,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
|
|
||||||
public class CSetGravatar : Command
|
public class CSetGravatar : Command
|
||||||
{
|
{
|
||||||
public CSetGravatar() : base("setgravatar", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_GRAVATAR_DESC"], "sg", Player.Permission.User, false, new CommandArgument[]
|
public CSetGravatar() : base("setgravatar", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_GRAVATAR_DESC"], "sg", EFClient.Permission.User, false, new CommandArgument[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
{
|
{
|
||||||
@ -1304,7 +1338,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CNextMap : Command
|
public class CNextMap : Command
|
||||||
{
|
{
|
||||||
public CNextMap() : base("nextmap", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_NEXTMAP_DESC"], "nm", Player.Permission.User, false) { }
|
public CNextMap() : base("nextmap", Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_NEXTMAP_DESC"], "nm", EFClient.Permission.User, false) { }
|
||||||
public static async Task<string> GetNextMap(Server s)
|
public static async Task<string> GetNextMap(Server s)
|
||||||
{
|
{
|
||||||
string mapRotation = (await s.GetDvarAsync<string>("sv_mapRotation")).Value.ToLower();
|
string mapRotation = (await s.GetDvarAsync<string>("sv_mapRotation")).Value.ToLower();
|
||||||
|
@ -3,6 +3,7 @@ using SharedLibraryCore.Database.Models;
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using static SharedLibraryCore.Database.Models.EFClient;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Database
|
namespace SharedLibraryCore.Database
|
||||||
{
|
{
|
||||||
@ -47,7 +48,7 @@ namespace SharedLibraryCore.Database
|
|||||||
Connections = 0,
|
Connections = 0,
|
||||||
FirstConnection = DateTime.UtcNow,
|
FirstConnection = DateTime.UtcNow,
|
||||||
LastConnection = DateTime.UtcNow,
|
LastConnection = DateTime.UtcNow,
|
||||||
Level = Objects.Player.Permission.Console,
|
Level = Permission.Console,
|
||||||
Masked = true,
|
Masked = true,
|
||||||
NetworkId = 0,
|
NetworkId = 0,
|
||||||
AliasLinkId = 1,
|
AliasLinkId = 1,
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
using System;
|
using Microsoft.Data.Sqlite;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using SharedLibraryCore.Database.Models;
|
using SharedLibraryCore.Database.Models;
|
||||||
using System.Reflection;
|
|
||||||
using System.IO;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.Data.Sqlite;
|
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Npgsql;
|
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Database
|
namespace SharedLibraryCore.Database
|
||||||
{
|
{
|
||||||
@ -26,6 +22,7 @@ namespace SharedLibraryCore.Database
|
|||||||
|
|
||||||
static string _ConnectionString;
|
static string _ConnectionString;
|
||||||
static string _provider;
|
static string _provider;
|
||||||
|
private static string _migrationPluginDirectory = @"X:\IW4MAdmin\BUILD\Plugins\";
|
||||||
|
|
||||||
public DatabaseContext(DbContextOptions<DatabaseContext> opt) : base(opt) { }
|
public DatabaseContext(DbContextOptions<DatabaseContext> opt) : base(opt) { }
|
||||||
|
|
||||||
@ -57,7 +54,7 @@ namespace SharedLibraryCore.Database
|
|||||||
$"{Path.DirectorySeparatorChar}{currentPath}" :
|
$"{Path.DirectorySeparatorChar}{currentPath}" :
|
||||||
currentPath;
|
currentPath;
|
||||||
|
|
||||||
var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = $"{currentPath}{Path.DirectorySeparatorChar}Database{Path.DirectorySeparatorChar}Database.db" };
|
var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = Path.Join(currentPath, "Database", "Database.db") };
|
||||||
var connectionString = connectionStringBuilder.ToString();
|
var connectionString = connectionStringBuilder.ToString();
|
||||||
var connection = new SqliteConnection(connectionString);
|
var connection = new SqliteConnection(connectionString);
|
||||||
|
|
||||||
@ -126,23 +123,11 @@ namespace SharedLibraryCore.Database
|
|||||||
|
|
||||||
// adapted from
|
// adapted from
|
||||||
// https://aleemkhan.wordpress.com/2013/02/28/dynamically-adding-dbset-properties-in-dbcontext-for-entity-framework-code-first/
|
// https://aleemkhan.wordpress.com/2013/02/28/dynamically-adding-dbset-properties-in-dbcontext-for-entity-framework-code-first/
|
||||||
IEnumerable<string> directoryFiles;
|
string pluginDir = Path.Join(Utilities.OperatingDirectory, "Plugins");
|
||||||
|
IEnumerable<string> directoryFiles = Directory.GetFiles(pluginDir).Where(f => f.EndsWith(".dll"));
|
||||||
|
|
||||||
string pluginDir = $@"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}Debug{Path.DirectorySeparatorChar}netcoreapp2.1{Path.DirectorySeparatorChar}Plugins";
|
|
||||||
|
|
||||||
if (!Directory.Exists(pluginDir))
|
|
||||||
{
|
|
||||||
pluginDir = Path.Join(Environment.CurrentDirectory, "Plugins");
|
|
||||||
|
|
||||||
if (!Directory.Exists(pluginDir))
|
|
||||||
{
|
|
||||||
pluginDir = Path.Join(Utilities.OperatingDirectory, "Plugins");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
directoryFiles = Directory.GetFiles(pluginDir).Where(f => f.EndsWith(".dll"));
|
|
||||||
#if DEBUG == TRUE
|
#if DEBUG == TRUE
|
||||||
foreach (string dllPath in Directory.GetFiles(@"C:\Projects\IW4M-Admin\Application\bin\Debug\netcoreapp2.1\Plugins").Where(f => f.EndsWith(".dll")))
|
foreach (string dllPath in Directory.GetFiles(_migrationPluginDirectory).Where(f => f.EndsWith(".dll")))
|
||||||
#else
|
#else
|
||||||
foreach (string dllPath in directoryFiles)
|
foreach (string dllPath in directoryFiles)
|
||||||
#endif
|
#endif
|
||||||
@ -163,7 +148,9 @@ namespace SharedLibraryCore.Database
|
|||||||
.Select(c => (IModelConfiguration)Activator.CreateInstance(c));
|
.Select(c => (IModelConfiguration)Activator.CreateInstance(c));
|
||||||
|
|
||||||
foreach (var configurable in configurations)
|
foreach (var configurable in configurations)
|
||||||
|
{
|
||||||
configurable.Configure(modelBuilder);
|
configurable.Configure(modelBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var type in library.ExportedTypes)
|
foreach (var type in library.ExportedTypes)
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
|
|
||||||
namespace SharedLibraryCore.Database.Models
|
namespace SharedLibraryCore.Database.Models
|
||||||
{
|
{
|
||||||
public class EFClient : SharedEntity
|
public partial class EFClient : SharedEntity
|
||||||
{
|
{
|
||||||
[Key]
|
[Key]
|
||||||
public int ClientId { get; set; }
|
public int ClientId { get; set; }
|
||||||
@ -25,7 +25,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
[ForeignKey("AliasLinkId")]
|
[ForeignKey("AliasLinkId")]
|
||||||
public virtual EFAliasLink AliasLink { get; set; }
|
public virtual EFAliasLink AliasLink { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
public Objects.Player.Permission Level { get; set; }
|
public Permission Level { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public int CurrentAliasId { get; set; }
|
public int CurrentAliasId { get; set; }
|
||||||
@ -57,11 +57,5 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
|
|
||||||
public virtual ICollection<EFPenalty> ReceivedPenalties { get; set; }
|
public virtual ICollection<EFPenalty> ReceivedPenalties { get; set; }
|
||||||
public virtual ICollection<EFPenalty> AdministeredPenalties { get; set; }
|
public virtual ICollection<EFPenalty> AdministeredPenalties { get; set; }
|
||||||
|
|
||||||
public EFClient()
|
|
||||||
{
|
|
||||||
ReceivedPenalties = new List<EFPenalty>();
|
|
||||||
AdministeredPenalties = new List<EFPenalty>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,10 @@
|
|||||||
using System;
|
namespace SharedLibraryCore.Dtos
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using static SharedLibraryCore.Objects.Player;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Dtos
|
|
||||||
{
|
{
|
||||||
public class ClientInfo
|
public class ClientInfo
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public int ClientId { get; set; }
|
public int ClientId { get; set; }
|
||||||
public int LinkId { get; set; }
|
public int LinkId { get; set; }
|
||||||
public Permission Level { get; set; }
|
public Database.Models.EFClient.Permission Level { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
|
|
||||||
namespace SharedLibraryCore
|
namespace SharedLibraryCore
|
||||||
@ -50,11 +51,11 @@ namespace SharedLibraryCore
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Stop,
|
Stop,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// a client was detecting as connecting via RCon
|
/// a client was detecting as connecting via log
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Connect,
|
Connect,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// a client was detecting joining via log
|
/// a client was detecting joining by RCon
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Join,
|
Join,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -170,8 +171,8 @@ namespace SharedLibraryCore
|
|||||||
public EventType Type;
|
public EventType Type;
|
||||||
public string Data; // Data is usually the message sent by player
|
public string Data; // Data is usually the message sent by player
|
||||||
public string Message;
|
public string Message;
|
||||||
public Player Origin;
|
public EFClient Origin;
|
||||||
public Player Target;
|
public EFClient Target;
|
||||||
public Server Owner;
|
public Server Owner;
|
||||||
public Boolean Remote = false;
|
public Boolean Remote = false;
|
||||||
public object Extra { get; set; }
|
public object Extra { get; set; }
|
||||||
@ -200,7 +201,7 @@ namespace SharedLibraryCore
|
|||||||
public static bool ShouldOriginEventBeDelayed(GameEvent queuedEvent)
|
public static bool ShouldOriginEventBeDelayed(GameEvent queuedEvent)
|
||||||
{
|
{
|
||||||
return queuedEvent.Origin != null &&
|
return queuedEvent.Origin != null &&
|
||||||
(queuedEvent.Origin.State != Player.ClientState.Connected &&
|
(queuedEvent.Origin.State != EFClient.ClientState.Connected &&
|
||||||
// we want to allow join and quit events
|
// we want to allow join and quit events
|
||||||
queuedEvent.Type != EventType.Connect &&
|
queuedEvent.Type != EventType.Connect &&
|
||||||
queuedEvent.Type != EventType.Join &&
|
queuedEvent.Type != EventType.Join &&
|
||||||
@ -219,7 +220,7 @@ namespace SharedLibraryCore
|
|||||||
public static bool ShouldTargetEventBeDelayed(GameEvent queuedEvent)
|
public static bool ShouldTargetEventBeDelayed(GameEvent queuedEvent)
|
||||||
{
|
{
|
||||||
return (queuedEvent.Target != null && queuedEvent.Target.ClientNumber != -1) &&
|
return (queuedEvent.Target != null && queuedEvent.Target.ClientNumber != -1) &&
|
||||||
(queuedEvent.Target.State != Player.ClientState.Connected &&
|
(queuedEvent.Target.State != EFClient.ClientState.Connected &&
|
||||||
queuedEvent.Target.NetworkId != 0 &&
|
queuedEvent.Target.NetworkId != 0 &&
|
||||||
queuedEvent.Origin?.ClientId != 1);
|
queuedEvent.Origin?.ClientId != 1);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -12,16 +13,16 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
/// occurs in the log, as no IP is given
|
/// occurs in the log, as no IP is given
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="client">client that has joined from the log</param>
|
/// <param name="client">client that has joined from the log</param>
|
||||||
void RequestClientAuthentication(Player client);
|
void RequestClientAuthentication(EFClient client);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// get all clients that have been authenticated by the status poll
|
/// get all clients that have been authenticated by the status poll
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>list of all authenticated clients</returns>
|
/// <returns>list of all authenticated clients</returns>
|
||||||
IList<Player> GetAuthenticatedClients();
|
IList<EFClient> GetAuthenticatedClients();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// authenticate a list of clients from status poll
|
/// authenticate a list of clients from status poll
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="clients">list of clients to authenticate</param>
|
/// <param name="clients">list of clients to authenticate</param>
|
||||||
void AuthenticateClients(IList<Player> clients);
|
void AuthenticateClients(IList<EFClient> clients);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using SharedLibraryCore.Objects;
|
|||||||
using SharedLibraryCore.Services;
|
using SharedLibraryCore.Services;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Interfaces
|
namespace SharedLibraryCore.Interfaces
|
||||||
{
|
{
|
||||||
@ -17,12 +18,12 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
IList<Server> GetServers();
|
IList<Server> GetServers();
|
||||||
IList<Command> GetCommands();
|
IList<Command> GetCommands();
|
||||||
IList<Helpers.MessageToken> GetMessageTokens();
|
IList<Helpers.MessageToken> GetMessageTokens();
|
||||||
IList<Player> GetActiveClients();
|
IList<EFClient> GetActiveClients();
|
||||||
IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings();
|
IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings();
|
||||||
ClientService GetClientService();
|
ClientService GetClientService();
|
||||||
AliasService GetAliasService();
|
AliasService GetAliasService();
|
||||||
PenaltyService GetPenaltyService();
|
PenaltyService GetPenaltyService();
|
||||||
IDictionary<int, Player> GetPrivilegedClients();
|
IDictionary<int, EFClient> GetPrivilegedClients();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the event handlers
|
/// Get the event handlers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using SharedLibraryCore.RCon;
|
using SharedLibraryCore.RCon;
|
||||||
|
|
||||||
@ -10,7 +11,7 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
Task<Dvar<T>> GetDvarAsync<T>(Connection connection, string dvarName);
|
Task<Dvar<T>> GetDvarAsync<T>(Connection connection, string dvarName);
|
||||||
Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue);
|
Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue);
|
||||||
Task<string[]> ExecuteCommandAsync(Connection connection, string command);
|
Task<string[]> ExecuteCommandAsync(Connection connection, string command);
|
||||||
Task<List<Player>> GetStatusAsync(Connection connection);
|
Task<List<EFClient>> GetStatusAsync(Connection connection);
|
||||||
CommandPrefix GetCommandPrefixes();
|
CommandPrefix GetCommandPrefixes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
using System;
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using SharedLibraryCore.Objects;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Objects
|
namespace SharedLibraryCore.Database.Models
|
||||||
{
|
{
|
||||||
public class Player : Database.Models.EFClient
|
public partial class EFClient
|
||||||
{
|
{
|
||||||
public enum ClientState
|
public enum ClientState
|
||||||
{
|
{
|
||||||
@ -76,7 +77,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
Console = 8
|
Console = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player()
|
public EFClient()
|
||||||
{
|
{
|
||||||
ConnectionTime = DateTime.UtcNow;
|
ConnectionTime = DateTime.UtcNow;
|
||||||
ClientNumber = -1;
|
ClientNumber = -1;
|
||||||
@ -87,7 +88,10 @@ namespace SharedLibraryCore.Objects
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() => $"{Name}::{NetworkId}";
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"{Name}::{NetworkId}";
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// send a message directly to the connected client
|
/// send a message directly to the connected client
|
||||||
@ -113,7 +117,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="warnReason">reason for warn</param>
|
/// <param name="warnReason">reason for warn</param>
|
||||||
/// <param name="sender">client performing the warn</param>
|
/// <param name="sender">client performing the warn</param>
|
||||||
public GameEvent Warn(String warnReason, Player sender)
|
public GameEvent Warn(String warnReason, EFClient sender)
|
||||||
{
|
{
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -146,7 +150,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender">client performing the warn clear</param>
|
/// <param name="sender">client performing the warn clear</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public GameEvent WarnClear(Player sender)
|
public GameEvent WarnClear(EFClient sender)
|
||||||
{
|
{
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -175,7 +179,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
/// <param name="reportReason">reason for the report</param>
|
/// <param name="reportReason">reason for the report</param>
|
||||||
/// <param name="sender">client performing the report</param>
|
/// <param name="sender">client performing the report</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public GameEvent Report(string reportReason, Player sender)
|
public GameEvent Report(string reportReason, EFClient sender)
|
||||||
{
|
{
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -221,7 +225,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
/// <param name="flagReason">reason for flagging</param>
|
/// <param name="flagReason">reason for flagging</param>
|
||||||
/// <param name="sender">client performing the flag</param>
|
/// <param name="sender">client performing the flag</param>
|
||||||
/// <returns>game event for the flag</returns>
|
/// <returns>game event for the flag</returns>
|
||||||
public GameEvent Flag(string flagReason, Player sender)
|
public GameEvent Flag(string flagReason, EFClient sender)
|
||||||
{
|
{
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -238,14 +242,14 @@ namespace SharedLibraryCore.Objects
|
|||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (this.Level == Player.Permission.Flagged)
|
else if (this.Level == Permission.Flagged)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.Level = Player.Permission.Flagged;
|
this.Level = Permission.Flagged;
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
sender.CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
||||||
@ -258,7 +262,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
/// <param name="unflagReason">reason to unflag a player for</param>
|
/// <param name="unflagReason">reason to unflag a player for</param>
|
||||||
/// <param name="sender">client performing the unflag</param>
|
/// <param name="sender">client performing the unflag</param>
|
||||||
/// <returns>game event for the un flug</returns>
|
/// <returns>game event for the un flug</returns>
|
||||||
public GameEvent Unflag(string unflagReason, Player sender)
|
public GameEvent Unflag(string unflagReason, EFClient sender)
|
||||||
{
|
{
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -275,7 +279,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (this.Level != Player.Permission.Flagged)
|
else if (this.Level != EFClient.Permission.Flagged)
|
||||||
{
|
{
|
||||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||||
}
|
}
|
||||||
@ -294,7 +298,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="kickReason">reason to kick for</param>
|
/// <param name="kickReason">reason to kick for</param>
|
||||||
/// <param name="sender">client performing the kick</param>
|
/// <param name="sender">client performing the kick</param>
|
||||||
public GameEvent Kick(String kickReason, Player sender)
|
public GameEvent Kick(String kickReason, EFClient sender)
|
||||||
{
|
{
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -322,7 +326,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
/// <param name="tempbanReason">reason for the temp ban</param>
|
/// <param name="tempbanReason">reason for the temp ban</param>
|
||||||
/// <param name="banLength">how long the temp ban lasts</param>
|
/// <param name="banLength">how long the temp ban lasts</param>
|
||||||
/// <param name="sender">client performing the tempban</param>
|
/// <param name="sender">client performing the tempban</param>
|
||||||
public GameEvent TempBan(String tempbanReason, TimeSpan banLength, Player sender)
|
public GameEvent TempBan(String tempbanReason, TimeSpan banLength, EFClient sender)
|
||||||
{
|
{
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -350,7 +354,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="banReason">reason for the ban</param>
|
/// <param name="banReason">reason for the ban</param>
|
||||||
/// <param name="sender">client performing the ban</param>
|
/// <param name="sender">client performing the ban</param>
|
||||||
public GameEvent Ban(String banReason, Player sender)
|
public GameEvent Ban(String banReason, EFClient sender)
|
||||||
{
|
{
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -378,7 +382,7 @@ namespace SharedLibraryCore.Objects
|
|||||||
/// <param name="unbanReason">reason for the unban</param>
|
/// <param name="unbanReason">reason for the unban</param>
|
||||||
/// <param name="sender">client performing the unban</param>
|
/// <param name="sender">client performing the unban</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public GameEvent Unban(String unbanReason, Player sender)
|
public GameEvent Unban(String unbanReason, EFClient sender)
|
||||||
{
|
{
|
||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
@ -400,10 +404,119 @@ namespace SharedLibraryCore.Objects
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles any client related logic on connection
|
||||||
|
/// </summary>
|
||||||
|
public void OnConnect()
|
||||||
|
{
|
||||||
|
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||||
|
//#if !DEBUG
|
||||||
|
if (Name.Length < 3)
|
||||||
|
{
|
||||||
|
CurrentServer.Logger.WriteDebug($"Kicking {this} because their name is too short");
|
||||||
|
Kick(loc["SERVER_KICK_MINNAME"], Utilities.IW4MAdminClient(CurrentServer));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Name == "Unknown Soldier" ||
|
||||||
|
Name == "UnknownSoldier" ||
|
||||||
|
Name == "CHEATER")
|
||||||
|
{
|
||||||
|
CurrentServer.Logger.WriteDebug($"Kicking {this} because their name is generic");
|
||||||
|
Kick(loc["SERVER_KICK_GENERICNAME"], Utilities.IW4MAdminClient(CurrentServer));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Name.Where(c => char.IsControl(c)).Count() > 0)
|
||||||
|
{
|
||||||
|
CurrentServer.Logger.WriteDebug($"Kicking {this} because their name contains control characters");
|
||||||
|
Kick(loc["SERVER_KICK_CONTROLCHARS"], Utilities.IW4MAdminClient(CurrentServer));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reserved slots stuff
|
||||||
|
if ((CurrentServer.GetClientsAsList().Count(_client => !_client.IsPrivileged()) - CurrentServer.MaxClients) < CurrentServer.ServerConfig.ReservedSlotNumber &&
|
||||||
|
!this.IsPrivileged())
|
||||||
|
{
|
||||||
|
CurrentServer.Logger.WriteDebug($"Kicking {this} their spot is reserved");
|
||||||
|
Kick(loc["SERVER_KICK_SLOT_IS_RESERVED"], Utilities.IW4MAdminClient(CurrentServer));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastConnection = DateTime.UtcNow;
|
||||||
|
Connections += 1;
|
||||||
|
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnJoin(int ipAddress)
|
||||||
|
{
|
||||||
|
// todo: fix this up
|
||||||
|
CurrentAlias.IPAddress = IPAddress;
|
||||||
|
await CurrentServer.Manager.GetClientService().Update(this);
|
||||||
|
|
||||||
|
var loc = Utilities.CurrentLocalization.LocalizationIndex;
|
||||||
|
var activePenalties = await CurrentServer.Manager.GetPenaltyService().GetActivePenaltiesAsync(AliasLinkId, ipAddress);
|
||||||
|
var currentBan = activePenalties.FirstOrDefault(p => p.Type == Penalty.PenaltyType.Ban || p.Type == Penalty.PenaltyType.TempBan);
|
||||||
|
|
||||||
|
var currentAutoFlag = activePenalties.Where(p => p.Type == Penalty.PenaltyType.Flag && p.PunisherId == 1)
|
||||||
|
.Where(p => p.Active)
|
||||||
|
.OrderByDescending(p => p.When)
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
// remove their auto flag status after a week
|
||||||
|
if (Level == Permission.Flagged &&
|
||||||
|
currentAutoFlag != null &&
|
||||||
|
(DateTime.UtcNow - currentAutoFlag.When).TotalDays > 7)
|
||||||
|
{
|
||||||
|
Level = Permission.User;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentBan != null)
|
||||||
|
{
|
||||||
|
CurrentServer.Logger.WriteInfo($"Banned client {this} trying to join...");
|
||||||
|
var autoKickClient = Utilities.IW4MAdminClient(CurrentServer);
|
||||||
|
|
||||||
|
|
||||||
|
// reban the "evading" guid
|
||||||
|
if (Level != Permission.Banned &&
|
||||||
|
currentBan.Type == Penalty.PenaltyType.Ban)
|
||||||
|
{
|
||||||
|
// hack: re apply the automated offense to the reban
|
||||||
|
if (currentBan.AutomatedOffense != null)
|
||||||
|
{
|
||||||
|
autoKickClient.AdministeredPenalties.Add(new EFPenalty()
|
||||||
|
{
|
||||||
|
AutomatedOffense = currentBan.AutomatedOffense
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ban($"{currentBan.Offense}", autoKickClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the player is permanently banned
|
||||||
|
else if (currentBan.Type == Penalty.PenaltyType.Ban)
|
||||||
|
{
|
||||||
|
Kick($"{loc["SERVER_BAN_PREV"]} {currentBan.Offense} ({loc["SERVER_BAN_APPEAL"]} {CurrentServer.Website})", autoKickClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//string formattedKick = String.Format(
|
||||||
|
// RconParser.GetCommandPrefixes().Kick,
|
||||||
|
// polledPlayer.ClientNumber,
|
||||||
|
// $"{loc["SERVER_TB_REMAIN"]} ({(currentBan.Expires.Value - DateTime.UtcNow).TimeSpanText()} {loc["WEBFRONT_PENALTY_TEMPLATE_REMAINING"]})");
|
||||||
|
//await this.ExecuteCommandAsync(formattedKick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
Dictionary<string, object> _additionalProperties;
|
Dictionary<string, object> _additionalProperties;
|
||||||
|
|
||||||
public T GetAdditionalProperty<T>(string name) => _additionalProperties.ContainsKey(name) ? (T)_additionalProperties[name] : default(T);
|
public T GetAdditionalProperty<T>(string name)
|
||||||
|
{
|
||||||
|
return _additionalProperties.ContainsKey(name) ? (T)_additionalProperties[name] : default(T);
|
||||||
|
}
|
||||||
|
|
||||||
public void SetAdditionalProperty(string name, object value)
|
public void SetAdditionalProperty(string name, object value)
|
||||||
{
|
{
|
||||||
@ -433,18 +546,18 @@ namespace SharedLibraryCore.Objects
|
|||||||
public int Score { get; set; }
|
public int Score { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public bool IsBot { get; set; }
|
public bool IsBot { get; set; }
|
||||||
private int _ipaddress;
|
//private int _ipaddress;
|
||||||
public override int IPAddress
|
//public override int IPAddress
|
||||||
{
|
//{
|
||||||
get { return _ipaddress; }
|
// get => _ipaddress;
|
||||||
set { _ipaddress = value; }
|
// set => _ipaddress = value;
|
||||||
}
|
//}
|
||||||
private string _name;
|
//private string _name;
|
||||||
public override string Name
|
//public override string Name
|
||||||
{
|
//{
|
||||||
get { return _name; }
|
// get => _name;
|
||||||
set { _name = value; }
|
// set => _name = value;
|
||||||
}
|
//}
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public ClientState State { get; set; }
|
public ClientState State { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
@ -460,9 +573,12 @@ namespace SharedLibraryCore.Objects
|
|||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
return ((Player)obj).NetworkId == this.NetworkId;
|
return ((EFClient)obj).NetworkId == this.NetworkId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() => (int)NetworkId;
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return (int)NetworkId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,4 @@
|
|||||||
using System;
|
using static SharedLibraryCore.Database.Models.EFClient;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using static SharedLibraryCore.Objects.Player;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Objects
|
namespace SharedLibraryCore.Objects
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -8,8 +9,8 @@ namespace SharedLibraryCore.Objects
|
|||||||
{
|
{
|
||||||
public class Report
|
public class Report
|
||||||
{
|
{
|
||||||
public Player Target { get; set; }
|
public EFClient Target { get; set; }
|
||||||
public Player Origin { get; set; }
|
public EFClient Origin { get; set; }
|
||||||
public String Reason { get; set; }
|
public string Reason { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,12 +137,9 @@ namespace SharedLibraryCore.RCon
|
|||||||
throw new NetworkException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_RCON_NOTSET"]);
|
throw new NetworkException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_RCON_NOTSET"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.WriteInfo(responseString);
|
|
||||||
|
|
||||||
string[] splitResponse = responseString.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
string[] splitResponse = responseString.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
.Select(line => line.Trim()).ToArray();
|
.Select(line => line.Trim()).ToArray();
|
||||||
return splitResponse;
|
return splitResponse;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<byte[]> SendPayloadAsync(byte[] payload, bool waitForResponse)
|
private async Task<byte[]> SendPayloadAsync(byte[] payload, bool waitForResponse)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -71,7 +72,7 @@ namespace SharedLibraryCore
|
|||||||
cfg.AllowClr(new[]
|
cfg.AllowClr(new[]
|
||||||
{
|
{
|
||||||
typeof(System.Net.Http.HttpClient).Assembly,
|
typeof(System.Net.Http.HttpClient).Assembly,
|
||||||
typeof(Objects.Player).Assembly,
|
typeof(EFClient).Assembly,
|
||||||
})
|
})
|
||||||
.CatchClrExceptions());
|
.CatchClrExceptions());
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Objects;
|
|||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
using SharedLibraryCore.Configuration;
|
using SharedLibraryCore.Configuration;
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace SharedLibraryCore
|
namespace SharedLibraryCore
|
||||||
{
|
{
|
||||||
@ -37,9 +38,9 @@ namespace SharedLibraryCore
|
|||||||
ServerConfig = config;
|
ServerConfig = config;
|
||||||
RemoteConnection = new RCon.Connection(IP, Port, Password, Logger);
|
RemoteConnection = new RCon.Connection(IP, Port, Password, Logger);
|
||||||
|
|
||||||
Players = new List<Player>(new Player[18]);
|
Clients = new List<EFClient>(new EFClient[18]);
|
||||||
Reports = new List<Report>();
|
Reports = new List<Report>();
|
||||||
PlayerHistory = new Queue<PlayerHistory>();
|
ClientHistory = new Queue<PlayerHistory>();
|
||||||
ChatHistory = new List<ChatInfo>();
|
ChatHistory = new List<ChatInfo>();
|
||||||
NextMessage = 0;
|
NextMessage = 0;
|
||||||
CustomSayEnabled = Manager.GetApplicationSettings().Configuration().EnableCustomSayName;
|
CustomSayEnabled = Manager.GetApplicationSettings().Configuration().EnableCustomSayName;
|
||||||
@ -61,32 +62,32 @@ namespace SharedLibraryCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Returns list of all current players
|
//Returns list of all current players
|
||||||
public List<Player> GetPlayersAsList()
|
public List<EFClient> GetClientsAsList()
|
||||||
{
|
{
|
||||||
return Players.FindAll(x => x != null);
|
return Clients.FindAll(x => x != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a player to the server's player list
|
/// Add a player to the server's player list
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="P">Player pulled from memory reading</param>
|
/// <param name="P">EFClient pulled from memory reading</param>
|
||||||
/// <returns>True if player added sucessfully, false otherwise</returns>
|
/// <returns>True if player added sucessfully, false otherwise</returns>
|
||||||
abstract public Task<bool> AddPlayer(Player P);
|
abstract public Task OnClientConnected(EFClient P);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove player by client number
|
/// Remove player by client number
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cNum">Client ID of player to be removed</param>
|
/// <param name="cNum">Client ID of player to be removed</param>
|
||||||
/// <returns>true if removal succeded, false otherwise</returns>
|
/// <returns>true if removal succeded, false otherwise</returns>
|
||||||
abstract public Task RemovePlayer(int cNum);
|
abstract public Task RemoveClient(int cNum);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a player by name
|
/// Get a player by name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pName">Player name to search for</param>
|
/// <param name="pName">EFClient name to search for</param>
|
||||||
/// <returns>Matching player if found</returns>
|
/// <returns>Matching player if found</returns>
|
||||||
public List<Player> GetClientByName(String pName)
|
public List<EFClient> GetClientByName(String pName)
|
||||||
{
|
{
|
||||||
string[] QuoteSplit = pName.Split('"');
|
string[] QuoteSplit = pName.Split('"');
|
||||||
bool literal = false;
|
bool literal = false;
|
||||||
@ -96,9 +97,9 @@ namespace SharedLibraryCore
|
|||||||
literal = true;
|
literal = true;
|
||||||
}
|
}
|
||||||
if (literal)
|
if (literal)
|
||||||
return Players.Where(p => p != null && p.Name.ToLower().Equals(pName.ToLower())).ToList();
|
return Clients.Where(p => p != null && p.Name.ToLower().Equals(pName.ToLower())).ToList();
|
||||||
|
|
||||||
return Players.Where(p => p != null && p.Name.ToLower().Contains(pName.ToLower())).ToList();
|
return Clients.Where(p => p != null && p.Name.ToLower().Contains(pName.ToLower())).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual public Task<bool> ProcessUpdatesAsync(CancellationToken cts) => (Task<bool>)Task.CompletedTask;
|
virtual public Task<bool> ProcessUpdatesAsync(CancellationToken cts) => (Task<bool>)Task.CompletedTask;
|
||||||
@ -115,7 +116,7 @@ namespace SharedLibraryCore
|
|||||||
/// Send a message to all players
|
/// Send a message to all players
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">Message to be sent to all players</param>
|
/// <param name="message">Message to be sent to all players</param>
|
||||||
public GameEvent Broadcast(string message, Player sender = null)
|
public GameEvent Broadcast(string message, EFClient sender = null)
|
||||||
{
|
{
|
||||||
string formattedMessage = String.Format(RconParser.GetCommandPrefixes().Say, $"{(CustomSayEnabled ? $"{CustomSayName}: " : "")}{message}");
|
string formattedMessage = String.Format(RconParser.GetCommandPrefixes().Say, $"{(CustomSayEnabled ? $"{CustomSayName}: " : "")}{message}");
|
||||||
|
|
||||||
@ -139,19 +140,19 @@ namespace SharedLibraryCore
|
|||||||
/// Send a message to a particular players
|
/// Send a message to a particular players
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Message">Message to send</param>
|
/// <param name="Message">Message to send</param>
|
||||||
/// <param name="Target">Player to send message to</param>
|
/// <param name="Target">EFClient to send message to</param>
|
||||||
protected async Task Tell(String Message, Player Target)
|
protected async Task Tell(String Message, EFClient Target)
|
||||||
{
|
{
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
string formattedMessage = String.Format(RconParser.GetCommandPrefixes().Tell, Target.ClientNumber, $"{(CustomSayEnabled ? $"{CustomSayName}: " : "")}{Message}");
|
string formattedMessage = String.Format(RconParser.GetCommandPrefixes().Tell, Target.ClientNumber, $"{(CustomSayEnabled ? $"{CustomSayName}: " : "")}{Message}");
|
||||||
if (Target.ClientNumber > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console)
|
if (Target.ClientNumber > -1 && Message.Length > 0 && Target.Level != EFClient.Permission.Console)
|
||||||
await this.ExecuteCommandAsync(formattedMessage);
|
await this.ExecuteCommandAsync(formattedMessage);
|
||||||
#else
|
#else
|
||||||
Logger.WriteVerbose($"{Target.ClientNumber}->{Message.StripColors()}");
|
Logger.WriteVerbose($"{Target.ClientNumber}->{Message.StripColors()}");
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Target.Level == Player.Permission.Console)
|
if (Target.Level == EFClient.Permission.Console)
|
||||||
{
|
{
|
||||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||||
Console.WriteLine(Message.StripColors());
|
Console.WriteLine(Message.StripColors());
|
||||||
@ -179,7 +180,7 @@ namespace SharedLibraryCore
|
|||||||
/// <param name="message">Message to send out</param>
|
/// <param name="message">Message to send out</param>
|
||||||
public void ToAdmins(String message)
|
public void ToAdmins(String message)
|
||||||
{
|
{
|
||||||
foreach (var client in GetPlayersAsList().Where(c => c.Level > Player.Permission.Flagged))
|
foreach (var client in GetClientsAsList().Where(c => c.Level > EFClient.Permission.Flagged))
|
||||||
{
|
{
|
||||||
client.Tell(message);
|
client.Tell(message);
|
||||||
}
|
}
|
||||||
@ -189,15 +190,15 @@ namespace SharedLibraryCore
|
|||||||
/// Kick a player from the server
|
/// Kick a player from the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Reason">Reason for kicking</param>
|
/// <param name="Reason">Reason for kicking</param>
|
||||||
/// <param name="Target">Player to kick</param>
|
/// <param name="Target">EFClient to kick</param>
|
||||||
abstract protected Task Kick(String Reason, Player Target, Player Origin);
|
abstract protected Task Kick(String Reason, EFClient Target, EFClient Origin);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Temporarily ban a player ( default 1 hour ) from the server
|
/// Temporarily ban a player ( default 1 hour ) from the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="Reason">Reason for banning the player</param>
|
/// <param name="Reason">Reason for banning the player</param>
|
||||||
/// <param name="Target">The player to ban</param>
|
/// <param name="Target">The player to ban</param>
|
||||||
abstract protected Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin);
|
abstract protected Task TempBan(String Reason, TimeSpan length, EFClient Target, EFClient Origin);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perm ban a player from the server
|
/// Perm ban a player from the server
|
||||||
@ -205,9 +206,9 @@ namespace SharedLibraryCore
|
|||||||
/// <param name="Reason">The reason for the ban</param>
|
/// <param name="Reason">The reason for the ban</param>
|
||||||
/// <param name="Target">The person to ban</param>
|
/// <param name="Target">The person to ban</param>
|
||||||
/// <param name="Origin">The person who banned the target</param>
|
/// <param name="Origin">The person who banned the target</param>
|
||||||
abstract protected Task Ban(String Reason, Player Target, Player Origin);
|
abstract protected Task Ban(String Reason, EFClient Target, EFClient Origin);
|
||||||
|
|
||||||
abstract protected Task Warn(String Reason, Player Target, Player Origin);
|
abstract protected Task Warn(String Reason, EFClient Target, EFClient Origin);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unban a player by npID / GUID
|
/// Unban a player by npID / GUID
|
||||||
@ -215,7 +216,7 @@ namespace SharedLibraryCore
|
|||||||
/// <param name="npID">npID of the player</param>
|
/// <param name="npID">npID of the player</param>
|
||||||
/// <param name="Target">I don't remember what this is for</param>
|
/// <param name="Target">I don't remember what this is for</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
abstract public Task Unban(string reason, Player Target, Player Origin);
|
abstract public Task Unban(string reason, EFClient Target, EFClient Origin);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Change the current searver map
|
/// Change the current searver map
|
||||||
@ -284,7 +285,7 @@ namespace SharedLibraryCore
|
|||||||
public List<Map> Maps { get; protected set; }
|
public List<Map> Maps { get; protected set; }
|
||||||
public List<Report> Reports { get; set; }
|
public List<Report> Reports { get; set; }
|
||||||
public List<ChatInfo> ChatHistory { get; protected set; }
|
public List<ChatInfo> ChatHistory { get; protected set; }
|
||||||
public Queue<PlayerHistory> PlayerHistory { get; private set; }
|
public Queue<PlayerHistory> ClientHistory { get; private set; }
|
||||||
public Game GameName { get; protected set; }
|
public Game GameName { get; protected set; }
|
||||||
|
|
||||||
// Info
|
// Info
|
||||||
@ -296,11 +297,11 @@ namespace SharedLibraryCore
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Players.Where(p => p != null).Count();
|
return Clients.Where(p => p != null).Count();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public int MaxClients { get; protected set; }
|
public int MaxClients { get; protected set; }
|
||||||
public List<Player> Players { get; protected set; }
|
public List<EFClient> Clients { get; protected set; }
|
||||||
public string Password { get; private set; }
|
public string Password { get; private set; }
|
||||||
public bool Throttled { get; protected set; }
|
public bool Throttled { get; protected set; }
|
||||||
public bool CustomCallback { get; protected set; }
|
public bool CustomCallback { get; protected set; }
|
||||||
@ -309,6 +310,7 @@ namespace SharedLibraryCore
|
|||||||
public IRConParser RconParser { get; protected set; }
|
public IRConParser RconParser { get; protected set; }
|
||||||
public IEventParser EventParser { get; set; }
|
public IEventParser EventParser { get; set; }
|
||||||
public string LogPath { get; protected set; }
|
public string LogPath { get; protected set; }
|
||||||
|
public bool RestartRequested { get; set; }
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
protected string IP;
|
protected string IP;
|
||||||
|
@ -10,6 +10,7 @@ using System.Linq.Expressions;
|
|||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
|
using static SharedLibraryCore.Database.Models.EFClient;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Services
|
namespace SharedLibraryCore.Services
|
||||||
{
|
{
|
||||||
@ -60,8 +61,8 @@ namespace SharedLibraryCore.Services
|
|||||||
Level = hasExistingAlias ?
|
Level = hasExistingAlias ?
|
||||||
(await context.Clients.Where(c => c.AliasLinkId == existingAlias.LinkId)
|
(await context.Clients.Where(c => c.AliasLinkId == existingAlias.LinkId)
|
||||||
.OrderByDescending(c => c.Level)
|
.OrderByDescending(c => c.Level)
|
||||||
.FirstOrDefaultAsync())?.Level ?? Player.Permission.User :
|
.FirstOrDefaultAsync())?.Level ?? Permission.User :
|
||||||
Player.Permission.User,
|
Permission.User,
|
||||||
FirstConnection = DateTime.UtcNow,
|
FirstConnection = DateTime.UtcNow,
|
||||||
Connections = 1,
|
Connections = 1,
|
||||||
LastConnection = DateTime.UtcNow,
|
LastConnection = DateTime.UtcNow,
|
||||||
@ -228,7 +229,7 @@ namespace SharedLibraryCore.Services
|
|||||||
{
|
{
|
||||||
using (var context = new DatabaseContext())
|
using (var context = new DatabaseContext())
|
||||||
return await context.Clients
|
return await context.Clients
|
||||||
.Where(c => c.Level == Player.Permission.Owner)
|
.Where(c => c.Level == Permission.Owner)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +238,7 @@ namespace SharedLibraryCore.Services
|
|||||||
using (var context = new DatabaseContext(disableTracking: true))
|
using (var context = new DatabaseContext(disableTracking: true))
|
||||||
{
|
{
|
||||||
var iqClients = from client in context.Clients
|
var iqClients = from client in context.Clients
|
||||||
where client.Level >= Player.Permission.Trusted
|
where client.Level >= Permission.Trusted
|
||||||
where client.Active
|
where client.Active
|
||||||
select new ClientInfo()
|
select new ClientInfo()
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,7 @@ using SharedLibraryCore.Database.Models;
|
|||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
|
using static SharedLibraryCore.Database.Models.EFClient;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Services
|
namespace SharedLibraryCore.Services
|
||||||
{
|
{
|
||||||
@ -35,7 +36,7 @@ namespace SharedLibraryCore.Services
|
|||||||
{
|
{
|
||||||
await context.Clients
|
await context.Clients
|
||||||
.Where(c => c.AliasLinkId == addedEntity.LinkId)
|
.Where(c => c.AliasLinkId == addedEntity.LinkId)
|
||||||
.ForEachAsync(c => c.Level = Objects.Player.Permission.Banned);
|
.ForEachAsync(c => c.Level = Permission.Banned);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make flags propogate to all aliases
|
// make flags propogate to all aliases
|
||||||
@ -43,7 +44,7 @@ namespace SharedLibraryCore.Services
|
|||||||
{
|
{
|
||||||
await context.Clients
|
await context.Clients
|
||||||
.Where(c => c.AliasLinkId == addedEntity.LinkId)
|
.Where(c => c.AliasLinkId == addedEntity.LinkId)
|
||||||
.ForEachAsync(c => c.Level = Objects.Player.Permission.Flagged);
|
.ForEachAsync(c => c.Level = Permission.Flagged);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Penalties.Add(addedEntity);
|
context.Penalties.Add(addedEntity);
|
||||||
@ -221,10 +222,12 @@ namespace SharedLibraryCore.Services
|
|||||||
var iqPenalties = context.Penalties
|
var iqPenalties = context.Penalties
|
||||||
.Where(p => p.LinkId == linkId ||
|
.Where(p => p.LinkId == linkId ||
|
||||||
p.Link.Children.Any(a => a.IPAddress == ip))
|
p.Link.Children.Any(a => a.IPAddress == ip))
|
||||||
|
.Where(p => p.Type == Penalty.PenaltyType.TempBan ||
|
||||||
|
p.Type == Penalty.PenaltyType.Ban ||
|
||||||
|
p.Type == Penalty.PenaltyType.Flag)
|
||||||
.Where(p => p.Active)
|
.Where(p => p.Active)
|
||||||
.Where(p => p.Expires == null || p.Expires > now);
|
.Where(p => p.Expires == null || p.Expires > now);
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
var penaltiesSql = iqPenalties.ToSql();
|
var penaltiesSql = iqPenalties.ToSql();
|
||||||
#endif
|
#endif
|
||||||
@ -256,7 +259,7 @@ namespace SharedLibraryCore.Services
|
|||||||
{
|
{
|
||||||
await internalContext.Clients
|
await internalContext.Clients
|
||||||
.Where(c => c.AliasLinkId == p.LinkId)
|
.Where(c => c.AliasLinkId == p.LinkId)
|
||||||
.ForEachAsync(c => c.Level = Player.Permission.User);
|
.ForEachAsync(c => c.Level = EFClient.Permission.User);
|
||||||
await internalContext.SaveChangesAsync();
|
await internalContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ using System.Diagnostics;
|
|||||||
using Microsoft.EntityFrameworkCore.Query;
|
using Microsoft.EntityFrameworkCore.Query;
|
||||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
using Microsoft.EntityFrameworkCore.Query.Internal;
|
||||||
using Microsoft.EntityFrameworkCore.Storage;
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
|
||||||
namespace SharedLibraryCore
|
namespace SharedLibraryCore
|
||||||
{
|
{
|
||||||
@ -27,12 +28,13 @@ namespace SharedLibraryCore
|
|||||||
#endif
|
#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(Server server = null) => new Player()
|
public static EFClient IW4MAdminClient(Server server = null) => new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = 1,
|
ClientId = 1,
|
||||||
State = Player.ClientState.Connected,
|
State = EFClient.ClientState.Connected,
|
||||||
Level = Player.Permission.Console,
|
Level = EFClient.Permission.Console,
|
||||||
CurrentServer = server
|
CurrentServer = server,
|
||||||
|
Name = "IW4MAdmin"
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string HttpRequest(string location, string header, string headerValue)
|
public static string HttpRequest(string location, string header, string headerValue)
|
||||||
@ -98,16 +100,16 @@ namespace SharedLibraryCore
|
|||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Player.Permission MatchPermission(String str)
|
public static EFClient.Permission MatchPermission(String str)
|
||||||
{
|
{
|
||||||
String lookingFor = str.ToLower();
|
String lookingFor = str.ToLower();
|
||||||
|
|
||||||
for (Player.Permission Perm = Player.Permission.User; Perm < Player.Permission.Console; Perm++)
|
for (EFClient.Permission Perm = EFClient.Permission.User; Perm < EFClient.Permission.Console; Perm++)
|
||||||
if (lookingFor.Contains(Perm.ToString().ToLower())
|
if (lookingFor.Contains(Perm.ToString().ToLower())
|
||||||
|| lookingFor.Contains(CurrentLocalization.LocalizationIndex[$"GLOBAL_PERMISSION_{Perm.ToString().ToUpper()}"].ToLower()))
|
|| lookingFor.Contains(CurrentLocalization.LocalizationIndex[$"GLOBAL_PERMISSION_{Perm.ToString().ToUpper()}"].ToLower()))
|
||||||
return Perm;
|
return Perm;
|
||||||
|
|
||||||
return Player.Permission.Banned;
|
return EFClient.Permission.Banned;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -131,25 +133,25 @@ namespace SharedLibraryCore
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="level">Specified player level</param>
|
/// <param name="level">Specified player level</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static String ConvertLevelToColor(Player.Permission level, string localizedLevel)
|
public static String ConvertLevelToColor(EFClient.Permission level, string localizedLevel)
|
||||||
{
|
{
|
||||||
char colorCode = '6';
|
char colorCode = '6';
|
||||||
// todo: maybe make this game independant?
|
// todo: maybe make this game independant?
|
||||||
switch (level)
|
switch (level)
|
||||||
{
|
{
|
||||||
case Player.Permission.Banned:
|
case EFClient.Permission.Banned:
|
||||||
colorCode = '1';
|
colorCode = '1';
|
||||||
break;
|
break;
|
||||||
case Player.Permission.Flagged:
|
case EFClient.Permission.Flagged:
|
||||||
colorCode = '9';
|
colorCode = '9';
|
||||||
break;
|
break;
|
||||||
case Player.Permission.Owner:
|
case EFClient.Permission.Owner:
|
||||||
colorCode = '5';
|
colorCode = '5';
|
||||||
break;
|
break;
|
||||||
case Player.Permission.User:
|
case EFClient.Permission.User:
|
||||||
colorCode = '2';
|
colorCode = '2';
|
||||||
break;
|
break;
|
||||||
case Player.Permission.Trusted:
|
case EFClient.Permission.Trusted:
|
||||||
colorCode = '3';
|
colorCode = '3';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -159,7 +161,7 @@ namespace SharedLibraryCore
|
|||||||
return $"^{colorCode}{localizedLevel ?? level.ToString()}";
|
return $"^{colorCode}{localizedLevel ?? level.ToString()}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ToLocalizedLevelName(this Player.Permission perm) => CurrentLocalization.LocalizationIndex[$"GLOBAL_PERMISSION_{perm.ToString().ToUpper()}"];
|
public static string ToLocalizedLevelName(this EFClient.Permission perm) => CurrentLocalization.LocalizationIndex[$"GLOBAL_PERMISSION_{perm.ToString().ToUpper()}"];
|
||||||
|
|
||||||
public static String ProcessMessageToken(this Server server, IList<Helpers.MessageToken> tokens, String str)
|
public static String ProcessMessageToken(this Server server, IList<Helpers.MessageToken> tokens, String str)
|
||||||
{
|
{
|
||||||
@ -392,9 +394,9 @@ namespace SharedLibraryCore
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Player AsPlayer(this Database.Models.EFClient client)
|
public static EFClient AsEFClient(this Database.Models.EFClient client)
|
||||||
{
|
{
|
||||||
return client == null ? null : new Player()
|
return client == null ? null : new EFClient()
|
||||||
{
|
{
|
||||||
Active = client.Active,
|
Active = client.Active,
|
||||||
AliasLink = client.AliasLink,
|
AliasLink = client.AliasLink,
|
||||||
@ -419,7 +421,7 @@ namespace SharedLibraryCore
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsPrivileged(this Player p) => p.Level > Player.Permission.User;
|
public static bool IsPrivileged(this EFClient p) => p.Level > EFClient.Permission.User;
|
||||||
|
|
||||||
public static bool PromptBool(string question)
|
public static bool PromptBool(string question)
|
||||||
{
|
{
|
||||||
@ -524,7 +526,7 @@ namespace SharedLibraryCore
|
|||||||
|
|
||||||
public static async Task<string[]> ExecuteCommandAsync(this Server server, string commandName) => await server.RconParser.ExecuteCommandAsync(server.RemoteConnection, commandName);
|
public static async Task<string[]> ExecuteCommandAsync(this Server server, string commandName) => await server.RconParser.ExecuteCommandAsync(server.RemoteConnection, commandName);
|
||||||
|
|
||||||
public static Task<List<Player>> GetStatusAsync(this Server server) => server.RconParser.GetStatusAsync(server.RemoteConnection);
|
public static Task<List<EFClient>> GetStatusAsync(this Server server) => server.RconParser.GetStatusAsync(server.RemoteConnection);
|
||||||
|
|
||||||
public static async Task<Dictionary<string, string>> GetInfoAsync(this Server server)
|
public static async Task<Dictionary<string, string>> GetInfoAsync(this Server server)
|
||||||
{
|
{
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Events;
|
using SharedLibraryCore.Events;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace WebfrontCore.Controllers.API
|
namespace WebfrontCore.Controllers.API
|
||||||
{
|
{
|
||||||
public class ApiController : BaseController
|
public class ApiController : BaseController
|
||||||
{
|
{
|
||||||
public IActionResult Index() => Ok($"IW4MAdmin API");
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return Ok($"IW4MAdmin API");
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult Event(bool shouldConsume = true)
|
public IActionResult Event(bool shouldConsume = true)
|
||||||
@ -28,12 +28,12 @@ namespace WebfrontCore.Controllers.API
|
|||||||
Id = server.GetHashCode(),
|
Id = server.GetHashCode(),
|
||||||
Name = server.Hostname,
|
Name = server.Hostname,
|
||||||
MaxPlayers = server.MaxClients,
|
MaxPlayers = server.MaxClients,
|
||||||
CurrentPlayers = server.GetPlayersAsList().Count,
|
CurrentPlayers = server.GetClientsAsList().Count,
|
||||||
Map = server.CurrentMap,
|
Map = server.CurrentMap,
|
||||||
GameMode = server.Gametype,
|
GameMode = server.Gametype,
|
||||||
Port = server.GetPort(),
|
Port = server.GetPort(),
|
||||||
Game = server.GameName.ToString(),
|
Game = server.GameName.ToString(),
|
||||||
Players = server.GetPlayersAsList()
|
Players = server.GetClientsAsList()
|
||||||
.Select(player => new
|
.Select(player => new
|
||||||
{
|
{
|
||||||
player.Name,
|
player.Name,
|
||||||
@ -53,5 +53,23 @@ namespace WebfrontCore.Controllers.API
|
|||||||
|
|
||||||
return Json(serverInfo);
|
return Json(serverInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult RestartApproved()
|
||||||
|
{
|
||||||
|
var serverToRestart = Manager.GetServers().FirstOrDefault(_server => _server.RestartRequested);
|
||||||
|
|
||||||
|
if (serverToRestart != null)
|
||||||
|
{
|
||||||
|
serverToRestart.RestartRequested = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return serverToRestart != null ?
|
||||||
|
(IActionResult)Json(new
|
||||||
|
{
|
||||||
|
port = serverToRestart.GetPort()
|
||||||
|
}) :
|
||||||
|
Unauthorized();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using WebfrontCore.ViewModels;
|
using WebfrontCore.ViewModels;
|
||||||
using static SharedLibraryCore.Objects.Player;
|
using static SharedLibraryCore.Database.Models.EFClient;
|
||||||
|
|
||||||
namespace WebfrontCore.Controllers
|
namespace WebfrontCore.Controllers
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@ namespace WebfrontCore.Controllers
|
|||||||
Client = Client ?? new EFClient()
|
Client = Client ?? new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = -1,
|
ClientId = -1,
|
||||||
Level = Player.Permission.User,
|
Level = EFClient.Permission.User,
|
||||||
CurrentAlias = new EFAlias() { Name = "Web Console Guest" }
|
CurrentAlias = new EFAlias() { Name = "Web Console Guest" }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ namespace WebfrontCore.Controllers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Client.ClientId = Convert.ToInt32(base.User.Claims.First(c => c.Type == ClaimTypes.Sid).Value);
|
Client.ClientId = Convert.ToInt32(base.User.Claims.First(c => c.Type == ClaimTypes.Sid).Value);
|
||||||
Client.Level = (Player.Permission)Enum.Parse(typeof(Player.Permission), User.Claims.First(c => c.Type == ClaimTypes.Role).Value);
|
Client.Level = (EFClient.Permission)Enum.Parse(typeof(EFClient.Permission), User.Claims.First(c => c.Type == ClaimTypes.Role).Value);
|
||||||
Client.CurrentAlias = new EFAlias() { Name = User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value };
|
Client.CurrentAlias = new EFAlias() { Name = User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value };
|
||||||
var stillExists = Manager.GetPrivilegedClients()[Client.ClientId];
|
var stillExists = Manager.GetPrivilegedClients()[Client.ClientId];
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ namespace WebfrontCore.Controllers
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Client.ClientId = 1;
|
Client.ClientId = 1;
|
||||||
Client.Level = Player.Permission.Console;
|
Client.Level = EFClient.Permission.Console;
|
||||||
Client.CurrentAlias = new EFAlias() { Name = "IW4MAdmin" };
|
Client.CurrentAlias = new EFAlias() { Name = "IW4MAdmin" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Database;
|
using SharedLibraryCore.Database;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
using SharedLibraryCore.Services;
|
using SharedLibraryCore.Services;
|
||||||
using System;
|
using System;
|
||||||
@ -63,7 +64,7 @@ namespace WebfrontCore.Controllers
|
|||||||
var administeredPenaltiesMeta = await Manager.GetPenaltyService()
|
var administeredPenaltiesMeta = await Manager.GetPenaltyService()
|
||||||
.ReadGetClientPenaltiesAsync(client.ClientId, false);
|
.ReadGetClientPenaltiesAsync(client.ClientId, false);
|
||||||
|
|
||||||
if (Authorized && client.Level > SharedLibraryCore.Objects.Player.Permission.Trusted)
|
if (Authorized && client.Level > EFClient.Permission.Trusted)
|
||||||
clientDto.Meta.Add(new ProfileMeta()
|
clientDto.Meta.Add(new ProfileMeta()
|
||||||
{
|
{
|
||||||
Key = Localization["WEBFRONT_CLIENT_META_MASKED"],
|
Key = Localization["WEBFRONT_CLIENT_META_MASKED"],
|
||||||
@ -122,7 +123,7 @@ namespace WebfrontCore.Controllers
|
|||||||
.OrderByDescending(a => a.Level)
|
.OrderByDescending(a => a.Level)
|
||||||
.GroupBy(a => a.LinkId).Select(a => a.First());
|
.GroupBy(a => a.LinkId).Select(a => a.First());
|
||||||
|
|
||||||
var adminsDict = new Dictionary<SharedLibraryCore.Objects.Player.Permission, IList<ClientInfo>>();
|
var adminsDict = new Dictionary<EFClient.Permission, IList<ClientInfo>>();
|
||||||
|
|
||||||
foreach (var admin in admins)
|
foreach (var admin in admins)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
using SharedLibraryCore.Objects;
|
using SharedLibraryCore.Objects;
|
||||||
using System;
|
using System;
|
||||||
@ -29,7 +30,7 @@ namespace WebfrontCore.Controllers
|
|||||||
public async Task<IActionResult> ExecuteAsync(int serverId, string command)
|
public async Task<IActionResult> ExecuteAsync(int serverId, string command)
|
||||||
{
|
{
|
||||||
var server = Manager.GetServers().First(s => s.GetHashCode() == serverId);
|
var server = Manager.GetServers().First(s => s.GetHashCode() == serverId);
|
||||||
var client = new Player()
|
var client = new EFClient()
|
||||||
{
|
{
|
||||||
ClientId = Client.ClientId,
|
ClientId = Client.ClientId,
|
||||||
Level = Client.Level,
|
Level = Client.Level,
|
||||||
|
@ -27,7 +27,7 @@ namespace WebfrontCore.Controllers
|
|||||||
ClientCount = s.ClientNum,
|
ClientCount = s.ClientNum,
|
||||||
MaxClients = s.MaxClients,
|
MaxClients = s.MaxClients,
|
||||||
GameType = s.Gametype,
|
GameType = s.Gametype,
|
||||||
Players = s.GetPlayersAsList()
|
Players = s.GetClientsAsList()
|
||||||
.Select(p => new PlayerInfo
|
.Select(p => new PlayerInfo
|
||||||
{
|
{
|
||||||
Name = p.Name,
|
Name = p.Name,
|
||||||
@ -36,7 +36,7 @@ namespace WebfrontCore.Controllers
|
|||||||
LevelInt = (int)p.Level
|
LevelInt = (int)p.Level
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
ChatHistory = s.ChatHistory,
|
ChatHistory = s.ChatHistory,
|
||||||
PlayerHistory = s.PlayerHistory.ToArray(),
|
PlayerHistory = s.ClientHistory.ToArray(),
|
||||||
};
|
};
|
||||||
return PartialView("_ClientActivity", serverInfo);
|
return PartialView("_ClientActivity", serverInfo);
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@ namespace WebfrontCore.ViewComponents
|
|||||||
ClientCount = s.ClientNum,
|
ClientCount = s.ClientNum,
|
||||||
MaxClients = s.MaxClients,
|
MaxClients = s.MaxClients,
|
||||||
GameType = s.Gametype,
|
GameType = s.Gametype,
|
||||||
PlayerHistory = s.PlayerHistory.ToArray(),
|
PlayerHistory = s.ClientHistory.ToArray(),
|
||||||
Players = s.GetPlayersAsList()
|
Players = s.GetClientsAsList()
|
||||||
.Select(p => new PlayerInfo()
|
.Select(p => new PlayerInfo()
|
||||||
{
|
{
|
||||||
Name = p.Name,
|
Name = p.Name,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
Version 2.3:
|
Version 2.3:
|
||||||
-added configuration option to ignore bots
|
-added configuration option to ignore bots
|
||||||
|
-updated anticheat slightly
|
||||||
|
|
||||||
Version 2.2:
|
Version 2.2:
|
||||||
-upgraded projects to .NET 2.1
|
-upgraded projects to .NET 2.1
|
||||||
|
Loading…
Reference in New Issue
Block a user