Exemplo n.º 1
0
    async def get_player_name(self, pid):
        pid = int(pid)
        friend = self.friends.get_friend(pid)
        if friend is None:
            name = await self.fetch_player_name(pid)
            if name is None:
                return

            try:
                friend = await self.friends.add(name)
            except Exception:
                return normalize_name(name)

        return normalize_name(friend.name)
Exemplo n.º 2
0
	async def handle_module_packet(self, tid, packet):
		if tid == SYNCHRONIZE:
			# Synchronizes the game and the bot
			now = time.time()

			lua_time, ranks, staff = packet.split("\x00", 2)
			self.time_diff = int(lua_time) // 1000 - now

			self.player_ranks = {}
			self.ranks = {}

			for rank in ranks.split("\x01"):
				self.ranks[rank] = False

			for data in staff.split("\x00"):
				player, *ranks = data.split("\x01")
				player = normalize_name(player)

				self.player_ranks[player] = self.ranks.copy()
				for rank in ranks:
					self.player_ranks[player][rank] = True

			self.dispatch("module_synchronization")

		else:
			return False

		return True
Exemplo n.º 3
0
	async def on_channel_message(self, msg):
		# send the message to discord
		for chat in (self.mod_chat, self.mapper_chat):
			if msg.channel != chat.channel:
				continue

			content = re.sub(
				r"`(https?://(?:-\.)?(?:[^\s/?\.#-]+\.?)+(?:/[^\s]*)?)`",
				r"\1",

				"`" + msg.content.replace("`", "'")
				.replace("&lt;", "<")
				.replace("&amp;", "&")
				.replace(" ", "` `") + "`"
			)
			author = normalize_name(msg.author)

			await self.send_webhook(
				chat.chat_webhook,
				"`[{}]` `[{}]` {}".format(
					msg.community.name, author, content
				)
			)

			if author != "Parkour#8558" and msg.content[0] == ".":
				args = msg.content.split(" ")
				cmd = args.pop(0).lower()[1:]
				ranks = self.get_player_rank(author)

				self.dispatch(
					"channel_command",
					msg.channel, chat.name, author, ranks, cmd, args
				)

			break
Exemplo n.º 4
0
	async def on_friend_connected(self, friend):
		if friend.isSoulmate:
			return
		name = normalize_name(friend.name)

		# Check which chats this player should be in
		ranks = self.get_player_rank(name)
		chats = []

		for chat in (self.mod_chat, self.mapper_chat):
			for rank in chat.ranks:
				if ranks[rank]:
					break
			else:
				continue

			chats.append(chat)

		# Wait for the chats to loop and update their players/members
		while chats:
			updated = await self.wait_for("on_chat_loop")

			for chat in updated:
				if chat in chats:
					chats.remove(chat)

					if name not in chat.players:
						await self.whisper(
							name,
							"Please join the {} chat: /chat {}"
							.format(chat.name, chat.channel_name)
						)
Exemplo n.º 5
0
    async def limit_whois_cache(self):
        while not self.main.open:
            await asyncio.sleep(3.0)

        while self.main.open:
            await asyncio.sleep(300.0)

            if self.friends is None or len(self.friends.friends) < 400:
                continue

            count, friends, required = 0, [], len(self.friends.friends) - 350

            for friend in self.friends.friends:
                if (friend.isSoulmate
                        or normalize_name(friend.name) in self.player_ranks):
                    continue

                count += 1
                friends.append(friend)
                if count >= required:
                    break

            for friend in friends:
                await friend.remove()
                await asyncio.sleep(1.0)
Exemplo n.º 6
0
    async def on_whisper(self, whisper):
        await super().on_whisper(whisper)

        if whisper.content.startswith("tfm"):
            await self.proxy.sendTo(
                {
                    "type": "verification",
                    "username": normalize_name(whisper.author),
                    "token": whisper.content
                }, "discord")
Exemplo n.º 7
0
    def prettify_message(self, author, content, community=None):
        content = re.sub(
            r"`(https?://(?:-\.)?(?:[^\s/?\.#-]+\.?)+(?:/[^\s]*)?)`", r"\1",
            "`" + content.replace("`", "'").replace("&lt;", "<").replace(
                "&amp;", "&").replace(" ", "` `") + "`")
        author = normalize_name(author)

        if community is not None:
            return "`[{}]` `[{}]` {}".format(community, author, content)
        else:
            return "`[{}]` {}".format(author, content)
Exemplo n.º 8
0
    async def save_player_file(self, name, file, update, online_check=True):
        name = normalize_name(name)
        if online_check:
            pid, name, online = await self.get_player_info(name)
            if not online:
                return False

        await self.send_callback(
            SAVE_PLAYER_FILE, "{}\x00{}\x00{}".format(
                name, json.dumps(file),
                "\x01".join(update) if isinstance(update, tuple) else update))
        return True
Exemplo n.º 9
0
    async def load_player_file(self, name, online_check=True):
        name = normalize_name(name)
        if online_check:
            pid, name, online = await self.get_player_info(name)
            if not online:
                return

        await self.send_callback(LOAD_PLAYER_FILE, name)
        try:
            name, data = await self.wait_for(
                "on_player_file_loaded",
                lambda player, data: name == player,
                timeout=1.0)
        except Exception:
            return

        return json.loads(data) if data else None
