• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

TFS 1.X+ Double Login? - IOLoginData

Dumjaevl

#1 Error Maker
Joined
Sep 9, 2011
Messages
46
Reaction score
2
Location
Sweden
Hello guys,

I'm trying to startup an OT with the resp otservbr-global (Fork of TFS) with an edited 12.00 client.
Everything works fine with the login towards the character screen and i'm available to browse the characters, but when i choose to connect to the world, the following pops up in the server-side:

1581814153145.png
(Ps. persontest1 is the password).

The login is connected trough myAAC-Login from the tibiaclient with http towards the IPV4-adress (xx.xx.xx.xx/login.php)
It feels like the encryption in the image above is either encrypting the accountname or password wrong, thus making it an incorrect login, but I have no idea where the issue occurs, and there is no logs aswell on it.
I've been trying for hours to figure this out, but i'm totally stuck on this one!

Is there anybody that might have a solution on this one?
 
post both your config.lua and config from myAAC

Oh, right! Sorry ^^

CONFIG.LUA (Server)
Lua:
-- Combat settings
-- NOTE: valid values for worldType are: "pvp", "no-pvp" and "pvp-enforced"
worldType = "pvp"
hotkeyAimbotEnabled = true
protectionLevel = 7
pzLocked = 60 * 1000
removeChargesFromRunes = true
removeChargesFromPotions = true
removeWeaponAmmunition = true
removeWeaponCharges = true
timeToDecreaseFrags = 45 * 24 * 60 * 60
whiteSkullTime = 15 * 60 * 1000
stairJumpExhaustion = 2 * 1000
experienceByKillingPlayers = false
expFromPlayersLevelRange = 75
dayKillsToRedSkull = 3
weekKillsToRedSkull = 5
monthKillsToRedSkull = 10
redSkullDuration = 30
blackSkullDuration = 45
orangeSkullDuration = 7

-- Connection Config
-- NOTE: maxPlayers set to 0 means no limit
-- NOTE: MaxPacketsPerSeconds if you change you will be subject to bugs by WPE, keep the default value of 25
ip = "**.**.**.**"
bindOnlyGlobalAddress = false
loginProtocolPort = 7171
gameProtocolPort = 7172
statusProtocolPort = 7171
maxPlayers = 0
motd = "Welcome to our Development!"
onePlayerOnlinePerAccount = true
allowClones = false
serverName = "Development"
statusTimeout = 5 * 1000
replaceKickOnLogin = true
maxPacketsPerSecond = 25
maxItem = 2000
maxContainer = 100

-- Version Manual
clientVersionMin = 1000
clientVersionMax = 1200
clientVersionStr = "Only support outdated 10.00 and version 12.00"

-- Depot Limit
freeDepotLimit = 2000
premiumDepotLimit = 10000
depotBoxes = 17

-- GameStore
gamestoreByModules = true

-- Quest Sytem
loadQuestLua = true

-- Expert Pvp Config
expertPvp = false

-- Deaths
-- NOTE: Leave deathLosePercent as -1 if you want to use the default
-- death penalty formula. For the old formula, set it to 10. For
-- no skill/experience loss, set it to 0.
deathLosePercent = -1

-- Houses
-- NOTE: set housePriceEachSQM to -1 to disable the ingame buy house functionality
housePriceEachSQM = 1000
houseRentPeriod = "never"

-- Item Usage
-- Do not touch here
-- Avoid use of WIPE program to crash the distro
timeBetweenActions = 500
timeBetweenExActions = 700

-- Map
-- NOTE: set mapName WITHOUT .otbm at the end
-- NOTE: unzip the map world.rar
mapName = "otservbr"
mapAuthor = "OTServBR"

-- Market
marketOfferDuration = 30 * 24 * 60 * 60
premiumToCreateMarketOffer = true
checkExpiredMarketOffersEachMinutes = 60
maxMarketOffersAtATimePerPlayer = 100

-- MySQL
mysqlHost = "127.0.0.1"
mysqlUser = "****"
mysqlPass = "****"
mysqlDatabase = "****"
mysqlPort = 3306
mysqlSock = ""

-- Misc.
allowChangeOutfit = true
freePremium = true
kickIdlePlayerAfterMinutes = 15
idleWarningTime = 10 * 60 * 1000
idleKickTime = 15 * 60 * 1000
maxMessageBuffer = 4
emoteSpells = false
classicEquipmentSlots = false
allowWalkthrough = true
coinPacketSize = 25
coinImagesURL = "http://127.0.0.1/images/store/"
classicAttackSpeed = false
showScriptsLogInConsole = false

-- Server Save
-- NOTE: serverSaveNotifyDuration in minutes
serverSaveNotifyMessage = true
serverSaveNotifyDuration = 5
serverSaveCleanMap = false
serverSaveClose = false
serverSaveShutdown = true

-- Rates
-- NOTE: rateExp is not used if you have enabled stages in data/XML/stages.xml
rateExp = 1
rateSkill = 50
rateLoot = 3
rateMagic = 25
rateSpawn = 1

-- Monster rates
rateMonsterHealth = 1.0
rateMonsterAttack = 1.0
rateMonsterDefense = 1.0

-- Monsters
deSpawnRange = 2
deSpawnRadius = 50

-- Stamina
staminaSystem = true

-- Scripts
warnUnsafeScripts = true
convertUnsafeScripts = true

-- Startup
-- NOTE: defaultPriority only works on Windows and sets process
-- priority, valid values are: "normal", "above-normal", "high"
defaultPriority = "high"
startupDatabaseOptimization = true

-- Status server information
ownerName = ""
ownerEmail = ""
url = ""
location = "Sweden"

Login.php (MyAAC)
PHP:
<?php
require_once 'engine/init.php';

// Client 11 loginWebService
if($_SERVER['HTTP_USER_AGENT'] == "Mozilla/5.0" && $config['ServerEngine'] === 'TFS_10') {

    function jsonError($message, $code = 3) {
        die(json_encode(array('errorCode' => $code, 'errorMessage' => $message)));
    }

    header("Content-Type: application/json");
    $input = file_get_contents("php://input");

    // Based on tests, input length should be at least 67+ chars.
    if (strlen($input) > 10) {
        /* {
            'accountname' => 'username',
            'password' => 'superpass',
            'stayloggedin' => true,
            'token' => '123123', (or not set)
            'type' => 'login', (What other types do we have?)
        } */
        $jsonObject = json_decode($input);

        $username = sanitize($jsonObject->accountname);
        $password = SHA1($jsonObject->password);
        $token = (isset($jsonObject->token)) ? sanitize($jsonObject->token) : false;
        
        $fields = '`id`, `premdays`, `secret`';
        if ($config['twoFactorAuthenticator']) $fields .= ', `secret`';

        $account = mysql_select_single("SELECT {$fields} FROM `accounts` WHERE `name`='{$username}' AND `password`='{$password}' LIMIT 1;");
        if ($account === false) {
            jsonError('Wrong username and/or password.');
        }

        if ($config['twoFactorAuthenticator'] === true && $account['secret'] !== null) {
            if ($token === false) {
                jsonError('Submit a valid two-factor authentication token.', 6);
            } else {
                require_once("engine/function/rfc6238.php");
                if (TokenAuth6238::verify($account['secret'], $token) !== true) {
                    jsonError('Two-factor authentication failed, token is wrong.', 6);
                }
            }
        }

        $players = mysql_select_multi("SELECT `name`, `sex`, `level`, `vocation`, `lookbody`, `looktype`, `lookhead`, `looklegs`, `lookfeet`, `lookaddons`, `deletion` FROM `players` WHERE `account_id`='".$account['id']."';");
        if ($players !== false) {

            $gameserver = $config['gameserver'];
            // todo: Fix dynamic desition to pass along token. (and verify that it works). Hostname: otx11.lan
            $sessionKey = $username."\n".$jsonObject->password;
            if (strlen($account['secret']) > 5) $sessionKey .= "\n".$token."\n".floor(time() / 30);
            $response = array(
                'session' => array(
                    'fpstracking' => false,
                    'optiontracking' => false,
                    'isreturner' => true,
                    'returnernotification' => false,
                    'showrewardnews' => false,
                    'tournamentticketpurchasestate' => 0,
                    'emailcoderequest' => false,
                    'sessionkey' => $sessionKey,
                    'lastlogintime' => 0,
                    'ispremium' => ($account['premdays'] > 0) ? true : false,
                    'premiumuntil' => time() + ($account['premdays'] * 86400),
                    'status' => 'active'
                ),
                'playdata' => array(
                    'worlds' => array(
                        array(
                            'id' => 0,
                            'name' => $gameserver['name'],
                            'externaladdress' => $gameserver['ip'],
                            'externalport' => $gameserver['port'],
                            'previewstate' => 0,
                            'location' => 'ALL',
                            'pvptype' => 'pvp',
                            'externaladdressunprotected' => $gameserver['ip'],
                            'externaladdressprotected' => $gameserver['ip'],
                            'externalportunprotected' => $gameserver['port'],
                            'externalportprotected' => $gameserver['port'],
                            'istournamentworld' => false,
                            'restrictedstore' => false,
                            'currenttournamentphase' => 2,
                            'anticheatprotection' => false
                        )
                    ),
                    'characters' => array(
                        //array( 'worldid' => ASD, 'name' => asd, 'ismale' => true, 'tutorial' => false ),
                    )
                )
            );

            foreach ($players as $player) {
                $response['playdata']['characters'][] = array(
                    'worldid' => 0,
                    'name' => $player['name'],
                    'ismale' => ($player['sex'] === 1) ? true : false,
                    'tutorial' => false,
                    'level' => intval($player['level']),
                    'vocation' => vocation_id_to_name($player['vocation']),
                    'outfitid' => intval($player['looktype']),
                    'headcolor' => intval($player['lookhead']),
                    'torsocolor' => intval($player['lookbody']),
                    'legscolor' => intval($player['looklegs']),
                    'detailcolor' => intval($player['lookfeet']),
                    'addonsflags' => intval($player['lookaddons']),
                    'ishidden' => intval($player['deletion']) === 1,
                    'istournamentparticipant' => false,
                    'remainingdailytournamentplaytime' => 0
                );
            }

            //error_log("= SESSION KEY: " . $response['session']['sessionkey']);
            die(json_encode($response));
        } else {
            jsonError("Character list is empty.");
        }
    } else {
        jsonError("Unrecognized event.");
    }
} // End client 11 loginWebService

