ensl.org/app/models/gatherer.rb
2019-06-07 22:47:21 +03:00

171 lines
5.8 KiB
Ruby

# == Schema Information
#
# Table name: gatherers
#
# id :integer not null, primary key
# user_id :integer
# gather_id :integer
# team :integer
# created_at :datetime
# updated_at :datetime
# votes :integer default(0), not null
# status :integer default(0), not null
#
class Gatherer < ActiveRecord::Base
IDLE_TIME = 600
EJECT_VOTES = 4
STATE_ACTIVE = 0
STATE_AWAY = 1
STATE_LEAVING = 2
include Extra
attr_protected :id
attr_accessor :confirm, :username
cattr_accessor :skip_callbacks
scope :team,
lambda { |team| {:conditions => {:team => team}} }
scope :of_user,
lambda { |user| {:conditions => {:user_id => user.id}} }
scope :lobby, :conditions => "team IS NULL"
scope :best,
lambda { |gather| {
:select => "u.id, u.username, (COUNT(*) / (SELECT COUNT(*) FROM gatherers g3 WHERE g3.user_id = u.id)) AS skill, g4.id",
:from => "gathers g1",
:joins => "LEFT JOIN gatherers g2 ON g1.captain1_id = g2.id OR g1.captain2_id = g2.id
LEFT JOIN users u ON g2.user_id = u.id
LEFT JOIN gatherers g4 ON u.id = g4.user_id AND g4.gather_id = #{gather.id}",
:group => "u.id",
:having => "g4.id IS NOT NULL",
:order => "skill DESC",
:limit => 15 } }
scope :with_kpd,
:select => "gatherers.*, SUM(kills)/SUM(deaths) as kpd, COUNT(rounders.id) as rounds",
:joins => "LEFT JOIN rounders ON rounders.user_id = gatherers.user_id",
:group => "rounders.user_id",
:order => "kpd DESC"
scope :lobby_team,
lambda { |team| {
:conditions => ["gatherers.team IS NULL OR gatherers.team = ?", team],
:order => "gatherers.team"} }
scope :most_voted, :order => "votes DESC, created_at DESC"
scope :not_user,
lambda { |user| {:conditions => ["user_id != ?", user.id]} }
scope :eject_order, :order => "votes ASC"
scope :ordered,
:joins => "LEFT JOIN gathers ON captain1_id = gatherers.id OR captain2_id = gatherers.id",
:order => "captain1_id, captain2_id, gatherers.id"
scope :idle,
:joins => "LEFT JOIN users ON users.id = gatherers.user_id",
:conditions => ["lastvisit < ?", 30.minutes.ago.utc]
belongs_to :user
belongs_to :gather
has_many :real_votes, :class_name => "Vote", :as => :votable, :dependent => :destroy
validates_uniqueness_of :user_id, :scope => :gather_id
validates_inclusion_of :team, :in => 1..2, :allow_nil => true
validates :confirm, :acceptance => true, :unless => Proc.new {|gatherer| gatherer.user.gatherers.count >= 5}
validate :validate_username
after_create :start_gather, :if => Proc.new {|gatherer| gatherer.gather.gatherers.count == Gather::FULL}
after_create :notify_gatherers, :if => Proc.new {|gatherer| gatherer.gather.gatherers.count == Gather::NOTIFY}
after_update :change_turn, :unless => Proc.new {|gatherer| gatherer.skip_callbacks == true}
after_destroy :cleanup_votes
def to_s
user.to_s
end
def validate_username
if username
if u = User.first(:conditions => {:username => username})
self.user = u
else
errors.add(:username, t(:gatherer_wrong_username))
end
end
end
def start_gather
gather.update_attribute :status, Gather::STATE_VOTING
end
def notify_gatherers
Profile.all(:include => :user, :conditions => "notify_gather = 1").each do |p|
Notifications.gather p.user, gather if p.user
end
end
def change_turn
if team_changed? and team != nil
new_turn = (team == 1 ? 2 : 1)
if team == 2 and [2, 4].include?(gather.gatherers.team(2).count.to_i)
new_turn = 2
elsif team == 1 and [3, 5].include?(gather.gatherers.team(1).count.to_i)
new_turn = 1
end
gather.update_attribute :turn, new_turn
if gather.gatherers.lobby.count == 1
gather.gatherers.lobby.first.update_attribute :team, (self.team == 1 ? 2 : 1)
end
if gather.gatherers.lobby.count == 0
gather.update_attribute :status, Gather::STATE_FINISHED
end
end
end
def cleanup_votes
gather.map_votes.all(:conditions => {:user_id => user_id}).each { |g| g.destroy }
gather.server_votes.all(:conditions => {:user_id => user_id}).each { |g| g.destroy }
gather.gatherer_votes.all(:conditions => {:user_id => user_id}).each { |g| g.destroy }
end
def votes_needed?
return 5
end
def captain?
gather.captain1 == self or gather.captain2 == self
end
def turn?
(gather.captain1 == self and gather.turn == 1) or (gather.captain2 == self and gather.turn == 2)
end
def can_create? cuser, params = {}
# and check_params(params, [:user_id, :gather_id])
cuser \
and user == cuser \
and !cuser.banned?(Ban::TYPE_GATHER) \
and gather.status == Gather::STATE_RUNNING \
and gather.gatherers.count < Gather::FULL \
and !gather.gatherers.of_user(cuser).first
end
def can_update? cuser, params = {}
return false unless cuser
if params.keys.include? "username"
if cuser.admin? or cuser.gather_moderator?
return true
else
return false
end
end
return false unless team.nil? \
and ((gather.captain1.user == cuser and gather.turn == 1) or (gather.captain2.user == cuser and gather.turn == 2))
return false if gather.turn == 1 and gather.gatherers.team(1).count == 2 and gather.gatherers.team(2).count < 3
return false if gather.turn == 2 and gather.gatherers.team(1).count < 4 and gather.gatherers.team(2).count == 3
return false if gather.turn == 1 and gather.gatherers.team(1).count == 4 and gather.gatherers.team(2).count < 5
return false if gather.turn == 2 and gather.gatherers.team(1).count < 6 and gather.gatherers.team(2).count == 5
return false if gather.turn == 1 and gather.gatherers.team(1).count == 6
true
end
def can_destroy? cuser
cuser and ((user == cuser or cuser.admin? or cuser.gather_moderator?) and gather.status == Gather::STATE_RUNNING)
end
end