Skip to content

Commit

Permalink
feat(mqtt): Allow sending private object/user messages
Browse files Browse the repository at this point in the history
  • Loading branch information
mwfarb committed Dec 2, 2024
1 parent 56d97f0 commit bb16f82
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 37 deletions.
8 changes: 4 additions & 4 deletions Runtime/ArenaCamera.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public class ArenaCamera : PrettyObject
private float publishInterval; // varies

private string messageType = "object";
private Color displayColor = Color.white;
internal string userid = null;
internal string camid = null;
public Color displayColor = Color.white;
public string userid = null;
public string camid = null;

[Tooltip("User display name")]
public string displayName = null;
Expand Down Expand Up @@ -117,7 +117,7 @@ public bool PublishCreateUpdate()
msg.data = updatedData;
string payload = JsonConvert.SerializeObject(msg);
if (ArenaClientScene.Instance)
ArenaClientScene.Instance.PublishCamera(msg.object_id, payload, HasPermissions);
ArenaClientScene.Instance.PublishCamera(msg.object_id, payload);
if (!created)
created = true;

Expand Down
79 changes: 51 additions & 28 deletions Runtime/ArenaClientScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ protected override void Awake()
internal List<string> parentalQueue = new List<string>();
internal List<string> localCameraIds = new List<string>();
internal ArenaDefaultsJson arenaDefaults { get; private set; }
internal ArenaMqttTokenClaimsJson perms { get; private set; }

// Define callbacks
public delegate void DecodeMessageDelegate(string topic, string message);
Expand Down Expand Up @@ -250,11 +251,8 @@ public IEnumerator ConnectArena()
LogAndExit("Permissions not received.");
yield break;
}
ArenaMqttTokenClaimsJson perms = JsonConvert.DeserializeObject<ArenaMqttTokenClaimsJson>(permissions);
foreach (string pubperm in perms.publ)
{
if (MqttTopicMatch(pubperm, sceneTopic.PUB_SCENE_OBJECTS)) sceneObjectRights = true;
}
perms = JsonConvert.DeserializeObject<ArenaMqttTokenClaimsJson>(permissions);
sceneObjectRights = HasPerms(sceneTopic.PUB_SCENE_OBJECTS);
// publish arena cameras where requested
bool foundFirstCam = false;
foreach (ArenaCamera cam in camlist)
Expand Down Expand Up @@ -285,17 +283,23 @@ public IEnumerator ConnectArena()
idtag: cam.userid,
userobj: cam.camid
);
foreach (string pubperm in perms.publ)
{
if (MqttTopicMatch(pubperm, camTopic.PUB_SCENE_USER)) cam.HasPermissions = true;
}
cam.HasPermissions = HasPerms(camTopic.PUB_SCENE_USER);
localCameraIds.Add(cam.camid);
}

// get persistence objects
StartCoroutine(SceneLoadPersist());
}

private bool HasPerms(string topic)
{
foreach (string pubperm in perms.publ)
{
if (MqttTopicMatch(pubperm, topic)) return true;
}
return false;
}

/// <summary>
/// Disconnect MQTT and remove ARENA objects from local app.
/// </summary>
Expand Down Expand Up @@ -331,7 +335,7 @@ protected override void Update()
persist = true,
};
string payload = JsonConvert.SerializeObject(msg);
PublishObject(msg.object_id, payload, sceneObjectRights);
PublishObject(msg.object_id, payload);
}
}
#endif
Expand Down Expand Up @@ -1288,16 +1292,17 @@ private IEnumerator ExportGLTF(string name, GameObject[] gameObjects, ExportSett
}
};
string payload = JsonConvert.SerializeObject(msg);
PublishObject(msg.object_id, payload, sceneObjectRights);
PublishObject(msg.object_id, payload);
yield return true;
}

//TODO (mwfarb): prevent publish and throw errors on publishing without rights

/// <summary>
/// Object changes are published using a ClientId + ObjectId topic, a user must have permissions for the entire scene graph.
/// </summary>
public void PublishObject(string object_id, string msgJson, bool hasPermissions = true)
/// <param name="object_id">The object id.</param>
/// <param name="msgJson">The wire-format JSON string paylod for the MQTT message.</param>
/// <param name="toUserId">The user id to send this message to, if private (optional).</param>
public void PublishObject(string object_id, string msgJson, string toUserId = null)
{
ArenaObjectJson msg = JsonConvert.DeserializeObject<ArenaObjectJson>(msgJson);
msg.timestamp = GetTimestamp();
Expand All @@ -1306,15 +1311,22 @@ public void PublishObject(string object_id, string msgJson, bool hasPermissions
name_space: sceneTopic.nameSpace,
scenename: sceneTopic.sceneName,
userclient: userclient,
objectid: object_id
objectid: object_id,
touid: toUserId
);
PublishSceneMessage(objTopic.PUB_SCENE_OBJECTS, msg, hasPermissions);
if (toUserId == null)
PublishSceneMessage(objTopic.PUB_SCENE_OBJECTS, msg);
else
PublishSceneMessage(objTopic.PUB_SCENE_OBJECTS_PRIVATE, msg);
}

/// <summary>
/// Camera presence changes are published using a ObjectId-only topic, a user might only have permissions for their camid.
/// </summary>
public void PublishCamera(string object_id, string msgJson, bool hasPermissions = true)
/// <param name="object_id">The user id.</param>
/// <param name="msgJson">The wire-format JSON string paylod for the MQTT message.</param>
/// <param name="toUserId">The user id to send this message to, if private (optional).</param>
public void PublishCamera(string object_id, string msgJson, string toUserId = null)
{
ArenaObjectJson msg = JsonConvert.DeserializeObject<ArenaObjectJson>(msgJson);
msg.timestamp = GetTimestamp();
Expand All @@ -1323,21 +1335,29 @@ public void PublishCamera(string object_id, string msgJson, bool hasPermissions
name_space: sceneTopic.nameSpace,
scenename: sceneTopic.sceneName,
userclient: userclient,
userobj: object_id
userobj: object_id,
touid: toUserId
);
PublishSceneMessage(camTopic.PUB_SCENE_USER, msg, hasPermissions);
if (toUserId == null)
PublishSceneMessage(camTopic.PUB_SCENE_USER, msg);
else
PublishSceneMessage(camTopic.PUB_SCENE_USER_PRIVATE, msg);
}

[Obsolete("PublishEvent message signature has changed. Instreand of object_id, include data.target in msgJsonData.")]
public void PublishEvent(string object_id, string eventType, string source, string msgJsonData, bool hasPermissions = true)
{
PublishEvent(eventType, source, msgJsonData, hasPermissions);
PublishEvent(eventType, source, msgJsonData);
}

/// <summary>
/// Camera events are published using a ObjectId-only topic, a user might only have permissions for their camid.
/// </summary>
public void PublishEvent(string eventType, string source, string msgJsonData, bool hasPermissions = true)
/// <param name="eventType"The type of event message, e.g. "mousedown".</param>
/// <param name="source">The user id the event is from.</param>
/// <param name="msgJsonData">The wire-format JSON string paylod for the MQTT message, data section only.</param>
/// <param name="toUserId">The user id to send this message to, if private (optional).</param>
public void PublishEvent(string eventType, string source, string msgJsonData, string toUserId = null)
{
ArenaObjectJson msg = new ArenaObjectJson
{
Expand All @@ -1352,19 +1372,22 @@ public void PublishEvent(string eventType, string source, string msgJsonData, bo
name_space: sceneTopic.nameSpace,
scenename: sceneTopic.sceneName,
userclient: userclient,
userobj: source
userobj: source,
touid: toUserId
);
PublishSceneMessage(evtTopic.PUB_SCENE_USER, msg, hasPermissions);
if (toUserId == null)
PublishSceneMessage(evtTopic.PUB_SCENE_USER, msg);
else
PublishSceneMessage(evtTopic.PUB_SCENE_USER_PRIVATE, msg);
}

/// <summary>
/// Egress point for messages to send to remote graph scenes.
/// </summary>
/// <param name="topic"></param>
/// <param name="msg"></param>
/// <param name="hasPermissions"></param>
private void PublishSceneMessage(string topic, ArenaObjectJson msg, bool hasPermissions)
private void PublishSceneMessage(string topic, ArenaObjectJson msg)
{
// TODO (mwfarb): make warning of publishing without rights more effiecient
bool hasPermissions = HasPerms(topic);
byte[] payload = System.Text.Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(msg));
Publish(topic, payload); // remote
var topicSplit = topic.Split("/");
Expand Down Expand Up @@ -1569,7 +1592,7 @@ protected override void OnApplicationQuit()
action = "delete",
};
string delCamMsg = JsonConvert.SerializeObject(msg);
PublishCamera(camid, delCamMsg, sceneObjectRights);
PublishCamera(camid, delCamMsg);
}
base.OnApplicationQuit();
}
Expand Down
2 changes: 1 addition & 1 deletion Runtime/ArenaMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ private static void PublishWireObject(MenuCommand menuCommand, string object_typ
};
msg.data = data;
string payload = JsonConvert.SerializeObject(msg);
client.PublishObject(msg.object_id, payload, client.sceneObjectRights);
client.PublishObject(msg.object_id, payload);
}

static void ExportGameObject(MenuCommand command)
Expand Down
6 changes: 3 additions & 3 deletions Runtime/ArenaObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private void HandleRename()
};
string payload = JsonConvert.SerializeObject(msg);
if (ArenaClientScene.Instance)
ArenaClientScene.Instance.PublishObject(msg.object_id, payload, HasPermissions);
ArenaClientScene.Instance.PublishObject(msg.object_id, payload);
// add new object with new name, it pubs
created = false;
transform.hasChanged = true;
Expand Down Expand Up @@ -210,7 +210,7 @@ public bool PublishCreateUpdate(bool transformOnly = false)
msg.data = transformOnly ? (object)dataUnity : updatedData;
string payload = JsonConvert.SerializeObject(msg);
if (ArenaClientScene.Instance)
ArenaClientScene.Instance.PublishObject(msg.object_id, payload, HasPermissions);
ArenaClientScene.Instance.PublishObject(msg.object_id, payload);
if (!created)
created = true;

Expand Down Expand Up @@ -241,7 +241,7 @@ internal void PublishUpdate(string objData, bool all = false, bool overwrite = f
msg.data = all ? updatedData : JObject.Parse(objData);
string payload = JsonConvert.SerializeObject(msg);
if (ArenaClientScene.Instance)
ArenaClientScene.Instance.PublishObject(msg.object_id, payload, HasPermissions);
ArenaClientScene.Instance.PublishObject(msg.object_id, payload);
}

// object type
Expand Down
2 changes: 1 addition & 1 deletion Runtime/ArenaObjectAddUrlWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected void OnGUI()
};
msg.data = data;
string payload = JsonConvert.SerializeObject(msg);
client.PublishObject(msg.object_id, payload, client.sceneObjectRights);
client.PublishObject(msg.object_id, payload);
Close();
}

Expand Down

0 comments on commit bb16f82

Please sign in to comment.