stuff
This commit is contained in:
parent
4c2ad9e60e
commit
984385d92e
198
TODO
198
TODO
@ -1,67 +1,141 @@
|
|||||||
MULTIPLATFORM:
|
//==================================================================================================//
|
||||||
|
//Big TODO list for cathook //
|
||||||
Signature Scanner
|
//Organized by Julianacat //
|
||||||
Whole IPC thing | actually, no. cathook for windows WON'T have followbots/ipc.
|
//==================================================================================================//
|
||||||
Signatures and offsets
|
|
||||||
File handling (playerlist, spam, etc...)
|
|
||||||
CMake?
|
|
||||||
|
|
||||||
------------====-----------
|
|
||||||
|
|
||||||
|
|
||||||
TF2C teams
|
|
||||||
TF2C merc
|
|
||||||
HL2DM teams
|
|
||||||
|
|
||||||
fullbright toggle
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
Hunter Rifle
|
//Aimbot/Triggerbot //
|
||||||
TTS
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
namesteal
|
// //
|
||||||
autovote
|
Hook + Aimbot FIX // //
|
||||||
voice command spam (not like 1 voice command every 1 ms but like just spamming it on the menu)
|
// //
|
||||||
|
no aim sapper // //
|
||||||
|
// //
|
||||||
|
Make hacks respect Mannpower powerups and other conditions when calcuating damage, hitbox and prioritizing targets // //
|
||||||
|
Proper AutoHitbox, Isnt this already a thing?? // //
|
||||||
|
// //
|
||||||
|
Flare aim on fire // //
|
||||||
|
Improve Projectile Aimbot. A lot. // //
|
||||||
|
ProjPredOrigin // //
|
||||||
|
MAX -> MIN priority // //
|
||||||
|
// //
|
||||||
|
Hunter Rifle? // //
|
||||||
|
// //
|
||||||
|
AutoDetonator // //
|
||||||
|
// //
|
||||||
|
No AutoShoot when disguised // //
|
||||||
|
Ambassador bodyshotting // //
|
||||||
|
No Trigger Mediguns // //
|
||||||
|
More projectile weapons aimbot (wrap assassin, wrangler, stickybomb, airstrike) // //
|
||||||
|
Auto trigger DR before rockets // //
|
||||||
|
// //
|
||||||
|
Make make sentrys slightly lower priority (for getting those pesky turtle engies) // //
|
||||||
|
// //
|
||||||
|
Make building aimbot compensate for gravity on projectile weapons // //
|
||||||
|
// //
|
||||||
|
add Spectator Silent for projectile weapons // //
|
||||||
|
// //
|
||||||
|
Improve aimbot accuracy // //
|
||||||
|
// //
|
||||||
|
Add Multipoint (Take hitbox, shrink it, then use corners as points to check) // //
|
||||||
|
// //
|
||||||
|
Make ambasador check rely on wait for charge user setting // //
|
||||||
|
// //
|
||||||
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
|
// //
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dominatesay assistsay worldsay
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
AutoDetonator
|
//Visuals/GUI //
|
||||||
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
|
// //
|
||||||
|
Display on the left // //
|
||||||
|
// //
|
||||||
|
make gui color change // //
|
||||||
|
// //
|
||||||
|
Cheat status menu (A gui to display enabled/disabled states of user settings for when the menu is off) // //
|
||||||
|
// //
|
||||||
|
add teleporter count down // //
|
||||||
|
add spy cloak esp // //
|
||||||
|
// //
|
||||||
|
Make ubercharge esp color RGB when fully charged // //
|
||||||
|
// //
|
||||||
|
fullbright toggle // //
|
||||||
|
// //
|
||||||
|
FLAG ESP? // //
|
||||||
|
// //
|
||||||
|
ESP Icons // //
|
||||||
|
ESP Distance sort // //
|
||||||
|
Show sapped buildings in ESP // //
|
||||||
|
halloween medkits // //
|
||||||
|
carrying esp // //
|
||||||
|
Tracers/Spy Cam // //
|
||||||
|
// //
|
||||||
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
|
// //
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
|
|
||||||
ProjPredOrigin
|
|
||||||
MAX -> MIN priority
|
|
||||||
Deflected by enemy player
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
Aim Stickies
|
//Chat and Related //
|
||||||
FLAG ESP
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
no aim sapper
|
// //
|
||||||
Improve Projectile Aimbot. A lot.
|
TTS // //
|
||||||
Proper AutoHitbox
|
namesteal // //
|
||||||
Display on the left
|
autovote // //
|
||||||
Flare aim on fire
|
// //
|
||||||
Aim Sticky
|
dominatesay assistsay worldsay // //
|
||||||
Proj Pred visuals
|
InsultSpam // //
|
||||||
Hook + Aimbot FIX
|
// //
|
||||||
ESP Icons
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
ESP Distance sort
|
// //
|
||||||
Show sapped buildings in ESP
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
Make hacks respect Mannpower powerups and other conditions when calcuating damage, hitbox and prioritizing targets
|
|
||||||
Fake Lag
|
|
||||||
Engine Prediction
|
|
||||||
AutoSticky improve
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
No AutoShoot when disguised
|
//Followbots //
|
||||||
Ambassador bodyshotting
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
No Trigger Mediguns
|
// //
|
||||||
More projectile weapons aimbot (wrap assassin, wrangler, stickybomb, airstrike)
|
Proper medic followbot AI, breadcrumb followbot is good but a nav system would be better // //
|
||||||
Auto trigger DR before rockets
|
// //
|
||||||
Sticky vischeck
|
Bot option for aiming at owner's prey (just for fun) // //
|
||||||
InsultSpam
|
Bot pathfinding & navigation files system // //
|
||||||
Critical rifles bodyshotting
|
Proper entity classes (actually I might just use a lot of helper functions taking IClientEntity* as first arg) // //
|
||||||
FLAG ESP
|
// //
|
||||||
Spy alert uses angles
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
halloween medkits
|
// //
|
||||||
carrying esp
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
Tracers/Spy Cam
|
|
||||||
Bodyshot if not zoomed
|
|
||||||
Proper medic followbot AI
|
|
||||||
Bot option for aiming at owner's prey (just for fun)
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
Bot pathfinding & navigation files system
|
//Misc //
|
||||||
Proper entity classes (actually I might just use a lot of helper functions taking IClientEntity* as first arg)
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
Priority system optimization and testing
|
// //
|
||||||
General optimization and refactoring
|
Proper Fake Lag // //
|
||||||
Bone ESP
|
Add auto-strafe // //
|
||||||
XorString or something to make it harder to detect.
|
// //
|
||||||
|
Fix achievement hack getting blocked with sv_cheats // //
|
||||||
|
// //
|
||||||
|
Spy alert uses angles // //
|
||||||
|
// //
|
||||||
|
Add ignore gunslinger to melee crit hack // //
|
||||||
|
// //
|
||||||
|
Priority system optimization and testing // //
|
||||||
|
General optimization and refactoring // //
|
||||||
|
// //
|
||||||
|
XorString or something to make it harder to detect. // //
|
||||||
|
// //
|
||||||
|
TF2C teams // //
|
||||||
|
TF2C merc // //
|
||||||
|
HL2DM teams // //
|
||||||
|
// //
|
||||||
|
//------------------------------------------------------------------------------------------------------------------// //
|
||||||
|
// //
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------//
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 94a287d6faa00d44e1084b04e602842849858443
|
Subproject commit e532876ffd707a48389d54ff904dcc40a84f2839
|
@ -77,6 +77,9 @@ void CreateMove() {
|
|||||||
// Check user settings if auto-sticky is enabled
|
// Check user settings if auto-sticky is enabled
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
|
|
||||||
|
// Check if game is a tf game
|
||||||
|
IF_GAME (!IsTF()) return;
|
||||||
|
|
||||||
// Check if player is demoman
|
// Check if player is demoman
|
||||||
if (g_pLocalPlayer->clazz != tf_demoman) return;
|
if (g_pLocalPlayer->clazz != tf_demoman) return;
|
||||||
|
|
||||||
|
@ -13,6 +13,19 @@
|
|||||||
|
|
||||||
namespace hacks { namespace shared { namespace followbot {
|
namespace hacks { namespace shared { namespace followbot {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Big Followbot TODO list
|
||||||
|
1. Fix crash when setting followbot_idx var and remove the fix var in its place
|
||||||
|
2. Test with followbots to ensure that vector followbot and crumb followbot work as intended
|
||||||
|
3. Clean the finished code and push to main from fork
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// User settings
|
// User settings
|
||||||
CatVar bot(CV_SWITCH, "fb_bot", "0", "Master Followbot Switch", "Set to 1 in followbots' configs");
|
CatVar bot(CV_SWITCH, "fb_bot", "0", "Master Followbot Switch", "Set to 1 in followbots' configs");
|
||||||
CatVar follow_distance(CV_FLOAT, "fb_follow_distance", "175", "Followbot Follow Distance", "How close the bots should stay to the target");
|
CatVar follow_distance(CV_FLOAT, "fb_follow_distance", "175", "Followbot Follow Distance", "How close the bots should stay to the target");
|
||||||
@ -50,7 +63,7 @@ bool destination_reached { false };
|
|||||||
|
|
||||||
// Vars for breadcrumb followbot
|
// Vars for breadcrumb followbot
|
||||||
// An array for storing the breadcrumbs
|
// An array for storing the breadcrumbs
|
||||||
Vector breadcrumbs [55];
|
static Vector breadcrumbs [55];
|
||||||
// Array Bookkeeping vars
|
// Array Bookkeeping vars
|
||||||
int crumbBottom = 0;
|
int crumbBottom = 0;
|
||||||
int crumbTop = 0;
|
int crumbTop = 0;
|
||||||
@ -112,8 +125,8 @@ void DoWalking() {
|
|||||||
// Get our best target, preferably from a steamid
|
// Get our best target, preferably from a steamid
|
||||||
|
|
||||||
//following_idx = 0;
|
//following_idx = 0;
|
||||||
CachedEntity* best_target = 0;
|
CachedEntity* best_target = nullptr;
|
||||||
CachedEntity* target_priority = 0;
|
CachedEntity* target_priority = nullptr;
|
||||||
|
|
||||||
// Get ent from steamid
|
// Get ent from steamid
|
||||||
for (int i = 1; i < HIGHEST_ENTITY; i++) {
|
for (int i = 1; i < HIGHEST_ENTITY; i++) {
|
||||||
@ -165,7 +178,7 @@ void DoWalking() {
|
|||||||
|
|
||||||
float target_highest_score = -256;
|
float target_highest_score = -256;
|
||||||
CachedEntity* ent;
|
CachedEntity* ent;
|
||||||
target_last = 0;
|
target_last = nullptr;
|
||||||
crumbStopped = true;
|
crumbStopped = true;
|
||||||
|
|
||||||
for (int i = 0; i < HIGHEST_ENTITY; i++) {
|
for (int i = 0; i < HIGHEST_ENTITY; i++) {
|
||||||
@ -193,6 +206,9 @@ void DoWalking() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CachedEntity* found_entity = best_target;
|
CachedEntity* found_entity = best_target;
|
||||||
|
// TODO, setting following_idx causes a crash for an unknown reason, probs to do with autoheal.
|
||||||
|
// I created a different var to take its place and prevent the crash but i need to fix the crash with the externed var.
|
||||||
|
// For now this works and it will stay like this untill i fix it
|
||||||
int following_idx2 = 0;
|
int following_idx2 = 0;
|
||||||
if (CE_GOOD(found_entity)) {
|
if (CE_GOOD(found_entity)) {
|
||||||
following_idx2 = found_entity->m_IDX;
|
following_idx2 = found_entity->m_IDX;
|
||||||
@ -206,8 +222,10 @@ void DoWalking() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Slot Changer/Mimicer
|
// Slot Changer/Mimicer
|
||||||
logging::Info("Slot changer");
|
|
||||||
// Set a static var for last slot check
|
// Set a static var for last slot check
|
||||||
static float last_slot_check = 0.0f;
|
static float last_slot_check = 0.0f;
|
||||||
|
|
||||||
@ -252,9 +270,12 @@ void DoWalking() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
logging::Info("Start follow");
|
|
||||||
|
|
||||||
|
|
||||||
// Main followbot code
|
// Main followbot code
|
||||||
if (allow_moving) {
|
if (allow_moving) {
|
||||||
|
|
||||||
// Switch to different types of following mechanisms depending on the type we need to go to
|
// Switch to different types of following mechanisms depending on the type we need to go to
|
||||||
switch (current_follow_type) {
|
switch (current_follow_type) {
|
||||||
case EFollowType::VECTOR: // If were using a vector to follow, we just go directly to it
|
case EFollowType::VECTOR: // If were using a vector to follow, we just go directly to it
|
||||||
@ -274,7 +295,7 @@ void DoWalking() {
|
|||||||
case EFollowType::ENTITY: // If were using a player to follow, we use the breadcrumb followbot
|
case EFollowType::ENTITY: // If were using a player to follow, we use the breadcrumb followbot
|
||||||
|
|
||||||
if (CE_GOOD(found_entity)) {
|
if (CE_GOOD(found_entity)) {
|
||||||
//If the bot is lost but it finds the player again, start the followbot again.
|
// If the bot is lost but it finds the player again, start the followbot again.
|
||||||
if (crumbStopped) {
|
if (crumbStopped) {
|
||||||
crumbForceMove = true;
|
crumbForceMove = true;
|
||||||
CrumbReset();
|
CrumbReset();
|
||||||
@ -311,7 +332,7 @@ void DoWalking() {
|
|||||||
// Check 15 times for close crumbs to prune, this allows simple miss steps to be smoothed out as well as make room for new crumbs
|
// Check 15 times for close crumbs to prune, this allows simple miss steps to be smoothed out as well as make room for new crumbs
|
||||||
for (int i = 0; i < 15; i++) {
|
for (int i = 0; i < 15; i++) {
|
||||||
|
|
||||||
//When one is close or too high, just bump the array and reset the stuck timer
|
// When one is close or too high, just bump the array and reset the stuck timer
|
||||||
if (g_pLocalPlayer->v_Origin.DistTo(breadcrumbs[crumbBottom]) < 60.0F && crumbArrayLength > 1) {
|
if (g_pLocalPlayer->v_Origin.DistTo(breadcrumbs[crumbBottom]) < 60.0F && crumbArrayLength > 1) {
|
||||||
CrumbBottomAdd();
|
CrumbBottomAdd();
|
||||||
|
|
||||||
@ -563,7 +584,7 @@ void WalkTo(const Vector& vector) {
|
|||||||
// Set idle time if we havent already
|
// Set idle time if we havent already
|
||||||
if (!idle_time) idle_time = g_GlobalVars->curtime;
|
if (!idle_time) idle_time = g_GlobalVars->curtime;
|
||||||
// If the vector is too high for the local player to reach,
|
// If the vector is too high for the local player to reach,
|
||||||
if (vector.z - LOCAL_E->m_vecOrigin.z > 30.0f) {
|
if (vector.z - LOCAL_E->m_vecOrigin.z > 15.0f) {
|
||||||
// If the time idle is over 2 seconds
|
// If the time idle is over 2 seconds
|
||||||
if (g_GlobalVars->curtime - idle_time > 2.0f) {
|
if (g_GlobalVars->curtime - idle_time > 2.0f) {
|
||||||
// If the player isnt zoomed, then jump
|
// If the player isnt zoomed, then jump
|
||||||
@ -603,7 +624,7 @@ std::pair<float, float> ComputeMove(const Vector& a, const Vector& b) {
|
|||||||
|
|
||||||
// Crumb Followbot Helper functions
|
// Crumb Followbot Helper functions
|
||||||
|
|
||||||
//A function to reset the crumb followbot
|
// A function to reset the crumb followbot
|
||||||
void CrumbReset() {
|
void CrumbReset() {
|
||||||
|
|
||||||
//A check to make sure using the fb tool repeatedly doesnt clear the cache of crumbs
|
//A check to make sure using the fb tool repeatedly doesnt clear the cache of crumbs
|
||||||
@ -679,7 +700,14 @@ void Draw() {
|
|||||||
|
|
||||||
// A Function for when we want to draw out the crumbs in the array onto the screen
|
// A Function for when we want to draw out the crumbs in the array onto the screen
|
||||||
void DrawFollowbot() {
|
void DrawFollowbot() {
|
||||||
|
|
||||||
|
// Usefull debug info to know
|
||||||
|
AddSideString(format("Array Length: ", crumbArrayLength));
|
||||||
|
AddSideString(format("Top Crumb: ", crumbTop));
|
||||||
|
AddSideString(format("Bottom Crumb: ", crumbBottom));
|
||||||
|
|
||||||
|
// Disabled as the enum was misbeghaving for an unknown reason
|
||||||
|
|
||||||
/*switch (current_follow_type) {
|
/*switch (current_follow_type) {
|
||||||
case EFollowType::VECTOR: // If our follow type is a vector, then we just draw a rect on the vector
|
case EFollowType::VECTOR: // If our follow type is a vector, then we just draw a rect on the vector
|
||||||
|
|
||||||
@ -738,9 +766,7 @@ void DrawFollowbot() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}*/
|
}*/
|
||||||
AddSideString(format("Array Length: ", crumbArrayLength));
|
|
||||||
AddSideString(format("Top Crumb: ", crumbTop));
|
|
||||||
AddSideString(format("Bottom Crumb: ", crumbBottom));
|
|
||||||
// Not using switch due to switch not working
|
// Not using switch due to switch not working
|
||||||
if (crumbArrayLength < 2) {
|
if (crumbArrayLength < 2) {
|
||||||
|
|
||||||
|
@ -14,8 +14,13 @@ static CatEnum spam_enum({"DISABLED", "CUSTOM", "DEFAULT", "LENNYFACES", "BLANKS
|
|||||||
CatVar spam_source(spam_enum, "spam", "0", "Chat Spam", "Defines source of spam lines. CUSTOM spam file must be set in cat_spam_file and loaded with cat_spam_reload (Use console!)");
|
CatVar spam_source(spam_enum, "spam", "0", "Chat Spam", "Defines source of spam lines. CUSTOM spam file must be set in cat_spam_file and loaded with cat_spam_reload (Use console!)");
|
||||||
CatVar random_order(CV_SWITCH, "spam_random", "0", "Random Order");
|
CatVar random_order(CV_SWITCH, "spam_random", "0", "Random Order");
|
||||||
CatVar filename(CV_STRING, "spam_file", "spam.txt", "Spam file", "Spam file name. Each line should be no longer than 100 characters, file must be located in cathook data folder");
|
CatVar filename(CV_STRING, "spam_file", "spam.txt", "Spam file", "Spam file name. Each line should be no longer than 100 characters, file must be located in cathook data folder");
|
||||||
CatVar teamname_spam(CV_SWITCH, "spam_teamname", "0", "Teamname Spam", "Spam changes the tournament name");
|
|
||||||
CatCommand reload("spam_reload", "Reload spam file", Reload);
|
CatCommand reload("spam_reload", "Reload spam file", Reload);
|
||||||
|
|
||||||
|
static CatEnum voicecommand_enum({"DISABLED", "RANDOM", "MEDIC", "THANKS", "NICE SHOT", "CHEERS", "JEERS"});
|
||||||
|
CatVar voicecommand_spam(voicecommand_enum, "spam_voicecommand", "0", "Voice Command Spam", "Spams tf voice commands");
|
||||||
|
|
||||||
|
CatVar teamname_spam(CV_SWITCH, "spam_teamname", "0", "Teamname Spam", "Spam changes the tournament name");
|
||||||
|
|
||||||
|
|
||||||
bool teamname_swap = false;
|
bool teamname_swap = false;
|
||||||
int current_index { 0 };
|
int current_index { 0 };
|
||||||
@ -24,6 +29,8 @@ TextFile file {};
|
|||||||
|
|
||||||
const std::string teams[] = { "RED", "BLU" };
|
const std::string teams[] = { "RED", "BLU" };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// FUCK enum class.
|
// FUCK enum class.
|
||||||
// It doesn't have bitwise operators by default!! WTF!! static_cast<int>(REEE)!
|
// It doesn't have bitwise operators by default!! WTF!! static_cast<int>(REEE)!
|
||||||
|
|
||||||
@ -166,15 +173,46 @@ bool FormatSpamMessage(std::string& message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CreateMove() {
|
void CreateMove() {
|
||||||
if (teamname_spam) {
|
|
||||||
if (teamname_swap) {
|
IF_GAME (IsTF2()) {
|
||||||
teamname_swap = false;
|
// Spam changes the tournament name in casual and compeditive gamemodes
|
||||||
g_IEngine->ServerCmd("tournament_teamname Cat");
|
if (teamname_spam) {
|
||||||
} else {
|
if (teamname_swap) {
|
||||||
teamname_swap = true;
|
teamname_swap = false;
|
||||||
g_IEngine->ServerCmd("tournament_teamname Hook");
|
g_IEngine->ServerCmd("tournament_teamname Cat");
|
||||||
}
|
} else {
|
||||||
|
teamname_swap = true;
|
||||||
|
g_IEngine->ServerCmd("tournament_teamname Hook");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (voicecommand_spam) {
|
||||||
|
static float last_voice_spam = 0.0f;
|
||||||
|
if (g_GlobalVars->curtime - 4.0F > last_voice_spam) {
|
||||||
|
switch ((int)voicecommand_spam) {
|
||||||
|
case 1: // RANDOM
|
||||||
|
g_IEngine->ServerCmd(format("voicemenu ", floor(RandFloatRange(0, 2.9)), " ", floor(RandFloatRange(0, 8.9))).c_str());
|
||||||
|
break;
|
||||||
|
case 2: // MEDIC
|
||||||
|
g_IEngine->ServerCmd("voicemenu 0 0");
|
||||||
|
break;
|
||||||
|
case 3: // THANKS
|
||||||
|
g_IEngine->ServerCmd("voicemenu 0 1");
|
||||||
|
break;
|
||||||
|
case 4: // NICE SHOT
|
||||||
|
g_IEngine->ServerCmd("voicemenu 2 6");
|
||||||
|
break;
|
||||||
|
case 5: // CHEERS
|
||||||
|
g_IEngine->ServerCmd("voicemenu 2 2");
|
||||||
|
break;
|
||||||
|
case 6: // JEERS
|
||||||
|
g_IEngine->ServerCmd("voicemenu 2 3");
|
||||||
|
}
|
||||||
|
last_voice_spam = g_GlobalVars->curtime;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!spam_source) return;
|
if (!spam_source) return;
|
||||||
static int safety_ticks = 0;
|
static int safety_ticks = 0;
|
||||||
static int last_spam = 0;
|
static int last_spam = 0;
|
||||||
|
Reference in New Issue
Block a user