예제 #1
0
bool GameModeCommand::execute(CommandSender *sender, std::string &label, std::vector<std::string> &args)
{
	if (!testPermission(sender)) return true;
	if (args.empty())
	{
		sender->sendTranslation(ChatColor::RED + "%commands.generic.usage", { usageMessage });
		return false;
	}

	std::string modeArg = args[0];
	std::string playerArg = sender->getName();

	if ((int)args.size() >= 2)
		playerArg = args[1];

	SMPlayer *player = ServerManager::getPlayer(playerArg);
	if (!player)
	{
		sender->sendTranslation("commands.generic.player.notFound", {});
		return false;
	}

	GameType gametype = Server::getGamemodeFromString(args[0]);
	if (gametype == GameType::UNDEFINED)
	{
		sender->sendMessage("Unknown game mode");
		return true;
	}

	if (player->getGameType() == gametype)
	{
		sender->sendMessage(player->getName() + " already has game mode " + SMUtil::toString((int)gametype));
		return true;
	}
	player->setGameType(gametype);

	if (gametype != player->getGameType())
		sender->sendMessage("Game mode change for " + player->getName() + " failed!");
	else
	{
		if (sender == player)
			Command::broadcastCommandTranslation(sender, "commands.gamemode.success.self", { Server::getGamemodeString(gametype) });
		else
			Command::broadcastCommandTranslation(sender, "commands.gamemode.success.other", { player->getName(), Server::getGamemodeString(gametype) });
	}
	return true;
}
void CustomServerNetworkHandler::handleLogin(ServerNetworkHandler *real, const RakNet::RakNetGUID &guid, LoginPacket *packet)
{
	if (!real->visible || real->_getPlayer(guid))
		return;

	if (packet->protocol1 != SharedConstants::NetworkProtocolVersion)
	{
		PlayStatusPacket statusPacket;
		if (packet->protocol1 < SharedConstants::NetworkProtocolVersion)
			statusPacket.status = PlayStatusPacket::LOGIN_FAILED_CLIENT;
		else
			statusPacket.status = PlayStatusPacket::LOGIN_FAILED_SERVER;
		real->sender->send(guid, statusPacket);
		return;
	}

	std::string username = packet->username;
	const char *ipAddress = real->raknet->getPeer()->GetSystemAddressFromGuid(guid).ToString(false);

	PlayerPreLoginEvent preLoginEvent(username, ipAddress, packet->clientUUID);
	ServerManager::getPluginManager()->callEvent(preLoginEvent);
	if (preLoginEvent.getResult() != PlayerPreLoginEvent::ALLOWED)
	{
		disconnectClient(real, guid, preLoginEvent.getKickMessage());
		return;
	}

	bool valid = true;

	int len = username.length();
	if (len > 16 || len < 3)
		valid = false;

	for (int i = 0; i < len; i++)
	{
		char c = username[i];
		if ((c >= 'a' && c <= 'z') ||
			(c >= 'A' && c <= 'Z') ||
			(c >= '0' && c <= '9') || c == '_')
			continue;

		valid = false;
		break;
	}

	std::unique_ptr<ServerPlayer> serverPlayer = real->createNewPlayer(guid, packet);
	SMPlayer *smPlayer = new SMPlayer(ServerManager::getServer(), serverPlayer.get());

	PlayerLoginEvent loginEvent(smPlayer, ipAddress);

	std::string iusername = SMUtil::toLower(packet->username);
	if (!valid || !iusername.compare(SMUtil::toLower(ServerManager::getLocalPlayer()->getName())) ||
		!iusername.compare("rcon") || !iusername.compare("console") || !iusername.compare("server"))
		loginEvent.disallow(PlayerLoginEvent::KICK_INVALID_NAME, "disconnectionScreen.invalidName");
	else if (packet->skin.length() != 64 * 32 * 4 && packet->skin.length() != 64 * 64 * 4)
		loginEvent.disallow(PlayerLoginEvent::KICK_INVALID_SKIN, "disconnectionScreen.invalidSkin");
	else if (ServerManager::getBanList(BanList::NAME)->isBanned(iusername))
	{
		BanEntry *entry = ServerManager::getBanList(BanList::NAME)->getBanEntry(iusername);
		loginEvent.disallow(PlayerLoginEvent::KICK_BANNED, "You are banned from this server! Reason: " + entry->getReason());
	}
	else if (ServerManager::hasWhitelist() && !ServerManager::isWhitelisted(iusername))
		loginEvent.disallow(PlayerLoginEvent::KICK_WHITELIST, "You are not white-listed on this server!");
	else if (ServerManager::getBanList(BanList::IP)->isBanned(ipAddress))
	{
		BanEntry *entry = ServerManager::getBanList(BanList::IP)->getBanEntry(ipAddress);
		loginEvent.disallow(PlayerLoginEvent::KICK_BANNED, "Your IP address is banned from this server! Reason: " + entry->getReason());
	}

	ServerManager::getPluginManager()->callEvent(loginEvent);
	if (loginEvent.getResult() != PlayerLoginEvent::ALLOWED)
	{
		disconnectClient(real, guid, loginEvent.getKickMessage());
		delete smPlayer;
		return;
	}

	std::vector<SMPlayer *> players = ServerManager::getOnlinePlayers();
	for (int i = 0; i < players.size(); ++i)
	{
		SMPlayer *p = players[i];
		if (!SMUtil::toLower(p->getName()).compare(iusername))
		{
			disconnectClient(real, p->getHandle()->guid, "You logged in from another location");
			break;
		}
	}

	PlayStatusPacket pk;
	pk.status = PlayStatusPacket::LOGIN_SUCCESS;
	real->sender->send(guid, pk);

	Dimension *dimension = serverPlayer->getDimension();
	if (!dimension)
		dimension = real->level->createDimension(DIMENSION_NORMAL);

	serverPlayer->prepareRegion(*dimension->getChunkSource());
	real->_sendLevelData(serverPlayer.get(), guid);

	ServerPlayer *player = serverPlayer.get();
	real->level->addPlayer(std::move(serverPlayer));
	real->_sendAdditionalLevelData(player, guid);
	ServerManager::getServer()->addPlayer(smPlayer);

	real->raknet->announceServer(ServerManager::getServerName());

	smPlayer->setAddress(real->raknet->getPeer()->GetSystemAddressFromGuid(guid).ToString(false));

	PlayerJoinEvent joinEvent(smPlayer, "");
	ServerManager::getPluginManager()->callEvent(joinEvent);
}
예제 #3
0
bool BanIpCommand::execute(SMPlayer *sender, std::string &label, std::vector<std::string> &args)
{
	if ((int)args.size() < 1)
	{
		sender->sendTranslation("§c%commands.generic.usage", { usageMessage });
		return false;
	}

	std::string nameOrIP = args[0];

	args.erase(args.begin());
	std::string reason = SMUtil::trim(SMUtil::join(args, " "));

	std::regex rx("\\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b");
	if (std::regex_match(nameOrIP, rx))
	{
		Command::broadcastCommandTranslation(sender, "commands.banip.success", { nameOrIP });
		processIPBan(nameOrIP, sender, reason);
	}
	else
	{
		SMPlayer *player = ServerManager::getPlayer(nameOrIP);
		if (!player)
		{
			sender->sendTranslation("§c%commands.banip.invalid", {});
			return false;
		}

		std::string ip = player->getAddress();

		Command::broadcastCommandTranslation(sender, "commands.banip.success.players", { ip, player->getName() });
		processIPBan(ip, sender, reason);
	}
	return true;
}
void CustomServerNetworkHandler::handleUseItem(ServerNetworkHandler *real, const RakNet::RakNetGUID &guid, UseItemPacket *packet)
{
	Player *player = real->_getPlayer(guid);
	if (!player || !player->isAlive())
		return;

	if (player->getSelectedItem())
		packet->item = *player->getSelectedItem();
	else
		packet->item.setNull();

	// TEST start
	BlockPos test_pos = packet->pos;
	ItemInstance test_item = packet->item;
	FullBlock test_targetBlock = player->getRegion()->getBlockAndData(test_pos);

	SMPlayer *smPlayer = ServerManager::getServer()->getPlayer(player);
	if (!smPlayer->isOp())
	{
		int id = packet->item.getId();
		if (id == 373 || id == 438)
			return;
	}
	// TEST end

	if (packet->face == 255)
	{
		std::unique_ptr<PlayerInteractEvent> event = EventFactory::callPlayerInteractEvent(player, Action::RIGHT_CLICK_AIR, &packet->item);
		if (event && event->useItemInHand() != Event::DENY)
			real->gamemode->useItem(*player, packet->item);
	}
	else
	{
		if (player->distanceTo(Vec3(packet->pos)) >= 12)
			return;

		Block *touchedBlock = player->getRegion()->getBlock(packet->pos);
		if (touchedBlock->isType(Block::mInvisibleBedrock))
			return;

		if (!player->isSneaking())
		{
			if (touchedBlock->use(*player, packet->pos))
				return;
		}

		Vec3 oldPos = player->pos;
		player->setPos(packet->entityPos);

		real->gamemode->useItemOn(*player, &packet->item, packet->pos, packet->face,
			Vec3(packet->pos.x + packet->fPos.x, packet->pos.y + packet->fPos.y, packet->pos.z + packet->fPos.z));

		player->setPos(oldPos);
	}

	// TEST start
	if (!smPlayer->isOp())
	{
		if (test_targetBlock.id.id != Block::mTallgrass->id)
		{
			switch (packet->face)
			{
			case 0: test_pos.y--; break;
			case 1: test_pos.y++; break;
			case 2: test_pos.z--; break;
			case 3: test_pos.z++; break;
			case 4: test_pos.x--; break;
			case 5: test_pos.x++; break;
			}
		}

		FullBlock test_newBlock = player->getRegion()->getBlockAndData(test_pos);

		int id = test_newBlock.id.id;
		int aux = test_newBlock.aux;
		if (id == 46 || id == 51 || id == 95 || id == 90 || (id >= 8 && id <= 11))
		{
			for (SMPlayer *p : smPlayer->getServer()->getOnlinePlayers())
			{
				if (p->isOp())
					p->sendMessage("§4" + smPlayer->getName() + " -> " + test_item.getName());
			}
			player->getRegion()->setBlockAndData(test_pos, FullBlock::AIR, 2);
		}
	}
	// TEST end
}