demo-reader 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/.gitignore +21 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +18 -0
  4. data/Rakefile +51 -0
  5. data/VERSION +1 -0
  6. data/demo-reader.gemspec +74 -0
  7. data/lib/demo-reader.rb +25 -0
  8. data/lib/demo_reader_warsow.rb +225 -0
  9. data/test/demo_reader_test.rb +10 -0
  10. data/test/demo_reader_warsow_wd10_race_test.rb +37 -0
  11. data/test/demo_reader_warsow_wd11_race_test.rb +31 -0
  12. data/test/fixtures/warsow/wd10/racesow_0.42.b2/dinirun2_racesow_0.42.b2.wd10 +0 -0
  13. data/test/fixtures/warsow/wd10/racesow_local/boris.wd10 +0 -0
  14. data/test/fixtures/warsow/wd10/racesow_local/die11.7.wd10 +0 -0
  15. data/test/fixtures/warsow/wd10/racesow_local/dvr_antr.wd10 +0 -0
  16. data/test/fixtures/warsow/wd10/racesow_local/e-lava.wd10 +0 -0
  17. data/test/fixtures/warsow/wd10/racesow_local/j4n12.8.wd10 +0 -0
  18. data/test/fixtures/warsow/wd10/racesow_local/terror.wd10 +0 -0
  19. data/test/fixtures/warsow/wd10/racesow_local/yescomp006-2.wd10 +0 -0
  20. data/test/fixtures/warsow/wd10/racesow_local/zugo.wd10 +0 -0
  21. data/test/fixtures/warsow/wd10/trouble_making/2.wd10 +0 -0
  22. data/test/fixtures/warsow/wd10/trouble_making/boris_cab1.wd10 +0 -0
  23. data/test/fixtures/warsow/wd10/trouble_making/very_short_demo.wd10 +0 -0
  24. data/test/fixtures/warsow/wd11/bomb_wbomb1_b2uberspot.wd11 +0 -0
  25. data/test/fixtures/warsow/wd11/race_bardok-lick-revamped_54.882.wd11 +0 -0
  26. data/test/fixtures/warsow/wd11/race_cwrace5.wd11 +0 -0
  27. data/test/fixtures/warsow/wd11/race_killua-hykon.wd11 +0 -0
  28. data/test/fixtures/warsow/wd11/race_st1_07.848.wd11 +0 -0
  29. data/test/fixtures/warsow/wd11/race_wdm16_unfinished.wd11 +0 -0
  30. data/test/fixtures/warsow/wd11/race_wrc03-3_28.684.wd11 +0 -0
  31. data/test/helper.rb +9 -0
  32. metadata +89 -0
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 aekym
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,18 @@
1
+ = demo-reader
2
+
3
+ A library to parse warsow demo files
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (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)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 aekym. See LICENSE for details.
18
+
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "demo-reader"
8
+ gem.summary = %Q{A library to read warsow and defrag demo files}
9
+ gem.description = %Q{A library to read warsow and defrag demo files}
10
+ gem.email = "me@aekym.com"
11
+ gem.homepage = "http://github.com/aekym/demo-reader"
12
+ gem.authors = ["aekym"]
13
+ end
14
+ Jeweler::GemcutterTasks.new
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
37
+ end
38
+
39
+ task :test => :check_dependencies
40
+
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
46
+
47
+ rdoc.rdoc_dir = 'rdoc'
48
+ rdoc.title = "demo-reader #{version}"
49
+ rdoc.rdoc_files.include('README*')
50
+ rdoc.rdoc_files.include('lib/**/*.rb')
51
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,74 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{demo-reader}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["aekym"]
12
+ s.date = %q{2010-01-16}
13
+ s.description = %q{A library to read warsow and defrag demo files}
14
+ s.email = %q{me@aekym.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "demo-reader.gemspec",
26
+ "lib/demo-reader.rb",
27
+ "lib/demo_reader_warsow.rb",
28
+ "test/demo_reader_test.rb",
29
+ "test/demo_reader_warsow_wd10_race_test.rb",
30
+ "test/demo_reader_warsow_wd11_race_test.rb",
31
+ "test/fixtures/warsow/wd10/racesow_0.42.b2/dinirun2_racesow_0.42.b2.wd10",
32
+ "test/fixtures/warsow/wd10/racesow_local/boris.wd10",
33
+ "test/fixtures/warsow/wd10/racesow_local/die11.7.wd10",
34
+ "test/fixtures/warsow/wd10/racesow_local/dvr_antr.wd10",
35
+ "test/fixtures/warsow/wd10/racesow_local/e-lava.wd10",
36
+ "test/fixtures/warsow/wd10/racesow_local/j4n12.8.wd10",
37
+ "test/fixtures/warsow/wd10/racesow_local/terror.wd10",
38
+ "test/fixtures/warsow/wd10/racesow_local/yescomp006-2.wd10",
39
+ "test/fixtures/warsow/wd10/racesow_local/zugo.wd10",
40
+ "test/fixtures/warsow/wd10/trouble_making/2.wd10",
41
+ "test/fixtures/warsow/wd10/trouble_making/boris_cab1.wd10",
42
+ "test/fixtures/warsow/wd10/trouble_making/very_short_demo.wd10",
43
+ "test/fixtures/warsow/wd11/bomb_wbomb1_b2uberspot.wd11",
44
+ "test/fixtures/warsow/wd11/race_bardok-lick-revamped_54.882.wd11",
45
+ "test/fixtures/warsow/wd11/race_cwrace5.wd11",
46
+ "test/fixtures/warsow/wd11/race_killua-hykon.wd11",
47
+ "test/fixtures/warsow/wd11/race_st1_07.848.wd11",
48
+ "test/fixtures/warsow/wd11/race_wdm16_unfinished.wd11",
49
+ "test/fixtures/warsow/wd11/race_wrc03-3_28.684.wd11",
50
+ "test/helper.rb"
51
+ ]
52
+ s.homepage = %q{http://github.com/aekym/demo-reader}
53
+ s.rdoc_options = ["--charset=UTF-8"]
54
+ s.require_paths = ["lib"]
55
+ s.rubygems_version = %q{1.3.5}
56
+ s.summary = %q{A library to read warsow and defrag demo files}
57
+ s.test_files = [
58
+ "test/demo_reader_test.rb",
59
+ "test/demo_reader_warsow_wd10_race_test.rb",
60
+ "test/demo_reader_warsow_wd11_race_test.rb",
61
+ "test/helper.rb"
62
+ ]
63
+
64
+ if s.respond_to? :specification_version then
65
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
+ s.specification_version = 3
67
+
68
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
69
+ else
70
+ end
71
+ else
72
+ end
73
+ end
74
+
@@ -0,0 +1,25 @@
1
+ require "demo_reader_warsow"
2
+
3
+
4
+ class DemoReader
5
+
6
+
7
+ # tries to parse the given demo file in order to detect a warsow demo
8
+ #
9
+ # @returns an instance of DemoReaderWarsow or nil on failure
10
+ #
11
+ def self.parse(filename)
12
+ try_warsow(filename)
13
+ end
14
+
15
+
16
+ protected
17
+
18
+ def self.try_warsow(filename)
19
+ demo = DemoReaderWarsow.new(filename)
20
+
21
+ demo.valid ? demo : nil
22
+ end
23
+
24
+ end
25
+
@@ -0,0 +1,225 @@
1
+ class DemoReaderWarsow
2
+ attr_reader :filename, :version, :mapname, :time, :playernames, :scoreboards, :gamemode, :player, :basegamedir, :gamedir, :valid
3
+
4
+
5
+ def initialize(filename)
6
+ @filename = filename
7
+ @version = -1
8
+ @mapname = nil
9
+ @time = nil
10
+ @time_in_msec = nil
11
+ @playernames = []
12
+ @scoreboards = []
13
+ @gamemode = nil
14
+ @player = nil
15
+ @basegamedir = nil
16
+ @gamedir = nil
17
+ @valid = false
18
+
19
+ self.init()
20
+ end
21
+
22
+
23
+
24
+ def init
25
+ file = File.new(@filename, 'r')
26
+
27
+ return if file.stat.size < 10
28
+
29
+ @version = detect_version(file)
30
+
31
+ # just support some wd* file versions
32
+ return unless [8, 9, 10, 11].include? @version
33
+
34
+ # skip 4 bytes "svs.spawncount"
35
+ file.pos += 4
36
+
37
+ # skip 2 bytes "cl.snapFrameTime"
38
+ file.pos += 2 if [10, 11].include? @version
39
+
40
+ # skip 4 bytes "cl.baseServerTime"
41
+ file.pos += 4 if @version == 10
42
+
43
+
44
+ # FS_BaseGameDirectory
45
+ @basegamedir = file.gets("\0").chop
46
+
47
+ # FS_GameDirectory
48
+ @gamedir = file.gets("\0").chop
49
+
50
+ # skip short "playernum"
51
+ file.pos += 2
52
+
53
+
54
+ # mapname
55
+ @mapname = file.gets("\0").chop.downcase
56
+
57
+ content = file.gets nil
58
+ file.close
59
+
60
+
61
+
62
+
63
+ # detect scoreboard
64
+
65
+ regex = /scb \"([^\"]+)/
66
+ matchdata = regex.match(content)
67
+
68
+ while matchdata
69
+ @scoreboards.push matchdata[1]
70
+ matchdata = regex.match(matchdata.post_match)
71
+ end
72
+
73
+
74
+
75
+ # detect game mode
76
+
77
+ if @version == 11
78
+ @gamemode = gamemode_wd11(content)
79
+ else
80
+ regex = /&([^ ]+) /
81
+
82
+ gamemodes = []
83
+ @scoreboards.each do |scb|
84
+ matchdata = regex.match(scb)
85
+ gamemodes.push matchdata[1]
86
+ end
87
+ gamemodes.uniq!
88
+ if gamemodes.length.zero?
89
+ @gamemode = 'unknown'
90
+ else
91
+ if gamemodes.length == 1
92
+ @gamemode = gamemodes.first
93
+ @gamemode.chop! if ['races', 'dms', 'ctfs'].include? @gamemode
94
+ else
95
+ @gamemode = "multiple gamemodes found: #{gamemodes.join(', ')}!"
96
+ end
97
+ end
98
+ end
99
+
100
+
101
+
102
+ # detect time by sent message string with time from server
103
+ if ['race', 'unknown'].include?(@gamemode)
104
+ matches = []
105
+ regex = /(server record|race finished)(?:!.*(?:current|times\^7 ))?: (\d+):(\d+)\.(\d+)/im
106
+ matchdata = regex.match(content)
107
+
108
+ while matchdata
109
+ matches.push("%02d:%02d.%03d" % [$2,$3,$4].map(&:to_i))
110
+ matchdata = regex.match(matchdata.post_match)
111
+ end
112
+
113
+ if matches.length > 0
114
+ @time = matches.sort.first
115
+ @gamemode = 'race' if @gamemode == 'unknown'
116
+ end
117
+ end
118
+
119
+
120
+
121
+ #detect all player names
122
+ matches = []
123
+ regex = /cs ([0-9]+) \"\\name\\([^\0]*)\\hand/
124
+ rest_content = content
125
+ matchdata = regex.match(rest_content)
126
+ first_no = matchdata[1].to_i
127
+
128
+ while matchdata
129
+ # damit werden doppelte eintraege durch den letzten aktuellen ueberschrieben
130
+ matches[matchdata[1].to_i - first_no] = matchdata[2]
131
+ rest_content = matchdata.post_match
132
+ matchdata = regex.match(rest_content)
133
+ end
134
+
135
+ if matches.length > 0
136
+ # save player names only
137
+ @playernames = []
138
+ matches.each_with_index { |player, number|
139
+ #playernames.push [number, player].join(': ')
140
+ @playernames[number] = player
141
+ }
142
+ end
143
+
144
+
145
+
146
+ # detect player
147
+
148
+ playernames = @playernames.compact.sort.uniq
149
+ if playernames.length == 1
150
+ @player = playernames.first
151
+ else
152
+ if @time && @gamemode == 'race' && !@scoreboards.empty? && !playernames.empty?
153
+ min, sec, msec = @time.scan(/^([0-9]+):([0-9]+)\.([0-9]+)$/).flatten.map { |x| x.to_i }
154
+ min = 9 if min > 9 # scoreboard does not support race times > 9:55:999; max minute value is 9 !
155
+ t = "#{min}#{sec}#{msec}"
156
+ regex = Regexp.new("&p ([0-9]+) #{t}")
157
+ playerids = @scoreboards.join('').scan(regex).flatten.uniq
158
+ if playerids.length == 1
159
+ @player = @playernames[playerids.first.to_i]
160
+ end
161
+ end
162
+ end
163
+
164
+ @valid = true
165
+ end
166
+
167
+
168
+
169
+ def detect_version(file)
170
+ # try to detect version 8, 9 or 10
171
+ #
172
+ file.pos = 0
173
+
174
+ file.pos += 4 # skip 4 byte message length
175
+ file.pos += 1 # skip 1 byte "svc_serverdata"
176
+
177
+ # version
178
+ # reads 4 bytes and decodes the little-endian format
179
+ version = file.read(4).unpack('V')[0]
180
+
181
+ return version if [8, 9, 10].include? version
182
+
183
+
184
+ # try to detect version 11
185
+ #
186
+ file.pos = 0
187
+
188
+ file.pos += 1 # skip 1 byte "svc_demoinfo"
189
+
190
+ file.pos += 4 # skip 4 byte "initial server time"
191
+ file.pos += 4 # skip 4 byte "demo duration in milliseconds"
192
+ file.pos += 4 # skip 4 byte "file offset at which the final -1 was written"
193
+
194
+ file.pos += 1 # skip 1 byte "svc_serverdata"
195
+
196
+ file.pos += 4 # skip 4 byte "UNKNOWN! - not documented in source, but is needed to fit demos!"
197
+
198
+ # version
199
+ # reads 4 bytes and decodes the little-endian format
200
+ version = file.read(4).unpack('V')[0]
201
+
202
+ return version if version == 11
203
+
204
+ nil # could not detect any known version
205
+ end
206
+
207
+
208
+ def time_in_msec
209
+ return @time_in_msec unless @time_in_msec.nil?
210
+
211
+ # time str to int
212
+ if @time.kind_of? String
213
+ min, sec, msec = @time.scan(/^([0-9]+):([0-9]+)\.([0-9]+)$/).flatten.map { |x| x.to_i }
214
+ @time_in_msec = msec + sec * 1000 + min * 60 * 1000
215
+ end
216
+ end
217
+
218
+
219
+ def gamemode_wd11(file_content)
220
+ if file_content =~ /cs 12 "(.*?)"/
221
+ $1
222
+ end
223
+ end
224
+ end
225
+
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class DemoReaderTest < Test::Unit::TestCase
4
+
5
+ def test_interface
6
+ assert DemoReader.respond_to?(:parse)
7
+ end
8
+
9
+ end
10
+
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class DemoReaderWarsowWd10RaceTest < Test::Unit::TestCase
4
+
5
+ version = 10
6
+
7
+ [
8
+ %w(racesow_0.42.b2/dinirun2_racesow_0.42.b2 dinirun2 00:21.870),
9
+ %w(racesow_local/boris boris_75m 00:16.336),
10
+ %w(racesow_local/die11.7 die 00:11.737),
11
+ %w(racesow_local/dvr_antr dvr_antr 00:09.485),
12
+ %w(racesow_local/e-lava e-lavastore 00:06.313),
13
+ %w(racesow_local/j4n12.8 j4n_wtf 00:12.814),
14
+ %w(racesow_local/terror terror-box 00:18.553),
15
+ %w(racesow_local/yescomp006-2 un-dead!020_4 00:14.971),
16
+ %w(racesow_local/zugo zugo 00:14.894),
17
+ %w(trouble_making/2 gu3#8-bomb 00:12.834),
18
+ %w(trouble_making/boris_cab1 boris_cab1 16:34.514),
19
+ %w(trouble_making/very_short_demo gu3-bored 00:02.748)
20
+ ].each do |entry|
21
+
22
+ file, map, time = entry
23
+
24
+ define_method "test_warsow_wd#{version}_demo_#{file.gsub(/[^a-z_0-9]/, "_")}" do
25
+ demo = DemoReader.parse("test/fixtures/warsow/wd#{version}/#{file}.wd#{version}")
26
+
27
+ assert demo.valid
28
+ assert_equal "race", demo.gamemode
29
+ assert_equal version, demo.version
30
+ assert_equal map, demo.mapname
31
+ assert_equal time, demo.time
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+
@@ -0,0 +1,31 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class DemoReaderWarsowWd11RaceTest < Test::Unit::TestCase
4
+
5
+ version = 11
6
+
7
+ [
8
+ %w(race_cwrace5 cwrace5),
9
+ %w(race_killua-hykon killua-hykon),
10
+ %w(race_st1_07.848 st1 00:07.848),
11
+ %w(race_wdm16_unfinished wdm16),
12
+ %w(race_bardok-lick-revamped_54.882 bardok-lick-revamped 00:54.882),
13
+ %w(race_wrc03-3_28.684 wrc03-3 00:28.684)
14
+ ].each do |entry|
15
+
16
+ file, map, time = entry
17
+
18
+ define_method "test_warsow_wd#{version}_demo_#{file.gsub(/[^a-z_0-9]/, "_")}" do
19
+ demo = DemoReader.parse("test/fixtures/warsow/wd#{version}/#{file}.wd#{version}")
20
+
21
+ assert demo.valid
22
+ assert_equal "race", demo.gamemode
23
+ assert_equal version, demo.version
24
+ assert_equal map, demo.mapname
25
+ assert_equal time, demo.time if time
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
data/test/helper.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'demo-reader'
7
+
8
+ class Test::Unit::TestCase
9
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: demo-reader
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - aekym
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-16 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A library to read warsow and defrag demo files
17
+ email: me@aekym.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - .gitignore
27
+ - LICENSE
28
+ - README.rdoc
29
+ - Rakefile
30
+ - VERSION
31
+ - demo-reader.gemspec
32
+ - lib/demo-reader.rb
33
+ - lib/demo_reader_warsow.rb
34
+ - test/demo_reader_test.rb
35
+ - test/demo_reader_warsow_wd10_race_test.rb
36
+ - test/demo_reader_warsow_wd11_race_test.rb
37
+ - test/fixtures/warsow/wd10/racesow_0.42.b2/dinirun2_racesow_0.42.b2.wd10
38
+ - test/fixtures/warsow/wd10/racesow_local/boris.wd10
39
+ - test/fixtures/warsow/wd10/racesow_local/die11.7.wd10
40
+ - test/fixtures/warsow/wd10/racesow_local/dvr_antr.wd10
41
+ - test/fixtures/warsow/wd10/racesow_local/e-lava.wd10
42
+ - test/fixtures/warsow/wd10/racesow_local/j4n12.8.wd10
43
+ - test/fixtures/warsow/wd10/racesow_local/terror.wd10
44
+ - test/fixtures/warsow/wd10/racesow_local/yescomp006-2.wd10
45
+ - test/fixtures/warsow/wd10/racesow_local/zugo.wd10
46
+ - test/fixtures/warsow/wd10/trouble_making/2.wd10
47
+ - test/fixtures/warsow/wd10/trouble_making/boris_cab1.wd10
48
+ - test/fixtures/warsow/wd10/trouble_making/very_short_demo.wd10
49
+ - test/fixtures/warsow/wd11/bomb_wbomb1_b2uberspot.wd11
50
+ - test/fixtures/warsow/wd11/race_bardok-lick-revamped_54.882.wd11
51
+ - test/fixtures/warsow/wd11/race_cwrace5.wd11
52
+ - test/fixtures/warsow/wd11/race_killua-hykon.wd11
53
+ - test/fixtures/warsow/wd11/race_st1_07.848.wd11
54
+ - test/fixtures/warsow/wd11/race_wdm16_unfinished.wd11
55
+ - test/fixtures/warsow/wd11/race_wrc03-3_28.684.wd11
56
+ - test/helper.rb
57
+ has_rdoc: true
58
+ homepage: http://github.com/aekym/demo-reader
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --charset=UTF-8
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ requirements: []
79
+
80
+ rubyforge_project:
81
+ rubygems_version: 1.3.5
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: A library to read warsow and defrag demo files
85
+ test_files:
86
+ - test/demo_reader_test.rb
87
+ - test/demo_reader_warsow_wd10_race_test.rb
88
+ - test/demo_reader_warsow_wd11_race_test.rb
89
+ - test/helper.rb