add achievement management

This commit is contained in:
2021-08-15 16:45:49 +02:00
parent 2552a78d15
commit 39ebeea387
27 changed files with 435 additions and 26 deletions

View File

@@ -0,0 +1,6 @@
# frozen_string_literal: true
class CompletedWowAchievement < ApplicationRecord
belongs_to :wow_character
belongs_to :wow_achievement
end

View File

@@ -0,0 +1,6 @@
# frozen_string_literal: true
class CompletedWowAchievementCriterium < ApplicationRecord
belongs_to :wow_character
belongs_to :wow_achievement_criterium
end

View File

@@ -0,0 +1,22 @@
# frozen_string_literal: true
class WowAchievement < ApplicationRecord
extend Mobility
translates :name, :description, :reward_description
belongs_to :wow_achievement_category, optional: true
belongs_to :wow_achievement_criterium, optional: true
belongs_to :prerequisite_achievement, class_name: 'WowAchievement', optional: true
has_one :next_achievement,
class_name: 'WowAchievement',
foreign_key: 'prerequisite_achievement_id',
dependent: :nullify,
inverse_of: :prerequisite_achievement
has_many :completed_wow_achievements, dependent: :destroy
has_many :wow_characters, through: :completed_wow_achievements
validates :name, presence: true
validates :achievement_id, presence: true, uniqueness: true
end

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
class WowAchievementCategory < ApplicationRecord
extend Mobility
translates :name
has_many :wow_achievements, dependent: :destroy
validates :name, presence: true
validates :category_id, presence: true, uniqueness: true
end

View File

@@ -0,0 +1,18 @@
# frozen_string_literal: true
class WowAchievementCriterium < ApplicationRecord
extend Mobility
translates :description, :operator_name
has_many :wow_achievements, dependent: :destroy
has_many :child_criteria,
class_name: 'WowAchievementCriterium',
foreign_key: 'parent_criterium_id',
dependent: :destroy,
inverse_of: :parent_criterium
belongs_to :parent_criterium, class_name: 'WowAchievementCriterium', optional: true
has_many :completed_wow_achievement_criteria, dependent: :destroy
has_many :wow_characters, through: :completed_wow_achievement_criteria
validates :criterium_id, presence: true, uniqueness: true
end

View File

@@ -19,6 +19,10 @@ class WowCharacter < ApplicationRecord
has_many :wow_reputations, through: :wow_standings
has_many :wow_character_play_rp_worlds, dependent: :destroy
has_many :rp_worlds, through: :wow_character_play_rp_worlds
has_many :completed_wow_achievements, dependent: :destroy
has_many :wow_achievements, through: :completed_wow_achievements
has_many :completed_wow_achievement_criteria, dependent: :destroy
has_many :wow_achievement_criteria, through: :completed_wow_achievement_criteria
validates :name, presence: true
validates :character_id, presence: true, uniqueness: true

View File

@@ -1,6 +1,8 @@
<h1>Editing Rp World</h1>
<%= render 'form', rp_world: @rp_world %>
<%= turbo_frame_tag "rp_world" do %>
<%= render 'form', rp_world: @rp_world %>
<%= link_to 'Show', @rp_world %> |
<%= link_to 'Back', rp_worlds_path %>
<%= link_to 'Show', @rp_world %> |
<%= link_to 'Back', rp_worlds_path, data: { "turbo-frame": "_top" } %>
<% end %>

View File

