openra 1.8.2 → 2.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3636042a779c88135640420729bddffea4af5f7be68ce85f215a01c09b42c24
4
- data.tar.gz: 5762e992a1d242bc8b02ae1f07bc4a6628f28f9cb77d30001aa5b39fd645c0c7
3
+ metadata.gz: 4d50772fdfb058a097600d6739787d971d4181ea94f889f463f5790d87cae0df
4
+ data.tar.gz: 325f6d9fae9516003c127b7ea580e69d4fdb45c70183a30e4b2ab35598ff2996
5
5
  SHA512:
6
- metadata.gz: 47d3f9b58ce7c8132ef1c25f053a30cd016dfa4c7adc13fba47647996b491050ebf73a3b7836378f9c42d93fb797a08acb09b626f3f85507f018b8e50e2d857d
7
- data.tar.gz: c9b9bf3d3782942c5348eb4ef347de4f65d5ecb9183217b4015692eec02905183e17ee416f6496e103c99fed61a59a8ff44143e57ef2f715aa51ae21cdbb0465
6
+ metadata.gz: 4b7591e6daa6aa379d36f990a01f873826e133a9c5cffacb7bcf63f935148410c67e2936a875da5507b7c14ad1c7c1f4389136fbfb19672fb8028306a3500ade
7
+ data.tar.gz: 2304fa6ca53e18438a18c213fff87157a7835b4937e391af64cabd4202a2b9aa974e208cda17bbbf7bc2a51dba29585bcfd68c6f973d9fbc671b6ebd4bc758da
data/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  ## Unreleased
2
2
 
