stock market refactor (#2141)
* stock market refactor * PlayEntity * make client use int * refactor and fix cartridge system * fix * deny sound if it fails * reviews * thank you ss14 --------- Co-authored-by: deltanedas <@deltanedas:kde.org>
This commit is contained in:
parent
36d634bdff
commit
8360e715c2
|
|
@ -36,7 +36,7 @@ public sealed partial class StockTradingUi : UIFragment
|
|||
}
|
||||
}
|
||||
|
||||
private static void SendStockTradingUiMessage(StockTradingUiAction action, int company, float amount, BoundUserInterface userInterface)
|
||||
private static void SendStockTradingUiMessage(StockTradingUiAction action, int company, int amount, BoundUserInterface userInterface)
|
||||
{
|
||||
var newsMessage = new StockTradingUiMessageEvent(action, company, amount);
|
||||
var message = new CartridgeUiMessage(newsMessage);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ public sealed partial class StockTradingUiFragment : BoxContainer
|
|||
private readonly Dictionary<int, CompanyEntry> _companyEntries = new();
|
||||
|
||||
// Event handlers for the parent UI
|
||||
public event Action<int, float>? OnBuyButtonPressed;
|
||||
public event Action<int, float>? OnSellButtonPressed;
|
||||
public event Action<int, int>? OnBuyButtonPressed;
|
||||
public event Action<int, int>? OnSellButtonPressed;
|
||||
|
||||
// Define colors
|
||||
public static readonly Color PositiveColor = Color.FromHex("#00ff00"); // Green
|
||||
|
|
@ -70,8 +70,8 @@ public sealed partial class StockTradingUiFragment : BoxContainer
|
|||
|
||||
public CompanyEntry(int companyIndex,
|
||||
string displayName,
|
||||
Action<int, float>? onBuyPressed,
|
||||
Action<int, float>? onSellPressed)
|
||||
Action<int, int>? onBuyPressed,
|
||||
Action<int, int>? onSellPressed)
|
||||
{
|
||||
Container = new BoxContainer
|
||||
{
|
||||
|
|
@ -216,13 +216,13 @@ public sealed partial class StockTradingUiFragment : BoxContainer
|
|||
// Button click events
|
||||
_buyButton.OnPressed += _ =>
|
||||
{
|
||||
if (float.TryParse(_amountEdit.Text, out var amount) && amount > 0)
|
||||
if (int.TryParse(_amountEdit.Text, out var amount) && amount > 0)
|
||||
onBuyPressed?.Invoke(companyIndex, amount);
|
||||
};
|
||||
|
||||
_sellButton.OnPressed += _ =>
|
||||
{
|
||||
if (float.TryParse(_amountEdit.Text, out var amount) && amount > 0)
|
||||
if (int.TryParse(_amountEdit.Text, out var amount) && amount > 0)
|
||||
onSellPressed?.Invoke(companyIndex, amount);
|
||||
};
|
||||
|
||||
|
|
@ -235,7 +235,7 @@ public sealed partial class StockTradingUiFragment : BoxContainer
|
|||
};
|
||||
}
|
||||
|
||||
public void Update(StockCompanyStruct company, int ownedStocks)
|
||||
public void Update(StockCompany company, int ownedStocks)
|
||||
{
|
||||
_nameLabel.Text = company.LocalizedDisplayName;
|
||||
_priceLabel.Text = $"${company.CurrentPrice:F2}";
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public sealed partial class StationStockMarketComponent : Component
|
|||
/// The list of companies you can invest in
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<StockCompanyStruct> Companies = [];
|
||||
public List<StockCompany> Companies = [];
|
||||
|
||||
/// <summary>
|
||||
/// The list of shares owned by the station
|
||||
|
|
@ -53,19 +53,12 @@ public sealed partial class StationStockMarketComponent : Component
|
|||
[DataField]
|
||||
public List<MarketChange> MarketChanges =
|
||||
[
|
||||
new() { Chance = 0.86f, Range = new Vector2(-0.05f, 0.05f) }, // Minor
|
||||
new() { Chance = 0.10f, Range = new Vector2(-0.3f, 0.2f) }, // Moderate
|
||||
new() { Chance = 0.03f, Range = new Vector2(-0.5f, 1.5f) }, // Major
|
||||
new() { Chance = 0.01f, Range = new Vector2(-0.9f, 4.0f) }, // Catastrophic
|
||||
new(0.86f, new Vector2(-0.05f, 0.05f)), // Minor
|
||||
new(0.10f, new Vector2(-0.3f, 0.2f)), // Moderate
|
||||
new(0.03f, new Vector2(-0.5f, 1.5f)), // Major
|
||||
new(0.01f, new Vector2(-0.9f, 4.0f)), // Catastrophic
|
||||
];
|
||||
}
|
||||
|
||||
[DataDefinition]
|
||||
public sealed partial class MarketChange
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public float Chance;
|
||||
|
||||
[DataField(required: true)]
|
||||
public Vector2 Range;
|
||||
}
|
||||
[DataRecord]
|
||||
public record struct MarketChange(float Chance, Vector2 Range);
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ using Content.Shared.Access.Systems;
|
|||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.CartridgeLoader.Cartridges;
|
||||
using Content.Shared.Database;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
|
|
@ -22,15 +20,14 @@ namespace Content.Server._DV.Cargo.Systems;
|
|||
/// </summary>
|
||||
public sealed class StockMarketSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AccessReaderSystem _accessSystem = default!;
|
||||
[Dependency] private readonly AccessReaderSystem _access = default!;
|
||||
[Dependency] private readonly CargoSystem _cargo = default!;
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly ILogManager _log = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
|
||||
[Dependency] private readonly IdCardSystem _idCard = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
private const float MaxPrice = 262144; // 1/64 of max safe integer
|
||||
|
|
@ -64,38 +61,27 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
if (args is not StockTradingUiMessageEvent message)
|
||||
return;
|
||||
|
||||
var user = args.Actor;
|
||||
var companyIndex = message.CompanyIndex;
|
||||
var amount = (int)message.Amount;
|
||||
var station = ent.Comp.Station;
|
||||
var amount = message.Amount;
|
||||
var loader = GetEntity(args.LoaderUid);
|
||||
var xform = Transform(loader);
|
||||
|
||||
// Ensure station and stock market components are valid
|
||||
if (station == null || !TryComp<StationStockMarketComponent>(station, out var stockMarket))
|
||||
if (ent.Comp.Station is not {} station || !TryComp<StationStockMarketComponent>(station, out var stockMarket))
|
||||
return;
|
||||
|
||||
// Validate company index
|
||||
if (companyIndex < 0 || companyIndex >= stockMarket.Companies.Count)
|
||||
return;
|
||||
|
||||
if (!TryComp<AccessReaderComponent>(ent.Owner, out var access))
|
||||
if (!TryComp<AccessReaderComponent>(ent, out var access))
|
||||
return;
|
||||
|
||||
// Attempt to retrieve ID card from loader
|
||||
IdCardComponent? idCard = null;
|
||||
if (_idCardSystem.TryGetIdCard(loader, out var pdaId))
|
||||
idCard = pdaId;
|
||||
|
||||
// Play deny sound and exit if access is not allowed
|
||||
if (idCard == null || !_accessSystem.IsAllowed(pdaId.Owner, ent.Owner, access))
|
||||
// Attempt to retrieve ID card from loader,
|
||||
// play deny sound and exit if access is not allowed
|
||||
if (!_idCard.TryGetIdCard(loader, out var idCard) || !_access.IsAllowed(idCard, ent.Owner, access))
|
||||
{
|
||||
_audio.PlayEntity(
|
||||
stockMarket.DenySound,
|
||||
Filter.Empty().AddInRange(_transform.GetMapCoordinates(loader, xform), 0.05f),
|
||||
loader,
|
||||
true,
|
||||
AudioParams.Default.WithMaxDistance(0.05f)
|
||||
);
|
||||
_audio.PlayEntity(stockMarket.DenySound, loader, user);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -110,15 +96,15 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
case StockTradingUiAction.Buy:
|
||||
_adminLogger.Add(LogType.Action,
|
||||
LogImpact.Medium,
|
||||
$"{ToPrettyString(loader)} attempting to buy {amount} stocks of {company.LocalizedDisplayName}");
|
||||
success = TryBuyStocks(station.Value, stockMarket, companyIndex, amount);
|
||||
$"{ToPrettyString(user):user} attempting to buy {amount} stocks of {company.LocalizedDisplayName}");
|
||||
success = TryChangeStocks(station, stockMarket, companyIndex, amount, user);
|
||||
break;
|
||||
|
||||
case StockTradingUiAction.Sell:
|
||||
_adminLogger.Add(LogType.Action,
|
||||
LogImpact.Medium,
|
||||
$"{ToPrettyString(loader)} attempting to sell {amount} stocks of {company.LocalizedDisplayName}");
|
||||
success = TrySellStocks(station.Value, stockMarket, companyIndex, amount);
|
||||
$"{ToPrettyString(user):user} attempting to sell {amount} stocks of {company.LocalizedDisplayName}");
|
||||
success = TryChangeStocks(station, stockMarket, companyIndex, -amount, user);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -126,32 +112,29 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
}
|
||||
|
||||
// Play confirmation sound if the transaction was successful
|
||||
if (success)
|
||||
{
|
||||
_audio.PlayEntity(
|
||||
stockMarket.ConfirmSound,
|
||||
Filter.Empty().AddInRange(_transform.GetMapCoordinates(loader, xform), 0.05f),
|
||||
loader,
|
||||
true,
|
||||
AudioParams.Default.WithMaxDistance(0.05f)
|
||||
);
|
||||
}
|
||||
_audio.PlayEntity(success ? stockMarket.ConfirmSound : stockMarket.DenySound, loader, user);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Raise the event to update the UI regardless of outcome
|
||||
var ev = new StockMarketUpdatedEvent(station.Value);
|
||||
RaiseLocalEvent(ev);
|
||||
UpdateStockMarket(station);
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryBuyStocks(
|
||||
private void UpdateStockMarket(EntityUid station)
|
||||
{
|
||||
var ev = new StockMarketUpdatedEvent(station);
|
||||
RaiseLocalEvent(ref ev);
|
||||
}
|
||||
|
||||
private bool TryChangeStocks(
|
||||
EntityUid station,
|
||||
StationStockMarketComponent stockMarket,
|
||||
int companyIndex,
|
||||
int amount)
|
||||
int amount,
|
||||
EntityUid user)
|
||||
{
|
||||
if (amount <= 0 || companyIndex < 0 || companyIndex >= stockMarket.Companies.Count)
|
||||
if (amount == 0 || companyIndex < 0 || companyIndex >= stockMarket.Companies.Count)
|
||||
return false;
|
||||
|
||||
// Check if the station has a bank account
|
||||
|
|
@ -161,58 +144,37 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
var company = stockMarket.Companies[companyIndex];
|
||||
var totalValue = (int)Math.Round(company.CurrentPrice * amount);
|
||||
|
||||
// See if we can afford it
|
||||
if (bank.Balance < totalValue)
|
||||
return false;
|
||||
|
||||
if (!stockMarket.StockOwnership.TryGetValue(companyIndex, out var currentOwned))
|
||||
currentOwned = 0;
|
||||
|
||||
// Update the bank account
|
||||
_cargo.UpdateBankAccount(station, bank, -totalValue);
|
||||
stockMarket.StockOwnership[companyIndex] = currentOwned + amount;
|
||||
if (amount > 0)
|
||||
{
|
||||
// Buying: see if we can afford it
|
||||
if (bank.Balance < totalValue)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Selling: see if we have enough stocks to sell
|
||||
var selling = -amount;
|
||||
if (currentOwned < selling)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Log the transaction
|
||||
_adminLogger.Add(LogType.Action,
|
||||
LogImpact.Medium,
|
||||
$"[StockMarket] Bought {amount} stocks of {company.LocalizedDisplayName} at {company.CurrentPrice:F2} credits each (Total: {totalValue})");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TrySellStocks(
|
||||
EntityUid station,
|
||||
StationStockMarketComponent stockMarket,
|
||||
int companyIndex,
|
||||
int amount)
|
||||
{
|
||||
if (amount <= 0 || companyIndex < 0 || companyIndex >= stockMarket.Companies.Count)
|
||||
return false;
|
||||
|
||||
// Check if the station has a bank account
|
||||
if (!TryComp<StationBankAccountComponent>(station, out var bank))
|
||||
return false;
|
||||
|
||||
if (!stockMarket.StockOwnership.TryGetValue(companyIndex, out var currentOwned) || currentOwned < amount)
|
||||
return false;
|
||||
|
||||
var company = stockMarket.Companies[companyIndex];
|
||||
var totalValue = (int)Math.Round(company.CurrentPrice * amount);
|
||||
|
||||
// Update stock ownership
|
||||
var newAmount = currentOwned - amount;
|
||||
var newAmount = currentOwned + amount;
|
||||
if (newAmount > 0)
|
||||
stockMarket.StockOwnership[companyIndex] = newAmount;
|
||||
else
|
||||
stockMarket.StockOwnership.Remove(companyIndex);
|
||||
|
||||
// Update the bank account
|
||||
_cargo.UpdateBankAccount(station, bank, totalValue);
|
||||
// Update the bank account (take away for buying and give for selling)
|
||||
_cargo.UpdateBankAccount(station, bank, -totalValue);
|
||||
|
||||
// Log the transaction
|
||||
var verb = amount > 0 ? "bought" : "sold";
|
||||
_adminLogger.Add(LogType.Action,
|
||||
LogImpact.Medium,
|
||||
$"[StockMarket] Sold {amount} stocks of {company.LocalizedDisplayName} at {company.CurrentPrice:F2} credits each (Total: {totalValue})");
|
||||
$"[StockMarket] {ToPrettyString(user):user} {verb} {Math.Abs(amount)} stocks of {company.LocalizedDisplayName} at {company.CurrentPrice:F2} credits each (Total: {totalValue})");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -225,7 +187,7 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
var changeType = DetermineMarketChange(stockMarket.MarketChanges);
|
||||
var multiplier = CalculatePriceMultiplier(changeType);
|
||||
|
||||
UpdatePriceHistory(company);
|
||||
UpdatePriceHistory(ref company);
|
||||
|
||||
// Update price with multiplier
|
||||
var oldPrice = company.CurrentPrice;
|
||||
|
|
@ -243,8 +205,7 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
var percentChange = (company.CurrentPrice - oldPrice) / oldPrice * 100;
|
||||
|
||||
// Raise the event
|
||||
var ev = new StockMarketUpdatedEvent(station);
|
||||
RaiseLocalEvent(ev);
|
||||
UpdateStockMarket(station);
|
||||
|
||||
// Log it
|
||||
_adminLogger.Add(LogType.Action,
|
||||
|
|
@ -273,13 +234,12 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
return false;
|
||||
|
||||
var company = stockMarket.Companies[companyIndex];
|
||||
UpdatePriceHistory(company);
|
||||
UpdatePriceHistory(ref company);
|
||||
|
||||
company.CurrentPrice = MathF.Max(newPrice, company.BasePrice * 0.1f);
|
||||
stockMarket.Companies[companyIndex] = company;
|
||||
|
||||
var ev = new StockMarketUpdatedEvent(station);
|
||||
RaiseLocalEvent(ev);
|
||||
UpdateStockMarket(station);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -293,7 +253,7 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
string displayName)
|
||||
{
|
||||
// Create a new company struct with the specified parameters
|
||||
var company = new StockCompanyStruct
|
||||
var company = new StockCompany
|
||||
{
|
||||
LocalizedDisplayName = displayName, // Assume there's no Loc for it
|
||||
BasePrice = basePrice,
|
||||
|
|
@ -301,36 +261,33 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
PriceHistory = [],
|
||||
};
|
||||
|
||||
UpdatePriceHistory(ref company);
|
||||
stockMarket.Companies.Add(company);
|
||||
UpdatePriceHistory(company);
|
||||
|
||||
var ev = new StockMarketUpdatedEvent(station);
|
||||
RaiseLocalEvent(ev);
|
||||
UpdateStockMarket(station);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to add a new company to the station using the StockCompanyStruct
|
||||
/// Attempts to add a new company to the station using the StockCompany
|
||||
/// </summary>
|
||||
/// <returns>False if the company already exists, true otherwise</returns>
|
||||
public bool TryAddCompany(EntityUid station,
|
||||
StationStockMarketComponent stockMarket,
|
||||
StockCompanyStruct company)
|
||||
public bool TryAddCompany(Entity<StationStockMarketComponent> station,
|
||||
StockCompany company)
|
||||
{
|
||||
// Add the new company to the dictionary
|
||||
stockMarket.Companies.Add(company);
|
||||
|
||||
// Make sure it has a price history
|
||||
UpdatePriceHistory(company);
|
||||
UpdatePriceHistory(ref company);
|
||||
|
||||
var ev = new StockMarketUpdatedEvent(station);
|
||||
RaiseLocalEvent(ev);
|
||||
// Add the new company to the dictionary
|
||||
station.Comp.Companies.Add(company);
|
||||
|
||||
UpdateStockMarket(station);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void UpdatePriceHistory(StockCompanyStruct company)
|
||||
private static void UpdatePriceHistory(ref StockCompany company)
|
||||
{
|
||||
// Create if null
|
||||
company.PriceHistory ??= [];
|
||||
|
|
@ -379,7 +336,9 @@ public sealed class StockMarketSystem : EntitySystem
|
|||
return Math.Clamp(result, change.Range.X, change.Range.Y);
|
||||
}
|
||||
}
|
||||
public sealed class StockMarketUpdatedEvent(EntityUid station) : EntityEventArgs
|
||||
{
|
||||
public EntityUid Station = station;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Broadcast whenever a stock market is updated.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct StockMarketUpdatedEvent(EntityUid Station);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ public sealed class StockTradingCartridgeSystem : EntitySystem
|
|||
|
||||
private void OnBalanceUpdated(Entity<StockTradingCartridgeComponent> ent, ref BankBalanceUpdatedEvent args)
|
||||
{
|
||||
UpdateAllCartridges(args.Station);
|
||||
UpdateAllCartridges(args.Station);
|
||||
}
|
||||
|
||||
private void OnUiReady(Entity<StockTradingCartridgeComponent> ent, ref CartridgeUiReadyEvent args)
|
||||
|
|
@ -35,7 +35,7 @@ public sealed class StockTradingCartridgeSystem : EntitySystem
|
|||
UpdateUI(ent, args.Loader);
|
||||
}
|
||||
|
||||
private void OnStockMarketUpdated(StockMarketUpdatedEvent args)
|
||||
private void OnStockMarketUpdated(ref StockMarketUpdatedEvent args)
|
||||
{
|
||||
UpdateAllCartridges(args.Station);
|
||||
}
|
||||
|
|
@ -81,17 +81,9 @@ public sealed class StockTradingCartridgeSystem : EntitySystem
|
|||
!TryComp<StationBankAccountComponent>(ent.Comp.Station, out var bankAccount))
|
||||
return;
|
||||
|
||||
// Convert company data to UI state format
|
||||
var entries = stockMarket.Companies.Select(company => new StockCompanyStruct(
|
||||
displayName: company.LocalizedDisplayName,
|
||||
currentPrice: company.CurrentPrice,
|
||||
basePrice: company.BasePrice,
|
||||
priceHistory: company.PriceHistory))
|
||||
.ToList();
|
||||
|
||||
// Send the UI state with balance and owned stocks
|
||||
var state = new StockTradingUiState(
|
||||
entries: entries,
|
||||
entries: stockMarket.Companies,
|
||||
ownedStocks: stockMarket.StockOwnership,
|
||||
balance: bankAccount.Balance
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ using Robust.Shared.Serialization;
|
|||
namespace Content.Shared.CartridgeLoader.Cartridges;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class StockTradingUiMessageEvent(StockTradingUiAction action, int companyIndex, float amount)
|
||||
public sealed class StockTradingUiMessageEvent(StockTradingUiAction action, int companyIndex, int amount)
|
||||
: CartridgeMessageEvent
|
||||
{
|
||||
public readonly StockTradingUiAction Action = action;
|
||||
public readonly int CompanyIndex = companyIndex;
|
||||
public readonly float Amount = amount;
|
||||
public readonly int Amount = amount;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
|
|
|||
|
|
@ -4,19 +4,19 @@ namespace Content.Shared.CartridgeLoader.Cartridges;
|
|||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class StockTradingUiState(
|
||||
List<StockCompanyStruct> entries,
|
||||
List<StockCompany> entries,
|
||||
Dictionary<int, int> ownedStocks,
|
||||
float balance)
|
||||
: BoundUserInterfaceState
|
||||
{
|
||||
public readonly List<StockCompanyStruct> Entries = entries;
|
||||
public readonly List<StockCompany> Entries = entries;
|
||||
public readonly Dictionary<int, int> OwnedStocks = ownedStocks;
|
||||
public readonly float Balance = balance;
|
||||
}
|
||||
|
||||
// No structure, zero fucks given
|
||||
[DataDefinition, Serializable]
|
||||
public partial struct StockCompanyStruct
|
||||
public partial struct StockCompany
|
||||
{
|
||||
/// <summary>
|
||||
/// The displayed name of the company shown in the UI.
|
||||
|
|
@ -55,7 +55,7 @@ public partial struct StockCompanyStruct
|
|||
[DataField]
|
||||
public List<float>? PriceHistory;
|
||||
|
||||
public StockCompanyStruct(string displayName, float currentPrice, float basePrice, List<float>? priceHistory)
|
||||
public StockCompany(string displayName, float currentPrice, float basePrice, List<float>? priceHistory)
|
||||
{
|
||||
DisplayName = displayName;
|
||||
_displayName = null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue