Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Support for upcoming SPT 3.10, using EFT 0.15.5.33420 #590

Merged
merged 60 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
e9b9c2c
Proto for upcoming spt release
sailro Sep 4, 2024
8f683dd
Rewrite
sailro Sep 4, 2024
8d66285
Fix instant-reveal
sailro Sep 5, 2024
46d5b52
Remove unused namespaces
sailro Sep 5, 2024
cbd927f
Removve newline
sailro Sep 5, 2024
4b64f36
Only enable when needed
sailro Sep 5, 2024
0036089
Fix wishlist
sailro Sep 6, 2024
c8f9897
Add an option to track the auto-wishlist
sailro Sep 6, 2024
61e341f
Add `spawnhi` command
sailro Sep 6, 2024
d17130f
Reword/consistency, do not use `wallhack` term anymore.
sailro Sep 9, 2024
bc0d583
Update Strings.zh-cn.resx
sailro Sep 9, 2024
35b9861
Update Strings.zh-cn.resx
sailro Sep 10, 2024
0ae1c64
Merge pull request #561 from sailro/wallhack-to-players
sailro Sep 10, 2024
c7b1e1b
Add noflash feature
sailro Sep 10, 2024
0570c89
Update readme
sailro Sep 10, 2024
6cb895b
Merge pull request #562 from sailro/noflash
sailro Sep 11, 2024
4169c94
Refine installer
sailro Sep 11, 2024
c728c4d
Improve prompt
sailro Sep 12, 2024
798cbb0
Bump installer version
sailro Sep 12, 2024
91ded69
Check if the version is supported
sailro Sep 12, 2024
fbf6616
Faster branch check
sailro Sep 12, 2024
0d219d9
Refine implementation
sailro Sep 13, 2024
a78e85d
Merge pull request #563 from sailro/refine-installer
sailro Sep 13, 2024
de3c698
Reword
sailro Sep 16, 2024
8d12206
Detect SPT-AKI install locations from MUI cache
sailro Sep 17, 2024
1691856
handle 'The variable 'e' is declared but never used'
sailro Sep 17, 2024
5ce1bae
Merge pull request #566 from sailro/muicache
sailro Sep 17, 2024
52f2fc4
Bump installer version
sailro Sep 17, 2024
f7e2847
Minor fixes
sailro Sep 23, 2024
532768d
Add extra setup for spawned items
sailro Sep 25, 2024
7533eb4
Merge pull request #570 from sailro/setup-items
sailro Sep 26, 2024
fa1c0f2
Update readme
sailro Sep 27, 2024
bb59f45
Triggers a mortar strike at the player's location
sailro Sep 27, 2024
0ec5e85
Merge pull request #572 from sailro/mortar
sailro Sep 28, 2024
21da983
Improve spawn
sailro Sep 29, 2024
e8be903
Merge pull request #573 from sailro/better-spawn
sailro Sep 30, 2024
f115e22
Triggers an airdrop at the player's location
sailro Sep 30, 2024
0ed1cab
Simplify
sailro Sep 30, 2024
e0f6c0d
Comment is now incorrect
sailro Sep 30, 2024
dc27e4d
Merge pull request #574 from sailro/airdrop
sailro Oct 1, 2024
78eaa8e
Bump Microsoft.CodeAnalysis.Analyzers in the roslyn group
dependabot[bot] Oct 7, 2024
2e4c206
Merge pull request #579 from sailro/dependabot/nuget/roslyn-31eff403df
sailro Oct 8, 2024
86f2555
Bump Microsoft.CodeAnalysis.Analyzers in the roslyn group
dependabot[bot] Oct 14, 2024
5777fe3
Bump System.Reflection.Metadata from 8.0.0 to 8.0.1
dependabot[bot] Oct 14, 2024
1c6773f
Fix translation
sailro Oct 24, 2024
9f80c94
Enable IAmDevShowMeLogs
sailro Oct 24, 2024
2950515
Use DamageInfoStruct
sailro Nov 3, 2024
a1a8bb9
Profile.Examined overload is now using MongoId
sailro Nov 3, 2024
008048b
Bump Microsoft.Unity.Analyzers in the analyzers group
dependabot[bot] Nov 4, 2024
1de184a
Merge pull request #582 from sailro/dependabot/nuget/System.Reflectio…
sailro Nov 8, 2024
68d60c1
Merge pull request #581 from sailro/dependabot/nuget/roslyn-31eff403df
sailro Nov 8, 2024
72d0c2b
Merge branch 'dev-0.15.5.33420' into dependabot/nuget/analyzers-f1acd…
sailro Nov 8, 2024
b0d27ab
Merge pull request #591 from sailro/dependabot/nuget/analyzers-f1acdf…
sailro Nov 8, 2024
effe2d9
Latest updates
sailro Nov 16, 2024
4cd3f45
Fix Examine after latest update
sailro Nov 16, 2024
5fb34b9
Update packages
sailro Nov 16, 2024
1171b6d
Fix template/spawn
sailro Nov 16, 2024
352f4ea
Fill magazines or Amoboxes with compatible ammunition
sailro Nov 17, 2024
1841b75
Use .net 9
sailro Nov 18, 2024
faf689a
Update publish profile
sailro Nov 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci-installer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ env:
CONFIGURATION: ${{ inputs.configuration != '' && inputs.configuration || 'Release' }}
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
DOTNET_NOLOGO: 1
INSTALLER_DOTNET_VERSION: '8.0'
INSTALLER_DOTNET_VERSION: '9.0'
INSTALLER_PLATFORM: 'win-x64'

