kHold'em — Architecture & Integration Study

Read-only investigation of the installation on host EC2AMAZ-OJ656GO
version 3.17 (build 53) setup Server date 2026-07-18 READ-ONLY · no writes
01 Executive summary

A client ↔ server poker-room suite where the server owns every write

kHold'em (by eShark / LiPoker) is a .NET Framework 4.6 Windows tournament-management suite installed at C:\kHoldem. Clients never touch the database — they speak to a WCF/binary-TCP server that is the only sanctioned path to the data.

Bounty / PKO already ships. It is a first-class tournament type — 144 of 403 live tournaments are already knockout events. You configure it, you don't build it. See §7.
The server is the sole DB gateway. Business logic, caching, permissions, and sync bookkeeping all live server-side. When SQL briefly dropped, the server — not the client — threw the error.
Best way to "write" is to drive the server, not the database. Three integration surfaces exist (Addon SDK, client-protocol side-car, local Web/API). See §8.
Secrets are locked to this machine. DB auth is Windows-integrated (no stored password); cloud tokens in service.json are DPAPI-encrypted and non-portable.
145
Tables in kHoldem DB
11
Stored procedures
~110
Cloud-synced tables
144/403
Tournaments already knockout
03 How it's wired

Every client funnels through one core server into one database

kholdem.exe
operator desktop UI
Tablet · clock · display
floor devices
Web viewer
Angular live results
kHoldemServer
core app server — business logic, caches, sole DB connection
kHoldemWebServer
OWIN + ASP.NET Web API on 5855
SQL Server 2017
instance .\KHOLDEM · db kHoldem
eShark Cloud
multi-venue sync via kholdemsync (HTTPS)
Siblings kHoldemBackup, kHoldemPrintEngine, and kHoldemPokerLens hang off the same server/DB layer. Every backend service is the same binary — kholdemhost.exe /service <Name> — running as LocalSystem.
03 The services

Backend roles & ports

ServiceRolePorts
kHoldemServerCore app server — logic, SQL connection, serves all clients250558567215
kHoldemWebServerLocal Web + API (OWIN, Swagger), serves pages & Angular app5855
kholdemsyncCloud sync engine — pushes/pulls to eSharkoutbound
kHoldemBackupScheduled DB backups
kHoldemPrintEngineTicket / receipt / report printing
kHoldemPokerLensRFID / card-recognition integration
MSSQL$KHOLDEMSQL Server instanceUDP 1434
04 Where data lives

System of record

  • Engine: Microsoft SQL Server 2017 (MSSQL14.KHOLDEM), running as NT AUTHORITY\LOCALSERVICE.
  • Database: kHoldem — 145 tables, 11 stored procedures.
  • Auth: Mixed mode enabled, but the app uses Windows integrated (trusted)service.json has a Connection block with server + database but no password.
  • Keys: nearly every table uses an app-generated uniqueidentifier (GUID) primary key; a sync_lastupdated column drives optimistic concurrency.
  • Collation caveat: columns mix Latin1_General_CI_AS_KS_WS and SQL_Latin1_General_CP1_CI_AS — cross-collation string concatenation throws in ad-hoc SQL.

Domain families: Tournament*, Cash*, Player / PlayerClub / VIP*, Ranking / Season / League, Transaction / Payment / Document, Mail / SMS, Server / Device / Domain, BlackList, Permission / Group / User (RBAC).

02 Physical layout · C:\kHoldem

What sits on disk

PathWhat it is
kholdem.exeDesktop client — WinForms + DevExpress + WebView2. The operator UI.
kholdemhost.exeService host — one process per backend service.
kholdemmedia.exeMedia / clock renderer (tournament clock, displays).
Components\Application assemblies — LiPoker.*.dll core, DevExpress UI, Twilio, AWS SNS, Chilkat, Google APIs, SignalR, OWIN.
Addons\Plug-in modules (*.kpl): triton, pslive, barriere, igt, pokerlens, eid, apt, cis, leris, luxon, neon, zino, direpay, ci, spider — evidence of a supported extension mechanism.
Web\Local web + API host: legacy ASP.NET (LiPokerWS) pages + Web\v2\ compiled Angular SPA (public results / clock viewer).
Configuration\syncengine.jsonDeclarative map of every table that participates in multi-site cloud sync.
Database\Release.bakShipped baseline DB backup, used to provision the DB on install.

Runtime state lives outside the install dir in C:\ProgramData\kHoldem\: service.json (connection + cloud identity), version.json, *.lic, Log\, Data\, and server-side addon binaries under Addons\Server\ (Core, Sync, Backup, PokerLens, PrintEngine, Security).

05 Cloud sync & multi-site

Timestamp-based, last-writer-wins delta sync

  • syncengine.json declares ~110 replicating tables, each with GUID key(s) and UTC-vs-date-only markers (DateTimeMode).
  • Account, Club, Player, Tournament carry NetworkLastUpload / NetworkLastDownload / LastUpdated markers.
Why it matters
Write to the DB out-of-band and you must respect these markers, or the sync engine will overwrite your change or push a corrupt delta to the cloud. This is the single biggest reason not to bypass the server.
06 Credentials & secrets

What each layer requires

