Änderung: Anpassung der TaxiHighscore-API und Verbesserung der Highscore-Anzeige im Taxi-Spiel

Änderungen:
- Umbenennung des API-Endpunkts für Highscores von `/api/taxi/highscore` zu `/api/taxi/highscores`.
- Anpassung der Highscore-Datenstruktur zur Verwendung von `hashedUserId` anstelle von `userId`.
- Erweiterung der Router-Logik zur besseren Organisation der Highscore-Abfragen.
- Implementierung einer neuen Highscore-Anzeige im Spiel, die die Top 20 Spieler und den aktuellen Spieler anzeigt.

Diese Anpassungen verbessern die API-Konsistenz und erweitern die Benutzeroberfläche für die Highscore-Anzeige im Spiel.
This commit is contained in:
Torsten Schulz (local)
2025-10-05 12:42:37 +02:00
parent 42349e46c8
commit 1bde46430b
6 changed files with 345 additions and 43 deletions

View File

@@ -44,7 +44,7 @@ app.use('/api/admin', adminRouter);
app.use('/api/match3', match3Router);
app.use('/api/taxi', taxiRouter);
app.use('/api/taxi-maps', taxiMapRouter);
app.use('/api/taxi/highscore', taxiHighscoreRouter);
app.use('/api/taxi/highscores', taxiHighscoreRouter);
app.use('/images', express.static(path.join(__dirname, '../frontend/public/images')));
app.use('/api/contact', contactRouter);
app.use('/api/socialnetwork', socialnetworkRouter);

View File

