-
Notifications
You must be signed in to change notification settings - Fork 0
/
game_server.py
128 lines (109 loc) · 4.23 KB
/
game_server.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
122
123
124
125
126
127
128
import pickle
import socket
import threading
import time
from select import select
from typing import List
from requests import get
class GameServer:
def __init__(self, listen_ip: str, port: int, client_list: List[socket.socket]):
self.client_list: List[socket.socket] = client_list
self.data_dict = {}
self.players = {}
self.game_running = True
self.server_socket = socket.socket()
self.listen_ip = listen_ip
self.port = port
self.winner = ""
def run(self):
time_at_start = str(time.time())
# Notify each client of game start
for client in self.client_list:
# self.notify_client_of_game_start(client, time_at_start, self.current_game_port)
threading.Thread(
target=self.notify_client_of_game_start,
args=(client, time_at_start, self.port),
).start()
self.server_socket.bind((self.listen_ip, self.port))
self.server_socket.listen(1)
# Connect all the clients playing
self.connect_clients()
# Pass information between the players
while self.game_running:
print("hi")
read_list, write_list, _ = select(self.client_list, self.client_list, [])
try:
self.handle_read(read_list)
self.handle_write(write_list)
except Exception as e:
print(e)
break
self.server_socket.close()
print(self.players)
return self.winner, self.players.values()
@staticmethod
def notify_client_of_game_start(client, time_at_start, server_port):
client.send(f"Started%{time_at_start},{server_port}".encode())
def handle_read(self, read_list: List[socket.socket]):
"""Handles reading from the clients"""
for client in read_list:
data = client.recv(25600)
try:
data = pickle.loads(data)
except EOFError:
print("data", data.decode())
self.game_running = False
self.players.pop(client)
self.client_list.remove(client)
continue
# Game ended, someone won
if data[0] == "W":
self.data_dict = {}
for other_client in self.client_list:
if other_client is client:
continue
other_client.send(pickle.dumps(["Win", 0, 0]))
self.winner = self.players[other_client]
self.game_over()
return
# Send the screen from one client to another
else:
for other_client in self.client_list:
if other_client is client:
continue
self.data_dict[other_client] = pickle.dumps(data)
def game_over(self):
"""End the game"""
self.game_running = False
def handle_write(self, write_list: List[socket.socket]):
"""Handles writing from the client"""
# Send every client their foe's screen
for client in write_list:
foe_data = self.data_dict.get(client)
# A screen is available to send
if foe_data:
self.data_dict.pop(client)
client.send(foe_data)
def connect_clients(self):
players = len(self.client_list)
for _ in range(players):
client, addr = self.server_socket.accept()
name = client.recv(1024).decode()
client.send("ok".encode())
self.players[client] = name
self.client_list.append(client)
self.client_list = [
sock for sock in self.client_list if sock.getsockname()[1] == self.port
]
def get_outer_ip():
return get("https://api.ipify.org").text
def get_inner_ip():
return socket.gethostbyname(socket.gethostname())
if __name__ == "__main__":
outer_ip = get_outer_ip()
inner_ip = get_inner_ip()
print("server starts on", outer_ip, inner_ip)
server = GameServer(outer_ip, inner_ip, True, "test room")
# Add the room to the database
# server.server_communicator.create_room(DBPostCreator.create_db_post(ip))
server.run()