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

Last change on this file since 190 was 190, checked in by alloc, 6 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.