Skip to content
Snippets Groups Projects
DDMsgReader.js 824 KiB
Newer Older

	// Find start & end indexes of a @MSG_TO* @-code, i.e.,
	// @MSG_TO, @MSG_TO_NAME, @MSG_TO_EXT, @MSG_TO_NET
	var toCodeStartIdx = pStr.indexOf("@MSG_TO");
	if (toCodeStartIdx < 0)
		return pStr;
	// Insert the color in the right position and return the line
	return pStr.substr(0, toCodeStartIdx) + "\1n" + pToUserColor + pStr.substr(toCodeStartIdx) + "\1n";
	/*
	// Insert the color in the right position, and
	// put a \1n right after the end of the @-code
	var str = "";
	var toCodeEndIdx = pStr.indexOf("@", toCodeStartIdx+1);
	if (toCodeEndIdx >= 0)
	{
		str = pStr.substr(0, toCodeStartIdx) + "\1n" + pToUserColor + pStr.substr(toCodeStartIdx, toCodeEndIdx-toCodeStartIdx+1)
		    + "\1n" + pStr.substr(toCodeEndIdx);
	}
	else
		str = pStr.substr(0, toCodeStartIdx) + "\1n" + pToUserColor + pStr.substr(toCodeStartIdx) + "\1n";
	return str;
	*/
}

// Returns whether a string has any Synchronet attribute codes
//
// Parameters:
//  pStr: the string to check
//
// Return value: Boolean - Whether or not the string has any Synchronet attribute codes
function hasSyncAttrCodes(pStr)
{
	return (pStr.search(/\1[krgybmcwhifn\-_01234567]/i) > -1);
}

// Gets the value of the user's current scan_ptr in a sub-board, or if it's
// 0xffffffff, returns the message number of the last readable message in
// the sub-board (this is the message number, not the index).
//
// Parameters:
//  pSubCode: A sub-board internal code
//
// Return value: The user's scan_ptr value or the message number of the
//               last readable message in the sub-board
function GetScanPtrOrLastMsgNum(pSubCode)
{
	var msgNumToReturn = 0;
	// If pMsgNum is 4294967295 (0xffffffff, or ~0), that is a special value
	// for the user's scan_ptr meaning it should point to the latest message
	// in the messagebase.
	if (msg_area.sub[pSubCode].scan_ptr != 0xffffffff)
		msgNumToReturn = msg_area.sub[pSubCode].scan_ptr;
	else
	{
		var msgbase = new MsgBase(pSubCode);
		if (msgbase.open())
		{
			var numMsgs = msgbase.total_msgs;
			for (var msgIdx = numMsgs - 1; msgIdx >= 0; --msgIdx)
			{
				var msgHdr = msgbase.get_msg_header(true, msgIdx);
				if ((msgHdr != null) && ((msgHdr.attr & MSG_DELETE) == 0))
				{
					msgNumToReturn = msgHdr.number;
					break;
				}
			}

			msgbase.close();
		}
	}

	return msgNumToReturn;
}

// Returns whether a message header has one of the attachment flags
// enabled (for Synchtonet 3.17 or newer).
//
// Parameters:
//  pMsgHdr: A message header (returned from MsgBase.get_msg_header())
//
// Return value: Boolean - Whether or not the message has one of the attachment flags
function msgHdrHasAttachmentFlag(pMsgHdr)
{
	if (typeof(pMsgHdr) !== "object" || typeof(pMsgHdr.auxattr) === "undefined")
		return false;

	var attachmentFlag = false;
	if (typeof(MSG_FILEATTACH) !== "undefined" && typeof(MSG_MIMEATTACH) !== "undefined")
		attachmentFlag = (pMsgHdr.auxattr & (MSG_FILEATTACH|MSG_MIMEATTACH)) > 0;
	return attachmentFlag;
}

// Allows the user to download a message and its attachments, using the newer
// Synchronet interface (the function bbs.download_msg_attachments() must exist).
//
// Parameters:
//  pMsgHdr: The message header
//  pSubCode: The sub-board code that the message is in
function allowUserToDownloadMessage_NewInterface(pMsgHdr, pSubCode)
{
	if (typeof(bbs.download_msg_attachments) !== "function")
		return;
	if (typeof(pSubCode) !== "string")
		return;
	if (typeof(pMsgHdr) !== "object" || typeof(pMsgHdr.number) == "undefined")
		return;

	var msgBase = new MsgBase(pSubCode);
	if (msgBase.open())
	{
		// bbs.download_msg_attachments() requires a message header returned
		// by MsgBase.get_msg_header()
		var msgHdrForDownloading = msgBase.get_msg_header(false, pMsgHdr.number, false);
		// Allow the user to download the message
		if (!console.noyes("Download message", P_NOCRLF))
		{
			if (!download_msg(msgHdrForDownloading, msgBase, console.yesno("Plain-text only")))
				console.print("\1n\r\nFailed\r\n");
		}
		// Allow the user to download the attachments
		console.creturn();
		bbs.download_msg_attachments(msgHdrForDownloading);
		msgBase.close();
		delete msgBase; // Free some memory?
	}
}

