/// <summary> /// Remove terminal from disconnected telnet client /// </summary> /// <param name="telnetClient"></param> private void ClientDisconnected(TelnetClient telnetClient) { var terminalManager = Services.GetService <IModuleManager>().GetManager <ITerminalManager>(); terminalManager.DestroyTerminal(telnetClient.GetTerminal()); telnetClient.SetTerminal(null); }
/// <summary> /// Gets the socket by client. /// </summary> /// <param name="client">The client instance.</param> /// <returns>If the client is found, the socket is /// returned; otherwise null is returned.</returns> private Socket GetSocketByClient(TelnetClient client) { Socket s; s = clients.FirstOrDefault(x => x.Value.GetClientID() == client.GetClientID()).Key; return(s); }
private void MFCAdminItemTree(TelnetClient telnetClient, string message) { var response = telnetClient.GetTerminal().SendToApi(new CoreReadItemGraphRequest() { ItemId = new Guid("f4212bfe-ef65-4632-df2b-08d63af92e75") }); telnetClient.GetTerminal().SendToClientAsync(response); }
/// <summary> /// Handle Message From Client when emote command is issued /// </summary> /// <param name="telnetClient"></param> /// <param name="message"></param> private void MFCEmote(TelnetClient telnetClient, string message) { WorldEmoteType?emoteType = null; emoteType = (message == "smile") ? WorldEmoteType.Smile : emoteType; emoteType = (message == "frown") ? WorldEmoteType.Frown : emoteType; telnetClient.GetTerminal().SendToApi(new WorldPerformEmoteRequest() { EmoteType = emoteType.Value }); }
/// <summary> /// Assign new telnet client an environment terminal and send greeting /// </summary> /// <param name="telnetClient"></param> private void ClientConnected(TelnetClient telnetClient) { var terminalManager = Services.GetService <IModuleManager>().GetManager <ITerminalManager>(); telnetClient.SetTerminal(terminalManager.RequestTerminal("Telnet", telnetClient.GetRemoteAddress())); telnetClient.GetTerminal().GetDataBag()["step"] = "connected"; TelnetServer.ClearClientScreen(telnetClient); TelnetServer.SendMessageToClient(telnetClient, "Terminal granted " + telnetClient.GetTerminal().GetId() + ".\r\n\r\n" + "Welcome to Before Our Time. For help type \"help\".\r\n\r\n" + "Welcome> "); }
private void MFCAdminItemJsonRead(TelnetClient telnetClient, string itemId) { var response = telnetClient.GetTerminal().SendToApi(new CoreReadItemJsonRequest() { IncludeChildren = false, ItemIds = new List <Guid>() { new Guid(itemId) } }); telnetClient.GetTerminal().SendToClientAsync(response); }
/// <summary> /// Process a message from the telnet client (MFC) to the terminal /// </summary> /// <param name="telnetClient"></param> /// <param name="message"></param> private void MessageFromClient(TelnetClient telnetClient, string message) { if (telnetClient.GetTerminal().GetStatus() == TerminalStatus.Guest) { MFCTerminalGuest(telnetClient, message); } else if (telnetClient.GetTerminal().GetStatus() == TerminalStatus.Authenticated) { MFCTerminalAuthenticated(telnetClient, message); } else if (telnetClient.GetTerminal().GetStatus() == TerminalStatus.Attached) { MFCTerminalAttached(telnetClient, message); } }
private void MFCAdminItemJsonUpdate(TelnetClient telnetClient, string itemId, string json) { var response = telnetClient.GetTerminal().SendToApi(new CoreUpdateItemJsonRequest() { ItemsJson = new List <CoreItemJson>() { new CoreItemJson() { Id = itemId, IncludeChildren = true, JSON = json } } }); telnetClient.GetTerminal().SendToClientAsync(response); }
/// <summary> /// Handle Message From Client when Go command is issued /// </summary> /// <param name="telnetClient"></param> /// <param name="message"></param> private void MFCGo(TelnetClient telnetClient, string message) { string secondWord = message.Split(' ').LastOrDefault(); var exitResponse = telnetClient.ItemExits .Where(x => x.Name.ToLower() .Contains(secondWord.ToLower())) .FirstOrDefault(); if (exitResponse != null) { var response = telnetClient.GetTerminal().SendToApi(new CoreUseItemRequest() { ItemId = exitResponse.Item.Id }); telnetClient.GetTerminal().SendToClientAsync(response); } else { TelnetServer.SendMessageToClient(telnetClient, "\r\nGo where??\r\n> "); } }
/// <summary> /// Handles an incoming connection. /// If incoming connections are allowed, /// the client is added to the clients list /// and triggers the client connected event. /// Else, the connection blocked event is /// triggered. /// </summary> private void HandleIncomingConnection(IAsyncResult result) { try { Socket oldSocket = (Socket)result.AsyncState; if (acceptIncomingConnections) { Socket newSocket = oldSocket.EndAccept(result); uint clientID = (uint)clients.Count + 1; TelnetClient client = new TelnetClient(clientID, (IPEndPoint)newSocket.RemoteEndPoint); clients.Add(newSocket, client); // Do Echo // Do Remote Flow Control // Will Echo // Will Suppress Go Ahead SendBytesToSocket( newSocket, new byte[] { 0xff, 0xfd, 0x01, 0xff, 0xfd, 0x21, 0xff, 0xfb, 0x01, 0xff, 0xfb, 0x03 } ); client.resetReceivedData(); ClientConnected(client); serverSocket.BeginAccept(new AsyncCallback(HandleIncomingConnection), serverSocket); } else { ConnectionBlocked((IPEndPoint)oldSocket.RemoteEndPoint); } } catch { } }
/// <summary> /// Handle Message From Client when associated terminal is in authenticated status /// </summary> /// <remarks> /// Handles all messages when DataBag step is "create_character" /// </remarks> /// <param name="telnetClient">Telnet client</param> /// <param name="message">message from client</param> private void MFCTerminalAuthenticatedCreatePlayer(TelnetClient telnetClient, string message) { if (!telnetClient.GetTerminal().GetDataBag().ContainsKey("create_character_step")) { telnetClient.GetTerminal().GetDataBag()["create_character_step"] = "create"; } switch (telnetClient.GetTerminal().GetDataBag()["create_character_step"]) { case "create": TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Ok, let's create a new character.\r\n\r\n" + " Name: "); telnetClient.GetTerminal().GetDataBag()["create_character_step"] = "save_name"; break; case "save_name": telnetClient.GetTerminal().GetDataBag()["create_character_name"] = message; if (telnetClient.GetTerminal().CreatePlayer(telnetClient.GetTerminal().GetDataBag()["create_character_name"])) { telnetClient.GetTerminal().GetDataBag()["step"] = "attached"; TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Terminal attached to avatar. Play!\r\n\r\n" + "> "); } else { telnetClient.GetTerminal().GetDataBag()["step"] = "attached"; telnetClient.GetTerminal().GetDataBag().Remove("create_character_name"); telnetClient.GetTerminal().GetDataBag().Remove("create_character_step"); TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Something went wrong. Character not created.\r\n\r\n" + "Account> "); } break; } }
/// <summary> /// Kicks the specified client from the server. /// </summary> /// <param name="client">The client.</param> public void KickClient(TelnetClient client) { CloseSocket(GetSocketByClient(client)); ClientDisconnected(client); }
/// <summary> /// Sends a text message to the specified /// client. /// </summary> /// <param name="c">The client.</param> /// <param name="message">The message.</param> public void SendMessageToClient(TelnetClient c, string message) { Socket clientSocket = GetSocketByClient(c); SendMessageToSocket(clientSocket, message); }
/// <summary> /// Clears the screen for the specified /// client. /// </summary> /// <param name="c">The client on which /// to clear the screen.</param> public void ClearClientScreen(TelnetClient c) { SendMessageToClient(c, "\u001B[1J\u001B[H"); }
/// <summary> /// Handle Message From Client when associated terminal is in authenticated status /// </summary> /// <param name="telnetClient">Telnet client</param> /// <param name="message">message from client</param> private void MFCTerminalAuthenticated(TelnetClient telnetClient, string message) { if (telnetClient.GetTerminal().GetDataBag()["step"] == "create_character") { MFCTerminalAuthenticatedCreatePlayer(telnetClient, message); } else if (telnetClient.GetTerminal().GetDataBag()["step"] == "authenticated") { switch (message.Split(' ').First().ToLower()) { case "?": case "help": TelnetServer.SendMessageToClient(telnetClient, "\r\n\r\n" + " new - Create a new character\r\n" + " list - List existing characters\r\n" + " play {name} - Play an existing character\r\n" + " back - Return to previous screen\r\n" + " bye - Disconnect\r\n\r\n" + "Account> "); break; case "back": telnetClient.GetTerminal().SetStatus(TerminalStatus.Guest); telnetClient.GetTerminal().GetDataBag()["step"] = "connected"; TelnetServer.SendMessageToClient(telnetClient, "\r\nWelcome> "); break; case "new": telnetClient.GetTerminal().GetDataBag()["step"] = "create_character"; MFCTerminalAuthenticatedCreatePlayer(telnetClient, message); break; case "list": TelnetServer.SendMessageToClient(telnetClient, "\r\n\r\n"); var characters = telnetClient.GetTerminal().GetAttachable(); characters.ForEach(delegate(Item player) { TelnetServer.SendMessageToClient(telnetClient, " " + player.GetProperty <VisibleItemProperty>().Name + " (" + player.Id + ")\r\n"); }); TelnetServer.SendMessageToClient(telnetClient, "\r\n"); TelnetServer.SendMessageToClient(telnetClient, "Account> "); break; case "q": case "bye": TelnetServer.SendMessageToClient(telnetClient, "Cya...\r\n"); TelnetServer.KickClient(telnetClient); break; case "play": var name = message.Split(' ').Last().ToLower(); telnetClient.GetTerminal().GetAttachable().ForEach(delegate(Item player) { if (player.GetProperty <VisibleItemProperty>().Name.ToLower() == name) { telnetClient.GetTerminal().Attach(player.Id); telnetClient.GetTerminal().GetDataBag()["step"] = "attached"; TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Terminal attached to avatar. Play!\r\n\r\n" + "> "); } }); if (telnetClient.GetTerminal().GetStatus() != TerminalStatus.Attached) { TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Unknown character \"" + name + "\"\r\n" + "Account> "); } break; default: TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Unknown account command \"" + message + "\". Try \"help\".\r\n\r\n" + "Account> "); break; } } }
/// <summary> /// Handle Message From client when associated terminal is in attached status (playing!) /// </summary> /// <param name="telnetClient"></param> /// <param name="message"></param> private void MFCTerminalAttached(TelnetClient telnetClient, string message) { string firstWord = message.Split(' ').First(); switch (firstWord) { case "admin": var words = message.Split(' '); if (message == "admin item graph") { MFCAdminItemTree(telnetClient, message); } if (words[1] == "item" && words[2] == "json" && words[3] == "update") { var json = message.Remove(0, message.IndexOf('{')); MFCAdminItemJsonUpdate(telnetClient, words[4], json); } if (words[1] == "item" && words[2] == "json" && words[3] == "read") { MFCAdminItemJsonRead(telnetClient, words[4]); } break; case "bye": case "q": case "exit": TelnetServer.SendMessageToClient(telnetClient, "\r\n\r\nCya...\r\n"); TelnetServer.KickClient(telnetClient); break; case "look": var response = telnetClient.GetTerminal().SendToApi(new WorldReadLocationSummaryRequest() { }); telnetClient.GetTerminal().SendToClientAsync(response); break; case "go": MFCGo(telnetClient, message); break; case "smile": case "frown": MFCEmote(telnetClient, message); break; case "help": TelnetServer.SendMessageToClient(telnetClient, "\r\n\r\n" + " - Admin item graph\r\n" + " - Admin item json update {guid} {json}\r\n" + " - Admin item json read {guid}\r\n" + " - Look\r\n" + " - Bye\r\n" + " - Go {exit name, or partial exit name}\r\n" + " - Smile\r\n" + " - Frown\r\n\r\n> "); break; default: TelnetServer.SendMessageToClient(telnetClient, "\r\nBad command. Try \"help\"\r\n> "); break; } }
/// <summary> /// Receives and processes data from a socket. /// It triggers the message received event in /// case the client pressed the return key. /// </summary> private void ReceiveData(IAsyncResult result) { try { Socket clientSocket = (Socket)result.AsyncState; TelnetClient client = GetClientBySocket(clientSocket); int bytesReceived = clientSocket.EndReceive(result); if (bytesReceived == 0) { CloseSocket(clientSocket); serverSocket.BeginAccept(new AsyncCallback(HandleIncomingConnection), serverSocket); } else if (data[0] < 0xF0) { string receivedData = client.GetReceivedData(); // 0x2E = '.', 0x0D = carriage return, 0x0A = new line if ((data[0] == 0x2E && data[1] == 0x0D && receivedData.Length == 0) || (data[0] == 0x0D)) { //sendMessageToSocket(clientSocket, "\u001B[1J\u001B[H"); MessageReceived(client, client.GetReceivedData()); client.resetReceivedData(); } else { // 0x08 => backspace character if (data[0] == 0x08 || data[0] == 0x7f) { if (receivedData.Length > 0) { client.RemoveLastCharacterReceived(); SendBytesToSocket(clientSocket, new byte[] { 0x08, 0x20, 0x08 }); } else { clientSocket.BeginReceive(data, 0, dataSize, SocketFlags.None, new AsyncCallback(ReceiveData), clientSocket); } } // 0x7F => delete character else if (data[0] == 0x7F) { clientSocket.BeginReceive(data, 0, dataSize, SocketFlags.None, new AsyncCallback(ReceiveData), clientSocket); } else { client.appendReceivedData(Encoding.ASCII.GetString(data, 0, bytesReceived)); // Echo back the received character // if client is not writing any password if (client.GetCurrentStatus() != EClientStatus.Authenticating) { SendBytesToSocket(clientSocket, new byte[] { data[0] }); } // Echo back asterisks if client is // writing a password else { SendMessageToSocket(clientSocket, "*"); } clientSocket.BeginReceive(data, 0, dataSize, SocketFlags.None, new AsyncCallback(ReceiveData), clientSocket); } } } else { clientSocket.BeginReceive(data, 0, dataSize, SocketFlags.None, new AsyncCallback(ReceiveData), clientSocket); } } catch (ObjectDisposedException) { } }
/// <summary> /// Handle Message From Client when associated terminal is in guest status /// </summary> /// <param name="telnetClient">Telnet client</param> /// <param name="message">message from client</param> private void MFCTerminalGuest(TelnetClient telnetClient, string message) { if (telnetClient.GetTerminal().GetDataBag()["step"] == "connected") { switch (message.ToLower()) { case "?": case "help": TelnetServer.SendMessageToClient(telnetClient, "\r\n\r\n" + " new - Create a new account\r\n" + " login - Login to an existing account\r\n" + " bye - Disconnect\r\n\r\n" + "Welcome> "); break; case "q": case "bye": TelnetServer.SendMessageToClient(telnetClient, "\r\nCya...\r\n\r\n"); TelnetServer.KickClient(telnetClient); break; case "new": TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Name: "); telnetClient.GetTerminal().GetDataBag()["step"] = "create_name"; break; case "login": TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Email: "); telnetClient.GetTerminal().GetDataBag()["step"] = "login_name"; break; default: TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Unknown welcome command \"" + message + "\". Try \"help\".\r\n\r\n" + "Welcome> "); break; } } else if (telnetClient.GetTerminal().GetDataBag()["step"] == "login_name") { telnetClient.GetTerminal().GetDataBag()["login_name"] = message; telnetClient.GetTerminal().GetDataBag()["step"] = "login_password"; TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Password: "******"step"] == "login_password") { var loginRequest = new AccountLoginAccountRequest() { Email = telnetClient.GetTerminal().GetDataBag()["login_name"], Password = message }; AccountLoginAccountResponse loginResponse = (AccountLoginAccountResponse)telnetClient.GetTerminal().SendToApi(loginRequest); if (loginResponse.IsSuccess()) { telnetClient.GetTerminal().Authenticate(loginResponse.Account.Id); telnetClient.GetTerminal().SubscribeMessageToTerminal(MessageFromTerminal); Clients[telnetClient.GetTerminal().GetId()] = telnetClient; telnetClient.GetTerminal().GetDataBag()["step"] = "authenticated"; TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Hello " + telnetClient.GetTerminal().GetDataBag()["login_name"] + "\r\n\r\n" + "Account> "); } else { telnetClient.GetTerminal().GetDataBag()["step"] = "connected"; TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Bad username or password.\r\n\r\n" + "Welcome> "); } } else if (telnetClient.GetTerminal().GetDataBag()["step"] == "create_name") { telnetClient.GetTerminal().GetDataBag()["create_name"] = message; telnetClient.GetTerminal().GetDataBag()["step"] = "create_email"; TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Email: "); } else if (telnetClient.GetTerminal().GetDataBag()["step"] == "create_email") { telnetClient.GetTerminal().GetDataBag()["create_email"] = message; telnetClient.GetTerminal().GetDataBag()["step"] = "create_password"; TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Password: "******"step"] == "create_password") { var createAccountResponse = telnetClient.GetTerminal().SendToApi(new AccountCreateAccountRequest() { Email = telnetClient.GetTerminal().GetDataBag()["create_email"], Password = message }); if (createAccountResponse.IsSuccess()) { telnetClient.GetTerminal().SubscribeMessageToTerminal(MessageFromTerminal); Clients[telnetClient.GetTerminal().GetId()] = telnetClient; telnetClient.GetTerminal().GetDataBag()["step"] = "authenticated"; TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Hello " + telnetClient.GetTerminal().GetDataBag()["create_name"] + "\r\n\r\n" + "Account> "); } else { TelnetServer.SendMessageToClient(telnetClient, "\r\n" + "Unable to create account (but I still like you).\r\n\r\n" + "Welcome> "); } } }