예제 #1
0
    /// Send updates about just one tracked object (intended for waypoint pin)
    /// <param name="trackedObject"></param>
    public void UpdateExclusive(GameObject trackedObject)
    {
        RefreshTrackedPos(false);

        bool notFound = true;

        var entries = Entries;

        for (var i = 0; i < entries.Length; i++)
        {
            var entry = entries[i] as RadarEntry;
            if (!entry || entry.TrackedObject != trackedObject)
            {
                continue;
            }

            notFound = false;

            List <ElementValue> valuesToSend = new List <ElementValue>(10)
            {
                ElementValue
            };
            var entryElements = entry.Elements;
            for (var j = 0; j < entryElements.Length; j++)
            {
                var element = entryElements[j];
                valuesToSend.Add(element.ElementValue);
            }
            TabUpdateMessage.SendToPeepers(MasterTab.Provider, MasterTab.Type, TabAction.Update, valuesToSend.ToArray());
        }
        //if not found (being hidden etc), send just the list entry count so it would disappear for peepers, too
        if (notFound)
        {
            TabUpdateMessage.SendToPeepers(MasterTab.Provider, MasterTab.Type, TabAction.Update, new [] { ElementValue });
        }
    }
예제 #2
0
    private void UpdateGUI()
    {
        List <ElementValue> valuesToSend = new List <ElementValue>();

        valuesToSend.Add(new ElementValue()
        {
            Id = "TextTrack", Value = Encoding.UTF8.GetBytes(TrackPosition)
        });
        valuesToSend.Add(new ElementValue()
        {
            Id = "TextSong", Value = Encoding.UTF8.GetBytes(SongName)
        });
        valuesToSend.Add(new ElementValue()
        {
            Id = "TextArtist", Value = Encoding.UTF8.GetBytes(Artist)
        });
        valuesToSend.Add(new ElementValue()
        {
            Id = "ImagePlayStop", Value = Encoding.UTF8.GetBytes(PlayStopButtonPrefabImage)
        });

        // Update all UI currently opened.
        TabUpdateMessage.SendToPeepers(gameObject, NetTabType.Jukebox, TabAction.Update, valuesToSend.ToArray());
    }
예제 #3
0
 public void ServerPerformInteraction(HandApply interaction)
 {
     TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType, TabAction.Open);
 }
예제 #4
0
 public override void Interaction(HandApply interaction)
 {
     TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType.Mixer, TabAction.Open);
 }
 private TabUpdateMessage FailValidation(ConnectedPlayer player, GameObject tabProvider, string reason = "")
 {
     Logger.LogWarning($"{player.Name}: Tab interaction w/{tabProvider} denied: {reason}", Category.NetUI);
     return(TabUpdateMessage.Send(player.GameObject, tabProvider, NetTabType, TabAction.Close));
 }
    private void ProcessFurther(ConnectedPlayer player, GameObject tabProvider)
    {
        var playerScript = player.Script;
        //First Validations is for objects in the world (computers, etc), second check is for items in active hand (null rod, PADs).
        bool validate = Validations.CanApply(player.Script, tabProvider, NetworkSide.Server) ||
                        playerScript.ItemStorage.GetActiveHandSlot().ItemObject == tabProvider;

        if (!validate)
        {
            FailValidation(player, tabProvider, "Can't interact/reach");
            return;
        }

        var tabInfo = NetworkTabManager.Instance.Get(tabProvider, NetTabType);

        if (!tabInfo /* == NetworkTabInfo.Invalid*/)
        {
            //No such tab exists on server!
            FailValidation(player, tabProvider, $"No such tab: {tabProvider}/{NetTabType}");
            return;
        }

        var updatedElement = tabInfo[ElementId];

        if (updatedElement == null)
        {
            //No such element exists on server!
            FailValidation(player, tabProvider, $"No such element: {tabInfo}[{ElementId}]");
            return;
        }

        if (updatedElement.InteractionMode == ElementMode.ServerWrite)
        {
            //Don't change labels and other non-interactable elements. If this is triggered, someone's tampering with client
            FailValidation(player, tabProvider, $"Non-interactable {updatedElement}");
            return;
        }

        var valueBeforeUpdate = updatedElement.ValueObject;

        updatedElement.BinaryValue = ElementValue;
        updatedElement.ExecuteServer(player);

        if (updatedElement.InteractionMode == ElementMode.ClientWrite)
        {
            //Don't rememeber value provided by client and restore to the initial one
            updatedElement.ValueObject = valueBeforeUpdate;
        }

        //Notify all peeping players of the change
        List <ConnectedPlayer> list = NetworkTabManager.Instance.GetPeepers(tabProvider, NetTabType);

        for (var i = 0; i < list.Count; i++)
        {
            var connectedPlayer = list[i];
//Not sending that update to the same player
            if (connectedPlayer.GameObject != player.GameObject)
            {
                TabUpdateMessage.Send(connectedPlayer.GameObject, tabProvider, NetTabType, TabAction.Update,
                                      player.GameObject,
                                      new[] { new ElementValue {
                                                  Id = ElementId, Value = updatedElement.BinaryValue
                                              } });
            }
        }
    }
