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

Spells.cpp

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

#include "Win32PluginAPI.cpp"
#include "Spells.h"

static Spells * spells = NULL;
static regex_t spell_regex;

#define MAJOR "0"
#define MINOR "4"

#define SPELL_REGEX "spell_string"
#define SPELL_TEXT "spell_text"
#define DEFAULT_SPELL_REGEX "Spell: '(.*)' .*"

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

extern "C" G_MODULE_EXPORT char * plugin_query_description()
{
  return _("Informs the user which spells their character is missing.");
}

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);
      spells = new Spells();
}

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

Spells::Spells()
{
  name = strdup("Spells");

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

  spellsPreference = new SpellsPreference();

  preference_add_editor(spellsPreference);
}

Spells::~Spells()
{
  preference_remove_editor(spellsPreference);
  delete spellsPreference;
  unregister_plugin(this);
}

void spells_callback(Connection * c, char * buf, void * d)
{
  int nmatch = 2;
  regmatch_t match[2];
  char spell[128];
  int start, end;
  
  struct spell_data * data = spells->find_entry(c);
  if (!data)
    return;

  if (!buf) {
    /* Print a list of the missing spells for this connection. */
    for (int i = 0; i < MAX_SPELLS; i++) {
      
      if (data->spell[i] && data->seen[i] == 0) {
      char buf[1024];
      sprintf(buf, "\033[1;34m%s %s\033[0m\n", _("Missing:"), data->spell[i]);
      vt_append(connection_get_vt(c), buf);
      }
      
      // Free the data.
      if (data->spell[i]) {
      free(data->spell[i]);
      data->spell[i] = NULL;
      }
      
    }
    
    vt_scroll(connection_get_vt(c));
    if (d)
      free(d);
    
    return;
  }

  
  char * spell_string = preferences_get_preference(connection_query_preferences(c), SPELL_REGEX);
  if (spell_string && strlen(spell_string) > 0)
    regcomp(&spell_regex, spell_string, REG_ICASE|REG_EXTENDED);
  else
    regcomp(&spell_regex, DEFAULT_SPELL_REGEX, REG_ICASE|REG_EXTENDED);
  
  if (regexec(&spell_regex, buf, nmatch, match, 0) == REG_NOMATCH) {
    regfree(&spell_regex);
    return;
  }
  
  start = match[1].rm_so;
  end = match[1].rm_eo;
  
  if (end-start > 127) {
    regfree(&spell_regex);
    return;
  }
  
  memcpy(spell, buf + start, end - start);
  spell[end-start] = '\0';
  
  /* spell contains the string name of the spell we found */
  
  for (int i = 0; i < MAX_SPELLS; i++) {
    if (data->spell[i] && !strncasecmp(data->spell[i], spell, strlen(spell))) {
      data->seen[i] = 1;
    }
  }
  
  regfree(&spell_regex);
  
}

void Spells::input(Connection * c, char * buf)
{
 
  if (strncasecmp(buf, "missing", 7))
    return;

  if (!turf_protocol_is_supported(c)) {
    vt_append(connection_get_vt(c), "TurfProtocol is not enabled/loaded.  Sending command to MUD.\n");
    return;
  }

  // Do we have a spell_data for this connection?
  
  struct spell_data * data = find_entry(c);
  if (!data)
    data = create_new_entry(c);

  // We're using the text box's data.
  gchar * text = strdup(preferences_get_preference(connection_query_preferences(c), SPELL_TEXT));
  getSpellData(text, data);
  free(text);
  
  buf[0] = '\0';

  turf_protocol_add_command(c, "affects", (void *)spells_callback, NULL);
  return;
}

static int SpellDataCmp(struct spell_data * s1, struct spell_data * s2) {
  return (s1 < s2);
}

struct spell_data * Spells::find_entry(Connection * conn) {
  for (SpellDataList::iterator i = spellData.begin(); i != spellData.end(); i++) {
    if ((*i)->connection == conn)
      return (*i);
  }
  return NULL;
}

struct spell_data *  Spells::create_new_entry(Connection * conn) {
  struct spell_data * data = (struct spell_data *)malloc(sizeof(struct spell_data));
  memset(data, 0, sizeof(struct spell_data));
  data->connection = conn;

