// GPL License - see http://opensource.org/licenses/gpl-license.php // Copyright 2006 *nixCoders team - don't forget to credit us #include #include "eth.h" /* ============================== Some utils functions ============================== */ int getSpawntimer(qboolean enemySpawn) { int team = eth.clientInfo[eth.cg_snap->ps.clientNum].team; int limbotime = 0; // Reverse the value from clientinfo[myself].team to make the function return the spawn time of the other team if(enemySpawn == qtrue) { if (team == TEAM_AXIS) { team = TEAM_ALLIES; limbotime = eth.cg_bluelimbotime; } else if (team == TEAM_ALLIES) { team = TEAM_AXIS; limbotime = eth.cg_redlimbotime; } else return -1; } else { if (team == TEAM_AXIS) { limbotime = eth.cg_redlimbotime; } else if (team == TEAM_ALLIES) { limbotime = eth.cg_bluelimbotime; } else return -1; } // Sanity check if (limbotime == 0) { ethLog("warning: can't get spawntimer for team %i", team); return -1; } return (int)(1 + (limbotime - ((eth.cgs_aReinfOffset[team] + eth.cg_time - eth.cgs_levelStartTime) % limbotime)) * 0.001f); } int findSatchel() { int entityNum = 0; for (; entityNum < MAX_GENTITIES; entityNum++) { if ((eth.cg_entities[entityNum].currentState->weapon == WP_SATCHEL) && (eth.cg_entities[entityNum].currentState->clientNum == eth.cg_snap->ps.clientNum) && (!VectorCompare(eth.entities[entityNum].origin, vec3_origin))) return entityNum; } #ifdef ETH_DEBUG ethDebug("satchel cam: don't find satchel for %i", eth.cg_snap->ps.clientNum); #endif return -1; } qboolean isKeyActionDown(char *action) { int key1, key2; orig_syscall(CG_KEY_BINDINGTOKEYS, action, &key1, &key2); if (syscall_CG_Key_IsDown(key1) || syscall_CG_Key_IsDown(key2)) return qtrue; else return qfalse; } int getIdByName (const char *name, int len) { int i; if (!len) len = strlen(name); for (i=0; i < MAX_CLIENTS; i++) if (eth.clientInfo[i].infoValid && !strncmp(eth.clientInfo[i].name, name, len)) return i; return -1; } qboolean isVisible(vec3_t target) { trace_t trace; eth.CG_Trace(&trace, eth.cg_refdef.vieworg, NULL, NULL, target, eth.cg_snap->ps.clientNum, CONTENTS_SOLID | CONTENTS_CORPSE); return (trace.fraction == 1.0f); } qboolean isPlayerVisible(vec3_t target, int player) { trace_t traceVisible; eth.CG_Trace(&traceVisible, eth.cg_refdef.vieworg, NULL, NULL, target, eth.cg_snap->ps.clientNum, CONTENTS_SOLID | CONTENTS_CORPSE); trace_t tracePlayer; eth.CG_Trace(&tracePlayer, eth.cg_refdef.vieworg, NULL, NULL, target, eth.cg_snap->ps.clientNum, CONTENTS_SOLID | CONTENTS_BODY); //printf("XXX: want %i got %i\n", player, tracePlayer.entityNum); return ((traceVisible.fraction == 1.0f) && (tracePlayer.entityNum == player)); } void ethLog(const char *format, ...) { printf("eth: "); va_list arglist; va_start(arglist, format); vprintf(format, arglist); va_end(arglist); printf("\n"); #ifdef ETH_DEBUG // If log file if (debugFile) { fprintf(debugFile, "log: "); va_list arglist; va_start(arglist, format); vfprintf(debugFile, format, arglist); va_end(arglist); fprintf(debugFile, "\n"); } #endif } #ifdef ETH_DEBUG FILE *debugFile = NULL; void ethDebug(const char *format, ...) { // If log file if (debugFile) { va_list arglist; va_start(arglist, format); vfprintf(debugFile, format, arglist); va_end(arglist); fprintf(debugFile, "\n"); } } #endif // ETH_DEBUG void fatalError(const char *msg) { char str[256]; snprintf(str, sizeof(str), "A fatal error has occured. You must restart the game.\n\nError: %s\n\n\n*nixCoders eth-v%s", msg, ETH_VERSION); orig_syscall(CG_ERROR, str); #ifdef ETH_DEBUG ethLog("fatal error: %s", msg); #endif } // Helper function for get ouput of a system command // This function return the first line of this command output char *getOutputSystemCommand(const char *command) { static char buf[256]; memset(buf, 0, sizeof(buf)); FILE *cmd = popen(command, "r"); int c; int count = 0; while (((c = getc(cmd)) != EOF) && (count < (sizeof(buf) - 1))) { if (c == '\n') break; buf[count++] = c; } pclose(cmd); return buf; } // If cgame is load, send a UI_PRINT message else just show a message at console, // WARNING ! use this function only when call from ui vmMain. ex: irc and game command #define MESSAGE_COLOR "^n" void gameMessage(qboolean forceConsole, char *format, ...) { char msg[MAX_SAY_TEXT]; memset(msg, 0, sizeof(msg)); char buffer[sizeof(msg)]; memset(buffer, 0, sizeof(buffer)); va_list arglist; va_start(arglist, format); vsnprintf(msg, sizeof msg, format, arglist); va_end(arglist); if (eth.hookLoad && !forceConsole) { snprintf(buffer, sizeof(buffer), "echo \"" MESSAGE_COLOR "%s\"\n", msg); orig_syscall(UI_CMD_EXECUTETEXT, EXEC_APPEND, buffer); } else { snprintf(buffer, sizeof(buffer), MESSAGE_COLOR "%s\n", msg); orig_syscall(UI_PRINT, buffer); } } void doAutoVote(char *str) { char *ptr = strstr(str, "^7 called a vote. Voting for: "); int id = getIdByName(str, ptr - str); // id not found if (id == -1) return; // who votes switch (eth.clientInfo[id].targetType) { case PLIST_FRIEND: syscall_CG_SendConsoleCommand("vote yes\n"); return; case PLIST_TEAMKILLER: syscall_CG_SendConsoleCommand("vote no\n"); return; default: break; } // Voter is not a friend/teamkiller ptr += strlen("^7 called a vote. Voting for: "); if (!strncmp(ptr, "KICK ", 5) || !strncmp(ptr, "MUTE ", 5)) { ptr += 5; id = getIdByName(ptr, strrchr(ptr, '\n') - ptr); // id not found if (id == -1) return; // vote against client if (id == eth.cg_clientNum) { syscall_CG_SendConsoleCommand("vote no\n"); return; } // who is voted against switch (eth.clientInfo[id].targetType) { case PLIST_FRIEND: syscall_CG_SendConsoleCommand("vote no\n"); return; case PLIST_TEAMKILLER: syscall_CG_SendConsoleCommand("vote yes\n"); return; default: break; } } } // Auto request medic #define TIME_BETWEEN_REQUEST 5000 void autoRequestMedic() { if (eth.cg_snap->ps.clientNum != eth.cg_clientNum) return; static int lastRequestTime = 0; if (lastRequestTime + TIME_BETWEEN_REQUEST > eth.cg_time) return; // If need revive if (eth.cg_entities[eth.cg_clientNum].currentState->eFlags & EF_DEAD) { int vsay = (int)(2.0f * (rand() / (RAND_MAX + 1.0f))); if (!vsay) syscall_CG_SendConsoleCommand("vsay_team Medic\n"); else syscall_CG_SendConsoleCommand("vsay FTReviveMe\n"); lastRequestTime = eth.cg_time; // If need health } else if (eth.cg_snap->ps.stats[STAT_HEALTH] < 40) { int vsay = (int)(2.0f * (rand() / (RAND_MAX + 1.0f))); if (!vsay) syscall_CG_SendConsoleCommand("vsay_team Medic\n"); else syscall_CG_SendConsoleCommand("vsay FTHealMe\n"); lastRequestTime = eth.cg_time; } } // Calc muzzle // kobj fixed the muzzle thing :D (Hooked server bullet_fire, and they match) void setCurrentMuzzle() { VectorCopy(eth.cg_refdef.vieworg, eth.muzzle); if(eth.cg_snap->ps.viewangles[PITCH] > 30 && (eth.cg_snap->ps.eFlags & EF_CROUCHING)) eth.muzzle[2] += 30.0 - eth.cg_snap->ps.viewheight; SnapVector( eth.muzzle ); } qboolean isAimbotWeapon(int weapon){ switch( weapon ){ case WP_AMMO: case WP_ARTY: case WP_MEDIC_SYRINGE: case WP_DYNAMITE: case WP_SMOKETRAIL: case WP_MAPMORTAR: case WP_MEDKIT: case WP_BINOCULARS: case WP_PLIERS: case WP_LANDMINE: case WP_SATCHEL: case WP_TRIPMINE: case WP_SMOKE_BOMB: case WP_MORTAR: case WP_MEDIC_ADRENALINE: return qfalse; default: return qtrue; } } //Speedshooting for single shot weapons :D qboolean isSingleShootWeapon(){ int weapon = eth.cg_entities[eth.cg_clientNum].currentState->weapon; switch( weapon ){ case WP_K43: case WP_GARAND: case WP_CARBINE: case WP_KAR98: case WP_LUGER: case WP_SILENCER: case WP_AKIMBO_LUGER: case WP_AKIMBO_SILENCEDLUGER: case WP_COLT: case WP_SILENCED_COLT: case WP_AKIMBO_COLT: case WP_AKIMBO_SILENCEDCOLT: return qtrue; default: return qfalse; } } /* ============================== Config stuff ============================== */ char *getConfigFilename() { // If config filename is set by enviromment var if (getenv("ETH_CONF_FILE")) return getenv("ETH_CONF_FILE"); static char filename[PATH_MAX]; snprintf(filename, sizeof(filename), "%s/%s", getenv("HOME"), ETH_CONFIG_FILE); return filename; } void readConfig() { FILE *file; // Init all user vars with the default value int count = 0; for (; count < VARS_TOTAL; count++) seth.value[count] = seth.vars[count].defaultValue; if ((file = fopen(getConfigFilename(), "rb")) == NULL) return; // Get config file line by line char line[1024]; while (fgets(line, sizeof(line) - 1, file) != 0) { char *sep = strrchr(line, '='); *sep = '\0'; // Separate name from value if( !sep ) fatalError("Config error. Check your config file!"); // Search this var int count = 0; if( !strcmp(line,"ksFormat") ){ strncpy(dieFormat, Q_ValidStr(sep+1), sizeof(ksFormat)); } else if( !strcmp(line,"dieFormat") ) { strncpy(dieFormat, Q_ValidStr(sep+1), sizeof(ksFormat)); } else if( !strcmp(line,"bnFormat") ) { strncpy(bnFormat, Q_ValidStr(sep+1), sizeof(ksFormat)); } else if( !strcmp(line,"skFormat") ) { strncpy(skFormat, Q_ValidStr(sep+1), sizeof(ksFormat)); } else { for (; count < VARS_TOTAL; count++) { if (!seth.vars[count].cvarName) { ethLog("readConfig: error: VAR_%i undefine", count); } else if (!strcmp(line, seth.vars[count].cvarName)) { seth.value[count] = atof(sep + 1); break; } else if ((count + 1) == VARS_TOTAL) { ethLog("readConfig: don't know this var: [%s]", line); } if (count == VAR_CHUD) if (atoi(sep + 1)) syscall_CG_SendConsoleCommand(va("cg_draw2d %s\n", seth.value[count] ? "0" : "1")); } } } fclose(file); } void writeConfig() { FILE *file; if ((file = fopen(getConfigFilename(), "w")) == NULL) { ethLog("eth: can't write config file."); return; } int count = 0; fprintf(file,"ksFormat=%s\n",ksFormat); fprintf(file,"bnFormat=%s\n",bnFormat); fprintf(file,"dieFormat=%s\n",dieFormat); fprintf(file,"skFormat=%s\n",skFormat); for (; count < VARS_TOTAL; count++) { if (!seth.vars[count].cvarName) ethLog("writeConfig: error: VAR_%i undefine", count); else if (seth.value[count] == (float)(int)seth.value[count]) fprintf(file, "%s=%i\n", seth.vars[count].cvarName, (int)seth.value[count]); else fprintf(file, "%s=%.2f\n", seth.vars[count].cvarName, seth.value[count]); } fclose(file); } /* ============================== Console actions ============================== */ void initActions() { eth.actions[ACTION_ATTACK] = (ethAction_t){ 0, 0, "+attack\n", "-attack\n" }; eth.actions[ACTION_BACKWARD] = (ethAction_t){ 0, 0, "+backward\n", "-backward\n" }; eth.actions[ACTION_BINDMOUSE1] = (ethAction_t){ 1, 1, "bind mouse1 +attack\n", "unbind mouse1\n" }; eth.actions[ACTION_CROUCH] = (ethAction_t){ 0, 0, "+movedown\n", "-movedown\n" }; eth.actions[ACTION_JUMP] = (ethAction_t){ 0, 0, "+moveup\n", "-moveup\n" }; eth.actions[ACTION_PRONE] = (ethAction_t){ 0, 0, "+prone; -prone\n", "+moveup; -moveup\n" }; eth.actions[ACTION_RUN] = (ethAction_t){ 0, 0, "+sprint; +movedown; +forward\n", "-sprint; -forward\n" }; eth.actions[ACTION_SCOREBOARD] = (ethAction_t){ 0, 0, "cg_draw2d 1; +scores\n", "-scores; cg_draw2d 0\n" }; eth.actions[ACTION_RELOAD] = (ethAction_t){ 0, 0, "+reload\n", "-reload\n" }; } // Set an action if not already set. void setAction(int action, int state) { if (state && !eth.actions[action].state) forceAction(action, state); else if (!state && eth.actions[action].state) forceAction(action, state); } // Use this with caution void forceAction(int action, int state) { if (state) { eth.actions[action].state = 1; syscall_CG_SendConsoleCommand(eth.actions[action].startAction); #ifdef ETH_DEBUG ethDebug("forceAction: %s", eth.actions[action].startAction); #endif } else { eth.actions[action].state = 0; syscall_CG_SendConsoleCommand(eth.actions[action].stopAction); #ifdef ETH_DEBUG ethDebug("forceAction: %s", eth.actions[action].stopAction); #endif } } void resetAllActions() { int action; for (action=0; action spreeLevelMax) level = spreeLevelMax; int levelSize = spreeLevels[level].end - spreeLevels[level].start; int sound = (int)((float)(levelSize + 1) * rand() / (RAND_MAX + 1.0f)); sound += spreeLevels[level].start; eth.spreelevel = sound; eth.startFadeTime = eth.cg_time; eth.s_level = level; orig_syscall(CG_S_STARTLOCALSOUND, eth.sounds[sound], CHAN_LOCAL_SOUND, 230); } } /* replaces tokens with correct value and returns pointer parsed string [c] - current spree count [v] - victim name [n] - clean victim name [t] - total kills [m] - double/triple/multikill msg [x] - Player XP [p] - Player name [M] - Mod name [h] - Player health [k] - Killer name [K] - Clean killer name [q] - amount of punkbuster screenshots requested */ char *Format(char *in){ char out[256]; memset(out, 0, sizeof(out)); int a, b, len = strlen(in); for (a = 0, b = 0; a < len; a++) { if ((a <= len-2) && (in[a] == '[' && in[a+2] == ']')) { switch (in[a+1]) { case 'v': strncat(out, eth.VictimName, sizeof(out)); break; case 'n': strncat(out, Q_CleanStr(eth.VictimName), sizeof(out)); break; case 't': strncat(out, va("%i", eth.killCount), sizeof(out)); break; case 'x': strncat(out, va("%i", eth.cg_snap->ps.stats[STAT_XP]), sizeof(out)); break; case 'q': strncat(out, va("%i", eth.pbss), sizeof(out)); break; case 'p': strncat(out, eth.clientInfo[eth.cg_clientNum].name, sizeof(out)); break; case 'M': { char gameMod[20]; syscall_CG_Cvar_VariableStringBuffer("fs_game", gameMod, sizeof(gameMod)); strncat(out, gameMod, sizeof(out)); break; } case 'k': strncat(out, eth.KillerName, sizeof(out)); break; case 'K': { char *c = strdup(eth.KillerName); strncat(out, Q_CleanStr(c) , sizeof(out)); free(c); break; } case 'h': strncat(out, va("%i", eth.cg_snap->ps.stats[STAT_HEALTH]), sizeof(out)); break; case 'c': strncat(out, va("%i", eth.killCountNoDeath), sizeof(out)); break; case '1': { char *multikillmsg ; if (eth.killSpreeCount == 2) { multikillmsg = " ^1*** DOUBLEKILL***^7"; } else if (eth.killSpreeCount == 3) { multikillmsg = " ^1*** MULTIKILL***^7"; } else if (eth.killSpreeCount == 4) { multikillmsg = " ^1*** ULTRAKILL***^7"; } else if (eth.killSpreeCount == 5) { multikillmsg = " ^1*** MONSTERKILL***^7"; } else if (eth.killSpreeCount > 5) { multikillmsg = " ^1*** HOLY SHIT***^7"; } else break; if (eth.killSpreeCount >= 2) sprintf(out, "^2%s ^7was owned! %s ", eth.VictimName, multikillmsg); break; } case '2': { char *multikillmsg; if (eth.killSpreeCount == 2) { multikillmsg = "^1"; } else if (eth.killSpreeCount == 3) { multikillmsg = "^1"; } else if (eth.killSpreeCount == 4) { multikillmsg = "^1"; } else if (eth.killSpreeCount > 4) { multikillmsg = "^1"; } else break; if (eth.killSpreeCount >= 2) sprintf(out, "%s ", multikillmsg); break; } case '3': { char *multikillmsg; if (eth.killSpreeCount == 2) { multikillmsg = " ^7::: ^2Doublekill ^7:::"; } else if (eth.killSpreeCount == 3) { multikillmsg = " ^7::: ^2Multikill ^7:::"; } else if (eth.killSpreeCount == 4) { multikillmsg = " ^7::: ^2Ultrakill ^7:::"; } else if (eth.killSpreeCount >= 5) { multikillmsg = " ^7::: ^2Monsterkill ^7:::"; } else break; if (eth.killSpreeCount >= 2) sprintf(out, "%s ", multikillmsg); break; } case 'e': { char *msg; if (eth.killCountNoDeath == 10) { msg = "^7... is ^/tied for the lead! ^%(10 frags in a row)"; } else if (eth.killCountNoDeath == 15) { msg = "^7... has ^/taken the lead! ^%(15 frags in a row)"; } else if (eth.killCountNoDeath == 20) { msg = "^7... is on a ^/KILLING SPREE!!! ^%(20 frags in a row)"; } else if (eth.killCountNoDeath == 25) { msg = "^7... is ^/DOMINATING!!! ^%(25 frags in a row)"; } else if (eth.killCountNoDeath == 30) { msg = "^7... is on a ^/RAMPAGE!!! ^%(30 frags in a row)"; } else break; if (eth.killCountNoDeath >= 2) sprintf(out, "%s ", msg); break; } case '6': { char *killmsg; int randmsg = rand() % 16; if (eth.killCount) { if (!randmsg) killmsg = "^3 Let's Rock!!"; else if (randmsg == 1) killmsg = "^3 Haha, Its a hole in Your head!"; else if (randmsg == 2) killmsg = "^3 Eat my ass and God bless.."; else if (randmsg == 3) killmsg = "^3 was soo weak and glassy-eyed"; else if (randmsg == 4) killmsg = "^3, So I guess you’re not a fan of Eth"; else if (randmsg == 5) killmsg = "^3 Give Me Your Soul"; else if (randmsg == 6) killmsg = "^3 Once More, You Have to be the Grown-Up"; else if (randmsg == 7) killmsg = "^3 Your Blood is soo Sweet, like marmalade"; else if (randmsg == 8) killmsg = "^3 There is no God, no heaven, Just ME !!"; else if (randmsg == 9) killmsg = "^3 Join Me in Hell, Won’t You?"; else if (randmsg == 10) killmsg = "^3"; else if (randmsg == 11) killmsg = "^3 I Am Your One-Way Ticket to Hell"; else if (randmsg == 12) killmsg = "^3..How much is your dead body worth?..."; else if (randmsg == 13) killmsg = "^3 Dead man walking? Not sure :)"; else if (randmsg == 14) killmsg = "^3 Death Is Waiting 4 YOU!"; else if (randmsg == 15) killmsg = "^3 Welcome to my list of fucked Bodies"; else if (randmsg == 16) killmsg = "^3 Oh Yes, here is your Destination.."; else killmsg = "^3 Time to Die. "; } else break; strncat(out,killmsg, sizeof(out)); break; } case 'R': { char *msg; if (eth.killCountNoDeath == 10) { msg = "^3is on a ^2KILLING SPREE!!! ^3(10 frags in a row)"; } else if (eth.killCountNoDeath == 15) { msg = "^3is ^2DOMINATING!!! ^3(15 frags in a row)"; } else if (eth.killCountNoDeath == 20) { msg = "^3is on a ^2RAMPAGE!!! ^3(20 frags in a row)"; } else if (eth.killCountNoDeath == 25) { msg = "^3is ^2UNSTOPPABLE!!! ^3(25 frags in a row)"; } else if (eth.killCountNoDeath == 30) { msg = "^3is ^2WICKED SICK!!! ^3(30 frags in a row)"; } else if (eth.killCountNoDeath == 35) { msg = "^3is on a MEGA KILLINGSPREE!!! ^3(35 frags in a row)"; } else if (eth.killCountNoDeath == 40) { msg = "^3is OMFGHAXOR!!! ^3(40 frags in a row)"; } else if (eth.killCountNoDeath == 45) { msg = "^3I'M HARD AS FUCKING STEEL!!! ^3(45 frags in a row)"; } else if (eth.killCountNoDeath == 50) { msg = "^3NOBODY CAN STOP ME NOW!!! ^3(50 frags in a row)"; } else break; if (eth.killCountNoDeath >= 2) sprintf(out, "%s ", msg); break; } case '5': { char *multikillmsg; int randmsg = rand() % 3; if (eth.killSpreeCount == 2) { if (!randmsg) multikillmsg = " ^1-> ^7doubleLEAK!"; else if (randmsg == 1) multikillmsg = " ^1-> ^7doubleLEAK!"; else multikillmsg = " ^1-> ^7doubleLEAK!"; } else if (eth.killSpreeCount == 3) { if (!randmsg) multikillmsg = " ^1-> ^7multiLEAK!"; else if (randmsg == 1) multikillmsg = " ^1-> ^7multiLEAK!"; else multikillmsg = " ^1-> ^7multiLEAK!"; } else if (eth.killSpreeCount == 4) { if (!randmsg) multikillmsg = " ^1-> ^7ultraLEAK!"; else if (randmsg == 1) multikillmsg = " ^1-> ^7ultraLEAK!"; else multikillmsg = " ^1-> ^7ultraLEAK!"; } else if (eth.killSpreeCount > 4) { if (!randmsg) multikillmsg = " ^1-> ^7monsterLEAK!"; else if (randmsg == 1) multikillmsg = " ^1-> ^7Holy Shit!!!!!LEAK"; else multikillmsg = " ^1-> ^7monsterLEAK!"; } else break; strncat(out, multikillmsg, sizeof(out)); break; } case 'N': { char *multikillmsg; int randmsg = rand() % 3; if (eth.killSpreeCount == 1) { if (!randmsg) multikillmsg = "EATEN"; else if (randmsg == 1) multikillmsg = "OWNED"; else multikillmsg = "ADIOS AMIGO"; } if (eth.killSpreeCount == 2) { if (!randmsg) multikillmsg = "DOUBLE KILL"; else if (randmsg == 1) multikillmsg = "PERFECT"; else multikillmsg = "OWNED"; } else if (eth.killSpreeCount == 3) { if (!randmsg) multikillmsg = "TRIPLE KILL"; else if (randmsg == 1) multikillmsg = "GODLIKE"; else multikillmsg = "LUDICROUS"; } else if (eth.killSpreeCount == 4) { if (!randmsg) multikillmsg = "DOMINATING"; else if (randmsg == 1) multikillmsg = "ULTRA KILL"; else multikillmsg = "MEGA KILL"; } else if (eth.killSpreeCount > 4) { if (!randmsg) multikillmsg = "WICKED SICK"; else if (randmsg == 1) multikillmsg = "MONSTER KILL"; else multikillmsg = "BOOM HEADSHOT"; } else break; strncat(out, multikillmsg, sizeof(out)); break; } case 'X': { char *killmsg; int randmsg = rand() % 24; if (eth.killCount) { if (!randmsg) killmsg = " ^7 + My Gun = +1 on my owned list."; else if (randmsg == 1) killmsg = "^7... What? There's only one of you?"; else if (randmsg == 2) killmsg = " ^7 You're a joke!"; else if (randmsg == 3) killmsg = "^7... suck it down!"; else if (randmsg == 4) killmsg = " ^7, go home!"; else if (randmsg == 5) killmsg = " ^7... Suprise, asshole!"; else if (randmsg == 6) killmsg = "^7, shit happens."; else if (randmsg == 7) killmsg = "^7, you are the weakest link, good-bye!"; else if (randmsg == 8) killmsg = "^7- Mmmm, bad case of lead poisoning!"; else if (randmsg == 9) killmsg = " ^7is now in a better place!"; else if (randmsg == 10) killmsg = " ^7 wanted to take part in my killingspree."; else if (randmsg == 11) killmsg = " ^7 enjoyed a ^3crisp ^7bullet to the head!"; else if (randmsg == 12) killmsg = " ^7 is no more."; else if (randmsg == 13) killmsg = "^7, It's time to kick ass, and chew bubblegum... and i'm all outta gum."; else if (randmsg == 14) killmsg = "^7, it's time to abort your whole friggin' species."; else if (randmsg == 15) killmsg = "^7, Come get some."; else if (randmsg == 16) killmsg = " ^7... Get that crap outta here."; else if (randmsg == 17) killmsg = " ^7 got on the bad side of me... and ended up ^3DEAD^7!"; else if (randmsg == 18) killmsg = "^7's brain made a mess on the floor... * clean up on isle"; else if (randmsg == 19) killmsg = " ^7got in my way."; else if (randmsg == 20) killmsg = "^7... Eat shit and Die!"; else if (randmsg == 21) killmsg = "^7, you suck."; else if (randmsg == 22) killmsg = "^7... Hehehe, what a mess."; else if (randmsg == 23) killmsg = "^7 was killed!"; else if (randmsg == 24) killmsg = "^7, Looks like it's Time to Kill."; else killmsg = "^7 Time to Die."; } else break; strncat(out,killmsg, sizeof(out)); break; } case 'C': { char *killmsg; int randmsg = rand() % 12; if (eth.killCountNoDeath) { if (!randmsg) killmsg = strncpy(ksFormat, " ^2...Suprise, Suprise, asshole^1!",sizeof(ksFormat)); else if (randmsg == 1) killmsg = strncpy(ksFormat, " ^7You're a joke^1!",sizeof(ksFormat)); else if (randmsg == 2) killmsg = strncpy(ksFormat, "^2... suck it down^1!",sizeof(ksFormat)); else if (randmsg == 3) killmsg = strncpy(ksFormat, "^7, go home!",sizeof(ksFormat)); else if (randmsg == 4) killmsg = strncpy(ksFormat, "^2...Suprise, Suprise, asshole^1!!",sizeof(ksFormat)); else if (randmsg == 5) killmsg = strncpy(ksFormat, "^7, shit happens.",sizeof(ksFormat)); else if (randmsg == 6) killmsg = strncpy(ksFormat, "^7 is now in a better place!",sizeof(ksFormat)); else if (randmsg == 7) killmsg = strncpy(ksFormat, "^2 is no more^1.",sizeof(ksFormat)); else if (randmsg == 8) killmsg = strncpy(ksFormat, "^7, Come get some^1.",sizeof(ksFormat)); else if (randmsg == 9) killmsg = strncpy(ksFormat, "^7 got in my way.",sizeof(ksFormat)); else if (randmsg == 10) killmsg = strncpy(ksFormat, "^2... Eat shit and ^1Die!",sizeof(ksFormat)); else if (randmsg == 11) killmsg = strncpy(ksFormat, "^7, you suck.",sizeof(ksFormat)); else if (randmsg == 12) killmsg = strncpy(ksFormat, "^2 was killed^1!",sizeof(ksFormat)); else killmsg = strncpy(ksFormat, "^7 was killed^1!",sizeof(ksFormat)); } else break; strncat(out, killmsg, sizeof(out)); break; } case 'P': { char *multikillmsg; if (eth.killSpreeCount == 2) { multikillmsg = "^1<-- |DoubleKill|"; } else if (eth.killSpreeCount == 3) { multikillmsg = "^1<-- |MultiKill|"; } else if (eth.killSpreeCount == 4) { multikillmsg = "^1<-- |UltraKill|"; } else if (eth.killSpreeCount > 4) { multikillmsg = "^1<--|MonsterKill|"; } else break; strncat(out, multikillmsg, sizeof(out)); break; } default: break; } a += 2; } else out[b] = in[a]; b = strlen(out); } strncpy(in,out,sizeof(out)); return in; } //tes: once per command call int isCommandTime(void) { static int lastTimeC; if(seth.value[VAR_SNAPDELAY] != 0) { if(lastTimeC + (int)seth.value[VAR_SNAPDELAY] > (eth.cg_time )) return 0; lastTimeC = eth.cg_time; return 1; } // tes: so if set to 0 then we do it like this: // count time delay for max commands we can send between snapshots // this is strictly ping based and seems to be solution i search for :) if((lastTimeC + (eth.cg_snap->ping/(CMD_BACKUP -1))) <= (eth.cg_time)){ lastTimeC = eth.cg_time; return 1; } return 0; } void selfkillSpam() { char send[256]; char msg[256]; strncpy(msg,skFormat,sizeof(msg)); snprintf(send, sizeof(send), "say \"%s\"\n", Format(msg)); syscall_CG_SendConsoleCommand(send); } // Customizable spam void killSpam() { char msg[256]; char send[256]; strncpy(msg,ksFormat,sizeof(msg)); snprintf(send, sizeof(send), "say \"%s\"\n", Format(msg)); syscall_CG_SendConsoleCommand(send); } void timenudge(int nTime) { char send[256]; snprintf(send, sizeof(send), "cl_timenudge %d\n", nTime); syscall_CG_SendConsoleCommand(send); } void deathSpam() { char send[256]; char msg[256]; strncpy(msg,dieFormat,sizeof(msg)); snprintf(send, sizeof(send), "say \"%s\"\n", Format(msg)); syscall_CG_SendConsoleCommand(send); } // Auto demo record void autoRecord() { #define TMP_FILE_NAME "demo_in_progress" static qboolean demoState = qfalse; static int stateTime ; int ethRate; // Speed return if we don't want record demo if (!demoState && !seth.value[VAR_RECDEMO]) return; if ((eth.cg_snap->ps.eFlags != EF_DEAD) && (eth.cg_snap->ps.clientNum == eth.cg_clientNum) && (eth.clientInfo[eth.cg_clientNum].team != TEAM_SPECTATOR) && (eth.cg_snap->ps.stats[STAT_HEALTH] > 0) && (eth.cg_snap->ps.pm_flags != PMF_FOLLOW) && seth.value[VAR_RECDEMO] && !demoState) { stateTime=0 ; // FIXME: check if a tmp demo file already exist syscall_CG_SendConsoleCommand("record " TMP_FILE_NAME "\n"); stateTime = eth.cg_time; #ifdef ETH_DEBUG ethDebug("demo: start"); #endif demoState = qtrue; } else if (((eth.cg_snap->ps.eFlags == EF_DEAD) || (eth.cg_snap->ps.clientNum != eth.cg_clientNum) || (eth.clientInfo[eth.cg_clientNum].team == TEAM_SPECTATOR) || (eth.cg_snap->ps.stats[STAT_HEALTH] <= 0) || (eth.cg_snap->ps.pm_flags == PMF_FOLLOW) || (!seth.value[VAR_RECDEMO])) && demoState) { char buffFrom[MAX_OSPATH]; char buffTo[MAX_OSPATH]; // Get fsgame char fsGame[MAX_QPATH]; syscall_CG_Cvar_VariableStringBuffer("fs_game", fsGame, sizeof(fsGame)); // Get current time time_t ethTime = time(NULL); struct tm *localTime = localtime(ðTime); orig_Cbuf_ExecuteText(EXEC_NOW, "stoprecord\n"); stateTime = ((eth.cg_time - stateTime)/1000) ; ethRate=(int)((((float)eth.autoDemoKillCount/(float)stateTime)*100.0f)/(float)(0.2)) ; #ifdef ETH_DEBUG ethDebug("demo: final stateTime:[%i]", stateTime) ; ethDebug("demo: kill acc:[%i]",ethRate); ethDebug("demo: stop"); #endif // buffForm = /homepath/fsgame/ syscall_CG_Cvar_VariableStringBuffer("fs_homepath", buffFrom, sizeof(buffFrom)); sprintf(buffFrom, "%s/%s/demos/", buffFrom, fsGame); strncpy(buffTo, buffFrom, sizeof(buffFrom)); // buffForm = /homepath/fsgame/demos/demoinprogress strcat(buffFrom, TMP_FILE_NAME ".dm_"); // Contruct final file name, buffTo = /homepath/fsgame/demo/aaaa_mm_dd_hhmmss_mod_map_killcount sprintf(buffTo,"%s%i-%.2i-%.2i-%.2i%.2i%.2i_%s_%s_%ikills_%isec_%irate.dm_", buffTo, localTime->tm_year + 1900, localTime->tm_mon + 1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec, fsGame, eth_Info_ValueForKey(eth.cgs_gameState->stringData + eth.cgs_gameState->stringOffsets[CS_SERVERINFO], "mapname"), eth.autoDemoKillCount, stateTime, ethRate); // Version of the demo if (!strcmp(sethET->version, "2.55")){ strcat(buffFrom, "82"); strcat(buffTo, "82"); } else if(!strcmp(sethET->version, "2.56")){ strcat(buffFrom, "83"); strcat(buffTo, "83"); } else { strcat(buffFrom, "84"); strcat(buffTo, "84"); } #ifdef ETH_DEBUG ethDebug("demo: got %i kills, need %i kills", eth.autoDemoKillCount, (int)seth.value[VAR_RECDEMO]); #endif // If we more than kills threshold then rename the demo if (eth.autoDemoKillCount >= seth.value[VAR_RECDEMO]) { #ifdef ETH_DEBUG ethDebug("demo: move [%s] to [%s]", buffFrom, buffTo); #endif rename(buffFrom, buffTo); // Else delete it } else { #ifdef ETH_DEBUG ethDebug("demo: delete [%s]", buffFrom, buffTo); #endif unlink(buffFrom); } eth.autoDemoKillCount = 0; demoState = qfalse; } } /* ============================== et guid ============================== */ // Init cl_guid by environnement var void loadCL_GUID(void) { char *cl_guid = getenv("CLGUID"); if (cl_guid) { syscall_CG_Cvar_Set("cl_guid", cl_guid); // Delete env var so cl_guid is set once, and not each cg_init unsetenv("CLGUID"); } } void doMusicSpam() { static char oldTitle[MAX_STRING_CHARS]; static qboolean firstTime = qtrue; char *artist,*currentTime,*totalTime,*title; artist=currentTime=totalTime=title=NULL; if( firstTime ){ oldTitle[0] = '\0'; firstTime = qfalse; return; } if( seth.value[VAR_MUSICSPAM]==1 ) title = strdup(getOutputSystemCommand("dcop amarok player title")); else if (seth.value[VAR_MUSICSPAM]==2) title = strdup(getOutputSystemCommand("xmmsctrl print %T")); else return; if( strcmp(title,oldTitle) ){ //new song char msg[MAX_STRING_CHARS]; strncpy(oldTitle,title,MAX_STRING_CHARS); if( seth.value[VAR_MUSICSPAM]==1 ){ artist = strdup(getOutputSystemCommand("dcop amarok player artist")); currentTime = strdup(getOutputSystemCommand("dcop amarok player currentTime")); totalTime = strdup(getOutputSystemCommand("dcop amarok player totalTime")); } else if( seth.value[VAR_MUSICSPAM]==2 ) { artist = NULL; // no artist print in xmmsctrl?? wtf? currentTime = strdup(getOutputSystemCommand("xmmsctrl print %m")); totalTime = strdup(getOutputSystemCommand("xmmsctrl print %M")); } if( artist ){ sprintf(msg,"say \"^oPlaying ^0[^w%s - %s^0]^*-^0[^w%s/%s^0]\"\n", artist, title, currentTime, totalTime); free(artist); } else sprintf(msg,"say \"^oPlaying ^0[^w%s^0]^*-^0[^w%s/%s^0]\"\n", title, currentTime, totalTime); syscall_CG_SendConsoleCommand(msg); free(currentTime); free(totalTime); } free(title); }