From 15cce52aeac578835da5c15c61706138e704cecc Mon Sep 17 00:00:00 2001 From: steev Date: Sun, 14 Jan 2024 17:55:35 +0100 Subject: [PATCH 1/2] fixed issue crashing connections and added system logger --- .vscode/settings.json | 5 + Game Server/Classes/System/GameManager.py | 6 +- Game Server/Classes/System/Logger.py | 18 ++++ .../Classes/System/Network/EventHandler.py | 13 +-- .../Classes/System/Network/NetworkManger.py | 92 ++++++------------ .../__pycache__/EventHandler.cpython-311.pyc | Bin 2256 -> 2223 bytes .../__pycache__/NetworkManger.cpython-311.pyc | Bin 7483 -> 9809 bytes Game Server/Classes/System/Server.py | 16 ++- .../__pycache__/GameManager.cpython-311.pyc | Bin 3826 -> 4017 bytes .../System/__pycache__/Logger.cpython-311.pyc | Bin 0 -> 1309 bytes .../System/__pycache__/Server.cpython-311.pyc | Bin 1900 -> 2529 bytes Game Server/index.py | 17 +++- Game_Client/Classes/Game/Events/PlaceCard.py | 5 +- .../__pycache__/PlaceCard.cpython-311.pyc | Bin 1879 -> 1955 bytes Game_Client/Classes/System/App.py | 2 +- .../System/__pycache__/App.cpython-311.pyc | Bin 9767 -> 9679 bytes 16 files changed, 93 insertions(+), 81 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 Game Server/Classes/System/Logger.py create mode 100644 Game Server/Classes/System/__pycache__/Logger.cpython-311.pyc diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..dbb72d1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.ignoreWords": [ + "posx" + ] +} \ No newline at end of file diff --git a/Game Server/Classes/System/GameManager.py b/Game Server/Classes/System/GameManager.py index db684b7..36e2bf8 100644 --- a/Game Server/Classes/System/GameManager.py +++ b/Game Server/Classes/System/GameManager.py @@ -9,13 +9,17 @@ class GameManager: __state:str __round:str - def __init__(self): + def __init__(self, logger): self.__players = {} self.__playingPlayer = None self.__state = "waiting" self.__round = "none" + self.logger = logger pass + def getLogger(self): + return self.logger + # game round management # this section manages the flow of rounds this should inherit itself # ============================================================================= diff --git a/Game Server/Classes/System/Logger.py b/Game Server/Classes/System/Logger.py new file mode 100644 index 0000000..b548160 --- /dev/null +++ b/Game Server/Classes/System/Logger.py @@ -0,0 +1,18 @@ +import logging + + +class Logger: + def __init__(self, filename): + logging.basicConfig(filename=filename, + filemode='a', + format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', + datefmt='%H:%M:%S', + level=logging.DEBUG) + + def info(self, message): + print(message) + logging.info(message) + + def error(self, message): + print(message) + logging.error(message) \ No newline at end of file diff --git a/Game Server/Classes/System/Network/EventHandler.py b/Game Server/Classes/System/Network/EventHandler.py index 38112fc..a9cd090 100644 --- a/Game Server/Classes/System/Network/EventHandler.py +++ b/Game Server/Classes/System/Network/EventHandler.py @@ -13,15 +13,7 @@ class TCPEventHandler: # handles passing of event data to the right functions def handleTCPEvents(self, event, gameManager:GameManager, address): - pass - -class UDPEventHandler: - __udpSocket:socket - - def __init__(self, socket:socket, gameManager:GameManager): - self.__udpSocket = socket - - def handleUDPEvents(self, event): + gameManager.getLogger().info(f"incommingevent {event}") if event["event"] == "PlaceCard": pass elif event["event"] == "MoveCard": @@ -35,4 +27,5 @@ class UDPEventHandler: elif event["event"] == "ActivateEffectCard": pass elif event["event"] == "ActivateMonsterCard": - pass \ No newline at end of file + pass + pass \ No newline at end of file diff --git a/Game Server/Classes/System/Network/NetworkManger.py b/Game Server/Classes/System/Network/NetworkManger.py index abc7626..341c3e1 100644 --- a/Game Server/Classes/System/Network/NetworkManger.py +++ b/Game Server/Classes/System/Network/NetworkManger.py @@ -1,4 +1,5 @@ import json +import signal import socket import sys import threading @@ -9,56 +10,6 @@ from Classes.System.Network.EventHandler import UDPEventHandler, TCPEventHandler from Classes.System.World import World class NetworkManager: - -#class UDP: -# __Addr:str -# __Port:str -# __BufferSize:int = 1024 -# __udpSocket:socket -# __users:dict -# __eventHandler: UDPEventHandler -# __UDPClientThread:threading.Thread -# __gameManager:GameManager -# -# def __init__(self, Addr:str, Port:str, gameManager:GameManager): -# self.__Addr = Addr -# self.__Port = int(Port) -# self.__gameManager = gameManager -# self.__users = {} -# self.__eventHandler = {} -# self.__udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -# -# try: -# self.__udpSocket.bind((self.__Addr, self.__Port)) -# except OSError as e: -# print(f"Error binding UDP socket: {e}") -# -# self.__UDPClientThread = threading.Thread(target=self.receive) -# self.__UDPClientThread.start() -# -# # handles incoming udp data -# def receive(self): -# while True: -# data, address = self.__udpSocket.recvfrom(self.__BufferSize) -# message = data.decode() -# messageJson = json.loads(message) -# user = messageJson.get("user") -# -# if user not in self.__users: -# self.__users[user] = address # Storing new user in dictionary -# -# # Process the message and handle accordingly -# self.__eventHandler.handleUDPEvents(messageJson, self.__serverWorld) -# print(f"Received message from {address}: {message}") -# -# def broadcast(self, payload:dict): -# for user_address in self.__users.values(): -# self.__udpSocket.sendto(json.dumps(payload).encode(), user_address) -# -# def send(self, payload:dict, user:str): -# if user in self.__users: -# self.__udpSocket.sendto(json.dumps(payload).encode(), self.__users[user]) -# class TCP: __Addr:str __Port:str @@ -70,40 +21,49 @@ class NetworkManager: __gameManager:GameManager def __init__(self, Addr:str, Port:str, gameManager:GameManager): + gameManager.getLogger().info("starting up network manager") + self.running = True self.__Addr = Addr self.__Port = int(Port) self.__gameManager = gameManager self.__eventHandler = {} + + gameManager.getLogger().info("starting up tcp server") self.__tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.__tcpSocket.bind((self.__Addr, self.__Port)) self.__tcpSocket.listen() + gameManager.getLogger().info("starting up thread for client socket accepting") self.__TCPClientThread = threading.Thread(target=self.accept_connections) + self.__TCPClientThread.daemon = True self.__TCPClientThread.start() def accept_connections(self): while self.running: try: client_tcp_socket, client_address = self.__tcpSocket.accept() - print(f"Connected with {client_address}") + self.__gameManager.getLogger().info(f"Connected with {client_address}") self.__gameManager.getPlayers()[client_address] = client_tcp_socket self.__eventHandler[client_address] = TCPEventHandler(client_tcp_socket) client_handler_thread = threading.Thread( target=self.receive, args=(client_tcp_socket, client_address) ) + self.__gameManager.getLogger().info(f"starting client handler thread for client at address {client_address}") + client_handler_thread.daemon = True client_handler_thread.start() except Exception as e: - print(f"tcp socket failed to accept connection due to error: {e}") + self.__gameManager.getLogger().error(f"tcp socket failed to accept connection due to error: {e}") pass + client_handler_thread.join() def receive(self, client_socket, client_address): while self.running: try: data = client_socket.recv(self.__BufferSize) if not data: - print(f"Connection with {client_address} closed.") + self.__gameManager.getLogger().info(f"Connection with {client_address} closed.") break message = data.decode() @@ -114,21 +74,23 @@ class NetworkManager: # if enough users for a round are connected the server has to start the game if user not in self.__gameManager.getPlayers(): if messageJson["event"] == "login": + self.logger.__gameManager.getLogger().info("user logging in") + self.logger.__gameManager.getLogger().info("task passed off to gameManager") self.__gameManager.addPlayers(Player(messageJson["username"], messageJson["deck"]), client_socket, client_address) - print(f"connected users {len(self.__gameManager.getPlayers())}") + self.__gameManager.getLogger().info(f"connected users {len(self.__gameManager.getPlayers())}") self.__eventHandler[client_address].handleTCPEvents(messageJson, self.__gameManager, client_address) - print(f"Received message from {client_address}: {message}") + self.__gameManager.getLogger().info(f"Received message from {client_address}: {message}") except socket.error as e: if e.errno == 10054: - print(f"Connection with {client_address} forcibly closed by remote host.") + self.__gameManager.getLogger().error(f"Connection with {client_address} forcibly closed by remote host.") break - print(f"Socket error receiving data from {client_address}: {e}") + self.__gameManager.getLogger().error(f"Socket error receiving data from {client_address}: {e}") except json.JSONDecodeError as e: - print(f"JSON decoding error receiving data from {client_address}: {e}") + self.__gameManager.getLogger().error(f"JSON decoding error receiving data from {client_address}: {e}") except Exception as e: - print(f"Error receiving data from {client_address}: {e}") + self.__gameManager.getLogger().error(f"Error receiving data from {client_address}: {e}") def broadcast(self, payload:dict): for user in self.__gameManager.getPlayers().values(): @@ -140,11 +102,19 @@ class NetworkManager: if user in players and "socket" in players[user]: players[user]["socket"].send(json.dumps(payload).encode()) else: - print(f"user '{user}' or socket was not found 'socket' failed to send data.") + self.__gameManager.getLogger().error(f"user '{user}' or socket was not found 'socket' failed to send data.") + + def stop(self): + self.__TCPClientThread.join() # Wait for the thread to finish before exiting tcp: TCP # udp: UDP def __init__(self, Addr:str, TCPPort:str, UDPPort:str, gameManager:GameManager): self.tcp = self.TCP(Addr, TCPPort, gameManager) - # self.udp = self.UDP(Addr, UDPPort, gameManager) \ No newline at end of file + signal.signal(signal.SIGINT, self.handle_interrupt) # Register the signal handler + + def handle_interrupt(self, signum, frame): + self.__gameManager.getLogger().info("Received keyboard interrupt. Stopping the server.") + self.tcp().stop() + sys.exit(0) \ No newline at end of file diff --git a/Game Server/Classes/System/Network/__pycache__/EventHandler.cpython-311.pyc b/Game Server/Classes/System/Network/__pycache__/EventHandler.cpython-311.pyc index a715b7a17f8683998011bf7fa6ada7fb8d99ca0c..207f7952affea3f1633f8903f9037ccba040250d 100644 GIT binary patch delta 666 zcmZ{f%}WA77>8$PzthpRGRdV(j7%ab41x}k5J3b&T9={^Xzd~hZQ)6xV~_`7h&*_Y zPSw4xU6VaYf5i%(qj}fba;-T$^YVM%`FNY5hY-0VWB{>M-e?ropU51ho1D7+%#vGF z;S6pRq_YfM#88-ADeE!3Ycd`qxMq=RV&sr3B|ROI+Y$8`*)_ytly9RV1LaXl&Ay9; za-noitD+IOM=8Pd!%v48sDbm*8&+JRmQSlisw?$9%QtN!qJ~<2jUGwETP-qJTdE$^ zD;Altk?M%vOzz1pEHY~&@psmYr7e=S5#PP_O$yT&oRh}j8#)d1JMo}M9(5bB?H|x< z{*{}gIbl^xz_B1eV>rfi0Ve{c&gvBY8jXI4ncXRtoXHGqIK_V@IPKY#Vve)Si~%M9 zDj*IJ00BS}09QJPOahhjE?|N#%WL$MkH}q{pbhy%aI71hOaT3v^wS2J=~T772AGVG`^ zX37fF6Nru4_4Do5AHWzqhuq3&vb3_j#&a$E;* zf0mfT(sSIzsbEqm26z~qCAI;N3iagfP35zGs%?! diff --git a/Game Server/Classes/System/Network/__pycache__/NetworkManger.cpython-311.pyc b/Game Server/Classes/System/Network/__pycache__/NetworkManger.cpython-311.pyc index 7d5188f91f19ea55044e2f67762d294a6561646e..769b27dcae9ff8cdc045a20315be639cc41b4458 100644 GIT binary patch literal 9809 zcmcIqTWl0pny%_=*{-(RP}q&#K!a~I0don)#@viC7)ZuIY#=mFn#NVeZTH1fRmQl} z&azUpA`#MfS43fEGn&>YlVy~QgjV|yX%+3PBF!@URMo0gw@N}nTJ6KW8Igx5Py7F; zx~i+}X60yStB?Ql*SY?6F5mgiIsS)0pq_$fxbX|2qlKdW6JN~7Q&C>!LHUg0DV|PI zF~g^0GJ$l|@86;u3FrEKCcm6uoVfbtn7Q21Rj*HyzJ8Z2_H zvB)jB1rP5&4(WN1;N`vW=Yv1L;G1T6<|9wc&)0oK#TdRGEN{>o#{_vXE6!C+b=2-N zYk#_?c2Wn8br8)(YIDcDf)DEUkZ?a}UZOFe`7F&(w7OZ+uUJ0BG9;`4v^v!Idcn;% zz#l6#O#Ao%*v#^cU~_ij0bJ?-H)!+VhDAVo931-`B2$4$;} z>xCxQ>*FBf@zXpnn)>CeC?_cxPI}OY9A2277R2#nPSBf-5P52TJUcZf$oeKDK(O~^ zgAukM38JKLF#OSLIH{UwBdWyQf5cjc+LHJbA@ykTABk?Ty2qVg_hPDtl9 zWAko!Ge-)Qq~Oh8jVqX{!{3m#ZfBh|B{x?KnKfqyB?oPxmd%b(Ypglv3Rv1;=FL;H zmR?}ZP`eK)thNE&`u^!PZ9_u~*vbmn%P@84_d^bM!HjbF&UCNoRnNM1+Ey)Ow#n4N zDyyZw_B!)GOIU4-V`A2Ni*K^!w?Ye>%}~4Vv=$K*W}$B^*DlEkm|>Yak%jq4#(t6OSh|NjV4 zP1yz@ai1!)ttED6k=?1X9U9wFVs{tW-AeSF%8qL6sKSoEXy5T*#y&kLp^ljz)?0HPxS$>`@_p${nusp0;SfE4;o-3(sfKgrgA)N)fu=u#9 zU0<)EGs|w?op;AAKn9@P5TItxbx?BHw4b6nDe>sC$MK~bX-V5RR?Ff&c~7mDya9l> z?D^1>VGMtfUZn21Z%~Wa!dCVb`l%1T!h&Ke0u*OER{+#ImTNj=0E)mz7L)Q!B2C-J_ET7Jlu-G zZCF7);Hbf9B@sskfl6@~Y8@Ew7lkPy325DgLERWsclI7ZWJEhslkS<#CNoj5*n`o{ z27JfC#tgjP9uB!%=t%u<~kW@Nv zfZC>(M|)pVje)JJu0ZqF^1yLz;CyM|QgPstI&eiBxT11>3fEQmu*`)tuDiq?C~^l> z?vTbEDslZqu3s65J?jMlPUUWD+)ahMSw44tWrU+?yKr=F>5iJM(<-f^zYu zIyk8fPGX9lCygrC|9o$sw)c2>N5|*+^7j2tw=3I*R=w_hEiWk$-=k2t=qf`U9spnC z4wSiQiQ8Y~_N&}MjXS6i_rvqn$SUP(-dYv4Odcq51IkfZ`MHSlsH}1e8n>Wu3y^qa z#Q6OH&#D)SLVqi@xz%i;?Nk8pue->0tL$zKz~6Kd4!}=_kDQ^Y@96pwkNdlZ{bx?O zzdPjxeagZsNQ7jN;Nl8&9}rmkTyTls0xr_Ei4CN*P|`_PmH`u_LqB;o|1Y@6yMDcn zZX$hwnTq3n-Q%38%N{!#+OTg8HCy)Py#_dW;*ocYBmZ=@l{{p&0l?6L!kk+zl7fX%Ia}Kf33Iw!+OQY z2v3#AVgCl&!Z}`Qp*57)XqE1&eqW&`=I6b33;y4}xenK8zMiZvYsL;ut(||TP4sG(6v8ZuF7QJm*gbP&V`HR}ov>`i? zfsmG|$v|9B{~7xV|DwUMT(H6}V7p?_iyQ-+tgIyPy}Ad_G+-ge(+=I6%HBz4bOysR zu>a6Kyf8JF3sxuw&<>1|BDt1#3|hcP(y*Yz30P!W%%&qb*I*=h4ro9wf;+jXT62!8CCIOFsfaLh?;`l0}vFLrAWz234vMI6QWfu7Ulq=`;Azwm_O*b%mSLbh&+Z zseNCuecuya>pi8m4{7Z~D>6OvvySl&F^W?g^t54h2xAIoGz56$( zes$`}5w-o0)_!PZ1ZYqwTsW+C^p!e>iXB60$FSBhth5fVQtmAufOXx4MXi1R)Ba-n zAXu~&g2E9k+*=ACErySN+x^G(XEE*cyGl$@rc+uhtqx|i!HhD$yh>3+t})k3irRL` z^*xag1iG1jpco!d!-HCQuoOO344+blmi}Y>nsWW7c0F0TE*G!M>h-(Y^}Fi$qBgz= zvEbBjP7CLhaP9@NM__vz*I(jBi`?k52IcAv?dlyRxu|mYH13|l-K)jd42qdjuEdpr z6uPNdLs7Z3#-$Z54ayJy)w=CbewFex%d}mVTSJc)3th$5p4WEH@nYyWeCNs2F6Hw3 zhGLh{99xI6IY2@@RhmEOwq$JBPH+AvJhf3!YYpgK=eL7jf50Y<6s@a2rE9 zeHiw$KfTjo^W@6A?^5CwI1&QA+N}^a>I`vox_#h*3C1Ji_O9~GT7++1r`OziIS1p~ zPOs2Ovv6u71E*lK#>$Ad97wC(>!~XlRvu$m<$TCqB0ahOo(PZyW7Ul;CZtFvD+6Cy z$ncRKBeW+{J!ZjiM_5TOtlQ)`8ONnKh60D9cnQU26xh;a`Hy* z4lE_tT4P*dt+yaj`Yi|;k}Yjo%kEOko5hwl)s{Z3rSHM$i>A#hix2(^R>{CJT^M+> z_*DLSS?K`m$AEIM^|9ws;PH$W>?sBJ7K3~LF!6Ql8^5}5NZU75+BaI&QtpzXV$ z1}|#Ci;C%91UW6Z%gCYzd$nM1DR{UTJgoG6@C^^baB48G1@nsO$Vhgamf~O{gBV%M zPanj_+1T&tF*pjtEsuBzM3g4YD&Z-saYO{L0O#hlTM!~$_u2z(qU zw{>W3dlUwp%Iqn(>{J+ZDzkId(_HsP!M#d>_oRb(-y9>}TG1V>i>^|Z=-gh1OR-H3 z(XP5-x-bGv1^gP4@zue|^{i6pKRILgHDr*k+XH~RP8d!0K4~&IZzR_(x*r;k+_?JT zMjjP%_cCP%C<|c!2D0MVEP%iM!4vDe$9ehz7il>9$Rpdzte#}a*x8k*dhQOpR4d$h z!eWec@hW72GgSN-F%AOmtCDvziInaezc6}XY(ftjn+>?(kzsGKFfUh5T#ZYnTbM6_ zg4{HrWv~RA2dOyp)=d)gJ}3i`5^gJCl5B4MY~b$(9*-1yo*Yv*_iLN`A9x-z&zZ)D zflsF&r3({U*PzNA)0kt5>5QpwCk&{Qsb2);r%(Obq-FixHguc4R;bH(oU2a3YIZXo zePk#T^YdEBzfGeYII zvsXkwjQaI(+==$_xa}VUj1>e==E)ck5gBy1v;_1=xR;bGRL2+^3u)auEdpFQ_>L$* zmfQ|!9ldLZjtGe)T(_Xh8CGN3N=#>w=~S6+jp;5iZxop~l)Z74xur3;6y_GB`33U{ z^Kt#d`d>7C(xft5HD;^AY<Pep_5vEzmM=;8_x9Mli>eRYKY#!HU!Py~ zxxB|81I~c=WHa%eP7&{q9}sV?VBB5~meX~@uoexCHW?&f3XLY)e_V42^y`}|_qM%w zm)mQcA&59+^)@rcxX~pED*vBD8b|L~lc3U{z4rew5^<7~TN|BQlbrmYk%(N$XiaAe z|HvFS7Pph)JS0Ipll}z+P*a*NQw{gYuS^B*lb=ngzfXQ;DyW#QOm!?%A delta 2974 zcmaJ@YfN0n6`r|w-*1+??6PkR3#7O%o=$u1%X4EfW@uIMj=hx*wyY{v!^dJMb#cg!Sexe~1UE84qdV zC~Bf}xE}w8UdMM>)kV9x&#Q76p?6UdXVC?<8_Ht(+pvdT<16F5+L-0RL!;K_5!AG5 zO|+^SLJK-o7cHs=t$I}#E!3eAf_o6iK#eoChd)pX5pR9Kg@2V<+@5qU)aYUtoZJ$=#G zfHgGlVAD2bxlV9liK025=M3~HXJp${Q4RqKP<8N=8N%vWoaHWZu(myWyuxSsbu(K> zGe%3%S|obZ&Ir{Z;$P8-<)IJ|Dy#W9dY_}AN*Dc|sm7A~a}vdYX+Q`K)tW;zVs7(W z3Cl5Ii7M)56N%I%v8cU7=9ffLNwa2eeVCbRm|0I!iPZe%6scu3W6x{Md472*swH*w zbMt^M!dwr~kmaD~9H<#Pqzsbjth&`)LRM>aiL=mIi{Jf3sFu8)8!-SVd7-NybV))N z{n&Dza~-5+Ys4eFoReOTOWt!(^1^6A7?p%kI&Jl&-Kf&7hLq#(g$zr}^^?w%e)Pa^ zI>qr1>YXRM_y=8D&=X~vgA>aZtN;5s;JZNdoy~m*lV?VDJdXIP=-1W|?}B|Ew>43x zvDN{JHbb}VXF*5*XbaF*KREJs=ZY??gGdI|yl!M$rn!vCYqZtw)~1<}(Vi3CbkW|| zxM$N0yE(r<4E@q)qrDC{w$cj@7q-!>CPA0g${~O1@G>$!bu_juZ2&uh>I~rUI8+^Y za%x4N)i0Dum^8m4Un8U%I$y0g!eachqP1Z%iB|M)=&xY0%u5L5+!ZLaq6gnqXKUba z*|%P`%al|+^p(Rr&i(7N@k$e}6lB5`H9)4zgq>s3MAw9%u9B(E^cTXB6FyLj+7uzn zL>5cSMSFjIICeUfSWc#TSUWicK2ZayW3JXjdOo!zUdSvbUP+1M2(`Mxf$y<+-vP+5 zod|C~MCNDUX-{IT~o4yX{Qaw$NR=s%W ziN8iVF!}rVU7^rE@J0LRX8UNqeXP(vmOnaPI64kCD0%->!9OMWr|7+^$f|r0V!3X~ z3&$mP|GXme!f-(tmgMsMsXK5hTSA(Ob9gsyxjnb8tVcH84Lft5WpkcYO5QV9@XSe` zxh+rNwpRVg#^Th2dxSL7{S4_bSc2JHraeqeg zPOx%*Oi}W}WI>pe_7x>mm_>kXP;gZia-hN78`dK>x2joRLp&y3Xu9A>nQ>WM;R(2Kguv*}k;nW83>T1t{*wAJhKFv1e{sUeJ@ z8Fu>sHA#fdc$@K?^ewMwZcwcWo_=5uuz`kr|KLO`?esTeAD#F2#CDBB2ADfr02yR3 z#GnZvs*z8}&R|9TrS$CUDU!)(z|0PWavBCG4)}G~p)K<^tqs&UXYhL4#+97-$%<6l zSwg&ZhK>h18lO5`Qq|OL5kM(<$8^ClEvbdDiO1lJ`gZU{+zUF953(jXpAboy)!Ao+ zu)zttCddH>Eev7|*g`%=auj)DMSkSe8Nx2wZg?|B8VN1;nvG5CdP z@Y;;kB~*rR(8xGdM*8T>N*D22tet^$e1llsZhfX0zuN0_ zkwYfyTHjjV)xMGrYuj!^-au?r$|9GL#r+@2;#)zPD4Sl?rVv-=37>gAL&EfLbw8=y xyPW?RIv1CduclMoWDYvPp9+-u1HBRP(@!Ibj-(r>L@n1_Jx&QzG diff --git a/Game Server/Classes/System/Server.py b/Game Server/Classes/System/Server.py index bc8f7f6..c3485db 100644 --- a/Game Server/Classes/System/Server.py +++ b/Game Server/Classes/System/Server.py @@ -6,6 +6,7 @@ from Classes.System.GameManager import GameManager from Classes.System.Network.NetworkManger import NetworkManager from Classes.System.PlayerManager import Player from Classes.System.World import World +from Classes.System.Logger import Logger class Server: @@ -17,16 +18,23 @@ class Server: networkManager:NetworkManager - def __init__(self, address:str, tcpPort:str, udpPort:str): + def __init__(self, address:str, tcpPort:str, udpPort:str, logger:Logger): self.__address = address self.__tcpPort = tcpPort self.__udpPort = udpPort self.__world = World() - self.__gameManager = GameManager() + self.logger = logger - + self.logger.info("starting up game manager") + self.__gameManager = GameManager(logger) + + self.logger.info("preparing to start server") self.startServer(self.__gameManager) # handles starting the server and assigning socket values to the local reference def startServer(self, gameManager:GameManager): - self.__networkManager = NetworkManager(self.__address, self.__tcpPort, self.__udpPort, gameManager) \ No newline at end of file + self.logger.info("starting up network manager") + self.__networkManager = NetworkManager(self.__address, self.__tcpPort, self.__udpPort, gameManager) + + def getNetworkManager(self) -> NetworkManager: + return self.__networkManager \ No newline at end of file diff --git a/Game Server/Classes/System/__pycache__/GameManager.cpython-311.pyc b/Game Server/Classes/System/__pycache__/GameManager.cpython-311.pyc index 1e24e1dce94a888aa2ad79056f413e00a5359727..52b6cf32f127c6b978885d3e0f3376081450c694 100644 GIT binary patch delta 633 zcmZ{f&r4KM6vyv*zk2iDyKiQ69GV$Z!PP68m0*N6ibzpbf)yxAJ-F8idMeykLG~5} zE?f+V9>|?;0ukE8`~lV<5VV|T*SgJ^wQ1G8kDMs#!2NLep7TBD+^^@}4$=ck9U|iq zea*jb)0dEJZ%vPFkcAAhxwEXX%!aYxGDj*NbGa@RPb!pAZZe-csb;aP)O?nkBS9V= zh>Dt;`72be%Xcz^4H&l)NXUHy-@_o7_!$b7wiT__>s$m{+lYCzEU0Xbm1_t!ErtvD zR2$9}`!|h-+p@h)<3yGSesRvv9m1^u(*8pbzOsR`iL7KhQ|FIo(#h+6SHl&4Gh7Yj znrc@rD1-X_3)0H=HlBa9%Oa2a+L0-GrHY}x1pUn;{gn=-=Djl$02SP|=b_p>w%-60 zaL=j2b^PGmy_k;ry;}s*zh3-n>ueN0<08I;x81W)!iVm=o^jb180qPvBy%x^m%T}t z$HZHNEPnECO!g_coYoYSLrf^B9paioO(CzKJ}%5tSTc!Q_<&v-uuR$^UF5*5bVwID vJfJ()h_X##%^xoRIq-))wz9^aMEr`F#l#=2EddO4$iI1<>fioTO|Se3`udO; delta 495 zcmdle|4Ej2IWI340}yObnv*(xB5xyO*~ETVvsBJBrWB4AmME?i&K8C!?i8+6W}pZ+ zP=qIiCzUmYH$ZD!$9E4V`id4Z;YjZ!G$2U(#u z`5w2lQ~*d6HD~PZG5nuzsma>AlAOhsy;**mF_$>HYS$RJ&zzK=T zX?&B|3_8U5*+udyGhgaY3{PxY8H}B2wy^rYwSDy zB@pr(Cj*gVrC$PNi&(@G98xDDsSrzCBbKx+60!>;lDc3CHKNIXa9VA|*6;(7L+Kab zvqdNYUs4w>VU5%!j8&H{2~e?Qh@b?i*>4Ft3Es8}+2!?#_k@%zP+%V~paR-st(Of-Sw&?V|5 zGnaC1wqT{B7GF&lUr!fnaB{V2I~08)&23vWNHyEcHT@uMnLcg0exQVrG$}|sz|;0x z!N^CG+l_MDYuc?qnR)SiuA+&7%&F64NSq^wLgD0Pd0L<2lyRN=lrHHrlz;Nu3;G++ zu{~$PQYclD^M4;GdK)i7+&_6?&m8XE@&EDnDNuu2Zq z(F67Nw-4Q$ce)dAyEpD0j!%AddqeV2@rVE%BlONfA9j*6eZ!vpqi-w1Hgs+`>7GD* z^o-@SZx{WrZ#zO2N~kO_+w)llHU+ZnHQPHP8^uXFZcto0HU>sE4$v8iDWf;;;MOiWsAml0^P(BvdBb2=@Gw|G zhDmowxH+mT{wf#(4*m>aHFK9ACu|B9@Fwx606j?%gf7XghEFe*6CnIWI6~X;B@1DOzkIY5wg3PC literal 0 HcmV?d00001 diff --git a/Game Server/Classes/System/__pycache__/Server.cpython-311.pyc b/Game Server/Classes/System/__pycache__/Server.cpython-311.pyc index f6841be261e4d63e622e2b085aa2d34d8ba7532f..9c11ea7f48ed176cc115e364215a5d9a6efa9036 100644 GIT binary patch literal 2529 zcma)8O=#mr6duX4Jn>(CH-8%!ElsyE-Da0IX`n3ILrVA3qzh?UFa}|wN$NzF(~+_v z!Gsh-*~4B6h23KgB~3}8*FCh*V-G#Z#jr*Y2=vsOOM2Q<-y2!7<)qN@=)G^=n|U*O z@6D6H&t#GW+Ume}?6o){f8ro$N*i1{0G<(p7?Mc}K9>rT7|R72xNOEMNDn28E4P=VuSUnN;c3apx`O1hAih)f<5BXL9wdLk2Y29Mtg8ADnj`M$q!xSW@~ z)WcGREtRa&2IDZyE;DDh%C|Za^^sZH6T0~4Rc;zEN&UFG0n^voHU*>Y!DS7=Gr|bI zM?qdCEXEW=x(`x;=CWF%P3pz!p;lVo(A8mS|t&}XEXx-J_T zz)2&^5`g;wr;Gu3w?R)`Vf-=U-hl1{T`w61XSUrXan`mURk_n8*)e=cHe3acFb!`c z9B*`7+b& z)*SbBtalLD3hnl;F$jb4;E^$;jRZUFOY>^20 zB*)9hQ%KTC&E`GZu+#-jKTW-)ri{WSncZ?Xy8Z^vPh1rp@fBw(1b1lOZA(ExYSyeqM5(h11V zx^#M&>LPjM<^7x8$<_i0*p*SQ<3ucP5XkNby;r9T4Z7gcg>!B8)cNt?h4b^lZ_e)ruD)5y@gpVVI#3Pe zTm^ew$z2TJauw`#x&Ww5yh<+SRo!=6HS17o3$0sBYe5yLim{#bXxhO8a{)YM3|OGoc;R z*-mWX>n$AYP4!ImKlXt&yn^0H&lK@5Km^LW(WCPJ7jO|Z5t`dzpcAfF^uC`A5BObB zVCLCB0cph~NotbRq4+gP=1}~aWWWu2lf2_b`vv*HjrJzF>qdK%+;*eANoL$=Zz(wm QB65}djk15PQHU4%7rk?0IRF3v delta 721 zcmaDT{DzNjIWI340}yP`nv;5*c_N<#W5z^vUj-%xcZL+U7KRk|WlRhVtAQ8-qPSBS zgBdhACN8iNPlgGCXf`P4bI!!y;ZkXADO@cqQ5-4UscdOXDLgQC)8r`P1ZpS( zIlPD)M1T|*@qh@BNkzOs;ud#tNn%k+aB5LmYLO<(EtcZcoU|f-khB1Z5Cjs%Aa_iD z!<^100^<2jj$~04yeq3QGj>jF2g?->sSj)noV=5du{h}k0ToPVC}9LrP*B5=1?K_T z@E`)RnI~tlN~^*>nZgjvP$Uf0rpa0a5=3_W str: + # choose from all lowercase letter + letters = string.ascii_lowercase + result_str = ''.join(random.choice(letters) for i in range(length)) + print("Random string of length", length, "is:", result_str) + return result_str def main(): # retrieves host data from environment @@ -9,9 +20,11 @@ def main(): TCPPORT = "54322" UDPPORT = "54323" - Server(HOST, TCPPORT, UDPPORT) + logger = Logger("log/"+get_random_string(8)+".log") + logger.info("starting up server") + server = Server(HOST, TCPPORT, UDPPORT, logging) + server.getNetworkManager().tcp.stop() sys.exit(0) - if __name__ == "__main__": main() \ No newline at end of file diff --git a/Game_Client/Classes/Game/Events/PlaceCard.py b/Game_Client/Classes/Game/Events/PlaceCard.py index 1be3cc7..6068a30 100644 --- a/Game_Client/Classes/Game/Events/PlaceCard.py +++ b/Game_Client/Classes/Game/Events/PlaceCard.py @@ -13,7 +13,8 @@ def PlaceCard(tcpClient, card): "event":"placecard", "card": card.getID(), "type": card.getType(), - "pos": card.getPos(), + "posx": card.getPos().x, + "posy": card.getPos().y, } tcpClient.send(payload) @@ -27,7 +28,7 @@ def CardPlaced(world:World, card:int, type:str, owner:str, pos:pygame.Vector2, i world.spawnSpellCard(f"Assets/Cards/{card}/", pos, inputHandler, owner) pass elif type == "TrapCard": - world.spawmTrapCard(f"Assets/Cards/{card}/", pos, inputHandler, owner) + world.spawnTrapCard(f"Assets/Cards/{card}/", pos, inputHandler, owner) pass pass diff --git a/Game_Client/Classes/Game/Events/__pycache__/PlaceCard.cpython-311.pyc b/Game_Client/Classes/Game/Events/__pycache__/PlaceCard.cpython-311.pyc index 25507b3ef58b404eded5d4192837e37079e82024..de829abd8c9dd691b48fa14c578ef68f3d99bbd8 100644 GIT binary patch delta 486 zcmZvW&r1S96vubg-SHQz9{f?!K}#_`MzOW(xqFMg>FI6Jca1cgZa#R^S<+a?Cdj9&Tx%fiTr;{X#ugZgieNVLn8uqAqmOC2d=1%?34vX7@WpXdR37X6$FM z(2t0{Qxc;dhGkBqS~4o?3TjvoiHqeu+4oe+Oe^SW@!J)S<)2HI;^X`@q;8)h(#NjK^N zcmWH5MZl5-gIV!e(6CH}4}Min8ckx-RrwI(6YUX2`L155{pXaF8kz#k?A$V&+r{U8 z-hHb}OfaQuvImw7L<422c?M+~l`E zT8t5s1DV7*lZx`Qftr)kC#N&Ha0vk|Vgur0zsXyf6eakD`>VUEJ8OGtKX9`0vwdIy z5)JMj_$L2lGG#3SxpT8Qb0VX6Zb(sLfiuu{O|~KtplA^Xh~NYfq96jKvPcX_6oU*` z0D~eyAoCU%NLN5kVsdIqkvvd9Z1Q84O^m{mr?FaxVlznrsHR8}M1YNB2eKf>DL~BQ z^vy3zO#vBNqym&v0^(wjq6UT=EF29kMZ%NS*g|YT-n_+}2@Esl;*z3U>|v?NCHX~0 zU>AV(6)6K%6bXX}kTZXA*yQG?l;)(`6=_f2#^%7!%P8}K0Zu4PW@Vqn0#XeCR@!dw diff --git a/Game_Client/Classes/System/App.py b/Game_Client/Classes/System/App.py index 969f758..1b5a3a3 100644 --- a/Game_Client/Classes/System/App.py +++ b/Game_Client/Classes/System/App.py @@ -117,7 +117,7 @@ class App: if event.button == 1: # Wenn linke Maustaste losgelassen wird for card in self.__world.getCards(): card.setDragging(False) - card.setState("placed") + # card.setState("placed") # TODO: send place card event to server # resets the currently selected card in order to prevent it getting moved try: diff --git a/Game_Client/Classes/System/__pycache__/App.cpython-311.pyc b/Game_Client/Classes/System/__pycache__/App.cpython-311.pyc index b40c2b170e1bf4fb8c917ca5316d8b0696d69a7a..102cb35b6dcd4d8fb10d4a8db96109a03d27e433 100644 GIT binary patch delta 249 zcmZ4PbKaYGIWI340}#yly(radBX1xZqx0l=Hu233Y_GV5de|8lrZc24)H2mDx-d*& zj@`StMu?G(ao6NJiAKiCNs`9w@wMzV>92t{x2#h#K}-%4Kfb`Y8bNQCeM+S zXSAEVM^cuZw}x{z!(67x8(Bmrf0b0@PME;lvpdkVhoQwbiu|_5U delta 298 zcmX@_z1)X)IWI340}y=Co0ICXkvEWy(RXq@n>c4uQGRx6UP*HL=2EuT+(O&f85pKB zq%hPn)iAm+Okj?^w7E!#k&W^E)c7RF;>sA0&GpPV5n&*(6@LsFKVuZD9r!(67x8(BmrACy$%E}g*K zb0vi#m_d_&@+Zj#j$3R6If==sDU*w&3>XzRFP36rDd8u?ilOW4x zGnr~;ksA^+^Lc0SF37kjp?^g}|AK`62e!$Z Date: Sun, 14 Jan 2024 18:41:45 +0100 Subject: [PATCH 2/2] cleaned up code --- Game Server/Classes/System/GameManager.py | 4 +++ .../Classes/System/Network/NetworkManger.py | 28 ++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Game Server/Classes/System/GameManager.py b/Game Server/Classes/System/GameManager.py index 36e2bf8..9347fc2 100644 --- a/Game Server/Classes/System/GameManager.py +++ b/Game Server/Classes/System/GameManager.py @@ -87,13 +87,17 @@ class GameManager: # creates a player and handles counting all players and if conditions met starting the game # returns the new dict in which the new player now is added def addPlayers(self, player:Player, socket:socket, clientAddr) -> dict: + + self.__gameManager.getLogger().info(f"creating user with id: {player.getID}") self.__players[clientAddr] = { player: player, socket:socket } + self.__gameManager.getLogger().info(f"new length of user dictionary: {len(self.__players)}") # counts participating players and starts the game if enough have joined if len(self.__players) == 2: + self.__gameManager.getLogger().info("2 players have join game starts") self.startGame(socket) return self.__players \ No newline at end of file diff --git a/Game Server/Classes/System/Network/NetworkManger.py b/Game Server/Classes/System/Network/NetworkManger.py index 341c3e1..9cb2b78 100644 --- a/Game Server/Classes/System/Network/NetworkManger.py +++ b/Game Server/Classes/System/Network/NetworkManger.py @@ -46,13 +46,16 @@ class NetworkManager: self.__gameManager.getLogger().info(f"Connected with {client_address}") self.__gameManager.getPlayers()[client_address] = client_tcp_socket self.__eventHandler[client_address] = TCPEventHandler(client_tcp_socket) + client_handler_thread = threading.Thread( target=self.receive, args=(client_tcp_socket, client_address) ) + self.__gameManager.getLogger().info(f"starting client handler thread for client at address {client_address}") client_handler_thread.daemon = True client_handler_thread.start() + except Exception as e: self.__gameManager.getLogger().error(f"tcp socket failed to accept connection due to error: {e}") pass @@ -66,9 +69,16 @@ class NetworkManager: self.__gameManager.getLogger().info(f"Connection with {client_address} closed.") break - message = data.decode() - messageJson = json.loads(message) - user = messageJson.get("user") + try: + + message = data.decode() + messageJson = json.loads(message) + self.__gameManager.getLogger().info(f"decoded message {messageJson}") + user = messageJson.get("user") + self.__gameManager.getLogger().info(f"user in message {user}") + + except Exception as ex: + self.__gameManager.getLogger().info(f"decoding incoming packet failed due to exception: {ex}") # creates a user and counts how many currently are connected to the server # if enough users for a round are connected the server has to start the game @@ -76,19 +86,29 @@ class NetworkManager: if messageJson["event"] == "login": self.logger.__gameManager.getLogger().info("user logging in") self.logger.__gameManager.getLogger().info("task passed off to gameManager") - self.__gameManager.addPlayers(Player(messageJson["username"], messageJson["deck"]), client_socket, client_address) + user = self.__gameManager.addPlayers(Player(messageJson["username"], messageJson["deck"]), client_socket, client_address) self.__gameManager.getLogger().info(f"connected users {len(self.__gameManager.getPlayers())}") + + self.__gameManager.getLogger().info(f"confirming login for user") + self.send({ + "event":"loginresponse", + "id": user["player"].getID(), + }) self.__eventHandler[client_address].handleTCPEvents(messageJson, self.__gameManager, client_address) self.__gameManager.getLogger().info(f"Received message from {client_address}: {message}") except socket.error as e: + if e.errno == 10054: self.__gameManager.getLogger().error(f"Connection with {client_address} forcibly closed by remote host.") break + self.__gameManager.getLogger().error(f"Socket error receiving data from {client_address}: {e}") + except json.JSONDecodeError as e: self.__gameManager.getLogger().error(f"JSON decoding error receiving data from {client_address}: {e}") + except Exception as e: self.__gameManager.getLogger().error(f"Error receiving data from {client_address}: {e}")