Danro-Jump/Assets/Scripts/Runtime/Prizes/Qr/QrPrizeTextSettings.cs
Danil Iarosh d39d160d92 Implement physical prize dispensing, service stats, and QR screen timeout
- Добавлен асинхронный процесс аппаратной выдачи физических призов (хоппер и витрина) в GameplayHudController.
- Реализована блокировка выдачи по 10-секундному таймауту датчика хоппера с гарантированной отправкой команды отключения двигателя '300'.
- Реализован автоматический таймаут неактивности на экране QR-кода с последующим переходом в главное меню.
- Расширен сервис статистики PrizeSessionStateService новыми долгосрочными счетчиками (сыгранные игры, очки, монеты, сбои связи COM, физ. выдачи и ошибки).
- Обновлен построитель сводки статистики в меню настроек для отображения новых счетчиков и списка последних 5 сессий.
- Написаны EditMode тесты для проверки инкремента счетчиков и запуска выдачи призов.
2026-06-23 10:36:13 +03:00

145 lines
4.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DanroJump.Settings;
namespace DanroJump.Prizes.Qr
{
/// <summary>
/// Читает короткие тексты QR-призов по рангам из сервисных настроек.
/// </summary>
public static class QrPrizeTextSettings
{
public const int MaxPrizeTextLength = 12;
private static readonly QrPrizeTier[] PreferredTiers =
{
QrPrizeTier.Gold,
QrPrizeTier.Silver,
QrPrizeTier.Bronze
};
public static string GetSettingKey(QrPrizeTier tier)
{
return tier switch
{
QrPrizeTier.Bronze => ServiceSettingsKeys.QrPrizeTextBronze,
QrPrizeTier.Silver => ServiceSettingsKeys.QrPrizeTextSilver,
QrPrizeTier.Gold => ServiceSettingsKeys.QrPrizeTextGold,
_ => string.Empty
};
}
public static string GetDisplayName(QrPrizeTier tier)
{
return tier switch
{
QrPrizeTier.Bronze => "Бронзовый",
QrPrizeTier.Silver => "Серебряный",
QrPrizeTier.Gold => "Золотой",
_ => "Не задан"
};
}
public static string GetPrizeText(IReadOnlyServiceSettings settings, QrPrizeTier tier)
{
var key = GetSettingKey(tier);
return string.IsNullOrWhiteSpace(key)
? string.Empty
: NormalizePrizeText(settings?.GetString(key));
}
public static string GetPreferredPrizeText(IReadOnlyServiceSettings settings)
{
foreach (var tier in PreferredTiers)
{
var text = GetPrizeText(settings, tier);
if (!string.IsNullOrWhiteSpace(text))
{
return text;
}
}
return string.Empty;
}
public static string GetPrizeTextForResult(IReadOnlyServiceSettings settings, PrizeFlowResult result, out QrPrizeTier tier)
{
tier = ResolveTier(settings, result);
if (tier != QrPrizeTier.None)
{
var tierText = GetPrizeText(settings, tier);
if (!string.IsNullOrWhiteSpace(tierText))
{
return tierText;
}
}
return GetPreferredPrizeText(settings);
}
public static QrPrizeTier ResolveTier(IReadOnlyServiceSettings settings, PrizeFlowResult result)
{
if (result.RewardKind != PrizeRewardKind.QRCode)
{
return QrPrizeTier.None;
}
return ResolveTier(settings, result.Score);
}
public static QrPrizeTier ResolveTier(IReadOnlyServiceSettings settings, int score)
{
var sanitizedScore = score < 0 ? 0 : score;
var levels = PrizeLevelTable.FromJson(settings?.GetString(ServiceSettingsKeys.PrizeLevels));
var qrLevelIndex = -1;
for (var index = 0; index < levels.Levels.Count; index++)
{
var level = levels.Levels[index];
if (level.RewardKind != PrizeRewardKind.QRCode)
{
continue;
}
if (level.Score > sanitizedScore)
{
break;
}
qrLevelIndex++;
}
if (qrLevelIndex >= 0)
{
return qrLevelIndex switch
{
0 => QrPrizeTier.Bronze,
1 => QrPrizeTier.Silver,
_ => QrPrizeTier.Gold
};
}
foreach (var tier in PreferredTiers)
{
if (!string.IsNullOrWhiteSpace(GetPrizeText(settings, tier)))
{
return tier;
}
}
return QrPrizeTier.None;
}
public static string NormalizePrizeText(string text)
{
if (string.IsNullOrWhiteSpace(text))
{
return string.Empty;
}
var normalized = text.Trim();
return normalized.Length <= MaxPrizeTextLength
? normalized
: normalized.Substring(0, MaxPrizeTextLength);
}
}
}