예제 #1
0
    async def on_pick(self, ctx, member: discord.Member):
        if not self.model.ChkIsReg(ctx):
            return

        choosingId = ctx.message.author.id
        choosingPlayer = ctx.message.author.name
        pickedId = member.id
        pickedPlayer = member.name

        game = await self.can_pick(ctx, choosingId, choosingPlayer, pickedId)
        if not game:
            return

        if game.playerTurn.id != choosingId:
            await ctx.send(CodeSB(f'Not your turn to pick'))
            return None

        if pickedId not in game.PoolIds:
            await ctx.send(CodeSB(f"{pickedPlayer} not in player pool"))
            return

        if game.state == State.IN_GAME:
            await ctx.send(CodeSB(f'Game already running'))
            return None

        await self.model.PickPlayer(ctx, game, choosingPlayer, pickedId,
                                    pickedPlayer)
예제 #2
0
 async def RemPlayerQueue(self, ctx, playerName, playerId, region: Region):
     if self.queues.remove_all_of(region.region, playerId):
         embed = discord.Embed(colour=discord.Colour.blue(),
                               description=self.QueueStatus())
         await ctx.channel.send(content=CodeSB(
             f'{playerName} removed from: {", ".join(region.ToList())}'),
                                embed=embed)
     else:
         await ctx.send(CodeSB(f'{playerName} not queued on any region'))
예제 #3
0
    async def can_pick(self, ctx, choosingId, choosingPlayer, pickedId):
        if not (self.model.ChkIsRegId(choosingId)
                and self.model.ChkIsRegId(pickedId)):
            return None

        region = self.model.RegFromPlayer(choosingId)
        if region == None:
            await ctx.send(CodeSB(f'Must be a captain in order to pick'))
            return None

        if choosingId == pickedId:
            await ctx.send(CodeSB(f'Cannot pick self'))
            return None

        return self.model.games[region]
예제 #4
0
    async def StartGame(self, ctx, game):
        zerg = [(self.IdToUser(id), id) for id in game.zerg.Ids]
        terran = [(self.IdToUser(id), id) for id in game.terran.Ids]

        zergNames = ", ".join(
            map(lambda memtup: Model.UserToName(memtup[0], memtup[1]), zerg))
        terranNames = ", ".join(
            map(lambda memtup: Model.UserToName(memtup[0], memtup[1]), terran))

        zergMentions = " ".join(
            map(lambda memtup: Model.UserToMention(memtup[0], memtup[1]),
                zerg))
        terranMentions = " ".join(
            map(lambda memtup: Model.UserToMention(memtup[0], memtup[1]),
                terran))

        description = f'''
One captain start a prepicked lobby and arrange teams and report back the result of the game with < !rw/!rl/!rt >

<Zerg> {zergNames}
<Terran> {terranNames}
'''
        embed = discord.Embed(description=CodeB(description, 'md'),
                              colour=discord.Colour.blue())
        await ctx.channel.send(
            content=CodeSB(f"Game Starting on {game.region}") +
            f' {zergMentions} {terranMentions}',
            embed=embed)
        await self.CreateVoice(game)
예제 #5
0
파일: Mod.py 프로젝트: CameronClay/zhex-bot
    async def on_set_stats(self, ctx, member: discord.Member, region: Region,
                           race: Race, wins: int, loses: int, ties: int):
        playerName = member.name
        regions = region.ToList()
        races = race.ToList()

        for reg in regions:
            usPlayer = self.model.playerDB.Find(member.id, reg)
            if usPlayer == None:
                await ctx.send(f'Player {playerName} not registered')
                return

            if not usPlayer.lastPlayed:
                usPlayer.SetPlayed()

            for r in races:
                usPlayer.wins[r] = wins
                usPlayer.loses[r] = loses
                usPlayer.ties[r] = ties
            self.model.playerDB.UpdateStats(usPlayer)

        await ctx.send(
            CodeSB(
                f"Updated {playerName}'s wins={usPlayer.wins[races[0]]}, loses={usPlayer.loses[races[0]]}, ties={usPlayer.ties[races[0]]} for {', '.join(races)} on {', '.join(regions)}"
            ))
예제 #6
0
파일: Mod.py 프로젝트: CameronClay/zhex-bot
 async def on_queue_flush(self, ctx, region: Region = Region(Region.ALL)):
     self.model.queues.clear(region.region)
     embed = discord.Embed(colour=discord.Colour.blue(),
                           description=self.model.QueueStatus())
     await ctx.channel.send(
         content=CodeSB(f'Queues cleared on: {", ".join(region.ToList())}'),
         embed=embed)
예제 #7
0
파일: Mod.py 프로젝트: CameronClay/zhex-bot
 async def on_queue_bot(self, ctx, region: Region, count: int):
     await self.model.CreateStubs(ctx, region, count)
     embed = discord.Embed(colour=discord.Colour.blue(),
                           description=self.model.QueueStatus())
     await ctx.channel.send(
         content=CodeSB(f'Queued {count} bots on {region.region}'),
         embed=embed)
예제 #8
0
 async def ValidateReg(self, ctx, region):
     if not Region.Valid(region):
         await ctx.send(
             CodeSB(
                 f'Invalid region, expected: {"/".join(Region.VALID_REGIONS)}'
             ))
         return False
     return True
예제 #9
0
    async def ReportMatchResult(self, ctx, res, playerId):
        region = self.RegFromPlayer(playerId)
        if region == None:
            await ctx.send(
                CodeSB(f'Must be a captain in order to report match result'))
            return

        game = self.games[region]
        if game == None or game.state != State.IN_GAME:
            await ctx.send(CodeSB(f'Cannot report result of non-running game'))
            return

        oldZElo = [(self.IdToName(player.id), int(player.zelo))
                   for player in game.zerg.players]
        oldTElo = [(self.IdToName(player.id), int(player.telo))
                   for player in game.terran.players]
        game.MatchResult(playerId, res)
        for player in itertools.chain(game.zerg.players, game.terran.players):
            self.playerDB.UpdatePlayer(player)

        newZElo = [(self.IdToName(player.id), int(player.zelo))
                   for player in game.zerg.players]
        newTElo = [(self.IdToName(player.id), int(player.telo))
                   for player in game.terran.players]

        embed = discord.Embed(
            description=f"Victor: {game.GetVictor(playerId, res)}",
            colour=discord.Colour.blue())

        nameMax = max(len(name) for name, _ in oldZElo)
        strZUpdElos = '\n'.join([
            f'{oldElo[0].ljust(nameMax)}: {oldElo[1]} -> {newElo[1]}'
            for oldElo, newElo in zip(oldZElo, newZElo)
        ])
        strTUpdElos = '\n'.join([
            f'{oldElo[0].ljust(nameMax)}: {oldElo[1]} -> {newElo[1]}'
            for oldElo, newElo in zip(oldTElo, newTElo)
        ])

        embed.add_field(name="Updated Z elo's: ", value=strZUpdElos)
        embed.add_field(name="Updated T elo's: ", value=strTUpdElos)
        await ctx.channel.send(
            content=CodeSB(f"Match Concluded on {game.region}"), embed=embed)

        await self.EndMatch(ctx, game)
예제 #10
0
    async def RemPlayerSub(self, ctx, playerName, playerId, region: Region):
        regions = region.ToList()

        for reg in regions:
            self.subs[reg].discard(playerId)

        await ctx.send(
            CodeSB(
                f'{playerName} no longer avaiable to sub on {", ".join(regions)}'
            ))
예제 #11
0
    async def on_register(self, ctx):
        playerId = ctx.message.author.id
        playerName = ctx.message.author.name

        registeredRegs = []
        for reg in Region.REGIONS:
            res = self.model.playerDB.IsRegistered(playerId, reg)
            if not res:
                self.model.playerDB.Register(Player(playerId, reg))
                registeredRegs.append(reg)

        if len(registeredRegs) == 0:
            await ctx.send(CodeSB(f'{playerName} already registered'))
            return
        else:
            await ctx.send(
                CodeSB(
                    f'{playerName} successfully registered on {", ".join(registeredRegs)}'
                ))
예제 #12
0
    async def on_cancel_match(self, ctx):
        if not self.model.ChkIsReg(ctx):
            return

        invokingId = ctx.message.author.id
        invokingPlayer = ctx.message.author.name

        region = self.model.RegFromPlayer(invokingId)
        if region == None:
            await ctx.send(CodeSB(f'Must be a captain in order to cancel'))
            return

        game = self.model.games[region]

        otherCaptId = game.terranCapt.id if game.zergCapt.id == invokingId else game.zergCapt.id
        otherCaptMent = self.model.IdToMention(otherCaptId)

        REQUEST_TIMEOUT = 60

        await ctx.send(
            CodeSB(f'{invokingPlayer} attempting to cancel game on {region}.')
            + f'{otherCaptMent} `respond with y/n`')

        def check(msg):
            response = msg.content.lower()
            return msg.author.id == otherCaptId and response in ['y', 'n']

        try:
            msg = await self.model.bot.wait_for("message",
                                                check=check,
                                                timeout=REQUEST_TIMEOUT)
        except asyncio.TimeoutError:
            await ctx.send(CodeSB(f"Cancelation request on {region} timed out")
                           )
        else:
            if msg.content == 'y':
                await self.model.EndMatch(ctx, game)
                await ctx.send(
                    CodeSB(f"Cancelation on {region} was successfull"))
            else:
                await ctx.send(
                    CodeSB(f"Cancelation on {region} was not successfull"))
