forked from OpenNeo/impress
basic neopia api integration
This commit is contained in:
parent
fef87d664a
commit
7c6e607612
11 changed files with 138 additions and 41 deletions
|
@ -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(),
|
||||||
|
|
|
@ -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'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 + '#'
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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')
|
||||||
|
|
||||||
|
|
5
config/initializers/neopia.rb
Normal file
5
config/initializers/neopia.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
if Rails.env.production?
|
||||||
|
Rails.configuration.neopia_host = 'neopia.openneo.net'
|
||||||
|
else
|
||||||
|
Rails.configuration.neopia_host = 'localhost:3200'
|
||||||
|
end
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue