Improved formatting of users with colors, distinguishing of server messages, more message info

This commit is contained in:
Xevion
2021-01-09 13:16:32 -06:00
parent ab1c14adb5
commit 67236d2aa8
3 changed files with 146 additions and 37 deletions
+25 -11
View File
@@ -17,9 +17,10 @@ HEADER_LENGTH = 10
class ReceiveWorker(QThread): class ReceiveWorker(QThread):
messages = pyqtSignal(str) messages = pyqtSignal(str, str, str, int)
client_list = pyqtSignal(list) client_list = pyqtSignal(list)
error = pyqtSignal() error = pyqtSignal()
sent_nick = pyqtSignal()
def __init__(self, client: socket.socket, nickname: str, parent=None): def __init__(self, client: socket.socket, nickname: str, parent=None):
QThread.__init__(self, parent) QThread.__init__(self, parent)
@@ -29,9 +30,11 @@ class ReceiveWorker(QThread):
def run(self): def run(self):
while True: while True:
try: try:
length = int(self.client.recv(HEADER_LENGTH).decode('utf-8')) raw_length = self.client.recv(HEADER_LENGTH).decode('utf-8')
raw = self.client.recv(length).decode('utf-8') if not raw_length:
if len(raw) == 0: continue
raw = self.client.recv(int(raw_length)).decode('utf-8')
if not raw:
continue continue
message = json.loads(raw) message = json.loads(raw)
@@ -43,8 +46,9 @@ class ReceiveWorker(QThread):
'nickname': self.nickname 'nickname': self.nickname
} }
)) ))
self.sent_nick.emit()
elif message['type'] == constants.Types.MESSAGE: elif message['type'] == constants.Types.MESSAGE:
self.messages.emit(message['content']) self.messages.emit(message['nickname'], message['content'], message['color'], message['time'])
elif message['type'] == constants.Types.USER_LIST: elif message['type'] == constants.Types.USER_LIST:
self.client_list.emit(message['users']) self.client_list.emit(message['users'])
except: except:
@@ -61,9 +65,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.show() self.show()
# Get Nickname # Get Nickname
while True:
nicknameDialog = NicknameDialog(self) nicknameDialog = NicknameDialog(self)
nicknameDialog.exec_() nicknameDialog.exec_()
self.nickname = nicknameDialog.lineEdit.text() self.nickname = nicknameDialog.lineEdit.text().strip()
if len(self.nickname) > 3:
break
# Connect to server # Connect to server
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -78,10 +85,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.connectionsListTimer = QTimer() self.connectionsListTimer = QTimer()
self.connectionsListTimer.timeout.connect(self.refreshConnectionsList) self.connectionsListTimer.timeout.connect(self.refreshConnectionsList)
self.connectionsListTimer.start(1000 * 30) self.connectionsListTimer.start(1000 * 30)
self.refreshConnectionsList() self.receiveThread.sent_nick.connect(self.refreshConnectionsList)
self.messageBox.setPlaceholderText('Type your message here...')
self.messageBox.installEventFilter(self) self.messageBox.installEventFilter(self)
self.messages = []
def eventFilter(self, obj, event): def eventFilter(self, obj, event):
if event.type() == QEvent.KeyPress and obj is self.messageBox: if event.type() == QEvent.KeyPress and obj is self.messageBox:
if event.key() == Qt.Key_Return and self.messageBox.hasFocus(): if event.key() == Qt.Key_Return and self.messageBox.hasFocus():
@@ -93,14 +103,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.messageBox.setTextCursor(cursor) self.messageBox.setTextCursor(cursor)
return super().eventFilter(obj, event) return super().eventFilter(obj, event)
def addMessage(self, message: str) -> None: def addMessage(self, nickname: str, message: str, color: str, time: int) -> None:
self.messageHistory.append(message) self.messages.append([nickname, message, color, time])
self.messageHistory.append(f'&lt;<span style="color: {color}">{nickname}</span>&gt; {message}')
def sendMessage(self, message: str) -> None: def sendMessage(self, message: str) -> None:
message = message.strip()
if len(message) > 0:
self.client.send(helpers.prepare_json( self.client.send(helpers.prepare_json(
{ {
'type': constants.Types.MESSAGE, 'type': constants.Types.MESSAGE,
'content': message.strip() 'content': message
} }
)) ))
@@ -114,4 +127,5 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def updateConnectionsList(self, users): def updateConnectionsList(self, users):
self.connectionsList.clear() self.connectionsList.clear()
self.connectionsList.addItems(users)
self.connectionsList.addItems([user['nickname'] for user in users])
+58
View File
@@ -3,8 +3,66 @@ class Requests:
REFRESH_CONNECTIONS_LIST = 'REFRESH_CLIENT_LIST' REFRESH_CONNECTIONS_LIST = 'REFRESH_CLIENT_LIST'
GET_HISTORY = 'GET_HISTORY' GET_HISTORY = 'GET_HISTORY'
class Types: class Types:
SERVER_MESSAGE = 'SERVER_MESSAGE'
REQUEST = 'REQUEST' REQUEST = 'REQUEST'
NICKNAME = 'NICKNAME' NICKNAME = 'NICKNAME'
USER_LIST = 'USER_LIST' USER_LIST = 'USER_LIST'
MESSAGE = 'MESSAGE' MESSAGE = 'MESSAGE'
class Colors:
AQUA = "#00ffff"
AZURE = "#f0ffff"
BEIGE = "#f5f5dc"
BLACK = "#000000"
BLUE = "#0000ff"
BROWN = "#a52a2a"
CYAN = "#00ffff"
DARKBLUE = "#00008b"
DARKCYAN = "#008b8b"
DARKGREY = "#a9a9a9"
DARKGREEN = "#006400"
DARKKHAKI = "#bdb76b"
DARKMAGENTA = "#8b008b"
DARKOLIVEGREEN = "#556b2f"
DARKORANGE = "#ff8c00"
DARKORCHID = "#9932cc"
DARKRED = "#8b0000"
DARKSALMON = "#e9967a"
DARKVIOLET = "#9400d3"
FUCHSIA = "#ff00ff"
GOLD = "#ffd700"
GREEN = "#008000"
INDIGO = "#4b0082"
KHAKI = "#f0e68c"
LIGHTBLUE = "#add8e6"
LIGHTCYAN = "#e0ffff"
LIGHTGREEN = "#90ee90"
LIGHTGREY = "#d3d3d3"
LIGHTPINK = "#ffb6c1"
LIGHTYELLOW = "#ffffe0"
LIME = "#00ff00"
MAGENTA = "#ff00ff"
MAROON = "#800000"
NAVY = "#000080"
OLIVE = "#808000"
ORANGE = "#ffa500"
PINK = "#ffc0cb"
PURPLE = "#800080"
VIOLET = "#800080"
RED = "#ff0000"
SILVER = "#c0c0c0"
WHITE = "#ffffff"
YELLOW = "#ffff00"
ALL_NAMES = ['Aqua', 'Azure', 'Beige', 'Black', 'Blue', 'Brown', 'Cyan', 'Dark Blue', 'Dark Cyan', 'Dark Grey',
'Dark Green', 'Dark Khaki', 'Dark Magenta', 'Dark Olive Green', 'Dark Orange', ' Dark Orchid', 'Dark Red', 'Dark Salmon',
'Dark Violet', 'Fuchsia', 'Gold', 'Green', 'Indigo', 'Khaki', 'Light Blue', 'Light Cyan',
'Light Green', 'Light Grey', 'Light Pink', 'Light Yellow', 'Lime', 'Magenta', 'Maroon', 'Navy',
'Olive', 'Orange', 'Pink', 'Purple', 'Violet', 'Red', 'Silver', 'White', 'Yellow']
ALL = [AQUA, AZURE, BEIGE, BLACK, BLUE, BROWN, CYAN, DARKBLUE, DARKCYAN, DARKGREY, DARKGREEN, DARKKHAKI,
DARKMAGENTA, DARKOLIVEGREEN, DARKORANGE, DARKORCHID, DARKRED, DARKSALMON, DARKVIOLET, FUCHSIA, GOLD, GREEN,
INDIGO, KHAKI, LIGHTBLUE, LIGHTCYAN, LIGHTGREEN, LIGHTGREY, LIGHTPINK, LIGHTYELLOW, LIME, MAGENTA, MAROON,
NAVY, OLIVE, ORANGE, PINK, PURPLE, VIOLET, RED, SILVER, WHITE, YELLOW, ]
+56 -19
View File
@@ -1,18 +1,19 @@
import json import json
import random
import socket import socket
import threading import threading
import time import time
import traceback import traceback
import uuid import uuid
from pprint import pprint
import constants import constants
import helpers import helpers
from config import config
# Connection Data # Connection Data
host = '127.0.0.1' host = '127.0.0.1'
port = 55555 port = 55555
HEADER_LENGTH = int(config['DEFAULT']['HeaderLength']) HEADER_LENGTH = 10
# Starting Server # Starting Server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -23,15 +24,9 @@ server.listen()
clients = {} clients = {}
# Sending Messages To All Connected Clients def broadcast_data(data):
def broadcast(message):
print(f'"{message}"')
encoded = helpers.prepare_json({
'type': constants.Types.MESSAGE,
'content': message
})
for client in clients.values(): for client in clients.values():
client['client'].send(encoded) client['client'].send(data)
# Handling Messages From Clients # Handling Messages From Clients
@@ -51,29 +46,68 @@ def handle(client_id):
{ {
'type': constants.Types.USER_LIST, 'type': constants.Types.USER_LIST,
'users': [ 'users': [
clients[other]['nickname'] for other in clients.keys() if other != client_id {
'nickname': other['nickname'],
'color': other['color']
} for other in clients.values()
] ]
} }
)) ))
elif message['type'] == constants.Types.NICKNAME: elif message['type'] == constants.Types.NICKNAME:
nickname = message['nickname'] nickname = message['nickname']
if not clients[client_id]['has_nickname']: if not clients[client_id]['has_nickname']:
print("Nickname is {}".format(nickname)) print("Nickname is {}".format(nickname))
broadcast("{} joined!".format(nickname)) broadcast_data(helpers.prepare_json(
{
'type': constants.Types.MESSAGE,
'nickname': 'Server',
'content': f'{nickname} joined!',
'color': constants.Colors.PINK,
'time': int(time.time())
}
))
clients[client_id]['has_nickname'] = True clients[client_id]['has_nickname'] = True
else: else:
print(f'{clients[client_id]["nickname"]} changed their name to {nickname}') print(f'{clients[client_id]["nickname"]} changed their name to {nickname}')
clients[client_id]['nickname'] = nickname clients[client_id]['nickname'] = nickname
elif message['type'] == constants.Types.MESSAGE: elif message['type'] == constants.Types.MESSAGE:
broadcast(f'<{nickname}>: {message["content"]}') if message['content'] == '/reroll':
color = random.choice(constants.Colors.ALL)
colorname = constants.Colors.ALL_NAMES[constants.Colors.ALL.index(color)]
clients[client_id]['color'] = color
broadcast_data(helpers.prepare_json(
{
'type': constants.Types.MESSAGE,
'nickname': 'Server',
'content': f'Changed your color to {colorname} ({color})',
'color': constants.Colors.PINK,
'time': int(time.time())
}
))
broadcast_data(helpers.prepare_json(
{
'type': constants.Types.MESSAGE,
'nickname': nickname,
'content': message["content"],
'color': clients[client_id]['color'],
'time': int(time.time())
}
))
except: except:
# Removing And Closing Clients traceback.print_exc()
print(f'Closing Client {clients[client_id]["nickname"]}')
client.close() client.close()
del clients[client_id] del clients[client_id]
broadcast('{} left!'.format(nickname)) broadcast_data(helpers.prepare_json(
{
'type': constants.Types.MESSAGE,
'nickname': 'Server',
'content': f'{nickname} left!',
'color': constants.Colors.PINK,
'time': int(time.time())
}
))
break break
@@ -95,14 +129,17 @@ def receive():
clients[client_id] = { clients[client_id] = {
'client': client, 'client': client,
'id': client_id,
'nickname': client_id[:10], 'nickname': client_id[:10],
'first_seen': int(time.time()), 'first_seen': int(time.time()),
'has_nickname': False 'has_nickname': False,
'color': random.choice(constants.Colors.ALL)
} }
pprint(clients[client_id])
client.send(helpers.prepare_json( client.send(helpers.prepare_json(
{ {
'type': constants.Types.MESSAGE, 'type': constants.Types.SERVER_MESSAGE,
'content': 'Connected to server!' 'content': 'Connected to server!'
} }
)) ))