AStopher
AStopher

Reputation: 4551

Table Empty when adding content

I'm having a huge problem when I've added content to a table (Lua), where all content in the table suddenly disappears. The table in question holds the data for a banlist (608 entries at present) and is placed within the table by using table.insert, however the lead entry for the user is done as Umbra.Banlist[profileId] = {};. The Umbra.Banlist[profileId] = {}; table alone should mean that there's content within the Umbra.Banlist table. I get no errors when running the code, and when using

    if (#Umbra.Banlist == 0) then
        System.LogAlways(Umbra.Tag.." The Banlist seems to be empty. It seems that some part of loading has failed.");
    end

I get this:

1

I've looked on the web and on this site but there doesn't seem to be any related questions, so I'm posting it here.

This code is part of a server mod for Crysis Wars (see the whole function below), but has the entire Lua library at hand (so don't worry if you don't think your answer won't solve the problem).

The Code:

    Umbra.ReadBans = function()
    self = Umbra;
    System.LogAlways(Umbra.Tag.." Starting banlist read.");
    FileHnd, err = io.open(Root().."Mods/Infinity/System/Read/Banlst.lua", "r");
    if (not FileHnd) then
        System.LogAlways(Umbra.Tag.." Unable to find file 'Banlst.lua'.");
        return;
    end
    for line in FileHnd:lines() do
        local name, profile, ip, domain, reason, date, bannedby = line:match([[Umbra.BanSystem:Add%('(.-)', '(.+)', '(.+)', '(.+)', '(.+)', '(.+)', '(.-)'%);]]);
        if (not name) then
            System.LogAlways(Umbra.Tag.." Failed to read the banlist at line "..count or 0);
            break;
        end
        System.LogAlways(Umbra.Tag.." Banlist; Name: [ "..name.." ], For: [ "..reason.." ], By: [ "..bannedby.." ]");
        --local Msg, Date, Reason, Type, Domain = line:match([[User:Read%( "(.-)", { Date="(.+)"; Reason="(.+)"; Typ="(.+)"; Info="(.+)"; } %);]]);
        --User:Read( "Banned", { Date="31.03.2011"; Reason="WEBSTREAM"; Typ="Inetnum"; Info="COMPUTER.SED.gg"; } );
        --Umbra.BanSystem:Add('patryk', '258132298', '178.183.243.163', '178.183.243.163.dsl.dynamic.t-mobile.pl', 'flyhack', '08/11/2012 | 21:39:53', 'Anti-Noob');
        Umbra.Banlist[profile] = {};
        table.insert(Umbra.Banlist[profile], name);
        table.insert(Umbra.Banlist[profile], ip);
        table.insert(Umbra.Banlist[profile], domain);
        table.insert(Umbra.Banlist[profile], reason);
        table.insert(Umbra.Banlist[profile], date);
        table.insert(Umbra.Banlist[profile], bannedby);
        --[[Umbra.Banlist[profile].name = name;
        Umbra.Banlist[profile].ip = ip;
        Umbra.Banlist[profile].domain = domain;
        Umbra.Banlist[profile].reason = reason;
        Umbra.Banlist[profile].date = date;
        Umbra.Banlist[profile].bannedby = bannedby;--]]
        if not count then count = 0; end
        count = count + 1;
    end
    Umbra.Bans = {};
    Umbra.Bans.cnt = count;
    System.LogAlways(Umbra.Tag.." Read "..count.." banned players (added into the Umbra Global Banlist)");
    if (#Umbra.Banlist == 0) then
        System.LogAlways(Umbra.Tag.." The Banlist seems to be empty. It seems that some part of loading has failed.");
    end
    count = nil; --Purge this one as well, again!
end

Edit:

I don't get the message that the code below should print if their profile doesn't exist in the table, so their profile does actually exist.

    if (not Umbra.Banlist[profile]) then
            System.LogAlways(Umbra.Tag.." Error in 'Umbra.Banlist': The profile does not exist.)");
            break;
        end

Another Edit:

Proof that the system can in fact get the 'ID' variable:

enter image description here

Upvotes: -1

Views: 310

Answers (2)

user704565
user704565

Reputation:

Just try to use this function to get count of items in table:

function count(t)
    local c=0;
    for i in pairs(t) do c=c+1; end
    return c;
end
--...
if(count(Umbra.Banlist)==0)then
    --...
end

The thing is, that # counts an array/table with number indexes, but you have table with string indexes. # is same like when you would replace "pairs" with "ipairs" in that count function. So and when you do #Umbra.Banlist, where all indexes are strings, it returns 0, because there are 0 integer indexes, but it does not mean, that table is empty.

Upvotes: 2

greatwolf
greatwolf

Reputation: 20858

Near the end of your code you have #Umbra.Banlist == 0 but I don't see any item insertions into it by numeric keys. Here are some things to check to see if you're assumptions matches up with reality.

Check that profile isn't nil. It looks like in your use-case you're assuming it's a number. You can check this easily with:

assert(profile)
assert(type(profile) == 'number')

If profile is actually not a number type then checking Umbra.Banlist with # operator is faulty. Note # does not count the associative part of the table. If you only care whether Umbra.Banlist is empty or not you can use if next(Umbra.Banlist) then to check for it.

Upvotes: 4

Related Questions