eldhamud/boards/
eldhamud/clans/
eldhamud/classes/
eldhamud/councils/
eldhamud/deity/
eldhamud/doc/
eldhamud/doc/DIKU/
eldhamud/doc/MERC/
eldhamud/doc/mudprogs/
eldhamud/gods/
eldhamud/houses/
eldhamud/lockers/
eldhamud/player/a/
/*
.-------------------------------------------------------------------------------.
| 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;

}