forked from cory/tildefriends
sandboxos => tildefriends
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3157 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
315
packages/cory/bbs/bbs.js
Normal file
315
packages/cory/bbs/bbs.js
Normal file
@ -0,0 +1,315 @@
|
||||
"use strict";
|
||||
var gOnInput = null;
|
||||
|
||||
var kMaxHistory = 20;
|
||||
var kShowHistory = 20;
|
||||
|
||||
var lastTimestamp = null;
|
||||
|
||||
if (imports.terminal) {
|
||||
core.register("onMessage", function(sender, message) {
|
||||
if (message.message && message.when) {
|
||||
printMessage(message, true);
|
||||
}
|
||||
});
|
||||
core.register("onSessionBegin", function(user) {
|
||||
if (user.packageName === core.user.packageName &&
|
||||
user.index !== core.user.index) {
|
||||
listUsers(user.name + " has joined the BBS. ");
|
||||
}
|
||||
});
|
||||
core.register("onSessionEnd", function(user) {
|
||||
if (user.packageName === core.user.packageName &&
|
||||
user.index !== core.user.index) {
|
||||
listUsers(user.name + " has left the BBS. ");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Chat service process.
|
||||
core.register("onMessage", function(sender, message) {
|
||||
if (message.message && message.when) {
|
||||
message.sender = sender;
|
||||
return database.get("board").catch(function() {
|
||||
return null;
|
||||
}).then(function(data) {
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch(error) {
|
||||
data = [];
|
||||
}
|
||||
data.push(message);
|
||||
while (data.length > kMaxHistory) {
|
||||
data.shift();
|
||||
}
|
||||
return saveBoard(data);
|
||||
}).then(function() {
|
||||
return core.broadcast(message);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function listUsers() {
|
||||
return core.getUsers(core.user.packageOwner, core.user.packageName).then(function(users) {
|
||||
terminal.select("users");
|
||||
terminal.clear();
|
||||
terminal.print("Users:");
|
||||
var counts = {};
|
||||
for (var i = 0; i < users.length; i++) {
|
||||
counts[users[i].name] = (counts[users[i].name] || 0) + 1;
|
||||
}
|
||||
var names = Object.keys(counts).sort();
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
var name = names[i];
|
||||
var message = [];
|
||||
if (message.length > 1) {
|
||||
message.push(", ");
|
||||
}
|
||||
message.push({class: "orange", value: name});
|
||||
if (counts[name] > 1) {
|
||||
message.push({class: "base01", value: "(x" + counts[name] + ")"});
|
||||
}
|
||||
terminal.print(message);
|
||||
}
|
||||
terminal.select("terminal");
|
||||
});
|
||||
}
|
||||
|
||||
function saveBoard(data) {
|
||||
return database.set("board", JSON.stringify(data)).catch(function(error) {
|
||||
if (error.message.indexOf("MDB_MAP_FULL") != -1) {
|
||||
data.shift();
|
||||
return saveBoard(data);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
core.register("onInput", function(input) {
|
||||
if (gOnInput && typeof input == "string") {
|
||||
gOnInput(input);
|
||||
}
|
||||
});
|
||||
|
||||
function logo() {
|
||||
terminal.clear();
|
||||
terminal.print("");
|
||||
terminal.print("");
|
||||
terminal.print('Welcome to');
|
||||
terminal.print(' ______ _ ____ ____ _____');
|
||||
terminal.print(' / ____/___ _______ _( )_____ / __ )/ __ ) ___/');
|
||||
terminal.print(' / / / __ \\/ ___/ / / /// ___/ / __ / __ \\__ \\ ');
|
||||
terminal.print('/ /___/ /_/ / / / /_/ / (__ ) / /_/ / /_/ /__/ / ');
|
||||
terminal.print('\\____/\\____/_/ \\__, / /____/ /_____/_____/____/ ');
|
||||
terminal.print(' /____/ ');
|
||||
terminal.print(' yesterday\'s technology...today!');
|
||||
terminal.print("");
|
||||
}
|
||||
|
||||
function welcome() {
|
||||
logo();
|
||||
chat();
|
||||
}
|
||||
|
||||
function main() {
|
||||
terminal.clear();
|
||||
logo();
|
||||
terminal.print("");
|
||||
terminal.print("Main menu commands:");
|
||||
terminal.print(" ", {command: "chat"}, " chat message board");
|
||||
terminal.print(" ", {command: "guess"}, " guess the number game");
|
||||
terminal.print(" ", {command: "exit"}, " back to that sweet logo");
|
||||
gOnInput = function(input) {
|
||||
input = input.toLowerCase();
|
||||
if (input == "chat") {
|
||||
chat();
|
||||
} else if (input == "guess") {
|
||||
guess();
|
||||
} else if (input == "exit") {
|
||||
terminal.print("Goodbye.");
|
||||
exit(0);
|
||||
} else {
|
||||
terminal.print("I didn't understand that: " + input);
|
||||
main();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function formatMessage(message) {
|
||||
var result;
|
||||
if (typeof message == "string") {
|
||||
result = [];
|
||||
var regex = /(\w+:\/*\S+?)(?=(?:[\.!?])?(?:$|\s))/gi;
|
||||
var match;
|
||||
var lastIndex = 0;
|
||||
while ((match = regex.exec(message)) !== null) {
|
||||
result.push({class: "base1", value: message.substring(lastIndex, match.index)});
|
||||
result.push({href: match[0]});
|
||||
lastIndex = regex.lastIndex;
|
||||
}
|
||||
result.push({class: "base1", value: message.substring(lastIndex)});
|
||||
} else {
|
||||
result = message;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function niceTime(lastTime, thisTime) {
|
||||
if (!lastTime) {
|
||||
return thisTime;
|
||||
}
|
||||
let result = [];
|
||||
let lastParts = lastTime.split(" ");
|
||||
let thisParts = thisTime.split(" ");
|
||||
for (let i = 0; i < thisParts.length; i++) {
|
||||
if (thisParts[i] !== lastParts[i]) {
|
||||
result.push(thisParts[i]);
|
||||
}
|
||||
}
|
||||
return result.join(" ");
|
||||
}
|
||||
|
||||
function printMessage(message, notify) {
|
||||
terminal.print(
|
||||
{class: "base0", value: niceTime(lastTimestamp, message.when)},
|
||||
" ",
|
||||
{class: "base00", value: "<"},
|
||||
{class: "base3", value: (message.sender ? message.sender.name : "unknown")},
|
||||
{class: "base00", value: ">"},
|
||||
" ",
|
||||
formatMessage(message.message));
|
||||
lastTimestamp = message.when;
|
||||
if (notify) {
|
||||
return core.getUser().then(function(user) {
|
||||
if (message.message.indexOf("!") != -1) {
|
||||
return terminal.notify("SOMEONE IS SHOUTING!", {body: "<" + (message.sender ? message.sender.name : "unknown") + "> " + message.message});
|
||||
} else if (message.message.indexOf(user.name + ":") != -1) {
|
||||
return terminal.notify("Someone is talking at you.", {body: "<" + (message.sender ? message.sender.name : "unknown") + "> " + message.message});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function chat() {
|
||||
terminal.setEcho(false);
|
||||
terminal.print("");
|
||||
terminal.print("You are now in a chat. Anything you type will be broadcast to everyone else connected. To leave, say ", {command: "exit"}, ".");
|
||||
listUsers();
|
||||
database.get("board").catch(function() {
|
||||
return null;
|
||||
}).then(function(board) {
|
||||
try {
|
||||
board = JSON.parse(board);
|
||||
} catch (error) {
|
||||
board = [];
|
||||
}
|
||||
|
||||
for (let i = Math.max(0, board.length - kShowHistory); i < board.length; i++) {
|
||||
printMessage(board[i], false);
|
||||
}
|
||||
});
|
||||
gOnInput = function(input) {
|
||||
if (input == "exit") {
|
||||
terminal.setEcho(true);
|
||||
main();
|
||||
} else {
|
||||
core.getService("chat").then(function(chatService) {
|
||||
return chatService.postMessage({when: new Date().toString(), message: input});
|
||||
}).catch(function(error) {
|
||||
terminal.print("ERROR: " + JSON.stringify(error));
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function guess() {
|
||||
terminal.clear();
|
||||
var number = Math.round(Math.random() * 100);
|
||||
var guesses = 0;
|
||||
terminal.print("OK, I have a number in mind. What do you think it is? Use ", {command: "exit"}, " to stop.");
|
||||
gOnInput = function(input) {
|
||||
if (input == "exit") {
|
||||
main();
|
||||
} else {
|
||||
var guess = parseInt(input);
|
||||
guesses++;
|
||||
if (input != guess.toString()) {
|
||||
terminal.print("I'm not sure that's an integer. Please guess only integers.");
|
||||
} else {
|
||||
if (guess < number) {
|
||||
terminal.print("Too low.");
|
||||
} else if (guess > number) {
|
||||
terminal.print("Too high.");
|
||||
} else if (guess == number) {
|
||||
terminal.print("Wow, you got it in " + guesses + " guesses! It was " + number + ".");
|
||||
guessEnd(guesses);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function guessEnd(guesses) {
|
||||
terminal.print("What's your name, for the high score table?");
|
||||
gOnInput = function(name) {
|
||||
var entry = {'guesses': guesses, 'name': name, 'when': new Date().toString()};
|
||||
database.get("guessHighScores").then(function(data) {
|
||||
data = JSON.parse(data);
|
||||
var index = data.length;
|
||||
for (var i in data) {
|
||||
if (guesses < data[i].guesses) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
data.splice(index, 0, entry);
|
||||
printHighScores(data);
|
||||
database.set("guessHighScores", JSON.stringify(data));
|
||||
gOnInput = function() {
|
||||
main();
|
||||
};
|
||||
}).catch(function() {
|
||||
var data = [entry];
|
||||
printHighScores(data);
|
||||
database.set("guessHighScores", JSON.stringify(data));
|
||||
main();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function printTable(data) {
|
||||
var widths = [];
|
||||
for (var i in data) {
|
||||
var row = data[i];
|
||||
for (var c in row) {
|
||||
widths[c] = Math.max(widths[c] || 0, row[c].length);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i in data) {
|
||||
var row = data[i];
|
||||
var line = "";
|
||||
for (var c in row) {
|
||||
line += row[c];
|
||||
line += " ".repeat(widths[c] - row[c].length + 2);
|
||||
}
|
||||
terminal.print(line);
|
||||
}
|
||||
}
|
||||
|
||||
function printHighScores(data) {
|
||||
printTable([["Name", "Guesses", "Date"]].concat(data.map(function(entry) {
|
||||
return [entry.name, entry.guesses.toString(), entry.when];
|
||||
})));
|
||||
}
|
||||
|
||||
if (imports.terminal) {
|
||||
terminal.split([
|
||||
{type: "horizontal", children: [
|
||||
{name: "terminal", grow: 1},
|
||||
{name: "users", grow: 0},
|
||||
]},
|
||||
]);
|
||||
welcome();
|
||||
}
|
Reference in New Issue
Block a user