demoman 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ script: bundle exec rake
5
+ before_install:
6
+ - gem update --system
data/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # demoman
2
2
 
3
+
4
+ [![Build Status](https://travis-ci.org/webdestroya/demoman.png)](https://travis-ci.org/webdestroya/demoman)
5
+ [![Code Climate](https://codeclimate.com/github/webdestroya/demoman.png)](https://codeclimate.com/github/webdestroya/demoman)
6
+ [![Coverage Status](https://coveralls.io/repos/webdestroya/demoman/badge.png)](https://coveralls.io/r/webdestroya/demoman)
7
+
3
8
  Demoman allows you to extract metadata from Half-Life and Half-Life 2 demo (.dem) files.
4
9
 
5
10
  ## Installation
@@ -14,37 +19,37 @@ And add the gem to your Gemfile:
14
19
 
15
20
  ## Usage
16
21
 
22
+ ```ruby
23
+ # Load a file
24
+ demo_object = Demoman.from_file("test/test.dem")
17
25
 
18
- # Load a file
19
- demo_object = Demoman.from_file("test/test.dem")
20
-
21
- # OR Load from a string
22
- demo_object = Demoman.from_string("##DEMO_DATA##")
26
+ # OR Load from a string
27
+ demo_object = Demoman.from_string("##DEMO_DATA##")
23
28
 
24
29
 
25
- # Server IP Address
26
- puts demo_object.server_address
30
+ # Server IP Address
31
+ puts demo_object.server_address
27
32
 
28
33
 
29
- # Player who recorded the demo
30
- puts demo_object.player_name
34
+ # Player who recorded the demo
35
+ puts demo_object.player_name
31
36
 
32
- # The map being played
33
- puts demo_object.map
37
+ # The map being played
38
+ puts demo_object.map
34
39
 
35
- # The game directory (dod, tf2, ...)
36
- puts demo_object.game_dir
40
+ # The game directory (dod, tf2, ...)
41
+ puts demo_object.game_dir
37
42
 
38
- # The duration of the demo (in seconds)
39
- puts demo_object.duration
43
+ # The duration of the demo (in seconds)
44
+ puts demo_object.duration
40
45
 
41
- # The number of ticks in the demo
42
- puts demo_object.ticks
46
+ # The number of ticks in the demo
47
+ puts demo_object.ticks
43
48
 
44
- # The total number of frames
45
- puts demo_object.frames
49
+ # The total number of frames
50
+ puts demo_object.frames
51
+ ```
46
52
 
47
- </pre>
48
53
 
49
54
 
50
55
  ## Note on Patches/Pull Requests
@@ -57,6 +62,10 @@ And add the gem to your Gemfile:
57
62
  (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
58
63
  * Send me a pull request. Bonus points for topic branches.
59
64
 
65
+ ## License
66
+
67
+ GPLv3
68
+
60
69
  ## Copyright
61
70
 
62
- Copyright (c) 2012 Mitch Dempsey. See LICENSE for details.
71
+ Copyright (c) 2013 Mitch Dempsey. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,11 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
2
3
 
3
- require 'rake/testtask'
4
-
5
- Rake::TestTask.new do |t|
6
- t.libs << 'lib/demoman'
7
- t.test_files = FileList['test/*_test.rb']
8
- t.verbose = true
9
- end
10
-
11
- task :default => :test
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/demoman.gemspec CHANGED
@@ -17,4 +17,10 @@ Gem::Specification.new do |gem|
17
17
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
19
  gem.require_paths = ["lib"]
20
+
21
+ gem.add_development_dependency "bundler", "~> 1.3"
22
+ gem.add_development_dependency "rake"
23
+ gem.add_development_dependency "rspec", ">= 2.14"
24
+ gem.add_development_dependency "simplecov"
25
+ gem.add_development_dependency "coveralls"
20
26
  end
@@ -1,36 +1,144 @@
1
1
  module Demoman
2
2
 
3
+ # Parses and provides data about a Half life demo file.
4
+ #
5
+ # @see https://developer.valvesoftware.com/wiki/DEM_Format
3
6
  class DemoFile
4
7
 
5
- attr_reader :server_address, :player_name, :map, :game_dir, :demo_protocol, :network_protocol, :type, :duration, :ticks, :frames, :sign_on_length
6
-
8
+
9
+ # If recorded by a client, then this will be the +IPAddress:Port+ of
10
+ # the server.
11
+ #
12
+ # If recorded by SourceTV then this will be the hostname of the server.
13
+ #
14
+ # @return [String]
15
+ attr_reader :server_address
16
+
17
+ # The name of the player recording the demo.
18
+ #
19
+ # If recorded by SourceTV it will be the name of the SourceTV player.
20
+ #
21
+ # @return [String]
22
+ attr_reader :player_name
23
+
24
+ # The current map on the server
25
+ #
26
+ # @return [String]
27
+ attr_reader :map
28
+
29
+ # The game directory as reported by the server.
30
+ # Examples: +tf+, +dod+, etc.
31
+ #
32
+ # @return [String]
33
+ attr_reader :game_dir
34
+
35
+ # This is the demo protocol version.
36
+ # This is almost always +3+
37
+ #
38
+ # @return [Integer]
39
+ attr_reader :demo_protocol
40
+
41
+ # This is the network protocol, which varies by game.
42
+ #
43
+ # @return [Integer]
44
+ attr_reader :network_protocol
45
+
46
+ # The type of demo. This is usually +HL2DEMO+
47
+ #
48
+ # @return [String]
49
+ attr_reader :type
50
+
51
+ # This is the duration of the demo, in seconds.
52
+ #
53
+ # @return [Float]
54
+ attr_reader :duration
55
+
56
+ # This is the number of server ticks that occurred.
57
+ # This is roughly the tick rate of the server multiplied by the duration.
58
+ #
59
+ # @return [Integer]
60
+ attr_reader :ticks
61
+
62
+ # The number of frames in the demo
63
+ #
64
+ # @return [Integer]
65
+ attr_reader :frames
66
+
67
+ # Length of the signon data (Init for first frame)
68
+ #
69
+ # @return [Integer]
70
+ attr_reader :sign_on_length
71
+
72
+ # Initialize a {DemoFile} object.
73
+ # If the +file+ parameter is provided, then the file is read and parsed.
74
+ #
75
+ # @param file [String] path to a demo file
7
76
  def initialize(file=nil)
8
-
77
+ @demodata = nil
9
78
  unless file.nil?
10
79
  io = File.new(file, "r")
11
80
  data = io.sysread(4096)
12
81
  parse_data data
13
82
  end
14
-
83
+
15
84
  end
16
85
 
86
+ # Parses the demo file header.
87
+ #
88
+ # @param data [String] the raw demo file header data.
89
+ #
90
+ # @return [void]
17
91
  def parse_data(data)
18
- demodata = data.unpack("A8/I/I/A260/A260/A260/A260/f/I/I/I/")
19
- @type = demodata[0]
20
- @demo_protocol = demodata[1]
21
- @network_protocol = demodata[2]
22
- @server_address = demodata[3]
23
- @player_name = demodata[4]
24
- @map = demodata[5]
25
- @game_dir = demodata[6]
92
+ @demodata = nil
93
+ # 0 1 2 3 4 5 6 7 8 9 10
94
+ @demodata = data.unpack("A8/I/I/A260/A260/A260/A260/f/I/I/I/")
95
+ @type = @demodata[0]
96
+ @demo_protocol = @demodata[1]
97
+ @network_protocol = @demodata[2]
98
+ @server_address = @demodata[3]
99
+ @player_name = @demodata[4]
100
+ @map = @demodata[5]
101
+ @game_dir = @demodata[6]
102
+
103
+ @duration = @demodata[7]
104
+ @ticks = @demodata[8]
105
+ @frames = @demodata[9]
106
+ @sign_on_length = @demodata[10]
26
107
 
27
- @duration = demodata[7]
28
- @ticks = demodata[8]
29
- @frames = demodata[9]
30
- @sign_on_length = demodata[10]
31
- nil
108
+ return self
109
+ end
110
+
111
+
112
+ # Returns if the demo has been parsed.
113
+ # *Note:* This does not check if the demo was valid.
114
+ #
115
+ # @see #valid?
116
+ #
117
+ # @since 2.0.2
118
+ #
119
+ # @return [Boolean] true
120
+ def parsed?
121
+ !@demodata.nil?
122
+ end
123
+
124
+ # Returns whether or not the parsed demo is considered valid.
125
+ #
126
+ # *Note:* This is a somewhat _educated_ guess. As long as the
127
+ # values appear to be within a specific range, then the demo
128
+ # is assumed to be valid.
129
+ #
130
+ # @since 2.0.2
131
+ #
132
+ # @return [Boolean]
133
+ def valid?
134
+ return false unless self.parsed?
135
+
136
+ return false unless @demodata.compact.size == 11
137
+
138
+ return false unless @type.eql?('HL2DEMO')
139
+
140
+ true
32
141
  end
33
-
34
142
 
35
143
  end
36
144
 
@@ -1,3 +1,5 @@
1
1
  module Demoman
2
- VERSION = "2.0.1"
2
+
3
+ # The current version of the +demoman+ gem.
4
+ VERSION = "2.0.2"
3
5
  end
data/lib/demoman.rb CHANGED
@@ -1,21 +1,32 @@
1
1
  require "demoman/version"
2
2
  require "demoman/demo_file"
3
3
 
4
+ # Handles static creation of {DemoFile} objects
4
5
  module Demoman
5
-
6
6
 
7
+
8
+ # Create a {DemoFile} object from a file path
9
+ #
10
+ # @param file [String] the path to the +.dem+ file.
11
+ #
12
+ # @return [DemoFile]
7
13
  def self.from_file(file)
8
14
  io = File.new(file, "r")
9
15
  data = io.sysread(4096)
10
-
16
+
11
17
  Demoman.from_string(data)
12
18
  end
13
-
19
+
20
+ # Create a {DemoFile} object from a raw string
21
+ #
22
+ # @param data [String] the raw demo file data
23
+ #
24
+ # @return [DemoFile]
14
25
  def self.from_string(data)
15
26
  demo = DemoFile.new
16
27
  demo.parse_data(data)
17
28
  demo
18
29
  end
19
-
20
-
30
+
31
+
21
32
  end
File without changes
File without changes
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ describe Demoman do
4
+ it "read demo" do
5
+ demoman = Demoman::DemoFile.new("spec/data/test.dem")
6
+
7
+ demoman.server_address.should eq("69.90.189.79:27037")
8
+ demoman.player_name.should eq("Ham Salad[AOF]")
9
+ demoman.map.should eq("dod_jagd")
10
+ demoman.game_dir.should eq("dod")
11
+ demoman.demo_protocol.should eq(3)
12
+ demoman.network_protocol.should eq(7)
13
+ demoman.type.should eq("HL2DEMO")
14
+ demoman.duration.should eq(13.242424964904785)
15
+ demoman.ticks.should eq(874)
16
+ demoman.frames.should eq(390)
17
+ demoman.sign_on_length.should eq(115449)
18
+
19
+ demoman.valid?.should be_true
20
+
21
+ end
22
+
23
+ it "new style load demo" do
24
+
25
+ demoman = Demoman.from_file("spec/data/test.dem")
26
+
27
+ demoman.server_address.should eq("69.90.189.79:27037")
28
+ demoman.player_name.should eq("Ham Salad[AOF]")
29
+ demoman.map.should eq("dod_jagd")
30
+ demoman.game_dir.should eq("dod")
31
+ demoman.demo_protocol.should eq(3)
32
+ demoman.network_protocol.should eq(7)
33
+
34
+ demoman.ticks.should eq(874)
35
+ demoman.frames.should eq(390)
36
+ demoman.sign_on_length.should eq(115449)
37
+
38
+ demoman.valid?.should be_true
39
+ end
40
+
41
+ it "read from string" do
42
+ io = File.new("spec/data/test.dem", "r")
43
+ data = io.sysread(4096)
44
+
45
+ demoman = Demoman.from_string(data)
46
+
47
+ demoman.server_address.should eq("69.90.189.79:27037")
48
+ demoman.player_name.should eq("Ham Salad[AOF]")
49
+ demoman.map.should eq("dod_jagd")
50
+ demoman.game_dir.should eq("dod")
51
+ demoman.demo_protocol.should eq(3)
52
+ demoman.network_protocol.should eq(7)
53
+
54
+ demoman.ticks.should eq(874)
55
+ demoman.frames.should eq(390)
56
+ demoman.sign_on_length.should eq(115449)
57
+
58
+ demoman.valid?.should be_true
59
+
60
+ end
61
+
62
+ it "loads a SourceTV demo" do
63
+
64
+ demoman = Demoman.from_file("spec/data/sourcetv.dem")
65
+
66
+ demoman.server_address.should eq("WebDestroya's Stomping Grounds | MitchDB.com")
67
+ demoman.player_name.should eq("SourceTV Demo")
68
+ demoman.map.should eq("ctf_well")
69
+ demoman.game_dir.should eq("tf")
70
+ demoman.network_protocol.should eq(24)
71
+ demoman.valid?.should be_true
72
+ end
73
+
74
+ it 'loads jibberish' do
75
+ demoman = Demoman.from_string("asdasdasdasdasdasdaasdasdasdass")
76
+ demoman.parsed?.should be_true
77
+ demoman.valid?.should be_false
78
+
79
+ puts demoman.inspect
80
+ end
81
+
82
+ end
@@ -0,0 +1,9 @@
1
+ require "simplecov"
2
+ require "coveralls"
3
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
4
+ SimpleCov::Formatter::HTMLFormatter,
5
+ Coveralls::SimpleCov::Formatter
6
+ ]
7
+ SimpleCov.start { add_filter "/spec/" }
8
+
9
+ require "demoman"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: demoman
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,88 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-27 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-09-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '2.14'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '2.14'
62
+ - !ruby/object:Gem::Dependency
63
+ name: simplecov
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: coveralls
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
14
94
  description: Library for reading metadata from Half-Life demo files
15
95
  email:
16
96
  - mrdempsey@gmail.com
@@ -20,6 +100,7 @@ extra_rdoc_files: []
20
100
  files:
21
101
  - .document
22
102
  - .gitignore
103
+ - .travis.yml
23
104
  - Gemfile
24
105
  - LICENSE
25
106
  - README.md
@@ -28,10 +109,10 @@ files:
28
109
  - lib/demoman.rb
29
110
  - lib/demoman/demo_file.rb
30
111
  - lib/demoman/version.rb
31
- - test/data/sourcetv.dem
32
- - test/data/test.dem
33
- - test/demoman_test.rb
34
- - test/test_helper.rb
112
+ - spec/data/sourcetv.dem
113
+ - spec/data/test.dem
114
+ - spec/demoman/demoman_spec.rb
115
+ - spec/spec_helper.rb
35
116
  homepage: http://www.mitchdb.com/
36
117
  licenses:
37
118
  - GPL-3
@@ -47,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
47
128
  version: '0'
48
129
  segments:
49
130
  - 0
50
- hash: -983082405090195856
131
+ hash: 4451018120548773554
51
132
  required_rubygems_version: !ruby/object:Gem::Requirement
52
133
  none: false
53
134
  requirements:
@@ -56,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
56
137
  version: '0'
57
138
  segments:
58
139
  - 0
59
- hash: -983082405090195856
140
+ hash: 4451018120548773554
60
141
  requirements: []
61
142
  rubyforge_project:
62
143
  rubygems_version: 1.8.23
@@ -64,7 +145,7 @@ signing_key:
64
145
  specification_version: 3
65
146
  summary: Library for reading metadata from Half-Life demo files
66
147
  test_files:
67
- - test/data/sourcetv.dem
68
- - test/data/test.dem
69
- - test/demoman_test.rb
70
- - test/test_helper.rb
148
+ - spec/data/sourcetv.dem
149
+ - spec/data/test.dem
150
+ - spec/demoman/demoman_spec.rb
151
+ - spec/spec_helper.rb
data/test/demoman_test.rb DELETED
@@ -1,67 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- describe Demoman do
4
- it "read demo" do
5
- demoman = Demoman::DemoFile.new("test/data/test.dem")
6
-
7
- assert_equal "69.90.189.79:27037", demoman.server_address
8
- assert_equal "Ham Salad[AOF]", demoman.player_name
9
- assert_equal "dod_jagd", demoman.map
10
- assert_equal "dod", demoman.game_dir
11
- assert_equal 3, demoman.demo_protocol
12
- assert_equal 7, demoman.network_protocol
13
-
14
- assert_equal 874, demoman.ticks
15
- assert_equal 390, demoman.frames
16
- assert_equal 115449, demoman.sign_on_length
17
-
18
- #["HL2DEMO", 3, 7, "69.90.189.79:27037", "Ham Salad[AOF]", "dod_jagd", "dod", 13.2424249649048, 874, 390, 115449]
19
-
20
- end
21
-
22
- it "new style load demo" do
23
-
24
- demoman = Demoman.from_file("test/data/test.dem")
25
-
26
- assert_equal "69.90.189.79:27037", demoman.server_address
27
- assert_equal "Ham Salad[AOF]", demoman.player_name
28
- assert_equal "dod_jagd", demoman.map
29
- assert_equal "dod", demoman.game_dir
30
- assert_equal 3, demoman.demo_protocol
31
- assert_equal 7, demoman.network_protocol
32
-
33
- assert_equal 874, demoman.ticks
34
- assert_equal 390, demoman.frames
35
- assert_equal 115449, demoman.sign_on_length
36
- end
37
-
38
- it "read from string" do
39
- io = File.new("test/data/test.dem", "r")
40
- data = io.sysread(4096)
41
-
42
- demoman = Demoman.from_string(data)
43
-
44
- assert_equal "69.90.189.79:27037", demoman.server_address
45
- assert_equal "Ham Salad[AOF]", demoman.player_name
46
- assert_equal "dod_jagd", demoman.map
47
- assert_equal "dod", demoman.game_dir
48
- assert_equal 3, demoman.demo_protocol
49
- assert_equal 7, demoman.network_protocol
50
-
51
- assert_equal 874, demoman.ticks
52
- assert_equal 390, demoman.frames
53
- assert_equal 115449, demoman.sign_on_length
54
-
55
- end
56
-
57
- it "loads a SourceTV demo" do
58
-
59
- demoman = Demoman.from_file("test/data/sourcetv.dem")
60
-
61
- assert_equal "WebDestroya's Stomping Grounds | MitchDB.com", demoman.server_address
62
- assert_equal "SourceTV Demo", demoman.player_name
63
- assert_equal "ctf_well", demoman.map
64
- assert_equal "tf", demoman.game_dir
65
- end
66
-
67
- end
data/test/test_helper.rb DELETED
@@ -1,3 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'minitest/pride'
3
- require File.expand_path('../../lib/demoman.rb', __FILE__)