Commit Graph
154 Commits
Author SHA1 Message Date
neckfireandClaude Opus 4.8 3243b70555 game-server: catch-all request capture for squad-invite RE
Build & Deploy / build (push) Successful in 50s
Log every unrouted POST at Warning [CAPTURE UNROUTED] (reveals native PlayFab
endpoints the emulator doesn't implement, e.g. /Group/CreateGroup, /Lobby/*) and
every social/squad/invite/friend/matchmaking call (path or body) at Information
[CAPTURE SOCIAL]. Lets us pin the exact invite mechanism when reproduced in game.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 11:45:24 +02:00
neckfireandClaude Opus 4.8 d7821ebf1f friends: richer GetFriendList payload (field aliases) + log returned JSON
Build & Deploy / build (push) Successful in 53s
The friend tile rendered empty/offline because the UE client couldn't read our
best-guess response shape. Expose each friend's identity/name/steam/presence under
every plausible field name (camelCase + PlayFab PascalCase, flat + nested profile)
under both friends/Friends keys, and log the JSON so we can pin the exact shape.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 09:06:17 +02:00
neckfireandClaude Opus 4.8 81092b077e fortuna: add FortunaPass2_Rewards catalog so tiers can be claimed
Build & Deploy / build (push) Successful in 50s
The claim function only grants a tier when a FortunaPass2_Rewards TitleData catalog
maps its rewardId (Level_N, sent by the client) to an item/amount. That catalog was
absent (client-side DataTable) so claims granted nothing and stayed unclaimable.
Add a Level_1..Level_100 catalog (K-Marks scaling, Insurance every 5, Aurum every 10)
so players can actually collect Fortuna pass rewards.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 22:17:34 +02:00
neckfireandClaude Opus 4.8 95541b6221 docs: rewrite README around our build/CI + client switch tool
Build & Deploy / build (push) Successful in 32s
Replace the upstream Windows/local-run README with a dev-focused one: how the
client redirection works (loader+agent+backend.txt), repo structure, building
and running the API in a container, the TLS cert SAN gotcha, the Gitea CI/CD
branch model (preprod:preprod / main:latest), the Prospect.Client.Config
switch+cert tool, and an up-to-date feature status.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 13:54:36 +02:00
neckfireandClaude Opus 4.8 a8fca38038 admin: fix empty tables — define DT engine before page init scripts
Build & Deploy / build (push) Successful in 43s
The DT table engine lived in the page footer, after the per-page
<script>DT.init(...)</script> in the body, so DT was undefined when init ran
(ReferenceError, nothing rendered). Move the engine into a DtScript const
injected right after <main>, before any body content, so it is always defined
first.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 11:51:58 +02:00
neckfireandClaude Opus 4.8 b5c295f45c admin: interactive tables (sort/filter/search/paging) via client-side JS engine
Build & Deploy / build (push) Successful in 42s
Players and Catalog pages now fetch /admin/api/{players,catalog} JSON and render
a self-contained vanilla-JS data table: clickable column sort, live search,
dropdown filters (auth / category / rarity), page-size selector + prev/next
paging, result count. No CDN, works offline. Server-rendered dashboard,
player detail and titledata pages unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 11:30:22 +02:00
neckfireandClaude Opus 4.8 0b771c5447 feat(admin): resolve item/vanity ids to readable names + catalog browser
Build & Deploy / build (push) Successful in 42s
Bundle a compact id -> {name,rarity,category} lookup (Data/gameref.json, 1177 entries,
built from community-datamined TCF-Wiki data) and a GameRefService. The admin back-office
now shows readable names + coloured rarity for inventory items instead of raw ids, and a
new /admin/catalog page browses the known game catalog (searchable, by category).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 11:19:14 +02:00
neckfireandClaude Opus 4.8 4614b135a1 feat: resolve player display names from Steam persona (Steam Web API)
Build & Deploy / build (push) Successful in 41s
Accounts were created as 'Unknown' and the client never sends a name, so the admin
panel / friends / squad showed no names. Add SteamWebApiService (GetPlayerSummaries),
wired into LoginWithSteam to backfill the DisplayName from the Steam persona when it's
still 'Unknown'. Admin gets a LAN-only /admin/backfill-names action (+ button) to
backfill existing accounts in one shot. Key read from config SteamWebApiKey (Vault ->
env), inert when unset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 10:25:52 +02:00
neckfireandClaude Opus 4.8 b8d023b02a feat(admin): read-only back-office at /admin (LAN-only)
Build & Deploy / build (push) Successful in 38s
Filament-style dark UI served directly by the API:
- Dashboard: player/entity/userdata/titledata counts + recent players
- /admin/players: searchable player list (name/id/steam)
- /admin/players/{id}: full player view — balance/faction/Fortuna cards, inventory
  table, and every UserData key pretty-printed (collapsible)
- /admin/titledata + /admin/titledata/{key}: browse in-memory title data
Restricted to LAN/loopback callers (RemoteIpAddress check) so it is never reachable
from the public internet even though :8443 is port-forwarded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 09:56:34 +02:00
neckfireandClaude Opus 4.8 0a68a97291 fix(audit léger): stats carrière, présence amis, AddGenericId
Build & Deploy / build (push) Successful in 43s
- GetPlayerStatisticsRequestsClient: renvoyait vide -> renvoie les stats demandées
  (0 pour l'instant, raid client-hosted non traçable) pour que l'écran carrière s'affiche.
- UpdatePlayerPresenceState: persiste {inMatch,lastSeenUtc}; GetFriendList lit la présence
  et calcule onlineState (online si vu <3min, 2=en raid) au lieu de 0 en dur.
- AddGenericId: persiste l'id de service lié (était un no-op).
(Free-loadout non touché: S3 only, pas de free-loadout en S2.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 09:02:45 +02:00
neckfireandClaude Opus 4.8 1b4c1b2606 fix(audit): Fortuna pass level, display-name persist, loadout & craft-timer queries
Build & Deploy / build (push) Successful in 39s
Audit of the emulator surface + 4 fixes:
- Fortuna pass level was frozen: nothing ever granted season XP. ClaimActiveContract
  now grants + persists FortunaPass{2,3}_SeasonXp (scaled to the contract's reputation)
  and returns the new total, so the pass level moves as you complete contracts.
- UpdateUserTitleDisplayName never persisted the rename (echoed back, lost on relog).
  Added DbUserService.UpdateDisplayNameAsync and call it.
- GetPlayerSets returned a blank loadout; now reads the persisted LOADOUT key.
- GetCraftingInProgressData was a stub; now returns the persisted CraftingTimer so an
  in-progress craft + remaining time survive a menu reopen/relog.

Remaining known gaps documented in Plane (need client data / multiplayer / out of scope).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 02:56:47 +02:00
neckfireandClaude Opus 4.8 14ab3267f4 fix(shop): don't treat ContractLockPurchase sentinel 'None' as a real lock
Build & Deploy / build (push) Successful in 34s
Regression from the contract-lock feature: the check gated on any non-empty
ContractLockPurchase, but the blueprint data uses the string "None" (not "")
for items with no lock (749/773 items). So virtually every item returned
'Item is locked' before the currency deduction -> players couldn't buy anything
(error shown, K-Marks unchanged). Skip the gate when the value is null/empty/"None".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 02:15:13 +02:00
neckfireandClaude Opus 4.8 dc34233e40 fix(contracts): persist raid-zone objective progress (client-hosted raids)
Build & Deploy / build (push) Successful in 36s
Symptom: missions done in raid zones weren't saved -> contracts stuck on
'Objective not met', no claim possible.

Root cause: client-hosted raids have no dedicated game server, so
UpdatePlayerActiveContracts is never called (confirmed: 0 calls in prod logs).
Only Kills and OwnNumOfItem objectives were handled; DeadDrop/VisitArea/
LootContainer had Progress[i]=0 forever -> unclaimable and not shown at station.

Fix: EYContractObjectiveType.IsRaidRuntime() groups the objectives that can only
be observed in a live raid (Kills/DeadDrop/VisitArea/LootContainer). Auto-credit
them on deploy (EnterMatchmakingMatch, persisted) so the station shows them
complete, and accept them in ClaimActiveContract. OwnNumOfItem still validated
against the real stash; FactionLevel/CompletedMission unchanged. Added a
defensive guard against a Progress array shorter than the objective list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 01:54:25 +02:00
neckfireandClaude Opus 4.8 71a2c8a1e9 feat(deploy): optional dedicated-server travel via GAMESERVER_ADDRESS
Build & Deploy / build (push) Successful in 31s
When GAMESERVER_ADDRESS ("host:port") is set, EnterMatchmaking returns
that server (SingleplayerStation=false) and EnterMatchmakingMatch's
deploy signal carries its address, so the client travels to the real
game server instead of the client-hosted station. Unset = unchanged
(normal preprod). Lets a 2nd preprod run the same :preprod image and
differ only by this env var (dedicated-server test bench).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 18:41:20 +02:00
neckfireandClaude Opus 4.8 55a9571958 fix(matchmaking): deploy signal targets only the deploying player
Build & Deploy / build (push) Successful in 32s
EnterMatchmakingMatch broadcast OnSquadMatchmakingSuccess to Clients.All,
so one player deploying pulled every connected player into the match.
Map each player to their SignalR connection (GetSignalRConnection tags the
URL with uid; CycleHub records it via a SignalRConnectionRegistry) and
send the deploy signal only to that connection (broadcast fallback if
unmapped). Also enable m_automaticImportPlatformFriends (Steam friends).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 17:56:22 +02:00
neckfireandClaude Opus 4.8 8057fcae47 fix(social): disable friends limit (was capping at 0 friends)
Build & Deploy / build (push) Successful in 31s
FeatureToggles had m_isFriendsLimitEnabled=true with no positive limit,
so the client showed 'friend limit reached: 0 friends' and blocked adding
friends / squad invites. Disabled the toggle (squads/social already on).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 17:31:44 +02:00
neckfireandClaude Opus 4.8 c70f674431 docs(tool): document automatic Proton prefix cert import
Build & Deploy / build (push) Successful in 28s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 16:50:30 +02:00
neckfireandClaude Opus 4.8 61e45351cd feat(tool): import cert into the Proton prefix on Linux
Build & Deploy / build (push) Successful in 28s
On Linux the tool now actually trusts the server certificate inside the
game's Proton/Wine prefix (the wine certutil tool is broken under Proton):
it fetches the live cert from the server (backend.txt), builds the wine
serialized cert blob (SHA1 + encoded cert) and writes it to the prefix
Root store via `wine reg import`. Auto-detects the Proton wine and lists
compatdata prefixes (most-recent first) so the non-Steam-shortcut prefix
is picked correctly; the chosen prefix is remembered.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 16:48:49 +02:00
neckfireandClaude Opus 4.8 6d77bb4b82 chore(signalr): log remote IP + resolved URL for diagnostics
Build & Deploy / build (push) Successful in 30s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 16:24:49 +02:00
neckfireandClaude Opus 4.8 0089833b74 fix(signalr): return LAN SignalR URL to local clients
Build & Deploy / build (push) Successful in 34s
GetSignalRConnection now serves the SignalR URL on 192.168.1.136 to
clients whose remote IP is on the LAN, and keeps the public domain for
external clients. The real-time WebSocket (libwebsockets, incl. under
Proton/Wine) couldn't reach the public domain from inside the LAN
(hairpin NAT) — it failed right after the intro as "error code 5".
External friends are unaffected (still get the domain).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 16:18:35 +02:00
neckfireandClaude Opus 4.8 2809033b76 docs(tool): README for ProspectServerSwitcher
Build & Deploy / build (push) Successful in 26s
Documents the cross-platform server switcher: backend.txt mechanism,
domain presets, interactive/CLI usage, cert import (Windows / Proton),
launch, settings location and self-contained publish commands.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 16:03:24 +02:00
neckfireandClaude Opus 4.8 2cc90a22e0 feat(tool): use public domains as presets (works LAN + internet)
Build & Deploy / build (push) Successful in 26s
Switcher presets now use the public domains (tc.nfteam.ovh:8443 /
rd-tc.nfteam.ovh:8444) so the same target works for everyone; the
unified TLS cert covers both hostnames. LAN users add a hosts entry to
avoid hairpin NAT.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 15:57:51 +02:00
neckfireandClaude Opus 4.8 b04621e2a0 feat(tool): cross-platform server switcher (Prospect.Client.Config)
Build & Deploy / build (push) Successful in 25s
New console utility (net8.0, Linux/Proton + Windows) to point a client at
a server by writing backend.txt — the single value the Prospect agent
reads. Presets for PROD/PREPROD LAN and PROD internet, plus custom URL,
certificate import (native on Windows, guided with Proton-prefix
detection on Linux) and game launch. Interactive menu + scriptable CLI
(--folder/--set). Added to the solution; not built by the server CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 15:53:43 +02:00
neckfireandClaude Opus 4.8 0588849e4c feat(squad): in-memory squad/lobby state + wire squad functions
Build & Deploy / build (push) Successful in 31s
Adds SquadService (singleton, process-local) tracking squads by the
squadId the client shares across party members, plus a user->squad index
so TryGetCompleteSquadInfo (no squadId in request) can resolve the
caller's squad. Members are lazily registered on any squad call.

- TryGetCompleteSquadInfo: returns the caller's real squad.
- SquadMemberReadyForMatch: joins the squad, records readiness/map,
  returns the squad + whether everyone is ready.
- SquadMemberSelectedMap: records the member's selected map.
- DbUserService.FindByIdAsync: resolve display name for squad members.

Groundwork for the station lobby; assumes the client drives squads via
these calls with a shared squadId (to confirm with a 2-client session).
Real-time SignalR push (unknown event names) deferred; the squad is
carried in responses + TryGetCompleteSquadInfo for now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 15:34:43 +02:00
neckfire 922deb8397 docs: pointer vers la release pour LoaderPack + cert
Build & Deploy / build (push) Successful in 16s
2026-07-14 13:09:57 +00:00
neckfire f4d93c9e71 docs: ajoute la commande download_depot + astuce disque
Build & Deploy / build (push) Successful in 14s
2026-07-14 13:07:36 +00:00
neckfire b0822c34cd docs: guide install client amis
Build & Deploy / build (push) Successful in 14s
2026-07-14 12:33:52 +00:00
neckfireandClaude Opus 4.8 310e2bf7e9 feat(social): friends list resolution + fix ping request 500
Build & Deploy / build (push) Successful in 24s
- RequestUsersPingRequest: the client sends ping=2147483648 (int.MaxValue+1)
  for "no ping", which overflowed the int field and made every ping request
  return 500. Widened to long.
- ClientsideFriendsImport: persist the imported Steam friend ids per user.
- GetFriendList: resolve those ids to the players that exist on this server
  (batch lookup by Steam auth key) and return them as friends. Response
  shape is best-effort pending in-game confirmation.
- DbUserService.FindManyAsync: batch-resolve auth keys to players.

First step of the station lobby (see friends on the server). Squad
formation / invite flow to follow once friends are visible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 14:18:44 +02:00
neckfireandClaude Opus 4.8 5d93b3541d fix(store): return per-user owned vanities, not the whole catalogue
Build & Deploy / build (push) Successful in 23s
GetUserInventory returned every vanity in the Vanities title data as an
owned item, so the client showed all Aurum-shop cosmetics as already
owned. Return only the cosmetics the player actually owns: purchased
(VanityItems) plus currently equipped (CharacterVanity slots and the
GlobalVanity sprays / banner / emotes / drop pod), so the starter outfit
stays owned while the rest of the Aurum shop becomes purchasable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:55:50 +02:00
neckfireandClaude Opus 4.8 40dad82559 feat(store): populate Aurum/cosmetic shops from Vanities
Build & Deploy / build (push) Successful in 23s
GetStoreItems now also serves the cosmetic stores the client queries
(AurumShop, and the DailyShop_/WeeklyShop_ rotations) from the Vanities
title data: every vanity with StoreData.Amount > 0 is offered for that
price in Aurum (AU). AurumShop lists the full priced catalogue (632
items); the daily/weekly ids show a deterministic rotating slice so they
stay stable within a period but change across periods.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:46:17 +02:00
neckfireandClaude Opus 4.8 3b108d99ca feat(store): populate shops via GetStoreItems
Build & Deploy / build (push) Successful in 23s
GetStoreItems was a stub returning an empty object, so every shop
(Korolev / ICA / Osiris / QuickShop vendors) showed up empty. Build the
store on the fly from the Blueprints title data: for the requested
StoreId, list every item that declares an ItemShopsCraftingData entry
for that store, converting its currency recipe ingredients into
VirtualCurrencyPrices (SoftCurrency->SC, Aurum->AU, InsuranceCurrency->IN).
Item-ingredient (crafting) entries are left to the crafting UI.

Adds the StoreId/CatalogVersion fields to the request and the
FGetStoreItemsResult / FStoreItem PlayFab response models.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:53:37 +02:00
neckfireandClaude Opus 4.8 89e7a69049 feat(insurance,fortuna): payout on death + Fortuna Pass claim safety
Build & Deploy / build (push) Successful in 21s
- CompleteInventoryUpdate: insured items lost in a raid (present in
  ItemsToRemove) are recovered back to the stash and the insurance is
  consumed. This is the payout counterpart to the premium already
  debited on deploy (EnterMatchmakingStation). Gated on the policy
  declaring a positive Payout; never fails the inventory commit.
- RequestClaimFortunaPassRewards: log the client-sent reward IDs so a
  real FortunaPass{2,3}_Rewards catalog can be built to match, and stop
  recording a reward as claimed when there is no catalog entry to grant
  (previously it was burned permanently and became unclaimable).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:30:11 +02:00
neckfireandClaude Opus 4.8 6f3410b37d fix(contracts): auto-credit kill objectives in client-hosted raids
Build & Deploy / build (push) Successful in 21s
Kill-type contract objectives were never persisted: the client-hosted
raid has no dedicated game server to report per-kill progress, so
creature kills stayed at 0 and contracts reported "no kills" at claim.

- EnterMatchmakingMatch: auto-credit Kills objectives to MaxProgress on
  deploy (mirrors the item-ownership pre-compute already done there and
  the player-kill auto-credit in ActivateContract).
- ClaimActiveContract: treat Kills objectives as met as a safety net for
  contracts activated before deploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 11:56:14 +02:00
neckfireandClaude Opus 4.8 345a822a2e feat(preprod): contrats fonctionnels, réputation factions, gating tech-tree & shop
Build & Deploy / build (push) Successful in 21s
- RequestPlayerContracts: renvoie les vrais contrats actifs + job boards du joueur
  (peuplement initial des boards vides) au lieu d'une liste hardcodée.
- RequestFactionProgression: renvoie la réputation réelle des 3 factions (au lieu de 0).
- StartTechTreeNodeUpgradeClient: dependency check PlayerQuarterLevelRequired.
- PurchaseWeaponShopItem: critère de déblocage par contrat (UnlockData.ContractLockPurchase).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 02:20:27 +02:00
neckfireandClaude Opus 4.8 1e79360b6e feat: rotation shops (daily/weekly) + items insurance + season pass
Build & Deploy / build (push) Successful in 10s
- RequestStoreRotationData: rotation daily (reset 00:00 UTC) + weekly (lundi) avec
  storeIDs rotatifs déterministes et timers d'expiration corrects.
- EnterMatchmakingStation: traite purchaseInsuranceRequest au déploiement — marque
  les items assurés (Insurance + owner) et débite la prime (TitleData InventoryInsurance).
- FYPurchaseInventoryInsuranceRequest: modèle complété (insuranceId + itemIds).
- RequestClaimFortunaPassRewards: claim saison-correct (S2/S3 séparés, plus d'écrasement)
  + octroi des récompenses depuis catalogue TitleData optionnel (repli sûr sinon).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 02:55:54 +02:00
neckfireandClaude Opus 4.8 31aa20abd8 fix(ci): publier en configuration 'Season 2 Release' (client S2 déployé)
Build & Deploy / build (push) Successful in 8s
Le code sélectionne la saison via #if SEASON_2_RELEASE ; sans cette config le
build échoue (#error Unsupported build type). Build validé en local.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 02:37:11 +02:00
neckfireandClaude Opus 4.8 2630a9f2af ci: build serveur API depuis les sources + déploiement registry (prod/preprod)
Build & Deploy / build (push) Failing after 12s
Dockerfile multi-stage (SDK 8 publish → aspnet 8) et workflow Gitea Actions :
main → :latest (prod), preprod → :preprod. Base = tag b8 (état déployé).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 02:33:04 +02:00
Yury d9bd46e6e0 Update README b8 2025-03-31 01:40:20 +03:00
Yury 269659b8da Stash changes 2025-03-31 01:39:22 +03:00
Yury 14097808d8 Add CompleteInventoryUpdate CloudScript function from closed beta 2025-03-31 01:38:58 +03:00
Yury 6fe4432c6e Add custom UpdatePlayerActiveContracts CloudScript function for contracts update 2025-03-31 01:38:35 +03:00
Yury 4f11c8e550 Change Prospect.Client.Loader output dir 2025-03-31 01:37:34 +03:00
Yury 1ac2374eff Update README 2025-03-31 01:37:16 +03:00
Yury b5cb885262 Improve loader
* Improve loading speed
* Change DLL loading order
* Add Prospect.Agent.dll
2025-03-31 01:37:00 +03:00
Yury d55ef94fd9 Update launchSettings for HTTP server 2025-03-31 01:35:20 +03:00
Yury 1f4640fccd Fix given amount of quest reward 2025-03-31 01:34:41 +03:00
Yury faf90c1841 Autocomplete only PvP quests now 2025-03-31 01:34:16 +03:00
Yury efbacc57d1 Add Prospect.Agent DLL for utility functions 2025-03-31 01:33:41 +03:00
Yury 458585c37f Add "common-name" command-line parameter to generate_ssl 2025-03-31 01:33:01 +03:00
Yury b3c5fa3e2b Disallow accepting already completed contracts 2025-03-31 01:32:15 +03:00