Fixed non player killstreak kills counting as suicide
(custom callbacks) RCON tweaks to hopefully prevent RCON flooding Stats reimp added IW4x extra weapons
This commit is contained in:
parent
0b62cba52a
commit
850d9e8c1a
@ -34,7 +34,7 @@ namespace IW4MAdmin
|
|||||||
AliasService AliasSvc;
|
AliasService AliasSvc;
|
||||||
PenaltyService PenaltySvc;
|
PenaltyService PenaltySvc;
|
||||||
#if FTP_LOG
|
#if FTP_LOG
|
||||||
const int UPDATE_FREQUENCY = 15000;
|
const int UPDATE_FREQUENCY = 700;
|
||||||
#else
|
#else
|
||||||
const int UPDATE_FREQUENCY = 300;
|
const int UPDATE_FREQUENCY = 300;
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,7 +19,7 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return IP.GetHashCode() + Port;
|
return Math.Abs(IP.GetHashCode() + Port);
|
||||||
}
|
}
|
||||||
override public async Task<bool> AddPlayer(Player polledPlayer)
|
override public async Task<bool> AddPlayer(Player polledPlayer)
|
||||||
{
|
{
|
||||||
@ -405,11 +405,7 @@ namespace IW4MAdmin
|
|||||||
if (lines != oldLines)
|
if (lines != oldLines)
|
||||||
{
|
{
|
||||||
l_size = LogFile.Length();
|
l_size = LogFile.Length();
|
||||||
int end;
|
int end = (lines.Length == oldLines.Length) ? lines.Length - 1 : Math.Abs((lines.Length - oldLines.Length)) - 1;
|
||||||
if (lines.Length == oldLines.Length)
|
|
||||||
end = lines.Length - 1;
|
|
||||||
else
|
|
||||||
end = Math.Abs((lines.Length - oldLines.Length)) - 1;
|
|
||||||
|
|
||||||
for (int count = 0; count < lines.Length; count++)
|
for (int count = 0; count < lines.Length; count++)
|
||||||
{
|
{
|
||||||
@ -434,7 +430,6 @@ namespace IW4MAdmin
|
|||||||
await ExecuteEvent(event_);
|
await ExecuteEvent(event_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -537,8 +532,13 @@ namespace IW4MAdmin
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
#if !DEBUG
|
||||||
LogFile = new IFile(logPath);
|
LogFile = new IFile(logPath);
|
||||||
|
#else
|
||||||
|
}
|
||||||
|
LogFile = new RemoteFile("https://raidmax.org/IW4MAdmin/getlog.php");
|
||||||
|
#endif
|
||||||
Logger.WriteInfo("Log file is " + logPath);
|
Logger.WriteInfo("Log file is " + logPath);
|
||||||
await ExecuteEvent(new Event(Event.GType.Start, "Server started", null, null, this));
|
await ExecuteEvent(new Event(Event.GType.Start, "Server started", null, null, this));
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
|
Binary file not shown.
@ -1,4 +1,8 @@
|
|||||||
Version 1.6:
|
Version 1.7:
|
||||||
|
CHANGELOG:
|
||||||
|
-EntityFramework is now the main database system
|
||||||
|
|
||||||
|
Version 1.6:
|
||||||
CHANGELOG:
|
CHANGELOG:
|
||||||
-got rid of pesky "error on character" message
|
-got rid of pesky "error on character" message
|
||||||
-optimizations to commands
|
-optimizations to commands
|
||||||
|
@ -102,10 +102,15 @@ namespace StatsPlugin.Helpers
|
|||||||
clientStats = ClientStatSvc.Insert(clientStats);
|
clientStats = ClientStatSvc.Insert(clientStats);
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
lock (playerStats)
|
lock (playerStats)
|
||||||
|
{
|
||||||
|
if (playerStats.ContainsKey(pl.ClientNumber))
|
||||||
|
{
|
||||||
|
Log.WriteWarning($"Duplicate clientnumber in stats {pl.ClientId} vs {playerStats[pl.ClientNumber].ClientId}");
|
||||||
|
playerStats.Remove(pl.ClientNumber);
|
||||||
|
}
|
||||||
playerStats.Add(pl.ClientNumber, clientStats);
|
playerStats.Add(pl.ClientNumber, clientStats);
|
||||||
|
}
|
||||||
return clientStats;
|
return clientStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,29 +118,32 @@ namespace StatsPlugin.Helpers
|
|||||||
{
|
{
|
||||||
int serverId = pl.CurrentServer.GetHashCode();
|
int serverId = pl.CurrentServer.GetHashCode();
|
||||||
var playerStats = Servers[serverId].PlayerStats;
|
var playerStats = Servers[serverId].PlayerStats;
|
||||||
|
|
||||||
// get individual client's stats
|
// get individual client's stats
|
||||||
var clientStats = playerStats[pl.ClientNumber];
|
var clientStats = playerStats[pl.ClientNumber];
|
||||||
// remove the client from the stats dictionary as they're leaving
|
// remove the client from the stats dictionary as they're leaving
|
||||||
lock (playerStats)
|
lock (playerStats)
|
||||||
playerStats.Remove(pl.ClientNumber);
|
playerStats.Remove(pl.ClientNumber);
|
||||||
|
// allow accessing certain properties
|
||||||
|
//clientStats.Client = pl;
|
||||||
|
// update skill
|
||||||
|
// clientStats = UpdateStats(clientStats);
|
||||||
|
// reset for EF cache
|
||||||
|
//clientStats.SessionDeaths = 0;
|
||||||
|
// clientStats.SessionKills = 0;
|
||||||
|
// prevent mismatched primary key
|
||||||
|
//clientStats.Client = null;
|
||||||
// update in database
|
// update in database
|
||||||
await ClientStatSvc.SaveChangesAsync();
|
//await ClientStatSvc.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Process stats for kill event
|
/// Process stats for kill event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task AddKill(Player attacker, Player victim, int serverId, string map, string hitLoc, string type,
|
public async Task AddScriptKill(Player attacker, Player victim, int serverId, string map, string hitLoc, string type,
|
||||||
string damage, string weapon, string killOrigin, string deathOrigin)
|
string damage, string weapon, string killOrigin, string deathOrigin)
|
||||||
{
|
{
|
||||||
var attackerStats = Servers[serverId].PlayerStats[attacker.ClientNumber];
|
AddStandardKill(attacker, victim);
|
||||||
attackerStats.Kills += 1;
|
|
||||||
|
|
||||||
var victimStats = Servers[serverId].PlayerStats[victim.ClientNumber];
|
|
||||||
victimStats.Deaths += 1;
|
|
||||||
|
|
||||||
var kill = new EFClientKill()
|
var kill = new EFClientKill()
|
||||||
{
|
{
|
||||||
@ -156,10 +164,88 @@ namespace StatsPlugin.Helpers
|
|||||||
await KillSvc.SaveChangesAsync();
|
await KillSvc.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private EFClientStatistics UpdateStats(EFClientStatistics cs)
|
public void AddStandardKill(Player attacker, Player victim)
|
||||||
{
|
{
|
||||||
// todo: everything
|
var attackerStats = Servers[attacker.CurrentServer.GetHashCode()].PlayerStats[attacker.ClientNumber];
|
||||||
return cs;
|
// set to access total time
|
||||||
|
attackerStats.Client = attacker;
|
||||||
|
var victimStats = Servers[victim.CurrentServer.GetHashCode()].PlayerStats[victim.ClientNumber];
|
||||||
|
|
||||||
|
CalculateKill(attackerStats, victimStats);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs the incrementation of kills and deaths for client statistics
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="attackerStats">Stats of the attacker</param>
|
||||||
|
/// <param name="victimStats">Stats of the victim</param>
|
||||||
|
public void CalculateKill(EFClientStatistics attackerStats, EFClientStatistics victimStats)
|
||||||
|
{
|
||||||
|
attackerStats.Kills += 1;
|
||||||
|
attackerStats.SessionKills += 1;
|
||||||
|
attackerStats.KillStreak += 1;
|
||||||
|
attackerStats.DeathStreak = 0;
|
||||||
|
|
||||||
|
victimStats.Deaths += 1;
|
||||||
|
victimStats.SessionDeaths += 1;
|
||||||
|
victimStats.DeathStreak += 1;
|
||||||
|
victimStats.KillStreak = 0;
|
||||||
|
|
||||||
|
// process the attacker's stats after the kills
|
||||||
|
UpdateStats(attackerStats);
|
||||||
|
attackerStats.Client = null;
|
||||||
|
|
||||||
|
// immediately write changes in debug
|
||||||
|
#if DEBUG
|
||||||
|
ClientStatSvc.SaveChanges();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the client stats (skill etc)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="clientStats">Client statistics</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private EFClientStatistics UpdateStats(EFClientStatistics clientStats)
|
||||||
|
{
|
||||||
|
// if it's their first kill we need to set the last kill as the time they joined
|
||||||
|
clientStats.LastStatCalculation = (clientStats.LastStatCalculation == DateTime.MinValue) ? DateTime.UtcNow : clientStats.LastStatCalculation;
|
||||||
|
double timeSinceLastCalc = (DateTime.UtcNow - clientStats.LastStatCalculation).TotalSeconds / 60.0;
|
||||||
|
|
||||||
|
// each 'session' is one minute
|
||||||
|
if (timeSinceLastCalc >= 1)
|
||||||
|
{
|
||||||
|
Log.WriteDebug($"Updated stats for {clientStats.ClientId} ({clientStats.SessionKills})");
|
||||||
|
// calculate the players Score Per Minute for the current session
|
||||||
|
// todo: score should be based on gamemode
|
||||||
|
double killSPM = clientStats.SessionKills * 100.0;
|
||||||
|
|
||||||
|
// calculate how much the KDR should weigh
|
||||||
|
// 1.637 is a Eddie-Generated number that weights the KDR nicely
|
||||||
|
double KDRWeight = Math.Round(Math.Pow(clientStats.KDR, 1.637 / Math.E), 3);
|
||||||
|
|
||||||
|
// if no SPM, weight is 1 else the weight ishe current session's spm / lifetime average score per minute
|
||||||
|
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;
|
||||||
|
|
||||||
|
double SPMAgainstPlayWeight = timeSinceLastCalc / Math.Min(600, (totalConnectionTime / 60.0));
|
||||||
|
|
||||||
|
// calculate the new weight against average times the weight against play time
|
||||||
|
clientStats.SPM = (killSPM * SPMAgainstPlayWeight) + (clientStats.SPM * (1 - SPMAgainstPlayWeight));
|
||||||
|
clientStats.SPM = Math.Round(clientStats.SPM, 3);
|
||||||
|
clientStats.Skill = Math.Round((clientStats.SPM * KDRWeight) / 10.0, 3);
|
||||||
|
|
||||||
|
clientStats.SessionKills = 0;
|
||||||
|
clientStats.SessionDeaths = 0;
|
||||||
|
|
||||||
|
clientStats.LastStatCalculation = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clientStats;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1225,7 +1225,118 @@ namespace StatsPlugin
|
|||||||
nuke_mp = 1190,
|
nuke_mp = 1190,
|
||||||
barrel_mp = 1191,
|
barrel_mp = 1191,
|
||||||
lightstick_mp = 1192,
|
lightstick_mp = 1192,
|
||||||
throwingknife_rhand_mp = 1193
|
throwingknife_rhand_mp = 1193,
|
||||||
|
deserteaglegold_akimbo_mp,
|
||||||
|
deserteaglegold_fmj_mp,
|
||||||
|
deserteaglegold_tactical_mp,
|
||||||
|
deserteaglegold_akimbo_fmj_mp,
|
||||||
|
deserteaglegold_fmj_tactical_mp,
|
||||||
|
ak47classic_mp,
|
||||||
|
ak47classic_acog_mp,
|
||||||
|
ak47classic_eotech_mp,
|
||||||
|
ak47classic_fmj_mp,
|
||||||
|
ak47classic_gl_mp,
|
||||||
|
gl_ak47classic_mp,
|
||||||
|
ak47classic_heartbeat_mp,
|
||||||
|
ak47classic_reflex_mp,
|
||||||
|
ak47classic_shotgun_mp,
|
||||||
|
ak47classic_shotgun_attach_mp,
|
||||||
|
ak47classic_silencer_mp,
|
||||||
|
ak47classic_thermal_mp,
|
||||||
|
ak47classic_xmags_mp,
|
||||||
|
ak47classic_acog_fmj_mp,
|
||||||
|
ak47classic_acog_gl_mp,
|
||||||
|
ak47classic_acog_heartbeat_mp,
|
||||||
|
ak47classic_acog_shotgun_mp,
|
||||||
|
ak47classic_acog_silencer_mp,
|
||||||
|
ak47classic_acog_xmags_mp,
|
||||||
|
ak47classic_eotech_fmj_mp,
|
||||||
|
ak47classic_eotech_gl_mp,
|
||||||
|
ak47classic_eotech_heartbeat_mp,
|
||||||
|
ak47classic_eotech_shotgun_mp,
|
||||||
|
ak47classic_eotech_silencer_mp,
|
||||||
|
ak47classic_eotech_xmags_mp,
|
||||||
|
ak47classic_fmj_gl_mp,
|
||||||
|
ak47classic_fmj_heartbeat_mp,
|
||||||
|
ak47classic_fmj_reflex_mp,
|
||||||
|
ak47classic_fmj_shotgun_mp,
|
||||||
|
ak47classic_fmj_silencer_mp,
|
||||||
|
ak47classic_fmj_thermal_mp,
|
||||||
|
ak47classic_fmj_xmags_mp,
|
||||||
|
ak47classic_gl_heartbeat_mp,
|
||||||
|
ak47classic_gl_reflex_mp,
|
||||||
|
ak47classic_gl_silencer_mp,
|
||||||
|
ak47classic_gl_thermal_mp,
|
||||||
|
ak47classic_gl_xmags_mp,
|
||||||
|
ak47classic_heartbeat_reflex_mp,
|
||||||
|
ak47classic_heartbeat_shotgun_mp,
|
||||||
|
ak47classic_heartbeat_silencer_mp,
|
||||||
|
ak47classic_heartbeat_thermal_mp,
|
||||||
|
ak47classic_heartbeat_xmags_mp,
|
||||||
|
ak47classic_reflex_shotgun_mp,
|
||||||
|
ak47classic_reflex_silencer_mp,
|
||||||
|
ak47classic_reflex_xmags_mp,
|
||||||
|
ak47classic_shotgun_silencer_mp,
|
||||||
|
ak47classic_shotgun_thermal_mp,
|
||||||
|
ak47classic_shotgun_xmags_mp,
|
||||||
|
ak47classic_silencer_thermal_mp,
|
||||||
|
ak47classic_silencer_xmags_mp,
|
||||||
|
ak47classic_thermal_xmags_mp,
|
||||||
|
ak74u_mp,
|
||||||
|
ak74u_acog_mp,
|
||||||
|
ak74u_eotech_mp,
|
||||||
|
ak74u_fmj_mp,
|
||||||
|
ak74u_gl_mp,
|
||||||
|
gl_ak74u_mp,
|
||||||
|
ak74u_heartbeat_mp,
|
||||||
|
ak74u_reflex_mp,
|
||||||
|
ak74u_shotgun_mp,
|
||||||
|
ak74u_shotgun_attach_mp,
|
||||||
|
ak74u_silencer_mp,
|
||||||
|
ak74u_thermal_mp,
|
||||||
|
ak74u_xmags_mp,
|
||||||
|
ak74u_acog_fmj_mp,
|
||||||
|
ak74u_acog_gl_mp,
|
||||||
|
ak74u_acog_heartbeat_mp,
|
||||||
|
ak74u_acog_shotgun_mp,
|
||||||
|
ak74u_acog_silencer_mp,
|
||||||
|
ak74u_acog_xmags_mp,
|
||||||
|
ak74u_eotech_fmj_mp,
|
||||||
|
ak74u_eotech_gl_mp,
|
||||||
|
ak74u_eotech_heartbeat_mp,
|
||||||
|
ak74u_eotech_shotgun_mp,
|
||||||
|
ak74u_eotech_silencer_mp,
|
||||||
|
ak74u_eotech_xmags_mp,
|
||||||
|
ak74u_fmj_gl_mp,
|
||||||
|
ak74u_fmj_heartbeat_mp,
|
||||||
|
ak74u_fmj_reflex_mp,
|
||||||
|
ak74u_fmj_shotgun_mp,
|
||||||
|
ak74u_fmj_silencer_mp,
|
||||||
|
ak74u_fmj_thermal_mp,
|
||||||
|
ak74u_fmj_xmags_mp,
|
||||||
|
ak74u_gl_heartbeat_mp,
|
||||||
|
ak74u_gl_reflex_mp,
|
||||||
|
ak74u_gl_silencer_mp,
|
||||||
|
ak74u_gl_thermal_mp,
|
||||||
|
ak74u_gl_xmags_mp,
|
||||||
|
ak74u_heartbeat_reflex_mp,
|
||||||
|
ak74u_heartbeat_shotgun_mp,
|
||||||
|
ak74u_heartbeat_silencer_mp,
|
||||||
|
ak74u_heartbeat_thermal_mp,
|
||||||
|
ak74u_heartbeat_xmags_mp,
|
||||||
|
ak74u_reflex_shotgun_mp,
|
||||||
|
ak74u_reflex_silencer_mp,
|
||||||
|
ak74u_reflex_xmags_mp,
|
||||||
|
ak74u_shotgun_silencer_mp,
|
||||||
|
ak74u_shotgun_thermal_mp,
|
||||||
|
ak74u_shotgun_xmags_mp,
|
||||||
|
ak74u_silencer_thermal_mp,
|
||||||
|
ak74u_silencer_xmags_mp,
|
||||||
|
ak74u_thermal_xmags_mp,
|
||||||
|
m40a3_mp = 1194,
|
||||||
|
peacekeeper_mp,
|
||||||
|
dragunov_mp,
|
||||||
|
cobra_player_minigun_mp
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MapName
|
public enum MapName
|
||||||
|
@ -28,11 +28,22 @@ namespace StatsPlugin.Models
|
|||||||
[NotMapped]
|
[NotMapped]
|
||||||
public double KDR
|
public double KDR
|
||||||
{
|
{
|
||||||
get => Deaths == 0 ? 0.0 : Math.Round((float)Kills / (float)Deaths, 2);
|
get => Deaths == 0 ? Kills : Math.Round((float)Kills / (float)Deaths, 2);
|
||||||
}
|
}
|
||||||
[Required]
|
[Required]
|
||||||
public double SPM { get; set; }
|
public double SPM { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
public double Skill { get; set; }
|
public double Skill { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public int SessionKills { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public int SessionDeaths { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public int KillStreak { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public int DeathStreak { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public DateTime LastStatCalculation { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ namespace StatsPlugin
|
|||||||
case Event.GType.Kill:
|
case Event.GType.Kill:
|
||||||
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
||||||
if (killInfo.Length >= 9 && killInfo[0].Contains("ScriptKill"))
|
if (killInfo.Length >= 9 && killInfo[0].Contains("ScriptKill"))
|
||||||
await Manager.AddKill(E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8], killInfo[5], killInfo[6], killInfo[3], killInfo[4]);
|
await Manager.AddScriptKill(E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8], killInfo[5], killInfo[6], killInfo[3], killInfo[4]);
|
||||||
break;
|
break;
|
||||||
case Event.GType.Death:
|
case Event.GType.Death:
|
||||||
break;
|
break;
|
||||||
|
@ -202,8 +202,6 @@ namespace IW4MAdmin.Plugins
|
|||||||
Interval = DateTime.Now;
|
Interval = DateTime.Now;
|
||||||
if (S.ClientNum > 0)
|
if (S.ClientNum > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
//"K;26d2f66b95184934;1;allies;egor;5c56fef676b3818d;0;axis;1_din;m21_heartbeat_mp;98;MOD_RIFLE_BULLET;torso_lower";
|
|
||||||
var victimPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
|
var victimPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
|
||||||
var attackerPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
|
var attackerPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ namespace SharedLibrary.Database.Models
|
|||||||
[Required]
|
[Required]
|
||||||
public int Connections { get; set; }
|
public int Connections { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
|
// in seconds
|
||||||
public int TotalConnectionTime { get; set; }
|
public int TotalConnectionTime { get; set; }
|
||||||
[Required]
|
[Required]
|
||||||
public DateTime FirstConnection { get; set; }
|
public DateTime FirstConnection { get; set; }
|
||||||
|
@ -3,19 +3,53 @@ using System.Collections.Generic;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
namespace SharedLibrary
|
namespace SharedLibrary
|
||||||
{
|
{
|
||||||
|
public class RemoteFile : IFile
|
||||||
|
{
|
||||||
|
string Location;
|
||||||
|
string[] FileCache;
|
||||||
|
|
||||||
|
public RemoteFile(string location) : base(string.Empty)
|
||||||
|
{
|
||||||
|
Location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Retrieve()
|
||||||
|
{
|
||||||
|
using (var cl = new HttpClient())
|
||||||
|
FileCache = cl.GetStringAsync(Location).Result.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string[] Tail(int lineCount)
|
||||||
|
{
|
||||||
|
Retrieve();
|
||||||
|
return FileCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Length()
|
||||||
|
{
|
||||||
|
Retrieve();
|
||||||
|
return FileCache[0].Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public class IFile
|
public class IFile
|
||||||
{
|
{
|
||||||
public IFile(String fileName)
|
public IFile(String fileName)
|
||||||
{
|
{
|
||||||
Name = fileName;
|
if (fileName != string.Empty)
|
||||||
Handle = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
{
|
||||||
sze = Handle.BaseStream.Length;
|
Name = fileName;
|
||||||
|
Handle = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
|
||||||
|
sze = Handle.BaseStream.Length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long Length()
|
public virtual long Length()
|
||||||
{
|
{
|
||||||
sze = Handle.BaseStream.Length;
|
sze = Handle.BaseStream.Length;
|
||||||
return sze;
|
return sze;
|
||||||
@ -36,7 +70,7 @@ namespace SharedLibrary
|
|||||||
return Handle?.ReadToEnd();
|
return Handle?.ReadToEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] Tail(int lineCount)
|
public virtual String[] Tail(int lineCount)
|
||||||
{
|
{
|
||||||
var buffer = new List<string>(lineCount);
|
var buffer = new List<string>(lineCount);
|
||||||
string line;
|
string line;
|
||||||
|
@ -40,7 +40,7 @@ namespace SharedLibrary.Helpers
|
|||||||
public void Update(Task<bool> T)
|
public void Update(Task<bool> T)
|
||||||
{
|
{
|
||||||
RequestedTask = T;
|
RequestedTask = T;
|
||||||
Console.WriteLine($"Starting Task {T.Id} ");
|
// Console.WriteLine($"Starting Task {T.Id} ");
|
||||||
RequestedTask.Start();
|
RequestedTask.Start();
|
||||||
|
|
||||||
if (TimesRun > 25)
|
if (TimesRun > 25)
|
||||||
|
@ -26,12 +26,12 @@ namespace SharedLibrary.Network
|
|||||||
|
|
||||||
static string[] SendQuery(QueryType Type, Server QueryServer, string Parameters = "")
|
static string[] SendQuery(QueryType Type, Server QueryServer, string Parameters = "")
|
||||||
{
|
{
|
||||||
if ((DateTime.Now - LastQuery).TotalMilliseconds < 30)
|
if ((DateTime.Now - LastQuery).TotalMilliseconds < 100)
|
||||||
Task.Delay(30).Wait();
|
Task.Delay(100).Wait();
|
||||||
LastQuery = DateTime.Now;
|
LastQuery = DateTime.Now;
|
||||||
var ServerOOBConnection = new UdpClient();
|
var ServerOOBConnection = new UdpClient();
|
||||||
ServerOOBConnection.Client.SendTimeout = 5000;
|
ServerOOBConnection.Client.SendTimeout = 1000;
|
||||||
ServerOOBConnection.Client.ReceiveTimeout = 5000;
|
ServerOOBConnection.Client.ReceiveTimeout = 1000;
|
||||||
var Endpoint = new IPEndPoint(IPAddress.Parse(QueryServer.GetIP()), QueryServer.GetPort());
|
var Endpoint = new IPEndPoint(IPAddress.Parse(QueryServer.GetIP()), QueryServer.GetPort());
|
||||||
|
|
||||||
string QueryString = String.Empty;
|
string QueryString = String.Empty;
|
||||||
@ -139,7 +139,7 @@ namespace SharedLibrary.Network
|
|||||||
|
|
||||||
public static async Task<List<Player>> GetStatusAsync(this Server server)
|
public static async Task<List<Player>> GetStatusAsync(this Server server)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG && DEBUG_PLAYERS
|
||||||
string[] response = await Task.Run(() => System.IO.File.ReadAllLines("players.txt"));
|
string[] response = await Task.Run(() => System.IO.File.ReadAllLines("players.txt"));
|
||||||
#else
|
#else
|
||||||
string[] response = await Task.FromResult(SendQuery(QueryType.DVAR, server, "status"));
|
string[] response = await Task.FromResult(SendQuery(QueryType.DVAR, server, "status"));
|
||||||
|
@ -140,11 +140,13 @@ namespace SharedLibrary
|
|||||||
/// <param name="Message">Message to be sent to all players</param>
|
/// <param name="Message">Message to be sent to all players</param>
|
||||||
public async Task Broadcast(String Message)
|
public async Task Broadcast(String Message)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
|
||||||
//return;
|
|
||||||
#endif
|
|
||||||
string sayCommand = (GameName == Game.IW4) ? "sayraw" : "say";
|
string sayCommand = (GameName == Game.IW4) ? "sayraw" : "say";
|
||||||
|
#if !DEBUG
|
||||||
await this.ExecuteCommandAsync($"{sayCommand} {Message}");
|
await this.ExecuteCommandAsync($"{sayCommand} {Message}");
|
||||||
|
#else
|
||||||
|
Logger.WriteVerbose(Message.StripColors());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -156,8 +158,12 @@ namespace SharedLibrary
|
|||||||
{
|
{
|
||||||
string tellCommand = (GameName == Game.IW4) ? "tellraw" : "tell";
|
string tellCommand = (GameName == Game.IW4) ? "tellraw" : "tell";
|
||||||
|
|
||||||
|
#if !DEBUG
|
||||||
if (Target.ClientNumber > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console)
|
if (Target.ClientNumber > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console)
|
||||||
await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientNumber} {Message}^7");
|
await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientNumber} {Message}^7");
|
||||||
|
#else
|
||||||
|
Logger.WriteVerbose($"{Target.ClientNumber}->{Message.StripColors()}");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (Target.Level == Player.Permission.Console)
|
if (Target.Level == Player.Permission.Console)
|
||||||
{
|
{
|
||||||
|
@ -86,6 +86,7 @@
|
|||||||
<HintPath>..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll</HintPath>
|
<HintPath>..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
<Reference Include="System.Web" />
|
<Reference Include="System.Web" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
@ -13,9 +13,10 @@ init()
|
|||||||
Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
|
Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
|
||||||
{
|
{
|
||||||
victim = self;
|
victim = self;
|
||||||
|
_attacker = attacker;
|
||||||
if (!isDefined(attacker) || !isPlayer(attacker))
|
if (!isDefined(attacker) || !isPlayer(attacker))
|
||||||
attacker = victim;
|
_attacker = victim;
|
||||||
|
|
||||||
logPrint("ScriptKill;" + attacker.guid + ";" + victim.guid + ";" + attacker.origin + ";" + victim.origin + ";" + iDamage + ";" + sWeapon + ";" + sHitLoc + ";" + sMeansOfDeath + "\n");
|
logPrint("ScriptKill;" + _attacker.guid + ";" + victim.guid + ";" + _attacker.origin + ";" + victim.origin + ";" + iDamage + ";" + sWeapon + ";" + sHitLoc + ";" + sMeansOfDeath + "\n");
|
||||||
self maps\mp\gametypes\_damage::Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration );
|
self maps\mp\gametypes\_damage::Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration );
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user