Files
reallife-gamemode/ReallifeGamemode.Server/Managers/VehicleManager.cs
2020-04-04 18:33:44 +02:00

887 lines
21 KiB
C#

using GTANetworkAPI;
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"
};
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.Pools.GetAllVehicles().ForEach(v =>
{
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 (!_serverVehicles.ContainsKey(serverVehicle.Id))
{
return null;
}
return GetVehicleFromHandle(_serverVehicles[serverVehicle.Id]);
}
public static ServerVehicle GetServerVehicleFromVehicle(Vehicle veh, DatabaseContext dbContext = 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 async Task VehicleManagerVehicleDeath(Vehicle vehicle)
{
ServerVehicle serverVehicle = GetServerVehicleFromVehicle(vehicle);
if (serverVehicle == null)
{
vehicle.Delete();
return;
}
Vehicle newVeh = serverVehicle.Spawn(vehicle);
await Task.Delay(2000);
newVeh.Repair();
newVeh.Rotation = new Vector3(0, 0, serverVehicle.Heading);
}
}
}