summaryrefslogtreecommitdiff
path: root/src/irc.c
blob: 7d87d38feeb3981934daf980c4e95dd9bbd2459b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
/* File: irc.c */

/* Purpose: irc chat */

/*
 * Copyright (c) 2001 DarkGod, Andrew Sidwell
 *
 * This software may be copied and distributed for educational, research, and
 * not for profit purposes provided that this copyright and statement are
 * included in all such copies.
 */

#include "angband.h"

#define IRC_SERVER "irc.worldirc.org"
#define IRC_PORT "6667"
#define IRC_CHANNEL "#tome"

/*
 * By the way, CTCP's for unique kills and artefact finds would be nice to
 * have, for example:
 *
 * *pelpel finds Long Sword 'Ringil' (4d5) (+22,+25) (+10 to speed) :)
 */

ip_connection tome_irc_forge;
ip_connection *tome_irc = &tome_irc_forge;
bool irc_can_join = FALSE;
char irc_nick[30];
char irc_world[100];

void irc_connect()
{
	char buf[500], *s;
	int rnd_name = randint(999);

	if (tome_irc->connected) return;

	sprintf(irc_world, "%99s", IRC_CHANNEL);
	sprintf(irc_nick, "Dummy_%03d", rnd_name);
	get_string("Enter Nickname: ", irc_nick, 10);

	zsock.setup(tome_irc, IRC_SERVER, atoi(IRC_PORT), ZSOCK_TYPE_TCP, FALSE);
	zsock.open(tome_irc);
	zsock.write_simple(tome_irc, format("NICK %s\r\n", irc_nick));
	zsock.wait(tome_irc, 40);
	zsock.read_simple(tome_irc, buf, 500);
	s = strchr(buf, ':');
	zsock.write_simple(tome_irc, format("PONG %s\r\n", s));
	zsock.write_simple(tome_irc, format("USER tome 0 *BIRC :%s %d.%d.%d User\r\n",
	                                    game_module, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH));
#if 0 /* Pfft spoilsport */
	while (!irc_can_join)
		irc_poll();
#endif

	zsock.write_simple(tome_irc, format("JOIN %s\r\n", irc_world));

	cmsg_print(TERM_L_GREEN, "Connected to IRC");

	zsock.add_timer(irc_poll);
}

void irc_change_nick()
{
	return;
}

void irc_disconnect()
{
	if (!tome_irc->connected) return;
	irc_can_join = FALSE;

	irc_quit(format("%s %d.%d.%d", game_module, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH));

	cmsg_print(TERM_L_RED, "Disconnected from IRC");
}

void irc_disconnect_aux(char *str, bool message)
{
	if (!tome_irc->connected) return;
	irc_can_join = FALSE;

	irc_quit(str);

	if (message) cmsg_print(TERM_L_RED, "Disconnected from IRC");
}

void irc_emote(char *buf)
{
	char *b;
	char *base = "PRIVMSG %s :%cACTION %s%c\r\n";

	if (!tome_irc->connected) return;

	C_MAKE(b, strlen(buf) + strlen(base) + 1, char);
	sprintf(b, base, irc_world, 1, buf, 1);
	zsock.write_simple(tome_irc, b);
	sprintf(b, "* %s %s", irc_nick, buf);
	message_add(MESSAGE_IRC, b, TERM_YELLOW);
	C_FREE(b, strlen(buf) + strlen(base) + 1, char);
	fix_irc_message();
}

void irc_chat()
{
	char buf[80] = "";

	if (!tome_irc->connected) return;
	if (get_string("Say: ", buf, 80))
	{
		if (prefix(buf, "/me "))
		{
			irc_emote(buf + 4);
		}
		else if ((prefix(buf, "/join ")) && (buf[6] != '\0'))
		{
			zsock.write_simple(tome_irc, format("PART %s\r\n", irc_world));
			sprintf(irc_world, "%99s", buf + 6);
			zsock.write_simple(tome_irc, format("JOIN %s\r\n", irc_world));
		}
		else
		{
			zsock.write_simple(tome_irc, format("PRIVMSG %s :%s\r\n", irc_world, buf /*, 3, irc_world */));
			message_add(MESSAGE_IRC, format("<%s> #w%s", irc_nick, buf), TERM_L_BLUE);
			fix_irc_message();
		}
	}
}

#define TERM_CTCP	TERM_L_GREEN
#define TERM_SERVER	TERM_L_BLUE
#define TERM_CHAT1	TERM_YELLOW
#define TERM_CHAT2	TERM_WHITE

