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

Lua Send item to depot offer owner

caquinha

Member
Joined
Aug 8, 2016
Messages
248
Solutions
1
Reaction score
24
I'm using this market system for 8.60
https://otland.net/threads/offline-player-to-player-item-trader-auction-system.51447/

And i need some help to if offer have more then 30 days, it be delete for offers lists and send item back to player depot...
@Stellow made this script to delete offers but it not send item back to owners:

There is a way to convert this script 1.0 to 0.4
https://otland.net/threads/automatic-znote-aac-shop-tfs-1-0.224483/
It send parcel...

Code:
<globalevent name="marketcleaner" type="startup" event="script" value="marketcleaner.lua"/>

marketcleaner.lua
Code:
function onStartup()
   local result = db.getResult("SELECT `id`, `date` FROM `auction_system` ORDER by `date` ASC;")
   local days = 30*3600*24
   local nowtime = os.date('*t')
   if(result:getID() ~= -1) then
     while(true)
       local id = result:getDataInt("id")
       local date = result:getDataInt("date")
       local time= os.time(nowtime) - date
       local duedate = time - days
       if duedate >= 0 then
           -- delete offer
           db.executeQuery("DELETE FROM `auction_system` WHERE `id` = '".. id .."';")
       end
       if not(result:next()) then
           break
       end
   end
   end
   result:free()
end


Anyone know how to help me?
 
Last edited:
Now the script its working? its sending parcel to depot?
Pid is the number of the slot where is the items, example = (pid 1 = left hand) (pid 2 = right hand) etc
pid 101 = depot 1
pid 102 = depot 2 ETC ETC
SID < is the count into the PID
for example if you have 5 "plate armor" on the depot with the "PID" 101 then
plate armor (1) = pid 101, sid 101<
plate armor (2) = pid 101, sid 102<
plate armor (3) = pid 101, sid 103<
plate armor (4) = pid 101, sid 104<
plate armor (5) = pid 101, sid 105< ETC ETC

tell me if the script work, to add the part to send the items without using parcels

It's not work, showing it when expires (when should send the item)
Code:
[17:46:01.689] >> Initializing game state and binding services...
[17:46:03.385] Error during getDataInt(item_id).

[17:46:03.413] [Error - GlobalEvent Interface]
[17:46:03.413] data/globalevents/scripts/marketcleaner.lua:onStartup
[17:46:03.413] Description:
[17:46:03.422] (luaGetCreatureName) Creature not found
3

Carlin

[17:46:03.423] [Error - GlobalEvent Interface]
[17:46:03.423] data/globalevents/scripts/marketcleaner.lua:onStartup
[17:46:03.423] Description:
[17:46:03.423] (luaDoAddContainerItemEx) Container not found

[17:46:03.424] [Error - GlobalEvent Interface]
[17:46:03.424] data/globalevents/scripts/marketcleaner.lua:onStartup
[17:46:03.424] Description:
[17:46:03.425] (luaDoTeleportThing) Thing not found
[17:46:03.647] > Global IP address: 127.0.0.1
 
So pid 101 is DP to town 1, pid 102 is DP to town 2, just to get all clear :D

---

You know how to make that?
No.
pid 1 = town id 1
pid 101 = first container in xxx town
pid 102 = second container in xxx town, or first container inside first container, or simple item inside sid container 102
pid 103 = can be first container inside second container in town xxx

read it
 
Last edited:
'player_depotitems' only save items of pid 101+

pid 1 = town id 1 ??????????????????????????????????

iologidata.cpp

if (pid >= 1 && pid <= 11) {
player->internalAddThing(pid, item);
load inventory items.
You should delete what you wrote.
 
'player_depotitems' only save items of pid 101+

pid 1 = town id 1 ??????????????????????????????????

iologidata.cpp

if (pid >= 1 && pid <= 11) {
player->internalAddThing(pid, item);
load inventory items.
You should delete what you wrote.
DID YOU FIND MY BANANA?

Read it step by step and DONT MAKE A TRASH
 
sid | pid | itemtype | count
104 | 101 | 2647 | 1
Means depot have sid 1, so depot box have pid 1 and sid 101, and all items inside depot box have pid 101

You don't know and don't understand anything.

If you want to add items to someone depot you have to find his depot sid = town id then find coresponding pid, then add items to his depot with pid equal to the number.
If he do it like you said, it will be bugged as hell. Becouse if new player opens depot in second town for the first time, pid 101 will be in second town not first (main).
 
you make open the server and delete all the items inside the depot of the city 1 and make a test.
result=
using tfs 1.2 latest sources.

1, i make 6 "Containers" .
2, save 3 containers inside the depot.
3, save 1 container inside the first container on the depot.
4, save 1 container inside the second container on the depot.
5, save 1 container inside the third container on the depot.

3d4731ef14856e29bce590275dd06f7bo.png


d686c041a84d8ffcceb59b43a250285eo.png

the Three containers saved on the depot have THE SAME PID so, if we need to save the items in the depot 1 = pid 101.
the others container saved inside other container saved on the depot have diferent pids. we dont need this pid.
 
Put items there. Empty container have nothing in difference between normal items like torch, for example. Noob. Go back to the banana post.
 
Put items there. Empty container have nothing in difference between normal items like torch, for example. Noob. Go back to the banana post.

13:50 You see a letter.
It weighs 0.50 oz.
Item ID: 110

79d87259cbabd2c60edb1c11987f5000o.png


ORANGE = 3 letters inside DEPOT 1
BLUE = 3 "containers" inside DEPOT 1
GREEN = 3 "containers" inside CONTAINERS inside DEPOT 1

Nothing to say. wasting time.
RESULT OF ALL THIS CONVERSATION WITH YOU,
all the items saved on the depot of the town 1 have the pid 101.

DATA: you need to fix your banana.

im not going to post more things in this post. (ask to @andu )
good luck with your broken banana.

caquinha send me pm if you need the script.
 
Last edited:
Here is the logic and how it should looks like. On heavy loaded servers it needs to be executed partially becouse if you send tons of queries your engine may corrupt your db. The script you made yourself was very good with one exception, cid works only on online players. So, you had to check player_id via db queries, not cid. Also making milions of parcels at the same time is bad idea. It's like 'the best way to self DDoSing'. Sing sing sing XD.

This script works exactly like that:
Code:
    1. checks expired auctions
    2. checks player's id of expired auction
    3. checks player's town of expired auction
    4. checks if player with id XXX opened his depot yet or have two important lines in db
        4.1. if not:
            4.1.1. !!!script unfinished!!!
                4.1.1.1. should add two new lines, the same as those what are generated by engine when you opens your dp for the first time
                4.1.1.2. repeat point 4
        4.2. if yes:
            4.2.1. checks sids and pids of containers
            4.2.2. adds new item/count equal to expired auction's item/count
            4.2.3. deletes expired auction
    5. ends script if no more expired auctions

For normal players, they will see a new item in blackbox depot, but it will be always in the last slot.

It may contain some code mistakes, but with info up what I wrote, your knowledge and help of people who hates bananas you will fix it very easly.

Code:
-- local banana = knowledge
-- not sure is `town_id` or `town id` and same with `item_id` or `item id` etc

function onStartup()
    local auctions = db.getResult("SELECT `id`, `player`, `date`, `item_id`, `count` FROM `auction_system` ORDER by `date` ASC;")
    local players = db.getResult("SELECT `id`, `town_id` FROM `players`;")
    local expireTime = 24 * 3600 * 1
    local nowTime = os.date('*t')
    if auctions:getID() ~= -1 then
        while(true) do
            local expired = time - expireTime
            if expired >= 0 then
                local a_id = auctions:getDataInt("id")
                local a_player_id = auctions:getDataInt("player")
                local a_itemid = auctions:getDataInt("item_id")
                local a_itemcount = auctions:getDataInt("count")
                local date = auctions:getDataInt("date")
 
                local player_town = players:getDataInt("town_id")
                local time = os.time(nowTime) - date
 
                -- send item back to old owner
                local depot_items = db.getResult("SELECT `sid` FROM `player_depotitems` WHERE `player_id` = `"..a_player_id.."` AND `pid` = `"..player_town.."`;")
                if depot_items:getID() ~= -1 then
                    local depotBlackBoxSid = depot_items:getDataInt("sid")
                    local black_depotbox_items = db.getResult("SELECT `sid` FROM `player_depotitems` WHERE `player_id` = `"..a_player_id.."` AND `pid` = `"..depotBlackBoxSid.."` ORDER by `sid` ASC;")
                    local newSid = #black_depotbox_items + 1 -- not sure this is the way to check it
                    db.executeQuery("INSERT INTO `player_depotitems` (`player_id`, `sid`, `pid`, `itemtype`, `count`) VALUES ("..a_player_id..", "..newSid..", "..depotBlackBoxSid..", "..a_itemid..", "..a_itemcount..")")
                    -- delete item
                    db.executeQuery("DELETE FROM `auction_system` WHERE `id` = '"..a_id.."';")
                else
                    -- if player doesnt opened his depo yet, create new two lines in db then execute the same code up
                    -- bla bla bla
                    -- bla bla bla
                end
            end
            if not(auctions:next()) then
                break
            end
        end
        auctions:free()
    end
    return true
end

RESULT OF ALL THIS CONVERSATION WITH YOU,
Result is: you didn't found banana.
 
Last edited:
After talking with other OTS developer, we noticed that large amount of db queries executed via lua will often corrupt db. And there will be alot of queries, becouse all expired auctions will be fixed at startup. It's recommended to use method used in newer Tibia with Cipsoft's market. In engines for newer Tibia is auction cleaner inside sources, this method protects db from corrupting. Keep this in mind, that if you decide to use any lua code we wrote here, it may corrupt your database (becouse is like self ddosing + overflowing buffer) if it executed for large amount of auctions.

We tried to launch those scripts on low CPU machine with 100 expired auctions. Almost everytime db got corrupted.

Atm, I recommend to do a backup of your db.
 
After talking with other OTS developer, we noticed that large amount of db queries executed via lua will often corrupt db. And there will be alot of queries, becouse all expired auctions will be fixed at startup. It's recommended to use method used in newer Tibia with Cipsoft's market. In engines for newer Tibia is auction cleaner inside sources, this method protects db from corrupting. Keep this in mind, that if you decide to use any lua code we wrote here, it may corrupt your database (becouse is like self ddosing + overflowing buffer) if it executed for large amount of auctions.

We tried to launch those scripts on low CPU machine with 100 expired auctions. Almost everytime db got corrupted.

Atm, I recommend to do a backup of your db.

LOL who you was talking for?

This auction system is to 0.3.6/0.4 servers (tibia 8x)

There is the problem to execute querys on LUA?
If there is a problem to execute a lot, why no create a waiter, timer idk
Because it don't like to make so sense, if have, maybe there is a right way to do it
 
LOL who you was talking for?

This auction system is to 0.3.6/0.4 servers (tibia 8x)

There is the problem to execute querys on LUA?
If there is a problem to execute a lot, why no create a waiter, timer idk
Because it don't like to make so sense, if have, maybe there is a right way to do it

This auction system have nothing to do with it. While auction cleaner script, which we talking about here, yes. Becouse it is executed at startup. So, it will send many queries at the same time.
On heavy loaded servers it needs to be executed partially
Exactly like that. The best option will be putting this cleaner inside sources, like TFS' devs did with newer versions for newer Tibia. Or, executing it in globalevents every xxx time to reduce load. Still not best solution. Also on one similar topic, someone said something about doing it trought cylinder, idk what he wanted to tell but he agreed with that - sending alot of queries may be bad idea.
Always C++ will do it better then LUA.
 
Here is the logic and how it should looks like. On heavy loaded servers it needs to be executed partially becouse if you send tons of queries your engine may corrupt your db. The script you made yourself was very good with one exception, cid works only on online players. So, you had to check player_id via db queries, not cid. Also making milions of parcels at the same time is bad idea. It's like 'the best way to self DDoSing'. Sing sing sing XD.

This script works exactly like that:
Code:
    1. checks expired auctions
    2. checks player's id of expired auction
    3. checks player's town of expired auction
    4. checks if player with id XXX opened his depot yet or have two important lines in db
        4.1. if not:
            4.1.1. !!!script unfinished!!!
                4.1.1.1. should add two new lines, the same as those what are generated by engine when you opens your dp for the first time
                4.1.1.2. repeat point 4
        4.2. if yes:
            4.2.1. checks sids and pids of containers
            4.2.2. adds new item/count equal to expired auction's item/count
            4.2.3. deletes expired auction
    5. ends script if no more expired auctions

For normal players, they will see a new item in blackbox depot, but it will be always in the last slot.

It may contain some code mistakes, but with info up what I wrote, your knowledge and help of people who hates bananas you will fix it very easly.

Code:
-- local banana = knowledge
-- not sure is `town_id` or `town id` and same with `item_id` or `item id` etc

function onStartup()
    local auctions = db.getResult("SELECT `id`, `player`, `date`, `item_id`, `count` FROM `auction_system` ORDER by `date` ASC;")
    local players = db.getResult("SELECT `id`, `town_id` FROM `players`;")
    local expireTime = 24 * 3600 * 1
    local nowTime = os.date('*t')
    if auctions:getID() ~= -1 then
        while(true) do
            local expired = time - expireTime
            if expired >= 0 then
                local a_id = auctions:getDataInt("id")
                local a_player_id = auctions:getDataInt("player")
                local a_itemid = auctions:getDataInt("item_id")
                local a_itemcount = auctions:getDataInt("count")
                local date = auctions:getDataInt("date")
 
                local player_town = players:getDataInt("town_id")
                local time = os.time(nowTime) - date
 
                -- send item back to old owner
                local depot_items = db.getResult("SELECT `sid` FROM `player_depotitems` WHERE `player_id` = `"..a_player_id.."` AND `pid` = `"..player_town.."`;")
                if depot_items:getID() ~= -1 then
                    local depotBlackBoxSid = depot_items:getDataInt("sid")
                    local black_depotbox_items = db.getResult("SELECT `sid` FROM `player_depotitems` WHERE `player_id` = `"..a_player_id.."` AND `pid` = `"..depotBlackBoxSid.."` ORDER by `sid` ASC;")
                    local newSid = #black_depotbox_items + 1 -- not sure this is the way to check it
                    db.executeQuery("INSERT INTO `player_depotitems` (`player_id`, `sid`, `pid`, `itemtype`, `count`) VALUES ("..a_player_id..", "..newSid..", "..depotBlackBoxSid..", "..a_itemid..", "..a_itemcount..")")
                    -- delete item
                    db.executeQuery("DELETE FROM `auction_system` WHERE `id` = '"..a_id.."';")
                else
                    -- if player doesnt opened his depo yet, create new two lines in db then execute the same code up
                    -- bla bla bla
                    -- bla bla bla
                end
            end
            if not(auctions:next()) then
                break
            end
        end
        auctions:free()
    end
    return true
end


Result is: you didn't found banana.
hiho, I'd just like to point out that not using a variable showcasing the condition is bad practice and results in bad readability. Surely it was an example, and it works but it will look more clear. Also, try to remove irrelevant comments.
 
This auction system have nothing to do with it. While auction cleaner script, which we talking about here, yes. Becouse it is executed at startup. So, it will send many queries at the same time.

Exactly like that. The best option will be putting this cleaner inside sources, like TFS' devs did with newer versions for newer Tibia. Or, executing it in globalevents every xxx time to reduce load. Still not best solution. Also on one similar topic, someone said something about doing it trought cylinder, idk what he wanted to tell but he agreed with that - sending alot of queries may be bad idea.
Always C++ will do it better then LUA.

Yeah, the script official don't have a clean function, but the owner was thinking to do it, thats why he saved date...
I like this script, but its unusable in a right server who don't reset, imagine 1 year to offers never cleaned

I don't understand why the samething on sources should be better then in LUA script too
Could you show to us how should be on sources your best way? 0.4/0.3.6 ... anyone 8.6
 
Back
Top