def test_setter(self): cache = Cacher() pairs = {} for _ in range(test_count): random_key = self.get_random_generator()() random_val = self.get_random_generator()() cache.set_cache(random_key, random_val) pairs.update({random_key: random_val}) for pair in pairs.keys(): assert cache.get_cache(pair) == pairs.get(pair)
def test_deleter(self): cache = Cacher() keys = [] for _ in range(test_count): random_key = self.get_random_generator()() random_val = self.get_random_generator()() cache.set_cache(random_key, random_val) keys.append(random_key) for key in keys: cache.del_cache(key) assert cache.get_cache(key) is None assert cache.data == {}
class CooldownControl(object): def __init__(self, bot): self.bot = bot self.db = self.bot.db self.cache = Cacher() self.cds = self.db[self.bot.cfg.db.database].CooldownSystem async def cache_cooldowns(self): cooldowns = await self.cds.find({}).to_list(None) for cooldown in cooldowns: self.cache.set_cache(cooldown.get('name'), cooldown) self.bot.log.info(f'Finished pre-caching {len(cooldowns)} cooldowns.') async def on_cooldown(self, cmd, user): if isinstance(user, str): cd_name = f'cd_{cmd}_{user}' else: cd_name = f'cd_{cmd}_{user.id}' entry = self.cache.get_cache(cd_name) if entry is None: entry = await self.cds.find_one({'name': cd_name}) self.cache.set_cache(cd_name, entry) if entry: end_stamp = entry['end_stamp'] now_stamp = arrow.utcnow().timestamp if now_stamp > end_stamp: cooldown = False else: cooldown = True else: cooldown = False return cooldown async def get_cooldown(self, cmd, user): if isinstance(user, str): cd_name = f'cd_{cmd}_{user}' else: cd_name = f'cd_{cmd}_{user.id}' entry = self.cache.get_cache(cd_name) if entry is None: entry = await self.cds.find_one({'name': cd_name}) self.cache.set_cache(cd_name, entry) if entry: end_stamp = entry['end_stamp'] now_stamp = arrow.utcnow().float_timestamp cooldown = end_stamp - now_stamp if cooldown < 2: if cooldown <= 0: cooldown = 0.01 else: cooldown = round(cooldown, 2) else: cooldown = int(cooldown) else: cooldown = 0 return cooldown async def set_cooldown(self, cmd, user, amount): if isinstance(user, str): cd_name = f'cd_{cmd}_{user}' else: if user.id in self.bot.cfg.dsc.owners: amount = 0 cd_name = f'cd_{cmd}_{user.id}' entry = await self.cds.find_one({'name': cd_name}) end_stamp = arrow.utcnow().timestamp + amount if entry: await self.cds.update_one({'name': cd_name}, {'$set': { 'end_stamp': end_stamp }}) else: cd_data = {'name': cd_name, 'end_stamp': end_stamp} await self.cds.insert_one(cd_data) self.cache.del_cache(cd_name)
def test_getter(self): cache = Cacher() assert cache.get_cache(self.get_random_generator()()) is None
class Database(motor.AsyncIOMotorClient): def __init__(self, bot, db_cfg: DatabaseConfig): self.bot = bot self.db_cfg = db_cfg self.db_nam = self.db_cfg.database self.cache = Cacher() if self.db_cfg.auth: self.db_address = f'mongodb://{self.db_cfg.username}:{self.db_cfg.password}' self.db_address += f'@{self.db_cfg.host}:{self.db_cfg.port}/' else: self.db_address = f'mongodb://{self.db_cfg.host}:{self.db_cfg.port}/' super().__init__(self.db_address) async def get_prefix(self, message: discord.Message): prefix = self.bot.cfg.pref.prefix if message.guild: pfx_search = await self.get_guild_settings(message.guild.id, 'prefix') if pfx_search: prefix = pfx_search return prefix async def precache_settings(self): self.bot.log.info('Pre-Caching all guild settings...') all_settings = await self[self.db_cfg.database].ServerSettings.find({}).to_list(None) for setting_file in all_settings: guild_id = setting_file.get('server_id') if guild_id: self.cache.set_cache(guild_id, setting_file) self.bot.log.info(f'Finished pre-caching {len(all_settings)} guild settings.') async def get_guild_settings(self, guild_id, setting_name): guild_settings = self.cache.get_cache(guild_id) if guild_settings is None: guild_settings = await self[self.bot.cfg.db.database].ServerSettings.find_one({'server_id': guild_id}) or {} self.cache.set_cache(guild_id, guild_settings) if not guild_settings: setting_value = None else: setting_value = guild_settings.get(setting_name) return setting_value async def set_guild_settings(self, guild_id, setting_name, value): guild_settings = await self[self.bot.cfg.db.database].ServerSettings.find_one({'server_id': guild_id}) if guild_settings: update_target = {"server_id": guild_id} update_data = {"$set": {setting_name: value}} await self[self.bot.cfg.db.database].ServerSettings.update_one(update_target, update_data) else: update_data = {'server_id': guild_id, setting_name: value} await self[self.bot.cfg.db.database].ServerSettings.insert_one(update_data) self.cache.del_cache(guild_id) async def get_experience(self, user, guild): collection = self[self.bot.cfg.db.database].ExperienceSystem entry = await collection.find_one({'user_id': user.id}) or {} global_xp = entry.get('global', 0) guild_id = str(guild.id) guilds = entry.get('guilds', {}) guild_xp = guilds.get(guild_id, 0) total_xp = entry.get('total', 0) output = {'global': global_xp, 'guild': guild_xp, 'total': total_xp} return output async def add_experience(self, user, guild, points, additive=True): sabotage_file = await self[self.db_cfg.database].SabotagedUsers.find_one({'user_id': user.id}) if not sabotage_file: collection = self[self.bot.cfg.db.database].ExperienceSystem entry = await collection.find_one({'user_id': user.id}) or {} if not entry: await collection.insert_one({'user_id': user.id}) total_xp = entry.get('total', 0) global_xp = entry.get('global', 0) guilds = entry.get('guilds', {}) guild_id = str(guild.id) guild_points = guilds.get(guild_id, 0) if additive: global_xp += points guild_points += points total_xp += points guild_data = {guild_id: guild_points} guilds.update(guild_data) xp_data = {'global': global_xp, 'guilds': guilds, 'total': total_xp} update_target = {'user_id': user.id} update_data = {'$set': xp_data} await collection.update_one(update_target, update_data) async def get_currency(self, user, guild): collection = self[self.bot.cfg.db.database].CurrencySystem entry = await collection.find_one({'user_id': user.id}) or {} global_amount = entry.get('global', 0) current_amount = entry.get('current', 0) guild_id = str(guild.id) guilds = entry.get('guilds', {}) guild_amount = guilds.get(guild_id, 0) total_amount = entry.get('total', 0) output = {'current': current_amount, 'global': global_amount, 'guild': guild_amount, 'total': total_amount} return output async def add_currency(self, user, guild, points, additive=True): sabotage_file = await self[self.db_cfg.database].SabotagedUsers.find_one({'user_id': user.id}) if not sabotage_file: collection = self[self.bot.cfg.db.database].CurrencySystem points = abs(points) entry = await collection.find_one({'user_id': user.id}) or {} if not entry: await collection.insert_one({'user_id': user.id}) current_amount = entry.get('current', 0) global_amount = entry.get('global', 0) total_amount = entry.get('total', 0) guilds = entry.get('guilds', {}) guild_id = str(guild.id) guild_points = guilds.get(guild_id, 0) if additive: global_amount += points guild_points += points total_amount += points current_amount += points guild_data = {guild_id: guild_points} guilds.update(guild_data) xp_data = {'current': current_amount, 'global': int(global_amount), 'guilds': guilds, 'total': total_amount} update_target = {'user_id': user.id} update_data = {'$set': xp_data} await collection.update_one(update_target, update_data) async def rmv_currency(self, user, points): collection = self[self.bot.cfg.db.database].CurrencySystem points = abs(points) entry = await collection.find_one({'user_id': user.id}) or {} if not entry: await collection.insert_one({'user_id': user.id}) current_amount = entry.get('current', 0) current_amount -= points xp_data = {'current': current_amount} update_target = {'user_id': user.id} update_data = {'$set': xp_data} await collection.update_one(update_target, update_data) async def get_inventory(self, user): inventory = await self[self.db_cfg.database].Inventory.find_one({'user_id': user.id}) or {} if not inventory: await self[self.db_cfg.database].Inventory.insert_one({'user_id': user.id, 'items': []}) inventory = inventory.get('items', []) return inventory async def update_inv(self, user, inv): await self[self.db_cfg.database].Inventory.update_one({'user_id': user.id}, {'$set': {'items': inv}}) async def add_to_inventory(self, user, item_data): sabotage_file = await self[self.db_cfg.database].SabotagedUsers.find_one({'user_id': user.id}) if not sabotage_file: stamp = arrow.utcnow().timestamp item_data.update({'timestamp': stamp}) inv = await self.get_inventory(user) inv.append(item_data) await self.update_inv(user, inv) async def del_from_inventory(self, user, item_id): inv = await self.get_inventory(user) for item in inv: if item.get('item_id') == item_id: inv.remove(item) await self.update_inv(user, inv) async def get_inventory_item(self, user, item_file_id): inv = await self.get_inventory(user) output = None for item in inv: if item.get('item_file_id').lower() == item_file_id.lower(): output = item break return output
class ApexSigma(client_class): def __init__(self): super().__init__() self.ready = False # State attributes before initialization. self.log = None self.cfg = None self.db = None self.cool_down = None self.music = None self.modules = None self.queue = ExecutionClockwork(self) self.cache = Cacher() # Initialize startup methods and attributes. self.create_cache() self.init_logger() self.log.info('---------------------------------') self.init_config() self.log.info('---------------------------------') self.loop.run_until_complete(self.init_database()) self.log.info('---------------------------------') self.init_cool_down() self.log.info('---------------------------------') self.init_music() self.log.info('---------------------------------') self.info = Information() self.init_modules(init=True) self.start_time = arrow.utcnow() self.message_count = 0 self.command_count = 0 @staticmethod def create_cache(): if os.path.exists('cache'): shutil.rmtree('cache') os.makedirs('cache') def init_logger(self): self.log = create_logger('Sigma') self.log.info('Logger Created') def init_config(self): self.log.info('Loading Configuration...') self.cfg = init_cfg self.log.info(f'Running as a Bot: {self.cfg.dsc.bot}') self.log.info(f'Default Bot Prefix: {self.cfg.pref.prefix}') self.log.info('Core Configuration Data Loaded') async def init_database(self): self.log.info('Connecting to Database...') self.db = Database(self, self.cfg.db) try: await self.db[self.db.db_nam].collection.find_one({}) await self.db.precache_settings() set_color_cache_coll(self.db[self.db.db_nam].ColorCache) except ServerSelectionTimeoutError: self.log.error('A Connection To The Database Host Failed!') exit(errno.ETIMEDOUT) except OperationFailure: self.log.error('Database Access Operation Failed!') exit(errno.EACCES) self.log.info('Successfully Connected to Database') def init_cool_down(self): self.log.info('Loading Cool-down Controls...') self.cool_down = CooldownControl(self) self.loop.run_until_complete(self.cool_down.clean_cooldowns()) self.loop.run_until_complete(self.cool_down.cache_cooldowns()) self.log.info('Cool-down Controls Successfully Enabled') def init_music(self): self.log.info('Loading Music Controller...') self.music = MusicCore(self) self.log.info('Music Controller Initialized and Ready') def init_modules(self, init: bool = False): if init: self.log.info('Loading Sigma Modules') self.modules = PluginManager(self, init) def is_ready(self): try: ready = super().is_ready() except Exception: ready = False return ready def get_all_members(self): now = arrow.utcnow().timestamp timestamp = self.cache.get_cache('all_members_stamp') or 0 if now > timestamp + 60: members = list(super().get_all_members()) self.cache.set_cache('all_members', members) self.cache.set_cache('all_members_stamp', now) else: members = self.cache.get_cache('all_members') return members def get_all_channels(self): now = arrow.utcnow().timestamp timestamp = self.cache.get_cache('all_channels_stamp') or 0 if now > timestamp + 60: channels = list(super().get_all_channels()) self.cache.set_cache('all_channels', channels) self.cache.set_cache('all_channels_stamp', now) else: channels = self.cache.get_cache('all_channels') return channels def run(self): try: self.log.info('Connecting to Discord Gateway...') super().run(self.cfg.dsc.token, bot=self.cfg.dsc.bot) except discord.LoginFailure: self.log.error('Invalid Token!') exit(errno.EPERM) async def on_connect(self): event_name = 'connect' if event_name in self.modules.events: for event in self.modules.events[event_name]: self.loop.create_task(event.execute()) async def on_shard_ready(self, shard_id: int): self.log.info(f'Connection to Discord Shard #{shard_id} Established') event_name = 'shard_ready' self.loop.create_task(self.queue.event_runner(event_name, shard_id)) async def on_ready(self): self.ready = True self.log.info('---------------------------------') self.log.info('Apex Sigma Fully Loaded and Ready') self.log.info('---------------------------------') self.log.info(f'User Account: {self.user.name}#{self.user.discriminator}') self.log.info(f'User Snowflake: {self.user.id}') self.log.info('---------------------------------') self.log.info('Launching On-Ready Modules...') self.loop.create_task(self.queue.event_runner('ready')) self.log.info('Launching DB-Init Modules...') self.loop.create_task(self.queue.event_runner('dbinit')) self.log.info('All On-Ready Module Loops Created') self.log.info('---------------------------------') async def on_message(self, message: discord.Message): self.message_count += 1 if not message.author.bot: self.loop.create_task(self.queue.event_runner('message', message)) if self.user.mentioned_in(message): self.loop.create_task(self.queue.event_runner('mention', message)) await self.queue.command_runner(message) async def on_message_edit(self, before: discord.Message, after: discord.Message): if not before.author.bot: self.loop.create_task(self.queue.event_runner('message_edit', before, after)) async def on_message_delete(self, message: discord.Message): if not message.author.bot: self.loop.create_task(self.queue.event_runner('message_delete', message)) async def on_member_join(self, member: discord.Member): if not member.bot: self.loop.create_task(self.queue.event_runner('member_join', member)) async def on_member_remove(self, member: discord.Member): if not member.bot: self.loop.create_task(self.queue.event_runner('member_remove', member)) async def on_member_update(self, before: discord.Member, after: discord.Member): if not before.bot: self.loop.create_task(self.queue.event_runner('member_update', before, after)) async def on_guild_join(self, guild: discord.Guild): self.loop.create_task(self.queue.event_runner('guild_join', guild)) async def on_guild_remove(self, guild: discord.Guild): self.loop.create_task(self.queue.event_runner('guild_remove', guild)) async def on_guild_update(self, before: discord.Guild, after: discord.Guild): self.loop.create_task(self.queue.event_runner('guild_update', before, after)) async def on_voice_state_update(self, member: discord.Member, b: discord.VoiceState, a: discord.VoiceState): if not member.bot: self.loop.create_task(self.queue.event_runner('voice_state_update', member, b, a)) async def on_reaction_add(self, reaction: discord.Reaction, user: discord.User): if not user.bot: self.loop.create_task(self.queue.event_runner('reaction_add', reaction, user)) async def on_reaction_remove(self, reaction: discord.Reaction, user: discord.User): if not user.bot: self.loop.create_task(self.queue.event_runner('reaction_remove', reaction, user)) async def on_raw_reaction_add(self, payload: RawReactionActionEvent): self.loop.create_task(self.queue.event_runner('raw_reaction_add', payload)) async def on_raw_reaction_remove(self, payload: RawReactionActionEvent): self.loop.create_task(self.queue.event_runner('raw_reaction_remove', payload))
class Database(motor.AsyncIOMotorClient): def __init__(self, bot, db_cfg: DatabaseConfig): self.bot = bot self.db_cfg = db_cfg self.db_nam = self.db_cfg.database self.cache = Cacher() if self.db_cfg.auth: self.db_address = f'mongodb://{self.db_cfg.username}:{self.db_cfg.password}' self.db_address += f'@{self.db_cfg.host}:{self.db_cfg.port}/' else: self.db_address = f'mongodb://{self.db_cfg.host}:{self.db_cfg.port}/' super().__init__(self.db_address) async def get_prefix(self, message: discord.Message): prefix = self.bot.cfg.pref.prefix if message.guild: pfx_search = await self.get_guild_settings(message.guild.id, 'prefix') if pfx_search: prefix = pfx_search return prefix async def precache_settings(self): self.bot.log.info('Pre-Caching all guild settings...') all_settings = await self[self.db_cfg.database ].ServerSettings.find({}).to_list(None) for setting_file in all_settings: guild_id = setting_file.get('server_id') if guild_id: self.cache.set_cache(guild_id, setting_file) self.bot.log.info( f'Finished pre-caching {len(all_settings)} guild settings.') async def get_guild_settings(self, guild_id: int, setting_name: str): guild_settings = self.cache.get_cache(guild_id) if guild_settings is None: guild_settings = await self[self.db_nam].ServerSettings.find_one( {'server_id': guild_id}) or {} self.cache.set_cache(guild_id, guild_settings) setting_value = guild_settings.get(setting_name) return setting_value async def set_guild_settings(self, guild_id: int, setting_name: str, value): guild_settings = await self[self.db_nam].ServerSettings.find_one( {'server_id': guild_id}) if guild_settings: update_target = {"server_id": guild_id} update_data = {"$set": {setting_name: value}} await self[self.db_nam ].ServerSettings.update_one(update_target, update_data) else: update_data = {'server_id': guild_id, setting_name: value} await self[self.db_nam].ServerSettings.insert_one(update_data) self.cache.del_cache(guild_id) #why is none of this commented? async def precache_profiles(self): self.bot.log.info('Pre-Caching all member profiles...') all_settings = await self[self.db_cfg.database ].Profiles.find({}).to_list(None) for setting_file in all_settings: guild_id = setting_file.get('user_id') if guild_id: self.cache.set_cache(guild_id, setting_file) self.bot.log.info( f'Finished pre-caching {len(all_settings)} member profiles.') async def get_profile(self, user_id: int, entry_name: str): user_profile = self.cache.get_cache(user_id) if user_profile is None: user_profile = await self[self.db_nam].Profiles.find_one( {'user_id': user_id}) or {} self.cache.set_cache(user_profile, user_id) entry_value = user_profile.get(entry_value) return entry_value async def set_profile(self, user_id: int, entry_name: str, value): user_profile = await self[self.db_nam].Profiles.find_one( {'user_id': user_id}) or {} if user_profile: update_target = {"user_id": user_id} update_data = {"$set": {entry_name: value}} await self[self.db_nam ].Profiles.update_one(update_target, update_data) else: update_data = {'user_id': user_id, entry_name: value} await self[self.db_nam].Profiles.insert_one(update_data) self.cache.del_cache(user_id) async def update_resource(self, resource: SigmaResource, user_id: int, name: str): resources = await self.get_profile(user_id, 'resources') or {} resources.update({name: resource.dictify()}) await self.set_profile(user_id, 'resources', resources) async def get_resource(self, user_id: int, resource_name: str): resources = await self.get_profile(user_id, 'resources') or {} resource_data = resources.get(resource_name, {}) return SigmaResource(resource_data) async def is_notsabotaged(self, user_id: int): return bool(await self.get_profile(user_id, 'sabotaged')) async def add_resource(self, user_id: int, name: str, amount: int, trigger: str, origin=None, ranked: bool = True): if not await self.is_sabotaged(user_id): amount = abs(int(amount)) resource = await self.get_resource(user_id, name) resource.add_value(amount, trigger, origin, ranked) await self.update_resource(resource, user_id, name) async def del_resource(self, user_id: int, name: str, amount: int, trigger: str, origin=None): amount = abs(int(amount)) resource = await self.get_resource(user_id, name) resource.del_value(amount, trigger, origin) await self.update_resource(resource, user_id, name) async def get_inventory(self, user: discord.Member): inventory = await self.get_profile(user.id, 'inventory') or [] add_to_inventory( self.get_profile( user_id, "THE F*****G CHALSA I'VE BEEN LOOKING FOR SINCE ALEX ANNOUNCED THAT DAMN COMPETITIONT" )) return inventory async def add_to_inventory(self, user: discord.Member, item_data: dict): stamp = arrow.utcnow().timestamp item_data.update({'timestamp': stamp}) inv = await self.get_inventory(user) inv.append(item_data) await self.set_profile(user.id, 'inventory', inv) async def del_from_inventory(self, user, item_id): inv = await self.get_inventory(user) for item in inv: if item.get('item_id') == item_id: inv.remove(item) await self.set_profile(user.id, 'inventory', inv) async def get_inventory_item(self, user: discord.Member, item_file_id: str): inv = await self.get_inventory(user) output = None for item in inv: if item.get('item_file_id').lower() == item_file_id.lower(): output = item break return output
class CooldownControl(object): def __init__(self, bot): self.bot = bot self.cmd = CommandCooldown() self.db = self.bot.db self.cache = Cacher() self.cds = self.db[self.bot.cfg.db.database].CooldownSystem async def on_cooldown(self, cmd, user): if isinstance(user, str): cd_name = f'cd_{cmd}_{user}' else: cd_name = f'cd_{cmd}_{user.id}' entry = self.cache.get_cache(cd_name) if entry is None: entry = await self.cds.find_one({'name': cd_name}) if entry: end_stamp = entry['end_stamp'] now_stamp = arrow.utcnow().timestamp if now_stamp > end_stamp: cooldown = False else: cooldown = True else: cooldown = False return cooldown async def get_cooldown(self, cmd, user): if isinstance(user, str): cd_name = f'cd_{cmd}_{user}' else: cd_name = f'cd_{cmd}_{user.id}' entry = self.cache.get_cache(cd_name) if entry is None: entry = await self.cds.find_one({'name': cd_name}) if entry: end_stamp = entry['end_stamp'] now_stamp = arrow.utcnow().float_timestamp cooldown = end_stamp - now_stamp if cooldown < 2: if cooldown <= 0: cooldown = 0.01 else: cooldown = round(cooldown, 2) else: cooldown = int(cooldown) else: cooldown = 0 return cooldown async def set_cooldown(self, cmd, user, amount): if isinstance(user, str): cd_name = f'cd_{cmd}_{user}' else: cd_name = f'cd_{cmd}_{user.id}' entry = self.cache.get_cache(cd_name) if entry: self.cache.del_cache(cd_name) else: entry = await self.cds.find_one({'name': cd_name}) end_stamp = arrow.utcnow().timestamp + amount if entry: await self.cds.update_one({'name': cd_name}, {'$set': { 'end_stamp': end_stamp }}) else: cd_data = {'name': cd_name, 'end_stamp': end_stamp} await self.cds.insert_one(cd_data)
class Database(motor.AsyncIOMotorClient): def __init__(self, bot, db_cfg): self.bot = bot self.db_cfg = db_cfg self.cache = Cacher() if self.db_cfg.auth: self.db_address = f'mongodb://{self.db_cfg.username}:{self.db_cfg.password}' self.db_address += f'@{self.db_cfg.host}:{self.db_cfg.port}/' else: self.db_address = f'mongodb://{self.db_cfg.host}:{self.db_cfg.port}/' super().__init__(self.db_address) async def get_guild_settings(self, guild_id, setting_name): guild_settings = self.cache.get_cache(guild_id) if guild_settings is None: guild_settings = await self[self.bot.cfg.db.database ].ServerSettings.find_one( {'ServerID': guild_id}) self.cache.set_cache(guild_id, guild_settings) if not guild_settings: await self[self.bot.cfg.db.database ].ServerSettings.insert_one({'ServerID': guild_id}) setting_value = None else: setting_value = guild_settings.get(setting_name) return setting_value async def set_guild_settings(self, guild_id, setting_name, value): guild_settings = await self[self.bot.cfg.db.database ].ServerSettings.find_one( {'ServerID': guild_id}) if guild_settings: update_target = {"ServerID": guild_id} update_data = {"$set": {setting_name: value}} await self[self.bot.cfg.db.database ].ServerSettings.update_one(update_target, update_data) else: update_data = {'ServerID': guild_id, setting_name: value} await self[self.bot.cfg.db.database ].ServerSettings.insert_one(update_data) self.cache.del_cache(guild_id) async def get_experience(self, user, guild): database = self[self.bot.cfg.db.database] collection = database['ExperienceSystem'] entry = await collection.find_one({'UserID': user.id}) if entry: global_xp = entry.get('global') or 0 guild_id = str(guild.id) guilds = entry.get('guilds') or {} guild_xp = guilds.get(guild_id) or 0 else: global_xp = 0 guild_xp = 0 output = {'global': global_xp, 'guild': guild_xp} return output async def add_experience(self, user, guild, points, additive=True): sabotage_file = await self[ self.db_cfg.database].SabotagedUsers.find_one({'UserID': user.id}) if not sabotage_file: database = self[self.bot.cfg.db.database] collection = database['ExperienceSystem'] entry = await collection.find_one({'UserID': user.id}) if entry: global_xp = entry.get('global') or 0 guilds = entry.get('guilds') or {} else: await collection.insert_one({'UserID': user.id}) global_xp = 0 guilds = {} guild_id = str(guild.id) guild_points = guilds.get(guild_id) or 0 if additive: global_xp += points guild_points += points guild_data = {guild_id: guild_points} guilds.update(guild_data) xp_data = {'global': global_xp, 'guilds': guilds} update_target = {'UserID': user.id} update_data = {'$set': xp_data} await collection.update_one(update_target, update_data) async def get_currency(self, user, guild): database = self[self.bot.cfg.db.database] collection = database['CurrencySystem'] entry = await collection.find_one({'UserID': user.id}) if entry: global_amount = entry.get('global') or 0 current_amount = entry.get('current') or 0 guild_id = str(guild.id) guilds = entry.get('guilds') or {} guild_amount = guilds.get(guild_id) or 0 else: current_amount = 0 global_amount = 0 guild_amount = 0 output = { 'current': current_amount, 'global': global_amount, 'guild': guild_amount } return output async def add_currency(self, user, guild, points, additive=True): sabotage_file = await self[ self.db_cfg.database].SabotagedUsers.find_one({'UserID': user.id}) if not sabotage_file: database = self[self.bot.cfg.db.database] collection = database['CurrencySystem'] entry = await collection.find_one({'UserID': user.id}) points = abs(points) if entry: current_amount = entry.get('current') or 0 global_amount = entry.get('global') or 0 guilds = entry.get('guilds') or {} else: await collection.insert_one({'UserID': user.id}) global_amount = 0 current_amount = 0 guilds = {} guild_id = str(guild.id) guild_points = guilds.get(guild_id) or 0 if additive: global_amount += points guild_points += points current_amount += points guild_data = {guild_id: guild_points} guilds.update(guild_data) xp_data = { 'current': current_amount, 'global': int(global_amount), 'guilds': guilds } update_target = {'UserID': user.id} update_data = {'$set': xp_data} await collection.update_one(update_target, update_data) async def rmv_currency(self, user, points): database = self[self.bot.cfg.db.database] collection = database['CurrencySystem'] entry = await collection.find_one({'UserID': user.id}) points = abs(points) if entry: current_amount = entry.get('current') or 0 else: await collection.insert_one({'UserID': user.id}) current_amount = 0 current_amount -= points xp_data = {'current': current_amount} update_target = {'UserID': user.id} update_data = {'$set': xp_data} await collection.update_one(update_target, update_data) async def get_inventory(self, user): inventory = await self[self.db_cfg.database ]['Inventory'].find_one({'UserID': user.id}) if not inventory: await self[self.db_cfg.database]['Inventory'].insert_one({ 'UserID': user.id, 'Items': [] }) inventory = [] else: inventory = inventory.get('Items') return inventory async def update_inv(self, user, inv): await self[self.db_cfg.database ]['Inventory'].update_one({'UserID': user.id}, {'$set': { 'Items': inv }}) async def add_to_inventory(self, user, item_data): sabotage_file = await self[ self.db_cfg.database].SabotagedUsers.find_one({'UserID': user.id}) if not sabotage_file: stamp = arrow.utcnow().timestamp item_data.update({'Timestamp': stamp}) inv = await self.get_inventory(user) inv.append(item_data) await self.update_inv(user, inv) async def del_from_inventory(self, user, item_id): inv = await self.get_inventory(user) for item in inv: if item['item_id'] == item_id: inv.remove(item) await self.update_inv(user, inv) async def get_inventory_item(self, user, item_file_id): inv = await self.get_inventory(user) output = None for item in inv: if item['item_file_id'].lower() == item_file_id.lower(): output = item break return output