Class: Mclaunch::Tools

Inherits:
Object
  • Object
show all
Defined in:
lib/mclaunch/tools.rb

Instance Method Summary collapse

Constructor Details

#initialize(runtime, options) ⇒ Tools



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/mclaunch/tools.rb', line 10

def initialize(runtime, options)
  @runtime = runtime
  @options = options
  @server_properties = @runtime.get_server_properties
  @versions = {}
  @debug = @options[:debug]
  @quiet = @options[:quiet]
  @xml_document = nil
  @craftbukkit_version_regex = /^[1-9]\.[0-9]\.[0-9]-R[0-9]\.[0-9]$/
  @commands = nil
end

Instance Method Details

#array_to_string(array, delimiter = " ") ⇒ Object

Convert a array into a String.



62
63
64
65
66
67
68
# File 'lib/mclaunch/tools.rb', line 62

def array_to_string(array, delimiter=" ")
  tmp = ""
  array.each do |s|
    tmp += s+delimiter
  end
  tmp
end

#commands(commands = nil) ⇒ Object

Method desctiption



23
24
25
26
# File 'lib/mclaunch/tools.rb', line 23

def commands(commands=nil)
  @commands = commands
  @commands unless @commands
end

#download_file(url, path) ⇒ Object

Download url to path



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/mclaunch/tools.rb', line 263

def download_file(url, path)
  puts "downloading file from: \"#{url}\"" unless @quiet
  url = URI(url)
  location = URI(Net::HTTP.get_response(url)['location'])
  Net::HTTP.start(location.host, location.port) do |http|
    unless File.exist?(path)
      f = open(path, 'wb')
      begin
        downloadedSize = 0
        http.request_get(location.request_uri) do |resp|
          progressBar = ProgressBar.new("Downloading", 100)
          size = resp.content_length
          resp.read_body do |segment|
            downloadedSize += segment.length
            if(downloadedSize != 0)
              percent = (downloadedSize * 100 / size)
              progressBar.set(percent)
            end
            f.write(segment)
          end #end resp.read_body
          progressBar.finish
        end #end http.request_get
      ensure
        f.close()
      end #end begin
    end #end Net::HTTP.start
  end
end

#download_server_executable(version) ⇒ Object

Download the latest server executable



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/mclaunch/tools.rb', line 222

def download_server_executable(version)
  link = get_download_link(version)
  url = link[:link]
  md5 = link[:checksum]
  version = link[:version]
  build_number = link[:build_number]
  channel = link[:channel]
  target = "#{@options[:server_jar_directory]}craftbukkit-#{channel}-#{version}-#{build_number}.jar"

  #Debug output
  if @debug
    puts "[#{version}]"
    puts "  link:\t\t#{url}"
    puts "  md5:\t\t#{md5}"
    puts "  taret:\t#{target}"
    puts "  build_nr:\t#{build_number}"
    puts "  channel:\t#{channel}"
  end

  if local_version_available? channel, version, build_number
    puts "local version available. Will symlink local version to server runtime directory." if @debug
  else
    puts "local version not available. Will download new version and put symlink to it in server runtime directory." if @debug
    download_file(url, target)
  end
  set_server_exe_symlink(target)
end

Return the link for the latest version of craftbukkit



206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/mclaunch/tools.rb', line 206

def get_download_link(version)
  prefix = "http://dl.bukkit.org"
  url = "#{prefix}/api/1.0/downloads/projects/craftbukkit/artifacts/#{version}/?_accept=application%2Fxml" if version =~ /^(rb|beta|dev)$/
  url = "#{prefix}/api/1.0/downloads/projects/craftbukkit/view/build-#{version}/?_accept=application%2Fxml" if version =~ /^[0-9][0-9][0-9][0-9]$/
  url = "#{prefix}/api/1.0/downloads/projects/craftbukkit/view/build-#{get_latest_build_number(version)}/?_accept=application%2Fxml" if version =~ @craftbukkit_version_regex
  raise "Thist is no Craftbukkit Version." unless url
  {
    :link => "#{prefix}#{get_xml_first_path(url, '//file/url')}",
    :checksum => get_xml_first_path(url, "//file/checksum_md5"),
    :version => get_xml_first_path(url, "//version"),
    :build_number => get_xml_first_path(url, "//build_number"),
    :channel => get_xml_first_path(url, "//channel/slug"),
  }
end

#get_latest_build_number(version, page = 1) ⇒ Object

Get the latest build number for given version that was not broken



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/mclaunch/tools.rb', line 187

def get_latest_build_number(version, page=1)
  url = "http://dl.bukkit.org/api/1.0/downloads/projects/craftbukkit/artifacts/?_accept=application%2Fxml&limit=20&page=#{page}"
  build_number = nil
  get_xml_document(url)
  max_page = REXML::XPath.first(@xml_document, "//pages").text
  REXML::XPath.each(@xml_document, "/root/results/list-item") do |element|
    vers = element.text "version"
    build_nr = element.text "build_number"
    next if element.text("is_broken") =~ /^[Tt][Rr][Uu][Ee]$/
    build_number = build_nr if version.eql? vers
  end
  if build_number.to_i > 0
    return build_number
  else
    get_latest_build_number(version, page + 1) if page <= max_page.to_i
  end
end

#get_local_server_versionsObject

Get a hash of the locally available server versions



152
153
154
155
156
157
158
# File 'lib/mclaunch/tools.rb', line 152

def get_local_server_versions
  dir = Dir.new(@options[:server_jar_directory])
  dir.sort.each do |f|
    @versions[f.gsub(/^craftbukkit-|\.jar$/, "")] = "#{@options[:server_jar_directory]}#{f}" unless f =~ /^(\.\.|\.)$/
  end
  @versions
end

#get_worldsObject

end array_to_string(array, delimiter=“ ”)



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/mclaunch/tools.rb', line 70

def get_worlds
  worlds = {}
  dir = Dir.new(@options[:server_world_directory])
  dir.each do |world|
    unless world =~ /^(\.|\.\.)$/
      ramdisk = false
      ramdisk = true if File.exists?("#{@options[:server_world_directory]}#{world}/ramdisk")
      worlds[world] = ramdisk
      if @debug
        puts "  world: #{world} runs from ramdisk" if ramdisk
        puts "  world: #{world} runs from disk" unless ramdisk
      end
    end
  end #end dir.each
  return worlds
end

#get_xml_document(url) ⇒ Object

Get an xml Document from the given url



173
174
175
176
177
178
# File 'lib/mclaunch/tools.rb', line 173

def get_xml_document(url)
    xml_data = Net::HTTP.get_response(URI.parse(url))
    raise "Search for xml document data returned HTTP Error 404\n\nMaybe the version you entered does not exist." if xml_data.is_a?(Net::HTTPNotFound)
    @xml_document = REXML::Document.new(xml_data.body)
    raise "xml document empty" unless @xml_document
end

#get_xml_first_path(url, path) ⇒ Object

Get xml data from craftbukkit site as hash



181
182
183
184
# File 'lib/mclaunch/tools.rb', line 181

def get_xml_first_path(url, path)
  get_xml_document(url)
  REXML::XPath.first(@xml_document, path).text
end

#is_minecraft_player?(player) ⇒ Boolean

Check online if Player name is a valid minecraft username if server is in online mode



29
30
31
32
33
34
35
36
37
38
39
# File 'lib/mclaunch/tools.rb', line 29

def is_minecraft_player?(player)
  if to_boolean(@server_properties['online-mode']) == true
    uri = URI.parse("https://minecraft.net/haspaid.jsp?user=#{player}")
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    request = Net::HTTP::Get.new(uri.request_uri)
    response = http.request(request)
    to_boolean response.body
  end
end

#is_op?(player) ⇒ Boolean

check if player is in ops.txt



42
43
44
45
46
47
48
49
50
# File 'lib/mclaunch/tools.rb', line 42

def is_op?(player)
  puts "checking if \"#{player}\" is op." if @debug
  ops = File.new("#{@options[:server_runtime_directory]}ops.txt", "r")
  op = false
  ops.each_line do |l|
    op = true if l.gsub("\n", "").eql?(player)
  end
  op
end

end is_op?



52
53
54
# File 'lib/mclaunch/tools.rb', line 52

def is_symlink_or_file(path)
  File.exist?(path) || File.symlink?(path)
end

#local_version_available?(channel, version, build_number) ⇒ Boolean

Check if given version is available locally



168
169
170
# File 'lib/mclaunch/tools.rb', line 168

def local_version_available?(channel, version, build_number)
  true if get_local_server_versions.has_key?("#{channel}-#{version}-#{build_number}")
end

Print locally available server versions to stdout



161
162
163
164
165
# File 'lib/mclaunch/tools.rb', line 161

def print_local_server_versions
  get_local_server_versions.each do |k,v|
    puts "#{k}, #{v}"
  end
end

#server_change_version(version) ⇒ Object

Change server version manually



251
252
253
254
255
256
257
258
259
260
# File 'lib/mclaunch/tools.rb', line 251

def server_change_version(version)
  link = get_download_link(version)
  raise "This is no Craftbukkit Version!" unless version =~ /^(#{@craftbukkit_version_regex}|[0-9]{4})$/
  if local_version_available?(link[:channel], link[:version], link[:build_number])
    filename = "craftbukkit-#{version}.jar"
    set_server_exe_symlink filename
  else
    download_server_executable(version)
  end
end

end download_file(url, path)



292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/mclaunch/tools.rb', line 292

def set_server_exe_symlink(file)
  current_file = "#{@options[:server_runtime_directory]}#{@options[:server_executable]}"
  was_running = false
  if @runtime.is_running?
    was_running = true
    @runtime.stop
  end
  puts "symlinking #{file} to #{current_file}"
  File.unlink(current_file) if is_symlink_or_file(current_file)
  File.symlink(file,current_file)
  @runtime.start if was_running
end

#to_boolean(s) ⇒ Object

Convert String to Boolean



57
58
59
# File 'lib/mclaunch/tools.rb', line 57

def to_boolean(s)
  s.eql?"true"
end

#world_backup_createObject

Create a world backup with rsync



306
307
308
309
310
311
312
313
314
315
# File 'lib/mclaunch/tools.rb', line 306

def world_backup_create
  puts "Creating world folder backup now." unless @quiet
  @commands.save_off
  @commands.save_all
  sleep 1
  `rsync -a --delete-after #{@options[:server_world_directory]} #{@options[:server_backup_directory]}worlds/latest > #{@options[:server_backup_directory]}worlds/latest/rsync.log`
  @commands.save_on
  now = DateTime.now.strftime("%Y-%m-%d-%H:%M:%S")
  `cp -al #{@options[:server_backup_directory]}worlds/latest #{@options[:server_backup_directory]}worlds/#{now}`
end

#world_backup_deleteObject

Delete world backups which are older than a month



318
319
320
321
# File 'lib/mclaunch/tools.rb', line 318

def world_backup_delete
  puts "Deleting old backups" unless @quiet
  `find #{@options[:server_backup_directory]} -mindepth 1 -maxdepth 1  -not -newermt '1 month ago' -exec rm -rf {} \\;`
end

#world_ramdisk_state(world_name) ⇒ Object

end worlds_create_symlinks



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/mclaunch/tools.rb', line 101

def world_ramdisk_state(world_name)
  worlds = get_worlds
  world_exists = false
  world_already_on_ramdisk = false
  worlds.each do |world,ramdisk|
    if world.eql? world_name
      world_exists = true
      world_already_on_ramdisk = ramdisk
    end
  end
  if world_name
    if world_exists
      if world_already_on_ramdisk
        puts "\"#{world_name}\" will run from harddisk on next server start" unless @quiet
        File.delete("#{@options[:server_world_directory]}#{world_name}/ramdisk")
      else
        puts "\"#{world_name}\" will run from ramdisk on next server start" unless @quiet
        File.open("#{@options[:server_world_directory]}#{world_name}/ramdisk", "w")
      end #end if world_already_on_ramdisk
    else
      puts "\"#{world_name}\" does not exist in world folder!"
    end #end if world_exists
  end #end if world_name
end

Create world Symlinks



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/mclaunch/tools.rb', line 88

def worlds_create_symlinks
  worlds = get_worlds
  worlds.each do |world,ramdisk|
    src = "#{@options[:server_world_directory]}#{world}"
    src = "#{@options[:server_ramdisk_directory]}#{world}" if ramdisk
    dst = "#{@options[:server_runtime_directory]}#{world}"
    File.unlink(dst) if File.symlink?(dst)
    File.symlink(src,dst)
    puts "Symlink created for: #{world}" unless @quiet
    puts "Source: #{src}\nDestination: #{dst}" if @debug
  end
end

#worlds_to_diskObject

end to_ramdisk



137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/mclaunch/tools.rb', line 137

def worlds_to_disk
  worlds = get_worlds()
  ramdisk_worlds = Dir.open("#{@options[:server_ramdisk_directory]}")
  ramdisk_worlds.each do |world|
    if worlds.key?(world)
      if worlds[world]
        print "copy #{world} to harddisk... " unless @quiet
        `rsync -rt --exclude 'ramdisk' #{@options[:server_ramdisk_directory]}#{world}/ #{@options[:server_world_directory]}#{world}`
        puts "ok" unless @quiet
      end
    end #end if ramdisk
  end #worlds.each
end

#worlds_to_ramdiskObject

end world_ramdisk_state(world_name)



126
127
128
129
130
131
132
133
134
135
# File 'lib/mclaunch/tools.rb', line 126

def worlds_to_ramdisk
  worlds = get_worlds
  worlds.each do |world,ramdisk|
    if ramdisk
      print "copy #{world} to ramdisk... " unless @quiet
      `rsync -rt --exclude 'ramdisk' #{@options[:server_world_directory]}#{world}/ #{@options[:server_ramdisk_directory]}#{world}`
      puts "ok" unless @quiet
    end #end if ramdisk
  end #worlds.each
end