• 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!

Login failed. Tibia might be down for maintenance.

Sasyia

Member
Joined
Mar 9, 2020
Messages
42
Solutions
3
Reaction score
20
Hello,
Im getting error "Login failed. Tibia might be down for maintenance. Please try again later." when trying to connect to local server. Im using TFS 1.3
My ZNOTTE login.php:
PHP:
<?php
require_once 'engine/init.php';

// Client 11 loginWebService
// DEV: Uncomment all //error_log lines and tail error.log file to see communication from and to client.
// ...: Configure webserver to don't display PHP errors/warnings so the client can parse the json response.
if($_SERVER['HTTP_USER_AGENT'] == "Mozilla/5.0" && $config['ServerEngine'] === 'TFS_10' && $config['login_web_service'] == true) {

    function sendError($message, $code = 3) {
        $response = json_encode(array('errorCode' => $code, 'errorMessage' => $message));
        error_log("\nServer = " . $response . "\n-");
        die($response);
    }

    function sendMessage($message) {
        $response = json_encode($message);
        error_log("\nServer = " . $response . "\n\n-");
        die($response);
    }


    header("Content-Type: application/json");
    $input = file_get_contents("php://input");
    error_log("\n\n\nClient = " . $input . "\n");

    $client = json_decode($input);

    if (!isset($client->type)) {
        sendError("Type missing.");
    }

    switch($client->type) {
        // {"count":0,"isreturner":true,"offset":0,"showrewardnews":false,"type":"news"}
        case "cacheinfo":
            // {"type":"cacheinfo"}
            sendMessage(array(
                'playersonline' => (int)user_count_online(),
                'twitchstreams' => 0,
                'twitchviewer' => 0,
                'gamingyoutubestreams' => 0,
                'gamingyoutubeviewer' => 0
            ));
            break;

        case 'eventschedule':
            // {"type":"eventschedule"}
            $eventlist = [];
                $file_path = $config['server_path'] . 'data/XML/events.xml';
                /*  <?xml version="1.0" encoding="UTF-8"?>
                    <events>
                        <event name="Otservbr example 1" startdate="11/03/2020" enddate="11/30/2020" >
                            <ingame exprate="250" lootrate="200" spawnrate="100" skillrate="200" />
                            <description description="Otserver br example 1 description double exp and a half, double loot !chance!, regular spawn and double skill" />
                            <colors colordark="#235c00" colorlight="#2d7400" />
                            <details displaypriority="6" isseasonal="0" specialevent="0" />
                        </event>
                        <event name="Otservbr example 2" startdate="12/01/2020" enddate="12/26/2020" >
                            <ingame exprate="50" lootrate="300" spawnrate="150" skillrate="100" />
                            <description description="Otserver br example 2 description 50% less exp, triple loot !chance!, 50% faster spawn and regular skill" />
                            <colors colordark="#735D10" colorlight="#8B6D05" />
                            <details displaypriority="6" isseasonal="0" specialevent="0" />
                        </event>
                    </events>
                */
                if (!file_exists($file_path)) {
                    sendMessage(array(
                        'eventlist' => array()
                    ));
                }
                $xml = new DOMDocument;
                $xml->load($file_path);
                $tableevent = $xml->getElementsByTagName('event');

                if (!function_exists("parseEvent")) {
                    function parseEvent($table1, $date, $table2) {
                        if ($table1) {
                            if ($date) {
                                if ($table2) {
                                    $date = $table1->getAttribute('startdate');
                                    return date_create("{$date}")->format('U');
                                } else {
                                    $date = $table1->getAttribute('enddate');
                                    return date_create("{$date}")->format('U');
                                }
                            } else {
                                foreach($table1 as $attr) {
                                    if ($attr) {
                                        return $attr->getAttribute($table2);
                                    }
                                }
                            }
                        }
                        return;
                    }
                }

                foreach ($tableevent as $event) {
                    if ($event) {
                        $eventlist[] = array(
                            'colorlight' => parseEvent($event->getElementsByTagName('colors'), false, 'colorlight'),
                            'colordark' => parseEvent($event->getElementsByTagName('colors'), false, 'colordark'),
                            'description' => parseEvent($event->getElementsByTagName('description'), false, 'description'),
                            'displaypriority' => intval(parseEvent($event->getElementsByTagName('details'), false, 'displaypriority')),
                            'enddate' => intval(parseEvent($event, true, false)),
                            'isseasonal' => (intval(parseEvent($event->getElementsByTagName('details'), false, 'isseasonal')) == 1) ? true : false,
                            'name' => $event->getAttribute('name'),
                            'startdate' => intval(parseEvent($event, true, true)),
                            'specialevent' => intval(parseEvent($event->getElementsByTagName('details'), false, 'specialevent'))
                        );
                    }
                }

                sendMessage(array(
                    'eventlist' => $eventlist,
                    'lastupdatetimestamp' => time()
                ));
            break;

        case 'boostedcreature':
            // {"type":"boostedcreature"}
            sendMessage(array(
                //'boostedcreature' => false,
                'raceid' => 219
            ));
            break;

        case 'news':
            // {"count":0,"isreturner":true,"offset":0,"showrewardnews":false,"type":"news"}
            sendMessage(array(
                'gamenews' => array(), // element structure?
                'categorycounts' => array(
                    'support' => 1,
                    'game contents' => 2,
                    'useful info' => 3,
                    'major updates' => 4,
                    'client features' => 5
                ),
                'maxeditdate' => 1590979202
            ));
            break;

        case "login":
            /* {
                'accountname' => 'username',
                "email":"[email protected]",
                'password' => 'superpass',
                'stayloggedin' => true,
                'token' => '123123', (or not set)
                'type' => 'login',
            } */

            $email = (isset($client->email)) ? sanitize($client->email) : false;
            $username = (isset($client->accountname)) ? sanitize($client->accountname) : false;
            $password = SHA1($client->password);
            $token = (isset($client->token)) ? sanitize($client->token) : false;

            $fields = '`id`, `premdays`';
            if ($config['twoFactorAuthenticator']) $fields .= ', `secret`';

            $account = false;

            if ($email !== false) {
                $fields .= ', `name`';
                $account = mysql_select_single("SELECT {$fields} FROM `accounts` WHERE `email`='{$email}' AND `password`='{$password}' LIMIT 1;");
                if ($account !== false) {
                    $username = $account['name'];
                }
            } elseif ($username !== false) {
                $account = mysql_select_single("SELECT {$fields} FROM `accounts` WHERE `name`='{$username}' AND `password`='{$password}' LIMIT 1;");
            }

            if ($account === false) {
                sendError('Wrong username and/or password.');
            }

            if ($config['twoFactorAuthenticator'] === true && $account['secret'] !== null) {
                if ($token === false) {
                    sendError('Submit a valid two-factor authentication token.', 6);
                } else {
                    require_once("engine/function/rfc6238.php");
                    if (TokenAuth6238::verify($account['secret'], $token) !== true) {
                        sendError('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'];
                // Override $config['gameserver'] if server has installed Lua script for loginWebService
                $sql_elements = mysql_select_multi("
                    SELECT
                        `key`,
                        `value`
                    FROM `znote_global_storage`
                    WHERE `key` IN('SERVER_NAME', 'IP', 'GAME_PORT')
                ");
                if ($sql_elements !== false) {
                    foreach ($sql_elements AS $element) {
                        switch ($element['key']) {
                            case 'SERVER_NAME':
                                $gameserver['name'] = $element['value'];
                                break;
                            case 'IP':
                                $gameserver['ip'] = $element['value'];
                                break;
                            case 'GAME_PORT':
                                $gameserver['port'] = (int)$element['value'];
                                break;
                        }
                    }
                }

                $sessionKey = ($email !== false) ? $email."\n".$client->password : $username."\n".$client->password;
                if (isset($account['secret']) && 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
                    );
                }

                sendMessage($response);
            } else {
                sendError("Character list is empty.");
            }
            break;

        default:
            sendError("Unsupported type: " . sanitize($client->type));
    }

} // 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'; ?>
Config.lua:
Lua:
-- Combat settings
-- NOTE: valid values for worldType are: "pvp", "no-pvp" and "pvp-enforced"
worldType = "pvp"
hotkeyAimbotEnabled = true
protectionLevel = 1
killsToRedSkull = 3
killsToBlackSkull = 6
pzLocked = 60000
removeChargesFromRunes = true
removeChargesFromPotions = true
removeWeaponAmmunition = true
removeWeaponCharges = true
timeToDecreaseFrags = 24 * 60 * 60
whiteSkullTime = 15 * 60
stairJumpExhaustion = 2000
experienceByKillingPlayers = false
expFromPlayersLevelRange = 75

-- Connection Config
-- NOTE: maxPlayers set to 0 means no limit
-- NOTE: allowWalkthrough is only applicable to players
ip = "127.0.0.1"
bindOnlyGlobalAddress = false
loginProtocolPort = 7171
gameProtocolPort = 7172
statusProtocolPort = 7171
maxPlayers = 0
motd = "Welcome to The Forgotten Server!"
onePlayerOnlinePerAccount = true
allowClones = false
allowWalkthrough = true
serverName = "Forgotten"
statusTimeout = 5000
replaceKickOnLogin = true
maxPacketsPerSecond = 25

-- 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
-- NOTE: valid values for houseRentPeriod are: "daily", "weekly", "monthly", "yearly"
-- use any other value to disable the rent system
housePriceEachSQM = 1000
houseRentPeriod = "never"
houseOwnedByAccount = false
houseDoorShowPrice = true
onlyInvitedCanMoveHouseItems = true

-- Item Usage
timeBetweenActions = 200
timeBetweenExActions = 1000

-- Map
-- NOTE: set mapName WITHOUT .otbm at the end
mapName = "forgotten"
mapAuthor = "Komic"

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

-- MySQL
mysqlHost = "127.0.0.1"
mysqlUser = "Sasyia"
mysqlPass = "zxc123"
mysqlDatabase = "forgottenserver"
mysqlPort = 3306
mysqlSock = ""

-- Misc.
-- NOTE: classicAttackSpeed set to true makes players constantly attack at regular
-- intervals regardless of other actions such as item (potion) use. This setting
-- may cause high CPU usage with many players and potentially affect performance!
-- NOTE: forceMonsterTypesOnLoad loads all monster types on startup to validate them.
-- You can disable it to save some memory if you don't see any errors at startup.
allowChangeOutfit = true
freePremium = false
kickIdlePlayerAfterMinutes = 15
maxMessageBuffer = 4
emoteSpells = false
classicEquipmentSlots = false
classicAttackSpeed = false
showScriptsLogInConsole = false
showOnlineStatusInCharlist = false
yellMinimumLevel = 2
yellAlwaysAllowPremium = false
forceMonsterTypesOnLoad = true
cleanProtectionZones = false
luaItemDesc = false
showPlayerLogInConsole = true

-- VIP and Depot limits
-- NOTE: you can set custom limits per group in data/XML/groups.xml
vipFreeLimit = 20
vipPremiumLimit = 100
depotFreeLimit = 2000
depotPremiumLimit = 10000

-- World Light
-- NOTE: if defaultWorldLight is set to true the world light algorithm will
-- be handled in the sources. set it to false to avoid conflicts if you wish
-- to make use of the function setWorldLight(level, color)
defaultWorldLight = true

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

-- Experience stages
-- NOTE: to use a flat experience multiplier, set experienceStages to nil
-- minlevel and multiplier are MANDATORY
-- maxlevel is OPTIONAL, but is considered infinite by default
-- to disable stages, create a stage with minlevel 1 and no maxlevel
experienceStages = {
    { minlevel = 1, maxlevel = 8, multiplier = 7 },
    { minlevel = 9, maxlevel = 20, multiplier = 6 },
    { minlevel = 21, maxlevel = 50, multiplier = 5 },
    { minlevel = 51, maxlevel = 100, multiplier = 4 },
    { minlevel = 101, multiplier = 3 }
}

-- Rates
-- NOTE: rateExp is not used if you have enabled stages above
rateExp = 5
rateSkill = 3
rateLoot = 2
rateMagic = 3
rateSpawn = 1

-- Monster Despawn Config
-- despawnRange is the amount of floors a monster can be from its spawn position
-- despawnRadius is how many tiles away it can be from its spawn position
-- removeOnDespawn will remove the monster if true or teleport it back to its spawn position if false
deSpawnRange = 2
deSpawnRadius = 50
removeOnDespawn = true

-- 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 = false

-- Status Server Information
ownerName = ""
ownerEmail = ""
url = "https://otland.net/"
location = "Sweden"
Any help/ideas will be appreciated,
Thanks :)
 
You can try your local ipv4 address then, if you don't know how to find it just do: Windows key + R and type cmd, then in cmd type ipconfig. Look at your network adapter's ipv4 address and try with that ip
 
you using tfs 1.3 or otservbr? please be more specific as tfs 1.3 doesn't need any login.php to work because client 10.98 doesn't use that.
 
You can try your local ipv4 address then, if you don't know how to find it just do: Windows key + R and type cmd, then in cmd type ipconfig. Look at your network adapter's ipv4 address and try with that ip
Still same error =/
you using tfs 1.3 or otservbr? please be more specific as tfs 1.3 doesn't need any login.php to work because client 10.98 doesn't use that.
Im using tfs 1.3 and trying to connect with 12.x client. Where comes to 10.98 im getting error "Server name does not exist"
 
For anyone checking this at this time and date.
If you're using Znote acc + OTBR, you'll need a different login.php which you'll find here:
This will allow you to connect with an x12 series client. Keep in mind, you'll need to configure your config.php's login information.

 
Back
Top