/// <summary>Returns a congratulation message when given "CONNECTED"</summary> /// <param name="User"></param> /// <param name="Command"></param> /// <returns></returns> public override string Parse(ref SwitchboardUser User, string Command) { if (Command == "CONNECTED") { return("Congrats! You've connected to the server!"); } return(null); }
public override string Parse(ref SwitchboardUser User, string Command) { string[] CommandSplit = Command.Split(' '); switch (CommandSplit[0].ToUpper()) { case "VER": //Return version of this server return(HeadServer.TheForm.Config.ServerName + " [Version " + HeadServer.TheForm.Config.ServerVersion + "]"); case "SHOWEXTENSIONS": //Show all extensions on this server String AllExtensions = HeadServer.Extensions.Count + " Extension(s)\n\n"; foreach (SwitchboardExtension Extension in HeadServer.Extensions) { AllExtensions += Extension.GetName() + " [Version " + Extension.GetVersion() + "]\n"; } return(AllExtensions); case "HELP": //Show Server Help (Or the help of a specific command) if (CommandSplit.Length == 1) { return(Help()); } foreach (SwitchboardExtension Extension in HeadServer.Extensions) { if (Extension.GetName().ToUpper() == CommandSplit[1].ToUpper()) { return(Extension.Help()); } } return("Could not find extension " + CommandSplit[1]); case "SETPASS": //Set the password of the current user if (CommandSplit.Length != 3 || Command.Contains("~")) { return("Could not update password due to invalid characters"); } if (User == HeadServer.AnonymousUser) { return("cannot set password if user is not logged in"); } if (User.SetPassword(CommandSplit[1], CommandSplit[2])) { HeadServer.SaveUsers(); //Make sure to save all users. return("Successfully updated password!"); } return("Server was unable to update your password"); default: //Return nada because we could not parse it. return(null); } }
//------------------------------[Constructor]------------------------------ /// <summary>Creates and starts a Switchboard Server</summary> /// <param name="TheForm">Form that's managing this server</param> /// <param name="IP">IP to listen on</param> /// <param name="Port">Port to listen on</param> /// <param name="WelcomeMessage">Welcome message for each user.</param> /// <param name="AllowAnonymous">Allow Anonymous Users on this server.</param> /// <param name="AllowMultiLogin">Allow logins with the same user on different collections</param> internal SwitchboardServer(MainForm TheForm, string IP, int Port, string WelcomeMessage, bool AllowAnonymous, bool AllowMultiLogin) { //Get us our pen LogPen = File.AppendText("SwitchboardLog.log"); LogPen.WriteLine("\n\n" + TheForm.Config.ServerName + " [Version " + TheForm.Config.ServerVersion + "]\n\n" + "[" + DateTime.Now.ToShortDateString() + "] Starting Server..."); //Get us the main form this.TheForm = TheForm; //Get the welcome message this.WelcomeMessage = WelcomeMessage; //Register the extensions from the Switchboard Configuration and add the default extensions. ToLog("Registering extensions..."); Extensions = TheForm.Config.ServerExtensions(); Extensions.Add(new DummyExtension()); Extensions.Add(new SwitchboardMainExtension(this)); //Load users ToLog("Loading Users..."); Users = new List <SwitchboardUser>(); if (File.Exists("SwitchboardUsers.txt")) { //Read all lines from the file string[] UserStrings = File.ReadAllLines("SwitchboardUsers.txt"); //For each userstring, add a new user foreach (String UserString in UserStrings) { Users.Add(new SwitchboardUser(UserString)); } } //Allow Anonymous and generate the anonymous user. this.AllowAnonymous = AllowAnonymous; AnonymousUser = new SwitchboardUser("Anonymous", "", 0, ""); this.AllowMultiLogin = AllowMultiLogin; //Display a warning in case there are no users and we do not allow anonymous access. if (Users.Count == 0 && !AllowAnonymous) { ToLog("WARNING! No registered users and now annonymous access! You won't be able to actually use this server!"); } //Create the Connections list ToLog("One last thing..."); Connections = new Dictionary <int, SwitchboardConnection>(); //Finally, Actually start the server. ToLog("Actually starting the server..."); Ears = new TcpListener(IPAddress.Parse(IP), Port); Ears.Start(); ToLog("Server started!"); }
//~~~~~~~~~~~~~~{Constructor}~~~~~~~~~~~~~~ public SwitchboardConnection(SwitchboardServer HeadServer, Socket MainSocket, int ID) { this.ID = ID; ConnectedSince = DateTime.Now; IP = (IPEndPoint)MainSocket.RemoteEndPoint; River = new NetworkStream(MainSocket); TheSocket = MainSocket; this.HeadServer = HeadServer; HeadServer.ToLog("New user connected from " + IP.Address.ToString()); User = HeadServer.AnonymousUser; ConsolePreview = ""; }
//~~~~~~~~~~~~~~{Functions}~~~~~~~~~~~~~~ /// <summary>Ticks this connection. Essentially processes any input it may need to parse.</summary> public void Tick() { //If there's data available. if (IsConnected && River.DataAvailable) { //HeadServer.ToLog("Attempting to read message from " + IP.Address.ToString()); //no mas //Save all the bytes to an array List <byte> Bytes = new List <byte>(); while (River.DataAvailable) { Bytes.Add((byte)River.ReadByte()); } //Parse that array of bytes as a ASCII encoded string string Command = Encoding.ASCII.GetString(Bytes.ToArray()); //Handle VBNullChar or \0 in this case. Command = Command.Replace("\0", ""); //Add this to the list of commands. ConsolePreview += IP.Address + "> " + Command; //Now let's try to parse it. string Reply = ""; string[] CommandSplit = Command.Split(' '); switch (CommandSplit[0].ToUpper()) { case "WELCOME": Reply = HeadServer.GetWelcomeMessage(); break; case "LOGIN": if (User != HeadServer.AnonymousUser) { Reply = "2"; } //ALREADY else if (CommandSplit.Length != 3) { Reply = "1"; } //INVALID else { SwitchboardUser myUser = null; //Find the user. foreach (SwitchboardUser User in HeadServer.Users) { if (User.GetUsername().ToUpper() == CommandSplit[1].ToUpper()) { myUser = User; break; } } if (myUser != null && myUser.VerifyPassword(CommandSplit[2])) { if (myUser.IsOnline() && !HeadServer.AllowMultiLogin) { Reply = "3"; } //OTHERLOCALE else { User = myUser; User.SetOnline(true); //Refresh the list, this connection has logged in try { HeadServer.TheForm.ServerBWorker.ReportProgress(0); } catch (Exception) {} //In a try because this may cause a problem if two users try to log in at the same time. The user will still sign in though, so this would sitll //refresh anyways, so no need to worry. Reply = "0"; //SUCCESS } } else { Reply = "1"; } //INVALID } break; case "LOGOUT": if (User == HeadServer.AnonymousUser) { Reply = "0"; } else { User.SetOnline(false); User = HeadServer.AnonymousUser; HeadServer.TheForm.ServerBWorker.ReportProgress(0); //Refresh the list, this connection has logged out. Reply = "1"; } break; case "CLOSE": Close(true); return; case "USERINFO": if (CommandSplit.Length == 1) { Reply = User.InfoString(); } if (CommandSplit.Length == 2) { //Check if they want info on the anonymous user if (CommandSplit[1].ToUpper() == HeadServer.AnonymousUser.GetUsername().ToUpper()) { Reply = HeadServer.AnonymousUser.InfoString(); break; } //Find the given user foreach (SwitchboardUser U in HeadServer.Users) { if (U.GetUsername().ToUpper() == CommandSplit[1].ToUpper()) { Reply = U.InfoString(); break; } } //Make sure that if we haven't found it, we say we didn't find it. if (string.IsNullOrWhiteSpace(Reply)) { Reply = "NOTFOUND~-1~0"; } } break; case "ID": Reply = ID + ""; break; case "REBIND": //Check if the rebind exist try { int OtherConnectionID = int.Parse(CommandSplit[1]); if (OtherConnectionID == ID) { Reply = "Could not rebind connection " + ID + ". Cannot rebind connection to itself"; break; } if (!HeadServer.Connections.ContainsKey(OtherConnectionID)) { Reply = "Could not rebind connection " + OtherConnectionID + ". It was not found."; break; } HeadServer.Connections[OtherConnectionID].AbsorbConnection(this); //Absorbing this connection should stop the thread but just in case TickThread.Abort(); } catch (Exception E) { Reply = "An Exception Occurred:\n\n" + E.Message + "\n" + E.StackTrace; } break; case "REPEAT": Reply = LastMessage; break; default: if (!HeadServer.AllowAnonymous && User == HeadServer.AnonymousUser) { Reply = "You're unauthorized to run any other commands."; } else { foreach (SwitchboardExtension extension in HeadServer.Extensions) { if (!string.IsNullOrEmpty(Reply)) { break; } Reply = extension.Parse(ref User, Command); } if (string.IsNullOrEmpty(Reply)) { Reply = "Could not parse command [" + Command + "]"; } } break; } if (string.IsNullOrWhiteSpace(Reply)) { Reply = "An unspecified error occured"; } //Time to return whatever it is we got. Send(Reply); //and we're done. } }
//In implementation, the settings function should probably launch a tiny winform. //Your extension, should it have settings, should be able to save them, and load them when being instantiated. //Settings subroutine should only launch while the server *isn't running* /// <summary>Parses a given command.</summary> /// <param name="User">USER attempting to execute a command within this extension</param> /// <param name="Command">The command the user is trying to execute</param> /// <returns>A string if the extension was able to parse it, otherwise null</returns> public abstract string Parse(ref SwitchboardUser User, string Command);