Commit c80edfcc authored by Geovanny's avatar Geovanny

Added discord bot with getall and and get unit info commands

parent c635527c
DISCORD_TOKEN=NTM0MDcwMDMxNzQ3Nzc2NTM0.XpOg7g.xeXbsvAgWiR4L_r8ZFYgLIJSaMs
API_URL_BASE=http://localhost:3000
CRYPT_SALT=SlTKeYOpHygTYkP3
CRYPT_KEY=ConqBlad3keY
ENC_DEC_MEDTHOD=utf-8
\ No newline at end of file
import asyncio
import discord
from discord.ext import commands
from unit.manager import UnitManager
from settings import DISCORD_TOKEN
loop = asyncio.get_event_loop()
bot = commands.Bot(command_prefix='>')
bot.add_cog(UnitManager(bot))
@bot.event
async def on_ready():
print('It is on')
print('I am running on ' + bot.user.name)
print('With the ID: ' + str(bot.user.id))
bot.run(DISCORD_TOKEN)
\ No newline at end of file
discord.py
python-dotenv
requests
pycryptodome
\ No newline at end of file
import os
from dotenv import load_dotenv
load_dotenv()
DISCORD_TOKEN = os.getenv('DISCORD_TOKEN')
API_URL_BASE = os.getenv('API_URL_BASE')
CRYPT_SALT = os.getenv('CRYPT_SALT')
CRYPT_KEY = os.getenv('CRYPT_KEY')
ENC_DEC_MEDTHOD = os.getenv('ENC_DEC_MEDTHOD')
\ No newline at end of file
from util.api_requests import Api
import asyncio
import discord
import json
from discord.ext import commands
from discord.user import User
from unit.model import Unit
class UnitManager(commands.Cog):
def __init__(self, bot, loop=None):
self.bot = bot
self.loop = loop or asyncio.get_event_loop()
@commands.command()
async def unitinfo(self, ctx, *, unit:str):
"""Get info from unit"""
data = None
try:
unit_id = int(unit)
data = await Api.get('/unit/id/{0}'.format(unit_id))
except ValueError:
data = await Api.get('/unit/name/{0}'.format(unit))
if data==None:
return await ctx.send('No unit found for: ' + unit)
unit_data = Unit(**data)
embed = discord.Embed();
embed.title = unit_data.name
embed.set_image(url=unit_data.vet_img)
embed.set_thumbnail(url=unit_data.img)
embed.add_field(name='ID', value=unit_data.id, inline=True)
embed.add_field(name='Name', value=unit_data.name)
embed.add_field(name='Type', value=unit_data.type, inline=True)
embed.add_field(name='Stars', value=(unit_data.stars/2))
embed.add_field(name='Speed', value=unit_data.speed, inline=True)
embed.add_field(name='Range', value=unit_data.range)
embed.add_field(name='Ammo', value=unit)
embed.add_field(name='Leadership Cost', value=unit_data.leadership)
embed.add_field(name='Troop Count', value=unit_data.troop_count, inline=True)
embed.add_field(name='Piercing AP', value=unit_data.pap, inline=True)
embed.add_field(name='Piercing Dg', value=unit_data.pd, inline=True)
embed.add_field(name='Piercing Df', value=unit_data.pdf, inline=True)
embed.add_field(name='Slasing AP', value=unit_data.sap, inline=True)
embed.add_field(name='Slasing Dg', value=unit_data.sd, inline=True)
embed.add_field(name='Slasing Df', value=unit_data.sdf, inline=True)
embed.add_field(name='Blunt AP', value=unit_data.bap, inline=True)
embed.add_field(name='Blunt Dg', value=unit_data.bd, inline=True)
embed.add_field(name='Blunt Df', value=unit_data.bdf, inline=True)
embed.add_field(name='Labour', value=unit_data.labour, inline=True)
await ctx.send(embed=embed)
@commands.command()
async def allunits(self, ctx):
"""Gets all units"""
data = await Api.get('/unit/all')
if data == None:
return await ctx.send('No units found')
units_data = []
for item in data['units']:
units_data.append(Unit(**item))
await self.createUnitTable(ctx, units_data)
async def createUnitTable(self, ctx, data):
max_rows = 5
max_pages = len(data) // max_rows
rem = len(data) % max_rows
cur_page = 0;
first_run = True
if rem!=0:
max_pages+=1
while True:
if first_run:
embed = self.createUnitPage(data, max_rows*cur_page, max_rows*cur_page + max_rows)
first_run = False
msg = await ctx.send(embed=embed)
reactmoji = []
if max_pages == 1 and cur_page == 0:
pass
elif cur_page == 0:
reactmoji.append('⏩')
elif cur_page == max_pages-1:
reactmoji.append('⏪')
elif cur_page > 0 and cur_page < max_pages-1:
reactmoji.extend(['⏪', '⏩'])
for react in reactmoji:
await msg.add_reaction(react)
def check_react(reaction, user):
if reaction.message.id != msg.id:
return False
if user != ctx.message.author:
return False
if str(reaction.emoji) not in reactmoji:
return False
return True
try:
res, user = await self.bot.wait_for('reaction_add', timeout=30.0, check=check_react)
except asyncio.TimeoutError:
return await msg.clear_reactions()
if '⏪' in str(res.emoji):
cur_page-= 1
embed = self.createUnitPage(data, max_rows*cur_page, max_rows*cur_page + max_rows)
await msg.clear_reactions()
await msg.edit(embed=embed)
if '⏩' in str(res.emoji):
cur_page+= 1
embed = self.createUnitPage(data, max_rows*cur_page, max_rows*cur_page + max_rows)
await msg.clear_reactions()
await msg.edit(embed=embed)
def createUnitPage(self, data, minI, maxI):
embed = discord.Embed(color=0x19212d)
embed.set_author(name='TestBot')
units_str = '';
for i in range(minI, maxI):
if i < len(data):
units_str+= str(data[i]) + '\n'
embed.add_field(name='id\t| name\t| type\t| stars', value=units_str)
return embed
class Unit(object):
def __init__(self, id, name, type, stars=0, hp=0, pap=0, pd=0, sap=0, sd=0, bap=0, bd=0, pdf=0, sdf=0, bdf=0, leadership=0, troop_count=0, hero_level=0, speed=0, range=0, ammo=0, labour=0,
img=None,
vet_img=None):
self.id = id
self.name = name
self.type = type
self.stars = stars
self.hp = hp
self.pap = pap
self.pd = pd
self.sap = sap
self.sd = sd
self.bap = bap
self.bd = bd
self.pdf = pdf
self.sdf = sdf
self.bdf = bdf
self.leadership = leadership
self.troop_count = troop_count
self.hero_level = hero_level
self.speed = speed
self.range = range
self.ammo = ammo
self.labour = labour
self.img = img
if img == None:
self.img = 'https://www.conquerorsblade.com/static/img/Conqueror.cd5398b.png'
self.vet_img = vet_img
if vet_img == None:
self.vet_img = 'https://www.conquerorsblade.com/static/img/Conqueror.cd5398b.png'
@classmethod
def from_dict(cls, **data):
return cls(**data)
def to_dict(self):
return {
'uid': self.id
}
def __str__(self):
return '[{0}] {1}\t| {2}\t| {3}'.format(self.id, self.name, self.type, self.stars)
\ No newline at end of file
import json
import requests
from util.crypto import Crypto
from settings import API_URL_BASE
class Api:
@staticmethod
async def get(url, cookies=None):
req_url = API_URL_BASE + url
response = requests.get(req_url, cookies=cookies)
return Api.status_code_handling(response)
@staticmethod
async def post(url, data, cookies=None):
req_url = API_URL_BASE + url
response = requests.get(req_url, json=data, cookies=cookies)
return Api.status_code_handling(response)
@staticmethod
async def getWithUser(url, uid):
enc_id = Crypto.encrypt(str(uid))
cookies = {'discord_id': enc_id}
print('ENC: ' + enc_id)
return await Api.get(url, cookies)
@staticmethod
async def postWithUser(url, data, uid):
enc_id = Crypto.encrypt(str(uid))
cookies = {'discord_id': enc_id}
print('ENC: ' + enc_id)
return await Api.get(url, data, cookies)
@staticmethod
def status_code_handling(response):
if response.status_code >= 500:
print('[!] [{0}] Server Error'.format(response.status_code))
return None
elif response.status_code == 404:
print('[!] [{0}] URL not found'.format(response.status_code))
return None
elif response.status_code == 401:
print('[!] [{0}] Authentication Failed'.format(response.status_code))
return None
elif response.status_code >= 400:
print('[!] [{0}] Bad Request'.format(response.status_code))
print(response.content )
return None
elif response.status_code >= 300:
print('[!] [{0}] Unexpected redirect.'.format(response.status_code))
return None
elif response.status_code == 200:
return json.loads(response.content.decode('utf-8'))
else:
print('[?] Unexpected Error: [HTTP {0}]: Content: {1}'.format(response.status_code, response.content))
return None
\ No newline at end of file
import os
from Crypto.Cipher import AES
from base64 import b64encode, b64decode
from settings import CRYPT_SALT
from settings import CRYPT_KEY
from settings import ENC_DEC_MEDTHOD
class Crypto:
@staticmethod
def encrypt(str_to_enc):
try:
aes_obj = AES.new(CRYPT_KEY, AES.MODE_CFB, CRYPT_SALT)
hx_enc = aes_obj.encrypt(str_to_enc.encode('utf8'))
mret = b64encode(hx_enc).decode(ENC_DEC_MEDTHOD)
return mret
except ValueError as value_error:
if value_error.args[0] == 'IV must be 16 bytes long':
raise ValueError('Encryption Error: SALT must be 16 characters long')
elif value_error.args[0] == 'AES key must be either 16, 24, or 32 bytes long':
raise ValueError('Encryption Error: Encryption key must be either 16, 24, or 32 characters long')
else:
raise ValueError(value_error)
@staticmethod
def decrypt(enc_str):
try:
aes_obj = AES.new(CRYPT_KEY.encode('utf8'), AES.MODE_CFB, CRYPT_SALT)
str_tmp = b64decode(enc_str.encode(ENC_DEC_MEDTHOD))
str_dec = aes_obj.decrypt(str_tmp)
mret = str_dec.decode(ENC_DEC_MEDTHOD)
return mret
except ValueError as value_error:
if value_error.args[0] == 'IV must be 16 bytes long':
raise ValueError('Decryption Error: SALT must be 16 characters long')
elif value_error.args[0] == 'AES key must be either 16, 24, or 32 bytes long':
raise ValueError('Decryption Error: Encryption key must be either 16, 24, or 32 characters long')
else:
raise ValueError(value_error)
\ No newline at end of file
...@@ -8,7 +8,7 @@ const unitsRouter = require('./routes/units'); ...@@ -8,7 +8,7 @@ const unitsRouter = require('./routes/units');
const app = new Koa(); const app = new Koa();
app.use(bodyParser()); app.use(bodyParser());
app.use(auth()); //app.use(auth());
app.use(unitsRouter.routes()).use(unitsRouter.allowedMethods()); app.use(unitsRouter.routes()).use(unitsRouter.allowedMethods());
......
...@@ -8,7 +8,7 @@ const unit_columns = ['name', 'type', 'stars', 'hp', 'pap', 'pd', 'sap', 'sd', ' ...@@ -8,7 +8,7 @@ const unit_columns = ['name', 'type', 'stars', 'hp', 'pap', 'pd', 'sap', 'sd', '
units.getAll = async (context, next) =>{ units.getAll = async (context, next) =>{
let sql_text = 'SELECT * FROM units'; let sql_text = 'SELECT * FROM units ORDER BY name ASC';
try{ try{
let data = await db.con.query(sql_text); let data = await db.con.query(sql_text);
context.response.body = {units: data}; context.response.body = {units: data};
...@@ -17,17 +17,27 @@ units.getAll = async (context, next) =>{ ...@@ -17,17 +17,27 @@ units.getAll = async (context, next) =>{
context.throw(400, 'INVALID_DATA'); context.throw(400, 'INVALID_DATA');
} }
} }
units.getUnit = async (context, next) =>{ units.getUnitById = async (context, next) =>{
let sql_text = `SELECT * FROM units WHERE id=${context.params.id}`; let sql_text = `SELECT * FROM units WHERE id=${context.params.id}`;
try{ try{
let data = await db.con.query(sql_text); let data = await db.con.query(sql_text);
context.response.body = {unit: data}; context.response.body = data[0];
}catch(error){ }catch(error){
console.log(error); console.log(error);
context.throw(400, 'INVALID_DATA'); context.throw(400, 'INVALID_DATA');
} }
} }
units.getUnitByName = async (context, next) =>{
let sql_text = `SELECT * FROM units WHERE name LIKE '%${context.params.name}%'`;
try{
let data = await db.con.query(sql_text);
context.response.body = data[0];
}catch(error){
console.log(error);
context.throw(400, 'INVALID_DATA');
}
}
units.insertUnit = async (context, next) =>{ units.insertUnit = async (context, next) =>{
let body = context.request.body; let body = context.request.body;
......
...@@ -7,7 +7,9 @@ const router = new Router(); ...@@ -7,7 +7,9 @@ const router = new Router();
const unitsModel = require('../models/units'); const unitsModel = require('../models/units');
router.get('/unit/all', unitsModel.getAll); router.get('/unit/all', unitsModel.getAll);
router.get('/unit/:id', unitsModel.getUnit); router.get('/unit/id/:id', unitsModel.getUnitById);
router.get('/unit/name/:name', unitsModel.getUnitByName);
router.post('/unit/insert', unitsModel.insertUnit); router.post('/unit/insert', unitsModel.insertUnit);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment