openra 2.1.0 → 3.0.1

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: e488c6ceb71360aa93bfcb831c16754fbe2ba4faf55608a7572b8b302e1820bb
4
- data.tar.gz: a78247905a1918531599f321bfa3b1c31d4b2520e3f955b55dc15e44c4db3fc5
3
+ metadata.gz: 0f9c700154d2bb31c15ac83a1edc2ec365fb567c17a4bc2d2e37c920c67de779
4
+ data.tar.gz: 13ed839f20179328684f677211cf663bc83aad21024105baf26beaf012757b2b
5
5
  SHA512:
6
- metadata.gz: e69e8ceeeabbd611d12f54850ffbd89fee488637d895d783c13582d1747426cad2659248d9c38332576125d5c5d0854a6ff82d384f52bfa05ba81dcb9792e9d5
7
- data.tar.gz: 4926b3ce501e4c138239bd3660b45baa3199484b8c33ec8bf7fe8ecb0922673c9f1d841e07195fe2db38202217a2e55fbb471faffc31ba4fee6ca1b3a57d001b
6
+ metadata.gz: 8bd6a6092972426e71f7f885f6eaa5f56dac5310c285c4b5af80aaaf48b67618d586b861b25151edfc9fbc98fc6f5fa4642dcdca19ea4c0e7a340aee484cd3a1
7
+ data.tar.gz: 4d2ad04c37f95a9a88f9852bfe36f936f1977e5cfeb72fbc84901911d73f1c5df441569249a53c406c8df9f17430d22aeccdc70962810d432a7c25491390ed7c
@@ -1,6 +1,45 @@
1
1
  ## Unreleased
2
2
 
