# encoding: utf-8 # Set default encoding case RUBY_VERSION when /1\.8\.[0-9]/ class Array def to_s "[#{self.join(', ')}]" end end else Encoding.default_internal, Encoding.default_external = ['utf-8'] * 2 end case RUBY_PLATFORM when /-mingw32$/, /-mswin32$/ gem 'win32-process' require 'win32/registry' require "win32/process" require 'win32ole' end require 'open3' module SixUpdaterWeb VERSION = "0.24.7" COMPONENT = "six-updater-web" DEFAULT_IP = "127.0.0.1" unless defined?(DEFAULT_IP) DEFAULT_PORT = 3000 unless defined?(DEFAULT_PORT) SIX_HOST = DEFAULT_IP unless defined?(SIX_HOST) SIX_PORT = DEFAULT_PORT unless defined?(SIX_PORT) LOCAL_URL = "http://#{SIX_HOST == "0.0.0.0" ? DEFAULT_IP : SIX_HOST}:#{SIX_PORT}" bpath = if ENV['BASE_PATH'] OLDLOCATION = "#{ENV['BASE_PATH']}" unless defined?(OLDLOCATION) "#{ENV['BASE_PATH']}" elsif defined?(OLDLOCATION) OLDLOCATION else Dir.pwd end bpath.gsub!("\\", "/") BASE_PATH = bpath TOOL_PATH = File.join(BASE_PATH, 'tools') args = ARGV.join(" ") if args[/RAILS_ENV=(\w*)/] ENV["RAILS_ENV"] = $1 end rpath, distro = nil, nil case RUBY_PLATFORM when /-mingw32$/, /-mswin32$/ ARMA2 = ['SOFTWARE\\Bohemia Interactive Studio\\ArmA 2', 'MAIN'] ARMA2_ALT = ['SOFTWARE\\Bohemia Interactive\\ArmA 2', 'InstallPath'] ARMA2_STEAM = ['SOFTWARE\\Valve\\Steam\\Common\\ARMA 2', 'InstallPath'] #case RUBY_VERSION # when /1\.8\.[0-9]/ # begin # reg_path = Win32::Registry::HKEY_CURRENT_USER.open("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")['AppData'] # rescue # end #end TEMP_PATH = if ENV['TEMP'] if ENV['TEMP'].size > 0 File.directory?(ENV['TEMP']) ? "#{ENV['TEMP']}" : BASE_PATH else BASE_PATH end else BASE_PATH end # Handles non us-ascii characters on Windows; appdata won't exist etc. HOME_PATH = File.exists?(File.join(ENV['APPDATA'])) ? File.join(ENV['APPDATA']) : TEMP_PATH CMD_EXE = File.join(ENV['WINDIR'], 'system32', 'cmd.exe') # TODO: Deprecated; This has moved to the six-updater-web.rb included in the windows suite # But requires everyone to update to it, unless we do it for them :D path = File.join(BASE_PATH, "tools") rubypath = File.join(path, 'ruby', 'bin') tpath = "#{path};#{File.join(path, 'bin')};#{rubypath}" tpath.gsub!('/', '\\') ENV['PATH'] = "" unless ENV['PATH'] ENV['PATH'] = "#{tpath};#{ENV['PATH']}" unless ENV['PATH'].include?(tpath) begin rpath = Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, ARMA2_STEAM[0] + " OA")[ARMA2_STEAM[1]] distro = "OA STEAM" rescue begin rpath = Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, ARMA2_ALT[0] + " OA")[ARMA2_ALT[1]] distro = "OA ALT" rescue begin rpath = Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, ARMA2[0] + " OA")[ARMA2[1]] distro = "OA STANDARD" rescue begin rpath = Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, ARMA2_STEAM[0])[ARMA2_STEAM[1]] distro = "A2 STEAM" rescue begin rpath = Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, ARMA2_ALT[0])[ARMA2_ALT[1]] distro = "A2 ALT" rescue begin rpath = Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, ARMA2[0])[ARMA2[1]] distro = "A2 STANDARD" rescue end end end end end end else HOME_PATH = "#{ENV['HOME']}" # Unfreezes the string TEMP_PATH = '/tmp' end DATA_PATH = File.join(File.exists?(File.join(BASE_PATH, "legacy.txt")) ? BASE_PATH : HOME_PATH, "six-updater") # COMPONENT) ARMA_PATH, DISTRO = rpath, distro FileUtils.mkdir_p DATA_PATH unless File.directory?(DATA_PATH) PID_FILE = File.join(DATA_PATH, "#{COMPONENT}.pid") File.open(PID_FILE, 'w') {|f| f.puts Process.pid} module_function def update_gamespy(nogeo = nil) puts "Fetching server info..." geo = ENV['NOGEO'] || nogeo ? "" : nil #geo = "" types = ENV['GAMESPY_TYPES'].split(",") puts "Pings and Countries: #{geo.nil?}" puts "" ids = [] types.each do |game| q = Six::Query::GamespyMaster.new(geo, game) h = q.process puts "" puts "Received #{h.size} servers" puts "" puts "Updating database..." i, saved = 0, 0 #hasj = Hash.new timestart = Time.now h.each_pair do |key, e| i += 1 time = Time.now r = Queryserver.import(e) next unless r if r[0].changed? #hasj[r[0].id] = r[1] saved += 1 r[0].save else ids << r[0].id end print "#{i} / #{h.keys.size}, took #{SixUpdaterWeb::stamp(time)}s\r" end puts "Saved: #{saved}, Unchanged: #{h.keys.size - saved}. Took: #{SixUpdaterWeb::stamp(timestart)}s" end =begin timestart = Time.now puts "Updating #{hasj.keys.size} records..." begin Queryserver.update(hasj.keys, hasj.values) unless hasj.keys.empty? rescue => e puts "#{e.class}: #{e.message} #{e.backtrace.join("\n")}" sleep 3 ensure puts "Took: #{SixUpdaterWeb::stamp(timestart)}s" end =end timestart = Time.now puts "Tagging... #{ids.size} records" begin Queryserver.update_all("updated_at = '#{Time.now}'", ["id in (?)",ids]) unless ids.empty? rescue => e puts "#{e.class}: #{e.message} #{e.backtrace.join("\n")}" ensure puts "Took: #{SixUpdaterWeb::stamp(timestart)}s" end puts "Pruning database..." timestart = Time.now Queryserver.prune puts "Took: #{SixUpdaterWeb::stamp(timestart)}s" puts "Cleaning database..." timestart = Time.now Queryserver.clean puts "Took: #{SixUpdaterWeb::stamp(timestart)}s" puts "" puts "Done!" end def mirror_priority puts "Checking mirror latencies, please be patient..." repos = Repository.rank(true) puts repos.each do |rep| puts "#{rep.priority} - #{rep.ping_value} - #{rep.url}" end end def logger ActiveRecord::Base.logger end def stamp(time) (Time.now - time).to_s[/(.*\..?.?.?)/] $1 end def initialize(config) if defined?(OLDLOCATION) config.log_path = File.join(DATA_PATH, 'logs', 'six-updater-web.log') end end def print_info puts "Six Updater Web (GUI) #{VERSION}, by Sickboy" puts "BASE: #{BASE_PATH}" puts "DATA: #{DATA_PATH}" puts "ARMA: #{DISTRO} PATH: #{ARMA_PATH}" end def after_initialize if defined?(OLDLOCATION && SPECIAL) # Open the browser return unless defined?(OPEN_BROWSER) case RUBY_PLATFORM when /-mingw32$/, /-mswin32$/ Thread.new() do file_to_use = "#{LOCAL_URL}/main" sleep 3 iron = File.join(BASE_PATH, "tools", "IronPortable", "IronPortable.exe") chrome = File.join(BASE_PATH, "tools", "GoogleChromePortable", "GoogleChromePortable.exe") if File.exists?(iron) Dir.chdir(File.dirname(iron)) do system "cmd /c \"#{iron}\" --app=#{file_to_use}" end elsif File.exists?(chrome) Dir.chdir(File.dirname(chrome)) do system "cmd /c \"#{chrome}\" --app=#{file_to_use}" end else system "start #{file_to_use}" end end end end end def update_site_controllers from_classes = Goldberg::SiteController.classes from_db = Goldberg::SiteController.find(:all, :order => 'name') known = Hash.new missing = Array.new for dbc in from_db do if from_classes.has_key? dbc.name known[dbc.name] = dbc else missing << dbc end end unknown = Hash.new app = Array.new builtin = Array.new for name in from_classes.keys.sort do if known.has_key? name if known[name].builtin == 1 builtin << known[name] else app << known[name] end else unknown[name] = from_classes[name] end end saved = false logger.info "Unknown: #{unknown.inspect}" unknown.keys.each do |name| h = Hash.new h[:name] = name h[:permission_id] = 1 # TODO: Search for it instead? h[:builtin] = 0 site_controller = Goldberg::SiteController.new(h) if site_controller.save #flash[:notice] = 'SiteController was successfully created.' saved = true else #foreign #render :action => 'new' end end Goldberg::Role.rebuild_cache if saved end def run_program(exec, startpath, cl) logger.info "Current Path: #{Dir.pwd}, BASE_PATH: #{BASE_PATH}, DATA_PATH: #{DATA_PATH}" logger.info "Starting with #{cl} from #{startpath}" # TODO: Cleanup startpath = "#{startpath}" begin case RUBY_PLATFORM when /-mingw32$/, /-mswin32$/ cl = "\"#{exec}\" #{cl}" cl = "/C #{cl}" logger.info "#{CMD_EXE} #{cl}" struct = Process.create( :app_name => CMD_EXE, :command_line => cl, :creation_flags => Process::DETACHED_PROCESS, :process_inherit => false, :thread_inherit => false, :cwd => startpath, :inherit => false #:environment => "" ) else Dir.chdir(startpath) do # TODO: Properly create seperate process like on windows.. or maybe this is fine just needs 2>&1 >> /dev/null ? # as logfiles deliver the feedback, or rather run integrated. However maybe when running in a desktop environment # maybe it's useful to open a new terminal window/tab .. p = Process.fork do logger.info "#{exec} #{cl}" system "#{exec} #{cl}" end end #logger.info "Unimplemented on current platform: #{RUBY_PLATFORM}" end rescue => e logger.info "WARNING: Something went wrong starting the app" logger.info "#{e.class}: #{e.message} #{e.backtrace.join("\n")}" end end end