Advertisement
Guest User

WinSock for RPG Maker VX Ace

a guest
Sep 7th, 2014
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 18.79 KB | None | 0 0
  1. #==============================================================================
  2. # ** Module Win32 - Handles numerical based data.
  3. #------------------------------------------------------------------------------
  4. # Author    Ruby
  5. # Version   1.8.1
  6. #==============================================================================
  7.  
  8. module Win32
  9.  
  10.   #----------------------------------------------------------------------------
  11.   # ● Retrieves data from a pointer.
  12.   #----------------------------------------------------------------------------
  13.   def copymem(len)
  14.     buf = "\0" * len
  15.     Win32API.new('kernel32', 'RtlMoveMemory', 'ppl', '').call(buf, self, len)
  16.     buf
  17.   end
  18.  
  19. end
  20.  
  21. # Extends the numeric class.
  22. class Numeric
  23.   include Win32
  24. end
  25.  
  26. # Extends the string class.
  27. class String
  28.   include Win32
  29. end
  30.  
  31. #==============================================================================
  32. # ** Module Winsock - Maps out the functions held in the Winsock DLL.
  33. #------------------------------------------------------------------------------
  34. # Author    Ruby
  35. # Version   1.8.1
  36. #==============================================================================
  37.  
  38. module Winsock
  39.  
  40.   DLL = 'ws2_32'
  41.  
  42.   #----------------------------------------------------------------------------
  43.   # * Accept Connection
  44.   #----------------------------------------------------------------------------
  45.   def self.accept(*args)
  46.     Win32API.new(DLL, 'accept', 'ppl', 'l').call(*args)
  47.   end
  48.   #----------------------------------------------------------------------------
  49.   # * Bind
  50.   #----------------------------------------------------------------------------
  51.   def self.bind(*args)
  52.     Win32API.new(DLL, 'bind', 'ppl', 'l').call(*args)
  53.   end
  54.   #----------------------------------------------------------------------------
  55.   # * Close Socket
  56.   #----------------------------------------------------------------------------
  57.   def self.closesocket(*args)
  58.     Win32API.new(DLL, 'closesocket', 'p', 'l').call(*args)
  59.   end  
  60.   #----------------------------------------------------------------------------
  61.   # * Connect
  62.   #----------------------------------------------------------------------------
  63.   def self.connect(*args)
  64.     Win32API.new(DLL, 'connect', 'ppl', 'l').call(*args)
  65.   end    
  66.   #----------------------------------------------------------------------------
  67.   # * Get host (Using Adress)
  68.   #----------------------------------------------------------------------------
  69.   def self.gethostbyaddr(*args)
  70.     Win32API.new(DLL, 'gethostbyaddr', 'pll', 'l').call(*args)
  71.   end
  72.   #----------------------------------------------------------------------------
  73.   # * Get host (Using Name)
  74.   #----------------------------------------------------------------------------
  75.   def self.gethostbyname(*args)
  76.     Win32API.new(DLL, 'gethostbyname', 'p', 'l').call(*args)
  77.   end
  78.   #----------------------------------------------------------------------------
  79.   # * Get host's Name
  80.   #----------------------------------------------------------------------------
  81.   def self.gethostname(*args)
  82.     Win32API.new(DLL, 'gethostname', 'pl', '').call(*args)
  83.   end
  84.   #----------------------------------------------------------------------------
  85.   # * Get Server (Using Name)
  86.   #----------------------------------------------------------------------------
  87.   def self.getservbyname(*args)
  88.     Win32API.new(DLL, 'getservbyname', 'pp', 'p').call(*args)
  89.   end
  90.   #----------------------------------------------------------------------------
  91.   # * HT OnL
  92.   #----------------------------------------------------------------------------
  93.   def self.htonl(*args)
  94.     Win32API.new(DLL, 'htonl', 'l', 'l').call(*args)
  95.   end
  96.   #----------------------------------------------------------------------------
  97.   # * HT OnS
  98.   #----------------------------------------------------------------------------
  99.   def self.htons(*args)
  100.     Win32API.new(DLL, 'htons', 'l', 'l').call(*args)
  101.   end
  102.   #----------------------------------------------------------------------------
  103.   # * Inet Adress
  104.   #----------------------------------------------------------------------------
  105.   def self.inet_addr(*args)
  106.     Win32API.new(DLL, 'inet_addr', 'p', 'l').call(*args)
  107.   end
  108.   #----------------------------------------------------------------------------
  109.   # * Inet NtOA
  110.   #----------------------------------------------------------------------------
  111.   def self.inet_ntoa(*args)
  112.     Win32API.new(DLL, 'inet_ntoa', 'l', 'p').call(*args)
  113.   end  
  114.   #----------------------------------------------------------------------------
  115.   # * Listen
  116.   #----------------------------------------------------------------------------
  117.   def self.listen(*args)
  118.     Win32API.new(DLL, 'listen', 'pl', 'l').call(*args)
  119.   end
  120.   #----------------------------------------------------------------------------
  121.   # * Recieve
  122.   #----------------------------------------------------------------------------
  123.   def self.recv(*args)
  124.     Win32API.new(DLL, 'recv', 'ppll', 'l').call(*args)
  125.   end
  126.   #----------------------------------------------------------------------------
  127.   # * Select
  128.   #----------------------------------------------------------------------------
  129.   def self.select(*args)
  130.     Win32API.new(DLL, 'select', 'lpppp', 'l').call(*args)
  131.   end
  132.   #----------------------------------------------------------------------------
  133.   # * Send
  134.   #----------------------------------------------------------------------------
  135.   def self.send(*args)
  136.     Win32API.new(DLL, 'send', 'ppll', 'l').call(*args)
  137.   end
  138.   #----------------------------------------------------------------------------
  139.   # * Set Socket Options
  140.   #----------------------------------------------------------------------------
  141.   def self.setsockopt(*args)
  142.     Win32API.new(DLL, 'setsockopt', 'pllpl', 'l').call(*args)
  143.   end  
  144.   #----------------------------------------------------------------------------
  145.   # * Shutdown
  146.   #----------------------------------------------------------------------------
  147.   def self.shutdown(*args)
  148.     Win32API.new(DLL, 'shutdown', 'pl', 'l').call(*args)
  149.   end
  150.   #----------------------------------------------------------------------------
  151.   # * Socket
  152.   #----------------------------------------------------------------------------
  153.   def self.socket(*args)
  154.     Win32API.new(DLL, 'socket', 'lll', 'l').call(*args)  
  155.   end
  156.   #----------------------------------------------------------------------------
  157.   # * Get Last Error
  158.   #----------------------------------------------------------------------------
  159.   def self.WSAGetLastError(*args)
  160.     Win32API.new(DLL, 'WSAGetLastError', '', 'l').call(*args)
  161.   end
  162.  
  163.   def self.ioctlsocket(*args)
  164.       Win32API.new(DLL, 'ioctlsocket','llp', 'l').call(*args)
  165.   end
  166.  
  167. end
  168.  
  169. #==============================================================================
  170. # ** Socket - Creates and manages sockets.
  171. #------------------------------------------------------------------------------
  172. # Author    Ruby
  173. # Version   1.8.1
  174. #==============================================================================
  175.  
  176. class Socket
  177.  
  178.   #----------------------------------------------------------------------------
  179.   # ● Constants
  180.   #----------------------------------------------------------------------------
  181.   AF_UNSPEC                 = 0  
  182.   AF_UNIX                   = 1
  183.   AF_INET                   = 2
  184.   AF_IPX                    = 6
  185.   AF_APPLETALK              = 16
  186.  
  187.   PF_UNSPEC                 = 0  
  188.   PF_UNIX                   = 1
  189.   PF_INET                   = 2
  190.   PF_IPX                    = 6
  191.   PF_APPLETALK              = 16
  192.  
  193.   SOCK_STREAM               = 1
  194.   SOCK_DGRAM                = 2
  195.   SOCK_RAW                  = 3
  196.   SOCK_RDM                  = 4
  197.   SOCK_SEQPACKET            = 5
  198.  
  199.   IPPROTO_IP                = 0
  200.   IPPROTO_ICMP              = 1
  201.   IPPROTO_IGMP              = 2
  202.   IPPROTO_GGP               = 3
  203.   IPPROTO_TCP               = 6
  204.   IPPROTO_PUP               = 12
  205.   IPPROTO_UDP               = 17
  206.   IPPROTO_IDP               = 22
  207.   IPPROTO_ND                = 77
  208.   IPPROTO_RAW               = 255
  209.   IPPROTO_MAX               = 256
  210.  
  211.   SOL_SOCKET                = 65535
  212.  
  213.   SO_DEBUG                  = 1
  214.   SO_REUSEADDR              = 4
  215.   SO_KEEPALIVE              = 8
  216.   SO_DONTROUTE              = 16
  217.   SO_BROADCAST              = 32
  218.   SO_LINGER                 = 128
  219.   SO_OOBINLINE              = 256
  220.   SO_RCVLOWAT               = 4100
  221.   SO_SNDTIMEO               = 4101
  222.   SO_RCVTIMEO               = 4102
  223.   SO_ERROR                  = 4103
  224.   SO_TYPE                   = 4104
  225.   SO_SNDBUF                 = 4097
  226.   SO_RCVBUF                 = 4098
  227.   SO_SNDLOWAT               = 4099
  228.  
  229.   TCP_NODELAY               = 1
  230.  
  231.   MSG_OOB                   = 1
  232.   MSG_PEEK                  = 2
  233.   MSG_DONTROUTE             = 4
  234.  
  235.   IP_OPTIONS                = 1
  236.   IP_DEFAULT_MULTICAST_LOOP = 1
  237.   IP_DEFAULT_MULTICAST_TTL  = 1
  238.   IP_MULTICAST_IF           = 2
  239.   IP_MULTICAST_TTL          = 3
  240.   IP_MULTICAST_LOOP         = 4
  241.   IP_ADD_MEMBERSHIP         = 5
  242.   IP_DROP_MEMBERSHIP        = 6
  243.   IP_TTL                    = 7
  244.   IP_TOS                    = 8
  245.   IP_MAX_MEMBERSHIPS        = 20
  246.  
  247.   EAI_ADDRFAMILY            = 1
  248.   EAI_AGAIN                 = 2
  249.   EAI_BADFLAGS              = 3
  250.   EAI_FAIL                  = 4
  251.   EAI_FAMILY                = 5
  252.   EAI_MEMORY                = 6
  253.   EAI_NODATA                = 7
  254.   EAI_NONAME                = 8
  255.   EAI_SERVICE               = 9
  256.   EAI_SOCKTYPE              = 10
  257.   EAI_SYSTEM                = 11
  258.   EAI_BADHINTS              = 12
  259.   EAI_PROTOCOL              = 13
  260.   EAI_MAX                   = 14
  261.  
  262.   AI_PASSIVE                = 1
  263.   AI_CANONNAME              = 2
  264.   AI_NUMERICHOST            = 4
  265.   AI_MASK                   = 7
  266.   AI_ALL                    = 256
  267.   AI_V4MAPPED_CFG           = 512
  268.   AI_ADDRCONFIG             = 1024
  269.   AI_DEFAULT                = 1536
  270.   AI_V4MAPPED               = 2048
  271.  
  272.   #----------------------------------------------------------------------------
  273.   # ● Returns the associated IP address for the given hostname.
  274.   #----------------------------------------------------------------------------  
  275.   def self.getaddress(host)
  276.     gethostbyname(host)[3].unpack('C4').join('.')
  277.   end
  278.   #----------------------------------------------------------------------------
  279.   # ● Returns the associated IP address for the given hostname.
  280.   #----------------------------------------------------------------------------  
  281.   def self.getservice(serv)
  282.     case serv
  283.     when Numeric
  284.       return serv
  285.     when String
  286.       return getservbyname(serv)
  287.     else
  288.       raise 'Please us an interger or string for services.'
  289.     end
  290.   end
  291.   #----------------------------------------------------------------------------
  292.   # ● Returns information about the given hostname.
  293.   #----------------------------------------------------------------------------
  294.   def self.gethostbyname(name)
  295.     raise SocketError::ENOASSOCHOST if (ptr = Winsock.gethostbyname(name)) == 0
  296.     host = ptr.copymem(16).unpack('iissi')
  297.     [host[0].copymem(64), [], host[2], host[4].copymem(4).unpack('l')[0].copymem(4)]
  298.   end
  299.   #----------------------------------------------------------------------------
  300.   # ● Returns the user's hostname.
  301.   #----------------------------------------------------------------------------  
  302.   def self.gethostname
  303.     buf = "\0" * 256
  304.     Winsock.gethostname(buf, 256)
  305.     buf.strip
  306.   end
  307.   #----------------------------------------------------------------------------
  308.   # ● Returns information about the given service.
  309.   #----------------------------------------------------------------------------
  310.   def self.getservbyname(name)
  311.     case name
  312.     when /echo/i
  313.       return 7
  314.     when /daytime/i
  315.       return 13
  316.     when /ftp/i
  317.       return 21
  318.     when /telnet/i
  319.       return 23
  320.     when /smtp/i
  321.       return 25
  322.     when /time/i
  323.       return 37
  324.     when /http/i
  325.       return 80
  326.     when /pop/i
  327.       return 110
  328.     else
  329.       raise 'Service not recognized.'
  330.     end
  331.   end
  332.   #----------------------------------------------------------------------------
  333.   # ● Creates an INET-sockaddr struct.
  334.   #----------------------------------------------------------------------------  
  335.   def self.sockaddr_in(port, host)
  336.     begin
  337.       [AF_INET, getservice(port)].pack('sn') + gethostbyname(host)[3] + [].pack('x8')
  338.     rescue Exception => e
  339.       puts e.to_s
  340.       puts e.backtrace
  341.     end
  342.   end
  343.   #----------------------------------------------------------------------------
  344.   # ● Creates a new socket and connects it to the given host and port.
  345.   #----------------------------------------------------------------------------  
  346.   def self.open(*args)
  347.     socket = new(*args)
  348.     if block_given?
  349.       begin
  350.         yield socket
  351.       ensure
  352.         socket.close
  353.       end
  354.     end
  355.     nil
  356.   end
  357.   #----------------------------------------------------------------------------
  358.   # ● Creates a new socket.
  359.   #----------------------------------------------------------------------------  
  360.   def initialize(domain, type, protocol)
  361.     SocketError.check if (@fd = Winsock.socket(domain, type, protocol)) == -1
  362.     Winsock.ioctlsocket(@fd, 2147772030, "\1\0\0\0\0\0\0\0");
  363.     @fd
  364.   end
  365.   #----------------------------------------------------------------------------
  366.   # ● Accepts incoming connections.
  367.   #----------------------------------------------------------------------------  
  368.   def accept(flags = 0)
  369.     buf = "\0" * 16
  370.     SocketError.check if Winsock.accept(@fd, buf, flags) == -1
  371.     buf
  372.   end
  373.   #----------------------------------------------------------------------------
  374.   # ● Binds a socket to the given sockaddr.
  375.   #----------------------------------------------------------------------------  
  376.   def bind(sockaddr)
  377.     SocketError.check if (ret = Winsock.bind(@fd, sockaddr, sockaddr.size)) == -1
  378.     ret
  379.   end
  380.   #----------------------------------------------------------------------------
  381.   # ● Closes a socket.
  382.   #----------------------------------------------------------------------------  
  383.   def close
  384.     SocketError.check if (ret = Winsock.closesocket(@fd)) == -1
  385.     ret
  386.   end
  387.   #----------------------------------------------------------------------------
  388.   # ● Connects a socket to the given sockaddr.
  389.   #----------------------------------------------------------------------------  
  390.   def connect(sockaddr)
  391.     SocketError.check if (ret = Winsock.connect(@fd, sockaddr, sockaddr.size)) == -1
  392.     while not self.connected?
  393.         Fiber.yield
  394.       end
  395.     puts "Connected!"
  396.     ret
  397.   end
  398.   #----------------------------------------------------------------------------
  399.   # ● Listens for incoming connections.
  400.   #----------------------------------------------------------------------------  
  401.   def listen(backlog)
  402.     SocketError.check if (ret = Winsock.listen(@fd, backlog)) == -1
  403.     ret
  404.   end
  405.   #----------------------------------------------------------------------------
  406.   # ● Checks waiting data's status.
  407.   #----------------------------------------------------------------------------  
  408.   def select(timeout)
  409.     SocketError.check if (ret = Winsock.select(1, [1, @fd].pack('ll'), 0, 0, [timeout, timeout * 1000000].pack('ll'))) == -1
  410.     ret
  411.   end
  412.  
  413.   def select_write(timeout)
  414.     SocketError.check if (ret = Winsock.select(1, 0, [1, @fd].pack('ll'), 0, [timeout, timeout * 1000000].pack('ll'))) == -1
  415.     ret
  416.   end
  417.  
  418.   def connected?
  419.     not select_write(0) == 0
  420.   end
  421.  
  422.   #----------------------------------------------------------------------------
  423.   # ● Checks if data is waiting.
  424.   #----------------------------------------------------------------------------  
  425.   def ready?
  426.     not select(0) == 0
  427.   end  
  428.   #----------------------------------------------------------------------------
  429.   # ● Reads data from socket.
  430.   #----------------------------------------------------------------------------  
  431.   def read(len)
  432.     buf = "\0" * len
  433.     Win32API.new('msvcrt', '_read', 'lpl', 'l').call(@fd, buf, len)
  434.     buf
  435.   end
  436.   #----------------------------------------------------------------------------
  437.   # ● Returns recieved data.
  438.   #----------------------------------------------------------------------------  
  439.   def recv(len, flags = 0)
  440.     buf = "\0" * len
  441.     SocketError.check if Winsock.recv(@fd, buf, buf.size, flags) == -1
  442.     buf
  443.   end
  444.   #----------------------------------------------------------------------------
  445.   # ● Sends data to a host.
  446.   #----------------------------------------------------------------------------  
  447.   def send(data, flags = 0)
  448.     SocketError.check if (ret = Winsock.send(@fd, data, data.size, flags)) == -1
  449.     ret
  450.   end
  451.   #----------------------------------------------------------------------------
  452.   # ● Writes data to socket.
  453.   #----------------------------------------------------------------------------  
  454.   def write(data)
  455.     Win32API.new('msvcrt', '_write', 'lpl', 'l').call(@fd, data, 1)
  456.   end
  457.  
  458. end
  459.  
  460. #==============================================================================
  461. # ** TCPSocket - Creates and manages TCP sockets.
  462. #------------------------------------------------------------------------------
  463. # Author    Ruby
  464. # Version   1.8.1
  465. #==============================================================================
  466.  
  467. class TCPSocket < Socket
  468.  
  469.   #----------------------------------------------------------------------------
  470.   # ● Creates a new socket and connects it to the given host and port.
  471.   #----------------------------------------------------------------------------  
  472.   def self.open(*args)
  473.     socket = new(*args)
  474.     if block_given?
  475.       begin
  476.         yield socket
  477.       ensure
  478.         socket.close
  479.       end
  480.     end
  481.     socket
  482.   end
  483.   #----------------------------------------------------------------------------
  484.   # ● Creates a new socket and connects it to the given host and port.
  485.   #----------------------------------------------------------------------------  
  486.   def initialize(host, port)
  487.     super(AF_INET, SOCK_STREAM, IPPROTO_TCP)
  488.     connect(Socket.sockaddr_in(port, host))
  489.   end
  490.  
  491. end
  492.  
  493. #==============================================================================
  494. # ** SocketError
  495. #------------------------------------------------------------------------------
  496. # Default exception class for sockets.
  497. #==============================================================================
  498.  
  499. class SocketError < StandardError
  500.  
  501.   ENOASSOCHOST = 'getaddrinfo: no address associated with hostname.'
  502.  
  503.     def self.check
  504.       errno = Winsock.WSAGetLastError
  505.       return if errno == 10035
  506.        
  507.        
  508.       constName = Errno.constants.detect {|c| Errno.const_get(c).new.errno == errno }
  509.       if constName
  510.         raise Errno.const_get(constName)
  511.       else
  512.         raise "Unknown network error code: #{errno}"
  513.       end
  514.   end
  515.  
  516. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement