mmi 0.1.3 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +57 -19
- data/exe/mmi +13 -13
- data/lib/mmi/assets_processor.rb +29 -16
- data/lib/mmi/cached_download.rb +59 -0
- data/lib/mmi/github_api.rb +11 -0
- data/lib/mmi/interactive/assets.rb +208 -0
- data/lib/mmi/interactive/modloader.rb +139 -0
- data/lib/mmi/interactive/updater.rb +25 -138
- data/lib/mmi/interactive.rb +1 -2
- data/lib/mmi/mod_file_processor.rb +39 -26
- data/lib/mmi/modloader/fabric.rb +65 -36
- data/lib/mmi/modloader/none.rb +3 -1
- data/lib/mmi/modrinth_api.rb +14 -0
- data/lib/mmi/option_attributes.rb +38 -0
- data/lib/mmi/semver.rb +4 -4
- data/lib/mmi/source/github.rb +28 -28
- data/lib/mmi/source/modrinth.rb +79 -0
- data/lib/mmi/source/url.rb +59 -0
- data/lib/mmi/version.rb +1 -1
- data/lib/mmi.rb +2 -7
- metadata +82 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54e9d7ed91e3ac72f8c78ba1d9bb550de696e87b134e4bd1f5db393e99e7d7d2
|
4
|
+
data.tar.gz: 55df81f836288de4d0166c03488b7a3362992e6fc76304ccba2dc085758b1bb8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c9e1954062c87ea12251b23103fee16b141a9c1f78ca88199c70441649090c16f5bb09481e5d6b158903f6553c201a754608346b12dbc208400fa973eebab73
|
7
|
+
data.tar.gz: '0481cffce09c9bf0439c1b739cb53cfeba1779a994c4b0ee203f45c3c17becd0164cc8c4b6c7400da01e26605e4e2065c4eeb141f0c6054fef06722f7bd7def2'
|
data/README.adoc
CHANGED
@@ -13,14 +13,29 @@ The application is currently CLI-only, but should work on Linux, MacOS and Windo
|
|
13
13
|
|
14
14
|
toc::[]
|
15
15
|
|
16
|
-
|
16
|
+
== Installation
|
17
17
|
|
18
|
-
|
18
|
+
=== Prerequisites
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
It is recommended to use MMI with Ruby 3.0 or higher.
|
21
|
+
While lower versions might work, further development is expected to ignore any specifics that may render those versions unusable.
|
22
22
|
|
23
|
-
|
23
|
+
=== Steps
|
24
|
+
|
25
|
+
==== Installation through rubygems.org
|
26
|
+
|
27
|
+
[example]
|
28
|
+
====
|
29
|
+
*Disclaimer:* While MMI releases are published on rubygems.org, they might not reflect current development.
|
30
|
+
If something does not work, try the manual installation.
|
31
|
+
====
|
32
|
+
|
33
|
+
[source,bash]
|
34
|
+
----
|
35
|
+
$ gem install mmi
|
36
|
+
----
|
37
|
+
|
38
|
+
==== Manual installation
|
24
39
|
|
25
40
|
Clone the repository and navigate into its root directory.
|
26
41
|
|
@@ -33,27 +48,32 @@ $ hg clone https://github.com/expeehaa/mmi.git
|
|
33
48
|
$ cd mmi
|
34
49
|
----
|
35
50
|
|
36
|
-
Install gem dependencies
|
51
|
+
Install gem dependencies using bundler
|
37
52
|
|
38
53
|
[source,bash]
|
39
54
|
----
|
40
55
|
$ bundle install
|
41
56
|
----
|
42
57
|
|
43
|
-
If you get an error
|
58
|
+
If you get an error saying the lockfile requires `bundler` version 2.0+, install it first.
|
44
59
|
|
45
60
|
[source,bash]
|
46
61
|
----
|
47
62
|
$ gem install bundler
|
48
63
|
----
|
49
64
|
|
50
|
-
|
65
|
+
Install the gem.
|
51
66
|
|
52
|
-
|
67
|
+
[source,bash]
|
68
|
+
----
|
69
|
+
$ rake install
|
70
|
+
----
|
71
|
+
|
72
|
+
== Basic usage
|
53
73
|
|
54
74
|
[source,text]
|
55
75
|
----
|
56
|
-
Syntax:
|
76
|
+
Syntax: mmi <config file> [action=install]
|
57
77
|
|
58
78
|
where action is one of
|
59
79
|
install - Install the modloader and assets as specified in the config file.
|
@@ -62,30 +82,48 @@ Syntax: exe/mmi <config file> [action=install]
|
|
62
82
|
----
|
63
83
|
|
64
84
|
The script currently does not support any arguments besides the ones listed above.
|
65
|
-
Trying to get help by running `
|
85
|
+
Trying to get help by running `mmi --help` or similar will not work.
|
66
86
|
|
67
|
-
|
87
|
+
== Example configs
|
68
88
|
|
69
89
|
Example configuration files can be found in `examples/`.
|
70
|
-
They
|
90
|
+
They can be parsed by the MMI version they come with.
|
91
|
+
Example configurations download and install files into `tmp/` so that your `.minecraft` folder will stay unharmed.
|
71
92
|
|
93
|
+
The files are intended to provide an overview of the different features of MMI.
|
94
|
+
They are not intended to create a working modded Minecraft environment and will therefore not be updated for each new Minecraft version.
|
72
95
|
|
73
|
-
|
96
|
+
== TODOs
|
74
97
|
|
75
98
|
* Improve argument parsing.
|
76
99
|
* Write tests.
|
77
100
|
* Add command to interactively create a config file.
|
78
101
|
* Be able to update/change modloader interactively.
|
79
102
|
* Be able to remove assets interactively.
|
80
|
-
* Think about advising
|
103
|
+
* Think about advising users to use another file extension than `.yaml` (e.g. `.mmi`, `.mmiconf`).
|
81
104
|
* Try to make a Java-executable `.jar` file using `warbler` and `JRuby`.
|
82
105
|
|
83
|
-
|
106
|
+
== Versioning
|
107
|
+
|
108
|
+
MMI uses semantic versioning with major, minor and patch versions.
|
109
|
+
|
110
|
+
Versions are coupled to the configuration file specification.
|
111
|
+
This means, within the same major version, every release must be backwards-compatible regarding config file interpreting and MMI releases with a lower minor version must still be able to interpret a config file with a higher minor version (although they are allowed and expected to not support some configurations).
|
112
|
+
|
113
|
+
An exception to this rule are all releases with the major version `0`.
|
114
|
+
There, within the same minor version, backwards compatibility can be expected, but different minor versions will (most likely) not be compatible.
|
115
|
+
|
116
|
+
== Contributing
|
117
|
+
|
118
|
+
Contributions are very welcome, as well as feature/bug requests.
|
119
|
+
|
120
|
+
In case you want to implement a feature, it would be best to create an issue beforehand so that we can discuss it.
|
121
|
+
This reduces the chance of a pull request being rejected.
|
84
122
|
|
85
|
-
Contributions are very welcome.
|
86
123
|
If you intend to create a pull request, please choose a branch name describing its changes (i.e. not some generic term like `master` or `fix`, but e.g. `fix_typo` or `add_interactive_update_command`).
|
87
124
|
|
88
125
|
Please be aware that I have a very specific code style and am interested in keeping it in this repository.
|
89
126
|
Some basic rules are specified in the `.editorconfig` file, which your editor should support.
|
90
|
-
|
91
|
-
|
127
|
+
Additionally, Rubocop has been configured using the existing code and every commit should pass Rubocop’s inspection.
|
128
|
+
There most likely are a lot of Rubocop rules that are currently not triggered and therefore not configured.
|
129
|
+
In such a case, either try to derive a style from existing code or feel free to ask.
|
data/exe/mmi
CHANGED
@@ -19,25 +19,25 @@ def processor(file)
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
if ARGV.
|
22
|
+
if !ARGV.empty?
|
23
23
|
file = ARGV.shift
|
24
24
|
action_param = ARGV.shift
|
25
25
|
action = action_param.nil? ? :install : action_param.to_sym
|
26
26
|
|
27
27
|
case action
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
28
|
+
when :install
|
29
|
+
processor(file).install
|
30
|
+
when :validate
|
31
|
+
processor(file)
|
32
|
+
|
33
|
+
puts 'File is valid.'
|
34
|
+
when :update
|
35
|
+
Mmi::Interactive.update(processor(file), file)
|
36
|
+
else
|
37
|
+
warn "Unknown action: #{action_param.inspect}."
|
38
|
+
Kernel.exit 1
|
39
39
|
end
|
40
40
|
else
|
41
41
|
puts 'No file given.'
|
42
42
|
Kernel.exit 1
|
43
|
-
end
|
43
|
+
end
|
data/lib/mmi/assets_processor.rb
CHANGED
@@ -1,41 +1,54 @@
|
|
1
|
+
require 'mmi/option_attributes'
|
1
2
|
require 'mmi/source/github'
|
3
|
+
require 'mmi/source/modrinth'
|
4
|
+
require 'mmi/source/url'
|
2
5
|
|
3
6
|
module Mmi
|
4
7
|
class AssetsProcessor
|
5
|
-
|
6
|
-
attr_reader :assets
|
8
|
+
include OptionAttributes
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
opt_accessor(:profile_dir) { Mmi.minecraft_dir }
|
11
|
+
opt_accessor(:items ) { [] }
|
12
|
+
|
13
|
+
attr_reader :parsed_items
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
@options = options
|
12
17
|
|
13
|
-
|
14
|
-
|
18
|
+
parse!
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse!
|
22
|
+
if self.items.is_a?(Array)
|
23
|
+
@parsed_items = self.items.map.with_index do |asset, index|
|
15
24
|
source = asset['source']
|
16
25
|
|
17
26
|
if source
|
18
27
|
type = source['type']
|
19
28
|
|
20
29
|
case type
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
30
|
+
when 'github'
|
31
|
+
Source::Github.new(source)
|
32
|
+
when 'modrinth'
|
33
|
+
Source::Modrinth.new(source)
|
34
|
+
when 'url'
|
35
|
+
Source::Url.new(source)
|
36
|
+
else
|
37
|
+
raise Mmi::InvalidAttributeError, %Q(Invalid "source.type" in asset #{index.inspect}: #{type.inspect})
|
25
38
|
end
|
26
39
|
else
|
27
|
-
raise Mmi::MissingAttributeError, %Q
|
40
|
+
raise Mmi::MissingAttributeError, %Q(Missing "source" in asset #{index.inspect}.)
|
28
41
|
end
|
29
42
|
end
|
30
43
|
else
|
31
|
-
raise Mmi::InvalidAttributeError, %Q
|
44
|
+
raise Mmi::InvalidAttributeError, %Q(Invalid "assets": expected Array or nothing, got #{self.items.inspect}.)
|
32
45
|
end
|
33
46
|
end
|
34
47
|
|
35
48
|
def install
|
36
|
-
|
49
|
+
self.parsed_items.each do |asset|
|
37
50
|
asset.install(self.profile_dir)
|
38
51
|
end
|
39
52
|
end
|
40
53
|
end
|
41
|
-
end
|
54
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
module Mmi
|
6
|
+
module CachedDownload
|
7
|
+
class << self
|
8
|
+
def open_cached(path, sha512: nil)
|
9
|
+
if File.exist?(path)
|
10
|
+
File.open(path).tap do |f|
|
11
|
+
if !sha512 || sha512 == Digest::SHA512.hexdigest(f.read)
|
12
|
+
f.seek(0)
|
13
|
+
f
|
14
|
+
else
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
else
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def download(uri, sha512: nil)
|
24
|
+
URI.parse(uri).open.tap do |stream|
|
25
|
+
if sha512
|
26
|
+
actual_sha512 = Digest::SHA512.hexdigest(stream.read)
|
27
|
+
|
28
|
+
if sha512 == actual_sha512
|
29
|
+
stream.seek(0)
|
30
|
+
else
|
31
|
+
Mmi.fail! "Expected download to have SHA512 sum #{expected_hexdigest.inspect} but received #{actual_sha512.inspect}."
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def download_cached(uri, download_path, sha512_uri: nil)
|
38
|
+
ensure_cache_dir_exists!
|
39
|
+
|
40
|
+
expected_hexdigest = URI.parse(sha512_uri).open.read
|
41
|
+
cached_file = open_cached(download_path, sha512: expected_hexdigest)
|
42
|
+
|
43
|
+
if !cached_file
|
44
|
+
stream = download(uri, sha512: expected_hexdigest)
|
45
|
+
|
46
|
+
IO.copy_stream(stream, download_path)
|
47
|
+
else
|
48
|
+
Mmi.info "Using cached version of #{uri.inspect} from #{download_path.inspect}."
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def ensure_cache_dir_exists!
|
55
|
+
FileUtils.mkdir_p(Mmi.cache_dir)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'cli/ui'
|
2
|
+
|
3
|
+
require 'mmi/github_api'
|
4
|
+
require 'mmi/source/github'
|
5
|
+
|
6
|
+
module Mmi
|
7
|
+
module Interactive
|
8
|
+
module Assets
|
9
|
+
def update_assets
|
10
|
+
loop do
|
11
|
+
assets = processor.parsed_assets.parsed_items
|
12
|
+
|
13
|
+
choice = CLI::UI::Prompt.ask('Which asset do you want to change?') do |handler|
|
14
|
+
assets.each do |asset|
|
15
|
+
handler.option(asset.display_name) do
|
16
|
+
asset
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
handler.option('add', &:to_sym)
|
21
|
+
handler.option('quit', &:to_sym)
|
22
|
+
end
|
23
|
+
|
24
|
+
case choice
|
25
|
+
when :quit
|
26
|
+
break
|
27
|
+
when :add
|
28
|
+
add_asset
|
29
|
+
else
|
30
|
+
update_asset_version(choice)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_asset
|
36
|
+
source_type = CLI::UI::Prompt.ask('Choose a source type.') do |handler|
|
37
|
+
%w[
|
38
|
+
github
|
39
|
+
modrinth
|
40
|
+
url
|
41
|
+
].each do |type|
|
42
|
+
handler.option(type, &:to_sym)
|
43
|
+
end
|
44
|
+
|
45
|
+
handler.option('quit', &:to_sym)
|
46
|
+
end
|
47
|
+
|
48
|
+
opts, source =
|
49
|
+
case source_type
|
50
|
+
when :quit
|
51
|
+
return false
|
52
|
+
when :github
|
53
|
+
options = {
|
54
|
+
'source' => {
|
55
|
+
'type' => 'github',
|
56
|
+
'asset_id' => 0,
|
57
|
+
},
|
58
|
+
}
|
59
|
+
|
60
|
+
options['source']['owner' ] = CLI::UI::Prompt.ask('Who is the owner of the source repository?').strip
|
61
|
+
options['source']['repo' ] = CLI::UI::Prompt.ask('What is the name of the source repository?').strip
|
62
|
+
options['source']['install_dir'] = CLI::UI::Prompt.ask('In which directory should the asset be placed?', default: 'mods').strip
|
63
|
+
options['source']['filename' ] = CLI::UI::Prompt.ask('Under which filename should the asset be saved? (leave empty for release asset name)', allow_empty: true).strip.then do |filename|
|
64
|
+
filename == '' ? nil : filename
|
65
|
+
end
|
66
|
+
|
67
|
+
options['source'].compact!
|
68
|
+
|
69
|
+
[options, Mmi::Source::Github.new(options['source'])]
|
70
|
+
when :modrinth
|
71
|
+
options = {
|
72
|
+
'source' => {
|
73
|
+
'type' => 'modrinth',
|
74
|
+
'version' => '0',
|
75
|
+
'version_file' => '0',
|
76
|
+
},
|
77
|
+
}
|
78
|
+
|
79
|
+
options['source']['name' ] = CLI::UI::Prompt.ask('What is the name of the mod in the Modrinth URL?').strip
|
80
|
+
options['source']['install_dir'] = CLI::UI::Prompt.ask('In which directory should the asset be placed?', default: 'mods').strip
|
81
|
+
options['source']['filename' ] = CLI::UI::Prompt.ask('Under which filename should the asset be saved? (leave empty for release asset name)', allow_empty: true).strip.then do |filename|
|
82
|
+
filename == '' ? nil : filename
|
83
|
+
end
|
84
|
+
|
85
|
+
options['source'].compact!
|
86
|
+
|
87
|
+
[options, Mmi::Source::Modrinth.new(options['source'])]
|
88
|
+
when :url
|
89
|
+
options = {
|
90
|
+
'source' => {
|
91
|
+
'type' => 'url',
|
92
|
+
'url' => '',
|
93
|
+
},
|
94
|
+
}
|
95
|
+
|
96
|
+
options['source']['install_dir'] = CLI::UI::Prompt.ask('In which directory should the asset be placed?', default: 'mods').strip
|
97
|
+
options['source']['filename' ] = CLI::UI::Prompt.ask('Under which filename should the asset be saved? (leave empty for release asset name)', allow_empty: true).strip.then do |filename|
|
98
|
+
filename == '' ? nil : filename
|
99
|
+
end
|
100
|
+
|
101
|
+
options['source'].compact!
|
102
|
+
|
103
|
+
[options, Mmi::Source::Url.new(options['source'])]
|
104
|
+
end
|
105
|
+
|
106
|
+
if update_asset_version(source)
|
107
|
+
self.processor.parsed_assets.items.push(opts)
|
108
|
+
self.processor.parsed_assets.parsed_items.push(source)
|
109
|
+
|
110
|
+
true
|
111
|
+
else
|
112
|
+
CLI::UI.puts('Aborting asset addition. No change will be made.', color: CLI::UI::Color::RED)
|
113
|
+
|
114
|
+
false
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def update_asset_version(asset)
|
119
|
+
case asset
|
120
|
+
when Mmi::Source::Github
|
121
|
+
github_releases = Mmi::GithubApi.client.releases("#{asset.owner}/#{asset.repo}")
|
122
|
+
|
123
|
+
github_release = CLI::UI::Prompt.ask('Choose a release.') do |handler|
|
124
|
+
github_releases.select do |release|
|
125
|
+
release.assets.any?
|
126
|
+
end.each do |release|
|
127
|
+
handler.option(release.name) do
|
128
|
+
release
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
handler.option('quit', &:to_sym)
|
133
|
+
end
|
134
|
+
|
135
|
+
case github_release
|
136
|
+
when :quit
|
137
|
+
false
|
138
|
+
else
|
139
|
+
release_asset = CLI::UI::Prompt.ask('Choose an asset.') do |handler|
|
140
|
+
github_release.assets.each do |a|
|
141
|
+
handler.option(a.name) do
|
142
|
+
a
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
handler.option('quit', &:to_sym)
|
147
|
+
end
|
148
|
+
|
149
|
+
case release_asset
|
150
|
+
when :quit
|
151
|
+
false
|
152
|
+
else
|
153
|
+
asset.release = nil
|
154
|
+
asset.file = nil
|
155
|
+
|
156
|
+
asset.asset_id = release_asset.id
|
157
|
+
|
158
|
+
true
|
159
|
+
end
|
160
|
+
end
|
161
|
+
when Mmi::Source::Modrinth
|
162
|
+
mod_version = CLI::UI::Prompt.ask('Choose a version.') do |handler|
|
163
|
+
asset.cached_mod_versions.select do |version|
|
164
|
+
version['files'].any?
|
165
|
+
end.each do |version|
|
166
|
+
handler.option("#{version['name']} (for game versions #{version['game_versions'].join('/')})") do
|
167
|
+
version
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
handler.option('quit', &:to_sym)
|
172
|
+
end
|
173
|
+
|
174
|
+
case mod_version
|
175
|
+
when :quit
|
176
|
+
false
|
177
|
+
else
|
178
|
+
version_file = CLI::UI::Prompt.ask('Choose a version file.') do |handler|
|
179
|
+
mod_version['files'].each do |file|
|
180
|
+
handler.option(file['filename']) do
|
181
|
+
file
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
handler.option('quit', &:to_sym)
|
186
|
+
end
|
187
|
+
|
188
|
+
case version_file
|
189
|
+
when :quit
|
190
|
+
false
|
191
|
+
else
|
192
|
+
asset.version = mod_version['name']
|
193
|
+
asset.version_file = version_file['filename']
|
194
|
+
|
195
|
+
true
|
196
|
+
end
|
197
|
+
end
|
198
|
+
when Mmi::Source::Url
|
199
|
+
asset.url = CLI::UI::Prompt.ask('What is the URL of the file that should be downloaded?', default: asset.url).strip
|
200
|
+
else
|
201
|
+
CLI::UI.puts('This asset cannot be updated.', color: CLI::UI::Color::RED)
|
202
|
+
|
203
|
+
false
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'cli/ui'
|
2
|
+
|
3
|
+
require 'mmi/modloader/fabric'
|
4
|
+
require 'mmi/modloader/none'
|
5
|
+
|
6
|
+
module Mmi
|
7
|
+
module Interactive
|
8
|
+
module Modloader
|
9
|
+
def update_modloader
|
10
|
+
choice = CLI::UI::Prompt.ask('What do you want to do?') do |handler|
|
11
|
+
[
|
12
|
+
(["Update current modloader #{self.processor.modloader['name']}", :update_current] unless self.processor.parsed_modloader.is_a?(Mmi::Modloader::None)),
|
13
|
+
['quit', :quit ],
|
14
|
+
].each do |name, result|
|
15
|
+
handler.option(name) do
|
16
|
+
result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
case choice
|
22
|
+
when :update_current
|
23
|
+
update_modloader_current
|
24
|
+
when :quit
|
25
|
+
# Pass.
|
26
|
+
else
|
27
|
+
raise 'Consider yourself lucky, you found a bug.'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_modloader_current
|
32
|
+
ml = self.processor.parsed_modloader
|
33
|
+
|
34
|
+
case ml
|
35
|
+
when Mmi::Modloader::None
|
36
|
+
CLI::UI.puts('There is currently no modloader set, please choose one first.', color: CLI::UI::Color::RED)
|
37
|
+
when Mmi::Modloader::Fabric
|
38
|
+
loop do
|
39
|
+
choice = CLI::UI::Prompt.ask('What do you want to update?') do |handler|
|
40
|
+
[
|
41
|
+
['Installer version', :version ],
|
42
|
+
['Minecraft version', :mc_version ],
|
43
|
+
['Download Minecraft?', :download_mc ],
|
44
|
+
['Install directory', :install_dir ],
|
45
|
+
['Install type', :install_type],
|
46
|
+
['quit', :quit ],
|
47
|
+
].each do |name, result|
|
48
|
+
handler.option(name) do
|
49
|
+
result
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
case choice
|
55
|
+
when :version
|
56
|
+
choice2 = CLI::UI::Prompt.ask('Choose a fabric installer version') do |handler|
|
57
|
+
ml.available_versions.sort.reverse.each do |v|
|
58
|
+
handler.option(v, &:itself)
|
59
|
+
end
|
60
|
+
|
61
|
+
handler.option('quit', &:to_sym)
|
62
|
+
end
|
63
|
+
|
64
|
+
case choice2
|
65
|
+
when :quit
|
66
|
+
# Pass.
|
67
|
+
else
|
68
|
+
ml.version = choice2
|
69
|
+
end
|
70
|
+
when :mc_version
|
71
|
+
choice2 =
|
72
|
+
begin
|
73
|
+
CLI::UI::Prompt.ask('Which Minecraft version do you need?')
|
74
|
+
rescue Interrupt
|
75
|
+
:quit
|
76
|
+
end
|
77
|
+
|
78
|
+
case choice2
|
79
|
+
when :quit
|
80
|
+
# Pass.
|
81
|
+
else
|
82
|
+
ml.mcversion = choice2
|
83
|
+
end
|
84
|
+
when :download_mc
|
85
|
+
choice2 =
|
86
|
+
begin
|
87
|
+
CLI::UI::Prompt.confirm('Download minecraft when installing the modloader? (Ctrl+C for no change)', default: ml.download_mc)
|
88
|
+
rescue Interrupt
|
89
|
+
:quit
|
90
|
+
end
|
91
|
+
|
92
|
+
case choice2
|
93
|
+
when :quit
|
94
|
+
# Pass.
|
95
|
+
else
|
96
|
+
ml.download_mc = choice2
|
97
|
+
end
|
98
|
+
when :install_dir
|
99
|
+
choice2 =
|
100
|
+
begin
|
101
|
+
CLI::UI::Prompt.ask('In which directory should the modloader be installed? ', is_file: true)
|
102
|
+
rescue Interrupt
|
103
|
+
:quit
|
104
|
+
end
|
105
|
+
|
106
|
+
case choice2
|
107
|
+
when :quit
|
108
|
+
# Pass.
|
109
|
+
else
|
110
|
+
ml.install_dir = choice2.strip.empty? ? nil : choice2
|
111
|
+
end
|
112
|
+
when :install_type
|
113
|
+
choice2 = CLI::UI::Prompt.ask('What type of installation do you want?') do |handler|
|
114
|
+
ml.allowed_install_types.each do |type|
|
115
|
+
handler.option(type, &:itself)
|
116
|
+
end
|
117
|
+
|
118
|
+
handler.option('quit', &:to_sym)
|
119
|
+
end
|
120
|
+
|
121
|
+
case choice2
|
122
|
+
when :quit
|
123
|
+
# Pass.
|
124
|
+
else
|
125
|
+
ml.install_type = choice2
|
126
|
+
end
|
127
|
+
when :quit
|
128
|
+
break
|
129
|
+
else
|
130
|
+
raise 'Consider yourself lucky, you found a bug.'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
else
|
134
|
+
CLI::UI.puts("Modloader #{self.processor.modloader['name']} is not supported.", color: CLI::UI::Color::RED)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|