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

Instance Method Details

#append_acks(packet) ⇒ Object



147
148
149
150
151
# File 'lib/network.rb', line 147

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



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/network.rb', line 67

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)


97
98
99
# File 'lib/network.rb', line 97

def connected?
	@connected
end

#disconnectObject

Disconnect from the sim



108
109
110
111
112
113
# File 'lib/network.rb', line 108

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

#packet_received(packet) ⇒ Object

Called when a packet is received from the simulator

Parameters:

  • packet (Packet)

    The received packet



140
141
142
143
144
145
# File 'lib/network.rb', line 140

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



153
154
155
156
157
158
159
160
161
# File 'lib/network.rb', line 153

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



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/network.rb', line 120

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
	data = packet.encode()
	@connection.send_datagram data, @sim_ip, @sim_port
end