PDA

View Full Version : User.isHost() giving odd return...



celestian
October 13th, 2017, 18:17
This is related to User.* https://www.fantasygrounds.com/refdoc/User.xcp

I'm trying to clean up some output that will only show to player when it's not DMonly and if not, show them.

Problem is User.isHost() is returning TRUE when the client it initiating the action.



Runtime Notice: s'manager_effect_adnd.lua' | s'sendRawMessage' | s'nDMOnly' | #1
Runtime Notice: s'manager_effect_adnd.lua' | s'sendRawMessage' | s'sUser' | s'DM'
Runtime Notice: s'manager_effect_adnd.lua' | s'sendRawMessage' | s'msg' | { s'font' = s'msgfont', s'icon' = s'roll_effect', s'text' = s'Advanced Effect ['BSTR: 18; BPSTR: 100'] removed [from Paladin] [by Magical, Gauntlets of Ogre Power]' }
Runtime Notice: s'manager_effect_adnd.lua' | s'sendRawMessage' | s'User.isHost()' | bTRUE
Database Notice: Campaign saved.


How is that possible if the user (connected as a player) is the one responsible for the action (they are toggling the equipment "equipped").

The code that generated the debug output for above is just a send message function but here it is.



function sendRawMessage(nDMOnly,sUser, msg)
Debug.console("manager_effect_adnd.lua","sendRawMessage","nDMOnly",nDMOnly);
Debug.console("manager_effect_adnd.lua","sendRawMessage","sUser",sUser);
Debug.console("manager_effect_adnd.lua","sendRawMessage","msg",msg);
Debug.console("manager_effect_adnd.lua","sendRawMessage","User.isHost()",User.isHost());
if nDMOnly == 1 and User.isHost() then
msg.secret = true;
Comm.addChatMessage(msg);
elseif nDMOnly ~= 1 then
if sUser ~= "" then
Comm.addChatMessage(msg);
--Comm.deliverChatMessage(msg, sUser);
else
Comm.deliverChatMessage(msg);
end
end
end


There has to be something fiddly about this I just am not aware of because it should be responding FALSE (User.isHost()). Does it matter the player is connected to the server locally (server and player are running in same instance of windows). I don't recall that being an issue before but it's all I can think of.

Moon Wizard
October 13th, 2017, 19:24
The item transfers happen on the GM machine, because each user only has access to modify their own character, not the other character involved in the trade.

Regards,
JPG

celestian
October 13th, 2017, 19:37
The item transfers happen on the GM machine, because each user only has access to modify their own character, not the other character involved in the trade.

Regards,
JPG

There is no transfer, the person is just marking the item equipped which is then scanned for effects on it and then applied, the "effects" details are what I'm outputting.

Wondering if it might just be best to only output that to DM only completely and what the player sees in the combat tracker is sufficient.

Moon Wizard
October 13th, 2017, 19:51
Similarly, when effects are applied to a creature, it is done on the GM machine, since the GM owns that combat tracker node and is only one who can edit.

I haven’t seen any case where User.isHost returns incorrectly. It’s a very simple function internally.

So, I’m trying to brainstorm why it might return true. My guess is that the code is actually running on the host for some reason.

Another function for debugging that might be useful is printstack(), in conjunction with Debug.console.

Regards,
JPG

celestian
October 13th, 2017, 20:26
Similarly, when effects are applied to a creature, it is done on the GM machine, since the GM owns that combat tracker node and is only one who can edit.

I haven’t seen any case where User.isHost returns incorrectly. It’s a very simple function internally.

So, I’m trying to brainstorm why it might return true. My guess is that the code is actually running on the host for some reason.

Another function for debugging that might be useful is printstack(), in conjunction with Debug.console.


Oh, good one, I like that thanks!

Here is what it shows.



Script Notice:
stack traceback:
[string "scripts/manager_effect_adnd.lua"]:193: in function 'sendRawMessage'
[string "scripts/manager_effect_adnd.lua"]:173: in function 'sendEffectRemovedMessage'
[string "scripts/manager_effect_adnd.lua"]:66: in function 'updateItemEffect'
[string "scripts/manager_effect_adnd.lua"]:41: in function 'updateItemEffects'
[string "campaign/scripts/char_invlist.lua"]:185: in function 'updateItemEffects'
[string "campaign/scripts/char_invlist.lua"]:118: in function <[string "campaign/scripts/char_invlist.lua"]:95>

