Example #1
0
void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, parameterlist& params)
{
	User* who = ServerInstance->FindUUID(prefix);
	std::string direction;

	if (!who)
	{
		TreeServer* ServerSource = Utils->FindServer(prefix);
		if (prefix.empty())
			ServerSource = MyRoot;

		if (ServerSource)
		{
			who = ServerSource->ServerUser;
		}
		else
		{
			/* It is important that we don't close the link here, unknown prefix can occur
			 * due to various race conditions such as the KILL message for a user somehow
			 * crossing the users QUIT further upstream from the server. Thanks jilles!
			 */

			if ((prefix.length() == UIDGenerator::UUID_LENGTH) && (isdigit(prefix[0])) &&
				((command == "FMODE") || (command == "MODE") || (command == "KICK") || (command == "TOPIC") || (command == "KILL") || (command == "ADDLINE") || (command == "DELLINE")))
			{
				/* Special case, we cannot drop these commands as they've been committed already on a
				 * part of the network by the time we receive them, so in this scenario pretend the
				 * command came from a server to avoid desync.
				 */

				who = ServerInstance->FindUUID(prefix.substr(0, 3));
				if (!who)
					who = this->MyRoot->ServerUser;
			}
			else
			{
				ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Command '%s' from unknown prefix '%s'! Dropping entire command.",
					command.c_str(), prefix.c_str());
				return;
			}
		}
	}

	// Make sure prefix is still good
	direction = who->server;
	prefix = who->uuid;

	/*
	 * Check for fake direction here, and drop any instances that are found.
	 * What is fake direction? Imagine the following server setup:
	 *    0AA <-> 0AB <-> 0AC
	 * Fake direction would be 0AC sending a message to 0AB claiming to be from
	 * 0AA, or something similar. Basically, a message taking a path that *cannot*
	 * be correct.
	 *
	 * When would this be seen?
	 * Well, hopefully never. It could be caused by race conditions, bugs, or
	 * "miscreant" servers, though, so let's check anyway. -- w
	 *
	 * We also check here for totally invalid prefixes (prefixes that are neither
	 * a valid SID or a valid UUID, so that invalid UUID or SID never makes it
	 * to the higher level functions. -- B
	 */
	TreeServer* route_back_again = Utils->BestRouteTo(direction);
	if ((!route_back_again) || (route_back_again->GetSocket() != this))
	{
		if (route_back_again)
			ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Protocol violation: Fake direction '%s' from connection '%s'",
				prefix.c_str(),linkID.c_str());
		return;
	}

	// Translate commands coming from servers using an older protocol
	if (proto_version < ProtocolVersion)
	{
		if (!PreProcessOldProtocolMessage(who, command, params))
			return;
	}

	ServerCommand* scmd = Utils->Creator->CmdManager.GetHandler(command);
	CommandBase* cmdbase = scmd;
	Command* cmd;
	if (!scmd)
	{
		// Not a special server-to-server command
		cmd = ServerInstance->Parser->GetHandler(command);
		if (!cmd)
		{
			irc::stringjoiner pmlist(params);
			ServerInstance->Logs->Log(MODNAME, LOG_SPARSE, "Unrecognised S2S command :%s %s %s",
				who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str());
			SendError("Unrecognised command '" + command + "' -- possibly loaded mismatched modules");
			return;
		}
		cmdbase = cmd;
	}

	if (params.size() < cmdbase->min_params)
	{
		irc::stringjoiner pmlist(params);
		ServerInstance->Logs->Log(MODNAME, LOG_SPARSE, "Insufficient parameters for S2S command :%s %s %s",
			who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str());
		SendError("Insufficient parameters for command '" + command + "'");
		return;
	}

	if ((!params.empty()) && (params.back().empty()) && (!cmdbase->allow_empty_last_param))
	{
		// the last param is empty and the command handler doesn't allow that, check if there will be enough params if we drop the last
		if (params.size()-1 < cmdbase->min_params)
			return;
		params.pop_back();
	}

	CmdResult res;
	if (scmd)
		res = scmd->Handle(who, params);
	else
		res = cmd->Handle(params, who);

	if (res == CMD_INVALID)
	{
		irc::stringjoiner pmlist(params);
		ServerInstance->Logs->Log(MODNAME, LOG_SPARSE, "Error handling S2S command :%s %s %s",
			who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str());
		SendError("Error handling '" + command + "' -- possibly loaded mismatched modules");
	}
	else if (res == CMD_SUCCESS)
		Utils->RouteCommand(route_back_again, cmdbase, params, who);
}
Example #2
0
void CTransportCAI::UnloadLandFlood(Command& c)
{
	//land, then release all units at once
	CTransportUnit* transport = static_cast<CTransportUnit*>(owner);
	if (inCommand) {
		if (!owner->script->IsBusy()) {
			FinishCommand();
		}
	} else {
		const std::list<CTransportUnit::TransportedUnit>& transList = transport->GetTransportedUnits();

		if (transList.empty()) {
			FinishCommand();
			return;
		}

		//check units are all carried
		CUnit* unit = NULL;
		if (c.params.size() < 4) {
			unit = transList.front().unit;
		} else {
			const int unitID = (int)c.params[3];
			std::list<CTransportUnit::TransportedUnit>::const_iterator it;
			for (it = transList.begin(); it != transList.end(); ++it) {
				CUnit* carried = it->unit;
				if (unitID == carried->id) {
					unit = carried;
					break;
				}
			}
			if (unit == NULL) {
				FinishCommand();
				return;
			}
		}

		// move to position
		float3 pos = c.GetPos(0);
		if (isFirstIteration) {
			if (goalPos.SqDistance2D(pos) > 400) {
				SetGoal(startingDropPos, owner->pos);
			}
		}

		if (startingDropPos.SqDistance2D(owner->pos) < Square(owner->unitDef->loadingRadius * 0.9f)) {
			// create aircraft movetype instance
			CHoverAirMoveType* am = dynamic_cast<CHoverAirMoveType*>(owner->moveType);

			if (am != NULL) {
				// lower to ground

				startingDropPos.y = ground->GetHeightAboveWater(startingDropPos.x,startingDropPos.z);
				const float3 wantedPos = startingDropPos + UpVector * unit->model->height;
				SetGoal(wantedPos, owner->pos);

				am->SetWantedAltitude(1);
				am->maxDrift = 1;
				am->dontLand = false;

				// when on our way down start animations for unloading gear
				if (isFirstIteration) {
					owner->script->StartUnload();
				}
				isFirstIteration = false;

				// once at ground
				if (owner->pos.y - ground->GetHeightAboveWater(wantedPos.x,wantedPos.z) < 8) {

					// nail it to the ground before it tries jumping up, only to land again...
					am->SetState(am->AIRCRAFT_LANDED);
					// call this so that other animations such as opening doors may be started
					owner->script->TransportDrop(transList.front().unit, pos);

					transport->DetachUnitFromAir(unit,pos);

					FinishCommand();
					if (transport->GetTransportedUnits().empty()) {
						am->dontLand = false;
						owner->script->EndTransport();
						am->UpdateLanded();
					}
				}
			} else {
				// land transports
				inCommand = true;
				isFirstIteration = false;

				StopMove();
				owner->script->TransportDrop(transList.front().unit, pos);
				transport->DetachUnitFromAir(unit, pos);
				FinishCommand();

				if (transport->GetTransportedUnits().empty()) {
					owner->script->EndTransport();
				}
			}
		}
	}
}
Example #3
0
void CSelectedUnits::GiveCommand(Command c, bool fromUser)
{
	GML_RECMUTEX_LOCK(grpsel); // GiveCommand

//	logOutput.Print("Command given %i",c.id);
	if ((gu->spectating && !gs->godMode) || selectedUnits.empty()) {
		return;
	}

	const int& cmd_id = c.GetID();

	if (fromUser) { // add some statistics
		playerHandler->Player(gu->myPlayerNum)->currentStats.numCommands++;
		if (selectedGroup != -1) {
			playerHandler->Player(gu->myPlayerNum)->currentStats.unitCommands += grouphandlers[gu->myTeam]->groups[selectedGroup]->units.size();
		} else {
			playerHandler->Player(gu->myPlayerNum)->currentStats.unitCommands += selectedUnits.size();
		}
	}

	if (cmd_id == CMD_GROUPCLEAR) {
		for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
			if ((*ui)->group) {
				(*ui)->SetGroup(0);
				possibleCommandsChanged = true;
			}
		}
		return;
	}
	else if (cmd_id == CMD_GROUPSELECT) {
		SelectGroup((*selectedUnits.begin())->group->id);
		return;
	}
	else if (cmd_id == CMD_GROUPADD) {
		CGroup* group = NULL;
		for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
			if ((*ui)->group) {
				group = (*ui)->group;
				possibleCommandsChanged = true;
				break;
			}
		}
		if (group) {
			for (CUnitSet::iterator ui = selectedUnits.begin(); ui != selectedUnits.end(); ++ui) {
				if (!(*ui)->group) {
					(*ui)->SetGroup(group);
				}
			}
			SelectGroup(group->id);
		}
		return;
	}
	else if (cmd_id == CMD_TIMEWAIT) {
		waitCommandsAI.AddTimeWait(c);
		return;
	}
	else if (cmd_id == CMD_DEATHWAIT) {
		waitCommandsAI.AddDeathWait(c);
		return;
	}
	else if (cmd_id == CMD_SQUADWAIT) {
		waitCommandsAI.AddSquadWait(c);
		return;
	}
	else if (cmd_id == CMD_GATHERWAIT) {
		waitCommandsAI.AddGatherWait(c);
		return;
	}

	SendCommand(c);

	#if (PLAY_SOUNDS == 1)
	if (!selectedUnits.empty()) {
		CUnitSet::const_iterator ui = selectedUnits.begin();

		const int soundIdx = (*ui)->unitDef->sounds.ok.getRandomIdx();
		if (soundIdx >= 0) {
			Channels::UnitReply.PlaySample(
				(*ui)->unitDef->sounds.ok.getID(soundIdx), (*ui),
				(*ui)->unitDef->sounds.ok.getVolume(soundIdx));
		}
	}
	#endif
}
Example #4
0
void CCommandAI::GiveAllowedCommand(const Command& c, bool fromSynced)
{
	if (ExecuteStateCommand(c))
		return;

	switch (c.GetID()) {
		case CMD_SELFD: {
			if (owner->unitDef->canSelfD) {
				if (!(c.options & SHIFT_KEY) || commandQue.empty()) {
					if (owner->selfDCountdown != 0) {
						owner->selfDCountdown = 0;
					} else {
						owner->selfDCountdown = owner->unitDef->selfDCountdown*2+1;
					}
				}
				else if (commandQue.back().GetID() == CMD_SELFD) {
					commandQue.pop_back();
				} else {
					commandQue.push_back(c);
				}
			}
			return;
		}
		case CMD_SET_WANTED_MAX_SPEED: {
			if (CanSetMaxSpeed() &&
			    (commandQue.empty() ||
			     (commandQue.back().GetID() != CMD_SET_WANTED_MAX_SPEED))) {
				// bail early, do not check for overlaps or queue cancelling
				commandQue.push_back(c);
				if (commandQue.size()==1 && !owner->beingBuilt) {
					SlowUpdate();
				}
			}
			return;
		}
		case CMD_WAIT: {
			GiveWaitCommand(c);
			return;
		}
		case CMD_INSERT: {
			ExecuteInsert(c, fromSynced);
			return;
		}
		case CMD_REMOVE: {
			ExecuteRemove(c);
			return;
		}
	}

	// flush the queue for immediate commands
	// NOTE: CMD_STOP can be a queued order (!)
	if (!(c.options & SHIFT_KEY)) {
		waitCommandsAI.ClearUnitQueue(owner, commandQue);
		ClearTargetLock((commandQue.empty())? Command(CMD_STOP): commandQue.front());
		ClearCommandDependencies();
		SetOrderTarget(NULL);

		// if c is an attack command, the actual order-target
		// gets set via ExecuteAttack (called from SlowUpdate
		// at the end of this function)
		commandQue.clear();
		assert(commandQue.empty());

		inCommand = false;
	}

	AddCommandDependency(c);

	if (c.GetID() == CMD_PATROL) {
		CCommandQueue::iterator ci = commandQue.begin();
		for (; ci != commandQue.end() && ci->GetID() != CMD_PATROL; ++ci) {
			// just increment
		}
		if (ci == commandQue.end()) {
			if (commandQue.empty()) {
				Command c2(CMD_PATROL, c.options, owner->pos);
				commandQue.push_back(c2);
			} else {
				do {
					--ci;
					if (ci->params.size() >= 3) {
						Command c2(CMD_PATROL, c.options);
						c2.params = ci->params;
						commandQue.push_back(c2);
						break;
					} else if (ci == commandQue.begin()) {
						Command c2(CMD_PATROL, c.options, owner->pos);
						commandQue.push_back(c2);
						break;
					}
				}
				while (ci != commandQue.begin());
			}
		}
	}

	// cancel duplicated commands
	bool first;
	if (CancelCommands(c, commandQue, first) > 0) {
		if (first) {
			Command stopCommand(CMD_STOP);
			commandQue.push_front(stopCommand);
			SlowUpdate();
		}
		return;
	}

	// do not allow overlapping commands
	if (!GetOverlapQueued(c).empty()) {
		return;
	}

	if (c.GetID() == CMD_ATTACK) {
		// avoid weaponless units moving to 0 distance when given attack order
		if (owner->weapons.empty() && (!owner->unitDef->canKamikaze)) {
			Command c2(CMD_STOP);
			commandQue.push_back(c2);
			return;
		}
	}

	commandQue.push_back(c);

	if (commandQue.size() == 1 && !owner->beingBuilt && !owner->IsStunned()) {
		SlowUpdate();
	}
}
Example #5
0
void CTransportCAI::ExecuteLoadUnits(Command& c)
{
	CTransportUnit* transport = reinterpret_cast<CTransportUnit*>(owner);

	if (c.params.size() == 1) {
		// load single unit
		CUnit* unit = unitHandler->GetUnit(c.params[0]);

		if (!unit) {
			FinishCommand();
			return;
		}
		if (c.options & INTERNAL_ORDER) {
			if (unit->commandAI->commandQue.empty()) {
				if (!LoadStillValid(unit)) {
					FinishCommand();
					return;
				}
			} else {
				Command& currentUnitCommand = unit->commandAI->commandQue[0];
				if ((currentUnitCommand.GetID() == CMD_LOAD_ONTO) && (currentUnitCommand.params.size() == 1) && (int(currentUnitCommand.params[0]) == owner->id)) {
					if ((unit->moveType->progressState == AMoveType::Failed) && (owner->moveType->progressState == AMoveType::Failed)) {
						unit->commandAI->FinishCommand();
						FinishCommand();
						return;
					}
				} else if (!LoadStillValid(unit)) {
					FinishCommand();
					return;
				}
			}
		}
		if (inCommand) {
			if (!owner->script->IsBusy()) {
				FinishCommand();
			}
			return;
		}
		if (unit && CanTransport(unit) && UpdateTargetLostTimer(int(c.params[0]))) {
			SetTransportee(unit);

			const float sqDist = unit->pos.SqDistance2D(owner->pos);
			const bool inLoadingRadius = (sqDist <= Square(owner->unitDef->loadingRadius));
			
			CHoverAirMoveType* am = dynamic_cast<CHoverAirMoveType*>(owner->moveType);

			// subtracting 1 square to account for pathfinder/groundmovetype inaccuracy
			if (goalPos.SqDistance2D(unit->pos) > Square(owner->unitDef->loadingRadius - SQUARE_SIZE) || 
				(!inLoadingRadius && (!owner->isMoving || (am && am->aircraftState != AAirMoveType::AIRCRAFT_FLYING)))) {
				SetGoal(unit->pos, owner->pos, std::min(64.0f, owner->unitDef->loadingRadius));
			}

			if (inLoadingRadius) {
				if (am) { // handle air transports differently
					float3 wantedPos = unit->pos;
					wantedPos.y = static_cast<CTransportUnit*>(owner)->GetLoadUnloadHeight(wantedPos, unit);
					SetGoal(wantedPos, owner->pos);

					am->loadingUnits = true;
					am->ForceHeading(static_cast<CTransportUnit*>(owner)->GetLoadUnloadHeading(unit));
					am->SetWantedAltitude(wantedPos.y - ground->GetHeightAboveWater(wantedPos.x, wantedPos.z));
					am->maxDrift = 1;

					if ((owner->pos.SqDistance(wantedPos) < Square(AIRTRANSPORT_DOCKING_RADIUS)) &&
						(abs(owner->heading-unit->heading) < AIRTRANSPORT_DOCKING_ANGLE) &&
						(owner->updir.dot(UpVector) > 0.995f))
					{
						am->loadingUnits = false;
						am->dontLand = true;

						owner->script->BeginTransport(unit);
						SetTransportee(NULL);
						transport->AttachUnit(unit, owner->script->QueryTransport(unit));
						am->SetWantedAltitude(0);

						FinishCommand();
						return;
					}
				} else {
					inCommand = true;

					StopMove();
					owner->script->TransportPickup(unit);
				}
			} else if (owner->moveType->progressState == AMoveType::Failed && sqDist < (200 * 200)) {
				// if we're pretty close already but CGroundMoveType fails because it considers
				// the goal clogged (with the future passenger...), just try to move to the
				// point halfway between the transport and the passenger.
				SetGoal((unit->pos + owner->pos) * 0.5f, owner->pos);
			}
		} else {
			FinishCommand();
		}
	} else if (c.params.size() == 4) { // area-load
		if (lastCall == gs->frameNum) { // avoid infinite loops
			return;
		}

		lastCall = gs->frameNum;

		const float3 pos = c.GetPos(0);
		const float radius = c.params[3];

		CUnit* unit = FindUnitToTransport(pos, radius);

		if (unit && CanTransport(unit)) {
			Command c2(CMD_LOAD_UNITS, c.options|INTERNAL_ORDER, unit->id);
			commandQue.push_front(c2);
			inCommand = false;

			SlowUpdate();
			return;
		} else {
			FinishCommand();
			return;
		}
	}

	isFirstIteration = true;
	startingDropPos = float3(-1.0f, -1.0f, -1.0f);
}
Example #6
0
void CoasterChannel::checkHeartbeat() {
	// TODO: this can be sent after shutdown
	Command* cmd = new HeartBeatCommand();
	cmd->send(this, &heartbeatCB);
}
Example #7
0
bool CCommandAI::ExecuteStateCommand(const Command& c)
{
	switch (c.GetID()) {
		case CMD_FIRE_STATE: {
			owner->fireState = (int)c.params[0];
			SetCommandDescParam0(c);
			selectedUnitsHandler.PossibleCommandChange(owner);
			return true;
		}
		case CMD_MOVE_STATE: {
			owner->moveState = (int)c.params[0];
			SetCommandDescParam0(c);
			selectedUnitsHandler.PossibleCommandChange(owner);
			return true;
		}
		case CMD_REPEAT: {
			if (c.params[0] == 1) {
				repeatOrders = true;
			} else if(c.params[0] == 0) {
				repeatOrders = false;
			} else {
				// cause some code parts need it to be either 0 or 1,
				// we can not accept any other values as valid
				return false;
			}
			SetCommandDescParam0(c);
			selectedUnitsHandler.PossibleCommandChange(owner);
			return true;
		}
		case CMD_TRAJECTORY: {
			owner->useHighTrajectory = !!c.params[0];
			SetCommandDescParam0(c);
			selectedUnitsHandler.PossibleCommandChange(owner);
			return true;
		}
		case CMD_ONOFF: {
			if (c.params[0] == 1) {
				owner->Activate();
			} else if (c.params[0] == 0) {
				owner->Deactivate();
			} else {
				// cause some code parts need it to be either 0 or 1,
				// we can not accept any other values as valid
				return false;
			}
			SetCommandDescParam0(c);
			selectedUnitsHandler.PossibleCommandChange(owner);
			return true;
		}
		case CMD_CLOAK: {
			if (c.params[0] == 1) {
				owner->wantCloak = true;
			} else if(c.params[0] == 0) {
				owner->wantCloak = false;
				owner->curCloakTimeout = gs->frameNum + owner->cloakTimeout;
			} else {
				// cause some code parts need it to be either 0 or 1,
				// we can not accept any other values as valid
				return false;
			}
			SetCommandDescParam0(c);
			selectedUnitsHandler.PossibleCommandChange(owner);
			return true;
		}
		case CMD_STOCKPILE: {
			int change = 1;
			if (c.options & RIGHT_MOUSE_KEY) { change *= -1; }
			if (c.options & SHIFT_KEY)       { change *=  5; }
			if (c.options & CONTROL_KEY)     { change *= 20; }
			stockpileWeapon->numStockpileQued += change;
			if (stockpileWeapon->numStockpileQued < 0) {
				stockpileWeapon->numStockpileQued = 0;
			}
			UpdateStockpileIcon();
			return true;
		}
	}

	// this is a custom lua command, calling CommandFallback
	// and ignoring the result as this can't stay in the queue
	if (nonQueingCommands.find(c.GetID()) != nonQueingCommands.end()) {
		eventHandler.CommandFallback(owner, c);
		return true;
	}

	return false;
}
void CSelectedUnitsHandlerAI::SelectAttack(const Command& cmd, int player)
{
	std::vector<int> targets;

	if (cmd.params.size() == 4) {
		SelectCircleUnits(cmd.GetPos(0), cmd.params[3], player, targets);
	} else {
		SelectRectangleUnits(cmd.GetPos(0), cmd.GetPos(3), player, targets);
	}

	if (targets.empty())
		return;

	const bool queueing = !!(cmd.options & SHIFT_KEY);
	const std::vector<int>& selected = selectedUnitsHandler.netSelected[player];

	const unsigned int targetsCount = targets.size();
	const unsigned int selectedCount = selected.size();

	if (selectedCount == 0)
		return;

	Command attackCmd(CMD_ATTACK, cmd.options, 0.0f);

	// delete the attack commands and bail for CONTROL_KEY
	if (cmd.options & CONTROL_KEY) {
		attackCmd.options |= SHIFT_KEY;

		for (unsigned int s = 0; s < selectedCount; s++) {
			const CUnit* unit = unitHandler->units[ selected[s] ];

			if (unit == NULL)
				continue;

			CCommandAI* commandAI = unitHandler->units[selected[s]]->commandAI;

			for (unsigned int t = 0; t < targetsCount; t++) {
				attackCmd.params[0] = targets[t];

				if (commandAI->WillCancelQueued(attackCmd)) {
					commandAI->GiveCommand(attackCmd, false);
				}
			}
		}

		return;
	}

	// get the group center
	float3 midPos;
	unsigned int realCount = 0;
	for (unsigned int s = 0; s < selectedCount; s++) {
		CUnit* unit = unitHandler->units[selected[s]];

		if (unit == NULL)
			continue;

		if (queueing) {
			midPos += LastQueuePosition(unit);
		} else {
			midPos += unit->midPos;
		}

		realCount++;
	}

	if (realCount == 0)
		return;

	midPos /= realCount;

	// sort the targets
	std::vector<DistInfo> distVec;

	for (unsigned int t = 0; t < targetsCount; t++) {
		const CUnit* unit = unitHandler->units[ targets[t] ];
		const float3 unitPos = queueing ? LastQueuePosition(unit) : float3(unit->midPos);

		DistInfo di;
		di.unitID = targets[t];
		di.dist = (unitPos - midPos).SqLength2D();
		distVec.push_back(di);
	}
	sort(distVec.begin(), distVec.end());

	// give the commands
	for (unsigned int s = 0; s < selectedCount; s++) {
		if (!queueing) {
			// clear it for the first command
			attackCmd.options &= ~SHIFT_KEY;
		}

		CUnit* unit = unitHandler->units[selected[s]];

		if (unit == NULL)
			continue;

		CCommandAI* commandAI = unit->commandAI;

		for (unsigned t = 0; t < targetsCount; t++) {
			attackCmd.params[0] = distVec[t].unitID;

			if (!queueing || !commandAI->WillCancelQueued(attackCmd)) {
				commandAI->GiveCommand(attackCmd, false);
				AddUnitSetMaxSpeedCommand(unit, attackCmd.options);
				// following commands are always queued
				attackCmd.options |= SHIFT_KEY;
			}
		}
	}
}
void CSelectedUnitsHandlerAI::GiveCommandNet(Command &c, int player)
{
	const std::vector<int>& netSelected = selectedUnitsHandler.netSelected[player];
	std::vector<int>::const_iterator ui;

	const int nbrOfSelectedUnits = netSelected.size();
	const int cmd_id = c.GetID();

	if (nbrOfSelectedUnits < 1) {
		// no units to command
	}
	else if ((cmd_id == CMD_ATTACK) && (
			(c.GetParamsCount() == 6) ||
			((c.GetParamsCount() == 4) && (c.GetParam(3) > 0.001f))
		))
	{
		SelectAttack(c, player);
	}
	else if (nbrOfSelectedUnits == 1) {
		// a single unit selected
		CUnit* unit = unitHandler->units[*netSelected.begin()];
		if (unit) {
			unit->commandAI->GiveCommand(c, true);
			if (MayRequireSetMaxSpeedCommand(c)) {
				AddUnitSetMaxSpeedCommand(unit, c.options);
			}
			if (cmd_id == CMD_WAIT) {
				if (player == gu->myPlayerNum) {
					waitCommandsAI.AcknowledgeCommand(c);
				}
			}
		}
	}

	// User Move Front Command:
	//
	//   CTRL:      Group Front/Speed  command
	//
	// User Move Command:
	//
	//   ALT:       Group Front        command
	//   ALT+CTRL:  Group Front/Speed  command
	//   CTRL:      Group Locked/Speed command  (maintain relative positions)
	//
	// User Patrol and Fight Commands:
	//
	//   CTRL:      Group Locked/Speed command  (maintain relative positions)
	//   ALT+CTRL:  Group Locked       command  (maintain relative positions)
	//

	else if (((cmd_id == CMD_MOVE) || (cmd_id == CMD_FIGHT)) && (c.GetParamsCount() == 6)) {
		CalculateGroupData(player, !!(c.options & SHIFT_KEY));

		MakeFrontMove(&c, player);

		const bool groupSpeed = !!(c.options & CONTROL_KEY);
		for(ui = netSelected.begin(); ui != netSelected.end(); ++ui) {
			CUnit* unit = unitHandler->units[*ui];
			if (unit) {
				if (groupSpeed) {
					AddGroupSetMaxSpeedCommand(unit, c.options);
				} else {
					AddUnitSetMaxSpeedCommand(unit, c.options);
				}
			}
		}
	}
	else if ((cmd_id == CMD_MOVE) && (c.options & ALT_KEY)) {
		CalculateGroupData(player, !!(c.options & SHIFT_KEY));

		// use the vector from the middle of group to new pos as forward dir
		const float3 pos(c.GetParam(0), c.GetParam(1), c.GetParam(2));
		float3 frontdir = pos - centerCoor;
		frontdir.y = 0.0f;
		frontdir.ANormalize();
		const float3 sideDir = frontdir.cross(UpVector);

		// calculate so that the units form in an aproximate square
		float length = 100.0f + (math::sqrt((float)nbrOfSelectedUnits) * 32.0f);

		// push back some extra params so it confer with a front move
		c.PushPos(pos + (sideDir * length));

		MakeFrontMove(&c, player);

		const bool groupSpeed = !!(c.options & CONTROL_KEY);
		for(ui = netSelected.begin(); ui != netSelected.end(); ++ui) {
			CUnit* unit = unitHandler->units[*ui];
			if (unit) {
				if (groupSpeed) {
					AddGroupSetMaxSpeedCommand(unit, c.options);
				} else {
					AddUnitSetMaxSpeedCommand(unit, c.options);
				}
			}
		}
	}
	else if ((c.options & CONTROL_KEY) &&
	         ((cmd_id == CMD_MOVE) || (cmd_id == CMD_PATROL) || (cmd_id == CMD_FIGHT))) {
		CalculateGroupData(player, !!(c.options & SHIFT_KEY));

		const bool groupSpeed = !(c.options & ALT_KEY);

		for (ui = netSelected.begin(); ui != netSelected.end(); ++ui) {
			CUnit* unit = unitHandler->units[*ui];
			if (unit) {
				// Modifying the destination relative to the center of the group
				Command uc = c;
				float3 midPos;
				if (c.options & SHIFT_KEY) {
					midPos = LastQueuePosition(unit);
				} else {
					midPos = unit->midPos;
				}
				uc.params[CMDPARAM_MOVE_X] += midPos.x - centerCoor.x;
				uc.params[CMDPARAM_MOVE_Y] += midPos.y - centerCoor.y;
				uc.params[CMDPARAM_MOVE_Z] += midPos.z - centerCoor.z;
				unit->commandAI->GiveCommand(uc, false);

				if (groupSpeed) {
					AddGroupSetMaxSpeedCommand(unit, c.options);
				} else {
					AddUnitSetMaxSpeedCommand(unit, c.options);
				}
			}
		}
	}
	else {
		for (ui = netSelected.begin(); ui != netSelected.end(); ++ui) {
			CUnit* unit = unitHandler->units[*ui];
			if (unit) {
				// appending a CMD_SET_WANTED_MAX_SPEED command to
				// every command is a little bit wasteful, n'est pas?
				unit->commandAI->GiveCommand(c, false);
				if (MayRequireSetMaxSpeedCommand(c)) {
					AddUnitSetMaxSpeedCommand(unit, c.options);
				}
			}
		}
		if (cmd_id == CMD_WAIT) {
			if (player == gu->myPlayerNum) {
				waitCommandsAI.AcknowledgeCommand(c);
			}
		}
	}
}
Example #10
0
CommandResult Actions::echo(const Command &cmd)
{
  return {true, cmd.argument()};
}
// Only override the ones you need; the default action is to return false.
bool MapOutfitterPanel::KeyDown(SDL_Keycode key, Uint16 mod, const Command &command)
{
	if(command.Has(Command::MAP) || key == 'd' || key == SDLK_ESCAPE || (key == 'w' && (mod & (KMOD_CTRL | KMOD_GUI))))
		GetUI()->Pop(this);
	else if(key == 's')
	{
		GetUI()->Pop(this);
		GetUI()->Push(new MapShipyardPanel(*this));
	}
	else if(key == 'i')
	{
		GetUI()->Pop(this);
		GetUI()->Push(new MissionPanel(*this));
	}
	else if(key == 'p')
	{
		GetUI()->Pop(this);
		GetUI()->Push(new MapDetailPanel(*this));
	}
	else if((key == SDLK_DOWN || key == SDLK_UP) && !zones.empty())
	{
		// First, find the currently selected item, if any
		auto it = zones.begin();
		if(!selected)
		{
			if(key == SDLK_DOWN)
				it = --zones.end();
		}
		else
		{
			for( ; it != zones.end() - 1; ++it)
				if(it->Value() == selected)
					break;
		}
		if(key == SDLK_DOWN)
		{
			++it;
			if(it == zones.end())
				it = zones.begin();
		}
		else
		{
			if(it == zones.begin())
				it = zones.end();
			--it;
		}
		double top = (it->Center() - it->Size()).Y();
		double bottom = (it->Center() + it->Size()).Y();
		if(bottom > Screen::Bottom())
			scroll += Screen::Bottom() - bottom;
		if(top < Screen::Top())
			scroll += Screen::Top() - top;
		selected = it->Value();
	}
	else if(key == SDLK_PAGEUP || key == SDLK_PAGEDOWN)
	{
		scroll += (Screen::Height() - 100) * ((key == SDLK_PAGEUP) - (key == SDLK_PAGEDOWN));
		scroll = min(0, max(-maxScroll, scroll));
	}
	else
		return false;
	
	return true;
}
Example #12
0
void* ThreadPool::Process(void* arg)
{
    ThreadProcess threadprocess;
    Command command;
    while (true)
    {
        pthread_mutex_lock(&command_mutex_);
        // 如果线程需要退出,则此时退出
        if (1 == thread_id_map_[pthread_self()])
        {
            pthread_mutex_unlock(&command_mutex_);
            printf("thread %u will exit\n", pthread_self());
            pthread_exit(NULL);
        }
        // 当线程不需要退出且没有需要处理的任务时,需要缩容的则缩容,不需要的则等待信号
        if (0 == command_.size() && !bshutdown_)
        {
            if(icurr_thread_num_ >  THREAD_NUM)
            {
                DeleteThread();
                if (1 == thread_id_map_[pthread_self()])
                {
                    pthread_mutex_unlock(&command_mutex_);
                    printf("thread %u will exit\n", pthread_self());
                    pthread_exit(NULL);
                }
            }
            pthread_cond_wait(&command_cond_,&command_mutex_);
        }
        // 线程池需要关闭,关闭已有的锁,线程退出
        if(bshutdown_)
        {
            pthread_mutex_unlock (&command_mutex_);
            printf ("thread %u will exit\n", pthread_self ());
            pthread_exit (NULL);
        }
        // 如果线程池的最大线程数不等于初始线程数,则表明需要扩容
        if(icurr_thread_num_ < command_.size()))
        {
            AddThread();
        }
        // 从容器中取出待办任务
        std::vector<Command>::iterator iter = command_.begin();
        command.set_arg(iter->get_arg());
        command.set_cmd(iter->get_cmd());
        command_.erase(iter);
        pthread_mutex_unlock(&command_mutex_);
        // 开始业务处理
        switch(command.get_cmd())
        {
        case 0:
            threadprocess.Process0(command.get_arg());
            break;
        case 1:
            threadprocess.Process1(command.get_arg());
            break;
        case 2:
            threadprocess.Process2(command.get_arg());
            break;
        default:
            break;
        }
    }
    return NULL; // 完全为了消除警告(eclipse编写的代码,警告很烦人)
}
 ExecResult
 operator() (ARGS&& ...args)
   {
     com_.bind (std::forward<ARGS> (args)...);
     return com_();
   }
