steam_hlds_log_parser 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 30af9317dcddbf6bebd31d3bb02ff5df117db707
4
+ data.tar.gz: ab06662bf153b61c2cdab5b9d64209ced673e4e9
5
+ SHA512:
6
+ metadata.gz: 774c7685110aca35822f3642a5a93bbca4bd196f6ddad776345938e29a76df62f3f3b72c866898925f64ed0128a064b8046e9581db9553e6eb4719ea200a07aa
7
+ data.tar.gz: 5b8c66867b180997d6769fbff9f047346a270bddfce355fc842eafe55c3af72df5a4ab0deaf3f21112704609393682cba8e5b064a9c2e97420e7631d10ece3f9
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ repo_token: WVARN24eiGJQ6GenqWAsqNQEZroHGj2SP
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
19
+
20
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in steam_hlds_log_parser.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Thomas VIAL
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # Steam Hlds Log Parser
2
+
3
+ Creates a server with EventMachine which listens to HLDS logs, parse and returns readable content from your game server.
4
+ The returned content can be sent to a website, IRC or flowdock for match live streaming.
5
+
6
+ Mostly tested on Steam HLDS for Counter-Strike.
7
+
8
+ Note : content is sent in english or french at this time. Need i18n contributors!
9
+
10
+ ## Build Status
11
+
12
+ [![Build Status](https://travis-ci.org/tomav/steam_hlds_log_parser.png?branch=master)](https://travis-ci.org/tomav/steam_hlds_log_parser)
13
+ [![Gem Version](https://badge.fury.io/rb/steam_hlds_log_parser.png)](http://badge.fury.io/rb/steam_hlds_log_parser)
14
+ [![Coverage Status](https://coveralls.io/repos/tomav/steam_hlds_log_parser/badge.png)](https://coveralls.io/r/tomav/steam_hlds_log_parser)
15
+
16
+ ## Installation
17
+
18
+ Add this line to your application's Gemfile:
19
+
20
+ gem 'steam_hlds_log_parser'
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install steam_hlds_log_parser
29
+
30
+ ## Usage
31
+
32
+ 1. Create your own displayer callback `class` which will receive parsed data
33
+ Ask this `class` to write a file, send content to IRC or flowdock... whatever... and give it as `:displayer` Hash option
34
+ 2. Create a new client on desired IP / Port / Options
35
+ 3. In your HLDS server: `logaddress 127.0.0.1 27035`
36
+
37
+ ## Example
38
+
39
+ require "rubygems"
40
+ require "steam_hlds_log_parser"
41
+
42
+ class Formatter
43
+ def initialize(data)
44
+ # will 'puts' the translated content
45
+ SteamHldsLogParser::Displayer.new(data).display_translation
46
+ end
47
+ end
48
+
49
+
50
+ ## These are default options
51
+ options = {
52
+ :locale => :en,
53
+ :display_kills => true,
54
+ :display_actions => true,
55
+ :display_changelevel => true,
56
+ :displayer => Formatter
57
+ }
58
+
59
+ parser = SteamHldsLogParser::Client.new("127.0.0.1", 27035, options)
60
+ parser.start
61
+
62
+
63
+ ## Contributing
64
+
65
+ 1. Fork it
66
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
67
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
68
+ 4. Push to the branch (`git push origin my-new-feature`)
69
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "rubygems"
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task :default => [:spec]
@@ -0,0 +1,22 @@
1
+ require "rubygems"
2
+ require "steam_hlds_log_parser"
3
+
4
+ class Formatter
5
+ def initialize(data)
6
+ # will 'puts' the translated content
7
+ SteamHldsLogParser::Displayer.new(data).display_translation
8
+ end
9
+ end
10
+
11
+
12
+ ## These are default options
13
+ options = {
14
+ :locale => :en,
15
+ :display_kills => true,
16
+ :display_actions => true,
17
+ :display_changelevel => true,
18
+ :displayer => Formatter
19
+ }
20
+
21
+ parser = SteamHldsLogParser::Client.new("127.0.0.1", 27035, options)
22
+ parser.start
@@ -0,0 +1,24 @@
1
+ require "rubygems"
2
+ require "steam_hlds_log_parser"
3
+ # require "flowdock"
4
+
5
+ ## The displayer class that will be used to send content to Flowdock
6
+ class FlowdockPusher
7
+ def initialize(data)
8
+ # Get translated data
9
+ content = SteamHldsLogParser::Displayer.new(data).get_translation
10
+ # Source: https://github.com/flowdock/flowdock-api
11
+ flow = Flowdock::Flow.new(:api_token => "12345678901234567890123456789012", :external_user_name => "HLDS-Live")
12
+ flow.push_to_chat(:content => content)
13
+ end
14
+ end
15
+
16
+ options = {
17
+ :locale => :fr,
18
+ :display_kills => true,
19
+ :display_actions => true,
20
+ :display_changelevel => true,
21
+ :displayer => FlowdockPusher
22
+ }
23
+
24
+ SteamHldsLogParser::Client.new("127.0.0.1", 27035, options).start
data/lib/.DS_Store ADDED
Binary file
@@ -0,0 +1,42 @@
1
+ en:
2
+ # client
3
+ client_connect: "HLDS connected and sending data"
4
+ client_disconnect: "HLDS disconnected? No data is received."
5
+ client_stop: "HLDS Log Parser stopped."
6
+ # team
7
+ full_team_name_te: "Terrorist"
8
+ full_team_name_ct: "Counter-Terrorist"
9
+ short_team_name_te: "TE"
10
+ short_team_name_ct: "CT"
11
+ # round conclusion types
12
+ all_hostages_rescued: "All hostages have been rescued"
13
+ bomb_defused: "Bomb has been defused"
14
+ cts_preventescape: "The CT's have prevented most of the terrorists from escaping"
15
+ cts_win: "Counter-Terrorists Win"
16
+ hostages_not_rescued: "Hostages have not been rescued"
17
+ target_bombed: "Target Successfully Bombed!"
18
+ target_saved: "Target has been saved"
19
+ terrorists_escaped: "Terrorists have escaped"
20
+ terrorists_not_escaped: "Terrorists have not escaped"
21
+ terrorists_win: "Terrorists Win"
22
+ vip_assassinated: "The VIP has been assassinated"
23
+ vip_escaped: "The VIP has escaped"
24
+ vip_not_escaped: "VIP has not escaped"
25
+ # user actions
26
+ begin_bomb_defuse_with_kit: "begin bomb defuse with kit"
27
+ begin_bomb_defuse_without_kit: "begin bomb defuse without kit"
28
+ defused_the_bomb: "defused the bomb"
29
+ dropped_the_bomb: "dropped the bomb"
30
+ got_the_bomb: "got the bomb"
31
+ killed_a_hostage: "killed a hostage"
32
+ planted_the_bomb: "planted the bom"
33
+ rescued_a_hostage: "rescued a hostage"
34
+ spawned_with_the_bomb: "spawned with the bomb"
35
+ touched_a_hostage: "touched a hostage"
36
+ # events
37
+ map_ends: "Map ends: %{winner} => %{score}"
38
+ victory: "[CT] %{score_ct} - %{score_t} [T]"
39
+ kill: "[%{killer_team}] %{killer} killed [%{killed_team}] %{killed} with %{weapon}"
40
+ suicide: "%{killed} commited suicide"
41
+ event: "[%{person_team}] %{person} %{event_i18n}"
42
+ loading_map: "Loading %{map}"
@@ -0,0 +1,42 @@
1
+ fr:
2
+ # client
3
+ client_connect: "HLDS vient de se connecter et transmets des données."
4
+ client_disconnect: "HLDS s'est déconnecté ?"
5
+ client_stop: "HLDS Log Parser stoppé."
6
+ # team
7
+ full_team_name_te: "Terroriste"
8
+ full_team_name_ct: "Anti-Terroriste"
9
+ short_team_name_te: "TE"
10
+ short_team_name_ct: "CT"
11
+ # round conclusion types
12
+ all_hostages_rescued: "Tous les otages ont été sauvés"
13
+ bomb_defused: "La bombe a été désamorçée"
14
+ cts_preventescape: "Les CT ont empéché l'évasion des Terroristes"
15
+ cts_win: "Victoire des Anti-Terroristes"
16
+ hostages_not_rescued: "Les otages n'ont pas été sauvés"
17
+ target_bombed: "La cible a été détruite !"
18
+ target_saved: "La cible a été protégée"
19
+ terrorists_escaped: "Les Terroristes se sont échappés"
20
+ terrorists_not_escaped: "Les Terroristes ne se sont pas échappés"
21
+ terrorists_win: "Victoire des Terroristes"
22
+ vip_assassinated: "Le VIP a été assassiné"
23
+ vip_escaped: "Le VIP s'est échappé"
24
+ vip_not_escaped: "Le VIP ne s'est pas échappé"
25
+ # user actions
26
+ begin_bomb_defuse_with_kit: "commence à désamorcer la bombe avec un kit"
27
+ begin_bomb_defuse_without_kit: "commence à désamorcer la bombe sans kit"
28
+ defused_the_bomb: "a désamorcé la bombe"
29
+ dropped_the_bomb: "a perdu la bombe"
30
+ got_the_bomb: "a récupéré la bombe"
31
+ killed_a_hostage: "a tué un otage"
32
+ planted_the_bomb: "a posé la bombe"
33
+ rescued_a_hostage: "a sauvé un otage"
34
+ spawned_with_the_bomb: "a la bombe"
35
+ touched_a_hostage: "a récupéré un otage"
36
+ # events
37
+ map_ends: "Fin de partie : Score des %{winner} => %{score}"
38
+ victory: "[CT] %{score_ct} - %{score_t} [TE]"
39
+ kill: "[%{killer_team}] %{killer} a tué [%{killed_team}] %{killed} au %{weapon}"
40
+ suicide: "%{killed} s'est tué"
41
+ event: "[%{person_team}] %{person} %{event_i18n}"
42
+ loading_map: "Chargement de %{map}"
@@ -0,0 +1,52 @@
1
+ module SteamHldsLogParser
2
+
3
+ class Client
4
+
5
+ attr_reader :host, :port, :options
6
+
7
+ # Creates a new client
8
+ #
9
+ # @host [String] Hostname / IP Address the server will be running
10
+ # @port [Integer] Port to listen to
11
+ # @options [Hash] Other options
12
+ #
13
+ # ==== Options
14
+ #
15
+ # * +locale+ - Set the language of returned content
16
+ # * +display_kills+ Enable kills / frags detail (default=true)
17
+ # * +display_actions+ Enable players actions / defuse / ... detail (default=true)
18
+ # * +display_changelevel+ Enable changelevel (map) display (default=true)
19
+ # * +displayer+ Class that will be use to display content (default=HldsReturnDisplayer)
20
+ #
21
+ def initialize(host, port, options = {})
22
+ default_options = {
23
+ :locale => :en,
24
+ :display_kills => true,
25
+ :display_actions => true,
26
+ :display_changelevel => true
27
+ }
28
+ @host, @port = host, port
29
+ @options = default_options.merge(options)
30
+ end
31
+
32
+ # Starts the client which will receive HLDS logs (using UDP)
33
+ def start
34
+ # setting locale
35
+ I18n.locale = @options[:locale] || I18n.default_locale
36
+ EM.run {
37
+ # catch CTRL+C
38
+ Signal.trap("INT") { EM.stop }
39
+ Signal.trap("TERM") { EM.stop }
40
+ # Let's start
41
+ EM::open_datagram_socket(@host, @port, Handler, @host, @port, @options)
42
+ }
43
+ end
44
+
45
+ # Stops the client
46
+ def stop
47
+ puts "## #{@host}:#{@port} => #{I18n.t('client_stop')}"
48
+ EM::stop_event_loop
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,37 @@
1
+ module SteamHldsLogParser
2
+
3
+ # Default Displayer
4
+ #
5
+ # @data [Hash] Data returned by 'receive_data'
6
+ #
7
+ class Displayer
8
+
9
+ attr_reader :data
10
+
11
+ def initialize(data)
12
+ @data = data
13
+ end
14
+
15
+ # Return data
16
+ def get_data
17
+ return @data
18
+ end
19
+
20
+ # Display data
21
+ def display_data
22
+ puts get_data
23
+ end
24
+
25
+ # Return data translation
26
+ def get_translation
27
+ return I18n.t(@data[:type], @data[:params]) unless @data[:type].nil?
28
+ end
29
+
30
+ # Display data translation
31
+ def display_translation
32
+ puts get_translation
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,103 @@
1
+ module SteamHldsLogParser
2
+
3
+ class Handler < EM::Connection
4
+
5
+ attr_reader :host, :port, :options
6
+
7
+ # Initialize Handler from Client options
8
+ #
9
+ # @host [String] Hostname / IP Address the server will be running
10
+ # @port [Integer] Port to listen to
11
+ # @options [Hash] Other options
12
+ #
13
+ def initialize(host, port, options)
14
+ @host, @port, @options = host, port, options
15
+ end
16
+
17
+ # Triggered when HLDS connects
18
+ def post_init
19
+ puts "## #{@host}:#{@port} => #{I18n.t('client_connect')}"
20
+ end
21
+
22
+ # Triggered when HLDS disconnects
23
+ def unbind
24
+ puts "## #{@host}:#{@port} => #{I18n.t('client_disconnect')}"
25
+ end
26
+
27
+ # Get data from Client and parse using Regexp
28
+ #
29
+ # * match end of map, with winner team and score
30
+ # * match the end of round, with score and victory type
31
+ # * match who killed who with what (frags)
32
+ # * match suicides
33
+ # * match who did what (defuse, drop the bomb...)
34
+ # * match changelevel
35
+ #
36
+ # @data [String] Data received by Client from HLDS server (a line of log)
37
+ #
38
+ def receive_data(data)
39
+
40
+ # L 05/10/2000 - 12:34:56: Team "CT" scored "17" with "0" players
41
+ if data.gsub(/Team "(.+)" scored "(\d+)" with "(\d+)"/).count > 0
42
+ winner, winner_score = data.match(/Team "(.+)" scored "(\d+)" with/).captures
43
+ content = { :type => 'map_ends', :params => { :winner => get_short_team_name(winner), :score => winner_score } }
44
+
45
+ # L 05/10/2000 - 12:34:56: Team "CT" triggered "CTs_Win" (CT "3") (T "0")
46
+ elsif data.gsub(/(: Team ")/).count > 0
47
+ winner, type, score_ct, score_t = data.match(/Team "([A-Z]+)" triggered "([A-Za-z_]+)" \(CT "(\d+)"\) \(T "(\d+)"\)/i).captures
48
+ content = { :type => 'victory', :params => { :score_ct => score_ct, :score_t => score_t } }
49
+
50
+ # L 05/10/2000 - 12:34:56: "Killer | Player<66><STEAM_ID_LAN><TERRORIST>" killed "Killed | Player<60><STEAM_ID_LAN><CT>" with "ak47"
51
+ elsif @options[:display_kills] && data.gsub(/(\>" killed ")/).count > 0
52
+ killer, killer_team, killed, killed_team, weapon = data.match(/"(.+)<\d+><STEAM_ID_LAN><(.+)>" killed "(.+)<\d+><STEAM_ID_LAN><(.+)>" with "(.+)"/i).captures
53
+ content = { :type => 'kill', :params => { :killer_team => get_short_team_name(killer_team), :killer => killer, :killed_team => get_short_team_name(killed_team), :killed => killed, :weapon => weapon } }
54
+
55
+ # L 05/10/2000 - 12:34:56: "Player<66><STEAM_ID_LAN><TERRORIST>" committed suicide with "worldspawn" (world)
56
+ elsif @options[:display_kills] && data.gsub(/>" committed suicide/).count > 0
57
+ killed = data.match(/: "(.+)<\d+>/).captures.first
58
+ content = { :type => 'suicide', :params => { :killed => killed } }
59
+
60
+ # L 05/10/2000 - 12:34:56: "Killer | Player<66><STEAM_ID_LAN><CT>" triggered "Defused_The_Bomb"
61
+ elsif @options[:display_actions] && data.gsub(/<STEAM_ID_LAN><.+>" triggered "(.+)"$/).count > 0
62
+ person, person_team, event = data.match(/: "(.+)<\d+><STEAM_ID_LAN><(.+)>" triggered "(.+)"/i).captures
63
+ content = { :type => 'event', :params => { :person_team => get_short_team_name(person_team), :person => person, :event_item => event, :event_i18n => I18n.t(event.downcase)} }
64
+
65
+ # L 05/10/2000 - 12:34:56: Loading map "de_dust2"
66
+ elsif @options[:display_changelevel] && data.gsub(/: Loading map "(.+)"/).count > 0
67
+ map = data.match(/: Loading map "(.+)"/i).captures.first
68
+ content = { :type => 'loading_map', :params => { :map => map } }
69
+
70
+ end
71
+
72
+ if @options[:displayer].nil?; return(content) else @options[:displayer].new(content) end
73
+
74
+ end
75
+
76
+ # Format team name with long format (textual)
77
+ #
78
+ # @winner [String] Round winner (+CT+ or +T+) from logs
79
+ #
80
+ def get_full_team_name(winner)
81
+ case winner
82
+ when "T"
83
+ return "#{I18n.t('full_team_name_te')}"
84
+ else
85
+ return "#{I18n.t('full_team_name_ct')}"
86
+ end
87
+ end
88
+
89
+ # Format team name with short format (initials)
90
+ #
91
+ # @team [String] Round winner (+CT+ or +TERRORIST+) from logs
92
+ #
93
+ def get_short_team_name(team)
94
+ case team
95
+ when "TERRORIST"
96
+ return "#{I18n.t('short_team_name_te')}"
97
+ else
98
+ return "#{I18n.t('short_team_name_ct')}"
99
+ end
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,3 @@
1
+ module SteamHldsLogParser
2
+ VERSION = "0.4.0"
3
+ end
@@ -0,0 +1,16 @@
1
+ require "rubygems"
2
+ require "eventmachine"
3
+ require "i18n"
4
+ require "rdoc"
5
+
6
+ require "steam_hlds_log_parser/version"
7
+ require "steam_hlds_log_parser/client"
8
+ require "steam_hlds_log_parser/handler"
9
+ require "steam_hlds_log_parser/displayer"
10
+
11
+ module SteamHldsLogParser
12
+
13
+ I18n.load_path = Dir.glob( File.dirname(__FILE__) + "/locales/*.yml" )
14
+ I18n.default_locale = :en
15
+
16
+ end
@@ -0,0 +1,69 @@
1
+ require "helper_spec"
2
+
3
+ module SteamHldsLogParser
4
+
5
+ describe "SteamHldsLogParser" do
6
+
7
+ before :all do
8
+ @client = Client.new("0.0.0.0", 27035)
9
+ @options = @client.options
10
+ @custom_options = custom_options
11
+ @custom_client = Client.new("127.0.0.1", 27045, @custom_options)
12
+ end
13
+
14
+ describe "Client" do
15
+
16
+ it "raises an exception when parameters are missing" do
17
+ expect { Client.new }.to raise_error(ArgumentError)
18
+ end
19
+
20
+ subject { @client }
21
+ context "when a 'Client' is created without options"
22
+ it { should be_an_instance_of Client }
23
+ it "has a 'host'" do
24
+ @client.host.should_not be_nil
25
+ @client.host.should eq("0.0.0.0")
26
+ end
27
+ it "has a 'port'" do
28
+ @client.port.should_not be_nil
29
+ @client.port.should eq(27035)
30
+ end
31
+ it "has a default 'options' Hash" do
32
+ @client.options.should_not be_nil
33
+ @client.options.should_not be(nil)
34
+ @client.options.class.should be(Hash)
35
+ @client.options.should eq(@options)
36
+ end
37
+
38
+ subject(:custom_client) { @custom_client }
39
+ context "when custom options are given"
40
+ it "can get a custom 'options' Hash" do
41
+ @custom_client.options.should_not be_nil
42
+ @custom_client.options.class.should be(Hash)
43
+ @custom_client.options.should eq(@custom_options)
44
+ @custom_client.options[:displayer].should eq(RSpecDisplayer)
45
+ @custom_client.options[:locale].should be(:fr)
46
+ @custom_client.options[:display_kills].should be(false)
47
+ @custom_client.options[:display_actions].should be(false)
48
+ @custom_client.options[:display_changelevel].should be(false)
49
+ end
50
+
51
+ describe "#start and #stop" do
52
+
53
+ context "when 'start' and 'stop' are triggered one after the other"
54
+ it "starts then stops an eventmachine with appropriate messages" do
55
+ EM.run {
56
+ capture_stdout { @client.start }.should eq("## 0.0.0.0:27035 => HLDS connected and sending data\n")
57
+ EM.add_timer(0.2) {
58
+ capture_stdout { @client.stop }.should eq("## 0.0.0.0:27035 => HLDS Log Parser stopped.\n")
59
+ }
60
+ }
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,59 @@
1
+ require "helper_spec"
2
+
3
+ module SteamHldsLogParser
4
+
5
+ describe "SteamHldsLogParser" do
6
+
7
+ before :all do
8
+ @data = {:type=>"victory", :params=>{:score_ct=>"3", :score_t=>"0"}}
9
+ @displayer = Displayer.new(@data)
10
+ end
11
+
12
+ describe "Displayer" do
13
+
14
+ context "when 'data' is missing" do
15
+ it "raises an exception" do
16
+ expect { Displayer.new }.to raise_error(ArgumentError)
17
+ end
18
+ end
19
+
20
+ context "when 'data' is given" do
21
+
22
+ it "creates a 'Displayer'" do
23
+ @displayer.should be_an_instance_of Displayer
24
+ end
25
+
26
+ describe "#get_data" do
27
+ it "returns 'data' given as argument" do
28
+ @displayer.get_data.should_not be_nil
29
+ @displayer.get_data.should be(@data)
30
+ end
31
+ end
32
+
33
+ describe "#display_data" do
34
+ it "displays 'data' given as argument" do
35
+ eval(capture_stdout { @displayer.display_data }).should eq(@data)
36
+ end
37
+ end
38
+
39
+ describe "#get_translation" do
40
+ it "returns translated 'data' given as argument" do
41
+ @displayer.get_translation.should_not be_nil
42
+ @displayer.get_translation.class.should be(String)
43
+ @displayer.get_translation.should eq("[CT] 3 - 0 [T]")
44
+ end
45
+ end
46
+
47
+ describe "#display_translation" do
48
+ it "displays translated 'data' given as argument" do
49
+ capture_stdout { @displayer.display_translation }.should eq("[CT] 3 - 0 [T]\n")
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,138 @@
1
+ require "helper_spec"
2
+
3
+ module SteamHldsLogParser
4
+
5
+ describe "SteamHldsLogParser" do
6
+
7
+ before :all do
8
+ @client = Client.new("0.0.0.0", 27035)
9
+ @options = @client.options
10
+ @handler = Handler.new("", "0.0.0.0", 27035, @options)
11
+ end
12
+
13
+ describe "Handler" do
14
+
15
+ context "when parameters are missing" do
16
+ it "raises an exception" do
17
+ expect { Handler.new }.to raise_error(ArgumentError)
18
+ end
19
+ end
20
+
21
+ context "when parameters are given" do
22
+ subject { @handler }
23
+
24
+ context "when 'host' and 'port' are given"
25
+ it { should be_an_instance_of Handler }
26
+ it "has a 'host'" do
27
+ @handler.host.should_not be_nil
28
+ @handler.host.should eq("0.0.0.0")
29
+ end
30
+ it "has a 'port'" do
31
+ @handler.port.should_not be_nil
32
+ @handler.port.should eq(27035)
33
+ end
34
+
35
+ describe "#post_init" do
36
+ it "displays a console message when hlds connects" do
37
+ capture_stdout { @handler.post_init }.should eq("## 0.0.0.0:27035 => HLDS connected and sending data\n")
38
+ end
39
+ end
40
+
41
+ describe "#unbind" do
42
+ it "displays a console message when hlds disconnects" do
43
+ capture_stdout { @handler.unbind }.should eq("## 0.0.0.0:27035 => HLDS disconnected? No data is received.\n")
44
+ end
45
+ end
46
+
47
+ describe "#receive_data" do
48
+
49
+ context "when data is not supported" do
50
+ it "returns anything" do
51
+ data = '# L 05/10/2000 - 12:34:56: I am a fake line of log'
52
+ @handler.receive_data(data).should eq(nil)
53
+ end
54
+ end
55
+
56
+ context "when data is 'map_ends'" do
57
+ it "returns Hash on map_ends" do
58
+ data = '# L 05/10/2000 - 12:34:56: Team "CT" scored "17" with "0" players"'
59
+ expected = {:type=>"map_ends", :params=>{:winner=>"CT", :score=>"17"}}
60
+ @handler.receive_data(data).class.should eq(Hash)
61
+ @handler.receive_data(data).should eq(expected)
62
+ end
63
+ end
64
+
65
+ context "when data is 'victory'" do
66
+ it "returns Hash on victory" do
67
+ data = '# L 05/10/2000 - 12:34:56: Team "CT" triggered "CTs_Win" (CT "3") (T "0")'
68
+ expected = {:type=>"victory", :params=>{:score_ct=>"3", :score_t=>"0"}}
69
+ @handler.receive_data(data).class.should eq(Hash)
70
+ @handler.receive_data(data).should eq(expected)
71
+ end
72
+ end
73
+
74
+ context "when data is 'killed'" do
75
+ it "returns Hash on killed" do
76
+ data = '# L 05/10/2000 - 12:34:56: "Killer | Player<66><STEAM_ID_LAN><TERRORIST>" killed "Killed | Player<60><STEAM_ID_LAN><CT>" with "ak47"'
77
+ expected = {:type=>"kill", :params => {:killer_team=>"TE", :killer=>"Killer | Player", :killed_team=>"CT", :killed=>"Killed | Player", :weapon=>"ak47"}}
78
+ @handler.receive_data(data).class.should eq(Hash)
79
+ @handler.receive_data(data).should eq(expected)
80
+ end
81
+ end
82
+
83
+ context "when data is 'suicide'" do
84
+ it "returns Hash on suicide" do
85
+ data = '# L 05/10/2000 - 12:34:56: "Player<66><STEAM_ID_LAN><TERRORIST>" committed suicide with "worldspawn" (world)'
86
+ expected = {:type=>"suicide", :params=>{:killed=>"Player"}}
87
+ @handler.receive_data(data).class.should eq(Hash)
88
+ @handler.receive_data(data).should eq(expected)
89
+ end
90
+ end
91
+
92
+ context "when data is 'event'" do
93
+ it "returns Hash on event" do
94
+ data = '# L 05/10/2000 - 12:34:56: "Killer | Player<66><STEAM_ID_LAN><CT>" triggered "Defused_The_Bomb"'
95
+ expected = {:type=>"event", :params=> {:person_team=>"CT", :person=>"Killer | Player", :event_item=>"Defused_The_Bomb", :event_i18n=>"defused the bomb"}}
96
+ @handler.receive_data(data).class.should eq(Hash)
97
+ @handler.receive_data(data).should eq(expected)
98
+ end
99
+ end
100
+
101
+ context "when data is 'changelevel'" do
102
+ it "returns Hash on changelevel" do
103
+ data = '# L 05/10/2000 - 12:34:56: Loading map "de_dust2"'
104
+ expected = {:type=>"loading_map", :params=>{:map=>"de_dust2"}}
105
+ @handler.receive_data(data).class.should eq(Hash)
106
+ @handler.receive_data(data).should eq(expected)
107
+ end
108
+ end
109
+
110
+ end
111
+
112
+ describe "#get_full_team_name" do
113
+
114
+ context "when short name is given"
115
+ it "returns full name" do
116
+ @handler.get_full_team_name("T").should eq("Terrorist")
117
+ @handler.get_full_team_name("CT").should eq("Counter-Terrorist")
118
+ end
119
+
120
+ end
121
+
122
+ describe "#get_short_team_name" do
123
+
124
+ context "when full name is given"
125
+ it "returns short name" do
126
+ @handler.get_short_team_name("TERRORIST").should eq("TE")
127
+ @handler.get_short_team_name("CT").should eq("CT")
128
+ end
129
+
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+
136
+ end
137
+
138
+ end
@@ -0,0 +1,39 @@
1
+ require "simplecov"
2
+ require "coveralls"
3
+ require "rspec"
4
+
5
+ # Simplecov / Coverall configuration
6
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
7
+ SimpleCov.start do
8
+ add_filter "/example/"
9
+ add_filter "/spec/"
10
+ end
11
+
12
+ # Get ouput content of the given block
13
+ # Source: https://github.com/cldwalker/hirb/blob/master/test/test_helper.rb
14
+ def capture_stdout(&block)
15
+ original_stdout = $stdout
16
+ $stdout = fake = StringIO.new
17
+ begin
18
+ yield
19
+ ensure
20
+ $stdout = original_stdout
21
+ end
22
+ fake.string
23
+ end
24
+
25
+ class RSpecDisplayer
26
+ end
27
+
28
+ require "steam_hlds_log_parser"
29
+
30
+ # Returns custom options as a Hash
31
+ def custom_options
32
+ options = {
33
+ :locale => :fr,
34
+ :display_kills => false,
35
+ :display_actions => false,
36
+ :display_changelevel => false,
37
+ :displayer => RSpecDisplayer
38
+ }
39
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'steam_hlds_log_parser/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "steam_hlds_log_parser"
8
+ spec.version = SteamHldsLogParser::VERSION
9
+ spec.authors = ["Thomas VIAL"]
10
+ spec.email = ["github@ifusio.com"]
11
+ spec.description = %q{Steam HLDS Log Parser receives logs from your Steam game server and parses them in real time to give you usable content for your website, irc channel / flowdock... Works well with Counter-Strike and others Half-life based games.}
12
+ spec.summary = %q{Steam HLDS Log Parser receives logs from your Steam game server and parses them in real time to give you usable content for your website, irc channel / flowdock... Works well with Counter-Strike and others Half-life based games.}
13
+ spec.homepage = "https://github.com/tomav/steam_hlds_log_parser"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "bundler", "~> 1.3"
22
+ spec.add_dependency "rake"
23
+ spec.add_dependency "eventmachine", "~> 1.0.3"
24
+ spec.add_dependency "i18n"
25
+
26
+ spec.add_development_dependency "simplecov"
27
+ spec.add_development_dependency "coveralls"
28
+ spec.add_development_dependency "rspec-core"
29
+ spec.add_development_dependency "rspec"
30
+
31
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: steam_hlds_log_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Thomas VIAL
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2013-08-13 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: "1.3"
22
+ type: :runtime
23
+ version_requirements: *id001
24
+ - !ruby/object:Gem::Dependency
25
+ name: rake
26
+ prerelease: false
27
+ requirement: &id002 !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - &id004
30
+ - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id002
35
+ - !ruby/object:Gem::Dependency
36
+ name: eventmachine
37
+ prerelease: false
38
+ requirement: &id003 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: 1.0.3
43
+ type: :runtime
44
+ version_requirements: *id003
45
+ - !ruby/object:Gem::Dependency
46
+ name: i18n
47
+ prerelease: false
48
+ requirement: &id005 !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - *id004
51
+ type: :runtime
52
+ version_requirements: *id005
53
+ - !ruby/object:Gem::Dependency
54
+ name: simplecov
55
+ prerelease: false
56
+ requirement: &id006 !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - *id004
59
+ type: :development
60
+ version_requirements: *id006
61
+ - !ruby/object:Gem::Dependency
62
+ name: coveralls
63
+ prerelease: false
64
+ requirement: &id007 !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - *id004
67
+ type: :development
68
+ version_requirements: *id007
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-core
71
+ prerelease: false
72
+ requirement: &id008 !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - *id004
75
+ type: :development
76
+ version_requirements: *id008
77
+ - !ruby/object:Gem::Dependency
78
+ name: rspec
79
+ prerelease: false
80
+ requirement: &id009 !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - *id004
83
+ type: :development
84
+ version_requirements: *id009
85
+ description: Steam HLDS Log Parser receives logs from your Steam game server and parses them in real time to give you usable content for your website, irc channel / flowdock... Works well with Counter-Strike and others Half-life based games.
86
+ email:
87
+ - github@ifusio.com
88
+ executables: []
89
+
90
+ extensions: []
91
+
92
+ extra_rdoc_files: []
93
+
94
+ files:
95
+ - .coveralls.yml
96
+ - .gitignore
97
+ - .rspec
98
+ - .travis.yml
99
+ - Gemfile
100
+ - LICENSE.txt
101
+ - README.md
102
+ - Rakefile
103
+ - example/example-1.rb
104
+ - example/example-2.rb
105
+ - lib/.DS_Store
106
+ - lib/locales/en.yml
107
+ - lib/locales/fr.yml
108
+ - lib/steam_hlds_log_parser.rb
109
+ - lib/steam_hlds_log_parser/client.rb
110
+ - lib/steam_hlds_log_parser/displayer.rb
111
+ - lib/steam_hlds_log_parser/handler.rb
112
+ - lib/steam_hlds_log_parser/version.rb
113
+ - spec/client_spec.rb
114
+ - spec/displayer_spec.rb
115
+ - spec/handler_spec.rb
116
+ - spec/helper_spec.rb
117
+ - steam_hlds_log_parser.gemspec
118
+ homepage: https://github.com/tomav/steam_hlds_log_parser
119
+ licenses:
120
+ - MIT
121
+ metadata: {}
122
+
123
+ post_install_message:
124
+ rdoc_options: []
125
+
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - *id004
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - *id004
134
+ requirements: []
135
+
136
+ rubyforge_project:
137
+ rubygems_version: 2.0.3
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Steam HLDS Log Parser receives logs from your Steam game server and parses them in real time to give you usable content for your website, irc channel / flowdock... Works well with Counter-Strike and others Half-life based games.
141
+ test_files:
142
+ - spec/client_spec.rb
143
+ - spec/displayer_spec.rb
144
+ - spec/handler_spec.rb
145
+ - spec/helper_spec.rb