0

I was working on a multiplayer game when I ran into a bug where the the data would be sent two times. I worked fine with a single player, but once another player joined the server, data would be sent twice. This is what the data received from the server looked like if only a single client was connected: {"player locations": [[1, 84, 100, false, ["n", "a", "m", "e"]]]}. This is the data received from the server when two clients are connected:

{"player locations": [[1, 80, 102, true, ["P", "l", "a", "y", "e", "r", "O", "n", "e"]], [2, 57, 102, false, ["P", "l", "a", "y", "e", "r", "T", "w", "o"]]]}{"player locations": [[1, 80, 102, true, ["P", "l", "a", "y", "e", "r", "O", "n", "e"]], [2, 57, 102, false, ["P", "l", "a", "y", "e", "r", "T", "w", "o"]]]} 

This is the data that the server sent

b'{"player locations": [[1, 80, 102, true, ["P", "l", "a", "y", "e", "r", "O", "n", "e"]], [2, 57, 102, false, ["P", "l", "a", "y", "e", "r", "T", "w", "o"]]]}' 

This is the server.py file's code:

IMPORTS/SETUP -------------------------------------------------------------------------------------------------------- # import socket, sys, json import threading # FUNCTIONS ------------------------------------------------------------------------------------------------------------ # def get_ip_port(path): with open(path, "r") as ipf: ipf_data = ipf.read() ipf.close() data_split = ipf_data.split(":") return [data_split[0],int(data_split[1])] print(get_ip_port("serverip.txt")) def update_clients(updatemessage): """ update_data[0][0] is the player's x pos update_data[0][1] is the player's y pos update_data[1] is the player's flip bool update_data[2] is the player's name str :param updatemessage: :return: """ # player key structure: {playerid:[[x,y],flip,name]} update_data = json.loads(updatemessage) playerid = [key for key in update_data.keys()][0] update_lst = update_data[playerid] playerid = update_lst[0] #print(update_lst) #print(playerid) print(players) if playerid == 0: return playermap[playerid][0][0] = update_lst[1] playermap[playerid][0][1] = update_lst[2] playermap[playerid][1] = update_lst[3] playermap[playerid][2] = update_lst[4] remove = [] for player_socket in players: update = {'player locations':[]} for key, value in playermap.items(): update['player locations'].append([key, value[0][0], value[0][1], value[1], value[2]]) try: print(json.dumps(update).encode()) player_socket.sendall(json.dumps(update).encode()) except Exception as e: remove.append(player_socket) print(e) continue for r in remove: players.remove(r) def client_thread(conn, player_id): while True: try: recvdata = conn.recv(bufsize) if recvdata: update_clients(recvdata) else: break except Exception as e: print(e) break playermap.pop(player_id) players.remove(conn) conn.close() # VARIABLES ------------------------------------------------------------------------------------------------------------ # MAX_PLAYER_COUNT = 15 ipport = get_ip_port("serverip.txt") s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(tuple(ipport)) s.listen(MAX_PLAYER_COUNT+1) bufsize = 2048 global playermap global players players = [] playermap = {} playerstartpos = [50,50] print("Server has started, waiting for connections.") #player key structure: {playerid:[[x,y],flip,name]} # SERVER LOOP ---------------------------------------------------------------------------------------------------------- # while True: conn, addr = s.accept() print(f"Connection from {addr}") players.append(conn) playerid = len(players) playermap[playerid] = [[playerstartpos[0], playerstartpos[1]],False,""] conn.send(json.dumps({"id update": playerid}).encode()) pthread = threading.Thread(target=client_thread, args=[conn,playerid]) pthread.start() 

and this is the code in the client.py file that receives the data from the server:

 # player key structure: {playerid:[[x,y],flip,name]} # update = {'player locations':[[value.id, value.x, value.y, value.flip, value.name]]} ins, outs, ex = select.select([n.socket], [], [], 0) for in_ in ins: data = in_.recv(2048) print(data.decode() + "\n") if data: try: socket_event = json.loads(data) except Exception as e: print(e) event_type = [key for key in socket_event.keys()][0] event_data_lst = socket_event[event_type] if event_type == 'id update': player.id = event_data_lst if event_type == 'player locations': #socket_event.pop(0) players = [] for splayer in event_data_lst: if splayer[0] != player.id: socket_player = Player((splayer[1], splayer[2]), (15,37), splayer[4], splayer[0]) socket_player.flip = splayer[3] players.append(socket_player) #else: # player.x = splayer[1] # player.y = splayer[2] 

1 Answer 1

1

here could be the problem:

 for player_socket in players: update = {'player locations':[]} for key, value in playermap.items(): update['player locations'].append([key, value[0][0], value[0][1], value[1], value[2]]) try: print(json.dumps(update).encode()) player_socket.sendall(json.dumps(update).encode()) 

so basically what happens is you send from all player_socket and that should be fine however when there are two players there are two of these loops running almost in parallel which means that you send twice from each socket(hope you understand) you should I think make it so that this for loop excludes the sender

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.