/*
	PalNFO
	Copyright (C) 2005-2006 Paul Taylor

	PalNFO 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 PalNFO 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 __PALNFO_H__
#define __PALNFO_H__

#include <pthread.h>
#include <ppsdk/s-pluginapi.h>

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

// Internal PreProc //

#define INT_PLGNAME	"PalNFO"
#define INT_PLGHOME	"http://palacecommunity.com"
#define INT_PLGCOPY	"Palace Community ( 2003 - 2006 ) [webmaster@palacecommunity.com] {GNU/GPL}"
#define INT_INIFILE	"psdata/palnfo.ini"

#define INT_INPTTPL	0x00008000L	//   32K
#define INT_INPTBFR	0x00002000L	//    8K	( INPTBFR >= INPTMAX )
#define INT_INPTMAX	0x00001000L	//    4K	( INPTBFR >= INPTMAX )
#define INT_STRBASE	sizeof( Str31 )	//   32B
#define INT_PTNBASE	0x00001000L	//    1K
#define INT_DEFTIME	0x0000003CL	//   60s

#define INT_GUESTCRC	0x5905F923L	//		Guest CRC
#define INT_GUESTCTR	0xCF07309CL	//		Guest Counter

// Template In/Out  //

enum
{
    IO_NONE,
    IO_INPUT,
    IO_OUTPUT,
    IO_OTHER,
    NBR_IO
};

// Template Type    //

#define TPL_NONE	0x00000000L

#define TPL_MAIN	0x00000001L
#define TPL_ROOM	0x00000002L
#define TPL_SRVR	0x00000004L
#define TPL_USER	0x00000008L

#define TPL_SRU		( TPL_SRVR | TPL_ROOM | TPL_USER )

#define ATR_FOOT	0x00000010L
#define ATR_HEAD	0x00000020L
#define ATR_LOOP	0x00000040L
#define ATR_SHELL	0x00000080L

// VarType Flags    //

enum
{
    VAR_NONE,
    VAR_STRING,
    VAR_INTEGER,
    VAR_SWITCH,
    VAR_OTHER,
    NBR_VAR
};

// Error Messages   //

#define ERR_EMPTYVAL	"ERROR: Empty Value for Variable: %0.31s..."
#define ERR_MAKETPL	"ERROR: Couldn't create template file: %0.255s"
#define ERR_NOCFG	"ERROR: Unable to open INI Conf: %0.255s..."
#define ERR_THREAD	"ERROR: Unable to create new thread ( %0.31s )..."
#define ERR_UNRECVAR	"ERROR: Unrecognized INI Variable: %0.31s..."

// Registered Cmds  //

#define NFO_ABOUT	"about"
#define NFO_RELOAD	"reload"

// Internal Values  //

#define CMD_DATETIME	"datetime"
#define CMD_INCREMENT	"incrementor"
#define CMD_PLGNHOME	"pluginhome"
#define CMD_PLGNNAME	"pluginname"
#define CMD_PLGNVER	"pluginversion"
#define CMD_PLGNCOPY	"plugincopyright"
#define CMD_TIMESTAMP	"timestamp"
#define CMD_UPDATEFREQ	"updatefreq"

// Key INI Commands //

#define CMD_CUSTOMPRPS  "customprops"
#define CMD_CYBORGS	"cyborgs"
#define CMD_DUMPSTARTUP	"dumpatstartup"
#define CMD_DUPIP	"duplicateips"
#define CMD_ESCSHELL	"escapeshell"
#define CMD_GUESTS	"guests"
#define CMD_LGS		"listguests"
#define CMD_LHRMS	"listhiddenrooms"
#define CMD_LHURS	"listhiddenusers"
#define CMD_LMRMS	"listmemrooms"
#define CMD_MRMS	"memberrooms"
#define CMD_MRMSCNT	"memroomscount"
#define CMD_PAINTING	"painting"
#define CMD_PALTPL	"palacetemplate"
#define CMD_RESET	"reset"
#define CMD_RMARTIST	"roomartist"
#define CMD_RMCLOSED	"roomclosed"
#define CMD_RMMAKE	"roomcreate"
#define CMD_RMCYBORG	"roomcyborg"
#define CMD_RMDEL	"roomdelete"
#define CMD_RMDROPZONE	"roomdropzone"
#define CMD_RMGUESTS	"roomguests"
#define CMD_RMH		"roomhidden"
#define CMD_RMID	"roomid"
#define CMD_RMLPRPS	"roomlooseprops"
#define CMD_RMMAXOCC	"roommaxocc"
#define CMD_RMM		"roommember"
#define CMD_RMNAME	"roomname"
#define CMD_RMOWNURID	"roomowneruserid"
#define CMD_RMPAINT	"roompaint"
#define CMD_RMPRI	"roomprivate"
#define CMD_RMSFOOT	"roomsfooter"
#define CMD_RMSHEAD	"roomsheader"
#define CMD_RMSHELL	"roomshell"
#define CMD_RMSNFO	"roomsnfo"
#define CMD_RMTPL	"roomtemplate"
#define CMD_RMTPLWRAP	"roomtemplatewrapper"
#define CMD_RMURCNT	"roomusercount"
#define CMD_RMWIZONLY	"roomwizonly"
#define CMD_SVRAVS	"serveravatars"
#define CMD_SVRENTRMID	"serverentranceroomid"
#define CMD_SVRFOOT	"serverfooter"
#define CMD_SVRHEAD	"serverheader"
#define CMD_SVRMAXOCC	"servermaxocc"
#define CMD_SVRMEDIA	"servermedia"
#define CMD_SVRNAME	"servername"
#define CMD_SVRNBRGURS	"servernbrguestusers"
#define CMD_SVRNBRHGURS	"servernbrhiddenguestusers"
#define CMD_SVRNBRHMRMS	"servernbrhiddenmemberrooms"
#define CMD_SVRNBRHRMS	"servernbrhiddenrooms"
#define CMD_SVRNBRHURS	"servernbrhiddenusers"
#define CMD_SVRNBRMRMS	"servernbrmemberrooms"
#define CMD_SVRNBRRMS	"servernbrrooms"
#define CMD_SVRNBRURS	"servernbrusers"
#define CMD_SVRNFO	"servernfo"
#define CMD_SVRRMMAXOCC	"serverroommaxocc"
#define CMD_SVRSHELL	"servershell"
#define CMD_SVRTPL	"servertemplate"
#define CMD_SVRTPLWRAP	"servertemplatewrapper"
#define CMD_SVRUPDATE	"serveruptimedatetime"
#define CMD_SVRUPTIME	"serveruptimetimestamp"
#define CMD_SVRURL	"serverurl"
#define CMD_SPOOFING	"spoofing"
#define CMD_THREAD	"thread"
#define CMD_TIMER	"timer"
#define CMD_TPLFOOT	"templatefooter"
#define CMD_TPLHEAD	"templateheader"
#define CMD_URENTR	"userenter"
#define CMD_URLOGON	"userlogon"
#define CMD_URLOGOFF	"userlogoff"
#define CMD_URGAG	"usergag"
#define CMD_URH		"userhidden"
#define CMD_URID	"userid"
#define CMD_URLACTDATE	"userlastactivedatetime"
#define CMD_URLACTTIME	"userlastactivetimestamp"
#define CMD_URLOGONDATE	"userlogondatetime"
#define CMD_URLOGONTIME	"userlogontimestamp"
#define CMD_URNAME	"username"
#define CMD_UROS	"useros"
#define CMD_URPIN	"userpin"
#define CMD_URPRPGAG	"userpropgag"
#define CMD_URRANK	"userrank"
#define CMD_URRJCTESP	"userrejectesp"
#define CMD_URRJCTPRI	"userrejectpri"
#define CMD_URRMID	"userroomid"
#define CMD_URRMNAME	"userroomname"
#define CMD_URSHELL	"usershell"
#define CMD_URSFOOT	"usersfooter"
#define CMD_URSHEAD	"usersheader"
#define CMD_URSNFO	"usersnfo"
#define CMD_URTPL	"usertemplate"
#define CMD_URTPLWRAP	"usertemplatewrapper"

// Standard Lib API //

  static const Str7 OnSwitches[ ] =
{
    "on", "t", "true", "y", "yes", "si", "\0"
};

  static const Str7 OffSwitches[ ] =
{
    "off", "f", "false", "n", "no", "0", "\0"
};

  static const Str7 NullSwitches[ ] =
{
    "empty", "nan", "nothing", "null", "\0"
};

  static const uint8 escChr[ ][2][3] =
{
    "\\r", "\r",
    "\\n", "\n",
    "\\t", "\t",
    "\\0", "\0",
    "\0",  "\0"
};

  typedef struct
{
    Str31 cmd;
    uint8 bit;
} Switch;

  typedef struct
{
    Str31 cmd;
    uint16 num;
} Numeric;

  typedef struct
{
    Str31 cmd;
    uint8 tpl;
    uint8 io;
    uint8 *ptr;
} Template;

  typedef struct
{
    Str31 cmd;
    uint8 tpl;
    uint8 var;
    uint8 *ptn;
    uint8 *off;
    uint8 *on;
} Flag;

  typedef struct
{
    pthread_t		id;
    pthread_attr_t	attr;
} PThrd;

  typedef struct
{
    Str31  date;
    uint32 time;
    uint32 uptime;
    uint32 inc;
    uint32 freqc;
    uint32 freqt;
    uint16 nbrRooms[4];		//	Perm/Visible, Perm/Hidden, Mem/Visible, Mem/Hidden
    uint16 nbrUsers[4];		//	Mem/Visible, Mem/Hidden, Guest/Visible, Guest/Hidden
    RoomID entrance;
    ServerUserRec *users;
    ServerRoomRec *rooms;
    ServerConfiguration *cfg;
    PThrd *pthrd;
} SvrCfg;

  static const uint8 Struct[ ] =
{
    TPL_MAIN | ATR_HEAD,
    TPL_SRVR | ATR_HEAD,
    TPL_SRVR,
    TPL_SRVR | ATR_FOOT,
    TPL_USER | ATR_HEAD,
    TPL_USER | ATR_LOOP,
    TPL_USER | ATR_FOOT,
    TPL_ROOM | ATR_HEAD,
    TPL_ROOM | ATR_LOOP,
    TPL_ROOM | ATR_FOOT,
    TPL_MAIN | ATR_FOOT,
    '\0'
};

  static Switch Switches[ ] =
{
    CMD_DUMPSTARTUP	, 1,
    CMD_DUPIP		, 1,
    CMD_ESCSHELL	, 1,
    CMD_LGS		, 0,
    CMD_LHRMS		, 0,
    CMD_LHURS		, 0,
    CMD_LMRMS		, 0,
    CMD_RESET		, 1,
    CMD_RMMAKE		, 0,
    CMD_RMDEL		, 0,
    CMD_RMTPLWRAP	, 0,
    CMD_SVRTPLWRAP	, 0,
    CMD_THREAD		, 1,
    CMD_URENTR		, 0,
    CMD_URLOGON		, 0,
    CMD_URLOGOFF	, 0,
    CMD_URTPLWRAP	, 0,
    "\0"		, 0
};

  static Numeric Numerics[ ] =
{
    CMD_TIMER		, INT_DEFTIME,
    "\0"		, 0
};

  static Template Templates[ ] =
{
    CMD_PALTPL		, TPL_MAIN | TPL_SRU		, IO_OUTPUT	, NULL,
    CMD_RMSFOOT		, TPL_ROOM | ATR_FOOT		, IO_INPUT	, NULL,
    CMD_RMSHEAD		, TPL_ROOM | ATR_HEAD		, IO_INPUT	, NULL,
    CMD_RMSNFO		, TPL_ROOM			, IO_INPUT	, NULL,
    CMD_RMSHELL		, TPL_ROOM | ATR_SHELL		, IO_OUTPUT	, NULL,
    CMD_RMTPL		, TPL_ROOM			, IO_OUTPUT	, NULL,
    CMD_SVRFOOT		, TPL_SRVR | ATR_FOOT		, IO_INPUT	, NULL,
    CMD_SVRHEAD		, TPL_SRVR | ATR_HEAD		, IO_INPUT	, NULL,
    CMD_SVRNFO		, TPL_SRVR			, IO_INPUT	, NULL,
    CMD_SVRSHELL	, TPL_SRVR | ATR_SHELL		, IO_OUTPUT	, NULL,
    CMD_SVRTPL		, TPL_SRVR			, IO_OUTPUT	, NULL,
    CMD_TPLFOOT		, TPL_MAIN | TPL_SRVR | ATR_FOOT, IO_INPUT	, NULL,
    CMD_TPLHEAD		, TPL_MAIN | TPL_SRVR | ATR_HEAD, IO_INPUT	, NULL,
    CMD_URSFOOT		, TPL_USER | ATR_FOOT		, IO_INPUT	, NULL,
    CMD_URSHEAD		, TPL_USER | ATR_HEAD		, IO_INPUT	, NULL,
    CMD_URSNFO		, TPL_USER			, IO_INPUT	, NULL,
    CMD_URSHELL		, TPL_USER | ATR_SHELL		, IO_OUTPUT	, NULL,
    CMD_URTPL		, TPL_USER			, IO_OUTPUT	, NULL,
    "\0"		, TPL_NONE			, IO_NONE	, NULL
};

  static Flag Flags[ ] =
{
    CMD_DATETIME	, TPL_NONE	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_INCREMENT	, TPL_NONE	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_PLGNCOPY	, TPL_NONE	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_PLGNHOME	, TPL_NONE	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_PLGNNAME	, TPL_NONE	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_PLGNVER		, TPL_NONE	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_TIMESTAMP	, TPL_NONE	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_UPDATEFREQ	, TPL_NONE	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_CUSTOMPRPS	, TPL_SRVR	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_CYBORGS		, TPL_SRVR	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_GUESTS		, TPL_SRVR	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_MRMS		, TPL_SRVR	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_PAINTING	, TPL_SRVR	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMARTIST	, TPL_ROOM	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_RMCLOSED	, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMCYBORG	, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMDROPZONE	, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMGUESTS	, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMH		, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMID		, TPL_ROOM	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_RMLPRPS		, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMMAXOCC	, TPL_ROOM	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_RMM		, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMNAME		, TPL_ROOM	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_RMOWNURID	, TPL_ROOM	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_RMPAINT		, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMPRI		, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_RMURCNT		, TPL_ROOM	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_RMWIZONLY	, TPL_ROOM	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_SPOOFING	, TPL_SRVR	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_SVRAVS		, TPL_SRVR	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_SVRENTRMID	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRMAXOCC	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRMEDIA	, TPL_SRVR	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_SVRNAME		, TPL_SRVR	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_SVRNBRGURS	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRNBRHGURS	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRNBRHMRMS	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRNBRHRMS	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRNBRHURS	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRNBRMRMS	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRNBRRMS	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRNBRURS	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRRMMAXOCC	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRUPDATE	, TPL_SRVR	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_SVRUPTIME	, TPL_SRVR	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_SVRURL		, TPL_SRVR	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_URGAG		, TPL_USER	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_URH		, TPL_USER	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_URID		, TPL_USER	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_URLACTDATE	, TPL_USER	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_URLACTTIME	, TPL_USER	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_URLOGONDATE	, TPL_USER	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_URLOGONTIME	, TPL_USER	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_URNAME		, TPL_USER	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_UROS		, TPL_USER	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_URPIN		, TPL_USER	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_URPRPGAG	, TPL_USER	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_URRANK		, TPL_USER	, VAR_INTEGER	, NULL	, NULL	, NULL,
    CMD_URRJCTESP	, TPL_USER	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_URRJCTPRI	, TPL_USER	, VAR_SWITCH	, NULL	, NULL	, NULL,
    CMD_URRMNAME	, TPL_USER	, VAR_STRING	, NULL	, NULL	, NULL,
    CMD_URRMID		, TPL_USER	, VAR_INTEGER	, NULL	, NULL	, NULL,
    "\0"		, TPL_NONE	, VAR_NONE	, NULL	, NULL	, NULL
};

  static SvrCfg sCfg;
  static uint16 timer;
  static sint32 svrStrtd = -1;

  static CommandResult PalNFO( ServerUserRec *, int, char *[ ] );

  static void createThread( const ServerState *, const uint8 * );
  static void createTemplate( );
  static void readTemplate( const FILE *, const uint8 *, const uint32 );
  static void writeTemplate( const FILE *, const uint8 *, const uint8 *, const uint8 );

  static void rprtErr( const ServerUserRec *, const uint8 *, const uint8 * );
  static uint8 freeVar( void **, const uint8 *, const uint32 );
  static uint8 LoadConfig( const ServerUserRec *, const uint8 * );

  static uint8 isOn( uint8 * );
  static uint8 isOff( uint8 * );
  static uint8 isNull( uint8 * );
  static uint8 isMode( uint8 * );
  static uint8 isGuest( ServerUserRec * );

  static uint8 * strlwr( const uint8 * );
  static uint8 * rmvchr( const uint8 *, const uint8 * );
  static uint8 * fndrpl( const uint8 *, const uint8 *, const uint8 *, const uint32, uint8 );
  static uint8 * escstr( const uint8 *, const uint32 );

  static sint32 getIndexbyName( uint8 *, void *, const uint8, const uint8 );

#endif /* __PALNFO_H__ */
