#!/usr/bin/env python3 import socket import threading import WorldManager as wm from JSONStreamParser import JSONStreamParser import json SOCKETSIZE = 4096 class ConnectionWorker(threading.Thread): def __init__(self, clientsocket: 'socket', address, world: wm.WorldManager): self.clientsocket = clientsocket self.address = address self.connectionEnabled = False self.world = world self.stream_parser = JSONStreamParser() super(ConnectionWorker, self).__init__() def run(self): self._connect() self._work() self._close() def _connect(self): if not self._authenticate(): print("could not authenticate from " + str(self.address)) self.clientsocket.close() return self.connectionEnabled = True # dummy action: print("successfully established connection to " + str(self.address)) def _sendChunk(self, chunk_x: int, chunk_y: int, chunk_z: int) -> None: # TODO: world generation should be done by another thread, # just for testing purposes!! if not self.world.isChunkKnown(chunk_x, chunk_y, chunk_z): self.world.createEmptyChunk(chunk_x, chunk_y, chunk_z) self.world.applyPerlinToChunk(chunk_x, chunk_y, chunk_z) json = self.world.getChunkAsJson(chunk_x, chunk_y, chunk_z) self.clientsocket.sendall(json.encode()) def _sendMessage(self, message: str) -> None: msg_object = {} msg_object['datatype'] = 'message' msg_object['data'] = message self.clientsocket.sendall(json.dumps(msg_object).encode()) def _processData(self, data: dict): # check type: print("processing\n:", data) if 'datatype' not in data: self._sendMessage('bad data') raise Exception("bad data received") if data['datatype'] == 'request_chunk': chunk_x = int(data['position'][0]) chunk_y = int(data['position'][1]) chunk_z = int(data['position'][2]) self._sendChunk(chunk_x, chunk_y, chunk_z) else: self._sendMessage('unknown request') def _work(self): self.data = self.clientsocket.recv(SOCKETSIZE) while len(self.data) > 0: self.stream_parser.appendRawData(self.data) while not self.stream_parser.isQueueEmpty(): parsed_data = self.stream_parser.popAsDictionary() self._processData(parsed_data) self.data = self.clientsocket.recv(SOCKETSIZE) def _authenticate(self) -> bool: # TODO print("looking busy like i would check permissions of new ", "client... beep... boop... beep... ") print("new client accepted! [from ", str(self.address), " ]") return True def _close(self): print("close connection to ", str(self.address)) self.clientsocket.close()