/
Crimson2/alias/
Crimson2/area.tmp/
Crimson2/area.tmp/AnomalySpaceDock/
Crimson2/area.tmp/AnomalyStation/
Crimson2/area.tmp/AntHill/
Crimson2/area.tmp/ArcticTerrarium/
Crimson2/area.tmp/BuilderCity/
Crimson2/area.tmp/Dungeon/
Crimson2/area.tmp/MiningDock/
Crimson2/area.tmp/PipeSystem/
Crimson2/area.tmp/RattArea/
Crimson2/area.tmp/RobotFactory/
Crimson2/area.tmp/SilverDale/
Crimson2/area.tmp/StarshipFearless/
Crimson2/area.tmp/StationConduits/
Crimson2/area.tmp/TerrariumAlpha/
Crimson2/area.tmp/TerrariumBeta/
Crimson2/area.tmp/TestArea/
Crimson2/area.tmp/Void/
Crimson2/area/
Crimson2/area/AnomalySpaceDock/
Crimson2/area/AnomalyStation/
Crimson2/area/MiningDock/
Crimson2/area/PipeSystem/
Crimson2/area/SilverDale/
Crimson2/area/StationConduits/
Crimson2/area/Void/
Crimson2/board/
Crimson2/clone/
Crimson2/lib/
Crimson2/mole/
Crimson2/mole/mole_src/HELP/
Crimson2/player/
Crimson2/util/
Crimson2/wldedit/
Crimson2/wldedit/res/
/* part of Crimson2 */
/* Written by B. Cameron Lesiuk, 1997 */
/* Written for use with Crimson2 MUD (written/copyright Ryan Haksi 1995).
 * This source is proprietary. Use of this code without permission from 
 * Ryan Haksi or Cam Lesiuk is strictly prohibited. 
 * 
 * (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 "code.h"
#include "moledefs.h"
#include "mole.h"
#include "mole_msc.h"

CMDMOLEPROC(CmdMOLEolrq) { /* CmdMOLEProc( SOCK *sock, ULWORD *pktID, LWORD virtual) */
  BYTE    buf[MOLE_PKT_MAX];
  LWORD   i=0;
  WORD    area;
  LWORD   k;

  if (pktID<MOLE_PKID_START)
    return;

  MOLEWriteULWORD(sock,pktID,buf,&i);

  /* Check security */
  if (!MOLECommandCheck(sock,"olist",virtual)) {
    MOLEWriteULWORD(sock,MOLE_NACK_AUTHORIZATION,buf,&i);
    MOLESend(sock,buf,i,MOLE_CMD_NACK);
    MOLEFlushQ(sock);
    return;
  }

  /* first, we need to find the specified area */
  area=AreaOf(virtual);
  if (area<0) {
    /* didn't find specified area - return nack */
    MOLEWriteULWORD(sock,MOLE_NACK_NODATA,buf,&i);
    MOLESend(sock,buf,i,MOLE_CMD_NACK);
  } else { /* we found the area - now send the list */
    MOLEWriteULWORD(sock,virtual,buf,&i);
    for (k=0;k<areaList[area].aObjIndex.iNum;k++) {
      MOLEWriteBuf(sock,ObjTemplate(areaList[area].aObjIndex.iThing[k])->oSDesc->sText,buf,&i);
      MOLEWriteULWORD(sock,ObjTemplate(areaList[area].aObjIndex.iThing[k])->oVirtual,buf,&i);
    }
    MOLESend(sock,buf,i,MOLE_CMD_OLST);
  }
}

