/** * Process transaction. * * @access public */ public function process() { $this->logPayPal('Received notification from %s (%s)', $_SERVER['REMOTE_ADDR'], gethostbyaddr($_SERVER['REMOTE_ADDR'])); if ($this->verify()) { $this->logPayPal('Proceeding to validate the authenticity of the transaction...'); $accountEmails = Flux::config('PayPalReceiverEmails'); $accountEmails = array_merge(array($this->myBusinessEmail), $accountEmails->toArray()); $receiverEmail = $this->ipnVariables->get('receiver_email'); $transactionID = $this->ipnVariables->get('txn_id'); $paymentStatus = $this->ipnVariables->get('payment_status'); $payerEmail = $this->ipnVariables->get('payer_email'); $currencyCode = strtoupper(substr($this->ipnVariables->get('mc_currency'), 0, 3)); $trusted = true; // Identify transaction number. $this->logPayPal('Transaction identified as %s.', $transactionID); if (!in_array($receiverEmail, $accountEmails)) { $this->logPayPal('Receiver e-mail (%s) is not recognized, unauthorized to continue.', $receiverEmail); } else { $customArray = @unserialize(base64_decode((string) $this->ipnVariables->get('custom'))); $customArray = $customArray && is_array($customArray) ? $customArray : array(); $customData = new Flux_Config($customArray); $accountID = $customData->get('account_id'); $serverName = $customData->get('server_name'); if ($currencyCode != $this->myCurrencyCode) { $this->logPayPal('Transaction currency not exchangeable, accepting anyways. (recv: %s, expected: %s)', $currencyCode, $this->myCurrencyCode); $exchangeableCurrency = false; } else { $exchangeableCurrency = true; } // How much was received? (and in what currency?) $this->logPayPal('Received %s (%s).', $this->ipnVariables->get('mc_gross'), $currencyCode); // How much will be deposited? $settleAmount = $this->ipnVariables->get('settle_amount'); $settleCurrency = $this->ipnVariables->get('settle_currency'); if ($settleAmount && $settleCurrency) { $this->logPayPal('Deposited into PayPal account: %s %s.', $settleAmount, $settleCurrency); } // Let's see where the donation credits should go to. $this->logPayPal('Game server name: %s, account ID: %s', $serverName ? $serverName : '(absent)', $accountID ? $accountID : '(absent)'); if (!$accountID || !$serverName) { $this->logPayPal('Account ID and/or game server name absent, cannot exchange for credits.'); } elseif ($this->ipnVariables->get('txn_type') != 'web_accept') { $this->logPayPal('Transaction type is not web_accept, amount will not be exchanged for credits.'); } elseif (!($servGroup = Flux::getServerGroupByName($serverName))) { $this->logPayPal('Unknown game server "%s", cannot process donation for credits.', $serverName); } if ($paymentStatus == 'Completed') { $this->logPayPal('Payment for txn_id#%s has been completed.', $transactionID); if ($servGroup && $exchangeableCurrency) { $sql = "SELECT COUNT(account_id) AS acc_id_count FROM {$servGroup->loginDatabase}.login WHERE sex != 'S' AND group_id >= 0 AND account_id = ?"; $sth = $servGroup->connection->getStatement($sql); $sth->execute(array($accountID)); $res = $sth->fetch(); if (!$res) { $this->logPayPal('Unknown account #%s on server %s, cannot exchange for credits.', $accountID, $serverName); } else { if (!$servGroup->loginServer->hasCreditsRecord($accountID)) { $this->logPayPal('Identified as first-time donation to the server from this account.'); } $amount = (double) $this->ipnVariables->get('mc_gross'); $minimum = (double) Flux::config('MinDonationAmount'); if ($amount >= $minimum) { $trustTable = Flux::config('FluxTables.DonationTrustTable'); $holdHours = +(int) Flux::config('HoldUntrustedAccount'); if ($holdHours) { $sql = "SELECT account_id, email FROM {$servGroup->loginDatabase}.{$trustTable} WHERE account_id = ? AND email = ? LIMIT 1"; $sth = $servGroup->connection->getStatement($sql); $sth->execute(array($accountID, $payerEmail)); $res = $sth->fetch(); if ($res && $res->account_id) { $this->logPayPal('Account ID and e-mail are trusted.'); $trusted = true; } else { $trusted = false; } } $rate = Flux::config('CreditExchangeRate'); $credits = floor($amount / $rate); if ($trusted) { $sql = "SELECT * FROM {$servGroup->loginDatabase}.{$this->creditsTable} WHERE account_id = ?"; $sth = $servGroup->connection->getStatement($sql); $sth->execute(array($accountID)); $acc = $sth->fetch(); $this->logPayPal('Updating account credit balance from %s to %s', (int) $acc->balance, $acc->balance + $credits); $res = $servGroup->loginServer->depositCredits($accountID, $credits, $amount); if ($res) { $this->logPayPal('Deposited credits.'); } else { $this->logPayPal('Failed to deposit credits.'); } } else { $this->logPayPal('Account/e-mail is not trusted, holding donation credits for %d hours.', $holdHours); } } else { $this->logPayPal('User has donated less than the configured minimum, not exchanging credits.'); } } } } else { $this->logPayPal('Incomplete payment status: %s (exchanging for credits will not take place)', $paymentStatus); $banStatuses = Flux::config('BanPaymentStatuses'); if ($banStatuses instanceof Flux_Config) { $banStatuses = $banStatuses->toArray(); } else { $banStatuses = array(); } $pymntStatus = strtolower($paymentStatus); $banStatuses = array_map('strtolower', $banStatuses); if (in_array($pymntStatus, $banStatuses)) { $this->logPayPal('Auto-ban payment status detected: %s', $paymentStatus); if ($servGroup && $serverName && $accountID) { $this->logPayPal('Banning account! (serv: %s, account_id: %s)', $serverName, $accountID); $servGroup->loginServer->permanentlyBan(null, "Banned for invalid payment status: {$paymentStatus}", $accountID); } else { $this->logPayPal("Couldn't ban account, it's unknown."); } } } if (!$servGroup) { foreach (Flux::$loginAthenaGroupRegistry as $servGroup) { $this->logToPayPalTable($servGroup, $accountID, $serverName, $trusted); } } else { if (empty($credits)) { $credits = 0; } $this->logToPayPalTable($servGroup, $accountID, $serverName, $trusted, $credits); } $this->logPayPal('Saving transaction details for %s...', $transactionID); if ($logFile = $this->saveDetailsToFile()) { $this->logPayPal('Saved transaction details for %s to: %s', $transactionID, $logFile); } else { $this->logPayPal('Failed to save transaction details for %s to file.', $transactionID); } $this->logPayPal('Done processing %s.', $transactionID); } } else { $this->logPayPal('Transaction invalid, aborting.'); } return false; }
/** * User login. * * @param string $server Server name * @param string $username * @param string $password * @throws Flux_LoginError * @access public */ public function login($server, $username, $password, $securityCode = null) { $loginAthenaGroup = Flux::getServerGroupByName($server); if (!$loginAthenaGroup) { throw new Flux_LoginError('Invalid server.', Flux_LoginError::INVALID_SERVER); } if ($loginAthenaGroup->loginServer->isIpBanned() && !Flux::config('AllowIpBanLogin')) { throw new Flux_LoginError('IP address is banned', Flux_LoginError::IPBANNED); } if ($securityCode !== false && Flux::config('UseLoginCaptcha')) { if (strtolower($securityCode) != strtolower($this->securityCode)) { throw new Flux_LoginError('Invalid security code', Flux_LoginError::INVALID_SECURITY_CODE); } elseif (Flux::config('EnableReCaptcha')) { require_once 'recaptcha/recaptchalib.php'; $resp = recaptcha_check_answer(Flux::config('ReCaptchaPrivateKey'), $_SERVER['REMOTE_ADDR'], $_POST['recaptcha_challenge_field'], $_POST['recaptcha_response_field']); if (!$resp->is_valid) { throw new Flux_LoginError('Invalid security code', Flux_LoginError::INVALID_SECURITY_CODE); } } } if (!$loginAthenaGroup->isAuth($username, $password)) { throw new Flux_LoginError('Invalid login', Flux_LoginError::INVALID_LOGIN); } $creditsTable = Flux::config('FluxTables.CreditsTable'); $creditColumns = 'credits.balance, credits.last_donation_date, credits.last_donation_amount'; $sql = "SELECT login.*, {$creditColumns} FROM {$loginAthenaGroup->loginDatabase}.login "; $sql .= "LEFT OUTER JOIN {$loginAthenaGroup->loginDatabase}.{$creditsTable} AS credits ON login.account_id = credits.account_id "; $sql .= "WHERE login.sex != 'S' AND login.group_id >= 0 AND login.userid = ? LIMIT 1"; $smt = $loginAthenaGroup->connection->getStatement($sql); $res = $smt->execute(array($username)); if ($res && ($row = $smt->fetch())) { if ($row->unban_time > 0) { if (time() >= $row->unban_time) { $row->unban_time = 0; $sql = "UPDATE {$loginAthenaGroup->loginDatabase}.login SET unban_time = 0 WHERE account_id = ?"; $sth = $loginAthenaGroup->connection->getStatement($sql); $sth->execute(array($row->account_id)); } elseif (!Flux::config('AllowTempBanLogin')) { throw new Flux_LoginError('Temporarily banned', Flux_LoginError::BANNED); } } if ($row->state == 5) { $createTable = Flux::config('FluxTables.AccountCreateTable'); $sql = "SELECT id FROM {$loginAthenaGroup->loginDatabase}.{$createTable} "; $sql .= "WHERE account_id = ? AND confirmed = 0"; $sth = $loginAthenaGroup->connection->getStatement($sql); $sth->execute(array($row->account_id)); $row2 = $sth->fetch(); if ($row2 && $row2->id) { throw new Flux_LoginError('Pending confirmation', Flux_LoginError::PENDING_CONFIRMATION); } } if (!Flux::config('AllowPermBanLogin') && $row->state == 5) { throw new Flux_LoginError('Permanently banned', Flux_LoginError::PERMABANNED); } $this->setServerNameData($server); $this->setUsernameData($username); $this->initialize(false); } else { $message = "Unexpected error during login.\n"; $message .= 'PDO error info, if any: ' . print_r($smt->errorInfo(), true); throw new Flux_LoginError($message, Flux_LoginError::UNEXPECTED); } return true; }
if (!defined('FLUX_ROOT')) { exit; } $title = Flux::message('ResetPassTitle'); $serverNames = $this->getServerNames(); $resetPassTable = Flux::config('FluxTables.ResetPasswordTable'); if (count($_POST)) { $userid = $params->get('userid'); $email = $params->get('email'); $groupName = $params->get('login'); if (!$userid) { $errorMessage = Flux::message('ResetPassEnterAccount'); } elseif (!$email) { $errorMessage = Flux::message('ResetPassEnterEmail'); } else { if (!$groupName || !($loginAthenaGroup = Flux::getServerGroupByName($groupName))) { $loginAthenaGroup = $session->loginAthenaGroup; } $sql = "SELECT account_id, user_pass, group_id FROM {$loginAthenaGroup->loginDatabase}.login WHERE "; if ($loginAthenaGroup->loginServer->config->getNoCase()) { $sql .= 'LOWER(userid) = LOWER(?) '; } else { $sql .= 'BINARY userid = ? '; } $sql .= "AND email = ? AND state = 0 AND sex IN ('M', 'F') LIMIT 1"; $sth = $loginAthenaGroup->connection->getStatement($sql); $sth->execute(array($userid, $email)); $row = $sth->fetch(); if ($row) { if ($row->group_id >= Flux::config('NoResetPassLevel')) { $errorMessage = Flux::message('ResetPassDisallowed');
if ($session->loginAthenaGroup->loginServer->config->getUseMD5()) { $password = Flux::hashPassword($password); } $sql = "INSERT INTO {$session->loginAthenaGroup->loginDatabase}.{$loginLogTable} "; $sql .= "(account_id, username, password, ip, error_code, login_date) "; $sql .= "VALUES (?, ?, ?, ?, ?, NOW())"; $sth = $session->loginAthenaGroup->connection->getStatement($sql); $sth->execute(array($session->account->account_id, $username, $password, $_SERVER['REMOTE_ADDR'], null)); if ($returnURL) { $this->redirect($returnURL); } else { $this->redirect(); } } catch (Flux_LoginError $e) { if ($username && $password && $e->getCode() != Flux_LoginError::INVALID_SERVER) { $loginAthenaGroup = Flux::getServerGroupByName($server); $sql = "SELECT account_id FROM {$loginAthenaGroup->loginDatabase}.login WHERE "; if (!$loginAthenaGroup->loginServer->config->getNoCase()) { $sql .= "CAST(userid AS BINARY) "; } else { $sql .= "userid "; } $sql .= "= ? LIMIT 1"; $sth = $loginAthenaGroup->connection->getStatement($sql); $sth->execute(array($username)); $row = $sth->fetch(); if ($row) { $accountID = $row->account_id; if ($loginAthenaGroup->loginServer->config->getUseMD5()) { $password = Flux::hashPassword($password); }
$recaptcha = recaptcha_get_html(Flux::config('ReCaptchaPublicKey')); } $title = Flux::message('AccountCreateTitle'); $serverNames = $this->getServerNames(); if (count($_POST)) { require_once 'Flux/RegisterError.php'; try { $server = $params->get('server'); $username = $params->get('username'); $password = $params->get('password'); $confirm = $params->get('confirm_password'); $email = trim($params->get('email_address')); $gender = $params->get('gender'); $birthdate = $params->get('birthdate_date'); $code = $params->get('security_code'); if (!($server = Flux::getServerGroupByName($server))) { throw new Flux_RegisterError('Invalid server', Flux_RegisterError::INVALID_SERVER); } // Woohoo! Register ;) $result = $server->loginServer->register($username, $password, $confirm, $email, $gender, $birthdate, $code); if ($result) { if (Flux::config('RequireEmailConfirm')) { require_once 'Flux/Mailer.php'; $user = $username; $code = md5(rand()); $name = $session->loginAthenaGroup->serverName; $link = $this->url('account', 'confirm', array('_host' => true, 'code' => $code, 'user' => $username, 'login' => $name)); $mail = new Flux_Mailer(); $sent = $mail->send($email, 'Account Confirmation', 'confirm', array('AccountUsername' => $username, 'ConfirmationLink' => htmlspecialchars($link))); $createTable = Flux::config('FluxTables.AccountCreateTable'); $bind = array($code);
/** * Process transaction. * * @access public */ public function process() { $this->logPayPal('Notificação recebida de %s (%s)', $_SERVER['REMOTE_ADDR'], gethostbyaddr($_SERVER['REMOTE_ADDR'])); if ($this->verify()) { $this->logPayPal('Processo para validar a autenticidade da transação...'); $accountEmails = Flux::config('PayPalReceiverEmails'); $accountEmails = array_merge(array($this->myBusinessEmail), $accountEmails->toArray()); $receiverEmail = $this->ipnVariables->get('receiver_email'); $transactionID = $this->ipnVariables->get('txn_id'); $paymentStatus = $this->ipnVariables->get('payment_status'); $payerEmail = $this->ipnVariables->get('payer_email'); $currencyCode = strtoupper(substr($this->ipnVariables->get('mc_currency'), 0, 3)); $trusted = true; // Identify transaction number. $this->logPayPal('Transação identificada como %s.', $transactionID); if (!in_array($receiverEmail, $accountEmails)) { $this->logPayPal('E-mail do receptor (%s) não é reconhecido, não autorizado para continuar.', $receiverEmail); } else { $customArray = @unserialize(base64_decode((string) $this->ipnVariables->get('custom'))); $customArray = $customArray && is_array($customArray) ? $customArray : array(); $customData = new Flux_Config($customArray); $accountID = $customData->get('account_id'); $serverName = $customData->get('server_name'); if ($currencyCode != $this->myCurrencyCode) { $this->logPayPal('Moeda de transação não passíveis de troca, aceitando qualquer forma. (recebido: %s, espera: %s)', $currencyCode, $this->myCurrencyCode); $exchangeableCurrency = false; } else { $exchangeableCurrency = true; } // How much was received? (and in what currency?) $this->logPayPal('Recebido %s (%s).', $this->ipnVariables->get('mc_gross'), $currencyCode); // How much will be deposited? $settleAmount = $this->ipnVariables->get('settle_amount'); $settleCurrency = $this->ipnVariables->get('settle_currency'); if ($settleAmount && $settleCurrency) { $this->logPayPal('Depositado na conta do PayPal: %s %s.', $settleAmount, $settleCurrency); } // Let's see where the donation credits should go to. $this->logPayPal('Nome do servidor do jogo: %s, account ID: %s', $serverName ? $serverName : '(absent)', $accountID ? $accountID : '(absent)'); if (!$accountID || !$serverName) { $this->logPayPal('ID de conta e/ou nome no servidor de jogo ausente, não é possível trocar por créditos.'); } elseif ($this->ipnVariables->get('txn_type') != 'web_accept') { $this->logPayPal('Tipo de transação não é web_accept, a quantidade não será trocada por créditos.'); } elseif (!($servGroup = Flux::getServerGroupByName($serverName))) { $this->logPayPal('Servidor de jogo desconhecido "%s", não é possível processo de doação para créditos.', $serverName); } if ($paymentStatus == 'Completed') { $this->logPayPal('Pagamento para txn_id#%s foi concluído.', $transactionID); if ($servGroup && $exchangeableCurrency) { $sql = "SELECT COUNT(account_id) AS acc_id_count FROM {$servGroup->loginDatabase}.login WHERE sex != 'S' AND group_id >= 0 AND account_id = ?"; $sth = $servGroup->connection->getStatement($sql); $sth->execute(array($accountID)); $res = $sth->fetch(); if (!$res) { $this->logPayPal('Conta desconhecida #%s no servidor %s, não é possível trocar por créditos.', $accountID, $serverName); } else { if (!$servGroup->loginServer->hasCreditsRecord($accountID)) { $this->logPayPal('Identificado como doação pela primeira vez desta conta ao servidor.'); } $amount = (double) $this->ipnVariables->get('mc_gross'); $minimum = (double) Flux::config('MinDonationAmount'); if ($amount >= $minimum) { $trustTable = Flux::config('FluxTables.DonationTrustTable'); $holdHours = +(int) Flux::config('HoldUntrustedAccount'); if ($holdHours) { $sql = "SELECT account_id, email FROM {$servGroup->loginDatabase}.{$trustTable} WHERE account_id = ? AND email = ? LIMIT 1"; $sth = $servGroup->connection->getStatement($sql); $sth->execute(array($accountID, $payerEmail)); $res = $sth->fetch(); if ($res && $res->account_id) { $this->logPayPal('Account ID and e-mail are trusted.'); $trusted = true; } else { $trusted = false; } } $rate = Flux::config('CreditExchangeRate'); $credits = floor($amount / $rate); if ($trusted) { $sql = "SELECT * FROM {$servGroup->loginDatabase}.{$this->creditsTable} WHERE account_id = ?"; $sth = $servGroup->connection->getStatement($sql); $sth->execute(array($accountID)); $acc = $sth->fetch(); $this->logPayPal('Atualizando o saldo de crédito de %s para %s', (int) $acc->balance, $acc->balance + $credits); $res = $servGroup->loginServer->depositCredits($accountID, $credits, $amount); if ($res) { $this->logPayPal('Créditos depositados.'); } else { $this->logPayPal('Não conseguiu depositar créditos.'); } } else { $this->logPayPal('Conta/e-mail não é confiável, mantendo os créditos de doação para %d horas.', $holdHours); } } else { $this->logPayPal('Usuário doou menos do que o mínimo configurado, não trocar créditos.'); } } } } else { $this->logPayPal('Status de pagamento incompleto: %s (troca por créditos não vai ocorrer)', $paymentStatus); $banStatuses = Flux::config('BanPaymentStatuses'); if ($banStatuses instanceof Flux_Config) { $banStatuses = $banStatuses->toArray(); } else { $banStatuses = array(); } $pymntStatus = strtolower($paymentStatus); $banStatuses = array_map('strtolower', $banStatuses); if (in_array($pymntStatus, $banStatuses)) { $this->logPayPal('Auto-banimento status de pagamento detectado: %s', $paymentStatus); if ($servGroup && $serverName && $accountID) { $this->logPayPal('Conta Banida! (servidor: %s, ID da Conta: %s)', $serverName, $accountID); $servGroup->loginServer->permanentlyBan(null, "Banido por status de pagamento inválido: {$paymentStatus}", $accountID); } else { $this->logPayPal("Não poderia proibir conta, ele é desconhecido."); } } } if (!$servGroup) { foreach (Flux::$loginAthenaGroupRegistry as $servGroup) { $this->logToPayPalTable($servGroup, $accountID, $serverName, $trusted); } } else { if (empty($credits)) { $credits = 0; } $this->logToPayPalTable($servGroup, $accountID, $serverName, $trusted, $credits); } $this->logPayPal('Detalhes de transações de poupança %s...', $transactionID); if ($logFile = $this->saveDetailsToFile()) { $this->logPayPal('Salvo os detalhes de transações %s para: %s', $transactionID, $logFile); } else { $this->logPayPal('Falha ao salvar detalhes de transações %s para arquivo.', $transactionID); } $this->logPayPal('Processamento feito %s.', $transactionID); } } else { $this->logPayPal('Transação inválida, abortando.'); } return false; }