Module: Nova::Starbound::Protocol::Socket

Included in:
Nova::Starbound::Protocol
Defined in:
lib/nova/starbound/protocol/socket.rb

Overview

Handles sending data on the socket.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#current_packet_idNumeric (readonly)

The current packet id.

Returns:

  • (Numeric)


23
24
25
# File 'lib/nova/starbound/protocol/socket.rb', line 23

def current_packet_id
  @current_packet_id
end

#queueQueue (readonly)

The queue that holds messages.

Returns:

  • (Queue)


18
19
20
# File 'lib/nova/starbound/protocol/socket.rb', line 18

def queue
  @queue
end

#socket#read, #write

The socket to write data to.

Returns:



13
14
15
# File 'lib/nova/starbound/protocol/socket.rb', line 13

def socket
  @socket
end

Instance Method Details

#callbacksHash<Symbol, Object>

The callbacks that have been defined on this protocol.

Returns:

  • (Hash<Symbol, Object>)

    the symbol is the type of packet.



149
150
151
# File 'lib/nova/starbound/protocol/socket.rb', line 149

def callbacks
  @_callbacks ||= Hash.new { |h, k| h[k] = [] }
end

#closevoid

This method returns an undefined value.

Closes down the socket.



198
199
200
201
202
# File 'lib/nova/starbound/protocol/socket.rb', line 198

def close
  @run = false

  socket.close
end

#initializeObject

Initializes the socket.



105
106
107
108
109
110
111
# File 'lib/nova/starbound/protocol/socket.rb', line 105

def initialize
  @threaded = @options.fetch(:threaded, true)
  @run = true
  @queue = Queue.new
  @read  = []
  @current_packet_id = 0
end

#loopvoid

This method returns an undefined value.

Keep looping until we stop running. Reads packets continuously until we do stop.



170
171
172
173
174
# File 'lib/nova/starbound/protocol/socket.rb', line 170

def loop
  while run?
    read
  end
end

#on(data) {|packet| ... } ⇒ Object

Stores callbacks for when packets arrive.

Parameters:

  • data (Hash<(Symbol, Symbol)>)

    should consist of only one key-value pair, with the key being the struct that represents the packet, and the type being the type of packet.

Yield Parameters:

  • packet (Packet)

    the packet.



137
138
139
140
141
142
143
# File 'lib/nova/starbound/protocol/socket.rb', line 137

def on(data, &block)
  struct = data.keys.first
  type   = data.values.first

  callbacks[type].push :struct => struct,
    :type => type, :block => block
end

#read(read_check = true) ⇒ Packet

Waits for a packet and returns it. If it’s threaded, or if there’s data in the queue, it waits for a message in the queue and pops off the top one. If it’s not, it just reads from the socket.

Parameters:

  • read_check (Boolean) (defaults to: true)

    whether or not to check the read list for the packet.

Returns:

Raises:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/nova/starbound/protocol/socket.rb', line 73

def read(read_check = true)
  pack = if @read.length > 0 && read_check
    @read.pop
  elsif threaded?
    queue.pop
  else
    wait_for_socket
  end

  if pack && pack.type == :close
    raise RemoteClosedError
  end

  pack
end

#respond_to(packet, type, body, others = {}) ⇒ Packet

Sends out a response packet with the given type and body.

Parameters:

  • packet (Packet)

    the packet to respond to.

  • type (Symbol)

    the packet tpye of this packet. See Packet::Type for a list of packet types.

  • body (String)

    the body of this packet.

  • others (Hash) (defaults to: {})

    the other data to pass to the packet.

Returns:

  • (Packet)

    the sent packet.



46
47
48
49
# File 'lib/nova/starbound/protocol/socket.rb', line 46

def respond_to(packet, type, body, others = {})
  write_packet Packet.build_response(type, body, packet,
    others)
end

#response_to(packet) ⇒ nil, Packet

Finds the response to the given packet.

Parameters:

Returns:

  • (nil, Packet)

    nil if it was told to stop running before it could find a response.



181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/nova/starbound/protocol/socket.rb', line 181

def response_to(packet)
  response = nil

  while response.nil? && run?
    temp = read(false)

    if temp.struct == :response && temp.response_id == packet.id
      response = temp
    end
  end

  response
end

#run?Boolean

Whether or not this is actually running.

Returns:

  • (Boolean)


100
101
102
# File 'lib/nova/starbound/protocol/socket.rb', line 100

def run?
  @run
end

#run_callback(struct, type, *args) ⇒ Array<Object>

Runs a callback. Automatically called by #wait_for_socket.

Parameters:

  • struct (Symbol)

    the struct that the callback is for.

  • type (Symbol)

    the type of callback this is for.

Returns:

  • (Array<Object>)

    all of the results from running the callbacks.



159
160
161
162
163
164
# File 'lib/nova/starbound/protocol/socket.rb', line 159

def run_callback(struct, type, *args)
  callbacks[type].select { |c|
    c[:struct] == struct }.map do |c|
    c[:block].call(*args)
  end
end

#send(packet_type, body, others = {}) ⇒ Packet

Sends out a regular packet with the given type and body.

Parameters:

  • packet_type (Symbol)

    the packet type of this packet. See Packet::Type for a list of packet types.

  • body (String)

    the body of the packet.

  • others (Hash) (defaults to: {})

    other data to pass to the packet.

Returns:

  • (Packet)

    the sent packet.



32
33
34
35
36
# File 'lib/nova/starbound/protocol/socket.rb', line 32

def send(packet_type, body, others = {})
  others = others.merge(:packet_id => current_packet_id)
  @current_packet_id += 1
  write_packet Packet.build(packet_type, body, others)
end

#threadnil, Thread

The thread that is filling the queue with packet data. If it doesn’t exist, it creates one, if this is threaded.

Returns:

  • (nil, Thread)

    nil if this is not threaded, Thread otherwise.



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/nova/starbound/protocol/socket.rb', line 118

def thread
  return unless threaded?

  @_thread ||= Thread.start do
    while run?
      packet = wait_for_socket

      queue << packet
    end
  end
end

#threaded?Boolean

Returns whether or not this instance of the protocol uses threads to handle reading.

Returns:

  • (Boolean)


93
94
95
# File 'lib/nova/starbound/protocol/socket.rb', line 93

def threaded?
  @threaded
end

#write_packet(packet) ⇒ Packet

Writes the given packet to the socket, after handling the encryption of the packet.

Returns:

  • (Packet)

    the sent packet.



55
56
57
58
59
60
61
62
# File 'lib/nova/starbound/protocol/socket.rb', line 55

def write_packet(packet)
  new_packet = encryption_provider.encrypt(packet)

  socket.write new_packet
  socket.flush

  new_packet
end