baseline: OpenMU upstream b5a0961 (fresh source)

This commit is contained in:
Acentech Dev
2026-07-14 19:00:35 +03:00
parent 450402e47d
commit 36fc125d5c
11968 changed files with 748705 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
// <copyright file="ClearInventoryChatCommandPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameLogic.PlugIns.ChatCommands;
using System.ComponentModel.DataAnnotations;
using System.Runtime.InteropServices;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// A chat command plugin which clears a character's inventory.
/// </summary>
[Guid("1E895A6F-3056-4A78-BA64-96E24363B8BC")]
[PlugIn]
[Display(Name = nameof(PlugInResources.ClearInventoryChatCommandPlugIn_Name), Description = nameof(PlugInResources.ClearInventoryChatCommandPlugIn_Description), ResourceType = typeof(PlugInResources))]
[ChatCommandHelp(Command, null, MinimumStatus)]
public class ClearInventoryChatCommandPlugIn : ChatCommandPlugInBase<ClearInventoryChatCommandPlugIn.Arguments>, ISupportCustomConfiguration<ClearInventoryChatCommandPlugIn.ClearInventoryConfiguration>, ISupportDefaultCustomConfiguration, IDisabledByDefault
{
private const string Command = "/clearinv";
private const CharacterStatus MinimumStatus = CharacterStatus.Normal;
private const int ConfirmationTimeoutSeconds = 10;
private readonly Dictionary<Guid, DateTime> pendingConfirmations = new();
/// <summary>
/// Gets or sets the configuration.
/// </summary>
public ClearInventoryConfiguration? Configuration { get; set; }
/// <inheritdoc />
public override string Key => Command;
/// <inheritdoc />
public override CharacterStatus MinCharacterStatusRequirement => MinimumStatus;
/// <inheritdoc />
public object CreateDefaultConfig() => new ClearInventoryConfiguration();
/// <inheritdoc />
protected override async ValueTask DoHandleCommandAsync(Player player, Arguments arguments)
{
if (player.SelectedCharacter is not { } selectedCharacter)
{
return;
}
var configuration = this.Configuration ??= (ClearInventoryConfiguration)this.CreateDefaultConfig();
bool removeMoney = configuration.MoneyCost > 0;
var targetPlayer = player;
bool isGameMaster = selectedCharacter?.CharacterStatus >= CharacterStatus.GameMaster;
if (isGameMaster)
{
removeMoney = false;
if (arguments?.CharacterName is { } characterName)
{
targetPlayer = player.GameContext.GetPlayerByCharacterName(characterName);
if (targetPlayer?.SelectedCharacter is null ||
!targetPlayer.SelectedCharacter.Name.Equals(characterName, StringComparison.OrdinalIgnoreCase))
{
await player.ShowLocalizedBlueMessageAsync(nameof(PlayerMessage.CharacterNotFound), characterName).ConfigureAwait(false);
return;
}
}
}
if (targetPlayer.Inventory is null)
{
return;
}
if (!isGameMaster && configuration.RequireConfirmation)
{
var playerId = selectedCharacter!.Id;
if (!this.pendingConfirmations.TryGetValue(playerId, out var confirmationTime) || (DateTime.UtcNow - confirmationTime).TotalSeconds > ConfirmationTimeoutSeconds)
{
this.pendingConfirmations[playerId] = DateTime.UtcNow;
if (configuration.ConfirmationMessage.GetTranslation(player.Culture) is { Length: > 0 } message)
{
await player.ShowBlueMessageAsync(message).ConfigureAwait(false);
}
return;
}
this.pendingConfirmations.Remove(playerId);
}
var itemsToRemove = targetPlayer.Inventory.Items
.Where(item => item is not null &&
(item.ItemSlot < InventoryConstants.FirstEquippableItemSlotIndex ||
item.ItemSlot > InventoryConstants.LastEquippableItemSlotIndex))
.ToList();
if (itemsToRemove.Count == 0)
{
return;
}
if (removeMoney && !player.TryRemoveMoney(configuration.MoneyCost))
{
if (configuration.NotEnoughMoneyMessage.GetTranslation(player.Culture) is { Length: > 0 } notEnoughMoneyMessage)
{
await player.ShowBlueMessageAsync(notEnoughMoneyMessage).ConfigureAwait(false);
}
return;
}
foreach (var item in itemsToRemove)
{
await targetPlayer.DestroyInventoryItemAsync(item).ConfigureAwait(false);
}
if (configuration.InventoryClearedMessage.GetTranslation(player.Culture) is { Length: > 0 } clearedMessage)
{
await player.ShowBlueMessageAsync(clearedMessage).ConfigureAwait(false);
}
}
/// <summary>
/// Arguments for the Clear Inventory chat command.
/// </summary>
public class Arguments : ArgumentsBase
{
/// <summary>
/// Gets or sets the character name to clear inventory for (GM only).
/// </summary>
public string? CharacterName { get; set; }
}
/// <summary>
/// The configuration of a <see cref="ClearInventoryChatCommandPlugIn"/>.
/// </summary>
public class ClearInventoryConfiguration
{
/// <summary>
/// Gets or sets the character name to clear inventory for (GM only).
/// </summary>
[Display(ResourceType = typeof(PlugInResources), Name = nameof(PlugInResources.ClearInventoryConfiguration_MoneyCost_Name), Description = nameof(PlugInResources.ClearInventoryConfiguration_MoneyCost_Description))]
public int MoneyCost { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the player needs to run the command again within 10 seconds to confirm the inventory clearing (excluding GM).
/// </summary>
[Display(ResourceType = typeof(PlugInResources), Name = nameof(PlugInResources.ClearInventoryConfiguration_RequireConfirmation_Name), Description = nameof(PlugInResources.ClearInventoryConfiguration_RequireConfirmation_Description))]
public bool RequireConfirmation { get; set; } = true;
/// <summary>
/// Gets or sets the message to show the confirmation message.
/// </summary>
[Display(ResourceType = typeof(PlugInResources), Name = nameof(PlugInResources.ClearInventoryConfiguration_ConfirmationMessage_Name), Description = nameof(PlugInResources.ClearInventoryConfiguration_ConfirmationMessage_Description))]
public LocalizedString ConfirmationMessage { get; set; } = "Confirmation: run again within 10 seconds to confirm inventory clearing";
/// <summary>
/// Gets or sets the message to show when the player does not have enough money to run the command.
/// </summary>
[Display(ResourceType = typeof(PlugInResources), Name = nameof(PlugInResources.ClearInventoryConfiguration_NotEnoughMoneyMessage_Name), Description = nameof(PlugInResources.ClearInventoryConfiguration_NotEnoughMoneyMessage_Description))]
public LocalizedString NotEnoughMoneyMessage { get; set; } = "Not enough money to run command";
/// <summary>
/// Gets or sets the message to show when the inventory is cleared.
/// </summary>
[Display(ResourceType = typeof(PlugInResources), Name = nameof(PlugInResources.ClearInventoryConfiguration_InventoryClearedMessage_Name), Description = nameof(PlugInResources.ClearInventoryConfiguration_InventoryClearedMessage_Description))]
public LocalizedString InventoryClearedMessage { get; set; } = "Inventory cleared";
}
}