diff --git a/EXILED/EXILED.props b/EXILED/EXILED.props index a949e45c5..e11ce67c2 100644 --- a/EXILED/EXILED.props +++ b/EXILED/EXILED.props @@ -22,6 +22,7 @@ 2.2.2 1.1.118 2.0.2 + disable Copyright © $(Authors) 2020 - $([System.DateTime]::Now.ToString("yyyy")) Git diff --git a/EXILED/Exiled.API/Features/Items/Firearm.cs b/EXILED/Exiled.API/Features/Items/Firearm.cs index fb83411f2..6bfa9d237 100644 --- a/EXILED/Exiled.API/Features/Items/Firearm.cs +++ b/EXILED/Exiled.API/Features/Items/Firearm.cs @@ -13,24 +13,18 @@ namespace Exiled.API.Features.Items using CameraShaking; using Enums; - using Exiled.API.Features.Pickups; - using Exiled.API.Interfaces; - using Exiled.API.Structs; using Extensions; - using InventorySystem; - using InventorySystem.Items; - using InventorySystem.Items.Firearms; + using Interfaces; + using InventorySystem.Items.Autosync; using InventorySystem.Items.Firearms.Attachments; using InventorySystem.Items.Firearms.Attachments.Components; - using InventorySystem.Items.Firearms.BasicMessages; using InventorySystem.Items.Firearms.Modules; - using InventorySystem.Items.Pickups; using MEC; - using UnityEngine; + using Pickups; + using Structs; using BaseFirearm = InventorySystem.Items.Firearms.Firearm; using FirearmPickup = Pickups.FirearmPickup; - using Object = UnityEngine.Object; /// /// A wrapper class for . @@ -47,6 +41,8 @@ public class Firearm : Item, IWrapper /// internal static readonly Dictionary BaseCodesValue = new(); + private readonly IPrimaryAmmoContainerModule ammoModule; + /// /// Initializes a new instance of the class. /// @@ -55,6 +51,11 @@ public Firearm(BaseFirearm itemBase) : base(itemBase) { Base = itemBase; + foreach (ModuleBase mod in itemBase.Modules) + { + if (mod is IPrimaryAmmoContainerModule primary) + ammoModule = primary; + } } /// @@ -86,7 +87,7 @@ public static IReadOnlyDictionary>> playerPreferences = AttachmentsServerHandler.PlayerPreferences.Where( kvp => kvp.Key is not null).Select( - (KeyValuePair> keyValuePair) => + keyValuePair => { return new KeyValuePair>( Player.Get(keyValuePair.Key), @@ -109,8 +110,8 @@ public static IReadOnlyDictionary public int Ammo { - get => (Base.Modules[Array.IndexOf(Base.Modules, typeof(MagazineModule))] as MagazineModule).AmmoStored; - set => (Base.Modules[Array.IndexOf(Base.Modules, typeof(MagazineModule))] as MagazineModule).AmmoStored = value; + get => ammoModule?.AmmoStored ?? 0; + set => ammoModule?.ServerModifyAmmo(value); } /// @@ -119,8 +120,21 @@ public int Ammo /// Disruptor can't be used for MaxAmmo. public int MaxAmmo { - get => (Base.Modules[Array.IndexOf(Base.Modules, typeof(MagazineModule))] as MagazineModule).AmmoMax; - set => (Base.Modules[Array.IndexOf(Base.Modules, typeof(MagazineModule))] as MagazineModule)._defaultCapacity = value; // Synced? + get => ammoModule?.AmmoMax ?? 0; + set + { + switch (ammoModule) + { + case null: + throw new InvalidOperationException("Cannot change max ammo for non-ammo weapons."); + case MagazineModule mag: + mag._defaultCapacity = value; + break; + case CylinderAmmoModule: + CylinderAmmoModule.ServerPrepareNewChambers(Serial, value); + break; + } + } } /// @@ -131,7 +145,7 @@ public int MaxAmmo /// /// Gets the of the firearm. /// - public AmmoType AmmoType => (Base.Modules.OfType().FirstOrDefault()?.AmmoType ?? ItemType.None).GetAmmoType(); + public AmmoType AmmoType => ammoModule?.AmmoType.GetAmmoType() ?? AmmoType.None; /// /// Gets a value indicating whether the firearm is being aimed. @@ -406,7 +420,7 @@ public bool TryGetAttachment(AttachmentIdentifier identifier, out Attachment fir { firearmAttachment = default; - if (!Attachments.Any(attachment => attachment.Name == identifier.Name)) + if (Attachments.All(attachment => attachment.Name != identifier.Name)) return false; firearmAttachment = GetAttachment(identifier); @@ -558,11 +572,10 @@ public void RemovePreference(IEnumerable players, IEnumerableThe of which must be cleared. public void ClearPreferences(Player player) { - if (AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary)) - { - foreach (KeyValuePair kvp in dictionary) - dictionary[kvp.Key] = kvp.Key.GetFirearmType().GetBaseCode(); - } + if (!AttachmentsServerHandler.PlayerPreferences.TryGetValue(player.ReferenceHub, out Dictionary dictionary)) + return; + foreach (KeyValuePair kvp in dictionary) + dictionary[kvp.Key] = kvp.Key.GetFirearmType().GetBaseCode(); } /// @@ -590,20 +603,22 @@ public void ClearPreferences() /// Whether empty magazine should be loaded. public void Reload(bool emptyMagazine = false) { - MagazineModule magazineModule = Base.Modules.OfType().FirstOrDefault(); - - if (magazineModule == null) - return; - - magazineModule.ServerRemoveMagazine(); + if (ammoModule is MagazineModule magazineModule) + { + magazineModule.ServerRemoveMagazine(); - Timing.CallDelayed(0.1f, () => + Timing.CallDelayed(0.1f, () => + { + if (emptyMagazine) + magazineModule.ServerInsertEmptyMagazine(); + else + magazineModule.ServerInsertMagazine(); + }); + } + else if (Base.TryGetModule(out AnimatorReloaderModuleBase animatorModule)) { - if (emptyMagazine) - magazineModule.ServerInsertEmptyMagazine(); - else - magazineModule.ServerInsertMagazine(); - }); + animatorModule.StartReloading(); + } } /// @@ -639,6 +654,8 @@ internal override void ChangeOwner(Player oldOwner, Player newOwner) { Base.Owner = newOwner.ReferenceHub; Base._footprintCacheSet = false; + foreach (SubcomponentBase component in Base.AllSubcomponents) + component.OnAdded(); } /// @@ -648,8 +665,7 @@ internal override void ReadPickupInfo(Pickup pickup) if (pickup is FirearmPickup firearmPickup) { - // TODO If synced - // MaxAmmo = firearmPickup.MaxAmmo; + Timing.CallDelayed(0.1f, () => Ammo = firearmPickup.Ammo); } } } diff --git a/EXILED/Exiled.API/Features/Lockers/Locker.cs b/EXILED/Exiled.API/Features/Lockers/Locker.cs index 0e04382fc..997cf525f 100644 --- a/EXILED/Exiled.API/Features/Lockers/Locker.cs +++ b/EXILED/Exiled.API/Features/Lockers/Locker.cs @@ -10,20 +10,18 @@ namespace Exiled.API.Features.Lockers using System.Collections.Generic; using System.Linq; - using Exiled.API.Enums; - using Exiled.API.Extensions; - using Exiled.API.Features; - using Exiled.API.Features.Pickups; - using Exiled.API.Interfaces; - + using Enums; + using Extensions; + using Features; + using Interfaces; using InventorySystem.Items.Pickups; using MapGeneration.Distributors; - using Mirror; + using Pickups; using UnityEngine; using BaseLocker = MapGeneration.Distributors.Locker; -#nullable enable + /// /// The in-game Locker. /// @@ -79,7 +77,7 @@ public Locker(BaseLocker locker) /// /// Gets the in which the is located. /// - public Room? Room => Room.Get(Position); + public Room Room => Room.Get(Position); /// /// Gets the in which the locker is located. @@ -126,7 +124,7 @@ public Vector3 RandomChamberPosition /// /// The to get. /// A or if not found. - public static Locker? Get(BaseLocker locker) => locker == null ? null : + public static Locker Get(BaseLocker locker) => locker == null ? null : BaseToExiledLockers.TryGetValue(locker, out Locker supply) ? supply : new Locker(locker); /// @@ -149,7 +147,7 @@ public Vector3 RandomChamberPosition /// The to filter by. If unspecified, all zones are considered. /// The to filter by. If unspecified, all locker types are considered. /// A random object, or if no matching locker is found. - public static Locker? Random(ZoneType zone = ZoneType.Unspecified, LockerType lockerType = LockerType.Unknow) + public static Locker Random(ZoneType zone = ZoneType.Unspecified, LockerType lockerType = LockerType.Unknow) { IEnumerable filteredLockers = List; diff --git a/EXILED/Exiled.API/Features/Npc.cs b/EXILED/Exiled.API/Features/Npc.cs index 4055dfa6a..717dd0202 100644 --- a/EXILED/Exiled.API/Features/Npc.cs +++ b/EXILED/Exiled.API/Features/Npc.cs @@ -7,17 +7,13 @@ namespace Exiled.API.Features { -#nullable enable using System; using System.Collections.Generic; using System.Linq; - using System.Reflection; - using CentralAuth; using CommandSystem; using CommandSystem.Commands.RemoteAdmin.Dummies; using Exiled.API.Enums; - using Exiled.API.Features.Components; using Exiled.API.Features.Roles; using Footprinting; using GameCore; @@ -26,8 +22,6 @@ namespace Exiled.API.Features using PlayerRoles; using UnityEngine; - using Object = UnityEngine.Object; - /// /// Wrapper class for handling NPC players. /// @@ -68,7 +62,7 @@ public override Vector3 Position /// Gets or sets the player being followed. /// /// The npc must have . - public Player? FollowedPlayer + public Player FollowedPlayer { get => !GameObject.TryGetComponent(out PlayerFollower follower) ? null : Player.Get(follower._hubToFollow); @@ -176,70 +170,70 @@ public float? Speed /// /// The ReferenceHub to retrieve the NPC for. /// The NPC associated with the ReferenceHub, or null if not found. - public static new Npc? Get(ReferenceHub rHub) => Player.Get(rHub) as Npc; + public static new Npc Get(ReferenceHub rHub) => Player.Get(rHub) as Npc; /// /// Retrieves the NPC associated with the specified GameObject. /// /// The GameObject to retrieve the NPC for. /// The NPC associated with the GameObject, or null if not found. - public static new Npc? Get(GameObject gameObject) => Player.Get(gameObject) as Npc; + public static new Npc Get(GameObject gameObject) => Player.Get(gameObject) as Npc; /// /// Retrieves the NPC associated with the specified user ID. /// /// The user ID to retrieve the NPC for. /// The NPC associated with the user ID, or null if not found. - public static new Npc? Get(string userId) => Player.Get(userId) as Npc; + public static new Npc Get(string userId) => Player.Get(userId) as Npc; /// /// Retrieves the NPC associated with the specified ID. /// /// The ID to retrieve the NPC for. /// The NPC associated with the ID, or null if not found. - public static new Npc? Get(int id) => Player.Get(id) as Npc; + public static new Npc Get(int id) => Player.Get(id) as Npc; /// /// Retrieves the NPC associated with the specified ICommandSender. /// /// The ICommandSender to retrieve the NPC for. /// The NPC associated with the ICommandSender, or null if not found. - public static new Npc? Get(ICommandSender sender) => Player.Get(sender) as Npc; + public static new Npc Get(ICommandSender sender) => Player.Get(sender) as Npc; /// /// Retrieves the NPC associated with the specified Footprint. /// /// The Footprint to retrieve the NPC for. /// The NPC associated with the Footprint, or null if not found. - public static new Npc? Get(Footprint footprint) => Player.Get(footprint) as Npc; + public static new Npc Get(Footprint footprint) => Player.Get(footprint) as Npc; /// /// Retrieves the NPC associated with the specified CommandSender. /// /// The CommandSender to retrieve the NPC for. /// The NPC associated with the CommandSender, or null if not found. - public static new Npc? Get(CommandSender sender) => Player.Get(sender) as Npc; + public static new Npc Get(CommandSender sender) => Player.Get(sender) as Npc; /// /// Retrieves the NPC associated with the specified Collider. /// /// The Collider to retrieve the NPC for. /// The NPC associated with the Collider, or null if not found. - public static new Npc? Get(Collider collider) => Player.Get(collider) as Npc; + public static new Npc Get(Collider collider) => Player.Get(collider) as Npc; /// /// Retrieves the NPC associated with the specified net ID. /// /// The net ID to retrieve the NPC for. /// The NPC associated with the net ID, or null if not found. - public static new Npc? Get(uint netId) => Player.Get(netId) as Npc; + public static new Npc Get(uint netId) => Player.Get(netId) as Npc; /// /// Retrieves the NPC associated with the specified NetworkConnection. /// /// The NetworkConnection to retrieve the NPC for. /// The NPC associated with the NetworkConnection, or null if not found. - public static new Npc? Get(NetworkConnection conn) => Player.Get(conn) as Npc; + public static new Npc Get(NetworkConnection conn) => Player.Get(conn) as Npc; /// /// Spawns an NPC based on the given parameters. @@ -348,4 +342,4 @@ public void LateDestroy(float time) }); } } -} +} \ No newline at end of file diff --git a/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs b/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs index 936ac1d2c..b78043db6 100644 --- a/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs +++ b/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs @@ -7,9 +7,13 @@ namespace Exiled.API.Features.Pickups { - using Exiled.API.Interfaces; + using System; + using Interfaces; using InventorySystem.Items.Firearms; + using InventorySystem.Items.Firearms.Attachments; + using InventorySystem.Items.Firearms.Modules; + using UnityEngine; using BaseFirearm = InventorySystem.Items.Firearms.FirearmPickup; @@ -18,6 +22,8 @@ namespace Exiled.API.Features.Pickups /// public class FirearmPickup : Pickup, IWrapper { + private IPrimaryAmmoContainerModule module; + /// /// Initializes a new instance of the class. /// @@ -26,6 +32,7 @@ internal FirearmPickup(BaseFirearm pickupBase) : base(pickupBase) { Base = pickupBase; + module = AttachmentPreview.TryGet(Base.CurId, false, out Firearm firearm) ? firearm.TryGetModule(out CylinderAmmoModule cylinder) ? cylinder : firearm.TryGetModule(out MagazineModule magazine) ? magazine : null : null; } /// @@ -36,12 +43,7 @@ internal FirearmPickup(ItemType type) : base(type) { Base = (BaseFirearm)((Pickup)this).Base; - IsDistributed = true; - - // TODO not finish - /* - if (type is ItemType.ParticleDisruptor && Status.Ammo == 0) - Status = new FirearmStatus(5, FirearmStatusFlags.MagazineInserted, 0);*/ + module = AttachmentPreview.TryGet(Base.CurId, false, out Firearm firearm) ? firearm.TryGetModule(out CylinderAmmoModule cylinder) ? cylinder : firearm.TryGetModule(out MagazineModule magazine) ? magazine : null : null; } /// @@ -49,46 +51,20 @@ internal FirearmPickup(ItemType type) /// public new BaseFirearm Base { get; } - /// - /// Gets or sets a value indicating whether the pickup is already distributed. - /// - public bool IsDistributed { get; set; } - - // TODO NOT FINISH - /*{ - get => Base.Distributed; - set => Base.Distributed = value; - }*/ - - // TODO not finish - - /* - /// - /// Gets or sets the . - /// - public FirearmStatus Status - { - get => Base.NetworkStatus; - set => Base.NetworkStatus = value; - } - */ - /// /// Gets or sets a value indicating how many ammo have this . /// /// This will be updated only when item will be picked up. - public int Ammo { get; set; } - - /* - /// - /// Gets or sets the . - /// - public FirearmStatusFlags Flags + public int Ammo { - get => Base.NetworkStatus.Flags; - set => Base.NetworkStatus = new(Base.NetworkStatus.Ammo, value, Base.NetworkStatus.Attachments); + get => module?.AmmoStored ?? 0; + set + { + if (module is null) + throw new InvalidOperationException("Cannot set ammo for non-ammo using weapons."); + module.ServerModifyAmmo(value); + } } - */ /// /// Gets or sets a value indicating whether the attachment code have this . @@ -96,13 +72,40 @@ public FirearmStatusFlags Flags public uint Attachments { get => Base.Worldmodel.AttachmentCode; - set => Base.Worldmodel.AttachmentCode = value; + set => Base.Worldmodel.Setup(Base.CurId, Base.Worldmodel.WorldmodelType, value); } + /// + /// Gets a value indicating whether the item has been distributed. + /// + public bool IsDistributed { get; internal set; } + /// /// Returns the FirearmPickup in a human readable format. /// /// A string containing FirearmPickup related data. - public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{IsDistributed}| -{/*Ammo*/0}-"; + public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* -{Ammo}-"; + + /// + public override void Spawn() + { + base.Spawn(); + Base.OnDistributed(); + } + + /// + public override Pickup Spawn(Vector3 position, Quaternion? rotation = null, Player previousOwner = null) + { + Pickup pickup = base.Spawn(position, rotation, previousOwner); + Base.OnDistributed(); + return pickup; + } + + /// + public override void UnSpawn() + { + base.UnSpawn(); + IsDistributed = false; + } } } diff --git a/EXILED/Exiled.API/Features/Pickups/Pickup.cs b/EXILED/Exiled.API/Features/Pickups/Pickup.cs index 047958be7..4939b78f1 100644 --- a/EXILED/Exiled.API/Features/Pickups/Pickup.cs +++ b/EXILED/Exiled.API/Features/Pickups/Pickup.cs @@ -7,22 +7,19 @@ namespace Exiled.API.Features.Pickups { - using System; using System.Collections.Generic; using System.Linq; - using Exiled.API.Extensions; - using Exiled.API.Features.Core; - using Exiled.API.Features.Pickups.Projectiles; - using Exiled.API.Interfaces; - + using Core; + using Extensions; + using Interfaces; using InventorySystem; using InventorySystem.Items; using InventorySystem.Items.Pickups; using InventorySystem.Items.ThrowableProjectiles; using InventorySystem.Items.Usables.Scp244; - using Mirror; + using Projectiles; using RelativePositioning; using UnityEngine; @@ -37,7 +34,6 @@ namespace Exiled.API.Features.Pickups using BaseScp1576Pickup = InventorySystem.Items.Usables.Scp1576.Scp1576Pickup; using BaseScp2176Projectile = InventorySystem.Items.ThrowableProjectiles.Scp2176Projectile; using BaseScp330Pickup = InventorySystem.Items.Usables.Scp330.Scp330Pickup; - using Object = UnityEngine.Object; /// @@ -563,11 +559,17 @@ public float PickupTimeForPlayer(Player player) return Base.SearchTimeForPlayer(player.ReferenceHub); } + /// + /// Destroys the already spawned pickup. + /// + /// + public void Destroy() => Base.DestroySelf(); + /// /// Spawns pickup on a server. /// /// - public void Spawn() + public virtual void Spawn() { // condition for projectiles if (!GameObject.activeSelf) @@ -589,7 +591,7 @@ public void Spawn() /// An optional previous owner of the item. /// The spawned . /// - public Pickup Spawn(Vector3 position, Quaternion? rotation = null, Player previousOwner = null) + public virtual Pickup Spawn(Vector3 position, Quaternion? rotation = null, Player previousOwner = null) { Position = position; Rotation = rotation ?? Quaternion.identity; @@ -604,7 +606,7 @@ public Pickup Spawn(Vector3 position, Quaternion? rotation = null, Player previo /// /// /// - public void UnSpawn() + public virtual void UnSpawn() { if (IsSpawned) { @@ -612,12 +614,6 @@ public void UnSpawn() } } - /// - /// Destroys the already spawned pickup. - /// - /// - public void Destroy() => Base.DestroySelf(); - /// /// Clones the current pickup with a different serial. /// diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index b76a88753..94de341bf 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -17,21 +17,16 @@ namespace Exiled.API.Features using CustomPlayerEffects; using CustomPlayerEffects.Danger; using DamageHandlers; + using Doors; using Enums; using Exiled.API.Features.Core.Interfaces; - using Exiled.API.Features.Doors; - using Exiled.API.Features.Hazards; - using Exiled.API.Features.Items; - using Exiled.API.Features.Pickups; - using Exiled.API.Features.Pools; - using Exiled.API.Features.Roles; - using Exiled.API.Interfaces; - using Exiled.API.Structs; using Extensions; using Footprinting; using global::Scp914; + using Hazards; using Hints; using Interactables.Interobjects; + using Interfaces; using InventorySystem; using InventorySystem.Disarming; using InventorySystem.Items; @@ -41,10 +36,12 @@ namespace Exiled.API.Features using InventorySystem.Items.Firearms.ShotEvents; using InventorySystem.Items.Usables; using InventorySystem.Items.Usables.Scp330; + using Items; using MapGeneration.Distributors; using MEC; using Mirror; using Mirror.LiteNetLib4Mirror; + using Pickups; using PlayerRoles; using PlayerRoles.FirstPersonControl; using PlayerRoles.FirstPersonControl.Thirdperson.Subcontrollers; @@ -53,10 +50,13 @@ namespace Exiled.API.Features using PlayerRoles.Voice; using PlayerStatsSystem; using PluginAPI.Core; + using Pools; using RelativePositioning; using RemoteAdmin; using Respawning.NamingRules; + using Roles; using RoundRestarting; + using Structs; using UnityEngine; using Utils; using Utils.Networking; @@ -2654,6 +2654,12 @@ public Item AddItem(FirearmType firearmType, IEnumerable i else if (Preferences is not null && Preferences.TryGetValue(firearmType, out AttachmentIdentifier[] attachments)) firearm.Base.ApplyAttachmentsCode(attachments.GetAttachmentsCode(), true); + foreach (ModuleBase module in firearm.Base.Modules) + { + if (module is IPrimaryAmmoContainerModule primaryAmmo) + primaryAmmo.ServerModifyAmmo(primaryAmmo.AmmoMax); + } + // TODO Not finish /* FirearmStatusFlags flags = FirearmStatusFlags.MagazineInserted; diff --git a/EXILED/Exiled.Events/EventArgs/Player/ReloadingWeaponEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ReloadingWeaponEventArgs.cs index 0dde302a9..29feac45b 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/ReloadingWeaponEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/ReloadingWeaponEventArgs.cs @@ -26,20 +26,16 @@ public class ReloadingWeaponEventArgs : IPlayerEvent, IFirearmEvent, IDeniableEv /// /// /// - /// - /// - /// - public ReloadingWeaponEventArgs(Player player, Firearm firearm, bool isAllowed = true) + public ReloadingWeaponEventArgs(Player player, Firearm firearm) { Firearm = firearm; Player = player; - IsAllowed = isAllowed; } /// /// Gets or sets a value indicating whether the weapon can be reloaded. /// - public bool IsAllowed { get; set; } + public bool IsAllowed { get; set; } = true; /// /// Gets the being reloaded. diff --git a/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs index 0eb6a5c69..f2e6daf7c 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/ShotEventArgs.cs @@ -28,12 +28,19 @@ public class ShotEventArgs : IPlayerEvent, IFirearmEvent public ShotEventArgs(HitscanHitregModuleBase hitregModule, RaycastHit hitInfo, InventorySystem.Items.Firearms.Firearm firearm, IDestructible destructible) { HitregModule = hitregModule; + Firearm = Item.Get(firearm); + Player = Firearm.Owner; + Distance = hitInfo.distance; + Position = hitInfo.point; RaycastHit = hitInfo; Destructible = destructible; - Firearm = Item.Get(firearm); + if (Destructible is null) + { + hitInfo.distance = float.PositiveInfinity; + return; + } - Player = Firearm.Owner; - Damage = Destructible is not null ? HitregModule.DamageAtDistance(hitInfo.distance) : 0f; + Damage = HitregModule.DamageAtDistance(hitInfo.distance); if (Destructible is HitboxIdentity hitboxIdentity) { @@ -61,19 +68,24 @@ public ShotEventArgs(HitscanHitregModuleBase hitregModule, RaycastHit hitInfo, I public HitscanHitregModuleBase HitregModule { get; } /// - /// Gets the raycast info. + /// Gets the shot distance. Can be 0.0f if the raycast doesn't hit collider. /// - public RaycastHit RaycastHit { get; } + public float Distance { get; } + + /// + /// Gets the shot position. Can be if the raycast doesn't hit collider. + /// + public Vector3 Position { get; } /// - /// Gets the bullet travel distance. + /// Gets the component of the hit collider. Can be . /// - public float Distance => RaycastHit.distance; + public IDestructible Destructible { get; } /// - /// Gets the position of the hit. + /// Gets the raycast result. /// - public Vector3 Position => RaycastHit.point; + public RaycastHit RaycastHit { get; } /// /// Gets the firearm base damage at the hit distance. Actual inflicted damage may vary. @@ -86,15 +98,10 @@ public ShotEventArgs(HitscanHitregModuleBase hitregModule, RaycastHit hitInfo, I public Player Target { get; } /// - /// Gets the component of the target player that was hit. Can be null. + /// Gets the component of the target player that was hit. Can be . /// public HitboxIdentity Hitbox { get; } - /// - /// Gets the component of the hit collider. Can be null. - /// - public IDestructible Destructible { get; } - /// /// Gets or sets a value indicating whether the shot can deal damage. /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/UnloadingWeaponEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/UnloadingWeaponEventArgs.cs index a5c8df5f0..ee0ed4f65 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/UnloadingWeaponEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/UnloadingWeaponEventArgs.cs @@ -26,20 +26,16 @@ public class UnloadingWeaponEventArgs : IPlayerEvent, IFirearmEvent, IDeniableEv /// /// /// - /// - /// - /// - public UnloadingWeaponEventArgs(Player player, Firearm firearm, bool isAllowed = true) + public UnloadingWeaponEventArgs(Player player, Firearm firearm) { Firearm = firearm; Player = player; - IsAllowed = isAllowed; } /// /// Gets or sets a value indicating whether the weapon can be unloaded. /// - public bool IsAllowed { get; set; } + public bool IsAllowed { get; set; } = true; /// /// Gets the being unloaded. diff --git a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs index 47f1ede44..c9b92a2f5 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs @@ -151,8 +151,18 @@ private static IEnumerable Transpiler(IEnumerable -// Copyright (c) ExMod Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Events.Player -{ - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features.Items; - using Exiled.Events.Attributes; - using Exiled.Events.EventArgs.Player; - using Handlers; - using HarmonyLib; - using InventorySystem.Items; - using InventorySystem.Items.Firearms; - using InventorySystem.Items.Firearms.BasicMessages; - using PluginAPI.Events; - - using static HarmonyLib.AccessTools; - - /* TODO - /// - /// Patches . - /// Adds , , - /// , and - /// events. - /// - [EventPatch(typeof(Player), nameof(Player.ReloadingWeapon))] - [EventPatch(typeof(Player), nameof(Player.UnloadingWeapon))] - [EventPatch(typeof(Player), nameof(Player.DryfiringWeapon))] - [EventPatch(typeof(Player), nameof(Player.AimingDownSight))] - [EventPatch(typeof(Player), nameof(Player.TogglingWeaponFlashlight))] - [HarmonyPatch(typeof(FirearmUtils), nameof())] - internal static class FirearmRequestReceived - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder ev = generator.DeclareLocal(typeof(TogglingWeaponFlashlightEventArgs)); - LocalBuilder player = generator.DeclareLocal(typeof(API.Features.Player)); - LocalBuilder firearm = generator.DeclareLocal(typeof(Firearm)); - - Label returnLabel = generator.DefineLabel(); - - int offset = -1; - int index = newInstructions.FindLastIndex(instruction => instruction.LoadsField(Field(typeof(RequestMessage), nameof(RequestMessage.Request)))) + offset; - - newInstructions.InsertRange(index, new[] - { - // Player player = Player.Get(hub); - // if (player == null) - // return; - new CodeInstruction(OpCodes.Ldloc_0).MoveLabelsFrom(newInstructions[index]), - new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Dup), - new(OpCodes.Stloc_S, player.LocalIndex), - new(OpCodes.Brfalse_S, returnLabel), - - // Firearm firearm = (Firearm)Item.Get(hub); - // if (Firearm == null) - // return; - new CodeInstruction(OpCodes.Ldloc_1), - new(OpCodes.Call, GetDeclaredMethods(typeof(API.Features.Items.Item)).First(x => !x.IsGenericMethod && x.Name is nameof(API.Features.Items.Item.Get) && x.GetParameters().Length is 1 && x.GetParameters()[0].ParameterType == typeof(ItemBase))), - new(OpCodes.Isinst, typeof(Firearm)), - new(OpCodes.Dup), - new(OpCodes.Stloc_S, firearm.LocalIndex), - new(OpCodes.Brfalse_S, returnLabel), - }); - - offset = -2; - index = newInstructions.FindIndex( - instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerReloadWeaponEvent))[0]) + offset; - - newInstructions.InsertRange( - index, - new[] - { - // player - new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]), - - // firearm - new(OpCodes.Ldloc_S, firearm.LocalIndex), - - // true - new(OpCodes.Ldc_I4_1), - - // ReloadingWeaponEventArgs ev = new(Player, firearm, bool) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ReloadingWeaponEventArgs))[0]), - new(OpCodes.Dup), - - // Player.OnReloadingWeapon(ev) - new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnReloadingWeapon))), - - // if (!ev.IsAllowed) - // return; - new(OpCodes.Callvirt, PropertyGetter(typeof(ReloadingWeaponEventArgs), nameof(ReloadingWeaponEventArgs.IsAllowed))), - new(OpCodes.Brfalse, returnLabel), - }); - - offset = -2; - index = newInstructions.FindIndex( - instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerUnloadWeaponEvent))[0]) + offset; - - newInstructions.InsertRange( - index, - new[] - { - // player - new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]), - - // firearm - new(OpCodes.Ldloc_S, firearm.LocalIndex), - - // true - new(OpCodes.Ldc_I4_1), - - // UnloadingWeaponEventArgs ev = new(Player, firearm, bool) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(UnloadingWeaponEventArgs))[0]), - new(OpCodes.Dup), - - // Player.OnUnloadingWeapon(ev) - new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnUnloadingWeapon))), - - // if (!ev.IsAllowed) - // return; - new(OpCodes.Callvirt, PropertyGetter(typeof(UnloadingWeaponEventArgs), nameof(UnloadingWeaponEventArgs.IsAllowed))), - new(OpCodes.Brfalse, returnLabel), - }); - - offset = -2; - index = newInstructions.FindIndex( - instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerDryfireWeaponEvent))[0]) + offset; - - newInstructions.InsertRange( - index, - new[] - { - // player - new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]), - - // firearm - new(OpCodes.Ldloc_S, firearm.LocalIndex), - - // true - new(OpCodes.Ldc_I4_1), - - // DryfiringWeaponEventArgs ev = new(Player, firearm, bool) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(DryfiringWeaponEventArgs))[0]), - new(OpCodes.Dup), - - // Player.OnDryfiringWeapon(ev) - new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnDryfiringWeapon))), - - // if (!ev.IsAllowed) - // return; - new(OpCodes.Callvirt, PropertyGetter(typeof(DryfiringWeaponEventArgs), nameof(DryfiringWeaponEventArgs.IsAllowed))), - new(OpCodes.Brfalse, returnLabel), - }); - - offset = -3; - index = newInstructions.FindIndex( - instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerAimWeaponEvent))[0]) + offset; - - newInstructions.InsertRange( - index, - new[] - { - // player - new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]), - - // firearm - new(OpCodes.Ldloc_S, firearm.LocalIndex), - - // true (adsIn) - new(OpCodes.Ldc_I4_1), - - // false (adsOut) - new(OpCodes.Ldc_I4_0), - - // AimingDownSightEventArgs ev = new(Player, firearm, bool, bool) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(AimingDownSightEventArgs))[0]), - - // Player.OnAimingDownSight(ev) - new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnAimingDownSight))), - }); - - offset = -3; - index = newInstructions.FindLastIndex( - instruction => instruction.opcode == OpCodes.Newobj && (ConstructorInfo)instruction.operand == GetDeclaredConstructors(typeof(PlayerAimWeaponEvent))[0]) + offset; - - newInstructions.InsertRange( - index, - new[] - { - // player - new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex).MoveLabelsFrom(newInstructions[index]), - - // firearm - new(OpCodes.Ldloc_S, firearm.LocalIndex), - - // false (adsIn) - new(OpCodes.Ldc_I4_0), - - // true (adsOut) - new(OpCodes.Ldc_I4_1), - - // AimingDownSightEventArgs ev = new(Player, firearm, bool, bool) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(AimingDownSightEventArgs))[0]), - - // Player.OnAimingDownSight(ev) - new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnAimingDownSight))), - }); - - offset = -7; - index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ceq) + offset; - - newInstructions.InsertRange( - index, - new[] - { - // player - new CodeInstruction(OpCodes.Ldloc_S, player.LocalIndex), - - // firearm - new(OpCodes.Ldloc_S, firearm.LocalIndex), - - // !flag - new(OpCodes.Ldloc_S, 8), - new(OpCodes.Ldc_I4_0), - new(OpCodes.Ceq), - - // true - new(OpCodes.Ldc_I4_1), - - // TogglingWeaponFlashlightEventArgs ev = new(Player, firearm, bool, bool) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(TogglingWeaponFlashlightEventArgs))[0]), - new(OpCodes.Dup), - new(OpCodes.Dup), - new(OpCodes.Stloc_S, ev.LocalIndex), - - // Player.OnTogglingWeaponFlashlight(ev) - new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnTogglingWeaponFlashlight))), - - // if (!ev.IsAllowed) - // return; - new(OpCodes.Callvirt, PropertyGetter(typeof(TogglingWeaponFlashlightEventArgs), nameof(TogglingWeaponFlashlightEventArgs.IsAllowed))), - new(OpCodes.Brfalse_S, returnLabel), - - // flag = !ev.NewState - new(OpCodes.Ldloc_S, ev.LocalIndex), - new(OpCodes.Callvirt, PropertyGetter(typeof(TogglingWeaponFlashlightEventArgs), nameof(TogglingWeaponFlashlightEventArgs.NewState))), - new(OpCodes.Ldc_I4_0), - new(OpCodes.Ceq), - new(OpCodes.Stloc_S, 6), - }); - - newInstructions[newInstructions.Count - 1].WithLabels(returnLabel); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } - */ -} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Player/ReloaderProcessCommand.cs b/EXILED/Exiled.Events/Patches/Events/Player/ReloaderProcessCommand.cs new file mode 100644 index 000000000..b11f5573f --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Events/Player/ReloaderProcessCommand.cs @@ -0,0 +1,115 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Player +{ + using System.Collections.Generic; + using System.Linq; + using System.Reflection.Emit; + + using Attributes; + using Exiled.API.Features.Items; + using Exiled.API.Features.Pools; + using Exiled.Events.EventArgs.Player; + using HarmonyLib; + using InventorySystem.Items.Autosync; + using InventorySystem.Items.Firearms.Modules; + + using static HarmonyLib.AccessTools; + + using Player = Exiled.Events.Handlers.Player; + + /// + /// Patches the method to add the and events. + /// + [EventPatch(typeof(Player), nameof(Player.ReloadingWeapon))] + [HarmonyPatch(typeof(AnimatorReloaderModuleBase), nameof(AnimatorReloaderModuleBase.ServerProcessCmd))] + internal static class ReloaderProcessCommand + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + LocalBuilder player = generator.DeclareLocal(typeof(API.Features.Player)); + LocalBuilder firearm = generator.DeclareLocal(typeof(Firearm)); + + Label ret = generator.DefineLabel(); + Label cont = generator.DefineLabel(); + Label unloadCheck = generator.DefineLabel(); + + int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Ldloc_1); + + // Index is correct, player and firearm exist, skips reload and continues to no action. + newInstructions.InsertRange(index, new[] + { + // player = Player.Get(this.Item.Owner); + new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Callvirt, PropertyGetter(typeof(AnimatorReloaderModuleBase), nameof(AnimatorReloaderModuleBase.Item))), + new(OpCodes.Callvirt, PropertyGetter(typeof(ModularAutosyncItem), nameof(ModularAutosyncItem.Owner))), + new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), + new(OpCodes.Isinst, typeof(API.Features.Player)), + new(OpCodes.Dup), + new(OpCodes.Stloc_S, player.LocalIndex), + new(OpCodes.Brfalse_S, cont), + + // firearm = Firearm.Get(this.ItemSerial); + new(OpCodes.Ldarg_0), + new(OpCodes.Callvirt, PropertyGetter(typeof(AnimatorReloaderModuleBase), nameof(AnimatorReloaderModuleBase.ItemSerial))), + new(OpCodes.Call, GetDeclaredMethods(typeof(API.Features.Items.Item)).First(x => !x.IsGenericMethod && x.Name is nameof(API.Features.Items.Item.Get) && x.GetParameters().Length is 1 && x.GetParameters()[0].ParameterType == typeof(ushort))), + new(OpCodes.Isinst, typeof(Firearm)), + new(OpCodes.Dup), + new(OpCodes.Stloc_S, firearm.LocalIndex), + new(OpCodes.Brfalse_S, cont), + + // if (header == Reloading) ... + new(OpCodes.Ldloc_2), + new(OpCodes.Ldc_I4_1), + new(OpCodes.Ceq), + new(OpCodes.Brfalse_S, unloadCheck), + + // ReloadingWeaponEventArgs ev = new(player, firearm); + // Player.OnReloadingWeapon(ev); + // if (!ev.IsAllowed) + // return; + new(OpCodes.Ldloc_S, player.LocalIndex), + new(OpCodes.Ldloc_S, firearm.LocalIndex), + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ReloadingWeaponEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnReloadingWeapon))), + new(OpCodes.Callvirt, PropertyGetter(typeof(ReloadingWeaponEventArgs), nameof(ReloadingWeaponEventArgs.IsAllowed))), + new(OpCodes.Brfalse_S, ret), + new(OpCodes.Br_S, cont), + + // else if (header == Unloading) ... + new CodeInstruction(OpCodes.Ldloc_2).WithLabels(unloadCheck), + new(OpCodes.Ldc_I4_2), + new(OpCodes.Ceq), + new(OpCodes.Brfalse_S, cont), + + // UnloadingWeaponEventArgs ev = new(player, firearm); + // Player.OnUnloadingWeapon(ev); + // if (!ev.IsAllowed) + // return; + new(OpCodes.Ldloc_S, player.LocalIndex), + new(OpCodes.Ldloc_S, firearm.LocalIndex), + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(UnloadingWeaponEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Call, Method(typeof(Player), nameof(Player.OnUnloadingWeapon))), + new(OpCodes.Callvirt, PropertyGetter(typeof(UnloadingWeaponEventArgs), nameof(UnloadingWeaponEventArgs.IsAllowed))), + new(OpCodes.Brfalse_S, ret), + + new CodeInstruction(OpCodes.Nop).WithLabels(cont), + }); + + newInstructions[newInstructions.Count - 1].labels.Add(ret); + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs b/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs index 501c1f812..0de58f557 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs @@ -25,7 +25,6 @@ namespace Exiled.Events.Patches.Events.Player /// Adds the events. /// [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Shooting))] - [HarmonyPatch(typeof(ShotBacktrackData), nameof(ShotBacktrackData.ProcessShot))] internal static class Shooting { diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Shot.cs b/EXILED/Exiled.Events/Patches/Events/Player/Shot.cs index 317a694ae..8338de2c3 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/Shot.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/Shot.cs @@ -87,26 +87,36 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions); Label returnLabel = generator.DefineLabel(); - LocalBuilder ev = generator.DeclareLocal(typeof(ElevatorTeleportingEventArgs)); - int offset = -3; - int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldloc_2) + offset; - - newInstructions.InsertRange(index, new[] - { - // Player.Get(base.Owner) - new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - - // base.CurrentCamSync.CurrentCamera.Room - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(Scp079AbilityBase), nameof(Scp079AbilityBase.CurrentCamSync))), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079CurrentCameraSync), nameof(Scp079CurrentCameraSync.CurrentCamera))), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079Camera), nameof(Scp079Camera.Room))), - - // chamber - new(OpCodes.Ldloc_2), - - // (float)this._cost - new(OpCodes.Ldarg_0), - new(OpCodes.Ldfld, Field(typeof(Scp079ElevatorStateChanger), nameof(Scp079ElevatorStateChanger._cost))), - new(OpCodes.Conv_R4), - - // ElevatorTeleportingEventArgs ev = new(Player, RoomIdentifier, ElevatorChamber, float) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ElevatorTeleportingEventArgs))[0]), - new(OpCodes.Dup), - new(OpCodes.Dup), - new(OpCodes.Stloc_S, ev.LocalIndex), - - // Scp079.OnElevatorTeleporting(ev); - new(OpCodes.Call, Method(typeof(Scp079), nameof(Scp079.OnElevatorTeleporting))), - - // if (!ev.IsAllowed) - // return; - new(OpCodes.Callvirt, PropertyGetter(typeof(ElevatorTeleportingEventArgs), nameof(ElevatorTeleportingEventArgs.IsAllowed))), - new(OpCodes.Brfalse, returnLabel), - }); + LocalBuilder ev = generator.DeclareLocal(typeof(ElevatorTeleportingEventArgs)); + int offset = 0; + int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldloc_3) + offset; + + // ElevatorTeleportingEventArgs ev = new(Player.Get(base.Owner), base.CurrentCamSync.CurrentCamera.Room, elevatorDoor, (float)this._cost); + // + // Handlers.Scp079.OnElevatorTeleporting(ev); + // + // if (!ev.IsAllowed) + // return; + newInstructions.InsertRange( + index, + new CodeInstruction[] + { + // Player.Get(base.Owner) + new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), + new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), + + // base.CurrentCamSync.CurrentCamera.Room + new(OpCodes.Ldarg_0), + new(OpCodes.Call, PropertyGetter(typeof(Scp079AbilityBase), nameof(Scp079AbilityBase.CurrentCamSync))), + new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079CurrentCameraSync), nameof(Scp079CurrentCameraSync.CurrentCamera))), + new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079Camera), nameof(Scp079Camera.Room))), + + // elevatorDoor + new(OpCodes.Ldloc_3), + + // (float)this._cost + new(OpCodes.Ldarg_0), + new(OpCodes.Ldfld, Field(typeof(Scp079ElevatorStateChanger), nameof(Scp079ElevatorStateChanger._cost))), + new(OpCodes.Conv_R4), + + // ElevatorTeleportingEventArgs ev = new(Player, RoomIdentifier, ElevatorDoor, float) + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ElevatorTeleportingEventArgs))[0]), + new(OpCodes.Dup), + new(OpCodes.Dup), + new(OpCodes.Stloc_S, ev.LocalIndex), + + // Scp079.OnElevatorTeleporting(ev); + new(OpCodes.Call, Method(typeof(Scp079), nameof(Scp079.OnElevatorTeleporting))), + + // if (!ev.IsAllowed) + // return; + new(OpCodes.Callvirt, PropertyGetter(typeof(ElevatorTeleportingEventArgs), nameof(ElevatorTeleportingEventArgs.IsAllowed))), + new(OpCodes.Brfalse, returnLabel), + }); + + // Replace "(float)this._cost" with "ev.AuxiliaryPowerCost" offset = -1; - index = newInstructions.FindLastIndex(instruction => instruction.LoadsField(Field(typeof(Scp079ElevatorStateChanger), nameof(Scp079ElevatorStateChanger._cost)))) + offset; + index = newInstructions.FindLastIndex( + instruction => instruction.LoadsField(Field(typeof(Scp079ElevatorStateChanger), nameof(Scp079ElevatorStateChanger._cost)))) + offset; newInstructions.RemoveRange(index, 3); - newInstructions.InsertRange(index, new CodeInstruction[] - { - // ev.AuxiliaryPowerCost - new(OpCodes.Ldloc, ev.LocalIndex), - new(OpCodes.Callvirt, PropertyGetter(typeof(ElevatorTeleportingEventArgs), nameof(ElevatorTeleportingEventArgs.AuxiliaryPowerCost))), - }); + newInstructions.InsertRange( + index, + new CodeInstruction[] + { + // ev.AuxiliaryPowerCost + new(OpCodes.Ldloc, ev.LocalIndex), + new(OpCodes.Callvirt, PropertyGetter(typeof(ElevatorTeleportingEventArgs), nameof(ElevatorTeleportingEventArgs.AuxiliaryPowerCost))), + }); newInstructions[newInstructions.Count - 1].WithLabels(returnLabel); diff --git a/EXILED/Exiled.Installer/CommandSettings.cs b/EXILED/Exiled.Installer/CommandSettings.cs index 55f5b226d..b9bb94db0 100644 --- a/EXILED/Exiled.Installer/CommandSettings.cs +++ b/EXILED/Exiled.Installer/CommandSettings.cs @@ -21,7 +21,7 @@ internal sealed class CommandSettings /// public static readonly RootCommand RootCommand = new() { - new Option( + new Option( new[] { "-p", "--path" }, (parsed) => { @@ -44,7 +44,7 @@ internal sealed class CommandSettings "Path to the folder with the SL server") { IsRequired = true }, - new Option( + new Option( "--appdata", (parsed) => { @@ -67,7 +67,7 @@ internal sealed class CommandSettings "Forces the folder to be the AppData folder (useful for containers when pterodactyl runs as root)") { IsRequired = true }, - new Option( + new Option( "--exiled", (parsed) => { @@ -96,17 +96,17 @@ internal sealed class CommandSettings "Includes pre-releases") { IsRequired = false }, - new Option( + new Option( "--target-port", "Target port for ExiledLoader installation") { IsRequired = false }, - new Option( + new Option( "--target-version", "Target version for installation") { IsRequired = false }, - new Option( + new Option( "--github-token", "Uses a token for auth in case the rate limit is exceeded (no permissions required)") { IsRequired = false }, @@ -122,7 +122,6 @@ internal sealed class CommandSettings { IsRequired = false }, }; -#nullable disable /// /// Gets or sets the directory path. /// @@ -137,7 +136,7 @@ internal sealed class CommandSettings /// Gets or sets the Exiled directory path. /// public DirectoryInfo Exiled { get; set; } -#nullable restore + /// /// Gets or sets if it is a prerelease. /// @@ -146,17 +145,17 @@ internal sealed class CommandSettings /// /// Gets or sets the target port. /// - public string? TargetPort { get; set; } + public string TargetPort { get; set; } /// /// Gets or sets the target version. /// - public string? TargetVersion { get; set; } + public string TargetVersion { get; set; } /// /// Gets or sets the GitHub token. /// - public string? GitHubToken { get; set; } + public string GitHubToken { get; set; } /// /// Gets or sets the version of Exiled available. diff --git a/EXILED/Exiled.Installer/Program.cs b/EXILED/Exiled.Installer/Program.cs index c7a43a2dc..e95a665b6 100644 --- a/EXILED/Exiled.Installer/Program.cs +++ b/EXILED/Exiled.Installer/Program.cs @@ -15,14 +15,10 @@ namespace Exiled.Installer using System.Reflection; using System.Text; using System.Threading.Tasks; - - using Exiled.Installer.Properties; - using ICSharpCode.SharpZipLib.GZip; using ICSharpCode.SharpZipLib.Tar; - using Octokit; - + using Properties; using Version = SemanticVersioning.Version; internal enum PathResolution @@ -101,7 +97,7 @@ internal static async Task MainSafe(CommandSettings args) Console.WriteLine(Resources.Program_MainSafe_Release_found_); Console.WriteLine(FormatRelease(targetRelease!)); - ReleaseAsset? exiledAsset = targetRelease!.Assets.FirstOrDefault(a => a.Name.Equals(ExiledAssetName, StringComparison.OrdinalIgnoreCase)); + ReleaseAsset exiledAsset = targetRelease!.Assets.FirstOrDefault(a => a.Name.Equals(ExiledAssetName, StringComparison.OrdinalIgnoreCase)); if (exiledAsset is null) { Console.WriteLine(Resources.Program_MainSafe_____ASSETS____); @@ -220,7 +216,7 @@ private static void ExtractEntry(TarInputStream tarInputStream, TarEntry entry, EnsureDirExists(Path.GetDirectoryName(path)!); - FileStream? fs = null; + FileStream fs = null; try { fs = new FileStream(path, System.IO.FileMode.Create, FileAccess.Write, FileShare.None); @@ -280,7 +276,7 @@ static PathResolution TryParse(string s) private static Release FindRelease(CommandSettings args, IEnumerable releases) { Console.WriteLine(Resources.Program_TryFindRelease_Trying_to_find_release__); - Version? targetVersion = args.TargetVersion is not null ? new Version(args.TargetVersion) : null; + Version targetVersion = args.TargetVersion is not null ? new Version(args.TargetVersion) : null; List enumerable = releases.ToList();