-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
170 lines (133 loc) · 5.1 KB
/
main.py
File metadata and controls
170 lines (133 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import discord
from discord.ext import commands
import asyncio
import sys
from pathlib import Path
from loguru import logger
# Adiciona src ao path
sys.path.insert(0, str(Path(__file__).parent))
from src.config import get_settings
from src.database import db
from src.services import roblox_api
from src.cogs.tickets import TicketCreateButton, setup_ticket_panel
class RobuxBot(commands.Bot):
"""Bot principal de vendas de Robux."""
def __init__(self):
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
intents.guilds = True
super().__init__(command_prefix="!", intents=intents, help_command=None)
self.settings = get_settings()
self.ticket_coupons = {} # Cache de cupons por ticket
async def setup_hook(self):
"""Configuração inicial do bot."""
logger.info("🔧 Iniciando configuração do bot...")
# Conecta ao PostgreSQL
await db.connect(self.settings.database_url)
# Valida cookie do Roblox
valid, message = await roblox_api.validate_cookie()
if valid:
logger.success(f"🎮 Roblox: {message}")
else:
logger.warning(f"⚠️ Roblox: {message}")
# Registra views persistentes
self.add_view(TicketCreateButton())
from src.cogs.tickets import TicketActionsView
from src.cogs.orders import OrderActionsView, GamepassConfirmView
self.add_view(TicketActionsView())
self.add_view(OrderActionsView())
self.add_view(GamepassConfirmView())
# Views de tickets são adicionadas dinamicamente
# Carrega cogs
cogs = [
"src.cogs.orders",
"src.cogs.admin",
"src.cogs.user",
"src.cogs.tickets",
]
for cog in cogs:
try:
await self.load_extension(cog)
logger.info(f"✅ Cog carregada: {cog}")
except Exception as e:
logger.error(f"❌ Erro ao carregar {cog}: {e}")
# Sincroniza comandos
try:
guild = discord.Object(id=self.settings.discord_guild_id)
self.tree.copy_global_to(guild=guild)
synced = await self.tree.sync(guild=guild)
logger.success(f"✅ {len(synced)} comandos sincronizados")
except Exception as e:
logger.error(f"❌ Erro ao sincronizar comandos: {e}")
async def on_ready(self):
"""Evento quando o bot está pronto."""
logger.success(f"🤖 Bot conectado como {self.user}")
logger.info(f"📊 Servidores: {len(self.guilds)}")
# Configura status
await self.change_presence(
activity=discord.Activity(
type=discord.ActivityType.watching, name="💎 Loja de Robux"
)
)
# Configura painel de tickets
await asyncio.sleep(2) # Aguarda cache carregar
await setup_ticket_panel(self)
async def on_guild_join(self, guild: discord.Guild):
"""Evento quando bot entra em um servidor."""
logger.info(f"➕ Entrou no servidor: {guild.name} ({guild.id})")
async def on_guild_remove(self, guild: discord.Guild):
"""Evento quando bot sai de um servidor."""
logger.info(f"➖ Saiu do servidor: {guild.name} ({guild.id})")
async def on_command_error(self, ctx: commands.Context, error: Exception):
"""Handler global de erros."""
if isinstance(error, commands.CommandNotFound):
return
logger.error(f"❌ Erro no comando: {error}")
if isinstance(error, commands.MissingPermissions):
await ctx.send("❌ Você não tem permissão para isso!")
elif isinstance(error, commands.MissingRequiredArgument):
await ctx.send(f"❌ Argumento obrigatório: `{error.param.name}`")
else:
await ctx.send("❌ Ocorreu um erro. Tente novamente.")
async def close(self):
"""Cleanup ao fechar o bot."""
logger.info("🔌 Desconectando...")
await roblox_api.close()
await db.disconnect()
await super().close()
def setup_logging():
"""Configura o sistema de logs."""
logger.remove()
# Console
logger.add(
sys.stdout,
format="<green>{time:HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{message}</cyan>",
level="INFO",
colorize=True,
)
# Arquivo
logger.add(
"logs/bot_{time:YYYY-MM-DD}.log",
format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {message}",
level="DEBUG",
rotation="00:00",
retention="7 days",
)
async def main():
"""Função principal."""
setup_logging()
logger.info("=" * 50)
logger.info("🚀 Iniciando Bot de Vendas de Robux")
logger.info("=" * 50)
bot = RobuxBot()
try:
await bot.start(bot.settings.discord_token)
except KeyboardInterrupt:
logger.info("⏹️ Interrompido pelo usuário")
except Exception as e:
logger.error(f"❌ Erro fatal: {e}")
finally:
await bot.close()
if __name__ == "__main__":
asyncio.run(main())