Files
reallife-gamemode/ReallifeGamemode.Server/Managers/VehicleManager.cs

953 lines
23 KiB
C#

using GTANetworkAPI;
using Newtonsoft.Json;
using ReallifeGamemode.Database.Entities;
using ReallifeGamemode.Database.Models;
using ReallifeGamemode.Server.Extensions;
using ReallifeGamemode.Server.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
namespace ReallifeGamemode.Server.Managers
{
public class VehicleManager : Script
{
private static readonly List<string> _enabledMods = new List<string>()
{
"ninef",
"ninef2",
"blista",
"asea",
"asea2",
"boattrailer",
"bus",
"armytanker",
"armytrailer",
"armytrailer2",
"freighttrailer",
"coach",
"airbus",
"asterope",
"airtug",
"ambulance",
"barracks",
"barracks2",
"baller",
"baller2",
"bjxl",
"banshee",
"benson",
"bfinjection",
"biff",
"blazer",
"blazer2",
"blazer3",
"bison",
"bison2",
"bison3",
"boxville",
"boxville2",
"boxville3",
"bobcatxl",
"bodhi2",
"buccaneer",
"buffalo",
"buffalo2",
"bulldozer",
"bullet",
"blimp",
"burrito",
"burrito2",
"burrito3",
"burrito4",
"burrito5",
"cavalcade",
"cavalcade2",
"policet",
"gburrito",
"cablecar",
"caddy",
"caddy2",
"camper",
"carbonizzare",
"cheetah",
"comet2",
"cogcabrio",
"coquette",
"cutter",
"gresley",
"dilettante",
"dilettante2",
"dune",
"dune2",
"hotknife",
"dloader",
"dubsta",
"dubsta2",
"dump",
"rubble",
"docktug",
"dominator",
"emperor",
"emperor2",
"emperor3",
"entityxf",
"exemplar",
"elegy2",
"f620",
"fbi",
"fbi2",
"felon",
"felon2",
"feltzer2",
"firetruk",
"flatbed",
"forklift",
"fq2",
"fusilade",
"fugitive",
"futo",
"granger",
"gauntlet",
"habanero",
"hauler",
"handler",
"infernus",
"ingot",
"intruder",
"issi2",
"Jackal",
"journey",
"jb700",
"khamelion",
"landstalker",
"lguard",
"manana",
"mesa",
"mesa2",
"mesa3",
"crusader",
"minivan",
"mixer",
"mixer2",
"monroe",
"mower",
"mule",
"mule2",
"oracle",
"oracle2",
"packer",
"patriot",
"pbus",
"penumbra",
"peyote",
"phantom",
"phoenix",
"picador",
"pounder",
"police",
"police4",
"police2",
"police3",
"policeold1",
"policeold2",
"pony",
"pony2",
"prairie",
"pranger",
"premier",
"primo",
"proptrailer",
"rancherxl",
"rancherxl2",
"rapidgt",
"rapidgt2",
"radi",
"ratloader",
"rebel",
"regina",
"rebel2",
"rentalbus",
"ruiner",
"rumpo",
"rumpo2",
"rhino",
"riot",
"ripley",
"rocoto",
"romero",
"sabregt",
"sadler",
"sadler2",
"sandking",
"sandking2",
"schafter2",
"schwarzer",
"scrap",
"seminole",
"sentinel",
"sentinel2",
"zion",
"zion2",
"serrano",
"sheriff",
"sheriff2",
"speedo",
"speedo2",
"stanier",
"stinger",
"stingergt",
"stockade",
"stockade3",
"stratum",
"sultan",
"superd",
"surano",
"surfer",
"surfer2",
"surge",
"taco",
"tailgater",
"taxi",
"trash",
"tractor",
"tractor2",
"tractor3",
"graintrailer",
"baletrailer",
"tiptruck",
"tiptruck2",
"tornado",
"tornado2",
"tornado3",
"tornado4",
"tourbus",
"towtruck",
"towtruck2",
"utillitruck",
"utillitruck2",
"utillitruck3",
"voodoo2",
"washington",
"stretch",
"youga",
"ztype",
"sanchez",
"sanchez2",
"scorcher",
"tribike",
"tribike2",
"tribike3",
"fixter",
"cruiser",
"BMX",
"policeb",
"akuma",
"carbonrs",
"bagger",
"bati",
"bati2",
"ruffian",
"daemon",
"double",
"pcj",
"vader",
"vigero",
"faggio2",
"hexer",
"annihilator",
"buzzard",
"buzzard2",
"cargobob",
"cargobob2",
"cargobob3",
"skylift",
"polmav",
"maverick",
"nemesis",
"frogger",
"frogger2",
"cuban800",
"duster",
"stunt",
"mammatus",
"jet",
"shamal",
"luxor",
"titan",
"lazer",
"cargoplane",
"squalo",
"marquis",
"dinghy",
"dinghy2",
"jetmax",
"predator",
"tropic",
"seashark",
"seashark2",
"submersible",
"freightcar",
"freight",
"freightcont1",
"freightcont2",
"freightgrain",
"tankercar",
"metrotrain",
"docktrailer",
"trailers",
"trailers2",
"trailers3",
"tvtrailer",
"raketrailer",
"tanker",
"trailerlogs",
"tr2",
"tr3",
"tr4",
"trflat",
"trailersmall",
"velum",
"adder",
"voltic",
"vacca",
"suntrap",
"submersible2",
"dukes",
"dukes2",
"buffalo3",
"dominator2",
"dodo",
"marshall",
"blimp2",
"gauntlet2",
"stalion",
"stalion2",
"blista2",
"blista3",
"bifta",
"speeder",
"kalahari",
"paradise",
"btype",
"jester",
"turismor",
"alpha",
"vestra",
"zentorno",
"massacro",
"huntley",
"thrust",
"rhapsody",
"warrener",
"blade",
"glendale",
"panto",
"dubsta3",
"pigalle",
"monster",
"sovereign",
"innovation",
"hakuchou",
"furoregt",
"miljet",
"besra",
"coquette2",
"swift",
"jester2",
"massacro2",
"ratloader2",
"slamvan",
"mule3",
"velum2",
"tanker2",
"casco",
"boxville4",
"hydra",
"insurgent",
"insurgent2",
"gburrito2",
"technical",
"dinghy3",
"savage",
"enduro",
"guardian",
"lectro",
"kuruma",
"kuruma2",
"trash2",
"barracks3",
"valkyrie",
"slamvan2",
"swift2",
"luxor2",
"feltzer3",
"osiris",
"virgo",
"windsor",
"coquette3",
"vindicator",
"t20",
"brawler",
"toro",
"chino",
"faction",
"faction2",
"moonbeam",
"moonbeam2",
"primo2",
"chino2",
"buccaneer2",
"voodoo",
"Lurcher",
"btype2",
"verlierer2",
"nightshade",
"mamba",
"limo2",
"schafter3",
"schafter4",
"schafter5",
"schafter6",
"cog55",
"cog552",
"cognoscenti",
"cognoscenti2",
"baller3",
"baller4",
"baller5",
"baller6",
"toro2",
"seashark3",
"dinghy4",
"tropic2",
"speeder2",
"cargobob4",
"supervolito",
"supervolito2",
"valkyrie2",
"tampa",
"sultanrs",
"banshee2",
"btype3",
"faction3",
"minivan2",
"sabregt2",
"slamvan3",
"tornado5",
"virgo2",
"virgo3",
"nimbus",
"xls",
"xls2",
"seven70",
"fmj",
"bestiagts",
"pfister811",
"brickade",
"rumpo3",
"volatus",
"prototipo",
"reaper",
"tug",
"windsor2",
"lynx",
"gargoyle",
"tyrus",
"sheava",
"omnis",
"le7b",
"contender",
"trophytruck",
"trophytruck2",
"rallytruck",
"cliffhanger",
"bf400",
"tropos",
"brioso",
"tampa2",
"tornado6",
"faggio3",
"faggio",
"raptor",
"vortex",
"avarus",
"sanctus",
"youga2",
"hakuchou2",
"nightblade",
"chimera",
"esskey",
"wolfsbane",
"zombiea",
"zombieb",
"defiler",
"daemon2",
"ratbike",
"shotaro",
"manchez",
"blazer4",
"elegy",
"tempesta",
"italigtb",
"italigtb2",
"nero",
"nero2",
"specter",
"specter2",
"diablous",
"diablous2",
"blazer5",
"ruiner2",
"dune4",
"dune5",
"phantom2",
"voltic2",
"penetrator",
"boxville5",
"wastelander",
"technical2",
"fcr",
"fcr2",
"comet3",
"ruiner3",
"turismo2",
"infernus2",
"gp1",
"ruston",
"trailers4",
"xa21",
"caddy3",
"vagner",
"phantom3",
"nightshark",
"cheetah2",
"torero",
"hauler2",
"trailerlarge",
"technical3",
"insurgent3",
"apc",
"tampa3",
"dune3",
"trailersmall2",
"halftrack",
"ardent",
"oppressor",
"vigilante",
"bombushka",
"alphaz1",
"seabreeze",
"tula",
"havok",
"hunter",
"microlight",
"rogue",
"pyro",
"howard",
"mogul",
"starling",
"nokota",
"molotok",
"rapidgt3",
"retinue",
"cyclone",
"visione",
"z190",
"viseris",
"comet5",
"raiden",
"riata",
"sc1",
"autarch",
"savestra",
"gt500",
"comet4",
"neon",
"sentinel3",
"khanjali",
"barrage",
"volatol",
"akula",
"deluxo",
"stromberg",
"chernobog",
"riot2",
"avenger",
"avenger2",
"thruster",
"yosemite",
"hermes",
"hustler",
"streiter",
"revolter",
"pariah",
"kamacho",
"entity2",
"cheburek",
"jester3",
"caracara",
"hotring",
"seasparrow",
"flashgt",
"ellie",
"michelli",
"fagaloa",
"dominator3",
"tyrant",
"tezeract",
"gb200",
"issi3",
"taipan",
"blimp3",
"mule4",
"pounder2",
"speedo4",
"pbus2",
"patriot2",
"swinger",
"terbyte",
"oppressor2",
"strikeforce",
"menacer",
"scramjet",
"freecrawler",
"stafford",
"bruiser",
"bruiser2",
"bruiser3",
"brutus",
"brutus2",
"brutus3",
"cerberus",
"cerberus2",
"cerberus3",
"clique",
"deathbike",
"deathbike2",
"deathbike3",
"deveste",
"deviant",
"dominator4",
"dominator5",
"dominator6",
"impaler",
"impaler2",
"impaler3",
"impaler4",
"imperator",
"imperator2",
"imperator3",
"issi4",
"issi5",
"issi6",
"italigto",
"monster3",
"monster4",
"monster5",
"rcbandito",
"scarab",
"scarab2",
"scarab3",
"schlagen",
"slamvan4",
"slamvan5",
"slamvan6",
"toros",
"tulip",
"vamos",
"zr380",
"zr3802",
"zr3803",
"streiter2", //Mod
"caracara2",
"drafter",
"dynasty",
"emerus",
"gauntlet3",
"gauntlet4",
"hellion",
"issi7",
"jugular",
"krieger",
"locust",
"nebula",
"neo",
"novak",
"paragon",
"paragon2",
"peyote2",
"rrocket",
"s80",
"thrax",
"zorrusso",
"zion3",
"lsfd", //Mod
"lsfd2", //Mod
"lsfd3", //Mod
"lsfd4", //Mod
"lsfd5", //Mod
"lsfdtruck", //Mod
"lsfdtruck2", //Mod
"lsfdtruck3", //Mod
"polbullet", //Mod
"polbullet2", //Mod
"sherbullet", //Mod
"hwaybullet", //Mod
"zhaba",
"yosemite2",
"vstr",
"vagrant",
"sultan2",
"sugoi",
"stryder",
"retinue2",
"rebla",
"outlaw",
"minitank",
"komoda",
"kanjo",
"jb7002",
"imorgon",
"furia",
"formula2",
"formula",
"everon",
"asbo",
"openwheel1",
"openwheel2",
"tigon",
"landstalker2",
"penumbra2",
"club",
"coquette4",
"seminole2",
"dukes3",
"manana2",
"peyote3",
"gauntlet5",
"yosemite3",
"youga3",
"glendale2",
"alkonost",
"annihilator2",
"avisa",
"brioso2",
"dinghy5",
"italirsx",
"kosatka",
"longfin",
"manchez2",
"patrolboat",
"seasparrow2",
"seasparrow3",
"slamtruck",
"squaddie",
"toreador",
"verus",
"vetir",
"veto",
"veto2",
"weevil",
"winky",
"polamggtr", //mod
"newsfrog", //mod
};
private static readonly Dictionary<int, NetHandle> _serverVehicles = new Dictionary<int, NetHandle>();
private static readonly Dictionary<NetHandle, Vector3> lastPositions = new Dictionary<NetHandle, Vector3>();
private static DateTime lastSave = DateTime.UtcNow;
public static void CheckEnabledMods()
{
foreach (var name in _enabledMods)
{
if (_enabledMods.Where(x => x == name).Count() != 1)
{
NAPI.Util.ConsoleOutput($"{name} double");
}
}
}
public static void VehicleTimerTick()
{
NAPI.Task.Run(() =>
{
NAPI.Pools.GetAllVehicles().ForEach(v =>
{
if (v.Handle.Value == 0 || v.Handle == default)
{
return;
}
Vector3 lastPosition = v.Position;
if (lastPositions.ContainsKey(v.Handle)) lastPosition = lastPositions[v.Handle];
lastPositions[v.Handle] = v.Position;
double distanceDriven;
try
{
distanceDriven = v.HasSharedData("drivenDistance") ? (double)v.GetSharedData<dynamic>("drivenDistance") : 0D;
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
{
distanceDriven = 0;
}
double distance = lastPosition.DistanceTo(v.Position) / 1000.0;
if (distance > 0.2)
{
lastPositions[v.Handle] = v.Position;
return;
}
distanceDriven += distance;
v.SetSharedData("drivenDistance", (float)distanceDriven);
});
if (DateTime.UtcNow.Subtract(lastSave).Seconds >= 30)
{
lastSave = DateTime.UtcNow;
// save to db
using (var dbContext = new DatabaseContext())
{
foreach (var key in lastPositions.Keys.ToList())
{
Vehicle v = key.Entity<Vehicle>();
if (v == null) continue;
if (!v.HasSharedData("drivenDistance")) continue;
ServerVehicle sVeh = VehicleManager.GetServerVehicleFromVehicle(v, dbContext);
if (sVeh == null) continue;
sVeh.DistanceDriven = (float)v.GetSharedData<dynamic>("drivenDistance");
}
dbContext.SaveChanges();
}
}
});
}
public static void AddVehicle(ServerVehicle serverVehicle, Vehicle vehicle)
{
if (_serverVehicles.ContainsKey(serverVehicle.Id))
{
return;
}
if (_serverVehicles.ContainsValue(vehicle.Handle))
{
return;
}
_serverVehicles[serverVehicle.Id] = vehicle.Handle;
}
internal static void DeleteVehicle(Vehicle veh)
{
ServerVehicle sVeh;
if ((sVeh = GetServerVehicleFromVehicle(veh)) != null)
{
_serverVehicles.Remove(sVeh.Id);
}
veh.Delete();
}
public static Vehicle GetVehicleFromHandle(NetHandle handle)
{
return NAPI.Pools.GetAllVehicles().Find(v => v.Handle == handle);
}
public static Vehicle GetVehicleFromId(int id)
{
using (var dbcontext = new DatabaseContext())
{
ServerVehicle sVeh = dbcontext.ServerVehicles.Where(sV => sV.Id == id).FirstOrDefault();
return GetVehicleFromServerVehicle(sVeh);
}
}
public static Vehicle GetVehicleFromServerVehicle(ServerVehicle serverVehicle)
{
if (serverVehicle == null)
{
return null;
}
if (!_serverVehicles.ContainsKey(serverVehicle.Id))
{
return null;
}
return GetVehicleFromHandle(_serverVehicles[serverVehicle.Id]);
}
public static ServerVehicle GetServerVehicleFromVehicle(Vehicle veh, DatabaseContext dbContext = null)
{
if (veh == null)
{
return null;
}
dbContext = dbContext ?? new DatabaseContext();
foreach (KeyValuePair<int, NetHandle> pair in _serverVehicles)
{
if (pair.Value == veh.Handle)
{
return dbContext.ServerVehicles.Find(pair.Key);
}
}
return null;
}
public static bool IsValidHash(uint hash)
{
foreach (VehicleHash vh in Enum.GetValues(typeof(VehicleHash)))
{
if ((uint)vh == hash) return true;
}
foreach (string mod in _enabledMods)
{
if (NAPI.Util.GetHashKey(mod) == hash) return true;
}
return false;
}
[ServerEvent(Event.VehicleDeath)]
public static void VehicleManagerVehicleDeath(Vehicle vehicle)
{
ServerVehicle serverVehicle = GetServerVehicleFromVehicle(vehicle);
NAPI.Util.ConsoleOutput("VehicleDeat: Debug 1");
if (serverVehicle == null)
{
NAPI.Util.ConsoleOutput("VehicleDeath: Debug 2");
vehicle.Delete();
return;
}
InventoryManager.RemoveAllItemsfromVehicleInventory(vehicle);
NAPI.Util.ConsoleOutput("VehicleDeath: Debug 3");
Vehicle newVeh = serverVehicle.Spawn(vehicle);
newVeh.Repair();
newVeh.Rotation = new Vector3(0, 0, serverVehicle.Heading);
}
[RemoteEvent("CLIENT:setMarkerBehindVehicle")]
public void setVectorBehindVehicle(Player player, int id, string jsonX, string jsonY, string jsonZ)
{
Vehicle vehicle = NAPI.Pools.GetAllVehicles().Find(v => v.Id == id);
Vector3 vector3 = new Vector3(Convert.ToSingle((double)JsonConvert.DeserializeObject(jsonX)), Convert.ToSingle((double)JsonConvert.DeserializeObject(jsonY)), Convert.ToSingle((double)JsonConvert.DeserializeObject(jsonZ)));
vehicle.AddMarkerBehind(vector3);
}
}
}