Merge branch 'main' into develop

This commit is contained in:
slawkens
2025-10-31 06:56:34 +01:00
215 changed files with 5224 additions and 3088 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -26,10 +26,11 @@ use MyAAC\Cache\Cache;
*/
class OTS_DB_MySQL extends OTS_Base_DB
{
private $has_table_cache = array();
private $has_column_cache = array();
private array $has_table_cache = [];
private array $has_column_cache = [];
private array $get_column_info_cache = [];
private $clearCacheAfter = false;
private bool $clearCacheAfter = false;
/**
* Creates database connection.
*
@@ -119,6 +120,11 @@ class OTS_DB_MySQL extends OTS_Base_DB
if($cache->fetch('database_columns', $tmp) && $tmp) {
$this->has_column_cache = unserialize($tmp);
}
$tmp = null;
if($cache->fetch('database_columns_info', $tmp) && $tmp) {
$this->get_column_info_cache = unserialize($tmp);
}
}
}
@@ -155,11 +161,13 @@ class OTS_DB_MySQL extends OTS_Base_DB
if ($this->clearCacheAfter) {
$cache->delete('database_tables');
$cache->delete('database_columns');
$cache->delete('database_columns_info');
$cache->delete('database_checksum');
}
else {
$cache->set('database_tables', serialize($this->has_table_cache), 3600);
$cache->set('database_columns', serialize($this->has_column_cache), 3600);
$cache->set('database_columns_info', serialize($this->get_column_info_cache), 3600);
$cache->set('database_checksum', serialize(sha1($config['database_host'] . '.' . $config['database_name'])), 3600);
}
}
@@ -209,7 +217,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
return $sql;
}
public function hasTable($name) {
public function hasTable($name): bool
{
if(isset($this->has_table_cache[$name])) {
return $this->has_table_cache[$name];
}
@@ -217,12 +226,13 @@ class OTS_DB_MySQL extends OTS_Base_DB
return $this->hasTableInternal($name);
}
private function hasTableInternal($name) {
global $config;
return ($this->has_table_cache[$name] = $this->query('SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = ' . $this->quote($config['database_name']) . ' AND `TABLE_NAME` = ' . $this->quote($name) . ' LIMIT 1;')->rowCount() > 0);
private function hasTableInternal($name): bool
{
return ($this->has_table_cache[$name] = $this->query('SELECT `TABLE_NAME` FROM `information_schema`.`tables` WHERE `TABLE_SCHEMA` = ' . $this->quote(config('database_name')) . ' AND `TABLE_NAME` = ' . $this->quote($name) . ' LIMIT 1;')->rowCount() > 0);
}
public function hasColumn($table, $column) {
public function hasColumn($table, $column): bool
{
if(isset($this->has_column_cache[$table . '.' . $column])) {
return $this->has_column_cache[$table . '.' . $column];
}
@@ -230,8 +240,8 @@ class OTS_DB_MySQL extends OTS_Base_DB
return $this->hasColumnInternal($table, $column);
}
private function hasColumnInternal($table, $column) {
return $this->hasTable($table) && ($this->has_column_cache[$table . '.' . $column] = count($this->query('SHOW COLUMNS FROM `' . $table . "` LIKE '" . $column . "'")->fetchAll()) > 0);
private function hasColumnInternal($table, $column): bool {
return $this->hasTable($table) && ($this->has_column_cache[$table . '.' . $column] = count($this->query('SHOW COLUMNS FROM `' . $table . "` LIKE " . $this->quote($column))->fetchAll()) > 0);
}
public function hasTableAndColumns(string $table, array $columns = []): bool
@@ -247,7 +257,53 @@ class OTS_DB_MySQL extends OTS_Base_DB
return true;
}
public function revalidateCache() {
public function getColumnInfo(string $table, string $column): bool|array
{
if(isset($this->get_column_info_cache[$table . '.' . $column])) {
return $this->get_column_info_cache[$table . '.' . $column];
}
return $this->getColumnInfoInternal($table, $column);
}
private function getColumnInfoInternal(string $table, string $column): bool|array
{
if (!$this->hasTable($table) || !$this->hasColumn($table, $column)) {
return false;
}
$formatResult = function ($result) {
return [
'field' => $result['Field'],
'type' => $result['Type'],
'null' => strtolower($result['Null']),
'default' => $result['Default'],
'extra' => $result['Extra'],
];
};
$query = $this->query('SHOW COLUMNS FROM `' . $table . "` LIKE " . $this->quote($column));
$rowCount = $query->rowCount();
if ($rowCount > 1) {
$tmp = [];
$results = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($results as $result) {
$tmp[] = $formatResult($result);
}
return ($this->get_column_info_cache[$table . '.' . $column] = $tmp);
}
else if ($rowCount == 1) {
$result = $query->fetch(PDO::FETCH_ASSOC);
return ($this->get_column_info_cache[$table . '.' . $column] = $formatResult($result));
}
return [];
}
public function revalidateCache(): void
{
foreach($this->has_table_cache as $key => $value) {
$this->hasTableInternal($key);
}
@@ -262,6 +318,21 @@ class OTS_DB_MySQL extends OTS_Base_DB
$this->hasColumnInternal($explode[0], $explode[1]);
}
}
foreach($this->get_column_info_cache as $key => $value) {
$explode = explode('.', $key);
if(!isset($this->has_table_cache[$explode[0]])) { // first check if table exist
$this->hasTableInternal($explode[0]);
}
if($this->has_table_cache[$explode[0]]) {
$this->hasColumnInternal($explode[0], $explode[1]);
}
if($this->has_table_cache[$explode[0]]) {
$this->getColumnInfoInternal($explode[0], $explode[1]);
}
}
}
public function setClearCacheAfter($clearCache)

View File

@@ -15,11 +15,11 @@
/**
* Wrapper for 'info' respond's DOMDocument.
*
*
* <p>
* Note: as this class extends DOMDocument class and contains exacly respond XML tree you can work on it as on normal DOM tree.
* </p>
*
*
* @package POT
* @version 0.1.0
* @property-read string $tspqVersion Root element version.
@@ -48,252 +48,257 @@ class OTS_InfoRespond extends DOMDocument
{
/**
* Returns version of root element.
*
*
* @return string TSPQ version.
* @throws DOMException On DOM operation error.
*/
public function getTSPQVersion()
{
return $this->documentElement->getAttribute('version');
}
public function getTSPQVersion()
{
return $this->documentElement->getAttribute('version');
}
/**
* Returns server uptime.
*
*
* @return int Uptime.
* @throws DOMException On DOM operation error.
*/
public function getUptime()
{
return (int) $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('uptime');
}
public function getUptime()
{
return (int) $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('uptime');
}
/**
* Returns server IP.
*
*
* @return string IP.
* @throws DOMException On DOM operation error.
*/
public function getIP()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('ip');
}
public function getIP()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('ip');
}
/**
* Returns server name.
*
*
* @return string Name.
* @throws DOMException On DOM operation error.
*/
public function getName()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('servername');
}
public function getName()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('servername');
}
/**
* Returns server port.
*
*
* @return int Port.
* @throws DOMException On DOM operation error.
*/
public function getPort()
{
return (int) $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('port');
}
public function getPort()
{
return (int) $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('port');
}
/**
* Returns server location.
*
*
* @return string Location.
* @throws DOMException On DOM operation error.
*/
public function getLocation()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('location');
}
public function getLocation()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('location');
}
/**
* Returns server website.
*
*
* @return string Website URL.
* @throws DOMException On DOM operation error.
*/
public function getURL()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('url');
}
public function getURL()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('url');
}
/**
* Returns server attribute.
*
*
* I have no idea what the hell is it representing :P.
*
*
* @return string Attribute value.
* @throws DOMException On DOM operation error.
*/
public function getServer()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('server');
}
public function getServer()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('server');
}
/**
* Returns server version.
*
*
* @return string Version.
* @throws DOMException On DOM operation error.
*/
public function getServerVersion()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('version');
}
public function getServerVersion()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('version');
}
/**
* Returns dedicated version of client.
*
*
* @return string Version.
* @throws DOMException On DOM operation error.
*/
public function getClientVersion()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('client');
}
public function getClientVersion()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('client');
}
/**
* Returns owner name.
*
*
* @return string Owner name.
* @throws DOMException On DOM operation error.
*/
public function getOwner()
{
return $this->documentElement->getElementsByTagName('owner')->item(0)->getAttribute('name');
}
public function getOwner()
{
return $this->documentElement->getElementsByTagName('owner')->item(0)->getAttribute('name');
}
/**
* Returns owner e-mail.
*
*
* @return string Owner e-mail.
* @throws DOMException On DOM operation error.
*/
public function getEMail()
{
return $this->documentElement->getElementsByTagName('owner')->item(0)->getAttribute('email');
}
public function getEMail()
{
return $this->documentElement->getElementsByTagName('owner')->item(0)->getAttribute('email');
}
/**
* Returns current amount of players online.
*
*
* @return int Count of players.
* @throws DOMException On DOM operation error.
*/
public function getOnlinePlayers()
{
return (int) $this->documentElement->getElementsByTagName('players')->item(0)->getAttribute('online');
}
public function getOnlinePlayers()
{
return (int) $this->documentElement->getElementsByTagName('players')->item(0)->getAttribute('online');
}
/**
* Returns maximum amount of players online.
*
*
* @return int Maximum allowed count of players.
* @throws DOMException On DOM operation error.
*/
public function getMaxPlayers()
{
return (int) $this->documentElement->getElementsByTagName('players')->item(0)->getAttribute('max');
}
public function getMaxPlayers()
{
return (int) $this->documentElement->getElementsByTagName('players')->item(0)->getAttribute('max');
}
/**
* Returns record of online players.
*
*
* @return int Players online record.
* @throws DOMException On DOM operation error.
*/
public function getPlayersPeak()
{
return (int) $this->documentElement->getElementsByTagName('players')->item(0)->getAttribute('peak');
}
public function getPlayersPeak()
{
return (int) $this->documentElement->getElementsByTagName('players')->item(0)->getAttribute('peak');
}
/**
* Returns number of all monsters on map.
*
*
* @return int Count of monsters.
* @throws DOMException On DOM operation error.
*/
public function getMonstersCount()
{
return (int) $this->documentElement->getElementsByTagName('monsters')->item(0)->getAttribute('total');
}
public function getMonstersCount(): int
{
return (int) $this->documentElement->getElementsByTagName('monsters')->item(0)->getAttribute('total');
}
public function getNPCsCount(): int
{
return (int) $this->documentElement->getElementsByTagName('npcs')->item(0)->getAttribute('total');
}
/**
* Returns map name.
*
*
* @return string Map name.
* @throws DOMException On DOM operation error.
*/
public function getMapName()
{
return $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('name');
}
public function getMapName()
{
return $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('name');
}
/**
* Returns map author.
*
*
* @return string Mapper name.
* @throws DOMException On DOM operation error.
*/
public function getMapAuthor()
{
return $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('author');
}
public function getMapAuthor()
{
return $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('author');
}
/**
* Returns map width.
*
*
* @return int Map width.
* @throws DOMException On DOM operation error.
*/
public function getMapWidth()
{
return (int) $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('width');
}
public function getMapWidth()
{
return (int) $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('width');
}
/**
* Returns map height.
*
*
* @return int Map height.
* @throws DOMException On DOM operation error.
*/
public function getMapHeight()
{
return (int) $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('height');
}
public function getMapHeight()
{
return (int) $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('height');
}
/**
* Returns server's Message Of The Day
*
*
* @version 0.1.0
* @return string Server MOTD.
* @throws DOMException On DOM operation error.
*/
public function getMOTD()
{
// look for text node child
foreach( $this->documentElement->getElementsByTagName('motd')->item(0)->childNodes as $child)
{
if($child->nodeType == XML_TEXT_NODE)
{
// found
return $child->nodeValue;
}
}
public function getMOTD()
{
// look for text node child
foreach( $this->documentElement->getElementsByTagName('motd')->item(0)->childNodes as $child)
{
if($child->nodeType == XML_TEXT_NODE)
{
// found
return $child->nodeValue;
}
}
// strange...
return '';
}
// strange...
return '';
}
/**
* Magic PHP5 method.
*
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
@@ -301,89 +306,89 @@ class OTS_InfoRespond extends DOMDocument
* @throws OutOfBoundsException For non-supported properties.
* @throws DOMException On DOM operation error.
*/
public function __get($name)
{
switch($name)
{
case 'tspqVersion':
return $this->getTSPQVersion();
public function __get($name)
{
switch($name)
{
case 'tspqVersion':
return $this->getTSPQVersion();
case 'uptime':
return $this->getUptime();
case 'uptime':
return $this->getUptime();
case 'ip':
return $this->getIP();
case 'ip':
return $this->getIP();
case 'name':
return $this->getName();
case 'name':
return $this->getName();
case 'port':
return $this->getPort();
case 'port':
return $this->getPort();
case 'location':
return $this->getLocation();
case 'location':
return $this->getLocation();
case 'url':
return $this->getURL();
case 'url':
return $this->getURL();
case 'server':
return $this->getServer();
case 'server':
return $this->getServer();
case 'serverVersion':
return $this->getServerVersion();
case 'serverVersion':
return $this->getServerVersion();
case 'clientVersion':
return $this->getClientVersion();
case 'clientVersion':
return $this->getClientVersion();
case 'owner':
return $this->getOwner();
case 'owner':
return $this->getOwner();
case 'eMail':
return $this->getEMail();
case 'eMail':
return $this->getEMail();
case 'onlinePlayers':
return $this->getOnlinePlayers();
case 'onlinePlayers':
return $this->getOnlinePlayers();
case 'maxPlayers':
return $this->getMaxPlayers();
case 'maxPlayers':
return $this->getMaxPlayers();
case 'playersPeak':
return $this->getPlayersPeak();
case 'playersPeak':
return $this->getPlayersPeak();
case 'monstersCount':
return $this->getMonstersCount();
case 'monstersCount':
return $this->getMonstersCount();
case 'mapName':
return $this->getMapName();
case 'mapName':
return $this->getMapName();
case 'mapAuthor':
return $this->getMapAuthor();
case 'mapAuthor':
return $this->getMapAuthor();
case 'mapWidth':
return $this->getMapWidth();
case 'mapWidth':
return $this->getMapWidth();
case 'mapHeight':
return $this->getMapHeight();
case 'mapHeight':
return $this->getMapHeight();
case 'motd':
return $this->getMOTD();
case 'motd':
return $this->getMOTD();
default:
throw new OutOfBoundsException();
}
}
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of XML.
*
*
* @version 0.1.0
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
return $this->saveXML();
}
public function __toString()
{
return $this->saveXML();
}
}
/**#@-*/

View File

@@ -2919,6 +2919,32 @@ class OTS_Player extends OTS_Row_DAO
$this->data['banned'] = $ban['active'];
$this->data['banned_time'] = $ban['expires'];
}
public function isNameLocked(): bool
{
// nothing can't be banned
if( !$this->isLoaded() ) {
throw new E_OTS_NotLoaded();
}
if($this->db->hasTable('player_namelocks')) {
$ban = $this->db->query('SELECT 1 FROM `player_namelocks` WHERE `player_id` = ' . $this->data['id'])->fetch(PDO::FETCH_ASSOC);
return (isset($ban['1']));
}
else if($this->db->hasTable('bans')) {
if($this->db->hasColumn('bans', 'active')) {
$ban = $this->db->query('SELECT `active`, `expires` FROM `bans` WHERE `type` = 2 AND `active` = 1 AND `value` = ' . $this->data['id'] . ' AND (`expires` > ' . time() .' OR `expires` = -1) ORDER BY `expires` DESC')->fetch();
return isset($ban['active']);
}
else { // tfs 0.2
$ban = $this->db->query('SELECT `time` FROM `bans` WHERE `type` = 2 AND `account` = ' . $this->data['account_id'] . ' AND (`time` > ' . time() .' OR `time` = -1) ORDER BY `time` DESC')->fetch();
return isset($ban['time']) && ($ban['time'] == -1 || $ban['time'] > 0);
}
}
return false;
}
/**
* Deletes player.
*
@@ -2953,21 +2979,14 @@ class OTS_Player extends OTS_Row_DAO
* @return string Player proffesion name.
* @throws E_OTS_NotLoaded If player is not loaded or global vocations list is not loaded.
*/
public function getVocationName()
public function getVocationName(): string
{
if( !isset($this->data['vocation']) )
{
throw new E_OTS_NotLoaded();
}
global $config;
$voc = $this->getVocation();
if(!isset($config['vocations'][$voc])) {
return 'Unknown';
}
return $config['vocations'][$voc];
//return POT::getInstance()->getVocationsList()->getVocationName($this->data['vocation']);
return OTS_Toolbox::getVocationName($this->data['vocation'], $this->data['promotion'] ?? 0);
}
/**

View File

@@ -26,14 +26,19 @@ class OTS_ServerInfo
*
* @var string
*/
private $server;
private string $server;
/**
* Connection port.
*
* @var int
*/
private $port;
private int $port;
/**
* Status timeout
*/
private float $timeout = 2.0;
/**
* Creates handler for new server.
@@ -41,11 +46,11 @@ class OTS_ServerInfo
* @param string $server Server IP/domain.
* @param int $port OTServ port.
*/
public function __construct($server, $port)
{
$this->server = $server;
$this->port = $port;
}
public function __construct($server, $port)
{
$this->server = $server;
$this->port = $port;
}
/**
* Sends packet to server.
@@ -54,46 +59,46 @@ class OTS_ServerInfo
* @return OTS_Buffer|null Respond buffer (null if server is offline).
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
private function send(OTS_Buffer $packet)
{
// connects to server
$socket = @fsockopen($this->server, $this->port, $error, $message, setting('core.status_timeout'));
private function send(OTS_Buffer $packet)
{
// connects to server
$socket = @fsockopen($this->server, $this->port, $error, $message, $this->timeout);
// if connected then checking statistics
if($socket)
{
// sets 5 second timeout for reading and writing
stream_set_timeout($socket, 5);
// if connected then checking statistics
if($socket)
{
// sets 5 second timeout for reading and writing
stream_set_timeout($socket, 5);
// creates real packet
$packet = $packet->getBuffer();
$packet = pack('v', strlen($packet) ) . $packet;
// creates real packet
$packet = $packet->getBuffer();
$packet = pack('v', strlen($packet) ) . $packet;
// sends packet with request
// 06 - length of packet, 255, 255 is the comamnd identifier, 'info' is a request
fwrite($socket, $packet);
// sends packet with request
// 06 - length of packet, 255, 255 is the comamnd identifier, 'info' is a request
fwrite($socket, $packet);
// reads respond
//$data = stream_get_contents($socket);
// reads respond
//$data = stream_get_contents($socket);
$data = '';
while (!feof($socket))
$data .= fgets($socket, 1024);
// closing connection to current server
fclose($socket);
// closing connection to current server
fclose($socket);
// sometimes server returns empty info
if( empty($data) )
{
// returns offline state
return false;
}
// sometimes server returns empty info
if( empty($data) )
{
// returns offline state
return false;
}
return new OTS_Buffer($data);
}
return new OTS_Buffer($data);
}
return false;
}
return false;
}
/**
* Queries server status.
@@ -108,30 +113,30 @@ class OTS_ServerInfo
* @example examples/info.php info.php
* @tutorial POT/Server_status.pkg
*/
public function status()
{
// request packet
$request = new OTS_Buffer();
$request->putChar(255);
$request->putChar(255);
$request->putString('info', false);
public function status()
{
// request packet
$request = new OTS_Buffer();
$request->putChar(255);
$request->putChar(255);
$request->putString('info', false);
$status = $this->send($request);
$status = $this->send($request);
// checks if server is online
if($status)
{
// loads respond XML
$info = new OTS_InfoRespond();
if(!$info->loadXML( $status->getBuffer()))
// checks if server is online
if($status)
{
// loads respond XML
$info = new OTS_InfoRespond();
if(!$info->loadXML( $status->getBuffer()))
return false;
return $info;
}
return $info;
}
// offline
return false;
}
// offline
return false;
}
/**
* Queries server information.
@@ -146,26 +151,26 @@ class OTS_ServerInfo
* @example examples/server.php info.php
* @tutorial POT/Server_status.pkg
*/
public function info($flags)
{
// request packet
$request = new OTS_Buffer();
$request->putChar(255);
$request->putChar(1);
$request->putShort($flags);
public function info($flags)
{
// request packet
$request = new OTS_Buffer();
$request->putChar(255);
$request->putChar(1);
$request->putShort($flags);
$status = $this->send($request);
$status = $this->send($request);
// checks if server is online
if($status)
{
// loads respond
return new OTS_ServerStatus($status);
}
// checks if server is online
if($status)
{
// loads respond
return new OTS_ServerStatus($status);
}
// offline
return false;
}
// offline
return false;
}
/**
* Checks player online status.
@@ -180,27 +185,27 @@ class OTS_ServerInfo
* @example examples/server.php info.php
* @tutorial POT/Server_status.pkg
*/
public function playerStatus($name)
{
// request packet
$request = new OTS_Buffer();
$request->putChar(255);
$request->putChar(1);
$request->putShort(OTS_ServerStatus::REQUEST_PLAYER_STATUS_INFO);
$request->putString($name);
public function playerStatus($name)
{
// request packet
$request = new OTS_Buffer();
$request->putChar(255);
$request->putChar(1);
$request->putShort(OTS_ServerStatus::REQUEST_PLAYER_STATUS_INFO);
$request->putString($name);
$status = $this->send($request);
$status = $this->send($request);
// checks if server is online
if($status)
{
$status->getChar();
return (bool) $status->getChar();
}
// checks if server is online
if($status)
{
$status->getChar();
return (bool) $status->getChar();
}
// offline
return false;
}
// offline
return false;
}
/**
* Magic PHP5 method.
@@ -210,20 +215,24 @@ class OTS_ServerInfo
* @throws OutOfBoundsException For non-supported properties.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function __get($name)
{
switch($name)
{
case 'status':
return $this->status();
public function __get($name)
{
switch($name)
{
case 'status':
return $this->status();
case 'info':
return $this->info(OTS_ServerStatus::REQUEST_BASIC_SERVER_INFO | OTS_ServerStatus::REQUEST_OWNER_SERVER_INFO | OTS_ServerStatus::REQUEST_MISC_SERVER_INFO | OTS_ServerStatus::REQUEST_PLAYERS_INFO | OTS_ServerStatus::REQUEST_MAP_INFO | OTS_ServerStatus::REQUEST_PLAYER_STATUS_INFO);
case 'info':
return $this->info(OTS_ServerStatus::REQUEST_BASIC_SERVER_INFO | OTS_ServerStatus::REQUEST_OWNER_SERVER_INFO | OTS_ServerStatus::REQUEST_MISC_SERVER_INFO | OTS_ServerStatus::REQUEST_PLAYERS_INFO | OTS_ServerStatus::REQUEST_MAP_INFO | OTS_ServerStatus::REQUEST_PLAYER_STATUS_INFO);
default:
throw new OutOfBoundsException();
}
}
default:
throw new OutOfBoundsException();
}
}
public function setTimeout($timeout) {
$this->timeout = $timeout;
}
}
/**#@-*/

