instantiation working nicely, including when objects join later

handTracking
Kyle Johnsen 2022-01-03 23:36:11 -05:00
parent 0167ca3003
commit 1a57cd3879
9 changed files with 387 additions and 177 deletions

View File

@ -9,7 +9,7 @@ public abstract class NetworkObject: MonoBehaviour, NetworkSyncable
{
public NetworkPlayer owner;
public string networkId; //this is forged from the combination of the creator's id (-1 in the case of a scene object) and an object id, so it's always unique for a room
public string prefabName; //this may be empty if it's not a prefab (scene object)
public abstract byte[] getSyncMessage();
public abstract void handleSyncMessage(byte[] message);
}

View File

@ -1150,101 +1150,6 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 711524766}
m_CullTransparentMesh: 1
--- !u!1 &720148908
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 720148909}
- component: {fileID: 720148912}
- component: {fileID: 720148911}
- component: {fileID: 720148910}
m_Layer: 0
m_Name: Sphere
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &720148909
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 720148908}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 1720689858}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!135 &720148910
SphereCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 720148908}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Radius: 0.5
m_Center: {x: 0, y: 0, z: 0}
--- !u!23 &720148911
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 720148908}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &720148912
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 720148908}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!1 &720503449
GameObject:
m_ObjectHideFlags: 0
@ -1919,7 +1824,8 @@ MonoBehaviour:
userid: -1
room:
playerPrefab: {fileID: 6139051692386484099, guid: d4158ab9c4a204cdbba28d3273fc1fb3, type: 3}
prefabs: []
prefabs:
- {fileID: 8565720275311462452, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
connected: 0
--- !u!1 &1154194181
GameObject:
@ -2750,54 +2656,6 @@ RectTransform:
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: -20, y: -20}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &1720689856
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1720689858}
- component: {fileID: 1720689857}
m_Layer: 0
m_Name: TestNetworkedGameObject
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1720689857
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1720689856}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3f1f9b0bbd93a484a987c51f1107ebe5, type: 3}
m_Name:
m_EditorClassIdentifier:
owner: {fileID: 0}
networkId:
targetPosition: {x: 0, y: 0, z: 0}
targetRotation: {x: 0, y: 0, z: 0, w: 0}
--- !u!4 &1720689858
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1720689856}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 720148909}
m_Father: {fileID: 0}
m_RootOrder: 6
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1760805524
GameObject:
m_ObjectHideFlags: 0
@ -3530,3 +3388,60 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2144436499}
m_CullTransparentMesh: 1
--- !u!1001 &8565720276829121781
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 8565720275311462453, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_Name
value: TestNetworkedGameObject
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_RootOrder
value: 6
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3}

View File

