Example #1
0
        protected async void Spawn()
        {
            var characterSessions = await this.characterManager.ActiveCharacterSessions();

            lock (SpawnLock)
            {
                var vehiclesToSpawn = this.ActiveVehicles.Where(v => v.Handle == null);
                foreach (var vehicle in vehiclesToSpawn)
                {
                    var characterToSpawn = characterSessions
                                           .Where(c => c.IsConnected)
                                           .Select(s => new
                    {
                        Char = s.Character,
                        Dist = Vector3.Distance(vehicle.Position.ToVector3().ToCitVector3(), s.Character.Position.ToVector3().ToCitVector3())
                    })
                                           .Where(c => c.Dist < this.Configuration.DespawnDistance)
                                           .OrderBy(c => c.Dist)
                                           .FirstOrDefault();
                    if (characterToSpawn == null)
                    {
                        continue;
                    }
                    var characterSession =
                        characterSessions.FirstOrDefault(s => s.Character.Id == characterToSpawn.Char.Id);
                    if (characterSession == null)
                    {
                        continue;
                    }

                    // TODO: Await client response to prevent races.
                    this.comms.Event(VehicleEvents.Spawn).ToClient(this.clientList.Clients.First(c => c.Handle == characterSession.Session.Handle)).Emit(vehicle);
                }
            }
        }
Example #2
0
        private async void OnClientDisconnected(ICommunicationMessage e, IClient client, Session session)
        {
            var characterSessions = await this.characterManager.ActiveCharacterSessions();

            foreach (var vehicle in this.ActiveVehicles.Where(v => v.Handle != null).ToList())
            {
                var nearestCharacter = characterSessions
                                       .Where(c => c.IsConnected && c.SessionId != session.Id)
                                       .Select(s => new
                {
                    CharSession = s,
                    Dist        = Vector3.Distance(vehicle.Position.ToVector3().ToCitVector3(), s.Character.Position.ToVector3().ToCitVector3())
                })
                                       .OrderBy(c => c.Dist)
                                       .FirstOrDefault();
                if (nearestCharacter == null)
                {
                    this.Destroy(null, vehicle.NetId ?? 0);
                }
                else
                {
                    this.Transfer(null, vehicle.Id, nearestCharacter.CharSession.Session.UserId);
                }
            }
        }
Example #3
0
        internal void Send(VoiceClient voiceClient, bool isSending)
        {
            if (!this.TryGetMember(voiceClient, out RadioChannelMember radioChannelMember))
            {
                return;
            }

            bool stateChanged = radioChannelMember.IsSending != isSending;

            radioChannelMember.IsSending = isSending;

            RadioChannelMember[] channelMembers = this.Members;
            RadioChannelMember[] onSpeaker      = channelMembers.Where(m => m.IsSpeakerEnabled && m.VoiceClient != voiceClient).ToArray();

            CitizenFX.Core.Vector3 position = voiceClient.Player.GetPosition();

            if (onSpeaker.Length > 0)
            {
                string[] channelMemberNames = onSpeaker.Select(m => m.VoiceClient.TeamSpeakName).ToArray();

                foreach (VoiceClient remoteClient in VoiceManager.Instance.VoiceClients)
                {
                    remoteClient.Player.TriggerEvent(Event.SaltyChat_IsSendingRelayed, voiceClient.Player.Handle, voiceClient.TeamSpeakName, this.Name, isSending, stateChanged, position, this.IsMember(remoteClient), channelMemberNames);
                }
            }
            else
            {
                foreach (RadioChannelMember member in channelMembers)
                {
                    member.VoiceClient.Player.TriggerEvent(Event.SaltyChat_IsSending, voiceClient.Player.Handle, voiceClient.TeamSpeakName, this.Name, isSending, stateChanged, position);
                }
            }
        }
Example #4
0
        protected void OnClientDisconnect(ClientSessionEventArgs e)
        {
            var characterSessions = this.characterManager.ActiveCharacterSessions;

            foreach (var vehicle in this.ActiveVehicles.Where(v => v.Handle != null).ToList())
            {
                var nearestCharacter = characterSessions
                                       .Where(c => c.IsConnected && c.SessionId != e.Session.Id)
                                       .Select(s => new
                {
                    CharSession = s,
                    Dist        = Vector3.Distance(vehicle.Position.ToVector3(), s.Character.Position.ToVector3())
                })
                                       .OrderBy(c => c.Dist)
                                       .FirstOrDefault();
                if (nearestCharacter == null)
                {
                    this.Destroy(null, vehicle.NetId ?? 0);
                }
                else
                {
                    this.Transfer(null, vehicle.Id, nearestCharacter.CharSession.Session.UserId);
                }
            }
        }
Example #5
0
 /// <summary>
 /// Used for <see cref="Command.PlayerStateUpdate"/>
 /// </summary>
 /// <param name="name"></param>
 /// <param name="position"></param>
 /// <param name="voiceRange"></param>
 /// <param name="isAlive"></param>
 public PlayerState(string name, CitizenFX.Core.Vector3 position, float voiceRange, bool isAlive)
 {
     this.Name       = name;
     this.Position   = position;
     this.VoiceRange = voiceRange;
     this.IsAlive    = isAlive;
 }
Example #6
0
 /// <summary>
 /// Used for <see cref="Command.PlayerStateUpdate"/>
 /// </summary>
 /// <param name="name"></param>
 /// <param name="position"></param>
 /// <param name="voiceRange"></param>
 /// <param name="isAlive"></param>
 /// <param name="distanceCulled"></param>
 public PlayerState(string name, CitizenFX.Core.Vector3 position, float voiceRange, bool isAlive, bool distanceCulled = false)
 {
     this.Name           = name;
     this.Position       = position;
     this.VoiceRange     = voiceRange;
     this.IsAlive        = isAlive;
     this.DistanceCulled = distanceCulled;
 }
Example #7
0
 /// <summary>
 /// Used for <see cref="Command.PlayerStateUpdate"/>
 /// </summary>
 /// <param name="name"></param>
 /// <param name="position"></param>
 /// <param name="voiceRange"></param>
 /// <param name="isAlive"></param>
 /// <param name="distanceCulled"></param>
 /// <param name="muffleIntensity"></param>
 public PlayerState(string name, CitizenFX.Core.Vector3 position, float voiceRange, bool isAlive, bool distanceCulled = false, int?muffleIntensity = null)
 {
     this.Name            = name;
     this.Position        = new Vector3(position.X, position.Y, position.Z);
     this.VoiceRange      = voiceRange;
     this.IsAlive         = isAlive;
     this.MuffleIntensity = muffleIntensity;
     this.DistanceCulled  = distanceCulled;
 }
Example #8
0
 /// <summary>
 /// Used for <see cref="Command.PlayerStateUpdate"/>
 /// </summary>
 /// <param name="name"></param>
 /// <param name="position"></param>
 /// <param name="voiceRange"></param>
 /// <param name="isAlive"></param>
 /// <param name="distanceCulled"></param>
 /// <param name="noLos"></param>
 public PlayerState(string name, CitizenFX.Core.Vector3 position, float voiceRange, bool isAlive, bool distanceCulled = false, bool noLos = false)
 {
     this.Name           = name;
     this.Position       = new Vector3(position.X, position.Y, position.Z);
     this.VoiceRange     = voiceRange;
     this.IsAlive        = isAlive;
     this.NoLoS          = noLos;
     this.DistanceCulled = distanceCulled;
 }
Example #9
0
        public SelfState(CitizenFX.Core.Vector3 position, float rotation, bool echo = false)
        {
            this.Position = new Vector3(position.X, position.Y, position.Z);
            this.Rotation = rotation;
            this.IsAlive  = true;

            if (echo)
            {
                this.Echo = new EchoEffect();
            }
        }
Example #10
0
        public SelfState(CitizenFX.Core.Vector3 position, float rotation, float voiceRange, bool isAlive, bool echo = false)
        {
            this.Position   = new TSVector(position.X, position.Y, position.Z);
            this.Rotation   = rotation;
            this.VoiceRange = voiceRange;
            this.IsAlive    = isAlive;

            if (echo)
            {
                this.Echo = new EchoEffect();
            }
        }
