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

Have problem with player.lua and login.lua interfering with eachother.

Batalj

Member
Joined
May 26, 2017
Messages
51
Solutions
1
Reaction score
13
Hello! So I have a problem that I have tried to solve myself.

It all started with that I wanted to get npcs to work on the server, which made me swap out some npc/lib files and lib/lib files to get storage etc to work. Now to the problem.


Here is my errorcode which makes me unavailable to login:
1633610107315.png



player.lua
Lua:
local foodCondition = Condition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)

function Player.feed(self, food)
    local condition = self:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
    if condition then
        condition:setTicks(condition:getTicks() + (food * 1000))
    else
        local vocation = self:getVocation()
        if not vocation then
            return nil
        end

        foodCondition:setTicks(food * 1000)
        foodCondition:setParameter(CONDITION_PARAM_HEALTHGAIN, vocation:getHealthGainAmount())
        foodCondition:setParameter(CONDITION_PARAM_HEALTHTICKS, vocation:getHealthGainTicks() * 1000)
        foodCondition:setParameter(CONDITION_PARAM_MANAGAIN, vocation:getManaGainAmount())
        foodCondition:setParameter(CONDITION_PARAM_MANATICKS, vocation:getManaGainTicks() * 1000)

        self:addCondition(foodCondition)
    end
    return true
end

function Player.getClosestFreePosition(self, position, extended)
    if self:getGroup():getAccess() and self:getAccountType() >= ACCOUNT_TYPE_GOD then
        return position
    end
    return Creature.getClosestFreePosition(self, position, extended)
end

function Player.getDepotItems(self, depotId)
    return self:getDepotChest(depotId, true):getItemHoldingCount()
end

function Player.hasFlag(self, flag)
    return self:getGroup():hasFlag(flag)
end

function Player.getLossPercent(self)
    local blessings = 0
    local lossPercent = {
        [0] = 100,
        [1] = 70,
        [2] = 45,
        [3] = 25,
        [4] = 10,
        [5] = 0
    }

    for i = 1, 5 do
        if self:hasBlessing(i) then
            blessings = blessings + 1
        end
    end
    return lossPercent[blessings]
end

function Player.getPremiumTime(self)
    return math.max(0, self:getPremiumEndsAt() - os.time())
end

function Player.setPremiumTime(self, seconds)
    self:setPremiumEndsAt(os.time() + seconds)
    return true
end

function Player.addPremiumTime(self, seconds)
    self:setPremiumTime(self:getPremiumTime() + seconds)
    return true
end

function Player.removePremiumTime(self, seconds)
    local currentTime = self:getPremiumTime()
    if currentTime < seconds then
        return false
    end

    self:setPremiumTime(currentTime - seconds)
    return true
end

function Player.getPremiumDays(self)
    return math.floor(self:getPremiumTime() / 86400)
end

function Player.addPremiumDays(self, days)
    return self:addPremiumTime(days * 86400)
end

function Player.removePremiumDays(self, days)
    return self:removePremiumTime(days * 86400)
end

function Player.isPremium(self)
     return isPremium(self) > 0 or configManager.getBoolean(configKeys.FREE_PREMIUM) or self:hasFlag(PlayerFlag_IsAlwaysPremium)
end

function Player.sendCancelMessage(self, message)
    if type(message) == "number" then
        message = Game.getReturnMessage(message)
    end
    return self:sendTextMessage(MESSAGE_STATUS_SMALL, message)
end

function Player.isUsingOtClient(self)
    return self:getClient().os >= CLIENTOS_OTCLIENT_LINUX
end

function Player.sendExtendedOpcode(self, opcode, buffer)
    if not self:isUsingOtClient() then
        return false
    end

    local networkMessage = NetworkMessage()
    networkMessage:addByte(0x32)
    networkMessage:addByte(opcode)
    networkMessage:addString(buffer)
    networkMessage:sendToPlayer(self)
    networkMessage:delete()
    return true
