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

LagIndicator.cpp

#include <stdlib.h>
#include <sys/types.h>
#ifdef WIN32
#include <winsock2.h>
#include <time.h>
#else
#include <sys/time.h>
#endif

#include <string.h>
#include <stdio.h>

#include "LagIndicator.h"
#include "Win32PluginAPI.cpp"

//#include "TurfProtocol.h"

static struct indicator * first_lag = (struct indicator *)NULL;

static LagIndicator * lag;

#define MAJOR "1"
#define MINOR "2"

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

extern "C" G_MODULE_EXPORT char * plugin_query_description() {
  return _("Displays an estimate of the current lag to the MUD.  Requires TurfProtocol.");
}

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

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

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

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

LagIndicator::LagIndicator() {
  version = 1.0;
  name = strdup("Lag Indicator");

  first_lag = NULL;

      register_plugin(this, VERSION);
  plugin_handler_add_input_filter(get_plugin_handler(), this);
}

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

  struct indicator * ind, * ind_next;
  // Remove all the widgets from the tray.
  for (ind = first_lag; ind; ind = ind_next) {
    ind_next = ind->next;
 
    vt_remove_from_tray(connection_get_vt(ind->connection), ind->event_box, ind->frame);
    gtk_timeout_remove(ind->timeout);

    g_object_unref(ind->tip);
    free(ind);
  }

  unregister_plugin(this);
}

struct indicator * LagIndicator::findIndicator(Connection * c, bool fnew) {

  struct indicator * tmp = first_lag;

  for ( ;tmp; tmp = tmp->next) {
    if (tmp->connection == c)
      return tmp;
  }

  if (!fnew)
    return (struct indicator *)NULL;

  return newIndicator(c);
}

int lag_timeout(gpointer data) {
  struct indicator * ind = (struct indicator *)data;
  lag->checkLag(ind->connection);
  return 1;
}

struct indicator * LagIndicator::newIndicator(Connection * c) {
  struct indicator * tmp = (struct indicator *)malloc(sizeof(struct indicator));

  tmp->connection = c;
  tmp->event_box = gtk_event_box_new();
  tmp->widget = gtk_label_new(_("Initialising"));

  gtk_container_add(GTK_CONTAINER(tmp->event_box), tmp->widget);
  gtk_widget_show(tmp->widget);

  tmp->tip = gtk_tooltips_new();
  gtk_tooltips_set_tip(tmp->tip, tmp->event_box, "LagIndicator: this plugin requires the TurfProtocol plugin and a TurfProtocol aware MUD.", NULL);

  // Insert into list
  tmp->next = first_lag;
  first_lag = tmp;

  // Add into the tray.
  vt_add_to_tray(connection_get_vt(c), tmp->event_box, &tmp->frame);

  // Configure a timeout event.
  tmp->timeout = gtk_timeout_add(60000, lag_timeout, (gpointer)tmp);
  return tmp;
}

void LagIndicator::remove(struct indicator * ind) {
  struct indicator * tmp = first_lag;

  gtk_timeout_remove(ind->timeout);

  if (ind == first_lag) {
    first_lag = ind->next;
    g_object_unref(ind->tip);
    free(ind);
    return;
  }

  for (; tmp; tmp = tmp->next) {
    if (ind == tmp->next) {
      tmp->next = ind->next;
      g_object_unref(ind->tip);
      free(ind);
      return;
    }
  }
}

void LagIndicator::onEvent(Event * e, Connection * c) {

  if (event_get_type(e) == EvConnect) {
    // This will create a new indicator if necessary
    findIndicator(c, TRUE);
    return;
  }

  if (event_get_type(e) == EvDisconnect) {
    struct indicator * ind = findIndicator(c, FALSE);
    if (ind) {
      vt_remove_from_tray(connection_get_vt(c), ind->event_box, ind->frame);
      // Remove from the linked list.
      remove(ind);
    }
    return;
  }
}

void LagIndicator::input(Connection *c, char *in) {
  if (!strcasecmp(in, "lag")) {
    *in = '\0';
    checkLag(c);
  }
}

void LagCallbackPtr(Connection * c, char * buf, void * data) {

  char buf2[1024];
  int end, start, laggy;

  if (buf)
    return;

  // Only get this far if the buf is NULL (end of response)
 
      // @2 GetSystemTimeAsFileTime on win32
#ifdef WIN32
  
  DWORD start_time = (DWORD) data;
  DWORD end_time = GetTickCount();

  laggy = end_time - start_time;

#else
  struct timeval * start_time = (struct timeval *) data;
  struct timeval end_time;

  gettimeofday(&end_time, NULL);
  //  ftime(&end_time);

  // Figure out the time difference

  end = end_time.tv_sec * 1000 + end_time.tv_usec / 1000;
  start = start_time->tv_sec * 1000 + start_time->tv_usec / 1000;

  laggy = end - start;
#endif

  struct indicator * ind = lag->findIndicator(c, FALSE);
  if (!ind) {
    return;
  }

  sprintf(buf2, "%.2f seconds", (float)((float)laggy/1000.00));
  gtk_label_set_text(GTK_LABEL(ind->widget), buf2);

  // No need to free(data) as this is removed by the Turf Protocol handler.
}

void LagIndicator::checkLag(Connection * c) {
  if (!turf_protocol_is_supported(c))
    return;

  char * cmd = "who";

  // Get the current time.
      // @2 GetSystemTimeAsFileTime on win32
#ifdef WIN32
  DWORD * time = (DWORD *)malloc(sizeof(DWORD));
  time = GetTickCount();
#else
  struct timeval * time = (struct timeval *)malloc(sizeof(struct timeval));
  gettimeofday(time, NULL);
#endif
  //  ftime(time);

  turf_protocol_add_command(c, cmd, (void *)LagCallbackPtr, (void *)time);
}

char * LagIndicator::getDescription() {
  return "Displays the current command round trip time for each connection.";
}

Generated by  Doxygen 1.6.0   Back to index