# ZenBlackjack Changelog

## 1.6.1 - Channel selection for shoe controls

- Added an optional channel to public `-shoe`, `-hold` and `-shuffle`.
  Without a channel, each command continues to use the current channel.
- Examples: `-shoe #zen`, `-hold #zen on`, `-hold #zen --games 3`,
  `-shuffle #zen --gid 1100` and `-shuffle #zen --cancel`.
- The channel can also appear last: `-hold on #zen` or `-shuffle --cancel #zen`.
- The bot must be on the target channel with blackjack enabled. Hold and
  shuffle still require existing blackjack admin access; shoe status remains
  available to ordinary players and is returned by notice.
- Updated usage/help text. Existing private command forms remain available.
- No database migration is required; update only the script and rehash.

## 1.6.0 - SQLite persistence

### Storage and migration

- Replaced the flat-file database with SQLite, using Tcl's `sqlite3` binding.
  No separate database server or SQLite command-line program is required.
- The default database is now `scripts/blackjack.sqlite3` (`dbfile`).
  `chipfile` remains the legacy import source.
- Added a one-time import when the SQLite database has not been initialized.
  The original `.dat` file is retained, and a `.pre-sqlite.bak` copy is made
  if that backup does not already exist. Later loads use SQLite only.
- Preserved player IDs, services accounts, nickname aliases, learned hosts,
  manual hostmasks, bankrolls, statistics and gift preferences.
- Preserved shoe card order, remaining cards, holds, scheduled shuffles,
  ID counters and outstanding wager escrow.
- Player, identity, statistic, shoe and escrow data are stored in separate
  tables. Shoe cards retain their exact positions.

### Transactions and recovery

- Each save commits balances, statistics, identities, shoes, counters and
  wager escrow together in one transaction, with FULL synchronous writes.
- SQL values use bound parameters, including nicknames and hostmasks.
- Rehashing preserves live wagers. A process restart refunds interrupted
  wagers exactly once, retaining the existing recovery behavior.
- A failed save rolls back the transaction, pauses gameplay and cancels
  round timers. After repairing the cause, restart Eggdrop for recovery;
  rehashing is refused after a storage failure.
- Added schema, integrity and foreign-key checks when opening the database.
- A saved generation counter detects another writer using the same database.
  Direct editing of the live database remains unsupported.

### Backups and compatibility

- Added `::blackjack::backup_database <destination>` for consistent backups
  while the bot is running. It refuses to overwrite an existing backup or
  the live database. This is a Tcl procedure, not a new public IRC command.
- The old `.dat` stops receiving updates after migration. It remains a
  rollback source before new activity; later rollback requires reconciling
  or exporting current SQLite data.
- Gameplay rules, payouts, identity matching and existing IRC commands are
  unchanged. The deployed 420-second account-cache setting is retained.
- Tested offline with Tcl 8.6 and SQLite 3.34.1: full import comparisons,
  restart refunds, transaction rollback, backups and all 19 existing
  identity/game regression tests passed.
- Live verification confirmed account links and balances, a completed hand,
  balance/shoe/hold/game-ID persistence across rehash, successful backup,
  and an `ok` database integrity check.

## 1.5.2 - Services accounts and identity controls

### Account recognition

- Preserved Eggdrop's native services-account lookup (`getaccount`). Reliable
  native tracking remains the preferred source of identity information.
- Added a verified server WHOIS fallback for AuthServ and other networks that
  supply account names through numeric 330 when native tracking is unavailable
  or incomplete.
- WHOIS replies are checked against the player's nickname and current
  ident/host before an account is accepted. Commands wait for verification;
  failed or timed-out checks do not create a player record.
- Verified accounts are learned automatically when an existing player is
  recognized through their host, or when a new player record is created.
- Account checks are cached for a configurable interval
  (`account_cache_seconds`, 30 seconds by default). Further checks occur when
  needed by a command; idle players are not periodically polled.
- Account, nick and host changes, joins/leaves, and bot reconnections clear
  cached information. Rehashing clears pending checks without replaying old
  commands or wagers.

### Identity administration

- Added `-identity [nick]` to show the live account and its source, current
  host, matching player ID, and saved nickname alias. Live checks require the
  target to be in the channel where the command is used.
- Added `-listaccounts <id>`, `-addaccount <id> <account>` and
  `-delaccount <id> <account>` to inspect and manage persistent account links.
- These commands require blackjack admin access: global +B or +n. Account
  changes require the player to be out of all games and are saved immediately.
- An account already linked to another ID cannot be silently reassigned.

### Matching and host cleanup

- Services accounts take priority over manual blackjack hostmasks and learned
  exact hosts. Nicknames remain lookup aliases, not proof of identity.
- A different authenticated account cannot claim an account-linked record
  merely by matching its host.
- Normalized duplicate host aliases are consolidated. `-delhost` removes
  equivalent manual and learned entries, including leading-tilde variants.
- Ambiguous host ownership is detected rather than used to guess a player ID.
- `-chips`, `-stats` and `-getpid` no longer create new player records merely
  to answer a lookup.

### IDs and compatibility

- Existing v6 databases retain player IDs, bankrolls, statistics, gift
  preferences, shoes, holds and scheduled shuffles.
- Host matching remains available for unauthenticated players and networks
  without a supported account provider.

## 1.5.1 - Timed holds and scheduled shuffles

This update replaces the old --gid stale-command check with actual scheduling.

### Holds

- `-hold on` holds indefinitely; `-hold off` releases any hold early.
- `-hold --gid 50` holds through game #50. Normal automatic shuffling becomes
  available again before this channel's next deal above that ID.
- `-hold --games 5` holds for the next five rounds dealt in this channel.
  A round already underway does not count toward a newly set five-round hold.
- Canceled or refused rounds before dealing do not consume the count. Rounds
  that were dealt count even if later canceled. Rehashing does not count.
- Setting a new hold replaces the previous duration. `-hold on` clears any
  previous expiry and makes the hold indefinite.
- Expiry releases HOLD; it does not force a shuffle unless normal rules need one.

### Emergency shuffles

- A held shoe no longer blocks play when too few cards remain. The bot explains
  why it must shuffle, retains queued wagers, and proceeds with a fresh shoe:

    HOLD is enabled: X cards remain; at least Y are required to safely deal
    to Z player(s). Shuffling a fresh shoe; HOLD remains enabled.

- Emergency shuffles preserve HOLD and its game-ID target or remaining count.
  They do not reset or extend the duration.
- If even a fresh shoe cannot safely support the player count, the round is
  still refused and wagers are refunded; a hold count is not consumed.

### Scheduled shuffles

- `-shuffle` shuffles immediately, between rounds only.
- `-shuffle --gid 50` schedules a one-time shuffle after game #50, before
  this channel's next deal above that ID. Scheduling is allowed during play.
- `-shuffle --cancel` removes the schedule without affecting HOLD.
- Setting another target replaces the previous schedule. Already-past targets
  are rejected; the currently active round can be used as a target.
- A scheduled shuffle explicitly overrides HOLD for that shuffle, but preserves
  the hold setting and duration afterward.
- Manual and emergency shuffles do not cancel a future scheduled shuffle.
- Game IDs remain global across channels. If another channel receives the
  target ID, the action occurs before this channel's next deal above it.

### Status, persistence and configuration

- `-shoe` and `-hold` show the hold type, target ID or future rounds remaining,
  plus any scheduled shuffle. During the final counted round, zero future
  rounds remain; HOLD stays enabled until that round ends.
- All hold and schedule settings survive rehashes and restarts. Existing
  1.5.0 shoes keep their cards and hold state when upgraded.
- Updated help and private admin routes support the new command forms.
- Preserved the changelog URL in `-version` and its compatibility alias.

## 1.5.0 - Persistent shoes and game IDs

### The shoe

- Cards now carry over between rounds instead of using a freshly shuffled
  single deck for every game.
- Each channel has its own independent shoe.
- The default shoe contains six standard decks shuffled together: 312 cards.
  Identical cards can appear in the same hand because each card has six copies.
- Deck count is configurable from 1 to 8.
- Automatic reshuffling defaults to 75% of the shoe dealt. The shuffle happens
  before the next round, never halfway through a hand.
