본문 바로가기
프로젝트/디스코드 봇

[Python] #5 디스코드 봇 만들기 - Data Dragon

by 알래스카비버 2022. 3. 27.
반응형

목차

     

    디스코드 봇 만들기의 마지막 글이 2021년 7월에 올라왔었습니다.

    그 사이에 시즌도 바뀌고 새로운 챔피언들도 4명이나 나왔습니다.

    챔피언 수도 많고 새로 업데이트될 때마다 수동으로 바꿔주는 것은 귀찮기 때문에 

    Data Dragon에서 데이터를 가져와보도록 하겠습니다.

    Data Dragon에서도 수동으로 업데이트를 하는 듯해서 패치 후 즉시 업데이트가 되지는 않는다고 합니다.

    https://developer.riotgames.com/docs/lol#data-dragon

     

    Riot Developer Portal

    League of Legends Overview This set of documentation will help you gain a better understanding of how to use the APIs and developer resources related to League of Legends. It is designed to help you begin developing your own tools and products for the Leag

    developer.riotgames.com

     

    수정

    그전에 제가 lol.py를 잘못 생각하고 만든 것 같아서 class로 바꿔주겠습니다.

    더보기
    # lol.py
    
    import random
    
    
    class lol:
        lanes = ['탑', '정글', '미드', '봇', '서포터']
        keystones = ['집중 공격', '치명적 속도', '기민한 발놀림' ...]
        items = ['돌풍', '크라켄 학살자', '불멸의 철갑궁', ...]
        champions = ['가렌', '갈리오', '갱플랭크', '그라가스', '그레이브즈', ...]
    
    
        def __init__(self):
            pass
    
        def getResult(self, text):
            words = text.split()
    
            result = {"라인": '', "룬": '', "아이템": '', '챔피언': ''}
    
            for word in words:
                if word == "라인":
                    index = random.randrange(0, len(self.lanes))
                    result["라인"] = self.lanes[index]
                elif word == "룬":
                    index = random.randrange(0, len(self.keystones))
                    result["룬"] = self.keystones[index]
                elif word == "아이템":
                    index = random.randrange(0, len(self.items))
                    result["아이템"] = self.items[index]
                elif word == "챔피언":
                    index = random.randrange(0, len(self.champions))
                    result["챔피언"] = self.champions[index]
    
            return result

    lol.py 가 바뀌었기 때문에 main.py도 변경하겠습니다.

    lol.py 를 import 할 때를 변경했고

    접두사 부분 밑줄에 _lol 변수를 만들어 할당했습니다.

    random_lol 함수에서 _lol.getResult(text) 로 변경했습니다.

    더보기
    import discord
    from discord.ext import commands
    from lol import lol
    
    bot = commands.Bot(command_prefix='$')  # 접두사가 '$'
    _lol = lol()
    
    
    @bot.event
    async def on_ready():
        print('We have logged in as {0.user}'.format(bot))
    
    
    @bot.command(aliases=['안녕'])
    async def hello(ctx):  # '$hello'라는 메시지를 보냈을 때 @ Hello!를 보내줌
        await ctx.send('{0.author.mention} Hello!'.format(ctx))
    
    
    @bot.command(name='롤')
    async def random_lol(ctx, *, text=''):
        result = _lol.getResult(text)
        embed = discord.Embed(title="결과", color=discord.Color.green())
        for key, value in result.items():
            if value != '':
                embed.add_field(name=key, value=value, inline=True)
        if embed.fields:
            await ctx.send(embed=embed)
        else:
            await ctx.send("잘못된 명령어입니다.")
    
    
    @bot.event
    async def on_command_error(ctx, exception):
        if isinstance(exception, commands.CommandNotFound):
            await ctx.send("잘못된 명령어입니다.")
    
    
    bot.run('ODYxNDMwMjIwNzQ0NDI1NTAz.YOJraQ.AxbPOJucuig4zD_dgdlfgMMXkI0')
    

     

    Versions

    Data Dragon의 버전은 아래 링크에서 볼 수 있습니다.

    https://ddragon.leagueoflegends.com/api/versions.json

    일단 lol.py 맨 위에 requests 를 import 합니다.

    import requests
    

    룬, 아이템, 챔피언을 받아올 것이기 때문에 빈 리스트로 놔두겠습니다.

    그리고 champions 리스트를 선언한 곳 밑에 version 도 선언하겠습니다.

    lanes = ['탑', '정글', '미드', '봇', '서포터']
    keystones = []
    items = []
    champions = []
    version = ''

    init 메서드에서 가장 최신의 Data Dragon 버전을 가져오겠습니다.

    def __init__(self):
        headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Accept': '*/*'}
        # 버전
        self.version = requests.get('https://ddragon.leagueoflegends.com/api/versions.json', headers=headers).json()[0]
        print(version)

    version을 출력해보면 최신의 버전이 나오는 것을 확인할 수 있습니다.

     

    Champions

    버전을 얻어온 것은 최신 버전의 챔피언을 얻어오기 위해서였습니다.

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/champion.json

    에서 모든 챔피언을 가져오겠습니다.

    다른 언어로 가져오고 싶다면 

    https://ddragon.leagueoflegends.com/cdn/languages.json

    을 참고해 url을 수정합니다.

    champions 리스트에 넣어줍니다.

    def __init__(self):
        headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Accept': '*/*'}
        # 버전
        self.version = requests.get('https://ddragon.leagueoflegends.com/api/versions.json', headers=headers).json()[0]
        # 챔피언
        champion_res = requests.get('https://ddragon.leagueoflegends.com/cdn/' + self.version + '/data/ko_KR/champion.json', headers=headers).json()['data']
        for champion in champion_res:
            self.champions.append(champion_res[champion]['name'])
        print(self.champions)

    챔피언 목록이 잘 나옵니다.

     

    Items

    아이템 url 입니다.

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/item.json

    하지만 신화 아이템만 리스트에 넣어야 하는데 아이템이 너무 많습니다.

    신화 아이템은 신화급 지속 효과가 있습니다.

    description rarityMythic 태그가 있어서 'rarityMythic' 이 포함되어 있는 아이템만 리스트에 추가하겠습니다.

    계속 init 메서드 밑에 내용을 추가하겠습니다.

    # 아이템
    item_res = requests.get('https://ddragon.leagueoflegends.com/cdn/' + self.version + '/data/ko_KR/item.json', headers=headers).json()['data']
    for item in item_res:
        if 'rarityMythic' in item_res[item]['description']:
            self.items.append(item_res[item]['name'])
    print(self.items)
    print(len(self.items))

    신화 아이템 목록이 잘 나옵니다.

     

    Runes

    룬 url 입니다.

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/runesReforged.json

    지배, 정밀 등 각 항목에 slots에  첫 번째 runes가 핵심 룬 입니다.

    # 룬
    rune_res = requests.get('https://ddragon.leagueoflegends.com/cdn/' + self.version + '/data/ko_KR/runesReforged.json', headers=headers).json()
    for i in range(len(rune_res)):
        for rune in rune_res[i]['slots'][0]['runes']:
            self.keystones.append(rune['name'])
    print(self.keystones)
    print(len(self.keystones))

     

    Image

    글만 있으니 밋밋합니다. 챔피언 이미지도 추가해보겠습니다.

    http://ddragon.leagueoflegends.com/cdn/12.5.1/img/champion/[챔피언아이디].png

    챔피언 이름에는 Aatrox, Ahri, Akali 등 챔피언의 아이디를 넣습니다.

    위 url 에서 챔피언의 정사각형 이미지를 볼 수 있습니다.

     

    클래스 변수를 선언해준 곳에 images 리스트를 추가합니다.

    lanes = ['탑', '정글', '미드', '봇', '서포터']
    keystones = []
    items = []
    champions = []
    images = []
    version = ''

    init 메서드에서 챔피언 리스트에 챔피언을 추가하는 부분 밑에 이미지를 추가하는 부분도 추가합니다.

    # 챔피언
    champion_res = requests.get('https://ddragon.leagueoflegends.com/cdn/' + self.version + '/data/ko_KR/champion.json', headers=headers).json()['data']
    for champion in champion_res:
        self.champions.append(champion_res[champion]['name'])
        self.images.append(champion_res[champion]['image']['full'])

    getResult 메서드에서 result 에 이미지를 추가합니다.

    result = {'라인': '', "룬": '', '아이템': '', '챔피언': '', '이미지': ''}

    챔피언을 랜덤으로 뽑는 부분 밑에 이미지도 같은 인덱스로 url 을 넣습니다.

    for word in words:
        if word == "라인":
            index = random.randrange(0, len(self.lanes))
            result["라인"] = self.lanes[index]
        elif word == "룬":
            index = random.randrange(0, len(self.keystones))
            result["룬"] = self.keystones[index]
        elif word == "아이템":
            index = random.randrange(0, len(self.items))
            result["아이템"] = self.items[index]
        elif word == "챔피언":
            index = random.randrange(0, len(self.champions))
            result["챔피언"] = self.champions[index]
            result["이미지"] = 'http://ddragon.leagueoflegends.com/cdn/' + self.version + '/img/champion/' + self.images[index]
    

    getResult 메서드 전체입니다.

    def getResult(self, text):
        words = text.split()
    
        result = {'라인': '', "룬": '', '아이템': '', '챔피언': '', '이미지': ''}
    
        for word in words:
            if word == "라인":
                index = random.randrange(0, len(self.lanes))
                result["라인"] = self.lanes[index]
            elif word == "룬":
                index = random.randrange(0, len(self.keystones))
                result["룬"] = self.keystones[index]
            elif word == "아이템":
                index = random.randrange(0, len(self.items))
                result["아이템"] = self.items[index]
            elif word == "챔피언":
                index = random.randrange(0, len(self.champions))
                result["챔피언"] = self.champions[index]
                result["이미지"] = 'http://ddragon.leagueoflegends.com/cdn/' + self.version + '/img/champion/' + self.images[index]
    
        return result

    main.py 에 random_lol 에서 메시지를 전송하기 전에 이미지를 추가합니다.

    그리고 이미지 key 도 추가되었으니 필드를 추가할 때 이미지는 제외하고 필드를 추가해줍니다.

    @bot.command(name='롤')
    async def random_lol(ctx, *, text=''):
        result = _lol.getResult(text)
        embed = discord.Embed(title="결과", color=discord.Color.green())
        for key, value in result.items():
            if value != '' and key != '이미지':
                embed.add_field(name=key, value=value, inline=True)
        if embed.fields:
            embed.set_thumbnail(url=result['이미지'])
            await ctx.send(embed=embed)
        else:
            await ctx.send("잘못된 명령어입니다.")
    

     

    결과

    결과와 함께 챔피언 이미지가 잘 나옵니다.

    명령어에 챔피언이 포함이 안되면 이미지가 없다만

    코드를 잘 바꾸면 아이템이나 룬으로도 이미지를 띄운다거나 설명을 추가할 수도 있겠습니다.

     

    전체 코드

    전체 코드입니다.

    main.py

    더보기
    import discord
    from discord.ext import commands
    from lol import lol
    
    bot = commands.Bot(command_prefix='$')  # 접두사가 '$'
    _lol = lol()
    
    
    @bot.event
    async def on_ready():
        print('We have logged in as {0.user}'.format(bot))
    
    
    @bot.command(aliases=['안녕'])
    async def hello(ctx):  # '$hello'라는 메시지를 보냈을 때 @ Hello!를 보내줌
        await ctx.send('{0.author.mention} Hello!'.format(ctx))
    
    
    @bot.command(name='롤')
    async def random_lol(ctx, *, text=''):
        result = _lol.getResult(text)
        embed = discord.Embed(title="결과", color=discord.Color.green())
        for key, value in result.items():
            if value != '' and key != '이미지':
                embed.add_field(name=key, value=value, inline=True)
        if embed.fields:
            embed.set_thumbnail(url=result['이미지'])
            await ctx.send(embed=embed)
        else:
            await ctx.send("잘못된 명령어입니다.")
    
    
    @bot.event
    async def on_command_error(ctx, exception):
        if isinstance(exception, commands.CommandNotFound):
            await ctx.send("잘못된 명령어입니다.")
    
    
    bot.run('token')	# 본인 토큰

    lol.py

    더보기
    # lol.py
    
    import random
    import requests
    
    
    class lol:
        lanes = ['탑', '정글', '미드', '봇', '서포터']
        keystones = []
        items = []
        champions = []
        images = []
        version = ''
    
        def __init__(self):
            headers = {'Content-Type': 'application/json', 'charset': 'UTF-8', 'Accept': '*/*'}
            # 버전
            self.version = requests.get('https://ddragon.leagueoflegends.com/api/versions.json', headers=headers).json()[0]
            # 챔피언
            champion_res = requests.get('https://ddragon.leagueoflegends.com/cdn/' + self.version + '/data/ko_KR/champion.json', headers=headers).json()['data']
            for champion in champion_res:
                self.champions.append(champion_res[champion]['name'])
                self.images.append(champion_res[champion]['image']['full'])
            # 아이템
            item_res = requests.get('https://ddragon.leagueoflegends.com/cdn/' + self.version + '/data/ko_KR/item.json', headers=headers).json()['data']
            for item in item_res:
                if 'rarityMythic' in item_res[item]['description']:
                    self.items.append(item_res[item]['name'])
            # 룬
            rune_res = requests.get('https://ddragon.leagueoflegends.com/cdn/' + self.version + '/data/ko_KR/runesReforged.json', headers=headers).json()
            for i in range(len(rune_res)):
                for rune in rune_res[i]['slots'][0]['runes']:
                    self.keystones.append(rune['name'])
    
        def getResult(self, text):
            words = text.split()
    
            result = {'라인': '', "룬": '', '아이템': '', '챔피언': '', '이미지': ''}
    
            for word in words:
                if word == "라인":
                    index = random.randrange(0, len(self.lanes))
                    result["라인"] = self.lanes[index]
                elif word == "룬":
                    index = random.randrange(0, len(self.keystones))
                    result["룬"] = self.keystones[index]
                elif word == "아이템":
                    index = random.randrange(0, len(self.items))
                    result["아이템"] = self.items[index]
                elif word == "챔피언":
                    index = random.randrange(0, len(self.champions))
                    result["챔피언"] = self.champions[index]
                    result["이미지"] = 'http://ddragon.leagueoflegends.com/cdn/' + self.version + '/img/champion/' + self.images[index]
    
            return result

     

    참고

    Riot Data Dragon 문서입니다.

    https://developer.riotgames.com/docs/lol#data-dragon

     

    Riot Developer Portal

    League of Legends Overview This set of documentation will help you gain a better understanding of how to use the APIs and developer resources related to League of Legends. It is designed to help you begin developing your own tools and products for the Leag

    developer.riotgames.com

     

    챔피언 정보

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/champion.json

    더 자세한 챔피언 정보 (스킬 등)

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/championFull.json

    특정 챔피언 정보 (챔피언 아이디 ex : Aatrox, Ahri, Akali 등)

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/champion/[챔피언아이디].json

    특정 챔피언 스플래시 아트 (챔피언 이름 뒤 숫자는 스킨 num)

    https://ddragon.leagueoflegends.com/cdn/img/champion/splash/[챔피언아이디]_0.jpg

    아이템 정보

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/item.json

    특정 아이템 이미지 (아이템 번호 ex : 1001-장화, 1004-요정의부적, 6630-선혈포식자)

    http://ddragon.leagueoflegends.com/cdn/12.5.1/img/item/[아이템번호].png

    룬 정보

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/runesReforged.json

    특정 룬 이미지 (icon : 위 룬 정보에 icon / perk-images/Styles/Domination/Electrocute/Electrocute.png-감전)

    https://ddragon.leagueoflegends.com/cdn/img/[icon]

    https://ddragon.leagueoflegends.com/cdn/img/perk-images/Styles/Domination/Electrocute/Electrocute.png

    스펠 정보

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/summoner.json

    특정 스펠 이미지 (스펠 아이디 ex : SummonerBarrier-방어막, SummonerFlash-점멸)

    http://ddragon.leagueoflegends.com/cdn/12.5.1/img/spell/[스펠아이디].png

    맵 정보

    https://ddragon.leagueoflegends.com/cdn/12.5.1/data/ko_KR/map.json

    맵 이미지 (맵 아이디 ex : 11-소환사의협곡, 12-칼바람나락)

    http://ddragon.leagueoflegends.com/cdn/6.8.1/img/map/map[맵아이디].png

     

     

     

    반응형

    댓글