using System; using System.Dynamic; using System.Linq; using System.Threading.Tasks; using CitizenFX.Core; using Mosleys.Shared; using Mosleys.Shared.Models; using Newtonsoft.Json; using Nexd.ESX.Server; using ESX = Nexd.ESX.Server.ESX; namespace Mosleys.Server { public sealed class ServerScript : BaseScript { public static ServerConfig Config; public ServerScript() { Config = new ServerConfig(); MySql.MySqlObject = Exports["oxmysql"]; MySql.InitialSetup(); RegisterCallback("mosleys:server:checkVehicleOwnership", CheckVehicleOwnership); RegisterCallback("mosleys:server:checkMoney", CheckMoney); RegisterCallback("mosleys:server:sellVehicle", SellVehicle, true); RegisterCallback("mosleys:server:getExhibits", GetExhibits); RegisterCallback("mosleys:server:getPlayerExhibits", GetPlayerExhibits); RegisterCallback("mosleys:server:getExhibitBySlot", GetExhibitBySlot); RegisterCallback("mosleys:server:buyVehicle", BuyVehicle, true); RegisterCallback("mosleys:server:updateExhibit", UpdateVehicle, true); RegisterCallback("mosleys:server:push", PushToExhibit); EventHandlers["mosleys:server:testDrive"] += new Action(UpdateTestDrive); } 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) { Debug.WriteLine(e.ToString()); 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) { Debug.WriteLine(e.ToString()); cb(null); } }); } private async Task CheckVehicleOwnership(xPlayer source, string plate) { var result = await MySql.FetchAll($"SELECT * FROM owned_vehicles WHERE owner = '{source.GetIdentifier()}'"); return result.Any(vehicle => vehicle.plate == plate); } private async Task CheckMoney(xPlayer source, int price) { return source.GetAccount("bank").money >= price; } private async Task SellVehicle(xPlayer source, SellData data) { var exhibit = new ExhibitVehicle { Uuid = Guid.NewGuid().ToString(), Owner = source.GetIdentifier(), Description = data.Description, Price = data.Price, Vehicle = data.VehicleProperties, TestDrive = false }; int slot = data.ParkingSpace == 0 ? await Utils.FindFreeSlot() : 0; if (slot >= Config.CarSlots.Length) slot = 0; exhibit.Slot = slot; await Utils.SaveExhibit(exhibit); if (data.ParkingSpace == 0) { source.RemoveAccountMoney("bank", Config.ExhibitPrice); Utils.UpdatePlayers(slot); } return slot != 0; } private async Task GetExhibits(xPlayer soruce) { var vehicles = await Utils.GetAllExhibits(); dynamic data = new ExpandoObject(); data.vehicles = vehicles; return data; } private async Task GetPlayerExhibits(xPlayer source) { var vehicles = await Utils.GetAllExhibits(); vehicles = vehicles.Where(vehicle => vehicle.Owner == source.GetIdentifier()).ToArray(); dynamic data = new ExpandoObject(); data.vehicles = vehicles; return data; } private async Task GetExhibitBySlot(xPlayer source, int slot) => await Utils.GetExhibitBySlot(slot); private async void UpdateTestDrive(int slot, bool toggle) { var exhibit = await Utils.GetExhibitBySlot(slot); if (exhibit == null) return; exhibit.TestDrive = toggle; await Utils.SaveExhibit(exhibit); Utils.UpdatePlayers(slot); } private async Task BuyVehicle(xPlayer source, BuyData data) { var exhibit = await Utils.GetExhibitByUuid(data.Uuid); if (exhibit == null) return false; var hasMoney = await CheckMoney(source, exhibit.Price); if (!hasMoney) return false; dynamic vehicle = exhibit.Vehicle; vehicle.plate = data.Plate; source.RemoveAccountMoney("bank", exhibit.Price); Utils.PaySeller(exhibit.Owner, exhibit.Price); TriggerEvent("esx_vehicleshop:setVehicleOwnedPlayerId", source.Index, vehicle); await MySql.Execute($"DELETE FROM cardealer WHERE uuid = '{data.Uuid}'"); if (exhibit.Slot != 0) TriggerClientEvent("mosleys:client:onRemove", exhibit.Slot); return true; } private async Task UpdateVehicle(xPlayer source, ExhibitUpdate update) { if (update.Exhibit.Owner != source.GetIdentifier()) return false; if (update.Action == UpdateAction.Update) { await Utils.SaveExhibit(update.Exhibit); if (update.Exhibit.Slot != 0 ) Utils.UpdatePlayers(update.Exhibit.Slot); } if (update.Action == UpdateAction.Delete) { await MySql.Execute($"DELETE FROM cardealer WHERE uuid = '{update.Exhibit.Uuid}'"); TriggerEvent("esx_vehicleshop:setVehicleOwnedPlayerId", source.Index, update.Exhibit.Vehicle); if (update.Exhibit.Slot != 0) TriggerClientEvent("mosleys:client:onRemove", update.Exhibit.Slot); } return true; } private async Task PushToExhibit(xPlayer source, string uuid) { var exhibit = await Utils.GetExhibitByUuid(uuid); var slot = await Utils.FindFreeSlot(); if (slot >= Config.CarSlots.Length) return 0; var hasMoney = await CheckMoney(source, Config.ExhibitPrice); if (!hasMoney) return 0; source.RemoveAccountMoney("bank", Config.ExhibitPrice); exhibit.Slot = slot; await Utils.SaveExhibit(exhibit); Utils.UpdatePlayers(slot); return slot; } } }