Exemplo n.º 10
0
    async def get_player_info(self, query):
        if isinstance(query, str) and query.isdigit():
            query = int(query)

        friend = self.friends.get_friend(query)
        if friend is None:
            if isinstance(query, int):
                name = await self.fetch_player_name(query)
                if name is None:
                    return (None, None, None)

            else:
                name = query

            try:
                friend = await self.friends.add(name)
            except Exception:
                return (None, None, None)

        return (friend.id, normalize_name(friend.name), friend.isConnected)
Exemplo n.º 11
0
    async def fetch_player_name(self, pid):
        pid = int(pid)

        for attempt in range(3):
            try:
                async with self.forum_session.get(
                        "https://atelier801.com/profile?pr={}".format(
                            pid)) as resp:
                    match = re.search(
                        rb'> ([^<]+)<span class="nav-header-hashtag">'
                        rb'(#\d{4})<\/span>', await resp.read())

                    if match is None:
                        return

                    return normalize_name(
                        (match.group(1) + match.group(2)).decode())

            except Exception:
                await self.forum_session.close()
                self.forum_session = aiohttp.ClientSession()
Exemplo n.º 12
0
    async def on_channel_message(self, msg):
        # send the message to discord
        for chat in (self.mod_chat, self.mapper_chat):
            if msg.channel != chat.channel:
                continue

            await self.send_webhook(
                chat.chat_webhook,
                self.prettify_message(msg.author, msg.content,
                                      msg.community.name))

            author = normalize_name(msg.author)
            if author != "Parkour#8558" and msg.content[0] == ".":
                args = msg.content.split(" ")
                cmd = args.pop(0).lower()[1:]
                ranks = self.get_player_rank(author)

                self.dispatch("channel_command", msg.channel, chat.name,
                              author, ranks, cmd, args)

            break
Exemplo n.º 13
0
	async def check_intruders(self):
		while not self.main.open:
			await asyncio.sleep(3.0)

		while self.main.open:
			await asyncio.sleep(15.0)

			updated = []
			for chat in (self.mod_chat, self.mapper_chat):
				if not chat.loaded:
					continue

				try:
					players = await chat.channel.who()
				except Exception: # timeout
					continue

				chat.players = []
				updated.append(chat)

				for player in players:
					player = normalize_name(player.username)
					chat.players.append(player) # append normalized names
					if player == "Parkour#8558":
						continue

					ranks = self.get_player_rank(player)
					for rank in chat.ranks:
						if ranks[rank]:
							break
					else:
						# intruder!
						await chat.channel.send(
							"Intruder alert: {}".format(player)
						)
						await asyncio.sleep(3.0)
						await self.generate_new_chat(chat)

			self.dispatch("chat_loop", updated)
Exemplo n.º 14
0
    async def on_whisper_command(self, whisper, author, ranks, cmd, args):
        if await super().on_whisper_command(whisper, author, ranks, cmd, args):
            return True

        if cmd == "norep":
            if not ranks["admin"] and not ranks["mod"]:
                return True

            if not args:
                await whisper.reply("Usage: .norep Username#0000")
                return True

            target = normalize_name(args[0])
            pid, name, online = await self.get_player_info(target)
            if name is None or not online:
                await whisper.reply(
                    "That player ({}) is not online.".format(target))
                return True

            file = await self.load_player_file(name, online_check=False)
            if file is None:
                await whisper.reply("Could not load {}'s file.".format(name))
                return True

            file["report"] = not file["report"]
            if not await self.save_player_file(
                    name, file, "report", online_check=False):
                await whisper.reply("Could not modify {}'s file.".format(name))
                return True

            action = "enabled" if file["report"] else "disabled"
            await self.send_webhook(
                env.webhooks.sanctions,
                "**`[NOREP]:`** `{}` has {} reports from `{}` (ID: `{}`)".
                format(author, action, name, pid))
            await whisper.reply(
                "Reports from {} (ID: {}) have been {}.".format(
                    name, pid, action))

        elif cmd == "report":
            # Argument check
            if not args:
                await whisper.reply("Usage: .report Username#0000")
                return True

            reported = normalize_name(args[0])
            if reported == author:
                await whisper.reply("Why are you trying to report yourself?")
                return True

            pid, name, online = await self.get_player_info(reported)
            if name is None or not online:
                await whisper.reply(
                    "That player ({}) is not online.".format(reported))
                return True

            await whisper.reply(
                "Your report of the player {} will be handled shortly.".format(
                    reported))

            # Player information check
            if self.report_cooldown(author):
                return True

            if reported in self.reported:
                return True

            file = await self.load_player_file(author, online_check=False)
            if file is None or not file["report"]:
                return True

            file = await self.load_player_file(reported, online_check=False)
            if file is None:
                return True

            now = self.tfm_time()
            if now < file.get("killed", 0):
                return

            ban = file.get("banned", 0)
            if ban == 2 or now < ban:
                return True

            # Create report
            report = self.rep_id
            self.rep_id += 1

            online = len(self.mod_chat.players) - 1
            now = time.time()
            self.reports[report] = [
                author, reported, online == 0, now + 60 * 5, now + 60 * 30
            ]
            self.reported.append(reported)
            self.reporters.append((now + 60 * 5, author))

            if online == 0:
                await self.report_discord(report)

            else:
                await self.mod_chat.channel.send(
                    "{} reported {} (report id: {}) (room: {}) "
                    "(use the handle command here before handling it)".format(
                        author, reported, report, file["room"]))

        else:
            return False
        return True
Exemplo n.º 15
0
	def get_player_rank(self, player):
		return self.player_ranks.get(
			normalize_name(player),
			self.ranks
		)