Skip to content

Instantly share code, notes, and snippets.

@Maverun
Last active September 8, 2018 10:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Maverun/5ea5871cf46a82ebb2ed87fef2daa090 to your computer and use it in GitHub Desktop.
Save Maverun/5ea5871cf46a82ebb2ed87fef2daa090 to your computer and use it in GitHub Desktop.
folder structure
from discord.ext import commands
from cogs.utils import utils
import traceback
import datetime
import storage
import asyncio
import glob
description = '''Grepolis's Command List. '''
bot = commands.Bot(command_prefix=commands.when_mentioned_or("$"), description=description,help_attrs=dict(pm_help=False,hidden=True))
bot.db= storage.Redis()
# utils.redis_connection()
print("Starting Grepolis")
def get_bot_uptime(): # to calculates how long it been up
now = datetime.datetime.utcnow()
delta = now - bot.uptime
hours, remainder = divmod(int(delta.total_seconds()), 3600)
minutes, seconds = divmod(remainder, 60)
days, hours = divmod(hours, 24)
if days:
fmt = '{d} days, {h} hours, {m} minutes, and {s} seconds'
else:
fmt = '{h} hours, {m} minutes, and {s} seconds'
return fmt.format(d=days, h=hours, m=minutes, s=seconds)
@bot.command(hidden=True)
async def uptime(ctx): # Showing Time that bot been total run
"""Tells you how long the bot has been up for."""
await ctx.send(content = "```py\nI have been up for {}\n```".format(get_bot_uptime()))
@bot.event
async def on_ready():
print('Logged in')
print(bot.user.id)
print(bot.user.name)
print(len(bot.guilds))
print('------')
if not hasattr(bot, 'uptime'):
bot.uptime = datetime.datetime.utcnow()
bot.owner = (await bot.application_info()).owner
bot.background = {}
bot.conquest = False
load_cogs()
def load_cogs():
cogs = list_cogs()
for cogs in cogs:
try:
bot.load_extension(cogs)
print ("Load {}".format(cogs))
except Exception as e:
utils.prRed(cogs)
utils.prRed(e)
raise
def list_cogs():
cogs = glob.glob("cogs/*.py")
clean = []
for c in cogs:
c = c.replace("/", "\\") # Linux fix
if "__init__" in c:
continue
clean.append("cogs." + c.split("\\")[1].replace(".py", ""))
return clean
# Load/Unload/Reload cogs
@bot.command(hidden=True)
@commands.check(utils.is_owner)
async def load(ctx,*, module: str):
"""Loads a module
Example: load cogs.mod"""
module = "cogs." + module.strip()
if not module in list_cogs():
await ctx.send(content = "{} doesn't exist.".format(module))
return
try:
bot.load_extension(module)
except Exception as e:
await ctx.send(content = '{}: {}'.format(type(e).__name__, e))
raise
else:
await ctx.send(content = "Enabled.".format(module))
@bot.command(hidden=True)
@commands.check(utils.is_owner)
async def unload(ctx,*, module: str):
"""Unloads a module
Example: unload cogs.mod"""
module = "cogs." + module.strip()
if not module in list_cogs():
await ctx.send(content = "That module doesn't exist.")
return
try:
bot.unload_extension(module)
except Exception as e:
await ctx.send(content = '{}: {}'.format(type(e).__name__, e))
else:
await ctx.send(content = "Module disabled.")
@bot.command(name="reload", hidden=True)
@commands.check(utils.is_owner)
async def _reload(ctx,*, module: str):
"""Reloads a module
Example: reload cogs.mod"""
module = "cogs." + module.strip()
if not module in list_cogs():
await ctx.send(content = "This module doesn't exist.".format(module))
return
try:
bot.unload_extension(module)
bot.load_extension(module)
except Exception as e:
await ctx.send(content = '\U0001f52b')
await ctx.send(content = '{}: {}'.format(type(e).__name__, e))
raise
else:
await ctx.send(content = "Module reloaded.")
async def update_check(self):
data = self.bot.background
now = datetime.datetime.now()
info = []
failed = []
failed_boolean = False
for x in data:
c = now - data[x]
time = divmod(c.days * 86400 + c.seconds, 60)
minutes = time[0]
second = time[1]
if minutes >= 1:
if x in bot.cogs:
failed.append("-{}: {} min, {} second".format(x, minutes, second))
bot.unload_extension("cogs.{}".format(x))
await asyncio.sleep(3)
bot.load_extension("cogs.{}".format(x))
failed_boolean = True
else:
info.append("+{}: {} min, {} second".format(x, minutes, second))
if failed_boolean:
user = self.bot.owner
msg = "Background task of cogs have failed!\n"
msg += "```diff\n{}\n\n{}\n```".format("\n".join(failed), "\n".join(info))
await user.send(msg)
else:
self.update_info = "\n".join(info)
@bot.event
async def on_error(event,*args,**kwargs):
Current_Time = datetime.datetime.utcnow().strftime("%b/%d/%Y %H:%M:%S UTC")
utils.prRed(Current_Time)
utils.prRed("Error!")
utils.prRed(traceback.format_exc())
error = '```py\n{}\n```'.format(traceback.format_exc())
await bot.owner.send(content = "```py\n{}```".format(Current_Time + "\n"+ "ERROR!") + "\n" + error)
if __name__ == '__main__':
bot.run("TOKEN HERE REQUIRE.")
from discord.ext import commands
from grepolis import grepolis
from .utils import utils
import datetime
import asyncio
import time
import json
class Cache():
def __init__(self,bot):
self.bot = bot
self.redis = bot.db.redis
self.bot.grep_cache = {}
self.cache_loop = asyncio.get_event_loop().create_task(self.cache())
def __unload(self):
self.cache_loop.cancel()
utils.prPurple("Closing loops of Caches")
async def cache(self):
while True:
temp = []
for guild in list(self.bot.guilds):
print(guild)
world = await self.redis.get("{}:World".format(guild.id))
print(world)
if world in temp or world is None: #since we dont wanna repeat again during that moment
print(world," already taken or is None")
continue
grep =grepolis.Grepolis(world)
await grep.get_conquest(int(await self.redis.get("time")))
self.bot.grep_cache[world] = grep
# await self.bp_track(guild,grep) #storing gain bp
utils.prCyan("Done cache {}".format(world))
temp.append(world)
self.bot.background.update({"cache":datetime.datetime.now()})
await asyncio.sleep(600)
# async def bp_track(self,guild,grep):
# print(guild)
# utils.prPurple("under BPTRACK")
# data = {"alliance":{},"player":{}}
# [data["alliance"].update({key:{"obp":value.obp,"abp":value.abp,"dbp":value.dbp,"city":value.points}}) for key,value in grep.alliance.items()]
# [data["player"].update({key:{"obp":value.obp,"abp":value.abp,"dbp":value.dbp,"city":value.points}}) for key,value in grep.player.items()]
# for x in ("12","24","168"): #hours
# key = "{}:{}".format(guild.id,x)
# exist = await self.redis.exists(key)
# print(exist)
# if exist:
# utils.prPurple("Already Exists!")
# continue
# else:
# await self.redis.set(key,json.dumps(data),expire = int(x)*3600)
# utils.prPurple("Done")
async def bp_track(self,guild,grep):
time = datetime.datetime.utcnow()
print(time)
if time.weekday() != 0:
return utils.prPurple(time)
if time.hour != 0:
return utils.prPurple(time)
if await self.redis.get("{}:weekly_bp_cooldown".format(guild.id)) is not None:
return utils.prPurple("Still undercooldown")
await self.redis.set("{}:weekly_bp_cooldown".format(guild.id),"cooldown",expire = 3600)
data = {"alliance":{},"player":{}}
[data["alliance"].update({key:{"obp":value.obp,"abp":value.abp,"dbp":value.dbp,"city":value.points}}) for key,value in grep.alliance.items()]
[data["player"].update({key:{"obp":value.obp,"abp":value.abp,"dbp":value.dbp,"city":value.points}}) for key,value in grep.player.items()]
data["time"] = int(time.timestamp())
utils.prPurple("Update weekly bp")
await self.redis.lpush("{}:weekly_bp".format(guild.id),json.dumps(data))
@commands.command(pass_context=True,hidden = True)
async def refresh(self,ctx):
world = await self.redis.get("{}:World".format(ctx.message.guild.id))
self.bot.grep_cache[world] = await grepolis.Grepolis(world).get_conquest(await self.redis.get("time"))
await ctx.send(content = "Refreshed")
def setup(bot):
bot.add_cog(Cache(bot))
from discord.ext import commands
from grepolis import grepolis
from .utils import utils
import datetime
import discord
import inspect
class Setting():
def __init__(self,bot):
self.bot = bot
self.redis = bot.db.redis
@commands.command(brief = "Setting up world for auto print.",pass_context = True)
@commands.check(utils.is_owner)
async def setup(self,ctx,world):
print(world)
await self.redis.set("{}:World".format(ctx.message.guild.id),world)
await self.redis.set("{}:Channel".format(ctx.message.guild.id),ctx.message.channel.id)
print(ctx.message.channel.id)
if world not in self.bot.grep_cache:
self.bot.grep_cache[world] = await grepolis.Grepolis(world).get_conquest(int(await self.redis.get("time")))
await ctx.send(content = "{} setup for this channel.".format(world))
@commands.group(brief = "Track alliance, color provides",pass_context = True,invoke_without_command=True)
async def add(self,ctx,alliance,color:discord.Color = None):
print("ok")
print(color)
if color is None:
color = "000000"
else:
color = color.value
info = await self.redis.get("{}:World".format(ctx.message.guild.id))
if info is None:
return await ctx.send(content = "You haven't added any world yet!")
print("getting world")
grep = self.bot.grep_cache[info]
data = await self.bot.cogs["Stats"].search_query(ctx,await grep.get_alliance(alliance),alliance = True)
if data is None:
return
print(data)
await self.redis.hset("{0.guild.id}:Alliances".format(ctx.message),data.id,color)
await ctx.send(content = "Added {} success.".format(data.name))
@add.command(brief = "Tracking player instead of alliance",pass_context = True, invoke_without_command=True)
async def player(self,ctx,*,name):
info = await self.redis.get("{}:World".format(ctx.message.guild.id))
if info is None:
return await ctx.send(content = "You haven't added any world yet!")
print("getting world")
grep = self.bot.grep_cache[info]
data = await self.bot.cogs["Stats"].search_query(ctx,await grep.get_player(name))
if data is None:
return
await self.redis.sadd("{}:Player_track".format(ctx.message.guild.id),data.id)
await ctx.send(content = "Added {} success.".format(data.name))
@commands.command(brief = "Remove alliance tracking",pass_context =True)
async def remove(self,ctx,name,player = None):
info = await self.redis.get("{}:World".format(ctx.message.guild.id))
if info is None:
return await ctx.send(content = "You haven't added any world yet!")
print("getting world")
grep = self.bot.grep_cache[info]
if player:
data = await self.bot.cogs["Stats"].search_query(ctx,await grep.get_player(name))
else:
data = await self.bot.cogs["Stats"].search_query(ctx,await grep.get_alliance(name),alliance = True)
if data is None:
return
if player:
await self.redis.hdel("{0.guild.id}:Player_track".format(ctx.message),data.id)
else:
await self.redis.hdel("{0.guild.id}:Alliances".format(ctx.message),data.id)
await ctx.send(content = "Remove {} success.".format(data.name))
@commands.command(brief = "Show a list of tracking alliance/player",pass_context = True,name = "list")
async def _list(self,ctx,name= None):
info = await self.redis.get("{}:World".format(ctx.message.guild.id))
if info is None:
return await ctx.send(content = "You haven't added any world yet!")
print("getting world")
grep = self.bot.grep_cache[info]
if name == "player":
player = await self.redis.smembers("{}:Player_track".format(ctx.message.guild.id))
print(player)
list_name = [grep.player.get(x) for x in player if grep.player.get(x)]
pass
else:
alliance = await self.redis.hgetall("{}:Alliances".format(ctx.message.guild.id))
list_name = [grep.alliance.get(x).name for x in alliance if grep.alliance.get(x)]
await ctx.send(content = "```fix\n{}\n```".format("\n".join(list_name)))
@commands.command(hidden=True)
@commands.check(utils.is_owner)
async def debug(self, ctx, *, code : str):
print("OK")
"""Evaluates code."""
code = code.strip('` ')
python = '```py\n{}\n```'
result = None
env = {
'bot': self.bot,
'ctx': ctx,
'message': ctx.message,
'guild': ctx.message.guild,
'channel': ctx.message.channel,
'author': ctx.message.author,
'redis': self.redis
}
env.update(globals())
try:
result = eval(code, env)
if inspect.isawaitable(result):
result = await result
except Exception as e:
await ctx.send(python.format(type(e).__name__ + ': ' + str(e)))
return
if len(python.format(result)) >= 2000:
msg = await utils.send_hastebin(python.format(result))
else:
msg = python.format(result)
await ctx.send(msg)
#setting up world for that channel
#then also set up to get colors
#track who
def setup(bot):
bot.add_cog(Setting(bot))
from discord.ext import commands
from grepolis import grepolis
from .utils import utils
import datetime
import aiohttp
import discord
import json
import time
import re
max_day = 7 #for activity limit
limit_day_data = max_day * 24 + 1 #day time 24 hours then add 1
class Stats():
def __init__(self,bot):
self.bot = bot
self.redis = bot.db.redis
async def world(self,ctx):
world = await self.redis.get("{}:World".format(ctx.message.guild.id))
if world is None:
return await ctx.send(content = "You haven't added any world yet!")
print(world)
return self.bot.grep_cache[world]
async def search_query(self,ctx,data,msg = None, player = None, town = True,alliance = False):
try:
await msg.delete()
except:
pass
print("under search_query")
print(data,"uh really?")
print(type(data))
if data is None:
await ctx.send(content = "I am afraid, this name does not exist, please double check a spelling.")
elif type(data) is list:
if len(data) == 1: #if name is not accurate, but only shown once.
return data[0]
if alliance:
show_list = ["{}. {}".format(count,x.name) for count,x in enumerate(data,start = 1)]
else:
show_list = ["{}. {} ({})".format(count,x.name,x.alliance if player else x.player if town else "") for count,x in enumerate(data,start = 1)]
def digit_check(num): # to ensure that answer is int
return num.content.isdigit() and num.author == ctx.message.author
print(show_list)
if len("\n".join(show_list)) >= 2000:
show_list= show_list[:50]
asking = await ctx.send(content = "```{}```\nWhich number?".format("\n".join(show_list)))
answer = await self.bot.wait_for("message",timeout=30, check=digit_check)
try:
await asking.delete()
await answer.delete()
except:
pass
if answer is None: # if user didnt reply any or not, it will print this
await ctx.send(content = "You took too long, try again!")
return None
elif int(answer.content) <= len(data): # Check if it below in list range so it dont split out of error about out of range
return data[int(answer.content) - 1]
else:
await ctx.send(content = "You enter a number that is out of range!")
return None
else:
return data
# async def hour_bp(self,guild,grep,who):
# try:
# data = []
# for x in ("12","24","168"): #hours
# temp = []
# key = "{}:{}".format(guild.id,x)
# temp_data = json.loads(await self.redis.get(key))[who].get(grep.id)
# if temp_data is None:
# return
# temp.append("{} Hours".format(x) if x != "168" else "7 Days")
# temp.append(str(int(grep.points) - int(temp_data["city"])))
# temp.append(str(int(grep.obp) - int(temp_data["obp"])))
# temp.append(str(int(grep.abp) - int(temp_data["abp"])))
# temp.append(str(int(grep.dbp) - int(temp_data["dbp"])))
# data.append(temp)
# return data
# except Exception as e :
# print(e)
# return None
@commands.command(pass_context=True,brief = "Stats of player")
async def player(self,ctx,*,name):
"""
Allow to give you a stats of player
It will show you a list of player if there is multi of similar name
It will provide
Name
Alliance: Alliance Name
Town: Total Town
BP
Overall Battle Points Points Rank
Attacker Battle Points Points Rank
Defend Battle Points Points Rank
"""
msg = await ctx.send(content = "Getting data...")
grep = await self.world(ctx)
data = await self.search_query(ctx,await grep.get_player(name),msg,player = True)
if data is None:
return
utils.prPurple("ok")
# hours_bp = await self.hour_bp(ctx.message.guild,data,"player")
utils.prPurple("ok")
embed = discord.Embed()
embed.set_author(name = "{0.name}".format(data))
embed.description = "Alliance: **{0.alliance.name}**\nTowns: **{0.total_towns}**\nRank: **{0.rank}**\nPoint: **{0.points}**".format(data)
color = await self.redis.hget("{}:Alliances".format(ctx.message.guild.id),data.alliance.id)
embed.colour = int(color) if color else 000000
embed.add_field(name = "BP",value = "Overall Battle Points\nAttacker Battle Points\nDefend Battle Points")
embed.add_field(name = "Points",value = "{0.obp}\n{0.abp}\n{0.dbp}".format(data))
embed.add_field(name = "Rank",value = "{0.overall_rank}\n{0.attack_rank}\n{0.defend_rank}".format(data))
# if hours_bp:
# embed.add_field(name = "Hours Track", value = "\n".join([x[0] for x in hours_bp]))
# embed.add_field(name = "ABP Gain", value = "\n".join([x[3] for x in hours_bp]))
# embed.add_field(name = "DBP Gain", value = "\n".join([x[4] for x in hours_bp]))
await ctx.send(embed=embed)
@commands.command(pass_context = True,brief = "stats of alliance")
async def alliance(self,ctx,*,name):
"""
Allow to give you a stats of alliance
It will show you a list of alliance if there is multi of similar name
It will provide
Name
Town: Total Town of all member
Members: Total Member
BP
Overall Battle Points Points Rank
Attacker Battle Points Points Rank
Defend Battle Points Points Rank
"""
msg = await ctx.send(content = "Getting data...")
print(name)
start = datetime.datetime.now()
grep = await self.world(ctx)
data = await self.search_query(ctx,await grep.get_alliance(name),msg)
end = datetime.datetime.now()
c = end - start
if data is None:
return
# hours_bp = await self.hour_bp(ctx.message.guild,data,"alliance")
embed = discord.Embed()
embed.set_author(name = "{0.name}".format(data))
embed.description = "**Towns**: {0.towns}\n**Members**:{0.total_members}\nRank: **{0.rank}**\n".format(data)
color = await self.redis.hget("{}:Alliances".format(ctx.message.guild.id),data.id)
embed.colour = int(color) if color else 000000
embed.add_field(name = "BP",value = "Overall Battle Points\nAttacker Battle Points\nDefend Battle Points")
embed.add_field(name = "Points",value = "{0.obp}\n{0.abp}\n{0.dbp}".format(data))
embed.add_field(name = "Rank",value = "{0.overall_rank}\n{0.attack_rank}\n{0.defend_rank}".format(data))
# if hours_bp:
# embed.add_field(name = "Hours Track", value = "\n".join([x[0] for x in hours_bp]))
# embed.add_field(name = "ABP Gain", value = "\n".join([x[3] for x in hours_bp]))
# embed.add_field(name = "DBP Gain", value = "\n".join([x[4] for x in hours_bp]))
print(c.total_seconds())
utils.prGreen(data.id)
await ctx.send(embed=embed)
@commands.command(pass_context = True,brief="Give stats of world")
async def stats(self,ctx):
"""
The stats of world
Total People: number
Total Alliance: number
Total Overall Battle Points: number
Total Attack Battle Points: number
Total Defend Battle Points: number
"""
msg = await ctx.send(content = "Getting data...")
grep = await self.world(ctx)
abp = sum(grep.player_abp[x]["points"] for x in grep.player_abp)
dbp = sum(grep.player_dbp[x]["points"] for x in grep.player_dbp)
await msg.delete()
await ctx.send(content =
"```xl\n"
"Total People: {}\n"
"Total Alliance: {}\n"
"Total Overall Battle Points: {}\n"
"Total Attack Battle Points: {}\n"
"Total Defend Battle Points: {}\n"
"```".format(len(grep.player),len(grep.alliance),abp+dbp,abp,dbp))
@commands.group(pass_context = True,invoke_without_command=True,brief = "Show info of the Town")
async def town(self,ctx,*,name):
"""
Allow to give you a stats of town
It will show you a list of town if there is multi of similar name
It will provide
Name: Name of Town
Player: Owner of Town
Alliance: Under what Alliance is this Town in
Ocean: Ocean
Points: Points
BBCode: [town]....[/town]
"""
msg = await ctx.send(content = "Getting data...")
start = datetime.datetime.now()
grep = await self.world(ctx)
data = await self.search_query(ctx,await grep.get_town(name),msg,town = True)
if data is None:
return
print(data.island_x,data.island_y)
if data.player.name is None:
data.player.name = "Ghost"
end = datetime.datetime.now()
c = end - start
print(data)
owner = data.player or ""
alliance = "" if owner == "" else data.player.alliance
hor = "W" if int(data.island_x[1:]) <= 50 else "E"
ver = "N" if int(data.island_y[1:]) <= 50 else "S"
await ctx.send(content =
"```xl\n"
"Name: {0.name}\n"
"Player: {0.player}\n"
"Alliance: {1}\n"
"Ocean: {0.ocean}-{2}\n"
"Coordinates: ({0.island_x},{0.island_y})\n"
"Points: {0.point}\n"
"BBCode: [town]{0.id}[/town]"
"\n```".format(data,alliance,ver+hor))
print(c.total_seconds())
@commands.command(pass_context = True,brief = "Show status of that player")
async def activity(self,ctx,*,name):
"""
Shown how much he gain per hours
"""
current_page = 0
#Order is Time, Overall, Attack, Defend
utils.prPurple("under activity")
msg = await self.bot.say("Getting data...")
grep = await self.world(ctx)
data = await self.search_query(ctx,await grep.get_player(name),msg,player = True)
if data is None:
return
info = await self.redis.lrange("{}:Tracking:{}".format(ctx.message.guild.id,data.id),0,limit_day_data)
if not(bool(info)):
print("NONE!")
return await ctx.send(content = "This player are not being tracking, make sure add this player's alliance, `{}`".format(data.alliance))
day_info = [info[x:24+x] for x in range(0,len(info),24)]
print(day_info)
print(len(day_info))
print(len(info))
max_page = len(day_info)
if current_page > max_page:
current_page = max_page
date_list = []
obp_list = []
abp_list = []
dbp_list = []
for main in day_info:
utils.prPurple(main)
for x in main:
print(x)
x= x.split(",")
if "0" == x[2] and "0" == x[3]:
continue
clock = time.gmtime(int(x[0]))
date_list.append("{0[2]:02d}/{0[1]:02d} - {0[3]:02d}:{0[4]:02d}".format(clock))
obp_list.append(x[1])
abp_list.append(x[2])
dbp_list.append(x[3])
embed_page = []
print(len(date_list))
for num in range(0,len(date_list),24):
print(num)
date = date_list[num:num+24]
obp = obp_list[num:num+24]
abp = abp_list[num:num+24]
dbp = dbp_list[num:num+24]
print(abp)
embed = discord.Embed()
embed.set_author(name = data.name)
embed.add_field(name = "Date",value = "\n".join(date))
embed.add_field(name = "OBP",value = "\n".join(obp))
embed.add_field(name = "ABP",value = "\n".join(abp))
embed.add_field(name = "DBP",value = "\n".join(dbp))
embed_page.append(embed)
first_time = True
if len(embed_page) == 0:
return await ctx.send(content = "I am afraid there is nothing data on this user which mean, either that person haven't gain any bp within 7 day or was recently added")
while True:
embed_page[current_page].set_footer(text = "{}/{}ᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠᅠ".format(current_page+1,len(embed_page)))
utils.prCyan(current_page)
if first_time:
first_time = False
msg = await ctx.send(embed=embed_page[current_page])
await msg.add_reaction(u"\u2B05")
await msg.add_reaction(u"\u27A1")
else:
msg = await msg.edit(embed=embed_page[current_page])
react = await self.bot.wait_for_reaction([u"\u2B05", u"\u27A1"], message=msg, user=ctx.message.author, timeout=120)
if react is None:
return await msg.clear_reaction()
await msg.remove_reaction(react.reaction.emoji, ctx.message.author)
if react.reaction.emoji == "⬅":
# go back by one
if current_page - 1 == -1: # if it on first page, dont do any
continue
else:
current_page -= 1
elif react.reaction.emoji == "➡":
# go next page by one
if current_page + 1 == max_page: # if it on last page, dont do any
continue
else:
current_page += 1
@town.command(pass_context = True,name = "all")
async def _all(self,ctx,*,name):
def order(item): # Using regex to sort number in ABP or DBP gained and City points
p = re.compile('(\d{3,})')
match = re.search(p, item)
if match:
return str(grep.town[match.group(1)])
msg = await ctx.send(content = "Getting data...")
grep = await self.world(ctx)
data = await self.search_query(ctx,await grep.get_player(name),msg)
# town_list = ["[*]#[|]{ocean}.[|][town]{town}[/town][/*]".format(ocean = value.ocean,town = key) for key,value in data.towns.items()]
town_list = ["[*](#)[|] [|][town]{town}[/town][|] [|]{ocean}[/*]".format(ocean = value.ocean,town = key) for key,value in data.towns.items()]
town_list.sort(key = order)
utils.prPurple(town_list)
town_list = [x.replace("#",str(index)) for index,x in enumerate(town_list,start = 1)]
print(town_list)
utils.prPurple(town_list)
# if len("\n".join(town_list)) >= 1800:
# await self.bot.say("```\n{}\n```".format("\n".join(town_list)))
table = "[table]\n" \
"[**][||] [||]City[||] [||]O[/**]\n" \
"{}\n[/table]".format("\n".join(town_list))
with aiohttp.ClientSession() as session:
async with session.post("https://hastebin.com/documents", data=table) as post:
if post.status == 200:
link = "https://hastebin.com/raw/{}".format((await post.json())["key"])
await ctx.send(content = link)
else:
print(post.status)
print(await post.text())
await ctx.send(content = "Something went wrong.")
@commands.command(pass_context = True, name = "weekly")
async def _alliance_all(self,ctx,*,name):
msg = await ctx.send(content = "Getting data...")
print(name)
new = datetime.datetime.now()
grep = await self.world(ctx)
data = await self.search_query(ctx,await grep.get_alliance(name),msg)
if data is None: return
info = await self.redis.lrange("{}:weekly_bp".format(ctx.message.guild.id), 0, 1)
utils.prYellow(len(info))
if len(info) == 1:
utils.prYellow("under one info")
new_data = {"alliance": {}, "player": {}}
[new_data["alliance"].update({key: {"obp": value.obp, "abp": value.abp, "dbp": value.dbp, "city": value.points}}) for key, value in grep.alliance.items()]
[new_data["player"].update({key: {"obp": value.obp, "abp": value.abp, "dbp": value.dbp, "city": value.points}}) for key, value in grep.player.items()]
new_data["time"] = int(new.timestamp())
old_data = json.loads(info[0])
else:
utils.prYellow("Under two info")
new_data = json.loads(info[0])
old_data = json.loads(info[1])
old_data_player = old_data["player"]
new_data_player = new_data["player"]
info_player = ""
for x in list(data.members):
print(x,type(x))
new_player = new_data_player.get(x.id)
old_player = old_data_player.get(x.id)
if new_player is None or old_player is None:
utils.prCyan("No found for {}".format(x.name))
utils.prCyan(new_player)
utils.prCyan(old_player)
utils.prCyan("Next now")
continue
abp = new_player["abp"] - old_player["abp"]
dbp = new_player["dbp"] - old_player["dbp"]
if abp <= 10000 or dbp <= 10000:
info_player += "[player]{}[/player] {} abp; {} dbp\n".format(x.name,abp,dbp)
else:
utils.prGreen("{} got more than 10k on both.{} , {}".format(x.name,abp,dbp))
utils.prYellow("let see info \n {}".format(info_player))
print(new_data["time"],"\n",old_data["time"])
new_time = datetime.datetime.utcfromtimestamp(new_data["time"])
old_time = datetime.datetime.utcfromtimestamp(old_data["time"])
time_second = new_time - old_time
pre_info = "From {} to {}\nDiffences with last data are {} day, {} second\n\n".format(old_time,new_time,time_second.days,time_second.seconds)
merge = pre_info + info_player
with aiohttp.ClientSession() as session:
async with session.post("https://hastebin.com/documents", data=merge) as post:
if post.status == 200:
link = "https://hastebin.com/raw/{}".format((await post.json())["key"])
await ctx.send(content = link)
else:
print(post.status)
print(await post.text())
await ctx.send(content = "Something went wrong.")
@town.command(pass_context = True)
async def intel(self,ctx,*,name):
msg = await ctx.send(content = "Getting data...")
grep = await self.world(ctx)
data = await self.search_query(ctx,await grep.get_town(name),msg,town = True)
print(data)
if data is None:
return
data_info = await self.redis.lrange("Intel:Town:{}".format(data.id),0,-1)
print(data_info)
if data_info is []:
return await ctx.send(content = "I am sorry, We do not have intel for this town")
list_embed = []
for x in data_info:
embed = discord.Embed()
x = json.loads(x)
embed.timestamp = datetime.datetime.utcfromtimestamp(x.pop("time"))
embed.set_footer(text=x.pop("owner"))
embed.description = "\n".join("{}: {}".format(first,second) for first,second in x.items())
list_embed.append(embed)
max_page = len(list_embed)
utils.prGreen(max_page)
page = 0
first_time = True
while True:
list_embed[page].title = "{} ||| Page:{}/{}".format(data.name,page+1,max_page)
utils.prCyan(page)
if first_time:
first_time = False
msg = await self.bot.say(embed=list_embed[page])
await msg.add_reaction(u"\u2B05")
await msg.add_reaction(u"\u27A1")
else:
msg = await msg.edit(embed=list_embed[page])
react = await self.bot.wait_for_reaction([u"\u2B05", u"\u27A1"], message=msg, user=ctx.message.author, timeout=120)
if react is None:
return await msg.clear_reaction()
await msg.remove_reaction(react.reaction.emoji, ctx.message.author)
if react.reaction.emoji == "⬅":
# go back by one
if page - 1 == -1: # if it on first page, dont do any
continue
else:
page -= 1
elif react.reaction.emoji == "➡":
# go next page by one
if page + 1 == max_page: # if it on last page, dont do any
continue
else:
page += 1
# print(list_embed)
# await self.bot.say(embed = list_embed[0])
def calculatedefences(self,get_unit,report = False):
msg = ""
get_unit = get_unit.replace(" ", "").lower()
landDef = {"Militia": (6, 8, 4), "Swordsman": (14, 8, 30), "Slinger": (7, 8, 2), "Archer": (7, 25, 13), "Hoplite": (18, 12, 7), "Horseman": (18, 1, 24), "Chariot": (76, 16, 56), "Catapult": (30, 30, 30), "Minotaur": (750, 330, 640), "Manticore": (170, 225, 505), "Cyclop": (1050, 10, 1450), "Harpy": (105, 70, 1), "Medusa": (480, 345, 290), "Centaur": (195, 585, 80), "Pegasus": (750, 275, 275), "Cerberus": (825, 300, 1575), "Erinys": (460, 460, 595), "Griffin": (320, 330, 100), "Calydonian Boar": (700, 700, 100), "Divine Envoy": (40, 40, 40)}
myths = ("Minotaur", "Manticore", "Cyclop", "Harpy", "Medusa", "Centaur", "Pegasus", "Cerberus", "Erinys", "Griffin", "Calydonian Boar", "Divine Envoy")
heroes = {"Agamemnon": ((132, 88, 132), (360, 240, 360), (("Archer", "Hoplite"), (1.11, 1.3))), "Atalanta": ((66, 55, 99), (180, 150, 270), None), "Deimos": ((44, 44, 55), (120, 120, 150), None), "Hector": ((165, 165, 121), (450, 450, 330), (("Swordsman", "Slinger"), (1.11, 1.3))), "Helen": ((88, 99, 99), (240, 270, 270), None), "Heracles": ((99, 99, 143), (270, 270, 390), None), "Jason": ((88, 99, 77), (240, 270, 210), None), "Leonidas": ((143, 143, 110), (390, 390, 300), (landDef.keys(), (1.055, 1.15))), "Medea": ((44, 44, 33), (120, 120, 90), (("Slinger"), (1.16, 1.35))), "Pelops": ((181.5, 88, 55), (495, 240, 150), (("Hoplite", "Chariot"), (1.11, 1.3))), "Themistokles": ((170.5, 176, 225.5), (465, 480, 615), (("Horseman", "Divine Envoy"), (1.11, 1.3))), "Urephon": ((77, 88, 99), (210, 240, 270), (myths, (1.055, 1.15))), "Zuretha": ((77, 66, 77), (210, 180, 210), None), "Andromeda": ((88, 110, 99), (240, 300, 270), None), "Apheledes": ((66, 88, 198), (180, 240, 540), None), "Aristotle": ((27.5, 181.5, 137.5), (75, 495, 375), None), "Chiron": ((121, 132, 121), (330, 360, 330), None), "Christopholus": ((88, 99, 99), (240, 270, 270), None), "Daidalos": ((132, 165, 176), (360, 450, 480), None), "Democritus": ((88, 99, 77), (240, 270, 210), None), "Ferkyon": ((132, 132, 121), (360, 360, 330), None), "Odysseus": ((154, 110, 143), (420, 300, 390), None), "Orpheus": ((99, 110, 77), (270, 300, 210), None), "Pariphaistes": ((93.5, 126.5, 99), (255, 345, 270), None), "Rekonos": ((82.5, 82.5, 181.5), (225, 225, 495), None), "Terylea": ((88, 88, 132), (240, 240, 360), None), "Ylestres": ((121, 77, 49.5), (330, 210, 135), None)}
hero = None
if report:
for x in heroes:
get_unit = get_unit.replace(x.lower(), "*{}".format(x.lower()))
hero = re.findall(r"\*([a-z]+)\:(\d+)", get_unit)
if len(hero) > 1:
msg += "Only 1 hero allowed"
return msg
units = re.findall(r"(?<!\*|[a-z])([a-z]+)\:(\d+)", get_unit)
if hero:
hero[0] = hero[0][::-1]
for i in range(len(units)):
units[i] = units[i][::-1]
else:
hero = re.findall(r"\*(\d+)([a-z]+)", get_unit)
if len(hero) > 1:
msg += "Only 1 hero allowed"
return msg
units = re.findall(r"(?<!\*|\d)(\d+)([a-z]+)", get_unit)
if hero:
key = next(filter(lambda x: x.lower().startswith(hero[0][1]), heroes.keys()), None)
if not key:
print("\"{}\" is not a hero (´・ω・`)".format(hero[0][1]))
# msg += "Hero doesn't exist"
# return msg
hero = (hero[0][0], key)
for i in range(len(units)):
key = next(filter(lambda x: re.search("\\b" + units[i][1].replace("", "\s*"), x.lower()) or list(units[i][1]) == re.findall(r"\b[a-z]", x.lower()), landDef.keys()), None)
if not key:
print("\"{}\" is not a unit (´・ω・`)".format(units[i][1]))
# msg += "You enter the format wrong! It should be look like this $calcdef 1 swo, 12 sli, 123 arc"
# return msg
units[i] = (units[i][0], key)
defCalc = [0, 0, 0]
for x in units:
if x[1]:
for i in range(3):
defCalc[i] += int(x[0]) * landDef[x[1]][i] * (heroes[hero[1]][2][1][0] + (int(hero[0]) - 1) * (heroes[hero[1]][2][1][1] - heroes[hero[1]][2][1][0]) / 19.0 if hero and hero[1] and heroes[hero[1]][2] and x[1] in heroes[hero[1]][2][0] else 1)
if hero:
if hero[1]:
for i in range(3):
defCalc[i] += heroes[hero[1]][0][i] + (int(hero[0]) - 1) * (heroes[hero[1]][1][i] - heroes[hero[1]][0][i]) / 19.0
msg += "Lv {} {}".format(*hero)
for x in units:
if x[1]:
if msg:
msg += " "
msg += "{} {}".format(*x)
msg += "\n\n"
msg += "Defence: Blunt {} Sharp {} Ranged {}".format(*defCalc)
return msg
@commands.command(pass_context = True)
async def calcdef(self,ctx,*,get_unit):
await ctx.send(content = self.calculatedefences(get_unit))
def setup(bot):
bot.add_cog(Stats(bot))
import aioredis
import asyncio
from cogs.utils import utils
class Redis:
def __init__(self):
self.loop = asyncio.get_event_loop()
self.loop.create_task(self.Start())
async def Start(self):
utils.prYellow("AIOREDIS")
self.redis = await aioredis.create_redis((utils.OS_Get("Redis"),6379),encoding='utf8',db=9)
from discord.ext import commands
from grepolis import grepolis
from .utils import utils
import traceback
import datetime
import discord
import asyncio
import time
import json
import re
max_day = 7 #for activity limit
limit_day_data = max_day * 24 + 1 #day time 24 hours then add 1
def getNum(item): # Using regex to sort number in ABP or DBP gained and City points
p = re.compile('\(([+-]?\d+)\)')
match = re.search(p, item)
if match:
return int(match.group(1))
class Tracking():
def __init__(self,bot):
self.bot = bot
self.redis = bot.db.redis
self.check_exist = False
self.tracking_loop = asyncio.get_event_loop().create_task(self.startup())
def __unload(self):
self.tracking_loop.cancel()
utils.prPurple("Closing loops of tracking")
def role_mention(self, guild, name):
role = discord.utils.get(guild.roles, name=name)
if role is None:
return name
else:
if role.mentionable:
return role.mention
else:
print("NOT MENTIONABLE ROLE!")
return name
async def startup(self):
if bool(self.bot.grep_cache) is False:
await asyncio.sleep(30)
while True:
try:
print("running")
await self.background_task()
self.bot.background.update({"tracking":datetime.datetime.now()})
await asyncio.sleep(3600)
except:
utils.prRed("Under startup function")
utils.prRed(traceback.format_exc())
utils.prRed(traceback.format_exc())
error = '```py\n{}\n```'.format(traceback.format_exc())
await self.bot.owner.send(error)
break #temp
async def first_time(self,guild,grep):
alliance_list = await self.redis.hgetall("{}:Alliances".format(guild.id))
#run each alliance ID from config
data = {}
data["alliance"] = {}
for alliance in alliance_list:
ally = grep.alliance.get(alliance)
if ally is None:
continue
data["alliance"].update({alliance:{"attack":ally.abp,"defend":ally.dbp}})
[data.update({member.id:{"attack":member.abp,"defend":member.dbp}}) for member in ally.members]
await self.redis.set("{}:battle_points".format(guild.id),json.dumps(data))
async def background_task(self):
start = datetime.datetime.now()
for guild in self.bot.guilds:
print("ok",guild.name)
info = await self.redis.get("{}:World".format(guild.id))
if info is None:
continue
utils.prGreen(self.bot.grep_cache)
grep = self.bot.grep_cache.get(info)
# if grep is None:
# print("here")
# grep = grepolis.Grepolis(info)
# await grep.get_conquest(int(await self.redis.get("time"))) #to get all object update, player, alliances,town,conquest
# self.bot.grep_cache[info] = grep
#call battle points
print("ok after check grep")
self._data = await self.redis.get("{}:battle_points".format(guild.id))
utils.prGreen(self._data)
if self._data is None: #if it first time or empty
print("It is none!")
await self.first_time(guild,grep)
continue
self._data = json.loads(self._data)
if bool(self._data) is False:
print("EMPTY DICT!")
await self.first_time(guild,grep)
continue
self._fresh_data = {} #once collect BP, it will store latest values.
self._fresh_data["alliance"] = {}
#call bp then once done, store new _data into db
try:
await self.battle_point(guild,grep,"attack")
await self.battle_point(guild,grep,"defend")
await self.conquest(guild,grep)
except Exception as e:
utils.prRed(e)
#Then do tracking activity before store new_data
await self.tracking_point(guild,grep)
await self.redis.set("{}:battle_points".format(guild.id), json.dumps(self._fresh_data)) #puting them back into db with new update
await self.redis.set("time", int(time.time()))
end = datetime.datetime.now()
c = end - start
print(c.total_seconds())
print("Now printing")
print(self.bot.grep_cache)
async def tracking_point(self,guild,grep):
utils.prPurple("inside tracking points")
alliance_list = await self.redis.hgetall("{}:Alliances".format(guild.id))
member_list = await self.redis.smembers("{}:Player_track".format(guild.id))
clock = int(time.time())
for alliance_id in alliance_list:
alliance = grep.alliance.get(alliance_id)
print(len(alliance.members))
for member in alliance.members: # a member of that alliances
player = self._data.get(member.id)
if player is None:
continue
# data = "{},{},{},{}".format(clock,int(member.obp) - player.get("overall",0),int(member.abp) - player.get("attack",0),int(member.dbp) - player.get("defend",0)) #OBP GAIN
data = "{},{},{},{}".format(clock,member.obp,int(member.abp) - player.get("attack",0),int(member.dbp) - player.get("defend",0))
await self.redis.lpush("{}:Tracking:{}".format(guild.id,member.id),data)
await self.redis.ltrim("{}:Tracking:{}".format(guild.id,member.id),0,limit_day_data)
for name in ("attack","defend"):
member_gain = []
for member in member_list:
print(member,type(member))
player = grep.player.get(member)
print(player)
if player is None:
continue
old_data = self._data.get(player.id)
if old_data is None:
continue
gain = int((player.abp if name == "attack" else player.dbp)) - old_data[name]
if gain <= 0:
continue
member_gain.append("{}({}):{} (+{})".format(player.name,player.alliance,player.abp if name =="attack" else player.dbp,gain))
member_gain.sort(key = getNum, reverse = True)
utils.prPurple(member_gain)
if member_gain:
#sending summary report first.
embed = discord.Embed()
embed.colour = 14614528 if name == "attack" else 16544
embed.title = "{} Battle Points Report".format(name.title())
channel = self.bot.get_channel(int(await self.redis.get("{}:Channel".format(guild.id))))
if name == "attack":
await channel.send(content = "```fix\nPlayer Report\n```")
await channel.send(embed=embed)
msg = ""
# print(total_report)
for x in member_gain:
# utils.prGreen(x)
msg += "".join(x)
utils.prYellow(len(msg))
if len(msg) >= 1000:
print(len(msg))
await channel.send(content = msg)
msg = ""
if len(msg) > 0: #sending last remain
print("the message is ",msg)
await channel.send(content = msg)
utils.prPurple("all done under tracking points")
async def battle_point(self,guild,grep,name):
print("battle point",name)
total_report = []
temp_alliance = []
alliance_report = []
alliance_list = await self.redis.hgetall("{}:Alliances".format(guild.id))
#run each alliance ID from config
for alliance_id in alliance_list:
# print(alliance_id)
ally = self._data["alliance"].get(alliance_id)
alliance = grep.alliance.get(alliance_id)
if alliance is None:
await self.redis.hdel("{}:Alliances".format(guild.id),alliance_id)
alliance_list = await self.redis.hgetall("{}:Alliances".format(guild.id))
continue
self._fresh_data["alliance"].update({alliance_id: {"attack": alliance.abp, "defend": alliance.dbp}})
[self._fresh_data.update({member.id: {"attack": member.abp, "defend": member.dbp}}) for member in alliance.members]
if ally is None:
utils.prPurple("None ally!")
continue
alliance_points = int((alliance.abp if name == "attack" else alliance.dbp)) - ally[name]
if alliance_points == 0:#if it 0, meaning no members gain bp
continue
alliance_report.append("{}:{} (+{})".format(alliance.name,alliance.abp if name == "attack" else alliance.dbp,alliance_points))
for member in alliance.members: #a member of that alliances
player = self._data.get(member.id)
if player is None: #temp
continue
gain = int((member.abp if name == "attack" else member.dbp)) - player[name]
if gain <= 0:
continue
temp_alliance.append("{}:{} (+{})".format(member.name,member.abp if name =="attack" else member.dbp,gain))
# utils.prYellow(temp_alliance)
temp_alliance.sort(key = getNum, reverse = True)
total_report.append("\n{}\n\n\t\t{}\n".format(self.role_mention(guild,alliance.name),"\n\t\t".join(temp_alliance)))
temp_alliance = [] #reset it
alliance_report.sort(key=getNum, reverse=True)
if alliance_report:
#sending summary report first.
embed = discord.Embed()
embed.colour = 14614528 if name == "attack" else 16544
embed.title = "{} Battle Points Report".format(name.title())
embed.description = "\n".join(alliance_report)
channel = self.bot.get_channel(int(await self.redis.get("{}:Channel".format(guild.id))))
if name == "attack":
await channel.send(content = "```fix\nAlliance Report\n```")
await channel.send(embed=embed)
msg = ""
# print(total_report)
for x in total_report:
# utils.prGreen(x)
msg += "".join(x)
utils.prYellow(len(msg))
if len(msg) >= 1000:
print(len(msg))
await channel.send(msg)
msg = ""
if len(msg) > 0: #sending last remain
print("the message is ",msg)
await channel.send(msg)
#later, add them to self._fresh_data so we can put them into db
async def conquest(self,guild,grep):
utils.prPurple("CONQUEST")
summary = {"Gain":{},"Loss":{},"Internal":{}}
alliance_list = dict(await self.redis.hgetall("{}:Alliances".format(guild.id)))
name_list = [grep.alliance[x].name for x in alliance_list]
utils.prYellow(len(grep.conquest))
for x in grep.conquest: # running each loops of data collect
if not x.new_alliance.id in alliance_list and not x.old_alliance.id in alliance_list:
# print("meh",x.new_alliance,x.new_alliance.id,x.old_alliance,x.old_alliance.id,not x.new_alliance.id in alliance_list,not x.old_alliance.id in alliance_list)
continue
new_alliance = self.role_mention(guild,x.new_alliance.name)
new_alliance = new_alliance if new_alliance else ""
old_alliance = self.role_mention(guild,x.old_alliance.name)
old_alliance = old_alliance if old_alliance else ""
new_player_alliance = "{} ({})".format(x.new_player,new_alliance) # If there is no alliance, aka guildless player
old_player_alliance = "{} ({})".format(x.old_player,old_alliance) # If there is no alliance, meaning guildless player
word = "{1} has conquered {2}. [town]{0.town.id}[/town]".format(x, new_player_alliance, old_player_alliance)
#putting them into reports
if x.new_alliance.name not in summary["Gain"]:
summary["Gain"][x.new_alliance.name] = []
summary["Internal"][x.new_alliance.name] = []
if x.old_alliance.name not in summary["Loss"]:
summary["Loss"][x.old_alliance.name] = []
if x.new_alliance.id == x.old_alliance.id: #if same alliances
summary["Internal"][x.new_alliance.name].append(word)
else:
summary["Gain"][x.new_alliance.name].append(word)
summary["Loss"][x.old_alliance.name].append(word)
embed = discord.Embed(title = "Conquest Report Summary",colour=5814272)
utils.prPurple("checking keys inside gain")
utils.prPurple(summary)
data = []
for x in summary:
temp = []
for name,key in summary[x].items(): #summary of showing who gain and lost
if bool(key) and name is not None and name in name_list:
data.append("\n{}\n\n\t\t{}\n".format(self.role_mention(guild,name),"\n\t\t".join(key)))
temp.append("{}: {}".format(name,len(key)))
if bool(temp):
embed.add_field(name = x,value="\n".join(temp))
channel = self.bot.get_channel(int(await self.redis.get("{}:Channel".format(guild.id))))
if data:
await channel.send(embed=embed)
msg = ""
for x in data:
# utils.prGreen(x)
try:
msg += "".join(x)
if len(msg) >= 1500:
print(len(msg))
await channel.send(msg)
msg = ""
except:
continue
if len(msg) > 0: # sending last remain
await channel.send(msg)
#58B800
def setup(bot):
bot.add_cog(Tracking(bot))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment