|
|
|
@ -4,8 +4,8 @@ dotenv.config(); |
|
|
|
import express from 'express'; |
|
|
|
import { Request, Response, NextFunction } from 'express'; |
|
|
|
import cors from 'cors'; |
|
|
|
import { open, Database } from 'sqlite'; |
|
|
|
import sqlite3 from 'sqlite3'; |
|
|
|
import { open } from 'sqlite'; |
|
|
|
import jwt from 'jsonwebtoken'; |
|
|
|
import bcrypt from 'bcrypt'; |
|
|
|
import fs from 'fs/promises'; |
|
|
|
@ -313,123 +313,156 @@ interface PokemonFamilyEntry { |
|
|
|
Any?: number; |
|
|
|
Male?: number; |
|
|
|
Female?: number; |
|
|
|
evolve_to_augmented?: PokemonEntry[] |
|
|
|
breed_for_augmented?: PokemonEntry[] |
|
|
|
} |
|
|
|
|
|
|
|
interface PokemonEntry { |
|
|
|
pfic: string |
|
|
|
name: string |
|
|
|
} |
|
|
|
|
|
|
|
const getDbConnection = async (): Promise<Database<sqlite3.Database, sqlite3.Statement>> => { |
|
|
|
return open({ |
|
|
|
filename: './pokemon_forms.db', // Adjust path to your database file
|
|
|
|
driver: sqlite3.Database |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
app.get('/api/plan', authenticateToken, async (req: AuthRequest, res: Response) => { |
|
|
|
let db: Database<sqlite3.Database, sqlite3.Statement> | null = null; |
|
|
|
try { |
|
|
|
// Get the Pokemon database connection
|
|
|
|
db = await getDbConnection(); |
|
|
|
|
|
|
|
// Read the efficiency plan file
|
|
|
|
const planData = await fs.readFile( |
|
|
|
path.join(__dirname, '../plan.json'), |
|
|
|
'utf-8' |
|
|
|
); |
|
|
|
const efficiencyPlan: GamePlan[] = JSON.parse(planData); |
|
|
|
efficiencyPlan.forEach((game_plan) => { |
|
|
|
for (const key in game_plan["pokemon"]) { |
|
|
|
game_plan["pokemon"][key]["family_pfic"] = key; |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
// Get the Pokemon database connection
|
|
|
|
const db = await open({ |
|
|
|
filename: '../pokemon_forms.db', |
|
|
|
driver: sqlite3.Database |
|
|
|
}); |
|
|
|
// Loop through each game plan
|
|
|
|
for (let i = 0; i < efficiencyPlan.length; i++) { |
|
|
|
const game_plan = efficiencyPlan[i]; |
|
|
|
for (const key in game_plan.pokemon) { |
|
|
|
if (Object.hasOwnProperty.call(game_plan.pokemon, key)) { |
|
|
|
const pokemonFamily: PokemonFamilyEntry = game_plan.pokemon[key]; |
|
|
|
pokemonFamily.family_pfic = key; |
|
|
|
|
|
|
|
// Get user's caught Pokemon
|
|
|
|
const userDb = await userDbPromise; |
|
|
|
const caughtPokemon = await userDb.all( |
|
|
|
'SELECT pfic FROM caught_pokemon WHERE user_id = ?', |
|
|
|
[req.user.id] |
|
|
|
); |
|
|
|
const caughtPfics = new Set(caughtPokemon.map(p => p.pfic)); |
|
|
|
// Merge evolve_to into pfics array
|
|
|
|
const pfics: string[] = pokemonFamily.evolve_to.concat(pokemonFamily.evolve_to); |
|
|
|
|
|
|
|
// Helper function to get evolution methods
|
|
|
|
async function getEvolutionMethods(fromPfic: string, toPfic: string) { |
|
|
|
// Try direct evolution first
|
|
|
|
const direct = await db.get(` |
|
|
|
SELECT method, to_pfic |
|
|
|
FROM evolution_chains |
|
|
|
WHERE from_pfic = ? AND to_pfic = ? |
|
|
|
`, [fromPfic, toPfic]);
|
|
|
|
// Loop through pfics to get details from the database
|
|
|
|
for (let j = 0; j < pfics.length; j++) { |
|
|
|
const pkmn: string = pfics[j]; |
|
|
|
|
|
|
|
if (direct) { |
|
|
|
return [direct.method]; |
|
|
|
try { |
|
|
|
const details = await db.get<{ PFIC: string; data: string }>( |
|
|
|
`SELECT * FROM pokemon_forms WHERE PFIC = ?`, |
|
|
|
pkmn |
|
|
|
); |
|
|
|
|
|
|
|
if (!details) { |
|
|
|
console.log("Details not found for PFIC:", pkmn); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
// Try indirect evolution path
|
|
|
|
const methods = await db.all(` |
|
|
|
WITH RECURSIVE evolution_path AS ( |
|
|
|
SELECT from_pfic, to_pfic, method, 1 as depth |
|
|
|
FROM evolution_chains |
|
|
|
WHERE from_pfic = ? |
|
|
|
const data = JSON.parse(details.data); |
|
|
|
const pokemon = { |
|
|
|
pfic: details.PFIC, |
|
|
|
data: data, |
|
|
|
}; |
|
|
|
|
|
|
|
if (!pokemonFamily.evolve_to_augmented) { |
|
|
|
pokemonFamily.evolve_to_augmented = []; |
|
|
|
} |
|
|
|
|
|
|
|
UNION ALL |
|
|
|
const entry = { |
|
|
|
pfic: key, |
|
|
|
name: pokemon.data.name, |
|
|
|
}; |
|
|
|
|
|
|
|
SELECT e.from_pfic, e.to_pfic, e.method, ep.depth + 1 |
|
|
|
FROM evolution_chains e |
|
|
|
JOIN evolution_path ep ON e.from_pfic = ep.to_pfic |
|
|
|
WHERE ep.depth < 3 |
|
|
|
) |
|
|
|
SELECT method |
|
|
|
FROM evolution_path |
|
|
|
WHERE to_pfic = ? |
|
|
|
ORDER BY depth; |
|
|
|
`, [fromPfic, toPfic]);
|
|
|
|
pokemonFamily.evolve_to_augmented.push(entry); |
|
|
|
|
|
|
|
if (methods && methods.length > 0) { |
|
|
|
return methods.map(m => m.method); |
|
|
|
} catch (err) { |
|
|
|
console.error(`Error fetching details for PFIC ${pkmn}:`, err); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
res.json(efficiencyPlan); |
|
|
|
|
|
|
|
return ['Evolution']; |
|
|
|
} catch (err) { |
|
|
|
console.error('Error loading efficiency plan:', err); |
|
|
|
res.status(500).json({ error: 'Internal server error' }); |
|
|
|
} finally { |
|
|
|
if (db) { |
|
|
|
await db.close(); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const debug_pfic = "0010-01-000-0"; |
|
|
|
// Enhance the plan with evolution methods and account for caught Pokemon
|
|
|
|
/* |
|
|
|
for (const game of efficiencyPlan) { |
|
|
|
for (const pokemon of game.pokemon.keys()) { |
|
|
|
// Set initial catch count
|
|
|
|
pokemon.catch_count = 1; |
|
|
|
if (pokemon.pfic === debug_pfic) { |
|
|
|
console.log(`pokemon: ${pokemon.name} - ${pokemon.catch_count}`); |
|
|
|
} |
|
|
|
app.get('/api/plan', authenticateToken, async (req: AuthRequest, res: Response) => { |
|
|
|
try { |
|
|
|
// Get the Pokemon database connection
|
|
|
|
const db = await dbPromise; |
|
|
|
|
|
|
|
// Add evolution targets to catch count
|
|
|
|
if (pokemon.evolve_to) { |
|
|
|
pokemon.catch_count += pokemon.evolve_to.length; |
|
|
|
if (pokemon.pfic === debug_pfic) { |
|
|
|
console.log(`pokemon: ${pokemon.name} - ${pokemon.catch_count}`); |
|
|
|
} |
|
|
|
// Read the efficiency plan file
|
|
|
|
const planData = await fs.readFile( |
|
|
|
path.join(__dirname, '../plan.json'), |
|
|
|
'utf-8' |
|
|
|
); |
|
|
|
const efficiencyPlan: GamePlan[] = JSON.parse(planData); |
|
|
|
for (let game_plan of efficiencyPlan){ |
|
|
|
for (const key in game_plan["pokemon"]) { |
|
|
|
//console.log(key)
|
|
|
|
game_plan["pokemon"][key]["family_pfic"] = key; |
|
|
|
let pfics = [] |
|
|
|
|
|
|
|
// Add evolution methods
|
|
|
|
for (const evolution of pokemon.evolve_to) { |
|
|
|
const methods = await getEvolutionMethods(pokemon.pfic, evolution.pfic); |
|
|
|
evolution.method = methods.join(' → '); |
|
|
|
//console.log(game_plan["pokemon"][key])
|
|
|
|
|
|
|
|
for (let pkmn of game_plan["pokemon"][key]["evolve_to"]) { |
|
|
|
pfics.push(pkmn) |
|
|
|
} |
|
|
|
for (let pkmn of game_plan["pokemon"][key]["evolve_to"]) { |
|
|
|
pfics.push(pkmn) |
|
|
|
} |
|
|
|
for (let pkmn of pfics) { |
|
|
|
console.log(pkmn) |
|
|
|
const details = await db.get(` |
|
|
|
SELECT * |
|
|
|
FROM pokemon_forms |
|
|
|
WHERE PFIC = ? |
|
|
|
`, pkmn);
|
|
|
|
|
|
|
|
// Reduce catch count for already caught Pokemon
|
|
|
|
if (caughtPfics.has(pokemon.pfic)) { |
|
|
|
pokemon.catch_count = Math.max(0, pokemon.catch_count - 1); |
|
|
|
if (pokemon.pfic === debug_pfic) { |
|
|
|
console.log(`B pokemon: ${pokemon.name} - ${pokemon.catch_count}`); |
|
|
|
} |
|
|
|
if(!details) { |
|
|
|
console.log("oh noes") |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
// Check evolution targets
|
|
|
|
if (pokemon.evolve_to) { |
|
|
|
for (const evolution of pokemon.evolve_to) { |
|
|
|
if (caughtPfics.has(evolution.pfic)) { |
|
|
|
pokemon.catch_count = Math.max(0, pokemon.catch_count - 1); |
|
|
|
if (pokemon.pfic === debug_pfic) { |
|
|
|
console.log(`C pokemon: ${pokemon.name} - ${pokemon.catch_count} (${evolution.pfic})`); |
|
|
|
const data = JSON.parse(details.data) |
|
|
|
const pokemon = { |
|
|
|
"pfic": details.PFIC, |
|
|
|
"data": data |
|
|
|
} |
|
|
|
|
|
|
|
if (!game_plan["pokemon"][key].evolve_to_augmented) { |
|
|
|
game_plan["pokemon"][key].evolve_to_augmented = [] |
|
|
|
} |
|
|
|
let entry = { |
|
|
|
pfic: key, |
|
|
|
name: pokemon.data.name |
|
|
|
} |
|
|
|
game_plan["pokemon"][key].evolve_to_augmented.push(entry) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
await db.close(); |
|
|
|
res.json(efficiencyPlan); |
|
|
|
@ -439,7 +472,7 @@ app.get('/api/plan', authenticateToken, async (req: AuthRequest, res: Response) |
|
|
|
res.status(500).json({ error: 'Internal server error' }); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
*/ |
|
|
|
// Update the caught Pokemon routes
|
|
|
|
app.get('/api/pokemon/caught', authenticateToken, (req: AuthRequest, res: Response) => { |
|
|
|
void userDbPromise.then(async (db) => { |
|
|
|
|