Пример #1
0
 def __init__(self, bot, db_cfg: DatabaseConfig):
     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)
Пример #2
0
 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)
Пример #3
0
 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 == {}
Пример #4
0
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import asyncio

import discord

from sigma.core.mechanics.caching import Cacher

gcp_cache = Cacher()
scp_cache = Cacher()


class GlobalCommandPermissions(object):
    def __init__(self, command, message: discord.Message):
        self.message = message
        self.bot = command.bot
        self.cmd = command
        self.db = command.db
        self.loop = asyncio.get_event_loop()
        # Default States
        self.nsfw_denied = False
        self.black_user = False
        self.black_srv = False
        self.owner_denied = False
Пример #5
0
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import discord
from humanfriendly.tables import format_pretty_table as boop

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand
from sigma.core.utilities.data_processing import get_image_colors
from sigma.modules.moderation.server_settings.filters.name_check_clockwork import clean_name


tck_cache = Cacher(True, 3600)


async def topcookies(cmd: SigmaCommand, message: discord.Message, args: list):
    value_name = 'Cookies'
    sort_key = 'Cookies'
    lb_icon = cmd.bot.user.avatar_url
    lb_category = 'Global'
    localed = False
    if args:
        if args[0].lower() == 'total':
            sort_key = 'Total'
            lb_category = 'Total'
        elif args[0].lower() == 'local':
            lb_category = 'Local'
            lb_icon = message.guild.icon_url or lb_icon
Пример #6
0
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import functools
import secrets
from concurrent.futures import ThreadPoolExecutor

import discord
import markovify

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand
from sigma.core.utilities.data_processing import user_avatar
from sigma.modules.utilities.mathematics.impersonate import chain_object_cache

combination_cache = Cacher()


def combine_names(user_one, user_two):
    cutoff_one = len(user_one.name) // 2
    cutoff_two = len(user_two.name) // 2
    piece_one = user_one.name[:cutoff_one]
    piece_two = user_two.name[cutoff_two:]
    output = piece_one + piece_two
    return output


async def combinechains(cmd: SigmaCommand, message: discord.Message,
                        args: list):
    if len(message.mentions) == 2:
        target_one = message.mentions[0]
Пример #7
0
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import functools
from concurrent.futures import ThreadPoolExecutor

import discord
import markovify

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand
from sigma.core.utilities.data_processing import user_avatar

chain_object_cache = Cacher()


async def impersonate(cmd: SigmaCommand, message: discord.Message, args: list):
    if args:
        if message.mentions:
            target = message.mentions[0]
        else:
            target = discord.utils.find(
                lambda x: x.name.lower() == ' '.join(args).lower(),
                message.guild.members)
    else:
        target = message.author
    if target:
        chain_data = await cmd.db[cmd.db.db_nam].MarkovChains.find_one(
            {'user_id': target.id})
Пример #8
0
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import discord
from humanfriendly.tables import format_pretty_table as boop

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand
from sigma.core.utilities.data_processing import get_image_colors
from sigma.modules.moderation.server_settings.filters.name_check_clockwork import clean_name

tcr_cache = Cacher(True, 3600)


async def topcurrency(cmd: SigmaCommand, message: discord.Message, args: list):
    value_name = cmd.bot.cfg.pref.currency
    sort_key = 'global'
    lb_icon = cmd.bot.user.avatar_url
    lb_category = 'Global'
    search = {}
    if args:
        if args[0].lower() == 'local':
            sort_key = f'guilds.{message.guild.id}'
            search = {sort_key: {'$exists': True}}
            lb_icon = message.guild.icon_url or lb_icon
            lb_category = message.guild.name
        elif args[0].lower() == 'total':
Пример #9
0
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
import arrow
import discord
from humanfriendly.tables import format_pretty_table as boop

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand
from sigma.modules.moderation.server_settings.filters.name_check_clockwork import clean_name

txplb_cache = Cacher()


async def topexperience(cmd: SigmaCommand, message: discord.Message,
                        args: list):
    value_name = 'Experience'
    sort_key = 'global'
    lb_category = 'Global'
    search = {}
    if args:
        if args[0].lower() == 'local':
            sort_key = f'guilds.{message.guild.id}'
            search = {sort_key: {'$exists': True}}
            lb_category = message.guild.name
        elif args[0].lower() == 'total':
            sort_key = 'total'
Пример #10
0
 def test_getter(self):
     cache = Cacher()
     assert cache.get_cache(self.get_random_generator()()) is None
Пример #11
0
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
Пример #12
0
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)
Пример #13
0
 def __init__(self, bot):
     self.bot = bot
     self.db = self.bot.db
     self.cache = Cacher()
     self.cds = self.db[self.db.db_nam].CooldownSystem
