using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CitizenFX.Core; using Newtonsoft.Json; using Nexd.ESX.Server; using TaxiJob.Shared; namespace TaxiJob.Server { public sealed class ServerScript : BaseScript { private readonly List _servicePlayers = new List(); private readonly Dictionary _pendingJobs = new Dictionary(); private readonly Dictionary _pendingCount = new Dictionary(); public ServerScript() { _servicePlayers.Clear(); _pendingJobs.Clear(); _pendingCount.Clear(); EventHandlers["taxijob:server:service"] += new Action(Service); EventHandlers["taxijob:server:payout"] += new Action(Payout); EventHandlers["taxijob:server:request"] += new Action(OnTaxiRequest); EventHandlers["taxijob:server:accept"] += new Action(HasJobAccepted); EventHandlers["taxijob:server:sync_meter"] += new Action(SyncMeter); EventHandlers["taxijob:server:bill"] += new Action(PlaceBill); } private static void RegisterCallback(string name, Func> handler) { ESX.RegisterServerCallback(name, async (source, cb, args) => { try { var result = await handler.Invoke(ESX.GetPlayerFromId(source)); cb(result); } catch (Exception e) { cb(null); } }); } private static void RegisterCallback(string name, Func> handler, bool castViaJson = false) { ESX.RegisterServerCallback(name, async (source, cb, args) => { try { TArg arg; if (castViaJson) { arg = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(args)); } else { arg = Convert.ChangeType(args, typeof(TArg)); } var result = await handler.Invoke(ESX.GetPlayerFromId(source), arg); cb(result); } catch (Exception e) { cb(null); } }); } private void Service([FromSource] Player player, bool onService) { if (onService == false) _servicePlayers.Remove(player); else if (!_servicePlayers.Contains(player)) _servicePlayers.Add(player); } private void Payout([FromSource] Player player, int amount) { var xPlayer = ESX.GetPlayerFromId(player.ServerId()); xPlayer.AddMoney(amount); } private void OnTaxiRequest([FromSource] Player player) { player.TriggerEvent("okokNotify:Alert", "Taxi", "Es wird ein Taxifahrer benachrichtigt...", 4000, "info"); if (_servicePlayers.Count == 0) player.TriggerEvent("taxijob:client:npc"); else { var jobId = Guid.NewGuid().ToString(); var playerPos = player.Character.Position; _pendingJobs.Add(jobId, player); _pendingCount.Add(jobId, 0); _servicePlayers.OrderBy(p => Math.Sqrt(p.Character.Position.DistanceToSquared(playerPos))).First().TriggerEvent("taxijob:client:job", playerPos, jobId); } } private void HasJobAccepted([FromSource] Player player, bool accepted, string jobId) { if (jobId == null || !_pendingJobs.ContainsKey(jobId)) return; _pendingCount[jobId]++; if (accepted) { player.TriggerEvent("taxijob:client:set_passanger", int.Parse(_pendingJobs[jobId].Handle)); _pendingJobs[jobId].TriggerEvent("okokNotify:Alert", "Taxi", "Ein Taxi ist auf dem Weg zu ihnen!", 5000, "info"); _pendingJobs.Remove(jobId); _pendingCount.Remove(jobId); } else { var pos = _pendingJobs[jobId].Character.Position; if (_servicePlayers.Count - _pendingCount[jobId] <= 0) { _pendingJobs[jobId].TriggerEvent("taxijob:client:npc"); _pendingJobs.Remove(jobId); _pendingCount.Remove(jobId); } else _servicePlayers.Where(p => p != player).OrderBy(p => Math.Sqrt(p.Character.Position.DistanceToSquared(pos))).First().TriggerEvent("taxijob:client:job", pos, jobId); } } private void SyncMeter(object attributes, int client, bool activate) { Players[client].TriggerEvent("taxijob:client:sync_meter", attributes, activate); } private void PlaceBill([FromSource] Player player, int amount, int target) { if (amount == 0) return; TriggerEvent("esx_billing:sendBill", target, null, "Taxifahrtgebühren", amount); } } }