Advertisement
MrBukkitHackYT

Untitled

Jan 6th, 2020
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.64 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3.  
  4. #    The current settings assume your server is running on port 7777
  5. #
  6. #    iptables -t nat -A PREROUTING -p udp --dport 7777 -s 0.0.0.0 -m string --algo bm --string 'SAMP' -j REDIRECT --to-port 7777
  7. #    iptables -t nat -A PREROUTING -p udp --dport 7777 -m string --algo bm --string 'SAMP' -j REDIRECT --to-port 7778
  8. #    iptables -I INPUT -p udp --dport 7778 -m string --algo bm --string 'SAMP' -m hashlimit ! --hashlimit-upto 10/sec --hashlimit-burst 15/sec --hashlimit-mode srcip --hashlimit-name query -j DROP
  9. #    
  10. #
  11. #    make sure ports above match ports below
  12. #    
  13. #    Basicly all query packets get directed to this script, and sync packets are left untouched
  14. #
  15.  
  16.  
  17. import array
  18. import socket
  19. import socketserver
  20. import threading
  21. import time
  22. import binascii
  23. ####################### MUST BE CONFIGURED ##########################
  24. SERVER_PORT = 7778 #Assuming your samp server runs on this port
  25. PROXY_PORT = 7777 #Assuming no other servers are running on this one, as it will be taken by the code.
  26. SAMP_SERVER_ADDRESS = "38.107.214.212" #Public ip set this to the ip you using in bind in your server.cfg
  27. #####################################################################
  28.  
  29. SAMP_SERVER_LOCALHOST = "0.0.0.0" #Edit this if you run this on a different server than the samp server
  30. SAMP_SERVER_ADDRESS_BYTES = socket.inet_aton(SAMP_SERVER_ADDRESS)
  31.  
  32. info = " "
  33. rules = " "
  34. clients = " "
  35. detail = " "
  36. isonline = False
  37.  
  38.  
  39. iplogpos = 0
  40. iplog = []
  41.  
  42.  
  43. class UDPServer:
  44.   def __init__(self, bind_address, target_address, internal_host = "0.0.0.0", timeout = 0.3): #ulimit?
  45.     self.target_address = target_address
  46.     self.timeout = timeout
  47.  
  48.     self.server = socketserver.UDPServer(bind_address, create_handler(self.handle_external_packet))
  49.  
  50.   def querythread(self):
  51.  
  52.     global info
  53.     global rules
  54.     global clients
  55.     global detail
  56.     global isonline
  57.  
  58.     socket.setdefaulttimeout(1)
  59.     self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  60.     while True:
  61.      
  62.       if self.ping():
  63.  
  64.         packet = self.assemblePacket("i")
  65.         self.sock.sendto(packet, (SAMP_SERVER_ADDRESS, SERVER_PORT))
  66.         info = self.sock.recv(1024)[11:]
  67.  
  68.         packet = self.assemblePacket("r")
  69.         self.sock.sendto(packet, (SAMP_SERVER_ADDRESS, SERVER_PORT))
  70.         rules = self.sock.recv(1024)[11:]
  71.  
  72.         packet = self.assemblePacket("d")
  73.         self.sock.sendto(packet, (SAMP_SERVER_ADDRESS, SERVER_PORT))
  74.         detail = self.sock.recv(1024)[11:]
  75.  
  76.         packet = self.assemblePacket("c")
  77.         self.sock.sendto(packet, (SAMP_SERVER_ADDRESS, SERVER_PORT))
  78.         clients = self.sock.recv(1024)[11:]
  79.  
  80.         isonline = True
  81.  
  82.         time.sleep(2)
  83.       else:
  84.         isonline = False
  85.         print("Server unable to be reached...")
  86.  
  87.   def ping(self):
  88.  
  89.     pack = self.assemblePacket("p0101")
  90.     self.sock.sendto(pack, (SAMP_SERVER_ADDRESS, SERVER_PORT))
  91.     try:
  92.       reply = self.sock.recv(1024)[10:]
  93.       if reply == b'p0101':
  94.         return True
  95.       else:
  96.         return False
  97.     except socket.timeout:
  98.       return False
  99.      
  100.   def assemblePacket(self, type):
  101.     PUBLIC_PORT_BYTES = SERVER_PORT.to_bytes(2, byteorder='little')
  102.     packet = b'SAMP'
  103.     packet += SAMP_SERVER_ADDRESS_BYTES
  104.     packet += PUBLIC_PORT_BYTES
  105.     packet += bytes(type, 'utf-8')
  106.     return packet
  107.  
  108.  
  109.  
  110.   def start(self):
  111.     q = threading.Thread(target=self.querythread)
  112.     q.daemon = True
  113.     q.start()
  114.     self.server.serve_forever()
  115.     self.server.socket.settimeout(self.timeout)
  116.  
  117.  
  118.   def stop(self):
  119.     self.server.shutdown()
  120.  
  121.   def handle_external_packet(self, handler):
  122.     (payload, socket) = handler.request
  123.     client_address = handler.client_address
  124.     if(isonline == False):
  125.       return
  126.     if payload[4:8] != SAMP_SERVER_ADDRESS_BYTES: #Payload with IP bytes are not matching your public IP
  127.       return False
  128.    
  129.     if payload[10] not in b'pirdc': #opcodes defined here: https://wiki.sa-mp.com/wiki/Query/Request#Opcodes
  130.       return False
  131.  
  132.     if payload[10] in b'p': #Ping packets are just sent back to the client
  133.       client_address = handler.client_address
  134.       self.server.socket.sendto(payload, client_address)
  135.       return True
  136.  
  137.     elif payload[10] in b'i':
  138.  
  139.       client_address = handler.client_address
  140.       argument = payload+info
  141.       self.server.socket.sendto(argument, client_address)
  142.       return True
  143.      
  144.  
  145.     elif payload[10] in b'r':
  146.       client_address = handler.client_address
  147.       argument = payload+rules
  148.       self.server.socket.sendto(argument, client_address)
  149.       #print(binascii.hexlify(payload+rules))
  150.       return True
  151.      
  152.  
  153.     elif payload[10] in b'd':
  154.       client_address = handler.client_address
  155.       argument = payload+detail
  156.       self.server.socket.sendto(argument, client_address)
  157.       return True
  158.      
  159.  
  160.     elif payload[10] in b'c':
  161.       client_address = handler.client_address
  162.       argument = payload+clients
  163.       self.server.socket.sendto(argument, client_address)
  164.       #thebytes=payload+clients
  165.       #print(len(payload+clients))
  166.       return True
  167.     return
  168.  
  169. def create_handler(func):
  170.   class Handler(socketserver.BaseRequestHandler):
  171.     def handle(self):
  172.       try:
  173.         func(self)
  174.       except Exception as e:
  175.         print("An error occurred: %s" % (e,))
  176.       func(self)
  177.   return Handler
  178.  
  179. if __name__ == '__main__':
  180.   print("Listening on port", PROXY_PORT, "for server",SAMP_SERVER_ADDRESS,"on port",SERVER_PORT)
  181.   bind_address = (SAMP_SERVER_ADDRESS, PROXY_PORT)
  182.   target_address = ("0.0.0.0", SERVER_PORT)
  183.   proxy = UDPServer(bind_address, target_address)
  184.   proxy.start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement