VoxelServer/ServerCore/ConnectionWorker.py

97 lines
3.0 KiB
Python

#!/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()