Class: RomLoader::RomLoaderCli

Inherits:
Object
  • Object
show all
Defined in:
lib/romloader/romloader_cli.rb

Overview

The CLI class

Instance Method Summary collapse

Constructor Details

#initializeRomLoaderCli

Returns a new instance of RomLoaderCli.



5
6
7
8
# File 'lib/romloader/romloader_cli.rb', line 5

def initialize
  RomLoader::GameSystem.create_from_collection(RomLoader::FreeromsScraper.system_scrape("http://freeroms.com"))
  raise RomLoader::ScrapingError::NoElementFound.exception("ERROR: Systems index is currently unavailable. Exiting the program.") if RomLoader::GameSystem.all.size == 0
end

Instance Method Details

#display_rom_details(game) ⇒ Object

List the details of the selected game (e.g. Chrono Trigger | SNES | 5.38 MB | .zip)



160
161
162
163
164
# File 'lib/romloader/romloader_cli.rb', line 160

def display_rom_details(game)
  puts "Rom details:"
  puts "#{game.name} | System: #{game.system.name} | File size: #{game.size} | File type: #{game.file_ext}"
  print "\n"
end

#download_rom(game) ⇒ Object

Downloads the selected game to the local directory (~/videogame_roms)



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/romloader/romloader_cli.rb', line 193

def download_rom(game)
  file_or_dir_to_open = nil
  extract_dir = RomLoader::ArchiveExtractor.create_extract_dir(game)
  if !File.exist?(File.join(extract_dir,game.filename))
    puts "Downloading #{game.name} (#{game.size})..."
    if isWindows?
      result = Dir.chdir(extract_dir) { system("powershell -command \"& { Invoke-WebRequest '#{game.download_url}' -OutFile '#{game.filename}' }\"") }
    else
      result = Dir.chdir(extract_dir) { system("curl -Og# \"#{game.download_url}\"") }
    end

    if result && !isWindows? && game.system.name != "MAME"
      puts "Finished downloading #{game.filename} to #{extract_dir}. Extracting..."
      file_or_dir_to_open = RomLoader::ArchiveExtractor.extract(File.join(extract_dir,game.filename),extract_dir,game)
      RomLoader::ArchiveExtractor.delete_archive(File.join(extract_dir,game.filename))
    elsif result && !isWindows? && game.system.name == "MAME"
      puts "Finished downloading #{game.filename} to #{extract_dir}."
      puts "NOTE: No archive extraction. MAME roms must remain zipped to play."
      file_or_dir_to_open = extract_dir
    elsif result && isWindows?
      puts "Finished downloading #{game.filename} to #{extract_dir}."
      file_or_dir_to_open = extract_dir
    else
      puts "An error occured, the rom couldn't be downloaded.\n\n"
    end
  else
    puts "File already exists.\n\n"
  end

  sleep 2
  file_or_dir_to_open
end

#flow_controller(input, control_flow_level, input_stack) ⇒ Object

Sets control_flow_level in RomLoaderCli#start, manipulates input_stack in RomLoaderCli#start



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/romloader/romloader_cli.rb', line 101

def flow_controller(input,control_flow_level,input_stack)
  if input == "exit"
    0
  elsif input == "back"
    input_stack.shift
    control_flow_level - 1
  else
    input_stack.unshift(input)
    control_flow_level + 1
  end
end

#input_prompt(message, accepted_input, control_flow_level = nil) ⇒ Object

Prints a custom message, takes user input, asesses whether the input is valid, and returns the input



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/romloader/romloader_cli.rb', line 167

def input_prompt(message,accepted_input,control_flow_level=nil)
  valid = false
  until valid 
    print message + " "
    input = gets.chomp.strip.downcase
    if accepted_input.class == Regexp && accepted_input.match(input)
      valid = true
    elsif accepted_input.class == Range && /\A\d+\Z/.match(input) && accepted_input.include?(input.to_i)
      valid = true
    elsif input == "exit" || (input == "back" &&  control_flow_level && control_flow_level.between?(2,3))
      valid = true
    elsif input == "" && control_flow_level == 4
      valid = true
    else
      print "Invalid input! "
    end
  end
  print "\n"
  input
end

#isWindows?Boolean

Returns:

  • (Boolean)


188
189
190
# File 'lib/romloader/romloader_cli.rb', line 188

def isWindows?
  /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
end

#list_games(games) ⇒ Object

List all the games available for the selected index (e.g. “S”: 1. Super Castlevania, 2. Super Mario World, etc…)



147
148
149
150
# File 'lib/romloader/romloader_cli.rb', line 147

def list_games(games)
  games.each_with_index {|game,index| puts "#{index+1}. #{game.name}"}
  print "\n"
end

#list_system_index(selected_system) ⇒ Object

List game index for the selected system by letter (e.g. A B C D…)



127
128
129
130
131
132
133
134
135
# File 'lib/romloader/romloader_cli.rb', line 127

def list_system_index(selected_system)
  if selected_system.get_rom_indices.empty?
    selected_system.rom_indices = RomLoader::FreeromsScraper.rom_index_scrape(selected_system.rom_index_url)
  end
  
  puts "#{selected_system.name} index:"
  selected_system.get_rom_indices.each {|letter| print letter + " "}
  puts "\n\n"
