partially implemented GiveSptCommand
This commit is contained in:
+230
-7
@@ -1,13 +1,42 @@
|
||||
using SptCommon.Annotations;
|
||||
using System.Text.RegularExpressions;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Eft.Dialog;
|
||||
using Core.Models.Eft.Profile;
|
||||
using Core.Models.Enums;
|
||||
using Core.Models.Utils;
|
||||
using Core.Services;
|
||||
using Core.Utils;
|
||||
using Core.Utils.Cloners;
|
||||
using SptCommon.Annotations;
|
||||
|
||||
namespace Core.Helpers.Dialog.Commando.SptCommands.GiveCommand;
|
||||
namespace Core.Helpers.Dialogue.Commando.SptCommands.GiveCommand;
|
||||
|
||||
[Injectable]
|
||||
public class GiveSptCommand
|
||||
public class GiveSptCommand(
|
||||
ISptLogger<GiveSptCommand> _logger,
|
||||
HashUtil _hashUtil,
|
||||
DatabaseService _databaseService,
|
||||
ItemHelper _itemHelper,
|
||||
PresetHelper _presetHelper,
|
||||
ItemFilterService _itemFilterService,
|
||||
MailSendService _mailSendService,
|
||||
LocaleService _localeService,
|
||||
ICloner _cloner
|
||||
|
||||
)
|
||||
{
|
||||
protected Dictionary<string, SavedCommand> _savedCommand = new();
|
||||
//private const Regex _commandRegex = new Regex(@"/^spt give(((([a - z]{ 2,5}) )?")(.+)"|\w+) )?([0 - 9]+)$/";
|
||||
private const double _acceptableConfidence = 0.9d;
|
||||
|
||||
// Exception for flares
|
||||
protected readonly HashSet<string> _excludedPresetItems =
|
||||
[
|
||||
ItemTpl.FLARE_RSP30_REACTIVE_SIGNAL_CARTRIDGE_RED,
|
||||
ItemTpl.FLARE_RSP30_REACTIVE_SIGNAL_CARTRIDGE_GREEN,
|
||||
ItemTpl.FLARE_RSP30_REACTIVE_SIGNAL_CARTRIDGE_YELLOW
|
||||
];
|
||||
|
||||
public string GetCommand()
|
||||
{
|
||||
return "give";
|
||||
@@ -15,14 +44,198 @@ public class GiveSptCommand
|
||||
|
||||
public string GetCommandHelp()
|
||||
{
|
||||
return "spt give\n========\nSends items to the player through the message system.\n\n\tspt give [template ID] [quantity]\n\t\tEx: " +
|
||||
"spt give 544fb25a4bdc2dfb738b4567 2\n\n\tspt give [\"item name\"] [quantity]\n\t\tEx: spt give \"pack of sugar\" 10\n\n\tspt " +
|
||||
"give [locale] [\"item name\"] [quantity]\n\t\tEx: spt give fr \"figurine de chat\" 3";
|
||||
return
|
||||
"spt give\n========\nSends items to the player through the message system.\n\n\tspt give [template ID] [quantity]\n\t\tEx: " +
|
||||
"spt give 544fb25a4bdc2dfb738b4567 2\n\n\tspt give [\"item name\"] [quantity]\n\t\tEx: spt give \"pack of sugar\" 10\n\n\tspt " +
|
||||
"give [locale] [\"item name\"] [quantity]\n\t\tEx: spt give fr \"figurine de chat\" 3";
|
||||
}
|
||||
|
||||
public string PerformAction(UserDialogInfo commandHandler, string sessionId, SendMessageRequest request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/**
|
||||
|
||||
if (!_commandRegex.IsMatch(request.Text)) {
|
||||
_mailSendService.SendUserMessageToPlayer(
|
||||
sessionId,
|
||||
commandHandler,
|
||||
"Invalid use of give command. Use 'help' for more information.");
|
||||
return request.DialogId;
|
||||
}
|
||||
|
||||
var result = _commandRegex.Match(request.Text);
|
||||
|
||||
string item;
|
||||
int quantity;
|
||||
bool isItemName;
|
||||
string? locale = null;
|
||||
Dictionary<string, string>? localizedGlobal = null;
|
||||
|
||||
// This is a reply to a give request previously made pending a reply
|
||||
if (result.Groups[1].Value == null) {
|
||||
if (!_savedCommand.ContainsKey(sessionId)) {
|
||||
_mailSendService.SendUserMessageToPlayer(
|
||||
sessionId,
|
||||
commandHandler,
|
||||
"Invalid use of give command. Use 'help' for more information."
|
||||
);
|
||||
return request.DialogId;
|
||||
}
|
||||
_savedCommand.TryGetValue(sessionId, out var savedCommand);
|
||||
var locationSixValue = +int.Parse( result.Groups[6].Value);
|
||||
if (locationSixValue > savedCommand.PotentialItemNames.Count) {
|
||||
_mailSendService.SendUserMessageToPlayer(
|
||||
sessionId,
|
||||
commandHandler,
|
||||
"Invalid selection. Outside of bounds! Use 'help' for more information.");
|
||||
return request.DialogId;
|
||||
}
|
||||
item = savedCommand.PotentialItemNames[locationSixValue - 1];
|
||||
quantity = savedCommand.Quantity;
|
||||
locale = savedCommand.Locale;
|
||||
isItemName = true;
|
||||
_savedCommand.Remove(sessionId);
|
||||
} else {
|
||||
// A new give request was entered, we need to ignore the old saved command
|
||||
if (_savedCommand.ContainsKey(sessionId)) {
|
||||
_savedCommand.Remove(sessionId);
|
||||
}
|
||||
isItemName = result.Groups[5].Value != null;
|
||||
item = result.Groups[5].Value is not null ? result.Groups[5].Value : result.Groups[2].Value;
|
||||
quantity = +int.Parse(result.Groups[6].Value);
|
||||
if (quantity <= 0) {
|
||||
_mailSendService.SendUserMessageToPlayer(
|
||||
sessionId,
|
||||
commandHandler,
|
||||
"Invalid quantity! Must be 1 or higher. Use 'help' for more information.");
|
||||
return request.DialogId;
|
||||
}
|
||||
|
||||
if (isItemName) {
|
||||
try {
|
||||
locale = result.Groups[4] ?? _localeService.GetDesiredGameLocale() ?? "en";
|
||||
} catch (Exception ex) {
|
||||
_mailSendService.SendUserMessageToPlayer(
|
||||
sessionId,
|
||||
commandHandler,
|
||||
$"An error occurred while trying to use localized text. Locale will be defaulted to 'en'. {ex.Message}");
|
||||
|
||||
_logger.Warning(ex.Message);
|
||||
locale = "en";
|
||||
}
|
||||
|
||||
localizedGlobal = GetGlobalsLocale(locale);
|
||||
|
||||
var closestItemsMatchedByName = _itemHelper
|
||||
.GetItems()
|
||||
.Where((i) => IsItemAllowed(i))
|
||||
.Select((i) => localizedGlobal[$"{i?.Id} Name"]?.ToLower() ?? i.Properties.Name)
|
||||
.Where((i) => !string.IsNullOrEmpty(i))
|
||||
.Select((i) => ({ Match = StringSimilarity(item.ToLower(), i.ToLower())ItemName = i }))
|
||||
.Sort((a1, a2) => a2.match - a1.match);
|
||||
|
||||
if (closestItemsMatchedByName[0].match >= _acceptableConfidence) {
|
||||
item = closestItemsMatchedByName[0].ItemName;
|
||||
} else {
|
||||
var i = 1;
|
||||
var slicedItems = closestItemsMatchedByName.Slice(0, 10);
|
||||
// max 10 item names and map them
|
||||
var itemList = slicedItems
|
||||
.map((match) => $"{i++}. {match.ItemName} (conf: ${(match.match * 100).toFixed(2)})")
|
||||
.Join("\n");
|
||||
_savedCommand.Add(
|
||||
sessionId,
|
||||
new SavedCommand(
|
||||
quantity,
|
||||
slicedItems.map((item) => item.ItemName),
|
||||
locale));
|
||||
_mailSendService.SendUserMessageToPlayer(
|
||||
sessionId,
|
||||
commandHandler,
|
||||
"Could not find exact match. Closest matches are:\n\n${itemList}\n\nUse 'spt give [number]' to select one.");
|
||||
|
||||
return request.DialogId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
localizedGlobal ??= GetGlobalsLocale(locale ?? "en");
|
||||
// If item is an item name, we need to search using that item name and the locale which one we want otherwise
|
||||
// item is just the tplId.
|
||||
var tplId = isItemName
|
||||
? _itemHelper
|
||||
.GetItems()
|
||||
.Where((i) => IsItemAllowed(i))
|
||||
.FirstOrDefault((i) => (localizedGlobal[$"{i?.Id} Name"]?.ToLower() ?? i.Properties.Name) == item).Id
|
||||
: item;
|
||||
|
||||
var checkedItem = _itemHelper.GetItem(tplId);
|
||||
if (!checkedItem.Key) {
|
||||
_mailSendService.SendUserMessageToPlayer(
|
||||
sessionId,
|
||||
commandHandler,
|
||||
"That item could not be found. Please refine your request and try again.");
|
||||
return request.DialogId;
|
||||
}
|
||||
|
||||
List<Item> itemsToSend = [];
|
||||
var preset = _presetHelper.GetDefaultPreset(checkedItem.Value.Id);
|
||||
if (preset is not null && !_excludedPresetItems.Contains(checkedItem.Value.Id)) {
|
||||
for (var i = 0; i < quantity; i++) {
|
||||
var items = _cloner.Clone(preset.Items);
|
||||
items = _itemHelper.ReplaceIDs(items);
|
||||
itemsToSend.AddRange(items);
|
||||
}
|
||||
} else if (_itemHelper.IsOfBaseclass(checkedItem.Value.Id, BaseClasses.AMMO_BOX)) {
|
||||
for (var i = 0; i < quantity; i++) {
|
||||
List<Item> ammoBoxArray = [];
|
||||
ammoBoxArray.Add( new Item{ Id = _hashUtil.Generate(), Template = checkedItem.Value.Id });
|
||||
// DO NOT generate the ammo box cartridges, the mail service does it for us! :)
|
||||
// _itemHelper.addCartridgesToAmmoBox(ammoBoxArray, checkedItem[1]);
|
||||
itemsToSend.AddRange(ammoBoxArray);
|
||||
}
|
||||
} else {
|
||||
if (checkedItem.Value.Properties.StackMaxSize == 1) {
|
||||
for (var i = 0; i < quantity; i++) {
|
||||
itemsToSend.Add( new Item{
|
||||
Id = _hashUtil.Generate(),
|
||||
Template = checkedItem.Value.Id,
|
||||
Upd = _itemHelper.generateUpdForItem(checkedItem.Value) });
|
||||
}
|
||||
} else {
|
||||
var itemToSend = new Item{
|
||||
Id = _hashUtil.Generate(),
|
||||
Template = checkedItem.Value.Id,
|
||||
Upd = _itemHelper.generateUpdForItem(checkedItem.Value),
|
||||
};
|
||||
itemToSend.Upd.StackObjectsCount = quantity;
|
||||
try {
|
||||
itemsToSend.AddRange(_itemHelper.SplitStack(itemToSend));
|
||||
} catch {
|
||||
_mailSendService.SendUserMessageToPlayer(
|
||||
sessionId,
|
||||
commandHandler,
|
||||
"Too many items requested. Please lower the amount and try again.");
|
||||
|
||||
return request.DialogId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flag the items as FiR
|
||||
_itemHelper.SetFoundInRaid(itemsToSend);
|
||||
|
||||
_mailSendService.SendSystemMessageToPlayer(sessionId, "SPT GIVE", itemsToSend);
|
||||
return request.DialogId;
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
protected Dictionary<string, string> GetGlobalsLocale(string desiredLocale)
|
||||
{
|
||||
return _databaseService.GetLocales().Global.TryGetValue(desiredLocale, out var locale)
|
||||
? locale.Value
|
||||
: _databaseService.GetLocales().Global["en"].Value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,6 +245,16 @@ public class GiveSptCommand
|
||||
*/
|
||||
protected bool IsItemAllowed(TemplateItem templateItem)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return templateItem.Type != "Node" &&
|
||||
!_itemHelper.IsQuestItem(templateItem.Id) &&
|
||||
!_itemFilterService.IsItemBlacklisted(templateItem.Id) &&
|
||||
(templateItem.Properties?.Prefab?.Path ?? "") != "" &&
|
||||
!_itemHelper.IsOfBaseclasses(
|
||||
templateItem.Id,
|
||||
[
|
||||
BaseClasses.HIDEOUT_AREA_CONTAINER, BaseClasses.LOOT_CONTAINER,
|
||||
BaseClasses.RANDOM_LOOT_CONTAINER, BaseClasses.MOB_CONTAINER
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user