static S myBotName;
static long botRoom = 1;
static new Matches m; // for matching lines
static int historyGrab = 10; // read last 10 lines from history
static new L<ChatLine> msgs;
static long lastSucked; // timestamp
static long suckDelay = 2000; // suck every X ms
static int maxLineLength = 1024; // should match groupchat.json.botsay.php
static boolean loop_firstTime = true;
static int loopDelay = 5000;
static boolean debug_printIncoming;
static O externalSucker, externalPoster;
static TestRoom testRoom; // Set for testing
static class TestRoom {
long roomID;
new L<ChatLine> msgs;
new L<S> presences;
void post(S name, S text) {
testPost(name, text, true);
}
void testPost(S name, S text, boolean isBot) {
new ChatLine line;
line.room = roomID;
line.id = l(msgs)+1;
line.who = name;
line.text = text;
line.isBot = isBot;
msgs.add(line);
}
}
static void testMode() {
testMode(1);
}
static synchronized void testMode(long roomID) {
testRoom = new TestRoom;
testRoom.roomID = roomID;
}
static void enterRoom(long roomID) {
if (testRoom != null) ret; // Do nothing on testing
botRoom = roomID; // TODO: presence?
lastSucked = 0;
msgs = new L;
}
static void changeName(S name) {
myBotName = unnull(name);
}
static S botifyName(S name) {
name = unnull(name);
if (!name.endsWith("bot"))
name += " Bot";
ret name;
}
static S getMyName() {
S name = myBotName;
if (empty(name))
name = getProgramName();
ret botifyName(name);
}
static synchronized void say(S text) {
text = cleanLine(text);
S name = getMyName();
print(">> " + (testRoom != null ? "TEST" : "") + " " + roomNr() + " > " + name + " > " + text);
if (testRoom != null)
testRoom.post(name, text);
else if (externalPoster != null)
call(externalPoster, "say", name, text, mc());
else
sayInWebChatRoom(name, text, botRoom);
}
// should match server's line processing - so we can recognize
// our own lines
static S cleanLine(S line) {
line = unnull(line);
if (l(line) > maxLineLength) {
print("Warning: Cutting line from " + l(line) + " to " + maxLineLength + " chars.");
line = substring(line, 0, maxLineLength);
}
ret line.trim();
}
static void suckChat() {
if (testRoom != null) {
addMsgs(subList(testRoom.msgs, l(msgs)));
ret;
}
ChatLine last = last(msgs);
long lastID = last == null ? 0 : last.id;
if (externalSucker != null) {
addMsgs((L) quickImport(call(externalSucker, "getNewMessages", lastID)));
ret;
}
if (now() < lastSucked + suckDelay) ret;
try {
L<ChatLine> newMsgs = suckWebChatRoom(getMyName(), botRoom, lastID, lastID == 0 ? historyGrab : 1000);
addMsgs(newMsgs);
} finally {
lastSucked = now();
}
}
static void addMsgs(L<ChatLine> l) {
if (l == null) ret;
if (debug_printIncoming)
for (ChatLine line : l)
print("INCOMING: " + line.who + " > " + line.text);
for (ChatLine line : l) {
hackfixUmlauts(line);
msgs.add(line);
}
}
// ISO to UTF-8 (lines coming from chat) - broken I think
static void hackfixUmlauts(ChatLine line) {
/*
S s = line.text;
new StringBuilder buf;
for (int i = 0; i < l(s); i++) {
int c = (int) s.charAt(i);
if (c == 252) c = 195; // ü
buf.append((char) c);
}
line.text = str(buf);
*/
}
static class MsgMarker {
long room, idSeen;
void advance(ChatLine line) {
if (line == null) ret;
idSeen = max(idSeen, line.id);
}
void setRoom(long roomID) {
if (room != roomID) {
room = roomID;
idSeen = 0;
}
}
}
static L<ChatLine> msgsFrom(MsgMarker marker) {
marker.setRoom(botRoom);
ret msgsFrom(marker.idSeen);
}
static synchronized L<ChatLine> msgsFrom(long idSeen) {
int i = l(msgs);
while (i > 0 && msgs.get(i-1).id > idSeen)
--i;
L<ChatLine> l = subList(msgs, i);
ret l;
}
static class WordDropper extends S2S {
Set wordSet;
*(S words) {
wordSet = dropWords_preprocess(words);
}
S get(S s) {
ret dropWords_impl(s, wordSet);
}
}
static S getWordDropper_c1;
static S2S getWordDropper_c2;
static S2S getWordDropper(S wordsToDrop) {
if (neq(getWordDropper_c1, wordsToDrop)) {
getWordDropper_c1 = wordsToDrop;
getWordDropper_c2 = new WordDropper(wordsToDrop);
}
ret getWordDropper_c2;
}
static new MsgMarker matchQuestion_seen;
static ChatLine matchQuestion_msg;
static boolean matchQuestion_dropping(S pat, S wordsToDrop) {
ret matchQuestion(pat, getWordDropper(wordsToDrop));
}
static boolean matchQuestion(S pat) {
ret matchQuestion(pat, null);
}
static boolean matchQuestion(S pat, S2S preprocessor) {
suckChat();
matchQuestion_msg = null;
for (ChatLine line : msgsFrom(matchQuestion_seen)) {
matchQuestion_seen.advance(line);
S text = preprocess(line.text, preprocessor);
if (debug_printIncoming)
print("matchQuestion " + quote(text));
if (match(pat, text, m)) {
matchQuestion_msg = line;
ret true;
}
}
ret false;
}
static S whoAsks() {
ret matchQuestion_msg.who;
}
static boolean haveAnswered(MsgMarker marker, S answer) {
S myName = getMyName();
for (ChatLine line : msgsFrom(marker))
if (eq(line.who, myName) && eq(line.text, answer))
ret true;
ret false;
}
static void answerQuestion(S answer) {
if (haveAnswered(matchQuestion_seen, answer))
print("Have answered already :)");
else
say(answer);
}
static long roomNr() {
ret botRoom;
}
static S roomNrString() {
ret str(botRoom);
}
static boolean loop() {
if (!licensed()) ret false;
if (loop_firstTime)
loop_firstTime = false;
else if (testRoom != null)
ret false;
else
sleep(loopDelay);
ret true;
}
static synchronized void testPost(S name, S text, boolean isUser) {
if (testRoom != null)
testRoom.testPost(name, text, !isUser);
}
static void userPost(S text) {
testPost("User", text, true);
}
// for test mode - get my responses
static synchronized L<S> getResponses() {
new L<S> l;
if (testRoom == null) ret l;
S name = getMyName();
for (ChatLine line : testRoom.msgs) {
if (eq(line.who, name) && line.isBot)
l.add(line.text);
}
ret l;
}
// string-to-string function
static abstract class S2S {
abstract S get(S s);
}
static S preprocess(S text, S2S preprocessor) {
pcall {
if (preprocessor != null)
text = preprocessor.get(text);
}
ret text;
}
static void printIncoming() {
debug_printIncoming = true;
}
static synchronized L<S> getPresentNicks() {
if (testRoom != null)
ret cloneList(testRoom.presences);
// TODO: cache this for a bit?
ret getWebChatPresences(roomNr());
}download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
| Snippet ID: | #1002900 |
| Snippet name: | Web Chat API (include) |
| Eternal ID of this version: | #1002900/1 |
| Text MD5: | 87ea57b865b1153f4656e245c7d75fee |
| Author: | stefan |
| Category: | javax |
| Type: | JavaX fragment (include) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2016-04-05 23:32:20 |
| Source code size: | 6970 bytes / 303 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 1197 / 1987 |
| Referenced in: | [show references] |