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
2
.gitignore
vendored
2
.gitignore
vendored
@ -230,3 +230,5 @@ bootstrap-custom.min.css
|
||||
/DiscordWebhook/config.dev.json
|
||||
/GameLogServer/env
|
||||
launchSettings.json
|
||||
/VpnDetectionPrivate.js
|
||||
/Plugins/ScriptPlugins/VpnDetectionPrivate.js
|
||||
|
@ -6,7 +6,7 @@
|
||||
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
|
||||
<PackageId>RaidMax.IW4MAdmin.Application</PackageId>
|
||||
<Version>2.2.1.0</Version>
|
||||
<Version>2.2.2.0</Version>
|
||||
<Authors>RaidMax</Authors>
|
||||
<Company>Forever None</Company>
|
||||
<Product>IW4MAdmin</Product>
|
||||
@ -31,8 +31,8 @@
|
||||
<PropertyGroup>
|
||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||
<TieredCompilation>true</TieredCompilation>
|
||||
<AssemblyVersion>2.2.1.0</AssemblyVersion>
|
||||
<FileVersion>2.2.1.0</FileVersion>
|
||||
<AssemblyVersion>2.2.2.0</AssemblyVersion>
|
||||
<FileVersion>2.2.2.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,4 +1,5 @@
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -9,16 +10,16 @@ namespace IW4MAdmin.Application.Core
|
||||
{
|
||||
class ClientAuthentication : IClientAuthentication
|
||||
{
|
||||
private Queue<Player> ClientAuthenticationQueue;
|
||||
private Dictionary<long, Player> AuthenticatedClients;
|
||||
private Queue<EFClient> ClientAuthenticationQueue;
|
||||
private Dictionary<long, EFClient> AuthenticatedClients;
|
||||
|
||||
public ClientAuthentication()
|
||||
{
|
||||
ClientAuthenticationQueue = new Queue<Player>();
|
||||
AuthenticatedClients = new Dictionary<long, Player>();
|
||||
ClientAuthenticationQueue = new Queue<EFClient>();
|
||||
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
|
||||
var clientNetworkIds = clients.Select(c => c.NetworkId);
|
||||
@ -33,10 +34,10 @@ namespace IW4MAdmin.Application.Core
|
||||
foreach (var client in clients)
|
||||
{
|
||||
// they've not been authenticated
|
||||
if (!AuthenticatedClients.TryGetValue(client.NetworkId, out Player value))
|
||||
if (!AuthenticatedClients.TryGetValue(client.NetworkId, out EFClient value))
|
||||
{
|
||||
// authenticate them
|
||||
client.State = Player.ClientState.Authenticated;
|
||||
client.State = EFClient.ClientState.Authenticated;
|
||||
AuthenticatedClients.Add(client.NetworkId, client);
|
||||
}
|
||||
else
|
||||
@ -54,16 +55,16 @@ namespace IW4MAdmin.Application.Core
|
||||
// grab each client that's connected via log
|
||||
var clientToAuthenticate = ClientAuthenticationQueue.Dequeue();
|
||||
// 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
|
||||
clientToAuthenticate.State = Player.ClientState.Authenticated;
|
||||
clientToAuthenticate.State = EFClient.ClientState.Authenticated;
|
||||
AuthenticatedClients.Add(clientToAuthenticate.NetworkId, clientToAuthenticate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IList<Player> GetAuthenticatedClients()
|
||||
public IList<EFClient> GetAuthenticatedClients()
|
||||
{
|
||||
if (AuthenticatedClients.Values.Count > 18)
|
||||
{
|
||||
@ -74,7 +75,7 @@ namespace IW4MAdmin.Application.Core
|
||||
return AuthenticatedClients.Values.ToList();
|
||||
}
|
||||
|
||||
public void RequestClientAuthentication(Player client)
|
||||
public void RequestClientAuthentication(EFClient client)
|
||||
{
|
||||
ClientAuthenticationQueue.Enqueue(client);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
|
||||
@ -20,7 +21,7 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
|
||||
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()
|
||||
{
|
||||
@ -41,7 +42,7 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
.Replace("\x15", "")
|
||||
.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] == '@')
|
||||
{
|
||||
@ -70,8 +71,8 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
{
|
||||
if (!server.CustomCallback)
|
||||
{
|
||||
var origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 6));
|
||||
var target = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2));
|
||||
var origin = server.GetClientsAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 6));
|
||||
var target = server.GetClientsAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2));
|
||||
|
||||
return new GameEvent()
|
||||
{
|
||||
@ -86,8 +87,8 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
|
||||
if (eventType == "ScriptKill")
|
||||
{
|
||||
var origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||
var target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
||||
var origin = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||
var target = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
||||
return new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.ScriptKill,
|
||||
@ -100,8 +101,8 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
|
||||
if (eventType == "ScriptDamage")
|
||||
{
|
||||
var origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||
var target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
||||
var origin = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||
var target = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
||||
|
||||
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)
|
||||
{
|
||||
var origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[5].ConvertLong());
|
||||
var target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||
var origin = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[5].ConvertLong());
|
||||
var target = server.GetClientsAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||
|
||||
return new GameEvent()
|
||||
{
|
||||
@ -146,12 +147,12 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
Type = GameEvent.EventType.Join,
|
||||
Data = logLine,
|
||||
Owner = server,
|
||||
Origin = new Player()
|
||||
Origin = new EFClient()
|
||||
{
|
||||
Name = regexMatch.Groups[4].ToString().StripColors(),
|
||||
NetworkId = regexMatch.Groups[2].ToString().ConvertLong(),
|
||||
ClientNumber = Convert.ToInt32(regexMatch.Groups[3].ToString()),
|
||||
State = Player.ClientState.Connecting,
|
||||
State = EFClient.ClientState.Connecting,
|
||||
CurrentServer = server
|
||||
}
|
||||
};
|
||||
@ -185,11 +186,11 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
{
|
||||
Type = GameEvent.EventType.MapEnd,
|
||||
Data = lineSplit[0],
|
||||
Origin = new Player()
|
||||
Origin = new EFClient()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
Target = new Player()
|
||||
Target = new EFClient()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
@ -205,14 +206,8 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
{
|
||||
Type = GameEvent.EventType.MapChange,
|
||||
Data = lineSplit[0],
|
||||
Origin = new Player()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
Target = new Player()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
Origin = Utilities.IW4MAdminClient(server),
|
||||
Target = Utilities.IW4MAdminClient(server),
|
||||
Owner = server,
|
||||
Extra = dump.DictionaryFromKeyValue()
|
||||
};
|
||||
@ -221,14 +216,8 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
return new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Unknown,
|
||||
Origin = new Player()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
Target = new Player()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
Origin = Utilities.IW4MAdminClient(server),
|
||||
Target = Utilities.IW4MAdminClient(server),
|
||||
Owner = server
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
@ -23,7 +24,7 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
|
||||
int clientNum = Int32.Parse(lineSplit[2]);
|
||||
|
||||
var player = new Player()
|
||||
var player = new EFClient()
|
||||
{
|
||||
NetworkId = lineSplit[1].ConvertLong(),
|
||||
ClientNumber = clientNum,
|
||||
@ -33,11 +34,11 @@ namespace IW4MAdmin.Application.EventParsers
|
||||
return new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Join,
|
||||
Origin = new Player()
|
||||
Origin = new EFClient()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
Target = new Player()
|
||||
Target = new EFClient()
|
||||
{
|
||||
ClientId = 1
|
||||
},
|
||||
|
@ -110,7 +110,7 @@ namespace IW4MAdmin.Application
|
||||
var consoleTask = Task.Run(async () =>
|
||||
{
|
||||
String userInput;
|
||||
Player Origin = Utilities.IW4MAdminClient(ServerManager.Servers[0]);
|
||||
var Origin = Utilities.IW4MAdminClient(ServerManager.Servers[0]);
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -19,6 +19,7 @@ using SharedLibraryCore.Events;
|
||||
|
||||
using IW4MAdmin.Application.API.Master;
|
||||
using IW4MAdmin.Application.Migration;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
namespace IW4MAdmin.Application
|
||||
{
|
||||
@ -26,7 +27,7 @@ namespace IW4MAdmin.Application
|
||||
{
|
||||
private List<Server> _servers;
|
||||
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 bool Running { get; private set; }
|
||||
public bool IsInitialized { get; private set; }
|
||||
@ -60,7 +61,7 @@ namespace IW4MAdmin.Application
|
||||
ClientSvc = new ClientService();
|
||||
AliasSvc = new AliasService();
|
||||
PenaltySvc = new PenaltyService();
|
||||
PrivilegedClients = new Dictionary<int, Player>();
|
||||
PrivilegedClients = new Dictionary<int, EFClient>();
|
||||
ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("IW4MAdminSettings");
|
||||
StartTime = DateTime.UtcNow;
|
||||
OnQuit = new ManualResetEventSlim();
|
||||
@ -144,7 +145,7 @@ namespace IW4MAdmin.Application
|
||||
if (e.Target != null)
|
||||
{
|
||||
// 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);
|
||||
// we have to throw out the event because they left
|
||||
if (e.Target == null)
|
||||
@ -285,7 +286,7 @@ namespace IW4MAdmin.Application
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
c.Password,
|
||||
@ -299,7 +300,7 @@ namespace IW4MAdmin.Application
|
||||
{
|
||||
try
|
||||
{
|
||||
PrivilegedClients.Add(a.ClientId, new Player()
|
||||
PrivilegedClients.Add(a.ClientId, new EFClient()
|
||||
{
|
||||
Name = a.Name,
|
||||
ClientId = a.ClientId,
|
||||
@ -593,13 +594,13 @@ namespace IW4MAdmin.Application
|
||||
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 AliasService GetAliasService() => AliasSvc;
|
||||
public PenaltyService GetPenaltyService() => PenaltySvc;
|
||||
public IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings() => ConfigHandler;
|
||||
public IDictionary<int, Player> GetPrivilegedClients() => PrivilegedClients;
|
||||
public IDictionary<int, EFClient> GetPrivilegedClients() => PrivilegedClients;
|
||||
public bool ShutdownRequested() => !Running;
|
||||
public IEventHandler GetEventHandler() => Handler;
|
||||
|
||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.RCon;
|
||||
using SharedLibraryCore.Exceptions;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
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");
|
||||
return ClientsFromStatus(response);
|
||||
@ -74,9 +75,9 @@ namespace IW4MAdmin.Application.RconParsers
|
||||
|
||||
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)
|
||||
throw new ServerException("Unexpected status response received");
|
||||
@ -106,7 +107,7 @@ namespace IW4MAdmin.Application.RconParsers
|
||||
string name = regex.Groups[5].Value.StripColors().Trim();
|
||||
int ip = regex.Groups[7].Value.Split(':')[0].ConvertToIP();
|
||||
|
||||
Player P = new Player()
|
||||
var P = new EFClient()
|
||||
{
|
||||
Name = name,
|
||||
NetworkId = networkId,
|
||||
@ -115,7 +116,7 @@ namespace IW4MAdmin.Application.RconParsers
|
||||
Ping = ping,
|
||||
Score = score,
|
||||
IsBot = ip == 0,
|
||||
State = Player.ClientState.Connecting
|
||||
State = EFClient.ClientState.Connecting
|
||||
};
|
||||
StatusPlayers.Add(P);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore.RCon;
|
||||
using SharedLibraryCore.Exceptions;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
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");
|
||||
return ClientsFromStatus(response);
|
||||
@ -118,9 +119,9 @@ namespace IW4MAdmin.Application.RconParsers
|
||||
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)
|
||||
{
|
||||
@ -145,7 +146,7 @@ namespace IW4MAdmin.Application.RconParsers
|
||||
regex = Regex.Match(responseLine, @" +(\d+ +){3}");
|
||||
int score = Int32.Parse(regex.Value.Split(' ', StringSplitOptions.RemoveEmptyEntries)[0]);
|
||||
|
||||
var p = new Player()
|
||||
var p = new EFClient()
|
||||
{
|
||||
Name = name,
|
||||
NetworkId = networkId,
|
||||
@ -154,7 +155,7 @@ namespace IW4MAdmin.Application.RconParsers
|
||||
Ping = Ping,
|
||||
Score = score,
|
||||
IsBot = false,
|
||||
State = Player.ClientState.Connecting
|
||||
State = EFClient.ClientState.Connecting
|
||||
};
|
||||
|
||||
StatusPlayers.Add(p);
|
||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore.RCon;
|
||||
using SharedLibraryCore.Exceptions;
|
||||
using System.Text;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
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");
|
||||
return ClientsFromStatus(response);
|
||||
@ -73,9 +74,9 @@ namespace IW4MAdmin.Application.RconParsers
|
||||
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)
|
||||
{
|
||||
@ -98,7 +99,7 @@ namespace IW4MAdmin.Application.RconParsers
|
||||
#endif
|
||||
int ipAddress = regex.Value.Split(':')[0].ConvertToIP();
|
||||
regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+");
|
||||
var p = new Player()
|
||||
var p = new EFClient()
|
||||
{
|
||||
Name = name,
|
||||
NetworkId = networkId,
|
||||
@ -106,7 +107,7 @@ namespace IW4MAdmin.Application.RconParsers
|
||||
IPAddress = ipAddress,
|
||||
Ping = Ping,
|
||||
Score = 0,
|
||||
State = Player.ClientState.Connecting,
|
||||
State = EFClient.ClientState.Connecting,
|
||||
IsBot = networkId == 0
|
||||
};
|
||||
|
||||
|
@ -1,24 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using IW4MAdmin.Application.EventParsers;
|
||||
using IW4MAdmin.Application.IO;
|
||||
using IW4MAdmin.Application.RconParsers;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore.Configuration;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Dtos;
|
||||
using SharedLibraryCore.Configuration;
|
||||
using SharedLibraryCore.Exceptions;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Localization;
|
||||
|
||||
using IW4MAdmin.Application.RconParsers;
|
||||
using IW4MAdmin.Application.EventParsers;
|
||||
using IW4MAdmin.Application.IO;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IW4MAdmin
|
||||
{
|
||||
@ -58,234 +56,101 @@ namespace IW4MAdmin
|
||||
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 ||
|
||||
(existingClient.NetworkId != logClient.NetworkId &&
|
||||
existingClient.State != Player.ClientState.Connected))
|
||||
if (existingClient != null)
|
||||
{
|
||||
Logger.WriteDebug($"Log detected {logClient} joining");
|
||||
Players[logClient.ClientNumber] = logClient;
|
||||
await existingClient.OnJoin(polledClient.IPAddress);
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
override public async Task<bool> AddPlayer(Player polledPlayer)
|
||||
override public async Task OnClientConnected(EFClient clientFromLog)
|
||||
{
|
||||
if ((polledPlayer.Ping == 999 && !polledPlayer.IsBot) ||
|
||||
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");
|
||||
Logger.WriteDebug($"Client slot #{clientFromLog.ClientNumber} now reserved");
|
||||
|
||||
try
|
||||
{
|
||||
Player player = null;
|
||||
var client = await Manager.GetClientService().GetUnique(polledPlayer.NetworkId);
|
||||
EFClient client = await Manager.GetClientService().GetUnique(clientFromLog.NetworkId);
|
||||
|
||||
// first time client is connecting to server
|
||||
if (client == null)
|
||||
{
|
||||
Logger.WriteDebug($"Client {polledPlayer} first time connecting");
|
||||
player = (await Manager.GetClientService().Create(polledPlayer)).AsPlayer();
|
||||
Logger.WriteDebug($"Client {clientFromLog} first time connecting");
|
||||
client = await Manager.GetClientService().Create(clientFromLog);
|
||||
}
|
||||
|
||||
// client has connected in the past
|
||||
else
|
||||
{
|
||||
client.LastConnection = DateTime.UtcNow;
|
||||
client.Connections += 1;
|
||||
|
||||
var existingAlias = client.AliasLink.Children
|
||||
.FirstOrDefault(a => a.Name == polledPlayer.Name && a.IPAddress == polledPlayer.IPAddress);
|
||||
.FirstOrDefault(a => a.Name == clientFromLog.Name);
|
||||
|
||||
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()
|
||||
{
|
||||
IPAddress = polledPlayer.IPAddress,
|
||||
Name = polledPlayer.Name,
|
||||
// this gets updated on client join
|
||||
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
|
||||
{
|
||||
client.CurrentAlias = existingAlias;
|
||||
client.CurrentAliasId = existingAlias.AliasId;
|
||||
client.Name = existingAlias.Name;
|
||||
client.IPAddress = existingAlias.IPAddress;
|
||||
}
|
||||
|
||||
await Manager.GetClientService().Update(client);
|
||||
player = client.AsPlayer();
|
||||
}
|
||||
|
||||
// reserved slots stuff
|
||||
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...");
|
||||
Logger.WriteInfo($"Client {client} connected...");
|
||||
|
||||
// Do the player specific stuff
|
||||
player.ClientNumber = polledPlayer.ClientNumber;
|
||||
player.IsBot = polledPlayer.IsBot;
|
||||
player.Score = polledPlayer.Score;
|
||||
player.CurrentServer = this;
|
||||
client.ClientNumber = clientFromLog.ClientNumber;
|
||||
client.IsBot = clientFromLog.IsBot;
|
||||
client.Score = clientFromLog.Score;
|
||||
client.Ping = clientFromLog.Ping;
|
||||
client.CurrentServer = this;
|
||||
|
||||
player.DelayedEvents = (Players[player.ClientNumber]?.DelayedEvents) ?? new Queue<GameEvent>();
|
||||
Players[player.ClientNumber] = player;
|
||||
Clients[client.ClientNumber] = client;
|
||||
client.OnConnect();
|
||||
|
||||
var activePenalties = await Manager.GetPenaltyService().GetActivePenaltiesAsync(player.AliasLinkId, player.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 (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;
|
||||
client.State = EFClient.ClientState.Connected;
|
||||
}
|
||||
|
||||
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.StackTrace);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//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
|
||||
if (Leaving.State != Player.ClientState.Connected)
|
||||
if (Leaving.State != EFClient.ClientState.Connected)
|
||||
{
|
||||
Players[cNum] = null;
|
||||
Clients[cNum] = null;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Logger.WriteInfo($"Client {Leaving} [{Leaving.State.ToString().ToLower()}] disconnecting...");
|
||||
Leaving.State = Player.ClientState.Disconnecting;
|
||||
Leaving.State = EFClient.ClientState.Disconnecting;
|
||||
Leaving.TotalConnectionTime += Leaving.ConnectionLength;
|
||||
Leaving.LastConnection = DateTime.UtcNow;
|
||||
await Manager.GetClientService().Update(Leaving);
|
||||
Players[cNum] = null;
|
||||
Clients[cNum] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -340,7 +205,7 @@ namespace IW4MAdmin
|
||||
if (E.Type == GameEvent.EventType.Command &&
|
||||
E.Extra != null &&
|
||||
(canExecuteCommand ||
|
||||
E.Origin?.Level == Player.Permission.Console))
|
||||
E.Origin?.Level == EFClient.Permission.Console))
|
||||
{
|
||||
await (((Command)E.Extra).ExecuteAsync(E));
|
||||
}
|
||||
@ -355,25 +220,17 @@ namespace IW4MAdmin
|
||||
{
|
||||
if (E.Type == GameEvent.EventType.Connect)
|
||||
{
|
||||
E.Origin.State = Player.ClientState.Authenticated;
|
||||
// add them to the server
|
||||
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];
|
||||
E.Origin.State = EFClient.ClientState.Authenticated;
|
||||
await OnClientConnected(E.Origin);
|
||||
|
||||
ChatHistory.Add(new ChatInfo()
|
||||
{
|
||||
Name = E.Origin?.Name ?? "ERROR!",
|
||||
Name = E.Origin.Name,
|
||||
Message = "CONNECTED",
|
||||
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));
|
||||
}
|
||||
@ -381,7 +238,7 @@ namespace IW4MAdmin
|
||||
|
||||
else if (E.Type == GameEvent.EventType.Join)
|
||||
{
|
||||
await OnPlayerJoined(E.Origin);
|
||||
await OnClientJoined(E.Origin);
|
||||
}
|
||||
|
||||
else if (E.Type == GameEvent.EventType.Flag)
|
||||
@ -446,11 +303,11 @@ namespace IW4MAdmin
|
||||
|
||||
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 &&
|
||||
// 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
|
||||
origin.ConnectionLength < Manager.GetApplicationSettings().Configuration().RConPollRate)
|
||||
{
|
||||
@ -465,9 +322,9 @@ namespace IW4MAdmin
|
||||
}
|
||||
|
||||
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;
|
||||
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");
|
||||
}
|
||||
@ -569,12 +426,16 @@ namespace IW4MAdmin
|
||||
}
|
||||
|
||||
while (ChatHistory.Count > Math.Ceiling((double)ClientNum / 2))
|
||||
{
|
||||
ChatHistory.RemoveAt(0);
|
||||
}
|
||||
|
||||
// the last client hasn't fully disconnected yet
|
||||
// so there will still be at least 1 client left
|
||||
if (ClientNum < 2)
|
||||
{
|
||||
ChatHistory.Clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -585,12 +446,12 @@ namespace IW4MAdmin
|
||||
/// array index 1 = disconnecting clients
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
async Task<IList<Player>[]> PollPlayersAsync()
|
||||
async Task<IList<EFClient>[]> PollPlayersAsync()
|
||||
{
|
||||
#if DEBUG
|
||||
var now = DateTime.Now;
|
||||
#endif
|
||||
var currentClients = GetPlayersAsList();
|
||||
var currentClients = GetClientsAsList();
|
||||
var polledClients = (await this.GetStatusAsync()).AsEnumerable();
|
||||
if (this.Manager.GetApplicationSettings().Configuration().IgnoreBots)
|
||||
{
|
||||
@ -604,15 +465,15 @@ namespace IW4MAdmin
|
||||
foreach (var client in polledClients)
|
||||
{
|
||||
// todo: move out somehwere
|
||||
var existingClient = Players[client.ClientNumber] ?? client;
|
||||
var existingClient = Clients[client.ClientNumber] ?? client;
|
||||
existingClient.Ping = client.Ping;
|
||||
existingClient.Score = client.Score;
|
||||
}
|
||||
|
||||
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;
|
||||
@ -626,11 +487,13 @@ namespace IW4MAdmin
|
||||
if (Manager.ShutdownRequested())
|
||||
{
|
||||
// todo: fix up disconnect
|
||||
//for (int i = 0; i < Players.Count; i++)
|
||||
// await RemovePlayer(i);
|
||||
//for (int i = 0; i < EFClients.Count; i++)
|
||||
// await RemoveClient(i);
|
||||
|
||||
foreach (var plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins)
|
||||
{
|
||||
await plugin.OnUnloadAsync();
|
||||
}
|
||||
}
|
||||
|
||||
// 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])
|
||||
{
|
||||
if (disconnectingClient.State == Player.ClientState.Disconnecting)
|
||||
if (disconnectingClient.State == EFClient.ClientState.Disconnecting)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -669,8 +532,8 @@ namespace IW4MAdmin
|
||||
foreach (var client in polledClients[0])
|
||||
{
|
||||
// this prevents duplicate events from being sent to the event api
|
||||
if (GetPlayersAsList().Count(c => c.NetworkId == client.NetworkId &&
|
||||
c.State == Player.ClientState.Connected) != 0)
|
||||
if (GetClientsAsList().Count(c => c.NetworkId == client.NetworkId &&
|
||||
c.State == EFClient.ClientState.Connected) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -730,9 +593,12 @@ namespace IW4MAdmin
|
||||
// update the player history
|
||||
if ((lastCount - playerCountStart).TotalMinutes >= SharedLibraryCore.Helpers.PlayerHistory.UpdateInterval)
|
||||
{
|
||||
while (PlayerHistory.Count > ((60 / SharedLibraryCore.Helpers.PlayerHistory.UpdateInterval) * 12)) // 12 times a hour for 12 hours
|
||||
PlayerHistory.Dequeue();
|
||||
PlayerHistory.Enqueue(new SharedLibraryCore.Helpers.PlayerHistory(ClientNum));
|
||||
while (ClientHistory.Count > ((60 / SharedLibraryCore.Helpers.PlayerHistory.UpdateInterval) * 12)) // 12 times a hour for 12 hours
|
||||
{
|
||||
ClientHistory.Dequeue();
|
||||
}
|
||||
|
||||
ClientHistory.Enqueue(new SharedLibraryCore.Helpers.PlayerHistory(ClientNum));
|
||||
playerCountStart = DateTime.Now;
|
||||
}
|
||||
|
||||
@ -782,7 +648,9 @@ namespace IW4MAdmin
|
||||
new IW3RConParser();
|
||||
|
||||
if (ServerConfig.UseIW5MParser)
|
||||
{
|
||||
RconParser = new IW5MRConParser();
|
||||
}
|
||||
|
||||
var version = await this.GetDvarAsync<string>("version");
|
||||
GameName = Utilities.GetGame(version.Value);
|
||||
@ -793,16 +661,26 @@ namespace IW4MAdmin
|
||||
RconParser = new IW4RConParser();
|
||||
}
|
||||
else if (GameName == Game.IW5)
|
||||
{
|
||||
EventParser = new IW5EventParser();
|
||||
}
|
||||
else if (GameName == Game.T5M)
|
||||
{
|
||||
EventParser = new T5MEventParser();
|
||||
}
|
||||
else if (GameName == Game.T6M)
|
||||
{
|
||||
EventParser = new T6MEventParser();
|
||||
}
|
||||
else
|
||||
{
|
||||
EventParser = new IW3EventParser(); // this uses the 'main' folder for log paths
|
||||
}
|
||||
|
||||
if (GameName == Game.UKN)
|
||||
{
|
||||
Logger.WriteWarning($"Game name not recognized: {version}");
|
||||
}
|
||||
|
||||
var infoResponse = await this.GetInfoAsync();
|
||||
// this is normally slow, but I'm only doing it because different games have different prefixes
|
||||
@ -906,7 +784,7 @@ namespace IW4MAdmin
|
||||
#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
|
||||
if (Target.ClientNumber < 0)
|
||||
@ -948,7 +826,7 @@ namespace IW4MAdmin
|
||||
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
|
||||
if (Target.ClientNumber < 0)
|
||||
@ -971,7 +849,7 @@ namespace IW4MAdmin
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
await Target.CurrentServer.RemovePlayer(Target.ClientNumber);
|
||||
await Target.CurrentServer.RemoveClient(Target.ClientNumber);
|
||||
#endif
|
||||
|
||||
var newPenalty = new Penalty()
|
||||
@ -988,7 +866,7 @@ namespace IW4MAdmin
|
||||
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
|
||||
if (Target.ClientNumber < 0)
|
||||
@ -1009,7 +887,7 @@ namespace IW4MAdmin
|
||||
await Target.CurrentServer.ExecuteCommandAsync(formattedKick);
|
||||
}
|
||||
#else
|
||||
await Target.CurrentServer.RemovePlayer(Target.ClientNumber);
|
||||
await Target.CurrentServer.RemoveClient(Target.ClientNumber);
|
||||
#endif
|
||||
|
||||
Penalty newPenalty = new Penalty()
|
||||
@ -1027,15 +905,15 @@ namespace IW4MAdmin
|
||||
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
|
||||
if (Target.ClientNumber < 0)
|
||||
{
|
||||
Player ingameClient = null;
|
||||
EFClient ingameClient = null;
|
||||
|
||||
ingameClient = Manager.GetServers()
|
||||
.Select(s => s.GetPlayersAsList())
|
||||
.Select(s => s.GetClientsAsList())
|
||||
.FirstOrDefault(l => l.FirstOrDefault(c => c.ClientId == Target.ClientId) != null)
|
||||
?.First(c => c.ClientId == Target.ClientId);
|
||||
|
||||
@ -1049,13 +927,13 @@ namespace IW4MAdmin
|
||||
else
|
||||
{
|
||||
// this is set only because they're still in the server.
|
||||
Target.Level = Player.Permission.Banned;
|
||||
Target.Level = EFClient.Permission.Banned;
|
||||
|
||||
#if !DEBUG
|
||||
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);
|
||||
#else
|
||||
await Target.CurrentServer.RemovePlayer(Target.ClientNumber);
|
||||
await Target.CurrentServer.RemoveClient(Target.ClientNumber);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1077,7 +955,7 @@ namespace IW4MAdmin
|
||||
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()
|
||||
{
|
||||
|
@ -27,6 +27,11 @@
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Prerelease' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<OutputPath>bin\Prerelease\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DiscordWebhook.py" />
|
||||
</ItemGroup>
|
||||
@ -50,7 +55,7 @@
|
||||
<Publish>True</Publish>
|
||||
</Content>
|
||||
</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
|
||||
Visual Studio and specify your pre- and post-build commands in
|
||||
the BeforeBuild and AfterBuild targets below. -->
|
||||
@ -59,7 +64,7 @@
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
<ProjectExtensions>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
|
@ -27,10 +27,16 @@
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Prerelease' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
|
||||
<OutputPath>bin\Prerelease\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="GameLogServer\log_reader.py">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="GameLogServer\restart_resource.py" />
|
||||
<Compile Include="GameLogServer\server.py">
|
||||
<SubType>Code</SubType>
|
||||
</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_restful import Api
|
||||
from .log_resource import LogResource
|
||||
from .restart_resource import RestartResource
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
def init():
|
||||
api = Api(app)
|
||||
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
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.16
|
||||
@ -41,6 +40,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ScriptPlugins", "ScriptPlug
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Plugins\ScriptPlugins\SharedGUIDKick.js = Plugins\ScriptPlugins\SharedGUIDKick.js
|
||||
Plugins\ScriptPlugins\VPNDetection.js = Plugins\ScriptPlugins\VPNDetection.js
|
||||
Plugins\ScriptPlugins\VpnDetectionPrivate.js = Plugins\ScriptPlugins\VpnDetectionPrivate.js
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "GameLogServer", "GameLogServer\GameLogServer.pyproj", "{42EFDA12-10D3-4C40-A210-9483520116BC}"
|
||||
|
@ -17,7 +17,7 @@
|
||||
<SuppressCollectPythonCloudServiceFiles>true</SuppressCollectPythonCloudServiceFiles>
|
||||
<Name>Master</Name>
|
||||
<RootNamespace>Master</RootNamespace>
|
||||
<InterpreterId>MSBuild|dev_env|$(MSBuildProjectFullPath)</InterpreterId>
|
||||
<InterpreterId>MSBuild|env|X:\IW4MAdmin\GameLogServer\GameLogServer.pyproj</InterpreterId>
|
||||
<IsWindowsApplication>False</IsWindowsApplication>
|
||||
<PythonRunWebServerCommand>
|
||||
</PythonRunWebServerCommand>
|
||||
@ -111,23 +111,15 @@
|
||||
<Folder Include="master\templates\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="FolderProfile.pubxml" />
|
||||
<Content Include="master\config\master.json" />
|
||||
<Content Include="master\templates\serverlist.html" />
|
||||
<None Include="Release.pubxml" />
|
||||
<Content Include="requirements.txt" />
|
||||
<Content Include="master\templates\index.html" />
|
||||
<Content Include="master\templates\layout.html" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Interpreter Include="dev_env\">
|
||||
<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>
|
||||
<InterpreterReference Include="MSBuild|env|X:\IW4MAdmin\GameLogServer\GameLogServer.pyproj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.Web.targets" />
|
||||
<!-- 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
|
||||
Flask==0.12.2
|
||||
Flask==1.0.2
|
||||
Flask-JWT==0.3.2
|
||||
Flask-JWT-Extended==3.8.1
|
||||
Flask-RESTful==0.3.6
|
||||
@ -8,9 +8,15 @@ itsdangerous==0.24
|
||||
Jinja2==2.10
|
||||
MarkupSafe==1.0
|
||||
marshmallow==3.0.0b8
|
||||
pip==9.0.1
|
||||
pip==9.0.3
|
||||
PyJWT==1.4.2
|
||||
pytz==2018.4
|
||||
pytz==2018.5
|
||||
setuptools==39.0.1
|
||||
six==1.11.0
|
||||
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.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -17,15 +18,15 @@ namespace IW4ScriptCommands.Commands
|
||||
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)
|
||||
.Select(c => c.Split(','))
|
||||
.Select(c => new TeamAssignment()
|
||||
{
|
||||
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,
|
||||
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(server.Players.FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0])).ClientId, server.GetHashCode())
|
||||
Num = server.GetClientsAsList().FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0]))?.ClientNumber ?? -1,
|
||||
Stats = IW4MAdmin.Plugins.Stats.Plugin.Manager.GetClientStats(server.Clients.FirstOrDefault(p => p.ClientNumber == Int32.Parse(c[0])).ClientId, server.GetHashCode())
|
||||
})
|
||||
.ToList();
|
||||
|
||||
@ -39,7 +40,7 @@ namespace IW4ScriptCommands.Commands
|
||||
|
||||
List<string> teamAssignments = new List<string>();
|
||||
|
||||
var _c = server.GetPlayersAsList();
|
||||
var _c = server.GetClientsAsList();
|
||||
if (isDisconnect && client != null)
|
||||
{
|
||||
_c = _c.Where(c => c.ClientNumber != client.ClientNumber).ToList();
|
||||
|
@ -6,6 +6,7 @@
|
||||
<RuntimeFrameworkVersion>2.1.5</RuntimeFrameworkVersion>
|
||||
<ApplicationIcon />
|
||||
<StartupObject />
|
||||
<Configurations>Debug;Release;Prerelease</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
|
@ -1,4 +1,5 @@
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -8,7 +9,7 @@ namespace IW4MAdmin.Plugins.Login.Commands
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Configuration;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Exceptions;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
@ -38,11 +39,11 @@ namespace IW4MAdmin.Plugins.Login
|
||||
|
||||
if (E.Type == GameEvent.EventType.Command)
|
||||
{
|
||||
if (E.Origin.Level < Player.Permission.Moderator ||
|
||||
E.Origin.Level == Player.Permission.Console)
|
||||
if (E.Origin.Level < EFClient.Permission.Moderator ||
|
||||
E.Origin.Level == EFClient.Permission.Console)
|
||||
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 &&
|
||||
client?.Password == null)
|
||||
|
@ -5,6 +5,7 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Configuration;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
|
||||
@ -48,7 +49,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
||||
|
||||
if (containsObjectionalWord)
|
||||
{
|
||||
E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, new Player()
|
||||
E.Origin.Kick(Settings.Configuration().ProfanityKickMessage, new EFClient()
|
||||
{
|
||||
ClientId = 1,
|
||||
CurrentServer = E.Owner
|
||||
@ -85,7 +86,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
||||
var clientProfanity = ProfanityCounts[E.Origin.ClientId];
|
||||
if (clientProfanity.Infringements >= Settings.Configuration().KickAfterInfringementCount)
|
||||
{
|
||||
clientProfanity.Client.Kick(Settings.Configuration().ProfanityKickMessage, new Player()
|
||||
clientProfanity.Client.Kick(Settings.Configuration().ProfanityKickMessage, new EFClient()
|
||||
{
|
||||
ClientId = 1,
|
||||
CurrentServer = E.Owner
|
||||
@ -96,7 +97,7 @@ namespace IW4MAdmin.Plugins.ProfanityDeterment
|
||||
{
|
||||
clientProfanity.Infringements++;
|
||||
|
||||
clientProfanity.Client.Warn(Settings.Configuration().ProfanityWarningMessage, new Player()
|
||||
clientProfanity.Client.Warn(Settings.Configuration().ProfanityWarningMessage, new EFClient()
|
||||
{
|
||||
ClientId = 1,
|
||||
CurrentServer = E.Owner
|
||||
|
@ -1,16 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
|
||||
namespace IW4MAdmin.Plugins.ProfanityDeterment
|
||||
{
|
||||
class Tracking
|
||||
{
|
||||
public Player Client { get; private set; }
|
||||
public EFClient Client { get; private set; }
|
||||
public int Infringements { get; set; }
|
||||
|
||||
public Tracking(Player client)
|
||||
public Tracking(EFClient client)
|
||||
{
|
||||
Client = client;
|
||||
Infringements = 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
using SharedLibraryCore.Helpers;
|
||||
using IW4MAdmin.Plugins.Stats.Models;
|
||||
using SharedLibraryCore.Helpers;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
using IW4MAdmin.Plugins.Stats.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -20,7 +20,9 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
};
|
||||
|
||||
public ChangeTracking<EFACSnapshot> Tracker { get; private set; }
|
||||
public const int QUEUE_COUNT = 10;
|
||||
|
||||
public List<EFClientKill> QueuedHits { get; set; }
|
||||
int Kills;
|
||||
int HitCount;
|
||||
Dictionary<IW4Info.HitLocation, int> HitLocationCount;
|
||||
@ -37,10 +39,14 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
Log = log;
|
||||
HitLocationCount = new Dictionary<IW4Info.HitLocation, int>();
|
||||
foreach (var loc in Enum.GetValues(typeof(IW4Info.HitLocation)))
|
||||
{
|
||||
HitLocationCount.Add((IW4Info.HitLocation)loc, 0);
|
||||
}
|
||||
|
||||
ClientStats = clientStats;
|
||||
Strain = new Strain();
|
||||
Tracker = new ChangeTracking<EFACSnapshot>();
|
||||
QueuedHits = new List<EFClientKill>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -56,10 +62,12 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
hit.HitLoc == IW4Info.HitLocation.none || hit.TimeOffset - LastOffset < 0 ||
|
||||
// hack: prevents false positives
|
||||
(LastWeapon != hit.Weapon && (hit.TimeOffset - LastOffset) == 50))
|
||||
{
|
||||
return new DetectionPenaltyResult()
|
||||
{
|
||||
ClientPenalty = Penalty.PenaltyType.Any,
|
||||
};
|
||||
}
|
||||
|
||||
DetectionPenaltyResult result = null;
|
||||
LastWeapon = hit.Weapon;
|
||||
@ -141,7 +149,6 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
ClientStats.MaxStrain = currentStrain;
|
||||
}
|
||||
|
||||
|
||||
// flag
|
||||
if (currentStrain > Thresholds.MaxStrainFlag)
|
||||
{
|
||||
@ -201,7 +208,10 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
||||
var sb = new StringBuilder();
|
||||
foreach (var kvp in HitLocationCount)
|
||||
{
|
||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||
}
|
||||
|
||||
Log.WriteDebug(sb.ToString());
|
||||
|
||||
result = new DetectionPenaltyResult()
|
||||
@ -222,7 +232,10 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
Log.WriteDebug($"**MaxRatio {maxHeadshotLerpValueForFlag}");
|
||||
var sb = new StringBuilder();
|
||||
foreach (var kvp in HitLocationCount)
|
||||
{
|
||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||
}
|
||||
|
||||
Log.WriteDebug(sb.ToString());
|
||||
|
||||
result = new DetectionPenaltyResult()
|
||||
@ -251,7 +264,10 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
Log.WriteDebug($"**MaxRatio {maxBoneRatioLerpValueForBan}");
|
||||
var sb = new StringBuilder();
|
||||
foreach (var kvp in HitLocationCount)
|
||||
{
|
||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||
}
|
||||
|
||||
Log.WriteDebug(sb.ToString());
|
||||
|
||||
result = new DetectionPenaltyResult()
|
||||
@ -272,7 +288,10 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
Log.WriteDebug($"**MaxRatio {maxBoneRatioLerpValueForFlag}");
|
||||
var sb = new StringBuilder();
|
||||
foreach (var kvp in HitLocationCount)
|
||||
{
|
||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||
}
|
||||
|
||||
Log.WriteDebug(sb.ToString());
|
||||
|
||||
result = new DetectionPenaltyResult()
|
||||
@ -306,15 +325,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
|
||||
if (currentChestAbdomenRatio > chestAbdomenLerpValueForBan && chestHits >= Thresholds.MediumSampleMinKills + 30)
|
||||
{
|
||||
Log.WriteDebug("**Maximum Chest/Abdomen Ratio Reached For Ban**");
|
||||
Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
||||
Log.WriteDebug($"**Chest Hits: {chestHits}");
|
||||
Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||
Log.WriteDebug($"**MaxRatio {chestAbdomenLerpValueForBan}");
|
||||
var sb = new StringBuilder();
|
||||
foreach (var kvp in HitLocationCount)
|
||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||
Log.WriteDebug(sb.ToString());
|
||||
//Log.WriteDebug("**Maximum Chest/Abdomen Ratio Reached For Ban**");
|
||||
//Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
||||
//Log.WriteDebug($"**Chest Hits: {chestHits}");
|
||||
//Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||
//Log.WriteDebug($"**MaxRatio {chestAbdomenLerpValueForBan}");
|
||||
//var sb = new StringBuilder();
|
||||
//foreach (var kvp in HitLocationCount)
|
||||
// sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||
//Log.WriteDebug(sb.ToString());
|
||||
|
||||
result = new DetectionPenaltyResult()
|
||||
{
|
||||
@ -327,16 +346,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.WriteDebug("**Maximum Chest/Abdomen Ratio Reached For Flag**");
|
||||
Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
||||
Log.WriteDebug($"**Chest Hits: {chestHits}");
|
||||
Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||
Log.WriteDebug($"**MaxRatio {chestAbdomenRatioLerpValueForFlag}");
|
||||
var sb = new StringBuilder();
|
||||
foreach (var kvp in HitLocationCount)
|
||||
sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||
Log.WriteDebug(sb.ToString());
|
||||
// Log.WriteDebug($"ThresholdReached: {AboveThresholdCount}");
|
||||
//Log.WriteDebug("**Maximum Chest/Abdomen Ratio Reached For Flag**");
|
||||
//Log.WriteDebug($"ClientId: {hit.AttackerId}");
|
||||
//Log.WriteDebug($"**Chest Hits: {chestHits}");
|
||||
//Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||
//Log.WriteDebug($"**MaxRatio {chestAbdomenRatioLerpValueForFlag}");
|
||||
//var sb = new StringBuilder();
|
||||
//foreach (var kvp in HitLocationCount)
|
||||
// sb.Append($"HitLocation: {kvp.Key} -> {kvp.Value}\r\n");
|
||||
//Log.WriteDebug(sb.ToString());
|
||||
|
||||
result = new DetectionPenaltyResult()
|
||||
{
|
||||
@ -407,15 +425,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
|
||||
if (currentChestAbdomenRatio > chestAbdomenLerpValueForBan)
|
||||
{
|
||||
Log.WriteDebug("**Maximum Lifetime Chest/Abdomen Ratio Reached For Ban**");
|
||||
Log.WriteDebug($"ClientId: {stats.ClientId}");
|
||||
Log.WriteDebug($"**Total Chest Hits: {totalChestHits}");
|
||||
Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||
Log.WriteDebug($"**MaxRatio {chestAbdomenLerpValueForBan}");
|
||||
var sb = new StringBuilder();
|
||||
foreach (var location in stats.HitLocations)
|
||||
sb.Append($"HitLocation: {location.Location} -> {location.HitCount}\r\n");
|
||||
Log.WriteDebug(sb.ToString());
|
||||
//Log.WriteDebug("**Maximum Lifetime Chest/Abdomen Ratio Reached For Ban**");
|
||||
//Log.WriteDebug($"ClientId: {stats.ClientId}");
|
||||
//Log.WriteDebug($"**Total Chest Hits: {totalChestHits}");
|
||||
//Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||
//Log.WriteDebug($"**MaxRatio {chestAbdomenLerpValueForBan}");
|
||||
//var sb = new StringBuilder();
|
||||
//foreach (var location in stats.HitLocations)
|
||||
// sb.Append($"HitLocation: {location.Location} -> {location.HitCount}\r\n");
|
||||
//Log.WriteDebug(sb.ToString());
|
||||
|
||||
return new DetectionPenaltyResult()
|
||||
{
|
||||
@ -428,15 +446,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.WriteDebug("**Maximum Lifetime Chest/Abdomen Ratio Reached For Flag**");
|
||||
Log.WriteDebug($"ClientId: {stats.ClientId}");
|
||||
Log.WriteDebug($"**Total Chest Hits: {totalChestHits}");
|
||||
Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||
Log.WriteDebug($"**MaxRatio {chestAbdomenRatioLerpValueForFlag}");
|
||||
var sb = new StringBuilder();
|
||||
foreach (var location in stats.HitLocations)
|
||||
sb.Append($"HitLocation: {location.Location} -> {location.HitCount}\r\n");
|
||||
Log.WriteDebug(sb.ToString());
|
||||
//Log.WriteDebug("**Maximum Lifetime Chest/Abdomen Ratio Reached For Flag**");
|
||||
//Log.WriteDebug($"ClientId: {stats.ClientId}");
|
||||
//Log.WriteDebug($"**Total Chest Hits: {totalChestHits}");
|
||||
//Log.WriteDebug($"**Ratio {currentChestAbdomenRatio}");
|
||||
//Log.WriteDebug($"**MaxRatio {chestAbdomenRatioLerpValueForFlag}");
|
||||
//var sb = new StringBuilder();
|
||||
//foreach (var location in stats.HitLocations)
|
||||
// sb.Append($"HitLocation: {location.Location} -> {location.HitCount}\r\n");
|
||||
//Log.WriteDebug(sb.ToString());
|
||||
|
||||
return new DetectionPenaltyResult()
|
||||
{
|
||||
|
@ -23,18 +23,15 @@ namespace IW4MAdmin.Plugins.Stats.Cheat
|
||||
|
||||
double decayFactor = GetDecay(deltaTime);
|
||||
CurrentStrain *= decayFactor;
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine($"Decay Factor = {decayFactor} ");
|
||||
#endif
|
||||
|
||||
double[] distance = Helpers.Extensions.AngleStuff(newAngle, LastAngle);
|
||||
LastDistance = distance[0] + distance[1];
|
||||
|
||||
#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
|
||||
|
||||
// this happens on first kill
|
||||
if ((distance[0] == 0 && distance[1] == 0) ||
|
||||
deltaTime == 0 ||
|
||||
|
@ -8,6 +8,7 @@ using SharedLibraryCore.Objects;
|
||||
using IW4MAdmin.Plugins.Stats.Models;
|
||||
using SharedLibraryCore.Database;
|
||||
using System.Collections.Generic;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
@ -34,7 +35,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
join alias in db.Aliases
|
||||
on client.CurrentAliasId equals alias.AliasId
|
||||
where stats.ServerId == serverId
|
||||
where client.Level != Player.Permission.Banned
|
||||
where client.Level != EFClient.Permission.Banned
|
||||
where client.LastConnection >= thirtyDaysAgo
|
||||
orderby stats.Kills descending
|
||||
select new
|
||||
@ -55,7 +56,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
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)
|
||||
{
|
||||
|
@ -8,12 +8,13 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharedLibraryCore.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Services;
|
||||
using IW4MAdmin.Plugins.Stats.Models;
|
||||
using SharedLibraryCore.Database;
|
||||
using System.Collections.Generic;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
@ -33,7 +34,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
on client.CurrentAliasId equals alias.AliasId
|
||||
where stats.ServerId == serverId
|
||||
where stats.TimePlayed >= Plugin.Config.Configuration().TopPlayersMinPlayTime
|
||||
where client.Level != Player.Permission.Banned
|
||||
where client.Level != EFClient.Permission.Banned
|
||||
where client.LastConnection >= fifteenDaysAgo
|
||||
orderby stats.Performance descending
|
||||
select new
|
||||
@ -66,7 +67,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
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)
|
||||
{
|
||||
|
@ -10,12 +10,13 @@ using System.Threading.Tasks;
|
||||
using SharedLibraryCore.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using IW4MAdmin.Plugins.Stats.Helpers;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
namespace IW4MAdmin.Plugins.Stats.Commands
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
@ -1,23 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using IW4MAdmin.Plugins.Stats.Cheat;
|
||||
using IW4MAdmin.Plugins.Stats.Models;
|
||||
using IW4MAdmin.Plugins.Stats.Web.Dtos;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Helpers;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore.Commands;
|
||||
using IW4MAdmin.Plugins.Stats.Models;
|
||||
using System.Text.RegularExpressions;
|
||||
using IW4MAdmin.Plugins.Stats.Web.Dtos;
|
||||
using SharedLibraryCore.Database;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Services;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
{
|
||||
@ -40,14 +38,17 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
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)
|
||||
{
|
||||
var fifteenDaysAgo = DateTime.UtcNow.AddDays(-15);
|
||||
return (r) => r.ServerId == serverId &&
|
||||
r.When > fifteenDaysAgo &&
|
||||
r.RatingHistory.Client.Level != Player.Permission.Banned &&
|
||||
r.RatingHistory.Client.Level != EFClient.Permission.Banned &&
|
||||
r.Newest &&
|
||||
r.ActivityAmount >= Plugin.Config.Configuration().TopPlayersMinPlayTime;
|
||||
}
|
||||
@ -235,7 +236,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
/// </summary>
|
||||
/// <param name="pl">Player to add/retrieve stats for</param>
|
||||
/// <returns>EFClientStatistic of specified player</returns>
|
||||
public async Task<EFClientStatistics> AddPlayer(Player pl)
|
||||
public async Task<EFClientStatistics> AddPlayer(EFClient pl)
|
||||
{
|
||||
await OnProcessingSensitive.WaitAsync();
|
||||
|
||||
@ -373,7 +374,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
/// </summary>
|
||||
/// <param name="pl">Disconnecting client</param>
|
||||
/// <returns></returns>
|
||||
public async Task RemovePlayer(Player pl)
|
||||
public async Task RemovePlayer(EFClient pl)
|
||||
{
|
||||
Log.WriteInfo($"Removing {pl} from stats");
|
||||
|
||||
@ -432,7 +433,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
/// Process stats for kill event
|
||||
/// </summary>
|
||||
/// <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 fraction, string visibilityPercentage, string snapAngles)
|
||||
{
|
||||
@ -548,7 +549,22 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
case Penalty.PenaltyType.Ban:
|
||||
if (attacker.Level == Player.Permission.Banned)
|
||||
if (attacker.Level == EFClient.Permission.Banned)
|
||||
{
|
||||
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,
|
||||
AdministeredPenalties = new List<EFPenalty>()
|
||||
@ -588,7 +604,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
$"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}",
|
||||
}
|
||||
},
|
||||
Level = Player.Permission.Console,
|
||||
Level = EFClient.Permission.Console,
|
||||
CurrentServer = attacker.CurrentServer
|
||||
});
|
||||
if (clientDetection.Tracker.HasChanges)
|
||||
@ -597,7 +613,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
}
|
||||
break;
|
||||
case Penalty.PenaltyType.Flag:
|
||||
if (attacker.Level != Player.Permission.User)
|
||||
if (attacker.Level != EFClient.Permission.User)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -606,10 +622,10 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
$"{penalty.Type}-{(int)penalty.Location}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}" :
|
||||
$"{penalty.Type}-{Math.Round(penalty.Value, 2)}@{penalty.HitCount}";
|
||||
|
||||
attacker.Flag(flagReason, new Player()
|
||||
attacker.Flag(flagReason, new EFClient()
|
||||
{
|
||||
ClientId = 1,
|
||||
Level = Player.Permission.Console,
|
||||
Level = EFClient.Permission.Console,
|
||||
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();
|
||||
|
||||
@ -712,10 +728,14 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
|
||||
// this happens when the round has changed
|
||||
if (attackerStats.SessionScore == 0)
|
||||
{
|
||||
attackerStats.LastScore = 0;
|
||||
}
|
||||
|
||||
if (victimStats.SessionScore == 0)
|
||||
{
|
||||
victimStats.LastScore = 0;
|
||||
}
|
||||
|
||||
attackerStats.SessionScore = attacker.Score;
|
||||
victimStats.SessionScore = victim.Score;
|
||||
@ -780,7 +800,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
/// <param name="client">client to update</param>
|
||||
/// <param name="clientStats">stats of client that is being updated</param>
|
||||
/// <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;
|
||||
|
||||
@ -1158,7 +1178,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
{
|
||||
// the web users can have no account
|
||||
if (clientId < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var ctx = new DatabaseContext(disableTracking: true))
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
using IW4MAdmin.Application;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Commands;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -25,7 +26,7 @@ namespace Tests
|
||||
[Fact]
|
||||
public void SetAdditionalPropertyShouldSucceed()
|
||||
{
|
||||
var client = new Player();
|
||||
var client = new EFClient();
|
||||
int newProp = 5;
|
||||
client.SetAdditionalProperty("NewProp", newProp);
|
||||
}
|
||||
@ -33,7 +34,7 @@ namespace Tests
|
||||
[Fact]
|
||||
public void GetAdditionalPropertyShouldSucceed()
|
||||
{
|
||||
var client = new Player();
|
||||
var client = new EFClient();
|
||||
int newProp = 5;
|
||||
client.SetAdditionalProperty("NewProp", newProp);
|
||||
|
||||
@ -48,11 +49,11 @@ namespace Tests
|
||||
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");
|
||||
|
||||
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();
|
||||
|
||||
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,
|
||||
"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();
|
||||
|
||||
Assert.True(warnEvent.FailReason == GameEvent.EventFailReason.Permission &&
|
||||
client.Warnings == 1, "warning was applied without proper permissions");
|
||||
|
||||
// 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 &&
|
||||
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");
|
||||
}
|
||||
@ -85,11 +86,11 @@ namespace Tests
|
||||
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");
|
||||
|
||||
// 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);
|
||||
var reportEvent = client.Report("test report", player);
|
||||
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()}]");
|
||||
|
||||
// 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);
|
||||
|
||||
Assert.True(!reportEvent.Failed &&
|
||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"report was not applied [{reportEvent.FailReason.ToString()}]");
|
||||
|
||||
// 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 &&
|
||||
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");
|
||||
|
||||
// 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 &&
|
||||
client.CurrentServer.Reports.Count(r => r.Target.NetworkId == client.NetworkId) == 1, $"duplicate report was applied");
|
||||
@ -132,42 +133,42 @@ namespace Tests
|
||||
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");
|
||||
|
||||
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();
|
||||
|
||||
// succeed
|
||||
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");
|
||||
|
||||
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();
|
||||
|
||||
// fail
|
||||
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();
|
||||
|
||||
// fail
|
||||
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();
|
||||
|
||||
// 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();
|
||||
|
||||
// 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();
|
||||
|
||||
// succeed
|
||||
@ -182,18 +183,18 @@ namespace Tests
|
||||
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");
|
||||
|
||||
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();
|
||||
|
||||
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();
|
||||
|
||||
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]
|
||||
@ -204,13 +205,13 @@ namespace Tests
|
||||
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");
|
||||
|
||||
var tbCommand = new CTempBan();
|
||||
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,
|
||||
Data = "5days test tempban",
|
||||
Type = GameEvent.EventType.Command,
|
||||
@ -229,13 +230,13 @@ namespace Tests
|
||||
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");
|
||||
|
||||
var banCommand = new CBan();
|
||||
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,
|
||||
Data = "test ban",
|
||||
Type = GameEvent.EventType.Command,
|
||||
@ -248,8 +249,8 @@ namespace Tests
|
||||
var unbanCommand = new CUnban();
|
||||
unbanCommand.ExecuteAsync(new GameEvent()
|
||||
{
|
||||
Origin = new Player() { ClientId = 1, Level = Player.Permission.Console, CurrentServer = client.CurrentServer },
|
||||
Target = Manager.GetClientService().Find(c => c.NetworkId == client.NetworkId).Result.First().AsPlayer(),
|
||||
Origin = new EFClient() { ClientId = 1, Level = EFClient.Permission.Console, CurrentServer = client.CurrentServer },
|
||||
Target = Manager.GetClientService().Find(c => c.NetworkId == client.NetworkId).Result.First().AsEFClient(),
|
||||
Data = "test unban",
|
||||
Type = GameEvent.EventType.Command,
|
||||
Owner = client.CurrentServer
|
||||
|
@ -1,5 +1,6 @@
|
||||
using IW4MAdmin.Application;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
@ -53,7 +54,7 @@ namespace Tests
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Join,
|
||||
Origin = new Player()
|
||||
Origin = new EFClient()
|
||||
{
|
||||
Name = $"Player{i}",
|
||||
NetworkId = i,
|
||||
@ -78,7 +79,7 @@ namespace Tests
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Disconnect,
|
||||
Origin = new Player()
|
||||
Origin = new EFClient()
|
||||
{
|
||||
Name = $"Player{i}",
|
||||
NetworkId = i,
|
||||
@ -113,7 +114,7 @@ namespace Tests
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Connect,
|
||||
Origin = new Player()
|
||||
Origin = new EFClient()
|
||||
{
|
||||
Name = $"Player{i}",
|
||||
NetworkId = i,
|
||||
@ -134,7 +135,7 @@ namespace Tests
|
||||
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}");
|
||||
|
||||
for (int i = clientIndexStart; i < clientNum + clientIndexStart; i++)
|
||||
@ -142,7 +143,7 @@ namespace Tests
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Disconnect,
|
||||
Origin = new Player()
|
||||
Origin = new EFClient()
|
||||
{
|
||||
Name = $"Player{i}",
|
||||
NetworkId = i,
|
||||
|
@ -1,5 +1,6 @@
|
||||
using IW4MAdmin.Application;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
using Xunit;
|
||||
|
||||
@ -21,7 +22,7 @@ namespace Tests
|
||||
var e = new GameEvent()
|
||||
{
|
||||
Type = GameEvent.EventType.Connect,
|
||||
Origin = new Player()
|
||||
Origin = new EFClient()
|
||||
{
|
||||
Name = $"Player1",
|
||||
NetworkId = 1,
|
||||
@ -33,7 +34,7 @@ namespace Tests
|
||||
Manager.GetEventHandler().AddEvent(e);
|
||||
e.OnProcessed.Wait();
|
||||
|
||||
var client = Manager.GetServers()[0].Players[0];
|
||||
var client = Manager.GetServers()[0].Clients[0];
|
||||
|
||||
e = new GameEvent()
|
||||
{
|
||||
|
@ -13,12 +13,13 @@ using Microsoft.EntityFrameworkCore;
|
||||
using System.Net;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using static SharedLibraryCore.Database.Models.EFClient;
|
||||
|
||||
namespace IW4MAdmin.Plugins.Welcome
|
||||
{
|
||||
public class Plugin : IPlugin
|
||||
{
|
||||
String TimesConnected(Player P)
|
||||
String TimesConnected(EFClient P)
|
||||
{
|
||||
int connection = P.Connections;
|
||||
String Prefix = String.Empty;
|
||||
@ -85,13 +86,13 @@ namespace IW4MAdmin.Plugins.Welcome
|
||||
{
|
||||
if (E.Type == GameEvent.EventType.Connect)
|
||||
{
|
||||
Player newPlayer = E.Origin;
|
||||
if (newPlayer.Level >= Player.Permission.Trusted && !E.Origin.Masked)
|
||||
EFClient newPlayer = E.Origin;
|
||||
if (newPlayer.Level >= Permission.Trusted && !E.Origin.Masked)
|
||||
E.Owner.Broadcast(await ProcessAnnouncement(Config.Configuration().PrivilegedAnnouncementMessage, newPlayer));
|
||||
|
||||
newPlayer.Tell(await ProcessAnnouncement(Config.Configuration().UserWelcomeMessage, newPlayer));
|
||||
|
||||
if (newPlayer.Level == Player.Permission.Flagged)
|
||||
if (newPlayer.Level == Permission.Flagged)
|
||||
{
|
||||
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("{{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 Application/Application.csproj -c Prerelease -o C:\Projects\IW4M-Admin\Publish\WindowsPrerelease
|
||||
dotnet publish GameLogServer/GameLogServer.pyproj -c Release -o C:\Projects\IW4M-Admin\Publish\WindowsPrerelease\GameLogServer
|
||||
dotnet publish WebfrontCore/WebfrontCore.csproj -c Prerelease -o X:\IW4MAdmin\Publish\WindowsPrerelease
|
||||
dotnet publish Application/Application.csproj -c Prerelease -o X:\IW4MAdmin\Publish\WindowsPrerelease
|
||||
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"
|
||||
msbuild GameLogServer/GameLogServer.pyproj /p:PublishProfile=FolderProfile /p:DeployOnBuild=true /p:PublishProfileRootFolder=C:\Projects\IW4M-Admin\GameLogServer\
|
||||
msbuild DiscordWebhook/DiscordWebhook.pyproj /p:PublishProfile=FolderProfile /p:DeployOnBuild=true /p:PublishProfileRootFolder=C:\Projects\IW4M-Admin\DiscordWebhook\
|
||||
cd "C:\Projects\IW4M-Admin\DEPLOY\"
|
||||
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=X:\IW4MAdmin\DiscordWebhook\
|
||||
cd "X:\IW4MAdmin\DEPLOY\"
|
||||
PowerShell ".\upload_prerelease.ps1"
|
@ -1,8 +1,8 @@
|
||||
dotnet publish WebfrontCore/WebfrontCore.csproj -c Release -o C:\Projects\IW4M-Admin\Publish\Windows
|
||||
dotnet publish Application/Application.csproj -c Release -o C:\Projects\IW4M-Admin\Publish\Windows
|
||||
dotnet publish GameLogServer/GameLogServer.pyproj -c Release -o C:\Projects\IW4M-Admin\Publish\Windows\GameLogServer
|
||||
dotnet publish WebfrontCore/WebfrontCore.csproj -c Release -o X:\IW4MAdmin\Publish\Windows
|
||||
dotnet publish Application/Application.csproj -c Release -o X:\IW4MAdmin\Publish\Windows
|
||||
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"
|
||||
msbuild GameLogServer/GameLogServer.pyproj /p:PublishProfile=Stable /p:DeployOnBuild=true /p:PublishProfileRootFolder=C:\Projects\IW4M-Admin\GameLogServer\
|
||||
msbuild DiscordWebhook/DiscordWebhook.pyproj /p:PublishProfile=Stable /p:DeployOnBuild=true /p:PublishProfileRootFolder=C:\Projects\IW4M-Admin\DiscordWebhook\
|
||||
cd "C:\Projects\IW4M-Admin\DEPLOY\"
|
||||
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=X:\IW4MAdmin\DiscordWebhook\
|
||||
cd "X:\IW4MAdmin\DEPLOY\"
|
||||
PowerShell ".\upload_release.ps1"
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
|
||||
namespace SharedLibraryCore
|
||||
@ -14,7 +14,7 @@ namespace SharedLibraryCore
|
||||
|
||||
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;
|
||||
Description = commandDescription;
|
||||
@ -33,7 +33,7 @@ namespace SharedLibraryCore
|
||||
public String Alias { get; private set; }
|
||||
public int RequiredArgumentCount => Arguments.Count(c => c.Required);
|
||||
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; }
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using SharedLibraryCore.Exceptions;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Exceptions;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -60,7 +61,7 @@ namespace SharedLibraryCore.Commands
|
||||
var found = await Manager.GetClientService().Get(dbID);
|
||||
if (found != null)
|
||||
{
|
||||
E.Target = found.AsPlayer();
|
||||
E.Target = found;
|
||||
E.Target.CurrentServer = E.Owner;
|
||||
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
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
List<Player> matchingPlayers;
|
||||
List<EFClient> matchingPlayers;
|
||||
|
||||
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.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using static SharedLibraryCore.RCon.StaticHelpers;
|
||||
|
||||
namespace SharedLibraryCore.Commands
|
||||
{
|
||||
public class CQuit : Command
|
||||
{
|
||||
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)
|
||||
@ -31,14 +30,14 @@ namespace SharedLibraryCore.Commands
|
||||
public class COwner : Command
|
||||
{
|
||||
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)
|
||||
{
|
||||
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"]);
|
||||
// so setpassword/login works
|
||||
E.Owner.Manager.GetPrivilegedClients().Add(E.Origin.ClientId, E.Origin);
|
||||
@ -54,7 +53,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CWarn : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -83,7 +82,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CWarnClear : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -107,7 +106,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CKick : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -133,7 +132,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CSay : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -153,7 +152,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CTempBan : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -201,7 +200,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CBan : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -227,7 +226,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CUnban : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -260,7 +259,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CWhoAmI : Command
|
||||
{
|
||||
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)
|
||||
@ -275,27 +274,33 @@ namespace SharedLibraryCore.Commands
|
||||
public class CList : Command
|
||||
{
|
||||
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)
|
||||
{
|
||||
StringBuilder playerList = new StringBuilder();
|
||||
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)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// todo: fix spacing
|
||||
// todo: make this better :)
|
||||
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
|
||||
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());
|
||||
count = 0;
|
||||
@ -320,7 +325,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CHelp : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -385,7 +390,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CFastRestart : Command
|
||||
{
|
||||
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)
|
||||
@ -401,7 +406,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CMapRotate : Command
|
||||
{
|
||||
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)
|
||||
@ -418,7 +423,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CSetLevel : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -441,17 +446,17 @@ namespace SharedLibraryCore.Commands
|
||||
return;
|
||||
}
|
||||
|
||||
Player.Permission oldPerm = E.Target.Level;
|
||||
Player.Permission newPerm = Utilities.MatchPermission(E.Data);
|
||||
EFClient.Permission oldPerm = E.Target.Level;
|
||||
EFClient.Permission newPerm = Utilities.MatchPermission(E.Data);
|
||||
|
||||
if (newPerm == Player.Permission.Owner &&
|
||||
if (newPerm == EFClient.Permission.Owner &&
|
||||
!E.Owner.Manager.GetApplicationSettings().Configuration().EnableMultipleOwners)
|
||||
{
|
||||
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_SETLEVEL_OWNER"]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (E.Origin.Level < Player.Permission.Owner &&
|
||||
if (E.Origin.Level < EFClient.Permission.Owner &&
|
||||
!E.Owner.Manager.GetApplicationSettings().Configuration().EnableSteppedHierarchy)
|
||||
{
|
||||
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 (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()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else if (newPerm > Player.Permission.Banned)
|
||||
else if (newPerm > EFClient.Permission.Banned)
|
||||
{
|
||||
var ActiveClient = E.Owner.Manager.GetActiveClients()
|
||||
.FirstOrDefault(p => p.NetworkId == E.Target.NetworkId);
|
||||
@ -530,7 +535,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CUsage : Command
|
||||
{
|
||||
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)
|
||||
@ -543,7 +548,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CUptime : Command
|
||||
{
|
||||
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)
|
||||
@ -558,13 +563,13 @@ namespace SharedLibraryCore.Commands
|
||||
public class CListAdmins : Command
|
||||
{
|
||||
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)
|
||||
{
|
||||
var onlineAdmins = S.GetPlayersAsList()
|
||||
.Where(p => p.Level > Player.Permission.Flagged)
|
||||
var onlineAdmins = S.GetClientsAsList()
|
||||
.Where(p => p.Level > EFClient.Permission.Flagged)
|
||||
.Where(p => !p.Masked)
|
||||
.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 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()
|
||||
{
|
||||
@ -620,7 +625,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CFindPlayer : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -664,7 +669,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CListRules : Command
|
||||
{
|
||||
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)
|
||||
@ -682,7 +687,9 @@ namespace SharedLibraryCore.Commands
|
||||
var rules = new List<string>();
|
||||
rules.AddRange(E.Owner.Manager.GetApplicationSettings().Configuration().GlobalRules);
|
||||
if (E.Owner.ServerConfig.Rules != null)
|
||||
{
|
||||
rules.AddRange(E.Owner.ServerConfig.Rules);
|
||||
}
|
||||
|
||||
foreach (string r in rules)
|
||||
{
|
||||
@ -697,7 +704,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CPrivateMessage : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -724,7 +731,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CFlag : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -766,7 +773,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CUnflag : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -804,7 +811,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CReport : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -875,7 +882,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CListReports : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -912,7 +919,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CMask : Command
|
||||
{
|
||||
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)
|
||||
@ -935,7 +942,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CListBanInfo : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -968,7 +975,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CListAlias : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -1002,7 +1009,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CExecuteRCON : Command
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -1016,16 +1023,21 @@ namespace SharedLibraryCore.Commands
|
||||
{
|
||||
var Response = await E.Owner.ExecuteCommandAsync(E.Data.Trim());
|
||||
foreach (string S in Response)
|
||||
{
|
||||
E.Origin.Tell(S.StripColors());
|
||||
}
|
||||
|
||||
if (Response.Length == 0)
|
||||
{
|
||||
E.Origin.Tell(Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_RCON_SUCCESS"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CPlugins : Command
|
||||
{
|
||||
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)
|
||||
@ -1042,7 +1054,7 @@ namespace SharedLibraryCore.Commands
|
||||
public class CIP : Command
|
||||
{
|
||||
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)
|
||||
@ -1054,7 +1066,7 @@ namespace SharedLibraryCore.Commands
|
||||
|
||||
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()
|
||||
{
|
||||
@ -1074,7 +1086,9 @@ namespace SharedLibraryCore.Commands
|
||||
{
|
||||
inactiveDays = Int32.Parse(E.Data);
|
||||
if (inactiveDays < 1)
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1091,10 +1105,10 @@ namespace SharedLibraryCore.Commands
|
||||
{
|
||||
var lastActive = DateTime.UtcNow.AddDays(-inactiveDays);
|
||||
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)
|
||||
.ToListAsync();
|
||||
inactiveUsers.ForEach(c => c.Level = Player.Permission.User);
|
||||
inactiveUsers.ForEach(c => c.Level = EFClient.Permission.User);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
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 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()
|
||||
{
|
||||
@ -1137,77 +1151,89 @@ namespace SharedLibraryCore.Commands
|
||||
|
||||
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)
|
||||
{
|
||||
var gameserverProcesses = System.Diagnostics.Process.GetProcessesByName("iw4x");
|
||||
|
||||
System.Diagnostics.Process currentProcess = null;
|
||||
|
||||
foreach (var p in gameserverProcesses)
|
||||
if (E.Owner.ServerConfig.ManualLogPath != null)
|
||||
{
|
||||
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())
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
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
|
||||
{
|
||||
// attempt to kill it natively
|
||||
try
|
||||
var gameserverProcesses = System.Diagnostics.Process.GetProcessesByName("iw4x");
|
||||
|
||||
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
|
||||
await E.Owner.ExecuteCommandAsync("quit");
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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()
|
||||
{
|
||||
@ -1222,16 +1248,24 @@ namespace SharedLibraryCore.Commands
|
||||
if (E.Message.IsBroadcastCommand())
|
||||
{
|
||||
if (E.Target == null)
|
||||
{
|
||||
E.Owner.Broadcast($"{E.Origin.Name}'s {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_TARGET"]} ^5{E.Origin.Ping}^7ms");
|
||||
}
|
||||
else
|
||||
{
|
||||
E.Owner.Broadcast($"{E.Target.Name}'s {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_TARGET"]} ^5{E.Target.Ping}^7ms");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (E.Target == null)
|
||||
{
|
||||
E.Origin.Tell($"{Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_SELF"]} ^5{E.Origin.Ping}^7ms");
|
||||
}
|
||||
else
|
||||
{
|
||||
E.Origin.Tell($"{E.Target.Name}'s {Utilities.CurrentLocalization.LocalizationIndex["COMMANDS_PING_TARGET"]} ^5{E.Target.Ping}^7ms");
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
@ -1240,7 +1274,7 @@ namespace SharedLibraryCore.Commands
|
||||
|
||||
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()
|
||||
{
|
||||
@ -1304,7 +1338,7 @@ namespace SharedLibraryCore.Commands
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
string mapRotation = (await s.GetDvarAsync<string>("sv_mapRotation")).Value.ToLower();
|
||||
|
@ -3,6 +3,7 @@ using SharedLibraryCore.Database.Models;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using static SharedLibraryCore.Database.Models.EFClient;
|
||||
|
||||
namespace SharedLibraryCore.Database
|
||||
{
|
||||
@ -47,7 +48,7 @@ namespace SharedLibraryCore.Database
|
||||
Connections = 0,
|
||||
FirstConnection = DateTime.UtcNow,
|
||||
LastConnection = DateTime.UtcNow,
|
||||
Level = Objects.Player.Permission.Console,
|
||||
Level = Permission.Console,
|
||||
Masked = true,
|
||||
NetworkId = 0,
|
||||
AliasLinkId = 1,
|
||||
|
@ -1,17 +1,13 @@
|
||||
using System;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Npgsql;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
namespace SharedLibraryCore.Database
|
||||
{
|
||||
@ -26,6 +22,7 @@ namespace SharedLibraryCore.Database
|
||||
|
||||
static string _ConnectionString;
|
||||
static string _provider;
|
||||
private static string _migrationPluginDirectory = @"X:\IW4MAdmin\BUILD\Plugins\";
|
||||
|
||||
public DatabaseContext(DbContextOptions<DatabaseContext> opt) : base(opt) { }
|
||||
|
||||
@ -57,7 +54,7 @@ namespace SharedLibraryCore.Database
|
||||
$"{Path.DirectorySeparatorChar}{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 connection = new SqliteConnection(connectionString);
|
||||
|
||||
@ -126,23 +123,11 @@ namespace SharedLibraryCore.Database
|
||||
|
||||
// adapted from
|
||||
// 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
|
||||
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
|
||||
foreach (string dllPath in directoryFiles)
|
||||
#endif
|
||||
@ -163,7 +148,9 @@ namespace SharedLibraryCore.Database
|
||||
.Select(c => (IModelConfiguration)Activator.CreateInstance(c));
|
||||
|
||||
foreach (var configurable in configurations)
|
||||
{
|
||||
configurable.Configure(modelBuilder);
|
||||
}
|
||||
|
||||
foreach (var type in library.ExportedTypes)
|
||||
{
|
||||
|
@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace SharedLibraryCore.Database.Models
|
||||
{
|
||||
public class EFClient : SharedEntity
|
||||
public partial class EFClient : SharedEntity
|
||||
{
|
||||
[Key]
|
||||
public int ClientId { get; set; }
|
||||
@ -25,7 +25,7 @@ namespace SharedLibraryCore.Database.Models
|
||||
[ForeignKey("AliasLinkId")]
|
||||
public virtual EFAliasLink AliasLink { get; set; }
|
||||
[Required]
|
||||
public Objects.Player.Permission Level { get; set; }
|
||||
public Permission Level { get; set; }
|
||||
|
||||
[Required]
|
||||
public int CurrentAliasId { get; set; }
|
||||
@ -57,11 +57,5 @@ namespace SharedLibraryCore.Database.Models
|
||||
|
||||
public virtual ICollection<EFPenalty> ReceivedPenalties { 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static SharedLibraryCore.Objects.Player;
|
||||
|
||||
namespace SharedLibraryCore.Dtos
|
||||
namespace SharedLibraryCore.Dtos
|
||||
{
|
||||
public class ClientInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int ClientId { 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.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
|
||||
namespace SharedLibraryCore
|
||||
@ -50,11 +51,11 @@ namespace SharedLibraryCore
|
||||
/// </summary>
|
||||
Stop,
|
||||
/// <summary>
|
||||
/// a client was detecting as connecting via RCon
|
||||
/// a client was detecting as connecting via log
|
||||
/// </summary>
|
||||
Connect,
|
||||
/// <summary>
|
||||
/// a client was detecting joining via log
|
||||
/// a client was detecting joining by RCon
|
||||
/// </summary>
|
||||
Join,
|
||||
/// <summary>
|
||||
@ -170,8 +171,8 @@ namespace SharedLibraryCore
|
||||
public EventType Type;
|
||||
public string Data; // Data is usually the message sent by player
|
||||
public string Message;
|
||||
public Player Origin;
|
||||
public Player Target;
|
||||
public EFClient Origin;
|
||||
public EFClient Target;
|
||||
public Server Owner;
|
||||
public Boolean Remote = false;
|
||||
public object Extra { get; set; }
|
||||
@ -200,7 +201,7 @@ namespace SharedLibraryCore
|
||||
public static bool ShouldOriginEventBeDelayed(GameEvent queuedEvent)
|
||||
{
|
||||
return queuedEvent.Origin != null &&
|
||||
(queuedEvent.Origin.State != Player.ClientState.Connected &&
|
||||
(queuedEvent.Origin.State != EFClient.ClientState.Connected &&
|
||||
// we want to allow join and quit events
|
||||
queuedEvent.Type != EventType.Connect &&
|
||||
queuedEvent.Type != EventType.Join &&
|
||||
@ -219,7 +220,7 @@ namespace SharedLibraryCore
|
||||
public static bool ShouldTargetEventBeDelayed(GameEvent queuedEvent)
|
||||
{
|
||||
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.Origin?.ClientId != 1);
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
@ -12,16 +13,16 @@ namespace SharedLibraryCore.Interfaces
|
||||
/// occurs in the log, as no IP is given
|
||||
/// </summary>
|
||||
/// <param name="client">client that has joined from the log</param>
|
||||
void RequestClientAuthentication(Player client);
|
||||
void RequestClientAuthentication(EFClient client);
|
||||
/// <summary>
|
||||
/// get all clients that have been authenticated by the status poll
|
||||
/// </summary>
|
||||
/// <returns>list of all authenticated clients</returns>
|
||||
IList<Player> GetAuthenticatedClients();
|
||||
IList<EFClient> GetAuthenticatedClients();
|
||||
/// <summary>
|
||||
/// authenticate a list of clients from status poll
|
||||
/// </summary>
|
||||
/// <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.Configuration;
|
||||
using System.Reflection;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
namespace SharedLibraryCore.Interfaces
|
||||
{
|
||||
@ -17,12 +18,12 @@ namespace SharedLibraryCore.Interfaces
|
||||
IList<Server> GetServers();
|
||||
IList<Command> GetCommands();
|
||||
IList<Helpers.MessageToken> GetMessageTokens();
|
||||
IList<Player> GetActiveClients();
|
||||
IList<EFClient> GetActiveClients();
|
||||
IConfigurationHandler<ApplicationConfiguration> GetApplicationSettings();
|
||||
ClientService GetClientService();
|
||||
AliasService GetAliasService();
|
||||
PenaltyService GetPenaltyService();
|
||||
IDictionary<int, Player> GetPrivilegedClients();
|
||||
IDictionary<int, EFClient> GetPrivilegedClients();
|
||||
/// <summary>
|
||||
/// Get the event handlers
|
||||
/// </summary>
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore.RCon;
|
||||
|
||||
@ -10,7 +11,7 @@ namespace SharedLibraryCore.Interfaces
|
||||
Task<Dvar<T>> GetDvarAsync<T>(Connection connection, string dvarName);
|
||||
Task<bool> SetDvarAsync(Connection connection, string dvarName, object dvarValue);
|
||||
Task<string[]> ExecuteCommandAsync(Connection connection, string command);
|
||||
Task<List<Player>> GetStatusAsync(Connection connection);
|
||||
Task<List<EFClient>> GetStatusAsync(Connection connection);
|
||||
CommandPrefix GetCommandPrefixes();
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
using System;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SharedLibraryCore.Objects
|
||||
namespace SharedLibraryCore.Database.Models
|
||||
{
|
||||
public class Player : Database.Models.EFClient
|
||||
public partial class EFClient
|
||||
{
|
||||
public enum ClientState
|
||||
{
|
||||
@ -76,7 +77,7 @@ namespace SharedLibraryCore.Objects
|
||||
Console = 8
|
||||
}
|
||||
|
||||
public Player()
|
||||
public EFClient()
|
||||
{
|
||||
ConnectionTime = DateTime.UtcNow;
|
||||
ClientNumber = -1;
|
||||
@ -87,7 +88,10 @@ namespace SharedLibraryCore.Objects
|
||||
};
|
||||
}
|
||||
|
||||
public override string ToString() => $"{Name}::{NetworkId}";
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name}::{NetworkId}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// send a message directly to the connected client
|
||||
@ -113,7 +117,7 @@ namespace SharedLibraryCore.Objects
|
||||
/// </summary>
|
||||
/// <param name="warnReason">reason for 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()
|
||||
{
|
||||
@ -146,7 +150,7 @@ namespace SharedLibraryCore.Objects
|
||||
/// </summary>
|
||||
/// <param name="sender">client performing the warn clear</param>
|
||||
/// <returns></returns>
|
||||
public GameEvent WarnClear(Player sender)
|
||||
public GameEvent WarnClear(EFClient sender)
|
||||
{
|
||||
var e = new GameEvent()
|
||||
{
|
||||
@ -175,7 +179,7 @@ namespace SharedLibraryCore.Objects
|
||||
/// <param name="reportReason">reason for the report</param>
|
||||
/// <param name="sender">client performing the report</param>
|
||||
/// <returns></returns>
|
||||
public GameEvent Report(string reportReason, Player sender)
|
||||
public GameEvent Report(string reportReason, EFClient sender)
|
||||
{
|
||||
var e = new GameEvent()
|
||||
{
|
||||
@ -221,7 +225,7 @@ namespace SharedLibraryCore.Objects
|
||||
/// <param name="flagReason">reason for flagging</param>
|
||||
/// <param name="sender">client performing the flag</param>
|
||||
/// <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()
|
||||
{
|
||||
@ -238,14 +242,14 @@ namespace SharedLibraryCore.Objects
|
||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||
}
|
||||
|
||||
else if (this.Level == Player.Permission.Flagged)
|
||||
else if (this.Level == Permission.Flagged)
|
||||
{
|
||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
this.Level = Player.Permission.Flagged;
|
||||
this.Level = Permission.Flagged;
|
||||
}
|
||||
|
||||
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="sender">client performing the unflag</param>
|
||||
/// <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()
|
||||
{
|
||||
@ -275,7 +279,7 @@ namespace SharedLibraryCore.Objects
|
||||
e.FailReason = GameEvent.EventFailReason.Permission;
|
||||
}
|
||||
|
||||
else if (this.Level != Player.Permission.Flagged)
|
||||
else if (this.Level != EFClient.Permission.Flagged)
|
||||
{
|
||||
e.FailReason = GameEvent.EventFailReason.Invalid;
|
||||
}
|
||||
@ -294,7 +298,7 @@ namespace SharedLibraryCore.Objects
|
||||
/// </summary>
|
||||
/// <param name="kickReason">reason to kick for</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()
|
||||
{
|
||||
@ -322,7 +326,7 @@ namespace SharedLibraryCore.Objects
|
||||
/// <param name="tempbanReason">reason for the temp ban</param>
|
||||
/// <param name="banLength">how long the temp ban lasts</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()
|
||||
{
|
||||
@ -350,7 +354,7 @@ namespace SharedLibraryCore.Objects
|
||||
/// </summary>
|
||||
/// <param name="banReason">reason for 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()
|
||||
{
|
||||
@ -378,7 +382,7 @@ namespace SharedLibraryCore.Objects
|
||||
/// <param name="unbanReason">reason for the unban</param>
|
||||
/// <param name="sender">client performing the unban</param>
|
||||
/// <returns></returns>
|
||||
public GameEvent Unban(String unbanReason, Player sender)
|
||||
public GameEvent Unban(String unbanReason, EFClient sender)
|
||||
{
|
||||
var e = new GameEvent()
|
||||
{
|
||||
@ -400,10 +404,119 @@ namespace SharedLibraryCore.Objects
|
||||
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]
|
||||
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)
|
||||
{
|
||||
@ -433,18 +546,18 @@ namespace SharedLibraryCore.Objects
|
||||
public int Score { get; set; }
|
||||
[NotMapped]
|
||||
public bool IsBot { get; set; }
|
||||
private int _ipaddress;
|
||||
public override int IPAddress
|
||||
{
|
||||
get { return _ipaddress; }
|
||||
set { _ipaddress = value; }
|
||||
}
|
||||
private string _name;
|
||||
public override string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set { _name = value; }
|
||||
}
|
||||
//private int _ipaddress;
|
||||
//public override int IPAddress
|
||||
//{
|
||||
// get => _ipaddress;
|
||||
// set => _ipaddress = value;
|
||||
//}
|
||||
//private string _name;
|
||||
//public override string Name
|
||||
//{
|
||||
// get => _name;
|
||||
// set => _name = value;
|
||||
//}
|
||||
[NotMapped]
|
||||
public ClientState State { get; set; }
|
||||
[NotMapped]
|
||||
@ -460,9 +573,12 @@ namespace SharedLibraryCore.Objects
|
||||
|
||||
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 System.Collections.Generic;
|
||||
using System.Text;
|
||||
using static SharedLibraryCore.Objects.Player;
|
||||
using static SharedLibraryCore.Database.Models.EFClient;
|
||||
|
||||
namespace SharedLibraryCore.Objects
|
||||
{
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -8,8 +9,8 @@ namespace SharedLibraryCore.Objects
|
||||
{
|
||||
public class Report
|
||||
{
|
||||
public Player Target { get; set; }
|
||||
public Player Origin { get; set; }
|
||||
public String Reason { get; set; }
|
||||
public EFClient Target { get; set; }
|
||||
public EFClient Origin { get; set; }
|
||||
public string Reason { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -137,12 +137,9 @@ namespace SharedLibraryCore.RCon
|
||||
throw new NetworkException(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_RCON_NOTSET"]);
|
||||
}
|
||||
|
||||
Log.WriteInfo(responseString);
|
||||
|
||||
string[] splitResponse = responseString.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(line => line.Trim()).ToArray();
|
||||
return splitResponse;
|
||||
|
||||
}
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.IO;
|
||||
@ -71,7 +72,7 @@ namespace SharedLibraryCore
|
||||
cfg.AllowClr(new[]
|
||||
{
|
||||
typeof(System.Net.Http.HttpClient).Assembly,
|
||||
typeof(Objects.Player).Assembly,
|
||||
typeof(EFClient).Assembly,
|
||||
})
|
||||
.CatchClrExceptions());
|
||||
|
||||
|
@ -9,6 +9,7 @@ using SharedLibraryCore.Objects;
|
||||
using SharedLibraryCore.Dtos;
|
||||
using SharedLibraryCore.Configuration;
|
||||
using SharedLibraryCore.Interfaces;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
namespace SharedLibraryCore
|
||||
{
|
||||
@ -37,9 +38,9 @@ namespace SharedLibraryCore
|
||||
ServerConfig = config;
|
||||
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>();
|
||||
PlayerHistory = new Queue<PlayerHistory>();
|
||||
ClientHistory = new Queue<PlayerHistory>();
|
||||
ChatHistory = new List<ChatInfo>();
|
||||
NextMessage = 0;
|
||||
CustomSayEnabled = Manager.GetApplicationSettings().Configuration().EnableCustomSayName;
|
||||
@ -61,32 +62,32 @@ namespace SharedLibraryCore
|
||||
}
|
||||
|
||||
//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>
|
||||
/// Add a player to the server's player list
|
||||
/// </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>
|
||||
abstract public Task<bool> AddPlayer(Player P);
|
||||
abstract public Task OnClientConnected(EFClient P);
|
||||
|
||||
/// <summary>
|
||||
/// Remove player by client number
|
||||
/// </summary>
|
||||
/// <param name="cNum">Client ID of player to be removed</param>
|
||||
/// <returns>true if removal succeded, false otherwise</returns>
|
||||
abstract public Task RemovePlayer(int cNum);
|
||||
abstract public Task RemoveClient(int cNum);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a player by name
|
||||
/// </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>
|
||||
public List<Player> GetClientByName(String pName)
|
||||
public List<EFClient> GetClientByName(String pName)
|
||||
{
|
||||
string[] QuoteSplit = pName.Split('"');
|
||||
bool literal = false;
|
||||
@ -96,9 +97,9 @@ namespace SharedLibraryCore
|
||||
literal = true;
|
||||
}
|
||||
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;
|
||||
@ -115,7 +116,7 @@ namespace SharedLibraryCore
|
||||
/// Send a message to all players
|
||||
/// </summary>
|
||||
/// <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}");
|
||||
|
||||
@ -139,19 +140,19 @@ namespace SharedLibraryCore
|
||||
/// Send a message to a particular players
|
||||
/// </summary>
|
||||
/// <param name="Message">Message to send</param>
|
||||
/// <param name="Target">Player to send message to</param>
|
||||
protected async Task Tell(String Message, Player Target)
|
||||
/// <param name="Target">EFClient to send message to</param>
|
||||
protected async Task Tell(String Message, EFClient Target)
|
||||
{
|
||||
#if !DEBUG
|
||||
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);
|
||||
#else
|
||||
Logger.WriteVerbose($"{Target.ClientNumber}->{Message.StripColors()}");
|
||||
await Task.CompletedTask;
|
||||
#endif
|
||||
|
||||
if (Target.Level == Player.Permission.Console)
|
||||
if (Target.Level == EFClient.Permission.Console)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
||||
Console.WriteLine(Message.StripColors());
|
||||
@ -179,7 +180,7 @@ namespace SharedLibraryCore
|
||||
/// <param name="message">Message to send out</param>
|
||||
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);
|
||||
}
|
||||
@ -189,15 +190,15 @@ namespace SharedLibraryCore
|
||||
/// Kick a player from the server
|
||||
/// </summary>
|
||||
/// <param name="Reason">Reason for kicking</param>
|
||||
/// <param name="Target">Player to kick</param>
|
||||
abstract protected Task Kick(String Reason, Player Target, Player Origin);
|
||||
/// <param name="Target">EFClient to kick</param>
|
||||
abstract protected Task Kick(String Reason, EFClient Target, EFClient Origin);
|
||||
|
||||
/// <summary>
|
||||
/// Temporarily ban a player ( default 1 hour ) from the server
|
||||
/// </summary>
|
||||
/// <param name="Reason">Reason for banning the player</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>
|
||||
/// Perm ban a player from the server
|
||||
@ -205,9 +206,9 @@ namespace SharedLibraryCore
|
||||
/// <param name="Reason">The reason for the ban</param>
|
||||
/// <param name="Target">The person to ban</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>
|
||||
/// Unban a player by npID / GUID
|
||||
@ -215,7 +216,7 @@ namespace SharedLibraryCore
|
||||
/// <param name="npID">npID of the player</param>
|
||||
/// <param name="Target">I don't remember what this is for</param>
|
||||
/// <returns></returns>
|
||||
abstract public Task Unban(string reason, Player Target, Player Origin);
|
||||
abstract public Task Unban(string reason, EFClient Target, EFClient Origin);
|
||||
|
||||
/// <summary>
|
||||
/// Change the current searver map
|
||||
@ -284,7 +285,7 @@ namespace SharedLibraryCore
|
||||
public List<Map> Maps { get; protected set; }
|
||||
public List<Report> Reports { get; 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; }
|
||||
|
||||
// Info
|
||||
@ -296,11 +297,11 @@ namespace SharedLibraryCore
|
||||
{
|
||||
get
|
||||
{
|
||||
return Players.Where(p => p != null).Count();
|
||||
return Clients.Where(p => p != null).Count();
|
||||
}
|
||||
}
|
||||
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 bool Throttled { get; protected set; }
|
||||
public bool CustomCallback { get; protected set; }
|
||||
@ -309,6 +310,7 @@ namespace SharedLibraryCore
|
||||
public IRConParser RconParser { get; protected set; }
|
||||
public IEventParser EventParser { get; set; }
|
||||
public string LogPath { get; protected set; }
|
||||
public bool RestartRequested { get; set; }
|
||||
|
||||
// Internal
|
||||
protected string IP;
|
||||
|
@ -10,6 +10,7 @@ using System.Linq.Expressions;
|
||||
using SharedLibraryCore.Objects;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SharedLibraryCore.Dtos;
|
||||
using static SharedLibraryCore.Database.Models.EFClient;
|
||||
|
||||
namespace SharedLibraryCore.Services
|
||||
{
|
||||
@ -60,8 +61,8 @@ namespace SharedLibraryCore.Services
|
||||
Level = hasExistingAlias ?
|
||||
(await context.Clients.Where(c => c.AliasLinkId == existingAlias.LinkId)
|
||||
.OrderByDescending(c => c.Level)
|
||||
.FirstOrDefaultAsync())?.Level ?? Player.Permission.User :
|
||||
Player.Permission.User,
|
||||
.FirstOrDefaultAsync())?.Level ?? Permission.User :
|
||||
Permission.User,
|
||||
FirstConnection = DateTime.UtcNow,
|
||||
Connections = 1,
|
||||
LastConnection = DateTime.UtcNow,
|
||||
@ -228,7 +229,7 @@ namespace SharedLibraryCore.Services
|
||||
{
|
||||
using (var context = new DatabaseContext())
|
||||
return await context.Clients
|
||||
.Where(c => c.Level == Player.Permission.Owner)
|
||||
.Where(c => c.Level == Permission.Owner)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
@ -237,7 +238,7 @@ namespace SharedLibraryCore.Services
|
||||
using (var context = new DatabaseContext(disableTracking: true))
|
||||
{
|
||||
var iqClients = from client in context.Clients
|
||||
where client.Level >= Player.Permission.Trusted
|
||||
where client.Level >= Permission.Trusted
|
||||
where client.Active
|
||||
select new ClientInfo()
|
||||
{
|
||||
|
@ -8,6 +8,7 @@ using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Dtos;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SharedLibraryCore.Objects;
|
||||
using static SharedLibraryCore.Database.Models.EFClient;
|
||||
|
||||
namespace SharedLibraryCore.Services
|
||||
{
|
||||
@ -35,7 +36,7 @@ namespace SharedLibraryCore.Services
|
||||
{
|
||||
await context.Clients
|
||||
.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
|
||||
@ -43,7 +44,7 @@ namespace SharedLibraryCore.Services
|
||||
{
|
||||
await context.Clients
|
||||
.Where(c => c.AliasLinkId == addedEntity.LinkId)
|
||||
.ForEachAsync(c => c.Level = Objects.Player.Permission.Flagged);
|
||||
.ForEachAsync(c => c.Level = Permission.Flagged);
|
||||
}
|
||||
|
||||
context.Penalties.Add(addedEntity);
|
||||
@ -221,10 +222,12 @@ namespace SharedLibraryCore.Services
|
||||
var iqPenalties = context.Penalties
|
||||
.Where(p => p.LinkId == linkId ||
|
||||
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.Expires == null || p.Expires > now);
|
||||
|
||||
|
||||
#if DEBUG == true
|
||||
var penaltiesSql = iqPenalties.ToSql();
|
||||
#endif
|
||||
@ -256,7 +259,7 @@ namespace SharedLibraryCore.Services
|
||||
{
|
||||
await internalContext.Clients
|
||||
.Where(c => c.AliasLinkId == p.LinkId)
|
||||
.ForEachAsync(c => c.Level = Player.Permission.User);
|
||||
.ForEachAsync(c => c.Level = EFClient.Permission.User);
|
||||
await internalContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ using System.Diagnostics;
|
||||
using Microsoft.EntityFrameworkCore.Query;
|
||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
|
||||
namespace SharedLibraryCore
|
||||
{
|
||||
@ -27,12 +28,13 @@ namespace SharedLibraryCore
|
||||
#endif
|
||||
public static Encoding EncodingType;
|
||||
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,
|
||||
State = Player.ClientState.Connected,
|
||||
Level = Player.Permission.Console,
|
||||
CurrentServer = server
|
||||
State = EFClient.ClientState.Connected,
|
||||
Level = EFClient.Permission.Console,
|
||||
CurrentServer = server,
|
||||
Name = "IW4MAdmin"
|
||||
};
|
||||
|
||||
public static string HttpRequest(string location, string header, string headerValue)
|
||||
@ -98,16 +100,16 @@ namespace SharedLibraryCore
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static Player.Permission MatchPermission(String str)
|
||||
public static EFClient.Permission MatchPermission(String str)
|
||||
{
|
||||
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())
|
||||
|| lookingFor.Contains(CurrentLocalization.LocalizationIndex[$"GLOBAL_PERMISSION_{Perm.ToString().ToUpper()}"].ToLower()))
|
||||
return Perm;
|
||||
|
||||
return Player.Permission.Banned;
|
||||
return EFClient.Permission.Banned;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -131,25 +133,25 @@ namespace SharedLibraryCore
|
||||
/// </summary>
|
||||
/// <param name="level">Specified player level</param>
|
||||
/// <returns></returns>
|
||||
public static String ConvertLevelToColor(Player.Permission level, string localizedLevel)
|
||||
public static String ConvertLevelToColor(EFClient.Permission level, string localizedLevel)
|
||||
{
|
||||
char colorCode = '6';
|
||||
// todo: maybe make this game independant?
|
||||
switch (level)
|
||||
{
|
||||
case Player.Permission.Banned:
|
||||
case EFClient.Permission.Banned:
|
||||
colorCode = '1';
|
||||
break;
|
||||
case Player.Permission.Flagged:
|
||||
case EFClient.Permission.Flagged:
|
||||
colorCode = '9';
|
||||
break;
|
||||
case Player.Permission.Owner:
|
||||
case EFClient.Permission.Owner:
|
||||
colorCode = '5';
|
||||
break;
|
||||
case Player.Permission.User:
|
||||
case EFClient.Permission.User:
|
||||
colorCode = '2';
|
||||
break;
|
||||
case Player.Permission.Trusted:
|
||||
case EFClient.Permission.Trusted:
|
||||
colorCode = '3';
|
||||
break;
|
||||
default:
|
||||
@ -159,7 +161,7 @@ namespace SharedLibraryCore
|
||||
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)
|
||||
{
|
||||
@ -392,9 +394,9 @@ namespace SharedLibraryCore
|
||||
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,
|
||||
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)
|
||||
{
|
||||
@ -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 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)
|
||||
{
|
||||
|
@ -1,16 +1,16 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WebfrontCore.Controllers.API
|
||||
{
|
||||
public class ApiController : BaseController
|
||||
{
|
||||
public IActionResult Index() => Ok($"IW4MAdmin API");
|
||||
public IActionResult Index()
|
||||
{
|
||||
return Ok($"IW4MAdmin API");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Event(bool shouldConsume = true)
|
||||
@ -28,12 +28,12 @@ namespace WebfrontCore.Controllers.API
|
||||
Id = server.GetHashCode(),
|
||||
Name = server.Hostname,
|
||||
MaxPlayers = server.MaxClients,
|
||||
CurrentPlayers = server.GetPlayersAsList().Count,
|
||||
CurrentPlayers = server.GetClientsAsList().Count,
|
||||
Map = server.CurrentMap,
|
||||
GameMode = server.Gametype,
|
||||
Port = server.GetPort(),
|
||||
Game = server.GameName.ToString(),
|
||||
Players = server.GetPlayersAsList()
|
||||
Players = server.GetClientsAsList()
|
||||
.Select(player => new
|
||||
{
|
||||
player.Name,
|
||||
@ -53,5 +53,23 @@ namespace WebfrontCore.Controllers.API
|
||||
|
||||
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 SharedLibraryCore;
|
||||
using WebfrontCore.ViewModels;
|
||||
using static SharedLibraryCore.Objects.Player;
|
||||
using static SharedLibraryCore.Database.Models.EFClient;
|
||||
|
||||
namespace WebfrontCore.Controllers
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ namespace WebfrontCore.Controllers
|
||||
Client = Client ?? new EFClient()
|
||||
{
|
||||
ClientId = -1,
|
||||
Level = Player.Permission.User,
|
||||
Level = EFClient.Permission.User,
|
||||
CurrentAlias = new EFAlias() { Name = "Web Console Guest" }
|
||||
};
|
||||
|
||||
@ -55,7 +55,7 @@ namespace WebfrontCore.Controllers
|
||||
try
|
||||
{
|
||||
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 };
|
||||
var stillExists = Manager.GetPrivilegedClients()[Client.ClientId];
|
||||
|
||||
@ -81,7 +81,7 @@ namespace WebfrontCore.Controllers
|
||||
else
|
||||
{
|
||||
Client.ClientId = 1;
|
||||
Client.Level = Player.Permission.Console;
|
||||
Client.Level = EFClient.Permission.Console;
|
||||
Client.CurrentAlias = new EFAlias() { Name = "IW4MAdmin" };
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Dtos;
|
||||
using SharedLibraryCore.Services;
|
||||
using System;
|
||||
@ -63,7 +64,7 @@ namespace WebfrontCore.Controllers
|
||||
var administeredPenaltiesMeta = await Manager.GetPenaltyService()
|
||||
.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()
|
||||
{
|
||||
Key = Localization["WEBFRONT_CLIENT_META_MASKED"],
|
||||
@ -122,7 +123,7 @@ namespace WebfrontCore.Controllers
|
||||
.OrderByDescending(a => a.Level)
|
||||
.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)
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SharedLibraryCore;
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using SharedLibraryCore.Dtos;
|
||||
using SharedLibraryCore.Objects;
|
||||
using System;
|
||||
@ -29,7 +30,7 @@ namespace WebfrontCore.Controllers
|
||||
public async Task<IActionResult> ExecuteAsync(int serverId, string command)
|
||||
{
|
||||
var server = Manager.GetServers().First(s => s.GetHashCode() == serverId);
|
||||
var client = new Player()
|
||||
var client = new EFClient()
|
||||
{
|
||||
ClientId = Client.ClientId,
|
||||
Level = Client.Level,
|
||||
|
@ -27,7 +27,7 @@ namespace WebfrontCore.Controllers
|
||||
ClientCount = s.ClientNum,
|
||||
MaxClients = s.MaxClients,
|
||||
GameType = s.Gametype,
|
||||
Players = s.GetPlayersAsList()
|
||||
Players = s.GetClientsAsList()
|
||||
.Select(p => new PlayerInfo
|
||||
{
|
||||
Name = p.Name,
|
||||
@ -36,7 +36,7 @@ namespace WebfrontCore.Controllers
|
||||
LevelInt = (int)p.Level
|
||||
}).ToList(),
|
||||
ChatHistory = s.ChatHistory,
|
||||
PlayerHistory = s.PlayerHistory.ToArray(),
|
||||
PlayerHistory = s.ClientHistory.ToArray(),
|
||||
};
|
||||
return PartialView("_ClientActivity", serverInfo);
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ namespace WebfrontCore.ViewComponents
|
||||
ClientCount = s.ClientNum,
|
||||
MaxClients = s.MaxClients,
|
||||
GameType = s.Gametype,
|
||||
PlayerHistory = s.PlayerHistory.ToArray(),
|
||||
Players = s.GetPlayersAsList()
|
||||
PlayerHistory = s.ClientHistory.ToArray(),
|
||||
Players = s.GetClientsAsList()
|
||||
.Select(p => new PlayerInfo()
|
||||
{
|
||||
Name = p.Name,
|
||||
|
@ -1,5 +1,6 @@
|
||||
Version 2.3:
|
||||
-added configuration option to ignore bots
|
||||
-updated anticheat slightly
|
||||
|
||||
Version 2.2:
|
||||
-upgraded projects to .NET 2.1
|
||||
|
Loading…
Reference in New Issue
Block a user