@zaisma/game-server 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zaisma/game-server",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "Run your Zaisma game server: the same rooms on Zaisma or on your own server.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://zaisma.com",
package/sdk/zaisma.d.ts CHANGED
@@ -566,6 +566,32 @@ declare namespace Zaisma {
566
566
  */
567
567
  const versions: Versions;
568
568
 
569
+ /**
570
+ * Whether Zaisma's page covers the game right now, so a game can pause or hold the player's input while it does.
571
+ * coveredBy is "sheet" while one of Zaisma's sheets is open over the game (buying, Players, Report: the player is
572
+ * busy with it), "card" while one of its cards is over the game's corner (Still there?, Keep your progress; the
573
+ * game stays in view and playable), and null otherwise. Always null outside Zaisma's page (your own site, a
574
+ * local test). Listen for "coveredBy" to hear each change.
575
+ * @example
576
+ * Zaisma.page.on("coveredBy", (coveredBy) => {
577
+ * if (coveredBy === "sheet") pauseGame();
578
+ * else resumeGame();
579
+ * });
580
+ */
581
+ const page: Page;
582
+
583
+ /** Whether Zaisma's page covers the game ({@link page}). */
584
+ interface Page {
585
+ /** "sheet", "card" or null: what of Zaisma's is over the game now. Read-only. */
586
+ readonly coveredBy: CoveredBy;
587
+ /** Listen for "coveredBy": called with the new value each time it changes. A wrong name fails with error.code "unknown_event". */
588
+ on(event: "coveredBy", listener: (coveredBy: CoveredBy) => void): Page;
589
+ off(event: "coveredBy", listener: (coveredBy: CoveredBy) => void): Page;
590
+ }
591
+
592
+ /** What of Zaisma's covers the game ({@link page}): one of its sheets, one of its cards, or nothing. */
593
+ type CoveredBy = "sheet" | "card" | null;
594
+
569
595
  /** A version published "now" ({@link versions}). */
570
596
  interface Versions {
571
597
  /** Listen for "update". A wrong name fails with error.code "unknown_event". */
package/sdk/zaisma.js CHANGED
@@ -37,6 +37,7 @@
37
37
  var SAVES_EVENTS = ["conflict", "developerChange"];
38
38
  var ITEMS_EVENTS = ["purchase", "refund", "sheetOpen", "sheetClose"];
39
39
  var VERSIONS_EVENTS = ["update"];
40
+ var PAGE_EVENTS = ["coveredBy"];
40
41
  var BUY_OPTIONS = ["itemCount", "gameAccountId"];
41
42
  /** The room messages this SDK speaks (zaisma.d.ts: the wire protocol), sent in the hello. */
42
43
  var PROTOCOL_VERSION_NUMBER = 1;
@@ -2023,6 +2024,34 @@
2023
2024
  });
2024
2025
  }
2025
2026
 
2027
+ /*
2028
+ * Whether Zaisma's page covers the game: "sheet" while one of its sheets is open over it (buying, Players, Report), "card" while one of
2029
+ * its cards is over the game's corner, null otherwise, and always null outside Zaisma's page. The page says so whenever it changes
2030
+ * (zaisma:covered), and only the page is heard. A game can pause while a sheet covers it.
2031
+ */
2032
+ var pageEvents = new Emitter(PAGE_EVENTS, "Zaisma.page has");
2033
+ var coveredBy = null;
2034
+ var zaismaPage = {
2035
+ on: function (event, listener) {
2036
+ pageEvents.on(event, listener);
2037
+ return zaismaPage;
2038
+ },
2039
+ off: function (event, listener) {
2040
+ pageEvents.off(event, listener);
2041
+ return zaismaPage;
2042
+ },
2043
+ };
2044
+ Object.defineProperty(zaismaPage, "coveredBy", { enumerable: true, get: function () { return coveredBy; } });
2045
+ if (config.site && window.parent !== window) {
2046
+ window.addEventListener("message", function (event) {
2047
+ if (event.origin !== config.site || event.source !== window.parent || !event.data || event.data.type !== "zaisma:covered") return;
2048
+ var now = event.data.coveredBy === "sheet" || event.data.coveredBy === "card" ? event.data.coveredBy : null;
2049
+ if (now === coveredBy) return;
2050
+ coveredBy = now;
2051
+ pageEvents._emit("coveredBy", now);
2052
+ });
2053
+ }
2054
+
2026
2055
  /*
2027
2056
  * The player's cloud saves, for games that draw their own save screens. The game page on Zaisma holds
2028
2057
  * the player's session and answers (apps/site/src/saves-client.ts); the game never talks to a server.
@@ -2506,5 +2535,5 @@
2506
2535
  });
2507
2536
 
2508
2537
  var friends = { list: listFriends, setRoom: setOwnRoom, sendRequest: sendFriendRequest };
2509
- window.Zaisma = { sdkVersionNumber: 1, gameSlug: config.game || null, player: player, joinRoom: joinRoom, rooms: rooms, server: server, invite: invite, checkChat: checkChat, openPlayersPanel: openPlayersPanel, links: links, items: items, friends: friends, saves: saves, versions: versions };
2538
+ window.Zaisma = { sdkVersionNumber: 1, gameSlug: config.game || null, player: player, joinRoom: joinRoom, rooms: rooms, server: server, invite: invite, checkChat: checkChat, openPlayersPanel: openPlayersPanel, links: links, items: items, friends: friends, saves: saves, versions: versions, page: zaismaPage };
2510
2539
  })();
package/src/qr-code.d.ts CHANGED
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * QR codes for game and room links (docs/DECISIONS.md, "QR codes"): players get one behind Share,
3
- * developers on the dashboard and through the API and MCP. Byte mode, error correction level M,
4
- * versions 1 to 10 (up to 213 bytes, far more than a link needs). Written here rather than taken from a
3
+ * developers on the dashboard and through the API and MCP. Byte mode, error correction level H, so a
4
+ * small picture over its middle (a game's icon) still leaves it readable, versions 1 to 10 (up to 119
5
+ * bytes, far more than a link needs). Written here rather than taken from a
5
6
  * package so the site's page and the API draw the same code with no dependency; it follows ISO/IEC
6
7
  * 18004 the way Project Nayuki's reference encoder does.
7
8
  */
8
9
  export declare const QR_CODE_LIMITS: {
9
- /** Version 10 at level M holds 213 bytes. */
10
- readonly maximumTextBytes: 213;
10
+ /** Version 10 at level H holds 119 bytes. */
11
+ readonly maximumTextBytes: 119;
11
12
  /** Light modules around the code, as the standard asks. */
12
13
  readonly quietZoneModuleCount: 4;
13
14
  };
package/src/qr-code.js CHANGED
@@ -1,21 +1,22 @@
1
1
  /**
2
2
  * QR codes for game and room links (docs/DECISIONS.md, "QR codes"): players get one behind Share,
3
- * developers on the dashboard and through the API and MCP. Byte mode, error correction level M,
4
- * versions 1 to 10 (up to 213 bytes, far more than a link needs). Written here rather than taken from a
3
+ * developers on the dashboard and through the API and MCP. Byte mode, error correction level H, so a
4
+ * small picture over its middle (a game's icon) still leaves it readable, versions 1 to 10 (up to 119
5
+ * bytes, far more than a link needs). Written here rather than taken from a
5
6
  * package so the site's page and the API draw the same code with no dependency; it follows ISO/IEC
6
7
  * 18004 the way Project Nayuki's reference encoder does.
7
8
  */
8
9
  export const QR_CODE_LIMITS = {
9
- /** Version 10 at level M holds 213 bytes. */
10
- maximumTextBytes: 213,
10
+ /** Version 10 at level H holds 119 bytes. */
11
+ maximumTextBytes: 119,
11
12
  /** Light modules around the code, as the standard asks. */
12
13
  quietZoneModuleCount: 4,
13
14
  };
14
- // Level M: error correction codewords per block and blocks, by version (index 0 unused).
15
- const ERROR_CORRECTION_CODEWORD_COUNTS_PER_BLOCK = [0, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26];
16
- const ERROR_CORRECTION_BLOCK_COUNTS = [0, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5];
17
- /** Error correction level M (medium)'s two bits in the format information. */
18
- const MEDIUM_CORRECTION_FORMAT_NUMBER = 0;
15
+ // Level H: error correction codewords per block and blocks, by version (index 0 unused).
16
+ const ERROR_CORRECTION_CODEWORD_COUNTS_PER_BLOCK = [0, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28];
17
+ const ERROR_CORRECTION_BLOCK_COUNTS = [0, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8];
18
+ /** Error correction level H (high)'s two bits in the format information. */
19
+ const HIGH_CORRECTION_FORMAT_NUMBER = 2;
19
20
  const HIGHEST_VERSION_NUMBER = 10;
20
21
  const isBitSet = (bitsNumber, bitIndex) => ((bitsNumber >>> bitIndex) & 1) !== 0;
21
22
  function rawDataModuleCount(versionNumber) {
@@ -226,7 +227,7 @@ export function qrCodeModules(text) {
226
227
  }
227
228
  }));
228
229
  const drawFormat = (maskIndex) => {
229
- const formatNumber = (MEDIUM_CORRECTION_FORMAT_NUMBER << 3) | maskIndex;
230
+ const formatNumber = (HIGH_CORRECTION_FORMAT_NUMBER << 3) | maskIndex;
230
231
  let remainderNumber = formatNumber;
231
232
  for (let stepIndex = 0; stepIndex < 10; stepIndex++)
232
233
  remainderNumber = (remainderNumber << 1) ^ ((remainderNumber >>> 9) * 0x537);