Newer
Older
19001
19002
19003
19004
19005
19006
19007
19008
19009
19010
19011
19012
19013
19014
19015
19016
19017
19018
19019
19020
19021
19022
return pollClosed;
}
// Closes a poll.
//
// Parameters:
// pSubBoardCode: The internal code of the sub-board
// pMsgNum: The message number (not the index)
//
// Return value: Boolean - Whether or not closing the poll succeeded
function closePoll(pSubBoardCode, pMsgNum)
{
var pollClosed = false;
var msgbase = new MsgBase(pSubBoardCode);
if (msgbase.open())
{
pollClosed = closePollWithOpenMsgbase(msgbase, pMsgNum);
msgbase.close();
}
return pollClosed;
}
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
19054
19055
19056
19057
19058
// Gets a message header from the messagebase, either by index (offset) or number.
//
// Parameters:
// pMsgbase: Optional messagebase object. If this is provided, then pSubBoardCode is not used.
// pSubBoardCode: The messagebase sub-board code
// pByIdx: Boolean - Whether or not to get the message header by index (if false, then by number)
// pMsgIdxOrNum: The message index or number of the message header to retrieve
// pExpandFields: Boolean - Whether or not to expand fields for the message header
function getHdrFromMsgbase(pMsgbase, pSubBoardCode, pByIdx, pMsgIdxOrNum, pExpandFields)
{
var msgbaseIsOpen = false;
var msgbase = null;
var msgHdr = null;
if (pMsgbase == null)
{
msgbase = new MsgBase(pSubBoardCode);
msgbaseIsOpen = msgbase.open();
}
else
{
msgbase = pMsgbase;
msgbaseIsOpen = pMsgbase.is_open;
}
if (msgbaseIsOpen)
{
var getMsgHdr = true;
if (pByIdx)
getMsgHdr = ((pMsgIdxOrNum >= 0) && (pMsgIdxOrNum < msgbase.total_msgs))
if (getMsgHdr)
msgHdr = msgbase.get_msg_header(pByIdx, pMsgIdxOrNum, pExpandFields);
if (pMsgbase == null)
msgbase.close();
}
return msgHdr;
}
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
// Inputs a string from the user, restricting their input to certain keys (optionally).
//
// Parameters:
// pKeys: A string containing valid characters for input. Optional
// pMaxNumChars: The maximum number of characters to input. Optional
// pCaseSensitive: Boolean - Whether or not the input should be case-sensitive. Optional.
// Defaults to true. If false, then the user input will be uppercased.
//
// Return value: A string containing the user's input
function consoleGetStrWithValidKeys(pKeys, pMaxNumChars, pCaseSensitive)
{
var maxNumChars = 0;
if ((typeof(pMaxNumChars) == "number") && (pMaxNumChars > 0))
maxNumChars = pMaxNumChars;
var regexPattern = (typeof(pKeys) == "string" ? "[" + pKeys + "]" : ".");
var caseSensitive = (typeof(pCaseSensitive) == "boolean" ? pCaseSensitive : true);
var regex = new RegExp(regexPattern, (caseSensitive ? "" : "i"));
var CTRL_H = "\x08";
var BACKSPACE = CTRL_H;
var CTRL_M = "\x0d";
var KEY_ENTER = CTRL_M;
var modeBits = (caseSensitive ? K_NONE : K_UPPER);
var userInput = "";
var continueOn = true;
while (continueOn)
{
var userChar = console.getkey(K_NOECHO|modeBits);
if (regex.test(userChar) && isPrintableChar(userChar))
{
var appendChar = true;
if ((maxNumChars > 0) && (userInput.length >= maxNumChars))
appendChar = false;
if (appendChar)
{
userInput += userChar;
if ((modeBits & K_NOECHO) == 0)
console.print(userChar);
}
}
else if (userChar == BACKSPACE)
{
if (userInput.length > 0)
{
if ((modeBits & K_NOECHO) == 0)
{
console.print(BACKSPACE);
console.print(" ");
console.print(BACKSPACE);
}
userInput = userInput.substr(0, userInput.length-1);
}
}
else if (userChar == KEY_ENTER)
{
continueOn = false;
if ((modeBits & K_NOCRLF) == 0)
console.crlf();
}
}
return userInput;
}
// Returns whether or not a character is printable.
//
// Parameters:
// pChar: A character to test
//
// Return value: Boolean - Whether or not the character is printable
function isPrintableChar(pChar)
{
// Make sure pChar is valid and is a string.
if (typeof(pChar) != "string")
return false;
if (pChar.length == 0)
return false;
// Make sure the character is a printable ASCII character in the range of 32 to 254,
// except for 127 (delete).
var charCode = pChar.charCodeAt(0);
return ((charCode > 31) && (charCode < 255) && (charCode != 127));
}
// Adds message attributes to a message header and saves it in the messagebase.
// To do that, this function first loads the messag header from the messagebase
// without expanded fields, applies the attributes, and then saves the header
// back to the messagebase.
//
// Parameters:
// pMsgbaseOrSubCode: An open MessageBase object or a sub-board code (string)
// pMsgNum: The number of the message to update
// pMsgAttrs: The message attributes to apply to the message (numeric bitfield)
//
// Return value: An object containing the following properties:
// saveSucceeded: Boolean - Whether or not the message header was successfully saved
// msgAttrs: A numeric bitfield containing the updated attributes of the message header
function applyAttrsInMsgHdrInMessagbase(pMsgbaseOrSubCode, pMsgNum, pMsgAttrs)
{
var retObj = {
saveSucceeded: false,
msgAttrs: 0
};
var msgbaseOpen = false;
var msgbase = null;
if (typeof(pMsgbaseOrSubCode) == "object")
{
msgbase = pMsgbaseOrSubCode;
msgbaseOpen = msgbase.is_open;
}
else if (typeof(pMsgbaseOrSubCode) == "string")
{
msgbase = new MsgBase(pMsgbaseOrSubCode);
msgbaseOpen = msgbase.open();
}
else
return retObj;
if (msgbaseOpen)
{
19181
19182
19183
19184
19185
19186
19187
19188
19189
19190
19191
19192
19193
19194
19195
19196
19197
19198
19199
19200
19201
19202
19203
19204
19205
19206
19207
19208
19209
19210
19211
19212
19213
19214
19215
19216
19217
19218
19219
19220
19221
19222
// Get the message header without expanded fields (we can't save it with
// expanded fields), then add the 'read' attribute and save it back to the messagebase.
var msgHdr = msgbase.get_msg_header(false, pMsgNum, false);
if (msgHdr != null)
{
msgHdr.attr |= pMsgAttrs;
retObj.saveSucceeded = msgbase.put_msg_header(false, pMsgNum, msgHdr);
if (retObj.saveSucceeded)
retObj.msgAttrs = msgHdr.attr;
else
{
writeToSysAndNodeLog("Failed to save message header with the following attributes: " + msgAttrsToString(pMsgAttrs), LOG_ERR);
writeToSysAndNodeLog(getMsgAreaDescStr(msgbase), LOG_ERR);
writeToSysAndNodeLog(format("Message offset: %d, number: %d", msgHdr.offset, msgHdr.number), LOG_ERR);
writeToSysAndNodeLog("Status: " + msgbase.status, LOG_ERR);
writeToSysAndNodeLog("Error: " + msgbase.error, LOG_ERR);
/*
// For sysops, output a debug message
if (gIsSysop)
{
console.print("\1n");
console.crlf();
console.print("* Failed to save msg header the with the following attributes: " + msgAttrsToString(pMsgAttrs));
console.crlf();
console.print("Status: " + msgbase.status);
console.crlf();
console.print("Error: " + msgbase.error);
console.crlf();
console.crlf();
//console.print("put_msg_header params: false, " + msgHdr.number + ", header:\r\n");
//console.print("put_msg_header params: true, " + msgHdr.offset + ", header:\r\n");
//console.print("put_msg_header params: " + msgHdr.number + ", header:\r\n");
printMsgHdr(msgHdr);
}
*/
}
}
// If a sub-board code was passed in, then close the messagebase object
// that we created here.
if (typeof(pMsgbaseOrSubCode) == "string")
msgbase.close();
}
return retObj;
}
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
19265
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
// Converts a message attributes bitfield to a string.
//
// Parameters:
// pMsgAttrs: A numeric type with message attribute bits
//
// Return value: A string containing a list of the message attributes
function msgAttrsToString(pMsgAttrs)
{
if (typeof(pMsgAttrs) != "number")
return "";
var attrsStr = "";
if ((pMsgAttrs & MSG_PRIVATE) == MSG_PRIVATE)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_PRIVATE";
}
if ((pMsgAttrs & MSG_READ) == MSG_READ)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_READ";
}
if ((pMsgAttrs & MSG_PERMANENT) == MSG_PERMANENT)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_PERMANENT";
}
if ((pMsgAttrs & MSG_LOCKED) == MSG_LOCKED)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_LOCKED";
}
if ((pMsgAttrs & MSG_DELETE) == MSG_DELETE)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_DELETE";
}
if ((pMsgAttrs & MSG_ANONYMOUS) == MSG_ANONYMOUS)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_ANONYMOUS";
}
if ((pMsgAttrs & MSG_KILLREAD) == MSG_KILLREAD)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_KILLREAD";
}
if ((pMsgAttrs & MSG_MODERATED) == MSG_MODERATED)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_MODERATED";
}
if ((pMsgAttrs & MSG_VALIDATED) == MSG_VALIDATED)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_VALIDATED";
}
if ((pMsgAttrs & MSG_REPLIED) == MSG_REPLIED)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_REPLIED";
}
if ((pMsgAttrs & MSG_NOREPLY) == MSG_NOREPLY)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_NOREPLY";
}
if ((pMsgAttrs & MSG_UPVOTE) == MSG_UPVOTE)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_UPVOTE";
}
if ((pMsgAttrs & MSG_DOWNVOTE) == MSG_DOWNVOTE)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_DOWNVOTE";
}
if ((pMsgAttrs & MSG_POLL) == MSG_POLL)
{
if (attrsStr.length > 0)
attrsStr += ", ";
attrsStr += "MSG_POLL";
}
return attrsStr;
}
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
19390
19391
19392
19393
19394
19395
19396
19397
19398
19399
19400
19401
19402
19403
19404
19405
19406
19407
19408
19409
19410
19411
19412
// Returns the index of the first Synchronet attribute code before a given index
// in a string.
//
// Parameters:
// pStr: The string to search in
// pIdx: The index to search back from
// pSeriesOfAttrs: Optional boolean - Whether or not to look for a series of
// attributes. Defaults to false (look for just one attribute).
// pOnlyInWord: Optional boolean - Whether or not to look only in the current word
// (with words separated by whitespace). Defaults to false.
//
// Return value: The index of the first Synchronet attribute code before the given
// index in the string, or -1 if there is none or if the parameters
// are invalid
function strIdxOfSyncAttrBefore(pStr, pIdx, pSeriesOfAttrs, pOnlyInWord)
{
if (typeof(pStr) != "string")
return -1;
if (typeof(pIdx) != "number")
return -1;
if ((pIdx < 0) || (pIdx >= pStr.length))
return -1;
var seriesOfAttrs = (typeof(pSeriesOfAttrs) == "boolean" ? pSeriesOfAttrs : false);
var onlyInWord = (typeof(pOnlyInWord) == "boolean" ? pOnlyInWord : false);
var attrCodeIdx = pStr.lastIndexOf("\1", pIdx-1);
if (attrCodeIdx > -1)
{
// If we are to only check the current word, then continue only if
// there isn't a space between the attribute code and the given index.
if (onlyInWord)
{
if (pStr.lastIndexOf(" ", pIdx-1) >= attrCodeIdx)
attrCodeIdx = -1;
}
}
if (attrCodeIdx > -1)
{
var syncAttrRegexWholeWord = /^\1[krgybmcw01234567hinpq,;\.dtl<>\[\]asz]$/i;
if (syncAttrRegexWholeWord.test(pStr.substr(attrCodeIdx, 2)))
{
if (seriesOfAttrs)
{
for (var i = attrCodeIdx - 2; i >= 0; i -= 2)
{
if (syncAttrRegexWholeWord.test(pStr.substr(i, 2)))
attrCodeIdx = i;
else
break;
}
}
}
else
attrCodeIdx = -1;
}
return attrCodeIdx;
}
// Returns a string with any Synchronet color/attribute codes found in a string
// before a given index.
//
// Parameters:
// pStr: The string to search in
// pIdx: The index in the string to search before
//
// Return value: A string containing any Synchronet attribute codes found before
// the given index in the given string
function getAttrsBeforeStrIdx(pStr, pIdx)
{
if (typeof(pStr) != "string")
return "";
if (typeof(pIdx) != "number")
return "";
if (pIdx < 0)
return "";
var idx = (pIdx < pStr.length ? pIdx : pStr.length-1);
var attrStartIdx = strIdxOfSyncAttrBefore(pStr, idx, true, false);
var attrEndIdx = strIdxOfSyncAttrBefore(pStr, idx, false, false); // Start of 2-character code
var attrsStr = "";
if ((attrStartIdx > -1) && (attrEndIdx > -1))
attrsStr = pStr.substring(attrStartIdx, attrEndIdx+2);
return attrsStr;
}
19413
19414
19415
19416
19417
19418
19419
19420
19421
19422
19423
19424
19425
19426
19427
19428
19429
19430
19431
19432
19433
19434
19435
19436
19437
19438
// 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);
}
}