Enable/Disable fast restart plugin via config

Deleted legacy connection & heartbeat classes
Hopefully fixed issues relating to certain web requests throwing recoverable error
Modified Serializer class slightly
This commit is contained in:
RaidMax 2017-06-06 22:45:21 -05:00
parent 3ca73a5a7a
commit bd99add434
14 changed files with 106 additions and 107 deletions

View File

@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
namespace IW4MAdmin
{
class Connection
{
public Connection(String Loc)
{
Location = Loc;
ConnectionHandle = WebRequest.Create(Location);
ConnectionHandle.Proxy = null;
ConnectionHandle.Timeout = 1000;
}
public String Read()
{
try
{
WebResponse Resp = ConnectionHandle.GetResponse();
StreamReader data_in = new StreamReader(Resp.GetResponseStream());
String result = data_in.ReadToEnd();
data_in.Close();
Resp.Close();
return result;
}
catch (System.Net.WebException)
{
return null;
}
}
public void Request(String data)
{
try
{
WebResponse Resp = WebRequest.Create(data).GetResponse();
Resp.Close();
}
catch (System.Net.WebException)
{
return;
}
}
private String Location;
private WebRequest ConnectionHandle;
}
}

View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using SharedLibrary;
namespace IW4MAdmin
{
class Heartbeat
{
public Heartbeat(Server I)
{
Handle = new Connection("http://raidmax.org/IW4M/Admin");
}
public void Send(Server S)
{
String URI = String.Format("http://raidmax.org/IW4M/Admin/heartbeat.php?port={0}&name={1}&map={2}&players={3}&version={4}&gametype={5}&servercount={6}", S.getPort(), S.getName(), S.CurrentMap.Name, S.getPlayers().Count, IW4MAdmin.Program.Version.ToString(), S.Gametype, Manager.GetInstance().Servers);
// blind fire
Handle.Request(URI);
}
private Connection Handle;
}
}

View File

@ -124,8 +124,6 @@
<ItemGroup> <ItemGroup>
<Compile Include="Commands.cs" /> <Compile Include="Commands.cs" />
<Compile Include="Config.cs" /> <Compile Include="Config.cs" />
<Compile Include="Connection.cs" />
<Compile Include="Heartbeat.cs" />
<Compile Include="Kayak.cs" /> <Compile Include="Kayak.cs" />
<Compile Include="Logger.cs" /> <Compile Include="Logger.cs" />
<Compile Include="Main.cs" /> <Compile Include="Main.cs" />
@ -334,6 +332,8 @@ copy /Y "$(TargetDir)$(TargetName).exe" "$(SolutionDir)BUILD"
copy /Y "$(TargetDir)IW4MAdmin.exe.config" "$(SolutionDir)BUILD" copy /Y "$(TargetDir)IW4MAdmin.exe.config" "$(SolutionDir)BUILD"
copy /Y "$(ProjectDir)lib\Kayak.dll" "$(SolutionDir)BUILD\lib" copy /Y "$(ProjectDir)lib\Kayak.dll" "$(SolutionDir)BUILD\lib"
xcopy /Y /I /E "$(ProjectDir)webfront\*" "$(SolutionDir)BUILD\Webfront"
if $(ConfigurationName) == Release powershell.exe -file "$(SolutionDir)DEPLOY\publish_nightly.ps1" 1.3 if $(ConfigurationName) == Release powershell.exe -file "$(SolutionDir)DEPLOY\publish_nightly.ps1" 1.3
if $(ConfigurationName) == Release-Stable powershell.exe -file "$(SolutionDir)DEPLOY\publish_stable.ps1" 1.3</PostBuildEvent> if $(ConfigurationName) == Release-Stable powershell.exe -file "$(SolutionDir)DEPLOY\publish_stable.ps1" 1.3</PostBuildEvent>

View File