end

#list_systemsObject

Lists the game systems scraped from freeroms.com and saved in Romloader::GameSystem.all (e.g. 1. Amiga, 2. Atari, etc…)



115
116
117
118
# File 'lib/romloader/romloader_cli.rb', line 115

def list_systems 
  RomLoader::GameSystem.all.each_with_index { |game_system, index| puts "#{index+1}. #{game_system.name}"}
  print "\n"
end

#select_game(game_collection, index) ⇒ Object

Selects an individual game from the provided collection via index



153
154
155
156
# File 'lib/romloader/romloader_cli.rb', line 153

def select_game(game_collection,index)
  game_collection[index-1].set_rom_details(RomLoader::FreeromsScraper.rom_details(game_collection[index-1].rom_detail_url))
  game_collection[index-1]
end

#select_game_collection_by_index(system, letter) ⇒ Object

Retrieves all the games available for the selected system under the selected index (e.g. NES,“G”)



139
140
141
142
143
# File 'lib/romloader/romloader_cli.rb', line 139

def select_game_collection_by_index(system, letter)
  puts "Loading roms...\n"
  games_list = system.get_roms_by_letter(letter)
  games_list ||= system.add_roms_to_collection_by_letter(letter,RomLoader::GameRom.create_collection(RomLoader::FreeromsScraper.rom_scrape(system.get_rom_collection_url(letter))))
end

#select_system(index) ⇒ Object

Retrieves an individual Romloader::GameSystem object from Romloader::GameSystem.all



121
122
123
# File 'lib/romloader/romloader_cli.rb', line 121

def select_system(index)
  RomLoader::GameSystem.all[index-1]
end

#startObject

Starts the CLI, called in romloader.rb



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/romloader/romloader_cli.rb', line 11

def start
  input_stack = []
  control_flow_level = 1

  puts "\nThanks for using RomLoader, powered by freeroms.com!\nNOTE: To play the games, please download an emulator for the desired system.\nConnecting to freeroms.com and retrieving the systems index...\n\n"
  sleep 3
  while control_flow_level > 0 
    case control_flow_level
    when 1
      list_systems
      input = input_prompt("Select a system (1-#{RomLoader::GameSystem.all.size}) [exit]:",1..RomLoader::GameSystem.all.size)
      if input == "exit"
        control_flow_level = 0
      else
        input_stack.unshift(input)
        control_flow_level += 1
      end
    when 2
      system = select_system(input_stack[0].to_i)
      list_system_index(system)
      if system.get_rom_indices.empty?
        begin
          raise RomLoader::ScrapingError::NoElementFound.exception("ERROR: Requested system is currently unavailable. Try another one.")
        rescue => e
          puts "#{e.message}\n\n"
          sleep 2
          control_flow_level -= 1
          input_stack.shift
        end 
      else
        input = input_prompt("Select a letter [back|exit]:", /[#{system.get_rom_indices.join.downcase}]/,control_flow_level)
        control_flow_level = flow_controller(input,control_flow_level,input_stack)
      end
    when 3
      game_collection = select_game_collection_by_index(system,input_stack[0].upcase)
      if game_collection.empty?
        begin
          raise RomLoader::ScrapingError::NoElementFound.exception("ERROR: Requested game index is currently unavailable. Try another one.")
        rescue => e
          puts "#{e.message}\n\n"
          sleep 2
          control_flow_level -= 1
          input_stack.shift
        end
      else
        list_games(game_collection)
        input = input_prompt("Select a game (1-#{game_collection.size}) [back|exit]", 1..game_collection.size,control_flow_level)
        control_flow_level = flow_controller(input,control_flow_level,input_stack)
      end
    when 4
      game = select_game(game_collection,input_stack[0].to_i)
      if game.download_url == nil
        begin
          raise RomLoader::ScrapingError::NoElementFound.exception("ERROR: Requested game is currently unavailable. Try another one.")
        rescue => e
          puts "#{e.message}\n\n"
          sleep 2
          control_flow_level -= 1
          input_stack.shift
        end
      else
        display_rom_details(game)
        input = input_prompt("Download? (Y/n) [exit]:", /[yn]/, control_flow_level)
        if input == 'y' || input == ""
          file_or_dir_to_open = download_rom(game)
          if file_or_dir_to_open
            if /\".+\"/.match(file_or_dir_to_open)
              game_file = /\".+\"/.match(file_or_dir_to_open)[0]
              input = input_prompt("Play #{game_file}? (y/N) [exit]:", /[yn]/,control_flow_level)
            else
              input = input_prompt("Open #{file_or_dir_to_open}? (y/N) [exit]:", /[yn]/,control_flow_level)
            end
            
            if !isWindows?
              system("open #{file_or_dir_to_open}") if input == 'y'
            else
              system("powershell -command \"& { Invoke-Item '#{file_or_dir_to_open}' }\"") if input == 'y'
            end
          end 
        end
        input_stack.shift
        input == "exit" ? control_flow_level = 0 : control_flow_level -= 1
      end
    end
  end

  puts "Happy Gaming!\n\n"
end