Protected shared objects

Added by Carlos Peña-Monferrer over 1 year ago

Hi all,

Thank you Josip for sharing VRSpace, really really great work!

I'm creating a world with objects moving around the scene, such as some non-playable characters. These objects should be visible by all the connected users but they won't be allowed to change the object's properties. Also, they should see the same state (position, animations, ...) of the objects.

I took a look at code and examples and started playing with VRObject similar to the `babylon/multiuser-test.html` example. Using this approach I managed to send and receive events to the clients. However, this had some side issues like the need of some kind of master client that creates first the shared objects and sends later the events. Another issue is that other clients could manipulate events of the VRObjects as they are public.

I guess I could play a bit with this and label the VRObjects as Owned or setting up this logic on the server side, but wanted to check with you guys if someone tried something similar. If you have some suggestions please also let me know.


Replies (6)

RE: Protected shared objects - Added by Josip Almasi over 1 year ago

Hi Carlos,

Now one dolphin is a VRObject but the other dolphin is a Client. Client is Owned and it's properties can not be changed by other Client instances.
So clicks on both spheres create a dolphin and another click on the sphere removes it. But click on one dolphin is shared, and the click on the other is shared only if it comes from the owner.
You should see error in the console of the other browser, an in server log, 'Cannot change owned object' SecurityException.

Client may be what just you need to implement NPCs. Currently that's how bots and event recorder are implemented - there are server-side classes that extend Client. So they can do everything that a user can, they receive events and so on, except they don't have associated Session. Basically you'd need to override processEvent and sendMessage methods of Client, see e.g. and

That really depends on what you want your NPCs to do, of course. These respond to chat events only. Should they respond to movement, you'd need to handle VREvent objects instead of/in addition to Add/Remove in sendMessage().
This may be somewhat confusing due to method naming. Like, sendMessage() is supposed to send the message to the client, while you might expect it to be used for NPC to send a message :)
But I guess that solves NPCs.

General owned shared objects aren't there yet, because I did not need them yet. But it should be easy enough, like

public class OwnedVRObject extends VRObject {

That should be all, literally. There still needs to be appropriate test suite to confirm it works though :>
Then your client code would simply create these OwnedVRObjects instead of plain VRObjects.
You could also use Owned annotation of some fields of publicly accessible objects. I really don't know what for, but it seemed a good idea at the moment ;)

Who's the owner?
A Client who created the object, or an Admin, but there's no Admin yet. Specifically, that's about implementations of Owner interface.
And so on.

So let me know how this works for you, if you need anything, and especially if you want to contribute.

RE: Protected shared objects - Added by Carlos Peña-Monferrer over 1 year ago

Many thanks for the detailed reply! I will check how it works with a `OwnedVRObject` and come back.

I would be happy to contribute on this or other developments. For this one, what about a PR with a minimal example with some dolphins? I might be able to also share the bigger case once it's ready if you like, although I would need to double-check first with my partner who is actually doing the world's design.


RE: Protected shared objects - Added by Josip Almasi over 1 year ago

I think start small, see how it goes.
Test coverage you need is in DispatcherTest.testOwnedClass() - one client tries to change the name of the other client.
In your case, you'd

OwnedVRObject owned = new OwnedVRObject(123L);
String payload = "{\"object\":{\"OwnedVRObject\":123},\"changes\":{\"something\":\"whatever\"}}" 

Maybe try to dispatch request first with null owner - that should not throw, then set owner and dispatch - should throw.
Certainly faster than hitting browser reload button again and again ;)
Once that passes, proceed with client side.

RE: Protected shared objects - Added by Carlos Peña-Monferrer over 1 year ago

Thanks for the tip! My last message was more in the line of defining some kind of "longer-term" goal that would work for your repo too.

Following your message, I've created the following `testOwnedObject` that works as you expected so far:

  public void testOwnedObject() throws Exception {
    OwnedVRObject obj = new OwnedVRObject(123L);
    // VRObject obj = new VRObject(123L); // This won't throw
    Client c1 = new Client(1L);
    Client c2 = new Client(2L);
    String payload = "{\"object\":{\"OwnedVRObject\":123},\"changes\":{\"something\":\"whatever\"}}";

    ClientRequest req = mapper.readValue(payload, ClientRequest.class);
    // req.setClient(c1); // This won't throw

    assertThrows(SecurityException.class, () -> dispatcher.dispatch(req));

RE: Protected shared objects - Added by Josip Almasi over 1 year ago

I'd say start small see how it includes longer term goals ;)
If you use it, and you think it would be useful for someone else, publish it. Generally, I'd welcome it to the repo.
But then there's a small matter of maintenance. Will you, can I?
And so on, that 'see how it goes' part gets complicated.

Re long term goals, I'd love to see this project under the hood of apache foundation or alike.

RE: Protected shared objects - Added by Josip Almasi over 1 year ago

Hey Carlos,
I just realized that multiuser-test was broken :(
I.e. using non-humanoid avatars did not work.
Fix pushed.