source: binary-improvements/7dtd-server-fixes/src/AllocsNetTelnetServer.cs@ 74

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

7dtd server fixes

File size: 6.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Net;
5using System.Net.Sockets;
6using System.Reflection;
7using System.Threading;
8
9public class AllocsNetTelnetServer
10{
11 private class Connection
12 {
13 private bool authenticated = false;
14 private TcpClient client;
15 private NetworkStream stream;
16 private string lineBuffer = string.Empty;
17 private EndPoint endpoint;
18
19 public Connection (TcpClient client)
20 {
21 this.client = client;
22 this.stream = client.GetStream ();
23 this.endpoint = client.Client.RemoteEndPoint;
24 }
25
26 public EndPoint GetEndPoint ()
27 {
28 return endpoint;
29 }
30
31 private void WriteByte (byte v)
32 {
33 if (!IsClosed () && stream.CanWrite) {
34 stream.WriteByte (v);
35 }
36 }
37
38 public void WriteLine (string s)
39 {
40 if (!IsClosed () && stream.CanWrite) {
41 for (int i = 0; i < s.Length; i++) {
42 WriteByte ((byte)s [i]);
43 }
44 WriteByte (10);
45 }
46 }
47
48 public void Close ()
49 {
50 if (client != null)
51 client.Close ();
52 client = null;
53 }
54
55 public bool IsClosed ()
56 {
57 if (client != null && !client.Connected) {
58 Log.Out ("Telnet connection interrupted: " + endpoint);
59 }
60 return (client == null) || (!client.Connected);
61 }
62
63 public bool IsAuthenticated ()
64 {
65 return !authEnabled || authenticated;
66 }
67
68 public void SetAuthenticated ()
69 {
70 authenticated = true;
71 }
72
73 public bool Read ()
74 {
75 while (!IsClosed() && stream.CanRead && stream.DataAvailable) {
76 int b = stream.ReadByte ();
77 if (b == '\r' || b == '\n') {
78 if (lineBuffer.Length > 0)
79 return true;
80 } else {
81 lineBuffer += (char)b;
82 }
83 }
84 return false;
85 }
86
87 public string GetLine ()
88 {
89 string res = lineBuffer;
90 lineBuffer = string.Empty;
91 return res;
92 }
93 }
94
95 private static cl004c console = null;
96 private static Thread telnetThread = null;
97 private static TcpListener listener = null;
98 private static bool closed = false;
99 private static bool authEnabled = false;
100 private static List<Connection> conns = new List<Connection> ();
101
102 public static void init (int port)
103 {
104 Log.Out ("[7dtd-server-fixes by Alloc] Version: " + Assembly.GetExecutingAssembly().GetName().Version);
105 authEnabled = GamePrefs.GetString (EnumGamePrefs.TelnetPassword).Length != 0;
106 if (authEnabled)
107 listener = new TcpListener (IPAddress.Any, port);
108 else
109 listener = new TcpListener (IPAddress.Loopback, port);
110 telnetThread = ThreadMaster.Create ("thread Allocs TelnetListenThread", new ThreadStart (telnetListenThread));
111 telnetThread.Start ();
112 Log.Out ("Started Allocs NetTelnetServer thread on " + port);
113 }
114
115 private static void telnetListenThread ()
116 {
117 try {
118 Log.Out ("Started thread_Allocs_TelnetListenThread()");
119 listener.Start ();
120 while (!closed) {
121 Thread.Sleep (10);
122 if (listener.Pending ()) {
123 Connection c = new Connection (listener.AcceptTcpClient ());
124 conns.Add (c);
125 Log.Out ("Telnet connection from: " + c.GetEndPoint ());
126 if (authEnabled) {
127 c.WriteLine ("Please enter password:");
128 } else {
129 LoginMessage (c);
130 }
131 }
132
133 foreach (Connection c in conns) {
134 if (c.IsClosed ()) {
135 c.Close ();
136 conns.Remove (c);
137 break;
138 }
139 if (c.Read ()) {
140 string line = lineCorrecter (c.GetLine ());
141 if (!c.IsAuthenticated ()) {
142 if (line.Equals (GamePrefs.GetString (EnumGamePrefs.TelnetPassword))) {
143 c.SetAuthenticated ();
144 c.WriteLine ("Logon successful.");
145 c.WriteLine (string.Empty);
146 c.WriteLine (string.Empty);
147 c.WriteLine (string.Empty);
148 LoginMessage (c);
149 } else {
150 c.WriteLine ("Password incorrect, please enter password:");
151 }
152 } else {
153 if (line.ToLower ().Equals ("exit")) {
154 Log.Out ("Telnet connection closed by client: " + c.GetEndPoint ());
155 c.Close ();
156 conns.Remove (c);
157 break;
158 }
159
160 Log.Out ("Telnet executed \"" + line + "\" from: " + c.GetEndPoint ());
161 console.md000f (line);
162 }
163 }
164 }
165 }
166 Log.Out ("Exited thread_Allocs_TelnetListenThread()");
167 ThreadMaster.Remove (Thread.CurrentThread.Name);
168 } catch (Exception ex) {
169 Log.Out ("Error in Allocs telnetListenThread: " + ex.Message);
170 Log.Out ("Stack Trace: " + ex.StackTrace);
171 }
172 }
173
174 private static void LoginMessage (Connection c)
175 {
176 c.WriteLine ("*** Connected with 7DTD server.");
177 c.WriteLine ("*** Server version: Alpha 8.7 (b29) Compatibility Version: Alpha 8.7");
178 c.WriteLine (string.Empty);
179 c.WriteLine ("Server IP: " +
180 ((GamePrefs.GetString (EnumGamePrefs.ServerIP) != null && GamePrefs.GetString (EnumGamePrefs.ServerIP).Length != 0) ? GamePrefs.GetString (EnumGamePrefs.ServerIP) : "Any")
181 );
182 c.WriteLine ("Server port: " + GamePrefs.GetInt (EnumGamePrefs.ServerPort));
183 c.WriteLine ("Max players: " + GamePrefs.GetInt (EnumGamePrefs.ServerMaxPlayerCount));
184 c.WriteLine ("Game mode: " + GamePrefs.GetString (EnumGamePrefs.GameMode));
185 c.WriteLine ("World: " + GamePrefs.GetString (EnumGamePrefs.GameWorld));
186 c.WriteLine ("Game name: " + GamePrefs.GetString (EnumGamePrefs.GameName));
187 c.WriteLine ("Difficulty: " + GamePrefs.GetInt (EnumGamePrefs.GameDifficulty));
188 c.WriteLine (string.Empty);
189 c.WriteLine ("Press 'help' to get a list of all commands. Press 'exit' to end session.");
190 c.WriteLine (string.Empty);
191 }
192
193 private static string lineCorrecter (string line)
194 {
195 string res = "";
196 for (int i = 0; i < line.Length; i++) {
197 if (line [i] >= ' ' && line [i] != '\'' && line [i] <= '~') {
198 res += line [i];
199 }
200 }
201 return res.Trim ();
202 }
203
204 public static void Disconnect ()
205 {
206 closed = true;
207 if (listener != null) {
208 listener.Stop ();
209 }
210 foreach (Connection c in conns) {
211 c.Close ();
212 }
213 Thread.Sleep (100);
214 }
215
216 public static void SetConsole (cl004c console)
217 {
218 AllocsNetTelnetServer.console = console;
219 }
220
221 private static void RemoveClosedConnections ()
222 {
223 foreach (Connection c in conns) {
224 if (c.IsClosed ()) {
225 c.Close ();
226 }
227 }
228 }
229
230 public static void WriteToClient (string line)
231 {
232 if (line == null) {
233 return;
234 }
235 RemoveClosedConnections ();
236 foreach (Connection c in conns) {
237 if (c.IsAuthenticated())
238 c.WriteLine (line);
239 }
240 }
241}
Note: See TracBrowser for help on using the repository browser.