1
0
Fork 0
forked from OpenNeo/impress

basic neopia api integration

This commit is contained in:
Emi Matchu 2013-12-08 22:59:36 -06:00
parent fef87d664a
commit 7c6e607612
11 changed files with 138 additions and 41 deletions

View file

@ -211,6 +211,7 @@ View.Hash = function (wardrobe) {
STRING: 2, STRING: 2,
INTEGER_ARRAY: 3 INTEGER_ARRAY: 3
}, KEYS = { }, KEYS = {
biologies: TYPES.INTEGER_ARRAY,
closet: TYPES.INTEGER_ARRAY, closet: TYPES.INTEGER_ARRAY,
color: TYPES.INTEGER, color: TYPES.INTEGER,
name: TYPES.STRING, name: TYPES.STRING,
@ -252,6 +253,9 @@ View.Hash = function (wardrobe) {
} }
} }
if(new_data.biologies) {
wardrobe.outfits.setPetStateAssetsByIds(new_data.biologies);
}
if(new_data.color !== data.color || new_data.species !== data.species) { if(new_data.color !== data.color || new_data.species !== data.species) {
wardrobe.outfits.setPetTypeByColorAndSpecies(new_data.color, new_data.species); wardrobe.outfits.setPetTypeByColorAndSpecies(new_data.color, new_data.species);
} }
@ -372,7 +376,7 @@ View.Hash = function (wardrobe) {
singleOutfitResponse('updatePetState', function (pet_state) { singleOutfitResponse('updatePetState', function (pet_state) {
var pet_type = wardrobe.outfits.getPetType(); var pet_type = wardrobe.outfits.getPetType();
if(pet_state.id != data.state && pet_type && (data.state || pet_state.id != pet_type.pet_states[0].id)) { if(pet_state.id != data.state && pet_type && (data.state || pet_state.id != pet_type.pet_states[0].id)) {
changeQuery({state: pet_state.id}); changeQuery({biologies: undefined, state: pet_state.id});
} }
}); });
@ -384,6 +388,7 @@ View.Hash = function (wardrobe) {
wardrobe.outfits.bind('loadOutfit', function (outfit) { wardrobe.outfits.bind('loadOutfit', function (outfit) {
changeQuery({ changeQuery({
biologies: undefined,
closet: outfit.getClosetItemIds(), closet: outfit.getClosetItemIds(),
color: outfit.pet_type.color_id, color: outfit.pet_type.color_id,
objects: outfit.getWornItemIds(), objects: outfit.getWornItemIds(),

View file

@ -476,9 +476,26 @@ function Wardrobe() {
} }
} }
this.setPetStateAssetsByIds = function (assetIds, petStateOnLoad) {
this.pet_state = PetState.createFromAssetIds(assetIds);
this.pet_state.loadAssets(petStateOnLoad);
}
this.setPetStateById = function (id, petStateOnLoad) { this.setPetStateById = function (id, petStateOnLoad) {
if(!id && this.pet_type) { if(!id && this.pet_type) {
id = this.pet_type.pet_states[0].id; if(this.pet_state) {
var candidate;
for(var i = 0; i < this.pet_type.pet_states.length; i++) {
candidate = this.pet_type.pet_states[i];
if(arraysMatch(this.pet_state.assetIds, candidate.assetIds)) {
id = candidate.id;
break;
}
}
}
if(!id) {
id = this.pet_type.pet_states[0].id;
}
} }
if(id) { if(id) {
this.pet_state = PetState.find(id); this.pet_state = PetState.find(id);
@ -712,6 +729,7 @@ function Wardrobe() {
this.id = id; this.id = id;
this.gender_mood_description = ''; this.gender_mood_description = '';
this.assetIds = [];
this.assets = []; this.assets = [];
this.loadAssets = function (success) { this.loadAssets = function (success) {
@ -722,6 +740,9 @@ function Wardrobe() {
$.getJSON('/pet_states/' + pet_state.id + '/swf_assets.json', $.getJSON('/pet_states/' + pet_state.id + '/swf_assets.json',
function (data) { function (data) {
pet_state.assets = $.map(data, function (obj) { return new BiologyAsset(obj) }); pet_state.assets = $.map(data, function (obj) { return new BiologyAsset(obj) });
pet_state.assetIds = $.map(pet_state.assets, function (asset) {
return asset.id;
});
loaded = true; loaded = true;
success(pet_state); success(pet_state);
}); });
@ -730,11 +751,32 @@ function Wardrobe() {
this.update = function (data) { this.update = function (data) {
this.gender_mood_description = data.gender_mood_description; this.gender_mood_description = data.gender_mood_description;
this.assetIds = data.swf_asset_ids;
} }
PetState.cache[id] = this; PetState.cache[id] = this;
} }
PetState.createFromAssetIds = function (assetIds) {
// Fun lame hacks to be able to create from biology asset IDs. Not even a
// real PetState, gasp!
assetIds.sort();
var petState = {
id: null,
gender_mood_description: '',
assets: [],
assetIds: assetIds,
loadAssets: function (success) {
$.getJSON('/swf_assets.json', {ids: {biology: assetIds}}, function (data) {
this.assets = $.map(data, function (obj) { return new BiologyAsset(obj) });
success(petState);
});
},
update: $.noop
};
return petState;
}
PetState.find = function (id) { PetState.find = function (id) {
var pet_state = PetState.cache[id]; var pet_state = PetState.cache[id];
if(!pet_state) { if(!pet_state) {
@ -1001,6 +1043,10 @@ function Wardrobe() {
} }
} }
this.setPetStateAssetsByIds = function (assetIds) {
outfit.setPetStateAssetsByIds(assetIds, controller.event('updatePetState'));
}
this.setPetStateById = function (pet_state_id) { this.setPetStateById = function (pet_state_id) {
outfit.setPetStateById(pet_state_id, controller.event('updatePetState')); outfit.setPetStateById(pet_state_id, controller.event('updatePetState'));
} }

View file

@ -27,6 +27,10 @@ class ApplicationController < ActionController::Base
I18n.default_locale I18n.default_locale
end end
def local_only
raise AccessDenied unless request.ip == '127.0.0.1'
end
def localized_fragment_exist?(key) def localized_fragment_exist?(key)
localized_key = localize_fragment_key(key, locale) localized_key = localize_fragment_key(key, locale)
fragment_exist?(localized_key) fragment_exist?(localized_key)

View file

@ -3,6 +3,9 @@ class PetsController < ApplicationController
rescue_from PetType::DownloadError, SwfAsset::DownloadError, :with => :asset_download_error rescue_from PetType::DownloadError, SwfAsset::DownloadError, :with => :asset_download_error
rescue_from Pet::DownloadError, :with => :pet_download_error rescue_from Pet::DownloadError, :with => :pet_download_error
protect_from_forgery except: :submit
before_filter :local_only, only: :submit
cache_sweeper :user_sweeper cache_sweeper :user_sweeper
def load def load
@ -11,14 +14,7 @@ class PetsController < ApplicationController
else else
raise Pet::PetNotFound unless params[:name] raise Pet::PetNotFound unless params[:name]
@pet = Pet.load(params[:name], :item_scope => Item.includes(:translations)) @pet = Pet.load(params[:name], :item_scope => Item.includes(:translations))
if user_signed_in? points = contribute(current_user, @pet)
points = current_user.contribute! @pet
else
@pet.save
points = true
end
@pet.translate_items
respond_to do |format| respond_to do |format|
format.html do format.html do
@ -33,8 +29,26 @@ class PetsController < ApplicationController
end end
end end
def submit
viewer_data = HashWithIndifferentAccess.new(JSON.parse(params[:viewer_data]))
@pet = Pet.from_viewer_data(viewer_data, :item_scope => Item.includes(:translations))
@user = params[:user_id].present? ? User.find(params[:user_id]) : nil
render json: {points: contribute(@user, @pet)}
end
protected protected
def contribute(user, pet)
if user.present?
points = user.contribute! pet
else
pet.save!
points = true
end
pet.translate_items
points
end
def destination def destination
case (params[:destination] || params[:origin]) case (params[:destination] || params[:origin])
when 'wardrobe' then wardrobe_path + '#' when 'wardrobe' then wardrobe_path + '#'

View file

@ -50,6 +50,10 @@ module OutfitsHelper
content_tag(:dd, search_query_description(base, filter_key)) content_tag(:dd, search_query_description(base, filter_key))
end end
def remote_load_pet_path
"http://#{Rails.configuration.neopia_host}/api/1/pet/customization"
end
def outfit_creation_summary(outfit) def outfit_creation_summary(outfit)
user = outfit.user user = outfit.user
user_link = link_to(user.name, user_contributions_path(user)) user_link = link_to(user.name, user_contributions_path(user))

View file

@ -272,8 +272,10 @@ class Item < ActiveRecord::Base
end end
def origin_registry_info=(info) def origin_registry_info=(info)
Rails.logger.debug("info! #{info}")
# bear in mind that numbers from registries are floats # bear in mind that numbers from registries are floats
self.species_support_ids = info[:species_support].map(&:to_i) species_support_strs = info['species_support'] || []
self.species_support_ids = species_support_strs.map(&:to_i)
attribute_names.each do |attribute| attribute_names.each do |attribute|
value = info[attribute.to_sym] value = info[attribute.to_sym]
if value if value

View file

@ -18,31 +18,33 @@ class Pet < ActiveRecord::Base
} }
def load!(options={}) def load!(options={})
options[:item_scope] ||= Item.scoped
options[:locale] ||= I18n.default_locale options[:locale] ||= I18n.default_locale
I18n.with_locale(options.delete(:locale)) do
I18n.with_locale(options[:locale]) do use_viewer_data(fetch_viewer_data(options.delete(:timeout)), options)
viewer_data = fetch_viewer_data(options[:timeout])
pet_data = viewer_data[: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]
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.label_by_pet(self, pet_data[:owner])
@items = Item.collection_from_pet_type_and_registries(self.pet_type,
viewer_data[:object_info_registry], viewer_data[:object_asset_registry],
options[:item_scope])
end end
true true
end end
def use_viewer_data(viewer_data, options={})
options[:item_scope] ||= Item.scoped
pet_data = viewer_data[: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]
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.label_by_pet(self, pet_data[:owner])
@items = Item.collection_from_pet_type_and_registries(self.pet_type,
viewer_data[:object_info_registry], viewer_data[:object_asset_registry],
options[:item_scope])
end
def fetch_viewer_data(timeout=4) def fetch_viewer_data(timeout=4)
begin begin
neopets_language_code = I18n.compatible_neopets_language_code_for(I18n.locale) neopets_language_code = I18n.compatible_neopets_language_code_for(I18n.locale)
@ -170,6 +172,12 @@ class Pet < ActiveRecord::Base
pet pet
end end
def self.from_viewer_data(viewer_data, options={})
pet = Pet.find_or_initialize_by_name(viewer_data[:custom_pet][:name])
pet.use_viewer_data(viewer_data, options)
pet
end
class PetNotFound < Exception;end class PetNotFound < Exception;end
class DownloadError < Exception;end class DownloadError < Exception;end
end end

View file

@ -38,7 +38,11 @@ class PetState < ActiveRecord::Base
order("glitched ASC, (mood_id = 1) DESC, COUNT(effect_assets.remote_id) ASC, COUNT(parents_swf_assets.swf_asset_id) DESC, female ASC, SUM(parents_swf_assets.swf_asset_id) ASC") order("glitched ASC, (mood_id = 1) DESC, COUNT(effect_assets.remote_id) ASC, COUNT(parents_swf_assets.swf_asset_id) DESC, female ASC, SUM(parents_swf_assets.swf_asset_id) ASC")
def as_json(options={}) def as_json(options={})
serializable_hash :only => [:id], :methods => [:gender_mood_description] {
id: id,
gender_mood_description: gender_mood_description,
swf_asset_ids: swf_asset_ids_array
}
end end
def reassign_children_to!(main_pet_state) def reassign_children_to!(main_pet_state)
@ -66,13 +70,17 @@ class PetState < ActiveRecord::Base
end end
def sort_swf_asset_ids! def sort_swf_asset_ids!
self.swf_asset_ids = swf_asset_ids.split(',').map(&:to_i).sort.join(',') self.swf_asset_ids = swf_asset_ids_array.sort.join(',')
end end
def swf_asset_ids def swf_asset_ids
self['swf_asset_ids'] self['swf_asset_ids']
end end
def swf_asset_ids_array
swf_asset_ids.split(',').map(&:to_i)
end
def swf_asset_ids=(ids) def swf_asset_ids=(ids)
self['swf_asset_ids'] = ids self['swf_asset_ids'] = ids
end end

View file

@ -10,18 +10,18 @@
%h1= t 'app_name' %h1= t 'app_name'
%h2= t '.tagline' %h2= t '.tagline'
= form_tag load_pet_path, :id => 'load-pet-to-wardrobe' do = form_tag remote_load_pet_path, method: 'GET', id: 'load-pet-to-wardrobe' do
- localized_cache :action_suffix => 'main_load_pet_form_content' do = hidden_field_tag 'impress_user', current_user.try(:id)
= origin_tag root_path - localized_cache action_suffix: 'outfits#new main_load_pet_form_content' do
= destination_tag 'wardrobe' = hidden_field_tag 'redirect', "#{wardrobe_url}\#{q}"
%fieldset %fieldset
%legend= t '.load_pet.legend' %legend= t '.load_pet.legend'
= pet_name_tag :id => 'main-pet-name' = pet_name_tag :id => 'main-pet-name'
%button{:type => "submit"} %button{:type => "submit"}
= t '.load_pet.submit' = t '.load_pet.submit'
= form_tag wardrobe_path, :method => 'get', :id => 'start-from-scratch' do - localized_cache action_suffix: 'outfits#new start_from_scratch_form' do
- localized_cache :action_suffix => 'start_from_scratch_form_content' do = form_tag wardrobe_path, method: 'GET', id: 'start-from-scratch', authenticity_token: false do
%fieldset %fieldset
%legend= t '.start_from_scratch.legend' %legend= t '.start_from_scratch.legend'
= pet_attribute_select 'color', @colors, 8 = pet_attribute_select 'color', @colors, 8
@ -60,8 +60,8 @@
%div %div
%h4= t '.modeling_hub.tagline' %h4= t '.modeling_hub.tagline'
%p= t '.modeling_hub.description' %p= t '.modeling_hub.description'
= form_tag load_pet_path do = form_tag remote_load_pet_path, method: 'GET' do
= origin_tag root_path = hidden_field_tag 'redirect', "#{root_url}\#{q}"
= pet_name_tag :placeholder => t('.modeling_hub.load_pet.placeholder') = pet_name_tag :placeholder => t('.modeling_hub.load_pet.placeholder')
= submit_tag t('.modeling_hub.load_pet.submit') = submit_tag t('.modeling_hub.load_pet.submit')

View file

@ -0,0 +1,5 @@
if Rails.env.production?
Rails.configuration.neopia_host = 'neopia.openneo.net'
else
Rails.configuration.neopia_host = 'localhost:3200'
end

View file

@ -49,6 +49,7 @@ OpenneoImpressItems::Application.routes.draw do
match '/users/current-user/outfits' => 'outfits#index', :as => :current_user_outfits match '/users/current-user/outfits' => 'outfits#index', :as => :current_user_outfits
match '/pets/load' => 'pets#load', :method => :post, :as => :load_pet match '/pets/load' => 'pets#load', :method => :post, :as => :load_pet
match '/pets/submit' => 'pets#submit', :method => :post
match '/modeling' => 'pets#bulk', :as => :bulk_pets match '/modeling' => 'pets#bulk', :as => :bulk_pets
match '/login' => 'sessions#new', :as => :login match '/login' => 'sessions#new', :as => :login