strip drive letter on gamelog server if running on linux

strip undecodable chacters from gamelog server log file
finish re work on alias add/update ( I think)
This commit is contained in:
RaidMax 2019-04-05 21:15:17 -05:00
parent 8ab89e113d
commit 863ba8b096
14 changed files with 157 additions and 109 deletions

3
.gitignore vendored
View File

@ -232,4 +232,5 @@ bootstrap-custom.min.css
launchSettings.json
/VpnDetectionPrivate.js
/Plugins/ScriptPlugins/VpnDetectionPrivate.js
**/Master/env_master
**/Master/env_master
/GameLogServer/log_env

View File

@ -36,8 +36,7 @@ namespace IW4MAdmin
override public async Task OnClientConnected(EFClient clientFromLog)
{
Logger.WriteDebug($"Client slot #{clientFromLog.ClientNumber} now reserved");
Clients[clientFromLog.ClientNumber] = new EFClient();
try
{
EFClient client = await Manager.GetClientService().GetUnique(clientFromLog.NetworkId);
@ -71,7 +70,7 @@ namespace IW4MAdmin
Clients[client.ClientNumber] = client;
client.State = EFClient.ClientState.Connected;
client.State = ClientState.Connected;
#if DEBUG == true
Logger.WriteDebug($"End PreConnect for {client}");
#endif
@ -207,7 +206,14 @@ namespace IW4MAdmin
var existingClient = GetClientsAsList().FirstOrDefault(_client => _client.Equals(E.Origin));
// they're already connected
if (existingClient != null)
{
return false;
}
CONNECT:
// we can go ahead and put them in
if (Clients[E.Origin.ClientNumber] == null)
{
#if DEBUG == true
@ -229,17 +235,12 @@ namespace IW4MAdmin
}
// for some reason there's still a client in the spot
else if (existingClient == null)
else
{
Logger.WriteWarning($"{E.Origin} is connecteding but {Clients[E.Origin.ClientNumber]} is currently in that client slot");
await OnClientDisconnected(Clients[E.Origin.ClientNumber]);
goto CONNECT;
}
else
{
return false;
}
}
else if (E.Type == GameEvent.EventType.Flag)

View File

@ -17,7 +17,7 @@
<SuppressCollectPythonCloudServiceFiles>true</SuppressCollectPythonCloudServiceFiles>
<Name>GameLogServer</Name>
<RootNamespace>GameLogServer</RootNamespace>
<InterpreterId>MSBuild|env|$(MSBuildProjectFullPath)</InterpreterId>
<InterpreterId>MSBuild|log_env|$(MSBuildProjectFullPath)</InterpreterId>
<EnableNativeCodeDebugging>False</EnableNativeCodeDebugging>
<Environment>DEBUG=True</Environment>
</PropertyGroup>
@ -50,7 +50,6 @@
<Folder Include="GameLogServer\" />
</ItemGroup>
<ItemGroup>
<Content Include="requirements.txt" />
<None Include="Stable.pubxml" />
</ItemGroup>
<ItemGroup>
@ -63,6 +62,18 @@
<PathEnvironmentVariable>PYTHONPATH</PathEnvironmentVariable>
<Architecture>X64</Architecture>
</Interpreter>
<Interpreter Include="log_env\">
<Id>log_env</Id>
<Version>3.6</Version>
<Description>log_env (Python 3.6 (64-bit))</Description>
<InterpreterPath>Scripts\python.exe</InterpreterPath>
<WindowsInterpreterPath>Scripts\pythonw.exe</WindowsInterpreterPath>
<PathEnvironmentVariable>PYTHONPATH</PathEnvironmentVariable>
<Architecture>X64</Architecture>
</Interpreter>
</ItemGroup>
<ItemGroup>
<Content Include="requirements.txt" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.Web.targets" />
<!-- Specify pre- and post-build commands in the BeforeBuild and

View File

@ -6,8 +6,7 @@ class LogReader(object):
def __init__(self):
self.log_file_sizes = {}
# (if the time between checks is greater, ignore ) - in seconds
# self.max_file_time_change = 60
self.max_file_time_change = 10
self.max_file_time_change = 30
def read_file(self, path):
# this removes old entries that are no longer valid
@ -17,33 +16,34 @@ class LogReader(object):
print('could not clear old logs')
print(e)
if os.name != 'nt':
path = re.sub(r'^[A-Z]\:', '', path)
path = re.sub(r'\\+', '/', path)
# prevent traversing directories
if re.search('r^.+\.\.\\.+$', path):
return False
# must be a valid log path and log file
if not re.search(r'^.+[\\|\/](.+)[\\|\/].+.log$', path):
return False
# set the initial size to the current file size
file_size = 0
# this is the first time the log has been requested
if path not in self.log_file_sizes:
self.log_file_sizes[path] = {
'length' : self.file_length(path),
'read': time.time()
}
return ''
# grab the previous values
last_length = self.log_file_sizes[path]['length']
# the file is being tracked already
# get the new file size
new_file_size = self.file_length(path)
# the log size was unable to be read (probably the wrong path)
if new_file_size < 0:
return False
# this is the first time the log has been requested
if path not in self.log_file_sizes:
self.log_file_sizes[path] = {
'length' : new_file_size,
'read': time.time()
}
return ''
# grab the previous values
last_length = self.log_file_sizes[path]['length']
file_size_difference = new_file_size - last_length
# update the new size and actually read the data
@ -61,7 +61,8 @@ class LogReader(object):
file_handle.seek(-length, 2)
file_data = file_handle.read(length)
file_handle.close()
return file_data.decode('utf-8')
# using ignore errors omits the pesky 0xb2 bytes we're reading in for some reason
return file_data.decode('utf-8', errors='ignore')
except Exception as e:
print('could not read the log file at {0}, wanted to read {1} bytes'.format(path, length))
print(e)

View File

@ -6,7 +6,6 @@ class LogResource(Resource):
def get(self, path):
path = urlsafe_b64decode(path).decode('utf-8')
log_info = reader.read_file(path)
print(log_info)
return {
'success' : log_info is not False,

View File

@ -1,29 +1,29 @@
from flask_restful import Resource
from flask import request
import requests
import os
import subprocess
import re
#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
#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
#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

View File

@ -1,7 +1,7 @@
from flask import Flask
from flask_restful import Api
from .log_resource import LogResource
from .restart_resource import RestartResource
#from .restart_resource import RestartResource
import logging
app = Flask(__name__)
@ -11,4 +11,4 @@ def init():
log.setLevel(logging.ERROR)
api = Api(app)
api.add_resource(LogResource, '/log/<string:path>')
api.add_resource(RestartResource, '/restart')
#api.add_resource(RestartResource, '/restart')

View File

@ -1,26 +1,12 @@
aniso8601==3.0.2
APScheduler==3.5.3
certifi==2018.10.15
chardet==3.0.4
click==6.7
aniso8601==6.0.0
Click==7.0
Flask==1.0.2
Flask-JWT==0.3.2
Flask-JWT-Extended==3.8.1
Flask-RESTful==0.3.6
idna==2.7
itsdangerous==0.24
Flask-RESTful==0.3.7
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.0
marshmallow==3.0.0b8
pip==9.0.3
psutil==5.4.8
pygal==2.4.0
PyJWT==1.4.2
pytz==2018.7
requests==2.20.0
setuptools==40.5.0
six==1.11.0
timeago==1.0.8
tzlocal==1.5.1
urllib3==1.24
Werkzeug==0.14.1
MarkupSafe==1.1.1
pip==10.0.1
pytz==2018.9
setuptools==39.0.1
six==1.12.0
Werkzeug==0.15.2

View File

@ -51,7 +51,6 @@ namespace IW4MAdmin.Plugins.Stats
{
await Manager.AddMessageAsync(E.Origin.ClientId, await StatManager.GetIdForServer(E.Owner), E.Data);
}
break;
case GameEvent.EventType.MapChange:
Manager.SetTeamBased(await StatManager.GetIdForServer(E.Owner), E.Owner.Gametype != "dm");
@ -79,6 +78,22 @@ namespace IW4MAdmin.Plugins.Stats
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
if (killInfo.Length >= 14)
{
if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1)
{
return;
}
// this treats "world" damage as self damage
if (E.Origin.ClientId <= 1)
{
E.Origin = E.Target;
}
if (E.Target.ClientId <= 1)
{
E.Target = E.Origin;
}
await Manager.AddScriptHit(false, E.Time, E.Origin, E.Target, await StatManager.GetIdForServer(E.Owner), S.CurrentMap.Name, killInfo[7], killInfo[8],
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15]);
}
@ -86,13 +101,18 @@ namespace IW4MAdmin.Plugins.Stats
case GameEvent.EventType.Kill:
if (!E.Owner.CustomCallback)
{
if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1)
{
return;
}
// this treats "world" damage as self damage
if (E.Origin.ClientId == 1)
if (E.Origin.ClientId <= 1)
{
E.Origin = E.Target;
}
if (E.Target.ClientId == 1)
if (E.Target.ClientId <= 1)
{
E.Target = E.Origin;
}
@ -103,13 +123,18 @@ namespace IW4MAdmin.Plugins.Stats
case GameEvent.EventType.Damage:
if (!E.Owner.CustomCallback)
{
if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1)
{
return;
}
// this treats "world" damage as self damage
if (E.Origin.ClientId == 1)
if (E.Origin.ClientId <= 1)
{
E.Origin = E.Target;
}
if (E.Target.ClientId == 1)
if (E.Target.ClientId <= 1)
{
E.Target = E.Origin;
}
@ -121,6 +146,22 @@ namespace IW4MAdmin.Plugins.Stats
killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
if (killInfo.Length >= 14)
{
if (E.Origin.ClientId <= 1 && E.Target.ClientId <= 1)
{
return;
}
// this treats "world" damage as self damage
if (E.Origin.ClientId <= 1)
{
E.Origin = E.Target;
}
if (E.Target.ClientId <= 1)
{
E.Target = E.Origin;
}
await Manager.AddScriptHit(true, E.Time, E.Origin, E.Target, await StatManager.GetIdForServer(E.Owner), S.CurrentMap.Name, killInfo[7], killInfo[8],
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13], killInfo[14], killInfo[15]);
}

View File

@ -18,7 +18,7 @@ namespace Tests
{
File.WriteAllText("test_mp.log", "test_log_file");
IW4MAdmin.Application.Localization.Configure.Initialize("en-US");
//IW4MAdmin.Application.Localization.Configure.Initialize("en-US");
Manager = ApplicationManager.GetInstance();
@ -41,7 +41,7 @@ namespace Tests
Maps = new List<MapConfiguration>(),
RConPollRate = 10000
};
Manager.ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("test.json");
Manager.ConfigHandler = new BaseConfigurationHandler<ApplicationConfiguration>("test");
Manager.ConfigHandler.Set(config);
Manager.Init().Wait();

View File

@ -34,7 +34,7 @@ namespace Tests
[Fact]
public void AreCommandAliasesUnique()
{
var mgr = IW4MAdmin.Application.Program.ServerManager;
var mgr = Program.ServerManager;
bool test = mgr.GetCommands().Count == mgr.GetCommands().Select(c => c.Alias).Distinct().Count();
Assert.True(test, "command aliases are not unique");

View File

@ -28,7 +28,7 @@ namespace SharedLibraryCore.Configuration
public string WebfrontBindUrl { get; set; }
[LocalizedDisplayName("WEBFRONT_CONFIGURATION_MANUAL_URL")]
public string ManualWebfrontUrl { get; set; }
public string WebfrontUrl => string.IsNullOrEmpty(ManualWebfrontUrl) ? WebfrontBindUrl.Replace("0.0.0.0", "127.0.0.1") : ManualWebfrontUrl;
public string WebfrontUrl => string.IsNullOrEmpty(ManualWebfrontUrl) ? WebfrontBindUrl?.Replace("0.0.0.0", "127.0.0.1") : ManualWebfrontUrl;
[LocalizedDisplayName("SETUP_USE_CUSTOMENCODING")]
public bool EnableCustomParserEncoding { get; set; }
[LocalizedDisplayName("WEBFRONT_CONFIGURATION_ENCODING")]

View File

@ -17,7 +17,6 @@ namespace SharedLibraryCore.Services
{
using (var context = new DatabaseContext())
{
int? linkId = null;
int? aliasId = null;
@ -45,23 +44,31 @@ namespace SharedLibraryCore.Services
NetworkId = entity.NetworkId
};
if (linkId.HasValue)
{
client.AliasLinkId = linkId.Value;
}
else
{
client.AliasLink = new EFAliasLink();
}
// they're just using a new GUID
if (aliasId.HasValue)
{
client.CurrentAliasId = aliasId.Value;
client.AliasLinkId = linkId.Value;
}
// link was found but they don't have an exact alias
else if (!aliasId.HasValue && linkId.HasValue)
{
client.AliasLinkId = linkId.Value;
client.CurrentAlias = new Alias()
{
Name = entity.Name,
DateAdded = DateTime.UtcNow,
IPAddress = entity.IPAddress,
LinkId = linkId.Value
};
}
// brand new players (supposedly)
else
{
client.AliasLink = new EFAliasLink();
client.CurrentAlias = new Alias()
{
Name = entity.Name,
@ -69,11 +76,6 @@ namespace SharedLibraryCore.Services
IPAddress = entity.IPAddress,
Link = client.AliasLink,
};
if (client.CurrentAlias.Link == null)
{
client.CurrentAlias.LinkId = linkId.Value;
}
}
context.Clients.Add(client);
@ -126,6 +128,11 @@ namespace SharedLibraryCore.Services
var oldAliasLink = entity.AliasLink;
// update all the clients that have the old alias link
await context.Clients
.Where(_client => _client.AliasLinkId == oldAliasLink.AliasLinkId)
.ForEachAsync(_client => _client.AliasLinkId = newAliasLink.AliasLinkId);
entity.AliasLink = newAliasLink;
entity.AliasLinkId = newAliasLink.AliasLinkId;

View File

@ -22,7 +22,8 @@ namespace SharedLibraryCore
public static class Utilities
{
#if DEBUG == true
public static string OperatingDirectory => $"{Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)}{Path.DirectorySeparatorChar}";
public static string OperatingDirectory => @"X:\IW4MAdmin\Application\bin\Debug\netcoreapp2.2\";
//public static string OperatingDirectory => $"{Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)}{Path.DirectorySeparatorChar}";
#else
public static string OperatingDirectory => $"{Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)}{Path.DirectorySeparatorChar}..{Path.DirectorySeparatorChar}";
#endif