* @license MIT * * Register this provider by adding ONE line to app/Providers/AppServiceProvider.php: * $this->app->register(\Pterodactyl\Addons\AdvancedAdmin\AddonServiceProvider::class); * * See patches/PATCHES.md for full patch instructions. */ namespace Pterodactyl\Addons\AdvancedAdmin; use Illuminate\Support\ServiceProvider; use Illuminate\Console\Scheduling\Schedule; use Pterodactyl\Addons\AdvancedAdmin\Jobs\Network\CollectNetworkMetricsJob; use Pterodactyl\Addons\AdvancedAdmin\Jobs\Network\DownsampleNetworkMetricsJob; use Pterodactyl\Addons\AdvancedAdmin\Jobs\Network\PruneNetworkMetricsJob; use Pterodactyl\Addons\AdvancedAdmin\Jobs\Revisions\PruneFileRevisionsJob; use Pterodactyl\Addons\AdvancedAdmin\Jobs\Console\ExpireStalePlayersJob; use Pterodactyl\Addons\AdvancedAdmin\Listeners\Console\ConsoleOutputListener; use Pterodactyl\Addons\AdvancedAdmin\Services\Roles\PermissionResolver; class AddonServiceProvider extends ServiceProvider { /** * Register addon bindings. */ public function register(): void { // Merge addon config (won't overwrite user's published config) $this->mergeConfigFrom( __DIR__ . '/../../config/advanced-admin.php', 'advanced-admin' ); // Bind the PermissionResolver as a singleton for performance $this->app->singleton(PermissionResolver::class); } /** * Bootstrap addon services. */ public function boot(): void { // ── Routes ──────────────────────────────────────────────────────────── $this->loadRoutesFrom(__DIR__ . '/../../routes/addon-client.php'); $this->loadRoutesFrom(__DIR__ . '/../../routes/addon-application.php'); // ── Migrations ──────────────────────────────────────────────────────── $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations/addon'); // ── Scheduled Jobs ──────────────────────────────────────────────────── $this->callAfterResolving(Schedule::class, function (Schedule $schedule) { if (config('advanced-admin.network.enabled')) { $schedule->job(CollectNetworkMetricsJob::class) ->everyTenSeconds() ->withoutOverlapping(5) ->onOneServer(); $schedule->job(DownsampleNetworkMetricsJob::class) ->hourly() ->withoutOverlapping(30) ->onOneServer(); $schedule->job(PruneNetworkMetricsJob::class) ->daily() ->withoutOverlapping(60) ->onOneServer(); } if (config('advanced-admin.revisions.enabled')) { $schedule->job(PruneFileRevisionsJob::class) ->daily() ->withoutOverlapping(60) ->onOneServer(); } if (config('advanced-admin.console.enabled')) { $schedule->job(ExpireStalePlayersJob::class) ->everyFiveMinutes() ->withoutOverlapping(4); } }); // ── Event Listeners ─────────────────────────────────────────────────── // Console output listener (parses join/leave for player cache) // Hooked to Pterodactyl's existing console output events if they exist. // Falls back gracefully if event is not fired by this panel version. if (class_exists(\Pterodactyl\Events\Server\ConsoleDataReceived::class)) { $this->app['events']->listen( \Pterodactyl\Events\Server\ConsoleDataReceived::class, ConsoleOutputListener::class ); } // ── Artisan Commands ────────────────────────────────────────────────── if ($this->app->runningInConsole()) { $this->commands([ Console\Commands\AddonPatchCommand::class, Console\Commands\AddonInstallCommand::class, Console\Commands\AddonUninstallCommand::class, Console\Commands\CollectNetworkCommand::class, ]); } // ── Publishable Assets ──────────────────────────────────────────────── $this->publishes([ __DIR__ . '/../../config/advanced-admin.php' => config_path('advanced-admin.php'), ], 'advanced-admin-config'); $this->publishes([ __DIR__ . '/../../config/addon-commands' => base_path('config/addon-commands'), ], 'advanced-admin-commands'); } }