Index: binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/Telnet.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/Telnet.cs	(revision 189)
+++ binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/Telnet.cs	(revision 190)
@@ -63,12 +63,4 @@
 		}
 
-		public bool RegisterFailedLogin (int addressHash)
-		{
-			lock (loginAttemptsPerIP) {
-				LoginAttempts la = loginAttemptsPerIP [addressHash];
-				return la.LogAttempt ();
-			}
-		}
-
 		private void AcceptClient (IAsyncResult asyncResult)
 		{
@@ -80,6 +72,6 @@
 				if (endpoint is IPEndPoint) {
 					addressHash = ((IPEndPoint)endpoint).Address.GetHashCode ();
-					//Log.Out ("Hash: " + endpointAddressHash);
 				} else {
+					addressHash = endpoint.GetHashCode ();
 					Log.Out ("EndPoint is not an IPEndPoint but: " + endpoint.GetType ().ToString ());
 				}
@@ -87,5 +79,5 @@
 				lock (loginAttemptsPerIP) {
 					LoginAttempts la = null;
-					if (loginAttemptsPerIP.ContainsKey(addressHash))
+					if (loginAttemptsPerIP.ContainsKey (addressHash))
 						la = loginAttemptsPerIP [addressHash];
 					if (la == null) {
@@ -95,5 +87,7 @@
 					if (!la.IsBanned ()) {
 						TelnetConnection con = new TelnetConnection (this, client, authEnabled);
-						connections.Add (con);
+						lock (connections) {
+							connections.Add (con);
+						}
 					} else {
 						client.Close ();
@@ -102,4 +96,19 @@
 				}
 				listener.BeginAcceptTcpClient (new AsyncCallback (AcceptClient), null);
+			}
+		}
+
+		public bool RegisterFailedLogin (TelnetConnection con)
+		{
+			lock (loginAttemptsPerIP) {
+				LoginAttempts la = loginAttemptsPerIP [con.EndPointHash];
+				return la.LogAttempt ();
+			}
+		}
+
+		public void ConnectionClosed (TelnetConnection con)
+		{
+			lock (connections) {
+				connections.Remove (con);
 			}
 		}
@@ -112,5 +121,6 @@
 					listener = null;
 				}
-				foreach (TelnetConnection c in connections) {
+				List<TelnetConnection> cur = new List<TelnetConnection> (connections);
+				foreach (TelnetConnection c in cur) {
 					c.Close ();
 				}
@@ -120,44 +130,19 @@
 		}
 
