Сборка REDL: панель на PHP 8, капча-тумблер, закрытые уязвимости, установщики в один клик

- панель работает на PHP 8.4 (оригинал под PHP 7.0): elFinder utf8_encode, apache_get_modules, warnings
- капча выключена и управляется из админки (флаг captcha_enable + блок настроек)
- закрыты две SQL-инъекции без авторизации (createAuthLog: пароль из POST и CF-Connecting-IP)
- убрано хранение паролей в открытом виде в authlog, XSS в поле ref
- установщики install-panel.sh и install-node.sh (оригинальный затирал sources.list репозиториями Debian 9)
- современный Dockerfile (оригинальный на debian:stretch больше не собирается)
- планировщик и автозапуск работают без systemd
- брендинг REDL.IO, год 2026, ссылки на redl.io
- документация на русском: ИЗМЕНЕНИЯ, БЕЗОПАСНОСТЬ, ИНСТРУКЦИЯ
This commit is contained in:
2026-07-30 02:00:01 +00:00
commit 6ee2744e3a
492 changed files with 354172 additions and 0 deletions
+406
View File
@@ -0,0 +1,406 @@
<?php
/*
Copyright (c) 2020 HOSTINPL (HOSTING-RUS) https://vk.com/hosting_rus
Developed by Samir Shelenko and Alexander Zemlyanoy (https://vk.com/id00v / https://vk.com/mrsasha082)
*/
class SampRconAPI {
private $sock = null;
private $server = null;
private $port = null;
private $password = null;
/**
* Creates a new SampRcon object.
* @param $server hostname of the server
* @param $port port of the server
* @param $password rcon password for the server
*/
public function __construct($server, $port, $password) {
$this->server = $server;
$this->port = $port;
$this->password = $password;
}
/**
* Returns an array of rcon commands.
* @return Array
* (
* Array[0] => "echo"
* ...
* )
* ...
* @see getServerVariables()
*/
public function getCommandList() {
$commands = $this->rconSend('cmdlist');
foreach($commands as &$command) {
$command = trim($command);
}
return $commands;
}
/**
* Returns an array of server variables.
* @return Array[]
* (
* ['variableName'] = variableValue
* ...
* )
* @see getCommandList
*/
public function getServerVariables() {
$aVariables = $this->rconSend('varlist');
unset($aVariables[0]);
$aReturn = array();
foreach($aVariables as $sString) {
preg_match('/(.*)=[\s]+(.*)/', $sString, $aMatches);
if($aMatches[2][0] == '"') {
preg_match('/\"(.*)\"[\s]+\(/', $aMatches[2], $aTemp);
$aReturn[trim($aMatches[1])] = $aTemp[1];
} else {
preg_match('/(.*?)\s+\(/', $aMatches[2], $aTemp);
$aReturn[trim($aMatches[1])] = $aTemp[1];
}
}
return $aReturn;
}
/**
* Sets the server's current weather, if no weather ID is given 1 is used.
* @param $weatherID weather ID
*/
public function setWeather($weatherID=1) {
$this->rconSend("weather ".$weatherID, false);
}
/**
* Sets the server's current gravity, of mp gravity is given 0.008 is used.
* @param $gravity gravity double / float
*/
public function setGravity($gravity=0.008) {
$this->rconSend("gravity ".$gravity, false);
}
/**
* Ban a player from the server.
* @param $playerID player's ID
* @return Output from ban
*/
public function ban($playerID) {
return $this->rconSend("ban ".$playerID);
}
/**
* Kick a player from the server.
* @param $playerID player's ID
* @return Output from kick
*/
public function kick($playerID) {
return $this->rconSend("kick ".$playerID);
}
/**
* Ban an IP address from the server.
* @param $address IP address
* @return Output from ban
*/
public function banAddress($address) {
return $this->rconSend("banip ".$address);
}
/**
* Unban an IP address from the server.
* @param $address IP address
* @return Output from unban
*/
public function unbanAddress($address) {
return $this->rconSend("unbanip ".$address);
}
/**
* Reload the server's log file.
*/
public function reloadLog() {
return $this->rconSend("reloadlog");
}
/**
* Reload the server's bans file.
*/
public function reloadBans() {
return $this->rconSend("reloadbans");
}
/**
* Send an admin message to players on the server.
* @param $message message to send to players
*/
public function say($message) {
$this->rconSend("say ".$message, false);
}
/**
* Change the server's current gamemode.
* @param $gameMode game mode to change to
*/
public function changeGameMode($gameMode) {
$this->rconSend("changemode ".$gameMode, false);
}
/**
* Set the server's current displayed game mode text.
* @param $gameModeText game mode text to change to
*/
public function setGameModeText($gameModeText) {
$this->rconSend("gamemodetext ".$gameModeText, false);
}
/**
* Run the server's next gamemode (gmx).
*/
public function nextGameMode() {
$this->rconSend("gmx", false);
}
/**
* Run the server's next gamemode (gmx).
*/
public function gmx() {
$this->nextGamemode();
}
/**
* Execute config file.
* @param $config config file to execute
* @return Output from exec
*/
public function execConfig($config) {
return $this->rconSend("exec ".$config);
}
/**
* Load a filterscript.
* @param $fs filterscript to load
* @return Output from filterscript load
*/
public function loadFilterscript($fs) {
return $this->rconSend("loadfs ".$fs);
}
/**
* Unload a filterscript.
* @param $fs filterscript to unload
* @return Output from filterscript unload
*/
public function unloadFilterscript($fs) {
return $this->rconSend("unloadfs ".$fs);
}
/**
* Reload a filterscript.
* @param $fs filterscript to reload
* @return Output from filterscript reload
*/
public function reloadFilterscript($fs) {
return $this->rconSend("reloadfs ".$fs);
}
/**
* Shutdown the server.
*/
public function exitGame() {
$this->rconSend("exit", false);
}
/**
* Sets the server's host name.
* @param $hostName the host name to set the server to
*/
public function setHostName($hostName) {
$this->rconSend("hostname ".$hostName, false);
}
/**
* Sets the server's map name.
* @param $mapName the map name to set the server to
*/
public function setMapname($mapName) {
$this->rconSend("mapname ".$mapName, false);
}
/**
* Sets the server's time.
* Note: This will not change the weather relative to the time.
* @param $time the time to set the server to
*/
public function setTime($time) {
$this->rconSend("worldtime ".$time, false);
}
/**
* Sets the server's web url.
* @param $url the url to set the server to
*/
public function setURL($url) {
$this->rconSend("weburl ".$url, false);
}
/**
* Sets the server's password.
* @param $password the password to set the server to
*/
public function setPassword($password) {
$this->rconSend("password ".$password, false);
}
/**
* Remove the server's password.
*/
public function removePassword() {
$this->rconSend("password 0", false);
}
/**
* Sets the server's rcon password.
* @param $password the password the rcon password should be set to
*/
public function setRconPassword($password) {
$this->rconSend("rcon_password ".$password, false);
}
/**
* Disables remote rcon to the server.
*/
public function disableRcon() {
$this->rconSend("rcon 0", false);
}
/**
* Enables remote queries to the server.
*/
public function enableQuery() {
$this->rconSend("query 1", false);
}
/**
* Disables remote queries to the server.
*/
public function disableQuery() {
$this->rconSend("query 0", false);
}
/**
* Enables the server's announce.
*/
public function enableAnnounce() {
$this->rconSend("announce 1", false);
}
/**
* Disables the server's announce.
*/
public function disableAnnounce() {
$this->rconSend("announce 0", false);
}
/**
* Sets the server's max number of NPCs.
* @param $maxNPCs the maximum numbers of NPCs
*/
public function setMaxNPCs($maxNPCs) {
$this->rconSend("maxnpc ".$maxNPCs, false);
}
/**
* Execute an rcon command.
* @param $command command to execute
* @param $delay delay time, if you don't expect any data back set this to false
* @return Output from command
*/
public function call($command, $delay=1.0) {
return $this->rconSend($command, $delay);
}
private function rconSend($command, $delay=1.0) {
fwrite($this->sock, $this->assemblePacket($command));
if ($delay === false) {
return;
}
$result = array();
$iMicrotime = microtime(true) + $delay;
while (microtime(true) < $iMicrotime) {
$temp = substr(fread($this->sock, 128), 13);
if (strlen($temp)) {
$result[] = $temp;
} else {
break;
}
}
return $result;
}
private function assemblePacket($command) {
$sPacket = "SAMP";
$sPacket .= chr(strtok($this->server, "."));
$sPacket .= chr(strtok("."));
$sPacket .= chr(strtok("."));
$sPacket .= chr(strtok("."));
$sPacket .= chr($this->port & 0xFF);
$sPacket .= chr($this->port >> 8 & 0xFF);
$sPacket .= "x";
$sPacket .= chr(strlen($this->password) & 0xFF);
$sPacket .= chr(strlen($this->password) >> 8 & 0xFF);
$sPacket .= $this->password;
$sPacket .= chr(strlen($command) & 0xFF);
$sPacket .= chr(strlen($command) >> 8 & 0xFF);
$sPacket .= $command;
return $sPacket;
}
/**
* Attempts to connect to the server and returns whether it was successful.
* @return boolean
*/
public function connect() {
$connected = false;
$packet = "SAMP";
$packet .= chr(strtok($this->server, "."));
$packet .= chr(strtok("."));
$packet .= chr(strtok("."));
$packet .= chr(strtok("."));
$packet .= chr($this->port & 0xFF);
$packet .= chr($this->port >> 8 & 0xFF);
$packet .= "p0101";
$this->sock = fsockopen("udp://".$this->server, $this->port, $errorNum, $errorString, 2);
socket_set_timeout($this->sock, 2);
fwrite($this->sock, $packet);
if(fread($this->sock, 10)) {
if(fread($this->sock, 5) == 'p0101') {
$connected = true;
}
}
return $connected;
}
/**
* Closes the connection
*/
public function close() {
@fclose($this->sock);
}
}