Exemplo n.º 1
0
    /*
     *  Users SHOULD be able to:
     *      Request object creation and assign the object to themselves
     *      Request object ownership change of others' objects if the object is unlocked
     *      Request object deletion of their own objects
     *
     *
     *  Users SHOULD NOT be able to:
     *      Request object deletion of others' objects
     *      Create objects and make other players the owner
     *      Request object ownership change of others' objects if the object is locked
     *      Request changing objects' objectID, prefabID, or any other
     *
     */
    public void ConsiderChangeRequest(MeshPacket p)
    {
        if (GetAuthorized() == false)
        {
            Debug.LogError("Being asked to change the database when not authorized!");
            return;
        }
        if (LookupPlayer(p.GetSourcePlayerId()) == null)
        {
            Debug.LogError("Change request source player does not exist on the database");
            return;
        }

        StateChangeTransaction transaction = StateChangeTransaction.ParseSerializedBytes(p.GetContents());

        if (transaction.GetChangeType() == StateChange.Addition)
        {
            //Check if the desired owner is the packet sender
            if (p.GetSourcePlayerId() != transaction.GetObjectData().GetOwnerID())
            {
                Debug.LogError("Requested object creation tries to assign to new player: prohibited");
                return;
            }
            DatabaseChangeResult result = AddObject(transaction.GetObjectData(), true);
            if (result.success == false)
            {
                Debug.LogError("Requested object addition failed: " + result.error);
                return;
            }
            else
            {
                game.SpawnObject(result.data);
                EchoChangeRequest(transaction.GetTransactionID(), result.data, p.GetSourcePlayerId());
            }
        }
        else if (transaction.GetChangeType() == StateChange.Removal)
        {
            //Check if requesting user owns the object
            if (p.GetSourcePlayerId() != transaction.GetObjectData().GetOwnerID())
            {
                Debug.LogError("User trying to remove an object that doesn't belong to them");
                return;
            }
            MeshNetworkIdentity localObjectToRemove = LookupObject(transaction.GetObjectData().GetObjectID());
            if (localObjectToRemove == null)
            {
                Debug.LogError("Couldn't find the object requested to be removed.");
                return;
            }
            DatabaseChangeResult result = RemoveObject(LookupObject(transaction.GetObjectData().GetObjectID()), true);
            if (result.success == false)
            {
                Debug.LogError("Requested object removal failed: " + result.error);
                return;
            }
            else
            {
                game.RemoveObject(result.data);
                EchoChangeRequest(transaction.GetTransactionID(), localObjectToRemove.GetObjectID(), p.GetSourcePlayerId());
            }
        }
        else if (transaction.GetChangeType() == StateChange.Change)
        {
            if (p.GetSourcePlayerId() != transaction.GetObjectData().GetOwnerID())
            {
                Debug.LogError("User trying to change an object that doesn't belong to them");
                return;
            }
            MeshNetworkIdentity localObjectToChange = LookupObject(transaction.GetObjectData().GetObjectID());
            if (localObjectToChange == null)
            {
                Debug.LogError("Couldn't find the object requested to be changed.");
                return;
            }
            DatabaseChangeResult result = ChangeObject(LookupObject(transaction.GetObjectData().GetObjectID()), true);
            if (result.success == false)
            {
                Debug.LogError("Requested object change failed: " + result.error);
                return;
            }
            else
            {
                EchoChangeRequest(transaction.GetTransactionID(), localObjectToChange.GetObjectID(), p.GetSourcePlayerId());
            }
        }
    }
Exemplo n.º 2
0
    //This is called when the authorized database sends an update to this database.
    //If this object is the authorized database, this should never be called.
    public void ReceiveDeltaUpdate(DatabaseUpdate dbup)
    {
        //TODO: Write safe methods for local addition/deletion etc
        //TODO: Make sure that network and local references are not confused (StateChange.Change)
        //TODO: Refactor "override" full update system so that omissions are meaningful
        foreach (Player p in dbup.playerDelta.Keys)
        {
            if (dbup.playerDelta[p] == StateChange.Addition)
            {
                AddPlayer(p, false);
            }
            else if (dbup.playerDelta[p] == StateChange.Removal)
            {
                RemovePlayer(p, false);
            }
            else if (dbup.playerDelta[p] == StateChange.Change)
            {
                playerList[p.GetUniqueID()].DeepCopyAndApply(p);
            }
            else if (dbup.playerDelta[p] == StateChange.Override)     //Probably coming from a FullUpdate
            {
                Debug.LogError("Received an override update inside a delta update");
            }
        }
        foreach (MeshNetworkIdentity i in dbup.objectDelta.Keys)
        {
            if (dbup.objectDelta[i] == StateChange.Addition)
            {
                //If the incoming object is the database, we don't want to create it
                //(because this script is running off of the already created database!)
                //We only want to create a recursive link.
                if (i.GetObjectID() == (ushort)ReservedObjectIDs.DatabaseObject)
                {
                    DatabaseChangeResult result = AddObject(GetIdentity(), false);
                    if (result.success)
                    {
                        Debug.Log("Successfully added database to database: recursive link achieved");
                    }
                }
                else
                {
                    DatabaseChangeResult result = AddObject(i, false);
                    if (result.success)
                    {
                        game.SpawnObject(i.GetObjectID());
                    }
                }
            }
            else if (dbup.objectDelta[i] == StateChange.Removal)
            {
                DatabaseChangeResult result = RemoveObject(i, false);
                if (result.success)
                {
                    game.RemoveObject(i.GetObjectID());
                }
            }
            else if (dbup.objectDelta[i] == StateChange.Change)
            {
                objectList[i.GetObjectID()].DeepCopyAndApply(i);
            }
            else if (dbup.objectDelta[i] == StateChange.Override)     //Probably coming from a FullUpdate
            {
                Debug.LogError("Received an override update inside a delta update");
            }
        }

        ushort check = GenerateDatabaseChecksum(playerList, objectList);

        if (check != dbup.fullHash)
        {
            Debug.Log("Database checksum doesn't match: " + check + " vs " + dbup.fullHash + ". Requesting full update.");
            MeshPacket p = new MeshPacket(new byte[0], PacketType.FullUpdateRequest,
                                          GetIdentity().meshnetReference.GetLocalPlayerID(),
                                          GetIdentity().GetOwnerID(),
                                          GetIdentity().GetObjectID(),
                                          GetIdentity().GetObjectID(),
                                          GetSubcomponentID());
            GetIdentity().RoutePacket(p);
        }
        else
        {
            //Debug.Log("Delta successful, hash matches");
        }
    }