0

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()







  • Can you provide information baout the crash ? Do you have a stack trace ? Could you reduce it to a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) ? Have you tried to [use a debugger](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) ? You are expected to show what you have done to solve the problem, and how we can help you, cf https://stackoverflow.com/help/how-to-ask – Lenormju Dec 12 '22 at 15:00

0 Answers0