Example #1
0
void Client::SendPathPacket(const std::vector<FindPerson_Point> &points) {
	EQ::BackgroundTask task([](EQEmu::Any &data) {
		auto &points = EQEmu::any_cast<std::vector<FindPerson_Point>&>(data);
		CullPoints(points);
	}, [this](EQEmu::Any &data) {
		auto &points = EQEmu::any_cast<std::vector<FindPerson_Point>&>(data);

		if (points.size() < 2) {
			if (Admin() > 10) {
				Message(MT_System, "Too few points");
			}

			EQApplicationPacket outapp(OP_FindPersonReply, 0);
			QueuePacket(&outapp);
			return;
		}

		if (points.size() > 36) {
			if (Admin() > 10) {
				Message(MT_System, "Too many points %u", points.size());
			}

			EQApplicationPacket outapp(OP_FindPersonReply, 0);
			QueuePacket(&outapp);
			return;
		}

		if (Admin() > 10) {
			Message(MT_System, "Total points %u", points.size());
		}

		int len = sizeof(FindPersonResult_Struct) + (points.size() + 1) * sizeof(FindPerson_Point);
		auto outapp = new EQApplicationPacket(OP_FindPersonReply, len);
		FindPersonResult_Struct* fpr = (FindPersonResult_Struct*)outapp->pBuffer;

		std::vector<FindPerson_Point>::iterator cur, end;
		cur = points.begin();
		end = points.end();
		unsigned int r;
		for (r = 0; cur != end; ++cur, r++) {
			fpr->path[r] = *cur;

		}
		//put the last element into the destination field
		--cur;
		fpr->path[r] = *cur;
		fpr->dest = *cur;

		FastQueuePacket(&outapp);
	}, points);
}
Example #2
0
	void MainView::Login()
	{
		string name, password;

		name = CLI::GetInput("用户名:");
		password = CLI::GetInput("密码:");

		if (!Data.VerifyUser(name, password)) {
			CLI::ShowMsg("用户名或密码错误!");
			BOOST_LOG_TRIVIAL(warning) << "Log in failed, User Name:" << name;
			return;
		}

		model::User& user = Data.GetUser(name);

		if (user.isAdmin()) {
			AdministratorView Admin(user, &Data);
			while (Admin.Loop) Admin.Show();
			CLI::CleanCLI();
		}
		else {
			BankTellerView Teller(user, &Data);
			while (Teller.Loop) Teller.Show();
			CLI::CleanCLI();
		}
	}
Example #3
0
bool Client::CanBeInZone() {
	//check some critial rules to see if this char needs to be booted from the zone
	//only enforce rules here which are serious enough to warrant being kicked from
	//the zone

	if(Admin() >= RuleI(GM, MinStatusToZoneAnywhere))
		return(true);

	float safe_x, safe_y, safe_z;
	int16 minstatus = 0;
	uint8 minlevel = 0;
	char flag_needed[128];
	if(!database.GetSafePoints(zone->GetShortName(), zone->GetInstanceVersion(), &safe_x, &safe_y, &safe_z, &minstatus, &minlevel, flag_needed)) {
		//this should not happen...
		_log(CLIENT__ERROR, "Unable to query zone info for ourself '%s'", zone->GetShortName());
		return(false);
	}

	if(GetLevel() < minlevel) {
		_log(CLIENT__ERROR, "Character does not meet min level requirement (%d < %d)!", GetLevel(), minlevel);
		return(false);
	}
	if(Admin() < minstatus) {
		_log(CLIENT__ERROR, "Character does not meet min status requirement (%d < %d)!", Admin(), minstatus);
		return(false);
	}

	if(flag_needed[0] != '\0') {
		//the flag needed string is not empty, meaning a flag is required.
		if(Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(zone->GetZoneID())) {
			_log(CLIENT__ERROR, "Character does not have the flag to be in this zone (%s)!", flag_needed);
			return(false);
		}
	}

	return(true);
}
Example #4
0
static void give_money (dbref giver, dbref recipient, int key, int amount)
{
dbref	aowner;
int	cost, pcost, rcost, aflags, dpamount;
char	*str;

	/* do amount consistency check */

	if (amount < 0 && ((!Builder(giver) && !HasPriv(giver,recipient,POWER_STEAL,POWER3,NOTHING)) ||
				DePriv(giver,recipient,DP_STEAL,POWER6,NOTHING))) {
		notify(giver,
			unsafe_tprintf("You look through your pockets. Nope, no negative %s.",
				mudconf.many_coins));
		return;
	}

	if (!amount) {
		notify(giver,
			unsafe_tprintf("You must specify a positive number of %s.",
							mudconf.many_coins));
		return;
	}

	dpamount = 0;
	if (amount < 0) 
	  dpamount = DePriv(giver,NOTHING,DP_NOSTEAL,POWER7,POWER_LEVEL_NA);
	else
	  dpamount = DePriv(giver,NOTHING,DP_NOGOLD,POWER7,POWER_LEVEL_NA);
	if (dpamount) {
	  if (DPShift(giver))
	    dpamount--;
	  dpamount = mudconf.money_limit[dpamount];
	}
	else
	  dpamount = -1;
	if (!Admin(Owner(giver))) {
		if ((Typeof(recipient) == TYPE_PLAYER) && (Pennies(recipient) + amount > mudconf.paylimit)) {
			notify(giver,
				unsafe_tprintf("That player doesn't need that many %s!",
					mudconf.many_coins));
			return;
		}
		if ((Typeof(recipient) != TYPE_PLAYER) && (!could_doit(giver, recipient, A_LUSE,1))) {
			notify(giver,
				unsafe_tprintf("%s won't take your money.",
					Name(recipient)));
			return;
		}
	}

	str = atr_get(Owner(giver), A_PAYLIM, &aowner, &aflags);
	pcost = atoi(str);
	free_lbuf(str);
	if (!Immortal(Owner(giver)) && pcost) {
		if ((Typeof(recipient) == TYPE_PLAYER) && (amount > 0) &&
			 (Pennies(recipient) + amount > pcost)) {
			notify(giver,
				unsafe_tprintf("That player doesn't need that many %s!",
					mudconf.many_coins));
			return;
		}
		else if (Pennies(recipient) + amount < (-pcost)) {
			notify(giver,"That player doesn't need that much debt!");
			return;
		}
	}
        str = atr_get(Owner(recipient), A_RECEIVELIM, &aowner, &aflags);
        rcost = atoi(str);
        free_lbuf(str);
	if (!Immortal(Owner(giver)) && rcost) {
		if ((Typeof(recipient) == TYPE_PLAYER) && (amount > 0) &&
			 (Pennies(recipient) + amount > rcost)) {
			notify(giver,
				unsafe_tprintf("That player doesn't need that many %s!",
					mudconf.many_coins));
			return;
		}
		else if (Pennies(recipient) + amount < (-rcost)) {
			notify(giver,"That player doesn't need that much debt!");
			return;
		}
	}

	if (!Immortal(Owner(giver))) {
	  if (dpamount >= 0) {
	    if (amount > 0) {
	      if ((Typeof(recipient) == TYPE_PLAYER) && (Pennies(recipient) + amount > dpamount)) {
		notify(giver,
			unsafe_tprintf("That player doesn't need that many %s!",
				mudconf.many_coins));
		return;
	      }
	      else if (amount > dpamount) {
		notify(giver, "Permission denied.");
		return;
	      }
	    }
	    else {
	      if ((Typeof(recipient) == TYPE_PLAYER) && (Pennies(recipient) + amount < (-dpamount))) {
		notify(giver,
			unsafe_tprintf("That player doesn't need that many %s!",
				mudconf.many_coins));
		return;
	      }
	      else if (amount < (-dpamount)) {
		notify(giver, "Permission denied.");
		return;
	      }
	    }
	  }
	}

	/* try to do the give */

	if (!payfor_give(giver, amount)) {
		notify(giver,
			unsafe_tprintf("You don't have that many %s to give!",
				mudconf.many_coins));
		return;
	}

	/* Find out cost if an object */

	if (Typeof(recipient) == TYPE_THING) {
		str = atr_pget(recipient, A_COST, &aowner, &aflags);
		cost = atoi(str);
		free_lbuf(str);

		/* Can't afford it? */

		if (amount < cost) {
			notify(giver, "Feeling poor today?");
			giveto(giver, amount, NOTHING);
			return;
		}

		/* Negative cost */

		if (cost < 0) {
			return;
		}
	} else {
		cost = amount;
	}

	if (!(key & GIVE_QUIET)) {
		if (amount == 1) {
			notify(giver,
				unsafe_tprintf("You give a %s to %s.",
					mudconf.one_coin, Name(recipient)));
			notify_with_cause(recipient, giver,
				unsafe_tprintf("%s gives you a %s.", Name(giver),
					mudconf.one_coin));
		} else {
			notify(giver,
				unsafe_tprintf("You give %d %s to %s.", amount,
					mudconf.many_coins, Name(recipient)));
			notify_with_cause(recipient, giver,
				unsafe_tprintf("%s gives you %d %s.", Name(giver),
				amount, mudconf.many_coins));
		}
	}
	else {
		if (amount == 1) {
			notify(giver,
				unsafe_tprintf("You give a %s to %s. (quiet)",
					mudconf.one_coin, Name(recipient)));
		}
		else {
			notify(giver,
				unsafe_tprintf("You give %d %s to %s. (quiet)",
					amount, mudconf.many_coins,
					Name(recipient)));
		}
	}

	/* Report change given */

	if((amount - cost) == 1) {
        	notify(giver,
			unsafe_tprintf("You get 1 %s in change.", mudconf.one_coin));
		giveto(giver, 1, NOTHING);
	} else if (amount != cost) {
		notify(giver,
			unsafe_tprintf("You get %d %s in change.",
				(amount - cost), mudconf.many_coins));
		giveto(giver, (amount - cost), NOTHING);
	}
	if (pcost && (Pennies(Owner(recipient)) + cost > pcost)) {
	  pcost = pcost - Pennies(Owner(recipient));
	  if (pcost < 0)
	    pcost = 0;
	}
	else
	  pcost = cost;
	if (!giveto(recipient, pcost, giver))
		giveto(giver, cost, NOTHING);

	/* Transfer the money and run PAY attributes */
        /* Rooms should not kick off the PAY attribute */

        if ( !isRoom(giver) )
	   did_it(giver, recipient, A_PAY, NULL, A_OPAY, NULL, A_APAY,
	   	  (char **)NULL, 0);
	return;
}
Example #5
0
void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
#ifdef BOTS
	// This block is necessary to clean up any bot objects owned by a Client
	Bot::ProcessClientZoneChange(this);
