-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
182 lines (159 loc) · 7.87 KB
/
server.py
File metadata and controls
182 lines (159 loc) · 7.87 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import socket
import struct
import threading
import time
import concurrent.futures
import random
import multiprocessing
from typing import DefaultDict
from colorama import Fore, Style,Back
import scapy.all
winners_dict=DefaultDict(int) #Winners to get the highest score
"""
thread_send_Announcements & send_broadcast_suggestion:
Send the invitation to join the game through the given udp_socket.
The invitation sent is a broadcast message, and every 1 second.
"""
def send_broadcast_suggestion(udp_socket):
message = struct.pack('Ibh', 0xabcddcba, 0x2, 2101) #unsigned integer, signed char and a short (16 bit integer)
udp_socket.sendto(message, ("<broadcast>", 13117))
def thread_send_Announcements(udp_socket):
threading.Timer(1.0, thread_send_Announcements, args=[udp_socket]).start()
send_broadcast_suggestion(udp_socket)
"""
randomize_math :
Generates a simple math question, the output is a list.
The list contains the expected answer [0] and a string representing the question [1].
"""
def randomize_math(): #Randomizes a math question
num1=random.choice([1,2,3,4,5])
num2=random.choice([1,2,3,4])
expected=num1+num2
return [expected,f'{num1} + {num2}']
"""
start_new_game:
The game will end in 10 seconds, the server waits for answers from both clients.
The answer is sent with the current time stamp [1], the one who answered first either wins or loses depending on their answer.
If neither answered after 10 seconds it's a tie.
"""
def start_new_game(client,expected): #the game that everyone plays
start_time = time.time()
while time.time() - start_time < 10:
client.settimeout(10) #will exit once 10 seconds have passed
try:
message = client.recv(1024).decode("utf-8")
if message==expected:
return ("Winner",time.time())
else :
return ("Looser",time.time())
except:
pass
return ("Tie",time.time())
"""
Explanations:
Create a UDP socket that will wait for connections and send invitations.
Create a TCP socket that will get 2 connections from clients who were invited through the UDP socket.
The TCP socket will wait for 2 connections, each connection is saved into a list that will have two tuples one for each client.
We will communicate with the clients through the address recieved from them which is saved in [0] of the tuple.
The game begins once the question is sent to both of the participants.
We will wait for both clients to respond, the one who responded first will either win or lose depending on their answer.
The winner will be saved inside a dictionary that represents the leaderboard.
In the end we will send the invitations again.
"""
if __name__ == '__main__':
sockets_list = []
# SERVER_IP = socket.gethostbyname(socket.gethostname())
dev_card='eth1'
test_card='eth2'
SERVER_IP=scapy.all.get_if_addr('eth1')
PORT_NUM = 2101
print(f"Server started,listening on IP address {SERVER_IP} \nCome To me baby")
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sending_suggestions_thread = multiprocessing.Process(target=thread_send_Announcements, args=(udp_socket,))
sending_suggestions_thread.start()
<<<<<<< HEAD
global tcp_socket
=======
# while True:
# pass
# global tcp_socket
>>>>>>> f5ab53682cafd62132909f2f197b05d6b84b96c1
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_socket.bind(('', PORT_NUM))
tcp_socket.listen(2) #after 2 connections the socket will not accept new connections
with concurrent.futures.ThreadPoolExecutor(2) as executor:
while True:
client, address_1 = tcp_socket.accept()
group_name = client.recv(1024).decode("utf-8")
sockets_list.append((client, group_name))
print(f"{Fore.CYAN}Player 1{Style.RESET_ALL} connected, group name : {group_name} \nWaiting for Player 2")
client, address_2 = tcp_socket.accept()
group_name = client.recv(1024).decode("utf-8")
sockets_list.append((client, group_name))
print(f"{Fore.YELLOW}Player 2{Style.RESET_ALL} connected, group name : {group_name} \nGame will start if a few seconds")
time.sleep(2)
group1 = sockets_list[0][1]
group2 = sockets_list[1][1]
math_problem=randomize_math()
start_message = bytes(f"{Back.BLUE}Welcome to Quick Maths.{Style.RESET_ALL}\n{Fore.CYAN}Player 1: {group1}{Style.RESET_ALL}\n{Fore.YELLOW}Player 2: {group2}{Style.RESET_ALL}\n==\nPlease Answer the following question: \nHow much is {math_problem[1]}?","utf-8")
for clientadd, group_name in sockets_list:
<<<<<<< HEAD
clientadd.sendall(start_message)
"""
Send the start_new_game function to the clients and the expected answer.
"""
=======
try:
clientadd.sendall(start_message)
except:
print("Couldn't send to one of the clients")
pass
>>>>>>> f5ab53682cafd62132909f2f197b05d6b84b96c1
game1 = executor.submit(start_new_game, sockets_list[0][0],math_problem[0])
game2 = executor.submit(start_new_game, sockets_list[1][0],math_problem[0])
group1_result = game1.result()
group2_result = game2.result()
result_message = f"Game over! \nThe correct answer was {math_problem[0]}! \nCongratulations to the winner:"
if group1_result[0] =="Tie" and group2_result[0]=="Tie":
print("Tie")
result_message = bytes(f"Time's up {Back.MAGENTA}loosers{Style.RESET_ALL}, it a Tie!", "utf-8")
for clientadd, group_name in sockets_list:
try:
clientadd.sendall(result_message)
except:
print("Couldn't send to one of the clients")
pass
else:
if group1_result[1]<group2_result[1]:
if group1_result[0]=="Winner":
print(f"{group1} are the winner")
result_message = bytes(result_message + f"{group1}", "utf-8")
for clientadd, group_name in sockets_list:
clientadd.sendall(result_message)
winners_dict[group1]+=1
else:
print(f"{group2} are the winner")
result_message = bytes(result_message + f"{group2}", "utf-8")
for clientadd, group_name in sockets_list:
clientadd.sendall(result_message)
winners_dict[group2]+=1
else:
if group2_result[0]=="Winner":
print(f"{group2} are the winner")
result_message = bytes(result_message + f"{group2}", "utf-8")
for clientadd, group_name in sockets_list:
clientadd.sendall(result_message)
winners_dict[group2]+=1
else:
print(f"{group1} are the winner")
result_message = bytes(result_message + f"{group1}", "utf-8")
for clientadd, group_name in sockets_list:
clientadd.sendall(result_message)
winners_dict[group1]+=1
if len(winners_dict.keys())!=0:
print(f"{max(winners_dict, key=winners_dict.get)} Has the Highest Score on the Server")
print(f"{Fore.RED}Game over{Style.RESET_ALL}, sending out offer requests... ")
sockets_list = []
sending_suggestions_thread = multiprocessing.Process(target=thread_send_Announcements, args=(udp_socket,))
sending_suggestions_thread.start()