예제 #1
0
        public static void InputInterpreter(Client commandingClient)
        {
            string clientInput         = ""; // Pliant clients give silent compliance...
            string parsedCommand       = "";
            string adjustedClientInput = "";

            List <string> commandList = new List <string> {
                "quit!", "dog", "say", "help", "chist", "lusers"
            };
            List <string> adminCommandList = new List <string> {
                "nuser", "laccounts", "kick", "ban", "unban", "xmltest", "loadcheck", "findroom"
            };
            List <string> verbList = new List <string> {
                "quit!", "say", "kick", "ban", "unban"
            };

            clientInput = commandingClient.incoming.ReadLine();  // Get the input.
            ArrayList commandingClients = new ArrayList();

            try
            {
                if (Regex.Match(clientInput, "^[/:]{1}").Success&& commandingClient.isAdmin)
                {
                    commandingClient.outgoing.WriteLine("You typed an admin command indicator (/,:).");
                    commandingClient.outgoing.WriteLine("These commands are not yet implemented.");
                }//if (clientInput.IndexOf(" ") != -1) // Three ways I can see to do this: These two and a regex. What would be the least resource-intensive?
                else if (clientInput.Contains(' ')) // If there's a space, then there are multiple words in the string and the first word might be a command.
                {
                    parsedCommand       = Regex.Match(clientInput, "^\\S*\\b{1}").Value;           // Parse the first word out of the string, below we'll compare it against our list of commands to see if it's a valid command.
                    adjustedClientInput = Regex.Replace(clientInput, "^\\S*\\s{1}", string.Empty); // And here's the content of the supposed command.
                }
                else
                {
                    parsedCommand = clientInput.ToLower(); // If there are no spaces, then the input is all one word, and we'll check to see if THAT is a command.
                    // first check to see if the player is trying to exit the room
                    foreach (EXIT exitEnum in commandingClient.currentRoom.exits)
                    {
                        if (exitEnum.exitName.ToLower() == parsedCommand.ToLower())
                        {
                            RoomHandler.changeRoom(commandingClient, RoomHandler.findRoom(exitEnum.exitDestination));
                            parsedCommand = "roomchange";
                            break;
                        }
                    }
                }

                //Input method to check the parsed command against any special commands defined by the room the player is currently in.

                if (adminCommandList.Contains(parsedCommand))
                {
                    if (commandingClient.isAdmin)
                    {
                        switch (parsedCommand) // What would be a better method of listing commands? // For admin commands, this needs to check for privilege level.
                        {                      // Maybe listing the commands in a database table and polling for something that matches the input?
                        case "nuser":
                            NewUser(commandingClient);
                            break;

                        case "laccounts":      // List all usernames in the database. In the future I'll add a few flags to these db entries which will be displayed here.
                            ListAccounts(commandingClient);
                            break;

                        case "kick":
                            KickUser(commandingClient, adjustedClientInput);
                            break;

                        case "ban":
                            BanUser(commandingClient, adjustedClientInput);
                            break;

                        case "unban":
                            UnBanUser(commandingClient, adjustedClientInput);
                            break;

                        case "xmltest":
                            RoomHandler.readRoom(commandingClient, "../../TestRoom1.xml");
                            break;

                        case "loadcheck":
                            commandingClient.outgoing.WriteLine("Reading room data...");
                            RoomHandler.showLoadedRooms(commandingClient);
                            commandingClient.outgoing.WriteLine("Finished.");
                            break;

                        case "findroom":
                            commandingClient.outgoing.WriteLine("Looking for room: " + adjustedClientInput);
                            commandingClient.outgoing.WriteLine(RoomHandler.findRoom(adjustedClientInput).roomName);
                            break;

                        default:
                            break;
                        }
                    }
                    else
                    {
                        commandingClient.outgoing.WriteLine("\nYou must be an admin to use that command.");
                    }
                }
                else // if(commandList.Contains(parsedCommand))  // Can add this in if we want to give the user an error when they give input that is not in the command list, instead of simply treating it like a Say command.
                {
                    switch (parsedCommand.ToLower())
                    {
                    case "quit!":
                        commandingClient.disconnectFlag = true;
                        break;

                    case "dog":
                        commandingClient.outgoing.WriteLine("\nYou found the secret word!");      // Because, dammit!
                        break;

                    case "say":
                        ChatServer.Chat(commandingClient, adjustedClientInput, "Say");
                        break;

                    case "tell":
                        string tellTarget = Regex.Match(adjustedClientInput, "^\\S*\\b{1}").Value;
                        adjustedClientInput = Regex.Replace(adjustedClientInput, "^\\S*\\s{1}", string.Empty);
                        Console.WriteLine(tellTarget + ":" + adjustedClientInput);
                        ChatServer.Tell(commandingClient, tellTarget, adjustedClientInput);
                        break;

                    case "help":
                        commandingClients.Add(commandingClient);
                        OutputHandler.fileOutputHandler("HelpFile.txt", commandingClients);
                        commandingClients.Remove(commandingClient);
                        break;

                    case "chist":
                        DisplayChatHistory(commandingClient);
                        break;

                    case "lusers":
                        ListUsers(commandingClient);
                        break;

                    case "roomchange":
                        break;

                    default:
                        ChatServer.Chat(commandingClient, clientInput, "Say");      // If it's not in the recognized command list, treat it like the clientInput was preceeded by the Say command.
                        break;
                    }
                }
                if (!NetworkServer.clientsToDisconnect.Contains(commandingClient))
                {
                    commandingClient.outgoing.Write("\nInput Please > ");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                LogHandler.LogAClientEvent(e.ToString(), commandingClient);
            }
        }
예제 #2
0
        public Client(TcpClient connectedClient)
        {
            //***************************************************
            // This is here to account for the extra bytes that fat ftp clients (putty, etc) will send upon an initial connection.
            // Eventually a proper telnet handler will exist and this won't be necessary.
            //byte[] bytesFromClient = new byte[32]; // Set the buffer size.


            //var testReader = connectedClient.GetStream().BeginRead(bytesFromClient, 0, bytesFromClient.Length, null, null); // Read all incoming bytes.
            //WaitHandle waiter = testReader.AsyncWaitHandle;
            //bool finishedRead = waiter.WaitOne(250, false); // If there are no bytes to read, we'll wait 1/4 of a second before continuing.
            //if (finishedRead)
            //{
            //    connectedClient.GetStream().EndRead(testReader);
            //    foreach (int i in bytesFromClient)
            //        Console.WriteLine("Read a byte:" + i); // This is for debugging.
            //}
            //else
            //{

            //    connectedClient.GetStream().EndRead(testReader);
            //}


            //***************************************************

            // Need to add a unique ID, possibly based on yearmonthdayhourminutesecondincrement pattern. This will be a session-unique ID,
            // but we also need an account-specific identifier.
            this.isAdmin        = false;
            this.connectedOn    = DateTime.Now; // When the client connected.
            this.disconnectFlag = false;
            this.loggedInFlag   = false;
            this.clientUsername = "******";

            this.connectedClient = connectedClient;
            this.clientIP        = IPAddress.Parse(((IPEndPoint)connectedClient.Client.RemoteEndPoint).Address.ToString());
            this.clientEndPoint  = connectedClient.Client.RemoteEndPoint;
            NetworkServer.clientsToLogIn.Add(this);
            Console.WriteLine("Client connected from: " + clientIP);
            this.daStream           = connectedClient.GetStream();
            this.incoming           = new StreamReader(daStream);
            this.outgoing           = new StreamWriter(daStream);
            this.outgoing.AutoFlush = true;  // Why?

            //this.daStream.ReadTimeout = 250;
            try
            {
                this.outgoing.Write("Press any key...");
                this.incoming.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            //this.daStream.ReadTimeout = -1;


            InputHandler.DisplayTextFile(this, "WelcomeScreen.txt");  // Display the welcome screen when the client connects.
            // Also need a mechanic for creating accounts
            while (!GateKeeper(this))
            {
            }
            this.loggedInFlag = true;

            Console.WriteLine(this.clientUsername + " logged in.");
            LogHandler.LogAClientEvent("connected", this);  // Is it better to put this here or within the GateKeeper?

            this.outgoing.WriteLine("Welcome " + clientUsername);
            ChatServer.globalChannel.Add(this);


            using (SqlConnection dbConnection = new SqlConnection(NetworkServer.connectionString))  // Move this to a method?
            {
                dbConnection.Open();
                SqlDataReader dbReader  = null;
                SqlCommand    dbCommand = new SqlCommand("select lastRoom from users where username like '" + clientUsername + "'", dbConnection);
                dbReader = dbCommand.ExecuteReader();
                dbReader.Read();
                string roomToFindInArrayList = dbReader["lastRoom"].ToString();
                lastRoom = RoomHandler.findRoom(roomToFindInArrayList);
                if (lastRoom == null)
                {
                    lastRoom = RoomHandler.findRoom("TestRoom1");
                }
            }
            onRoomChange(this, lastRoom);  // Make the client appear in the room there were in when they logged off.

            this.outgoing.Write("\nInput Please > ");
        }
예제 #3
0
        static void Main(string[] args) // Not sure if I want to take arguments yet, but keeping it here to remind myself
        {
            serverStarted = DateTime.Now;
            LogHandler.CheckForLogFile();
            LogHandler.LogServerStart();
            CheckForConfigFile();  // This is for future use.

            RoomHandler.loadAllRooms();

            IPAddress myip         = Dns.GetHostAddresses("localhost")[0]; // I want it to give me the ipv4 addy, or maybe I'm having a problem using telnet to connect to an ipv6 addy?
            IPAddress mystaticipv4 = IPAddress.Parse("192.168.1.128");     // V V V This is such an effing pain. V V V

            receptionist = new TcpListener(mystaticipv4, 7022);            // TcpListener(int port) will allow clients to connect to the server's ipv4 addy, but that method is considered 'deprecated' by visual studio :(
            // TCPListener(int port) will accept connections to any ip addy on the server
            receptionist.Start();

            Console.WriteLine("The receptionist is in. Lines are open at {0}, on port 7022.", myip); // Is it IPv6 notation because I'm using Windows 7?

            while (true)                                                                             // The main game loop
            {
                if (receptionist.Pending())                                                          // The plan is to move this to a parallel thread
                {
                    TcpClient client = receptionist.AcceptTcpClient();

                    Thread t = new Thread(() => Client.CreateClient(client));                              // Testing the idea of delegating the client creation to a seperate thread: So far, so good.
                    t.Start();
                    Console.WriteLine("We have a guest. They're in from " + client.Client.RemoteEndPoint); // This is fine for now, but this info should be appended to the client object for tracking purposes, also this should show the unique identifier for the client.
                }

                try
                {
                    foreach (Client dyingClient in clientsToDisconnect)
                    {
                        CloseClientConnection(dyingClient);
                    }
                    clientsToDisconnect.Clear();

                    foreach (Client loggingInClient in clientsToLogIn)
                    {
                        if (loggingInClient.loggedInFlag == true)
                        {
                            clients.Add(loggingInClient);
                        }
                    }

                    foreach (Client clientToReadWrite in clients)
                    {
                        //Console.WriteLine("In main foreach loop with" + clientToReadWrite.clientUsername);
                        if (clientsToLogIn.Contains(clientToReadWrite))
                        {
                            clientsToLogIn.Remove(clientToReadWrite);
                        }

                        if (clientToReadWrite.connectedClient.GetStream().DataAvailable)  // Is the connected client trying to send us input?
                        {
                            InputHandler.InputInterpreter(clientToReadWrite);
                        }
                        if (clientToReadWrite.disconnectFlag == true)
                        {
                            clientsToDisconnect.Add(clientToReadWrite);
                        }
                    }
                    ;
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    LogHandler.LogAServerEvent(e.ToString());
                }
            }
        }