Example #14
0
/** Checks for an already occupied shortcut. */
void DlgCustomKeyboardImp::on_editShortcut_textChanged(const QString& sc)
{
    assignedTreeWidget->clear();
    QTreeWidgetItem* item = commandTreeWidget->currentItem();
    if (!item)
        return;
    QVariant data = item->data(1, Qt::UserRole);
    QByteArray name = data.toByteArray(); // command name

    CommandManager & cCmdMgr = Application::Instance->commandManager();
    Command* cmd = cCmdMgr.getCommandByName(name.constData());
    if (cmd && !cmd->getAction()) {
        buttonAssign->setEnabled(false); // command not in use
        return;
    }

    buttonAssign->setEnabled(true);
    QKeySequence ks(sc);
    if (!ks.isEmpty()) {
        int countAmbiguous = 0;
        QString ambiguousCommand;
        QString ambiguousMenu;

        CommandManager & cCmdMgr = Application::Instance->commandManager();
        std::vector<Command*> cmds = cCmdMgr.getAllCommands();
        for (std::vector<Command*>::iterator it = cmds.begin(); it != cmds.end(); ++it) {
            QList<QAction*> acts;
            if ((*it)->getAction()) {
                // A command may have several QAction's. So, check all of them if one of them matches (See bug #0002160)
                QList<QAction*> acts = (*it)->getAction()->findChildren<QAction*>();
                for (QList<QAction*>::iterator jt = acts.begin(); jt != acts.end(); ++jt) {
                    if ((*jt)->shortcut() == ks) {
                        ++countAmbiguous;
                        ambiguousCommand = QString::fromLatin1((*it)->getName()); // store the last one
                        ambiguousMenu = qApp->translate((*it)->className(), (*it)->getMenuText());

                        QTreeWidgetItem* item = new QTreeWidgetItem(assignedTreeWidget);
                        item->setText(1, qApp->translate((*it)->className(), (*it)->getMenuText()));
                        item->setToolTip(1, qApp->translate((*it)->className(), (*it)->getToolTipText()));
                        item->setData(1, Qt::UserRole, QByteArray((*it)->getName()));
                        item->setSizeHint(0, QSize(32, 32));
                        if ((*it)->getPixmap())
                            item->setIcon(0, BitmapFactory().iconFromTheme((*it)->getPixmap()));
                        break;
                    }
                }
            }
        }

        if (countAmbiguous > 0)
            assignedTreeWidget->resizeColumnToContents(0);
        
        if (countAmbiguous > 1) {
            QMessageBox::warning(this, tr("Multiple defined shortcut"),
                                 tr("The shortcut '%1' is defined more than once. This could result into unexpected behaviour.").arg(sc) );
            editShortcut->setFocus();
            buttonAssign->setEnabled(false);
        } else if (countAmbiguous == 1 && ambiguousCommand != QLatin1String(name)) {
            QMessageBox::warning(this, tr("Already defined shortcut"),
                                 tr("The shortcut '%1' is already assigned to '%2'.\n\nPlease define another shortcut.").arg(sc).arg(ambiguousMenu) );
            editShortcut->setFocus();
            buttonAssign->setEnabled(false);
        } else {
            if (cmd && cmd->getAction() && cmd->getAction()->shortcut() == ks)
                buttonAssign->setEnabled(false);
        }
    } else {
        if (cmd && cmd->getAction() && cmd->getAction()->shortcut().isEmpty())
            buttonAssign->setEnabled(false); // both key sequences are empty
    }
}
Example #15
0
int ClusterCommand::execute(){
	try {
	
		if (abort == true) { if (calledHelp) { return 0; }  return 2;	}
		
		//phylip file given and cutoff not given - use cluster.classic because it uses less memory and is faster
		if ((format == "phylip") && (cutoff > 10.0)) {
			m->mothurOutEndLine(); m->mothurOut("You are using a phylip file and no cutoff.  I will run cluster.classic to save memory and time."); m->mothurOutEndLine();
			
			//run unique.seqs for deconvolute results
			string inputString = "phylip=" + distfile;
			if (namefile != "") { inputString += ", name=" + namefile; }
            else if (countfile != "") { inputString += ", count=" + countfile; }
			inputString += ", precision=" + toString(precision);
			inputString += ", method=" + method;
			if (hard)	{ inputString += ", hard=T";	}
			else		{ inputString += ", hard=F";	}
			if (sim)	{ inputString += ", sim=T";		}
			else		{ inputString += ", sim=F";		}

			
			m->mothurOutEndLine(); 
			m->mothurOut("/------------------------------------------------------------/"); m->mothurOutEndLine(); 
			m->mothurOut("Running command: cluster.classic(" + inputString + ")"); m->mothurOutEndLine(); 
			
			Command* clusterClassicCommand = new ClusterDoturCommand(inputString);
			clusterClassicCommand->execute();
			delete clusterClassicCommand;
			
			m->mothurOut("/------------------------------------------------------------/"); m->mothurOutEndLine();  

			return 0;
		}
		
		ReadMatrix* read;
		if (format == "column") { read = new ReadColumnMatrix(columnfile, sim); }	//sim indicates whether its a similarity matrix
		else if (format == "phylip") { read = new ReadPhylipMatrix(phylipfile, sim); }
		
		read->setCutoff(cutoff);
		
		NameAssignment* nameMap = NULL;
        CountTable* ct = NULL;
        map<string, int> counts;
		if(namefile != ""){	
			nameMap = new NameAssignment(namefile);
			nameMap->readMap();
            read->read(nameMap);
		}else if (countfile != "") {
            ct = new CountTable();
            ct->readTable(countfile, false, false);
            read->read(ct);
            counts = ct->getNameMap();
        }else { read->read(nameMap); }
		
		list = read->getListVector();
		matrix = read->getDMatrix();
        
		if(countfile != "") {
            rabund = new RAbundVector();
            createRabund(ct, list, rabund); //creates an rabund that includes the counts for the unique list
            delete ct;
        }else { rabund = new RAbundVector(list->getRAbundVector()); }
		delete read;
		
		if (m->control_pressed) { //clean up
			delete list; delete matrix; delete rabund; if(countfile == ""){rabundFile.close(); sabundFile.close();  m->mothurRemove((fileroot+ tag + ".rabund")); m->mothurRemove((fileroot+ tag + ".sabund")); }
			listFile.close(); m->mothurRemove((fileroot+ tag + ".list")); outputTypes.clear(); return 0;
		}
		
		//create cluster
		if (method == "furthest")	{	cluster = new CompleteLinkage(rabund, list, matrix, cutoff, method, adjust); }
		else if(method == "nearest"){	cluster = new SingleLinkage(rabund, list, matrix, cutoff, method, adjust); }
		else if(method == "average"){	cluster = new AverageLinkage(rabund, list, matrix, cutoff, method, adjust);	}
		else if(method == "weighted"){	cluster = new WeightedLinkage(rabund, list, matrix, cutoff, method, adjust);	}
		tag = cluster->getTag();
		
		if (outputDir == "") { outputDir += m->hasPath(distfile); }
		fileroot = outputDir + m->getRootName(m->getSimpleName(distfile));
		
        map<string, string> variables; 
        variables["[filename]"] = fileroot;
        variables["[clustertag]"] = tag;
        string sabundFileName = getOutputFileName("sabund", variables);
        string rabundFileName = getOutputFileName("rabund", variables);
        if (countfile != "") { variables["[tag2]"] = "unique_list"; }
        string listFileName = getOutputFileName("list", variables);
        
        if (countfile == "") {
            m->openOutputFile(sabundFileName,	sabundFile);
            m->openOutputFile(rabundFileName,	rabundFile);
            outputNames.push_back(sabundFileName); outputTypes["sabund"].push_back(sabundFileName);
            outputNames.push_back(rabundFileName); outputTypes["rabund"].push_back(rabundFileName);

        }
		m->openOutputFile(listFileName,	listFile);
        outputNames.push_back(listFileName); outputTypes["list"].push_back(listFileName);
        list->printHeaders(listFile);
		
		time_t estart = time(NULL);
		float previousDist = 0.00000;
		float rndPreviousDist = 0.00000;
		oldRAbund = *rabund;
		oldList = *list;

		print_start = true;
		start = time(NULL);
		loops = 0;
		double saveCutoff = cutoff;
		
		while (matrix->getSmallDist() < cutoff && matrix->getNNodes() > 0){  
		
			if (m->control_pressed) { //clean up
				delete list; delete matrix; delete rabund; delete cluster;
				if(countfile == "") {rabundFile.close(); sabundFile.close();  m->mothurRemove((fileroot+ tag + ".rabund")); m->mothurRemove((fileroot+ tag + ".sabund")); }
                listFile.close(); m->mothurRemove((fileroot+ tag + ".list")); outputTypes.clear(); return 0;
			}
		
			if (print_start && m->isTrue(timing)) {
				m->mothurOut("Clustering (" + tag + ") dist " + toString(matrix->getSmallDist()) + "/" 
					+ toString(m->roundDist(matrix->getSmallDist(), precision)) 
					+ "\t(precision: " + toString(precision) + ", Nodes: " + toString(matrix->getNNodes()) + ")");
				cout.flush();
				print_start = false;
			}

			loops++;

			cluster->update(cutoff);
            
            float dist = matrix->getSmallDist();
			float rndDist;
			if (hard) {
				rndDist = m->ceilDist(dist, precision); 
			}else{
				rndDist = m->roundDist(dist, precision); 
			}

			if(previousDist <= 0.0000 && dist != previousDist){
				printData("unique", counts);
			}
			else if(rndDist != rndPreviousDist){
				printData(toString(rndPreviousDist,  length-1), counts);
			}
		
			previousDist = dist;
			rndPreviousDist = rndDist;
			oldRAbund = *rabund;
			oldList = *list;
		}

		if (print_start && m->isTrue(timing)) {
			m->mothurOut("Clustering (" + tag + ") for distance " + toString(previousDist) + "/" + toString(rndPreviousDist) 
					 + "\t(precision: " + toString(precision) + ", Nodes: " + toString(matrix->getNNodes()) + ")");
			cout.flush();
	 		print_start = false;
		}
		
		if(previousDist <= 0.0000){
			printData("unique", counts);
		}
		else if(rndPreviousDist<cutoff){
			printData(toString(rndPreviousDist, length-1), counts);
		}
		
		delete matrix;
		delete list;
		delete rabund;
		delete cluster;
        if (countfile == "") {
            sabundFile.close();
            rabundFile.close();
        }
		listFile.close();
	
		if (saveCutoff != cutoff) { 
			if (hard)	{  saveCutoff = m->ceilDist(saveCutoff, precision);	}
			else		{	saveCutoff = m->roundDist(saveCutoff, precision);  }

			m->mothurOut("changed cutoff to " + toString(cutoff)); m->mothurOutEndLine(); 
		}
		
		//set list file as new current listfile
		string current = "";
		itTypes = outputTypes.find("list");
		if (itTypes != outputTypes.end()) {
			if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setListFile(current); }
		}
		
		//set rabund file as new current rabundfile
		itTypes = outputTypes.find("rabund");
		if (itTypes != outputTypes.end()) {
			if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setRabundFile(current); }
		}
		
		//set sabund file as new current sabundfile
		itTypes = outputTypes.find("sabund");
		if (itTypes != outputTypes.end()) {
			if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setSabundFile(current); }
		}
		
		m->mothurOutEndLine();
		m->mothurOut("Output File Names: "); m->mothurOutEndLine();
		for (int i = 0; i < outputNames.size(); i++) {	m->mothurOut(outputNames[i]); m->mothurOutEndLine();	}
		m->mothurOutEndLine();

		
		//if (m->isTrue(timing)) {
			m->mothurOut("It took " + toString(time(NULL) - estart) + " seconds to cluster"); m->mothurOutEndLine();
		//}
		
		
		return 0;
	}
	catch(exception& e) {
		m->errorOut(e, "ClusterCommand", "execute");
		exit(1);
	}
}
Example #16
0
void
NNCommand2(Connection *conn)
{
    char *ptr;
    char *cmd;
    char *buf;
    Command *scan;
    int len;

    conn->co_Func = NNCommand2;
    conn->co_State = "waitcmd";

    /*
     * we have to be careful in regards to recursive operation, nor do
     * we want one descriptor to hog the process.  We can't set RFds
     * because the next command may already be entirely loaded into an
     * MBuf so setting RFds may not unblock us.  Instead, we set WFds
     * which basically forces a wakeup at some point in the future.
     */

    if (conn->co_FCounter) {
	FD_SET(conn->co_Desc->d_Fd, &WFds);
	/*
	 * if the other side closed the connection, select() is
	 * not going to wake up for write(!) so set RFds too.
	 */
	if (conn->co_TMBuf.mh_WError)
	    FD_SET(conn->co_Desc->d_Fd, &RFds);
	return;
    }
    ++conn->co_FCounter;

    /*
     * if there is still output pending, do not process the next
     * command.
     */
    if (conn->co_TMBuf.mh_Bytes > 0 && !conn->co_TMBuf.mh_WError)
	return;

    /*
     * get command
     */

    if ((len = MBReadLine(&conn->co_RMBuf, &buf)) == 0) {
	StatusUpdate(conn, "(idle)");
	return;
    }

    conn->co_ByteCountType = DRBC_NONE;

    /*
     * check EOF
     */

    if (len < 0 || conn->co_TMBuf.mh_WError) {
	NNTerminate(conn);
	return;
    }

    /*
     * strip CR LF
     */

    ptr = buf;

    if (len > 1 && ptr[len-2] == '\r')
	ptr[len-2] = 0;

    if (DebugOpt)
	printf("command: %s\n", ptr);

    if (strncasecmp(ptr, "authinfo pass ", 14)) {
        LogCmd(conn, '<', ptr);
    } else {
        LogCmd(conn, '<', "authinfo pass **unlogged**");
    }

    if (conn->co_Auth.dr_Flags & DF_USEPROXIED) {
      struct sockaddr_in sin;
      char *pt = NULL;

      if (strncasecmp(ptr, "proxied ", 8) || ! ((pt = strrchr(ptr, ':')))) {
          MBLogPrintf(conn,
              &conn->co_TMBuf,
              "400 %s: Proxy authentication failure.\r\n",
              conn->co_Auth.dr_VServerDef->vs_HostName
          );
          NNTerminate(conn);
      }

      *pt++ = '\0';
      ptr += 8;

      bzero((void *)&sin, sizeof(&sin));
      sin.sin_family = AF_INET;
      sin.sin_port = htons(atoi(pt));
      sin.sin_addr.s_addr = inet_addr(ptr);
      bcopy(&sin, &conn->co_Auth.dr_Addr, sizeof(conn->co_Auth.dr_Addr));

      conn->co_Auth.dr_Flags &= ~DF_USEPROXIED;
      conn->co_Auth.dr_ResultFlags = DR_REQUIRE_DNS;
      return;
    }

    /*
     * extract command (note: StatusUpdate() will limit the line length)
     */

    StatusUpdate(conn, "%s", ptr);

    if ((cmd = parseword(&ptr, " \t")) == NULL) {
	NNCommand(conn);
	return;
    }
    {
	int i;

	for (i = 0; cmd[i]; ++i)
	    cmd[i] = tolower((int)(unsigned char)cmd[i]);
    }

    /*
     * Locate and execute command
     */

    for (scan = &Cmds[0]; scan < &Cmds[arysize(Cmds)]; ++scan) {
	if (strcmp(cmd, scan->cmd_Name) == 0) {
	    if (conn->co_Flags & COF_SERVER) {
		if (scan->cmd_Flags & CMDF_SERVER) {
		    if ((conn->co_Auth.dr_Flags & DF_FEEDONLY) == 0)
			break;
		    if ((scan->cmd_Flags & CMDF_NOTFEEDONLY) == 0)
			break;
		}
	    } else {
		if (scan->cmd_Flags & CMDF_READER)
		    break;
	    }
	}
    }
    if (scan < &Cmds[arysize(Cmds)]) {
	if ((scan->cmd_Flags & CMDF_AUTH) &&
	    (conn->co_Auth.dr_Flags & DF_AUTHREQUIRED)
	) {
	    MBLogPrintf(conn, &conn->co_TMBuf, "480 Authentication required for command\r\n");
	    NNCommand(conn);
	} else {
	    conn->co_ByteCountType = scan->cmd_DRBC_Type;
	    scan->cmd_Func(conn, &ptr);
	}
    } else {
	NNUnknownCommand(conn);
    }
}
Example #17
0
void CommandParser::ProcessCommand(LocalUser *user, std::string &cmd)
{
	std::vector<std::string> command_p;
	irc::tokenstream tokens(cmd);
	std::string command, token;
	tokens.GetToken(command);

	/* A client sent a nick prefix on their command (ick)
	 * rhapsody and some braindead bouncers do this --
	 * the rfc says they shouldnt but also says the ircd should
	 * discard it if they do.
	 */
	if (command[0] == ':')
		tokens.GetToken(command);

	while (tokens.GetToken(token))
		command_p.push_back(token);

	std::transform(command.begin(), command.end(), command.begin(), ::toupper);

	/* find the command, check it exists */
	Command* handler = GetHandler(command);

	/* Modify the user's penalty regardless of whether or not the command exists */
	if (!user->HasPrivPermission("users/flood/no-throttle"))
	{
		// If it *doesn't* exist, give it a slightly heftier penalty than normal to deter flooding us crap
		user->CommandFloodPenalty += handler ? handler->Penalty * 1000 : 2000;
	}

	if (!handler)
	{
		ModResult MOD_RESULT;
		FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, command_p, user, false, cmd));
		if (MOD_RESULT == MOD_RES_DENY)
			return;

		/*
		 * This double lookup is in case a module (abbreviation) wishes to change a command.
		 * Sure, the double lookup is a bit painful, but bear in mind this only happens for unknowns anyway.
		 *
		 * Thanks dz for making me actually understand why this is necessary!
		 * -- w00t
		 */
		handler = GetHandler(command);
		if (!handler)
		{
			if (user->registered == REG_ALL)
				user->WriteNumeric(ERR_UNKNOWNCOMMAND, "%s :Unknown command",command.c_str());
			ServerInstance->stats->statsUnknown++;
			return;
		}
	}

	// If we were given more parameters than max_params then append the excess parameter(s)
	// to command_p[maxparams-1], i.e. to the last param that is still allowed
	if (handler->max_params && command_p.size() > handler->max_params)
	{
		/*
		 * command_p input (assuming max_params 1):
		 *	this
		 *	is
		 *	a
		 *	test
		 */

		// Iterator to the last parameter that will be kept
		const std::vector<std::string>::iterator lastkeep = command_p.begin() + (handler->max_params - 1);
		// Iterator to the first excess parameter
		const std::vector<std::string>::iterator firstexcess = lastkeep + 1;

		// Append all excess parameter(s) to the last parameter, seperated by spaces
		for (std::vector<std::string>::const_iterator i = firstexcess; i != command_p.end(); ++i)
		{
			lastkeep->push_back(' ');
			lastkeep->append(*i);
		}

		// Erase the excess parameter(s)
		command_p.erase(firstexcess, command_p.end());
	}

	/*
	 * We call OnPreCommand here seperately if the command exists, so the magic above can
	 * truncate to max_params if necessary. -- w00t
	 */
	ModResult MOD_RESULT;
	FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, command_p, user, false, cmd));
	if (MOD_RESULT == MOD_RES_DENY)
		return;

	/* activity resets the ping pending timer */
	user->nping = ServerInstance->Time() + user->MyClass->GetPingTime();

	if (handler->flags_needed)
	{
		if (!user->IsModeSet(handler->flags_needed))
		{
			user->WriteNumeric(ERR_NOPRIVILEGES, ":Permission Denied - You do not have the required operator privileges");
			return;
		}

		if (!user->HasPermission(command))
		{
			user->WriteNumeric(ERR_NOPRIVILEGES, ":Permission Denied - Oper type %s does not have access to command %s",
				user->oper->name.c_str(), command.c_str());
			return;
		}
	}

	if ((user->registered == REG_ALL) && (!user->IsOper()) && (handler->IsDisabled()))
	{
		/* command is disabled! */
		if (ServerInstance->Config->DisabledDontExist)
		{
			user->WriteNumeric(ERR_UNKNOWNCOMMAND, "%s :Unknown command", command.c_str());
		}
		else
		{
			user->WriteNumeric(ERR_UNKNOWNCOMMAND, "%s :This command has been disabled.", command.c_str());
		}

		ServerInstance->SNO->WriteToSnoMask('t', "%s denied for %s (%s@%s)",
				command.c_str(), user->nick.c_str(), user->ident.c_str(), user->host.c_str());
		return;
	}

	if ((!command_p.empty()) && (command_p.back().empty()) && (!handler->allow_empty_last_param))
		command_p.pop_back();

	if (command_p.size() < handler->min_params)
	{
		user->WriteNumeric(ERR_NEEDMOREPARAMS, "%s :Not enough parameters.", command.c_str());
		if ((ServerInstance->Config->SyntaxHints) && (user->registered == REG_ALL) && (handler->syntax.length()))
			user->WriteNumeric(RPL_SYNTAX, ":SYNTAX %s %s", handler->name.c_str(), handler->syntax.c_str());
		return;
	}

	if ((user->registered != REG_ALL) && (!handler->WorksBeforeReg()))
	{
		user->WriteNumeric(ERR_NOTREGISTERED, "%s :You have not registered",command.c_str());
	}
	else
	{
		/* passed all checks.. first, do the (ugly) stats counters. */
		handler->use_count++;

		/* module calls too */
		FIRST_MOD_RESULT(OnPreCommand, MOD_RESULT, (command, command_p, user, true, cmd));
		if (MOD_RESULT == MOD_RES_DENY)
			return;

		/*
		 * WARNING: be careful, the user may be deleted soon
		 */
		CmdResult result = handler->Handle(command_p, user);

		FOREACH_MOD(OnPostCommand, (handler, command_p, user, result, cmd));
	}
}
void OutputPaneManager::init()
{
    ActionContainer *mwindow = ActionManager::actionContainer(Constants::M_WINDOW);
    const Context globalContext(Constants::C_GLOBAL);

    // Window->Output Panes
    ActionContainer *mpanes = ActionManager::createMenu(Constants::M_WINDOW_PANES);
    mwindow->addMenu(mpanes, Constants::G_WINDOW_PANES);
    mpanes->menu()->setTitle(tr("Output &Panes"));
    mpanes->appendGroup("Coreplugin.OutputPane.ActionsGroup");
    mpanes->appendGroup("Coreplugin.OutputPane.PanesGroup");

    Command *cmd;

    cmd = ActionManager::registerAction(m_clearAction, "Coreplugin.OutputPane.clear", globalContext);
    m_clearButton->setDefaultAction(cmd->action());
    mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");

    cmd = ActionManager::registerAction(m_prevAction, "Coreplugin.OutputPane.previtem", globalContext);
    cmd->setDefaultKeySequence(QKeySequence(tr("Shift+F6")));
    m_prevToolButton->setDefaultAction(cmd->action());
    mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");

    cmd = ActionManager::registerAction(m_nextAction, "Coreplugin.OutputPane.nextitem", globalContext);
    m_nextToolButton->setDefaultAction(cmd->action());
    cmd->setDefaultKeySequence(QKeySequence(tr("F6")));
    mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");

    cmd = ActionManager::registerAction(m_minMaxAction, "Coreplugin.OutputPane.minmax", globalContext);
    cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Ctrl+9") : tr("Alt+9")));
    cmd->setAttribute(Command::CA_UpdateText);
    cmd->setAttribute(Command::CA_UpdateIcon);
    mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup");
    connect(m_minMaxAction, SIGNAL(triggered()), this, SLOT(slotMinMax()));
    m_minMaxButton->setDefaultAction(cmd->action());

    mpanes->addSeparator(globalContext, "Coreplugin.OutputPane.ActionsGroup");

    QFontMetrics titleFm = m_titleLabel->fontMetrics();
    int minTitleWidth = 0;

    m_panes = ExtensionSystem::PluginManager::getObjects<IOutputPane>();
    qSort(m_panes.begin(), m_panes.end(), &comparePanes);
    const int n = m_panes.size();

    int shortcutNumber = 1;
    const Id baseId = Id("QtCreator.Pane.");
    for (int i = 0; i != n; ++i) {
        IOutputPane *outPane = m_panes.at(i);
        const int idx = m_outputWidgetPane->addWidget(outPane->outputWidget(this));
        QTC_CHECK(idx == i);

        connect(outPane, SIGNAL(showPage(int)), this, SLOT(showPage(int)));
        connect(outPane, SIGNAL(hidePage()), this, SLOT(slotHide()));
        connect(outPane, SIGNAL(togglePage(int)), this, SLOT(togglePage(int)));
        connect(outPane, SIGNAL(navigateStateUpdate()), this, SLOT(updateNavigateState()));
        connect(outPane, SIGNAL(flashButton()), this, SLOT(flashButton()));
        connect(outPane, SIGNAL(setBadgeNumber(int)), this, SLOT(setBadgeNumber(int)));

        QWidget *toolButtonsContainer = new QWidget(m_opToolBarWidgets);
        QHBoxLayout *toolButtonsLayout = new QHBoxLayout;
        toolButtonsLayout->setMargin(0);
        toolButtonsLayout->setSpacing(0);
        foreach (QWidget *toolButton, outPane->toolBarWidgets())
            toolButtonsLayout->addWidget(toolButton);
        toolButtonsLayout->addStretch(5);
        toolButtonsContainer->setLayout(toolButtonsLayout);

        m_opToolBarWidgets->addWidget(toolButtonsContainer);

        minTitleWidth = qMax(minTitleWidth, titleFm.width(outPane->displayName()));

        QString suffix = outPane->displayName().simplified();
        suffix.remove(QLatin1Char(' '));
        const Id id = baseId.withSuffix(suffix);
        QAction *action = new QAction(outPane->displayName(), this);
        Command *cmd = ActionManager::registerAction(action, id, globalContext);

        mpanes->addAction(cmd, "Coreplugin.OutputPane.PanesGroup");
        m_actions.append(cmd->action());
        m_ids.append(id);

        cmd->setDefaultKeySequence(QKeySequence(paneShortCut(shortcutNumber)));
        OutputPaneToggleButton *button = new OutputPaneToggleButton(shortcutNumber, outPane->displayName(),
                                                                    cmd->action());
        ++shortcutNumber;
        m_buttonsWidget->layout()->addWidget(button);
        m_buttons.append(button);
        connect(button, SIGNAL(clicked()), this, SLOT(buttonTriggered()));

        bool visible = outPane->priorityInStatusBar() != -1;
        button->setVisible(visible);

        connect(cmd->action(), SIGNAL(triggered()), this, SLOT(shortcutTriggered()));
    }

    m_titleLabel->setMinimumWidth(minTitleWidth + m_titleLabel->contentsMargins().left()
                                  + m_titleLabel->contentsMargins().right());
    m_buttonsWidget->layout()->addWidget(m_manageButton);
    connect(m_manageButton, SIGNAL(clicked()), this, SLOT(popupMenu()));

    readSettings();
}
Example #19
0
bool CCommandAI::AllowedCommand(const Command& c, bool fromSynced)
{
	const int cmdID = c.GetID();

	// TODO check if the command is in the map first, for more commands
	switch (cmdID) {
		case CMD_MOVE:
		case CMD_ATTACK:
		case CMD_AREA_ATTACK:
		case CMD_RECLAIM:
		case CMD_REPAIR:
		case CMD_RESURRECT:
		case CMD_PATROL:
		case CMD_RESTORE:
		case CMD_FIGHT:
		case CMD_MANUALFIRE:
		case CMD_UNLOAD_UNIT:
		case CMD_UNLOAD_UNITS: {
			if (!IsCommandInMap(c)) {
				return false;
			}
		} break;

		default: {
			// build commands
			if (cmdID < 0) {
				if (!IsCommandInMap(c))
					return false;

				const CBuilderCAI* bcai = dynamic_cast<const CBuilderCAI*>(this);
				const CFactoryCAI* fcai = dynamic_cast<const CFactoryCAI*>(this);

				// non-builders cannot ever execute these
				// we can get here if a factory is selected along with the
				// unit it is currently building and a build-order is given
				// to the former
				if (fcai == NULL && bcai == NULL)
					return false;

				// {Builder,Factory}CAI::GiveCommandReal (should) handle the
				// case where buildOptions.find(cmdID) == buildOptions.end()
			}
		} break;
	}


	const UnitDef* ud = owner->unitDef;
	// AI's may do as they like
	const CSkirmishAIHandler::ids_t& saids = skirmishAIHandler.GetSkirmishAIsInTeam(owner->team);
	const bool aiOrder = (!saids.empty());

	switch (cmdID) {
		case CMD_MANUALFIRE:
			if (!ud->canManualFire)
				return false;
			// fall through

		case CMD_ATTACK: {
			if (!IsAttackCapable())
				return false;

			if (c.params.size() == 1) {
				const CUnit* attackee = GetCommandUnit(c, 0);

				if (attackee == NULL)
					return false;
				if (!attackee->pos.IsInBounds())
					return false;
			} else {
				AdjustGroundAttackCommand(c, fromSynced, aiOrder);
			}
			break;
		}

		case CMD_MOVE:      if (!ud->canmove)       return false; break;
		case CMD_FIGHT:     if (!ud->canFight)      return false; break;
		case CMD_GUARD: {
			const CUnit* guardee = GetCommandUnit(c, 0);

			if (!ud->canGuard) { return false; }
			if (owner && !owner->pos.IsInBounds()) { return false; }
			if (guardee && !guardee->pos.IsInBounds()) { return false; }
		} break;

		case CMD_PATROL: {
			if (!ud->canPatrol) { return false; }
		} break;

		case CMD_CAPTURE: {
			const CUnit* capturee = GetCommandUnit(c, 0);

			if (!ud->canCapture) { return false; }
			if (capturee && !capturee->pos.IsInBounds()) { return false; }
		} break;

		case CMD_RECLAIM: {
			const CUnit* reclaimeeUnit = GetCommandUnit(c, 0);
			const CFeature* reclaimeeFeature = NULL;

			if (c.IsAreaCommand()) { return true; }
			if (!ud->canReclaim) { return false; }
			if (reclaimeeUnit && !reclaimeeUnit->unitDef->reclaimable) { return false; }
			if (reclaimeeUnit && !reclaimeeUnit->AllowedReclaim(owner)) { return false; }
			if (reclaimeeUnit && !reclaimeeUnit->pos.IsInBounds()) { return false; }

			if (reclaimeeUnit == NULL && !c.params.empty()) {
				const unsigned int reclaimeeFeatureID(c.params[0]);

				if (reclaimeeFeatureID >= unitHandler->MaxUnits()) {
					reclaimeeFeature = featureHandler->GetFeature(reclaimeeFeatureID - unitHandler->MaxUnits());

					if (reclaimeeFeature && !reclaimeeFeature->def->reclaimable) {
						return false;
					}
				}
			}
		} break;

		case CMD_RESTORE: {
			if (!ud->canRestore || mapDamage->disabled) {
				return false;
			}
		} break;

		case CMD_RESURRECT: {
			if (!ud->canResurrect) { return false; }
		} break;

		case CMD_REPAIR: {
			const CUnit* repairee = GetCommandUnit(c, 0);

			if (!ud->canRepair && !ud->canAssist) { return false; }
			if (repairee && !repairee->pos.IsInBounds()) { return false; }
			if (repairee && ((repairee->beingBuilt && !ud->canAssist) || (!repairee->beingBuilt && !ud->canRepair))) { return false; }
		} break;
	}


	if (cmdID == CMD_FIRE_STATE
			&& (c.params.empty() || !CanChangeFireState()))
	{
		return false;
	}
	if (cmdID == CMD_MOVE_STATE
			&& (c.params.empty() || (!ud->canmove && !ud->builder)))
	{
		return false;
	}
	if (cmdID == CMD_REPEAT && (c.params.empty() || !ud->canRepeat || ((int)c.params[0] % 2) != (int)c.params[0]/* only 0 or 1 allowed */))
	{
		return false;
	}
	if (cmdID == CMD_TRAJECTORY
			&& (c.params.empty() || ud->highTrajectoryType < 2))
	{
		return false;
	}
	if (cmdID == CMD_ONOFF
			&& (c.params.empty() || !ud->onoffable || owner->beingBuilt || ((int)c.params[0] % 2) != (int)c.params[0]/* only 0 or 1 allowed */))
	{
		return false;
	}
	if (cmdID == CMD_CLOAK && (c.params.empty() || !ud->canCloak || ((int)c.params[0] % 2) != (int)c.params[0]/* only 0 or 1 allowed */))
	{
		return false;
	}
	if (cmdID == CMD_STOCKPILE && !stockpileWeapon)
	{
		return false;
	}
	return true;
}
Example #20
0
    string OpDebug::report(const CurOp& curop, const SingleThreadedLockStats& lockStats) const {
        StringBuilder s;
        if ( iscommand )
            s << "command ";
        else
            s << opToString( op ) << ' ';
        s << ns;

        if ( ! query.isEmpty() ) {
            if ( iscommand ) {
                s << " command: ";

                Command* curCommand = curop.getCommand();
                if (curCommand) {
                    mutablebson::Document cmdToLog(query, mutablebson::Document::kInPlaceDisabled);
                    curCommand->redactForLogging(&cmdToLog);
                    s << curCommand->name << " ";
                    s << cmdToLog.toString();
                }
                else { // Should not happen but we need to handle curCommand == NULL gracefully
                    s << query.toString();
                }
            }
            else {
                s << " query: ";
                s << query.toString();
            }
        }

        if (!planSummary.empty()) {
            s << " planSummary: " << planSummary.toString();
        }

        if ( ! updateobj.isEmpty() ) {
            s << " update: ";
            updateobj.toString( s );
        }

        OPDEBUG_TOSTRING_HELP( cursorid );
        OPDEBUG_TOSTRING_HELP( ntoreturn );
        OPDEBUG_TOSTRING_HELP( ntoskip );
        OPDEBUG_TOSTRING_HELP_BOOL( exhaust );

        OPDEBUG_TOSTRING_HELP( nscanned );
        OPDEBUG_TOSTRING_HELP( nscannedObjects );
        OPDEBUG_TOSTRING_HELP_BOOL( idhack );
        OPDEBUG_TOSTRING_HELP_BOOL( scanAndOrder );
        OPDEBUG_TOSTRING_HELP( nmoved );
        OPDEBUG_TOSTRING_HELP( nMatched );
        OPDEBUG_TOSTRING_HELP( nModified );
        OPDEBUG_TOSTRING_HELP( ninserted );
        OPDEBUG_TOSTRING_HELP( ndeleted );
        OPDEBUG_TOSTRING_HELP_BOOL( fastmod );
        OPDEBUG_TOSTRING_HELP_BOOL( fastmodinsert );
        OPDEBUG_TOSTRING_HELP_BOOL( upsert );
        OPDEBUG_TOSTRING_HELP_BOOL( cursorExhausted );
        OPDEBUG_TOSTRING_HELP( keyUpdates );
        OPDEBUG_TOSTRING_HELP( writeConflicts );

        if ( extra.len() )
            s << " " << extra.str();

        if ( ! exceptionInfo.empty() ) {
            s << " exception: " << exceptionInfo.msg;
            if ( exceptionInfo.code )
                s << " code:" << exceptionInfo.code;
        }

        s << " numYields:" << curop.numYields();

        OPDEBUG_TOSTRING_HELP( nreturned );
        if (responseLength > 0) {
            s << " reslen:" << responseLength;
        }

        {
            BSONObjBuilder locks;
            lockStats.report(&locks);
            s << " locks:" << locks.obj().toString();
        }

        s << " " << executionTime << "ms";

        return s.str();
    }
