You've already forked Atomcms-edit
290 lines
6.9 KiB
PHP
Executable File
290 lines
6.9 KiB
PHP
Executable File
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Enums\CurrencyTypes;
|
|
use App\Exceptions\RconConnectionException;
|
|
use Illuminate\Support\Facades\Log;
|
|
use JsonException;
|
|
use Socket;
|
|
|
|
class RconService
|
|
{
|
|
private ?Socket $socket = null;
|
|
|
|
public bool $isConnected = false;
|
|
|
|
/**
|
|
* @var array<string, mixed>
|
|
*/
|
|
private array $config = [];
|
|
|
|
public function __construct()
|
|
{
|
|
$this->config = [
|
|
'ip' => setting('rcon_ip'),
|
|
'port' => (int) setting('rcon_port'),
|
|
];
|
|
}
|
|
|
|
public function connect(): bool
|
|
{
|
|
if ($this->isConnected) {
|
|
return true;
|
|
}
|
|
|
|
$this->socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
|
|
|
if ($this->socket === false) {
|
|
$error = socket_strerror(socket_last_error());
|
|
Log::error("RCON initialization failed: {$error}");
|
|
$this->closeConnection();
|
|
|
|
return false;
|
|
}
|
|
|
|
if (! @socket_connect($this->socket, $this->config['ip'], $this->config['port'])) {
|
|
$error = socket_strerror(socket_last_error());
|
|
Log::error("RCON connection failed: {$error}");
|
|
$this->closeConnection();
|
|
|
|
return false;
|
|
}
|
|
|
|
$this->isConnected = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
private function initialize(): void
|
|
{
|
|
$this->connect();
|
|
}
|
|
|
|
private function closeConnection(): void
|
|
{
|
|
if ($this->socket instanceof Socket) {
|
|
socket_close($this->socket);
|
|
}
|
|
|
|
$this->socket = null;
|
|
$this->isConnected = false;
|
|
}
|
|
|
|
public function isConnected(): bool
|
|
{
|
|
if (! $this->isConnected) {
|
|
$this->connect();
|
|
}
|
|
|
|
return $this->isConnected;
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function sendCommand(string $command, ?array $data = null): bool
|
|
{
|
|
if (! $this->isConnected) {
|
|
Log::error('RCON command failed: Not connected');
|
|
$this->closeConnection();
|
|
|
|
return false;
|
|
}
|
|
|
|
$payload = json_encode(['key' => $command, 'data' => $data], JSON_THROW_ON_ERROR);
|
|
|
|
if (! @socket_write($this->socket, $payload, strlen($payload))) {
|
|
$error = socket_strerror(socket_last_error($this->socket));
|
|
Log::error("RCON command ({$command}) failed: {$error}");
|
|
$this->closeConnection();
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException|JsonException
|
|
*/
|
|
public function sendGift(object $user, int $itemId, string $message = 'Here is a gift.'): void
|
|
{
|
|
$this->sendCommand('sendgift', [
|
|
'user_id' => $user->id,
|
|
'itemid' => $itemId,
|
|
'message' => $message,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException|JsonException
|
|
*/
|
|
public function giveCredits(object $user, int $credits): void
|
|
{
|
|
$this->sendCommand('givecredits', [
|
|
'user_id' => $user->id,
|
|
'credits' => $credits,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException|JsonException
|
|
*/
|
|
public function giveBadge(object $user, string $badge): void
|
|
{
|
|
$this->sendCommand('givebadge', [
|
|
'user_id' => $user->id,
|
|
'badge' => $badge,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException|JsonException
|
|
*/
|
|
public function setMotto(object $user, string $motto): void
|
|
{
|
|
$this->sendCommand('setmotto', [
|
|
'user_id' => $user->id,
|
|
'motto' => $motto,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException|JsonException
|
|
*/
|
|
public function updateWordFilter(): void
|
|
{
|
|
$this->sendCommand('updatewordfilter');
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException|JsonException
|
|
*/
|
|
public function disconnectUser(object $user): void
|
|
{
|
|
$this->sendCommand('disconnect', [
|
|
'user_id' => $user->id,
|
|
'username' => $user->username,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException|JsonException
|
|
*/
|
|
public function givePoints(object $user, CurrencyTypes $type, int $amount): void
|
|
{
|
|
$this->sendCommand('givepoints', [
|
|
'user_id' => $user->id,
|
|
'points' => $amount,
|
|
'type' => $type,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function giveGotw(object $user, int $amount): void
|
|
{
|
|
$this->givePoints($user, CurrencyTypes::Points, $amount);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function giveDiamonds(object $user, int $amount): void
|
|
{
|
|
$this->givePoints($user, CurrencyTypes::Diamonds, $amount);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function giveDuckets(object $user, int $amount): void
|
|
{
|
|
$this->givePoints($user, CurrencyTypes::Duckets, $amount);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function setRank(object $user, int $rank): void
|
|
{
|
|
$this->sendCommand('setrank', [
|
|
'user_id' => $user->id,
|
|
'rank' => $rank,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function updateCatalog(): void
|
|
{
|
|
$this->sendCommand('updatecatalog');
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function alertUser(object $user, string $message): void
|
|
{
|
|
$this->sendCommand('alertuser', [
|
|
'user_id' => $user->id,
|
|
'message' => $message,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function forwardUser(object $user, int $roomId): void
|
|
{
|
|
$this->sendCommand('forwarduser', [
|
|
'user_id' => $user->id,
|
|
'room_id' => $roomId,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function updateConfig(object $user, string $command): void
|
|
{
|
|
$this->sendCommand('executecommand', [
|
|
'user_id' => $user->id,
|
|
'command' => $command,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Send an RCON command safely from dashboard with error handling
|
|
*
|
|
* @param array<string, mixed> $params The parameters for the command
|
|
*
|
|
* @throws RconConnectionException
|
|
* @throws JsonException
|
|
*/
|
|
public function sendSafelyFromDashboard(string $command, array $params, string $errorMessage): void
|
|
{
|
|
if (! $this->isConnected()) {
|
|
Log::error($errorMessage . ' - RCON not connected');
|
|
|
|
return;
|
|
}
|
|
|
|
$this->sendCommand($command, $params);
|
|
}
|
|
}
|