wonko_the_sane 0.1.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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/bin/wonko_the_sane +91 -0
  3. data/data/minecraft.json +668 -0
  4. data/data/mods.json +2475 -0
  5. data/data/sources.json +427 -0
  6. data/data/timestamps.json +13 -0
  7. data/lib/wonko_the_sane.rb +66 -0
  8. data/lib/wonko_the_sane/input/base_input.rb +55 -0
  9. data/lib/wonko_the_sane/input/forge_installer_profile_input.rb +134 -0
  10. data/lib/wonko_the_sane/input/forgefiles_mods_input.rb +30 -0
  11. data/lib/wonko_the_sane/input/jenkins_input.rb +46 -0
  12. data/lib/wonko_the_sane/input/mojang_input.rb +214 -0
  13. data/lib/wonko_the_sane/reader_writer.rb +163 -0
  14. data/lib/wonko_the_sane/registry.rb +61 -0
  15. data/lib/wonko_the_sane/rules.rb +69 -0
  16. data/lib/wonko_the_sane/timestamps.rb +30 -0
  17. data/lib/wonko_the_sane/tools/update_nem.rb +85 -0
  18. data/lib/wonko_the_sane/util/configuration.rb +35 -0
  19. data/lib/wonko_the_sane/util/deep_storage_cache.rb +65 -0
  20. data/lib/wonko_the_sane/util/extraction_cache.rb +30 -0
  21. data/lib/wonko_the_sane/util/file_hash_cache.rb +42 -0
  22. data/lib/wonko_the_sane/util/http_cache.rb +143 -0
  23. data/lib/wonko_the_sane/util/maven_identifier.rb +39 -0
  24. data/lib/wonko_the_sane/util/task_stack.rb +21 -0
  25. data/lib/wonko_the_sane/version.rb +3 -0
  26. data/lib/wonko_the_sane/version_index.rb +33 -0
  27. data/lib/wonko_the_sane/version_parser.rb +115 -0
  28. data/lib/wonko_the_sane/versionlists/base_version_list.rb +103 -0
  29. data/lib/wonko_the_sane/versionlists/curse_version_list.rb +52 -0
  30. data/lib/wonko_the_sane/versionlists/forge_version_list.rb +142 -0
  31. data/lib/wonko_the_sane/versionlists/forgefiles_mods_list.rb +24 -0
  32. data/lib/wonko_the_sane/versionlists/jenkins_version_list.rb +29 -0
  33. data/lib/wonko_the_sane/versionlists/liteloader_version_list.rb +66 -0
  34. data/lib/wonko_the_sane/versionlists/vanilla_legacy_version_list.rb +39 -0
  35. data/lib/wonko_the_sane/versionlists/vanilla_version_list.rb +35 -0
  36. data/lib/wonko_the_sane/wonko_version.rb +184 -0
  37. metadata +324 -0
@@ -0,0 +1,55 @@
1
+ class BaseInput
2
+ def logger
3
+ Logging.logger[@artifact]
4
+ end
5
+ end
6
+
7
+ class BaseSanitizer
8
+ def self.sanitize(file)
9
+ raise :AbstractMethodCallError
10
+ end
11
+
12
+ def self.sanitize(input, *sanitizers)
13
+ output = [input]
14
+ sanitizers.each do |sanitizer|
15
+ tmp = []
16
+ output.each do |file|
17
+ #puts "Running #{sanitizer.to_s} on #{file.id}"
18
+ result = sanitizer.sanitize(file.clone)
19
+ if result.is_a? Array
20
+ tmp = tmp + result
21
+ elsif not result.nil?
22
+ tmp << result
23
+ end
24
+ end
25
+ output = tmp
26
+ end
27
+ return output
28
+ end
29
+ end
30
+
31
+ class DownloadsFixer < BaseSanitizer
32
+ def self.sanitize(file)
33
+ file.client.downloads.map! do |download|
34
+ if not download.size or not download.sha256 or download.sha256 == ''
35
+ url = download.internalUrl ? download.internalUrl : download.url
36
+ info = WonkoTheSane::Util::DeepStorageCache.get_info url, ctxt: file.uid
37
+ download.size = info[:size]
38
+ download.sha256 = info[:sha256]
39
+ download
40
+ end
41
+ download
42
+ end
43
+ file.server.downloads.map! do |download|
44
+ if not download.size or not download.sha256 or download.sha256 == ''
45
+ url = download.internalUrl ? download.internalUrl : download.url
46
+ info = WonkoTheSane::Util::DeepStorageCache.get_info url, ctxt: file.uid
47
+ download.size = info[:size]
48
+ download.sha256 = info[:sha256]
49
+ download
50
+ end
51
+ download
52
+ end
53
+ file
54
+ end
55
+ end
@@ -0,0 +1,134 @@
1
+ class ForgeInstallerProfileInput < BaseInput
2
+ def initialize(artifact)
3
+ @artifact = artifact
4
+ end
5
+
6
+ def parse(data, version)
7
+ object = JSON.parse data, symbolize_names: true
8
+ info = object[:versionInfo]
9
+ file = WonkoVersion.new
10
+
11
+ file.uid = @artifact
12
+ file.version = version
13
+ file.time = info[:time]
14
+ file.type = info[:type]
15
+ file.client.mainClass = info[:mainClass]
16
+ file.client.minecraftArguments = info[:minecraftArguments]
17
+ file.client.assets = info[:assets]
18
+ file.requires << Referenced.new('net.minecraft', object[:install][:minecraft])
19
+ libraries = info[:libraries].map do |obj|
20
+ MojangInput.sanetize_mojang_library obj
21
+ end.flatten 1
22
+ file.client.downloads = libraries
23
+ file.common.folders['minecraft/mods'] = ['mc.forgemods']
24
+ file.common.folders['minecraft/mods'] << 'mc.forgecoremods' if object[:install][:minecraft].match /[^1]*1\.[0-6]/
25
+ file.common.folders['minecraft/coremods'] = ['mc.forgecoremods'] if object[:install][:minecraft].match /[^1]*1\.[0-6]/
26
+ file.server.downloads = libraries
27
+ file.server.launchMethod = 'java.mainClass'
28
+ file.server.extra[:forgeLibraryName] = %W(net.minecraftforge:forge:#{object[:install][:minecraft]}-#{version}:universal net.minecraftforge:forge:#{object[:install][:minecraft]}-#{version} net.minecraftforge:forge:#{version}:universal net.minecraftforge:forge:#{version} net.minecraftforge:minecraftforge:#{object[:install][:minecraft]}-#{version}:universal net.minecraftforge:minecraftforge:#{object[:install][:minecraft]}-#{version} net.minecraftforge:minecraftforge:#{version}:universal net.minecraftforge:minecraftforge:#{version})
29
+
30
+ return BaseSanitizer.sanitize file, MojangExtractTweakersSanitizer, MojangSplitLWJGLSanitizer, ForgeRemoveMinecraftSanitizer, ForgeFixJarSanitizer, ForgePackXZUrlsSanitizer, ForgeServerMainClassSanitizer
31
+ end
32
+ end
33
+
34
+ class ForgeFixJarSanitizer < BaseSanitizer
35
+ def self.sanitize(file)
36
+ file.client.downloads.map! do |lib|
37
+ ident = WonkoTheSane::Util::MavenIdentifier.new(lib.name)
38
+ ident.artifact = 'forge' if 'net.minecraftforge' == ident.group && 'minecraftforge' == ident.artifact
39
+ if ['forge', 'fml'].include?(ident.artifact) && ['net.minecraftforge', 'cpw.mods'].include?(ident.group)
40
+ mcversion = nil
41
+ file.requires.each do |req|
42
+ if req.uid == 'net.minecraft'
43
+ mcversion = req.version
44
+ end
45
+ end
46
+ lib = lib.clone
47
+ ident.classifier = 'universal'
48
+ ident.version = "#{mcversion}-#{ident.version}" unless ident.version.start_with? "#{mcversion}"
49
+ lib.name = ident.to_name()
50
+ end
51
+ lib
52
+ end
53
+ file
54
+ end
55
+ end
56
+
57
+ # Removes minecraft stuff (libraries, arguments etc.)
58
+ class ForgeRemoveMinecraftSanitizer < BaseSanitizer
59
+ def self.sanitize(file)
60
+ return nil if file.uid == 'org.lwjgl' # remove lwjgl, it's managed by minecraft
61
+ return file if file.uid != 'net.minecraftforge'
62
+ mcversion = nil
63
+ file.requires.each do |req|
64
+ if req.uid == 'net.minecraft'
65
+ mcversion = req.version
66
+ end
67
+ end
68
+ minecraft = Registry.instance.retrieve 'net.minecraft', mcversion
69
+ if not minecraft
70
+ # if we can't find the wanted version on the first try we try reloading the list to see if we get something
71
+ WonkoTheSane.lists.each do |list|
72
+ list.refresh if list.artifact == 'net.minecraft'
73
+ end
74
+ minecraft = Registry.instance.retrieve 'net.minecraft', mcversion
75
+ end
76
+ if minecraft
77
+ file.client.mainClass = nil if minecraft.client.mainClass == file.client.mainClass
78
+ file.client.minecraftArguments = nil if minecraft.client.minecraftArguments == file.client.minecraftArguments
79
+ file.client.assets = nil if minecraft.client.assets == file.client.assets
80
+ file.client.downloads.select! do |lib|
81
+ nil == minecraft.client.downloads.find do |mcLib|
82
+ lib.name == mcLib.name
83
+ end
84
+ end
85
+ file.requires.select! do |req|
86
+ if minecraft.requires
87
+ nil == minecraft.requires.find do |mcReq|
88
+ req == mcReq
89
+ end
90
+ else
91
+ true
92
+ end
93
+ end
94
+ else
95
+ # don't know which version of minecraft this is, so we can't know which parts to eliminate
96
+ end
97
+ file
98
+ end
99
+ end
100
+
101
+ class ForgePackXZUrlsSanitizer < BaseSanitizer
102
+ @@packXZLibs = ['org.scala-lang', 'com.typesafe', 'com.typesafe.akka']
103
+
104
+ def self.sanitize(file)
105
+ file.client.downloads.map! do |lib|
106
+ if @@packXZLibs.include? WonkoTheSane::Util::MavenIdentifier.new(lib.name).group
107
+ lib = lib.clone
108
+ lib.mavenBaseUrl = 'http://repo.spongepowered.org/maven/'
109
+ end
110
+ lib
111
+ end
112
+ file
113
+ end
114
+ end
115
+
116
+ class ForgeServerMainClassSanitizer < BaseSanitizer
117
+ def self.sanitize(file)
118
+ file.server.downloads.each do |download|
119
+ if file.server.extra[:forgeLibraryName].include? download.name
120
+ url = download.internalUrl ? download.internalUrl : download.url
121
+ libFile = HTTPCache.file(url, ctxt: file.uid, check_stale: false)
122
+ # Handle entries one by one
123
+ text = ExtractionCache.get(libFile, :zip, 'META-INF/MANIFEST.MF')
124
+ lines = text.lines
125
+ lines.each do |l|
126
+ if l =~ /Main-Class: (.*)/
127
+ file.server.mainClass = $1.strip
128
+ end
129
+ end
130
+ end
131
+ end
132
+ file
133
+ end
134
+ end
@@ -0,0 +1,30 @@
1
+ class ForgeFilesModsInput < BaseInput
2
+ def initialize(artifact)
3
+ @artifact = artifact
4
+ end
5
+
6
+ def parse(data, version)
7
+ file = WonkoVersion.new
8
+
9
+ file.uid = @artifact
10
+ file.version = version
11
+ file.time = data[:info]
12
+
13
+ f = data[:files].find do |file|
14
+ type = file[:buildtype].downcase
15
+ (file[:ext] == 'jar' or file[:ext] == 'zip') and (type == 'universal' or type == 'client' or type == 'main') #not type.include? 'src' and not type.include? 'deobf' and not type.include? 'api' and not type.include? 'backup'
16
+ end
17
+ if not f
18
+ logger.warn 'No file found for ' + file.uid + ' version ' + file.version
19
+ return []
20
+ end
21
+ file.requires << Referenced.new('net.minecraft', f[:mcver])
22
+
23
+ dl = FileDownload.new
24
+ dl.url = f[:url]
25
+ dl.destination = "mods/#{file.uid}-#{file.version}.jar"
26
+ file.common.downloads << dl
27
+
28
+ return BaseSanitizer.sanitize file
29
+ end
30
+ end
@@ -0,0 +1,46 @@
1
+ class JenkinsInput < BaseInput
2
+ def initialize(artifact, fileRegex)
3
+ @artifact = artifact
4
+ @fileRegex = fileRegex
5
+ end
6
+
7
+ def parse(data)
8
+ if data[:result] != 'SUCCESS'
9
+ return nil
10
+ end
11
+
12
+ file = WonkoVersion.new
13
+
14
+ file.uid = @artifact
15
+ file.version = data[:number].to_s
16
+ file.time = data[:timestamp]
17
+
18
+ artifact = data[:artifacts].find do |art|
19
+ path = art[:fileName]
20
+ if @fileRegex
21
+ path.match @fileRegex
22
+ else
23
+ not path.include? '-api.' and not path.include? '-deobf.' and not path.include? '-dev.' and not path.include? '-javadoc.' and not path.include? '-library.' and not path.include? '-sources.' and not path.include? '-src.' and not path.include? '-util.'
24
+ end
25
+ end
26
+
27
+ if not artifact
28
+ logger.warn 'No valid artifact found for ' + file.version
29
+ else
30
+ dl = FileDownload.new
31
+ dl.destination = "mods/#{file.uid}-#{file.version}.jar"
32
+ dl.url = "#{clean_url data[:url]}/artifact/#{artifact[:relativePath]}"
33
+ file.common.downloads << dl
34
+ end
35
+
36
+ return BaseSanitizer.sanitize file
37
+ end
38
+
39
+ private
40
+ def clean_url(url)
41
+ if url[url.length - 1] == '/'
42
+ url[url.length - 1] = ''
43
+ end
44
+ return url
45
+ end
46
+ end
@@ -0,0 +1,214 @@
1
+ def allowedPlatformsForRules(rules)
2
+ possible = ['win32', 'win64', 'lin32', 'lin64', 'osx64']
3
+
4
+ allowed = possible
5
+ if rules
6
+ rules.each do |rule|
7
+ if rule.action == :allow
8
+ if rule.is_a? OsRule
9
+ if rule.os == 'windows'
10
+ allowed << 'win32'
11
+ allowed << 'win64'
12
+ elsif rule.os == 'linux'
13
+ allowed << 'lin32'
14
+ allowed << 'lin64'
15
+ elsif rule.os == 'osx'
16
+ allowed << 'osx64'
17
+ end
18
+ elsif rule.is_a? ImplicitRule
19
+ allowed = possible
20
+ end
21
+ elsif rule.action == :disallow
22
+ if rule.is_a? OsRule
23
+ if rule.os == 'windows'
24
+ allowed.delete 'win32'
25
+ allowed.delete 'win64'
26
+ elsif rule.os == 'linux'
27
+ allowed.delete 'lin32'
28
+ allowed.delete 'lin64'
29
+ elsif rule.os == 'osx'
30
+ allowed.delete 'osx64'
31
+ end
32
+ elsif rule.is_a? ImplicitRule
33
+ allowed = []
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ return allowed
40
+ end
41
+
42
+ class MojangInput
43
+ # reads a general mojang-style library
44
+ def self.sanetize_mojang_library(object)
45
+ lib = if object.key? :natives then VersionLibraryNative.new else VersionLibrary.new end
46
+ lib.name = object[:name]
47
+ lib.mavenBaseUrl = object.key?(:url) ? object[:url] : 'https://libraries.minecraft.net/'
48
+
49
+ lib.rules = object[:rules].map do |obj| Rule.from_json obj end if object[:rules]
50
+
51
+ libs = []
52
+ if not lib.is_a? VersionLibraryNative
53
+ libs << lib
54
+ else
55
+ nativeIds = {}
56
+ if object.key? :natives
57
+ natives = object[:natives]
58
+ if natives.key? :windows
59
+ nativeIds['win32'] = natives[:windows].gsub "${arch}", '32'
60
+ nativeIds['win64'] = natives[:windows].gsub "${arch}", '64'
61
+ end
62
+ if natives.key? :linux
63
+ nativeIds['lin32'] = natives[:linux].gsub "${arch}", '32'
64
+ nativeIds['lin64'] = natives[:linux].gsub "${arch}", '64'
65
+ end
66
+ if natives.key? :osx
67
+ nativeIds['osx64'] = natives[:osx].gsub "${arch}", '64'
68
+ end
69
+ end
70
+
71
+ allowedPlatformsForRules(lib.rules).uniq.each do |platform|
72
+ if not nativeIds.key? platform
73
+ next
74
+ end
75
+
76
+ native = lib.clone
77
+ native.rules = [
78
+ ImplicitRule.new(:disallow),
79
+ OsRule.new(:allow,
80
+ {'win32': :windows, 'win64': :windows, 'lin32': :linux, 'lin64': :linux, 'osx64': :osx}[platform.to_sym],
81
+ nil,
82
+ {'win32': '32', 'win64': '64', 'lin32': '32', 'lin64': '64', 'osx64': '64'}[platform.to_sym])
83
+ ]
84
+ native.url = native.url.sub '.jar', ('-' + nativeIds[platform] + '.jar')
85
+ libs << native
86
+ end
87
+ end
88
+
89
+ return libs
90
+ end
91
+
92
+ def initialize(artifact)
93
+ @artifact = artifact
94
+ end
95
+
96
+ def parse(data)
97
+ object = data.class == Hash ? data : JSON.parse(data, symbolize_names: true)
98
+
99
+ if object[:minimumLauncherVersion] and object[:minimumLauncherVersion] > 14
100
+ # TODO log error
101
+ return []
102
+ end
103
+
104
+ file = WonkoVersion.new
105
+
106
+ file.uid = @artifact
107
+ file.version = object[:id]
108
+ file.time = object[:releaseTime]
109
+ file.type = object[:type]
110
+ file.client.mainClass = object[:mainClass]
111
+ file.client.assets = object[:assets]
112
+ file.client.minecraftArguments = object[:minecraftArguments]
113
+ file.client.jarModTarget = "net.minecraft:minecraft:#{file.version}"
114
+ file.client.downloads = object[:libraries].map do |obj|
115
+ MojangInput.sanetize_mojang_library obj
116
+ end.flatten 1
117
+ mainLib = VersionLibrary.new
118
+ mainLib.name = "net.minecraft:minecraft:#{file.version}"
119
+ mainLib.url = 'http://s3.amazonaws.com/Minecraft.Download/versions/' + file.version + '/' + file.version + '.jar'
120
+ file.client.downloads << mainLib
121
+ file.client.launchMethod = 'minecraft'
122
+
123
+ serverLib = VersionLibrary.new
124
+ serverLib.name = "net.minecraft:minecraft_server:#{file.version}"
125
+ serverLib.url = 'http://s3.amazonaws.com/Minecraft.Download/versions/' + file.version + '/minecraft_server.' + file.version + '.jar'
126
+ file.server.downloads << serverLib
127
+ file.server.jarModTarget = "net.minecraft:minecraft_server:#{file.version}"
128
+ file.server.launchMethod = 'java.jar'
129
+
130
+ file.client.folders['minecraft/screenshots'] = ['general.screenshots']
131
+ file.client.folders['minecraft/resourcepackks'] = ['mc.resourcepacks'] if file.time >= 1372430921
132
+ file.client.folders['minecraft/texturepacks'] = ['mc.texturepacks'] if file.time < 1372430921
133
+ file.client.folders['minecraft/saves'] = ['mc.saves.anvil'] if file.time >= 1330552800
134
+ file.client.folders['minecraft/saves'] = ['mc.saves.region'] if file.time >= 1298325600 and file.time < 1330552800
135
+ file.client.folders['minecraft/saves'] = ['mc.saves.infdev'] if file.time >= 1291327200 and file.time < 1298325600
136
+
137
+ return BaseSanitizer.sanitize file, MojangSplitLWJGLSanitizer
138
+ end
139
+ end
140
+
141
+ class MojangExtractTweakersSanitizer < BaseSanitizer
142
+ def self.sanitize(file)
143
+ file.client.tweakers = file.client.minecraftArguments.scan(/--tweakClass ([^ ]*)/).flatten
144
+ file.client.minecraftArguments = file.client.minecraftArguments.gsub /\ ?--tweakClass ([^ ]*)/, ''
145
+ return file
146
+ end
147
+ end
148
+
149
+ # extract lwjgl specific libraries and natives
150
+ class MojangSplitLWJGLSanitizer < BaseSanitizer
151
+ @@lwjglList = ['org.lwjgl', 'net.java.jinput', 'net.java.jutils']
152
+ @@lwjglExtras = ['net.java.jinput', 'net.java.jutils']
153
+
154
+ def self.sanitize(file)
155
+ file.requires = [] if file.requires.nil?
156
+ file.requires << Referenced.new('org.lwjgl')
157
+
158
+ extras = [] # [Download]
159
+ versioned = {} # String => [Download]
160
+ file.client.downloads.select! do |lib|
161
+ nil == @@lwjglList.find do |lwjglCandidate|
162
+ if lib.name.include? lwjglCandidate
163
+ if @@lwjglExtras.include? lib.maven.group
164
+ extras << lib
165
+ else
166
+ versioned[lib.maven.version] ||= []
167
+ versioned[lib.maven.version] << lib
168
+ end
169
+ true
170
+ else
171
+ false
172
+ end
173
+ end
174
+ end
175
+
176
+ files = [file]
177
+ versioned.each do |version, downloads|
178
+ lwjgl = WonkoVersion.new
179
+ lwjgl.uid = 'org.lwjgl'
180
+ lwjgl.type = 'release'
181
+ lwjgl.version = version
182
+ lwjgl.time = nil # re-fetches the time for the version from storage
183
+ lwjgl.client.downloads = extras + downloads
184
+ files << lwjgl
185
+ end
186
+
187
+ return files
188
+ end
189
+ end
190
+
191
+ class MojangTraitsSanitizer < BaseSanitizer
192
+ def self.sanitize(file)
193
+ if file.uid == 'net.minecraft'
194
+ end
195
+ file
196
+ end
197
+ end
198
+
199
+ class MojangProcessArgumentsSanitizer < BaseSanitizer
200
+ def self.sanitize(file)
201
+ if file.client.extra[:processArguments]
202
+ case file.client.extra[:processArguments]
203
+ when 'legacy'
204
+ file.client.minecraftArguments = ' ${auth_player_name} ${auth_session}'
205
+ when 'username_session'
206
+ file.client.minecraftArguments = '--username ${auth_player_name} --session ${auth_session}'
207
+ when 'username_session_version'
208
+ file.client.minecraftArguments = '--username ${auth_player_name} --session ${auth_session} --version ${profile_name}'
209
+ end
210
+ file.client.extra.delete :processArguments
211
+ end
212
+ file
213
+ end
214
+ end