Added protocol .c .h

This commit is contained in:
Vatiken 2012-02-12 22:12:57 +00:00
parent b34c23da96
commit 01dc0b79b6
2 changed files with 3012 additions and 0 deletions

513
src/protocol.h Normal file
View file

@ -0,0 +1,513 @@
/******************************************************************************
Protocol snippet by KaVir. Released into the Public Domain in February 2011.
******************************************************************************/
#ifndef PROTOCOL_H
#define PROTOCOL_H
/******************************************************************************
Set your MUD_NAME, and change descriptor_t if necessary.
******************************************************************************/
#define MUD_NAME "tbaMUD"
typedef struct descriptor_data descriptor_t;
/******************************************************************************
If your mud supports MCCP (compression), uncomment the next line.
******************************************************************************/
/*
#define USING_MCCP
*/
/******************************************************************************
If your offer a Mudlet GUI for autoinstallation, put the path/filename here.
******************************************************************************/
/*
#define MUDLET_PACKAGE "1\nhttp://blah.org/download/MY_GUI.mpackage"
*/
/******************************************************************************
Symbolic constants.
******************************************************************************/
#define SNIPPET_VERSION 6 /* Helpful for debugging */
#define MAX_PROTOCOL_BUFFER 2048
#define MAX_VARIABLE_LENGTH 4096
#define MAX_OUTPUT_BUFFER 8192
#define MAX_MSSP_BUFFER 4096
#define SEND 1
#define ACCEPTED 2
#define REJECTED 3
#define TELOPT_CHARSET 42
#define TELOPT_MSDP 69
#define TELOPT_MSSP 70
#define TELOPT_MCCP 86 /* This is MCCP version 2 */
#define TELOPT_MSP 90
#define TELOPT_MXP 91
#define TELOPT_ATCP 200
#define MSDP_VAR 1
#define MSDP_VAL 2
#define MSDP_TABLE_OPEN 3
#define MSDP_TABLE_CLOSE 4
#define MSDP_ARRAY_OPEN 5
#define MSDP_ARRAY_CLOSE 6
#define MAX_MSDP_SIZE 100
#define MSSP_VAR 1
#define MSSP_VAL 2
#define UNICODE_MALE 9794
#define UNICODE_FEMALE 9792
#define UNICODE_NEUTER 9791
/******************************************************************************
Types.
******************************************************************************/
typedef enum
{
false,
true
} bool_t;
typedef enum
{
eUNKNOWN,
eNO,
eSOMETIMES,
eYES
} support_t;
typedef enum
{
eMSDP_NONE = -1, /* This must always be first. */
/* General */
eMSDP_CHARACTER_NAME,
eMSDP_SERVER_ID,
eMSDP_SERVER_TIME,
eMSDP_SNIPPET_VERSION,
/* Character */
eMSDP_AFFECTS,
eMSDP_ALIGNMENT,
eMSDP_EXPERIENCE,
eMSDP_EXPERIENCE_MAX,
eMSDP_EXPERIENCE_TNL,
eMSDP_HEALTH,
eMSDP_HEALTH_MAX,
eMSDP_LEVEL,
eMSDP_RACE,
eMSDP_CLASS,
eMSDP_MANA,
eMSDP_MANA_MAX,
eMSDP_WIMPY,
eMSDP_PRACTICE,
eMSDP_MONEY,
eMSDP_MOVEMENT,
eMSDP_MOVEMENT_MAX,
eMSDP_HITROLL,
eMSDP_DAMROLL,
eMSDP_AC,
eMSDP_STR,
eMSDP_INT,
eMSDP_WIS,
eMSDP_DEX,
eMSDP_CON,
eMSDP_STR_PERM,
eMSDP_INT_PERM,
eMSDP_WIS_PERM,
eMSDP_DEX_PERM,
eMSDP_CON_PERM,
/* Combat */
eMSDP_OPPONENT_HEALTH,
eMSDP_OPPONENT_HEALTH_MAX,
eMSDP_OPPONENT_LEVEL,
eMSDP_OPPONENT_NAME,
/* World */
eMSDP_AREA_NAME,
eMSDP_ROOM_EXITS,
eMSDP_ROOM_NAME,
eMSDP_ROOM_VNUM,
eMSDP_WORLD_TIME,
/* Configuration */
eMSDP_CLIENT_ID,
eMSDP_CLIENT_VERSION,
eMSDP_PLUGIN_ID,
eMSDP_ANSI_COLORS,
eMSDP_XTERM_256_COLORS,
eMSDP_UTF_8,
eMSDP_SOUND,
eMSDP_MXP,
/* GUI variables */
eMSDP_BUTTON_1,
eMSDP_BUTTON_2,
eMSDP_BUTTON_3,
eMSDP_BUTTON_4,
eMSDP_BUTTON_5,
eMSDP_GAUGE_1,
eMSDP_GAUGE_2,
eMSDP_GAUGE_3,
eMSDP_GAUGE_4,
eMSDP_GAUGE_5,
eMSDP_MAX /* This must always be last */
} variable_t;
typedef struct
{
variable_t Variable; /* The enum type of this variable */
const char *pName; /* The string name of this variable */
bool_t bString; /* Is this variable a string or a number? */
bool_t bConfigurable; /* Can it be configured by the client? */
bool_t bWriteOnce; /* Can only set this variable once */
bool_t bGUI; /* It's a special GUI configuration variable */
int Min; /* The minimum valid value or string length */
int Max; /* The maximum valid value or string length */
int Default; /* The default value for a number */
const char *pDefault; /* The default value for a string */
} variable_name_t;
typedef struct
{
bool_t bReport; /* Is this variable being reported? */
bool_t bDirty; /* Does this variable need to be sent again? */
int ValueInt; /* The numeric value of the variable */
char *pValueString; /* The string value of the variable */
} MSDP_t;
typedef struct
{
const char *pName; /* The name of the MSSP variable */
const char *pValue; /* The value of the MSSP variable */
const char *(*pFunction)();/* Optional function to return the value */
} MSSP_t;
typedef struct
{
int WriteOOB; /* Used internally to indicate OOB data */
bool_t bIACMode; /* Current mode - deals with broken packets */
bool_t bNegotiated; /* Indicates client successfully negotiated */
bool_t bBlockMXP; /* Used internally based on MXP version */
bool_t bTTYPE; /* The client supports TTYPE */
bool_t bNAWS; /* The client supports NAWS */
bool_t bCHARSET; /* The client supports CHARSET */
bool_t bMSDP; /* The client supports MSDP */
bool_t bATCP; /* The client supports ATCP */
bool_t bMSP; /* The client supports MSP */
bool_t bMXP; /* The client supports MXP */
bool_t bMCCP; /* The client supports MCCP */
support_t b256Support; /* The client supports XTerm 256 colors */
int ScreenWidth; /* The client's screen width */
int ScreenHeight; /* The client's screen height */
char *pMXPVersion; /* The version of MXP supported */
char *pLastTTYPE; /* Used for the cyclic TTYPE check */
MSDP_t **pVariables; /* The MSDP variables */
} protocol_t;
/******************************************************************************
Protocol functions.
******************************************************************************/
/* Function: ProtocolCreate
*
* Creates, initialises and returns a structure containing protocol data for a
* single user. This should be called when the descriptor is initialised.
*/
protocol_t *ProtocolCreate( void );
/* Function: ProtocolDestroy
*
* Frees the memory allocated by the specified structure. This should be
* called just before a descriptor is freed.
*/
void ProtocolDestroy( protocol_t *apProtocol );
/* Function: ProtocolNegotiate
*
* Negatiates with the client to see which protocols the user supports, and
* stores the results in the user's protocol structure. Call this when you
* wish to perform negotiation (but only call it once). It is usually called
* either immediately after the user has connected, or just after they have
* entered the game.
*/
void ProtocolNegotiate( descriptor_t *apDescriptor );
/* Function: ProtocolInput
*
* Extracts any negotiation sequences from the input buffer, and passes back
* whatever is left for the mud to parse normally. Call this after data has
* been read into the input buffer, before it is used for anything else.
*/
void ProtocolInput( descriptor_t *apDescriptor, char *apData, int aSize, char *apOut );
/* Function: ProtocolOutput
*
* This function takes a string, applies colour codes to it, and returns the
* result. It should be called just before writing to the output buffer.
*
* The special character used to indicate the start of a colour sequence is
* '\t' (i.e., a tab, or ASCII character 9). This makes it easy to include
* in help files (as you can literally press the tab key) as well as strings
* (where you can use \t instead). However players can't send tabs (on most
* muds at least), so this stops them from sending colour codes to each other.
*
* The predefined colours are:
*
* n: no colour (switches colour off)
* r: dark red R: bright red
* g: dark green G: bright green
* b: dark blue B: bright blue
* y: dark yellow Y: bright yellow
* m: dark magenta M: bright magenta
* c: dark cyan C: bright cyan
* w: dark white W: bright white
* o: dark orange O: bright orange
*
* So for example "This is \tOorange\tn." will colour the word "orange". You
* can add more colours yourself just by updating the switch statement.
*
* It's also possible to explicitly specify an RGB value, by including the four
* character colour sequence (as used by ColourRGB) within square brackets, eg:
*
* This is a \t[F010]very dark green foreground\tn.
*
* The square brackets can also be used to send unicode characters, like this:
*
* Boat: \t[U9973/B]
* Rook: \t[U9814/C]
*
* For example you might use 'B' to represent a boat on your ASCII map, or a 'C'
* to represent a castle - but players with UTF-8 support would actually see the
* appropriate unicode characters for a boat or a rook (the chess playing piece).
*
* The exact syntax is '\t' (tab), '[', 'U' (indicating unicode), then the decimal
* number of the unicode character (see http://www.unicode.org/charts), then '/'
* followed by the ASCII character/s that should be used if the client doesn't
* support UTF-8. The ASCII sequence can be up to 7 characters in length, but in
* most cases you'll only want it to be one or two characters (so that it has the
* same alignment as the unicode character).
*
* Finally, this function also allows you to embed MXP tags. The easiest and
* safest way to do this is via the ( and ) bracket options:
*
* From here, you can walk \t(north\t).
*
* However it's also possible to include more explicit MSP tags, like this:
*
* The baker offers to sell you a \t<send href="buy pie">pie\t</send>.
*
* Note that the MXP tags will automatically be removed if the user doesn't
* support MXP, but it's very important you remember to close the tags.
*/
const char *ProtocolOutput( descriptor_t *apDescriptor, const char *apData, int *apLength );
/******************************************************************************
Copyover save/load functions.
******************************************************************************/
/* Function: CopyoverGet
*
* Returns the protocol values stored as a short string. If your mud uses
* copyover, you should call this for each player and insert it after their
* name in the temporary text file.
*/
const char *CopyoverGet( descriptor_t *apDescriptor );
/* Function: CopyoverSet
*
* Call this function for each player after a copyover, passing in the string
* you added to the temporary text file. This will restore their protocol
* settings, and automatically renegotiate MSDP/ATCP.
*
* Note that the client doesn't recognise a copyover, and therefore refuses to
* renegotiate certain telnet options (to avoid loops), so they really need to
* be saved. However MSDP/ATCP is handled through scripts, and we don't want
* to have to save all of the REPORT variables, so it's easier to renegotiate.
*
* Client name and version are not saved. It is recommended you save these in
* the player file, as then you can grep to collect client usage stats.
*/
void CopyoverSet( descriptor_t *apDescriptor, const char *apData );
/******************************************************************************
MSDP functions.
******************************************************************************/
/* Function: MSDPUpdate
*
* Call this regularly (I'd suggest at least once per second) to flush every
* dirty MSDP variable that has been requested by the client via REPORT. This
* will automatically use ATCP instead if MSDP is not supported by the client.
*/
void MSDPUpdate( descriptor_t *apDescriptor );
/* Function: MSDPFlush
*
* Works like MSDPUpdate(), except only flushes a specific variable. The
* variable will only actually be sent if it's both reported and dirty.
*
* Call this function after setting a variable if you want it to be reported
* immediately, instead of on the next update.
*/
void MSDPFlush( descriptor_t *apDescriptor, variable_t aMSDP );
/* Function: MSDPSend
*
* Send the specified MSDP variable to the player. You shouldn't ever really
* need to do this manually, except perhaps when debugging something. This
* will automatically use ATCP instead if MSDP is not supported by the client.
*/
void MSDPSend( descriptor_t *apDescriptor, variable_t aMSDP );
/* Function: MSDPSendPair
*
* Send the specified strings to the user as an MSDP variable/value pair. This
* will automatically use ATCP instead if MSDP is not supported by the client.
*/
void MSDPSendPair( descriptor_t *apDescriptor, const char *apVariable, const char *apValue );
/* Function: MSDPSendList
*
* Works like MSDPSendPair, but the value is sent as an MSDP array.
*
* apValue should be a list of values separated by spaces.
*/
void MSDPSendList( descriptor_t *apDescriptor, const char *apVariable, const char *apValue );
/* Function: MSDPSetNumber
*
* Call this whenever an MSDP integer variable has changed. The easiest
* approach is to send every MSDP variable within an update function (and
* this is what the snippet does by default), but if the variable is only
* set in one place you can just move its MDSPSend() call to there.
*
* You can also this function for bools, chars, enums, short ints, etc.
*/
void MSDPSetNumber( descriptor_t *apDescriptor, variable_t aMSDP, int aValue );
/* Function: MSDPSetString
*
* Call this whenever an MSDP string variable has changed. The easiest
* approach is to send every MSDP variable within an update function (and
* this is what the snippet does by default), but if the variable is only
* set in one place you can just move its MDSPSend() call to there.
*/
void MSDPSetString( descriptor_t *apDescriptor, variable_t aMSDP, const char *apValue );
/* Function: MSDPSetTable
*
* Works like MSDPSetString, but the value is sent as an MSDP table.
*
* You must add the MSDP_VAR and MSDP_VAL manually, for example:
*
* sprintf( Buffer, "%c%s%c%s", (char)MSDP_VAR, Name, (char)MSDP_VAL, Value );
* MSDPSetTable( d, eMSDP_TEST, Buffer );
*/
void MSDPSetTable( descriptor_t *apDescriptor, variable_t aMSDP, const char *apValue );
/* Function: MSDPSetArray
*
* Works like MSDPSetString, but the value is sent as an MSDP array.
*
* You must add the MSDP_VAR before each element manually, for example:
*
* sprintf( Buffer, "%c%s%c%s", (char)MSDP_VAL, Val1, (char)MSDP_VAL, Val2 );
* MSDPSetArray( d, eMSDP_TEST, Buffer );
*/
void MSDPSetArray( descriptor_t *apDescriptor, variable_t aMSDP, const char *apValue );
/******************************************************************************
MSSP functions.
******************************************************************************/
/* Function: MSSPSetPlayers
*
* Stores the current number of players. The first time it's called, it also
* stores the uptime.
*/
void MSSPSetPlayers( int aPlayers );
/******************************************************************************
MXP functions.
******************************************************************************/
/* Function: MXPCreateTag
*
* Puts the specified tag into a secure line, if MXP is supported. If the user
* doesn't support MXP they will see the string unchanged, meaning they will
* see the <send> tags or whatever. You should therefore check for support and
* provide a different sequence for other users, or better yet just embed MXP
* tags for the ProtocolOutput() function.
*/
const char *MXPCreateTag( descriptor_t *apDescriptor, const char *apTag );
/* Function: MXPSendTag
*
* This works like MXPCreateTag, but instead of returning the string it sends
* it directly to the user. This is mainly useful for the <VERSION> tag.
*/
void MXPSendTag( descriptor_t *apDescriptor, const char *apTag );
/******************************************************************************
Sound functions.
******************************************************************************/
/* Function: SoundSend
*
* Sends the specified sound trigger to the player, using MSDP or ATCP if
* supported, MSP if not. The trigger string itself is a relative path and
* filename, eg: SoundSend( pDesc, "monster/growl.wav" );
*/
void SoundSend( descriptor_t *apDescriptor, const char *apTrigger );
/******************************************************************************
Colour functions.
******************************************************************************/
/* Function: ColourRGB
*
* Returns a colour as an escape code, based on the RGB value provided. The
* string must be four characters, where the first is either 'f' for foreground
* or 'b' for background (case insensitive), and the other three characters are
* numeric digits in the range 0 to 5, representing red, green and blue.
*
* For example "F500" returns a red foreground, "B530" an orange background,
* and so on. An invalid colour will clear whatever you've set previously.
*
* If the user doesn't support XTerm 256 colours, this function will return the
* best-fit ANSI colour instead.
*
* If you wish to embed colours in strings, use ProtocolOutput().
*/
const char *ColourRGB( descriptor_t *apDescriptor, const char *apRGB );
/******************************************************************************
Unicode (UTF-8 conversion) functions.
******************************************************************************/
/* Function: UnicodeGet
*
* Returns the UTF-8 sequence for the specified unicode value.
*/
char *UnicodeGet( int aValue );
/* Function: UnicodeAdd
*
* Adds the UTF-8 sequence for the specified unicode value onto the end of the
* string, without adding a NUL character at the end.
*/
void UnicodeAdd( char **apString, int aValue );
#endif /* PROTOCOL_H */