- The bot may shuffle earlier if too few cards remain to safely finish a round.
  The safety reserve accounts for the number of players and possible draws.

### Game and shoe IDs

- Each dealt round receives a game ID; each fresh shoe receives a shoe ID.
- Both IDs appear in the dealing header. Results include the game ID.
- ID counters persist across restarts and are shared across channels, so IDs
  may skip within one channel when another channel is also playing.

### New commands

- `-shoe` shows the shoe ID, deck count, cards remaining, hold status, and
  current or last game ID. Anyone can use it; the reply is a notice.
- `-hold on` prevents automatic reshuffling of the current shoe.
- `-hold off` restores automatic reshuffling.
- `-hold` shows the current status.
- `-shuffle` creates a fresh shoe between rounds. It is refused while a game
  is waiting to start or already in progress.
- Hold and shuffle controls require blackjack admin access: global +B or +n.
- A manual shuffle preserves the hold setting. Use `-hold off` to release it.
- If a held shoe cannot safely support the next round, the round is canceled
  before dealing and all waiting wagers are returned. No silent reshuffle.

An optional game-ID check protects against acting on the wrong round:

    -shuffle --gid 42
    -hold on --gid 42
    -hold off --gid 42

The command is refused if the channel's current/last game ID is not 42.
This is a safety check, not a seed or a way to replay an earlier game.

Private admin commands are also supported:

    /msg zen shuffle #zen
    /msg zen hold #zen on
    /msg zen hold #zen off
    /msg zen shoe #zen

### Persistence and recovery

- Shoe order, remaining cards, hold settings and ID counters are saved.
- Rehashing retains live rounds and their committed wagers.
- A full restart cancels unfinished rounds and refunds outstanding wagers.
  Cards already drawn remain removed from the shoe.
- Database saves write a temporary file before replacing the existing file,
  protecting the previous save if writing fails.
- Balances, identities, statistics and gift preferences are retained.
- Natural-blackjack payouts use exact integer arithmetic for the 3:2 profit,
  with fractional chips rounded down.

### Configuration

    variable shoe_decks 6
    variable shoe_cut_percent 75

A deck-count change takes effect when the next fresh shoe is shuffled.
The cut percentage controls when automatic reshuffling becomes due; the
safety reserve can require an earlier shuffle. Hold overrides automatic
shuffling, but does not override the safety check.

Back up the chip database before upgrading. The database now uses v6 records
for shoes, counters and outstanding wagers alongside the player records.

## 1.4.2k - Help and transfer limits

- Added `-help` with brief command explanations, sent by notice.
- Added `-commands` for the compact command list and `-version` for the version.
- Retained `-bjcommands`, `-bjcmds` and `-bjversion` as compatibility aliases.
- Help advertises the shorter command names. Admins receive additional help.
- Added configurable per-transaction limits:
  - `max_mint`: 1,000,000 chips for `-mint` and `-give --house`.
  - `max_gift`: 100,000 chips for player-to-player gifts.
- Transfers above the limit are rejected without moving chips.
- Bankrolls and legitimate game payouts remain uncapped.

## 1.4.2j - Gift preferences

- Added `-gifts off` to block incoming player gifts.
- Added `-gifts on` to accept them again; enabled is the default.
- `-gifts` reports the current setting by notice.
- Preferences are saved per player and survive reloads.
- Blocked gifts leave both balances and transfer totals unchanged.
- House grants and bailouts remain available when player gifts are disabled.

## 1.4.2i - Offline simulated bailout fix

- Fixed `-simul <nick> bailout` for players absent from the channel.
- The simulation uses the existing player ID instead of resolving an empty
  live host and accidentally creating a new player record.
- Normal bailout eligibility and cooldown checks still apply.

## 1.4.2h - Expanded statistics

- Expanded `-stats` into two lines: gameplay results and bankroll information.
- Renamed "Net" to "Game net" to distinguish gambling results from transfers.
- Added gifts sent/received, house-granted chips and bailout counts alongside
  the current bankroll and highest bankroll.
- Bailouts show counts; historical bailout chip totals were not recorded.
