Newer
Older
}
// 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);
}
19014
19015
19016
19017
19018
19019
19020
19021
19022
19023
19024
19025
19026
19027
19028
19029
19030
19031
19032
19033
19034
19035
19036
19037
19038
19039
19040
19041
19042
19043
19044
19045
19046
19047
19048
19049
19050
19051
19052
19053
// 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;
}
19054
19055
19056
19057
19058
19059
19060
19061
19062
19063
19064
19065
19066
19067
19068
19069
19070
19071
19072
19073
19074
19075
19076
19077
19078
19079
19080
19081
19082
19083
19084
19085
19086
19087
19088
19089
19090
19091
19092
19093
19094
19095
19096
19097
19098
19099
19100
19101
19102
19103
19104
19105
19106
19107
19108
19109
19110
19111
19112
19113
19114
19115
19116
19117
19118
19119
19120
19121
19122
19123
19124
19125
19126
19127
19128
19129
19130
19131
19132
19133
19134
19135
19136
19137
19138
19139
19140
19141
19142
19143
19144
19145
19146
19147
19148
19149
19150
19151
19152
19153
19154
19155
19156
19157
19158
19159
19160
19161
19162
19163
19164
19165
19166
19167
19168
19169
19170
19171
19172
19173
19174
19175
19176
19177
19178
19179
19180
19181
19182
19183
19184
19185
19186
19187
19188
19189
19190
19191
19192
19193
19194
19195
19196
19197
19198
// 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;
}
}
}
}
}
}
Eric Oulashin
committed
19199
19200
19201
19202
19203
19204
19205
19206
19207
19208
19209
19210
19211
19212
19213
19214
19215
19216
19217
19218
19219
19220
19221
19222
19223
19224
19225
19226
// 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;
}
19227
19228
19229
19230
19231
19232
19233
19234
19235
19236
19237
19238
19239
19240
19241
19242
19243
19244
19245
19246
19247
19248
19249
19250
19251
19252
19253
19254
19255
19256
19257
19258
19259
19260
19261
19262
19263
19264
// 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;
}
19266
19267
19268
19269
19270
19271
19272
19273
19274
19275
19276
19277
19278
19279
19280
19281
19282
19283
19284
19285
19286
19287
19288
19289
19290
19291
19292
19293
19294
19295
19296
19297
19298
19299
19300
19301
19302
19303
19304
19305
19306
19307
19308
19309
19310
19311
19312
19313
19314
19315
19316
19317
19318
19319
19320
19321
19322
19323
19324
19325
19326
19327
19328
19329
19330
19331
19332
19333
19334
19335
19336
19337
19338
19339
19340
19341
19342
19343
19344
19345
19346
19347
19348
19349
19350
19351
19352
19353
19354
19355
19356
19357
19358
19359
19360
19361
19362
19363
19364
19365
19366
19367
19368
19369
19370
19371
19372
19373
19374
19375
19376
19377
19378
19379
19380
19381
19382
19383
19384
19385
19386
19387
19388
19389
// 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;
}
// 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 (pPauseMS > 0)
mswait(pPauseMS);
if (pClearLineAfter)
{
console.gotoxy(pX, pY);
console.cleartoeol(clearLineAttrib);
}