Code Search for Developers
 
 
  

client.rb from Thousand Parsec at Krugle


Show client.rb syntax highlighted


require 'socket'
require 'packet'

DEFAULT_PORT = 6923
DEFAULT_SSL_PORT = 6924

TPProto::XMLParser.define_packets_from_xml 'protocol.xml'

class String
  def underscore
    gsub(/([A-Z0-9]{2,}s?|[A-Z][^A-Z]+)(?=$|[A-Z])/, '_\1').sub(/^_/, '').downcase
  end
end

class TPConnection
  FrameHandler = Struct.new(:frame_type, :max_calls, :block)

  def initialize(host='demo1.thousandparsec.net', port=DEFAULT_PORT)
    @conn = TCPSocket.new( host, port )
    @handlers = []
    @unprocessed = []
    handle :sequence, -1 do |frame|
      frames = []
      frame.number.times do
        frames << get_unprocessed
      end
      prototype = (frames.find {|fr| !(TPProto::Fail === fr) } || frames.first)
      invoke_handler frame_type_from_frame(prototype), frames
    end
  end
  TPProto::PacketNames.each do |name, klass|
    method_name = name.underscore
    class_eval <<-END, __FILE__, __LINE__
    def #{method_name}(*a)
      @conn.write #{klass.name}.new(*a).to_wire
    end
    def #{method_name}!(*a)
      #{method_name} *a
      result = get_unprocessed
      if TPProto::Fail === result
        raise "Protocol error: \#{result}"
      end
      result
    end
    END
  end
  def handle(frame_type, max_calls=1, &block)
    max_calls = nil unless Integer === max_calls || max_calls < 1
    @handlers << FrameHandler.new(frame_type, max_calls, block)
  end
  def check_queue!
    if frame = read(false)
      process_frame frame
    end
  end
  def process_frame(frame)
    invoke_handler frame_type_from_frame(frame), frame
  end
  def frame_type_from_frame(frame)
    frame.class.name.sub(/.*::/, '').underscore
  end
  def invoke_handler(frame_type, frame)
    if handler = @handlers.find {|hd| hd.frame_type.to_s == frame_type }
      handler.block.call *[frame].flatten
      handler.max_calls -= 1 if handler.max_calls
      @handlers.delete handler if handler.max_calls == 0
    else
      @unprocessed << frame
    end
    handler
  end
  def read(block=true)
    # FIXME: Shouldn't be hard-coding the header length :|
    begin
      wire_header = @conn.__send__(block ? :recvfrom : :recvfrom_nonblock, 16)[0]
    rescue Errno::EAGAIN
      return nil
    end

    return nil unless wire_header && wire_header != ''
    header = TPProto::Header.from_wire( wire_header )
    wire_payload = ''
    while wire_payload.size < header.length
      wire_payload << @conn.recvfrom( header.length - wire_payload.size )[0]
    end
    packet = TPProto::Header.load( wire_header + wire_payload )
  end
  def get_unprocessed
    process_frame( read ) while @unprocessed.empty?
    @unprocessed.shift
  end
end


def object_tree(root=nil, indent='')
  root ||= $conn.get_objects_by_id!([0]).first
  n = 1

  puts indent + root.class.name.sub(/.*::/, '') + ' #' + root.id.to_s + ' - ' + root.name
  children = $conn.get_objects_by_id!(root.contains)
  children.each do |child|
    n += object_tree(child, indent + '  ')
  end

  n
end





See more files for this project here

Thousand Parsec

Thousand Parsec is a framework for turn based 4 X\'s game (eXplore, eXpand, eXploit, eXterminate). Designed for long games, supporting massive universes and has an easily expanded tech tree.

Project homepage: http://sourceforge.net/projects/thousandparsec
Programming language(s): C++,Python
License: other

  client.rb
  libtpproto-rb.tailor
  pack.rb
  packet.rb
  socket_support.rb
  test_client_help.rb
  test_server.rb
  wire-demo.rb