| @@ -0,0 +1,358 @@ | |||
| <?php | |||
| class MinecraftPaymentPlugin extends Plugin { | |||
| public static function get_plugin_name(): string { | |||
| return 'Minecraft Payment'; | |||
| } | |||
| public function __construct( $_DB ) { | |||
| $this->require_class( 'RCon' ); | |||
| } | |||
| public function has_page(): bool { | |||
| return true; | |||
| } | |||
| public function get_page_path() { | |||
| return [ | |||
| '/minecraft-pay/' => [ | |||
| 'settings' => [ | |||
| null => 'settings_view', | |||
| '/*' => 'server_settings_view' | |||
| ], | |||
| 'users' => [ | |||
| null => 'users_view', | |||
| '/*' => 'user_view' | |||
| ], | |||
| 'grant' => 'grant_view', | |||
| 'settle' => 'settle_view', | |||
| 'balance' => 'balance_view', | |||
| 'acredit' => 'acredit_view' | |||
| ] | |||
| ]; | |||
| // return [ '/minecraft-pay/settings', '/minecraft-pay/settings/*', '/minecraft-pay/users', '/minecraft-pay/grant', '/minecraft-pay/settle', '/minecraft-pay/balance', '/minecraft-pay/users/*', '/minecraft-pay/acredit' ]; | |||
| } | |||
| public function grant_view( string $url ) { | |||
| if ( !Permission::PERMITTED( 'Minecraft-Pay-Settings', 1 ) ) return; | |||
| $params = []; | |||
| if ( array_key_exists( 'GrantUserRights', $_POST ) && array_key_exists( 'ID', $_POST ) ) { | |||
| $u = User::GetByID( $_POST[ 'ID' ] ); | |||
| $s = false; | |||
| if ( !is_null( $u ) ) { | |||
| $p = Permission::SEARCH( 'Minecraft-Possess-User' ); | |||
| $s = $p->grant_user( $u->GetID(), true ); $s = true; | |||
| // echo $p; | |||
| // echo $s; | |||
| $params[ 'save_message' ] = | |||
| // $s ? | |||
| __( [ 'de' => 'Recht erfolgreich gewährt', 'en' => 'Right granted successfully' ] ); // : | |||
| // __( [ 'de' => 'Recht konnte nicht gewährt werden', 'en' => 'Right could not be granted' ] ); | |||
| } | |||
| else $params[ 'save_message' ] = __( [ 'de' => 'Benutzer nicht gefunden', 'en' => 'Could not find user' ] ); | |||
| $params[ 'save_success' ] = $s; | |||
| } | |||
| $this->show_template( 'GrantUser', $params ); | |||
| } | |||
| public function settle_view( string $url ) { | |||
| $m = array_key_exists( 'month', $_GET ) ? $_GET[ 'month' ] : date( 'm' ) - 1; | |||
| $y = array_key_exists( 'month', $_GET ) ? $_GET[ 'month' ] : date( 'Y' ); | |||
| if ( $m == '0' ) { $m = '12'; $y--; } | |||
| $mp = MinecraftMonthPaid::GetByUnique( 0, $m ,$y ); | |||
| if ( $mp ) { | |||
| echo __( [ 'de' => 'Bereits abgerechnet', 'en' => 'Already settled' ] ); | |||
| return; | |||
| } | |||
| $sum = 0; | |||
| foreach ( MinecraftServer::GetAll() as $server ) { | |||
| $m = strlen( $m ) == 2 ? $m : '0' . $m; | |||
| $f = "$y-$m-01"; | |||
| $cap = date( 't', strtotime( $f ) ); | |||
| $l = "$y-$m-$cap"; | |||
| $sid = $server->ID; | |||
| $subscribers = MinecraftServerSubscription::GetAll( "ConcerningServerID = $sid AND SubscriptionDate BETWEEN '$f' AND '$l'" ); | |||
| $subsCount = count( $subscribers ); | |||
| $pot = $subsCount * $server->GetPerMonthPrice(); | |||
| $potPart = ceil( ( $pot / $subsCount ) * 100 ) / 100; | |||
| if ( $pot == 0 ) continue; | |||
| $potPart *= -1; | |||
| if ( $pot > $server->GetMaxPerMonthPrice() ) $pot = $server->GetMaxPerMonthPrice(); | |||
| $sum += $pot; | |||
| /* $dayssum = 0; | |||
| $subs = []; | |||
| $sum += $pot; | |||
| $potheap = 0; | |||
| $dayssumheap = 0; | |||
| foreach( $subscribers as $subscriber ) { | |||
| $days = date( 'd', strtotime( $subscriber->GetSubscriptionDate() ) ); | |||
| $dayssum += $days; | |||
| $subs[] = [ $days, $subscriber ]; | |||
| } | |||
| foreach ( $subs as $subscription ) { | |||
| $price = $pot * ( $dayssum / $subscription[ 0 ] ) | |||
| }*/ | |||
| foreach( $subscribers as $subscriber ) { | |||
| $u = $subscriber->GetUnlockedUser()->GetOwner(); | |||
| $ac = new MinecraftUserAccount(); | |||
| $ac->SetMod( $potPart ); | |||
| $ac->SetDebtor( $u ); | |||
| $ac->SetComment( 'Host-Relief for ' . $server->GetName() . ' for ' . $m . '-' . $y ); | |||
| $ac->Save(); | |||
| } | |||
| $server->ClearWhitelist(); | |||
| } | |||
| $mp = new MinecraftMonthPaid(); | |||
| $mp->SetAmount( $sum ); | |||
| $mp->SetMonth( $m ); | |||
| $mp->SetYear( $y ); | |||
| if ( $mp->Save() ) { | |||
| echo __( [ 'de' => 'Abrechnung beendet', 'en' => 'Settled' ] ); | |||
| } | |||
| } | |||
| public function acredit_view( string $url ) { | |||
| if ( !Permission::PERMITTED( 'Minecraft-Pay-Settings', 1 ) ) return; | |||
| $params = null; | |||
| if ( | |||
| array_key_exists( 'AddAccountChange', $_POST ) && | |||
| array_key_exists( 'Mod', $_POST ) && | |||
| array_key_exists( 'DebtorID', $_POST ) && | |||
| array_key_exists( 'Comment', $_POST ) | |||
| ) { | |||
| $ac = MinecraftUserAccount::FromPropertyArray( $_POST ); | |||
| $ac->SetDebtor( User::GetByID( $_POST[ 'DebtorID' ] ) ); | |||
| $params = []; | |||
| $params[ 'save_success' ] = $ac->Save(); | |||
| $params[ 'save_message' ] = | |||
| $params[ 'save_success' ] ? | |||
| __( [ 'de' => 'Gutschrift erfolgreich', 'en' => 'Credit successful' ] ) : | |||
| __( [ 'de' => 'Gutschrift fehlgeschlagen', 'en' => 'Credit failed' ] ); | |||
| } | |||
| $this->show_template( 'AlterAccount', $params ); | |||
| } | |||
| public function balance_view( string $url ) { | |||
| if ( !Permission::PERMITTED( 'Minecraft-Possess-User', 1 ) ) return; | |||
| $this->show_template( 'AccountList', null ); | |||
| } | |||
| public function users_view( string $url ) { | |||
| if ( !Permission::PERMITTED( 'Minecraft-Possess-User', 1 ) ) return; | |||
| if ( $url == '/minecraft-pay/users' ) { | |||
| $params = []; | |||
| if ( array_key_exists( 'CreateMinecraftUser', $_POST ) && array_key_exists( 'Username', $_POST ) ) { | |||
| $s = MinecraftUser::FromPropertyArray( $_POST ); | |||
| $s->SetOwner( User::CURRENT() ); | |||
| try { | |||
| $s->Save(); | |||
| $params[ 'save_message' ] = __( [ 'de' => 'Minecraft Benutzer erfolgreich angelegt', 'en' => 'Created minecraft user successfully' ] ); | |||
| $params[ 'save_success' ] = true; | |||
| } catch( Exception $ex ) { | |||
| $params[ 'save_message' ] = $ex->getMessage(); | |||
| if ( startsWith( $params[ 'save_message' ], 'Duplicate entry' ) ) | |||
| $params[ 'save_message' ] = __( | |||
| [ | |||
| 'de' => 'Doppelter Name oder es wurde bei einem anderen Server weder Domain noch Port angegeben', | |||
| 'en' => 'Duplicated Name or another server has neither domain nor port' | |||
| ] | |||
| ); | |||
| $params[ 'save_success' ] = false; | |||
| } | |||
| } | |||
| if ( array_key_exists( 'DeleteMinecraftUser', $_POST ) && array_key_exists( 'ID', $_POST ) ) { | |||
| $s = MinecraftUser::GetByID( $_POST[ 'ID' ] ); | |||
| if ( User::CURRENT()->GetID() != $s->GetOwner()->GetID() ) { | |||
| $params[ 'save_message' ] = __( [ 'de' => 'Dieser Benutzer gehöt Ihnen nicht!', 'en' => 'This user does not belong to you!' ] ); | |||
| $params[ 'save_success' ] = false; | |||
| } else { | |||
| try { | |||
| $s->Delete(); | |||
| $params[ 'save_message' ] = __( [ 'de' => 'Minecraft Benutzer erfolgreich gelöscht', 'en' => 'Deleted minecraft user successfully' ] ); | |||
| $params[ 'save_success' ] = true; | |||
| } catch( Exception $ex ) { | |||
| $params[ 'save_message' ] = $ex->getMessage(); | |||
| $params[ 'save_success' ] = false; | |||
| } | |||
| } | |||
| } | |||
| $this->show_template( 'UsersList', $params ); | |||
| } else $this->user_view( $url ); | |||
| } | |||
| public function user_view( string $url ) { | |||
| if ( !Permission::PERMITTED( 'Minecraft-Possess-User', 1 ) ) return; | |||
| if ( !preg_match( '/\/minecraft-pay\/users\/([0-9]+)/', $url, $m ) || is_null( MinecraftUser::GetByID( $m[ 1 ] ) ) ) { | |||
| Alert::SHOW( __( [ 'de' => 'Dieser Benutzer existiert nicht', 'en' => 'This user does not exist' ] ) ); | |||
| return; | |||
| } | |||
| $params = []; | |||
| if ( array_key_exists( 'RUnlockUser', $_POST ) && array_key_exists( 'ID', $_POST ) ) { | |||
| $s = MinecraftServer::GetByID( $_POST[ 'ID' ] ); | |||
| $u = MinecraftUser::GetByID( $m[ 1 ] ); | |||
| if ( is_null( $s ) ) { $params[ 'save_message' ] = __( [ 'de' => 'Unbekannter Server', 'en' => 'Unknown server' ] ); $params[ 'save_success' ] = false; } | |||
| else if ( is_null( $u ) ) { $params[ 'save_message' ] = __( [ 'de' => 'Unbekannter Benutzer', 'en' => 'Unknown user' ] ); $params[ 'save_success' ] = false; } | |||
| else { | |||
| if ( $s->Unlock( $u ) ) { | |||
| if ( !$u->HasSubscripted( $s ) ) { | |||
| $ms = new MinecraftServerSubscription(); | |||
| $ms->SetConcerningServer( $s ); | |||
| $ms->SetUnlockedUser( $u ); | |||
| $params[ 'save_success' ] = $ms->Save(); | |||
| $params[ 'save_message' ] = | |||
| $params[ 'save_success' ] ? | |||
| __( [ 'de' => 'Erfolgreich freigeschaltet', 'en' => 'Unlock successful' ] ) : | |||
| __( [ 'de' => 'Freischaltung fehlgeschlagen', 'en' => 'Unlock failed' ] ); | |||
| if ( !$params[ 'save_success' ] ) $s->Lock( $u ); | |||
| } else { $params[ 'save_message' ] = __( [ 'de' => 'Erfolgreich freigeschaltet', 'en' => 'Unlock successful' ] ); $params[ 'save_success' ] = true; } | |||
| } else { $params[ 'save_message' ] = __( [ 'de' => 'Freischaltung fehlgeschlagen', 'en' => 'Unlock failed' ] ); $params[ 'save_success' ] = false; } | |||
| } | |||
| } | |||
| $params[ 'user' ] = MinecraftUser::GetByID( $m[ 1 ] ); | |||
| $this->show_template( 'Users', $params ); | |||
| } | |||
| public function settings_view( string $url ) { | |||
| if ( !Permission::PERMITTED( 'Minecraft-Pay-Settings', 1 ) ) return; | |||
| if ( $url == '/minecraft-pay/settings' ) { | |||
| $params = []; | |||
| if ( array_key_exists( 'CreateServer', $_POST ) && array_key_exists( 'Name', $_POST ) ) { | |||
| $s = MinecraftServer::FromPropertyArray( $_POST ); | |||
| try { | |||
| $s->Save(); | |||
| $params[ 'save_message' ] = __( [ 'de' => 'Server erfolgreich angelegt', 'en' => 'Created server successfully' ] ); | |||
| $params[ 'save_success' ] = true; | |||
| } catch( Exception $ex ) { | |||
| $params[ 'save_message' ] = $ex->getMessage(); | |||
| if ( startsWith( $params[ 'save_message' ], 'Duplicate entry' ) ) | |||
| $params[ 'save_message' ] = __( | |||
| [ | |||
| 'de' => 'Doppelter Name oder es wurde bei einem anderen Server weder Domain noch Port angegeben', | |||
| 'en' => 'Duplicated Name or another server has neither domain nor port' | |||
| ] | |||
| ); | |||
| $params[ 'save_success' ] = false; | |||
| } | |||
| } | |||
| if ( array_key_exists( 'DeleteServer', $_POST ) && array_key_exists( 'ID', $_POST ) ) { | |||
| $s = MinecraftServer::FromPropertyArray( $_POST ); | |||
| try { | |||
| $s->Delete(); | |||
| $params[ 'save_message' ] = __( [ 'de' => 'Server erfolgreich gelöscht', 'en' => 'Deleted server successfully' ] ); | |||
| $params[ 'save_success' ] = true; | |||
| } catch( Exception $ex ) { | |||
| $params[ 'save_message' ] = $ex->getMessage(); | |||
| $params[ 'save_success' ] = false; | |||
| } | |||
| } | |||
| $this->show_template( 'SettingsList', $params ); | |||
| } | |||
| else $this->server_settings_view( $url ); | |||
| // $this->show_template( 'Settings', [ 'settings' => (object) [ 'Server' => '', 'Port' => 35575, 'Password' => '' ] ] ); | |||
| } | |||
| public function server_settings_view( string $url ) { | |||
| if ( !Permission::PERMITTED( 'Minecraft-Pay-Settings', 1 ) ) return; | |||
| if ( !preg_match( '/\/minecraft-pay\/settings\/([0-9]+)/', $url, $m ) || is_null( MinecraftServer::GetByID( $m[ 1 ] ) ) ) { | |||
| Alert::SHOW( __( [ 'de' => 'Dieser Server existiert nicht', 'en' => 'This server does not exist' ] ) ); | |||
| return; | |||
| } | |||
| $params = []; | |||
| if ( | |||
| array_key_exists( 'SaveServerSettings', $_POST ) && | |||
| array_key_exists( 'Domain', $_POST ) && | |||
| array_key_exists( 'Port', $_POST ) && | |||
| array_key_exists( 'Password', $_POST ) && | |||
| array_key_exists( 'ServerPath', $_POST ) | |||
| ) { | |||
| if ( !$_POST[ 'Port' ] ) $_POST[ 'Port' ] = null; | |||
| $o = MinecraftServer::GetByID( $m[ 1 ] ); | |||
| $s = MinecraftServer::FromPropertyArray( $_POST ); | |||
| $s->SetID( $o->GetID() ); | |||
| $s->SetName( $o->GetName() ); | |||
| try { | |||
| $s->Save(); | |||
| $params[ 'save_message' ] = __( [ 'de' => 'Server erfolgreich gespeichert', 'en' => 'Saved server successfully' ] ); | |||
| $params[ 'save_success' ] = true; | |||
| } catch( Exception $ex ) { | |||
| $params[ 'save_message' ] = $ex->getMessage(); | |||
| if ( startsWith( $params[ 'save_message' ], 'Duplicate entry' ) ) | |||
| $params[ 'save_message' ] = __( | |||
| [ | |||
| 'de' => 'Doppelte Domain noch Port Kombination', | |||
| 'en' => 'Duplicated domain - port combination' | |||
| ] | |||
| ); | |||
| $params[ 'save_success' ] = false; | |||
| } | |||
| } | |||
| $params[ 'settings' ] = MinecraftServer::GetByID( $m[ 1 ] ); | |||
| $this->show_template( 'Settings', $params ); | |||
| } | |||
| public function load_plugin(): void { | |||
| if ( is_null( Permission::GetByUnique( 0, 'Minecraft-Pay-Settings' ) ) ) { | |||
| $p = Permission::FromArray( [], [] ); | |||
| $p->SetName( 'Minecraft-Pay-Settings' ); | |||
| $p->SetSlug( slugify( 'Minecraft-Pay-Settings' ) ); | |||
| $p->Save(); | |||
| } | |||
| if ( is_null( Permission::GetByUnique( 0, 'Minecraft-Possess-User' ) ) ) { | |||
| $p = Permission::FromArray( [], [] ); | |||
| $p->SetName( 'Minecraft-Possess-User' ); | |||
| $p->SetSlug( slugify( 'Minecraft-Possess-User' ) ); | |||
| $p->Save(); | |||
| } | |||
| if ( User::ONLINE() && Permission::PERMITTED( 'Minecraft-Possess-User' ) ) { | |||
| $me = new MenuEntry( 'Minecraft Payment' ); | |||
| $me->addImageFromResource( 'minecraft.svg', MinecraftPaymentPlugin::get_plugin_name() ); | |||
| $me->setFilter( 'none' ); | |||
| if ( Permission::PERMITTED( 'Minecraft-Pay-Settings' ) ) { | |||
| $sub = new MenuEntry( 'Minecraft Payment', HOME_URL . 'minecraft-pay/settings' ); | |||
| $sub->addImageFromResource( 'settings.svg', Plugin_Plugin::get_plugin_name() ); | |||
| $me->addSubEntry( $sub ); | |||
| } | |||
| $sub = new MenuEntry( [ 'de' => 'Minecraft Benutzer', 'en' => 'Minecraft Users' ], HOME_URL . 'minecraft-pay/users' ); | |||
| $sub->addImageFromResource( 'users.svg', UserManager_Plugin::get_plugin_name() ); | |||
| $me->addSubEntry( $sub ); | |||
| if ( Permission::PERMITTED( 'Minecraft-Pay-Settings' ) ) { | |||
| $sub = new MenuEntry( [ 'de' => 'Gutschrift', 'en' => 'Credit' ], HOME_URL . 'minecraft-pay/acredit' ); | |||
| $sub->addImageFromResource( 'cash.svg', MinecraftPaymentPlugin::get_plugin_name() ); | |||
| $me->addSubEntry( $sub ); | |||
| } | |||
| $sub = new MenuEntry( [ 'de' => 'Transaktionen', 'en' => 'Transactions' ], HOME_URL . 'minecraft-pay/balance' ); | |||
| $sub->addImageFromResource( 'cash.svg', MinecraftPaymentPlugin::get_plugin_name() ); | |||
| $me->addSubEntry( $sub ); | |||
| if ( Permission::PERMITTED( 'Minecraft-Pay-Settings' ) ) { | |||
| $sub = new MenuEntry( [ 'de' => 'Recht gewähren', 'en' => 'Grant right' ], HOME_URL . 'minecraft-pay/grant' ); | |||
| $sub->addImageFromResource( 'key.svg', MinecraftPaymentPlugin::get_plugin_name() ); | |||
| $me->addSubEntry( $sub ); | |||
| }; | |||
| SideMenu::addMainMenuEntry( $me ); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,211 @@ | |||
| <?php | |||
| /** | |||
| * See https://developer.valvesoftware.com/wiki/Source_RCON_Protocol for | |||
| * more information about Source RCON Packets | |||
| * | |||
| * PHP Version 7 | |||
| * | |||
| * @copyright 2013-2017 Chris Churchwell | |||
| * @author thedudeguy | |||
| * @link https://github.com/thedudeguy/PHP-Minecraft-Rcon | |||
| */ | |||
| class Rcon | |||
| { | |||
| private $host; | |||
| private $port; | |||
| private $password; | |||
| private $timeout; | |||
| private $socket; | |||
| private $authorized = false; | |||
| private $lastResponse = ''; | |||
| const PACKET_AUTHORIZE = 5; | |||
| const PACKET_COMMAND = 6; | |||
| const SERVERDATA_AUTH = 3; | |||
| const SERVERDATA_AUTH_RESPONSE = 2; | |||
| const SERVERDATA_EXECCOMMAND = 2; | |||
| const SERVERDATA_RESPONSE_VALUE = 0; | |||
| /** | |||
| * Create a new instance of the Rcon class. | |||
| * | |||
| * @param string $host | |||
| * @param integer $port | |||
| * @param string $password | |||
| * @param integer $timeout | |||
| */ | |||
| public function __construct($host, $port, $password, $timeout) | |||
| { | |||
| $this->host = $host; | |||
| $this->port = $port; | |||
| $this->password = $password; | |||
| $this->timeout = $timeout; | |||
| } | |||
| /** | |||
| * Get the latest response from the server. | |||
| * | |||
| * @return string | |||
| */ | |||
| public function getResponse() | |||
| { | |||
| return $this->lastResponse; | |||
| } | |||
| /** | |||
| * Connect to a server. | |||
| * | |||
| * @return boolean | |||
| */ | |||
| public function connect() | |||
| { | |||
| $this->socket = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout); | |||
| if (!$this->socket) { | |||
| $this->lastResponse = $errstr; | |||
| return false; | |||
| } | |||
| //set timeout | |||
| stream_set_timeout($this->socket, 3, 0); | |||
| // check authorization | |||
| return $this->authorize(); | |||
| } | |||
| /** | |||
| * Disconnect from server. | |||
| * | |||
| * @return void | |||
| */ | |||
| public function disconnect() | |||
| { | |||
| if ($this->socket) { | |||
| fclose($this->socket); | |||
| } | |||
| $this->authorized = false; | |||
| } | |||
| /** | |||
| * True if socket is connected and authorized. | |||
| * | |||
| * @return boolean | |||
| */ | |||
| public function isConnected() | |||
| { | |||
| return $this->authorized; | |||
| } | |||
| /** | |||
| * Send a command to the connected server. | |||
| * | |||
| * @param string $command | |||
| * | |||
| * @return boolean|mixed | |||
| */ | |||
| public function sendCommand($command) | |||
| { | |||
| if (!$this->isConnected()) { | |||
| return false; | |||
| } | |||
| // send command packet | |||
| $this->writePacket(self::PACKET_COMMAND, self::SERVERDATA_EXECCOMMAND, $command); | |||
| // get response | |||
| $response_packet = $this->readPacket(); | |||
| if ($response_packet['id'] == self::PACKET_COMMAND) { | |||
| if ($response_packet['type'] == self::SERVERDATA_RESPONSE_VALUE) { | |||
| $this->lastResponse = $response_packet['body']; | |||
| return $response_packet['body']; | |||
| } | |||
| } | |||
| return false; | |||
| } | |||
| /** | |||
| * Log into the server with the given credentials. | |||
| * | |||
| * @return boolean | |||
| */ | |||
| private function authorize() | |||
| { | |||
| $this->writePacket(self::PACKET_AUTHORIZE, self::SERVERDATA_AUTH, $this->password); | |||
| $response_packet = $this->readPacket(); | |||
| if ($response_packet['type'] == self::SERVERDATA_AUTH_RESPONSE) { | |||
| if ($response_packet['id'] == self::PACKET_AUTHORIZE) { | |||
| $this->authorized = true; | |||
| return true; | |||
| } | |||
| } | |||
| $this->disconnect(); | |||
| return false; | |||
| } | |||
| /** | |||
| * Writes a packet to the socket stream. | |||
| * | |||
| * @param $packetId | |||
| * @param $packetType | |||
| * @param string $packetBody | |||
| * | |||
| * @return void | |||
| */ | |||
| private function writePacket($packetId, $packetType, $packetBody) | |||
| { | |||
| /* | |||
| Size 32-bit little-endian Signed Integer Varies, see below. | |||
| ID 32-bit little-endian Signed Integer Varies, see below. | |||
| Type 32-bit little-endian Signed Integer Varies, see below. | |||
| Body Null-terminated ASCII String Varies, see below. | |||
| Empty String Null-terminated ASCII String 0x00 | |||
| */ | |||
| //create packet | |||
| $packet = pack('VV', $packetId, $packetType); | |||
| $packet = $packet.$packetBody."\x00"; | |||
| $packet = $packet."\x00"; | |||
| // get packet size. | |||
| $packet_size = strlen($packet); | |||
| // attach size to packet. | |||
| $packet = pack('V', $packet_size).$packet; | |||
| // write packet. | |||
| fwrite($this->socket, $packet, strlen($packet)); | |||
| } | |||
| /** | |||
| * Read a packet from the socket stream. | |||
| * | |||
| * @return array | |||
| */ | |||
| private function readPacket() | |||
| { | |||
| //get packet size. | |||
| $size_data = fread($this->socket, 4); | |||
| $size_pack = unpack('V1size', $size_data); | |||
| $size = $size_pack['size']; | |||
| // if size is > 4096, the response will be in multiple packets. | |||
| // this needs to be address. get more info about multi-packet responses | |||
| // from the RCON protocol specification at | |||
| // https://developer.valvesoftware.com/wiki/Source_RCON_Protocol | |||
| // currently, this script does not support multi-packet responses. | |||
| $packet_data = fread($this->socket, $size); | |||
| $packet_pack = unpack('V1id/V1type/a*body', $packet_data); | |||
| return $packet_pack; | |||
| } | |||
| } | |||
| @@ -0,0 +1 @@ | |||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M32 96v256h448V96H32zm160.5 224h-80.4c0-26.6-21.5-48.1-48.1-48.1V192c35.3 0 64-28.7 64-64h64.5c-19.9 23.5-32.5 57.8-32.5 96s12.6 72.5 32.5 96zM448 271.9c-26 0-48 21.5-48 48.1h-80.5c19.9-23.5 32.5-57.8 32.5-96s-12.6-72.5-32.5-96H384c0 35.3 28.7 64 64 64v79.9zM32 384h448v32H32z"/></svg> | |||
| @@ -0,0 +1 @@ | |||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M435.2 80H76.8c-24.9 0-44.6 19.6-44.6 44L32 388c0 24.4 19.9 44 44.8 44h358.4c24.9 0 44.8-19.6 44.8-44V124c0-24.4-19.9-44-44.8-44zm0 308H76.8V256h358.4v132zm0-220H76.8v-44h358.4v44z"/></svg> | |||
| @@ -0,0 +1 @@ | |||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M249.2 224c-14.2-40.2-55.1-72-100.2-72-57.2 0-101 46.8-101 104s45.8 104 103 104c45.1 0 84.1-31.8 98.2-72H352v64h69.1v-64H464v-64H249.2zm-97.6 66.5c-19 0-34.5-15.5-34.5-34.5s15.5-34.5 34.5-34.5 34.5 15.5 34.5 34.5-15.5 34.5-34.5 34.5z"/></svg> | |||
| @@ -0,0 +1 @@ | |||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M376 186h-20v-40c0-55-45-100-100-100S156 91 156 146v40h-20c-22.002 0-40 17.998-40 40v200c0 22.002 17.998 40 40 40h240c22.002 0 40-17.998 40-40V226c0-22.002-17.998-40-40-40zM256 368c-22.002 0-40-17.998-40-40s17.998-40 40-40 40 17.998 40 40-17.998 40-40 40zm62.002-182H193.998v-40c0-34.004 28.003-62.002 62.002-62.002 34.004 0 62.002 27.998 62.002 62.002v40z"/></svg> | |||
| @@ -0,0 +1 @@ | |||
| <svg xmlns="http://www.w3.org/2000/svg" width="480" height="480" viewBox="0 0 48 48"><path fill="#8BC34A" d="M11 7L21 7 20 11 23 11 21 16 25 16 27 11 30 11 31 7 41 7 35 33 3 33z"/><path fill="#263238" d="M40.754,6H40h-9h-0.74l-1.182,5H27.5h-1.299l-0.509,1.854L20.785,6H20h-7.266H11h-0.359h-0.01L2,33l8.908,9h0.229h2.004h7.982l1.523-6.172L23.698,37h2.62l4.104,5H30.6h1.784h8.538L46,17L40.754,6z M31.333,8h8.133l-1.808,8h-3.754l1.086-4.402c0.029-0.146-0.009-0.299-0.104-0.415C34.792,11.067,34.649,11,34.5,11h-3.908L31.333,8z M27.5,11.916V12h6.39l-1.012,4h-6.581l1.087-3.66L27.5,11.916z M18.887,11h-7.715l0.938-3h7.688L18.887,11z M12.334,33.042H4.369L4.328,33H4.297l3.125-10h1.915L7.52,29.362c-0.043,0.151-0.014,0.313,0.081,0.438C7.695,29.927,7.843,30,8,30h5.217L12.334,33.042z M9.52,26h4.858l-0.871,3H8.663L9.52,26z M25.094,33l2.628-11h-2.094h-1.121l-1.352,5H17.4l1.354-5h-3.215l-0.871,3H9.806l0.675-2.362c0.043-0.151,0.014-0.313-0.081-0.438C10.305,22.073,10.157,22,10,22H7.734l3.125-10h7.725H19h2.292l-1.354,5H25h1h11.432l-3.615,16H25.094z"/><path fill="#8D6E63" d="M18.841 40L12.334 33 4.328 33 11.182 40zM38.801 40L33.816 33 25.094 33 30.764 40zM23.036 33L23 33 24.117 28.324 23.084 27 17.484 27 24.071 35.001 24.678 35.001z"/></svg> | |||
| @@ -0,0 +1 @@ | |||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M376 186h-20v-40c0-55-45-100-100-100S156 91 156 146h37.998c0-34.004 28.003-62.002 62.002-62.002 34.004 0 62.002 27.998 62.002 62.002H318v40H136c-22.002 0-40 17.998-40 40v200c0 22.002 17.998 40 40 40h240c22.002 0 40-17.998 40-40V226c0-22.002-17.998-40-40-40zM256 368c-22.002 0-40-17.998-40-40s17.998-40 40-40 40 17.998 40 40-17.998 40-40 40z"/></svg> | |||
| @@ -0,0 +1,37 @@ | |||
| <?php | |||
| /** | |||
| * @Name minecraft_month_paid | |||
| * @Unique Month, Year | |||
| */ | |||
| class MinecraftMonthPaid extends Entity { | |||
| /** | |||
| * @DB-Column | |||
| * @Name ID | |||
| * @Type INT | |||
| * @Primary | |||
| * @AutoIncrement | |||
| * @NotNull | |||
| */ | |||
| public $ID; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Amount | |||
| * @Type DECIMAL(10,2) | |||
| * @NotNull | |||
| */ | |||
| public $Amount; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Month | |||
| * @Type INT(4) | |||
| * @NotNull | |||
| */ | |||
| public $Month; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Year | |||
| * @Type INT | |||
| * @NotNull | |||
| */ | |||
| public $Year; | |||
| } | |||
| @@ -0,0 +1,132 @@ | |||
| <?php | |||
| /** | |||
| * @Name minecraft_server | |||
| * @Unique Name | |||
| * @Unique Domain, Port | |||
| */ | |||
| class MinecraftServer extends Entity { | |||
| /** | |||
| * @DB-Column | |||
| * @Name ID | |||
| * @Type INT | |||
| * @Primary | |||
| * @AutoIncrement | |||
| * @NotNull | |||
| */ | |||
| public $ID; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Name | |||
| * @Type VARCHAR(256) | |||
| * @NotNull | |||
| */ | |||
| public $Name; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Domain | |||
| * @Type VARCHAR(256) | |||
| */ | |||
| public $Domain = null; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Port | |||
| * @Type INT(4) | |||
| */ | |||
| public $Port = null; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Password | |||
| * @Type VARCHAR(256) | |||
| */ | |||
| public $Password = null; | |||
| /** | |||
| * @DB-Column | |||
| * @Name ServerPath | |||
| * @Type VARCHAR(256) | |||
| */ | |||
| public $ServerPath = null; | |||
| /** | |||
| * @DB-Column | |||
| * @Name PerMonthPrice | |||
| * @Type INT(4) | |||
| */ | |||
| public $PerMonthPrice = null; | |||
| /** | |||
| * @DB-Column | |||
| * @Name MaxPerMonthPrice | |||
| * @Type INT(4) | |||
| */ | |||
| public $MaxPerMonthPrice = null; | |||
| /** | |||
| * @DB-Relation | |||
| * @Field ID | |||
| * @FieldName SubscriptionID | |||
| * @OneToMany | |||
| * @OnUpdate CASCADE | |||
| * @OnDelete CASCADE | |||
| * @var MinecraftServer[] | |||
| */ | |||
| public $Subscriptions; | |||
| public function IsUnlocked( MinecraftUser $user ): bool { | |||
| return in_array( strtolower( $user->GetUsername() ), $this->GetWhitelistedNames() ); | |||
| } | |||
| private $RCon = null; | |||
| private function GetRCon() { | |||
| if ( $this->RCon == null ) $this->RCon = new Rcon( $this->GetDomain(), $this->GetPort(), $this->GetPassword(), 1500 ); | |||
| return $this->RCon; | |||
| } | |||
| public function Unlock( MinecraftUser $user, bool $keepOpen = false ): bool { | |||
| $rcon = $this->GetRCon(); | |||
| if ( !$rcon->isConnected() ) $rcon->connect(); | |||
| $rcon->sendCommand( 'whitelist add ' . $user->GetUsername() ); | |||
| $res = $rcon->getResponse(); | |||
| if ( !$keepOpen ) $rcon->disconnect(); | |||
| return $this->IsUnlocked( $user ); | |||
| } | |||
| public function Lock( MinecraftUser $user, bool $keepOpen = false ): bool { | |||
| $rcon = $this->GetRCon(); | |||
| if ( !$rcon->isConnected() ) $rcon->connect(); | |||
| $rcon->sendCommand( 'whitelist remove ' . $user->GetUsername() ); | |||
| $res = $rcon->getResponse(); | |||
| if ( !$keepOpen ) $rcon->disconnect(); | |||
| return !$this->IsUnlocked( $user ); | |||
| } | |||
| public function GetWhitelistedNames( bool $keepOpen = false ) { | |||
| // There are 1 whitelisted players: DragonSkills99 | |||
| $rcon = $this->GetRCon(); | |||
| if ( !$rcon->isConnected() ) $rcon->connect(); | |||
| $rcon->sendCommand( 'whitelist list' ); | |||
| $res = $rcon->getResponse(); | |||
| if ( !$keepOpen ) $rcon->disconnect(); | |||
| if ( nocase_compare( 'There are no whitelisted players', trim( $res ) ) ) return []; | |||
| preg_match( '/^There are [0-9]+ whitelisted players: (.*)/', trim( $res ), $m ); | |||
| if ( !isset( $m[ 1 ] ) ) return []; | |||
| $players = explode( ', ', strtolower( $m[ 1 ] ) ); | |||
| if ( trim( $players[ 0 ] ) == '' ) return []; | |||
| else return $players; | |||
| } | |||
| public function ClearWhitelist( int $tries = 3 ) { | |||
| $rcon = $this->GetRCon(); | |||
| $players = $this->GetWhitelistedNames( true ); | |||
| if ( !count( $players ) ) { $rcon->disconnect(); return true; } | |||
| foreach( $players as $player ) { | |||
| $rcon->sendCommand( "whitelist remove $player" ); | |||
| } | |||
| $nplayers = $this->GetWhitelistedNames( true ); | |||
| if ( count( $nplayers ) ) { | |||
| if ( $tries > 0 ) $this->ClearWhitelist( $tries - 1 ); | |||
| else { $rcon->disconnect(); return false; } | |||
| } | |||
| $rcon->disconnect(); | |||
| return true; | |||
| } | |||
| } | |||
| @@ -0,0 +1,43 @@ | |||
| <?php | |||
| /** | |||
| * @Name minecraft_server_subscription | |||
| */ | |||
| class MinecraftServerSubscription extends Entity { | |||
| /** | |||
| * @DB-Column | |||
| * @Name ID | |||
| * @Type INT | |||
| * @Primary | |||
| * @AutoIncrement | |||
| * @NotNull | |||
| */ | |||
| public $ID; | |||
| /** | |||
| * @DB-Relation | |||
| * @Field ID | |||
| * @FieldName ConcerningServerID | |||
| * @ManyToOne | |||
| * @OnUpdate CASCADE | |||
| * @OnDelete CASCADE | |||
| * @var MinecraftServer | |||
| */ | |||
| public $ConcerningServer; | |||
| /** | |||
| * @DB-Relation | |||
| * @Field ID | |||
| * @FieldName UnlockedUserID | |||
| * @ManyToOne | |||
| * @OnUpdate CASCADE | |||
| * @OnDelete CASCADE | |||
| * @var MinecraftUser | |||
| */ | |||
| public $UnlockedUser; | |||
| /** | |||
| * @DB-Column | |||
| * @Name SubscriptionDate | |||
| * @Default CURRENT_TIMESTAMP | |||
| * @Type TIMESTAMP | |||
| * @NotNull | |||
| */ | |||
| public $SubscriptionDate; | |||
| } | |||
| @@ -0,0 +1,53 @@ | |||
| <?php | |||
| /** | |||
| * @Name minecraft_user | |||
| * @Unique Username | |||
| */ | |||
| class MinecraftUser extends Entity { | |||
| /** | |||
| * @DB-Column | |||
| * @Name ID | |||
| * @Type INT | |||
| * @Primary | |||
| * @AutoIncrement | |||
| * @NotNull | |||
| */ | |||
| public $ID; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Username | |||
| * @Type VARCHAR(256) | |||
| * @NotNull | |||
| * @Pattern /^[a-zA-Z0-9_]{3,16}$/ | |||
| * @Pattern-Missmatch-Comment [ 'de' => 'Der Benutzername ist nur 3-16 Zeichen lang und enthält a-z, A-Z, 0-9, _', 'en' => 'The Username is only 3-16 chars long and contains only a-z, A-Z, 0-9, _' ] | |||
| */ | |||
| public $Username; | |||
| /** | |||
| * @DB-Relation | |||
| * @Field ID | |||
| * @FieldName SubscriptionID | |||
| * @OneToMany | |||
| * @OnUpdate CASCADE | |||
| * @OnDelete CASCADE | |||
| * @var MinecraftServer[] | |||
| */ | |||
| public $Subscriptions; | |||
| /** | |||
| * @DB-Relation | |||
| * @Field ID | |||
| * @FieldName OwnerID | |||
| * @ManyToOne | |||
| * @OnUpdate CASCADE | |||
| * @OnDelete CASCADE | |||
| * @var User | |||
| */ | |||
| public $Owner; | |||
| public function HasSubscripted( MinecraftServer $server ) { | |||
| $f = date( 'Y-m-01' ); $l = date( 'Y-m-t' ); | |||
| $uid = $this->GetID(); | |||
| $sid = $server->GetID(); | |||
| $earlier = MinecraftServerSubscription::GetAll( "SubscriptionDate BETWEEN '$f' AND '$l' AND UnlockedUserID = $uid AND ConcerningServerID = $sid" ); | |||
| return !!count( $earlier ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,51 @@ | |||
| <?php | |||
| /** | |||
| * @Name minecraft_user_account | |||
| */ | |||
| class MinecraftUserAccount extends Entity { | |||
| /** | |||
| * @DB-Column | |||
| * @Name ID | |||
| * @Type INT | |||
| * @Primary | |||
| * @AutoIncrement | |||
| * @NotNull | |||
| */ | |||
| public $ID; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Modifier | |||
| * @Type DECIMAL(10,2) | |||
| * @NotNull | |||
| */ | |||
| public $Mod; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Comment | |||
| * @Type TEXT | |||
| */ | |||
| public $Comment; | |||
| /** | |||
| * @DB-Relation | |||
| * @Field ID | |||
| * @FieldName DebtorID | |||
| * @ManyToOne | |||
| * @OnUpdate CASCADE | |||
| * @OnDelete CASCADE | |||
| * @var User | |||
| */ | |||
| public $Debtor; | |||
| /** | |||
| * @DB-Column | |||
| * @Name Occurence | |||
| * @Type TIMESTAMP | |||
| * @Default CURRENT_TIMESTAMP | |||
| * @NotNull | |||
| */ | |||
| public $Occurence; | |||
| public static function ACCOUNT() { | |||
| if ( User::ONLINE() ) return defaulted( MinecraftUserAccount::SUM( 'Modifier', [ 'DebtorID' => User::CURRENT()->ID ] ), '0' ); | |||
| return '0'; | |||
| } | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| <meta log-in /> | |||
| <div style="width: 100%; text-align: right; border: 1px solid white; border-radius: 1rem; padding: 1rem; margin: 1rem 0; box-sizing: border-box;"> | |||
| <span>Account: <a eval-innerText="MinecraftUserAccount::ACCOUNT() . ' €'"></a></span> | |||
| </div> | |||
| @@ -0,0 +1,20 @@ | |||
| <meta log-in permission="Minecraft-Possess-User" /> | |||
| <div dyn-if="isset( $save_message )"> | |||
| <div dyn-type="alert" eval-value="$save_message" eval-type="$save_success ? ALERT_SUCCESS : ALERT_DANGER"></div> | |||
| </div> | |||
| <table class="table"> | |||
| <thead> | |||
| <tr> | |||
| <th eval-innerText="__( [ 'de' => 'Datum', 'en' => 'Date' ] )"></th> | |||
| <th style="width: 100%;" eval-innerText="__( [ 'de' => 'Kommentar', 'en' => 'Comment' ] )"></th> | |||
| <th eval-innerText="__( [ 'de' => 'Menge', 'en' => 'Amount' ] )"></th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr dyn-for="[ 'credit', 'MinecraftUserAccount::GetAll( [ \'DebtorID\' => User::CURRENT()->ID ] )' ]"> | |||
| <td eval-innerText="$credit->GetOccurence()"></td> | |||
| <td eval-innerText="$credit->GetComment()"></td> | |||
| <td style="text-align: right;" eval-innerText="$credit->GetMod() . ' €'"></td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| @@ -0,0 +1,40 @@ | |||
| <meta log-in permission="Minecraft-Pay-Settings" /> | |||
| <div dyn-if="isset( $save_message )"> | |||
| <div dyn-type="alert" eval-value="$save_message" eval-type="$save_success ? ALERT_SUCCESS : ALERT_DANGER"></div> | |||
| </div> | |||
| <form method="POST"> | |||
| <table> | |||
| <thead> | |||
| <tr> | |||
| <th innerText="Minecraft Payment" colspan="2"></th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Benutzer', 'en' => 'User' ])"></th> | |||
| <td> | |||
| <select name="DebtorID"> | |||
| <div dyn-for="[ 'user', 'User::GetAll()' ]"><option eval-value="$user->GetID()" eval-innerText="$user->GetUsername()"></option></div> | |||
| </select> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Menge', 'en' => 'Amount' ])"></th> | |||
| <td> | |||
| <input type="number" step="0.01" name="Mod" value="0.00" /> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Kommentar', 'en' => 'Comment' ])"></th> | |||
| <td> | |||
| <input type="string" name="Comment" /> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <td colspan="2"> | |||
| <input type="submit" name="AddAccountChange" eval-value="__([ 'de' => 'Gutschreiben', 'en' => 'Credit' ])" /> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </form> | |||
| @@ -0,0 +1,28 @@ | |||
| <meta log-in permission="Minecraft-Pay-Settings" /> | |||
| <div dyn-if="isset( $save_message )"> | |||
| <div dyn-type="alert" eval-value="$save_message" eval-type="$save_success ? ALERT_SUCCESS : ALERT_DANGER"></div> | |||
| </div> | |||
| <form method="POST"> | |||
| <table> | |||
| <thead> | |||
| <tr> | |||
| <th innerText="Minecraft Payment" colspan="2"></th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Benutzer', 'en' => 'User' ])"></th> | |||
| <td> | |||
| <select name="ID"> | |||
| <div dyn-for="[ 'user', 'User::GetAll()' ]"><option eval-value="$user->GetID()" eval-innerText="$user->GetUsername()"></option></div> | |||
| </select> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <td colspan="2"> | |||
| <input type="submit" name="GrantUserRights" eval-value="__([ 'de' => 'Als Minecraft Nutzer eintragte', 'en' => 'Enter as Minecraft User' ])" /> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </form> | |||
| @@ -0,0 +1,56 @@ | |||
| <meta log-in permission="Minecraft-Pay-Settings" /> | |||
| <div dyn-if="isset( $save_message )"> | |||
| <div dyn-type="alert" eval-value="$save_message" eval-type="$save_success ? ALERT_SUCCESS : ALERT_DANGER"></div> | |||
| </div> | |||
| <form method="POST"> | |||
| <table> | |||
| <thead> | |||
| <tr> | |||
| <th eval-innerText="'Minecraft Payment ' . __([ 'de' => 'Einstellungen', 'en' => 'Settings' ])" colspan="2"></th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Domäne', 'en' => 'Domain' ])"></th> | |||
| <td> | |||
| <input type="text" name="Domain" eval-value="$settings->GetDomain()" /> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Port', 'en' => 'Port' ])"></th> | |||
| <td> | |||
| <input type="number" name="Port" eval-value="$settings->GetPort()" /> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Passwort', 'en' => 'Password' ])"></th> | |||
| <td> | |||
| <input type="password" name="Password" eval-value="$settings->GetPassword()" /> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Server-Pfad', 'en' => 'Server-Path' ])"></th> | |||
| <td> | |||
| <input type="text" name="ServerPath" eval-value="$settings->GetServerPath()" /> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Preis/Monat', 'en' => 'Price/Month' ])"></th> | |||
| <td> | |||
| <input type="number" name="PerMonthPrice" eval-value="$settings->GetPerMonthPrice()" /> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <th eval-innerText="__([ 'de' => 'Preis/Monat (Limit)', 'en' => 'Price/Month (Limit)' ])"></th> | |||
| <td> | |||
| <input type="number" name="MaxPerMonthPrice" eval-value="$settings->GetMaxPerMonthPrice()" /> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <td colspan="2"> | |||
| <input type="submit" name="SaveServerSettings" eval-value="__([ 'de' => 'Speichern', 'en' => 'Save' ])" /> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </form> | |||
| @@ -0,0 +1,42 @@ | |||
| <meta log-in permission="Minecraft-Pay-Settings" /> | |||
| <div dyn-if="isset( $save_message )"> | |||
| <div dyn-type="alert" eval-value="$save_message" eval-type="$save_success ? ALERT_SUCCESS : ALERT_DANGER"></div> | |||
| </div> | |||
| <form method="POST"> | |||
| <table class="table"> | |||
| <tbody> | |||
| <tr> | |||
| <td><input type="text" name="Name" /></td> | |||
| <td><input type="submit" name="CreateServer" eval-value="__( [ 'de' => 'Server anlegen', 'en' => 'Create server' ] )" /></td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </form> | |||
| <hr /> | |||
| <table class="table"> | |||
| <thead> | |||
| <tr> | |||
| <th style="width: 100%;">Name</th> | |||
| <th colspan="2"></th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr dyn-for="[ 'server', 'MinecraftServer::GetAll()' ]"> | |||
| <td eval-innerText="$server->GetName()"></td> | |||
| <td> | |||
| <a style="cursor: pointer;" eval-href="HOME_URL . 'minecraft-pay/settings/' . $server->GetID()"> | |||
| <input style="cursor: pointer;" type="button" eval-value="__( [ 'de' => 'Bearbeiten', 'en' => 'Edit' ] )" /> | |||
| </a> | |||
| </td> | |||
| <td> | |||
| <form method="POST"> | |||
| <input type="hidden" name="ID" eval-value="$server->GetID()" /> | |||
| <input type="submit" name="DeleteServer" eval-value="__( [ 'de' => 'Löschen', 'en' => 'Delete' ] )" /> | |||
| </form> | |||
| <a eval-href=""> | |||
| </a> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| @@ -0,0 +1,38 @@ | |||
| <meta log-in permission="Minecraft-Possess-User" /> | |||
| <div dyn-if="isset( $save_message )"> | |||
| <div dyn-type="alert" eval-value="$save_message" eval-type="$save_success ? ALERT_SUCCESS : ALERT_DANGER"></div> | |||
| </div> | |||
| <form method="POST"> | |||
| <table class="table"> | |||
| <thead> | |||
| <tr> | |||
| <th eval-innerText="$user->GetUsername()" colspan="2"></th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr> | |||
| <th colspan="2" eval-innerText="__([ 'de' => 'Server', 'en' => 'Server' ])"></th> | |||
| </tr> | |||
| <tr> | |||
| <td colspan="2"> | |||
| <table class="table"> | |||
| <tbody> | |||
| <tr dyn-for="[ 'server', 'MinecraftServer::GetAll()' ]"> | |||
| <td style="vertical-align: middle; width: 100%" dyn-set="[ 'isUnlocked' => '$server->IsUnlocked( $user )' ]" eval-innerText="$server->GetName()"></td> | |||
| <td> | |||
| <form method="POST"> | |||
| <input type="hidden" name="ID" eval-value="$server->GetID()" /> | |||
| <input type="submit" dyn-if="!$isUnlocked" eval-name="( isset( $_POST[ 'UnlockUser' ] ) && $_POST[ 'ID' ] == $server->GetID() ) ? 'RUnlockUser' : 'UnlockUser'" | |||
| eval-style="( isset( $_POST[ 'UnlockUser' ] ) && $_POST[ 'ID' ] == $server->GetID() ) ? 'background-color: red' : ''" | |||
| eval-value="__( [ 'de' => 'Freischalten', 'en' => 'Unlock' ] ) . ' ~' . $server->GetPerMonthPrice() . ' €'" /> | |||
| </form> | |||
| </td> | |||
| <td><img style="height: 1em; filter: invert( 1 ); vertical-align: middle;" eval-src="HOME_URL . 'imgs/' . MinecraftPaymentPlugin::get_plugin_name() . '/' . ($isUnlocked ? 'unlock.svg' : 'lock.svg')" /></td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </form> | |||
| @@ -0,0 +1,42 @@ | |||
| <meta log-in permission="Minecraft-Possess-User" /> | |||
| <div dyn-if="isset( $save_message )"> | |||
| <div dyn-type="alert" eval-value="$save_message" eval-type="$save_success ? ALERT_SUCCESS : ALERT_DANGER"></div> | |||
| </div> | |||
| <form method="POST"> | |||
| <table class="table"> | |||
| <tbody> | |||
| <tr> | |||
| <td><input type="text" name="Username" eval-placeholder="__( [ 'de' => 'Benutzername', 'en' => 'Username' ] )" /></td> | |||
| <td><input type="submit" name="CreateMinecraftUser" eval-value="__( [ 'de' => 'Minecraft Benutzer hinzufügen', 'en' => 'Add Minecraft User' ] )" /></td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </form> | |||
| <hr /> | |||
| <table class="table"> | |||
| <thead> | |||
| <tr> | |||
| <th style="width: 100%;">Name</th> | |||
| <th colspan="2"></th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr dyn-for="[ 'user', 'MinecraftUser::GetAll( [ \'OwnerID\' => User::CURRENT()->GetID() ] )' ]"> | |||
| <td eval-innerText="$user->GetUsername()"></td> | |||
| <td> | |||
| <a style="cursor: pointer;" eval-href="HOME_URL . 'minecraft-pay/users/' . $user->GetID()"> | |||
| <input style="cursor: pointer;" type="button" eval-value="__( [ 'de' => 'Bearbeiten', 'en' => 'Edit' ] )" /> | |||
| </a> | |||
| </td> | |||
| <td> | |||
| <form method="POST"> | |||
| <input type="hidden" name="ID" eval-value="$user->GetID()" /> | |||
| <input type="submit" name="DeleteMinecraftUser" eval-value="__( [ 'de' => 'Löschen', 'en' => 'Delete' ] )" /> | |||
| </form> | |||
| <a eval-href=""> | |||
| </a> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||