PDA

View Full Version : SMAC Anti Wall hack



Ice1
26th October 2012, 15:45
Regarding the anti-wall hack smac has... I was looking through the code and a few descriptions of how it works and I believe it may be possible to simply disable the checking if you are the hidden, so the aura would work correctly. I'm still looking through, preferably you would not be checking the hidden client each tick thereby saving 11% CPU usage on a full server. Will have some time to check it out on sunday but I invite others who know sourcepawn to have a crack at it too as I think this would tackle cheating quite well. :D The major thing is this plugin has probably never been used on hidden so we have to make sure It doesn't have any negative impacts on the game and that it works correctly with the above change.

Paegus
26th October 2012, 15:58
I'll take a look at it this weekend if I have any time left after fixing the visibility plugin...

I think you're right about just disabling it on Hidden players being a functional solution. Though form reading through some of the threads there are sometimes issues where players will pop into existence after coming into view... There is also a significant CPU usage increase when using plugins like this that do large amounts of work per-frame. Especially when your framerate is ~500.

Ice1
26th October 2012, 16:01
Yes I realize that it may be impractical due to the CPU usage etc, but even if there is a split second where you wont see the hidden as he comes around the corner, its not like counter strike where he will just hs you just as you see him. It wouldnt be ideal, but it may be reasonable. Anyway I just found this function

Wallhack_UpdateClientCache(client)
{
g_iTeam[client] = GetClientTeam(client);
g_bIsObserver[client] = IsClientObserver(client);
g_bIsFake[client] = IsFakeClient(client);
g_bProcess[client] = IsPlayerAlive(client);

// Clients that should not be tested for visibility.
g_bIgnore[client] = g_bIsFake[client] || ((g_Game == Game_L4D || g_Game == Game_L4D2) && g_iTeam[client] != 2);
}

Perhaps in here we could simply ignore the entire IRIS team? Still trying to wrap my head around what is called up where in this plugin though.

EDIT
Preferably we would only be checking for the hidden entity on each tick and not trying to use a bool or exceptions on that tick, so it might have to change a bit

Paegus
26th October 2012, 16:21
This is true. limiting it to iris vs hidden only would certainly help kill a lot of overhead and sort the visually jarring pop-in effect. Though we'd want to see how bad it is in the first place. If really bad then it might scew things a bit I think.

Will need to edit two sections. The bit you posted and the deeper part to ignore teammates... unless it already does that which would make a ton of sense in general use I think, so it probably does already.

All this aside, my server refuses to load the required sdkhooks or w/e the wallhack module requires. I haven't found a working version. It may an outdated engine issue. Or I'm a moron. I'd rather the latter.

e: on checking the source code it does already ignore team-on-team so i guess the only change required is


//...
Wallhack_UpdateClientCache(client)
{
g_iTeam[client] = GetClientTeam(client);
g_bIsObserver[client] = IsClientObserver(client);
g_bIsFake[client] = IsFakeClient(client);
g_bProcess[client] = IsPlayerAlive(client);

// Clients that should not be tested for visibility.
g_bIgnore[client] = g_bIsFake[client] || ((g_Game == Game_L4D || g_Game == Game_L4D2 || g_Game == Game_HIDDEN) && g_iTeam[client] != 2)
}
//...

