Raised This Month: $51 Target: $400
 12% 

SMAC Development Thread


Post New Thread Closed Thread   
 
Thread Tools Display Modes
niask1
Junior Member
Join Date: Dec 2010
Location: Kaluga, Russia
Old 11-21-2011 , 01:43   Re: SMAC Development Thread
#311

smac_eyetest still bans players in l4d2 on campaign change
and smac_autotrigger too

Last edited by niask1; 11-21-2011 at 01:44.
niask1 is offline
GoD-Tony
Veteran Member
Join Date: Jul 2005
Old 11-21-2011 , 02:31   Re: SMAC Development Thread
#312

Quote:
Originally Posted by niask1 View Post
smac_eyetest still bans players in l4d2 on campaign change
and smac_autotrigger too
L4D2 strikes again. What version of SMAC were you running? Can you PM me the logs?
__________________

Last edited by GoD-Tony; 11-21-2011 at 02:56.
GoD-Tony is offline
niask1
Junior Member
Join Date: Dec 2010
Location: Kaluga, Russia
Old 11-22-2011 , 01:15   Re: SMAC Development Thread
#313

Quote:
Originally Posted by GoD-Tony View Post
L4D2 strikes again. What version of SMAC were you running? Can you PM me the logs?
I was running version 0.7.3.8. Oups, as the bans were false I've already purged SMAC.log after unbanning concerned players (sorry, didn't think of sending it ). Then I disabled smac_autotrigger.smx and smac_eyetest.smx.
niask1 is offline
egor1908
Veteran Member
Join Date: Sep 2009
Old 11-22-2011 , 14:08   Re: SMAC Development Thread
#314

Quote:
Originally Posted by GoD-Tony View Post
L4D2 strikes again. What version of SMAC were you running? Can you PM me the logs?
L4D2, nothing wrong here. Probably because i run versus?
egor1908 is offline
zrayz
Junior Member
Join Date: Nov 2011
Location: Russia
Old 11-23-2011 , 05:24   Re: SMAC Development Thread
#315

I am use SM 1.4 and MM 1.8.7 and i have some errors with last SMAC version:
Code:
L 11/22/2011 - 21:10:02: Info (map "mg_twotowers") (file "errors_20111122.log")
L 11/22/2011 - 21:10:02: [SM] Fatal error encountered parsing translation file "fi/smac.phrases.txt"
L 11/22/2011 - 21:10:02: [SM] Error (line 110, column 78): Line contained too many invalid tokens
L 11/22/2011 - 21:25:41: Error log file session closed.
zrayz is offline
GoD-Tony
Veteran Member
Join Date: Jul 2005
Old 11-23-2011 , 05:38   Re: SMAC Development Thread
#316

Quote:
Originally Posted by zrayz View Post
I am use SM 1.4 and MM 1.8.7 and i have some errors with last SMAC version:
I have no idea what it is about translation files and FTP, but every time that error is posted it has different line/column numbers.

Try forcing Binary uploads only (not Auto or ASCII) and see if that helps.
__________________
GoD-Tony is offline
TwOzCaR
Senior Member
Join Date: Jul 2010
Old 11-23-2011 , 05:50   Re: SMAC Development Thread
#317

Quote:
Originally Posted by GoD-Tony View Post
I have no idea what it is about translation files and FTP, but every time that error is posted it has different line/column numbers.

Try forcing Binary uploads only (not Auto or ASCII) and see if that helps.
yes most of the people here do it wrong, are they forgetting to put in the translations files from the -> http://godtony.mooo.com/smac/smac.zip or is it just because their ftp management program sux and not uploading it right?

another thing which is far more complicated is to compile the smac yourself, but it requires everything that tony wrote on this page -> https://forums.alliedmods.net/showthread.php?t=162720

i recommend this compiling yourself with the newest repost from here -> http://hg.nicholashastings.com/smac/archive/tip.zip

edit: sourcemod\scripting\compile.exe <- this exe can do the compile job, you just need to put these files in scripting & (includes) <-very important

->

To compile SMAC and all of its modules, you will need these dependencies in your scripting/includes directory:sourcemod/translations ->

and the translations files is very important to have on the server, upload it with a good ftp program in binary mode, example: filezilla, good & free
its not just this one -> smac.phrases.txt it's all the ones in the dir under translations examples: [da] & [de] & [en] & [se] & so on

Last edited by TwOzCaR; 11-23-2011 at 08:55.
TwOzCaR is offline
Unsleddable
New Member
Join Date: Nov 2011
Old 11-23-2011 , 13:48   Re: SMAC Development Thread
#318

