Beispiel #1
0
 async def checkPermission(self, rctx, cmd):
     try:
         cmd = "command_{}".format(cmd)
         pr = self.PermissionConfig.cfgPermissions_Roles
         role = "@everyone"
         #check if everybody can use it
         if (cmd in pr[role] and pr[role][cmd]):
             #anyone can use the cmd
             return True
         #check if user can use it
         #Lookup user in linked accounts:
         for user_id, data in self.user_data.items():
             log.info("{} {}".format(data["account_arma3"], rctx.user_guid))
             if ("account_arma3" in data
                     and data["account_arma3"][0] == rctx.user_guid):
                 #check if user has permission:
                 server = self.bot.guilds[0]
                 user = discord.utils.get(server.members, id=int(user_id))
                 if (user):
                     #get user roles, and check if role has permission
                     for role in user.roles:
                         if str(role) in pr.keys():
                             if (cmd in pr[str(role)]
                                     and pr[str(role)][cmd]):
                                 return True
         return False
     except Exception as e:
         log.print_exc()
         log.error(e)
         return False
Beispiel #2
0
    def pre_scan(self):
        try:
            if (self.maxMissions <= 0):
                return
            #disable Event handlers, so they dont trigger
            self.EH.disabled = True

            logs = self.getLogs()
            tempdataMissions = deque(maxlen=self.maxMissions)

            #scan most recent log. Until enough data is collected
            #go from newest to oldest log until the data buffer is filled
            for _log in reversed(logs):
                log.info("Pre-scanning: " + _log)
                self.scanfile(_log)
                if (len(tempdataMissions) + len(self.Missions) <=
                        self.maxMissions):
                    tempdataMissions.extendleft(reversed(self.Missions))
                    self.Missions = deque(maxlen=self.maxMissions)
                    self.Missions.append({"dict": {}, "data": []})
                else:
                    break
                if (len(tempdataMissions) >= self.maxMissions):
                    break
            self.Missions = tempdataMissions
            self.EH.disabled = False
        except Exception as e:
            log.print_exc()
            log.error(e)
Beispiel #3
0
    def processMission(self, event, data):
        try:
            #new mission is being started
            if (event == "Mission readname"):
                self.Missions.append({
                    "dict": {
                        "Server sessionID": self.server_sessionID,
                        event: data
                    },
                    "data": []
                })
            elif (event == "Server sessionID"):
                self.server_sessionID = data[2].group(2)

            #mission is complete, switching to between mission block
            elif (event == "Mission finished" or event == "Mission restarted"):
                log.info("{} {}".format(
                    self.Missions[-1]["dict"]["Mission id"][0],
                    self.Missions[-1]["dict"]["Mission id"][1]))
                self.Missions[-1]["dict"][event] = data
                self.Missions.append({
                    "dict": {
                        "Server sessionID": self.server_sessionID
                    },
                    "data": []
                })

            #process data within a mission
            elif ("Mission" in event):
                self.Missions[-1]["dict"][event] = data
            self.Missions[-1]["data"].append(data)
        except Exception as e:
            log.print_exc()
            log.error(e)
Beispiel #4
0
    def add_role(self, data):
        role = data["add_role"][0]
        log.info("Created new role: '{}'".format(role))
        self.cfgPermissions_Roles[role] = type(self).cfg.new(
            type(self).path + "/permissions_{}.json".format(role))

        for command in type(self).bot.commands:
            self.cfgPermissions_Roles[role]["command_" + str(command)] = False
Beispiel #5
0
 async def genStats(self, ctx):
     await ctx.send("Generating Player stats...")
     log.info("[JMW] Updating Player stats")
     t = threading.Thread(target=self.psg.generateStats())
     t.start()
     self.psg_updated = datetime.datetime.now(datetime.timezone.utc)
     t.join()
     await ctx.send("Stats Updated")
Beispiel #6
0
 def _generateGame(self, gameindex=None):
     if(gameindex == None):
         gameindex = 0
     log.info("Generating Game, index: '{}'".format(gameindex))
     game = self.buildGameBlock(gameindex)
     dict, game = self.processGameBlock(game)
     meta, pdata = self.processGameData(game)
     return [meta, pdata, dict]
Beispiel #7
0
 async def on_ready(self):
     await self.bot.wait_until_ready()
     if ("CommandRcon" not in self.bot.cogs):
         log.info(
             "[module] 'CommandRcon' required, but not found in '{}'. Module unloaded"
             .format(type(self).__name__))
         del self
         return
     self.CommandRcon = self.bot.cogs["CommandRcon"]
