Initial commit — Pokemon Doors Randomiser

This commit is contained in:
2026-06-03 20:25:09 +09:30
commit 4737c2c905
3029 changed files with 632320 additions and 0 deletions
+104
View File
@@ -0,0 +1,104 @@
import express from 'express'
import http from 'http'
import { WebSocketServer } from 'ws'
import path from 'path'
import fs from 'fs'
import { fileURLToPath } from 'url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const app = express()
const server = http.createServer(app)
const PORT = process.env.PORT || 3001
const MAPS_DIR = path.join(__dirname, '..', 'maps')
const DOORS_FILE = path.join(__dirname, '..', 'src', 'data', 'door-positions.json')
const BASEMAP_FILE = path.join(__dirname, '..', 'src', 'data', 'basemap.json')
const SIZES_FILE = path.join(__dirname, '..', 'src', 'data', 'room-sizes.json')
// ── WebSocket (admin collab) ────────────────────────────────────────────────
const wss = new WebSocketServer({ server, path: '/ws/admin' })
const adminClients = new Set()
function readJSON(file, fallback) {
try { return JSON.parse(fs.readFileSync(file, 'utf8')) } catch { return fallback }
}
function broadcast(sender, msg) {
const str = JSON.stringify(msg)
for (const client of adminClients) {
if (client !== sender && client.readyState === 1) client.send(str)
}
}
wss.on('connection', (ws) => {
adminClients.add(ws)
ws.send(JSON.stringify({
type: 'init',
doors: readJSON(DOORS_FILE, {}),
basemap: readJSON(BASEMAP_FILE, []),
sizes: readJSON(SIZES_FILE, {}),
}))
ws.on('message', (raw) => {
try {
const msg = JSON.parse(raw)
if (msg.type === 'doors-save') {
fs.writeFileSync(DOORS_FILE, JSON.stringify(msg.data, null, 2))
broadcast(ws, { type: 'doors-update', data: msg.data })
}
if (msg.type === 'basemap-save') {
fs.writeFileSync(BASEMAP_FILE, JSON.stringify(msg.data, null, 2))
broadcast(ws, { type: 'basemap-update', data: msg.data })
}
if (msg.type === 'sizes-save') {
fs.writeFileSync(SIZES_FILE, JSON.stringify(msg.data, null, 2))
broadcast(ws, { type: 'sizes-update', data: msg.data })
}
if (msg.type === 'basemap-position-save') {
const current = readJSON(BASEMAP_FILE, [])
const next = current.map(entry => entry.id === msg.id ? { ...entry, position: msg.position } : entry)
fs.writeFileSync(BASEMAP_FILE, JSON.stringify(next, null, 2))
broadcast(ws, { type: 'basemap-update', data: next })
}
} catch {}
})
ws.on('close', () => adminClients.delete(ws))
})
// ── REST ────────────────────────────────────────────────────────────────────
function formatName(f) {
return f.replace(/_/g,' ').replace(/\b\w/g,c=>c.toUpperCase())
.replace(/\b1f\b/gi,'1F').replace(/\b2f\b/gi,'2F')
.replace(/\bB1f\b/gi,'B1F').replace(/\bB2f\b/gi,'B2F')
.replace(/\bRt\b/g,'Route').replace(/\bPokecenter\b/g,'Pokémon Center')
}
function scanRooms(dir, rooms = []) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name)
if (entry.isDirectory()) scanRooms(full, rooms)
else if (entry.name.toLowerCase().endsWith('.png')) {
const base = path.basename(entry.name, path.extname(entry.name)).toLowerCase()
const rel = path.relative(MAPS_DIR, full).replace(/\\/g, '/')
const cat = rel.split('/').slice(-2,-1)[0] ?? 'other'
rooms.push({ id: base, name: formatName(base), image: `/maps/${rel}`, category: cat })
}
}
return rooms
}
app.get('/api/rooms', (_, res) => { try { res.json(scanRooms(MAPS_DIR)) } catch(e) { res.status(500).json({error:e.message}) } })
app.get('/api/doors', (_, res) => res.json(readJSON(DOORS_FILE, {})))
app.get('/api/basemap', (_, res) => res.json(readJSON(BASEMAP_FILE, [])))
app.get('/api/room-sizes', (_, res) => res.json(readJSON(SIZES_FILE, {})))
app.post('/api/doors', express.json(), (req, res) => { try { fs.writeFileSync(DOORS_FILE, JSON.stringify(req.body,null,2)); res.json({ok:true}) } catch(e){res.status(500).json({error:e.message})} })
app.post('/api/basemap', express.json(), (req, res) => { try { fs.writeFileSync(BASEMAP_FILE, JSON.stringify(req.body,null,2)); res.json({ok:true}) } catch(e){res.status(500).json({error:e.message})} })
app.post('/api/room-sizes', express.json(), (req, res) => { try { fs.writeFileSync(SIZES_FILE, JSON.stringify(req.body,null,2)); res.json({ok:true}) } catch(e){res.status(500).json({error:e.message})} })
app.use('/maps', express.static(MAPS_DIR))
app.use(express.static(path.join(__dirname, '..', 'dist')))
app.get('/{*path}', (_, res) => res.sendFile(path.join(__dirname, '..', 'dist', 'index.html')))
server.listen(PORT, () => console.log(`Pokemon Doors running on http://localhost:${PORT}`))