celestian
October 13th, 2017, 21:13
So, I did some experimentation to try and figure this out a bit.

First I added debug output for onInit() in char_invlist.lua for both 5E and my ruleset.

Started up server. Did nothing with it, immediately started client up and connected. As player selected a character and opened and toggled an equipped item and the weight carried changed when it was not carried. If the item had an AC it would adjust character AC during this phase if toggled on/off. During this phase NO logging was showing.

If I toggled it with the host side it would suddenly start showing debug output and from then on both sides would show it.

I checked the 5E ruleset for this and saw the same behavior.

The fact that weight carried changes indicates it's actually running the functions. I am confused as to the debug output and why it doesn't work all the time.. until a Host actually does it.

At each point of the above traceback I added a debug output to show the User.isHost() and that was why I was surprised nothing was showing. Once the host did something to cause it to begin logging ... from then on it was always "TRUE" no matter who toggled anything.

Moon Wizard
October 13th, 2017, 21:40
As I mentioned, there's nothing specifically in the client that would do that. The User.isHost check is simply a "if (mode == HOST) return true; return false;" in the client. If the mode == HOST was wrong, a bunch of stuff would be messed up because it's used extensively.

So, that leads me to believe that there is something specific to the Lua code that only triggers after host scripts run. Since scripts don't run until they are loaded (at campaign load for global scripts, or when window opened for window/control scripts), my guess is that the scripts are windows/control scripts that aren't registered until the script is loaded on the host.

Is there a way to get me a simple example using an extension that shows this issue?

JPG

celestian
October 14th, 2017, 06:20
Okay, so... uh... I was not watching console on the client connection (duh, now I get it). I made some bad assumptions on that one. So when watching the client /console my debug of User.isHost() is correct.

Everyday I learn more than a few things about how FG works ;)

What it seems I must do as host/DM is load each PC up and select the inventory tab for the players to be able to toggle on/off the items so that they apply/remove effects. If I do not do that they get the messages that it happens but the effects are not actually changed.

I'll have to see if I can figure out a way to trigger a load of the PC when the client loads it if that's even possible. Time for more digging...

Apologies for the wrong direction!

celestian
October 14th, 2017, 07:12
So while looking into figuring out how to trigger a load I found this dude asking a similar question. I was digging for "onIdentityActivation" when I found this.



Moon Wizard said:
October 26th, 2007 20:41
Just figured it out. Apparently, database nodes are only shared with clients if the user is a "holder" registered with the database node. Once I registered each client as they login, then they are able to correctly see the options nodes I set up.

Cheers,
JPG


Hah, they have some old logs here... and Moon as been at this at least 10 years!

Bidmaron
October 14th, 2017, 12:48
What it seems I must do as host/DM is load each PC up and select the inventory tab for the players to be able to toggle on/off the items so that they apply/remove effects. If I do not do that they get the messages that it happens but the effects are not actually changed.

You mean on the client you have to load their PCs up and select the inventory tab?
Seems like you just need to register each client as a holder of their inventory nodes instead as they login....

celestian
October 14th, 2017, 18:28
You mean on the client you have to load their PCs up and select the inventory tab?
Seems like you just need to register each client as a holder of their inventory nodes instead as they login....

Client would already have the character sheet opened to inventory to be able to toggle the items equipped un-equipped. I mean, if the host hasn't opened their sheet and also clicked the inventory tab.

Far as I know they should already be a holder of their inventory. It's the CT node that is the problem I think.

Bidmaron
October 14th, 2017, 19:21
I am having trouble following your remedy.

Moon Wizard
October 14th, 2017, 20:13
I'm not sure if this is the right approach (triggering off of player login/activation), but some thoughts below:

When the user logs in, you should be able to set up the triggers for any data a player may have visible (i.e. holder or owner). However, a big caveat is that the data is streamed in one data node at a time in the current networking, so the database will be building itself out after the login event. So, you would need to create DB handlers to get triggered on the add/update events.

Regards,
JPG

