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

Server only for PACC

Tibia Idle

Premium User
Premium User
Joined
Nov 23, 2023
Messages
117
Reaction score
23
I'm wondering if there is an option in TFS 1.2 to make the server accessible only for players with pacc. I would like only players with pacc to be able to log in. I've checked the config.lua, but there doesn't seem to be any option for this.

Is this functionality built-in by default, or do I need to implement it myself? Any guidance or advice on how to set this up would be greatly appreciated!
 
Solution
creaturescripts/login.lua
if not player:isPremium() then
player:remove()
end

player will get kicked this way.
if you wish to do it properly you would have to do it in the sources where player logs in his character.
Post automatically merged:


C++:
void ProtocolGame::login(const std::string& name, uint32_t accountId, OperatingSystem_t operatingSystem)
{
    // OTCv8 features and extended opcodes
    if (otclientV8 || operatingSystem >= CLIENTOS_OTCLIENT_LINUX) {
        if (otclientV8)
            sendFeatures();
    }
    //dispatcher thread
    Player* foundPlayer = g_game.getPlayerByName(name);
    if (!foundPlayer || g_config.getBoolean(ConfigManager::ALLOW_CLONES)) {
        player = new Player(getThis());
        player->setName(name)...
creaturescripts/login.lua
if not player:isPremium() then
player:remove()
end

player will get kicked this way.
if you wish to do it properly you would have to do it in the sources where player logs in his character.
Post automatically merged:


C++:
void ProtocolGame::login(const std::string& name, uint32_t accountId, OperatingSystem_t operatingSystem)
{
    // OTCv8 features and extended opcodes
    if (otclientV8 || operatingSystem >= CLIENTOS_OTCLIENT_LINUX) {
        if (otclientV8)
            sendFeatures();
    }
    //dispatcher thread
    Player* foundPlayer = g_game.getPlayerByName(name);
    if (!foundPlayer || g_config.getBoolean(ConfigManager::ALLOW_CLONES)) {
        player = new Player(getThis());
        player->setName(name);

        player->incrementReferenceCounter();
        player->setID();

        if (!IOLoginData::preloadPlayer(player, name)) {
            disconnectClient("Your character could not be loaded.");
            return;
        }

        if (IOBan::isPlayerNamelocked(player->getGUID())) {
            disconnectClient("Your character has been namelocked.");
            return;
        }

        if (g_game.getGameState() == GAME_STATE_CLOSING && !player->hasFlag(PlayerFlag_CanAlwaysLogin)) {
            disconnectClient("The game is just going down.\nPlease try again later.");
            return;
        }

        if (g_game.getGameState() == GAME_STATE_CLOSED && !player->hasFlag(PlayerFlag_CanAlwaysLogin)) {
            disconnectClient("Server is currently closed.\nPlease try again later.");
            return;
        }
//warning no config lua option change in this add codes below instead.
        if (!player->isPremium()) {
            disconnectClient("You need to be premium account to play on this world.");
            return;
        }


        if (g_config.getBoolean(ConfigManager::ONE_PLAYER_ON_ACCOUNT) && player->getAccountType() < ACCOUNT_TYPE_GAMEMASTER && g_game.getPlayerByAccount(player->getAccount())) {
            disconnectClient("You may only login with one character\nof your account at the same time.");
            return;
        }

        if (!player->hasFlag(PlayerFlag_CannotBeBanned)) {
            BanInfo banInfo;
            if (IOBan::isAccountBanned(accountId, banInfo)) {
                if (banInfo.reason.empty()) {
                    banInfo.reason = "(none)";
                }

                if (banInfo.expiresAt > 0) {
                    disconnectClient(fmt::format("Your account has been banned until {:s} by {:s}.\n\nReason specified:\n{:s}", formatDateShort(banInfo.expiresAt), banInfo.bannedBy, banInfo.reason));
                } else {
                    disconnectClient(fmt::format("Your account has been permanently banned by {:s}.\n\nReason specified:\n{:s}", banInfo.bannedBy, banInfo.reason));
                }
                return;
            }
        }

        if (std::size_t currentSlot = clientLogin(*player)) {
            uint8_t retryTime = getWaitTime(currentSlot);
            auto output = OutputMessagePool::getOutputMessage();
            output->addByte(0x16);
            output->addString(fmt::format("Too many players online.\nYou are at place {:d} on the waiting list.", currentSlot));
            output->addByte(retryTime);
            send(output);
            disconnect();
            return;
        }

        if (!IOLoginData::loadPlayerById(player, player->getGUID())) {
            disconnectClient("Your character could not be loaded.");
            return;
        }

        player->setOperatingSystem(operatingSystem);

        if (!g_game.placeCreature(player, player->getLoginPosition())) {
            if (!g_game.placeCreature(player, player->getTemplePosition(), false, true)) {
                disconnectClient("Temple position is wrong. Contact the administrator.");
                return;
            }
        }

        if (operatingSystem >= CLIENTOS_OTCLIENT_LINUX) {
            player->registerCreatureEvent("ExtendedOpcode");
        }

        player->lastIP = player->getIP();
        player->lastLoginSaved = std::max<time_t>(time(nullptr), player->lastLoginSaved + 1);
        acceptPackets = true;
    } else {
        if (eventConnect != 0 || !g_config.getBoolean(ConfigManager::REPLACE_KICK_ON_LOGIN)) {
            //Already trying to connect
            disconnectClient("You are already logged in.");
            return;
        }

        if (foundPlayer->client) {
            foundPlayer->disconnect();
            foundPlayer->isConnecting = true;

            eventConnect = g_scheduler.addEvent(createSchedulerTask(1000, std::bind(&ProtocolGame::connect, getThis(), foundPlayer->getID(), operatingSystem)));
        } else {
            connect(foundPlayer->getID(), operatingSystem);
        }
    }
    OutputMessagePool::getInstance().addProtocolToAutosend(shared_from_this());
}
Post automatically merged:

1731490721954.webp

this one works. enjoy :)
Post automatically merged:

for other peoples here is final version:

under the first function(line is where to paste)
add the second one line/function of each code:
protocolgame.cpp
C++:
        if (g_game.getGameState() == GAME_STATE_CLOSED && !player->hasFlag(PlayerFlag_CanAlwaysLogin)) {
            disconnectClient("Server is currently closed.\nPlease try again later.");
            return;
        }

      
if (!player->isPremium() && g_config.getBoolean(ConfigManager::PREMIUM_ONLY_WORLD)) {
    disconnectClient("You need to be premium account to play on this world.");
    return;
}
luascript.cpp
C++:
    registerEnumIn("configKeys", ConfigManager::PLAYER_CONSOLE_LOGS)
    registerEnumIn("configKeys", ConfigManager::PREMIUM_ONLY_WORLD)

configmanager.cpp
C++:
    boolean[PLAYER_CONSOLE_LOGS] = getGlobalBoolean(L, "showPlayerLogInConsole", true);
    boolean[PREMIUM_ONLY_WORLD] = getGlobalBoolean(L, "premiumOnlyWorld", false);
configmanager.h
C++:
    PLAYER_CONSOLE_LOGS,
    PREMIUM_ONLY_WORLD,


config.lua
LUA:
premiumOnlyWorld = true -- only premium players allowed.

enjoy free release otland ;)
 
Last edited:
Solution
Back
Top