История версий CMS Donate Engine

2026-10-16 15:39:03
fix(user): read balance from money db in PlayerDataRepository

2026-10-16 13:53:46
fix(store): prevent double refund on concurrent cancel The cancel flow credited the buyer before flipping the message body, so two admins clicking at the same time could each pass the marker check and each trigger addMoney, doubling the refund. Flip the message body first with a conditional UPDATE on the original body and bail out when affectedRows is 0. Only the request that wins the UPDATE proceeds to credit the buyer and write the refund log. Roll back the body if addMoney returns false.

2026-10-16 13:34:33
fix(store): restore add-product action in category nav

2026-10-16 13:19:48
feat(store): manual delivery with admin workflow in IM Discord is a notification channel, not a delivery method. Split the concern: GiveType::Manual replaces GiveType::Discord as the delivery type, ManualGive settles the purchase (money, stock, log) at buy time, and delivery is performed by an admin in-game. PurchaseDialogNotifier posts new manual orders to the shared admin dialog: the bot is the author, admins are members, the message shows the server, item x count, a link to the buyer profile, and the command in a code block. Three inline actions per order: - Copy 14 client-side, clipboard - I delivered 14 atomic UPDATE on the message body, first click wins - Cancel and refund 14 credits the buyer via memberData and writes a buy_store_refund row through PurchaseLog::writeRefund Admin membership in the server dialog is synced on each purchase: new owners are added, removed owners are dropped, the bot stays first. StorePurchaseService notifies admins only for Manual. StoreApiController and StoreAdminDeleteService use UrlGeneratorInterface for URLs instead of string concatenation. Rename name -> serverName in StoreProductQuery::findForPurchase and GiveContext. Discord webhook (discord_hook_shop) is used only as an additional notification channel for manual orders, in plain text. Migration 19248: - products: give 'discord' -> 'manual' - bundles: '"give":"discord"' -> '"give":"manual"' in command JSON - new translations for admin workflow and player refund notice - remove obsolete ADMIN_PURCHASE_NOTIFY_SUBJECT(_GLOBAL)

2026-10-14 13:09:04
fix(session): reload steam_id when session holds an empty string

2026-10-14 08:52:57
fix(session): reload steam_id from profile when session holds an empty string

2026-10-14 08:36:33
refactor(store): unify SteamID validation, DI purchase service fix(database): cache tags

2026-10-14 06:29:21
refactor(rcon): move protocol implementations into Protocol subdirectory

2026-10-13 18:50:39
refactor(rcon,query): add RconClient interface, rename Facade adapters

2026-10-13 08:56:46
feat(store): name the server in player-offline message

2026-10-12 23:33:43
fix(store): route GiveQueue to RCON, classify placeholder failures, read member fields from main db GiveType::fromGive mapped GiveQueue to Inventory, so store purchases went through the wrong delivery path. Placeholder failures were indistinguishable, surfacing server unavailable for missing Steam. Member fields were read through the money connection without cache. ValidatePayment duplicated the identity check. - GiveType: GiveQueue !92 Rcon - PlaceholderResolver: PlaceholderKind (Identity/Presence/Runtime/Unknown) and a single missingIdentity() preflight - RconGive: match on PlaceholderKind, no preflight duplication - StorePurchaseService: take CurrentUser, drop flat fields and ValidatePayment - MemberDataFactory/memberData: split $mainDb from $moneyDb - CurrentUser::getServerAuth() - Frontend: SteamID as placeholder, not value

2026-10-12 17:29:18
fix(http): return 405 for routing MethodNotAllowedException

2026-10-12 07:09:52
fix(admin): layout alignment and Response support - restore text-right on #naviButtons for legacy float-based toolbars - wrap cron navi in d-inline-flex to prevent button collapse - capture controller return value in AdminRunner and pass Response through, matching FrontRunner behaviour

2026-10-12 06:26:39
feat(store): distinguish missing identity from offline player When the account has neither a Steam id nor a server auth id, the store cannot identify the player in the game at all, but RconGive returned playerOffline and the UI asked the user to join the server. Add GiveResult::identityMissing, return it when both steam and playerServerAuth are empty, and surface STORE_IDENTITY_MISSING from the purchase match. playerOffline is now returned only when an identifier exists but the player is not on the server.

2026-10-12 05:56:32
fix(store): use Steam auth id and drop undefined from purchase POST StorePurchaseService read $_SESSION[steam_id] (linked profile) instead of $_SESSION[STEAMID] (Steam auth), so userIsOnline() missed players who were online. form_submit_ajax unconditionally read #username_inp, #steam_inp and #server_auth; .val() returned undefined for absent fields and the literal undefined went into every purchase request. Prefer STEAMID when building GiveContext, coalesce the three lookups and ignore the literal undefined on the server side.

2026-10-11 18:02:44
fix(store/give): reject offline RCON delivery instead of silently queueing

2026-10-11 17:42:08
fix(store/purchase): handle player_off and not_deliverable statuses explicitly

2026-10-11 15:46:56
fix(store/give): return player_off for offline player instead of fake ok

2026-10-11 15:35:38
fix(store/give): fail explicitly on unresolved placeholders PlaceholderResolver previously treated empty placeholder values null as absent and let them slip through to str_ireplace, so commands like tele %crossid% ... reached the game server with literal tokens and the game replied player not found. - add PlaceholderNotResolvedException with the missing placeholder list - collect unresolved placeholders before substitution and throw instead of emitting a half-built command - catch it separately in RconGive and return GiveResult::notDeliverable instead of misleading serverOffline - persist the failure via PurchaseLog::writePlaceholderFailure

2026-10-11 11:58:14
feat(cron): add same_type queue delivery mode - QueueService: MODE_SAME_TYPE + runSameTypeWithConnections() - ServerMonitor: match three modes (strict/same_type/any) - cron.php + panel.tpl: select with three options - MigrateMySQL19228: QUEUE_DELIVERY_* translations (up/down)