jobs:
Expand Down
24 changes: 0 additions & 24 deletions ConsoleCommands/BaseTemplateCommand.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Comfort.Common;
using EFT.InventoryLogic;

#nullable enable

namespace EFT.Trainer.ConsoleCommands;

internal abstract class BaseTemplateCommand : ConsoleCommandWithArgument
{
public override string Pattern => RequiredArgumentPattern;

protected static ItemTemplate[] FindTemplates(string searchShortNameOrTemplateId)
{
if (!Singleton<ItemFactory>.Instantiated)
return [];

var templates = Singleton<ItemFactory>
.Instance
.ItemTemplates;

// Match by TemplateId
if (templates.TryGetValue(searchShortNameOrTemplateId, out var template))
return [template];

// Match by short name(s)
return templates
.Values
.Where(t => t.ShortNameLocalizationKey.Localized().IndexOf(searchShortNameOrTemplateId, StringComparison.OrdinalIgnoreCase) >= 0
|| t.NameLocalizationKey.Localized().IndexOf(searchShortNameOrTemplateId, StringComparison.OrdinalIgnoreCase) >= 0)
.ToArray();
}
}
87 changes: 80 additions & 7 deletions ConsoleCommands/Spawn.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
Expand All @@ -10,7 +11,6 @@
using EFT.Trainer.Features;
using EFT.Trainer.Properties;
using JetBrains.Annotations;
using UnityEngine;
using Random = UnityEngine.Random;

#nullable enable
Expand All @@ -33,7 +33,7 @@ public override void Execute(Match match)
return;

var search = matchGroup.Value;
var templates = FindTemplates(search);
var templates = TemplateHelper.FindTemplates(search);

