diff --git a/managed/src/SwiftlyS2.Core/Modules/Schemas/Extensions/CEntityInstanceImpl.cs b/managed/src/SwiftlyS2.Core/Modules/Schemas/Extensions/CEntityInstanceImpl.cs index 097ff1615..2dcf45574 100644 --- a/managed/src/SwiftlyS2.Core/Modules/Schemas/Extensions/CEntityInstanceImpl.cs +++ b/managed/src/SwiftlyS2.Core/Modules/Schemas/Extensions/CEntityInstanceImpl.cs @@ -1,100 +1,102 @@ using SwiftlyS2.Core.Natives; -using SwiftlyS2.Core.Schemas; using SwiftlyS2.Shared.EntitySystem; -using SwiftlyS2.Shared.Natives; using SwiftlyS2.Shared.SchemaDefinitions; -using SwiftlyS2.Shared.Schemas; namespace SwiftlyS2.Core.SchemaDefinitions; -internal partial class CEntityInstanceImpl : CEntityInstance { +internal partial class CEntityInstanceImpl : CEntityInstance +{ + public uint Index => Entity?.EntityHandle.EntityIndex ?? uint.MaxValue; + public string DesignerName => Entity?.DesignerName ?? string.Empty; - public uint Index => Entity?.EntityHandle.EntityIndex ?? uint.MaxValue; - - public string DesignerName => Entity?.DesignerName ?? string.Empty; - - public void AcceptInput(string input, T value, CEntityInstance? activator = null, CEntityInstance? caller = null, int outputID = 0) { - switch (value) { - case bool boolValue: - NativeEntitySystem.AcceptInputBool(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, boolValue, outputID); - break; - case int intValue: - NativeEntitySystem.AcceptInputInt32(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, intValue, outputID); - break; - case uint uintValue: - NativeEntitySystem.AcceptInputUInt32(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, uintValue, outputID); - break; - case long longValue: - NativeEntitySystem.AcceptInputInt64(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, longValue, outputID); - break; - case ulong ulongValue: - NativeEntitySystem.AcceptInputUInt64(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, ulongValue, outputID); - break; - case float floatValue: - NativeEntitySystem.AcceptInputFloat(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, floatValue, outputID); - break; - case double doubleValue: - NativeEntitySystem.AcceptInputDouble(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, doubleValue, outputID); - break; - case string stringValue: - NativeEntitySystem.AcceptInputString(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, stringValue, outputID); - break; - default: - throw new InvalidOperationException($"Unsupported type: {typeof(T).Name}"); + public void AcceptInput( string input, T value, CEntityInstance? activator = null, CEntityInstance? caller = null, int outputID = 0 ) + { + switch (value) + { + case bool boolValue: + NativeEntitySystem.AcceptInputBool(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, boolValue, outputID); + break; + case int intValue: + NativeEntitySystem.AcceptInputInt32(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, intValue, outputID); + break; + case uint uintValue: + NativeEntitySystem.AcceptInputUInt32(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, uintValue, outputID); + break; + case long longValue: + NativeEntitySystem.AcceptInputInt64(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, longValue, outputID); + break; + case ulong ulongValue: + NativeEntitySystem.AcceptInputUInt64(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, ulongValue, outputID); + break; + case float floatValue: + NativeEntitySystem.AcceptInputFloat(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, floatValue, outputID); + break; + case double doubleValue: + NativeEntitySystem.AcceptInputDouble(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, doubleValue, outputID); + break; + case string stringValue: + NativeEntitySystem.AcceptInputString(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, stringValue, outputID); + break; + default: + throw new InvalidOperationException($"Unsupported type: {typeof(T).Name}"); + } } - } - public void AddEntityIOEvent(string input, T value, CEntityInstance? activator = null, CEntityInstance? caller = null, float delay = 0f) { - switch (value) { - case bool boolValue: - NativeEntitySystem.AddEntityIOEventBool(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, boolValue, delay); - break; - case int intValue: - NativeEntitySystem.AddEntityIOEventInt32(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, intValue, delay); - break; - case uint uintValue: - NativeEntitySystem.AddEntityIOEventUInt32(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, uintValue, delay); - break; - case long longValue: - NativeEntitySystem.AddEntityIOEventInt64(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, longValue, delay); - break; - case ulong ulongValue: - NativeEntitySystem.AddEntityIOEventUInt64(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, ulongValue, delay); - break; - case float floatValue: - NativeEntitySystem.AddEntityIOEventFloat(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, floatValue, delay); - break; - case double doubleValue: - NativeEntitySystem.AddEntityIOEventDouble(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, doubleValue, delay); - break; - case string stringValue: - NativeEntitySystem.AddEntityIOEventString(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, stringValue, delay); - break; - default: - throw new InvalidOperationException($"Unsupported type: {typeof(T).Name}"); + public void AddEntityIOEvent( string input, T value, CEntityInstance? activator = null, CEntityInstance? caller = null, float delay = 0f ) + { + switch (value) + { + case bool boolValue: + NativeEntitySystem.AddEntityIOEventBool(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, boolValue, delay); + break; + case int intValue: + NativeEntitySystem.AddEntityIOEventInt32(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, intValue, delay); + break; + case uint uintValue: + NativeEntitySystem.AddEntityIOEventUInt32(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, uintValue, delay); + break; + case long longValue: + NativeEntitySystem.AddEntityIOEventInt64(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, longValue, delay); + break; + case ulong ulongValue: + NativeEntitySystem.AddEntityIOEventUInt64(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, ulongValue, delay); + break; + case float floatValue: + NativeEntitySystem.AddEntityIOEventFloat(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, floatValue, delay); + break; + case double doubleValue: + NativeEntitySystem.AddEntityIOEventDouble(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, doubleValue, delay); + break; + case string stringValue: + NativeEntitySystem.AddEntityIOEventString(Address, input, activator?.Address ?? nint.Zero, caller?.Address ?? nint.Zero, stringValue, delay); + break; + default: + throw new InvalidOperationException($"Unsupported type: {typeof(T).Name}"); + } } - } - public void SetTransmitState( bool transmitting , int playerId ) { - NativePlayer.ShouldBlockTransmitEntity(playerId, (int)Index, transmitting); + public void SetTransmitState( bool transmitting, int playerId ) + { + NativePlayer.ShouldBlockTransmitEntity(playerId, (int)Index, !transmitting); + } - } + public void SetTransmitState( bool transmitting ) + { + NativePlayerManager.ShouldBlockTransmitEntity((int)Index, !transmitting); + } - public void SetTransmitState( bool transmitting ) - { - NativePlayerManager.ShouldBlockTransmitEntity((int)Index, transmitting); - } - - public bool IsTransmitting( int playerId ) - { - return NativePlayer.IsTransmitEntityBlocked(playerId, (int)Index); - } + public bool IsTransmitting( int playerId ) + { + return !NativePlayer.IsTransmitEntityBlocked(playerId, (int)Index); + } - public void DispatchSpawn(CEntityKeyValues? entityKV = null) { - NativeEntitySystem.Spawn(Address, entityKV?.Address ?? nint.Zero); - } + public void DispatchSpawn( CEntityKeyValues? entityKV = null ) + { + NativeEntitySystem.Spawn(Address, entityKV?.Address ?? nint.Zero); + } - public void Despawn() { - NativeEntitySystem.Despawn(Address); - } + public void Despawn() + { + NativeEntitySystem.Despawn(Address); + } } \ No newline at end of file diff --git a/managed/src/TestPlugin/TestPlugin.cs b/managed/src/TestPlugin/TestPlugin.cs index 34127d9a0..bd559d245 100644 --- a/managed/src/TestPlugin/TestPlugin.cs +++ b/managed/src/TestPlugin/TestPlugin.cs @@ -639,10 +639,43 @@ public void GetIpCommand( ICommandContext context ) // } [Command("ed")] - public void EmitGrenadeCommand( ICommandContext _ ) + public void EmitGrenadeCommand( ICommandContext context ) { var smoke = CSmokeGrenadeProjectile.EmitGrenade(new(0, 0, 0), new(0, 0, 0), new(0, 0, 0), Team.CT, null); smoke.Despawn(); + smoke.SetTransmitState(true, context.Sender!.PlayerID); + } + + [Command("hbw")] + public void HideBotWeapon( ICommandContext context ) + { + Core.PlayerManager.GetAlive() + .Where(player => player.PlayerID != context.Sender!.PlayerID && player.IsValid && player.IsFakeClient) + .ToList() + .ForEach(player => player.PlayerPawn!.WeaponServices!.ActiveWeapon.Value!.SetTransmitState(false, context.Sender!.PlayerID)); + } + + [Command("sihb")] + public void ShowIfHideBot( ICommandContext context ) + { + Core.PlayerManager.GetAlive() + .Where(player => player.PlayerID != context.Sender!.PlayerID && player.IsValid && player.IsFakeClient) + .ToList() + .ForEach(player => Console.WriteLine($"{player.Controller!.PlayerName} -> {(!player.PlayerPawn!.IsTransmitting(context.Sender!.PlayerID) ? "Hide" : "V")}")); + } + + [Command("hb")] + public void HideBot( ICommandContext context ) + { + Core.PlayerManager.GetAlive() + .Where(player => player.PlayerID != context.Sender!.PlayerID && player.IsValid && player.IsFakeClient) + .ToList() + .ForEach(player => + { + // Console.WriteLine($"{player.Controller!.PlayerName}(B) -> {player.PlayerPawn!.IsTransmitting(context.Sender!.PlayerID)}({player.PlayerPawn!.IsTransmitting(player.PlayerID)})"); + player.PlayerPawn!.SetTransmitState(!player.PlayerPawn!.IsTransmitting(context.Sender!.PlayerID), context.Sender!.PlayerID); + // Console.WriteLine($"{player.Controller!.PlayerName} -> {player.PlayerPawn!.IsTransmitting(context.Sender!.PlayerID)}({player.PlayerPawn!.IsTransmitting(player.PlayerID)})"); + }); } [Command("ss")] diff --git a/src/scripting/server/player.cpp b/src/scripting/server/player.cpp index f6d16a94a..82e10e252 100644 --- a/src/scripting/server/player.cpp +++ b/src/scripting/server/player.cpp @@ -160,12 +160,16 @@ void Bridge_Player_Kick(int playerid, const char* reason, int gamereason) void Bridge_Player_ShouldBlockTransmitEntity(int playerid, int entityidx, bool shouldBlockTransmit) { if (playerid + 1 == entityidx) + { return; + } static auto playerManager = g_ifaceService.FetchInterface(PLAYERMANAGER_INTERFACE_VERSION); auto player = playerManager->GetPlayer(playerid); if (!player) + { return; + } auto& bv = player->GetBlockedTransmittingBits(); @@ -173,30 +177,42 @@ void Bridge_Player_ShouldBlockTransmitEntity(int playerid, int entityidx, bool s if (shouldBlockTransmit) { bool wasEmpty = (bv.blockedMask[dword] == 0); - bv.blockedMask[dword] |= (1 << (entityidx % 64)); + bv.blockedMask[dword] |= (1ULL << (entityidx % 64)); if (wasEmpty) + { bv.activeMasks.push_back(dword); + } } else { - bv.blockedMask[dword] &= ~(1 << (entityidx % 64)); + bv.blockedMask[dword] &= ~(1ULL << (entityidx % 64)); if (bv.blockedMask[dword] == 0) - bv.activeMasks.erase(std::find(bv.activeMasks.begin(), bv.activeMasks.end(), dword)); + { + auto it = std::find(bv.activeMasks.begin(), bv.activeMasks.end(), dword); + if (it != bv.activeMasks.end()) + { + bv.activeMasks.erase(it); + } + } } } bool Bridge_Player_IsTransmitEntityBlocked(int playerid, int entityidx) { if (playerid + 1 == entityidx) + { return false; + } static auto playerManager = g_ifaceService.FetchInterface(PLAYERMANAGER_INTERFACE_VERSION); auto player = playerManager->GetPlayer(playerid); if (!player) + { return false; + } auto& bv = player->GetBlockedTransmittingBits(); - return (bv.blockedMask[entityidx / 64] & (1 << (entityidx % 64))) != 0; + return (bv.blockedMask[entityidx / 64] & (1ULL << (entityidx % 64))) != 0; } void Bridge_Player_ClearTransmitEntityBlocked(int playerid) diff --git a/src/server/players/manager.cpp b/src/server/players/manager.cpp index 8a6f8061e..1a678df28 100644 --- a/src/server/players/manager.cpp +++ b/src/server/players/manager.cpp @@ -213,6 +213,7 @@ void CheckTransmitHook(void* _this, CCheckTransmitInfo** ppInfoList, int infoCou { continue; } + auto player = playermanager->GetPlayer(playerid); if (!player) { @@ -220,16 +221,13 @@ void CheckTransmitHook(void* _this, CCheckTransmitInfo** ppInfoList, int infoCou } auto& blockedBits = player->GetBlockedTransmittingBits(); - uint64_t* base = reinterpret_cast(pInfo->m_pTransmitEntity->Base()); - uint64_t* baseAlways = reinterpret_cast(pInfo->m_pTransmitAlways->Base()); auto& activeMasks = blockedBits.activeMasks; // NUM_MASKS_ACTIVE ops = NUM_MASKS_ACTIVE*64 bits -> 64 players -> NUM_MASKS_ACTIVE*64 ops for (auto& dword : activeMasks) { base[dword] &= ~blockedBits.blockedMask[dword]; - baseAlways[dword] &= ~blockedBits.blockedMask[dword]; } // 512 ops = 16k bits -> 64 players -> 32k ops