331 lines
No EOL
7.8 KiB
C
331 lines
No EOL
7.8 KiB
C
|
|
|
|
#ifndef DEDICATED
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning( disable : 4206 ) //nonstandard extension: empty translation unit
|
|
#endif
|
|
|
|
#ifdef USE_IRC
|
|
|
|
#include "q_shared.h"
|
|
#include "qcommon.h"
|
|
|
|
typedef enum {
|
|
RPL_WELCOME = 1,
|
|
RPL_YOURHOST,
|
|
RPL_CREATED,
|
|
RPL_MYINFO,
|
|
RPL_BOUNCE,
|
|
RPL_AWAY = 301,
|
|
RPL_USERHOST,
|
|
RPL_ISON,
|
|
RPL_UNAWAY = 305,
|
|
RPL_NOAWAY,
|
|
RPL_LIST = 322,
|
|
RPL_LISTEND,
|
|
ERR_CANNOTSENDTOCHAN=404,
|
|
ERR_NOMOTD = 422,
|
|
ERR_NICKNAMEINUSE = 433,
|
|
ERR_NICKCOLLISION = 436,
|
|
ERR_ALREADYREGISTRED = 462,
|
|
} irc_response_t;
|
|
|
|
extern cvar_t *cl_authserver;
|
|
extern cvar_t *cl_ircport;
|
|
extern cvar_t *sv_ircchannel;
|
|
extern cvar_t *sv_hostname;
|
|
extern cvar_t *sv_mapname;
|
|
|
|
#define IRC_PORT cl_ircport->integer
|
|
#define IRC_SERVER cl_authserver->string
|
|
static netadr_t irc_server;
|
|
|
|
static int irc_connected=qfalse;
|
|
static int irc_registered=qfalse;
|
|
|
|
#ifndef DEDICATED
|
|
extern void CL_ServerAddToRefreshList( const char *info, const char *channel );
|
|
#endif
|
|
|
|
extern qboolean Sys_GetPacket ( netadr_t *net_from, msg_t *net_message );
|
|
extern qboolean Sys_GetPacketData( netadr_t *net_from, msg_t *net_message );
|
|
extern int NET_IPSocket (char *net_interface, int port, netadrtype_t type);
|
|
|
|
void Net_IRC_OpenNetworkPort(char *host){
|
|
char *addr;
|
|
if ( host ) {
|
|
netadr_t client;
|
|
addr = strstr(host, "@")+1;
|
|
if (NET_StringToAdr( addr, &client ) )
|
|
{
|
|
client.port = BigShort(Cvar_VariableIntegerValue("net_port"));
|
|
NET_OutOfBandPrint( NS_SERVER, client, "poke" );
|
|
}
|
|
}
|
|
}
|
|
/*void Net_IRC_QueryRemotePort(){
|
|
netadr_t to;
|
|
NET_StringToAdr( va("%s:%d", IRC_SERVER, PORT_SERVER ), &to );
|
|
NET_OutOfBandPrint( NS_SERVER, to, "getmylocalport" );
|
|
}*/
|
|
void Net_IRC_HandleResponse(char *line)
|
|
{
|
|
char *cmd;
|
|
const char *text_p;
|
|
int msgnum;
|
|
text_p = line;
|
|
Com_Printf("IRC: Raw: [%s]\n", line);
|
|
if (line[0] == ':') {
|
|
char *host, *msg;
|
|
host = COM_Parse(&text_p); // <nick>!<user>@ip
|
|
msg = COM_Parse(&text_p);
|
|
msgnum = atoi(msg);
|
|
if (msgnum == 0)
|
|
{
|
|
switch(SWITCHSTRING(msg))
|
|
{
|
|
case CS('N','O','T','I'): //NOTICE
|
|
if (irc_registered == qfalse) {
|
|
cvar_t *name = Cvar_Get("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE);
|
|
|
|
Net_IRC_RegisterUser(name->string, NULL);
|
|
}
|
|
Com_Printf("IRC: [NOTICE]: %s\n", text_p);
|
|
break;
|
|
case CS('J','O','I','N'): // JOIN
|
|
if (com_sv_running->integer!= 0) {
|
|
|
|
char * channel = COM_Parse(&text_p);
|
|
//ignore the : in front of the channel name
|
|
channel++;
|
|
|
|
// someone is joining this server's channel
|
|
if ( !Q_stricmp( channel, sv_ircchannel->string ) ) {
|
|
cvar_t *sv_ircnick = Cvar_Get("sv_ircnick", "na", CVAR_ROM);
|
|
char *end_of_nick = strstr(host+1, "!");
|
|
char nick[256];
|
|
Q_strncpyz(nick, host+1, end_of_nick - host);
|
|
if ( !Q_stricmp( nick, sv_ircnick->string) ) { // if we are the ones joining our channel, then set the topic
|
|
char *addr = strstr(host, "@")+1;
|
|
Net_IRC_SendMessage( va("TOPIC %s :addr\\%s\\hostname\\%s\\mapname\\%s", sv_ircchannel->string,addr, sv_hostname->string, sv_mapname->string ) );
|
|
}
|
|
Net_IRC_OpenNetworkPort(host);
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
switch(msgnum) {
|
|
case RPL_WELCOME:
|
|
case RPL_YOURHOST:
|
|
case RPL_CREATED:
|
|
case RPL_BOUNCE:
|
|
break;
|
|
case RPL_MYINFO:
|
|
irc_registered = qtrue;
|
|
Com_Printf("Registered!\n");
|
|
//Net_IRC_JoinChannel("#consolespam");
|
|
Net_IRC_JoinChannel( Cvar_VariableString( "sv_ircchannel" ) );
|
|
break;
|
|
|
|
case RPL_LIST: //"<channel> <# visible> :<topic>"
|
|
{
|
|
#ifndef DEDICATED
|
|
if ( !com_sv_running->integer ) {
|
|
|
|
const char *channel;
|
|
|
|
COM_Parse(&text_p); // username
|
|
channel = COM_Parse(&text_p); // channel
|
|
|
|
if ( !Q_strncmp( channel, "#server-", 8 ) ) {
|
|
COM_Parse(&text_p); // num users
|
|
COM_Parse(&text_p); // channel mode
|
|
text_p++;
|
|
|
|
CL_ServerAddToRefreshList( text_p, channel );
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
break;
|
|
case RPL_LISTEND:
|
|
break;
|
|
case ERR_CANNOTSENDTOCHAN:
|
|
case ERR_NOMOTD:
|
|
case ERR_ALREADYREGISTRED:
|
|
break;
|
|
|
|
case ERR_NICKNAMEINUSE:
|
|
{
|
|
char *nick = va("%s_%d", Cvar_VariableString( "name" ), Q_rand() );
|
|
Cvar_Set("sv_ircnick", nick);
|
|
Net_IRC_SendMessage( va("NICK %s", nick) );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if ( msgnum > 400 ) {
|
|
Com_Printf( "irc error: %d\n", msgnum );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
// Server messages?
|
|
} else {
|
|
cmd = COM_Parse(&text_p);
|
|
switch(SWITCHSTRING(cmd))
|
|
{
|
|
case CS('P','I','N','G'):
|
|
{
|
|
char *host;
|
|
host = COM_Parse(&text_p);
|
|
Net_IRC_SendMessage(va("PONG %s", host));
|
|
break;
|
|
}
|
|
default:
|
|
Com_Printf("IRC: Unknown server message: [%s %s]\n", cmd, text_p);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Net_IRC_CleanString(char *msg)
|
|
{
|
|
int i;
|
|
for(i=0; i < strlen(msg); i++)
|
|
{
|
|
switch(msg[i]){
|
|
case '\r':
|
|
case '\n':
|
|
msg[i] = ' ';
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Net_IRC_SendMessage(const char *msg)
|
|
{
|
|
char buf[512];
|
|
//We are going to toss a \r\n to the end, so only copy the first 510 bytes
|
|
Q_strncpyz(buf, msg, 510);
|
|
Net_IRC_CleanString(buf);
|
|
Q_strcat(buf, 512, "\r\n");
|
|
if (irc_server.socket != 0)
|
|
{
|
|
NET_SendPacket(0, strlen(buf), buf, irc_server);
|
|
}
|
|
}
|
|
|
|
void Net_IRC_ReadMessage(msg_t *netmsg)
|
|
{
|
|
char buf[512]; //irc max line length is 512
|
|
int i, offset;
|
|
for (i=0,offset=0; i < netmsg->cursize-1; i++)
|
|
{
|
|
if (netmsg->data[i] == '\r' && netmsg->data[i+1] == '\n'){
|
|
if ( (i - offset+1) < sizeof(buf) )
|
|
{
|
|
Q_strncpyz(buf, netmsg->data + offset, i - offset+1);
|
|
Net_IRC_HandleResponse(buf);
|
|
//set our offset to i + the \r\n
|
|
offset = i+2;
|
|
// increment i for the \r, when the for loop wraps it will
|
|
// increment again for the \n
|
|
i++;
|
|
} else {
|
|
Com_Error(ERR_DROP, "Invalid packet");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//A return of qtrue means the message was able to be sent, not that you
|
|
//were actually able to be registered successfully
|
|
qboolean Net_IRC_RegisterUser(char *nick, char *pass)
|
|
{
|
|
if (irc_connected)
|
|
{
|
|
if ( !irc_registered )
|
|
{
|
|
if (pass)
|
|
Net_IRC_SendMessage( va("PASS %s", pass));
|
|
|
|
Cvar_Set("sv_ircnick", nick);
|
|
Net_IRC_SendMessage( va("NICK %s", nick));
|
|
Net_IRC_SendMessage( va("USER %s NA NA :NA", nick) );
|
|
return qtrue;
|
|
}
|
|
return qfalse;
|
|
}
|
|
return qfalse;
|
|
}
|
|
void Net_IRC_ListServers()
|
|
{
|
|
if ( irc_connected && irc_registered )
|
|
Net_IRC_SendMessage("LIST");
|
|
}
|
|
|
|
|
|
//A return of qtrue means the message was able to be sent, not that you
|
|
//were actually able to join the channel
|
|
qboolean Net_IRC_JoinChannel(const char *channel)
|
|
{
|
|
if (irc_connected && irc_registered) {
|
|
Net_IRC_SendMessage(va("JOIN %s", channel));
|
|
return qtrue;
|
|
}
|
|
return qfalse;
|
|
}
|
|
|
|
void Net_IRC_SendChat(const char *channel, const char *message)
|
|
{
|
|
if (irc_connected && irc_registered)
|
|
{
|
|
char msg[ 2048 ];
|
|
Com_sprintf( msg, sizeof(msg), "PRIVMSG %s : %s", channel, message );
|
|
Net_IRC_SendMessage( msg );
|
|
}
|
|
}
|
|
|
|
void Net_IRC_Init()
|
|
{
|
|
if (irc_server.socket == 0 ) {
|
|
irc_server.type = NA_TCP;
|
|
irc_server.socket = NET_IPSocket(IRC_SERVER, IRC_PORT, NA_TCP);
|
|
if (irc_server.socket > 0)
|
|
{
|
|
irc_connected = qtrue;
|
|
} else {
|
|
Com_Error(ERR_DROP, "Unable to create socket");
|
|
}
|
|
} else {
|
|
Com_Error(ERR_DROP, "IRC Already Initialized");
|
|
}
|
|
}
|
|
|
|
void Net_IRC_Pump()
|
|
{
|
|
char buf[MAX_MSGLEN];
|
|
msg_t netmsg;
|
|
|
|
MSG_Init( &netmsg, buf, sizeof( buf ) );
|
|
if ( Sys_GetPacketData ( &irc_server, &netmsg ) )
|
|
{
|
|
Net_IRC_ReadMessage(&netmsg);
|
|
}
|
|
}
|
|
|
|
void Net_IRC_Shutdown(const char *msg)
|
|
{
|
|
NET_Shutdown(irc_server.socket);
|
|
irc_registered = qfalse;
|
|
irc_connected = qfalse;
|
|
irc_server.socket = 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif |