changed player graph update interval to every 5 minutes

hopefully fixed skipping the logging of Kayak library issue.
I'm an idiot, 59 in playerhistory, not 60
added IW4 callback gsc for custom scriptkills.
Fixed duplicate death events
Trusted group can be enabled/disabled with !enable/disabletrusted
This commit is contained in:
RaidMax 2017-11-02 11:49:45 -05:00
parent c19d6e98f5
commit 9699f7c3f1
21 changed files with 189 additions and 29 deletions

View File

@ -351,7 +351,8 @@
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>copy /Y "$(SolutionDir)lib\*.dll" "$(TargetDir)lib"
<PostBuildEvent>xcopy /E "$(SolutionDir)lib" "$(TargetDir)lib"
copy /Y "$(SolutionDir)_customcallbacks.gsc" "$(SolutionDir)BUILD\userraw\scripts\_customcallbacks.gsc"
copy /Y "$(TargetDir)$(TargetName).exe" "$(SolutionDir)BUILD"
copy /Y "$(TargetDir)IW4MAdmin.exe.config" "$(SolutionDir)BUILD"

View File

@ -15,7 +15,7 @@ namespace IW4MAdmin
{
// it looks like there's a library error in
// Kayak.Http.HttpServerTransactionDelegate.OnError
if (e.GetType() == typeof(NullReferenceException))
if ((uint)e.HResult ==0x80004003)
return;
ApplicationManager.GetInstance().Logger.WriteWarning("Web service has encountered an error - " + e.Message);

View File

@ -360,9 +360,9 @@ namespace IW4MAdmin
tickTime = DateTime.Now;
}
if ((lastCount - playerCountStart).TotalMinutes >= 15)
if ((lastCount - playerCountStart).TotalMinutes >= SharedLibrary.Helpers.PlayerHistory.UpdateInterval)
{
while (PlayerHistory.Count > 48) // 4 times a hour for 12 hours
while (PlayerHistory.Count > ((60 / SharedLibrary.Helpers.PlayerHistory.UpdateInterval) * 12 )) // 12 times a hour for 12 hours
PlayerHistory.Dequeue();
PlayerHistory.Enqueue(new SharedLibrary.Helpers.PlayerHistory(ClientNum));
playerCountStart = DateTime.Now;
@ -492,18 +492,15 @@ namespace IW4MAdmin
await this.ExecuteCommandAsync("map_restart");
logfile = await this.GetDvarAsync<string>("g_log");
}
CustomCallback = await ScriptLoaded();
#if DEBUG
//if (Environment.OSVersion.VersionString != "Microsoft Windows NT 6.2.9200.0")
{
basepath.Value = (GameName == Game.IW4) ?
@"\\tsclient\J\WIN7_10.25\MW2" :
@"\\tsclient\G\Program Files (x86)\Steam\SteamApps\common\Call of Duty 4";
}
// else
// {
// basepath.Value = @"C:\MW2";
// }
#endif
string mainPath = (GameName == Game.IW4) ? "userraw" : "main";

Binary file not shown.

View File

@ -6,7 +6,7 @@ CHANGELOG:
-fixed resolution of tempban times from console feedback
-reconfigured solution and projects to be correct debug/release and files copy properly
-started working on more advanced statistics
-fixed misc issues
-fixed misc issuess
VERSION 1.4
CHANGELOG:

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.16
VisualStudioVersion = 15.0.27004.2006
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "Admin\Application.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}"
ProjectSection(ProjectDependencies) = postProject
@ -37,6 +37,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastRestartPlugin", "Plugin
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8C8F3945-0AEF-4949-A1F7-B18E952E50BC}"
ProjectSection(SolutionItems) = preProject
_customcallbacks.gsc = _customcallbacks.gsc
README.md = README.md
EndProjectSection
EndProject

View File

