const express = require('express'); const sqlite3 = require('sqlite3').verbose(); const bcrypt = require('bcrypt'); const cors = require('cors'); const bodyParser = require('body-parser'); const crypto = require('crypto'); const app = express(); const port = 5000; // Middleware app.use(cors()); app.use(bodyParser.json()); // SQLite database setup const db = new sqlite3.Database('./database.db', (err) => { if (err) { console.error(err.message); } else { console.log('Connected to SQLite database.'); } }); // Create users table if it doesn't exist db.run(`CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE, email TEXT UNIQUE, password TEXT )`); // Create games table if it doesn't exist db.run(`CREATE TABLE IF NOT EXISTS games ( game_id TEXT PRIMARY KEY, name TEXT, description TEXT, game_master_id INTEGER, participants TEXT )`); //User Part // Registration route app.post('/register', async (req, res) => { const { username, email, password } = req.body; console.log("Trying to Register: ", username); try { const hashedPassword = await bcrypt.hash(password, 10); const stmt = db.prepare('INSERT INTO users (username, email, password) VALUES (?, ?, ?)'); stmt.run([username, email, hashedPassword], function (err) { if (err) { return res.status(400).json({ error: 'User already exists or invalid data.' }); } res.status(201).json({ message: 'User registered successfully!', userId: this.lastID }); }); stmt.finalize(); } catch (error) { res.status(500).json({ error: 'Internal server error' }); } }); // Login route app.post('/login', (req, res) => { const { username, password } = req.body; db.get('SELECT * FROM users WHERE username = ?', [username], async (err, row) => { if (err) { return res.status(500).json({ error: 'Internal server error' }); } if (!row || !(await bcrypt.compare(password, row.password))) { return res.status(400).json({ error: 'Invalid username or password.' }); } res.json({ success: true, message: 'Login successful!', userId: row.id }); }); }); // Game Part // Fetch games for a specific user app.get('/games/:userId', (req, res) => { const userId = req.params.userId; db.all( `SELECT * FROM games WHERE game_master_id = ? OR participants LIKE ?`, [userId, `%${userId}%`], (err, rows) => { if (err) { return res.status(500).json({ error: 'Internal server error' }); } res.json(rows); } ); }); // Join Game app.post('/joinGame/:gameId', (req, res) => { const gameId = req.params.gameId; const userId = req.body.userId; db.get('SELECT * FROM games WHERE game_id = ?', [gameId], (err, game) => { if (err) { return res.status(500).json({ error: 'Internal server error' }); } if (!game) { return res.status(404).json({ error: 'Game not found' }); } const participants = JSON.parse(game.participants); const gameMasterId = game.game_master_id; // Check if the user is already a participant or the game master if (gameMasterId === userId || participants.includes(userId)) { return res.status(400).json({ error: 'User is already a participant or the game master.' }); } participants.push(userId); const stmt = db.prepare('UPDATE games SET participants = ? WHERE game_id = ?'); stmt.run([JSON.stringify(participants), gameId], function (err) { if (err) { return res.status(400).json({ error: 'Failed to join game.' }); } res.status(201).json({ message: 'User joined game successfully!', gameId: gameId }); }); stmt.finalize(); }); }); // Create a new game app.post('/games', (req, res) => { const { name, description, gameMasterId, participants } = req.body; const stmt = db.prepare('INSERT INTO games (name, description, game_master_id, participants) VALUES (?, ?, ?, ?)'); stmt.run([name, description, gameMasterId, JSON.stringify(participants)], function (err) { if (err) { return res.status(400).json({ error: 'Failed to create game.' }); } res.status(201).json({ message: 'Game created successfully!', gameId: this.lastID }); }); stmt.finalize(); }); app.post('/createGame', (req, res) => { const { name, description, gameMasterId, participants } = req.body; const gameId = crypto.randomBytes(4).toString('hex'); const stmt = db.prepare('INSERT INTO games (game_id, name, description, game_master_id, participants) VALUES (?, ?, ?, ?, ?)'); stmt.run([gameId, name, description, gameMasterId, JSON.stringify(participants)], function (err) { if (err) { return res.status(400).json({ error: 'Failed to create game.' }); } res.status(201).json({ message: 'Game created successfully!', gameId: gameId }); }); stmt.finalize(); }); // Master Part // Fetch game Participant Characters app.get('/games/:gameId/playerchars', (req, res) => { const gameId = req.params.gameId; db.get('SELECT * FROM PlayerCharacter WHERE GameID = ?', [gameId], (err, row) => { if (err) { return res.status(500).json({ error: 'Internal server error' }); } res.json(row); }); }) // Fetch game NPCs app.get('/games/:gameId/npcs', (req, res) => { const gameId = req.params.gameId; db.get('SELECT * FROM NPC WHERE GameID = ?', [gameId], (err, row) => { if (err) { return res.status(500).json({ error: 'Internal server error' }); } res.json(row); }); }) // Fetch game Items app.get('/games/:gameId/items', (req, res) => { const gameId = req.params.gameId; db.get('SELECT * FROM Item WHERE GameID = ?', [gameId], (err, row) => { if (err) { return res.status(500).json({ error: 'Internal server error' }); } res.json(row); }); }) // Player Part // Fetch all Player Characters of Player app.get('/games/:userId/characters', (req, res) => { const userId = req.params.userId; db.all('SELECT * FROM PlayerCharacter WHERE PlayerId = ?', [userId], (err, rows) => { if (err) { return res.status(500).json({ error: 'Internal server error' }); } res.json(rows); }); }); // Fetch Player Character app.get('/games/:gameId/:userId/character', (req, res) => { const gameId = req.params.gameId; const userId = req.params.userId; console.log(`Fetching character for gameId: ${gameId}, userId: ${userId}`); // Debug output db.get('SELECT * FROM PlayerCharacter WHERE GameID = ? AND PlayerID = ?', [gameId, userId], (err, row) => { if (err) { console.error('Database error:', err); // Debug output return res.status(500).json({ error: 'Internal server error' }); } if (!row) { console.log('No character found'); // Debug output return res.status(404).json({ error: 'No character found' }); } console.log('Character found:', row); // Debug output res.json(row); }); }); // Update Player Character Description app.put('/games/:gameId/:userId/character', (req, res) => { const gameId = req.params.gameId; const userId = req.params.userId; const { description } = req.body; const stmt = db.prepare('UPDATE PlayerCharacter SET description = ? WHERE GameID = ? AND PlayerID = ?'); stmt.run([description, gameId, userId], function (err) { if (err) { console.error('Database error:', err); // Debug output return res.status(500).json({ error: 'Internal server error' }); } res.json({ message: 'Description updated successfully!' }); }); stmt.finalize(); }); // Fetch Player Items app.get('/games/:gameId/:charId/items', (req, res) => { const gameId = req.params.gameId; const charId = req.params.charId; console.log(`Fetching Items for GameID: ${gameId}, CharID: ${charId}`); db.all('SELECT * FROM Item WHERE GameID = ? AND OwnerID = ?', [gameId, charId], (err, rows) => { if (err) { console.error('Database error:', err); // Debug output return res.status(500).json({ error: 'Internal server error' }); } console.log(rows); // Debug output res.json(rows); }); }); // Item Part // Set Item Owner app.post('/games/:charId/:itemId/owner', (req, res) => { const gameId = req.params.gameId; const itemId = req.params.itemId; const ownerId = req.body.ownerId; db.run('UPDATE Item SET OwnerID = ? WHERE ItemID = ?', [ownerId, gameId, itemId], function (err) { if (err) { return res.status(400).json({ error: 'Failed to update item owner.' }); } res.json({ message: 'Item owner updated successfully!' }); }); }) // Start the server app.listen(port, () => { console.log(`Server running on http://localhost:${port}`); });