def __exclude_clan_from_citadel(clanid):
     citadelroleid = 636372439261249566
     discordserverid = CommonFramework.RetrieveConfigOptions('discord')
     discordserverid = discordserverid['serverid']
     results = CosmosFramework.QueryItems(
         'SELECT * FROM c WHERE c.clan = {0} AND c.citadel = true'.format(
             clanid), 'users')
     for result in results:
         status_code = DiscordFramework.RemoveUserRole(
             citadelroleid, result['discordid'], discordserverid)
         if status_code == 204:
             del result['citadel']
             CosmosFramework.ReplaceItem(result['_self'], result)
         else:
             DiscordFramework.send_discord_private_message(
                 "Citadel checker is having issues", 113304266269003776)
             raise "Clan removal failed"
def cone(body: dict) -> dict:
    """Cones user, adds information to database and sends return messages"""
    discordmessage = body['message'].split()
    ConeOfShameDiscordId = '525870180505747467'
    returnmessage = {}
    config = CommonFramework.RetrieveConfigOptions('discord')
    try:
        if len(discordmessage) < 3:
            returnmessage['author'] = 'Invalid command format'
            return returnmessage
        timetocone = int(discordmessage[2])
        if timetocone > 2880:
            returnmessage[
                'author'] = 'You cannot Cone someone longer then 2 days'
            return returnmessage
        discordid = int(__discord_id_from_mention(
            discordmessage[1]))  ##Trys int to make sure it's int
        result = __query_cosmos_for_info_by_discordid(discordid)
        if result is None:
            newitem = {}
            newitem['discordid'] = str(discordid)
            result = CosmosFramework.InsertItem(newitem, 'users')
        if 'cone' in result:
            returnmessage['author'] = 'User is already coned'
        statuscode = DiscordFramework.AddUserRole(ConeOfShameDiscordId,
                                                  discordid,
                                                  config['serverid'])
        if statuscode == 204:  #Meaning add role was successful
            result['cone'] = int(time.time()) + (60 * int(timetocone))
            CosmosFramework.ReplaceItem(result['_self'], result)
            returnmessage['channel'] = '{0} muted user for {1} minutes'.format(
                body['authordisplayname'], timetocone)
            returnmessage['author'] = 'Cone issued as requested'
            returnmessage['targetdiscordid'] = discordid
            returnmessage[
                'target'] = 'You were muted for {0} minutes by {1}'.format(
                    timetocone, body['authordisplayname'])
    except Exception as e:
        returnmessage['author'] = 'Following error has occured: {0}'.format(e)
    return returnmessage
 def __post_contest_results(channelid: str,
                            statrandom: bool = True) -> None:
     """Posts Contest results, Needs Channel ID and if results should be randomized"""
     results = CosmosFramework.QueryItems(
         'SELECT TOP 3 * FROM c WHERE IS_DEFINED(c.contest.currentscore) AND c.contest.currentscore != 0 ORDER BY c.contest.currentscore DESC',
         'users')
     if not bool(results):  ##No users with score greater then 1
         return None
     config = CommonFramework.RetrieveConfigOptions('discord')
     place = 1
     if statrandom is True:
         message = 'Please note that score is slightly randomized when displayed and may lead to appear that lower place is winning, true score is used when determining place.'
         DiscordFramework.SendDiscordMessage(message=message,
                                             channelid=channelid)
     DiscordFramework.SendDiscordMessage('Current Contest results:',
                                         channelid)
     for result in results:
         userdata = DiscordFramework.get_user_guild_info(
             result['discordid'], config['serverid'])
         if result['contest']['currentscore'] == 0:
             place += 1
             continue
         if 'code' in userdata and userdata['code'] == 10007:
             CosmosFramework.delete_user_from_cosmos_by_discordid(
                 result['discordid'])
             continue
         if userdata['nick'] is None:
             nick = userdata['user']['username']
         else:
             nick = userdata['nick']
         if statrandom is True:
             score = int(result['contest']['currentscore'] *
                         (random.randint(100, 110) / 100))
         else:
             score = int(result['contest']['currentscore'])
         discordmessage = "{0} is currently in #{1} place with score: {2}".format(
             nick, place, score)
         DiscordFramework.SendDiscordMessage(discordmessage, channelid)
         place += 1
import json
import MySQLdb
import Modules.CommonFramework as CommonFramework
import Modules.CosmosFramework as CosmosFramework
import time

mysqlcinfo = CommonFramework.RetrieveConfigOptions("mysql")
mysqlconn = MySQLdb.connect(host=mysqlcinfo['server'],
                            user=mysqlcinfo['username'],
                            passwd=mysqlcinfo['password'],
                            db=mysqlcinfo['database'])
mysqlconn.autocommit(True)
mysqlcur = mysqlconn.cursor()
cmd = "SELECT discordid,wgid,clan,rank,wgtoken,updated FROM users"
mysqlcur.execute(cmd)
data = mysqlcur.fetchall()
#discordserverid = CommonFramework.RetrieveConfigOptions('discord')
#discordserverid = discordserverid['discordserverid']
#Upload Users
csdbdoc = {}
for row in data:
    csdbdoc.clear()
    csdbdoc['discordid'] = str(row[0])
    csdbdoc['wgid'] = row[1]
    csdbdoc['clan'] = row[2]
    csdbdoc['rank'] = row[3]
    csdbdoc['wgtoken'] = str(row[4])
    csdbdoc['server'] = 'NA'
    CosmosFramework.InsertItem(csdbdoc, 'users')
    #time.sleep(.03)
def run_citadel_check():
    def __get_citadel_results() -> dict:
        primary = {}
        secondary = {}
        results = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.citadel = true', 'citadel')
        for result in results:
            secondary['tag'] = result.get('tag')
            secondary['name'] = result.get('name')
            secondary['citadel'] = result.get('citadel')
            secondary['override'] = result.get('citadeloverride')
            secondary['excludereason'] = result.get('excludereason')
            secondary['excludetime'] = result.get('excludetime')
            primary[result['wgid']] = dict(secondary)
            secondary.clear()
        return primary

    def __exclude_clan_from_citadel(clanid):
        citadelroleid = 636372439261249566
        discordserverid = CommonFramework.RetrieveConfigOptions('discord')
        discordserverid = discordserverid['serverid']
        results = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.clan = {0} AND c.citadel = true'.format(
                clanid), 'users')
        for result in results:
            status_code = DiscordFramework.RemoveUserRole(
                citadelroleid, result['discordid'], discordserverid)
            if status_code == 204:
                del result['citadel']
                CosmosFramework.ReplaceItem(result['_self'], result)
            else:
                DiscordFramework.send_discord_private_message(
                    "Citadel checker is having issues", 113304266269003776)
                raise "Clan removal failed"

    def __exclude_wgid_from_citadel(wgid: int) -> None:
        """Removes WGID from citadel"""
        citadelroleid = 636372439261249566
        discordserverid = CommonFramework.RetrieveConfigOptions('discord')
        discordserverid = discordserverid['serverid']
        result = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.discordid="{0}"'.format(wgid), 'users')
        if bool(result):
            result = result[0]
            DiscordFramework.RemoveUserRole(citadelroleid, result['discordid'],
                                            discordserverid)
            DiscordFramework.send_discord_private_message(
                'You have been removed from RDDT citadel due clan/rank changes',
                result['discordid'])
            del result['citadel']
            CosmosFramework.ReplaceItem(result['_self'], result)

    citadelchannelid = 636374196355858452  #Actual citadel channel
    wgapi = CommonFramework.RetrieveConfigOptions('wargaming')
    results = __get_citadel_results()
    apiresults = CommonFramework.get_json_data(
        "https://api.worldoftanks.com/wot/clanratings/top/?application_id={0}&rank_field=gm_elo_rating&limit=200"
        .format(wgapi['apitoken']))
    wgidlist = []
    #Do clan checks ##TODO put this in it's own def block
    for apiresult in apiresults[
            'data']:  #Get information about clans from Wargaming API
        wgidlist.append(apiresult['clan_id'])
        if apiresult['clan_id'] not in results:
            item = {}
            item['wgid'] = apiresult['clan_id']
            item['name'] = apiresult['clan_name']
            item['tag'] = apiresult['clan_tag']
            item['citadel'] = True
            CosmosFramework.InsertItem(item, 'citadel')
        elif apiresult['clan_id'] in results and (
                results[apiresult['clan_id']]['tag'] != apiresult['clan_tag']
                or results[apiresult['clan_id']]['name'] !=
                apiresult['clan_name']):
            #Checks the database and Wargaming API match around clan tag and name, if not, it updates it
            updateitem = CosmosFramework.QueryItems(
                'SELECT * FROM c WHERE c.wgid={0}'.format(
                    apiresult['clan_id']), 'citadel')
            updateitem = updateitem[0]
            updateitem['name'] = apiresult['clan_name']
            updateitem['tag'] = apiresult['clan_tag']
            CosmosFramework.ReplaceItem(updateitem['_self'], updateitem)
    clanlist = list(results.keys())
    removeclans = list(set(clanlist) -
                       set(wgidlist))  #List of clans to be removed
    for removeclan in removeclans:
        claninfo = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.wgid={0}'.format(removeclan), 'citadel')
        claninfo = claninfo[0]
        if 'override' in claninfo and claninfo['override'] is True:
            continue  #Overrides are not removed
        elif 'excludetime' not in claninfo:  #Step 2, put in removal time
            claninfo['excludetime'] = int(time.time(
            )) + 604700  #This is 6 days, 23 hours and ~58 minutes
            message = "WARNING: Clan {0} ({1}) will be removed within 7 days due to lack of clan rating.".format(
                claninfo['name'], claninfo['tag'])
            DiscordFramework.SendDiscordMessage(message, citadelchannelid)
            CosmosFramework.ReplaceItem(claninfo['_self'], claninfo)
        elif claninfo['excludetime'] < int(
                time.time()
        ):  #when their time is hit, mark them no longer allowed in citadel with reason and remove all clan members
            __exclude_clan_from_citadel(removeclan)
            message = "Clan {0} ({1}) has been removed from citadel.".format(
                claninfo['name'], claninfo['tag'])
            DiscordFramework.SendDiscordMessage(message, citadelchannelid)
            claninfo['citadel'] = False
            claninfo['excludetime'] = None
            claninfo['excludereason'] = 'Excluded due to lack of ranking'
            CosmosFramework.ReplaceItem(claninfo['_self'], claninfo)
    #Do user checks ##TODO Put this in it's own def block
    userresults = CosmosFramework.QueryItems(
        'SELECT c.wgid FROM c WHERE c.citadel = true', 'users')
    wgidtocheck = []
    for userresult in userresults:
        wgidtocheck.append(userresult['wgid'])
        if len(wgidtocheck) >= 99:
            apiresults = wotframework.GetPlayersClanInfo(wgidtocheck)
            for apiresult in apiresults:
                if apiresult[1] is None or apiresult[2] not in [
                        'commander', 'executive_officer', 'combat_officer',
                        'personnel_officer'
                ]:
                    __exclude_wgid_from_citadel(apiresult[0])
            wgidtocheck.clear()
#This module is to provide web interface for users to register. This module simply takes token generated by another application and matches up WG OpenID response then stores WGID in
#the database for RDDT_Teamspeak_Bot Module to interact with.

from flask import Flask, request, redirect, session
from flask_openid import OpenID
import re
#import MySQLdb
import Modules.CommonFramework as CommonFramework
import Modules.CosmosFramework as CosmosFramework

#Flask Setup
config = CommonFramework.RetrieveConfigOptions('registration')

app_id = config['app_id']
oid = OpenID()
app = Flask(__name__)
app.secret_key = config['app_secret']

port = 8080
wgid_handler = '/wgid/redirect'
response_message = 'Processing registration'
login_message = 'Please click here to log in with wargaming'
auth_url = '/wgid/auth'

min_battles = 0


@app.route(auth_url)
def landing_page():
    if 'token' not in request.values:
        return 'Invalid request'
import discord
from azure.servicebus import QueueClient, Message
import json
#Local Modules
import Modules.CommonFramework as CommonFramework
import Modules.DiscordFramework as DiscordFramework
import Modules.CosmosFramework as CosmosFramework

#import Modules.EventGridFramework as EventGridFramework
#import Modules.DiscordBotFramework as DiscordBotFramework

##Discord options
discordoptions = CommonFramework.RetrieveConfigOptions('discord')
token = discordoptions['token']
discordclient = discord.Client()
commandprefix = '!'

#Discord Incoming Service Bus setup
servicebusoptions = CommonFramework.RetrieveConfigOptions('discordlisten')
connection_str = servicebusoptions['connectionstring']
queue_path = servicebusoptions['queue']
servicebusclient = QueueClient.from_connection_string(connection_str,
                                                      queue_path)
###


@discordclient.event
async def on_message(message):
    if message.author == discordclient.user:
        return None  #Bot ignores itself
Beispiel #8
0
import json
import requests
import os
from time import sleep
import Modules.CommonFramework as CommonFramework

baseuri = "https://discord.com/api"
config = CommonFramework.RetrieveConfigOptions("discord")


