-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgame_server.py
123 lines (93 loc) · 4.31 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
import tkinter as tk
from types import TracebackType
from typing import Optional, Type
from networking.server import Server
class GameServerWindow(object):
""" This class manages game server frame. """
def __init__(self) -> None:
self.parent = tk.Tk(className='Battleship - Game server')
self.parent.geometry('300x300')
self.parent.resizable(width=False, height=False)
self.parent.eval('tk::PlaceWindow . center')
# Core attributes
self.server = None
self.polling_interval = 1000
# Top frame for start and stop game server
self.top_frame = tk.Frame(self.parent)
self.start_btn = tk.Button(
self.top_frame, text='Start', command=lambda: self.start_server())
self.start_btn.pack(side=tk.LEFT)
self.stop_btn = tk.Button(
self.top_frame, text='Stop', command=lambda: self.stop_server(), state=tk.DISABLED)
self.stop_btn.pack(side=tk.LEFT)
self.top_frame.pack(side=tk.TOP, pady=(5, 0))
# Middle frame for showing Server IP address and Port
self.mid_frame = tk.Frame(self.parent)
self.lbl_host = tk.Label(self.mid_frame, text='Address: X.X.X.X')
self.lbl_host.pack(side=tk.LEFT)
self.lbl_port = tk.Label(self.mid_frame, text='Port: XXXX')
self.lbl_port.pack(side=tk.LEFT)
self.mid_frame.pack(side=tk.TOP, pady=(5, 0))
# Client frame for show connected clients
self.client_frame = tk.Frame(self.parent)
self.lbl_line = tk.Label(
self.client_frame, text='**********Client List**********').pack()
self.text_display = tk.Text(self.client_frame, height=10, width=30)
self.text_display.pack(side=tk.LEFT, fill=tk.Y, padx=(5, 0))
self.text_display.config(background='#F4F6F7',
highlightbackground='grey', state='disabled')
self.client_frame.pack(side=tk.TOP, pady=(5, 0))
# Dev sign frame
self.dev_sign_frame = tk.Frame(self.parent)
self.lbl_dev_sign = tk.Label(
self.dev_sign_frame, text='Made by jvillegasd :D')
self.lbl_dev_sign.pack(side=tk.RIGHT)
self.dev_sign_frame.pack(side=tk.BOTTOM, pady=(0, 20))
# Define a timer for client refresh polling
self.text_display.after(self.polling_interval,
self.refresh_clients_display)
def __enter__(self) -> 'GameServerWindow':
return self
def __exit__(
self,
exctype: Optional[Type[BaseException]],
excinst: Optional[BaseException],
exctb: Optional[TracebackType]) -> None:
""" This build-in function close server if window is closed. """
if self.server:
self.server.stop_server()
self.server = None
def start_server(self) -> None:
""" This function starts a new server instance. """
self.start_btn.config(state=tk.DISABLED)
self.stop_btn.config(state=tk.NORMAL)
host_address = 'localhost'
host_port = 65432
self.server = Server(host_address, host_port)
self.server.start_server()
self.lbl_host['text'] = f'Address: {host_address}'
self.lbl_port['text'] = f'Port: {host_port}'
def stop_server(self) -> None:
""" This function stops current server instances and delete it. """
self.start_btn.config(state=tk.NORMAL)
self.stop_btn.config(state=tk.DISABLED)
self.server.stop_server()
self.server = None
self.lbl_host['text'] = 'Address: X.X.X.X'
self.lbl_port['text'] = 'Port: XXXX'
def refresh_clients_display(self) -> None:
""" This function polls connected clients to current server. """
if self.server:
connected_clients = self.server.get_connected_clients()
self.text_display.config(state=tk.NORMAL)
self.text_display.delete('1.0', tk.END)
for client_name in connected_clients:
self.text_display.insert(tk.END, client_name + '\n')
self.text_display.config(state=tk.DISABLED)
self.text_display.after(self.polling_interval,
self.refresh_clients_display)
def main() -> None:
with GameServerWindow() as gs:
gs.parent.mainloop()
if __name__ == '__main__':
main()