1
0
mirror of https://github.com/RaidMax/IW4M-Admin.git synced 2025-06-11 15:52:25 -05:00

more work on skill based team balance.

added on player disconnect to custom callbacks
This commit is contained in:
RaidMax
2018-10-25 08:14:39 -05:00
parent d84de353ff
commit fd087c5506
19 changed files with 315 additions and 110 deletions

View File

@ -37,7 +37,7 @@ namespace IW4MAdmin.Application.IO
Server = server;
}
public void PollForChanges()
public async Task PollForChanges()
{
while (!Server.Manager.ShutdownRequested())
{
@ -45,7 +45,7 @@ namespace IW4MAdmin.Application.IO
{
try
{
UpdateLogEvents();
await UpdateLogEvents();
}
catch (Exception e)
@ -59,7 +59,7 @@ namespace IW4MAdmin.Application.IO
}
}
private void UpdateLogEvents()
private async Task UpdateLogEvents()
{
long fileSize = Reader.Length;
@ -74,7 +74,7 @@ namespace IW4MAdmin.Application.IO
PreviousFileSize = fileSize;
var events = Reader.ReadEventsFromLog(Server, fileDiff, 0);
var events = await Reader.ReadEventsFromLog(Server, fileDiff, 0);
foreach (var ev in events)
{

View File

@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace IW4MAdmin.Application.IO
{
@ -22,7 +23,7 @@ namespace IW4MAdmin.Application.IO
Parser = parser;
}
public ICollection<GameEvent> ReadEventsFromLog(Server server, long fileSizeDiff, long startPosition)
public async Task<ICollection<GameEvent>> ReadEventsFromLog(Server server, long fileSizeDiff, long startPosition)
{
// allocate the bytes for the new log lines
List<string> logLines = new List<string>();
@ -30,6 +31,7 @@ namespace IW4MAdmin.Application.IO
// open the file as a stream
using (var rd = new StreamReader(new FileStream(LogFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Utilities.EncodingType))
{
// todo: max async
// take the old start position and go back the number of new characters
rd.BaseStream.Seek(-fileSizeDiff, SeekOrigin.End);
// the difference should be in the range of a int :P

View File

@ -5,6 +5,7 @@ using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using static SharedLibraryCore.Utilities;
namespace IW4MAdmin.Application.IO
@ -29,18 +30,19 @@ namespace IW4MAdmin.Application.IO
public int UpdateInterval => 1000;
public ICollection<GameEvent> ReadEventsFromLog(Server server, long fileSizeDiff, long startPosition)
public async Task<ICollection<GameEvent>> ReadEventsFromLog(Server server, long fileSizeDiff, long startPosition)
{
#if DEBUG == true
server.Logger.WriteDebug($"Begin reading {fileSizeDiff} from http log");
#endif
var events = new List<GameEvent>();
string b64Path = server.LogPath.ToBase64UrlSafeString();
var response = Api.Log(b64Path).Result;
var response = await Api.Log(b64Path);
if (!response.Success)
{
server.Logger.WriteError($"Could not get log server info of {LogFile}/{b64Path} ({server.LogPath})");
return events;
}
// parse each line

View File

@ -151,7 +151,9 @@ namespace IW4MAdmin.Application
{
Logger.WriteWarning($"Delayed event for {e.Origin} was ignored because the target has left");
// hack: don't do anything with the event because the target is invalid
e.Origin = null;
e.Type = GameEvent.EventType.Unknown;
}
}
Logger.WriteDebug($"Adding delayed event of type {e.Type} for {e.Origin} back for processing");
@ -265,11 +267,7 @@ namespace IW4MAdmin.Application
ThreadPool.GetAvailableThreads(out int availableThreads, out int m);
Logger.WriteDebug($"There are {workerThreads - availableThreads} active threading tasks");
#endif
#if DEBUG
await Task.Delay(10000);
#else
await Task.Delay(ConfigHandler.Configuration().RConPollRate);
#endif
}
// trigger the event processing loop to end

View File

@ -26,6 +26,7 @@ namespace IW4MAdmin
{
private static readonly Index loc = Utilities.CurrentLocalization.LocalizationIndex;
private GameLogEventDetection LogEvent;
public int Id { get; private set; }
public IW4MServer(IManager mgr, ServerConfiguration cfg) : base(mgr, cfg)
{
@ -33,30 +34,28 @@ namespace IW4MAdmin
public override int GetHashCode()
{
if (GameName == Game.IW4)
if ($"{IP}:{Port.ToString()}" == "66.150.121.184:28965")
{
// todo: make this better with collisions
int id = Math.Abs($"{IP}:{Port.ToString()}".Select(a => (int)a).Sum());
// hack: this is a nasty fix for get hashcode being changed
switch (id)
{
case 765:
return 886229536;
case 760:
return 1645744423;
case 761:
return 1645809959;
}
return id;
return 886229536;
}
else
if ($"{IP}:{Port.ToString()}" == "66.150.121.184:28960")
{
int id = HashCode.Combine(IP, Port);
return id < 0 ? Math.Abs(id) : id;
return 1645744423;
}
if ($"{IP}:{Port.ToString()}" == "66.150.121.184:28970")
{
return 1645809959;
}
if (Id == 0)
{
Id = HashCode.Combine(IP, Port);
Id = Id < 0 ? Math.Abs(Id) : Id;
}
return Id;
}
public async Task OnPlayerJoined(Player logClient)
@ -560,11 +559,13 @@ namespace IW4MAdmin
if (E.Type == GameEvent.EventType.Broadcast)
{
#if DEBUG == false
// this is a little ugly but I don't want to change the abstract class
if (E.Data != null)
{
await E.Owner.ExecuteCommandAsync(E.Data);
}
#endif
}
while (ChatHistory.Count > Math.Ceiling((double)ClientNum / 2))
@ -661,7 +662,7 @@ namespace IW4MAdmin
waiterList.Add(e);
}
// wait for all the disconnect tasks to finish
await Task.WhenAll(waiterList.Select(e => e.WaitAsync()));
await Task.WhenAll(waiterList.Select(e => e.WaitAsync(10 * 1000)));
waiterList.Clear();
// this are our new connecting clients
@ -686,7 +687,7 @@ namespace IW4MAdmin
}
// wait for all the connect tasks to finish
await Task.WhenAll(waiterList.Select(e => e.WaitAsync()));
await Task.WhenAll(waiterList.Select(e => e.WaitAsync(10 * 1000)));
if (ConnectionErrors > 0)
{
@ -700,7 +701,7 @@ namespace IW4MAdmin
catch (NetworkException e)
{
ConnectionErrors++;
if (ConnectionErrors == 1)
if (ConnectionErrors == 3)
{
Logger.WriteError($"{e.Message} {IP}:{Port}, {loc["SERVER_ERROR_POLLING"]}");
Logger.WriteDebug($"Internal Exception: {e.Data["internal_exception"]}");

View File

@ -0,0 +1,31 @@
var plugin = {
author: 'RaidMax',
version: 1.1,
name: 'Shared GUID Kicker Plugin',
onEventAsync: function (gameEvent, server) {
// make sure we only check for IW4(x)
if (server.GameName !== 2) {
return false;
}
// connect or join event
if (gameEvent.Type === 3) {
// this GUID seems to have been packed in a IW4 torrent and results in an unreasonable amount of people using the same GUID
if (gameEvent.Origin.NetworkId === -805366929435212061) {
gameEvent.Origin.Kick('Your GUID is generic. Delete players/guids.dat and rejoin', _IW4MAdminClient);
}
}
},
onLoadAsync: function (manager) {
},
onUnloadAsync: function () {
},
onTickAsync: function (server) {
}
};

View File

@ -0,0 +1,62 @@
var plugin = {
author: 'RaidMax',
version: 1.0,
name: 'VPN Detection Plugin',
manager: null,
logger: null,
vpnExceptionIds: [],
checkForVpn: function (origin) {
var exempt = false;
// prevent players that are exempt from being kicked
this.vpnExceptionIds.forEach(function (id) {
if (id === origin.ClientId) {
exempt = true;
return false;
}
});
if (exempt) {
return;
}
var usingVPN = false;
try {
var cl = new System.Net.Http.HttpClient();
var re = cl.GetAsync('https://api.xdefcon.com/proxy/check/?ip=' + origin.IPAddressString).Result;
var co = re.Content;
var parsedJSON = JSON.parse(co.ReadAsStringAsync().Result);
co.Dispose();
re.Dispose();
cl.Dispose();
usingVPN = parsedJSON.success && parsedJSON.proxy;
} catch (e) {
this.logger.WriteError(e.message);
}
if (usingVPN) {
this.logger.WriteInfo(origin + ' is using a VPN (' + origin.IPAddressString + ')');
origin.Kick(_localization.LocalizationIndex["SERVER_KICK_VPNS_NOTALLOWED"], _IW4MAdminClient);
}
},
onEventAsync: function (gameEvent, server) {
// connect event
if (gameEvent.Type === 3) {
this.checkForVpn(gameEvent.Origin);
}
},
onLoadAsync: function (manager) {
this.manager = manager;
this.logger = manager.GetLogger(0);
},
onUnloadAsync: function () {
},
onTickAsync: function (server) {
}
};