diff --git a/app/controllers/break_escape/api/games_controller.rb b/app/controllers/break_escape/api/games_controller.rb deleted file mode 100644 index 0cae3b3..0000000 --- a/app/controllers/break_escape/api/games_controller.rb +++ /dev/null @@ -1,114 +0,0 @@ -module BreakEscape - module Api - class GamesController < ApplicationController - before_action :set_game - - # GET /games/:id/bootstrap - # Initial game data for client - def bootstrap - authorize @game if defined?(Pundit) - - render json: { - gameId: @game.id, - missionName: @game.mission.display_name, - startRoom: @game.scenario_data['startRoom'], - playerState: @game.player_state, - roomLayout: build_room_layout - } - end - - # PUT /games/:id/sync_state - # Periodic state sync from client - def sync_state - authorize @game if defined?(Pundit) - - # Update allowed fields - if params[:currentRoom] - @game.player_state['currentRoom'] = params[:currentRoom] - end - - if params[:globalVariables] - @game.update_global_variables!(params[:globalVariables].to_unsafe_h) - end - - @game.save! - - render json: { success: true } - end - - # POST /games/:id/unlock - # Validate unlock attempt - def unlock - authorize @game if defined?(Pundit) - - target_type = params[:targetType] - target_id = params[:targetId] - attempt = params[:attempt] - method = params[:method] - - is_valid = @game.validate_unlock(target_type, target_id, attempt, method) - - if is_valid - if target_type == 'door' - @game.unlock_room!(target_id) - room_data = @game.filtered_room_data(target_id) - - render json: { - success: true, - type: 'door', - roomData: room_data - } - else - @game.unlock_object!(target_id) - render json: { - success: true, - type: 'object' - } - end - else - render json: { - success: false, - message: 'Invalid attempt' - }, status: :unprocessable_entity - end - end - - # POST /games/:id/inventory - # Update inventory - def inventory - authorize @game if defined?(Pundit) - - action_type = params[:action_type] || params[:actionType] - item = params[:item] - - case action_type - when 'add' - @game.add_inventory_item!(item.to_unsafe_h) - render json: { success: true, inventory: @game.player_state['inventory'] } - when 'remove' - @game.remove_inventory_item!(item['id']) - render json: { success: true, inventory: @game.player_state['inventory'] } - else - render json: { success: false, message: 'Invalid action' }, status: :bad_request - end - end - - private - - def set_game - @game = Game.find(params[:id]) - end - - def build_room_layout - layout = {} - @game.scenario_data['rooms'].each do |room_id, room_data| - layout[room_id] = { - connections: room_data['connections'], - locked: room_data['locked'] || false - } - end - layout - end - end - end -end diff --git a/app/controllers/break_escape/games_controller.rb b/app/controllers/break_escape/games_controller.rb index 5a42eec..d634951 100644 --- a/app/controllers/break_escape/games_controller.rb +++ b/app/controllers/break_escape/games_controller.rb @@ -2,7 +2,7 @@ require 'open3' module BreakEscape class GamesController < ApplicationController - before_action :set_game, only: [:show, :scenario, :ink, :room] + before_action :set_game, only: [:show, :scenario, :ink, :room, :sync_state, :unlock, :inventory] def show authorize @game if defined?(Pundit) @@ -11,10 +11,9 @@ module BreakEscape # GET /games/:id/scenario # Returns scenario JSON for this game instance - # Filtered for lazy-loading: only metadata and connections, no room contents def scenario authorize @game if defined?(Pundit) - render json: @game.filtered_scenario_for_bootstrap + render json: @game.scenario_data end # GET /games/:id/room/:room_id @@ -72,6 +71,82 @@ module BreakEscape render_error("Invalid JSON in compiled ink: #{e.message}", :internal_server_error) end + # PUT /games/:id/sync_state + # Periodic state sync from client + def sync_state + authorize @game if defined?(Pundit) + + # Update allowed fields + if params[:currentRoom] + @game.player_state['currentRoom'] = params[:currentRoom] + end + + if params[:globalVariables] + @game.update_global_variables!(params[:globalVariables].to_unsafe_h) + end + + @game.save! + + render json: { success: true } + end + + # POST /games/:id/unlock + # Validate unlock attempt + def unlock + authorize @game if defined?(Pundit) + + target_type = params[:targetType] + target_id = params[:targetId] + attempt = params[:attempt] + method = params[:method] + + is_valid = @game.validate_unlock(target_type, target_id, attempt, method) + + if is_valid + if target_type == 'door' + @game.unlock_room!(target_id) + room_data = @game.filtered_room_data(target_id) + + render json: { + success: true, + type: 'door', + roomData: room_data + } + else + @game.unlock_object!(target_id) + render json: { + success: true, + type: 'object' + } + end + else + render json: { + success: false, + message: 'Invalid attempt' + }, status: :unprocessable_entity + end + end + + # POST /games/:id/inventory + # Update inventory + def inventory + authorize @game if defined?(Pundit) + + action_type = params[:action_type] || params[:actionType] + item = params[:item] + + case action_type + when 'add' + @game.add_inventory_item!(item.to_unsafe_h) + render json: { success: true, inventory: @game.player_state['inventory'] } + when 'remove' + @game.remove_inventory_item!(item['id']) + render json: { success: true, inventory: @game.player_state['inventory'] } + else + render json: { success: false, message: 'Invalid action' }, status: :bad_request + end + end + private def set_game diff --git a/config/routes.rb b/config/routes.rb index 774785f..e12079a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,13 +19,10 @@ BreakEscape::Engine.routes.draw do get 'ink' # Returns NPC script (JIT compiled) get 'room/:room_id', to: 'games#room' # Returns room data for lazy-loading - # API endpoints - scope module: :api do - get 'bootstrap' # Initial game data - put 'sync_state' # Periodic state sync - post 'unlock' # Validate unlock attempt - post 'inventory' # Update inventory - end + # Game state and actions + put 'sync_state' # Periodic state sync + post 'unlock' # Validate unlock attempt + post 'inventory' # Update inventory end end diff --git a/public/break_escape/js/api-client.js b/public/break_escape/js/api-client.js index 2bcd7be..6940718 100644 --- a/public/break_escape/js/api-client.js +++ b/public/break_escape/js/api-client.js @@ -68,11 +68,6 @@ export class ApiClient { return response.json(); } - // Bootstrap - get initial game data - static async bootstrap() { - return this.get('/bootstrap'); - } - // Get scenario JSON static async getScenario() { return this.get('/scenario');