lpc-forge 1.0.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.
Files changed (75) hide show
  1. package/CREDITS.csv +22985 -0
  2. package/LICENSE +674 -0
  3. package/README.md +281 -0
  4. package/assets/music/.gitkeep +0 -0
  5. package/dist/character/batch.d.ts +17 -0
  6. package/dist/character/batch.js +48 -0
  7. package/dist/character/batch.js.map +1 -0
  8. package/dist/character/composer.d.ts +3 -0
  9. package/dist/character/composer.js +164 -0
  10. package/dist/character/composer.js.map +1 -0
  11. package/dist/character/definitions.d.ts +16 -0
  12. package/dist/character/definitions.js +116 -0
  13. package/dist/character/definitions.js.map +1 -0
  14. package/dist/character/presets.d.ts +6 -0
  15. package/dist/character/presets.js +246 -0
  16. package/dist/character/presets.js.map +1 -0
  17. package/dist/character/slicer.d.ts +8 -0
  18. package/dist/character/slicer.js +66 -0
  19. package/dist/character/slicer.js.map +1 -0
  20. package/dist/character/types.d.ts +48 -0
  21. package/dist/character/types.js +32 -0
  22. package/dist/character/types.js.map +1 -0
  23. package/dist/cli.d.ts +2 -0
  24. package/dist/cli.js +938 -0
  25. package/dist/export/frames.d.ts +5 -0
  26. package/dist/export/frames.js +15 -0
  27. package/dist/export/frames.js.map +1 -0
  28. package/dist/export/godot.d.ts +17 -0
  29. package/dist/export/godot.js +464 -0
  30. package/dist/export/godot.js.map +1 -0
  31. package/dist/export/types.d.ts +11 -0
  32. package/dist/export/types.js +2 -0
  33. package/dist/export/types.js.map +1 -0
  34. package/dist/license.d.ts +49 -0
  35. package/dist/license.js +271 -0
  36. package/dist/map/cellular.d.ts +3 -0
  37. package/dist/map/cellular.js +191 -0
  38. package/dist/map/cellular.js.map +1 -0
  39. package/dist/map/dungeon.d.ts +3 -0
  40. package/dist/map/dungeon.js +238 -0
  41. package/dist/map/dungeon.js.map +1 -0
  42. package/dist/map/multifloor.d.ts +20 -0
  43. package/dist/map/multifloor.js +57 -0
  44. package/dist/map/multifloor.js.map +1 -0
  45. package/dist/map/overworld.d.ts +3 -0
  46. package/dist/map/overworld.js +205 -0
  47. package/dist/map/overworld.js.map +1 -0
  48. package/dist/map/town.d.ts +7 -0
  49. package/dist/map/town.js +181 -0
  50. package/dist/map/town.js.map +1 -0
  51. package/dist/map/types.d.ts +65 -0
  52. package/dist/map/types.js +16 -0
  53. package/dist/map/types.js.map +1 -0
  54. package/dist/map/wfc.d.ts +18 -0
  55. package/dist/map/wfc.js +192 -0
  56. package/dist/map/wfc.js.map +1 -0
  57. package/dist/tileset/atlas.d.ts +15 -0
  58. package/dist/tileset/atlas.js +55 -0
  59. package/dist/tileset/atlas.js.map +1 -0
  60. package/dist/tileset/registry.d.ts +12 -0
  61. package/dist/tileset/registry.js +71 -0
  62. package/dist/tileset/registry.js.map +1 -0
  63. package/dist/tileset/terrain.d.ts +3 -0
  64. package/dist/tileset/terrain.js +110 -0
  65. package/dist/tileset/terrain.js.map +1 -0
  66. package/dist/utils/credits.d.ts +11 -0
  67. package/dist/utils/credits.js +74 -0
  68. package/dist/utils/credits.js.map +1 -0
  69. package/dist/utils/image.d.ts +17 -0
  70. package/dist/utils/image.js +94 -0
  71. package/dist/utils/image.js.map +1 -0
  72. package/dist/utils/rng.d.ts +18 -0
  73. package/dist/utils/rng.js +48 -0
  74. package/dist/utils/rng.js.map +1 -0
  75. package/package.json +77 -0
