demo-reader 0.0.2 → 0.1.0
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/.gitignore +4 -0
- data/README.rdoc +1 -1
- data/Rakefile +3 -2
- data/VERSION +1 -1
- data/demo-reader.gemspec +30 -7
- data/ext/dm68/README.txt +14 -0
- data/ext/dm68/common.c +797 -0
- data/ext/dm68/common.h +568 -0
- data/ext/dm68/dm68.c +57 -0
- data/ext/dm68/dump.c +196 -0
- data/ext/dm68/extconf.rb +16 -0
- data/ext/dm68/huff.c +542 -0
- data/ext/dm68/huff.h +34 -0
- data/ext/dm68/main.c +175 -0
- data/ext/dm68/main.h +126 -0
- data/ext/dm68/msg.c +1082 -0
- data/ext/dm68/msg.h +114 -0
- data/ext/dm68/parse.c +393 -0
- data/lib/demo-reader.rb +11 -3
- data/lib/demo_reader_defrag.rb +106 -0
- data/lib/demo_reader_warsow.rb +3 -5
- data/test/demo_reader_defrag_dm_68_cpm_test.rb +29 -0
- data/test/demo_reader_defrag_dm_68_vq3_test.rb +29 -0
- data/test/fixtures/defrag/dm_68/cpm/pornchronostar_mdf.cpm_00.49.216_tyaz.germany.dm_68 +0 -0
- data/test/fixtures/defrag/dm_68/cpm/puremotion_df.cpm_00.10.600_eS-Rody.russia.dm_68 +0 -0
- data/test/fixtures/defrag/dm_68/vq3/runkull2_df.vq3_01.05.904_XunderBIRD.Germany.dm_68 +0 -0
- data/test/fixtures/defrag/dm_68/vq3/un-dead029_df.vq3_00.16.912_uN-DeaD!WiNTeR.ru.dm_68 +0 -0
- metadata +43 -9
data/lib/demo-reader.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
require "demo_reader_warsow"
|
2
|
+
require "demo_reader_defrag"
|
2
3
|
|
3
4
|
|
4
5
|
class DemoReader
|
5
6
|
|
6
7
|
|
7
|
-
# tries to parse the given demo file in order to detect a warsow
|
8
|
+
# tries to parse the given demo file in order to detect first a warsow,
|
9
|
+
# then a defrag demo
|
8
10
|
#
|
9
|
-
# @returns an instance of DemoReaderWarsow or nil on failure
|
11
|
+
# @returns an instance of DemoReaderWarsow or DemoReaderDefrag or nil on failure
|
10
12
|
#
|
11
13
|
def self.parse(filename)
|
12
|
-
try_warsow(filename)
|
14
|
+
try_warsow(filename) || try_defrag(filename)
|
13
15
|
end
|
14
16
|
|
15
17
|
|
@@ -21,5 +23,11 @@ class DemoReader
|
|
21
23
|
demo.valid ? demo : nil
|
22
24
|
end
|
23
25
|
|
26
|
+
def self.try_defrag(filename)
|
27
|
+
demo = DemoReaderDefrag.new(filename)
|
28
|
+
|
29
|
+
demo.valid ? demo : nil
|
30
|
+
end
|
31
|
+
|
24
32
|
end
|
25
33
|
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'ext/dm68/dm68'
|
3
|
+
|
4
|
+
class DemoReaderDefrag
|
5
|
+
attr_reader :filename, :version, :mapname, :time, :playernames, :scoreboards, :gamemode, :player, :basegamedir, :gamedir, :valid
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
def initialize(filename)
|
10
|
+
@filename = filename
|
11
|
+
|
12
|
+
@version = -1
|
13
|
+
@mapname = nil
|
14
|
+
@time = nil
|
15
|
+
@time_in_msec = nil
|
16
|
+
@playernames = []
|
17
|
+
@scoreboards = []
|
18
|
+
@gamemode = nil
|
19
|
+
@player = nil
|
20
|
+
@basegamedir = nil
|
21
|
+
@gamedir = nil
|
22
|
+
@valid = false
|
23
|
+
@raw = nil
|
24
|
+
|
25
|
+
self.init()
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
def init
|
31
|
+
out = DM68.parse_file(@filename)
|
32
|
+
@raw = YAML.load(out)
|
33
|
+
|
34
|
+
raise out unless @raw
|
35
|
+
|
36
|
+
@version = @raw['server_info']['protocol'].to_i
|
37
|
+
@mapname = @raw['server_info']['mapname'].downcase
|
38
|
+
|
39
|
+
# @playernames = []
|
40
|
+
@scoreboards = @raw['prints']
|
41
|
+
@basegamedir = @raw['server_info']['gamename']
|
42
|
+
@gamedir = @raw['system_info']['fs_game']
|
43
|
+
|
44
|
+
if @raw['server_info']['defrag_vers'].to_i > 0
|
45
|
+
@gamemode = @raw['server_info']['df_promode'].to_i.zero? ? 'vq3' : 'cpm'
|
46
|
+
@time = extract_time(@raw['prints'])
|
47
|
+
@player = extract_player(@raw['prints'])
|
48
|
+
@playernames << @player # just support one player atm
|
49
|
+
end
|
50
|
+
|
51
|
+
@valid = true
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
def time_in_msec
|
57
|
+
return @time_in_msec unless @time_in_msec.nil?
|
58
|
+
|
59
|
+
# time str to int
|
60
|
+
if @time.kind_of? String
|
61
|
+
min, sec, msec = @time.scan(/^([0-9]+):([0-9]+)\.([0-9]+)$/).flatten.map { |x| x.to_i }
|
62
|
+
@time_in_msec = msec + sec * 1000 + min * 60 * 1000
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
protected
|
69
|
+
|
70
|
+
# extract player from server prints
|
71
|
+
# supports only one player atm otherwise raises an exception
|
72
|
+
#
|
73
|
+
def extract_player(prints)
|
74
|
+
players = prints.inject([]) do |arr,p|
|
75
|
+
arr << $1 if p =~ /^(.+)\^7 reached the finish line/
|
76
|
+
arr << $1 if p =~ /^Time performed by (.+)\^7 :/
|
77
|
+
arr
|
78
|
+
end
|
79
|
+
|
80
|
+
raise "Not only one player was found #{players.inspect}." if players.length != 1
|
81
|
+
|
82
|
+
players.first
|
83
|
+
end
|
84
|
+
|
85
|
+
# extract time from server prints
|
86
|
+
# supports only one time atm otherwise raises an exception
|
87
|
+
#
|
88
|
+
def extract_time(prints)
|
89
|
+
times = prints.inject([]) do |arr,p|
|
90
|
+
arr << $1 if p =~ /(\^[0-9]+:[\^:0-9]+)/
|
91
|
+
arr
|
92
|
+
end
|
93
|
+
|
94
|
+
raise "Not only one time was found #{times.inspect}." if times.length != 1
|
95
|
+
|
96
|
+
time = plain_text(times.first)
|
97
|
+
|
98
|
+
time = "0:#{time}" if time.count(":") < 2
|
99
|
+
"%02d:%02d.%03d" % time.split(":").map(&:to_i)
|
100
|
+
end
|
101
|
+
|
102
|
+
def plain_text(text)
|
103
|
+
text.gsub(/\^\d/, '')
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
data/lib/demo_reader_warsow.rb
CHANGED
@@ -61,7 +61,7 @@ class DemoReaderWarsow
|
|
61
61
|
|
62
62
|
|
63
63
|
# detect scoreboard
|
64
|
-
|
64
|
+
|
65
65
|
regex = /scb \"([^\"]+)/
|
66
66
|
matchdata = regex.match(content)
|
67
67
|
|
@@ -73,7 +73,7 @@ class DemoReaderWarsow
|
|
73
73
|
|
74
74
|
|
75
75
|
# detect game mode
|
76
|
-
|
76
|
+
|
77
77
|
if @version == 11
|
78
78
|
@gamemode = gamemode_wd11(content)
|
79
79
|
else
|
@@ -100,7 +100,6 @@ class DemoReaderWarsow
|
|
100
100
|
|
101
101
|
|
102
102
|
# detect time by sent message string with time from server
|
103
|
-
#
|
104
103
|
if ['race', 'unknown'].include?(@gamemode)
|
105
104
|
matches = []
|
106
105
|
regex = /(server record|race finished)(?:!.*(?:current|times\^7 ))?:[0-9:\. ]* (\d+):(\d+)\.(\d+)/im
|
@@ -120,7 +119,6 @@ class DemoReaderWarsow
|
|
120
119
|
|
121
120
|
|
122
121
|
#detect all player names
|
123
|
-
#
|
124
122
|
matches = []
|
125
123
|
regex = /cs ([0-9]+) \"\\name\\([^\0]*)\\hand/
|
126
124
|
rest_content = content
|
@@ -146,7 +144,7 @@ class DemoReaderWarsow
|
|
146
144
|
|
147
145
|
|
148
146
|
# detect player
|
149
|
-
|
147
|
+
|
150
148
|
playernames = @playernames.compact.sort.uniq
|
151
149
|
if playernames.length == 1
|
152
150
|
@player = playernames.first
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class DemoReaderDefragDm68CpmTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
version = 68
|
6
|
+
gamemode = "cpm"
|
7
|
+
|
8
|
+
[
|
9
|
+
%w(pornchronostar_mdf.cpm_00.49.216_tyaz.germany pornchronostar 00:49.216 *tyaz*),
|
10
|
+
%w(puremotion_df.cpm_00.10.600_eS-Rody.russia puremotion 00:10.600 ^2eS-Rody)
|
11
|
+
].each do |entry|
|
12
|
+
|
13
|
+
file, map, time, player = entry
|
14
|
+
|
15
|
+
define_method "test_warsow_wd#{version}_demo_#{file.gsub(/[^a-z_0-9]/, "_")}" do
|
16
|
+
demo = DemoReader.parse("test/fixtures/defrag/dm_#{version}/#{gamemode}/#{file}.dm_#{version}")
|
17
|
+
|
18
|
+
assert demo.valid
|
19
|
+
assert_equal gamemode, demo.gamemode
|
20
|
+
assert_equal version, demo.version
|
21
|
+
assert_equal map, demo.mapname
|
22
|
+
assert_equal player, demo.player
|
23
|
+
assert_equal time, demo.time
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class DemoReaderDefragDm68Vq3Test < Test::Unit::TestCase
|
4
|
+
|
5
|
+
version = 68
|
6
|
+
gamemode = "vq3"
|
7
|
+
|
8
|
+
[
|
9
|
+
%w(runkull2_df.vq3_01.05.904_XunderBIRD.Germany runkull2 01:05.904 ^2XunderBIRD),
|
10
|
+
%w(un-dead029_df.vq3_00.16.912_uN-DeaD!WiNTeR.ru un-dead029 00:16.912 ^2uN-DeaD!WiNTeR)
|
11
|
+
].each do |entry|
|
12
|
+
|
13
|
+
file, map, time, player = entry
|
14
|
+
|
15
|
+
define_method "test_warsow_wd#{version}_demo_#{file.gsub(/[^a-z_0-9]/, "_")}" do
|
16
|
+
demo = DemoReader.parse("test/fixtures/defrag/dm_#{version}/#{gamemode}/#{file}.dm_#{version}")
|
17
|
+
|
18
|
+
assert demo.valid
|
19
|
+
assert_equal gamemode, demo.gamemode
|
20
|
+
assert_equal version, demo.version
|
21
|
+
assert_equal map, demo.mapname
|
22
|
+
assert_equal player, demo.player
|
23
|
+
assert_equal time, demo.time
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: demo-reader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- aekym
|
@@ -9,16 +15,16 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
18
|
+
date: 2010-08-03 00:00:00 +02:00
|
13
19
|
default_executable:
|
14
20
|
dependencies: []
|
15
21
|
|
16
|
-
description: A library to read warsow demo files (.wd8, .wd9, .wd10, .wd11 files)
|
22
|
+
description: A library to read warsow demo files (.wd8, .wd9, .wd10, .wd11 files) and q3 demo files (*.dm68)
|
17
23
|
email: me@aekym.com
|
18
24
|
executables: []
|
19
25
|
|
20
|
-
extensions:
|
21
|
-
|
26
|
+
extensions:
|
27
|
+
- ext/dm68/extconf.rb
|
22
28
|
extra_rdoc_files:
|
23
29
|
- LICENSE
|
24
30
|
- README.rdoc
|
@@ -29,11 +35,31 @@ files:
|
|
29
35
|
- Rakefile
|
30
36
|
- VERSION
|
31
37
|
- demo-reader.gemspec
|
38
|
+
- ext/dm68/README.txt
|
39
|
+
- ext/dm68/common.c
|
40
|
+
- ext/dm68/common.h
|
41
|
+
- ext/dm68/dm68.c
|
42
|
+
- ext/dm68/dump.c
|
43
|
+
- ext/dm68/extconf.rb
|
44
|
+
- ext/dm68/huff.c
|
45
|
+
- ext/dm68/huff.h
|
46
|
+
- ext/dm68/main.c
|
47
|
+
- ext/dm68/main.h
|
48
|
+
- ext/dm68/msg.c
|
49
|
+
- ext/dm68/msg.h
|
50
|
+
- ext/dm68/parse.c
|
32
51
|
- lib/demo-reader.rb
|
52
|
+
- lib/demo_reader_defrag.rb
|
33
53
|
- lib/demo_reader_warsow.rb
|
54
|
+
- test/demo_reader_defrag_dm_68_cpm_test.rb
|
55
|
+
- test/demo_reader_defrag_dm_68_vq3_test.rb
|
34
56
|
- test/demo_reader_test.rb
|
35
57
|
- test/demo_reader_warsow_wd10_race_test.rb
|
36
58
|
- test/demo_reader_warsow_wd11_race_test.rb
|
59
|
+
- test/fixtures/defrag/dm_68/cpm/pornchronostar_mdf.cpm_00.49.216_tyaz.germany.dm_68
|
60
|
+
- test/fixtures/defrag/dm_68/cpm/puremotion_df.cpm_00.10.600_eS-Rody.russia.dm_68
|
61
|
+
- test/fixtures/defrag/dm_68/vq3/runkull2_df.vq3_01.05.904_XunderBIRD.Germany.dm_68
|
62
|
+
- test/fixtures/defrag/dm_68/vq3/un-dead029_df.vq3_00.16.912_uN-DeaD!WiNTeR.ru.dm_68
|
37
63
|
- test/fixtures/warsow/wd10/racesow_0.42.b2/dinirun2_racesow_0.42.b2.wd10
|
38
64
|
- test/fixtures/warsow/wd10/racesow_local/boris.wd10
|
39
65
|
- test/fixtures/warsow/wd10/racesow_local/die11.7.wd10
|
@@ -65,25 +91,33 @@ rdoc_options:
|
|
65
91
|
require_paths:
|
66
92
|
- lib
|
67
93
|
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
68
95
|
requirements:
|
69
96
|
- - ">="
|
70
97
|
- !ruby/object:Gem::Version
|
98
|
+
hash: 3
|
99
|
+
segments:
|
100
|
+
- 0
|
71
101
|
version: "0"
|
72
|
-
version:
|
73
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
74
104
|
requirements:
|
75
105
|
- - ">="
|
76
106
|
- !ruby/object:Gem::Version
|
107
|
+
hash: 3
|
108
|
+
segments:
|
109
|
+
- 0
|
77
110
|
version: "0"
|
78
|
-
version:
|
79
111
|
requirements: []
|
80
112
|
|
81
113
|
rubyforge_project:
|
82
|
-
rubygems_version: 1.3.
|
114
|
+
rubygems_version: 1.3.7
|
83
115
|
signing_key:
|
84
116
|
specification_version: 3
|
85
|
-
summary: A library to read warsow demo files
|
117
|
+
summary: A library to read warsow and q3 demo files
|
86
118
|
test_files:
|
119
|
+
- test/demo_reader_defrag_dm_68_cpm_test.rb
|
120
|
+
- test/demo_reader_defrag_dm_68_vq3_test.rb
|
87
121
|
- test/demo_reader_test.rb
|
88
122
|
- test/demo_reader_warsow_wd10_race_test.rb
|
89
123
|
- test/demo_reader_warsow_wd11_race_test.rb
|