  SpellDataList::iterator i = std::lower_bound(spellData.begin(),
                                     spellData.end(),
                                     data,
                                     SpellDataCmp);
  spellData.insert(i, data);
  return data;
}

void Spells::getSpellData(char * buf, struct spell_data * data) {

  char * pc;
  char * last = buf;
  int current = 0;

  // Remove the entries already here.
  for (int i = 0; i < MAX_SPELLS; i++) {
    if (data->spell[i])
      free(data->spell[i]);
    data->spell[i] = NULL;
  }

  while ((pc = strchr(last, '`'))) {
    *pc = '\0';

    data->spell[current] = strdup(last);
    data->seen[current] = 0;
    current++;

    if (current >= MAX_SPELLS)
      return;

    last = pc + 1;
  }

  if (strlen(last) > 0) {
    data->spell[current] = strdup(last);
    data->seen[current] = 0;
    current++;
  }

  return;
}

void Spells::getSpellData(FILE * fp, struct spell_data * data) {
  char line[1024];
  int current = 0;

  // Remove the entries already here.
  for (int i = 0; i < MAX_SPELLS; i++) {
    if (data->spell[i])
      free(data->spell[i]);
    data->spell[i] = NULL;
  }

  // Read spells in.
  while (fgets(line, 1023, fp)) {
    data->spell[current] = strdup(line);
    data->seen[current] = 0;
    current++;

    if (current >= MAX_SPELLS)
      return;
  }

  return;
}

SpellsPreference::SpellsPreference() {
  xml = NULL;
}

SpellsPreference::~SpellsPreference() {
  if (xml)
    g_object_unref(xml);
}

void SpellsPreference::loadPreferences(Prefs * prefs) {

  GtkWidget * text_view = glade_xml_get_widget(xml, "spell_list_text_view");
  GtkTextBuffer * text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));

  char * text = preferences_get_preference(prefs, SPELL_TEXT);
  if (text) {
    char * last = text;
    char * pc;
    while ((pc = strchr(last, '`'))) {
      *pc = '\n';
      last = pc + 1;
    }
    
    GtkTextIter start, end;
    gtk_text_buffer_get_bounds(text_buffer, &start, &end);
    gtk_text_buffer_insert(text_buffer, &end, text, -1);
  }

  GtkWidget * entry = glade_xml_get_widget(xml, "spell_regex_entry");
  text = preferences_get_preference(prefs, SPELL_REGEX);
  if (text && strlen(text) > 0)
    gtk_entry_set_text(GTK_ENTRY(entry), text);
  else
    gtk_entry_set_text(GTK_ENTRY(entry), DEFAULT_SPELL_REGEX);
}

void SpellsPreference::applyPreferences(Prefs * prefs) {
  GtkWidget * text_view = glade_xml_get_widget(xml, "spell_list_text_view");
  GtkTextBuffer * text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));

  GtkTextIter start, end;
  gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(text_buffer), &start, &end);
  gchar * text = (gchar *)gtk_text_buffer_get_text(text_buffer, &start, &end, false);

  char * last = text;
  char * pc;

  while ((pc = strchr(last, '\n'))) {
    *pc = '`';
    last = pc + 1;
  }

  preferences_set_preference(prefs, SPELL_TEXT, text);
  g_free(text);

  GtkWidget * entry = glade_xml_get_widget(xml, "spell_regex_entry");
  preferences_set_preference(prefs, SPELL_REGEX, (gchar *) gtk_entry_get_text(GTK_ENTRY(entry)));

}

GtkWidget * SpellsPreference::getWidget() {
  char buf[1024];
  snprintf(buf, 1024, "%s/share/papaya/spellspreferences.glade", get_prefix());
  
  if (xml) {
    GtkWidget * vbox = glade_xml_get_widget(xml, "vbox");
    return vbox;
  }

  xml = glade_xml_new(buf, NULL, NULL);
  glade_xml_signal_autoconnect(xml);
  GtkWidget * vbox = glade_xml_get_widget(xml, "vbox");
  gtk_widget_show(vbox);
  return vbox;
}

void SpellsPreference::destroyWidget() {
  if (xml)
    g_object_unref(xml);
  xml = NULL;
}

Category * SpellsPreference::getCategories() {
  return (Category *)spells_categories;
}

Generated by  Doxygen 1.6.0   Back to index