Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions managed/CounterStrikeSharp.API/Core/BasePlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
{
private bool _disposed;

public BasePlugin()

Check warning on line 43 in managed/CounterStrikeSharp.API/Core/BasePlugin.cs

View workflow job for this annotation

GitHub Actions / build_managed

Non-nullable property 'ModuleAuthor' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
{
RegisterListener<Listeners.OnMapEnd>(() =>
{
Expand Down Expand Up @@ -370,6 +370,21 @@
return timer;
}

/// <summary>
/// Adds a timer that will call the given callback after the specified amount of ticks.
/// By default will only run once unless the <see cref="TimerFlags.REPEAT"/> flag is set.
/// </summary>
/// <param name="interval">Interval/Delay in ticks</param>
/// <param name="callback">Code to run when timer elapses</param>
/// <param name="flags">Controls if the timer is a one-off, repeat or stops on map change etc.</param>
/// <returns>An instance of the <see cref="Timer"/></returns>
public Timer AddTickTimer(int tickInterval, Action callback, TimerFlags? flags = null)
{
var timer = new Timer(tickInterval * Server.TickInterval, callback, flags ?? 0);
Timers.Add(timer);
return timer;
}

/// <summary>
/// Registers all attribute handlers on the given instance.
/// Can be used to register event handlers, console commands, entity outputs etc. from classes that are not derived from `BasePlugin`.
Expand Down Expand Up @@ -511,7 +526,7 @@
}
}

public void RegisterFakeConVars(Type type, object instance = null)

Check warning on line 529 in managed/CounterStrikeSharp.API/Core/BasePlugin.cs

View workflow job for this annotation

GitHub Actions / build_managed

Cannot convert null literal to non-nullable reference type.

Check warning on line 529 in managed/CounterStrikeSharp.API/Core/BasePlugin.cs

View workflow job for this annotation

GitHub Actions / build_managed

Cannot convert null literal to non-nullable reference type.
{
var convars = type
.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)
Expand Down
15 changes: 14 additions & 1 deletion managed/CounterStrikeSharp.Tests.Native/SchemaTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
Expand All @@ -14,7 +15,19 @@ public void GetSchemaOffset_ReturnsValidOffset()
{
var offset = NativeAPI.GetSchemaOffset("CBaseEntity", "m_iHealth");

Assert.True(offset > 0, $"Schema offset for m_iHealth should be positive, got {offset}");
Assert.Equal(1464, offset); // Hardcode for now, this may change but I want to know if it changes
}

[Fact]
public async Task GetSchemaOffset_CanRunOnAnotherThread()
{
await Task.Run(async () =>
{
await Task.Yield();
Assert.NotEqual(Thread.CurrentThread.ManagedThreadId, NativeTestsPlugin.gameThreadId);
var offset = NativeAPI.GetSchemaOffset("CBaseEntity", "m_iHealth");
Assert.True(offset > 0);
});
}

[Fact]
Expand Down
26 changes: 26 additions & 0 deletions managed/CounterStrikeSharp.Tests.Native/TimerTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using CounterStrikeSharp.API;
using CounterStrikeSharp.API.Core;
Expand Down Expand Up @@ -60,6 +61,31 @@ public async Task CreateTimer_RepeatsWithFlag()
}
}

[Fact]
public async Task CreateTimer_TickBased()
{
var startTick = Server.TickCount;
var tickCounts = new List<int>();
int timesTicked = 0;

// Run every 4 ticks
var timer = new Timer(4 * Server.TickInterval, () =>
{
timesTicked++;
tickCounts.Add(Server.TickCount);
}, TimerFlags.REPEAT);

await Server.RunOnTickAsync(startTick + 16, () => { });
timer.Kill();

Assert.Equal(4, timesTicked);
for (int i = 0; i < tickCounts.Count; i++)
{
var expectedTick = startTick + (i + 1) * 4;
Assert.Equal(expectedTick, tickCounts[i]);
}
}

[Fact]
public async Task KillTimer_StopsExecution()
{
Expand Down
15 changes: 3 additions & 12 deletions src/core/timer_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,7 @@ void TimerSystem::OnGameFrame(bool simulating)
m_last_ticked_time = globals::getGlobalVars()->curtime;
m_has_map_ticked = true;

// Handle timer tick
if (timers::universal_time >= timers::timer_next_think)
{
RunFrame();

timers::timer_next_think = CalculateNextThink(timers::timer_next_think, 0.1f);
}
RunFrame();

if (m_on_tick_callback_->GetFunctionCount())
{
Expand All @@ -138,14 +132,11 @@ void TimerSystem::OnGameFrame(bool simulating)

double TimerSystem::CalculateNextThink(double last_think_time, float interval)
{
if (timers::universal_time - last_think_time - interval <= 0.1)
if (timers::universal_time - last_think_time - interval <= globals::engine_fixed_tick_interval)
{
return last_think_time + interval;
}
else
{
return timers::universal_time + interval;
}
return timers::universal_time + interval;
}

void TimerSystem::RunFrame()
Expand Down
1 change: 1 addition & 0 deletions src/mm_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ DLL_EXPORT void InvokeNative(counterstrikesharp::fxNativeContext& context)
if (context.nativeIdentifier == 0) return;

if (context.nativeIdentifier != counterstrikesharp::hash_string_const("QUEUE_TASK_FOR_FRAME") &&
context.nativeIdentifier != counterstrikesharp::hash_string_const("GET_SCHEMA_OFFSET") &&
counterstrikesharp::globals::gameThreadId != std::this_thread::get_id())
{
counterstrikesharp::ScriptContextRaw scriptContext(context);
Expand Down
Loading