Gabz

Online Ranking

Jul 20th, 2014
355
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 8.14 KB | None | 0 0
  1. #===============================================================================
  2. # Gab Heroku Online Ranking
  3. #-----------------------------------------------------------------------------
  4. # @author  : Gabriel "Gab!" Teles
  5. # @date    : 2014/07/19
  6. # @version : 1.0a
  7. #-----------------------------------------------------------------------------
  8. #
  9. # Permite criar um ranking online utilizando o Heroku para armazenamento e
  10. # processamento dos dados.
  11. #
  12. #-----------------------------------------------------------------------------
  13. #
  14. # Utilização:
  15. #
  16. # - OnlineRanking.sendScore(name, points)
  17. #   Envia para o servidor uma entrada de nome e pontuação. Pode ser utilizado
  18. #   em condicionais dos eventos, visto que retorna "true" quando sucesso e
  19. #   "false" em caso de erro. No modo de testes o erro será mostrado.
  20. #
  21. # - OnlineRanking.getRanking(n)
  22. #   Requere os "n" primeiros do ranking. Também pode ser utilizado em
  23. #   condicionais; o procedimento de sucesso/falho é idêntico ao do método
  24. #   anterior.
  25. #
  26. #   #---------------------------------------------------------------------#
  27. #   # ATENÇÃO: Os métodos abaixo só funcionarão corretamente após fazer o #
  28. #   # requerimento das pontuações do servidor através do método acima.    #
  29. #   #---------------------------------------------------------------------#
  30. #
  31. # - OnlineRanking.getName(n)
  32. #   Requere o nome do n-ésimo (começando do 0) colocado no ranking.
  33. #
  34. # - OnlineRanking.getScore(n)
  35. #   Requere a pontuação do n-ésimo (començando do 0) colocado no ranking.
  36. #
  37. # - OnlineRanking.getDate(n, format="%d/%m/%y %H:%M")
  38. #   Requere a data de entrada do n-ésimo (começando do 0) colocado no ranking.
  39. #   Não é necessário especificar o segundo argumento, apenas para o caso de
  40. #   querer alterar formato da data. O padrão é: dia/mês/ano hora:minuto.
  41. #   Para saber mais sobre formatação da data veja a referência do método
  42. #   Time#strftime na documentação do Ruby:
  43. #   http://www.ruby-doc.org/core-1.9.3/Time.html#method-i-strftime
  44. #
  45. #===============================================================================
  46.  
  47. module Gab
  48.   module OnlineRanking
  49. #===============================================================================
  50. # * CONFIGURAÇÃO
  51. #===============================================================================
  52.    
  53.     # IP do aplicativo no Heroku
  54.     HEROKU_IP  = "50.16.239.160"
  55.    
  56.     # URL do aplicativo no Heroku
  57.     HEROKU_URL = "glacial-inlet-1181.herokuapp.com"
  58.    
  59. #===============================================================================
  60. # * FIM DA CONFIGURAÇÃO
  61. #===============================================================================
  62.   end
  63. end
  64.  
  65. module Socket
  66.   Socket    = Win32API.new('ws2_32', 'socket',      'lll',  'l')
  67.   Connect   = Win32API.new('ws2_32', 'connect',     'ppl',  'l')
  68.   Close     = Win32API.new('ws2_32', 'closesocket', 'p',    'l')
  69.   Send      = Win32API.new('ws2_32', 'send',        'ppll', 'l')
  70.   Recv      = Win32API.new('ws2_32', 'recv',        'ppll', 'l')
  71.   Inet_addr = Win32API.new('ws2_32', 'inet_addr',   'p',    'l')
  72.   Htons     = Win32API.new('ws2_32', 'htons',       'l',    'l')
  73.   Shutdown  = Win32API.new('ws2_32', 'shutdown',    'pl',   'l')
  74.  
  75.   AF_INET     = 2
  76.   SOCK_STREAM = 1
  77.   IPPROTO_TCP = 6
  78.  
  79.   module_function
  80.  
  81.   def sockaddr_in(host, port)
  82.      sin_family = AF_INET
  83.      sin_port = Htons.(port)
  84.      in_addr = Inet_addr.(host)
  85.      sockaddr_in = [sin_family, sin_port, in_addr].pack('sSLx8')
  86.      return sockaddr_in
  87.   end
  88.  
  89.   def socket()
  90.     return Socket.(AF_INET, SOCK_STREAM, IPPROTO_TCP)
  91.   end
  92.  
  93.   def connect_sock(sock, sockaddr)
  94.      Connect.(sock, sockaddr, sockaddr.size)
  95.   end
  96.  
  97.   def connect(host = "127.0.0.1", port = 9999)
  98.      sockaddr = sockaddr_in(host, port)
  99.      sock = socket()
  100.      connect_sock(sock, sockaddr)
  101.      return sock
  102.   end
  103.  
  104.   def send(socket, data)
  105.      value = Send.(socket, data, data.length, 0)
  106.      if value == -1
  107.         shutdown(socket, 2)
  108.         return false
  109.      end
  110.      return true
  111.   end
  112.  
  113.   def recv(socket, len = 256)
  114.     buffer = [].pack('x'+len.to_s)
  115.     value = Recv.(socket, buffer, len, 0)
  116.     return buffer.gsub(/\x00/, "") if value != -1
  117.     return false
  118.   end
  119.    
  120.   def gets(socket, delimiter=$/)
  121.     line = ""
  122.     line << recv(socket, 1) until line[-1] == delimiter
  123.     return line
  124.   end
  125.  
  126.   def shutdown(socket, how)
  127.     Shutdown.(socket, how)
  128.   end
  129.  
  130.   def close(socket)
  131.     Close.(socket)
  132.   end
  133. end
  134.  
  135. module OnlineRanking
  136.  
  137.   # GABOA : GAB BULLSHIT OBFUSCATION ALGORITHMS
  138.  
  139.   ALGORITHMS = [
  140.     ->(data, compress) {
  141.       if compress
  142.         "A" + compress([
  143.           data[:points],
  144.           Time.now.to_i,
  145.           *data[:name].unpack("C*")
  146.         ].pack("DIC*")).reverse.strip
  147.       else
  148.         data = decompress(data.reverse).unpack("DIC*")
  149.        
  150.         points = data.shift
  151.         date   = data.shift
  152.         name   = data.pack("C*")
  153.        
  154.         [name, points, date]
  155.       end
  156.     },
  157.    
  158.     ->(data, compress) {
  159.       if compress
  160.         "B" + compress([
  161.           Time.now.to_i,
  162.           data[:points],
  163.           *data[:name].unpack("C*")
  164.         ].pack("IDC*").reverse).reverse.strip
  165.       else
  166.         data = decompress(data.reverse).reverse.unpack("IDC*")
  167.        
  168.         date   = data.shift
  169.         points = data.shift
  170.         name   = data.pack("C*")
  171.        
  172.         [name, points, date]
  173.       end
  174.     },
  175.    
  176.     ->(data, compress) {
  177.       if compress
  178.         "C" + compress([
  179.           Time.now.to_i,
  180.           data[:points],
  181.           *data[:name].unpack("C*").reverse
  182.         ].pack("IDC*")).reverse.strip
  183.       else
  184.         data = decompress(data.reverse).unpack("IDC*")
  185.        
  186.         date   = data.shift
  187.         points = data.shift
  188.         name   = data.reverse.pack("C*")
  189.        
  190.         [name, points, date]
  191.       end
  192.     }
  193.   ]
  194.  
  195.   module_function
  196.  
  197.   def decompress(string)
  198.     stringIO = Zlib::Inflate.inflate(string.unpack('m*').first)
  199.     object = Marshal.load(stringIO)
  200.     return object
  201.   end
  202.  
  203.   def compress(object)
  204.     return [Zlib::Deflate.deflate(Marshal.dump(object))].pack('m*')
  205.   end
  206.  
  207.   def getPath(path)
  208.     host = Socket.connect(Gab::OnlineRanking::HEROKU_IP, 80)
  209.    
  210.     return compress("Não foi possível se conectar ao servidor.") if host.zero?
  211.    
  212.     # Request
  213.     Socket.send(host, "GET #{path} HTTP/1.1\r\n")
  214.     Socket.send(host, "Host: #{Gab::OnlineRanking::HEROKU_URL}\r\n")
  215.     Socket.send(host, "Accept: text/html\r\n")
  216.     Socket.send(host, "\r\n")
  217.  
  218.     # Response
  219.     response = Socket.gets(host).rstrip
  220.     if response == "HTTP/1.1 200 OK"
  221.       # Header
  222.       header = {}
  223.       until (line = Socket.gets(host).rstrip).empty?
  224.         definition = line.split(": ")
  225.         header[definition.shift] = definition.join
  226.         break if header.has_key?("Content-Length")
  227.       end
  228.      
  229.       # Body
  230.       return Socket.recv(host, header["Content-Length"].to_i)
  231.     else
  232.       return compress("Ocorreu um erro ao receber o requerimento do servidor.")
  233.     end
  234.   end
  235.  
  236.   def getRanking(num = 5)
  237.     @ranking ||= []
  238.    
  239.     response = decompress(getPath("/get/#{num}"))
  240.     if response.is_a?(Array)
  241.       @ranking = response
  242.       return true
  243.     else
  244.       msgbox(response) if $TEST
  245.       return false
  246.     end
  247.   end
  248.  
  249.   def sendScore(name, points)
  250.     hash = ALGORITHMS.sample[{name: name, points: points}, true]
  251.     response = decompress(getPath("/set/#{hash}"))
  252.    
  253.     if response.is_a?(String)
  254.       msgbox(response) if $TEST
  255.       return false
  256.     else
  257.       return true
  258.     end
  259.   end
  260.  
  261.   def getInfo(index, info)
  262.     default, i = case info
  263.     when :pos   then [ 0, 0]
  264.     when :name  then ["", 1]
  265.     when :score then [ 0, 2]
  266.     when :date  then [ 0, 3]
  267.     end
  268.    
  269.     return @ranking.size >= index ? default : @ranking[index][i]
  270.   end
  271.  
  272.   def getName(index)
  273.     return getInfo(index, :name)
  274.   end
  275.  
  276.   def getScore(index)
  277.     return getInfo(index, :score)
  278.   end
  279.  
  280.   def getDate(index, format="%d/%m/%y %H:%M")
  281.     date = Time.at(getInfo(index, :date))
  282.     return date.strftime(format)
  283.   end
  284. end
Advertisement
Add Comment
Please, Sign In to add comment