diff --git a/managed/CounterStrikeSharp.API/Core/API.cs b/managed/CounterStrikeSharp.API/Core/API.cs
index e0320288b..40785f520 100644
--- a/managed/CounterStrikeSharp.API/Core/API.cs
+++ b/managed/CounterStrikeSharp.API/Core/API.cs
@@ -560,6 +560,17 @@ public static void PrintToServerConsole(string msg){
}
}
+ public static void DisconnectClient(int slot, int reason){
+ lock (ScriptContext.GlobalScriptContext.Lock) {
+ ScriptContext.GlobalScriptContext.Reset();
+ ScriptContext.GlobalScriptContext.Push(slot);
+ ScriptContext.GlobalScriptContext.Push(reason);
+ ScriptContext.GlobalScriptContext.SetIdentifier(0x799EE9C3);
+ ScriptContext.GlobalScriptContext.Invoke();
+ ScriptContext.GlobalScriptContext.CheckErrors();
+ }
+ }
+
public static IntPtr GetEntityFromIndex(int index){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
diff --git a/managed/CounterStrikeSharp.API/Core/Model/CCSPlayerController.cs b/managed/CounterStrikeSharp.API/Core/Model/CCSPlayerController.cs
index 6967662aa..76700911a 100644
--- a/managed/CounterStrikeSharp.API/Core/Model/CCSPlayerController.cs
+++ b/managed/CounterStrikeSharp.API/Core/Model/CCSPlayerController.cs
@@ -1,10 +1,10 @@
using System;
-
using CounterStrikeSharp.API.Modules.Cvars;
using CounterStrikeSharp.API.Modules.Entities;
using CounterStrikeSharp.API.Modules.Entities.Constants;
using CounterStrikeSharp.API.Modules.Memory;
using CounterStrikeSharp.API.Modules.Utils;
+using CounterStrikeSharp.API.ValveConstants.Protobuf;
namespace CounterStrikeSharp.API.Core;
@@ -241,6 +241,15 @@ public void ExecuteClientCommand(string command)
NativeAPI.IssueClientCommand(Slot, command);
}
+ ///
+ /// Disconnects a player from the server with the specified reason.
+ ///
+ ///
+ public void Disconnect(NetworkDisconnectionReason reason)
+ {
+ NativeAPI.DisconnectClient(Slot, (int)reason);
+ }
+
///
/// Issue the specified command directly from the server (mimics the server executing the command with the given player context).
/// Works with server commands like `kill`, `explode`, `noclip`, etc.
diff --git a/managed/CounterStrikeSharp.API/ValveConstants/Protobuf/NetworkDisconnectionReason.cs b/managed/CounterStrikeSharp.API/ValveConstants/Protobuf/NetworkDisconnectionReason.cs
new file mode 100644
index 000000000..d75261329
--- /dev/null
+++ b/managed/CounterStrikeSharp.API/ValveConstants/Protobuf/NetworkDisconnectionReason.cs
@@ -0,0 +1,126 @@
+namespace CounterStrikeSharp.API.ValveConstants.Protobuf;
+
+///
+/// Enum derived from `network_connection.proto`
+///
+public enum NetworkDisconnectionReason
+{
+ NETWORK_DISCONNECT_INVALID = 0,
+ NETWORK_DISCONNECT_SHUTDOWN = 1,
+ NETWORK_DISCONNECT_DISCONNECT_BY_USER = 2,
+ NETWORK_DISCONNECT_DISCONNECT_BY_SERVER = 3,
+ NETWORK_DISCONNECT_LOST = 4,
+ NETWORK_DISCONNECT_OVERFLOW = 5,
+ NETWORK_DISCONNECT_STEAM_BANNED = 6,
+ NETWORK_DISCONNECT_STEAM_INUSE = 7,
+ NETWORK_DISCONNECT_STEAM_TICKET = 8,
+ NETWORK_DISCONNECT_STEAM_LOGON = 9,
+ NETWORK_DISCONNECT_STEAM_AUTHCANCELLED = 10,
+ NETWORK_DISCONNECT_STEAM_AUTHALREADYUSED = 11,
+ NETWORK_DISCONNECT_STEAM_AUTHINVALID = 12,
+ NETWORK_DISCONNECT_STEAM_VACBANSTATE = 13,
+ NETWORK_DISCONNECT_STEAM_LOGGED_IN_ELSEWHERE = 14,
+ NETWORK_DISCONNECT_STEAM_VAC_CHECK_TIMEDOUT = 15,
+ NETWORK_DISCONNECT_STEAM_DROPPED = 16,
+ NETWORK_DISCONNECT_STEAM_OWNERSHIP = 17,
+ NETWORK_DISCONNECT_SERVERINFO_OVERFLOW = 18,
+ NETWORK_DISCONNECT_TICKMSG_OVERFLOW = 19,
+ NETWORK_DISCONNECT_STRINGTABLEMSG_OVERFLOW = 20,
+ NETWORK_DISCONNECT_DELTAENTMSG_OVERFLOW = 21,
+ NETWORK_DISCONNECT_TEMPENTMSG_OVERFLOW = 22,
+ NETWORK_DISCONNECT_SOUNDSMSG_OVERFLOW = 23,
+ NETWORK_DISCONNECT_SNAPSHOTOVERFLOW = 24,
+ NETWORK_DISCONNECT_SNAPSHOTERROR = 25,
+ NETWORK_DISCONNECT_RELIABLEOVERFLOW = 26,
+ NETWORK_DISCONNECT_BADDELTATICK = 27,
+ NETWORK_DISCONNECT_NOMORESPLITS = 28,
+ NETWORK_DISCONNECT_TIMEDOUT = 29,
+ NETWORK_DISCONNECT_DISCONNECTED = 30,
+ NETWORK_DISCONNECT_LEAVINGSPLIT = 31,
+ NETWORK_DISCONNECT_DIFFERENTCLASSTABLES = 32,
+ NETWORK_DISCONNECT_BADRELAYPASSWORD = 33,
+ NETWORK_DISCONNECT_BADSPECTATORPASSWORD = 34,
+ NETWORK_DISCONNECT_HLTVRESTRICTED = 35,
+ NETWORK_DISCONNECT_NOSPECTATORS = 36,
+ NETWORK_DISCONNECT_HLTVUNAVAILABLE = 37,
+ NETWORK_DISCONNECT_HLTVSTOP = 38,
+ NETWORK_DISCONNECT_KICKED = 39,
+ NETWORK_DISCONNECT_BANADDED = 40,
+ NETWORK_DISCONNECT_KICKBANADDED = 41,
+ NETWORK_DISCONNECT_HLTVDIRECT = 42,
+ NETWORK_DISCONNECT_PURESERVER_CLIENTEXTRA = 43,
+ NETWORK_DISCONNECT_PURESERVER_MISMATCH = 44,
+ NETWORK_DISCONNECT_USERCMD = 45,
+ NETWORK_DISCONNECT_REJECTED_BY_GAME = 46,
+ NETWORK_DISCONNECT_MESSAGE_PARSE_ERROR = 47,
+ NETWORK_DISCONNECT_INVALID_MESSAGE_ERROR = 48,
+ NETWORK_DISCONNECT_BAD_SERVER_PASSWORD = 49,
+ NETWORK_DISCONNECT_DIRECT_CONNECT_RESERVATION = 50,
+ NETWORK_DISCONNECT_CONNECTION_FAILURE = 51,
+ NETWORK_DISCONNECT_NO_PEER_GROUP_HANDLERS = 52,
+ NETWORK_DISCONNECT_RECONNECTION = 53,
+ NETWORK_DISCONNECT_LOOPSHUTDOWN = 54,
+ NETWORK_DISCONNECT_LOOPDEACTIVATE = 55,
+ NETWORK_DISCONNECT_HOST_ENDGAME = 56,
+ NETWORK_DISCONNECT_LOOP_LEVELLOAD_ACTIVATE = 57,
+ NETWORK_DISCONNECT_CREATE_SERVER_FAILED = 58,
+ NETWORK_DISCONNECT_EXITING = 59,
+ NETWORK_DISCONNECT_REQUEST_HOSTSTATE_IDLE = 60,
+ NETWORK_DISCONNECT_REQUEST_HOSTSTATE_HLTVRELAY = 61,
+ NETWORK_DISCONNECT_CLIENT_CONSISTENCY_FAIL = 62,
+ NETWORK_DISCONNECT_CLIENT_UNABLE_TO_CRC_MAP = 63,
+ NETWORK_DISCONNECT_CLIENT_NO_MAP = 64,
+ NETWORK_DISCONNECT_CLIENT_DIFFERENT_MAP = 65,
+ NETWORK_DISCONNECT_SERVER_REQUIRES_STEAM = 66,
+ NETWORK_DISCONNECT_STEAM_DENY_MISC = 67,
+ NETWORK_DISCONNECT_STEAM_DENY_BAD_ANTI_CHEAT = 68,
+ NETWORK_DISCONNECT_SERVER_SHUTDOWN = 69,
+ NETWORK_DISCONNECT_REPLAY_INCOMPATIBLE = 71,
+ NETWORK_DISCONNECT_CONNECT_REQUEST_TIMEDOUT = 72,
+ NETWORK_DISCONNECT_SERVER_INCOMPATIBLE = 73,
+ NETWORK_DISCONNECT_LOCALPROBLEM_MANYRELAYS = 74,
+ NETWORK_DISCONNECT_LOCALPROBLEM_HOSTEDSERVERPRIMARYRELAY = 75,
+ NETWORK_DISCONNECT_LOCALPROBLEM_NETWORKCONFIG = 76,
+ NETWORK_DISCONNECT_LOCALPROBLEM_OTHER = 77,
+ NETWORK_DISCONNECT_REMOTE_TIMEOUT = 79,
+ NETWORK_DISCONNECT_REMOTE_TIMEOUT_CONNECTING = 80,
+ NETWORK_DISCONNECT_REMOTE_OTHER = 81,
+ NETWORK_DISCONNECT_REMOTE_BADCRYPT = 82,
+ NETWORK_DISCONNECT_REMOTE_CERTNOTTRUSTED = 83,
+ NETWORK_DISCONNECT_UNUSUAL = 84,
+ NETWORK_DISCONNECT_INTERNAL_ERROR = 85,
+ NETWORK_DISCONNECT_REJECT_BADCHALLENGE = 128,
+ NETWORK_DISCONNECT_REJECT_NOLOBBY = 129,
+ NETWORK_DISCONNECT_REJECT_BACKGROUND_MAP = 130,
+ NETWORK_DISCONNECT_REJECT_SINGLE_PLAYER = 131,
+ NETWORK_DISCONNECT_REJECT_HIDDEN_GAME = 132,
+ NETWORK_DISCONNECT_REJECT_LANRESTRICT = 133,
+ NETWORK_DISCONNECT_REJECT_BADPASSWORD = 134,
+ NETWORK_DISCONNECT_REJECT_SERVERFULL = 135,
+ NETWORK_DISCONNECT_REJECT_INVALIDRESERVATION = 136,
+ NETWORK_DISCONNECT_REJECT_FAILEDCHANNEL = 137,
+ NETWORK_DISCONNECT_REJECT_CONNECT_FROM_LOBBY = 138,
+ NETWORK_DISCONNECT_REJECT_RESERVED_FOR_LOBBY = 139,
+ NETWORK_DISCONNECT_REJECT_INVALIDKEYLENGTH = 140,
+ NETWORK_DISCONNECT_REJECT_OLDPROTOCOL = 141,
+ NETWORK_DISCONNECT_REJECT_NEWPROTOCOL = 142,
+ NETWORK_DISCONNECT_REJECT_INVALIDCONNECTION = 143,
+ NETWORK_DISCONNECT_REJECT_INVALIDCERTLEN = 144,
+ NETWORK_DISCONNECT_REJECT_INVALIDSTEAMCERTLEN = 145,
+ NETWORK_DISCONNECT_REJECT_STEAM = 146,
+ NETWORK_DISCONNECT_REJECT_SERVERAUTHDISABLED = 147,
+ NETWORK_DISCONNECT_REJECT_SERVERCDKEYAUTHINVALID = 148,
+ NETWORK_DISCONNECT_REJECT_BANNED = 149,
+ NETWORK_DISCONNECT_KICKED_TEAMKILLING = 150,
+ NETWORK_DISCONNECT_KICKED_TK_START = 151,
+ NETWORK_DISCONNECT_KICKED_UNTRUSTEDACCOUNT = 152,
+ NETWORK_DISCONNECT_KICKED_CONVICTEDACCOUNT = 153,
+ NETWORK_DISCONNECT_KICKED_COMPETITIVECOOLDOWN = 154,
+ NETWORK_DISCONNECT_KICKED_TEAMHURTING = 155,
+ NETWORK_DISCONNECT_KICKED_HOSTAGEKILLING = 156,
+ NETWORK_DISCONNECT_KICKED_VOTEDOFF = 157,
+ NETWORK_DISCONNECT_KICKED_IDLE = 158,
+ NETWORK_DISCONNECT_KICKED_SUICIDE = 159,
+ NETWORK_DISCONNECT_KICKED_NOSTEAMLOGIN = 160,
+ NETWORK_DISCONNECT_KICKED_NOSTEAMTICKET = 161
+}
diff --git a/src/scripting/natives/natives_engine.cpp b/src/scripting/natives/natives_engine.cpp
index 488425cd7..04b250d69 100644
--- a/src/scripting/natives/natives_engine.cpp
+++ b/src/scripting/natives/natives_engine.cpp
@@ -224,6 +224,20 @@ void PrintToServerConsole(ScriptContext& scriptContext)
META_CONPRINT(message);
}
+void DisconnectClient(ScriptContext& scriptContext)
+{
+ auto slot = scriptContext.GetArgument(0);
+ auto disconnectReason = scriptContext.GetArgument(1);
+
+ if (!ENetworkDisconnectionReason_IsValid(disconnectReason))
+ {
+ scriptContext.ThrowNativeError("Invalid disconnect reason");
+ return;
+ }
+
+ globals::engineServer2->DisconnectClient(slot, disconnectReason);
+}
+
REGISTER_NATIVES(engine, {
ScriptEngine::RegisterNativeHandler("GET_GAME_DIRECTORY", GetGameDirectory);
ScriptEngine::RegisterNativeHandler("GET_MAP_NAME", GetMapName);
@@ -248,5 +262,6 @@ REGISTER_NATIVES(engine, {
ScriptEngine::RegisterNativeHandler("GET_VALVE_INTERFACE", GetValveInterface);
ScriptEngine::RegisterNativeHandler("GET_COMMAND_PARAM_VALUE", GetCommandParamValue);
ScriptEngine::RegisterNativeHandler("PRINT_TO_SERVER_CONSOLE", PrintToServerConsole);
+ ScriptEngine::RegisterNativeHandler("DISCONNECT_CLIENT", DisconnectClient);
})
} // namespace counterstrikesharp
diff --git a/src/scripting/natives/natives_engine.yaml b/src/scripting/natives/natives_engine.yaml
index dcc6ac22b..1718a69e1 100644
--- a/src/scripting/natives/natives_engine.yaml
+++ b/src/scripting/natives/natives_engine.yaml
@@ -25,4 +25,5 @@ QUEUE_TASK_FOR_FRAME: tick:int, callback:func -> void
QUEUE_TASK_FOR_NEXT_WORLD_UPDATE: callback:func -> void
GET_VALVE_INTERFACE: interfaceType:int, interfaceName:string -> pointer
GET_COMMAND_PARAM_VALUE: param:string, dataType:DataType_t, defaultValue:any -> any
-PRINT_TO_SERVER_CONSOLE: msg:string -> void
\ No newline at end of file
+PRINT_TO_SERVER_CONSOLE: msg:string -> void
+DISCONNECT_CLIENT: slot:int, reason:int -> void