public object ReadSceneObject() { byte type = ReadByte(); if (type == NetworkedSO) { long id = ReadLong(); if (id == long.MinValue) { return(null); } if (Side.IsServer) { ObjectRegistration obj = null; ServerRegistry.GetObject(id, out obj); return(obj); } else { NetworkBehaviour obj = null; ClientRegistry.GetObject(id, out obj); return(obj); } } else if (type == LocalSO) { string str = ReadString(); if (string.IsNullOrEmpty(str)) { return(null); } return(GetTransform(str)); } else { throw new InvalidOperationException("Invalid scene object type: " + type); } }
public static object ReadObject(ByteBuffer data, byte dataType) { if (dataType == ObjectType) { byte dataLength = data.ReadByte(); byte[] fieldData = data.ReadBytes(dataLength); return(SerialUtility.Deserialize(fieldData)); } else { if (dataType == Vector3Type) { return(data.ReadVector3()); } else if (dataType == QuaternionType) { return(data.ReadQuaternion()); } else if (dataType == IntType) { return(data.ReadInt()); } else if (dataType == FloatType) { return(data.ReadFloat()); } else if (dataType == LongType) { return(data.ReadLong()); } else if (dataType == BoolType) { return(data.ReadBool()); } else if (dataType == StringType) { return(data.ReadString()); } else if (dataType == BehaviourType) { long id = data.ReadLong(); if (id == long.MinValue) { return(null); } if (Side.IsClient) { NetworkBehaviour obj = null; ClientRegistry.GetObject(id, out obj); return(obj); } else { ObjectRegistration obj = null; ServerRegistry.GetObject(id, out obj); return(obj.Object); } } else if (dataType == ByteType) { return(data.ReadByte()); } else { NetworkBridge.Warn("Invalid serialization type: " + dataType); return(null); } } }
public static void HandleServerData(ByteBuffer data, Socket client) { byte type = data.ReadByte(); if (type == Data) { byte dType = data.ReadByte(); long clientId = data.ReadLong(); if (client.SpecificUdp) { Socket serverClient = ServerRegistry.GetClient(clientId); if (serverClient.Udp == null) { serverClient.Udp = client.Udp; serverClient.UdpRemote = client.UdpRemote; } } if (dType == InstantiateObject) { string resourcePath = data.ReadString(); Vector3 position = data.ReadVector3(); Quaternion rotation = data.ReadQuaternion(); Vector3 scale = data.ReadVector3(); object parent = null; NetworkBridge.AwaitInvoke(() => parent = data.ReadSceneObject()); bool here = data.ReadBool(); byte childCount = data.ReadByte(); long[] ids = new long[childCount + 1]; for (int i = 0; i < ids.Length; i++) { ids[i] = Server.GenerateId(); } long[] childIds = new long[childCount]; System.Array.Copy(ids, 1, childIds, 0, childCount); NetworkBridge.Invoke(() => { Debug.Log("Loading resource: " + resourcePath); Object resource = Resources.Load(resourcePath); GameObject inst = (GameObject)Object.Instantiate(resource); inst.name = resource.name; NetworkBehaviour net = inst.GetComponent <NetworkBehaviour>(); IEnumerable <long> userIds = here ? ServerRegistry.GetClientIDs() : ServerRegistry.GetOtherClientIDs(clientId); foreach (long userId in userIds) { Socket to = ServerRegistry.GetClient(userId); lock (to.Buffer) { to.Buffer.WriteByte(Data); to.Buffer.WriteByte(InstantiateObject); to.Buffer.WriteLong(ids[0]); to.Buffer.WriteBool(!net.ServerOnly && userId == clientId); to.Buffer.WriteString(resourcePath); to.Buffer.WriteVector3(position); to.Buffer.WriteQuaternion(rotation); to.Buffer.WriteVector3(scale); to.Buffer.WriteSceneObject(parent); to.Buffer.WriteByte(childCount); foreach (long id in childIds) { to.Buffer.WriteLong(id); } to.WriteBufferTcp(); } } net.NetworkId = ids[0]; net.transform.UseNetwork = false; net.transform.position = position; net.transform.rotation = rotation; net.transform.lossyScale = scale; if (parent == null) { net.transform.SetParent((Transform)null); } else { if (parent is ObjectRegistration) { net.transform.SetParent(((ObjectRegistration)parent).Object.transform); } else if (parent is Transform) { net.transform.SetParent((Transform)parent); } } ServerRegistry.Objects[ids[0]] = new ObjectRegistration(net, clientId, resourcePath, false, childIds); Debug.Log("Registered object with ID: " + ids[0] + "."); int idCount = 0; for (int i = 0; i < inst.transform.childCount; i++) { Transform child = inst.transform.GetChild(i); NetworkBehaviour cnet = child.GetComponent <NetworkBehaviour>(); if (cnet != null) { cnet.NetworkId = childIds[idCount++]; cnet.transform.UseNetwork = true; ServerRegistry.Objects[cnet.NetworkId] = new ObjectRegistration(net, clientId, resourcePath, true, new long[0]); Debug.Log("Registered child with ID: " + cnet.NetworkId + "."); cnet.NetworkAwake(); } } net.transform.UseNetwork = true; net.NetworkAwake(); }); } else if (dType == DestroyObject) { long objectId = data.ReadLong(); ObjectRegistration obj = null; if (!ServerRegistry.GetObject(objectId, out obj)) { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + objectId); } else { if (obj.ClientOwner == clientId) { Object.Destroy(obj.Object); ServerRegistry.Objects.Remove(objectId); foreach (long userId in ServerRegistry.GetClientIDs()) { Socket to = ServerRegistry.GetClient(userId); lock (to.Buffer) { to.Buffer.WriteByte(Data); to.Buffer.WriteByte(DestroyObject); to.Buffer.WriteLong(objectId); to.WriteBufferTcp(); } } } } } else if (dType == UpdateTransform) { long objectId = data.ReadLong(); ObjectRegistration reg = null; if (!ServerRegistry.GetObject(objectId, out reg)) { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + objectId); } else { NetworkBehaviour obj = reg.Object; if ((!obj.transform.RequiresAuthority || reg.ClientOwner == clientId) && obj.transform.AcceptUpdates) { NetworkBridge.Invoke(() => { bool old = obj.transform.UseNetwork; obj.transform.UseNetwork = true; byte tType = data.ReadByte(); if (tType == Vector3Type) { Vector3 vec = data.ReadVector3(); byte vType = data.ReadByte(); if (vType == 1) { obj.transform.position = vec; } else if (vType == 2) { obj.transform.lossyScale = vec; } } else if (tType == QuaternionType) { obj.transform.rotation = data.ReadQuaternion(); } else { Debug.LogWarning("Received malformed data packet with type: " + dType + ": invalid transformation object type id: " + tType); } obj.transform.UseNetwork = old; }); } } } else if (dType == UpdateParent) { long id = data.ReadLong(); ObjectRegistration reg = null; if (!ServerRegistry.GetObject(id, out reg)) { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + id); } else { NetworkBehaviour obj = reg.Object; if ((!obj.transform.RequiresAuthority || reg.ClientOwner == clientId) && obj.transform.AcceptUpdates) { NetworkBridge.Invoke(() => { object newParent = data.ReadSceneObject(); bool worldPositionStays = data.ReadBool(); if (newParent == null) { obj.transform.SetParent((Transform)null, worldPositionStays); } else { if (newParent is ObjectRegistration) { obj.transform.SetParent(((ObjectRegistration)newParent).Object.transform, worldPositionStays); } else if (newParent is Transform) { obj.transform.SetParent((Transform)newParent, worldPositionStays); } } }); } else { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": missing authority"); } } } else if (dType == UpdateField) { long id = data.ReadLong(); bool tcp = data.ReadBool(); string fieldName = data.ReadString(); byte dataType = data.ReadByte(); object value = ReadObject(data, dataType); ObjectRegistration reg = null; if (!ServerRegistry.GetObject(id, out reg)) { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + id); } else { Synchronized sync; FieldInfo field = reg.Object.GetLocal(fieldName, true, out sync); if (field == null) { NetworkBridge.Log("Received malformed data packet with type: " + dType + ": invalid field"); } else { if (!sync.RequiresAuthority || reg.ClientOwner == clientId) { NetworkBridge.Invoke(() => reg.Object.SetLocal(fieldName, value)); foreach (long userId in ServerRegistry.GetOtherClientIDs(clientId)) { Socket to = ServerRegistry.GetClient(userId); lock (to.Buffer) { to.Buffer.WriteByte(Data); to.Buffer.WriteByte(UpdateField); to.Buffer.WriteLong(id); to.Buffer.WriteString(fieldName); to.Buffer.WriteByte(dataType); WriteObject(value, to.Buffer); if (tcp) { to.WriteBufferTcp(); } else { to.WriteBufferUdp(); } } } } else { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": missing authority"); } } } } else if (dType == InvokeRPC) { long id = data.ReadLong(); string methodName = data.ReadString(); byte argCount = data.ReadByte(); object[] args = new object[argCount]; for (int i = 0; i < argCount; i++) { args[i] = ReadObject(data, data.ReadByte()); } ObjectRegistration reg = null; if (!ServerRegistry.GetObject(id, out reg)) { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + id); } else { RemoteMethod remote; MethodInfo method = reg.Object.GetLocalMethod(methodName, out remote); if (method == null) { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid method"); } else { if (!remote.RequiresAuthority || reg.ClientOwner == clientId) { NetworkBridge.Invoke(() => reg.Object.InvokeLocalMethod(methodName, args)); // the server shouldn't make other clients invoke the RPC, so this code is broken! /* foreach(long userId in ServerRegistry.GetOtherClientIDs(clientId)) { * Socket to = ServerRegistry.Clients[userId]; * to.Buffer.WriteByte(Data); * to.Buffer.WriteByte(InvokeRPC); * to.Buffer.WriteLong(id); * to.Buffer.WriteString(methodName); * to.Buffer.WriteByte(argCount); * foreach(object arg in args) { * WriteObject(arg, to.Buffer); * } * to.WriteBufferTcp(); * } */ } else { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": missing authority"); } } } } else { NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid type"); } } else if (type == Management) { byte mType = data.ReadByte(); if (mType == Authenticate) { long clientId = Server.GenerateId(); lock (client.Buffer) { client.Buffer.WriteByte(Management); client.Buffer.WriteByte(Authenticate); client.Buffer.WriteLong(clientId); client.Buffer.WriteByte((byte)Server.Current.Config.TickRate); client.WriteBufferTcp(); } lock (ServerRegistry.Clients) { ServerRegistry.Clients[clientId] = client; NetworkBridge.Log("Registered client with ID: " + clientId); } NetworkBridge.Invoke(() => { foreach (long id in ServerRegistry.Objects.Keys) { ObjectRegistration reg = ServerRegistry.Objects[id]; if (!reg.IsChild) { Debug.Log("objid: " + id); lock (client.Buffer) { client.Buffer.WriteByte(Data); client.Buffer.WriteByte(InstantiateObject); client.Buffer.WriteLong(id); client.Buffer.WriteBool(false); client.Buffer.WriteString(reg.ResourcePath); client.Buffer.WriteVector3(reg.Object.transform.position); client.Buffer.WriteQuaternion(reg.Object.transform.rotation); client.Buffer.WriteVector3(reg.Object.transform.lossyScale); Transform parent = reg.Object.transform.parent; /* NetworkBehaviour parentNet = null; * if(parent != null) { * parentNet = parent.gameObject.GetComponent<NetworkBehaviour>(); * } */ client.Buffer.WriteSceneObject(parent); client.Buffer.WriteByte((byte)reg.ChildIds.Length); foreach (long cid in reg.ChildIds) { client.Buffer.WriteLong(cid); } client.WriteBufferTcp(); } } NetworkBehaviour net = reg.Object; foreach (string key in net.FieldChanges.Keys) { object val = net.FieldChanges[key]; Debug.Log("field: " + key + " = " + val); lock (client.Buffer) { client.Buffer.WriteByte(Data); client.Buffer.WriteByte(UpdateField); client.Buffer.WriteLong(id); client.Buffer.WriteString(key); client.Buffer.WriteByte(GetObjectType(val)); WriteObject(val, client.Buffer); client.WriteBufferTcp(); } } } NetworkBridge.Log("Sent all existing objects and their updated fields to client."); lock (client.Buffer) { client.Buffer.WriteByte(Management); client.Buffer.WriteByte(Complete); client.WriteBufferTcp(); NetworkBridge.Log("Sent Management/Complete message."); } }); } else { NetworkBridge.Warn("Received malformed management packet with type: " + mType + ": invalid type"); } } else if (type == QueryDatabase) { long id = data.ReadLong(); string dataName = data.ReadString(); byte argCount = data.ReadByte(); object[] args = new object[argCount]; for (int i = 0; i < argCount; i++) { args[i] = ReadObject(data, data.ReadByte()); } if (ServerDatabase.IsRegistered(dataName)) { NetworkBridge.Invoke(() => { lock (client.Buffer) { client.Buffer.WriteByte(QueryDatabase); client.Buffer.WriteByte(0); client.Buffer.WriteLong(id); byte[] query = ServerDatabase.Request(dataName, args); NetworkBridge.Log("Query: " + dataName + ": " + query.Length + " bytes"); client.Buffer.WriteInt(query.Length); client.Buffer.WriteBytes(query); client.WriteBufferTcp(); } }); } else { NetworkBridge.Warn("Received malformed query packet: data not found: " + dataName); NetworkBridge.Invoke(() => { lock (client.Buffer) { client.Buffer.WriteByte(QueryDatabase); client.Buffer.WriteByte(1); client.WriteBufferTcp(); } }); } } else { NetworkBridge.Warn("Received malformed packet with type: " + type + ": invalid type (not data or management"); } }