end

APPLY_SKILL_MULTIPLIER = true
local addSkillTriesFunc = Player.addSkillTries
function Player.addSkillTries(...)
    APPLY_SKILL_MULTIPLIER = false
    local ret = addSkillTriesFunc(...)
    APPLY_SKILL_MULTIPLIER = true
    return ret
end

local addManaSpentFunc = Player.addManaSpent
function Player.addManaSpent(...)
    APPLY_SKILL_MULTIPLIER = false
    local ret = addManaSpentFunc(...)
    APPLY_SKILL_MULTIPLIER = true
    return ret
end

-- Always pass the number through the isValidMoney function first before using the transferMoneyTo
function Player.transferMoneyTo(self, target, amount)
    if not target then
        return false
    end

    -- See if you can afford this transfer
    local balance = self:getBankBalance()
    if amount > balance then
        return false
    end

    -- See if player is online
    local targetPlayer = Player(target.guid)
    if targetPlayer then
        targetPlayer:setBankBalance(targetPlayer:getBankBalance() + amount)
    else
        db.query("UPDATE `players` SET `balance` = `balance` + " .. amount .. " WHERE `id` = '" .. target.guid .. "'")
    end

    self:setBankBalance(self:getBankBalance() - amount)
    return true
end

function Player.canCarryMoney(self, amount)
    -- Anyone can carry as much imaginary money as they desire
    if amount == 0 then
        return true
    end

    -- The 3 below loops will populate these local variables
    local totalWeight = 0
    local inventorySlots = 0

    -- Add crystal coins to totalWeight and inventorySlots
    local type_crystal = ItemType(ITEM_CRYSTAL_COIN)
    local crystalCoins = math.floor(amount / 10000)
    if crystalCoins > 0 then
        amount = amount - (crystalCoins * 10000)
        while crystalCoins > 0 do
            local count = math.min(100, crystalCoins)
            totalWeight = totalWeight + type_crystal:getWeight(count)
            crystalCoins = crystalCoins - count
            inventorySlots = inventorySlots + 1
        end
    end

    -- Add platinum coins to totalWeight and inventorySlots
    local type_platinum = ItemType(ITEM_PLATINUM_COIN)
    local platinumCoins = math.floor(amount / 100)
    if platinumCoins > 0 then
        amount = amount - (platinumCoins * 100)
        while platinumCoins > 0 do
            local count = math.min(100, platinumCoins)
            totalWeight = totalWeight + type_platinum:getWeight(count)
            platinumCoins = platinumCoins - count
            inventorySlots = inventorySlots + 1
        end
    end

    -- Add gold coins to totalWeight and inventorySlots
    local type_gold = ItemType(ITEM_GOLD_COIN)
    if amount > 0 then
        while amount > 0 do
            local count = math.min(100, amount)
            totalWeight = totalWeight + type_gold:getWeight(count)
            amount = amount - count
            inventorySlots = inventorySlots + 1
        end
    end

    -- If player don't have enough capacity to carry this money
    if self:getFreeCapacity() < totalWeight then
        return false
    end

    -- If player don't have enough available inventory slots to carry this money
    local backpack = self:getSlotItem(CONST_SLOT_BACKPACK)
    if not backpack or backpack:getEmptySlots(true) < inventorySlots then
        return false
    end
    return true
end

function Player.withdrawMoney(self, amount)
    local balance = self:getBankBalance()
    if amount > balance or not self:addMoney(amount) then
        return false
    end

    self:setBankBalance(balance - amount)
    return true
end

function Player.depositMoney(self, amount)
    if not self:removeMoney(amount) then
        return false
    end

    self:setBankBalance(self:getBankBalance() + amount)
    return true
end

