openra 2.3.1 → 3.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: fb765723f864f95b995b8fd38c8590c7ed916ed9dcbeaa16212eedf0ee32d1b5
4
- data.tar.gz: ad408fb02eb733dc1eaec9b9a7cdc1ab039f265f72d87f28ef6ff20e7e470738
3
+ metadata.gz: 2f08aa3006104ee390f946d7ee77972682fe47d771d384b47bff2244d1b9c65d
4
+ data.tar.gz: 14d912561d616f58da10f1fd4d25cd355fed9fcb5dba1eca6a48d409693a0096
5
5
  SHA512:
6
- metadata.gz: 4c53d05f0d0e9d5d5b6b424b1c96994f3c05f91cab405537c6ab9e0a2a81dd373a4bc9442520866af37ce95faa024d4727e4511797c9d7475674cef3a239077e
7
- data.tar.gz: 61ceaa4c5025b5fc5203084692f24b71c93207fedcd8efae883a05b038fd8cf966dd018ad94115c2020944286b5ed26b2d8cbd180cd7ab964350a916e3b51993
6
+ metadata.gz: e5ec9afc0028c3f8c51446c0f105fa04c990074ea8ce32e5a3abf5baf0adc75357dd387825ba3ec227f2a053b0f67d7a4c8b2db68ca16d0adc13637c9aacee32
7
+ data.tar.gz: 6d787e65bc015eef273afa360c456efa76ada52539eb01ece86d737323a65625f4d7c4671ebb9afa67aad6c710e67dec60de586d741c26ea388a20d6f548e934
@@ -1,6 +1,12 @@
1
1
  ## Unreleased
2
2
 
3
- [Compare v2.3.1...HEAD](https://github.com/AMHOL/openra-ruby/compare/v2.3.0...HEAD)
3
+ [Compare v3.0.0...HEAD](https://github.com/AMHOL/openra-ruby/compare/v3.0.0...HEAD)
4
+
5
+ ## v3.0.0
6
+
7
+ * [replay-metadata] Rename metadata command to replay-metadata ([AMHOL](https://github.com/AMHOL))
8
+
9
+ [Compare v2.3.1...v3.0.0](https://github.com/AMHOL/openra-ruby/compare/v2.3.0...v3.0.0)
4
10
 
5
11
  ## v2.3.1
6
12
 
data/README.md CHANGED
@@ -25,7 +25,7 @@ gem update openra
25
25
 
26
26
  ```sh
27
27
  openra replay-data /path/to/replay.orarep [--format json|pretty-json|yaml]
28
- openra metadata /path/to/replay.orarep [--format json|pretty-json|yaml]
28
+ openra replay-metadata /path/to/replay.orarep [--format json|pretty-json|yaml]
29
29
  ```
30
30
 
31
31
  ### Other tools
@@ -7,10 +7,10 @@ require 'dry/cli'
7
7
  require 'openra/version'
8
8
  require 'openra/constants'
9
9
  require 'openra/replays'
10
- require 'openra/cli/utils'
10
+ require 'openra/commands'
11
11
  require 'openra/cli/formatters'
12
- require 'openra/cli/commands/metadata'
13
12
  require 'openra/cli/commands/replay_data'
13
+ require 'openra/cli/commands/replay_metadata'
14
14
  require 'openra/cli/commands/version'
15
15
  require 'openra/cli/command_registry'
16
16
 
@@ -5,8 +5,8 @@ module Openra
5
5
  class CommandRegistry
6
6
  extend Dry::CLI::Registry
7
7
 
8
- register 'metadata', Commands::Metadata
9
8
  register 'replay-data', Commands::ReplayData
9
+ register 'replay-metadata', Commands::ReplayMetadata
10
10
  register 'version', Commands::Version
11
11
  end
12
12
  end
@@ -4,155 +4,13 @@ module Openra
4
4
  class CLI
5
5
  module Commands
6
6
  class ReplayData < Dry::CLI::Command
7
- include CLI::Utils
8
-
9
7
  desc 'Output replay data to stdout'
10
8
 
11
9
  argument :replay, required: true, desc: 'Path of the replay file to read data from'
12
10
  option :format, default: 'json', values: %w(json pretty-json yaml), desc: 'Output format'
13
11
 
14
12
  def call(replay:, **options)
15
- replay = Openra::Replays::Replay.new(replay)
16
- support_powers = SUPPORT_POWERS.fetch(replay.metadata.mod, {})
17
-
18
- data = {
19
- mod: replay.metadata.mod,
20
- version: replay.metadata.version,
21
- server_name: nil,
22
- map: {
23
- name: utf8(replay.metadata.map_name),
24
- hash: replay.metadata.map_hash
25
- },
26
- game: {
27
- type: replay.players.each_with_object(Hash.new(0)) { |player, hash|
28
- if player.team.nil?
29
- hash[SecureRandom.uuid] += 1
30
- else
31
- hash[player.team] += 1
32
- end
33
- }.values.join('v'),
34
- start_time: replay.metadata.start_time.iso8601,
35
- end_time: replay.metadata.end_time.iso8601,
36
- duration: time((replay.metadata.end_time - replay.metadata.start_time) * 1000),
37
- options: nil
38
- },
39
- clients: [],
40
- chat: []
41
- }
42
-
43
- current_sync_clients = []
44
- current_sync_info = nil
45
-
46
- replay.each_order do |order|
47
- client = current_sync_clients.find do |candidate|
48
- candidate.index == order.client_index.to_s
49
- end
50
-
51
- case order.command
52
- when 'StartGame'
53
- data[:clients] = current_sync_info.clients.map do |client|
54
- player = replay.player(client.index)
55
- player_index = replay.players.index(player) + FIRST_PLAYER_INDEX if player
56
-
57
- {
58
- index: client.index,
59
- player_index: player_index,
60
- name: utf8(client.name),
61
- fingerprint: client.fingerprint,
62
- preferred_color: client.preferred_color,
63
- color: client.color,
64
- spawn: {
65
- random: player&.is_random_spawn,
66
- point: client.spawn_point
67
- },
68
- faction: {
69
- random: player&.is_random_faction,
70
- chosen: client.faction_name.downcase,
71
- actual: player&.faction_id
72
- },
73
- ip: client.ip,
74
- team: player&.team,
75
- is_bot: player&.is_bot || false,
76
- is_admin: client.is_admin,
77
- is_player: !player.nil?,
78
- is_winner: player&.outcome == 'Won',
79
- outcome_time: player&.outcome_time&.iso8601,
80
- build: [],
81
- support_powers: []
82
- }
83
- end
84
-
85
- data[:game][:options] = {
86
- explored_map: current_sync_info.global_settings.game_options.explored_map_enabled.value,
87
- speed: current_sync_info.global_settings.game_options.game_speed.value,
88
- starting_cash: current_sync_info.global_settings.game_options.starting_cash.value,
89
- starting_units: current_sync_info.global_settings.game_options.starting_units.value,
90
- fog_enabled: current_sync_info.global_settings.game_options.fog_enabled.value,
91
- cheats_enabled: current_sync_info.global_settings.game_options.cheats_enabled.value,
92
- kill_bounty_enabled: current_sync_info.global_settings.game_options.bounties_enabled.value,
93
- allow_undeploy: current_sync_info.global_settings.game_options.conyard_undeploy_enabled.value,
94
- crates_enabled: current_sync_info.global_settings.game_options.crates_enabled.value,
95
- build_off_allies: current_sync_info.global_settings.game_options.build_off_allies_enabled.value,
96
- restrict_build_radius: current_sync_info.global_settings.game_options.restricted_build_radius_enabled.value,
97
- short_game: current_sync_info.global_settings.game_options.short_game_enabled.value,
98
- techlevel: current_sync_info.global_settings.game_options.tech_level.value
99
- }
100
- when 'SyncInfo'
101
- current_sync_info = Openra::Struct::SyncInfo.new(
102
- Openra::MiniYAML.load(order.target)
103
- )
104
- current_sync_clients = current_sync_info.clients
105
- when 'SyncLobbyClients'
106
- current_sync_clients = Openra::Struct::SyncLobbyClients.new(
107
- Openra::MiniYAML.load(order.target)
108
- ).clients
109
- when *support_powers.keys
110
- key = support_powers.fetch(utf8(order.command))
111
- client_hash = data[:clients].find do |candidate|
112
- candidate[:index] == order.client_index.to_s
113
- end
114
-
115
- client_hash[:support_powers] << {
116
- type: key,
117
- game_time: time(order.frame.pred * current_sync_info.global_settings.frametime_multiplier),
118
- placement: cell(order.target_cell.to_i),
119
- extra_placement: cell(order.extra_cell.to_i),
120
- }
121
- when 'PlaceBuilding'
122
- # subject_id stores the player index here
123
- # as bot commands are issued by the host client
124
- client_hash = data[:clients].find do |candidate|
125
- candidate[:player_index] == order.subject_id
126
- end
127
-
128
- client_hash[:build] << {
129
- structure: utf8(order.target),
130
- game_time: time(order.frame.pred * current_sync_info.global_settings.frametime_multiplier),
131
- placement: cell(order.target_cell.to_i)
132
- }
133
- when 'Message'
134
- data[:chat] << {
135
- channel: 'server',
136
- name: nil,
137
- message: utf8(order.target)
138
- }
139
- when 'Chat'
140
- data[:chat] << {
141
- channel: 'global',
142
- name: utf8(client.name),
143
- message: utf8(order.target)
144
- }
145
- when 'TeamChat'
146
- data[:chat] << {
147
- channel: client.team,
148
- name: utf8(client.name),
149
- message: utf8(order.target)
150
- }
151
- end
152
- end
153
-
154
- data[:server_name] = utf8(current_sync_info.global_settings.server_name)
155
-
13
+ data = Openra::Commands::Replays::ExtractData.new.call(replay)
156
14
  puts FORMATTERS.fetch(options[:format]).call(data)
157
15
  end
158
16
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # frozen_string_literal: true
4
+
5
+ module Openra
6
+ class CLI
7
+ module Commands
8
+ class ReplayMetadata < Dry::CLI::Command
9
+ desc 'Output replay metadata to stdout'
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
+ data = Openra::Commands::Replays::ExtractMetadata.new.call(replay)
16
+ puts FORMATTERS.fetch(options[:format]).call(data)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ require 'openra/commands/utils'
2
+ require 'openra/commands/replays/extract_metadata'
3
+ require 'openra/commands/replays/extract_data'
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Openra
4
+ module Commands
5
+ module Replays
6
+ class ExtractData
7
+ include Utils
8
+
9
+ def call(filepath)
10
+ replay = Openra::Replays::Replay.new(filepath)
11
+ support_powers = SUPPORT_POWERS.fetch(replay.metadata.mod, {})
12
+
13
+ data = {
14
+ mod: replay.metadata.mod,
15
+ version: replay.metadata.version,
16
+ server_name: nil,
17
+ map: {
18
+ name: utf8(replay.metadata.map_name),
19
+ hash: replay.metadata.map_hash
20
+ },
21
+ game: {
22
+ type: replay.players.each_with_object(Hash.new(0)) { |player, hash|
23
+ if player.team.nil?
24
+ hash[SecureRandom.uuid] += 1
25
+ else
26
+ hash[player.team] += 1
27
+ end
28
+ }.values.join('v'),
29
+ start_time: replay.metadata.start_time.iso8601,
30
+ end_time: replay.metadata.end_time.iso8601,
31
+ duration: time((replay.metadata.end_time - replay.metadata.start_time) * 1000),
32
+ options: nil
33
+ },
34
+ clients: [],
35
+ chat: []
36
+ }
37
+
38
+ current_sync_clients = []
39
+ current_sync_info = nil
40
+
41
+ replay.each_order do |order|
42
+ client = current_sync_clients.find do |candidate|
43
+ candidate.index == order.client_index.to_s
44
+ end
45
+
46
+ case order.command
47
+ when 'StartGame'
48
+ data[:clients] = current_sync_info.clients.map do |client|
49
+ player = replay.player(client.index)
50
+ player_index = replay.players.index(player) + FIRST_PLAYER_INDEX if player
51
+
52
+ {
53
+ index: client.index,
54
+ player_index: player_index,
55
+ name: utf8(client.name),
56
+ fingerprint: client.fingerprint,
57
+ preferred_color: client.preferred_color,
58
+ color: client.color,
59
+ spawn: {
60
+ random: player&.is_random_spawn,
61
+ point: client.spawn_point
62
+ },
63
+ faction: {
64
+ random: player&.is_random_faction,
65
+ chosen: client.faction_name.downcase,
66
+ actual: player&.faction_id
67
+ },
68
+ ip: client.ip,
69
+ team: player&.team,
70
+ is_bot: player&.is_bot || false,
71
+ is_admin: client.is_admin,
72
+ is_player: !player.nil?,
73
+ is_winner: player&.outcome == 'Won',
74
+ outcome_time: player&.outcome_time&.iso8601,
75
+ build: [],
76
+ support_powers: []
77
+ }
78
+ end
79
+
80
+ data[:game][:options] = {
81
+ explored_map: current_sync_info.global_settings.game_options.explored_map_enabled.value,
82
+ speed: current_sync_info.global_settings.game_options.game_speed.value,
83
+ starting_cash: current_sync_info.global_settings.game_options.starting_cash.value,
84
+ starting_units: current_sync_info.global_settings.game_options.starting_units.value,
85
+ fog_enabled: current_sync_info.global_settings.game_options.fog_enabled.value,
86
+ cheats_enabled: current_sync_info.global_settings.game_options.cheats_enabled.value,
87
+ kill_bounty_enabled: current_sync_info.global_settings.game_options.bounties_enabled.value,
88
+ allow_undeploy: current_sync_info.global_settings.game_options.conyard_undeploy_enabled.value,
89
+ crates_enabled: current_sync_info.global_settings.game_options.crates_enabled.value,
90
+ build_off_allies: current_sync_info.global_settings.game_options.build_off_allies_enabled.value,
91
+ restrict_build_radius: current_sync_info.global_settings.game_options.restricted_build_radius_enabled.value,
92
+ short_game: current_sync_info.global_settings.game_options.short_game_enabled.value,
93
+ techlevel: current_sync_info.global_settings.game_options.tech_level.value
94
+ }
95
+ when 'SyncInfo'
96
+ current_sync_info = Openra::Struct::SyncInfo.new(
97
+ Openra::MiniYAML.load(order.target)
98
+ )
99
+ current_sync_clients = current_sync_info.clients
100
+ when 'SyncLobbyClients'
101
+ current_sync_clients = Openra::Struct::SyncLobbyClients.new(
102
+ Openra::MiniYAML.load(order.target)
103
+ ).clients
104
+ when *support_powers.keys
105
+ key = support_powers.fetch(utf8(order.command))
106
+ client_hash = data[:clients].find do |candidate|
107
+ candidate[:index] == order.client_index.to_s
108
+ end
109
+
110
+ client_hash[:support_powers] << {
111
+ type: key,
112
+ game_time: time(order.frame.pred * current_sync_info.global_settings.frametime_multiplier),
113
+ placement: cell(order.target_cell.to_i),
114
+ extra_placement: cell(order.extra_cell.to_i),
115
+ }
116
+ when 'PlaceBuilding'
117
+ # subject_id stores the player index here
118
+ # as bot commands are issued by the host client
119
+ client_hash = data[:clients].find do |candidate|
120
+ candidate[:player_index] == order.subject_id
121
+ end
122
+
123
+ client_hash[:build] << {
124
+ structure: utf8(order.target),
125
+ game_time: time(order.frame.pred * current_sync_info.global_settings.frametime_multiplier),
126
+ placement: cell(order.target_cell.to_i)
127
+ }
128
+ when 'Message'
129
+ data[:chat] << {
130
+ channel: 'server',
131
+ name: nil,
132
+ message: utf8(order.target)
133
+ }
134
+ when 'Chat'
135
+ data[:chat] << {
136
+ channel: 'global',
137
+ name: utf8(client.name),
138
+ message: utf8(order.target)
139
+ }
140
+ when 'TeamChat'
141
+ data[:chat] << {
142
+ channel: client.team,
143
+ name: utf8(client.name),
144
+ message: utf8(order.target)
145
+ }
146
+ end
147
+ end
148
+
149
+ data[:server_name] = utf8(current_sync_info.global_settings.server_name)
150
+
151
+ data
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -1,20 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Openra
4
- class CLI
5
- module Commands
6
- class Metadata < Dry::CLI::Command
7
- include CLI::Utils
4
+ module Commands
5
+ module Replays
6
+ class ExtractMetadata
7
+ include Utils
8
8
 
9
- desc 'Output replay metadata to stdout'
9
+ def call(filepath)
10
+ replay = Openra::Replays::Replay.new(filepath)
10
11
 
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
-
17
- data = {
12
+ {
18
13
  mod: replay.metadata.mod,
19
14
  version: replay.metadata.version,
20
15
  map: {
@@ -55,8 +50,6 @@ module Openra
55
50
  }
56
51
  }
57
52
  }
58
-
59
- puts FORMATTERS.fetch(options[:format]).call(data)
60
53
  end
61
54
  end
62
55
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Openra
4
- class CLI
4
+ module Commands
5
5
  module Utils
6
6
  def utf8(string)
7
7
  string.force_encoding('UTF-8')
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'dry/transformer/all'
4
- require 'dry-struct'
5
4
  require 'openra/types'
5
+ require 'dry-struct'
6
6
  require 'openra/struct/functions'
7
7
  require 'openra/struct/pre_processor'
8
8
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Openra
4
- VERSION = '2.3.1'.freeze
4
+ VERSION = '3.0.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openra
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Holland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-11 00:00:00.000000000 Z
11
+ date: 2020-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -158,11 +158,14 @@ files:
158
158
  - lib/openra.rb
159
159
  - lib/openra/cli.rb
160
160
  - lib/openra/cli/command_registry.rb
161
- - lib/openra/cli/commands/metadata.rb
162
161
  - lib/openra/cli/commands/replay_data.rb
162
+ - lib/openra/cli/commands/replay_metadata.rb
163
163
  - lib/openra/cli/commands/version.rb
164
164
  - lib/openra/cli/formatters.rb
165
- - lib/openra/cli/utils.rb
165
+ - lib/openra/commands.rb
166
+ - lib/openra/commands/replays/extract_data.rb
167
+ - lib/openra/commands/replays/extract_metadata.rb
168
+ - lib/openra/commands/utils.rb
166
169
  - lib/openra/constants.rb
167
170
  - lib/openra/mini_yaml.rb
168
171
  - lib/openra/replays.rb