IW4M-Admin/SharedLibraryCore/Events/GameEvent.cs
2019-10-08 17:02:22 -05:00

250 lines
7.5 KiB
C#

using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Events;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace SharedLibraryCore
{
public class GameEvent
{
// define what the delagate function looks like
public delegate void OnServerEventEventHandler(object sender, GameEventArgs e);
public enum EventFailReason
{
/// <summary>
/// event execution did not fail
/// </summary>
None,
/// <summary>
/// an internal exception prevented the event
/// from executing
/// </summary>
Exception,
/// <summary>
/// event origin didn't have the necessary privileges
/// to execute the command
/// </summary>
Permission,
/// <summary>
/// executing the event would cause an invalid state
/// </summary>
Invalid,
/// <summary>
/// client is doing too much of something
/// </summary>
Throttle,
/// <summary>
/// the event timed out before completion
/// </summary>
Timeout
}
public enum EventType
{
/// <summary>
/// the event wasn't parsed properly
/// </summary>
Unknown,
// events "generated" by the server
/// <summary>
/// a server started being monitored
/// </summary>
Start,
/// <summary>
/// a server stopped being monitored
/// </summary>
Stop,
/// <summary>
/// a client was detecting as connecting via log
/// </summary>
Connect,
/// <summary>
/// a client was detecting joining by RCon
/// </summary>
Join,
/// <summary>
/// a client was detected leaving via log
/// </summary>
Quit,
/// <summary>
/// a client was detected leaving by RCon
/// </summary>
Disconnect,
/// <summary>
/// the current map ended
/// </summary>
MapEnd,
/// <summary>
/// the current map changed
/// </summary>
MapChange,
/// <summary>
/// a client was detected as starting to connect
/// </summary>
PreConnect,
/// <summary>
/// a client was detecting as starting to disconnect
/// </summary>
PreDisconnect,
/// <summary>
/// a client's information was updated
/// </summary>
Update,
/// <summary>
/// connection was lost to a server (the server has not responded after a number of attempts)
/// </summary>
ConnectionLost,
/// <summary>
/// connection was restored to a server (the server began responding again)
/// </summary>
ConnectionRestored,
// events "generated" by clients
/// <summary>
/// a client sent a message
/// </summary>
Say = 100,
/// <summary>
/// a client was warned
/// </summary>
Warn = 101,
/// <summary>
/// all warnings for a client were cleared
/// </summary>
WarnClear = 102,
/// <summary>
/// a client was reported
/// </summary>
Report = 103,
/// <summary>
/// a client was flagged
/// </summary>
Flag = 104,
/// <summary>
/// a client was unflagged
/// </summary>
Unflag = 105,
/// <summary>
/// a client was kicked
/// </summary>
Kick = 106,
/// <summary>
/// a client was tempbanned
/// </summary>
TempBan = 107,
/// <summary>
/// a client was banned
/// </summary>
Ban = 108,
/// <summary>
/// a client was unbanned
/// </summary>
Unban = 109,
/// <summary>
/// a client entered a command
/// </summary>
Command = 110,
/// <summary>
/// a client's permission was changed
/// </summary>
ChangePermission = 111,
// events "generated" by IW4MAdmin
/// <summary>
/// a message is sent to all clients
/// </summary>
Broadcast = 200,
/// <summary>
/// a message is sent to a specific client
/// </summary>
Tell = 201,
// events "generated" by script/log
/// <summary>
/// AC Damage Log
/// </summary>
ScriptDamage = 300,
/// <summary>
/// AC Kill Log
/// </summary>
ScriptKill = 301,
/// <summary>
/// damage info printed out by game script
/// </summary>
Damage = 302,
/// <summary>
/// kill info printed out by game script
/// </summary>
Kill = 303,
/// <summary>
/// team info printed out by game script
/// </summary>
JoinTeam = 304,
/// <summary>
/// used for community generated plugin events
/// </summary>
Other
}
[Flags]
public enum EventRequiredEntity
{
None = 1,
Origin = 2,
Target = 4
}
static long NextEventId;
static long GetNextEventId()
{
return Interlocked.Increment(ref NextEventId);
}
public GameEvent()
{
OnProcessed = new ManualResetEventSlim(false);
Time = DateTime.UtcNow;
Id = GetNextEventId();
}
public EventType Type;
public EventRequiredEntity RequiredEntity { get; set; }
public string Data; // Data is usually the message sent by player
public string Message;
public EFClient Origin;
public EFClient Target;
public Server Owner;
public bool IsRemote { get; set; } = false;
public object Extra { get; set; }
public ManualResetEventSlim OnProcessed { get; set; }
public DateTime Time { get; set; }
public long Id { get; private set; }
public EventFailReason FailReason { get; set; }
public bool Failed => FailReason != EventFailReason.None;
/// <summary>
/// asynchronously wait for GameEvent to be processed
/// </summary>
/// <returns>waitable task </returns>
public Task<GameEvent> WaitAsync(TimeSpan timeSpan, CancellationToken token)
{
return Task.Run(() =>
{
bool processed = OnProcessed.Wait(timeSpan, token);
// this let's us know if the the action timed out
FailReason = FailReason == EventFailReason.None & !processed ? EventFailReason.Timeout : FailReason;
return this;
});
}
public GameEvent Wait()
{
OnProcessed.Wait();
return this;
}
}
}