async def update_lang(lang, retry=True): t_info = Configuration.get_master_var("TRANSLATIONS") if t_info["SOURCE"] == "DISABLED": return if t_info["SOURCE"] == "CROWDIN": download_link = f"https://api.crowdin.com/api/project/gearbot/export-file?login={t_info['LOGIN']}&account-key={t_info['KEY']}&json&file={urllib.parse.quote('/bot/commands.json', safe='')}&language={lang}" else: download_link = f"https://gearbot.rocks/lang/{lang}.json" GearbotLogging.info(f"Updating {lang} ({LANG_NAMES[lang]}) file...") async with BOT.aiosession.get(download_link) as response: content = await response.text() content = json.loads(content) if "success" in content: if retry: GearbotLogging.warn( f"Failed to update {lang} ({LANG_NAMES[lang]}), trying again in 3 seconds" ) await asyncio.sleep(3) await update_lang(lang, False) else: await tranlator_log( 'NO', f"Failed to update {lang} ({LANG_NAMES[lang]}) from {t_info['SOURCE']}" ) Utils.save_to_disk(f'lang/{lang}', content) LANGS[lang] = content GearbotLogging.info(f"Updated {lang} ({LANG_NAMES[lang]})!")
async def on_member_join(self, member: discord.Member): raid_settings = Configuration.get_var(member.guild.id, "RAID_HANDLING") if not raid_settings["ENABLED"]: return # track in redis, pipelines reduce overhead of multiple commands pipeline = self.bot.redis_pool.pipeline() key = f"joins:{member.guild.id}" pipeline.sadd(key, member.id) # get all potential raiders pipeline.smembers(key) _, potential_raiders = await pipeline.execute() longest = max(h["trigger"]["seconds"] for h in raid_settings["SHIELDS"]) buckets = {h["id"]: [] for h in raid_settings["SHIELDS"]} #cleaning pipe! pipeline = self.bot.redis_pool.pipeline() now = datetime.utcfromtimestamp(time.time()) for user in potential_raiders: m = member.guild.get_member(int(user)) #discard users who are no left already if m is None: pipeline.srem(key, user) continue if m.joined_at is None: GearbotLogging.warn( f"User {m.id} in {m.guild.id} has no joined timestamp, disregarding" ) pipeline.srem(key, user) continue dif = abs((now - m.joined_at).total_seconds()) # clean up users who have been here for long enough if dif >= longest: pipeline.srem(key, user) else: # put them in the buckets for h in raid_settings["SHIELDS"]: if dif < h["trigger"]["seconds"]: buckets[h["id"]].append(m) # clean up now? you crazy, i'll do it later! self.bot.loop.create_task(pipeline.execute()) # stored, fetched and sorted them, now to take care of the bad guys for shield in raid_settings["SHIELDS"]: #check if it's not disabled if not shield["enabled"]: continue # check if active, if it is, let that take care of it if member.guild.id in self.raid_trackers and shield[ "id"] in self.raid_trackers[member.guild.id]["SHIELDS"]: h = self.raid_trackers[member.guild.id]["SHIELDS"][ shield["id"]] if member.id not in self.raid_trackers[ member.guild.id]["raider_ids"]: r = Raider.create( raid=self.raid_trackers[member.guild.id]["raid_id"], user_id=member.id, joined_at=member.joined_at) self.raid_trackers[member.guild.id]["raider_ids"][ member.id] = r.id await h.handle_raider( self.bot, member, self.raid_trackers[member.guild.id]["raid_id"], self.raid_trackers[member.guild.id]["raider_ids"], shield) continue #not active, check if we should trigger trigger_info = shield["trigger"] if len(buckets[shield["id"]]) >= trigger_info["count"] and ( member.guild.id not in self.raid_trackers or shield["id"] not in self.raid_trackers[member.guild.id]["triggered"]): #TRIGGERED if member.guild.id not in self.raid_trackers: # assign raid id, track raiders raid = Raid.create(guild_id=member.guild.id, start=datetime.utcfromtimestamp( time.time())) GearbotLogging.log_key(member.guild.id, 'raid_new', raid_id=raid.id) # create trackers if needed raider_ids = dict() terminator = self.bot.loop.create_task( self.terminator(member.guild.id)) self.raid_trackers[member.guild.id] = dict( raid_id=raid.id, SHIELDS=dict(), raider_ids=raider_ids, triggered=set(), terminator=terminator, timers=[]) for raider in buckets[shield["id"]]: if member.guild.id not in self.raid_trackers or member.id not in self.raid_trackers[ member.guild.id]["raider_ids"]: r = Raider.create(raid=raid, user_id=raider.id, joined_at=raider.joined_at) raider_ids[member.id] = r.id # assign the handler and call execute initial actions h = RaidShield(shield) self.raid_trackers[member.guild.id]["SHIELDS"][ shield["id"]] = h self.raid_trackers[member.guild.id]["triggered"].add( shield["id"]) await h.raid_detected( self.bot, member.guild, self.raid_trackers[member.guild.id]["raid_id"], self.raid_trackers[member.guild.id]["raider_ids"], shield) # create background terminator timer = self.bot.loop.create_task( self.timers[shield["duration"]["type"]]( member.guild.id, h, shield, shield["duration"])) self.raid_trackers[member.guild.id]["timers"].append(timer) # deal with them for raider in buckets[shield["id"]]: await h.handle_raider( self.bot, raider, self.raid_trackers[member.guild.id]["raid_id"], self.raid_trackers[member.guild.id]["raider_ids"], shield)