-
Posts
95 -
Joined
-
Last visited
Everything posted by Dretax
-
I would like to make the player hold his hand If It was holding an item. What do I need to do for this inorder to achieve that? Use the boneattach resource somehow, or animations? (I need to make the player to be able to move while also holding his hands)
-
Possibly. Any idea how would I reproduce the same thing, if i could in lua? Or how would i do the webrequests for that? Would those be fast enough at all?
-
https://github.com/Contex/XenAPI/wiki/REST-API-Actions This seems to work. Request: api.php?action=authenticate&username=USERNAME&password=PASSWORD Example: api.php?action=authenticate&username=Contex&password=MyPassword Response: { "hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" } You think you can figure the way it generates the hash? It gives nothing back if it fails. {"error":5,"message":"Authentication error: Invalid username or password!"} https://github.com/Contex/XenAPI/blob/master/net/xenapi/XenAPI/api.php As far as I can tell It somehow deserializes the data line from the record? No idea how would that look in lua lmao. Guess i could do webrequests and use this API at login?
-
Uhh. No idea, this is in the registration php. <?php /** * Controller for registration-related actions. * * @package XenForo_Users */ class XenForo_ControllerPublic_Register extends XenForo_ControllerPublic_Abstract { protected function _preDispatch($action) { // prevent discouraged IP addresses from registering if (XenForo_Application::get('options')->preventDiscouragedRegistration && $this->_isDiscouraged()) { throw $this->responseException($this->responseError( new XenForo_Phrase('new_registrations_currently_not_being_accepted') )); } } /** * Displays a form to register a new user. * * @return XenForo_ControllerResponse_Abstract */ public function actionIndex() { if (XenForo_Visitor::getUserId()) { throw $this->responseException( $this->responseRedirect( XenForo_ControllerResponse_Redirect::RESOURCE_CANONICAL, $this->getDynamicRedirect() ) ); } $this->_assertRegistrationActive(); $username = ''; $email = ''; if ($login = $this->_input->filterSingle('login', XenForo_Input::STRING)) { if (XenForo_Helper_Email::isEmailValid($login)) { $email = $login; } else { $username = $login; } } $fields = array( 'username' => $username, 'email' => $email ); $writer = XenForo_DataWriter::create('XenForo_DataWriter_User'); if ($username !== '') { $writer->set('username', $username); } if ($email !== '') { $writer->set('email', $email); } return $this->_getRegisterFormResponse($fields, $writer->getErrors()); } protected function _getRegisterFormResponse(array $fields, array $errors = array()) { $options = XenForo_Application::get('options'); if (empty($fields['timezone'])) { $fields['timezone'] = $options->guestTimeZone; $fields['timezoneAuto'] = true; } if (!empty($fields['custom_fields']) && is_array($fields['custom_fields'])) { $customFieldValues = $fields['custom_fields']; } else { $customFieldValues = array(); } XenForo_Application::getSession()->set('registrationTime', time()); $regKey = md5(uniqid('xf', true)); XenForo_Application::getSession()->set('registrationKey', $regKey); $customFields = $this->_getFieldModel()->prepareUserFields( $this->_getFieldModel()->getUserFields(array('registration' => true)), true, $customFieldValues, false ); $viewParams = array( 'fields' => $fields, 'errors' => $errors, 'timeZones' => XenForo_Helper_TimeZone::getTimeZones(), 'dobRequired' => $options->get('registrationSetup', 'requireDob'), 'captcha' => XenForo_Captcha_Abstract::createDefault(), 'tosUrl' => XenForo_Dependencies_Public::getTosUrl(), 'regKey' => $regKey, 'fieldMap' => $this->_getFieldHashMap(), 'customFields' => $customFields, 'customFieldHoneyPot' => $this->_getCustomFieldHoneyPot($customFields) ); return $this->responseView( 'XenForo_ViewPublic_Register_Form', 'register_form', $viewParams, $this->_getRegistrationContainerParams() ); } /** * Validate a single field * * @return XenForo_ControllerResponse_Redirect */ public function actionValidateField() { $this->_assertPostOnly(); $field = $this->_getFieldValidationInputParams(); $inputName = $field['name']; $fieldMap = $this->_getFieldHashMap(); $doValidate = true; foreach ($fieldMap AS $name => $hashedName) { if ($field['name'] == $hashedName) { $field['name'] = $name; $doValidate = $this->_hashableFields[$name]; break; } } $writer = XenForo_DataWriter::create('XenForo_DataWriter_User'); if ($doValidate) { if (preg_match('/^custom_field_([a-zA-Z0-9_]+)$/', $field['name'], $match)) { $writer->setCustomFields(array($match[1] => $field['value'])); } else { $writer->set($field['name'], $field['value']); } } if ($errors = $writer->getErrors()) { foreach ($errors AS $key => $value) { if ($key === $field['name']) { unset($errors[$key]); $errors[$inputName] = $value; } } return $this->responseError($errors); } return $this->responseRedirect( XenForo_ControllerResponse_Redirect::SUCCESS, '', new XenForo_Phrase('redirect_field_validated', array('name' => $inputName, 'value' => $field['value'])) ); } /** * Fields that get hashed names. Key is field, value is true if included in part of * DW data directly. (False otherwise.) * * @var array */ protected $_hashableFields = array( 'username' => true, 'username_hp' => false, 'email' => true, 'email_hp' => false, 'gender' => true, 'timezone' => true, 'password' => false, 'password_hp' => false, 'password_confirm' => false, 'password_confirm_hp' => false, 'custom_fields' => false ); protected function _getFieldHashMap($secretKey = null) { if (!$secretKey) { $session = XenForo_Application::getSession(); $secretKey = hash_hmac('md5', $session->isRegistered('registrationKey') ? $session->get('registrationKey') : XenForo_Application::$time, XenForo_Application::getConfig()->globalSalt ); } $map = array(); foreach ($this->_hashableFields AS $field => $null) { $map[$field] = hash_hmac('md5', $field, $secretKey); } return $map; } protected function _getCustomFieldHoneyPot(array $customFields) { if ($customFields) { $field = reset($customFields); } else { $session = XenForo_Application::getSession(); $key = $session->isRegistered('registrationKey') ? $session->get('registrationKey') : strval(XenForo_Application::$time); $field = array( 'field_id' => substr($key, 0, hexdec($key[0]) + 1), 'title' => new XenForo_Phrase('verification') ); } $field['field_id'] = strtolower(rtrim(strtr(base64_encode($field['field_id']), '+/', '__'), '=')); $field['field_type'] = 'textbox'; $field['field_value'] = ''; $field['required'] = 0; $field['show_registration'] = 1; $field['user_editable'] = 1; $field['display_template'] = ''; $field['isEditable'] = true; $field['showRegistration'] = true; $field['description'] = new XenForo_Phrase('please_leave_this_field_blank'); return $field; } protected function _getRegistrationInputData() { $errors = array(); $fieldMap = $this->_getFieldHashMap(); $data = $this->_input->filter(array( 'username' => XenForo_Input::STRING, 'email' => XenForo_Input::STRING, 'timezone' => XenForo_Input::STRING, 'gender' => XenForo_Input::STRING, 'location' => XenForo_Input::STRING, 'dob_day' => XenForo_Input::UINT, 'dob_month' => XenForo_Input::UINT, 'dob_year' => XenForo_Input::UINT, )); $passwords = array( 'password' => $this->_input->filterSingle($fieldMap['password'], XenForo_Input::STRING), 'password_confirm' => $this->_input->filterSingle($fieldMap['password_confirm'], XenForo_Input::STRING) ); foreach ($fieldMap AS $fieldName => $hashedName) { if ($this->_hashableFields[$fieldName]) { if (strlen($data[$fieldName])) { $errors['field_hash'] = new XenForo_Phrase('some_fields_contained_unexpected_data_try_again'); } $data[$fieldName] = $this->_input->filterSingle($hashedName, XenForo_Input::STRING); } else if (substr($fieldName, -3) == '_hp') { if (strlen($this->_input->filterSingle($hashedName, XenForo_Input::STRING))) { $errors['field_hash'] = new XenForo_Phrase('some_fields_contained_unexpected_data_try_again'); } } } $customFields = $this->_input->filterSingle($fieldMap['custom_fields'], XenForo_Input::ARRAY_SIMPLE); $customFieldsShown = $this->_getFieldModel()->getUserFields(array('registration' => true)); $customFieldHoneyPot = $this->_getCustomFieldHoneyPot($customFieldsShown); if ($customFieldHoneyPot && isset($customFields[$customFieldHoneyPot['field_id']]) && $customFields[$customFieldHoneyPot['field_id']] !== '' ) { $errors['field_hash'] = new XenForo_Phrase('some_fields_contained_unexpected_data_try_again'); } // bit of a hack, but ensures HP password fields don't get logged unset($_POST[$fieldMap['password']], $_POST[$fieldMap['password_confirm']]); return array( 'data' => $data, 'passwords' => $passwords, 'customFields' => $customFields, 'customFieldsShown' => array_keys($customFieldsShown), 'errors' => $errors ); } protected $_regInputData; protected function _getRegistrationInputDataSafe() { if (!$this->_regInputData) { $this->_regInputData = $this->_getRegistrationInputData(); } return $this->_regInputData; } /** * Registers a new user. * * @return XenForo_ControllerResponse_Abstract */ public function actionRegister() { $this->_assertPostOnly(); $this->_assertRegistrationActive(); $inputData = $this->_getRegistrationInputDataSafe(); $data = $inputData['data']; $passwords = $inputData['passwords']; $customFields = $inputData['customFields']; $customFieldsShown = $inputData['customFieldsShown']; $errors = $inputData['errors']; $options = XenForo_Application::getOptions(); if (!XenForo_Captcha_Abstract::validateDefault($this->_input)) { $errors[] = new XenForo_Phrase('did_not_complete_the_captcha_verification_properly'); } if (XenForo_Dependencies_Public::getTosUrl() && !$this->_input->filterSingle('agree', XenForo_Input::UINT)) { $errors[] = new XenForo_Phrase('you_must_agree_to_terms_of_service'); } $writer = XenForo_DataWriter::create('XenForo_DataWriter_User'); if ($options->registrationDefaults) { $writer->bulkSet($options->registrationDefaults, array('ignoreInvalidFields' => true)); } $writer->bulkSet($data); $writer->setPassword($passwords['password'], $passwords['password_confirm'], null, true); // if the email corresponds to an existing Gravatar, use it if ($this->_canApplyAvatar() && $options->gravatarEnable && XenForo_Model_Avatar::gravatarExists($data['email'])) { $writer->set('gravatar', $data['email']); } $writer->set('user_group_id', XenForo_Model_User::$defaultRegisteredGroupId); $writer->set('language_id', XenForo_Visitor::getInstance()->get('language_id')); $writer->setCustomFields($customFields, $customFieldsShown); if (!$this->_validateBirthdayInput($writer, $birthdayError)) { $errors[] = $birthdayError; } $registerTime = XenForo_Application::getSession()->get('registrationTime'); if (!$registerTime || ($registerTime + $options->get('registrationTimer')) > time()) { $errors[] = new XenForo_Phrase('sorry_you_must_wait_longer_to_create_account'); } $regKey = XenForo_Application::getSession()->get('registrationKey'); if (!$regKey || $regKey != $this->_input->filterSingle('reg_key', XenForo_Input::STRING)) { $errors[] = new XenForo_Phrase('something_went_wrong_please_try_again'); } $spamModel = $this->_runSpamCheck($writer, $errors); $writer->advanceRegistrationUserState(); $writer->preSave(); $errors = array_merge($errors, $writer->getErrors()); if ($errors) { $fields = $data; $fields['tos'] = $this->_input->filterSingle('agree', XenForo_Input::UINT); $fields['custom_fields'] = $customFields; return $this->_getRegisterFormResponse($fields, $errors); } $writer->save(); $user = $writer->getMergedData(); $spamModel->logSpamTrigger('user', $user['user_id']); if ($user['user_state'] == 'email_confirm') { $this->_getUserConfirmationModel()->sendEmailConfirmation($user); } return $this->_completeRegistration($user); } protected function _completeRegistration(array $user, array $extraParams = array()) { XenForo_Model_Ip::log($user['user_id'], 'user', $user['user_id'], 'register'); $userModel = $this->_getUserModel(); $userModel->sendWelcomeContact($user); $visitor = XenForo_Visitor::setup($user['user_id']); XenForo_Application::getSession()->userLogin($user['user_id'], $visitor['password_date']); $this->_executePromotionUpdate(true); $this->_executeTrophyUpdate(true); // keep the user logged in for a while - more friendly for new users $userModel->setUserRememberCookie($user['user_id']); $redirect = $this->_input->filterSingle('redirect', XenForo_Input::STRING); $visitor = XenForo_Visitor::getInstance(); $viewParams = $extraParams + array( 'user' => $visitor->toArray(), 'canEditProfile' => $visitor->canEditProfile(), 'redirect' => ($redirect ? XenForo_Link::convertUriToAbsoluteUri($redirect) : '') ); return $this->responseView( 'XenForo_ViewPublic_Register_Process', 'register_process', $viewParams, $this->_getRegistrationContainerParams() ); } /** * Displays a form to join using Facebook or logs in an existing account. * * @return XenForo_ControllerResponse_Abstract */ public function actionFacebook() { $assocUserId = $this->_input->filterSingle('assoc', XenForo_Input::UINT); $redirect = $this->_getExternalAuthRedirect(); $fbRedirectUri = XenForo_Link::buildPublicLink('canonical:register/facebook', false, array( 'assoc' => ($assocUserId ? $assocUserId : false) )); if ($this->_input->filterSingle('reg', XenForo_Input::UINT)) { XenForo_Application::getSession()->set('loginRedirect', $redirect); XenForo_Application::getSession()->remove('fbToken'); return $this->responseRedirect( XenForo_ControllerResponse_Redirect::RESOURCE_CANONICAL, XenForo_Helper_Facebook::getFacebookRequestUrl($fbRedirectUri) ); } $fbToken = $this->_input->filterSingle('t', XenForo_Input::STRING); if (!$fbToken) { $fbToken = XenForo_Application::getSession()->get('fbToken'); } if (!$fbToken) { $error = $this->_input->filterSingle('error', XenForo_Input::STRING); if ($error == 'access_denied') { return $this->responseError(new XenForo_Phrase('you_did_not_grant_permission_to_access_external_account')); } $code = $this->_input->filterSingle('code', XenForo_Input::STRING); if (!$code) { return $this->responseError(new XenForo_Phrase('error_occurred_while_connecting_with_facebook')); } $state = $this->_input->filterSingle('state', XenForo_Input::STRING); $session = XenForo_Application::getSession(); if (!$state || !$session->get('fbCsrfState') || $state !== $session->get('fbCsrfState')) { return $this->responseRedirect( XenForo_ControllerResponse_Redirect::SUCCESS, XenForo_Link::buildPublicLink('canonical:index') ); } $token = XenForo_Helper_Facebook::getAccessTokenFromCode($code, $fbRedirectUri); $fbError = XenForo_Helper_Facebook::getFacebookRequestErrorInfo($token, 'access_token'); if ($fbError) { return $this->responseError(new XenForo_Phrase('error_occurred_while_connecting_with_facebook')); } $fbToken = $token['access_token']; } $fbUser = XenForo_Helper_Facebook::getUserInfo($fbToken); $fbError = XenForo_Helper_Facebook::getFacebookRequestErrorInfo($fbUser, 'id'); if ($fbError) { return $this->responseError(new XenForo_Phrase('error_occurred_while_connecting_with_facebook')); } $userModel = $this->_getUserModel(); $userExternalModel = $this->_getUserExternalModel(); $fbAssoc = $userExternalModel->getExternalAuthAssociation('facebook', $fbUser['id']); if ($fbAssoc && $userModel->getUserById($fbAssoc['user_id'])) { $userExternalModel->updateExternalAuthAssociationExtra( $fbAssoc['user_id'], 'facebook', array('token' => $fbToken) ); $redirect = XenForo_Application::getSession()->get('loginRedirect'); if (!$redirect) { $redirect = $this->getDynamicRedirect(false, false); } XenForo_Helper_Facebook::setUidCookie($fbUser['id']); /** @var XenForo_ControllerHelper_Login $loginHelper */ $loginHelper = $this->getHelper('Login'); $loginHelper->tfaRedirectIfRequiredPublic($fbAssoc['user_id'], $redirect, true); $visitor = XenForo_Visitor::setup($fbAssoc['user_id']); XenForo_Application::getSession()->userLogin($fbAssoc['user_id'], $visitor['password_date']); $this->_getUserModel()->setUserRememberCookie($fbAssoc['user_id']); return $this->responseRedirect( XenForo_ControllerResponse_Redirect::SUCCESS, $redirect ); } XenForo_Helper_Facebook::setUidCookie(0); parent::_assertBoardActive('facebook'); if (empty($fbUser['email'])) { return $this->responseError(new XenForo_Phrase('facebook_did_not_provide_email')); } $existingUser = false; $emailMatch = false; if (XenForo_Visitor::getUserId()) { $existingUser = XenForo_Visitor::getInstance(); } else if ($assocUserId) { $existingUser = $userModel->getUserById($assocUserId); } if (!$existingUser) { $existingUser = $userModel->getUserByEmail($fbUser['email']); $emailMatch = true; } $viewName = 'XenForo_ViewPublic_Register_Facebook'; $templateName = 'register_facebook'; XenForo_Application::getSession()->set('fbToken', $fbToken); if ($existingUser) { // must associate: matching user return $this->_getExternalRegisterFormResponse($viewName, $templateName, array( 'associateOnly' => true, 'fbUser' => $fbUser, 'existingUser' => $existingUser, 'emailMatch' => $emailMatch, 'redirect' => $redirect )); } $this->_assertRegistrationActive(); if (!empty($fbUser['birthday'])) { $this->_validateBirthdayString($fbUser['birthday'], 'm/d/y'); } return $this->_getExternalRegisterFormResponse($viewName, $templateName, array( 'fbUser' => $fbUser, 'redirect' => $redirect, 'showDob' => empty($fbUser['birthday']) )); } /** * Registers a new account (or associates with an existing one) using Facebook. * * @return XenForo_ControllerResponse_Abstract */ public function actionFacebookRegister() { $this->_assertPostOnly(); $fbToken = XenForo_Application::getSession()->get('fbToken'); $fbUser = XenForo_Helper_Facebook::getUserInfo($fbToken); if (empty($fbUser['id'])) { return $this->responseError(new XenForo_Phrase('error_occurred_while_connecting_with_facebook')); } if (empty($fbUser['email'])) { return $this->responseError(new XenForo_Phrase('facebook_did_not_provide_email')); } $userExternalModel = $this->_getUserExternalModel(); $redirect = XenForo_Application::getSession()->get('loginRedirect'); if (!$redirect) { $redirect = $this->getDynamicRedirect(false, false); } $doAssoc = ($this->_input->filterSingle('associate', XenForo_Input::STRING) || $this->_input->filterSingle('force_assoc', XenForo_Input::UINT) ); if ($doAssoc) { $userId = $this->_associateExternalAccount(); $userExternalModel->updateExternalAuthAssociation( 'facebook', $fbUser['id'], $userId, array('token' => $fbToken) ); XenForo_Helper_Facebook::setUidCookie($fbUser['id']); XenForo_Application::getSession()->remove('loginRedirect'); XenForo_Application::getSession()->remove('fbToken'); return $this->responseRedirect( XenForo_ControllerResponse_Redirect::SUCCESS, $redirect ); } $data = $this->_input->filter(array( 'username' => XenForo_Input::STRING, 'timezone' => XenForo_Input::STRING, 'location' => XenForo_Input::STRING, 'dob_day' => XenForo_Input::UINT, 'dob_month' => XenForo_Input::UINT, 'dob_year' => XenForo_Input::UINT )); if (isset($fbUser['gender'])) { switch ($fbUser['gender']) { case 'man': case 'male': $data['gender'] = 'male'; break; case 'woman': case 'female': $data['gender'] = 'female'; break; } } if (!empty($fbUser['birthday'])) { $birthday = $this->_validateBirthdayString($fbUser['birthday'], 'm/d/y'); if ($birthday) { $data['dob_year'] = $birthday[0]; $data['dob_month'] = $birthday[1]; $data['dob_day'] = $birthday[2]; } } if (!empty($fbUser['website'])) { list($website) = preg_split('/\r?\n/', $fbUser['website']); if ($website && Zend_Uri::check($website)) { $data['homepage'] = $website; } } $data['email'] = $fbUser['email']; if (!empty($fbUser['location']['name'])) { $data['location'] = $fbUser['location']['name']; } $writer = $this->_setupExternalUser($data); if (!$this->_validateBirthdayInput($writer, $birthdayError)) { $writer->error($birthdayError); } $spamModel = $this->_runSpamCheck($writer); $writer->advanceRegistrationUserState(false); $writer->save(); $user = $writer->getMergedData(); $spamModel->logSpamTrigger('user', $user['user_id']); if ($this->_canApplyAvatar()) { $avatarData = XenForo_Helper_Facebook::getUserPicture($fbToken); $this->_applyAvatar($user, $avatarData); } $userExternalModel->updateExternalAuthAssociation( 'facebook', $fbUser['id'], $user['user_id'], array('token' => $fbToken) ); XenForo_Helper_Facebook::setUidCookie($fbUser['id']); XenForo_Application::getSession()->remove('loginRedirect'); XenForo_Application::getSession()->remove('fbToken'); return $this->_completeRegistration($user, array('redirect' => $redirect)); } public function actionTwitter() { $assocUserId = $this->_input->filterSingle('assoc', XenForo_Input::UINT); $oauth = XenForo_Helper_Twitter::getOauthConsumer( XenForo_Link::buildPublicLink('canonical:register/twitter', null, array( 'assoc' => ($assocUserId ? $assocUserId : false) )) ); if (!$oauth) { return $this->responseRedirect( XenForo_ControllerResponse_Redirect::RESOURCE_CANONICAL, $this->getDynamicRedirect() ); } $session = XenForo_Application::getSession(); $redirect = $this->_getExternalAuthRedirect(); if ($this->_input->filterSingle('reg', XenForo_Input::UINT)) { XenForo_Application::getSession()->set('loginRedirect', $redirect); try { $requestToken = $oauth->getRequestToken(); } catch (Zend_Oauth_Exception $e) { return $this->responseError(new XenForo_Phrase('unexpected_error_occurred')); } $session->set('twitterRequestToken', serialize($requestToken)); return $this->responseRedirect( XenForo_ControllerResponse_Redirect::RESOURCE_CANONICAL, $oauth->getRedirectUrl() ); } try { $requestToken = @unserialize($session->get('twitterRequestToken')); if ($requestToken) { if ($this->_input->filterSingle('denied', XenForo_Input::STRING)) { return $this->responseError(new XenForo_Phrase('unexpected_error_occurred')); } $accessToken = $oauth->getAccessToken($this->_input->filter(array( 'oauth_token' => XenForo_Input::STRING, 'oauth_verifier' => XenForo_Input::STRING )), $requestToken); } else { $accessToken = @unserialize($session->get('twitterAccessToken')); if (!$accessToken) { return $this->responseError(new XenForo_Phrase('unexpected_error_occurred')); } } } catch (Zend_Service_Twitter_Exception $e) { return $this->responseError(new XenForo_Phrase('unexpected_error_occurred')); } $session->remove('twitterRequestToken'); $session->set('twitterAccessToken', serialize($accessToken)); $credentials = XenForo_Helper_Twitter::getUserFromToken($accessToken); if (!$credentials) { return $this->responseError(new XenForo_Phrase('unexpected_error_occurred')); } $userId = $credentials['id_str']; $userModel = $this->_getUserModel(); $userExternalModel = $this->_getUserExternalModel(); $redirect = XenForo_Application::getSession()->get('loginRedirect'); $twitterAssoc = $userExternalModel->getExternalAuthAssociation('twitter', $userId); if ($twitterAssoc && $userModel->getUserById($twitterAssoc['user_id'])) { $userExternalModel->updateExternalAuthAssociationExtra( $twitterAssoc['user_id'], 'twitter', array( 'token' => $accessToken->getToken(), 'secret' => $accessToken->getTokenSecret() ) ); /** @var XenForo_ControllerHelper_Login $loginHelper */ $loginHelper = $this->getHelper('Login'); $loginHelper->tfaRedirectIfRequiredPublic($twitterAssoc['user_id'], $redirect, true); $visitor = XenForo_Visitor::setup($twitterAssoc['user_id']); XenForo_Application::getSession()->userLogin($twitterAssoc['user_id'], $visitor['password_date']); $this->_getUserModel()->setUserRememberCookie($twitterAssoc['user_id']); return $this->responseRedirect( XenForo_ControllerResponse_Redirect::SUCCESS, $redirect ? $redirect : $this->getDynamicRedirect(false, false) ); } parent::_assertBoardActive('twitter'); $session->set('twitterCredentials', serialize($credentials)); $viewName = 'XenForo_ViewPublic_Register_Twitter'; $templateName = 'register_twitter'; $existingUser = XenForo_Visitor::getUserId() ? XenForo_Visitor::getInstance() : false; if ($existingUser) { // must associate: matching user return $this->_getExternalRegisterFormResponse($viewName, $templateName, array( 'associateOnly' => true, 'existingUser' => $existingUser, 'redirect' => $redirect )); } $this->_assertRegistrationActive(); return $this->_getExternalRegisterFormResponse($viewName, $templateName, array( 'redirect' => $redirect, 'credentials' => $credentials )); } /** * Registers a new account (or associates with an existing one) using Twitter. * * @return XenForo_ControllerResponse_Abstract */ public function actionTwitterRegister() { $this->_assertPostOnly(); $session = XenForo_Application::getSession(); $accessToken = @unserialize($session->get('twitterAccessToken')); $credentials = @unserialize($session->get('twitterCredentials')); if (!$accessToken || !$credentials) { return $this->responseError(new XenForo_Phrase('you_did_not_grant_permission_to_access_external_account')); } $userExternalModel = $this->_getUserExternalModel(); $doAssoc = ($this->_input->filterSingle('associate', XenForo_Input::STRING) || $this->_input->filterSingle('force_assoc', XenForo_Input::UINT) ); $redirect = XenForo_Application::getSession()->get('loginRedirect'); if (!$redirect) { $redirect = $this->getDynamicRedirect(false, false); } if ($doAssoc) { $userId = $this->_associateExternalAccount(); $userExternalModel->updateExternalAuthAssociation( 'twitter', $credentials['id_str'], $userId, array( 'token' => $accessToken->getToken(), 'secret' => $accessToken->getTokenSecret() ) ); return $this->responseRedirect( XenForo_ControllerResponse_Redirect::SUCCESS, $redirect ); } $options = XenForo_Application::getOptions(); $data = $this->_input->filter(array( 'username' => XenForo_Input::STRING, 'email' => XenForo_Input::STRING, 'timezone' => XenForo_Input::STRING, 'location' => XenForo_Input::STRING, 'dob_day' => XenForo_Input::UINT, 'dob_month' => XenForo_Input::UINT, 'dob_year' => XenForo_Input::UINT, )); if (!empty($credentials['location'])) { $data['location'] = $credentials['location']; } if (!empty($credentials['entities']['url']['urls'][0]['expanded_url'])) { $website = $credentials['entities']['url']['urls'][0]['expanded_url']; if (Zend_Uri::check($website)) { $data['homepage'] = $website; } } $writer = $this->_setupExternalUser($data); if (!$this->_validateBirthdayInput($writer, $birthdayError)) { $writer->error($birthdayError); } $spamModel = $this->_runSpamCheck($writer); $writer->advanceRegistrationUserState(); $writer->save(); $user = $writer->getMergedData(); $spamModel->logSpamTrigger('user', $user['user_id']); if (!empty($credentials['profile_image_url']) && $this->_canApplyAvatar()) { try { // get the original size $url = str_replace('_normal', '', $credentials['profile_image_url']); $request = XenForo_Helper_Http::getClient($url)->request(); $avatarData = $request->getBody(); } catch (Exception $e) { $avatarData = ''; } $this->_applyAvatar($user, $avatarData); } $userExternalModel->updateExternalAuthAssociation( 'twitter', $credentials['id_str'], $user['user_id'], array( 'token' => $accessToken->getToken(), 'secret' => $accessToken->getTokenSecret() ) ); if ($user['user_state'] == 'email_confirm') { $this->_getUserConfirmationModel()->sendEmailConfirmation($user); } return $this->_completeRegistration($user); } public function actionGoogle() { $code = $this->_input->filterSingle('code', XenForo_Input::STRING); $options = XenForo_Application::getOptions(); $session = XenForo_Application::getSession(); $redirect = $this->_getExternalAuthRedirect(); if (!$options->googleClientId) { return $this->responseRedirect( XenForo_ControllerResponse_Redirect::RESOURCE_CANONICAL, $this->getDynamicRedirect() ); } $csrf = $this->_input->filterSingle('csrf', XenForo_Input::STRING); if ($csrf !== $session->get('sessionCsrf')) { return $this->responseError(new XenForo_Phrase('unexpected_error_occurred')); } $client = XenForo_Helper_Http::getClient('https://accounts.google.com/o/oauth2/token'); $client->setParameterPost(array( 'code' => $code, 'client_id' => $options->googleClientId, 'client_secret' => $options->googleClientSecret, 'redirect_uri' => 'postmessage', 'grant_type' => 'authorization_code' )); $result = $client->request('POST'); $body = @json_decode($result->getBody(), true); if (!$body || !empty($body['error'])) { $credentials = $session->get('googleCredentials'); if (!$credentials) { return $this->responseError(new XenForo_Phrase('error_occurred_when_connecting_to_google')); } } else { $idTokenParts = explode('.', $body['id_token']); $basicInfo = json_decode(base64_decode($idTokenParts[1]), true); if (!$basicInfo || empty($basicInfo['sub'])) { return $this->responseError(new XenForo_Phrase('error_occurred_when_connecting_to_google')); } $credentials = array( 'extra' => array( 'access_token' => $body['access_token'], 'expiry' => XenForo_Application::$time + $body['expires_in'], 'refresh_token' => isset($body['refresh_token']) ? $body['refresh_token'] : null ), 'basic' => $basicInfo ); } $basicInfo = $credentials['basic']; $userId = $basicInfo['sub']; $userModel = $this->_getUserModel(); $userExternalModel = $this->_getUserExternalModel(); $googleAssoc = $userExternalModel->getExternalAuthAssociation('google', $userId); if ($googleAssoc && $userModel->getUserById($googleAssoc['user_id'])) { $existingExtra = unserialize($googleAssoc['extra_data']); if (!$credentials['extra']['refresh_token'] && !empty($existingExtra['refresh_token'])) { $credentials['extra']['refresh_token'] = $existingExtra['refresh_token']; } $userExternalModel->updateExternalAuthAssociationExtra( $googleAssoc['user_id'], 'google', $credentials['extra'] ); /** @var XenForo_ControllerHelper_Login $loginHelper */ $loginHelper = $this->getHelper('Login'); $loginHelper->tfaRedirectIfRequiredPublic($googleAssoc['user_id'], $redirect, true); $visitor = XenForo_Visitor::setup($googleAssoc['user_id']); XenForo_Application::getSession()->userLogin($googleAssoc['user_id'], $visitor['password_date']); $this->_getUserModel()->setUserRememberCookie($googleAssoc['user_id']); return $this->responseRedirect( XenForo_ControllerResponse_Redirect::SUCCESS, $redirect ); } if (empty($basicInfo['email']) || empty($basicInfo['email_verified']) || $basicInfo['email_verified'] != 'true') { return $this->responseError(new XenForo_Phrase('you_must_have_verified_email_to_register_via_google')); } parent::_assertBoardActive('google'); if (empty($credentials['user'])) { $client = XenForo_Helper_Http::getClient('https://www.googleapis.com/plus/v1/people/me'); $client->setParameterGet('access_token', $credentials['extra']['access_token']); $response = $client->request('GET'); $userInfo = json_decode($response->getBody(), true); $credentials['user'] = $userInfo; } $session->set('googleCredentials', $credentials); $viewName = 'XenForo_ViewPublic_Register_Google'; $templateName = 'register_google'; $emailMatch = false; if (XenForo_Visitor::getUserId()) { $existingUser = XenForo_Visitor::getInstance(); } else { $existingUser = $userModel->getUserByEmail($basicInfo['email']); $emailMatch = (bool)$existingUser; } XenForo_Application::getSession()->set('loginRedirect', $redirect); if ($existingUser) { // must associate: matching user return $this->_getExternalRegisterFormResponse($viewName, $templateName, array( 'associateOnly' => true, 'existingUser' => $existingUser, 'emailMatch' => $emailMatch, 'redirect' => $redirect )); } $this->_assertRegistrationActive(); return $this->_getExternalRegisterFormResponse($viewName, $templateName, array( 'redirect' => $redirect, 'credentials' => $credentials, 'showDob' => empty($credentials['user']['birthday']) )); } /** * Registers a new account (or associates with an existing one) using Google. * * @return XenForo_ControllerResponse_Abstract */ public function actionGoogleRegister() { $this->_assertPostOnly(); $session = XenForo_Application::getSession(); $credentials = $session->get('googleCredentials'); if (!$credentials) { return $this->responseError(new XenForo_Phrase('you_did_not_grant_permission_to_access_external_account')); } $userExternalModel = $this->_getUserExternalModel(); $doAssoc = ($this->_input->filterSingle('associate', XenForo_Input::STRING) || $this->_input->filterSingle('force_assoc', XenForo_Input::UINT) ); $redirect = XenForo_Application::getSession()->get('loginRedirect'); if (!$redirect) { $redirect = $this->getDynamicRedirect(false, false); } if ($doAssoc) { $userId = $this->_associateExternalAccount(); $userExternalModel->updateExternalAuthAssociation( 'google', $credentials['basic']['sub'], $userId, $credentials['extra'] ); return $this->responseRedirect( XenForo_ControllerResponse_Redirect::SUCCESS, $redirect ); } $googleUser = $credentials['user']; $data = $this->_input->filter(array( 'username' => XenForo_Input::STRING, 'timezone' => XenForo_Input::STRING, 'location' => XenForo_Input::STRING, 'dob_day' => XenForo_Input::UINT, 'dob_month' => XenForo_Input::UINT, 'dob_year' => XenForo_Input::UINT, )); $data['email'] = $credentials['basic']['email']; if (!empty($googleUser['currentLocation'])) { $data['location'] = $googleUser['currentLocation']; } else if (!empty($googleUser['placesLived']) && is_array($googleUser['placesLived'])) { foreach ($googleUser['placesLived'] AS $place) { if (!empty($place['primary'])) { $data['location'] = $place['value']; break; } } } if (isset($googleUser['gender'])) { switch ($googleUser['gender']) { case 'male': case 'female': $data['gender'] = $googleUser['gender']; break; } } if (!empty($googleUser['birthday'])) { $birthday = $this->_validateBirthdayString($googleUser['birthday'], 'y-m-d'); if ($birthday) { $data['dob_year'] = $birthday[0]; $data['dob_month'] = $birthday[1]; $data['dob_day'] = $birthday[2]; } } $writer = $this->_setupExternalUser($data); if (!$this->_validateBirthdayInput($writer, $birthdayError)) { $writer->error($birthdayError); } $spamModel = $this->_runSpamCheck($writer); $writer->advanceRegistrationUserState(false); $writer->save(); $user = $writer->getMergedData(); $spamModel->logSpamTrigger('user', $user['user_id']); if (!empty($googleUser['image']['url']) && $this->_canApplyAvatar()) { try { // get the original size $url = preg_replace('/(\?|&)sz=\d+/', '', $googleUser['image']['url']); $request = XenForo_Helper_Http::getClient($url)->request(); $avatarData = $request->getBody(); } catch (Exception $e) { $avatarData = ''; } $this->_applyAvatar($user, $avatarData); } $userExternalModel->updateExternalAuthAssociation( 'google', $credentials['basic']['sub'], $user['user_id'], $credentials['extra'] ); return $this->_completeRegistration($user); } protected function _getExternalRegisterFormResponse($viewName, $templateName, array $extraParams = array()) { $options = XenForo_Application::getOptions(); $viewParams = $extraParams + array( 'customFields' => $this->_getFieldModel()->prepareUserFields( $this->_getFieldModel()->getUserFields(array('registration' => true)), true ), 'timeZones' => XenForo_Helper_TimeZone::getTimeZones(), 'tosUrl' => XenForo_Dependencies_Public::getTosUrl(), 'dobRequired' => $options->get('registrationSetup', 'requireDob'), ); return $this->responseView($viewName, $templateName, $viewParams, $this->_getRegistrationContainerParams()); } protected function _setupExternalUser(array $data) { $this->_assertRegistrationActive(); if (XenForo_Dependencies_Public::getTosUrl() && !$this->_input->filterSingle('agree', XenForo_Input::UINT)) { throw $this->responseException( $this->responseError(new XenForo_Phrase('you_must_agree_to_terms_of_service')) ); } $writer = XenForo_DataWriter::create('XenForo_DataWriter_User'); $options = XenForo_Application::get('options'); if ($options->registrationDefaults) { $writer->bulkSet($options->registrationDefaults, array('ignoreInvalidFields' => true)); } $writer->bulkSet($data); $writer->set('user_group_id', XenForo_Model_User::$defaultRegisteredGroupId); $writer->set('language_id', XenForo_Visitor::getInstance()->get('language_id')); $customFields = $this->_input->filterSingle('custom_fields', XenForo_Input::ARRAY_SIMPLE); $customFieldsShown = array_keys($this->_getFieldModel()->getUserFields(array('registration' => true))); $writer->setCustomFields($customFields, $customFieldsShown); $auth = XenForo_Authentication_Abstract::create('XenForo_Authentication_NoPassword'); $writer->set('scheme_class', $auth->getClassName()); $writer->set('data', $auth->generate(''), 'xf_user_authenticate'); return $writer; } protected function _validateBirthdayString($birthday, $format) { $format = strtr(preg_quote($format, '#'), array( 'm' => '(?P<month>\d{1,2})', 'd' => '(?P<day>\d{1,2})', 'y' => '(?P<year>\d{1,4})', )); if (!preg_match('#^' . $format . '$#i', $birthday, $match)) { return false; } $month = intval($match['month']); $day = intval($match['day']); $year = intval($match['year']); if (!$year) { return false; } $userAge = $this->_getUserProfileModel()->calculateAge($year, $month, $day); $options = XenForo_Application::getOptions(); if ($userAge < intval($options->get('registrationSetup', 'minimumAge'))) { throw $this->responseException( $this->responseError(new XenForo_Phrase('sorry_you_too_young_to_create_an_account')) ); } return array($year, $month, $day); } protected function _validateBirthdayInput(XenForo_DataWriter_User $writer, &$error) { $options = XenForo_Application::getOptions(); $error = false; $writer->checkDob(); if (!$options->get('registrationSetup', 'requireDob')) { return true; } // dob required if (!$writer->get('dob_day') || !$writer->get('dob_month') || !$writer->get('dob_year')) { $error = new XenForo_Phrase('please_enter_valid_date_of_birth'); return false; } else { $userAge = $this->_getUserProfileModel()->getUserAge($writer->getMergedData(), true); if ($userAge < 1) { $error = new XenForo_Phrase('please_enter_valid_date_of_birth'); return false; } else if ($userAge < intval($options->get('registrationSetup', 'minimumAge'))) { // TODO: set a cookie to prevent re-registration attempts $error = new XenForo_Phrase('sorry_you_too_young_to_create_an_account'); return false; } } return true; } protected function _runSpamCheck(XenForo_DataWriter_User $writer, array $extraErrors = array()) { /** @var XenForo_Model_SpamPrevention $spamModel */ $spamModel = $this->getModelFromCache('XenForo_Model_SpamPrevention'); if ($extraErrors || $writer->getErrors()) { return $spamModel; } $spamResponse = $spamModel->allowRegistration($writer->getMergedData(), $this->_request); switch ($spamResponse) { case XenForo_Model_SpamPrevention::RESULT_DENIED: $spamModel->logSpamTrigger('user', null); $writer->error(new XenForo_Phrase('spam_prevention_registration_rejected'), 'spam'); break; case XenForo_Model_SpamPrevention::RESULT_MODERATED: $writer->set('user_state', 'moderated'); break; } return $spamModel; } protected function _getExternalAuthRedirect() { $redirect = XenForo_Link::convertUriToAbsoluteUri($this->getDynamicRedirect(), true); $baseDomain = preg_replace( '#^([a-z]+://[^/]+).*$#i', '$1', XenForo_Link::convertUriToAbsoluteUri(XenForo_Application::getOptions()->boardUrl, true) ); if (strpos($redirect, $baseDomain) !== 0) { $redirect = XenForo_Link::buildPublicLink('canonical:index'); } return $redirect; } protected function _associateExternalAccount() { $associate = $this->_input->filter(array( 'associate_password' => XenForo_Input::STRING )); $loginModel = $this->_getLoginModel(); $userModel = $this->_getUserModel(); $visitor = XenForo_Visitor::getInstance(); if (!$visitor['user_id']) { throw $this->responseException( $this->responseError( new XenForo_Phrase('to_associate_existing_account_first_log_in') ) ); } if ($loginModel->requireLoginCaptcha($visitor['username'])) { throw $this->responseException( $this->responseError( new XenForo_Phrase('your_account_has_temporarily_been_locked_due_to_failed_login_attempts') ) ); } $userId = $userModel->validateAuthentication( $visitor['username'], $associate['associate_password'], $error ); if (!$userId) { $loginModel->logLoginAttempt($visitor['username']); throw $this->responseException( $this->responseError($error) ); } return $userId; } protected function _canApplyAvatar($combinationId = null) { /** @var XenForo_Model_Permission $permissionModel */ $permissionModel = $this->getModelFromCache('XenForo_Model_Permission'); if (!$combinationId) { $combinationId = $permissionModel->getPermissionCombinationIdByUserRole( 0, array(XenForo_Model_User::$defaultRegisteredGroupId) ); } if (!$combinationId) { return false; } $permissionSet = $permissionModel->getPermissionCombinationById($combinationId); if (!$permissionSet) { return false; } $permissions = $permissionSet ? XenForo_Permission::unserializePermissions($permissionSet['cache_value']) : null; return ($permissions && XenForo_Permission::hasPermission($permissions, 'avatar', 'allowed') && XenForo_Permission::hasPermission($permissions, 'avatar', 'maxFileSize') != 0 ); } protected function _applyAvatar(array $user, $data) { $success = false; if (!$data || !$user['user_id']) { return false; } $avatarFile = tempnam(XenForo_Helper_File::getTempDir(), 'xf'); if ($avatarFile) { file_put_contents($avatarFile, $data); try { $user = array_merge($user, $this->getModelFromCache('XenForo_Model_Avatar')->applyAvatar($user['user_id'], $avatarFile) ); $success = true; } catch (XenForo_Exception $e) {} @unlink($avatarFile); } return $success; } protected function _assertRegistrationActive() { if (!XenForo_Application::get('options')->get('registrationSetup', 'enabled')) { throw $this->responseException($this->responseError( new XenForo_Phrase('new_registrations_currently_not_being_accepted') )); } } protected function _assertBoardActive($action) { switch (strtolower($action)) { case 'facebook': case 'twitter': case 'google': break; default: parent::_assertBoardActive($action); } } protected function _assertCorrectVersion($action) { switch (strtolower($action)) { case 'facebook': case 'twitter': case 'google': break; default: parent::_assertCorrectVersion($action); } } protected function _assertViewingPermissions($action) {} protected function _assertTfaRequirement($action) {} /** * Session activity details. * @see XenForo_Controller::getSessionActivityDetailsForList() */ public static function getSessionActivityDetailsForList(array $activities) { return new XenForo_Phrase('registering'); } /** * @return XenForo_Model_User */ protected function _getUserModel() { return $this->getModelFromCache('XenForo_Model_User'); } /** * @return XenForo_Model_UserProfile */ protected function _getUserProfileModel() { return $this->getModelFromCache('XenForo_Model_UserProfile'); } /** * @return XenForo_Model_UserField */ protected function _getFieldModel() { return $this->getModelFromCache('XenForo_Model_UserField'); } /** * @return XenForo_Model_UserConfirmation */ protected function _getUserConfirmationModel() { return $this->getModelFromCache('XenForo_Model_UserConfirmation'); } /** * @return XenForo_Model_UserExternal */ protected function _getUserExternalModel() { return $this->getModelFromCache('XenForo_Model_UserExternal'); } /** * @return XenForo_Model_Login */ protected function _getLoginModel() { return $this->getModelFromCache('XenForo_Model_Login'); } } Doh... Here is a randomly created user. That blob is a bin file. https://xenforo.com/community/threads/xf-db-tables.18825/ It contains: a:1:{s:4:"hash";s:60:"$2a$10$jlWdNFyeOgxR.ogqhyVmwOyAFIlZWWWj3g6Z8MlUChvYVFHbqF8Ei";}
-
Alright, so as I thought It's like that. I will see If I can look It up, since older posts on the Xenforo page doesn't really tell anything. I will also wait, somebody may have a solution. Thanks.
-
I was thinking on using XenForo instead of SMF. I have been using Xenforo most of the time anyway. I'm trying to build up the same hashing style at the login part, in MTA, but I'm kinda lost. Is anyone here familiar with XenForo? I'm unsure where could I find the salt, or which one is the salt in the db... As I see It hashes the given (password + randomgeneratedstringfromthedb) and then hashes It again? I'm not a PHP expert, sorry for that, but I'm trying to reproduce the same thing in Lua. Anyone could tell me where is, or which one is the salt string in the db? /** * Default Salt Length * * @var integer */ const DEFAULT_SALT_LENGTH = 30; public static function generateSalt($length = null) { if (!$length) { $length = self::DEFAULT_SALT_LENGTH; } return XenForo_Application::generateRandomString($length); } protected function _createHash($data) { $this->_setupHash(); switch ($this->_hashFunc) { case 'sha256': return hash('sha256', $data); case 'sha1': return sha1($data); default: throw new XenForo_Exception("Unknown hash type"); } } protected function _newPassword($password, $salt) { $hash = $this->_createHash($this->_createHash($password) . $salt); return array('hash' => $hash, 'salt' => $salt, 'hashFunc' => $this->_hashFunc); }
-
I was thinking about that, will give It a go.
-
We are discussing a different matter at the moment. See up there ^
-
Weirdo. Some guys say It feels like the same.
-
One more thing. Is there a default method that would automatically decrease the volume, based on the distance?
-
local sound = playSound3D("sounds/9mmshot.mp3", x,y,z) setSoundMaxDistance(sound, 75) Any idea why isn't It playing in interiors? Tried enable interiorsounds, but doesn't work as well.
-
Hello! I read somewhere that specific skins that you cannot attack items to, are not having the bone components. How can I add these sort of bone components to skins? Any tutorial on that? Thanks
-
Seems like i was wrong. Some of the interiors cause crash when doing CTRL+ALT+DEL or user switching.
-
Why Is this? Is It because an old game? I have windows 7, and I tried to run It in compatibility mode, but MTA always unticks It. Every other game seems to be working at user switching, why isn't It the same for MTA? I would suggest a fix if possible. Cheers
-
Python and Java is getting added?
Dretax replied to Dretax's topic in Site/Forum/Discord/Mantis/Wiki related
Too bad. I would be happy for python though. -
I see traces in the github, where python and java is getting added. Is this for real? Finally we can see Python plugins running on MTA instead of crappy lua? https://github.com/multitheftauto/mtasa ... 9cdb090095 https://github.com/multitheftauto/mtasa ... arch?utf8=✓&q=java https://github.com/multitheftauto/mtasa ... arch?utf8=✓&q=python I saw the commits where It was pushed in Sept. I'm excited seeing this. When are you guys planning to release the full functional builds?
-
"Much faster" how? "More stable" how? And what capabilities are you talking about? Lua is Turing complete language, therefore it is capable of solving any computational problem, just like Python. If you're talking about stuff in Python standard library which should not be allowed to be freely executed by scripts downloaded from servers, then they would have to be reimplemented anyway for security reasons. It's like with file functions, Lua has them but MTA disables them and instead provides its own file functions to prevent the scripts from messing with files anywhere outside resources directory. That said, I like both Lua and Python. They're my favorite scripting languages, but I still prefer Lua for its simplicity. I don't remember encountering stability problems and because of variety of criteria for performance, I can't see Python as "much faster" than Lua. Personally, I would like to see both Lua and Python in MTA, but since one language can already be used to do all the stuff, second one would provide little benefit, especially since potential security issues would need to be taken care of. I agree that ad populum is a bad argument though. "People say so" has never been an accurate way to determine the objective reality. That's why I don't use popularity as an argument except as a troll response to opponents who use the same fallacy Lua is not readable. Stinks. Ugly. Not simple at all. Python is. Programming in Python rather than LUA. Everyone would do that if they would be allowed. Python might not be small, but It has more libs. If It would be C#, IronPython would kill your lua 5.1. Actually putting Python in would bring more people, since looking at SAMP has the other ugly shit called pawn. We need modern languages. And looking at this: http://githut.info just proves me that MTA would benefit more than using LUA.
-
Nem fontos, az egyik MTA fejlesztő elválalta.
-
Sziasztok! RP szerverünkhöz keresünk komolyabb scriptert, lehetőleg sok tapasztalattal, és lua tudással. A mod megírásához fizetnénk, nem ingyenes melóról lenne szó. Ha érdekelne valakit, dobjon egy PM-et. Köszönöm.
-
Yes, but there are tons of other languages that do the same thing. Name multiple AAA games that use python as their language. Here's a list for lua. http://en.wikipedia.org/wiki/Category:L ... ideo_games Lua might be light what you say, but people only implement it, cause its easy to. Python is much better than lua, much faster, much more stable, and more stable. Lua < JavaScript < Python If you ask any of those who know all the languages, they will say the same, even if they love on of the more. Python has more capabilites, and prooved me a lot in CSS, or in Socket. Statistic doesn't matter, a language can be popular for anything.