yuroyami / syncplay-mobile

📱 Unofficial Syncplay client app for Android and iOS. Watch stuff in sync with your friends. Works well with Syncplay on PC. Fully written in Kotlin and Compose multiplatform.
115 stars 5 forks source link

Port the managed room functionality #17

Open yuroyami opened 2 years ago

yuroyami commented 2 years ago

PC Syncplay provides various helpful methods of syncing rooms. A room where there is an operator who controls when to pause, play or seek, is called a managed room. Syncplay Android does not include this functionality yet.

Et0h commented 2 years ago

Good to see this feature is planned as it is quite useful for large groups.

The way managed rooms were implemented in Syncplay is a bit quirky as we didn't want to store room passwords to a file so as to maintain anonymity. Fortunately, most of the quirkiness is server side and so all the client needs to do when creating a managed room is to basically tell the server "I want to make a managed room with this password" and the server will reply with the name of the managed room which corresponds to that password. After that, anyone with the control password can become a room operator for the room of the name that was created (and so there could theoretically be more than one).

You can see a room is a managed room because it follows the format +RoomName:Hash. On such rooms only those who have identified as an operator can control the room, and everyone else who tries to seek etc when they shouldn't will be ignored (and their client told what state they should actually be).

Importantly if you the room operator is disconnected their client will need to re-identify to become an operator again.

Et0h commented 2 years ago

In terms of the relevant Syncplay protocol, it should be something like this...

Hello feature for server/client:

{"Hello": {"features": {"managedRooms": true}}}

Creating a managed room:

client >> {"Set": {"controllerAuth": {"room": "foobar", "password": "JE-411-084"}}}
server << {"Set": {"newControlledRoom": {"password": "JE-411-084", "roomName": "+foobar:DF6E12D2FB8B"}}}
client >> {"Set": {"room": {"name": "+foobar:DF6E12D2FB8B"} } }
client >> {"Set": {"controllerAuth": {"room": "+foobar:DF6E12D2FB8B", "password": "JE-411-084"}}}

Identifying as a room operator when in an existing managed room:

client >> {"Set": {"controllerAuth": {"room": "+foobar:DF6E12D2FB8B", "password": "JE-411-084"}}}
server << {"Set": {"controllerAuth": {"user": "Etoh", "room": "+foobar:DF6E12D2FB8B", "success": true}}}

Someone in room identifies as room operator:

server << {"Set": {"controllerAuth": {"user": "Etoh", "room": "+foobar:DF6E12D2FB8B", "success": true}}}

Determine whether or not someone in room has already identifier as an operator:


client >> {"List": null}
server << {"List": {"+foobar:DF6E12D2FB8B": {"Etoh": {"controller": true}}}}
yuroyami commented 2 years ago

@Et0h I still haven't checked the entire code yet but I kind of had a faint idea that the server takes care of it. All I have to do on client side is to set and handle controllerAuth sets I see. I kept the code empty for it for now, so I believe the missing features would cause the app to crash or probably drop connection at the very least. However, it doesn't seem so complicated. You have broken it down for me clearly and exquisitely I believe this can be implemented and ported in no time as the feature is hugely beneficial for large group of users. Thank you very much. I will make sure to put that to use.