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

58 lines
2.0 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-билет для Telegram-связи с владельцем автомата.
/// </summary>
public sealed class PrizeQrService : IPrizeQrService
{
private readonly IReadOnlyServiceSettings settings;
private readonly TelegramPrizeQrPayloadBuilder payloadBuilder;
private readonly QrCodeTextureRenderer textureRenderer;
public PrizeQrService(
[Zenject.InjectOptional] IReadOnlyServiceSettings settings = null,
TelegramPrizeQrPayloadBuilder payloadBuilder = null,
QrCodeTextureRenderer textureRenderer = null)
{
this.settings = settings;
this.payloadBuilder = payloadBuilder ?? new TelegramPrizeQrPayloadBuilder();
this.textureRenderer = textureRenderer ?? new QrCodeTextureRenderer();
}
public bool TryCreateTicket(PrizeFlowResult result, out PrizeQrTicket ticket, out string error)
{
ticket = null;
if (result.RewardKind != PrizeRewardKind.QRCode)
{
error = "QR создается только для QR-приза.";
return false;
}
if (!payloadBuilder.TryBuild(result, settings, out var payload, out error))
{
return false;
}
if (!QrCodeByteModeEncoder.TryEncode(payload.Url, out var matrix, out error))
{
return false;
}
var texture = textureRenderer.Render(
matrix,
darkColor: QrPrizeTierPalette.GetQrColor(payload.Tier));
ticket = new PrizeQrTicket(
payload.Url,
payload.OriginalPhone,
payload.PhoneDigits,
payload.Message,
texture,
payload.Tier);
error = string.Empty;
return true;
}
}
}