From 1f3304ad2d2cb6b1aec2085faa8b427b1cbef10f Mon Sep 17 00:00:00 2001 From: pjht Date: Thu, 14 May 2020 14:55:37 -0500 Subject: [PATCH] Basic server with multiple players and common map --- client.py | 35 ++++++++++- lib/player_img.py | 4 +- serv.py | 149 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 6 deletions(-) create mode 100644 serv.py diff --git a/client.py b/client.py index a1dcb48..62349dd 100644 --- a/client.py +++ b/client.py @@ -57,7 +57,9 @@ def recvall(sock): return data +UNAME=input("UNAME:") pygame.init() +pygame.display.set_caption(UNAME) screen=pygame.display.set_mode((constants.WINDWIDTH,constants.WINDHEIGHT)) running=True @@ -70,10 +72,18 @@ key_to_dir={ pygame.K_RIGHT:"right" } -map=Map(screen,None,0) +sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM) +sock.connect(("localhost",30000)) +send_str(sock,UNAME) +send_str(sock,"GET_POS") +x=int(recv_str(sock)) +y=int(recv_str(sock)) +fac=recv_str(sock) +map=Map(screen,sock) map.tiles={} -player=Player(0,0,map,screen,"PJHT","player_local") -player.direction="up" +player=Player(x,y,map,screen,"PJHT","player_local") +player.direction=fac + while running: for event in pygame.event.get(): @@ -101,8 +111,27 @@ while running: direction="right" if move: player.move(direction) + send_str(sock,"SET_POS") + send_str(sock,str(player.x)) + send_str(sock,str(player.y)) + send_str(sock,player.direction) screen.fill([0,0,0]) map.draw(player.x,player.y) player.draw() + send_str(sock,"GET_POS_MAP") + pos_map=recv_hash(sock) + print(pos_map) + for uname,pos in pos_map.items(): + if uname==UNAME: + continue + pos=eval(pos) # FIXME: Eval is dangerous + char=PlayerImg(screen,"player") + char.direction=pos[2] + offsetx=pos[0]-player.x + offsety=pos[1]-player.y + char.draw(constants.CENTERX+offsetx,constants.CENTERY+offsety) pygame.display.flip() sleep(0.1) + +send_str(sock,"CLOSE") +sock.close() diff --git a/lib/player_img.py b/lib/player_img.py index a732dfe..a4e17b8 100644 --- a/lib/player_img.py +++ b/lib/player_img.py @@ -18,10 +18,8 @@ class PlayerImg(Sprite): frames[direction]=frame_array return frames - def __init__(self,x,y,screen,type,*groups): + def __init__(self,screen,type,*groups): super().__init__(groups) - self.x=x - self.y=y self.screen=screen self.frames=self.loadFrames(type) self.frame=1 diff --git a/serv.py b/serv.py new file mode 100644 index 0000000..6303f75 --- /dev/null +++ b/serv.py @@ -0,0 +1,149 @@ +import pygame +import sys +def my_load(path): + return None +mod=sys.modules["pygame.image"] +mod.load=my_load +sys.modules["pygame.image"]=mod +import os +import random +import select +import socket +import _thread +import pickle +import signal +import glob +import os.path +import lib.constants as constants +from lib.gameregistry import GameRegistry +from lib.map import Map +from lib.character import Character +from lib.block import Block +from lib.player import Player +from time import sleep +import blocks +import pprint +player_map={} +pos_map={} +map_changes={} +next_x=0 + +def recv_str(sock): + str="" + ch="" + while True: + ch=sock.recv(1).decode("utf-8") + if ch=="\n": + break + str+=ch + # print("Got string: "+str) + return str + +def send_str(sock,str,print_str=True): + if print_str: + pass + # print("Sending string: "+str) + sock.send((str+"\n").encode("utf-8")) + +def send_hash(sock,hash): + # print("Sending hash: "+pp.pformat(hash)) + send_str(sock,str(len(hash)),False) + for key,val in hash.items(): + send_str(sock,str(key),False) + send_str(sock,str(val),False) + +def recvall(sock): + BUFF_SIZE=4096 + data=b'' + while True: + part=sock.recv(BUFF_SIZE) + data+=part + if len(part)0: + if cmd[0]=="stop": + s.close() + f=open("worlds/map_{}.pkl".format(map_name),"wb") + pickle.dump(map,f) + f.close() + exit(1) + +def exit_cleanup(signal,frame): + s.close() + f=open("worlds/map_{}.pkl".format(map_name),"wb") + pickle.dump(map,f) + f.close() + +Block.init() +files=glob.glob("worlds/map_*.pkl") +if len(files)==0: + new="y" +else: + new=input("New world?").lower() +if new=="n" or new=="no": + i=1 + map_map=[] + for name in files: + name=name.split("_") + name.pop(0) + name="_".join(name) + name,_=os.path.splitext(name) + print("{}. {}".format(i,name)) + map_map.append(name) + i+=1 + map_name=map_map[int(input("Which world?"))-1] + f=open("worlds/map_{}.pkl".format(map_name),"rb") + map=pickle.load(f) + f.close() +else: + map_name=input("World name:") + map=Map(None) + +s=socket.socket() +s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +host="localhost" +port=30000 +s.bind((host, port)) +s.listen(5) +_thread.start_new_thread(handle_cmds,()) +signal.signal(signal.SIGINT, exit_cleanup) +while True: + c,addr=s.accept() + _thread.start_new_thread(on_new_client,(c,))