bool sendRemoteMessage(Socket socket, Int16 id, MemoryStream msg) { List <byte> buffer = new List <byte>(); RPCMessageHeader header = new RPCMessageHeader(); header.id = id; header.size = (Int32)msg.Length; buffer.AddRange(header.ConvertToBtyes()); buffer.AddRange(msg.ToArray()); int fullsz = buffer.Count; String arrayReport = ""; for (int i = 0; i < buffer.Count; i++) { byte number = buffer[i]; if ((number < 32) || (number > 126)) { arrayReport += number; } else { arrayReport += (char)number; } arrayReport += ","; } //String tempString = ""; //byte[] tempArray = buffer.ToArray(); //for (int i = 0; i < tempArray.GetUpperBound(0); i++) //{ // //if (Char.IsControl((char)buf[i])) // tempString += (byte)tempArray[i]; // //else // // tempString += (char)buf[i]; // tempString += ","; //} //UnityEngine.Debug.Log("Sent buf[" + tempArray.Length + "] = " + tempString); int got = socket.Send(buffer.ToArray()); return(got == fullsz); }
protected command_result execute <Input, Output>(color_ostream outString, Input input, out Output output) where Input : class, message_type, new() where Output : class, message_type, new() { if (!isValid()) { outString.printerr("Calling an unbound RPC function %s::%s.\n", this.proto, this.name); output = default(Output); return(command_result.CR_NOT_IMPLEMENTED); } if (p_client.socket == null) { outString.printerr("In call to %s::%s: invalid socket.\n", this.proto, this.name); output = default(Output); return(command_result.CR_LINK_FAILURE); } MemoryStream sendStream = new MemoryStream(); ProtoBuf.Serializer.Serialize <Input>(sendStream, input); long send_size = sendStream.Length; if (send_size > RPCMessageHeader.MAX_MESSAGE_SIZE) { outString.printerr("In call to %s::%s: message too large: %d.\n", this.proto, this.name, send_size); output = default(Output); return(command_result.CR_LINK_FAILURE); } if (!sendRemoteMessage(p_client.socket, id, sendStream)) { outString.printerr("In call to %s::%s: I/O error in send.\n", this.proto, this.name); output = default(Output); return(command_result.CR_LINK_FAILURE); } color_ostream_proxy text_decoder = new color_ostream_proxy(outString); CoreTextNotification text_data; //output = new Output(); //return command_result.CR_OK; while (true) { RPCMessageHeader header = new RPCMessageHeader(); byte[] buffer = new byte[8]; if (!RemoteClient.readFullBuffer(p_client.socket, buffer, 8)) { outString.printerr("In call to %s::%s: I/O error in receive header.\n", this.proto, this.name); output = default(Output); return(command_result.CR_LINK_FAILURE); } header.id = BitConverter.ToInt16(buffer, 0); header.size = BitConverter.ToInt32(buffer, 4); //because something, somewhere, is f*****g retarded //outString.print("Received %d:%d.\n", header.id, header.size); if ((DFHackReplyCode)header.id == DFHackReplyCode.RPC_REPLY_FAIL) { output = default(Output); if (header.size == (int)command_result.CR_OK) { return(command_result.CR_FAILURE); } else { return((command_result)header.size); } } if (header.size < 0 || header.size > RPCMessageHeader.MAX_MESSAGE_SIZE) { outString.printerr("In call to %s::%s: invalid received size %d.\n", this.proto, this.name, header.size); output = default(Output); return(command_result.CR_LINK_FAILURE); } byte[] buf = new byte[header.size]; if (!RemoteClient.readFullBuffer(p_client.socket, buf, header.size)) { outString.printerr("In call to %s::%s: I/O error in receive %d bytes of data.\n", this.proto, this.name, header.size); output = default(Output); return(command_result.CR_LINK_FAILURE); } switch ((DFHackReplyCode)header.id) { case DFHackReplyCode.RPC_REPLY_RESULT: //if (buf.Length >= 50) //{ // String tempString = ""; // for (int i = header.size - 50; i < header.size; i++) // { // //if (Char.IsControl((char)buf[i])) // tempString += (byte)buf[i]; // //else // // tempString += (char)buf[i]; // tempString += ","; // } // UnityEngine.Debug.Log("Got buf[" + buf.Length + "] = " + tempString); //} output = ProtoBuf.Serializer.Deserialize <Output>(new MemoryStream(buf)); if (output == null) { outString.printerr("In call to %s::%s: error parsing received result.\n", this.proto, this.name); return(command_result.CR_LINK_FAILURE); } return(command_result.CR_OK); case DFHackReplyCode.RPC_REPLY_TEXT: text_data = ProtoBuf.Serializer.Deserialize <CoreTextNotification>(new MemoryStream(buf)); if (text_data != null) { text_decoder.decode(text_data); } else { outString.printerr("In call to %s::%s: received invalid text data.\n", this.proto, this.name); } break; default: break; } } }