Example #1
0
 async def betting_start_command(self, ctx: commands.Context, *argv):
     if len(argv) != 1 or not argv[0].isdigit():
         await ctx.channel.send('參數錯誤: 請使用`!betitng start 賭局id`')
         return
     game_id = int(argv[0])
     game: GamblingGame = GamblingUtil.get_game(game_id)
     if game == None:
         await ctx.channel.send(
             '參數錯誤: 無法找到id 為:{} 的賭盤。請使用`!betitng list`查詢。'.format(game_id))
         return
     if game.creater_id != ctx.author.id:
         await ctx.channel.send('權限錯誤: 這個賭盤不是你創建的!')
         return
     if game.guild_id != ctx.guild.id:
         await ctx.channel.send('權限錯誤: 這個賭盤不是在這裡創建的,創建的伺服為: {}'.format(
             self.bot.get_guild(game.guild_id).name))
         return
     if game.status != Util.GamblingStatus.init:
         await ctx.channel.send('權限錯誤: 這個賭盤的狀態為: {},無法開始。'.format(
             Util.GamblingStatus(game.status).name))
         return
     embed = GamblingEmbed.get_betting_embed(game)
     msg = await ctx.channel.send(embed=embed)
     await msg.pin()
     GamblingUtil.update_game_status(game, Util.GamblingStatus.ready,
                                     ctx.channel.id, msg.id)
    def test_addGamePoolAmount(self):
        original: GamblingGame = GamblingUtil.create_game(
            123, "new_game", 5, ["hello", "hi"], 123)
        GamblingUtil.add_game_pool_amount(original, 300)
        original = GamblingUtil.get_game(original.id)

        assert original.pool == 300
    def test_updateGameStatus(self):
        game: GamblingGame = GamblingUtil.create_game(123, "new_game", 5,
                                                      ["hello", "hi"], 123)
        GamblingUtil.update_game_status(game, Util.GamblingStatus.ready, 123,
                                        456)
        result_game = GamblingUtil.get_game(game.id)

        assert game == result_game
    def test_getBets(self):
        original: GamblingGame = GamblingUtil.create_game(
            123, "new_game", 5, ["hello", "hi"], 123)
        GamblingUtil.update_game_status(original, Util.GamblingStatus.ready,
                                        123, 456)
        assert GamblingUtil.add_bet(original, 123, 10, 1)

        bets = GamblingUtil.get_bets(original)
        assert len(bets) == 1
Example #5
0
    async def betting_exchange_command(self, ctx: commands.Context, *argv):
        exchange_rate = GamblingUtil.get_token_rate()
        if len(argv) != 1:
            await ctx.channel.send('參數錯誤: 請使用`!betitng exchange 🍗數量`')
            return
        if not argv[0].isdigit():
            await ctx.channel.send('參數錯誤: 🍗數量必須為數字')
            return
        desired_token = int(argv[0])
        if desired_token < 1:
            await ctx.channel.send('參數錯誤: 🍗數量不能低於1')
            return

        member: Member = self.database.get_member(ctx.author.id)
        if member == None:
            member = self.database.add_member(ctx.author.id)

        required_coin = exchange_rate * desired_token
        if member.coin < required_coin:
            await ctx.channel.send(
                f'參數錯誤: 您目前手持硬幣數量不夠 目前 {exchange_rate}硬幣兌換1🍗\n目前您擁有硬幣{member.coin}, 小於交換所需量 {required_coin}'
            )
            return

        self.database.add_coin(member.member_id, -1 * required_coin)
        self.database.add_token(member.member_id, desired_token)
        member: Member = self.database.get_member(ctx.author.id)
        msg = "```兌換完成! 兌換明細如下:\n"
        msg += f"本次兌換匯率: {exchange_rate}\n"
        msg += f"本次兌換消耗硬幣: {required_coin}\n"
        msg += f"本次兌換獲得🍗: {desired_token}根\n"
        msg += f"目前持有硬幣: {member.coin}\n"
        msg += f"目前持有🍗: {member.token}根\n"
        msg += "```"
        await ctx.channel.send(msg)
Example #6
0
 async def refresh_betting_message(self):
     for guild in self.bot.guilds:
         games = GamblingUtil.get_active_games(guild.id)
         game: GamblingGame
         for game in games:
             channel = game.guild_id
             massage = await channel.fetch_message(game.message_id)
             embed = self.get_betting_embed(game)
             await massage.edit(embed=embed)
    def test_gameCreation(self):
        game: GamblingGame = GamblingUtil.create_game(123, "new_game", 5,
                                                      ["hello", "hi"], 123)

        assert game.guild_id == 123
        assert game.name == "new_game"
        assert game.base == 5
        assert game.pool == 0
        assert game.item_list == ["hello", "hi"]
        assert game.creater_id == 123
        assert game.status == Util.GamblingStatus.init
    def test_getActiveGameInChannel(self):
        original: GamblingGame = GamblingUtil.create_game(
            123, "new_game", 5, ["hello", "hi"], 123)
        GamblingUtil.update_game_status(original, Util.GamblingStatus.ready,
                                        123, 456)

        game = GamblingUtil.get_active_game_in_channel(123, 456)
        assert len(game) == 0
        game = GamblingUtil.get_active_game_in_channel(123, 123)
        assert game == [original]

        another = GamblingUtil.create_game(123, "new_game", 5, ["hello", "hi"],
                                           123)
        GamblingUtil.update_game_status(another, Util.GamblingStatus.ready,
                                        123, 456)
        game = GamblingUtil.get_active_game_in_channel(123, 123)
        assert len(game) == 2
    def test_getActiveGameList(self):
        game1: GamblingGame = GamblingUtil.create_game(123, "new_game1", 5,
                                                       ["hello", "hi"], 123)
        game2: GamblingGame = GamblingUtil.create_game(123, "new_game2", 5,
                                                       ["hello", "hi"], 123)
        gameList = GamblingUtil.get_active_games(123)
        assert len(gameList) == 0

        GamblingUtil.update_game_status(game1, Util.GamblingStatus.ready, 123,
                                        321)
        gameList = GamblingUtil.get_active_games(123)
        assert len(gameList) == 1

        GamblingUtil.update_game_status(game2, Util.GamblingStatus.ready, 123,
                                        321)
        gameList = GamblingUtil.get_active_games(123)
        assert len(gameList) == 2
        assert gameList == [game1, game2]
Example #10
0
 async def exchange_token(self, ctx: commands.Command, need_token: int):
     member = MemberUtil.get_or_add_member(ctx.author.id)
     if member is None:
         await ctx.send("沒硬幣還想換雞腿,趕快去店外雜談區聊天賺硬幣!")
     else:
         coinspertoken = GamblingUtil.get_token_rate()
         spend = need_token * coinspertoken
         if member.coin > spend:
             MemberUtil.add_coin(member_id=member.id, amount=-spend)
             MemberUtil.add_token(member_id=member.id, amount=need_token)
             await ctx.send(f"成功兌換{need_token}個雞腿,目前剩下{member.coin}個硬幣")
         else:
             msg = f"兌換失敗!不足{spend - member.coin}個硬幣\n"
             msg += f"目前匯率為 一隻雞腿{coinspertoken}個硬幣"
             await ctx.send(msg)