celestian
October 15th, 2017, 05:56
I'm not sure if this is the right approach (triggering off of player login/activation), but some thoughts below:

When the user logs in, you should be able to set up the triggers for any data a player may have visible (i.e. holder or owner). However, a big caveat is that the data is streamed in one data node at a time in the current networking, so the database will be building itself out after the login event. So, you would need to create DB handlers to get triggered on the add/update events.

Regards,
JPG

Going to have to spend some time looking into this. Not really sure where to start yet. Sounds like I need to grant the user access to the node of the user in the CT when they take a character. Is there any examples of this anywhere I can poke at?

I'm guessing it's something around this.

User.onIdentityActivation = onIdentityActivation;

Moon Wizard
October 15th, 2017, 07:33
They should already have access to read the CT node, since the CT node to a set to public.

They probably should not have ownership of nodes in the CT in general, as only one user can own. All of the current functions that need to make modifications to nodes not owned by players go through OOB messages to the GM client, and the GM client makes the appropriate updates.

Cheers,
JPG

Moon Wizard
October 15th, 2017, 07:35
The “characterlist” window classes are a good place to start. (Which I think uses the onIdentityActivation handler)

There’s also an onUserLogin or onLogin handler as well. (Answering from phone, so just quick answer. )

JPG

JPG

celestian
October 15th, 2017, 18:44
They should already have access to read the CT node, since the CT node to a set to public.

They probably should not have ownership of nodes in the CT in general, as only one user can own. All of the current functions that need to make modifications to nodes not owned by players go through OOB messages to the GM client, and the GM client makes the appropriate updates.

Cheers,
JPG

I'm going to do a walk through in the process tonight or tomorrow and see where the problem is. It's somewhere related to applying the effect to their self.

I've another feature I added that is comparable to the concentration you have in 5E that will appy a "Casting Bless (C)" effect on the player when they select it for their initiative option. It will not apply that effect if the client runs the initiative option but will if the host does it from his side.It's similar to the issue im having with gear toggle on/off and it applying the associated effects.

celestian
October 16th, 2017, 05:32
Okay, I have it working ! Not sure it's the best way but here is what I have so far.

First, I created a AccessManagerADND.



<script name="AccessManagerADND" file="scripts/manager_access_adnd.lua" />



And this is the script above: scripts/manager_access_adnd.lua



--
--
-- Access to nodes managed for certain places here
--
-- Right now this mainly deals with CT nodes so that players can apply effects
-- that are on items or other areas --celestian
--

function onInit()
User.onIdentityActivation = onIdentityActivation;
end

function onIdentityActivation(sIdentity, sUser, bActivated)
if bActivated then
-- give access to CT node it character if exists
local nodeCT = CombatManager.getCTFromNode("charsheet." .. sIdentity);
if nodeCT and sUser ~= "" then
local owner = nodeCT.getOwner();
if owner then
nodeCT.removeHolder(owner);
end
DB.setOwner(nodeCT, sUser);
end
else
-- remove access to CT node if character exists
local nodeCT = CombatManager.getCTFromNode("charsheet." .. sIdentity);
if nodeCT and sUser ~= "" then
local owner = nodeCT.getOwner();
if owner then
nodeCT.removeHolder(owner);
end
end
end
end

-- flip through active users and their active identities and if they match
-- the nodeCT we just added then give them ownership
function manageCTOwners(nodeCT)
for _,vUser in ipairs(User.getActiveUsers()) do
for _,vIdentity in ipairs(User.getActiveIdentities(vUser)) do
local _, sRecord = DB.getValue(nodeCT, "link", "", "");
if (sRecord == ("charsheet." .. vIdentity)) then
DB.setOwner(nodeCT, vUser);
end
end
end
end


onIdentityActivation(sIdentity, sUser, bActivated)
run when a player selects a character. If the character also exists in the combat tracker the ownership privs are granted.

manageCTOwners(nodeCT)
run from addPC() in manager_combat2.lua so that it matches up users/identities ownerships when a character is placed into the combat tracker.

So far in my testing using this method has allowed clients to apply effects from items w/o any issues.

Thoughts? Suggestions?

Bidmaron
October 16th, 2017, 05:41
Celestian, thanks for posting your solutions as you go. It is great to see working code.