@@ -1,22 +1,24 @@
<p id="notice"><%= notice %></p>
<%= turbo_frame_tag "rp_world" do %>
<p id="notice"><%= notice %></p>
<div class="row">
<div class="col-5">
<div class="card">
<div class="card-body">
<h5 class="card-title"><%= @rp_world.name %></h5>
<p class="card-text">Description: <%= @rp_world.description %></p>
<p>Membres: </p>
<% @rp_world.wow_characters.each do |member| %>
<p><%= link_to member.name, member %></p>
<% end %>
<div class="row">
<div class="col-5">
<div class="card">
<div class="card-body">
<h5 class="card-title"><%= @rp_world.name %></h5>
<p class="card-text">Description: <%= @rp_world.description %></p>
<p>Membres: </p>
<% @rp_world.wow_characters.each do |member| %>
<p><%= link_to member.name, member %></p>
<% end %>
</div>
</div>
</div>
<div class="col-7">
<h1>Suite...</h1>
</div>
</div>
<div class="col-7">
<h1>Suite...</h1>
</div>
</div>
<%= link_to 'Edit', edit_rp_world_path(@rp_world) %> |
<%= link_to 'Back', rp_worlds_path %>
<%= link_to 'Edit', edit_rp_world_path(@rp_world) %> |
<%= link_to 'Back', rp_worlds_path, data: { "turbo-frame": "_top" } %>
<% end %>

View File

@@ -0,0 +1,22 @@
# frozen_string_literal: true
class WowAchievementCategoriesWorker < WowSidekiqWorker
def perform
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::AchievementCategory.all
return unless result.status_code == 200
result.categories.each do |category|
wow_category = WowAchievementCategory.find_or_initialize_by(category_id: category.id)
# Localisation data
locales.each do |locale|
Mobility.with_locale(locale[0]) { wow_category.name = category.name[locale[1]] }
end
wow_category.save
end
end
end

View File

@@ -0,0 +1,62 @@
# frozen_string_literal: true
class WowAchievementDetailWorker < WowSidekiqWorker
def perform(wow_achievement_id)
return unless (wow_achievement = WowAchievement.find_by(achievement_id: wow_achievement_id))
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
# Public data
result = RBattlenet::Wow::Achievement.find(wow_achievement_id)
return unless result.status_code == 200
locales.each do |locale|
Mobility.with_locale(locale[0]) do
wow_achievement.description = result.description[locale[1]]
wow_achievement.reward_description = result.reward_description[locale[1]] if result.reward_description
end
end
wow_achievement.points = result.points
wow_achievement.is_account_wide = result.is_account_wide
wow_achievement.display_order = result.display_order
wow_achievement.prerequisite_achievement = WowAchievement.find_by(achievement_id: result.prerequisite_achievement.id) if result.prerequisite_achievement
wow_achievement.wow_achievement_category = WowAchievementCategory.find_by(category_id: result.category.id) if result.category
wow_achievement.wow_achievement_criterium = find_or_create_wow_achievement_criterium(result.criteria) if result.criteria
wow_achievement.icon = RBattlenet::Wow::AchievementMedia.find(result.media.id).assets[0].value if result.media
wow_achievement.save
end
def find_or_create_wow_achievement_criterium(criteria)
wow_achievement_criterium = WowAchievementCriterium.find_or_initialize_by(criterium_id: criteria.id)
wow_achievement_criterium.amount = criteria.amount
locales.each do |locale|
Mobility.with_locale(locale[0]) { wow_achievement_criterium.description = criteria.description[locale[1]] }
end
if criteria.operator
wow_achievement_criterium.operator_type = criteria.operator.type
locales.each do |locale|
Mobility.with_locale(locale[0]) { wow_achievement_criterium.operator_name = criteria.operator.name[locale[1]] }
end
end
wow_achievement_criterium.save
criteria.child_criteria&.each do |child_criterium|
wow_child_achievement_criterium = WowAchievementCriterium.find_or_initialize_by(criterium_id: child_criterium.id)
wow_child_achievement_criterium.parent_criterium = wow_achievement_criterium
wow_child_achievement_criterium.amount = child_criterium.amount
locales.each do |locale|
Mobility.with_locale(locale[0]) { wow_child_achievement_criterium.description = child_criterium.description[locale[1]] }
end
wow_child_achievement_criterium.save
end
wow_achievement_criterium.persisted? ? wow_achievement_criterium : nil
end
end

View File

