+static void helpmod_cmd_version (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ helpmod_reply(sender, returntype, "HelpMod version " HELPMOD_VERSION " by strutsi (strutsi@quakenet.org)");
+}
+
+static void helpmod_cmd_ticketmsg (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ hchannel *hchan;
+
+ DEFINE_HCHANNEL;
+
+ HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
+
+ if (hchan == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not view or set ticket message: No channel is specified.");
+ return;
+ }
+
+ if (argc == 0)
+ { /* view */
+ if (hchan->ticket_message == NULL)
+ helpmod_reply(sender, returntype, "No ticket message is set for channel %s", hchannel_get_name(hchan));
+ else
+ helpmod_reply(sender, returntype, "Ticket message for channel %s is: %s", hchannel_get_name(hchan), hchan->ticket_message->content);
+ return;
+ }
+
+ /* set */
+ if (hchan->ticket_message != NULL)
+ freesstring(hchan->ticket_message);
+
+ hchan->ticket_message = getsstring(ostr, strlen(ostr));
+ helpmod_reply(sender, returntype, "Ticket message for channel %s set to: %s", hchannel_get_name(hchan), hchan->ticket_message->content);
+}
+
+static void helpmod_cmd_lcedit (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ hlc_profile *profile;
+
+ if (argc == 0)
+ {
+ helpmod_reply(sender, returntype, "Can not handle lamer control profiles: Operation not defined");
+ return;
+ }
+
+ if (!ci_strcmp(argv[0], "list"))
+ {
+ if (hlc_profiles == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not list lamer control profiles: No profiles");
+ return;
+ }
+ helpmod_reply(sender, returntype, "Following lamer control profiles are currently available:");
+ for (profile = hlc_profiles;profile != NULL;profile = profile->next)
+ helpmod_reply(sender, returntype, "%s", profile->name->content);
+ }
+ else if (!ci_strcmp(argv[0], "add"))
+ {
+ if (argc < 2)
+ {
+ helpmod_reply(sender, returntype, "Can not add a lamer control profile: Profile name not defined");
+ return;
+ }
+
+ profile = hlc_get(argv[1]);
+
+ if (profile != NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not add a lamer control profile: Profile named %s already exists", argv[1]);
+ return;
+ }
+ profile = hlc_add(argv[1]);
+
+ { /* set the default values */
+ profile->caps_max_percentage = 40;
+ profile->caps_min_count = 20;
+
+ profile->repeats_max_count = 3;
+ profile->repeats_min_length = 7;
+
+ profile->symbol_repeat_max_count = 6;
+ profile->character_repeat_max_count = 7;
+ profile->symbol_max_count = 9;
+
+ profile->tolerance_flood = 5;
+
+ profile->tolerance_spam = 0.008;
+ profile->constant_spam = 10;
+
+ profile->tolerance_warn = 1;
+ profile->tolerance_kick = 3;
+ profile->tolerance_remove = 5;
+ }
+
+ helpmod_reply(sender, returntype, "Lamer control profile %s added", argv[1]);
+ }
+ else if (!ci_strcmp(argv[0], "del"))
+ {
+ hchannel *hchan;
+ if (argc < 2)
+ {
+ helpmod_reply(sender, returntype, "Can not delete a lamer control profile: Profile name not defined");
+ return;
+ }
+
+ profile = hlc_get(argv[1]);
+
+ if (profile == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not delete a lamer control profile: Profile named %s does not exist", argv[1]);
+ return;
+ }
+ for (hchan = hchannels;hchan != NULL;hchan = hchan->next)
+ if (hchan->lc_profile == profile)
+ {
+ helpmod_reply(sender, returntype, "Can not delete a lamer control profile: Profile %s is in use", argv[1]);
+ return;
+ }
+ hlc_del(profile);
+ helpmod_reply(sender, returntype, "Lamer control profile %s deleted", argv[1]);
+ }
+ else if (!ci_strcmp(argv[0], "view"))
+ {
+ if (argc < 2)
+ {
+ helpmod_reply(sender, returntype, "Can not view a lamer control profile: Profile name not defined");
+ return;
+ }
+
+ profile = hlc_get(argv[1]);
+
+ if (profile == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not view a lamer control profile: Profile named %s not found", argv[1]);
+ return;
+ }
+
+ helpmod_reply(sender, returntype, "Lamer control profile %s:", profile->name->content);
+ helpmod_reply(sender, returntype, "Maximum caps percentage: %d", profile->caps_max_percentage);
+ helpmod_reply(sender, returntype, "Caps minimum count: %d", profile->caps_min_count);
+ helpmod_reply(sender, returntype, "Repeat tolerance: %d", profile->repeats_max_count);
+ helpmod_reply(sender, returntype, "Repeat minimum length: %d", profile->repeats_min_length);
+ helpmod_reply(sender, returntype, "Symbol repeat tolerance: %d", profile->symbol_repeat_max_count);
+ helpmod_reply(sender, returntype, "Character repeat tolerance: %d", profile->character_repeat_max_count);
+ helpmod_reply(sender, returntype, "Continuous symbol tolerance: %d", profile->symbol_max_count);
+ helpmod_reply(sender, returntype, "Flood tolerance: %d", profile->tolerance_flood);
+ helpmod_reply(sender, returntype, "Spam tolerance: %d", profile->tolerance_spam);
+ helpmod_reply(sender, returntype, "Spam multiplier: %f", profile->constant_spam);
+ helpmod_reply(sender, returntype, "Warning limit: %d", profile->tolerance_warn);
+ helpmod_reply(sender, returntype, "Kick limit: %d", profile->tolerance_kick);
+ helpmod_reply(sender, returntype, "Ban limit: %d", profile->tolerance_remove);
+ }
+ else if (!ci_strcmp(argv[0], "edit"))
+ {
+ int int_val = -1;
+ double dbl_val = -1;
+
+ if (argc != 4)
+ {
+ helpmod_reply(sender, returntype, "Can not edit a lamer control profile: Syntax error");
+ return;
+ }
+
+ profile = hlc_get(argv[1]);
+
+ if (profile == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not edit a lamer control profile: Profile %s not found", argv[1]);
+ return;
+ }
+
+ sscanf(argv[3], "%d", &int_val);
+ sscanf(argv[3], "%lf", &dbl_val);
+
+ if (dbl_val < 0)
+ { /* All int values are also valid double values */
+ helpmod_reply(sender, returntype, "Can not edit a lamer control profile: Invalid argument");
+ return;
+ }
+
+ if (!ci_strcmp(argv[2], "caps_percentage"))
+ profile->caps_max_percentage = int_val;
+ else if (!ci_strcmp(argv[2], "caps_count"))
+ profile->caps_min_count = int_val;
+ else if (!ci_strcmp(argv[2], "repeat_tolerance"))
+ profile->repeats_max_count = int_val;
+ else if (!ci_strcmp(argv[2], "repeat_length"))
+ profile->repeats_min_length = int_val;
+ else if (!ci_strcmp(argv[2], "symbol_repeat"))
+ profile->symbol_repeat_max_count = int_val;
+ else if (!ci_strcmp(argv[2], "character_repeat"))
+ profile->character_repeat_max_count = int_val;
+ else if (!ci_strcmp(argv[2], "continuous_symbol"))
+ profile->symbol_max_count = int_val;
+ else if (!ci_strcmp(argv[2], "flood_tolerance"))
+ profile->tolerance_flood = int_val;
+ else if (!ci_strcmp(argv[2], "spam_tolerance"))
+ profile->tolerance_spam = int_val;
+ else if (!ci_strcmp(argv[2], "spam_multiplier"))
+ profile->constant_spam = dbl_val;
+ else if (!ci_strcmp(argv[2], "warn_limit"))
+ profile->tolerance_warn = int_val;
+ else if (!ci_strcmp(argv[2], "kick_limit"))
+ profile->tolerance_kick = int_val;
+ else if (!ci_strcmp(argv[2], "ban_limit"))
+ profile->tolerance_remove = int_val;
+ else
+ {
+ helpmod_reply(sender, returntype, "Can not edit a lamer control profile: No component named %s", argv[2]);
+ return;
+ }
+ helpmod_reply(sender, returntype, "Lamer control profile component value changed succesfully.");
+ }
+}
+
+static void helpmod_cmd_ged (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ helpmod_editor *editor;
+
+ if (sender->editor == NULL)
+ { /* Start a new editor */
+ if (argc == 0)
+ {
+ helpmod_reply(sender, returntype, "Can not use ged: Filename not specified");
+ return;
+ }
+ editor = hed_open(sender, argv[0]);
+ if (editor == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not use ged: Invalid filename %s", argv[0]);
+ return;
+ }
+ if (editor->user != sender)
+ {
+ helpmod_reply(sender, returntype, "Can not use ged: File %s is currently being edited by %s", editor->filename, huser_get_nick(editor->user));
+ return;
+ }
+ editor->user = sender;
+ sender->editor = editor;
+
+ helpmod_reply(sender, returntype, "Ged: %d", hed_byte_count(editor));
+ }
+ else
+ {
+ hed_command(sender, returntype, ostr, argc, argv);
+ }
+}
+
+static void helpmod_cmd_text (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ hchannel *hchan;
+ DEFINE_HCHANNEL;
+ FILE *in;
+
+ if (argc == 0 || !ci_strcmp(argv[0], "list"))
+ {
+ DIR *dir;
+ struct dirent *dent;
+ char buffer[384], **lines, *start;
+ int nwritten, bufpos = 0, nlines = 0,i;
+
+ dir = opendir(HELPMOD_TEXT_DIR);
+ assert(dir != NULL);
+
+ /* First pass, count */
+ for (dent = readdir(dir);dent != NULL;dent = readdir(dir))
+ {
+ /* Skip stuff like . and .. */
+ if (!strncmp(dent->d_name, ".", 1))
+ continue;
+ nlines++;
+ }
+
+ if (nlines == 0)
+ {
+ helpmod_reply(sender, returntype, "No texts are available.");
+ return;
+ }
+
+ helpmod_reply(sender, returntype, "Following texts are available:");
+
+ {
+ lines = (char **)malloc(sizeof(char*) * nlines);
+ *lines = (char *)malloc(sizeof(char) * (HED_FILENAME_LENGTH+1) * nlines);
+ /* We need the start to free this array */
+ start = *lines;
+ for(i=0;i < nlines;i++)
+ lines[i] = &lines[0][(HED_FILENAME_LENGTH+1) * i];
+ }
+
+ /* Second pass, create array */
+ rewinddir(dir);
+ for (dent = readdir(dir), i = 0;dent != NULL && i < nlines;dent = readdir(dir))
+ {
+ /* Skip stuff like . and .. */
+ if (!strncmp(dent->d_name, ".", 1))
+ continue;
+ strncpy(lines[i], dent->d_name, 64);
+ i++;
+ }
+ /* Sort */
+ qsort(*lines, nlines, sizeof(char)*(HED_FILENAME_LENGTH+1), (int (*)(const void*, const void*))&strcmp);
+
+ for (i = 0;i < nlines;i++)
+ {
+ if (bufpos)
+ {
+ buffer[bufpos] = ' ';
+ bufpos++;
+ }
+ sprintf(buffer + bufpos, "%s%n", lines[i], &nwritten);
+ bufpos+=nwritten;
+
+ if (bufpos > (384 - (HED_FILENAME_LENGTH+1)))
+ {
+ helpmod_reply(sender, returntype, buffer);
+ bufpos = 0;
+ }
+ }
+
+ if (bufpos)
+ helpmod_reply(sender, returntype, buffer);
+
+ free(start);
+ free(lines);
+
+ return;
+ }
+ else if (!ci_strcmp(argv[0], "show"))
+ {
+ char fname_buffer[128], buffer[512];
+ if (argc < 2)
+ {
+ helpmod_reply(sender, returntype, "Can not show text: Text not specified");
+ return;
+ }
+ if (!hed_is_valid_filename(argv[1]))
+ {
+ helpmod_reply(sender, returntype, "Can not show text: Invalid filename");
+ return;
+ }
+ sprintf(fname_buffer, HELPMOD_TEXT_DIR"/%s" ,argv[1]);
+ in = fopen(fname_buffer, "rwt");
+ if (in == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not show text: Text %s not found", argv[1]);
+ return;
+ }
+ while (!feof(in))
+ {
+ if (!fgets(buffer, 512, in))
+ break;
+ if (returntype != NULL && huser_get_level(sender) >= H_TRIAL)
+ helpmod_message_channel(hchannel_get_by_channel(returntype), "%s", buffer);
+ else
+ helpmod_reply(sender, returntype, "%s", buffer);
+ }
+ fclose (in);
+ return;
+ }
+
+ if (huser_get_level(sender) < H_STAFF)
+ {
+ helpmod_reply(sender, returntype, "Can not handle text: Insufficient user level");
+ return;
+ }
+
+ if (!ci_strcmp(argv[0], "add"))
+ {
+ char fname_buffer[128];
+ if (argc < 2)
+ {
+ helpmod_reply(sender, returntype, "Can not add text: Text not specified");
+ return;
+ }
+ if (!hed_is_valid_filename(argv[1]))
+ {
+ helpmod_reply(sender, returntype, "Can not add text: Invalid filename");
+ return;
+ }
+ sprintf(fname_buffer, HELPMOD_TEXT_DIR"/%s" ,argv[1]);
+ if ((in = fopen(fname_buffer, "rt")) != NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not add text: Text %s already exists", argv[1]);
+ return;
+ }
+ else
+ {
+ if ((in = fopen(fname_buffer, "wt")) == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not add text: Unexpected error, please contact strutsi");
+ return;
+ }
+ fclose(in);
+ }
+ helpmod_reply(sender, returntype, "Text %s added succesfully", argv[1]);
+ }
+ else if (!ci_strcmp(argv[0], "del"))
+ {
+ char fname_buffer[128];
+ if (argc < 2)
+ {
+ helpmod_reply(sender, returntype, "Can not delete text: Text not specified");
+ return;
+ }
+ if (!hed_is_valid_filename(argv[1]))
+ {
+ helpmod_reply(sender, returntype, "Can not delete text: Invalid filename");
+ return;
+ }
+ sprintf(fname_buffer, HELPMOD_TEXT_DIR"/%s" ,argv[1]);
+
+ if (!remove(fname_buffer))
+ helpmod_reply(sender, returntype, "Text %s removed", argv[1]);
+ else
+ helpmod_reply(sender, returntype, "Can not delete text: Text %s does not exist or can not be deleted", argv[1]);
+ }
+ else
+ {
+ helpmod_reply(sender, returntype, "Can not handle text: Unknown operation %s", argv[0]);
+ return;
+ }
+}
+
+static void helpmod_cmd_rating (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ hchannel *hchan;
+ hstat_account_entry sum = {0,0,0,0};
+ hstat_account *ptr;
+ int i;
+
+ DEFINE_HCHANNEL;
+
+ HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
+
+ if (hchan == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not show rating: Unknown channel");
+ return;
+ }
+ if (sender->account == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not show rating: You do not have an account");
+ return;
+ }
+ for (ptr = sender->account->stats;ptr != NULL;ptr = ptr->next)
+ if (ptr->hchan == hchan)
+ {
+ if (hstat_day() == 0)
+ { /* Sunday screws the indexing */
+ for (i = 0;i < 7;i++)
+ HSTAT_ACCOUNT_SUM(sum, sum, ptr->week[i]);
+ }
+ else
+ { /* Normal case */
+ for (i = 1;i <= hstat_day();i++)
+ HSTAT_ACCOUNT_SUM(sum, sum, ptr->week[i]);
+ }
+
+ helpmod_reply(sender, returntype, "Your rating for channel %s for this week is: %s", hchannel_get_name(hchan), helpmod_strtime(sum.time_spent));
+ return;
+ }
+ helpmod_reply(sender, returntype, "Can not show rating: You do not have any statistics for channel %s", hchannel_get_name(hchan));
+}
+
+static void helpmod_cmd_writedb (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ rename(HELPMOD_DEFAULT_DB, HELPMOD_DEFAULT_DB".old");
+ helpmod_config_write(HELPMOD_DEFAULT_DB);
+
+ helpmod_reply(sender, returntype, "Database written");
+}
+
+static void helpmod_cmd_evilhack1 (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ int tmp;
+
+ if (argc == 0)
+ helpmod_reply(sender, returntype, "hstat_cycle: %d", hstat_cycle);
+ else
+ {
+ if (!sscanf(argv[0], "%d", &tmp) || tmp < 0)
+ {
+ helpmod_reply(sender, returntype, "Invalid argument");
+ return;
+ }
+ hstat_cycle = tmp;
+ helpmod_reply(sender, returntype, "hstat_cycle is now: %d", hstat_cycle);
+ }
+}
+
+static void helpmod_cmd_evilhack2 (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ haccount *hacc = haccounts;
+ hchannel *hchan;
+ hstat_account *ptr;
+ hstat_account_entry tmp_account;
+ hstat_channel_entry tmp_channel;
+ int first, second;
+
+ if (argc != 2)
+ {
+ helpmod_reply(sender, returntype, "Syntax error: evilhack2 <first> <second>");
+ return;
+ }
+
+ if (!sscanf(argv[0],"%d", &first) || first < 0 || first > 9)
+ {
+ helpmod_reply(sender, returntype, "Syntax error: Invalid first");
+ return;
+ }
+
+ if (!sscanf(argv[1],"%d", &second) || second < 0 || second > 9)
+ {
+ helpmod_reply(sender, returntype, "Syntax error: Invalid second");
+ return;
+ }
+
+ for (;hacc;hacc = hacc->next)
+ for (ptr = hacc->stats;ptr;ptr = ptr->next)
+ {
+ tmp_account = ptr->longterm[first];
+ ptr->longterm[first] = ptr->longterm[second];
+ ptr->longterm[second] = tmp_account;
+ }
+
+ for (hchan = hchannels;hchan;hchan = hchan->next)
+ {
+ tmp_channel = hchan->stats->longterm[first];
+ hchan->stats->longterm[first] = hchan->stats->longterm[second];
+ hchan->stats->longterm[second] = tmp_channel;
+ }
+
+ helpmod_reply(sender, returntype, "Evilhack2 done: Swapped %d and %d", first, second);
+}
+
+static void helpmod_cmd_channel (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ hchannel *hchan;
+ hchannel_user *hchanuser;
+
+ DEFINE_HCHANNEL;
+
+ if (hchan == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not show channel: Channel not specified");
+ return;
+ }
+
+ HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
+
+ helpmod_reply(sender, returntype, "Users for channel %s", hchannel_get_name(hchan));
+ helpmod_reply(sender, returntype, "Nick Account User level Idle time");
+
+ for (hchanuser = hchan->channel_users;hchanuser;hchanuser=hchanuser->next)
+ helpmod_reply(sender, returntype, "%-16s %-16s %-24s %s",hchanuser->husr->real_user->nick,hchanuser->husr->account?hchanuser->husr->account->name->content:"-",hlevel_name(huser_get_level(hchanuser->husr)), helpmod_strtime(time(NULL)-huser_on_channel(hchanuser->husr, hchan)->last_activity));
+
+ helpmod_reply(sender, returntype, "Listed %d users for channel %s", hchannel_count_users(hchan, H_ANY), hchannel_get_name(hchan));
+}
+
+static void helpmod_cmd_weekstats (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+ hchannel *hchan;
+ hstat_accounts_array arr;
+ int i;
+ hlevel lvl = H_ANY;
+
+ DEFINE_HCHANNEL;
+
+ if (hchan == NULL)
+ {
+ helpmod_reply(sender, returntype, "Can not list weekly stats: Channel not specified");
+ return;
+ }
+
+ HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
+
+ if (argc >= 1)
+ {
+ if (!ci_strcmp(argv[0], "opers") || !ci_strcmp(argv[0], "o"))
+ lvl = H_OPER;
+ else if (!ci_strcmp(argv[0], "staff") || !ci_strcmp(argv[0], "s"))
+ lvl = H_STAFF;
+ else if (!ci_strcmp(argv[0], "all") || !ci_strcmp(argv[0], "a"))
+ lvl = H_ANY;
+ }
+
+ arr = create_hstat_account_array(hchan, lvl, HSTAT_ACCOUNT_ARRAY_WEEKSTATS);
+
+ helpmod_reply(sender, returntype, "Weekly statistics for %ss on channel %s", hlevel_name(lvl), hchannel_get_name(hchan));
+
+ for (i=0;i < arr.arrlen && arr.array[i].time_spent > HDEF_m;i++)
+ helpmod_reply(sender, returntype, "%-20s %-20s %-20s",((haccount*)(arr.array[i].owner))->name->content, helpmod_strtime(arr.array[i].prime_time_spent), helpmod_strtime(arr.array[i].time_spent));
+
+ free(arr.array);
+}
+