예제 #7
0
        public void ServerPerformInteraction(HandApply interaction)
        {
            if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Screwdriver))
            {
                AudioSourceParameters audioSourceParameters = new AudioSourceParameters(pitch: UnityEngine.Random.Range(0.8f, 1.2f));
                SoundManager.PlayNetworkedAtPos(CommonSounds.Instance.screwdriver, interaction.Performer.AssumedWorldPosServer(), audioSourceParameters, sourceObj: gameObject);
                //Unscrew panel
                panelopen = !panelopen;
                if (panelopen)
                {
                    Chat.AddActionMsgToChat(interaction.Performer,
                                            $"You unscrews the {gameObject.ExpensiveName()}'s cable panel.",
                                            $"{interaction.Performer.ExpensiveName()} unscrews {gameObject.ExpensiveName()}'s cable panel.");
                    return;
                }
                else
                {
                    Chat.AddActionMsgToChat(interaction.Performer,
                                            $"You screw in the {gameObject.ExpensiveName()}'s cable panel.",
                                            $"{interaction.Performer.ExpensiveName()} screws in {gameObject.ExpensiveName()}'s cable panel.");
                    return;
                }
            }

            if (HackingProcessBase != null)
            {
                if (panelopen && (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Cable) ||
                                  Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Wirecutter)))
                {
                    TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType.HackingPanel, TabAction.Open);
                }
            }

            if (MachineParts == null)
            {
                return;
            }

            if (canNotBeDeconstructed)
            {
                Chat.AddExamineMsgFromServer(interaction.Performer,
                                             "This machine is too well built to be deconstructed.");
                return;
            }

            if (mustBeUnanchored && gameObject.GetComponent <PushPull>()?.IsPushable == false)
            {
                Chat.AddExamineMsgFromServer(interaction.Performer,
                                             $"The {gameObject.ExpensiveName()} needs to be unanchored first.");
                return;
            }

            if (Validations.HasUsedItemTrait(interaction, CommonTraits.Instance.Crowbar) && panelopen)
            {
                //unsecure
                ToolUtils.ServerUseToolWithActionMessages(interaction, secondsToScrewdrive,
                                                          $"You start to deconstruct the {gameObject.ExpensiveName()}...",
                                                          $"{interaction.Performer.ExpensiveName()} starts to deconstruct the {gameObject.ExpensiveName()}...",
                                                          $"You deconstruct the {gameObject.ExpensiveName()}.",
                                                          $"{interaction.Performer.ExpensiveName()} deconstructs the {gameObject.ExpensiveName()}.",
                                                          () => { WhenDestroyed(null); });
            }
        }
