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.2.32757 #576

Closed
wants to merge 44 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 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
1c6773f
Fix translation
sailro Oct 24, 2024
9f80c94
Enable IAmDevShowMeLogs
sailro Oct 24, 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
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();
}
}
68 changes: 61 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,67 @@ 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);
}

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);
}
}
}
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);
}
}
5 changes: 3 additions & 2 deletions ConsoleCommands/Template.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Text.RegularExpressions;
using Comfort.Common;
using EFT.Trainer.Extensions;
using EFT.Trainer.Features;
using EFT.Trainer.Properties;
using JetBrains.Annotations;

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

if (!Singleton<ItemFactory>.Instantiated)
if (!Singleton<ItemFactoryClass>.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
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);
}
}
4 changes: 2 additions & 2 deletions Features/Ammunition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
17 changes: 8 additions & 9 deletions Features/Examine.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using EFT.InventoryLogic;
using EFT.Trainer.Properties;
using JetBrains.Annotations;
using static EFT.Player;

#nullable enable

Expand All @@ -22,32 +23,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, 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(Item)]);
HarmonyPrefix(harmony, typeof(SearchableItemClass), nameof(SearchableItemClass.GetSearchState), nameof(GetSearchStatePrefix));
HarmonyConstructorPrefix(harmony, typeof(SinglePlayerInventoryController), nameof(SinglePlayerInventoryControllerConstructorPrefix), [typeof(Player), typeof(Profile), typeof(bool)]);
});
}
}
Loading