diff --git a/app/controllers/pets_controller.rb b/app/controllers/pets_controller.rb index bff2de63..084cc91d 100644 --- a/app/controllers/pets_controller.rb +++ b/app/controllers/pets_controller.rb @@ -2,7 +2,7 @@ class PetsController < ApplicationController rescue_from Pet::PetNotFound, with: :pet_not_found rescue_from PetType::DownloadError, SwfAsset::DownloadError, with: :asset_download_error rescue_from Pet::DownloadError, with: :pet_download_error - rescue_from Pet::AltStyleNotSupportedYet, with: :alt_style_not_supported_yet + rescue_from Pet::UnexpectedDataFormat, with: :unexpected_data_format def load # Uncomment this to temporarily disable modeling for most users. @@ -84,11 +84,8 @@ class PetsController < ApplicationController status: :forbidden end - def alt_style_not_supported_yet - pet_load_error( - long_message: "This pet is using the new Alt Styles feature, which " + - "we're still working on. Thank you for trying, we'll be ready soon!!", - status: :bad_request, - ) + def unexpected_data_format + pet_load_error long_message: t('pets.load.unexpected_data_format'), + status: :internal_server_error end end diff --git a/app/models/alt_style.rb b/app/models/alt_style.rb new file mode 100644 index 00000000..30741ed8 --- /dev/null +++ b/app/models/alt_style.rb @@ -0,0 +1,16 @@ +class AltStyle < ApplicationRecord + belongs_to :species + belongs_to :color + + has_many :parent_swf_asset_relationships, as: :parent + has_many :swf_assets, through: :parent_swf_asset_relationships + + def biology=(biology) + # TODO: This is very similar to what `PetState` does, but like… much much + # more compact? Idk if I'm missing something, or if I was just that much + # more clueless back when I wrote it, lol 😅 + biology.values.each do |asset_data| + self.swf_assets << SwfAsset.from_biology_data(self.body_id, asset_data) + end + end +end diff --git a/app/models/pet.rb b/app/models/pet.rb index 388e05c4..dfaee1ff 100644 --- a/app/models/pet.rb +++ b/app/models/pet.rb @@ -11,7 +11,7 @@ class Pet < ApplicationRecord belongs_to :pet_type - attr_reader :items, :pet_state + attr_reader :items, :pet_state, :alt_style scope :with_pet_type_color_ids, ->(color_ids) { joins(:pet_type).where(PetType.arel_table[:id].in(color_ids)) @@ -33,9 +33,9 @@ class Pet < ApplicationRecord pet_data = viewer_data[:custom_pet] - if pet_data[:alt_style] - raise AltStyleNotSupportedYet - end + raise UnexpectedDataFormat unless pet_data[:species_id] + raise UnexpectedDataFormat unless pet_data[:color_id] + raise UnexpectedDataFormat unless pet_data[:body_id] self.pet_type = PetType.find_or_initialize_by( species_id: pet_data[:species_id].to_i, @@ -43,9 +43,26 @@ class Pet < ApplicationRecord ) self.pet_type.body_id = pet_data[:body_id] self.pet_type.origin_pet = self - biology = pet_data[:biology_by_zone] - biology[0] = nil # remove effects if present - @pet_state = self.pet_type.add_pet_state_from_biology! biology + + pet_state_biology = pet_data[:alt_style] ? + pet_data[:original_biology] : pet_data[:biology_by_zone] + raise UnexpectedDataFormat if pet_state_biology.empty? + pet_state_biology[0] = nil # remove effects if present + @pet_state = self.pet_type.add_pet_state_from_biology! pet_state_biology + + if pet_data[:alt_style] + raise UnexpectedDataFormat unless pet_data[:alt_color] + raise UnexpectedDataFormat if pet_data[:biology_by_zone].empty? + + @alt_style = AltStyle.new( + id: pet_data[:alt_style].to_i, + color_id: pet_data[:alt_color].to_i, + species_id: pet_data[:species_id].to_i, + body_id: pet_data[:body_id].to_i, + biology: pet_data[:biology_by_zone], + ) + end + @items = Item.collection_from_pet_type_and_registries(self.pet_type, viewer_data[:object_info_registry], viewer_data[:object_asset_registry], options[:item_scope]) @@ -83,6 +100,10 @@ class Pet < ApplicationRecord item.handle_assets! end end + + if @alt_style + @alt_style.save! + end end def self.load(name, options={}) @@ -123,6 +144,6 @@ class Pet < ApplicationRecord class PetNotFound < RuntimeError;end class DownloadError < RuntimeError;end - class AltStyleNotSupportedYet < RuntimeError;end + class UnexpectedDataFormat < RuntimeError;end end diff --git a/app/models/swf_asset.rb b/app/models/swf_asset.rb index b072dac3..a3478bbe 100644 --- a/app/models/swf_asset.rb +++ b/app/models/swf_asset.rb @@ -180,6 +180,15 @@ class SwfAsset < ApplicationRecord self.manifest_url = parsed_manifest_url.to_s end + def self.from_biology_data(body_id, data) + remote_id = data[:part_id].to_i + swf_asset = SwfAsset.find_or_initialize_by type: 'biology', + remote_id: remote_id + swf_asset.body_id = body_id + swf_asset.origin_biology_data = data + swf_asset + end + def self.from_wardrobe_link_params(ids) where(( arel_table[:remote_id].in(ids[:biology]).and(arel_table[:type].eq('biology')) diff --git a/config/locales/en.yml b/config/locales/en.yml index b299e5d0..6122ed8f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -784,6 +784,10 @@ en: modeling_disabled: We've turned off pet loading for a bit, while we investigate some changes in how it works. We'll be back as soon as we can! + unexpected_data_format: + We found the pet and what it's wearing, but the data isn't in quite the + format we usually expect, so we're stopping to make sure we don't make + a mistake. Sorry about this—if it keeps happening, let us know! swf_assets: links: diff --git a/db/migrate/20240124102340_create_alt_styles.rb b/db/migrate/20240124102340_create_alt_styles.rb new file mode 100644 index 00000000..80fd3c46 --- /dev/null +++ b/db/migrate/20240124102340_create_alt_styles.rb @@ -0,0 +1,11 @@ +class CreateAltStyles < ActiveRecord::Migration[7.1] + def change + create_table :alt_styles do |t| + t.references :species, type: :integer, null: false, foreign_key: true + t.references :color, type: :integer, null: false, foreign_key: true + t.integer :body_id, null: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 8f978e45..6ffe0d55 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,17 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2024_01_23_133215) do +ActiveRecord::Schema[7.1].define(version: 2024_01_24_102340) do + create_table "alt_styles", charset: "utf8mb4", collation: "utf8mb4_general_ci", force: :cascade do |t| + t.integer "species_id", null: false + t.integer "color_id", null: false + t.integer "body_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["color_id"], name: "index_alt_styles_on_color_id" + t.index ["species_id"], name: "index_alt_styles_on_species_id" + end + create_table "auth_servers", id: :integer, charset: "latin1", collation: "latin1_swedish_ci", force: :cascade do |t| t.string "short_name", limit: 10, null: false t.string "name", limit: 40, null: false @@ -301,4 +311,6 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_23_133215) do t.string "plain_label", null: false end + add_foreign_key "alt_styles", "colors" + add_foreign_key "alt_styles", "species" end