Example #11
0
 async def betting_lock_command(self, ctx: commands.Context, *argv):
     send_target = None
     if ctx.channel == None:
         send_target = ctx.author
     else:
         send_target = ctx.channel
     if len(argv) != 1 or not argv[0].isdigit():
         await send_target.send('參數錯誤: `!betting lock 賭盤id`')
         return
     game_id = int(argv[0])
     game: GamblingGame = GamblingUtil.get_game(game_id)
     if game == None:
         await send_target.send('參數錯誤: 沒有ID為{}的賭盤'.format(game_id))
         return
     if game.creater_id != ctx.author.id:
         await send_target.send('權限錯誤: 你不是創建這個賭盤的人')
         return
     if game.status != Util.GamblingStatus.ready:
         await send_target.send('權限錯誤: 這個賭盤的狀態為:{}'.format(game.status.name)
                                )
         return
     GamblingUtil.update_game_status(game, Util.GamblingStatus.wait)
     await send_target.send('更新賭盤狀態為: {}'.format(
         Util.GamblingStatus.wait.name))
    def test_tokenRateCorrect(self):
        self.database.add_member(123)  # token: 100, coin: 0, rate: NAN
        assert GamblingUtil.DEFAULT_RATE == GamblingUtil.get_token_rate()

        self.database.add_coin(123, 10)  # token: 100, coin: 10, rate: 0.1
        assert GamblingUtil.DEFAULT_RATE == GamblingUtil.get_token_rate()

        self.database.add_coin(123, 90)  # token: 100, coin: 100, rate: 1
        assert GamblingUtil.get_token_rate() == GamblingUtil.get_token_rate()

        self.database.add_coin(123, 500)  # token: 100, coin: 600, rate: 6
        assert GamblingUtil.get_token_rate() == 6

        self.database.add_member(321)  # token: 200, coin: 600, rate: 3
        assert GamblingUtil.get_token_rate() == GamblingUtil.get_token_rate()

        self.database.add_coin(321, 600)  # token: 200, coin: 1200, rate: 6
        assert GamblingUtil.get_token_rate() == 6
Example #13
0
 async def betting_list_command(self, ctx: commands.Context, *argv):
     guild = ctx.guild
     game_list = GamblingUtil.get_active_games(guild.id)
     if len(game_list) == 0:
         return
     embed = Embed()
     embed.title = '賭盤列表'
     game: GamblingGame
     for game in game_list:
         channel = ctx.channel
         embed.add_field(
             name=game.name,
             value='每注: {}, 獎金池: {}, 狀態: {}\n頻道: <#{}>, 伺服器:{}'.format(
                 game.base, game.pool, game.status.name, channel.id,
                 guild.name),
             inline=False)
     await ctx.channel.send(embed=embed)
    def test_addBetSuccess(self):
        original: GamblingGame = GamblingUtil.create_game(
            123, "new_game", 5, ["hello", "hi"], 123)
        GamblingUtil.update_game_status(original, Util.GamblingStatus.ready,
                                        123, 456)
        assert GamblingUtil.add_bet(original, 123, 10, 1)

        original: GamblingGame = GamblingUtil.get_game(original.id)
        assert original.pool == 10

        assert GamblingUtil.add_bet(original, 123, 10, 1)
        assert original.pool == 20
Example #15
0
 async def betting_exchange_rate_command(self, ctx: commands.Context,
                                         *argv):
     exchange_rate = GamblingUtil.get_token_rate()
     await ctx.channel.send(f"目前🍗兌換率為 {exchange_rate} 硬幣:1隻🍗")
Example #16
0
    async def betting_end_command(self, ctx: commands.Context, *argv):
        if len(argv) != 2:
            await ctx.channel.send('參數錯誤: `!betting lock 勝利編號 賭盤id`')
            return
        if not argv[1].isdigit() or not argv[0].isdigit():
            await ctx.channel.send('參數錯誤: `!betting lock 勝利編號 賭盤id`')
            return
        game_id = int(argv[1])
        option_index = int(argv[0])
        game: GamblingGame = GamblingUtil.get_game(int(argv[1]))
        if not game:
            await ctx.channel.send('參數錯誤: 找不到id 為{}的賭盤'.format(game_id))
            return
        if game.creater_id != ctx.author.id:
            await ctx.channel.send('權限錯誤: 你不是創建這個賭盤的人')
            return
        if game.status != Util.GamblingStatus.wait:
            await ctx.channel.send('權限錯誤: 這個賭盤的狀態為:{}'.format(game.status.name)
                                   )
            return
        betting_items = json.loads(game.item_list)
        if option_index < 0 or option_index > len(betting_items):
            await ctx.channel.send(f'參數錯誤: `勝利編號 {option_index} 為無效編號`')
            return

        #[第一項總注,第n項總注...,總項總注]
        member_charge_sum = [0] * len(betting_items)
        member_bet = {}
        winning_item = betting_items[option_index]
        bets = GamblingUtil.get_bets(game)
        bet: GamblingBet
        for bet in bets:
            member_charge_sum[bet.item_index] += bet.charge
            member_bet[bet.member_id] = member_bet.get(bet.member_id,
                                                       0) + bet.charge

        for member_id in member_bet:
            member: Member = self.database.get_member(member_id)
            if member == None:
                continue
            token_spent = 0
            if member_bet[member_id].get(winning_item, 0) != 0:
                token_spent = member_bet[member_id][winning_item]
            coin_won = 0
            winning_sum = member_charge_sum[option_index]
            if winning_sum != 0:
                coin_won = int(token_spent / winning_sum * game.base *
                               game.pool)
            user = await self.bot.fetch_user(member_id)
            if user == None:
                await ctx.channel.send('無法找到該id的用戶: {},跳過!')
                continue
            self.database.add_token(member_id, coin_won)
            member = self.database.get_member(member_id)
            await user.send('恭喜獲得{}點🍗, ...結餘:{}'.format(coin_won, member.coin))

        GamblingUtil.update_game_status(game,
                                        Util.GamblingStatus.end,
                                        winning_index=option_index)

        channel = await self.bot.fetch_channel(game.channel_id)
        if channel != None:
            msg = await channel.fetch_message(game.message_id)
            await msg.edit(embed=GamblingEmbed.get_betting_embed(
                self.bot, self.database, game))
            if msg.pinned:
                await msg.unpin()
        await ctx.channel.send('結算成功')
Example #17
0
    async def betting_create_command(self, ctx: commands.Context, *argv):

        descript_base = '請<@{}>跟著指示完成創建\n'.format(ctx.author.id)
        embed = Embed()
        embed.title = '創建賭盤: 創建者<@!{}>'.format(ctx.author.id)
        embed.description = descript_base
        embed.add_field(name='設定賭盤名稱', value='請直接回覆賭局名稱', inline=False)
        embed.add_field(name='設定賭注單位', value='請先回覆賭局名稱', inline=False)
        main_message = await ctx.channel.send(embed=embed)

        def reaction_check(reaction, user):
            if user == ctx.author and reaction.message == main_message:
                return str(reaction.emoji) == '⭕' or '❌'
            else:
                return False

        betting_count = 0
        bet_item_offset = 2

        if not await GamblingUtil.create_loop(embed, main_message, ctx,
                                              type(str()), '賭盤名稱', 0):
            return
        embed.set_field_at(1, name='設定賭注單位', value='請直接回覆每注單位', inline=False)
        await main_message.edit(embed=embed)
        if not await GamblingUtil.create_loop(embed, main_message, ctx,
                                              type(int()), '賭注單位', 1):
            return
        add_flag = True
        while add_flag or betting_count < 2:
            embed.add_field(name='設定賭注項目-第{}項'.format(betting_count),
                            value='請先回覆賭注項目-第{}項'.format(betting_count),
                            inline=False)
            await main_message.edit(embed=embed)
            if not await GamblingUtil.create_loop(
                    embed, main_message, ctx, type(
                        str()), '賭品-第{}項'.format(betting_count),
                    betting_count + bet_item_offset):
                return
            if betting_count > 0:
                embed.add_field(name='完成設定?',
                                value='完成設定⭕️繼續設定❌',
                                inline=False)
                await main_message.edit(embed=embed)
                await main_message.add_reaction('⭕')
                await main_message.add_reaction('❌')
                try:
                    get_reaction = await self.bot.wait_for(
                        'reaction_add', timeout=30.0, check=reaction_check)
                except asyncio.TimeoutError:
                    embed.set_field_at(betting_count + bet_item_offset + 1,
                                       name='完成設定?-等待反應超時',
                                       value='error')
                    await main_message.clear_reactions()
                    await main_message.edit(embed=embed)
                    return False
                else:
                    if get_reaction[0].emoji == '⭕':
                        tem_list = []
                        for i in embed.fields[2:-1]:
                            tem_list.append(i.value)
                        game: GamblingGame = GamblingUtil.create_game(
                            ctx.guild.id, embed.fields[0].value,
                            int(embed.fields[1].value), tem_list,
                            ctx.author.id)
                        embed.set_field_at(
                            betting_count + bet_item_offset + 1,
                            name='完成設定!!!',
                            value=
                            '設定完成!!!\n請<@{}> 到想要的頻道輸入\n`!betting start {}`\n開啟賭局!'
                            .format(ctx.author.id, game.id),
                            inline=False)
                        add_flag = False
                    else:
                        embed.remove_field(betting_count + bet_item_offset + 1)
                    await main_message.clear_reactions()
                    await main_message.edit(embed=embed)

            betting_count += 1
