예제 #1
0
        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);
            }
        }
예제 #2
0
 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);
         }
     }
 }
예제 #3
0
        public static void HandleClientData(ByteBuffer data)
        {
            byte type = data.ReadByte();

            if (type == Data)
            {
                byte dType = data.ReadByte();
                long id    = data.ReadLong();

                /* NetworkBehaviour obj = null;
                 * if(dType != InstantiateObject && !ClientRegistry.GetObject(id, out obj)) {
                 *   NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + id);
                 * } else {*/
                if (dType == InstantiateObject)
                {
                    bool hasAuthority = data.ReadBool();
                    // Debug.Log(hasAuthority);
                    string resourcePath = data.ReadString();
                    // Debug.Log(resourcePath);
                    Vector3    position = data.ReadVector3();
                    Quaternion rotation = data.ReadQuaternion();
                    Vector3    scale    = data.ReadVector3();
                    // Debug.Log(scale);
                    // data.Debug(data.Pointer, data.Length);
                    int    ptr    = data.Pointer;
                    object parent = null;
                    NetworkBridge.AwaitInvoke(() => {
                        try {
                            parent = data.ReadSceneObject();
                        } catch (System.IndexOutOfRangeException e) {
                            NetworkBridge.Warn("hasAuthority: " + hasAuthority);
                            NetworkBridge.Warn("resourcePath: " + resourcePath);
                            NetworkBridge.Warn("position: " + position);
                            NetworkBridge.Warn("rotation: " + position);
                            NetworkBridge.Warn("scale: " + position);
                            NetworkBridge.Warn("ptr: " + ptr);
                            NetworkBridge.Warn("len: " + data.Length);
                            NetworkBridge.Warn("byte: " + data.Bytes[ptr]);

                            data.Debug(0, data.Length);
                            throw e;
                        }
                    });
                    byte childCount = data.ReadByte();

                    long[] childIds = new long[childCount];
                    for (int i = 0; i < childCount; i++)
                    {
                        childIds[i] = data.ReadLong();
                    }

                    NetworkBridge.Invoke(() => {
                        Object resource = Resources.Load(resourcePath);
                        GameObject inst = (GameObject)Object.Instantiate(resource);
                        inst.name       = resource.name;

                        NetworkBehaviour net = inst.GetComponent <NetworkBehaviour>();

                        net.NetworkId            = id;
                        net.HasAuthority         = hasAuthority;
                        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 NetworkBehaviour)
                            {
                                net.transform.SetParent(((NetworkBehaviour)parent).transform);
                            }
                            else if (parent is Transform)
                            {
                                net.transform.SetParent((Transform)parent);
                            }
                        }

                        int i = 0;
                        foreach (Transform child in net.transform)
                        {
                            NetworkBehaviour c = child.GetComponent <NetworkBehaviour>();
                            if (c != null)
                            {
                                c.transform.UseNetwork = true;
                                c.HasAuthority         = hasAuthority;
                                ClientRegistry.Objects[c.NetworkId = childIds[i++]] = c;
                                c.NetworkAwake();
                            }
                        }

                        net.transform.UseNetwork   = true;
                        ClientRegistry.Objects[id] = net;
                        Debug.Log("Registered object with ID: " + id);
                        net.NetworkAwake();
                    });
                }
                else if (dType == DestroyObject)
                {
                    NetworkBehaviour obj = null;
                    if (!ClientRegistry.GetObject(id, out obj))
                    {
                        NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + id);
                        return;
                    }
                    NetworkBridge.Invoke(() => Object.Destroy(obj.gameObject));
                    ClientRegistry.Objects.Remove(id);
                }
                else if (dType == UpdateTransform)
                {
                    NetworkBehaviour obj = null;
                    if (!ClientRegistry.GetObject(id, out obj))
                    {
                        NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + id);
                        return;
                    }

                    if (obj.transform.AcceptUpdates && (!obj.HasAuthority || obj.transform.AcceptUpdatesWithAuthority))
                    {
                        NetworkBridge.Invoke(() => {
                            bool old = obj.transform.UseNetwork;
                            obj.transform.UseNetwork = false;
                            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)
                {
                    NetworkBehaviour obj = null;
                    if (!ClientRegistry.GetObject(id, out obj))
                    {
                        NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + id);
                        return;
                    }

                    if (obj.transform.AcceptUpdates && (!obj.HasAuthority || obj.transform.AcceptUpdatesWithAuthority))
                    {
                        NetworkBridge.Invoke(() => {
                            // ReadSceneObject needs to be called from an invocation to the bridge.
                            // is this safe?
                            object newParent        = data.ReadSceneObject();
                            bool worldPositionStays = data.ReadBool();

                            bool old = obj.transform.UseNetwork;
                            obj.transform.UseNetwork = false;
                            if (newParent == null)
                            {
                                obj.transform.SetParent((Transform)null, worldPositionStays);
                            }
                            else
                            {
                                if (newParent is NetworkBehaviour)
                                {
                                    obj.transform.SetParent(((NetworkBehaviour)newParent).transform, worldPositionStays);
                                }
                                else if (newParent is Transform)
                                {
                                    obj.transform.SetParent((Transform)newParent, worldPositionStays);
                                }
                            }
                            obj.transform.UseNetwork = old;
                        });
                    }
                }
                else if (dType == UpdateField)
                {
                    if (!Client.Current.IsAuthenticated)
                    {
                        data.Pointer = 0;
                        ExecuteLater.Add(data.CopyAll());
                    }
                    else
                    {
                        NetworkBehaviour obj = null;
                        if (!ClientRegistry.GetObject(id, out obj))
                        {
                            NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + id);
                            return;
                        }

                        string fieldName = data.ReadString();
                        byte   dataType  = data.ReadByte();
                        object value     = ReadObject(data, dataType);

                        NetworkBridge.Invoke(() => obj.SetLocal(fieldName, value, true));
                    }
                }
                else if (dType == InvokeRPC)
                {
                    NetworkBehaviour obj = null;
                    if (!ClientRegistry.GetObject(id, out obj))
                    {
                        NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid object id: " + id);
                        return;
                    }

                    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());
                    }

                    NetworkBridge.Invoke(() => obj.InvokeLocalMethod(methodName, args));
                }
                else
                {
                    NetworkBridge.Warn("Received malformed data packet with type: " + dType + ": invalid type");
                }
            }
            else if (type == Management)
            {
                byte mType = data.ReadByte();

                if (mType == Authenticate)
                {
                    Client.Current.ClientId = data.ReadLong();
                    NetworkBridge.Log("Client ID: " + Client.Current.ClientId);
                    Client.Current.TickRate = data.ReadByte();
                    NetworkBridge.Log("Network tick rate: " + Client.Current.TickRate);
                }
                else if (mType == Disconnect)
                {
                    Client.Current.Socket.Close();
                }
                else if (mType == Complete)
                {
                    NetworkBridge.Log("Authentication complete.");
                    NetworkBridge.Invoke(() => {
                        Client.Current.NotifyAuthenticate();

                        foreach (ByteBuffer buf in ExecuteLater)
                        {
                            HandleClientData(buf);
                        }

                        ExecuteLater.Clear();
                    });
                }
                else
                {
                    NetworkBridge.Warn("Received malformed management packet with type: " + mType + ": invalid type");
                }
            }
            else if (type == QueryDatabase)
            {
                byte code = data.ReadByte();
                if (code == 0)
                {
                    long       id  = data.ReadLong();
                    int        len = data.ReadInt();
                    ByteBuffer ret = new ByteBuffer(len);
                    System.Array.Copy(data.Bytes, data.Pointer, ret.Bytes, 0, ret.Length);
                    NetworkBridge.Log("Query response: " + ret.Length + " bytes");

                    NetworkBridge.Invoke(() => {
                        Client.Queries[id](ret);
                        Client.Queries.Remove(id);
                    });
                }
                else
                {
                    NetworkBridge.Warn("Received malformed query packet: query unsuccessful");
                }
            }
            else
            {
                NetworkBridge.Warn("Received malformed packet with type: " + type + ": invalid type (not data or management)");
            }
        }