Beispiel #8
0
    def upgrade_database(self):
        try:
            json_f = self.path + "/player_db.json"
            if (not os.path.isfile(json_f)):
                return

            #get the count of tables with the name
            self.c.execute(
                ''' SELECT count(name) FROM sqlite_master WHERE type='table' AND name='users' '''
            )
            if self.c.fetchone()[0] == 0:

                #load old table
                with open(json_f) as json_file:
                    data_db = json.load(json_file)

                data = []
                for key, item in data_db.items():
                    for _item in item:
                        id = None
                        name = None
                        beid = None
                        ip = None
                        date = None
                        if "ID" in _item:
                            id = int(_item["ID"])
                        if "name" in _item:
                            name = _item["name"]
                        if "beid" in _item:
                            beid = _item["beid"]
                        if "ip" in _item:
                            ip = _item["ip"]
                        if "last-seen" in _item:
                            date = _item["last-seen"]
                        data.append((id, name, beid, ip, date))

                self.c.execute("""
                    CREATE TABLE users (
                        id INTEGER NOT NULL,
                        name  TEXT,
                        beid TEXT,
                        ip TEXT,
                        stamp DATETIME,
                        profileid INTEGER
                    );
                """)

                #date yyyy-MM-dd HH:mm:ss
                sql = 'INSERT INTO users (id, name, beid, ip, stamp) values(?, ?, ?, ?, ?)'
                self.c.executemany(sql, data)
                self.con.commit()
                json_f_new = json_f.replace(".json", "_old.json")
                os.rename(json_f, json_f_new)
                log.info("*** Database has been upgraded! ***")
        except Exception as e:
            log.print_exc()
            log.error(e)
Beispiel #9
0
 async def task_setStatus(self):
     while True:
         try:
             await asyncio.sleep(60)
             await self.setStatus()
         except (KeyboardInterrupt, asyncio.CancelledError):
             log.info("[asyncio] exiting", task_setStatus)
         except Exception as e:
             log.error("setting status failed", e)
             log.print_exc()
Beispiel #10
0
 def test(self, msg):
     try:
         print(log)
         print(log.info)
         log.info(msg)
         log.warning(msg)
         log.error(msg)
         print(log.handlers)
         return "Sucess"
     except Exception as e:
         print(e)
Beispiel #11
0
 def stop_server(self, pid=-1):
     if(self.server_pid != None):
         self.server_pid.kill()
         self.server_pid = None
     elif(pid>=0):
         try:
             os.kill(pid, 0)
         except SystemError as e:
             pass
         log.info("Terminated process '{}'".format(pid))
     else:
         return False
Beispiel #12
0
 async def dm_users_new_game(self):
     if (self.bot.is_closed()):
         return False
     msg = "A game just ended, now is the best time to join for a new game!"
     for user in self.user_data:
         if "nextgame" in self.user_data[user] and self.user_data[user][
                 "nextgame"] == True:
             log.info("sending DM to: " + str(user))
             puser = self.bot.get_user(int(user))
             await puser.send(msg)
             self.user_data[user]["nextgame"] = False
     await self.set_user_data()  #save changes
Beispiel #13
0
    async def bans_watchdog(self):
        #watches for changes that are not noted in the log (e.g. removal of bans)
        #on every check the full ban list will be copied,
        #for large ban lists its recommended to keep the update rate >60s

        #bans format: ["ID", "GUID", "Time", "Reason"]
        log.info("Starting ban watchdog")
        try:
            while True:
                await asyncio.sleep(60)
                await self.check_newBan()
        except (KeyboardInterrupt, asyncio.CancelledError):
            log.info("[asyncio] exiting {}".format(bans_watchdog))
Beispiel #14
0
 async def task_updatePlayerStats(self):
     await asyncio.sleep(60 * 2)
     while True:
         try:
             log.info("[JMW] Updating Player stats")
             t = threading.Thread(target=self.psg.generateStats())
             t.start()
             self.psg_updated = datetime.datetime.now(datetime.timezone.utc)
         except (KeyboardInterrupt, asyncio.CancelledError):
             pass
         except Exception as e:
             log.error("Failed to update player stats", e)
             log.print_exc()
         await asyncio.sleep(60 * 60 * 24)
