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

LoginTracker.cpp

#include <sys/time.h>
#include <stdlib.h>
#include <regex.h>
#include <stdio.h>
#include <string.h>

#include "mudclient.h"
#include "PapayaList.h"
#include "SystemTriggerEntity.h"
#include "EntityHandler.h"
#include "PluginHandler.h"
#include "LoginTracker.h"
#include "version.h"
#include "Message.h"

#define TURF_PROTOCOL

#ifdef TURF_PROTOCOL
#include "TurfProtocol.h"
#endif

struct login_data {
  int start_logins; // Number of logins when we first started counting.
  int logins; // Number of logins we've seen since logging on.
  gint timeout;
};

extern PluginHandler * phandler;
extern EntityHandler * entities;

static List * ltlist = NULL;

#define MAJOR "0"
#define MINOR "3"

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

extern "C" char * plugin_query_description() {
  return "Attempts to warn you when a player invisible to you has logged onto Turf.";
}

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

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

static LoginTracker * lt = NULL;

extern "C" void plugin_init(void) {
  lt = new LoginTracker();
}

extern "C" void plugin_cleanup(void) {
  if (lt) {
    delete lt;
    lt = NULL;
  }
}

int LoginTracker_SignedOnCallback(regex_t * regexp, Connection * c, char * buf, char * stripped_buf, void * d) {

  // Now that we have the value, find an entry for our connection in the list.
  struct login_data * data;
  ListElement * ele = ltlist->findEntry(c);
  if (!ele) {
    return 1;
  }

  data = (struct login_data *)ele->getData();
  if (data->start_logins == -1)
    return 1;

  data->logins++;
  return 1;
}

#ifndef TURF_PROTOCOL

int LoginTracker_ConnectedTriggerCallback(regex_t * regexp, Connection * c, char * buf, char * stripped_buf, void * d) {

  regmatch_t match[2];
  int nmatch = 2;
  char value[1024];

  // There have been ([0-9]+) logins since the last reboot.
  // There has been (1) login since the last reboot.

  // Figure out how many logins there have been.

  if (regexec(regexp, buf, nmatch, match, 0) == REG_NOMATCH) {
    return 0;
  }

  int len = match[1].rm_eo - match[1].rm_so;
  memcpy(value, buf + match[1].rm_so, len);
  value[len] = '\0';
  
  int logins = atoi(value);

  // Now that we have the value, find an entry for our connection in the list.
  struct login_data * data;
  ListElement * ele = ltlist->findEntry(c);
  if (!ele) {
    ele = ltlist->newEntry(c, NULL);
    data = (struct login_data *)malloc(sizeof(struct login_data));
    data->start_logins = -1;
    data->logins = -1;
    ele->setData(data);
  }

  data = (struct login_data *)ele->getData();

  if (data->start_logins == -1) { // This is the first time we've seen this.
    data->start_logins = logins;
    data->logins = 0;
  } else { // We've seen this before, make sure our numbers add up.
    while (data->start_logins + data->logins < logins) {
      char buf[1024];
      sprintf(buf, "\033[1;33mInvisible login detected.\033[0m\n");
      data->logins++;
      c->getVT()->append(buf);
    }
  }
  
  return 1;
}

#else // ifndef TURF_PROTOCOL

void LoginTracker_TurfCallback(Connection * c, char * buf, void * d) {

  if (!buf)
    return;

  // Need to parse the input for a logins line.
  regmatch_t match[2];
  int nmatch = 2;
  char value[1024];
  regex_t regexp;
  char * pattern = "There have been ([0-9]+) logins since the last reboot.";

  // There have been ([0-9]+) logins since the last reboot.
  // There has been (1) login since the last reboot.

  // Figure out how many logins there have been.
  regcomp(&regexp, pattern, REG_ICASE|REG_EXTENDED);
  if (regexec(&regexp, buf, nmatch, match, 0) == REG_NOMATCH) {
    return;
  }

  int len = match[1].rm_eo - match[1].rm_so;
  memcpy(value, buf + match[1].rm_so, len);
  value[len] = '\0';
  
  int logins = atoi(value);

  struct login_data * data;
  ListElement * ele = ltlist->findEntry(c);
  if (!ele) {
    ele = ltlist->newEntry(c, NULL);
    data = (struct login_data *)malloc(sizeof(struct login_data));
    data->start_logins = -1;
    data->logins = -1;
    data->timeout = 0;
    ele->setData(data);
  }

  data = (struct login_data *)ele->getData();

  if (data->start_logins == -1) { // This is the first time we've seen this.
    data->start_logins = logins;
    data->logins = 0;
  } else { // We've seen this before, make sure our numbers add up.
    while (data->start_logins + data->logins < logins) {
      char buf2[1024];
      sprintf(buf2, "\033[1;33mInvisible login detected.\033[0m\n");
      data->logins++;
      c->getVT()->append(buf2);
    }
  }
}

