mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-13 06:42:35 +00:00
141 lines
4.6 KiB
Ruby
141 lines
4.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module CyberarmEngine
|
|
module Networking
|
|
module PacketHandler
|
|
def self.type_to_name(type:)
|
|
Protocol.constants.select { |const| const.to_s.start_with?("PACKET_") }
|
|
.find { |const| Protocol.const_get(const) == type }
|
|
end
|
|
|
|
def self.handle(host:, raw:, peer:)
|
|
packet = Packet.decode(raw)
|
|
type = packet.message.unpack1("C")
|
|
|
|
puts "#{host.class} received #{type_to_name(type: type)}"
|
|
pp raw
|
|
|
|
case type
|
|
when Protocol::PACKET_CONTROL
|
|
handle_control_packet(host, packet, peer)
|
|
when Protocol::PACKET_RAW
|
|
handle_raw_packet(packet)
|
|
when Protocol::PACKET_RELIABLE
|
|
handle_reliable_packet(host, packet, peer)
|
|
else
|
|
raise NotImplementedError, "A Packet handler for #{type_to_name(type: type)}[#{type}] is not implemented!"
|
|
end
|
|
end
|
|
|
|
def self.handle_control_packet(host, packet, peer)
|
|
pkt = ControlPacket.decode(packet.message)
|
|
|
|
case pkt.control_type
|
|
when Protocol::CONTROL_CONNECT # TOSERVER only
|
|
if (peer_id = host.available_peer_id)
|
|
peer.id = peer_id
|
|
host.peers << peer
|
|
peer.write_queue << create_control_packet(peer: peer, control_type: Protocol::CONTROL_SET_PEER_ID, message: [peer_id].pack("n"))
|
|
host.peer_connected(peer: peer)
|
|
else
|
|
host.write(
|
|
peer: peer,
|
|
packet: PacketHandler.create_control_packet(
|
|
peer: peer,
|
|
control_type: Protocol::CONTROL_DISCONNECT,
|
|
message: "ERROR: max number of clients already connected"
|
|
)
|
|
)
|
|
end
|
|
|
|
when Protocol::CONTROL_SET_PEER_ID # TOCLIENT only
|
|
peer.id = pkt.message.unpack1("n")
|
|
host.connected
|
|
|
|
when Protocol::CONTROL_DISCONNECT
|
|
if host.is_a?(Server)
|
|
host.peer_disconnected(peer: peer)
|
|
else
|
|
host.disconnected(reason: pkt.message)
|
|
end
|
|
|
|
when Protocol::CONTROL_HEARTBEAT
|
|
when Protocol::CONTROL_PING
|
|
peer.write_queue << PacketHandler.create_control_packet(
|
|
peer: peer, control_type: Protocol::CONTROL_PONG,
|
|
reliable: true,
|
|
message: [Networking.milliseconds].pack("Q") # Uint64, native endian
|
|
)
|
|
when Protocol::CONTROL_PONG
|
|
sent_time = pkt.message.unpack1("Q")
|
|
difference = Networking.milliseconds - sent_time
|
|
|
|
peer.ping = difference
|
|
end
|
|
|
|
nil
|
|
end
|
|
|
|
def self.handle_raw_packet(packet)
|
|
RawPacket.decode(packet.message)
|
|
end
|
|
|
|
def self.handle_reliable_packet(host, packet, peer)
|
|
# TODO: Preserve delivery order of reliable packets
|
|
|
|
pkt = ReliablePacket.decode(packet.message)
|
|
peer.write_queue << create_control_packet(
|
|
peer: peer,
|
|
control_type: Protocol::CONTROL_ACKNOWLEDGE,
|
|
message: [pkt.sequence_number].pack("n")
|
|
)
|
|
|
|
handle(host: host, raw: pkt.message, peer: peer)
|
|
end
|
|
|
|
def self.create_control_packet(peer:, control_type:, message: nil, reliable: false, channel: 0)
|
|
message_packet = nil
|
|
|
|
if reliable
|
|
warn "Reliable packets are not yet implemented!"
|
|
packet = Packet.new(
|
|
protocol_version: Protocol::PROTOCOL_VERSION,
|
|
peer_id: peer.id,
|
|
channel: channel,
|
|
message: ControlPacket.new(control_type: control_type, message: message).encode
|
|
)
|
|
message_packet = ReliablePacket.new(sequence_number: peer.next_reliable_sequence_number, message: packet.encode)
|
|
else
|
|
message_packet = ControlPacket.new(control_type: control_type, message: message)
|
|
end
|
|
|
|
Packet.new(
|
|
protocol_version: Protocol::PROTOCOL_VERSION,
|
|
peer_id: peer.id,
|
|
channel: channel,
|
|
message: message_packet.encode
|
|
)
|
|
end
|
|
|
|
def self.create_raw_packet(peer:, message:, reliable: false, channel: 0)
|
|
message_packet = nil
|
|
|
|
if reliable
|
|
warn "Reliable packets are not yet implemented!"
|
|
packet = RawPacket.new(message: message)
|
|
message_packet = ReliablePacket.new(sequence_number: peer.next_reliable_sequence_number, message: packet.encode)
|
|
else
|
|
message_packet = RawPacket.new(message: message)
|
|
end
|
|
|
|
Packet.new(
|
|
protocol_version: Protocol::PROTOCOL_VERSION,
|
|
peer_id: peer.id,
|
|
channel: channel,
|
|
message: message_packet.encode
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|