Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Sockets TCP Sever

Seto

Member

Sockets TCP Sever
This is a request for a modification of an existing script.
Networking Script:
RMXP:

Detailed Description:
I want to be able to host a sever from within the game itself, so that a player can pick whether to host or join a game. I just need the to be able to use the TCPSever functions that are normally accessible in ruby, from my knowledge this script has the ability to create host sockets their are just no functions that put it all together and allow it to be used. Although it was a long time ago I used to know how to create a host socket I remember there being 3 steps one of which uses the bind method, although now I need to create one I have totally forgotten and can not find what I need on the net. Anything on this subject would is appreciated, explanations advice, links, tutorials or the actually modification of the script. To be as clear as possible below is a small snipit of the script that works the TCPclient side.

Code:
 

#===============================================================================

# ** TCPSocket - Creates and manages TCP sockets.

#-------------------------------------------------------------------------------

# Author    Ruby

# Version   1.8.1

#===============================================================================

 

class TCPSocket < Socket

 

  #--------------------------------------------------------------------------

  # ● Creates a new socket and connects it to the given host and port.

  #--------------------------------------------------------------------------  

  def self.open(*args)

    socket = new(*args)

    if block_given?

      begin

        yield socket

      ensure

        socket.close

      end

    end

    nil

  end

 

  #--------------------------------------------------------------------------

  # ● Creates a new socket and connects it to the given host and port.

  #--------------------------------------------------------------------------  

  def initialize(host, port)

    super(AF_INET, SOCK_STREAM, IPPROTO_TCP)

    connect(Socket.sockaddr_in(port, host))

  end

 

end

 

#==============================================================================

# â–  SocketError

#------------------------------------------------------------------------------

#  Default exception class for sockets.

#==============================================================================

class SocketError < StandardError

  ENOASSOCHOST = "getaddrinfo: no address associated with hostname."

  def self.check

    errno = Winsock.WSAGetLastError

    errno = Errno.constants.detect { |c| Errno.const_get(c).new.errno == errno }

    if errno != nil

      raise Errno.const_get(errno)

    end

  end

end

 

I would like this part of the script modified to allow hosting/server capabilities.
Screen shots:
Not screen shots, not applicable.
Other Scripts I am using (in order):
For this script I am using no other scripts and no SDK

Bellow is the networking script, thanks in advance for any help given.

Code:
 

#===============================================================================

# ** Module Win32 - Handles numerical based data.

#-------------------------------------------------------------------------------

# Author    Ruby

# Version   1.8.1

#===============================================================================

 

 

module Win32

 

  #--------------------------------------------------------------------------

  # ● Retrieves data from a pointer.

  #--------------------------------------------------------------------------

  def copymem(len)

    buf = "\0" * len

    Win32API.new("kernel32", "RtlMoveMemory", "ppl", "").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 Winsock - Maps out the functions held in the Winsock DLL.

#-------------------------------------------------------------------------------

# Author    Ruby

# Version   1.8.1

#===============================================================================

 

module Winsock

 

  DLL = "ws2_32"

 

  #--------------------------------------------------------------------------

  # * Accept Connection

  #--------------------------------------------------------------------------

  def self.accept(*args)

    Win32API.new(DLL, "accept", "ppl", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Bind

  #--------------------------------------------------------------------------

  def self.bind(*args)

    Win32API.new(DLL, "bind", "ppl", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Close Socket

  #--------------------------------------------------------------------------

  def self.closesocket(*args)

    Win32API.new(DLL, "closesocket", "p", "l").call(*args)

  end  

 

  #--------------------------------------------------------------------------

  # * Connect

  #--------------------------------------------------------------------------

  def self.connect(*args)

    Win32API.new(DLL, "connect", "ppl", "l").call(*args)

  end    

 

  #--------------------------------------------------------------------------

  # * Get host (Using Adress)

  #--------------------------------------------------------------------------

  def self.gethostbyaddr(*args)

    Win32API.new(DLL, "gethostbyaddr", "pll", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Get host (Using Name)

  #--------------------------------------------------------------------------

  def self.gethostbyname(*args)

    Win32API.new(DLL, "gethostbyname", "p", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Get host's Name

  #--------------------------------------------------------------------------

  def self.gethostname(*args)

    Win32API.new(DLL, "gethostname", "pl", "").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Get Server (Using Name)

  #--------------------------------------------------------------------------

  def self.getservbyname(*args)

    Win32API.new(DLL, "getservbyname", "pp", "p").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * HT OnL

  #--------------------------------------------------------------------------

  def self.htonl(*args)

    Win32API.new(DLL, "htonl", "l", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * HT OnS

  #--------------------------------------------------------------------------

  def self.htons(*args)

    Win32API.new(DLL, "htons", "l", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Inet Adress

  #--------------------------------------------------------------------------

  def self.inet_addr(*args)

    Win32API.new(DLL, "inet_addr", "p", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Inet NtOA

  #--------------------------------------------------------------------------

  def self.inet_ntoa(*args)

    Win32API.new(DLL, "inet_ntoa", "l", "p").call(*args)

  end  

 

  #--------------------------------------------------------------------------

  # * Listen

  #--------------------------------------------------------------------------

  def self.listen(*args)

    Win32API.new(DLL, "listen", "pl", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Recieve

  #--------------------------------------------------------------------------

  def self.recv(*args)

    Win32API.new(DLL, "recv", "ppll", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Select

  #--------------------------------------------------------------------------

  def self.select(*args)

    Win32API.new(DLL, "select", "lpppp", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Send

  #--------------------------------------------------------------------------

  def self.send(*args)

    Win32API.new(DLL, "send", "ppll", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Set Socket Options

  #--------------------------------------------------------------------------

  def self.setsockopt(*args)

    Win32API.new(DLL, "setsockopt", "pllpl", "l").call(*args)

  end  

 

  #--------------------------------------------------------------------------

  # * Shutdown

  #--------------------------------------------------------------------------

  def self.shutdown(*args)

    Win32API.new(DLL, "shutdown", "pl", "l").call(*args)

  end

 

  #--------------------------------------------------------------------------

  # * Socket

  #--------------------------------------------------------------------------

  def self.socket(*args)

    Win32API.new(DLL, "socket", "lll", "l").call(*args)  

  end

 

  #--------------------------------------------------------------------------

  # * Get Last Error

  #--------------------------------------------------------------------------

  def self.WSAGetLastError(*args)

    Win32API.new(DLL, "WSAGetLastError", "", "l").call(*args)

  end

 

end

 

#===============================================================================

# ** Socket - Creates and manages sockets.

#-------------------------------------------------------------------------------

# Author    Ruby

# Version   1.8.1

#===============================================================================

 

class Socket

 

  #--------------------------------------------------------------------------

  # ● Constants

  #--------------------------------------------------------------------------

  AF_UNSPEC                 = 0  

  AF_UNIX                   = 1

  AF_INET                   = 2

  AF_IPX                    = 6

  AF_APPLETALK              = 16

 

  PF_UNSPEC                 = 0  

  PF_UNIX                   = 1

  PF_INET                   = 2

  PF_IPX                    = 6

  PF_APPLETALK              = 16

 

  SOCK_STREAM               = 1

  SOCK_DGRAM                = 2

  SOCK_RAW                  = 3

  SOCK_RDM                  = 4

  SOCK_SEQPACKET            = 5

 

  IPPROTO_IP                = 0

  IPPROTO_ICMP              = 1

  IPPROTO_IGMP              = 2

  IPPROTO_GGP               = 3

  IPPROTO_TCP               = 6

  IPPROTO_PUP               = 12

  IPPROTO_UDP               = 17

  IPPROTO_IDP               = 22

  IPPROTO_ND                = 77

  IPPROTO_RAW               = 255

  IPPROTO_MAX               = 256

 

  SOL_SOCKET                = 65535

 

  SO_DEBUG                  = 1

  SO_REUSEADDR              = 4

  SO_KEEPALIVE              = 8

  SO_DONTROUTE              = 16

  SO_BROADCAST              = 32

  SO_LINGER                 = 128

  SO_OOBINLINE              = 256

  SO_RCVLOWAT               = 4100

  SO_SNDTIMEO               = 4101

  SO_RCVTIMEO               = 4102

  SO_ERROR                  = 4103

  SO_TYPE                   = 4104

  SO_SNDBUF                 = 4097

  SO_RCVBUF                 = 4098

  SO_SNDLOWAT               = 4099

 

  TCP_NODELAY               =   1

 

  MSG_OOB                   = 1

  MSG_PEEK                  = 2

  MSG_DONTROUTE             = 4

 

  IP_OPTIONS                =   1

  IP_DEFAULT_MULTICAST_LOOP =   1

  IP_DEFAULT_MULTICAST_TTL  =   1

  IP_MULTICAST_IF           =   2

  IP_MULTICAST_TTL          =   3

  IP_MULTICAST_LOOP         =   4

  IP_ADD_MEMBERSHIP         =   5

  IP_DROP_MEMBERSHIP        =   6

  IP_TTL                    =   7

  IP_TOS                    =   8

  IP_MAX_MEMBERSHIPS        =   20

 

  EAI_ADDRFAMILY            = 1

  EAI_AGAIN                 = 2

  EAI_BADFLAGS              = 3

  EAI_FAIL                  = 4

  EAI_FAMILY                = 5

  EAI_MEMORY                = 6

  EAI_NODATA                = 7

  EAI_NONAME                = 8

  EAI_SERVICE               = 9

  EAI_SOCKTYPE              = 10

  EAI_SYSTEM                = 11

  EAI_BADHINTS              = 12

  EAI_PROTOCOL              = 13

  EAI_MAX                   = 14

 

  AI_PASSIVE                = 1

  AI_CANONNAME              = 2

  AI_NUMERICHOST            = 4

  AI_MASK                   = 7

  AI_ALL                    = 256

  AI_V4MAPPED_CFG           = 512

  AI_ADDRCONFIG             = 1024

  AI_DEFAULT                = 1536

  AI_V4MAPPED               = 2048

 

  #--------------------------------------------------------------------------

  # ● Returns the associated IP address for the given hostname.

  #--------------------------------------------------------------------------  

  def self.getaddress(host)

    gethostbyname(host)[3].unpack("C4").join(".")

  end

 

  #--------------------------------------------------------------------------

  # ● Returns the associated IP address for the given hostname.

  #--------------------------------------------------------------------------  

  def self.getservice(serv)

    case serv

    when Numeric

      return serv

    when String

      return getservbyname(serv)

    else

      raise "Please us an interger or string for services."

    end

  end

 

  #--------------------------------------------------------------------------

  # ● Returns information about the given hostname.

  #--------------------------------------------------------------------------

  def self.gethostbyname(name)

    raise SocketError::ENOASSOCHOST if (ptr = Winsock.gethostbyname(name)) == 0

    host = ptr.copymem(16).unpack("iissi")

    [host[0].copymem(64).split("\0")[0], [], host[2], host[4].copymem(4).unpack("l")[0].copymem(4)]

  end

 

  #--------------------------------------------------------------------------

  # ● Returns the user's hostname.

  #--------------------------------------------------------------------------  

  def self.gethostname

    buf = "\0" * 256

    Winsock.gethostname(buf, 256)

    buf.strip

  end

 

  #--------------------------------------------------------------------------

  # ● Returns information about the given service.

  #--------------------------------------------------------------------------

  def self.getservbyname(name)

    case name

    when /echo/i

      return 7

    when /daytime/i

      return 13

    when /ftp/i

      return 21

    when /telnet/i

      return 23

    when /smtp/i

      return 25

    when /time/i

      return 37

    when /http/i

      return 80

    when /pop/i

      return 110

    else

      raise "Service not recognized."

    end

  end

 

  #--------------------------------------------------------------------------

  # ● Creates an INET-sockaddr struct.

  #--------------------------------------------------------------------------  

  def self.sockaddr_in(port, host)

    begin

      [AF_INET, getservice(port)].pack("sn") + gethostbyname(host)[3] + [].pack("x8")

    rescue

      nil

    end

  end

 

  #--------------------------------------------------------------------------

  # ● Creates a new socket and connects it to the given host and port.

  #--------------------------------------------------------------------------  

  def self.open(*args)

    socket = new(*args)

    if block_given?

      begin

        yield socket

      ensure

        socket.close

      end

    end

    nil

  end

 

  #--------------------------------------------------------------------------

  # ● Creates a new socket.

  #--------------------------------------------------------------------------  

  def initialize(domain, type, protocol)

    SocketError.check if (@fd = Winsock.socket(domain, type, protocol)) == -1

    @fd

  end

 

  #--------------------------------------------------------------------------

  # ● Accepts incoming connections.

  #--------------------------------------------------------------------------  

  def accept(flags = 0)

    buf = "\0" * 16

    SocketError.check if Winsock.accept(@fd, buf, flags) == -1

    buf

  end

 

  #--------------------------------------------------------------------------

  # ● Binds a socket to the given sockaddr.

  #--------------------------------------------------------------------------  

  def bind(sockaddr)

    SocketError.check if (ret = Winsock.bind(@fd, sockaddr, sockaddr.size)) == -1

    ret

  end

 

  #--------------------------------------------------------------------------

  # ● Closes a socket.

  #--------------------------------------------------------------------------  

  def close

    SocketError.check if (ret = Winsock.closesocket(@fd)) == -1

    ret

  end

 

  #--------------------------------------------------------------------------

  # ● Connects a socket to the given sockaddr.

  #--------------------------------------------------------------------------  

  def connect(sockaddr)

    ret = Winsock.connect(@fd, sockaddr, sockaddr.size)

    SocketError.check if ret == -1

    ret

  end

 

  #--------------------------------------------------------------------------

  # ● Listens for incoming connections.

  #--------------------------------------------------------------------------  

  def listen(backlog)

    SocketError.check if (ret = Winsock.listen(@fd, backlog)) == -1

    ret

  end

 

  #--------------------------------------------------------------------------

  # ● Checks waiting data's status.

  #--------------------------------------------------------------------------  

  def select(timeout)

    SocketError.check if (ret = Winsock.select(1, [1, @fd].pack("ll"), 0, 0, [timeout, timeout * 1000000].pack("ll"))) == -1

    ret

  end

 

  #--------------------------------------------------------------------------

  # ● Checks if data is waiting.

  #--------------------------------------------------------------------------  

  def ready?

    not select(0) == 0

  end  

 

  #--------------------------------------------------------------------------

  # ● Reads data from socket.

  #--------------------------------------------------------------------------  

  def read(len)

    buf = "\0" * len

    Win32API.new("msvcrt", "_read", "lpl", "l").call(@fd, buf, len)

    buf

  end

 

  #--------------------------------------------------------------------------

  # ● Returns recieved data.

  #--------------------------------------------------------------------------  

  def recv(len, flags = 0)

    buf = "\0" * len

    SocketError.check if Winsock.recv(@fd, buf, buf.size, flags) == -1

    buf

  end

 

  #--------------------------------------------------------------------------

  # ● Sends data to a host.

  #--------------------------------------------------------------------------  

  def send(data, flags = 0)

    SocketError.check if (ret = Winsock.send(@fd, data, data.size, flags)) == -1

    ret

  end

 

  #--------------------------------------------------------------------------

  # * Gets

  #--------------------------------------------------------------------------

  def gets

    # Create buffer

    buffer = ""

    # Loop Until "end of line"

    while (char = recv(1)) != "\n"

      buffer += char

    end

    # Return recieved data

    return buffer

  end

 

  #--------------------------------------------------------------------------

  # ● Writes data to socket.

  #--------------------------------------------------------------------------  

  def write(data)

    Win32API.new("msvcrt", "_write", "lpl", "l").call(@fd, data, 1)

  end

 

end

 

 

#===============================================================================

# ** TCPSocket - Creates and manages TCP sockets.

#-------------------------------------------------------------------------------

# Author    Ruby

# Version   1.8.1

#===============================================================================

 

class TCPSocket < Socket

 

  #--------------------------------------------------------------------------

  # ● Creates a new socket and connects it to the given host and port.

  #--------------------------------------------------------------------------  

  def self.open(*args)

    socket = new(*args)

    if block_given?

      begin

        yield socket

      ensure

        socket.close

      end

    end

    nil

  end

 

  #--------------------------------------------------------------------------

  # ● Creates a new socket and connects it to the given host and port.

  #--------------------------------------------------------------------------  

  def initialize(host, port)

    super(AF_INET, SOCK_STREAM, IPPROTO_TCP)

    connect(Socket.sockaddr_in(port, host))

  end

 

end

 

#==============================================================================

# â–  SocketError

#------------------------------------------------------------------------------

#  Default exception class for sockets.

#==============================================================================

class SocketError < StandardError

  ENOASSOCHOST = "getaddrinfo: no address associated with hostname."

  def self.check

    errno = Winsock.WSAGetLastError

    errno = Errno.constants.detect { |c| Errno.const_get(c).new.errno == errno }

    if errno != nil

      raise Errno.const_get(errno)

    end

  end

end

 

 

Please note that I didn't make this script and do not take credit for it, its actually a combination of multiply scripts needed for networking functions.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top