switch (templates.Length)
{
Expand All @@ -54,7 +54,7 @@ public override void Execute(Match match)

internal static void SpawnTemplate(string template, Player player, ConsoleCommand command, Func<ItemTemplate, bool> filter)
{
var result = FindTemplates(template)
var result = TemplateHelper.FindTemplates(template)
.FirstOrDefault(filter);

if (result == null)
Expand All @@ -79,21 +79,19 @@ private static void SpawnTemplate(ItemTemplate template, Player player, ConsoleC
}
else
{
var itemFactory = Singleton<ItemFactory>.Instance;
var itemFactory = Singleton<ItemFactoryClass>.Instance;
var item = itemFactory.CreateItem(MongoID.Generate(), template._id, null);
if (item == null)
{
command.AddConsoleLog(Strings.ErrorFailedToCreateItem.Red());
}
else
{
item.SpawnedInSession = true; // found in raid

_ = new TraderControllerClass(item, item.Id, item.ShortName);
var go = poolManager.CreateLootPrefab(item, ECameraType.Default);

go.SetActive(value: true);
var lootItem = Singleton<GameWorld>.Instance.CreateLootWithRigidbody(go, item, item.ShortName, Singleton<GameWorld>.Instance, randomRotation: false, null, out _);
var lootItem = Singleton<GameWorld>.Instance.CreateLootWithRigidbody(go, item, item.ShortName, randomRotation: false, null, out _, true);

var transform = player.Transform;
var position = transform.position
Expand All @@ -103,11 +101,86 @@ private static void SpawnTemplate(ItemTemplate template, Player player, ConsoleC

lootItem.transform.SetPositionAndRotation(position, transform.rotation);
lootItem.LastOwner = player;

// setup after loot item is created, else we are hitting issues with weapon
SetupItem(itemFactory, item);
}
}
});

return Task.CompletedTask;
});
}

private static void SetupItem(ItemFactoryClass itemFactory, Item item)
{
item.SpawnedInSession = true; // found in raid

if (item.TryGetItemComponent<DogtagComponent>(out var dogtag))
{
dogtag.AccountId = Random.Range(0, int.MaxValue).ToString();
dogtag.ProfileId = Random.Range(0, int.MaxValue).ToString();
dogtag.Nickname = $"Rambo{Random.Range(1, 256)}";
dogtag.Side = Enum.GetValues(typeof(EPlayerSide)).Cast<EPlayerSide>().Random();
dogtag.Level = Random.Range(1, 69);
dogtag.Time = DateTime.Now;
dogtag.Status = "died";
dogtag.KillerAccountId = Random.Range(0, int.MaxValue).ToString();
dogtag.KillerProfileId = Random.Range(0, int.MaxValue).ToString();
dogtag.KillerName = "";
dogtag.WeaponName = "";
}

if (item.TryGetItemComponent<ArmorHolderComponent>(out var armorHolder))
FillSlots(itemFactory, armorHolder.ArmorSlots);

if (item.TryGetItemComponent<RepairableComponent>(out var repairable))
{
repairable.MaxDurability = repairable.TemplateDurability;
repairable.Durability = repairable.MaxDurability;
}

if (item is CompoundItem compound)
FillSlots(itemFactory, compound.AllSlots);

if (item is IAmmoContainer container) // AmmoBox or Magazine
FillStackSlot(itemFactory, container.Cartridges);
}

private static void FillSlots(ItemFactoryClass itemFactory, IEnumerable<Slot> slots)
{
foreach (var slot in slots)
{
if (slot.Items.Any())
continue;

var filter = slot
.Filters.FirstOrDefault()?
.Filter.Random();

if (filter == null)
continue;

var item = itemFactory.CreateItem(MongoID.Generate(), filter, null);
SetupItem(itemFactory, item);

slot.AddWithoutRestrictions(item);
}
}

private static void FillStackSlot(ItemFactoryClass itemFactory, StackSlot slot)
{
var filter = slot
.Filters.FirstOrDefault()?
.Filter.Random();

if (filter == null)
return;

while (slot.Count < slot.MaxCount)
{
var item = itemFactory.CreateItem(MongoID.Generate(), filter, null);
slot.Add(item, false);
}
}
}
40 changes: 40 additions & 0 deletions ConsoleCommands/SpawnHideoutItems.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.Collections.Generic;
using System.Linq;
using EFT.Trainer.Extensions;
using EFT.Trainer.Features;
using EFT.Trainer.Properties;
using HarmonyLib;
using JetBrains.Annotations;

#nullable enable

namespace EFT.Trainer.ConsoleCommands;