Beispiel #15
0
    async def watch_log(self):
        try:
            update_counter = 0
            while (True):  #Wait till a log file exsists
                logs = self.getLogs()
                if (len(logs) > 0):
                    self.current_log = logs[-1]
                    log.info("current log: " + self.current_log)
                    self.currentLinePos = 0
                    file = open(self.log_path + self.current_log, "r")
                    for i, l in enumerate(file):
                        pass
                    self.currentLinePos = i + 1
                    #file.seek(0, 2) #jump to the end of the file
                    try:
                        while (True):
                            #where = file.tell()
                            try:
                                line = file.readline()
                                update_counter += 1
                            except:
                                line = None
                            if not line:
                                await asyncio.sleep(1)
                                #file.seek(where)
                                if (
                                        update_counter >= 60
                                ):  #only check for new log files every 60s, to reduce IOPS
                                    update_counter = 0
                                    if (self.current_log !=
                                            self.getLogs()[-1]):
                                        old_log = self.current_log
                                        self.current_log = self.getLogs()[
                                            -1]  #update to new recent log
                                        self.currentLinePos = 0
                                        file = open(
                                            self.log_path + self.current_log,
                                            "r")
                                        log.info("current log: " +
                                                 self.current_log)
                                        self.EH.check_Event(
                                            "Log new", old_log,
                                            self.current_log)
                            else:
                                self.currentLinePos += 1
                                self.line = line  #access to last read line (debugging)
                                self.processLogLine(line)

                    except (KeyboardInterrupt, asyncio.CancelledError):
                        log.info("[asyncio] exiting {}".format(watch_log))
                    except Exception as e:
                        log.error(e)
                        log.print_exc()
                else:
                    await asyncio.sleep(10 * 60)
        except (KeyboardInterrupt, asyncio.CancelledError):
            log.info("[asyncio] exiting {}".format(watch_log))
        except Exception as e:
            log.print_exc()
            log.error(e)
Beispiel #16
0
async def main():

    utils.Modules.loadCogs(bot)

    try:
        await bot.login(cfg["TOKEN"])
        await bot.connect()
    except (KeyboardInterrupt, asyncio.CancelledError):
        sys.exit("Bot Terminated (KeyboardInterrupt)")
    except (KeyError, discord.errors.LoginFailure):
        log.info("PROMPT: Please configure the bot")
        input(
            "\nPlease configure the bot on the settings page. [ENTER to terminte the bot]\n"
        )
Beispiel #17
0
 def _start_server(self, port=8000):
     s_port = port
     with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
         while (s.connect_ex(('localhost', port)) == 0):
             port += 1
             if (port >= 65535):
                 raise ConnectionAbortedError(
                     "Unable to find free port".format(port))
     if (s_port != port):
         log.info("[WARNING] Port '{}' already in use, using '{}' instead.".
                  format(s_port, port))
     log.info("Settings page online on: http://localhost:{}/".format(port))
     self.httpd = HTTPServer(('localhost', port), SimpleHTTPRequestHandler)
     self.httpd.serve_forever()
Beispiel #18
0
 def verifyAccount(self, verifyCode, link_id):
     try:
         verifyCode = self.account_verify_codes.index(verifyCode)
     except ValueError:
         log.info("Account not found ({}, {})".format(verifyCode, link_id))
         verifyCode = None
     else:
         verifyCode = self.account_verify_codes[verifyCode]
     if (verifyCode):
         log.info("[ingcmd] Linked account '{}' with arma 3 '{}'".format(
             verifyCode.authorID, link_id))
         self.set_user_data(str(verifyCode.authorID), "account_arma3",
                            link_id)
         return True
     return False
Beispiel #19
0
    def alter_database(self):
        try:
            ## Alter table (upgrade by adding the profileid column)
            self.c.execute(
                "SELECT COUNT(*) AS CNTREC FROM pragma_table_info('users') WHERE name='profileid'"
            )
            if self.c.fetchone()[0] == 0:

                sql = """   ALTER TABLE users
                            ADD COLUMN profileid INTEGER;"""
                self.c.execute(sql)
                self.con.commit()
                log.info("Altered DB Table: 'Added COLUMN profileid'")
        except Exception as e:
            log.print_exc()
            log.error(e)
Beispiel #20
0
 async def on_ready(self):
     await self.bot.wait_until_ready()
     self.channel = self.bot.get_channel(self.cfg["post_channel"])
     if ("CommandRcon" not in self.bot.cogs):
         log.info(
             "[module] 'CommandRcon' required, but not found in '{}'. Module unloaded"
             .format(type(self).__name__))
         del self
         return
     try:
         self.CommandRcon = self.bot.cogs["CommandRcon"]
         self.CommandRcon.arma_rcon.add_Event("received_ServerMessage",
                                              self.rcon_on_msg_received)
     except Exception as e:
         log.print_exc()
         log.error(e)
Beispiel #21
0
    async def query(self, ctx, *query):
        try:
            query = " ".join(query)
            log.info(query)
            result = self.c.execute(query)
            result = list(result)
            self.con.commit()

            msg = ""
            for row in result[:15]:
                msg += "{}\n".format(row)
            if (msg == ""):
                msg = "Query returned nothing"
        except Exception as e:
            msg = str(e)
        await ctx.send(msg)
Beispiel #22
0
    async def rcon_on_disconnect(self):
        await asyncio.sleep(10)

        # cleanup old records
        try:
            while self.lastReconnect[0] < datetime.datetime.now() - datetime.timedelta(seconds=60):
                self.lastReconnect.popleft()
        except IndexError:
            pass # there are no records in the queue.
        if len(self.lastReconnect) > self.rcon_settings["max_reconnects_per_minute"]:
            log.warning("Stopped Reconnecting - Too many reconnects!")
            if(self.streamChat):
                await self.streamChat.send(":warning: Stopped Reconnecting - Too many reconnects!\n Reconnect with '!reconnect'")
        else:
            self.lastReconnect.append(datetime.datetime.now())
            log.info("Reconnecting to BEC Rcon")
            self.setupRcon(self.arma_rcon.serverMessage) #restarts form scratch (due to weird behaviour on reconnect)
Beispiel #23
0
    def loadCogs(bot):
        Modules.module_list = sorted(list(glob.glob("modules/*")))

        for module in Modules.module_list:
            module = module.replace("\\", "/")
            try:
                cfg = Modules.loadCfg(module)
                if (cfg):
                    CoreConfig.modules[module] = {
                        Modules.general_settings_file: cfg
                    }
                    if (cfg["load_module"] == True):
                        bot.load_extension(
                            module.replace("/", ".") + ".module")
                else:
                    log.info("[Modules] Skipped Cogs in '{}'".format(module))
            except (discord.ClientException, ModuleNotFoundError) as e:
                log.print_exc()
                log.error(f'Failed to load extension: {module} ({e})')
        Modules.fix_wrappers()
Beispiel #24
0
    def __init__(self, log_path, maxMisisons=20):
        self.maxMisisons = maxMisisons  #max amount of Missions stored in the buffer
        #also contains datablock between the mission
        #(e.g 2 scenarios played --> 5 Missions blocks)

        self.path = os.path.dirname(os.path.realpath(__file__))
        self.log_path = log_path
        self.currentLinePos = 0
        self.current_log = None
        self.multiEventLock = None
        self.multiEventLockData = []
        if (len(self.getLogs()) == 0):
            log.info("[WARNNING] No log files found in '{}'".format(
                self.log_path))

        #all data rows are stored in here, limited to prevent memory leaks
        self.Missions = deque(maxlen=self.maxMisisons)
        self.Missions.append({"dict": {}, "data": []})

        self.define_line_types()
Beispiel #25
0
 async def on_ready(self):
     await self.bot.wait_until_ready()
     #await asyncio.sleep(60) #wait addional time for everything to be ready
     try:
         if ("CommandRcon" not in self.bot.cogs):
             log.info(
                 "[module] 'CommandRcon' required, but not found in '{}'. Module unloaded"
                 .format(type(self).__name__))
             del self
             return
         self.CommandRcon = self.bot.cogs["CommandRcon"]
         self.post_channel = self.bot.get_channel(
             self.cfg["post_channel"])  #channel id
         self.CommandRcon.arma_rcon.add_Event("received_ServerMessage",
                                              self.rcon_on_msg_received)
         await self.init_bans_watchdog()
     except (KeyboardInterrupt, asyncio.CancelledError):
         log.info("[asyncio] exiting {}".format(on_ready))
     except Exception as e:
         log.print_exc()
         log.error(e)
Beispiel #26
0
    async def linkAccount(self, ctx):
        code = AccountVerificationCode(ctx.author.id, timelimit=60 * 5)
        asyncio.ensure_future(code.destruct(code))
        self.account_verify_codes.append(code)

        log.info("[ingcmd] Generated code '{}' for user {} [{}]".format(
            code, ctx.author.name, ctx.author.id))
        msg = "To verify your account, use the in game command '{}link {}'\nThe code is valid for 5min.".format(
            RconCommandEngine.command_prefix, code)

        if (str(ctx.author.id) in self.user_data
                and "account_arma3" in self.user_data[str(ctx.author.id)]):
            msg = "You account is already linked.\n" + msg
        await ctx.author.send(
            msg
        )  #handle the case that the user blocked the bot / does not have DM enabled

        await asyncio.sleep(60 * 5)
        if (not (str(ctx.author.id) in self.user_data
                 and "account_arma3" in self.user_data[str(ctx.author.id)])):
            await ctx.author.send("Code expired")
    def processLogLine(self, timestamp, line):
        #check if line contains a datapacket
        m = re.match('^(\[\["CTI_DataPacket","(.*?)"],.*])', line)
        if(m):
            type = m.group(2)
            try:
                datarow = self.parseLine(line) #convert string into array object
                if(type == "Header"):
                    datarow["timestamp"] = timestamp
                    return datarow
                elif("Data_" in type):
                    index = int(re.match('.*_([0-9]*)', type).group(1))
                    if(len(self.databuilder)>0):
                        index_db = int(re.match('.*_([0-9]*)', self.databuilder["CTI_DataPacket"]).group(1))
                        #check if previous 'Data_x' is present
                        if(index_db+1 == index):
                            self.databuilder = self.updateDicArray(self.databuilder, datarow)
                            #If last element "Data_EOD" is present, 
                            if("EOD" in type):
                                self.databuilder["CTI_DataPacket"] = "Data"
                                datarow = self.databuilder.copy()
                                self.databuilder = {}
                                return datarow
                    elif(type == "Data_1"):
                        #add first element
                        self.databuilder = self.updateDicArray(self.databuilder, datarow)

                elif(type == "EOF"):
                    pass
                    #raise Exception("Read mission EOF")
                    #return datarow #return EOF (should usually never be called)
                elif(type == "GameOver"):
                    datarow["timestamp"] = timestamp #finish time
                    return datarow #return Gameover / End
                
            except Exception as e:
                log.error(e)
                log.info(line)
                log.print_exc()
Beispiel #28
0
async def on_ready():
    log.info('Logged in as {} [{}]'.format(bot.user.name, bot.user.id))
    log.info(bot.guilds)
    log.info('------------')
    roles = []
    for guild in list(bot.guilds):
        roles += await guild.fetch_roles()
    bot.CoreConfig.load_role_permissions(roles)
Beispiel #29
0
    def set_module_settings(file, data):
        #log.info(data)

        #for key,row in data.items():
        key = data["name"][0]
        if ("value" not in data):
            new_val = ""
        else:
            new_val = data["value"][0]

        keys = key.split(".")
        if (len(keys) == 3):
            old_val = WebServer.bot.CoreConfig.modules[keys[0]][keys[1]][
                keys[2]]
            if (isinstance(old_val, str)):
                new_val = str(new_val)
            elif (isinstance(old_val, bool)):
                if (new_val.lower() in [
                        'true', '1', 't', 'y', 'yes', 'yeah', 'yup',
                        'certainly', 'uh-huh'
                ]):
                    new_val = True
                else:
                    new_val = False
            elif (isinstance(old_val, int)):
                if (new_val == ""):
                    new_val = 0
                else:
                    new_val = int(new_val)
            else:
                raise Exception("Unkown datatype '{}'".format(type(value)))
            WebServer.bot.CoreConfig.modules[keys[0]][keys[1]][
                keys[2]] = new_val
            log.info("{}, to {}".format(keys, new_val))
            WebServer.bot.CoreConfig.modules[keys[0]][keys[1]].json_save()
        else:
            raise Exception("Invalid data structure for '{}'".format(data))
Beispiel #30
0
 def check_log_events(self, line, events):
     if (self.multiEventLock):
         try:
             m = re.match(self.multiEventLock[2], line)
             if m:
                 self.multiEventLockData.append(line)
                 result = (self.multiEventLock[0], self.multiEventLockData)
                 self.multiEventLock = None
                 tmpB = self.multiEventLockData.copy()
                 self.multiEventLockData = []
                 return result
             self.multiEventLockData.append(line)
             if (len(self.multiEventLockData) > 5):  #max multi line lenght
                 log.info(
                     "Warning Exceeded 'multiEventLock' length! For '{}'".
                     format(
                         (self.multiEventLock[0], self.multiEventLockData)))
                 self.multiEventLock = None
                 self.multiEventLockData = []
         except Exception as e:
             log.print_exc()
             raise Exception(
                 "Error processing MultiEventLock: '{}' '{}'".format(
                     self.multiEventLock, e))
     else:
         try:
             for event in events:
                 m = re.match(event[1], line)
                 if m:
                     if (len(event) > 2):
                         self.multiEventLock = event
                         self.multiEventLockData.append(line)
                     else:
                         return event[0], m
         except Exception as e:
             raise Exception("Invalid Regex: '{}' '{}'".format(event, e))
     return None, None