Example #21
0
void CCommandAI::ClearTargetLock(const Command &c) {
	if (((c.GetID() == CMD_ATTACK) || (c.GetID() == CMD_MANUALFIRE)) && (c.options & META_KEY) == 0) {
		// no meta-bit attack lock, clear the order
		owner->DropCurrentAttackTarget();
	}
}
static
void ExecuteTemplightCommand(Driver &TheDriver, DiagnosticsEngine &Diags,
    Compilation &C, Command &J, const char* Argv0,
    SmallVector<std::pair<int, const Command *>, 4>& FailingCommands) {

  // Since commandLineFitsWithinSystemLimits() may underestimate system's capacity
  // if the tool does not support response files, there is a chance/ that things
  // will just work without a response file, so we silently just skip it.
  if ( J.getCreator().getResponseFilesSupport() != Tool::RF_None &&
       llvm::sys::commandLineFitsWithinSystemLimits(
         StringRef(J.getCreator().getName()), J.getArguments()) ) {
    std::string TmpName = TheDriver.GetTemporaryPath("response", "txt");
    J.setResponseFile(C.addTempFile(C.getArgs().MakeArgString(TmpName.c_str())));
  }

  if ( StringRef(J.getCreator().getName()) == "clang" ) {
    // Initialize a compiler invocation object from the clang (-cc1) arguments.
    const ArgStringList &cc_arguments = J.getArguments();
    const char** args_start = const_cast<const char**>(cc_arguments.data());
    const char** args_end = args_start + cc_arguments.size();

    std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());

    int Res = !CompilerInvocation::CreateFromArgs(
        Clang->getInvocation(), args_start, args_end, Diags);
    if(Res)
      FailingCommands.push_back(std::make_pair(Res, &J));

    Clang->getFrontendOpts().DisableFree = false;

    // Infer the builtin include path if unspecified.
    void *GetExecutablePathVP = (void *)(intptr_t) GetExecutablePath;
    if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
        Clang->getHeaderSearchOpts().ResourceDir.empty())
      Clang->getHeaderSearchOpts().ResourceDir =
        CompilerInvocation::GetResourcesPath(Argv0, GetExecutablePathVP);

    // Create the compilers actual diagnostics engine.
    Clang->createDiagnostics();
    if (!Clang->hasDiagnostics()) {
      FailingCommands.push_back(std::make_pair(1, &J));
      return;
    }

    LocalOutputFilename = ""; // Let the filename be created from options or output file name.
    std::string TemplightOutFile = TemplightAction::CreateOutputFilename(
      Clang.get(), "", InstProfiler, OutputToStdOut, MemoryProfile);
    // Check if templight filename is in a temporary path:
    llvm::SmallString<128> TDir;
    llvm::sys::path::system_temp_directory(true, TDir);
    if ( TDir.equals(llvm::sys::path::parent_path(llvm::StringRef(TemplightOutFile))) ) {
      C.addTempFile(TemplightOutFile.c_str());
      TempOutputFiles.push_back(TemplightOutFile);
    }

    // Execute the frontend actions.
    Res = ExecuteTemplightInvocation(Clang.get());
    if(Res)
      FailingCommands.push_back(std::make_pair(Res, &J));

  } else {

    const Command *FailingCommand = nullptr;
    if (int Res = C.ExecuteCommand(J, FailingCommand))
      FailingCommands.push_back(std::make_pair(Res, FailingCommand));

  }

}
Example #23
0
void CTransportCAI::GiveCommandReal(const Command& c, bool fromSynced) {
	if (!(c.options & SHIFT_KEY) && nonQueingCommands.find(c.GetID()) == nonQueingCommands.end()){
		SetTransportee(NULL);
	}
	return CMobileCAI::GiveCommandReal(c, fromSynced);
}
		bool ChassicCommandInterpreter::handle(const Command& command)
		{
			if(command.compareModule("CH"))
			{
				// CHASSIC
				if(command.compareAction("MV"))
				{
					// MOVE
					if(command.compareArgument1("FW"))
					{
						// FORWARD
						_platform.move(rover::chassic::MOVE_FORWARD, getMotorSpeed(command, rover::chassic::SPEED_75));
						return true;
					}

					if(command.compareArgument1("BW"))
					{
						// FORWARD
						_platform.move(rover::chassic::MOVE_BACKWARD, getMotorSpeed(command, rover::chassic::SPEED_75));
						return true;
					}

					rover::telemetry::Logger::debug("Wrong CHASSIC MOVE command");
				}
				else if(command.compareAction("RT"))
				{
					// ROTATE
					if(command.compareArgument1("TL"))
					{
						// LEFT
						_platform.rotate(rover::chassic::ROTATE_LEFT, getMotorSpeed(command, rover::chassic::SPEED_75));
						return true;
					}

					if(command.compareArgument1("TR"))
					{
						// FORWARD
						_platform.rotate(rover::chassic::ROTATE_RIGHT, getMotorSpeed(command, rover::chassic::SPEED_75));
						return true;
					}

					rover::telemetry::Logger::debug("Wrong CHASSIC ROTATE command");
				}
				else if(command.compareAction("ST"))
				{
					// STOP
					_platform.stop();
					return true;
				}
				else if(command.compareAction("BR"))
				{
					// BRAKE
					_platform.brake();
					return true;
				}
				else
				{
					rover::telemetry::Logger::debug("Wrong CHASSIC command");					
				}

				return false;
			}
		}