#endif

	zoning = true;
	if (app->size != sizeof(ZoneChange_Struct)) {
		LogFile->write(EQEMuLog::Debug, "Wrong size: OP_ZoneChange, size=%d, expected %d", app->size, sizeof(ZoneChange_Struct));
		return;
	}

#if EQDEBUG >= 5
	LogFile->write(EQEMuLog::Debug, "Zone request from %s", GetName());
	DumpPacket(app);
#endif
	ZoneChange_Struct* zc=(ZoneChange_Struct*)app->pBuffer;

	uint16 target_zone_id = 0;
	uint16 target_instance_id = zc->instanceID;
	ZonePoint* zone_point = nullptr;

	//figure out where they are going.
	if(zc->zoneID == 0) {
		//client dosent know where they are going...
		//try to figure it out for them.

		switch(zone_mode) {
		case EvacToSafeCoords:
		case ZoneToSafeCoords:
			//going to safe coords, but client dosent know where?
			//assume it is this zone for now.
			target_zone_id = zone->GetZoneID();
			break;
		case GMSummon:
			target_zone_id = zonesummon_id;
			break;
		case GateToBindPoint:
			target_zone_id = m_pp.binds[0].zoneId;
			break;
		case ZoneToBindPoint:
			target_zone_id = m_pp.binds[0].zoneId;
			break;
		case ZoneSolicited: //we told the client to zone somewhere, so we know where they are going.
			target_zone_id = zonesummon_id;
			break;
		case ZoneUnsolicited: //client came up with this on its own.
			zone_point = zone->GetClosestZonePointWithoutZone(GetX(), GetY(), GetZ(), this, ZONEPOINT_NOZONE_RANGE);
			if(zone_point) {
				//we found a zone point, which is a reasonable distance away
				//assume that is the one were going with.
				target_zone_id = zone_point->target_zone_id;
				target_instance_id = zone_point->target_zone_instance;
			} else {
				//unable to find a zone point... is there anything else
				//that can be a valid un-zolicited zone request?

				CheatDetected(MQZone, zc->x, zc->y, zc->z);
				Message(13, "Invalid unsolicited zone request.");
				LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
				SendZoneCancel(zc);
				return;
			}
			break;
		default:
			break;
		};
	}
	else {
		// This is to allow both 6.2 and Titanium clients to perform a proper zoning of the client when evac/succor
		// WildcardX 27 January 2008
		if(zone_mode == EvacToSafeCoords && zonesummon_id > 0)
			target_zone_id = zonesummon_id;
		else
			target_zone_id = zc->zoneID;

		//if we are zoning to a specific zone unsolicied,
		//then until otherwise determined, they must be zoning
		//on a zone line.
		if(zone_mode == ZoneUnsolicited)
		{
			if(target_zone_id == zone->GetZoneID())
			{
				SendZoneCancel(zc);
				return;
			}

			zone_point = zone->GetClosestZonePoint(GetX(), GetY(), GetZ(), target_zone_id, this, ZONEPOINT_ZONE_RANGE);
			//if we didnt get a zone point, or its to a different zone,
			//then we assume this is invalid.
			if(!zone_point || zone_point->target_zone_id != target_zone_id) {
				LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id);
				CheatDetected(MQGate, zc->x, zc->y, zc->z);
				SendZoneCancel(zc);
				return;
			}
		}
	}

	if(target_instance_id > 0)
	{
		//make sure we are in it and it's unexpired.
		if(!database.VerifyInstanceAlive(target_instance_id, CharacterID()))
		{
			Message(13, "Instance ID was expired or you were not in it.");
			SendZoneCancel(zc);
			return;
		}

		if(!database.VerifyZoneInstance(target_zone_id, target_instance_id))
		{
			Message(13, "Instance ID was %u does not go with zone id %u", target_instance_id, target_zone_id);
			SendZoneCancel(zc);
			return;
		}
	}

		//make sure its a valid zone.
	const char *target_zone_name = database.GetZoneName(target_zone_id);
	if(target_zone_name == nullptr) {
		//invalid zone...
		Message(13, "Invalid target zone ID.");
		LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get zone name for zone id '%d'.", GetName(), target_zone_id);
		SendZoneCancel(zc);
		return;
	}

	//load up the safe coords, restrictions, and verify the zone name
	float safe_x, safe_y, safe_z;
	int16 minstatus = 0;
	uint8 minlevel = 0;
	char flag_needed[128];
	if(!database.GetSafePoints(target_zone_name, database.GetInstanceVersion(target_instance_id), &safe_x, &safe_y, &safe_z, &minstatus, &minlevel, flag_needed)) {
		//invalid zone...
		Message(13, "Invalid target zone while getting safe points.");
		LogFile->write(EQEMuLog::Error, "Zoning %s: Unable to get safe coordinates for zone '%s'.", GetName(), target_zone_name);
		SendZoneCancel(zc);
		return;
	}

	char buf[10];
	snprintf(buf, 9, "%d", target_zone_id);
	buf[9] = '\0';
	parse->EventPlayer(EVENT_ZONE, this, buf, 0);

	//handle circumvention of zone restrictions
	//we need the value when creating the outgoing packet as well.
	uint8 ignorerestrictions = zonesummon_ignorerestrictions;
	zonesummon_ignorerestrictions = 0;

	float dest_x=0, dest_y=0, dest_z=0, dest_h;
	dest_h = GetHeading();
	switch(zone_mode) {
	case EvacToSafeCoords:
	case ZoneToSafeCoords:
		LogFile->write(EQEMuLog::Debug, "Zoning %s to safe coords (%f,%f,%f) in %s (%d)", GetName(), safe_x, safe_y, safe_z, target_zone_name, target_zone_id);
		dest_x = safe_x;
		dest_y = safe_y;
		dest_z = safe_z;
		break;
	case GMSummon:
		dest_x = zonesummon_x;
		dest_y = zonesummon_y;
		dest_z = zonesummon_z;
		ignorerestrictions = 1;
		break;
	case GateToBindPoint:
		dest_x = m_pp.binds[0].x;
		dest_y = m_pp.binds[0].y;
		dest_z = m_pp.binds[0].z;
		break;
	case ZoneToBindPoint:
		dest_x = m_pp.binds[0].x;
		dest_y = m_pp.binds[0].y;
		dest_z = m_pp.binds[0].z;
		ignorerestrictions = 1;	//can always get to our bind point? seems exploitable
		break;
	case ZoneSolicited: //we told the client to zone somewhere, so we know where they are going.
		//recycle zonesummon variables
		dest_x = zonesummon_x;
		dest_y = zonesummon_y;
		dest_z = zonesummon_z;
		break;
	case ZoneUnsolicited: //client came up with this on its own.
		//client requested a zoning... what are the cases when this could happen?

		//Handle zone point case:
		if(zone_point != nullptr) {
			//they are zoning using a valid zone point, figure out coords

			//999999 is a placeholder for 'same as where they were from'
			if(zone_point->target_x == 999999)
				dest_x = GetX();
			else
				dest_x = zone_point->target_x;
			if(zone_point->target_y == 999999)
				dest_y = GetY();
			else
				dest_y = zone_point->target_y;
			if(zone_point->target_z == 999999)
				dest_z=GetZ();
			else
				dest_z = zone_point->target_z;
			if(zone_point->target_heading == 999)
				dest_h = GetHeading();
			else
				dest_h = zone_point->target_heading;

			break;
		}

		//for now, there are no other cases...

		//could not find a valid reason for them to be zoning, stop it.
		CheatDetected(MQZoneUnknownDest, 0.0, 0.0, 0.0);
		LogFile->write(EQEMuLog::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%s'. Not near a zone point.", GetName(), target_zone_name);
		SendZoneCancel(zc);
		return;
	default:
		break;
	};

	//OK, now we should know where were going...

	//Check some rules first.
	int8 myerror = 1;		//1 is succes

	//not sure when we would use ZONE_ERROR_NOTREADY

	//enforce min status and level
	if (!ignorerestrictions && (Admin() < minstatus || GetLevel() < minlevel))
	{
		myerror = ZONE_ERROR_NOEXPERIENCE;
	}

	if(!ignorerestrictions && flag_needed[0] != '\0') {
		//the flag needed string is not empty, meaning a flag is required.
		if(Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(target_zone_id))
		{
			Message(13, "You do not have the flag to enter %s.", target_zone_name);
			myerror = ZONE_ERROR_NOEXPERIENCE;
		}
	}

	//TODO: ADVENTURE ENTRANCE CHECK

	if(myerror == 1) {
		//we have successfully zoned
		DoZoneSuccess(zc, target_zone_id, target_instance_id, dest_x, dest_y, dest_z, dest_h, ignorerestrictions);
	} else {
		LogFile->write(EQEMuLog::Error, "Zoning %s: Rules prevent this char from zoning into '%s'", GetName(), target_zone_name);
		SendZoneError(zc, myerror);
	}
}