Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tidy up repositories - this will be the main one from now on. #3

Merged
merged 24 commits into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bcf5735
Merge pull request #1 from AMacro/updated-server-browser
morm075 Jun 16, 2024
81aa6ba
Minor adjustments and commenting
morm075 Jun 18, 2024
6e721e5
added button icons
AMacro Jun 20, 2024
c66ee37
minor correction
morm075 Jun 22, 2024
d236a90
PHP and Rust servers implemented
AMacro Jun 22, 2024
0e373f4
Merge branch 'updated-server-browser' of https://github.com/morm075/d…
AMacro Jun 22, 2024
c190545
another correction
morm075 Jun 22, 2024
4b2c6bb
Fixed SSL compilation issues
AMacro Jun 23, 2024
76f5aee
Merge branch 'updated-server-browser' of https://github.com/morm075/d…
morm075 Jun 23, 2024
492938e
Update Read Me.md
AMacro Jun 23, 2024
94f344f
Improved servers and server browser code
AMacro Jun 27, 2024
8329b63
Updates to locale.csv
morm075 Jun 30, 2024
a7ae049
Server browser and lobby server working
AMacro Jun 30, 2024
499dacf
Merge branch 'updated-server-browser' of https://github.com/morm075/d…
AMacro Jun 30, 2024
0fa44a6
Minor UI fixes and version update
AMacro Jun 30, 2024
e5051da
Updated default server to https
AMacro Jul 1, 2024
eb3b948
Refactored server browser for consistency
AMacro Jul 1, 2024
6e8df46
Added auto refresh
AMacro Jul 6, 2024
a99179a
Server details displayed in pane
AMacro Jul 6, 2024
86f8245
Updated translations for server browser details pane
AMacro Jul 6, 2024
30c5988
Fixed translation issue
AMacro Jul 6, 2024
252745d
Updated default server browser text.
AMacro Jul 6, 2024
9925783
General tidy up and QoL for server browser
AMacro Jul 13, 2024
00359ad
Bug fixes for lobby server redirects
AMacro Jul 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,5 @@ MultiplayerAssets/ProjectSettings/*
!MultiplayerAssets/ProjectSettings/ProjectVersion.txt
# Packages
!MultiplayerAssets/Packages
/Lobby Servers/Rust Server/target
*.pem
11 changes: 11 additions & 0 deletions Lobby Servers/PHP Server/.htaccess
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Enable the RewriteEngine
RewriteEngine On

# Uncomment below to force HTTPS
# RewriteCond %{HTTPS} off
# RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# Redirect all non-existing paths to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
10 changes: 10 additions & 0 deletions Lobby Servers/PHP Server/DatabaseInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

interface DatabaseInterface {
public function addGameServer($data);
public function updateGameServer($data);
public function removeGameServer($data);
public function listGameServers();
}

?>
100 changes: 100 additions & 0 deletions Lobby Servers/PHP Server/FlatfileDatabase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php
include 'DatabaseInterface.php';

class FlatfileDatabase implements DatabaseInterface {
private $filePath;

public function __construct($dbConfig) {
$this->filePath = $dbConfig['flatfile_path'];
}

private function readData() {
if (!file_exists($this->filePath)) {
return [];
}
return json_decode(file_get_contents($this->filePath), true) ?? [];
}

private function writeData($data) {
file_put_contents($this->filePath, json_encode($data, JSON_PRETTY_PRINT));
}

public function addGameServer($data) {
$data['last_update'] = time(); // Set current time as last_update

$servers = $this->readData();
$servers[] = $data;
$this->writeData($servers);

return json_encode([
"game_server_id" => $data['game_server_id'],
"private_key" => $data['private_key']
]);
}

public function updateGameServer($data) {
$servers = $this->readData();
$updated = false;

foreach ($servers as &$server) {
if ($server['game_server_id'] === $data['game_server_id']) {
$server['current_players'] = $data['current_players'];
$server['time_passed'] = $data['time_passed'];
$server['last_update'] = time(); // Update with current time
$updated = true;
break;
}
}

if ($updated) {
$this->writeData($servers);
return json_encode(["message" => "Server updated"]);
} else {
return json_encode(["error" => "Failed to update server"]);
}
}

public function removeGameServer($data) {
$servers = $this->readData();
$servers = array_filter($servers, function($server) use ($data) {
return $server['game_server_id'] !== $data['game_server_id'];
});
$this->writeData(array_values($servers));
return json_encode(["message" => "Server removed"]);
}

public function listGameServers() {
$servers = $this->readData();
$current_time = time();
$active_servers = [];
$changed = false;

foreach ($servers as $key => $server) {
if ($current_time - $server['last_update'] <= TIMEOUT) {
$active_servers[] = $server;
} else {
$changed = true; // Indicates there's a change if any server is removed
}
}

if ($changed) {
$this->writeData($active_servers); // Write back only if there are changes
}

return json_encode($active_servers);
}



public function getGameServer($game_server_id) {
$servers = $this->readData();
foreach ($servers as $server) {
if ($server['game_server_id'] === $game_server_id) {
return json_encode($server);
}
}
return json_encode(null);
}
}

?>
78 changes: 78 additions & 0 deletions Lobby Servers/PHP Server/MySQLDatabase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
include 'DatabaseInterface.php';

class MySQLDatabase implements DatabaseInterface {
private $pdo;

public function __construct($dbConfig) {
$this->pdo = new PDO("mysql:host={$dbConfig['host']};dbname={$dbConfig['dbname']}", $dbConfig['username'], $dbConfig['password']);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}

public function addGameServer($data) {
$stmt = $this->pdo->prepare("INSERT INTO game_servers (game_server_id, private_key, ip, port, server_name, password_protected, game_mode, difficulty, time_passed, current_players, max_players, required_mods, game_version, multiplayer_version, server_info, last_update)
VALUES (:game_server_id, :private_key, :ip, :port, :server_name, :password_protected, :game_mode, :difficulty, :time_passed, :current_players, :max_players, :required_mods, :game_version, :multiplayer_version, :server_info, :last_update)");
$stmt->execute([
':game_server_id' => $data['game_server_id'],
':private_key' => $data['private_key'],
':ip' => $data['ip'],
':port' => $data['port'],
':server_name' => $data['server_name'],
':password_protected' => $data['password_protected'],
':game_mode' => $data['game_mode'],
':difficulty' => $data['difficulty'],
':time_passed' => $data['time_passed'],
':current_players' => $data['current_players'],
':max_players' => $data['max_players'],
':required_mods' => $data['required_mods'],
':game_version' => $data['game_version'],
':multiplayer_version' => $data['multiplayer_version'],
':server_info' => $data['server_info'],
':last_update' => time() //use current time
]);
return json_encode([
"game_server_id" => $data['game_server_id'],
"private_key" => $data['private_key']
]);
}

public function updateGameServer($data) {
$stmt = $this->pdo->prepare("UPDATE game_servers
SET current_players = :current_players, time_passed = :time_passed, last_update = :last_update
WHERE game_server_id = :game_server_id");
$stmt->execute([
':current_players' => $data['current_players'],
':time_passed' => $data['time_passed'],
':last_update' => time(), // Update with current time
':game_server_id' => $data['game_server_id']
]);

return $stmt->rowCount() > 0 ? json_encode(["message" => "Server updated"]) : json_encode(["error" => "Failed to update server"]);
}

public function removeGameServer($data) {
$stmt = $this->pdo->prepare("DELETE FROM game_servers WHERE game_server_id = :game_server_id");
$stmt->execute([':game_server_id' => $data['game_server_id']]);
return $stmt->rowCount() > 0 ? json_encode(["message" => "Server removed"]) : json_encode(["error" => "Failed to remove server"]);
}

public function listGameServers() {
// Remove servers that exceed TIMEOUT directly in the SQL query
$stmt = $this->pdo->prepare("DELETE FROM game_servers WHERE last_update < :timeout");
$stmt->execute([':timeout' => time() - TIMEOUT]);

// Fetch remaining servers
$stmt = $this->pdo->query("SELECT * FROM game_servers");
$servers = $stmt->fetchAll(PDO::FETCH_ASSOC);

return json_encode($servers);
}

public function getGameServer($game_server_id) {
$stmt = $this->pdo->prepare("SELECT * FROM game_servers WHERE game_server_id = :game_server_id");
$stmt->execute([':game_server_id' => $game_server_id]);
return json_encode($stmt->fetch(PDO::FETCH_ASSOC));
}
}

?>
149 changes: 149 additions & 0 deletions Lobby Servers/PHP Server/Read Me.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Lobby Server - PHP

This is a PHP implementation of the Derail Valley Lobby Server REST API service. It is designed to run on any standard web hosting and does not rely on long-running/persistent behaviour.
HTTPS support depends on the configuration of the hosting environment.

As this implementation is not persistent in memory, a database is used to store server information. Two options are available for the database engine - a JSON based flatfile or a MySQL database.

## Installing

The following instructions assume you will be using an Apache web server and may need to be modified for other configurations.

1. Copy the following files to your public html folder (consult your web server/web host's documentation)
```
index.php
DatabaseInterface.php
FlatfileDatabase.php
MySQLDatabase.php
.htaccess
```
2. Copy `config.php` to a secure location outside of your public html directory
3. Edit `index.php` and update the path to the config file on line 2:
```php
<?php
include '/path/to/config.php';
...
```

### Setup the database

Choose between a MySQL database and a flatfile database.

#### MySQL

1. Edit `config.php` and set the `type` parameter to `mysql`
2. Update the `host`, `dbname`, `username` and `password` parameters for your MySQL server
3. Copy the `install.php` file to a location you can execute it
4. Edit `install.php` and update the path to the config file on line 2:
```php
<?php
include '/path/to/config.php';
...
```
5. Run `install.php`
6. If `install.php` is in a publically visible location, remove it


#### Flatfile
1. In a secure location (outside of your public html directory), create a directory to store the database
2. Edit `config.php` and set the `type` parameter to `flatfile`
3. Update `flatfile_path` to the directory created in step 1


## Configuration Parameters
The server can be configured using the `config.php` file.

Below are the available parameters along with their defaults:
- `TIMEOUT` (u64): The time-out period in seconds for server removal.
-- Default: `120`
-- `dbConfig`.`type` (string): Type of database for persisting data.
-- Options: `mysql`, `flatfile`
-- Default: `mysql`
- `dbConfig`.`host` (string): hostname of MySQLServer.
-- Required when: `dbConfig`.`type` is `mysql`
-- Default: `localhost`
- `dbConfig`.`dbname` (string): Database name.
- Required when: `dbConfig`.`type` is `mysql`
-- Default: N/A
- `dbConfig`.`username` (string): Username for connecting to the MySQLServer.
-- Required when: `dbConfig`.`type` is `mysql`
-- Default: N/A
- `dbConfig`.`password` (string): Password for connecting to the MySQLServer.
-- Required when: `dbConfig`.`type` is `mysql`
-- Default: N/A
- `dbConfig`.`flatfile_path` (string): Path to secure directory.
-- Required when: `dbConfig`.`type` is `flatfile`
-- Default: N/A

Example `config.php` using MySQL:
```php
<?php

// Timeout value (in seconds)
define('TIMEOUT', 120);

// Database configuration
$dbConfig = [
'type' => 'mysql',
'host' => 'localhost',
'dbname' => 'dv_lobby',
'username' => 'dv_lobby_server',
'password' => 'n16O5+LMpeqI`{E',
'flatfile_path' => '' // Path to store the flatfile database
];
?>
```

Example `config.php` using Flatfile:
```php
<?php

// Timeout value (in seconds)
define('TIMEOUT', 120);

// Database configuration
$dbConfig = [
'type' => 'flatfile',
'host' => '',
'dbname' => '',
'username' => '',
'password' => '',
'flatfile_path' => '/dv_lobby/flatfile.db' // Path to store the flatfile database
];
?>
```

## Security Considerations
This is a non-comprehensive overview of security considerations. You should always use up-to-date best practices and seek professional advice where required.

### Environment variables
Consider using environment variables to store sensitive database credentials (e.g. `dbConfig`.`host`, `dbConfig`.`dbname`, `dbConfig`.`username`, `dbConfig`.`password`) instead of hardcoding them in config.php.
Your `config.php` can be updated to reference the environment variables.

Example:
```php
$dbConfig = [
'type' => 'mysql',
'host' => getenv('DB_HOST'),
'dbname' => getenv('DB_NAME'),
'username' => getenv('DB_USER'),
'password' => getenv('DB_PASSWORD'),
'flatfile_path' => '/path/to/flatfile.db'
];
```


### File Permissions
Ensure that `config.php` and any other sensitive files outside the web root are only readable by the web server user (chmod 600).
For directories containing flatfile databases, restrict permissions (chmod 700 or 750) to prevent unauthorised access.

### HTTPS (SSL)
Configure your server to use https. Many web hosts provide free SSL certificates via Let's Encrypt.
Consider forcing https via server config/`.httaccess`.

Example:
```apacheconf
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
```
16 changes: 16 additions & 0 deletions Lobby Servers/PHP Server/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

// Timeout value (in seconds)
define('TIMEOUT', 120);

// Database configuration
$dbConfig = [
'type' => 'mysql', // Change to 'flatfile' to use flatfile database
'host' => 'localhost',
'dbname' => 'your_database',
'username' => 'your_username',
'password' => 'your_password',
'flatfile_path' => '/path/to/flatfile.db' // Path to store the flatfile database
];

?>
Loading