Example #11
0
        protected void SpawnForPlayer(CharacterSessionEventArgs e)
        {
            lock (SpawnLock)
            {
                var vehiclesToSpawn = this.ActiveVehicles
                                      .Where(v =>
                                             v.Handle == null &&
                                             Vector3.Distance(v.Position.ToVector3().ToCitVector3(), e.CharacterSession.Character.Position.ToVector3().ToCitVector3()) <
                                             this.Configuration.DespawnDistance
                                             );

                foreach (var vehicle in vehiclesToSpawn)
                {
                    // TODO: Await client response to prevent races.
                    this.comms.Event(VehicleEvents.Spawn).ToClient(this.clientList.Clients.First(c => c.Handle == e.CharacterSession.Session.Handle)).Emit(vehicle);
                }
            }
        }
Example #12
0
        /// <summary>
        /// Used for <see cref="Command.PlayerStateUpdate"/> with volume override
        /// </summary>
        /// <param name="name"></param>
        /// <param name="position"></param>
        /// <param name="voiceRange"></param>
        /// <param name="isAlive"></param>
        /// <param name="volumeOverride">Overrides the volume (phone, radio and proximity) - from 0 (0%) to 1.6 (160%)</param>
        public PlayerState(string name, CitizenFX.Core.Vector3 position, float voiceRange, bool isAlive, float volumeOverride)
        {
            this.Name       = name;
            this.Position   = new Vector3(position.X, position.Y, position.Z);
            this.VoiceRange = voiceRange;
            this.IsAlive    = isAlive;

            if (volumeOverride > 1.6f)
            {
                this.VolumeOverride = 1.6f;
            }
            else if (volumeOverride < 0f)
            {
                this.VolumeOverride = 0f;
            }
            else
            {
                this.VolumeOverride = volumeOverride;
            }
        }
Example #13
0
        internal void RemoveMember(VoiceClient voiceClient)
        {
            lock (this._memberLock)
            {
                RadioChannelMember member = this._members.FirstOrDefault(m => m.VoiceClient == voiceClient);

                if (member != null)
                {
                    if (member.IsSending)
                    {
                        CitizenFX.Core.Vector3 position = member.VoiceClient.Player.GetPosition();

                        if (member.VoiceClient.IsRadioSpeakerEnabled)
                        {
                            foreach (VoiceClient client in VoiceManager.Instance.VoiceClients)
                            {
                                client.TriggerEvent(Event.SaltyChat_IsSendingRelayed, voiceClient.Player.Handle, voiceClient.TeamSpeakName, this.Name, false, true, position, false, new string[0]);
                            }
                        }
                        else
                        {
                            foreach (RadioChannelMember channelMember in this._members)
                            {
                                channelMember.VoiceClient.TriggerEvent(Event.SaltyChat_IsSending, voiceClient.Player.Handle, voiceClient.TeamSpeakName, this.Name, false, true, position);
                            }
                        }
                    }

                    this._members.Remove(member);

                    foreach (RadioChannelMember channelMember in this._members.Where(m => m.IsSending))
                    {
                        voiceClient.TriggerEvent(Event.SaltyChat_IsSending, channelMember.VoiceClient.Player.Handle, channelMember.VoiceClient.TeamSpeakName, this.Name, false, false, channelMember.VoiceClient.Player.GetPosition());
                    }

                    voiceClient.TriggerEvent(Event.SaltyChat_SetRadioChannel, null, member.IsPrimary);

                    this.BroadcastEvent(Event.SaltyChat_RadioChannelMemberUpdated, this.Name, this.Members.Select(m => m.VoiceClient.TeamSpeakName));
                }
            }
        }
