mirror of
https://github.com/cyberarm/i-mic-fps.git
synced 2025-12-15 15:42:35 +00:00
Cleanup, moved Map lifecycle into Director, added renderer_info command
This commit is contained in:
@@ -7,10 +7,11 @@ class IMICFPS
|
|||||||
|
|
||||||
def handle(subscriber, context, *args)
|
def handle(subscriber, context, *args)
|
||||||
return unless subscriber.entity == args.first.first
|
return unless subscriber.entity == args.first.first
|
||||||
|
|
||||||
event = EventHandler::Event.new(entity: subscriber.entity, context: context)
|
event = EventHandler::Event.new(entity: subscriber.entity, context: context)
|
||||||
|
|
||||||
subscriber.trigger(event)
|
subscriber.trigger(event)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def jump
|
def jump
|
||||||
if InputMapper.down?(:jump) && window.current_state.map.collision_manager.on_ground?(self)
|
return unless InputMapper.down?(:jump) && window.director.map.collision_manager.on_ground?(self)
|
||||||
@velocity.y = 1.5
|
|
||||||
end
|
@velocity.y = 1.5
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,25 +7,24 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def insert_entity(package, name, position, orientation, data = {})
|
def insert_entity(package, name, position, orientation, data = {})
|
||||||
ent = MapParser::Entity.new(package, name, position, orientation, Vector.new(1,1,1))
|
ent = MapParser::Entity.new(package, name, position, orientation, Vector.new(1, 1, 1))
|
||||||
add_entity(IMICFPS::Entity.new(map_entity: ent, manifest: Manifest.new(package: package, name: name)))
|
add_entity(IMICFPS::Entity.new(map_entity: ent, manifest: Manifest.new(package: package, name: name)))
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_entity(entity)
|
def find_entity(entity)
|
||||||
@entities.detect {|entity| entity == entity}
|
@entities.detect { |e| e == entity }
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_entity_by(name:)
|
def find_entity_by(name:)
|
||||||
@entities.detect { |entity| entity.name == name}
|
@entities.detect { |entity| entity.name == name }
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_entity(entity)
|
def remove_entity(entity)
|
||||||
ent = @entities.detect {|entity| entity == entity}
|
return unless (ent = @entities.detect { |e| e == entity })
|
||||||
if ent
|
|
||||||
@collision_manager.remove(entity) if @collision_manager && entity.manifest.collision
|
@collision_manager.remove(entity) if @collision_manager && entity.manifest.collision
|
||||||
@publisher.publish(:destroy, nil, entity)
|
@publisher.publish(:destroy, nil, entity)
|
||||||
@entities.delete(ent)
|
@entities.delete(ent)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def entities
|
def entities
|
||||||
|
|||||||
98
lib/map.rb
98
lib/map.rb
@@ -4,8 +4,8 @@ class IMICFPS
|
|||||||
include LightManager
|
include LightManager
|
||||||
include CommonMethods
|
include CommonMethods
|
||||||
|
|
||||||
attr_reader :collision_manager
|
attr_reader :collision_manager, :gravity
|
||||||
attr_reader :gravity
|
|
||||||
def initialize(map_parser:, gravity: IMICFPS::EARTH_GRAVITY)
|
def initialize(map_parser:, gravity: IMICFPS::EARTH_GRAVITY)
|
||||||
@map_parser = map_parser
|
@map_parser = map_parser
|
||||||
@gravity = gravity
|
@gravity = gravity
|
||||||
@@ -18,24 +18,92 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
add_entity(Terrain.new(map_entity: @map_parser.terrain, manifest: Manifest.new(package: @map_parser.terrain.package, name: @map_parser.terrain.name)))
|
add_terrain
|
||||||
|
add_skybox
|
||||||
|
add_lights
|
||||||
|
add_entities
|
||||||
|
|
||||||
add_entity(Skydome.new(map_entity: @map_parser.skydome, manifest: Manifest.new(package: @map_parser.skydome.package, name: @map_parser.skydome.name), backface_culling: false))
|
# TODO: Add player entity from director
|
||||||
|
add_entity(
|
||||||
|
Player.new(
|
||||||
|
spawnpoint: @map_parser.spawnpoints.sample,
|
||||||
|
manifest: Manifest.new(
|
||||||
|
package: "base",
|
||||||
|
name: "character"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_terrain
|
||||||
|
add_entity(
|
||||||
|
Terrain.new(
|
||||||
|
map_entity: @map_parser.terrain,
|
||||||
|
manifest: Manifest.new(
|
||||||
|
package: @map_parser.terrain.package,
|
||||||
|
name: @map_parser.terrain.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_skybox
|
||||||
|
add_entity(
|
||||||
|
Skydome.new(
|
||||||
|
map_entity: @map_parser.skydome,
|
||||||
|
backface_culling: false,
|
||||||
|
manifest: Manifest.new(
|
||||||
|
package: @map_parser.skydome.package,
|
||||||
|
name: @map_parser.skydome.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_lights
|
||||||
@map_parser.lights.each do |l|
|
@map_parser.lights.each do |l|
|
||||||
add_light(Light.new(id: available_light, type: l.type, position: l.position, diffuse: l.diffuse, ambient: l.ambient, specular: l.specular, intensity: l.intensity))
|
add_light(
|
||||||
|
Light.new(
|
||||||
|
id: available_light,
|
||||||
|
type: l.type,
|
||||||
|
position: l.position,
|
||||||
|
diffuse: l.diffuse,
|
||||||
|
ambient: l.ambient,
|
||||||
|
specular: l.specular,
|
||||||
|
intensity: l.intensity
|
||||||
|
)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@map_parser.entities.each do |ent|
|
|
||||||
add_entity(Entity.new(map_entity: ent, manifest: Manifest.new(package: ent.package, name: ent.name)))
|
|
||||||
end
|
|
||||||
|
|
||||||
add_entity(Player.new(spawnpoint: @map_parser.spawnpoints.sample, manifest: Manifest.new(package: "base", name: "character")))
|
|
||||||
|
|
||||||
# Default lights if non are defined
|
# Default lights if non are defined
|
||||||
if @map_parser.lights.size == 0
|
return unless @map_parser.lights.size.zero?
|
||||||
add_light(Light.new(id: available_light, position: Vector.new(30, 10.0, 30)))
|
|
||||||
add_light(Light.new(id: available_light, position: Vector.new(0, 100, 0), diffuse: Color.new(1.0, 0.5, 0.1)))
|
add_light(
|
||||||
|
Light.new(
|
||||||
|
id: available_light,
|
||||||
|
position: Vector.new(30, 10.0, 30)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
add_light(
|
||||||
|
Light.new(
|
||||||
|
id: available_light,
|
||||||
|
position: Vector.new(0, 100, 0), diffuse: Color.new(1.0, 0.5, 0.1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_entities
|
||||||
|
@map_parser.entities.each do |ent|
|
||||||
|
add_entity(
|
||||||
|
Entity.new(
|
||||||
|
map_entity: ent,
|
||||||
|
manifest: Manifest.new(
|
||||||
|
package: ent.package,
|
||||||
|
name: ent.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -48,7 +116,7 @@ class IMICFPS
|
|||||||
|
|
||||||
Gosu.gl do
|
Gosu.gl do
|
||||||
gl_error?
|
gl_error?
|
||||||
glClearColor(0,0.2,0.5,1) # skyish blue
|
glClearColor(0, 0.2, 0.5, 1) # skyish blue
|
||||||
gl_error?
|
gl_error?
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen and the depth buffer
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear the screen and the depth buffer
|
||||||
gl_error?
|
gl_error?
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ module CyberarmEngine
|
|||||||
module Networking
|
module Networking
|
||||||
class Connection
|
class Connection
|
||||||
attr_reader :hostname, :port, :peer
|
attr_reader :hostname, :port, :peer
|
||||||
|
|
||||||
def initialize(hostname:, port:, channels: 3)
|
def initialize(hostname:, port:, channels: 3)
|
||||||
@hostname = hostname
|
@hostname = hostname
|
||||||
@port = port
|
@port = port
|
||||||
@@ -26,7 +27,7 @@ module CyberarmEngine
|
|||||||
|
|
||||||
# Functions #
|
# Functions #
|
||||||
def send_packet(message:, reliable: false, channel: 0)
|
def send_packet(message:, reliable: false, channel: 0)
|
||||||
@peer.write_queue << PacketHandler.create_raw_packet(peer: @peer, message: message, reliable: reliable, channel: channel)
|
@peer.write_queue << PacketHandler.create_raw_packet(peer: @peer, message: message, reliable: reliable, channel: channel)
|
||||||
end
|
end
|
||||||
|
|
||||||
def connect(timeout: Protocol::TIMEOUT_PERIOD)
|
def connect(timeout: Protocol::TIMEOUT_PERIOD)
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ module CyberarmEngine
|
|||||||
when Protocol::CONTROL_CONNECT # TOSERVER only
|
when Protocol::CONTROL_CONNECT # TOSERVER only
|
||||||
if (peer_id = host.available_peer_id)
|
if (peer_id = host.available_peer_id)
|
||||||
peer.id = peer_id
|
peer.id = peer_id
|
||||||
host.clients << peer
|
host.peers << peer
|
||||||
peer.write_queue << create_control_packet(peer: peer, control_type: Protocol::CONTROL_SET_PEER_ID, message: [peer_id].pack("n"))
|
peer.write_queue << create_control_packet(peer: peer, control_type: Protocol::CONTROL_SET_PEER_ID, message: [peer_id].pack("n"))
|
||||||
host.client_connected(peer: peer)
|
host.peer_connected(peer: peer)
|
||||||
else
|
else
|
||||||
host.write(
|
host.write(
|
||||||
peer: peer,
|
peer: peer,
|
||||||
@@ -52,7 +52,7 @@ module CyberarmEngine
|
|||||||
|
|
||||||
when Protocol::CONTROL_DISCONNECT
|
when Protocol::CONTROL_DISCONNECT
|
||||||
if host.is_a?(Server)
|
if host.is_a?(Server)
|
||||||
host.client_disconnected(peer: peer)
|
host.peer_disconnected(peer: peer)
|
||||||
else
|
else
|
||||||
host.disconnected(reason: pkt.message)
|
host.disconnected(reason: pkt.message)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
module CyberarmEngine
|
module CyberarmEngine
|
||||||
module Networking
|
module Networking
|
||||||
class Server
|
class Server
|
||||||
attr_reader :hostname, :port, :max_clients
|
attr_reader :hostname, :port, :max_peers, :peers
|
||||||
attr_accessor :total_packets_sent, :total_packets_received,
|
attr_accessor :total_packets_sent, :total_packets_received,
|
||||||
:total_data_sent, :total_data_received,
|
:total_data_sent, :total_data_received,
|
||||||
:last_read_time, :last_write_time
|
:last_read_time, :last_write_time
|
||||||
@@ -9,12 +9,12 @@ module CyberarmEngine
|
|||||||
def initialize(
|
def initialize(
|
||||||
hostname: CyberarmEngine::Networking::DEFAULT_SERVER_HOSTNAME,
|
hostname: CyberarmEngine::Networking::DEFAULT_SERVER_HOSTNAME,
|
||||||
port: CyberarmEngine::Networking::DEFAULT_SERVER_PORT,
|
port: CyberarmEngine::Networking::DEFAULT_SERVER_PORT,
|
||||||
max_clients: CyberarmEngine::Networking::DEFAULT_PEER_LIMIT,
|
max_peers: CyberarmEngine::Networking::DEFAULT_PEER_LIMIT,
|
||||||
channels: 3
|
channels: 3
|
||||||
)
|
)
|
||||||
@hostname = hostname
|
@hostname = hostname
|
||||||
@port = port
|
@port = port
|
||||||
@max_clients = max_clients + 2
|
@max_peers = max_peers + 2
|
||||||
|
|
||||||
@channels = Array(0..channels).map { |id| Channel.new(id: id, mode: :default) }
|
@channels = Array(0..channels).map { |id| Channel.new(id: id, mode: :default) }
|
||||||
@peers = []
|
@peers = []
|
||||||
@@ -28,35 +28,26 @@ module CyberarmEngine
|
|||||||
@total_data_received = 0
|
@total_data_received = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helpers #
|
|
||||||
def connected_clients
|
|
||||||
@peers.size
|
|
||||||
end
|
|
||||||
|
|
||||||
def clients
|
|
||||||
@peers
|
|
||||||
end
|
|
||||||
|
|
||||||
# Callbacks #
|
# Callbacks #
|
||||||
|
|
||||||
# Called when client connects
|
# Called when peer connects
|
||||||
def client_connected(peer:)
|
def peer_connected(peer:)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Called when client times out or explicitly disconnects
|
# Called when peer times out or explicitly disconnects
|
||||||
def client_disconnected(peer:, reason:)
|
def peer_disconnected(peer:, reason:)
|
||||||
end
|
end
|
||||||
|
|
||||||
### REMOVE? ###
|
### REMOVE? ###
|
||||||
# Called when client was not sending heartbeats or regular packets for a
|
# Called when peer was not sending heartbeats or regular packets for a
|
||||||
# period of time, but was not logically disconnected and removed, and started
|
# period of time, but was not logically disconnected and removed, and started
|
||||||
# send packets again.
|
# send packets again.
|
||||||
#
|
#
|
||||||
# TLDR: Client was temporarily unreachable but did not timeout.
|
# TLDR: peer was temporarily unreachable but did not timeout.
|
||||||
def client_reconnected(peer:)
|
def peer_reconnected(peer:)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Called when a (logical) packet is received from client
|
# Called when a (logical) packet is received from peer
|
||||||
def packet_received(peer:, message:, channel:)
|
def packet_received(peer:, message:, channel:)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -84,7 +75,7 @@ module CyberarmEngine
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Disconnect peer
|
# Disconnect peer
|
||||||
def disconnect_client(peer:, reason: "")
|
def disconnect_peer(peer:, reason: "")
|
||||||
if (peer = @peers[peer])
|
if (peer = @peers[peer])
|
||||||
packet = PacketHandler.create_disconnect_packet(peer.id, reason)
|
packet = PacketHandler.create_disconnect_packet(peer.id, reason)
|
||||||
peer.write_now!(packet)
|
peer.write_now!(packet)
|
||||||
@@ -110,7 +101,7 @@ module CyberarmEngine
|
|||||||
message: message
|
message: message
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
client_disconnected(peer: peer, reason: message)
|
peer_disconnected(peer: peer, reason: message)
|
||||||
@peers.delete(peer)
|
@peers.delete(peer)
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
@@ -135,7 +126,7 @@ module CyberarmEngine
|
|||||||
|
|
||||||
def available_peer_id
|
def available_peer_id
|
||||||
peer_ids = @peers.map(&:id)
|
peer_ids = @peers.map(&:id)
|
||||||
ids = (2..@max_clients).to_a - peer_ids
|
ids = (2..@max_peers).to_a - peer_ids
|
||||||
|
|
||||||
ids.size.positive? ? ids.first : nil
|
ids.size.positive? ? ids.first : nil
|
||||||
end
|
end
|
||||||
@@ -157,7 +148,7 @@ module CyberarmEngine
|
|||||||
packet: PacketHandler.create_control_packet(
|
packet: PacketHandler.create_control_packet(
|
||||||
peer: peer,
|
peer: peer,
|
||||||
control_type: Protocol::CONTROL_DISCONNECT,
|
control_type: Protocol::CONTROL_DISCONNECT,
|
||||||
message: "ERROR: client not connected"
|
message: "ERROR: peer not connected"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,29 +1,36 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
module Networking
|
module Networking
|
||||||
class Director
|
class Director
|
||||||
attr_reader :address, :port, :tick_rate, :storage, :map
|
attr_reader :tick_rate, :storage, :map, :server, :connection
|
||||||
def initialize(address: DEFAULT_SERVER_HOST, port: DEFAULT_SERVER_PORT, tick_rate: 2)
|
|
||||||
@address = address
|
def initialize(tick_rate: 15)
|
||||||
@port = port
|
|
||||||
@tick_rate = (1000.0 / tick_rate) / 1000.0
|
@tick_rate = (1000.0 / tick_rate) / 1000.0
|
||||||
|
|
||||||
@server = Server.new(address: @address, port: @port, max_peers: DEFAULT_PEER_LIMIT)
|
@last_tick_time = CyberarmEngine::Networking.milliseconds
|
||||||
@server.bind
|
|
||||||
|
|
||||||
@last_tick_time = Networking.milliseconds
|
|
||||||
@directing = true
|
@directing = true
|
||||||
@storage = {}
|
@storage = {}
|
||||||
@map = nil
|
@map = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def host_server(hostname: CyberarmEngine::Networking::DEFAULT_SERVER_HOSTNAME, port: CyberarmEngine::Networking::DEFAULT_SERVER_PORT, max_peers: CyberarmEngine::Networking::DEFAULT_PEER_LIMIT)
|
||||||
|
@server = Server.new(hostname: hostname, port: port, max_peers: max_peers)
|
||||||
|
@server.bind
|
||||||
|
end
|
||||||
|
|
||||||
|
def connect(hostname:, port: CyberarmEngine::Networking::DEFAULT_SERVER_PORT)
|
||||||
|
@connection = Connection.new(hostname: hostname, port: port)
|
||||||
|
@connection.connect
|
||||||
|
end
|
||||||
|
|
||||||
def load_map(map_parser:)
|
def load_map(map_parser:)
|
||||||
# TODO: send map_change to clients
|
# TODO: send map_change to clients
|
||||||
@map = Map.new(map_parser: map_parser)
|
@map = Map.new(map_parser: map_parser)
|
||||||
|
@map.setup
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
Thread.start do |thread|
|
Thread.start do
|
||||||
while(@directing)
|
while @directing
|
||||||
dt = milliseconds - @last_tick_time
|
dt = milliseconds - @last_tick_time
|
||||||
|
|
||||||
tick(dt)
|
tick(dt)
|
||||||
@@ -35,18 +42,20 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def tick(delta_time)
|
def tick(delta_time)
|
||||||
if @map
|
return unless @map
|
||||||
Publisher.instance.publish(:tick, delta_time * 1000.0)
|
|
||||||
|
|
||||||
@map.update
|
Publisher.instance.publish(:tick, delta_time * 1000.0)
|
||||||
@server.update
|
|
||||||
end
|
@map.update
|
||||||
|
@server&.update
|
||||||
|
@connection&.update
|
||||||
end
|
end
|
||||||
|
|
||||||
def shutdown
|
def shutdown
|
||||||
@directing = false
|
@directing = false
|
||||||
@server.close
|
@server&.close
|
||||||
|
@connection&.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
class IMICFPS
|
|
||||||
module Networking
|
|
||||||
class Peer
|
|
||||||
attr_reader :id, :address, :port, :packet_read_queue, :packet_write_queue
|
|
||||||
attr_accessor :total_packets_sent, :total_packets_received, :total_data_sent, :total_data_received, :last_read_time, :last_write_time
|
|
||||||
def initialize(id:, address:, port:)
|
|
||||||
@id = id
|
|
||||||
@address, @port = address, port
|
|
||||||
|
|
||||||
@packet_write_queue = []
|
|
||||||
@packet_read_queue = []
|
|
||||||
|
|
||||||
@last_read_time = Networking.milliseconds
|
|
||||||
@last_write_time = Networking.milliseconds
|
|
||||||
|
|
||||||
@total_packets_sent = 0
|
|
||||||
@total_packets_received = 0
|
|
||||||
@total_data_sent = 0
|
|
||||||
@total_data_received = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,135 +1,14 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
module Networking
|
module Networking
|
||||||
class Server
|
class Server < CyberarmEngine::Networking::Server
|
||||||
attr_reader :address, :port, :max_peers, :peers
|
def connected(peer:)
|
||||||
attr_accessor :total_packets_sent, :total_packets_received, :total_data_sent, :total_data_received, :last_read_time, :last_write_time
|
|
||||||
def initialize(address:, port:, max_peers:)
|
|
||||||
@address = address
|
|
||||||
@port = port
|
|
||||||
@max_peers = max_peers
|
|
||||||
|
|
||||||
@peers = Array.new(@max_peers + 1, nil)
|
|
||||||
|
|
||||||
@read_buffer = ReadBuffer.new
|
|
||||||
|
|
||||||
@last_read_time = Networking.milliseconds
|
|
||||||
@last_write_time = Networking.milliseconds
|
|
||||||
|
|
||||||
@total_packets_sent = 0
|
|
||||||
@total_packets_received = 0
|
|
||||||
@total_data_sent = 0
|
|
||||||
@total_data_received = 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Peer ID 0 is reserved for unconnected peers to pass packet validation
|
def disconnected(peer:, reason:)
|
||||||
def create_peer(address:, port:)
|
|
||||||
@peers.each_with_index do |peer, i|
|
|
||||||
unless peer
|
|
||||||
new_peer = Peer.new(id: i + 1, address: address, port: port)
|
|
||||||
@peers[i + 1] = new_peer
|
|
||||||
|
|
||||||
return new_peer
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_peer(peer_id)
|
def packet_received(peer:, message:, channel:)
|
||||||
@peers[peer_id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove_peer(peer_id)
|
|
||||||
@peers[peer_id] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def bind
|
|
||||||
@socket = UDPSocket.new
|
|
||||||
@socket.bind(@address, @port)
|
|
||||||
end
|
|
||||||
|
|
||||||
def send_packet( peer_id, packet )
|
|
||||||
if peer = get_peer(peer_id)
|
|
||||||
packets = Packet.splinter(packet)
|
|
||||||
|
|
||||||
packets.each { |pkt| peer.packet_write_queue.push(pkt) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def broadcast_packet(packet)
|
|
||||||
@peers.each do |peer|
|
|
||||||
next unless peer
|
|
||||||
|
|
||||||
send_packet(peer.id, packet)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
while(read)
|
|
||||||
end
|
|
||||||
|
|
||||||
@peers.each do |peer|
|
|
||||||
next unless peer
|
|
||||||
|
|
||||||
peer.packet_write_queue.each do |packet|
|
|
||||||
write(peer, packet)
|
|
||||||
peer.packet_write_queue.delete(packet)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# "deliver" packets to peers, record stats to peers
|
|
||||||
@read_buffer.reconstruct_packets.each do |packet, addr_info|
|
|
||||||
peer = nil
|
|
||||||
|
|
||||||
# initial connection
|
|
||||||
if packet.peer_id == 0 && packet.type == Protocol::CONNECT
|
|
||||||
peer = create_peer(address: addr_info[2], port: addr_info[1])
|
|
||||||
send_packet(
|
|
||||||
peer.id,
|
|
||||||
Packet.new(
|
|
||||||
peer_id: 0,
|
|
||||||
sequence: 0,
|
|
||||||
type: Protocol::VERIFY_CONNECT,
|
|
||||||
payload: [peer.id].pack("C")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else
|
|
||||||
peer = get_peer(packet.peer_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# broadcast_packet(Packet.new(peer_id: 0, sequence: 0, type: Protocol::HEARTBEAT, payload: [Networking.milliseconds].pack("G")))
|
|
||||||
end
|
|
||||||
|
|
||||||
def close
|
|
||||||
@socket.close if @socket
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def read
|
|
||||||
data, addr = @socket.recvfrom_nonblock(Protocol::MAX_PACKET_SIZE)
|
|
||||||
@read_buffer.add(data, addr )
|
|
||||||
|
|
||||||
@total_packets_received += 1
|
|
||||||
@total_data_received += data.length
|
|
||||||
@last_read_time = Networking.milliseconds
|
|
||||||
return true
|
|
||||||
rescue IO::WaitReadable
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
def write(peer, packet)
|
|
||||||
raw = packet.encode
|
|
||||||
@socket.send( raw, 0, peer.address, peer.port )
|
|
||||||
|
|
||||||
@total_packets_sent += 1
|
|
||||||
@total_data_sent += raw.length
|
|
||||||
@last_write_time = Networking.milliseconds
|
|
||||||
|
|
||||||
peer.total_packets_sent += 1
|
|
||||||
peer.total_data_sent += raw.length
|
|
||||||
peer.last_write_time = Networking.milliseconds
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def map
|
def map
|
||||||
$window.current_state.map
|
$window.director.map
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1,16 +1,13 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Game < GameState
|
class Game < GameState
|
||||||
|
|
||||||
attr_reader :map
|
attr_reader :map
|
||||||
def setup
|
|
||||||
@map = Map.new(map_parser: @options[:map_parser])
|
|
||||||
@map.setup
|
|
||||||
|
|
||||||
@player = @map.find_entity_by(name: "character")
|
def setup
|
||||||
|
window.director.load_map(map_parser: @options[:map_parser])
|
||||||
|
|
||||||
|
@player = window.director.map.find_entity_by(name: "character")
|
||||||
@camera = PerspectiveCamera.new( position: @player.position.clone, aspect_ratio: window.aspect_ratio )
|
@camera = PerspectiveCamera.new( position: @player.position.clone, aspect_ratio: window.aspect_ratio )
|
||||||
@camera_controller = CameraController.new(mode: :fpv, camera: @camera, entity: @player)
|
@camera_controller = CameraController.new(mode: :fpv, camera: @camera, entity: @player)
|
||||||
# @director = Networking::Director.new
|
|
||||||
# @director.load_map(map_parser: @options[:map_parser])
|
|
||||||
|
|
||||||
# @connection = Networking::Connection.new(address: "localhost", port: Networking::DEFAULT_SERVER_PORT)
|
# @connection = Networking::Connection.new(address: "localhost", port: Networking::DEFAULT_SERVER_PORT)
|
||||||
# @connection.connect
|
# @connection.connect
|
||||||
@@ -26,32 +23,20 @@ class IMICFPS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def draw
|
def draw
|
||||||
@map.render(@camera)
|
window.director.map.render(@camera)
|
||||||
|
|
||||||
@hud.draw
|
@hud.draw
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
update_text
|
|
||||||
|
|
||||||
control_player
|
control_player
|
||||||
@hud.update
|
@hud.update
|
||||||
@camera_controller.update
|
@camera_controller.update
|
||||||
|
|
||||||
# @connection.update
|
# @connection.update
|
||||||
# @director.tick(window.dt)
|
window.director.tick(window.dt)
|
||||||
@map.update
|
|
||||||
|
|
||||||
@demo.update if @demo
|
@demo&.update
|
||||||
end
|
|
||||||
|
|
||||||
def update_text
|
|
||||||
string = <<-eos
|
|
||||||
OpenGL Vendor: #{glGetString(GL_VENDOR)}
|
|
||||||
OpenGL Renderer: #{glGetString(GL_RENDERER)}
|
|
||||||
OpenGL Version: #{glGetString(GL_VERSION)}
|
|
||||||
OpenGL Shader Language Version: #{glGetString(GL_SHADING_LANGUAGE_VERSION)}
|
|
||||||
eos
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def control_player
|
def control_player
|
||||||
@@ -73,25 +58,25 @@ eos
|
|||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@demo.button_down(id) if @demo
|
@demo&.button_down(id)
|
||||||
@camera_controller.button_down(id)
|
@camera_controller.button_down(id)
|
||||||
|
|
||||||
InputMapper.keydown(id)
|
InputMapper.keydown(id)
|
||||||
Publisher.instance.publish(:button_down, nil, id)
|
Publisher.instance.publish(:button_down, nil, id)
|
||||||
|
|
||||||
@map.entities.each do |entity|
|
window.director.map.entities.each do |entity|
|
||||||
entity.button_down(id) if defined?(entity.button_down)
|
entity.button_down(id) if defined?(entity.button_down)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def button_up(id)
|
def button_up(id)
|
||||||
@demo.button_up(id) if @demo
|
@demo&.button_up(id)
|
||||||
@camera_controller.button_up(id)
|
@camera_controller.button_up(id)
|
||||||
|
|
||||||
InputMapper.keyup(id)
|
InputMapper.keyup(id)
|
||||||
Publisher.instance.publish(:button_up, nil, id)
|
Publisher.instance.publish(:button_up, nil, id)
|
||||||
|
|
||||||
@map.entities.each do |entity|
|
window.director.map.entities.each do |entity|
|
||||||
entity.button_up(id) if defined?(entity.button_up)
|
entity.button_up(id) if defined?(entity.button_up)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
24
lib/ui/commands/renderer_info_command.rb
Normal file
24
lib/ui/commands/renderer_info_command.rb
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
class IMICFPS
|
||||||
|
class Commands
|
||||||
|
class RendererInfoCommand < Command
|
||||||
|
def group
|
||||||
|
:global
|
||||||
|
end
|
||||||
|
|
||||||
|
def command
|
||||||
|
:renderer_info
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle(arguments, console)
|
||||||
|
console.stdin("OpenGL Vendor: #{Style.notice(glGetString(GL_VENDOR))}")
|
||||||
|
console.stdin("OpenGL Renderer: #{Style.notice(glGetString(GL_RENDERER))}")
|
||||||
|
console.stdin("OpenGL Version: #{Style.notice(glGetString(GL_VERSION))}")
|
||||||
|
console.stdin("OpenGL Shader Language Version: #{Style.notice(glGetString(GL_SHADING_LANGUAGE_VERSION))}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def usage
|
||||||
|
"#{Style.highlight("renderer_info")} #{Style.notice("Returns OpenGL renderer information")}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
class IMICFPS
|
class IMICFPS
|
||||||
class Window < CyberarmEngine::Window
|
class Window < CyberarmEngine::Window
|
||||||
attr_accessor :number_of_vertices, :needs_cursor
|
attr_accessor :number_of_vertices, :needs_cursor
|
||||||
attr_reader :renderer, :scene, :config
|
attr_reader :renderer, :scene, :config, :director
|
||||||
|
|
||||||
attr_reader :console, :delta_time
|
attr_reader :console, :delta_time
|
||||||
def initialize(window_width = 1280, window_height = 720, fullscreen = false)
|
def initialize(window_width = 1280, window_height = 720, fullscreen = false)
|
||||||
@@ -23,6 +23,8 @@ class IMICFPS
|
|||||||
|
|
||||||
self.caption = "#{IMICFPS::NAME} v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME})"
|
self.caption = "#{IMICFPS::NAME} v#{IMICFPS::VERSION} (#{IMICFPS::RELEASE_NAME})"
|
||||||
|
|
||||||
|
@director = Networking::Director.new
|
||||||
|
|
||||||
@config = CyberarmEngine::ConfigFile.new(file: IMICFPS::GAME_ROOT_PATH + "/data/config.json")
|
@config = CyberarmEngine::ConfigFile.new(file: IMICFPS::GAME_ROOT_PATH + "/data/config.json")
|
||||||
@show_console = false
|
@show_console = false
|
||||||
@console = Console.new
|
@console = Console.new
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ require_all "lib/networking/backend"
|
|||||||
Thread.abort_on_exception = true
|
Thread.abort_on_exception = true
|
||||||
|
|
||||||
server = CyberarmEngine::Networking::Server.new
|
server = CyberarmEngine::Networking::Server.new
|
||||||
def server.client_connected(peer:)
|
def server.peer_connected(peer:)
|
||||||
puts "Client connected as peer: #{peer.id}"
|
puts "Peer connected: #{peer.id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def server.packet_received(peer:, message:, channel:)
|
def server.packet_received(peer:, message:, channel:)
|
||||||
|
|||||||
Reference in New Issue
Block a user