csstats 1.1.0 → 1.2.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.
- checksums.yaml +5 -5
- data/.rubocop.yml +33 -0
- data/.travis.yml +23 -7
- data/Gemfile +3 -7
- data/LICENSE +1 -1
- data/README.md +12 -9
- data/bin/console +1 -1
- data/csstats.gemspec +3 -4
- data/lib/csstats.rb +5 -3
- data/lib/csstats/client.rb +23 -0
- data/lib/csstats/columns.rb +28 -0
- data/lib/csstats/parser.rb +13 -4
- data/lib/csstats/parser/reader.rb +11 -0
- data/lib/csstats/parser/reader/file_reader.rb +45 -0
- data/lib/csstats/parser/{file_reader/handler.rb → reader/file_streamer.rb} +8 -8
- data/lib/csstats/parser/reader/player.rb +41 -0
- data/lib/csstats/parser/reader/players.rb +41 -0
- data/lib/csstats/{writer.rb → parser/writer.rb} +4 -2
- data/lib/csstats/{writer/file_writer/handler.rb → parser/writer/file_streamer.rb} +9 -10
- data/lib/csstats/parser/writer/player.rb +34 -0
- data/lib/csstats/parser/writer/players.rb +29 -0
- data/lib/csstats/player.rb +34 -0
- data/lib/csstats/players.rb +52 -0
- data/lib/csstats/version.rb +1 -1
- data/spec/csstats/client_spec.rb +13 -0
- data/spec/csstats/parser/reader/player_spec.rb +17 -0
- data/spec/csstats/parser/writer/players_spec.rb +30 -0
- data/spec/csstats/player_spec.rb +109 -0
- data/spec/csstats/players_spec.rb +30 -0
- data/spec/csstats_spec.rb +2 -2
- data/spec/spec_helper.rb +3 -7
- metadata +29 -21
- data/lib/csstats/handler.rb +0 -50
- data/lib/csstats/parser/file_reader.rb +0 -39
- data/lib/csstats/parser/player.rb +0 -82
- data/lib/csstats/parser/players.rb +0 -42
- data/lib/csstats/writer/player.rb +0 -39
- data/lib/csstats/writer/players.rb +0 -24
- data/spec/csstats/handler_spec.rb +0 -113
- data/spec/csstats/parser/player_spec.rb +0 -17
- data/spec/csstats/writer/players_spec.rb +0 -26
data/spec/csstats_spec.rb
CHANGED
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe CSstats do
|
4
4
|
describe '.new' do
|
5
|
-
it 'is a CSstats::
|
6
|
-
expect(CSstats.new(path: csstats_file)).to be_a
|
5
|
+
it 'is a CSstats::Client' do
|
6
|
+
expect(CSstats.new(path: csstats_file)).to be_a(CSstats::Client)
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'is a CSstats::FileNotFound if file path empty' do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
require 'simplecov'
|
2
|
-
require 'coveralls'
|
3
|
-
require 'codeclimate-test-reporter'
|
4
2
|
|
5
3
|
SimpleCov.formatters = [
|
6
|
-
SimpleCov::Formatter::HTMLFormatter
|
7
|
-
Coveralls::SimpleCov::Formatter,
|
8
|
-
CodeClimate::TestReporter::Formatter
|
4
|
+
SimpleCov::Formatter::HTMLFormatter
|
9
5
|
]
|
10
6
|
|
11
7
|
SimpleCov.start
|
@@ -24,11 +20,11 @@ def csstats_file
|
|
24
20
|
end
|
25
21
|
|
26
22
|
def fixture_file(filename)
|
27
|
-
fixtures = File.expand_path('
|
23
|
+
fixtures = File.expand_path('fixtures', __dir__)
|
28
24
|
File.join(fixtures, filename)
|
29
25
|
end
|
30
26
|
|
31
27
|
def tmp_file(filename)
|
32
|
-
tmps = File.expand_path('
|
28
|
+
tmps = File.expand_path('tmp', __dir__)
|
33
29
|
File.join(tmps, filename)
|
34
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csstats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justas Palumickas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hashie
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '1.
|
33
|
+
version: '1.16'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '1.
|
40
|
+
version: '1.16'
|
41
41
|
description: Gem which handle csstats.dat file generated by CSX module in AMX Mod
|
42
42
|
X (http://www.amxmodx.org/)
|
43
43
|
email: jpalumickas@gmail.com
|
@@ -59,21 +59,27 @@ files:
|
|
59
59
|
- bin/console
|
60
60
|
- csstats.gemspec
|
61
61
|
- lib/csstats.rb
|
62
|
+
- lib/csstats/client.rb
|
63
|
+
- lib/csstats/columns.rb
|
62
64
|
- lib/csstats/error.rb
|
63
|
-
- lib/csstats/handler.rb
|
64
65
|
- lib/csstats/parser.rb
|
65
|
-
- lib/csstats/parser/
|
66
|
-
- lib/csstats/parser/file_reader
|
67
|
-
- lib/csstats/parser/
|
68
|
-
- lib/csstats/parser/
|
66
|
+
- lib/csstats/parser/reader.rb
|
67
|
+
- lib/csstats/parser/reader/file_reader.rb
|
68
|
+
- lib/csstats/parser/reader/file_streamer.rb
|
69
|
+
- lib/csstats/parser/reader/player.rb
|
70
|
+
- lib/csstats/parser/reader/players.rb
|
71
|
+
- lib/csstats/parser/writer.rb
|
72
|
+
- lib/csstats/parser/writer/file_streamer.rb
|
73
|
+
- lib/csstats/parser/writer/player.rb
|
74
|
+
- lib/csstats/parser/writer/players.rb
|
75
|
+
- lib/csstats/player.rb
|
76
|
+
- lib/csstats/players.rb
|
69
77
|
- lib/csstats/version.rb
|
70
|
-
-
|
71
|
-
-
|
72
|
-
-
|
73
|
-
-
|
74
|
-
- spec/csstats/
|
75
|
-
- spec/csstats/parser/player_spec.rb
|
76
|
-
- spec/csstats/writer/players_spec.rb
|
78
|
+
- spec/csstats/client_spec.rb
|
79
|
+
- spec/csstats/parser/reader/player_spec.rb
|
80
|
+
- spec/csstats/parser/writer/players_spec.rb
|
81
|
+
- spec/csstats/player_spec.rb
|
82
|
+
- spec/csstats/players_spec.rb
|
77
83
|
- spec/csstats_spec.rb
|
78
84
|
- spec/fixtures/csstats.dat
|
79
85
|
- spec/spec_helper.rb
|
@@ -90,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
96
|
requirements:
|
91
97
|
- - ">="
|
92
98
|
- !ruby/object:Gem::Version
|
93
|
-
version: 1.
|
99
|
+
version: 2.1.0
|
94
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
101
|
requirements:
|
96
102
|
- - ">="
|
@@ -98,14 +104,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
104
|
version: '0'
|
99
105
|
requirements: []
|
100
106
|
rubyforge_project:
|
101
|
-
rubygems_version: 2.
|
107
|
+
rubygems_version: 2.7.6
|
102
108
|
signing_key:
|
103
109
|
specification_version: 4
|
104
110
|
summary: ''
|
105
111
|
test_files:
|
106
|
-
- spec/csstats/
|
107
|
-
- spec/csstats/parser/player_spec.rb
|
108
|
-
- spec/csstats/writer/players_spec.rb
|
112
|
+
- spec/csstats/client_spec.rb
|
113
|
+
- spec/csstats/parser/reader/player_spec.rb
|
114
|
+
- spec/csstats/parser/writer/players_spec.rb
|
115
|
+
- spec/csstats/player_spec.rb
|
116
|
+
- spec/csstats/players_spec.rb
|
109
117
|
- spec/csstats_spec.rb
|
110
118
|
- spec/fixtures/csstats.dat
|
111
119
|
- spec/spec_helper.rb
|
data/lib/csstats/handler.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module CSstats
|
2
|
-
class Handler
|
3
|
-
attr_reader :file_path, :max_players
|
4
|
-
|
5
|
-
# Public: Initialize file.
|
6
|
-
#
|
7
|
-
# options - The Hash options:
|
8
|
-
# :path - The String of csstats.dat file path (required).
|
9
|
-
# :maxplayers - The Integer of how many players to return (optional).
|
10
|
-
#
|
11
|
-
# Returns nothing.
|
12
|
-
def initialize(options = {})
|
13
|
-
@file_path = options[:path]
|
14
|
-
@max_players = options[:maxplayers] || 0
|
15
|
-
|
16
|
-
raise CSstats::FileNotExist unless File.exist?(file_path.to_s)
|
17
|
-
end
|
18
|
-
|
19
|
-
# Public: Get the player information of specified id.
|
20
|
-
#
|
21
|
-
# id - The Integer of player id.
|
22
|
-
#
|
23
|
-
# Returns the Mash of player information.
|
24
|
-
def player(id)
|
25
|
-
players[id - 1]
|
26
|
-
end
|
27
|
-
|
28
|
-
# Public: Get total players count.
|
29
|
-
#
|
30
|
-
# Returns the Integer of player count.
|
31
|
-
def players_count
|
32
|
-
players.count
|
33
|
-
end
|
34
|
-
|
35
|
-
# Public: Get player by specified name.
|
36
|
-
#
|
37
|
-
# name - The String of player name.
|
38
|
-
#
|
39
|
-
# Returns the Mash of player information.
|
40
|
-
def search_by_name(name)
|
41
|
-
players.find { |player| player.nick == name }
|
42
|
-
end
|
43
|
-
|
44
|
-
def players
|
45
|
-
@players ||= CSstats::Parser::Players.new(
|
46
|
-
file_path, max_players: max_players
|
47
|
-
).parse
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require_relative 'file_reader/handler'
|
2
|
-
|
3
|
-
module CSstats
|
4
|
-
module Parser
|
5
|
-
class FileReader
|
6
|
-
attr_reader :file_path, :limit
|
7
|
-
|
8
|
-
def initialize(file_path, options = {})
|
9
|
-
@file_path = file_path
|
10
|
-
@limit = options[:limit] || 0
|
11
|
-
|
12
|
-
raise CSstats::FileNotExist unless File.exist?(file_path.to_s)
|
13
|
-
end
|
14
|
-
|
15
|
-
def read(&block)
|
16
|
-
return unless block_given?
|
17
|
-
|
18
|
-
file = File.new(file_path, 'r')
|
19
|
-
|
20
|
-
# Need to read first data, which means file version.
|
21
|
-
_file_version = Handler.new(file).read_short_data
|
22
|
-
|
23
|
-
read_data(file, &block)
|
24
|
-
|
25
|
-
file.close
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def read_data(file, &_block)
|
31
|
-
index = 0
|
32
|
-
while !file.eof? && (limit.zero? || index < limit)
|
33
|
-
yield(Handler.new(file), index)
|
34
|
-
index += 1
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'hashie/mash'
|
2
|
-
|
3
|
-
module CSstats
|
4
|
-
module Parser
|
5
|
-
class Player
|
6
|
-
DATA_COLUMNS = %w(
|
7
|
-
teamkill damage deaths kills shots hits headshots defusions defused
|
8
|
-
plants explosions - head chest stomach leftarm rightarm leftleg
|
9
|
-
rightleg -
|
10
|
-
).freeze
|
11
|
-
|
12
|
-
# Internal: Parse player information from file.
|
13
|
-
#
|
14
|
-
# handler - The File which was opened for reading data.
|
15
|
-
#
|
16
|
-
# Returns The Mash of player information.
|
17
|
-
def parse(handler)
|
18
|
-
length = handler.read_short_data
|
19
|
-
return if length.zero?
|
20
|
-
|
21
|
-
player_data = Hashie::Mash.new
|
22
|
-
player_data.nick = handler.read_string_data(length)
|
23
|
-
|
24
|
-
add_data(player_data, handler)
|
25
|
-
|
26
|
-
player_data
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def add_data(player_data, handler)
|
32
|
-
add_uniq(player_data, handler)
|
33
|
-
add_general_data(player_data, handler)
|
34
|
-
add_calculations(player_data)
|
35
|
-
end
|
36
|
-
|
37
|
-
def add_uniq(player_data, handler)
|
38
|
-
length = handler.read_short_data
|
39
|
-
player_data.uniq = handler.read_string_data(length)
|
40
|
-
end
|
41
|
-
|
42
|
-
def add_general_data(player_data, handler)
|
43
|
-
DATA_COLUMNS.each { |type| player_data[type] = handler.read_int_data }
|
44
|
-
|
45
|
-
# Remove all 0x00000000
|
46
|
-
player_data.tap { |x| x.delete('-') }
|
47
|
-
end
|
48
|
-
|
49
|
-
def add_calculations(player_data)
|
50
|
-
player_data.acc = count_accuracy(player_data.hits, player_data.shots)
|
51
|
-
player_data.eff = count_efficiency(
|
52
|
-
player_data.kills, player_data.deaths
|
53
|
-
)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Internal: Count player efficiency.
|
57
|
-
#
|
58
|
-
# kills - The Integer of player kills in game.
|
59
|
-
# deaths - The Integer of player deaths in game.
|
60
|
-
#
|
61
|
-
# Returns The Float of player efficiency.
|
62
|
-
def count_efficiency(kills, deaths)
|
63
|
-
kills_and_deaths = kills.to_f + deaths.to_f
|
64
|
-
return 0.0 if kills_and_deaths.zero?
|
65
|
-
|
66
|
-
(kills.to_f / kills_and_deaths * 100).round(2)
|
67
|
-
end
|
68
|
-
|
69
|
-
# Internal: Count player accuracy.
|
70
|
-
#
|
71
|
-
# hits - The Integer of player hits in game.
|
72
|
-
# shots - The Integer of player shots in game.
|
73
|
-
#
|
74
|
-
# Returns The Float of player accuracy.
|
75
|
-
def count_accuracy(hits, shots)
|
76
|
-
return 0.0 if shots.to_f.zero?
|
77
|
-
|
78
|
-
(hits.to_f / shots.to_f * 100).round(2)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module CSstats
|
2
|
-
module Parser
|
3
|
-
class Players
|
4
|
-
attr_reader :file_path, :max_players
|
5
|
-
|
6
|
-
def initialize(file_path, options = {})
|
7
|
-
@file_path = file_path
|
8
|
-
@max_players = options[:max_players] || 0
|
9
|
-
end
|
10
|
-
|
11
|
-
def parse
|
12
|
-
players = []
|
13
|
-
|
14
|
-
file_reader.read do |handler, index|
|
15
|
-
parse_player(handler, index, players)
|
16
|
-
end
|
17
|
-
|
18
|
-
players
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def parse_player(handler, index, players)
|
24
|
-
player = player_parser.parse(handler)
|
25
|
-
return unless player
|
26
|
-
|
27
|
-
player['rank'] = index + 1
|
28
|
-
players[index] = player
|
29
|
-
end
|
30
|
-
|
31
|
-
def player_parser
|
32
|
-
@player_parser ||= CSstats::Parser::Player.new
|
33
|
-
end
|
34
|
-
|
35
|
-
def file_reader
|
36
|
-
@file_reader ||= CSstats::Parser::FileReader.new(
|
37
|
-
file_path, limit: max_players
|
38
|
-
)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
module CSstats
|
2
|
-
module Writer
|
3
|
-
class Player
|
4
|
-
attr_reader :player
|
5
|
-
|
6
|
-
def initialize(player)
|
7
|
-
@player = player
|
8
|
-
end
|
9
|
-
|
10
|
-
def write(handler)
|
11
|
-
write_nick(handler)
|
12
|
-
write_uniq(handler)
|
13
|
-
write_general_data(handler)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def write_nick(handler)
|
19
|
-
handler.write_short_data(player.nick.length + 1)
|
20
|
-
handler.write_string_data(player.nick)
|
21
|
-
end
|
22
|
-
|
23
|
-
def write_uniq(handler)
|
24
|
-
handler.write_short_data(player.uniq.length + 1)
|
25
|
-
handler.write_string_data(player.uniq)
|
26
|
-
end
|
27
|
-
|
28
|
-
def write_general_data(handler)
|
29
|
-
CSstats::Parser::Player::DATA_COLUMNS.each do |type|
|
30
|
-
if type == '-'
|
31
|
-
handler.write_int_data(0)
|
32
|
-
else
|
33
|
-
handler.write_int_data(player[type])
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module CSstats
|
2
|
-
module Writer
|
3
|
-
class Players
|
4
|
-
attr_reader :players
|
5
|
-
|
6
|
-
def initialize(players)
|
7
|
-
@players = players
|
8
|
-
end
|
9
|
-
|
10
|
-
def write(file_path)
|
11
|
-
file = File.new(file_path, 'w')
|
12
|
-
handler = CSstats::Writer::FileWriter::Handler.new(file)
|
13
|
-
|
14
|
-
handler.write_short_data(11) # File version
|
15
|
-
|
16
|
-
players.each do |player|
|
17
|
-
CSstats::Writer::Player.new(player).write(handler)
|
18
|
-
end
|
19
|
-
|
20
|
-
file.close
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe CSstats::Handler do
|
4
|
-
before do
|
5
|
-
@handler = CSstats::Handler.new(path: csstats_file, maxplayers: 15)
|
6
|
-
end
|
7
|
-
|
8
|
-
it 'should return corrent players count' do
|
9
|
-
expect(@handler.players_count).to eq 15
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'should return correct player data' do
|
13
|
-
expect(@handler.player(2).nick).to eq 'CHMARSON'
|
14
|
-
end
|
15
|
-
|
16
|
-
describe 'player with specified name' do
|
17
|
-
before do
|
18
|
-
@player = @handler.search_by_name('CHMARSON')
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'should return searched player' do
|
22
|
-
expect(@player.nick).to eq 'CHMARSON'
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should return correct player rank' do
|
26
|
-
expect(@player.rank).to eq 2
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'should return correct player teamkill' do
|
30
|
-
expect(@player.teamkill).to eq 7
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should return correct player damage' do
|
34
|
-
expect(@player.damage).to eq 101_543
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should return correct player deaths' do
|
38
|
-
expect(@player.deaths).to eq 511
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'should return correct player kills' do
|
42
|
-
expect(@player.kills).to eq 759
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'should return correct player shots' do
|
46
|
-
expect(@player.shots).to eq 9421
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'should return correct player hits' do
|
50
|
-
expect(@player.hits).to eq 2885
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should return correct player headshots' do
|
54
|
-
expect(@player.headshots).to eq 225
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'should return correct player defusions' do
|
58
|
-
expect(@player.defusions).to eq 15
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should return correct player defused' do
|
62
|
-
expect(@player.defused).to eq 9
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'should return correct player plants' do
|
66
|
-
expect(@player.plants).to eq 33
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'should return correct player explosions' do
|
70
|
-
expect(@player.explosions).to eq 7
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should return correct player head' do
|
74
|
-
expect(@player.head).to eq 275
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'should return correct player chest' do
|
78
|
-
expect(@player.chest).to eq 407
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'should return correct player stomach' do
|
82
|
-
expect(@player.stomach).to eq 376
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'should return correct player leftarm' do
|
86
|
-
expect(@player.leftarm).to eq 1126
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'should return correct player rightarm' do
|
90
|
-
expect(@player.rightarm).to eq 283
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'should return correct player leftleg' do
|
94
|
-
expect(@player.leftleg).to eq 202
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'should return correct player rightleg' do
|
98
|
-
expect(@player.rightleg).to eq 214
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'should return correct player accuracy' do
|
102
|
-
expect(@player.acc).to eq 30.62
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'should return correct player efficiency' do
|
106
|
-
expect(@player.eff).to eq 59.76
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'should not return empty data' do
|
110
|
-
expect(@player['-']).to eq nil
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|