Class: LibSL::Simulator

Inherits:
Object
  • Object
show all
Defined in:
lib/network.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client, ip, port, circuit_code, session_id, agent_id) ⇒ Simulator

Manages the connection to a Simulator

Parameters:

  • client (Client)

    The client

  • ip (String)

    The simulator ip

  • port (Integer)

    The simulator port

  • circuit_code (LLU32)

    The circuit code

  • session_id (LLUUID)

    The current session id

  • agent_id (LLUUID)

    The id of the agent that logs into the sim



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/network.rb', line 38

def initialize(client, ip, port, circuit_code, session_id, agent_id)
	@client = client
	@connected = false
	@sim_ip = ip
	@sim_port = port
	@circuit_code = circuit_code
	@session_id = session_id
	@agent_id = agent_id
	@sequence_number = 0
	@connection = EventMachine::open_datagram_socket "0.0.0.0", 0, CircuitHandler, self
	@packets_sent_reliably = {}
	@packets_received_reliably = {}
	
	# Start ack timers
	@ack_timer = EventMachine::add_periodic_timer(1) do
		send_acks
	end
	@resend_timer = EventMachine::add_periodic_timer 2 do
		@packets_sent_reliably.each { |sequence_num, packet|
			if packet.resent_count < 3
				send_packet(packet, false, true)
			else
				@packets_sent_reliably.delete sequence_num
			end
		}
	end
end

Instance Attribute Details

#clientObject

Returns the value of attribute client.



28
29
30
# File 'lib/network.rb', line 28

def client
  @client
end

#connect_packet_ack_handlerObject (readonly)

Returns the value of attribute connect_packet_ack_handler.



29
30
31
# File 'lib/network.rb', line 29

def connect_packet_ack_handler
  @connect_packet_ack_handler
end

#connectedObject

Returns the value of attribute connected.



28
29
30
# File 'lib/network.rb', line 28

def connected
  @connected
end

#packets_received_reliablyObject

Returns the value of attribute packets_received_reliably.



28
29
30
# File 'lib/network.rb', line 28

def packets_received_reliably
  @packets_received_reliably
end

#packets_sent_reliablyObject

Returns the value of attribute packets_sent_reliably.



28
29
30
# File 'lib/network.rb', line 28

def packets_sent_reliably
  @packets_sent_reliably
end

#sim_ipObject (readonly)

Returns the value of attribute sim_ip.



29
30
31
# File 'lib/network.rb', line 29

def sim_ip
  @sim_ip
end

#sim_portObject (readonly)

Returns the value of attribute sim_port.



29
30
31
# File 'lib/network.rb', line 29

def sim_port
  @sim_port
end

Instance Method Details

#==(other) ⇒ Object



66
67
68
69
# File 'lib/network.rb', line 66

def ==(other)
	return false unless other.is_a? Simulator
	other.sim_ip == sim_ip and other.sim_port == sim_port
end

#append_acks(packet) ⇒ Object



157
158
159
160
161
# File 'lib/network.rb', line 157

def append_acks(packet)
	return if @packets_received_reliably.length == 0
	packet.acks = @packets_received_reliably.keys
	packet.acks_flag = true
end

#connect(move_to = true) ⇒ Object

Open the connection to the simulator



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/network.rb', line 76

def connect(move_to=true)

	# First PacketAck means connection is established
	@connect_packet_ack_handler = EventHandler.new(Proc.new do |type, packet, sim|
		EventManager::remove_handler(sim.connect_packet_ack_handler)
		# Add ping handler
		EventManager::register_handler(EventHandler.new(Proc.new do |type, packet, sim|
			packet = CompletePingCheckPacket.new({
				:PingID => {
					:PingID => packet.PingID.PingID
				}
			})
			send_packet packet
		end, :StartPingCheckPacket_Received))
		connected = true
		sim.client.agent_manager.move_to_sim(sim) if move_to
	end, :PacketAckPacket_Received)
	EventManager::register_handler(@connect_packet_ack_handler)

	packet = UseCircuitCodePacket.new({
		:CircuitCode => {
			:Code => @circuit_code,
			:SessionID => @session_id,
			:ID => @agent_id
		}
	})
	send_packet packet, true
end

#connected?Boolean

Check whether we are connected to the sim

Returns:

  • (Boolean)


106
107
108
# File 'lib/network.rb', line 106

def connected?
	@connected
end

#disconnectObject

Disconnect from the sim



117
118
119
120
121
122
# File 'lib/network.rb', line 117

def disconnect
	send_acks
	send_packet CloseCircuitPacket.new
	self.connected = false
	@connection.close_connection_after_writing
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/network.rb', line 71

def eql?(other)
	self == other
end

#packet_received(packet) ⇒ Object

Called when a packet is received from the simulator

Parameters:

  • packet (Packet)

    The received packet



150
151
152
153
154
155
# File 'lib/network.rb', line 150

def packet_received(packet)
	@packets_received_reliably[packet.sequence_number.number] = packet if packet.reliable_flag
	type = (packet.class.name.split("::")[-1] + "_Received").to_sym
	EventManager::fire_event(:PacketReceived, packet, self)
	EventManager::fire_event(type, packet, self)
end

#send_acksObject



163
164
165
166
167
168
169
170
171
# File 'lib/network.rb', line 163

def send_acks()
	return if @packets_received_reliably.length == 0
	packet = PacketAckPacket.new
	@packets_received_reliably.keys.each do |seq|
		packet.Packets.add.ID = LLU32.new(seq)
		@packets_received_reliably.delete seq
	end
	send_packet packet
end

#send_packet(packet, reliable = false, resend = false) ⇒ Object

Send a packet to the simulator be resent

Parameters:

  • packet (Packet)

    The packet to send to the sim

  • reliable (Bool) (defaults to: false)

    Whether to send the packet reliably

  • resend (Bool) (defaults to: false)

    Whether the packet has already been sent and should



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/network.rb', line 129

def send_packet(packet, reliable=false, resend=false)
	# If we resend a packet we keep the flags as they were
	packet.resent_flag = resend
	packet.resent_count += 1 if resend
	unless resend
		@sequence_number += 1
		packet.reliable_flag = reliable
		packet.sequence_number = @sequence_number
	end

	# Add packet to the reliably sent packets map
	@packets_sent_reliably[packet.sequence_number] = packet if packet.reliable_flag
	
	append_acks packet
	EventManager::fire_event(:sending_packet, packet, self)
	data = packet.encode()
	@connection.send_datagram data, @sim_ip, @sim_port
end