2025-07-18 13:27 CEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0000506Spring engineGeneralpublic2007-04-22 10:06
ReporterKloot 
Assigned ToILMTitan 
PrioritynormalSeverityminorReproducibilityN/A
StatusresolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0000506: [patch] .give command crash-fix
DescriptionModifies the handling of the .give command such that the per-team unit limit can not be exceeded anymore. (Also prevents the possibility of crashing the game by .giving a number that would bring the total number of units to >= MAX_UNITS.)
TagsNo tags attached.
Checked infolog.txt for Errors
Attached Files
  • patch file icon GiveCommand.patch (5,967 bytes) 2007-03-31 00:50 -
    Index: Game.cpp
    ===================================================================
    --- Game.cpp	(revision 3508)
    +++ Game.cpp	(working copy)
    @@ -3357,64 +3357,82 @@
     		gs->Team(team)->AddEnergy(1000);
     	}
     
    -	else if(s.find(".give")==0 && gs->cheatEnabled){
    -		int team=gs->players[player]->team;
    +	else if (s.find(".give") == 0 && gs->cheatEnabled) {
    +		int team = gs->players[player]->team;
     		int p1 = s.rfind(" @"), p2 = s.find(",", p1+1), p3 = s.find(",", p2+1);
     		if (p1 == string::npos || p2 == string::npos || p3 == string::npos)
     			logOutput.Print("Someone is spoofing invalid .give messages!");
     		float3 pos(atof(&s.c_str()[p1+2]), atof(&s.c_str()[p2+1]), atof(&s.c_str()[p3+1]));
     		s = s.substr(0, p1);
     
    -		if(s.find(" all")!=string::npos){
    -			int squareSize=(int)ceil(sqrt((float)unitDefHandler->numUnits));
    +		if (s.find(" all") != string::npos) {
    +			int squareSize = (int) ceil(sqrt((float) unitDefHandler->numUnits));
    +			int currentNumUnits = gs->Team(team)->units.size();
    +			int numRequestedUnits = unitDefHandler->numUnits;
     
    -			for(int a=1;a<=unitDefHandler->numUnits;++a){
    -				float3 pos2=float3(pos.x + (a%squareSize-squareSize/2) * 10*SQUARE_SIZE, pos.y, pos.z + (a/squareSize-squareSize/2) * 10*SQUARE_SIZE);
    +			// make sure team unit-limit not exceeded
    +			if ((currentNumUnits + numRequestedUnits) > uh->maxUnits)
    +				numRequestedUnits = uh->maxUnits - currentNumUnits;
    +
    +			for (int a = 1; a <= numRequestedUnits; ++a) {
    +				float3 pos2 = float3(pos.x + (a%squareSize-squareSize/2) * 10*SQUARE_SIZE, pos.y, pos.z + (a/squareSize-squareSize/2) * 10*SQUARE_SIZE);
     				const CUnit* unit =
    -					unitLoader.LoadUnit(unitDefHandler->unitDefs[a].name,pos2,team,false,0,NULL);
    +					unitLoader.LoadUnit(unitDefHandler->unitDefs[a].name, pos2, team, false, 0, NULL);
     				if (unit) {
     					unitLoader.FlattenGround(unit);
     				}
     			}
    -		} else if (((s.rfind(" "))!=string::npos) && ((s.length() - s.rfind(" ") -1)>0)){
    -			string unitName=s.substr(s.rfind(" ")+1,s.length() - s.rfind(" ") -1);
    -			string tempUnitName=s.substr(s.find(" "),s.rfind(" ")+1 - s.find(" "));
    -			if(tempUnitName.find_first_not_of(" ")!=string::npos)
    -				tempUnitName=tempUnitName.substr(tempUnitName.find_first_not_of(" "),tempUnitName.find_last_not_of(" ") +1 - tempUnitName.find_first_not_of(" "));
    -			bool createNano=(tempUnitName.find("nano")!=string::npos);
    +		} else if (((s.rfind(" ")) != string::npos) && ((s.length() - s.rfind(" ") - 1) > 0)) {
    +			string unitName = s.substr(s.rfind(" ")+1,s.length() - s.rfind(" ") -1);
    +			string tempUnitName = s.substr(s.find(" "), s.rfind(" ") + 1 - s.find(" "));
     
    -			int numUnits=1;
    -			if(tempUnitName.find_first_of("0123456789")!=string::npos){
    -				tempUnitName=tempUnitName.substr(tempUnitName.find_first_of("0123456789"),tempUnitName.find_last_of("0123456789") +1 -tempUnitName.find_first_of("0123456789"));
    -				numUnits = atoi(tempUnitName.c_str());
    -			}
    +			if (tempUnitName.find_first_not_of(" ") != string::npos)
    +				tempUnitName = tempUnitName.substr(tempUnitName.find_first_not_of(" "),tempUnitName.find_last_not_of(" ") +1 - tempUnitName.find_first_not_of(" "));
    +			bool createNano = (tempUnitName.find("nano") != string::npos);
     
    -			UnitDef* unitDef = unitDefHandler->GetUnitByName(unitName);
    -			if (unitDef != NULL) {
    -				int xsize=unitDef->xsize;
    -				int zsize=unitDef->ysize;
    -				int total=numUnits;
    -				int squareSize=(int)ceil(sqrt((float)numUnits));
    -				float3 minpos=pos;
    -				minpos.x-=((squareSize-1)*xsize*SQUARE_SIZE)/2;
    -				minpos.z-=((squareSize-1)*zsize*SQUARE_SIZE)/2;
    -				for(int z=0;z<squareSize;++z){
    -					for(int x=0;x<squareSize && total>0;++x){
    -						const float3 upos(minpos.x + x * xsize * SQUARE_SIZE, minpos.y,
    -						                  minpos.z + z * zsize * SQUARE_SIZE);
    -						const CUnit* unit = unitLoader.LoadUnit(unitName, upos, team, createNano, 0, NULL);
    -						if (unit) {
    -							unitLoader.FlattenGround(unit);
    +			int numRequestedUnits = 1;
    +			int currentNumUnits = gs->Team(team)->units.size();
    +
    +			if (currentNumUnits < uh->maxUnits) {
    +				if (tempUnitName.find_first_of("0123456789") != string::npos) {
    +					tempUnitName = tempUnitName.substr(tempUnitName.find_first_of("0123456789"),tempUnitName.find_last_of("0123456789") +1 -tempUnitName.find_first_of("0123456789"));
    +					numRequestedUnits = atoi(tempUnitName.c_str());
    +
    +					// make sure team unit-limit not exceeded
    +					if ((currentNumUnits + numRequestedUnits) > uh->maxUnits)
    +						numRequestedUnits = uh->maxUnits - currentNumUnits;
    +				}
    +
    +				UnitDef* unitDef = unitDefHandler->GetUnitByName(unitName);
    +				if (unitDef != NULL) {
    +					int xsize = unitDef->xsize;
    +					int zsize = unitDef->ysize;
    +					int squareSize = (int) ceil(sqrt((float) numRequestedUnits));
    +					float3 minpos = pos;
    +					minpos.x -= ((squareSize - 1) * xsize * SQUARE_SIZE) / 2;
    +					minpos.z -= ((squareSize - 1) * zsize * SQUARE_SIZE) / 2;
    +
    +					for (int z = 0; z < squareSize; ++z) {
    +						for (int x = 0; x < squareSize && numRequestedUnits > 0; ++x) {
    +							const float3 upos(minpos.x + x * xsize * SQUARE_SIZE, minpos.y,
    +											minpos.z + z * zsize * SQUARE_SIZE);
    +							const CUnit* unit = unitLoader.LoadUnit(unitName, upos, team, createNano, 0, NULL);
    +							if (unit) {
    +								unitLoader.FlattenGround(unit);
    +							}
    +							--numRequestedUnits;
     						}
    -						--total;
     					}
    +					logOutput.Print("Giving %i %s to team %i", numRequestedUnits, unitName.c_str(), team);
    +				} else {
    +					logOutput.Print(unitName + " is not a valid unitname");
     				}
    -				logOutput.Print("Giving %i %s to team %i", numUnits, unitName.c_str(),team);
     			} else {
    -				logOutput.Print(unitName+" is not a valid unitname");
    +				logOutput.Print("Unable to give any more units to team %i", team);
     			}
     		}
     	}
    +
     	else if(s.find(".take")==0 && (!gu->spectating || gs->cheatEnabled)){
     		int sendTeam=gs->players[player]->team;
     		for(int a=0;a<gs->activeTeams;++a){
    
    patch file icon GiveCommand.patch (5,967 bytes) 2007-03-31 00:50 +

-Relationships
+Relationships

-Notes

~0000869

tvo (reporter)

Go ahead and commit it if you are confident it works fine.

I don't see any problems with it at first sight, and I lack the time to extensively test it myself ;-)

~0000871

Kloot (developer)

committed in r3554 :)

~0000895

ILMTitan (reporter)

Committed a while ago.
+Notes

-Issue History
Date Modified Username Field Change
2007-03-31 00:49 Kloot New Issue
2007-03-31 00:50 Kloot File Added: GiveCommand.patch
2007-04-04 23:32 tvo Note Added: 0000869
2007-04-05 18:13 Kloot Note Added: 0000871
2007-04-22 10:06 ILMTitan Status new => resolved
2007-04-22 10:06 ILMTitan Resolution open => fixed
2007-04-22 10:06 ILMTitan Assigned To => ILMTitan
2007-04-22 10:06 ILMTitan Note Added: 0000895
+Issue History