winstxnhdw / lc-hax

A powerful, feature-rich and highly performant internal cheat for the co-op indie horror video game, Lethal Company.
77 stars 25 forks source link

[Bug]: AntiKickPatch Not Calling SendNewPlayerValuesClientRpc #449

Closed D1GQ closed 3 months ago

D1GQ commented 3 months ago

Problem

Hey I've been trying to find a way to spoof players names and steam IDs, slowly bringing my head against the wall, and I noticed an issue in the AntiKick, because you're returning SendNewPlayerValuesServerRpc as false, you are preventing the RPC to start SendNewPlayerValuesClientRpc, don't know if that's intentional or not, here is a fix

Screenshot 2024-03-04 225445

Fix

AntiKickPatch.cs

#pragma warning disable IDE1006

using GameNetcodeStuff;
using HarmonyLib;
using Hax;
using Steamworks;
using System.Reflection;

[HarmonyPatch(typeof(PlayerControllerB))]
class AntiKickPatch {
    [HarmonyPatch("SendNewPlayerValuesServerRpc")]
    static bool Prefix(PlayerControllerB __instance) {
        if (!Setting.EnableAntiKick) return true;
        MethodInfo SendNewPlayerValuesClientRpcMethod = typeof(PlayerControllerB).GetMethod("SendNewPlayerValuesClientRpc", BindingFlags.NonPublic | BindingFlags.Instance);

        Helper.GameNetworkManager?.currentLobby?.Members.ForEach((i, member) => {
            if (Helper.LocalPlayer?.playerSteamId == member.Id.Value) return;

            PlayerControllerB player = __instance.playersManager.allPlayerScripts[i];
            player.playerSteamId = member.Id.Value;
            player.playerUsername = member.Name;
            player.usernameBillboardText.text = member.Name;
            __instance.playersManager.mapScreen.radarTargets[i].name = player.playerUsername;
            __instance.quickMenuManager.AddUserToPlayerList(player.playerSteamId, player.playerUsername, i);
        });

        SendNewPlayerValuesClientRpcMethod.Invoke(__instance, new object[] {});

        return false;
    }

    [HarmonyPatch("SendNewPlayerValuesClientRpc")]
    static void Postfix(PlayerControllerB __instance) {
        if (!Setting.EnableAntiKick) return;
        if (Helper.LocalPlayer is not PlayerControllerB localPlayer) return;

        localPlayer.playerSteamId = SteamClient.SteamId;
        localPlayer.playerUsername = SteamClient.Name;
        localPlayer.usernameBillboardText.text = SteamClient.Name;
        __instance.playersManager.mapScreen.radarTargets[localPlayer.PlayerIndex()].name = localPlayer.playerUsername;
        __instance.quickMenuManager.AddUserToPlayerList(localPlayer.playerSteamId, localPlayer.playerUsername, localPlayer.PlayerIndex());
    }
}
winstxnhdw commented 3 months ago

It’s gonna sound crazy but SendNewPlayerValuesClientRpc cannot be called from the client. It can only be called when the host calls your client RPC.

D1GQ commented 3 months ago

Why???

winstxnhdw commented 3 months ago

So I was surprised too but if you read SendNewPlayerValuesClientRpc, there's a line here.

if (__rpc_exec_stage != __RpcExecStage.Client || (!networkManager.IsClient && !networkManager.IsHost))
{
    return;
}

Basically, this checks if the method is called from the client or the host. In this case, if it is called from the client, it returns.

D1GQ commented 3 months ago

If we really wanted to we could patch that out but it's really not necessary.

winstxnhdw commented 3 months ago

Yeap, which is why rather than patching it out, I just brought over what was necessary.

Helper.GameNetworkManager?.currentLobby?.Members.ForEach((i, member) => {
    if (Helper.LocalPlayer?.playerSteamId == member.Id.Value) return;

    PlayerControllerB player = __instance.playersManager.allPlayerScripts[i];
    player.playerSteamId = member.Id.Value;
    player.playerUsername = member.Name;
    player.usernameBillboardText.text = member.Name;
    __instance.playersManager.mapScreen.radarTargets[i].name = player.playerUsername;
    __instance.quickMenuManager.AddUserToPlayerList(player.playerSteamId, player.playerUsername, i);
});

return false;
winstxnhdw commented 3 months ago

So is this still an issue? Can we close this?

D1GQ commented 3 months ago

Yeah we can