diff --git a/exec/load/attr_conv.js b/exec/load/attr_conv.js index e3630db5fb74f45894bb6756ea0253d245c15e85..2c47200e36ab7f7885fdd71cd35af66a782375a4 100644 --- a/exec/load/attr_conv.js +++ b/exec/load/attr_conv.js @@ -1066,16 +1066,22 @@ function ANSIMultiConvertToSyncCodes(pText) // // Parameters: // pText: The text to be converted +// pConvertANSI: Optional boolean - Whether or not to convert ANSI. Defaults to true. // // Return value: The text with various other system attribute codes converted // to Synchronet attribute codes, or not, depending on the toggle // options in Extra Attribute Codes in SCFG -function convertAttrsToSyncPerSysCfg(pText) +function convertAttrsToSyncPerSysCfg(pText, pConvertANSI) { - // Convert any ANSI codes to Synchronet attribute codes. - // Then convert other BBS attribute codes to Synchronet attribute - // codes according to the current system configuration. - var convertedText = ANSIAttrsToSyncAttrs(pText); + var convertedText = pText; + var convertANSI = (typeof(pConvertANSI) === "boolean" ? pConvertANSI : true); + if (convertANSI) + { + // Convert any ANSI codes to Synchronet attribute codes. + // Then convert other BBS attribute codes to Synchronet attribute + // codes according to the current system configuration. + convertedText = ANSIAttrsToSyncAttrs(convertedText); + } if ((system.settings & SYS_RENEGADE) == SYS_RENEGADE) convertedText = renegadeAttrsToSyncAttrs(convertedText); if ((system.settings & SYS_WWIV) == SYS_WWIV) diff --git a/xtrn/DDMsgReader/DDMsgReader.js b/xtrn/DDMsgReader/DDMsgReader.js index fd4f3d1460856d592dc4a5a1209860a0123a2169..6ee9c39aba0fa3b0b9cd8319c9fabb507b0812d6 100644 --- a/xtrn/DDMsgReader/DDMsgReader.js +++ b/xtrn/DDMsgReader/DDMsgReader.js @@ -128,6 +128,11 @@ * reader (either from read mode or list mode), it now properly * says there are no messages and exits, rather than showing * a list of bogus messages. + * 2022-03-14 Eric Oulashin Version 1.47 + * Updated to make DDMsgReader can be called directly as a + * loadable module by Synchronet (work started on March 8). + * Also, refactored to use attr_conv.js and removed the + * attribute conversion functions from this script. */ @@ -193,12 +198,6 @@ added in the future. */ -// TODOs: -// - Search in text: Support current sub-board, group, or all searching -// - Make use of these lines from text.dat? -// "\1n\1c(\1h%u \1n\1csub-boards)\1h\1w complete.\r\n" 117 MessageScanComplete -// "\1r\1iaborted.\1n\r\n" 118 MessageScanAborted - // - For pageUp & pageDown, enable alternate keys: // - When reading a message - scrollTextLines() // - When listing messages @@ -218,6 +217,7 @@ if (requireFnExists) require("dd_lightbar_menu.js", "DDLightbarMenu"); require("mouse_getkey.js", "mouse_getkey"); require("html2asc.js", 'html2asc'); + require("attr_conv.js", "convertAttrsToSyncPerSysCfg"); } else { @@ -228,6 +228,7 @@ else load("dd_lightbar_menu.js"); load("mouse_getkey.js"); load("html2asc.js"); + load("attr_conv.js"); } load('822header.js'); @@ -248,8 +249,8 @@ if (system.version_num < 31500) } // Reader version information -var READER_VERSION = "1.46"; -var READER_DATE = "2022-03-07"; +var READER_VERSION = "1.47"; +var READER_DATE = "2022-03-14"; // Keyboard key codes for displaying on the screen var UP_ARROW = ascii(24); @@ -534,6 +535,8 @@ if (file_exists(backslash(system.exec_dir) + "load/smbdefs.js") && file_exists(b // Parse the command-line arguments var gCmdLineArgVals = parseArgs(argv); +if (gCmdLineArgVals.exitNow) + exit(0); var gAllPersonalEmailOptSpecified = (gCmdLineArgVals.hasOwnProperty("allpersonalemail") && gCmdLineArgVals.allpersonalemail); // Check to see if the command-line argument for reading personal email is enabled var gListPersonalEmailCmdLineOpt = ((gCmdLineArgVals.hasOwnProperty("personalemail") && gCmdLineArgVals.personalemail) || @@ -648,10 +651,19 @@ if (gDoDDMR) { case SEARCH_NONE: restoreOriginalSubCode = false; + if (msgReader.subBoardCode != "mail") + { + console.print("n"); + console.crlf(); + console.print("Loading " + subBoardGrpAndName(msgReader.subBoardCode) + "...."); + console.line_counter = 0; // To prevent a pause before the message list comes up + } msgReader.ReadOrListSubBoard(); break; case SEARCH_KEYWORD: - msgReader.SearchMsgScan("keyword_search"); + var txtToSearch = (gCmdLineArgVals.hasOwnProperty("searchtext") ? gCmdLineArgVals.searchtext : null); + var subBoardCode = (gCmdLineArgVals.hasOwnProperty("subboard") ? gCmdLineArgVals.subboard : null); + msgReader.SearchMsgScan("keyword_search", txtToSearch, subBoardCode); break; case SEARCH_FROM_NAME: msgReader.SearchMessages("from_name_search"); @@ -1763,8 +1775,10 @@ function DigDistMsgReader_RefreshHdrInSavedArrays(pMsgIndex, pAttrib, pSubBoardC // pScanScopeChar: Optional string with a character specifying "A" to scan all sub-boards, // "G" for the current message group, or "S" for the user's current sub-board. // If this is not specified, the current sub-board will be used. -function DigDistMsgReader_SearchMessages(pSearchModeStr, pSubBoardCode, pScanScopeChar) +// pTxtToSearch: Optional - Text to search for (if specified, this won't prompt the user for search text) +function DigDistMsgReader_SearchMessages(pSearchModeStr, pSubBoardCode, pScanScopeChar, pTxtToSearch) { + var searchTextProvided = (typeof(pTxtToSearch) === "string" && pTxtToSearch != ""); // Convert the search mode string to an integer representing the search // mode. If we get back -1, that means the search mode string was invalid. // If that's the case, simply list messages. Otherwise, do the search. @@ -1797,13 +1811,22 @@ function DigDistMsgReader_SearchMessages(pSearchModeStr, pSubBoardCode, pScanSco switch (this.searchType) { case SEARCH_KEYWORD: - console.print("\1n" + replaceAtCodesInStr(this.text.searchTextPromptText)); + if (!searchTextProvided) + console.print("\1n" + replaceAtCodesInStr(this.text.searchTextPromptText)); + else + console.print("\1n\1gSearching for: \1c" + pTxtToSearch + "\1n\r\n"); break; case SEARCH_FROM_NAME: - console.print("\1n" + replaceAtCodesInStr(this.text.fromNamePromptText)); + if (!searchTextProvided) + console.print("\1n" + replaceAtCodesInStr(this.text.fromNamePromptText)); + else + console.print("\1n\1gSearching for: \1c" + pTxtToSearch + "\1n\r\n"); break; case SEARCH_TO_NAME_CUR_MSG_AREA: - console.print("\1n" +replaceAtCodesInStr(this.text.toNamePromptText)); + if (!searchTextProvided) + console.print("\1n" +replaceAtCodesInStr(this.text.toNamePromptText)); + else + console.print("\1n\1gSearching for: \1c" + pTxtToSearch + "\1n\r\n"); break; case SEARCH_TO_USER_CUR_MSG_AREA: // Note: No prompt needed for this - Will search for the user's name/handle @@ -1816,7 +1839,12 @@ function DigDistMsgReader_SearchMessages(pSearchModeStr, pSubBoardCode, pScanSco var promptUserForText = this.SearchTypeRequiresSearchText(); // Get the search text from the user if (promptUserForText) - this.searchString = console.getstr(512, K_UPPER); + { + if (searchTextProvided) + this.searchString = pTxtToSearch; + else + this.searchString = console.getstr(512, K_UPPER); + } // If the user was prompted for search text but no search text was entered, // then show an abort message and don't do anything. Otherwise, go ahead // and list/read messages. @@ -1893,17 +1921,31 @@ function DigDistMsgReader_SearchMessages(pSearchModeStr, pSubBoardCode, pScanSco // "from_name_search": Search messages by from name // "to_name_search": Search messages by to name // "to_user_search": Search messages by to name, to the logged-in user -function DigDistMsgReader_SearchMsgScan(pSearchModeStr) +// pTxtToSearch: Optional - Text to search for (if specified, this won't prompt the user for search text) +// pSubCode: Optional - An internal code of a sub-board if scanning just one sub-board +function DigDistMsgReader_SearchMsgScan(pSearchModeStr, pTxtToSearch, pSubCode) { if (typeof(pSearchModeStr) !== "string" || pSearchModeStr.length == 0) return; - // Prompt the user for sub-board, group, or all, then call SearchMessages - // to do the search - console.mnemonics(bbs.text(SubGroupOrAll)); - var scanScopeChar = console.getkeys("SGAC").toString(); + // If the given sub-board code is valid, then use that and scan only in that + // sub-board. Otherwise, prompt the user for sub-board, group, or all, then + // call SearchMessages to do the search. + var scanScopeChar = ""; + var previousSubBoardCode = null; + if (typeof(pSubCode) === "string" && subBoardCodeIsValid(pSubCode)) + { + var previousSubBoardCode = this.subBoardCode; + this.subBoardCode = pSubCode; + scanScopeChar = "S"; + } + else + { + console.mnemonics(bbs.text(SubGroupOrAll)); + scanScopeChar = console.getkeys("SGAC").toString(); + } if (scanScopeChar.length > 0) - this.SearchMessages(pSearchModeStr, null, scanScopeChar); + this.SearchMessages(pSearchModeStr, null, scanScopeChar, pTxtToSearch); else { console.crlf(); @@ -1911,6 +1953,9 @@ function DigDistMsgReader_SearchMsgScan(pSearchModeStr) console.crlf(); console.pause(); } + // Restore this.subBoardCode if necessary + if (typeof(previousSubBoardCode) === "string") + this.subBoardCode = previousSubBoardCode; } // This function clears the search data from the object. @@ -12169,16 +12214,7 @@ function DigDistMsgReader_GetMsgInfoForEnhancedReader(pMsgHdr, pWordWrap, pDeter msgTextAltered = msgTextAltered.replace(/\t/g, this.tabReplacementText); // Convert other BBS color codes to Synchronet attribute codes if the settings // to do so are enabled. - if ((system.settings & SYS_RENEGADE) == SYS_RENEGADE) - msgTextAltered = renegadeAttrsToSyncAttrs(msgTextAltered); - if ((system.settings & SYS_WWIV) == SYS_WWIV) - msgTextAltered = WWIVAttrsToSyncAttrs(msgTextAltered); - if ((system.settings & SYS_CELERITY) == SYS_CELERITY) - msgTextAltered = celerityAttrsToSyncAttrs(msgTextAltered); - if ((system.settings & SYS_PCBOARD) == SYS_PCBOARD) - msgTextAltered = PCBoardAttrsToSyncAttrs(msgTextAltered); - if ((system.settings & SYS_WILDCAT) == SYS_WILDCAT) - msgTextAltered = wildcatAttrsToSyncAttrs(msgTextAltered); + msgTextAltered = convertAttrsToSyncPerSysCfg(msgTextAltered, false); // If the message contains ANSI codes, then if frame.js is available and // the user's terminal support ANSI, set up a Frame object for reading the // message with a scrollable interface. @@ -16361,1217 +16397,6 @@ function msgIsFromUser(pMsgHdr) return isFromUser; } -///////////////////////////////////////////////////////////////////////// -// Functions for converting other BBS color codes to Synchronet attribute codes - -// Converts WWIV attribute codes to Synchronet attribute codes. -// -// Parameters: -// pText: A string containing the text to convert -// -// Return value: The text with the color codes converted -function WWIVAttrsToSyncAttrs(pText) -{ - // First, see if the text has any WWIV-style attribute codes at - // all. We'll be performing a bunch of search & replace commands, - // so we don't want to do all that work for nothing.. :) - if (/\x03[0-9]/.test(pText)) - { - var text = pText.replace(/\x030/g, "\1n"); // Normal - text = text.replace(/\x031/g, "\1n\1c\1h"); // Bright cyan - text = text.replace(/\x032/g, "\1n\1y\1h"); // Bright yellow - text = text.replace(/\x033/g, "\1n\1m"); // Magenta - text = text.replace(/\x034/g, "\1n\1h\1w\1" + "4"); // Bright white on blue - text = text.replace(/\x035/g, "\1n\1g"); // Green - text = text.replace(/\x036/g, "\1h\1r\1i"); // Bright red, blinking - text = text.replace(/\x037/g, "\1n\1h\1b"); // Bright blue - text = text.replace(/\x038/g, "\1n\1b"); // Blue - text = text.replace(/\x039/g, "\1n\1c"); // Cyan - return text; - } - else - return pText; // No WWIV-style color attribute found, so just return the text. -} - -// Converts PCBoard attribute codes to Synchronet attribute codes. -// -// Parameters: -// pText: A string containing the text to convert -// -// Return value: The text with the color codes converted -function PCBoardAttrsToSyncAttrs(pText) -{ - // First, see if the text has any PCBoard-style attribute codes at - // all. We'll be performing a bunch of search & replace commands, - // so we don't want to do all that work for nothing.. :) - if (/@[xX][0-9A-Fa-f]{2}/.test(pText)) - { - // Black background - var text = pText.replace(/@[xX]00/g, "\1n\1k\1" + "0"); // Black on black - text = text.replace(/@[xX]01/g, "\1n\1b\1" + "0"); // Blue on black - text = text.replace(/@[xX]02/g, "\1n\1g\1" + "0"); // Green on black - text = text.replace(/@[xX]03/g, "\1n\1c\1" + "0"); // Cyan on black - text = text.replace(/@[xX]04/g, "\1n\1r\1" + "0"); // Red on black - text = text.replace(/@[xX]05/g, "\1n\1m\1" + "0"); // Magenta on black - text = text.replace(/@[xX]06/g, "\1n\1y\1" + "0"); // Yellow/brown on black - text = text.replace(/@[xX]07/g, "\1n\1w\1" + "0"); // White on black - text = text.replace(/@[xX]08/g, "\1n\1w\1" + "0"); // White on black - text = text.replace(/@[xX]09/g, "\1n\1w\1" + "0"); // White on black - text = text.replace(/@[xX]08/g, "\1h\1k\1" + "0"); // Bright black on black - text = text.replace(/@[xX]09/g, "\1h\1b\1" + "0"); // Bright blue on black - text = text.replace(/@[xX]0[Aa]/g, "\1h\1g\1" + "0"); // Bright green on black - text = text.replace(/@[xX]0[Bb]/g, "\1h\1c\1" + "0"); // Bright cyan on black - text = text.replace(/@[xX]0[Cc]/g, "\1h\1r\1" + "0"); // Bright red on black - text = text.replace(/@[xX]0[Dd]/g, "\1h\1m\1" + "0"); // Bright magenta on black - text = text.replace(/@[xX]0[Ee]/g, "\1h\1y\1" + "0"); // Bright yellow on black - text = text.replace(/@[xX]0[Ff]/g, "\1h\1w\1" + "0"); // Bright white on black - // Blinking foreground - - // Blue background - text = text.replace(/@[xX]10/g, "\1n\1k\1" + "4"); // Black on blue - text = text.replace(/@[xX]11/g, "\1n\1b\1" + "4"); // Blue on blue - text = text.replace(/@[xX]12/g, "\1n\1g\1" + "4"); // Green on blue - text = text.replace(/@[xX]13/g, "\1n\1c\1" + "4"); // Cyan on blue - text = text.replace(/@[xX]14/g, "\1n\1r\1" + "4"); // Red on blue - text = text.replace(/@[xX]15/g, "\1n\1m\1" + "4"); // Magenta on blue - text = text.replace(/@[xX]16/g, "\1n\1y\1" + "4"); // Yellow/brown on blue - text = text.replace(/@[xX]17/g, "\1n\1w\1" + "4"); // White on blue - text = text.replace(/@[xX]18/g, "\1h\1k\1" + "4"); // Bright black on blue - text = text.replace(/@[xX]19/g, "\1h\1b\1" + "4"); // Bright blue on blue - text = text.replace(/@[xX]1[Aa]/g, "\1h\1g\1" + "4"); // Bright green on blue - text = text.replace(/@[xX]1[Bb]/g, "\1h\1c\1" + "4"); // Bright cyan on blue - text = text.replace(/@[xX]1[Cc]/g, "\1h\1r\1" + "4"); // Bright red on blue - text = text.replace(/@[xX]1[Dd]/g, "\1h\1m\1" + "4"); // Bright magenta on blue - text = text.replace(/@[xX]1[Ee]/g, "\1h\1y\1" + "4"); // Bright yellow on blue - text = text.replace(/@[xX]1[Ff]/g, "\1h\1w\1" + "4"); // Bright white on blue - - // Green background - text = text.replace(/@[xX]20/g, "\1n\1k\1" + "2"); // Black on green - text = text.replace(/@[xX]21/g, "\1n\1b\1" + "2"); // Blue on green - text = text.replace(/@[xX]22/g, "\1n\1g\1" + "2"); // Green on green - text = text.replace(/@[xX]23/g, "\1n\1c\1" + "2"); // Cyan on green - text = text.replace(/@[xX]24/g, "\1n\1r\1" + "2"); // Red on green - text = text.replace(/@[xX]25/g, "\1n\1m\1" + "2"); // Magenta on green - text = text.replace(/@[xX]26/g, "\1n\1y\1" + "2"); // Yellow/brown on green - text = text.replace(/@[xX]27/g, "\1n\1w\1" + "2"); // White on green - text = text.replace(/@[xX]28/g, "\1h\1k\1" + "2"); // Bright black on green - text = text.replace(/@[xX]29/g, "\1h\1b\1" + "2"); // Bright blue on green - text = text.replace(/@[xX]2[Aa]/g, "\1h\1g\1" + "2"); // Bright green on green - text = text.replace(/@[xX]2[Bb]/g, "\1h\1c\1" + "2"); // Bright cyan on green - text = text.replace(/@[xX]2[Cc]/g, "\1h\1r\1" + "2"); // Bright red on green - text = text.replace(/@[xX]2[Dd]/g, "\1h\1m\1" + "2"); // Bright magenta on green - text = text.replace(/@[xX]2[Ee]/g, "\1h\1y\1" + "2"); // Bright yellow on green - text = text.replace(/@[xX]2[Ff]/g, "\1h\1w\1" + "2"); // Bright white on green - - // Cyan background - text = text.replace(/@[xX]30/g, "\1n\1k\1" + "6"); // Black on cyan - text = text.replace(/@[xX]31/g, "\1n\1b\1" + "6"); // Blue on cyan - text = text.replace(/@[xX]32/g, "\1n\1g\1" + "6"); // Green on cyan - text = text.replace(/@[xX]33/g, "\1n\1c\1" + "6"); // Cyan on cyan - text = text.replace(/@[xX]34/g, "\1n\1r\1" + "6"); // Red on cyan - text = text.replace(/@[xX]35/g, "\1n\1m\1" + "6"); // Magenta on cyan - text = text.replace(/@[xX]36/g, "\1n\1y\1" + "6"); // Yellow/brown on cyan - text = text.replace(/@[xX]37/g, "\1n\1w\1" + "6"); // White on cyan - text = text.replace(/@[xX]38/g, "\1h\1k\1" + "6"); // Bright black on cyan - text = text.replace(/@[xX]39/g, "\1h\1b\1" + "6"); // Bright blue on cyan - text = text.replace(/@[xX]3[Aa]/g, "\1h\1g\1" + "6"); // Bright green on cyan - text = text.replace(/@[xX]3[Bb]/g, "\1h\1c\1" + "6"); // Bright cyan on cyan - text = text.replace(/@[xX]3[Cc]/g, "\1h\1r\1" + "6"); // Bright red on cyan - text = text.replace(/@[xX]3[Dd]/g, "\1h\1m\1" + "6"); // Bright magenta on cyan - text = text.replace(/@[xX]3[Ee]/g, "\1h\1y\1" + "6"); // Bright yellow on cyan - text = text.replace(/@[xX]3[Ff]/g, "\1h\1w\1" + "6"); // Bright white on cyan - - // Red background - text = text.replace(/@[xX]40/g, "\1n\1k\1" + "1"); // Black on red - text = text.replace(/@[xX]41/g, "\1n\1b\1" + "1"); // Blue on red - text = text.replace(/@[xX]42/g, "\1n\1g\1" + "1"); // Green on red - text = text.replace(/@[xX]43/g, "\1n\1c\1" + "1"); // Cyan on red - text = text.replace(/@[xX]44/g, "\1n\1r\1" + "1"); // Red on red - text = text.replace(/@[xX]45/g, "\1n\1m\1" + "1"); // Magenta on red - text = text.replace(/@[xX]46/g, "\1n\1y\1" + "1"); // Yellow/brown on red - text = text.replace(/@[xX]47/g, "\1n\1w\1" + "1"); // White on red - text = text.replace(/@[xX]48/g, "\1h\1k\1" + "1"); // Bright black on red - text = text.replace(/@[xX]49/g, "\1h\1b\1" + "1"); // Bright blue on red - text = text.replace(/@[xX]4[Aa]/g, "\1h\1g\1" + "1"); // Bright green on red - text = text.replace(/@[xX]4[Bb]/g, "\1h\1c\1" + "1"); // Bright cyan on red - text = text.replace(/@[xX]4[Cc]/g, "\1h\1r\1" + "1"); // Bright red on red - text = text.replace(/@[xX]4[Dd]/g, "\1h\1m\1" + "1"); // Bright magenta on red - text = text.replace(/@[xX]4[Ee]/g, "\1h\1y\1" + "1"); // Bright yellow on red - text = text.replace(/@[xX]4[Ff]/g, "\1h\1w\1" + "1"); // Bright white on red - - // Magenta background - text = text.replace(/@[xX]50/g, "\1n\1k\1" + "5"); // Black on magenta - text = text.replace(/@[xX]51/g, "\1n\1b\1" + "5"); // Blue on magenta - text = text.replace(/@[xX]52/g, "\1n\1g\1" + "5"); // Green on magenta - text = text.replace(/@[xX]53/g, "\1n\1c\1" + "5"); // Cyan on magenta - text = text.replace(/@[xX]54/g, "\1n\1r\1" + "5"); // Red on magenta - text = text.replace(/@[xX]55/g, "\1n\1m\1" + "5"); // Magenta on magenta - text = text.replace(/@[xX]56/g, "\1n\1y\1" + "5"); // Yellow/brown on magenta - text = text.replace(/@[xX]57/g, "\1n\1w\1" + "5"); // White on magenta - text = text.replace(/@[xX]58/g, "\1h\1k\1" + "5"); // Bright black on magenta - text = text.replace(/@[xX]59/g, "\1h\1b\1" + "5"); // Bright blue on magenta - text = text.replace(/@[xX]5[Aa]/g, "\1h\1g\1" + "5"); // Bright green on magenta - text = text.replace(/@[xX]5[Bb]/g, "\1h\1c\1" + "5"); // Bright cyan on magenta - text = text.replace(/@[xX]5[Cc]/g, "\1h\1r\1" + "5"); // Bright red on magenta - text = text.replace(/@[xX]5[Dd]/g, "\1h\1m\1" + "5"); // Bright magenta on magenta - text = text.replace(/@[xX]5[Ee]/g, "\1h\1y\1" + "5"); // Bright yellow on magenta - text = text.replace(/@[xX]5[Ff]/g, "\1h\1w\1" + "5"); // Bright white on magenta - - // Brown background - text = text.replace(/@[xX]60/g, "\1n\1k\1" + "3"); // Black on brown - text = text.replace(/@[xX]61/g, "\1n\1b\1" + "3"); // Blue on brown - text = text.replace(/@[xX]62/g, "\1n\1g\1" + "3"); // Green on brown - text = text.replace(/@[xX]63/g, "\1n\1c\1" + "3"); // Cyan on brown - text = text.replace(/@[xX]64/g, "\1n\1r\1" + "3"); // Red on brown - text = text.replace(/@[xX]65/g, "\1n\1m\1" + "3"); // Magenta on brown - text = text.replace(/@[xX]66/g, "\1n\1y\1" + "3"); // Yellow/brown on brown - text = text.replace(/@[xX]67/g, "\1n\1w\1" + "3"); // White on brown - text = text.replace(/@[xX]68/g, "\1h\1k\1" + "3"); // Bright black on brown - text = text.replace(/@[xX]69/g, "\1h\1b\1" + "3"); // Bright blue on brown - text = text.replace(/@[xX]6[Aa]/g, "\1h\1g\1" + "3"); // Bright breen on brown - text = text.replace(/@[xX]6[Bb]/g, "\1h\1c\1" + "3"); // Bright cyan on brown - text = text.replace(/@[xX]6[Cc]/g, "\1h\1r\1" + "3"); // Bright red on brown - text = text.replace(/@[xX]6[Dd]/g, "\1h\1m\1" + "3"); // Bright magenta on brown - text = text.replace(/@[xX]6[Ee]/g, "\1h\1y\1" + "3"); // Bright yellow on brown - text = text.replace(/@[xX]6[Ff]/g, "\1h\1w\1" + "3"); // Bright white on brown - - // White background - text = text.replace(/@[xX]70/g, "\1n\1k\1" + "7"); // Black on white - text = text.replace(/@[xX]71/g, "\1n\1b\1" + "7"); // Blue on white - text = text.replace(/@[xX]72/g, "\1n\1g\1" + "7"); // Green on white - text = text.replace(/@[xX]73/g, "\1n\1c\1" + "7"); // Cyan on white - text = text.replace(/@[xX]74/g, "\1n\1r\1" + "7"); // Red on white - text = text.replace(/@[xX]75/g, "\1n\1m\1" + "7"); // Magenta on white - text = text.replace(/@[xX]76/g, "\1n\1y\1" + "7"); // Yellow/brown on white - text = text.replace(/@[xX]77/g, "\1n\1w\1" + "7"); // White on white - text = text.replace(/@[xX]78/g, "\1h\1k\1" + "7"); // Bright black on white - text = text.replace(/@[xX]79/g, "\1h\1b\1" + "7"); // Bright blue on white - text = text.replace(/@[xX]7[Aa]/g, "\1h\1g\1" + "7"); // Bright green on white - text = text.replace(/@[xX]7[Bb]/g, "\1h\1c\1" + "7"); // Bright cyan on white - text = text.replace(/@[xX]7[Cc]/g, "\1h\1r\1" + "7"); // Bright red on white - text = text.replace(/@[xX]7[Dd]/g, "\1h\1m\1" + "7"); // Bright magenta on white - text = text.replace(/@[xX]7[Ee]/g, "\1h\1y\1" + "7"); // Bright yellow on white - text = text.replace(/@[xX]7[Ff]/g, "\1h\1w\1" + "7"); // Bright white on white - - // Black background, blinking foreground - text = text.replace(/@[xX]80/g, "\1n\1k\1" + "0\1i"); // Blinking black on black - text = text.replace(/@[xX]81/g, "\1n\1b\1" + "0\1i"); // Blinking blue on black - text = text.replace(/@[xX]82/g, "\1n\1g\1" + "0\1i"); // Blinking green on black - text = text.replace(/@[xX]83/g, "\1n\1c\1" + "0\1i"); // Blinking cyan on black - text = text.replace(/@[xX]84/g, "\1n\1r\1" + "0\1i"); // Blinking red on black - text = text.replace(/@[xX]85/g, "\1n\1m\1" + "0\1i"); // Blinking magenta on black - text = text.replace(/@[xX]86/g, "\1n\1y\1" + "0\1i"); // Blinking yellow/brown on black - text = text.replace(/@[xX]87/g, "\1n\1w\1" + "0\1i"); // Blinking white on black - text = text.replace(/@[xX]88/g, "\1h\1k\1" + "0\1i"); // Blinking bright black on black - text = text.replace(/@[xX]89/g, "\1h\1b\1" + "0\1i"); // Blinking bright blue on black - text = text.replace(/@[xX]8[Aa]/g, "\1h\1g\1" + "0\1i"); // Blinking bright green on black - text = text.replace(/@[xX]8[Bb]/g, "\1h\1c\1" + "0\1i"); // Blinking bright cyan on black - text = text.replace(/@[xX]8[Cc]/g, "\1h\1r\1" + "0\1i"); // Blinking bright red on black - text = text.replace(/@[xX]8[Dd]/g, "\1h\1m\1" + "0\1i"); // Blinking bright magenta on black - text = text.replace(/@[xX]8[Ee]/g, "\1h\1y\1" + "0\1i"); // Blinking bright yellow on black - text = text.replace(/@[xX]8[Ff]/g, "\1h\1w\1" + "0\1i"); // Blinking bright white on black - - // Blue background, blinking foreground - text = text.replace(/@[xX]90/g, "\1n\1k\1" + "4\1i"); // Blinking black on blue - text = text.replace(/@[xX]91/g, "\1n\1b\1" + "4\1i"); // Blinking blue on blue - text = text.replace(/@[xX]92/g, "\1n\1g\1" + "4\1i"); // Blinking green on blue - text = text.replace(/@[xX]93/g, "\1n\1c\1" + "4\1i"); // Blinking cyan on blue - text = text.replace(/@[xX]94/g, "\1n\1r\1" + "4\1i"); // Blinking red on blue - text = text.replace(/@[xX]95/g, "\1n\1m\1" + "4\1i"); // Blinking magenta on blue - text = text.replace(/@[xX]96/g, "\1n\1y\1" + "4\1i"); // Blinking yellow/brown on blue - text = text.replace(/@[xX]97/g, "\1n\1w\1" + "4\1i"); // Blinking white on blue - text = text.replace(/@[xX]98/g, "\1h\1k\1" + "4\1i"); // Blinking bright black on blue - text = text.replace(/@[xX]99/g, "\1h\1b\1" + "4\1i"); // Blinking bright blue on blue - text = text.replace(/@[xX]9[Aa]/g, "\1h\1g\1" + "4\1i"); // Blinking bright green on blue - text = text.replace(/@[xX]9[Bb]/g, "\1h\1c\1" + "4\1i"); // Blinking bright cyan on blue - text = text.replace(/@[xX]9[Cc]/g, "\1h\1r\1" + "4\1i"); // Blinking bright red on blue - text = text.replace(/@[xX]9[Dd]/g, "\1h\1m\1" + "4\1i"); // Blinking bright magenta on blue - text = text.replace(/@[xX]9[Ee]/g, "\1h\1y\1" + "4\1i"); // Blinking bright yellow on blue - text = text.replace(/@[xX]9[Ff]/g, "\1h\1w\1" + "4\1i"); // Blinking bright white on blue - - // Green background, blinking foreground - text = text.replace(/@[xX][Aa]0/g, "\1n\1k\1" + "2\1i"); // Blinking black on green - text = text.replace(/@[xX][Aa]1/g, "\1n\1b\1" + "2\1i"); // Blinking blue on green - text = text.replace(/@[xX][Aa]2/g, "\1n\1g\1" + "2\1i"); // Blinking green on green - text = text.replace(/@[xX][Aa]3/g, "\1n\1c\1" + "2\1i"); // Blinking cyan on green - text = text.replace(/@[xX][Aa]4/g, "\1n\1r\1" + "2\1i"); // Blinking red on green - text = text.replace(/@[xX][Aa]5/g, "\1n\1m\1" + "2\1i"); // Blinking magenta on green - text = text.replace(/@[xX][Aa]6/g, "\1n\1y\1" + "2\1i"); // Blinking yellow/brown on green - text = text.replace(/@[xX][Aa]7/g, "\1n\1w\1" + "2\1i"); // Blinking white on green - text = text.replace(/@[xX][Aa]8/g, "\1h\1k\1" + "2\1i"); // Blinking bright black on green - text = text.replace(/@[xX][Aa]9/g, "\1h\1b\1" + "2\1i"); // Blinking bright blue on green - text = text.replace(/@[xX][Aa][Aa]/g, "\1h\1g\1" + "2\1i"); // Blinking bright green on green - text = text.replace(/@[xX][Aa][Bb]/g, "\1h\1c\1" + "2\1i"); // Blinking bright cyan on green - text = text.replace(/@[xX][Aa][Cc]/g, "\1h\1r\1" + "2\1i"); // Blinking bright red on green - text = text.replace(/@[xX][Aa][Dd]/g, "\1h\1m\1" + "2\1i"); // Blinking bright magenta on green - text = text.replace(/@[xX][Aa][Ee]/g, "\1h\1y\1" + "2\1i"); // Blinking bright yellow on green - text = text.replace(/@[xX][Aa][Ff]/g, "\1h\1w\1" + "2\1i"); // Blinking bright white on green - - // Cyan background, blinking foreground - text = text.replace(/@[xX][Bb]0/g, "\1n\1k\1" + "6\1i"); // Blinking black on cyan - text = text.replace(/@[xX][Bb]1/g, "\1n\1b\1" + "6\1i"); // Blinking blue on cyan - text = text.replace(/@[xX][Bb]2/g, "\1n\1g\1" + "6\1i"); // Blinking green on cyan - text = text.replace(/@[xX][Bb]3/g, "\1n\1c\1" + "6\1i"); // Blinking cyan on cyan - text = text.replace(/@[xX][Bb]4/g, "\1n\1r\1" + "6\1i"); // Blinking red on cyan - text = text.replace(/@[xX][Bb]5/g, "\1n\1m\1" + "6\1i"); // Blinking magenta on cyan - text = text.replace(/@[xX][Bb]6/g, "\1n\1y\1" + "6\1i"); // Blinking yellow/brown on cyan - text = text.replace(/@[xX][Bb]7/g, "\1n\1w\1" + "6\1i"); // Blinking white on cyan - text = text.replace(/@[xX][Bb]8/g, "\1h\1k\1" + "6\1i"); // Blinking bright black on cyan - text = text.replace(/@[xX][Bb]9/g, "\1h\1b\1" + "6\1i"); // Blinking bright blue on cyan - text = text.replace(/@[xX][Bb][Aa]/g, "\1h\1g\1" + "6\1i"); // Blinking bright green on cyan - text = text.replace(/@[xX][Bb][Bb]/g, "\1h\1c\1" + "6\1i"); // Blinking bright cyan on cyan - text = text.replace(/@[xX][Bb][Cc]/g, "\1h\1r\1" + "6\1i"); // Blinking bright red on cyan - text = text.replace(/@[xX][Bb][Dd]/g, "\1h\1m\1" + "6\1i"); // Blinking bright magenta on cyan - text = text.replace(/@[xX][Bb][Ee]/g, "\1h\1y\1" + "6\1i"); // Blinking bright yellow on cyan - text = text.replace(/@[xX][Bb][Ff]/g, "\1h\1w\1" + "6\1i"); // Blinking bright white on cyan - - // Red background, blinking foreground - text = text.replace(/@[xX][Cc]0/g, "\1n\1k\1" + "1\1i"); // Blinking black on red - text = text.replace(/@[xX][Cc]1/g, "\1n\1b\1" + "1\1i"); // Blinking blue on red - text = text.replace(/@[xX][Cc]2/g, "\1n\1g\1" + "1\1i"); // Blinking green on red - text = text.replace(/@[xX][Cc]3/g, "\1n\1c\1" + "1\1i"); // Blinking cyan on red - text = text.replace(/@[xX][Cc]4/g, "\1n\1r\1" + "1\1i"); // Blinking red on red - text = text.replace(/@[xX][Cc]5/g, "\1n\1m\1" + "1\1i"); // Blinking magenta on red - text = text.replace(/@[xX][Cc]6/g, "\1n\1y\1" + "1\1i"); // Blinking yellow/brown on red - text = text.replace(/@[xX][Cc]7/g, "\1n\1w\1" + "1\1i"); // Blinking white on red - text = text.replace(/@[xX][Cc]8/g, "\1h\1k\1" + "1\1i"); // Blinking bright black on red - text = text.replace(/@[xX][Cc]9/g, "\1h\1b\1" + "1\1i"); // Blinking bright blue on red - text = text.replace(/@[xX][Cc][Aa]/g, "\1h\1g\1" + "1\1i"); // Blinking bright green on red - text = text.replace(/@[xX][Cc][Bb]/g, "\1h\1c\1" + "1\1i"); // Blinking bright cyan on red - text = text.replace(/@[xX][Cc][Cc]/g, "\1h\1r\1" + "1\1i"); // Blinking bright red on red - text = text.replace(/@[xX][Cc][Dd]/g, "\1h\1m\1" + "1\1i"); // Blinking bright magenta on red - text = text.replace(/@[xX][Cc][Ee]/g, "\1h\1y\1" + "1\1i"); // Blinking bright yellow on red - text = text.replace(/@[xX][Cc][Ff]/g, "\1h\1w\1" + "1\1i"); // Blinking bright white on red - - // Magenta background, blinking foreground - text = text.replace(/@[xX][Dd]0/g, "\1n\1k\1" + "5\1i"); // Blinking black on magenta - text = text.replace(/@[xX][Dd]1/g, "\1n\1b\1" + "5\1i"); // Blinking blue on magenta - text = text.replace(/@[xX][Dd]2/g, "\1n\1g\1" + "5\1i"); // Blinking green on magenta - text = text.replace(/@[xX][Dd]3/g, "\1n\1c\1" + "5\1i"); // Blinking cyan on magenta - text = text.replace(/@[xX][Dd]4/g, "\1n\1r\1" + "5\1i"); // Blinking red on magenta - text = text.replace(/@[xX][Dd]5/g, "\1n\1m\1" + "5\1i"); // Blinking magenta on magenta - text = text.replace(/@[xX][Dd]6/g, "\1n\1y\1" + "5\1i"); // Blinking yellow/brown on magenta - text = text.replace(/@[xX][Dd]7/g, "\1n\1w\1" + "5\1i"); // Blinking white on magenta - text = text.replace(/@[xX][Dd]8/g, "\1h\1k\1" + "5\1i"); // Blinking bright black on magenta - text = text.replace(/@[xX][Dd]9/g, "\1h\1b\1" + "5\1i"); // Blinking bright blue on magenta - text = text.replace(/@[xX][Dd][Aa]/g, "\1h\1g\1" + "5\1i"); // Blinking bright green on magenta - text = text.replace(/@[xX][Dd][Bb]/g, "\1h\1c\1" + "5\1i"); // Blinking bright cyan on magenta - text = text.replace(/@[xX][Dd][Cc]/g, "\1h\1r\1" + "5\1i"); // Blinking bright red on magenta - text = text.replace(/@[xX][Dd][Dd]/g, "\1h\1m\1" + "5\1i"); // Blinking bright magenta on magenta - text = text.replace(/@[xX][Dd][Ee]/g, "\1h\1y\1" + "5\1i"); // Blinking bright yellow on magenta - text = text.replace(/@[xX][Dd][Ff]/g, "\1h\1w\1" + "5\1i"); // Blinking bright white on magenta - - // Brown background, blinking foreground - text = text.replace(/@[xX][Ee]0/g, "\1n\1k\1" + "3\1i"); // Blinking black on brown - text = text.replace(/@[xX][Ee]1/g, "\1n\1b\1" + "3\1i"); // Blinking blue on brown - text = text.replace(/@[xX][Ee]2/g, "\1n\1g\1" + "3\1i"); // Blinking green on brown - text = text.replace(/@[xX][Ee]3/g, "\1n\1c\1" + "3\1i"); // Blinking cyan on brown - text = text.replace(/@[xX][Ee]4/g, "\1n\1r\1" + "3\1i"); // Blinking red on brown - text = text.replace(/@[xX][Ee]5/g, "\1n\1m\1" + "3\1i"); // Blinking magenta on brown - text = text.replace(/@[xX][Ee]6/g, "\1n\1y\1" + "3\1i"); // Blinking yellow/brown on brown - text = text.replace(/@[xX][Ee]7/g, "\1n\1w\1" + "3\1i"); // Blinking white on brown - text = text.replace(/@[xX][Ee]8/g, "\1h\1k\1" + "3\1i"); // Blinking bright black on brown - text = text.replace(/@[xX][Ee]9/g, "\1h\1b\1" + "3\1i"); // Blinking bright blue on brown - text = text.replace(/@[xX][Ee][Aa]/g, "\1h\1g\1" + "3\1i"); // Blinking bright green on brown - text = text.replace(/@[xX][Ee][Bb]/g, "\1h\1c\1" + "3\1i"); // Blinking bright cyan on brown - text = text.replace(/@[xX][Ee][Cc]/g, "\1h\1r\1" + "3\1i"); // Blinking bright red on brown - text = text.replace(/@[xX][Ee][Dd]/g, "\1h\1m\1" + "3\1i"); // Blinking bright magenta on brown - text = text.replace(/@[xX][Ee][Ee]/g, "\1h\1y\1" + "3\1i"); // Blinking bright yellow on brown - text = text.replace(/@[xX][Ee][Ff]/g, "\1h\1w\1" + "3\1i"); // Blinking bright white on brown - - // White background, blinking foreground - text = text.replace(/@[xX][Ff]0/g, "\1n\1k\1" + "7\1i"); // Blinking black on white - text = text.replace(/@[xX][Ff]1/g, "\1n\1b\1" + "7\1i"); // Blinking blue on white - text = text.replace(/@[xX][Ff]2/g, "\1n\1g\1" + "7\1i"); // Blinking green on white - text = text.replace(/@[xX][Ff]3/g, "\1n\1c\1" + "7\1i"); // Blinking cyan on white - text = text.replace(/@[xX][Ff]4/g, "\1n\1r\1" + "7\1i"); // Blinking red on white - text = text.replace(/@[xX][Ff]5/g, "\1n\1m\1" + "7\1i"); // Blinking magenta on white - text = text.replace(/@[xX][Ff]6/g, "\1n\1y\1" + "7\1i"); // Blinking yellow/brown on white - text = text.replace(/@[xX][Ff]7/g, "\1n\1w\1" + "7\1i"); // Blinking white on white - text = text.replace(/@[xX][Ff]8/g, "\1h\1k\1" + "7\1i"); // Blinking bright black on white - text = text.replace(/@[xX][Ff]9/g, "\1h\1b\1" + "7\1i"); // Blinking bright blue on white - text = text.replace(/@[xX][Ff][Aa]/g, "\1h\1g\1" + "7\1i"); // Blinking bright green on white - text = text.replace(/@[xX][Ff][Bb]/g, "\1h\1c\1" + "7\1i"); // Blinking bright cyan on white - text = text.replace(/@[xX][Ff][Cc]/g, "\1h\1r\1" + "7\1i"); // Blinking bright red on white - text = text.replace(/@[xX][Ff][Dd]/g, "\1h\1m\1" + "7\1i"); // Blinking bright magenta on white - text = text.replace(/@[xX][Ff][Ee]/g, "\1h\1y\1" + "7\1i"); // Blinking bright yellow on white - text = text.replace(/@[xX][Ff][Ff]/g, "\1h\1w\1" + "7\1i"); // Blinking bright white on white - - return text; - } - else - return pText; // No PCBoard-style attribute codes found, so just return the text. -} - -// Converts Wildcat attribute codes to Synchronet attribute codes. -// -// Parameters: -// pText: A string containing the text to convert -// -// Return value: The text with the color codes converted -function wildcatAttrsToSyncAttrs(pText) -{ - // First, see if the text has any Wildcat-style attribute codes at - // all. We'll be performing a bunch of search & replace commands, - // so we don't want to do all that work for nothing.. :) - if (/@[0-9A-Fa-f]{2}@/.test(pText)) - { - // Black background - var text = pText.replace(/@00@/g, "\1n\1k\1" + "0"); // Black on black - text = text.replace(/@01@/g, "\1n\1b\1" + "0"); // Blue on black - text = text.replace(/@02@/g, "\1n\1g\1" + "0"); // Green on black - text = text.replace(/@03@/g, "\1n\1c\1" + "0"); // Cyan on black - text = text.replace(/@04@/g, "\1n\1r\1" + "0"); // Red on black - text = text.replace(/@05@/g, "\1n\1m\1" + "0"); // Magenta on black - text = text.replace(/@06@/g, "\1n\1y\1" + "0"); // Yellow/brown on black - text = text.replace(/@07@/g, "\1n\1w\1" + "0"); // White on black - text = text.replace(/@08@/g, "\1n\1w\1" + "0"); // White on black - text = text.replace(/@09@/g, "\1n\1w\1" + "0"); // White on black - text = text.replace(/@08@/g, "\1h\1k\1" + "0"); // Bright black on black - text = text.replace(/@09@/g, "\1h\1b\1" + "0"); // Bright blue on black - text = text.replace(/@0[Aa]@/g, "\1h\1g\1" + "0"); // Bright green on black - text = text.replace(/@0[Bb]@/g, "\1h\1c\1" + "0"); // Bright cyan on black - text = text.replace(/@0[Cc]@/g, "\1h\1r\1" + "0"); // Bright red on black - text = text.replace(/@0[Dd]@/g, "\1h\1m\1" + "0"); // Bright magenta on black - text = text.replace(/@0[Ee]@/g, "\1h\1y\1" + "0"); // Bright yellow on black - text = text.replace(/@0[Ff]@/g, "\1h\1w\1" + "0"); // Bright white on black - // Blinking foreground - - // Blue background - text = text.replace(/@10@/g, "\1n\1k\1" + "4"); // Black on blue - text = text.replace(/@11@/g, "\1n\1b\1" + "4"); // Blue on blue - text = text.replace(/@12@/g, "\1n\1g\1" + "4"); // Green on blue - text = text.replace(/@13@/g, "\1n\1c\1" + "4"); // Cyan on blue - text = text.replace(/@14@/g, "\1n\1r\1" + "4"); // Red on blue - text = text.replace(/@15@/g, "\1n\1m\1" + "4"); // Magenta on blue - text = text.replace(/@16@/g, "\1n\1y\1" + "4"); // Yellow/brown on blue - text = text.replace(/@17@/g, "\1n\1w\1" + "4"); // White on blue - text = text.replace(/@18@/g, "\1h\1k\1" + "4"); // Bright black on blue - text = text.replace(/@19@/g, "\1h\1b\1" + "4"); // Bright blue on blue - text = text.replace(/@1[Aa]@/g, "\1h\1g\1" + "4"); // Bright green on blue - text = text.replace(/@1[Bb]@/g, "\1h\1c\1" + "4"); // Bright cyan on blue - text = text.replace(/@1[Cc]@/g, "\1h\1r\1" + "4"); // Bright red on blue - text = text.replace(/@1[Dd]@/g, "\1h\1m\1" + "4"); // Bright magenta on blue - text = text.replace(/@1[Ee]@/g, "\1h\1y\1" + "4"); // Bright yellow on blue - text = text.replace(/@1[Ff]@/g, "\1h\1w\1" + "4"); // Bright white on blue - - // Green background - text = text.replace(/@20@/g, "\1n\1k\1" + "2"); // Black on green - text = text.replace(/@21@/g, "\1n\1b\1" + "2"); // Blue on green - text = text.replace(/@22@/g, "\1n\1g\1" + "2"); // Green on green - text = text.replace(/@23@/g, "\1n\1c\1" + "2"); // Cyan on green - text = text.replace(/@24@/g, "\1n\1r\1" + "2"); // Red on green - text = text.replace(/@25@/g, "\1n\1m\1" + "2"); // Magenta on green - text = text.replace(/@26@/g, "\1n\1y\1" + "2"); // Yellow/brown on green - text = text.replace(/@27@/g, "\1n\1w\1" + "2"); // White on green - text = text.replace(/@28@/g, "\1h\1k\1" + "2"); // Bright black on green - text = text.replace(/@29@/g, "\1h\1b\1" + "2"); // Bright blue on green - text = text.replace(/@2[Aa]@/g, "\1h\1g\1" + "2"); // Bright green on green - text = text.replace(/@2[Bb]@/g, "\1h\1c\1" + "2"); // Bright cyan on green - text = text.replace(/@2[Cc]@/g, "\1h\1r\1" + "2"); // Bright red on green - text = text.replace(/@2[Dd]@/g, "\1h\1m\1" + "2"); // Bright magenta on green - text = text.replace(/@2[Ee]@/g, "\1h\1y\1" + "2"); // Bright yellow on green - text = text.replace(/@2[Ff]@/g, "\1h\1w\1" + "2"); // Bright white on green - - // Cyan background - text = text.replace(/@30@/g, "\1n\1k\1" + "6"); // Black on cyan - text = text.replace(/@31@/g, "\1n\1b\1" + "6"); // Blue on cyan - text = text.replace(/@32@/g, "\1n\1g\1" + "6"); // Green on cyan - text = text.replace(/@33@/g, "\1n\1c\1" + "6"); // Cyan on cyan - text = text.replace(/@34@/g, "\1n\1r\1" + "6"); // Red on cyan - text = text.replace(/@35@/g, "\1n\1m\1" + "6"); // Magenta on cyan - text = text.replace(/@36@/g, "\1n\1y\1" + "6"); // Yellow/brown on cyan - text = text.replace(/@37@/g, "\1n\1w\1" + "6"); // White on cyan - text = text.replace(/@38@/g, "\1h\1k\1" + "6"); // Bright black on cyan - text = text.replace(/@39@/g, "\1h\1b\1" + "6"); // Bright blue on cyan - text = text.replace(/@3[Aa]@/g, "\1h\1g\1" + "6"); // Bright green on cyan - text = text.replace(/@3[Bb]@/g, "\1h\1c\1" + "6"); // Bright cyan on cyan - text = text.replace(/@3[Cc]@/g, "\1h\1r\1" + "6"); // Bright red on cyan - text = text.replace(/@3[Dd]@/g, "\1h\1m\1" + "6"); // Bright magenta on cyan - text = text.replace(/@3[Ee]@/g, "\1h\1y\1" + "6"); // Bright yellow on cyan - text = text.replace(/@3[Ff]@/g, "\1h\1w\1" + "6"); // Bright white on cyan - - // Red background - text = text.replace(/@40@/g, "\1n\1k\1" + "1"); // Black on red - text = text.replace(/@41@/g, "\1n\1b\1" + "1"); // Blue on red - text = text.replace(/@42@/g, "\1n\1g\1" + "1"); // Green on red - text = text.replace(/@43@/g, "\1n\1c\1" + "1"); // Cyan on red - text = text.replace(/@44@/g, "\1n\1r\1" + "1"); // Red on red - text = text.replace(/@45@/g, "\1n\1m\1" + "1"); // Magenta on red - text = text.replace(/@46@/g, "\1n\1y\1" + "1"); // Yellow/brown on red - text = text.replace(/@47@/g, "\1n\1w\1" + "1"); // White on red - text = text.replace(/@48@/g, "\1h\1k\1" + "1"); // Bright black on red - text = text.replace(/@49@/g, "\1h\1b\1" + "1"); // Bright blue on red - text = text.replace(/@4[Aa]@/g, "\1h\1g\1" + "1"); // Bright green on red - text = text.replace(/@4[Bb]@/g, "\1h\1c\1" + "1"); // Bright cyan on red - text = text.replace(/@4[Cc]@/g, "\1h\1r\1" + "1"); // Bright red on red - text = text.replace(/@4[Dd]@/g, "\1h\1m\1" + "1"); // Bright magenta on red - text = text.replace(/@4[Ee]@/g, "\1h\1y\1" + "1"); // Bright yellow on red - text = text.replace(/@4[Ff]@/g, "\1h\1w\1" + "1"); // Bright white on red - - // Magenta background - text = text.replace(/@50@/g, "\1n\1k\1" + "5"); // Black on magenta - text = text.replace(/@51@/g, "\1n\1b\1" + "5"); // Blue on magenta - text = text.replace(/@52@/g, "\1n\1g\1" + "5"); // Green on magenta - text = text.replace(/@53@/g, "\1n\1c\1" + "5"); // Cyan on magenta - text = text.replace(/@54@/g, "\1n\1r\1" + "5"); // Red on magenta - text = text.replace(/@55@/g, "\1n\1m\1" + "5"); // Magenta on magenta - text = text.replace(/@56@/g, "\1n\1y\1" + "5"); // Yellow/brown on magenta - text = text.replace(/@57@/g, "\1n\1w\1" + "5"); // White on magenta - text = text.replace(/@58@/g, "\1h\1k\1" + "5"); // Bright black on magenta - text = text.replace(/@59@/g, "\1h\1b\1" + "5"); // Bright blue on magenta - text = text.replace(/@5[Aa]@/g, "\1h\1g\1" + "5"); // Bright green on magenta - text = text.replace(/@5[Bb]@/g, "\1h\1c\1" + "5"); // Bright cyan on magenta - text = text.replace(/@5[Cc]@/g, "\1h\1r\1" + "5"); // Bright red on magenta - text = text.replace(/@5[Dd]@/g, "\1h\1m\1" + "5"); // Bright magenta on magenta - text = text.replace(/@5[Ee]@/g, "\1h\1y\1" + "5"); // Bright yellow on magenta - text = text.replace(/@5[Ff]@/g, "\1h\1w\1" + "5"); // Bright white on magenta - - // Brown background - text = text.replace(/@60@/g, "\1n\1k\1" + "3"); // Black on brown - text = text.replace(/@61@/g, "\1n\1b\1" + "3"); // Blue on brown - text = text.replace(/@62@/g, "\1n\1g\1" + "3"); // Green on brown - text = text.replace(/@63@/g, "\1n\1c\1" + "3"); // Cyan on brown - text = text.replace(/@64@/g, "\1n\1r\1" + "3"); // Red on brown - text = text.replace(/@65@/g, "\1n\1m\1" + "3"); // Magenta on brown - text = text.replace(/@66@/g, "\1n\1y\1" + "3"); // Yellow/brown on brown - text = text.replace(/@67@/g, "\1n\1w\1" + "3"); // White on brown - text = text.replace(/@68@/g, "\1h\1k\1" + "3"); // Bright black on brown - text = text.replace(/@69@/g, "\1h\1b\1" + "3"); // Bright blue on brown - text = text.replace(/@6[Aa]@/g, "\1h\1g\1" + "3"); // Bright breen on brown - text = text.replace(/@6[Bb]@/g, "\1h\1c\1" + "3"); // Bright cyan on brown - text = text.replace(/@6[Cc]@/g, "\1h\1r\1" + "3"); // Bright red on brown - text = text.replace(/@6[Dd]@/g, "\1h\1m\1" + "3"); // Bright magenta on brown - text = text.replace(/@6[Ee]@/g, "\1h\1y\1" + "3"); // Bright yellow on brown - text = text.replace(/@6[Ff]@/g, "\1h\1w\1" + "3"); // Bright white on brown - - // White background - text = text.replace(/@70@/g, "\1n\1k\1" + "7"); // Black on white - text = text.replace(/@71@/g, "\1n\1b\1" + "7"); // Blue on white - text = text.replace(/@72@/g, "\1n\1g\1" + "7"); // Green on white - text = text.replace(/@73@/g, "\1n\1c\1" + "7"); // Cyan on white - text = text.replace(/@74@/g, "\1n\1r\1" + "7"); // Red on white - text = text.replace(/@75@/g, "\1n\1m\1" + "7"); // Magenta on white - text = text.replace(/@76@/g, "\1n\1y\1" + "7"); // Yellow/brown on white - text = text.replace(/@77@/g, "\1n\1w\1" + "7"); // White on white - text = text.replace(/@78@/g, "\1h\1k\1" + "7"); // Bright black on white - text = text.replace(/@79@/g, "\1h\1b\1" + "7"); // Bright blue on white - text = text.replace(/@7[Aa]@/g, "\1h\1g\1" + "7"); // Bright green on white - text = text.replace(/@7[Bb]@/g, "\1h\1c\1" + "7"); // Bright cyan on white - text = text.replace(/@7[Cc]@/g, "\1h\1r\1" + "7"); // Bright red on white - text = text.replace(/@7[Dd]@/g, "\1h\1m\1" + "7"); // Bright magenta on white - text = text.replace(/@7[Ee]@/g, "\1h\1y\1" + "7"); // Bright yellow on white - text = text.replace(/@7[Ff]@/g, "\1h\1w\1" + "7"); // Bright white on white - - // Black background, blinking foreground - text = text.replace(/@80@/g, "\1n\1k\1" + "0\1i"); // Blinking black on black - text = text.replace(/@81@/g, "\1n\1b\1" + "0\1i"); // Blinking blue on black - text = text.replace(/@82@/g, "\1n\1g\1" + "0\1i"); // Blinking green on black - text = text.replace(/@83@/g, "\1n\1c\1" + "0\1i"); // Blinking cyan on black - text = text.replace(/@84@/g, "\1n\1r\1" + "0\1i"); // Blinking red on black - text = text.replace(/@85@/g, "\1n\1m\1" + "0\1i"); // Blinking magenta on black - text = text.replace(/@86@/g, "\1n\1y\1" + "0\1i"); // Blinking yellow/brown on black - text = text.replace(/@87@/g, "\1n\1w\1" + "0\1i"); // Blinking white on black - text = text.replace(/@88@/g, "\1h\1k\1" + "0\1i"); // Blinking bright black on black - text = text.replace(/@89@/g, "\1h\1b\1" + "0\1i"); // Blinking bright blue on black - text = text.replace(/@8[Aa]@/g, "\1h\1g\1" + "0\1i"); // Blinking bright green on black - text = text.replace(/@8[Bb]@/g, "\1h\1c\1" + "0\1i"); // Blinking bright cyan on black - text = text.replace(/@8[Cc]@/g, "\1h\1r\1" + "0\1i"); // Blinking bright red on black - text = text.replace(/@8[Dd]@/g, "\1h\1m\1" + "0\1i"); // Blinking bright magenta on black - text = text.replace(/@8[Ee]@/g, "\1h\1y\1" + "0\1i"); // Blinking bright yellow on black - text = text.replace(/@8[Ff]@/g, "\1h\1w\1" + "0\1i"); // Blinking bright white on black - - // Blue background, blinking foreground - text = text.replace(/@90@/g, "\1n\1k\1" + "4\1i"); // Blinking black on blue - text = text.replace(/@91@/g, "\1n\1b\1" + "4\1i"); // Blinking blue on blue - text = text.replace(/@92@/g, "\1n\1g\1" + "4\1i"); // Blinking green on blue - text = text.replace(/@93@/g, "\1n\1c\1" + "4\1i"); // Blinking cyan on blue - text = text.replace(/@94@/g, "\1n\1r\1" + "4\1i"); // Blinking red on blue - text = text.replace(/@95@/g, "\1n\1m\1" + "4\1i"); // Blinking magenta on blue - text = text.replace(/@96@/g, "\1n\1y\1" + "4\1i"); // Blinking yellow/brown on blue - text = text.replace(/@97@/g, "\1n\1w\1" + "4\1i"); // Blinking white on blue - text = text.replace(/@98@/g, "\1h\1k\1" + "4\1i"); // Blinking bright black on blue - text = text.replace(/@99@/g, "\1h\1b\1" + "4\1i"); // Blinking bright blue on blue - text = text.replace(/@9[Aa]@/g, "\1h\1g\1" + "4\1i"); // Blinking bright green on blue - text = text.replace(/@9[Bb]@/g, "\1h\1c\1" + "4\1i"); // Blinking bright cyan on blue - text = text.replace(/@9[Cc]@/g, "\1h\1r\1" + "4\1i"); // Blinking bright red on blue - text = text.replace(/@9[Dd]@/g, "\1h\1m\1" + "4\1i"); // Blinking bright magenta on blue - text = text.replace(/@9[Ee]@/g, "\1h\1y\1" + "4\1i"); // Blinking bright yellow on blue - text = text.replace(/@9[Ff]@/g, "\1h\1w\1" + "4\1i"); // Blinking bright white on blue - - // Green background, blinking foreground - text = text.replace(/@[Aa]0@/g, "\1n\1k\1" + "2\1i"); // Blinking black on green - text = text.replace(/@[Aa]1@/g, "\1n\1b\1" + "2\1i"); // Blinking blue on green - text = text.replace(/@[Aa]2@/g, "\1n\1g\1" + "2\1i"); // Blinking green on green - text = text.replace(/@[Aa]3@/g, "\1n\1c\1" + "2\1i"); // Blinking cyan on green - text = text.replace(/@[Aa]4@/g, "\1n\1r\1" + "2\1i"); // Blinking red on green - text = text.replace(/@[Aa]5@/g, "\1n\1m\1" + "2\1i"); // Blinking magenta on green - text = text.replace(/@[Aa]6@/g, "\1n\1y\1" + "2\1i"); // Blinking yellow/brown on green - text = text.replace(/@[Aa]7@/g, "\1n\1w\1" + "2\1i"); // Blinking white on green - text = text.replace(/@[Aa]8@/g, "\1h\1k\1" + "2\1i"); // Blinking bright black on green - text = text.replace(/@[Aa]9@/g, "\1h\1b\1" + "2\1i"); // Blinking bright blue on green - text = text.replace(/@[Aa][Aa]@/g, "\1h\1g\1" + "2\1i"); // Blinking bright green on green - text = text.replace(/@[Aa][Bb]@/g, "\1h\1c\1" + "2\1i"); // Blinking bright cyan on green - text = text.replace(/@[Aa][Cc]@/g, "\1h\1r\1" + "2\1i"); // Blinking bright red on green - text = text.replace(/@[Aa][Dd]@/g, "\1h\1m\1" + "2\1i"); // Blinking bright magenta on green - text = text.replace(/@[Aa][Ee]@/g, "\1h\1y\1" + "2\1i"); // Blinking bright yellow on green - text = text.replace(/@[Aa][Ff]@/g, "\1h\1w\1" + "2\1i"); // Blinking bright white on green - - // Cyan background, blinking foreground - text = text.replace(/@[Bb]0@/g, "\1n\1k\1" + "6\1i"); // Blinking black on cyan - text = text.replace(/@[Bb]1@/g, "\1n\1b\1" + "6\1i"); // Blinking blue on cyan - text = text.replace(/@[Bb]2@/g, "\1n\1g\1" + "6\1i"); // Blinking green on cyan - text = text.replace(/@[Bb]3@/g, "\1n\1c\1" + "6\1i"); // Blinking cyan on cyan - text = text.replace(/@[Bb]4@/g, "\1n\1r\1" + "6\1i"); // Blinking red on cyan - text = text.replace(/@[Bb]5@/g, "\1n\1m\1" + "6\1i"); // Blinking magenta on cyan - text = text.replace(/@[Bb]6@/g, "\1n\1y\1" + "6\1i"); // Blinking yellow/brown on cyan - text = text.replace(/@[Bb]7@/g, "\1n\1w\1" + "6\1i"); // Blinking white on cyan - text = text.replace(/@[Bb]8@/g, "\1h\1k\1" + "6\1i"); // Blinking bright black on cyan - text = text.replace(/@[Bb]9@/g, "\1h\1b\1" + "6\1i"); // Blinking bright blue on cyan - text = text.replace(/@[Bb][Aa]@/g, "\1h\1g\1" + "6\1i"); // Blinking bright green on cyan - text = text.replace(/@[Bb][Bb]@/g, "\1h\1c\1" + "6\1i"); // Blinking bright cyan on cyan - text = text.replace(/@[Bb][Cc]@/g, "\1h\1r\1" + "6\1i"); // Blinking bright red on cyan - text = text.replace(/@[Bb][Dd]@/g, "\1h\1m\1" + "6\1i"); // Blinking bright magenta on cyan - text = text.replace(/@[Bb][Ee]@/g, "\1h\1y\1" + "6\1i"); // Blinking bright yellow on cyan - text = text.replace(/@[Bb][Ff]@/g, "\1h\1w\1" + "6\1i"); // Blinking bright white on cyan - - // Red background, blinking foreground - text = text.replace(/@[Cc]0@/g, "\1n\1k\1" + "1\1i"); // Blinking black on red - text = text.replace(/@[Cc]1@/g, "\1n\1b\1" + "1\1i"); // Blinking blue on red - text = text.replace(/@[Cc]2@/g, "\1n\1g\1" + "1\1i"); // Blinking green on red - text = text.replace(/@[Cc]3@/g, "\1n\1c\1" + "1\1i"); // Blinking cyan on red - text = text.replace(/@[Cc]4@/g, "\1n\1r\1" + "1\1i"); // Blinking red on red - text = text.replace(/@[Cc]5@/g, "\1n\1m\1" + "1\1i"); // Blinking magenta on red - text = text.replace(/@[Cc]6@/g, "\1n\1y\1" + "1\1i"); // Blinking yellow/brown on red - text = text.replace(/@[Cc]7@/g, "\1n\1w\1" + "1\1i"); // Blinking white on red - text = text.replace(/@[Cc]8@/g, "\1h\1k\1" + "1\1i"); // Blinking bright black on red - text = text.replace(/@[Cc]9@/g, "\1h\1b\1" + "1\1i"); // Blinking bright blue on red - text = text.replace(/@[Cc][Aa]@/g, "\1h\1g\1" + "1\1i"); // Blinking bright green on red - text = text.replace(/@[Cc][Bb]@/g, "\1h\1c\1" + "1\1i"); // Blinking bright cyan on red - text = text.replace(/@[Cc][Cc]@/g, "\1h\1r\1" + "1\1i"); // Blinking bright red on red - text = text.replace(/@[Cc][Dd]@/g, "\1h\1m\1" + "1\1i"); // Blinking bright magenta on red - text = text.replace(/@[Cc][Ee]@/g, "\1h\1y\1" + "1\1i"); // Blinking bright yellow on red - text = text.replace(/@[Cc][Ff]@/g, "\1h\1w\1" + "1\1i"); // Blinking bright white on red - - // Magenta background, blinking foreground - text = text.replace(/@[Dd]0@/g, "\1n\1k\1" + "5\1i"); // Blinking black on magenta - text = text.replace(/@[Dd]1@/g, "\1n\1b\1" + "5\1i"); // Blinking blue on magenta - text = text.replace(/@[Dd]2@/g, "\1n\1g\1" + "5\1i"); // Blinking green on magenta - text = text.replace(/@[Dd]3@/g, "\1n\1c\1" + "5\1i"); // Blinking cyan on magenta - text = text.replace(/@[Dd]4@/g, "\1n\1r\1" + "5\1i"); // Blinking red on magenta - text = text.replace(/@[Dd]5@/g, "\1n\1m\1" + "5\1i"); // Blinking magenta on magenta - text = text.replace(/@[Dd]6@/g, "\1n\1y\1" + "5\1i"); // Blinking yellow/brown on magenta - text = text.replace(/@[Dd]7@/g, "\1n\1w\1" + "5\1i"); // Blinking white on magenta - text = text.replace(/@[Dd]8@/g, "\1h\1k\1" + "5\1i"); // Blinking bright black on magenta - text = text.replace(/@[Dd]9@/g, "\1h\1b\1" + "5\1i"); // Blinking bright blue on magenta - text = text.replace(/@[Dd][Aa]@/g, "\1h\1g\1" + "5\1i"); // Blinking bright green on magenta - text = text.replace(/@[Dd][Bb]@/g, "\1h\1c\1" + "5\1i"); // Blinking bright cyan on magenta - text = text.replace(/@[Dd][Cc]@/g, "\1h\1r\1" + "5\1i"); // Blinking bright red on magenta - text = text.replace(/@[Dd][Dd]@/g, "\1h\1m\1" + "5\1i"); // Blinking bright magenta on magenta - text = text.replace(/@[Dd][Ee]@/g, "\1h\1y\1" + "5\1i"); // Blinking bright yellow on magenta - text = text.replace(/@[Dd][Ff]@/g, "\1h\1w\1" + "5\1i"); // Blinking bright white on magenta - - // Brown background, blinking foreground - text = text.replace(/@[Ee]0@/g, "\1n\1k\1" + "3\1i"); // Blinking black on brown - text = text.replace(/@[Ee]1@/g, "\1n\1b\1" + "3\1i"); // Blinking blue on brown - text = text.replace(/@[Ee]2@/g, "\1n\1g\1" + "3\1i"); // Blinking green on brown - text = text.replace(/@[Ee]3@/g, "\1n\1c\1" + "3\1i"); // Blinking cyan on brown - text = text.replace(/@[Ee]4@/g, "\1n\1r\1" + "3\1i"); // Blinking red on brown - text = text.replace(/@[Ee]5@/g, "\1n\1m\1" + "3\1i"); // Blinking magenta on brown - text = text.replace(/@[Ee]6@/g, "\1n\1y\1" + "3\1i"); // Blinking yellow/brown on brown - text = text.replace(/@[Ee]7@/g, "\1n\1w\1" + "3\1i"); // Blinking white on brown - text = text.replace(/@[Ee]8@/g, "\1h\1k\1" + "3\1i"); // Blinking bright black on brown - text = text.replace(/@[Ee]9@/g, "\1h\1b\1" + "3\1i"); // Blinking bright blue on brown - text = text.replace(/@[Ee][Aa]@/g, "\1h\1g\1" + "3\1i"); // Blinking bright green on brown - text = text.replace(/@[Ee][Bb]@/g, "\1h\1c\1" + "3\1i"); // Blinking bright cyan on brown - text = text.replace(/@[Ee][Cc]@/g, "\1h\1r\1" + "3\1i"); // Blinking bright red on brown - text = text.replace(/@[Ee][Dd]@/g, "\1h\1m\1" + "3\1i"); // Blinking bright magenta on brown - text = text.replace(/@[Ee][Ee]@/g, "\1h\1y\1" + "3\1i"); // Blinking bright yellow on brown - text = text.replace(/@[Ee][Ff]@/g, "\1h\1w\1" + "3\1i"); // Blinking bright white on brown - - // White background, blinking foreground - text = text.replace(/@[Ff]0@/g, "\1n\1k\1" + "7\1i"); // Blinking black on white - text = text.replace(/@[Ff]1@/g, "\1n\1b\1" + "7\1i"); // Blinking blue on white - text = text.replace(/@[Ff]2@/g, "\1n\1g\1" + "7\1i"); // Blinking green on white - text = text.replace(/@[Ff]3@/g, "\1n\1c\1" + "7\1i"); // Blinking cyan on white - text = text.replace(/@[Ff]4@/g, "\1n\1r\1" + "7\1i"); // Blinking red on white - text = text.replace(/@[Ff]5@/g, "\1n\1m\1" + "7\1i"); // Blinking magenta on white - text = text.replace(/@[Ff]6@/g, "\1n\1y\1" + "7\1i"); // Blinking yellow/brown on white - text = text.replace(/@[Ff]7@/g, "\1n\1w\1" + "7\1i"); // Blinking white on white - text = text.replace(/@[Ff]8@/g, "\1h\1k\1" + "7\1i"); // Blinking bright black on white - text = text.replace(/@[Ff]9@/g, "\1h\1b\1" + "7\1i"); // Blinking bright blue on white - text = text.replace(/@[Ff][Aa]@/g, "\1h\1g\1" + "7\1i"); // Blinking bright green on white - text = text.replace(/@[Ff][Bb]@/g, "\1h\1c\1" + "7\1i"); // Blinking bright cyan on white - text = text.replace(/@[Ff][Cc]@/g, "\1h\1r\1" + "7\1i"); // Blinking bright red on white - text = text.replace(/@[Ff][Dd]@/g, "\1h\1m\1" + "7\1i"); // Blinking bright magenta on white - text = text.replace(/@[Ff][Ee]@/g, "\1h\1y\1" + "7\1i"); // Blinking bright yellow on white - text = text.replace(/@[Ff][Ff]@/g, "\1h\1w\1" + "7\1i"); // Blinking bright white on white - - return text; - } - else - return pText; // No Wildcat-style attribute codes found, so just return the text. -} - -// Converts Celerity attribute codes to Synchronet attribute codes. -// -// Parameters: -// pText: A string containing the text to convert -// -// Return value: The text with the color codes converted -function celerityAttrsToSyncAttrs(pText) -{ - // First, see if the text has any Celerity-style attribute codes at - // all. We'll be performing a bunch of search & replace commands, - // so we don't want to do all that work for nothing.. :) - if (/\|[kbgcrmywdBGCRMYWS]/.test(pText)) - { - // Using the \|S code (swap foreground & background) - - // Blue background - var text = pText.replace(/\|b\|S\|k/g, "\1n\1k\1" + "4"); // Black on blue - text = text.replace(/\|b\|S\|b/g, "\1n\1b\1" + "4"); // Blue on blue - text = text.replace(/\|b\|S\|g/g, "\1n\1g\1" + "4"); // Green on blue - text = text.replace(/\|b\|S\|c/g, "\1n\1c\1" + "4"); // Cyan on blue - text = text.replace(/\|b\|S\|r/g, "\1n\1r\1" + "4"); // Red on blue - text = text.replace(/\|b\|S\|m/g, "\1n\1m\1" + "4"); // Magenta on blue - text = text.replace(/\|b\|S\|y/g, "\1n\1y\1" + "4"); // Yellow/brown on blue - text = text.replace(/\|b\|S\|w/g, "\1n\1w\1" + "4"); // White on blue - text = text.replace(/\|b\|S\|d/g, "\1h\1k\1" + "4"); // Bright black on blue - text = text.replace(/\|b\|S\|B/g, "\1h\1b\1" + "4"); // Bright blue on blue - text = text.replace(/\|b\|S\|G/g, "\1h\1g\1" + "4"); // Bright green on blue - text = text.replace(/\|b\|S\|C/g, "\1h\1c\1" + "4"); // Bright cyan on blue - text = text.replace(/\|b\|S\|R/g, "\1h\1r\1" + "4"); // Bright red on blue - text = text.replace(/\|b\|S\|M/g, "\1h\1m\1" + "4"); // Bright magenta on blue - text = text.replace(/\|b\|S\|Y/g, "\1h\1y\1" + "4"); // Yellow on blue - text = text.replace(/\|b\|S\|W/g, "\1h\1w\1" + "4"); // Bright white on blue - - // Green background - text = text.replace(/\|g\|S\|k/g, "\1n\1k\1" + "2"); // Black on green - text = text.replace(/\|g\|S\|b/g, "\1n\1b\1" + "2"); // Blue on green - text = text.replace(/\|g\|S\|g/g, "\1n\1g\1" + "2"); // Green on green - text = text.replace(/\|g\|S\|c/g, "\1n\1c\1" + "2"); // Cyan on green - text = text.replace(/\|g\|S\|r/g, "\1n\1r\1" + "2"); // Red on green - text = text.replace(/\|g\|S\|m/g, "\1n\1m\1" + "2"); // Magenta on green - text = text.replace(/\|g\|S\|y/g, "\1n\1y\1" + "2"); // Yellow/brown on green - text = text.replace(/\|g\|S\|w/g, "\1n\1w\1" + "2"); // White on green - text = text.replace(/\|g\|S\|d/g, "\1h\1k\1" + "2"); // Bright black on green - text = text.replace(/\|g\|S\|B/g, "\1h\1b\1" + "2"); // Bright blue on green - text = text.replace(/\|g\|S\|G/g, "\1h\1g\1" + "2"); // Bright green on green - text = text.replace(/\|g\|S\|C/g, "\1h\1c\1" + "2"); // Bright cyan on green - text = text.replace(/\|g\|S\|R/g, "\1h\1r\1" + "2"); // Bright red on green - text = text.replace(/\|g\|S\|M/g, "\1h\1m\1" + "2"); // Bright magenta on green - text = text.replace(/\|g\|S\|Y/g, "\1h\1y\1" + "2"); // Yellow on green - text = text.replace(/\|g\|S\|W/g, "\1h\1w\1" + "2"); // Bright white on green - - // Cyan background - text = text.replace(/\|c\|S\|k/g, "\1n\1k\1" + "6"); // Black on cyan - text = text.replace(/\|c\|S\|b/g, "\1n\1b\1" + "6"); // Blue on cyan - text = text.replace(/\|c\|S\|g/g, "\1n\1g\1" + "6"); // Green on cyan - text = text.replace(/\|c\|S\|c/g, "\1n\1c\1" + "6"); // Cyan on cyan - text = text.replace(/\|c\|S\|r/g, "\1n\1r\1" + "6"); // Red on cyan - text = text.replace(/\|c\|S\|m/g, "\1n\1m\1" + "6"); // Magenta on cyan - text = text.replace(/\|c\|S\|y/g, "\1n\1y\1" + "6"); // Yellow/brown on cyan - text = text.replace(/\|c\|S\|w/g, "\1n\1w\1" + "6"); // White on cyan - text = text.replace(/\|c\|S\|d/g, "\1h\1k\1" + "6"); // Bright black on cyan - text = text.replace(/\|c\|S\|B/g, "\1h\1b\1" + "6"); // Bright blue on cyan - text = text.replace(/\|c\|S\|G/g, "\1h\1g\1" + "6"); // Bright green on cyan - text = text.replace(/\|c\|S\|C/g, "\1h\1c\1" + "6"); // Bright cyan on cyan - text = text.replace(/\|c\|S\|R/g, "\1h\1r\1" + "6"); // Bright red on cyan - text = text.replace(/\|c\|S\|M/g, "\1h\1m\1" + "6"); // Bright magenta on cyan - text = text.replace(/\|c\|S\|Y/g, "\1h\1y\1" + "6"); // Yellow on cyan - text = text.replace(/\|c\|S\|W/g, "\1h\1w\1" + "6"); // Bright white on cyan - - // Red background - text = text.replace(/\|r\|S\|k/g, "\1n\1k\1" + "1"); // Black on red - text = text.replace(/\|r\|S\|b/g, "\1n\1b\1" + "1"); // Blue on red - text = text.replace(/\|r\|S\|g/g, "\1n\1g\1" + "1"); // Green on red - text = text.replace(/\|r\|S\|c/g, "\1n\1c\1" + "1"); // Cyan on red - text = text.replace(/\|r\|S\|r/g, "\1n\1r\1" + "1"); // Red on red - text = text.replace(/\|r\|S\|m/g, "\1n\1m\1" + "1"); // Magenta on red - text = text.replace(/\|r\|S\|y/g, "\1n\1y\1" + "1"); // Yellow/brown on red - text = text.replace(/\|r\|S\|w/g, "\1n\1w\1" + "1"); // White on red - text = text.replace(/\|r\|S\|d/g, "\1h\1k\1" + "1"); // Bright black on red - text = text.replace(/\|r\|S\|B/g, "\1h\1b\1" + "1"); // Bright blue on red - text = text.replace(/\|r\|S\|G/g, "\1h\1g\1" + "1"); // Bright green on red - text = text.replace(/\|r\|S\|C/g, "\1h\1c\1" + "1"); // Bright cyan on red - text = text.replace(/\|r\|S\|R/g, "\1h\1r\1" + "1"); // Bright red on red - text = text.replace(/\|r\|S\|M/g, "\1h\1m\1" + "1"); // Bright magenta on red - text = text.replace(/\|r\|S\|Y/g, "\1h\1y\1" + "1"); // Yellow on red - text = text.replace(/\|r\|S\|W/g, "\1h\1w\1" + "1"); // Bright white on red - - // Magenta background - text = text.replace(/\|m\|S\|k/g, "\1n\1k\1" + "5"); // Black on magenta - text = text.replace(/\|m\|S\|b/g, "\1n\1b\1" + "5"); // Blue on magenta - text = text.replace(/\|m\|S\|g/g, "\1n\1g\1" + "5"); // Green on magenta - text = text.replace(/\|m\|S\|c/g, "\1n\1c\1" + "5"); // Cyan on magenta - text = text.replace(/\|m\|S\|r/g, "\1n\1r\1" + "5"); // Red on magenta - text = text.replace(/\|m\|S\|m/g, "\1n\1m\1" + "5"); // Magenta on magenta - text = text.replace(/\|m\|S\|y/g, "\1n\1y\1" + "5"); // Yellow/brown on magenta - text = text.replace(/\|m\|S\|w/g, "\1n\1w\1" + "5"); // White on magenta - text = text.replace(/\|m\|S\|d/g, "\1h\1k\1" + "5"); // Bright black on magenta - text = text.replace(/\|m\|S\|B/g, "\1h\1b\1" + "5"); // Bright blue on magenta - text = text.replace(/\|m\|S\|G/g, "\1h\1g\1" + "5"); // Bright green on magenta - text = text.replace(/\|m\|S\|C/g, "\1h\1c\1" + "5"); // Bright cyan on magenta - text = text.replace(/\|m\|S\|R/g, "\1h\1r\1" + "5"); // Bright red on magenta - text = text.replace(/\|m\|S\|M/g, "\1h\1m\1" + "5"); // Bright magenta on magenta - text = text.replace(/\|m\|S\|Y/g, "\1h\1y\1" + "5"); // Yellow on magenta - text = text.replace(/\|m\|S\|W/g, "\1h\1w\1" + "5"); // Bright white on magenta - - // Brown background - text = text.replace(/\|y\|S\|k/g, "\1n\1k\1" + "3"); // Black on brown - text = text.replace(/\|y\|S\|b/g, "\1n\1b\1" + "3"); // Blue on brown - text = text.replace(/\|y\|S\|g/g, "\1n\1g\1" + "3"); // Green on brown - text = text.replace(/\|y\|S\|c/g, "\1n\1c\1" + "3"); // Cyan on brown - text = text.replace(/\|y\|S\|r/g, "\1n\1r\1" + "3"); // Red on brown - text = text.replace(/\|y\|S\|m/g, "\1n\1m\1" + "3"); // Magenta on brown - text = text.replace(/\|y\|S\|y/g, "\1n\1y\1" + "3"); // Yellow/brown on brown - text = text.replace(/\|y\|S\|w/g, "\1n\1w\1" + "3"); // White on brown - text = text.replace(/\|y\|S\|d/g, "\1h\1k\1" + "3"); // Bright black on brown - text = text.replace(/\|y\|S\|B/g, "\1h\1b\1" + "3"); // Bright blue on brown - text = text.replace(/\|y\|S\|G/g, "\1h\1g\1" + "3"); // Bright green on brown - text = text.replace(/\|y\|S\|C/g, "\1h\1c\1" + "3"); // Bright cyan on brown - text = text.replace(/\|y\|S\|R/g, "\1h\1r\1" + "3"); // Bright red on brown - text = text.replace(/\|y\|S\|M/g, "\1h\1m\1" + "3"); // Bright magenta on brown - text = text.replace(/\|y\|S\|Y/g, "\1h\1y\1" + "3"); // Yellow on brown - text = text.replace(/\|y\|S\|W/g, "\1h\1w\1" + "3"); // Bright white on brown - - // White background - text = text.replace(/\|w\|S\|k/g, "\1n\1k\1" + "7"); // Black on white - text = text.replace(/\|w\|S\|b/g, "\1n\1b\1" + "7"); // Blue on white - text = text.replace(/\|w\|S\|g/g, "\1n\1g\1" + "7"); // Green on white - text = text.replace(/\|w\|S\|c/g, "\1n\1c\1" + "7"); // Cyan on white - text = text.replace(/\|w\|S\|r/g, "\1n\1r\1" + "7"); // Red on white - text = text.replace(/\|w\|S\|m/g, "\1n\1m\1" + "7"); // Magenta on white - text = text.replace(/\|w\|S\|y/g, "\1n\1y\1" + "7"); // Yellow/brown on white - text = text.replace(/\|w\|S\|w/g, "\1n\1w\1" + "7"); // White on white - text = text.replace(/\|w\|S\|d/g, "\1h\1k\1" + "7"); // Bright black on white - text = text.replace(/\|w\|S\|B/g, "\1h\1b\1" + "7"); // Bright blue on white - text = text.replace(/\|w\|S\|G/g, "\1h\1g\1" + "7"); // Bright green on white - text = text.replace(/\|w\|S\|C/g, "\1h\1c\1" + "7"); // Bright cyan on white - text = text.replace(/\|w\|S\|R/g, "\1h\1r\1" + "7"); // Bright red on white - text = text.replace(/\|w\|S\|M/g, "\1h\1m\1" + "7"); // Bright magenta on white - text = text.replace(/\|w\|S\|Y/g, "\1h\1y\1" + "7"); // Yellow on white - text = text.replace(/\|w\|S\|W/g, "\1h\1w\1" + "7"); // Bright white on white - - // Colors on black background - text = text.replace(/\|k/g, "\1n\1k\1" + "0"); // Black on black - text = text.replace(/\|k\|S\|k/g, "\1n\1k\1" + "0"); // Black on black - text = text.replace(/\|b/g, "\1n\1b\1" + "0"); // Blue on black - text = text.replace(/\|k\|S\|b/g, "\1n\1b\1" + "0"); // Blue on black - text = text.replace(/\|g/g, "\1n\1g\1" + "0"); // Green on black - text = text.replace(/\|k\|S\|g/g, "\1n\1g\1" + "0"); // Green on black - text = text.replace(/\|c/g, "\1n\1c\1" + "0"); // Cyan on black - text = text.replace(/\|k\|S\|c/g, "\1n\1c\1" + "0"); // Cyan on black - text = text.replace(/\|r/g, "\1n\1r\1" + "0"); // Red on black - text = text.replace(/\|k\|S\|r/g, "\1n\1r\1" + "0"); // Red on black - text = text.replace(/\|m/g, "\1n\1m\1" + "0"); // Magenta on black - text = text.replace(/\|k\|S\|m/g, "\1n\1m\1" + "0"); // Magenta on black - text = text.replace(/\|y/g, "\1n\1y\1" + "0"); // Yellow/brown on black - text = text.replace(/\|k\|S\|y/g, "\1n\1y\1" + "0"); // Yellow/brown on black - text = text.replace(/\|w/g, "\1n\1w\1" + "0"); // White on black - text = text.replace(/\|k\|S\|w/g, "\1n\1w\1" + "0"); // White on black - text = text.replace(/\|d/g, "\1h\1k\1" + "0"); // Bright black on black - text = text.replace(/\|k\|S\|d/g, "\1h\1k\1" + "0"); // Bright black on black - text = text.replace(/\|B/g, "\1h\1b\1" + "0"); // Bright blue on black - text = text.replace(/\|k\|S\|B/g, "\1h\1b\1" + "0"); // Bright blue on black - text = text.replace(/\|G/g, "\1h\1g\1" + "0"); // Bright green on black - text = text.replace(/\|k\|S\|G/g, "\1h\1g\1" + "0"); // Bright green on black - text = text.replace(/\|C/g, "\1h\1c\1" + "0"); // Bright cyan on black - text = text.replace(/\|k\|S\|C/g, "\1h\1c\1" + "0"); // Bright cyan on black - text = text.replace(/\|R/g, "\1h\1r\1" + "0"); // Bright red on black - text = text.replace(/\|k\|S\|R/g, "\1h\1r\1" + "0"); // Bright red on black - text = text.replace(/\|M/g, "\1h\1m\1" + "0"); // Bright magenta on black - text = text.replace(/\|k\|S\|M/g, "\1h\1m\1" + "0"); // Bright magenta on black - text = text.replace(/\|Y/g, "\1h\1y\1" + "0"); // Yellow on black - text = text.replace(/\|k\|S\|Y/g, "\1h\1y\1" + "0"); // Yellow on black - text = text.replace(/\|W/g, "\1h\1w\1" + "0"); // Bright white on black - text = text.replace(/\|k\|S\|W/g, "\1h\1w\1" + "0"); // Bright white on black - - return text; - } - else - return pText; // No Celerity-style attribute codes found, so just return the text. -} - -// Converts Renegade attribute (color) codes to Synchronet attribute codes. -// -// Parameters: -// pText: A string containing the text to convert -// -// Return value: The text with the color codes converted -function renegadeAttrsToSyncAttrs(pText) -{ - // First, see if the text has any Renegade-style attribute codes at - // all. We'll be performing a bunch of search & replace commands, - // so we don't want to do all that work for nothing.. :) - if (/\|[0-3][0-9]/.test(pText)) - { - var text = pText.replace(/\|00/g, "\1n\1k"); // Normal black - text = text.replace(/\|01/g, "\1n\1b"); // Normal blue - text = text.replace(/\|02/g, "\1n\1g"); // Normal green - text = text.replace(/\|03/g, "\1n\1c"); // Normal cyan - text = text.replace(/\|04/g, "\1n\1r"); // Normal red - text = text.replace(/\|05/g, "\1n\1m"); // Normal magenta - text = text.replace(/\|06/g, "\1n\1y"); // Normal brown - text = text.replace(/\|07/g, "\1n\1w"); // Normal white - text = text.replace(/\|08/g, "\1n\1k\1h"); // High intensity black - text = text.replace(/\|09/g, "\1n\1b\1h"); // High intensity blue - text = text.replace(/\|10/g, "\1n\1g\1h"); // High intensity green - text = text.replace(/\|11/g, "\1n\1c\1h"); // High intensity cyan - text = text.replace(/\|12/g, "\1n\1r\1h"); // High intensity red - text = text.replace(/\|13/g, "\1n\1m\1h"); // High intensity magenta - text = text.replace(/\|14/g, "\1n\1y\1h"); // Yellow (high intensity brown) - text = text.replace(/\|15/g, "\1n\1w\1h"); // High intensity white - text = text.replace(/\|16/g, "\1" + "0"); // Background black - text = text.replace(/\|17/g, "\1" + "4"); // Background blue - text = text.replace(/\|18/g, "\1" + "2"); // Background green - text = text.replace(/\|19/g, "\1" + "6"); // Background cyan - text = text.replace(/\|20/g, "\1" + "1"); // Background red - text = text.replace(/\|21/g, "\1" + "5"); // Background magenta - text = text.replace(/\|22/g, "\1" + "3"); // Background brown - text = text.replace(/\|23/g, "\1" + "7"); // Background white - text = text.replace(/\|24/g, "\1i\1w\1" + "0"); // Blinking white on black - text = text.replace(/\|25/g, "\1i\1w\1" + "4"); // Blinking white on blue - text = text.replace(/\|26/g, "\1i\1w\1" + "2"); // Blinking white on green - text = text.replace(/\|27/g, "\1i\1w\1" + "6"); // Blinking white on cyan - text = text.replace(/\|28/g, "\1i\1w\1" + "1"); // Blinking white on red - text = text.replace(/\|29/g, "\1i\1w\1" + "5"); // Blinking white on magenta - text = text.replace(/\|30/g, "\1i\1w\1" + "3"); // Blinking white on yellow/brown - text = text.replace(/\|31/g, "\1i\1w\1" + "7"); // Blinking white on white - return text; - } - else - return pText; // No Renegade-style attribute codes found, so just return the text. -} - -// Converts ANSI attribute codes to Synchronet attribute codes. -// -// Parameters: -// pText: A string containing the text to convert -// -// Return value: The text with the color codes converted -function ANSIAttrsToSyncAttrs(pText) -{ - // TODO: Test & update this some more.. Not sure if this is working 100% right. - - // Web pages with ANSI code information: - // http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html - // http://ascii-table.com/ansi-escape-sequences.php - // http://stackoverflow.com/questions/4842424/list-of-ansi-color-escape-sequences - - // First, see if the text has any ANSI attribute codes at all. We'll be - // performing a bunch of search & replace commands, so we don't want to do - // all that work for nothing. - if (textHasANSICodes(pText)) - { - var text = ""; - var tempDirExists = true; - // Temporary (to get it to run the old way for now) - tempDirExists = false; - /* - var readerTmpDir = backslash(system.node_dir + "DDMsgReaderTemp"); - if (!file_exists(readerTmpDir)) - tempDirExists = mkdir(readerTmpDir); - */ - if (tempDirExists) - { - var wroteTempFile = true; - var tmpFileName = readerTmpDir + "tmpMessage.ans"; - var msgTmpFile = new File(tmpFileName); - if (msgTmpFile.open("w")) - { - wroteTempFile = msgTmpFile.write(pText); - msgTmpFile.close(); - } - // If the temp file was written, then convert it to Synchronet - // attributes using ans2asc. - if (wroteTempFile) - { - var convertedTempFileName = readerTmpDir + "tmpMessage.asc"; - var cmdLine = system.exec_dir + "ans2asc \"" + tmpFileName + "\" \"" - + convertedTempFileName + "\""; - // Note: Both system.exec(cmdLine) and - // bbs.exec(cmdLine, EX_NATIVE, gStartupPath) could be used to - // execute the command, but system.exec() seems noticeably faster. - system.exec(cmdLine); - var convertedTmpFile = new File(convertedTempFileName); - if (convertedTmpFile.open("r")) - { - text = convertedTmpFile.read(); - convertedTmpFile.close(); - } - } - deltree(readerTmpDir); - } - else // Convert ANSI codes to Synchronet attributes & remove unwanted ANSI codes - text = cvtANSIToSyncAndRemoveUnwantedANSI(text); - - return text; - } - else - return pText; // No ANSI codes found, so just return the text. -} - -////////////////////////////////////////////////////////////////////////////// - -// Returns whether or not some text has any ANSI codes in it. -// -// Parameters: -// pText: The text to test -// -// Return value: Boolean - Whether or not the text has ANSI codes in it -function textHasANSICodes(pText) -{ - - return(/\[[0-9]+[mM]/.test(pText) || /\[[0-9]+(;[0-9]+)+[mM]/.test(pText) || - /\[[0-9]+[aAbBcCdD]/.test(pText) || /\[[0-9]+;[0-9]+[hHfF]/.test(pText) || - /\[[sSuUkK]/.test(pText) || /\[2[jJ]/.test(pText)); - /* - var regex1 = new RegExp(ascii(27) + "\[[0-9]+[mM]"); - var regex2 = new RegExp(ascii(27) + "\[[0-9]+(;[0-9]+)+[mM]"); - var regex3 = new RegExp(ascii(27) + "\[[0-9]+[aAbBcCdD]"); - var regex4 = new RegExp(ascii(27) + "\[[0-9]+;[0-9]+[hHfF]"); - var regex5 = new RegExp(ascii(27) + "\[[sSuUkK]"); - var regex6 = new RegExp(ascii(27) + "\[2[jJ]"); - return(regex1.test(pText) || regex2.test(pText) || regex3.test(pText) || - regex4.test(pText) || regex5.test(pText) || regex6.test(pText)); - */ -} - -// Returns the index of the last ANSI code in a string. -// -// Parameters: -// pStr: The string to search in -// pANSIRegexes: An array of regular expressions to use for searching for ANSI codes -// -// Return value: The index of the last ANSI code in the string, or -1 if not found -function idxOfLastANSICode(pStr, pANSIRegexes) -{ - var lastANSIIdx = -1; - for (var i = 0; i < pANSIRegexes.length; ++i) - { - var lastANSIIdxTmp = regexLastIndexOf(pStr, pANSIRegexes[i]); - if (lastANSIIdxTmp > lastANSIIdx) - lastANSIIdx = lastANSIIdxTmp; - } - return lastANSIIdx; -} - -// Returns the index of the first ANSI code in a string. -// -// Parameters: -// pStr: The string to search in -// pANSIRegexes: An array of regular expressions to use for searching for ANSI codes -// -// Return value: The index of the first ANSI code in the string, or -1 if not found -function idxOfFirstANSICode(pStr, pANSIRegexes) -{ - var firstANSIIdx = -1; - for (var i = 0; i < pANSIRegexes.length; ++i) - { - var firstANSIIdxTmp = regexFirstIndexOf(pStr, pANSIRegexes[i]); - if (firstANSIIdxTmp > firstANSIIdx) - firstANSIIdx = firstANSIIdxTmp; - } - return firstANSIIdx; -} - -// Returns the number of times an ANSI code is matched in a string. -// -// Parameters: -// pStr: The string to search in -// pANSIRegexes: An array of regular expressions to use for searching for ANSI codes -// -// Return value: The number of ANSI code matches in the string -function countANSICodes(pStr, pANSIRegexes) -{ - var ANSICount = 0; - for (var i = 0; i < pANSIRegexes.length; ++i) - { - var matches = pStr.match(pANSIRegexes[i]); - if (matches != null) - ANSICount += matches.length; - } - return ANSICount; -} - -// Removes ANSI codes from a string. -// -// Parameters: -// pStr: The string to remove ANSI codes from -// pANSIRegexes: An array of regular expressions to use for searching for ANSI codes -// -// Return value: A version of the string without ANSI codes -function removeANSIFromStr(pStr, pANSIRegexes) -{ - if (typeof(pStr) != "string") - return ""; - - var theStr = pStr; - for (var i = 0; i < pANSIRegexes.length; ++i) - theStr = theStr.replace(pANSIRegexes[i], ""); - return theStr; -} - -// Returns the last index in a string where a regex is found. -// From this page: -// http://stackoverflow.com/questions/273789/is-there-a-version-of-javascripts-string-indexof-that-allows-for-regular-expr -// -// Parameters: -// pStr: The string to search -// pRegex: The regular expression to match in the string -// pStartPos: Optional - The starting position in the string. If this is not -// passed, then the end of the string will be used. -// -// Return value: The last index in the string where the regex is found, or -1 if not found. -function regexLastIndexOf(pStr, pRegex, pStartPos) -{ - pRegex = (pRegex.global) ? pRegex : new RegExp(pRegex.source, "g" + (pRegex.ignoreCase ? "i" : "") + (pRegex.multiLine ? "m" : "")); - if (typeof(pStartPos) == "undefined") - pStartPos = pStr.length; - else if (pStartPos < 0) - pStartPos = 0; - var stringToWorkWith = pStr.substring(0, pStartPos + 1); - var lastIndexOf = -1; - var nextStop = 0; - while ((result = pRegex.exec(stringToWorkWith)) != null) - { - lastIndexOf = result.index; - pRegex.lastIndex = ++nextStop; - } - return lastIndexOf; -} - -// Returns the first index in a string where a regex is found. -// -// Parameters: -// pStr: The string to search -// pRegex: The regular expression to match in the string -// -// Return value: The first index in the string where the regex is found, or -1 if not found. -function regexFirstIndexOf(pStr, pRegex) -{ - pRegex = (pRegex.global) ? pRegex : new RegExp(pRegex.source, "g" + (pRegex.ignoreCase ? "i" : "") + (pRegex.multiLine ? "m" : "")); - var indexOfRegex = -1; - var nextStop = 0; - while ((result = pRegex.exec(pStr)) != null) - { - indexOfRegex = result.index; - pRegex.lastIndex = ++nextStop; - } - return indexOfRegex; -} - -// Converts ANSI ;-delimited modes (such as [Value;...;Valuem) to Synchronet -// attribute codes -// -// Parameters: -// pText: The text with ANSI ;-delimited modes to convert -// -// Return value: The text with ANSI ;-delimited codes converted to Synchronet attributes -function ANSIMultiConvertToSyncCodes(pText) -{ - var multiMatches = pText.match(/\[[0-9]+(;[0-9]+)+m/g); - if (multiMatches == null) - return pText; - var updatedText = pText; - for (var i = 0; i < multiMatches.length; ++i) - { - // Copy the string, with the [ removed from the beginning and the - // trailing 'm' removed - var text = multiMatches[i].substr(2); - text = text.substr(0, text.length-1); - var codes = text.split(";"); - var syncCodes = ""; - for (var idx = 0; idx < codes.length; ++idx) - { - if (codes[idx] == "0") // All attributes off - syncCodes += "\1n"; - else if (codes[idx] == "1") // Bold on (high intensity) - syncCodes += "\1h"; - else if (codes[idx] == "5") // Blink on - syncCodes += "\1i"; - else if (codes[idx] == "30") // Black foreground - syncCodes += "\1k"; - else if (codes[idx] == "31") // Red foreground - syncCodes += "\1r"; - else if (codes[idx] == "32") // Green foreground - syncCodes += "\1g"; - else if (codes[idx] == "33") // Yellow foreground - syncCodes += "\1y"; - else if (codes[idx] == "34") // Blue foreground - syncCodes += "\1b"; - else if (codes[idx] == "35") // Magenta foreground - syncCodes += "\1m"; - else if (codes[idx] == "36") // Cyan foreground - syncCodes += "\1c"; - else if (codes[idx] == "37") // White foreground - syncCodes += "\1w"; - else if (codes[idx] == "40") // Black background - syncCodes += "\1" + "0"; - else if (codes[idx] == "41") // Red background - syncCodes += "\1" + "1"; - else if (codes[idx] == "42") // Green background - syncCodes += "\1" + "2"; - else if (codes[idx] == "43") // Yellow background - syncCodes += "\1" + "3"; - else if (codes[idx] == "44") // Blue background - syncCodes += "\1" + "4"; - else if (codes[idx] == "45") // Magenta background - syncCodes += "\1" + "5"; - else if (codes[idx] == "46") // Cyan background - syncCodes += "\1" + "6"; - else if (codes[idx] == "47") // White background - syncCodes += "\1" + "7"; - } - updatedText = updatedText.replace(multiMatches[i], syncCodes); - } - return updatedText; -} - -// Converts Synchronet attribute codes to ANSI ;-delimited modes (such as [Value;...;Valuem) -// -// Parameters: -// pText: The text with Synchronet codes to convert -// -// Return value: The text with Synchronet attributes converted to ANSI ;-delimited codes -function syncAttrCodesToANSI(pText) -{ - // First, see if the text has any Synchronet attribute codes at - // all. We'll be performing a bunch of search & replace commands, - // so we don't want to do all that work for nothing.. :) - if (hasSyncAttrCodes(pText)) - { - var ANSIESCCodeStart = "["; - var newText = pText.replace(/\1n/gi, ANSIESCCodeStart + "0m"); // Normal - newText = newText.replace(/\1-/gi, ANSIESCCodeStart + "0m"); // Normal - newText = newText.replace(/\1_/gi, ANSIESCCodeStart + "0m"); // Normal - newText = newText.replace(/\1h/gi, ANSIESCCodeStart + "1m"); // High intensity/bold - newText = newText.replace(/\1i/gi, ANSIESCCodeStart + "5m"); // Blinking on - newText = newText.replace(/\1f/gi, ANSIESCCodeStart + "5m"); // Blinking on - newText = newText.replace(/\1k/gi, ANSIESCCodeStart + "30m"); // Black foreground - newText = newText.replace(/\1r/gi, ANSIESCCodeStart + "31m"); // Red foreground - newText = newText.replace(/\1g/gi, ANSIESCCodeStart + "32m"); // Green foreground - newText = newText.replace(/\1y/gi, ANSIESCCodeStart + "33m"); // Yellow/brown foreground - newText = newText.replace(/\1b/gi, ANSIESCCodeStart + "34m"); // Blue foreground - newText = newText.replace(/\1m/gi, ANSIESCCodeStart + "35m"); // Magenta foreground - newText = newText.replace(/\1c/gi, ANSIESCCodeStart + "36m"); // Cyan foreground - newText = newText.replace(/\1w/gi, ANSIESCCodeStart + "37m"); // White foreground - newText = newText.replace(/\1[0]/gi, ANSIESCCodeStart + "40m"); // Black background - newText = newText.replace(/\1[1]/gi, ANSIESCCodeStart + "41m"); // Red background - newText = newText.replace(/\1[2]/gi, ANSIESCCodeStart + "42m"); // Green background - newText = newText.replace(/\1[3]/gi, ANSIESCCodeStart + "43m"); // Yellow/brown background - newText = newText.replace(/\1[4]/gi, ANSIESCCodeStart + "44m"); // Blue background - newText = newText.replace(/\1[5]/gi, ANSIESCCodeStart + "45m"); // Magenta background - newText = newText.replace(/\1[6]/gi, ANSIESCCodeStart + "46m"); // Cyan background - newText = newText.replace(/\1[7]/gi, ANSIESCCodeStart + "47m"); // White background - return newText; - } - else - return pText; // No Synchronet-style attribute codes found, so just return the text. -} - // Given some text, this converts ANSI color codes to Synchronet codes and // removes unwanted ANSI codes (such as cursor movement codes, etc.). // @@ -17661,54 +16486,52 @@ function curMsgSubBoardIsLast(pGrpIdx, pSubIdx) // be a boolean. Otherwise, the value will be a string. // // Parameters: -// pArgArr: An array of strings containing values in the format -arg=val +// argv: An array of strings containing values in the format -arg=val // // Return value: An object containing the argument values. The index will be // the argument names, converted to lowercase. The values will // be either the string argument values or boolean values, depending // on the formats of the arguments passed in. -function parseArgs(pArgArr) +function parseArgs(argv) { - // Set default values for parameters that are just true/false values - var argVals = { - chooseareafirst: false, - personalemail: false, - onlynewpersonalemail: false, - personalemailsent: false, - verboselogging: false, - suppresssearchtypetext: false - }; + var argVals = getDefaultArgParseObj(); - // Sanity checking for pArgArr - Make sure it's an array - if ((typeof(pArgArr) != "object") || (typeof(pArgArr.length) != "number")) + // Sanity checking for argv - Make sure it's an array + if ((typeof(argv) != "object") || (typeof(argv.length) != "number")) return argVals; - // Go through pArgArr looking for strings in the format -arg=val and parse them + // First, test the arguments to see if they're in a format as called by + // Synchronet for loadable modules + argVals = parseLoadableModuleArgs(argv); + if (argVals.loadableModule) + return argVals; + + // Go through argv looking for strings in the format -arg=val and parse them // into objects in the argVals array. var equalsIdx = 0; var argName = ""; var argVal = ""; var argValLower = ""; // For case-insensitive "true"/"false" matching var argValIsTrue = false; - for (var i = 0; i < pArgArr.length; ++i) + for (var i = 0; i < argv.length; ++i) { // We're looking for strings that start with "-", except strings that are // only "-". - if ((typeof(pArgArr[i]) != "string") || (pArgArr[i].length == 0) || - (pArgArr[i].charAt(0) != "-") || (pArgArr[i] == "-")) + if ((typeof(argv[i]) != "string") || (argv[i].length == 0) || + (argv[i].charAt(0) != "-") || (argv[i] == "-")) { continue; } // Look for an = and if found, split the string on the = - equalsIdx = pArgArr[i].indexOf("="); + equalsIdx = argv[i].indexOf("="); // If a = is found, then split on it and add the argument name & value // to the array. Otherwise (if the = is not found), then treat the // argument as a boolean and set it to true (to enable an option). if (equalsIdx > -1) { - argName = pArgArr[i].substring(1, equalsIdx).toLowerCase(); - argVal = pArgArr[i].substr(equalsIdx+1); + argName = argv[i].substring(1, equalsIdx).toLowerCase(); + argVal = argv[i].substr(equalsIdx+1); argValLower = argVal.toLowerCase(); // If the argument value is the word "true" or "false", then add it as a // boolean. Otherwise, add it as a string. @@ -17720,7 +16543,7 @@ function parseArgs(pArgArr) } else // An equals sign (=) was not found. Add as a boolean set to true to enable the option. { - argName = pArgArr[i].substr(1).toLowerCase(); + argName = argv[i].substr(1).toLowerCase(); if ((argName == "chooseareafirst") || (argName == "personalemail") || (argName == "personalemailsent") || (argName == "allpersonalemail") || (argName == "verboselogging") || (argName == "suppresssearchtypetext") || @@ -17774,6 +16597,160 @@ function parseArgs(pArgArr) return argVals; } +// Helper for parseArgs() - If we get loadable module arguments from Synchronet, this parses them. +// +// Parameters: +// argv: An array of strings containing values in the format -arg=val +// +// Return value: An object containing the argument values. The property "loadableModule" +// in this object will be a boolean that specifies whether or not loadable +// module arguments were specified. +function parseLoadableModuleArgs(argv) +{ + var argVals = getDefaultArgParseObj(); + + var allDigitsRegex = /^[0-9]+$/; // To check if a string consists only of digits + var arg1Lower = argv[0].toLowerCase(); + // 2 args, and the 1st arg is a sub-board code & the 2nd arg is numeric & is + // the value of SCAN_INDEX: List messages in the specified sub-board (List Msgs module) + if (argv.length == 2 && subBoardCodeIsValid(arg1Lower) && allDigitsRegex.test(argv[1]) && +(argv[1]) === SCAN_INDEX) + { + argVals.loadableModule = true; + argVals.subboard = arg1Lower; + argVals.startmode = "list"; + } + // 2 parameters: Whether or not all subs are being scanned (0 or 1), and the scan mode (numeric) + // (Scan Subs module) + else if (argv.length == 2 && /^[0-1]$/.test(argv[0]) && allDigitsRegex.test(argv[1]) && isValidScanMode(+(argv[1]))) + { + argVals.loadableModule = true; + var scanAllSubs = (argv[0] == "1"); + var scanMode = +(argv[1]); + if ((scanMode & SCAN_NEW) == SCAN_NEW) + { + // Newscan + // TODO: SCAN_CONST and SCAN_BACK could be used along with SCAN_NEW + // SCAN_CONST: Continuous message scanning + // SCAN_BACK: Display most recent message if none new + argVals.search = "new_msg_scan"; + argVals.suppresssearchtypetext = true; + if (scanAllSubs) + argVals.search = "new_msg_scan_all"; + } + else if (((scanMode & SCAN_TOYOU) == SCAN_TOYOU) || ((scanMode & SCAN_UNREAD) == SCAN_UNREAD)) + { + // Scan for messages posted to you/new messages posted to you + argVals.startmode = "read"; + argVals.search = "to_user_new_scan"; + argVals.suppresssearchtypetext = true; + if (scanAllSubs) + argVals.search = "to_user_new_scan_all"; + } + else if ((scanMode & SCAN_FIND) == SCAN_FIND) + { + argVals.search = "keyword_search"; + argVals.startmode = "list"; + } + else + { + // Stock Synchronet functionality. Includes SCAN_CONST and SCAN_BACK. + bbs.scan_subs(scanMode, scanAllSubs); + argVals.exitNow = true; + } + } + // Scan Msgs loadable module support: + // 1. The sub-board internal code + // 2. The scan mode (numeric) + // 3. Optional: Search text (if any) + else if ((argv.length == 2 || argv.length == 3) && subBoardCodeIsValid(arg1Lower) && allDigitsRegex.test(argv[1]) && isValidScanMode(+(argv[1]))) + { + argVals.loadableModule = true; + var scanMode = +(argv[1]); + if (scanMode == SCAN_READ) + { + argVals.subboard = arg1Lower; + argVals.startmode = "read"; + // If a search string is specified (as the 3rd command-line argument), + // then use it for a search scan. + if (argv.length == 3 && argv[2] != "") + { + argVals.search = "keyword_search"; + argVals.searchtext = argv[2]; + } + } + else if (scanMode == SCAN_FIND) + { + argVals.subboard = arg1Lower; + argVals.search = "keyword_search"; + argVals.startmode = "list"; + if (argv.length == 3 && argv[2] != "") + argVals.searchtext = argv[2]; + } + // Some modes that the Digital Distortion Message Reader doesn't handle yet: Use + // Synchronet's stock behavior. + else + { + if (argv.length == 3) + bbs.scan_msgs(arg1Lower, scanMode, argv[2]); + else + bbs.scan_msgs(arg1Lower, scanMode); + argVals.exitNow = true; + } + } + // Reading personal email: 'Which' mailbox & user number (both numeric) (Read Mail module) + else if ((argv.length == 2 || argv.length == 3) && allDigitsRegex.test(argv[0]) && allDigitsRegex.test(argv[1]) && isValidUserNum(+(argv[1]))) + { + argVals.loadableModule = true; + var whichMailbox = +(argv[0]); + var userNum = +(argv[1]); + // The optional 3rd argument in this case is mode bits. See if we should only display + // new (unread) personal email. + var newMailOnly = false; + if (argv.length >= 3) + { + var modeVal = +(argv[2]); + newMailOnly = (((modeVal & SCAN_FIND) == SCAN_FIND) && ((modeVal & LM_UNREAD) == LM_UNREAD)); + } + // Start in list mode + argVals.startmode = "list"; // "read" + // Note: MAIL_ANY won't be passed to this script. + switch (whichMailbox) + { + case MAIL_YOUR: // Mail sent to you + argVals.personalemail = true; + argVals.usernum = argv[1]; + if (newMailOnly) + argVals.onlynewpersonalemail = true; + break; + case MAIL_SENT: // Mail you have sent + argVals.personalemailsent = true; + argVals.usernum = argv[1]; + break; + case MAIL_ALL: + argVals.allpersonalemail = true; + break; + default: + bbs.read_mail(whichMailbox); + argVals.exitNow = true; + break; + } + } + return argVals; +} +// Returns an object with default settings for argument parsing +function getDefaultArgParseObj() +{ + return { + chooseareafirst: false, + personalemail: false, + onlynewpersonalemail: false, + personalemailsent: false, + verboselogging: false, + suppresssearchtypetext: false, + loadableModule: false, + exitNow: false + }; +} // Returns a string describing all message attributes (main, auxiliary, and net). // @@ -20246,6 +19223,44 @@ function getSubBoardsToScanArray(pScanScopeChar) return subBoardsToScan; } +// Returns whether a number is a valid scan mode +// +// Parameters: +// pNum: A number to test +// +// Return value: Boolean - Whether or not the given number is a valid scan mode +function isValidScanMode(pNum) +{ + if (typeof(pNum) !== "number") + return false; + // The scan modes are defined in sbbsdefs.js + var validScanModes = [SCAN_READ, SCAN_CONST, SCAN_NEW, SCAN_BACK, SCAN_TOYOU, + SCAN_FIND, SCAN_UNREAD, SCAN_MSGSONLY, SCAN_POLLS, SCAN_INDEX]; + var numIsValidScanMode = false; + for (var i = 0; i < validScanModes.length && !numIsValidScanMode; ++i) + numIsValidScanMode = (pNum === validScanModes[i]); + return numIsValidScanMode; +} + +// Returns whether a user number is valid (only an actual, active user) +// +// Parameters: +// pUserNum: A user number +// +// Return value: Boolean - Whether or not the given user number is valid +function isValidUserNum(pUserNum) +{ + if (typeof(pUserNum) !== "number") + return false; + if (pUserNum < 1 || pUserNum > system.lastuser) + return false; + + var userIsValid = false; + var theUser = new User(pUserNum); + if (theUser != null && (theUser.settings & USER_DELETED) == 0 && (theUser.settings & USER_INACTIVE) == 0) + userIsValid = true; + return userIsValid; +} // For debugging: Writes some text on the screen at a given location with a given pause. // diff --git a/xtrn/DDMsgReader/ddmr_lm.js b/xtrn/DDMsgReader/ddmr_lm.js new file mode 100644 index 0000000000000000000000000000000000000000..87732a34b4c2ddb0321ccb674553c0de0cfe3ae7 --- /dev/null +++ b/xtrn/DDMsgReader/ddmr_lm.js @@ -0,0 +1,6 @@ +// SYSOPS: Change the msgReaderPath variable if you put Digital Distortion +// Message Reader in a different path +var msgReaderPath = "../xtrn/DDMsgReader"; + +// Run Digital Distortion Message Reader +bbs.exec("?" + msgReaderPath + "/DDMsgReader.js " + argv.join(" ")); \ No newline at end of file diff --git a/xtrn/DDMsgReader/loadable_module_scripts/DDReadPersonalMail.js b/xtrn/DDMsgReader/loadable_module_scripts/DDReadPersonalMail.js deleted file mode 100644 index 6a96de12aea28904280b07cc1e21fafefa02bd79..0000000000000000000000000000000000000000 --- a/xtrn/DDMsgReader/loadable_module_scripts/DDReadPersonalMail.js +++ /dev/null @@ -1,76 +0,0 @@ -// $Id: DDReadPersonalMail.js,v 1.5 2020/05/23 23:35:48 nightfox Exp $ - -// This script is to be executed for the 'Read mail' loadable module, configured -// in SCFG in System > Loadable Modules. - -if (typeof(require) === "function") - require("sbbsdefs.js", "SCAN_UNREAD"); -else - load("sbbsdefs.js"); - -console.print("\1n"); - -// Synchronet will pass 2 command-line arguments: -// 1. The 'which' mailbox value (numeric) - MAIL_YOUR, MAIL_SENT, or MAIL_ALL. -// MAIL_ANY won't be passed to this script. -// 2. The user number (numeric) -if (argc < 2) -{ - console.print("\1h\1yNot enough arguments were passed to the Read Mail module! Please inform the"); - console.crlf(); - console.print("sysop.\1n"); - console.crlf(); - console.pause(); - exit(1); -} -//bbs.read_mail(whichMailbox); -//exit(0); - - -var whichMailbox = Number(argv[0]); -var userNum = Number(argv[1]); -// The 3rd argument is mode bits. See if we should only display new (unread) -// personal email. -var newMailOnly = false; -if (argv.length >= 3) -{ - var modeVal = +(argv[2]); - newMailOnly = (((modeVal & SCAN_FIND) == SCAN_FIND) && ((modeVal & LM_UNREAD) == LM_UNREAD)); -} - - -// SYSOPS: Change the msgReaderPath variable if you put Digital Distortion -// Message Reader in a different path -var msgReaderPath = "../xtrn/DDMsgReader"; - -// The readerStartMode variable, below, controls whether the reader -// is to start in reader mode or message list mode. Set it to "list" -// for list mode or "read" for reader mode. -var readerStartmode = "list"; -//var readerStartmode = "read"; - - -// The start of the command string to use with bbs.exec() -var rdrCmdStrStart = "?" + msgReaderPath + "/DDMsgReader.js "; - -// Launch Digital Distortion depending on the value whichMailBox. -// Note: MAIL_ANY won't be passed to this script. -switch (whichMailbox) -{ - case MAIL_YOUR: // Mail sent to you - var cmdArgs = "-personalEmail -userNum=" + userNum; - if (newMailOnly) - cmdArgs += " -onlyNewPersonalEmail"; - cmdArgs += " -startMode=" + readerStartmode; - bbs.exec(rdrCmdStrStart + cmdArgs); - break; - case MAIL_SENT: // Mail you have sent - bbs.exec(rdrCmdStrStart + "-personalEmailSent -userNum=" + userNum + " -startMode=" + readerStartmode); - break; - case MAIL_ALL: - bbs.exec(rdrCmdStrStart + "-allPersonalEmail -startMode=" + readerStartmode); - break; - default: - bbs.read_mail(whichMailbox); - break; -} \ No newline at end of file diff --git a/xtrn/DDMsgReader/loadable_module_scripts/DDScanMsgs.js b/xtrn/DDMsgReader/loadable_module_scripts/DDScanMsgs.js deleted file mode 100644 index a8201f4c1795dac1cfb15cbddc14d5137dac6a1e..0000000000000000000000000000000000000000 --- a/xtrn/DDMsgReader/loadable_module_scripts/DDScanMsgs.js +++ /dev/null @@ -1,57 +0,0 @@ -// $Id: DDScanMsgs.js,v 1.9 2020/05/23 23:26:55 nightfox Exp $ - -// This script is to be executed for the 'Scan Msgs' loadable module, configured -// in SCFG in System > Loadable Modules. -// -// This module is used for: -// - Simply reading a sub-board -// - Find text in messages -// -// Date Author Description -// 2015-05-06 Eric Oulashin Version 1.0 - Initial release -// 2015-06-10 Eric Oulashin Version 1.02 -// Bug fix: Switched to bbs.scan_msgs() instead of -// bbs.scan_subs() for all other scan modes besides -// SCAN_READ. - -// For stock Synchronet functionality: -//bbs.scan_msgs([sub-board=current] [,mode=SCAN_READ] [,string find]) - -load("sbbsdefs.js"); - -console.print("\1n"); - -// Synchronet will pass at least 2 command-line arguments and sometimes 3: -// 1. The sub-board internal code -// 2. The scan mode (numeric) -// 3. Optional: Search text (if any) -if (argc < 2) -{ - console.print("\1h\1yNot enough arguments were passed to the Scan Messages module! Please inform the"); - console.crlf(); - console.print("sysop.\1n"); - console.crlf(); - console.pause(); - exit(1); -} - -var subBoardCode = argv[0]; -var scanMode = Number(argv[1]); -var searchText = argv[2]; - - -// SYSOPS: Change the msgReaderPath variable if you put Digital Distortion -// Message Reader in a different path -var msgReaderPath = "../xtrn/DDMsgReader"; - -// The start of the command string to use with bbs.exec() -var rdrCmdStrStart = "?" + msgReaderPath + "/DDMsgReader.js "; - -// No extra mode bits set, only read: Use Digital Distortion Message Reader -// in read mode -if (scanMode == SCAN_READ) - bbs.exec(rdrCmdStrStart + "-subBoard=" + subBoardCode + " -startMode=read"); -// Some modes that the Digital Distortion Message Reader doesn't handle yet: Use -// Synchronet's stock behavior. -else - bbs.scan_msgs(subBoardCode, scanMode, searchText); \ No newline at end of file diff --git a/xtrn/DDMsgReader/loadable_module_scripts/DDScanSubs.js b/xtrn/DDMsgReader/loadable_module_scripts/DDScanSubs.js deleted file mode 100644 index 0c36c737a6b0bef70b8b9deabbe08abd602f78f7..0000000000000000000000000000000000000000 --- a/xtrn/DDMsgReader/loadable_module_scripts/DDScanSubs.js +++ /dev/null @@ -1,66 +0,0 @@ -// $Id: DDScanSubs.js,v 1.6 2020/05/23 23:26:55 nightfox Exp $ - -// This script is to be executed for the 'Scan Subs' loadable module, configured -// in SCFG in System > Loadable Modules. -// -// This script is used for: -// - Continuous new scan -// - Browse New Scan -// - New message scan -// - Scan for messages to you (new messages to you) -// - Find text in messages - - -load("sbbsdefs.js"); - -console.print("\1n"); - -// Synchronet will pass 2 command-line arguments: Whether or not all subs -// are being scanned, and the scan mode (numeric). -if (argc < 2) -{ - console.print("\1h\1yNot enough arguments were passed to the Scan Subs module! Please inform the"); - console.crlf(); - console.print("sysop.\1n"); - console.crlf(); - console.pause(); - exit(1); -} - -var scanAllSubs = (argv[0] == "1"); -var scanMode = Number(argv[1]); - -// SYSOPS: Change the msgReaderPath variable if you put Digital Distortion -// Message Reader in a different path -var msgReaderPath = "../xtrn/DDMsgReader"; - -// The start of the command string to use with bbs.exec() -var rdrCmdStrStart = "?" + msgReaderPath + "/DDMsgReader.js "; - -// Note: SCAN_READ is 0, so the mode bits will always look like they have -// SCAN_READ. - -// For modes the Digital Distortion Message Reader doesn't handle yet, use -// Synchronet's stock behavior. -if (((scanMode & SCAN_CONST) == SCAN_CONST) || ((scanMode & SCAN_BACK) == SCAN_BACK)) - bbs.scan_subs(scanMode, scanAllSubs); -else if ((scanMode & SCAN_NEW) == SCAN_NEW) -{ - // Newscan - if (scanAllSubs) - bbs.exec(rdrCmdStrStart +"-search=new_msg_scan_all -suppressSearchTypeText"); - else // Prompt for sub-board, group, or all - bbs.exec(rdrCmdStrStart + "-search=new_msg_scan -suppressSearchTypeText"); -} -else if (((scanMode & SCAN_TOYOU) == SCAN_TOYOU) || ((scanMode & SCAN_UNREAD) == SCAN_UNREAD)) -{ - // Scan for messages posted to you/new messages posted to you - if (scanAllSubs) - bbs.exec(rdrCmdStrStart + "-startMode=read -search=to_user_new_scan_all -suppressSearchTypeText"); - else // Prompt for sub-board, group, or all - bbs.exec(rdrCmdStrStart + "-startMode=read -search=to_user_new_scan -suppressSearchTypeText"); -} -else if ((scanMode & SCAN_FIND) == SCAN_FIND) - bbs.exec(rdrCmdStrStart + "-search=keyword_search -startMode=list"); -else // Stock Synchronet functionality - bbs.scan_subs(scanMode, scanAllSubs); \ No newline at end of file diff --git a/xtrn/DDMsgReader/readme.txt b/xtrn/DDMsgReader/readme.txt index 66f9e8bd334d802162d6222eaa8d96b07165ec20..f202975db9596b9cc82fcdd313105373175693e6 100644 --- a/xtrn/DDMsgReader/readme.txt +++ b/xtrn/DDMsgReader/readme.txt @@ -1,6 +1,6 @@ Digital Distortion Message Reader - Version 1.46 - Release date: 2022-03-07 + Version 1.47 + Release date: 2022-03-14 by @@ -189,34 +189,39 @@ sbbs/xtrn/DDMsgReader directory. Loadable Modules setup ---------------------- -In Synchronet 3.16 builds starting on April 27, 2015, there are a few new -options in the Loadable Lodules configuration in SCFG: "Read Mail", "Scan -Msgs", and "Scan Subs". Functionality for these was updated on May 5, 2015. -These loadable modules options can enable the use of a message reader script -for the various message reading, searching, and scanning options provided by -Synchronet. That is probably the easiest way to install the reader, since it -only requires specifying a script in the Loadable Modules options and does not -require modification of your command shell. Setting it up that way also has -the advantage that the reader will be used for reading personal email and -performing a message newscan during the login process. If you have a recent -build of Synchronet 3.16 (or newer), then your version of Synchronet will -support this. If you are using an older version of Synchronet, skip ahead to -the "Command shell setup" subsection. - -To set up the reader with the Loadable Module scripts, do the following: -1. Copy DDReadPersonalMail.js, DDScanMsgs.js, and DDScanSubs.js from the - loadable_module_scripts directory to your sbbs/mods directory -2. If you will be running the script from a directory other than - xtrn/DDMsgReader, edit the above scripts and search for the text "SYSOPS:" - (without the double-quotes). One or two lines below that, there is a - variable called msgReaderPath - Change that so that it contains the path - where you copied DDMsgReader.js. -3. Run Synchronet's configuration program (scfg from the command prompt, or - from the GUI, select BBS > Configure). In there, select System, then - Loadable Modules -4. For the 'Read Mail' option, put in DDReadPersonalMail -5. For the 'Scan Msgs' option, put in DDScanMsgs -6. For the 'Scan Subs' option, put in DDScanSubs +The easiest way to get Digital Distortion Message Reader set up is via the +Loadable Module options in SCFG > System > LOadable Modules. + +The Loadable Modules options let you specify scripts to run for various events +in Synchronet. As of Synchronet 3.19, the following Loadable Modules options +are available in SCFG for message reading/scanning events: +- Read Mail (added in Synchronet 3.16) +- Scan Msgs (added in Synchronet 3.16) +- Scan Subs (added in Synchronet 3.16) +- List Msgs (added in Synchronet 3.18) + +The Loadable Modules options take the filename of the script without the +extension. The Loadable Modules options don't allow a leading path in front of +the name, so if you have DDMsgReader.js in a path other than sbbs/exec or +sbbs/mods, one solution is to copy the included ddmr_lm.js to either your +sbbs/exec or sbbs/mods directory (ideally sbbs/mods so it wouldn't get +accidentally deleted) and specify ddmr_lm in your Loadable Modules as follows: + + Read Mail ddmr_lm + Scan Msgs ddmr_lm + Scan Subs ddmr_lm + List Msgs ddmr_lm + +Also, if you will be running the script from a directory other than +xtrn/DDMsgReader, edit ddmr_lm.js and look for the text "SYSOPS:" (without the +double-quotes). One or two lines below that, there is a variable called +msgReaderPath - Change that so that it contains the path where you copied +DDMsgReader.js. + +Alternately, you can copy DDMsgReader.js to your sbbs/exec or sbbs/mods +directory and specify DDMsgReader in your Loadable Modules for the above +modules in SCFG. For that to work, you would also need to copy DDMsgReader.cfg +to your sbbs/ctrl directory or to sbbs/mods along with DDMsgReader.js. There are a few search modes that Synchronet provides that Digital Distortion Message Reader doesn't support yet (such as continuous newscan and browse new diff --git a/xtrn/DDMsgReader/revision_history.txt b/xtrn/DDMsgReader/revision_history.txt index d27dce649fa451659888a7fb1e43da0715f2b34d..6ab65d86fe30fb1c2c7624b464da97a0c7f41854 100644 --- a/xtrn/DDMsgReader/revision_history.txt +++ b/xtrn/DDMsgReader/revision_history.txt @@ -5,6 +5,10 @@ Revision History (change log) ============================= Version Date Description ------- ---- ----------- +1.47 2022-03-14 DDMsgReader can now be called directly as a loadable + module by Synchronet (though requires the included + ddmr_lm.js if DDMsgReader.js is not in sbbs/exec or + sbbs/mods) 1.46 2022-03-07 Fix: When changing to an empty sub-board from within the reader (either from read mode or list mode), it now properly says there are no messages and exits, rather than