@ -18,7 +18,7 @@ namespace IW4MAdmin
if (e.InnerException != null) if (e.InnerException != null)
{ {
Manager.GetInstance().Logger.WriteDebug($"Inner Execption: {e.InnerException.Message}"); Manager.GetInstance().Logger.WriteDebug($"Inner Exception: {e.InnerException.Message}");
Manager.GetInstance().Logger.WriteDebug($"Inner Stack Trace: {e.InnerException.StackTrace}"); Manager.GetInstance().Logger.WriteDebug($"Inner Stack Trace: {e.InnerException.StackTrace}");
} }
@ -34,14 +34,13 @@ namespace IW4MAdmin
{ {
public void OnRequest(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response, string IP) public void OnRequest(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response, string IP)
{ {
// Program.getManager().mainLog.Write("HTTP request received", SharedLibrary.Log.Level.Debug);
NameValueCollection querySet = new NameValueCollection(); NameValueCollection querySet = new NameValueCollection();
if (request.QueryString != null) if (request.QueryString != null)
querySet = System.Web.HttpUtility.ParseQueryString(SharedLibrary.Utilities.removeNastyChars(request.QueryString)); querySet = System.Web.HttpUtility.ParseQueryString(SharedLibrary.Utilities.removeNastyChars(request.QueryString));
querySet.Set("IP", IP); querySet.Set("IP", IP);
SharedLibrary.HttpResponse requestedPage = WebService.getPage(request.Path, querySet, request.Headers); SharedLibrary.HttpResponse requestedPage = WebService.GetPage(request.Path, querySet, request.Headers);
var headers = new HttpResponseHead() var headers = new HttpResponseHead()
{ {
@ -102,7 +101,7 @@ namespace IW4MAdmin
public void OnError(Exception error) public void OnError(Exception error)
{ {
errorCallback(error); errorCallback?.Invoke(error);
} }
public void OnEnd() public void OnEnd()

View File

@ -102,7 +102,7 @@ namespace IW4MAdmin
} }
webServiceTask = WebService.getScheduler(); webServiceTask = WebService.GetScheduler();
WebThread = new Thread(webServiceTask.Start) WebThread = new Thread(webServiceTask.Start)
{ {

View File

@ -1,12 +1,12 @@
using System; using Kayak;
using Kayak.Http;
using SharedLibrary;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using Kayak;
using Kayak.Http;
using System.Net; using System.Net;
using System.Text;
using System.Threading; using System.Threading;
using SharedLibrary;
namespace IW4MAdmin namespace IW4MAdmin
{ {
@ -14,7 +14,7 @@ namespace IW4MAdmin
{ {
public static IServer webService; public static IServer webService;
public static IScheduler getScheduler() public static IScheduler GetScheduler()
{ {
var webScheduler = Kayak.KayakScheduler.Factory.Create(new Scheduler()); var webScheduler = Kayak.KayakScheduler.Factory.Create(new Scheduler());
webService = KayakServer.Factory.CreateHttp(new Request(), webScheduler); webService = KayakServer.Factory.CreateHttp(new Request(), webScheduler);
@ -30,14 +30,14 @@ namespace IW4MAdmin
SharedLibrary.WebService.pageList.Add(new ConsoleJSON()); SharedLibrary.WebService.pageList.Add(new ConsoleJSON());
SharedLibrary.WebService.pageList.Add(new PubbansJSON()); SharedLibrary.WebService.pageList.Add(new PubbansJSON());
Thread scheduleThread = new Thread(() => { scheduleThreadStart(webScheduler, webService); }); Thread scheduleThread = new Thread(() => { ScheduleThreadStart(webScheduler, webService); });
scheduleThread.Name = "Web Service Thread"; scheduleThread.Name = "Web Service Thread";
scheduleThread.Start(); scheduleThread.Start();
return webScheduler; return webScheduler;
} }
private static void scheduleThreadStart(IScheduler S, IServer ss) private static void ScheduleThreadStart(IScheduler S, IServer ss)
{ {
try try
{ {
@ -65,8 +65,14 @@ namespace IW4MAdmin
} }
} }
public static HttpResponse getPage(string path, System.Collections.Specialized.NameValueCollection queryset, IDictionary<string, string> headers) public static HttpResponse GetPage(string path, System.Collections.Specialized.NameValueCollection queryset, IDictionary<string, string> headers)
{ {
if (SharedLibrary.WebService.pageList == null || SharedLibrary.WebService.pageList.Count == 0)
return new HttpResponse() { content = "Error: page list not initialized!", contentType = "text/plaintext" };
if (path == null)
return new HttpResponse() { content = "Error: no path specified", contentType = "text/plaintext" };
IPage requestedPage = SharedLibrary.WebService.pageList.Find(x => x.getPath().ToLower() == path.ToLower()); IPage requestedPage = SharedLibrary.WebService.pageList.Find(x => x.getPath().ToLower() == path.ToLower());
if (requestedPage != null) if (requestedPage != null)

Binary file not shown.

View File

@ -3,6 +3,7 @@ using SharedLibrary;
using SharedLibrary.Interfaces; using SharedLibrary.Interfaces;
using System.Threading.Tasks; using System.Threading.Tasks;
#if DEBUG
namespace Auto_Restart_Plugin namespace Auto_Restart_Plugin
{ {
public class Main : IPlugin public class Main : IPlugin
@ -70,3 +71,4 @@ namespace Auto_Restart_Plugin
} }
} }
} }
#endif

View File

@ -10,12 +10,42 @@ using SharedLibrary.Network;
namespace Plugin namespace Plugin
{ {
public class FastRestartConfig : Serialize<FastRestartConfig>
{
public bool Enabled;
}
public class CEnableFastRestart : Command
{
public CEnableFastRestart() : base("frenable", "enable fast restarting at the end of a map. syntax: !fre", "fre", Player.Permission.SeniorAdmin, 0, false) { }
public override async Task ExecuteAsync(Event E)
{
FastRestartPlugin.Config = new FastRestartConfig() { Enabled = true };
Serialize<FastRestartConfig>.Write($"config/fastrestartconfig_{E.Owner}.cfg", FastRestartPlugin.Config);
await E.Origin.Tell("Fast restarting is now enabled for this server");
}
}
public class CDisableFastRestart : Command
{
public CDisableFastRestart() : base("fredisable", "disable fast restarting at the end of a map. syntax: !frd", "frd", Player.Permission.SeniorAdmin, 0, false) { }
public override async Task ExecuteAsync(Event E)
{
FastRestartPlugin.Config = new FastRestartConfig() { Enabled = false };
Serialize<FastRestartConfig>.Write($"config/fastrestartconfig_{E.Owner}.cfg", FastRestartPlugin.Config);
await E.Origin.Tell("Fast restarting is now disabled for this server");
}
}
public class FastRestartPlugin : IPlugin public class FastRestartPlugin : IPlugin
{ {
bool MatchEnded; bool MatchEnded;
DateTime MatchEndTime; DateTime MatchEndTime;
public static FastRestartConfig Config;
public string Name { get { return "Fast Restart"; } } public string Name { get { return "Fast Restarter"; } }
public float Version { get { return 1.0f; } } public float Version { get { return 1.0f; } }
@ -28,27 +58,39 @@ namespace Plugin
try try
{ {
await S.GetDvarAsync<int>("scr_intermission_time"); await S.GetDvarAsync<int>("scr_intermission_time");
Config = Serialize<FastRestartConfig>.Read($"config/fastrestartconfig_{E.Owner}.cfg");
} }
catch (SharedLibrary.Exceptions.DvarException) catch (SharedLibrary.Exceptions.DvarException)
{ {
await S.ExecuteCommandAsync("set scr_intermission_time 20"); await S.ExecuteCommandAsync("set scr_intermission_time 20");
} }
catch (SharedLibrary.Exceptions.SerializeException)
{
Config = new FastRestartConfig() { Enabled = false };
Serialize<FastRestartConfig>.Write($"config/fastrestartconfig_{E.Owner}.cfg", Config);
}
} }
} }
public async Task OnLoadAsync() public Task OnLoadAsync()
{ {
return null;
} }
public async Task OnTickAsync(Server S) public async Task OnTickAsync(Server S)
{ {
if (!Config.Enabled)
return;
MatchEnded = (await S.GetDvarAsync<int>("scr_gameended")).Value == 1; MatchEnded = (await S.GetDvarAsync<int>("scr_gameended")).Value == 1;
if (MatchEnded && MatchEndTime == DateTime.MinValue) if (MatchEnded && MatchEndTime == DateTime.MinValue)
MatchEndTime = DateTime.Now; MatchEndTime = DateTime.Now;
if (MatchEnded && (DateTime.Now - MatchEndTime).TotalSeconds > (await S.GetDvarAsync<int>("scr_intermission_time")).Value - 5) // I'm pretty sure the timelength from game ended to scoreboard popup is 2000ms
if (MatchEnded && (DateTime.Now - MatchEndTime).TotalSeconds >= ((await S.GetDvarAsync<int>("scr_intermission_time")).Value - 2))
{ {
await S.ExecuteCommandAsync("fast_restart"); await S.ExecuteCommandAsync("fast_restart");
MatchEndTime = DateTime.MinValue; MatchEndTime = DateTime.MinValue;

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SharedLibrary.Exceptions
{
public class SerializeException : Exception
{
public SerializeException(string msg) : base(msg) { }
}
}

View File

@ -11,11 +11,6 @@ namespace SharedLibrary.Interfaces
void Write(); void Write();
} }
public class SerializeException : Exception
{
public SerializeException(string msg) : base(msg) { }
}
public class Serialize<T> : ISerializable<T> public class Serialize<T> : ISerializable<T>
{ {
public static T Read(string filename) public static T Read(string filename)
@ -28,7 +23,7 @@ namespace SharedLibrary.Interfaces
catch (Exception e) catch (Exception e)
{ {
throw new SerializeException($"Could not desialize file {filename}: {e.Message}"); throw new Exceptions.SerializeException($"Could not desialize file {filename}: {e.Message}");
} }
} }
@ -42,10 +37,24 @@ namespace SharedLibrary.Interfaces
catch (Exception e) catch (Exception e)
{ {
throw new SerializeException($"Could not serialize file {Filename()}: {e.Message}"); throw new Exceptions.SerializeException($"Could not serialize file {Filename()}: {e.Message}");
} }
} }
public virtual string Filename() { return this.ToString(); } public static void Write(string filename, T data)
{
try
{
string configText = Newtonsoft.Json.JsonConvert.SerializeObject(data);
File.WriteAllText(filename, configText);
}
catch (Exception e)
{
throw new Exceptions.SerializeException($"Could not serialize file {filename}: {e.Message}");
}
}
public virtual string Filename() { return ToString(); }
} }
} }

View File

@ -421,6 +421,11 @@ namespace SharedLibrary
ruleFile.Close(); ruleFile.Close();
} }
public override string ToString()
{
return $"{IP}_{Port}";
}
/// <summary> /// <summary>
/// Load up the built in commands /// Load up the built in commands
/// </summary> /// </summary>

View File

@ -71,6 +71,7 @@
<Compile Include="Exceptions\CommandException.cs" /> <Compile Include="Exceptions\CommandException.cs" />
<Compile Include="Exceptions\DvarException.cs" /> <Compile Include="Exceptions\DvarException.cs" />
<Compile Include="Exceptions\NetworkException.cs" /> <Compile Include="Exceptions\NetworkException.cs" />
<Compile Include="Exceptions\SerializationException.cs" />
<Compile Include="Exceptions\ServerException.cs" /> <Compile Include="Exceptions\ServerException.cs" />
<Compile Include="Interfaces\ILogger.cs" /> <Compile Include="Interfaces\ILogger.cs" />
<Compile Include="Interfaces\IManager.cs" /> <Compile Include="Interfaces\IManager.cs" />

View File

@ -6,6 +6,7 @@ using SharedLibrary.Network;
using SharedLibrary.Interfaces; using SharedLibrary.Interfaces;
using System.Threading.Tasks; using System.Threading.Tasks;
#if DEBUG
namespace Votemap_Plugin namespace Votemap_Plugin
{ {
/// <summary> /// <summary>
@ -305,3 +306,4 @@ namespace Votemap_Plugin
} }
} }
} }
#endif