@@ -17,7 +17,7 @@ class TaxiHighscoreController {
}
const highscoreData = {
userId: parseInt(userId),
hashedUserId: userId, // userId ist bereits ein String (Hash)
nickname,
passengersDelivered: parseInt(passengersDelivered),
playtime: parseInt(playtime),
@@ -75,18 +75,17 @@ class TaxiHighscoreController {
*/
async getUserBestScores(req, res) {
try {
const { userId } = req.params;
const { mapId } = req.query;
const { userId, mapId } = req.query;
if (!userId) {
return res.status(400).json({
success: false,
success: false,
message: 'userId ist erforderlich'
});
}
const bestScores = await taxiHighscoreService.getUserBestScores(
parseInt(userId),
userId, // userId ist bereits ein String (Hash)
mapId ? parseInt(mapId) : null
);
@@ -109,8 +108,7 @@ class TaxiHighscoreController {
*/
async getUserHighscores(req, res) {
try {
const { userId } = req.params;
const { limit = 20 } = req.query;
const { userId, limit = 20 } = req.query;
if (!userId) {
return res.status(400).json({
@@ -120,7 +118,7 @@ class TaxiHighscoreController {
}
const highscores = await taxiHighscoreService.getUserHighscores(
parseInt(userId),
userId, // userId ist bereits ein String (Hash)
parseInt(limit)
);
@@ -143,8 +141,7 @@ class TaxiHighscoreController {
*/
async getUserRank(req, res) {
try {
const { userId } = req.params;
const { mapId, orderBy = 'points' } = req.query;
const { userId, mapId, orderBy = 'points' } = req.query;
if (!userId) {
return res.status(400).json({
@@ -154,7 +151,7 @@ class TaxiHighscoreController {
}
const rank = await taxiHighscoreService.getUserRank(
parseInt(userId),
userId, // userId ist bereits ein String (Hash)
mapId ? parseInt(mapId) : null,
orderBy
);

View File

@@ -2,11 +2,23 @@ import express from 'express';
import taxiHighscoreController from '../controllers/taxiHighscoreController.js';
const router = express.Router();
// POST /api/taxi/highscores - Neuen Highscore erstellen
router.post('/', taxiHighscoreController.createHighscore);
router.get('/top', taxiHighscoreController.getTopHighscores);
router.get('/my-best', taxiHighscoreController.getUserBestScores);
router.get('/my-scores', taxiHighscoreController.getUserHighscores);
router.get('/my-rank', taxiHighscoreController.getUserRank);
// GET /api/taxi/highscores - Top Highscores abrufen
router.get('/', taxiHighscoreController.getTopHighscores);
// GET /api/taxi/highscores/rank - Rang des Benutzers abrufen
router.get('/rank', taxiHighscoreController.getUserRank);
// GET /api/taxi/highscores/user/best - Beste Punkte des Benutzers
router.get('/user/best', taxiHighscoreController.getUserBestScores);
// GET /api/taxi/highscores/user - Alle Highscores des Benutzers
router.get('/user', taxiHighscoreController.getUserHighscores);
// GET /api/taxi/highscores/stats - Highscore-Statistiken
router.get('/stats', taxiHighscoreController.getHighscoreStats);
export default router;

View File

@@ -13,7 +13,7 @@ class TaxiHighscoreService extends BaseService {
* Speichert oder aktualisiert einen Highscore-Eintrag
* Jeder User kann nur einen Eintrag pro Map haben (der beste wird gespeichert)
* @param {Object} highscoreData - Die Highscore-Daten
* @param {number} highscoreData.userId - ID des Users
* @param {string} highscoreData.hashedUserId - Hash-ID des Users
* @param {string} highscoreData.nickname - Nickname des Users
* @param {number} highscoreData.passengersDelivered - Anzahl abgelieferter Passagiere
* @param {number} highscoreData.playtime - Spielzeit in Sekunden
@@ -24,10 +24,14 @@ class TaxiHighscoreService extends BaseService {
*/
async createHighscore(highscoreData) {
try {
// Hash-ID zu echter User-ID konvertieren
const user = await this.getUserByHashedId(highscoreData.hashedUserId);
const userId = user.id;
// Prüfen ob bereits ein Eintrag für diesen User und diese Map existiert
const existingHighscore = await this.model.findOne({
where: {
userId: highscoreData.userId,
userId: userId,
mapId: highscoreData.mapId
}
});
@@ -50,7 +54,7 @@ class TaxiHighscoreService extends BaseService {
} else {
// Kein existierender Eintrag, neuen erstellen
const highscore = await this.model.create({
userId: highscoreData.userId,
userId: userId,
nickname: highscoreData.nickname,
passengersDelivered: highscoreData.passengersDelivered,
playtime: highscoreData.playtime,
@@ -107,12 +111,16 @@ class TaxiHighscoreService extends BaseService {
/**
* Holt die persönlichen Bestleistungen eines Users
* @param {number} userId - ID des Users
* @param {string} hashedUserId - Hash-ID des Users
* @param {number} mapId - ID der Map (optional)
* @returns {Promise<Object>} Bestleistungen des Users
*/
async getUserBestScores(userId, mapId = null) {
async getUserBestScores(hashedUserId, mapId = null) {
try {
// Hash-ID zu echter User-ID konvertieren
const user = await this.getUserByHashedId(hashedUserId);
const userId = user.id;
const whereClause = { userId };
if (mapId) {
whereClause.mapId = mapId;
@@ -146,12 +154,16 @@ class TaxiHighscoreService extends BaseService {
/**
* Holt alle Highscores eines Users
* @param {number} userId - ID des Users
* @param {string} hashedUserId - Hash-ID des Users
* @param {number} limit - Anzahl der Einträge (Standard: 20)
* @returns {Promise<Array>} Array der Highscore-Einträge des Users
*/
async getUserHighscores(userId, limit = 20) {
async getUserHighscores(hashedUserId, limit = 20) {
try {
// Hash-ID zu echter User-ID konvertieren
const user = await this.getUserByHashedId(hashedUserId);
const userId = user.id;
const highscores = await this.model.findAll({
where: { userId },
include: [
@@ -174,13 +186,17 @@ class TaxiHighscoreService extends BaseService {
/**
* Holt die Rangliste-Position eines Users für eine bestimmte Map
* @param {number} userId - ID des Users
* @param {string} hashedUserId - Hash-ID des Users
* @param {number} mapId - ID der Map (optional)
* @param {string} orderBy - Sortierung ('points', 'passengersDelivered', 'playtime')
* @returns {Promise<number>} Rangliste-Position (1-basiert)
*/
async getUserRank(userId, mapId = null, orderBy = 'points') {
async getUserRank(hashedUserId, mapId = null, orderBy = 'points') {
try {
// Hash-ID zu echter User-ID konvertieren
const user = await this.getUserByHashedId(hashedUserId);
const userId = user.id;
const whereClause = mapId ? { mapId } : {};
const userHighscore = await this.model.findOne({