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

View File

@@ -17,9 +17,10 @@ HEADER_LENGTH = 10
class ReceiveWorker(QThread):
messages = pyqtSignal(str)
messages = pyqtSignal(str, str, str, int)
client_list = pyqtSignal(list)
error = pyqtSignal()
sent_nick = pyqtSignal()
def __init__(self, client: socket.socket, nickname: str, parent=None):
QThread.__init__(self, parent)
@@ -29,9 +30,11 @@ class ReceiveWorker(QThread):
def run(self):
while True:
try:
length = int(self.client.recv(HEADER_LENGTH).decode('utf-8'))
raw = self.client.recv(length).decode('utf-8')
if len(raw) == 0:
raw_length = self.client.recv(HEADER_LENGTH).decode('utf-8')
if not raw_length:
continue
raw = self.client.recv(int(raw_length)).decode('utf-8')
if not raw:
continue
message = json.loads(raw)
@@ -43,8 +46,9 @@ class ReceiveWorker(QThread):
'nickname': self.nickname
}
))
self.sent_nick.emit()
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:
self.client_list.emit(message['users'])
except:
@@ -61,9 +65,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.show()
# Get Nickname
while True:
nicknameDialog = NicknameDialog(self)
nicknameDialog.exec_()
self.nickname = nicknameDialog.lineEdit.text()
self.nickname = nicknameDialog.lineEdit.text().strip()
if len(self.nickname) > 3:
break
# Connect to server
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -78,10 +85,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.connectionsListTimer = QTimer()
self.connectionsListTimer.timeout.connect(self.refreshConnectionsList)
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.messages = []
def eventFilter(self, obj, event):
if event.type() == QEvent.KeyPress and obj is self.messageBox:
if event.key() == Qt.Key_Return and self.messageBox.hasFocus():
@@ -93,14 +103,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
self.messageBox.setTextCursor(cursor)
return super().eventFilter(obj, event)
def addMessage(self, message: str) -> None:
self.messageHistory.append(message)
def addMessage(self, nickname: str, message: str, color: str, time: int) -> None:
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:
message = message.strip()
if len(message) > 0:
self.client.send(helpers.prepare_json(
{
'type': constants.Types.MESSAGE,
'content': message.strip()
'content': message
}
))
@@ -114,4 +127,5 @@ class MainWindow(QMainWindow, Ui_MainWindow):
def updateConnectionsList(self, users):
self.connectionsList.clear()
self.connectionsList.addItems(users)
self.connectionsList.addItems([user['nickname'] for user in users])

View File

@@ -3,8 +3,66 @@ class Requests:
REFRESH_CONNECTIONS_LIST = 'REFRESH_CLIENT_LIST'
GET_HISTORY = 'GET_HISTORY'
class Types:
SERVER_MESSAGE = 'SERVER_MESSAGE'
REQUEST = 'REQUEST'
NICKNAME = 'NICKNAME'
USER_LIST = 'USER_LIST'
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, ]

View File

@@ -1,18 +1,19 @@
import json
import random
import socket
import threading
import time
import traceback
import uuid
from pprint import pprint
import constants
import helpers
from config import config
# Connection Data
host = '127.0.0.1'
port = 55555
HEADER_LENGTH = int(config['DEFAULT']['HeaderLength'])
HEADER_LENGTH = 10
# Starting Server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -23,15 +24,9 @@ server.listen()
clients = {}
# Sending Messages To All Connected Clients
def broadcast(message):
print(f'"{message}"')
encoded = helpers.prepare_json({
'type': constants.Types.MESSAGE,
'content': message
})
def broadcast_data(data):
for client in clients.values():
client['client'].send(encoded)
client['client'].send(data)
# Handling Messages From Clients
@@ -51,29 +46,68 @@ def handle(client_id):
{
'type': constants.Types.USER_LIST,
'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:
nickname = message['nickname']
if not clients[client_id]['has_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
else:
print(f'{clients[client_id]["nickname"]} changed their name to {nickname}')
clients[client_id]['nickname'] = nickname
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:
# Removing And Closing Clients
traceback.print_exc()
print(f'Closing Client {clients[client_id]["nickname"]}')
client.close()
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
@@ -95,14 +129,17 @@ def receive():
clients[client_id] = {
'client': client,
'id': client_id,
'nickname': client_id[:10],
'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(
{
'type': constants.Types.MESSAGE,
'type': constants.Types.SERVER_MESSAGE,
'content': 'Connected to server!'
}
))