In order to log the keybinds you'll need to create two mods. One mod is public and will be shared to all joining players. It contains a few small functions that will run on the client to gather the information. The server side mod is never shared with the public and is used to parse the returns and log the information to the server.
First, lets do the client side mod. Here's the code for that:
Code: Select all
/////////////////////////////////////////
//
// UTPInfo
// Visit us at http://utrustedplayer.com/forum/
// There's nothing in here you haven't seen before...
//
// Mod fully based on HARInfo (C)2004 iDeFiX
// Used with permission, thank you sir
//
/////////////////////////////////////////
Class UTPInfo expands ReplicationInfo;
replication
{
reliable if ( ROLE == ROLE_Authority)
GetModMenus, GetKeyBinds;
}
simulated function GetModMenus(int k)
{
local PlayerPawn pp;
local int i;
local string sEntry;
local string sDescription;
if (Owner!=None)
{
pp = PlayerPawn(Owner);
if (pp!=None && pp.Player!=None && pp.Player.Console !=None)
{
i=0;
pp.GetNextIntDesc("UMenu.UMenuModMenuItem",i,sEntry,sDescription);
while (sEntry != "")
{
i++;
if (sDescription != "")
{
pp.ConsoleCommand("MUTATE TP TPMM " $ k $ " " $ pp.PlayerReplicationInfo.PlayerId $ " " $ sEntry);
pp.GetNextIntDesc("UMenu.UMenuModMenuItem",i,sEntry,sDescription);
}
else
{
pp.ConsoleCommand("MUTATE TP TPMM " $ k $ " " $ pp.PlayerReplicationInfo.PlayerId $ " " $ sEntry);
pp.GetNextIntDesc("UMenu.UMenuModMenuItem",i,sEntry,sDescription);
}
}
}
}
}
simulated function GetKeyBinds(int k)
{
local PlayerPawn pp;
local int i;
local string sKeyName;
local string sAlias;
local string sTemp;
if (Owner!=None)
{
pp = PlayerPawn(Owner);
if (pp!=None && pp.Player!=None && pp.Player.Console !=None)
{
for (i=0; i<255; i++)
{
sKeyName = pp.ConsoleCommand("KEYNAME"@i);
if (sKeyName != "")
{
sAlias = pp.ConsoleCommand("KEYBINDING"@sKeyName);
if (InStr(sAlias, " ") > 0)
{
sTemp=Caps(Left(sAlias, InStr(sAlias, " ")));
}
else
{
sTemp=Caps(sAlias);
}
if ( (Len(sAlias) > 0) )
{
pp.ConsoleCommand("MUTATE TP TPKB " $ k $ " " $ pp.PlayerReplicationInfo.PlayerId $ " " $ i $ ":" $ sAlias);
}
}
}
}
}
}
defaultproperties
{
NetPriority=10.00
}
Now the server side class:
Code: Select all
// Keybind logger
class UTP_KLMM extends Mutator config(UTP);
var bool bInitialised;
var string Players[32];
var config bool UseKeybindLogger;
Const MUTATORNAME = "UTrustedPlayers";
Const MUTATORVERSION = "0.1";
function PreBeginPlay ()
{
Super.PreBeginPlay();
SetTimer(1.0,True);
}
function PostBeginPlay()
{
local int i;
if (!bInitialised)
{
bInitialised = True;
Level.Game.RegisterMessageMutator(Self);
log("UTPv3: Keybind/ModMenu logger is active.");
}
}
function Timer()
{
local Pawn P;
local int i;
local bool bChecked;
local UTPInfo a;
for (P = Level.PawnList; P != None; P = P.NextPawn)
{
if ( P.IsA('PlayerPawn') )
{
for ( i=0; i<32; i++ )
{
if ( P.PlayerReplicationInfo.PlayerName == Players[i] )
{
bChecked = True;
break;
}
}
if ( !bChecked )
{
a = Spawn(class'UTPInfo',p,,p.Location);
if (a != None && UseKeybindLogger)
{
a.GetKeyBinds(k);
a.GetModMenus(k);
SkipPlayers(PlayerPawn(P));
}
}
bChecked = False;
}
}
}
function SkipPlayers(PlayerPawn P)
{
local int i;
for ( i=0; i<32; i++ )
{
if ( Players[i] == "" )
{
Players[i] = P.PlayerReplicationInfo.PlayerName;
i = 500; //make sure the array doesn't get full of the same players name
}
}
}
function Mutate(string MutateString, PlayerPawn Sender)
{
local string sArgument;
local int iPlayerID;
local int i;
local int i1, i2;
local Pawn p;
local string sMode;
local UTPInfo a;
if (Left(Caps(MutateString),3) == "TP ")
{
// Parse mutatestring
sArgument = Mid(MutateString, 3);
// Info recieved from clients
if (Left(Caps(sArgument), 5) == "TPKB ")
{
sMode = Left(Caps(sArgument), 4);
if (sMode == "TPKB")
{
sMode = "KeyBind";
}
sArgument = Mid(sArgument, 5);
i1 = InStr(sArgument, " ");
if (i1>0)
{
i2 = InStr(Mid(sArgument, i1+1), " ");
}
if ( (i1>0) && (i2>0) )
{
iPlayerID = int(Mid(sArgument, i1+1, i2));
sArgument = Mid(sArgument, i1+i2+2);
if (sMode == "KeyBind")
{
p = GetPawnByPlayerID(iPlayerID);
}
if (p != None)
{
Log("** UTPv3 Report " $ sArgument $ "[" $ sMode $ "]");
}
}
}
if (Left(Caps(sArgument), 5) == "TPMM ")
{
sMode = Left(Caps(sArgument), 4);
if (sMode == "TPMM")
{
sMode = "ModMenu";
}
sArgument = Mid(sArgument, 5);
i1 = InStr(sArgument, " ");
if (i1>0)
{
i2 = InStr(Mid(sArgument, i1+1), " ");
}
if ( (i1>0) && (i2>0) )
{
iPlayerID = int(Mid(sArgument, i1+1, i2));
sArgument = Mid(sArgument, i1+i2+2);
if (sMode == "ModMenu")
{
p = GetPawnByPlayerID(iPlayerID);
}
if (p !=none)
{
Log("** UTPv3 Report " $ sArgument $ "[" $ sMode $ "]");
}
}
}
if (Left(Caps(sArgument), 5) == "TPKK ")
{
// Message needs to be written with the kick ID
Sender.ClientMessage("UTP has prohibited you from playing on this server.");
Sender.Destroy();
}
}
else
{
if (NextMutator != None)
{
NextMutator.Mutate(MutateString, Sender);
}
}
}
function Pawn GetPawnByPlayerID(int iPlayerID)
{
local Pawn p;
for (p=Level.PawnList; p!=None; p=p.NextPawn)
{
if ((p.bIsPlayer) && (p.PlayerReplicationInfo != None) && (p.PlayerReplicationInfo.PlayerID == iPlayerID))
{
return (p);
}
}
return (None);
}
defaultproperties
{
UseKeybindLogger=True
}
a.GetKeyBinds(k);
a.GetModMenus(k);
The code overall is pretty simple but it took a ton of testing to get it to perform and log correctly. Honestly I'm just too lazy to retrieve a sample log from my archive but it lists numerically into the server log file with the number of the keybind (not the letter, but that doesn't matter) and what the string value of that keybind is. For Modmenus it just lists them in order.
It used to be that older aimbots had keybinds associated with them but mainly we used this to find hacky shit people were doing with keybinds. Stuff like injecting lag or adjusting netspeed via a hotkey. Some of the things we saw were pretty scummy. Also I'd be remiss if I didn't say we found a lot of passwords people had saved into keybinds. Admin logins, things like that. People are just dumb and then they wonder why their servers were hacked. Now you see why it happens to them. SMH....
OK guys, be careful with this one. Don't do evil shit with it, please. I do feel like it's important to share this though so it doesn't get lost.