@ -0,0 +1,145 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &8565720275311462453
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8565720275311462455}
- component: {fileID: 8565720275311462452}
m_Layer: 0
m_Name: TestNetworkedGameObject
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &8565720275311462455
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8565720275311462453}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 8565720276181857624}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &8565720275311462452
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8565720275311462453}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3f1f9b0bbd93a484a987c51f1107ebe5, type: 3}
m_Name:
m_EditorClassIdentifier:
owner: {fileID: 0}
networkId:
targetPosition: {x: 0, y: 0, z: 0}
targetRotation: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &8565720276181857625
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8565720276181857624}
- component: {fileID: 8565720276181857605}
- component: {fileID: 8565720276181857626}
- component: {fileID: 8565720276181857627}
m_Layer: 0
m_Name: Sphere
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &8565720276181857624
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8565720276181857625}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 8565720275311462455}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!33 &8565720276181857605
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8565720276181857625}
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0}
--- !u!23 &8565720276181857626
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8565720276181857625}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!135 &8565720276181857627
SphereCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8565720276181857625}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Radius: 0.5
m_Center: {x: 0, y: 0, z: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6e4a023f70e01405e8b249a4488fe319
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -32,9 +32,13 @@ public class NetworkPlayer : MonoBehaviour, Dissonance.IDissonancePlayer
public bool IsTracking => true;
bool isMaster = false;
void Awake()
void Start()
{
myObject.owner = this;
this.manager = GameObject.FindObjectOfType<NetworkManager>();
manager.onPlayerJoined += handlePlayerJoined;
}
// Update is called once per frame
@ -58,6 +62,23 @@ public class NetworkPlayer : MonoBehaviour, Dissonance.IDissonancePlayer
}
public void handlePlayerJoined(NetworkPlayer player)
{
//if this is the local player, go through the objects that I own, and send instantiation messages for the ones that have prefab names
if (this.isLocal)
{
foreach(KeyValuePair<string,NetworkObject> kvp in manager.objects)
{
if(kvp.Value.owner == this && kvp.Value.prefabName != "")
{
manager.sendTo(0, "7," + kvp.Value.networkId + "," + kvp.Value.prefabName);
}
}
}
}
public void handleMessage(NetworkManager.Message m)
{
//these are generally things that come from the "owner" and should be enacted locally, where appropriate
@ -133,27 +154,29 @@ public class NetworkPlayer : MonoBehaviour, Dissonance.IDissonancePlayer
}
case "6": //I'm trying to take ownership of an object
{
int objectId = int.Parse(sections[1]);
int creatorId = int.Parse(sections[2]);
string objectKey = creatorId + "-" + objectId;
if (manager.objects.ContainsKey(objectKey))
{
manager.objects[objectKey].owner = this;
string networkId = sections[1];
if (manager.objects.ContainsKey(networkId))
{
manager.objects[networkId].owner = this;
}
break;
}
case "7": //I'm trying to instantiate an object (sent to everyone)
case "7": //I'm trying to instantiate an object
{
int objectId = int.Parse(sections[1]);
string networkId = sections[1];
string prefabName = sections[2];
if (manager.objects.ContainsKey(networkId))
{
break; //we already have this one, ignore
}
NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName);
if (temp != null)
{
NetworkObject instance = GameObject.Instantiate<NetworkObject>(temp);
instance.networkId = this.userid + "-" + objectId;
instance.networkId = networkId;
instance.prefabName = prefabName;
instance.owner = this;
manager.objects.Add(instance.networkId, instance);
}
@ -162,16 +185,12 @@ public class NetworkPlayer : MonoBehaviour, Dissonance.IDissonancePlayer
}
case "8": //I'm trying to destroy a gameobject I own (I guess this is sent to everyone)
{
int objectId = int.Parse(sections[1]);
int creatorId = int.Parse(sections[2]);
string objectKey = creatorId + "-" + objectId;
if (manager.objects.ContainsKey(objectKey))
string networkId = sections[1];
if (manager.objects.ContainsKey(networkId) && manager.objects[networkId].owner == this)
{
if (manager.objects[objectKey].owner == this)
{
GameObject.Destroy(manager.objects[objectKey].gameObject);
}
manager.objects.Remove(objectKey);
GameObject.Destroy(manager.objects[networkId].gameObject);
manager.objects.Remove(networkId);
}
break;
}
@ -218,8 +237,42 @@ public class NetworkPlayer : MonoBehaviour, Dissonance.IDissonancePlayer
}
}
public void instantiateObject(string prefab)
public NetworkObject networkInstantiate(string prefabName)
{
if (!isLocal)
{
return null; //must be the local player to call instantiate
}
string networkId = this.userid + "-" + lastObjectId++;
NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName);
if (temp != null)
{
NetworkObject instance = GameObject.Instantiate<NetworkObject>(temp);
instance.networkId = networkId;
instance.prefabName = prefabName;
instance.owner = this;
manager.objects.Add(instance.networkId, instance);
manager.sendTo(0, "7," + networkId + "," + prefabName);
return instance;
}
return null;
}
public void networkDestroy(string networkId)
{
if (!manager.objects.ContainsKey(networkId) || manager.objects[networkId].owner != this || !isLocal) return; //must be the local owner of the object to destroy it
manager.sendTo(3, "8," + networkId); //send to all, which will make me delete as well
}
public void takeOwnership(string networkId)
{
if (!manager.objects.ContainsKey(networkId) || !isLocal) return; //must exist and be the the local player
manager.objects[networkId].owner = this; //immediately successful
manager.sendTo(2, "6," + networkId); //must be ordered, so that ownership transfers are not confused
}

