overlook-csgo 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +2 -0
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +115 -0
- data/README.md +77 -0
- data/Rakefile +6 -0
- data/bin/console +7 -0
- data/bin/setup +7 -0
- data/lib/overlook.rb +20 -0
- data/lib/overlook/bit_buffer.rb +52 -0
- data/lib/overlook/bit_reader.rb +64 -0
- data/lib/overlook/byte_reader.rb +58 -0
- data/lib/overlook/csgo.rb +9 -0
- data/lib/overlook/csgo/demo.rb +33 -0
- data/lib/overlook/csgo/demo/base.rb +20 -0
- data/lib/overlook/csgo/demo/command.rb +67 -0
- data/lib/overlook/csgo/demo/command_factory.rb +15 -0
- data/lib/overlook/csgo/demo/encrypted_data_handler.rb +16 -0
- data/lib/overlook/csgo/demo/game_event_list_message_handler.rb +19 -0
- data/lib/overlook/csgo/demo/game_event_message_handler.rb +35 -0
- data/lib/overlook/csgo/demo/header.rb +45 -0
- data/lib/overlook/csgo/demo/key_reader.rb +18 -0
- data/lib/overlook/csgo/demo/packet.rb +16 -0
- data/lib/overlook/csgo/demo/packet_factory.rb +22 -0
- data/lib/overlook/csgo/demo/packet_handler.rb +50 -0
- data/lib/overlook/csgo/demo/parser.rb +66 -0
- data/lib/overlook/csgo/demo/user_message_message_handler.rb +43 -0
- data/lib/overlook/csgo/match_info_decoder.rb +92 -0
- data/lib/overlook/csgo/sharecode_decoder.rb +83 -0
- data/lib/overlook/version.rb +3 -0
- data/lib/proto/.gitkeep +0 -0
- data/lib/proto/compiled/cstrike15_gcmessages.pb.rb +1382 -0
- data/lib/proto/compiled/cstrike15_usermessages.pb.rb +702 -0
- data/lib/proto/compiled/descriptor.pb.rb +280 -0
- data/lib/proto/compiled/netmessages.pb.rb +687 -0
- data/lib/proto/compiled/steammessages.pb.rb +798 -0
- data/overlook-csgo.gemspec +36 -0
- metadata +209 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4315287d2d511f86432769b0502b8c577f01f224
|
4
|
+
data.tar.gz: d01328bc2470a355e6518211c3edb7b44b9517a8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 96719088e5dee74f35585db2972f95909004a068eaf351b5db4399f6985b3f2d6d3adfc7301eb326cabeb0d6575871032cc8a4ca0d5cb28549fec83d123cf9e2
|
7
|
+
data.tar.gz: ed622e5f5992827ddc2c2473a8183f2dcd5b55b5224c08c297fc5b97d6ae955e148ffbfb3639a248294e78f964c246afff232750d3f015a761026560e352a04b
|
data/.gitattributes
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.3
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
overlook-csgo (0.2.0)
|
5
|
+
beefcake
|
6
|
+
steamidlib
|
7
|
+
wisper
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.4.0)
|
13
|
+
ast (2.2.0)
|
14
|
+
axiom-types (0.1.1)
|
15
|
+
descendants_tracker (~> 0.0.4)
|
16
|
+
ice_nine (~> 0.11.0)
|
17
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
18
|
+
beefcake (1.1.0)
|
19
|
+
codeclimate-engine-rb (0.3.1)
|
20
|
+
virtus (~> 1.0)
|
21
|
+
coderay (1.1.1)
|
22
|
+
coercible (1.0.0)
|
23
|
+
descendants_tracker (~> 0.0.1)
|
24
|
+
colorize (0.7.7)
|
25
|
+
descendants_tracker (0.0.4)
|
26
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
27
|
+
diff-lcs (1.2.5)
|
28
|
+
equalizer (0.0.11)
|
29
|
+
erubis (2.7.0)
|
30
|
+
ffi (1.9.10-java)
|
31
|
+
flay (2.7.0)
|
32
|
+
erubis (~> 2.7.0)
|
33
|
+
ruby_parser (~> 3.0)
|
34
|
+
sexp_processor (~> 4.0)
|
35
|
+
flog (4.3.2)
|
36
|
+
ruby_parser (~> 3.1, > 3.1.0)
|
37
|
+
sexp_processor (~> 4.4)
|
38
|
+
ice_nine (0.11.2)
|
39
|
+
launchy (2.4.3)
|
40
|
+
addressable (~> 2.3)
|
41
|
+
launchy (2.4.3-java)
|
42
|
+
addressable (~> 2.3)
|
43
|
+
spoon (~> 0.0.1)
|
44
|
+
method_source (0.8.2)
|
45
|
+
parser (2.3.0.6)
|
46
|
+
ast (~> 2.2)
|
47
|
+
pry (0.10.3)
|
48
|
+
coderay (~> 1.1.0)
|
49
|
+
method_source (~> 0.8.1)
|
50
|
+
slop (~> 3.4)
|
51
|
+
pry (0.10.3-java)
|
52
|
+
coderay (~> 1.1.0)
|
53
|
+
method_source (~> 0.8.1)
|
54
|
+
slop (~> 3.4)
|
55
|
+
spoon (~> 0.0)
|
56
|
+
rainbow (2.1.0)
|
57
|
+
rake (10.5.0)
|
58
|
+
reek (3.11)
|
59
|
+
codeclimate-engine-rb (~> 0.3.1)
|
60
|
+
parser (~> 2.3, >= 2.3.0.6)
|
61
|
+
rainbow (~> 2.0)
|
62
|
+
rspec (3.4.0)
|
63
|
+
rspec-core (~> 3.4.0)
|
64
|
+
rspec-expectations (~> 3.4.0)
|
65
|
+
rspec-mocks (~> 3.4.0)
|
66
|
+
rspec-core (3.4.3)
|
67
|
+
rspec-support (~> 3.4.0)
|
68
|
+
rspec-expectations (3.4.0)
|
69
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
70
|
+
rspec-support (~> 3.4.0)
|
71
|
+
rspec-mocks (3.4.1)
|
72
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
73
|
+
rspec-support (~> 3.4.0)
|
74
|
+
rspec-support (3.4.1)
|
75
|
+
ruby_parser (3.8.1)
|
76
|
+
sexp_processor (~> 4.1)
|
77
|
+
rubycritic (2.8.0)
|
78
|
+
colorize
|
79
|
+
flay (= 2.7.0)
|
80
|
+
flog (= 4.3.2)
|
81
|
+
launchy (= 2.4.3)
|
82
|
+
parser (~> 2.3)
|
83
|
+
reek (= 3.11)
|
84
|
+
ruby_parser (~> 3.8)
|
85
|
+
virtus (~> 1.0)
|
86
|
+
sexp_processor (4.7.0)
|
87
|
+
slop (3.6.0)
|
88
|
+
spoon (0.0.4)
|
89
|
+
ffi
|
90
|
+
steamidlib (1.0.1)
|
91
|
+
thread_safe (0.3.5)
|
92
|
+
thread_safe (0.3.5-java)
|
93
|
+
virtus (1.0.5)
|
94
|
+
axiom-types (~> 0.1)
|
95
|
+
coercible (~> 1.0)
|
96
|
+
descendants_tracker (~> 0.0, >= 0.0.3)
|
97
|
+
equalizer (~> 0.0, >= 0.0.9)
|
98
|
+
wisper (1.6.1)
|
99
|
+
yard (0.8.7.6)
|
100
|
+
|
101
|
+
PLATFORMS
|
102
|
+
java
|
103
|
+
ruby
|
104
|
+
|
105
|
+
DEPENDENCIES
|
106
|
+
bundler (~> 1.10)
|
107
|
+
overlook-csgo!
|
108
|
+
pry
|
109
|
+
rake (~> 10.0)
|
110
|
+
rspec
|
111
|
+
rubycritic
|
112
|
+
yard
|
113
|
+
|
114
|
+
BUNDLED WITH
|
115
|
+
1.11.2
|
data/README.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# Overlook
|
2
|
+
|
3
|
+
Ruby access to CS:GO demo files.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'overlook'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install overlook
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
You can suscribe a plain ruby class to the parser to act on events
|
24
|
+
in the demo. Only a few events have been implemented.
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
class ReplayAnalyzerSubscriber
|
28
|
+
attr_reader :rank_events
|
29
|
+
|
30
|
+
def initialize()
|
31
|
+
@rank_events = []
|
32
|
+
end
|
33
|
+
|
34
|
+
# Fired whenever a rank change happens.
|
35
|
+
# The update event comes in the form
|
36
|
+
# { community_id: 'ABC', rank: 12 }
|
37
|
+
def rank_update(event)
|
38
|
+
self.rank_events << event
|
39
|
+
end
|
40
|
+
|
41
|
+
# Write the header to the db when it is fired from Overlook.
|
42
|
+
# The header contains the map name
|
43
|
+
#
|
44
|
+
# The header event comes in the form
|
45
|
+
# { map_name: 'cs_office' }
|
46
|
+
def header(header)
|
47
|
+
# do something with the header.map_name
|
48
|
+
end
|
49
|
+
|
50
|
+
# Called when the replay has been parsed successfully.
|
51
|
+
# Flush the user ranks to the repository
|
52
|
+
def done(data)
|
53
|
+
rank_events.each do |rank_update|
|
54
|
+
# do something
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
subscriber = ReplayAnalyzerSubscriber.new
|
61
|
+
|
62
|
+
demo = Overlook::Csgo::Demo.new(File.open('demo.dem'))
|
63
|
+
demo.subscribe(subscriber)
|
64
|
+
demo.parse
|
65
|
+
```
|
66
|
+
|
67
|
+
You may also decompose sharecodes
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Overlook.decode_share_code('CSGO-MXzcE-vo6oX-LuOhB-Vhn7m-xiHeB')
|
71
|
+
=> {:matchid=>"3004024506927808536", :outcomeid=>"3004030760400191518", :tokenid=>"34492"}
|
72
|
+
```
|
73
|
+
|
74
|
+
## Contributing
|
75
|
+
|
76
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/taylorfinnell/overlook.
|
77
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
data/lib/overlook.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'overlook/version'
|
2
|
+
require 'overlook/csgo'
|
3
|
+
|
4
|
+
require 'overlook/bit_buffer'
|
5
|
+
require 'overlook/bit_reader'
|
6
|
+
require 'overlook/byte_reader'
|
7
|
+
|
8
|
+
require 'proto/compiled/descriptor.pb'
|
9
|
+
require 'proto/compiled/netmessages.pb'
|
10
|
+
require 'proto/compiled/cstrike15_usermessages.pb'
|
11
|
+
require 'proto/compiled/cstrike15_gcmessages.pb'
|
12
|
+
|
13
|
+
require 'steamidlib'
|
14
|
+
|
15
|
+
module Overlook
|
16
|
+
def self.decode_share_code(code)
|
17
|
+
decoder = Csgo::SharecodeDecoder.new(code)
|
18
|
+
decoder.decode
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Overlook
|
2
|
+
class BitBuffer
|
3
|
+
def initialize(io)
|
4
|
+
@io = io
|
5
|
+
@buffer = 0
|
6
|
+
@available = 0
|
7
|
+
end
|
8
|
+
|
9
|
+
def bytes(num)
|
10
|
+
@io.read(num)
|
11
|
+
end
|
12
|
+
|
13
|
+
def bits(numbits)
|
14
|
+
if numbits == 8 && @available == 0
|
15
|
+
byte = refresh_buffer
|
16
|
+
@available = 0
|
17
|
+
return byte
|
18
|
+
end
|
19
|
+
|
20
|
+
numbits.times.reduce(0) do |result, index|
|
21
|
+
refresh_buffer unless available_bits?
|
22
|
+
result |= getbit << index
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def eof?
|
27
|
+
@io.eof?
|
28
|
+
end
|
29
|
+
|
30
|
+
def skip(n)
|
31
|
+
@io.seek(n, IO::SEEK_CUR)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def getbit
|
37
|
+
bit = (@buffer >> (8 - @available)) & 1
|
38
|
+
@available = @available.pred
|
39
|
+
bit
|
40
|
+
end
|
41
|
+
|
42
|
+
def available_bits?
|
43
|
+
@available != 0
|
44
|
+
end
|
45
|
+
|
46
|
+
def refresh_buffer
|
47
|
+
@buffer = @io.getbyte
|
48
|
+
@available = 8
|
49
|
+
@buffer
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Overlook
|
2
|
+
class BitReader
|
3
|
+
def initialize(_buffer)
|
4
|
+
@buffer = BitBuffer.new(_buffer)
|
5
|
+
end
|
6
|
+
|
7
|
+
def bytes(n)
|
8
|
+
@buffer.bytes(n)
|
9
|
+
end
|
10
|
+
|
11
|
+
def bit
|
12
|
+
bits(1)
|
13
|
+
end
|
14
|
+
|
15
|
+
def byte
|
16
|
+
bits(8)
|
17
|
+
end
|
18
|
+
|
19
|
+
def skip(n)
|
20
|
+
@buffer.skip(n)
|
21
|
+
end
|
22
|
+
|
23
|
+
def short
|
24
|
+
ret = byte
|
25
|
+
ret |= byte << 8
|
26
|
+
end
|
27
|
+
|
28
|
+
def int32
|
29
|
+
ret = byte
|
30
|
+
ret |= byte << 8
|
31
|
+
ret |= byte << 16
|
32
|
+
ret |= byte << 24
|
33
|
+
end
|
34
|
+
|
35
|
+
def eof?
|
36
|
+
@buffer.eof?
|
37
|
+
end
|
38
|
+
|
39
|
+
def var_int32
|
40
|
+
var_int(4)
|
41
|
+
end
|
42
|
+
|
43
|
+
def var_int(max_len)
|
44
|
+
_byte = 0
|
45
|
+
count = 0
|
46
|
+
result = 0
|
47
|
+
|
48
|
+
loop do
|
49
|
+
return result if count + 1 == max_len
|
50
|
+
_byte = self.byte
|
51
|
+
result |= (_byte & 0x7F) << (7 * count)
|
52
|
+
count = count + 1
|
53
|
+
break if _byte & 0x80 == 0
|
54
|
+
end
|
55
|
+
result
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def bits(numbits)
|
61
|
+
@buffer.bits(numbits)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Overlook
|
4
|
+
# Reads bytes from a given IO object.
|
5
|
+
class ByteReader
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
attr_reader :io
|
9
|
+
|
10
|
+
def initialize(io)
|
11
|
+
@io = io
|
12
|
+
end
|
13
|
+
|
14
|
+
def read_int64
|
15
|
+
io.read(8).unpack("C*").each_with_index.reduce(0) do |sum, (byte, index)|
|
16
|
+
sum + byte * (256 ** index)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
alias :int64 :read_int64
|
20
|
+
|
21
|
+
def read_short
|
22
|
+
io.read(2).unpack('S*').first
|
23
|
+
end
|
24
|
+
alias :short :read_short
|
25
|
+
|
26
|
+
def string(len)
|
27
|
+
io.read(len)
|
28
|
+
end
|
29
|
+
|
30
|
+
def seek(len, type = IO::SEEK_CUR)
|
31
|
+
io.seek(len, type)
|
32
|
+
end
|
33
|
+
|
34
|
+
def float
|
35
|
+
@io.read(4).unpack('<e').first
|
36
|
+
end
|
37
|
+
|
38
|
+
def byte
|
39
|
+
io.read(1).ord
|
40
|
+
end
|
41
|
+
|
42
|
+
def char
|
43
|
+
byte.chr
|
44
|
+
end
|
45
|
+
|
46
|
+
def signed_int32
|
47
|
+
io.read(4).unpack('<l*').first
|
48
|
+
end
|
49
|
+
|
50
|
+
def signed_int16
|
51
|
+
io.read(2).unpack('<s*').first
|
52
|
+
end
|
53
|
+
|
54
|
+
def_delegator :@io, :read, :read
|
55
|
+
def_delegator :@io, :tell, :tell
|
56
|
+
def_delegator :@io, :lineno, :lineno
|
57
|
+
end
|
58
|
+
end
|