Пример #14
0
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import functools
from concurrent.futures import ThreadPoolExecutor

import discord
import markovify

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand
from sigma.core.utilities.data_processing import user_avatar

chain_object_cache = Cacher(True, 300)


async def impersonate(cmd: SigmaCommand, message: discord.Message, args: list):
    if args:
        if message.mentions:
            target = message.mentions[0]
        else:
            target = discord.utils.find(
                lambda x: x.name.lower() == ' '.join(args).lower(),
                message.guild.members)
    else:
        target = message.author
    if target:
        chain_data = await cmd.db[cmd.db.db_cfg.database
                                  ]['MarkovChains'].find_one(
Пример #15
0
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)
Пример #16
0
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import arrow
import discord

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand

afk_cache = Cacher()


async def afk(cmd: SigmaCommand, message: discord.Message, args: list):
    afk_data = afk_cache.get_cache(message.author.id)
    if not afk_data:
        afk_data = await cmd.db[cmd.db.db_nam].AwayUsers.find_one(
            {'user_id': message.author.id})
    if args:
        afk_reason = ' '.join(args)
    else:
        afk_reason = 'No reason stated.'
    in_data = {
        'user_id': message.author.id,
        'timestamp': arrow.utcnow().timestamp,
        'reason': afk_reason
Пример #17
0
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
Пример #18
0
 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
Пример #19
0
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))
Пример #20
0
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from sigma.core.mechanics.caching import Cacher

perm_cache = Cacher()


def generate_default_data(message):
    return {
        'server_id': message.guild.id,
        'disabled_commands': [],
        'disabled_modules': [],
        'command_exceptions': {},
        'module_exceptions': {},
    }


def generate_cmd_data(cmd_name):
    return {cmd_name: {'users': [], 'channels': [], 'roles': []}}
Пример #21
0
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
import asyncio

import arrow
import discord

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.event import SigmaEvent

decay_clock_running = False
decay_cache = Cacher()


async def decay_checker(ev: SigmaEvent):
    global decay_clock_running
    if not decay_clock_running:
        decay_clock_running = True
        ev.bot.loop.create_task(decay_checker_clock(ev))


async def decay_checker_clock(ev: SigmaEvent):
    while True:
        if ev.bot.is_ready():
            try:
                now = arrow.utcnow().timestamp
                dmsgs = decay_cache.get_cache('all')
Пример #22
0
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import arrow
import discord
from humanfriendly.tables import format_pretty_table as boop

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand
from sigma.modules.moderation.server_settings.filters.edit_name_check import clean_name

tcrlb_cache = Cacher()


async def topcurrency(cmd: SigmaCommand, message: discord.Message, args: list):
    value_name = cmd.bot.cfg.pref.currency
    sort_key = 'global'
    lb_category = 'Global'
    search = {}
    if args:
        if args[0].lower() == 'local':
            sort_key = f'guilds.{message.guild.id}'
            search = {sort_key: {'$exists': True}}
            lb_category = message.guild.name
        elif args[0].lower() == 'total':
            sort_key = 'total'
            lb_category = 'Total'
Пример #23
0
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
Пример #24
0
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import arrow
import discord
from humanfriendly.tables import format_pretty_table as boop

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand
from sigma.modules.moderation.server_settings.filters.name_check_clockwork import clean_name

tcklb_cache = Cacher()


async def topcookies(cmd: SigmaCommand, message: discord.Message, args: list):
    value_name = 'Cookies'
    sort_key = 'Cookies'
    lb_category = 'Global'
    localed = False
    if args:
        if args[0].lower() == 'total':
            sort_key = 'Total'
            lb_category = 'Total'
        elif args[0].lower() == 'local':
            lb_category = 'Local'
            localed = True
    cache_key = message.guild.id if localed else sort_key
Пример #25
0
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import discord
from humanfriendly.tables import format_pretty_table as boop

from sigma.core.mechanics.caching import Cacher
from sigma.core.mechanics.command import SigmaCommand
from sigma.core.utilities.data_processing import get_image_colors
from sigma.modules.moderation.server_settings.filters.name_check_clockwork import clean_name

txp_cache = Cacher(True, 3600)


async def topexperience(cmd: SigmaCommand, message: discord.Message,
                        args: list):
    value_name = 'Experience'
    sort_key = 'global'
    lb_icon = cmd.bot.user.avatar_url
    lb_category = 'Global'
    search = {}
    if args:
        if args[0].lower() == 'local':
            sort_key = f'guilds.{message.guild.id}'
            search = {sort_key: {'$exists': True}}
            lb_icon = message.guild.icon_url or lb_icon
            lb_category = message.guild.name