How to run code from a specific user

Hi, I have the function foo(bar) and when you run this function it opens a window with some details on is there a way I can make foundry think that the function was run from a specific userId, so the window appears on their screen instead of mine?
15 Replies
Ellam
EllamOP2y ago
or some other way to make the window appear on their screen doesn't necessarily have to be some kind of psudo command
Re4XN
Re4XN2y ago
Client code executes for everyone, I believe. So what you can do is use a gate that checks for that specific user, e.g.
if (!user.isGM()) {
// do nothing
}

// run code for this user
if (!user.isGM()) {
// do nothing
}

// run code for this user
Ellam
EllamOP2y ago
so the code will be run on a click event, I want the GM to click the button, and the USER to see the window
Re4XN
Re4XN2y ago
Right, I don't think that changes my suggestion. Imagine you have the following snippet in your code:
const printHello = () => {
console.log('Hello!')
}

printHello()
const printHello = () => {
console.log('Hello!')
}

printHello()
If you have 3 logged in users and this function is called, you will see 3 outputs in the console if you open it. The way you would refactor this to only print for a specific user is to add the gate pattern I mentioned above.
Ellam
EllamOP2y ago
but the function i'm running renders a handlebars template, and only runs it for the client which runs the code
Ethaks
Ethaks2y ago
If you want an action that is not tied to some document lifetime cycle executed on every client to trigger something for another client, you'll need sockets: https://foundryvtt.wiki/en/development/api/sockets
Foundry VTT Community Wiki
Sockets
API documentation for the Socket functionality available to packages.
Ethaks
Ethaks2y ago
With those the GM click can send a message to other clients, and the correct client (as determined by a userId check or via socketlib) can render something on their end.
Ellam
EllamOP2y ago
so if i wanted to use a socket to maker user: game.users.get(userId) run the below code:
await game.ptu.utils.dex.render(species, type)
await game.ptu.utils.dex.render(species, type)
it would be
socket.emit('ptu.renderDex', {
userId: userID,
species: species,
type: type
})
socket.emit('ptu.renderDex', {
userId: userID,
species: species,
type: type
})
then elsewhere i'd have
async function handleRenderDex({userId, species, type}) {
if(!!userId && game.userId !== userId) return

await game.ptu.utils.dex.render(species, type)
}

socket.on('ptu.renderDex', handleRenderDex);
async function handleRenderDex({userId, species, type}) {
if(!!userId && game.userId !== userId) return

await game.ptu.utils.dex.render(species, type)
}

socket.on('ptu.renderDex', handleRenderDex);
that right?
Ethaks
Ethaks2y ago
Mind the event name, it has to match specific requirements.
Ellam
EllamOP2y ago
so the system i'm editing is called ptu so does the event name have to be "system.ptu"?
Ethaks
Ethaks2y ago
Looks correct
Ellam
EllamOP2y ago
what if there is already an event that runs that?
Ethaks
Ethaks2y ago
The event name is essentially a Foundry determined value. If you want to have different events, you have to move the kind of event into the payload and use a single listener determining which function to run based on that.
Ellam
EllamOP2y ago
ok cool got it working thankyou!
4535992
45359922y ago
or just use https://github.com/mclemente/fvtt-advanced-macros you can speciy for what user run a macro on the macro sheet (it use always sockets ).
Want results from more Discord servers?
Add your server