Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #==============================================================================
- # ** 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
- 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)
- SocketError.check if (ret = Winsock.connect(@fd, sockaddr, sockaddr.size)) == -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
- #----------------------------------------------------------------------------
- # ● 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.'
- # fixed by: https://lthzelda.wordpress.com/2010/04/28/rm-4-tcp-sockets-in-rpg-maker-vx/
- def self.check
- errno = Winsock.WSAGetLastError
- const = Errno.constants.detect {|c| Errno.const_get(c).new.errno == errno }
- if const
- raise Errno.const_get(const)
- else
- raise "Unknown network error code: #{errno}"
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement