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.

Ruby - Sockets & co

Hmm. I need the socket classes from Ruby, though can't find them by searching the Ruby folder and the ones I currently have have been editted by Netplay+ so are useless for what I want to do (there is a lot missing from them).

Normally I'd just do:

require 'socket'
require 'winsock'
require 'tcpsocket'

But a, RGSS broke the require function, and b, then people without Ruby couldn't use what I'm creating.

I wondered if anyone has these three classes (or would be able to get them somehow)?
 
Are you trying to use the sockets in RGSS or in Ruby? If you are trying to do it in RGSS, why, exactly, are the NetPlay+ useless? I've been using those sockets just like the ruby sockets, and I've ported my IRC bot from Ruby to RGSS just fine using the NetPlay+ sockets.
 
Really?

What I'm trying to do is create an IRC client (well, I say client, more like just a simple bot I guess).

I found that the ones in Netplay need the Network script, which needs several other scripts, and by removing the Network lines in the classes it just created many other errors. There are also things called in there suck as SocketError which don't even exist (this error turned up a lot).
 
All you need is the SDK, Win32Library, Winsock, Socket Library, TCPSocket, Network.

I've tested it myself and you can connect to IRC just fine with it. If you haven't already made an IRC Bot in RUby before, I suggest you look up some references. It's easy to accidentally do stuff that will get the server owner pissed at you XD
 
DeM0nFiRe":273t2m5m said:
All you need is the SDK, Win32Library, Winsock, Socket Library, TCPSocket, Network.

Actually, the SDK is really easy to remove so you wont need that and the Network module is also pretty easy to remove so you wont need that either.

*looks through a bunch of old RMXP projects...* Found it!

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

 

Here is Win32Library, Winsock, Socket Library and TCPSocket put together.
You won't need anything else.

Good luck! :biggrin:
 
Commodore Whynot":2w4zcdrb said:
Hmm. I need the socket classes from Ruby, though can't find them by searching the Ruby folder and the ones I currently have have been editted by Netplay+ so are useless for what I want to do (there is a lot missing from them).

Normally I'd just do:

require 'socket'
require 'winsock'
require 'tcpsocket'

But a, RGSS broke the require function, and b, then people without Ruby couldn't use what I'm creating.

I wondered if anyone has these three classes (or would be able to get them somehow)?
require 'socket' import the TCP framework
but you don't need it in RMXP..
you got the socket script (4 scripts) in the netplay
copy them to your system it will give you the TCPSocket class working
as the same as it does in RUBY
 
Ah, this thread seems recent enough..

Does anyone know if you have to credit anyone for this script? - particularly when releasing with another script?

I know the author says "Ruby", and ruby version 1.8.1, but that seems rather fake, as ruby uses socket.so, wich is C++, not just a bunch of Win32API calls in a ruby wrapper.

I've taken a look at socket.c, but that's just way too complex for me.

And are you even alowed to use/redistribute this script? As it's a mayor part of NP+
 
AmIMeYet":3urx1v6p said:
Ah, this thread seems recent enough..

Does anyone know if you have to credit anyone for this script? - particularly when releasing with another script?

I know the author says "Ruby", and ruby version 1.8.1, but that seems rather fake, as ruby uses socket.so, wich is C++, not just a bunch of Win32API calls in a ruby wrapper.

I've taken a look at socket.c, but that's just way too complex for me.

And are you even alowed to use/redistribute this script? As it's a mayor part of NP+
each C++ class is Compiled intro RUBY file,
get the compiled file or the diffrence..
 
nowayskill":2p0vaz1y said:
[...]
each C++ class is Compiled intro RUBY file,
get the compiled file or the diffrence..
Yeah, the compiled file is socket.so. The same one you would normally require in standard Ruby, but even though you can make the .rb require's work (see my signature), you still can't require .so's.

And what do you mean with "or the diffrence.."?
 
AmIMeYet":3ggdidrt said:
Ah, this thread seems recent enough..

Does anyone know if you have to credit anyone for this script? - particularly when releasing with another script?

I know the author says "Ruby", and ruby version 1.8.1, but that seems rather fake, as ruby uses socket.so, wich is C++, not just a bunch of Win32API calls in a ruby wrapper.

I've taken a look at socket.c, but that's just way too complex for me.

And are you even alowed to use/redistribute this script? As it's a mayor part of NP+
Well, whoever wrote it has chosen to set the author to "Ruby", and there is no license on it, meaning you are allowed to do anything you want with it. (if you really want to credit someone, then credit Ruby)

And just as a notice, I'm almost certain that whoever made it has never used RMXP/VX and have nothing to do with N+ (but I may be wrong)
 
S S Muu":1bd1h4ji said:
[...]
Well, whoever wrote it has chosen to set the author to "Ruby", and there is no license on it, meaning you are allowed to do anything you want with it. (if you really want to credit someone, then credit Ruby)
Ok, sounds good.

S S Muu":1bd1h4ji said:
And just as a notice, I'm almost certain that whoever made it has never used RMXP/VX and have nothing to do with N+ (but I may be wrong)
Well, I think this almost has to be made specifically for RM because RM is the only ruby-interpreting-program I know of not allowing require's.. and the fact that this is made specifically for windows.. .. ..

Thanks!
 
I just checked in the Ruby source code and confirmed what I thought, it's just a C++ file converted to ruby.
However it could still have been made for use in RMXP, but remember, RMXP isn't the only program using ruby, it might as well have been made for something else.
 
S S Muu":2ifl22e6 said:
I just checked in the Ruby source code and confirmed what I thought, it's just a C++ file converted to ruby.
However it could still have been made for use in RMXP, but remember, RMXP isn't the only program using ruby, it might as well have been made for something else.
So very true, but as far as I know RM is the only one that blocked require.. and searches brought up nothing.

Now, one more thing.. you say that it's a C++ file converted to ruby.. but why then is the content not visible?
I mean.. I know it's all C++ code.. but I don't think that it gets converted to plain ruby. Some sort of semi-language I presume.. (or just some sort of dll with special ruby handles)

.so files are all scrambled, while .rb is plain text. I don't think you could possibly retrieve any code from .so's. I mean, the C++ source is jibberish enough ;) .. .. And I think the fact that you can't even require them says enough.. it just doesn't know how.

All in all, I think the highest chance is that it was made specifically for RM... how dumb of them not to credit themselves ;)
 
AmIMeYet":1u0y5o73 said:
So very true, but as far as I know RM is the only one that blocked require.. and searches brought up nothing.
Actually, any program embedding ruby would disable require, otherwise the user would have to have Ruby installed on their computer.

AmIMeYet":1u0y5o73 said:
...but why then is the content not visible...
What do you mean by that?
The content is visible, if you look at the C++ source you'll see that all they do is call the very same Dll functions.
 
When creditting Netplay+ in the past GoldenAura3 was always creditted as the one who "found" the socket classes; so I'm pretty sure it wasn't made for Netplay originally.
 
S S Muu":39xg8b2l said:
[...]
Actually, any program embedding ruby would disable require, otherwise the user would have to have Ruby installed on their computer.
Really? I thought it would just import the code and then run it inside the embedded ruby interpreter... I thougt ruby really just did the same.. 'merge' 2 (loaded) .rb files.

S S Muu":39xg8b2l said:
[...]
What do you mean by that?
The content is visible, if you look at the C++ source you'll see that all they do is call the very same Dll functions.
All I see is them defining dll's and functions, but never really making code that can call anything. (looking at "\ext\socket\socket.c")

Commodore Whynot":39xg8b2l said:
When creditting Netplay+ in the past GoldenAura3 was always creditted as the one who "found" the socket classes; so I'm pretty sure it wasn't made for Netplay originally.
Ah, ok.. so I guess I'll just credit GoldenAura3 then.

Thanks!
 
AmIMeYet":1o0mmaj1 said:
All I see is them defining dll's and functions, but never really making code that can call anything. (looking at "\ext\socket\socket.c")
Not sure where you're looking, because I can clearly see it.
 
S S Muu":2u3vm0kb said:
AmIMeYet":2u3vm0kb said:
All I see is them defining dll's and functions, but never really making code that can call anything. (looking at "\ext\socket\socket.c")
Not sure where you're looking, because I can clearly see it.
:S What ruby version do you have? I have 1.8.6.

Can you post a line number/snippet of where you see a call? That is, if it's not too much of a hassle...
 

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