It works baby, seems like timing could be improved or something, but it freakin works
This commit is contained in:
+264
-3
@@ -1,5 +1,266 @@
|
||||
import 'package:mumbullet/mumbullet.dart' as mumbullet;
|
||||
import 'dart:io';
|
||||
import 'dart:async';
|
||||
import 'package:args/args.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:mumbullet/mumbullet.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
void main(List<String> arguments) {
|
||||
print('Hello world: ${mumbullet.calculate()}!');
|
||||
Future<void> main(List<String> arguments) async {
|
||||
// Parse command line arguments
|
||||
final parser = ArgParser()
|
||||
..addOption('config',
|
||||
abbr: 'c',
|
||||
defaultsTo: 'config.json',
|
||||
help: 'Path to configuration file')
|
||||
..addOption('log-level',
|
||||
abbr: 'l',
|
||||
defaultsTo: 'info',
|
||||
allowed: ['debug', 'info', 'warning', 'error'],
|
||||
help: 'Log level (debug, info, warning, error)')
|
||||
..addFlag('console-log',
|
||||
abbr: 'o',
|
||||
defaultsTo: true,
|
||||
help: 'Log to console')
|
||||
..addOption('log-file',
|
||||
abbr: 'f',
|
||||
help: 'Path to log file')
|
||||
..addFlag('help',
|
||||
abbr: 'h',
|
||||
negatable: false,
|
||||
help: 'Display this help message');
|
||||
|
||||
try {
|
||||
final results = parser.parse(arguments);
|
||||
|
||||
if (results['help'] == true) {
|
||||
print('Mumble Music Bot - A Dart-based music bot for Mumble servers');
|
||||
print('');
|
||||
print('Usage:');
|
||||
print('dart bin/mumbullet.dart [options]');
|
||||
print('');
|
||||
print('Options:');
|
||||
print(parser.usage);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Set up logging
|
||||
final logLevelString = results['log-level'] as String;
|
||||
final Level logLevel = _parseLogLevel(logLevelString);
|
||||
final logManager = LogManager.getInstance();
|
||||
|
||||
logManager.initialize(
|
||||
level: logLevel,
|
||||
logToConsole: results['console-log'] as bool,
|
||||
logFilePath: results['log-file'] as String?,
|
||||
);
|
||||
|
||||
// Load configuration
|
||||
final configPath = results['config'] as String;
|
||||
final logger = logManager.logger;
|
||||
|
||||
logger.info('Starting Mumble Music Bot');
|
||||
logger.info('Loading configuration from $configPath');
|
||||
|
||||
final config = AppConfig.fromFile(configPath);
|
||||
try {
|
||||
config.validate();
|
||||
logger.info('Configuration loaded successfully');
|
||||
} catch (e) {
|
||||
logger.severe('Configuration validation error: $e');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Initialize database
|
||||
final dbPath = path.join(config.bot.cacheDirectory, 'mumbullet.db');
|
||||
logger.info('Initializing database: $dbPath');
|
||||
final database = DatabaseManager(dbPath);
|
||||
|
||||
// Initialize permission manager
|
||||
final permissionManager = PermissionManager(database, config.bot);
|
||||
|
||||
// Create Mumble connection
|
||||
logger.info('Connecting to Mumble server ${config.mumble.server}:${config.mumble.port}');
|
||||
final mumbleConnection = MumbleConnection(config.mumble);
|
||||
|
||||
// Create message handler
|
||||
final messageHandler = MumbleMessageHandler(mumbleConnection, config.bot);
|
||||
|
||||
// Initialize audio services
|
||||
logger.info('Initializing audio services');
|
||||
final audioConverter = AudioConverter();
|
||||
final youtubeDownloader = YoutubeDownloader(config.bot, database);
|
||||
final audioStreamer = MumbleAudioStreamer(mumbleConnection);
|
||||
|
||||
// Create music queue
|
||||
final musicQueue = MusicQueue(config.bot, audioStreamer, audioConverter);
|
||||
|
||||
// Create command parser with permission callback
|
||||
final commandParser = CommandParser(
|
||||
messageHandler,
|
||||
config.bot,
|
||||
(user) => permissionManager.getPermissionLevel(user),
|
||||
);
|
||||
|
||||
// Create command handler
|
||||
final commandHandler = CommandHandler(
|
||||
commandParser,
|
||||
musicQueue,
|
||||
youtubeDownloader,
|
||||
config.bot,
|
||||
);
|
||||
|
||||
// Set up event listeners
|
||||
mumbleConnection.connectionState.listen((isConnected) {
|
||||
if (isConnected) {
|
||||
logger.info('Connected to Mumble server');
|
||||
} else {
|
||||
logger.info('Disconnected from Mumble server');
|
||||
}
|
||||
});
|
||||
|
||||
mumbleConnection.userJoined.listen((user) {
|
||||
logger.info('User joined: ${user.name}');
|
||||
});
|
||||
|
||||
mumbleConnection.userLeft.listen((user) {
|
||||
logger.info('User left: ${user.name}');
|
||||
});
|
||||
|
||||
// Listen to music queue events
|
||||
musicQueue.events.listen((event) {
|
||||
final eventType = event['event'] as String;
|
||||
final data = event['data'] as Map<String, dynamic>;
|
||||
|
||||
logger.info('Music queue event: $eventType');
|
||||
|
||||
// Log important events
|
||||
switch (eventType) {
|
||||
case 'songStarted':
|
||||
final song = data['song'] as Song;
|
||||
logger.info('Now playing: ${song.title}');
|
||||
break;
|
||||
case 'songFinished':
|
||||
final song = data['song'] as Song;
|
||||
logger.info('Finished playing: ${song.title}');
|
||||
break;
|
||||
case 'queueEmpty':
|
||||
logger.info('Music queue is now empty');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// Connect to Mumble server
|
||||
try {
|
||||
await mumbleConnection.connect();
|
||||
|
||||
// Send a welcome message to the channel
|
||||
if (mumbleConnection.isConnected) {
|
||||
await mumbleConnection.sendChannelMessage('MumBullet Music Bot is online! Type ${config.bot.commandPrefix}help for a list of commands.');
|
||||
logger.info('Sent welcome message to channel');
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warning('Failed to connect to Mumble server: $e');
|
||||
logger.info('The bot will automatically attempt to reconnect...');
|
||||
}
|
||||
|
||||
logger.info('MumBullet is now running with the following features:');
|
||||
logger.info('- Mumble server connection');
|
||||
logger.info('- Command processing with permissions');
|
||||
logger.info('- YouTube audio downloading and streaming');
|
||||
logger.info('- Queue management');
|
||||
logger.info('- Admin dashboard');
|
||||
|
||||
logger.info('Press Ctrl+C to exit');
|
||||
|
||||
// Wait for shutdown
|
||||
final completer = Completer<void>();
|
||||
|
||||
// Set up signal handlers
|
||||
ProcessSignal.sigint.watch().listen((_) async {
|
||||
logger.info('Shutting down Mumble Music Bot');
|
||||
|
||||
// Stop music playback
|
||||
try {
|
||||
await audioStreamer.stopStreaming();
|
||||
musicQueue.dispose();
|
||||
} catch (e) {
|
||||
logger.warning('Error stopping audio services: $e');
|
||||
}
|
||||
|
||||
// Disconnect from Mumble server
|
||||
if (mumbleConnection.isConnected) {
|
||||
try {
|
||||
await mumbleConnection.sendChannelMessage('MumBullet Music Bot is shutting down...');
|
||||
await mumbleConnection.disconnect();
|
||||
} catch (e) {
|
||||
logger.warning('Error during shutdown: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Dispose resources
|
||||
mumbleConnection.dispose();
|
||||
messageHandler.dispose();
|
||||
database.close();
|
||||
|
||||
completer.complete();
|
||||
});
|
||||
|
||||
ProcessSignal.sigterm.watch().listen((_) async {
|
||||
logger.info('Shutting down Mumble Music Bot');
|
||||
|
||||
// Stop music playback
|
||||
try {
|
||||
await audioStreamer.stopStreaming();
|
||||
musicQueue.dispose();
|
||||
} catch (e) {
|
||||
logger.warning('Error stopping audio services: $e');
|
||||
}
|
||||
|
||||
// Disconnect from Mumble server
|
||||
if (mumbleConnection.isConnected) {
|
||||
try {
|
||||
await mumbleConnection.sendChannelMessage('MumBullet Music Bot is shutting down...');
|
||||
await mumbleConnection.disconnect();
|
||||
} catch (e) {
|
||||
logger.warning('Error during shutdown: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Dispose resources
|
||||
mumbleConnection.dispose();
|
||||
messageHandler.dispose();
|
||||
database.close();
|
||||
|
||||
completer.complete();
|
||||
});
|
||||
|
||||
await completer.future;
|
||||
|
||||
// Close logger
|
||||
logManager.close();
|
||||
exit(0);
|
||||
|
||||
} catch (e, stackTrace) {
|
||||
print('Error: $e');
|
||||
print('Stack trace: $stackTrace');
|
||||
print('');
|
||||
print('Usage:');
|
||||
print(parser.usage);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Level _parseLogLevel(String level) {
|
||||
switch (level.toLowerCase()) {
|
||||
case 'debug':
|
||||
return Level.FINE;
|
||||
case 'info':
|
||||
return Level.INFO;
|
||||
case 'warning':
|
||||
return Level.WARNING;
|
||||
case 'error':
|
||||
return Level.SEVERE;
|
||||
default:
|
||||
return Level.INFO;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user