class DiscordHTTP:
    def __init__(self) -> None:
        global config
        self.token = config['token']
        self.baseuri = "https://discord.com/api"

    def __generate_discord_header(self) -> dict:
        header = {
            'Authorization':
            str(f"Bot {self.token}"),
            'User-Agent':
            '/r/worldoftanks Discord Bot (https://github.com/Rabbit994/RDDT-Discord-Bot-Azure, v1.0.5)'
        }
        return header

    def __send_discord_put_request(self, uri: str):
        statuscode = 0
        for x in range(0, 3):
            r = requests.put(uri, headers=self.__generate_discord_header())
            statuscode = r.status_code
            if statuscode == 429:  #If
Beispiel #9
0
#This handles incoming discord messages

import json
from time import sleep
import requests
##3rd Party Modules
from azure.servicebus import QueueClient, Message
##Local Modules
import Modules.CosmosFramework as CosmosFramework
import Modules.CommonFramework as CommonFramework
import Modules.DiscordFramework as DiscordFramework
import Modules.DiscordBotFramework as DiscordBotFramework
from Modules.DiscordBotFramework import MessageHandler

#region Service Bus for incoming
config = CommonFramework.RetrieveConfigOptions('discordlisten')
connection_str = config['connectionstring']
queue = config['queue']
sbclient = QueueClient.from_connection_string(connection_str,queue)
#endregion

def __return_message(body:dict, returnmessage:dict) -> None:
    """Gets original message and return message and sends to proper channels"""
    if 'channel' in returnmessage:
        DiscordFramework.SendDiscordMessage(returnmessage['channel'],body['guildchannelid'])
    if 'author' in returnmessage:
        DiscordFramework.send_discord_private_message(returnmessage['author'],body['authorid'])
    if 'target' in returnmessage and 'targetdiscordid' in returnmessage:
        DiscordFramework.send_discord_private_message(returnmessage['target'],returnmessage['targetdiscordid'])
    return None
def checkroles(discordid: str) -> None:
    """Checks user for proper roles"""
    def get_responsible_roles() -> list:
        """Gets a list of Discordid roles that bot thinks it's responsible for"""
        results = CosmosFramework.QueryItems(
            "SELECT DISTINCT(c.discordid) FROM c", 'roles')
        listofroles = []
        for result in results:
            listofroles.append(result['discordid'])
        return listofroles

    discord_request = DiscordFramework.DiscordHTTP()
    config = CommonFramework.RetrieveConfigOptions('discord')
    playerresult = CosmosFramework.QueryItems(
        'SELECT * FROM c WHERE c.discordid="{0}"'.format(discordid), 'users')
    if not bool(playerresult):  #Meaning unknown Discord ID
        return None
    playerresult = playerresult[0]
    resproles = get_responsible_roles()  #Roles controlled by the bot
    userroles = DiscordFramework.GetUserRoles(discordid, config['serverid'])
    if userroles == 0:
        return None  #User unknown, exit
    if playerresult['rank'] == "friend":
        friendrole = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.wotrank = "friend"', 'roles')
        friendrole = friendrole[0]
        friendrole = friendrole['discordid']
        if int(friendrole) not in userroles:
            discord_request.add_role_to_user(guildid=config['serverid'],
                                             userid=discordid,
                                             roleid=friendrole)
            #DiscordFramework.AddUserRole(friendrole,discordid,config['serverid'])
        resproles.remove(friendrole)
    else:
        userrankrole = CosmosFramework.QueryItems(
            'SELECT c.discordid FROM c WHERE c.wotrank ="{0}" AND c.wotclan = {1}'
            .format(playerresult['rank'], playerresult['clan']), 'roles')
        userrankrole = userrankrole[0]['discordid']
        userclanrole = CosmosFramework.QueryItems(
            'SELECT c.discordid FROM c WHERE c.wotclan = {0} AND c.wotrank = null'
            .format(playerresult['clan']), 'roles')
        userclanrole = userclanrole[0]['discordid']
        if int(userrankrole) not in userroles or int(
                userclanrole) not in userroles:
            discord_request.add_role_to_user(guildid=config['serverid'],
                                             userid=discordid,
                                             roleid=userclanrole)
            discord_request.add_role_to_user(guildid=config['serverid'],
                                             userid=discordid,
                                             roleid=userrankrole)
            #DiscordFramework.AddUserRole(userclanrole,discordid,config['serverid'])
            #DiscordFramework.AddUserRole(userrankrole,discordid,config['serverid'])
        resproles.remove(userclanrole)
        resproles.remove(userrankrole)
    commonroles = set(int(i) for i in resproles) & set(
        userroles)  #userroles comes back as int
    if bool(commonroles
            ):  #Meaning there is roles showing up that shouldn't be there
        for role in commonroles:
            discord_request.remove_role_from_user(guildid=config['serverid'],
                                                  userid=discordid,
                                                  roleid=role)
            time.sleep(2)
            #DiscordFramework.RemoveUserRole(role,discordid,config['serverid'])
    return None
 def genURL(token: str) -> str:
     """Generate FLask URI"""
     link = CommonFramework.RetrieveConfigOptions("registration")
     link = link['flaskuri']
     return "{0}?token={1}".format(link, token)