function Player.removeTotalMoney(self, amount)
    local moneyCount = self:getMoney()
    local bankCount = self:getBankBalance()
    if amount <= moneyCount then
        self:removeMoney(amount)
        return true
    elseif amount <= (moneyCount + bankCount) then
        if moneyCount ~= 0 then
            self:removeMoney(moneyCount)
            local remains = amount - moneyCount
            self:setBankBalance(bankCount - remains)
            self:sendTextMessage(MESSAGE_INFO_DESCR, ("Paid %d from inventory and %d gold from bank account. Your account balance is now %d gold."):format(moneyCount, amount - moneyCount, self:getBankBalance()))
            return true
        else
            self:setBankBalance(bankCount - amount)
            self:sendTextMessage(MESSAGE_INFO_DESCR, ("Paid %d gold from bank account. Your account balance is now %d gold."):format(amount, self:getBankBalance()))
            return true
        end
    end
    return false
end

function Player.addLevel(self, amount, round)
    round = round or false
    local level, amount = self:getLevel(), amount or 1
    if amount > 0 then
        return self:addExperience(Game.getExperienceForLevel(level + amount) - (round and self:getExperience() or Game.getExperienceForLevel(level)))
    else
        return self:removeExperience(((round and self:getExperience() or Game.getExperienceForLevel(level)) - Game.getExperienceForLevel(level + amount)))
    end
end

function Player.addMagicLevel(self, value)
    local currentMagLevel = self:getBaseMagicLevel()
    local sum = 0

    if value > 0 then
        while value > 0 do
            sum = sum + self:getVocation():getRequiredManaSpent(currentMagLevel + value)
            value = value - 1
        end

        return self:addManaSpent(sum - self:getManaSpent())
    else
        value = math.min(currentMagLevel, math.abs(value))
        while value > 0 do
            sum = sum + self:getVocation():getRequiredManaSpent(currentMagLevel - value + 1)
            value = value - 1
        end

        return self:removeManaSpent(sum + self:getManaSpent())
    end
end

function Player.addSkillLevel(self, skillId, value)
    local currentSkillLevel = self:getSkillLevel(skillId)
    local sum = 0

    if value > 0 then
        while value > 0 do
            sum = sum + self:getVocation():getRequiredSkillTries(skillId, currentSkillLevel + value)
            value = value - 1
        end

        return self:addSkillTries(skillId, sum - self:getSkillTries(skillId))
    else
        value = math.min(currentSkillLevel, math.abs(value))
        while value > 0 do
            sum = sum + self:getVocation():getRequiredSkillTries(skillId, currentSkillLevel - value + 1)
            value = value - 1
        end

        return self:removeSkillTries(skillId, sum + self:getSkillTries(skillId), true)
    end
end

function Player.addSkill(self, skillId, value, round)
    if skillId == SKILL_LEVEL then
        return self:addLevel(value, round or false)
    elseif skillId == SKILL_MAGLEVEL then
        return self:addMagicLevel(value)
    end
    return self:addSkillLevel(skillId, value)
end

function Player.getWeaponType(self)
    local weapon = self:getSlotItem(CONST_SLOT_LEFT)
    if weapon then
        return weapon:getType():getWeaponType()
    end
    return WEAPON_NONE
end

Login.lua
Code:
function onLogin(player)
    local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
    if player:getLastLoginSaved() <= 0 then
        loginStr = loginStr .. " Please choose your outfit."
        player:sendOutfitWindow()
    else
        if loginStr ~= "" then
            player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
        end

        loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved()))
    end
    player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)

    -- Stamina
    nextUseStaminaTime[player.uid] = 0

    -- Promotion
    local vocation = player:getVocation()
    local promotion = vocation:getPromotion()
    if player.isPremium() == 0 then
        local value = player:getStorageValue(PlayerStorageKeys.promotion)
        if value == 1 then
            player:setVocation(promotion)
        end
    elseif not promotion then
        player:setVocation(vocation:getDemotion())
    end

    -- Events
    player:registerEvent("PlayerDeath")
    player:registerEvent("DropLoot")
    return true
end
 
Solution
Use master schema.sql

Is your MyAAC configured for TFS 1.4?
I am using the latest one here: Releases · slawkens/myaac (https://github.com/slawkens/myaac/releases)

Tried the master schema.sql, still gives the same error... Maybe its time for a new compile and datapack... Is there any newer on Github? I use this one_ GitHub - otland/forgottenserver: A free and open-source MMORPG server emulator written in C++ (https://github.com/otland/forgottenserver)

I decided to try another distropack and 1.4 instead. thanks for everything!
Thank you! Now I have a new problem...


1633612913342.png

Line 544 in compat.lua:
Lua:
function isPremium(cid) local p = Player(cid) return p and p:isPremium() or false end

Line 95 in player.lua:
Lua:
     return isPremium(self) > 0 or configManager.getBoolean(configKeys.FREE_PREMIUM) or self:hasFlag(PlayerFlag_IsAlwaysPremium)
 
Last edited:
TFS VERSION?

Try (player.lua)
Lua:
function Player.isPremium(self)
    return self:getPremiumTime() > 0 or configManager.getBoolean(configKeys.FREE_PREMIUM) or self:hasFlag(PlayerFlag_IsAlwaysPremium)
end
 
Last edited:
TFS VERSION?

Try (player.lua)
Lua:
function Player.isPremium(self)
    return self:getPremiumTime() > 0 or configManager.getBoolean(configKeys.FREE_PREMIUM) or self:hasFlag(PlayerFlag_IsAlwaysPremium)
end
It solved the compat error. I am using TFS 1.3.

New error codes:
1633615253160.png
 
player:getPremiumEndsAt() is defined in C++ in some '1.3' version (between 1.2 and 1.4):

It requires database structure changes. Full changelog:
Did add those in the database, however now I get alot of errors, most of which are connectet to "enum"

1633965781037.png
Post automatically merged:

Still looking for an solution, seems to be bugged...
 
Last edited:
Ive managed to fix the issue with compiling. However now when I try to talk to task npc and promotion npc it gives me the following error:
1634033959191.png

Ive tried to check if everything is insert corretctly according to "Better premium time handling" and it seems everything is put correctly there. Anyone who have a clue where in the database I have to change something to make this work?

Does it have to do with Database.cpp since of this?:
Lua:
std::string DBResult::getString(const std::string& s) const
{
    auto it = listNames.find(s);
    if (it == listNames.end()) {
        std::cout << "[Error - DBResult::getString] Column '" << s << "' does not exist in result set." << std::endl;
        return std::string();
    }

    if (row[it->second] == nullptr) {
        return std::string();
    }
 
Last edited:
Does this mean its wrong somewhere in the .exe file/compiling or in the data pack? Can Probebly try solve myself if someone know where the error is.
 
Yeah, I have deleted the database a couple of times and reloaded both schema.sql and the www file i use. Could it be that the Myaac-master is interfering with this premium_Ends_At at some way so it messes it up? It says it support it on Github, but who knows since its loading a couple of files to the database when installing.

I still get this error when I logging into a premium account, not free account:
1634079248112.png
It gives no errors at all not when starting up and database 'account' looks like this:
1634079300863.png
I dont see why the error still exists when no errors are reported more than when I logging into a character with premium account.
 
Use master schema.sql

Is your MyAAC configured for TFS 1.4?
I am using the latest one here: Releases · slawkens/myaac (https://github.com/slawkens/myaac/releases)

Tried the master schema.sql, still gives the same error... Maybe its time for a new compile and datapack... Is there any newer on Github? I use this one_ GitHub - otland/forgottenserver: A free and open-source MMORPG server emulator written in C++ (https://github.com/otland/forgottenserver)

I decided to try another distropack and 1.4 instead. thanks for everything!
 
Last edited:
Solution
Back
Top