티스토리 뷰

개발

오랜만에 올리는 디코 봇 현황

KWG07(joseph0528) 2021. 8. 8. 23:23

3개월 만에 봇을 건드렸는데 3개월 사이에 솔브드 api V2가 이제 지원이 안돼서 모든 코드를 갈아엎어야 되는 상황이 왔는데 블로그 올리는 당일날 v3를 찾아서 그걸로 기존 코드는 그냥 갈아엎고 새로운 코드를 다시 짰다.

2가지 기능이 있는데 첫번째는 어떤 유저가 어떤 티어 이상의 문제를 풀었을 때 자동 알림을 오게 하는 걸 하고 싶었지만 그랬다간 시프트님께 밴 당할 거 같아서 그냥 수동으로 check를 입력했을 때만 업데이트를 하도록 해놨다

만든 이유는 다른 갓분들과 같이 있는 디코 섭에서 그럴만한 일이 있었기 때문이다.

테스트를 위해 데이터를 좀 건들였다

마이너스는 개수가 줄었다는건데 주는 경우는 티어가 올랐거나 내려갔거나 아니면 없어졌거나 여러 가지 이유로 마이너스가 나올 수 있다.

 

두 번 째는 백준의 연습기능인데 그냥 할 게 없어서 만들었다. 백준처럼 시간이랑 틀린 횟수는 솔브드에서 지원을 안 해서 알 수가 없어서 그냥 풀었는가 안 풀었는가로만 판별하게 해 놨다

좀 틀이 안 맞긴 하지만 그건 넘어가고 왠지 모를 버그 때문에 좀 걸렸다 나중에 좀 더 가꿀 예정(이라곤 하지만 안건들 가능성 90%)

이거 말고는 싹 다 창고에 들어가 있다.

봇 가지고 뭔가를 많이 하다 보니 218MB나 썼다 

이번에도 좀 길긴 하지만 최근에 알게 된 거지만 참고하는 사람도 있긴 하기 때문에 코드를 올린다

import discord
from discord.http import Route
import requests
import random
import urllib.request as req
from bs4 import BeautifulSoup
import emoji
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from discord.utils import get
import math
import json
from urllib.error import URLError,HTTPError
import asyncio
tier={"b5":1,"b4":2,"b3":3,"b2":4,"b1":5,\
        "s5":6,"s4":7,"s3":8,"s2":9,"s1":10,\
        "g5":11,"g4":12,"g3":13,"g2":14,"g1":15,\
        "p5":16,"p4":17,"p3":18,"p2":19,"p1":20,\
        "d5":21,"d4":22,"d3":23,"d2":24,"d1":25,\
        "r5":26,"r4":27,"r3":28,"r2":29,"r1":30}
tierst=["b5","b4","b3","b2","b1",\
        "s5","s4","s3","s2","s1",\
        "g5","g4","g3","g2","g1",\
        "p5","p4","p3","p2","p1",\
        "d5","d4","d3","d2","d1",\
        "r5","r4","r3","r2","r1"]
tierimagelink=["<:unranked:828174300338585600>","<:bronze5:828174299247673345>","<:bronze4:828174298963116092>","<:bronze3:828174299269169183>","<:bronze2:828174300301099028>","<:bronze1:828174299239415828>",\
    "<:silver5:828174300502294549>","<:silver4:828174300057698325>","<:silver3:828174301088710716>","<:silver2:828174300329541632>","<:silver1:828174300120088619>",\
    "<:gold5:828174299843788811>","<:gold4:828174299630010398>","<:gold3:828174299944452116>","<:gold2:828174299722547200>","<:gold1:828174299210055711>",\
    "<:platinum5:828174300355493888>","<:platinum4:828174299750858762>","<:platinum3:828174300225077258>","<:platinum2:828174300401369088>","<:platinum1:828174299713765386>",\
    "<:diamond5:828174299419901972>","<:diamond4:828174299264843816>","<:diamond3:828174298950008833>","<:diamond2:828174299222245386>","<:diamond1:828174299298005002>",\
    "<:ruby5:828174300305293422>","<:ruby4:828174299772616715>","<:ruby3:828174300392718346>","<:ruby2:828174299901984768>","<:ruby1:828174300338323506>","<:master:828199362868936724>"]
tiercolor=[0x2d2d2d, 0xad5600, 0x435f7a, 0xec9a00, 0x27e2a4, 0x00b4fc, 0xff0062, 0xFFFFFF]
client=discord.Client()
pt_start=0
pt_list=[]
pt_user=[]
solved_list=[]
scoreboard_pb=""
scoreboard_link=""
pul=0
pll=0
@client.event
async def on_ready():
    #sq=token.f(0)
    #print(sq)
    print("Start {0.user}".format(client))