logged_in_redirect();
include 'layout/overall/header.php';

if (empty($_POST) === false) {

    if ($config['log_ip']) {
        znote_visitor_insert_detailed_data(5);
    }

    $username = $_POST['username'];
    $password = $_POST['password'];

    if (empty($username) || empty($password)) {
        $errors[] = 'You need to enter a username and password.';
    } else if (strlen($username) > 32 || strlen($password) > 64) {
            $errors[] = 'Username or password is too long.';
    } else if (user_exist($username) === false) {
        $errors[] = 'Failed to authorize your account, are the details correct, have you <a href=\'register.php\'>register</a>ed?';
    } /*else if (user_activated($username) === false) {
        $errors[] = 'You havent activated your account! Please check your email. <br>Note it may appear in your junk/spam box.';
    } */else if ($config['use_token'] && !Token::isValid($_POST['token'])) {
        Token::debug($_POST['token']);
        $errors[] = 'Token is invalid.';
    } else {

        // Starting loging
        if ($config['ServerEngine'] == 'TFS_02' || $config['ServerEngine'] == 'OTHIRE' || $config['ServerEngine'] == 'TFS_10') $login = user_login($username, $password);
        else if ($config['ServerEngine'] == 'TFS_03') $login = user_login_03($username, $password);
        else $login = false;
        if ($login === false) {
            $errors[] = 'Username and password combination is wrong.';
        } else {
            // Check if user have access to login
            $status = false;
            if ($config['mailserver']['register']) {
                $authenticate = mysql_select_single("SELECT `id` FROM `znote_accounts` WHERE `account_id`='$login' AND `active`='1' LIMIT 1;");
                if ($authenticate !== false) {
                    $status = true;
                } else {
                    $errors[] = "Your account is not activated. An email should have been sent to you when you registered. Please find it and click the activation link to activate your account.";
                }
            } else $status = true;

            if ($status) {
                // Regular login success, now lets check authentication token code
                if ($config['ServerEngine'] == 'TFS_10' && $config['twoFactorAuthenticator']) {
                    require_once("engine/function/rfc6238.php");

                    // Two factor authentication code / token
                    $authcode = (isset($_POST['authcode'])) ? getValue($_POST['authcode']) : false;

                    // Load secret values from db
                    $query = mysql_select_single("SELECT `a`.`secret` AS `secret`, `za`.`secret` AS `znote_secret` FROM `accounts` AS `a` INNER JOIN `znote_accounts` AS `za` ON `a`.`id` = `za`.`account_id` WHERE `a`.`id`='".(int)$login."' LIMIT 1;");

                    // If account table HAS a secret, we need to validate it
                    if ($query['secret'] !== NULL) {

                        // Validate the secret first to make sure all is good.
                        if (TokenAuth6238::verify($query['secret'], $authcode) !== true) {
                            $errors[] = "Submitted Two-Factor Authentication token is wrong.";
                            $errors[] = "Make sure to type the correct token from your mobile authenticator.";
                            $status = false;
                        }

                    } else {

                        // secret from accounts table is null/not set. Perhaps we can activate it:
                        if ($query['znote_secret'] !== NULL && $authcode !== false && !empty($authcode)) {

                            // Validate the secret first to make sure all is good.
                            if (TokenAuth6238::verify($query['znote_secret'], $authcode)) {
                                // Success, enable the 2FA system
                                mysql_update("UPDATE `accounts` SET `secret`= '".$query['znote_secret']."' WHERE `id`='$login';");
                            } else {
                                $errors[] = "Activating Two-Factor authentication failed.";
                                $errors[] = "Try to login without token and configure your app properly.";
                                $errors[] = "Submitted Two-Factor Authentication token is wrong.";
                                $errors[] = "Make sure to type the correct token from your mobile authenticator.";
                                $status = false;
                            }
                        }
                    }
                } // End tfs 1.0+ with 2FA auth

                if ($status) {
                    setSession('user_id', $login);

                    // if IP is not set (etc acc created before Znote AAC was in use)
                    $znote_data = user_znote_account_data($login, 'ip');
                    if ($znote_data['ip'] == 0) {
                        $update_data = array(
                        'ip' => getIPLong(),
                        );
                        user_update_znote_account($update_data);
                    }

                    // Send them to myaccount.php
                    header('Location: myaccount.php');
                    exit();
                }
            }
        }
    }
} else {
    header('Location: index.php');
}

if (empty($errors) === false) {
    ?>
    <h2>We tried to log you in, but...</h2>
    <?php
    header("HTTP/1.1 401 Not Found");
    echo output_errors($errors);
}

include 'layout/overall/footer.php'; ?>
Post automatically merged:

Config.php (MyAAC)
Could not paste it here since it's over 25000 lines, so i'll paste it in pastebin :D
 
Back
Top