TargetCredential
SQL DB
.\KHOLDEM / kHoldem
Windows login on the instance (services run as LocalSystem = sysadmin). No SQL password stored.
kHoldemServer
WCF
A kHold'em user account + a registered Device. Identity stored in HKCU\SOFTWARE\kHoldem.
eShark Cloud
sync / licensing
Membership account + DPAPI-encrypted token & AccessToken, licenseId, ServerID.
Local Web/API
port 5855
App-level auth — returns HTTP 500 to anonymous probes.

DPAPI blobs in service.json start with AQAAANCMnd8B… — decryptable only on this machine, by the account that encrypted them. Not portable, not a liftable API key.

07 Poker Bounty / PKO

It already exists — you configure it, not build it

Shipped
kHold'em ships bounty as a first-class tournament type. 144 of 403 live tournaments already have KnockOut = 1. Real events today include "NLH Big Bounty: $3,000", "Speed Racer – NLH Bounty", and "NLH Mystery Bounty". Standard bounty, Progressive KO, and Mystery Bounty are all modeled end-to-end.

Tournament  bounty configuration

ColumnTypeMeaning
KnockOutbitIs this a bounty/KO tournament
KnockOutTypeint1 = standard, 3 = Mystery Bounty
KnockOutAmountfloatBounty value per player
KnockOutProgressivefloatPKO — share rolling onto the eliminator
KnockOutProgressiveRoundTypeintRounding rule for the split
KnockOutTax · KnockOutHousebitTax / house-rake on the bounty portion
TotalKnockOutdecimalRoll-up of bounty money in the pool

TournamentPlayers  per-player accounting

  • KnockOutCount, KnockOutValue, KnockOutAmount
  • KnockedOutPlayerID, KnockedOutPlayersIDString — who this player eliminated
  • PayoutKnockOutAmount, PayoutAmount, PayoutAssigned
Bottom line
"Implement PKO" reduces to configure PKO: create a tournament with KnockOut = 1, set KnockOutType and KnockOutAmount, and a non-zero KnockOutProgressive. The UI, schema, and payout engine are already in place.
08 Integration surfaces

Four ways in — ranked by safety and supportability

Drive the server, not the database. The options below run from most-native to actively-discouraged.

A

Addon (.kpl) plugin

✅ Most native

kHold'em has a first-party plug-in model (triton.kpl, pslive.kpl, direpay.kpl…) with server-side binaries under ProgramData\…\Addons\Server\ and a LiPoker.Modules.Base.API.dll. A .kpl runs inside the server process, so it inherits the sanctioned data layer, sync-safe writes, and event hooks for free.

Cost: needs the eShark Addon SDK / partner docs (not on this box) and likely signing.
B

Client-protocol side-car

✅ Recommended

A standalone service that speaks the same WCF client protocol as kholdem.exe, reusing shipped SDK assemblies (LiPoker.Modules.Base.Client/API.dll, LiPoker.Network.dll). It authenticates as a user + Device and issues the same commands the UI does — every write passes server validation, permissions, and sync bookkeeping.

Cost: you must reflect/obtain the command contracts (e.g. AdministrationHandler) — feasible but unofficial.
C

Local Web / API (5855)

⚠ Limited

kHoldemWebServer self-hosts an ASP.NET Web API (LiPokerWS) with Swagger. Cleanest transport (HTTP/JSON) if the endpoints you need are exposed — but observed surface is live-results / display / cloud-registration oriented and returns 500 to unauthenticated probes.

Cost: enumerate its Swagger doc from an authenticated context before betting on it.
D

Direct SQL writes

❌ Do not

A local process can open a trusted connection and write — but don't, except read-only reporting:

  • Server holds in-memory caches — out-of-band writes go stale/incoherent until reload.
  • Sync engine overwrites hand-written rows or pushes bad deltas.
  • GUID keys, invariants, payout math & permissions are enforced in code — you'll create orphans.
  • The one safe direct use is READ — ideally against a restored Release.bak, not the live DB.
09 Recommended path for a PKO / bounty project

Configure first, automate through the server, never write raw

1
Confirm the built-in engine is insufficient.
Standard bounty, Progressive KO, and Mystery Bounty are already supported end-to-end. For most requirements the deliverable is configuration + a report or skin, not code.
2
If you need automation or external control…
Read side: query a backup/restored copy of the DB (Tournament, TournamentPlayers, payout tables) for dashboards/exports — safe and easy.  Write side: implement Option B side-car, or pursue Option A Addon SDK. Never write tournament/player/payout rows straight into the live DB.
3
Engage eShark for the Addon SDK + API docs.
Official contracts turn Options A/B/C from reverse-engineering into a supported build.
10 Quick reference

Everything on one card

InstallC:\kHoldem
State / secretsC:\ProgramData\kHoldem
Logs…\kHoldem\Log
DB connection.\KHOLDEM · kHoldem · SSPI
Server (WCF)TCP 2505 / 5856 / 7215
Local Web + APIHTTP 5855
SQL BrowserUDP 1434
Core assembliesLiPoker.dll · .Network · WS
Extension points.kpl · client SDK · Web API
Bounty / PKOTournament.KnockOut*
Cloud membershipzsop.team@gmail.com
SecretsDPAPI in service.json · *.lic