@@ -0,0 +1,24 @@
# frozen_string_literal: true
class WowAchievementsWorker < WowSidekiqWorker
def perform
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::Achievement.all
return unless result.status_code == 200
result.achievements.each do |achievement|
wow_achievement = WowAchievement.find_or_initialize_by(achievement_id: achievement.id)
# Localisation data
locales.each do |locale|
Mobility.with_locale(locale[0]) { wow_achievement.name = achievement.name[locale[1]] }
end
wow_achievement.save
WowAchievementDetailWorker.perform_async(wow_achievement.achievement_id) if wow_achievement.persisted?
end
end
end

View File

@@ -0,0 +1,54 @@
# frozen_string_literal: true
class WowCharacterAchievementsWorker < WowSidekiqWorker
def perform(wow_character_id)
return unless (wow_character = WowCharacter.find_by(character_id: wow_character_id))
RBattlenet.set_options(locale: 'en_US')
params = { realm: wow_character.wow_realm.slug, name: wow_character.name.downcase }
result = RBattlenet::Wow::Character::Achievements.find(params)
return unless result.status_code == 200
result.achievements&.each do |achievement|
next unless (wow_achievement = WowAchievement.find_by(achievement_id: achievement.id))
wow_achievement_completed = CompletedWowAchievement.where(
wow_achievement: wow_achievement,
wow_character: wow_character
).first_or_initialize
wow_achievement_completed.completed_timestamp = Time.at(achievement.completed_timestamp.to_s[0..-4].to_i).utc
wow_achievement_completed.save
if achievement.criteria
next unless (wow_achievement_criterium = WowAchievementCriterium.find_by(criterium_id: achievement.criteria.id))
wow_achievement_criterium_completed = CompletedWowAchievementCriterium.where(
wow_achievement_criterium: wow_achievement_criterium,
wow_character: wow_character
).first_or_initialize
wow_achievement_criterium_completed.is_completed = achievement.criteria.is_completed
wow_achievement_criterium_completed.amount = achievement.criteria.amount if achievement.criteria.amount
wow_achievement_criterium_completed.save
achievement.criteria.child_criteria&.each do |child_criteria|
next unless (wow_achievement_child_criterium = WowAchievementCriterium.find_by(criterium_id: child_criteria.id))
wow_achievement_child_criterium_completed = CompletedWowAchievementCriterium.where(
wow_achievement_criterium: wow_achievement_child_criterium,
wow_character: wow_character
).first_or_initialize
wow_achievement_child_criterium_completed.is_completed = child_criteria.is_completed
wow_achievement_child_criterium_completed.amount = child_criteria.amount if child_criteria.amount
wow_achievement_child_criterium_completed.save
end
end
end
end
end

View File

@@ -10,8 +10,8 @@ class WowCharactersWorker < WowSidekiqWorker
return unless result.status_code == 200
result.wow_accounts.each do |account|
account.characters.each do |character|
result.wow_accounts&.each do |account|
account.characters&.each do |character|
wow_char = user.wow_characters.find_or_initialize_by(character_id: character.id)
wow_char.name = character.name
@@ -19,9 +19,9 @@ class WowCharactersWorker < WowSidekiqWorker
wow_char.faction = character.faction.type
wow_char.href = character.character.href
wow_char.level = character.level
wow_char.wow_realm = WowRealm.where(realm_id: character.realm.id).first
wow_char.wow_class = WowClass.where(class_id: character.playable_class.id).first
wow_char.wow_race = WowRace.where(race_id: character.playable_race.id).first
wow_char.wow_realm = WowRealm.find_by(realm_id: character.realm.id)
wow_char.wow_class = WowClass.find_by(class_id: character.playable_class.id)
wow_char.wow_race = WowRace.find_by(race_id: character.playable_race.id)
wow_char.user = user
wow_char.account_id = account.id
@@ -40,6 +40,7 @@ class WowCharactersWorker < WowSidekiqWorker
WowCharacterDetailWorker.perform_async(wow_char.character_id)
WowCharacterPositionsWorker.perform_async(wow_char.character_id)
WowStandingWorker.perform_async(wow_char.character_id)
WowCharacterAchievementsWorker.perform_async(wow_char.character_id)
end
end
end