@ -146,7 +146,14 @@ namespace EventAPI
if (E.Type == Event.GType.Say && E.Origin.Level < Player.Permission.Moderator)
{
string message = E.Data.ToLower();
bool flagged = message.Contains(" wh ") || message.Contains("hax") || message.Contains("cheat") || message.Contains("hack") || message.Contains("aim") || message.Contains("wall") || message.Contains("cheto") || message.Contains("hak");
bool flagged = message.Contains(" wh ") ||
message.Contains("hax") ||
message.Contains("cheat") ||
message.Contains(" hack ") ||
message.Contains("aim") ||
message.Contains("wall") ||
message.Contains("cheto") ||
message.Contains("hak");
if (flagged)
{

View File

@ -44,11 +44,11 @@ namespace Plugin
public static ConfigurationManager ConfigManager { get; private set; }
public string Name { get { return "Fast Restarter"; } }
public string Name => "Fast Restarter";
public float Version { get { return 1.0f; } }
public float Version => 1.0f;
public string Author { get { return "RaidMax"; } }
public string Author => "RaidMax";
public async Task OnEventAsync(Event E, Server S)
{
@ -67,7 +67,7 @@ namespace Plugin
catch (SharedLibrary.Exceptions.DvarException)
{
await S.ExecuteCommandAsync("set src_intermission_time 20");
await S.SetDvarAsync("scr_intermission_time", 20);
}
}
}

View File

@ -146,7 +146,7 @@ copy /Y "$(TargetDir)DNA.Text.dll" "$(SolutionDir)Admin\bin\$(ConfigurationName)
copy /Y "$(TargetDir)CryptSharp.dll" "$(SolutionDir)Admin\bin\$(ConfigurationName)\lib\CryptSharp.dll"
copy /Y "$(TargetDir)CodeKicker.BBcode.dll" "$(SolutionDir)Admin\bin\$(ConfigurationName)\lib\CodeKicker.BBcode.dll"
copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)BUILD\plugins\"</PostBuildEvent>
if $(ConfigurationName) == Debug copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)BUILD\plugins\"</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -11,7 +11,7 @@ namespace StatsPlugin
{
public class CViewStats : Command
{
public CViewStats() : base("stats", "view your stats. syntax !stats", "xlrstats", Player.Permission.User, 0, false) { }
public CViewStats() : base("stats", "view your stats. syntax: !stats", "xlrstats", Player.Permission.User, 0, false) { }
public override async Task ExecuteAsync(Event E)
{
@ -54,7 +54,7 @@ namespace StatsPlugin
public class CViewTopStats : Command
{
public CViewTopStats() : base("topstats", "view the top 5 players on this server. syntax !topstats", "ts", Player.Permission.User, 0, false) { }
public CViewTopStats() : base("topstats", "view the top 5 players on this server. syntax: !topstats", "ts", Player.Permission.User, 0, false) { }
public override async Task ExecuteAsync(Event E)
{
@ -75,7 +75,7 @@ namespace StatsPlugin
public class CResetStats : Command
{
public CResetStats() : base("resetstats", "reset your stats to factory-new, !syntax !resetstats", "rs", Player.Permission.User, 0, false) { }
public CResetStats() : base("resetstats", "reset your stats to factory-new. syntax: !resetstats", "rs", Player.Permission.User, 0, false) { }
public override async Task ExecuteAsync(Event E)
{
@ -201,7 +201,6 @@ namespace StatsPlugin
ManagerInstance.GetMessageTokens().Add(new MessageToken("TOTALKILLS", GetTotalKills));
ManagerInstance.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", GetTotalPlaytime));
try
{
var minimapConfig = MinimapConfig.Read("Config/minimaps.cfg");
@ -229,6 +228,10 @@ namespace StatsPlugin
{
statLists.Add(new StatTracking(S.GetPort()));
ServerStats.Add(S.GetPort(), new ServerStatInfo());
var config = new ConfigurationManager(S);
if (config.GetProperty("EnableTrusted") == null)
config.AddProperty(new KeyValuePair<string, object>("EnableTrusted", true));
}
if (E.Type == Event.GType.Stop)
@ -241,9 +244,14 @@ namespace StatsPlugin
{
ResetCounters(E.Origin.ClientID, S.GetPort());
var config = new ConfigurationManager(E.Owner);
if (!(bool)config.GetProperty("EnableTrusted"))
return;
PlayerStats checkForTrusted = statLists.Find(x => x.Port == S.GetPort()).playerStats.GetStats(E.Origin);
//todo: move this out of here!!
if (checkForTrusted.TotalPlayTime >= 4320 && E.Origin.Level < Player.Permission.Trusted)
if (checkForTrusted.TotalPlayTime >= 4320 && E.Origin.Level < Player.Permission.Trusted && E.Origin.Level != Player.Permission.Flagged)
{
E.Origin.SetLevel(Player.Permission.Trusted);
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);

View File

@ -74,6 +74,7 @@
<Compile Include="Plugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="StatsPage.cs" />
<Compile Include="TrustedGroupCommands.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\SharedLibrary\SharedLibrary.csproj">

View File

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharedLibrary;
using SharedLibrary.Interfaces;
using SharedLibrary.Helpers;
namespace StatsPlugin
{
public class CEnableTrusted : Command
{
public CEnableTrusted() : base("enabletrusted", "enable trusted player group for the server. syntax: !enabletrusted", "et", Player.Permission.Owner, 0, false) { }
public override async Task ExecuteAsync(Event E)
{
var config = new ConfigurationManager(E.Owner);
if (config.GetProperty("EnableTrusted") == null)
config.AddProperty(new KeyValuePair<string, object>("EnableTrusted", true));
else
config.UpdateProperty(new KeyValuePair<string, object>("EnableTrusted", true));
await E.Origin.Tell("Trusted group has been disabled for this server");
}
}
public class CDisableTrusted : Command
{
public CDisableTrusted() : base("disabletrusted", "disable trusted player group for the server. syntax: !disabletrusted", "dt", Player.Permission.Owner, 0, false) { }
public override async Task ExecuteAsync(Event E)
{
var config = new ConfigurationManager(E.Owner);
if (config.GetProperty("EnableTrusted") == null)
config.AddProperty(new KeyValuePair<string, object>("EnableTrusted", false));
else
config.UpdateProperty(new KeyValuePair<string, object>("EnableTrusted", false));
await E.Origin.Tell("Trusted group has been disabled for this server");
}
}
}

View File

@ -33,10 +33,10 @@ namespace IW4MAdmin.Plugins
if (S.PlayerHistory.Count > 0)
return;
while (S.PlayerHistory.Count < 48)
while (S.PlayerHistory.Count < 144)
{
S.PlayerHistory.Enqueue(new PlayerHistory(time, rand.Next(7, 18)));
time = time.AddMinutes(15);
time = time.AddMinutes(PlayerHistory.UpdateInterval);
}
});
#endregion

View File

@ -91,6 +91,6 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)BUILD\plugins\"</PostBuildEvent>
<PostBuildEvent>if $(ConfigurationName) == Debug copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)BUILD\plugins\"</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@ -76,7 +76,7 @@
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)BUILD\plugins\"</PostBuildEvent>
<PostBuildEvent>if $(ConfigurationName) == Debug copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)BUILD\plugins\"</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -116,6 +116,7 @@ namespace SharedLibrary
Data.Append(line[i] + ";");
}
if (!SV.CustomCallback)
return new Event(GType.Script, Data.ToString(), SV.ParseClientFromString(line, 6), SV.ParseClientFromString(line, 2), SV);
}

View File

@ -7,7 +7,9 @@ namespace SharedLibrary.Helpers
public class ConfigurationManager
{
ConcurrentDictionary<string, Dictionary<string, object>> ConfigurationSet;
ConcurrentDictionary<string, object> ConfigSet;
Type PluginType;
Server ServerInstance;
public ConfigurationManager(Type PluginType)
{
@ -15,6 +17,27 @@ namespace SharedLibrary.Helpers
this.PluginType = PluginType;
}
public ConfigurationManager(Server S)
{
try
{
ConfigSet = Interfaces.Serialize<ConcurrentDictionary<string, object>>.Read($"config/Plugins_{S}.cfg");
}
catch (Exception)
{
S.Logger.WriteInfo("ConfigurationManager could not deserialize configuration file, so initializing default config set");
ConfigSet = new ConcurrentDictionary<string, object>();
}
ServerInstance = S;
}
private void SaveChanges()
{
Interfaces.Serialize<ConcurrentDictionary<string, object>>.Write($"config/Plugins_{ServerInstance}.cfg", ConfigSet);
}
public void AddConfiguration(Server S)
{
/* if (ConfigurationSet.ContainsKey(S.ToString()))
@ -41,15 +64,44 @@ namespace SharedLibrary.Helpers
Interfaces.Serialize<Dictionary<string, object>>.Write($"config/{PluginType.ToString()}_{S.ToString()}.cfg", ConfigurationSet[S.ToString()]);
}
public void AddProperty(KeyValuePair<string, object> prop)
{
if (!ConfigSet.ContainsKey(prop.Key))
ConfigSet.TryAdd(prop.Key, prop.Value);
SaveChanges();
}
public void UpdateProperty(Server S, KeyValuePair<string, object> Property)
{
ConfigurationSet[S.ToString()][Property.Key] = Property.Value;
Interfaces.Serialize<Dictionary<string, object>>.Write($"config/{PluginType.ToString()}_{S.ToString()}.cfg", ConfigurationSet[S.ToString()]);
}
public void UpdateProperty(KeyValuePair<string, object> prop)
{
if (ConfigSet.ContainsKey(prop.Key))
ConfigSet[prop.Key] = prop.Value;
SaveChanges();
}
public IDictionary<string, object> GetConfiguration(Server S)
{
return ConfigurationSet[S.ToString()];
}
public object GetProperty(string prop)
{
try
{
return ConfigSet[prop];
}
catch (Exception)
{
return null;
}
}
}
}

View File

@ -4,17 +4,20 @@ namespace SharedLibrary.Helpers
{
public class PlayerHistory
{
// how many minutes between updates
public static readonly int UpdateInterval = 5;
public PlayerHistory(int cNum)
{
DateTime t = DateTime.UtcNow;
When = new DateTime(t.Year, t.Month, t.Day, t.Hour, Math.Min(59, 15 * (int)Math.Round(t.Minute / 15.0)), 0);
When = new DateTime(t.Year, t.Month, t.Day, t.Hour, Math.Min(59, UpdateInterval * (int)Math.Round(t.Minute / (float)UpdateInterval)), 0);
PlayerCount = cNum;
}
#if DEBUG
public PlayerHistory(DateTime t, int cNum)
{
When = new DateTime(t.Year, t.Month, t.Day, t.Hour, Math.Min(59, 15 * (int)Math.Round(t.Minute / 15.0)), 0);
When = new DateTime(t.Year, t.Month, t.Day, t.Hour, Math.Min(59, UpdateInterval * (int)Math.Round(t.Minute / (float)UpdateInterval)), 0);
PlayerCount = cNum;
}
#endif

View File

@ -8,6 +8,7 @@ using System.Threading;
using SharedLibrary.Network;
using SharedLibrary.Commands;
using System.Threading.Tasks;
using SharedLibrary.Helpers;
namespace SharedLibrary
{
@ -37,6 +38,7 @@ namespace SharedLibrary
Reports = new List<Report>();
PlayerHistory = new Queue<Helpers.PlayerHistory>();
ChatHistory = new List<Chat>();
Configuration = new ConfigurationManager(this.GetType());
NextMessage = 0;
InitializeTokens();
InitializeAutoMessages();
@ -337,11 +339,26 @@ namespace SharedLibrary
ruleFile.Close();
}
public ConfigurationManager Configuration { get; private set; }
public override string ToString()
{
return $"{IP}_{Port}";
}
protected async Task<bool> ScriptLoaded()
{
try
{
return (await this.GetDvarAsync<string>("sv_customcallbacks")).Value == "1";
}
catch(Exceptions.DvarException)
{
return false;
}
}
// Objects
public Interfaces.IManager Manager { get; protected set; }
public Interfaces.ILogger Logger { get; private set; }
@ -369,6 +386,7 @@ namespace SharedLibrary
public List<Player> Players { get; protected set; }
public string Password { get; private set; }
public bool Throttled { get; protected set; }
public bool CustomCallback { get; protected set; }
// Internal
protected string IP;

View File

@ -142,6 +142,12 @@ copy /Y "$(TargetDir)Newtonsoft.Json.dll" "$(SolutionDir)Admin\lib"</PostBuildEv
</PropertyGroup>
<Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.105.1\build\net45\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.105.1\build\net45\System.Data.SQLite.Core.targets'))" />
</Target>
<PropertyGroup>
<PreBuildEvent>if not exist "$(SolutionDir)BUILD" mkdir "$(SolutionDir)BUILD"
if not exist "$(SolutionDir)BUILD\Lib" mkdir "$(SolutionDir)BUILD\Lib"
if not exist "$(SolutionDir)BUILD\Plugins" mkdir "$(SolutionDir)BUILD\Plugins"
if not exist "$(SolutionDir)BUILD\userraw\scripts" mkdir "$(SolutionDir)BUILD\userraw\scripts"</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

21
_customcallbacks.gsc Normal file
View File

@ -0,0 +1,21 @@
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
init()
{
SetDvarIfUninitialized("sv_customcallbacks", true);
level waittill("prematch_over");
level.callbackPlayerKilled = ::Callback_PlayerKilled;
}
Callback_PlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
{
victim = self;
if (!isDefined(attacker) || !isPlayer(attacker))
attacker = victim;
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 );
}