#!/usr/bin/env ruby # $Revision: 1.32 $ # $Date: 2003/12/06 18:12:08 $ # $Author: jefus, mikeman2 $ class Connection attr_accessor :socket, :address, :name, :player def initialize(socket) @socket = socket @address = [@socket.peeraddr[3], @socket.peeraddr[1]] @name = "someone" @player = nil Logger.log("#{self} connected.") Thread.abort_on_exception = true Thread.start do write(IO.readlines("../banner").join.gsub(/\n/, "\n\r")) # do login stuff write("login: ") begin # any errors are passed on to the drop method for clean handling @name = gets(nolog = true).capitalize # try and load the specified player from the database if $system.pidHash.attributes.key?(@name) @player = Player.new($system.pidHash[@name]) # player exists, so attach the connection object to it @player.connection = self # now we'll verify the password write("Password: ") if gets(nolog = true, obfuscate = true).encrypt.dump.delete('\\').chop.reverse.chop.reverse == $system.passwd[@name] #don't even ask :P # matches. greet the player and send him into the game. Logger.log("#{@address[0]}:#{@address[1]} authenticated as #{@name}") puts(IO.readlines("../motd").join.gsub(/\n/, "\n\r")) @player.enterGame else puts("Wrong password.") drop("wrong password") end else #god this took about 4 hours to debug. why does crypt have to return a string containing bogus escape chars? pid = $system.pidHash.attributes.length #we would want to add 1 but the first pid is 0 @player = Player.new(pid) @player.name = @name @player.connection = self $system.pidHash[@name] = pid.to_s # try and try until the player gets this shit right passwordsMatch = false while not passwordsMatch write("Choose a password: ") password = gets(nolog = true) write("Enter it again to confirm: ") password2 = gets(nolog = true) if password == password2 passwordsMatch = true # exit the loop after this puts("#{@player} created.") $system.passwd[@name] = password.encrypt.dump.delete('\\').chop.reverse.chop.reverse #hehe.. gotta format the passwd hash so it stores properly in the database else # i felt like ganking this line from lima. this will all be # done on the web in the future anyways. puts("Socks don't have to match, but passwords do. Try again.") #this is the worst joke i've heard all week end end @player.enterGame(new = true) @player.save Logger.log("#{self}> New user successfully created.") end rescue drop($!) break end # main command loop while true # note from jefus to jefus: add some prompt code here, and some in # player.rb begin line = gets command, args = line.split(/ /, 2) command.downcase! if command args = "" if not args case command # built-in aliases... for now when "l" command = "look" when "n" command = "north" when "s" command = "south" when "e" command = "east" when "w" command = "west" when "u" command = "up" when "d" command = "down" when "o" command = "out" when "inv" command = "inventory" end method = "do_#{command}" #p command #p $system.commands handled = false if $system.commands.include?(command) access = $system.commands[command].access if @player.access >= access Commands.send(method, @player, args) else @player.puts("You don't have access to that command.") handled = true end else if @player.location if @player.location.has_exit?(command) handled = true @player.puts("You go #{command}.") @player.move($system.rooms.fetch(@player.location.exit(command).rid)) #else # puts("Huh?") end end if command =~ /'(.+)/ handled = true Commands.send("do_say", @player, "#{$1} " << args) if args.length > 0 Commands.send("do_say", @player, $1) if args == "" else @player.puts("Huh?") if handled == false end end rescue drop($!) break end end end end def drop(error = nil) @socket.close if @socket if error Logger.log("#{self} lost connection. (#{error})\n*******TRACE**********\n#{$@}") Logger.log($@) else Logger.log("#{self} lost connection. (no error)") end $system.server.connections.delete(self) if @player Logger.log("Saving #{@player}...") @player.location.contents.delete(@player) @player.save end Thread.stop end def write(string) @socket.write(string.ansify) if @socket end def puts(line) @socket.puts(line.ansify) if @socket end def gets(nolog = false, obfuscate = false) error = "no error" begin line = @socket.gets if line line.chomp!.chomp! Logger.log("#{self}> #{line}") if nolog == false if obfuscate == true logline = "#{self}> " for i in line.length logline << "*" end Logger.log(logline) end end rescue error = $! end if line return line else raise error end end def to_s return "#{@name}@#{@address[0]}:#{@address[1]}" end end