Skip to content

Commit

Permalink
Game Event Broadcast Manipulation & Cancellation (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
roflmuffin authored Oct 23, 2023
1 parent 37b085a commit 65bdd0b
Show file tree
Hide file tree
Showing 17 changed files with 620 additions and 523 deletions.
34 changes: 18 additions & 16 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -4
Standard: c++11
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4
UseTab: Never
ColumnLimit: 100
DerivePointerAlignment: false
PointerAlignment: Left
AlignAfterOpenBracket: Align
BinPackParameters: false
AlignEscapedNewlines: Left
AlwaysBreakTemplateDeclarations: Yes
PackConstructorInitializers: Never
BreakConstructorInitializersBeforeComma: false
IndentPPDirectives: BeforeHash
SortIncludes: Never
...

KeepEmptyLinesAtTheStartOfBlocks: false
SortIncludes: false
SpaceBeforeParens: ControlStatements
AllowAllArgumentsOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
IndentCaseLabels: false
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterStruct: true
AfterEnum: true
AfterUnion: true
AfterNamespace: false
AfterFunction: true
IndentBraces: false
45 changes: 23 additions & 22 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Checks: >
-readability-redundant-declaration,
-readability-function-cognitive-complexity,
-readability-convert-member-functions-to-static,
-readability-implicit-bool-conversion,
-bugprone-narrowing-conversions,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
Expand All @@ -92,25 +93,25 @@ Checks: >
WarningsAsErrors: "*"

CheckOptions:
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold
value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines
value: '10'
- key: google-readability-namespace-comments.SpacesBeforeComments
value: '2'
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.MemberCase
value: camelBack
- key: readability-identifier-naming.EnumCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: CamelCase
- key: readability-identifier-naming.ParameterCase
value: camelBack
- key: readability-identifier-naming.UnionCase
value: CamelCase
- key: readability-identifier-naming.VariableCase
value: camelBack
google-readability-braces-around-statements.ShortStatementLines: '1'
google-readability-function-size.StatementThreshold: '800'
google-readability-namespace-comments.ShortNamespaceLines: '10'
google-readability-namespace-comments.SpacesBeforeComments: '2'
readability-identifier-naming.PrivateMemberPrefix: 'm_'
readability-identifier-naming.ProtectedMemberPrefix: 'm_'
readability-identifier-naming.MemberPrefix: 'm_'
readability-identifier-naming.ClassCase: CamelCase
readability-identifier-naming.MemberCase: CamelCase
readability-identifier-naming.EnumCase: CamelCase
readability-identifier-naming.FunctionCase: CamelCase
readability-identifier-naming.ParameterCase: CamelCase
readability-identifier-naming.UnionCase: CamelCase
readability-identifier-naming.VariableCase: CamelCase
readability-identifier-naming.LocalConstantPointerPrefix: 'p'
readability-identifier-naming.VariableHungarianPrefix: On
readability-identifier-naming.ParameterHungarianPrefix: On
readability-identifier-naming.MemberHungarianPrefix: On
readability-identifier-naming.PointerParameterHungarianPrefix: On
readability-identifier-naming.PointerParameterCase: CamelCase
readability-identifier-naming.HungarianNotation.UserDefinedType.std::string: s

16 changes: 14 additions & 2 deletions docs/src/content/docs/features/game-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ The first parameter type must be a subclass of the `GameEvent` class. The names

```csharp
[GameEventHandler]
public void OnPlayerConnect(EventPlayerConnect @event)
public HookResult OnPlayerConnect(EventPlayerConnect @event, GameEventInfo info)
{
// Userid will give you a reference to a CCSPlayerController class
Log($"Player {@event.Userid.PlayerName} has connected!");

return HookResult.Continue;
}
```

Expand All @@ -29,9 +31,11 @@ It is also possible to bind event listeners in the `OnLoad` (or anywhere you hav
```csharp
public override void Load(bool hotReload)
{
RegisterEventHandler<EventRoundStart>(@event =>
RegisterEventHandler<EventRoundStart>((@event, info) =>
{
Console.WriteLine($"Round has started with time limit of {@event.Timelimit}");

return HookResult.Continue;
});
}
```
Expand All @@ -41,3 +45,11 @@ public override void Load(bool hotReload)
The specific subclass of `GameEvent` will provide strongly typed parameters from the event definition. e.g. `event.Timelimit` will be a `long` value, `event.UserId` will be a `CCSPlayerController` and so-on.

These event properties are mutable so you can update them as normal and they will update in the event instance.

## Preventing Broadcast

You can modify a game event so that it does not get broadcast to clients by modifying the `bool info.DontBroadcast` property. e.g.

## Cancelling an Event

In a pre-event hook, you can prevent the event from continuing to other plugins by returning `HookResult.Handled` or `HookResult.Stop`.
4 changes: 3 additions & 1 deletion docs/src/content/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ public class HelloWorldPlugin : BasePlugin
}

[GameEventHandler]
public void OnPlayerConnect(EventPlayerConnect @event)
public HookResult OnPlayerConnect(EventPlayerConnect @event, GameEventInfo info)
{
// Userid will give you a reference to a CCSPlayerController class
Log($"Player {@event.Userid.PlayerName} has connected!");

return HookResult.Continue;
}

[ConsoleCommand("issue_warning", "Issue warning to player")]
Expand Down
2 changes: 1 addition & 1 deletion makefiles/linux.base.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ SET(
dynload_s
dyncall_s
distorm
funchook-shared
funchook-static
)
23 changes: 8 additions & 15 deletions managed/CounterStrikeSharp.API/Core/BasePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,27 +102,20 @@ public void Dispose()
new Dictionary<Delegate, CallbackSubscriber>();

public readonly List<Timer> Timers = new List<Timer>();

public delegate HookResult GameEventHandler<T>(T @event, GameEventInfo info) where T : GameEvent;

private void RegisterEventHandlerInternal<T>(string name, Action<T> handler, bool post = false)
where T : GameEvent, new()
private void RegisterEventHandlerInternal<T>(string name, GameEventHandler<T> handler, bool post = false)
where T : GameEvent
{
var wrappedHandler = new Action<IntPtr>(pointer =>
{
var @event = new T
{
Handle = pointer
};
handler.Invoke(@event);
});

var subscriber = new CallbackSubscriber(handler, wrappedHandler,
var subscriber = new CallbackSubscriber(handler, handler,
() => DeregisterEventHandler(name, handler, post));

NativeAPI.HookEvent(name, subscriber.GetInputArgument(), post);
Handlers[handler] = subscriber;
}

public void RegisterEventHandler<T>(Action<T> handler, bool post = false) where T : GameEvent, new()
public void RegisterEventHandler<T>(GameEventHandler<T> handler, bool post = false) where T : GameEvent
{
var name = typeof(T).GetCustomAttribute<EventNameAttribute>()?.Name;
RegisterEventHandlerInternal(name, handler, post);
Expand Down Expand Up @@ -276,8 +269,8 @@ public void RegisterAttributeHandlers(object instance)
var parameterType = eventHandler.GetParameters().First().ParameterType;
var eventName = parameterType.GetCustomAttribute<EventNameAttribute>()?.Name;

var actionType = typeof(Action<>).MakeGenericType(parameterType);
var action = eventHandler.CreateDelegate(actionType, instance);
var actionType = typeof(GameEventHandler<>).MakeGenericType(parameterType);
var action = Delegate.CreateDelegate(actionType, instance, eventHandler);

var generic = method.MakeGenericMethod(parameterType);
generic.Invoke(this, new object[] { eventName, action, false });
Expand Down
13 changes: 13 additions & 0 deletions managed/CounterStrikeSharp.API/Core/GameEventInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Runtime.CompilerServices;

namespace CounterStrikeSharp.API.Core;

public class GameEventInfo : NativeObject
{
public GameEventInfo(IntPtr pointer) : base(pointer)
{
}

public unsafe ref bool DontBroadcast => ref Unsafe.AsRef<bool>((void*)Handle);
}
Loading

0 comments on commit 65bdd0b

Please sign in to comment.