diff --git a/app/Models/Server.php b/app/Models/Server.php index 5ad99151a..c173e9afb 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -2,15 +2,20 @@ namespace Pterodactyl\Models; +use Illuminate\Support\Facades\Http; +use Psr\Http\Message\ResponseInterface; use Illuminate\Notifications\Notifiable; +use GuzzleHttp\Exception\GuzzleException; use Illuminate\Database\Query\JoinClause; use Znck\Eloquent\Traits\BelongsToThrough; +use GuzzleHttp\Exception\TransferException; use Illuminate\Database\Eloquent\Relations\HasOne; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphToMany; use Illuminate\Database\Eloquent\Relations\HasManyThrough; use Pterodactyl\Exceptions\Http\Server\ServerStateConflictException; +use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException; /** * \Pterodactyl\Models\Server. @@ -378,4 +383,20 @@ class Server extends Model throw new ServerStateConflictException($this); } } + + /** + * Sends a command or multiple commands to a running server instance. + * + * @throws DaemonConnectionException|GuzzleException + */ + public function send(array|string $command): ResponseInterface + { + try { + return Http::daemon($this->node)->post("/api/servers/{$this->uuid}/commands", [ + 'json' => ['commands' => is_array($command) ? $command : [$command]], + ])->toPsrResponse(); + } catch (TransferException $exception) { + throw new DaemonConnectionException($exception); + } + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index d4ffdadbb..86904c236 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -6,8 +6,10 @@ use View; use Cache; use Pterodactyl\Models; use Illuminate\Support\Str; +use Pterodactyl\Models\Node; use Illuminate\Support\Facades\URL; use Illuminate\Pagination\Paginator; +use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; use Pterodactyl\Extensions\Themes\Theme; @@ -49,6 +51,17 @@ class AppServiceProvider extends ServiceProvider 'task' => Models\Task::class, 'user' => Models\User::class, ]); + + Http::macro( + 'daemon', + fn (Node $node, array $headers = []) => Http::acceptJson()->withHeaders([ + 'Authorization' => 'Bearer ' . $node->getDecryptedKey(), + ] + $headers) + ->withOptions(['verify' => (bool) app()->environment('production')]) + ->timeout(config('pterodactyl.guzzle.timeout')) + ->connectTimeout(config('pterodactyl.guzzle.connect_timeout')) + ->baseUrl($node->getConnectionAddress()) + ); } /**