Example #18
0
    async def betting_bte_command(self, ctx: commands.Context, *argv):
        guild = ctx.guild
        channel = ctx.channel
        ##
        if channel == None:
            await ctx.author.send('請到開啟賭牌的頻道下注!!')
            return
        if guild == None:
            await ctx.author.send('無法處理的伺服器!')
            return
        if not self.database.has_channel(guild.id, channel.id,
                                         Util.ChannelType.AUTO_DELETE):
            await ctx.message.delete()
        flag = False
        if len(argv) < 2:
            flag = True
        elif not argv[0].isdigit() or not argv[1].isdigit():
            flag = True
        if flag:
            await ctx.author.send('參數錯誤: `!bet 加注數量 下注編號 [賭局ID]`')
            return
        bet_amount = int(argv[0])  # 加注數量
        choice_id = int(argv[1])  # 下注編號

        _bettings = GamblingUtil.get_active_game_in_channel(
            guild.id, ctx.channel.id)
        ready_games = []
        game: GamblingGame
        for game in _bettings:
            if game.status == Util.GamblingStatus.ready:
                ready_games.append(game)
        if len(ready_games) == 0:
            await ctx.author.send('參數錯誤: 這個頻道沒有開啟的賭局!')
            return
        if len(ready_games) > 1:
            if len(argv) <= 2:
                tem_betting_list = ''
                for game in ready_games:
                    tem_betting_list += '\n賭局名:{}, id: {}'.format(
                        game.name, game.id)
                await ctx.author.send('這個頻道有複數賭局開啟中\n請指定賭局`!bet 下注數 賭局ID`' +
                                      tem_betting_list)
                return
            if not argv[2].isdigit():
                await ctx.author.send('參數錯誤: 賭局ID必須是數字')
            betting_id = int(argv[2])
            flag = True
            for game in ready_games:
                if betting_id == game.id:
                    flag = False
                    break
            if flag:
                ctx.author.send('參數錯誤: 這個<#{}>沒有ID為: {}的賭局'.format(
                    ctx.channel.id, betting_id))
            ready_games = game
        elif len(ready_games) == 1:
            ready_games = ready_games[0]
        else:
            await ctx.channel.send('未預期的錯誤: <@!326752816238428164>快修阿!')
            return
        game: GamblingGame = ready_games
        if game.status != Util.GamblingStatus.ready:
            await ctx.author.send('權限錯誤: 現在的賭局狀態為: {}不能下注'.format(
                Util.GamblingStatus(game.status).name))
            return
        if bet_amount < 1:
            await ctx.author.send('參數錯誤: 下注🍗不能為此數: {}'.format(bet_amount))
            return
        # 所有可下注選項
        betting_item_list = json.load(game.item_list)
        if not choice_id < len(betting_item_list):
            await ctx.author.send('參數錯誤: 不存在編號: {}'.format(choice_id))
            return
        member = self.database.get_member(ctx.author.id)
        if member == None:
            member = self.database.add_member(ctx.author.id)
        require_amount = bet_amount * game.base
        if member.coin < require_amount:
            await ctx.author.send('道德錯誤: 你的🍗不夠啦! ...剩餘{},下注{}'.format(
                member.coin, require_amount))
            return
        self.database.add_coin(member, -1 * require_amount)
        GamblingUtil.add_bet(game=game,
                             user_id=member.member_id,
                             amount=require_amount,
                             item_index=choice_id)

        await ctx.author.send('你成功對{} 下注了{}點🍗。...餘額為: {}。'.format(
            betting_item_list[choice_id], require_amount, member.coin))
