Ejemplo n.º 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);
            }
        }
Ejemplo n.º 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);
         }
     }
 }
Ejemplo n.º 3
0
        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");
            }
        }