/// <summary> /// Handles the individual assembly requests sent by the client. /// </summary> /// <param name="messageStruct">Message received from the client containing the assembly details</param> /// <param name="socket">The websocket socket used to send back the assembled bytes to the client.</param> private void ReceiveMessage(Message.MessageStruct messageStruct, ReloadedSocket socket) { switch ((MessageTypes)messageStruct.MessageType) { case MessageTypes.Assemble: Assemble(DeserializeX86Mnemonics(messageStruct.Data), socket); break; case MessageTypes.ReportAssembler: Report(socket); break; } }
/// <summary> /// Automatically Replies "Okay" to a client. /// </summary> /// <param name="clientSocket">The socket to which the "ok" message should be sent.</param> public static void ReplyOk(ReloadedSocket clientSocket) { // Send back empty message struct Message.MessageStruct messageStruct = new Message.MessageStruct(); messageStruct.MessageType = (ushort)MessageTypes.MessageType.Okay; messageStruct.Data = new byte[1]; clientSocket.SendData(messageStruct, false); }
/// <summary> /// Send the data in a byte array to the server. /// Expects a delegate to be assigned to ProcessBytesMethod which will handle the data. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object connected to either a host or client.</param> /// <param name="message">The message that is to be sent to the server.</param> /// <param name="awaitResponse">Set true to wait for a response from the server, else false.</param> /// <param name="receiveDataDelegate">The method to call to process the received data from the server/client.</param> public static void SendData(this ReloadedSocket reloadedSocket, Message.MessageStruct message, bool awaitResponse, ProcessBytesDelegate receiveDataDelegate) { // Call the other overload and get our data back. Message.MessageStruct messageLocal = SendData(reloadedSocket, message, awaitResponse); // If we want a response from the client, receive it, copy to a buffer array and send it back to the method delegate linked to the method we want to process the outcome with. if (awaitResponse) { receiveDataDelegate(messageLocal, reloadedSocket); } }
/// <summary> /// Replies the name of the assembler back to the client. /// </summary> /// <param name="clientSocket">The socket to which the "ok" message should be sent.</param> private static void Report(ReloadedSocket clientSocket) { // Send back empty message struct. Message.MessageStruct messageStruct = new Message.MessageStruct { MessageType = (ushort)MessageTypes.ReportAssembler, // ABSOLUTELY DO NOT CHANGE THIS STRING // libReloaded EXPECTS THIS STRING AND WILL IGNORE SERVER UNTIL // THIS STRING IS RETURNED. THIS IDENTIFIES THE ASSEMBLER. Data = Encoding.ASCII.GetBytes(ReloadedCheckMessage) }; clientSocket.SendData(messageStruct, false); }
/// <summary> /// Handles the messages received from the individual client sockets consisting mainly of /// mods. Exposes various functionality features to mods. /// </summary> /// <param name="clientMessage">The message struct received from the individual mod loader server clients.</param> /// <param name="socket">The individual socket object to use for connection back with the mod loader clients.</param> private static void MessageHandler(Message.MessageStruct clientMessage, ReloadedSocket socket) { // Pass the relevant message. switch (clientMessage.MessageType) { // Regular Functions case (ushort)MessageType.Okay: ReplyOkay.ReplyOk(socket); break; // Text Functions case (ushort)MessageType.PrintText: Print(PrintMessageType.PrintText, clientMessage.Data, socket); break; case (ushort)MessageType.PrintInfo: Print(PrintMessageType.PrintInfo, clientMessage.Data, socket); break; case (ushort)MessageType.PrintWarning: Print(PrintMessageType.PrintWarning, clientMessage.Data, socket); break; case (ushort)MessageType.PrintError: Print(PrintMessageType.PrintError, clientMessage.Data, socket); break; } }
/// <summary> /// Sends a message to the mod loader server to print /// a message to standard output with a user defined style. /// </summary> /// <param name="message">The text to print to the console.</param> /// <param name="printMessageType">The style of text to be printed to the screen.</param> public static void Print(string message, PrintMessageType printMessageType) { // Get string to print as bytes. byte[] bytesToSend = Encoding.ASCII.GetBytes(message); // Build a Server Message with text to print. // The style of the message is user-set. Message.MessageStruct clientMessage = new Message.MessageStruct((ushort)MessageTypes.MessageType.PrintText, bytesToSend); // Switch message type if necessary. switch (printMessageType) { case PrintMessageType.PrintInfo: clientMessage.MessageType = (ushort)MessageTypes.MessageType.PrintInfo; break; case PrintMessageType.PrintError: clientMessage.MessageType = (ushort)MessageTypes.MessageType.PrintError; break; case PrintMessageType.PrintWarning: clientMessage.MessageType = (ushort)MessageTypes.MessageType.PrintWarning; break; } // Send the message. ServerClient.ClientSocket.SendData(clientMessage, false); }
/// <summary> /// Send the data in a byte array to the server. /// Expects a delegate to be assigned to ProcessBytesMethod which will handle the data. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object connected to either a host or client.</param> /// <param name="message">The message that is to be sent to the server.</param> public static void SendDataAsync(this ReloadedSocket reloadedSocket, Message.MessageStruct message) { try { // Return empty message if socket not connected. if (!reloadedSocket.Socket.Connected) { return; } // Convert the message struct into bytes to send. reloadedSocket.DataToSend = message.BuildMessage(); // Set sent bytes to 0. reloadedSocket.AsyncBytesToSend = reloadedSocket.DataToSend.Length; reloadedSocket.AsyncSentBytes = 0; // Begin sending the message. reloadedSocket.Socket.BeginSend(reloadedSocket.DataToSend, 0, reloadedSocket.DataToSend.Length, SocketFlags.None, SendAsyncCallback, reloadedSocket); } catch { reloadedSocket.CloseIfDisconnected(); } }
/// <summary> /// Assembles the received request and sends back information to the client. /// </summary> /// <param name="mnemonics">The assembly code to be assembled.</param> /// <param name="clientSocket">The socket used for communication with the client. which sent the request.</param> private static void Assemble(string[] mnemonics, ReloadedSocket clientSocket) { // Send back empty message struct Message.MessageStruct messageStruct = new Message.MessageStruct { // Client will likely ignore this anyway (but shouldn't). MessageType = ( ushort )MessageTypes.Assemble }; // Try Assembly // Assemble the bytes try { messageStruct.Data = FasmNet.Assemble(mnemonics); } // Failed to Assemble // Return nop on failure. catch { messageStruct.Data = new byte[1] { 0x90 }; } // Return back. clientSocket.SendData(messageStruct, false); }
/// <summary> /// Send the data in a byte array to the server. /// Expects a delegate to be assigned to ProcessBytesMethod which will handle the data. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object connected to either a host or client.</param> /// <param name="message">The message that is to be sent to the server.</param> /// <param name="awaitResponse">Set true to wait for a response from the server, else false.</param> public static Message.MessageStruct SendData(this ReloadedSocket reloadedSocket, Message.MessageStruct message, bool awaitResponse) { try { // Return empty message if socket not connected. if (!reloadedSocket.Socket.Connected) { return(null); } // Convert the message struct into bytes to send. byte[] data = message.BuildMessage(); // Get the amount of bytes sent. int bytesSent = 0; // Ensure we send all bytes. while (bytesSent < data.Length) { // Offset: Bytes Sent // Length to Send: Length to send - Already Sent int bytesSuccessfullySent = reloadedSocket.Socket.Send(data, bytesSent, data.Length - bytesSent, SocketFlags.None); // Send serialized Message! bytesSent += bytesSuccessfullySent; // If the reloadedSocket is not connected, return empty message struct. if (bytesSuccessfullySent == 0) { if (!IsSocketConnected(reloadedSocket)) { return(null); } } } // If we want a response from the client, receive it, copy to a buffer array and send it back to the method delegate linked to the method we want to process the outcome with. if (awaitResponse) { return(ReceiveData(reloadedSocket)); } return(null); } catch // Probably lost connection. { reloadedSocket.CloseIfDisconnected(); return(null); } }
/// <summary> /// Waits for data to be received from the websocket host. /// Can be used to wait for a response from the server in question. /// This version returns the result from the host as a byte array. /// </summary> /// <param name="reloadedSocket">The individual reloadedSocket object connected to either a host or client.</param> public static Message.MessageStruct ReceiveData(this ReloadedSocket reloadedSocket) { try { // Return empty message if socket not connected. if (!reloadedSocket.Socket.Connected) { return(null); } // ReceiveData the information from the host onto the buffer. // ClientSocket.Receive() returns the data length, stored here. int bytesToReceive = sizeof(uint); int bytesReceived = 0; bytesReceived += reloadedSocket.Socket.Receive(reloadedSocket.ReceiveBuffer, bytesToReceive, SocketFlags.None); // Receive packets until all information is acquired. while (bytesReceived < bytesToReceive) { // Receive extra bytes int newBytesReceived = reloadedSocket.Socket.Receive(reloadedSocket.ReceiveBuffer, bytesReceived, bytesToReceive - bytesReceived, SocketFlags.None); bytesReceived += newBytesReceived; // If the reloadedSocket is not connected, return empty message struct. if (newBytesReceived == 0) { if (!IsSocketConnected(reloadedSocket)) { return(null); } } } // Get the true length of the message to be received. bytesToReceive = BitConverter.ToInt32(reloadedSocket.ReceiveBuffer, 0); bytesReceived = 0; // Increase buffer size if necessary. bool messageTooLarge = false; if (bytesToReceive > reloadedSocket.ReceiveBuffer.Length) { reloadedSocket.ReceiveBuffer = new byte[bytesToReceive]; messageTooLarge = true; } // Receive packets until all information is acquired. while (bytesReceived < bytesToReceive) { // Receive extra bytes int newBytesReceived = reloadedSocket.Socket.Receive(reloadedSocket.ReceiveBuffer, bytesReceived, bytesToReceive - bytesReceived, SocketFlags.None); bytesReceived += newBytesReceived; // If the reloadedSocket is not connected, return empty message struct. if (newBytesReceived == 0) { if (!IsSocketConnected(reloadedSocket)) { return(null); } } } // Create a receive buffer with our own data length to be received. byte[] receiveBuffer = new byte[bytesToReceive]; // Copy the received data into the buffer. Array.Copy(reloadedSocket.ReceiveBuffer, receiveBuffer, bytesToReceive); // Convert Received Bytes into a Message Struct Message.MessageStruct receivedData = Message.ParseMessage(receiveBuffer); // Reset buffer size to smaller (for Garbage Collector to pick up old buffer) if (messageTooLarge) { reloadedSocket.ReceiveBuffer = new byte[reloadedSocket.DefaultBufferSize]; } // Process the received bytes. return(receivedData); } catch // Probably lost connection. { reloadedSocket.CloseIfDisconnected(); return(null); } }