예제 #13
0
    async def AddPlayerSub(self, ctx, playerName, playerId, region: Region):
        regions = region.ToList()

        if any((self.games[reg] and (playerId in self.games[reg].AllPlayers)
                for reg in regions)):
            await ctx.send(CodeSB(f'Cannot sub when in game or in player pool')
                           )
            return

        subbedRegs = []
        for reg in regions:
            if self.games[reg]:
                self.subs[reg].add(playerId)
                subbedRegs.append(reg)

        if len(subbedRegs) == 0:
            await ctx.send(CodeSB(f'No game found to sub/already in a pool'))
        else:
            await ctx.send(
                CodeSB(
                    f'{playerName} now avaiable to sub on {", ".join(subbedRegs)}'
                ))
예제 #14
0
    async def on_qracepref(self, ctx, region: Region = Region(Region.ALL)):
        if not self.model.ChkIsReg(ctx):
            return

        playerId = ctx.message.author.id
        playerName = ctx.message.author.name

        regions = region.ToList()
        racePrefs = dict()
        for reg in regions:
            usPlayer = self.model.playerDB.Find(playerId, reg)
            if usPlayer == None:
                await ctx.send(CodeSB(f'Player {playerName} not registered'))

            racePrefs[reg] = usPlayer.racePref

        racePrefStr = [
            f'{reg}: {pref.race}' for reg, pref in racePrefs.items()
        ]
        await ctx.send(
            CodeSB(f"{playerName}'s race preference: {', '.join(racePrefStr)}")
        )
예제 #15
0
파일: Mod.py 프로젝트: CameronClay/zhex-bot
    async def on_set_elo(self, ctx, member: discord.Member, region: Region,
                         race: Race, elo: float):
        playerName = member.name
        regions = region.ToList()
        races = race.ToList()

        for reg in regions:
            usPlayer = self.model.playerDB.Find(member.id, reg)
            if usPlayer == None:
                await ctx.send(CodeSB(f'Player {playerName} not registered'))
                return

            if not usPlayer.lastPlayed:
                usPlayer.SetPlayed()

            for r in races:
                usPlayer.elo[r] = elo
            self.model.playerDB.UpdateStats(usPlayer)
        await ctx.send(
            CodeSB(
                f"Updated {playerName}'s elo to {usPlayer.elo[races[0]]} for {', '.join(races)} on {', '.join(regions)}"
            ))
예제 #16
0
    async def on_set_racepref(self,
                              ctx,
                              racePref: Race,
                              region: Region = Region(Region.ALL)):
        if not self.model.ChkIsReg(ctx):
            return

        playerId = ctx.message.author.id
        playerName = ctx.message.author.name

        regions = region.ToList()
        for reg in regions:
            usPlayer = self.model.playerDB.Find(playerId, reg)
            if usPlayer == None:
                await ctx.send(CodeSB(f'Player {playerName} not registered'))

            usPlayer.racePref = racePref
            self.model.playerDB.UpdateStats(usPlayer)

        await ctx.send(
            CodeSB(
                f"{playerName}'s race preference updated to {racePref.race} on {', '.join(regions)}"
            ))
예제 #17
0
    async def pick_timeout(self):
        remQueues = dict()
        for reg, queue in self.queues:
            for id, timeQueued in queue.copy().items():
                timeDelta = (datetime.now() -
                             timeQueued).total_seconds() / 60.0
                if timeDelta > Model.QUEUE_TIMEOUT:
                    self.queues.remove(reg, id)
                    playerName = self.IdToName(id)
                    remQueues.setdefault(playerName, [])
                    remQueues[playerName].append(reg)

        if len(remQueues) != 0:
            description = ""
            for playerName, regSet in remQueues.items():
                description += f"-{playerName} timed out and removed from {', '.join(regSet)}\n"
            #description += f"\n\n{self.QueueStatus()}"
            embed = discord.Embed(colour=discord.Colour.blue(),
                                  description=CodeB(description, "diff"))
            await self.privChannel.send(content=CodeSB(self.QueueStatus()),
                                        embed=embed)
