PDA

View Full Version : Help needed with DB.setOwner and/or DB.addHolder



damned
March 1st, 2020, 22:06
Ok.
what am i doing wrong here?
in OOB Im doing this:
DB.setOwner(sMyNodePath, sPlayerName);
where
sMyNodePath = mc_world.id-00005.pcnewdesc [ DB.getPath(window.getDatabaseNode()) .. ".pcnewdesc" ]
sPlayerName = Fizzbo [ User.getUsername() ]
but nothing seems to get written to the db.xml
most of the time the player can edit the field but not always
what am I missing?
---
i also tried all three of these
DB.addHolder(sMyNodePath, sPlayerName, true);
--
DB.addHolder(sNodePath, sPlayerName, true);
--
DB.addHolder(sNode, sPlayerName, true);

where
sMyNodePath = mc_world.id-00005.pcnewdesc [ DB.getPath(window.getDatabaseNode()) .. ".pcnewdesc" ]
sPlayerName = Fizzbo [ User.getUsername() ]
sNodePath = mc_world.id-00005 [ DB.getPath(window.getDatabaseNode()) ]
sNode = databasenode = { mc_world.id-00005 } [ window.getDatabaseNode() ]

none of them set any owners...
---
is my syntax wrong or is my approach wrong?

Trenloe
March 2nd, 2020, 01:26
Are you making sure that the OOB message code only runs on the GM side by using if User.isHost() then ... in the OOB message handler that contains the DB.addHandler code?

And, just to check, you're issuing the \save chat command after the code runs and before you look at db.xml?

damned
March 2nd, 2020, 02:28
The code is initiated by Players not the GM. It is to allow Players to append data to records they dont own.
It works but at least 1 in 3 records dont "unlock" the first time.

I am hitting /save before previewing the database.

The process flow is something like this:

The GM shares a Places record.
it has a section called PC Notes.
Besides PC Notes is an Edit Icon visible only to players.
If the player clicks this
onClickDown initiates an OOB that
creates a field called ".pcnewdesc"
applies setOwner on the field
onClickRelease launches the window

if the two steps above have worked this new dialog has an empty but editable field

this window has a submit button

onClickRelease
the OOB does
gets the value of ".pcnotes" and ".pcnewdesc" and appends the two with the name of the new submitter
and writes this value to ".pcnotes" as the whole entry
and then clears ".pcnewdesc"

This works a lot of the time but not always
Sometimes the field ".pcnewdesc" is not editable but if you hit submit the rest of the process happens - including the player name being written - and then the field becomes editable.

however - at no time do i see the owner or holder being changed.

Moon Wizard
March 2nd, 2020, 08:29
Only the GM can modify holder/owner relationships. Make sure that all your code for changing ownership is running on client when initiated by player. The onObserverUpdate event will fire for that node when the event happens.

Add lots of debug statements on both sides to make sure that your OOB is being accepted by GM, that the owner is being set, and that both the GM and player receive the onObserverUpdate.

Regards,
JPG

damned
March 2nd, 2020, 08:50
Hi Moon Wizard.

The only place I can find that references something called an "observer list" is that function.
Can you provide any more info on what an observer is?

Trenloe
March 2nd, 2020, 11:22
The code is initiated by Players not the GM. It is to allow Players to append data to records they dont own.
Yep, I understand that. What I meant by "[make] sure that the OOB message code only runs on the GM side" was that sending OOB messaging from a player goes to all clients - see the "If client..." section here: https://www.fantasygrounds.com/refdoc/Comm.xcp#deliverOOBMessage

So, you need to ensure is that the code to change the DB ownership only runs on the GM side - by using if User.isHost() then... code in the OOB handler. Moon Wizard eludes to this also - except I think he meant to say "Make sure that all your code for changing ownership is running on [GM] client when initiated by player."

In the Star Wars: EotE ruleset I created a player DB manager script package (managers\playerdbmanager.lua) that has a number of OOB messages that are called from the player side to create and update fields in the database that aren't owned by the player. This doesn't specifically change the ownership of DB nodes, but it does show how OOB messaging can be used to pass off DB changing to the GM. You should be able to use the same approach to change the database ownership. Their's nothing special about these functions, all they do is work as we've mentioned - by ensuring the OOB triggered code only runs on the GM instance.

damned
March 2nd, 2020, 12:28
hmmm...
I have added some User.isHost
anything leaping out at you?



OOB_MSGTYPE_CREATENODE = "createnode";


function onInit()
OOBManager.registerOOBMsgHandler(OOB_MSGTYPE_CREAT ENODE, handleCreateNode);
end


function notifyCreateNode(sNodePath, sPCName, sPlayerPath, sPlayerID, sPlayerName, sNode)

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

