• 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
19
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 :)
 

Ramirow

Veteran OT User
Joined
Aug 22, 2009
Messages
573
Solutions
15
Reaction score
281
Location
Argentina
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
 

Evil Puncker

prolonged absenteeism
TFS Developer
Joined
May 30, 2009
Messages
7,952
Solutions
203
Reaction score
3,780
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.
 
OP
OP
Sasyia

Sasyia

Member
Joined
Mar 9, 2020
Messages
42
Solutions
3
Reaction score
19
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"
 

Evil Puncker

prolonged absenteeism
TFS Developer
Joined
May 30, 2009
Messages
7,952
Solutions
203
Reaction score
3,780
you will never be able to connect with 12.x client to tfs 1.3 (the official one), and about 10.98, are you using otland ipchanger?
 

Boy67

Well-Known Member
Joined
Jul 4, 2007
Messages
241
Solutions
11
Reaction score
93
Location
England
Try connecting to your server with a normal client + ip changer. If it works, then you know its a problem with your hex edited client.
 
Top