Example #19
0
    def get_betting_embed(bot: commands.Bot, database: KfpDb,
                          game: GamblingGame):
        guild: Guild = bot.get_guild(game.guild_id)
        if guild == None:
            return Embed(title='錯誤',
                         description='無法處理的伺服id: {}'.format(game.guild_id))
        embed = Embed()
        embed.colour = Color(randint(0, 0xffffff))
        embed.title = game.name
        _description = ''
        if game.status == Util.GamblingStatus.ready:
            _description += '請各位輸入`!bet 下注數 下注編號 {}` 開始下注!。\n'.format(game.id)
        if game.status == Util.GamblingStatus.wait:
            _description += '停止下注!'
        _description += '#目前所有選項的期望賠率都是一樣的,有人有想法可以聯絡<@326752816238428164>\n'
        if game.status == Util.GamblingStatus.ready:
            _description += '<@{}>可以輸入`!betting lock {}`來停止下注。'.format(
                game.creater_id, game.id)
        if game.status == Util.GamblingStatus.wait:
            _description += '<@{}>可以輸入`!betting end 勝利編號 {}`來結算賭盤。'.format(
                game.creater_id, game.id)
        embed.description = _description

        betting_items = json.loads(game.item_list)
        #[第一項總注,第n項總注...,總項總注]
        member_charge_sum = [0] * len(betting_items)
        member_bet = {}
        bets = GamblingUtil.get_bets(game)

        bet: GamblingBet
        for bet in bets:
            member_charge_sum[bet.item_index] += bet.charge
            member_bet[bet.member_id] = member_bet.get(bet.member_id,
                                                       0) + bet.charge

        for i, target_name in enumerate(betting_items):
            if member_charge_sum[i] > 0:
                embed.add_field(name='編號: {} #'.format(i) + target_name,
                                value='賠率: {:.3f}'.format(
                                    float((game.pool / member_charge_sum[i]))),
                                inline=False)
            else:
                embed.add_field(name='編號: {} #'.format(i) + target_name,
                                value='賠率: ?',
                                inline=False)
        embed.add_field(name='賭局id', value=str(game.id))
        embed.add_field(name='獎金池', value=str(game.pool * game.base))
        embed.add_field(name='每注單位', value=str('{}🍗'.format(game.base)))
        embed.add_field(name='刷新速度', value='5s')
        embed.add_field(name='狀態', value=Util.GamblingStatus(game.status).name)
        embed.add_field(name='====我是分隔線====', value='#', inline=False)
        inline_flasg = False
        for member_id in member_bet:
            member = guild.get_member(int(member_id))
            if member == None:
                continue
            value = ''
            for bet_item in member_bet[member_id]:
                if game.status == Util.GamblingStatus.end.value:
                    if bet_item == betting_items[game.winning_index]:
                        value += '{}:得到{}點🍗\n'.format(
                            bet_item, member_bet[member_id][bet_item] /
                            member_charge_sum[game.winning_index] *
                            member_charge_sum[-1] * game.base)
                    else:
                        value += '{}:輸掉{}點🍗拉\n'.format(
                            bet_item,
                            member_bet[member_id][bet_item] * game.base)
                else:
                    value += '{}:{}注\n'.format(bet_item,
                                               member_bet[member_id][bet_item])
            embed.add_field(name=member.display_name,
                            value=value[:-1],
                            inline=inline_flasg)
            if not inline_flasg:
                inline_flasg = True

        return embed
 def test_tokenRateDefault(self):
     assert GamblingUtil.DEFAULT_RATE == GamblingUtil.get_token_rate()
 def test_addBetFailedNotReady(self):
     original: GamblingGame = GamblingUtil.create_game(
         123, "new_game", 5, ["hello", "hi"], 123)
     assert not GamblingUtil.add_bet(original, 123, 2, 1)