@@ -0,0 +1,271 @@
1
+ import { readFile, writeFile, mkdir, unlink } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { homedir, hostname, platform, arch } from 'node:os';
4
+ import { createHmac } from 'node:crypto';
5
+ const LICENSE_DIR = join(homedir(), '.lpc-forge');
6
+ const LICENSE_FILE = join(LICENSE_DIR, 'license.json');
7
+ /**
8
+ * HMAC signing key derived from a combination of factors.
9
+ * This isn't meant to be uncrackable — it's a Node CLI tool, the source is
10
+ * open. The goal is to make casual bypass inconvenient enough that buying
11
+ * $10 is easier. Determined crackers will always win; we optimize for the
12
+ * honest middle.
13
+ */
14
+ const SIGNING_SEED = 'lpc-forge:blueth:2026';
15
+ // ─── Machine Fingerprint ──────────────────────────────────────────────
16
+ function getMachineFingerprint() {
17
+ const raw = `${hostname()}:${platform()}:${arch()}:${homedir()}`;
18
+ return createHmac('sha256', SIGNING_SEED).update(raw).digest('hex').slice(0, 16);
19
+ }
20
+ // ─── HMAC Signing ─────────────────────────────────────────────────────
21
+ function signLicense(data) {
22
+ const payload = [
23
+ data.key,
24
+ data.email,
25
+ data.product,
26
+ data.activatedAt,
27
+ data.lastVerifiedAt,
28
+ data.machineId,
29
+ ].join('|');
30
+ return createHmac('sha256', SIGNING_SEED).update(payload).digest('hex');
31
+ }
32
+ function verifySignature(license) {
33
+ const { signature, ...data } = license;
34
+ return signLicense(data) === signature;
35
+ }
36
+ // ─── License Validation ───────────────────────────────────────────────
37
+ /**
38
+ * Check if a valid premium license exists.
39
+ *
40
+ * Validates:
41
+ * 1. File exists and parses
42
+ * 2. HMAC signature is correct (not tampered)
43
+ * 3. Machine fingerprint matches (not copied from another machine)
44
+ * 4. Key format is valid
45
+ * 5. Activation is not absurdly far in the future
46
+ *
47
+ * Periodic re-validation:
48
+ * - If last online verification was > 30 days ago, attempts re-verify
49
+ * - If re-verify fails due to network, still valid (grace period)
50
+ * - If re-verify fails due to invalid key, invalidates
51
+ */
52
+ export async function hasValidLicense() {
53
+ try {
54
+ const license = await loadLicense();
55
+ if (!license)
56
+ return false;
57
+ // Signature check (tamper detection)
58
+ if (!verifySignature(license)) {
59
+ return false;
60
+ }
61
+ // Machine binding check
62
+ if (license.machineId !== getMachineFingerprint()) {
63
+ return false;
64
+ }
65
+ // Key format sanity
66
+ if (!isValidKeyFormat(license.key)) {
67
+ return false;
68
+ }
69
+ // Activation date sanity (not in the future)
70
+ const activated = new Date(license.activatedAt);
71
+ if (activated.getTime() > Date.now() + 86400000) {
72
+ return false;
73
+ }
74
+ // Periodic re-validation (every 30 days)
75
+ const lastVerified = new Date(license.lastVerifiedAt);
76
+ const daysSinceVerify = (Date.now() - lastVerified.getTime()) / 86400000;
77
+ if (daysSinceVerify > 30) {
78
+ // Try to re-verify online, but don't block on failure
79
+ const revalidated = await revalidateOnline(license);
80
+ if (revalidated === 'invalid') {
81
+ // Key was explicitly rejected by Gumroad (refunded, disabled, etc.)
82
+ await removeLicense();
83
+ return false;
84
+ }
85
+ // 'valid' or 'network_error' — both count as OK (grace period)
86
+ if (revalidated === 'valid') {
87
+ await updateLastVerified(license);
88
+ }
89
+ }
90
+ return true;
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ }
96
+ /** Require a valid license or exit with purchase instructions */
97
+ export async function requireLicense(commandName) {
98
+ const valid = await hasValidLicense();
99
+ if (!valid) {
100
+ const chalk = (await import('chalk')).default;
101
+ console.log('');
102
+ console.log(chalk.yellow(`⚠ The "${commandName}" command requires LPC Forge Premium.`));
103
+ console.log('');
104
+ console.log(chalk.white(' Purchase for $10: ') + chalk.cyan.underline('https://launchday.gumroad.com/l/lpc-forge-premium'));
105
+ console.log(chalk.white(' Then activate: ') + chalk.green('lpc-forge activate <your-license-key>'));
106
+ console.log('');
107
+ console.log(chalk.gray(' Free commands: character, batch, list, map, init (without --full)'));
108
+ console.log('');
109
+ process.exit(1);
110
+ }
111
+ }
112
+ // ─── Key Format ───────────────────────────────────────────────────────
113
+ function isValidKeyFormat(key) {
114
+ // Gumroad format: XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX (hex)
115
+ return /^[A-F0-9]{8}-[A-F0-9]{8}-[A-F0-9]{8}-[A-F0-9]{8}$/i.test(key);
116
+ }
117
+ // ─── Online Verification ──────────────────────────────────────────────
118
+ async function revalidateOnline(license) {
119
+ try {
120
+ const response = await fetch('https://api.gumroad.com/v2/licenses/verify', {
121
+ method: 'POST',
122
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
123
+ body: new URLSearchParams({
124
+ product_id: process.env.LPC_FORGE_PRODUCT_ID ?? '-2jxD5LR4p_tXnvxMiWU7g==',
125
+ license_key: license.key,
126
+ increment_uses_count: 'false', // Don't increment on re-validation
127
+ }),
128
+ signal: AbortSignal.timeout(10000),
129
+ });
130
+ const data = (await response.json());
131
+ if (data.success)
132
+ return 'valid';
133
+ // Check if explicitly rejected (refunded/disabled) vs just error
134
+ const msg = String(data.message ?? '').toLowerCase();
135
+ if (msg.includes('not found') || msg.includes('disabled') || msg.includes('refund')) {
136
+ return 'invalid';
137
+ }
138
+ return 'network_error';
139
+ }
140
+ catch {
141
+ return 'network_error';
142
+ }
143
+ }
144
+ // ─── File Operations ──────────────────────────────────────────────────
145
+ async function loadLicense() {
146
+ try {
147
+ const raw = await readFile(LICENSE_FILE, 'utf-8');
148
+ const data = JSON.parse(raw);
149
+ if (!data.key || !data.signature || !data.machineId)
150
+ return null;
151
+ return data;
152
+ }
153
+ catch {
154
+ return null;
155
+ }
156
+ }
157
+ async function storeLicense(license) {
158
+ const stored = { ...license, _v: 2 };
159
+ await mkdir(LICENSE_DIR, { recursive: true });
160
+ await writeFile(LICENSE_FILE, JSON.stringify(stored, null, 2), { mode: 0o600 });
161
+ }
162
+ async function updateLastVerified(license) {
163
+ const updated = {
164
+ ...license,
165
+ lastVerifiedAt: new Date().toISOString(),
166
+ signature: '', // Will be re-signed
167
+ };
168
+ updated.signature = signLicense(updated);
169
+ await storeLicense(updated);
170
+ }
171
+ async function removeLicense() {
172
+ try {
173
+ await unlink(LICENSE_FILE);
174
+ }
175
+ catch {
176
+ // Doesn't exist, that's fine
177
+ }
178
+ }
179
+ // ─── Public API ───────────────────────────────────────────────────────
180
+ /** Get stored license info (for display only) */
181
+ export async function getLicenseInfo() {
182
+ const license = await loadLicense();
183
+ if (!license)
184
+ return null;
185
+ const valid = verifySignature(license) && license.machineId === getMachineFingerprint();
186
+ return {
187
+ key: license.key.slice(0, 8) + '-****-****-' + license.key.slice(-8),
188
+ email: license.email,
189
+ activatedAt: license.activatedAt,
190
+ lastVerifiedAt: license.lastVerifiedAt,
191
+ valid,
192
+ };
193
+ }
194
+ /** Activate a license key */
195
+ export async function activateLicense(licenseKey) {
196
+ // Format check
197
+ if (!isValidKeyFormat(licenseKey)) {
198
+ return {
199
+ success: false,
200
+ message: 'Invalid key format. Expected: XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX',
201
+ };
202
+ }
203
+ // Try online verification first
204
+ try {
205
+ const response = await fetch('https://api.gumroad.com/v2/licenses/verify', {
206
+ method: 'POST',
207
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
208
+ body: new URLSearchParams({
209
+ product_id: process.env.LPC_FORGE_PRODUCT_ID ?? '-2jxD5LR4p_tXnvxMiWU7g==',
210
+ license_key: licenseKey,
211
+ increment_uses_count: 'true',
212
+ }),
213
+ signal: AbortSignal.timeout(15000),
214
+ });
215
+ const data = (await response.json());
216
+ if (!data.success) {
217
+ return {
218
+ success: false,
219
+ message: data.message ?? 'License key rejected by server.',
220
+ };
221
+ }
222
+ const purchase = data.purchase;
223
+ const now = new Date().toISOString();
224
+ const machineId = getMachineFingerprint();
225
+ const licenseData = {
226
+ key: licenseKey,
227
+ email: purchase?.email ?? 'unknown',
228
+ product: 'lpc-forge-premium',
229
+ activatedAt: now,
230
+ lastVerifiedAt: now,
231
+ machineId,
232
+ };
233
+ const license = {
234
+ ...licenseData,
235
+ signature: signLicense(licenseData),
236
+ };
237
+ await storeLicense(license);
238
+ return {
239
+ success: true,
240
+ message: 'License activated successfully!',
241
+ };
242
+ }
243
+ catch (err) {
244
+ // Offline activation — allow but mark as unverified
245
+ const now = new Date().toISOString();
246
+ const machineId = getMachineFingerprint();
247
+ // Set lastVerifiedAt to epoch so it triggers online check on first use
248
+ const licenseData = {
249
+ key: licenseKey,
250
+ email: 'offline-activation',
251
+ product: 'lpc-forge-premium',
252
+ activatedAt: now,
253
+ lastVerifiedAt: new Date(0).toISOString(),
254
+ machineId,
255
+ };
256
+ const license = {
257
+ ...licenseData,
258
+ signature: signLicense(licenseData),
259
+ };
260
+ await storeLicense(license);
261
+ return {
262
+ success: true,
263
+ message: 'License stored (offline — will verify online on next use).',
264
+ };
265
+ }
266
+ }
267
+ /** Deactivate the stored license */
268
+ export async function deactivateLicense() {
269
+ await removeLicense();
270
+ }
271
+ //# sourceMappingURL=license.js.map
@@ -0,0 +1,3 @@
1
+ import type { CellularConfig, GeneratedMap } from './types.js';
2
+ /** Generate a cave map using cellular automata */
3
+ export declare function generateCave(config: CellularConfig): GeneratedMap;
@@ -0,0 +1,191 @@
1
+ import { SeededRNG } from '../utils/rng.js';
2
+ import { TileType as TT } from './types.js';
3
+ const DEFAULT_BIRTH = 4;
4
+ const DEFAULT_DEATH = 3;
5
+ const DEFAULT_ITERATIONS = 5;
6
+ const DEFAULT_DENSITY = 0.45;
7
+ /** Generate a cave map using cellular automata */
8
+ export function generateCave(config) {
9
+ const { width, height, seed = Date.now(), birthLimit = DEFAULT_BIRTH, deathLimit = DEFAULT_DEATH, iterations = DEFAULT_ITERATIONS, initialDensity = DEFAULT_DENSITY, } = config;
10
+ const rng = new SeededRNG(seed);
11
+ // Initialize grid randomly
12
+ let grid = Array.from({ length: height }, () => Array.from({ length: width }, () => rng.random() < initialDensity));
13
+ // Force edges to be walls
14
+ for (let y = 0; y < height; y++) {
15
+ grid[y][0] = true;
16
+ grid[y][width - 1] = true;
17
+ }
18
+ for (let x = 0; x < width; x++) {
19
+ grid[0][x] = true;
20
+ grid[height - 1][x] = true;
21
+ }
22
+ // Run cellular automata iterations
23
+ for (let i = 0; i < iterations; i++) {
24
+ grid = step(grid, width, height, birthLimit, deathLimit);
25
+ }
26
+ // Find connected regions using flood fill
27
+ const regionMap = new Int32Array(width * height).fill(-1);
28
+ const regions = [];
29
+ let regionId = 0;
30
+ for (let y = 1; y < height - 1; y++) {
31
+ for (let x = 1; x < width - 1; x++) {
32
+ if (!grid[y][x] && regionMap[y * width + x] === -1) {
33
+ const cells = floodFill(grid, regionMap, x, y, width, height, regionId);
34
+ regions.push({ id: regionId, cells });
35
+ regionId++;
36
+ }
37
+ }
38
+ }
39
+ // Keep the largest region, or connect the largest ones
40
+ if (regions.length > 1) {
41
+ regions.sort((a, b) => b.cells.length - a.cells.length);
42
+ // Connect secondary regions to the main region via tunnels
43
+ const main = regions[0];
44
+ for (let i = 1; i < Math.min(regions.length, 5); i++) {
45
+ connectRegions(grid, main.cells, regions[i].cells, rng);
46
+ }
47
+ // Fill remaining small isolated regions
48
+ for (let i = 5; i < regions.length; i++) {
49
+ for (const cell of regions[i].cells) {
50
+ grid[cell.y][cell.x] = true;
51
+ }
52
+ }
53
+ }
54
+ // Convert to tile types
55
+ const tiles = grid.map((row) => row.map((wall) => (wall ? TT.WALL : TT.FLOOR)));
56
+ // Add water pools in dead-end areas
57
+ addWaterPools(tiles, rng, width, height);
58
+ // Find spawn and exit points
59
+ const floorCells = [];
60
+ for (let y = 1; y < height - 1; y++) {
61
+ for (let x = 1; x < width - 1; x++) {
62
+ if (tiles[y][x] === TT.FLOOR) {
63
+ floorCells.push({ x, y });
64
+ }
65
+ }
66
+ }
67
+ const spawnPoint = floorCells.length > 0 ? floorCells[0] : undefined;
68
+ const exitPoint = floorCells.length > 1 ? floorCells[floorCells.length - 1] : undefined;
69
+ // Create pseudo-rooms from connected areas
70
+ const rooms = regions.slice(0, 5).map((r, i) => {
71
+ const minX = Math.min(...r.cells.map((c) => c.x));
72
+ const minY = Math.min(...r.cells.map((c) => c.y));
73
+ const maxX = Math.max(...r.cells.map((c) => c.x));
74
+ const maxY = Math.max(...r.cells.map((c) => c.y));
75
+ return {
76
+ id: i,
77
+ x: minX,
78
+ y: minY,
79
+ width: maxX - minX + 1,
80
+ height: maxY - minY + 1,
81
+ connections: [],
82
+ };
83
+ });
84
+ return { width, height, tiles, rooms, seed, pois: [], spawnPoint, exitPoint };
85
+ }
86
+ function step(grid, width, height, birthLimit, deathLimit) {
87
+ const next = Array.from({ length: height }, () => Array(width).fill(false));
88
+ for (let y = 0; y < height; y++) {
89
+ for (let x = 0; x < width; x++) {
90
+ // Edges are always walls
91
+ if (y === 0 || y === height - 1 || x === 0 || x === width - 1) {
92
+ next[y][x] = true;
93
+ continue;
94
+ }
95
+ const neighbors = countNeighbors(grid, x, y, width, height);
96
+ if (grid[y][x]) {
97
+ // Alive cell: stays alive if enough neighbors
98
+ next[y][x] = neighbors >= deathLimit;
99
+ }
100
+ else {
101
+ // Dead cell: becomes alive if enough neighbors
102
+ next[y][x] = neighbors >= birthLimit;
103
+ }
104
+ }
105
+ }
106
+ return next;
107
+ }
108
+ function countNeighbors(grid, x, y, width, height) {
109
+ let count = 0;
110
+ for (let dy = -1; dy <= 1; dy++) {
111
+ for (let dx = -1; dx <= 1; dx++) {
112
+ if (dx === 0 && dy === 0)
113
+ continue;
114
+ const nx = x + dx;
115
+ const ny = y + dy;
116
+ if (nx < 0 || nx >= width || ny < 0 || ny >= height) {
117
+ count++; // Out of bounds counts as wall
118
+ }
119
+ else if (grid[ny][nx]) {
120
+ count++;
121
+ }
122
+ }
123
+ }
124
+ return count;
125
+ }
126
+ function floodFill(grid, regionMap, startX, startY, width, height, regionId) {
127
+ const cells = [];
128
+ const stack = [[startX, startY]];
129
+ while (stack.length > 0) {
130
+ const [x, y] = stack.pop();
131
+ if (x < 0 || x >= width || y < 0 || y >= height)
132
+ continue;
133
+ if (grid[y][x])
134
+ continue;
135
+ if (regionMap[y * width + x] !== -1)
136
+ continue;
137
+ regionMap[y * width + x] = regionId;
138
+ cells.push({ x, y });
139
+ stack.push([x + 1, y], [x - 1, y], [x, y + 1], [x, y - 1]);
140
+ }
141
+ return cells;
142
+ }
143
+ function connectRegions(grid, a, b, rng) {
144
+ // Find closest pair of cells between regions
145
+ const cellA = rng.pick(a);
146
+ let bestB = b[0];
147
+ let bestDist = Infinity;
148
+ for (const cb of b) {
149
+ const dist = Math.abs(cb.x - cellA.x) + Math.abs(cb.y - cellA.y);
150
+ if (dist < bestDist) {
151
+ bestDist = dist;
152
+ bestB = cb;
153
+ }
154
+ }
155
+ // Carve tunnel between them
156
+ let x = cellA.x;
157
+ let y = cellA.y;
158
+ while (x !== bestB.x || y !== bestB.y) {
159
+ if (x !== bestB.x) {
160
+ x += x < bestB.x ? 1 : -1;
161
+ }
162
+ else {
163
+ y += y < bestB.y ? 1 : -1;
164
+ }
165
+ if (y > 0 && y < grid.length - 1 && x > 0 && x < grid[0].length - 1) {
166
+ grid[y][x] = false;
167
+ }
168
+ }
169
+ }
170
+ function addWaterPools(tiles, rng, width, height) {
171
+ const poolCount = rng.randomInt(1, 3);
172
+ for (let i = 0; i < poolCount; i++) {
173
+ const cx = rng.randomInt(5, width - 5);
174
+ const cy = rng.randomInt(5, height - 5);
175
+ const radius = rng.randomInt(2, 4);
176
+ for (let dy = -radius; dy <= radius; dy++) {
177
+ for (let dx = -radius; dx <= radius; dx++) {
178
+ if (dx * dx + dy * dy > radius * radius)
179
+ continue;
180
+ const ty = cy + dy;
181
+ const tx = cx + dx;
182
+ if (ty > 0 && ty < height - 1 && tx > 0 && tx < width - 1) {
183
+ if (tiles[ty][tx] === TT.FLOOR) {
184
+ tiles[ty][tx] = TT.WATER;
185
+ }
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+ //# sourceMappingURL=cellular.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cellular.js","sourceRoot":"","sources":["../../src/map/cellular.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DungeonConfig, GeneratedMap } from './types.js';
2
+ /** Generate a dungeon using BSP (Binary Space Partition) */
3
+ export declare function generateDungeon(config: DungeonConfig): GeneratedMap;