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

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

Server fixes

File size: 5.7 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 ("*** Server version: " + GamePrefs.GetString(EnumGamePrefs.GameVersion));
62 toClientQueue.Enqueue ("*** Dedicated server only build");
63 toClientQueue.Enqueue ("*** Allocs server fixes loaded");
64 toClientQueue.Enqueue (string.Empty);
65 toClientQueue.Enqueue ("Server IP: " +
66 ((GamePrefs.GetString (EnumGamePrefs.ServerIP) != null && GamePrefs.GetString (EnumGamePrefs.ServerIP).Length != 0) ? GamePrefs.GetString (EnumGamePrefs.ServerIP) : "Any")
67 );
68 toClientQueue.Enqueue ("Server port: " + GamePrefs.GetInt (EnumGamePrefs.ServerPort));
69 toClientQueue.Enqueue ("Max players: " + GamePrefs.GetInt (EnumGamePrefs.ServerMaxPlayerCount));
70 toClientQueue.Enqueue ("Game mode: " + GamePrefs.GetString (EnumGamePrefs.GameMode));
71 toClientQueue.Enqueue ("World: " + GamePrefs.GetString (EnumGamePrefs.GameWorld));
72 toClientQueue.Enqueue ("Game name: " + GamePrefs.GetString (EnumGamePrefs.GameName));
73 toClientQueue.Enqueue ("Difficulty: " + GamePrefs.GetInt (EnumGamePrefs.GameDifficulty));
74 toClientQueue.Enqueue (string.Empty);
75 toClientQueue.Enqueue ("Press 'help' to get a list of all commands. Press 'exit' to end session.");
76 toClientQueue.Enqueue (string.Empty);
77 }
78
79 private void ReceiveThread ()
80 {
81 try {
82 StreamReader reader = new StreamReader (client.GetStream ());
83 while (!closed) {
84 string line = reader.ReadLine ();
85 if (line != null && (line = line.Trim ()).Length > 0) {
86 if (!IsAuthenticated) {
87 if (line.Equals (GamePrefs.GetString (EnumGamePrefs.TelnetPassword))) {
88 authenticated = true;
89 toClientQueue.Enqueue ("Logon successful.");
90 toClientQueue.Enqueue (string.Empty);
91 toClientQueue.Enqueue (string.Empty);
92 toClientQueue.Enqueue (string.Empty);
93 LoginMessage ();
94 } else {
95 if (telnet.RegisterFailedLogin (this)) {
96 toClientQueue.Enqueue ("Password incorrect, please enter password:");
97 } else {
98 toClientQueue.Enqueue ("Too many failed login attempts!");
99 Thread.Sleep (100);
100 Close (true);
101 break;
102 }
103 }
104 } else {
105 if (line.ToLower ().Equals ("exit")) {
106 break;
107 }
108 Log.Out ("Telnet executed \"" + line + "\" from: " + endpoint);
109 ConsoleOutputSeparator.QueueNetCommand (line, this);
110 }
111 }
112 }
113 } catch (Exception) {
114 }
115
116 if (!closed)
117 Close ();
118 ThreadMaster.Remove (Thread.CurrentThread.Name);
119 }
120
121 private void SendThread ()
122 {
123 try {
124 while (!closed && client.GetStream ().CanWrite) {
125 string line = toClientQueue.Dequeue ();
126 if (!closed && client.GetStream ().CanWrite) {
127 if (line == null) {
128 client.GetStream ().WriteByte (0);
129 } else {
130 byte[] utfData = Encoding.UTF8.GetBytes (line);
131 client.GetStream ().Write (utfData, 0, utfData.Length);
132 client.GetStream ().WriteByte (13);
133 client.GetStream ().WriteByte (10);
134 }
135 }
136 }
137 } catch (Exception) {
138 }
139
140 if (!closed)
141 Close ();
142 ThreadMaster.Remove (Thread.CurrentThread.Name);
143 }
144
145 public void Close (bool kickedForLogins = false)
146 {
147 if (!closed) {
148 closed = true;
149 toClientQueue.Close ();
150 client.GetStream ().Close ();
151 client.Close ();
152 telnet.ConnectionClosed (this);
153
154 if (kickedForLogins)
155 Log.Out ("Telnet connection closed for too many login attempts: " + endpoint);
156 else
157 Log.Out ("Telnet connection closed: " + endpoint);
158 }
159 }
160
161 public void SendLine (string line)
162 {
163 if (!closed && IsAuthenticated)
164 toClientQueue.Enqueue (line);
165 else
166 toClientQueue.Enqueue (null);
167 }
168
169 public void SendLog (string text, string trace, UnityEngine.LogType type)
170 {
171 throw new System.NotImplementedException ();
172 }
173
174 public string GetDescription ()
175 {
176 return "Telnet from " + endpoint;
177 }
178 }
179}
Note: See TracBrowser for help on using the repository browser.