示例#1
0
// Stored packets
void PlayerDataProvider::parseIncomingPacket(PacketReader &packet) {
	int32_t playerid = packet.get<int32_t>();
	bool fromCashOrMts = packet.getBool();

	size_t psize = packet.getBufferLength();
	unsigned char *buf = new unsigned char[psize]; // Prevent the packet memory from being freed by external sources
	memcpy(buf, packet.getBuffer(), psize);

	m_packets[playerid].reset(new PacketReader(buf, psize));
	SyncPacket::playerBuffsTransferred(ChannelServer::Instance()->getWorldConnection(), playerid, fromCashOrMts);
}
void WorldServerConnectHandler::sendToPlayers(PacketReader &packet) {
	PlayersPacket::sendToPlayers(packet.getBuffer(), packet.getBufferLength());
}
示例#3
0
void MobHandler::monsterControl(Player *player, PacketReader &packet) {
	int32_t mobid = packet.get<int32_t>();

	Mob *mob = Maps::getMap(player->getMap())->getMob(mobid);

	if (mob == nullptr || mob->getControlStatus() == Mobs::ControlStatus::ControlNone) {
		return;
	}

	int16_t moveid = packet.get<int16_t>();
	bool useskill = packet.getBool();
	int8_t skill = packet.get<int8_t>();
	uint8_t realskill = 0;
	uint8_t level = 0;
	Pos projectiletarget = packet.getPos();
	packet.skipBytes(5); // 1 byte of always 0?, 4 bytes of always 1 or always 0?
	Pos spot = packet.getPos();

	MovementHandler::parseMovement(mob, packet);

	if (useskill && (skill == -1 || skill == 0)) {
		if (!(mob->hasStatus(StatusEffects::Mob::Freeze) || mob->hasStatus(StatusEffects::Mob::Stun) || mob->hasStatus(StatusEffects::Mob::ShadowWeb))) {
			uint8_t size = mob->getSkillCount();
			bool used = false;
			if (size) {
				bool stop = false;
				uint8_t rand = Randomizer::Instance()->randChar(size - 1);
				MobSkillInfo *info = MobDataProvider::Instance()->getMobSkill(mob->getMobId(), rand);
				realskill = info->skillId;
 				level = info->level;
				MobSkillLevelInfo *mobskill = SkillDataProvider::Instance()->getMobSkill(realskill, level);
				switch (realskill) {
					case MobSkills::WeaponAttackUp:
					case MobSkills::WeaponAttackUpAoe:
						stop = mob->hasStatus(StatusEffects::Mob::Watk);
						break;
					case MobSkills::MagicAttackUp:
					case MobSkills::MagicAttackUpAoe:
						stop = mob->hasStatus(StatusEffects::Mob::Matk);
						break;
					case MobSkills::WeaponDefenseUp:
					case MobSkills::WeaponDefenseUpAoe:
						stop = mob->hasStatus(StatusEffects::Mob::Wdef);
						break;
					case MobSkills::MagicDefenseUp:
					case MobSkills::MagicDefenseUpAoe:
						stop = mob->hasStatus(StatusEffects::Mob::Mdef);
						break;
					case MobSkills::WeaponImmunity:
					case MobSkills::MagicImmunity:
					case MobSkills::WeaponDamageReflect:
					case MobSkills::MagicDamageReflect:
						stop = mob->hasImmunity();
						break;
					case MobSkills::McSpeedUp:
						stop = mob->hasStatus(StatusEffects::Mob::Speed);
						break;
					case MobSkills::Summon: {
						int16_t limit = mobskill->limit;
						if (limit == 5000) // Custom limit based on number of players on map
							limit = 30 + Maps::getMap(mob->getMapId())->getNumPlayers() * 2;
						if (mob->getSpawnCount() >= limit)
							stop = true;
						break;
					}
				}
				if (!stop) {
					time_t now = time(0);
					time_t ls = mob->getLastSkillUse(realskill);
					if (ls == 0 || ((int32_t)(now - ls) > mobskill->interval)) {
						mob->setLastSkillUse(realskill, now);
						int64_t reqhp = mob->getHp() * 100;
						reqhp /= mob->getMaxHp();
						if ((uint8_t)(reqhp) <= mobskill->hp) {
							if (info->effectAfter == 0) {
								handleMobSkill(mob, realskill, level, mobskill);
							}
							else {
								new Timer::Timer(bind(&MobHandler::handleMobSkill, mob, realskill, level, mobskill),
									Timer::Id(Timer::Types::MobSkillTimer, mob->getMobId(), mob->getCounter()),
									mob->getTimers(), Timer::Time::fromNow(info->effectAfter));
							}
							used = true;
						}
					}
				}
			}
			if (!used) {
				realskill = 0;
				level = 0;
			}
		}
	}
	MobsPacket::moveMobResponse(player, mobid, moveid, useskill, mob->getMp(), realskill, level);
	packet.reset(19);
	MobsPacket::moveMob(player, mobid, useskill, skill, projectiletarget, packet.getBuffer(), packet.getBufferLength());
}
示例#4
0
void InventoryHandler::useCashItem(Player *player, PacketReader &packet) {
	packet.get<int8_t>(); // Type
	packet.skipBytes(1);
	int32_t itemid = packet.get<int32_t>();

	if (!player->getInventory()->getItemAmount(itemid)) {
		// Hacking
		return;
	}

	bool used = false;
	if (GameLogicUtilities::getItemType(itemid) == Items::Types::WeatherCash) {
		string message = packet.getString();
		if (!player->updateTickCount(packet.get<int32_t>())) {
			// Tickcount was the same or less than 100 of the difference.
			return;
		}
		if (message.length() <= 35) {
			Map *map = Maps::getMap(player->getMap());
			message = player->getName() + " 's message : " + message;
			used = map->createWeather(player, false, Items::WeatherTime, itemid, message);
		}
	}
	else if (GameLogicUtilities::getItemType(itemid) == Items::Types::CashPetFood) {
		// Pet food.
		Pet *pet = player->getPets()->getSummoned(0);
		if (pet != nullptr) {
			if (pet->getFullness() < Stats::MaxFullness) {
				PetsPacket::showAnimation(player, pet, 1);
				pet->modifyFullness(Stats::MaxFullness, false);
				pet->addCloseness(100); // All cash pet food gives 100 closeness.
				used = true;
			}
		}
	}
	else {
		switch (itemid) {
			case Items::TeleportRock:
			case Items::TeleportCoke:
			case Items::VipRock: // Only occurs when you actually try to move somewhere
				used = handleRockTeleport(player, itemid, packet);
				break;
			case Items::FirstJobSpReset:
			case Items::SecondJobSpReset:
			case Items::ThirdJobSpReset:
			case Items::FourthJobSpReset: {
				int32_t toskill = packet.get<int32_t>();
				int32_t fromskill = packet.get<int32_t>();
				if (!player->getSkills()->addSkillLevel(fromskill, -1, true)) {
					// Hacking
					return;
				}
				if (!player->getSkills()->addSkillLevel(toskill, 1, true)) {
					// Hacking
					return;
				}
				used = true;
				break;
			}
			case Items::ApReset: {
				int32_t tostat = packet.get<int32_t>();
				int32_t fromstat = packet.get<int32_t>();
				player->getStats()->addStat(tostat, 1, true);
				player->getStats()->addStat(fromstat, -1, true);
				used = true;
				break;
			}
			case Items::Megaphone: {
				string msg = player->getMedalName() + " : " + packet.getString();
				InventoryPacket::showMegaphone(player, msg);
				used = true;
				break;
			}
			case Items::SuperMegaphone: {
				string msg = player->getMedalName() + " : " + packet.getString();
				bool whisper = packet.getBool();
				InventoryPacket::showSuperMegaphone(player, msg, whisper);
				used = true;
				break;
			}
			case Items::DiabloMessenger:
			case Items::Cloud9Messenger:
			case Items::LoveholicMessenger: {
				string msg = packet.getString();
				string msg2 = packet.getString();
				string msg3 = packet.getString();
				string msg4 = packet.getString();

				InventoryPacket::showMessenger(player, msg, msg2, msg3, msg4, packet.getBuffer(), packet.getBufferLength(), itemid);
				used = true;
				break;
			}
			case Items::ItemMegaphone: {
				string msg = player->getMedalName() + " : " + packet.getString();
				bool whisper = packet.getBool();
				Item *item = nullptr;
				if (packet.getBool()) {
					int8_t inv = (int8_t) packet.get<int32_t>();
					int16_t slot = (int16_t) packet.get<int32_t>();
					item = player->getInventory()->getItem(inv, slot);
					if (item == nullptr) {
						// Hacking
						return;
					}
				}
				InventoryPacket::showItemMegaphone(player, msg, whisper, item);
				used = true;
				break;
			}
			case Items::ArtMegaphone: {
				int8_t lines = packet.get<int8_t>();
				if (lines < 1 || lines > 3) {
					// Hacking
					return;
				}
				string text[3];
				for (int8_t i = 0; i < lines; i++) {
					text[i] = player->getMedalName() + " : " + packet.getString();
				}
				bool whisper = packet.getBool();
				InventoryPacket::showTripleMegaphone(player, lines, text[0], text[1], text[2], whisper);
				used = true;
				break;
			}
			case Items::PetNameTag: {
				string name = packet.getString();
				PetHandler::changeName(player, name);
				used = true;
				break;
			}
			case Items::ItemNameTag: {
				int16_t slot = packet.get<int16_t>();
				if (slot != 0) {
					Item *item = player->getInventory()->getItem(Inventories::EquipInventory, slot);
					if (item == nullptr) {
						// Hacking or failure, dunno
						return;
					}
					item->setName(player->getName());
					InventoryPacket::addNewItem(player, Inventories::EquipInventory, slot, item, true);
					used = true;
				}
				break;
			}
			case Items::ItemLock: 
			case Items::ScissorsOfKarma: {
				int8_t inventory = (int8_t) packet.get<int32_t>();
				int16_t slot = (int16_t) packet.get<int32_t>();
				if (slot != 0) {
					Item *item = player->getInventory()->getItem(inventory, slot);
					if (item == nullptr || (itemid == Items::ItemLock && item->hasLock()) || item->hasTradeBlock() || (itemid == Items::ScissorsOfKarma && item->hasKarma())) {
						// Hacking or failure, dunno
						return;
					}
					ItemInfo *info = ItemDataProvider::Instance()->getItemInfo(item->getId());
					if (itemid == Items::ScissorsOfKarma && info->karmascissors) {
						// Hacking
						return;
					}

					switch (itemid) {
						case Items::ItemLock: item->setLock(true); break;
						case Items::ScissorsOfKarma: item->setKarma(true); break;
					}

					InventoryPacket::addNewItem(player, inventory, slot, item, true);
					used = true;
				}
				break;
			}
			case Items::MapleTvMessenger: 
			case Items::Megassenger: {
				bool hasreceiver = (packet.get<int8_t>() == 3);
				bool show_whisper = (itemid == Items::Megassenger ? packet.getBool() : false);
				Player *receiver = PlayerDataProvider::Instance()->getPlayer(packet.getString());
				int32_t time = 15;

				if ((hasreceiver && receiver != nullptr) || (!hasreceiver && receiver == nullptr)) {
					string msg = packet.getString();
					string msg2 = packet.getString();
					string msg3 = packet.getString();
					string msg4 = packet.getString();
					string msg5 = packet.getString();
					if (!player->updateTickCount(packet.get<int32_t>())) {
						// Tickcount was the same or less than 100 of the difference.
						return;
					}
					MapleTvs::Instance()->addMessage(player, receiver, msg, msg2, msg3, msg4, msg5, itemid - (itemid == Items::Megassenger ? 3 : 0), time);

					if (itemid == Items::Megassenger) {
						InventoryPacket::showSuperMegaphone(player, player->getMedalName() + " : " + msg + msg2 + msg3 + msg4 + msg5, show_whisper);
					}
					used = true;
				}
				break;
			}
			case Items::MapleTvStarMessenger: 
			case Items::StarMegassenger: {
				int32_t time = 30;
				bool show_whisper = (itemid == Items::StarMegassenger ? packet.getBool() : false);
				string msg = packet.getString();
				string msg2 = packet.getString();
				string msg3 = packet.getString();
				string msg4 = packet.getString();
				string msg5 = packet.getString();
				if (!player->updateTickCount(packet.get<int32_t>())) {
					// Tickcount was the same or less than 100 of the difference.
					return;
				}
				MapleTvs::Instance()->addMessage(player, nullptr, msg, msg2, msg3, msg4, msg5, itemid - (itemid == Items::StarMegassenger ? 3 : 0), time);

				if (itemid == Items::StarMegassenger) {
					InventoryPacket::showSuperMegaphone(player, player->getMedalName() + " : " + msg + msg2 + msg3 + msg4 + msg5, show_whisper);
				}
				used = true;
				break;
			}
			case Items::MapleTvHeartMessenger:
			case Items::HeartMegassenger: {
				bool show_whisper = (itemid == Items::HeartMegassenger ? packet.getBool() : false);
				string name = packet.getString();
				Player *receiver = PlayerDataProvider::Instance()->getPlayer(name);
				int32_t time = 60;

				if (receiver != nullptr) {
					string msg = packet.getString();
					string msg2 = packet.getString();
					string msg3 = packet.getString();
					string msg4 = packet.getString();
					string msg5 = packet.getString();
					if (!player->updateTickCount(packet.get<int32_t>())) {
						// Tickcount was the same or less than 100 of the difference.
						return;
					}
					MapleTvs::Instance()->addMessage(player, receiver, msg, msg2, msg3, msg4, msg5, itemid - (itemid == Items::HeartMegassenger ? 3 : 0), time);
					if (itemid == Items::HeartMegassenger) {
						InventoryPacket::showSuperMegaphone(player, player->getMedalName() + " : " + msg + msg2 + msg3 + msg4 + msg5, show_whisper);
					}
					used = true;
				}
				break;
			}
			case Items::BronzeSackOfMesos:
			case Items::SilverSackOfMesos:
			case Items::GoldSackOfMesos: {
				int32_t mesos = ItemDataProvider::Instance()->getMesoBonus(itemid);
				if (!player->getInventory()->modifyMesos(mesos)) {
					InventoryPacket::sendMesobagFailed(player);
				}
				else {
					InventoryPacket::sendMesobagSucceed(player, mesos);
					used = true;
				}
				break;
			}
			case Items::Chalkboard:
			case Items::Chalkboard2: {
				string msg = packet.getString();
				player->setChalkboard(msg);
				InventoryPacket::sendChalkboardUpdate(player, msg);
				break;
			}
			case Items::FungusScroll:
			case Items::OinkerDelight:
			case Items::ZetaNightmare:
				Inventory::useItem(player, itemid);
				used = true;
				break;
			case Items::ViciousHammer: {
				int8_t inventory = (int8_t) packet.get<int32_t>(); // How pointless...
				int16_t slot = (int16_t) packet.get<int32_t>();
				Item *f = player->getInventory()->getItem(inventory, slot);
				if (f == nullptr || f->getHammers() == Items::MaxHammers) {
					// Hacking, probably
					return;
				}
				f->incHammers();
				f->incSlots();
				InventoryPacket::sendHammerSlots(player, f->getHammers());
				player->getInventory()->setHammerSlot(slot);
				used = true;
				break;
			}
			case Items::CongratulatorySong:
				if (!player->updateTickCount(packet.get<int32_t>())) {
					// Tickcount was the same or less than 100 of the difference.
					return;
				}
				used = Maps::getMap(player->getMap())->playJukebox(player, itemid, 60 * 5); // 5 minutes is enough!
				break;
			case Items::KoreanKite:
			case Items::HeartBalloon:
			case Items::GraduationBanner:
			case Items::AdmissionBanner: {
				string message = packet.getString();
				if (!player->updateTickCount(packet.get<int32_t>())) {
					// Tickcount was the same or less than 100 of the difference.
					return;
				}

				used = Maps::getMap(player->getMap())->createKite(player, itemid, message);
				if (!used) {
					InventoryPacket::sendCannotFlyHere(player);
				}

				break;
			}
			default: {
				packet.reset();
				std::stringstream x;
				x << "Unknown cash item! ItemID: " << itemid << "; Player ID: " << player->getId() << "; Packet: " << packet;
				ChannelServer::Instance()->log(LogTypes::Info, x.str());
				break;
			}
		}
	}
	if (used) {
		Inventory::takeItem(player, itemid, 1);
	}
	else {
		InventoryPacket::blankUpdate(player);
	}
}
示例#5
0
void PacketCreator::addBuffer(PacketReader &packet) {
	addBuffer(packet.getBuffer(), packet.getBufferLength());
}