예제 #18
0
    async def ShowTeamPickInfo(self, ctx, game, pingCapts=False):
        playerPool = ', '.join(
            f'{self.IdToName(player.id)}({player.racePref.race})'
            for player in list(game.PoolPlayers))

        zCapt = self.IdToMention(
            game.zergCapt.id
        ) if pingCapts else f"`{self.IdToName(game.zergCapt.id)}`"
        tCapt = self.IdToMention(
            game.terranCapt.id
        ) if pingCapts else f"`{self.IdToName(game.terranCapt.id)}`"
        embed = discord.Embed(colour=discord.Colour.blue())
        embed.add_field(name=f"{self.IdToName(game.playerTurn.id)}'s pick",
                        value=CodeB(f'<Pool> {playerPool}', 'md'))

        zerg = self.IdsToNames(game.zerg.Ids)
        terran = self.IdsToNames(game.terran.Ids)
        embed.add_field(name="Teams",
                        value=CodeB(f"<Zerg> {zerg}\n<Terran> {terran}", 'md'))
        await ctx.channel.send(
            content=CodeSB(f'Picking teams on {game.region}') +
            f' - Captains - <Zerg> {zCapt} | <Terran> {tCapt}',
            embed=embed)
예제 #19
0
    async def AddPlayerQueue(self,
                             ctx,
                             playerName,
                             playerId,
                             region: Region,
                             showStatus=True):
        regions = region.ToList()

        regionsAddedTo = []
        for reg in regions:
            if playerId not in self.queues[reg]:
                if not any((self.games[newReg] != None and self.games[newReg].IsPlaying(playerId) \
                for newReg in Region.REGIONS)):
                    self.queues.add(reg, playerId)
                    regionsAddedTo.append(reg)

                    if self.queues.is_full(reg):
                        if self.games[reg]:
                            #      await ctx.send(CodeSB(f'Game on {reg} already running... waiting until it ends'))
                            return

                        for remReg in [r for r in regions if r != reg]:
                            if playerId in self.queues[remReg]:
                                self.queues.remove(remReg, playerId)
                        if showStatus:
                            await self.ShowAddQueueStatus(
                                ctx, playerName, [reg])
                        await self.StartTeamPick(ctx, reg)
                        return

        if len(regionsAddedTo) == 0:
            await ctx.send(
                CodeSB(f'{playerName} already added to {", ".join(regions)}'))
            return

        if showStatus:
            await self.ShowAddQueueStatus(ctx, playerName, regionsAddedTo)
예제 #20
0
    async def on_sub(self, ctx, memSub: discord.Member,
                     memSubWith: discord.Member):
        if not (self.model.ChkIsRegId(memSub.id)
                and self.model.ChkIsRegId(memSubWith.id)):
            await ctx.send(f'`All subbed players must be registered`')

        choosingId = ctx.message.author.id
        choosingPlayer = ctx.message.author.name

        game = await self.can_pick(ctx, choosingId, choosingPlayer,
                                   memSubWith.id)
        if not game:
            return

        if any(self.model.games[reg]
               and self.model.games[reg].IsPlaying(memSubWith.id)
               for reg in Region.REGIONS):
            await ctx.send(f"`{memSubWith.name} already in game/player pool`")
            return

        if memSubWith.id not in self.model.subs[game.region]:
            await ctx.send(
                CodeSB(
                    f"{memSubWith.name} has not agreed to sub (they can allow themself sub via !sub <region>"
                ))
            return

        #must validate memSubWith.id not in another game already but should already be handled with above check

        pSubWith = self.model.playerDB.Find(memSubWith.id, game.region)
        game.Sub(memSub.id, pSubWith)
        await ctx.send(
            f'`{memSub.name} subbed with {memSubWith.name} on {game.region}`')
        if game.state != State.IN_GAME:
            await self.model.PickPlayer(ctx, game, choosingPlayer,
                                        memSubWith.id, memSubWith.name)
예제 #21
0
파일: Mod.py 프로젝트: CameronClay/zhex-bot
 async def on_force_end(self, ctx, region: Region = Region(Region.ALL)):
     for reg in region.ToList():
         if self.model.games[reg]:
             await self.model.EndMatch(ctx, self.model.games[reg])
             await ctx.send(CodeSB(f"Match Concluded on {reg}"))
예제 #22
0
 async def ShowAddQueueStatus(self, ctx, playerName, regionsAddedTo):
     embed = discord.Embed(description=self.QueueStatus(),
                           colour=discord.Colour.blue())
     await ctx.channel.send(content=CodeSB(
         f'{playerName} added to: {", ".join(regionsAddedTo)}'),
                            embed=embed)