// From msglist.js - Prompts the user if they want to download the message text
function download_msg(msg, msgbase, plain_text)
{
	var fname = system.temp_dir + "msg_" + msg.number + ".txt";
	var f = new File(fname);
	if(!f.open("wb"))
		return false;
	var text = msgbase.get_msg_body(msg
				,/* strip ctrl-a */false
				,/* dot-stuffing */false
				,/* tails */true
				,plain_text);
	f.write(msg.get_rfc822_header(/* force_update: */false, /* unfold: */false
		,/* default_content_type */!plain_text));
	f.writeln(text);
	f.close();
	return bbs.send_file(fname);
}


////////// Message list sort functions

// For sorting message headers by date & time
//
// Parameters:
//  msgHdrA: The first message header
//  msgHdrB: The second message header
//
// Return value: -1, 0, or 1, depending on whether header A comes before,
//               is equal to, or comes after header B
function sortMessageHdrsByDateTime(msgHdrA, msgHdrB)
{
	// Return -1, 0, or 1, depending on whether msgHdrA's date & time comes
	// before, is equal to, or comes after msgHdrB's date & time
	// Convert when_written_time to local time before comparing the times
	var localWrittenTimeA = msgWrittenTimeToLocalBBSTime(msgHdrA);
	var localWrittenTimeB = msgWrittenTimeToLocalBBSTime(msgHdrB);
	var yearA = +strftime("%Y", localWrittenTimeA);
	var monthA = +strftime("%m", localWrittenTimeA);
	var dayA = +strftime("%d", localWrittenTimeA);
	var hourA = +strftime("%H", localWrittenTimeA);
	var minuteA = +strftime("%M", localWrittenTimeA);
	var secondA = +strftime("%S", localWrittenTimeA);
	var yearB = +strftime("%Y", localWrittenTimeB);
	var monthB = +strftime("%m", localWrittenTimeB);
	var dayB = +strftime("%d", localWrittenTimeB);
	var hourB = +strftime("%H", localWrittenTimeB);
	var minuteB = +strftime("%M", localWrittenTimeB);
	var secondB = +strftime("%S", localWrittenTimeB);
	if (yearA < yearB)
		return -1;
	else if (yearA > yearB)
		return 1;
	else
	{
		if (monthA < monthB)
			return -1;
		else if (monthA > monthB)
			return 1;
		else
		{
			if (dayA < dayB)
				return -1;
			else if (dayA > dayB)
				return 1;
			else
			{
				if (hourA < hourB)
					return -1;
				else if (hourA > hourB)
					return 1;
				else
				{
					if (minuteA < minuteB)
						return -1;
					else if (minuteA > minuteB)
						return 1;
					else
					{
						if (secondA < secondB)
							return -1;
						else if (secondA > secondB)
							return 1;
						else
							return 0;
					}
				}
			}
		}
	}
}

// Returns an array of internal sub-board codes to scan for a given scan scope.
//
// Parameters:
//  pScanScopeChar: A string specifying "A" for all sub-boards, "G" for current
//                  message group sub-boards, or "S" for the current sub-board
//
// Return value: An array of internal sub-board codes for sub-boards to scan
function getSubBoardsToScanArray(pScanScopeChar)
{
	var subBoardsToScan = [];
	if (pScanScopeChar == "A") // All sub-board scan
	{
		for (var grpIndex = 0; grpIndex < msg_area.grp_list.length; ++grpIndex)
		{
			for (var subIndex = 0; subIndex < msg_area.grp_list[grpIndex].sub_list.length; ++subIndex)
				subBoardsToScan.push(msg_area.grp_list[grpIndex].sub_list[subIndex].code);
		}
	}
	else if (pScanScopeChar == "G") // Group scan
	{
		for (var subIndex = 0; subIndex < msg_area.grp_list[bbs.curgrp].sub_list.length; ++subIndex)
			subBoardsToScan.push(msg_area.grp_list[bbs.curgrp].sub_list[subIndex].code);
	}
	else if (pScanScopeChar == "S") // Current sub-board scan
		subBoardsToScan.push(bbs.cursub_code);
	return subBoardsToScan;
}

// For debugging: Writes some text on the screen at a given location with a given pause.
//
// Parameters:
//  pX: The column number on the screen at which to write the message
//  pY: The row number on the screen at which to write the message
//  pText: The text to write
//  pPauseMS: The pause time, in milliseconds
//  pClearLineAttrib: Optional - The color/attribute to clear the line with.
//                    If not specified or null is specified, defaults to normal attribute.
//  pClearLineAfter: Whether or not to clear the line again after the message is dispayed and
//                   the pause occurred.  This is optional.
function writeWithPause(pX, pY, pText, pPauseMS, pClearLineAttrib, pClearLineAfter)
{
	var clearLineAttrib = "\1n";
	if ((pClearLineAttrib != null) && (typeof(pClearLineAttrib) == "string"))
		clearLineAttrib = pClearLineAttrib;
	console.gotoxy(pX, pY);
	console.cleartoeol(clearLineAttrib);
	console.print(pText);
	if (pClearLineAfter)
	{
		console.gotoxy(pX, pY);
		console.cleartoeol(clearLineAttrib);
	}