3
- [Compare v1.8.2...HEAD](https://github.com/AMHOL/openra-ruby/compare/v1.8.2...HEAD)
3
+ [Compare v2.0.0...HEAD](https://github.com/AMHOL/openra-ruby/compare/v2.0.0...HEAD)
4
+
5
+ ## v2.0.0
6
+
7
+ ### Removed
8
+
9
+ * [detect-production-macros] Remove command because it's garbage ([AMHOL](https://github.com/AMHOL))
10
+
11
+ [Compare v1.8.2...v2.0.0](https://github.com/AMHOL/openra-ruby/compare/v1.8.2...v2.0.0)
4
12
 
5
13
  ## v1.8.2
6
14
 
data/lib/openra/cli.rb CHANGED
@@ -8,8 +8,7 @@ require 'openra/version'
8
8
  require 'openra/constants'
9
9
  require 'openra/replays'
10
10
  require 'openra/cli/utils'
11
- require 'openra/cli/commands/formatters'
12
- require 'openra/cli/commands/detect_production_macros'
11
+ require 'openra/cli/formatters'
13
12
  require 'openra/cli/commands/replay_data'
14
13
  require 'openra/cli/commands/version'
15
14
  require 'openra/cli/command_registry'
@@ -6,7 +6,6 @@ module Openra
6
6
  extend Dry::CLI::Registry
7
7
 
8
8
  register 'replay-data', Commands::ReplayData
9
- register 'detect-production-macros', Commands::DetectProductionMacros
10
9
  register 'version', Commands::Version
11
10
  end
12
11
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Openra
4
+ class CLI
5
+ module Formatters
6
+ class JSON
7
+ def call(data)
8
+ ::JSON.dump(data)
9
+ end
10
+ end
11
+
12
+ class PrettyJSON
13
+ def call(data)
14
+ ::JSON.pretty_generate(data)
15
+ end
16
+ end
17
+
18
+ class YAML
19
+ def call(data)
20
+ ::YAML.dump(
21
+ Openra::Struct::Functions[:deep_stringify_keys].(data)
22
+ )
23
+ end
24
+ end
25
+ end
26
+
27
+ FORMATTERS = {
28
+ 'json' => Formatters::JSON.new,
29
+ 'pretty-json' => Formatters::PrettyJSON.new,
30
+ 'yaml' => Formatters::YAML.new,
31
+ }.freeze
32
+ end
33
+ end
@@ -4,7 +4,7 @@ module Openra
4
4
  class CLI
5
5
  module Utils
6
6
  def utf8(string)
7
- string.force_encoding('UTF-8').to_s
7
+ string.force_encoding('UTF-8')
8
8
  end
9
9
 
10
10
  def time(msec)
@@ -16,9 +16,11 @@ module Openra
16
16
  template = Packet.new(fields: Packet.fields)
17
17
 
18
18
  loop do
19
- template.new.read(file).orders.each(&block)
20
- rescue EOFError, IOError
21
- break
19
+ begin
20
+ template.new.read(file).orders.each(&block)
21
+ rescue EOFError, IOError
22
+ break
23
+ end
22
24
  end
23
25
  end
24
26
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Openra
4
- VERSION = '1.8.2'.freeze
4
+ VERSION = '2.0.0'.freeze
5
5
  end
data/openra.gemspec CHANGED
@@ -10,13 +10,16 @@ Gem::Specification.new do |spec|
10
10
  spec.homepage = 'https://github.com/AMHOL/openra-ruby'
11
11
  spec.license = 'MIT'
12
12
 
13
- spec.files = `git ls-files -z`.split("\x0") - %w(
14
- bin/console
15
- bin/profile
16
- bin/trace_alloc
17
- )
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
13
+ spec.files = Dir[
14
+ 'CHANGELOG.md',
15
+ 'LICENSE',
16
+ 'README.md',
17
+ 'openra.gemspec',
18
+ 'lib/**/*',
19
+ 'bin/openra'
20
+ ]
21
+ spec.bindir = 'bin'
22
+ spec.executables = ['openra']
20
23
  spec.require_paths = ['lib']
21
24
 
22
25
  spec.add_dependency 'bundler'
@@ -27,7 +30,6 @@ Gem::Specification.new do |spec|
27
30
  spec.add_dependency 'dry-cli'
28
31
 
29
32
  spec.add_development_dependency 'rake'
33
+ spec.add_development_dependency 'rspec'
30
34
  spec.add_development_dependency 'pry'
31
- spec.add_development_dependency 'memory_profiler'
32
- spec.add_development_dependency 'stackprof'
33
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openra
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Holland
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: pry
112
+ name: rspec
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -123,21 +123,7 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: memory_profiler
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: stackprof
126
+ name: pry
141
127
  requirement: !ruby/object:Gem::Requirement
142
128
  requirements:
143
129
  - - ">="
@@ -158,12 +144,9 @@ executables:
158
144
  extensions: []
159
145
  extra_rdoc_files: []
160
146
  files:
161
- - ".gitignore"
162
147
  - CHANGELOG.md
163
- - Gemfile
164
148
  - LICENSE
165
149
  - README.md
166
- - Rakefile
167
150
  - bin/openra
168
151
  - lib/bindata/big_integer.rb
169
152
  - lib/bindata/pascal_string.rb
@@ -175,10 +158,9 @@ files:
175
158
  - lib/openra.rb
176
159
  - lib/openra/cli.rb
177
160
  - lib/openra/cli/command_registry.rb
178
- - lib/openra/cli/commands/detect_production_macros.rb
179
- - lib/openra/cli/commands/formatters.rb
180
161
  - lib/openra/cli/commands/replay_data.rb
181
162
  - lib/openra/cli/commands/version.rb
163
+ - lib/openra/cli/formatters.rb
182
164
  - lib/openra/cli/utils.rb
183
165
  - lib/openra/constants.rb
184
166
  - lib/openra/replays.rb
@@ -226,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
226
208
  - !ruby/object:Gem::Version
227
209
  version: '0'
228
210
  requirements: []
229
- rubygems_version: 3.0.3
211
+ rubygems_version: 3.1.2
230
212
  signing_key:
231
213
  specification_version: 4
232
214
  summary: Openra Rubygem
data/.gitignore DELETED
@@ -1,50 +0,0 @@
1
- *.gem
2
- *.rbc
3
- /.config
4
- /coverage/
5
- /InstalledFiles
6
- /pkg/
7
- /spec/reports/
8
- /spec/examples.txt
9
- /test/tmp/
10
- /test/version_tmp/
11
- /tmp/
12
-
13
- # Used by dotenv library to load environment variables.
14
- # .env
15
-
16
- ## Specific to RubyMotion:
17
- .dat*
18
- .repl_history
19
- build/
20
- *.bridgesupport
21
- build-iPhoneOS/
22
- build-iPhoneSimulator/
23
-
24
- ## Specific to RubyMotion (use of CocoaPods):
25
- #
26
- # We recommend against adding the Pods directory to your .gitignore. However
27
- # you should judge for yourself, the pros and cons are mentioned at:
28
- # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
- #
30
- # vendor/Pods/
31
-
32
- ## Documentation cache and generated files:
33
- /.yardoc/
34
- /_yardoc/
35
- /doc/
36
- /rdoc/
37
-
38
- ## Environment normalization:
39
- /.bundle/
40
- /vendor/bundle
41
- /lib/bundler/man/
42
-
43
- # for a library or gem, you might want to ignore these files since the code is
44
- # intended to run in multiple environments; otherwise, check them in:
45
- Gemfile.lock
46
- .ruby-version
47
- .ruby-gemset
48
-
49
- # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
- .rvmrc
data/Gemfile DELETED
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- gemspec
data/Rakefile DELETED
@@ -1,3 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
@@ -1,141 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Openra
4
- class CLI
5
- module Commands
6
- class DetectProductionMacros < Dry::CLI::Command
7
- ARRAY_HASH = ->(hash, key) { hash[key] = [] }
8
-
9
- desc 'Detect whether players are using production macros'
10
-
11
- argument :replay, required: true, desc: 'Path of the replay file to read data from'
12
- option :format, default: 'json', values: %w(json pretty-json yaml), desc: 'Output format'
13
-
14
- def call(replay:, **options)
15
- replay = Openra::Replays::Replay.new(replay)
16
- commands = Hash.new(&ARRAY_HASH)
17
- sync_info = nil
18
-
19
- replay.each_order do |order|
20
- case order.command
21
- when 'StartGame'
22
- game_started = true
23
- when 'SyncInfo'
24
- sync_info = Openra::Struct::SyncInfo.new(
25
- Openra::YAML.load(order.target)
26
- ) unless game_started
27
- when 'StartProduction'
28
- commands[order.client_index.to_s] << {
29
- target: utf8(order.target),
30
- msec: order.frame * sync_info.global_settings.frametime_multiplier
31
- }
32
- end
33
- end
34
-
35
- data = {
36
- players: replay.players.select(&:is_human).map { |player|
37
- player_commands = commands_with_delay(commands[player.index])
38
- production_stats = production_stats(player_commands)
39
- sequences = detect_sequences(player_commands)
40
-
41
- {
42
- index: player.index,
43
- name: utf8(player.name),
44
- team: player.team,
45
- outcome: player.outcome,
46
- production_stats: production_stats,
47
- sequences: sequences,
48
- suspected_macros: suspected_macros(production_stats, sequences)
49
- }
50
- }
51
- }
52
-
53
- puts FORMATTERS.fetch(options[:format]).call(data)
54
- end
55
-
56
- private
57
-
58
- def commands_with_delay(commands)
59
- commands.inject do |last_command, command|
60
- command[:delay] = command[:msec] - last_command[:msec]
61
- command
62
- end
63
-
64
- # Drop the first command, as we don't have a delay for that
65
- commands.drop(1)
66
- end
67
-
68
- def detect_sequences(player_commands)
69
- sequences = []
70
- groups = player_commands.each_with_object(
71
- Hash.new(&ARRAY_HASH)
72
- ).with_index do |(command, hash), index|
73
- hash[command[:delay]] << command.merge(index: index)
74
- end
75
-
76
- groups.each_pair do |delay, commands|
77
- sequence = []
78
-
79
- commands.inject do |last_command, command|
80
- if last_command[:index].next == command[:index]
81
- sequence << command
82
- elsif sequence.length > 1
83
- sequences << {
84
- delay: delay,
85
- sequence: sequence.map { |c| c[:target] }
86
- }
87
- sequence = []
88
- end
89
-
90
- command
91
- end
92
- end
93
-
94
- sequences = sequences.uniq.map do |sequence|
95
- sequence.merge(
96
- occurences: sequences.count { |current| current == sequence }
97
- )
98
- end
99
-
100
- sequences.select { |sequence| sequence[:occurences] > 1 }.sort do |a, b|
101
- b[:occurences] <=> a[:occurences]
102
- end
103
- end
104
-
105
- def production_stats(player_commands)
106
- order_delays = player_commands.map { |command| command[:delay] }
107
-
108
- {
109
- order_delay: {
110
- min: order_delays.min,
111
- max: order_delays.max,
112
- mean: mean(order_delays),
113
- median: median(order_delays)
114
- }
115
- }
116
- end
117
-
118
- def suspected_macros(production_stats, sequences)
119
- suspicious_sequences = sequences.count do |sequence|
120
- sequence[:delay] < 100 &&
121
- sequence[:sequence].length > 3 &&
122
- sequence[:sequence].uniq.length > 2
123
- end
124
-
125
- production_stats[:order_delay][:min] < 50 || suspicious_sequences > 0
126
- end
127
-
128
- def mean(ints)
129
- ints.sum / ints.length
130
- end
131
-
132
- def median(ints)
133
- ints = ints.sort
134
- middle_index = (ints.length - 1) / 2.0
135
-
136
- (ints[middle_index.floor] + ints[middle_index.ceil]) / 2
137
- end
138
- end
139
- end
140
- end
141
- end
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Openra
4
- class CLI
5
- module Commands
6
- module Formatters
7
- class JSON
8
- def call(data)
9
- ::JSON.dump(data)
10
- end
11
- end
12
-
13
- class PrettyJSON
14
- def call(data)
15
- ::JSON.pretty_generate(data)
16
- end
17
- end
18
-
19
- class YAML
20
- def call(data)
21
- ::YAML.dump(
22
- Openra::Struct::Functions[:deep_stringify_keys].(data)
23
- )
24
- end
25
- end
26
- end
27
-
28
- FORMATTERS = {
29
- 'json' => Formatters::JSON.new,
30
- 'pretty-json' => Formatters::PrettyJSON.new,
31
- 'yaml' => Formatters::YAML.new,
32
- }.freeze
33
- end
34
- end
35
- end