aboutsummaryrefslogtreecommitdiff
path: root/src/irc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/irc.c')
-rw-r--r--src/irc.c191
1 files changed, 185 insertions, 6 deletions
diff --git a/src/irc.c b/src/irc.c
index 1f7aad3..8343897 100644
--- a/src/irc.c
+++ b/src/irc.c
@@ -15,15 +15,23 @@
#define MAX_MSG 512
+extern void __fastcall__ bell(void); /* see src/bell.s */
+
char *msg_src, *msg_cmd, *msg_dest, *msg_text;
char *msg_args[MAX_MSG_ARGS];
int msg_argcount;
+char irc_away = 0;
+char bell_type = 3;
+
static char msgbuf[MAX_MSG] = { 0 };
static char *msg; /* with source removed */
static int msgbuf_len = 0, msg_len = 0;
static char regged = 0, hilite = 0;
+static char scr_prev = SCR_PRIV;
+
+char numbuf[10];
/*
static void join_channel(void) {
@@ -56,6 +64,7 @@ static void hilite_bold(void) {
}
static void do_chan_nick(void) {
+ if(hilite) bell();
hilite_bold();
scr_print_active("<");
hilite_bold();
@@ -75,6 +84,107 @@ static void do_priv_nick(void) {
scr_print_active("*");
scr_print_active(msg_src);
scr_print_active("* ");
+ bell();
+}
+
+static void print_ping_time(char *p) {
+ static long now, pingtime;
+ static int sec, frac;
+
+ now = read_rtclok();
+ pingtime = atol(p);
+
+ /* correct for rtclock rollover (every 77 hours) */
+ if(now < pingtime) now |= 0x01000000L;
+
+ pingtime = now - pingtime;
+
+ sec = pingtime / hz;
+ frac = pingtime % hz;
+ frac *= 1000;
+ frac /= (hz * 10);
+
+ scr_print_active("*** ");
+ scr_print_active(msg_src);
+ scr_print_active(" ping time: ");
+ itoa(sec, numbuf, 10);
+ scr_print_active(numbuf);
+ scr_print_active(".");
+ itoa(frac, numbuf, 10);
+ scr_print_active(numbuf);
+ scr_print_active(" sec");
+
+ /* for debugging:
+ scr_print_active(" ");
+ ltoa(pingtime, numbuf, 10);
+ scr_print_active(numbuf);
+ */
+}
+
+/* FIXME: this isn't very fast */
+static void do_ctcp(int is_notice) {
+ static char *p, *ctcp_type, *resp;
+
+ resp = 0;
+ ctcp_type = ++msg_text; /* skip leading ^A */
+
+ if( (p = strchr(msg_text, '\x01')) ) {
+ /* kill trailing ^A */
+ *p = 0;
+ }
+
+ if( (p = strchr(msg_text, ' ')) ) {
+ *p++ = 0;
+ }
+
+ if(is_notice) {
+ /* NOTICEs are responses */
+ if(p && streq_i(ctcp_type, "PING")) {
+ print_ping_time(p);
+ } else {
+ scr_print_active("*** CTCP ");
+ scr_print_active(ctcp_type);
+ scr_print_active(" response from ");
+ scr_print_active(msg_src);
+ if(p) {
+ scr_print_active(": ");
+ scr_print_active(p);
+ }
+ }
+ scr_eol_active();
+ } else {
+ /* this is a PRIVMSG (aka a request) */
+ if(streq_i(ctcp_type, "ACTION")) {
+ scr_print_active("* ");
+ scr_print_active(msg_src);
+ scr_print_active(" ");
+ scr_print_active(p);
+ scr_eol_active();
+ return;
+ }
+
+ scr_print_active("*** CTCP ");
+ scr_print_active(ctcp_type);
+ scr_print_active(" request from ");
+ scr_print_active(msg_src);
+ scr_eol_active();
+
+ if(streq_i(ctcp_type, "PING")) {
+ resp = p;
+ } else if(streq_i(ctcp_type, "CLIENTINFO")) {
+ resp = "PING VERSION CLIENTINFO";
+ } else if(streq_i(ctcp_type, "VERSION")) {
+ resp = "FujiNetChat pre-alpha on an Atari 8-bit";
+ } else {
+ /* unknown CTCP type, ignore */
+ return;
+ }
+
+ txbuf_set_str3("NOTICE ", msg_src, " :\x01");
+ txbuf_append_str3(ctcp_type, " ", resp);
+ txbuf_append_str("\x01");
+ txbuf_send();
+ }
}
static void do_privmsg(void) {
@@ -84,6 +194,11 @@ static void do_privmsg(void) {
else
hilite = 0;
+ if(*msg_text == '\x01') {
+ do_ctcp(0);
+ return;
+ }
+
if(*msg_dest == '#')
do_chan_nick();
else
@@ -93,6 +208,15 @@ static void do_privmsg(void) {
scr_eol_active();
}
+static void do_notice(void) {
+ if(*msg_text == '\x01') {
+ do_ctcp(1);
+ } else {
+ scr_print_active("NOTICE ");
+ do_privmsg();
+ }
+}
+
static void do_join(void) {
if(streq_i(usernick, msg_src)) {
scr_print_active("You have ");
@@ -321,6 +445,8 @@ static void dispatch_msg(void) {
if(streq_i(msg_cmd, "PRIVMSG")) {
do_privmsg();
+ } else if(streq_i(msg_cmd, "NOTICE")) {
+ do_notice();
} else if(streq_i(msg_cmd, "JOIN")) {
do_join();
} else if(streq_i(msg_cmd, "NICK")) {
@@ -459,10 +585,9 @@ static void irc_split_Lines(void) {
/* TODO: there needs to be a scr_printnum() */
void print_errnum(void) {
extern unsigned char err;
- char tmp[10];
scr_print_current("Error #");
- itoa(err, tmp, 10);
- scr_print_current(tmp);
+ itoa(err, numbuf, 10);
+ scr_print_current(numbuf);
scr_print_current(", press any key...\n");
}
@@ -472,11 +597,13 @@ int irc_read(void) {
err = nstatus(url);
if(err != 1) {
+ regged = 0;
if(err == 136) {
scr_print_current("Disconnected, press any key...\n");
} else {
print_errnum();
}
+ bell();
cgetc();
scr_display(0);
return 0;
@@ -529,23 +656,71 @@ static void scrollback() {
scr_end_scrollback();
}
+static void hunt_screen(signed char dir) {
+ signed char s = scr_current;
+
+ do {
+ s += dir;
+ if(s < 0)
+ s = MAX_SCREENS - 1;
+ s %= MAX_SCREENS;
+ } while(scr_status[s] == SCR_UNUSED);
+
+ scr_display(s);
+}
+
+void switch_to_active() {
+ char i;
+
+ for(i = 0; i < MAX_SCREENS; i++) {
+ if(scr_status[i] == SCR_ACTIVE) {
+ scr_prev = scr_current;
+ scr_display(i);
+ return;
+ }
+ }
+}
+
static void start_keystroke(void) {
char i, s;
i = cgetc();
if(i >= '1' && i <= '7') {
s = i - '1';
- if(scr_status[s] != SCR_UNUSED)
- scr_display(s);
+ if(s != scr_current) {
+ if(scr_status[s] != SCR_UNUSED) {
+ scr_prev = scr_current;
+ scr_display(s);
+ }
+ }
} else if(i == CH_CURS_UP || i == '-') {
scrollback();
- } else if(i == 0x1b) { /* escape */
+ } else if(i == CH_ESC) {
+ scr_prev = SCR_PRIV;
scr_destroy(scr_current);
+ } else if(i == CH_CURS_LEFT || i == '+') {
+ scr_prev = scr_current;
+ hunt_screen(-1);
+ } else if(i == CH_CURS_RIGHT || i == '*') {
+ scr_prev = scr_current;
+ hunt_screen(1);
+ } else if(i == CH_TAB) {
+ i = scr_current;
+ scr_display(scr_prev);
+ scr_prev = i;
+ } else if(i == 'a' || i == 'A') {
+ switch_to_active();
+ } else if(i == 's' || i == 'S') {
+ edbox_hide();
}
}
static void keystroke(void) {
if(OS.ch == 0xff) return;
+ if(irc_away) {
+ txbuf_send_str("AWAY");
+ irc_away = 0;
+ }
if(GTIA_READ.consol == 6) { /* start pressed */
start_keystroke();
} else {
@@ -556,6 +731,10 @@ static void keystroke(void) {
/* only exits on error (e.g. connection closed, which might be via /QUIT). */
void irc_loop(void) {
while(1) {
+ if(!irc_away && (OS.atract & 0x80)) {
+ irc_away = 1;
+ txbuf_send_str("AWAY :ATRACT mode");
+ }
if(!irc_read()) return;
keystroke();
}