Some network & other fixes
parent
eba911af01
commit
b6fc2e001f
|
@ -10,7 +10,8 @@
|
|||
"request": "launch",
|
||||
"program": "${file}",
|
||||
//"args": ["--sizeable", "--server"],
|
||||
"args": ["--sizeable", "--player", "1", "127.0.0.1"],
|
||||
"args": ["--sizeable", "--player", "1", "localhost"],
|
||||
//"args": ["--sizeable", "--viewer", "127.0.0.1"],
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -92,11 +92,14 @@ Then to run a headless game server instance use
|
|||
|
||||
To connect player #1, use
|
||||
|
||||
./pp_player1.sh
|
||||
./pp_player1.sh <remote_host_ip_or_name>
|
||||
|
||||
where <remote_host_ip_or_name> may be "127.0.0.1" or localhost or any other internet
|
||||
host.
|
||||
|
||||
To connect player #2, use
|
||||
|
||||
./pp_player2.sh
|
||||
./pp_player2.sh <remote_host_ip_or_name>
|
||||
|
||||
If you want to access a remote game server, edit the IP address within
|
||||
the cl1.sh or cl2.sh file respectively.
|
||||
|
@ -107,7 +110,7 @@ To achieve this, substitute --sizeable by --fullscreen in both files.
|
|||
|
||||
Finally, you may also connect one pure view client as
|
||||
|
||||
./pp_viewer.sh
|
||||
./pp_viewer.sh <remote_host_ip_or_name>
|
||||
|
||||
### 2.3 Scoring ###
|
||||
A game is won by the player who first reaches 10 points.
|
||||
|
|
|
@ -32,6 +32,15 @@ class PongGame:
|
|||
[vs.Thread(i, self) for i in range(3)] # Spawn player listeners & streams
|
||||
print("Game server started & listening ...")
|
||||
|
||||
def reinit(self):
|
||||
"""Reinit game stats & settings"""
|
||||
print("Match reset, ready for next round ...")
|
||||
self.state = pgc.STATE_START
|
||||
self.delay = 0
|
||||
self.p1_game = 0
|
||||
self.p2_game = 0
|
||||
self.playsound = pgc.NOSOUND # Play the provided sound & reset locally
|
||||
|
||||
def game_fsm(self, player1, player2):
|
||||
"""Game engine state machine"""
|
||||
|
||||
|
@ -164,16 +173,16 @@ class PongGame:
|
|||
|
||||
def pong_game(self, ball, player1, player2):
|
||||
|
||||
if (pgv.bIsServer == True) or (pgv.bIsLocal == True):
|
||||
if (pgv.bIsServer == True) or (pgv.bIsLocal == True): # Game engine runs locally or on server only!
|
||||
if self.game_fsm(player1, player2) == False: # Exit
|
||||
return False
|
||||
|
||||
# 1. Retrieve user entries
|
||||
if pgv.bIsServer == True:
|
||||
bChanged = player1.eval_socket(player2)
|
||||
else:
|
||||
bChanged = player1.eval_gamepad()
|
||||
bChanged = player2.eval_gamepad()
|
||||
bChanged = player1.eval_socket(player2) # Either from network inputs
|
||||
else:
|
||||
bChanged = player1.eval_gamepad() # Or from actual USB gamepad inputs
|
||||
bChanged = player2.eval_gamepad()
|
||||
|
||||
if (pgv.bIsServer == True) or (pgv.bIsLocal == True):
|
||||
if self.state == pgc.STATE_PLAY: # Actually playing?
|
||||
|
@ -195,7 +204,11 @@ class PongGame:
|
|||
player1.score = player1.score + 1
|
||||
ball.reinit(-(8 + (random() - 0.5) * 4), (random() - 0.5) * 10)
|
||||
self.playsound = pgc.PLAYERMISSSOUND
|
||||
|
||||
else: # This is a remote player or a viewer ...
|
||||
if self.state == pgc.STATE_EXIT: # If we're on exit, terminate!
|
||||
if self.delay <= 10: # But permit some exit sound play ...
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
|
|
@ -55,7 +55,8 @@ class PongPlayer:
|
|||
if (player_index == 1) and (bThisIsTheServer): # Is this THE server? (But init. only once!)
|
||||
UDP_PACKET_SIZE = struct.calcsize(pgc.UDP_TRANSFER_FORMAT) # Size of receiver buffer
|
||||
serverUDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP Receiver
|
||||
serverUDP.bind(("127.0.0.1", pgc.PANDEMIC_PONG_PORT)) # Localhost
|
||||
#serverUDP.bind(("127.0.0.1", pgc.PANDEMIC_PONG_PORT)) # Localhost
|
||||
serverUDP.bind(("localhost", pgc.PANDEMIC_PONG_PORT)) # Localhost
|
||||
serverUDP.setblocking(False) # Do not block ...
|
||||
|
||||
self.state = pgc.BTN_STATE_NONE # Button mask (as listed above)
|
||||
|
|
|
@ -231,6 +231,7 @@ class pongWindow(QMainWindow):
|
|||
|
||||
if self.game.pong_game(self.ball, self.player1, self.player2) == False:
|
||||
# Quit gracefully
|
||||
print("Player exiting ...")
|
||||
self.player2.exit()
|
||||
self.player1.exit()
|
||||
sys.exit(0)
|
||||
|
|
|
@ -56,9 +56,10 @@ def init_server_socket():
|
|||
class ViewServer:
|
||||
"""View server (one only instantiated)"""
|
||||
|
||||
def __init__(self):
|
||||
self.tcpClientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.tcpClientSocket.connect((socket.gethostname(), pgc.PANDEMIC_PONG_PORT))
|
||||
def __init__(self, player_server):
|
||||
self.player_server = player_server
|
||||
self.tcpClientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.tcpClientSocket.connect((self.player_server, pgc.PANDEMIC_PONG_PORT))
|
||||
self.tcpClientSocket.send("GET / HTTP/1.1\r\n\r\n".encode()) # Initiate streaming on server
|
||||
# Will return:
|
||||
# HTTP/1.0 200 OK
|
||||
|
@ -67,22 +68,30 @@ class ViewServer:
|
|||
# Date: Mon, 30 Nov 2020 09:59:52 GMT
|
||||
# Content-type: application/octet-stream
|
||||
# <CR/LF><CR/LF><CR/LF>
|
||||
msg = self.tcpClientSocket.recv(130).decode() # Skip server header
|
||||
print("Searching stream packet start ... ", end="")
|
||||
msg = self.tcpClientSocket.recv(120).decode() # Skip server header
|
||||
print("Searching stream packet start ... ")
|
||||
self.tcpClientSocket.setblocking(False) # Do not block ...
|
||||
iCount = 0
|
||||
iCountRec = 0
|
||||
iCountErr = 0
|
||||
while True: # Hunting ffa0 (little endian: a0, ff!)
|
||||
data = self.tcpClientSocket.recv(1)
|
||||
if data == b'\xa0':
|
||||
data = self.tcpClientSocket.recv(1)
|
||||
if data == b'\xff':
|
||||
break
|
||||
iCount += 1 # Count retries
|
||||
if iCount > TCP_PACKET_SIZE: # Somethin's wrong here ...
|
||||
raise BlockingIOError # Well, some error ...
|
||||
|
||||
try:
|
||||
data = self.tcpClientSocket.recv(1)
|
||||
if data == b'\xa0':
|
||||
data = self.tcpClientSocket.recv(1)
|
||||
if data == b'\xff':
|
||||
break
|
||||
iCountRec += 1 # Count retries
|
||||
if iCountRec > TCP_PACKET_SIZE: # Somethin's wrong here ...
|
||||
print(" Giving up, no data synchronization marker ...")
|
||||
raise BlockingIOError # Well, some error ...
|
||||
except BlockingIOError: # Always on empty receives ...
|
||||
iCountErr += 1 # Count <no data> ...
|
||||
if iCountErr > 8191:
|
||||
print(" Giving up, no data from server received ...")
|
||||
raise BlockingIOError
|
||||
|
||||
data = self.tcpClientSocket.recv(TCP_PACKET_SIZE-2) # Skip complete packet
|
||||
print("detected! Receiving stream ...")
|
||||
print("Detected after {} empty packets, {} bytes skipped!\nReceiving stream now ...".format(iCountErr, iCountRec))
|
||||
|
||||
def receive_data(self):
|
||||
"""Client receiver function"""
|
||||
|
|
|
@ -87,7 +87,7 @@ if __name__ == '__main__':
|
|||
game = PongGame(pgv.bIsServer)
|
||||
ball = PongObject(pgc.GAMEAREA_MAX_X/2, pgc.GAMEAREA_MAX_Y/2, 20, 20, 8.0, 2.5)
|
||||
if player_index == 0: # Local or viewer or server?
|
||||
if pgv.bIsServer == True: # Server & viewer version, no gamepads locally avail.
|
||||
if (pgv.bIsServer == True) or (pgv.bIsViewer == True): # Server & viewer version, no gamepads locally avail.
|
||||
player1 = PongPlayer(None, True, 1, "", 10, pgc.GAMEAREA_MAX_Y/2-50, 20, 160)
|
||||
player2 = PongPlayer(None, True, 2, "", pgc.GAMEAREA_MAX_X-40, pgc.GAMEAREA_MAX_Y/2-50, 20, 160)
|
||||
else: # Local version (both gamepads assumed locally connected)
|
||||
|
@ -107,8 +107,8 @@ if __name__ == '__main__':
|
|||
vs.init_send_structures(game, player1, player2, ball)
|
||||
|
||||
# 3 View clients permissible
|
||||
if (player_index > 0) or (pgv.bIsViewer): # i.e. NOT local only
|
||||
viewserver = vs.ViewServer() # Create a view server
|
||||
if (player_index > 0) or (pgv.bIsViewer == True): # i.e. NOT local only
|
||||
viewserver = vs.ViewServer(player_server) # Create a view server
|
||||
else: # Local
|
||||
viewserver = None
|
||||
|
||||
|
@ -131,11 +131,11 @@ if __name__ == '__main__':
|
|||
else: # Headless server-side game loop
|
||||
while True:
|
||||
try:
|
||||
if game.pong_game(ball, player1, player2) == False:
|
||||
break # Regular game exit
|
||||
if game.pong_game(ball, player1, player2) == False: # Player game ended
|
||||
game.reinit() # Re-init on server
|
||||
time.sleep(0.025) # Yield to other threads ...
|
||||
except KeyboardInterrupt:
|
||||
print("Server stopped by user.")
|
||||
print("\rPandemic Pong Server stopped by user.")
|
||||
break
|
||||
|
||||
# Quit gracefully
|
||||
|
|
|
@ -1,2 +1,8 @@
|
|||
# Client, player #1
|
||||
./pandemic_pong.py --sizeable --player 1 127.0.0.1
|
||||
# Pandemic Pong Player #1
|
||||
if [ -z $1 ]; then
|
||||
echo "usage: ./pp_player1.sh <gameserver>"
|
||||
exit
|
||||
fi
|
||||
|
||||
./pandemic_pong.py --sizeable --player 1 $1
|
||||
echo "Pandemic Pong player #1 client terminated."
|
|
@ -1,2 +1,8 @@
|
|||
# Client, player #2
|
||||
./pandemic_pong.py --sizeable --player 2 127.0.0.1
|
||||
# Pandemic Pong Player #2
|
||||
if [ -z $1 ]; then
|
||||
echo "usage: ./pp_player2.sh <gameserver>"
|
||||
exit
|
||||
fi
|
||||
|
||||
./pandemic_pong.py --sizeable --player 2 $1
|
||||
echo "Pandemic Pong player #2 client terminated."
|
10
pp_viewer.sh
10
pp_viewer.sh
|
@ -1,2 +1,8 @@
|
|||
# View client only
|
||||
./pandemic_pong.py --sizeable --viewer 127.0.0.1
|
||||
# Pandemic Pong Viewer
|
||||
if [ -z $1 ]; then
|
||||
echo "usage: ./pp_viewer.sh <gameserver>"
|
||||
exit
|
||||
fi
|
||||
|
||||
./pandemic_pong.py --sizeable --viewer $1
|
||||
echo "Pandemic Pong View Client terminated."
|
||||
|
|
Loading…
Reference in New Issue