public void sendToOneClient(Packet packet, String name) { NetworkStream stream = getstream(name); if (stream != null) { sendToOneClient(packet, stream); } }
// this is for the greeting message when // an android device initially connects private void sendToOneClient(Packet packet, NetworkStream stream) { string message = serial.Serialize(packet); byte[] buffer = new UTF8Encoding().GetBytes(message + "\n"); try { stream.Write(buffer, 0, buffer.Length); stream.Flush(); } catch { // the client just connected, so there shouldn't be a problem // but if there is, it will be removed from the clientlist // in the socket2queue thread } }
// there is 1 socket2queue thread per client. private void socket2queue(Object clientinfoobject) { ClientInfo clientinfo = (ClientInfo)clientinfoobject; NetworkStream stream = clientinfo.stream; TcpClient tcpClient = clientinfo.client; int bytesRead; byte[] message = new byte[4096]; while (enabled) { bytesRead = 0; try { //blocks until a client sends a message bytesRead = stream.Read(message, 0, 4096); } catch { //a socket error has occured break; } if (bytesRead == 0) { //the client has disconnected from the server break; } //message has successfully been received UTF8Encoding encoder = new UTF8Encoding(); string data = encoder.GetString(message, 0, bytesRead); data = data.Substring(0, data.Length-1); // useable data. gets rid of the "/n" that java is putting into the stream at the end Packet p = new Packet(); try { p = serial.Deserialize<Packet>(data); // convert from a JSON String into a Packet object //the other android clients need to be able to chat with each other AndroidPlugin.instance.changeoriginator(p); // send it back to the outqueue, but with originator of "server" // we'll let the android app deal with filtering out chat from itself // for terraria inqueue.Enqueue(p); } catch (ArgumentException e) { // sender gave us incorrect JSON, so lets inform them that an error occured sendToOneClient(Packet.IMPROPER_JSON_ERROR(), stream); break; } } KeyValuePair<TcpClient, String> name; clientlist.TryGetValue(stream, out name); stream.Close(); tcpClient.Close(); ProgramLog.Log("[Android] Client disconnected..."); inqueue.Enqueue(new Packet("androidapp" , Packet.Type.LEAVE , name.Value)); AndroidPlugin.instance.changeoriginator(new Packet("androidapp" ,Packet.Type.LEAVE , name.Value, "Terraria")); // and this, because the other android apps would like to know aswell KeyValuePair<TcpClient, String> temp; clientlist.TryRemove(stream, out temp); // i really don't like this way of doing this, but i don't like locks either :/ connectedClients--; ProgramLog.Log(connectedClients + " remaining."); }
public void changeoriginator(Packet tochange, String originator = "server") { Packet info = new Packet(originator, tochange.type, tochange.from, tochange.data1, tochange.data2, tochange.array1); if (info.type != Packet.Type.LEAVE && info.type != Packet.Type.JOIN && info.type != Packet.Type.PLAYERSONLINE) { send(info.type, info.data1, info.from, info.data2, info.array1, originator); } if (info.type == Packet.Type.LEAVE) { send(info.type, info.from + " has left chat.", "Terraria", info.data2, info.array1, originator); } else if (info.type == Packet.Type.JOIN) { send(info.type, info.from + " has joined chat.", "Terraria", info.data2, info.array1, originator); } }