3
- [Compare v2.1.0...HEAD](https://github.com/AMHOL/openra-ruby/compare/v2.1.0...HEAD)
3
+ [Compare v3.0.1...HEAD](https://github.com/AMHOL/openra-ruby/compare/v3.0.0...HEAD)
4
+
5
+ ## v3.0.1
6
+
7
+ * [maint] Added openra-commands file to load stand-alone commands ([AMHOL](https://github.com/AMHOL))
8
+
9
+ [Compare v3.0.0...v3.0.1](https://github.com/AMHOL/openra-ruby/compare/v3.0.0...v3.0.1)
10
+
11
+ ## v3.0.0
12
+
13
+ * [replay-metadata] Renamed metadata command to replay-metadata ([AMHOL](https://github.com/AMHOL))
14
+
15
+ [Compare v2.3.1...v3.0.0](https://github.com/AMHOL/openra-ruby/compare/v2.3.0...v3.0.0)
16
+
17
+ ## v2.3.1
18
+
19
+ * [replay-data] Fixed error when parsing replays with spectators ([AMHOL](https://github.com/AMHOL))
20
+
21
+ [Compare v2.3.0...v2.3.1](https://github.com/AMHOL/openra-ruby/compare/v2.3.0...v2.3.1)
22
+
23
+ ## v2.3.0
24
+
25
+ ### Added
26
+
27
+ * [replay-data] Add AdvancedChronoshift to Openra::SUPPORT_POWERS ([AMHOL](https://github.com/AMHOL))
28
+ * [metadata] Added metadata command ([AMHOL](https://github.com/AMHOL))
29
+
30
+ ### Fixed
31
+
32
+ * [replay-data] Store clients from SyncInfo command and keep syncing after game start ([AMHOL](https://github.com/AMHOL))
33
+
34
+ [Compare v2.2.0...v2.3.0](https://github.com/AMHOL/openra-ruby/compare/v2.2.0...v2.3.0)
35
+
36
+ ## v2.2.0
37
+
38
+ ### Fixed
39
+
40
+ * [replay-data] Fixed timing calculations ([AMHOL](https://github.com/AMHOL))
41
+
42
+ [Compare v2.1.0...v2.2.0](https://github.com/AMHOL/openra-ruby/compare/v2.1.0...v2.2.0)
4
43
 
5
44
  ## v2.1.0
6
45
 
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 detect-production-macros /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
@@ -0,0 +1 @@
1
+ require 'openra/commands'
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'openra/yaml
3
+ require 'openra/mini_yaml
@@ -1,15 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securerandom'
4
3
  require 'yaml'
5
4
  require 'json'
6
5
  require 'dry/cli'
7
6
  require 'openra/version'
8
- require 'openra/constants'
9
- require 'openra/replays'
10
- require 'openra/cli/utils'
7
+ require 'openra/commands'
11
8
  require 'openra/cli/formatters'
12
9
  require 'openra/cli/commands/replay_data'
10
+ require 'openra/cli/commands/replay_metadata'
13
11
  require 'openra/cli/commands/version'
14
12
  require 'openra/cli/command_registry'
15
13
 
@@ -6,6 +6,7 @@ module Openra
6
6
  extend Dry::CLI::Registry
7
7
 
8
8
  register 'replay-data', Commands::ReplayData
9
+ register 'replay-metadata', Commands::ReplayMetadata
9
10
  register 'version', Commands::Version
10
11
  end
11
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
- game_started = false
44
- current_sync_clients = []
45
- sync_info = nil
46
-
47
- replay.each_order do |order|
48
- client = current_sync_clients.find do |candidate|
49
- candidate.index == order.client_index.to_s
50
- end
51
-
52
- case order.command
53
- when 'StartGame'
54
- game_started = true
55
-
56
- data[:clients] = sync_info.clients.map do |client|
57
- player = replay.player(client.index)
58
- player_index = replay.players.index(player) + FIRST_PLAYER_INDEX if player
59
-
60
- {
61
- index: client.index,
62
- player_index: player_index,
63
- name: utf8(client.name),
64
- fingerprint: client.fingerprint,
65
- preferred_color: client.preferred_color,
66
- color: client.color,
67
- spawn: {
68
- random: player&.is_random_spawn,
69
- point: client.spawn_point
70
- },
71
- faction: {
72
- chosen: client.faction_name.downcase,
73
- actual: player&.faction_id
74
- },
75
- ip: client.ip,
76
- team: player&.team,
77
- is_bot: player&.is_bot || false,
78
- is_admin: client.is_admin,
79
- is_player: !player.nil?,
80
- is_winner: player&.outcome == 'Won',
81
- build: [],
82
- support_powers: []
83
- }
84
- end
85
-
86
- data[:game][:options] = {
87
- explored_map: sync_info.global_settings.game_options.explored_map_enabled.value,
88
- speed: sync_info.global_settings.game_options.game_speed.value,
89
- starting_cash: sync_info.global_settings.game_options.starting_cash.value,
90
- starting_units: sync_info.global_settings.game_options.starting_units.value,
91
- fog_enabled: sync_info.global_settings.game_options.fog_enabled.value,
92
- cheats_enabled: sync_info.global_settings.game_options.cheats_enabled.value,
93
- kill_bounty_enabled: sync_info.global_settings.game_options.bounties_enabled.value,
94
- allow_undeploy: sync_info.global_settings.game_options.conyard_undeploy_enabled.value,
95
- crates_enabled: sync_info.global_settings.game_options.crates_enabled.value,
96
- build_off_allies: sync_info.global_settings.game_options.build_off_allies_enabled.value,
97
- restrict_build_radius: sync_info.global_settings.game_options.restricted_build_radius_enabled.value,
98
- short_game: sync_info.global_settings.game_options.short_game_enabled.value,
99
- techlevel: sync_info.global_settings.game_options.tech_level.value
100
- }
101
- when 'SyncInfo'
102
- sync_info = Openra::Struct::SyncInfo.new(
103
- Openra::YAML.load(order.target)
104
- ) unless game_started
105
- when 'SyncLobbyClients'
106
- current_sync_clients = Openra::Struct::SyncLobbyClients.new(
107
- Openra::YAML.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 * 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 * 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(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,6 @@
1
+ require 'securerandom'
2
+ require 'openra/constants'
3
+ require 'openra/replays'
4
+ require 'openra/commands/utils'
5
+ require 'openra/commands/replays/extract_metadata'
6
+ 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
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Openra
4
+ module Commands
5
+ module Replays
6
+ class ExtractMetadata
7
+ include Utils
8
+
9
+ def call(filepath)
10
+ replay = Openra::Replays::Replay.new(filepath)
11
+
12
+ {
13
+ mod: replay.metadata.mod,
14
+ version: replay.metadata.version,
15
+ map: {
16
+ name: utf8(replay.metadata.map_name),
17
+ hash: replay.metadata.map_hash
18
+ },
19
+ game: {
20
+ type: replay.players.each_with_object(Hash.new(0)) { |player, hash|
21
+ if player.team.nil?
22
+ hash[SecureRandom.uuid] += 1
23
+ else
24
+ hash[player.team] += 1
25
+ end
26
+ }.values.join('v'),
27
+ start_time: replay.metadata.start_time.iso8601,
28
+ end_time: replay.metadata.end_time.iso8601,
29
+ duration: time((replay.metadata.end_time - replay.metadata.start_time) * 1000)
30
+ },
31
+ players: replay.players.map { |player|
32
+ {
33
+ player_index: player.client_index,
34
+ name: utf8(player.name),
35
+ fingerprint: player.fingerprint,
36
+ color: player.color,
37
+ spawn: {
38
+ random: player&.is_random_spawn,
39
+ point: player.spawn_point
40
+ },
41
+ faction: {
42
+ random: player&.is_random_faction,
43
+ chosen: player.faction_name.downcase,
44
+ actual: player&.faction_id
45
+ },
46
+ team: player&.team,
47
+ is_bot: player&.is_bot || false,
48
+ is_winner: player&.outcome == 'Won',
49
+ outcome_time: player.outcome_time.iso8601
50
+ }
51
+ }
52
+ }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,12 +1,13 @@
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')
8
8
  end
9
9
 
10
+ # https://github.com/OpenRA/OpenRA/blob/bleed/OpenRA.Game/CPos.cs#L24
10
11
  def cell(pos)
11
12
  return if pos.zero?
12
13
 
@@ -1,6 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Openra
4
+ # # https://github.com/OpenRA/OpenRA/blob/23b3c237b7071fd308c4664b0b6c5d719c0f3c74/OpenRA.Game/Map/MapPlayers.cs
5
+ # The player index is stored in the subject_id on orders to indicate which
6
+ # player issued the order, this is used because bot orders are issued by the
7
+ # host client
8
+ # I think the indices are as follows, but may differ for scripted maps:
9
+ # 0 => World
10
+ # 1 => Neutral
11
+ # 2 => Creeps
12
+ # 3 => Players@{0}
13
+ # 4 => Players@{1}
14
+ # 5 => ...
4
15
  FIRST_PLAYER_INDEX = 3
5
16
 
6
17
  SUPPORT_POWERS = {
@@ -9,6 +20,7 @@ module Openra
9
20
  'SovietParatroopers' => :paratroopers,
10
21
  'UkraineParabombs' => :parabombs,
11
22
  'Chronoshift' => :chronoshift,
23
+ 'AdvancedChronoshift' => :chronoshift,
12
24
  'NukePowerInfoOrder' => :nuke,
13
25
  'GrantExternalConditionPowerInfoOrder' => :iron_curtain
14
26
  },
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Openra
4
- class YAML
4
+ class MiniYAML
5
5
  MATCHER = /(?<indentation>\t+)?(?<key>[^\:]+)?\:?\s?(?<value>.+)?/.freeze
6
6
 
7
7
  def self.load(yaml_string)
@@ -4,7 +4,7 @@ require 'date'
4
4
  require 'bindata'
5
5
  require 'bindata/big_integer'
6
6
  require 'bindata/pascal_string'
7
- require 'openra/yaml'
7
+ require 'openra/mini_yaml'
8
8
  require 'openra/struct'
9
9
  require 'openra/replays/order_decorator'
10
10
  require 'openra/replays/order'
@@ -25,15 +25,15 @@ module Openra
25
25
  end
26
26
 
27
27
  def metadata
28
+ # https://github.com/OpenRA/OpenRA/blob/23b3c237b7071fd308c4664b0b6c5d719c0f3c74/OpenRA.Game/FileFormats/ReplayMetadata.cs#L96
28
29
  @metadata ||= begin
29
- metadata_fs = file.tap(&:rewind)
30
- offset = -(metadata_marker.data_length + 4)
31
- metadata_fs.seek(offset, IO::SEEK_END)
32
- Metadata.read(metadata_fs)
30
+ io = file.tap(&:rewind)
31
+ metadata_offset = -(metadata_marker.data_length + 4)
32
+ io.seek(metadata_offset, IO::SEEK_END)
33
+ Metadata.read(io)
33
34
  end
34
35
  end
35
36
 
36
-
37
37
  private
38
38
 
39
39
  attr_reader :filename
@@ -5,6 +5,7 @@ module Openra
5
5
  class Metadata < BinData::Record
6
6
  endian :little
7
7
  count_bytes_remaining :total_size
8
+ # -8 to remove metadata marker (int32)
8
9
  string :data, length: -> { total_size - 8 }
9
10
  end
10
11
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Openra
4
4
  module Replays
5
+ # The metadata markers is an int32 marker at the end of the file, indicating
6
+ # the offset at which the metadata MiniYAML is stored in the replay file
5
7
  class MetadataMarker < BinData::Record
6
8
  endian :little
7
9
  count_bytes_remaining :total_size
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Openra
4
4
  module Replays
5
+ # https://github.com/OpenRA/OpenRA/blob/bleed/OpenRA.Game/Network/Order.cs
5
6
  class Order < BinData::Record
6
7
  HEX_FE = ?\xFE.dup.force_encoding('ASCII-8BIT').freeze
7
8
  HEX_FF = ?\xFF.dup.force_encoding('ASCII-8BIT').freeze
@@ -11,7 +11,7 @@ module Openra
11
11
 
12
12
  def metadata
13
13
  @metadata ||= Openra::Struct::Metadata.new(
14
- Openra::YAML.load(file.metadata.data)
14
+ Openra::MiniYAML.load(file.metadata.data)
15
15
  )
16
16
  end
17
17
 
@@ -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
 
@@ -34,7 +34,7 @@ module Openra
34
34
  end
35
35
 
36
36
  def frametime_multiplier
37
- timestep * order_latency
37
+ timestep * 3
38
38
  end
39
39
  end
40
40
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Openra
4
- VERSION = '2.1.0'.freeze
4
+ VERSION = '3.0.1'.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.1.0
4
+ version: 3.0.1
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-04-12 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
@@ -151,18 +151,24 @@ files:
151
151
  - lib/bindata/big_integer.rb
152
152
  - lib/bindata/pascal_string.rb
153
153
  - lib/openra-cli.rb
154
+ - lib/openra-commands.rb
155
+ - lib/openra-mini_yaml.rb
154
156
  - lib/openra-replays.rb
155
157
  - lib/openra-struct.rb
156
158
  - lib/openra-types.rb
157
- - lib/openra-yaml.rb
158
159
  - lib/openra.rb
159
160
  - lib/openra/cli.rb
160
161
  - lib/openra/cli/command_registry.rb
161
162
  - lib/openra/cli/commands/replay_data.rb
163
+ - lib/openra/cli/commands/replay_metadata.rb
162
164
  - lib/openra/cli/commands/version.rb
163
165
  - lib/openra/cli/formatters.rb
164
- - lib/openra/cli/utils.rb
166
+ - lib/openra/commands.rb
167
+ - lib/openra/commands/replays/extract_data.rb
168
+ - lib/openra/commands/replays/extract_metadata.rb
169
+ - lib/openra/commands/utils.rb
165
170
  - lib/openra/constants.rb
171
+ - lib/openra/mini_yaml.rb
166
172
  - lib/openra/replays.rb
167
173
  - lib/openra/replays/file.rb
168
174
  - lib/openra/replays/metadata.rb
@@ -187,7 +193,6 @@ files:
187
193
  - lib/openra/struct/sync_lobby_clients.rb
188
194
  - lib/openra/types.rb
189
195
  - lib/openra/version.rb
190
- - lib/openra/yaml.rb
191
196
  - openra.gemspec
192
197
  homepage: https://github.com/AMHOL/openra-ruby
193
198
  licenses: