• 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 Checking duplicates value in a table

chiitus

Member
Joined
Jun 1, 2009
Messages
206
Reaction score
12
Hey guys i'm trying to create a anti-dupe system with basic attribute item give by the shop system of gesior acc.
Like the script gives a unique 'tid' to item and i'm trying to use this and the function created by Summ to remove items with the same 'tid' (unique id).

Function by Summ: otland.net/threads/function-get-all-items-by-id-get-all-items-in-slot-by-id.171981/

Shop by Gesior: http://otland.net/threads/gesior2012-items-shop-installation-administration.170654/

The script i'm trying to do:

Code:
function onThink(interval, lastExecution)

local Dupes = {}

for _, pid in ipairs(getPlayersOnline()) do
    for _, item in pairs(getAllItemsById(pid, 2358)) do
            if not Dupes[item] then
                Dupes[item] = true
                table.remove(item, item)
                doRemoveItem(item.uid)
            end
    end
end

return true
end

The error on console:
[Error - GlobalEvent Interface]
data/globalevents/scripts/trackitems.lua:eek:nThink
Description:
data/globalevents/scripts/trackitems.lua:9: bad argument #2 to 'remove' (number expected, got table)
stack traceback:
[C]: in function 'remove'
data/globalevents/scripts/trackitems.lua:9: in function <data/globalevents/scripts/trackitems.lua:1>
[Error - GlobalEvents::think] Couldn't execute event: removeitems

I'm not good handling with tables on LUA, please i need help!
Thanks :)
 
I'm trying to remove the duplicated value, like for each index in table "remove" that is not in table "Dupes" the script will add, so when the script add it will too remove that added index from the original table.
Like, the table "item" will only contains the duplicated values, can you understand?
This what i'm thinking i'm doing, i don't know if i'm doing this right, i'm horrible with tables in .LUA
:/
 
I don't have TFS 0.4/0.36 set up ATM, but I'll try to help. First of all, you need to realize that the "item" variable in the inner loop isn't a table - it is the "current" value of the array you're looping over (the key is "_"). Secondly, the array you're trying to remove items from is temporary and you're trying to remove stuff from it while you're looping over it with a for loop which is usually a bad idea (it's sort of like cutting a branch you're sitting on).

Code:
function onThink(interval, lastExecution)

   local Dupes = {}

   for _, pid in ipairs(getPlayersOnline()) do
      for _, item in pairs(getAllItemsById(pid, 2358)) do
         local tid = getItemAttribute("tid")
         if tid and not Dupes[tid] then
            Dupes[tid] = item.uid
         elseif tid then
             doRemoveItem(item.uid)
         end
      end
end

    return true
end

This should store the uid with a key of tid. If there's an entry for tid already then we remove the item.
Please bear in mind that this script is horribly resource hungry and inefficient. I also wonder why are you wondering about certain items getting duplicated - if you run into such an issue then you're gonna have bigger problems than "only some" items being duplicated ;). As for lua tables - don't worry, they're probably the worst feature of lua as they're trying to be like both arrays and dictionaries in Python so you end up with a lot of confusion amongst newbies ;).
 
Heyyyy!
Sorry for the late :)
I'm tried and get this error:
(luaGetItemAttribute) Item not found

I will make some try, thanks for teach me how handle with tables in LUA :)

EDIT: OHHHHHHHHHHHHH!!!!!!!

I tried:
for _, pid in ipairs(getPlayersOnline()) do
for _, item in pairs(getAllItemsById(pid, 5468)) do
local tid = getItemAttribute(item.uid, "tid")
if tid and not Dupes[tid] then
Dupes[tid] = item.uid
elseif tid then
doRemoveItem(item.uid)
end
end
end

And work perfectly!
Why you say is not good use this system? I really like it, it's working!!
 
Last edited:
The problem with this script is that it will potentially to do tens of thousends(maybe even hundreds) of lua calls when you have, let's say, 100+ players. When you're not using luajit (and IIRC TFS 0.4/0.36 doesn't support it) it's going to lag the server probably for a few seconds. Another problem is that it (obviously) can't track the items of offline players.

P.S. Sorry for that error, I forgot to add the first argument in getItemAttribute(...) ;)
 
The problem with this script is that it will potentially to do tens of thousends(maybe even hundreds) of lua calls when you have, let's say, 100+ players. When you're not using luajit (and IIRC TFS 0.4/0.36 doesn't support it) it's going to lag the server probably for a few seconds. Another problem is that it (obviously) can't track the items of offline players.

P.S. Sorry for that error, I forgot to add the first argument in getItemAttribute(...) ;)

Yes this is true, and if i put this script in a function "onlogin"? To check a single player by time.
You think is better?

A noob question, LUAJIT is much better? Have some TFS for 8.60 client version that have this feature?

You really help me! Thanks :D
 
It's probably a better solution to do the checks on login, however it would probably be best to use an external script/application to query the database during scheduled server maintenance.
As for LuaJIT vs "normal" Lua interpreter - there are some benchmarks on the LuaJIT website. They aren't exactly equivalent to OTS workloads but they give you a rough idea: http://luajit.org/performance_x86.html
Using LuaJIT can yield from 150% up to even 10.000% performance improvment on x64.
 
Back
Top