I have been learning to use the library pygase for python, and have run into the issue of the server crashing when the client disconnects. Is there any way to prevent the server crash?
I have tried to find a function to close the connection server side, but have found none. The disconnect function client side causes the server to crash as well.
code below:
Server:
# backend.py
import math
from pygase import GameState, Backend
from inspect import getmembers, isfunction
### SETUP ###
# Let there be an imaginary enemy at position 0 with 100 health points.
initial_game_state = GameState(position=0, hp=100)
# Define what happens in an iteration of the game loop.
def time_step(game_state, dt):
# Make the imaginary enemy move in sinuous lines like a drunkard.
new_position = game_state.position + math.sin(dt)
return {"position": new_position}
# Create the backend.
backend = Backend(initial_game_state, time_step)
# variables
connected_clients_ids = []
version = 1
### EVENT HANDLERS ###
def on_attack(attack_position, client_id, client_address, game_state, **kwargs):
print(f'attacked by {client_id}')
# Check if the attack landed near enough to hit.
if abs(attack_position - game_state.position) < 0.1:
backend.server.dispatch_event("ATTACK_FEEDBACK", "Hit!", target_client=client_address)
# Subtract the attacks damage from the enemies health.
return {"hp": game_state.hp - 10}
backend.server.dispatch_event("ATTACK_FEEDBACK", f'Missed {client_id}', target_client=client_address)
return {}
def on_attemped_join(client_id, client_version, client_address, game_state, **kwargs):
global connected_clients_ids, version
func_failed = False
if connected_clients_ids.__contains__(client_id):
backend.server.dispatch_event("JOIN_RESULT", [False, "Client id already connected"], target_client=client_address)
func_failed = True
if client_version != version:
backend.server.dispatch_event("JOIN_RESULT", [False, f'server version is {version}, client version is {client_version}'], target_client=client_address)
func_failed = True
if not func_failed:
connected_clients_ids.append(client_id)
backend.server.dispatch_event("JOIN_RESULT", [True, "success"], target_client=client_address)
print(f'client {client_id} joined')
return {}
def on_leave(client_id, client_address, game_state, **kwargs):
global connected_clients_ids
print(backend.server.connections)
connected_clients_ids.remove(client_id)
backend.server.dispatch_event("LEAVE_RESULT", [True, "goodbye"], target_client=client_address)
backend.game_state_machine.register_event_handler("ATTACK", on_attack)
backend.game_state_machine.register_event_handler("ATTEMPT_JOIN", on_attemped_join)
backend.game_state_machine.register_event_handler("LEAVE", on_leave)
### MAIN PROCESS ###
if __name__ == "__main__":
while True:
try:
print("server opened")
backend.run('localhost', 8080)
except Exception as e:
print(e)
Client:
from pygase import Client
import pygame
import os
from pygame.locals import RESIZABLE
# inits
os.environ['SDL_VIDEO_CENTERED'] = '1' # You have to call this before pygame.init()
pygame.init()
pygame.mixer.init()
clock = pygame.time.Clock()
# variables
id = 451
version = 1
client = Client()
connected = False
connection_address = ["0.0.0.0", 8080]
running = True
screen_id = 0
### Handler ###
def client_join(joined):
global connected
if not joined[0]:
print("error, could not connect")
print(joined[1])
client.disconnect()
else:
print("joined successfully")
connected = True
# Register handlers
client.register_event_handler("ATTACK_FEEDBACK", print)
client.register_event_handler("JOIN_RESULT", client_join)
# functions
def Join(address="localhost", port=8080):
global connection_address, screen_id
client.connect_in_thread(port, address)
client.dispatch_event("ATTEMPT_JOIN", client_id=id, client_version=version)
connection_address = [address, port]
for i in range(5):
clock.tick(1)
if connected:
screen_id = 1
return
print("connection failed")
def Leave():
client.dispatch_event("LEAVE", client_id=id, client_version=version)
for i in range(5):
clock.tick(1)
client.disconnect()
while running:
if screen_id == 0:
if input("specify address and port? y/n\n").__contains__("y"):
Join(input("Attempting to find server\naddress:"), int(input("port:")))
else:
Join()
elif screen_id == 1:
if input("exit()? y/n\n").__contains__("y"):
Leave()