Initial Commit
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 1.7 MiB |
|
@ -0,0 +1,169 @@
|
|||
from cgi import test
|
||||
from cmath import pi
|
||||
from tkinter import CENTER
|
||||
from PIL import Image, ImageDraw, ImageFont, ImagePath
|
||||
import textwrap
|
||||
import botOptions
|
||||
import random
|
||||
import math
|
||||
import time
|
||||
|
||||
watermarkFont = ImageFont.truetype('Roboto-Bold.ttf',120)
|
||||
textFont = ImageFont.truetype('Roboto-Bold.ttf',23)
|
||||
|
||||
def generate_bingo(playerName,seed):
|
||||
random.seed(seed)
|
||||
background = Image.open('background.png')
|
||||
midground = Image.open('midground.png')
|
||||
draw = ImageDraw.Draw(background)
|
||||
#Draw Watermark
|
||||
draw.text((500,1000),playerName,font=watermarkFont,fill=(100,0,0),anchor='mb')
|
||||
background.paste(midground,(0,0),midground)
|
||||
selectedTasks = random.sample(botOptions.alternatives,25)
|
||||
for x in range(0,5):
|
||||
for y in range(0,5):
|
||||
|
||||
wrapText = textwrap.fill(text=selectedTasks.pop(),width=13)
|
||||
draw.multiline_text((137+(180*x),267+(180*y)),wrapText,font=textFont,fill=(0,0,0,),anchor='mm',align=CENTER)
|
||||
return background
|
||||
|
||||
def generate_gif_test(displayname,tier):
|
||||
images = []
|
||||
frameCount = 80
|
||||
startAngle = random.random()*720
|
||||
im = Image.new("RGBA", (582, 582), (44, 47, 51,255))
|
||||
wheelGenResult = drawWheel(tier)
|
||||
wheel = wheelGenResult[0]
|
||||
endAngle = (startAngle+(10*(frameCount-1)))%360
|
||||
#print(endAngle)
|
||||
targetAngle = 180-endAngle
|
||||
#Calculate winning segment
|
||||
if endAngle > 180:
|
||||
targetAngle = 360 - endAngle + 180
|
||||
#print(wheelGenResult)
|
||||
#print(targetAngle)
|
||||
for n,seg in enumerate(wheelGenResult[1]):
|
||||
if seg[0]+seg[1] > targetAngle:
|
||||
reward = getTierAwards(tier)[n][2]
|
||||
#print(reward)
|
||||
break
|
||||
|
||||
dot = Image.open('dot.png')
|
||||
|
||||
for n in range(0,frameCount):
|
||||
frame = im.copy()
|
||||
draw = ImageDraw.Draw(frame)
|
||||
|
||||
|
||||
rotwheel = wheel.rotate(startAngle+(n*10))
|
||||
rotwheel.paste(dot,(0,0),dot)
|
||||
frame.paste(rotwheel,(0,0),rotwheel)
|
||||
images.append(frame)
|
||||
c=im.width/2
|
||||
#draw.line((c,c)+(c+250*math.sin((endAngle)/180*pi),c+250*math.cos((endAngle)/180*pi)))
|
||||
images[0].save(displayname+'.gif',
|
||||
save_all=True,
|
||||
append_images=images[1:],
|
||||
duration=22,
|
||||
loop=1)
|
||||
return reward
|
||||
|
||||
def getTierAwards(number):
|
||||
#imageIcons
|
||||
#Tier one
|
||||
tier1 = [
|
||||
(0,Image.open('resources/1kweps.png'),"1000 Weapons"),
|
||||
(0,Image.open('resources/250kgold.png'),"250k Parish Gold"),
|
||||
(0,Image.open('resources/250cat.png'),"250 Catapults"),
|
||||
(0,Image.open('resources/100kpitch.png'),"100k Pitch"),
|
||||
(0,Image.open('resources/fullbanquet.png'),"2700 Banqueting Goods"),
|
||||
(10,Image.open('resources/t2.png'),"T2")
|
||||
]
|
||||
#Tier two
|
||||
tier2 = [
|
||||
(0,Image.open('resources/500kgold.png'),"500k Parish Gold"),
|
||||
(0,Image.open('resources/500cat.png'),"500 Catapults"),
|
||||
(0,Image.open('resources/2kweps.png'),"2000 Weapons"),
|
||||
(6,Image.open('resources/t3.png'),"T3")
|
||||
]
|
||||
#Tier three
|
||||
tier3 = [
|
||||
(0,Image.open('resources/1mgold.png'),"1MILLION GOLD"),
|
||||
(0,Image.open('resources/1kcat.png'),"1000 Catapults"),
|
||||
(0,Image.open('resources/3kweps.png'),"3000 Weapons"),
|
||||
(0,Image.open('resources/5crowns.png'),"$5 Crown Gift")
|
||||
]
|
||||
if number >= 3:
|
||||
return tier3
|
||||
elif number == 2:
|
||||
return tier2
|
||||
else:
|
||||
return tier1
|
||||
|
||||
|
||||
def drawWheel(tier):
|
||||
awards = getTierAwards(tier)
|
||||
im = Image.new("RGBA", (582, 582), (44, 47, 51,0))
|
||||
c = im.width/2
|
||||
radius = 290
|
||||
segments = []
|
||||
|
||||
#generate segment sizes
|
||||
fairChance = 100
|
||||
specials = 0
|
||||
circleCheck = 0
|
||||
for a in awards:
|
||||
if a[0] > 0:
|
||||
fairChance -= a[0]
|
||||
specials +=1
|
||||
|
||||
for award in awards:
|
||||
#set arclengths
|
||||
if award == awards[-1]:
|
||||
arc = 360-circleCheck
|
||||
circleCheck += arc
|
||||
segments.append((arc,award))
|
||||
break
|
||||
if award[0] == 0:
|
||||
arc = int((361*fairChance/100)/(len(awards)-specials))
|
||||
circleCheck += arc
|
||||
segments.append((arc,award))
|
||||
else:
|
||||
arc = int(361*award[0]/100)
|
||||
circleCheck += arc
|
||||
segments.append((arc,award))
|
||||
|
||||
polygons = []
|
||||
iconPositions = []
|
||||
sectorAreas = []
|
||||
sectorStart = 0
|
||||
for seg in segments:
|
||||
sectorSize = seg[0]
|
||||
polygons.append(drawSegmentVector(sectorStart,sectorSize,c,radius))
|
||||
sectorAreas.append((sectorStart,sectorSize))
|
||||
iconPositions.append(int(sectorStart+(sectorSize/2)))
|
||||
sectorStart += seg[0]
|
||||
imdraw = ImageDraw.Draw(im)
|
||||
#selectedColors = random.sample(circleColors,len(polygons))
|
||||
for polys in polygons:
|
||||
imdraw.polygon(polys,fill=random.choice(botOptions.circleColors),outline='black')
|
||||
#add icons to center of segment
|
||||
for index,iconArc in enumerate(iconPositions):
|
||||
icon = awards[index][1]
|
||||
rotIcon = icon.rotate(iconArc-180)
|
||||
imgSize = icon.size
|
||||
|
||||
im.paste(rotIcon,(int(c+(radius*0.75)*math.sin((iconArc)/180*pi))-int(imgSize[0]/2),int(c+(radius*0.75)*math.cos((iconArc)/180*pi))-int(imgSize[1]/2)),mask=rotIcon)
|
||||
#im.show()
|
||||
return((im,sectorAreas))
|
||||
|
||||
|
||||
def drawSegmentVector(arcStart,arcLength,center,radius):
|
||||
vectors = []
|
||||
vectors.append((center,center)) #Start in center
|
||||
for a in range(0,arcLength+1):
|
||||
vectors.append((center+radius*math.sin((a+arcStart)/180*pi),center+radius*math.cos((a+arcStart)/180*pi)))
|
||||
vectors.append((center,center)) #End in center
|
||||
return vectors
|
||||
|
||||
#generate_gif_test("test",1)
|
|
@ -0,0 +1,134 @@
|
|||
verifiedUsers = [194754951547715585,273918567018397697,140988518515212288]
|
||||
prefix = '%'
|
||||
|
||||
alternatives = [
|
||||
"Kill an AI in a parish you do not own",
|
||||
"Raze a village off a player in H13 Bravo",
|
||||
"Raze a village off a player in Green Machine",
|
||||
"Raze a village off a player in League of Nations",
|
||||
"Raze a village off a player in Brothers of the Knighthood",
|
||||
"Raze a village off a player in The Irish Knights",
|
||||
"Raze a village off a player in Band of the Red Hand",
|
||||
"Raze a village off a player in THE PINK FLUFFY UNICORNS",
|
||||
"Raze a village off a player in THE PINK FLUFFY UNICORNS INC",
|
||||
"Raze a village off a player in prisoners of war",
|
||||
"Raze a village off a player in Wind of the Iron Fists",
|
||||
"Raze a village off a player in The Unforgiven",
|
||||
"Raze a village off a player in Godz",
|
||||
"Raze a village off a player in Royal FLush",
|
||||
"Raze a village off a player in THE RIZEN",
|
||||
"Raze a village off a player in The Insane Squirrels",
|
||||
"Raze a village off a player in The Loyal Ones",
|
||||
"Raze a village off a player in DYWIZION 303",
|
||||
"Raze H3 HM Lord Perrin",
|
||||
"Raze H10 HM KingJohn1743",
|
||||
"Raze H13 HM Amber_Rose",
|
||||
"Raze H14 HM War_Ghost",
|
||||
"Raze H17 HM Tasakpol",
|
||||
"Raze H4 HM richardhood",
|
||||
"Raze H3 FG Lord Perrin",
|
||||
"Raze H3 FG bigbucki",
|
||||
"Raze H3 FG sir william 2",
|
||||
"Raze H10 FG BlaCK-NeKR",
|
||||
"Raze H10 FG KingJohn1743",
|
||||
"Raze H10 FG andracoz",
|
||||
"Raze H14 FG Lord Darko900",
|
||||
"Raze H14 FG War_Ghost",
|
||||
"Raze H14 FG Lady Carl",
|
||||
"Raze H17 FG Tasakpol",
|
||||
"Raze H17 FG Peps",
|
||||
"Raze H17 FG johndex",
|
||||
"Raze H13 FG Amber_Rose",
|
||||
"Raze H13 FG Sweet69",
|
||||
"Raze H13 FG Dovis7",
|
||||
"Raze H4 FG richardhood",
|
||||
"Raze H4 FG mcguyber Ill",
|
||||
"Raze local dumbass WinNytHepOOh89",
|
||||
"Raze a pot monster (150 pots minimum)",
|
||||
"Absolve a teammate",
|
||||
"Flip an enemy county neutral",
|
||||
"Flip a parish from enemy to ally",
|
||||
"Send 100 salt to german71",
|
||||
"Send or participate in a bomb base on a target",
|
||||
"Raze a village with at least 3 vassals",
|
||||
"Capture an enemy village with a fully loaded vassal",
|
||||
"Kill 5 irish rats",
|
||||
"Kill 5 english rats",
|
||||
"Kill 5 welsh rats",
|
||||
"Receive A County Proclamation",
|
||||
"Message an SB player you have never talked to before",
|
||||
"Heal 200 disease not in your own parish",
|
||||
"Send 150 Catapult reinforcements to an allied breaker seat",
|
||||
"Fill one empty vassal to 500 troops",
|
||||
"Successfully scout a spice stash",
|
||||
"Call out an H13/H4 player not sitting on ID",
|
||||
"Call out an H3/10/14 player not sitting on ID",
|
||||
"Call out an H17 player not sitting on ID",
|
||||
"Fulfill a request in Ask and Give",
|
||||
"Make a request in Ask and Give channel",
|
||||
"Unlock an achievement",
|
||||
"Collect 3 treasure-castle chests",
|
||||
"Raze an H13 village",
|
||||
"Raze an H4 village",
|
||||
"Raze an H3 village",
|
||||
"Raze an H10 village",
|
||||
"Raze an H14 village",
|
||||
"Raze an H17 village",
|
||||
"Capture an H3 village",
|
||||
"Capture an H10 village",
|
||||
"Capture an H14 village",
|
||||
"Capture an H17 village",
|
||||
"Capture an H13 village",
|
||||
"Capture an H4 village",
|
||||
"Successfully defend against an H13/4 attack",
|
||||
"Successfully defend against an H3/10/14 attack",
|
||||
"Successfully defend against an H17 attack",
|
||||
"Post your castle in Castle-Designs on Discord",
|
||||
"Add a friend on Discord",
|
||||
"Spot marksdad talking about apples",
|
||||
"Successfully scout a fish stash",
|
||||
"Experience Heavy Rain -24",
|
||||
"Experience Sunny Spells +12",
|
||||
"Upgrade a parish building",
|
||||
"Talk to someone in voice chat on Discord",
|
||||
"Get a gold (or rarer) daily card",
|
||||
"Get a CASTLE daily card",
|
||||
"Get an ARMY daily card",
|
||||
"Get a BANQUETING GOODS Daily Card",
|
||||
"Get an SPECIALIST daily card",
|
||||
"Get a FOOD based daily card",
|
||||
"Lose a vassal",
|
||||
"Get a RESOURCES daily card",
|
||||
"LL someone on our Discord",
|
||||
"Complete a quest",
|
||||
"Approach someone in SB w/Wolf-castle & offer to remove it- remove it",
|
||||
"Send some interdiction to an SB vassal hub",
|
||||
"Turn tax to 9x and leave it on",
|
||||
"Send Bglizard (at least) 2000 fish",
|
||||
"Ask your FG what you can do to help",
|
||||
"Experience someone scouting your stash before you do",
|
||||
"Play Improved Guardhouses and put troops up in your towns",
|
||||
"Get a WEAPONS daily card",
|
||||
"Spot more than 40 people online at once on Discord",
|
||||
"1-shot a Wolf AI",
|
||||
"Lose a tower to AI attack",
|
||||
"Rank up without losing any LL",
|
||||
"Experience someone killing Rat AI in your parish",
|
||||
"Experience someone killing Paladin AI in your parish",
|
||||
"Experience someone killing Snake AI in your parish",
|
||||
"Talk to someone in a different house on your Discord",
|
||||
"Someone from a different house on Discord talks to you"
|
||||
]
|
||||
|
||||
|
||||
circleColors = [
|
||||
(15,159,251),
|
||||
(36,139,205),
|
||||
(4,100,161),
|
||||
(68,182,254),
|
||||
(0,180,255),
|
||||
(0,97,159),
|
||||
(62,120,180),
|
||||
(149,195,242)
|
||||
]
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import disnake
|
||||
import requests
|
||||
import datetime
|
||||
import time
|
||||
from helpers import sql_get
|
||||
def lfll(parent):
|
||||
embed = disnake.Embed(title="Looking for Liege Lords")
|
||||
embed.description = "List of people looking for LL, use /LL anywhere you you have access to add to this list!\n **Open the thread below and ✅ the requests that you fulfill**"
|
||||
requests = sql_get("SELECT * FROM llrequests WHERE parentID = {parentID} AND fulfilled = '0'".format(parentID=parent))
|
||||
if len(requests) > 0:
|
||||
users = {}
|
||||
userCP = {}
|
||||
for entries in requests:
|
||||
if entries[7] in users.keys():
|
||||
if entries[4] > userCP[entries[7]]:
|
||||
userCP[entries[7]] = entries[4]
|
||||
users[entries[7]].append(entries[2])
|
||||
else:
|
||||
users[entries[7]] = [entries[2]]
|
||||
userCP[entries[7]] = entries[4]
|
||||
for name,user in users.items():
|
||||
field_body = ""
|
||||
for villa in user:
|
||||
field_body += ">{villa}\n".format(villa=villa)
|
||||
embed.add_field(name="{name} CP:{cp}".format(name=name,cp=userCP[name]),value=field_body)
|
||||
|
||||
return embed
|
||||
|
||||
def check_player(user):
|
||||
activity = requests.get('https://shk.azure-api.net/shkinfo/v1/UserActivity?world=World%202&username={user}&Key=5E78CFC8-1FFA-4036-8427-D94ED6E1A45B&subscription-key=ff2e578e119348ea8b48a2acd2f5a48d'.format(user=user))
|
||||
banStatus = requests.get('http://login.strongholdkingdoms.com/ajaxphp/username_search.php?term={user}'.format(user=user))
|
||||
shield = requests.get('https://login.strongholdkingdoms.com/ajaxphp/get_shield_url.php?username={user}&transparent=1'.format(user=user))
|
||||
print(banStatus.text)
|
||||
banned = "Account is **BANNED**"
|
||||
act = "Error"
|
||||
shieldURL=''
|
||||
known = False
|
||||
if 'error' not in shield.json().keys():
|
||||
shieldURL = shield.json()['url']
|
||||
known = True
|
||||
if len(banStatus.text) == 2:
|
||||
banned = "Account is **BANNED**"
|
||||
if not known:
|
||||
banned = "Account is unknown, typo?"
|
||||
|
||||
else:
|
||||
result = banStatus.json()
|
||||
check = user.lower()
|
||||
if check in (string.lower() for string in result):
|
||||
banned = "**NOT** Banned"
|
||||
if activity.text == '01/Jan/0001 00:00:00':
|
||||
print("Unknown player")
|
||||
act = "-No W2 Data-"
|
||||
else:
|
||||
date = datetime.datetime.strptime(activity.text,'%d/%b/%Y %H:%M:%S')
|
||||
print(date)
|
||||
act = '<t:{t1}:R>'.format(t1=int(date.timestamp()))
|
||||
embed = disnake.Embed(title="{user}'s info".format(user=user))
|
||||
embed.description = "Generated <t:{t1}:R>\nCurrent avaliable info is:".format(user=user,t1=int(time.time()))
|
||||
embed.add_field(name="Last Activity",value = act)
|
||||
embed.add_field(name="Status",value=banned)
|
||||
if shieldURL == '':
|
||||
embed.set_thumbnail(file=disnake.File('StormBrigade_White.png'))
|
||||
else:
|
||||
embed.set_thumbnail(url=shieldURL)
|
||||
return embed
|
30
helpers.py
|
@ -0,0 +1,30 @@
|
|||
import sqlite3
|
||||
from sqlite3 import Cursor, Error
|
||||
def sql_set(query = None,data = None):
|
||||
if query == None: return
|
||||
try:
|
||||
con = sqlite3.connect('sbsheriff.sqlite')
|
||||
cur = con.cursor()
|
||||
cur.execute(query,data)
|
||||
cur.close()
|
||||
con.commit()
|
||||
con.close()
|
||||
|
||||
except Error as e:
|
||||
print(e)
|
||||
return Error
|
||||
|
||||
def sql_get(query = None):
|
||||
if query == None: return
|
||||
try:
|
||||
con = sqlite3.connect('sbsheriff.sqlite')
|
||||
cur = con.cursor()
|
||||
cur.execute(query)
|
||||
re = cur.fetchall()
|
||||
cur.close()
|
||||
con.close()
|
||||
return re
|
||||
|
||||
except Error as e:
|
||||
print(e)
|
||||
return Error
|
426
main.py
|
@ -0,0 +1,426 @@
|
|||
import disnake
|
||||
from disnake.ext import commands
|
||||
import json
|
||||
import modals
|
||||
import helpers
|
||||
import time
|
||||
import embed_factory
|
||||
from disnake.ext import tasks
|
||||
import sqlite3
|
||||
from sqlite3 import Cursor, Error
|
||||
import asyncio
|
||||
import botOptions
|
||||
import bingo
|
||||
import random
|
||||
import math
|
||||
import os
|
||||
from datetime import datetime,timezone
|
||||
import datetime
|
||||
import sbclasses
|
||||
import requests
|
||||
|
||||
intents = disnake.Intents().all()
|
||||
|
||||
bot = commands.Bot(
|
||||
command_preifx='%',
|
||||
sync_commands_debug=False,
|
||||
intents=intents
|
||||
)
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
print('Logged In')
|
||||
|
||||
@bot.slash_command(description='List some villages in need of LL')
|
||||
async def ll(inter:disnake.ApplicationCommandInteraction):
|
||||
playerCP = helpers.sql_get("SELECT cp,prefPikes,prefArchers FROM user WHERE dID = {dID}".format(dID=inter.author.id))
|
||||
print(playerCP)
|
||||
cp = 0
|
||||
prefArcher = 300
|
||||
prefPikes = 200
|
||||
if len(playerCP):
|
||||
cp = int(playerCP[0][0])
|
||||
if playerCP[0][1] != None:
|
||||
prefArcher = int(playerCP[0][2])
|
||||
prefPikes = int(playerCP[0][1])
|
||||
await inter.response.send_modal(modal=modals.LLModal(cp=cp,pike=prefPikes,archer=prefArcher))
|
||||
|
||||
@bot.event
|
||||
async def on_guild_available(guild):
|
||||
helpers.sql_set('INSERT INTO guild(gID,name) VALUES(?,?) ON CONFLICT DO NOTHING',(guild.id,guild.name))
|
||||
|
||||
typeList = ['ll']
|
||||
@bot.slash_command(description='set LL advert channel')
|
||||
async def create_advert(inter:disnake.ApplicationCommandInteraction,advert_type:str = commands.Param(description='What type=',choices=typeList), target: disnake.abc.GuildChannel = commands.Param(description='Channel override, optional')):
|
||||
embed = disnake.Embed(title='Looking for Liege Lords')
|
||||
result = json.loads(helpers.sql_get("SELECT lldata FROM guild WHERE gID = {gID}".format(gID = inter.guild.id))[0][0])
|
||||
if advert_type not in result:
|
||||
message = await target.send(embed=embed)
|
||||
await message.create_thread(name="Requests")
|
||||
result[advert_type] = (message.channel.id,message.id)
|
||||
helpers.sql_set("INSERT INTO guild(gID,lldata) VALUES(?,?) ON CONFLICT DO UPDATE SET lldata = excluded.lldata",(message.guild.id,json.dumps(result)))
|
||||
else:
|
||||
await inter.response.send_message(content="Already set",ephemeral=True)
|
||||
|
||||
@bot.slash_command(description="List some info about target")
|
||||
async def check_player(inter:disnake.ApplicationCommandInteraction,user:str = commands.Param(description='Player Name')):
|
||||
embed = embed_factory.check_player(user)
|
||||
await inter.response.send_message(embed=embed)
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_message_interaction(inter:disnake.MessageInteraction):
|
||||
if inter.component.custom_id == 'llcheck' and not inter.response.is_done():
|
||||
await inter.response.defer(ephemeral=True)
|
||||
inter.component.disabled = True
|
||||
ll_data_dict = json.loads(helpers.sql_get("SELECT lldata FROM guild WHERE gID = {gid}".format(gid=inter.guild.id))[0][0])
|
||||
ll_channel = inter.guild.get_channel_or_thread(ll_data_dict['ll'][0])
|
||||
ll_thread_message = await ll_channel.fetch_message(ll_data_dict['ll'][1])
|
||||
helpers.sql_set("UPDATE llrequests SET fulfilled = ? WHERE messageID = ?",(time.time(),inter.message.id))
|
||||
await ll_thread_message.edit(embed= embed_factory.lfll(ll_data_dict['ll'][1]))
|
||||
|
||||
message = await inter.message.delete()
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
timedAttacks = {}
|
||||
timesMessages = {}
|
||||
|
||||
|
||||
def sql_connection():
|
||||
try:
|
||||
|
||||
con = sqlite3.connect('sbingo2.sqlite')
|
||||
|
||||
return con
|
||||
|
||||
except Error:
|
||||
|
||||
print(Error)
|
||||
|
||||
def sql_setSeed(con,entry):
|
||||
cursorObj = con.cursor()
|
||||
cursorObj.execute('INSERT INTO overrides(dID,seed) VALUES(?,?) ON CONFLICT(dID) DO UPDATE SET seed = excluded.seed',entry)
|
||||
cursorObj.close()
|
||||
con.commit()
|
||||
|
||||
def sql_setCard(con,entry):
|
||||
cursorObj = con.cursor()
|
||||
cursorObj.execute('INSERT INTO defaultCard(dID,speed) VALUES(?,?) ON CONFLICT(dID) DO UPDATE SET speed = excluded.speed',entry)
|
||||
cursorObj.close()
|
||||
con.commit()
|
||||
|
||||
def sql_getCard(con,id):
|
||||
cursorObj = con.cursor()
|
||||
query = 'SELECT speed FROM defaultCard WHERE dID = '+str(id)
|
||||
cursorObj.execute(query)
|
||||
result = cursorObj.fetchall()
|
||||
cursorObj.close()
|
||||
if len(result) == 1:
|
||||
return result[0][0]
|
||||
return result
|
||||
|
||||
def sql_addVM(con,name,dateTime):
|
||||
ok = True
|
||||
data = (name.lower(),dateTime)
|
||||
cursorObj = con.cursor()
|
||||
try:
|
||||
cursorObj.execute('INSERT INTO vecations(name,date) VALUES(?,?)',data)
|
||||
except Error:
|
||||
ok = False
|
||||
cursorObj.close()
|
||||
con.commit()
|
||||
return ok
|
||||
|
||||
def sql_getVM(con):
|
||||
cursorObj = con.cursor()
|
||||
cursorObj.execute('SELECT * FROM vecations where date > unixepoch("now","-14 days");')
|
||||
result = cursorObj.fetchall()
|
||||
cursorObj.close()
|
||||
return result
|
||||
|
||||
def sql_getSeed(con,id):
|
||||
cursorObj = con.cursor()
|
||||
query = 'SELECT dID, seed FROM overrides WHERE dID = '+str(id)
|
||||
cursorObj.execute(query)
|
||||
result = cursorObj.fetchall()
|
||||
cursorObj.close()
|
||||
return result
|
||||
|
||||
def generateBingoCard(display_name, id):
|
||||
bingoimg = bingo.generate_bingo(display_name,id)
|
||||
bingoimg.save(display_name+'.png')
|
||||
|
||||
@bot.event
|
||||
async def on_message(message):
|
||||
if message.author == bot.user:
|
||||
return
|
||||
|
||||
if message.content.startswith(botOptions.prefix):
|
||||
#Potential command
|
||||
command = message.content.lower().split()[0][1:] or None
|
||||
args = message.content.split()[1:] or [None]
|
||||
match command:
|
||||
case 'spin':
|
||||
random.seed(time.time())
|
||||
response = bingo.generate_gif_test(str(message.id),1)
|
||||
await message.channel.send(content='Spinning the wheel for: '+message.author.display_name,file=disnake.File(str(message.id)+".gif"))
|
||||
if response == 'T2':
|
||||
await asyncio.sleep(4)
|
||||
response = bingo.generate_gif_test(str(message.id),2)
|
||||
await message.channel.send(content='LUCKY! You won another spin!',file=disnake.File(str(message.id)+".gif"))
|
||||
if response == 'T3':
|
||||
await asyncio.sleep(4)
|
||||
response = bingo.generate_gif_test(str(message.id),3)
|
||||
await message.channel.send(content='SPINTASTIC!!! Max level spin achieved',file=disnake.File(str(message.id)+".gif"))
|
||||
await asyncio.sleep(4)
|
||||
await message.channel.send('Congratulations! You won: '+response)
|
||||
os.remove(str(message.id)+".gif")
|
||||
case 'bingo':
|
||||
seed = sql_getSeed(con,message.author.id)
|
||||
if seed:
|
||||
generateBingoCard(message.author.display_name,seed[0][1])
|
||||
else:
|
||||
generateBingoCard(message.author.display_name,message.author.id)
|
||||
await message.channel.send(content='Here is your bingo card, if you find something impossible ask for an override!',file=disnake.File(message.author.display_name+".png"))
|
||||
os.remove(message.author.display_name+".png")
|
||||
case 'reroll':
|
||||
if message.author.id in botOptions.verifiedUsers:
|
||||
if len(args) != 1:
|
||||
await message.channel.send('Expecting an user ID')
|
||||
elif not args[0].isnumeric():
|
||||
await message.channel.send('The argument needs to be the user ID')
|
||||
else:
|
||||
target = message.guild.get_member(int(args[0]))
|
||||
print(args)
|
||||
print(message.guild)
|
||||
print(target)
|
||||
if target == None:
|
||||
await message.channel.send("Can't find the user in this disnake")
|
||||
await message.delete()
|
||||
return
|
||||
newRandom = math.floor(random.random()*100000000000)
|
||||
sql_setSeed(con,(target.id,newRandom))
|
||||
generateBingoCard(target.display_name,newRandom)
|
||||
await message.channel.send('New seed set!',file=disnake.File(target.display_name+".png"))
|
||||
os.remove(target.display_name+".png")
|
||||
case 'vm':
|
||||
if len(args) < 1 or args[0] == 'list':
|
||||
vms = sql_getVM(con)
|
||||
print(datetime.fromtimestamp(vms[0][1],timezone.utc))
|
||||
vmList = 'Players potentially still on VM:'
|
||||
if len(vms) == 0:
|
||||
vmList += '\n-None'
|
||||
else:
|
||||
for player in vms:
|
||||
vmList += '\n'+player[0]+' - <t:'+str(int(player[1]))+':R>'
|
||||
await message.channel.send(vmList)
|
||||
if len(args) == 1:
|
||||
if sql_addVM(con,args[0],message.created_at.replace(tzinfo=timezone.utc).timestamp()):
|
||||
await message.channel.send(args[0]+' Added to VM list!')
|
||||
else:
|
||||
await message.channel.send(args[0]+' Is already on the list')
|
||||
case 'test':
|
||||
editAttack = timedAttacks[args[0]]
|
||||
editAttack.setMark(time.time())
|
||||
|
||||
case ('timed'|'attack'|'countdown'):
|
||||
#validate args
|
||||
if len(args) <= 1:
|
||||
if args[0] == 'help' or args[0] == None:
|
||||
embed = disnake.Embed(color=0x5eb4ee,title="<:SB:947837030782615613> Sheriff Timed Attacks for dummies!"\
|
||||
,description="The SB Sheriff can keep track of your times and participating villas!\nThis can be used to keep track of targets and work out what to set the timer to,\n but it can also show a countdown for each attack \
|
||||
Granted this can be a bit slow, and inconvenient for some, but on large timed operations or keeping track of multiple attacks it can be quite useful!\n\n \
|
||||
The only command needed is: **{prefix}timed <target ID> <Time> <Name of Attack>**\n\
|
||||
**<target ID>** : The village ID of intended target\n\
|
||||
**<Time>** : The time you want to add, must be in HH:MM:SS or MM:SS format. Example 1:23:45\n\
|
||||
**<Name of Attack>** : Name of the attacking villa, keep it short and don't use spaces. Example: Mayo5\n\n\
|
||||
Command Example: {prefix}timed 12345 1:23:45 Ros1\n\n\
|
||||
You can add as many or few attacks needed, the Target ID and the time to set timers to is displayed in the attack event.\n\
|
||||
the <:timer_green:947634559225327707> reaction can be used by anyone participating to convert the times to countdowns. After clicking you have 10 seconds to send the longest attack".format(prefix=botOptions.prefix))
|
||||
embed.set_footer(text="Command aliases: timed,attack,countdown")
|
||||
await message.channel.send(embed=embed)
|
||||
await message.delete()
|
||||
return
|
||||
|
||||
if len(args) < 3:
|
||||
#Not the correct number of args
|
||||
await message.channel.send(delete_after=30.0 ,content="Invalid arguments! Usage: {prefix}{command} targetID timeToLand shortName\nExample: {prefix}{command} 69420 1:43:25 Mayo4\nYour input: {msg}".format(msg=message.content,prefix=botOptions.prefix,command=command))
|
||||
await message.delete()
|
||||
return
|
||||
if not ':' in args[1]:
|
||||
await message.channel.send(delete_after=30.0 ,content="Invalid timestamp, HH:MM:SS or MM:SS")
|
||||
await message.delete()
|
||||
return
|
||||
tempTime = [int(n) for n in args[1].split(':')]
|
||||
if len(tempTime) > 3 or len(tempTime) < 2:
|
||||
await message.channel.send(delete_after=30.0 ,content="Invalid timestamp, HH:MM:SS or MM:SS")
|
||||
await message.delete()
|
||||
return
|
||||
#Sanity checks passed, create the event
|
||||
if len(tempTime) == 3:
|
||||
attacktime = (tempTime[0]*3600)+(tempTime[1]*60)+tempTime[2]
|
||||
else:
|
||||
attacktime = (tempTime[0]*60)+tempTime[1]
|
||||
#Determine if this is a new attack:
|
||||
|
||||
|
||||
if args[0] in timedAttacks:
|
||||
editAttack = timedAttacks[args[0]]
|
||||
editAttack.addAttack(message.author.display_name,attacktime,args[2])
|
||||
messageEmbed = editAttack.generateEmbed()
|
||||
#fetch message object
|
||||
target_message = await message.guild.get_channel(editAttack.cID).fetch_message(editAttack.mID)
|
||||
await target_message.edit(embed = messageEmbed,suppress=False,content=None)
|
||||
else:
|
||||
attackObject = sbclasses.TimedAttack(message.author.display_name,message.channel.id,args[0],attacktime,args[2])
|
||||
attackObject.addAttack(message.author.display_name,attacktime,args[2])
|
||||
messageEmbed = attackObject.generateEmbed()
|
||||
sendtMessage = await message.channel.send(embed = messageEmbed)
|
||||
#print(message.guild.emojis)
|
||||
startEmoji = await message.guild.fetch_emoji(947634559225327707)
|
||||
await sendtMessage.add_reaction(startEmoji)
|
||||
attackObject.setMessageID(sendtMessage.id)
|
||||
timedAttacks[args[0]]=attackObject
|
||||
if not updateEmbeds.is_running():
|
||||
updateEmbeds.start()
|
||||
|
||||
|
||||
case ('timescard'|'defaultcard'):
|
||||
if len(args) != 1:
|
||||
await message.channel.send(delete_after=30.0 ,content="Must supply a number, (2,3,4,5,6)")
|
||||
await message.delete()
|
||||
return
|
||||
elif len(args) == 1:
|
||||
if args[0].isnumeric():
|
||||
sql_setCard(con,(message.author.id,int(args[0])))
|
||||
|
||||
|
||||
case ('times'|'calc'|'calculate'|'card'|'time'):
|
||||
if len(args) <= 1:
|
||||
if args[0] == 'help' or args[0] == None:
|
||||
embed = disnake.Embed(color=0x5eb4ee,title="<:SB:947837030782615613> Sheriff Time Converter for dummies!"\
|
||||
,description="The SB Sheriff can calculate your times!\n\
|
||||
It can accept a single time or as many times as you need, you can then use the numbers below to switch output\n\n \
|
||||
The two commands needed is: **{prefix}times <HH:MM:SS>** and **{prefix}timescard <number>** \n\
|
||||
Command Example: {prefix}times 1:23:45 23:45 45 23423\nCommand Example: {prefix}timescard 5\nThe timescard command sets your personal default, otherwise its assumed to be 4\n\n\
|
||||
To try and limit spam the messages delete themselves after a while!".format(prefix=botOptions.prefix))
|
||||
embed.set_footer(text="Command aliases: times,calc,calculate,card,time")
|
||||
await message.channel.send(embed=embed)
|
||||
await message.delete()
|
||||
return
|
||||
|
||||
timeList = []
|
||||
times = sql_getCard(con,message.author.id) or None
|
||||
for arg in args:
|
||||
if not ":" in arg:
|
||||
if not arg.isnumeric():
|
||||
await message.channel.send(delete_after=30.0 ,content="Invalid timestamp, HH:MM:SS or MM:SS or Seconds - Offender:{arg} -- Command sendt: {content}".format(arg=arg,content=message.content))
|
||||
await message.delete()
|
||||
return
|
||||
tempTime = [int(n) for n in arg.split(':')]
|
||||
for n in range(0,3-len(tempTime)):
|
||||
tempTime = [0]+tempTime
|
||||
timeList.append(tempTime)
|
||||
if len(timeList) == 1 and not times:
|
||||
attacktime = (timeList[0][0]*3600)+(timeList[0][1]*60)+timeList[0][2]
|
||||
await message.channel.send(delete_after=60.0,content="Here's the carded times for: {t1}\nUse {prefix}timescard to change your default card\n**2x:** {t2}\n**3x:** {t3}\n**4x:** {t4}\n**5x:** {t5}\n**6x:** {t6}".format(t1=datetime.timedelta(seconds=attacktime),t2=datetime.timedelta(seconds=int(attacktime/2)),t3=datetime.timedelta(seconds=int(attacktime/3)),t4=datetime.timedelta(seconds=int(attacktime/4)),t5=datetime.timedelta(seconds=int(attacktime/5)),t6=datetime.timedelta(seconds=int(attacktime/6))))
|
||||
await message.delete()
|
||||
return
|
||||
if not times: times = 4
|
||||
textContent = "**Modifying times to {times}x:**\nUse {prefix}timescard to change your default card\n".format(times=times,prefix=botOptions.prefix)
|
||||
for t in timeList:
|
||||
attacktime = (t[0]*3600)+(t[1]*60)+t[2]
|
||||
textContent += "{t} -{card}x-> {t1}\n".format(t=datetime.timedelta(seconds=attacktime),t1=datetime.timedelta(seconds=int(attacktime/times)),card=times)
|
||||
textContent += "This message will selfdestruct in <t:{t}:R>".format(t=int(time.time())+240)
|
||||
newMessage = await message.channel.send(content=textContent, delete_after=240.0)
|
||||
timesMessages[newMessage.id] = timeList
|
||||
await newMessage.add_reaction("2️⃣")
|
||||
await newMessage.add_reaction("3️⃣")
|
||||
await newMessage.add_reaction("4️⃣")
|
||||
await newMessage.add_reaction("5️⃣")
|
||||
await newMessage.add_reaction("6️⃣")
|
||||
|
||||
|
||||
|
||||
case _:
|
||||
return
|
||||
await message.delete()
|
||||
|
||||
def updateTimes(id,times):
|
||||
timeList = timesMessages[id]
|
||||
textContent = "**Modifying times to {times}x:**\nUse {prefix}timescard to change your default card\n".format(times=times,prefix=botOptions.prefix)
|
||||
for t in timeList:
|
||||
attacktime = (t[0]*3600)+(t[1]*60)+t[2]
|
||||
textContent += "{t} -{card}x-> {t1}\n".format(t=datetime.timedelta(seconds=attacktime),t1=datetime.timedelta(seconds=int(attacktime/times)),card=times)
|
||||
textContent += "This message will selfdestruct in <t:{t}:R>".format(t=int(time.time())+240)
|
||||
return textContent
|
||||
|
||||
@bot.event
|
||||
async def on_raw_reaction_add(event):
|
||||
if event.user_id == bot.user.id: return
|
||||
if event.message_id in timesMessages.keys():
|
||||
if event.emoji.name == '2️⃣':
|
||||
updateText = updateTimes(event.message_id,2)
|
||||
if event.emoji.name == '3️⃣':
|
||||
updateText = updateTimes(event.message_id,3)
|
||||
if event.emoji.name == '4️⃣':
|
||||
updateText = updateTimes(event.message_id,4)
|
||||
if event.emoji.name == '5️⃣':
|
||||
updateText = updateTimes(event.message_id,5)
|
||||
if event.emoji.name == '6️⃣':
|
||||
updateText = updateTimes(event.message_id,6)
|
||||
targetMessage = await bot.get_channel(event.channel_id).fetch_message(event.message_id)
|
||||
await targetMessage.edit(content=updateText,delete_after=240.0)
|
||||
if event.emoji.id == 947634559225327707:
|
||||
if len(timedAttacks) == 0: return
|
||||
reactedAttack = None
|
||||
for attack in timedAttacks.values():
|
||||
if attack.mID == event.message_id:
|
||||
reactedAttack = attack
|
||||
if reactedAttack == None: return
|
||||
for name in reactedAttack.attackers.keys():
|
||||
if name == event.member.display_name:
|
||||
if reactedAttack.mark > 0: return
|
||||
reactedAttack.setMark(time.time())
|
||||
messageEmbed = reactedAttack.generateEmbed()
|
||||
#fetch message object
|
||||
target_message = await bot.get_channel(reactedAttack.cID).fetch_message(reactedAttack.mID)
|
||||
await target_message.edit(embed = messageEmbed,suppress=False,content=None)
|
||||
|
||||
|
||||
|
||||
@tasks.loop(seconds=1.0)
|
||||
async def updateEmbeds():
|
||||
await bot.wait_until_ready()
|
||||
if len(timedAttacks) == 0:
|
||||
updateEmbeds.stop()
|
||||
else:
|
||||
toPop = []
|
||||
for attack in timedAttacks.values():
|
||||
if attack.mark == 0:
|
||||
continue
|
||||
if attack.needsUpdate():
|
||||
embed = attack.generateEmbed()
|
||||
if attack.isOver():
|
||||
embed = attack.generateEmbed()
|
||||
toPop.append(attack.tID)
|
||||
print("Updated a embed")
|
||||
msg = await bot.get_channel(attack.cID).fetch_message(attack.mID)
|
||||
await msg.edit(embed=embed)
|
||||
|
||||
if len(toPop):
|
||||
for pops in toPop:
|
||||
timedAttacks.pop(pops)
|
||||
if 0 == len(timedAttacks):
|
||||
print("updateEmbeds Hibernating")
|
||||
updateEmbeds.stop()
|
||||
|
||||
con = sql_connection()
|
||||
#bot.run('OTk0NzAzNTcxMjMwNjY2ODk1.GFMMJU.PZCwXKPC76haun-uk7ESYcVfODoCNMXs486P9U')
|
||||
bot.run('OTUxMjU2NTgxMjU1ODc2Njcw.GW5cRr.De_TGPkljNWJEJJJR8LrmI8FtAZEav9mC69OEk')
|
After Width: | Height: | Size: 216 KiB |
|
@ -0,0 +1,80 @@
|
|||
import disnake
|
||||
from disnake import TextInputStyle
|
||||
import helpers
|
||||
import json
|
||||
import embed_factory
|
||||
class LLModal(disnake.ui.Modal):
|
||||
def __init__(self,cp,pike=0,archer=0):
|
||||
components = [
|
||||
disnake.ui.TextInput(
|
||||
label="Enter CP Rank if number below is wrong",
|
||||
placeholder="Last CP was: {cp}".format(cp=cp),
|
||||
custom_id="cp",
|
||||
style=TextInputStyle.short,
|
||||
max_length=5,
|
||||
required=False,
|
||||
value = cp,
|
||||
),
|
||||
disnake.ui.TextInput(
|
||||
label="Villa ID's seperate with space",
|
||||
placeholder="1234 4352 54234 ...etc",
|
||||
custom_id="villa_ids",
|
||||
style=TextInputStyle.short,
|
||||
),
|
||||
disnake.ui.TextInput(
|
||||
label="How many Archers?",
|
||||
placeholder="200",
|
||||
custom_id="archers",
|
||||
value=pike,
|
||||
style=TextInputStyle.short,
|
||||
),
|
||||
disnake.ui.TextInput(
|
||||
label="How many Pikes?",
|
||||
placeholder="300",
|
||||
custom_id="pikes",
|
||||
value=archer,
|
||||
style=TextInputStyle.short,
|
||||
),
|
||||
]
|
||||
super().__init__(
|
||||
title="Liege Lord Request Form",
|
||||
custom_id="submit_ll",
|
||||
components=components
|
||||
)
|
||||
|
||||
async def callback(self,inter: disnake.ModalInteraction):
|
||||
await inter.response.defer(ephemeral=True)
|
||||
playerCP = inter.text_values['cp']
|
||||
prefArchers = inter.text_values['archers']
|
||||
prefPikes = inter.text_values['pikes']
|
||||
print("{player} is cp {cp} and input: {villaids}".format(player=inter.author.display_name,cp=playerCP,villaids=inter.text_values['villa_ids']))
|
||||
helpers.sql_set("INSERT INTO user(dID,name,cp,gID,prefArchers,prefPikes) VALUES(?,?,?,?,?,?) ON CONFLICT(dID) DO UPDATE SET cp = excluded.cp,prefArchers = excluded.prefArchers,prefPikes = excluded.prefPikes",(inter.author.id,inter.author.display_name,playerCP,inter.guild_id,prefArchers,prefPikes))
|
||||
result = json.loads(helpers.sql_get("SELECT lldata FROM guild WHERE gID = {gID}".format(gID = inter.guild.id))[0][0])
|
||||
|
||||
if 'll' not in result.keys():
|
||||
await inter.response.send_message(content="Failed, no thread open", ephemeral=True)
|
||||
return
|
||||
thread = inter.guild.get_channel_or_thread(result['ll'][1])
|
||||
|
||||
if ',' in inter.text_values['villa_ids']:
|
||||
villa_ids = [villa for villa in inter.text_values['villa_ids'].split(',')]
|
||||
else:
|
||||
villa_ids = [villa for villa in inter.text_values['villa_ids'].split()]
|
||||
if len(villa_ids):
|
||||
for villa in villa_ids:
|
||||
button_done = disnake.ui.Button(emoji='✅',custom_id='llcheck')
|
||||
#button_done.callback = sbComponents.ll_button_callback
|
||||
embed = disnake.Embed(title="LL Request - {id} from {name} CP: {cp}".format(id=villa,cp=playerCP,name=inter.author.display_name))
|
||||
embed.description = "{name} is looking for a LL for {id}, if you fulfill this request, or have gotten a LL click the ✅ below to remove it from the list".format(name=inter.author.display_name,id=villa)
|
||||
embed.add_field(name="Archers",value=prefArchers,inline=True)
|
||||
embed.add_field(name="Pikes",value=prefPikes,inline=True)
|
||||
view = disnake.ui.View()
|
||||
view.add_item(button_done)
|
||||
msg = await thread.send(embed=embed,view=view)
|
||||
helpers.sql_set("INSERT INTO llrequests(parentID,villaID,ownerID,ownerCP,fulfilled,messageID,displayName) VALUES(?,?,?,?,?,?,?)",(thread.id,villa,inter.author.id,playerCP,0,msg.id,inter.author.display_name))
|
||||
channel = inter.guild.get_channel_or_thread(result['ll'][0])
|
||||
message = await channel.fetch_message(result['ll'][1])
|
||||
await message.edit(embed=embed_factory.lfll(result['ll'][1]))
|
||||
await channel.send(content="Request has been added!",delete_after=30)
|
||||
await inter.followup.send(content="Done! 💖 Should be listed here: <#{id}>".format(id=channel.id))
|
||||
return
|
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,96 @@
|
|||
from os import times
|
||||
from telnetlib import NOP
|
||||
import time
|
||||
import disnake
|
||||
import datetime
|
||||
import botOptions
|
||||
|
||||
class TimedAttack:
|
||||
def __init__(self,owner,cID,tID,duration,name):
|
||||
self.attackers = {}
|
||||
self.mID = 0
|
||||
self.cID = cID
|
||||
self.tID = tID
|
||||
self.duration = duration
|
||||
self.name = name
|
||||
self.owner = owner
|
||||
self.mark = 0
|
||||
self.longestAttack = 0
|
||||
self.leadIn = 10
|
||||
self.attacks = 0
|
||||
self.sendt = 0
|
||||
self.color = 0xffff00
|
||||
|
||||
def setMessageID(self,id):
|
||||
self.mID = id
|
||||
|
||||
def setMark(self,time):
|
||||
self.color = 0x00ff00
|
||||
self.mark = time
|
||||
|
||||
def addAttack(self,owner,time,name):
|
||||
self.attacks += 1
|
||||
if time > self.longestAttack: self.longestAttack = time
|
||||
if owner in self.attackers.keys():
|
||||
#Attacker adding more attacks
|
||||
self.attackers[owner].append((time,name))
|
||||
self.attackers[owner].sort(key=lambda y: y[0],reverse=True)
|
||||
else:
|
||||
attacklist = []
|
||||
attacklist.append((time,name))
|
||||
self.attackers[owner] = attacklist
|
||||
return
|
||||
|
||||
def isOver(self):
|
||||
if self.mark == 0: return False
|
||||
if time.time() > self.longestAttack+self.mark+self.leadIn:
|
||||
return True
|
||||
return False
|
||||
|
||||
def needsUpdate(self):
|
||||
check = 0
|
||||
for attacks in self.attackers.values():
|
||||
for attack in attacks:
|
||||
ttl = int(self.longestAttack - attack[0] + self.leadIn + self.mark)
|
||||
if int(time.time()) > ttl:
|
||||
check += 1
|
||||
if check > self.sendt:
|
||||
return True
|
||||
return False
|
||||
|
||||
def generateEmbed(self):
|
||||
if self.isOver():
|
||||
self.color = 0xff0000
|
||||
self.sendt = 0
|
||||
|
||||
#timeString = str(datetime.timedelta(seconds=self.duration))
|
||||
attackString = ""
|
||||
if self.mark > 0:
|
||||
attackString = "\nLanding in: <t:{t}:R>".format(t=int(self.longestAttack + self.leadIn + self.mark))
|
||||
embed = disnake.Embed(title="Timed attack on ID: {targetID} - Longest attack: {t} {cd}".format(cd = attackString, targetID = self.tID,owner = self.owner,t=str(datetime.timedelta(seconds=self.longestAttack)))\
|
||||
,description="To participate add your times using: \n {prefix}timed {tID} <Time to Land> <Name of Attack> \n\
|
||||
Once everything is added, click the green timer reaction to start the countdowns.\n {leadin} seconds is added to the timers as a lead in.\n**Confused? use {prefix}timed help**"\
|
||||
.format(prefix=botOptions.prefix,owner=self.owner,tID=self.tID,leadin=self.leadIn),color = self.color)
|
||||
#If theres attackers, add them.
|
||||
for name, attacks in self.attackers.items():
|
||||
|
||||
valString = ""
|
||||
for attack in attacks:
|
||||
if self.mark > 0:
|
||||
#long Time - time + leadin + mark
|
||||
ttl = int(self.longestAttack - attack[0] + self.leadIn + self.mark)
|
||||
if int(time.time()) > ttl:
|
||||
self.sendt += 1
|
||||
valString += '**{name}**: Sendt\n'.format(name=attack[1])
|
||||
continue
|
||||
valString += '**{name}**: <t:{t}:R>\n'.format(t=ttl,name=attack[1])
|
||||
else:
|
||||
valString += '**{name}**: {t}\n'.format(t=str(datetime.timedelta(seconds=attack[0])),name=attack[1])
|
||||
embed.add_field(name = "__{name}__".format(name = name),value = valString,inline=True)
|
||||
#embed.add_field(name = 'Strix',value='VilA:<t:{t1}:R>\nVilA:<t:{t2}:R>'.format(t1=int(time.time()+random.random()*360),t2=int(time.time()+random.random()*360)),inline=True)
|
||||
|
||||
|
||||
embed.set_author(name='Storm Brigade',icon_url='https://media.disnakeapp.net/attachments/947633992688103424/947805799231660032/StormBrigade_White.png')
|
||||
return embed
|
||||
|
||||
|