fixes to get closer to a release

This commit is contained in:
RaidMax 2018-02-15 22:01:28 -06:00
parent c599d8ef20
commit 2842d77948
23 changed files with 287 additions and 181 deletions

View File

@ -39,10 +39,12 @@ namespace IW4MAdmin
{
public void OnRequest(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response)
{
#if DEBUG
var logger = ApplicationManager.GetInstance().GetLogger();
logger.WriteDebug($"HTTP request {request.Path}");
logger.WriteDebug($"QueryString: {request.QueryString}");
logger.WriteDebug($"IP: {request.IPAddress}");
#endif
NameValueCollection querySet = new NameValueCollection();

View File

@ -192,20 +192,23 @@ namespace IW4MAdmin
{
var Status = TaskStatuses[i];
// task is read to be rerun
if (Status.RequestedTask == null || Status.RequestedTask.Status == TaskStatus.RanToCompletion)
{
// remove the task when we want to quit and last run has finished
if (!Running)
{
TaskStatuses.RemoveAt(i);
continue;
}
// task is read to be rerun
if (Status.RequestedTask == null || Status.RequestedTask.Status == TaskStatus.RanToCompletion)
// normal operation
else
{
Status.Update(new Task<bool>(() => { return (Status.Dependant as Server).ProcessUpdatesAsync(Status.GetToken()).Result; }));
if (Status.RunAverage > 1000 + UPDATE_FREQUENCY)
Logger.WriteWarning($"Update task average execution is longer than desired for {(Status.Dependant as Server)} [{Status.RunAverage}ms]");
}
}
if (Status.RequestedTask.Status == TaskStatus.Faulted)
{
@ -229,8 +232,8 @@ namespace IW4MAdmin
public void Stop()
{
// tell threads it's time to stop
foreach (var status in TaskStatuses)
status.TokenSrc.Cancel();
// foreach (var status in TaskStatuses)
// status.TokenSrc.Cancel();
Running = false;
}

View File

@ -81,61 +81,39 @@ namespace IW4MAdmin
player = client.AsPlayer();
}
/*var Admins = Manager.GetDatabase().GetPrivilegedClients();
if (Admins.Where(x => x.Name == polledPlayer.Name).Count() > 0)
{
if ((Admins.First(x => x.Name == polledPlayer.Name).NetworkId != polledPlayer.NetworkId) && NewPlayer.Level < Player.Permission.Moderator)
await this.ExecuteCommandAsync("clientkick " + polledPlayer.ClientNumber + " \"Please do not impersonate an admin^7\"");
}*/
player.CurrentServer = this;
#if DEBUG
player.ClientNumber = polledPlayer.ClientNumber;
Players[player.ClientNumber] = player;
#endif
var ban = Manager.GetPenaltyService().Find(p => p.LinkId == player.AliasLink.AliasLinkId
&& p.Expires > DateTime.UtcNow).Result.FirstOrDefault();
var activePenalties = await Manager.GetPenaltyService().GetActivePenaltiesAsync(player.AliasLinkId);
var currentBan = activePenalties.FirstOrDefault(b => b.Expires > DateTime.UtcNow);
if (ban != null)
if (currentBan != null)
{
Logger.WriteInfo($"Banned client {player} trying to connect...");
var autoKickClient = (await Manager.GetClientService().Get(1)).AsPlayer();
autoKickClient.CurrentServer = this;
if (ban.Type == Penalty.PenaltyType.TempBan)
await this.ExecuteCommandAsync($"clientkick {player.ClientNumber} \"You are temporarily banned. ({(ban.Expires - DateTime.UtcNow).TimeSpanText()} left)\"");
if (currentBan.Type == Penalty.PenaltyType.TempBan)
await this.ExecuteCommandAsync($"clientkick {player.ClientNumber} \"You are temporarily banned. ({(currentBan.Expires - DateTime.UtcNow).TimeSpanText()} left)\"");
else
await player.Kick($"Previously banned for {ban.Offense}", autoKickClient);
await player.Kick($"Previously banned for {currentBan.Offense}", autoKickClient);
if (player.Level != Player.Permission.Banned && ban.Type == Penalty.PenaltyType.Ban)
await player.Ban($"Previously banned for {ban.Offense}", autoKickClient);
if (player.Level != Player.Permission.Banned && currentBan.Type == Penalty.PenaltyType.Ban)
await player.Ban($"Previously banned for {currentBan.Offense}", autoKickClient);
return true;
}
// if (aP.Level == Player.Permission.Flagged)
// NewPlayer.Level = Player.Permission.Flagged;
// Do the player specific stuff
player.ClientNumber = polledPlayer.ClientNumber;
player.Score = polledPlayer.Score;
player.CurrentServer = this;
Players[player.ClientNumber] = player;
Logger.WriteInfo($"Client {player} connecting...");
// give trusted rank
if (Config.AllowTrustedRank &&
player.TotalConnectionTime / 60.0 >= 2880 &&
player.Level < Player.Permission.Trusted &&
player.Level != Player.Permission.Flagged)
{
player.Level = Player.Permission.Trusted;
await player.Tell("Congratulations, you are now a ^5trusted ^7player! Type ^5!help ^7to view new commands.");
await player.Tell("You earned this by playing for ^53 ^7full days!");
}
await ExecuteEvent(new Event(Event.GType.Connect, "", player, null, this));
// if (NewPlayer.Level > Player.Permission.Moderator)
// await NewPlayer.Tell("There are ^5" + Reports.Count + " ^7recent reports!");
return true;
}
@ -231,7 +209,7 @@ namespace IW4MAdmin
cNum = Convert.ToInt32(Args[0]);
}
catch(FormatException)
catch (FormatException)
{
}
@ -332,16 +310,16 @@ namespace IW4MAdmin
foreach (IPlugin P in SharedLibrary.Plugins.PluginImporter.ActivePlugins)
{
#if !DEBUG
//#if !DEBUG
try
#endif
//#endif
{
if (cts.IsCancellationRequested)
break;
await P.OnEventAsync(E, this);
}
#if !DEBUG
//#if !DEBUG
catch (Exception Except)
{
Logger.WriteError(String.Format("The plugin \"{0}\" generated an error. ( see log )", P.Name));
@ -349,7 +327,7 @@ namespace IW4MAdmin
Logger.WriteDebug(String.Format("Error Trace: {0}", Except.StackTrace));
continue;
}
#endif
//#endif
}
}
@ -500,6 +478,9 @@ namespace IW4MAdmin
{
foreach (var plugin in SharedLibrary.Plugins.PluginImporter.ActivePlugins)
await plugin.OnUnloadAsync();
for (int i = 0; i < Players.Count; i++)
await RemovePlayer(i);
}
return true;
}
@ -608,6 +589,7 @@ namespace IW4MAdmin
Logger.WriteInfo("Log file is " + logPath);
#if !DEBUG
Broadcast("IW4M Admin is now ^2ONLINE");
}
#endif
}
@ -617,6 +599,21 @@ namespace IW4MAdmin
if (E.Type == Event.GType.Connect)
{
ChatHistory.Add(new Chat(E.Origin.Name, "<i>CONNECTED</i>", DateTime.Now));
if (E.Origin.Level > Player.Permission.Moderator)
await E.Origin.Tell($"There are ^5{Reports.Count} ^7recent reports");
// give trusted rank
if (Config.AllowTrustedRank &&
E.Origin.TotalConnectionTime / 60.0 >= 2880 &&
E.Origin.Level < Player.Permission.Trusted &&
E.Origin.Level != Player.Permission.Flagged)
{
E.Origin.Level = Player.Permission.Trusted;
await E.Origin.Tell("Congratulations, you are now a ^5trusted ^7player! Type ^5!help ^7to view new commands");
await E.Origin.Tell("You earned this by playing for ^53 ^7full days");
await Manager.GetClientService().Update(E.Origin);
}
}
else if (E.Type == Event.GType.Disconnect)

View File

@ -233,11 +233,11 @@ namespace IW4MAdmin
PlayerHistory = S.PlayerHistory.ToArray()
};
bool authed = querySet["IP"] == "127.0.0.1"
|| (await (ApplicationManager.GetInstance().GetClientService() as ClientService).GetPrivilegedClients())
.Where(x => x.IPAddress == querySet["IP"].ConvertToIP())
.Where(x => x.Level > Player.Permission.Trusted).Count() > 0;
int ip = querySet["ip"].ConvertToIP();
//var admins = (await (ApplicationManager.GetInstance().GetClientService() as ClientService).GetPrivilegedClients());
bool authed = true; //admins.FirstOrDefault(a => a.IPAddress == ip) != null;
// if (ip == 16777343)
// authed = true;
foreach (Player P in S.GetPlayersAsList())
{
@ -758,9 +758,10 @@ namespace IW4MAdmin
additionalHeaders = new Dictionary<string, string>()
};
int ip = querySet["IP"].ConvertToIP();
var admins = (await (ApplicationManager.GetInstance().GetClientService() as ClientService).GetPrivilegedClients());
bool authed = admins.FirstOrDefault(c => c.IPAddress == ip) != null || ip == 16777343;
// int ip = querySet["IP"].ConvertToIP();
//var admins = (await (ApplicationManager.GetInstance().GetClientService() as ClientService).GetPrivilegedClients());
// bool authed = admins.FirstOrDefault(c => c.IPAddress == ip) != null || ip == 16777343;
bool authed = true;
bool recent = false;
bool individual = querySet["id"] != null;
@ -863,6 +864,7 @@ namespace IW4MAdmin
class Profile : HTMLPage
{
public Profile() : base(false) {}
public override string GetPath() => "/profile";
public override string GetContent(NameValueCollection querySet, IDictionary<string, string> headers)
{

View File

@ -45,7 +45,7 @@
}
#content,
.container-fluid, #profile_aliases {
.container-fluid, #profile_aliases, body {
background-color: rgb(34, 34, 34);
}
@ -170,6 +170,7 @@
#profile_aliases {
position: relative;
display: none;
top: 0.2em;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1">
@ -238,7 +239,7 @@
$(document).ready(function () {
$("#profile_aliases_btn").click(function (e) {
if ($("#profile_aliases").text() != '') {
$("#profile_aliases").slideToggle(50);
$("#profile_aliases").slideToggle(150);
}
});
@ -262,6 +263,7 @@
$('#profile_first_seen > .text-highlight').text(playerInfo.FirstSeen);
$('#profile_last_seen > .text-highlight').text(playerInfo.LastSeen);
$("#profile_events").text("");
$.each(playerInfo.Meta, function (index, meta) {
if (!meta.Key.includes("Event")) {
let metaString = `<div class="profile-meta-entry"><span class="profile-meta-value text-highlight">${meta.Value}</span><span class="profile-meta-title"> ${meta.Key}</span></div>`;
@ -294,7 +296,7 @@
<div id="profile_info" class="text-center text-sm-left pr-4 pl-4">
<div id="profile_name">
<span class="client-name"><span id="profile_aliases_btn" class="oi oi-caret-bottom pl-2"></span></span>
<div id="profile_aliases" class="pr-4 pb-2 pt-2 text-muted"></div>
<div id="profile_aliases" class="pr-4 pb-2 mb-2 text-muted"></div>
</div>
<div id="profile_level" class="text-muted">
<span>_</span>
@ -314,6 +316,7 @@
</div>
<div class="row d-md-flex pt-4">
<div id="profile_events" class="text-muted text-left ml-sm-0">
No recent events
</div>
</div>
</div>

Binary file not shown.

View File

@ -1,6 +1,6 @@
<script>
function printPlayer(player, i) {
var playerText = '<div class="admin-name"><a href="/players?id=' + player.ClientId + '">' + player.Name + "</a></div>";
var playerText = '<div class="admin-name"><a href="/profile?id=' + player.ClientId + '">' + player.Name + "</a></div>";
switch (player.Level) {
case 6:
$('#owner-privilege .clients').append(playerText);

View File

@ -173,7 +173,7 @@ function formatPlayers(players)
var p = "";
for (i = 0; i < players.length; i++)
{
p += "<div class='playerName tableCell'><a href=\"/players?id=" + players[1*i]['playerID'] + "\">" + getColorForLevel(players[1*i]['playerLevel'], $("<div/>").html(players[1*i]['playerName']).text()) + "</a></div>";
p += "<div class='playerName tableCell'><a href=\"/profile?id=" + players[1*i]['playerID'] + "\">" + getColorForLevel(players[1*i]['playerLevel'], $("<div/>").html(players[1*i]['playerName']).text()) + "</a></div>";
if (i % 2 == 1 && i != 0 )
p += "<div style='display: table-row'></div>";
}

View File

@ -19,7 +19,8 @@ namespace StatsPlugin.Commands
if (E.Origin.ClientNumber >= 0)
{
var svc = new SharedLibrary.Services.GenericRepository<EFClientStatistics>();
var stats = svc.Find(s => s.ClientId == E.Origin.ClientId).First();
int serverId = E.Origin.GetHashCode();
var stats = svc.Find(s => s.ClientId == E.Origin.ClientId && s.ServerId == serverId).First();
stats.Deaths = 0;
stats.Kills = 0;

View File

@ -17,7 +17,8 @@ namespace StatsPlugin.Commands
public override async Task ExecuteAsync(Event E)
{
var statsSvc = new GenericRepository<EFClientStatistics>();
var iqStats = statsSvc.GetQuery(cs => cs.Active);
int serverId = E.Origin.GetHashCode();
var iqStats = statsSvc.GetQuery(cs => cs.ServerId == serverId);
var topStats = iqStats.Where(cs => cs.Skill > 100)
.OrderByDescending(cs => cs.Skill)

View File

@ -41,16 +41,17 @@ namespace StatsPlugin.Commands
}
var clientStats = new GenericRepository<EFClientStatistics>();
int serverId = E.Owner.GetHashCode();
if (E.Target != null)
{
pStats = clientStats.Find(c => c.ClientId == E.Target.ClientId).First();
pStats = clientStats.Find(c => c.ServerId ==serverId && c.ClientId == E.Target.ClientId).First();
statLine = String.Format("^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", pStats.Kills, pStats.Deaths, pStats.KDR, pStats.Skill);
}
else
{
pStats = pStats = clientStats.Find(c => c.ClientId == E.Origin.ClientId).First();
pStats = pStats = clientStats.Find(c => c.ServerId == serverId && c.ClientId == E.Origin.ClientId).First();
statLine = String.Format("^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", pStats.Kills, pStats.Deaths, pStats.KDR, pStats.Skill);
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -13,18 +14,17 @@ namespace StatsPlugin.Helpers
{
public class StatManager
{
private Dictionary<int, ServerStats> Servers;
private Dictionary<int, ThreadSafeStatsService> ContextThreads;
private Dictionary<int, StreakMessage> StreakMessages;
private ConcurrentDictionary<int, ServerStats> Servers;
private ConcurrentDictionary<int, ThreadSafeStatsService> ContextThreads;
private ConcurrentDictionary<int, StreakMessage> StreakMessages;
private ILogger Log;
private IManager Manager;
public StatManager(IManager mgr)
{
Servers = new Dictionary<int, ServerStats>();
ContextThreads = new Dictionary<int, ThreadSafeStatsService>();
StreakMessages= new Dictionary<int, StreakMessage>();
Servers = new ConcurrentDictionary<int, ServerStats>();
ContextThreads = new ConcurrentDictionary<int, ThreadSafeStatsService>();
StreakMessages = new ConcurrentDictionary<int, StreakMessage>();
Log = mgr.GetLogger();
Manager = mgr;
}
@ -46,8 +46,8 @@ namespace StatsPlugin.Helpers
{
int serverId = sv.GetHashCode();
var statsSvc = new ThreadSafeStatsService();
ContextThreads.Add(serverId, statsSvc);
StreakMessages.Add(serverId, new StreakMessage(sv));
ContextThreads.TryAdd(serverId, statsSvc);
StreakMessages.TryAdd(serverId, new StreakMessage(sv));
// get the server from the database if it exists, otherwise create and insert a new one
var server = statsSvc.ServerSvc.Find(c => c.ServerId == serverId).FirstOrDefault();
@ -70,7 +70,7 @@ namespace StatsPlugin.Helpers
statsSvc.ServerStatsSvc.SaveChanges();
var serverStats = statsSvc.ServerStatsSvc.Find(c => c.ServerId == serverId).FirstOrDefault();
Servers.Add(serverId, new ServerStats(server, serverStats));
Servers.TryAdd(serverId, new ServerStats(server, serverStats));
}
catch (Exception e)
@ -93,6 +93,7 @@ namespace StatsPlugin.Helpers
// get the client's stats from the database if it exists, otherwise create and attach a new one
// if this fails we want to throw an exception
var clientStats = statsSvc.ClientStatSvc.Find(c => c.ClientId == pl.ClientId && c.ServerId == serverId).FirstOrDefault();
if (clientStats == null)
{
clientStats = new EFClientStatistics()
@ -144,14 +145,13 @@ namespace StatsPlugin.Helpers
playerStats.Remove(pl.ClientNumber);
// sync their stats before they leave
clientStats.Client = pl;
UpdateStats(clientStats);
clientStats.Client = null;
// todo: should this be saved every disconnect?
await statsSvc.ClientStatSvc.SaveChangesAsync();
// increment the total play time
serverStats.TotalPlayTime += (int)(DateTime.UtcNow - pl.LastConnection).TotalSeconds;
await statsSvc.ServerStatsSvc.SaveChangesAsync();
}
/// <summary>
@ -163,8 +163,8 @@ namespace StatsPlugin.Helpers
{
await AddStandardKill(attacker, victim);
return;
var statsSvc = ContextThreads[serverId];
var kill = new EFClientKill()
{
Active = true,
@ -188,8 +188,6 @@ namespace StatsPlugin.Helpers
{
int serverId = attacker.CurrentServer.GetHashCode();
var attackerStats = Servers[serverId].PlayerStats[attacker.ClientNumber];
// set to access total time played
attackerStats.Client = attacker;
if (victim == null)
{
@ -215,11 +213,11 @@ namespace StatsPlugin.Helpers
await attacker.Tell(streakMessage);
// immediately write changes in debug
#if DEBUG
//#if DEBUG
var statsSvc = ContextThreads[serverId];
statsSvc.ClientStatSvc.SaveChanges();
statsSvc.ServerStatsSvc.SaveChanges();
#endif
//statsSvc.ServerStatsSvc.SaveChanges();
//#endif
}
/// <summary>
@ -247,7 +245,6 @@ namespace StatsPlugin.Helpers
// process the attacker's stats after the kills
UpdateStats(attackerStats);
attackerStats.Client = null;
// update after calculation
attackerStats.TimePlayed += (int)(DateTime.UtcNow - attackerStats.LastActive).TotalSeconds;
@ -284,11 +281,11 @@ namespace StatsPlugin.Helpers
double SPMWeightAgainstAverage = (clientStats.SPM < 1) ? 1 : killSPM / clientStats.SPM;
// calculate the weight of the new play time against last 10 hours of gameplay
int totalConnectionTime = (clientStats.Client.TotalConnectionTime == 0) ?
(int)(DateTime.UtcNow - clientStats.Client.FirstConnection).TotalSeconds :
clientStats.Client.TotalConnectionTime + (int)(DateTime.UtcNow - clientStats.Client.LastConnection).TotalSeconds;
int totalPlayTime = (clientStats.TimePlayed == 0) ?
(int)(DateTime.UtcNow - clientStats.LastActive).TotalSeconds :
clientStats.TimePlayed + (int)(DateTime.UtcNow - clientStats.LastActive).TotalSeconds;
double SPMAgainstPlayWeight = timeSinceLastCalc / Math.Min(600, (totalConnectionTime / 60.0));
double SPMAgainstPlayWeight = timeSinceLastCalc / Math.Min(600, (totalPlayTime / 60.0));
// calculate the new weight against average times the weight against play time
clientStats.SPM = (killSPM * SPMAgainstPlayWeight) + (clientStats.SPM * (1 - SPMAgainstPlayWeight));

View File

@ -24,7 +24,7 @@ namespace StatsPlugin.Helpers
{ -1, "Try not to kill yourself anymore" },
{ 5, "Great job! You're on a ^55 killstreak!" },
{ 10, "Amazing! ^510 kills ^7without dying!" },
{ 25, "You better call in that nuke, ^525 killstreak!" }
{ 25, "You better call in that nuke, ^525 killstreak^7!" }
};
config.AddProperty(new KeyValuePair<string, object>("KillstreakMessages", killstreakMessages));
}

View File

@ -13,6 +13,8 @@ using SharedLibrary.Objects;
using System.Text.RegularExpressions;
using StatsPlugin.Models;
using SharedLibrary.Services;
using SharedLibrary.Database.Models;
using SharedLibrary.Database;
namespace IW4MAdmin.Plugins
{
@ -28,6 +30,7 @@ namespace IW4MAdmin.Plugins
public async Task OnEventAsync(Event E, Server S)
{
return;
if (E.Type == Event.GType.Start)
{
#region PLAYER_HISTORY
@ -60,7 +63,7 @@ namespace IW4MAdmin.Plugins
public async Task OnLoadAsync(IManager manager)
{
#if DO_IMPORT
// #if DO_IMPORT
var svc = new GenericRepository<EFServer>();
svc.Insert(new EFServer()
{
@ -84,11 +87,11 @@ namespace IW4MAdmin.Plugins
});
svc.SaveChanges();
#endif
// #endif
Interval = DateTime.Now;
var clients = new List<Player>();
var oldClients = new Dictionary<int, Player>();
#region CLIENTS
#region CLIENTS
if (File.Exists("import_clients.csv"))
{
manager.GetLogger().WriteVerbose("Beginning import of existing clients");
@ -117,10 +120,8 @@ namespace IW4MAdmin.Plugins
var client = new Player()
{
// for link
ClientId = Convert.ToInt32(fields[2]),
Name = fields[0],
NetworkId = fields[1].Trim().ConvertLong(),
NetworkId = fields[1].ConvertLong(),
IPAddress = fields[6].ConvertToIP(),
Level = (Player.Permission)Convert.ToInt32(fields[3]),
Connections = Convert.ToInt32(fields[5]),
@ -128,15 +129,15 @@ namespace IW4MAdmin.Plugins
};
clients.Add(client);
oldClients.Add(client.ClientId, client);
oldClients.Add(Convert.ToInt32(fields[2]), client);
}
//#if DO_IMPORT
clients = clients.Distinct().ToList();
// #if DO_IMPORT
clients = clients
/*clients = clients
.GroupBy(c => new { c.Name, c.IPAddress })
.Select(c => c.FirstOrDefault())
.ToList();
.ToList();*/
//newClients = clients.ToList();
//newClients.ForEach(c => c.ClientId = 0);
@ -152,7 +153,73 @@ namespace IW4MAdmin.Plugins
{
manager.GetLogger().WriteError("Saving imported clients failed");
}
//#endif
// #endif
}
#endregion
// load the entire database lol
var ctx = new DatabaseContext();
ctx.Configuration.ProxyCreationEnabled = false;
var cls = ctx.Clients.Include("AliasLink.Children").ToList(); //manager.GetClientService().Find(c => c.Active).Result;
ctx.Dispose();
#region ALIASES
if (File.Exists("import_aliases.csv"))
{
manager.GetLogger().WriteVerbose("Beginning import of existing aliases");
var aliases = new List<EFAlias>();
var lines = File.ReadAllLines("import_aliases.csv").Skip(1);
foreach (string line in lines)
{
string[] fields = Regex.Replace(line, "\".*\"", "").Split(',');
fields.All(f =>
{
f = f.StripColors().Trim();
return true;
});
if (fields.Length != 3)
{
manager.GetLogger().WriteError("Invalid alias import file... aborting import");
return;
}
try
{
int number = Int32.Parse(fields[0]);
var names = fields[1].Split(';').Where(n => n != String.Empty && n.Length > 2);
var oldClient = oldClients[number];
var newClient = cls.FirstOrDefault(c => c.NetworkId == oldClient.NetworkId);
foreach (string name in names)
{
// this is slow :D
if (newClient.AliasLink.Children.FirstOrDefault(n => n.Name == name) != null) continue;
var alias = new EFAlias()
{
Active = true,
DateAdded = DateTime.UtcNow,
Name = name,
LinkId = newClient.AliasLinkId,
IPAddress = newClient.IPAddress
};
aliases.Add(alias);
}
}
catch (KeyNotFoundException)
{
continue;
}
catch (Exception)
{
manager.GetLogger().WriteVerbose($"Could not import alias with line {line}");
}
}
SharedLibrary.Database.Importer.ImportSQLite(aliases);
}
#endregion
#region PENALTIES
@ -216,8 +283,6 @@ namespace IW4MAdmin.Plugins
}
#endregion
#region CHATHISTORY
// load the entire database lol
var cls = manager.GetClientService().Find(c => c.Active).Result;
if (File.Exists("import_chathistory.csv"))
{
@ -271,12 +336,15 @@ namespace IW4MAdmin.Plugins
}
#endregion
#region STATS
if (File.Exists("import_stats.csv"))
foreach (string file in Directory.GetFiles(Environment.CurrentDirectory))
{
if (Regex.Match(file, @"import_stats_[0-9]+.csv").Success)
{
int port = Int32.Parse(Regex.Match(file, "[0-9]{5}").Value);
var stats = new List<EFClientStatistics>();
manager.GetLogger().WriteVerbose("Beginning import of existing client stats");
var lines = File.ReadAllLines("import_stats.csv").Skip(1);
var lines = File.ReadAllLines(file).Skip(1);
foreach (string line in lines)
{
string[] fields = line.Split(',');
@ -293,7 +361,7 @@ namespace IW4MAdmin.Plugins
continue;
long id = fields[0].ConvertLong();
var client = cls.First(c => c.NetworkId == id);
var client = cls.Single(c => c.NetworkId == id);
var time = Convert.ToInt32(fields[8]);
double spm = time < 60 ? 0 : Math.Round(Convert.ToInt32(fields[1]) * 100.0 / time, 3);
@ -304,25 +372,36 @@ namespace IW4MAdmin.Plugins
{
Active = true,
ClientId = client.ClientId,
ServerId = Math.Abs("127.0.0.1:28965".GetHashCode()),
ServerId = Math.Abs($"127.0.0.1:{port}".GetHashCode()),
Kills = Convert.ToInt32(fields[1]),
Deaths = Convert.ToInt32(fields[2]),
SPM = spm,
Skill = 0
Skill = 0,
TimePlayed = time * 60
};
// client.TotalConnectionTime += time;
stats.Add(st);
stats = stats.AsEnumerable()
.GroupBy(c => new { c.ClientId })
.Select(c => c.FirstOrDefault()).ToList();
var cl = await manager.GetClientService().Get(st.ClientId);
cl.TotalConnectionTime += time * 60;
await manager.GetClientService().Update(cl);
}
catch (Exception e)
{
continue;
}
}
manager.GetLogger().WriteVerbose($"Read {stats.Count} clients stats for import");
try
{
SharedLibrary.Database.Importer.ImportSQLite<EFClientStatistics>(stats);
SharedLibrary.Database.Importer.ImportSQLite(stats);
}
catch (Exception e)
@ -330,6 +409,7 @@ namespace IW4MAdmin.Plugins
manager.GetLogger().WriteError("Saving imported stats failed");
}
}
}
#endregion
}

View File

@ -66,6 +66,7 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />

View File

@ -40,7 +40,7 @@ namespace CountryLookupProj
"O1","AX","GG","IM","JE","BL","MF"
};
private static string[] countryName =
{"An Unknown Country","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles","Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados","Bangladesh","Belgium",
{"a third world country","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles","Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados","Bangladesh","Belgium",
"Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia","Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the","Central African Republic","Congo","Switzerland","Cote D'Ivoire",
"Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica","Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic","Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji","Falkland Islands (Malvinas)",
"Micronesia, Federated States of","Faroe Islands","France","France, Metropolitan","Gabon","United Kingdom","Grenada","Georgia","French Guiana","Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala","Guam","Guinea-Bissau","Guyana",
@ -103,7 +103,7 @@ namespace CountryLookupProj
}
catch (FormatException)
{
return "An Unknown Country";
return "a third world country";
}
return lookupCountryName(addr);
}

View File

@ -91,7 +91,7 @@ namespace Welcome_Plugin
await newPlayer.Tell(ProcessAnnouncement(cfg.GetProperty<string>("UserWelcomeMessage"), newPlayer));
if (newPlayer.Level == Player.Permission.Flagged)
await E.Owner.ToAdmins($"^1NOTICE: ^7Flagged player ^5{newPlayer.Name}^7 has joined!");
await E.Owner.ToAdmins($"^1NOTICE: ^7Flagged player ^5{newPlayer.Name} ^7has joined!");
else
await E.Owner.Broadcast(ProcessAnnouncement(cfg.GetProperty<string>("UserAnnouncementMessage"), newPlayer));
}
@ -114,7 +114,7 @@ namespace Welcome_Plugin
if (cfg.GetProperty<string>("UserAnnouncementMessage") == null)
{
string annoucementMsg = "^5{{ClientName}}^7hails from ^5{{ClientLocation}}";
string annoucementMsg = "^5{{ClientName}} ^7hails from ^5{{ClientLocation}}";
cfg.AddProperty(new KeyValuePair<string, dynamic>("UserAnnouncementMessage", annoucementMsg));
}
}

View File

@ -350,12 +350,12 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
if (!E.Origin.Masked)
await E.Owner.Broadcast($"Fast restarting in ^53 ^7seconds [^5{E.Origin.Name}^7]");
else
await E.Owner.Broadcast($"Fast restarting in ^53 ^7seconds [^5Masked Admin^7]");
Task.Delay(3000).Wait();
await E.Owner.ExecuteCommandAsync("fast_restart");
if (!E.Origin.Masked)
await E.Owner.Broadcast($"^5{E.Origin.Name} ^7fast restarted the server");
else
await E.Owner.Broadcast($"The server has been fast restarted");
}
}
@ -527,7 +527,10 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
var db_players = await (E.Owner.Manager.GetClientService() as ClientService).GetClientByName(E.Data);
var db_players = (await (E.Owner.Manager.GetClientService() as ClientService)
.GetClientByName(E.Data))
.OrderByDescending(p => p.LastConnection)
.ToList();
if (db_players.Count == 0)
{
@ -567,9 +570,9 @@ namespace SharedLibrary.Commands
foreach (String r in E.Owner.Rules)
{
if (E.Message.IsBroadcastCommand())
await E.Owner.Broadcast("- " + r);
await E.Owner.Broadcast($"- {r}");
else
await E.Origin.Tell("- " + r);
await E.Origin.Tell($"- {r}");
}
}
}
@ -595,8 +598,8 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
await E.Target.Tell("^1" + E.Origin.Name + " ^3[PM]^7 - " + E.Data);
await E.Origin.Tell(String.Format("To ^3{0} ^7-> {1}", E.Target.Name, E.Data));
await E.Target.Tell($"^1{E.Origin.Name} ^3[PM]^7 - {E.Data}");
await E.Origin.Tell($"To ^3{E.Target.Name} ^7-> {E.Data}");
}
}
@ -667,7 +670,7 @@ namespace SharedLibrary.Commands
await E.Owner.Manager.GetPenaltyService().Create(newPenalty);
await E.Owner.ExecuteEvent(new Event(Event.GType.Flag, E.Data, E.Origin, E.Target, E.Owner));
await E.Origin.Tell("You have ^5flagged ^7" + E.Target.Name);
await E.Origin.Tell($"You have flagged ^5{E.Target.Name}");
}
}
@ -693,6 +696,12 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
if (E.Data.ToLower().Contains("camp"))
{
await E.Origin.Tell("You cannot report a player for camping");
return;
}
if (E.Owner.Reports.Find(x => (x.Origin == E.Origin && x.Target.NetworkId == E.Target.NetworkId)) != null)
{
await E.Origin.Tell("You have already reported this player");

View File

@ -29,8 +29,8 @@ namespace SharedLibrary.Network
using (var ServerOOBConnection = new UdpClient())
{
// prevent flooding
if ((DateTime.Now - LastQuery).TotalMilliseconds < 300)
Task.Delay(300).Wait();
if ((DateTime.Now - LastQuery).TotalMilliseconds < 100)
Task.Delay(100).Wait();
LastQuery = DateTime.Now;
ServerOOBConnection.Client.SendTimeout = 1000;

Binary file not shown.

View File

@ -57,7 +57,7 @@ namespace SharedLibrary.Services
// set the level to the level of the existing client if they have the same IP + Name but new NetworkId
Level = hasExistingAlias ?
context.Clients.First(c => c.CurrentAliasId == existingAlias.AliasId).Level :
Objects.Player.Permission.User,
Player.Permission.User,
FirstConnection = DateTime.UtcNow,
Connections = 1,
LastConnection = DateTime.UtcNow,

View File

@ -192,6 +192,20 @@ namespace SharedLibrary.Services
}
}
public async Task<List<EFPenalty>> GetActivePenaltiesAsync(int aliasId)
{
using (var context = new DatabaseContext())
{
var iqPenalties = from link in context.AliasLinks
where link.AliasLinkId == aliasId
join penalty in context.Penalties
on link.AliasLinkId equals penalty.LinkId
where penalty.Active
select penalty;
return await iqPenalties.ToListAsync();
}
}
public async Task RemoveActivePenalties(int aliasLinkId)
{
using (var context = new DatabaseContext())

View File

@ -149,11 +149,6 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="SQLite.Interop.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>move "$(TargetDir)Newtonsoft.Json.dll" "$(TargetDir)lib\Newtonsoft.Json.dll"