+
+ return 0;
+}
+
+static CHANSERV_FUNC(cmd_spin)
+{
+ if(!channel)
+ return 1;
+
+ int type = 0, lamep = 1;
+ char *tstr;
+
+ tstr = conf_get_data("server/type", RECDB_QSTRING);
+ if(tstr) {
+ type = atoi(tstr);
+ if (type > 6)
+ lamep = 0;
+ }
+
+
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_WHEEL1", user->nick);
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_WHEEL2");
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_WHEEL3");
+
+ if(chanserv_conf.wheel->used < 1) {
+ /* wheel actions not defined! eek */
+ return 1;
+ }
+
+ const char *wheel = chanserv_conf.wheel->list[ (int) ( (chanserv_conf.wheel->used) * (rand() / (RAND_MAX + 1.0)) ) ];
+ if(!wheel && *wheel)
+ return 1;
+
+/* enable this to be able to manually specify a result for testing:
+ log_module(MAIN_LOG, LOG_DEBUG,"Testing wheel randomness: %s\n", wheel);
+ if(argc > 1) {
+ wheel = argv[1];
+ }
+*/
+
+ /* connection reset by peer */
+ if (!strcasecmp(wheel, "peer")) {
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_PEER");
+ if (type < 7)
+ irc_kill(chanserv, user, "Connection reset by peer");
+ else
+ irc_svsquit(chanserv, user, "Connection reset by peer");
+ }
+ /* part all channels */
+ else if (!strcasecmp(wheel, "partall")) {
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_PARTALL");
+ if (lamep)
+ lamepart(user);
+ else
+ sputsock("%s SJ %s 0 "FMT_TIME_T, self->numeric, user->numeric, now);
+ }
+ /* random time gline */
+ else if (!strcasecmp(wheel, "gline")) {
+ char target[IRC_NTOP_MAX_SIZE + 3];
+ int wtime = 120 + rand() % 600;
+
+ strcpy(target, "*@");
+ strcat(target, user->hostname);
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_GLINE");
+
+ gline_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, 1, 0);
+// irc_kill(chanserv, user, "Reward for spinning the wheel of misfortune!");
+ }
+ /* random shun */
+ else if (!strcasecmp(wheel, "shun")) {
+ char target[IRC_NTOP_MAX_SIZE + 3];
+ int wtime = 120 + rand() % 600;
+
+ strcpy(target, "*@");
+ strcat(target, user->hostname);
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_SHUN");
+
+ shun_add(chanserv->nick, target, wtime, "Reward for spinning the wheel of misfortune!", now, 1);
+ }
+ /* absolutely nothing */
+ else if (!strcasecmp(wheel, "nothing")) {
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_NOTHING");
+ }
+ /* join random chans and part em several times */
+ else if (!strcasecmp(wheel, "randjoin")) {
+ int complete = 0;
+ int rndchans = 0;
+ int chango = 0;
+ int roundz0r = 0;
+
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_RANDJOIN");
+ while(complete != 1) {
+ if (rndchans != 15) {
+ chango = 120 + rand() % 600;
+ sputsock("%s SJ %s #%d "FMT_TIME_T, self->numeric, user->numeric, chango, now);
+ rndchans++;
+ } else {
+ if (roundz0r != 1) {
+ if (lamep)
+ lamepart(user);
+ else
+ sputsock("%s SJ %s 0 "FMT_TIME_T, self->numeric, user->numeric, now);
+ roundz0r = 1;
+ rndchans = 0;
+ } else {
+ if (lamep)
+ lamepart(user);
+ else
+ sputsock("%s SJ %s 0 "FMT_TIME_T, self->numeric, user->numeric, now);
+ complete = 1;
+ }
+ }
+ }
+ }
+ /* abuse line added to /whois */
+ else if (!strcasecmp(wheel, "abusewhois")) {
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_ABUSEWHOIS");
+ irc_swhois(chanserv, user, "is being defecated on by services");
+ }
+ /* kick from each channel your in */
+ else if (!strcasecmp(wheel, "kickall")) {
+ unsigned int count, n;
+ struct modeNode *mn;
+
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_KICKALL");
+
+ for (n=count=0; n<user->channels.used; n++) {
+ mn = user->channels.list[n];
+ irc_kick(chanserv, user, mn->channel, "Reward for spinning the wheel of misfortune!");
+ }
+ }
+ /* random nick change */
+ else if (!strcasecmp(wheel, "nickchange")) {
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_NICKCHANGE");
+
+ char *oldnick = NULL;
+ char *oldident = NULL;
+ char *oldhost = NULL;
+ char abusednick[NICKLEN] = "";
+ int abusednum = 1 + (int) (10000.0 * (rand() / (RAND_MAX + 1.0)));
+ struct userNode *clone;
+
+ oldnick = strdup(user->nick);
+ oldident = strdup(user->ident);
+ oldhost = strdup(user->hostname);
+
+ //snprintf(abusednick, NICKLEN, "Abused%d", abusednum+(1 + rand() % 120));
+ while (1) {
+ snprintf(abusednick, NICKLEN, "Abused%d", abusednum+(1 + rand() % 120));
+ log_module(MAIN_LOG, LOG_DEBUG, "Abused Nick: %s, Client Nick: %s", abusednick, user->nick);
+ if(!GetUserH(abusednick))
+ break;
+ }
+
+ SVSNickChange(user, abusednick);
+ irc_svsnick(chanserv, user, abusednick);
+
+ clone = AddClone(oldnick, oldident, oldhost, "I got abused by the wheel of misfortune :D");
+ timeq_add(now + 300, chanserv_remove_abuse, clone->nick);
+ }
+ /* kill */
+ else if (!strcasecmp(wheel, "kill")) {
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_KILL");
+
+ DelUser(user, chanserv, 1, "Reward for spinning the wheel of misfortune!");
+ //irc_kill(chanserv, user, "Reward for spinning the wheel of misfortune!");
+ }
+ /* service ignore */
+ else if (!strcasecmp(wheel, "svsignore")) {
+ int gagged, ignoretime = 0;
+ char target[IRC_NTOP_MAX_SIZE + 13];
+
+ if(IsOper(user)) {
+ /* we cant gag opers, so just verbally abuse them */
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_SVSIGNORE_OPER");
+ return 1;
+ }
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_SVSIGNORE");
+
+ strcpy(target, "*!*@");
+ strcat(target, user->hostname);
+ ignoretime = now + (1 + rand() % 120);
+
+ gagged = gag_create(target, "wheelofabuse", "Reward for spinning the wheel of misfortune!", ignoretime);
+ }
+ /* kick and ban from each channel your in */
+ else if (!strcasecmp(wheel, "kickbanall")) {
+ unsigned int count, n;
+ struct modeNode *mn;
+ //char ban[IRC_NTOP_MAX_SIZE + 1];
+
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_KICKBANALL");
+
+ //snprintf(ban, sizeof(ban), "*!*@%s", user->hostname);
+ for (n=count=0; n<user->channels.used; n++) {
+ struct mod_chanmode *change;
+/* struct banData *bData; */
+ unsigned int exists;
+/* int duration = 300; */
+ char *ban;
+
+ ban = generate_hostmask(user, GENMASK_STRICT_HOST|GENMASK_ANY_IDENT|GENMASK_USENICK);
+
+ log_module(MAIN_LOG, LOG_DEBUG, "Generated ban %s", ban);
+ mn = user->channels.list[n];
+ if(mn->channel->banlist.used >= MAXBANS) {
+ reply("CSMSG_BANLIST_FULL", mn->channel->name);
+ free(ban);
+ continue;
+ }
+
+/* bData = add_channel_ban(mn->channel->channel_info, ban, chanserv->nick, now, now, now + duration, "Reward for spinning the wheel of misfortune!"); */
+
+ change = mod_chanmode_alloc(1);
+ change->args[0].mode = MODE_REMOVE|MODE_CHANOP|MODE_HALFOP|MODE_VOICE;
+ change->args[0].u.member = GetUserMode(mn->channel, user);
+ change->argc = 1;
+
+ mod_chanmode_announce(chanserv, mn->channel, change);
+ mod_chanmode_free(change);
+
+ exists = ChannelBanExists(mn->channel, ban);
+ if(!exists) {
+ change = mod_chanmode_alloc(1);
+ change->args[0].mode = MODE_BAN;
+ change->args[0].u.hostmask = ban;
+ change->argc = 1;
+ mod_chanmode_announce(chanserv, mn->channel, change);
+ mod_chanmode_free(change);
+ }
+
+ if(exists) {
+ reply("CSMSG_REDUNDANT_BAN", ban, mn->channel->name);
+ free(ban);
+ }
+
+ irc_kick(chanserv, user, mn->channel, "Reward for spinning the wheel of misfortune!");
+ }
+ }
+ else {
+ send_target_message(1, channel->name, chanserv, "CSMSG_SPIN_UNKNOWN", wheel);
+ }
+
+ return 1;
+}
+
+#ifdef lame8ball
+static CHANSERV_FUNC(cmd_8ball)
+{
+ unsigned int i, j, accum;
+ const char *resp;
+
+ REQUIRE_PARAMS(2);
+ accum = 0;
+ for(i=1; i<argc; i++)
+ for(j=0; argv[i][j]; j++)
+ accum = (accum << 5) - accum + toupper(argv[i][j]);
+ resp = chanserv_conf.eightball->list[accum % chanserv_conf.eightball->used];
+ if(channel)
+ {
+ char response[MAXLEN];
+ sprintf(response, "\ 2%s\ 2: %s", user->nick, resp);
+ irc_privmsg(cmd->parent->bot, channel->name, response);
+ }
+ else
+ send_message_type(4, user, cmd->parent->bot, "%s", resp);
+ return 1;
+}
+
+#else /* Use cool 8ball instead */
+
+void eightball(char *outcome, int method, unsigned int seed)
+{
+ int answer = 0;
+
+#define NUMOFCOLORS 18
+ char ballcolors[50][50] = {"blue", "red", "green", "yellow",
+ "white", "black", "grey", "brown",
+ "yellow", "pink", "purple", "orange", "teal", "burgandy",
+ "fuchsia","turquoise","magenta", "cyan"};
+#define NUMOFLOCATIONS 50
+ char balllocations[50][55] = {
+ "Locke's house", "Oregon", "California", "Indiana", "Canada",
+ "Russia", "Japan", "Florida", "the Bahamas", "Hiroshima",
+ "the Caribbean", "the Everglades", "your head", "your pants", "your school",
+ "the Statue of Liberty", "Mt. Fugi", "your mother's house", "IRC", "OSU",
+ "Locke's cat", "the closet", "the washroom", "the lake", "Spain",
+ "the bathtub", "the toilet", "the sewer", "a horse", "Jupiter",
+ "Uranus", "Pluto", "a dark place", "your undies", "your shirt",
+ "your bra", "your hair", "your bed", "the couch", "the wall",
+ "Reed", "here --> [X]", "your brain", "Italy", "the Netherlands",
+ "Mars", "my hardware", "the bar", "Neverland Ranch", "Germany" };
+#define NUMOFPREPS 15
+ char ballpreps[50][50] = {
+ "Near", "Somewhere near", "In", "In", "In",
+ "In", "Hiding in", "Under", "Next to", "Over",
+ "Crying in", "Right beside", "Nowhere near", "North of", "Trying to find"};
+#define NUMOFNUMS 34
+ char ballnums[50][50] = {
+ "A hundred", "A thousand", "A few", "42",
+ "About 1", "About 2", "About 3", "About 4", "About 5", "About 6", "About 7", "About 8", "About 9", "About 10",
+ "1", "2", "3", "4", "5", "6", "7", "8", "9", "Ten",
+ "1", "2", "3", "4", "5", "6", "7", "8", "9", "Ten",
+ };
+#define NUMOFMULTS 8
+ char ballmults[50][50] = { " million", " or so", " thousand", "", " or less", " or more", "", ""};
+
+ /* Method:
+ * 0: normal (Not used in x3)
+ * 1: color
+ * 2: where is
+ * 3: how many
+ */
+
+ srand(seed);
+ if (method == 1) /* A Color */
+ {
+ char tmp[MAXLEN];
+
+ answer = (rand() % 12); /* Make sure this is the # of entries */
+ switch(answer)
+ {
+ case 0: strcpy(tmp, "Very bright %s, I'd say.");
+ break;
+ case 1: strcpy(tmp, "Sort of a light %s color.");
+ break;
+ case 2: strcpy(tmp, "Dark and dreary %s.");
+ break;
+ case 3: strcpy(tmp, "Quite a pale shade of %s.");
+ break;
+ case 4: strcpy(tmp, "A gross kind of mucky %s.");
+ break;
+ case 5: strcpy(tmp, "Brilliant whiteish %s.");
+ break;
+ case 6: case 7: case 8: case 9: strcpy(tmp, "%s.");
+ break;
+ case 10: strcpy(tmp, "Solid %s.");
+ break;
+ case 11: strcpy(tmp, "Transparent %s.");
+ break;
+ default: strcpy(outcome, "An invalid random number was generated.");
+ return;
+ }
+ sprintf(outcome, tmp, ballcolors[rand() % NUMOFCOLORS]);
+ return;
+ }
+ else if (method == 2) /* Location */
+ {
+ sprintf(outcome, "%s %s.", ballpreps[rand() % NUMOFPREPS], balllocations[rand() % NUMOFLOCATIONS]);
+ }
+ else if (method == 3) /* Number of ___ */
+ {
+ sprintf(outcome, "%s%s.", ballnums[rand() % NUMOFNUMS], ballmults[rand() % NUMOFMULTS]);
+ }
+ else
+ {
+ //Debug(DBGWARNING, "Error in 8ball.");
+ }
+ return;
+}
+
+static CHANSERV_FUNC(cmd_8ball)
+{
+ char *word1, *word2, *word3;
+ static char eb[MAXLEN];
+ unsigned int accum, i, j;
+
+ REQUIRE_PARAMS(2);
+ accum = 0;
+ for(i=1; i<argc; i++)
+ for(j=0; argv[i][j]; j++)
+ accum = (accum << 5) - accum + toupper(argv[i][j]);
+
+ accum += time(NULL)/3600;
+ word1 = argv[1];
+ word2 = argc>2?argv[2]:"";
+ word3 = argc>3?argv[3]:"";
+
+/*** COLOR *****/
+ if((word2) && strcasecmp(word1, "what") == 0 && strcasecmp(word2, "color") == 0)
+ eightball(eb, 1, accum);
+ else if((word3) && strcasecmp(word1, "what's") == 0 && strcasecmp(word2, "the") == 0 && strcasecmp(word3, "color") == 0)
+ eightball(eb, 1, accum);
+ else if((word3) && strcasecmp(word1, "whats") == 0 && strcasecmp(word2, "the") == 0 && strcasecmp(word3, "color") == 0)
+ eightball(eb, 1, accum);
+/*** LOCATION *****/
+ else if(
+ (
+ word2 &&
+ (
+ (strcasecmp(word1, "where") == 0) &&
+ (strcasecmp(word2, "is") == 0)
+ )
+ ) ||
+ (
+ strcasecmp(word1, "where's") == 0
+ )
+ )
+ eightball(eb, 2, accum);
+/*** NUMBER *****/
+ else if((word2) && strcasecmp(word1, "how") == 0 && strcasecmp(word2, "many") == 0)
+ eightball(eb, 3, accum);
+/*** GENERIC *****/
+ else
+ {
+ /* Generic 8ball question.. so pull from x3.conf srvx style */
+ const char *resp;
+
+ resp = chanserv_conf.eightball->list[accum % chanserv_conf.eightball->used];
+ if(channel)
+ {
+ char response[MAXLEN];
+ sprintf(response, "\002%s\002: %s", user->nick, resp);
+ irc_privmsg(cmd->parent->bot, channel->name, response);
+ }
+ else
+ send_message_type(4, user, cmd->parent->bot, "%s", resp);
+ return 1;
+ }
+
+ if(channel)
+ {
+ char response[MAXLEN];
+ sprintf(response, "\002%s\002: %s", user->nick, eb);
+ irc_privmsg(cmd->parent->bot, channel->name, response);
+ }
+ else
+ send_message_type(4, user, cmd->parent->bot, "%s", eb);
+ return 1;
+}
+#endif
+
+static CHANSERV_FUNC(cmd_d)
+{
+ unsigned long sides, count, modifier, ii, total;
+ char response[MAXLEN], *sep;
+ const char *fmt;
+
+ REQUIRE_PARAMS(2);
+ if((count = strtoul(argv[1], &sep, 10)) < 1)
+ goto no_dice;
+ if(sep[0] == 0)
+ {
+ if(count == 1)
+ goto no_dice;
+ sides = count;
+ count = 1;
+ modifier = 0;
+ }
+ else if(((sep[0] == 'd') || (sep[0] == 'D')) && isdigit(sep[1])
+ && (sides = strtoul(sep+1, &sep, 10)) > 1)
+ {
+ if(sep[0] == 0)
+ modifier = 0;
+ else if((sep[0] == '-') && isdigit(sep[1]))
+ modifier = strtoul(sep, NULL, 10);
+ else if((sep[0] == '+') && isdigit(sep[1]))