Logo Search packages:      
Sourcecode: papaya version File versions  Download package

MXP.cpp

#include <string.h>
#include <stdlib.h>

#include "MXP.h"

// All plugins must include this, even on UNIX platforms where .sos are sane.
#include "Win32PluginAPI.cpp"

#include <ctype.h>

#define TELOPT_MXP 91

void mxp_element_parse(Connection *, char *, char **);
static MXP * mxp;

// Configure the minor and major versions of this plugin.
#define MAJOR "1"
#define MINOR "0"

extern "C" G_MODULE_EXPORT void plugin_init(plugin_address_table_t * pat) {
  plugin_address_table_init(pat);
  mxp = new MXP();
}

extern "C" G_MODULE_EXPORT void plugin_cleanup(void) {
  delete mxp;
}

extern "C" G_MODULE_EXPORT char * plugin_query_name() {
  return "MXP";
}

extern "C" G_MODULE_EXPORT char * plugin_query_description() {
  return "";
}

extern "C" G_MODULE_EXPORT char * plugin_query_major() {
  return MAJOR;
}

extern "C" G_MODULE_EXPORT char * plugin_query_minor() {
  return MINOR;
}

MXP::MXP() {
  version = 1.0;
  name = strdup("MXP");

  // This MUST be done after all variable initialisation as it can cause
  // onEvent(Event *, Connection *) to be called.
  register_plugin(this, VERSION);
  plugin_handler_add_output_filter(get_plugin_handler(), this);
  plugin_handler_add_telopt_filter(get_plugin_handler(), this, TELOPT_MXP);
}

MXP::~MXP() {
  free(name);

  unregister_plugin(this);
}

// Uncomment this if you want to parse input from the user
//void G_MODULE_EXPORT MXP::input(Connection * conn, char * input) {
//}

// Uncomment this if you want to parse output from the MUD
void G_MODULE_EXPORT MXP::output(Connection * conn, char * input) {
  char output[32768];
  char * output_ptr = output;
  char * pc = input;

  // MXP has not been negotiated for this connection.
  if (!socket_get_telnet_option(connection_get_socket(conn), (int) TELOPT_MXP))
    return;

  output[0] = '\0';

  // On an MXP-enabled MUD a < is always indicative of a tag.  Ditto &

  // Papaya attempts to guarantee a line of text at a time, however
  // it's not always possible to distinguish a prompt from a pause in
  // delivery of a new packet.

  // MXP has three types of tag to look out for:
  //   1. <sometext some args>  - elements
  //   2. &sometextnospaces;    - entities
  //   3. \033[<n>z             - MXP Line Tags (no mention about having to be at start of line)

  // 3. can technically be done in colour code, but must be done here in order
  // that this plugin knows if we're in secure/open mode on parsing 1 and 2.

  while (*pc != '\0') {

    switch (*pc) {

    case '\033':
      output_ptr = parseLineTag(conn, &pc, output_ptr);
      break;

    case '<':
      output_ptr = parseElement(conn, &pc, output_ptr);
      break;

    case '&':
      output_ptr = parseEntity(conn, &pc, output_ptr);
      break;

    default:
      *output_ptr++ = *pc++;
      break;
    }

  }

  *output_ptr = '\0';

  // if output different to input, copy output to input.
  if (strcmp(output, input)) {
    printf ("MXP: %s", input);
    printf ("MXP: %s", output);
    strcpy(input, output);
  }

}

char * MXP::parseLineTag(Connection * conn, char ** pc_ptr, char * output) {
  char * pc = *pc_ptr;
  char * start = pc;

  pc++;
  if (*pc != ']') {
    *output++ = *start++;
    *pc_ptr = start;
    return output;
  }

  pc++;
  while (isdigit(*pc))
    pc++;

  if (*pc != 'z') {
    *output++ = *start++;
    *pc_ptr = start;
    return output;
  }

  *pc_ptr = pc + 1;

  *pc = '\0';

  printf ("MXP: Line Tag: %s\n", start + 2);

  return output;
}

char * MXP::parseElement(Connection * conn, char ** pc_ptr, char * output) {
  char * pc = *pc_ptr;
  char * start = pc;

  pc = strchr(pc, '>');
  if (!pc) {
    *output++ = *start++;
    *pc_ptr = start;
    return output;
  }

  *pc_ptr = pc + 1;
  *pc = '\0';

  printf ("MXP: Element: %s\n", start);

  char ** output_ptr = &output;
  mxp_element_parse(conn, start, output_ptr);
  output = *output_ptr;

  return output;
}

char * MXP::parseEntity(Connection * conn, char ** pc_ptr, char * output) {
  char * pc = *pc_ptr;
  char * start = pc;

  pc = strchr(pc, ';');
  if (!pc) {
    *output++ = *start++;
    *pc_ptr = start;
    return output;
  }

  *pc_ptr = pc + 1;
  *pc = '\0';
  printf ("MXP: Entity: %s\n", start);


  return output;
}

bool G_MODULE_EXPORT MXP::teloptAllowRemote(Connection * conn, int option) {
  if (option == TELOPT_MXP)
    return true;

  return false;
}

void G_MODULE_EXPORT MXP::teloptHandleRemote(Connection * conn, int option, bool onoff) {
  if (option == TELOPT_MXP) { // This connection has agreed to do MXP.
    if (onoff == true)
      printf ("MXP negotiated as enabled.\n");
    else
      printf ("MXP negotiated as disabled.\n");
  }
}

// Uncomment this if you want to parse incoming prompts
//void G_MODULE_EXPORT MXP::prompt(Connection * conn, char * input) {
//}

// Uncomment this if you want to respond to "EvConnect" and "EvDisconnect"
// events.
//void G_MODULE_EXPORT MXP::onEvent(Event * event, Connection * conn) {
//}

// Uncomment this if you want to receive TurfProtocol client messages.
//void G_MODULE_EXPORT MXP::clientMessage(Connection * conn, char * text) {
//}

Generated by  Doxygen 1.6.0   Back to index