|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"autocomp",
|
||||
"disnake",
|
||||
"sqlalchemy"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
URL = 'https://www.google.com/'
|
||||
IMAGE_1 = 'https://cdn.discordapp.com/embed/avatars/1.png'
|
||||
IMAGE_2 = 'https://cdn.discordapp.com/embed/avatars/2.png'
|
||||
|
||||
# embeds must have the same url
|
||||
# works with more up to 4(?) embeds on desktop, might not work at all on mobile
|
||||
|
||||
embed1 = discord.Embed(
|
||||
title='TITLE 1',
|
||||
description='DESCRIPTION 1',
|
||||
url=URL # <<< same url as other embeds
|
||||
)
|
||||
embed1.set_image(url=IMAGE_1)
|
||||
|
||||
embed2 = discord.Embed(
|
||||
title='TITLE 2',
|
||||
description='DESCRIPTION 2',
|
||||
url=URL # <<< same url as other embeds
|
||||
)
|
||||
embed2.set_image(url=IMAGE_2)
|
||||
await channel.send(embeds=[embed1, embed2])
|
After Width: | Height: | Size: 2.3 MiB |
|
@ -0,0 +1,75 @@
|
|||
from disnake.ext import commands
|
||||
import disnake
|
||||
from main import StronkBot
|
||||
from loguru import logger
|
||||
import httpx
|
||||
from thefuzz import process
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Relationship_Manager(commands.Cog):
|
||||
def __init__(self,bot:StronkBot):
|
||||
self.bot = bot
|
||||
self.houses = ["House 1 - The Heavenly Ones","House 2 - High Castle","House 3 - The Dragons","House 4 - The Farmers","House 5 - The Navigators","House 6 - The Free Folk","House 7 - The Royals","House 8 - The Roses","House 9 - The Rams","House 10 - Fighters","House 11 - Heroes","House 12 - Stags","House 13 - Oak","House 14 - Beasts","House 15 - The Pure","House 16 - Lionheart","House 17 - The Insane","House 18 - Sinners","House 19 - The Double-Eagles","House 20 - Maidens",]
|
||||
|
||||
@commands.slash_command()
|
||||
async def set_relationship(self,inter:disnake.ApplicationCommandInteraction,
|
||||
target_type:str = commands.Param(choices=["House", "Player"]),
|
||||
relation:str = commands.Param(choices=["Faction", "Allied", "Neutral", "Peace", "Enemy", "Rogue"]),
|
||||
world:str = commands.Param(description="What world does this relation apply? Leave blank to affect all worlds", default = None),
|
||||
target:str = commands.Param(description="Type the name of the target of this relation change"),
|
||||
comment:str = commands.Param(default="",description="If you want you can add some info about this relationship for clarity. Might not be used anywhere")):
|
||||
#Validate target name
|
||||
if target_type == "Player":
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(f'http://login.strongholdkingdoms.com/ajaxphp/username_search.php?term={target}')
|
||||
if target not in response.json(): return await inter.send(ephemeral=True, content=f"You submitted {target} this name does not seem valid. Make sure the name has the right capitalization. Or the player is banned")
|
||||
await self.bot.database.players.update_one({"in_game_name": target},{"$set": {"in_game_name": target}},upsert=True)
|
||||
if target_type == "House":
|
||||
if target not in self.houses: return await inter.send(ephemeral=True,content=f"You submitted {target} this name does not seem valid. Make sure to pick from the list")
|
||||
target = target.partition(" - ")[0]
|
||||
|
||||
document = {
|
||||
"guild_id": inter.guild_id,
|
||||
"world": world,
|
||||
"target": target,
|
||||
"type": target_type,
|
||||
"state": relation,
|
||||
"comment": comment,
|
||||
"author": {
|
||||
"discord_id" : inter.author.id,
|
||||
"discord_name" : inter.author.display_name,
|
||||
"date": datetime.now()
|
||||
}
|
||||
}
|
||||
|
||||
#Upsert the correct document to the relationship collection
|
||||
|
||||
await self.bot.database.relationships.update_one({"guild_id": inter.guild_id, "type": target_type, "target": target}, {"$set": document},upsert=True)
|
||||
await inter.send(ephemeral=True,content=f"Done! Set {target} as {relation}!\nNote that this does not update adverts, any changes will be updated during their scheduled updates.")
|
||||
|
||||
@set_relationship.autocomplete("target")
|
||||
async def autocomp_input(self, inter:disnake.ApplicationCommandInteraction,user_input:str):
|
||||
if len(user_input) == 0: return []
|
||||
target_type = inter.filled_options.get("target_type")
|
||||
if target_type is None: return ["Please set a target type first"]
|
||||
if target_type == "Player":
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(f'http://login.strongholdkingdoms.com/ajaxphp/username_search.php?term={user_input}')
|
||||
return response.json()
|
||||
if target_type == "House":
|
||||
return [option[0] for option in process.extract(user_input,self.houses,limit=4)]
|
||||
|
||||
@set_relationship.autocomplete("world")
|
||||
async def autocomp_world(self, inter:disnake.ApplicationCommandInteraction,user_input:str):
|
||||
server_document = await self.bot.database.servers.find_one({"_id":inter.guild_id})
|
||||
return server_document["worlds"].keys()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def setup(bot):
|
||||
logger.info(f"{__name__} Loaded")
|
||||
bot.add_cog(Relationship_Manager(bot))
|
|
@ -1,13 +1,66 @@
|
|||
from disnake.ext import commands
|
||||
from PIL import Image
|
||||
import disnake
|
||||
from main import StronkBot
|
||||
from loguru import logger
|
||||
class Setup(commands.Cog):
|
||||
typelist = ["liegelord","vm_tracker","diplomacy"]
|
||||
def __init__(self,bot) -> None:
|
||||
def __init__(self,bot:StronkBot):
|
||||
self.bot = bot
|
||||
self.worlds = []
|
||||
self.advert_types = []
|
||||
|
||||
@commands.slash_command(description='Define an advert channel',default_member_permissions=disnake.Permissions(manage_guild=True))
|
||||
async def create_advert(self,
|
||||
@commands.slash_command(description="Assign a world to this server",default_member_permissions=disnake.Permissions(manage_guild=True))
|
||||
async def set_server_world(self,
|
||||
inter:disnake.ApplicationCommandInteraction,
|
||||
advert_type:str = commands.Param(description='What type=',choices=typelist),
|
||||
target: disnake.abc.GuildChannel = commands.Param(description='Channel override, optional')):
|
||||
world:str,
|
||||
api_key:str = None):
|
||||
if not world in self.worlds:
|
||||
await inter.response.send_message(content="Not found, use suggestions please",ephemeral=True)
|
||||
return
|
||||
|
||||
world_document = await self.bot.database.worlds.find_one({"world_name": world})
|
||||
if not world_document:
|
||||
return await inter.response.send_message(ephemeral=True,content="Can't find the world, contact Strix please")
|
||||
server_document = await self.bot.database.servers.find_one({"_id": inter.guild_id})
|
||||
if not server_document:
|
||||
new_document = {"_id": inter.guild_id,"server_name": inter.guild.name,"worlds":{world_document["world_name"]:api_key}}
|
||||
result = await self.bot.database.servers.insert_one(new_document)
|
||||
return await inter.response.send_message(ephemeral=True, content=f'Great! Server registered and added {world_document["world_name"]} to your server')
|
||||
world_list = server_document.get("worlds")
|
||||
if world_list and world_document["_id"] in world_list:
|
||||
return await inter.response.send_message(ephemeral=True, content="This world is already registered on this world!")
|
||||
await self.bot.database.servers.find_one_and_update({"_id": inter.guild_id},{"$set":{"worlds.{}".format(world_document["world_name"]):api_key}},upsert=True)
|
||||
await inter.response.send_message(f"Done, added {world_document['world_name']}")
|
||||
|
||||
@set_server_world.autocomplete("world")
|
||||
async def autocomp_worlds(self, inter:disnake.ApplicationCommandInteraction, user_input:str):
|
||||
if len(self.worlds) == 0:
|
||||
cursor = self.bot.database.worlds.find()
|
||||
world_docs = await cursor.to_list(length=None)
|
||||
self.worlds = [world["world_name"] for world in world_docs if not world["ended"]]
|
||||
return [world for world in self.worlds if user_input.lower() in world.lower()][:25]
|
||||
|
||||
@commands.slash_command(description="Define one of your channels as an advert channel")
|
||||
async def set_advert_channel(self, inter:disnake.ApplicationCommandInteraction, ad_type:str, channel:disnake.TextChannel):
|
||||
if not ad_type in self.advert_types:
|
||||
await inter.response.send_message(content="Not found, use suggestions please",ephemeral=True)
|
||||
return
|
||||
|
||||
result = await self.bot.database.adverts.update_one({"guild_id": inter.guild_id}, {"$set":{"advert_type": ad_type, "channel_id": channel.id}}, upsert=True)
|
||||
await inter.send(content=f"Ok, registered {channel.name} as a {ad_type}. The advert should appear shortly.")
|
||||
|
||||
|
||||
#TODO: Trigger individual refresh of this advert.
|
||||
|
||||
|
||||
@set_advert_channel.autocomplete("ad_type")
|
||||
async def autocomp_worlds(self, inter:disnake.ApplicationCommandInteraction, user_input:str):
|
||||
if len(self.advert_types) == 0:
|
||||
results = await self.bot.database.config.find_one({"name":"advert_types"})
|
||||
self.advert_types = results.get("advert_types")
|
||||
return [ad_type for ad_type in self.advert_types if user_input.lower() in ad_type.lower()][:25]
|
||||
|
||||
|
||||
def setup(bot):
|
||||
logger.info(f"{__name__} Loaded")
|
||||
bot.add_cog(Setup(bot))
|
|
@ -0,0 +1,65 @@
|
|||
import aiohttp
|
||||
import disnake
|
||||
from disnake.ext import commands, tasks
|
||||
from loguru import logger
|
||||
import httpx
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
|
||||
class Shk_tasks(commands.Cog):
|
||||
def __init__(self,bot):
|
||||
self.bot = bot
|
||||
self.getHouseData.start()
|
||||
|
||||
def cog_unload(self):
|
||||
logger.info(f"{__name__} Unloaded")
|
||||
self.getHouseData.cancel()
|
||||
|
||||
@tasks.loop(hours=2)
|
||||
async def getHouseData(self) -> None:
|
||||
#Collect all worlds we have access too.
|
||||
await self.bot.wait_until_ready()
|
||||
logger.info("Starting House Data Update")
|
||||
|
||||
filter_query = {"worlds": {"$exists": True}}
|
||||
documents = await self.bot.database.servers.find(filter_query).to_list(None)
|
||||
|
||||
# Combine dictionaries into a collated list of worlds
|
||||
collated_worlds = {}
|
||||
for doc in documents:
|
||||
worlds = doc.get("worlds")
|
||||
collated_worlds.update(worlds)
|
||||
upsert_operations = []
|
||||
world:str
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
for world,key in collated_worlds.items():
|
||||
if key is None: continue
|
||||
logger.info(f"Updating house info for {world}")
|
||||
for house in range(1,21):
|
||||
try:
|
||||
async with session.get(f'https://shk.azure-api.net/shkinfo/v1/HouseActivity?world={world}&house={house}&Key={key}&subscription-key=ff2e578e119348ea8b48a2acd2f5a48d',timeout=20) as houseActivity:
|
||||
for user in await houseActivity.json():
|
||||
filter_query = {
|
||||
"in_game_name": user["Username"],
|
||||
"world": world,
|
||||
"house": house
|
||||
}
|
||||
update_query = {
|
||||
"$set": {
|
||||
"timestamp": datetime.now()
|
||||
}
|
||||
}
|
||||
await self.bot.database.players.update_one({"in_game_name": user["Username"]},{"$set": {"in_game_name": user["Username"]}},upsert=True)
|
||||
await self.bot.database.house_history.update_one(filter_query, update_query, upsert=True)
|
||||
except aiohttp.ServerTimeoutError:
|
||||
logger.exception(f"Timeout when trying to fetch data for World {world} and house {house}")
|
||||
logger.info(f"Finished {world} update")
|
||||
except Exception as e:
|
||||
logger.exception("Scan failed due to exception")
|
||||
logger.info("Finished House Data update")
|
||||
|
||||
def setup(bot):
|
||||
logger.info(f"{__name__} Loaded")
|
||||
bot.add_cog(Shk_tasks(bot))
|
|
@ -0,0 +1,175 @@
|
|||
from disnake.ext import commands, tasks
|
||||
import disnake
|
||||
from main import StronkBot
|
||||
from loguru import logger
|
||||
from datetime import datetime, timedelta
|
||||
from embed_factory import vm_advert
|
||||
import httpx
|
||||
from thefuzz import process
|
||||
|
||||
|
||||
class Vm_tracker(commands.Cog):
|
||||
def __init__(self,bot:StronkBot):
|
||||
self.bot = bot
|
||||
self.update_vm_embeds.start()
|
||||
|
||||
def cog_unload(self):
|
||||
self.update_vm_embeds.cancel()
|
||||
|
||||
@commands.slash_command(description="Report someone going in VM")
|
||||
async def report_vm(self,inter:disnake.ApplicationCommandInteraction, in_game_name:str):
|
||||
logger.info(f"{inter.application_command.name} used by {inter.author} using {inter.filled_options}")
|
||||
inter.response.defer(ephemeral=True)
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(f'http://login.strongholdkingdoms.com/ajaxphp/username_search.php?term={in_game_name}')
|
||||
if in_game_name not in response.json(): return await inter.send(content=f"You submitted {in_game_name} this name does not seem valid. Make sure the name has the right capitalization. Or the player is banned")
|
||||
|
||||
#See if this is a duplicate
|
||||
check = await self.bot.database.vm_entries.find_one({"in_game_name": in_game_name,"guild_id": inter.guild_id, "finished": {"$exists" : False}})
|
||||
if check is not None:
|
||||
return await inter.send(content="Good news, this is already reported! :D")
|
||||
await self.bot.database.vm_entries.insert_one(
|
||||
{"guild_id": inter.guild_id, "in_game_name": in_game_name, "added": datetime.now()}
|
||||
)
|
||||
advert = await self.bot.database.adverts.find_one({"advert_type":"vm_tracker", "guild_id": inter.guild_id})
|
||||
if advert is not None:
|
||||
await self.update_adverts([advert])
|
||||
await inter.send(content=f"Thank you! {in_game_name} has been registered")
|
||||
|
||||
@commands.slash_command(description="Edit a VM entry on this server")
|
||||
async def edit_vm(self,inter:disnake.ApplicationCommandInteraction, in_game_name:str, action:str = commands.Param(choices=["Remove", "Adjust Start Time"], description="If you choose adjust time add the optional 'Value' argument"), value:int = commands.Param(default= 0 ,description="In hours how much do you want to adjust the start time. Negative numbers go forward in time")):
|
||||
logger.info(f"{inter.application_command.name} used by {inter.author} using {inter.filled_options}")
|
||||
# Get the list of players this server is allowed to edit.
|
||||
filter = {
|
||||
"added": {
|
||||
"$gte": datetime(datetime.now().year - 1, 12, 15),
|
||||
"$lte": datetime(datetime.now().year + 1, 1, 15)
|
||||
},
|
||||
"guild_id": inter.guild_id,
|
||||
"finished": {"$exists" : False}
|
||||
}
|
||||
vm_entries = await self.bot.database.vm_entries.find(filter, {"_id": 0, "in_game_name": 1} ).to_list(length=None)
|
||||
eligible_names = [entry["in_game_name"] for entry in vm_entries]
|
||||
filter.update({"in_game_name": in_game_name})
|
||||
if in_game_name not in eligible_names: return await inter.send(ephemeral=True, content=f"You submitted {in_game_name} this name does not seem valid. You can only edit entries submitted by your server")
|
||||
if action == "Remove":
|
||||
await self.bot.database.vm_entries.update_one(filter, {"$set": {"finished": datetime.now()}})
|
||||
elif action == "Adjust Start Time":
|
||||
await self.bot.database.vm_entries.update_one(filter, [{"$set": {"added": { "$add": ["$added", -value*3600000]}}}])
|
||||
|
||||
advert = await self.bot.database.adverts.find_one({"advert_type":"vm_tracker", "guild_id": inter.guild_id})
|
||||
if advert is not None:
|
||||
await self.update_adverts([advert])
|
||||
await inter.response.send_message(ephemeral=True,content=f"Thank you! {in_game_name} has been edited")
|
||||
|
||||
@edit_vm.autocomplete("in_game_name")
|
||||
async def autocomp_input(self, inter:disnake.ApplicationCommandInteraction,user_input:str):
|
||||
if len(user_input) == 0: return []
|
||||
filter = {
|
||||
"added": {
|
||||
"$gte": datetime(datetime.now().year - 1, 12, 15),
|
||||
"$lte": datetime(datetime.now().year + 1, 1, 15)
|
||||
},
|
||||
"guild_id": inter.guild_id,
|
||||
"finished": {"$exists" : False}
|
||||
|
||||
}
|
||||
vm_entries = await self.bot.database.vm_entries.find(filter, {"_id": 0, "in_game_name": 1} ).to_list(length=None)
|
||||
eligible_names = [entry["in_game_name"] for entry in vm_entries]
|
||||
return [option[0] for option in process.extract(user_input,set(eligible_names),limit=4)]
|
||||
|
||||
@tasks.loop(hours=1)
|
||||
async def update_vm_embeds(self) -> None:
|
||||
await self.bot.wait_until_ready()
|
||||
logger.info(f"---> Updating VM adverts")
|
||||
|
||||
|
||||
#Check if any entries have expired
|
||||
result = await self.bot.database.vm_entries.update_many({"added": {"$lt": datetime.now()-timedelta(days=15)}, "finished" : { "$exists" : False }},{"$set":{"finished": datetime.now()}})
|
||||
adverts = await self.bot.database.adverts.find({"advert_type": "vm_tracker"}).to_list(length=None)
|
||||
|
||||
#TODO Enable some way to switch what world house colors should be pulled from. As servers might have more than one world listed.
|
||||
|
||||
await self.update_adverts(adverts)
|
||||
|
||||
async def update_adverts(self,adverts:list):
|
||||
for advert in adverts:
|
||||
#Make sure the guild is still present
|
||||
target_guild = self.bot.get_guild(advert["guild_id"])
|
||||
if not target_guild:
|
||||
logger.error(f"Tried updating VM advert in {advert['guild_id']} but its not present in the bot")
|
||||
continue
|
||||
#TODO Note infraction for later cleanup if this repeats.
|
||||
target_channel = target_guild.get_channel(advert["channel_id"])
|
||||
if not target_channel:
|
||||
logger.error(f"Tried updating VM advert in {target_guild.name} but the channel is not present in the guild")
|
||||
continue
|
||||
#TODO Note infraction, warn the server owner. Repeated failures will result in advert removal
|
||||
|
||||
#Collect what world(s) the guild is looking at
|
||||
|
||||
current_server_document = await self.bot.database.servers.find_one({"_id": advert["guild_id"]})
|
||||
world_list:dict = current_server_document.get("worlds", None)
|
||||
|
||||
vm_entries = await self.collect_server_vms(guild_id=advert["guild_id"],all=True)
|
||||
|
||||
vm_entries = sorted(vm_entries, key=lambda x: x["added"])
|
||||
#Get the relevant house affiliations if applicable
|
||||
house_data = None
|
||||
house_relations = None
|
||||
if len(world_list) > 0:
|
||||
house_data = await self.bot.database.house_history.find({"timestamp":{"$gte":datetime.now()- timedelta(hours=2)}, "in_game_name": {"$in":[entry["in_game_name"] for entry in vm_entries]}, "world":next(iter(world_list))}).to_list(length=None)
|
||||
house_data = {doc["in_game_name"]: doc for doc in house_data}
|
||||
house_relations = await self.bot.database.relationships.find({"guild_id": advert["guild_id"], "type": "House", "world": {"$in": [next(iter(world_list)),None]}}).to_list(length=None)
|
||||
relations = {doc["target"]: doc["state"] for doc in house_relations}
|
||||
|
||||
player_relations = await self.bot.database.relationships.find({"guild_id": advert["guild_id"], "type": "Player", "world": {"$in": [next(iter(world_list)),None]}}).to_list(length=None)
|
||||
relations.update({doc["target"]: doc["state"] for doc in player_relations})
|
||||
|
||||
|
||||
embed = vm_advert.generate_embed(bot = self.bot, guild_id = advert["guild_id"],vm_entries=vm_entries,house_data=house_data,relations=relations)
|
||||
target_message_id = advert.get("message_id", None)
|
||||
if target_message_id is None:
|
||||
sent_message = await target_channel.send(embed=embed)
|
||||
#Add new message to advert for future updates
|
||||
await self.bot.database.adverts.update_one({"guild_id":advert["guild_id"],"channel_id":advert["channel_id"]},{"$set": {"message_id":sent_message.id}})
|
||||
continue
|
||||
else:
|
||||
target_message = await target_channel.fetch_message(target_message_id)
|
||||
await target_message.edit(embed=embed,components=None)
|
||||
|
||||
async def collect_server_vms(self,guild_id:int, all=False):
|
||||
|
||||
from_date = datetime(datetime.now().year - 1, 12, 15)
|
||||
to_date = datetime(datetime.now().year + 1, 1, 15)
|
||||
|
||||
# Build the filter for the query
|
||||
filter_query = {
|
||||
"added": {
|
||||
"$gte": from_date,
|
||||
"$lte": to_date
|
||||
},
|
||||
"guild_id": guild_id,
|
||||
}
|
||||
if not all:
|
||||
filter_query.update({"finished": {"$exists" : False}})
|
||||
return await self.bot.database.vm_entries.find(filter_query).to_list(length=None)
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_button_click(self, inter:disnake.MessageInteraction):
|
||||
if "vm_tracker" not in inter.component.custom_id: return
|
||||
logger.info(f"{inter.component.custom_id} used by {inter.author}")
|
||||
await inter.response.defer(with_message=False)
|
||||
|
||||
await self.bot.database.vm
|
||||
|
||||
await self.bot.database.adverts.update_one({"advert_type":"vm_tracker", "guild_id": inter.guild_id}, [ { "$set": {"private": {"$not": "$private" } } } ] )
|
||||
|
||||
advert = await self.bot.database.adverts.find_one({"advert_type":"vm_tracker", "guild_id": inter.guild_id})
|
||||
if advert is not None:
|
||||
await self.update_adverts([advert])
|
||||
|
||||
|
||||
def setup(bot):
|
||||
logger.info(f"{__name__} Loaded")
|
||||
bot.add_cog(Vm_tracker(bot))
|
|
@ -0,0 +1,89 @@
|
|||
from disnake.ext import commands, tasks
|
||||
import disnake
|
||||
import db
|
||||
import httpx
|
||||
from datetime import datetime
|
||||
from sqlalchemy import func
|
||||
from loguru import logger
|
||||
import sb_utils
|
||||
import embed_factory.check_player
|
||||
from main import StronkBot
|
||||
|
||||
class Check_Player(commands.Cog):
|
||||
def __init__(self,bot):
|
||||
self.bot:StronkBot = bot
|
||||
|
||||
@commands.slash_command(description="Look up information about a player")
|
||||
async def check_player(self, inter:disnake.ApplicationCommandInteraction,player:str):
|
||||
logger.info(f"{inter.application_command.name} used by {inter.author} using {inter.filled_options}")
|
||||
#Get server specific shit
|
||||
server_document = await self.bot.database.servers.find_one({"_id" : inter.guild_id})
|
||||
server_worlds = list(server_document.get("worlds", {}).keys())
|
||||
await inter.response.defer()
|
||||
async with httpx.AsyncClient() as client:
|
||||
#
|
||||
#Check if player is banned
|
||||
ban_response = await client.get(f'http://login.strongholdkingdoms.com/ajaxphp/username_search.php?term={player}')
|
||||
#
|
||||
#Collect world activity data
|
||||
activity_response = await client.get(f'https://shk.azure-api.net/shkinfo/v1/UserActivity?world={server_worlds[0]}&username={player}&Key={server_document["worlds"][server_worlds[0]]}&subscription-key=ff2e578e119348ea8b48a2acd2f5a48d')
|
||||
if activity_response.text == '01/Jan/0001 00:00:00':
|
||||
activity_date = None
|
||||
else:
|
||||
activity_date = datetime.datetime.strptime(activity_response.text,'%d/%b/%Y %H:%M:%S')
|
||||
shk_banned_data = ban_response.json()
|
||||
|
||||
if server_document is None: return await inter.send(ephemeral=True,content="Missing server setup, have you done the setup process?")
|
||||
#Collect info about the player
|
||||
if len(server_worlds) > 0:
|
||||
#
|
||||
#Collect house history
|
||||
house_data = await self.bot.database.house_history.find({"in_game_name": player, "world": server_worlds[0]}).to_list(length=None)
|
||||
#
|
||||
#Collect Relationships with the server
|
||||
target_list = [f"House {entry['house']}" for entry in house_data]
|
||||
target_list.append(player)
|
||||
relationships = await self.bot.database.relationships.find({ "$and" : [ { "$or" : [ { "world" : server_worlds[0] }, { "world" : { "$not" : { "$exists" : True } } }, { "world" : None } ] }, { "guild_id" : inter.guild_id }, { "target" : { "$in" : target_list } } ] }).to_list(length=None)
|
||||
#
|
||||
#Collect Intel data
|
||||
intel = await self.bot.database.intel_screenshots.find({"in_game_name": player, "added_by.discord_guild_id": inter.guild_id}).to_list(length=None)
|
||||
##
|
||||
##Collect VM data
|
||||
from_date = datetime(datetime.now().year - 1, 12, 15)
|
||||
to_date = datetime(datetime.now().year + 1, 1, 15)
|
||||
filter_query = {
|
||||
"added": {
|
||||
"$gte": from_date,
|
||||
"$lte": to_date
|
||||
},
|
||||
"guild_id": inter.guild_id,
|
||||
"in_game_name" : player
|
||||
}
|
||||
vm_entries = await self.bot.database.vm_entries.find(filter_query).to_list(length=None)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@check_player.autocomplete("player")
|
||||
async def autocomp_input(self, inter:disnake.ApplicationCommandInteraction,user_input:str):
|
||||
if len(user_input) == 0: return []
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(f'http://login.strongholdkingdoms.com/ajaxphp/username_search.php?term={user_input}')
|
||||
return response.json()
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_message_interaction(self,inter:disnake.MessageInteraction):
|
||||
pass
|
||||
|
||||
# States:
|
||||
# 0 - Overview
|
||||
# 1 - Castle Designs
|
||||
# 2 - House History
|
||||
# 3 - Bot Usage Stats
|
||||
def generate_overview_embed_and_components(id:int):
|
||||
pass
|
||||
|
||||
def setup(bot):
|
||||
logger.info(f"{__name__} Loaded")
|
||||
bot.add_cog(Check_Player(bot))
|
|
@ -0,0 +1,18 @@
|
|||
from disnake.ext import commands
|
||||
import disnake
|
||||
from main import StronkBot
|
||||
from loguru import logger
|
||||
|
||||
|
||||
class Vm_tracker(commands.Cog):
|
||||
def __init__(self,bot:StronkBot):
|
||||
self.bot = bot
|
||||
def cog_unload(self):
|
||||
logger.info(f"{__name__} Unloaded")
|
||||
self.getHouseData.cancel()
|
||||
|
||||
|
||||
|
||||
def setup(bot):
|
||||
logger.info(f"{__name__} Loaded")
|
||||
bot.add_cog(Vm_tracker(bot))
|
|
@ -0,0 +1,11 @@
|
|||
from disnake.ext import commands
|
||||
import disnake
|
||||
import db
|
||||
|
||||
class User_Manager(commands.Cog):
|
||||
@commands.Cog.listener() #Welcome Screen Listener
|
||||
async def on_message_interaction(self,inter:disnake.MessageInteraction):
|
||||
if not inter.component.custom_id.startswith("advert_welcome_"):
|
||||
return
|
||||
if inter.component.custom_id.partition("advert_welcome_")[2] == "social":
|
||||
pass
|
|
@ -0,0 +1,22 @@
|
|||
from disnake.ext import commands
|
||||
import disnake
|
||||
import db
|
||||
import httpx
|
||||
from datetime import datetime
|
||||
from loguru import logger
|
||||
import sb_utils
|
||||
import sb_emojis
|
||||
|
||||
class PTest(commands.Cog):
|
||||
def __init__(self,bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.slash_command()
|
||||
async def test(self,inter: disnake.ApplicationCommandInteraction):
|
||||
|
||||
user = await inter.bot.fetch_user(inter.author.id)
|
||||
await inter.send(user.banner)
|
||||
|
||||
def setup(bot):
|
||||
logger.info(f"{__name__} Loaded")
|
||||
bot.add_cog(PTest(bot))
|
|
@ -0,0 +1,195 @@
|
|||
from ast import match_case
|
||||
from urllib import response
|
||||
from disnake.ext import commands
|
||||
import disnake
|
||||
import db
|
||||
import requests
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
from loguru import logger
|
||||
|
||||
class Calculate_Time(commands.Cog):
|
||||
def __init__(self,bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.slash_command(description="Calculate your times like a pro")
|
||||
async def calculate_time(self,inter:disnake.ApplicationCommandInteraction):
|
||||
db.log_interaction(inter,f"Issued calculate_time")
|
||||
logger.info(f"{inter.author.display_name} Issued calculate time command")
|
||||
await inter.response.send_modal(timesModal())
|
||||
|
||||
@commands.Cog.listener()
|
||||
async def on_message_interaction(self,inter:disnake.MessageInteraction):
|
||||
if 'calc_time' in inter.component.custom_id:
|
||||
db.log_interaction(inter,f"Interracted with {inter.component.custom_id} on {inter.message.id}")
|
||||
match(inter.component.custom_id):
|
||||
case 'calc_time_delete':
|
||||
await inter.response.defer()
|
||||
await inter.message.delete()
|
||||
case 'calc_time_add':
|
||||
await inter.response.send_modal(timesModal(inter=inter))
|
||||
case 'calc_time_new':
|
||||
await inter.response.send_modal(timesModal())
|
||||
case 'calc_time_show_all':
|
||||
await inter.response.defer()
|
||||
await update_message(inter=inter,display_all_multipliers=True)
|
||||
case 'calc_time_multi':
|
||||
await inter.response.defer()
|
||||
with db.get_session()() as session:
|
||||
time_data_list = session.query(db.Time_Data).filter(db.Time_Data.message_id == inter.message.id).all()
|
||||
print(len(time_data_list))
|
||||
for t in time_data_list:
|
||||
t.multiplier = int(inter.values[0][1])
|
||||
session.commit()
|
||||
await update_message(inter=inter,time_data_list=time_data_list)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def calc_times_from_modal(time_string,multi:int):
|
||||
#Split times
|
||||
timeList = re.split(',| ',time_string)
|
||||
times = []
|
||||
try:
|
||||
for num,time_ in enumerate(timeList):
|
||||
if time_ == '':
|
||||
continue
|
||||
#Try and idiotproof some edge cases
|
||||
if time_.startswith((':',';','.')):
|
||||
temp_time = time_[1:]
|
||||
else:
|
||||
temp_time = time_
|
||||
modifier = 0
|
||||
if '|' in time_:
|
||||
temp = time_.split('|')
|
||||
name = temp[0]
|
||||
if name.startswith('>') or name.lower() == 'breaker':
|
||||
#Breaker
|
||||
if name.startswith('>'): name = name[1:]
|
||||
modifier = 10
|
||||
temp_time = temp[1]
|
||||
else:
|
||||
name = f'{num+1}'
|
||||
time_components = [int(s) for s in re.split('\:|\;|\.',temp_time)]
|
||||
time_components.reverse()
|
||||
seconds = 0
|
||||
for n,t in enumerate(time_components):
|
||||
seconds += t*60**n
|
||||
times.append({'name': name, 'seconds': seconds, 'multiplier': multi, 'modifier': modifier})
|
||||
return times
|
||||
except:
|
||||
return []
|
||||
|
||||
|
||||
class timesModal(disnake.ui.Modal):
|
||||
def __init__(self,multi=4,inter=None):
|
||||
self.inter = inter
|
||||
self.id = None
|
||||
if inter != None:
|
||||
self.id = inter.message.id
|
||||
components = [
|
||||
disnake.ui.TextInput(
|
||||
label="name|hh:mm:ss or hh:mm:ss can add multiple",
|
||||
placeholder="Times to convert",
|
||||
custom_id="times",
|
||||
required=True,
|
||||
),
|
||||
disnake.ui.TextInput(
|
||||
label="Time multiplier",
|
||||
placeholder="4",
|
||||
custom_id="multi_value",
|
||||
style= disnake.TextInputStyle.short,
|
||||
max_length=1,
|
||||
value = multi,
|
||||
),
|
||||
]
|
||||
super().__init__(
|
||||
title="Calculate attack times",
|
||||
custom_id="submit_calc",
|
||||
components=components
|
||||
)
|
||||
async def callback(self, interaction: disnake.ModalInteraction):
|
||||
if self.id:
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
else:
|
||||
await interaction.response.defer()
|
||||
times = interaction.text_values['times']
|
||||
multi = int(interaction.text_values['multi_value'])
|
||||
#do tests on times:
|
||||
times_list = calc_times_from_modal(times,multi)
|
||||
if times_list:
|
||||
#Store relevant info
|
||||
time_data_list = []
|
||||
if not self.id:
|
||||
message:disnake.Message = await interaction.followup.send("If you see this for long something went wrong")
|
||||
message_id = self.id or message.id
|
||||
with db.get_session()() as session:
|
||||
user:db.User = session.query(db.User).filter(db.User.discord_id == interaction.author.id).first()
|
||||
for t in times_list:
|
||||
time_data_list.append(db.Time_Data(message_id=message_id, user_id = user.id, **t))
|
||||
session.add_all(time_data_list)
|
||||
session.commit()
|
||||
if self.id != None:
|
||||
await update_message(inter=interaction,override_inter=self.inter)
|
||||
else:
|
||||
await update_message(inter=interaction,time_data_list=time_data_list)
|
||||
|
||||
else:
|
||||
await interaction.followup.send("Something went wrong.")
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
async def update_message(inter:disnake.ApplicationCommandInteraction,time_data_list=None,display_all_multipliers=False,override_inter=None):
|
||||
if not time_data_list:
|
||||
with db.get_session()() as session:
|
||||
time_data_list = session.query(db.Time_Data).filter(db.Time_Data.message_id == inter.message.id).all()
|
||||
if not time_data_list:
|
||||
await inter.followup.edit("No time data found")
|
||||
return
|
||||
time_data_list.sort(key=lambda y: y.seconds)
|
||||
time_data_list.reverse()
|
||||
|
||||
#Components
|
||||
components = [[],[]]
|
||||
components[0].append(disnake.ui.Select(placeholder="Change multiplier",options=["x2","x3","x4","x5","x6"],custom_id="calc_time_multi"))
|
||||
if len(time_data_list) == 1:
|
||||
components[1].append(disnake.ui.Button(label="Show All Multipliers", custom_id="calc_time_show_all"))
|
||||
components[1].append( disnake.ui.Button(label="Add time",custom_id="calc_time_add",style=disnake.ButtonStyle.green))
|
||||
components[1].append( disnake.ui.Button(label="Create New",custom_id="calc_time_new",style=disnake.ButtonStyle.green))
|
||||
components[1].append( disnake.ui.Button(label="Delete Message",custom_id="calc_time_delete",style=disnake.ButtonStyle.danger))
|
||||
#Embed
|
||||
embed = disnake.Embed()
|
||||
embed.title = "Time Converter"
|
||||
embed.set_author(name='Storm Brigade',icon_url='https://i.imgur.com/Opk3fCq.png')
|
||||
embed.description = "Modifies any times to the desired card level\n Useful for prepping times from monk speeds"
|
||||
|
||||
before_string = ""
|
||||
after_string = ""
|
||||
data: db.Time_Data
|
||||
if not display_all_multipliers:
|
||||
for data in time_data_list:
|
||||
emoji = '<:Captain:947543163608924181>'
|
||||
if data.modifier > 0:
|
||||
emoji = '<:Breaker:947543175025819709>'
|
||||
before_string += f"{emoji}**{data.name}**:{timedelta(seconds=data.seconds)} -**x{data.multiplier}**->\n"
|
||||
after_string += f"{timedelta(seconds=int(data.seconds/data.multiplier))}\n"
|
||||
else:
|
||||
for m in range(2,7):
|
||||
emoji = '<:Captain:947543163608924181>'
|
||||
before_string += f"{emoji}**{time_data_list[0].name}**:{timedelta(seconds=time_data_list[0].seconds)} -**x{m}**->\n"
|
||||
after_string += f"{timedelta(seconds=int(time_data_list[0].seconds/m))}\n"
|
||||
|
||||
embed.add_field(name="Original",value=before_string)
|
||||
embed.add_field(name="Modified",value=after_string)
|
||||
if override_inter != None:
|
||||
await inter.followup.send("Added to the list, this message is required for now, sorry. Just dismiss it :)")
|
||||
await override_inter.edit_original_message(content="",embed=embed,components=components)
|
||||
else:
|
||||
await inter.edit_original_message(content="",embed=embed,components=components)
|
||||
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Calculate_Time(bot))
|
|
@ -0,0 +1,68 @@
|
|||
from disnake.ext import commands
|
||||
import disnake
|
||||
import db
|
||||
import httpx
|
||||
from datetime import datetime
|
||||
from loguru import logger
|
||||
import sb_utils
|
||||
import sb_emojis
|
||||
|
||||
class Check_House(commands.Cog):
|
||||
def __init__(self,bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.slash_command(description="Look up Activity about a house")
|
||||
async def check_house(self, inter:disnake.ApplicationCommandInteraction,house=commands.Param(description="Which house?",choices=[str(x) for x in range(1,21)]),ban_check=commands.Param(description="Also check for bans? This will take a while, slowed down to avoid FF banning the bot",choices=["Yes","No"],default="No"),world:str = ""):
|
||||
logger.info(f"{inter.application_command.name} used by {inter.author} using {inter.filled_options}")
|
||||
await inter.response.defer(with_message=True,ephemeral=True)
|
||||
async with httpx.AsyncClient() as client:
|
||||
result = await client.get(f"https://shk.azure-api.net/shkinfo/v1/HouseActivity?world=World%202&house={house}&Key=5E78CFC8-1FFA-4036-8427-D94ED6E1A45B&subscription-key=ff2e578e119348ea8b48a2acd2f5a48d")
|
||||
house_players_activity = {}
|
||||
for player in result.json():
|
||||
banned = None
|
||||
vm = None
|
||||
if ban_check == "Yes":
|
||||
banned_result = await sb_utils.check_banned_player(session,client,player["Username"])
|
||||
banned = banned_result["banned"]
|
||||
house_players_activity[player["Username"]] = (max(datetime.strptime(player["MaxPersonTime"],"%Y-%m-%dT%H:%M:%S"),datetime.strptime(player["MaxTraderTime"],"%Y-%m-%dT%H:%M:%S")),(banned,vm))
|
||||
#Done with Httpx session
|
||||
house_result = session.query(db.House).filter(db.House.id == house).one_or_none()
|
||||
#Done with db session
|
||||
sorted_players = sorted(house_players_activity.items(), key=lambda x: x[1][0]) # Sort by least active
|
||||
embed = disnake.Embed(title=f"{house_result.emoji} House {house} Activity Report {house_result.emoji}")
|
||||
embed.description = f"Generated at: {disnake.utils.format_dt(disnake.utils.utcnow(),'D')}\nOnly tracks map activity, so if they're online and not scouting/trading etc this won't reflect that"
|
||||
embed.set_thumbnail(file=disnake.File(f"resources\house_sprites\{house}.png"))
|
||||
player_entries = [(f"**{player}** - {data[0].strftime('%d/%b/%Y %H:%M:%S')}\n",data[1]) for player,data in sorted_players]
|
||||
temp_value = ""
|
||||
for player_tuple in player_entries:
|
||||
if player_tuple[1][0] != None: #Banned has been set
|
||||
if player_tuple[1][0]:
|
||||
banned_emoji = sb_emojis.embed_fillers["banned"]
|
||||
else:
|
||||
banned_emoji = sb_emojis.embed_fillers["banned_before"]
|
||||
else:
|
||||
banned_emoji = sb_emojis.embed_fillers["no_data"]
|
||||
|
||||
if player_tuple[1][1] != None: #VM has been set
|
||||
if player_tuple[1][1]:
|
||||
vm_emoji = sb_emojis.embed_fillers["vm_active"]
|
||||
else:
|
||||
vm_emoji = sb_emojis.embed_fillers["vm_logged"]
|
||||
else:
|
||||
vm_emoji = sb_emojis.embed_fillers["no_data"]
|
||||
temp = f"{vm_emoji}{banned_emoji} {player_tuple[0]}"
|
||||
if "01/Jan/0001 00:00:00" in player_tuple[0]:
|
||||
temp = temp.replace("01/Jan/0001 00:00:00","**INACTIVE/RESET**")
|
||||
if len(temp_value)+len(temp) > 1024:
|
||||
if len(embed)+len(temp_value) > 6000:
|
||||
break
|
||||
embed.add_field(name='\u200b',value=temp_value,inline=False)
|
||||
temp_value = ''
|
||||
temp_value += temp
|
||||
embed.add_field(name='\u200b',value=temp_value,inline=False)
|
||||
embed.colour = disnake.Color(int(house_result.color,0))
|
||||
await inter.send("Here you go, blame discord for this dumb message...",delete_after=1)
|
||||
await inter.channel.send(embed=embed)
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Check_House(bot))
|
|
@ -0,0 +1,24 @@
|
|||
from disnake.ext import commands
|
||||
import disnake
|
||||
import db
|
||||
import httpx
|
||||
from datetime import datetime
|
||||
from loguru import logger
|
||||
import sb_utils
|
||||
import sb_emojis
|
||||
import csv
|
||||
from io import StringIO
|
||||
|
||||
class Parish_Intel(commands.Cog):
|
||||
def __init__(self,bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.slash_command()
|
||||
async def moon(self,inter):
|
||||
asd = disnake.Embed(title="KEK0")
|
||||
asd.set_image(file=disnake.File("0.png"))
|
||||
|
||||
def setup(bot):
|
||||
logger.info(f"{__name__} Loaded")
|
||||
bot.add_cog(Parish_Intel(bot))
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
from disnake.ext import commands
|
||||
import disnake
|
||||
import db
|
||||
import httpx
|
||||
from datetime import datetime
|
||||
from loguru import logger
|
||||
import sb_utils
|
||||
import sb_emojis
|
||||
import csv
|
||||
from io import StringIO
|
||||
from uuid import uuid4
|
||||
from embed_factory import castle_design_confirmation
|
||||
from os import makedirs
|
||||
|
||||
|
||||
class Player_Intel(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.slash_command()
|
||||
async def upload_castle(self, inter:disnake.ApplicationCommandInteraction,player: str, design: disnake.Attachment):
|
||||
if not design.content_type.startswith('image'):
|
||||
return await inter.send("You can only use this with pictures",ephemeral=True)
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(
|
||||
f"http://login.strongholdkingdoms.com/ajaxphp/username_search.php?term={player}"
|
||||
)
|
||||
response = response.json()
|
||||
if len(response) != 1:
|
||||
return await inter.send(f"Sorry, {player} could not be found or theres too many results, check spelling")
|
||||
|
||||
await inter.response.defer(ephemeral=True)
|
||||
|
||||
with db.get_session()() as session:
|
||||
player:db.Player = db.get_or_create(session,db.Player,player_name = player)[0]
|
||||
server:db.Server = db.get_or_create(session,db.Server,server_name = inter.guild.name,discord_guild_id = inter.guild.id)[0]
|
||||
file_name, ext = design.filename.split('.')
|
||||
path = f"castle_designs//{player.id}"
|
||||
makedirs(path)
|
||||
await design.save(f"{path}//{uuid4()}.{ext}")
|
||||
castle_design = db.Player_Castle_Designs(path=f"{path}//{uuid4()}.{ext}", player_id=player.id, server_id=server.id)
|
||||
session.add(castle_design)
|
||||
session.commit()
|
||||
target_advert = session.query(db.Advert).filter(db.Advert.server_id == server.id).filter(db.Advert.advert_type_id == 6).first()
|
||||
if not target_advert:
|
||||
await inter.send("There's not a castle_design channel for this server, so posting confirmation in this channel")
|
||||
await inter.channel.send(embed=castle_design_confirmation.generate_embed(design,player.player_name,inter.author.display_name),components=castle_design_confirmation.generate_buttons(inter.author.id))
|
||||
|
||||
|
||||
|
||||
@upload_castle.autocomplete("player")
|
||||
async def autocomp_input(
|
||||
self, inter: disnake.ApplicationCommandInteraction, user_input: str
|
||||
):
|
||||
if len(user_input) == 0:
|
||||
return []
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(
|
||||
f"http://login.strongholdkingdoms.com/ajaxphp/username_search.php?term={user_input}"
|
||||
)
|
||||
return response.json()
|
||||
|
||||
|
||||
def setup(bot):
|
||||
logger.info(f"{__name__} Loaded")
|
||||
bot.add_cog(Player_Intel(bot))
|
368
db.py
|
@ -1,145 +1,197 @@
|
|||
#! .\sbsheriff\scripts\python.exe
|
||||
import sqlalchemy as sqla
|
||||
import json
|
||||
from time import time
|
||||
import disnake
|
||||
from requests import session
|
||||
from sqlalchemy import Integer, create_engine, String, Column, ForeignKey,Table,Boolean,BigInteger,SmallInteger,DateTime,func
|
||||
from sqlalchemy.orm import declarative_base, relationship, scoped_session, sessionmaker
|
||||
import sqlite3
|
||||
from dotenv import load_dotenv
|
||||
from os import getenv
|
||||
|
||||
engine = sqla.create_engine('postgresql://strix:unnipus1213@192.168.1.2:5432/sbdb')
|
||||
load_dotenv(".env", override=True)
|
||||
|
||||
engine = create_engine(getenv("DB_CON"),pool_pre_ping=True)
|
||||
Base = declarative_base()
|
||||
Session = sessionmaker(engine)
|
||||
|
||||
class World(Base):
|
||||
__tablename__ = 'world'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
short_name = sqla.Column(sqla.String(50))
|
||||
world_name = sqla.Column(sqla.String(50))
|
||||
shk_id = sqla.Column(sqla.Integer)
|
||||
age = sqla.Column(sqla.Integer)
|
||||
ended = sqla.Column(sqla.Boolean)
|
||||
hoh_scraped = sqla.Column(sqla.Boolean)
|
||||
id = Column(Integer, primary_key=True)
|
||||
short_name = Column(String(50))
|
||||
world_name = Column(String(50))
|
||||
shk_id = Column(Integer)
|
||||
age = Column(Integer)
|
||||
ended = Column(Boolean)
|
||||
hoh_scraped = Column(Boolean)
|
||||
servers = relationship('Server',back_populates='worlds') #Checked
|
||||
hoh_entries = relationship('Hall_Of_Heroes',back_populates='world') #Checked
|
||||
house_histories = relationship('House_History',back_populates='world') #Checked
|
||||
parishes = relationship("Parish_Data",back_populates='world') #Checked
|
||||
|
||||
class Player(Base):
|
||||
__tablename__ = 'player'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
player_name = sqla.Column(sqla.String(100))
|
||||
user_id = sqla.Column(sqla.Integer,sqla.ForeignKey('user.id'))
|
||||
id = Column(Integer, primary_key=True)
|
||||
player_name = Column(String(100))
|
||||
user_id = Column(Integer,ForeignKey('user.id'))
|
||||
|
||||
user = relationship('User',back_populates='player') #Checked
|
||||
vm_entries = relationship('Vm_Entry',back_populates='player') #Checked
|
||||
hoh_entries = relationship("Hall_Of_Heroes",back_populates="player") #Checked
|
||||
house_history = relationship("House_History",back_populates="player") #Checked
|
||||
castle_designs = relationship("Player_Castle_Designs",back_populates="player") #Checked
|
||||
checks = relationship('Check_Player_Data',back_populates='player')
|
||||
world_data = relationship("WorldPlayerData",back_populates="player")#C
|
||||
|
||||
server_user = sqla.Table(
|
||||
class PlayerBan(Base):
|
||||
__tablename__ = "player_ban"
|
||||
id = Column(Integer,primary_key=True)
|
||||
player_id = Column(Integer,ForeignKey("player.id"))
|
||||
date_added = Column(DateTime,server_default=func.now())
|
||||
last_check = Column(DateTime,server_default=func.now())
|
||||
unbanned = Column(Boolean,default=False)
|
||||
permanent = Column(Boolean,default=False)
|
||||
|
||||
class BanTrackedHouse(Base):
|
||||
__tablename__ = "ban_tracked_house"
|
||||
id = Column(Integer,primary_key=True)
|
||||
house_id = Column(Integer,ForeignKey("house.id"))
|
||||
tracked_by_server_id = Column(Integer,ForeignKey("server.id"))
|
||||
|
||||
class BanTrackedPlayer(Base):
|
||||
__tablename__ = "ban_tracked_player"
|
||||
id = Column(Integer,primary_key=True)
|
||||
player_id = Column(Integer,ForeignKey("player.id"))
|
||||
tracked_by_server_id = Column(Integer,ForeignKey("server.id"))
|
||||
|
||||
server_user = Table(
|
||||
"association",
|
||||
Base.metadata,
|
||||
sqla.Column("server_id",sqla.ForeignKey("server.id")),
|
||||
sqla.Column("user_id",sqla.ForeignKey("user.id")),
|
||||
Column("server_id",ForeignKey("server.id")),
|
||||
Column("user_id",ForeignKey("user.id")),
|
||||
)
|
||||
|
||||
class WorldPlayerData(Base):
|
||||
__tablename__ = 'world_player_data'
|
||||
id = Column(Integer,primary_key=True)
|
||||
player_id = Column(Integer,ForeignKey("player.id"))
|
||||
world_id = Column(Integer,ForeignKey("world.id"))
|
||||
cp_rank = Column(Integer)
|
||||
player = relationship("Player",back_populates="world_data")#C
|
||||
|
||||
class Server(Base):
|
||||
__tablename__ = 'server'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
server_name = sqla.Column(sqla.Integer)
|
||||
discord_guild_id = sqla.Column(sqla.BigInteger,unique=True)
|
||||
world_id = sqla.Column(sqla.Integer,sqla.ForeignKey('world.id'))
|
||||
id = Column(Integer, primary_key=True)
|
||||
server_name = Column(String)
|
||||
discord_guild_id = Column(BigInteger,unique=True)
|
||||
world_id = Column(Integer,ForeignKey('world.id'))
|
||||
api_key = Column(String)
|
||||
|
||||
worlds = relationship("World",back_populates="servers") #Checked
|
||||
users = relationship("User",secondary=server_user,back_populates='servers') #Checked
|
||||
roles = relationship("Server_Roles", back_populates="server")
|
||||
adverts = relationship("Advert",back_populates="server")
|
||||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = 'user'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
discord_id = sqla.Column(sqla.BigInteger,unique=True)
|
||||
display_name = sqla.Column(sqla.String(50))
|
||||
id = Column(Integer, primary_key=True)
|
||||
discord_id = Column(BigInteger,unique=True)
|
||||
display_name = Column(String(50))
|
||||
servers = relationship("Server",secondary=server_user,back_populates='users') #Checked
|
||||
|
||||
#Parent in user prefferences relationship
|
||||
user_prefference = relationship("User_Prefference",back_populates="user",uselist=False) #Checked
|
||||
#Parent in user preferences relationship
|
||||
user_preference = relationship("User_Preference",back_populates="user",uselist=False) #Checked
|
||||
|
||||
#Parent in user player relationship
|
||||
player = relationship('Player',back_populates='user',uselist=False) #Checked
|
||||
|
||||
class User_Prefference(Base):
|
||||
__tablename__ = 'user_prefference'
|
||||
id = sqla.Column(sqla.Integer,primary_key=True)
|
||||
preffered_pikes = sqla.Column(sqla.Integer)
|
||||
preffered_archers = sqla.Column(sqla.Integer)
|
||||
user_id = sqla.Column(sqla.Integer,sqla.ForeignKey('user.id'))
|
||||
user = relationship('User',back_populates='user_prefference') #Checked
|
||||
parish_actions = relationship("Parish_Action",back_populates='user')
|
||||
time_data = relationship("Time_Data",back_populates='user')
|
||||
|
||||
class User_Preference(Base):
|
||||
__tablename__ = 'user_preference'
|
||||
id = Column(Integer,primary_key=True)
|
||||
preferred_pikes = Column(Integer)
|
||||
preferred_archers = Column(Integer)
|
||||
user_id = Column(Integer,ForeignKey('user.id'))
|
||||
user = relationship('User',back_populates='user_preference') #Checked
|
||||
|
||||
class Advert_Type(Base):
|
||||
__tablename__ = 'advert_type'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
advert_name = sqla.Column(sqla.String(50))
|
||||
id = Column(Integer, primary_key=True)
|
||||
advert_name = Column(String(50))
|
||||
adverts = relationship("Advert",back_populates="advert_type") #Checked
|
||||
|
||||
class Advert(Base):
|
||||
__tablename__ = 'advert'
|
||||
advert_id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
advert_type_id = sqla.Column(sqla.SmallInteger, sqla.ForeignKey("advert_type.id"))
|
||||
channel_id = sqla.Column(sqla.BigInteger)
|
||||
message_id = sqla.Column(sqla.BigInteger)
|
||||
advert_id = Column(Integer, primary_key=True)
|
||||
advert_type_id = Column(SmallInteger, ForeignKey("advert_type.id"))
|
||||
server_id = Column(Integer,ForeignKey('server.id'))
|
||||
channel_id = Column(BigInteger)
|
||||
message_id = Column(BigInteger)
|
||||
advert_type = relationship("Advert_Type",back_populates="adverts") #Checked
|
||||
server = relationship("Server",back_populates="adverts")
|
||||
|
||||
class Vm_Entry(Base):
|
||||
__tablename__ = 'vm_entry'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
added_by_user_id = sqla.Column(sqla.Integer, sqla.ForeignKey("user.id"))
|
||||
player_id = sqla.Column(sqla.Integer, sqla.ForeignKey("player.id"))
|
||||
server_id = sqla.Column(sqla.Integer, sqla.ForeignKey("server.id"))
|
||||
time_added = sqla.Column(sqla.Time)
|
||||
time_ended = sqla.Column(sqla.Time,nullable=True)
|
||||
id = Column(Integer, primary_key=True)
|
||||
added_by_user_id = Column(Integer, ForeignKey("user.id"))
|
||||
player_id = Column(Integer, ForeignKey("player.id"))
|
||||
server_id = Column(Integer, ForeignKey("server.id"))
|
||||
time_added = Column(DateTime,server_default=func.now())
|
||||
time_ended = Column(DateTime,nullable=True)
|
||||
player = relationship("Player",back_populates="vm_entries") #Checked
|
||||
|
||||
class House(Base):
|
||||
__tablename__ = 'house'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
color = sqla.Column(sqla.String)
|
||||
emoji = sqla.Column(sqla.String)
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String)
|
||||
color = Column(String)
|
||||
emoji = Column(String)
|
||||
relationships = relationship("House_Relationship",back_populates="house")
|
||||
|
||||
class Relationship_State(Base):
|
||||
__tablename__ = 'relationship_state'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
relationship_name = sqla.Column(sqla.String(50))
|
||||
alignment = sqla.Column(sqla.Integer)
|
||||
id = Column(Integer, primary_key=True)
|
||||
relationship_name = Column(String(50))
|
||||
alignment = Column(Integer)
|
||||
emoji = Column(String)
|
||||
house_relations = relationship('House_Relationship',back_populates='relationship_state') #Checked
|
||||
player_relations = relationship('Player_Relationship',back_populates='relationship_state')#Checked
|
||||
|
||||
class House_Relationship(Base):
|
||||
__tablename__ = 'house_relationship'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
id = Column(Integer, primary_key=True)
|
||||
|
||||
server_id = sqla.Column(sqla.Integer, sqla.ForeignKey("server.id"))
|
||||
house_id = sqla.Column(sqla.Integer, sqla.ForeignKey("house.id"))
|
||||
server_id = Column(Integer, ForeignKey("server.id"))
|
||||
house_id = Column(Integer, ForeignKey("house.id"))
|
||||
house = relationship("House",back_populates="relationships") #Checked
|
||||
relationship_state_id = sqla.Column(sqla.Integer, sqla.ForeignKey("relationship_state.id"))
|
||||
relationship_state_id = Column(Integer, ForeignKey("relationship_state.id"))
|
||||
relationship_state = relationship("Relationship_State",back_populates="house_relations") #Checked
|
||||
|
||||
class Player_Relationship(Base):
|
||||
__tablename__ = 'player_relationship'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
note = sqla.Column(sqla.String(100),nullable=True)
|
||||
id = Column(Integer, primary_key=True)
|
||||
note = Column(String(100),nullable=True)
|
||||
|
||||
server_id = sqla.Column(sqla.Integer, sqla.ForeignKey("server.id"))
|
||||
player_id = sqla.Column(sqla.Integer, sqla.ForeignKey("player.id"))
|
||||
relationship_state_id = sqla.Column(sqla.Integer, sqla.ForeignKey("relationship_state.id"))
|
||||
server_id = Column(Integer, ForeignKey("server.id"))
|
||||
player_id = Column(Integer, ForeignKey("player.id"))
|
||||
relationship_state_id = Column(Integer, ForeignKey("relationship_state.id"))
|
||||
relationship_state = relationship('Relationship_State',back_populates='player_relations')#Checked
|
||||
|
||||
class Hoh_Rank(Base):
|
||||
__tablename__ = 'hoh_rank'
|
||||
id = sqla.Column(sqla.Integer, primary_key=True)
|
||||
rank_name = sqla.Column(sqla.String(50))
|
||||
id = Column(Integer, primary_key=True)
|
||||
rank_name = Column(String(50))
|
||||
hoh_entries = relationship("Hall_Of_Heroes",back_populates="rank") #Checked
|
||||
|
||||
class Hall_Of_Heroes(Base):
|
||||
__tablename__ = 'hall_of_heroes'
|
||||
id = sqla.Column(sqla.Integer,primary_key=True)
|
||||
player_id = sqla.Column(sqla.Integer,sqla.ForeignKey('player.id'))
|
||||
hoh_rank_id = sqla.Column(sqla.Integer,sqla.ForeignKey('hoh_rank.id'))
|
||||
world_id = sqla.Column(sqla.Integer,sqla.ForeignKey('world.id'))
|
||||
id = Column(Integer,primary_key=True)
|
||||
player_id = Column(Integer,ForeignKey('player.id'))
|
||||
hoh_rank_id = Column(Integer,ForeignKey('hoh_rank.id'))
|
||||
world_id = Column(Integer,ForeignKey('world.id'))
|
||||
|
||||
#Parent in player hoh relationship
|
||||
player = relationship('Player',back_populates='hoh_entries') #Checked
|
||||
|
@ -148,39 +200,191 @@ class Hall_Of_Heroes(Base):
|
|||
|
||||
class Player_Castle_Designs(Base):
|
||||
__tablename__ = "player_castle_designs"
|
||||
id = sqla.Column(sqla.Integer,primary_key=True)
|
||||
path = sqla.Column(sqla.String)
|
||||
player_id = sqla.Column(sqla.Integer,sqla.ForeignKey("player.id"))
|
||||
server_id = sqla.Column(sqla.Integer,sqla.ForeignKey("server.id"))
|
||||
id = Column(Integer,primary_key=True)
|
||||
path = Column(String)
|
||||
player_id = Column(Integer,ForeignKey("player.id"))
|
||||
server_id = Column(Integer,ForeignKey("server.id"))
|
||||
validated = Column(Boolean,default=False)
|
||||
|
||||
player = relationship("Player", back_populates="castle_designs") #Checked
|
||||
server = relationship("Server") #Checked
|
||||
|
||||
class House_History(Base):
|
||||
__tablename__ = 'house_history'
|
||||
id = sqla.Column(sqla.Integer,primary_key=True)
|
||||
date = sqla.Column(sqla.Date)
|
||||
id = Column(Integer,primary_key=True)
|
||||
date = Column(DateTime)
|
||||
|
||||
player_id = sqla.Column(sqla.Integer,sqla.ForeignKey("player.id"))
|
||||
world_id = sqla.Column(sqla.Integer,sqla.ForeignKey("world.id"))
|
||||
house_id = sqla.Column(sqla.Integer,sqla.ForeignKey("house.id"))
|
||||
player_id = Column(Integer,ForeignKey("player.id"))
|
||||
world_id = Column(Integer,ForeignKey("world.id"))
|
||||
house_id = Column(Integer,ForeignKey("house.id"))
|
||||
player = relationship("Player",back_populates='house_history') #Checked
|
||||
world = relationship("World",back_populates='house_histories') #Checked
|
||||
house = relationship("House") #Checked
|
||||
|
||||
class Liegelord_Requests(Base):
|
||||
__tablename__ = 'liegelord_requests'
|
||||
id = sqla.Column(sqla.Integer,primary_key=True)
|
||||
village_id = sqla.Column(sqla.SmallInteger)
|
||||
confirm_message_id = sqla.Column(sqla.BigInteger)
|
||||
id = Column(Integer,primary_key=True)
|
||||
village_id = Column(SmallInteger)
|
||||
confirm_message_id = Column(BigInteger)
|
||||
|
||||
server_id = sqla.Column(sqla.Integer,sqla.ForeignKey("server.id"))
|
||||
request_user_id = sqla.Column(sqla.Integer,sqla.ForeignKey('user.id'))
|
||||
fulfilled_user_id = sqla.Column(sqla.Integer,sqla.ForeignKey('user.id'))
|
||||
server_id = Column(Integer,ForeignKey("server.id"))
|
||||
request_user_id = Column(Integer,ForeignKey('user.id'))
|
||||
fulfilled_user_id = Column(Integer,ForeignKey('user.id'))
|
||||
server = relationship("Server") #Checked
|
||||
request_user = relationship("User",foreign_keys=[request_user_id])
|
||||
fulfilled_user= relationship("User",foreign_keys=[fulfilled_user_id])
|
||||
|
||||
def create_session():
|
||||
session = scoped_session(sessionmaker(bind=engine))
|
||||
return session
|
||||
class Parish_Data(Base):
|
||||
__tablename__ = 'parish_data'
|
||||
id = Column(Integer,primary_key=True)
|
||||
parish_id = Column(Integer)
|
||||
parish_name = Column(String)
|
||||
world_id = Column(Integer,ForeignKey('world.id'))
|
||||
|
||||
world = relationship("World",back_populates='parishes') #Checked
|
||||
actions = relationship("Parish_Action",back_populates='parish') #Checked
|
||||
|
||||
class Parish_Action(Base):
|
||||
__tablename__ = 'parish_action'
|
||||
id = Column(Integer,primary_key=True)
|
||||
parish_id = Column(Integer,ForeignKey('parish_data.id'))
|
||||
performed_by_user_id = Column(Integer,ForeignKey('user.id'))
|
||||
performed_at = Column(DateTime,server_default=func.now())
|
||||
building_id = Column(Integer,ForeignKey('parish_building.id'))
|
||||
|
||||
|
||||
parish = relationship("Parish_Data",back_populates = 'actions') #Checked
|
||||
building = relationship("Parish_Building",back_populates='actions') #Checked
|
||||
user = relationship("User",back_populates='parish_actions') #Checked
|
||||
|
||||
class Parish_Building(Base):
|
||||
__tablename__ = 'parish_building'
|
||||
id = Column(Integer,primary_key=True)
|
||||
name = Column(String)
|
||||
actions = relationship("Parish_Action",back_populates='building') #checked
|
||||
|
||||
class User_Interaction(Base):
|
||||
__tablename__ = "user_interaction"
|
||||
id = Column(Integer,primary_key=True)
|
||||
date = Column(DateTime,server_default=func.now())
|
||||
action = Column(String)
|
||||
user_id = Column(Integer,ForeignKey("user.id"))
|
||||
server_id = Column(Integer,ForeignKey("server.id"))
|
||||
|
||||
class Time_Data(Base):
|
||||
__tablename__ = 'time_data'
|
||||
id = Column(Integer,primary_key = True)
|
||||
message_id = Column(BigInteger)
|
||||
name = Column(String)
|
||||
seconds = Column(Integer)
|
||||
multiplier = Column(Integer)
|
||||
modifier = Column(Integer)
|
||||
user_id = Column(Integer,ForeignKey('user.id'))
|
||||
|
||||
user = relationship("User",back_populates='time_data')
|
||||
|
||||
class Check_Player_Data(Base):
|
||||
__tablename__ = 'check_player_data'
|
||||
id = Column(Integer,primary_key = True)
|
||||
player_id = Column(Integer,ForeignKey('player.id'))
|
||||
|
||||
player = relationship('Player',back_populates='checks')
|
||||
|
||||
class AI(Base):
|
||||
__tablename__ = 'ai'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String)
|
||||
|
||||
class AI_Castle(Base):
|
||||
__tablename__ = 'ai_castle'
|
||||
id = Column(Integer, primary_key=True)
|
||||
ai_id = Column(Integer, ForeignKey('ai.id'))
|
||||
ai_level = Column(Integer)
|
||||
archers = Column(Integer)
|
||||
pikemen = Column(Integer)
|
||||
catapults = Column(Integer)
|
||||
swordmen = Column(Integer)
|
||||
captains = Column(Integer)
|
||||
parish_compatible = Column(Boolean)
|
||||
img_path = Column(String)
|
||||
|
||||
class Role_Type(Base):
|
||||
__tablename__ = 'role_type'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String)
|
||||
|
||||
class Server_Roles(Base):
|
||||
__tablename__ = 'server_roles'
|
||||
id = Column(Integer, primary_key=True)
|
||||
server_id = Column(Integer, ForeignKey('server.id'))
|
||||
role_type_id = Column(Integer, ForeignKey('role_type.id'))
|
||||
discord_role_id = Column(BigInteger)
|
||||
|
||||
server = relationship("Server",back_populates="roles")
|
||||
|
||||
|
||||
|
||||
|
||||
def get_session():
|
||||
return Session
|
||||
|
||||
def log_interaction(inter:disnake.ApplicationCommandInteraction,action:str):
|
||||
with Session() as session:
|
||||
#Get or Create User
|
||||
user = session.query(User).filter(User.discord_id==inter.author.id).first()
|
||||
server = session.query(Server).filter(Server.discord_guild_id==inter.guild_id).first()
|
||||
if user == None:
|
||||
#Create user object and assosiate with server
|
||||
print(f"adding new user to database -> {inter.author.display_name}")
|
||||
user = User(display_name=inter.author.display_name,discord_id=inter.author.id)
|
||||
session.add(user)
|
||||
session.commit()
|
||||
if not server in user.servers:
|
||||
print(f"associating new user to server -> {inter.author.display_name} -> {inter.guild.name}")
|
||||
user.servers.append(server)
|
||||
interaction = User_Interaction(user_id=user.id,server_id=server.id,action=action)
|
||||
session.add(interaction)
|
||||
session.commit()
|
||||
|
||||
def add_players_from_search(json:dict):
|
||||
with Session() as session:
|
||||
for entry in json:
|
||||
player = session.query(Player).filter(Player.player_name==entry).first()
|
||||
if player == None:
|
||||
player = Player(player_name=entry)
|
||||
session.add(player)
|
||||
session.commit()
|
||||
|
||||
def get_or_create(session, model, defaults=None, **kwargs):
|
||||
instance = session.query(model).filter_by(**kwargs).one_or_none()
|
||||
if instance:
|
||||
return instance, False
|
||||
else:
|
||||
kwargs |= defaults or {}
|
||||
instance = model(**kwargs)
|
||||
try:
|
||||
session.add(instance)
|
||||
session.commit()
|
||||
except Exception:
|
||||
session.rollback()
|
||||
instance = session.query(model).filter_by(**kwargs).one()
|
||||
return instance, False
|
||||
else:
|
||||
return instance, True
|
||||
|
||||
def get_adverts():
|
||||
with Session() as session:
|
||||
return session.query(Advert_Type).all()
|
||||
|
||||
def get_advert_type_by_name(name: str):
|
||||
with Session() as session:
|
||||
advert_id = session.query(Advert_Type).filter_by(advert_name=name).one_or_none()
|
||||
if advert_id:
|
||||
return advert_id.id
|
||||
else:
|
||||
return None
|
||||
def get_ai_castles(ai_id: int):
|
||||
with Session() as session:
|
||||
return session.query(AI_Castle).filter(AI_Castle.ai_id == ai_id).all()
|
||||
|
||||
#Base.metadata.create_all(bind=engine)
|
|
@ -0,0 +1,13 @@
|
|||
import disnake
|
||||
from embed_factory import embeds
|
||||
|
||||
def generate_embed(attachment:disnake.Attachment,player_name,author_name):
|
||||
embed = embeds.base_embed()
|
||||
embed.set_image(attachment.to_file())
|
||||
embed.description = f"{author_name} submits this design for {player_name}"
|
||||
return embed
|
||||
|
||||
def generate_buttons(author_id):
|
||||
confirm = disnake.ui.Button(label="Confirm Submission",emoji="✅",style=disnake.ButtonStyle.green,custom_id=f"cdc-confirm-{author_id}")
|
||||
delete = disnake.ui.Button(label="Delete",emoji="❌",style=disnake.ButtonStyle.red,custom_id="cdc-delete")
|
||||
return [confirm,delete]
|
|
@ -0,0 +1,6 @@
|
|||
import disnake
|
||||
import sqlalchemy.orm
|
||||
class Overview(disnake.Embed):
|
||||
def __init__(self, session:sqlalchemy.orm.session, target_player_id:int):
|
||||
|
||||
super().__init__(title=f"{2+2}")
|
|
@ -0,0 +1,19 @@
|
|||
import disnake
|
||||
import httpx
|
||||
|
||||
class base_embed(disnake.Embed):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.set_footer(text="Provided by Storm Brigade",icon_url='https://i.imgur.com/Opk3fCq.png')
|
||||
#self.set_author(name='Storm Brigade',icon_url='https://i.imgur.com/Opk3fCq.png')
|
||||
self.set_thumbnail(file=disnake.File("resources\StormBrigade_White.png"))
|
||||
|
||||
async def add_player_shield(self,in_game_name:str):
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(f"https://login.strongholdkingdoms.com/ajaxphp/get_shield_url.php?username={in_game_name}&transparent=1")
|
||||
response_json = response.json()
|
||||
if response_json.get("url", None) is not None:
|
||||
self.set_thumbnail(url=response_json.get("url"))
|
||||
return self
|
||||
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
import disnake
|
||||
from embed_factory import embeds
|
||||
import sb_emojis
|
||||
from datetime import datetime, timedelta
|
||||
from main import StronkBot
|
||||
|
||||
def generate_embed(bot:StronkBot, guild_id:int, vm_entries:dict,house_data:dict,relations:dict):
|
||||
embed = embeds.base_embed()
|
||||
embed.title = f"VM tracker"
|
||||
embed.description = f"Players currently on VM\n Use </report_vm:{bot.get_global_command_named('report_vm').id}> to add more"
|
||||
|
||||
vm_names = [entry["in_game_name"] for entry in vm_entries]
|
||||
|
||||
if len(vm_entries) == 0: return embed
|
||||
entry_list = []
|
||||
for entry in vm_entries:
|
||||
if entry.get("finished"): continue
|
||||
vm_num = '<:SecondVm:1020804212399018157>' if vm_names.count(entry["in_game_name"]) > 1 else '<:no_data:1020809240648101978>'
|
||||
house_emoji = '<:no_data:1020809240648101978>' if house_data.get(entry["in_game_name"]) is None else sb_emojis.houseEmojis.get(house_data.get(entry["in_game_name"]).get("house"))
|
||||
#Check relationships
|
||||
relation_state = None
|
||||
if house_data.get(entry["in_game_name"]) is not None:
|
||||
relation_state = relations.get(f"House {house_data.get(entry['in_game_name']).get('house')}")
|
||||
|
||||
if relation_state is None: relation_state = relations.get(entry["in_game_name"])
|
||||
relationship_emoji = '<:no_data:1020809240648101978>' if relation_state is None else sb_emojis.relationshipEmojis.get(relation_state) or '<:no_data:1020809240648101978>'
|
||||
entry_list.append( f"{relationship_emoji}{house_emoji}{vm_num}{entry['in_game_name']}:{disnake.utils.format_dt(entry.get('added')+ timedelta(days=15), style='R')}\n")
|
||||
|
||||
temp_value = ''
|
||||
for vm_entry in entry_list:
|
||||
if len(temp_value)+len(vm_entry) > 1024:
|
||||
if len(embed)+len(temp_value) > 6000:
|
||||
print("embed is going to be too large lol")
|
||||
break
|
||||
embed.add_field(name='\u200b',value=temp_value,inline=False)
|
||||
temp_value = ''
|
||||
temp_value += vm_entry
|
||||
embed.add_field(name='\u200b',value=temp_value,inline=False)
|
||||
return embed
|
||||
|
||||
def generate_components():
|
||||
return [disnake.ui.Button(label="Remove VM", emoji="➖", custom_id="vm_tracker.spawn_remove")]
|
||||
|
||||
def vm_advert(gID = None):
|
||||
embed = disnake.Embed(title="VM tracker",description = "Players currently on VM")
|
||||
embed.set_author(name='Storm Brigade',icon_url='https://i.imgur.com/Opk3fCq.png')
|
||||
if gID == None:
|
||||
return embed
|
||||
#Cleanup expired vm's
|
||||
exired_vms = helpers.sql_get('SELECT name,added FROM vm_entries WHERE gID = {gID} AND added < unixepoch("now","-15 days") AND finished IS NULL'.format(gID=gID))
|
||||
vm_length = 1296000
|
||||
if len(exired_vms) > 0:
|
||||
for vm in exired_vms:
|
||||
helpers.sql_set("UPDATE vm_entries SET finished = ? WHERE gID = ? AND name = ? AND added = ?",(vm[1]+vm_length,gID,vm[0],vm[1]))
|
||||
|
||||
#print(exired_vms)
|
||||
from_date = int(datetime.datetime.fromisoformat("{YYYY}-12-15".format(YYYY=datetime.date.today().year-1)).timestamp())
|
||||
to_date = int(datetime.datetime.fromisoformat("{YYYY}-01-15".format(YYYY=datetime.date.today().year+1)).timestamp())
|
||||
#print("SELECT vm_entries.name,vm_entries.added,house.house FROM vm_entries INNER JOIN house ON LOWER(vm_entries.name) = LOWER(house.username) WHERE vm_entries.added BETWEEN {start} AND {end} AND vm_entries.finished IS NULL".format(start=from_date,end=to_date))
|
||||
query_result = helpers.sql_get("SELECT vm_entries.name,vm_entries.added,house.house FROM vm_entries LEFT JOIN house ON LOWER(vm_entries.name) = LOWER(house.username) AND house.date > unixepoch('now','-6 hours') WHERE vm_entries.added BETWEEN {start} AND {end} AND vm_entries.finished IS NULL ORDER BY added ASC".format(start=from_date,end=to_date),True)
|
||||
house_json = json.loads(helpers.sql_get("SELECT relationships FROM guild WHERE gID = {gID}".format(gID = gID))[0][0])
|
||||
if len(query_result) > 0:
|
||||
vm_entries = []
|
||||
for entry in query_result:
|
||||
vm_num = '<:no_data:1020809240648101978>'
|
||||
vm_info = helpers.sql_get(f"SELECT added FROM vm_entries WHERE LOWER(name) = LOWER('{entry['name']}') AND added BETWEEN {from_date} AND {to_date}")
|
||||
if len(vm_info) > 1:
|
||||
vm_num = '<:SecondVm:1020804212399018157>'
|
||||
house_emoji = '<:no_data:1020809240648101978>'
|
||||
relationship_emoji = '<:no_data:1020809240648101978>'
|
||||
if str(entry['house']) in house_json.keys():
|
||||
relationship_emoji = botOptions.relationshipEmojis[house_json[str(entry['house'])]]
|
||||
if entry['house'] != None:
|
||||
house_emoji = botOptions.houseEmojis[entry['house']]
|
||||
vm_entries.append( "{relationship}{house}{num}{name}:<t:{time_remaining}:R>\n".format(relationship= relationship_emoji,num=vm_num,house=house_emoji,name=entry['name'],time_remaining=entry['added']+vm_length))
|
||||
temp_value = ''
|
||||
for vm_entry in vm_entries:
|
||||
if len(temp_value)+len(vm_entry) > 1024:
|
||||
if len(embed)+len(temp_value) > 6000:
|
||||
print("embed is going to be too large lol")
|
||||
break
|
||||
embed.add_field(name='\u200b',value=temp_value,inline=False)
|
||||
temp_value = ''
|
||||
temp_value += vm_entry
|
||||
embed.add_field(name='\u200b',value=temp_value,inline=False)
|
||||
#print(len(embed))
|
||||
return embed
|
|
@ -0,0 +1,87 @@
|
|||
from pymongo import MongoClient
|
||||
import sqlite3
|
||||
import json
|
||||
from datetime import datetime
|
||||
import requests
|
||||
|
||||
# Connect to SQLite
|
||||
sqlite_conn = sqlite3.connect('sbsheriff.sqlite')
|
||||
sqlite_conn.row_factory = sqlite3.Row
|
||||
sqlite_cursor = sqlite_conn.cursor()
|
||||
|
||||
# Connect to MongoDB
|
||||
mongo_client = MongoClient('mongodb://sheriff:unnipus1213@192.168.1.109:27017/?retryWrites=true&serverSelectionTimeoutMS=5000&connectTimeoutMS=10000&authSource=stormbrigade&authMechanism=SCRAM-SHA-256')
|
||||
mongo_db = mongo_client['stormbrigade']
|
||||
mongo_collection = mongo_db['intel_screenshots']
|
||||
|
||||
# Fetch data from SQLite table
|
||||
sqlite_cursor.execute("SELECT gID, name, castle_designs, attack_designs FROM players")
|
||||
rows = sqlite_cursor.fetchall()
|
||||
|
||||
|
||||
# Iterate over the rows and migrate data to MongoDB
|
||||
for row in rows:
|
||||
|
||||
username = row['name']
|
||||
guild_id = row['gID']
|
||||
castle_design_json = row['castle_designs']
|
||||
attack_design_json = row['attack_designs']
|
||||
|
||||
# Convert house_history JSON to Python dictionary
|
||||
castle_dict = json.loads(castle_design_json)
|
||||
attack_dict = json.loads(attack_design_json)
|
||||
#print(castle_dict)
|
||||
# Iterate over house_history elements and upsert to MongoDB
|
||||
|
||||
player_doc = mongo_db.players.find_one(filter={"in_game_name": {"$regex": f"^{username}$", "$options": "i"}})
|
||||
if player_doc is None:
|
||||
player_doc = {}
|
||||
r = requests.get(f'http://login.strongholdkingdoms.com/ajaxphp/username_search.php?term={username}').json()
|
||||
if len(r) > 0:
|
||||
player_doc["in_game_name"] = r[0]
|
||||
else:
|
||||
print(username, len(castle_dict))
|
||||
continue
|
||||
#print(player_doc)
|
||||
|
||||
for filename in castle_dict.keys():
|
||||
filter_query = {
|
||||
"in_game_name": player_doc["in_game_name"],
|
||||
"added_by" : {
|
||||
"added_by_discord_id": 0,
|
||||
"added_by_discord_name": "Old Submission",
|
||||
"added_by_discord_server_id": 947398173805133834,
|
||||
},
|
||||
"type": "castle",
|
||||
"filename": filename
|
||||
}
|
||||
update_query = {
|
||||
"$set": {
|
||||
"filename": filename
|
||||
}
|
||||
}
|
||||
mongo_collection.update_one(filter_query, update_query, upsert=True)
|
||||
for filename in attack_dict.keys():
|
||||
filter_query = {
|
||||
"in_game_name": player_doc["in_game_name"],
|
||||
"added_by" : {
|
||||
"added_by_discord_id": 0,
|
||||
"added_by_discord_name": "Old Submission",
|
||||
"added_by_discord_server_id": 947398173805133834,
|
||||
},
|
||||
"type": "attack",
|
||||
"filename": filename
|
||||
}
|
||||
update_query = {
|
||||
"$set": {
|
||||
"filename": filename
|
||||
}
|
||||
}
|
||||
mongo_collection.update_one(filter_query, update_query, upsert=True)
|
||||
# Perform the upsert operation
|
||||
|
||||
|
||||
# Close connections
|
||||
sqlite_cursor.close()
|
||||
sqlite_conn.close()
|
||||
mongo_client.close()
|
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.4 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.4 MiB |
After Width: | Height: | Size: 2.5 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.2 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.4 MiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 2.1 MiB |
After Width: | Height: | Size: 2.5 MiB |