本文使用的是 CounterStrikeSharp 和 CS2Fixes 搭配进行的研究。
用于确定反恐精英2里玩家进出服务器时候的状态。

主要还是因为玩家的状态太迷惑了。
从连接服务器到进入服务器,再到完成 steam 验证,再到退出服务器,再到重新连接服务器。
(玩家退服之后 Controller 实体还在,就很神奇)

合理识别这些玩家状态很重要,因为对状态不正常的玩家进行操作会导致出错甚至崩溃。

注意,下表中的 OnClientAuthorized 的顺序位置仅供参考,因为实际中网络不畅时,玩家验证可能很迟才发生。

情况 Controller Connected UserId PrintToConsole PlayerPawn
第1次进
OnClientConnect
null 不测试 null
第1次进
OnClientConnected
Valid PlayerConnecting 0 OK null
第1次进
OnClientAuthorized
Valid PlayerConnecting 0 OK null
第1次进
OnClientPutInServer
Valid PlayerConnecting 0 OK Valid
第1次进
OnClientPutInServer
之后第1帧
Valid PlayerConnected 0 OK Valid
第1次退
OnClientDisconnect
Valid PlayerConnected 0 执行,但玩家收不到 Valid
第1次退
OnClientDisconnectPost
Valid PlayerDisconnected 0 执行,但玩家收不到 Valid
第1次退
OnClientDisconnectPost
之后第1帧
Valid PlayerDisconnected 65535 执行后服务端崩溃 可能是null
第2次进
OnClientConnect
Valid PlayerDisconnected 0 OK Valid
第2次进
OnClientConnected
Valid PlayerReconnecting 0 OK Valid
第2次进
OnClientAuthorized
Valid PlayerReconnecting 0 OK Valid
第2次进
OnClientPutInServer
Valid PlayerReconnecting 0 OK Valid
第2次进
OnClientPutInServer
之后第1帧
Valid PlayerConnected 0 OK Valid
第2次退
OnClientDisconnect
Valid PlayerConnected 0 执行,但玩家收不到 Valid
第2次退
OnClientDisconnectPost
Valid PlayerDisconnected 0 执行,但玩家收不到 Valid
第2次退
OnClientDisconnectPost
之后第1帧
Valid PlayerDisconnected 65535 执行后服务端崩溃 可能是null

PrintToConsole 的服务端崩溃表现为:

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

   at CounterStrikeSharp.API.Core.Helpers.InvokeNative(IntPtr)
 
   at CounterStrikeSharp.API.Core.ScriptContext.InvokeNativeInternal()
   at CounterStrikeSharp.API.Core.ScriptContext.Invoke()
   at CounterStrikeSharp.API.Core.NativeAPI.PrintToConsole(Int32, System.String)
   at CounterStrikeSharp.API.Core.CCSPlayerController.PrintToConsole(System.String)

总结:

  1. 玩家控制器就算是 .IsValid ,依然不可靠,需要检测 .Connected.UserId
  2. .PrintToConsole 需要特别小心的使用,BOT 玩家和离线玩家使用这个函数都会导致崩服。
  3. OnClientPutInServer 可以在大部分情况下使用,作为玩家进服的检测点,但是里面的玩家状态依然不是 PlayerConnected ,它的下一帧才是。