buggered if i can get sdkhooks to load though :(

Ice1
28th October 2012, 10:29
Please see my tutorial on fixing sdk hooks

Managed to get it working but the hidden model randomly dissapears when it shouldn't. Tried playing around with some settings and stuff but I couldn't get it to behave properly. Could someone (Paegus? :D) else please give it a try? BTW a good way i found of testing was to turn the server cheats on and use mat_wireframe 1.

Ice1
28th October 2012, 14:59
I was playing around with these

if (IsInFieldOfView(g_vEyePos[client], g_vEyeAngles[client], g_vAbsCentre[entity]))
{
// Check if centre is visible.
if (IsPointVisible(g_vEyePos[client], g_vAbsCentre[entity]))
return true;

// Check if weapon tip is visible.
if (IsFwdVecVisible(g_vEyePos[client], g_vEyeAngles[entity], g_vEyePos[entity]))
return true;

// Check outer 4 corners of player.
if (IsRectangleVisible(g_vEyePos[client], g_vAbsCentre[entity], g_vMins[entity], g_vMaxs[entity], 1.30))
return true;

// Check inner 4 corners of player.
if (IsRectangleVisible(g_vEyePos[client], g_vAbsCentre[entity], g_vMins[entity], g_vMaxs[entity], 0.65))
return true;
}

But didnt get desired results... Worth a try if yous want to have a go though

Paegus
28th October 2012, 15:34
It's simply if you are are north of the hidden model in the map coordinate system, he disappears, even if he's in plain view. By north I mean if you setang 0 0 0 in your client's console, you're facing 'north'. You can see this happening as you orbit him. As your position on the map's x-axis becomes higher than his, he vanishes. He reappears (so to speak) when you move south of him again and your x-axis coordinate is lower again.

I'll have a look at what trace code i can find, but i think the function i'll be looking for is embedded somewhere in the SDKHooks extension...

Paegus
28th October 2012, 16:00
it doesn't work even if you bypass that whole section with...

if (IsInFieldOfView(g_vEyePos[client], g_vEyeAngles[client], g_vAbsCentre[entity]))
{
return true;

// Check if centre is visible.
if (IsPointVisible(g_vEyePos[client], g_vAbsCentre[entity]))
return true;

// Check if weapon tip is visible.
if (IsFwdVecVisible(g_vEyePos[client], g_vEyeAngles[entity], g_vEyePos[entity]))
return true;

// Check outer 4 corners of player.
if (IsRectangleVisible(g_vEyePos[client], g_vAbsCentre[entity], g_vMins[entity], g_vMaxs[entity], 1.30))
return true;

// Check inner 4 corners of player.
if (IsRectangleVisible(g_vEyePos[client], g_vAbsCentre[entity], g_vMins[entity], g_vMaxs[entity], 0.65))
return true;
}


...so it'll be something either in...


bool:IsInFieldOfView(const Float:start[3], const Float:angles[3], const Float:end[3])
{
decl Float:normal[3], Float:plane[3];

GetAngleVectors(angles, normal, NULL_VECTOR, NULL_VECTOR);
SubtractVectors(end, start, plane);
NormalizeVector(plane, plane);

return GetVectorDotProduct(plane, normal) > 0.0; // Cosine(Deg2Rad(179.9 / 2.0))
}

...or in the data passed to it.

Wouldn't you know it, i fucking hate geometry!

Paegus
28th October 2012, 16:19
Ok so the reason is that the player's eye-angles aren't being updated by the aptly named function OnPlayerRunCmd because it simply never runs.

I recall from ages past that this function wasn't registered Hidden-Source at all because there was no offset for it. I do recall trying to add it but it never worked... I'll try poking around and see if I can at least capture the angle data with what ever does fire, but frankly I think we'll have to just move the code to OnGameFrame. Not ideal but it should sort out that issue.

e: OnGameFrame it makes work even more strangly?

Paegus
28th October 2012, 18:01
Ok so I'm an idiot who copy & pastes code from another plugin into OnGameFrame and forget to change the team to IRIS :D

Tacking...

//...
if (g_Game == Game_HIDDEN) // OnPlayerRunCmd not registered with The Hidden:Source
for (new client = 1; client <= MaxClients; client++) // cycle through all players
if (IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client) == 2) // Only match IRIS player angle
GetClientEyeAngles(client, g_vEyeAngles[client]); // update eye angles
//...
...onto the end of the plugin's OnGameFrame() function works perfectly.

E: posted at Allied Modders to see if anyone there can help:
https://forums.alliedmods.net/showthread.php?t=199497

Ice1
29th October 2012, 01:59
Very good work Paegus, I was on the wrong track there. I had a look at the post you made on allied modders and I will have a go at that sometime today. Cheers.

Ice1
29th October 2012, 02:30
e: that does seem to do the trick, though it seems to be firing every frame anyway?

I found this in entity_prop_stocks.inc

stock GetClientButtons(client)
{
static bool:gotconfig = false;
static String:datamap[32];

if (!gotconfig)
{
new Handle:gc = LoadGameConfigFile("core.games");
new bool:exists = GameConfGetKeyValue(gc, "m_nButtons", datamap, sizeof(datamap));
CloseHandle(gc);

if (!exists)
{
strcopy(datamap, sizeof(datamap), "m_nButtons");
}

gotconfig = true;
}

return GetEntProp(client, Prop_Data, datamap);
}

Then i looked for m_nButtons in the offsets list and couldnt find it. Could this mean that command isn't compatible with hidden and somehow sdkhooks is just defaulting to use ongameframe instead?

Ice1
29th October 2012, 04:26
Actually maybe this is normal behavior of this function? I was thinking of ignoring everything unless it was a movement button which i found the flags to be

Left=512
Up=8
Right=1024
Back=16

Jump=2

But still thinking about the ramifications of that

e
if someone was just standing still looking for the hidden he might just appear out of nowhere if i did that...

e2
I actually found a post that describes how this function works


I also notice that there is a large amount of logic done in OnGameFrame (every frame), and in OnPlayerRunCmd (every frame, for each player).

So it is every frame, its working as intended

Paegus
29th October 2012, 06:41
Fair enough, but from the chatter about it years ago, it was supposed to be the Savior to the overload that was ongameframe...
I
LLC

