-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathServer_start.py
121 lines (104 loc) · 4.08 KB
/
Server_start.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import pygame
import socket
import pickle
import labyrinth
import concurrent.futures
import time
import random
import threading
def server_program():
"""
Principal function that initiates the server and accepts client connections
"""
maze = labyrinth.getMaze()
goal = labyrinth.getGoal()
player_colors = [[255,188,66],[216,17,89],[226,160,255],[183,255,216],[255,220,204],[251,99,118],[100,245,141],[255,202,58],[138,201,38],[247,99,0],[237,37,78],[3,252,86],[233,223,0]]
player_coords = {}
lock = threading.Lock()
difficulty = False
# same maze and goal for every client
# maze, goal, difficulty all coded in message
message = [maze,goal,difficulty]
message = pickle.dumps(message)
message += b"746869736973746865656e64"
# dynamic hostname retreival
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
host = s.getsockname()[0]
print("Host IP is:", host)
port = 2001 # initiate port above 1024
server_socket = socket.socket() # get instance
server_socket.bind((host, port)) # bind host address and port together
server_socket.listen(5)
# thread method executer to run indefinitly, accept client connections, and handle clients
with concurrent.futures.ThreadPoolExecutor() as executor:
while True:
client_sock, client_addr = server_socket.accept()
print("Client Connected")
executor.submit(handle_client, client_sock, message, player_coords, lock)
executor.submit(data_receiver, client_sock, player_coords, client_addr, player_colors, lock)
def data_receiver(client_socket, dict, client_addr, player_colors, lock):
"""
Threaded function to handle client coordinate updates
:param client_socket: the socket a particular client is using
:param dict: dictionary containing the current coordinates for every client (key client_addr, value array of coordinates)
:param client_addr: the IP address of a connection
:param player_colors: array containing unique colors in RGB format
"""
# assign players a unique random color from dictionary
player_color = random.choice(player_colors)
player_colors.remove(player_color)
# constantly receive updates from player
while(True):
try:
data = b''
# waits to receive entire message based on bytestring
while b"746869736973746865656e647373737373737373" not in data:
packet = client_socket.recv(4096)
data += packet
lock.acquire()
cord_array = pickle.loads(data)
lock.release()
# player left the game
if(cord_array == "quit"):
#delete player
lock.acquire()
del dict[client_addr]
lock.release()
print("Client disconnected")
# player won - send to all players
elif(cord_array == "win"):
lock.acquire()
dict[client_addr] = "win"
lock.release()
# update player coord array
else:
lock.acquire()
cord_array.append(player_color)
dict[client_addr] = cord_array
lock.release()
except:
lock.release()
break
def handle_client(sock, message, dict, lock):
"""
Threaded function to initialize and update clients
:param sock: the socket a particular client is using
:param message: the maze and goal as a pickled object
:param dict: the dictionary containing all player coordinates
"""
sock.send(message) #the maze and goal are sent to the client
# constantly send updates to client
while True:
try:
lock.acquire()
cord_msg = pickle.dumps(dict)
cord_msg += b"746869736973746865656e64"
sock.send(cord_msg)
lock.release()
time.sleep(.03)
except:
lock.release()
break
if __name__ == '__main__':
server_program()