msgOOB.sNodePath = sNodePath;
msgOOB.sPCName = sPCName;
msgOOB.sPlayerPath = sPlayerPath;
msgOOB.sPlayerID = sPlayerID;
msgOOB.sPlayerName = sPlayerName;
msgOOB.sNode = sNode;
Debug.chat("notify: ", sNodePath, sPCName, sPlayerPath, sPlayerID, sPlayerName, sNode);

Comm.deliverOOBMessage(msgOOB, "");
end

function handleCreateNode(msgOOB)

sPlayerID = msgOOB.sPlayerID;
sNodePath = msgOOB.sNodePath;
sPCName = msgOOB.sPCName;
sPlayerName = msgOOB.sPlayerName;
sNode = msgOOB.sNode;

DB.createChild(sNodePath, "pcnewdesc", "formattedtext");

sMyNodePath = sNodePath .. ".pcnewdesc";


if User.isHost then
Debug.chat("I am GM");
DB.addHolder(sMyNodePath, sPlayerName, true);
DB.setOwner(sMyNodePath, sPlayerName);
else
Debug.chat("I am Nobody");
end

end


So... I wonder if there might not be a different approach....
Updating the final field all works fine.
Its gaining write access to the temp field...
Is it possible to have that field be source-less or to point at a field on the charsheet node?

Trenloe
March 2nd, 2020, 12:39
Is it possible to have that field be source-less or to point at a field on the charsheet node?
Yep. Maybe go source-less and then update the end field via OOB messaging to the GM? The problem might be gaining "write" access others sending data at the same time.

Trenloe
March 2nd, 2020, 12:42
function handleCreateNode(msgOOB)

sPlayerID = msgOOB.sPlayerID;
sNodePath = msgOOB.sNodePath;
sPCName = msgOOB.sPCName;
sPlayerName = msgOOB.sPlayerName;
sNode = msgOOB.sNode;

DB.createChild(sNodePath, "pcnewdesc", "formattedtext");

sMyNodePath = sNodePath .. ".pcnewdesc";


if User.isHost then
Debug.chat("I am GM");
DB.addHolder(sMyNodePath, sPlayerName, true);
DB.setOwner(sMyNodePath, sPlayerName);
else
Debug.chat("I am Nobody");
end

end
[/code]
Put the above highlighted code in the GM only portion as well?

EDIT: The whole of the handleCreateNode function code should be ran by the GM only, as only the GM can create the child node and then do operations against it.

damned
March 2nd, 2020, 13:03
Many thanks as always Trenloe

I tried that also and it doesnt seem to have made any change...
Out of curiosity if I hit submit on the window while its not writeable/active it does the rest of the next function AND if i click to edit again it functions as it should.
Below is the second OOB that does that in case something rings a bell...

Any pointers on how to make just the new data field sourceless?



OOB_MSGTYPE_UPDATENODE = "updatenode";

function onInit()
OOBManager.registerOOBMsgHandler(OOB_MSGTYPE_UPDAT ENODE, handleUpdateNode);
end

function notifyUpdateNode(sWorldPath, sPCNewdesc, sPCName)

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

msgOOB.sWorldPath = sWorldPath;
msgOOB.sPCNewdesc = sPCNewdesc;
msgOOB.sPCName = sPCName;

Comm.deliverOOBMessage(msgOOB, "");
end

function handleUpdateNode(msgOOB)

sPCName = msgOOB.sPCName;
sPCNewdesc = msgOOB.sPCNewdesc;
sWorldPath = msgOOB.sWorldPath;

DB.setValue(sWorldPath .. ".pcdescription", "formattedtext", DB.getValue(sWorldPath .. ".pcdescription") .. "<p>*" .. sPCName .. "*</p>" .. sPCNewdesc);
DB.setValue(sWorldPath .. ".pcnewdesc", "formattedtext", "<p></p>");

end

Trenloe
March 2nd, 2020, 13:19
Any pointers on how to make just the new data field sourceless?
Use a formattedtextcontrol not a formattedtextfield.

Trenloe
March 2nd, 2020, 13:24
Try to adding some DB.getOwner debug code throughout your process to see who owns the node and when. That might help you to pinpoint where things aren’t working.

Trenloe
March 2nd, 2020, 13:28
Also, your handleUpdateNode code in post #10 above is running on all clients (players and the GM). Again, you want to make sure that only the GM runs the code via OOB messaging, or (assuming you can get the correct ownership working) just run the DB.setValue code from the FG instance that is actually performing the update code - don’t use OOB messaging.

damned
March 2nd, 2020, 22:14
Hi Trenloe - I havent had a chance to make the other OOB changes but will.
Initial tests using formattedtextcontrol look..... good!