Example #14
0
        protected void Update()
        {
            var activeVehicles = this.ActiveVehicles.Where(v => v.Handle != null).ToList();

            var characterSessions = this.characterManager.ActiveCharacterSessions;

            foreach (var vehicle in activeVehicles)
            {
                var nearestCharacter = characterSessions
                                       .Where(c => c.IsConnected)
                                       .Select(s => new
                {
                    CharSession = s,
                    Dist        = Vector3.Distance(vehicle.Position.ToVector3(), s.Character.Position.ToVector3())
                })
                                       .OrderBy(c => c.Dist)
                                       .FirstOrDefault();
                if (nearestCharacter == null)
                {
                    continue;
                }
                if (nearestCharacter.Dist > this.Configuration.DespawnDistance)
                {
                    Despawn(vehicle.NetId ?? 0, nearestCharacter.CharSession.Session.Handle);
                }
                else if (nearestCharacter.CharSession.Session.UserId != vehicle.TrackingUserId)
                {
                    var trackingUser =
                        characterSessions.FirstOrDefault(s => s.Session.UserId == vehicle.TrackingUserId);
                    if (trackingUser == null)
                    {
                        continue;
                    }

                    this.Rpc.Event(VehicleEvents.Transfer)
                    .Target(this.clientList.Clients.First(c => c.Handle == trackingUser.Session.Handle))
                    .Trigger(vehicle.Id, nearestCharacter.CharSession.Session.UserId);
                }
            }
        }
Example #15
0
        internal void SetSpeaker(VoiceClient voiceClient, bool isEnabled)
        {
            if (!this.TryGetMember(voiceClient, out RadioChannelMember radioChannelMember) || radioChannelMember.IsSpeakerEnabled == isEnabled)
            {
                return;
            }

            radioChannelMember.IsSpeakerEnabled = isEnabled;
            RadioChannelMember[]             channelMembers = this.Members;
            IEnumerable <RadioChannelMember> sendingMembers = channelMembers.Where(m => m.IsSending);

            if (sendingMembers.Count() == 0)
            {
                return;
            }

            if (isEnabled || channelMembers.Any(m => m.IsSpeakerEnabled))
            {
                foreach (RadioChannelMember sendingMember in sendingMembers)
                {
                    this.Send(sendingMember.VoiceClient, true);
                }
            }
            else
            {
                foreach (RadioChannelMember sendingMember in sendingMembers)
                {
                    CitizenFX.Core.Vector3 position = sendingMember.VoiceClient.Player.GetPosition();

                    foreach (VoiceClient remoteClient in VoiceManager.Instance.VoiceClients.Where(v => !channelMembers.Any(m => m.VoiceClient == v)))
                    {
                        remoteClient.TriggerEvent(Event.SaltyChat_IsSendingRelayed, sendingMember.VoiceClient.Player.Handle, sendingMember.VoiceClient.TeamSpeakName, this.Name, false, false, position, false, new string[0]);
                    }
                }
            }
        }
Example #16
0
 public static Vector3 ToVector3(this CitizenFX.Core.Vector3 vector3) => new Vector3(vector3.X, vector3.Y, vector3.Z);
Example #17
0
 public VoiceClient(int serverId, string teamSpeakName, float voiceRange, bool isAlive, CitizenFX.Core.Vector3 lastPosition)
 {
     this.ServerId      = serverId;
     this.TeamSpeakName = teamSpeakName;
     this.VoiceRange    = voiceRange;
     this.IsAlive       = isAlive;
     this.LastPosition  = lastPosition;
 }
Example #18
0
 /// <summary>
 /// Used for <see cref="Command.SelfStateUpdate"/>
 /// </summary>
 /// <param name="position"></param>
 /// <param name="rotation"></param>
 public PlayerState(CitizenFX.Core.Vector3 position, float rotation)
 {
     this.Position = position;
     this.Rotation = rotation;
 }
Example #19
0
 /// <summary>
 /// Used for <see cref="Command.SelfStateUpdate"/>
 /// </summary>
 /// <param name="position"></param>
 /// <param name="rotation"></param>
 public PlayerState(CitizenFX.Core.Vector3 position, float rotation)
 {
     this.Position = new Vector3(position.X, position.Y, position.Z);
     this.Rotation = rotation;
 }