@client.event
async def on_message(message):
    global pt_start,pt_list,pt_user,solved_list,scoreboard_pb,pul,pll,scoreboard_link
    if message.author==client.user:return

    

    if message.content.startswith("~pt_scoreboard")and pt_start==2:
        await message.channel.send("시간이 걸릴 수 있습니다 잠시만 기다려주세요")
        msgpr=scoreboard_pb
        for i in range(pul):
            yu=len(pt_user[i])
            #print(pt_user[i]+"_"*(13-yu),yu)
            if yu>13:
                msgpr+=pt_user[i][:13]
            else:
                msgpr+=pt_user[i]+"_\\"*(13-yu-1)+"_"
            msgpr+=" "
            ve=1
            for g in range(pll):
                if solved_list[i][g]==0:
                    url='https://solved.ac/api/v3/search/suggestion?query='+pt_list[g]+'%20solved_by%3A'+pt_user[i]
                    res=requests.get(url)
                    soup=str(BeautifulSoup(res.text,'html.parser'))
                    soup=soup.replace("'","\"")
                    jsonData=json.loads(soup)
                    if jsonData["problems"]!=[]:solved_list[i][g]=1
                if solved_list[i][g]==1:
                    msgpr+=":white_check_mark: "
                else:
                    ve=0
                    msgpr+=":x: "
            msgpr+="\n"
        msgpr+="\n\n"
        msgpr+=scoreboard_link
        Embed=discord.Embed(title="scoreboard",description=msgpr,color=tiercolor[5])
        await message.channel.send(embed=Embed)
        if ve==1:
            await message.channel.send("다 푸신분이 생겼으므로 이 연습은 종료 됩니다")
            pt_start=0
            
    
    if message.content.startswith("~pt_start")and pt_start==1 and pul!=0:
        pt_start=2
        scoreboard_pb="user\\problems "
        scoreboard_link=""
        for i in range(pll):
            scoreboard_pb+=":regional_indicator_"+chr(i+97)+": "
            scoreboard_link+=":regional_indicator_"+chr(i+97)+": "+" : "+"https://www.acmicpc.net/problem/"+pt_list[i]+"\n"
        scoreboard_pb+="\n"
        solved_list=[[0 for i in range(pll)]for g in range(pul)]
        await message.channel.send("연습을 시작합니다")

    if message.content.startswith("~pt_attend")and pt_start!=0:
        try:
            ex=message.content[11:].split()
            if ex[0]in pt_user:
                await message.channel.send("이미 추가되어있습니다")
            else:
                url='https://solved.ac/api/v3/user/problem_stats?handle='+ex[0]
                res=requests.get(url)
                soup=str(BeautifulSoup(res.text,'html.parser'))
                soup=soup.replace("'","\"")
                jsonData=json.loads(soup)
                pt_user.append(ex[0])
                pul+=1
                if pt_start==2:
                    solved_list.append([0 for i in range(pll)])
                await message.channel.send("추가되었습니다")
        except:
            await message.channel.send("제대로 입력해주세요")
    
    if message.content.startswith("~pt_produce"):
        if pt_start!=0:await message.channel.send("이미 진행 중인 연습이 있습니다");return
        pt_start=1
        pt_list=[]
        pt_user=[]
        pul=0
        pll=0
        mg="새로운 연습을 시작합니다 연습에 추가할 문제를 입력해주세요\n추가 :  ~put 문제번호\n삭제 :  ~delete 문제번호\n참가 :  ~pt_attend 닉네임\n"
        mg+="스코어보드 :  ~pt_scoreboard\n연습은 스코어보드로 푼 문제 업뎃시 다 푼유저가 생기면 자동으로 종료됩니다.\n다 추가하셨으면 ~pt_start를 쳐서 시작해주세요"
        Embed=discord.Embed(title="pratice",description=mg,color=tiercolor[5])
        await message.channel.send(embed=Embed)
        
    if message.content.startswith("~put")and pt_start==1:
        try:
            ex=message.content[5:].split()
            url='https://solved.ac/api/v3/problem/show?problemId='+ex[0]
            res=requests.get(url)
            soup=str(BeautifulSoup(res.text,'html.parser'))
            soup=soup.replace("'","\"")
            jsonData=json.loads(soup)
            if not ex[0] in pt_list:
                if pll<26:
                    pt_list.append(ex[0])
                    pll+=1
                    await message.channel.send("추가되었습니다")
                else:
                    await message.channel.send("추가할 수 있는 문제수가 꽉찼습니다")
            else:
                await message.channel.send("이미 추가된 문제입니다")
        except:
            await message.channel.send("제대로 입력해주세요")

    if message.content.startswith("~delete")and pt_start==1:
        ex=message.content[8:].split()
        if ex[0]in pt_list:
            pt_list.pop(pt_list.index(ex[0]))
            pll-=1
            await message.channel.send("삭제 되었습니다")
        else:
            await message.channel.send("추가되지 않은 문제입니다")

    if message.content.startswith("pt"):await message.channel.send(":white_check_mark:")
    
    if message.content.startswith("~change"):
        try:
            ex=message.content[8:].split()
            check_tier=open("check_tier.txt","r")
            lines=check_tier.readlines()
            check_tier.close()
            msg=""
            ln=len(lines)
            for i in range(ln):
                ct=lines[i].split('/')
                if len(ct)<3:continue
                if ct[0]==ex[0]:
                    ntmsg=""
                    for g in range(i+1,ln):
                        ntmsg+=lines[g]
                        if g!=ln-1:ntmsg+="\n"
                    url='https://solved.ac/api/v3/user/problem_stats?handle='+ex[0]
                    res=requests.get(url)
                    soup=str(BeautifulSoup(res.text,'html.parser'))
                    soup=soup.replace("'","\"")
                    jsonData=json.loads(soup)
                    tsg=""
                    for g in range(tier[ex[1].lower()],31):
                        tsg+=str(jsonData[g]["solved"])+"/"
                    #print(ex)
                    #print(msg+ex[0]+'/'+str(tier[ex[1].lower()])+'/'+str(jsonData[tier[ex[1].lower()]]["solved"])+"\n"+ntmsg)
                    check_tier=open("check_tier.txt","w")
                    if ntmsg!="":
                        print(msg+ex[0]+'/'+str(tier[ex[1].lower()])+'/'+tsg+"\n"+ntmsg,file=check_tier)
                    else:
                        print(msg+ex[0]+'/'+str(tier[ex[1].lower()])+'/'+tsg,file=check_tier)
                    check_tier.close()
                    await message.channel.send("변경이 완료되었습니다")
                    return
                msg+=lines[i]+"\n"
            await message.channel.send("해당하는 닉을 가진 유저가 없습니다")
        except:
            await message.channel.send("제대로 입력해주세요")
    if message.content.startswith("~add"):
        try:
            ex=message.content[5:].split()
            check_tier=open("check_tier.txt","r")
            lines=check_tier.readlines()
            check_tier.close()
            for i in range(len(lines)):
                ct=lines[i].split('/')
                if len(ct)<3:continue
                if ct[0]==ex[0]:
                    await message.channel.send("이미 등록되어있습니다")
                    return
            url='https://solved.ac/api/v3/user/problem_stats?handle='+ex[0]
            res=requests.get(url)
            soup=str(BeautifulSoup(res.text,'html.parser'))
            soup=soup.replace("'","\"")
            jsonData=json.loads(soup)
            check_tier=open("check_tier.txt","a")
            tsg=ex[0]+'/'+str(tier[ex[1].lower()])+'/'
            for i in range(tier[ex[1].lower()],31):
                tsg+=str(jsonData[i]["solved"])+"/"
            print(tsg,file=check_tier)
            await message.channel.send("추가되었습니다")
            check_tier.close()
        except:
            await message.channel.send("제대로 입력해주세요")
    if message.content.startswith("~check"):
        try:
            ex=message.content[7:].split()
            check_tier=open("check_tier.txt","r")
            lines=check_tier.readlines()
            check_tier.close()
            for i in range(len(lines)):
                ct=lines[i].split('/')
                if len(ct)<3:continue
                if ct[0]==ex[0]:
                    url='https://solved.ac/api/v3/user/problem_stats?handle='+ex[0]
                    res=requests.get(url)
                    soup=str(BeautifulSoup(res.text,'html.parser'))
                    soup=soup.replace("'","\"")
                    jsonData=json.loads(soup)
                    cnt=[0]*33
                    for g in range(int(ct[1]),31):
                        if jsonData[g]["solved"]!=int(ct[g-int(ct[1])+2]):
                            cnt[g]=jsonData[g]["solved"]-int(ct[g-int(ct[1])+2])
                    scnt=sum(cnt)
                    if scnt!=0:
                        tsg="총 "+str(scnt)+"개의 "+tierst[int(ct[1])-1]+'보다 같거나 높은 티어 문제를 풀었습니다\n'
                        for i in range(1,31):
                            if cnt[i]!=0:tsg+=tierimagelink[i]+" : "+str(cnt[i])+"개\n"
                        
                        Embed=discord.Embed(description=tsg,color=tiercolor[(int(ct[1])-1)//5+1])
                        await message.channel.send(embed=Embed)
                        return
                    await message.channel.send("변동사항없습니다")
                    return
            await message.channel.send("해당하는 닉을 가진 유저가 없습니다")
        except:
            await message.channel.send('제대로 입력해주세요')

'개발' 카테고리의 다른 글

스와이프 벽돌깨기 게임 제작  (0) 2021.09.15
개발일지 1. 디스코드 봇 Solved_Coin 제작  (2) 2021.09.03
디스코드 봇 업데이트  (0) 2021.05.15
2048게임 제작  (5) 2021.02.28
디스코드 봇 업데이트  (0) 2021.02.08
댓글