import discord
from discord.ext import commands
import asyncio
import random
import json
import os
from datetime import datetime, timedelta
# ===== CẤU HÌNH =====
TOKEN = "NHẬP_TOKEN_BOT_CỦA_BẠN_VÀO_ĐÂY"
PREFIX = "!"
# ===== KHỞI TẠO BOT =====
intents = discord.Intents.all()
bot = commands.Bot(command_prefix=PREFIX, intents=intents)
# ===== FILE LƯU DỮ LIỆU =====
DATA_FILE = "quest_data.json"
# ===== CẤU TRÚC DỮ LIỆU =====
default_data = {
"auto_quest": {}, # {guild_id: {"channel_id": channel_id, "command": "!quest", "delay": 5, "running": False, "message": None}}
"quest_logs": {} # {guild_id: [{"time": "2024-01-01", "user": "name", "result": "success"}]}
}
def load_data():
if os.path.exists(DATA_FILE):
with open(DATA_FILE, "r", encoding="utf-8") as f:
return json.load(f)
return default_data.copy()
def save_data(data):
with open(DATA_FILE, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
data = load_data()
# ===== HÀM GỬI QUEST TỰ ĐỘNG =====
async def auto_quest_loop(guild_id):
guild_data = data["auto_quest"].get(str(guild_id))
if not guild_data:
return
channel = bot.get_channel(guild_data["channel_id"])
if not channel:
return
command = guild_data.get("command", "!quest")
delay = guild_data.get("delay", 5)
while data["auto_quest"][str(guild_id)]["running"]:
try:
# Gửi lệnh quest
msg = await channel.send(command)
print(f"[{guild_id}] Đã gửi: {command}")
# Đợi phản hồi
def check(m):
return m.channel.id == channel.id and m.reference and m.reference.message_id == msg.id
try:
reply = await bot.wait_for("message", timeout=30.0, check=check)
# Ghi log thành công
log_entry = {
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"user": reply.author.name,
"result": reply.content[:50]
}
if str(guild_id) not in data["quest_logs"]:
data["quest_logs"][str(guild_id)] = []
data["quest_logs"][str(guild_id)].append(log_entry)
if len(data["quest_logs"][str(guild_id)]) > 100:
data["quest_logs"][str(guild_id)] = data["quest_logs"][str(guild_id)][-100:]
save_data(data)
print(f"[{guild_id}] Phản hồi: {reply.content[:50]}")
except asyncio.TimeoutError:
print(f"[{guild_id}] Hết thời gian chờ phản hồi")
# Chờ ngẫu nhiên
await asyncio.sleep(delay + random.uniform(-1, 1))
except discord.Forbidden:
print(f"[{guild_id}] Không có quyền gửi tin nhắn")
data["auto_quest"][str(guild_id)]["running"] = False
save_data(data)
break
except Exception as e:
print(f"[{guild_id}] Lỗi: {e}")
await asyncio.sleep(10)
# ===== LỆNH: !quest_setup =====
@bot.command(name="quest_setup")
@commands.has_permissions(administrator=True)
async def quest_setup(ctx, channel: discord.TextChannel = None, command: str = "!quest", delay: float = 5.0):
"""Thiết lập auto quest cho server
Cách dùng: !quest_setup #channel !quest 5
"""
if channel is None:
channel = ctx.channel
guild_id = str(ctx.guild.id)
if guild_id not in data["auto_quest"]:
data["auto_quest"][guild_id] = {}
data["auto_quest"][guild_id]["channel_id"] = channel.id
data["auto_quest"][guild_id]["command"] = command
data["auto_quest"][guild_id]["delay"] = max(1.0, float(delay))
data["auto_quest"][guild_id]["running"] = False
save_data(data)
embed = discord.Embed(
title="✅ Thiết lập Auto Quest thành công!",
description=f"""
**Kênh:** {channel.mention}
**Lệnh:** `{command}`
**Thời gian chờ:** {delay}s
Dùng `!quest_start` để bắt đầu
Dùng `!quest_stop` để dừng
Dùng `!quest_status` để xem trạng thái
""",
color=discord.Color.green()
)
await ctx.send(embed=embed)
# ===== LỆNH: !quest_start =====
@bot.command(name="quest_start")
@commands.has_permissions(administrator=True)
async def quest_start(ctx):
"""Bắt đầu auto quest"""
guild_id = str(ctx.guild.id)
if guild_id not in data["auto_quest"]:
return await ctx.send("⚠️ Chưa thiết lập! Dùng `!quest_setup` trước.")
if data["auto_quest"][guild_id]["running"]:
return await ctx.send("⚠️ Auto quest đã đang chạy!")
data["auto_quest"][guild_id]["running"] = True
save_data(data)
embed = discord.Embed(
title="▶️ Đã bắt đầu Auto Quest!",
description=f"""
**Kênh:** <#{data['auto_quest'][guild_id]['channel_id']}>
**Lệnh:** `{data['auto_quest'][guild_id]['command']}`
**Chờ mỗi:** {data['auto_quest'][guild_id]['delay']}s
""",
color=discord.Color.blue()
)
await ctx.send(embed=embed)
# Chạy loop
bot.loop.create_task(auto_quest_loop(guild_id))
# ===== LỆNH: !quest_stop =====
@bot.command(name="quest_stop")
@commands.has_permissions(administrator=True)
async def quest_stop(ctx):
"""Dừng auto quest"""
guild_id = str(ctx.guild.id)
if guild_id not in data["auto_quest"]:
return await ctx.send("⚠️ Chưa thiết lập auto quest!")
if not data["auto_quest"][guild_id]["running"]:
return await ctx.send("⚠️ Auto quest đã dừng!")
data["auto_quest"][guild_id]["running"] = False
save_data(data)
embed = discord.Embed(
title="⏹️ Đã dừng Auto Quest!",
description="Auto quest đã được dừng lại.",
color=discord.Color.red()
)
await ctx.send(embed=embed)
# ===== LỆNH: !quest_status =====
@bot.command(name="quest_status")
@commands.has_permissions(administrator=True)
async def quest_status(ctx):
"""Xem trạng thái auto quest"""
guild_id = str(ctx.guild.id)
if guild_id not in data["auto_quest"]:
return await ctx.send("⚠️ Chưa thiết lập auto quest! Dùng `!quest_setup`")
g_data = data["auto_quest"][guild_id]
status = "🟢 Đang chạy" if g_data["running"] else "🔴 Đã dừng"
embed = discord.Embed(
title="📊 Trạng thái Auto Quest",
description=f"""
**Trạng thái:** {status}
**Kênh:** <#{g_data['channel_id']}>
**Lệnh:** `{g_data['command']}`
**Thời gian chờ:** {g_data['delay']}s
""",
color=discord.Color.blue()
)
# Thêm log gần đây
if str(guild_id) in data["quest_logs"] and data["quest_logs"][str(guild_id)]:
logs = data["quest_logs"][str(guild_id)][-5:]
log_text = "\n".join([f"`{l['time']}` {l['user']}: {l['result'][:30]}" for l in logs])
embed.add_field(name="📝 Log gần đây", value=log_text or "Chưa có log", inline=False)
await ctx.send(embed=embed)
# ===== LỆNH: !quest_logs =====
@bot.command(name="quest_logs")
@commands.has_permissions(administrator=True)
async def quest_logs(ctx, limit: int = 20):
"""Xem log auto quest
Cách dùng: !quest_logs 20
"""
guild_id = str(ctx.guild.id)
if guild_id not in data["quest_logs"] or not data["quest_logs"][guild_id]:
return await ctx.send("📭 Chưa có log nào.")
logs = data["quest_logs"][guild_id][-min(limit, 50):]
if not logs:
return await ctx.send("📭 Chưa có log nào.")
# Chia nhỏ nếu quá dài
text = "\n".join([f"`{l['time']}` {l['user']}: {l['result'][:40]}" for l in logs])
if len(text) > 1900:
parts = []
current = ""
for line in text.split("\n"):
if len(current) + len(line) > 1900:
parts.append(current)
current = line + "\n"
else:
current += line + "\n"
if current:
parts.append(current)
for i, part in enumerate(parts):
await ctx.send(f"📝 Log ({i+1}/{len(parts)}):\n```{part}```")
else:
await ctx.send(f"📝 Log gần đây:\n```{text}```")
# ===== LỆNH: !quest_clear =====
@bot.command(name="quest_clear")
@commands.has_permissions(administrator=True)
async def quest_clear(ctx):
"""Xóa toàn bộ cấu hình auto quest"""
guild_id = str(ctx.guild.id)
if guild_id in data["auto_quest"]:
data["auto_quest"][guild_id]["running"] = False
del data["auto_quest"][guild_id]
save_data(data)
await ctx.send("🗑️ Đã xóa cấu hình auto quest!")
# ===== LỆNH: !quest_set_delay =====
@bot.command(name="quest_set_delay")
@commands.has_permissions(administrator=True)
async def quest_set_delay(ctx, delay: float):
"""Đặt thời gian chờ giữa các lần gửi quest
Cách dùng: !quest_set_delay 5
"""
guild_id = str(ctx.guild.id)
if guild_id not in data["auto_quest"]:
return await ctx.send("⚠️ Chưa thiết lập! Dùng `!quest_setup` trước.")
delay = max(1.0, delay)
data["auto_quest"][guild_id]["delay"] = delay
save_data(data)
await ctx.send(f"✅ Đã đặt thời gian chờ thành {delay}s")
# ===== LỆNH: !quest_set_command =====
@bot.command(name="quest_set_command")
@commands.has_permissions(administrator=True)
async def quest_set_command(ctx, *, command: str):
"""Đặt lệnh quest
Cách dùng: !quest_set_command !daily
"""
guild_id = str(ctx.guild.id)
if guild_id not in data["auto_quest"]:
return await ctx.send("⚠️ Chưa thiết lập! Dùng `!quest_setup` trước.")
data["auto_quest"][guild_id]["command"] = command
save_data(data)
await ctx.send(f"✅ Đã đặt lệnh thành `{command}`")
# ===== LỆNH: !quest_set_channel =====
@bot.command(name="quest_set_channel")
@commands.has_permissions(administrator=True)
async def quest_set_channel(ctx, channel: discord.TextChannel):
"""Đặt kênh gửi quest
Cách dùng: !quest_set_channel #general
"""
guild_id = str(ctx.guild.id)
if guild_id not in data["auto_quest"]:
data["auto_quest"][guild_id] = {}
data["auto_quest"][guild_id]["channel_id"] = channel.id
save_data(data)
await ctx.send(f"✅ Đã đặt kênh thành {channel.mention}")
# ===== LỆNH: !quest_help =====
@bot.command(name="quest_help")
async def quest_help(ctx):
"""Hiển thị hướng dẫn sử dụng"""
embed = discord.Embed(
title="📖 Hướng dẫn Auto Quest Bot",
description="Bot tự động gửi lệnh quest theo chu kỳ",
color=discord.Color.gold()
)
embed.add_field(
name="🔧 Thiết lập",
value="""
`!quest_setup #channel !quest 5` - Thiết lập
`!quest_set_channel #channel` - Đổi kênh
`!quest_set_command !daily` - Đổi lệnh
`!quest_set_delay 5` - Đổi thời gian chờ
""",
inline=False
)
embed.add_field(
name="▶️ Điều khiển",
value="""
`!quest_start` - Bắt đầu
`!quest_stop` - Dừng
`!quest_status` - Xem trạng thái
`!quest_clear` - Xóa cấu hình
""",
inline=False
)
embed.add_field(
name="📊 Log",
value="""
`!quest_logs 20` - Xem 20 log gần nhất
""",
inline=False
)
embed.set_footer(text="Yêu cầu quyền Administrator để sử dụng")
await ctx.send(embed=embed)
# ===== SỰ KIỆN KHI BOT SẴN SÀNG =====
@bot.event
async def on_ready():
print(f"✅ Bot đã đăng nhập thành công!")
print(f"📊 Tên: {bot.user.name}")
print(f"🆔 ID: {bot.user.id}")
print(f"🌐 Đang hoạt động trên {len(bot.guilds)} server")
print("-" * 40)
# Khởi động lại các auto quest đang chạy
for guild_id, g_data in data["auto_quest"].items():
if g_data.get("running", False):
guild = bot.get_guild(int(guild_id))
if guild:
print(f"🔄 Khởi động lại auto quest cho server: {guild.name}")
bot.loop.create_task(auto_quest_loop(guild_id))
# ===== SỰ KIỆN KHI BOT JOIN SERVER =====
@bot.event
async def on_guild_join(guild):
print(f"✅ Bot đã tham gia server: {guild.name} ({guild.id})")
# ===== CHẠY BOT =====
if __name__ == "__main__":
print("""
╔══════════════════════════════════════╗
║ AUTO QUEST BOT FOR DISCORD ║
║ by meo bi depzai ║
╚══════════════════════════════════════╝
""")
bot.run(TOKEN)6 views