Skip to content

Commit

Permalink
fix(skymp5-client): partially fix animation exploit (skyrim-multiplay…
Browse files Browse the repository at this point in the history
  • Loading branch information
Pospelove authored Sep 28, 2024
1 parent ae8d2bf commit bd31a54
Showing 1 changed file with 40 additions and 0 deletions.
40 changes: 40 additions & 0 deletions skymp5-client/src/services/services/animDebugService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ButtonEvent, CameraStateChangedEvent, DxScanCode, Menu } from "skyrimPl

const playerId = 0x14;

// TODO: split into two separate services: AnimDebugService and <you name it: a service for 3rd person camera enforcement in anims>
export class AnimDebugService extends ClientListener {
constructor(private sp: Sp, private controller: CombinedController) {
super();
Expand Down Expand Up @@ -59,6 +60,7 @@ export class AnimDebugService extends ClientListener {
this.sp.Game.forceThirdPerson();
this.sp.Game.disablePlayerControls(true, false, true, false, false, false, false, false, 0);
this.needsExitingAnim = true;
this.startAntiExploitPolling();
});
}

Expand Down Expand Up @@ -113,6 +115,7 @@ export class AnimDebugService extends ClientListener {
this.sp.Debug.sendAnimationEvent(this.sp.Game.getPlayer(), this.settings.animKeys![e.code]);

this.needsExitingAnim = true;
this.startAntiExploitPolling("no_death");
}

logTrace(this, `Sent animation event: ${this.settings.animKeys![e.code]}`);
Expand All @@ -132,6 +135,43 @@ export class AnimDebugService extends ClientListener {
});
}

private startAntiExploitPolling(mode: "no_death" | "death" = "death") {
// Fixes https://github.com/skyrim-multiplayer/skymp5-gamemode/issues/240
// P.S. There is a very similar code in skymp5-gamemode
// See disableCheats.ts, skymp5-gamemode for comments

let _callNative = this.sp.callNative;
let cameraState = -1;
let needsExitingAnim = false;

let f = (i: number): void => {
if (i >= 10 * 60) {
return;
}

cameraState = _callNative("Game", "getCameraState", undefined) as number;

needsExitingAnim = this.needsExitingAnim;

if (!needsExitingAnim) {
return f(Infinity);
}

if (cameraState === 0) { // 1-st person
_callNative("Game", "forceThirdPerson", undefined);
this.exitAnim();
if (mode === "death") {
this.sp.Game.getPlayer()?.damageActorValue("Health", 10000);
}
return f(Infinity);
}

this.controller.once("update", () => f(i + 1));
}

f(0);
}

private queue?: AnimQueueCollection;
private settings?: AnimDebugSettings;

Expand Down

0 comments on commit bd31a54

Please sign in to comment.