/****************************************************************************
 *  NewCmds.AmIPlug - AmIRC Plugin
 *  Copyright (C) 1999 Joar Sivertsen <jsiv@start.no>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 ****************************************************************************
 *  $Id: newcmds.c 0.6.3 (5.11.99) $
 ****************************************************************************/

#include <newcmds.h>
#include <numerics.h>
#include <struct.h>

/*******************************************************************************/

__asm int	AMIPLUG_Hook_DCC(void) { return 0; }
__asm void	AMIPLUG_Cleanup(void) { }
__asm void	AMIPLUG_DoMenu(void) { }
__asm void	AMIPLUG_DoCTCP(void) { }

/*******************************************************************************/

__saveds __asm struct TagItem *AMIPLUG_Setup(void) { return NewCmdsTags; }

/*******************************************************************************/

__stdargs void	xsprintf(char *to, char *fmt, ...) { RawDoFmt(fmt, &fmt+1, (void(*))"\x16\xc0\x4e\x75", to); }

/*******************************************************************************/

void pdef(struct amiplug_functable *ft, char *type, char *txt, ...) {
	char buf[512];
	RawDoFmt(txt, (long *)&txt+1, (void(*))"\x16\xc0\x4e\x75", buf);
	ft->amiplug_out_defwin(ft, 3, type, buf);
}

/*******************************************************************************/

void sts(struct amiplug_functable *ft, ULONG dest, char *str, ...) {
	char buf[512], buf2[512];
	RawDoFmt(str, (long *)&str+1, (void(*))"\x16\xc0\x4e\x75", buf);
	switch(dest) {
		case MS: xsprintf(buf2, "MEMOSERV :%s", buf);	break;
		case NS: xsprintf(buf2, "NICKSERV :%s", buf);	break;
		case CS: xsprintf(buf2, "CHANSERV :%s", buf);	break;
		case SS: xsprintf(buf2, "STATSERV :%s", buf);	break;
		case HS: xsprintf(buf2, "HELPSERV :%s", buf);	break;
		case OS: xsprintf(buf2, "OPERSERV :%s", buf);	break;
		case ND: xsprintf(buf2, buf);			break;
		default:					return;
	}
	ft->amiplug_sendraw(ft, buf2, strlen(buf2));
}

/*******************************************************************************/

__saveds __asm int AMIPLUG_Hook_Rawline(register __a0 struct amiplug_functable *ft, register __a1 STRPTR line, register __d0 ULONG len) {
	char *lin = strdup(line), *from = strtok(lin, " "), *cmd = strtok(NULL, " "), *to = strtok(NULL, " "), *rest = strtok(NULL, "\0");
#ifdef UNSTABLE
	char	*matchhost	= "NickServ!service@dal.net",
		*matchline	= "If this is your nick",
		*nickpass	= "MyPass";
	if(from[0] == ':') from++;
	if(rest[0] == ':') rest++;
	if(!strcmp(from, matchhost) && !strcmp(cmd, "NOTICE") && !strncmp(rest, matchline, strlen(matchline))) {
		pdef(ft, "\033b«NewCmds»", "Auto-Identifying with NickServ");
		sts(ft, NS, "IDENTIFY %s\n", nickpass);
		return 0;
	} else 
#endif
	if(!strcmp(cmd, "RPONG")) pdef(ft, "\033b«RPong»", rest);
	else return 0;
	return 1;
}

/*******************************************************************************/

__saveds __asm int AMIPLUG_Hook_NumericMsg(	register __a0 struct amiplug_functable *ft,
						register __a1 STRPTR line,	register __d0 ULONG numeric,
						register __a2 STRPTR prefix,	register __a3 STRPTR dest,
						register __d1 ULONG numargs,	register __a5 STRPTR *args) {
	char *str = strdup(line), outbuf[2048], *arg1;

	strtok(str, " "); strtok(NULL, " "); strtok(NULL, " ");

	switch(numeric) {
		case ERR_SERVICESDOWN:
		case ERR_ONLYSERVERSCANCHANGE:
		case ERR_NEEDREGGEDNICK:
		case ERR_SILELISTFULL:
		case ERR_TOOMANYWATCH:
			strtok(NULL, " ");
			pdef(ft, "\033b«Error»", strtok(NULL, "\0")+1);
			return 1;
		case ERR_NOOPERMOTD:
		case ERR_NOTFORHALFOPS:
		case ERR_CANNOTKNOCK:
		case ERR_NOINVITE:
		case ERR_ADMONLY:
		case ERR_OPERONLY:
		case ERR_NORULES:	pdef(ft, "\033b«Error»", strtok(NULL, "\0")+1);	return 1;
		case ERR_LINKCHANNEL:	pdef(ft, "\033b«Error»", strtok(NULL, "\0"));	return 1;
		case RPL_WHOISREGNICK:
		case RPL_WHOISHELPOP:
		case RPL_WHOISBOT:
		case RPL_WHOISHOST: /* MOTD on some networks */
		case 325: /* 325 = "«Whois» Nick has sensitive ears" on CR */
			arg1 = strtok(NULL, "\0");
			if(arg1[0] == ':') pdef(ft, "\033b«MOTD»", arg1+1);
			else pdef(ft, "\033b«Whois»", "%s %s", strtok(arg1, " "), strtok(NULL, "\0")+1);
			return 1;
		case RPL_RULESSTART: /* 308 = "«Whois» Nick is a Services Agent" on CR */
		case RPL_ENDOFRULES: /* 309 = "«Whois» Nick prefers to speak in English" on CR */
		case RPL_RULES:
			arg1 = strtok(NULL, "\0");
			if(arg1[0] == ':') pdef(ft, "\033b«Rules»", arg1+1);
			else pdef(ft, "\033b«Whois»", "%s %s", strtok(arg1, " "), strtok(NULL, "\0")+1);
			return 1;
		case RPL_EXLIST:
			pdef(ft, "\033b«EBan List»", "Ban exception for channel %s: %s (set by %s)",
				strtok(NULL, " "), strtok(NULL, " "), strtok(NULL, " "));
			return 1;
		case RPL_ENDOFEXLIST:
			strtok(NULL, " ");
			pdef(ft, "\033b«EBan List»", strtok(NULL, "\0")+1);
			return 1;
		case RPL_CLOSING:	
			pdef(ft, "\033b«Close»", "%s %s", strtok(NULL, " "), strtok(NULL, "\0")+1);
			return 1;
		case RPL_CLOSEEND:
			pdef(ft, "\033b«Close»", "%s %s", strtok(NULL, ":"), strtok(NULL, "\0")+1);
			return 1;
		case RPL_WHOISMODES:	pdef(ft, "\033b«Whois»", strtok(NULL, "\0"));	return 1;
		case RPL_TRACECLASS:	pdef(ft, "\033b«Trace»", strtok(NULL, "\0"));	return 1;
		case RPL_STATSQLINE:
		case RPL_STATSXLINE:
		case RPL_STATSULINE:	pdef(ft, "\033b«Stats»", strtok(NULL, "\0"));	return 1;
		case RPL_STATSDEBUG:	pdef(ft, "\033b«Stats»", strtok(NULL, "\0")+1);	return 1;
		case RPL_HELPHDR:
		case RPL_HELPOP:
		case RPL_HELPTLR:
		case RPL_HELPHLP:
		case RPL_HELPFWD:
		case RPL_HELPIGN:	pdef(ft, "\033b«Help»", strtok(NULL, "\0")+1);	return 1;
		case RPL_MAP:
		case RPL_MAPMORE:
		case RPL_MAPEND:	pdef(ft, "\033b«Map»", strtok(NULL, "\0")+1);	return 1;
		case RPL_WATCHOFF:
			pdef(ft, "\033b«Watch»", "Stopped watching nick %s", strtok(NULL, " "));
			return 1;
		case RPL_WATCHSTAT:
		case RPL_ENDOFWATCHLIST:	pdef(ft, "\033b«Watch»", strtok(NULL, "\0")+1);	return 1;
		case RPL_NOWON:
		case RPL_LOGON:
		case RPL_LOGOFF:
			xsprintf(outbuf, "%s (%s@%s)", strtok(NULL, " "), strtok(NULL, " "), strtok(NULL, " "));
			strtok(NULL, " ");
			pdef(ft, "\033b«Watch»", "%s %s", outbuf, strtok(NULL, "\0")+1);
			return 1;
		case RPL_NOWOFF:
			xsprintf(outbuf, "%s", strtok(NULL, " "));
			strtok(NULL, " "); strtok(NULL, " "); strtok(NULL, " ");
			pdef(ft, "\033b«Watch»", "%s %s", outbuf, strtok(NULL, "\0")+1);
			return 1;
		case RPL_WATCHLIST:
			pdef(ft, "\033b«Watch»", "Watching nicks: %s", strtok(NULL, "\0")+1);
			return 1;
		case 396:
		case 399:	pdef(ft, "\033b«Set»", strtok(NULL, "\0")+1);	return 1;  /* ARCNet Virtual host */
		case 343:	pdef(ft, "\033b«News»", strtok(NULL, "\0"));	return 1; /* CR NewsFlash */
		default:
			break;
	}
	return 0;
}