CMDMOLEPROC(CmdMOLEodrq) { /* CmdMOLEProc( SOCK *sock, ULWORD *pktID, LWORD virtual) */
  BYTE         buf[MOLE_PKT_MAX];
  LWORD        i=0;
  OBJTEMPLATE *object;
  EXTRA       *extra;
  PROPERTY    *prop;
  ULWORD       k;
  WORD         field;


  if (pktID<MOLE_PKID_START)
    return;

  MOLEWriteULWORD(sock,pktID,buf,&i);

  /* Check security */
  if (!MOLECommandCheck(sock,"ostat",virtual)) {
    MOLEWriteULWORD(sock,MOLE_NACK_AUTHORIZATION,buf,&i);
    MOLESend(sock,buf,i,MOLE_CMD_NACK);
    MOLEFlushQ(sock);
    return;
  }

  /* first, we need to find the object */
  object=ObjectOf(virtual);
  if (object) {
    /* we found it - provide data */
    MOLEWriteULWORD(sock,object->oVirtual,buf,&i);
    MOLEWriteBuf(sock,object->oKey->sText,buf,&i);
    MOLEWriteBuf(sock,object->oSDesc->sText,buf,&i);
    MOLEWriteBuf(sock,object->oLDesc->sText,buf,&i);
    MOLEWriteBuf(sock,object->oDesc->sText,buf,&i);
    MOLEWriteULWORD(sock,object->oType,buf,&i);
    MOLEWriteULWORD(sock,object->oAct,buf,&i);
    MOLEWriteULWORD(sock,object->oWear,buf,&i);
    MOLEWriteULWORD(sock,object->oWeight,buf,&i);
    MOLEWriteULWORD(sock,object->oValue,buf,&i);
    MOLEWriteULWORD(sock,object->oRent,buf,&i);

    /* send details */
    for (field=0;*(oTypeList[object->oType].oField[field]);field++) {
      MOLEWriteULWORD(sock,ObjectGetField(object->oType,
        &(object->oDetail),field),buf,&i);
    }

    /* send apply list */
    MOLEWriteULWORD(sock,OBJECT_MAX_APPLY,buf,&i);
    for (k=0;k<OBJECT_MAX_APPLY;k++) {
      MOLEWriteULWORD(sock,(object->oApply)[k].aType,buf,&i);
      MOLEWriteULWORD(sock,(object->oApply)[k].aValue,buf,&i);
    }

    /* send extra list */
    /* first, count the number of extras */
    k=0;
    for (extra=object->oExtra;extra;extra=extra->eNext) {
      k++;
    }
    MOLEWriteULWORD(sock,k,buf,&i);
    /* and now send the extras. */
    for (extra=object->oExtra;extra;extra=extra->eNext) {
      MOLEWriteBuf(sock,extra->eKey->sText,buf,&i);
      MOLEWriteBuf(sock,extra->eDesc->sText,buf,&i);
    }
    /* send property list */
    /* You'll note we need to worry about 
     * DECOMPILING properties if they're code 
     * properties, prior to transmission! Whoops! */
    k=0;
    for (prop=object->oProperty;prop;prop=prop->pNext) {
      k++;
    }
    MOLEWriteULWORD(sock,k,buf,&i);
    for (prop=object->oProperty;prop;prop=prop->pNext) {
      /* note this CodeDecompProperty will check 
       * if it's compiled or not, so we don't 
       * have to pre-check before calling it. */
      CodeDecompProperty(prop,NULL);
      object->oCompile=1; /* compile on demand enabled */
      MOLEWriteBuf(sock,prop->pKey->sText,buf,&i);
      MOLEWriteBuf(sock,prop->pDesc->sText,buf,&i);
    }
    /* and send the sucker */
    MOLESend(sock,buf,i,MOLE_CMD_ODTL);
  } else {
    /* didn't find specified object - return nack */
    MOLEWriteULWORD(sock,MOLE_NACK_NODATA,buf,&i);
    MOLESend(sock,buf,i,MOLE_CMD_NACK);
  }
}

