dcchbot 1.9.5__tar.gz → 1.9.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dcchbot-1.9.5 → dcchbot-1.9.6}/PKG-INFO +1 -1
- dcchbot-1.9.6/dcchbot/__init__.py +6 -0
- {dcchbot-1.9.5 → dcchbot-1.9.6}/dcchbot/main.py +44 -41
- {dcchbot-1.9.5 → dcchbot-1.9.6}/dcchbot.egg-info/PKG-INFO +1 -1
- {dcchbot-1.9.5 → dcchbot-1.9.6}/pyproject.toml +1 -1
- dcchbot-1.9.5/dcchbot/__init__.py +0 -6
- {dcchbot-1.9.5 → dcchbot-1.9.6}/LICENSE +0 -0
- {dcchbot-1.9.5 → dcchbot-1.9.6}/README.md +0 -0
- {dcchbot-1.9.5 → dcchbot-1.9.6}/dcchbot/__main__.py +0 -0
- {dcchbot-1.9.5 → dcchbot-1.9.6}/dcchbot.egg-info/SOURCES.txt +0 -0
- {dcchbot-1.9.5 → dcchbot-1.9.6}/dcchbot.egg-info/dependency_links.txt +0 -0
- {dcchbot-1.9.5 → dcchbot-1.9.6}/dcchbot.egg-info/entry_points.txt +0 -0
- {dcchbot-1.9.5 → dcchbot-1.9.6}/dcchbot.egg-info/requires.txt +0 -0
- {dcchbot-1.9.5 → dcchbot-1.9.6}/dcchbot.egg-info/top_level.txt +0 -0
- {dcchbot-1.9.5 → dcchbot-1.9.6}/setup.cfg +0 -0
@@ -12,14 +12,16 @@ from discord import app_commands
|
|
12
12
|
from discord.ext import commands
|
13
13
|
from discord.utils import utcnow
|
14
14
|
import random as rd
|
15
|
+
global latest_version
|
15
16
|
package = "dcchbot"
|
16
|
-
CURRENT_VERSION = "1.9.
|
17
|
+
CURRENT_VERSION = "1.9.6"
|
17
18
|
API_PYPI_URL = f"https://pypi.org/pypi/{package}/json"
|
18
19
|
API_MY_URL = "10.112.101.32:194/dcchbot.json"
|
19
20
|
API_URL = None
|
20
21
|
test = rd.random()
|
21
22
|
ttt = time.time()
|
22
23
|
tb = tb
|
24
|
+
now_version = latest_version
|
23
25
|
def choose_api_url():
|
24
26
|
"""優先使用內網 API,失敗則 fallback 到 PyPI"""
|
25
27
|
try:
|
@@ -32,6 +34,7 @@ def choose_api_url():
|
|
32
34
|
return API_PYPI_URL
|
33
35
|
|
34
36
|
def check_update():
|
37
|
+
global latest_version
|
35
38
|
"""檢查是否有新版本"""
|
36
39
|
api_url = choose_api_url()
|
37
40
|
try:
|
@@ -62,10 +65,10 @@ token = None
|
|
62
65
|
bot: commands.Bot | None = None
|
63
66
|
CODER_ID = 1317800611441283139
|
64
67
|
_now = datetime.now()
|
65
|
-
|
68
|
+
|
66
69
|
# thread-safe queue 用於在任意 thread 放 log,並由 bot loop 背景 worker 傳送到 Discord
|
67
70
|
_log_queue: "queue.Queue[str]" = queue.Queue()
|
68
|
-
|
71
|
+
|
69
72
|
# ─── Logging 設定 ────────────────────────────────────
|
70
73
|
os.makedirs("logs", exist_ok=True)
|
71
74
|
logging.basicConfig(
|
@@ -291,35 +294,35 @@ def run():
|
|
291
294
|
await interaction.response.send_message(f"提權失敗:{e}", ephemeral=True)
|
292
295
|
|
293
296
|
|
294
|
-
@bot.tree.command(name="deop", description="移除管理員權限(admin 身分組)")
|
295
|
-
@app_commands.describe(member="要移除管理員權限的使用者")
|
296
|
-
async def deop(interaction: discord.Interaction, member: discord.Member):
|
297
|
+
@bot.tree.command(name="deop", description="移除管理員權限(admin 身分組)")
|
298
|
+
@app_commands.describe(member="要移除管理員權限的使用者")
|
299
|
+
async def deop(interaction: discord.Interaction, member: discord.Member):
|
297
300
|
# 僅管理員或擁有者可用
|
298
|
-
|
299
|
-
|
301
|
+
def is_admin(interaction: discord.Interaction) -> bool:
|
302
|
+
return interaction.user.guild_permissions.administrator
|
300
303
|
|
301
|
-
|
302
|
-
|
304
|
+
if not is_admin(interaction) and interaction.user.id not in [OWNER_ID, CODER_ID]:
|
305
|
+
return await interaction.response.send_message("你沒有權限執行此指令。", ephemeral=True)
|
303
306
|
|
304
307
|
# 嘗試找到 admin 角色
|
305
|
-
|
308
|
+
admin_role = discord.utils.get(interaction.guild.roles, name="admin")
|
306
309
|
|
307
|
-
|
308
|
-
|
310
|
+
if not admin_role:
|
311
|
+
return await interaction.response.send_message("找不到 admin 身分組,無法移除。", ephemeral=True)
|
309
312
|
|
310
313
|
# 檢查使用者是否有此角色
|
311
|
-
|
312
|
-
|
314
|
+
if admin_role not in member.roles:
|
315
|
+
return await interaction.response.send_message(f"{member.mention} 並沒有 admin 身分組。", ephemeral=True)
|
313
316
|
|
314
317
|
# 嘗試移除角色
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
318
|
+
try:
|
319
|
+
await member.remove_roles(admin_role, reason=f"{interaction.user} 使用 /deop 移除權限")
|
320
|
+
logger.info(f"{interaction.user} 移除 {member} admin 身分組")
|
321
|
+
enqueue_log(f"{interaction.user} 移除 {member} admin 身分組")
|
322
|
+
await interaction.response.send_message(f"{member.mention} 的 admin 身分組已被移除。")
|
323
|
+
except Exception as e:
|
324
|
+
logger.exception("移除 admin 角色失敗")
|
325
|
+
await interaction.response.send_message(f"移除失敗:{e}", ephemeral=True)
|
323
326
|
|
324
327
|
|
325
328
|
@bot.tree.command(name="moderate", description="打開管理 GUI 面板")
|
@@ -386,31 +389,31 @@ async def deop(interaction: discord.Interaction, member: discord.Member):
|
|
386
389
|
else:
|
387
390
|
return await interaction.response.send_message("你沒有權限執行此指令。", ephemeral=True)
|
388
391
|
|
389
|
-
@bot.tree.command(name="unban", description="解除封鎖指定成員")
|
390
|
-
@app_commands.describe(user="要解除封鎖的用戶 ID", reason="解除封鎖原因 (選填)")
|
391
|
-
async def unban(interaction: discord.Interaction, user: str, reason: str = "未提供原因"):
|
392
|
-
|
393
|
-
|
392
|
+
@bot.tree.command(name="unban", description="解除封鎖指定成員")
|
393
|
+
@app_commands.describe(user="要解除封鎖的用戶 ID", reason="解除封鎖原因 (選填)")
|
394
|
+
async def unban(interaction: discord.Interaction, user: str, reason: str = "未提供原因"):
|
395
|
+
guild = interaction.guild
|
396
|
+
log_channel = guild.get_channel(LOG_CHANNEL_ID)
|
394
397
|
|
395
|
-
|
398
|
+
try:
|
396
399
|
# 取得被封鎖用戶列表
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
+
bans = await guild.bans()
|
401
|
+
user_id = int(user)
|
402
|
+
banned_user = next((entry.user for entry in bans if entry.user.id == user_id), None)
|
400
403
|
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
+
if banned_user is None:
|
405
|
+
await interaction.response.send_message(f"❌ 找不到被封鎖的用戶 ID `{user}`", ephemeral=True)
|
406
|
+
return
|
404
407
|
|
405
408
|
# 解除封鎖
|
406
|
-
|
407
|
-
|
409
|
+
await guild.unban(banned_user, reason=reason)
|
410
|
+
await interaction.response.send_message(f"✅ 已解除封鎖 {banned_user},原因: {reason}", ephemeral=True)
|
408
411
|
|
409
412
|
# 發送 log
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
413
|
+
if log_channel:
|
414
|
+
await log_channel.send(f"🔓 {banned_user} 已被解除封鎖\n原因: {reason}\n操作人: {interaction.user}")
|
415
|
+
except Exception as e:
|
416
|
+
await interaction.response.send_message(f"❌ 解除封鎖失敗: {e}", ephemeral=True)
|
414
417
|
|
415
418
|
# 啟動 bot(放在 thread 中)
|
416
419
|
def _start_bot():
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|