CS# bug bypass for survival mode
This commit is contained in:
parent
99ff071723
commit
3602683a34
6 changed files with 29 additions and 6 deletions
|
|
@ -5,6 +5,6 @@
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<Deterministic>true</Deterministic>
|
<Deterministic>true</Deterministic>
|
||||||
<Version>1.0.3</Version>
|
<Version>1.0.4</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
23
Outnumbered/Engine/RespawnFix.cs
Normal file
23
Outnumbered/Engine/RespawnFix.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
using System;
|
||||||
|
using CounterStrikeSharp.API.Core;
|
||||||
|
using CounterStrikeSharp.API.Modules.Memory;
|
||||||
|
|
||||||
|
namespace Outnumbered.Engine;
|
||||||
|
|
||||||
|
// Workaround, pending a CounterStrikeSharp release carrying the upstream fix: CSSharp's
|
||||||
|
// CCSPlayerController.Respawn() calls SetPawn(PlayerPawn.Value), which faults inside the engine's
|
||||||
|
// network-state change code when the pawn is DEAD — the usual respawn case — on the current CS2
|
||||||
|
// build (a bot respawned right after we kill it took the crash). This mirrors CSSharp's Respawn()
|
||||||
|
// but only re-attaches a LIVE pawn; the CCSPlayerController_Respawn vfunc re-creates the pawn on
|
||||||
|
// respawn regardless. Revert every SafeRespawn() call back to .Respawn() once the fixed package ships.
|
||||||
|
internal static class RespawnFix
|
||||||
|
{
|
||||||
|
public static void SafeRespawn(this CCSPlayerController controller)
|
||||||
|
{
|
||||||
|
if (controller is not { IsValid: true }) return;
|
||||||
|
var pawn = controller.PlayerPawn.Value;
|
||||||
|
if (pawn == null) return;
|
||||||
|
if (pawn is { IsValid: true, Health: > 0 }) controller.SetPawn(pawn);
|
||||||
|
VirtualFunction.CreateVoid<IntPtr>(controller.Handle, GameData.GetOffset("CCSPlayerController_Respawn"))(controller.Handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Outnumbered;
|
||||||
public sealed partial class OutnumberedPlugin : BasePlugin, IPluginConfig<OutnumberedConfig>
|
public sealed partial class OutnumberedPlugin : BasePlugin, IPluginConfig<OutnumberedConfig>
|
||||||
{
|
{
|
||||||
public override string ModuleName => "Outnumbered";
|
public override string ModuleName => "Outnumbered";
|
||||||
public override string ModuleVersion => "1.0.3-modes";
|
public override string ModuleVersion => "1.0.4-modes";
|
||||||
public override string ModuleAuthor => "snake";
|
public override string ModuleAuthor => "snake";
|
||||||
public override string ModuleDescription => "Players-vs-bots RPG / perk mod.";
|
public override string ModuleDescription => "Players-vs-bots RPG / perk mod.";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -657,7 +657,7 @@ public sealed class SurvivalDriver : IMatchDriver, IDraftDriver
|
||||||
// Respawn a pool bot, then (deferred a frame so the spawn settles) teleport it to a spawn point away from the squad.
|
// Respawn a pool bot, then (deferred a frame so the spawn settles) teleport it to a spawn point away from the squad.
|
||||||
private void DirectedBotSpawn(CCSPlayerController bot)
|
private void DirectedBotSpawn(CCSPlayerController bot)
|
||||||
{
|
{
|
||||||
bot.Respawn();
|
bot.SafeRespawn(); // CSSharp's Respawn() faults in SetPawn on a dead controller (see RespawnFix)
|
||||||
if (_spawnPoints.Count == 0 || _p.Config.Survival.MinSpawnDistance <= 0) return; // no candidates / disabled -> plain respawn
|
if (_spawnPoints.Count == 0 || _p.Config.Survival.MinSpawnDistance <= 0) return; // no candidates / disabled -> plain respawn
|
||||||
int slot = bot.Slot;
|
int slot = bot.Slot;
|
||||||
OutnumberedPlugin.NextFrameForSlot(slot, b =>
|
OutnumberedPlugin.NextFrameForSlot(slot, b =>
|
||||||
|
|
@ -923,7 +923,7 @@ public sealed partial class OutnumberedPlugin
|
||||||
if (p is not { IsValid: true } || p.IsBot || p.PawnIsAlive || p.Team != CsTeam.CounterTerrorist) return;
|
if (p is not { IsValid: true } || p.IsBot || p.PawnIsAlive || p.Team != CsTeam.CounterTerrorist) return;
|
||||||
if (p.AuthorizedSteamID?.SteamId64 is not { } sid) return;
|
if (p.AuthorizedSteamID?.SteamId64 is not { } sid) return;
|
||||||
var dest = teleportTo is { } t ? new Vector(t.X, t.Y, t.Z) : null;
|
var dest = teleportTo is { } t ? new Vector(t.X, t.Y, t.Z) : null;
|
||||||
p.Respawn();
|
p.SafeRespawn(); // CSSharp's Respawn() faults in SetPawn on a dead controller (see RespawnFix)
|
||||||
NextFrameForSlot(p.Slot, sid, pl =>
|
NextFrameForSlot(p.Slot, sid, pl =>
|
||||||
{
|
{
|
||||||
var pd = PdOf(pl); var pawn = pl.PlayerPawn.Value;
|
var pd = PdOf(pl); var pawn = pl.PlayerPawn.Value;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.369" ExcludeAssets="runtime" />
|
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.370" ExcludeAssets="runtime" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" ExcludeAssets="runtime" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" ExcludeAssets="runtime" />
|
||||||
<PackageReference Include="Dapper" Version="2.1.72" />
|
<PackageReference Include="Dapper" Version="2.1.72" />
|
||||||
<PackageReference Include="Npgsql" Version="10.0.0" />
|
<PackageReference Include="Npgsql" Version="10.0.0" />
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ servers.
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- A CS2 dedicated server with **Metamod:Source** and **CounterStrikeSharp** installed
|
- A CS2 dedicated server with **Metamod:Source** and **CounterStrikeSharp** installed
|
||||||
(compiled against CounterStrikeSharp API **1.0.369**; use a matching or newer server build).
|
(compiled against CounterStrikeSharp API **1.0.370**; use a matching or newer server build).
|
||||||
- **.NET 10** — provided by the CounterStrikeSharp runtime; only needed as an SDK if you build from source.
|
- **.NET 10** — provided by the CounterStrikeSharp runtime; only needed as an SDK if you build from source.
|
||||||
- **Linux** — the damage path, native grenade spawning, and launch-flag parsing are Linux-specific.
|
- **Linux** — the damage path, native grenade spawning, and launch-flag parsing are Linux-specific.
|
||||||
- A database: **PostgreSQL** for production (recommended, required for multi-instance), or **SQLite** for single-server/dev.
|
- A database: **PostgreSQL** for production (recommended, required for multi-instance), or **SQLite** for single-server/dev.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue