async def test_choose_menu_repr(client, message): ''' Creates a ChooseMenu and returns it's repr. ''' choices = ['nice', 'cat'] choose_menu = await ChooseMenu(client, message.channel, choices, lambda *args: Future(KOKORO)) await client.message_create(message.channel, repr(choose_menu))
def __new__(cls, client, event, map_name, length, possibilities): self = object.__new__(cls) self.client = client self.channel = event.channel self.users = [event.user] self.map_name = map_name self.length = length self.possibilities = possibilities self.cancelled = False self.waiter = waiter = Future(KOKORO) future_or_timeout(waiter, 300.0) Task(self.start_waiting(), KOKORO) ACTIVE_GAMES[event.channel.id] = self return self
async def __new__(cls): waiter = cls.waiter if waiter is None: average_cpu_frequence = psutil.cpu_freq().current PROCESS.cpu_percent() cls.waiter = waiter = Future(KOKORO) await sleep(1.0, KOKORO) cpu_percent = PROCESS.cpu_percent() cpu_frequence = psutil.cpu_freq() average_cpu_frequence = (average_cpu_frequence + cpu_frequence.current) / 2.0 result = object.__new__(cls) result.cpu_percent = cpu_percent result.average_cpu_frequence = average_cpu_frequence waiter.set_result(result) cls.waiter = None else: result = await waiter return result
async def start(self): client = self.client player1 = self.player1 player2 = self.player2 player1.other = player2 player2.other = player1 try: #creating missing channel player1.channel = await client.channel_private_create(player1.user) #adding channels to the event to notify us client.events.message_create.append(player1.channel, self) client.events.message_create.append(player2.channel, self) #game starts self.future = FutureWM(KOKORO, 2) future_or_timeout(self.future, 300.) #startup self.process = self.process_state_0 Task(player1.set_state_0(), KOKORO) Task(player2.set_state_0(), KOKORO) try: await self.future except TimeoutError: if not self.future._result: text1 = text2 ='The time is over, both players timed out' elif player1 in self.future._result: text1 = 'The other player timed out' text2 = 'You timed out' else: text1 = 'You timed out' text2 = 'The other player timed out' Task(client.message_create(player1.channel, text1), KOKORO) Task(client.message_create(player2.channel, text2), KOKORO) return self.process = self.process_state_1 player1.ships_left[:] = user_profile.ships player2.ships_left[:] = user_profile.ships if randint(0, 1): self.actual = player1 else: self.actual = player2 await self.actual.set_state_1(True) await self.actual.other.set_state_1(False) while self.process is not None: self.future = Future(KOKORO) future_or_timeout(self.future, 300.) try: result = await self.future except TimeoutError: await self.actual.other.set_state_2(True, 'Your opponent timed out!') await self.actual.set_state_2(False, 'You timed out!') return if result: self.actual = self.actual.other except BaseException as err: if isinstance(err, ConnectionError): return if isinstance(err, DiscordException) and err.code == ERROR_CODES.invalid_message_send_user: return await client.events.error(client, f'{self!r}.start', err) finally: self.cancel()
class battleships_game: __slots__=('actual', 'client', 'future', 'player1', 'player2', 'process',) def __init__(self, client, user1, user2, channel2): BS_GAMES[user1] = self BS_GAMES[user2] = self self.client = client self.player1 = user_profile(user1, client) self.player2 = user_profile(user2, client) self.player2.channel = channel2 Task(self.start(), KOKORO) #compability async def start(self): client = self.client player1 = self.player1 player2 = self.player2 player1.other = player2 player2.other = player1 try: #creating missing channel player1.channel = await client.channel_private_create(player1.user) #adding channels to the event to notify us client.events.message_create.append(player1.channel, self) client.events.message_create.append(player2.channel, self) #game starts self.future = FutureWM(KOKORO, 2) future_or_timeout(self.future, 300.) #startup self.process = self.process_state_0 Task(player1.set_state_0(), KOKORO) Task(player2.set_state_0(), KOKORO) try: await self.future except TimeoutError: if not self.future._result: text1 = text2 ='The time is over, both players timed out' elif player1 in self.future._result: text1 = 'The other player timed out' text2 = 'You timed out' else: text1 = 'You timed out' text2 = 'The other player timed out' Task(client.message_create(player1.channel, text1), KOKORO) Task(client.message_create(player2.channel, text2), KOKORO) return self.process = self.process_state_1 player1.ships_left[:] = user_profile.ships player2.ships_left[:] = user_profile.ships if randint(0, 1): self.actual = player1 else: self.actual = player2 await self.actual.set_state_1(True) await self.actual.other.set_state_1(False) while self.process is not None: self.future = Future(KOKORO) future_or_timeout(self.future, 300.) try: result = await self.future except TimeoutError: await self.actual.other.set_state_2(True, 'Your opponent timed out!') await self.actual.set_state_2(False, 'You timed out!') return if result: self.actual = self.actual.other except BaseException as err: if isinstance(err, ConnectionError): return if isinstance(err, DiscordException) and err.code == ERROR_CODES.invalid_message_send_user: return await client.events.error(client, f'{self!r}.start', err) finally: self.cancel() async def process_state_0(self, message): if message.author is self.player1.user: player = self.player1 else: player = self.player2 other = player.other while True: if sum(player.ships_left) == 0: text='Waiting on the other player.' break result = NEW_RP.fullmatch(message.content) if result is not None: text='new' break result = POS_PATTERN_0.match(message.content) if result is None: text='Bad input format' break result=result.groups() value=result[0] if value.isdigit(): x = int(value) if x > 10: text='Bad input format.' break x -= 1 y = 100 else: x = 100 y = ('abcdefghij').index(value.lower()) value = result[1] if value.isdigit(): if x != 100: text = 'Dupe coordinate' break x = int(value) if x > 10: text = 'Bad input format.' break x -= 1 else: if y != 100: text = 'Dupe coordinate' break y = ('abcdefghij').index(value) size1 = int(result[2]) size2 = int(result[4]) if (size1 == 1 and size2 == 3) or (size1 == 3 and size2 == 1): type_=1 elif (size1 == 1 and size2 == 4) or (size1 == 4 and size2 == 1): type_ = 2 elif (size1 == 2 and size2 == 2): type_ = 3 else: text = 'Invalid ship size' break if player.ships_left[type_] == 0: text = 'You do not have anymore ships from that size' break text = '' x_start = x if x_start > 0: x_start -= 1 x_end = x+size1 if x_end > 10: text = 'There is not enough space to place that ship!' break elif x_end < 10: x_end += 1 y_start = y*10 if y_start > 0: y_start -= 10 y_end = (y+size2)*10 if y_end > 100: text = 'There is not enough space to place that ship!' break elif y_end < 100: y_end += 10 data = player.data for n_x in range(x_start, x_end): for n_y in range(y_start, y_end, 10): if data[n_x+n_y]: text = ( f'Can not set ship to {1+x}/{chr(65+y)}, because coordinate {1+n_x}/{chr(65+n_y//10)} is ' 'already used.' ) break if text: break ship = ship_type(x, y, size1, size2, type_) cords = [] x_start = x x_end = x+size1 y_start = y*10 y_end = (y+size2)*10 for n_x in range(x_start, x_end): for n_y in range(y_start, y_end, 10): cord = n_x+n_y data[cord] = type_ player.ship_positions[cord] = ship cords.append(f'{chr(65+n_y//10)}/{1+n_x}') player.ships_left[type_] -= 1 if sum(player.ships_left) == 0: self.future.set_result(player) text = ( f'You placed all of your ships. Last ship placed at: {", ".join(cords)}; waiting on the other ' 'player.' ) else: text = f'You placed the ship succesfully at: {", ".join(cords)}.' break client = self.client if text == 'new': await player.process(True, None) return if sum(player.ships_left) == sum(other.ships_left) == 0: return await player.process(False, text) async def process_state_1(self, message): if self.actual is self.player1: player = self.player1 other = self.player2 else: player = self.player2 other = self.player1 client = self.client if message.author is not self.actual.user: result = NEW_RP.fullmatch(message.content) if result is not None: await player.process(True, None) return data=other.data while True: result = NEW_RP.fullmatch(message.content) if result is not None: text = 'new' break result = POS_PATTERN_1.match(message.content) if result is None: text = 'Bad input format' break result = result.groups() value = result[0] if value.isdigit(): x = int(value) if x > 10: text = 'Bad input format.' break x = x-1 y = 100 else: x = 100 y = ('abcdefghij').index(value.lower()) value = result[1] if value.isdigit(): if x != 100: text = 'Dupe coordinate' break x = int(value) if x > 10: text = 'Bad input format.' break x = x-1 else: if y!=100: text='Dupe coordinate' break y = ('abcdefghij').index(value) value = data[x+y*10] if value > 4: text='That position is already shot' break text = '' break if text: if text == 'new': await player.process(True, None) else: await player.process(False, text) return if value == 0: data[x+y*10] = 5 player.state = False other.state = True await player.process(False, 'You missed!') await other.process(True, f'Your opponent shot {chr(65+y)}/{1+x}, it missed!\n') self.future.set_result(True) return del text data[x+y*10] = 6 ship=other.ship_positions.pop(x+y*10) ship.parts_left -= 1 if ship.parts_left == 0: other.ships_left[ship.type] -= 1 for cord in ship: data[cord] = 7 if sum(other.ships_left): text1 = f'You shot {chr(65+y)}/{1+x} and you sinked 1 of your opponents ships!\n' text2 = f'Your opponent shot {chr(65+y)}/{1+x} and your ship sinked :c\n' else: self.process = None await player.set_state_2(True, f'You shot {chr(65+y)}/{1+x} and you sinked your opponents last ship!') await other.set_state_2(False, f'Your opponent shot {chr(65+y)}/{1+x} and your last ship sinked :c') self.future.set_result(False) return else: text1 = f'You shot {chr(65+y)}/{1+x} and you hit a ship!' text2 = f'Your opponent shot {chr(65+y)}/{1+x} and hit 1 of your ships!' player.state = True other.state = False await player.process(False, text1) await other.process(True, text2) self.future.set_result(False) async def __call__(self, client, message): if message.author is client: return await self.process(message) def cancel(self): event = self.client.events.message_create event.remove(self, self.player1.channel) event.remove(self, self.player2.channel) del BS_GAMES[self.player1.user] del BS_GAMES[self.player2.user] self.player1.cancel() self.player2.cancel()
async def battle_manager(client, message, target:Converter('user', flags=ConverterFlag.user_default.update_by_keys(everywhere=True), default=None)): text = '' while True: if target is None: break guild = message.guild source = message.author if source in BS_GAMES: text = 'You cant start a game, if you are in 1 already' break if source in BS_REQUESTERS: text = 'You can have only one active request' break if target is source: text = 'Say 2 and easier.' break if target is client: text = 'NO AI opponent yet!' break if target in BS_GAMES: text = 'The user is already in game' break request = active_request(source, target) is_reversed = BS_REQUESTS.get(request) if is_reversed is not None: is_reversed.future.set_result(message) return BS_REQUESTS[request] = request BS_REQUESTERS.add(source) channel = message.channel private = await client.channel_private_create(target) await client.message_create(channel, f'Waiting on {target.full_name}\'s reply here and at dm.\nType:"accept name/mention" to accept') future = request.future=Future(KOKORO) check = wait_on_reply(guild, source, target) event = client.events.message_create waiter1 = WaitAndContinue(future, check, channel, event, 300.) waiter2 = WaitAndContinue(future, check, private, event, 300.) try: result = await future except TimeoutError: try: BS_REQUESTERS.remove(source) text = f'The request from {source.full_name} timed out' except KeyError: pass break finally: try: del BS_REQUESTS[request] except KeyError: pass for waiter in (waiter1,waiter2): waiter.cancel() try: BS_REQUESTERS.remove(source) except KeyError: text = 'The requester is already in a game' break if target in BS_GAMES: text='You already accepted a game' break try: BS_REQUESTERS.remove(target) await client.message_create(channel, f'Request from {target.full_name} got cancelled') except KeyError: pass game = battleships_game(client, source, target, private) break if text: await client.message_create(message.channel, text) else: embed = await bs_description(client, message) await Closer(client, message.channel, embed)
async def runner(self): client = self.client channel = self.channel answers = self.answers buffer = ReuBytesIO() embed = Embed(color=KANAKO_COLOR).add_image( 'attachment://guess_me.png').add_footer('') time_till_notify = CIRCLE_TIME - 10 for index, (question, answer) in enumerate(self.map, 1): embed.footer.text = f'{index} / {len(self.map)}' if self.possibilities: self.options = self.generate_options(answer) embed.description = '\n'.join([ f'**{index}.: {value}**' for index, value in enumerate(self.options, 1) ]) try: await client.message_create(channel, embed=embed, file=('guess_me.png', draw(buffer, question))) except BaseException as err: self.cancel() if isinstance(err, ConnectionError): return if isinstance(err, DiscordException): if err.code in ( ERROR_CODES.unknown_channel, # channel deleted ERROR_CODES.missing_access, # client removed ERROR_CODES. missing_permissions, # permissions changed meanwhile ): return await client.events.error(client, f'{self.__class__.__name__}.runner', err) return circle_start = LOOP_TIME() self.waiter = waiter = Future(KOKORO) future_or_timeout(waiter, time_till_notify) try: await waiter except TimeoutError: Task(self.notify_late_users(), KOKORO) self.waiter = waiter = Future(KOKORO) future_or_timeout(waiter, 10) try: await waiter except TimeoutError: leavers = [] users = self.users for index in reversed(range(len(users))): user = users[index] if user in answers: continue leavers.append(user) del users[index] for element in self.history: del element.answers[index] if len(self.users) == 0: self.cancel() embed = Embed( None, 'No-one gave answer in time, cancelling the game.', color=KANAKO_COLOR) else: embed = Embed(None, '\n'.join([ 'Users timed out:', *(user.full_name for user in leavers) ]), color=KANAKO_COLOR) try: await client.message_create(channel, embed=embed) except BaseException as err: self.cancel() if isinstance(err, ConnectionError): return if isinstance(err, DiscordException): if err.code in ( ERROR_CODES. unknown_channel, # channel deleted ERROR_CODES. missing_access, # client removed ERROR_CODES. missing_permissions, # permissions changed meanwhile ): return await client.events.error( client, f'{self.__class__.__name__}.runner', err) return if self.cancelled: return self.waiter = None element = HistoryElement() element.question = question element.answer = answer element.options = self.options element.answers = [(value[0], value[1] - circle_start) for value in (answers[user.id] for user in self.users)] self.history.append(element) answers.clear() embed.title = f'Last answer: {answer}' self.cancel() embed = Embed(embed.title, color=KANAKO_COLOR) try: await client.message_create(channel, embed=embed) except BaseException as err: self.cancel() if isinstance(err, ConnectionError): return if isinstance(err, DiscordException): if err.code in ( ERROR_CODES.unknown_channel, # channel deleted ERROR_CODES.missing_access, # client removed ERROR_CODES. missing_permissions, # permissions changed meanwhile ): return await client.events.error(client, f'{self.__class__.__name__}.runner', err) return await GameStatistics(self)
async def command(client, message, target_channel: ChannelText, time: int): guild = message.guild if guild is None: return if time < 1: await client.message_create( message.channel, f'Time cannot be less than 1, got {time!r}') return canceller = Future(KOKORO) KOKORO.call_later(time * 3600.0, Future.set_result_if_pending, canceller, None) await client.message_create( message.channel, f'Starting loop over {target_channel.mention} for {time} hours.') invites = [] total = 0 while True: try: invite = await client.invite_create(target_channel) parsed = INVITE_GEN_RP.search(invite.code) if parsed is None: await client.invite_delete(invite) else: invites.append(invite) total += 1 except BaseException as err: if isinstance(err, ConnectionError): canceller.cancel() sys.stderr.write( 'invite_gen failed, connection error occured meanwhile!\n' ) return if isinstance(err, DiscordException): err_code = err.code if err_code in ( ERROR_CODES. invalid_permissions, # permissions changed meanwhile ERROR_CODES.invalid_access, # client removed ): canceller.set_result_if_pending(None) break if err_code == ERROR_CODES.unknown_channel: # message's channel deleted canceller.cancel() return if err_code == ERROR_CODES.max_invites: canceller.set_result_if_pending(None) break canceller.cancel() await client.events.error(client, 'invite_gen', err) return if canceller.done(): break title = f'{total} invites generated, from this {len(invites)} passed.' pages = [ Embed(title, chunk) for chunk in cchunkify([invite.url for invite in invites]) ] await Pagination(client, message.channel, pages, timeout=7200.0)
async def __call__(self, key): cache = self.cache try: result = cache[key] except KeyError: pass else: cache.move_to_end(key) return result, False if self.limit.is_active(): return None, True quoted_key = quote(key) active = self.active try: waiters = active[key] except KeyError: pass else: waiter = Future(KOKORO) waiters.append(waiter) return await waiter waiters = [] active[key] = waiters try: async with self.limit.lock: # Check time again, because we may become limited when we get here. if self.limit.is_active(): result = None limited = True else: url = self.query_builder(quoted_key) async with self.http.get( url, headers=GITHUB_HEADERS) as response: self.limit.set(response.headers) if response.status in (200, 404): result_data = await response.json() else: result_data = None result = self.object_type(result_data) if len(cache) == 1000: del cache[next(iter(cache))] cache[key] = result limited = False except BaseException as err: try: del active[key] except KeyError: pass else: for waiter in waiters: waiter.set_exception_if_pending(err) raise err else: try: del active[key] except KeyError: pass else: for waiter in waiters: waiter.set_result_if_pending((result, limited)) return result, limited