Verify private relative mouse input against native player camera
This commit is contained in:
@@ -262,6 +262,7 @@ class ERR_OrdinaryInputObserver : Managed
|
||||
if (m_CaptureSuffix == "baseline" && !ERR_OrdinaryInputObserverRules.Stationary(forward, input, velocity, vector.Distance(origin, m_BaselineOrigin))) CancelCapture();
|
||||
m_Samples++;
|
||||
PrintFormat("ERR INPUT OBSERVE: run=%1 sample=%2 real=%3 world=%4 SAMPLE origin=%5 forward=%6 input=%7 velocity=%8 inventory=%9", m_Nonce, m_Samples, now, m_LastWorldTime, origin, forward, input, velocity, open);
|
||||
ERR_OrdinaryLookObserver.Sample(m_Mode, m_World, m_Controller, m_Actor, m_Nonce, m_Start, m_Samples, now);
|
||||
Observe(now, origin, forward, input, velocity, open);
|
||||
if (m_Opened && !m_Closed && menu) m_Menu = menu;
|
||||
m_Previous = now;
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
#ifndef WORKBENCH
|
||||
// Explicit native camera telemetry only. The existing input observer supplies
|
||||
// the schedule and original lifetime; this utility owns no callbacks or inputs.
|
||||
class ERR_OrdinaryLookObserver
|
||||
{
|
||||
protected static ref ERR_OrdinaryLookObserver s_Request;
|
||||
protected static bool s_Attempted;
|
||||
protected ERR_GameMode m_Mode;
|
||||
protected BaseWorld m_World;
|
||||
protected PlayerController m_Controller;
|
||||
protected IEntity m_Actor;
|
||||
protected PlayerCamera m_Camera;
|
||||
protected ERR_PlayerLife m_Life;
|
||||
protected UUID m_Account;
|
||||
protected string m_Nonce;
|
||||
protected int m_Start;
|
||||
protected int m_Previous;
|
||||
protected int m_Index;
|
||||
protected bool m_Stopped;
|
||||
|
||||
protected static bool Enabled(string nonce)
|
||||
{
|
||||
string look, input, scenario;
|
||||
return !System.IsConsoleApp() && Replication.IsServer() && RplSession.Mode() == RplMode.None
|
||||
&& ERR_OrdinaryInputObserverRules.Nonce(nonce)
|
||||
&& System.GetCLIParam("errOrdinaryLookObserve", look) && look == nonce
|
||||
&& System.GetCLIParam("errOrdinaryInputObserve", input) && input == nonce
|
||||
&& System.GetCLIParam("errOrdinaryScenario", scenario) && (scenario == "core" || scenario == "chat");
|
||||
}
|
||||
|
||||
static void Sample(ERR_GameMode mode, BaseWorld world, PlayerController controller, IEntity actor, string nonce, int started, int index, int now)
|
||||
{
|
||||
if (!Enabled(nonce))
|
||||
{
|
||||
if (s_Request) s_Request.Cancel(index, now, "explicit-scope-lost");
|
||||
return;
|
||||
}
|
||||
if (!s_Attempted)
|
||||
{
|
||||
s_Attempted = true;
|
||||
s_Request = new ERR_OrdinaryLookObserver();
|
||||
s_Request.m_Mode = mode; s_Request.m_World = world;
|
||||
s_Request.m_Controller = controller; s_Request.m_Actor = actor;
|
||||
s_Request.m_Nonce = nonce; s_Request.m_Start = started; s_Request.m_Previous = started;
|
||||
if (controller) s_Request.m_Camera = controller.GetPlayerCamera();
|
||||
if (mode && mode.Players()) s_Request.m_Life = mode.Players().CurrentActor(actor);
|
||||
if (s_Request.m_Life) s_Request.m_Account = s_Request.m_Life.AccountId;
|
||||
}
|
||||
s_Request.Observe(mode, world, controller, actor, nonce, started, index, now);
|
||||
}
|
||||
|
||||
protected void Cancel(int index, int now, string reason)
|
||||
{
|
||||
if (m_Stopped) return;
|
||||
m_Stopped = true;
|
||||
PrintFormat("ERR LOOK OBSERVE: run=%1 sample=%2 real=%3 CANCELLED %4", m_Nonce, index, now, reason);
|
||||
m_Mode = null; m_World = null; m_Controller = null; m_Actor = null; m_Camera = null; m_Life = null;
|
||||
}
|
||||
|
||||
protected bool Context()
|
||||
{
|
||||
if (!GetGame() || !m_Mode || !m_World || !m_Controller || !m_Actor || !m_Camera || !m_Life) return false;
|
||||
if (m_Mode != ERR_GameMode.Get() || !m_Mode.Active() || m_Mode.Phase() != ERR_Phase.PRISON) return false;
|
||||
if (GetGame().GetWorld() != m_World || m_Mode.GetWorld() != m_World || m_Actor.GetWorld() != m_World || m_Camera.GetWorld() != m_World) return false;
|
||||
if (GetGame().GetPlayerController() != m_Controller || m_Controller.GetControlledEntity() != m_Actor || m_Controller.GetPlayerCamera() != m_Camera) return false;
|
||||
PlayerManager manager = GetGame().GetPlayerManager();
|
||||
int connection = m_Controller.GetPlayerId();
|
||||
if (!manager || connection <= 0 || manager.GetPlayerController(connection) != m_Controller || manager.GetPlayerControlledEntity(connection) != m_Actor) return false;
|
||||
if (!m_Mode.Players() || m_Mode.Players().CurrentActor(m_Actor) != m_Life || m_Life.AccountId != m_Account || !ERR_Actors.CanFight(m_Actor)) return false;
|
||||
CameraManager cameras = GetGame().GetCameraManager();
|
||||
if (!cameras || cameras.CurrentCamera() != m_Camera) return false;
|
||||
if (!GetGame().GetInputManager() || !GetGame().GetMenuManager() || GetGame().GetMenuManager().GetTopMenu()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static bool FiniteVector(vector value)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
if (!(value[i] >= -10000000 && value[i] <= 10000000)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void Observe(ERR_GameMode mode, BaseWorld world, PlayerController controller, IEntity actor, string nonce, int started, int index, int now)
|
||||
{
|
||||
if (m_Stopped) return;
|
||||
if (mode != m_Mode || world != m_World || controller != m_Controller || actor != m_Actor || nonce != m_Nonce || started != m_Start)
|
||||
{ Cancel(index, now, "original-binding-changed"); return; }
|
||||
if (index != m_Index + 1 || index > 450 || now < m_Previous || now < m_Start || now - m_Start >= 45000)
|
||||
{ Cancel(index, now, "sample-or-clock-bound"); return; }
|
||||
if (GetGame() && GetGame().GetMenuManager() && GetGame().GetMenuManager().GetTopMenu())
|
||||
{ Cancel(index, now, "menu-opened"); return; }
|
||||
if (!Context()) { Cancel(index, now, "native-camera-or-player-context-lost"); return; }
|
||||
vector view[4], body[4];
|
||||
m_Camera.GetWorldCameraTransform(view);
|
||||
m_Actor.GetTransform(body);
|
||||
vector direction = view[2];
|
||||
vector facing = body[2];
|
||||
float viewLength = direction.Length();
|
||||
float bodyLength = facing.Length();
|
||||
float right = GetGame().GetInputManager().GetActionValue("CharacterTurnRight");
|
||||
float up = GetGame().GetInputManager().GetActionValue("CharacterTurnUp");
|
||||
vector turn = Vector(right, up, 0);
|
||||
if (!FiniteVector(view[3]) || !FiniteVector(body[3]) || !FiniteVector(direction) || !FiniteVector(facing) || !FiniteVector(turn) || !(viewLength >= 0.5 && viewLength <= 2) || !(bodyLength >= 0.5 && bodyLength <= 2))
|
||||
{ Cancel(index, now, "invalid-native-pose"); return; }
|
||||
direction = direction / viewLength;
|
||||
facing = facing / bodyLength;
|
||||
// Recheck the exact active camera/context after all native reads.
|
||||
if (!Context()) { Cancel(index, now, "native-camera-or-player-context-lost"); return; }
|
||||
if (m_Index == 0)
|
||||
PrintFormat("ERR LOOK OBSERVE: run=%1 sample=%2 real=%3 BASIS native-player-camera-world-transform", m_Nonce, index, now);
|
||||
PrintFormat("ERR LOOK OBSERVE: run=%1 sample=%2 real=%3 SAMPLE direction=%4 camera=%5 body=%6 bodyForward=%7 turn=%8", m_Nonce, index, now, direction, view[3], body[3], facing, turn);
|
||||
m_Index = index; m_Previous = now;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user