Class: Nova::Starbound::Protocol::Packet
- Inherits:
-
Object
- Object
- Nova::Starbound::Protocol::Packet
- Extended by:
- PackedStruct
- Defined in:
- lib/nova/starbound/protocol/packet.rb
Overview
Handles serialization and deserialization of packets.
Constant Summary collapse
- Type =
A list of the types of packets in existance, and their packet_type codes.
{ :nul => 0x00, # handshake :protocol_version => 0x01, :encryption_options => 0x02, :public_key => 0x03, # other stuff :standard_error => 0x04, :close => 0x05, # content :echo => 0x06, :password => 0x07, :star_run => 0x08 }.freeze
- Structs =
Used internally to check the types of packets when unpacking.
{ :packet => 0x00, :response => 0x01 }.freeze
- CloseReasons =
For checking why the protocol was closed.
{ :none => 0x00, :shutdown => 0x01 }.freeze
Instance Attribute Summary collapse
-
#data ⇒ Hash
readonly
The data in this packet.
-
#struct ⇒ Symbol
readonly
The type of struct this packet is.
Class Method Summary collapse
-
.build(type, body, others = {}) ⇒ Packet
Builds a packet from a given body.
-
.build_response(type, body, packet_data = {}, others = {}) ⇒ Packet
Builds a response from a given body.
-
.from_socket(sock) ⇒ Packet
Unpacks a struct from a socket.
-
.types ⇒ Hash
Provides access to the Type constant.
Instance Method Summary collapse
-
#body=(body) ⇒ void
Sets the body and the size for this packet.
-
#expect(type) ⇒ Object
Checks this packet for the expected type.
-
#id ⇒ Numeric
Forwards to the data key :packet_id, or if that doesn’t exist,
:packet_response_id. -
#initialize(struct, data) ⇒ Packet
constructor
Initialize the packet.
-
#initialize_copy(other) ⇒ void
private
Copies the data over to the new packet.
-
#inspect ⇒ String
Pretty inspect.
-
#method_missing(method, *args, &block) ⇒ Object
Forwards requests on this packet of unkown methds to the data hash.
-
#respond_to_missing?(method, include_all = false) ⇒ Boolean
Defined so ruby knows we’re doing #method_missing magic.
-
#to_s ⇒ String
(also: #to_str)
Turn this packet into a string.
-
#type ⇒ Symbol, Numeric
The type of packet this is.
Constructor Details
#initialize(struct, data) ⇒ Packet
Initialize the packet.
162 163 164 165 |
# File 'lib/nova/starbound/protocol/packet.rb', line 162 def initialize(struct, data) @struct = struct @data = data end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
Forwards requests on this packet of unkown methds to the data hash.
233 234 235 236 237 238 239 240 241 242 243 |
# 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 |
Instance Attribute Details
#data ⇒ Hash
The data in this packet.
156 157 158 |
# File 'lib/nova/starbound/protocol/packet.rb', line 156 def data @data end |
#struct ⇒ Symbol (readonly)
The type of struct this packet is. See Structs.
150 151 152 |
# File 'lib/nova/starbound/protocol/packet.rb', line 150 def struct @struct end |
Class Method Details
.build(type, body, others = {}) ⇒ Packet
Builds a packet from a given body.
84 85 86 87 88 89 90 91 92 93 |
# 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 = {}) ⇒ Packet
Builds a response from a given body. Doesn’t increment the packet id, as a response doesn’t have a packet id.
110 111 112 113 114 115 116 117 118 119 120 121 122 |
# 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) ⇒ Packet
Unpacks a struct from a socket.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# 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 |
.types ⇒ Hash
Provides access to the Type constant.
73 74 75 |
# File 'lib/nova/starbound/protocol/packet.rb', line 73 def self.types Type end |
Instance Method Details
#body=(body) ⇒ void
This method returns an undefined value.
Sets the body and the size for this packet.
204 205 206 207 |
# File 'lib/nova/starbound/protocol/packet.rb', line 204 def body=(body) data[:body] = body data[:size] = body.bytesize end |
#expect(type) ⇒ Object
Checks this packet for the expected type.
212 213 214 215 216 217 218 |
# 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 ⇒ Numeric
Forwards to the data key :packet_id, or if that doesn’t exist, :packet_response_id.
188 189 190 |
# File 'lib/nova/starbound/protocol/packet.rb', line 188 def id @data[:packet_id] || @data[:packet_response_id] end |
#initialize_copy(other) ⇒ void
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
This method returns an undefined value.
Copies the data over to the new packet. This is used when #clone or #dup is copied on the instance.
225 226 227 |
# File 'lib/nova/starbound/protocol/packet.rb', line 225 def initialize_copy(other) other.data = self.data.clone end |
#inspect ⇒ String
Pretty inspect.
180 181 182 |
# File 'lib/nova/starbound/protocol/packet.rb', line 180 def inspect "#<#{self.class.name}:#{@struct}:#{@data}>" end |
#respond_to_missing?(method, include_all = false) ⇒ Boolean
Defined so ruby knows we’re doing #method_missing magic.
251 252 253 |
# 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 ⇒ String Also known as: to_str
Turn this packet into a string.
170 171 172 173 |
# File 'lib/nova/starbound/protocol/packet.rb', line 170 def to_s @_cache ||= [Structs[@struct]].pack("c") + Packet.struct[@struct].pack(@data) end |
#type ⇒ Symbol, Numeric
The type of packet this is. Checks types before returning just the number.
196 197 198 |
# File 'lib/nova/starbound/protocol/packet.rb', line 196 def type Packet.types.key(@data[:packet_type]) || @data[:packet_type] end |