/// <summary>
        /// Tell the plugin we have a new call partner
        /// </summary>
        /// <param name="args">args[0] - handle | args[1] - bool | args[2] - string[]</param>
        private static void OnEstablishCallRelayed(object[] args)
        {
            ushort handle = Convert.ToUInt16(args[0]);
            bool   direct = (bool)args[1];

            string[] relays = Newtonsoft.Json.JsonConvert.DeserializeObject <string[]>((string)args[2]);

            Player player = Entities.Players.GetAtRemote(handle);

            if (player == null || !VoiceManager.TryGetVoiceClient(handle, out VoiceClient voiceClient))
            {
                return;
            }

            RAGE.Vector3 ownPosition    = RAGE.Elements.Player.LocalPlayer.Position;
            RAGE.Vector3 playerPosition = player.Position;

            VoiceManager.ExecuteCommand(
                new PluginCommand(
                    Command.PhoneCommunicationUpdate,
                    VoiceManager.ServerUniqueIdentifier,
                    new PhoneCommunication(
                        voiceClient.TeamSpeakName,
                        RAGE.Game.Zone.GetZoneScumminess(RAGE.Game.Zone.GetZoneAtCoords(ownPosition.X, ownPosition.Y, ownPosition.Z)) +
                        RAGE.Game.Zone.GetZoneScumminess(RAGE.Game.Zone.GetZoneAtCoords(playerPosition.X, playerPosition.Y, playerPosition.Z)),
                        direct,
                        relays
                        )
                    )
                );
        }
        /// <summary>
        /// Sends the plugin an update on all players
        /// </summary>
        private static void PlayerStateUpdate()
        {
            RAGE.Vector3 playerPosition = Player.LocalPlayer.Position;

            foreach (var voiceClient in VoiceManager.VoiceClients)
            {
                RAGE.Vector3 nPlayerPosition = voiceClient.Player.Position;

                VoiceManager.ExecuteCommand(
                    new PluginCommand(
                        Command.PlayerStateUpdate,
                        VoiceManager.ServerUniqueIdentifier,
                        new PlayerState(
                            voiceClient.TeamSpeakName,
                            nPlayerPosition,
                            voiceClient.VoiceRange,
                            voiceClient.IsAlive
                            )
                        )
                    );
            }

            VoiceManager.ExecuteCommand(
                new PluginCommand(
                    Command.SelfStateUpdate,
                    VoiceManager.ServerUniqueIdentifier,
                    new PlayerState(
                        playerPosition,
                        RAGE.Game.Cam.GetGameplayCamRot(0).Z
                        )
                    )
                );
        }
        private static void OnTick(List <RAGE.Events.TickNametagData> nametags)
        {
            RAGE.Game.Pad.DisableControlAction(1, (int)RAGE.Game.Control.EnterCheatCode, true);
            RAGE.Game.Pad.DisableControlAction(1, (int)RAGE.Game.Control.PushToTalk, true);

            // Calculate player states
            if (VoiceManager.IsReady && DateTime.Now > VoiceManager._nextUpdate)
            {
                VoiceManager.PlayerStateUpdate();

                VoiceManager._nextUpdate = DateTime.Now.AddMilliseconds(300);
            }

            // Lets the player talk on his radio channel with "N"
            if (!String.IsNullOrWhiteSpace(VoiceManager.RadioChannel))
            {
                if (RAGE.Game.Pad.IsDisabledControlJustPressed(1, (int)RAGE.Game.Control.PushToTalk))
                {
                    RAGE.Events.CallRemote(SaltyShared.Event.SaltyChat_IsSending, VoiceManager.RadioChannel, true);
                }
                else if (RAGE.Game.Pad.IsDisabledControlJustReleased(1, (int)RAGE.Game.Control.PushToTalk))
                {
                    RAGE.Events.CallRemote(SaltyShared.Event.SaltyChat_IsSending, VoiceManager.RadioChannel, false);
                }
            }

            // Lets the player change his voice range with "^"
            if (RAGE.Game.Pad.IsDisabledControlJustPressed(1, (int)RAGE.Game.Control.EnterCheatCode))
            {
                VoiceManager.ToggleVoiceRange();
            }
        }
        /// <summary>
        /// When someone is talking on our radio channel
        /// </summary>
        /// <param name="args">args[0] - handle | args[1] - isOnRadio | args[2] - stateChange | args[3] - direct | args[4] - relays</param>
        private static void OnPlayerIsSendingRelayed(object[] args)
        {
            ushort handle      = Convert.ToUInt16(args[0]);
            bool   isOnRadio   = (bool)args[1];
            bool   stateChange = (bool)args[2];
            bool   direct      = (bool)args[3];

            string[] relays = Newtonsoft.Json.JsonConvert.DeserializeObject <string[]>((string)args[4]);

            Player player = Entities.Players.GetAtRemote(handle);

            if (player == null)
            {
                return;
            }

            if (Player.LocalPlayer == player)
            {
                VoiceManager.PlaySound("selfMicClick", false, "MicClick");
            }
            else
            {
                if (!VoiceManager.TryGetVoiceClient(handle, out VoiceClient voiceClient))
                {
                    return;
                }

                if (isOnRadio)
                {
                    VoiceManager.ExecuteCommand(
                        new PluginCommand(
                            Command.RadioCommunicationUpdate,
                            VoiceManager.ServerUniqueIdentifier,
                            new RadioCommunication(
                                voiceClient.TeamSpeakName,
                                RadioType.LongRange | RadioType.Distributed,
                                RadioType.LongRange | RadioType.Distributed,
                                stateChange,
                                direct,
                                relays
                                )
                            )
                        );
                }
                else
                {
                    VoiceManager.ExecuteCommand(
                        new PluginCommand(
                            Command.StopRadioCommunication,
                            VoiceManager.ServerUniqueIdentifier,
                            new RadioCommunication(
                                voiceClient.TeamSpeakName,
                                stateChange
                                )
                            )
                        );
                }
            }
        }
        /// <summary>
        /// Plays a file from soundpack specified in <see cref="VoiceManager.SoundPack"/>
        /// </summary>
        /// <param name="fileName">filename (without .wav) of the soundfile</param>
        /// <param name="loop">use <see cref="true"/> to let the plugin loop the sound</param>
        /// <param name="handle">use your own handle instead of the filename, so you can play the sound multiple times</param>
        public static void PlaySound(string fileName, bool loop = false, string handle = null)
        {
            if (String.IsNullOrWhiteSpace(handle))
            {
                handle = fileName;
            }

            VoiceManager.ExecuteCommand(new PluginCommand(Command.PlaySound, VoiceManager.ServerUniqueIdentifier, new Sound(fileName, loop, handle)));
        }
        /// <summary>
        /// When someone is talking on our radio channel
        /// </summary>
        /// <param name="args">args[0] - handle | args[1] - isOnRadio</param>
        private static void OnPlayerIsSending(object[] args)
        {
            ushort handle    = Convert.ToUInt16(args[0]);
            bool   isOnRadio = (bool)args[1];

            Player player = Entities.Players.GetAtRemote(handle);

            if (player == null)
            {
                return;
            }

            if (Player.LocalPlayer == player)
            {
                VoiceManager.PlaySound("selfMicClick", false, "MicClick");
            }
            else
            {
                if (!VoiceManager.TryGetVoiceClient(handle, out VoiceClient voiceClient))
                {
                    return;
                }

                if (isOnRadio)
                {
                    VoiceManager.ExecuteCommand(
                        new PluginCommand(
                            Command.RadioCommunicationUpdate,
                            VoiceManager.ServerUniqueIdentifier,
                            new RadioCommunication(
                                voiceClient.TeamSpeakName,
                                RadioType.LongRange | RadioType.Distributed,
                                RadioType.LongRange | RadioType.Distributed,
                                true
                                )
                            )
                        );
                }
                else
                {
                    VoiceManager.ExecuteCommand(
                        new PluginCommand(
                            Command.StopRadioCommunication,
                            VoiceManager.ServerUniqueIdentifier,
                            new RadioCommunication(
                                voiceClient.TeamSpeakName,
                                true
                                )
                            )
                        );
                }
            }
        }
        /// <summary>
        /// Tell plugin the player is alive again, se we can hear him
        /// </summary>
        /// <param name="args">[0] - handle</param>
        public static void OnPlayerRevived(object[] args)
        {
            ushort handle = Convert.ToUInt16(args[0]);

            Player player = Entities.Players.GetAtRemote(handle);

            if (player == null || !VoiceManager.TryGetVoiceClient(handle, out VoiceClient voiceClient))
            {
                return;
            }

            voiceClient.IsAlive = true;
        }
        /// <summary>
        /// Tell plugin where all radio towers are
        /// </summary>
        /// <param name="args">[0] - towerPositions</param>
        private static void OnUpdateRadioTowers(object[] args)
        {
            TSVector[] towerPositions = Newtonsoft.Json.JsonConvert.DeserializeObject <TSVector[]>((string)args[0]);

            VoiceManager.ExecuteCommand(
                new PluginCommand(
                    Command.RadioTowerUpdate,
                    VoiceManager.ServerUniqueIdentifier,
                    new RadioTower(
                        towerPositions
                        )
                    )
                );
        }
        /// <summary>
        /// Remove a disconnected player
        /// </summary>
        /// <param name="args">args[0] - handle</param>
        private static void OnPlayerDisconnect(object[] args)
        {
            ushort handle = Convert.ToUInt16(args[0]);

            lock (VoiceManager._voiceClients)
            {
                if (VoiceManager._voiceClients.TryGetValue(handle, out VoiceClient voiceClient))
                {
                    VoiceManager._voiceClients.Remove(handle);

                    VoiceManager.ExecuteCommand(new PluginCommand(Command.RemovePlayer, VoiceManager.ServerUniqueIdentifier, new PlayerState(voiceClient.TeamSpeakName)));
                }
            }
        }
        /// <summary>
        /// Sets players radio channel
        /// </summary>
        /// <param name="args">args[0] - radioChannel</param>
        private static void OnSetRadioChannel(object[] args)
        {
            string radioChannel = (string)args[0];

            if (String.IsNullOrWhiteSpace(radioChannel))
            {
                VoiceManager.RadioChannel = null;
                VoiceManager.PlaySound("leaveRadioChannel", false, "radio");
            }
            else
            {
                VoiceManager.RadioChannel = radioChannel;
                VoiceManager.PlaySound("enterRadioChannel", false, "radio");
            }
        }
        /// <summary>
        /// Plugin error
        /// </summary>
        /// <param name="args">[0] - <see cref="PluginCommand"/> as json</param>
        public static void OnPluginError(object[] args)
        {
            try
            {
                PluginError pluginError = Newtonsoft.Json.JsonConvert.DeserializeObject <PluginError>((string)args[0]);

                if (pluginError.Error == Error.AlreadyInGame)
                {
                    VoiceManager.InitiatePlugin(); // try again an hope that the game instance was reset on plugin side
                }
                else
                {
                    RAGE.Chat.Output($"Salty Chat -- Error: {pluginError.Error} - Message: {pluginError.Message}");
                }
            }
            catch
            {
                RAGE.Chat.Output($"Salty Chat -- We got an error, but couldn't deserialize it...");
            }
        }
        /// <summary>
        /// Tell the plugin to end the call
        /// </summary>
        /// <param name="args">args[0] - handle</param>
        private static void OnEndCall(object[] args)
        {
            ushort handle = Convert.ToUInt16(args[0]);

            Player player = Entities.Players.GetAtRemote(handle);

            if (player == null || !VoiceManager.TryGetVoiceClient(handle, out VoiceClient voiceClient))
            {
                return;
            }

            VoiceManager.ExecuteCommand(
                new PluginCommand(
                    Command.StopPhoneCommunication,
                    VoiceManager.ServerUniqueIdentifier,
                    new PhoneCommunication(
                        voiceClient.TeamSpeakName
                        )
                    )
                );
        }