View File

@@ -40,175 +40,175 @@ class OTS_ServerStatus
/**
* Basic server info.
*/
const REQUEST_BASIC_SERVER_INFO = 1;
const REQUEST_BASIC_SERVER_INFO = 1;
/**
* Server owner info.
*/
const REQUEST_OWNER_SERVER_INFO = 2;
const REQUEST_OWNER_SERVER_INFO = 2;
/**
* Server extra info.
*/
const REQUEST_MISC_SERVER_INFO = 4;
const REQUEST_MISC_SERVER_INFO = 4;
/**
* Players stats info.
*/
const REQUEST_PLAYERS_INFO = 8;
const REQUEST_PLAYERS_INFO = 8;
/**
* Map info.
*/
const REQUEST_MAP_INFO = 16;
const REQUEST_MAP_INFO = 16;
/**
* Extended players info.
*/
const REQUEST_EXT_PLAYERS_INFO = 32;
const REQUEST_EXT_PLAYERS_INFO = 32;
/**
* Player status info.
*/
const REQUEST_PLAYER_STATUS_INFO = 64;
const REQUEST_PLAYER_STATUS_INFO = 64;
/**
* Server software info.
*/
const REQUEST_SERVER_SOFTWARE_INFO = 128;
const REQUEST_SERVER_SOFTWARE_INFO = 128;
/**
* Basic server respond.
*/
const RESPOND_BASIC_SERVER_INFO = 0x10;
const RESPOND_BASIC_SERVER_INFO = 0x10;
/**
* Server owner respond.
*/
const RESPOND_OWNER_SERVER_INFO = 0x11;
const RESPOND_OWNER_SERVER_INFO = 0x11;
/**
* Server extra respond.
*/
const RESPOND_MISC_SERVER_INFO = 0x12;
const RESPOND_MISC_SERVER_INFO = 0x12;
/**
* Players stats respond.
*/
const RESPOND_PLAYERS_INFO = 0x20;
const RESPOND_PLAYERS_INFO = 0x20;
/**
* Map respond.
*/
const RESPOND_MAP_INFO = 0x30;
const RESPOND_MAP_INFO = 0x30;
/**
* Extended players info.
*/
const RESPOND_EXT_PLAYERS_INFO = 0x21;
const RESPOND_EXT_PLAYERS_INFO = 0x21;
/**
* Player status info.
*/
const RESPOND_PLAYER_STATUS_INFO = 0x22;
const RESPOND_PLAYER_STATUS_INFO = 0x22;
/**
* Server software info.
*/
const RESPOND_SERVER_SOFTWARE_INFO = 0x23;
const RESPOND_SERVER_SOFTWARE_INFO = 0x23;
/**
* Server name.
*
* @var string
*/
private $name;
private $name;
/**
* Server IP.
*
* @var string
*/
private $ip;
private $ip;
/**
* Server port.
*
* @var string
*/
private $port;
private $port;
/**
* Owner name.
*
* @var string
*/
private $owner;
private $owner;
/**
* Owner's e-mail.
*
* @var string
*/
private $eMail;
private $eMail;
/**
* Message of the day.
*
* @var string
*/
private $motd;
private $motd;
/**
* Server location.
*
* @var string
*/
private $location;
private $location;
/**
* Website URL.
*
* @var string
*/
private $url;
private $url;
/**
* Uptime.
*
* @var int
*/
private $uptime;
private $uptime;
/**
* Status version.
*
* @var string
*/
private $version;
private $version;
/**
* Players online.
*
* @var int
*/
private $online;
private $online;
/**
* Maximum players.
*
* @var int
*/
private $max;
private $max;
/**
* Players peak.
*
* @var int
*/
private $peak;
private $peak;
/**
* Map name.
*
* @var string
*/
private $map;
private $map;
/**
* Map author.
*
* @var string
*/
private $author;
private $author;
/**
* Map width.
*
* @var int
*/
private $width;
private $width;
/**
* Map height.
*
* @var int
*/
private $height;
private $height;
/**
* Players online list.
*
* @var array
*/
private $players = array();
private $players = array();
/**
* Server software.
@@ -224,277 +224,277 @@ class OTS_ServerStatus
*
* @param OTS_Buffer $info Information packet.
*/
public function __construct(OTS_Buffer $info)
{
// skips packet length
$info->getShort();
public function __construct(OTS_Buffer $info)
{
// skips packet length
$info->getShort();
while( $info->isValid() )
{
switch( $info->getChar() )
{
case self::RESPOND_BASIC_SERVER_INFO:
$this->name = $info->getString();
$this->ip = $info->getString();
$this->port = (int) $info->getString();
break;
while( $info->isValid() )
{
switch( $info->getChar() )
{
case self::RESPOND_BASIC_SERVER_INFO:
$this->name = $info->getString();
$this->ip = $info->getString();
$this->port = (int) $info->getString();
break;
case self::RESPOND_OWNER_SERVER_INFO:
$this->owner = $info->getString();
$this->eMail = $info->getString();
break;
case self::RESPOND_OWNER_SERVER_INFO:
$this->owner = $info->getString();
$this->eMail = $info->getString();
break;
case self::RESPOND_MISC_SERVER_INFO:
$this->motd = $info->getString();
$this->location = $info->getString();
$this->url = $info->getString();
case self::RESPOND_MISC_SERVER_INFO:
$this->motd = $info->getString();
$this->location = $info->getString();
$this->url = $info->getString();
$uptime = $info->getLong() << 32;
$uptime = $info->getLong() << 32;
$this->uptime += $info->getLong() + $uptime;
$this->version = $info->getString();
break;
$this->uptime += $info->getLong() + $uptime;
$this->version = $info->getString();
break;
case self::RESPOND_PLAYERS_INFO:
$this->online = $info->getLong();
$this->max = $info->getLong();
$this->peak = $info->getLong();
break;
case self::RESPOND_PLAYERS_INFO:
$this->online = $info->getLong();
$this->max = $info->getLong();
$this->peak = $info->getLong();
break;
case self::RESPOND_MAP_INFO:
$this->map = $info->getString();
$this->author = $info->getString();
$this->width = $info->getShort();
$this->height = $info->getShort();
break;
case self::RESPOND_MAP_INFO:
$this->map = $info->getString();
$this->author = $info->getString();
$this->width = $info->getShort();
$this->height = $info->getShort();
break;
case self::RESPOND_EXT_PLAYERS_INFO:
$count = $info->getLong();
case self::RESPOND_EXT_PLAYERS_INFO:
$count = $info->getLong();
for($i = 0; $i < $count; $i++)
{
$name = $info->getString();
$this->players[$name] = $info->getLong();
}
break;
for($i = 0; $i < $count; $i++)
{
$name = $info->getString();
$this->players[$name] = $info->getLong();
}
break;
case self::RESPOND_SERVER_SOFTWARE_INFO:
$this->softwareName = $info->getString();
$this->softwareVersion = $info->getString();
$this->softwareProtocol = $info->getString();
break;
}
}
}
}
}
}
/**
* Returns server uptime.
*
* @return int Uptime.
*/
public function getUptime()
{
return $this->uptime;
}
public function getUptime()
{
return $this->uptime;
}
/**
* Returns server IP.
*
* @return string IP.
*/
public function getIP()
{
return $this->ip;
}
public function getIP()
{
return $this->ip;
}
/**
* Returns server name.
*
* @return string Name.
*/
public function getName()
{
return $this->name;
}
public function getName()
{
return $this->name;
}
/**
* Returns server port.
*
* @return int Port.
*/
public function getPort()
{
return $this->port;
}
public function getPort()
{
return $this->port;
}
/**
* Returns server location.
*
* @return string Location.
*/
public function getLocation()
{
return $this->location;
}
public function getLocation()
{
return $this->location;
}
/**
* Returns server website.
*
* @return string Website URL.
*/
public function getURL()
{
return $this->url;
}
public function getURL()
{
return $this->url;
}
/**
* Returns server version.
*
* @return string Version.
*/
public function getServerVersion()
{
return $this->version;
}
public function getServerVersion()
{
return $this->version;
}
/**
* Returns owner name.
*
* @return string Owner name.
*/
public function getOwner()
{
return $this->owner;
}
public function getOwner()
{
return $this->owner;
}
/**
* Returns owner e-mail.
*
* @return string Owner e-mail.
*/
public function getEMail()
{
return $this->eMail;
}
public function getEMail()
{
return $this->eMail;
}
/**
* Returns current amount of players online.
*
* @return int Count of players.
*/
public function getOnlinePlayers()
{
return $this->online;
}
public function getOnlinePlayers()
{
return $this->online;
}
/**
* Returns maximum amount of players online.
*
* @return int Maximum allowed count of players.
*/
public function getMaxPlayers()
{
return $this->max;
}
public function getMaxPlayers()
{
return $this->max;
}
/**
* Returns record of online players.
*
* @return int Players online record.
*/
public function getPlayersPeak()
{
return $this->peak;
}
public function getPlayersPeak()
{
return $this->peak;
}
/**
* Returns map name.
*
* @return string Map name.
*/
public function getMapName()
{
return $this->map;
}
public function getMapName()
{
return $this->map;
}
/**
* Returns map author.
*
* @return string Mapper name.
*/
public function getMapAuthor()
{
return $this->author;
}
public function getMapAuthor()
{
return $this->author;
}
/**
* Returns map width.
*
* @return int Map width.
*/
public function getMapWidth()
{
return $this->width;
}
public function getMapWidth()
{
return $this->width;
}
/**
* Returns map height.
*
* @return int Map height.
*/
public function getMapHeight()
{
return $this->height;
}
public function getMapHeight()
{
return $this->height;
}
/**
* Returns server's Message Of The Day
*
* @return string Server MOTD.
*/
public function getMOTD()
{
return $this->motd;
}
public function getMOTD()
{
return $this->motd;
}
/**
* Returns list of players currently online.
*
* @return array List of players in format 'name' => level.
*/
public function getPlayers()
{
}
public function getPlayers()
{
}
/**
* Returns software name.
*
* @return string Software name.
*/
public function getSoftwareName()
{
return $this->softwareName;
}
public function getSoftwareName()
{
return $this->softwareName;
}
/**
* Returns software version.
*
* @return string Software version.
*/
public function getSoftwareVersion()
{
return $this->softwareVersion;
}
public function getSoftwareVersion()
{
return $this->softwareVersion;
}
/**
* Returns software protocol.
*
* @return string Software protocol.
*/
public function getSoftwareProtocol()
{
return $this->softwareProtocol;
}
public function getSoftwareProtocol()
{
return $this->softwareProtocol;
}
/**
* Magic PHP5 method.
@@ -503,68 +503,68 @@ class OTS_ServerStatus
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __get($name)
{
switch($name)
{
case 'uptime':
return $this->getUptime();
public function __get($name)
{
switch($name)
{
case 'uptime':
return $this->getUptime();
case 'ip':
return $this->getIP();
case 'ip':
return $this->getIP();
case 'name':
return $this->getName();
case 'name':
return $this->getName();
case 'port':
return $this->getPort();
case 'port':
return $this->getPort();
case 'location':
return $this->getLocation();
case 'location':
return $this->getLocation();
case 'url':
return $this->getURL();
case 'url':
return $this->getURL();
case 'serverVersion':
return $this->getServerVersion();
case 'serverVersion':
return $this->getServerVersion();
case 'owner':
return $this->getOwner();
case 'owner':
return $this->getOwner();
case 'eMail':
return $this->getEMail();
case 'eMail':
return $this->getEMail();
case 'onlinePlayers':
return $this->getOnlinePlayers();
case 'onlinePlayers':
return $this->getOnlinePlayers();
case 'maxPlayers':
return $this->getMaxPlayers();
case 'maxPlayers':
return $this->getMaxPlayers();
case 'playersPeak':
return $this->getPlayersPeak();
case 'playersPeak':
return $this->getPlayersPeak();
case 'mapName':
return $this->getMapName();
case 'mapName':
return $this->getMapName();
case 'mapAuthor':
return $this->getMapAuthor();
case 'mapAuthor':
return $this->getMapAuthor();
case 'mapWidth':
return $this->getMapWidth();
case 'mapWidth':
return $this->getMapWidth();
case 'mapHeight':
return $this->getMapHeight();
case 'mapHeight':
return $this->getMapHeight();
case 'motd':
return $this->getMOTD();
case 'motd':
return $this->getMOTD();
case 'players':
return $this->getPlayers();
case 'players':
return $this->getPlayers();
default:
throw new OutOfBoundsException();
}
}
default:
throw new OutOfBoundsException();
}
}
}
/**#@-*/

View File

@@ -15,7 +15,7 @@
/**
* Toolbox for common operations.
*
*
* @package POT
* @version 0.1.5
*/
@@ -23,41 +23,41 @@ class OTS_Toolbox
{
/**
* Calculates experience points needed for given level.
*
*
* @param int $level Level for which experience should be calculated.
* @param int $experience Current experience points.
* @return int Experience points for level.
*/
public static function experienceForLevel($level, $experience = 0)
{
//return 50 * ($level - 1) * ($level * $level - 5 * $level + 12) / 3 - $experience;
{
//return 50 * ($level - 1) * ($level * $level - 5 * $level + 12) / 3 - $experience;
$level = $level - 1;
return ((50 * $level * $level * $level) - (150 * $level * $level) + (400 * $level)) / 3;
}
}
/**
* Finds out which level user have basing on his/her experience.
*
*
* <p>
* PHP doesn't support complex numbers natively so solving third-level polynomials would be quite hard. Rather then doing this, this method iterates calculating experience for next levels until it finds one which requires enought experience we have. Because of that, for high experience values this function can take relatively long time to be executed.
* </p>
*
*
* @param int $experience Current experience points.
* @return int Experience level.
*/
public static function levelForExperience($experience)
{
// default level
$level = 1;
public static function levelForExperience($experience)
{
// default level
$level = 1;
// until we will find level which requires more experience then we have we will step to next
while( self::experienceForLevel($level + 1) <= $experience)
{
$level++;
}
// until we will find level which requires more experience then we have we will step to next
while( self::experienceForLevel($level + 1) <= $experience)
{
$level++;
}
return $level;
}
return $level;
}
/**
* @version 0.1.5
@@ -65,25 +65,25 @@ class OTS_Toolbox
* @return OTS_Players_List Filtered list.
* @deprecated 0.1.5 Use OTS_PlayerBans_List.
*/
public static function bannedPlayers()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_PLAYER);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'players') );
public static function bannedPlayers()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_PLAYER);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'players') );
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// creates list and aplies filter
$list = new OTS_Players_List();
$list->setFilter($filter);
return $list;
}
// creates list and aplies filter
$list = new OTS_Players_List();
$list->setFilter($filter);
return $list;
}
/**
* @version 0.1.5
@@ -91,25 +91,34 @@ class OTS_Toolbox
* @return OTS_Accounts_List Filtered list.
* @deprecated 0.1.5 Use OTS_AccountBans_List.
*/
public static function bannedAccounts()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_ACCOUNT);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'accounts') );
public static function bannedAccounts()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_ACCOUNT);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'accounts') );
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// creates list and aplies filter
$list = new OTS_Accounts_List();
$list->setFilter($filter);
return $list;
}
// creates list and aplies filter
$list = new OTS_Accounts_List();
$list->setFilter($filter);
return $list;
}
public static function getVocationName($id, $promotion = 0): string
{
if($promotion > 0) {
$id = ($id + ($promotion * config('vocations_amount')));
}
return config('vocations')[$id] ?? 'Unknown';
}
}
/**#@-*/