mirror of
https://github.com/ENSL/ensl.org.git
synced 2024-12-24 11:31:33 +00:00
Add log and event functionality back
This commit is contained in:
parent
72782585be
commit
28da8fe5eb
15 changed files with 889 additions and 0 deletions
85
app/controllers/log_events_controller.rb
Normal file
85
app/controllers/log_events_controller.rb
Normal file
|
@ -0,0 +1,85 @@
|
|||
class LogEventsController < ApplicationController
|
||||
# GET /log_events
|
||||
# GET /log_events.xml
|
||||
def index
|
||||
@log_events = LogEvent.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.xml { render xml: @log_events }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /log_events/1
|
||||
# GET /log_events/1.xml
|
||||
def show
|
||||
@log_event = LogEvent.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.xml { render xml: @log_event }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /log_events/new
|
||||
# GET /log_events/new.xml
|
||||
def new
|
||||
@log_event = LogEvent.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.xml { render xml: @log_event }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /log_events/1/edit
|
||||
def edit
|
||||
@log_event = LogEvent.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /log_events
|
||||
# POST /log_events.xml
|
||||
def create
|
||||
@log_event = LogEvent.new(params[:log_event])
|
||||
|
||||
respond_to do |format|
|
||||
if @log_event.save
|
||||
flash[:notice] = t(:logevent_create)
|
||||
format.html { redirect_to(@log_event) }
|
||||
format.xml { render xml: @log_event, :status => :created, :location => @log_event }
|
||||
else
|
||||
format.html { render :new }
|
||||
format.xml { render xml: @log_event.errors, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /log_events/1
|
||||
# PUT /log_events/1.xml
|
||||
def update
|
||||
@log_event = LogEvent.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @log_event.update_attributes(params[:log_event])
|
||||
flash[:notice] = t(:logevent_update)
|
||||
format.html { redirect_to(@log_event) }
|
||||
format.xml { head :ok }
|
||||
else
|
||||
format.html { render :edit }
|
||||
format.xml { render xml: @log_event.errors, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /log_events/1
|
||||
# DELETE /log_events/1.xml
|
||||
def destroy
|
||||
@log_event = LogEvent.find(params[:id])
|
||||
@log_event.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to(log_events_url) }
|
||||
format.xml { head :ok }
|
||||
end
|
||||
end
|
||||
end
|
42
app/controllers/log_files_controller.rb
Normal file
42
app/controllers/log_files_controller.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
class LogFilesController < ApplicationController
|
||||
def index
|
||||
LogFile.process
|
||||
render text: 'Ok'
|
||||
end
|
||||
|
||||
def handle
|
||||
LogFile.find(params[:id]).deal
|
||||
render text: 'Ok'
|
||||
end
|
||||
|
||||
def refresh
|
||||
LogFile.unhandled.each do |lf|
|
||||
lf.deal
|
||||
end
|
||||
end
|
||||
|
||||
def fix
|
||||
Rounder.find_in_batches(batch_size: 100) do |rounders|
|
||||
rounders.each do |r|
|
||||
r.team_id = nil
|
||||
if r.user and t = Teamer.historic(r.user, r.round.start).first
|
||||
r.team_id = t.team_id
|
||||
end
|
||||
r.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pix
|
||||
Round.all.each do |r|
|
||||
r.team1_id = nil
|
||||
r.team2_id = nil
|
||||
[1, 2].each do |team|
|
||||
if s = r.rounders.team(team).stats.first
|
||||
r["team#{team}_id"] = s["team_id"]
|
||||
end
|
||||
end
|
||||
r.save
|
||||
end
|
||||
end
|
||||
end
|
26
app/controllers/rounds_controller.rb
Normal file
26
app/controllers/rounds_controller.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
class RoundsController < ApplicationController
|
||||
def index
|
||||
sort = case params['sort']
|
||||
when "start" then "start"
|
||||
when "server" then "server_id"
|
||||
when "team1" then "team1_id"
|
||||
when "team2" then "team2_id"
|
||||
when "map" then "map_name"
|
||||
when "commander" then "commander_id"
|
||||
end
|
||||
|
||||
@rounds = Round.basic.paginate \
|
||||
order: sort,
|
||||
page: params[:page],
|
||||
per_page: 30
|
||||
|
||||
if params[:ajax]
|
||||
render partial: 'list', layout: false
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@round = Round.find(params[:id])
|
||||
end
|
||||
end
|
197
app/models/log.rb
Normal file
197
app/models/log.rb
Normal file
|
@ -0,0 +1,197 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: logs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# server_id :integer
|
||||
# text :text
|
||||
# domain :integer
|
||||
# created_at :datetime
|
||||
# round_id :integer
|
||||
# details :string(255)
|
||||
# actor_id :integer
|
||||
# target_id :integer
|
||||
# specifics1 :string(255)
|
||||
# specifics2 :string(255)
|
||||
# log_file_id :integer
|
||||
#
|
||||
|
||||
class Log < ActiveRecord::Base
|
||||
include Extra
|
||||
attr_accessor :text
|
||||
|
||||
DOMAIN_LOG = 1
|
||||
DOMAIN_INFO = 4
|
||||
|
||||
TEAM_MARINES = 1
|
||||
TEAM_ALIENS = 2
|
||||
|
||||
RE_PLAYER = /".*?<\d*><STEAM_\d*:\d*:\d*><\w*>"/
|
||||
RE_PLAYER_ID = /".*?<\d*><STEAM_(\d*:\d*:\d*)><\w*>"/
|
||||
RE_PLAYER_ID_NAME_TEAM = /"(.*?)<\d*><STEAM_(\d*:\d*:\d*)><([a-z]*)1team>"/
|
||||
RE_PLAYER_NAME = /"(.*?)<\d*><STEAM_\d*:\d*:\d*><[a-z]*1team>"/
|
||||
RE_PLAYER_NAME_TEAM = /"(.*?)<\d*><STEAM_\d*:\d*:\d*><([a-z]*)1team>"/
|
||||
|
||||
scope :recent, :order => "id DESC", :limit => 5
|
||||
scope :ordered, :order => "created_at ASC, id ASC"
|
||||
scope :with_details,
|
||||
lambda { |details| {:conditions => ["details LIKE ?", details]} }
|
||||
scope :unhandled, :conditions => {:details => nil}
|
||||
scope :stats,
|
||||
:select => "id, details, COUNT(*) as num",
|
||||
:group => "details",
|
||||
:order => "details"
|
||||
|
||||
belongs_to :details, :class_name => "LogEvent"
|
||||
belongs_to :server
|
||||
belongs_to :round
|
||||
belongs_to :server
|
||||
belongs_to :log_file
|
||||
belongs_to :actor, :class_name => "Rounder"
|
||||
belongs_to :target, :class_name => "Rounder"
|
||||
|
||||
def since
|
||||
(created_at - round.start).to_i
|
||||
end
|
||||
|
||||
def time
|
||||
return sprintf("%02d:%02d", since/60, since%60)
|
||||
end
|
||||
|
||||
def frag
|
||||
text.match(/^#{RE_PLAYER_NAME_TEAM} killed #{RE_PLAYER_NAME_TEAM} with "([a-z0-9_]*)"$/)
|
||||
end
|
||||
|
||||
def role
|
||||
text.match(/^#{RE_PLAYER_NAME} changed role to "([a-z0-9_]*)"$/)
|
||||
end
|
||||
|
||||
def match_map vars
|
||||
if m = text.match(/^Started map "([A-Za-z0-9_]*)"/)
|
||||
vars[:map] = m[1]
|
||||
self.details = LogEvent.get "map"
|
||||
self.specifics1 = m[1]
|
||||
end
|
||||
end
|
||||
|
||||
def match_start vars
|
||||
if text.match(/^Game reset complete.$/)
|
||||
vars[:round] = Round.new
|
||||
vars[:round].server = server
|
||||
vars[:round].start = created_at
|
||||
vars[:round].map_name = vars[:map]
|
||||
vars[:round].map = Map.with_name(vars[:map]).first
|
||||
vars[:round].save
|
||||
vars[:lifeforms] = {}
|
||||
self.details = LogEvent.get "start"
|
||||
end
|
||||
end
|
||||
|
||||
def match_end vars
|
||||
if m = text.match(/^Team ([1-2]) has lost.$/)
|
||||
vars[:round].winner = (m[1].to_i == 1 ? 2 : 1)
|
||||
vars[:round].end = created_at
|
||||
[1, 2].each do |team|
|
||||
if s = vars[:round].rounders.team(team).stats.first
|
||||
vars[:round]["team#{team}_id"] = s["team_id"]
|
||||
end
|
||||
end
|
||||
vars[:round].save
|
||||
vars[:round] = nil
|
||||
self.details = LogEvent.get "end"
|
||||
end
|
||||
end
|
||||
|
||||
def match_join vars
|
||||
if m = text.match(/^#{RE_PLAYER_ID_NAME_TEAM} .*$/) and !(self.actor = vars[:round].rounders.match(m[2]).first)
|
||||
self.actor = Rounder.new
|
||||
self.actor.round = vars[:round]
|
||||
self.actor.name = m[1]
|
||||
self.actor.steamid = m[2]
|
||||
self.actor.user = User.first(:conditions => {:steamid => m[2]}) or User.historic(m[2])
|
||||
self.actor.team = (m[3] == "marine" ? TEAM_MARINES : TEAM_ALIENS)
|
||||
if self.actor.user and t = Teamer.historic(actor.user, vars[:round].start).first
|
||||
self.actor.ensl_team = t.team
|
||||
end
|
||||
self.actor.kills = 0
|
||||
self.actor.deaths = 0
|
||||
self.actor.save
|
||||
self.details = LogEvent.get "join"
|
||||
end
|
||||
end
|
||||
|
||||
def match_kill vars
|
||||
if m = text.match(/^#{RE_PLAYER} killed #{RE_PLAYER_ID} with "([a-z0-9_]*)"$/)
|
||||
if self.actor
|
||||
actor.increment :kills
|
||||
actor.save
|
||||
end
|
||||
if self.target = vars[:round].rounders.match(m[1]).first
|
||||
target.increment :deaths
|
||||
target.save
|
||||
end
|
||||
self.details = LogEvent.get "kill"
|
||||
self.specifics1 = m[3]
|
||||
save
|
||||
end
|
||||
end
|
||||
|
||||
def match_say vars
|
||||
if m = text.match(/^#{RE_PLAYER} (say(_team)?) ".*"$/)
|
||||
self.details = "say"
|
||||
self.specifics1 = m[1]
|
||||
end
|
||||
end
|
||||
|
||||
def match_built vars
|
||||
if m = text.match(/^#{RE_PLAYER} triggered "structure_built" \(type "([a-z0-9_]*)"\)$/)
|
||||
self.details = "built_" + m[1]
|
||||
end
|
||||
end
|
||||
|
||||
def match_destroyed vars
|
||||
if m = text.match(/^#{RE_PLAYER} triggered "structure_destroyed" \(type "([a-z0-9_]*)"\)$/)
|
||||
self.details = "destroyed_" + m[1]
|
||||
end
|
||||
end
|
||||
|
||||
def match_research_start vars
|
||||
if m = text.match(/^#{RE_PLAYER} triggered "research_start" \(type "([a-z0-9_]*)"\)$/)
|
||||
self.details = m[1]
|
||||
end
|
||||
end
|
||||
|
||||
def match_research_cancel vars
|
||||
if m = text.match(/^#{RE_PLAYER} triggered "research_cancel" \(type "([a-z0-9_]*)"\)$/)
|
||||
self.details = "research_cancel"
|
||||
end
|
||||
end
|
||||
|
||||
def match_role vars
|
||||
if m = text.match(/^#{RE_PLAYER_ID} changed role to "([a-z0-9_]*)"$/)
|
||||
if m[2] == "gestate"
|
||||
self.details = "gestate"
|
||||
elsif actor
|
||||
if m[2] == "commander" and !vars[:round].commander
|
||||
vars[:round].commander = actor
|
||||
vars[:round].save
|
||||
end
|
||||
if !actor.roles
|
||||
actor.update_attribute :roles, m[2]
|
||||
elsif !self.actor.roles.include?(m[2])
|
||||
actor.update_attribute :roles, actor.roles + ", " + m[2]
|
||||
end
|
||||
self.details = ((vars[:lifeforms].include? actor.id and vars[:lifeforms][actor.id] == m[2]) ? "upgrade" : m[2])
|
||||
vars[:lifeforms][actor.id] = m[2]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.add server, domain, text
|
||||
log = new
|
||||
log.server = server
|
||||
log.domain = domain
|
||||
log.text = text
|
||||
log.save
|
||||
end
|
||||
end
|
25
app/models/log_event.rb
Normal file
25
app/models/log_event.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: log_events
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255)
|
||||
# description :string(255)
|
||||
# team :integer
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
#
|
||||
|
||||
class LogEvent < ActiveRecord::Base
|
||||
def self.get search, team = nil
|
||||
if f = first({:conditions => {:name => search}})
|
||||
return f
|
||||
else
|
||||
f = LogEvent.new
|
||||
f.name = "get"
|
||||
f.team = team if team
|
||||
f.save
|
||||
return f
|
||||
end
|
||||
end
|
||||
end
|
95
app/models/log_file.rb
Normal file
95
app/models/log_file.rb
Normal file
|
@ -0,0 +1,95 @@
|
|||
# encoding: US-ASCII
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: log_files
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255)
|
||||
# md5 :string(255)
|
||||
# size :integer
|
||||
# server_id :integer
|
||||
# updated_at :datetime
|
||||
#
|
||||
|
||||
|
||||
require 'digest/md5'
|
||||
|
||||
class LogFile < ActiveRecord::Base
|
||||
NON_ASCII = /[\x80-\xff]/
|
||||
LOGS = File.join(Rails.root, "tmp", "logs")
|
||||
|
||||
attr_accessor :path
|
||||
belongs_to :server
|
||||
|
||||
has_many :logs
|
||||
has_many :rounds, :through => :logs
|
||||
|
||||
def after_create
|
||||
Pathname(path).each_line do |line|
|
||||
if m = line.gsub(NON_ASCII, "").match(/\d{2}:\d{2}:\d{2}: (.*)/)
|
||||
log = Log.new
|
||||
log.server = server
|
||||
log.domain = Log::DOMAIN_LOG
|
||||
log.log_file = self
|
||||
log.text = m[1].strip
|
||||
next if log.text.match(/^Server cvar/)
|
||||
next if log.text.match(/^\[ENSL\]/)
|
||||
next if log.text.match(/STEAM USERID validated/)
|
||||
next if log.text.match(/^\[META\]/)
|
||||
l.created_at = DateTime.parse(line.match(/\d{2}\/\d{2}\/\d{4} \- \d{2}:\d{2}:\d{2}:/)[0])
|
||||
vars = {}
|
||||
log.match_map vars or log.match_start vars
|
||||
if vars[:round] and !log.details
|
||||
log.match_end vars \
|
||||
or log.match_join vars \
|
||||
or log.match_kill vars \
|
||||
or log.match_say vars \
|
||||
or log.match_built vars \
|
||||
or log.match_destroyed vars \
|
||||
or log.match_research_start vars \
|
||||
or log.match_research_cancel vars \
|
||||
or log.match_role vars \
|
||||
end
|
||||
if log.details
|
||||
log.round = vars[:round] if vars[:round]
|
||||
log.save
|
||||
end
|
||||
end
|
||||
end
|
||||
rounds.each do |r|
|
||||
unless r.end
|
||||
r.destroy
|
||||
end
|
||||
end
|
||||
Log.delete_all(["details IS NULL AND log_file_id = ?", self.id])
|
||||
end
|
||||
|
||||
def format path
|
||||
self.name = File.basename(path)
|
||||
self.size = File.size(path)
|
||||
self.md5 = Digest::MD5.hexdigest(File.read(path))
|
||||
self.updated_at = File.mtime(path)
|
||||
self.path = path
|
||||
end
|
||||
|
||||
def deal
|
||||
# TODO
|
||||
end
|
||||
|
||||
def self.process
|
||||
Dir.glob("#{LOGS}/*").each do |entry|
|
||||
dir = File.basename(entry).to_i
|
||||
if File.directory?(entry) and dir > 0 and Server.find(dir)
|
||||
Dir.glob("#{entry}/*.log").each do |file|
|
||||
lf = LogFile.new
|
||||
lf.format file
|
||||
lf.server_id = dir
|
||||
|
||||
unless LogFile.first(:conditions => {:name => lf.name, :size => lf.size, :server_id => dir.to_i})
|
||||
lf.save
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
128
app/models/round.rb
Normal file
128
app/models/round.rb
Normal file
|
@ -0,0 +1,128 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: rounds
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# server_id :integer
|
||||
# start :datetime
|
||||
# end :datetime
|
||||
# winner :integer
|
||||
# match_id :integer
|
||||
# commander_id :integer
|
||||
# team1_id :integer
|
||||
# team2_id :integer
|
||||
# map_name :string(255)
|
||||
# map_id :integer
|
||||
#
|
||||
|
||||
class Round < ActiveRecord::Base
|
||||
scope :basic, :include => [:commander, :map, :server, :team1, :team2], :order => "start DESC"
|
||||
scope :team_stats,
|
||||
:select => "team1_id AS team_id, COUNT(*) as rounds, AVG(winner) AS wlr, teams.name",
|
||||
:joins => "LEFT JOIN teams ON teams.id = team1_id",
|
||||
:group => "team_id",
|
||||
:order => "rounds DESC",
|
||||
:having => "rounds > 10 AND team_id IS NOT NULL",
|
||||
:limit => 100
|
||||
|
||||
has_many :rounders, :dependent => :destroy
|
||||
has_many :logs, :dependent => :destroy
|
||||
|
||||
belongs_to :team1, :class_name => "Team"
|
||||
belongs_to :team2, :class_name => "Team"
|
||||
belongs_to :server
|
||||
belongs_to :match
|
||||
belongs_to :commander, :class_name => "Rounder"
|
||||
belongs_to :map
|
||||
|
||||
def length
|
||||
sprintf("%02d:%02d", (self.end - self.start).to_i/60, (self.end - self.start).to_i%60)
|
||||
end
|
||||
|
||||
def winner_s
|
||||
winner == 1 ? "Marines" : "Aliens"
|
||||
end
|
||||
|
||||
def marine_stats
|
||||
{"built_resourcetower" => "Marine RTs",
|
||||
"built_item_genericammo" => "Ammo Packs",
|
||||
"built_item_health" => "Medpacks"}
|
||||
end
|
||||
|
||||
def alien_stats
|
||||
{"built_alienresourcetower" => "Alien RTs",
|
||||
"lerk" => "Lerks",
|
||||
"fade" => "Fades",
|
||||
"onos" => "Onoses"}
|
||||
end
|
||||
|
||||
def self.marine_events
|
||||
{"built_resourcetower" => "RT Built",
|
||||
"built_phasegate" => "PG Built",
|
||||
"built_team_infportal" => "IP Built",
|
||||
"built_team_armory" => "Armory Built",
|
||||
"built_team_observatory" => "Obs Built",
|
||||
"built_team_armslab" => "ARMS Built",
|
||||
"built_team_command" => "CC Built",
|
||||
"built_team_prototypelab" => "Proto Built",
|
||||
"built_team_turretfactory" => "TF Built",
|
||||
"built_team_turret" => "Turret Built",
|
||||
"built_team_siegeturret" => "Siege Built",
|
||||
"destroyed_resourcetower" => "RT Destroyed",
|
||||
"destroyed_phasegate" => "PG Destroyed",
|
||||
"destroyed_team_infportal" => "IP Destroyed",
|
||||
"destroyed_team_armory" => "Armory Destroyed",
|
||||
"destroyed_team_observatory" => "Obs Destroyed",
|
||||
"destroyed_team_armslab" => "ARMS Destroyed",
|
||||
"destroyed_team_command" => "CC Destroyed",
|
||||
"destroyed_team_prototypelab" => "Proto Destroyed",
|
||||
"destroyed_team_turretfactory" => "TF Destroyed",
|
||||
"destroyed_team_turret" => "Turret Destroyed",
|
||||
"destroyed_team_siegeturret" => "Siege Destroyed",
|
||||
"scan" => "Scan",
|
||||
"research_motiontracking" => "MT Tech",
|
||||
"research_phasetech" => "PG Tech",
|
||||
"research_distressbeacon" => "Beacon",
|
||||
"research_armorl1" => "Armor 1",
|
||||
"research_armorl2" => "Armor 2",
|
||||
"research_armorl3" => "Armor 3",
|
||||
"research_weaponsl1" => "Weapons 1",
|
||||
"research_weaponsl2" => "Weapons 2",
|
||||
"research_weaponsl3" => "Weapons 3",
|
||||
"research_advarmory" => "AA",
|
||||
"research_electrical" => "Electrify",
|
||||
"research_advturretfactory" => "A-TFAC",
|
||||
"research_cancel" => "Research Cancel",
|
||||
"kill" => "Frag"}
|
||||
end
|
||||
|
||||
def self.alien_events
|
||||
{"built_team_hive" => "Hive Built",
|
||||
"built_movementchamber" => "MC Built",
|
||||
"built_sensorychamber" => "SC Built",
|
||||
"built_defensechamber" => "DC Built",
|
||||
"built_offensechamber" => "OC Built",
|
||||
"built_alienresourcetower" => "RT Built",
|
||||
"destroyed_team_hive" => "Hive Destroyed",
|
||||
"destroyed_movementchamber" => "MC Destroyed",
|
||||
"destroyed_sensorychamber" => "SC Destroyed",
|
||||
"destroyed_defensechamber" => "DC Destroyed",
|
||||
"destroyed_offensechamber" => "OC Destroyed",
|
||||
"destroyed_alienresourcetower" => "RT Destroyed",
|
||||
"gorge" => "Gorge up",
|
||||
"lerk" => "Lerk up",
|
||||
"fade" => "Fade up",
|
||||
"onos" => "Onos up",
|
||||
"kill" => "Frag"}
|
||||
end
|
||||
|
||||
def self.alien_event event
|
||||
return alien_events[event] if alien_events.include?(event)
|
||||
return nil
|
||||
end
|
||||
|
||||
def self.marine_event event
|
||||
return marine_events[event] if marine_events.include?(event)
|
||||
return nil
|
||||
end
|
||||
end
|
52
app/models/rounder.rb
Normal file
52
app/models/rounder.rb
Normal file
|
@ -0,0 +1,52 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: rounders
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# round_id :integer
|
||||
# user_id :integer
|
||||
# team :integer
|
||||
# roles :string(255)
|
||||
# kills :integer
|
||||
# deaths :integer
|
||||
# name :string(255)
|
||||
# steamid :string(255)
|
||||
# team_id :integer
|
||||
#
|
||||
|
||||
class Rounder < ActiveRecord::Base
|
||||
attr_accessor :lifeform
|
||||
|
||||
scope :team, lambda { |team| {:conditions => {:team => team}} }
|
||||
scope :match, lambda { |steamid| {:conditions => {:steamid => steamid}} }
|
||||
scope :ordered, :order => "kills DESC, deaths ASC"
|
||||
scope :stats,
|
||||
:select => "id, team_id, COUNT(*) as num",
|
||||
:group => "team_id",
|
||||
:order => "num DESC",
|
||||
:having => "num > 3"
|
||||
scope :player_stats,
|
||||
:select => "id, user_id, SUM(kills)/SUM(deaths) as kpd, COUNT(*) as rounds",
|
||||
:group => "user_id",
|
||||
:order => "kpd DESC",
|
||||
:having => "rounds > 30 AND kpd > 0 AND user_id IS NOT NULL",
|
||||
:limit => 100
|
||||
scope :team_stats,
|
||||
:select => "id, team_id, SUM(kills)/SUM(deaths) as kpd, COUNT(DISTINCT round_id) as rounds",
|
||||
:group => "team_id",
|
||||
:order => "kpd DESC",
|
||||
:having => "rounds > 30 AND kpd > 0 AND team_id IS NOT NULL",
|
||||
:limit => 100
|
||||
scope :extras, :include => [:round, :user]
|
||||
scope :within,
|
||||
lambda { |from, to|
|
||||
{:conditions => ["created_at > ? AND created_at < ?", from.utc, to.utc]} }
|
||||
|
||||
belongs_to :round
|
||||
belongs_to :user
|
||||
belongs_to :ensl_team, :class_name => "Team", :foreign_key => "team_id"
|
||||
|
||||
def to_s
|
||||
user ? user.username : name
|
||||
end
|
||||
end
|
16
app/views/log_events/edit.html.erb
Normal file
16
app/views/log_events/edit.html.erb
Normal file
|
@ -0,0 +1,16 @@
|
|||
<h1>Editing log_event</h1>
|
||||
|
||||
<%= form_for(@log_event) do |f| %>
|
||||
<%= f.error_messages %>
|
||||
|
||||
<p>
|
||||
<%= f.label :name %><br />
|
||||
<%= f.text_field :name %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.submit 'Update' %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Show', @log_event %> |
|
||||
<%= link_to 'Back', log_events_path %>
|
20
app/views/log_events/index.html.erb
Normal file
20
app/views/log_events/index.html.erb
Normal file
|
@ -0,0 +1,20 @@
|
|||
<h1>Listing log_events</h1>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
</tr>
|
||||
|
||||
<% @log_events.each do |log_event| %>
|
||||
<tr>
|
||||
<td><%=h log_event.name %></td>
|
||||
<td><%= link_to 'Show', log_event %></td>
|
||||
<td><%= link_to 'Edit', edit_log_event_path(log_event) %></td>
|
||||
<td><%= link_to 'Destroy', log_event, :confirm => 'Are you sure?', :method => :delete %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
<%= link_to 'New log_event', new_log_event_path %>
|
15
app/views/log_events/new.html.erb
Normal file
15
app/views/log_events/new.html.erb
Normal file
|
@ -0,0 +1,15 @@
|
|||
<h1>New log_event</h1>
|
||||
|
||||
<%= form_for(@log_event) do |f| %>
|
||||
<%= f.error_messages %>
|
||||
|
||||
<p>
|
||||
<%= f.label :name %><br />
|
||||
<%= f.text_field :name %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.submit 'Create' %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Back', log_events_path %>
|
8
app/views/log_events/show.html.erb
Normal file
8
app/views/log_events/show.html.erb
Normal file
|
@ -0,0 +1,8 @@
|
|||
<p>
|
||||
<b>Name:</b>
|
||||
<%=h @log_event.name %>
|
||||
</p>
|
||||
|
||||
|
||||
<%= link_to 'Edit', edit_log_event_path(@log_event) %> |
|
||||
<%= link_to 'Back', log_events_path %>
|
23
app/views/rounds/_rounds.html.erb
Normal file
23
app/views/rounds/_rounds.html.erb
Normal file
|
@ -0,0 +1,23 @@
|
|||
<table class="data">
|
||||
<tr>
|
||||
<th><%= sort_link "Date", :start %></th>
|
||||
<th><%= sort_link "Server", :server %></th>
|
||||
<th><%= sort_link "Team 1", :team1 %></th>
|
||||
<th><%= sort_link "Team 2", :team2 %></th>
|
||||
<th><%= sort_link "Map", :map %></th>
|
||||
<th><%= sort_link "commander", :commander %></th>
|
||||
</tr>
|
||||
|
||||
<% rounds.each do |round| %>
|
||||
<tr class="<%= cycle('even', 'odd') %>">
|
||||
<td><%= link_to (shorttime round.start), round %></td>
|
||||
<td><%= namelink round.server %></td>
|
||||
<td><%= namelink round.team1 if round.team1 %></td>
|
||||
<td><%= namelink round.team2 if round.team2 %></td>
|
||||
<td><%= round.map.nil? ? h(round.map_name) : namelink(round.map) %></td>
|
||||
<td><%= (round.commander.nil? or round.commander.user.nil?) ? h(round.commander) : namelink(round.commander.user) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<%= will_paginate rounds %>
|
7
app/views/rounds/index.html.erb
Normal file
7
app/views/rounds/index.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
|||
<h1>
|
||||
ENSL Round Archive
|
||||
</h1>
|
||||
|
||||
<div class="wide box" id="roundsList">
|
||||
<%= render :partial => "rounds", :object => @rounds %>
|
||||
</div>
|
150
app/views/rounds/show.html.erb
Normal file
150
app/views/rounds/show.html.erb
Normal file
|
@ -0,0 +1,150 @@
|
|||
<div class="wide box">
|
||||
<h1>
|
||||
<%= namelink @round.server %> : <%= longtime @round.start %>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="wide box">
|
||||
<h2 class="center">
|
||||
General Info and Statistics
|
||||
</h2>
|
||||
|
||||
<div class="wide center">
|
||||
<%= cascade @round, ["winner_s", "length", "commander", "map_name"] %>
|
||||
</div>
|
||||
|
||||
<div class="equal left center">
|
||||
<% @round.logs.stats.each do |s| %>
|
||||
<% next unless @round.marine_stats.include? s.details %>
|
||||
<b><%= @round.marine_stats[s.details] %></b>: <%= s.num %> <br />
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="equal left center">
|
||||
<% @round.logs.stats.each do |s| %>
|
||||
<% next unless @round.alien_stats.include? s.details %>
|
||||
<b><%= @round.alien_stats[s.details] %></b>: <%= s.num %> <br />
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% {Log::TEAM_MARINES => "Marines", Log::TEAM_ALIENS => "Aliens"}.each do |team, name| %>
|
||||
<div class="wide box">
|
||||
<h2 class="center">
|
||||
<%= name %>
|
||||
</h2>
|
||||
|
||||
<table class="data">
|
||||
<tr>
|
||||
<th width="30%">Name</th>
|
||||
<th width="15%">ENSL</th>
|
||||
<th width="15%">Team</th>
|
||||
<th width="45">Roles</th>
|
||||
<th width="5%">Kills</th>
|
||||
<th width="5%">Deaths</th>
|
||||
</tr>
|
||||
<% @round.rounders.team(team).ordered.each do |rounder| %>
|
||||
<tr>
|
||||
<td><%= h rounder.name %></td>
|
||||
<td><%= namelink rounder.user if rounder.user %></td>
|
||||
<td><%= namelink rounder.ensl_team if rounder.ensl_team %></td>
|
||||
<td><%= h rounder.roles %></td>
|
||||
<td><%= rounder.kills %></td>
|
||||
<td><%= rounder.deaths %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="wide box">
|
||||
<h2 class="center">
|
||||
Round Timeline
|
||||
</h2>
|
||||
|
||||
<div id="roundEvents">
|
||||
<div id="roundAliens">
|
||||
<h4 class="center">
|
||||
Aliens
|
||||
</h4>
|
||||
|
||||
<% alien_total = 0 %>
|
||||
<% consecutives = 0 %>
|
||||
<% @round.logs.each do |log| %>
|
||||
<% next unless e = Round.alien_event(log.details) %>
|
||||
<% next if log.details == "kill" and (m = log.frag)[2] != "alien" %>
|
||||
<% add = log.since*8 - alien_total %>
|
||||
<% consecutives = add < 0 ? (consecutives + 1) : 0 %>
|
||||
<% left = 145 - (add < 0 ? 105*consecutives : 0) %>
|
||||
|
||||
<% if log.details == "kill" %>
|
||||
<div class="roundEvent roundFrag" style="margin-top: <%= add %>px; margin-left: <%= left %>px" title="<%= log.time %>">
|
||||
<span>
|
||||
<%= Verification.uncrap(m[1])[0, 7] %>
|
||||
</span>
|
||||
<%= image_tag 'weapons/' + m[5] + '.gif', :width => 22, :height => 14 %>
|
||||
<span>
|
||||
<%= Verification.uncrap(m[3])[0, 7] %>
|
||||
</span>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="roundEvent" style="margin-top: <%= add %>px; margin-left: <%= left %>px" title="<%= log.time %>">
|
||||
<% if ["onos", "fade", "lerk", "gorge"].include? log.details %>
|
||||
<%= Verification.uncrap(log.role[1])[0, 7] %> <%= log.role[2] %>s
|
||||
<% else %>
|
||||
<%= h e %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% add = add + 15 %>
|
||||
<% alien_total = alien_total + (add > 0 ? add : 0) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div id="roundTimeline" style="height: <%= alien_total %>px"></div>
|
||||
|
||||
<div id="roundMarines">
|
||||
<h4 class="center">
|
||||
Marines
|
||||
</h4>
|
||||
|
||||
<% marine_total = 0 %>
|
||||
<% consecutives = 0 %>
|
||||
<% @round.logs.each do |log| %>
|
||||
<% next unless e = Round.marine_event(log.details) %>
|
||||
<% next if log.details == "kill" and (m = log.frag)[2] != "marine" %>
|
||||
<% add = log.since*8 - marine_total %>
|
||||
<% consecutives = add < 0 ? (consecutives + 1) : 0 %>
|
||||
<% left = 3 + (add < 0 ? 105*consecutives : 0) %>
|
||||
|
||||
<% if log.details == "kill" %>
|
||||
<div class="roundEvent roundFrag" style="margin-top: <%= add %>px; margin-left: <%= left %>px" title="<%= log.time %>">
|
||||
<span>
|
||||
<%= Verification.uncrap(m[1])[0, 7] %>
|
||||
</span>
|
||||
<%= image_tag 'weapons/' + m[5] + '.gif', :width => 30, :height => 14 %>
|
||||
<span>
|
||||
<%= Verification.uncrap(m[3])[0, 7] %>
|
||||
</span>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="roundEvent" style="margin-top: <%= add %>px; margin-left: <%= left %>px" title="<%= log.time %>">
|
||||
<%= h e %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% add = add + 15 %>
|
||||
<% marine_total = marine_total + (add > 0 ? add : 0) %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% total = marine_total > alien_total ? marine_total : alien_total %>
|
||||
<script type="application/javascript">
|
||||
$('roundAliens').style.height = "<%= total + 20 %>px";
|
||||
$('roundTimeline').style.height = "<%= total + 20 %>px"
|
||||
$('roundMarines').style.height = "<%= total + 20 %>px"
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br class="clear">
|
Loading…
Reference in a new issue