Example #25
0
void CTransportCAI::UnloadLand(Command& c)
{
	//default unload
	CTransportUnit* transport = static_cast<CTransportUnit*>(owner);
	if (inCommand) {
		if (!owner->script->IsBusy()) {
			FinishCommand();
		}
	} else {
		const std::list<CTransportUnit::TransportedUnit>& transList = transport->GetTransportedUnits();

		if (transList.empty()) {
			FinishCommand();
			return;
		}

		float3 pos = c.GetPos(0);
		if (goalPos.SqDistance2D(pos) > 400) {
			SetGoal(pos, owner->pos);
		}

		CUnit* unit = NULL;
		if (c.params.size() < 4) {
			unit = transList.front().unit;
		} else {
			const int unitID = (int)c.params[3];
			std::list<CTransportUnit::TransportedUnit>::const_iterator it;
			for (it = transList.begin(); it != transList.end(); ++it) {
				CUnit* carried = it->unit;
				if (unitID == carried->id) {
					unit = carried;
					break;
				}
			}
			if (unit == NULL) {
				FinishCommand();
				return;
			}
		}

		if (pos.SqDistance2D(owner->pos) < Square(owner->unitDef->loadingRadius * 0.9f)) {
			CHoverAirMoveType* am = dynamic_cast<CHoverAirMoveType*>(owner->moveType);
			pos.y = static_cast<CTransportUnit*>(owner)->GetLoadUnloadHeight(pos, unit);
			if (am != NULL) {
				// handle air transports differently
				SetGoal(pos, owner->pos);
				am->SetWantedAltitude(pos.y - ground->GetHeightAboveWater(pos.x, pos.z));
				float unloadHeading = static_cast<CTransportUnit*>(owner)->GetLoadUnloadHeading(unit);
				am->ForceHeading(unloadHeading);
				am->maxDrift = 1;
				if ((owner->pos.SqDistance(pos) < 64) &&
						(owner->updir.dot(UpVector) > 0.99f) && math::fabs(owner->heading - unloadHeading) < AIRTRANSPORT_DOCKING_ANGLE) {
					pos.y -= unit->radius;
					if (!SpotIsClearIgnoreSelf(pos, unit)) {
						// chosen spot is no longer clear to land, choose a new one
						// if a new spot cannot be found, don't unload at all
						float3 newpos;
						if (FindEmptySpot(pos, std::max(16.0f * SQUARE_SIZE, unit->radius * 4.0f), unit->radius, newpos, unit)) {
							c.SetPos(0, newpos);
							SetGoal(newpos + UpVector * unit->model->height, owner->pos);
							return;
						}
					} else {
						transport->DetachUnit(unit);
						if (transport->GetTransportedUnits().empty()) {
							am->dontLand = false;
							owner->script->EndTransport();
						}
					}
					const float3 fix = owner->pos + owner->frontdir * 20;
					SetGoal(fix, owner->pos); // move the transport away slightly
					FinishCommand();
				}
			} else {
				inCommand = true;
				StopMove();
				owner->script->TransportDrop(unit, pos);
			}
		}
	}
}
Example #26
0
void SetPointAbility::invoke(Unit &to_modify, const Command &cmd, bool) {
	auto &build_attr = to_modify.get_attribute<attr_type::building>();
	build_attr.gather_point = cmd.position();
}
Example #27
0
void Command::help() {
    // Build command name
    string commandName = _name;
    
    Command *command = this->parentCommand();
    while (command) {
        commandName = command->name() + " " + commandName;
        command = command->parentCommand();
    }
    
    // Build usage
    int offset = 0;
    
    if (_options.size() > 0) {
        vector<string> elements;
        
        // Add optinos
        for (int i = 0; i < _options.size(); i++) {
            Option option = _options[i];
            string element = "[";
            
            if (option.shortName() != "") {
                element += "-" + option.shortName();
                
                if (option.longName() != "") {
                    element += "|--" + option.longName();
                }
            } else {
                element += "--" + option.longName();
            }
            
            switch (option.argumentType()) {
                case Option::ArgumentType::Required:
                    element += " <" + option.argumentName() + ">";
                    break;
                    
                case Option::ArgumentType::Optional:
                    element += " [<" + option.argumentName() + ">]";
                    break;
                    
                case Option::ArgumentType::NoArgument:
                    break;
            }
            
            element += "]";
            elements.push_back(element);
        }
        
        // Calculate width
        int maximumLineWidth = 80;
        
        string header = "usage: " + commandName;
        offset = min(20, (int)header.size());
        
        // Show usage
        int i = 0;
        string line = header;
        
        while (i < elements.size()) {
            if (line.size() + 1 + elements[i].size() > maximumLineWidth) {
                cout << line << endl;
                
                line = "";
                for (int j = 0; j < offset; j++) {
                    line += " ";
                }
            }
            
            line += " " + elements[i];
            i++;
        }
        
        if (line != "") {
            cout << line << endl;
        }
    } else {
        cout << "usage: " + commandName;
    }
    
    // Check whether the command has subcommands
    if (_subcommands.size() == 0) {
        cout << endl;
        
        return;
    }
    
    // Show command usage
    for (int i = 0; i < offset; i++) {
        cout << " ";
    }
    
    cout << " <command> [<args>]" << endl;
    
    // Get max command length
    vector<Command> subcommands = _subcommands;
    int maximumCommandLength = 0;
    
    for (auto it = subcommands.begin(); it != subcommands.end(); ++it) {
        if ((int)it->name().size() > maximumCommandLength) {
            maximumCommandLength = (int)it->name().size();
        }
    }
    
    // Show commands
    cout << endl << "commands:" << endl;
    
    for (auto it = subcommands.begin(); it != subcommands.end(); ++it) {
        cout << "   " << it->name();
        
        for (int i = 0; i < (maximumCommandLength + 3 - (int)it->name().size()); i++) {
            cout << " ";
        }
        
        cout << it->description() << endl;
    }
}
Example #28
0
bool SetPointAbility::can_invoke(Unit &to_modify, const Command &cmd) {
	return cmd.has_position() &&
	       to_modify.has_attribute(attr_type::building);
}
Example #29
0
bool LocalNode::_cmdConnect( Command& command )
{
    EQASSERT( !command.getNode().isValid( ));
    EQASSERT( _inReceiverThread( ));

    const NodeConnectPacket* packet = command.get< NodeConnectPacket >();
    ConnectionPtr connection = _incoming.getConnection();
    const NodeID& nodeID = packet->nodeID;

    EQVERB << "handle connect " << packet << std::endl;
    EQASSERT( nodeID != _id );
    EQASSERT( _connectionNodes.find( connection ) == _connectionNodes.end( ));

    NodePtr remoteNode;

    // No locking needed, only recv thread modifies
    NodeHash::const_iterator i = _nodes->find( nodeID );
    if( i != _nodes->end( ))
    {
        remoteNode = i->second;
        if( remoteNode->isConnected( ))
        {
            // Node exists, probably simultaneous connect from peer
            EQINFO << "Already got node " << nodeID << ", refusing connect"
                   << std::endl;

            // refuse connection
            NodeConnectReplyPacket reply( packet );
            connection->send( reply, serialize( ));

            // NOTE: There is no close() here. The reply packet above has to be
            // received by the peer first, before closing the connection.
            _removeConnection( connection );
            return true;
        }
    }

    // create and add connected node
    if( !remoteNode )
        remoteNode = createNode( packet->nodeType );

    std::string data = packet->nodeData;
    if( !remoteNode->deserialize( data ))
        EQWARN << "Error during node initialization" << std::endl;
    EQASSERTINFO( data.empty(), data );
    EQASSERTINFO( remoteNode->_id == nodeID,
                  remoteNode->_id << "!=" << nodeID );

    remoteNode->_outgoing = connection;
    remoteNode->_state    = STATE_CONNECTED;
    
    _connectionNodes[ connection ] = remoteNode;
    {
        base::ScopedMutex< base::SpinLock > mutex( _nodes );
        _nodes.data[ remoteNode->_id ] = remoteNode;
    }
    EQVERB << "Added node " << nodeID << std::endl;

    // send our information as reply
    NodeConnectReplyPacket reply( packet );
    reply.nodeID    = _id;
    reply.nodeType  = getType();

    connection->send( reply, serialize( ));    
    return true;
}
Example #30
0
void CBuilderCAI::ExecuteReclaim(Command& c)
{
	// not all builders are reclaim-capable by default
	if (!owner->unitDef->canReclaim)
		return;

	if (c.params.size() == 1 || c.params.size() == 5) {
		const int signedId = (int) c.params[0];

		if (signedId < 0) {
			LOG_L(L_WARNING, "Trying to reclaim unit or feature with id < 0 (%i), aborting.", signedId);
			return;
		}

		const unsigned int uid = signedId;

		const bool checkForBetterTarget = ((++randomCounter % 5) == 0);
		if (checkForBetterTarget && (c.options & INTERNAL_ORDER) && (c.params.size() >= 5)) {
			// regular check if there is a closer reclaim target
			CSolidObject* obj;
			if (uid >= unitHandler->MaxUnits()) {
				obj = featureHandler->GetFeature(uid - unitHandler->MaxUnits());
			} else {
				obj = unitHandler->GetUnit(uid);
			}
			if (obj) {
				const float3& pos = c.GetPos(1);
				const float radius = c.params[4];
				const float curdist = pos.SqDistance2D(obj->pos);

				const bool recUnits = !!(c.options & META_KEY);
				const bool recEnemyOnly = (c.options & META_KEY) && (c.options & CONTROL_KEY);
				const bool recSpecial = !!(c.options & CONTROL_KEY);

				ReclaimOption recopt = REC_NORESCHECK;
				if (recUnits)     recopt |= REC_UNITS;
				if (recEnemyOnly) recopt |= REC_ENEMYONLY;
				if (recSpecial)   recopt |= REC_SPECIAL;

				const int rid = FindReclaimTarget(pos, radius, c.options, recopt, curdist);
				if ((rid > 0) && (rid != uid)) {
					StopMoveAndFinishCommand();
					RemoveUnitFromReclaimers(owner);
					RemoveUnitFromFeatureReclaimers(owner);
					return;
				}
			}
		}

		if (uid >= unitHandler->MaxUnits()) { // reclaim feature
			CFeature* feature = featureHandler->GetFeature(uid - unitHandler->MaxUnits());

			if (feature != NULL) {
				bool featureBeingResurrected = IsFeatureBeingResurrected(feature->id, owner);
				featureBeingResurrected &= (c.options & INTERNAL_ORDER) && !(c.options & CONTROL_KEY);

				if (featureBeingResurrected || !ReclaimObject(feature)) {
					StopMoveAndFinishCommand();
					RemoveUnitFromFeatureReclaimers(owner);
				} else {
					AddUnitToFeatureReclaimers(owner);
				}
			} else {
				StopMoveAndFinishCommand();
				RemoveUnitFromFeatureReclaimers(owner);
			}

			RemoveUnitFromReclaimers(owner);
		} else { // reclaim unit
			CUnit* unit = unitHandler->GetUnit(uid);

			if (unit != NULL && c.params.size() == 5) {
				const float3& pos = c.GetPos(1);
				const float radius = c.params[4] + 100.0f; // do not walk too far outside reclaim area

				const bool outOfReclaimRange =
					(pos.SqDistance2D(unit->pos) > radius * radius) ||
					(ownerBuilder->curReclaim == unit && unit->IsMoving() && !IsInBuildRange(unit));
				const bool busyAlliedBuilder =
					unit->unitDef->builder &&
					!unit->commandAI->commandQue.empty() &&
					teamHandler->Ally(owner->allyteam, unit->allyteam);

				if (outOfReclaimRange || busyAlliedBuilder) {
					StopMoveAndFinishCommand();
					RemoveUnitFromReclaimers(owner);
					RemoveUnitFromFeatureReclaimers(owner);
					return;
				}
			}

			if (unit != NULL && unit != owner && unit->unitDef->reclaimable && UpdateTargetLostTimer(unit->id) && unit->AllowedReclaim(owner)) {
				if (!ReclaimObject(unit)) {
					StopMoveAndFinishCommand();
				} else {
					AddUnitToReclaimers(owner);
				}
			} else {
				RemoveUnitFromReclaimers(owner);
				StopMoveAndFinishCommand();
			}

			RemoveUnitFromFeatureReclaimers(owner);
		}
	} else if (c.params.size() == 4) {
		// area reclaim
		const float3 pos = c.GetPos(0);
		const float radius = c.params[3];
		const bool recUnits = !!(c.options & META_KEY);
		const bool recEnemyOnly = (c.options & META_KEY) && (c.options & CONTROL_KEY);
		const bool recSpecial = !!(c.options & CONTROL_KEY);

		RemoveUnitFromReclaimers(owner);
		RemoveUnitFromFeatureReclaimers(owner);
		ownerBuilder->StopBuild();

		ReclaimOption recopt = REC_NORESCHECK;
		if (recUnits)     recopt |= REC_UNITS;
		if (recEnemyOnly) recopt |= REC_ENEMYONLY;
		if (recSpecial)   recopt |= REC_SPECIAL;

		if (FindReclaimTargetAndReclaim(pos, radius, c.options, recopt)) {
			inCommand = false;
			SlowUpdate();
			return;
		}
		if(!(c.options & ALT_KEY)){
			StopMoveAndFinishCommand();
		}
	} else {
		// wrong number of parameters
		RemoveUnitFromReclaimers(owner);
		RemoveUnitFromFeatureReclaimers(owner);
		StopMoveAndFinishCommand();
	}
}