/*
.-------------------------------------------------------------------------------.
| Title : MIP (Messaging Interface Protocol) v8.1 Support Module |
| Author : Chris Coulter (aka Gabriel Androctus) |
| Date : 08.26.02 |
| Dev. MUD : Perils of Quiernin ( perils.org 6000 ) |
| Platform : SMAUG v1.4a |
| MUD Page : http://www.perils.org/ |
| Res. Page: http://www.perils.org/goodies/ |
+-------------------------------------------------------------------------------+
| DESCRIPTION: |
| MIP (Messaging Interface Protocol) enables your mud to communicate specific |
| text strings to a player using the Portal client software. This module |
| provides basic support for establishing if the player is using the Portal |
| client and assigning the appropriate information, as well as a simplified |
| way to send the strings to trigger specific features on the player's client. |
| |
| For more information, visit Portal's web page ( www.gameaxle.com ) and click |
| on the "Developers" button on the menu bar. From there you can download a PDF |
| file that explains in detail the specifics of the MIP. |
| |
| NOTE: If a player is not using the Portal client, the mud will function as |
| it normally would, and the player would not receive the MIP codes. It will |
| only function for players who has connected via the Portal mud client |
| |
`-------------------------------------------------------------------------------'
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "./Headers/mud.h"
/* Parses jumpstart command and assigns sec_code & version information. -gabe */
void do_mip_start( CHAR_DATA * ch, char *argument )
{
char arg[MAX_INPUT_LENGTH]; /* version */
char buf[MAX_STRING_LENGTH];
int sec_code;
if( IS_NPC( ch ) )
{
send_to_char( "Huh?\n\r", ch );
return;
}
if( argument[0] == '\0' )
{
send_to_char( "Huh?\n\r", ch );
return;
}
sscanf( argument, "%d~%s\n\r", &sec_code, arg );
/*
* pad sec_code with zeros
*/
if( sec_code >= 10000 )
sprintf( buf, "%d", sec_code );
else if( sec_code >= 1000 )
sprintf( buf, "0%d", sec_code );
else if( sec_code >= 100 )
sprintf( buf, "00%d", sec_code );
else if( sec_code >= 10 )
sprintf( buf, "000%d", sec_code );
else if( sec_code >= 0 )
sprintf( buf, "0000%d", sec_code );
ch->pcdata->sec_code = str_dup( buf );
ch->pcdata->mip_ver = str_dup( arg );
xSET_BIT( ch->act, PLR_MIP );
}
/* Initial settings are all done here. -gabe */
void init_mip( CHAR_DATA * ch )
{
send_mip_mask( ch, CL_HP_MASK, "Hit Points" );
send_mip_mask( ch, CL_SP_MASK, "Mana" );
send_mip_mask( ch, CL_GP1_MASK, "Movement" );
send_mip_mask( ch, CL_GP2_MASK, "Unused" );
}
/* Is the character's client MIP-enhanced? -gabe */
bool mip_enabled( CHAR_DATA * ch )
{
if( IS_NPC( ch ) )
return FALSE;
if( ( !ch->pcdata->sec_code
||ch->pcdata->sec_code[0] == '\0' )
&&( !ch->pcdata->mip_ver
||ch->pcdata->mip_ver[0] == '\0' ) )
return FALSE;
if( xIS_SET( ch->act, PLR_MIP ) )
return TRUE;
return FALSE;
}
/* provides the generic prefix for all MIP communication -gabe */
void send_mip( char *argument, CHAR_DATA * ch )
{
char buf[MAX_STRING_LENGTH];
char length2[MAX_STRING_LENGTH];
int length;
if( !mip_enabled( ch ) )
return;
length = strlen( argument );
if( length >= 1000 )
sprintf( length2, "999" );
else if( length >= 100 )
sprintf( length2, "%d", length );
else if( length >= 10 )
sprintf( length2, "0%d", length );
else if( length >= 0 )
sprintf( length2, "00%d", length );
else
sprintf( length2, "000" );
sprintf( buf, "#K%%%s%s%s", ch->pcdata->sec_code, length2, argument );
send_to_char( buf, ch );
return;
}
void send_mip_2( char *argument, CHAR_DATA * victim )
{
char buf[MAX_STRING_LENGTH];
char length2[MAX_STRING_LENGTH];
int length;
if( !mip_enabled( victim ) )
return;
length = strlen( argument );
if( length >= 1000 )
sprintf( length2, "999" );
else if( length >= 100 )
sprintf( length2, "%d", length );
else if( length >= 10 )
sprintf( length2, "0%d", length );
else if( length >= 0 )
sprintf( length2, "00%d", length );
else
sprintf( length2, "000" );
sprintf( buf, "#K%%%s%s%s", victim->pcdata->sec_code, length2, argument );
send_to_char( buf, victim );
return;
}
void send_mip_3( char *argument, CHAR_DATA * victim )
{
char buf[MAX_STRING_LENGTH];
char length2[MAX_STRING_LENGTH];
int length;
length = strlen( argument );
if( length >= 1000 )
sprintf( length2, "999" );
else if( length >= 100 )
sprintf( length2, "%d", length );
else if( length >= 10 )
sprintf( length2, "0%d", length );
else if( length >= 0 )
sprintf( length2, "00%d", length );
else
sprintf( length2, "000" );
sprintf( buf, "#K%%%s%s%s", victim->pcdata->sec_code, length2, argument );
send_to_char( buf, victim );
return;
}
/* Triggers sound on client's computer. -gabe
* Formats: .WAV
*/
void send_mip_sound( CHAR_DATA * ch, char *filename )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_SOUND, filename );
send_mip( buf, ch );
return;
}
/* Triggers music on client's computer. -gabe
* Formats: .MID, .RMI, .MP3
*/
void send_mip_music( CHAR_DATA * ch, char *filename, int iterations )
{
char buf[MAX_STRING_LENGTH];
if( !filename || filename[0] == '\0' )
sprintf( buf, "%s", CL_SEND_MUSIC );
else if( iterations > 1 )
sprintf( buf, "%s%s%s%d", CL_SEND_MUSIC, filename, CL_DELIM, iterations );
else
sprintf( buf, "%s%s", CL_SEND_MUSIC, filename );
send_mip( buf, ch );
return;
}
/* Displays an image on client's computer. -gabe
* Formats: .BMP, .GIF
*/
void send_mip_image( CHAR_DATA * ch, char *filename, char *label )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s%s%s", CL_SEND_IMAGE, filename, CL_DELIM, label );
send_mip( buf, ch );
return;
}
/* Display amount of time remaining (HH:MM) until next reboot. -gabe */
void send_mip_reboot( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_REBOOT, argument );
send_mip( buf, ch );
return;
}
/* Display amount of time (HH:MM) the mud has been up since last reboot. -gabe */
void send_mip_uptime( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_UPTIME, argument );
send_mip( buf, ch );
return;
}
/* Trigger an .AVI on the client's computer -gabe */
void send_mip_avi( CHAR_DATA * ch, char *filename, char *label, int height, int width, bool fRepeat )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s%s%s%s%d%s%d%s%s",
CL_SEND_AVI, filename, CL_DELIM, label, CL_DELIM, height, CL_DELIM, width,
( fRepeat ) ? CL_DELIM : "",
( fRepeat ) ? "1" : "" );
send_mip( buf, ch );
return;
}
/* Send a media file to the client's hard disk. -gabe
* Formats: .WAV, .MID, .RMI, .MP3, .BMP, .GIF, .AVI
*/
void mip_download( CHAR_DATA * ch, char *filename )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s%s%s%s", CL_DOWNLOAD_MEDIA, filename, CL_DELIM, MIP_MEDIA_URL, filename );
send_mip( buf, ch );
return;
}
/* Send special information to client in a text string -gabe
* note: haven't found a use for this, but it's part of mip. so here it is. */
void send_mip_special( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_SPECIAL, argument );
send_mip( buf, ch );
return;
}
/* Send special guild information to client in a text string -gabe
* note: haven't found a use for this, but it's a part of mip. so here it is. */
void send_mip_special2( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_SPECIAL2, argument );
send_mip( buf, ch );
return;
}
/* Send 'tell' information to player's client -gabe
* fSender values:
* TRUE = ( ch == sender of tell ) + ( victim == receiver of tell )
* FALSE = ( ch == receiver of tell ) + ( victim == sender of tell )
*/
void send_mip_tell( CHAR_DATA * ch, CHAR_DATA * victim, char *argument, bool fSender )
{
char buf[MAX_STRING_LENGTH];
/*
* don't monitor NPC tells
*/
if( IS_NPC( ch ) || IS_NPC( victim ) )
return;
if( fSender )
{
sprintf( buf, "%sx%s%s%s%s", CL_SEND_TELL, CL_DELIM, victim->name, CL_DELIM, argument );
send_mip_2( buf, ch );
return;
}
else
{
sprintf( buf, "%s%s%s%s%s", CL_SEND_TELL, CL_DELIM, victim->name, CL_DELIM, argument );
send_mip( buf, victim );
return;
}
}
/* Send short description of a room to player's client -gabe */
void send_mip_room( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_ROOM, argument );
send_mip( buf, ch );
return;
}
/* Send a metered lag measurement to client -gabe */
void send_mip_mudlag( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_MUDLAG, argument );
send_mip( buf, ch );
return;
}
/* Send the current file that is being edited (??) -gabe */
void send_mip_edit( CHAR_DATA * ch, char *filename )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_EDIT, filename );
send_mip( buf, ch );
return;
}
/* Set the appropriate mask names on player's client -gabe
* note: for type values, see mip.h */
void send_mip_mask( CHAR_DATA * ch, char *type, char *argument )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", type, argument );
send_mip( buf, ch );
return;
}
/* Set the caption on the player's client -gabe */
void send_mip_caption( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_CAPTION, argument );
send_mip( buf, ch );
return;
}
/* Begin a line-by-line transfer (???) -gabe */
void send_mip_begin_file( CHAR_DATA * ch, int lines, char *tag )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%d%s%s", CL_SEND_BEGIN_FILE, lines, CL_DELIM, tag );
send_mip( buf, ch );
return;
}
/* Continue a line-by-line transfer (???) -gabe */
void send_mip_cont_file( CHAR_DATA * ch, char *line )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s", CL_SEND_CONT_FILE, line );
send_mip( buf, ch );
return;
}
/* End a line-by-line transfer (???) -gabe */
void send_mip_end_file( CHAR_DATA * ch )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s", CL_SEND_END_FILE );
send_mip( buf, ch );
return;
}
/* Send channel information to player's client -gabe */
void send_mip_channel( CHAR_DATA * ch, const char *cmd, char *channel, char *source, char *argument )
{
char buf[MAX_STRING_LENGTH];
char buf2[MAX_STRING_LENGTH];
sprintf( buf2, "%s-> %s-> %s", source, channel, argument );
sprintf( buf, "%s%s%s%s%s%s%s%s", CL_SEND_CHAT, cmd, CL_DELIM, channel,
CL_DELIM, source, CL_DELIM, buf2 );
send_mip_3( buf, ch );
return;
}
/* Send exit information to player's client (for room monitor) -gabe */
void send_mip_exits( CHAR_DATA * ch )
{
EXIT_DATA * exit_l;
char ex_buf[MAX_STRING_LENGTH];
char buf[MAX_STRING_LENGTH];
strcpy( ex_buf, "" );
if( !ch->in_room )
{
bug( "send_mip_exits (%s): ch->in_room == NULL", ch->name );
return;
}
for( exit_l = ch->in_room->first_exit; exit_l; exit_l = exit_l->next )
{
if( exit_l->to_room
&&!IS_SET( exit_l->exit_info, EX_CLOSED )
&&!IS_SET( exit_l->exit_info, EX_HIDDEN )
&&!IS_SET( exit_l->exit_info, EX_WINDOW ) )
{
switch ( exit_l->vdir )
{
default:
break;
case DIR_NORTH:
strcat( ex_buf, "n " );
break;
case DIR_EAST:
strcat( ex_buf, "e " );
break;
case DIR_SOUTH:
strcat( ex_buf, "s " );
break;
case DIR_WEST:
strcat( ex_buf, "w " );
break;
case DIR_UP:
strcat( ex_buf, "u " );
break;
case DIR_DOWN:
strcat( ex_buf, "d " );
break;
case DIR_NORTHEAST:
strcat( ex_buf, "ne " );
break;
case DIR_SOUTHEAST:
strcat( ex_buf, "se " );
break;
case DIR_NORTHWEST:
strcat( ex_buf, "nw " );
break;
case DIR_SOUTHWEST:
strcat( ex_buf, "sw " );
break;
}
}
}
sprintf( buf, "%s%s", CL_SEND_ROOMCODE, ex_buf );
send_mip( buf, ch );
return;
}
/* Send point information (hit points, mana & move points) -gabe */
void send_mip_points( CHAR_DATA * ch )
{
char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s%s%d%s%s%d%s%s%d%s%s%d%s%s%d%s%s%d", CL_SEND_COMPOSITE,
CL_SEND_HP, ch->hit, CL_DELIM,
CL_SEND_MAXHP,
ch->max_hit, CL_DELIM,
CL_SEND_SP, ch->mana, CL_DELIM,
CL_SEND_MAXSP, ch->max_mana, CL_DELIM,
CL_SEND_GP1,
ch->move, CL_DELIM,
CL_SEND_MAXGP1, ch->max_move );
send_mip( buf, ch );
return;
}
/* Send combat information (mob condition/name) -gabe */
void send_mip_attacker( CHAR_DATA * ch )
{
CHAR_DATA * victim;
char buf[MAX_STRING_LENGTH];
int condition;
if( !ch->fighting || !( victim = who_fighting( ch ) ) )
{
sprintf( buf, "%s%s%s", CL_SEND_COMPOSITE, CL_SEND_ATTACKER, CL_DELIM );
send_mip( buf, ch );
sprintf( buf, "%s%s%d", CL_SEND_COMPOSITE, CL_SEND_ATTCOND, 0 );
send_mip( buf, ch );
return;
}
if( victim->max_hit > 0 && victim->hit > 0 )
condition = ( 100 * victim->hit ) / victim->max_hit;
else
condition = 0;
sprintf( buf, "%s%s%s%s%s%d", CL_SEND_COMPOSITE, CL_SEND_ATTACKER,
( IS_NPC( victim ) ) ? capitalize( victim->short_descr ) : victim->name, CL_DELIM,
CL_SEND_ATTCOND,
condition );
send_mip( buf, ch );
return;
}