void irc_poll()
{
	char buf[5000], *next, *nick, *space;

	if (tome_irc->connected && zsock.can_read(tome_irc))
	{
		zsock.read_simple(tome_irc, buf, 2500);

		if (prefix(buf, "PING "))
		{
			message_add(MESSAGE_IRC, format("*** Recieved a PING request from server %s.", buf + 6), TERM_SERVER);
			zsock.write_simple(tome_irc, format("PONG %s\r\n", buf + 5));
			return;
		}
		if (*buf != ':') return;
		nick = buf + 1;

		space = strchr(nick, ' ');
		if (space)
		{
			if (prefix(space + 1, "376"))
				irc_can_join = TRUE;
		}

		if (prefix(nick, "_"))
		{
			nick = buf + 6;
		}

		next = strchr(nick, '!');
		if (next == NULL) return;
		*next = '\0';
		next++;
		next = strchr(next, ' ');
		if (next == NULL) return;
		next++;
		if (prefix(next, "PRIVMSG"))
		{
			next = strchr(next, ':');
			if (next == NULL) return;
			*next = '\0';
			next++;
			if (*next == 1)
			{
				next++;
				if (prefix(next, "ACTION"))
				{
					u32b i = 0, j = 0, max = (79 - strlen(nick) - 3);
					bool nicked = FALSE;
					char tmp[90];

					next += 7;
					if (strlen(next)) next[strlen(next) - 1] = '\0';

					while (next[i])
					{
						tmp[j++] = next[i++];
						if (j > max)
						{
							tmp[j] = '\0';
							if (nicked)
								message_add(MESSAGE_IRC, format("%s", tmp), TERM_CHAT1);
							else
								message_add(MESSAGE_IRC, format("* %s %s", nick, tmp), TERM_CHAT1);
							nicked = TRUE;
							j = 0;
						}
					}
					if (j > 0)
					{
						tmp[j] = '\0';
						if (nicked)
							message_add(MESSAGE_IRC, format("%s", tmp), TERM_CHAT1);
						else
							message_add(MESSAGE_IRC, format("* %s %s", nick, tmp), TERM_CHAT1);
					}

					fix_irc_message();
				}
				else if (prefix(next, "PING"))
				{
					message_add(MESSAGE_IRC, format("*** PING request from %s", nick), TERM_CTCP);
					fix_irc_message();

					zsock.write_simple(tome_irc, format("NOTICE %s :%cPING %d%c\r\n", nick, 1, next, 1));
				}
				else if (prefix(next, "NICK"))
				{
					message_add(MESSAGE_IRC, format("*** NICK request from %s", nick), TERM_CTCP);
					fix_irc_message();

					zsock.write_simple(tome_irc, format("NOTICE %s :%cNICK %s%c\r\n", nick, 1, irc_nick, 1));
				}
				else if (prefix(next, "VERSION"))
				{
					message_add(MESSAGE_IRC, format("*** VERSION request from %s", nick), TERM_CTCP);
					fix_irc_message();

					zsock.write_simple(tome_irc, format("NOTICE %s :%cVERSION %s %d.%d.%d%c\r\n", nick, 1, game_module, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, 1));
				}
			}
			else
			{
				u32b i = 0, j = 0, max = (79 - strlen(nick) - 3);
				bool nicked = FALSE;
				char tmp[90];

				while (next[i])
				{
					tmp[j++] = next[i++];
					if (j > max)
					{
						tmp[j] = '\0';
						if (nicked)
							message_add(MESSAGE_IRC, format("#w%s", tmp), TERM_CHAT1);
						else
							message_add(MESSAGE_IRC, format("#y<%s> #w%s", nick, tmp), TERM_CHAT1);
						nicked = TRUE;
						j = 0;
					}
				}
				if (j > 0)
				{
					tmp[j] = '\0';
					if (nicked)
						message_add(MESSAGE_IRC, format("#w%s", tmp), TERM_CHAT1);
					else
						message_add(MESSAGE_IRC, format("#y<%s> #w%s", nick, tmp), TERM_CHAT1);
				}
				fix_irc_message();
			}
		}
		if (prefix(next, "JOIN"))
		{
			message_add(MESSAGE_IRC, format("%s has entered the Chatroom", nick), TERM_YELLOW);
			fix_irc_message();
		}
		if (prefix(next, "QUIT"))
		{
			next = strchr(next, ':');
			if (next == NULL) return;
			*next = '\0';
			next++;
			message_add(MESSAGE_IRC, format("%s has quit the Chatroom (%s)", nick, next), TERM_YELLOW);
			fix_irc_message();
		}
	}
}


void irc_quit(char *str)
{
	char buf[300];

	zsock.remove_timer(irc_poll);

	sprintf(buf, "QUIT :%s\r\n", str);

	zsock.write_simple(tome_irc, buf);
	zsock.close(tome_irc);
	zsock.unsetup(tome_irc);
}