.
This commit is contained in:
parent
5368d21be4
commit
7222239774
3
bot.py
3
bot.py
@ -136,6 +136,9 @@ modules_path = pathlib.Path(__file__).parent / 'modules'
|
|||||||
extensions = []
|
extensions = []
|
||||||
for folder in modules_path.iterdir():
|
for folder in modules_path.iterdir():
|
||||||
if folder.is_dir():
|
if folder.is_dir():
|
||||||
|
# skip non-cog helpers under modules/common
|
||||||
|
if folder.name == 'common':
|
||||||
|
continue
|
||||||
for file in folder.glob('*.py'):
|
for file in folder.glob('*.py'):
|
||||||
if file.name == '__init__.py':
|
if file.name == '__init__.py':
|
||||||
continue
|
continue
|
||||||
|
@ -572,14 +572,27 @@ async def setup(bot):
|
|||||||
cog = PirateReportCog(bot)
|
cog = PirateReportCog(bot)
|
||||||
await bot.add_cog(cog)
|
await bot.add_cog(cog)
|
||||||
|
|
||||||
# Register commands either globally or to a specific guild if configured
|
|
||||||
home_gid = cfg(bot).int('home_guild_id', 0)
|
home_gid = cfg(bot).int('home_guild_id', 0)
|
||||||
|
guild_obj = discord.Object(id=home_gid) if home_gid else None
|
||||||
|
|
||||||
|
def _rm(name: str):
|
||||||
|
try:
|
||||||
|
bot.tree.remove_command(name, guild=guild_obj)
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
bot.tree.remove_command(name, guild=None)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# make re-loads idempotent
|
||||||
|
for name in ("report", "edit_pirate", "encounter"):
|
||||||
|
_rm(name)
|
||||||
|
|
||||||
if home_gid:
|
if home_gid:
|
||||||
guild_obj = discord.Object(id=home_gid)
|
|
||||||
bot.tree.add_command(cog.report, guild=guild_obj)
|
bot.tree.add_command(cog.report, guild=guild_obj)
|
||||||
bot.tree.add_command(cog.edit_pirate, guild=guild_obj)
|
bot.tree.add_command(cog.edit_pirate, guild=guild_obj)
|
||||||
bot.tree.add_command(cog.encounter, guild=guild_obj)
|
bot.tree.add_command(cog.encounter, guild=guild_obj)
|
||||||
else:
|
else:
|
||||||
bot.tree.add_command(cog.report)
|
bot.tree.add_command(cog.report)
|
||||||
bot.tree.add_command(cog.edit_pirate)
|
bot.tree.add_command(cog.edit_pirate)
|
||||||
bot.tree.add_command(cog.encounter)
|
bot.tree.add_command(cog.encounter)
|
@ -2,7 +2,8 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from mod_perms import require_mod_ctx # ctx-aware mod gate
|
from mod_perms import require_mod_ctx
|
||||||
|
from modules.common.settings import cfg as _cfg
|
||||||
|
|
||||||
|
|
||||||
class PiratesListCog(commands.Cog):
|
class PiratesListCog(commands.Cog):
|
||||||
@ -16,29 +17,17 @@ class PiratesListCog(commands.Cog):
|
|||||||
Posts are chunked to stay <2000 chars and previous posts are deleted on refresh.
|
Posts are chunked to stay <2000 chars and previous posts are deleted on refresh.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
cfg = bot.config["DEFAULT"]
|
|
||||||
self.list_channel_id = int(cfg["pirates_list_channel_id"])
|
c = _cfg(bot)
|
||||||
try:
|
self.list_channel_id = c.int("pirates_list_channel_id")
|
||||||
self.group_threshold = int(cfg.get("threat_group_threshold", "3"))
|
self.group_threshold = c.int("threat_group_threshold", 3)
|
||||||
except Exception:
|
self.min_samples = c.int("threat_min_samples_for_stats", 3)
|
||||||
self.group_threshold = 3
|
|
||||||
try:
|
|
||||||
self.min_samples = int(cfg.get("threat_min_samples_for_stats", "3"))
|
|
||||||
except Exception:
|
|
||||||
self.min_samples = 3
|
|
||||||
|
|
||||||
# serialize refreshes per guild
|
# serialize refreshes per guild
|
||||||
self._locks = {}
|
self._locks: dict[int, asyncio.Lock] = {}
|
||||||
self._no_mentions = discord.AllowedMentions.none()
|
# never ping on posted content
|
||||||
|
|
||||||
def _lock_for(self, guild_id: int):
|
|
||||||
import asyncio
|
|
||||||
self._locks.setdefault(guild_id, asyncio.Lock())
|
|
||||||
return self._locks[guild_id]
|
|
||||||
|
|
||||||
# send settings: never ping on posted content
|
|
||||||
self._no_mentions = discord.AllowedMentions.none()
|
self._no_mentions = discord.AllowedMentions.none()
|
||||||
|
|
||||||
# ----------------- utils -----------------
|
# ----------------- utils -----------------
|
||||||
@ -119,30 +108,19 @@ class PiratesListCog(commands.Cog):
|
|||||||
|
|
||||||
async def refresh_list(self, guild: discord.Guild):
|
async def refresh_list(self, guild: discord.Guild):
|
||||||
"""Edit list messages in place; only send extra messages when we need more chunks (new pirates)."""
|
"""Edit list messages in place; only send extra messages when we need more chunks (new pirates)."""
|
||||||
# ---- serialize per guild ----
|
async with self._lock_for(guild.id):
|
||||||
lock = getattr(self, "_locks", {}).get(guild.id)
|
|
||||||
if lock is None:
|
|
||||||
# tiny fallback if you didn't add _lock_for()
|
|
||||||
import asyncio as _asyncio
|
|
||||||
if not hasattr(self, "_locks"):
|
|
||||||
self._locks = {}
|
|
||||||
self._locks[guild.id] = _asyncio.Lock()
|
|
||||||
lock = self._locks[guild.id]
|
|
||||||
|
|
||||||
async with lock:
|
|
||||||
channel = guild.get_channel(self.list_channel_id)
|
channel = guild.get_channel(self.list_channel_id)
|
||||||
if not channel:
|
if not channel:
|
||||||
print("[pirates_list] list channel not found:", self.list_channel_id)
|
print("[pirates_list] list channel not found:", self.list_channel_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
dm = self.bot.data_manager
|
dm = self.bot.data_manager
|
||||||
allow = getattr(self, "_no_mentions", discord.AllowedMentions.none())
|
allow = self._no_mentions
|
||||||
|
|
||||||
# ---- load & prune existing posts for this guild/channel ----
|
# ---- load & prune existing posts for this guild/channel ----
|
||||||
records = [r for r in dm.get("pirates_list_posts")
|
records = [r for r in dm.get("pirates_list_posts")
|
||||||
if r.get("guild_id") == guild.id and r.get("channel_id") == self.list_channel_id]
|
if r.get("guild_id") == guild.id and r.get("channel_id") == self.list_channel_id]
|
||||||
|
|
||||||
# fetch messages (drop any that vanished)
|
|
||||||
msgs, kept_records = [], []
|
msgs, kept_records = [], []
|
||||||
for r in records:
|
for r in records:
|
||||||
try:
|
try:
|
||||||
@ -150,11 +128,8 @@ class PiratesListCog(commands.Cog):
|
|||||||
msgs.append(m)
|
msgs.append(m)
|
||||||
kept_records.append(r)
|
kept_records.append(r)
|
||||||
except Exception:
|
except Exception:
|
||||||
# prune dead record
|
|
||||||
dm.remove("pirates_list_posts", lambda x, mid=r["message_id"]: x.get("message_id") == mid)
|
dm.remove("pirates_list_posts", lambda x, mid=r["message_id"]: x.get("message_id") == mid)
|
||||||
|
|
||||||
records = kept_records # only live ones, in stored order
|
|
||||||
|
|
||||||
# ---- build fresh, sorted contents ----
|
# ---- build fresh, sorted contents ----
|
||||||
pirates = sorted(
|
pirates = sorted(
|
||||||
dm.get("pirates"),
|
dm.get("pirates"),
|
||||||
@ -168,13 +143,11 @@ class PiratesListCog(commands.Cog):
|
|||||||
if not pirates:
|
if not pirates:
|
||||||
placeholder = "_No verified pirates yet._"
|
placeholder = "_No verified pirates yet._"
|
||||||
if msgs:
|
if msgs:
|
||||||
# edit first, delete the rest
|
|
||||||
if msgs[0].content != placeholder:
|
if msgs[0].content != placeholder:
|
||||||
try:
|
try:
|
||||||
await msgs[0].edit(content=placeholder, allowed_mentions=allow)
|
await msgs[0].edit(content=placeholder, allowed_mentions=allow)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("[pirates_list] edit placeholder failed:", repr(e))
|
print("[pirates_list] edit placeholder failed:", repr(e))
|
||||||
# remove extra posts/records
|
|
||||||
for extra in msgs[1:]:
|
for extra in msgs[1:]:
|
||||||
try:
|
try:
|
||||||
await extra.delete()
|
await extra.delete()
|
||||||
@ -214,7 +187,7 @@ class PiratesListCog(commands.Cog):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("[pirates_list] edit block failed:", repr(e))
|
print("[pirates_list] edit block failed:", repr(e))
|
||||||
|
|
||||||
# ---- if we need *more* messages (usually after adding a pirate), send them ----
|
# ---- send additional messages if needed ----
|
||||||
if len(chunks) > len(msgs):
|
if len(chunks) > len(msgs):
|
||||||
for i in range(len(msgs), len(chunks)):
|
for i in range(len(msgs), len(chunks)):
|
||||||
try:
|
try:
|
||||||
@ -227,7 +200,7 @@ class PiratesListCog(commands.Cog):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("[pirates_list] send block failed:", repr(e))
|
print("[pirates_list] send block failed:", repr(e))
|
||||||
|
|
||||||
# ---- if we need fewer messages (e.g., pirate removed), delete extras ----
|
# ---- delete extras if fewer chunks now ----
|
||||||
elif len(chunks) < len(msgs):
|
elif len(chunks) < len(msgs):
|
||||||
extras = msgs[len(chunks):]
|
extras = msgs[len(chunks):]
|
||||||
for m in extras:
|
for m in extras:
|
||||||
@ -252,5 +225,5 @@ class PiratesListCog(commands.Cog):
|
|||||||
await ctx.reply("Pirates list refreshed.", ephemeral=is_slash)
|
await ctx.reply("Pirates list refreshed.", ephemeral=is_slash)
|
||||||
|
|
||||||
|
|
||||||
async def setup(bot):
|
async def setup(bot: commands.Bot):
|
||||||
await bot.add_cog(PiratesListCog(bot))
|
await bot.add_cog(PiratesListCog(bot))
|
||||||
|
@ -561,7 +561,7 @@ class _StartView(discord.ui.View):
|
|||||||
class SpicePayCog(commands.Cog):
|
class SpicePayCog(commands.Cog):
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self-sessions: Dict[tuple, Dict] = {}
|
self.sessions: Dict[tuple, Dict] = {}
|
||||||
|
|
||||||
r = cfg(bot)
|
r = cfg(bot)
|
||||||
def _f(key, default):
|
def _f(key, default):
|
||||||
|
@ -443,7 +443,7 @@ class UserCardsCog(commands.Cog):
|
|||||||
await self._log(member.guild, f"📝 User joined: {member.mention} (ID: {member.id})")
|
await self._log(member.guild, f"📝 User joined: {member.mention} (ID: {member.id})")
|
||||||
await self.refresh_card(member)
|
await self.refresh_card(member)
|
||||||
|
|
||||||
@commands.Cog.listener())
|
@commands.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):
|
||||||
if before.nick != after.nick or before.roles != after.roles:
|
if before.nick != after.nick or before.roles != after.roles:
|
||||||
await self.refresh_card(after)
|
await self.refresh_card(after)
|
||||||
|
Loading…
Reference in New Issue
Block a user