def register(message: dict) -> dict:
    """Registration"""
    def genToken(discordId: str) -> str:
        time = str(datetime.datetime.utcnow().microsecond
                   )  # only microseconds in last second. i.e. <100
        hasher = hashlib.sha256(discordId.encode('utf-8'))
        hasher.update(time.encode('utf-8'))
        return hasher.hexdigest()[-8:]

    def genURL(token: str) -> str:
        """Generate FLask URI"""
        link = CommonFramework.RetrieveConfigOptions("registration")
        link = link['flaskuri']
        return "{0}?token={1}".format(link, token)

    authordiscordid = message['authorid']
    link = CommonFramework.RetrieveConfigOptions("registration")
    link = link['flaskuri']
    returnmessage = {}
    result = CosmosFramework.QueryItems(
        'SELECT * FROM c WHERE c.discordid = "{0}"'.format(authordiscordid))
    if not bool(result):  #meaning no result
        document = {}
        document['discordid'] = str(
            authordiscordid)  #Discord IDs are in strings
        document['wgtoken'] = str(genToken(str(authordiscordid)))
        CosmosFramework.InsertItem(document)
        returnmessage[
            'channel'] = "Welcome {0}! Check your direct messages for a link. Please note, I only support NA Server for sign in.".format(
                message['authordisplayname'])
        #returnmessage['author'] = genURL(document['wgtoken'])
        pmresult = DiscordFramework.send_discord_private_message(
            message=genURL(document['wgtoken']), discordid=message['authorid'])
        if pmresult.get('message') == 'Cannot send messages to this user':
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="❌")
        else:
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="\N{WHITE HEAVY CHECK MARK}")
    elif result[0]['wgtoken'] is not None and 'wgid' not in result[0]:
        pmresult = DiscordFramework.send_discord_private_message(
            message=genURL(result[0]['wgtoken']),
            discordid=message['authorid'])
        if pmresult.get('message') == 'Cannot send messages to this user':
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="❌")
        else:
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="\N{WHITE HEAVY CHECK MARK}")
        #returnmessage['author'] = genURL(result[0]['wgtoken'])
    elif result[0]['wgid'] is not None:
        pmresult = DiscordFramework.send_discord_private_message(
            message="You have already registered",
            discordid=message['authorid'])
        if pmresult.get('message') == 'Cannot send messages to this user':
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="❌")
        else:
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="\N{WHITE HEAVY CHECK MARK}")
        #returnmessage['author'] = "You have already registered"
    return returnmessage
"""
This is check for Wargaming NA Stream and posting if active
"""
import time

from Modules.twitch import TwitchAPI
import Modules.CommonFramework as CommonFramework
import Modules.DiscordFramework as DiscordFramework

i = 0
channelid = '414607006821777440'
options = CommonFramework.RetrieveConfigOptions("twitch")
twitch = TwitchAPI(options['clientid'], options['clientsecret'])
users = ['worldoftanksna']
active = {}
for user in users:
    active[user] = False
while i < 1008:
    for user in users:
        currentstreams = twitch.get_streams_by_userlogin(userlogin=user)
        if len(currentstreams['data']) > 0 and active[user] is False:
            embed = {"title": f"Twitch Streamer {user} is active"}
            embed['type'] = 'rich'
            title = currentstreams['data'][0]['title']
            embed[
                'description'] = f"Twitch Stream {user} is currently active and streaming {title}"
            embed['url'] = f"https://www.twitch.tv/{user}"
            DiscordFramework.SendDiscordMessage(message=None,
                                                channelid=channelid,
                                                embed=embed)
            active[user] = True
def GetClanInfo(wgclanid: int) -> dict:
    apikey = CommonFramework.RetrieveConfigOptions("wargaming")
    apikey = apikey['apitoken']
    uri = f"https://api.worldoftanks.com/wot/clans/info/?application_id={apikey}&clan_id={wgclanid}"
    return CommonFramework.get_json_data(uri)