/* Crimson2 Mud Server * All source written/copyright Ryan Haksi 1995 * * This source code is proprietary. Use in whole or in part without * explicity permission by the author is strictly prohibited * * Current email address(es): cryogen@infoserve.net * Phone number: (604) 591-5295 * * C4 Script Language written/copyright Cam Lesiuk 1995 * Email: clesiuk@engr.uvic.ca */ /* MOLE related commands */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <time.h> #ifndef WIN32 #include <unistd.h> #endif #include "crimson2.h" #include "macro.h" #include "log.h" #include "str.h" #include "queue.h" #include "send.h" #include "ini.h" #include "extra.h" #include "property.h" #include "file.h" #include "thing.h" #include "index.h" #include "edit.h" #include "history.h" #include "mem.h" #include "socket.h" #include "site.h" #include "exit.h" #include "world.h" #include "base.h" #include "object.h" #include "char.h" #include "affect.h" #include "fight.h" #include "mobile.h" #include "skill.h" #include "player.h" #include "parse.h" #include "area.h" #include "moledefs.h" #include "mole.h" #include "cmd_mole.h" #include "mole_msc.h" #include "mole_are.h" #include "mole_wld.h" #include "mole_mob.h" #include "mole_obj.h" #include "mole_rst.h" const CMDMOLELIST cmdMOLEList[] = { { MOLE_CMD_MORE, NULL, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_IDRQ, CmdMOLEidrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_IDEN, NULL, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_SYSR, CmdMOLEsysr, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_SYSD, NULL, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_ALRQ, CmdMOLEalrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_RLRQ, CmdMOLErlrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_WLRQ, CmdMOLEwlrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_MLRQ, CmdMOLEmlrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_OLRQ, CmdMOLEolrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_ADRQ, CmdMOLEadrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_WDRQ, CmdMOLEwdrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_MDRQ, CmdMOLEmdrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_ODRQ, CmdMOLEodrq, POS_DEAD, 1, LOG_NEVER, CF_MISC }, { MOLE_CMD_RLST, CmdMOLErlst, POS_DEAD, 1, LOG_NORMAL, CF_MISC }, { MOLE_CMD_ADTL, CmdMOLEadtl, POS_DEAD, 1, LOG_NORMAL, CF_MISC }, { MOLE_CMD_WDTL, CmdMOLEwdtl, POS_DEAD, 1, LOG_NORMAL, CF_MISC }, { MOLE_CMD_MDTL, CmdMOLEmdtl, POS_DEAD, 1, LOG_NORMAL, CF_MISC }, { MOLE_CMD_ODTL, CmdMOLEodtl, POS_DEAD, 1, LOG_NORMAL, CF_MISC }, { MOLE_CMD_ACPY, NULL, POS_DEAD, 1, LOG_NORMAL, CF_MISC }, { MOLE_CMD_WCPY, NULL, POS_DEAD, 1, LOG_NORMAL, CF_MISC }, { MOLE_CMD_MCPY, NULL, POS_DEAD, 1, LOG_NORMAL, CF_MISC }, { MOLE_CMD_OCPY, NULL, POS_DEAD, 1, LOG_NORMAL, CF_MISC }, { 0L, NULL, 0, 0, 0, 0 } }; CMDPROC(CmdMOLE) { /* void CmdProc(THING *thing, BYTE* cmd) */ SOCK *sock; UWORD offset; ULWORD pktCmd; LWORD i; BYTE buf[MOLE_PKT_MAX]; ULWORD pktID; LWORD virtual; ULWORD error; if ((!thing)||(!cmd)) return; sock=BaseControlFind(thing); if (!sock) return; /* Check to ensure this is a valid MOLE packet, and if not, * respond with an error message. */ if(MOLEParse(sock,cmd,&pktCmd)<0) { ParseCommand(thing,"YOUDUMBASSWHATTHEHELLDOESTHATMEAN"); return; } /* don't process MORE commands any further */ if (pktCmd==MOLE_CMD_MORE) { return; } /* strip off packet number */ if (MOLEGetQULWORD(sock,&pktID)<0) { ParseCommand(thing,"YOUDUMBASSWHATTHEHELLDOESTHATMEAN"); MOLEFlushQ(sock); return; } else { /* and our virtual number / extra data */ if (MOLEGetQLWORD(sock,&virtual)<0) virtual=-1; } error=MOLE_NACK_NOTIMPLEMENTED; /* Find command in cmdMOLEList (note this can't use TYPEFIND * because CmdMoleList is indexed off a ULWORD, not a BYTE*). */ for (offset=0; (cmdMOLEList[offset].mCmd)&&(cmdMOLEList[offset].mCmd!=pktCmd); offset++); /* if valid command found, process the sucker */ if ((cmdMOLEList[offset].mCmd)&&(cmdMOLEList[offset].mProc)) { /* As Ryan says, "Choke if they are too weeny" */ /* NOTE NOTE NOTE: Permission responsibilities have changed to * the individual procedures and cross referenced through the * parse.c command security system. The following are left in for * future expansion or customization. */ if (Character(sock->sHomeThing)->cLevel >= cmdMOLEList[offset].mLevel) { /* check position */ if (CmdMOLEPositionCheck(offset,thing)) { if (CmdMOLEFlagCheck(offset,sock,virtual)) { /* call command */ if (cmdMOLEList[offset].mProc) (*cmdMOLEList[offset].mProc)(sock,pktID,virtual); MOLEFlushQ(sock); return; } else { error=MOLE_NACK_PROTECTION; } } else { error=MOLE_NACK_POSITION; } } else { error=MOLE_NACK_AUTHORIZATION; } } /* return an error message if something went wrong */ i=0; if (pktID>=MOLE_PKID_START){ MOLEWriteULWORD(sock,pktID,buf,&i); } MOLEWriteULWORD(sock,error,buf,&i); if (error==MOLE_NACK_POSITION) { /* send current & required positions */ MOLEWriteULWORD(sock,Character(thing)->cPos,buf,&i); MOLEWriteULWORD(sock,cmdMOLEList[offset].mPos,buf,&i); } MOLESend(sock,buf,i,MOLE_CMD_NACK); MOLEFlushQ(sock); return; } BYTE CmdMOLEPositionCheck(LWORD i, THING *thing) { if (Character(thing)->cPos >= cmdMOLEList[i].mPos) return TRUE; return FALSE; } /* this proc does any flag checking & logging necessary */ BYTE CmdMOLEFlagCheck(LWORD i,SOCK *sock,LWORD virtual) { WORD area; BYTE returnCode; returnCode=TRUE; /* special flags check */ if (BITANY(cmdMOLEList[i].mFlag,CF_AREAEDIT)) { area=AreaOf(virtual); if (area<0) return TRUE; if (AreaIsEditor(area,sock->sHomeThing)==2) returnCode=TRUE; else if (Character(sock->sHomeThing)->cLevel>=LEVEL_CODER) returnCode=TRUE; else returnCode=FALSE; } if (returnCode==TRUE) { /* check for logging */ if( (cmdMOLEList[i].mLog==LOG_ALLWAYS) ||( (BIT(Plr(sock->sHomeThing)->pSystem, PS_LOG)) &&(cmdMOLEList[i].mLog==LOG_NORMAL) ) ) { LogStr(sock->sHomeThing->tSDesc->sText,CmdMOLELog(i,virtual)); } /* log area editing to area channel */ if( (cmdMOLEList[i].mLog>=LOG_NORMAL) &&(BIT(cmdMOLEList[i].mFlag,CF_AREAEDIT)) ) { Log(LOG_AREA,sock->sHomeThing->tSDesc->sText); LogPrintf(LOG_AREA,CmdMOLELog(i,virtual)); } if( (cmdMOLEList[i].mLog>=LOG_NORMAL) &&(BIT(cmdMOLEList[i].mFlag,CF_GOD)) ) { Log(LOG_GOD,sock->sHomeThing->tSDesc->sText); LogPrintf(LOG_GOD,CmdMOLELog(i,virtual)); } } return returnCode; } /* this proc returns a string containing an appropriate log blurb. */ /* NOTE: the returned string is SHARED - it's reused each time * this proc is called, so it's only good until the next call * to this function! */ BYTE *CmdMOLELog(LWORD i,LWORD virtual) { static BYTE buf[100]; sprintf(buf," xxxx %li\n",virtual); buf[1]=(cmdMOLEList[i].mCmd>>24)&0xFF; buf[2]=(cmdMOLEList[i].mCmd>>16)&0xFF; buf[3]=(cmdMOLEList[i].mCmd>>8)&0xFF; buf[4]=(cmdMOLEList[i].mCmd)&0xFF; return buf; }