source: binary-improvements/7dtd-server-fixes/src/NetConnections/Servers/Telnet/TelnetConnection.cs@ 186

Last change on this file since 186 was 185, checked in by alloc, 11 years ago

fixes

File size: 5.5 KB
RevLine 
[75]1using System;
[182]2using System.Collections.Generic;
3using System.IO;
[75]4using System.Net;
5using System.Net.Sockets;
[142]6using System.Text;
[182]7using System.Threading;
[75]8
[132]9namespace AllocsFixes.NetConnections.Servers.Telnet
[130]10{
[132]11 public class TelnetConnection : IConnection
[75]12 {
[184]13 private readonly BlockingQueue<string> toClientQueue = new BlockingQueue<string> ();
14 private readonly Telnet owner;
15 private readonly Thread receiveThread = null;
16 private readonly Thread sendThread = null;
17 private int authTries = 0;
[132]18 private bool authenticated = false;
[184]19 private readonly bool authEnabled;
[132]20 private TcpClient client;
[184]21 private readonly NetworkStream stream;
22 private readonly EndPoint endpoint;
23 private readonly int endpointAddressHash;
[75]24
[184]25 public TelnetConnection (Telnet owner, TcpClient client, bool authEnabled)
[132]26 {
[184]27 this.owner = owner;
[132]28 this.authEnabled = authEnabled;
29 this.client = client;
30 this.stream = client.GetStream ();
31 this.endpoint = client.Client.RemoteEndPoint;
[182]32
33 Log.Out ("Telnet connection from: " + endpoint);
34
35 receiveThread = ThreadMaster.Create ("TelnetClientReceive", new ThreadStart (ReceiveThread));
36 receiveThread.Start ();
37 sendThread = ThreadMaster.Create ("TelnetClientSend", new ThreadStart (SendThread));
38 sendThread.Start ();
39
[184]40 if (endpoint is IPEndPoint) {
41 endpointAddressHash = ((IPEndPoint)endpoint).Address.GetHashCode();
[185]42 //Log.Out ("Hash: " + endpointAddressHash);
[184]43 } else {
44 Log.Out ("EndPoint is not an IPEndPoint but: " + endpoint.GetType().ToString());
45 }
46
[182]47 if (authEnabled) {
48 WriteLine ("Please enter password:");
49 } else {
50 LoginMessage ();
51 }
[132]52 }
[75]53
[182]54 private void LoginMessage ()
[132]55 {
[182]56 WriteLine ("*** Connected with 7DTD server.");
57 WriteLine ("*** Dedicated server only build");
58 WriteLine ("*** Allocs server fixes loaded");
59 WriteLine (string.Empty);
60 WriteLine ("Server IP: " +
61 ((GamePrefs.GetString (EnumGamePrefs.ServerIP) != null && GamePrefs.GetString (EnumGamePrefs.ServerIP).Length != 0) ? GamePrefs.GetString (EnumGamePrefs.ServerIP) : "Any")
62 );
63 WriteLine ("Server port: " + GamePrefs.GetInt (EnumGamePrefs.ServerPort));
64 WriteLine ("Max players: " + GamePrefs.GetInt (EnumGamePrefs.ServerMaxPlayerCount));
65 WriteLine ("Game mode: " + GamePrefs.GetString (EnumGamePrefs.GameMode));
66 WriteLine ("World: " + GamePrefs.GetString (EnumGamePrefs.GameWorld));
67 WriteLine ("Game name: " + GamePrefs.GetString (EnumGamePrefs.GameName));
68 WriteLine ("Difficulty: " + GamePrefs.GetInt (EnumGamePrefs.GameDifficulty));
69 WriteLine (string.Empty);
70 WriteLine ("Press 'help' to get a list of all commands. Press 'exit' to end session.");
71 WriteLine (string.Empty);
[75]72 }
73
[182]74 private void ReceiveThread ()
[132]75 {
[182]76 try {
77 StreamReader reader = new StreamReader (stream);
78 try {
79 while (!IsClosed()) {
80 string line = reader.ReadLine ();
81 if (line != null) {
82 line = line.Trim ();
83
84 if (!IsAuthenticated ()) {
85 if (line.Equals (GamePrefs.GetString (EnumGamePrefs.TelnetPassword))) {
86 authenticated = true;
87 WriteLine ("Logon successful.");
88 WriteLine (string.Empty);
89 WriteLine (string.Empty);
90 WriteLine (string.Empty);
91 LoginMessage ();
92 } else {
[184]93 authTries++;
94 // TODO: check if IP has more login attempts by now
95 if (authTries < 3) {
96 WriteLine ("Password incorrect, please enter password:");
97 } else {
98 WriteLine ("Too many failed login attempts!");
[185]99 Thread.Sleep(100);
[184]100 //TODO: owner.FailedLogins();
101 Close ();
[185]102 Log.Out ("Telnet connection closed for too many login attempts: " + endpoint);
[184]103 break;
104 }
[182]105 }
106 } else {
107 if (line.ToLower ().Equals ("exit")) {
108 Log.Out ("Telnet connection closed by client: " + endpoint);
109 Close ();
110 break;
111 }
112 Log.Out ("Telnet executed \"" + line + "\" from: " + endpoint);
113 ConsoleOutputSeparator.QueueNetCommand (line, this);
114 }
115 }
116 }
[183]117 } catch (ObjectDisposedException) {
[182]118 } catch (IOException) {
119 } catch (ThreadInterruptedException) {
120 }
121 ThreadMaster.Remove (Thread.CurrentThread.Name);
122 } catch (Exception ex) {
123 Log.Out ("Error in TelnetClientReceive: " + ex);
[132]124 }
[182]125
[132]126 }
127
[182]128 private void SendThread ()
[132]129 {
130 try {
[182]131 while (!IsClosed() && stream.CanWrite) {
132 try {
133 string line = toClientQueue.Dequeue ();
134 if (!IsClosed () && stream.CanWrite) {
135 byte[] utfData = Encoding.UTF8.GetBytes (line);
136 stream.Write (utfData, 0, utfData.Length);
137 stream.WriteByte (13);
138 stream.WriteByte (10);
139 }
140 } catch (IOException) {
141 } catch (ThreadInterruptedException) {
142 } catch (Exception e) {
143 Log.Out ("Error writing to client: " + e);
144 }
[91]145 }
[182]146
147 ThreadMaster.Remove (Thread.CurrentThread.Name);
148 } catch (Exception ex) {
149 Log.Out ("Error in TelnetClientSend: " + ex);
[75]150 }
[182]151
[75]152 }
153
[182]154 public void WriteLine (string s)
155 {
156 toClientQueue.Enqueue (s);
157 }
158
[132]159 public void Close ()
160 {
[182]161 if (receiveThread != null) {
162 receiveThread.Interrupt ();
163 }
164 if (sendThread != null) {
165 sendThread.Interrupt ();
166 }
[132]167 if (client != null)
168 client.Close ();
169 client = null;
170 }
[75]171
[132]172 public bool IsClosed ()
173 {
174 if (client != null && !client.Connected) {
175 Log.Out ("Telnet connection interrupted: " + endpoint);
[182]176 Close ();
[132]177 }
178 return (client == null) || (!client.Connected);
[75]179 }
180
[132]181 public bool IsAuthenticated ()
182 {
183 return !authEnabled || authenticated;
184 }
[75]185
186 }
187}
Note: See TracBrowser for help on using the repository browser.