fredag den 27. januar 2012

Adjusting aiming height for players with anti-aim

When playing HvH(Hacks vs. Hacks) in CSS, a feature, known as anti-aim, is often used.
I attached a screenshot of a bot, using anti-aim via the bot_mimic 1 convar:

As you can see on the screenshot, aiming at the center of the head hitbox, is not very effective for getting headshots.

I have attached my solution below with comments explaining the code:

struct Hitbox
{
 Hitbox( void )
 {
  hitbox = -1;
 }


 Hitbox( int newHitBox )
 {
  hitbox = newHitBox;
 }


 int  hitbox;
 Vector points[9];
};


enum
{
 FL_HIGH =  (1<<0),
 FL_LOW =  (1<<1),
 FL_SPECIAL = (1<<2)
};


struct BestPoint
{
 BestPoint( void )
 {
  hitbox = -1;
  point = 0;
  index = -1;
  dmg = -1;
  flags = 0;
 }


 BestPoint( int newHitBox )
 {
  hitbox = newHitBox;
  point = 0;
  index = -1;
  dmg = -1;
  flags = 0;
 }


 Vector point;
 int  index;
 int  dmg;
 int  flags;
 int  hitbox;
};
  
bool Aimbot::GetHitbox( CSPlayer *targetPlayer, Hitbox *box )
{
 matrix3x4_t matrix[MAXSTUDIOBONES];
 if ( !targetPlayer->SetupBones( matrix, MAXSTUDIOBONES, BONE_USED_BY_HITBOX, 0 ) )
 {
  return false;
 }


 studiohdr_t *studioHeader = g_InterfaceManager->ModelInfo()->GetVTable<IVModelInfo>()->GetStudiomodel( targetPlayer->GetModel() );
 if ( !studioHeader )
 {
  return false;
 }


 mstudiohitboxset_t *hitboxSet = studioHeader->pHitboxSet( targetPlayer->GetHitboxSet() );
 mstudiobbox_t *untransformedBox = hitboxSet->pHitbox( box->hitbox );

 
 // center and all the corners of the hitbox hehe
 Vector points[] = { ( ( untransformedBox->bbmin + untransformedBox->bbmax ) * .5f ),
  Vector( untransformedBox->bbmin.x, untransformedBox->bbmin.y, untransformedBox->bbmin.z ),
  Vector( untransformedBox->bbmin.x, untransformedBox->bbmax.y, untransformedBox->bbmin.z ),
  Vector( untransformedBox->bbmax.x, untransformedBox->bbmax.y, untransformedBox->bbmin.z ),
  Vector( untransformedBox->bbmax.x, untransformedBox->bbmin.y, untransformedBox->bbmin.z ),
  Vector( untransformedBox->bbmax.x, untransformedBox->bbmax.y, untransformedBox->bbmax.z ),
  Vector( untransformedBox->bbmin.x, untransformedBox->bbmax.y, untransformedBox->bbmax.z ),
  Vector( untransformedBox->bbmin.x, untransformedBox->bbmin.y, untransformedBox->bbmax.z ),
  Vector( untransformedBox->bbmax.x, untransformedBox->bbmin.y, untransformedBox->bbmax.z ) };


 for ( int index = 0; index <= 8; ++index )
 {
  if ( index != 0 )
  {
   // scale down the hitbox size
   points[index] =  ( ( ( ( points[index] + points[0] ) * .5f ) + points[index] ) * .5f );
  }
  
  // transform the vector
  VectorTransform( points[index], matrix[untransformedBox->bone], box->points[index] );

  //box.points[index] = this->GetExtrapolatedPosition( box.points[index], targetPlayer );
 }

 return true;
}


