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.



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

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)



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

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)



192
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
# File 'lib/romloader/romloader_cli.rb', line 192

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



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

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



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

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)


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

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…)



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

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…)



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

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…)



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

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



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

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”)



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

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



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

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

#startObject

Starts the CLI, called in romloader.rb



10
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
# File 'lib/romloader/romloader_cli.rb', line 10

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]:", /\A[#{system.get_rom_indices.join.downcase}]{1}\Z/,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]:", /\A[yn]{1}\Z/, 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]:", /\A[yn]{1}\Z/,control_flow_level)
            else
              input = input_prompt("Open #{file_or_dir_to_open}? (y/N) [exit]:", /\A[yn]{1}\Z/,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