Much code, many rewrite

This commit is contained in:
2019-12-14 20:08:34 +01:00
parent 3bdd78b61c
commit 2166a30aa9
34 changed files with 852 additions and 58 deletions

View File

@@ -1,49 +1,78 @@
from importlib import reload
import socket
from handlers import serverPingHandler, mainHandler
import logging
import struct
from network.compression import uncompress
from handlers import serverQueryHandler, mainHandler
from helpers.byteFormater import readable_bytes
logger = logging.getLogger(__name__)
class Client:
BUFF_SIZE = 65535
HANDLERS = {
b"SAMP": serverPingHandler
b"SAMP": serverQueryHandler.handle
}
def __init__(self, server, addr):
def __init__(self, server: "Server", addr: "Address"):
self.server = server
self.ip_uint = struct.unpack(b"<I", bytes(int(x) for x in addr[0].split(".")))[0]
self.addr = addr
self.state = 0
self.__writebuffer = []
self.__writebuffer = bytearray()
def handle_data(self, data):
def handle_data(self, data: bytes):
found = False
for pattern, handler in self.HANDLERS.items():
for pattern, handle in self.HANDLERS.items(): # SAMP query
if data.startswith(pattern):
queue = handler.handle(self, data)
queue = handle(self, data)
if queue:
self.write_to_buffer(queue)
found = True
if not found:
queue = mainHandler.handle(self, data)
if queue:
# deobfuscate
try:
data: bytearray = uncompress(data)
logger.debug("[%s] -> %s" % (self.addr, readable_bytes(data)))
queue = mainHandler.handle(self, data)
except Exception as err:
logger.error(err)
finally:
if queue:
self.write_to_buffer(queue)
#print("?[{}] -> {} / {}".format(self.addr, data, data.hex()))
def write_to_buffer(self, data):
if type(data) == bytes:
def write_to_buffer(self, data: bytes):
if type(data) == int:
self.__writebuffer.append(data)
elif type(data) == list:
for item in data:
self.write_to_buffer(item)
else:
self.__writebuffer += data
def write_buffer_size(self):
def get_buffer_size(self) -> int:
return len(self.__writebuffer)
def write_socket(self):
if len(self.__writebuffer) > 0:
write_chunk = self.__writebuffer.pop(0)
print("[{}] <- {}".format(self.addr, write_chunk))
self.server.socket.sendto(write_chunk, self.addr)
if self.get_buffer_size() > 0:
#write_chunk = self.__writebuffer.pop(0)
#logger.debug("[%s] <- %s" % (self.addr, write_chunk))
logger.debug("[%s] <- %s" % (self.addr, readable_bytes(self.__writebuffer)))
self.server.socket.sendto(self.__writebuffer, self.addr)
self.__writebuffer.clear()
def send_immediate(self, data: bytes):
logger.debug("[%s] <- %s" % (self.addr, readable_bytes(data)))
self.server.socket.sendto(data, self.addr)
def restart():
reload(serverPingHandler)
reload(serverQueryHandler)
reload(mainHandler)
mainHandler.restart()

View File

@@ -1,2 +1,47 @@
import sys
import json
import logging
from random import randint
from network.enums import types as TYPE
# ---------------------------------------------------------------------------
# public
config = None
server = None
server = None
challenge_short = None
# ---------------------------------------------------------------------------
with open("config.json", "r") as f:
config = json.load(f)
# fix for logging level
default_logging_fallback = False
if type(config["logging"]["level"]) is not int:
try:
config["logging"]["level"] = getattr(logging, config["logging"]["level"])
except:
config["logging"]["level"] = logging.INFO
default_logging_fallback = True
# Setup logging settings
logging_handlers = [logging.StreamHandler(sys.stdout)]
if len(config["logging"]["filename"]):
logging_handlers.append(logging.FileHandler(config["logging"]["filename"]))
del config["logging"]["filename"]
logging.basicConfig(**config["logging"], handlers = logging_handlers)
logger = logging.getLogger(__name__)
logger.debug("glob.configured logger")
if default_logging_fallback:
logger.warning("Invalid logging value in config! Defaulting to logging level INFO.")
logger.info("Logging level: %d" % config["logging"]["level"])
# ---------------------------------------------
challenge_short = randint(0, TYPE.MAX_USHORT)
logger.debug("Client challenge set to: %s" % ("0x" if challenge_short & 0x1000 else "0x0") + hex(challenge_short)[2:])

View File

@@ -1,10 +1,13 @@
import socket
import select
import logging
from threading import Thread
from .client import Client
logger = logging.getLogger(__name__)
class Server(Thread):
BUFF_SIZE = 65535
@@ -36,18 +39,19 @@ class Server(Thread):
else:
try:
self.clients[addr] = Client(self, addr)
print("[Server] Accepted connection from {}:{}".format(addr[0], addr[1]))
logger.info("Accepted connection from %s:%s" % (addr[0], addr[1]))
self.clients[addr].handle_data(data)
except socket.error:
try:
self.socket.close()
except:
pass
print("[Server] Something went very wrong...")
exit()
logger.warn("Something went very wrong...")
#exit()
return
clients = [x for x in self.clients.values()
if x.write_buffer_size() > 0]
if x.get_buffer_size() > 0]
for client in clients:
client.write_socket()