[UsedImplicitly]
internal class SpawnHideoutItems : ConsoleCommandWithoutArgument
{
public override string Name => Strings.CommandSpawnHideoutItems;

public override void Execute()
{
var player = GameState.Current?.LocalPlayer;
if (!player.IsValid())
return;

var manager = player.Profile?.WishlistManager;
if (manager == null)
return;

// Find the obfuscated method that returns the computed hidout items
// We need to have the auto-add hideout items enabled in EFT settings
var method = AccessTools
.GetDeclaredMethods(manager.GetType())
.FirstOrDefault(m => m.ReturnType == typeof(IEnumerable<MongoID>));

if (method?.Invoke(manager, []) is not IEnumerable<MongoID> templates)
return;

foreach (var template in templates)
Spawn.SpawnTemplate(template, player, this, i => true);
}
}
10 changes: 3 additions & 7 deletions ConsoleCommands/Template.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Linq;
using System.Text.RegularExpressions;
using Comfort.Common;
using System.Text.RegularExpressions;
using EFT.Trainer.Extensions;
using EFT.Trainer.Features;
using EFT.Trainer.Properties;
using JetBrains.Annotations;

Expand All @@ -20,12 +19,9 @@ public override void Execute(Match match)
if (matchGroup is not { Success: true })
return;

if (!Singleton<ItemFactory>.Instantiated)
return;

var search = matchGroup.Value;

var templates = FindTemplates(search).ToArray();
var templates = TemplateHelper.FindTemplates(search);

foreach (var template in templates)
AddConsoleLog(string.Format(Strings.CommandTemplateEnumerateFormat, template._id, template.ShortNameLocalizationKey.Localized().Green(), template.NameLocalizationKey.Localized()));
Expand Down
2 changes: 1 addition & 1 deletion ConsoleCommands/TrackList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ internal static void ShowTrackList(ConsoleCommand command, Features.LootItems lo
command.AddConsoleLog(Strings.CommandTrackListUpdated);

foreach (var templateId in lootItems.Wishlist)
command.AddConsoleLog(string.Format(Strings.CommandTrackListWishListEnumerateFormat, templateId.LocalizedShortName()));
command.AddConsoleLog(string.Format(Strings.CommandTrackListWishListEnumerateFormat, ((MongoID)templateId).LocalizedShortName()));

foreach (var item in lootItems.TrackedNames)
{
Expand Down
4 changes: 2 additions & 2 deletions Extensions/ItemExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public static bool IsFiltered(this Item item)
if (ItemViewFactory.IsSecureContainer(item))
return true;

if (item.CurrentAddress?.Container is { ParentItem.TemplateId: KnownTemplateIds.BossContainer })
if (item.CurrentAddress?.Container?.ParentItem?.TemplateId.ToString() == KnownTemplateIds.BossContainer)
return true;

return item.TemplateId switch
return item.TemplateId.ToString() switch
{
KnownTemplateIds.DefaultInventory or KnownTemplateIds.Pockets => true,
_ => false
Expand Down
2 changes: 1 addition & 1 deletion Features/Aimbot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ protected static bool CreateShotPrefix(object ammo, Vector3 origin, ref Vector3
}

[UsedImplicitly]
protected static bool ApplyShotPrefix(DamageInfo damageInfo, EBodyPart bodyPartType, EBodyPartColliderType colliderType, EArmorPlateCollider armorPlateCollider, object shotId, Player? __instance)
protected static bool ApplyShotPrefix(DamageInfoStruct damageInfo, EBodyPart bodyPartType, EBodyPartColliderType colliderType, EArmorPlateCollider armorPlateCollider, object shotId, Player? __instance)
{
var feature = FeatureFactory.GetFeature<Aimbot>();
if (feature == null || !feature.SilentAim || feature._silentAimTarget == null)
Expand Down
31 changes: 31 additions & 0 deletions Features/AirDrop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Linq;
using Comfort.Common;
using EFT.InventoryLogic;
using EFT.Trainer.Properties;
using JetBrains.Annotations;
using UnityEngine;

#nullable enable

namespace EFT.Trainer.Features;

[UsedImplicitly]
internal class AirDrop : TriggerFeature
{
public override string Name => Strings.FeatureAirDropName;
public override string Description => Strings.FeatureAirDropDescription;

public override KeyCode Key { get; set; } = KeyCode.None;

protected override void UpdateOnceWhenTriggered()
{
var player = GameState.Current?.LocalPlayer;
if (player == null)
return;

if (TemplateHelper.FindTemplates(KnownTemplateIds.RedSignalFlare).FirstOrDefault() is not AmmoTemplate template)
return;

player.HandleFlareSuccessEvent(player.Transform.position, template);
}
}
6 changes: 3 additions & 3 deletions Features/Ammunition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ private static void ShootPostfix(object shot)
var magazine = weapon.GetCurrentMagazine();
if (magazine != null)
{
if (magazine is CylinderMagazineClass cylinderMagazine)
if (magazine is CylinderMagazineItemClass cylinderMagazine)
{
// Rhino case
foreach (var slot in cylinderMagazine.Camoras)
Expand All @@ -62,11 +62,11 @@ private static void ShootPostfix(object shot)

private static Item CreateAmmo(Item ammo)
{
var instantiated = Singleton<ItemFactory>.Instantiated;
var instantiated = Singleton<ItemFactoryClass>.Instantiated;
if (!instantiated)
return ammo;

var instance = Singleton<ItemFactory>.Instance;
var instance = Singleton<ItemFactoryClass>.Instance;
var itemId = Guid.NewGuid().ToString("N").Substring(0, 24);
return instance.CreateItem(itemId, ammo.TemplateId, null) ?? ammo;
}
Expand Down
4 changes: 4 additions & 0 deletions Features/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ protected override void Update()
if (!PreloaderUI.Instantiated)
return;

#if DEBUG
ConsoleScreen.IAmDevShowMeLogs = true;
#endif

RegisterPropertyDisplays();
RegisterCommands();
}
Expand Down
20 changes: 10 additions & 10 deletions Features/Examine.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using EFT.InventoryLogic;
using EFT.Trainer.ConsoleCommands;
using EFT.Trainer.Properties;
using JetBrains.Annotations;
using static EFT.Player;

#nullable enable

Expand All @@ -22,32 +24,30 @@ protected static bool ExaminedPrefix(ref bool __result)
return true; // keep using original code, we are not enabled

__result = true;
return false; // skip the original code and all other prefix methods
return false; // skip the original code and all other prefix methods
}

#pragma warning disable IDE0060
[UsedImplicitly]
protected static bool GetSearchStatePrefix(SearchableItemClass __instance)
protected static bool SinglePlayerInventoryControllerConstructorPrefix(Player player, Profile profile, bool isBot, ref bool examined)
{
var feature = FeatureFactory.GetFeature<Examine>();
if (feature == null || !feature.Enabled)
return true; // keep using original code, we are not enabled

var player = GameState.Current?.LocalPlayer;
if (player == null)
return true;

__instance.UncoverAll(player.ProfileId);
// this will make the game use the passthrough type implementing IPlayerSearchController, ISearchController with all items known and searched
examined = true;
return true;
}

#pragma warning restore IDE0060

protected override void UpdateWhenEnabled()
{
HarmonyPatchOnce(harmony =>
{
HarmonyPrefix(harmony, typeof(Profile), nameof(Profile.Examined), nameof(ExaminedPrefix), [typeof(string)]);
HarmonyPrefix(harmony, typeof(Profile), nameof(Profile.Examined), nameof(ExaminedPrefix), [typeof(MongoID)]);
HarmonyPrefix(harmony, typeof(Profile), nameof(Profile.Examined), nameof(ExaminedPrefix), [typeof(Item)]);
HarmonyPrefix(harmony, typeof(SearchableItemClass), nameof(SearchableItemClass.GetSearchState), nameof(GetSearchStatePrefix));
HarmonyConstructorPrefix(harmony, typeof(SinglePlayerInventoryController), nameof(SinglePlayerInventoryControllerConstructorPrefix), [typeof(Player), typeof(Profile), typeof(bool), typeof(bool)]);
});
}
}
Loading