GoD-Tony,

Have you ever thought about detecting actual no spread, instead of just checking for improper angles?

For example

PHP Code:
/*
Attempt to detect if the client is running no spread. This is done by comparing the 
fixed angles of the current and last frame. If the delta is small enough, then the fixed
angles resulted in no difference, meaning that we found the client's original angles.
If they exist then the client must be accounting for spread. The delta is variable and
depends on the size of the spread.
*/
bool NoSpreadDetector::IsNoSpreadedict_tpEdictCBaseEntitypEntityCUserCmdcmdsint num)
{
    
CBaseEntitypWeapon gBrainiacUtils.GetActiveWeapon(pEntity);
    
int weaponID GetWeaponID(playerinfomanager->GetPlayerInfo(pEdict)->GetWeaponName());
    
float spread GetCSSSpread(pEntitypWeaponweaponID);

    
int numMouseMovements 0;

    
NoSpreadClientDatapData = (NoSpreadClientData*)GetClientData(IndexOfEdict(pEdict));

    
pData->timeAlive += (cmds[0].tick_count cmds[num-1].tick_count);
    
    
//Loop through the given cmds
    
for(int i num 2>= 0i--)
    {
        
CUserCmdprev = &cmds[i+1];
        
CUserCmdcur = &cmds[i];

        
Vector    vOriginalOldvOriginalNewvDeltavRealOldvRealNewvDeltaReal;

        
//Assuming the client is running no spread,
        //Get the real client view angles for the current and previous frame
        
GetSpreadVector(prev->random_seedspreadprev->viewanglesvOriginalOld);
        
GetSpreadVector(cur->random_seedspreadcur->viewanglesvOriginalNew);

        
//Get the real, non corrected angles as well
        
AngleVectors(prev->viewangles, &vRealOld);
        
AngleVectors(cur->viewangles, &vRealNew);

        
//Normalize to remove the increase in length due to adding the spread vector
        
vOriginalOld.NormalizeInPlace();
        
vOriginalNew.NormalizeInPlace();

        
//Get the difference in the spread fixed forward vectors
        //If they are running no spread, then the delta should be very small
        
vDelta vOriginalNew vOriginalOld;

        
//Check the actual angles to filter out legimate users
        
vDeltaReal vRealNew vRealOld;

        
//Only apply checks if there have been angle changes
        //Otherwise, we may have increased false positives
        
if(vDeltaReal.Length() > spread 500.0f)
        {
            
//We have detected no spread
            
if(vDelta.Length() < spread 500.0f)
            {
                
pData->numStaticDetections++;
                return 
true;
            }
            
//Angles are changing, but we aren't detecting no spread
            //Perhaps there have been mouse movements
            
else
            {
                
numMouseMovements++;
            }
        }
    }

    
//The mouse was moving for at least 3 frames
    //Try checking for a no spread pattern via linear regression
    
if(numMouseMovements >= 3)
    {
        
//First check for no spread
        
if(IsNoSpreadWithMouseMovement(pEdictpEntitytruecmdsnum))
        {
            
//Now filter out false positives
            
if(IsNoSpreadWithMouseMovement(pEdictpEntityfalsecmdsnum))
            {
                
pData->numDynamicDetections++;
                return 
true;
            }
        }
    }

    return 
false;

PHP Code:
/*
Check for no spread if there were changes in the angles that couldn't be accounted
for by no spread alone. We must now check for a pattern in the changes. Also,
allowing checking of error without no spread correction for removal of false positives.
*/
bool NoSpreadDetector::IsNoSpreadWithMouseMovementedict_tpEdictCBaseEntitypEntitybool correctSpreadCUserCmdcmdsint num )
{
    
CBaseEntitypWeapon gBrainiacUtils.GetActiveWeapon(pEntity);
    
int weaponID GetWeaponID(playerinfomanager->GetPlayerInfo(pEdict)->GetWeaponName());
    
float spread GetCSSSpread(pEntitypWeaponweaponID);

    
char url[512];

    
double x[32];
    
double y[32];
    
double z[32];

    
double out_x[32];
    
double out_y[32];

    
float flMovementDelta 0;
    
Vector vStartvEnd;

    if(
correctSpread)
    {
        
GetSpreadVector(cmds[0].random_seedspreadcmds[0].viewanglesvEnd);
        
GetSpreadVector(cmds[num 1].random_seedspreadcmds[num 1].viewanglesvStart);
    }
    else
    {
        
AngleVectors(cmds[0].viewangles, &vEnd);
        
AngleVectors(cmds[num 1].viewangles, &vStart);
    }

    
vEnd.NormalizeInPlace();
    
vStart.NormalizeInPlace();

    
flMovementDelta = (vEnd vStart).Length();

    
//Loop through cmds saving each forward vector
    //Add each one to the list of points to be checked
    //Pass the data to our analyzer function

    
for(int i num 1>= 0i--)
    {
        
CUserCmdcur = &cmds[i];
        
Vector vRealFwd;

        if(
correctSpread)
            
GetSpreadVector(cur->random_seedspreadcur->viewanglesvRealFwd);
        else
            
AngleVectors(cur->viewangles, &vRealFwd);

        
vRealFwd.NormalizeInPlace();

        
x[i] = vRealFwd.x;
        
y[i] = vRealFwd.y;
        
z[i] = vRealFwd.z;
    }

    
//We have enough data to attempt linear regression
    
if(num 3)
    {
        
float error gBrainiacUtils.GetStandardErrorForPointsInSphere(vStartvEndxyznumout_xout_y);

        
//If the error is less than the error bound we have detected no spread.
        //Also, if we aren't correcting for spread and the error is bigger than a 
        //larger error bound, we are probably running no spread
        
if((correctSpread && (error spread 1000.0)) || 
            (!
correctSpread && (error spread 100.0f)))
        {
            
//Ok, all signs point to the user running no spread
            //Perform the final check to excuse them
            
if(!correctSpread && IsLegitimateErrorPattern(out_xout_ynum))
                return 
false;

            return 
true;
        }
    }

    return 
false;

PHP Code:
/*
Figure out what kind of error pattern the data shows. If the first and last approximations
are on the same side of the least squares regression line, then perhaps they are a
legitimate user who would have been cleared if polynomial fitting was used instead.
Give them the benefit of the doubt since a client running real no spread will have
no problem getting detected, even if they accidentally pass this test once or twice.
*/
bool NoSpreadDetector::IsLegitimateErrorPatterndoublexdoubleyint num )
{
    
LinearRegression reg(xynum);

    
float firstError reg.estimateY(x[0]) - y[0];
    
float lastError reg.estimateY(x[num-1]) - y[num-1];

    
//We can't be sure they are running no spread
    //Give them the benefit of the doubt
    
if( (firstError && lastError 0) ||
        (
firstError && lastError 0))
        return 
true;

    
//If the error points lie on different sides of the residual line,
    //We have completed the process and detected a hacker, congratulations!
    
return false;

PHP Code:
/*
We are given a set of points in a sphere, essentially the forward vectors
of all of the cmd angles. We create a plane that is tangent to the sphere 
at the point on the sphere corresponding to the midpoint of the first and 
last vector. From there, we project all of the points on the sphere onto
this plane. This results in a 2d mapping of the changes over the given cmds. 
Finally, we run a regression analysis on the points to see if there is a 
spread pattern, or rather lack of one, due to the corrected cmd angles. 
We do it this way so that we can stick to 2D regression and improve performance.

TODO: figure out what gets canceled and simplify
*/
float BrainiacUtils::GetStandardErrorForPointsInSphere(Vector vStartVector vEnddoublexdoubleydoublezint sizedoubleout_xdoubleout_y)
{
    
Vector vTangentPointvMidPointvPlanevOffsetvInPlanevXAxisvSignReference;
    
LinearRegression reg;

    
vInPlane vEnd vStart;

    
vTangentPoint vStart vInPlane 2;
    
vTangentPoint.NormalizeInPlace();

    
//Equation of sphere: x^2 + y^2 + z^2 = 1
    //Gradient vector: 2x, 2y, 2z
    
vPlane vTangentPoint 2;
    
float planeD =    vPlane.* -vTangentPoint.
        
vPlane.* -vTangentPoint.+
        
vPlane.* -vTangentPoint.z;

    
//Project points onto the plane
    
for(int i 0sizei++)
    {
        
double distancenumeratordenominatorsignlength;

        
numerator abs(vPlane.x[i] + vPlane.y[i] + vPlane.z[i] + planeD);
        
denominator vPlane.Length();

        
distance numerator denominator;

        
//Map point onto the 3D plain! yay
        
Vector vNewPoint(    x[i] + vTangentPoint.distance,
            
y[i] + vTangentPoint.distance,
            
z[i] + vTangentPoint.distance);

        
//Get the vector that we want to re-create in 2D
        //We will do so by going 3D cartesian -> polar -> 2D cartesian
        
Vector vVecInPlane vNewPoint vTangentPoint;

        
length vVecInPlane.Length();

        
vVecInPlane.NormalizeInPlace();

        
//Construct arbitrary axis for conversion to 2d
        //vStart and vEnd are equidistant from the plane
        //Add the distance to vInPlane to get a vector in the plane
        //Use it to detirmine the sign of the y value
        //
        //TODO: ghetto as fuck, find a better solution
        
if(== 0)
        {
            
vXAxis vTangentPoint vInPlane;
            
vXAxis.NormalizeInPlace();

            
vSignReference vXAxis.Cross(vVecInPlane);
        }

        
//Sum with reference cross vector to see if it got longer,
        //or if it canceled out. The lengths should be 0 or 2
        
Vector vCrossSum vSignReference vXAxis.Cross(vVecInPlane);

        if(
vCrossSum.Length() > 1)
            
sign 1.0f;
        else
            
sign = -1.0f;

        
//Get the angle between the two vectors
        
float angle acos(vXAxis.Dot(vVecInPlane) / (vXAxis.Length() * vVecInPlane.Length()));

        
float cx length cos(angle);
        
float cy length sin(angle) * sign;

        
reg.addXY(cxcy);

        if(
out_x)
            
out_x[i] = cx;

        if(
out_y)
            
out_y[i] = cy;
    }

    return 
reg.getStdErrorEst();

Usage example:

PHP Code:
            //Get outta here
            
if(IsNoSpread(pEdictpEntitycmdsnum))
            {
                 
sprintf(kick"say %s\n"playerinfomanager->GetPlayerInfo(pEdict)->GetName());
                 
engine->ServerCommand(kick);
            } 
It works extremely well in detecting when clients run no spread, including when they run it while moving their mouse. It provides virtually no false positives, and almost no false negatives.
Unsleddable is offline
Unsleddable
New Member
Join Date: Nov 2011
Old 11-23-2011 , 14:02   Re: SMAC Development Thread
#319

It's also possible to do actual aimbot detection by callling StartLagCompensation, since it will rewind all players to their relative positions and allow you to check if their viewangles are locked onto someone's head bone. You can optimize by hooking WantsLagCompensationOnEntity and only rewinding the player that we think is being locked on to.

For example:
PHP Code:
bool BrainiacMM::Hook_WantsLagCompensationOnEntity(const CBaseEntity *pPlayer, const CUserCmd *pCmd, const CBitVec<MAX_EDICTS> *pEntityTransmitBits)
{
    
CBaseEntity *instance META_IFACEPTR(CBaseEntity);

    if(
g_pCompensatingPlayer && g_pCompensatingPlayer == instance)
    {
        if(
pPlayer == g_pPlayerToBacktrace)
            
RETURN_META_VALUE(MRES_SUPERCEDEtrue);
        else
            
RETURN_META_VALUE(MRES_SUPERCEDEfalse);
    }

    
RETURN_META_VALUE(MRES_IGNOREDfalse);

Then, for actual detection (snippet):
PHP Code:
    for(int i num 1>= 0i--)
    {
        
CUserCmdcur = &cmds[i];
        
Vector vTargetBonevBoneDirvCurFwd;

        
AngleVectors(cur->viewangles, &vCurFwd);

        if(
num 1)
        {
            
float angCmdDelta TO_DEG(acos(vCurFwd.Dot(vLastFwd)));

            if(
angCmdDelta 0.5f)
            {
                
//Msg("%s: angle change too small\n", playerinfomanager->GetPlayerInfo(pEdict)->GetName());
                
return 0;
            }
        }

        
g_pCompensatingPlayer pBaseEntity;
        
g_pPlayerToBacktrace pRemoteEnt;
        
gBrainiacUtils.GetLagCompensation()->StartLagCompensation((CBasePlayer*)pBaseEntitycur);

        
//First loop
        
if(== num 1)
        {
            
bone GetClosestBone(vEyesvCurFwdpRemoteEnt);
        }

        
GetBonePos(bonevTargetBonepRemoteEnt);

        if(
num 1)
        {
            
vBoneDir = (vTargetBone vEyes).Normalize();
            
float angDelta TO_DEG(acos(vCurFwd.Dot(vBoneDir)));

            
Vector vMoveDir = (vTargetBone vLastBone).Normalize();
            
float angRelativeMove TO_DEG(acos(vCurFwd.Dot(vMoveDir.Normalize())));

            if(
angDelta GetMaxAngle(length10.0f) &&
                
abs(90.0f angRelativeMove) < 45.0f)
            {
                
numPossible++;

                if(
angDelta GetMaxAngle(length1.5f))
                {
                    
numDetected++;
                }
            }
        }

        
gBrainiacUtils.GetLagCompensation()->FinishLagCompensation((CBasePlayer*)pBaseEntity);
        
g_pCompensatingPlayer NULL;
        
g_pPlayerToBacktrace NULL;

        
vLastFwd vCurFwd;
        
vLastBone vTargetBone;
    } 
This will essentially see how closely the client has been following a given player's "locked" bone over the past couple of frames. We can make it really fancy by running regression analysis on the pattern to see if it is incredibly smooth. Again, this almost never registers false positives, and almost always detects aimbots. The good thing here is that we can run some statistics on top of our detector, so a few false positives out of thousands wont matter, yet a significant percentage of positives relative to the total possible amount will.

Last edited by Unsleddable; 11-23-2011 at 14:04.
Unsleddable is offline
GoD-Tony
Veteran Member
Join Date: Jul 2005
Old 11-24-2011 , 07:52   Re: SMAC Development Thread
#320

A quick follow-up from IRC...

Quote:
Originally Posted by Unsleddable View Post
Have you ever thought about detecting actual no spread, instead of just checking for improper angles?
I did have an idea in mind but didn't get a chance to try it out. I quickly threw this together to help explain. After looking at it, I think it's a greatly oversimplified version of what you posted:
PHP Code:
public OnPluginStart()
{
    
// This tempent should provide all the data needed.
    
AddTempEntHook("Shotgun Shot"Hook_FireBullets);
    
    
// Init list of weapons that we should be checking.
    
g_bCheckWeapon[1] = true;
    
g_bCheckWeapon[5] = true;
    
g_bCheckWeapon[20] = true;
    
/* ... etc ... */
}

public 
Action:Hook_FireBullets(const String:te_name[], const Players[], numClientsFloat:delay)
{
    
/*
    "m_vecOrigin"        "vector"
    "m_vecAngles[0]"    "float"
    "m_vecAngles[1]"    "float"
    "m_iWeaponID"        "int"
    "m_iMode"            "int"
    "m_iSeed"            "int"
    "m_iPlayer"            "int"
    "m_fInaccuracy"        "float"
    "m_fSpread"            "float"
    */
    
    
new client TE_ReadNum("m_iPlayer") + 1;
    new 
iWeaponID TE_ReadNum("m_iWeaponID");
    
    if (
client && g_bCheckWeapon[iWeaponID])
    {
        
decl Float:vBulletAngles[3];
        
vBulletAngles[0] = TE_ReadFloat("m_vecAngles[0]");
        
vBulletAngles[1] = TE_ReadFloat("m_vecAngles[1]");
        
vBulletAngles[2] = 0.0// Not used in CS:S (and maybe all of ep2v).
        
        // Check if the client adjusted their angles perfectly for the shot.
        
decl Float:vDelta1[3], Float:vDelta2[3];
        
SubtractVectors(vBulletAnglesg_vPreviousEyeAngles[client], vDelta1);
        
SubtractVectors(g_vCurrentEyeAngles[client], g_vPreviousEyeAngles[client], vDelta2);
        
        if (
AreVectorsAlmostEqual(vDelta1vDelta21.0))
        {
            
g_iDetections[client]++;
        }
    }
    
    return 
Plugin_Continue;
}

public 
Action:OnPlayerRunCmd(client, &buttons, &impulseFloat:vel[3], Float:angles[3], &weapon)
{
    
g_vPreviousEyeAngles[client] = g_vCurrentEyeAngles[client];
    
g_vCurrentEyeAngles[client] = angles;
    return 
Plugin_Continue;
}

stock bool:AreVectorsAlmostEqual(const Float:vec1[3], const Float:vec2[3], const Float:tolerance=0.1)
{
    return 
FloatAbs(vec1[0] - vec2[0]) <= tolerance && 
        
FloatAbs(vec1[1] - vec2[1]) <= tolerance && 
        
FloatAbs(vec1[2] - vec2[2]) <= tolerance;

No real error checking as it was just an idea, but statistics could build very fast on full-auto weapons. I'm interested to know how your algorithm performs. Hopefully I get a chance for some test cases next week or so.

Quote:
Originally Posted by Unsleddable View Post
It's also possible to do actual aimbot detection by callling StartLagCompensation, since it will rewind all players to their relative positions and allow you to check if their viewangles are locked onto someone's head bone. You can optimize by hooking WantsLagCompensationOnEntity and only rewinding the player that we think is being locked on to.
This one is very interesting. Two questions: How often would the checks run, and what effect does it have on players when it runs?
__________________

Last edited by GoD-Tony; 11-24-2011 at 08:08.
GoD-Tony is offline
Closed Thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 19:43.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode