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
The data in this packet.
@see [] @return [Hash]
The type of struct this packet is. See {Structs}.
@return [Symbol]
Public Class Methods
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
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
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
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
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
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
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
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
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
Pretty inspect.
@return [String]
# File lib/nova/starbound/protocol/packet.rb, line 180 def inspect "#<#{self.class.name}:#{@struct}:#{@data}>" end
Forwards requests on this packet of unkown methds to the data hash.
@return [Object]
# 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
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
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
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
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