#endif // ifndef TURF_PROTOCOL

int LoginTracker_TimeCallback(gpointer data) {

  Connection * c = (Connection *)data;

  if (!c)
    return 0;

  if (!c->getSocket())
    return 0;

  if (!c->isConnected())
    return 0;

  TurfProtocol * tp = NULL;
  
  // Try and find the TurfProtocol object.
  void * handle = phandler->findPlugin("TurfProtocol");
  if (!handle)
    c->getSocket()->write("time\n", 5);
  else {

    if (!findTurf(handle, (void **)&tp))
      c->getSocket()->write("time\n", 5);
    else {
      if (!tp) {
      c->getSocket()->write("time\n", 5);
      } else {
      tp->addCommand(c, "time", LoginTracker_TurfCallback, NULL);
      }
    }
  }

  return 1;
}

int LoginTracker_ConnectedCallback(regex_t * regexp, Connection * c, char * buf, char * stripped_buf, void * d) {

  // Find a login_data structure for this connection.

  ListElement * ele = ltlist->findEntry(c);
  struct login_data * data;
  if (!ele) {
    ele = ltlist->newEntry(c, NULL);
    data = (struct login_data *)malloc(sizeof(struct login_data));
    data->start_logins = -1;
    data->logins = -1;
    data->timeout = 0;
    ele->setData(data);
  } else
    data = (struct login_data *)ele->getData();
  
  LoginTracker_TimeCallback((gpointer)c);


  if (data->timeout) {
    gtk_timeout_remove(data->timeout);
  }
  data->timeout = gtk_timeout_add(60000, LoginTracker_TimeCallback, (gpointer)c);
  
  return 1;
}

LoginTracker::LoginTracker() {
  name = strdup("Login Tracker");
  version = 1.0;
  ltlist = new List();
  
#ifndef TURF_PROTOCOL
  // Add a trigger to respond to the results of the time command.
  login_trigger = new SystemTriggerEntity("There have been ([0-9]+) logins since the last reboot.", NULL, LoginTracker_ConnectedTriggerCallback, NULL);
  entities->addEntity("Login Tracker", login_trigger);

  login_trigger2 = new SystemTriggerEntity("There has been (1) login since the last reboot.", NULL, LoginTracker_ConnectedTriggerCallback, NULL);
  entities->addEntity("Login Tracker", login_trigger2);
#endif // TURF_PROTOCOL

  SystemTriggerEntity * tmp = new SystemTriggerEntity("Welcome to Turf.  Have a pleasant stay.", NULL, LoginTracker_ConnectedCallback, NULL);
  entities->addEntity("Login Tracker", tmp);

  SystemTriggerEntity * tmp2 = new SystemTriggerEntity("You have reconnected.", NULL, LoginTracker_ConnectedCallback, NULL);
  entities->addEntity("Login Tracker", tmp2);

  SystemTriggerEntity * tmp3 = new SystemTriggerEntity(".* the level [0-9]+ [^ ]+ has signed on.", NULL, LoginTracker_SignedOnCallback, NULL);
  entities->addEntity("Login Tracker", tmp3);

  phandler->registerPlugin(this, VERSION);
}

LoginTracker::~LoginTracker() {
  printf("FIXME: Remove system triggers in login tracker cleanup.\n");
  delete ltlist;

  phandler->unregisterPlugin(this);
}

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

  if (e->getType() == EvConnect) {
    ListElement * ele = ltlist->findEntry(c);
    struct login_data * data;
    if (!ele) {
      ele = ltlist->newEntry(c, NULL);
      data = (struct login_data *)malloc(sizeof(struct login_data));
      data->start_logins = -1;
      data->logins = -1;
      data->timeout = 0;
      ele->setData(data);
    } else {
      data = (struct login_data *)ele->getData();
      data->start_logins = -1;
      data->logins = -1;
      data->timeout = 0;
    }
  }

  if (e->getType() == EvDisconnect) {
    ListElement * ele = ltlist->findEntry(c);
    if (!ele) {
      return;
    }
    struct login_data * data = (struct login_data *)ele->getData();
    if (data->timeout > 0) {
      gtk_timeout_remove(data->timeout);
    }
    data->timeout = 0;

    ltlist->deleteEntry(ele);
  }

}

Generated by  Doxygen 1.6.0   Back to index