## ETPub PCR alpha hacks (etpub_pcr_ah) ## (C) 2006-2007 PatheticCockroach.com ## This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License ## Derivative works may only be done if they are distributed with their source code. ## ## The original etpub_pcr_ah source and binaries can be found around http://www.patheticcockroach.com/etserver/etpub_pcr.php ## ## Note : ETPub PCR alpha hacks are just small modifications for ETPub (http://www.etpub.org) !lol can, if misused, stop the server (watchdog should be able to work though). For instance, !lol -1 16 several close times or with a lot of players would do the trick. With this fix, this can't happen anymore. ------------------------- MODIFICATION STARTS HERE src\game\g_shrubbot.c : (line 2731) **** REPLACE qboolean G_shrubbot_lol(gentity_t *ent, int skiparg) { int pids[MAX_CLIENTS]; char name[MAX_NAME_LENGTH], err[MAX_STRING_CHARS], numNades[4]; gentity_t *vic; qboolean doAll = qfalse; int pcount, nades = 0, count = 0; if(Q_SayArgc() >= 3+skiparg) { Q_SayArgv( 2+skiparg, numNades, sizeof( numNades ) ); nades = atoi( numNades ); if( nades < 1 ) nades = 1; else if( nades > SHRUBBOT_MAX_LOL_NADES ) nades = SHRUBBOT_MAX_LOL_NADES; } if(Q_SayArgc() < 2+skiparg) { if(g_legacyShrub.integer==1) doAll = qtrue; else { if(!ent) { SPC("lol: you are on the console"); return qfalse; } vic=ent; } } else { Q_SayArgv( 1+skiparg, name, sizeof( name ) ); if(!Q_stricmp( name, "all" ) && (g_legacyShrub.integer==0)) doAll=qtrue; else if(!Q_stricmp( name, "-1" ) && (g_legacyShrub.integer==1)) doAll=qtrue; } if( doAll ) { int it; for( it = 0; it < level.numConnectedClients; it++ ) { vic = g_entities + level.sortedClients[it]; if( !_shrubbot_admin_higher(ent, vic) || _shrubbot_immutable(ent, vic) || !(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) continue; if( nades ) G_createClusterNade( vic, nades ); else G_createClusterNade( vic, 1 ); count++; } AP(va("chat \"^/lol: ^7%d players lol\'d\" -1", count)); return qtrue; } pcount = ClientNumbersFromString(name, pids); if(pcount > 1) { int it; if(g_legacyShrub.integer==0) { G_MatchOnePlayer(pids, err, sizeof(err)); SPC(va("^/lol: ^7%s", err)); return qfalse; } for( it = 0; it < pcount; it++) { vic = &g_entities[pids[it]]; if(!_shrubbot_admin_higher(ent, vic)) { SPC(va("^/lol: ^7sorry, but %s^7 has a higher " "admin level than you do", vic->client->pers.netname)); continue; } if(_shrubbot_immutable(ent, vic)) { SPC("^/lol: ^7sorry, but your intended victim is immune to shrubbot commands"); continue; } if(!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { SPC(va("^/lol: ^7%s^7 must be on a " "team to be lol\'d", vic->client->pers.netname)); continue; } if( nades ) G_createClusterNade( vic, nades ); else G_createClusterNade( vic, 8 ); AP(va("chat \"^/lol: ^7%s\" -1", vic->client->pers.netname)); } return qtrue; } else if( (pcount < 1) && (g_legacyShrub.integer==1) ) { G_MatchOnePlayer(pids, err, sizeof(err)); SPC(va("^/lol: ^7%s", err)); return qfalse; } else { vic = &g_entities[pids[0]]; } if(!_shrubbot_admin_higher(ent, vic)) { SPC("^/lol: ^7sorry, but your intended victim has a higher " "admin level than you do"); return qfalse; } if(_shrubbot_immutable(ent, vic)) { SPC("^/lol: ^7sorry, but your intended victim is immune to shrubbot commands"); return qfalse; } if(!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { SPC("^/lol: ^7player must be on a team to be lol'd"); return qfalse; } if( nades ) G_createClusterNade( vic, nades ); else G_createClusterNade( vic, 8 ); AP(va("chat \"^/lol: ^7%s\" -1", vic->client->pers.netname)); return qtrue; } **** WITH qboolean G_shrubbot_lol(gentity_t *ent, int skiparg) { int pids[MAX_CLIENTS]; char name[MAX_NAME_LENGTH], err[MAX_STRING_CHARS], numNades[4]; gentity_t *vic; qboolean doAll = qfalse; int pcount = 0, nades = 1, count = 0; if(Q_SayArgc() >= 3+skiparg) { Q_SayArgv( 2+skiparg, numNades, sizeof( numNades ) ); nades = atoi( numNades ); if( nades < 1 ) nades = 1; else if( nades > SHRUBBOT_MAX_LOL_NADES ) nades = SHRUBBOT_MAX_LOL_NADES; } if(Q_SayArgc() < 2+skiparg) { if(g_legacyShrub.integer==1) doAll = qtrue; else { if(!ent) { SPC("lol: you are on the console"); return qfalse; } vic=ent; } } else { Q_SayArgv( 1+skiparg, name, sizeof( name ) ); if(!Q_stricmp( name, "all" ) && (g_legacyShrub.integer==0)) doAll=qtrue; else if(!Q_stricmp( name, "-1" ) && (g_legacyShrub.integer==1)) doAll=qtrue; } pcount = ClientNumbersFromString(name, pids); // nades*2 and *3 where pretty wild guesses that seemed to prevent the entities overflow if( (doAll && (G_GentitiesAvailable()-level.numConnectedClients*nades*2 < MIN_SPARE_GENTITIES)) || (G_GentitiesAvailable()-pcount*nades*3 < MIN_SPARE_GENTITIES) ) { SPC("^/lol: ^7too many entities, use fewer nades or nade fewer players"); return qfalse; } if( doAll ) { int it; for( it = 0; it < level.numConnectedClients; it++ ) { vic = g_entities + level.sortedClients[it]; if( !_shrubbot_admin_higher(ent, vic) || _shrubbot_immutable(ent, vic) || !(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) continue; G_createClusterNade( vic, nades ); count++; } AP(va("chat \"^/lol: ^7%d players lol\'d\" -1", count)); return qtrue; } if(pcount > 1) { int it; if(g_legacyShrub.integer==0) { G_MatchOnePlayer(pids, err, sizeof(err)); SPC(va("^/lol: ^7%s", err)); return qfalse; } for( it = 0; it < pcount; it++) { vic = &g_entities[pids[it]]; if(!_shrubbot_admin_higher(ent, vic)) { SPC(va("^/lol: ^7sorry, but %s^7 has a higher " "admin level than you do", vic->client->pers.netname)); continue; } if(_shrubbot_immutable(ent, vic)) { SPC("^/lol: ^7sorry, but your intended victim is immune to shrubbot commands"); continue; } if(!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { SPC(va("^/lol: ^7%s^7 must be on a " "team to be lol\'d", vic->client->pers.netname)); continue; } G_createClusterNade( vic, nades ); AP(va("chat \"^/lol: ^7%s\" -1", vic->client->pers.netname)); } return qtrue; } else if(pcount < 1) { G_MatchOnePlayer(pids, err, sizeof(err)); SPC(va("^/lol: ^7%s", err)); return qfalse; } else { vic = &g_entities[pids[0]]; } if(!_shrubbot_admin_higher(ent, vic)) { SPC("^/lol: ^7sorry, but your intended victim has a higher " "admin level than you do"); return qfalse; } if(_shrubbot_immutable(ent, vic)) { SPC("^/lol: ^7sorry, but your intended victim is immune to shrubbot commands"); return qfalse; } if(!(vic->client->sess.sessionTeam == TEAM_AXIS || vic->client->sess.sessionTeam == TEAM_ALLIES)) { SPC("^/lol: ^7player must be on a team to be lol'd"); return qfalse; } G_createClusterNade( vic, nades ); AP(va("chat \"^/lol: ^7%s\" -1", vic->client->pers.netname)); return qtrue; } ------------------------- PERSONAL NOTES For some reason this stuff just doesnt work... although replacing G_GentitiesAvailable() < MIN_SPARE_GENTITIES with qtrue does... WTF ? src\game\g_weapon.c : (line 5078) **** AFTER void G_createClusterNade( gentity_t *ent, int numNades ) { vec3_t dir; int it, grenadeWPID, degPerNade; float x, y; gentity_t *nade; **** ADD if( G_GentitiesAvailable() < MIN_SPARE_GENTITIES ) return; src\game\g_missile.c (line 1766) **** AFTER gentity_t *fire_grenade (gentity_t *self, vec3_t start, vec3_t dir, int grenadeWPID) { gentity_t *bolt; qboolean noExplode = qfalse; **** ADD if( (G_GentitiesAvailable() - numNades) < MIN_SPARE_GENTITIES ) return; if(G_GentitiesAvailable() < MIN_SPARE_GENTITIES) { CP("print \"server: ^1Weapon firing temporarily disabled " "due to entity overflow\n\"\n"); return; }