PDA

View Full Version : "Database node not owned" error



dr_venture
December 8th, 2012, 22:52
I'm tracking down a bug where the GM's Initiative rolls *do* propagate to the CT, but the player's rolls do not. I've found that in the debugging console of the player's FG I get the following message:

Script Warning: setValue: Database node not owned (combattracker.id-00003.initresult)

I have an idea of what this means, but don't really understand about node/db permissions in FG. Can anyone point me in the right direction for investigation/fixing this? Thanks in advance!

Ikael
December 8th, 2012, 23:40
"owned" usually means that person/client has full control of given node (read and write permissons) but that's would no be correct in most cases. I bet that you're dealing with code that's pre FG v2.8 base and didn't cause and issue back then, but now it does (from compatible 2.8 :: setValue, setPrototype and populateFromImageNode will no longer bypass database node ownership checks.). The idea is to make sure that players/clients are not trying to set values to fields where they have read-only permmissions (according to FG core). I strugggled with this a year a ago so if you have any more details where this comes from I might be able to help you

dr_venture
December 9th, 2012, 00:05
A couple questions:

1) I just realized that I'm not entirely certain where the code I'm looking at is executed: on the GM's computer as a 'server' or on the client as a sort-of 'distributed server'? I'm assuming that the code is executed locally whichever computer is initiating the code to run (by rolling dice, entering chat text, etc.)... correct?

I'm used to the web server environment, where code either executes on the server and is passed to the client, or on the client (web browser) and may or may not be passed to the server. I think I have to get used to the new environment.

2) You indicated setValue no longer bypasses db node ownership. It looks like that means the DB node 'combattracker.id-00003.initresult' is not owned by the player. So how do I have the players set a value to the node: pass the die result to the node's owner & have them write it? Set the node's owner/access level? Use another mechanism entirely?

I think I can piece together the code I need if I can get a bit of a road map or bullet items for what I'm trying to accomplish. I don't know if that can be done simply or not.

damned
December 9th, 2012, 01:09
i had a look at this about 3 weeks ago to see if I could work it out but I felt like I was wandering the labyrinth of Knossos... :(
i could find the initiative code but had no idea what else was going on.

Moon Wizard
December 9th, 2012, 01:53
I believe that the 3.5E and 4E ruleset use the OOB message functions to pass the result of initiative rolls to the host, so that the host can update the values.

FG uses a client-server model, where the host is the server. Dice roll results execute on whichever client or server that initiated the roll b

Let me know if you need help finding the code. There is a OOB manager script that handles encoding and decoding of OOB messages between client and host.

Regards,
JPG

dr_venture
December 9th, 2012, 02:28
I guess I need help: searched for "deliverOOBMessage" and "OOBMessage" and just "OOB" in both the 3.5 and 4 rulesets, but can't find any matches.

Does this mean I'm going to have to rewire my chat architecture for the whole ruleset, or can I just fix the roll in question? Or is that something I'm just going to have to figure out for myself, based on the ruleset implementation?

damned
December 9th, 2012, 03:34
i too would love to see a walk thru of this. im sure its a relatively easy "fix" but its really not that easy tracing the different functions between files. seeing an example of how to properly find how these functions link.

eg i think that this is where the players can generate initiative:

from charsheet_combat.xml

<description>
<text>Initiative</text>
</description>
<script>
function onDoubleClick(x,y)
ChatManager.DoubleClickInitiative("init", getValue(), self.description[1].text[1], {pc = window.getDatabaseNode()});
return true;
end

function onDragStart(button, x, y, draginfo)
if OptionsManager.isOption("DRGR", "on") then
local opt_indi = OptionsManager.getOption("INDI");
if opt_indi == "10" or opt_indi == "off" then
draginfo.setDieList({ "d10" });
elseif opt_indi == "20" then
draginfo.setDieList({ "d20" });
elseif opt_indi == "100" then
draginfo.setDieList({ "d100", "d10" });
end

draginfo.setType("init");

else
draginfo.setType("number");
end
draginfo.setDescription(self.description[1].text[1]);
draginfo.setNumberData(getValue());
draginfo.setShortcutData("charsheet", window.getDatabaseNode().getNodeName());

return true;
end
</script>
but i cant see where in this file it tries to send that data, or in what .lua script it tries to pick up that data.
from the error message posted vy doc above:

Script Warning: setValue: Database node not owned (combattracker.id-00003.initresult)
i would hazard a guess that it is the file combattracker.lua but all i can find there is:

--Roll initiative and sort
if opt_init == "group" then
if (namecount < 2) or (last_init == 0) then
newentry.initresult.setValue(math.random(InitDieTy pe)+newentry.init.getValue());
else
newentry.initresult.setValue(last_init);
end
applySort(getWindows());
elseif opt_init == "all" then
newentry.initresult.setValue(math.random(InitDieTy pe)+newentry.init.getValue());
applySort(getWindows());
end


and


function rollEntryInit(ctentry)
-- For PCs, we always roll unique initiative
if ctentry.type.getValue() == "pc" then
ctentry.initresult.setValue(math.random(InitDieTyp e) + ctentry.init.getValue());
return;
end

-- For NPCs, if NPC init option is not group, then roll unique initiative
local opt_init = OptionsManager.getOption("INIT");
if opt_init ~= "group" then
ctentry.initresult.setValue(math.random(InitDieTyp e) + ctentry.init.getValue());
return;
end

-- For NPCs with group option enabled

-- Get the entry's database node name and creature name
local ctentrynodename = ctentry.getDatabaseNode().getNodeName();
local ctentryname = stripCreatureNumber(ctentry.name.getValue());
if ctentryname == "" then
ctentry.initresult.setValue(math.random(InitDieTyp e) + ctentry.init.getValue());
return;
end

-- Iterate through list looking for other creature's with same name
local last_init = 0;
for k,v in pairs(getWindows()) do
if ctentrynodename ~= v.getDatabaseNode().getNodeName() then
local tempentryname = stripCreatureNumber(v.name.getValue());
if tempentryname == ctentryname then
local cur_init = v.initresult.getValue();
if cur_init ~= 0 then
last_init = cur_init;
end
end

end
end

-- If we found similar creatures with non-zero initiatives, then match the initiative of the last one found
if last_init == 0 then
ctentry.initresult.setValue(math.random(InitDieTyp e) + ctentry.init.getValue());
else
ctentry.initresult.setValue(last_init);
end
end

function rollAllInit()
for k, v in ipairs(getWindows()) do
if v.type.getValue() == "npc" or v.type.getValue() == "monster" then
v.initresult.setValue(0);
end
end

for k, v in ipairs(getWindows()) do
if v.type.getValue() == "pc" then
rollEntryInit(v);
end
if v.type.getValue() == "npc" or v.type.getValue() == "monster" then
if v.wounds.getValue() < v.hp.getValue() then
rollEntryInit(v);
end
end
end
end

in combattracker_entry.lua I see

function linkUpdate()

local src = link.getTargetDatabaseNode();
name.setLink(src.getChild("name"), true);
speed.setLink(src.getChild("move.current"));
bth.setLink(src.getChild("attackbonus.base"));

hp.setLink(src.getChild("hp.total"));
wounds.setLink(src.getChild("hp.wounds"));

ac.setLink(src.getChild("ac.totals.general"));
touchac.setLink(src.getChild("ac.totals.touch"));
flatfootedac.setLink(src.getChild("ac.totals.flatfooted"));
init.setLink(src.getChild("initiative.total"), true);

end

what i really cant see is where it is taking taking the value here and applying it in combat tracker....

draginfo.setDescription(self.description[1].text[1]);
draginfo.setNumberData(getValue());
draginfo.setShortcutData("charsheet", window.getDatabaseNode().getNodeName());

dr_venture
December 9th, 2012, 03:45
FWIW, The actual error occurs in the file "\scripts\chat_chat.lua" on line 433, which reads:

v.getChild("initresult").setValue(total);

The block of code reads (I have a comment here below indicating where the error occurs:


-- The following executes only if a PC/NPC name was found
if custom_nodename then
-- Check for exact CT match
for k, v in pairs(ct_node.getChildren()) do
if v.getNodeName() == custom_nodename then
v.getChild("initresult").setValue(total);
end
end
-- Otherwise, check for link match
for k, v in pairs(ct_node.getChildren()) do
local node_class, node_ref = v.getChild("link").getValue();
if node_ref == custom_nodename then
-- ERROR FOR PLAYERS HERE: Script Warning: setValue: Database node not owned (combattracker.id-00003.initresult)
v.getChild("initresult").setValue(total);
end
end
end

damned
December 9th, 2012, 04:18
i got the error to display about 10mins ago and now despit closing and relaunching 4 times I cant get the error to redisplay...
my error pointed to line 425 but I wanted to record the whole error....

but anyway... based on that it suggests that this .setValue is the one that doesnt have permissions anymore...


for k, v in pairs(ct_node.getChildren()) do
local node_class, node_ref = v.getChild("link").getValue();
if node_ref == custom_nodename then
v.getChild("initresult").setValue(total); end

dr_venture
December 9th, 2012, 04:30
In my case, I narrowed down the error with comments written to the console, so I'm sure of the exact line. That said, I'm guessing that you're seeing the same error with a different SetValue call - there could be quite a few of them that could potentially throw errors now... they'll all have to be ferreted out and fixed somehow. Joy! However at this point I don't even know what OOB stands for (out of bounds? odor on body? omnipresent outgoing belch?) , where to find it, or how it works.

Moon Wizard
December 9th, 2012, 04:46
OOB = out of band. It's a networking terminology used to denote a channel containing control information rather than data. In the case of FG, it's for messages between client and server not destined for the chat window.

Basically, the OOB mechanism is used to pass a LUA table from client to host on an init roll. When the host delivers message to self, it's just like it received one from client.

You don't need the whole "action" framework, just the OOB manager and making the right calls to the OOB Manager to generate and handle the OOB messages.

Looking at the current 3.5E ruleset:
C:\Users\John\AppData\Roaming\Fantasy Grounds II\rulesets\3.5E\base.xml


Line 138: <script name="OOBManager" file="scripts/manager_oob.lua" />


C:\Users\John\AppData\Roaming\Fantasy Grounds II\rulesets\3.5E\scripts\manager_action_init.lua


function onInit()
OOBManager.registerOOBMsgHandler(OOB_MSGTYPE_APPLY INIT, handleApplyInit);

ActionsManager.registerActionIcon("init", "action_roll");
ActionsManager.registerModHandler("init", modRoll);
ActionsManager.registerResultHandler("init", onResolve);
end

function handleApplyInit(msgOOB)
local nTotal = tonumber(msgOOB.nTotal) or 0;

DB.setValue(msgOOB.sSourceCTNode .. ".initresult", "number", nTotal);
end

function notifyApplyInit(rSource, nTotal)
if not rSource then
return;
end

local msgOOB = {};
msgOOB.type = OOB_MSGTYPE_APPLYINIT;

msgOOB.nTotal = nTotal;
msgOOB.sSourceCTNode = rSource.sCTNode;

Comm.deliverOOBMessage(msgOOB, "");
end


C:\Users\John\AppData\Roaming\Fantasy Grounds II\rulesets\3.5E\scripts\manager_action_init.lua


function onResolve(rSource, rTarget, rRoll)
local rMessage = ActionsManager.createActionMessage(rSource, rRoll);
Comm.deliverChatMessage(rMessage);

local nTotal = ActionsManager.total(rRoll);
notifyApplyInit(rSource, nTotal);
end


Regards,
JPG