예제 #8
0
        private void ProcessFurther(ConnectedPlayer player, GameObject tabProvider, NetMessage msg)
        {
            if (player == null)
            {
                Logger.LogWarning("[TabInteractMessage.ProcessFurther] - player is null", Category.NetUI);
                return;
            }
            else if (tabProvider == null)
            {
                Logger.LogWarning("[TabInteractMessage.ProcessFurther] - tabProvider is null", Category.NetUI);
                return;
            }

            var playerScript = player.Script;

            //First Validations is for objects in the world (computers, etc), second check is for items in active hand (null rod, PADs).
            bool validate;

            if (playerScript.PlayerState == PlayerScript.PlayerStates.Ai)
            {
                validate = Validations.CanApply(new AiActivate(player.GameObject, null,
                                                               tabProvider, Intent.Help, AiActivate.ClickTypes.NormalClick), NetworkSide.Server);
            }
            else
            {
                validate = Validations.CanApply(playerScript, tabProvider, NetworkSide.Server);

                try
                {
                    if (validate == false)
                    {
                        //Allow if in hand
                        var hand = playerScript.DynamicItemStorage.OrNull()?.GetActiveHandSlot();
                        if (hand != null)
                        {
                            validate = hand.ItemObject == tabProvider;
                        }
                    }
                }
                catch (NullReferenceException exception)
                {
                    Logger.LogError($"Caught NRE in TabInteractMessage.Process: Tab: {tabProvider.OrNull().ExpensiveName()} {exception.Message} \n {exception.StackTrace}", Category.Interaction);
                    return;
                }
            }

            if (validate == false)
            {
                FailValidation(player, tabProvider, msg, "Can't interact/reach");
                return;
            }

            var tabInfo = NetworkTabManager.Instance.Get(tabProvider, msg.NetTabType);

            if (!tabInfo /* == NetworkTabInfo.Invalid*/)
            {
                //No such tab exists on server!
                FailValidation(player, tabProvider, msg, $"No such tab: {tabProvider}/{msg.NetTabType}");
                return;
            }

            var updatedElement = tabInfo[msg.ElementId];

            if (updatedElement == null)
            {
                //No such element exists on server!
                FailValidation(player, tabProvider, msg, $"No such element: {tabInfo}[{msg.ElementId}]");
                return;
            }

            if (updatedElement.InteractionMode == ElementMode.ServerWrite)
            {
                //Don't change labels and other non-interactable elements. If this is triggered, someone's tampering with client
                FailValidation(player, tabProvider, msg, $"Non-interactable {updatedElement}");
                return;
            }

            var valueBeforeUpdate = updatedElement.ValueObject;

            updatedElement.BinaryValue = msg.ElementValue;
            updatedElement.ExecuteServer(player);

            if (updatedElement.InteractionMode == ElementMode.ClientWrite)
            {
                //Don't rememeber value provided by client and restore to the initial one
                updatedElement.ValueObject = valueBeforeUpdate;
            }

            //Notify all peeping players of the change
            List <ConnectedPlayer> list = NetworkTabManager.Instance.GetPeepers(tabProvider, msg.NetTabType);

            for (var i = 0; i < list.Count; i++)
            {
                var connectedPlayer = list[i];
//Not sending that update to the same player
                if (connectedPlayer.GameObject != player.GameObject)
                {
                    TabUpdateMessage.Send(connectedPlayer.GameObject, tabProvider, msg.NetTabType, TabAction.Update,
                                          player.GameObject,
                                          new[] { new ElementValue {
                                                      Id = msg.ElementId, Value = updatedElement.BinaryValue
                                                  } });
                }
            }
        }
예제 #9
0
 //Ai interaction
 public override void AiInteraction(AiActivate interaction)
 {
     TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType.Mixer, TabAction.Open);
 }
예제 #10
0
 public void ServerCloseTabFor(ConnectedPlayer player)
 {
     TabUpdateMessage.Send(player.GameObject, Provider, Type, TabAction.Close);
 }
예제 #11
0
 public void ServerPerformInteraction(InventoryApply interaction)
 {
     playerInteracted = interaction.Performer;
     TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType, TabAction.Open);
 }
예제 #12
0
 public void ServerPerformInteraction(InventoryApply interaction)
 {
     //show the paper to the client
     TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType, TabAction.Open);
     paper.UpdatePlayer(interaction.Performer);
 }
예제 #13
0
    public static TabUpdateMessage Send(GameObject recipient, GameObject provider, NetTabType type, TabAction tabAction,
                                        GameObject changedBy  = null,
                                        ElementValue[] values = null)
    {
        switch (tabAction)
        {
        case TabAction.Open:
            NetworkTabManager.Instance.Add(provider, type, recipient);
            values = NetworkTabManager.Instance.Get(provider, type).ElementValues;
            break;

        case TabAction.Close:
            NetworkTabManager.Instance.Remove(provider, type, recipient);
            break;

        case TabAction.Update:
            //fixme: duplication of NetTab.ValidatePeepers
            //Not sending updates and closing tab for players that don't pass the validation anymore
            var validate = Validations.CanApply(recipient, provider, NetworkSide.Server);
            if (!validate)
            {
                Send(recipient, provider, type, TabAction.Close);
                return(null);
            }
            break;
        }

        // SingleMessage, MoreIncoming, EndOfMessage
        var id = TabMessageType.SingleMessage;

        Counter++;
        var uniqueID = Counter;

        if (Counter > 10000)
        {
            Counter = 0;
        }

        var elementValuesLists = new Dictionary <List <ElementValue>, TabMessageType>();

        if (values != null && tabAction != TabAction.Close)
        {
            // get max possible packet size from current transform
            var maxPacketSize = Transport.activeTransport.GetMaxPacketSize(0);

            // set currentSize start value to max TCP header size (60b)
            var currentSize = 100;

            //Stores the current cycle of ElementValues
            var elementValues = new List <ElementValue>();

            //How many values are being sent
            var length = values.Length;

            //Total packet size if all values sent together
            var totalSize = 0;

            //Work out totalSize
            foreach (var value in values)
            {
                var size = value.GetSize();

                //If a single value is bigger than max packet size cannot proceed
                if (size + 60 >= maxPacketSize)
                {
                    Debug.LogError($"This value is above the max mirror packet limit, and cannot be split. Is {size + 60} bytes");
                    return(null);
                }

                totalSize += size;
            }

            //Rounds up to the max number of divisions of the max packet size will be needed for values
            var divisions = (int)Math.Ceiling((float)totalSize / maxPacketSize);

            //Counter for which division is currently being made
            var currentDivision = 0;

            //The loop for making the messages from the values
            for (var i = 0; i < length; i++)
            {
                //Keep adding values until bigger than packet size
                currentSize += values[i].GetSize();

                if (currentSize > maxPacketSize)
                {
                    currentDivision++;
                    currentSize = 100;

                    //Id MoreIncoming, means it is a multimessage but not the end.
                    id = TabMessageType.MoreIncoming;

                    //If last division then this will be the end, set to end Id of EndOfMessage
                    if (currentDivision == divisions)
                    {
                        id = TabMessageType.EndOfMessage;
                    }

                    //Add value list to the message list
                    elementValuesLists.Add(elementValues, id);
                    elementValues = new List <ElementValue>();
                }

                elementValues.Add(values[i]);
            }

            //Single message
            if (elementValuesLists.Count == 0)
            {
                values = elementValues.ToArray();
            }
            //Multimessage, if end division hasnt been reached yet then this last list must be end.
            else if (currentDivision != divisions)
            {
                elementValuesLists.Add(elementValues, TabMessageType.EndOfMessage);
            }
        }

        var count = elementValuesLists.Count;

        //Single message
        if (count == 0)
        {
            var msg = new TabUpdateMessage
            {
                Provider      = provider.NetId(),
                Type          = type,
                Action        = tabAction,
                ElementValues = values,
                Touched       = changedBy != null,
                ID            = id,
                UniqueID      = uniqueID
            };

            msg.SendTo(recipient);
            Logger.LogTraceFormat("{0}", Category.NetUI, msg);
            return(null);
        }

        foreach (var value in elementValuesLists)
        {
            var msg = new TabUpdateMessage
            {
                Provider      = provider.NetId(),
                Type          = type,
                Action        = tabAction,
                ElementValues = value.Key.ToArray(),
                Touched       = changedBy != null,
                ID            = value.Value,
                UniqueID      = uniqueID,
                NumOfMessages = count
            };

            msg.SendTo(recipient);
            Logger.LogTraceFormat("{0}", Category.NetUI, msg);
        }

        return(null);
    }
예제 #14
0
 protected override void ServerPerformInteraction(HandActivate interaction)
 {
     //show the paper to the client
     TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType, TabAction.Open);
     paper.UpdatePlayer(interaction.Performer);
 }
예제 #15
0
 private TabUpdateMessage FailValidation(GameObject player, GameObject tabProvider, string reason = "")
 {
     Debug.LogWarning($"{player}: Tab interaction w/{tabProvider} denied: {reason}");
     return(TabUpdateMessage.Send(player, tabProvider, NetTabType, TabAction.Close));
 }
예제 #16
0
 /// Send update to observers.
 /// Override if you want to include more values than just the current one
 protected virtual void UpdatePeepers()
 {
     TabUpdateMessage.SendToPeepers(MasterTab.Provider, MasterTab.Type, TabAction.Update, new[] { ElementValue });
 }