-		private void RemoveClosedConnections ()
-		{
-			try {
-				List<TelnetConnection> toRemove = new List<TelnetConnection> ();
-				foreach (TelnetConnection c in connections) {
-					if (c.IsClosed ())
-						toRemove.Add (c);
-				}
-				foreach (TelnetConnection c in toRemove) {
-					connections.Remove (c);
-				}
-			} catch (Exception e) {
-				Log.Out ("Error in Telnet.RemoveClosedConnections: " + e);
-			}
-		}
-
-		public void WriteToClient (string line)
+		public void SendLine (string line)
 		{
 			if (line == null) {
 				return;
 			}
-			RemoveClosedConnections ();
-			foreach (TelnetConnection c in connections) {
-				if (c.IsAuthenticated ())
-					c.WriteLine (line);
+			lock (connections) {
+				foreach (TelnetConnection c in connections) {
+					c.SendLine (line);
+				}
 			}
 		}
 
-		public void WriteToClient_Single (string line, IConnection client)
+		public void SendLog (string text, string trace, UnityEngine.LogType type)
 		{
-			if (line == null) {
-				return;
-			}
-			RemoveClosedConnections ();
-			foreach (TelnetConnection con in connections) {
-				if (con == client) {
-					if (con.IsAuthenticated ())
-						con.WriteLine (line);
-				}
-			}
+			throw new System.NotImplementedException ();
 		}
 
Index: binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/TelnetConnection.cs
===================================================================
--- binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/TelnetConnection.cs	(revision 189)
+++ binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/TelnetConnection.cs	(revision 190)
@@ -12,38 +12,43 @@
 	{
 		private readonly BlockingQueue<string> toClientQueue = new BlockingQueue<string> ();
-		private readonly Telnet owner;
+		private readonly Telnet telnet;
 		private readonly Thread receiveThread = null;
 		private readonly Thread sendThread = null;
 		private bool authenticated = false;
 		private readonly bool authEnabled;
-		private TcpClient client;
-		private readonly NetworkStream stream;
+		private readonly TcpClient client;
 		private readonly EndPoint endpoint;
 		private readonly int endpointAddressHash;
+		private bool closed = false;
+
+		public bool IsClosed { get { return closed; } }
+
+		public bool IsAuthenticated { get { return !authEnabled || authenticated; } }
+
+		public int EndPointHash { get { return endpointAddressHash; } }
 
 		public TelnetConnection (Telnet owner, TcpClient client, bool authEnabled)
 		{
-			this.owner = owner;
+			this.telnet = owner;
 			this.authEnabled = authEnabled;
 			this.client = client;
-			this.stream = client.GetStream ();
 			this.endpoint = client.Client.RemoteEndPoint;
+
+			if (endpoint is IPEndPoint) {
+				endpointAddressHash = ((IPEndPoint)endpoint).Address.GetHashCode ();
+			} else {
+				endpointAddressHash = endpoint.GetHashCode ();
+				Log.Out ("EndPoint is not an IPEndPoint but: " + endpoint.GetType ().ToString ());
+			}
 
 			Log.Out ("Telnet connection from: " + endpoint);
 
-			receiveThread = ThreadMaster.Create ("TelnetClientReceive", new ThreadStart (ReceiveThread));
+			receiveThread = ThreadMaster.Create ("TelnetClientReceive_" + endpoint.ToString (), new ThreadStart (ReceiveThread));
 			receiveThread.Start ();
-			sendThread = ThreadMaster.Create ("TelnetClientSend", new ThreadStart (SendThread));
+			sendThread = ThreadMaster.Create ("TelnetClientSend" + endpoint.ToString (), new ThreadStart (SendThread));
 			sendThread.Start ();
 
-			if (endpoint is IPEndPoint) {
-				endpointAddressHash = ((IPEndPoint)endpoint).Address.GetHashCode ();
-				//Log.Out ("Hash: " + endpointAddressHash);
-			} else {
-				Log.Out ("EndPoint is not an IPEndPoint but: " + endpoint.GetType ().ToString ());
-			}
-
 			if (authEnabled) {
-				WriteLine ("Please enter password:");
+				toClientQueue.Enqueue ("Please enter password:");
 			} else {
 				LoginMessage ();
@@ -53,20 +58,20 @@
 		private void LoginMessage ()
 		{
-			WriteLine ("*** Connected with 7DTD server.");
-			WriteLine ("*** Dedicated server only build");
-			WriteLine ("*** Allocs server fixes loaded");
-			WriteLine (string.Empty);
-			WriteLine ("Server IP:   " + 
+			toClientQueue.Enqueue ("*** Connected with 7DTD server.");
+			toClientQueue.Enqueue ("*** Dedicated server only build");
+			toClientQueue.Enqueue ("*** Allocs server fixes loaded");
+			toClientQueue.Enqueue (string.Empty);
+			toClientQueue.Enqueue ("Server IP:   " + 
 				((GamePrefs.GetString (EnumGamePrefs.ServerIP) != null && GamePrefs.GetString (EnumGamePrefs.ServerIP).Length != 0) ? GamePrefs.GetString (EnumGamePrefs.ServerIP) : "Any")
 			);
-			WriteLine ("Server port: " + GamePrefs.GetInt (EnumGamePrefs.ServerPort));
-			WriteLine ("Max players: " + GamePrefs.GetInt (EnumGamePrefs.ServerMaxPlayerCount));
-			WriteLine ("Game mode:   " + GamePrefs.GetString (EnumGamePrefs.GameMode));
-			WriteLine ("World:       " + GamePrefs.GetString (EnumGamePrefs.GameWorld));
-			WriteLine ("Game name:   " + GamePrefs.GetString (EnumGamePrefs.GameName));
-			WriteLine ("Difficulty:  " + GamePrefs.GetInt (EnumGamePrefs.GameDifficulty));
-			WriteLine (string.Empty);
-			WriteLine ("Press 'help' to get a list of all commands. Press 'exit' to end session.");
-			WriteLine (string.Empty);
+			toClientQueue.Enqueue ("Server port: " + GamePrefs.GetInt (EnumGamePrefs.ServerPort));
+			toClientQueue.Enqueue ("Max players: " + GamePrefs.GetInt (EnumGamePrefs.ServerMaxPlayerCount));
+			toClientQueue.Enqueue ("Game mode:   " + GamePrefs.GetString (EnumGamePrefs.GameMode));
+			toClientQueue.Enqueue ("World:       " + GamePrefs.GetString (EnumGamePrefs.GameWorld));
+			toClientQueue.Enqueue ("Game name:   " + GamePrefs.GetString (EnumGamePrefs.GameName));
+			toClientQueue.Enqueue ("Difficulty:  " + GamePrefs.GetInt (EnumGamePrefs.GameDifficulty));
+			toClientQueue.Enqueue (string.Empty);
+			toClientQueue.Enqueue ("Press 'help' to get a list of all commands. Press 'exit' to end session.");
+			toClientQueue.Enqueue (string.Empty);
 		}
 
@@ -74,51 +79,41 @@
 		{
 			try {
-				StreamReader reader = new StreamReader (stream);
-				try {
-					while (!IsClosed()) {
-						string line = reader.ReadLine ();
-						if (line != null && line.Length > 0) {
-							line = line.Trim ();
-							if (line.Length > 0) {
-								if (!IsAuthenticated ()) {
-									if (line.Equals (GamePrefs.GetString (EnumGamePrefs.TelnetPassword))) {
-										authenticated = true;
-										WriteLine ("Logon successful.");
-										WriteLine (string.Empty);
-										WriteLine (string.Empty);
-										WriteLine (string.Empty);
-										LoginMessage ();
-									} else {
-										if (owner.RegisterFailedLogin (endpointAddressHash)) {
-											WriteLine ("Password incorrect, please enter password:");
-										} else {
-											WriteLine ("Too many failed login attempts!");
-											Thread.Sleep (100);
-											Close ();
-											Log.Out ("Telnet connection closed for too many login attempts: " + endpoint);
-											break;
-										}
-									}
+				StreamReader reader = new StreamReader (client.GetStream ());
+				while (!closed) {
+					string line = reader.ReadLine ();
+					if (line != null && (line = line.Trim ()).Length > 0) {
+						if (!IsAuthenticated) {
+							if (line.Equals (GamePrefs.GetString (EnumGamePrefs.TelnetPassword))) {
+								authenticated = true;
+								toClientQueue.Enqueue ("Logon successful.");
+								toClientQueue.Enqueue (string.Empty);
+								toClientQueue.Enqueue (string.Empty);
+								toClientQueue.Enqueue (string.Empty);
+								LoginMessage ();
+							} else {
+								if (telnet.RegisterFailedLogin (this)) {
+									toClientQueue.Enqueue ("Password incorrect, please enter password:");
 								} else {
-									if (line.ToLower ().Equals ("exit")) {
-										Log.Out ("Telnet connection closed by client: " + endpoint);
-										Close ();
-										break;
-									}
-									Log.Out ("Telnet executed \"" + line + "\" from: " + endpoint);
-									ConsoleOutputSeparator.QueueNetCommand (line, this);
+									toClientQueue.Enqueue ("Too many failed login attempts!");
+									Thread.Sleep (100);
+									Close (true);
+									break;
 								}
 							}
+						} else {
+							if (line.ToLower ().Equals ("exit")) {
+								break;
+							}
+							Log.Out ("Telnet executed \"" + line + "\" from: " + endpoint);
+							ConsoleOutputSeparator.QueueNetCommand (line, this);
 						}
 					}
-				} catch (ObjectDisposedException) {
-				} catch (IOException) {
-				} catch (ThreadInterruptedException) {
 				}
-				ThreadMaster.Remove (Thread.CurrentThread.Name);
-			} catch (Exception ex) {
-				Log.Out ("Error in TelnetClientReceive: " + ex);
+			} catch (Exception) {
 			}
 
+			if (!closed)
+				Close ();
+			ThreadMaster.Remove (Thread.CurrentThread.Name);
 		}
 
@@ -126,59 +121,58 @@
 		{
 			try {
-				while (!IsClosed() && stream.CanWrite) {
-					try {
-						string line = toClientQueue.Dequeue ();
-						if (!IsClosed () && stream.CanWrite) {
+				while (!closed && client.GetStream ().CanWrite) {
+					string line = toClientQueue.Dequeue ();
+					if (!closed && client.GetStream ().CanWrite) {
+						if (line == null) {
+							client.GetStream ().WriteByte (0);
+						} else {
 							byte[] utfData = Encoding.UTF8.GetBytes (line);
-							stream.Write (utfData, 0, utfData.Length);
-							stream.WriteByte (13);
-							stream.WriteByte (10);
+							client.GetStream ().Write (utfData, 0, utfData.Length);
+							client.GetStream ().WriteByte (13);
+							client.GetStream ().WriteByte (10);
 						}
-					} catch (IOException) {
-					} catch (ThreadInterruptedException) {
-					} catch (Exception e) {
-						Log.Out ("Error writing to client: " + e);
 					}
 				}
-
-				ThreadMaster.Remove (Thread.CurrentThread.Name);
-			} catch (Exception ex) {
-				Log.Out ("Error in TelnetClientSend: " + ex);
+			} catch (Exception) {
 			}
 
+			if (!closed)
+				Close ();
+			ThreadMaster.Remove (Thread.CurrentThread.Name);
 		}
 
-		public void WriteLine (string s)
+		public void Close (bool kickedForLogins = false)
 		{
-			toClientQueue.Enqueue (s);
+			if (!closed) {
+				closed = true;
+				toClientQueue.Close ();
+				client.GetStream ().Close ();
+				client.Close ();
+				telnet.ConnectionClosed (this);
+
+				if (kickedForLogins)
+					Log.Out ("Telnet connection closed for too many login attempts: " + endpoint);
+				else
+					Log.Out ("Telnet connection closed: " + endpoint);
+			}
 		}
 
-		public void Close ()
+		public void SendLine (string line)
 		{
-			if (receiveThread != null) {
-				receiveThread.Interrupt ();
-			}
-			if (sendThread != null) {
-				sendThread.Interrupt ();
-			}
-			if (client != null)
-				client.Close ();
-			client = null;
+			if (!closed && IsAuthenticated)
+				toClientQueue.Enqueue (line);
+			else
+				toClientQueue.Enqueue (null);
 		}
 
-		public bool IsClosed ()
+		public void SendLog (string text, string trace, UnityEngine.LogType type)
 		{
-			if (client != null && !client.Connected) {
-				Log.Out ("Telnet connection interrupted: " + endpoint);
-				Close ();
-			}
-			return (client == null) || (!client.Connected);
+			throw new System.NotImplementedException ();
 		}
 
-		public bool IsAuthenticated ()
+		public string GetDescription ()
 		{
-			return !authEnabled || authenticated;
+			return "Telnet from " + endpoint;
 		}
-
 	}
 }