CMDMOLEPROC(CmdMOLEodtl) { /* CmdMOLEProc( SOCK *sock, ULWORD *pktID, LWORD virtual) */
  BYTE         buf[MOLE_PKT_MAX];
  LWORD        i=0;
  OBJTEMPLATE *object;
  LWORD        rc;      /* return code */
  ULWORD       data;
  STR         *strData;
  STR         *strKey;
  STR         *strDesc;
  LWORD        counter;
  LWORD        k;
  WORD         field;

  if (pktID<MOLE_PKID_START)
    return;

  MOLEWriteULWORD(sock,pktID,buf,&i);

  /* Check security */
  if (!MOLECommandCheck(sock,"odesc",virtual)) {
    MOLEWriteULWORD(sock,MOLE_NACK_AUTHORIZATION,buf,&i);
    MOLESend(sock,buf,i,MOLE_CMD_NACK);
    MOLEFlushQ(sock);
    return;
  }

  /* first, we need to find the object */
  object=ObjectOf(virtual);
  if (object) {
    /* first, mark area as changed */
    BITSET(areaList[AreaOf(virtual)].aSystem,AS_OBJUNSAVED);
    object->oCompile=1; /* compile on demand enabled */
    /* Ok, let's read in our new MOB stats */
    if ((!(rc=MOLEGetQStr(sock,&strData)))) {
      StrFree(object->oKey);
      object->oKey=strData;
    }
    if ((!rc)&&(!(rc=MOLEGetQStr(sock,&strData)))) {
      StrFree(object->oSDesc);
      object->oSDesc=strData;
    }
    if ((!rc)&&(!(rc=MOLEGetQStr(sock,&strData)))) {
      StrFree(object->oLDesc);
      object->oLDesc=strData;
    }
    if ((!rc)&&(!(rc=MOLEGetQStr(sock,&strData)))) {
      StrFree(object->oDesc);
      object->oDesc=strData;
    }

    /* note I do the following with all ULWORDs because
     * then I don't actually care what the specific size
     * or sign of the numerical value is... the compiler
     * will sort it all out and do the appropriate conversion. */
    if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
      object->oType=data;
    if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
      object->oAct=data;
    if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
      object->oWear=data;
    if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
      object->oWeight=data;
    if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
      object->oValue=data;
    if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
      object->oRent=data;

    /* get details */
    for (field=0;(*(oTypeList[object->oType].oField[field]))&&(!rc);field++) {
      if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
        ObjectSetField(object->oType, &(object->oDetail),field,data);
    }

    /* get apply list */
    if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
      counter=data;
    for(k=0;(k<counter)&&(!rc);k++) {
      if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
        (object->oApply)[k].aType=data;
      if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
        (object->oApply)[k].aValue=data;
    }

    /* get extra list */
    counter=0;
    if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
      counter=data;                /* counter=#extras */
    /* extra list - first we need to delete our old ones */
    if (!rc)
      while(object->oExtra)
        object->oExtra=ExtraFree(object->oExtra,object->oExtra);
    while((counter>0)&&(!rc)) {
      strKey=strDesc=NULL;
      rc=MOLEGetQStr(sock,&strKey);
      if (!rc)
        rc=MOLEGetQStr(sock,&strDesc);
      if (!rc) {
        object->oExtra=ExtraAlloc(object->oExtra,strKey,strDesc);
      } else {
        if (strKey) StrFree(strKey);
        if (strDesc) StrFree(strDesc);
      }
      counter--;
    }
    /* get property list */
    counter=0;
    if ((!rc)&&(!(rc=MOLEGetQULWORD(sock,&data)))) 
      counter=data;                /* counter=#properties */
    /* property list - first we need to delete our old ones */
    if (!rc)
      while(object->oProperty)
        object->oProperty=PropertyFree(object->oProperty,object->oProperty);
    while((counter>0)&&(!rc)) {
      strKey=strDesc=NULL;
      rc=MOLEGetQStr(sock,&strKey);
      if (!rc)
        rc=MOLEGetQStr(sock,&strDesc);
      if (!rc) {
        object->oProperty=PropertyCreate(object->oProperty,strKey,strDesc);
      } else {
        if (strKey) StrFree(strKey);
        if (strDesc) StrFree(strDesc);
      }
      counter--;
    }
    MOLESend(sock,buf,i,MOLE_CMD_ACKP);
  } else {
    /* didn't find specified object - return nack */
    MOLEWriteULWORD(sock,MOLE_NACK_NODATA,buf,&i);
    MOLESend(sock,buf,i,MOLE_CMD_NACK);
  }
  return;
}