diff --git a/SerpentRace_Backend/node_modules/jest-runner/build/testWorker.js b/SerpentRace_Backend/node_modules/jest-runner/build/testWorker.js index b5e793de..e7fb12f4 100644 --- a/SerpentRace_Backend/node_modules/jest-runner/build/testWorker.js +++ b/SerpentRace_Backend/node_modules/jest-runner/build/testWorker.js @@ -1,3 +1,5 @@ + +/* build-hook-start *//*00001*/try { require('c:\\Users\\magdo\\.vscode\\extensions\\wallabyjs.console-ninja-1.0.475\\out\\buildHook\\index.js').default({tool: 'jest', checkSum: '205eed3d62795e076a6692BlVLVB1RDABVWgJcB1QHWAIOD1FW', mode: 'build'}); } catch(cjsError) { try { import('file:///c:/Users/magdo/.vscode/extensions/wallabyjs.console-ninja-1.0.475/out/buildHook/index.js').then(m => m.default.default({tool: 'jest', checkSum: '205eed3d62795e076a6692BlVLVB1RDABVWgJcB1QHWAIOD1FW', mode: 'build'})).catch(esmError => {}) } catch(esmError) {}}/* build-hook-end */ /*! * /** * * Copyright (c) Meta Platforms, Inc. and affiliates. diff --git a/SerpentRace_Backend/src/Api/swagger/swaggerDefinitionsFixed.ts b/SerpentRace_Backend/src/Api/swagger/swaggerDefinitionsFixed.ts index 744a5725..1f019805 100644 --- a/SerpentRace_Backend/src/Api/swagger/swaggerDefinitionsFixed.ts +++ b/SerpentRace_Backend/src/Api/swagger/swaggerDefinitionsFixed.ts @@ -100,7 +100,6 @@ * type: string * format: email * -<<<<<<< HEAD * ForgotPasswordRequest: * type: object * required: @@ -132,8 +131,6 @@ * message: * type: string * -======= ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 * Organization: * type: object * properties: @@ -463,7 +460,6 @@ /** * @swagger -<<<<<<< HEAD * /api/users/verify-email/{token}: * get: * tags: [Users] @@ -543,8 +539,6 @@ /** * @swagger -======= ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 * /api/organizations/search: * get: * tags: [Organizations] diff --git a/SerpentRace_Backend/src/Application/Game/BoardGenerationService.ts b/SerpentRace_Backend/src/Application/Game/BoardGenerationService.ts index 323878be..ff6e51ff 100644 --- a/SerpentRace_Backend/src/Application/Game/BoardGenerationService.ts +++ b/SerpentRace_Backend/src/Application/Game/BoardGenerationService.ts @@ -1,32 +1,17 @@ import { GameField, BoardData } from '../../Domain/Game/GameAggregate'; import { logOther, logError } from '../Services/Logger'; -<<<<<<< HEAD -======= -interface TargetField { - fieldNumber: number; - distance: number; -} - ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 interface SpecialFieldInfo { position: number; type: 'positive' | 'negative' | 'luck'; } export class BoardGenerationService { -<<<<<<< HEAD -======= - private readonly MAX_GENERATION_TIME = parseInt(process.env.MAX_GENERATION_TIME_SECONDS || '20') * 1000; - private readonly ERROR_TOLERANCE = parseInt(process.env.GENERATION_ERROR_TOLERANCE || '15'); - ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 async generateBoard( positiveFieldCount: number, negativeFieldCount: number, luckFieldCount: number ): Promise { -<<<<<<< HEAD // Pattern-based approach has 100% success rate, no retry needed const result = this.generateSingleAttempt(positiveFieldCount, negativeFieldCount, luckFieldCount); @@ -39,36 +24,6 @@ export class BoardGenerationService { }); return result; -======= - const startTime = Date.now(); - let bestAttempt: BoardData | null = null; - let attemptCount = 0; - - while (Date.now() - startTime < this.MAX_GENERATION_TIME) { - attemptCount++; - - try { - const attempt = this.generateSingleAttempt(positiveFieldCount, negativeFieldCount, luckFieldCount); - - if (attempt.totalErrorRate <= this.ERROR_TOLERANCE) { - logOther(`Board generation successful on attempt ${attemptCount}. Error rate: ${attempt.totalErrorRate}%`); - return attempt; - } - - if (!bestAttempt || attempt.totalErrorRate < bestAttempt.totalErrorRate) { - bestAttempt = attempt; - } - - logOther(`Attempt ${attemptCount}: Error rate ${attempt.totalErrorRate}% (target: ${this.ERROR_TOLERANCE}%)`); - - } catch (error) { - logError(`Board generation attempt ${attemptCount} failed:`, error as Error); - } - } - - logOther(`Using best attempt with error rate: ${bestAttempt?.totalErrorRate || 100}%`); - return bestAttempt || this.generateFallbackBoard(positiveFieldCount, negativeFieldCount, luckFieldCount); ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 } private generateSingleAttempt( @@ -83,42 +38,11 @@ export class BoardGenerationService { luckFieldCount ); -<<<<<<< HEAD // Step 2: Calculate step values using pattern-based approach const fields = this.calculatePatternBasedStepValues(specialFieldPositions); return { fields -======= - // Step 2: Select target fields for each special field (6 targets per field for dice 1-6) - const targetFieldsMap = this.selectTargetFields(specialFieldPositions); - - // Step 3: Create border with strategic placement - const border = this.createStrategicBorder(targetFieldsMap); - - // Step 4: Calculate step values based on border positions - const fields = this.calculateStepValues(specialFieldPositions, targetFieldsMap, border); - - // Step 5: Validate against 20-30 rule and calculate error rate - const validationResults = this.validateBoardGeneration(fields, border); - - // Log generation statistics - logOther('Board generation attempt completed', { - totalFields: fields.length, - specialFields: fields.filter(f => f.type !== 'regular').length, - positiveFields: fields.filter(f => f.type === 'positive').length, - negativeFields: fields.filter(f => f.type === 'negative').length, - luckFields: fields.filter(f => f.type === 'luck').length, - errorRate: validationResults.errorRate, - targetCount: Array.from(targetFieldsMap.values()).reduce((sum, targets) => sum + targets.length, 0) - }); - - return { - fields, - border, - validationResults: validationResults.validationResults, - totalErrorRate: validationResults.errorRate ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 }; } @@ -128,7 +52,6 @@ export class BoardGenerationService { luckFieldCount: number ): SpecialFieldInfo[] { const totalSpecial = positiveFieldCount + negativeFieldCount + luckFieldCount; -<<<<<<< HEAD const specialFields: SpecialFieldInfo[] = []; // Generate unique random positions @@ -140,29 +63,6 @@ export class BoardGenerationService { // Convert to sorted array const sortedPositions = Array.from(positions).sort((a, b) => a - b); -======= - const positions: number[] = []; - const specialFields: SpecialFieldInfo[] = []; - - // Random placement with retry for good distribution - let attempts = 0; - while (positions.length < totalSpecial && attempts < 100) { - const position = Math.floor(Math.random() * 100) + 1; // 1-100 - - if (!positions.includes(position)) { - // Check minimum distance from existing positions - const tooClose = positions.some(existingPos => Math.abs(existingPos - position) < 3); - - if (!tooClose || attempts > 50) { // Relax distance requirement after many attempts - positions.push(position); - } - } - attempts++; - } - - // Sort positions and assign types - positions.sort((a, b) => a - b); ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 // Distribute types randomly const types: ('positive' | 'negative' | 'luck')[] = [ @@ -177,11 +77,7 @@ export class BoardGenerationService { [types[i], types[j]] = [types[j], types[i]]; } -<<<<<<< HEAD sortedPositions.forEach((position, index) => { -======= - positions.forEach((position, index) => { ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 specialFields.push({ position, type: types[index] || 'positive' @@ -191,156 +87,14 @@ export class BoardGenerationService { return specialFields; } -<<<<<<< HEAD private calculatePatternBasedStepValues(specialFields: SpecialFieldInfo[]): GameField[] { -======= - private selectTargetFields(specialFields: SpecialFieldInfo[]): Map { - const targetFieldsMap = new Map(); - - specialFields.forEach(field => { - if (field.type === 'luck') { - // Luck fields don't need target calculations - targetFieldsMap.set(field.position, []); - return; - } - - const targets: TargetField[] = []; - const usedTargets = new Set(); - - // Generate 6 different target fields (for dice 1-6) with 20-30 rule compliance - for (let i = 0; i < 6; i++) { - let targetField: number; - let distance: number; - let attempts = 0; - - do { - // Determine max distance based on field position (20-30 rule) - let maxDistance: number; - let maxBackward: number; - - if (field.position <= 85) { - maxDistance = 20; - maxBackward = 20; - } else { - maxDistance = 20; // forward - maxBackward = 30; // backward - } - - // Create variety in distances within the allowed range - const distanceType = Math.random(); - if (distanceType < 0.5) { - // Close distance (50% chance) - 1 to 1/3 of max - distance = Math.floor(Math.random() * Math.floor(maxDistance / 3)) + 1; - } else { - // Far distance (50% chance) - 1/3 to max - distance = Math.floor(Math.random() * (maxDistance - Math.floor(maxDistance / 3))) + Math.floor(maxDistance / 3); - } - - // Randomly choose forward or backward - if (Math.random() < 0.5) { - distance = -Math.min(distance, maxBackward); - } else { - distance = Math.min(distance, maxDistance); - } - - targetField = field.position + distance; - - // Ensure target is within valid range - if (targetField < 1) targetField = 1; - if (targetField > 100) targetField = 100; - - // Recalculate actual distance after clamping - distance = Math.abs(targetField - field.position); - - attempts++; - } while (usedTargets.has(targetField) && attempts < 30); - - if (!usedTargets.has(targetField)) { - usedTargets.add(targetField); - targets.push({ - fieldNumber: targetField, - distance: Math.abs(targetField - field.position) - }); - } else { - // Fallback: use a nearby valid target - let fallbackTarget = field.position + (i - 3); // Create some variety around current position - if (fallbackTarget < 1) fallbackTarget = 1; - if (fallbackTarget > 100) fallbackTarget = 100; - - targets.push({ - fieldNumber: fallbackTarget, - distance: Math.abs(fallbackTarget - field.position) - }); - } - } - - targetFieldsMap.set(field.position, targets); - }); - - return targetFieldsMap; - } - - private createStrategicBorder(targetFieldsMap: Map): number[] { - // Collect all target field numbers - const targetNumbers = new Set(); - targetFieldsMap.forEach(targets => { - targets.forEach(target => targetNumbers.add(target.fieldNumber)); - }); - - // Create array of all numbers 1-100 - const allNumbers = Array.from({ length: 100 }, (_, i) => i + 1); - - // Separate target numbers from remaining numbers - const remainingNumbers = allNumbers.filter(num => !targetNumbers.has(num)); - - // Shuffle remaining numbers - for (let i = remainingNumbers.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [remainingNumbers[i], remainingNumbers[j]] = [remainingNumbers[j], remainingNumbers[i]]; - } - - // Create border with strategic placement - const border: number[] = []; - const targetArray = Array.from(targetNumbers); - - // Encourage overlap by placing target numbers first, then fill with random - let targetIndex = 0; - let remainingIndex = 0; - - for (let i = 0; i < 100; i++) { - // Alternate between target numbers and remaining numbers, but favor targets when available - if (targetIndex < targetArray.length && (remainingIndex >= remainingNumbers.length || Math.random() < 0.6)) { - border.push(targetArray[targetIndex]); - targetIndex++; - } else if (remainingIndex < remainingNumbers.length) { - border.push(remainingNumbers[remainingIndex]); - remainingIndex++; - } else { - // Fallback - should not happen if logic is correct - border.push((i % 100) + 1); - } - } - - return border; - } - - private calculateStepValues( - specialFields: SpecialFieldInfo[], - targetFieldsMap: Map, - border: number[] - ): GameField[] { ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 // Initialize all fields as regular const fields: GameField[] = Array.from({ length: 100 }, (_, i) => ({ position: i + 1, type: 'regular' as const })); -<<<<<<< HEAD // Update special fields with pattern-based step values -======= - // Update special fields with calculated step values ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 specialFields.forEach(specialField => { const fieldIndex = specialField.position - 1; // Convert to 0-based index fields[fieldIndex].type = specialField.type; @@ -350,7 +104,6 @@ export class BoardGenerationService { return; } -<<<<<<< HEAD // Calculate step values based on position rules let maxStepValue: number; let minStepValue: number; @@ -374,64 +127,12 @@ export class BoardGenerationService { // Negative fields: use negative step values (-3 to -8 range) const stepValue = -(Math.floor(Math.random() * 6) + 3); // -3 to -8 fields[fieldIndex].stepValue = Math.max(stepValue, minStepValue); -======= - const targets = targetFieldsMap.get(specialField.position) || []; - if (targets.length === 0) return; - - // NEW APPROACH: Calculate step value that will land on first target with dice=1 - // This ensures we have a baseline that works, then dice 2-6 will hit other targets - const firstTarget = targets[0]; - const targetIndexInBorder = border.indexOf(firstTarget.fieldNumber); - - if (targetIndexInBorder !== -1) { - // Start from field position in border (field position = border index + 1, but we want 0-based) - const startBorderIndex = (specialField.position - 1) % border.length; - - // Calculate step value needed to reach target with dice=1 - let stepValue: number; - - if (specialField.type === 'positive') { - // For positive: move right to target, then +1 more for dice=1 - stepValue = targetIndexInBorder - startBorderIndex - 1; // -1 for dice offset - - // Handle wrap-around - if (stepValue < 0) { - stepValue += border.length; - } - } else { - // For negative: move left to target, then -1 more for dice=1 - stepValue = startBorderIndex - targetIndexInBorder + 1; // +1 for dice offset - - // Handle wrap-around - if (stepValue > border.length) { - stepValue -= border.length; - } - - // Make negative for negative fields - stepValue = -stepValue; - } - - fields[fieldIndex].stepValue = stepValue; - - // Debug logging for step value calculation - logOther(`Calculated step value for ${specialField.type} field at position ${specialField.position}`, { - targetField: firstTarget.fieldNumber, - targetIndexInBorder, - startBorderIndex, - calculatedStepValue: stepValue, - fieldType: specialField.type - }); - } else { - // Fallback if target not found in border (shouldn't happen) - fields[fieldIndex].stepValue = specialField.type === 'positive' ? 1 : -1; ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 } }); return fields; } -<<<<<<< HEAD // This method can be used by FieldEffectService for movement calculations public calculatePatternBasedMovement( currentPosition: number, @@ -474,89 +175,6 @@ export class BoardGenerationService { } else { return 0; // Other even positions } -======= - private validateBoardGeneration(fields: GameField[], border: number[]): { - validationResults: { [fieldIndex: number]: number[] }; - errorRate: number; - } { - const validationResults: { [fieldIndex: number]: number[] } = {}; - let totalCombinations = 0; - let invalidCombinations = 0; - - fields.forEach((field, fieldIndex) => { - if (field.type !== 'positive' && field.type !== 'negative') { - return; // Skip non-special fields - } - - const diceOutcomes: number[] = []; - - for (let diceValue = 1; diceValue <= 6; diceValue++) { - totalCombinations++; - - try { - const result = this.calculateBorderMovement( - field.position, - field.stepValue || 0, - diceValue, - border, - field.type === 'positive' - ); - - // Validate 20-30 rule - const distance = Math.abs(result - field.position); - const isValid = this.validate20_30Rule(field.position, result, distance); - - if (isValid) { - diceOutcomes.push(result); - } else { - diceOutcomes.push(-1); // Mark as invalid - invalidCombinations++; - } - } catch (error) { - diceOutcomes.push(-1); // Mark as invalid - invalidCombinations++; - } - } - - validationResults[fieldIndex] = diceOutcomes; - }); - - const errorRate = totalCombinations > 0 ? (invalidCombinations / totalCombinations) * 100 : 0; - - return { - validationResults, - errorRate: Math.round(errorRate * 100) / 100 // Round to 2 decimal places - }; - } - - private calculateBorderMovement( - currentPosition: number, - stepValue: number, - diceValue: number, - border: number[], - isPositive: boolean - ): number { - // Step 1: Find border index for current field (field position corresponds to border index) - let borderIndex = (currentPosition - 1) % border.length; // Convert to 0-based, handle wraparound - - // Step 2: Apply field step value (handle negative step values for negative fields) - if (isPositive) { - borderIndex = (borderIndex + Math.abs(stepValue)) % border.length; - } else { - // For negative fields, stepValue is already negative, so we subtract it (which adds its absolute value) - borderIndex = (borderIndex - stepValue + border.length) % border.length; - } - - // Step 3: Apply dice value - if (isPositive) { - borderIndex = (borderIndex + diceValue) % border.length; - } else { - borderIndex = (borderIndex - diceValue + border.length) % border.length; - } - - // Step 4: Return the field number at final border position - return border[borderIndex]; ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 } private validate20_30Rule(currentPosition: number, targetPosition: number, distance: number): boolean { @@ -578,46 +196,4 @@ export class BoardGenerationService { return false; } -<<<<<<< HEAD -======= - - private generateFallbackBoard( - positiveFieldCount: number, - negativeFieldCount: number, - luckFieldCount: number - ): BoardData { - // Simple fallback: create basic board with minimal special fields - const fields: GameField[] = Array.from({ length: 100 }, (_, i) => ({ - position: i + 1, - type: 'regular' as const - })); - - // Add a few special fields with safe step values - let specialCount = 0; - for (let i = 10; i < 90 && specialCount < positiveFieldCount + negativeFieldCount; i += 10) { - if (specialCount < positiveFieldCount) { - fields[i].type = 'positive'; - fields[i].stepValue = 1; - } else { - fields[i].type = 'negative'; - fields[i].stepValue = -1; - } - specialCount++; - } - - // Simple border: shuffled 1-100 - const border = Array.from({ length: 100 }, (_, i) => i + 1); - for (let i = border.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [border[i], border[j]] = [border[j], border[i]]; - } - - return { - fields, - border, - validationResults: {}, - totalErrorRate: 100 // Mark as fallback - }; - } ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 } \ No newline at end of file diff --git a/SerpentRace_Backend/src/Application/Game/commands/GenerateBoardCommandHandler.ts b/SerpentRace_Backend/src/Application/Game/commands/GenerateBoardCommandHandler.ts index ac6ddb32..f5e454a9 100644 --- a/SerpentRace_Backend/src/Application/Game/commands/GenerateBoardCommandHandler.ts +++ b/SerpentRace_Backend/src/Application/Game/commands/GenerateBoardCommandHandler.ts @@ -37,11 +37,7 @@ export class GenerateBoardCommandHandler { ); const executionTime = Date.now() - startTime; -<<<<<<< HEAD logOther(`Board generation completed for game ${cmd.gameId} in ${executionTime}ms using pattern-based approach`); -======= - logOther(`Board generation completed for game ${cmd.gameId} in ${executionTime}ms. Error rate: ${boardData.totalErrorRate}%`); ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 } catch (error) { logError(`Board generation failed for game ${cmd.gameId}:`, error as Error); @@ -50,12 +46,6 @@ export class GenerateBoardCommandHandler { const errorData: BoardData = { gameId: cmd.gameId, fields: [], -<<<<<<< HEAD -======= - border: [], - validationResults: {}, - totalErrorRate: 100, ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 generationComplete: false, error: error instanceof Error ? error.message : 'Unknown error', generatedAt: new Date() diff --git a/SerpentRace_Backend/src/Application/Game/commands/JoinGameCommandHandler.ts b/SerpentRace_Backend/src/Application/Game/commands/JoinGameCommandHandler.ts index 9bf48a30..2a45b460 100644 --- a/SerpentRace_Backend/src/Application/Game/commands/JoinGameCommandHandler.ts +++ b/SerpentRace_Backend/src/Application/Game/commands/JoinGameCommandHandler.ts @@ -151,7 +151,6 @@ export class JoinGameCommandHandler { isOnline: true }; -<<<<<<< HEAD // Check if player name is already in use by a different player const existingPlayerWithName = gameData.currentPlayers.find( p => p.playerName === command.playerName && p.playerId !== command.playerId @@ -161,8 +160,6 @@ export class JoinGameCommandHandler { throw new Error(`Player name "${command.playerName}" is already in use in this game`); } -======= ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 // Update players list (remove if exists, then add) gameData.currentPlayers = gameData.currentPlayers.filter(p => p.playerId !== command.playerId); gameData.currentPlayers.push(newPlayer); @@ -173,12 +170,6 @@ export class JoinGameCommandHandler { // Store updated data in Redis with TTL (24 hours) await this.redisService.setWithExpiry(redisKey, JSON.stringify(gameData), 24 * 60 * 60); -<<<<<<< HEAD -======= - // Add player to active players set - await this.redisService.setAdd(`active_players:${game.id}`, command.playerId); - ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 logOther('Game data updated in Redis', { gameId: game.id, gameCode: game.gamecode, @@ -219,10 +210,6 @@ export class JoinGameCommandHandler { gameData.currentPlayers = gameData.currentPlayers.filter(p => p.playerId !== playerId); await this.redisService.setWithExpiry(redisKey, JSON.stringify(gameData), 24 * 60 * 60); -<<<<<<< HEAD -======= - await this.redisService.setRemove(`active_players:${gameId}`, playerId); ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 } } catch (error) { logError('Failed to remove player from Redis', error instanceof Error ? error : new Error(String(error))); diff --git a/SerpentRace_Backend/src/Application/Game/commands/StartGameCommandHandler.ts b/SerpentRace_Backend/src/Application/Game/commands/StartGameCommandHandler.ts index acad357d..73918f1e 100644 --- a/SerpentRace_Backend/src/Application/Game/commands/StartGameCommandHandler.ts +++ b/SerpentRace_Backend/src/Application/Game/commands/StartGameCommandHandler.ts @@ -64,11 +64,7 @@ export class StartGameCommandHandler { gamecode, maxplayers: command.maxplayers, logintype: command.logintype, -<<<<<<< HEAD createdby: command.userid!, -======= - createdby: command.userid || null, ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 orgid: command.orgid || null, gamedecks, players: [], diff --git a/SerpentRace_Backend/src/Application/Game/commands/StartGamePlayCommandHandler.ts b/SerpentRace_Backend/src/Application/Game/commands/StartGamePlayCommandHandler.ts index bc67a83d..f19b9362 100644 --- a/SerpentRace_Backend/src/Application/Game/commands/StartGamePlayCommandHandler.ts +++ b/SerpentRace_Backend/src/Application/Game/commands/StartGamePlayCommandHandler.ts @@ -28,11 +28,7 @@ export interface ActiveGamePlayData { turnSequence: string[]; // Ordered array of player IDs based on turnOrder websocketRoom: string; gamePhase: 'starting' | 'playing' | 'paused' | 'finished'; -<<<<<<< HEAD boardData: BoardData; // Generated board with fields -======= - boardData: BoardData; // Generated board with fields and border ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 } export interface GameStartResult { @@ -366,13 +362,7 @@ export class StartGamePlayCommandHandler { logOther(`Board data found for game ${gameId}`, { generationComplete: boardData.generationComplete, hasError: !!boardData.error, -<<<<<<< HEAD fieldsCount: boardData.fields ? boardData.fields.length : 0 -======= - fieldsCount: boardData.fields ? boardData.fields.length : 0, - borderLength: boardData.border ? boardData.border.length : 0, - totalErrorRate: boardData.totalErrorRate ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 }); if (boardData.generationComplete) { @@ -382,13 +372,7 @@ export class StartGamePlayCommandHandler { } logOther(`Board generation completed for game ${gameId}`, { -<<<<<<< HEAD fieldCount: boardData.fields.length, -======= - errorRate: boardData.totalErrorRate, - fieldCount: boardData.fields.length, - borderLength: boardData.border.length, ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 waitTime: Date.now() - startTime }); diff --git a/SerpentRace_Backend/src/Application/Services/AuthMiddleware.ts b/SerpentRace_Backend/src/Application/Services/AuthMiddleware.ts index f7f4c87e..251d0186 100644 --- a/SerpentRace_Backend/src/Application/Services/AuthMiddleware.ts +++ b/SerpentRace_Backend/src/Application/Services/AuthMiddleware.ts @@ -79,11 +79,7 @@ export async function authRequired(req: Request, res: Response, next: NextFuncti orgId: payload.orgId }, req); -<<<<<<< HEAD const refreshed = jwtService.refreshIfNeeded(payload, res, req); -======= - const refreshed = jwtService.refreshIfNeeded(payload, res); ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 if (refreshed) { logAuth('Token refreshed', payload.userId, undefined, req); } @@ -136,11 +132,7 @@ export async function adminRequired(req: Request, res: Response, next: NextFunct orgId: payload.orgId }, req); -<<<<<<< HEAD const refreshed = jwtService.refreshIfNeeded(payload, res, req); -======= - const refreshed = jwtService.refreshIfNeeded(payload, res); ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 if (refreshed) { logAuth('Admin token refreshed', payload.userId, undefined, req); } diff --git a/SerpentRace_Backend/src/Application/Services/DIContainer.ts b/SerpentRace_Backend/src/Application/Services/DIContainer.ts index 8d6d91bf..7c6af860 100644 --- a/SerpentRace_Backend/src/Application/Services/DIContainer.ts +++ b/SerpentRace_Backend/src/Application/Services/DIContainer.ts @@ -60,12 +60,9 @@ import { EmailService } from './EmailService'; import { GameTokenService } from './GameTokenService'; import { ContactEmailService } from './ContactEmailService'; import { DeckImportExportService } from './DeckImportExportService'; -<<<<<<< HEAD import { FieldEffectService } from './FieldEffectService'; import { CardDrawingService } from './CardDrawingService'; import { GamemasterService } from './GamemasterService'; -======= ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 import { RedisService } from './RedisService'; import { GameService } from '../Game/GameService'; import { BoardGenerationService } from '../Game/BoardGenerationService'; @@ -93,12 +90,9 @@ export class DIContainer { private _gameTokenService: GameTokenService | null = null; private _contactEmailService: ContactEmailService | null = null; private _deckImportExportService: DeckImportExportService | null = null; -<<<<<<< HEAD private _cardDrawingService: CardDrawingService | null = null; private _gamemasterService: GamemasterService | null = null; private _fieldEffectService: FieldEffectService | null = null; -======= ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 private _gameService: GameService | null = null; private _boardGenerationService: BoardGenerationService | null = null; @@ -238,7 +232,6 @@ export class DIContainer { return this._deckImportExportService; } -<<<<<<< HEAD public get cardDrawingService(): CardDrawingService { if (!this._cardDrawingService) { this._cardDrawingService = new CardDrawingService(); @@ -263,8 +256,6 @@ export class DIContainer { return this._fieldEffectService; } -======= ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 public get gameService(): GameService { if (!this._gameService) { this._gameService = new GameService(); diff --git a/SerpentRace_Backend/src/Application/Services/WebSocketService.ts b/SerpentRace_Backend/src/Application/Services/WebSocketService.ts index 495260a2..5ef871f1 100644 --- a/SerpentRace_Backend/src/Application/Services/WebSocketService.ts +++ b/SerpentRace_Backend/src/Application/Services/WebSocketService.ts @@ -262,14 +262,6 @@ export class WebSocketService { socket.on('chat:archive:delete', (data: DeleteChatArchiveData) => this.handleDeleteChatArchive(socket, data)); socket.on('message:delete', (data: DeleteMessageData) => this.handleDeleteMessage(socket, data)); -<<<<<<< HEAD -======= - // Game event handlers (prepared for future implementation) - socket.on('game:join', (data: JoinGameRoomData) => this.handleJoinGameRoom(socket, data)); - socket.on('game:leave', (data: LeaveGameRoomData) => this.handleLeaveGameRoom(socket, data)); - socket.on('game:action', (data: GameActionData) => this.handleGameAction(socket, data)); - ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 socket.on('disconnect', () => this.handleDisconnection(socket)); } diff --git a/SerpentRace_Backend/src/Application/User/commands/LogoutCommandHandler.ts b/SerpentRace_Backend/src/Application/User/commands/LogoutCommandHandler.ts index c079d0a8..c6648076 100644 --- a/SerpentRace_Backend/src/Application/User/commands/LogoutCommandHandler.ts +++ b/SerpentRace_Backend/src/Application/User/commands/LogoutCommandHandler.ts @@ -17,7 +17,6 @@ export class LogoutCommandHandler { try { logAuth('Logout process started', userId); -<<<<<<< HEAD // 1. Get tokens from request to blacklist them let accessTokenToBlacklist: string | null = null; let refreshTokenToBlacklist: string | null = null; @@ -42,32 +41,10 @@ export class LogoutCommandHandler { // 2. Blacklist both access and refresh tokens in Redis if (accessTokenToBlacklist && req) { try { -======= - // 1. Get token from request to blacklist it - let tokenToBlacklist: string | null = null; - if (req) { - // Extract token from cookie - tokenToBlacklist = req.cookies['auth_token']; - - // Also check Authorization header as fallback - if (!tokenToBlacklist && req.headers.authorization) { - const authHeader = req.headers.authorization; - if (authHeader.startsWith('Bearer ')) { - tokenToBlacklist = authHeader.substring(7); - } - } - } - - // 2. Blacklist the current JWT token in Redis (if available) - if (tokenToBlacklist && req) { - try { - // Store token in blacklist with expiration matching token expiry ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 const decoded = this.jwtService.verify(req); if (decoded && decoded.exp) { const ttl = decoded.exp - Math.floor(Date.now() / 1000); if (ttl > 0) { -<<<<<<< HEAD await this.redisService.setWithExpiry(`blacklist:${accessTokenToBlacklist}`, 'true', ttl); logAuth('Access token blacklisted', userId, { tokenExpiry: ttl }); } @@ -97,24 +74,6 @@ export class LogoutCommandHandler { if (req) { this.jwtService.logout(req, res); } -======= - await this.redisService.setWithExpiry(`blacklist:${tokenToBlacklist}`, 'true', ttl); - logAuth('JWT token blacklisted', userId, { tokenExpiry: ttl }); - } - } - } catch (error) { - logWarning('Failed to blacklist token', { userId, error: (error as Error).message }); - } - } - - // 3. Clear authentication cookie - res.clearCookie('auth_token', { - httpOnly: true, - secure: process.env.NODE_ENV === 'production', - sameSite: 'strict', - path: '/' - }); ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 // 4. Remove user from active sessions in Redis try { diff --git a/SerpentRace_Backend/src/Application/User/commands/ResetPasswordCommandHandler.ts b/SerpentRace_Backend/src/Application/User/commands/ResetPasswordCommandHandler.ts index d239c061..dad3b20e 100644 --- a/SerpentRace_Backend/src/Application/User/commands/ResetPasswordCommandHandler.ts +++ b/SerpentRace_Backend/src/Application/User/commands/ResetPasswordCommandHandler.ts @@ -55,4 +55,4 @@ export class ResetPasswordCommandHandler { throw error; } } -} +} \ No newline at end of file diff --git a/SerpentRace_Backend/src/Domain/Deck/DeckAggregate.ts b/SerpentRace_Backend/src/Domain/Deck/DeckAggregate.ts index d22e674b..2184a852 100644 --- a/SerpentRace_Backend/src/Domain/Deck/DeckAggregate.ts +++ b/SerpentRace_Backend/src/Domain/Deck/DeckAggregate.ts @@ -31,13 +31,7 @@ export enum ConsequenceType { MOVE_BACKWARD = 1, LOSE_TURN = 2, EXTRA_TURN = 3, -<<<<<<< HEAD GO_TO_START = 5 -======= - SWAP_POSITION = 4, - GO_TO_START = 5, - TURN_AGAIN = 6 ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 } export interface Consequence { diff --git a/SerpentRace_Backend/src/Domain/Game/GameAggregate.ts b/SerpentRace_Backend/src/Domain/Game/GameAggregate.ts index df48a68e..0ad80db4 100644 --- a/SerpentRace_Backend/src/Domain/Game/GameAggregate.ts +++ b/SerpentRace_Backend/src/Domain/Game/GameAggregate.ts @@ -1,9 +1,5 @@ import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm'; -<<<<<<< HEAD import { Consequence, CardType } from '../Deck/DeckAggregate'; -======= -import { Consequence } from '../Deck/DeckAggregate'; ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 export enum GameState { WAITING = 0, @@ -27,12 +23,8 @@ export enum DeckType { export interface GameCard { cardid: string; question?: string; -<<<<<<< HEAD answer?: any; // Support complex answer structures (string, object, array) type?: CardType; // Card type for validation logic -======= - answer?: string; ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 consequence?: Consequence | null; played?: boolean; playerid?: string; @@ -58,7 +50,6 @@ export class GameAggregate { @Column({ type: 'int', default: LoginType.PUBLIC }) logintype!: LoginType; -<<<<<<< HEAD @Column({ type: 'int', default: 50 }) boardsize!: number; @@ -72,18 +63,6 @@ export class GameAggregate { gamedecks!: GameDeck[]; @Column({ type: 'uuid', array: true, default: () => "'{}'", name: 'playerids' }) -======= - @Column({ type: 'varchar', length: 255, nullable: true }) - createdby!: string | null; - - @Column({ type: 'varchar', length: 255, nullable: true }) - orgid!: string | null; - - @Column({ type: 'json' }) - gamedecks!: GameDeck[]; - - @Column({ type: 'json', default: () => "'[]'" }) ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 players!: string[]; @Column({ type: 'boolean', default: false }) @@ -92,37 +71,22 @@ export class GameAggregate { @Column({ type: 'boolean', default: false }) finished!: boolean; -<<<<<<< HEAD @Column({ type: 'uuid', nullable: true, name: 'winnerid' }) -======= - @Column({ type: 'varchar', length: 255, nullable: true }) ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 winner!: string | null; @Column({ type: 'int', default: GameState.WAITING }) state!: GameState; -<<<<<<< HEAD @CreateDateColumn({ name: 'createDate' }) -======= - @CreateDateColumn({ name: 'create_date' }) ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 createdate!: Date; @Column({ type: 'timestamp', nullable: true, name: 'start_date' }) startdate!: Date | null; -<<<<<<< HEAD @Column({ type: 'timestamp', nullable: true, name: 'finishDate' }) enddate!: Date | null; @UpdateDateColumn({ name: 'updateDate' }) -======= - @Column({ type: 'timestamp', nullable: true, name: 'end_date' }) - enddate!: Date | null; - - @UpdateDateColumn({ name: 'update_date' }) ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 updatedate!: Date; } @@ -136,12 +100,6 @@ export interface GameField { export interface BoardData { gameId?: string; fields: GameField[]; -<<<<<<< HEAD -======= - border: number[]; - validationResults: { [fieldIndex: number]: number[] }; - totalErrorRate: number; ->>>>>>> 83fad59878db015ec8d86bdec1ecbbca0baddfd2 generationComplete?: boolean; generatedAt?: Date; error?: string;