View File

@ -0,0 +1,80 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : NetworkObject
{
public Vector3 targetPosition;
public Quaternion targetRotation;
public override byte[] getSyncMessage()
{
float[] data = new float[7];
for (int i = 0; i < 3; i++)
{
data[i] = transform.position[i];
data[i + 3] = transform.rotation[i];
}
data[6] = transform.rotation[3];
byte[] toReturn = new byte[sizeof(float) * data.Length];
Buffer.BlockCopy(data, 0, toReturn, 0, toReturn.Length);
return toReturn;
}
public override void handleSyncMessage(byte[] message)
{
float[] data = new float[7];
Buffer.BlockCopy(message, 0, data, 0, message.Length);
for (int i = 0; i < 3; i++)
{
targetPosition[i] = data[i];
targetRotation[i] = data[i + 3];
}
targetRotation[3] = data[6];
}
// Start is called before the first frame update
void Start()
{
StartCoroutine(syncBehavior());
}
IEnumerator syncBehavior()
{
while (true)
{
if (owner != null && owner.isLocal)
{
owner.syncObject(this);
}
yield return new WaitForSeconds(.1f);
}
}
// Update is called once per frame
void Update()
{
if (owner != null && !owner.isLocal)
{
transform.position = Vector3.Lerp(transform.position, targetPosition, .1f);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, .1f);
}
else if(owner != null && owner.isLocal)
{
Vector3 movement = new Vector3();
movement.x += Input.GetAxis("Horizontal");
movement.y += Input.GetAxis("Vertical");
movement.z = 0;
transform.Translate(movement * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.Space))
{
owner.networkInstantiate("TestNetworkedGameObject");
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 89e3af759df774692a566a166b4bf69b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -13,7 +13,7 @@ GameObject:
- component: {fileID: 6854617867369839}
- component: {fileID: 5845716565458182149}
- component: {fileID: 5713671764962751473}
- component: {fileID: 2513801069545108573}
- component: {fileID: -4404668399269848200}
m_Layer: 0
m_Name: PlayerPrefab
m_TagString: Untagged
@ -109,7 +109,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d8d3b6de660834e3e898725928251405, type: 3}
m_Name:
m_EditorClassIdentifier:
myObject: {fileID: 2513801069545108573}
myObject: {fileID: -4404668399269848200}
userid: 0
username:
room:
@ -118,7 +118,7 @@ MonoBehaviour:
lastObjectId: 0
commsNetwork: {fileID: 0}
dissonanceID:
--- !u!114 &2513801069545108573
--- !u!114 &-4404668399269848200
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@ -127,7 +127,7 @@ MonoBehaviour:
m_GameObject: {fileID: 6139051692386484099}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 3f1f9b0bbd93a484a987c51f1107ebe5, type: 3}
m_Script: {fileID: 11500000, guid: 89e3af759df774692a566a166b4bf69b, type: 3}
m_Name:
m_EditorClassIdentifier:
owner: {fileID: 5713671764962751473}

View File

@ -145,14 +145,13 @@ def decode_message(client,message):
if messageType == '3' and len(decodedMessage) > 2:
subMessageType = decodedMessage[1]
if subMessageType == '0':
#send a message to everyone in the room (not synced)
#send a message to everyone else in the room (not synced)
send_room_message(client.room,f"3:{client.id}:{decodedMessage[2]}\n",client)
elif subMessageType == '1':
elif subMessageType == '1': #everyone including the client who sent it
send_room_message(client.room,f"3:{client.id}:{decodedMessage[2]}\n")
elif subMessageType == '2':
#send a message to everyone in the room (not synced)
elif subMessageType == '2': #everyone but the client, ensures order within the room
send_synced_room_message(client.room,f"3:{client.id}:{decodedMessage[2]}\n",client)
elif subMessageType == '3':
elif subMessageType == '3': #everyone including the client, ensuring order
send_synced_room_message(client.room,f"3:{client.id}:{decodedMessage[2]}\n")
def client_read_thread(conn, addr, client):