Beiträge von TedMosby
-
-
Guten Tag,
ich benutze es_extended und habe das Script "MI-phone" hinzugefügt. Es funktioniert wunderbar, jedoch kann ich keinen anrufen. Ich habe das ganze unter die Lupe genommen und habe bemerkt, dass da standardmäßig tokovoip_script verwendet wird. Dies hab ich geändert, weil ich SaltyChat nutze und es weiterhin nutzen will.
Code: MI-phone/client/main.lua
Alles anzeigenCancelCall = function() TriggerServerEvent('MI-phone:server:CancelCall', PhoneData.CallData) if PhoneData.CallData.CallType == "ongoing" then exports["saltychat"]:EndCall(PhoneData.CallData.CallId) end PhoneData.CallData.CallType = nil PhoneData.CallData.InCall = false PhoneData.CallData.AnsweredCall = false PhoneData.CallData.TargetData = {} PhoneData.CallData.CallId = nil if not PhoneData.isOpen then StopAnimTask(PlayerPedId(), PhoneData.AnimationData.lib, PhoneData.AnimationData.anim, 2.5) deletePhone() PhoneData.AnimationData.lib = nil PhoneData.AnimationData.anim = nil else PhoneData.AnimationData.lib = nil PhoneData.AnimationData.anim = nil end TriggerServerEvent('MI-phone:server:SetCallState', false) if not PhoneData.isOpen then SendNUIMessage({ action = "Notification", NotifyData = { title = Lang("PHONE_TITLE"), content = Lang("PHONE_CALL_END"), icon = "fas fa-phone", timeout = 3500, color = "#e84118", }, }) else SendNUIMessage({ action = "PhoneNotification", PhoneNotify = { title = Lang("PHONE_TITLE"), text = Lang("PHONE_CALL_END"), icon = "fas fa-phone", color = "#e84118", }, }) SendNUIMessage({ action = "SetupHomeCall", CallData = PhoneData.CallData, }) SendNUIMessage({ action = "CancelOutgoingCall", }) end end RegisterNetEvent('MI-phone:client:CancelCall') AddEventHandler('MI-phone:client:CancelCall', function() if PhoneData.CallData.CallType == "ongoing" then SendNUIMessage({ action = "CancelOngoingCall" }) exports["saltychat"]:EndCall(PhoneData.CallData.CallId) end PhoneData.CallData.CallType = nil PhoneData.CallData.InCall = false PhoneData.CallData.AnsweredCall = false PhoneData.CallData.TargetData = {} if not PhoneData.isOpen then StopAnimTask(PlayerPedId(), PhoneData.AnimationData.lib, PhoneData.AnimationData.anim, 2.5) deletePhone() PhoneData.AnimationData.lib = nil PhoneData.AnimationData.anim = nil else PhoneData.AnimationData.lib = nil PhoneData.AnimationData.anim = nil end TriggerServerEvent('MI-phone:server:SetCallState', false) if not PhoneData.isOpen then SendNUIMessage({ action = "Notification", NotifyData = { title = Lang("PHONE_TITLE"), content = Lang("PHONE_CALL_END"), icon = "fas fa-phone", timeout = 3500, color = "#e84118", }, }) else SendNUIMessage({ action = "PhoneNotification", PhoneNotify = { title = Lang("PHONE_TITLE"), text = Lang("PHONE_CALL_END"), icon = "fas fa-phone", color = "#e84118", }, }) SendNUIMessage({ action = "SetupHomeCall", CallData = PhoneData.CallData, }) SendNUIMessage({ action = "CancelOutgoingCall", }) end end) RegisterNetEvent('MI-phone:client:GetCalled') AddEventHandler('MI-phone:client:GetCalled', function(CallerNumber, CallId, AnonymousCall) local RepeatCount = 0 local CallData = { number = CallerNumber, name = IsNumberInContacts(CallerNumber), anonymous = AnonymousCall } print(AnonymousCall) if AnonymousCall then CallData.name = "Anoniem" end PhoneData.CallData.CallType = "incoming" PhoneData.CallData.InCall = true PhoneData.CallData.AnsweredCall = false PhoneData.CallData.TargetData = CallData PhoneData.CallData.CallId = CallId TriggerServerEvent('MI-phone:server:SetCallState', true) SendNUIMessage({ action = "SetupHomeCall", CallData = PhoneData.CallData, }) for i = 1, Config.CallRepeats + 1, 1 do if not PhoneData.CallData.AnsweredCall then if RepeatCount + 1 ~= Config.CallRepeats + 1 then if PhoneData.CallData.InCall then RepeatCount = RepeatCount + 1 TriggerServerEvent("InteractSound_SV:PlayOnSource", "ringing", 0.2) if not PhoneData.isOpen then SendNUIMessage({ action = "IncomingCallAlert", CallData = PhoneData.CallData.TargetData, Canceled = false, AnonymousCall = AnonymousCall, }) end else SendNUIMessage({ action = "IncomingCallAlert", CallData = PhoneData.CallData.TargetData, Canceled = true, AnonymousCall = AnonymousCall, }) TriggerServerEvent('MI-phone:server:AddRecentCall', "missed", CallData) break end Citizen.Wait(Config.RepeatTimeout) else SendNUIMessage({ action = "IncomingCallAlert", CallData = PhoneData.CallData.TargetData, Canceled = true, AnonymousCall = AnonymousCall, }) TriggerServerEvent('MI-phone:server:AddRecentCall', "missed", CallData) break end else TriggerServerEvent('MI-phone:server:AddRecentCall', "missed", CallData) break end end end) RegisterNUICallback('CancelOutgoingCall', function() CancelCall() end) RegisterNUICallback('DenyIncomingCall', function() CancelCall() end) RegisterNUICallback('CancelOngoingCall', function() CancelCall() end) RegisterNUICallback('AnswerCall', function() AnswerCall() end) function AnswerCall() if (PhoneData.CallData.CallType == "incoming" or PhoneData.CallData.CallType == "outgoing") and PhoneData.CallData.InCall and not PhoneData.CallData.AnsweredCall then PhoneData.CallData.CallType = "ongoing" PhoneData.CallData.AnsweredCall = true PhoneData.CallData.CallTime = 0 SendNUIMessage({ action = "AnswerCall", CallData = PhoneData.CallData}) SendNUIMessage({ action = "SetupHomeCall", CallData = PhoneData.CallData}) TriggerServerEvent('MI-phone:server:SetCallState', true) if PhoneData.isOpen then DoPhoneAnimation('cellphone_text_to_call') else DoPhoneAnimation('cellphone_call_listen_base') end Citizen.CreateThread(function() while true do if PhoneData.CallData.AnsweredCall then PhoneData.CallData.CallTime = PhoneData.CallData.CallTime + 1 SendNUIMessage({ action = "UpdateCallTime", Time = PhoneData.CallData.CallTime, Name = PhoneData.CallData.TargetData.name, }) else break end Citizen.Wait(1000) end end) TriggerServerEvent('MI-phone:server:AnswerCall', PhoneData.CallData) exports["saltychat"]:EstablishCall(PhoneData.CallData.CallId, 'Phone') else PhoneData.CallData.InCall = false PhoneData.CallData.CallType = nil PhoneData.CallData.AnsweredCall = false SendNUIMessage({ action = "PhoneNotification", PhoneNotify = { title = Lang("PHONE_TITLE"), text = Lang("PHONE_NOINCOMING"), icon = "fas fa-phone", color = "#e84118", }, }) end end
Diese 4 Zeilen habe ich ersetzt:
exports.tokovoip_script:removePlayerFromRadio(PhoneData.CallData.CallId) => exports["saltychat"]:EndCall(PhoneData.CallData.CallId)
exports.tokovoip_script:removePlayerFromRadio(PhoneData.CallData.CallId) => exports["saltychat"]:EndCall(PhoneData.CallData.CallId)
exports.tokovoip_script:addPlayerToRadio(PhoneData.CallData.CallId, 'Phone') => exports["saltychat"]:EstablishCall(PhoneData.CallData.CallId, 'Phone')
exports.tokovoip_script:addPlayerToRadio(PhoneData.CallData.CallId, 'Phone') => exports["saltychat"]:EstablishCall(PhoneData.CallData.CallId, 'Phone')
C#: Saltychat/SaltyServer/VoiceManager.cs
Alles anzeigenusing System; using System.Collections.Generic; using System.Linq; using SaltyShared; using CitizenFX.Core; using CitizenFX.Core.Native; using Newtonsoft.Json; namespace SaltyServer { public class VoiceManager : BaseScript { #region Properties / Fields public static VoiceManager Instance { get; private set; } public bool Enabled { get; private set; } public string MinimumPluginVersion { get; private set; } public Vector3[] RadioTowers { get; private set; } = new Vector3[0]; public VoiceClient[] VoiceClients => this._voiceClients.Values.ToArray(); private Dictionary<Player, VoiceClient> _voiceClients = new Dictionary<Player, VoiceClient>(); public RadioChannel[] RadioChannels => this._radioChannels.ToArray(); private List<RadioChannel> _radioChannels = new List<RadioChannel>(); #endregion #region CTOR public VoiceManager() { VoiceManager.Instance = this; // General Exports this.Exports.Add("SetPlayerAlive", new Action<int, bool>(this.SetPlayerAlive)); // Phone Exports this.Exports.Add("EstablishCall", new Action<int, int>(this.EstablishCall)); this.Exports.Add("EndCall", new Action<int, int>(this.EndCall)); // Radio Exports this.Exports.Add("SetPlayerRadioSpeaker", new Action<int, bool>(this.SetPlayerRadioSpeaker)); this.Exports.Add("SetPlayerRadioChannel", new Action<int, string, bool>(this.SetPlayerRadioChannel)); this.Exports.Add("RemovePlayerRadioChannel", new Action<int, string>(this.RemovePlayerRadioChannel)); this.Exports.Add("SetRadioTowers", new Action<dynamic>(this.SetRadioTowers)); } #endregion #region Server Events [EventHandler("onResourceStart")] private void OnResourceStart(string resourceName) { if (resourceName != API.GetCurrentResourceName()) return; this.Enabled = API.GetResourceMetadata(resourceName, "VoiceEnabled", 0).Equals("true", StringComparison.OrdinalIgnoreCase); if (this.Enabled) { this.MinimumPluginVersion = API.GetResourceMetadata(resourceName, "MinimumPluginVersion", 0); } } [EventHandler("onResourceStop")] private void OnResourceStop(string resourceName) { if (resourceName != API.GetCurrentResourceName()) return; this.Enabled = false; lock (this._voiceClients) { this._voiceClients.Clear(); } lock (this._radioChannels) { foreach (RadioChannel radioChannel in this._radioChannels) { foreach (RadioChannelMember member in radioChannel.Members) { radioChannel.RemoveMember(member.VoiceClient); } } this._radioChannels.Clear(); } } [EventHandler("playerDropped")] private void OnPlayerDisconnected([FromSource] Player player, string reason) { if (!this._voiceClients.TryGetValue(player, out VoiceClient client)) return; foreach (RadioChannel radioChannel in this.RadioChannels.Where(c => c.IsMember(client))) { radioChannel.RemoveMember(client); } lock (this._voiceClients) { this._voiceClients.Remove(player); } BaseScript.TriggerClientEvent(Event.SaltyChat_RemoveClient, player.Handle); } #endregion #region RemoteEvents (Proximity) [EventHandler(Event.SaltyChat_SetVoiceRange)] private void OnSetVoiceRange([FromSource] Player player, float voiceRange) { if (!this._voiceClients.TryGetValue(player, out VoiceClient client)) return; if (Array.IndexOf(SharedData.VoiceRanges, voiceRange) >= 0) { client.VoiceRange = voiceRange; BaseScript.TriggerClientEvent(Event.SaltyChat_UpdateVoiceRange, player.Handle, client.VoiceRange); } } #endregion #region Exports (General) private void SetPlayerAlive(int netId, bool isAlive) { Player player = this.Players[netId]; lock (this._voiceClients) { if (this._voiceClients.ContainsKey(player)) { this._voiceClients[player].IsAlive = isAlive; BaseScript.TriggerClientEvent(Event.SaltyChat_UpdateAlive, player.Handle, isAlive); } } } #endregion #region Exports (Phone) private void EstablishCall(int callerNetId, int partnerNetId) { Player caller = this.Players[callerNetId]; Player callPartner = this.Players[partnerNetId]; caller.TriggerEvent(Event.SaltyChat_EstablishCall, callPartner.Handle, JsonConvert.SerializeObject(callPartner.Character.Position)); callPartner.TriggerEvent(Event.SaltyChat_EstablishCall, caller.Handle, JsonConvert.SerializeObject(caller.Character.Position)); } private void EndCall(int callerNetId, int partnerNetId) { Player caller = this.Players[callerNetId]; Player callPartner = this.Players[partnerNetId]; caller.TriggerEvent(Event.SaltyChat_EndCall, callPartner.Handle); callPartner.TriggerEvent(Event.SaltyChat_EndCall, caller.Handle); } #endregion #region Exports (Radio) private void SetPlayerRadioSpeaker(int netId, bool toggle) { Player player = this.Players[netId]; if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; this.SetRadioSpeaker(voiceClient, toggle); } private void SetPlayerRadioChannel(int netId, string radioChannelName, bool isPrimary) { Player player = this.Players[netId]; if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; this.JoinRadioChannel(voiceClient, radioChannelName, isPrimary); } private void RemovePlayerRadioChannel(int netId, string radioChannelName) { Player player = this.Players[netId]; if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; this.LeaveRadioChannel(voiceClient, radioChannelName); } private void SetRadioTowers(dynamic towers) { List<Vector3> towerPositions = new List<Vector3>(); foreach (dynamic tower in towers) { towerPositions.Add(new Vector3(tower[0], tower[1], tower[2])); } this.RadioTowers = towerPositions.ToArray(); BaseScript.TriggerClientEvent(Event.SaltyChat_UpdateRadioTowers, this.RadioTowers); } #endregion #region Remote Events (Salty Chat) [EventHandler(Event.SaltyChat_Initialize)] private void OnInitialize([FromSource] Player player) { if (!this.Enabled) return; VoiceClient voiceClient; lock (this._voiceClients) { voiceClient = new VoiceClient(player, this.GetTeamSpeakName(player), SharedData.VoiceRanges[1], true); if (this._voiceClients.ContainsKey(player)) this._voiceClients[player] = voiceClient; else this._voiceClients.Add(player, voiceClient); } player.TriggerEvent(Event.SaltyChat_Initialize, voiceClient.TeamSpeakName, this.RadioTowers); Vector3 voiceClientPosition = voiceClient.Player.Character != null ? voiceClient.Player.Character.Position : new Vector3(0.0f, 0.0f, 0.0f); string clientJson = JsonConvert.SerializeObject(new SaltyShared.VoiceClient(voiceClient.Player.GetServerId(), voiceClient.TeamSpeakName, voiceClient.VoiceRange, true, new Position(voiceClientPosition.X, voiceClientPosition.Y, voiceClientPosition.Z))); List<SaltyShared.VoiceClient> voiceClients = new List<SaltyShared.VoiceClient>(); foreach (VoiceClient client in this.VoiceClients.Where(c => c.Player != player)) { Vector3 clientPosition = client.Player.Character != null ? client.Player.Character.Position : new Vector3(0.0f, 0.0f, 0.0f); voiceClients.Add(new SaltyShared.VoiceClient(client.Player.GetServerId(), client.TeamSpeakName, client.VoiceRange, client.IsAlive, new Position(clientPosition.X, clientPosition.Y, clientPosition.Z))); client.Player.TriggerEvent(Event.SaltyChat_UpdateClient, clientJson); } player.TriggerEvent(Event.SaltyChat_SyncClients, JsonConvert.SerializeObject(voiceClients)); } [EventHandler(Event.SaltyChat_CheckVersion)] private void OnCheckVersion([FromSource] Player player, string version) { if (!this._voiceClients.TryGetValue(player, out VoiceClient client)) return; if (!this.IsVersionAccepted(version)) { player.Drop($"[Salty Chat] Benötigte Version von SaltyChat: {this.MinimumPluginVersion}"); return; } } #endregion #region Commands (Radio) #if DEBUG [Command("speaker")] private void OnSetRadioSpeaker(Player player, string[] args) { if (args.Length < 1) { player.SendChatMessage("Usage", "/speaker {true/false}"); return; } if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; bool toggle = String.Equals(args[0], "true", StringComparison.OrdinalIgnoreCase); this.SetRadioSpeaker(voiceClient, toggle); player.SendChatMessage("Speaker", $"The speaker is now {(toggle ? "on" : "off")}."); } [Command("joinradio")] private void OnJoinRadioChannel(Player player, string[] args) { if (args.Length < 1) { player.SendChatMessage("Usage", "/joinradio {radioChannelName}"); return; } if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; this.JoinRadioChannel(voiceClient, args[0], true); player.SendChatMessage("Radio", $"You joined channel \"{args[0]}\"."); } [Command("joinsecradio")] private void OnJoinSecondaryRadioChannel(Player player, string[] args) { if (args.Length < 1) { player.SendChatMessage("Usage", "/joinsecradio {radioChannelName}"); return; } if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; this.JoinRadioChannel(voiceClient, args[0], false); player.SendChatMessage("Radio", $"You joined secondary channel \"{args[0]}\"."); } [Command("leaveradio")] private void OnLeaveRadioChannel(Player player, string[] args) { if (args.Length < 1) { player.SendChatMessage("Usage", "/leaveradio {radioChannelName}"); return; } if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; this.LeaveRadioChannel(voiceClient, args[0]); player.SendChatMessage("Radio", $"You left channel \"{args[0]}\"."); } #endif #endregion #region Remote Events (Radio) [EventHandler(Event.SaltyChat_IsSending)] private void OnSendingOnRadio([FromSource] Player player, string radioChannelName, bool isSending) { if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; RadioChannel radioChannel = this.GetRadioChannel(radioChannelName, false); if (radioChannel == null || !radioChannel.IsMember(voiceClient)) return; radioChannel.Send(voiceClient, isSending); } [EventHandler(Event.SaltyChat_SetRadioChannel)] private void OnJoinRadioChannel([FromSource] Player player, string radioChannelName, bool isPrimary) { if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; this.LeaveRadioChannel(voiceClient, isPrimary); if (!String.IsNullOrEmpty(radioChannelName)) { this.JoinRadioChannel(voiceClient, radioChannelName, isPrimary); } } #endregion #region Remote Events(Megaphoone) [EventHandler(Event.SaltyChat_IsUsingMegaphone)] private void OnIsUsingMegaphone([FromSource] Player player, bool isSending) { if (!this._voiceClients.TryGetValue(player, out VoiceClient voiceClient)) return; string positionJson = JsonConvert.SerializeObject(voiceClient.Player.Character.Position); float range = 100f; foreach (VoiceClient remoteClient in this.VoiceClients) { remoteClient.Player.TriggerEvent(Event.SaltyChat_IsUsingMegaphone, voiceClient.Player.Handle, range, isSending, positionJson); } } #endregion #region Methods (Radio) public RadioChannel GetRadioChannel(string name, bool create) { RadioChannel radioChannel; lock (this._radioChannels) { radioChannel = this.RadioChannels.FirstOrDefault(r => r.Name == name); if (radioChannel == null && create) { radioChannel = new RadioChannel(name); this._radioChannels.Add(radioChannel); } } return radioChannel; } public IEnumerable<RadioChannelMember> GetPlayerRadioChannelMembership(VoiceClient voiceClient) { foreach (RadioChannel radioChannel in this.RadioChannels) { RadioChannelMember membership = radioChannel.Members.FirstOrDefault(m => m.VoiceClient == voiceClient); if (membership != null) { yield return membership; } } } public void SetRadioSpeaker(VoiceClient voiceClient, bool toggle) { voiceClient.RadioSpeaker = toggle; } public void JoinRadioChannel(VoiceClient voiceClient, string radioChannelName, bool isPrimary) { foreach (RadioChannel channel in this.RadioChannels) { if (channel.Members.Any(v => v.VoiceClient == voiceClient && v.IsPrimary == isPrimary)) return; } RadioChannel radioChannel = this.GetRadioChannel(radioChannelName, true); radioChannel.AddMember(voiceClient, isPrimary); } public void LeaveRadioChannel(VoiceClient voiceClient) { foreach (RadioChannelMember membership in this.GetPlayerRadioChannelMembership(voiceClient)) { membership.RadioChannel.RemoveMember(voiceClient); if (membership.RadioChannel.Members.Length == 0) { lock (this._radioChannels) { this._radioChannels.Remove(membership.RadioChannel); } } } } public void LeaveRadioChannel(VoiceClient voiceClient, string radioChannelName) { foreach (RadioChannelMember membership in this.GetPlayerRadioChannelMembership(voiceClient).Where(m => m.RadioChannel.Name == radioChannelName)) { membership.RadioChannel.RemoveMember(voiceClient); if (membership.RadioChannel.Members.Length == 0) { lock (this._radioChannels) { this._radioChannels.Remove(membership.RadioChannel); } } } } public void LeaveRadioChannel(VoiceClient voiceClient, bool primary) { foreach (RadioChannelMember membership in this.GetPlayerRadioChannelMembership(voiceClient).Where(m => m.IsPrimary == primary)) { membership.RadioChannel.RemoveMember(voiceClient); if (membership.RadioChannel.Members.Length == 0) { lock (this._radioChannels) { this._radioChannels.Remove(membership.RadioChannel); } } } } #endregion #region Methods (Misc) public string GetTeamSpeakName(Player player) { string name; do { name = $"[{player.Handle.PadLeft(3, '0')}] Saphir-Life"; if (name.Length > 30) { name = name.Remove(29, name.Length - 30); } } while (this._voiceClients.Values.Any(c => c.TeamSpeakName == name)); return name; } public bool IsVersionAccepted(string version) { if (!String.IsNullOrWhiteSpace(this.MinimumPluginVersion)) { try { string[] minimumVersionArray = this.MinimumPluginVersion.Split('.'); string[] versionArray = version.Split('.'); int lengthCounter = 0; if (versionArray.Length >= minimumVersionArray.Length) { lengthCounter = minimumVersionArray.Length; } else { lengthCounter = versionArray.Length; } for (int i = 0; i < lengthCounter; i++) { int min = Convert.ToInt32(minimumVersionArray[i]); int cur = Convert.ToInt32(versionArray[i]); if (cur > min) { return true; } else if (min > cur) { return false; } } } catch { return false; } } return true; } #endregion } }
Code: saltychat/fxmanifest.lua
Alles anzeigenfx_version 'adamant' game 'gta5' ui_page 'NUI/SaltyWebSocket.html' client_scripts { 'SaltyClient/bin/Debug/SaltyClient.net.dll' } server_scripts { 'SaltyServer/bin/Debug/netstandard2.0/SaltyServer.net.dll' } files { 'NUI/SaltyWebSocket.html', 'Newtonsoft.Json.dll', } exports { 'SetPlayerAlive', 'EstablishCall', 'EndCall', 'SetPlayerRadioSpeaker', 'SetPlayerRadioChannel', 'RemovePlayerRadioChannel', 'SetRadioTowers' } VoiceEnabled 'true' ServerUniqueIdentifier '-' RequiredUpdateBranch 'Stable' MinimumPluginVersion '1.3.3' SoundPack 'default' IngameChannelId '-' IngameChannelPassword '-' SwissChannelIds '88678, 88868, 88869, 88867, 88871, 88682, 88873, 88874, 88852, 88863, 88858, 88876, 88857, 88877, 88753, 88879, 88848, 88849, 88850, 88851, 88853, 88679, 88680, 88681, 88840, 88841, 88842, 88843, 88900, 88901, 88902, 88903, 88904, 88905, 88906, 88907, 88908, 88909, 88910, 88911, 88912, 88884, 88882, 88883, 88899, 88885, 88844'
https://github.com/saltminede/saltychat-fivem
Fehlermeldung: https://gyazo.com/09914e246b69ce1dfe2cba5ece091d32
Ich bedanke mich für jede Hilfe!
Ich sitze seit Tagen dran, leider ohne Erfolg!
Liebe Grüße