using System;
using System.Threading;
using System.Threading.Tasks;
using SharedLibraryCore.Objects;
namespace SharedLibraryCore
{
public class GameEvent
{
public enum EventType
{
///
/// the event wasn't parsed properly
///
Unknown,
// events "generated" by the server
///
/// a server started being monitored
///
Start,
///
/// a server stopped being monitored
///
Stop,
///
/// a client was detecting as connecting via RCon
///
Connect,
///
/// a client was detecting joining via log
///
Join,
///
/// a client was detected leaving via log
///
Quit,
///
/// a client was detected leaving by RCon
///
Disconnect,
///
/// the current map ended
///
MapEnd,
///
/// the current map changed
///
MapChange,
// events "generated" by clients
///
/// a client sent a message
///
Say,
///
/// a client was warned
///
Warn,
///
/// a client was reported
///
Report,
///
/// a client was flagged
///
Flag,
///
/// a client was unflagged
///
Unflag,
///
/// a client was kicked
///
Kick,
///
/// a client was tempbanned
///
TempBan,
///
/// a client was banned
///
Ban,
///
/// a client entered a command
///
Command,
///
/// a client's permission was changed
///
ChangePermission,
// events "generated" by IW4MAdmin
///
/// a message is sent to all clients
///
Broadcast,
///
/// a message is sent to a specific client
///
Tell,
// events "generated" by script/log
///
/// AC Damage Log
///
ScriptDamage,
///
/// AC Kill Log
///
ScriptKill,
///
/// damage info printed out by game script
///
Damage,
///
/// kill info printed out by game script
///
Kill,
///
/// team info printed out by game script
///
JoinTeam,
}
static long NextEventId;
static long GetNextEventId() => Interlocked.Increment(ref NextEventId);
public GameEvent()
{
OnProcessed = new ManualResetEventSlim(false);
Time = DateTime.UtcNow;
Id = GetNextEventId();
}
public EventType Type;
public string Data; // Data is usually the message sent by player
public string Message;
public Player Origin;
public Player Target;
public Server Owner;
public Boolean Remote = false;
public object Extra { get; set; }
public ManualResetEventSlim OnProcessed { get; set; }
public DateTime Time { get; set; }
public long Id { get; private set; }
///
/// asynchronously wait for GameEvent to be processed
///
/// waitable task
public Task WaitAsync(int timeOut = int.MaxValue) => Task.FromResult(OnProcessed.Wait(timeOut));
///
/// determine whether an event should be delayed or not
/// applies only to the origin entity
///
/// event to determine status for
/// true if event should be delayed, false otherwise
public static bool ShouldOriginEventBeDelayed(GameEvent queuedEvent)
{
return queuedEvent.Origin != null &&
queuedEvent.Origin.State != Player.ClientState.Connected &&
// we want to allow join and quit events
queuedEvent.Type != EventType.Connect &&
queuedEvent.Type != EventType.Join &&
queuedEvent.Type != EventType.Quit &&
queuedEvent.Type != EventType.Disconnect &&
// we don't care about unknown events
queuedEvent.Origin.NetworkId != 0;
}
///
/// determine whether an event should be delayed or not
/// applies only to the target entity
///
/// event to determine status for
/// true if event should be delayed, false otherwise
public static bool ShouldTargetEventBeDelayed(GameEvent queuedEvent)
{
return queuedEvent.Target != null &&
queuedEvent.Target.State != Player.ClientState.Connected &&
queuedEvent.Target.NetworkId != 0;
}
public static bool IsEventTimeSensitive(GameEvent gameEvent) => gameEvent.Type == EventType.Connect;
}
}