Untitled
unknown
ruby
9 months ago
6.0 kB
14
Indexable
class UpdateMatchPerformanceJob
include Sidekiq::Job
include MatchesHelper
include PlayersHelper
include ActionView::Helpers::AssetUrlHelper
sidekiq_options retry: 0
def perform(match_id)
titles = {
minions: "Farmer",
damage_dealt_to_structures: "Devastator",
damage_dealt_to_objectives: "Hunter",
damage_taken_to_death: "Guardian",
damage_dealt_to_death: "Elusive",
damage_dealt_to_taken: "Dominator",
assists: "Altruist",
hero_damage: "Annihilator",
kda_score: "Assassin",
wards: "Sentinel"
}
match_data = MatchPlayerDatum.where(match_id: match_id)
match_data.each do |match_player_data|
performance_data = calculate_performance(match_player_data.match, match_player_data, avgStats(match_player_data.match.game_mode, match_player_data))
match_player_data.update(performance_score: performance_data.values.sum)
end
MatchPlayerDatum.teams.each do |team|
team_player_data = match_data.where(team: team)
team_data = team_player_data.map { |p| calculate_performance(p.match, p, avgStats(p.match.game_mode, p)).map { |pp| [p, *pp] } }.flatten(1)
team_data.reject! { |data|
(data.second == :kda_score && (data.first.kills < 5 || data.first.deaths > (data.first.kills / 2))) ||
(data.second == :minions && (data.first.support? || data.first.match.game_mode == "brawl")) ||
(data.second == :wards && data.first.match.game_mode == "brawl") ||
(data.second == :damage_dealt_to_structures && data.first.match.game_mode == "brawl") ||
(data.second == :hero_damage && data.first.kills + data.first.assists <= data.first.deaths) ||
(data.second == :damage_dealt_to_taken && (data.first.total_damage_dealt_to_heroes + 1.0) / (data.first.total_damage_taken_from_heroes + 1.0) < 1.25)
}
team_data.sort_by(&:last).reverse.uniq(&:first).each { |x| x.first.update(performance_title: titles[x.second]) }
end
transmit_match_to_channels(Match.find_by(id: match_id))
end
def transmit_match_to_channels(match)
data = prepare_api([match])
match.player_data.each do |player_data|
LiveMatchApiChannel.transmit_matches(player_data.player_id, data)
end
end
def avgStats(game_mode, match_player_data)
avg_role_stats = JSON.parse(GameStatistics.get(:role_ps_stats))
avg_hero_stats = JSON.parse(GameStatistics.get(:hero_ps_stats))
role = match_player_data.role.to_s
hero_id = match_player_data.hero_id.to_s
hero_stats = avg_hero_stats.dig(game_mode, hero_id, role)
role_stats = avg_role_stats.dig(game_mode, role)
hero_stats_match_count = hero_stats&.dig(9)&.to_i
if hero_stats_match_count && hero_stats_match_count >= 100
return hero_stats
elsif role_stats
return role_stats
end
return nil
end
def weights(game_mode)
case game_mode
when "pvp", "custom", "ranked", "TEAM_VS_TEAM_RUSH", "TEAM_VS_TEAM_LEGACY"
{
minions_weight: 10,
damage_dealt_to_structures_weight: 10,
damage_dealt_to_objectives_weight: 10,
damage_taken_to_death_weight: 10,
damage_dealt_to_death_weight: 10,
damage_dealt_to_taken_weight: 10,
assists_weight: 10,
hero_damage_weight: 10,
kda_weight: 10,
wards_weight: 10,
}
when "brawl"
return {
minions_weight: 0,
damage_dealt_to_structures_weight: 0,
damage_dealt_to_objectives_weight: 14.285,
damage_taken_to_death_weight: 14.285,
damage_dealt_to_death_weight: 14.285,
damage_dealt_to_taken_weight: 14.285,
assists_weight: 14.285,
hero_damage_weight: 14.285,
kda_weight: 14.285,
wards_weight: 0,
}
end
end
def calculate_performance(match, data, avg_stats)
return stats = {
minions: 10,
damage_dealt_to_structures: 10,
damage_dealt_to_objectives: 10,
damage_taken_to_death: 10,
damage_dealt_to_death: 10,
damage_dealt_to_taken: 10,
assists: 10,
hero_damage: 10,
kda_score: 10,
wards: 10
} if avg_stats.nil?
avg_match_length = avg_stats[10] || 1
average = {
minions: avg_stats[0] || 1,
damage_dealt_to_structures: avg_stats[1] || 1,
damage_dealt_to_objectives: avg_stats[2] || 1,
damage_taken_to_death: avg_stats[3] || 1,
damage_dealt_to_death: avg_stats[4] || 1,
damage_dealt_to_taken: avg_stats[5] || 1,
assists: avg_stats[6] || 1,
hero_damage: avg_stats[7] || 1,
kda: avg_stats[8] || 1,
wards: avg_stats[9] || 1,
}
weights = weights(match.game_mode)
kda = ((data.kills + (data.assists * 0.5)) / (data.deaths + 1.0))
kda_score = Math.log(kda + 1.0)
stats = {
minions: data.minions_killed,
damage_dealt_to_structures: data.total_damage_dealt_to_structures + 1.0,
damage_dealt_to_objectives: data.total_damage_dealt_to_objectives + 1.0,
damage_taken_to_death: ((data.total_damage_taken_from_heroes + data.total_damage_mitigated) / (data.deaths + 1.0)),
damage_dealt_to_death: (data.total_damage_dealt_to_heroes / (data.deaths + 1.0)),
damage_dealt_to_taken: (data.total_damage_dealt_to_heroes / (data.total_damage_taken_from_heroes + 1.0)),
assists: data.assists,
hero_damage: data.total_damage_dealt_to_heroes,
kda_score: kda_score,
wards: data.wards_placed + data.wards_destroyed
}
return stats.zip(average, weights).map { |(key, value), (_, avg), (_, weight)| [key, (value / match.game_duration.to_f) / (avg.to_f / avg_match_length.to_f) * weight] }.to_h
end
def update_all_match_performance
Match.in_batches(of: 10000).each_record do |match|
UpdateMatchPerformanceJob.perform_async(match.id)
end
end
end
Editor is loading...
Leave a Comment