/*******************************************************************************/

__saveds __asm void AMIPLUG_DoCommand(register __a0 struct amiplug_functable *ft, register __d0 ULONG id, register __a1 struct amiplug_cmdparm *parms) {
	switch(id) {
		case NEWCMDSVER:
			pdef(ft, "\033b«About»", "NewCmds.AmIPlug v%ld.%ld.%ld (%s). %s.",
				VERSION, MAJOR, MINOR, DATE, COPYRIGHT);
			break;
		case SERVICES:		sts(ft, ND, "SERVICES :%s\n", parms->parms);	break;
		case NICKSERV:		sts(ft, NS, "%s\n", parms->parms);		break;
		case CHANSERV:		sts(ft, CS, "%s\n", parms->parms);		break;
		case MEMOSERV:		sts(ft, MS, "%s\n", parms->parms);		break;
		case STATSERV:		sts(ft, SS, "%s\n", parms->parms);		break;
		case HELPSERV:		sts(ft, HS, "%s\n", parms->parms);		break;
		case OPERSERV:		sts(ft, OS, "%s\n", parms->parms);		break;
		case NS:		sts(ft, ND, "NS :%s\n", parms->parms);		break;
		case CS:		sts(ft, ND, "CS :%s\n", parms->parms);		break;
		case MS:		sts(ft, ND, "MS :%s\n", parms->parms);		break;
		case SS:		sts(ft, ND, "SS :%s\n", parms->parms);		break;
		case HS:		sts(ft, ND, "HS :%s\n", parms->parms);		break;
		case OS:		sts(ft, ND, "OS :%s\n", parms->parms);		break;
		case IDENTIFY:		sts(ft, ND, "IDENTIFY %s\n", parms->parms);	break;
		case MS_HELP:		sts(ft, MS, "HELP %s\n", parms->parms);		break;
		case MS_SEND:		sts(ft, MS, "SEND %s\n", parms->parms);		break;
		case MS_SENDSOP:	sts(ft, MS, "SENDSOP %s\n", parms->parms);	break;
		case MS_LIST:		sts(ft, MS, "LIST\n");				break;
		case MS_READ:		sts(ft, MS, "READ %s\n",parms->parms);		break;
		case MS_DEL:		sts(ft, MS, "DEL %s\n", parms->parms);		break;
		case MS_UNDEL:		sts(ft, MS, "UNDEL %s\n", parms->parms);	break;
		case MS_PURGE:		sts(ft, MS, "PURGE\n");				break;
		case MS_FORWARD:	sts(ft, MS, "FORWARD %s\n", parms->parms);	break;
		case NS_HELP:		sts(ft, NS, "HELP %s\n", parms->parms);		break;
		case NS_REGISTER:	sts(ft, NS, "REGISTER %s\n", parms->parms);	break;
		case NS_SET:		sts(ft, NS, "SET %s\n", parms->parms);		break;
		case NS_ACCESS:		sts(ft, NS, "ACCESS %s\n", parms->parms);	break;
		case NS_IDENTIFY:	sts(ft, ND, "IDENTIFY %s\n", parms->parms);	break;
		case NS_RECOVER:	sts(ft, NS, "RECOVER %s\n", parms->parms);	break;
		case NS_GHOST:		sts(ft, NS, "GHOST %s\n", parms->parms);	break;
		case NS_DROP:		sts(ft, NS, "DROP %s\n", parms->parms);		break;
		case NS_RELEASE:	sts(ft, NS, "RELEASE %s\n", parms->parms);	break;
		case NS_INFO:		sts(ft, NS, "INFO %s\n", parms->parms);		break;
		case NS_ACC:		sts(ft, NS, "ACC %s\n", parms->parms);		break;
		case CS_HELP:		sts(ft, CS, "HELP %s\n", parms->parms);		break;
		case CS_REGISTER:	sts(ft, CS, "REGISTER %s\n", parms->parms);	break;
		case CS_SET:		sts(ft, CS, "SET %s\n", parms->parms);		break;
		case CS_SOP:		sts(ft, CS, "SOP %s\n", parms->parms);		break;
		case CS_AOP:		sts(ft, CS, "AOP %s\n", parms->parms);		break;
		case CS_AKICK:		sts(ft, CS, "AKICK %s\n", parms->parms);	break;
		case CS_DROP:		sts(ft, CS, "DROP %s\n", parms->parms);		break;
		case CS_IDENTIFY:	sts(ft, CS, "IDENTIFY %s\n", parms->parms);	break;
		case CS_ACCESS:		sts(ft, CS, "ACCESS %s\n", parms->parms);	break;
		case CS_OP:		sts(ft, CS, "OP %s\n", parms->parms);		break;
		case CS_DEOP:		sts(ft, CS, "DEOP %s\n", parms->parms);		break;
		case CS_INFO:		sts(ft, CS, "INFO %s\n", parms->parms);		break;
		case CS_INVITE:		sts(ft, CS, "INVITE %s\n", parms->parms);	break;
		case CS_MKICK:		sts(ft, CS, "MKICK %s\n", parms->parms);	break;
		case CS_MDEOP:		sts(ft, CS, "MDEOP %s\n", parms->parms);	break;
		case CS_UNBAN:		sts(ft, CS, "UNBAN %s\n", parms->parms);	break;
		case CS_COUNT:		sts(ft, CS, "COUNT %s\n", parms->parms);	break;
		case CS_WHY:		sts(ft, CS, "WHY %s\n", parms->parms);		break;
		case CMD_GLOBOPS:	sts(ft, ND, "GLOBOPS :%s\n", parms->parms);	break;
		case CMD_CHATOPS:	sts(ft, ND, "CHATOPS :%s\n", parms->parms);	break;
		case CMD_LOCOPS:	sts(ft, ND, "LOCOPS :%s\n", parms->parms);	break;
		case CMD_OPERWALL:	sts(ft, ND, "OPERWALL :%s\n", parms->parms);	break;
		case CMD_LWALLOPS:	sts(ft, ND, "LWALLOPS :%s\n", parms->parms);	break;
		case CMD_SWALLOPS:	sts(ft, ND, "SWALLOPS :%s\n", parms->parms);	break;
		case CMD_ADMCHAT:	sts(ft, ND, "ADMCHAT :%s\n", parms->parms);	break;
		case CMD_GOPER:		sts(ft, ND, "GOPER :%s\n", parms->parms);	break;
		case CMD_GNOTICE:	sts(ft, ND, "GNOTICE :%s\n", parms->parms);	break;
		case CMD_SNOTE:		sts(ft, ND, "SNOTE :%s\n", parms->parms);	break;
		case CMD_SNOTES:	sts(ft, ND, "SNOTES %s\n", parms->parms);	break;
		case CMD_CLOSE:		sts(ft, ND, "CLOSE\n");				break;
		case CMD_DNS:		sts(ft, ND, "DNS\n");				break;
		case CMD_HTM:		sts(ft, ND, "HTM %s\n", parms->parms);		break;
		case CMD_SET:		sts(ft, ND, "SET %s\n", parms->parms);		break;
		case CMD_ADDLINE:	sts(ft, ND, "ADDLINE :%s\n", parms->parms);	break;
		case CMD_SAMODE:	sts(ft, ND, "SAMODE %s\n", parms->parms);	break;
		case CMD_SAJOIN:	sts(ft, ND, "SAJOIN %s\n", parms->parms);	break;
		case CMD_MKPASSWD:	sts(ft, ND, "MKPASSWD %s\n", parms->parms);	break;
		case CMD_KLINE:
			sts(ft, ND, "KLINE %s :%s\n",
				strtok(parms->parms, " "), strtok(NULL, "\0"));
			break;
		case CMD_UNKLINE:	sts(ft, ND, "UNKLINE %s\n", parms->parms);	break;
		case CMD_ZLINE:
			sts(ft, ND, "ZLINE %s :%s\n",
				strtok(parms->parms, " "), strtok(NULL, "\0"));
			break;
		case CMD_UNZLINE:	sts(ft, ND, "UNZLINE %s\n", parms->parms);	break;
		case CMD_AKILL:		sts(ft, ND, "AKILL %s\n", parms->parms);	break;
		case CMD_RAKILL:	sts(ft, ND, "RAKILL %s\n", parms->parms);	break;
		case CMD_UNAKILL:	sts(ft, ND, "UNAKILL %s\n", parms->parms);	break;
		case CMD_REMGLINE:	sts(ft, ND, "REMGLINE %s\n", parms->parms);	break;
		case CMD_DIE:
			ft->amiplug_out_defwin(ft, 3, "\033b«Warning»",
				"If you really want to terminate the server, please use /SHUTDOWN.");
			break;
		case CMD_SHUTDOWN:	sts(ft, ND, "DIE %s\n", parms->parms);		break;
		case CMD_HELPOP:	sts(ft, ND, "HELPOP %s\n", parms->parms);	break;
		case CMD_USRIP:		sts(ft, ND, "USRIP %s\n", parms->parms);	break;
		case CMD_WATCH:		sts(ft, ND, "WATCH %s\n", parms->parms);	break;
		case CMD_SHELP:		sts(ft, ND, "HELP %s\n", parms->parms);		break;
		case CMD_ADULT:		sts(ft, ND, "ADULT\n");				break;
		case CMD_KID:		sts(ft, ND, "KID\n");				break;
		case CMD_CNOTICE:
			sts(ft, ND, "CNOTICE %s %s :%s\n",
				strtok(parms->parms, " "), strtok(NULL, " "), strtok(NULL, "\0"));
			break;
		case CMD_CMSG:
			sts(ft, ND, "CMSG %s %s :%s\n",
				strtok(parms->parms, " "), strtok(NULL, " "), strtok(NULL, "\0"));
			break;
		case CMD_SUMODE:	sts(ft, ND, "UMODE %s\n", parms->parms);	break;
		case CMD_RULES:		sts(ft, ND, "RULES\n", parms->parms);		break;
		case CMD_KNOCK:
			sts(ft, ND, "KNOCK %s :%s\n",
				strtok(parms->parms, " "), strtok(NULL, "\0"));
			break;
		case CMD_LICENSE:	sts(ft, ND, "LICENSE %s\n", parms->parms);	break;
		case CMD_SETNAME:	sts(ft, ND, "SETNAME :%s\n", parms->parms);	break;
		case CMD_CREDITS:	sts(ft, ND, "CREDITS %s\n", parms->parms);	break;
		case CMD_DALINFO:	sts(ft, ND, "DALINFO %s\n", parms->parms);	break;
		case CMD_ADDMOTD:	sts(ft, ND, "ADDMOTD :%s\n", parms->parms);	break;
		case CMD_ADDOMOTD:	sts(ft, ND, "ADDOMOTD :%s\n", parms->parms);	break;
		case CMD_OPERMOTD:	sts(ft, ND, "OPERMOTD\n");			break;
		case CMD_SETHOST:	sts(ft, ND, "SETHOST %s\n", parms->parms);	break;
		case CMD_PASS:		sts(ft, ND, "PASS %s\n", parms->parms);		break;
		case CMD_SETIDENT:	sts(ft, ND, "SETIDENT %s\n", parms->parms);	break;
		case CMD_SDESC:		sts(ft, ND, "SDESC :%s\n", parms->parms);	break;
		case CMD_ADCHAT:	sts(ft, ND, "ADCHAT :%s\n", parms->parms);	break;
		case CMD_NACHAT:	sts(ft, ND, "NACHAT :%s\n", parms->parms);	break;
		case CMD_TECHAT:	sts(ft, ND, "TECHAT :%s\n", parms->parms);	break;
		case CMD_CHGHOST:	sts(ft, ND, "CHGHOST %s\n", parms->parms);	break;
		case CMD_TSCTL:		sts(ft, ND, "TSCTL %s\n", parms->parms);	break;
		case CMD_LAG:		sts(ft, ND, "LAG %s\n", parms->parms);		break;
		case CMD_SAPART:	sts(ft, ND, "SAPART %s\n", parms->parms);	break;
		case CMD_CHGIDENT:	sts(ft, ND, "CHGIDENT %s\n", parms->parms);	break;
		default:								break;
	}
}

/*******************************************************************************/

__saveds __asm long __UserLibInit(register __a6 struct Library *base) {
	base->lib_Node.ln_Pri = -128;
	return 0;
}
