Last active
March 9, 2018 16:51
-
-
Save pbhogan/0834e861d5c3f0dee404053d92265537 to your computer and use it in GitHub Desktop.
Factorio Helper Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
require "thor" | |
require "httparty" | |
require "logger" | |
require "fileutils" | |
class FactorioTools < Thor | |
SOURCE_LINK = "https://www.factorio.com/get-download/latest/headless/linux64" | |
TARGET_FILE = "factorio.tar.xz" | |
BINARY_PATH = "/opt/factorio/bin/x64/factorio" | |
class_option :quiet, type: :boolean, aliases: "-q" | |
class_option :log, type: :string, aliases: "-l" | |
class Factorio | |
class << self | |
def setup_logger(options = {}) | |
$logger = ::Logger.new(options[:log] ? options[:log] : STDOUT) | |
$logger.level = options[:quiet] ? ::Logger::WARN : ::Logger::INFO | |
$logger.datetime_format = "%Y-%m-%d %H:%M:%S" | |
$logger.formatter = proc do |severity, datetime, program_name, message| | |
"#{datetime.strftime($logger.datetime_format)} #{severity}: #{message}\n" | |
end | |
$logger | |
end | |
def get_installed_version(options = {}) | |
version_command = "#{BINARY_PATH} --version" | |
if File.exist? BINARY_PATH | |
version = `#{version_command}`[/Version: ([\d\.]+)/, 1] | |
if version.empty? | |
$logger.fatal "Could not parse version from command output: #{version_command}" | |
exit | |
end | |
version | |
else | |
unless options[:silent] | |
$logger.fatal "Could not find factorio binary at: #{BINARY_PATH}" | |
exit | |
end | |
end | |
rescue Exception => e | |
$logger.fatal e.message | |
exit | |
end | |
def get_target_time | |
File.mtime(TARGET_FILE).to_time.to_i | |
rescue | |
0 | |
end | |
def get_remote_info(version = "latest") | |
source_link = SOURCE_LINK.gsub "latest", "#{version.downcase}" | |
begin | |
response = HTTParty.head SOURCE_LINK | |
source_link = response.request.last_uri.to_s | |
if response["last-modified"].nil? || response["last-modified"].empty? | |
$logger.fatal "Could not find Last-Modified HTTP header: #{response}" | |
exit | |
end | |
begin | |
last_modified_at = DateTime.strptime(response["last-modified"], "%a, %d %b %Y %H:%M:%S %Z").to_time.to_i | |
rescue Exception => e | |
$logger.fatal "Could not parse version from Last-Modified HTTP header: #{response["last-modified"]}" | |
$logger.fatal e.message | |
exit | |
end | |
version = source_link[/factorio_headless_x64_([\d\.]+)\.tar/, 1] | |
if version.empty? | |
$logger.fatal "Could not parse version from URL: #{source_link}" | |
exit | |
end | |
return OpenStruct.new( | |
url: source_link, | |
last_modified_at: last_modified_at, | |
version: version, | |
) | |
rescue Exception => e | |
$logger.fatal "Could not access remote URL: #{source_link}" | |
$logger.fatal e.message | |
exit | |
end | |
end | |
def download_package(remote_info) | |
$logger.info "Downloading package #{remote_info.url}" | |
File.open(TARGET_FILE, "w") do |file| | |
response = HTTParty.get(remote_info.url, stream_body: true) do |part| | |
file.write part | |
end | |
end | |
$logger.info "Updating package mtime" | |
FileUtils.touch TARGET_FILE, mtime: remote_info.last_modified_at | |
end | |
def install_package | |
$logger.info "Extracting package" | |
`tar -Jxf #{TARGET_FILE}` | |
$logger.info "Changing ownership to user 'factorio'" | |
FileUtils.chown_R "factorio", "factorio", "./factorio" | |
$logger.info "Restarting service" | |
`systemctl restart factorio` | |
end | |
end | |
end | |
desc "version", "Detect the currently installed version of Factorio" | |
def version | |
Factorio.setup_logger options | |
if version = Factorio.get_installed_version | |
puts version | |
end | |
end | |
desc "latest", "Detect the latest version of Factorio available" | |
def latest | |
Factorio.setup_logger options | |
if remote_info = Factorio.get_remote_info | |
puts remote_info.version | |
end | |
end | |
desc "install [VERSION]", "Install Factorio version (default: latest)" | |
option :force, type: :boolean | |
def install(version = "latest") | |
Factorio.setup_logger options | |
if installed_version = Factorio.get_installed_version(silent: true) | |
$logger.fatal "Factorio is already installed. Use 'upgrade' to install a different version." | |
exit | |
end | |
remote_info = Factorio.get_remote_info version | |
if options[:force] || Factorio.get_target_time != remote_info.last_modified_at | |
Factorio.download_package remote_info | |
end | |
Factorio.install_package | |
end | |
desc "upgrade [VERSION]", "Upgrade to Factorio version (default: latest)" | |
option :force, type: :boolean | |
def upgrade(version = "latest") | |
Factorio.setup_logger options | |
remote_info = Factorio.get_remote_info version | |
if options[:force] || remote_info.version != Factorio.get_installed_version(silent: true) | |
if options[:force] || Factorio.get_target_time != remote_info.last_modified_at | |
Factorio.download_package remote_info | |
end | |
Factorio.install_package | |
$logger.info "Factorio #{remote_info.version} has been installed." | |
else | |
$logger.info "Factorio #{remote_info.version} is already up to date." | |
end | |
end | |
desc "download [VERSION]", "Download Factorio package for version (default: latest)" | |
option :force, type: :boolean | |
def download(version = "latest") | |
Factorio.setup_logger options | |
remote_info = Factorio.get_remote_info version | |
if options[:force] || Factorio.get_target_time != remote_info.last_modified_at | |
Factorio.download_package remote_info | |
$logger.info "#{TARGET_FILE} has been downloaded." | |
else | |
$logger.info "#{TARGET_FILE} is already present and up to date." | |
end | |
end | |
desc "backup", "Backup current installation to the archives folder" | |
def backup | |
Factorio.setup_logger options | |
backup_path = "archived/games" | |
version = Factorio.get_installed_version | |
FileUtils.mkdir_p backup_path | |
FileUtils.cp_r "factorio", "#{backup_path}/factorio-#{version}", remove_destination: true | |
$logger.info "Archived current Factorio installation to '#{backup_path}'" | |
end | |
end | |
FactorioTools.start ARGV | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment