More error checks, better help, common sense channel edits, and rate limit checks
This commit is contained in:
parent
27df384366
commit
9fdaf6ba07
@ -5,13 +5,14 @@ from redbot.core import Config, checks, commands
|
|||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
from redbot.core.commands import Cog
|
from redbot.core.commands import Cog
|
||||||
|
|
||||||
|
|
||||||
# Cog: Any = getattr(commands, "Cog", object)
|
# Cog: Any = getattr(commands, "Cog", object)
|
||||||
# listener = getattr(commands.Cog, "listener", None) # Trusty + Sinbad
|
# listener = getattr(commands.Cog, "listener", None) # Trusty + Sinbad
|
||||||
# if listener is None:
|
# if listener is None:
|
||||||
# def listener(name=None):
|
# def listener(name=None):
|
||||||
# return lambda x: x
|
# return lambda x: x
|
||||||
|
|
||||||
|
RATE_LIMIT_DELAY = 60 * 10 # If you're willing to risk rate limiting, you can decrease the delay
|
||||||
|
|
||||||
|
|
||||||
class InfoChannel(Cog):
|
class InfoChannel(Cog):
|
||||||
"""
|
"""
|
||||||
@ -21,6 +22,7 @@ class InfoChannel(Cog):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot: Red):
|
def __init__(self, bot: Red):
|
||||||
|
super().__init__()
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = Config.get_conf(
|
self.config = Config.get_conf(
|
||||||
self, identifier=731101021116710497110110101108, force_registration=True
|
self, identifier=731101021116710497110110101108, force_registration=True
|
||||||
@ -37,6 +39,8 @@ class InfoChannel(Cog):
|
|||||||
|
|
||||||
self.config.register_guild(**default_guild)
|
self.config.register_guild(**default_guild)
|
||||||
|
|
||||||
|
self._critical_section_wooah_ = 0
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
@checks.admin()
|
@checks.admin()
|
||||||
async def infochannel(self, ctx: commands.Context):
|
async def infochannel(self, ctx: commands.Context):
|
||||||
@ -46,9 +50,9 @@ class InfoChannel(Cog):
|
|||||||
|
|
||||||
def check(m):
|
def check(m):
|
||||||
return (
|
return (
|
||||||
m.content.upper() in ["Y", "YES", "N", "NO"]
|
m.content.upper() in ["Y", "YES", "N", "NO"]
|
||||||
and m.channel == ctx.channel
|
and m.channel == ctx.channel
|
||||||
and m.author == ctx.author
|
and m.author == ctx.author
|
||||||
)
|
)
|
||||||
|
|
||||||
guild: discord.Guild = ctx.guild
|
guild: discord.Guild = ctx.guild
|
||||||
@ -72,9 +76,13 @@ class InfoChannel(Cog):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if channel is None:
|
if channel is None:
|
||||||
await self.make_infochannel(guild)
|
try:
|
||||||
|
await self.make_infochannel(guild)
|
||||||
|
except discord.Forbidden:
|
||||||
|
await ctx.send("Failure: Missing permission to create voice channel")
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
await self.delete_infochannel(guild, channel)
|
await self.delete_all_infochannels(guild)
|
||||||
|
|
||||||
if not await ctx.tick():
|
if not await ctx.tick():
|
||||||
await ctx.send("Done!")
|
await ctx.send("Done!")
|
||||||
@ -85,6 +93,8 @@ class InfoChannel(Cog):
|
|||||||
"""
|
"""
|
||||||
Toggle different types of infochannels
|
Toggle different types of infochannels
|
||||||
"""
|
"""
|
||||||
|
if not ctx.invoked_subcommand:
|
||||||
|
pass
|
||||||
|
|
||||||
@infochannelset.command(name="botcount")
|
@infochannelset.command(name="botcount")
|
||||||
async def _infochannelset_botcount(self, ctx: commands.Context, enabled: bool = None):
|
async def _infochannelset_botcount(self, ctx: commands.Context, enabled: bool = None):
|
||||||
@ -94,7 +104,10 @@ class InfoChannel(Cog):
|
|||||||
guild = ctx.guild
|
guild = ctx.guild
|
||||||
if enabled is None:
|
if enabled is None:
|
||||||
enabled = not await self.config.guild(guild).bot_count()
|
enabled = not await self.config.guild(guild).bot_count()
|
||||||
|
|
||||||
await self.config.guild(guild).bot_count.set(enabled)
|
await self.config.guild(guild).bot_count.set(enabled)
|
||||||
|
await self.make_infochannel(ctx.guild)
|
||||||
|
|
||||||
if enabled:
|
if enabled:
|
||||||
await ctx.send("InfoChannel for bot count has been enabled.")
|
await ctx.send("InfoChannel for bot count has been enabled.")
|
||||||
else:
|
else:
|
||||||
@ -108,7 +121,10 @@ class InfoChannel(Cog):
|
|||||||
guild = ctx.guild
|
guild = ctx.guild
|
||||||
if enabled is None:
|
if enabled is None:
|
||||||
enabled = not await self.config.guild(guild).online_count()
|
enabled = not await self.config.guild(guild).online_count()
|
||||||
|
|
||||||
await self.config.guild(guild).online_count.set(enabled)
|
await self.config.guild(guild).online_count.set(enabled)
|
||||||
|
await self.make_infochannel(ctx.guild)
|
||||||
|
|
||||||
if enabled:
|
if enabled:
|
||||||
await ctx.send("InfoChannel for online user count has been enabled.")
|
await ctx.send("InfoChannel for online user count has been enabled.")
|
||||||
else:
|
else:
|
||||||
@ -122,25 +138,49 @@ class InfoChannel(Cog):
|
|||||||
guild.me: discord.PermissionOverwrite(manage_channels=True, connect=True),
|
guild.me: discord.PermissionOverwrite(manage_channels=True, connect=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Remove the old info channel first
|
||||||
|
channel_id = await self.config.guild(guild).channel_id()
|
||||||
|
if channel_id is not None:
|
||||||
|
channel: discord.VoiceChannel = guild.get_channel(channel_id)
|
||||||
|
if channel:
|
||||||
|
await channel.delete(reason="InfoChannel delete")
|
||||||
|
|
||||||
|
# Then create the new one
|
||||||
channel = await guild.create_voice_channel(
|
channel = await guild.create_voice_channel(
|
||||||
"Placeholder", reason="InfoChannel make", overwrites=overwrites
|
"Total Humans:", reason="InfoChannel make", overwrites=overwrites
|
||||||
)
|
)
|
||||||
await self.config.guild(guild).channel_id.set(channel.id)
|
await self.config.guild(guild).channel_id.set(channel.id)
|
||||||
|
|
||||||
if botcount:
|
if botcount:
|
||||||
|
# Remove the old bot channel first
|
||||||
|
botchannel_id = await self.config.guild(guild).botchannel_id()
|
||||||
|
if channel_id is not None:
|
||||||
|
botchannel: discord.VoiceChannel = guild.get_channel(botchannel_id)
|
||||||
|
if botchannel:
|
||||||
|
await botchannel.delete(reason="InfoChannel delete")
|
||||||
|
|
||||||
|
# Then create the new one
|
||||||
botchannel = await guild.create_voice_channel(
|
botchannel = await guild.create_voice_channel(
|
||||||
"Placeholder", reason="InfoChannel botcount", overwrites=overwrites
|
"Bots:", reason="InfoChannel botcount", overwrites=overwrites
|
||||||
)
|
)
|
||||||
await self.config.guild(guild).botchannel_id.set(botchannel.id)
|
await self.config.guild(guild).botchannel_id.set(botchannel.id)
|
||||||
if onlinecount:
|
if onlinecount:
|
||||||
|
# Remove the old online channel first
|
||||||
|
onlinechannel_id = await self.config.guild(guild).onlinechannel_id()
|
||||||
|
if channel_id is not None:
|
||||||
|
onlinechannel: discord.VoiceChannel = guild.get_channel(onlinechannel_id)
|
||||||
|
if onlinechannel:
|
||||||
|
await onlinechannel.delete(reason="InfoChannel delete")
|
||||||
|
|
||||||
|
# Then create the new one
|
||||||
onlinechannel = await guild.create_voice_channel(
|
onlinechannel = await guild.create_voice_channel(
|
||||||
"Placeholder", reason="InfoChannel onlinecount", overwrites=overwrites
|
"Online:", reason="InfoChannel onlinecount", overwrites=overwrites
|
||||||
)
|
)
|
||||||
await self.config.guild(guild).onlinechannel_id.set(onlinechannel.id)
|
await self.config.guild(guild).onlinechannel_id.set(onlinechannel.id)
|
||||||
|
|
||||||
await self.update_infochannel(guild)
|
await self.update_infochannel(guild)
|
||||||
|
|
||||||
async def delete_infochannel(self, guild: discord.Guild, channel: discord.VoiceChannel):
|
async def delete_all_infochannels(self, guild: discord.Guild):
|
||||||
guild_data = await self.config.guild(guild).all()
|
guild_data = await self.config.guild(guild).all()
|
||||||
botchannel_id = guild_data["botchannel_id"]
|
botchannel_id = guild_data["botchannel_id"]
|
||||||
onlinechannel_id = guild_data["onlinechannel_id"]
|
onlinechannel_id = guild_data["onlinechannel_id"]
|
||||||
@ -153,6 +193,7 @@ class InfoChannel(Cog):
|
|||||||
await botchannel.delete(reason="InfoChannel delete")
|
await botchannel.delete(reason="InfoChannel delete")
|
||||||
if onlinechannel_id is not None:
|
if onlinechannel_id is not None:
|
||||||
await onlinechannel.delete(reason="InfoChannel delete")
|
await onlinechannel.delete(reason="InfoChannel delete")
|
||||||
|
|
||||||
await self.config.guild(guild).clear()
|
await self.config.guild(guild).clear()
|
||||||
|
|
||||||
async def update_infochannel(self, guild: discord.Guild):
|
async def update_infochannel(self, guild: discord.Guild):
|
||||||
@ -164,23 +205,23 @@ class InfoChannel(Cog):
|
|||||||
# bots = lambda x: x.bot
|
# bots = lambda x: x.bot
|
||||||
# def bots(x): return x.bot
|
# def bots(x): return x.bot
|
||||||
|
|
||||||
num = len([m for m in guild.members if m.bot])
|
bot_num = len([m for m in guild.members if m.bot])
|
||||||
bot_msg = f"Bots: {num}"
|
# bot_msg = f"Bots: {num}"
|
||||||
|
|
||||||
# Gets count of online users
|
# Gets count of online users
|
||||||
members = guild.member_count
|
members = guild.member_count
|
||||||
offline = len(list(filter(lambda m: m.status is discord.Status.offline, guild.members)))
|
offline = len(list(filter(lambda m: m.status is discord.Status.offline, guild.members)))
|
||||||
num = members - offline
|
online_num = members - offline
|
||||||
online_msg = f"Online: {num}"
|
# online_msg = f"Online: {num}"
|
||||||
|
|
||||||
# Gets count of actual users
|
# Gets count of actual users
|
||||||
total = lambda x: not x.bot
|
total = lambda x: not x.bot
|
||||||
num = len([m for m in guild.members if total(m)])
|
human_num = len([m for m in guild.members if total(m)])
|
||||||
human_msg = f"Total Humans: {num}"
|
# human_msg = f"Total Humans: {num}"
|
||||||
|
|
||||||
channel_id = guild_data["channel_id"]
|
channel_id = guild_data["channel_id"]
|
||||||
if channel_id is None:
|
if channel_id is None:
|
||||||
return
|
return False
|
||||||
|
|
||||||
botchannel_id = guild_data["botchannel_id"]
|
botchannel_id = guild_data["botchannel_id"]
|
||||||
onlinechannel_id = guild_data["onlinechannel_id"]
|
onlinechannel_id = guild_data["onlinechannel_id"]
|
||||||
@ -190,30 +231,51 @@ class InfoChannel(Cog):
|
|||||||
onlinechannel: discord.VoiceChannel = guild.get_channel(onlinechannel_id)
|
onlinechannel: discord.VoiceChannel = guild.get_channel(onlinechannel_id)
|
||||||
|
|
||||||
if guild_data["member_count"]:
|
if guild_data["member_count"]:
|
||||||
name = "{} ".format(human_msg)
|
name = f"{channel.name.split(':')[0]}: {human_num}"
|
||||||
|
|
||||||
await channel.edit(reason="InfoChannel update", name=name)
|
await channel.edit(reason="InfoChannel update", name=name)
|
||||||
|
|
||||||
if botcount:
|
if botcount:
|
||||||
name = "{} ".format(bot_msg)
|
name = f"{botchannel.name.split(':')[0]}: {bot_num}"
|
||||||
await botchannel.edit(reason="InfoChannel update", name=name)
|
await botchannel.edit(reason="InfoChannel update", name=name)
|
||||||
|
|
||||||
if onlinecount:
|
if onlinecount:
|
||||||
name = "{} ".format(online_msg)
|
name = f"{onlinechannel.name.split(':')[0]}: {online_num}"
|
||||||
await onlinechannel.edit(reason="InfoChannel update", name=name)
|
await onlinechannel.edit(reason="InfoChannel update", name=name)
|
||||||
|
|
||||||
await asyncio.sleep(60)
|
async def update_infochannel_with_cooldown(self, guild):
|
||||||
|
"""My attempt at preventing rate limits, lets see how it goes"""
|
||||||
|
if self._critical_section_wooah_:
|
||||||
|
if self._critical_section_wooah_ == 2:
|
||||||
|
print("Already pending, skipping")
|
||||||
|
return # Another one is already pending, don't queue more than one
|
||||||
|
print("Queuing another update")
|
||||||
|
self._critical_section_wooah_ = 2
|
||||||
|
|
||||||
|
while self._critical_section_wooah_:
|
||||||
|
await asyncio.sleep(RATE_LIMIT_DELAY // 4) # Max delay ends up as 1.25 * RATE_LIMIT_DELAY
|
||||||
|
|
||||||
|
print("Issuing queued update")
|
||||||
|
return await self.update_infochannel_with_cooldown(guild)
|
||||||
|
|
||||||
|
print("Entering critical")
|
||||||
|
self._critical_section_wooah_ = 1
|
||||||
|
await self.update_infochannel(guild)
|
||||||
|
await asyncio.sleep(RATE_LIMIT_DELAY)
|
||||||
|
self._critical_section_wooah_ = 0
|
||||||
|
print("Exiting critical")
|
||||||
|
|
||||||
@Cog.listener()
|
@Cog.listener()
|
||||||
async def on_member_join(self, member: discord.Member):
|
async def on_member_join(self, member: discord.Member):
|
||||||
await self.update_infochannel(member.guild)
|
await self.update_infochannel_with_cooldown(member.guild)
|
||||||
|
|
||||||
@Cog.listener()
|
@Cog.listener()
|
||||||
async def on_member_remove(self, member: discord.Member):
|
async def on_member_remove(self, member: discord.Member):
|
||||||
await self.update_infochannel(member.guild)
|
await self.update_infochannel_with_cooldown(member.guild)
|
||||||
|
|
||||||
@Cog.listener()
|
@Cog.listener()
|
||||||
async def on_member_update(self, before: discord.Member, after: discord.Member):
|
async def on_member_update(self, before: discord.Member, after: discord.Member):
|
||||||
onlinecount = await self.config.guild(after.guild).online_count()
|
onlinecount = await self.config.guild(after.guild).online_count()
|
||||||
if onlinecount:
|
if onlinecount:
|
||||||
if before.status != after.status:
|
if before.status != after.status:
|
||||||
await self.update_infochannel(after.guild)
|
await self.update_infochannel_with_cooldown(after.guild)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user