class Client: def importScripts(self): self.decEncHelper = DecodingEncodingHelper() self.inputHandler = InputHandler(self.output) self.fileHelper = FileHelper(self.output) self.guiHelper = GUIHelper(self.output) def setConfig(self): Config = self.fileHelper.getConfig() self.ipV4 = Config.ip self.port = Config.port def inizializeClient(self, username, password): self.clientObject = ClientObject(username, None, self.ipV4, self.port, "Welcome_Channel") self.connected = False self.password = password def tryConnect(self): try: self.clientObject.socketObject = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.clientObject.socketObject.connect((self.clientObject.ip, self.clientObject.port)) threading.Thread(target=ServerHandler,args=[self.clientObject,self.windows]).start() self.clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("011" + self.clientObject.username + ":" + self.password)) self.connected = True except: self.connected = False def sendInput(self, message): if self.connected: if str(message).startswith("/"): self.inputHandler.handleInput(str(message[1:]), self.clientObject) else: self.output.append("you: " + message) try: self.clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("001" + message)) except: self.connected = False else: self.guiHelper.printOutput("not connected") def __init__(self, username, password, windows): #Imports self.windows = windows self.output = self.windows[0].output self.importScripts() #Config self.setConfig() #Client initializations self.inizializeClient(username, password) #Client trying to establish a connection self.tryConnect()
class ServerHandler: def __init__(self, clientObject, windows): mainWindow = windows[0] loginWindow = windows[1] self.guiHelper = GUIHelper(mainWindow.output) self.clientObject = clientObject self.easyRequestIds = ["001", "023", "401", "411", "031", "411", "711"] self.channelTreeList = list() self.kicked = False self.banned = False self.serverOffline = False while True: try: request = str(self.clientObject.socketObject.recv(1024), "utf-8") self.handleRequest(request, mainWindow, loginWindow) except: if self.kicked: self.guiHelper.printOutput( "[Client/Info] Press enter to quit") raise SystemExit() elif self.banned: self.guiHelper.printOutput( "[Client/Info] Press enter to quit") raise SystemExit() elif self.serverOffline: self.guiHelper.printOutput( "[Client/Info] Press enter to quit") raise SystemExit() def handleRequest(self, request, mainWindow, loginWindow): requestId = request[:3] requestdata = request[3:] if requestId in self.easyRequestIds: self.guiHelper.printOutput(requestdata) elif requestId == "402": print("[Client/Info] You got kicked by the console.") self.kicked = True elif requestId == "403": print("[Client/Info]Server shut down.") self.serverOffline = True elif requestId == "022": count = 0 countAtt = 0 channelNames = list() channelDescriptions = list() channelPasswords = list() channelAccessLevels = list() channelAttributes = requestdata.split(":") self.guiHelper.printOutput("[Client/Info] Channels: ") for attributeList in channelAttributes: attributes = attributeList.split(",") for attribute in attributes: attribute = attribute.replace("'", " ").strip("[]").strip() if countAtt == 0: channelNames.append(attribute) elif countAtt == 1: channelDescriptions.append(attribute) elif countAtt == 2: channelPasswords.append(attribute) else: channelAccessLevels.append(attribute) countAtt = countAtt + 1 for name in channelNames: self.guiHelper.printOutput(name + " desc: " + channelDescriptions[count] + " pw: " + channelPasswords[count] + " accessLevel: " + channelAccessLevels[count]) count = count + 1 elif requestId == "611": print("deleted") elif requestId == "405": self.guiHelper.printOutput(requestdata) self.banned = True elif requestId == "811": self.clientObject.socketObject.sendall( DecodingEncodingHelper().stringToBytes("901")) elif requestId == "903": mainWindow.statusButton.setText("Online Connected as: " + self.clientObject.username) self.clientObject.socketObject.sendall( DecodingEncodingHelper().stringToBytes("901")) elif requestId == "901": count = 0 mainWindow.channelTree.clear() requestdata = requestdata.strip("[]") requestdata = requestdata.split(";") for channel in requestdata: if count == 0: channel = channel.strip('"') channel = channel.replace(" '", "") channel = channel.strip("'") else: channel = channel.strip('"') channel = channel.replace(" '", "") channel = channel.strip("'") channel = channel[1:] channel = channel.strip() channel = channel.strip('"') channel = channel.split(":") channelName = channel[0] member = channel[1] member = member.strip("[]") member = member.split(",") channelItem = QTreeWidgetItem([channelName]) for mem in member: mem = mem.strip("'") clientItem = QTreeWidgetItem(["-" + mem]) channelItem.addChild(clientItem) mainWindow.channelTree.addTopLevelItem(channelItem) mainWindow.channelTree.expandAll() count = count + 1 elif requestId == "904": var = None #rank = requestdata elif requestId == "902": mainWindow.mainHide() loginWindow.loginShow() loginWindow.loginUsername.setText("") loginWindow.loginPassword.setText("") loginWindow.info.setText("Wrong password username combination.") elif len(requestId) == 0: raise SystemExit() else: self.guiHelper.printOutput( "[Client/Error] Server sent unknown requestId: " + requestId)
class InputHandler: commandList = list() def initializeCommands(self): self.cmdClear = self.createCommand("Clear", "/clear", "NONE", "Clears your interpreter console.") self.cmdHelp = self.createCommand("Help", "/help", "NONE", "Shows a list of available commands.") self.cmdSetName = self.createCommand("SetName", "/setName <Name>", "NAME", "Changes your name to the specified one.") self.cmdListChannel = self.createCommand("ListChannel", "/listChannel", "NONE", "Lists all Channel.") self.cmdChangeChannel = self.createCommand("ChangeChannel", "/changeChannel <CHANNEL NAME>", "ChannelName", "Enter the specified channel.") self.cmdDisconnect = self.createCommand("Disconnect", "/disconnect", "NONE", "Disconnects you from the server.") self.cmdListClients = self.createCommand("ListClients", "/listClients <CHANNEL NAME>", "Channel Name", "Shows you a list of clients connected to the specified channel.") self.cmdKick = self.createCommand("Kick", "/kick <name/ip>", "<NAME/IP>", "Kicks the specified client from the server.") self.cmdBan = self.createCommand("Ban", "/ban <name/ip> <time>", "<NAME/IP> <TIME>", "Bans the specified client for the given amount of time in minutes.") def createCommand(self, name, syntax, arguments, description): command = Command(name, syntax, arguments, description) self.commandList.append(command) return command def __init__(self, output): #Imports self.decEncHelper = DecodingEncodingHelper() self.guiHelper = GUIHelper(output) #Create Commands self.initializeCommands() def handleInput(self, command, clientObject): isCommand = True command = command.split() try: var = command[0] except IndexError: isCommand = False self.guiHelper.printOutput("[Client/Error] type /help for a list of commands") if isCommand: if str(command[0]).lower() == self.cmdClear.name: os.system('cls' if os.name=='nt' else 'clear') elif str(command[0]).lower() == self.cmdHelp.name: self.guiHelper.printOutput("[Client/Info] Commands:") self.guiHelper.printOutput("----------------------------------------------------------") for command in self.commandList: self.guiHelper.printOutput(command.syntax + " : " + command.description) self.guiHelper.printOutput("----------------------------------------------------------") elif str(command[0]).lower() == self.cmdListChannel.name: clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("022")) elif str(command[0]).lower() == self.cmdChangeChannel.name: newChannelName = None try: newChannelName = command[1] except IndexError: self.guiHelper.printOutput("[Client/Error] Syntax: " + self.cmdChangeChannel.syntax) if newChannelName != None: clientObject.channel = newChannelName clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("023" + newChannelName)) time.sleep(0.1) clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("611" + newChannelName)) time.sleep(0.1) clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("901")) elif str(command[0]).lower() == self.cmdSetName.name: newUsername = None try: newUsername = command[1] except IndexError: self.guiHelper.printOutput("[Client/Error] Syntax: " + self.cmdSetName.syntax) if newUsername != None: clientObject.username = newUsername clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("031" + newUsername)) elif str(command[0]).lower() == self.cmdDisconnect.name: clientObject.socketObject.shutdown(1) clientObject.socketObject.close() elif str(command[0]).lower() == self.cmdListClients.name: channel = None try: channel = command[1] except: self.guiHelper.printOutput("[Client/Error] Syntax: " + self.cmdListClients.syntax) if channel != None: clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("611" + channel)) elif str(command[0]).lower() == self.cmdKick.name: client = None try: client = command[1] except: self.guiHelper.printOutput("[Client/Error] Syntax: " + self.cmdKick.syntax) if client != None: clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("411" + client)) elif str(command[0]).lower() == self.cmdBan.name: client = None banTime = None try: client = command[1] banTime = command[2] except: self.guiHelper.printOutput("[Client/Error] Syntax: " + self.cmdBan.syntax) if client != None and banTime != None: clientObject.socketObject.sendall(self.decEncHelper.stringToBytes("711" + client + " " + banTime)) else: self.guiHelper.printOutput("[Client/Error] Unknown command: " + command[0]) self.guiHelper.printOutput("[Client/Error] type /help for a list of commands")
class Client: def importScripts(self): self.decEncHelper = DecodingEncodingHelper() self.inputHandler = InputHandler(self.output) self.fileHelper = FileHelper(self.output) self.guiHelper = GUIHelper(self.output) def setConfig(self): Config = self.fileHelper.getConfig() self.ipV4 = Config.ip self.port = Config.port def inizializeClient(self, username, password): self.clientObject = ClientObject(username, None, self.ipV4, self.port, "Welcome_Channel") self.connected = False self.password = password def button(self): if self.mainWindow.statusButton.text() != "Offline": self.sendInput("/disconnect") self.mainWindow.statusButton.setText("Offline") self.mainWindow.output.clear() self.mainWindow.channelTree.clear() self.connected = False else: data = CustomDialog().getData() if data == ":": self.mainWindow.close() else: data = data.split(":") self.inizializeClient(data[0], data[1]) self.tryConnect() def tryConnect(self): trys = 0 while not self.connected: try: self.clientObject.socketObject = socket.socket( socket.AF_INET, socket.SOCK_STREAM) self.clientObject.socketObject.connect( (self.clientObject.ip, self.clientObject.port)) threading.Thread(target=ServerHandler, args=[self.clientObject, self.mainWindow]).start() self.clientObject.socketObject.sendall( self.decEncHelper.stringToBytes( "011" + self.clientObject.username + ":" + self.password)) self.connected = True except: trys = trys + 1 os.system('cls' if os.name == 'nt' else 'clear') self.guiHelper.printOutput( "[Client/Info] Attempting to connect to server with ip: " + self.clientObject.ip + ". Attempts: " + str(trys)) time.sleep(5) def sendInput(self, message): if self.connected: if str(message).startswith("/"): self.inputHandler.handleInput(str(message[1:]), self.clientObject) else: self.output.append("you: " + message) try: self.clientObject.socketObject.sendall( self.decEncHelper.stringToBytes("001" + message)) except: self.connected = False else: self.guiHelper.printOutput("not connected") def __init__(self, username, password, mainWindow): #Imports self.mainWindow = mainWindow self.mainWindow.statusButton.clicked.connect(self.button) self.output = mainWindow.output self.importScripts() #Config self.setConfig() #Client initializations self.inizializeClient(username, password) #Client trying to establish a connection self.tryConnect()
class FileHelper: def createDefaultPaths(self): if not os.path.exists("config/"): os.makedirs("config/") def createDefaultFiles(self): if not os.path.isfile("config/config.json"): self.createDefaultConfig() def writeJsonFile(self, path, fileName, dataToBeWritten): fileToWrite = open(path + fileName + ".json", "w") json.dump(dataToBeWritten, fileToWrite, indent=4) def readJsonFile(self, path, fileName): fileToRead = open(path + fileName + ".json", "r") try: return json.load(fileToRead) except json.decoder.JSONDecodeError: self.guiHelper.printOutput("[Client/Error] Config file couldn't be read.") self.generateNew = True self.createDefaultConfig() def createDefaultConfig(self): if self.generateNew: self.guiHelper.printOutput("[Client/Error] Removin old one and generating the default one.") os.remove("config/config.json") config = { "Server Config": [ {"ip": "localhost"}, {"port": 5000} ], # "Other Config": [ # {"None": "None"} # ] } else: config = { "Server Config": [ {"ip": "localhost"}, {"port": 5000} ], # "Other Config": [ # {"None": "None"} # ] } self.writeJsonFile("config/", "config", config) def __init__(self, output): #imports self.guiHelper = GUIHelper(output) #default boolean self.generateNew = False #create default paths self.createDefaultPaths() #create default files self.createDefaultFiles() def getConfig(self): try: config = self.readJsonFile("config/", "config") serverConfig = config["Server Config"] return Config(serverConfig[0]["ip"], serverConfig[1]["port"]) except TypeError: self.guiHelper.printOutput("[Client/Error] Please restart your client.") raise SystemExit()