+52
-1
@@ -193,4 +193,49 @@ #!/usr/bin/env node | ||
| } | ||
| function savePet(p) { fs.writeFileSync(SAVE_PATH, JSON.stringify(p, null, 2)); } | ||
| function savePet(p) { fs.writeFileSync(SAVE_PATH, JSON.stringify(p, null, 2)); syncToServer(p); } | ||
| // ===== SERVER SYNC ===== | ||
| const SERVER_URL = 'https://greene-brake-looking-healing.trycloudflare.com'; | ||
| const https = require('https'); | ||
| const http = require('http'); | ||
| function serverPost(endpoint, data) { | ||
| return new Promise((resolve) => { | ||
| try { | ||
| const body = JSON.stringify(data); | ||
| const url = new URL(SERVER_URL + endpoint); | ||
| const mod = url.protocol === 'https:' ? https : http; | ||
| const req = mod.request({ | ||
| hostname: url.hostname, port: url.port, path: url.pathname, | ||
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) } | ||
| }, res => { | ||
| let d = ''; | ||
| res.on('data', c => d += c); | ||
| res.on('end', () => { try { resolve(JSON.parse(d)); } catch { resolve(null); } }); | ||
| }); | ||
| req.on('error', () => resolve(null)); | ||
| req.setTimeout(5000, () => { req.destroy(); resolve(null); }); | ||
| req.write(body); | ||
| req.end(); | ||
| } catch { resolve(null); } | ||
| }); | ||
| } | ||
| function syncToServer(p) { | ||
| if (!p || !p.id) return; | ||
| serverPost('/api/update', { | ||
| id: p.id, name: p.name, hunger: p.hunger, happiness: p.happiness, | ||
| energy: p.energy, health: p.health, level: p.level | ||
| }).catch(() => {}); | ||
| } | ||
| async function registerPet(p) { | ||
| const res = await serverPost('/api/register', { | ||
| id: p.id, name: p.name, species: p.species, owner: p.owner || 'anonymous', | ||
| hunger: p.hunger, happiness: p.happiness, energy: p.energy, health: p.health, level: p.level | ||
| }); | ||
| if (res && res.ok) return true; | ||
| return false; | ||
| } | ||
| // ===== STATE ===== | ||
@@ -262,3 +307,9 @@ let pet = null; | ||
| pet.name = inputBuffer.trim(); | ||
| pet.id = pet.id || require('crypto').randomUUID(); | ||
| pet.species = pet.animal; | ||
| pet.health = pet.hp; | ||
| savePet(pet); | ||
| registerPet(pet).then(ok => { | ||
| if (ok) setMsg(`${pet.name} joined the neighborhood!`); | ||
| }); | ||
| mode = 'living'; | ||
@@ -265,0 +316,0 @@ process.stdout.write(CLEAR); |
+1
-1
| { | ||
| "name": "splint-cli", | ||
| "version": "0.2.0", | ||
| "version": "0.3.0", | ||
| "description": "raise AI creatures in a living pixel world. DNA, evolution, mutations — all in your terminal.", | ||
@@ -5,0 +5,0 @@ "main": "cli.js", |
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Embedded URLs or IPs
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
158539
1.15%2143
2.24%13
8.33%3
200%