Skip to content

Commit

Permalink
Add support for 5 new games 馃幃
Browse files Browse the repository at this point in the history
  • Loading branch information
MrMicky-FR committed Aug 31, 2020
1 parent 3ae5cf9 commit 650f861
Show file tree
Hide file tree
Showing 39 changed files with 1,105 additions and 215 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ APP_DEBUG=false
APP_URL=http://localhost
APP_TIMEZONE=UTC
APP_LOCALE=en
AZURIOM_GAME=

LOG_CHANNEL=stack

Expand Down Expand Up @@ -34,6 +35,8 @@ MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=noreply@azuriom.net
MAIL_FROM_NAME=Azuriom

STEAM_KEY=

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
Expand Down
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ language: php
dist: trusty

php:
- '7.2'
- '7.3'
# - '7.4'
- '7.4'

services:
- mysql
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@

![Screenshot](https://azuriom.com/assets/img/home.png)

## Supported Games

Currently, Azuriom supports the following games:
* [Minecraft](https://www.minecraft.net/)
* [Garry's Mod](https://store.steampowered.com/app/4000/Garrys_Mod/)
* [ARK: Survival Evolved](https://store.steampowered.com/app/346110/ARK_Survival_Evolved/)
* [Rust](https://store.steampowered.com/agecheck/app/252490/)
* [Counter-Strike: Global Offensive](https://store.steampowered.com/app/730/CounterStrike_Global_Offensive/)
* [Team Fortress 2](https://store.steampowered.com/app/440/Team_Fortress_2/)

## Documentation

Azuriom's documentation is available [here](https://azuriom.com/docs).
Expand Down
36 changes: 36 additions & 0 deletions app/Games/FallbackGame.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Azuriom\Games;

use Azuriom\Models\User;

/**
* Fallback auth implementation unrelated to a game.
*/
class FallbackGame extends Game
{
public function name()
{
return 'None';
}

public function getAvatarUrl(User $user, int $size = 64)
{
return 'https://www.gravatar.com/avatar/'.md5($user->email).'?d=mp&s='.$size;
}

public function getUserUniqueId(string $name)
{
return null;
}

public function getUserName(User $user)
{
return $user->name;
}

public function getSupportedServers()
{
return [];
}
}
34 changes: 34 additions & 0 deletions app/Games/FallbackServerBridge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Azuriom\Games;

use Azuriom\Models\User;

class FallbackServerBridge extends ServerBridge
{
public function getServerData()
{
return null;
}

public function verifyLink()
{
return false;
}

public function sendCommands(array $commands, User $user = null, bool $needConnected = false)
{
foreach ($commands as $command) {
$this->server->commands()->create([
'command' => $command,
'user_id' => $user->name ?? null,
'need_online' => $needConnected,
]);
}
}

public function canExecuteCommand()
{
return false;
}
}
49 changes: 44 additions & 5 deletions app/Games/Game.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

use Azuriom\Models\User;

interface Game
abstract class Game
{
/**
* Get the name of this game.
*
* @return string
*/
public function name();
abstract public function name();

/**
* Get the avatar URL of the user.
Expand All @@ -21,20 +21,59 @@ public function name();
*
* @deprecated Will be removed in 1.0, use User::getAvatar()
*/
public function getAvatarUrl(User $user, int $size = 64);
abstract public function getAvatarUrl(User $user, int $size = 64);

/**
* Get the game id of the user.
*
* @param string $name
*/
public function getUserUniqueId(string $name);
abstract public function getUserUniqueId(string $name);

/**
* Get the game user name.
*
* @param \Azuriom\Models\User $user
* @return mixed
*/
public function getUserName(User $user);
abstract public function getUserName(User $user);

/**
* Get
*
* @param string $key
* @param array $placeholders
* @return string
*/
public function trans(string $key, array $placeholders = [])
{
return $key;
}

/**
* Return if the user must login with a third party provider.
*
* @return bool
*/
public function loginWithOAuth()
{
return $this->getSocialiteDriverName() !== null;
}

/**
* Get the socialite driver name, if loginWithSocialite return true.
*
* @return string|null
*/
public function getSocialiteDriverName()
{
return null;
}

/**
* Get the supported server bridge types.
*
* @return \Azuriom\Games\ServerBridge[]
*/
abstract public function getSupportedServers();
}
21 changes: 20 additions & 1 deletion app/Games/Minecraft/AbstractMinecraftGame.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,29 @@

namespace Azuriom\Games\Minecraft;

class AbstractMinecraftGame
use Azuriom\Games\Game;
use Azuriom\Games\Minecraft\Servers\AzLink;
use Azuriom\Games\Minecraft\Servers\Ping;
use Azuriom\Games\Minecraft\Servers\Rcon;

abstract class AbstractMinecraftGame extends Game
{
public function name()
{
return 'Minecraft';
}

public function getSupportedServers()
{
return [
'mc-ping' => Ping::class,
'mc-rcon' => Rcon::class,
'mc-azlink' => AzLink::class,
];
}

public function trans(string $key, array $placeholders = [])
{
return trans('game.minecraft.'.$key, $placeholders);
}
}
12 changes: 11 additions & 1 deletion app/Games/Minecraft/Servers/Rcon.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function sendCommands(array $commands, User $user = null, bool $needConne
$rcon = $this->connectRcon();

foreach ($commands as $command) {
$rcon->sendCommand(str_replace('{player}', $user->name ?? '?', $command));
$rcon->sendCommand($this->replacePlaceholders($command, $user));
}
}

Expand All @@ -45,4 +45,14 @@ protected function connectRcon()

return $rcon;
}

public function replacePlaceholders(string $command, User $user = null)
{
if ($user === null) {
return parent::replacePlaceholders($command, $user);
}

return parent::replacePlaceholders($command, $user)
->replace('{uuid}', $user->game_id);
}
}
12 changes: 12 additions & 0 deletions app/Games/ServerBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Azuriom\Models\Server;
use Azuriom\Models\User;
use Illuminate\Support\Str;

abstract class ServerBridge
{
Expand Down Expand Up @@ -74,4 +75,15 @@ public function getDefaultPort()
{
return 0;
}

public function replacePlaceholders(string $command, User $user = null)
{
if ($user === null) {
return Str::of($command);
}

return Str::of($command)
->replace('{player}', $user->name)
->replace('{name}', $user->name);
}
}
23 changes: 23 additions & 0 deletions app/Games/Steam/RustGame.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Azuriom\Games\Steam;

use Azuriom\Games\Steam\Servers\Query;
use Azuriom\Games\Steam\Servers\RustRcon;

class RustGame extends SteamGame
{
public function __construct()
{
parent::__construct('Rust');
}

public function getSupportedServers()
{
return [
'source-query' => Query::class,
// Rust use a WebSocket based Rcon
'rust-rcon' => RustRcon::class,
];
}
}
63 changes: 63 additions & 0 deletions app/Games/Steam/Servers/Protocol/RustRcon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Azuriom\Games\Steam\Servers\Protocol;

use WebSocket\Client;

/**
* A Rust RCON client implementation in PHP.
*
* Based on https://github.com/Facepunch/webrcon
*/
class RustRcon
{
/**
* The websocket client.
*
* @var \WebSocket\Client
*/
private $client;

/**
* Create a new Rcon instance.
*
* @param string $host
* @param int $port
* @param string $password
*/
public function __construct(string $host, int $port, string $password)
{
$this->client = new Client("ws://{$host}:{$port}/{$password}");
}

/**
* Send a command to the connected server.
*
* @param string $command
* @return array
*
* @throws \WebSocket\BadOpcodeException
*/
public function sendCommand(string $command)
{
$data = [
'Identifier' => -1,
'Message' => $command,
'name' => 'AzuriomRcon',
];

$this->client->send(json_encode($data));

return json_decode($this->client->receive(), true);
}

/**
* Disconnect from the server.
*
* @return void
*/
public function disconnect()
{
$this->client->close();
}
}
12 changes: 12 additions & 0 deletions app/Games/Steam/Servers/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Azuriom\Games\Steam\Servers;

use Azuriom\Games\ServerBridge;
use Azuriom\Games\Steam\SteamID;
use Azuriom\Models\User;
use Exception;
use RuntimeException;
Expand Down Expand Up @@ -72,4 +73,15 @@ protected function connect(bool $rcon = false)

return $query;
}

public function replacePlaceholders(string $command, User $user = null)
{
if ($user === null) {
return parent::replacePlaceholders($command, $user);
}

return parent::replacePlaceholders($command, $user)
->replace('{steam_id}', $user->game_id)
->replace('{steam_id_32}', SteamID::convertTo32($user->game_id));
}
}
2 changes: 1 addition & 1 deletion app/Games/Steam/Servers/Rcon.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function sendCommands(array $commands, User $user = null, bool $needConne
$query = $this->connect(true);

foreach ($commands as $command) {
$query->Rcon(str_replace('{player}', $user->name ?? '?', $command));
$query->Rcon($this->replacePlaceholders($command, $user));
}
}

Expand Down

0 comments on commit 650f861

Please sign in to comment.