Permalink
Browse files

core of pet loading, still needs get image hash, download assets

  • Loading branch information...
1 parent 8b7b400 commit bb233359d8590229a3c2931860b078277ba4d433 @matchu matchu committed Oct 7, 2010
View
@@ -1,22 +1,19 @@
source 'http://rubygems.org'
gem 'rails', '3.0.0'
-
gem 'sqlite3-ruby', :require => 'sqlite3'
+gem 'compass', '~> 0.10.1'
gem 'haml', '~> 3.0.18'
-
-gem 'will_paginate', '~> 3.0.pre2'
-
gem 'rdiscount', '~> 1.6.5'
-
-gem 'compass', '~> 0.10.1'
+gem 'RocketAMF', '~> 0.2.1'
+gem 'will_paginate', '~> 3.0.pre2'
group :development do
gem 'mysql'
end
group :test do
- gem 'rspec-rails', '~> 2.0.0.beta.22'
gem 'factory_girl_rails', '~> 1.0'
+ gem 'rspec-rails', '~> 2.0.0.beta.22'
end
View
@@ -1,6 +1,7 @@
GEM
remote: http://rubygems.org/
specs:
+ RocketAMF (0.2.1)
abstract (1.0.0)
actionmailer (3.0.0)
actionpack (= 3.0.0)
@@ -92,6 +93,7 @@ PLATFORMS
ruby
DEPENDENCIES
+ RocketAMF (~> 0.2.1)
compass (~> 0.10.1)
factory_girl_rails (~> 1.0)
haml (~> 3.0.18)
View
@@ -1,8 +1,10 @@
class Item < ActiveRecord::Base
- include SwfAssetParent
-
SwfAssetType = 'object'
+ has_many :parent_swf_asset_relationships, :foreign_key => 'parent_id',
+ :conditions => {:swf_asset_type => SwfAssetType}
+ has_many :swf_assets, :through => :parent_swf_asset_relationships
+
NCRarities = [0, 500]
PaintbrushSetDescription = 'This item is part of a deluxe paint brush set!'
@@ -102,6 +104,89 @@ def as_json(options = {})
}
end
+ def before_save
+ sold_in_mall = false
+ end
+
+ def origin_registry_info=(info)
+ # bear in mind that numbers from registries are floats
+ self.species_support_ids = info[:species_support].map(&:to_i)
+ attribute_names.each do |attribute|
+ value = info[attribute.to_sym]
+ if value
+ value = value.to_i if value.is_a? Float
+ self[attribute] = value
+ end
+ end
+ end
+
+ def self.collection_from_pet_type_and_registries(pet_type, info_registry, asset_registry)
+ # bear in mind that registries are arrays with many nil elements,
+ # due to how the parser works
+ items = {}
+ item_ids = []
+ info_registry.each do |info|
+ if info
+ item_ids << info[:obj_info_id].to_i
+ end
+ end
+ existing_relationships_by_item_id_and_swf_asset_id = {}
+ existing_items = Item.find_all_by_id(item_ids, :include => :parent_swf_asset_relationships)
+ existing_items.each do |item|
+ items[item.id] = item
+ relationships_by_swf_asset_id = {}
+ item.parent_swf_asset_relationships.each do |relationship|
+ relationships_by_swf_asset_id[relationship.swf_asset_id] = relationship
+ end
+ existing_relationships_by_item_id_and_swf_asset_id[item.id] =
+ relationships_by_swf_asset_id
+ end
+ swf_asset_ids = []
+ asset_registry.each_with_index do |asset_data, index|
+ swf_asset_ids << index if asset_data
+ end
+ existing_swf_assets = SwfAsset.find_all_by_id(swf_asset_ids)
+ existing_swf_assets_by_id = {}
+ existing_swf_assets.each do |swf_asset|
+ existing_swf_assets_by_id[swf_asset.id] = swf_asset
+ end
+ relationships_by_item_id = {}
+ asset_registry.each do |asset_data|
+ if asset_data
+ item_id = asset_data[:obj_info_id].to_i
+ item = items[item_id]
+ unless item
+ item = Item.new
+ item.id = item_id
+ items[item_id] = item
+ end
+ item.origin_registry_info = info_registry[item.id]
+ swf_asset_id = asset_data[:asset_id].to_i
+ swf_asset = existing_swf_assets[swf_asset_id]
+ unless swf_asset
+ swf_asset = SwfAsset.new
+ swf_asset.id = swf_asset_id
+ end
+ swf_asset.origin_object_data = asset_data
+ swf_asset.origin_pet_type = pet_type
+ relationship = existing_relationships_by_item_id_and_swf_asset_id[item.id][swf_asset_id] rescue nil
+ unless relationship
+ relationship = ParentSwfAssetRelationship.new
+ relationship.parent_id = item.id
+ relationship.swf_asset_type = SwfAssetType
+ relationship.swf_asset_id = swf_asset.id
+ end
+ relationship.swf_asset = swf_asset
+ relationships_by_item_id[item_id] ||= []
+ relationships_by_item_id[item_id] << relationship
+ end
+ end
+ relationships_by_item_id.each do |item_id, relationships|
+ items[item_id].parent_swf_asset_relationships = relationships
+ end
+ items.values
+ end
+
private
SearchFilterScopes = []
View
@@ -0,0 +1,55 @@
+class Pet < ActiveRecord::Base
+ GATEWAY_URL = 'http://www.neopets.com/amfphp/gateway.php'
+ AMF_SERVICE_NAME = 'CustomPetService'
+ PET_VIEWER_METHOD = 'getViewerData'
+ PET_NOT_FOUND_REMOTE_ERROR = 'PHP: Unable to retrieve records from the database.'
+
+ belongs_to :pet_type
+
+ attr_reader :items
+
+ def load!
+ require 'ostruct'
+ begin
+ envelope = Pet.amf_service.fetch(PET_VIEWER_METHOD, name, nil)
+ rescue RocketAMF::RemoteGateway::AMFError => e
+ if e.message == PET_NOT_FOUND_REMOTE_ERROR
+ raise PetNotFound, "Pet #{name.inspect} does not exist"
+ end
+ raise
+ end
+ contents = OpenStruct.new(envelope.messages[0].data.body)
+ pet_data = OpenStruct.new(contents.custom_pet)
+ self.pet_type = PetType.find_or_initialize_by_species_id_and_color_id(
+ pet_data.species_id.to_i,
+ pet_data.color_id.to_i
+ )
+ self.pet_type.body_id = pet_data.body_id
+ @pet_state = self.pet_type.add_pet_state_from_biology! pet_data.biology_by_zone
+ @items = Item.collection_from_pet_type_and_registries(self.pet_type,
+ contents.object_info_registry, contents.object_asset_registry)
+ true
+ end
+
+ def self.load(name)
+ pet = Pet.find_or_initialize_by_name(name)
+ pet.load!
+ pet
+ end
+
+ private
+
+ def self.amf_service
+ @amf_service ||= gateway.service AMF_SERVICE_NAME
+ end
+
+ def self.gateway
+ unless @gateway
+ require 'rocketamf/remote_gateway'
+ @gateway = RocketAMF::RemoteGateway.new(GATEWAY_URL)
+ end
+ @gateway
+ end
+
+ class PetNotFound < Exception;end
+end
@@ -1,4 +1,73 @@
class PetState < ActiveRecord::Base
- include SwfAssetParent
SwfAssetType = 'biology'
+
+ has_many :parent_swf_asset_relationships, :foreign_key => 'parent_id',
+ :conditions => {:swf_asset_type => SwfAssetType}
+ has_many :swf_assets, :through => :parent_swf_asset_relationships
+
+ belongs_to :pet_type
+
+ alias_method :swf_asset_ids_from_association, :swf_asset_ids
+
+ def swf_asset_ids
+ self['swf_asset_ids']
+ end
+
+ def swf_asset_ids=(ids)
+ self['swf_asset_ids'] = ids
+ end
+
+ def self.from_pet_type_and_biology_info(pet_type, info)
+ swf_asset_ids = []
+ info.each do |asset_info|
+ if asset_info
+ swf_asset_ids << asset_info[:part_id].to_i
+ end
+ end
+ swf_asset_ids_str = swf_asset_ids.join(',')
+ if pet_type.new_record?
+ pet_state = self.new :swf_asset_ids => swf_asset_ids_str
+ else
+ pet_state = self.find_or_initialize_by_pet_type_id_and_swf_asset_ids(
+ pet_type.id,
+ swf_asset_ids_str
+ )
+ end
+ existing_swf_assets = SwfAsset.find_all_by_id(swf_asset_ids)
+ existing_swf_assets_by_id = {}
+ existing_swf_assets.each do |swf_asset|
+ existing_swf_assets_by_id[swf_asset.id] = swf_asset
+ end
+ existing_relationships_by_swf_asset_id = {}
+ unless pet_state.new_record?
+ pet_state.parent_swf_asset_relationships.each do |relationship|
+ existing_relationships_by_swf_asset_id[relationship.swf_asset_id] = relationship
+ end
+ end
+ pet_state.pet_type = pet_type # save the second case from having to look it up by ID
+ relationships = []
+ info.each do |asset_info|
+ if asset_info
+ swf_asset_id = asset_info[:part_id].to_i
+ swf_asset = existing_swf_assets_by_id[swf_asset_id]
+ unless swf_asset
+ swf_asset = SwfAsset.new
+ swf_asset.id = swf_asset_id
+ end
+ swf_asset.origin_biology_data = asset_info
+ swf_asset.origin_pet_type = pet_type
+ relationship = existing_relationships_by_swf_asset_id[swf_asset_id]
+ unless relationship
+ relationship ||= ParentSwfAssetRelationship.new
+ relationship.parent_id = pet_state.id
+ relationship.swf_asset_type = SwfAssetType
+ relationship.swf_asset_id = swf_asset.id
+ end
+ relationship.swf_asset = swf_asset
+ relationships << relationship
+ end
+ end
+ pet_state.parent_swf_asset_relationships = relationships
+ pet_state
+ end
end
@@ -3,7 +3,6 @@ class PetType < ActiveRecord::Base
BasicHashes = YAML::load_file(Rails.root.join('config', 'basic_type_hashes.yml'))
-
StandardBodyIds = PetType.select(arel_table[:body_id]).
where(arel_table[:color_id].in(Color::BasicIds)).
group(arel_table[:species_id]).map(&:body_id)
@@ -55,4 +54,10 @@ def species
def image_hash
BasicHashes[species.name][color.name]
end
+
+ def add_pet_state_from_biology!(biology)
+ pet_state = PetState.from_pet_type_and_biology_info(self, biology)
+ self.pet_states << pet_state
+ pet_state
+ end
end
@@ -33,4 +33,21 @@ def as_json(options={})
def zone
@zone ||= Zone.find(zone_id)
end
+
+ def origin_pet_type=(pet_type)
+ self.body_id = pet_type.body_id
+ end
+
+ def origin_biology_data=(data)
+ self.type = 'biology'
+ self.zone_id = data[:zone_id].to_i
+ self.url = data[:asset_url]
+ self.zones_restrict = data[:zones_restrict]
+ end
+
+ def origin_object_data=(data)
+ self.type = 'object'
+ self.zone_id = data[:zone_id].to_i
+ self.url = data[:asset_url]
+ end
end
@@ -0,0 +1,10 @@
+module DeferredAttributes
+ def attr_deferred(name, &block)
+ instance_variable_name = "@#{name}"
+ define_method name do
+ value = instance_variable_get(instance_variable_name)
+ return value if value
+ instance_variable_set(instance_variable_name, self.instance_eval(&block))
+ end
+ end
+end
@@ -0,0 +1,18 @@
+require 'net/http'
+require 'rocketamf'
+require_relative 'remote_gateway/service'
+require_relative 'remote_gateway/request'
+
+module RocketAMF
+ class RemoteGateway
+ attr_reader :uri
+
+ def initialize(url)
+ @uri = URI.parse url
+ end
+
+ def service(name)
+ Service.new(self, name)
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit bb23335

Please sign in to comment.