/// 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 }); } }
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()); }
public void ServerPerformInteraction(HandApply interaction) { TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType, TabAction.Open); }
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 } }); } } }
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); }); } }
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 } }); } } }
//Ai interaction public override void AiInteraction(AiActivate interaction) { TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType.Mixer, TabAction.Open); }
public void ServerCloseTabFor(ConnectedPlayer player) { TabUpdateMessage.Send(player.GameObject, Provider, Type, TabAction.Close); }
public void ServerPerformInteraction(InventoryApply interaction) { playerInteracted = interaction.Performer; TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType, TabAction.Open); }
public void ServerPerformInteraction(InventoryApply interaction) { //show the paper to the client TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType, TabAction.Open); paper.UpdatePlayer(interaction.Performer); }
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); }
protected override void ServerPerformInteraction(HandActivate interaction) { //show the paper to the client TabUpdateMessage.Send(interaction.Performer, gameObject, NetTabType, TabAction.Open); paper.UpdatePlayer(interaction.Performer); }
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)); }
/// 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 }); }