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

Last change on this file since 200 was 190, checked in by alloc, 10 years ago

fixes

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