bool Aimbot::GetBestPoint( CSPlayer *targetPlayer, Hitbox *box, BestPoint *best )
{
 Vector center = box->points[0];

 // if we're checking the head hitbox
 if ( box->hitbox == 12 )
 {
  // aimpoints is already 3/4 of hitbox size
  Vector high = ( ( box->points[3] + box->points[5] ) * .5f );

  // is target looking down?
  float pitch = targetPlayer->GetEyeAngles().x;
  if ( ( pitch > 0.f )
   && ( pitch <= 89.f ) )
  {
   Vector height = ( ( ( high - box->points[0] ) / 3 ) * 4 );
   Vector newhigh = ( box->points[0] + ( height * ( pitch / 89.f ) ) );

   box->points[0] = newhigh;
   best->flags |= FL_HIGH;
  }
  // is target looking up?
  else if ( ( pitch < 292.5f )
   && ( pitch >= 271.f ) )
  {
   // lower the aimpoint
   box->points[0] -= Vector( 0.f, 0.f, 1.f );
   best->flags |= FL_LOW;
  }
 }


 for ( int index = 0; index <= 8; ++index )
 {
  int tmpdmg = GetDamage( box->points[index], targetPlayer );

  if ( ( tmpdmg != -1 )
   && ( best->dmg < tmpdmg )
   && ( ( tmpdmg - best->dmg ) > 1 ) )
  {
   best->dmg = tmpdmg;
   best->point = box->points[index];
   best->index = index;
  }
 }

 return ( best->dmg > 0 );
}
Usage should be quite obvious;
Result:
Happy hacking!

tirsdag den 10. januar 2012

Creating a simple string reversing user defined function(UDF) in C, for MySQL and running on CentOS

For an upcomming project, I need to use user defined functions in MySQL. Therefore I decided to figure out how it works, and what the optimal method of compiling an extention with the desired function, on CentOS would be.

To acquire the includes etc, download and install the MySQL source.

You need to customize the header called mysql_version.h according to your version of MySQL:
#ifndef _mysql_version_h
#define _mysql_version_h
#ifdef _CUSTOMCONFIG_
#include 
#else
#define PROTOCOL_VERSION 5
#define MYSQL_SERVER_VERSION "5.0.77"
#define MYSQL_BASE_VERSION "mysqld-5.0"
#define MYSQL_SERVER_SUFFIX_DEF  ""
#define FRM_VER 0
#define MYSQL_VERSION_ID 0
#define MYSQL_PORT 3306
#define MYSQL_PORT_DEFAULT 3306
#define MYSQL_UNIX_ADDR "/tmp/mysql.sock"
#define MYSQL_CONFIG_NAME "my"
#define MYSQL_COMPILATION_COMMENT ""

#endif /* _CUSTOMCONFIG_ */

#ifndef LICENSE
#define LICENSE GPL
#endif /* LICENSE */

#endif /* _mysql_version_h */

Now you can include mysql.h to your C-file, and start coding your UDF, I've coded a simple function for reversing a string, code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef unsigned long long ulonglong;
typedef long long longlong;
#include <mysql.h>
#include <ctype.h>


my_bool Inverse_init( UDF_INIT* initid, UDF_ARGS* args, char* message );
void Inverse_deinit( UDF_INIT* initid );
char* Inverse( UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error );


my_bool Inverse_init( UDF_INIT* initid, UDF_ARGS* args, char* message )
{
 if ( ( args->arg_count != 1 ) || ( args->arg_type[0] != STRING_RESULT ) )
 {
  strcpy( message, "Wrong argument type" );
  return 1;
 }

 return 0;
}


void Inverse_deinit( UDF_INIT* initid )
{
}


char* Inverse( UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error )
{
 const char* arg = args->args[0];

 (*length) = strlen( arg );

 int i;
 for ( i = (*length); i >= 0; i-- )
 {
  result[(*length) - i - 1] = arg[i];
 }

 return result;
}

 I have not made this code to be compatible with Unicode, but I intend to make a post in the near future, explaining Unicode.

We need to compile this, so let's fire up our CentOS and go the the directory where we saved the C-File(save it in your MySQL source directory somewhere), and compile using the following command:
gcc -shared -o filenamehere.so filenamehere.c -I ../include/

Obviously you want to customize the include directory parameter to lead to the include directory, from the directory where your file is, the include directories is: */mysqlsource/include/

So now that we have the shared object(.so) file, we can go ahead and put it in the following directory: */usr/lib/ 
then restart our mysqld service:
service mysqld restart

You can now load up your SQLyog, and define your newly created function using:
CREATE FUNCTION Inverse RETURNS STRING SONAME 'filenamehere.so'


And now your UDF is ready for use!