/*                  _________   __    ___   ___   ___               _________   _________   ___
                   /  ______/  /  |  /  /  /  /  /  /              /  ______/  /  ___   /  /  /
                  /  /        /   | /  /  /  /  /  /  _________   /  /        /  /__/  /  /  /
                 /  / ____   /  | |/  /  /  /  /  /  /        /  /  / ____   /  ______/  /  /
                /  / /_  /  /  /| |  /  /  /  /  /  /________/  /  / /_  /  /  /        /  /
               /  /___/ /  /  / |   /  /  /__/  /              /  /___/ /  /  /        /  /_____
              /________/  /__/  |__/  /________/              /________/  /__/        /________/
          _________   ___   ___    ______     _______     ________   _________     ______     __    ___
         /  ______/  /  /  /  /  _/     /_   /  ___  |   /  __   /  /___  ___/   _/     /_   /  |  /  /
        /  /        /  /  /  /  /  _/_   /  /  /  /  /  /  / /   /     / /      /  _/_   /  /   | /  /
       /  / ____   /  /  /  /  /  /__/  /  /  /__/ _/  /  /  /  /     / /      /  /__/  /  /  | |/  /
      /  / /_  /  /  /  /  /  /  ___   /  /  ___  /   /  / _/  /     / /      /  ___   /  /  /| |  /
     /  /___/ /  /  /__/  /  /  /  /  /  /  /  /  |  /  /_/  _/  ___/ /___   /  /  /  /  /  / |   /
    /________/  /________/  /__/  /__/  /__/  /__/  /_______/   /________/  /__/  /__/  /__/  |__/

	Guardian
	Copyright (C) 2004-2005 Paul Taylor

	Guardian is free software; you can redistribute it and/or modify it under
	the terms of the GNU General Public License as published by the Free
	Software Foundation; either version 2, or (at your option) any later
	version.

	The Guardian plugin and plugin source 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 General Public License for more details.

	You should be able to get a copy of the GNU General Public License at:
	*  http://www.gnu.org/copyleft/gpl.html
	Or, if these sites do not work, write to the Free Software Foundation,
	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#ifndef __GUARDIAN_H__
#define __GUARDIAN_H__

#define vMajor 0x02
#define vMinor 0x00
#define vBuild 0x0A

#include <ppsdk/s-pluginapi.h>

#define negtvOne 0xFFFFFFFFL
#define GuestCRC 0x5905F923L
#define GuestCtr 0xCF07309CL
#define MAGICLNG 0x9602C9BFL

#define INT_BADGE  0x00000001
#define INT_CLNBLS 0x00000002
#define INT_LOGOUT 0x00000004

#define fChk 0x0800

#define MaxAdm 32
#define MaxGrp 32
#define MaxStr 32
#define MaxBls 64
#define MaxIpt 64
#define MaxTxt 256
#define MaxCmd 384

#define MOD_INT 0x5F544E49L // 'INT_'
#define MOD_PKT 0x5F544B50L // 'PKT_'
#define MOD_CMD 0x5F444D43L // 'CMD_'
#define MOD_TLK 0x5F4B4C54L // 'TLK_'
#define MOD_WHS 0x5F534857L // 'WHS_'
#define MOD_IPT 0x5F545049L // 'IPT_'

  ServerConfiguration cfg;

#define CPP_ADM 0x6D64612FL // '/adm'
#define CPP_MOD 0x646F6D2FL // '/mod'
#define CPP_GRP 0x7072672FL // '/grp'

enum
{
	CFG_ADM,
	CFG_MOD,
	CFG_GRP,
	nbrCfg
};

  static uint8 *cfgLst[nbrCfg];

#define hMskLen 13
  static const sint8 hMsk[hMskLen] = "EFGHABCDMNOPI";

#define wMskLen 62

  static const sint8 wMsk[wMskLen] =
{
	'0', 'W', 'A', 'f', 'L', 'y', 'O', 'r',
	's', 't', 'Q', 'g', 'h', 'C', '1', '5',
	'6', 'D', 'u', 'U', '7', 'd', 'v', 'p',
	'q', '2', '3', 'N', '8', 'w', 'E', 'z',
	'F', 'V', '9', 'X', 'c', 'k', 'M', 'P',
	'I', 'R', 'S', 'T', 'Y', 'J', 'e', 'i',
	'j', 'm', 'n', 'Z', 'G', 'H', 'B', 'a',
	'b', 'l', '4', 'o', 'K', 'x'
};

  static const Str31 errLst[] =
{
	"root bless file not specified.\0",
	"command(s) file not specified.\0",
	"group bless file not specified.\0",
	"unable to load: %0.256s\0",
	"Input too long: %0.29s...\0",
	"Invalid character: %0.31s\0",
	"Invalid command: %0.31s\0",
	"Invalid packet: %0.4s\0",
	"Invalid privilege: %0.35s\0",
	"Unable to allocate memory (%s)\0",
	"Unknown rank: '%0.31s'\0",
	"Configuration reloaded.\0"
};

  static uint16 nbrCmd;
  static Str31 *cmdLst;

enum
{
	PRV_NON,
	PRV_TLK,
	PRV_WHS,
	PRV_ALL
};

  typedef struct
{
	uint8 intMsk;
	uint8 *cmdMsk;
	uint8 *pktMsk;
	uint8 nbrIpt;
	Str31 *iptLst;
} grdMsk;

  static grdMsk rstMsk;

enum
{
	RNK_LIMBO,
	RNK_GUEST,
	RNK_MEMBER,
	RNK_STAFF,
	RNK_WIZARD,
	RNK_OWNER,
	RNK_ROOT,
	nbrRnk
};

  static const Str7 rnkNme[nbrRnk] =
{
	"limbo\0",
	"guest\0",
	"member\0",
	"staff\0",
	"wizard\0",
	"owner\0",
	"root\0"
};

  static const sint8 rnkEqv[nbrRnk] =
{
	U_Guest,
	U_Guest,
	0x00,
	U_SuperUser,
	U_SuperUser,
	U_SuperUser | U_God,
	U_SuperUser | U_God
};

  static grdMsk *rnkLst;

  typedef struct
{
	Str31 nme;
	grdMsk msk;
} grpMgr;

  static uint8 nbrGrp;
  static grpMgr *grpLst;

  typedef struct
{
	uint8 rnk;
	uint8 grp;
	Str31 pwd;
	grdMsk msk;
} usrRec;

  typedef struct
{
	uint8 nbrPrp;
	AssetSpec Asset[9];
} prpRec;

  typedef struct
{
	UserID tID;
	usrRec usr;
	prpRec prp;
} usrMgr;

  typedef struct
{
	union
	{
		struct
		{
			uint32 ip;
		} i;
		struct
		{
			uint8 ip[4];
		} b;
	} nIP;
	union
	{
		struct
		{
			uint32 ip;
		} i;
		struct
		{
			uint8 ip[4];
		} b;
	} xIP;
} ipRec;

  typedef struct
{
	uint32 reg;
	uint32 puid;
    ipRec ip;
} blsRec;

  typedef struct
{
	Str31 nme;
	blsRec bls;
} admMgr;

  static uint8 nbrAdm;
  static admMgr *admLst;

  typedef struct
{
	Str31 nme;
	usrRec usr;
	blsRec bls;
	uint32 lst;
} blsMgr;

  static uint8 nbrBls;
  static blsMgr *blsLst;

  static const sint8 blsLyr[] =
{
	12, 13, MaxStr, MaxStr, MaxStr, MaxStr, 11, 36
};

#define nbrPkt 40
  static const sint32 pktLst[nbrPkt] =
{
    MSG_ASSETQUERY,     MSG_ASSETREGI,      MSG_BLOWTHRU,       MSG_DOORLOCK,
    MSG_DOORUNLOCK,     MSG_DRAW,           MSG_EXTENDEDINFO,   MSG_FILEQUERY,
    MSG_GMSG,           MSG_KILLUSER,       MSG_LISTOFALLROOMS, MSG_LISTOFALLUSERS,
    MSG_LOGOFF,         MSG_LOGON,          MSG_PICTMOVE,       MSG_PING,
    MSG_PONG,           MSG_PROPDEL,        MSG_PROPMOVE,       MSG_PROPNEW,
    MSG_RMSG,           MSG_ROOMGOTO,       MSG_ROOMNEW,        MSG_ROOMSETDESC,
    MSG_SMSG,           MSG_SPOTDEL,        MSG_SPOTMOVE,       MSG_SPOTNEW,
    MSG_SPOTSTATE,      MSG_SUPERUSER,      MSG_TALK,           MSG_USERCOLOR,
    MSG_USERDESC,       MSG_USERFACE,       MSG_USERMOVE,       MSG_USERNAME,
    MSG_USERPROP,       MSG_WHISPER,        MSG_XTALK,          MSG_XWHISPER
};

  static PluginID plgnID;
  static uint8 swtch = 1;
  static ServerUserRec *usrLst;
  static uint32 startTime, nbrUsr;

  static CommandResult cmdMain(ServerUserRec *, int, char *[]);
  static CommandResult cmdAddGrp(ServerUserRec *, int, char *[]);
  static CommandResult cmdAddGPrv(ServerUserRec *, int, char *[]);
  static CommandResult cmdAddUPrv(ServerUserRec *, int, char *[]);
  static CommandResult cmdBless(ServerUserRec *, int, char *[]);
  static CommandResult cmdBlsLst(ServerUserRec *, int, char *[]);
  static CommandResult cmdChngePass(ServerUserRec *, int, char *[]);
  static CommandResult cmdClnBls(ServerUserRec *, int, char *[]);
  static CommandResult cmdDelGrp(ServerUserRec *, int, char *[]);
  static CommandResult cmdDelGPrv(ServerUserRec *, int, char *[]);
  static CommandResult cmdDelUPrv(ServerUserRec *, int, char *[]);
  static CommandResult cmdGrpLst(ServerUserRec *, int, char *[]);
  static CommandResult cmdGrdLst(ServerUserRec *, int, char *[]);
  static CommandResult cmdLogOut(ServerUserRec *, int, char *[]);
  static uint8 fncLogOut(ServerUserRec *);
  static CommandResult cmdUnBless(ServerUserRec *, int, char *[]);

  static CommandResult cmdAccept(ServerUserRec *, int, char *[]);
  static CommandResult cmdOffer(ServerUserRec *, int, char *[]);
  static CommandResult cmdOfferAll(ServerUserRec *, int, char *[]);
  static CommandResult cmdSysop(ServerUserRec *, int, char *[]);
  static CommandResult cmdUpTime(ServerUserRec *, int, char *[]);

  static uint8 loadCfg(ServerUserRec *, uint8);
  static void saveMod();
  static uint8 loadMod(ServerUserRec *, uint8 *);
  static void saveBls();
  static uint8 loadBls(ServerUserRec *, uint8 *, uint8);
  static void addBls(ServerUserRec *, blsMgr *, uint8 *);
  static void txtBls(ServerUserRec *, blsMgr *);

  static void freeLst(uint8);
  static void bldUsr(ServerUserRec *, grdMsk *, uint8, uint8, uint8);
  static void bldUsrMsk(grdMsk *, grdMsk *, uint8);
  static void freeUsr(usrRec *, uint8, uint8);
  static void rldUsr(uint8);
  static void bldMsk(ServerUserRec *, grdMsk *);
  static uint8 cfgMsk(ServerUserRec *, grdMsk *, uint8 *, uint8, uint8);
  static void cfgIntMsk(uint8, uint8 *, uint8);
  static void freeMsk(grdMsk *, uint8, uint8);
  static void txtMsk(ServerUserRec *, grdMsk *);
  static void prntMsk(grdMsk *, FILE *, uint8);
  static void prntNL(FILE *, uint8, uint8, uint8);

  static uint8 fncCmds(uint8, ServerUserRec *, int, char *[]);
  static uint8 cmpBls(blsRec *, uint32, uint32, uint32);
  static void hPwd(uint8 *, uint8 *, uint8 *);
  static uint8 chrChk(ServerUserRec *, uint8 *);
  static void chngNme(ServerUserRec *, usrRec *, uint8 *, uint8 *);
  static void strtolower(uint8 *);
  static void rmvChr(uint8 *, uint8 *);
  static void rplChr(uint8 *, uint8 *, uint8 *);

  static uint8 fndRnkGrp(usrRec *, uint8 *);
  static uint8 *txtRnkGrp(usrRec *);
  static UserID GetTarget(ServerUserRec *);
  static uint8 *strtoken(uint8 *, uint8 *);
  static void rptUsr(ServerUserRec *, blsMgr *, uint8 *);
  static void rptErr(ServerUserRec *, uint8, uint8 *);

  static uint8 cvtIP2I(ipRec *, uint8 *);
  static void cvtI2IP(ipRec *, uint8 *, uint8);
  static uint32 cvtH2S(uint8 *);
  static void cvtS2H(uint32, uint8 *, uint8, uint8);

#endif /* __GUARDIAN_H__ */
