[mw-devel] [Git][arthur/mw][master] Add mw_logon, mw_logoff, talker_join and talker_leave mwjs events
Andrew Price
welshbyte at sucs.org
Sat Nov 3 15:08:09 GMT 2018
Andrew Price pushed to branch master at Justin Mitchell / mw
Commits:
ccde2b85 by Andrew Price at 2018-11-03T15:06:09+00:00
Add mw_logon, mw_logoff, talker_join and talker_leave mwjs events
Required a lot of IPC_CHECKONOFF-related changes and tidy-ups.
New js events handled like so:
function handler(ev)
{
switch(ev.type) {
case "mw_logon":
d = ev.data;
mw.print("d.user: " + d.user);
mw.print("d.quiet: " + d.quiet);
mw.print("d.autochat: " + d.autochat);
break;
case "mw_logoff":
d = ev.data;
mw.print("d.user: " + d.user);
mw.print("d.method: " + d.method);
mw.print("d.quiet: " + d.quiet);
mw.print("d.reason: " + d.reason);
mw.print("d.agent: " + d.agent);
break;
case "talker_join":
d = ev.data;
mw.print("d.user: " + d.user);
mw.print("d.method: " + d.method);
mw.print("d.quiet: " + d.quiet);
mw.print("d.channel: " + d.channel);
mw.print("d.agent: " + d.agent);
break;
case "talker_leave":
d = ev.data;
mw.print("d.user: " + d.user);
mw.print("d.method: " + d.method);
mw.print("d.quiet: " + d.quiet);
mw.print("d.channel: " + d.channel);
mw.print("d.agent: " + d.agent);
mw.print("d.message: " + d.message);
break;
}
}
mw.onevent.push(handler);
See src/server/PROTOCOL and src/onoff.h for hints on what those fields
are.
- - - - -
12 changed files:
- src/client/event.h
- src/client/incoming.c
- src/client/js-duk.c
- src/client/main.c
- src/client/main.h
- src/client/newmain.c
- + src/client/onoff.c
- + src/client/onoff.h
- src/client/script_inst.c
- src/client/talker.c
- + src/onoff.h
- src/server/PROTOCOL
Changes:
=====================================
src/client/event.h
=====================================
--- a/src/client/event.h
+++ b/src/client/event.h
@@ -6,12 +6,14 @@
typedef enum {
MWEV_TYPE_NONE = 0,
MWEV_TYPE_MSG,
+ MWEV_TYPE_ONOFF,
} mwev_type_t;
struct mwevent {
mwev_type_t ev_type;
union {
- ipc_message_t *msg; /* MWEV_TYPE_MSG */
+ ipc_message_t *msg; /* MWEV_TYPE_MSG */
+ ipc_message_t *onoff; /* MWEV_TYPE_ONOFF */
} ev_data;
};
=====================================
src/client/incoming.c
=====================================
--- a/src/client/incoming.c
+++ b/src/client/incoming.c
@@ -31,6 +31,7 @@
#include "gaglist.h"
#include "js.h"
#include "event.h"
+#include "onoff.h"
#include <jansson.h>
#include <str_util.h>
@@ -50,14 +51,13 @@ static void force_text(ipc_message_t *msg, const char *text, const char *from);
static void force_vtext(ipc_message_t *msg, const char *from, const char *format, ...) __attribute__((format (printf, 3, 4)));
static void force_ipc(char *text, char *from);
static void force_rpc(char *text, char *from);
-static void force_checkonoff(char *text, char *from);
static void force_wiz(ipc_message_t *msg, char *text, char *from);
-static void force_chatmode(char *text, unsigned long theirprivs, const char *from);
+static void force_chatmode(char *text, struct user *usr);
static void force_status(char *text, char *from);
static void force_channel(char *text, char *from, unsigned long theirprivs);
static void force_kick(char *text, char *from, unsigned long theirprivs);
static void force_gag(char *text, unsigned long theirprivs, const char *from);
-static void zod(char *from, char *msg);
+static void zod(const char *from, const char *msg);
static void mrod(char *from, char *msg);
static void force_newmail(void);
static void force_protlevel(char *text, unsigned long theirprivs, const char *from);
@@ -176,11 +176,37 @@ void DisplayStack(void)
}
case EST_CHECKONOFF:
{
- char *aargs[6];
- char *backup;
- char *onoff_name, *sep, *head, *head2;
- char *uname, *reason = NULL;
- int ccode, method, isquiet;
+ struct {
+ char ccode[13];
+ char type[13];
+ char quiet[3];
+ char name[NAMESIZE + 1];
+ char version[3];
+ char reason[MAXTEXTLENGTH];
+ } a;
+ char *aargs[6] = {
+ a.ccode,
+ a.type,
+ a.quiet,
+ a.name,
+ a.version,
+ a.reason
+ };
+ int action_to_ccode[] = {
+ [ONOFF_LOGON] = 3,
+ [ONOFF_LOGOFF] = 2,
+ [ONOFF_JOIN] = 1,
+ [ONOFF_LEAVE] = 0,
+ };
+ char *onoff_name;
+ const char *uname, *reason;
+ int ccode, isquiet, action, type;
+ struct mwevent ev = {
+ .ev_type = MWEV_TYPE_ONOFF,
+ .ev_data.onoff = new->msg,
+ };
+ script_output = 1;
+ js_handle_event(&ev);
/* go through list and find checkonoff function */
onoff_name = NULL;
@@ -189,209 +215,75 @@ void DisplayStack(void)
/* if no function found, skip everything else */
if (onoff_name == NULL) break;
- /* backup the input text */
- backup = strdup(new->text);
-
- /* get the first comma in the checkonoff code */
- sep = strchr(new->text, ',');
-
- /* if this comma does not exist, use the original version of checkonoff */
- if (sep == NULL)
- {
- /* simply convert to a number */
- ccode = atoi(new->text);
-
- /* due to backwards compatibility issues, we can only use 0 or 1 */
- if (ccode < 0) { free(backup); break; }
- if (ccode > 1) { free(backup); break; }
-
- /* create memory for argument strings */
- aargs[0] = malloc(sizeof(char) * 13);
- aargs[1] = malloc(sizeof(char) * 13);
- aargs[2] = malloc(sizeof(char) * 3);
- aargs[3] = malloc(sizeof(char) * NAMESIZE + 1);
- aargs[4] = malloc(sizeof(char) * 3);
- aargs[5] = malloc(sizeof(char) * MAXTEXTLENGTH);
-
- /* set up the argument strings */
- snprintf(aargs[0], 12, "%d", ccode);
- aargs[1][0] = 0;
- aargs[2][0] = 0;
- aargs[3][0] = 0;
- snprintf(aargs[4], 2, "1");
- aargs[5][0] = 0;
-
- /* run the event */
- ExecEvent2(onoff_name, "CheckOnOff", new->from, 0, 6, aargs);
-
- /* free memory and break out */
- free(backup);
- free(aargs[0]);
- free(aargs[1]);
- free(aargs[2]);
- free(aargs[3]);
- free(aargs[4]);
- free(aargs[5]);
- break;
- }
-
- /* set head to the character after the comma, and terminate the code before the comma */
- head = sep + 1;
- *sep = 0;
-
- /* get the checkonoff code number */
- ccode = atoi(new->text);
-
- /* get the next comma in the checkonoff code */
- sep = strchr(head, ',');
- /* if no comma found, then this must be an interim checkonoff */
- if (sep == NULL)
- {
- /* due to backwards compatibility issues, we can only use 0 or 1 */
- if (ccode < 0) { free(backup); break; }
- if (ccode > 1) { free(backup); break; }
-
- /* simply convert the next argument to a number */
- isquiet = atoi(head);
-
- /* create memory for argument strings */
- aargs[0] = malloc(sizeof(char) * 13);
- aargs[1] = malloc(sizeof(char) * 13);
- aargs[2] = malloc(sizeof(char) * 3);
- aargs[3] = malloc(sizeof(char) * NAMESIZE + 1);
- aargs[4] = malloc(sizeof(char) * 3);
- aargs[5] = malloc(sizeof(char) * MAXTEXTLENGTH);
-
- /* set up the argument strings */
- snprintf(aargs[0], 12, "%d", ccode);
- aargs[1][0] = 0;
- snprintf(aargs[2], 2, "%d", isquiet);
- aargs[3][0] = 0;
- snprintf(aargs[4], 2, "2");
- aargs[5][0] = 0;
-
- /* run the event */
- ExecEvent2(onoff_name, "CheckOnOff", new->from, 0, 6, aargs);
-
- /* free memory and break out */
- free(backup);
- free(aargs[0]);
- free(aargs[1]);
- free(aargs[2]);
- free(aargs[3]);
- free(aargs[4]);
- free(aargs[5]);
- break;
- }
-
- /* set second text head to the character after the comma, and terminate the method before the comma */
- head2 = sep + 1;
- *sep = 0;
-
- /* get the checkonoff method number */
- method = atoi(head);
-
- /* get the next comma in the checkonoff code */
- sep = strchr(head2, ',');
- /* if no comma found, then this must be broken! */
- if (sep == NULL)
- {
- printf("Invalid checkonoff broadcast received! (%s)\n", backup);
- free(backup);
+ json_t *j = ipcmsg_json_decode(new->msg);
+ uname = json_getstring(j, "user");
+ action = json_getint(j, "action");
+ type = json_getint(j, "type");
+ isquiet = json_is_true(json_object_get(j, "quiet"));
+ if (action == ONOFF_LOGOFF)
+ reason = json_getstring(j, "reason");
+ else
+ reason = json_getstring(j, "message");
+
+ if (action >= ONOFF_SIZE)
break;
- }
-
- /* set uname to the character after the comma, and terminate the method before the comma */
- uname = sep + 1;
- *sep = 0;
-
- /* get the checkonoff quiet flagr */
- isquiet = atoi(head2);
- /* get the optional next comma in the checkonoff code */
- sep = strchr(uname, ',');
- /* if comma is found, then the reason is there */
- if (sep != NULL)
- {
- reason = sep + 1;
- *sep = 0;
- }
+ ccode = action_to_ccode[action];
/* limit the method information */
- switch (ccode)
- {
- /* leave the talker */
- case 0:
- if (!cp_test(user, CP_CANZOD) && (method == 1))
+ switch (action) {
+ case ONOFF_LEAVE:
+ if (!cp_test(user, CP_CANZOD) && (type == LEAVE_ZOD))
{
- method = 0;
+ type = 0;
uname = new->from;
}
- if (!u_god(user) && (method == 2))
+ if (!u_god(user) && (type == LEAVE_FORCED))
{
- method = 0;
+ type = 0;
uname = new->from;
}
break;
- /* enter the talker */
- case 1:
- if (!cp_test(user, CP_SUMMON) && (method == 1))
+ case ONOFF_JOIN:
+ if (!cp_test(user, CP_SUMMON) && (type == JOIN_SUMMONED))
{
- method = 0;
+ type = 0;
uname = new->from;
}
- if (!u_god(user) && (method == 2))
+ if (!u_god(user) && (type == JOIN_FORCED))
{
- method = 0;
+ type = 0;
uname = new->from;
}
break;
- /* leave the board */
- case 2:
- if (!cp_test(user, CP_CANMROD) && (method == 3))
+ case ONOFF_LOGOFF:
+ if (!cp_test(user, CP_CANMROD) && (type == LOGOFF_MROD))
{
- method = 0;
+ type = 0;
uname = new->from;
}
- if (!u_god(user) && ((method == 4) || (method == 5) || (method == 6)))
+ if (!u_god(user) && (
+ (type == LOGOFF_BANNED) ||
+ (type == LOGOFF_ERROR) ||
+ (type == LOGOFF_DELETED)))
{
- method = 0;
+ type = 0;
uname = new->from;
}
break;
- /* enter the board */
- case 3:
+ case ONOFF_LOGON:
break;
}
-
- /* create memory for argument strings */
- aargs[0] = malloc(sizeof(char) * 13);
- aargs[1] = malloc(sizeof(char) * 13);
- aargs[2] = malloc(sizeof(char) * 3);
- aargs[3] = malloc(sizeof(char) * NAMESIZE + 1);
- aargs[4] = malloc(sizeof(char) * 3);
- aargs[5] = malloc(sizeof(char) * MAXTEXTLENGTH);
-
/* set up the argument strings */
- snprintf(aargs[0], 12, "%d", ccode);
- snprintf(aargs[1], 12, "%d", method);
- snprintf(aargs[2], 2, "%d", isquiet);
- snprintf(aargs[3], NAMESIZE, "%s", uname);
- snprintf(aargs[4], 2, "3");
- if (reason) snprintf(aargs[5], MAXTEXTLENGTH - 1, "%s", reason);
- else aargs[5][0] = 0;
-
- /* display the broadcast message */
+ memset(&a, 0, sizeof(a));
+ snprintf(a.ccode, 12, "%d", ccode);
+ snprintf(a.type, 12, "%d", type);
+ snprintf(a.quiet, 2, "%d", isquiet ? 1 : 0);
+ snprintf(a.name, NAMESIZE, "%s", uname);
+ a.version[0] = '3';
+ if (reason != NULL)
+ snprintf(a.reason, MAXTEXTLENGTH - 1, "%s", reason);
ExecEvent2(onoff_name, "CheckOnOff", new->from, 0, 6, aargs);
-
- /* free up the memory used */
- free(aargs[0]);
- free(aargs[1]);
- free(aargs[2]);
- free(aargs[3]);
- free(aargs[4]);
- free(aargs[5]);
- free(backup);
break;
}
default:
@@ -477,7 +369,7 @@ static void handle_ipc_error(ipc_message_t *msg)
printf("Undefined server error '%s'\n", type);
}
json_decref(j);
- close_down(0, NULL, NULL);
+ close_down(LOGOFF_NORMAL, NULL, NULL);
}
static void display_error(ipc_message_t *msg)
@@ -659,12 +551,20 @@ static void display_content(ipc_message_t *msg)
json_array_foreach(j, i, jgag) {
gaglist_append(json_string_value(jgag));
}
+ } else
+ if (msg->head.type == IPC_CHECKONOFF && cp_test(user, CP_SCRIPT)) {
+ struct mstack *ms;
+
+ ms = calloc(1, sizeof(*ms));
+ ms->flags = MST_SCREV;
+ ms->preamble = EST_CHECKONOFF;
+ ms->from = strdup(whom);
+ InsertMesg(ms, msg);
} else {
printf("Unknown message type %4.4s", (char *)&msg->head.type);
}
json_decref(j);
-
}
static void accept_pipe_cmd(ipc_message_t *msg, struct user *mesg_user)
@@ -703,7 +603,7 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct user *mesg_user)
user->record.chatprivs = cp_setbycode(user->record.chatprivs, newbuff);
break;
case IPC_CHATMODE:
- force_chatmode(newbuff, mesg_user->record.chatprivs, mesg_user->record.name);
+ force_chatmode(newbuff, mesg_user);
break;
case IPC_GAG:
force_gag(newbuff, mesg_user->record.chatprivs, mesg_user->record.name);
@@ -738,7 +638,7 @@ static void accept_pipe_cmd(ipc_message_t *msg, struct user *mesg_user)
force_rpc(newbuff, mesg_user->record.name);
break;
case IPC_CHECKONOFF:
- force_checkonoff(newbuff, mesg_user->record.name);
+ display_content(msg);
break;
case IPC_WIZ:
force_wiz(msg, newbuff, mesg_user->record.name);
@@ -862,14 +762,6 @@ static void force_wiz(ipc_message_t *msg, char *newbuff, char *from)
InsertMesg(mesg, msg);
}
-static void force_checkonoff(char *text, char *from)
-{
- if (cp_test(user, CP_SCRIPT))
- {
- StackEvent(text, from, EST_CHECKONOFF);
- }
-}
-
static void force_ipc(char *text, char *from)
{
if (cp_test(user, CP_SCRIPT))
@@ -893,39 +785,35 @@ static void force_status(char *newbuff, char *from)
if (u_ban(user))
{
printf(_("\n\n--> You appear to have been banned. Goodbye... <--\r\n"));
- close_down(4, from, NULL);
+ close_down(LOGOFF_BANNED, from, NULL);
}
/* we have received a +D status change */
if (u_del(user))
{
printf(_("\n\n--> You appear to have been DELETED. Goodbye... <--\r\n"));
- close_down(6, from, NULL);
+ close_down(LOGOFF_DELETED, from, NULL);
}
}
-static void force_chatmode(char *newbuff, unsigned long theirprivs, const char *from)
+static void force_chatmode(char *newbuff, struct user *usr)
{
- unsigned long mm;
- int ourapl = (user->record.chatprivs & CP_PROTMASK) >> CP_PROTSHIFT;
- int theirapl = (theirprivs & CP_PROTMASK) >> CP_PROTSHIFT;
- int oldchat;
+ unsigned long mm;
+ int ourapl = (user->record.chatprivs & CP_PROTMASK) >> CP_PROTSHIFT;
+ int theirapl = (usr->record.chatprivs & CP_PROTMASK) >> CP_PROTSHIFT;
+ int oldchat;
- if (!(theirprivs & CP_PROTECT)) theirapl = 0;
+ if (!(usr->record.chatprivs & CP_PROTECT)) theirapl = 0;
oldchat = cm_test(user, CM_ONCHAT);
mm=cm_setbycode(user->record.chatmode, newbuff);
- user->record.chatmode=chatmode_describe(user->record.chatmode, mm, ourapl, theirapl, from);
+ user->record.chatmode = chatmode_describe(user->record.chatmode, mm, ourapl, theirapl, NULL);
if (!cm_test(user, CM_ONCHAT) && oldchat)
- {
- /* announce leaving talker */
- broadcast_onoffcode(0, 2, from, NULL);
- }
+ announce_leave(user->record.name, user->record.room, LEAVE_FORCED,
+ usr->record.name, NULL, quietmode);
else if (cm_test(user, CM_ONCHAT) && !oldchat)
- {
- /* announce joining the talker */
- broadcast_onoffcode(1, 2, from, NULL);
- }
+ announce_join(user->record.name, user->record.room, JOIN_FORCED,
+ usr->record.name, quietmode);
disable_rl(1);
}
@@ -1014,10 +902,7 @@ static void force_channel(char *newbuff, char *from, unsigned long theirprivs)
/* run common talker entrance code with logon type set to 'summon' */
enter_talker(2);
-
- /* give an entrance broadcast */
- broadcast_onoffcode(1, 1, from, NULL);
-
+ announce_join(user->record.name, user->record.room, JOIN_SUMMONED, from, quietmode);
enter_room(newroom);
}
}else
@@ -1076,18 +961,15 @@ static void force_kick(char *newbuff, char *from, unsigned long theirprivs)
}
}
-static void zod(char *from, char *msg)
+static void zod(const char *from, const char *msg)
{
char text[MAXTEXTLENGTH];
/* remove from talker */
user->record.chatmode = cm_clear(user, CM_ONCHAT);
- /* force update of user */
update_user(user);
-
- /* announce leaving talker via zod */
- broadcast_onoffcode(0, 1, from, msg);
+ announce_leave(user->record.name, user->record.room, LEAVE_ZOD, from, msg, quietmode);
/* put standard message to screen */
snprintf(text, MAXTEXTLENGTH-1, _("\nBoing, Zebedee arrived. \"%s\033--\", said Zebedee\n"), (msg!=NULL)?msg:_("Time for bed"));
@@ -1129,5 +1011,5 @@ static void mrod(char *from, char *msg)
mrod_user = malloc(sizeof(char) * (strlen(from) + 1));
strcpy(mrod_user, from);
- close_down(3, from, msg);
+ close_down(LOGOFF_MROD, from, msg);
}
=====================================
src/client/js-duk.c
=====================================
--- a/src/client/js-duk.c
+++ b/src/client/js-duk.c
@@ -23,6 +23,7 @@
#include "iconv.h"
#include "sqlite.h"
#include "init.h"
+#include "onoff.h"
extern struct user * const user;
struct alarm *timeout_event = NULL;
@@ -204,6 +205,125 @@ static int js_push_ipcmsg_event(ipc_message_t *msg)
return 0;
}
+static int js_push_logon_event(json_t *j, duk_idx_t i, int type)
+{
+ duk_push_boolean(ctx, type == LOGON_AUTOCHAT);
+ duk_put_prop_string(ctx, i, "autochat");
+ return 0;
+}
+
+static int js_push_logoff_event(json_t *j, duk_idx_t i, int type)
+{
+ const char *reason;
+ const char *agent;
+ const char *subtypes[] = {
+ [LOGOFF_NORMAL] = "normal",
+ [LOGOFF_TIMEOUT] = "timeout",
+ [LOGOFF_EOFS] = "eof",
+ [LOGOFF_MROD] = "mrod",
+ [LOGOFF_BANNED] = "banned",
+ [LOGOFF_ERROR] = "error",
+ [LOGOFF_DELETED] = "deleted"
+ };
+ if (type > LOGOFF_DELETED || type < 0) {
+ fprintf(stderr, "mwjs error: bad logoff event type: %d\n", type);
+ duk_pop(ctx);
+ return 1;
+ }
+ duk_push_string(ctx, subtypes[type]);
+ duk_put_prop_string(ctx, i, "method");
+ reason = json_getstring(j, "reason");
+ if (reason != NULL) {
+ duk_push_string(ctx, reason);
+ duk_put_prop_string(ctx, i, "reason");
+ }
+ agent = json_getstring(j, "agent");
+ if (agent != NULL) {
+ duk_push_string(ctx, agent);
+ duk_put_prop_string(ctx, i, "agent");
+ }
+ return 0;
+}
+
+static int js_push_join_event(json_t *j, duk_idx_t i, int type)
+{
+ const char *agent = json_getstring(j, "agent");
+ const char *subtypes[] = {
+ [JOIN_NORMAL] = "normal",
+ [JOIN_SUMMONED] = "summoned",
+ [JOIN_FORCED] = "forced",
+ };
+ if (type > JOIN_FORCED || type < 0) {
+ fprintf(stderr, "mwjs error: bad join event type: %d\n", type);
+ duk_pop(ctx);
+ return 1;
+ }
+ duk_push_string(ctx, subtypes[type]);
+ duk_put_prop_string(ctx, i, "method");
+ if (agent != NULL) {
+ duk_push_string(ctx, agent);
+ duk_put_prop_string(ctx, i, "agent");
+ }
+ duk_push_number(ctx, json_getint(j, "channel"));
+ duk_put_prop_string(ctx, i, "channel");
+ return 0;
+}
+
+static int js_push_leave_event(json_t *j, duk_idx_t i, int type)
+{
+ const char *agent = json_getstring(j, "agent");
+ const char *msg = json_getstring(j, "message");
+ const char *subtypes[] = {
+ [LEAVE_NORMAL] = "normal",
+ [LEAVE_ZOD] = "zod",
+ [LEAVE_FORCED] = "forced",
+ [LEAVE_EXIT] = "logoff",
+ };
+ if (type > LEAVE_EXIT || type < 0) {
+ fprintf(stderr, "mwjs error: bad leave event type: %d\n", type);
+ duk_pop(ctx);
+ return 1;
+ }
+ duk_push_string(ctx, subtypes[type]);
+ duk_put_prop_string(ctx, i, "method");
+ if (agent != NULL) {
+ duk_push_string(ctx, agent);
+ duk_put_prop_string(ctx, i, "agent");
+ }
+ if (msg != NULL) {
+ duk_push_string(ctx, msg);
+ duk_put_prop_string(ctx, i, "message");
+ }
+ duk_push_number(ctx, json_getint(j, "channel"));
+ duk_put_prop_string(ctx, i, "channel");
+ return 0;
+}
+
+static int (*js_push_onoff_func[ONOFF_SIZE])(json_t*, duk_idx_t, int) = {
+ js_push_logon_event,
+ js_push_logoff_event,
+ js_push_join_event,
+ js_push_leave_event
+};
+
+/* Pushes the event object and attaches the common bits to it before calling
+ * the onoff action type-specific function to fill in the rest */
+static int js_push_onoff_event(json_t *j, int action)
+{
+ duk_idx_t idx = duk_push_bare_object(ctx);
+ int type = json_getint(j, "type");
+ int ret;
+
+ duk_push_boolean(ctx, json_is_true(json_object_get(j, "quiet")));
+ duk_put_prop_string(ctx, idx, "quiet");
+ duk_push_string(ctx, json_getstring(j, "user"));
+ duk_put_prop_string(ctx, idx, "user");
+
+ ret = js_push_onoff_func[action](j, idx, type);
+ json_decref(j);
+ return ret;
+}
+
static duk_ret_t js_print(duk_context *cx)
{
int argc = duk_get_top(cx);
@@ -756,6 +876,24 @@ static int js_push_event(struct mwevent *ev)
if (ret == 0)
duk_put_prop_string(ctx, idx, "data");
break;
+ case MWEV_TYPE_ONOFF:
+ duk_require_stack(ctx, 2);
+ /* ONOFF covers 4 different types of events so expose them as
+ separate event types to reduce js boilerplate */
+ json_t *j = ipcmsg_json_decode(ev->ev_data.onoff);
+ if (j == NULL) {
+ fprintf(stderr, "mwjs error: failed to unmarshall message\n");
+ return -1;
+ }
+ int action = json_getint(j, "action");
+ if (action >= ONOFF_SIZE || action < 0)
+ break;
+ duk_push_string(ctx, onoff_action_name[action]);
+ duk_put_prop_string(ctx, idx, "type");
+ ret = js_push_onoff_event(j, action);
+ if (ret == 0)
+ duk_put_prop_string(ctx, idx, "data");
+ break;
case MWEV_TYPE_NONE:
/* Fall through */
default:
=====================================
src/client/main.c
=====================================
--- a/src/client/main.c
+++ b/src/client/main.c
@@ -54,6 +54,7 @@
#include "userio.h"
#include "who.h"
#include "alias.h"
+#include "onoff.h"
static char version[]="Milliways III - Release "VERSION"\n";
@@ -198,7 +199,7 @@ static void accept_line(char *line)
broadcast(1, "\03304%s'%s connection has just dropped.", user->record.name,
user->record.name[strlen(user->record.name)] == 's' ? "" : "s");
mwlog("EOF(LOGOUT)");
- close_down(2, NULL, NULL);
+ close_down(LOGOFF_EOFS, NULL, NULL);
}
} else
{
@@ -727,8 +728,7 @@ int main(int argc, char **argv)
/* run all board init functions */
RunInitFuncs(0);
- /* broadcast board logon signal to other users */
- broadcast_onoffcode(3, autochat, NULL, NULL);
+ announce_logon(user->record.name, autochat ? LOGON_AUTOCHAT : LOGON_NORMAL, quietmode);
/* autochat - log onto talker immediately */
if (autochat && u_reg(user)) t_chaton();
@@ -757,7 +757,7 @@ int main(int argc, char **argv)
fflush(stdout);
perror("stdin");
mwlog("ERROR on stdin");
- close_down(5, NULL, NULL);
+ close_down(LOGOFF_ERROR, NULL, NULL);
}
if (!busy && MesgIsStacked())
{
@@ -837,7 +837,7 @@ void accept_command(char *cmd)
}
}
-void close_down(int exitmode, char *sourceuser, char *reason)
+void close_down(int logofftype, char *sourceuser, char *reason)
{
extern char *event_user;
extern char *event_body_text;
@@ -862,19 +862,10 @@ void close_down(int exitmode, char *sourceuser, char *reason)
else ExecEvent(shutdown_name, "", "ShutDown", NULL, 0);
}
}
- /* give 'straight to shell' logoff code */
- broadcast_onoffcode(0, 3, sourceuser, NULL);
+ announce_leave(user->record.name, user->record.room, LEAVE_EXIT, sourceuser, NULL, quietmode);
}
- /* send different broadcast depending on exitmode */
- /* 0 - normal */
- /* 1 - timeout */
- /* 2 - too many eof's */
- /* 3 - mrod */
- /* 4 - banned */
- /* 5 - error */
- broadcast_onoffcode(2, exitmode, sourceuser, reason);
-
+ announce_logoff(user->record.name, logofftype, sourceuser, reason, quietmode);
/* update user information */
time_t now = time(0);
@@ -904,11 +895,8 @@ void close_down(int exitmode, char *sourceuser, char *reason)
stop_js();
alarm_cleanup();
- /* dont display logoff text if quiet, or if dropped */
- if (!quietmode && exitmode!=1 && exitmode!=2)
- {
+ if (!quietmode && logofftype != LOGOFF_TIMEOUT && logofftype != LOGOFF_EOFS)
broadcast(1, "\03302%s has just left the board.", user->record.name);
- }
mwlog("LOGOUT");
sleep(1); //dodgy hack for race condition in checkonoff, cunningly we currently get woken by the very message we're waiting for.
@@ -1261,7 +1249,7 @@ static void time_out(void *idle_count_p)
broadcast(1, _("\03304%s has been timed out."), user->record.name);
mwlog("TIMEOUT(LOGOUT)");
- close_down(1, NULL, NULL);
+ close_down(LOGOFF_TIMEOUT, NULL, NULL);
}
else if (*icnt==0)
{
@@ -1274,7 +1262,7 @@ static void time_out(void *idle_count_p)
else
{
mwlog("TIMEOUT(BLOCKED)");
- close_down(1, NULL, NULL);
+ close_down(LOGOFF_TIMEOUT, NULL, NULL);
}
}
@@ -1846,26 +1834,3 @@ void devel_msg(const char *func, const char *fmt, ...)
if (cp_test(user, CP_DEVEL))
printf("\n*** WARNING (%s): %s\n", func, text);
}
-
-
-void broadcast_onoffcode(int ocode, int method, const char *sourceuser, const char *reason)
-{
- char logofftext[MAXTEXTLENGTH];
- extern int talker_logontype;
- const char *usr;
-
- if (sourceuser == NULL)
- usr = user->record.name;
- else
- usr = sourceuser;
-
- if (reason == NULL)
- snprintf(logofftext, MAXTEXTLENGTH-1, "%d,%d,%d,%s", ocode, method,
- talker_logontype & LOGONMASK_QUIET, usr);
- else
- snprintf(logofftext, MAXTEXTLENGTH-1, "%d,%d,%d,%s,%s", ocode, method,
- talker_logontype & LOGONMASK_QUIET, usr, reason);
-
- logofftext[MAXTEXTLENGTH-1] = '\0';
- ipc_send_to_all(IPC_CHECKONOFF, logofftext);
-}
=====================================
src/client/main.h
=====================================
--- a/src/client/main.h
+++ b/src/client/main.h
@@ -5,7 +5,6 @@ void close_down(int exitmode, char *sourceuser, char *reason);
void display_message(const char *text, int beeps, int newline);
void format_message(const char *format, ...) __attribute__((format(printf,1,0)));
void printfile(const char *filename);
-void broadcast_onoffcode(int code, int method, const char *sourceuser, const char *reason);
void reset_timeout(int secs);
int idle(int fd, int millis);
void set_rights(void);
=====================================
src/client/newmain.c
=====================================
--- a/src/client/newmain.c
+++ b/src/client/newmain.c
@@ -38,6 +38,7 @@
#include "userio.h"
#include "mesg.h"
#include "incoming.h"
+#include "onoff.h"
#include <util.h>
extern int currentfolder,last_mesg;
@@ -1025,7 +1026,7 @@ void c_date(CommandList *cm, int argc, const char **argv, char *args)
void c_quit(CommandList *cm, int argc, const char **argv, char *args)
{
- close_down(0, NULL, NULL);
+ close_down(LOGOFF_NORMAL, NULL, NULL);
}
void c_save(CommandList *cm, int argc, const char **argv, char *args)
=====================================
src/client/onoff.c
=====================================
--- /dev/null
+++ b/src/client/onoff.c
@@ -0,0 +1,99 @@
+#include <ipc.h>
+#include "onoff.h"
+
+extern struct user * const user;
+
+const char *onoff_action_name[ONOFF_SIZE] = {
+ [ONOFF_LOGON] = "mw_logon",
+ [ONOFF_LOGOFF] = "mw_logoff",
+ [ONOFF_JOIN] = "talker_join",
+ [ONOFF_LEAVE] = "talker_leave"
+};
+
+int announce_logon(const char *usr, int type, int quiet)
+{
+ ipc_message_t *msg;
+ json_t *j;
+
+ j = json_init(NULL);
+ json_addstring(j, "user", usr);
+ json_addint(j, "action", ONOFF_LOGON);
+ json_addint(j, "type", type);
+ json_object_set(j, "quiet", json_boolean(quiet));
+
+ msg = ipcmsg_create(IPC_CHECKONOFF, user->posn);
+ ipcmsg_destination(msg, SYSTEM_USER);
+ ipcmsg_json_encode(msg, j);
+ json_decref(j);
+ ipcmsg_transmit(msg);
+ return 0;
+}
+
+int announce_logoff(const char *usr, int type, const char *agent, const char *reason, int quiet)
+{
+ ipc_message_t *msg;
+ json_t *j;
+
+ j = json_init(NULL);
+ json_addstring(j, "user", usr);
+ json_addint(j, "action", ONOFF_LOGOFF);
+ json_addint(j, "type", type);
+ json_object_set(j, "quiet", json_boolean(quiet));
+ if (agent != NULL)
+ json_addstring(j, "agent", agent);
+ if (reason != NULL)
+ json_addstring(j, "reason", reason);
+
+ msg = ipcmsg_create(IPC_CHECKONOFF, user->posn);
+ ipcmsg_destination(msg, SYSTEM_USER);
+ ipcmsg_json_encode(msg, j);
+ json_decref(j);
+ ipcmsg_transmit(msg);
+ return 0;
+}
+
+int announce_join(const char *usr, int channel, int type, const char *agent, int quiet)
+{
+ ipc_message_t *msg;
+ json_t *j;
+
+ j = json_init(NULL);
+ json_addstring(j, "user", usr);
+ json_addint(j, "action", ONOFF_JOIN);
+ json_addint(j, "channel", channel);
+ json_addint(j, "type", type);
+ json_object_set(j, "quiet", json_boolean(quiet));
+ if (agent != NULL)
+ json_addstring(j, "agent", agent);
+
+ msg = ipcmsg_create(IPC_CHECKONOFF, user->posn);
+ ipcmsg_destination(msg, SYSTEM_USER);
+ ipcmsg_json_encode(msg, j);
+ json_decref(j);
+ ipcmsg_transmit(msg);
+ return 0;
+}
+
+int announce_leave(const char *usr, int channel, int type, const char *agent, const char *lmsg, int quiet)
+{
+ ipc_message_t *msg;
+ json_t *j;
+
+ j = json_init(NULL);
+ json_addstring(j, "user", usr);
+ json_addint(j, "action", ONOFF_LEAVE);
+ json_addint(j, "channel", channel);
+ json_addint(j, "type", type);
+ json_object_set(j, "quiet", json_boolean(quiet));
+ if (agent != NULL)
+ json_addstring(j, "agent", agent);
+ if (lmsg != NULL)
+ json_addstring(j, "message", lmsg);
+
+ msg = ipcmsg_create(IPC_CHECKONOFF, user->posn);
+ ipcmsg_destination(msg, SYSTEM_USER);
+ ipcmsg_json_encode(msg, j);
+ json_decref(j);
+ ipcmsg_transmit(msg);
+ return 0;
+}
=====================================
src/client/onoff.h
=====================================
--- /dev/null
+++ b/src/client/onoff.h
@@ -0,0 +1,13 @@
+#ifndef ONOFF_H
+#define ONOFF_H
+
+#include <onoff.h>
+
+extern const char *onoff_action_name[ONOFF_SIZE];
+
+int announce_logon(const char *usr, int type, int quiet);
+int announce_logoff(const char *usr, int type, const char *agent, const char *reason, int quiet);
+int announce_join(const char *usr, int channel, int type, const char *agent, int quiet);
+int announce_leave(const char *usr, int channel, int type, const char *agent, const char *msg, int quiet);
+
+#endif /* ONOFF_H */
=====================================
src/client/script_inst.c
=====================================
--- a/src/client/script_inst.c
+++ b/src/client/script_inst.c
@@ -27,6 +27,7 @@
#include "mesg.h"
#include "util.h"
#include "who.h"
+#include "onoff.h"
extern struct user * const user;
/* current script runaway variable */
@@ -462,8 +463,7 @@ void scr_talkpriv( struct code *pc, int fargc, char **fargv )
void scr_quit( struct code *pc, int fargc, char **fargv )
{
- /* close down milliways normally */
- close_down(0, NULL, NULL);
+ close_down(LOGOFF_NORMAL, NULL, NULL);
}
void scr_exec( struct code *pc, int fargc, char **fargv )
=====================================
src/client/talker.c
=====================================
--- a/src/client/talker.c
+++ b/src/client/talker.c
@@ -33,6 +33,7 @@
#include "mesg.h"
#include "incoming.h"
#include "alias.h"
+#include "onoff.h"
extern int busy; /* if true dont display messages i.e. during new/write */
extern unsigned long rights;
@@ -187,8 +188,7 @@ void t_quit(CommandList *cm, int argc, const char **argv, char *args)
snprintf(text, MAXTEXTLENGTH-1, "\03311%s has just left the talker", user->record.name);
if (!quietmode) talk_send_rawbcast(text);
- /* announce log off talker */
- broadcast_onoffcode(0, 0, NULL, NULL);
+ announce_leave(user->record.name, user->record.room, LEAVE_NORMAL, NULL, NULL, quietmode);
set_rights();
}
@@ -1128,10 +1128,7 @@ void t_chaton(void)
/* run the common stuff for entering the talker */
enter_talker(1);
-
- /* give an entrance broadcast */
- broadcast_onoffcode(1, 0, NULL, NULL);
-
+ announce_join(urec->name, urec->room, JOIN_NORMAL, NULL, quietmode);
enter_room(urec->room);
}
=====================================
src/onoff.h
=====================================
--- /dev/null
+++ b/src/onoff.h
@@ -0,0 +1,35 @@
+#ifndef MW_ONOFF_H
+#define MW_ONOFF_H
+
+enum onoff_action {
+ /* Relating to mw itself */
+ ONOFF_LOGON = 0,
+ ONOFF_LOGOFF = 1,
+ /* Relating to the talker */
+ ONOFF_JOIN = 2,
+ ONOFF_LEAVE = 3,
+
+ ONOFF_SIZE /* Keep at end */
+};
+
+#define LOGON_NORMAL 0
+#define LOGON_AUTOCHAT 1
+
+#define LOGOFF_NORMAL 0
+#define LOGOFF_TIMEOUT 1
+#define LOGOFF_EOFS 2
+#define LOGOFF_MROD 3
+#define LOGOFF_BANNED 4
+#define LOGOFF_ERROR 5
+#define LOGOFF_DELETED 6
+
+#define JOIN_NORMAL 0
+#define JOIN_SUMMONED 1
+#define JOIN_FORCED 2
+
+#define LEAVE_NORMAL 0
+#define LEAVE_ZOD 1
+#define LEAVE_FORCED 2
+#define LEAVE_EXIT 3
+
+#endif /* MW_ONOFF_H */
=====================================
src/server/PROTOCOL
=====================================
--- a/src/server/PROTOCOL
+++ b/src/server/PROTOCOL
@@ -134,6 +134,25 @@ IPC_WHOLIST - list of all the users currently known to the system
protection
wizchat
+IPC_CHECKONOFF - Logon, logoff, talker join, talker leave events.
+ Body: (json)
+ user - String; User who is doing the thing
+ action - Integer corresponding to the ONOFF_* values in onoff.h
+ type - Integer subtype of action; one of the LOGON_*, LOGOFF_*,
+ LEAVE_*, JOIN_* values.
+ quiet - Boolean; true if the user is in quiet mode.
+ ONOFF_LOGON fields:
+ (none)
+ ONOFF_LOGOFF fields:
+ reason - (Optional) String; the reason for logging off
+ agent - (Optional) String; who made this logoff happen
+ ONOFF_JOIN:
+ channel - Integer; currently unused (either on talker or not)
+ agent - (Optional) String; who made this join happen
+ ONOFF_LEAVE:
+ channel - Integer; currently unused (either on talker or not)
+ agent - (Optional) String; who made this leave happen
+ message - (Optional) String; what Zebedee says
all other codes are old unformatted messages and are to be phased out,
most commonly used is IPC_TEXT which is raw text to be displayed
View it on GitLab: https://projects.sucs.org/arthur/mw/commit/ccde2b8526802d6d0f19a740e110bfdff322ba84
--
View it on GitLab: https://projects.sucs.org/arthur/mw/commit/ccde2b8526802d6d0f19a740e110bfdff322ba84
You're receiving this email because of your account on projects.sucs.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sucs.org/pipermail/mw-devel/attachments/20181103/4d0ef656/attachment-0001.html>
More information about the mw-devel
mailing list