Code:
#define WINVER 0x0500 //windows XP and up
#include <iostream>
#include <windows.h>
#include <time.h>
#include <winable.h>
#include <map> //for mapping keys to virtual key values
#include <algorithm> //for searching through the maps
#include <pthread.h>
using namespace std;
bool chat_active = false; //if the player is currently talking
bool command_active = false; //if a chat command menu is open
int qswitch_key; //key used to switch your weapon
//==========================//
int crouch_key; //key used to crouch
//==========================//
int walk_key; //key used to walk
//==========================//
int scope_speed_milliseconds; //how fast the scope zooms
//==========================//
bool burst; //if you want to burst or not
int burst_amount; //how many burts
int burst_speed; //how fast to burst
int click_amount; //how many times to click
//==========================//
void Generate_Key(int key){ //sends keydown and keyup messages
INPUT input;
input.type = INPUT_LEOPARD; //set the flags
input.ki.wScan = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
input.ki.wVk = key;
SendInput(1, &input, sizeof(INPUT)); //send the message
input.ki.dwFlags = KEYEVENTF_KEYUP; //set the flag
SendInput(1, &input, sizeof(INPUT)); //send the message
}
void Generate_Key_down(int key){ //generates a key down
INPUT input;
input.type = INPUT_LEOPARD; //set the flags
input.ki.wScan = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
input.ki.wVk = key;
SendInput(1, &input, sizeof(INPUT)); //send the message
}
void Generate_Key_up(int key){ //generates a key up
INPUT input;
input.type = INPUT_LEOPARD; //set the flags
input.ki.wScan = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
input.ki.wVk = key;
input.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &input, sizeof(INPUT)); //send the message
}
void unclick(bool middle_or_right){ //unclicks a mouse button (middle or right)
INPUT input = {0};
input.type = INPUT_MOUSE;
if(middle_or_right){ //middle button click
input.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
SendInput(1, &input, sizeof(INPUT));
}
else if(!middle_or_right){ //right button click
input.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
SendInput(1, &input, sizeof(INPUT));
}
}
void click(bool middle_or_right){ //clicks a mouse button (middle or right)
INPUT input = {0};
input.type = INPUT_MOUSE;
if(middle_or_right){ //middle click
input.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
SendInput(1, &input, sizeof(INPUT));
}
else if(!middle_or_right){ //right click
input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
SendInput(1, &input, sizeof(INPUT));
}
}
void macro_click(){ //generates a click and unclick (middle only)
INPUT input={0};
// left down
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_MIDDLEDOWN;
SendInput(1,&input,sizeof(INPUT));
// left up
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_MIDDLEUP;
SendInput(1,&input,sizeof(INPUT));
}
int choose_scope_speed(){ //lets user set the scope speed
cin.clear();cin.sync(); //clear out the input buffer
float scope_speed_seconds;
int scope_speed_milliseconds;
cout << "Scope speeds:" << endl;
cout << "0.21s: Mosin Nagant Basic Scope, AWM Precision Scope" << endl;
cout << "0.23s: FR-F2 Sharpshooter Scope, ASW.338 Quick Scope II, AWM Basic Scope, DSR-1 Quick Scope 2, Blaser R93 Sharpshooter Scope" << endl;
cout << "0.25s: ASW.338 Sharpshooter Scope II" << endl;
cout << "0.27s: ASW.338 Basic Scope" << endl;
cout << "0.29s: M24 Basic Scope, SV98 Precision Scope, FR-F2 Basic Scope, DSR-1 Basic Scope, PGM.338 Precision Scope, Blaser R93 Precison Scope" << endl;
cout << "0.30s: SV98 Basic Scope" << endl;
cout << "0.31s: Blaser R93 Basic Scope, FR-F2 Quick Scope, DSR-1 High Powered Scope 2" << endl;
cout << "0.39s: TPG1 High Powered Scope, PGM.338 High Powered Scope" << endl;
cout << "0.43s: TPG1 Basic Scope, PGM.338 Basic Scope" << endl << endl;
cout << "Enter your scope speed in seconds: ";
cin >> scope_speed_seconds;
scope_speed_milliseconds = scope_speed_seconds * 1000;
return scope_speed_milliseconds;
}
int choose_key(int type){ //let the user choose their key for whatever function (walk, crouch, quickswitch)
cin.clear();cin.sync(); //clear the input buffer
map<string, int> keycodes;
keycodes.insert(make_pair("a", 0x41));
keycodes.insert(make_pair("b", 0x42));
keycodes.insert(make_pair("c", 0x43));
keycodes.insert(make_pair("d", 0x44));
keycodes.insert(make_pair("e", 0x45));
keycodes.insert(make_pair("f", 0x46));
keycodes.insert(make_pair("g", 0x47));
keycodes.insert(make_pair("h", 0x48));
keycodes.insert(make_pair("i", 0x49));
keycodes.insert(make_pair("j", 0x4A));
keycodes.insert(make_pair("k", 0x4B));
keycodes.insert(make_pair("l", 0x4C));
keycodes.insert(make_pair("m", 0x4D));
keycodes.insert(make_pair("n", 0x4E));
keycodes.insert(make_pair("o", 0x4F));
keycodes.insert(make_pair("p", 0x50));
keycodes.insert(make_pair("q", 0x51));
keycodes.insert(make_pair("r", 0x52));
keycodes.insert(make_pair("s", 0x53));
keycodes.insert(make_pair("t", 0x54));
keycodes.insert(make_pair("u", 0x55));
keycodes.insert(make_pair("v", 0x56));
keycodes.insert(make_pair("w", 0x57));
keycodes.insert(make_pair("x", 0x58));
keycodes.insert(make_pair("y", 0x59));
keycodes.insert(make_pair("z", 0x5A));
keycodes.insert(make_pair("left control", VK_LCONTROL));
keycodes.insert(make_pair("right control", VK_RCONTROL));
keycodes.insert(make_pair("left click", VK_LBUTTON));
keycodes.insert(make_pair("right click", VK_RBUTTON));
keycodes.insert(make_pair("middle click", VK_MBUTTON));
keycodes.insert(make_pair("enter", VK_RETURN));
keycodes.insert(make_pair("shift", VK_SHIFT));
keycodes.insert(make_pair("alt", VK_MENU));
keycodes.insert(make_pair("capslock", VK_CAPITAL));
keycodes.insert(make_pair("1-2-1", 2));
keycodes.insert(make_pair("1-3-1", 3));
keycodes.insert(make_pair("1-4-1", 4));
string key;
int key_int;
while(true){
if(type == 0){ //switch
cout << "What do you want as your quickswitch key? (type \'help\' for a list of supported keys) ";
}
else if(type == 1){ //crouch
cout << "What do you want as your crouch key? (type \'help\' for a list of supported keys) ";
}
else if(type == 2){
cout << "What do you want as your walk key? (type \'help\' for a list of supported keys) ";
}
getline(cin, key);
transform(key.begin(), key.end(), key.begin(), ::tolower);
if(key == "help"){
cout << "Supported keys:" << endl;
for(map<string, int>::const_iterator it = keycodes.begin(); it != keycodes.end(); ++it){
cout << it->first << endl;
}
continue;
}
if(keycodes.find(key) == keycodes.end()){
cout << "Key not supported." << endl;
continue;
}
break;
}
key_int = keycodes.find(key)->second;
return key_int;
}
void* qswitch(void* ignore){ //quickswitch function (note: type void* and a void* parameter for p_threads)
bool qswitch_active = false; //starts out deactivated
while(true){ //run the thread until the program exits
while(qswitch_active){ //when the user activates it, leave it active
if((GetKeyState(VK_LBUTTON) & 0x80) != 0){ //if the user left clicks, middle click and unclick
click(true);
Sleep(50);
unclick(true);
Sleep(50);
if(qswitch_key == 2 || qswitch_key == 3 || qswitch_key == 4){ //quickswitch using 1-2-1, 1-3-1, or 1-4-1
Generate_Key(qswitch_key); //quick switch using the key chosen
Sleep(5);
Generate_Key(1); //switch back to main weapon
Sleep(1);
}
else{ //or just use the key they set
Generate_Key(qswitch_key); //quick switch using the key chosen
Sleep(5);
Generate_Key(qswitch_key); //switch back to main weapon
Sleep(1);
}
}
if((GetKeyState(0x38) & 0x80) != 0){ //if the number 8 key is pressed, pause the quickswitcher
cout << "Quickswitch macro paused" << endl;
qswitch_active = false;
Sleep(100);
}
Sleep(1);
}
if(!chat_active && !command_active){ //if the command menu is not open, and the user is not typing
Sleep(200); //since threads run alongside each other, sleep to avoid catching number key when choosing command
if((GetKeyState(0x37) & 0x80) != 0){ //if the number 7 key is pressed, activate it
cout << "Quickswitch macro activated" << endl;
qswitch_active = true;
Sleep(100);
}
}
Sleep(1);
}
return NULL;
}
void* qscope(void* ignore){ //quickscope function
bool qscope_active = false;
while(true){
while(qscope_active){
if((GetKeyState(VK_LBUTTON) & 0x80) != 0){ //if the users presses the left mouse button
Sleep(50);
click(false); //click right (zoom)
Sleep(5);
unclick(false); //un_click right
Sleep(scope_speed_milliseconds); //wait for the scope to zoom
click(true); //click middle (fire)
Sleep(50);
unclick(true); //un_click middle
if(qswitch_key == 2 || qswitch_key == 3 || qswitch_key == 4){
Generate_Key(qswitch_key); //quick switch using the key chosen
Sleep(5);
Generate_Key(1); //switch back to main weapon
Sleep(1);
}
else{
Generate_Key(qswitch_key); //quick switch using the key chosen
Sleep(5);
Generate_Key(qswitch_key); //switch back to main weapon
Sleep(1);
}
}
if((GetKeyState(0x30) & 0x80) != 0){ //if the number 0 key is pressed, pause it
cout << "Quickscope macro paused" << endl;
qscope_active = false;
Sleep(100);
}
Sleep(1);
}
if(!chat_active && !command_active){
Sleep(200);
if((GetKeyState(0x39) & 0x80) != 0){ //if the number 9 key is pressed, activate it
cout << "Quickscope macro activated" << endl;
qscope_active = true;
Sleep(100);
}
}
Sleep(1);
}
return NULL;
}
void* crouch(void* ignore){ //crouch function
bool crouch_active = false;
while(true){
while(crouch_active){
if((GetKeyState(VK_LBUTTON) & 0x80) != 0){ //if the left mouse button is clicked
Generate_Key_down(crouch_key); //generate the crouch key DOWN ONLY
click(true); //middle click (fire)
}
else{ //if the left mouse button is not click
Generate_Key_up(crouch_key); //generate a key up
unclick(true); //unclick the middle (stop firing)
}
if((GetKeyState(0x28) & 0x80) != 0){ //if the down arrow is pressed, deactivate it
cout << "Crouch macro paused" << endl;
crouch_active = false;
Sleep(100);
}
Sleep(1);
}
if(!chat_active && !command_active){
if((GetKeyState(0x26) & 0x80) != 0){ //if the up arrow is pressed, activate it
cout << "Crouch macro activated" << endl;
crouch_active = true;
Sleep(100);
}
}
Sleep(1);
}
return NULL;
}
void* walk(void* ignore){ //walk function
bool walk_active = false;
while(true){
while(walk_active){
if((GetKeyState(VK_LBUTTON) & 0x80) != 0){ //if the user left clicks
Generate_Key_down(walk_key); //same idea as crouch, generate walk key DOWN
click(true); //and fire
}
else{ //no left click
Generate_Key_up(walk_key); //generate walk key up
unclick(true); //stop firing
}
if((GetKeyState(0x27) & 0x80) != 0){ //if the right arrow is pressed, deactivate it
cout << "Walk macro paused" << endl;
walk_active = false;
Sleep(100);
}
Sleep(1);
}
if(!chat_active && !command_active){
if((GetKeyState(0x25) & 0x80) != 0){ //if the left arrow is pressed, activate it
cout << "Walk macro activated" << endl;
walk_active = true;
Sleep(100);
}
}
Sleep(1);
}
return NULL;
}
void* tap(void* ignore){ //rapid mouse click function
bool tap_active = false;
int counter1 = 0; //number of clicks
int counter2 = 0; //number of bursts
while(true){
while(tap_active){
if((GetKeyState(VK_LBUTTON) & 0x80) != 0){ //if the left mouse button is clicked
if(burst){ //if the user chose to burst
while(counter2 < burst_amount){ //burst the chosen amount of times
while(counter1 < click_amount){ //click the chosen amount of times
macro_click();
Sleep(1000/click_amount);
counter1++;
}
counter1 = 0;
Sleep(burst_speed);
counter2++;
}
counter2 = 0;
}
else{ //if burst was not chosen
while(counter1 < click_amount){ //click the chosen amount of times
macro_click();
Sleep(1000/click_amount);
counter1++;
}
counter1 = 0;
}
}
if((GetKeyState(VK_END) & 0x80) != 0){ //if the end key is pressed, deactivate it
cout << "Tap macro paused" << endl;
tap_active = false;
Sleep(100);
}
Sleep(1);
}
if(!chat_active && !command_active){
if((GetKeyState(VK_HOME) & 0x80) != 0){ //if the home key is pressed, activate it
cout << "Tap macro activated" << endl;
tap_active = true;
Sleep(100);
}
}
Sleep(1);
}
return NULL;
}
void* normal(void* ignore){ //when you don't want to use any macros, but your fire button is middle click, and you still wanna left click
bool normal_active = false;
while(true){
while(normal_active){
if((GetKeyState(VK_LBUTTON) & 0x80) != 0){ //if the user left clicks
click(true); //fire
}
else{ //otherwise
unclick(true); //stop firing
}
if((GetKeyState(0x4C) & 0x80) != 0){ //if the "L" key is pressed, deactivate it
cout << "Normal macro paused" << endl;
normal_active = false;
Sleep(100);
}
Sleep(1);
}
if(!chat_active && !command_active){
if((GetKeyState(0x4B) & 0x80) != 0){ //if the "K" key is pressed, activate it
cout << "Normal macro activated" << endl;
normal_active = true;
Sleep(100);
}
}
Sleep(1);
}
return NULL;
}
void* catch_chat_command(void* ignore){ //if the user opens a command menu
Sleep(200); //stops it from catching the user entering macro settings
while(true){
if((GetKeyState(0x58) & 0x80) != 0){ //if the "Z" key is pressed
if(!command_active){ //if the menu was not open
command_active = true; //now it is
}
else if(command_active){ //if it was open
command_active = false; //now it's not
}
Sleep(200);
}
//Note: No need for a separate bool for each chat menu. If "X" is open, and "C" is pressed, "C" will open instead
if((GetKeyState(0x59) & 0x80) != 0){ //if the user presses the "X" key
if(!command_active){ //same idea as before
command_active = true;
}
else if(command_active){
command_active = false;
}
Sleep(200);
}
if((GetKeyState(0x5A) & 0x80) != 0){ //if the user presses the "C" key
if(!command_active){ //same idea as before
command_active = true;
}
else if(command_active){
command_active = false;
}
Sleep(200);
}
if((GetKeyState(VK_RETURN) & 0x80) != 0){ //if the user presses the "Enter/ Return" key
if(!chat_active){ //if the chat was not open
chat_active = true; //now it is
}
else if(chat_active){ //if it was open
chat_active = false; //now it's not
}
Sleep(200);
}
if(command_active){ //if a command menu is open
if((GetKeyState(0x30) & 0x80) != 0){ //if the user presses the 0 key,close it
command_active = false;
Sleep(200);
}
if((GetKeyState(0x31) & 0x80) != 0){ //if the user presses the 1 key,close it
command_active = false;
Sleep(200);
}
if((GetKeyState(0x32) & 0x80) != 0){ //if the user presses the 2 key,close it
command_active = false;
Sleep(200);
}
if((GetKeyState(0x33) & 0x80) != 0){ //if the user presses the 3 key,close it
command_active = false;
Sleep(200);
}
if((GetKeyState(0x34) & 0x80) != 0){ //if the user presses the 4 key,close it
command_active = false;
Sleep(200);
}
if((GetKeyState(0x35) & 0x80) != 0){ //if the user presses the 5 key,close it
command_active = false;
Sleep(200);
}
if((GetKeyState(0x36) & 0x80) != 0){ //if the user presses the 6 key,close it
command_active = false;
Sleep(200);
}
if((GetKeyState(0x37) & 0x80) != 0){ //if the user presses the 7 key,close it
command_active = false;
Sleep(200);
}
if((GetKeyState(0x38) & 0x80) != 0){ //if the user presses the 8 key,close it
command_active = false;
Sleep(200);
}
if((GetKeyState(0x39) & 0x80) != 0){ //if the user presses the 9 key,close it
command_active = false;
Sleep(200);
}
}
if(chat_active){ //if the chat is active
if((GetKeyState(VK_RETURN) & 0x80) != 0){ //if the "Return/ Enter" key is pressed, deactivate it
chat_active = false;
Sleep(200);
}
}
Sleep(1);
}
return NULL;
}
void setup(){ //prompts user for macro settings
scope_speed_milliseconds = choose_scope_speed(); //sets the scope speed
//==========================//
qswitch_key = choose_key(0); //chooses the quickswitch key
//==========================//
crouch_key = choose_key(1); //chooses the crouch key
//==========================//
walk_key = choose_key(2); //chooses the walk key
//==========================//
string response; //macro settings
cout << "Burst? (y/n) ";
cin >> response;
if(response == "y"){
burst = true;
cout << "Wait time between bursts? (in milliseconds) ";
cin >> burst_speed;
cout << "How many bursts? ";
cin >> burst_amount;
}
cout << "Clicks per second? ";
cin >> click_amount;
}
int main() //program STARTS here
{
setup(); //get settings
pthread_t qswitch_thread; //variables for threads
pthread_t qscope_thread;
pthread_t crouch_thread;
pthread_t walk_thread;
pthread_t tap_thread;
pthread_t normal_thread;
pthread_t catch_thread;
pthread_create(&qswitch_thread, NULL, &qswitch, NULL); //start each thread (using PTHREADS)
pthread_create(&qscope_thread, NULL, &qscope, NULL);
pthread_create(&crouch_thread, NULL, &crouch, NULL);
pthread_create(&walk_thread, NULL, &walk, NULL);
pthread_create(&tap_thread, NULL, &tap, NULL);
pthread_create(&normal_thread, NULL, &normal, NULL);
pthread_create(&catch_thread, NULL, &catch_chat_command, NULL);
while(true){
Sleep(1);
}
return 0;
}
This is actually an update I made to the currently-released program, but I didn't wanna make a new thread, or update the old one, so whoever compiles this gets the better version (adds a fix when you open the command menu/ chat and toggle a function with a number key, and adds a function to make your left mouse button click your middle if you don't have any macros toggled on).