new server that handles master clients; new client that handles additional objects in scene, with some progress towards instantiation and deleting
parent
e33201593b
commit
a967795b58
|
|
@ -0,0 +1,11 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public abstract class NetworkObject: MonoBehaviour
|
||||||
|
{
|
||||||
|
public NetworkPlayer owner;
|
||||||
|
public string networkId;
|
||||||
|
public abstract byte[] getSyncMessage(); //local owner asks for this and sends it periodically
|
||||||
|
public abstract void handleSyncMessage(byte[] message); //remote owner will call this
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dd77ffdf919cc444f863d7bf0cda29ea
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -1150,6 +1150,101 @@ CanvasRenderer:
|
||||||
m_PrefabAsset: {fileID: 0}
|
m_PrefabAsset: {fileID: 0}
|
||||||
m_GameObject: {fileID: 711524766}
|
m_GameObject: {fileID: 711524766}
|
||||||
m_CullTransparentMesh: 1
|
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
|
--- !u!1 &720503449
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
@ -1819,11 +1914,12 @@ MonoBehaviour:
|
||||||
m_Script: {fileID: 11500000, guid: 03a4d4e1a7fd74c7ab2eccca4ce168db, type: 3}
|
m_Script: {fileID: 11500000, guid: 03a4d4e1a7fd74c7ab2eccca4ce168db, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
host: neko.ugavel.com
|
host: localhost
|
||||||
port: 3290
|
port: 3290
|
||||||
userid: -1
|
userid: -1
|
||||||
room:
|
room:
|
||||||
playerPrefab: {fileID: 6139051692386484099, guid: d4158ab9c4a204cdbba28d3273fc1fb3, type: 3}
|
playerPrefab: {fileID: 6139051692386484099, guid: d4158ab9c4a204cdbba28d3273fc1fb3, type: 3}
|
||||||
|
prefabs: []
|
||||||
connected: 0
|
connected: 0
|
||||||
--- !u!1 &1154194181
|
--- !u!1 &1154194181
|
||||||
GameObject:
|
GameObject:
|
||||||
|
|
@ -2255,6 +2351,7 @@ GameObject:
|
||||||
- component: {fileID: 1434745019}
|
- component: {fileID: 1434745019}
|
||||||
- component: {fileID: 1434745022}
|
- component: {fileID: 1434745022}
|
||||||
- component: {fileID: 1434745023}
|
- component: {fileID: 1434745023}
|
||||||
|
- component: {fileID: 1434745024}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: Dissonance
|
m_Name: Dissonance
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
|
|
@ -2365,6 +2462,25 @@ MonoBehaviour:
|
||||||
_tokens: []
|
_tokens: []
|
||||||
_roomName: Global
|
_roomName: Global
|
||||||
_useTrigger: 0
|
_useTrigger: 0
|
||||||
|
--- !u!114 &1434745024
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1434745018}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 03a4d4e1a7fd74c7ab2eccca4ce168db, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
host:
|
||||||
|
port: 0
|
||||||
|
userid: -1
|
||||||
|
room:
|
||||||
|
playerPrefab: {fileID: 0}
|
||||||
|
prefabs: []
|
||||||
|
connected: 0
|
||||||
--- !u!1 &1484033255
|
--- !u!1 &1484033255
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
@ -2634,6 +2750,54 @@ RectTransform:
|
||||||
m_AnchoredPosition: {x: 0, y: 0}
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
m_SizeDelta: {x: -20, y: -20}
|
m_SizeDelta: {x: -20, y: -20}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
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
|
--- !u!1 &1760805524
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public class SyncTransform : 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3f1f9b0bbd93a484a987c51f1107ebe5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -22,6 +22,11 @@ public class NetworkManager : MonoBehaviour
|
||||||
public Action<NetworkPlayer> onJoinedRoom = delegate { };
|
public Action<NetworkPlayer> onJoinedRoom = delegate { };
|
||||||
public Action<NetworkPlayer> onPlayerJoined = delegate { };
|
public Action<NetworkPlayer> onPlayerJoined = delegate { };
|
||||||
public Action<NetworkPlayer> onPlayerLeft = delegate { };
|
public Action<NetworkPlayer> onPlayerLeft = delegate { };
|
||||||
|
|
||||||
|
public List<NetworkObject> prefabs = new List<NetworkObject>();
|
||||||
|
|
||||||
|
public Dictionary<string, NetworkObject> objects = new Dictionary<string, NetworkObject>(); //maintains a list of all known objects on the server (ones that have ids)
|
||||||
|
NetworkPlayer masterPlayer = null;
|
||||||
#endregion
|
#endregion
|
||||||
// Use this for initialization
|
// Use this for initialization
|
||||||
public class Message
|
public class Message
|
||||||
|
|
@ -47,9 +52,9 @@ public class NetworkManager : MonoBehaviour
|
||||||
receivedMessages.Add(m);
|
receivedMessages.Add(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
lock(receivedMessages) {
|
lock(receivedMessages) { //the main thread, which can do Unity stuff
|
||||||
foreach(Message m in receivedMessages)
|
foreach(Message m in receivedMessages)
|
||||||
{
|
{
|
||||||
if(m.type == 0) //when you join the server
|
if(m.type == 0) //when you join the server
|
||||||
|
|
@ -57,7 +62,7 @@ public class NetworkManager : MonoBehaviour
|
||||||
this.userid = m.sender;
|
this.userid = m.sender;
|
||||||
Debug.Log("joined server");
|
Debug.Log("joined server");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.type == 2)
|
if (m.type == 2)
|
||||||
{
|
{
|
||||||
//if this message is for me, that means I joined a new room...
|
//if this message is for me, that means I joined a new room...
|
||||||
|
|
@ -104,12 +109,44 @@ public class NetworkManager : MonoBehaviour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(m.type == 3)
|
if(m.type == 3) //generic message
|
||||||
{
|
{
|
||||||
|
|
||||||
players[m.sender]?.handleMessage(m);
|
players[m.sender]?.handleMessage(m);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if(m.type == 4) //change master player (this should only happen when the first player joins or if the master player leaves)
|
||||||
|
{
|
||||||
|
if (masterPlayer == null)
|
||||||
|
{
|
||||||
|
masterPlayer = players[m.sender];
|
||||||
|
|
||||||
|
//no master player yet, add the scene objects
|
||||||
|
NetworkObject[] sceneObjects = GameObject.FindObjectsOfType<NetworkObject>(); //add all local network objects
|
||||||
|
for (int i = 0; i < sceneObjects.Length; i++)
|
||||||
|
{
|
||||||
|
sceneObjects[i].networkId = -1 + "-" + i;
|
||||||
|
sceneObjects[i].owner = masterPlayer;
|
||||||
|
objects.Add(sceneObjects[i].networkId,sceneObjects[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
masterPlayer = players[m.sender];
|
||||||
|
}
|
||||||
|
|
||||||
|
masterPlayer.setAsMasterPlayer();
|
||||||
|
|
||||||
|
//master player should take over any objects that do not have an owner
|
||||||
|
|
||||||
|
foreach(KeyValuePair<string,NetworkObject> kvp in objects)
|
||||||
|
{
|
||||||
|
kvp.Value.owner = masterPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
messageReceived(m);
|
messageReceived(m);
|
||||||
}
|
}
|
||||||
receivedMessages.Clear();
|
receivedMessages.Clear();
|
||||||
|
|
@ -142,7 +179,7 @@ public class NetworkManager : MonoBehaviour
|
||||||
Debug.Log("On client connect exception " + e);
|
Debug.Log("On client connect exception " + e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void handleMessage(string s)
|
void handleMessage(string s) //this parses messages from the server, and adds them to a queue to be processed on the main thread
|
||||||
{
|
{
|
||||||
Message m = new Message();
|
Message m = new Message();
|
||||||
string[] sections = s.Split(':');
|
string[] sections = s.Split(':');
|
||||||
|
|
@ -192,6 +229,16 @@ public class NetworkManager : MonoBehaviour
|
||||||
m.sender = int.Parse(sections[1]);
|
m.sender = int.Parse(sections[1]);
|
||||||
m.text = sections[2];
|
m.text = sections[2];
|
||||||
addMessage(m);
|
addMessage(m);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: //change master client
|
||||||
|
{
|
||||||
|
if(sections.Length > 1)
|
||||||
|
{
|
||||||
|
m.type = 4;
|
||||||
|
m.sender = int.Parse(sections[1]);
|
||||||
|
addMessage(m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ public class NetworkPlayer : MonoBehaviour, Dissonance.IDissonancePlayer
|
||||||
public NetworkManager manager;
|
public NetworkManager manager;
|
||||||
Vector3 networkPosition;
|
Vector3 networkPosition;
|
||||||
public bool isLocal = false;
|
public bool isLocal = false;
|
||||||
|
public int lastObjectId=0; //for instantiation
|
||||||
|
|
||||||
public Dissonance.VelCommsNetwork commsNetwork;
|
public Dissonance.VelCommsNetwork commsNetwork;
|
||||||
bool isSpeaking = false;
|
bool isSpeaking = false;
|
||||||
|
|
@ -25,6 +26,7 @@ public class NetworkPlayer : MonoBehaviour, Dissonance.IDissonancePlayer
|
||||||
public Quaternion Rotation => transform.rotation;
|
public Quaternion Rotation => transform.rotation;
|
||||||
public NetworkPlayerType Type => isLocal?NetworkPlayerType.Local:NetworkPlayerType.Remote;
|
public NetworkPlayerType Type => isLocal?NetworkPlayerType.Local:NetworkPlayerType.Remote;
|
||||||
public bool IsTracking => true;
|
public bool IsTracking => true;
|
||||||
|
bool isMaster = false;
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
|
|
@ -132,6 +134,66 @@ public class NetworkPlayer : MonoBehaviour, Dissonance.IDissonancePlayer
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "5": //sync update for an object I may own
|
||||||
|
{
|
||||||
|
|
||||||
|
string objectKey = sections[1];
|
||||||
|
string syncMessage = sections[2];
|
||||||
|
byte[] messageBytes = Convert.FromBase64String(syncMessage);
|
||||||
|
if (manager.objects.ContainsKey(objectKey))
|
||||||
|
{
|
||||||
|
if(manager.objects[objectKey].owner == this)
|
||||||
|
{
|
||||||
|
manager.objects[objectKey].handleSyncMessage(messageBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "7": //I'm trying to instantiate an object (sent to everyone)
|
||||||
|
{
|
||||||
|
int objectId = int.Parse(sections[1]);
|
||||||
|
string prefabName = sections[2];
|
||||||
|
NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName);
|
||||||
|
if (temp != null)
|
||||||
|
{
|
||||||
|
NetworkObject instance = GameObject.Instantiate<NetworkObject>(temp);
|
||||||
|
instance.networkId = this.userid + "-" + objectId;
|
||||||
|
|
||||||
|
instance.owner = this;
|
||||||
|
manager.objects.Add(instance.networkId, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
if (manager.objects[objectKey].owner == this)
|
||||||
|
{
|
||||||
|
GameObject.Destroy(manager.objects[objectKey].gameObject);
|
||||||
|
}
|
||||||
|
manager.objects.Remove(objectKey);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,4 +216,21 @@ public class NetworkPlayer : MonoBehaviour, Dissonance.IDissonancePlayer
|
||||||
manager.sendTo(0, "3," + id+";");
|
manager.sendTo(0, "3," + id+";");
|
||||||
commsNetwork.comms.TrackPlayerPosition(this);
|
commsNetwork.comms.TrackPlayerPosition(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAsMasterPlayer()
|
||||||
|
{
|
||||||
|
isMaster = true;
|
||||||
|
//if I'm master, I'm now responsible for updating all scene objects
|
||||||
|
//FindObjectsOfType<NetworkObject>();
|
||||||
|
}
|
||||||
|
public void syncObject(NetworkObject obj)
|
||||||
|
{
|
||||||
|
byte[] data = obj.getSyncMessage();
|
||||||
|
manager.sendTo(0, "5," + obj.networkId + "," + Convert.ToBase64String(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void instantiateObject(string prefab)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using UnityEngine;
|
||||||
|
|
||||||
namespace Dissonance
|
namespace Dissonance
|
||||||
{
|
{
|
||||||
|
[RequireComponent(typeof(DissonanceComms),typeof(NetworkManager))]
|
||||||
public class VelCommsNetwork : MonoBehaviour, ICommsNetwork
|
public class VelCommsNetwork : MonoBehaviour, ICommsNetwork
|
||||||
{
|
{
|
||||||
public ConnectionStatus Status
|
public ConnectionStatus Status
|
||||||
|
|
@ -39,8 +40,6 @@ namespace Dissonance
|
||||||
ConnectionStatus _status = ConnectionStatus.Disconnected;
|
ConnectionStatus _status = ConnectionStatus.Disconnected;
|
||||||
CodecSettings initSettings;
|
CodecSettings initSettings;
|
||||||
public string dissonanceId;
|
public string dissonanceId;
|
||||||
List<VoicePacket> packets = new List<VoicePacket>();
|
|
||||||
bool loopBackSound = false;
|
|
||||||
public DissonanceComms comms;
|
public DissonanceComms comms;
|
||||||
public NetworkManager manager;
|
public NetworkManager manager;
|
||||||
NetworkPlayer myPlayer;
|
NetworkPlayer myPlayer;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ rooms - a list of rooms on the server, with counts
|
||||||
|
|
||||||
3:user_id:Message\n - message from sender user_id
|
3:user_id:Message\n - message from sender user_id
|
||||||
|
|
||||||
|
4:user_id\n - You are the master client
|
||||||
|
|
||||||
Unity-side.
|
Unity-side.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,36 @@ def send_client_message(client, message):
|
||||||
client.message_lock.release()
|
client.message_lock.release()
|
||||||
client.message_ready.set()
|
client.message_ready.set()
|
||||||
|
|
||||||
|
def leave_room(client, clientDisconnected=False):
|
||||||
|
global rooms
|
||||||
|
global rooms_lock
|
||||||
|
choseNewMaster = False
|
||||||
|
newMasterId = -1
|
||||||
|
rooms_lock.acquire()
|
||||||
|
try:
|
||||||
|
rooms[client.room].clients.remove(client)
|
||||||
|
if(len(rooms[client.room].clients) == 0):
|
||||||
|
del rooms[client.room]
|
||||||
|
elif rooms[client.room].master == client:
|
||||||
|
rooms[client.room].master = rooms[client.room].clients[0]
|
||||||
|
newMasterId = rooms[client.room].master.id
|
||||||
|
choseNewMaster = True
|
||||||
|
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("not in room")
|
||||||
|
rooms_lock.release()
|
||||||
|
send_room_message(client.room, f"2:{client.id}:\n") #client not in the room anymore
|
||||||
|
if not clientDisconnected:
|
||||||
|
send_client_message(client,f"2:{client.id}:\n") #so send again to them
|
||||||
|
else:
|
||||||
|
client_lock.acquire()
|
||||||
|
del client_dict[client.id] #remove the client from the list of clients...
|
||||||
|
client_lock.release()
|
||||||
|
if choseNewMaster:
|
||||||
|
send_room_message(client.room,f"4:{newMasterId}\n")
|
||||||
|
client.room = ""
|
||||||
|
|
||||||
def decode_message(client,message):
|
def decode_message(client,message):
|
||||||
global rooms
|
global rooms
|
||||||
global rooms_lock
|
global rooms_lock
|
||||||
|
|
@ -68,50 +98,46 @@ def decode_message(client,message):
|
||||||
if messageType == '2' and len(decodedMessage) > 1:
|
if messageType == '2' and len(decodedMessage) > 1:
|
||||||
|
|
||||||
#join or create a room
|
#join or create a room
|
||||||
|
print("request to join " + decodedMessage[1] + " from " + str(client.id))
|
||||||
roomName = decodedMessage[1]
|
roomName = decodedMessage[1]
|
||||||
if client.room == roomName: #don't join the same room
|
if client.room == roomName: #don't join the same room
|
||||||
|
print("Client trying to join the same room")
|
||||||
pass
|
pass
|
||||||
elif (roomName == '-1') and client.room != '': #can't leave a room if you aren't in one
|
elif (roomName == '-1') and client.room != '': #can't leave a room if you aren't in one
|
||||||
#leave the room
|
#leave the room
|
||||||
rooms_lock.acquire()
|
leave_room(client)
|
||||||
try:
|
|
||||||
|
|
||||||
rooms[client.room].clients.remove(client)
|
|
||||||
if(len(rooms[client.room].clients) == 0):
|
|
||||||
del rooms[client.room]
|
|
||||||
except Exception as e:
|
|
||||||
print("not in room")
|
|
||||||
rooms_lock.release()
|
|
||||||
send_room_message(client.room, f"2:{client.id}:\n")
|
|
||||||
send_client_message(client,f"2:{client.id}:\n")
|
|
||||||
client.room = ''
|
|
||||||
elif roomName != '': #join or create the room
|
elif roomName != '': #join or create the room
|
||||||
rooms_lock.acquire()
|
|
||||||
|
|
||||||
|
|
||||||
|
if client.room != '':
|
||||||
|
#leave that room
|
||||||
|
leave_room(client)
|
||||||
|
|
||||||
|
masterId = -1
|
||||||
|
rooms_lock.acquire()
|
||||||
|
|
||||||
if roomName in rooms:
|
if roomName in rooms:
|
||||||
#join the room
|
#join the room
|
||||||
rooms[roomName].clients.append(client)
|
rooms[roomName].clients.append(client)
|
||||||
|
masterId = rooms[roomName].master.id
|
||||||
else:
|
else:
|
||||||
#create the room and join
|
#create the room and join it as master
|
||||||
rooms[roomName] = types.SimpleNamespace(name=roomName,clients=[client],room_lock=threading.Lock())
|
rooms[roomName] = types.SimpleNamespace(name=roomName,clients=[client],master=client,room_lock=threading.Lock())
|
||||||
|
masterId = client.id
|
||||||
|
|
||||||
rooms_lock.release()
|
|
||||||
|
|
||||||
if (client.room != '') and (client.room != roomName): #client left the previous room
|
current_clients = rooms[roomName].clients
|
||||||
send_room_message(client.room, f"2:{client.id}:{roomName}:\n")
|
rooms_lock.release()
|
||||||
|
|
||||||
client.room = roomName #client joins the new room
|
client.room = roomName #client joins the new room
|
||||||
#send a message to the clients new room that they joined!
|
#send a message to the clients new room that they joined!
|
||||||
send_room_message(roomName, f"2:{client.id}:{client.room}\n")
|
send_room_message(roomName, f"2:{client.id}:{client.room}\n")
|
||||||
|
|
||||||
for c in rooms[roomName].clients:
|
|
||||||
|
for c in current_clients: #tell that client about all the other clients in the room
|
||||||
if c.id != client.id:
|
if c.id != client.id:
|
||||||
send_client_message(client,f"2:{c.id}:{client.room}\n")
|
send_client_message(client,f"2:{c.id}:{client.room}\n")
|
||||||
|
|
||||||
|
|
||||||
|
send_client_message(client, f"4:{masterId}\n") #tell the client who the master is
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -157,16 +183,10 @@ def client_read_thread(conn, addr, client):
|
||||||
client.message_ready.set()
|
client.message_ready.set()
|
||||||
pass
|
pass
|
||||||
#now we can kill the client, removing the client from the rooms
|
#now we can kill the client, removing the client from the rooms
|
||||||
client_lock.acquire()
|
|
||||||
rooms_lock.acquire()
|
|
||||||
if client.room != '':
|
leave_room(client,True)
|
||||||
rooms[client.room].clients.remove(client)
|
|
||||||
if(len(rooms[client.room].clients) == 0):
|
|
||||||
del rooms[client.room]
|
|
||||||
del client_dict[client.id] #remove the client from the list of clients...
|
|
||||||
rooms_lock.release()
|
|
||||||
client_lock.release()
|
|
||||||
send_room_message(client.room, f"2:{client.id}:\n")
|
|
||||||
print("client destroyed")
|
print("client destroyed")
|
||||||
def client_write_thread(conn, addr, client):
|
def client_write_thread(conn, addr, client):
|
||||||
while client.alive:
|
while client.alive:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue