2022-04-16 18:42:24 +02:00
< ? php
/**
* MinecraftIntegration class
*
* @ package Modules\Core\Integrations
* @ author Partydragen
2022-10-19 14:14:53 +02:00
* @ version 2.1 . 0
2022-04-16 18:42:24 +02:00
* @ license MIT
*/
class MinecraftIntegration extends IntegrationBase {
protected Language $_language ;
private string $_uuid ;
public function __construct ( Language $language ) {
$this -> _name = 'Minecraft' ;
$this -> _icon = 'fas fa-cubes' ;
$this -> _language = $language ;
2022-10-19 14:14:53 +02:00
$this -> _settings = ROOT_PATH . '/modules/Core/includes/admin_integrations/minecraft.php' ;
2022-04-16 18:42:24 +02:00
parent :: __construct ();
}
2022-07-17 17:41:41 +02:00
private function flashVerifyCommand ( string $verification_code ) : void {
2023-06-12 10:30:49 -06:00
$verification_command = Output :: getClean ( Settings :: get ( 'minecraft_verify_command' , '/verify' ));
2022-06-22 04:41:34 +00:00
$message = $this -> _language -> get ( 'user' , 'validate_account_command' , [ 'command' => $verification_command . ' ' . $verification_code ]);
Session :: flash ( 'connections_success' , $message );
}
2022-04-16 18:42:24 +02:00
public function onLinkRequest ( User $user ) {
$username = $user -> data () -> username ;
// Validate username
if ( ! $this -> validateUsername ( $username )) {
return ;
}
$result = $this -> getUuidByUsername ( $username );
if ( count ( $this -> getErrors ())) {
return ;
}
$this -> _uuid = $result [ 'uuid' ];
// Validate identifier
if ( ! $this -> validateIdentifier ( $this -> _uuid )) {
return ;
}
2022-06-01 22:15:07 +02:00
$code = SecureRandom :: alphanumeric ();
2022-04-16 18:42:24 +02:00
$integrationUser = new IntegrationUser ( $this );
$integrationUser -> linkIntegration ( $user , $this -> _uuid , $username , false , $code );
2022-06-22 04:41:34 +00:00
$this -> flashVerifyCommand ( $code );
2022-04-16 18:42:24 +02:00
}
public function onVerifyRequest ( User $user ) {
$integrationUser = new IntegrationUser ( $this , $user -> data () -> id , 'user_id' );
2023-01-14 00:59:14 +01:00
$code = $integrationUser -> data () -> code ;
if ( $code === null ) {
$code = SecureRandom :: alphanumeric ();
$integrationUser -> update ([
2023-01-26 14:08:11 -08:00
'code' => $code
2023-01-14 00:59:14 +01:00
]);
}
$this -> flashVerifyCommand ( $code );
2022-04-16 18:42:24 +02:00
}
public function onUnlinkRequest ( User $user ) {
$integrationUser = new IntegrationUser ( $this , $user -> data () -> id , 'user_id' );
$integrationUser -> unlinkIntegration ();
2022-04-23 06:27:10 -07:00
Session :: flash ( 'connections_success' , $this -> _language -> get ( 'user' , 'integration_unlinked' , [ 'integration' => Output :: getClean ( $this -> _name )]));
2022-04-16 18:42:24 +02:00
}
public function onSuccessfulVerification ( IntegrationUser $integrationUser ) {
// Nothing to do here
}
public function validateUsername ( string $username , int $integration_user_id = 0 ) : bool {
$validation = Validate :: check ([ 'username' => $username ], [
'username' => [
Validate :: REQUIRED => true ,
Validate :: MIN => 3 ,
Validate :: MAX => 20
]
]) -> messages ([
'username' => [
2022-04-23 06:27:10 -07:00
Validate :: REQUIRED => $this -> _language -> get ( 'admin' , 'integration_username_required' , [ 'integration' => $this -> getName ()]),
2022-04-16 18:42:24 +02:00
Validate :: MIN => $this -> _language -> get ( 'user' , 'mcname_minimum_3' ),
Validate :: MAX => $this -> _language -> get ( 'user' , 'mcname_maximum_20' )
]
]);
if ( count ( $validation -> errors ())) {
// Validation errors
foreach ( $validation -> errors () as $error ) {
$this -> addError ( $error );
}
} else {
// Ensure identifier doesn't already exist
2022-05-01 23:16:22 -07:00
$exists = DB :: getInstance () -> query ( " SELECT * FROM nl2_users_integrations WHERE integration_id = ? AND username = ? AND id <> ? " , [ $this -> data () -> id , $username , $integration_user_id ]);
2022-04-16 18:42:24 +02:00
if ( $exists -> count ()) {
2022-04-23 06:27:10 -07:00
$this -> addError ( $this -> _language -> get ( 'user' , 'integration_username_already_linked' , [ 'integration' => $this -> getName ()]));
2022-04-16 18:42:24 +02:00
return false ;
}
}
return $validation -> passed ();
}
public function validateIdentifier ( string $identifier , int $integration_user_id = 0 ) : bool {
$validation = Validate :: check ([ 'identifier' => $identifier ], [
'identifier' => [
Validate :: REQUIRED => true ,
Validate :: MIN => 32 ,
Validate :: MAX => 32
]
]) -> messages ([
'identifier' => [
2022-04-23 06:27:10 -07:00
Validate :: REQUIRED => $this -> _language -> get ( 'admin' , 'integration_identifier_required' , [ 'integration' => $this -> getName ()]),
Validate :: MIN => $this -> _language -> get ( 'admin' , 'integration_identifier_invalid' , [ 'integration' => $this -> getName ()]),
Validate :: MAX => $this -> _language -> get ( 'admin' , 'integration_identifier_invalid' , [ 'integration' => $this -> getName ()]),
2022-04-16 18:42:24 +02:00
]
]);
if ( count ( $validation -> errors ())) {
// Validation errors
foreach ( $validation -> errors () as $error ) {
$this -> addError ( $error );
}
} else {
// Ensure identifier doesn't already exist
2022-05-01 23:16:22 -07:00
$exists = DB :: getInstance () -> query ( " SELECT * FROM nl2_users_integrations WHERE integration_id = ? AND identifier = ? AND id <> ? " , [ $this -> data () -> id , $identifier , $integration_user_id ]);
2022-04-16 18:42:24 +02:00
if ( $exists -> count ()) {
2022-04-23 06:27:10 -07:00
$this -> addError ( $this -> _language -> get ( 'user' , 'integration_identifier_already_linked' , [ 'integration' => $this -> getName ()]));
2022-04-16 18:42:24 +02:00
return false ;
}
}
return $validation -> passed ();
}
public function onRegistrationPageLoad ( Fields $fields ) {
2023-06-12 10:30:49 -06:00
if ( Settings :: get ( 'mc_username_registration' , '1' , 'Minecraft Integration' ) != '1' ) {
2022-10-19 14:14:53 +02:00
return ;
}
2022-04-16 18:42:24 +02:00
$username_value = (( isset ( $_POST [ 'username' ]) && $_POST [ 'username' ]) ? Output :: getClean ( Input :: get ( 'username' )) : '' );
$fields -> add ( 'username' , Fields :: TEXT , $this -> _language -> get ( 'user' , 'minecraft_username' ), true , $username_value , null , null , 1 );
}
public function beforeRegistrationValidation ( Validate $validate ) {
// Nothing to do here
}
public function afterRegistrationValidation () {
2023-06-12 10:30:49 -06:00
if ( Settings :: get ( 'mc_username_registration' , '1' , 'Minecraft Integration' ) != '1' ) {
2022-10-19 14:14:53 +02:00
return ;
}
2022-04-16 18:42:24 +02:00
$username = Input :: get ( 'username' );
// Validate username
if ( ! $this -> validateUsername ( $username )) {
return ;
}
// Get minecraft UUID
$result = $this -> getUuidByUsername ( $username );
if ( count ( $this -> getErrors ())) {
return ;
}
$this -> _uuid = $result [ 'uuid' ];
// Validate identifier
if ( ! $this -> validateIdentifier ( $this -> _uuid )) {
return ;
}
}
public function successfulRegistration ( User $user ) {
2023-06-12 10:30:49 -06:00
if ( Settings :: get ( 'mc_username_registration' , '1' , 'Minecraft Integration' ) != '1' ) {
2022-10-19 14:14:53 +02:00
return ;
}
2023-01-26 14:08:11 -08:00
2022-06-01 22:15:07 +02:00
$code = SecureRandom :: alphanumeric ();
2022-04-16 18:42:24 +02:00
$integrationUser = new IntegrationUser ( $this );
$integrationUser -> linkIntegration ( $user , $this -> _uuid , Input :: get ( 'username' ), false , $code );
}
public function syncIntegrationUser ( IntegrationUser $integration_user ) : bool {
$profile = ProfileUtils :: getProfile ( $integration_user -> data () -> identifier );
if ( $profile ) {
$result = $profile -> getUsername ();
if ( ! empty ( $result )) {
$integration_user -> update ([
'username' => $result ,
'last_sync' => date ( 'U' )
]);
return true ;
}
}
return false ;
}
/**
* Get minecraft UUID by username
*
* @ param string $username
* @ return array
*/
public function getUuidByUsername ( string $username ) : array {
2023-06-12 10:30:49 -06:00
if ( Settings :: get ( 'uuid_linking' )) {
2022-04-16 18:42:24 +02:00
return $this -> getOnlineModeUuid ( $username );
}
2023-01-26 14:08:11 -08:00
return ProfileUtils :: getOfflineModeUuid ( $username );
2022-04-16 18:42:24 +02:00
}
/**
* Query mojang api to get online - mode UUID .
*
* @ param string $username
* @ return array
*/
public function getOnlineModeUuid ( string $username ) : array {
$profile = ProfileUtils :: getProfile ( str_replace ( ' ' , '%20' , $username ));
$mcname_result = $profile ? $profile -> getProfileAsArray () : [];
if ( isset ( $mcname_result [ 'username' ], $mcname_result [ 'uuid' ]) && ! empty ( $mcname_result [ 'username' ]) && ! empty ( $mcname_result [ 'uuid' ])) {
// Valid
2023-01-26 14:08:11 -08:00
return [
2022-04-16 18:42:24 +02:00
'uuid' => $mcname_result [ 'uuid' ],
'username' => $mcname_result [ 'username' ]
];
}
2023-01-26 14:08:11 -08:00
// Invalid
$this -> addError ( $this -> _language -> get ( 'user' , 'invalid_mcname' ));
2022-04-16 18:42:24 +02:00
return [];
}
}