class Nova::Starbound::Protocol::Packet

Handles serialization and deserialization of packets.

Constants

CloseReasons

For checking why the protocol was closed.

Structs

Used internally to check the types of packets when unpacking.

Type

A list of the types of packets in existance, and their packet_type codes.

Attributes

data[R]

The data in this packet.

@see [] @return [Hash]

struct[R]

The type of struct this packet is. See {Structs}.

@return [Symbol]

Public Class Methods

build(type, body, others = {}) click to toggle source

Builds a packet from a given body.

@param type [Symbol] the type of packet it is. See {Type}. @param body [String] the body of the packet. @param others [Hash] the data to pass to the struct. See

the packet struct definition to see what keys are allowed.

@return [Packet] the packet data.

# File lib/nova/starbound/protocol/packet.rb, line 84
def self.build(type, body, others = {})
  packet_data = {
    :packet_type => Packet.types[type],
    :body        => body,
    :size        => body.bytesize
  }.merge(others)

  # Packet.struct[:packet].pack(packet_data)
  Packet.new(:packet, packet_data)
end
build_response(type, body, packet_data = {}, others = {}) click to toggle source

Builds a response from a given body. Doesn’t increment the packet id, as a response doesn’t have a packet id.

@param type [Symbol] the type of packet. See {Type}. @param body [String] the body of the packet. @param packet_data [Hash<Symbol, Numeric>] the packet data

that this is a response to.

@param others [Hash] the data to pass to the struct. See

the response struct definition to see what keys are
allowed.

@option packet_data [Numeric] :packet_id the packet id this

response is a response to.

@option packet_data [Numeric] :packet_type the packet type

this response is a response to.

@return [Packet] the packet data.

# File lib/nova/starbound/protocol/packet.rb, line 110
def self.build_response(type, body, packet_data = {}, others = {})
  response_data = {
    :packet_response_id   => packet_data[:packet_id] ||
      packet_data[:packet_response_id],
    :packet_response_type => packet_data[:packet_type],
    :packet_type          => Packet.types[type],
    :body                 => body,
    :size                 => body.bytesize
  }.merge(others)

  # Packet.struct[:response].pack(response_data)
  Packet.new(:response, response_data)
end
from_socket(sock) click to toggle source

Unpacks a struct from a socket.

@param sock [#read, seek] the socket to read from. @raise [NoStructError] if it can’t determine the struct

type.

@return [Packet]

# File lib/nova/starbound/protocol/packet.rb, line 130
def self.from_socket(sock)
  # we're gonna read one byte to see what type of packet it
  # is, a response or a regular packet.
  struct_type_num = sock.read(1)

  struct_type = Structs.key(
    struct_type_num.unpack("c").first)

  unless struct_type
    raise NoStructError,
      "Undefined struct type #{struct_type_num.inspect}"
  end

  data = Packet.struct[struct_type].unpack_from_socket(sock)
  Packet.new(struct_type, data)
end
new(struct, data) click to toggle source

Initialize the packet.

@param struct [Symbol] the type of struct. @param data [Hash] the packet data.

# File lib/nova/starbound/protocol/packet.rb, line 162
def initialize(struct, data)
  @struct = struct
  @data = data
end
types() click to toggle source

Provides access to the {Type} constant.

@return [Hash]

# File lib/nova/starbound/protocol/packet.rb, line 73
def self.types
  Type
end

Public Instance Methods

body=(body) click to toggle source

Sets the body and the size for this packet.

@param body [String] the new body. @return [void]

# File lib/nova/starbound/protocol/packet.rb, line 204
def body=(body)
  data[:body] = body
  data[:size] = body.bytesize
end
expect(type) click to toggle source

Checks this packet for the expected type.

@raise [UnacceptablePacketError] if the type doesn’t match.

# File lib/nova/starbound/protocol/packet.rb, line 212
def expect(type)
  if self.type != type
    raise UnacceptablePacketError,
      "Expected packet to be of type #{type}, " +
      "got #{self.type} instead"
  end
end
id() click to toggle source

Forwards to the data key :packet_id, or if that doesn’t exist, :packet_response_id.

@return [Numeric]

# File lib/nova/starbound/protocol/packet.rb, line 188
def id
  @data[:packet_id] || @data[:packet_response_id]
end
initialize_copy(other) click to toggle source

Copies the data over to the new packet. This is used when clone or dup is copied on the instance.

@api private @return [void]

# File lib/nova/starbound/protocol/packet.rb, line 225
def initialize_copy(other)
  other.data = self.data.clone
end
inspect() click to toggle source

Pretty inspect.

@return [String]

# File lib/nova/starbound/protocol/packet.rb, line 180
def inspect
  "#<#{self.class.name}:#{@struct}:#{@data}>"
end
method_missing(method, *args, &block) click to toggle source

Forwards requests on this packet of unkown methds to the data hash.

@return [Object]

Calls superclass method
# File lib/nova/starbound/protocol/packet.rb, line 233
def method_missing(method, *args, &block)
  if @data.respond_to?(method)
    @data.public_send(method, *args, &block)
  elsif @data.key?(method)
    @data[method]
  elsif @data.key?(key = :"packet_#{method}")
    @data[key]
  else
    super
  end
end
respond_to_missing?(method, include_all = false) click to toggle source

Defined so ruby knows we’re doing method_missing magic.

@param method [Symbol] the method to check for. @param include_all [Boolean] whether or not to include

private and protected methods.

@return [Boolean]

# File lib/nova/starbound/protocol/packet.rb, line 251
def respond_to_missing?(method, include_all = false)
  @data.respond_to?(method, include_all) || @data.key?(method)
end
to_s() click to toggle source

Turn this packet into a string.

@return [String]

# File lib/nova/starbound/protocol/packet.rb, line 170
def to_s
  @_cache ||= [Structs[@struct]].pack("c") +
    Packet.struct[@struct].pack(@data)
end
Also aliased as: to_str
to_str()
Alias for: to_s
type() click to toggle source

The type of packet this is. Checks {Packet.types} before returning just the number.

@return [Symbol, Numeric]

# File lib/nova/starbound/protocol/packet.rb, line 196
def type
  Packet.types.key(@data[:packet_type]) || @data[:packet_type]
end

Protected Instance Methods

data=(data) click to toggle source

Sets the data to the given argument.

@api private @param data [Hash] the data to set to. @return [void]

# File lib/nova/starbound/protocol/packet.rb, line 262
def data=(data)
  @data = data
end