lib/gamefic/shell.rb in gamefic-1.1.0 vs lib/gamefic/shell.rb in gamefic-1.2.0
- old
+ new
@@ -1,25 +1,75 @@
+require 'thor'
+require 'gamefic/engine/tty'
+require 'zip'
+require 'tmpdir'
+require 'yaml'
+
module Gamefic
+ class Shell < Thor
+ map %w[--version -v] => :version
- class Shell
- autoload :Command, 'gamefic/shell/command'
+ desc "--version, -v", "Print the version"
+ def version
+ puts "gamefic #{Gamefic::VERSION}"
+ end
- def initialize
- @commands = {}
+ desc 'play FILE_NAME', 'Execute a compiled (.gfic) game'
+ option :verbose, type: :boolean, aliases: :v, desc: "Don't suppress Ruby exceptions"
+ def play(file)
+ Dir.mktmpdir 'gamefic_' do |dir|
+ puts 'Loading...'
+ decompress file, dir
+ run_game(dir)
+ end
+ rescue StandardError => e
+ puts "'#{file}' does not appear to be a valid Gamefic file."
+ show_exception(e) if options[:verbose]
end
+
+ desc 'info FILE_NAME', 'Print information about a (.gfic) game'
+ option :verbose, type: :boolean, aliases: :v, desc: "Don't suppress Ruby exceptions"
+ def info(file)
+ Dir.mktmpdir 'gamefic_' do |dir|
+ decompress file, dir
+ metadata = YAML.load_file File.join(dir, 'metadata.yaml')
+ metadata.each { |k, v|
+ puts "#{k}: #{v}"
+ }
+ end
+ rescue StandardError, Zip::Error => e
+ puts "'#{file}' does not appear to be a valid Gamefic file."
+ show_exception(e) if options[:verbose]
+ end
- def register cmd, cls
- @commands[cmd] = cls
+ # Custom error message for invalid command or filename
+ def method_missing(symbol, *args)
+ raise UndefinedCommandError, "Could not find command or file named \"#{symbol}\"."
end
- def execute
- command = ARGV[0]
- cls = @commands[command]
- if cls.nil?
- Gamefic::Shell::Command::Play.new.run(['play'] + ARGV)
- else
- cls.new.run ARGV
+ private
+
+ def show_exception(exception)
+ puts exception.inspect
+ puts exception.backtrace.join("\n")
+ end
+
+ def decompress(zipfile, destination)
+ Zip::File.open(zipfile) do |z|
+ z.each do |entry|
+ FileUtils.mkdir_p File.join(destination, File.dirname(entry.name))
+ full_path = File.join(destination, entry.name)
+ entry.extract full_path unless File.exist?(full_path)
+ end
end
end
+
+ def run_game(directory)
+ story = Plot.new(Source::File.new(File.join(directory, 'scripts')))
+ story.script 'main'
+ story.metadata = YAML.load_file File.join(directory, 'metadata.yaml')
+ engine = Tty::Engine.new story
+ puts "\n"
+ engine.run
+ end
end
-
end