using System; using System.Collections.Generic; using System.Linq; using GTANetworkAPI; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using ReallifeGamemode.Database.Entities; using ReallifeGamemode.Database.Models; using ReallifeGamemode.Server.Admin; using ReallifeGamemode.Server.Inventory.Interfaces; using ReallifeGamemode.Server.Log; using ReallifeGamemode.Server.Managers; using ReallifeGamemode.Server.Services; using ReallifeGamemode.Server.Types; using ReallifeGamemode.Server.Util; /** * @overview Life of German Reallife - Player Extension (PlayerExtension.cs) * @author hydrant, Siga, aviate * @copyright (c) 2008 - 2018 Life of German */ namespace ReallifeGamemode.Server.Extensions { public static class PlayerExtension { private static ILogger Logger => LogManager.GetLogger(typeof(PlayerExtension)); /// /// Gibt das User-Objekt eines Player's zurück. /// Gibt nichts zurück, wenn der Player nicht eingeloggt ist /// /// Der Player, dessen User man bekommen möchte /// Ein eventuell vorhandener Datenbank-Context, falls man Änderungen in der Datenbank vornehmen will /// public static User GetUser(this Player client, DatabaseContext context = null) { if (!client.IsLoggedIn()) return null; context = context ?? new DatabaseContext(); return context .Users .Include(u => u.Faction) .ThenInclude(f => f.BankAccount) .Include(u => u.FactionRank) .Include(u => u.Group) .Include(u => u.House) .Include(u => u.BankAccount) .Where(u => u.Name == client.Name) .FirstOrDefault(); } public static Character GetCharacter(this User user, DatabaseContext context = null) { if (context == null) { using (context = new DatabaseContext()) { return context.Characters.FirstOrDefault(u => u.Id == user.CharacterId); } } else { return context.Characters.FirstOrDefault(u => u.Id == user.CharacterId); } } public static void SafeTeleport(this Player player, Vector3 position, float heading = 0, bool spawn = false) { AntiCheat.NoTpAntiCheatForPlayer(player.Name); if (spawn) { AntiCheat.NoHealthAntiCheatForPlayer(player.Name); NAPI.Player.SpawnPlayer(player, position, heading); } else { player.Position = position; player.Heading = heading; } } public static void SafeSetHealth(this Player player, int health) { AntiCheat.NoHealthAntiCheatForPlayer(player.Name); player.Health = health; } public static void SafeSetArmor(this Player player, int armor) { AntiCheat.NoHealthAntiCheatForPlayer(player.Name); player.Armor = armor; } public static void SetJailTime(this User user, bool killed, DatabaseContext dbContext) { if (user == null) { return; } int time = 18 * user.Wanteds; if (killed) { time *= 2; } var lostItems = InventoryManager.RemoveIllegalItemsFromInventory(user.Player); if (lostItems.Any()) { Logger.LogInformation("Player {0} lost the following items when sent to prison: " + string.Join(", ", lostItems.Select(i => { IItem item = InventoryManager.GetItemById(i.ItemId); return $"{item.Name} ({item.Id}, amount: {i.Amount})"; }))); } var illegalItemsPrice = lostItems.Select(i => { IIllegalItem item = (IIllegalItem)InventoryManager.GetItemById(i.ItemId); return item.PriceForConfiscation * i.Amount; }).Sum(); int wantedMoney = user.Wanteds * 25; int factionMoney = wantedMoney + illegalItemsPrice; var executiveFactions = dbContext.Factions.Include(f => f.BankAccount).Where(f => f.Id == 1 || f.Id == 3); foreach (var faction in executiveFactions) { faction.BankAccount.Balance += factionMoney; } Logger.LogInformation("Player {0} was sent to jail for {1} seconds, executive factions got {2} dollars each (wanteds: {3}, illegal items: {4})", user.Name, time, factionMoney, wantedMoney, illegalItemsPrice); user.Wanteds = 0; user.JailTime = time; } public static void AnnouncePlayerJailedIn(this User user) { if (user == null) { return; } string message = user.Name + " wurde ins Gefängnis geliefert"; ChatService.HQMessage(message); } /// /// Gibt zurück, ob ein Player eingeloggt ist /// /// Der Player, dessen Login-Status man bekommen möchte /// public static bool IsLoggedIn(this Player player) { if (player == null) { return false; } return player.HasData("isLoggedIn") ? player.GetData("isLoggedIn") : false; } public static bool IsDuty(this Player player) { return player.GetServerData("duty", false); } public static bool IsAfk(this Player player) { if (!player.HasSharedData("isAfk")) { return false; } return player.GetSharedData("isAfk"); } public static bool IsAlive(this Player player) { return !player.HasData("isDead") || player.GetData("isDead") == false; } public static T GetServerData(this Player player, string key, T defaultValue = default) { if (player == null) { return default; } key += "data_"; if (!player.HasData(key)) return defaultValue; return JsonConvert.DeserializeObject(player.GetData(key)); } public static void SetServerData(this Player player, string key, object value) { if (player == null) { return; } key += "data_"; player.SetData(key, JsonConvert.SerializeObject(value)); } public static bool IsAdminDuty(this Player player) { return player.HasData("Adminduty") ? player.GetData("Adminduty") : false; } public static bool IsTSupport(this Player player) { return player.HasData("SAdminduty") ? player.GetData("SAdminduty") : false; } public static Vector3 GetPositionFromPlayer(Player player, float distance, int offset = 0) { var pos = player.Position; var a = player.Heading + offset; var rad = a * Math.PI / 180; var newpos = new Vector3(pos.X + (distance * Math.Sin(-rad)), pos.Y + (distance * Math.Cos(-rad)), pos.Z); return newpos; } internal static T GetData(this User user, string key, T nullValue) { return user.Player.GetServerData(key, nullValue); } internal static T GetData(this User user, string key) => user.GetData(key, default); internal static void SetData(this User user, string key, object value) { user.Player.SetServerData(key, value); } internal static void GiveWanteds(this User user, Player cop, int amount, string reason) { int newWanteds = user.Wanteds + amount; if (newWanteds > 50) { ChatService.ErrorMessage(cop, "Die Wanteds dürfen ein Limit von 50 nicht überschreiten"); newWanteds = 50; } using (var dbContext = new DatabaseContext()) { User dbUser = dbContext.Users.Where(u => u.Id == user.Id).FirstOrDefault(); dbUser.Wanteds = newWanteds; dbUser.SetBlipAndNametagColor(); dbContext.SaveChanges(); } user.Player.TriggerEvent("BN_ShowWithPicture", "Straftat", cop != null ? "Officer " + cop.Name + "" : "LSPD", "Du hast ein Verbrechen begangen: " + reason + " (" + newWanteds + ")", "DIA_POLICE", 1, true, 6); foreach (var copPlayer in NAPI.Pools.GetAllPlayers()) { if (copPlayer == null) { continue; } User copUser = copPlayer.GetUser(); if (copUser == null) { continue; } if (cop != null && (copUser.FactionId == 1 || copUser.FactionId == 3)) { ChatService.SendMessage(copPlayer, "!{#8181E9}HQ: Straftat gemeldet von " + cop.Name + " mit Fahndungslevel " + amount + ". Straftäter: " + user.Name + "."); ChatService.SendMessage(copPlayer, "!{#8181E9}HQ: Grund: " + reason + "."); ChatService.SendMessage(copPlayer, "!{#8181E9}HQ: Der Straftäter: " + user.Name + " wird nun mit Fahndungslevel " + newWanteds + " gesucht."); } else if ((copUser.FactionId == 1 || copUser.FactionId == 3) && cop == null) { ChatService.SendMessage(copPlayer, "!{#8181E9}HQ: " + user.Name + " hat eine Straftat begangen. Grund: " + reason + "."); ChatService.SendMessage(copPlayer, "!{#8181E9}HQ: Der Straftäter: " + user.Name + " wird nun mit Fahndungslevel " + newWanteds + " gesucht."); } } } public static FactionRank GetFactionRank(this User user) { using (var dbContext = new DatabaseContext()) { FactionRank toReturn = dbContext.FactionRanks.FirstOrDefault(fR => fR.Id == user.FactionRankId); if (toReturn == null) { toReturn = dbContext.FactionRanks.OrderBy(f => f.Order).FirstOrDefault(f => f.FactionId == user.FactionId); } if (toReturn == null) { toReturn = new FactionRank { RankName = "Rang-Fehler" }; } return toReturn; } } public static void BanPlayer(this User user, Player admin, string reason, int mins) { using (var banUserContext = new DatabaseContext()) { int unixTimestamp = (int)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; Ban banUser; if (mins == 0) { ChatService.Broadcast("!{#FF4040}[BAN] ~w~" + user.Name + " wurde von " + admin.Name + " permanent gebannt (Grund: " + reason + ")."); banUser = new Ban { UserId = user.Id, Reason = reason, BannedBy = admin.Name, Applied = unixTimestamp, UntilDateTime = unixTimestamp }; user.Player?.Kick(); mins--; } else { ChatService.Broadcast("!{#FF4040}[BAN] ~w~" + user.Name + " wurde von " + admin.Name + " für " + mins + " Minute(n) gebannt (Grund: " + reason + ")."); banUser = new Ban { UserId = user.Id, Reason = reason, BannedBy = admin.Name, Applied = unixTimestamp, UntilDateTime = unixTimestamp + mins * 60 }; user.Player?.Kick(); } banUserContext.Bans.Add(banUser); banUserContext.SaveChanges(); var targetUser = banUserContext.Users.Where(u => u.Name == user.Name).FirstOrDefault(); targetUser.BanId = banUser.Id; banUserContext.SaveChanges(); } } public static void UnbanPlayer(this User user) { using (var unbanUser = new DatabaseContext()) { var targetUser = unbanUser.Users.Where(u => u.Id == user.Id).FirstOrDefault(); targetUser.BanId = null; unbanUser.SaveChanges(); } } public static List GetItems(this User user) { using (var dbContext = new DatabaseContext()) { return dbContext.UserItems.Where(u => u.UserId == user.Id).ToList(); } } public static bool IsAdmin(this User user, AdminLevel adminLevel) { if (user == null) { return false; } return user.AdminLevel >= adminLevel; } public static void SetBlipAndNametagColor(this User user) { if (user == null) { return; } int blipColor = 0; int nameTagColor = 0; Player player = user.Player; if (player == null || !player.IsLoggedIn()) { return; } bool duty = user.GetData("duty"); bool adminUnshow = player.GetData("adminUnshow"); if (adminUnshow) { blipColor = -1; nameTagColor = -3; } else if (player.GetData("SAdminduty")) { blipColor = 30; nameTagColor = -2; } else if (user.Wanteds > 0) { nameTagColor = -1; blipColor = 64; } else if (user.FactionId != null) { if (user.FactionId > 3 || (user.FactionId >= 1 && user.FactionId <= 3 && duty)) { nameTagColor = user.FactionId.Value; } switch (user.FactionId) { case 1 when duty: blipColor = 38; break; case 2 when duty: blipColor = 6; break; case 3 when duty: blipColor = 63; break; case 4: break; case 5: blipColor = 33; break; case 6: break; case 7: blipColor = 52; break; case 8: blipColor = 83; break; case 9: blipColor = 25; break; } } user.Player.SetSharedData("nameTagColor", nameTagColor); user.Player.SetSharedData("blipColor", blipColor); } public static void SetInFrontOf(this Player player, Entity entity) { player.TriggerEvent("SERVER:SetInFrontPosition", entity); } public static void CuffPlayer(this Player player, Player nearestCuffPlayer) { nearestCuffPlayer.SetInFrontOf(player); nearestCuffPlayer.Heading = player.Heading; if (!nearestCuffPlayer.HasAnimation("Cuffed")) { player.SyncAnimation("doArrest"); nearestCuffPlayer.SyncAnimation(new List() { "getArrest", "Cuffed" }); nearestCuffPlayer.AddAttachment("handcuffs", false); nearestCuffPlayer.RemoveAllWeapons(); } else { nearestCuffPlayer.AddAttachment("handcuffs", true); player.SyncAnimation("doUncuff"); nearestCuffPlayer.SyncAnimation("getUncuff"); PositionManager.cuffPoints.Remove(nearestCuffPlayer); } } public static void CheckToggleSurrender(this Player player) { player.TriggerEvent("SERVER:Handsup_CheckIfPlayerCanHandsup"); } public static void ToggleSurrender(this Player player) { if (player.HasAnimation("hup")) { PositionManager.cuffPoints.Remove(player); player.ClearAnimation(); return; } if (player.HasAnimation()) return; player.SyncAnimation("hup"); NAPI.Player.SetPlayerCurrentWeapon(player, WeaponHash.Unarmed); if (player.GetUser().Wanteds > 0) PositionManager.cuffPoints.Add(player); } public static void ToggleInventory(this Player player, InventoryToggleOption option = InventoryToggleOption.TOGGLE) { if (option == InventoryToggleOption.TOGGLE) { player.TriggerEvent("inventoryShow"); } else { player.TriggerEvent("inventoryShow", option == InventoryToggleOption.SHOW); } } } }