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,103 @@
1
+ class BaseVersionList
2
+ attr_accessor :artifact
3
+ # @processed contains a list of version ids for all versions that have been processed. simply clear it to invalidate caches
4
+ attr_accessor :processed
5
+ attr_accessor :lastError
6
+
7
+ def initialize(artifact)
8
+ @artifact = artifact
9
+ if File.exist? cache_file
10
+ data = JSON.parse File.read(cache_file), symbolize_names: true
11
+ @processed = data[:versions] ? data[:versions] : []
12
+ @lastError = data[:lastError]
13
+ else
14
+ @processed = []
15
+ @lastError = nil
16
+ end
17
+ end
18
+
19
+ def refresh
20
+ @lastError = nil
21
+ begin
22
+ versions = get_versions
23
+
24
+ # check if some versions aren't in @processed (likely new ones) and fetch and process them
25
+ versions.each do |version|
26
+ begin
27
+ next if not version
28
+ id = version.is_a?(Array) ? version.first : version
29
+ unless @processed.include? id
30
+ files = get_version version
31
+ next if files.nil? or (files.is_a? Array and files.empty?)
32
+
33
+ files.flatten.each do |file|
34
+ file.is_complete = true
35
+ Registry.instance.store file
36
+ end if files and files.is_a? Array
37
+ files.is_complete = true if files and files.is_a? WonkoVersion
38
+ Registry.instance.store files if files and files.is_a? WonkoVersion
39
+
40
+ @processed << id
41
+ write_cache_file
42
+ end
43
+ rescue => e
44
+ logger.error e.message
45
+ logger.warn e.backtrace.first
46
+ binding.pry if $stdout.isatty && ENV['DEBUG_ON_ERROR']
47
+ @lastError = e.message
48
+ end
49
+ end
50
+
51
+ FileUtils.touch cache_file
52
+ end
53
+ end
54
+
55
+ def logger
56
+ Logging.logger[@artifact]
57
+ end
58
+
59
+ def invalidate(version = nil)
60
+ if version
61
+ @processed.remove version
62
+ else
63
+ @processed = []
64
+ end
65
+ write_cache_file
66
+ end
67
+
68
+ def last_modified
69
+ if File.exist? cache_file
70
+ File.mtime cache_file
71
+ else
72
+ nil
73
+ end
74
+ end
75
+
76
+ def write_cache_file
77
+ File.write cache_file, JSON.pretty_generate({
78
+ versions: @processed,
79
+ lastError: @lastError
80
+ })
81
+ end
82
+
83
+ def cache_file
84
+ 'cache/' + @artifact + '.json'
85
+ end
86
+
87
+ def get_versions
88
+ raise :AbstractMethodCallError
89
+ end
90
+
91
+ def get_version(id)
92
+ raise :AbstractMethodCallError
93
+ end
94
+
95
+ def get_json(url)
96
+ JSON.parse HTTPCache.file(url, ctxt: @artifact, check_stale: true), symbolize_names: true
97
+ end
98
+
99
+ def get_json_cached(url)
100
+ JSON.parse HTTPCache.file(url, ctxt: @artifact, check_stale: false), symbolize_names: true
101
+ end
102
+ end
103
+ Dir.mkdir 'cache' unless Dir.exist? 'cache'
@@ -0,0 +1,52 @@
1
+ require_relative 'base_version_list'
2
+ require 'date'
3
+ require 'time'
4
+
5
+ class CurseVersionList < BaseVersionList
6
+ def initialize(uid, curseId, fileRegex)
7
+ super(uid)
8
+ @curseId = curseId
9
+ @fileRegex = fileRegex.gsub /\?P\</, '?<'
10
+ end
11
+
12
+ def get_versions
13
+ result = Oga.parse_html HTTPCache.file('http://curse.com/project/' + @curseId, ctxt: @artifact, key: 'curse/' + @curseId + '.html', check_stale: false)
14
+ # start by getting rid of some elements that standard xml parsers have issues with
15
+ result.each_node do |node| node.remove if node.is_a? Oga::XML::Element and ['script', 'like'].include? node.name end
16
+ rows = result.xpath("html/body/#{'div/' * 14}table/tbody/tr")
17
+
18
+ return rows.map do |row|
19
+ match = row.xpath('td/a/text()').first.text.match @fileRegex
20
+ next if not match
21
+ version = match[:version]
22
+ [
23
+ version,
24
+ {
25
+ url: row.xpath('td/a/@href').first.value,
26
+ fileId: row.xpath('td/a/text()').first.text,
27
+ type: row.xpath('td[2]/text()').first.text,
28
+ mcVersion: row.xpath('td[3]/text()').first.text,
29
+ timestamp: row.xpath('td[5]/@data-sort-value').first.value.to_i / 1000,
30
+ version: version
31
+ }
32
+ ]
33
+ end
34
+ end
35
+
36
+ def get_version(id)
37
+ urlId = id[1][:url].match(/\/(\d*)$/)[1]
38
+ dl = FileDownload.new
39
+ dl.internalUrl = "http://addons-origin.cursecdn.com/files/#{urlId[0...4]}/#{urlId[4...7]}/#{id[1][:fileId]}"
40
+ dl.url = "http://curse.com" + id[1][:url]
41
+ dl.destination = "mods/#{@artifact}-#{id.first}.jar"
42
+
43
+ file = WonkoVersion.new
44
+ file.uid = @artifact
45
+ file.version = id.first
46
+ file.type = id[1][:type]
47
+ file.time = id[1][:timestamp]
48
+ file.requires << Referenced.new('net.minecraft', id[1][:mcVersion])
49
+ file.common.downloads << dl
50
+ return BaseSanitizer.sanitize file
51
+ end
52
+ end
@@ -0,0 +1,142 @@
1
+ require_relative 'base_version_list'
2
+
3
+ def fml_libs_mappings
4
+ def create_fmllib_download(file, forge_has = true)
5
+ forge_base_url = 'http://files.minecraftforge.net/fmllibs/'
6
+ multimc_base_url = 'http://files.multimc.org/fmllibs/'
7
+
8
+ FileDownload.new (forge_has ? forge_base_url : multimc_base_url) + file, 'minecraft/lib/' + file
9
+ end
10
+
11
+ libs14 = [
12
+ create_fmllib_download('argo-2.25.jar'),
13
+ create_fmllib_download('guava-12.0.1.jar'),
14
+ create_fmllib_download('asm-all-4.0.jar'),
15
+ create_fmllib_download('bcprov-jdk15on-147.jar')
16
+ ]
17
+
18
+ {
19
+ '1.3.2' => [
20
+ create_fmllib_download('argo-2.25.jar'),
21
+ create_fmllib_download('guava-12.0.1.jar'),
22
+ create_fmllib_download('asm-all-4.0.jar')
23
+ ],
24
+ '1.4' => libs14,
25
+ '1.4.1' => libs14,
26
+ '1.4.2' => libs14,
27
+ '1.4.3' => libs14,
28
+ '1.4.4' => libs14,
29
+ '1.4.5' => libs14,
30
+ '1.4.6' => libs14,
31
+ '1.4.7' => libs14,
32
+ '1.5' => [
33
+ create_fmllib_download('argo-small-3.2.jar'),
34
+ create_fmllib_download('guava-14.0-rc3.jar'),
35
+ create_fmllib_download('asm-all-4.1.jar'),
36
+ create_fmllib_download('bcprov-jdk15on-148.jar', false),
37
+ create_fmllib_download('deobfuscation_data_1.5.zip'),
38
+ create_fmllib_download('scala-library.jar', false)
39
+ ],
40
+ '1.5.1' => [
41
+ create_fmllib_download('argo-small-3.2.jar'),
42
+ create_fmllib_download('guava-14.0-rc3.jar'),
43
+ create_fmllib_download('asm-all-4.1.jar'),
44
+ create_fmllib_download('bcprov-jdk15on-148.jar', false),
45
+ create_fmllib_download('deobfuscation_data_1.5.1.zip'),
46
+ create_fmllib_download('scala-library.jar', false)
47
+ ],
48
+ '1.5.2' => [
49
+ create_fmllib_download('argo-small-3.2.jar'),
50
+ create_fmllib_download('guava-14.0-rc3.jar'),
51
+ create_fmllib_download('asm-all-4.1.jar'),
52
+ create_fmllib_download('bcprov-jdk15on-148.jar', false),
53
+ create_fmllib_download('deobfuscation_data_1.5.2.zip'),
54
+ create_fmllib_download('scala-library.jar', false)
55
+ ]
56
+ }
57
+ end
58
+
59
+ class ForgeVersionList < BaseVersionList
60
+ def initialize(artifact = 'net.minecraftforge', url_id = 'forge')
61
+ super(artifact)
62
+ @input = ForgeInstallerProfileInput.new artifact
63
+ @url_id = url_id
64
+ end
65
+
66
+ def get_versions
67
+ result = get_json "http://files.minecraftforge.net/maven/net/minecraftforge/#{@url_id}/json"
68
+
69
+ out = {}
70
+ result[:number].values.each do |obj|
71
+ out[obj[:build]] = obj.merge({
72
+ artifact: result[:artifact],
73
+ baseurl: result[:webpath]
74
+ })
75
+ end
76
+ return out
77
+ end
78
+
79
+ def get_version(id)
80
+ version = id[1][:mcversion] + '-' + id[1][:version]
81
+ version += '-' + id[1][:branch] unless id[1][:branch].nil?
82
+
83
+ result = []
84
+
85
+ files = id[1][:files]
86
+ installerFile = files.find do |file| file[1] == 'installer' end
87
+ universalFile = files.find do |file| file[1] == 'universal' end
88
+ clientFile = files.find do |file| file[1] == 'client' end
89
+ serverFile = files.find do |file| file[1] == 'server' end
90
+
91
+ # installer versions of forge
92
+ if not installerFile.nil? and id[1][:mcversion] != '1.5.2'
93
+ path = "#{version}/#{id[1][:artifact]}-#{version}-#{installerFile[1]}.#{installerFile[0]}"
94
+ url = id[1][:baseurl] + '/' + path
95
+ HTTPCache.get url, ctxt: @artifact, key: 'forgeinstallers/' + path, check_stale: false
96
+ result << @input.parse(ExtractionCache.get('cache/network/forgeinstallers/' + path, :zip, 'install_profile.json'), id[1][:version])
97
+ elsif not universalFile.nil?
98
+ res = construct_base_version id[1]
99
+ mod = Jarmod.new
100
+ mod.name = "net.minecraftforge:#{id[1][:artifact]}:#{version}:universal@#{universalFile[0]}"
101
+ mod.mavenBaseUrl = 'http://files.minecraftforge.net/maven/'
102
+ res.client.downloads << mod
103
+ res.client.downloads |= fml_libs_mappings[id[1][:mcversion]] if fml_libs_mappings[id[1][:mcversion]]
104
+ result << res
105
+ else
106
+ unless clientFile.nil?
107
+ res = construct_base_version id[1]
108
+ mod = Jarmod.new
109
+ mod.name = "net.minecraftforge:#{id[1][:artifact]}:#{version}:client@#{clientFile[0]}"
110
+ mod.mavenBaseUrl = 'http://files.minecraftforge.net/maven/'
111
+ res.client.downloads << mod
112
+ res.client.downloads |= fml_libs_mappings[id[1][:mcversion]] if fml_libs_mappings[id[1][:mcversion]]
113
+ result << res
114
+ end
115
+ unless serverFile.nil?
116
+
117
+ end
118
+ end
119
+ return result.flatten
120
+ end
121
+
122
+ def construct_base_version(data)
123
+ version = WonkoVersion.new
124
+ version.uid = @artifact
125
+ version.version = data[:version]
126
+ version.requires << Referenced.new('net.minecraft', data[:mcversion])
127
+ version.time = data[:modified]
128
+ version.client.minecraftArguments = [
129
+ '-Dfml.ignoreInvalidMinecraftCertificates=true', '-Dfml.ignorePatchDiscrepancies=true'
130
+ ]
131
+ version.common.folders['minecraft/mods'] = ['mc.forgemods']
132
+ version.common.folders['minecraft/mods'] << 'mc.forgecoremods' if data[:mcversion].match /[^1]*1\.[0-6]/
133
+ version.common.folders['minecraft/coremods'] = ['mc.forgecoremods'] if data[:mcversion].match /[^1]*1\.[0-6]/
134
+ version
135
+ end
136
+ end
137
+
138
+ class FMLVersionList < ForgeVersionList
139
+ def initialize
140
+ super('net.minecraftforge.fml', 'fml')
141
+ end
142
+ end
@@ -0,0 +1,24 @@
1
+ require 'pry'
2
+
3
+ class ForgeFilesModsList < BaseVersionList
4
+ def initialize(artifact, urlId)
5
+ super(artifact)
6
+ @urlId = urlId
7
+ @input = ForgeFilesModsInput.new(artifact)
8
+ end
9
+
10
+ def get_versions
11
+ result = get_json "http://files.minecraftforge.net/#{@urlId}/json"
12
+
13
+ return result[:builds].map do |build|
14
+ [
15
+ build[:version],
16
+ build
17
+ ]
18
+ end
19
+ end
20
+
21
+ def get_version(id)
22
+ @input.parse id[1], id[0]
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ require 'pry'
2
+
3
+ class JenkinsVersionList < BaseVersionList
4
+ def initialize(artifact, baseUrl, job, fileRegex)
5
+ super(artifact)
6
+ @baseUrl = baseUrl
7
+ @job = job
8
+ @input = JenkinsInput.new(artifact, fileRegex)
9
+
10
+ if @baseUrl[@baseUrl.length - 1] == '/'
11
+ @baseUrl[@baseUrl.length - 1] = ''
12
+ end
13
+ end
14
+
15
+ def get_versions
16
+ result = get_json "#{@baseUrl}/job/#{@job}/api/json"
17
+
18
+ return result[:builds].map do |build|
19
+ [
20
+ build[:number],
21
+ build[:url]
22
+ ]
23
+ end
24
+ end
25
+
26
+ def get_version(id)
27
+ @input.parse get_json_cached id[1] + 'api/json'
28
+ end
29
+ end
@@ -0,0 +1,66 @@
1
+ require_relative 'base_version_list'
2
+ require 'date'
3
+ require 'time'
4
+
5
+ class LiteLoaderVersionList < BaseVersionList
6
+ def initialize
7
+ super('com.mumfrey.liteloader')
8
+ end
9
+
10
+ def get_versions
11
+ result = get_json 'http://dl.liteloader.com/versions/versions.json'
12
+
13
+ out = []
14
+ result[:versions].each do |mcver|
15
+ minecraft = mcver.first
16
+ mcver[1][:artefacts].each do |artefact|
17
+ if artefact.first == :'com.mumfrey:liteloader'
18
+ latest = nil
19
+ artefact[1].each do |item|
20
+ if item.first == 'latest'
21
+ latest = item[1][:version]
22
+ break
23
+ end
24
+ end
25
+ artefact[1].each do |item|
26
+ if item.first != 'latest'
27
+ out << [
28
+ item[1][:version],
29
+ item[1].merge({
30
+ minecraft: minecraft.to_s,
31
+ type: latest == item[1][:version] ? 'latest' : nil
32
+ })
33
+ ]
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ return out
40
+ end
41
+
42
+ def get_version(id)
43
+ liteloaderLib = VersionLibrary.new
44
+ liteloaderLib.name = 'com.mumfrey:liteloader:' + id[1][:version]
45
+ liteloaderLib.url = 'http://dl.liteloader.com/versions/com/mumfrey/liteloader/' + id[1][:minecraft] + '/' + id[1][:file]
46
+
47
+ file = WonkoVersion.new
48
+ file.uid = 'com.mumfrey.liteloader'
49
+ file.version = id.first
50
+ file.type = 'release' # id[1][:type]
51
+ file.time = id[1][:timestamp]
52
+ file.requires << Referenced.new('net.minecraft', id[1][:minecraft])
53
+ file.client.tweakers = [ id[1][:tweakClass] ]
54
+ file.client.mainClass = 'net.minecraft.launchwrapper.Launch'
55
+ file.client.downloads = id[1][:libraries].map do |lib|
56
+ libs = MojangInput.sanetize_mojang_library lib
57
+ if lib[:name] == 'org.ow2.asm:asm-all:5.0.3'
58
+ libs[0].mavenBaseUrl = 'http://repo.maven.apache.org/maven2/'
59
+ end
60
+ libs
61
+ end.flatten 1
62
+ file.client.folders['minecraft/mods'] = ['mc.liteloadermods']
63
+ file.client.downloads.unshift liteloaderLib
64
+ return BaseSanitizer.sanitize file
65
+ end
66
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'base_version_list'
2
+
3
+ class VanillaLegacyVersionList < BaseVersionList
4
+ def initialize
5
+ super('net.minecraft')
6
+ end
7
+
8
+ def get_versions
9
+ WonkoTheSane.data_json('minecraft.json')[:versions].map do |obj| [obj[:id], obj] end
10
+ end
11
+
12
+ def get_version(id)
13
+ data = id[1]
14
+ file = WonkoVersion.new
15
+ file.uid = 'net.minecraft'
16
+ file.version = data[:id]
17
+ file.time = data[:releaseTime]
18
+ file.type = data[:type]
19
+ file.client.traits = data[:'+traits']
20
+ file.client.extra[:processArguments] = data[:processArguments]
21
+ file.client.mainClass = data[:mainClass] if data.has_key? :mainClass
22
+ file.client.appletClass = data[:appletClass] if data.has_key? :appletClass
23
+ mainLib = VersionLibrary.new
24
+ mainLib.name = 'net.minecraft:minecraft:' + file.version
25
+ mainLib.url = 'http://s3.amazonaws.com/Minecraft.Download/versions/' + file.version + '/' + file.version + '.jar'
26
+ file.client.downloads = [ mainLib ]
27
+
28
+ file.client.folders['minecraft/screenshots'] = ['general.screenshots']
29
+ file.client.folders['minecraft/resourcepackks'] = ['mc.resourcepacks'] if file.time >= 1372430921
30
+ file.client.folders['minecraft/texturepacks'] = ['mc.texturepacks'] if file.time < 1372430921
31
+ file.client.folders['minecraft/saves'] = ['mc.saves.anvil'] if file.time >= 1330552800
32
+ file.client.folders['minecraft/saves'] = ['mc.saves.region'] if file.time >= 1298325600 and file.time < 1330552800
33
+ file.client.folders['minecraft/saves'] = ['mc.saves.infdev'] if file.time >= 1291327200 and file.time < 1298325600
34
+ file.client.traits.delete 'texturepacks' if file.client.traits
35
+ file.client.traits.delete 'no-resourcepacks' if file.client.traits
36
+
37
+ BaseSanitizer.sanitize file, MojangProcessArgumentsSanitizer
38
+ end
39
+ end