Class: RuneRb::Network::Message

Inherits:
Object
  • Object
show all
Extended by:
Constants, System::Log
Includes:
Constants, System::Log
Defined in:
app/network/message.rb

Overview

A Message object represents a composable/decomposable network message that is either sent or received via a TCPSocket.

Since:

  • 0.9.3

Constant Summary

Constants included from Constants

Constants::BIT_MASK_OUT, Constants::BYTE_MUTATIONS, Constants::BYTE_ORDERS, Constants::BYTE_SIZE, Constants::CONNECTION_TYPES, Constants::LOGIN_RESPONSES, Constants::MESSAGE_SIZES, Constants::PROTOCOL_TEMPLATES, Constants::RW_TYPES, Constants::SIDEBAR_INTERFACES

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from System::Log

class_name, err, err!, log, log!, symbolize_file

Constructor Details

#initialize(mode, header = { op_code: -1, length: 0 }, type = :VARIABLE_BYTE, body = '') ⇒ Message

Called when a new Message is created

Parameters:

  • mode (String)

    access mode for the message (r w)

  • header (Hash, Struct, Array) (defaults to: { op_code: -1, length: 0 })

    an optional header for the message

  • body (String, StringIO) (defaults to: '')

    an optional body payload for the message.

Since:

  • 0.9.3


46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'app/network/message.rb', line 46

def initialize(mode, header = { op_code: -1, length: 0 }, type = :VARIABLE_BYTE, body = '')
  raise "Invalid mode for Message! Expecting: r || w || rw , Got: #{mode}" unless 'rw'.include?(mode)

  # Set the mode for the Message object.
  @mode = { raw: mode }

  # Optional header assignment
  @header = header

  # Payload assignment
  @payload = body

  @type = type

  # Enable write functions
  enable_writeable if mode.include?('w')

  # Enable read functions
  enable_readable if mode.include?('r')

  # Return an the instance for chains.
  self
end

Instance Attribute Details

#headerHash (readonly)

Returns the header for the message.

Returns:

  • (Hash)

    the header for the message.

Since:

  • 0.9.3


39
40
41
# File 'app/network/message.rb', line 39

def header
  @header
end

#modeHash (readonly)

Returns the access mode for the message.

Returns:

  • (Hash)

    the access mode for the message.

Since:

  • 0.9.3


36
37
38
# File 'app/network/message.rb', line 36

def mode
  @mode
end

Class Method Details

.compile_header(header, type) ⇒ String

Generates a binary string representation of the <@header> object.

Parameters:

  • header (Hash)

    the header to compile.

  • type (Symbol)

    the type of header to compile [:FIXED, :VARIABLE_SHORT, :VARIABLE_BYTE]

Returns:

  • (String)

    binary representation of the header.

Since:

  • 0.9.3


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'app/network/message.rb', line 100

def compile_header(header, type)
  case type
  when :FIXED then [header[:op_code]].pack('C') # Fixed packet lengths are known by both the client and server, so no length packing is necesssary
  when :VARIABLE_SHORT then [header[:op_code], header[:length]].pack('Cn') # Variable Short packet lengths fall into the range of a short type and can be packed as such
  when :VARIABLE_BYTE # Variable Byte packet lengths fall into the range of a byte type and can be packed as such
    if header[:length].nonzero? && header[:length].positive?
      [header[:op_code], header[:length]].pack('Cc')
    else
      compile_header(header, :FIXED)
    end
  when :RAW then return
  else
    compile_header(header, :FIXED)
  end
end

.validate(message, operation, options = {}) ⇒ Object

TODO:

implement a ValidationError type to be raised when a validation fails.

Validates the passed parameters according to the options.

Parameters:

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

    a map of rules to validate.

Since:

  • 0.9.3


81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/network/message.rb', line 81

def validate(message, operation, options = {})
  return false unless valid_mode?(message, operation)

  # Validate the current access mode if we're in a writeable state
  return false unless valid_access?(message, %i[bit bits].include?(options[:type]) ? :BIT : :BYTE) if message.mode[:writeable]

  # Validate the mutation there are any
  return false unless valid_mutation?(options[:mutation]) if options[:mutation]

  # Validate the byte order if it is passed.
  return false unless valid_order?(options[:order]) if options[:order]

  true
end

Instance Method Details

#inspectObject

Since:

  • 0.9.3


70
71
72
# File 'app/network/message.rb', line 70

def inspect
  log! "[Header]: [OpCode]: #{@header[:op_code]} || [Length]: #{@header[:length]} || [Mode]: #{@mode} || [Access]: #{@access} || [Payload]: #{snapshot}"
end

#peekString Also known as: snapshot

Fetches a snapshot of the message payload content.

Returns:

  • (String)

    a snapshot of the payload

Since:

  • 0.9.3


160
161
162
# File 'app/network/message.rb', line 160

def peek
  @payload.dup
end