Beispiel #13
0
 internal void SendPlayerStateUpdate(VoiceManager voiceManager)
 {
     voiceManager.ExecuteCommand(new PluginCommand(Command.PlayerStateUpdate, voiceManager.Configuration.ServerUniqueIdentifier, new PlayerState(this.TeamSpeakName, this.LastPosition, this.VoiceRange, this.IsAlive)));
 }
 /// <summary>
 /// Stops and dispose the sound
 /// </summary>
 /// <param name="handle">filename or handle of the sound</param>
 public static void StopSound(string handle)
 {
     VoiceManager.ExecuteCommand(new PluginCommand(Command.StopSound, VoiceManager.ServerUniqueIdentifier, new Sound(handle)));
 }
        /// <summary>
        /// Plugin state update
        /// </summary>
        /// <param name="args">[0] - <see cref="PluginCommand"/> as json</param>
        public static void OnPluginMessage(object[] args)
        {
            PluginCommand pluginCommand = PluginCommand.Deserialize((string)args[0]);

            if (pluginCommand.Command == Command.Ping && VoiceManager._nextUpdate.AddSeconds(1) > DateTime.Now)
            {
                VoiceManager.ExecuteCommand(new PluginCommand(VoiceManager.ServerUniqueIdentifier));
                return;
            }

            if (!pluginCommand.TryGetState(out PluginState pluginState))
            {
                return;
            }

            if (pluginState.IsReady != VoiceManager._isIngame)
            {
                RAGE.Events.CallRemote(SaltyShared.Event.SaltyChat_CheckVersion, pluginState.UpdateBranch, pluginState.Version);

                VoiceManager._isIngame = pluginState.IsReady;
            }

            bool hasTalkingChanged    = false;
            bool hasMicMutedChanged   = false;
            bool hasSoundMutedChanged = false;

            if (pluginState.IsTalking != VoiceManager.IsTalking)
            {
                VoiceManager.IsTalking = pluginState.IsTalking;
                hasTalkingChanged      = true;

                RAGE.Events.CallRemote(SaltyShared.Event.SaltyChat_IsTalking, VoiceManager.IsTalking);
            }

            if (pluginState.IsMicrophoneMuted != VoiceManager.IsMicrophoneMuted)
            {
                VoiceManager.IsMicrophoneMuted = pluginState.IsMicrophoneMuted;
                hasMicMutedChanged             = true;
            }

            if (pluginState.IsSoundMuted != VoiceManager.IsSoundMuted)
            {
                VoiceManager.IsSoundMuted = pluginState.IsSoundMuted;
                hasSoundMutedChanged      = true;
            }

            if (hasTalkingChanged)
            {
                VoiceManager.OnTalkingStateChange?.Invoke(new SoundEventArgs());
            }

            if (hasMicMutedChanged)
            {
                VoiceManager.OnMicrophoneMuteStateChange?.Invoke(new SoundEventArgs());
            }

            if (hasSoundMutedChanged)
            {
                VoiceManager.OnSoundMuteStateChange?.Invoke(new SoundEventArgs());
            }

            if (hasTalkingChanged || hasMicMutedChanged || hasSoundMutedChanged)
            {
                VoiceManager.OnSoundStateChange?.Invoke(new SoundEventArgs());
            }
        }
        /// <summary>
        /// Plugin connected to WebSocket
        /// </summary>
        /// <param name="args"></param>
        public static void OnPluginConnected(object[] args)
        {
            VoiceManager._isConnected = true;

            VoiceManager.InitiatePlugin();
        }