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
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> ();
[190]14 private readonly Telnet telnet;
[184]15 private readonly Thread receiveThread = null;
16 private readonly Thread sendThread = null;
[132]17 private bool authenticated = false;
[184]18 private readonly bool authEnabled;
[190]19 private readonly TcpClient client;
[184]20 private readonly EndPoint endpoint;
21 private readonly int endpointAddressHash;
[190]22 private bool closed = false;
[75]23
[190]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
[184]30 public TelnetConnection (Telnet owner, TcpClient client, bool authEnabled)
[132]31 {
[190]32 this.telnet = owner;
[132]33 this.authEnabled = authEnabled;
34 this.client = client;
35 this.endpoint = client.Client.RemoteEndPoint;
[182]36
[184]37 if (endpoint is IPEndPoint) {
[189]38 endpointAddressHash = ((IPEndPoint)endpoint).Address.GetHashCode ();
[184]39 } else {
[190]40 endpointAddressHash = endpoint.GetHashCode ();
[189]41 Log.Out ("EndPoint is not an IPEndPoint but: " + endpoint.GetType ().ToString ());
[184]42 }
43
[190]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
[182]51 if (authEnabled) {
[190]52 toClientQueue.Enqueue ("Please enter password:");
[182]53 } else {
54 LoginMessage ();
55 }
[132]56 }
[75]57
[182]58 private void LoginMessage ()
[132]59 {
[190]60 toClientQueue.Enqueue ("*** Connected with 7DTD server.");
[202]61 toClientQueue.Enqueue ("*** Server version: " + GamePrefs.GetString(EnumGamePrefs.GameVersion));
[190]62 toClientQueue.Enqueue ("*** Dedicated server only build");
63 toClientQueue.Enqueue ("*** Allocs server fixes loaded");
64 toClientQueue.Enqueue (string.Empty);
65 toClientQueue.Enqueue ("Server IP: " +
[182]66 ((GamePrefs.GetString (EnumGamePrefs.ServerIP) != null && GamePrefs.GetString (EnumGamePrefs.ServerIP).Length != 0) ? GamePrefs.GetString (EnumGamePrefs.ServerIP) : "Any")
67 );
[190]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);
[75]77 }
78
[182]79 private void ReceiveThread ()
[132]80 {
[182]81 try {
[190]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:");
[182]97 } else {
[190]98 toClientQueue.Enqueue ("Too many failed login attempts!");
99 Thread.Sleep (100);
100 Close (true);
101 break;
[182]102 }
103 }
[190]104 } else {
105 if (line.ToLower ().Equals ("exit")) {
106 break;
107 }
108 Log.Out ("Telnet executed \"" + line + "\" from: " + endpoint);
109 ConsoleOutputSeparator.QueueNetCommand (line, this);
[182]110 }
111 }
112 }
[190]113 } catch (Exception) {
[132]114 }
[182]115
[190]116 if (!closed)
117 Close ();
118 ThreadMaster.Remove (Thread.CurrentThread.Name);
[132]119 }
120
[182]121 private void SendThread ()
[132]122 {
123 try {
[190]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 {
[182]130 byte[] utfData = Encoding.UTF8.GetBytes (line);
[190]131 client.GetStream ().Write (utfData, 0, utfData.Length);
132 client.GetStream ().WriteByte (13);
133 client.GetStream ().WriteByte (10);
[182]134 }
135 }
[91]136 }
[190]137 } catch (Exception) {
[75]138 }
[182]139
[190]140 if (!closed)
141 Close ();
142 ThreadMaster.Remove (Thread.CurrentThread.Name);
[75]143 }
144
[190]145 public void Close (bool kickedForLogins = false)
[182]146 {
[190]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 }
[182]159 }
160
[190]161 public void SendLine (string line)
[132]162 {
[190]163 if (!closed && IsAuthenticated)
164 toClientQueue.Enqueue (line);
165 else
166 toClientQueue.Enqueue (null);
[132]167 }
[75]168
[190]169 public void SendLog (string text, string trace, UnityEngine.LogType type)
[132]170 {
[190]171 throw new System.NotImplementedException ();
[75]172 }
173
[190]174 public string GetDescription ()
[132]175 {
[190]176 return "Telnet from " + endpoint;
[132]177 }
[75]178 }
179}
Note: See TracBrowser for help on using the repository browser.