by Dahrkael
What is ENet?
ENet's purpose is to provide a relatively thin, simple and robust network communication layer on top of UDP (User Datagram Protocol). The primary feature it provides is optional reliable, in-order delivery of packets.
ENet omits certain higher level networking features such as authentication, lobbying, server discovery, encryption, or other similar tasks that are particularly application specific so that the library remains flexible, portable, and easily embeddable.
Isn't ENet just re-inventing TCP?! What's the point?
In a perfect world, that would be true. But as many have found, using TCP either in lieu of or in conjunction with UDP can lead to all kinds of nightmares. TCP is a good, solid protocol, however it simply isn't up to the task of real-time games. Too much of TCP's implementation dictates a policy that isn't practical for games. If you want to use TCP, then do so -- this library is for people that either don't want to use TCP or have tried and ended up being discouraged with the performance.
Can I make ultra MMORPGs with this script?
Short answer: Yes, if you know how.
Long answer: Yes, ENet is made to develop real-time games with low latency, so you can make any type of online game, but this script wont do it alone, it needs you if you dont know how to make a mmorpg, forget it. Right know this script is only an scripters tool.
Cool things about this lib
- It is made for games
- Server can be done in C/C++ using the same lib and run in different OS
- It is easy to understand
- Fuck, its cool.
Scripts and DLLs
The script uses 1 DLL in order to work: RubyENet.dll
Downlaod RubyENet.dll
This is the main script:
Ruby:
################################################################################
#
# ###### # # ###### ##### ENet Ruby Bindings
# # ## # # #
# #### # # # #### # Last Update: 24/8/2010
# # # # # # #
# ###### # ## ###### # By Dahrkael
#
################################################################################
#
# ENet's purpose is to provide a relatively thin, simple and robust network
# communication layer on top of UDP (User Datagram Protocol).
# The primary feature it provides is optional reliable, in-order delivery
# of packets.
#
# ENet omits certain higher level networking features such as authentication,
# lobbying, server discovery, encryption, or other similar tasks that are
# particularly application specific so that the library remains flexible,
# portable, and easily embeddable.
#
# Copyright (c) 2002-2010 Lee Salzman
# [url=http://enet.bespin.org/]http://enet.bespin.org/[/url]
#===============================================================================
#
# TODO:
# - Error control
# - Add all missing internal functions
#
#===============================================================================
#
# This script is free to use and doesnt need any credits B U T enet library does
#
################################################################################
#==============================================================================
# * Module Enet
#
# Methods
# - initialize
# - deinitialize
# - destroy_event_packet
# - get_packet_data
# - get_packet_datalength
# - get_packet_from_event
# - get_channelid_from_event
# - get_peer_from_event
# - get_peer_host
# - get_peer_port
#
# SubModules
# - DLLs
# - Types
# - Constants
# - APIFunctions
#
# SubClasses (and methods)
# - ENetHost
# - initialize
# - create_host
# - destroy_host
# - connect
# - peers_list
# - send_packet
# - broadcast_packet
# - disconnect
# - service
# - on_packet_receive
# - on_connection
# - on_disconnect
#
# - ENetAddress
# - initialize
# - set_host
# - set_port
#
# - ENetEvent
# - initialize
# - update
# - peer
# - peer_host
# - peer_port
# - channel_id
# - packet
# - destroy_packet
#
# - ENetPacket
# - initialize
# - update
# - data_length
# - data
#
#==============================================================================
module Win32
#--------------------------------------------------------------------------
# * Retrieves data from a pointer.
#--------------------------------------------------------------------------
def copymem(len)
buf = "\0" * len
Win32API.new("kernel32", "RtlMoveMemory", "pll", "").call(buf, self, len)
buf
end
end
# Extends the numeric class.
class Numeric
include Win32
end
# Extends the string class.
class String
include Win32
end
module Enet
#==============================================================================
# * M O D U L E S
#==============================================================================
#============================================================================
# ** DLLs
#----------------------------------------------------------------------------
# dlls containing needed functions
#============================================================================
module DLLs
Enet = "RubyENet.dll" # enet itself
RubyEnet = "RubyENet.dll" # auxiliar functions
end
#============================================================================
# ** Types
#----------------------------------------------------------------------------
# Enet types converted to Win32API types
#============================================================================
module Types
ENetAddress = 'P'
ENetHost = 'L'
ENetEvent = 'L'
ENetPacket = 'L'
ENetPeer = 'L'
Enet_uint32 = 'L'
Enet_uint16 = 'L'
Enet_uint8 = 'I'
Size_t = 'L'
Int = 'I'
Void = 'V'
Const_void = 'P'
Const_char = 'P'
end
#============================================================================
# ** Constants
#----------------------------------------------------------------------------
# Enet constants, better than numbers
#============================================================================
module Constants
NULL = 0 # yes...
ENET_HOST_ANY = 0
ENET_HOST_BROADCAST = 0xFFFFFFFF
ENET_PORT_ANY = 0
ENET_EVENT_TYPE_NONE = 0
ENET_EVENT_TYPE_CONNECT = 1
ENET_EVENT_TYPE_DISCONNECT = 2
ENET_EVENT_TYPE_RECEIVE = 3
ENET_PACKET_FLAG_RELIABLE = 1 # (1 << 0)
ENET_PACKET_FLAG_UNSEQUENCED = 2 # (1 << 1)
ENET_PACKET_FLAG_NO_ALLOCATE = 4 # (1 << 2)
end
#============================================================================
# ** APIFunctions
#----------------------------------------------------------------------------
# DLL Functions, some secondary and/or no-vital functions are missing
#============================================================================
module APIFunctions
include Types
#--------------------------------------------------------------------------
# * Workaround Function (anyone help :3?)
#--------------------------------------------------------------------------
RubyEnet_CreateENetEvent = Win32API.new(DLLs::RubyEnet, "RubyEnet_CreateENetEvent", [''], ENetEvent)
#--------------------------------------------------------------------------
# * ENetEvent Auxiliar Functions
#--------------------------------------------------------------------------
RubyEnet_GetPeerFromEvent = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetPeerFromEvent", [ENetEvent], ENetPeer)
RubyEnet_GetEventType = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetEventType", [ENetEvent], Int)
RubyEnet_GetChannelIDFromEvent = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetChannelIDFromEvent", [ENetEvent], Enet_uint8)
#--------------------------------------------------------------------------
# * ENetPacket Auxiliar Functions
#--------------------------------------------------------------------------
RubyEnet_GetPacketFromEvent = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetPacketFromEvent", [ENetEvent], ENetPacket)
RubyEnet_GetPacket_DataLength = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetPacket_DataLength", [ENetPacket], Size_t)
RubyEnet_GetPacket_Data = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetPacket_Data", [ENetPacket], 'P')
#--------------------------------------------------------------------------
# * ENetPeer Auxiliar Functions
#--------------------------------------------------------------------------
RubyEnet_GetPeerHost = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetPeerHost", [ENetPeer], Enet_uint32)
RubyEnet_GetPeerPort = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetPeerPort", [ENetPeer], Enet_uint32)
RubyEnet_GetPeerIP = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetPeerIP", [ENetPeer], "L")
RubyEnet_GetPeerIPlength = Win32API.new(DLLs::RubyEnet, "RubyEnet_GetPeerIPlength", [ENetPeer], Size_t)
#--------------------------------------------------------------------------
# * ENet Basic Functions
#--------------------------------------------------------------------------
Enet_initialize = Win32API.new(DLLs::Enet, "enet_initialize", [''], Int)
Enet_deinitialize = Win32API.new(DLLs::Enet, "enet_deinitialize", [''], Void)
#--------------------------------------------------------------------------
# * ENetHost Functions
#--------------------------------------------------------------------------
Enet_host_create = Win32API.new(DLLs::Enet, "enet_host_create", [ENetAddress, Size_t, Size_t, Enet_uint32, Enet_uint32], ENetHost)
Enet_host_destroy = Win32API.new(DLLs::Enet, "enet_host_destroy", [ENetHost], Void)
Enet_host_connect = Win32API.new(DLLs::Enet, "enet_host_connect", [ENetHost, ENetAddress, Size_t, Enet_uint32], ENetPeer)
Enet_host_service = Win32API.new(DLLs::Enet, "enet_host_service", [ENetHost, ENetEvent, Enet_uint32], Int)
Enet_host_broadcast = Win32API.new(DLLs::Enet, "enet_host_broadcast", [ENetHost, Enet_uint8, ENetPacket], Void)
Enet_host_flush = Win32API.new(DLLs::Enet, "enet_host_flush", [ENetHost], Void)
Enet_address_set_host = Win32API.new(DLLs::Enet, "enet_address_set_host", [ENetAddress, Const_char], Int)
#--------------------------------------------------------------------------
# * ENetpacket Functions
#--------------------------------------------------------------------------
Enet_packet_create = Win32API.new(DLLs::Enet, "enet_packet_create", [Const_void, Size_t, Enet_uint32], ENetPacket)
Enet_packet_destroy = Win32API.new(DLLs::Enet, "enet_packet_destroy", [ENetPacket], Void)
#--------------------------------------------------------------------------
# * ENetPeer Functions
#--------------------------------------------------------------------------
Enet_peer_send = Win32API.new(DLLs::Enet, "enet_peer_send", [ENetPeer, Enet_uint8, ENetPacket], Int)
Enet_peer_disconnect = Win32API.new(DLLs::Enet, "enet_peer_disconnect", [ENetPeer, Enet_uint32], Void)
Enet_peer_reset = Win32API.new(DLLs::Enet, "enet_peer_reset", [ENetPeer], Void)
end
#==============================================================================
# * M E T H O D S
#==============================================================================
#----------------------------------------------------------------------------
# * initialize
# Starts the library
#----------------------------------------------------------------------------
def self.initialize
APIFunctions::Enet_initialize.call()
end
#----------------------------------------------------------------------------
# * deinitialize
# Stops the library
#----------------------------------------------------------------------------
def self.deinitialize
APIFunctions::Enet_deinitialize.call()
end
#----------------------------------------------------------------------------
# * Destroy Event Packet
# Destroys the packet contained in the event
#----------------------------------------------------------------------------
def self.destroy_event_packet(event)
packet = self.get_packet_from_event(event)
APIFunctions::Enet_packet_destroy.call(packet)
end
#----------------------------------------------------------------------------
# * Get Packet Data
# Returns a string with the packet data
#----------------------------------------------------------------------------
def self.get_packet_data(packet)
length = APIFunctions::RubyEnet_GetPacket_DataLength.call(packet)
data = 0.chr * length
data = APIFunctions::RubyEnet_GetPacket_Data.call(packet)
return data
end
#----------------------------------------------------------------------------
# * Get Packet Datalength
# Returns the datalength from the packet (the data size)
#----------------------------------------------------------------------------
def self.get_packet_datalength(packet)
return APIFunctions::RubyEnet_GetPacket_DataLength.call(packet)
end
#----------------------------------------------------------------------------
# * Get Packet From Event
# Returns the packet pointer from the event
#----------------------------------------------------------------------------
def self.get_packet_from_event(event)
return APIFunctions::RubyEnet_GetPacketFromEvent.call(event)
end
#----------------------------------------------------------------------------
# * Get ChannelID From Event
# Returns the ChannelID used
#----------------------------------------------------------------------------
def self.get_channelid_from_event(event)
return APIFunctions::RubyEnet_GetChannelIDFromEvent.call(event)
end
#----------------------------------------------------------------------------
# * Get Peer From Event
# gets the peer pointer who generated the event
#----------------------------------------------------------------------------
def self.get_peer_from_event(event)
return APIFunctions::RubyEnet_GetPeerFromEvent.call(event)
end
#----------------------------------------------------------------------------
# * Get Peer Host
# Returns the hexadecimal peers address
#----------------------------------------------------------------------------
def self.get_peer_host(peer)
return APIFunctions::RubyEnet_GetPeerHost.call(peer)
end
#----------------------------------------------------------------------------
# * Get Peer Port
# Returns the peers port
#----------------------------------------------------------------------------
def self.get_peer_port(peer)
return APIFunctions::RubyEnet_GetPeerPort.call(peer)
end
def self.get_peer_ip(peer)
length = APIFunctions::RubyEnet_GetPeerIPlength.call(peer)
buf = APIFunctions::RubyEnet_GetPeerIP.call(peer)
ip = buf.copymem(length)
return ip
end
#==============================================================================
# * C L A S S E S
#==============================================================================
#============================================================================
# ** ENetHost
#----------------------------------------------------------------------------
# Class that represents the computer networking and the connections
# associated
#============================================================================
class ENetHost
#----------------------------------------------------------------------------
# * Public Instance Variables
#----------------------------------------------------------------------------
attr_reader :connected # returns true if connected, all peers uses this var :/
#----------------------------------------------------------------------------
# * Object Initialization
#----------------------------------------------------------------------------
def initialize
@enet_host = nil
@peers = {}
@connections = 0
@channels = 0
@downstream = 0
@upstream = 0
@event = APIFunctions::RubyEnet_CreateENetEvent.call()
@external_event = ENetEvent.new(@event)
@connected = false
@on_packet_receive = nil
@on_disconnect = nil
@on_connection = nil
end
#----------------------------------------------------------------------------
# * Event
#----------------------------------------------------------------------------
def event
return @external_event
end
#----------------------------------------------------------------------------
# * Create Host
# type: Client or Server, NULL = Client, Pointer to ENetAddress = Server
# connections: Outgoing connections allowed (number)
# channels: Number of avaiable channels for connections (number)
# downstream: Downstream bandwidth in bytes (number)
# upstream: Upstream bandwidth in bytes (number)
#----------------------------------------------------------------------------
def create_host(type, connections, channels, downstream, upstream)
@enet_host = APIFunctions::Enet_host_create.call(type, connections, channels, downstream, upstream)
if @enet_host != 0
@connections = connections
@channels = channels
@downstream = downstream
@upstream = upstream
return true
else
return false
end
end
#----------------------------------------------------------------------------
# * Destroy Host
#----------------------------------------------------------------------------
def destroy_host
APIFunctions::Enet_host_destroy.call(@enet_host)
@enet_host = nil
@connections = 0
@channels = 0
@downstream = 0
@upstream = 0
end
#----------------------------------------------------------------------------
# * Connect
# address: ENetAddres instance with the remote host address and port (ENetAddress)
# channels: Number of channels allocated for this connection (number)
# extradata: Optional data to send with the connection petition (string)
#----------------------------------------------------------------------------
def connect(address, channels, extradata=0)
peer = APIFunctions::Enet_host_connect.call(@enet_host, address.enet_address, channels, extradata)
if peer != 0
address = APIFunctions::RubyEnet_GetPeerHost.call(peer)
port = APIFunctions::RubyEnet_GetPeerPort.call(peer)
@peers["server"] = {
"peer" => peer,
"address" => address,
"port" => port
}
return true
else
return false
end
end
#----------------------------------------------------------------------------
# * Peers List
#----------------------------------------------------------------------------
def peers_list
return @peers
end
#----------------------------------------------------------------------------
# * Send packet
# peer: peer to send the packet (pointer to peer)
# data: data to send in the packet, text, binary, anything (~string)
# datalength: data length + 1 (number)
# channelID: Channel to send the packet (number)
# flags: Optional flags for the packet, default is ENET_PACKET_FLAG_RELIABLE
#----------------------------------------------------------------------------
def send_packet(peer, data, datalength, channelID, flags=Constants::ENET_PACKET_FLAG_RELIABLE)
packet = APIFunctions::Enet_packet_create.call(data, datalength, flags)
if APIFunctions::Enet_peer_send.call(peer, channelID, packet) < 0
return false
else
return true
end
end
#----------------------------------------------------------------------------
# * Broadcast Packet
# data: data to send in the packet, text, binary, anything (~string)
# datalength: data length + 1 (number)
# channelID: Channel to send the packet (number)
# flags: Optional flags for the packet, default is ENET_PACKET_FLAG_RELIABLE
#----------------------------------------------------------------------------
def broadcast_packet(data, datalength, channelID, flags=Constants::ENET_PACKET_FLAG_RELIABLE)
packet = APIFunctions::Enet_packet_create.call(data, datalength, flags)
APIFunctions::Enet_host_broadcast.call(@enet_host, channelID, packet)
return true
end
#----------------------------------------------------------------------------
# * Disconnect
# peer: peer to disconnect (peer name string)
# data: extra data to send with the disconnection petition (~string)
# timeout: time in milliseconds to get answer, when over disconnection is forced (number)
#----------------------------------------------------------------------------
def disconnect(peer, data=0, timeout=3000)
APIFunctions::Enet_peer_disconnect.call(peer, data)
while APIFunctions::Enet_host_service.call(@enet_host, @event, timeout) > 0
case APIFunctions::RubyEnet_GetEventType.call(@event)
when Constants::ENET_EVENT_TYPE_RECEIVE
APIFunctions::Enet_packet_destroy(RubyEnet_GetPacketFromEvent.call(@event))
when Constants::ENET_EVENT_TYPE_DISCONNECT
@peers[peer] = nil
#print "Disconnected"
return true
end
end
#APIFunctions::Enet_peer_reset(@peers[peer]["peer"])
@peers[peer] = nil
return true
end
#----------------------------------------------------------------------------
# * Service
# milliseconds: time to wait for a packet (number)
#----------------------------------------------------------------------------
def service(milliseconds=1000)
while APIFunctions::Enet_host_service.call(@enet_host, @event, milliseconds) > 0
case APIFunctions::RubyEnet_GetEventType.call(@event)
when Constants::ENET_EVENT_TYPE_NONE
when Constants::ENET_EVENT_TYPE_CONNECT
#print "new client connected"
@external_event.update(@event)
on_connection
APIFunctions::Enet_host_flush.call(@enet_host)
@connected = true
when Constants::ENET_EVENT_TYPE_DISCONNECT
@connected = false
#print "Disconnected"
@external_event.update(@event)
on_disconnect
when Constants::ENET_EVENT_TYPE_RECEIVE
@external_event.update(@event)
on_packet_receive
end
end
end
#----------------------------------------------------------------------------
# * On Disconnection
# Method called when a disconnection event arrives
#----------------------------------------------------------------------------
def on_disconnect(&block)
if block
@on_disconnect = block
elsif @on_disconnect
@on_disconnect.call()
end
end
#----------------------------------------------------------------------------
# * On Connection
# Method called when a connection event arrives
#----------------------------------------------------------------------------
def on_connection(&block)
if block
@on_connection = block
elsif @on_connection
@on_connection.call()
end
end
#----------------------------------------------------------------------------
# * Packet Received
# Method called when an event containing a packet arrives
#----------------------------------------------------------------------------
def on_packet_receive(&block)
if block
@on_packet_receive = block
elsif @on_packet_receive
@on_packet_receive.call()
#destroy_event_packet(@event)
end
end
end
#============================================================================
# ** ENetAddress
#----------------------------------------------------------------------------
# Class to simplify C ENetAddress structs
#============================================================================
class ENetAddress
#----------------------------------------------------------------------------
# * Public Instance Variables
#----------------------------------------------------------------------------
attr_reader :address
attr_reader :port
attr_reader :enet_address
#----------------------------------------------------------------------------
# * Object Initialization
#----------------------------------------------------------------------------
def initialize
@address = ""
@port = 0
@enet_address = ""
end
#----------------------------------------------------------------------------
# * Set Host
# host: remote host to get address (string)
#----------------------------------------------------------------------------
def set_host(host)
@enet_address = [Constants::ENET_HOST_ANY, @port].pack("LS")
if APIFunctions::Enet_address_set_host.call(@enet_address, host) < 0
return false
end
@address = host
return true
end
#----------------------------------------------------------------------------
# * Set Port
# port: port to bind
#----------------------------------------------------------------------------
def set_port(port)
@port = port
@enet_address = [Constants::ENET_HOST_ANY, @port].pack("LS")
set_host(@address)
return true
end
end
#============================================================================
# ** ENetPacket
#----------------------------------------------------------------------------
# Class to simplify C ENetPacket structs
#============================================================================
class ENetPacket
#----------------------------------------------------------------------------
# * Object Initialization
# packet: packet to wrap
#----------------------------------------------------------------------------
def initialize(packet)
@packet = packet
@length = 0
@data = 0
end
#----------------------------------------------------------------------------
# * Update
# packet: packet to wrap
#----------------------------------------------------------------------------
def update(packet)
@packet = packet
@length = 0
@data = 0
end
#----------------------------------------------------------------------------
# * Data Length
#----------------------------------------------------------------------------
def data_length
@length = Enet.get_packet_datalength(@packet)
return @length
end
#----------------------------------------------------------------------------
# * Data
#----------------------------------------------------------------------------
def data
if RUBY_VERSION.match(/1\.8\.*/)
@data = Enet.get_packet_data(@packet)
elsif RUBY_VERSION.match(/1\.9\.*/)
@length = Enet.get_packet_datalength(@packet)
data = Enet.get_packet_data(@packet)
@data = data.copymem(@length)
end
return @data
end
end
#============================================================================
# ** ENetEvent
#----------------------------------------------------------------------------
# Class to simplify C ENetEvent structs
#============================================================================
class ENetEvent
#----------------------------------------------------------------------------
# * Object Initialization
# event: event to wrap
#----------------------------------------------------------------------------
def initialize(event)
@event = event
@peer = 0
@peer_host = 0
@peer_port = 0
@channel_id = 0
@packet = 0
end
#----------------------------------------------------------------------------
# * Update
# event: event to wrap
#----------------------------------------------------------------------------
def update(event)
@event = event
@peer = 0
@peer_host = 0
@peer_port = 0
@channel_id = 0
@packet = 0
end
#----------------------------------------------------------------------------
# * Peer
#----------------------------------------------------------------------------
def peer
@peer = Enet.get_peer_from_event(@event)
return @peer
end
#----------------------------------------------------------------------------
# * Peer Host
#----------------------------------------------------------------------------
def peer_host
if @peer == 0
@peer = Enet.get_peer_from_event(@event)
end
@host = Enet.get_peer_host(@peer)
return @host
end
#----------------------------------------------------------------------------
# * Peer Port
#----------------------------------------------------------------------------
def peer_port
if @peer == 0
@peer = Enet.get_peer_from_event(@event)
end
@port = Enet.get_peer_port(@peer)
return @port
end
#----------------------------------------------------------------------------
# * Channel ID
#----------------------------------------------------------------------------
def channel_id
@channel_id = Enet.get_channelid_from_event(@event)
end
#----------------------------------------------------------------------------
# * Packet
#----------------------------------------------------------------------------
def packet
if @packet == 0
packet = Enet.get_packet_from_event(@event)
@packet = ENetPacket.new(packet)
end
return @packet
end
#----------------------------------------------------------------------------
# * Destroy Packet
#----------------------------------------------------------------------------
def destroy_packet
Enet.destroy_event_packet(@event)
@packet = 0
end
end
end # Classes end
Examples
Documentation from my part is not really cool, so here is an example script to make a client, so you can understand how this works:
Ruby:
class ENet_Example
def run
# First we initialize ENet
if Enet.initialize != 0 # 0 = all ok
print "error initializing enet"
exit # exit if enet fails
end
# Now we need two things to make this work
# an ENetAddress
# an ENetHost
# First the ENetAddress
@address = Enet::ENetAddress.new
# Set the address!
if @address.set_host("localhost") == true
print "host set"
else
print "error setting host"
end
# Now the port!
if @address.set_port(8000) == true
print "port set"
else
print "error setting port"
end
# Secondly the ENetHost
@client = Enet::ENetHost.new
# Now create the internal host
if @client.create_host(Enet::Constants::NULL, 1, 2, 57600/8, 14400/8) == true
print "host created"
end
# Optional but important step
# tell the host what to do when a packet arrives
@client.on_packet_receive do
print "packet arrived"
# get the peer
@client.event.peer
# show info about the peer
print "from "
+ @client.event.peer_host.to_s
+ ":"
+ @client.event.peer_port.to_s
print "packet arrived in channel: "
+ @client.event.channel_id.to_s
# get the packet
packet = @client.event.packet
# show info about the packet
print "packet lenght: " + packet.data_length.to_s
print "packet data: " + packet.data.to_s
# finished, destroy the packet
@client.event.destroy_packet
end
# Time to connect to the server!
if @client.connect(@address, 2, 0) == true
print "connection established"
end
# Now check for the server answer
@client.service
# if the server answers then connected will be true
if @client.connected == true
print "connection confirmed"
# Retrieve the peerlist and get the server peer pointer
# peer list is like
# [i][0] = peer pointer
# [i][1] = peer ip
# [i][2] = peer port
@server = @client.peers_list[0][0]
#send and check 5 times
for i in 0..5
# this checks and send the packets in queue
@client.service
string = "example packet"
# this queues a new packet
@client.send_packet(@server, string, string.size+1, 0)
end
else
print "connection unconfirmed"
end
# deinitialize the enet library
Enet.deinitialize
# finished!
end
end
You can make a server script in ruby too, but if your game is gonna be cool, make it in C/C++.
Server Example:
Ruby:
#------------------------------------------------------------------------------#
#
# Server Basis
#
# Packet Data doesnt work on ruby 1.9.x right now
#
#------------------------------------------------------------------------------#
if Enet.initialize != 0
print "error initializing enet\r\n"
exit
end
address = [0, 8000].pack("LS")
@server = Enet::ENetHost.new
if @server.create_host(address, 32, 2, 0, 0) == true
print "server created"
end
@server.on_connection do
print "new user connected"
end
@server.on_disconnect do
print "user disconnected"
end
@server.on_packet_receive do
print "packet arrived"
#@server.event.peer
print "from " + Enet.get_peer_ip(@server.event.peer).to_s + ":" + @server.event.peer_port.to_s
print "packet arrived in channel: " + @server.event.channel_id.to_s
packet = @server.event.packet
print "packet lenght: " + packet.data_length.to_s
print "packet data: " + packet.data.to_s
@server.event.destroy_packet
end
loop do
@server.service
#@server.send_packet(@server, string, string.size+1, 0)
end
Enet.deinitialize
Demo
All packed in one rpg maker xp demo:
Download RPG Maker XP Demo
Bugs
- No known bugs
Final Notes
Ask anything, request anything, comment anything. Cheers.