hensei-api/app/controllers/api/v1/grid_characters_controller.rb
Justin Edmund 7faa4883f0
June 2023 Update (#102)
* Implements advanced filters (#90)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix a bug where unauthenticated users couldn't view profiles (#92)

* Implements advanced filters (#90) (#91)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix being unable to see profiles when unauth

* Add tables used for Siero's revival (#94)

* Implements advanced filters (#90) (#91)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Deploy unauthenticated profile fix (#93)

* Implements advanced filters (#90)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix a bug where unauthenticated users couldn't view profiles (#92)

* Implements advanced filters (#90) (#91)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix being unable to see profiles when unauth

* Add guidebooks migration

* Implement business logic for reading Guidebooks

* Change to individual guidebook columns

* Properly output guidebook description

* Move to 1-index guidebooks

* Update party-related files for 1-index guidebooks

* Add tables for Siero

* Update download and export scripts

* Support for Siero, raids rework and edit party rework (#96)

* Add guidebooks migration

* Implement business logic for reading Guidebooks

* Change to individual guidebook columns

* Properly output guidebook description

* Move to 1-index guidebooks

* Update party-related files for 1-index guidebooks

* Add tables for Siero

* Add raid groups table

* Update raid model

To belong to the RaidGroup class

* Update job class

To have many job skills

* Add endpoint for raid groups

* Update Raid blueprint with views

* Added down for creating table

* Add guidebooks flag and auto summon flag

* Guidebooks → RaidGroup
* Auto summon → Party

* Add views to Raid blueprint

* Add views and guidebook flag to RaidGroup blueprint

* Add auto summon and Raid view to Party blueprint

* Add quick summons (#97)

* Adds quick summon migration
* Add route to update quick summon
* Add logic to update quick summon

* Remove ap call

* Add logic to updating summon uncap

You couldn't actually update summon transcendence on staging, maybe due to a bug?

Now you can. And it won't let you update outside of the bounds of what is defined on the canonical object.

* Fix summon logic

Updated logic for updating summon uncap and transcendence levels and quick summon status.

* Fix searching in Japanese (#99)

This was broken because we were using the browser-provided locale as a prefix to our method, but that is 'ja' and our methods were prefixed with 'jp'.

* Fix display of base skills (#100)

Base skills were not displaying due to a missing case in our search code. This is now fixed.

* Update awakenings (#101)

* Deploy unauthenticated profile fix (#93)

* Implements advanced filters (#90)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix a bug where unauthenticated users couldn't view profiles (#92)

* Implements advanced filters (#90) (#91)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix being unable to see profiles when unauth

* Add tables used for Siero's revival (#94)

* Implements advanced filters (#90) (#91)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Deploy unauthenticated profile fix (#93)

* Implements advanced filters (#90)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix a bug where unauthenticated users couldn't view profiles (#92)

* Implements advanced filters (#90) (#91)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix being unable to see profiles when unauth

* Add guidebooks migration

* Implement business logic for reading Guidebooks

* Change to individual guidebook columns

* Properly output guidebook description

* Move to 1-index guidebooks

* Update party-related files for 1-index guidebooks

* Add tables for Siero

* Adds guidebooks and gacha tables (#95)

* Implements advanced filters (#90)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix a bug where unauthenticated users couldn't view profiles (#92)

* Implements advanced filters (#90) (#91)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix being unable to see profiles when unauth

* Add tables used for Siero's revival (#94)

* Implements advanced filters (#90) (#91)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Deploy unauthenticated profile fix (#93)

* Implements advanced filters (#90)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix a bug where unauthenticated users couldn't view profiles (#92)

* Implements advanced filters (#90) (#91)

* Add advanced filters

Adds new filters to search:

* Full auto
* Charge attack
* Auto guard
* Number of weapons (user-selectable now)
* Number of summons
* Number of characters
* Maximum number of turns
* Maximum number of buttons
* Maximum clear time
* User quality (No anonymous users)
* Name quality (No untitled teams)
* Remixes (Only show original teams)

* Update advanced filter params

* Add default to party counter cache

* Fix being unable to see profiles when unauth

* Add guidebooks migration

* Implement business logic for reading Guidebooks

* Change to individual guidebook columns

* Properly output guidebook description

* Move to 1-index guidebooks

* Update party-related files for 1-index guidebooks

* Add tables for Siero

* Update download and export scripts

* Support for Siero, raids rework and edit party rework (#96)

* Add guidebooks migration

* Implement business logic for reading Guidebooks

* Change to individual guidebook columns

* Properly output guidebook description

* Move to 1-index guidebooks

* Update party-related files for 1-index guidebooks

* Add tables for Siero

* Add raid groups table

* Update raid model

To belong to the RaidGroup class

* Update job class

To have many job skills

* Add endpoint for raid groups

* Update Raid blueprint with views

* Added down for creating table

* Add guidebooks flag and auto summon flag

* Guidebooks → RaidGroup
* Auto summon → Party

* Add views to Raid blueprint

* Add views and guidebook flag to RaidGroup blueprint

* Add auto summon and Raid view to Party blueprint

* Remove ap call

* Add quick summons (#97)

* Adds quick summon migration
* Add route to update quick summon
* Add logic to update quick summon

* Add logic to updating summon uncap

You couldn't actually update summon transcendence on staging, maybe due to a bug?

Now you can. And it won't let you update outside of the bounds of what is defined on the canonical object.

* Fix summon logic

Updated logic for updating summon uncap and transcendence levels and quick summon status.

* Fix searching in Japanese (#99)

This was broken because we were using the browser-provided locale as a prefix to our method, but that is 'ja' and our methods were prefixed with 'jp'.

* Fix display of base skills (#100)

Base skills were not displaying due to a missing case in our search code. This is now fixed.

* Squash migrations into one file

* Add migrations

This adds migrations and data migrations for the awakening update.

* A new `Awakenings` table now exists that stores all possible awakenings, with a column for object type.
* GridCharacter and GridWeapon now have `awakening_id` and `awakening_level` fields. Their `awakening` and `awakening_type` fields were removed.
* Weapons have a mapping table, `WeaponAwakenings`, as not all weapons can be awakened.
* Data migrations are included to migrate existing user data. They should be run automatically when the migration is run with `rails db:migrate:with_data`

* Add and update models

This updates models for the awakening update.

* Awakening and WeaponAwakening models were added
* Weapon, GridWeapon and GridCharacter models get relationships to the new models defined
* GridCharacter had a validation on `awakening_level` that needed to be fixed

* Update controllers

This updates the GridCharacters and GridWeapons controllers to accept the new fields `awakening_id` and `awakening_level` from clients

* Update blueprints

This updates the blueprints to match the new schema. The new AwakeningBlueprint was accidentally added already, oops.

* Remove re-added migrations

* Implement removing job skills (#103)

This lets users remove job skills, for if they accidentally set them.

* Fix migration
2023-06-19 03:53:48 -07:00

173 lines
6.8 KiB
Ruby

# frozen_string_literal: true
module Api
module V1
class GridCharactersController < Api::V1::ApiController
attr_reader :party, :incoming_character, :current_characters
before_action :find_party, only: :create
before_action :set, only: %i[update destroy]
before_action :authorize, only: %i[create update destroy]
before_action :find_incoming_character, only: :create
before_action :find_current_characters, only: :create
def create
if !conflict_characters.nil? && conflict_characters.length.positive?
# Render a template with the conflicting and incoming characters,
# as well as the selected position, so the user can be presented with
# a decision.
# Up to 3 characters can be removed at the same time
conflict_view = render_conflict_view(conflict_characters, incoming_character, character_params[:position])
render json: conflict_view
else
# Destroy the grid character in the position if it is already filled
if GridCharacter.where(party_id: party.id, position: character_params[:position]).exists?
character = GridCharacter.where(party_id: party.id, position: character_params[:position]).limit(1)[0]
character.destroy
end
# Then, create a new grid character
character = GridCharacter.create!(character_params.merge(party_id: party.id,
character_id: incoming_character.id))
if character.save!
grid_character_view = render_grid_character_view(character)
render json: grid_character_view, status: :created
end
end
end
def update
mastery = {}
%i[ring1 ring2 ring3 ring4 earring awakening].each do |key|
value = character_params.to_h[key]
mastery[key] = value unless value.nil?
end
@character.attributes = character_params.merge(mastery)
return render json: GridCharacterBlueprint.render(@character, view: :full) if @character.save
render_validation_error_response(@character)
end
def resolve
incoming = Character.find(resolve_params[:incoming])
conflicting = resolve_params[:conflicting].map { |id| GridCharacter.find(id) }
party = conflicting.first.party
# Destroy each conflicting character
conflicting.each { |character| GridCharacter.destroy(character.id) }
# Destroy the character at the desired position if it exists
existing_character = GridCharacter.where(party: party.id, position: resolve_params[:position]).first
GridCharacter.destroy(existing_character.id) if existing_character
if incoming.special
uncap_level = 3
uncap_level = 5 if incoming.ulb
uncap_level = 4 if incoming.flb
else
uncap_level = 4
uncap_level = 6 if incoming.ulb
uncap_level = 5 if incoming.flb
end
character = GridCharacter.create!(party_id: party.id, character_id: incoming.id,
position: resolve_params[:position], uncap_level: uncap_level)
render json: GridCharacterBlueprint.render(character, view: :nested), status: :created if character.save!
end
def update_uncap_level
character = GridCharacter.find(character_params[:id])
render_unauthorized_response if current_user && (character.party.user != current_user)
character.uncap_level = character_params[:uncap_level]
character.transcendence_step = character_params[:transcendence_step]
return unless character.save!
render json: GridCharacterBlueprint.render(character, view: :nested, root: :grid_character)
end
# TODO: Implement removing characters
def destroy
render_unauthorized_response if @character.party.user != current_user
return render json: GridCharacterBlueprint.render(@character, view: :destroyed) if @character.destroy
end
private
def conflict_characters
@conflict_characters ||= find_conflict_characters(incoming_character)
end
def find_conflict_characters(incoming_character)
# Check all character ids on incoming character against current characters
conflict_ids = (current_characters & incoming_character.character_id)
return unless conflict_ids.length.positive?
# Find conflicting character ids in party characters
party.characters.filter do |c|
c if (conflict_ids & c.character.character_id).length.positive?
end.flatten
end
def find_current_characters
# Make a list of all character IDs
@current_characters = party.characters.map do |c|
Character.find(c.character.id).character_id
end.flatten
end
def set
@character = GridCharacter.find(params[:id])
end
def find_incoming_character
@incoming_character = Character.find(character_params[:character_id])
end
def find_party
@party = Party.find(character_params[:party_id])
render_unauthorized_response if current_user && (party.user != current_user)
end
def authorize
# Create
unauthorized_create = @party && (@party.user != current_user || @party.edit_key != edit_key)
unauthorized_update = @character && @character.party && (@character.party.user != current_user || @character.party.edit_key != edit_key)
render_unauthorized_response if unauthorized_create || unauthorized_update
end
# Specify whitelisted properties that can be modified.
def character_params
params.require(:character).permit(:id, :party_id, :character_id, :position,
:uncap_level, :transcendence_step, :perpetuity,
:awakening_id, :awakening_level,
ring1: %i[modifier strength], ring2: %i[modifier strength],
ring3: %i[modifier strength], ring4: %i[modifier strength],
earring: %i[modifier strength])
end
def resolve_params
params.require(:resolve).permit(:position, :incoming, conflicting: [])
end
def render_conflict_view(conflict_characters, incoming_character, incoming_position)
ConflictBlueprint.render(nil,
view: :characters,
conflict_characters: conflict_characters,
incoming_character: incoming_character,
incoming_position: incoming_position)
end
def render_grid_character_view(grid_character)
GridCharacterBlueprint.render(grid_character, view: :nested)
end
end
end
end