launchcraft 0.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.
- data/bin/minecraft +139 -0
- data/lib/launchcraft/auth.rb +75 -0
- data/lib/launchcraft/config.rb +98 -0
- data/lib/launchcraft/java.rb +81 -0
- data/lib/launchcraft/lzma.rb +29 -0
- data/lib/launchcraft/md5_file.rb +61 -0
- data/lib/launchcraft/update.rb +123 -0
- data/lib/launchcraft/uri.rb +30 -0
- data/lib/launchcraft/version.rb +22 -0
- data/lib/launchcraft/zip.rb +34 -0
- data/lib/launchcraft.rb +47 -0
- data/lib/os.rb +70 -0
- metadata +113 -0
data/bin/minecraft
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
4
|
+
#
|
5
|
+
# This file is part of launchcraft.
|
6
|
+
#
|
7
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as published
|
9
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# launchcraft is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU Affero General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#++
|
20
|
+
|
21
|
+
module Kernel
|
22
|
+
def self.die (message=nil)
|
23
|
+
puts message if message
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'launchcraft'
|
30
|
+
rescue RuntimeError => e
|
31
|
+
Kernel.die e
|
32
|
+
end
|
33
|
+
require 'highline/import'
|
34
|
+
|
35
|
+
require 'optparse'
|
36
|
+
|
37
|
+
OptionParser.new {|opts|
|
38
|
+
opts.banner = "Usage: #$0 [options] username"
|
39
|
+
|
40
|
+
opts.on('-l', '--login URL', 'Login URL') {|url|
|
41
|
+
LaunchCraft::Config['url.login'] = url
|
42
|
+
}
|
43
|
+
|
44
|
+
opts.on('-j', '--joinserver URL', 'Join Server URL') {|url|
|
45
|
+
LaunchCraft::Config['url.joinserver'] = url
|
46
|
+
}
|
47
|
+
|
48
|
+
opts.on('-s', '--skins URL', 'Skins URL') {|url|
|
49
|
+
LaunchCraft::Config['url.skins'] = url
|
50
|
+
}
|
51
|
+
|
52
|
+
opts.on('-r', '--resources URL', 'Resources URL') {|url|
|
53
|
+
LaunchCraft::Config['url.resources'] = url
|
54
|
+
}
|
55
|
+
|
56
|
+
opts.on('-d', '--download URL', 'Download URL') {|url|
|
57
|
+
LaunchCraft::Config['url.download'] = url
|
58
|
+
}
|
59
|
+
|
60
|
+
opts.on('-H', '--has-paid URL', 'Has paid URL') {|url|
|
61
|
+
LaunchCraft::Config['url.has_paid'] = url
|
62
|
+
}
|
63
|
+
|
64
|
+
opts.on('-c', '--cloacks URL', 'Cloacks URL') {|url|
|
65
|
+
LaunchCraft::Config['url.cloacks'] = url
|
66
|
+
}
|
67
|
+
|
68
|
+
opts.on('-a', '--anon', 'Play as anonymous') {
|
69
|
+
$anon = true
|
70
|
+
}
|
71
|
+
|
72
|
+
opts.on('-f', '--force', 'Force updates') {
|
73
|
+
$force = true
|
74
|
+
}
|
75
|
+
|
76
|
+
opts.on('-p', '--password PASSWORD', 'Password for login') {|pass|
|
77
|
+
$pass = pass
|
78
|
+
}
|
79
|
+
|
80
|
+
opts.on_tail('-v', '--version', 'Show version') {
|
81
|
+
puts "launchcraft #{LaunchCraft::VERSION}"
|
82
|
+
exit 0
|
83
|
+
}
|
84
|
+
|
85
|
+
opts.on_tail('-h', '--help', 'Show this helps') {
|
86
|
+
puts opts
|
87
|
+
exit 0
|
88
|
+
}
|
89
|
+
}.tap {|opts|
|
90
|
+
o = opts.parse!(ARGV)
|
91
|
+
LaunchCraft::Config.save
|
92
|
+
|
93
|
+
case o.size
|
94
|
+
when 0
|
95
|
+
$user = 'Player'
|
96
|
+
when 1
|
97
|
+
$user = o.first
|
98
|
+
else
|
99
|
+
puts opts
|
100
|
+
exit 1
|
101
|
+
end
|
102
|
+
|
103
|
+
$pass = ask('Password: ') {|q| q.echo = '*' } if !$anon and !$pass
|
104
|
+
}
|
105
|
+
|
106
|
+
STDIN.sync = true
|
107
|
+
|
108
|
+
l = LaunchCraft::Update.new
|
109
|
+
begin
|
110
|
+
l.check {|e|
|
111
|
+
puts "Checking #{e}..."
|
112
|
+
}
|
113
|
+
|
114
|
+
l.send($force ? :force_update : :update) {|stat|
|
115
|
+
print " " * 31
|
116
|
+
print "\r"
|
117
|
+
print "#{stat.current.file} (#{(100.0 / stat.total * stat.partial).round}%)"
|
118
|
+
}
|
119
|
+
puts
|
120
|
+
rescue Exception => e
|
121
|
+
Kernel.die "Unhandled exception: #{e.class}: #{e}"
|
122
|
+
end
|
123
|
+
|
124
|
+
if $anon
|
125
|
+
LaunchCraft::Java.exec($user)
|
126
|
+
else
|
127
|
+
a = LaunchCraft::Auth.new($user, $pass)
|
128
|
+
begin
|
129
|
+
a.login
|
130
|
+
rescue LaunchCraft::Auth::OldVersion
|
131
|
+
Kernel.die "Old version, please update launcher"
|
132
|
+
rescue LaunchCraft::Auth::BadLogin
|
133
|
+
Kernel.die "Username or password incorrect"
|
134
|
+
rescue Exception => e
|
135
|
+
Kernel.die "Unhandled exception: #{e.class}: #{e}"
|
136
|
+
end
|
137
|
+
|
138
|
+
LaunchCraft::Java.exec(a.username, a.uuid)
|
139
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'launchcraft'
|
21
|
+
require 'launchcraft/config'
|
22
|
+
require 'launchcraft/uri'
|
23
|
+
|
24
|
+
require 'net/http'
|
25
|
+
require 'cgi'
|
26
|
+
|
27
|
+
class LaunchCraft
|
28
|
+
class Auth
|
29
|
+
class OldVersion < Exception
|
30
|
+
end
|
31
|
+
|
32
|
+
class BadLogin < Exception
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :username, :password, :uuid
|
36
|
+
|
37
|
+
def initialize (username, password=nil)
|
38
|
+
@username, @password, @uuid, @logged = username, password, nil, false
|
39
|
+
end
|
40
|
+
|
41
|
+
def logged?
|
42
|
+
@logged
|
43
|
+
end
|
44
|
+
|
45
|
+
def login
|
46
|
+
post(Config['url.login'], "version=13&user=#{CGI.escape(@username)}&password=#{CGI.escape(@password)}", {
|
47
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
48
|
+
'Content-Language' => 'en-US'
|
49
|
+
}).tap {|b|
|
50
|
+
if (@logged = !!(b =~ /^.+?:.+?:(.+?):(.+?):?$/))
|
51
|
+
@username, @uuid = $1, $2
|
52
|
+
elsif b =~ /old/i
|
53
|
+
raise OldVersion
|
54
|
+
else
|
55
|
+
raise BadLogin
|
56
|
+
end
|
57
|
+
}
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
protected
|
62
|
+
def post (url, body, headers={})
|
63
|
+
uri = URI.parse(url)
|
64
|
+
Net::HTTP.start(uri.host, uri.port) {|http|
|
65
|
+
http.request_post(uri.request, body, headers) {|res|
|
66
|
+
case res
|
67
|
+
when Net::HTTPSuccess then return res.body
|
68
|
+
when Net::HTTPRedirection then return post(res['location'], body, headers)
|
69
|
+
else raise BadLogin
|
70
|
+
end
|
71
|
+
}
|
72
|
+
}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'launchcraft'
|
21
|
+
|
22
|
+
class LaunchCraft
|
23
|
+
Config = Class.new(Hash) {
|
24
|
+
def initialize
|
25
|
+
@path = File.join(LaunchCraft.working_dir, 'options.txt')
|
26
|
+
set_default
|
27
|
+
File.file?(@path) ? parse : save
|
28
|
+
end
|
29
|
+
|
30
|
+
def []= (key, value)
|
31
|
+
super(key.to_s, value.to_s)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
map {|*kv|
|
36
|
+
kv.join(':')
|
37
|
+
}.join("\n")
|
38
|
+
end
|
39
|
+
|
40
|
+
def save
|
41
|
+
File.open(@path, 'wb') {|f|
|
42
|
+
f.write to_s
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
def set_default
|
48
|
+
update({
|
49
|
+
'music' => '1.0',
|
50
|
+
'sound' => '1.0',
|
51
|
+
'invertYMouse' => 'false',
|
52
|
+
'mouseSensitivity' => '0.5',
|
53
|
+
'fov' => '0.0',
|
54
|
+
'gamma' => '0.0',
|
55
|
+
'viewDistance' => '0',
|
56
|
+
'guiScale' => '0',
|
57
|
+
'bobView' => 'false',
|
58
|
+
'anaglyph3d' => 'false',
|
59
|
+
'advancedOpengl' => 'false',
|
60
|
+
'fpsLimit' => '1',
|
61
|
+
'difficulty' => '0',
|
62
|
+
'fancyGraphics' => 'true',
|
63
|
+
'ao' => 'false',
|
64
|
+
'skin' => 'Default',
|
65
|
+
'lastServer' => '',
|
66
|
+
'url.login' => 'https://login.minecraft.net/',
|
67
|
+
'url.joinserver' => 'http://session.minecraft.net/game/joinserver.jsp',
|
68
|
+
'url.skins' => 'http://s3.amazonaws.com/MinecraftSkins/',
|
69
|
+
'url.resources' => 'http://s3.amazonaws.com/MinecraftResources/',
|
70
|
+
'url.download' => 'http://s3.amazonaws.com/MinecraftDownload/',
|
71
|
+
'url.has_paid' => 'https://login.minecraft.net/session',
|
72
|
+
'url.cloacks' => 'http://s3.amazonaws.com/MinecraftCloaks/',
|
73
|
+
'key_key.attack' => '-100',
|
74
|
+
'key_key.use' => '-99',
|
75
|
+
'key_key.forward' => '17',
|
76
|
+
'key_key.left' => '30',
|
77
|
+
'key_key.back' => '31',
|
78
|
+
'key_key.right' => '32',
|
79
|
+
'key_key.jump' => '57',
|
80
|
+
'key_key.sneak' => '42',
|
81
|
+
'key_key.drop' => '16',
|
82
|
+
'key_key.inventory' => '18',
|
83
|
+
'key_key.chat' => '20',
|
84
|
+
'key_key.playerList' => '15',
|
85
|
+
'key_key.pickItem' => '-98',
|
86
|
+
})
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse
|
90
|
+
update(Hash[File.read(@path).split(/\r?\n/).map {|line|
|
91
|
+
next if line =~ /^\s*#/
|
92
|
+
|
93
|
+
line.split(':', 2)
|
94
|
+
}])
|
95
|
+
save
|
96
|
+
end
|
97
|
+
}.new
|
98
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'launchcraft'
|
21
|
+
|
22
|
+
require 'rbconfig'
|
23
|
+
|
24
|
+
class Dir
|
25
|
+
def self.path
|
26
|
+
(((ENV.key?('PATH') and ENV['PATH'] and !ENV['PATH'].empty?) ? ENV['PATH'] : nil) ||
|
27
|
+
['/bin', '/usr/bin', '/sbin', '/usr/sbin', '/usr/local/bin'].join(RbConfig::CONFIG['PATH_SEPARATOR'])
|
28
|
+
).split(RbConfig::CONFIG['PATH_SEPARATOR'])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module Kernel
|
33
|
+
def self.which (bin, which=0)
|
34
|
+
res = Dir.path.map {|path|
|
35
|
+
File.join(path, bin)
|
36
|
+
}.select {|bin|
|
37
|
+
File.executable_real?(bin)
|
38
|
+
}
|
39
|
+
|
40
|
+
if which == :all
|
41
|
+
res
|
42
|
+
elsif which.is_a?(Integer)
|
43
|
+
res[which]
|
44
|
+
else
|
45
|
+
res[0]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class LaunchCraft
|
51
|
+
module Java
|
52
|
+
BIN = Kernel.which('java').tap {|x|
|
53
|
+
next x if x
|
54
|
+
break File.join(ENV['JAVA_HOME'], 'bin', 'java') if ENV['JAVA_HOME']
|
55
|
+
raise RuntimeError, "java bin not found."
|
56
|
+
}
|
57
|
+
|
58
|
+
class << self
|
59
|
+
def exec (user, sessid=nil)
|
60
|
+
Kernel.exec(*args(user, sessid))
|
61
|
+
end
|
62
|
+
|
63
|
+
def launch (user, sessid=nil)
|
64
|
+
Kernel.system(*args(user, sessid))
|
65
|
+
end
|
66
|
+
|
67
|
+
def spawn (user, sessid=nil)
|
68
|
+
Kernel.spawn(*args(user, sessid))
|
69
|
+
end
|
70
|
+
|
71
|
+
protected
|
72
|
+
def args (user, sessid=nil)
|
73
|
+
bindir = File.join(LaunchCraft.working_dir, 'bin')
|
74
|
+
[BIN, '-Xmx1024M', '-Xms512M', '-cp', %w[jinput lwjgl lwjgl_util minecraft].map {|x|
|
75
|
+
File.join(bindir, "#{x}.jar")
|
76
|
+
}.join(':'), "-Djava.library.path=#{File.join(bindir, 'natives')}",
|
77
|
+
'net.minecraft.client.Minecraft', user, sessid].compact
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'lzma'
|
21
|
+
|
22
|
+
class LZMA
|
23
|
+
def self.extract (file, out=File.basename(file, '.lzma'))
|
24
|
+
File.open(out, 'wb') {|f|
|
25
|
+
f.write(decompress(File.read(file)))
|
26
|
+
}
|
27
|
+
out
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'os'
|
21
|
+
require 'launchcraft'
|
22
|
+
|
23
|
+
class LaunchCraft
|
24
|
+
MD5File = Class.new {
|
25
|
+
attr_accessor :lwjgl, :jinput, :lwjgl_util, :minecraft
|
26
|
+
attr_accessor "#{OS.parse.to_s.gsub(/^macos$/, 'macosx')}_natives".to_sym
|
27
|
+
|
28
|
+
def initialize
|
29
|
+
@path = File.join(LaunchCraft.working_dir, 'bin', 'md5s')
|
30
|
+
parse if File.file?(@path)
|
31
|
+
end
|
32
|
+
|
33
|
+
"#{OS.parse.to_s.gsub(/^macos$/, 'macosx')}_natives".tap {|m|
|
34
|
+
alias_method :natives, m.to_sym
|
35
|
+
alias_method :natives=, "#{m}=".to_sym
|
36
|
+
}
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
n = OS.parse.to_s.gsub(/^macos$/, 'macosx')
|
40
|
+
"#md5 hashes for downloaded files\nlwjgl.jar=#{@lwjgl}\njinput.jar=#{@jinput}\n" +
|
41
|
+
"lwjgl_util.jar=#{@lwjgl_util}\n#{n}_natives.jar.lzma=" +
|
42
|
+
"#{instance_variable_get("@#{n}_natives")}\nminecraft.jar=#{@minecraft}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def save
|
46
|
+
File.open(@path, 'wb') {|f|
|
47
|
+
f.write to_s
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
def parse
|
53
|
+
File.read(@path).split(/\r?\n/).each {|line|
|
54
|
+
next if line =~ /^\s*#/
|
55
|
+
|
56
|
+
key, value = line.split('=', 2).map(&:strip)
|
57
|
+
instance_variable_set("@#{key.split('.').first}".to_sym, value)
|
58
|
+
}
|
59
|
+
end
|
60
|
+
}.new
|
61
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'os'
|
21
|
+
require 'launchcraft'
|
22
|
+
require 'launchcraft/md5_file'
|
23
|
+
require 'launchcraft/config'
|
24
|
+
require 'launchcraft/lzma'
|
25
|
+
require 'launchcraft/zip'
|
26
|
+
require 'launchcraft/uri'
|
27
|
+
|
28
|
+
require 'fileutils'
|
29
|
+
require 'net/http'
|
30
|
+
|
31
|
+
class LaunchCraft
|
32
|
+
class Update
|
33
|
+
class Entry < Struct.new(:file, :url, :md5, :length)
|
34
|
+
alias size length
|
35
|
+
alias size= length=
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
file
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Global < Struct.new(:total, :partial, :current)
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
@dir = File.join(LaunchCraft.working_dir, 'bin')
|
47
|
+
@os = OS.parse.to_s.gsub(/^macos$/, 'macosx')
|
48
|
+
|
49
|
+
@entries = {
|
50
|
+
lwjgl: Entry.new('lwjgl.jar', Config['url.download'] + 'lwjgl.jar'),
|
51
|
+
jinput: Entry.new('jinput.jar', Config['url.download'] + 'jinput.jar'),
|
52
|
+
lwjgl_util: Entry.new('lwjgl_util.jar', Config['url.download'] + 'lwjgl_util.jar'),
|
53
|
+
"#{@os}_natives".to_sym => Entry.new("#{@os}_natives.jar.lzma", Config['url.download'] + "#{@os}_natives.jar.lzma"),
|
54
|
+
minecraft: Entry.new('minecraft.jar', 'http://cloud.github.com/downloads/shurizzle/MyCraft/minecraft.jar')
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def check
|
59
|
+
@entries.each {|name, entry|
|
60
|
+
yield entry if block_given?
|
61
|
+
entry.md5, entry.size = get_infos(entry.url)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def update (&blk)
|
66
|
+
_update @entries.map {|name, entry|
|
67
|
+
entry if MD5File.send(name) != entry.md5
|
68
|
+
}.compact, &blk
|
69
|
+
end
|
70
|
+
|
71
|
+
def force_update (&blk)
|
72
|
+
_update @entries.values, &blk
|
73
|
+
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
def _update (ent)
|
77
|
+
tot = ent.map(&:size).reduce(:+)
|
78
|
+
part = 0
|
79
|
+
stat = Global.new(tot, part, nil)
|
80
|
+
|
81
|
+
ent.each {|e|
|
82
|
+
uri = URI.parse(e.url)
|
83
|
+
File.open(File.join(@dir, e.file), 'wb') {|f|
|
84
|
+
Net::HTTP.start(uri.host, uri.port) {|http|
|
85
|
+
http.request(Net::HTTP::Get.new(uri.request)) {|res|
|
86
|
+
res.read_body {|segment|
|
87
|
+
part += segment.bytesize
|
88
|
+
f.write(segment)
|
89
|
+
stat.total = tot
|
90
|
+
stat.partial = part
|
91
|
+
stat.current = e
|
92
|
+
yield stat if block_given?
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
}
|
97
|
+
MD5File.send("#{e.file.split('.').first}=", e.md5)
|
98
|
+
|
99
|
+
if e.file == "#{@os}_natives.jar.lzma"
|
100
|
+
dir = File.join(@dir, 'natives')
|
101
|
+
file = File.join(@dir, e.file)
|
102
|
+
FileUtils.rm_rf(dir) if File.exists?(dir)
|
103
|
+
file = LZMA.extract(file).tap {
|
104
|
+
FileUtils.rm_f(file)
|
105
|
+
}
|
106
|
+
Zip.extract(file, dir)
|
107
|
+
FileUtils.rm_f(file)
|
108
|
+
FileUtils.rm_rf(File.join(dir, 'META-INF'))
|
109
|
+
end
|
110
|
+
}
|
111
|
+
|
112
|
+
MD5File.save
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_infos (url)
|
116
|
+
uri = URI.parse(url)
|
117
|
+
Net::HTTP.start(uri.host, uri.port) {|http|
|
118
|
+
res = http.head(uri.request)
|
119
|
+
[res['etag'].gsub('"', '').strip, res['content-length'].to_i]
|
120
|
+
}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'uri'
|
21
|
+
|
22
|
+
module URI
|
23
|
+
class Generic
|
24
|
+
def request
|
25
|
+
x = dup
|
26
|
+
x.component.take_while {|y| y != :path }.each {|y| x.send("#{y}=".to_sym, nil) }
|
27
|
+
x.to_s
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
class LaunchCraft
|
21
|
+
VERSION = '0.0.1'.freeze
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'fileutils'
|
21
|
+
require 'zip'
|
22
|
+
|
23
|
+
module Zip
|
24
|
+
def self.extract (archive, path=Dir.pwd)
|
25
|
+
FileUtils.mkdir_p(path)
|
26
|
+
|
27
|
+
ZipFile.open(archive) {|zf|
|
28
|
+
zf.entries.each {|entry|
|
29
|
+
FileUtils.mkdir_p(File.dirname(File.join(path, entry.name)))
|
30
|
+
entry.extract(File.join(path, entry.name))
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
data/lib/launchcraft.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'os'
|
21
|
+
require 'launchcraft/version'
|
22
|
+
|
23
|
+
class LaunchCraft
|
24
|
+
def self.working_dir (appname='minecraft')
|
25
|
+
res = case OS.parse
|
26
|
+
when :linux, :solaris
|
27
|
+
File.join(ENV['HOME'], ".#{appname}")
|
28
|
+
when :windows
|
29
|
+
File.join(ENV['APPDATA'] || ENV['HOME'], ".#{appname}")
|
30
|
+
when :macos
|
31
|
+
File.join(ENV['HOME'], 'Library', 'Application Support', appname)
|
32
|
+
else
|
33
|
+
File.join(ENV['HOME'], appname)
|
34
|
+
end
|
35
|
+
|
36
|
+
Dir.mkdir(res) unless File.directory?(res)
|
37
|
+
%w[bin resources saves screenshots stats texturepacks].each {|dir|
|
38
|
+
dir = File.join(res, dir)
|
39
|
+
Dir.mkdir(dir) unless File.directory?(dir)
|
40
|
+
}
|
41
|
+
return res
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'launchcraft/update'
|
46
|
+
require 'launchcraft/auth'
|
47
|
+
require 'launchcraft/java'
|
data/lib/os.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [ shura1991@gmail.com ]
|
3
|
+
#
|
4
|
+
# This file is part of launchcraft.
|
5
|
+
#
|
6
|
+
# launchcraft is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# launchcraft is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with launchcraft. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
class OS
|
21
|
+
class << self
|
22
|
+
if RUBY_PLATFORM =~ /java/
|
23
|
+
def parse (what=Java::java.lang.System.getProperty('os.name'))
|
24
|
+
case what.downcase
|
25
|
+
when /win/
|
26
|
+
:windows
|
27
|
+
when /mac/
|
28
|
+
:macos
|
29
|
+
when /solaris|sunos/
|
30
|
+
:solaris
|
31
|
+
when /linux|unix/
|
32
|
+
:linux
|
33
|
+
else
|
34
|
+
:unknown
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
def parse (what=RUBY_PLATFORM)
|
39
|
+
case what
|
40
|
+
when /(?<!dar)win/
|
41
|
+
:windows
|
42
|
+
when /darwin/
|
43
|
+
:macos
|
44
|
+
when /linux/
|
45
|
+
:linux
|
46
|
+
when /solaris/
|
47
|
+
:solaris
|
48
|
+
else
|
49
|
+
:unknown
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def windows?
|
55
|
+
parse == :windows
|
56
|
+
end
|
57
|
+
|
58
|
+
def macos?
|
59
|
+
parse == :macos
|
60
|
+
end
|
61
|
+
|
62
|
+
def solaris?
|
63
|
+
parse == :solaris
|
64
|
+
end
|
65
|
+
|
66
|
+
def linux?
|
67
|
+
parse == :linux
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: launchcraft
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- shura
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-09-23 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: ruby-lzma
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: zip
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: highline
|
48
|
+
prerelease: false
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
type: :runtime
|
58
|
+
version_requirements: *id003
|
59
|
+
description: Simple cli launcher for minecraft
|
60
|
+
email: shura1991@gmail.com
|
61
|
+
executables:
|
62
|
+
- minecraft
|
63
|
+
extensions: []
|
64
|
+
|
65
|
+
extra_rdoc_files: []
|
66
|
+
|
67
|
+
files:
|
68
|
+
- lib/launchcraft/md5_file.rb
|
69
|
+
- lib/launchcraft/lzma.rb
|
70
|
+
- lib/launchcraft/zip.rb
|
71
|
+
- lib/launchcraft/version.rb
|
72
|
+
- lib/launchcraft/java.rb
|
73
|
+
- lib/launchcraft/update.rb
|
74
|
+
- lib/launchcraft/uri.rb
|
75
|
+
- lib/launchcraft/config.rb
|
76
|
+
- lib/launchcraft/auth.rb
|
77
|
+
- lib/launchcraft.rb
|
78
|
+
- lib/os.rb
|
79
|
+
- bin/minecraft
|
80
|
+
has_rdoc: true
|
81
|
+
homepage: http://github.com/shurizzle/launchcraft
|
82
|
+
licenses: []
|
83
|
+
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
version: "0"
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
version: "0"
|
105
|
+
requirements: []
|
106
|
+
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 1.3.7
|
109
|
+
signing_key:
|
110
|
+
specification_version: 3
|
111
|
+
summary: Simple cli launcher for minecraft
|
112
|
+
test_files: []
|
113
|
+
|