wonko_the_sane 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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