/// <summary> /// Initializes a new instance of a <see cref="TerminalEmulator"/> using the specified font to display text. /// </summary> public TerminalEmulator() { var options = new TerminalOptions(); options.LFlag = PtyConstants.ICANON | PtyConstants.ECHO; options.C_cc[PtyConstants.VERASE] = (byte)'\b'; options.C_cc[PtyConstants.VEOL] = (byte)'\r'; options.C_cc[PtyConstants.VEOL2] = (byte)'\n'; PseudoTerminal.CreatePair(out _master, out _slave, options); _stdout = new StreamWriter(_master); _stdin = new StreamReader(_master); _stdout.AutoFlush = true; HasFocusedChanged += (o, a) => { if (IsFocused) { _cursorOn = true; _cursorAnim = 0; Invalidate(true); } }; }
private async void OnTerminalOptionsChanged(object sender, TerminalOptions e) { await _applicationView.RunOnDispatcherThread(() => { BackgroundOpacity = e.BackgroundOpacity; }); }
private async void OnTerminalOptionsChanged(object sender, TerminalOptions e) { await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { BackgroundOpacity = e.BackgroundOpacity; }); }
public static async Task Main(string[] Arguments) { Splash(); Stage = Environment.GetEnvironmentVariable("SecureDNS_Enviroment") ?? "Production"; ApplicationData = Stage == "Production" ? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Texnomic", "SecureDNS - Terminal Edition") : Environment.CurrentDirectory; Directory.CreateDirectory(ApplicationData); if (!File.Exists(Path.Combine(ApplicationData, AppSettingsFile))) { await File.WriteAllBytesAsync(Path.Combine(ApplicationData, AppSettingsFile), ReadResource(AppSettingsFile)); await File.WriteAllBytesAsync(Path.Combine(ApplicationData, "AppSettings.Production.json"), ReadResource("AppSettings.Production.json")); await File.WriteAllBytesAsync(Path.Combine(ApplicationData, "AppSettings.Development.json"), ReadResource("AppSettings.Development.json")); } Configurations = new ConfigurationBuilder() .SetBasePath(ApplicationData) .AddJsonFile(AppSettingsFile, false, true) .AddJsonFile($"AppSettings.{Stage}.json", true, true) .AddUserSecrets <Program>(true, true) .AddEnvironmentVariables() .Build(); Options = Configurations.GetSection("Terminal Options").Get <TerminalOptions>(); BuildHost(); await HostBuilder.RunConsoleAsync(); }
public override OutputBuilder Render(TerminalOptions terminalOptions) { var topics = HelpManager.Instance.GetHelpTopics().Where(topic => topic.Aliases.Count > 0); var output = new OutputBuilder(); if (!topics.Any()) { output.AppendLine("There are no help topics written yet."); return(output); } // Format the first column to the number of characters to fit the longest topic, then have the description to the right of that. var lineFormat = "{0," + -1 * HelpManager.Instance.MaxPrimaryAliasLength + "} {1}"; output.AppendLine("Available help topics:"); output.AppendSeparator(color: "yellow"); foreach (var topic in topics) { var primaryAlias = topic.Aliases.FirstOrDefault(); output.AppendLine(string.Format(lineFormat, primaryAlias, "TODO: Topic Short Description Support Here")); } output.AppendSeparator(color: "yellow"); output.AppendLine(); output.AppendLine("<%yellow%>NOTE:<%n%> You can also use the \"<%green%>commands<%n%>\" command to list out commands, and you can get help for a specific command with \"<%green%>help <command name><%n%>\"."); return(output); }
protected void Dispose(bool disposing) { if (_debug > 0) { Console.WriteLine("TelnetSSH-Dispose-End"); } if (!this.disposed) { if (disposing) { _isRunning = false; this.close(); if (_Console != null) { _Console = null; } if (_terminalOptions != null) { _terminalOptions = null; } if (_terminalSettings != null) { _terminalSettings = null; } } //free unmanaged objects //AdditionalCleanup(); this.disposed = true; } }
public TerminalViewModel(ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService, ApplicationSettings applicationSettings, ShellProfile shellProfile, IApplicationView applicationView, IClipboardService clipboardService, string terminalState = null) { MessengerInstance.Register <ApplicationSettingsChangedMessage>(this, OnApplicationSettingsChanged); MessengerInstance.Register <CurrentThemeChangedMessage>(this, OnCurrentThemeChanged); MessengerInstance.Register <TerminalOptionsChangedMessage>(this, OnTerminalOptionsChanged); MessengerInstance.Register <KeyBindingsChangedMessage>(this, OnKeyBindingsChanged); SettingsService = settingsService; _terminalOptions = SettingsService.GetTerminalOptions(); TrayProcessCommunicationService = trayProcessCommunicationService; DialogService = dialogService; _keyboardCommandService = keyboardCommandService; ApplicationSettings = applicationSettings; ApplicationView = applicationView; ClipboardService = clipboardService; ShellProfile = shellProfile; TerminalTheme = shellProfile.TerminalThemeId == Guid.Empty ? SettingsService.GetCurrentTheme() : SettingsService.GetTheme(shellProfile.TerminalThemeId); TabThemes = new ObservableCollection <TabThemeViewModel>(SettingsService.GetTabThemes().Select(theme => new TabThemeViewModel(theme, this))); CloseCommand = new AsyncCommand(TryCloseAsync, CanExecuteCommand); CloseLeftTabsCommand = new RelayCommand(CloseLeftTabs, CanExecuteCommand); CloseRightTabsCommand = new RelayCommand(CloseRightTabs, CanExecuteCommand); CloseOtherTabsCommand = new RelayCommand(CloseOtherTabs, CanExecuteCommand); FindNextCommand = new RelayCommand(FindNext, CanExecuteCommand); FindPreviousCommand = new RelayCommand(FindPrevious, CanExecuteCommand); CloseSearchPanelCommand = new RelayCommand(CloseSearchPanel, CanExecuteCommand); EditTitleCommand = new AsyncCommand(EditTitleAsync, CanExecuteCommand); DuplicateTabCommand = new RelayCommand(DuplicateTab, CanExecuteCommand); CopyCommand = new AsyncCommand(Copy, () => HasSelection); PasteCommand = new AsyncCommand(Paste); CopyLinkCommand = new AsyncCommand(() => CopyTextAsync(HoveredUri), () => !string.IsNullOrWhiteSpace(HoveredUri)); ShowSearchPanelCommand = new RelayCommand(() => ShowSearchPanel = true, () => !ShowSearchPanel); if (!string.IsNullOrEmpty(terminalState)) { Restore(terminalState); } else { var defaultTabTheme = TabThemes.FirstOrDefault(t => t.Theme.Id == ShellProfile.TabThemeId); defaultTabTheme.IsSelected = true; } Terminal = new Terminal(TrayProcessCommunicationService, _terminalId); Terminal.KeyboardCommandReceived += Terminal_KeyboardCommandReceived; Terminal.OutputReceived += Terminal_OutputReceived; Terminal.SizeChanged += Terminal_SizeChanged; Terminal.TitleChanged += Terminal_TitleChanged; Terminal.Exited += Terminal_Exited; Terminal.Closed += Terminal_Closed; ContextMenu = BuidContextMenu(); TabContextMenu = BuildTabContextMenu(); }
/// <summary>Builds the prompt string for this player.</summary> /// <returns>The formatted prompt for this player.</returns> public override OutputBuilder BuildPrompt(TerminalOptions terminalOptions) { return(new OutputBuilder(5).Append("WRM> ")); /* TODO: Allow for player-customized prompts... * // Returns a string with the %tokens% replaced with appropriate values * string prompt = Prompt; * * if (prompt != null && prompt.Contains("%")) // Quick check, we can skip parsing if we have no chance of tokens * { * // TODO: This routine needs optimization * // Find all PlayerPromptables and replace their tokens with values if they exist in the supplied prompt string * foreach (MethodInfo m in GetType().GetMethods()) * { * object[] promptAttrs = m.GetCustomAttributes(typeof(PlayerPromptableAttribute), false); * if (promptAttrs.Length > 0 && * prompt.IndexOf(((PlayerPromptableAttribute)promptAttrs[0]).Token) >= 0) * { * var promptAttr = (PlayerPromptableAttribute)promptAttrs[0]; * prompt = prompt.Replace(promptAttr.Token, (string)m.Invoke(this, new object[] { })); * } * } * } * * return prompt; */ }
public override OutputBuilder Render(TerminalOptions terminalOptions, HelpTopic helpTopic) { var output = new OutputBuilder(); // TODO: What was this !element doing? Does it still work? Test with zMUD or something and re-read MXP specs? if (terminalOptions.UseMXP) { output.AppendLine($"{AnsiSequences.MxpSecureLine}<!element see '<send href=\"help &cref;\">' att='cref' open>"); } output.AppendSeparator(color: "yellow", design: '='); output.AppendLine($"HELP TOPIC: {helpTopic.Aliases.First()}"); output.AppendSeparator(color: "yellow"); if (terminalOptions.UseMXP) { var lines = helpTopic.Contents.Split(new string[] { AnsiSequences.NewLine }, StringSplitOptions.None); foreach (var line in lines) { output.AppendLine($"{AnsiSequences.MxpOpenLine}{line}<%n%>"); } } else { output.AppendLine($"{helpTopic.Contents}"); } output.AppendSeparator(color: "yellow", design: '='); return(output); }
public override OutputBuilder Render(TerminalOptions terminalOptions, Thing viewer, Thing viewedThing) { var senses = viewer.FindBehavior <SensesBehavior>(); return(new OutputBuilder().AppendLine(senses.CanPerceiveThing(viewedThing) ? $"You examine <%cyan%><%b%>{viewedThing.Name}<%n%>:<%nl%>{viewedThing.Description}" : "You cannot perceive that thing.")); }
public string CreateTerminal(TerminalOptions options) { var terminal = new Terminal(options); terminal.ConnectionClosed += OnTerminalConnectionClosed; _terminals.Add(terminal.Id, terminal); return(terminal.WebSocketUrl); }
public TelnetSSHLogin() { _instance = this; _isRunning = true; _Console = new ConsoleMain(); _terminalOptions = new TerminalOptions(""); _terminalSettings = new TerminalSettings(); _timeout = _Console.ProtocolOptions.SocketConnectTimeout / 1000; }
public TerminalSession(ITerminalConnection connection, ITerminalSettings terminalSettings, TerminalOptions terminalOptions) { _terminalSettings = terminalSettings; _terminalOptions = terminalOptions; //VT100Žw’è‚Å‚àxtermƒV[ƒPƒ“ƒX‚ð‘—‚Á‚Ä‚‚éƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚ªŒã‚ð‚½‚½‚È‚¢‚Ì‚Å _terminal = AbstractTerminal.Create(new TerminalInitializeInfo(this, connection.Destination)); _output = new TerminalTransmission(_terminal, _terminalSettings, connection); _keepAlive = new KeepAlive(this); }
public override OutputBuilder Render(TerminalOptions terminalOptions, Thing player) { // WheelMUD Core does not have any knowledge of game-specific stats and so on (if even applicable), so // by default, the prompt always prints quite simply. Games should generally export their own prompt // renderer with a higher priority, and do something smarter here. The Core PlayerBehavior has a Prompt // property which can be used to store player-customized prompt templates, and your Prompt renderer can // (for example) transform their custom prompt template into their final prompt output. return(new OutputBuilder(2).Append("> ")); }
private async Task <TerminalSize> CreateXtermView(TerminalOptions options, TerminalColors theme, IEnumerable <KeyBinding> keyBindings) { var serializedOptions = JsonConvert.SerializeObject(options); var serializedTheme = JsonConvert.SerializeObject(theme); var serializedKeyBindings = JsonConvert.SerializeObject(keyBindings); var size = await ExecuteScriptAsync($"createTerminal('{serializedOptions}', '{serializedTheme}', '{serializedKeyBindings}')").ConfigureAwait(true); return(JsonConvert.DeserializeObject <TerminalSize>(size)); }
public Task ChangeOptionsAsync(TerminalOptions options) { if (_terminalClosed) { return(Task.CompletedTask); } return(_optionsChanged.InvokeAsync(options)); }
private Task <TerminalSize> CreateXtermViewAsync(TerminalOptions options, TerminalColors theme, IEnumerable <KeyBinding> keyBindings) { var serializedOptions = JsonConvert.SerializeObject(options); var serializedTheme = JsonConvert.SerializeObject(theme); var serializedKeyBindings = JsonConvert.SerializeObject(keyBindings); return(ExecuteScriptAsync( $"createTerminal('{serializedOptions}', '{serializedTheme}', '{serializedKeyBindings}')") .ContinueWith(t => JsonConvert.DeserializeObject <TerminalSize>(t.Result))); }
public override OutputBuilder Render(TerminalOptions terminalOptions, IEnumerable <Command> commands, string categoryName) { var output = new OutputBuilder().AppendLine($"<%yellow%>{categoryName} commands<%n%>:"); foreach (var command in commands) { // NEED AN ALTERNATE NON-MXP VERSION, AND NEED SECURE LINE API TO BE THE ONLY WAY TO SEND SECURE LINES - Name to make very clear it cannot contain user-generated content? "AppendTrustedSecureLine" with extra comments? output.AppendLine($"{AnsiSequences.MxpSecureLine}<send \"help {command.Name}\">{command.Name.PadRight(15)}</send> {command.Description}"); } return(output); }
/// <inheritdoc/> public ServerResponseType HandleMessage(Backend backend, ServerMessageType message, string session, BinaryReader datareader, BinaryWriter datawriter) { PseudoTerminal _master = null; PseudoTerminal _slave = null; var options = new TerminalOptions(); options.LFlag = PtyConstants.ICANON; options.C_cc[PtyConstants.VERASE] = (byte)'\b'; options.C_cc[PtyConstants.VEOL] = (byte)'\r'; options.C_cc[PtyConstants.VEOL2] = (byte)'\n'; PseudoTerminal.CreatePair(out _master, out _slave, options); int slaveRemoteId = _remoteStreams.Create(_slave, session); var stdout = new StreamWriter(new BroadcastingStream(backend, session)); stdout.AutoFlush = true; var stdin = new StreamReader(_master); string commandname = datareader.ReadString(); int argCount = datareader.ReadInt32(); string[] argv = new string[argCount]; for (int i = 0; i < argCount; i++) { argv[i] = datareader.ReadString(); } var trmmgr = backend.GetBackendComponent <TerminalManager>(); Task.Run(() => { try { trmmgr.RunCommand(backend, commandname, argv, session, stdin, stdout); } catch (TerminationRequestException) { Logger.Log("Terminated command."); } finally { stdout.Write((char)0x02); } }); datawriter.Write(slaveRemoteId); return(ServerResponseType.REQ_SUCCESS); }
public override OutputBuilder Render(TerminalOptions terminalOptions, Thing player) { // Pretty basic placeholder. Most game systems will probably want to define their own stats systems // and races and attributes and so on, and provide a more traditional "score" breakdown of the // current character state as pertains to the actual game system. var livingBehavior = player.FindBehavior <LivingBehavior>(); var output = new OutputBuilder(); output.AppendLine($"{player.Name}. You are {livingBehavior.Consciousness}"); return(output); }
public string Post() { var cols = int.Parse(this.Request.GetQueryNameValuePairs().SingleOrDefault(q => q.Key == "cols").Value); var rows = int.Parse(this.Request.GetQueryNameValuePairs().SingleOrDefault(q => q.Key == "rows").Value); var options = new TerminalOptions { Columns = cols, Rows = rows }; return(_terminalsManager.CreateTerminal(options)); }
public TerminalViewModel(ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService, ApplicationSettings applicationSettings, ShellProfile shellProfile, IApplicationView applicationView, IDispatcherTimer dispatcherTimer, IClipboardService clipboardService, string terminalState = null) { SettingsService = settingsService; SettingsService.CurrentThemeChanged += OnCurrentThemeChanged; SettingsService.TerminalOptionsChanged += OnTerminalOptionsChanged; SettingsService.ApplicationSettingsChanged += OnApplicationSettingsChanged; SettingsService.KeyBindingsChanged += OnKeyBindingsChanged; _terminalOptions = SettingsService.GetTerminalOptions(); TrayProcessCommunicationService = trayProcessCommunicationService; DialogService = dialogService; _keyboardCommandService = keyboardCommandService; ApplicationSettings = applicationSettings; ApplicationView = applicationView; ClipboardService = clipboardService; ShellProfile = shellProfile; TerminalTheme = shellProfile.TerminalThemeId == Guid.Empty ? SettingsService.GetCurrentTheme() : SettingsService.GetTheme(shellProfile.TerminalThemeId); TabThemes = new ObservableCollection <TabTheme>(SettingsService.GetTabThemes()); TabTheme = TabThemes.FirstOrDefault(t => t.Id == ShellProfile.TabThemeId); CloseCommand = new RelayCommand(async() => await TryClose().ConfigureAwait(false)); CloseLeftTabsCommand = new RelayCommand(CloseLeftTabs); CloseRightTabsCommand = new RelayCommand(CloseRightTabs); CloseOtherTabsCommand = new RelayCommand(CloseOtherTabs); FindNextCommand = new RelayCommand(FindNext); FindPreviousCommand = new RelayCommand(FindPrevious); CloseSearchPanelCommand = new RelayCommand(CloseSearchPanel); SelectTabThemeCommand = new RelayCommand <string>(SelectTabTheme); EditTitleCommand = new AsyncCommand(EditTitle); DuplicateTabCommand = new RelayCommand(DuplicateTab); if (!String.IsNullOrEmpty(terminalState)) { Restore(terminalState); } Terminal = new Terminal(TrayProcessCommunicationService, _terminalId); Terminal.KeyboardCommandReceived += Terminal_KeyboardCommandReceived; Terminal.OutputReceived += Terminal_OutputReceived; Terminal.SizeChanged += Terminal_SizeChanged; Terminal.TitleChanged += Terminal_TitleChanged; Terminal.Exited += Terminal_Exited; Terminal.Closed += Terminal_Closed; Overlay = new OverlayViewModel(dispatcherTimer); }
public TerminalViewModel(ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService, ApplicationSettings applicationSettings, ShellProfile shellProfile, IApplicationView applicationView, IClipboardService clipboardService, string terminalState = null) { MessengerInstance.Register <ApplicationSettingsChangedMessage>(this, OnApplicationSettingsChanged); MessengerInstance.Register <CurrentThemeChangedMessage>(this, OnCurrentThemeChanged); MessengerInstance.Register <TerminalOptionsChangedMessage>(this, OnTerminalOptionsChanged); SettingsService = settingsService; _terminalOptions = SettingsService.GetTerminalOptions(); TrayProcessCommunicationService = trayProcessCommunicationService; DialogService = dialogService; _keyboardCommandService = keyboardCommandService; ApplicationSettings = applicationSettings; ApplicationView = applicationView; ClipboardService = clipboardService; ShellProfile = shellProfile; TerminalTheme = shellProfile.TerminalThemeId == Guid.Empty ? SettingsService.GetCurrentTheme() : SettingsService.GetTheme(shellProfile.TerminalThemeId); TabThemes = new ObservableCollection <TabTheme>(SettingsService.GetTabThemes()); TabTheme = TabThemes.FirstOrDefault(t => t.Id == ShellProfile.TabThemeId); CloseCommand = new AsyncCommand(CloseTab, CanExecuteCommand); CloseLeftTabsCommand = new RelayCommand(CloseLeftTabs, CanExecuteCommand); CloseRightTabsCommand = new RelayCommand(CloseRightTabs, CanExecuteCommand); CloseOtherTabsCommand = new RelayCommand(CloseOtherTabs, CanExecuteCommand); FindNextCommand = new RelayCommand(FindNext, CanExecuteCommand); FindPreviousCommand = new RelayCommand(FindPrevious, CanExecuteCommand); CloseSearchPanelCommand = new RelayCommand(CloseSearchPanel, CanExecuteCommand); SelectTabThemeCommand = new RelayCommand <string>(SelectTabTheme, CanExecuteCommand); EditTitleCommand = new AsyncCommand(EditTitle, CanExecuteCommand); DuplicateTabCommand = new RelayCommand(DuplicateTab, CanExecuteCommand); if (!String.IsNullOrEmpty(terminalState)) { Restore(terminalState); } Terminal = new Terminal(TrayProcessCommunicationService, _terminalId); Terminal.KeyboardCommandReceived += Terminal_KeyboardCommandReceived; Terminal.OutputReceived += Terminal_OutputReceived; Terminal.SizeChanged += Terminal_SizeChanged; Terminal.TitleChanged += Terminal_TitleChanged; Terminal.Exited += Terminal_Exited; Terminal.Closed += Terminal_Closed; }
public override OutputBuilder Render(TerminalOptions terminalOptions, Thing viewer, Thing room) { var senses = viewer.FindBehavior <SensesBehavior>(); var output = new OutputBuilder(); if (senses.CanPerceiveThing(room)) { output.AppendLine($"<%red%><%b%>{room.Name}<%n%>"); output.AppendLine(room.Description); } else { output.AppendLine("You cannot perceive much of note about the room."); } // TODO: Perhaps group things in the room by things you can pick up, things that are alive, etc? // var entities = senses.PerceiveEntities(); and also render players nicely; "(AFK)" etc? // var items = senses.PerceiveItems(); and also track tick or build sense-specific strings (like hearing only while blind...) // Handle exits differently from other Thing types // TODO: Also render closable exits like doors nicely; "(closed)"? // TODO: For viewer that is PlayerBehavior with negotiated MXP connection, render with embedded command links for click-to-execute support? var outputExits = from exit in senses.PerceiveExits() select $"<%magenta%>{exit}<%n%>"; // TODO: Color the parts of the thing names which are also legit keywords for the thing... // TODO: For viewer that is PlayerBehavior with negotiated MXP connection, render with embedded command links for click-to-execute support? var outputThings = from thing in room.Children where senses.CanPerceiveThing(thing) && thing != viewer && !thing.HasBehavior <ExitBehavior>() select $" {thing.FullName}<%n%>"; if (outputExits.Any() || outputThings.Any()) { output.AppendLine("<%yellow%>Here you notice:<%n%>"); if (outputExits.Any()) { output.AppendLine($" Routes: {string.Join(", ", outputExits)}"); } foreach (var outputThing in outputThings) { output.AppendLine(outputThing); } } else { output.AppendLine("<%yellow%>You notice nothing else inside the room.<%n%>"); } return(output); }
public override OutputBuilder Render(TerminalOptions terminalOptions, Thing activePlayer) { string mudNameLine = " "; // TODO: Dynamic centering instead, if we want centering! string plural = string.Empty; var output = new OutputBuilder(); string plural1 = "is"; // TODO: Should query for players who can be known about by this player (e.g. omit wiz-inviz players, if any?) if (PlayerManager.Instance.Players.Count > 1) { plural = "s"; plural1 = "are"; } // TODO: A game-system specific renderer could be used to includ race/class info and so on, if desired. // TODO: Dividing lines could be influenced by activePlayer connection Terminal.Width. mudNameLine += GameConfiguration.Name; output.AppendLine(); output.AppendSeparator(); output.AppendLine(mudNameLine); output.AppendSeparator(); output.AppendLine(); output.AppendLine($"The following player{plural} {plural1} currently online:"); foreach (PlayerBehavior player in PlayerManager.Instance.Players) { var playerName = player.Parent.Name; var playerState = GetPlayerState(player); if (terminalOptions.UseMXP) { // TODO: "tell {0}" is not a good menu command; possibly friend add/remove, invite to group, hailing, and so on. // TODO: #107: Fix handling of MXP Secure Lines... (This wasn't being built in a safe way, and does not render correctly now.) output.AppendLine($"<%mxpsecureline%><send \"finger {playerName}|tell {playerName}\" \"|finger|tell\">{playerName}</send> - {player.Parent.FullName} {playerState}"); } else { output.AppendLine($"{playerName} - {player.Parent.FullName} {playerState}"); } } output.AppendLine(); output.AppendSeparator(); output.AppendLine($"Counted {PlayerManager.Instance.Players.Count} player{plural} online."); output.AppendLine(); output.AppendSeparator(); return(output); }
public override OutputBuilder Render(TerminalOptions terminalOptions, Command command) { var output = new OutputBuilder().AppendLine($"<%yellow%>{command.Name.ToUpper()}<%n%>:"); if (!string.IsNullOrWhiteSpace(command.Description)) { output.AppendLine(command.Description); } // TODO: Add command.Usage? Rename Example to "Examples" as string[]? if (!string.IsNullOrWhiteSpace(command.Example)) { output.AppendLine("<%yellow%>USAGE<%n%>:"); output.AppendLine(command.Example); } // TODO: Add command.SeeAlso as string[]? return(output); }
public override OutputBuilder Render(TerminalOptions terminalOptions, Thing player) { var stats = player.Stats; var statEffects = player.Behaviors.OfType <StatEffect>(); var output = new OutputBuilder(); var health = stats["HP"]; var healthMod = statEffects.Where(e => e.Stat.Abbreviation == "HP").Sum(e => e.ValueMod); var mana = stats["MANA"]; var damage = stats["DAMAGE"]; var init = stats["INIT"]; var attack = stats["ATK"]; var defense = stats["DEF"]; var armorPenalty = stats["ARMORPENALTY"]; var wieldMax = stats["WEAPONWIELDMAX"]; var hunt = stats["HUNT"]; var familiar = stats["FAMILIAR"]; var fate = stats["FATE"]; var healthLine = $"{health.Name,-13} {health.Value,5:####0}/{health.MaxValue,-5:####0} ({healthMod})".PadRight(31); var manaLine = $"{mana.Name,-12} {mana.Value,5:####0}/{mana.MaxValue,-5:####0}".PadRight(31); var damageLine = $"{damage.Name,-13} {damage.Value,5:##0}/{damage.MaxValue,-5:##0}".PadRight(31); var initLine = $"{init.Name,-16} {init.Value,-6}".PadRight(31); var attackLine = $"{attack.Name,-15} {attack.Value,3:##0}/{attack.MaxValue,-3:##0}".PadRight(31); var defenseLine = $"{defense.Name,-14} {defense.Value,3:##0}/{defense.MaxValue,-3:##0}".PadRight(31); var armorPenaltyLine = $"{armorPenalty.Name,-16} {armorPenalty.Value,2}".PadRight(31); var wieldMaxLine = $"{wieldMax.Name,-16} {wieldMax.Value,1}/{wieldMax.MaxValue,-1}".PadRight(31); var huntLine = $"{hunt.Name,-16} {hunt.Value,2}({hunt.MaxValue,2})".PadRight(31); var familiarLine = $"{familiar.Name,-16} {familiar.Value,1:0}{familiar.MaxValue,-1:(0)}".PadRight(31); var fateLine = $"{fate.Name,-16} {fate.Value,2}({fate.MaxValue,2})".PadRight(31); var nameAndTitle = string.IsNullOrWhiteSpace(player.Title) ? player.Name : $"{player.Name}, {player.Title}"; var pipe = "<%green%>|<%n%>"; output.AppendLine("<%green%>+-------------------------------------------------------------------+"); output.AppendLine($"{pipe} {nameAndTitle,-19} Level {"?",-6} Reputation {"?",-6} Kudos {"?",-6} {pipe}"); output.AppendLine("<%green%>+----------------+----------------+----------------+----------------+"); output.AppendLine($"{pipe} {healthLine} {pipe} {manaLine} {pipe}"); output.AppendLine($"{pipe} {damageLine} {pipe} {initLine} {pipe}"); output.AppendLine($"{pipe} {attackLine} {pipe} {defenseLine} {pipe}"); output.AppendLine($"{pipe} {armorPenaltyLine} {pipe} {wieldMaxLine} {pipe}"); output.AppendLine($"{pipe} {huntLine} {pipe} {familiarLine} {pipe}"); output.AppendLine($"{pipe} {fateLine} {pipe} {string.Empty.PadRight(31)} {pipe}"); output.AppendLine("<%green%>+---------------------------------^---------------------------------+<%n%>"); return(output); }
public override OutputBuilder Render(TerminalOptions terminalOptions, Thing player) { var senses = player.FindBehavior <SensesBehavior>(); var output = new OutputBuilder(); var invThings = player.Children.Where(presentThing => senses.CanPerceiveThing(presentThing)).ToArray(); output.AppendLine(invThings.Length > 0 ? "<%yellow%>Searching your inventory, you find:<%n%>" : "<%yellow%>You found no inventory.<%n%>"); foreach (var presentThing in invThings) { output.AppendLine($" <%magenta%>{presentThing.FullName}<%n%>"); } return(output); }
public void DoesNotCrashWhenReflowingToTinyWidth() { var options = new TerminalOptions() { Cols = 10, Rows = 10 }; options.Scrollback = 1; var terminal = new Terminal(null, options); terminal.Feed("1234567890\r\n"); terminal.Feed("ABCDEFGH\r\n"); terminal.Feed("abcdefghijklmnopqrstxxx\r\n"); terminal.Feed("\r\n"); // if we resize to a small column width, content is pushed back up and out the top // of the buffer. Ensure that this does not crash terminal.Resize(3, 10); }
public override OutputBuilder Render(TerminalOptions terminalOptions, IEnumerable <Command> commands) { // Build a list of categories for the commands available to this player. var output = new OutputBuilder().AppendLine("Please specify a command category:"); foreach (CommandCategory category in Enum.GetValues(typeof(CommandCategory))) { if (category == CommandCategory.None) { continue; } var matchingcommands = commands.Where(command => command.Category.HasFlag(category)); if (matchingcommands.Any()) { // THIS DOESN'T WORK ANYMORE - NEED TO USE SECURE LINE API AND HAVE SEPARATE OUTPUT FOR NON-MXP CLIENTS! output.AppendLine($"<%mxpsecureline%><send \"commands {category}\">{category}</send> ({matchingcommands.Count()})"); } } return(output); }