mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-20 13:50:46 +00:00
Fix scenario endpoint to return filtered data and revert client to use /scenario
Changes: - Revert client game.js to use /scenario endpoint instead of /scenario_map - Update /scenario endpoint to return filtered_scenario_for_bootstrap - Add filter_requires_recursive method to remove sensitive 'requires' fields - Keep /scenario_map for potential future navigation queries - Add error handling to scenario endpoint Rationale: - The game client expects full scenario structure (startRoom, rooms, startItemsInInventory, etc.) - scenario_map returns minimal structure incompatible with game initialization - filtered_scenario_for_bootstrap provides room metadata without objects (lazy-loaded) - filter_requires_recursive ensures puzzle solutions aren't exposed to client - Maintains security while providing necessary data for game initialization
This commit is contained in:
@@ -10,10 +10,23 @@ module BreakEscape
|
||||
end
|
||||
|
||||
# GET /games/:id/scenario
|
||||
# Returns scenario JSON for this game instance
|
||||
# Returns filtered scenario JSON for this game instance
|
||||
# Uses filtered_scenario_for_bootstrap for lazy-loading support
|
||||
def scenario
|
||||
authorize @game if defined?(Pundit)
|
||||
render json: @game.scenario_data
|
||||
|
||||
begin
|
||||
# Use filtered bootstrap scenario and remove 'requires' fields for security
|
||||
filtered = @game.filtered_scenario_for_bootstrap
|
||||
|
||||
# Remove 'requires' fields recursively for security
|
||||
filter_requires_recursive(filtered)
|
||||
|
||||
render json: filtered
|
||||
rescue => e
|
||||
Rails.logger.error "[BreakEscape] scenario error: #{e.message}\n#{e.backtrace.first(5).join("\n")}"
|
||||
render_error("Failed to generate scenario: #{e.message}", :internal_server_error)
|
||||
end
|
||||
end
|
||||
|
||||
# GET /games/:id/scenario_map
|
||||
@@ -277,6 +290,19 @@ module BreakEscape
|
||||
@game = Game.find(params[:id])
|
||||
end
|
||||
|
||||
def filter_requires_recursive(obj)
|
||||
case obj
|
||||
when Hash
|
||||
# Remove 'requires' (the answer/solution) from all objects
|
||||
obj.delete('requires')
|
||||
|
||||
# Recursively filter nested structures
|
||||
obj.each_value { |value| filter_requires_recursive(value) }
|
||||
when Array
|
||||
obj.each { |item| filter_requires_recursive(item) }
|
||||
end
|
||||
end
|
||||
|
||||
def track_npc_encounters(room_id, room_data)
|
||||
return unless room_data['npcs'].present?
|
||||
|
||||
|
||||
@@ -441,9 +441,9 @@ export function preload() {
|
||||
|
||||
// Load scenario from Rails API endpoint if available, otherwise try URL parameter
|
||||
if (window.breakEscapeConfig?.apiBasePath) {
|
||||
// Load scenario map from Rails API endpoint (minimal metadata for lazy-loading)
|
||||
// Load scenario from Rails API endpoint (returns filtered scenario for security)
|
||||
// Use absolute URL with origin to prevent Phaser baseURL from interfering
|
||||
const scenarioUrl = `${window.location.origin}${window.breakEscapeConfig.apiBasePath}/scenario_map`;
|
||||
const scenarioUrl = `${window.location.origin}${window.breakEscapeConfig.apiBasePath}/scenario`;
|
||||
this.load.json('gameScenarioJSON', scenarioUrl);
|
||||
} else {
|
||||
// Fallback to old behavior for standalone HTML files
|
||||
|
||||
Reference in New Issue
Block a user