Ice1
29th October 2012, 10:24
Thanks for your help there though Paegus. I will be setting this up on my server in the next few days and see how it effects server performance.

Paegus
29th October 2012, 10:58
Glad to help.

Implementing the anti-wallhack plugin should be at least partially beneficial. If they're using mat_wireframe, they'll get caught out anyway. If they're using a 3rd party hack .exe then it wont help that much.

This should also resolve the issue with all the other modules (aim-bot detection and the related eye-angle checks etc) then we get the full protection SMAC affords.

I remain a little worried about the extra overhead since it's run every game frame for every active client but only time will tell... and I do love seeing a banlog blossom and grow via automated means...

TK Managers aside...

Ice1
29th October 2012, 13:02
If they're using a 3rd party hack .exe then it wont help that much.

How come? It will stop the hidden from being rendered behind walls - at least then they cant track you behind walls.

Paegus
29th October 2012, 14:19
If the 3rd party app shows the hidden somehow (think BHS) then he'll be easily spotted when in view...

Though there is an issue with the anti-wallhack plugin: you can't use cl_demooverride to fly around recorded demos and see things out of your local area since the hidden's model disappears.

Paegus
29th October 2012, 18:46
Also there seems to be an issue with the some model's collision boxes... if you play on Derelict, if the hidden is up in the attic area he's mostly invisible. I thought this was due to the marine_clip brush entity but it's not. That leave the collision boxes of the broken concrete model?

e: confirmed this thoroughly with the help of el Digit... those concrete broken-wall models are messing with the line of sight tracing.


http://www.youtube.com/watch?v=IT-s-XTBmbw

Paegus
30th October 2012, 07:22
Oddly enough, this is a known issue with TF2. On the advise of God-Tony from AlliedModders you can set...

bool:IsPointVisible(const Float:start[3], const Float:end[3])
{
// TF2's team-specific barriers don't have a suitable workaround.
if (g_Game == Game_TF2)
TR_TraceRayFilter(start, end, MASK_VISIBLE, RayType_EndPoint, Filter_WorldOnly);
else
TR_TraceRayFilter(start, end, MASK_VISIBLE, RayType_EndPoint, Filter_NoPlayers);

g_iTraceCount++;

return TR_GetFraction() == 1.0;
}
..similarly to the Wallhack_UpdateClientCache() line...

bool:IsPointVisible(const Float:start[3], const Float:end[3])
{
// TF2's team-specific barriers don't have a suitable workaround.
if (g_Game == Game_TF2 || g_Game == Game_HIDDEN)
TR_TraceRayFilter(start, end, MASK_VISIBLE, RayType_EndPoint, Filter_WorldOnly);
else
TR_TraceRayFilter(start, end, MASK_VISIBLE, RayType_EndPoint, Filter_NoPlayers);

g_iTraceCount++;

return TR_GetFraction() == 1.0;
}

and it seems to have resolved that issue.

He's also pointed us to using Metamod:Source v1.8.7 (http://www.sourcemm.net/downloads/mmsource-1.8.7-windows.zip) and SDKHooks 2.1-dev-hg147 (http://users.alliedmods.net/~psychonic/builds/sdkhooks/2.1/sdkhooks-2.1.0-dev-hg147-windows.zip) so we don't need to add the EventListener offsets.

You do, however still need to add the PlayerRunCmd offset to .../addons/sourcemod/gamedata/sdktools/game.hidden.txt:

"PlayerRunCmd"
{
"windows" "364"
"linux" "365"
}
to get various SMAC modules to update properly.

I've posted this setup to the two CCake servers so feedback would be appreciated.

I'll put together a proper guide in the server setup thread later on.

Ice1
30th October 2012, 09:26
Sounds good Paegus, I'll set this up on my server sometime this week. Cheers.

Ice1
2nd November 2012, 12:26
Paegus, I have tried changing the filter to world only and the hidden seems to be visible behind func_detail (or func_brush's, not sure), which on some maps is a bit useless. Do you know of a way of not including the func_brush in the filter?

Paegus
2nd November 2012, 15:27
I'll have a look this weekend but i think you're out of luck. The world filter is just that. No entities, only world bsp brushes.

What is the purpose of the func_brush/detail? do they really make that big of a difference?

Will need to check if the hidden can be seen behind physics props..

you could check the include files for the various types of filters usable.

Ice1
13th November 2012, 12:02
Poked around but couldnt find much. Theres not that many areas like that where it becomes a problem, its just something to be aware of more than anything. This plugin is still definitely worth it and have it running on both of my servers without issues. Im pretty pleased. I think we should make a tutorial and post the ready made smx file Paegus so that other server admins can use this. Don't mind if you want to, if not i will.