/* * Playground+ - multi.c * Multi (or chains) code written by Segtor * --------------------------------------------------------------------------- */ #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include "include/config.h" #ifdef ALLOW_MULTIS #define MULTI_VERSION "1.35.1" #include "include/player.h" #include "include/proto.h" multi *all_multis; void init_multis(void) { all_multis = NULL; } void destroy_all_multis(void) { multi *mscan = all_multis, *mscan2 = NULL; multiplayer *pscan, *pscan2; while (mscan) { pscan = mscan->players_list; pscan2 = NULL; while (pscan) { pscan2 = pscan; pscan = pscan->next_player; FREE(pscan2); } mscan2 = mscan; mscan = mscan->next_multi; FREE(mscan2); } all_multis = 0; } void multi_change_entries(player * p1, player * p2) { multi *mscan = all_multis; multiplayer *pscan, *prev; while (mscan) { pscan = mscan->players_list; prev = NULL; while (pscan && (pscan->the_player != p1)) { prev = pscan; pscan = pscan->next_player; } if (pscan->the_player == p1) pscan->the_player = p2; mscan = mscan->next_multi; } } int get_number(int real_number) { return ((real_number - 1) / 32); } int get_bit(int real_number) { return ((real_number - 1) % 32); } int get_real_number(int number, int bit) { return ((number * 32 + bit) + 1); } int multi_get_new_number(void) { multi *mscan = all_multis; int inuse[32]; /* 32 * 32 = 1024 possible multis */ int i, j; for (i = 0; i < 32; i++) inuse[i] = 0; /* create list of multis in use */ while (mscan) { inuse[get_number(mscan->number)] |= (2 << get_bit(mscan->number)); mscan = mscan->next_multi; } /* find free number */ for (i = 0; i < 32; i++) for (j = 0; j < 32; j++) if (!(inuse[i] & 2 << j)) return (get_real_number(i, j)); /* none found */ return 0; } void remove_from_multis(player * p) { multi *mscan = all_multis; multiplayer *pscan; while (mscan) { pscan = mscan->players_list; while (pscan) { if (pscan->the_player == p) pscan->the_player = NULL; pscan = pscan->next_player; } mscan = mscan->next_multi; } } void remove_from_multi(player * p, multi * m) { multiplayer *pscan; if (!(m->players_list)) return; pscan = m->players_list; while (pscan) { if (pscan->the_player == p) pscan->the_player = NULL; pscan = pscan->next_player; } } void tell_multi(int number, player * p, char *str) { multi *mscan = find_multi_from_number(number); multiplayer *pscan; int curr_sys_col; int is_emote = 0, br; int curr_mode; sys_color_atm = TELsc; command_type |= MULTI_COM; if (number < 0) { number = -number; is_emote = 1; mscan = find_multi_from_number(number); } if (mscan) { mscan->multi_idle = 0; mscan->multi_flags &= ~MULTI_WARNED; if (mscan->multi_flags & MULTI_FRIENDSLIST) sys_color_atm = FRTsc; curr_sys_col = sys_color_atm; pscan = mscan->players_list; while (pscan) { sys_color_atm = curr_sys_col; curr_mode = command_type; if ((pscan->the_player) && (pscan->the_player->tag_flags & BLOCK_MULTIS)) { command_type = 0; sys_color_atm = SYSsc; if (p) TELLPLAYER(p, " %s is blocking multis\n", pscan->the_player->name); command_type = curr_mode; } else if (pscan->the_player && ((pscan->the_player->tag_flags & BLOCK_FRIENDS) && (mscan->multi_flags & MULTI_FRIENDSLIST))) { command_type = 0; sys_color_atm = SYSsc; if (p) TELLPLAYER(p, " %s is blocking friends\n", pscan->the_player->name); command_type = curr_mode; } else if ((pscan->the_player) && (pscan->the_player->tag_flags & BLOCK_TELLS)) { command_type = 0; sys_color_atm = SYSsc; if (p) TELLPLAYER(p, " %s is blocking tells\n", pscan->the_player->name); command_type = curr_mode; } else { if (pscan->the_player != p) { if (pscan->the_player) { if (p && !(command_type & (ECHO_COM | REMOVE_COM))) { if (is_emote && emote_no_break(*str)) { TELLPLAYER(pscan->the_player, "(%d) %s%s", number, p->name, str); #ifdef INTELLIBOTS if (pscan->the_player->residency & ROBOT_PRIV) intelligent_robot(p, pscan->the_player, str, IR_PRIVATE); #endif } else { br = 0; if (*str == '\007' && pscan->the_player->custom_flags & NOBEEPS) { br = 1; str++; } TELLPLAYER(pscan->the_player, "(%d) %s %s", number, p->name, str); #ifdef INTELLIBOTS if (pscan->the_player->residency & ROBOT_PRIV) intelligent_robot(p, pscan->the_player, str, IR_PRIVATE); #endif if (br) str--; } } else { TELLPLAYER(pscan->the_player, "(%d) %s", number, str); #ifdef INTELLIBOTS if (p && (pscan->the_player->residency & ROBOT_PRIV)) intelligent_robot(p, pscan->the_player, str, IR_PRIVATE); #endif } } } } sys_color_atm = curr_sys_col; pscan = pscan->next_player; } } command_type &= ~MULTI_COM; sys_color_atm = SYSsc; if (mscan) { pscan = mscan->players_list; while (pscan) { if (pscan->the_player) pscan->the_player->flags &= ~TAGGED; pscan = pscan->next_player; } } } void vtell_multi(int number, player * p, char *format,...) { va_list argum; char *oldstack; oldstack = stack; va_start(argum, format); vsprintf(stack, format, argum); va_end(argum); stack = end_string(stack); tell_multi(number, p, oldstack); stack = oldstack; } multi *remove_multi_player(player *pc, multi * m1, multi * m2, char *reason) { multi *m3 = m1->next_multi; multiplayer *p, *n; if (!m1) return (multi *) 0; command_type |= REMOVE_COM; if (config_flags & cfMULTI_INFORM) vtell_multi(m1->number, pc, "Multi removed%s\n", reason); command_type &= ~REMOVE_COM; if (m2) m2->next_multi = m3; else all_multis = m3; p = m1->players_list; while (p) { n = p; p = p->next_player; FREE(n); } FREE(m1); if (m2) return (m2->next_multi); return m3; } multi *remove_multi(multi *m1, multi *m2, char *reason) { return remove_multi_player(NULL, m1, m2, reason); } void update_multis(void) { multi *mscan = all_multis, *mscan2 = NULL; multiplayer *temppl = NULL, *pscan = NULL; char ti1[250], ti2[250]; int ci; while (mscan) { action = "multi: list empty"; mscan->multi_idle++; /* remove multi if player list empty */ if (!(mscan->players_list)) { mscan = remove_multi(mscan, mscan2, ""); continue; } action = "multi: check idle"; /* remove multi for being idle too long */ ci = atoi(get_config_msg("multi_idle_out")); ci *= ONE_MINUTE; if (ci > 0 && mscan->multi_idle >= ci) { if (!(mscan->multi_flags & MULTI_NOIDLEOUT)) { mscan = remove_multi(mscan, mscan2, " due to being idle"); continue; } } action = "multi: owner lost"; /* remove friends multi that lost its owner */ if (mscan->multi_flags & MULTI_FRIENDSLIST) { if (!(mscan->players_list->the_player)) { mscan = remove_multi(mscan, mscan2, " due to owner leaving"); continue; } } action = "multi: enough users"; /* remove multi if too few people on */ if (players_on_multi(mscan) < 2) { mscan = remove_multi(mscan, mscan2, " due to too few users"); continue; } if (config_flags & cfMULTI_INFORM) { action = "multi: warn idle"; /* warn idle multis */ ci = atoi(get_config_msg("multi_idle_out")); ci *= ONE_MINUTE; if (ci > 0) { if ((mscan->multi_idle >= (ci - 60)) && (!(mscan->multi_flags & MULTI_WARNED))) { if (!(mscan->multi_flags & MULTI_NOIDLEOUT)) { strcpy(ti1, word_time(ci - 60)); strcpy(ti2, word_time(ci)); vtell_multi(mscan->number, NULL, "Multi has been idle for %s, " "will timeout in %s\n", ti1, ti2); mscan->multi_flags |= MULTI_WARNED; mscan->multi_idle = ci - 60; } } } } action = "multi: catenate first"; /* catenate players list */ while (mscan->players_list) { if (mscan->players_list->the_player) break; temppl = mscan->players_list; mscan->players_list = mscan->players_list->next_player; FREE(temppl); } action = "multi: catenate next"; pscan = mscan->players_list; temppl = NULL; while (pscan) { if (!(pscan->the_player)) { temppl->next_player = pscan->next_player; FREE(pscan); pscan = temppl; } temppl = pscan; pscan = pscan->next_player; } mscan2 = mscan; mscan = mscan->next_multi; } action = ""; } int player_on_multi(player * p, multi * m) { multiplayer *pscan = m->players_list; while (pscan) { if (pscan->the_player == p) return 1; pscan = pscan->next_player; } return 0; } multi *find_multi_from_number(int number) { multi *mscan = all_multis; while (mscan) { if (mscan->number == number) return mscan; mscan = mscan->next_multi; } return NULL; } int find_friend_multi_number_name(char *pl_name) { multi *mscan = all_multis; while (mscan) { if (mscan->multi_flags & MULTI_FRIENDSLIST) if (mscan->players_list) if (mscan->players_list->the_player) if (!(strcasecmp(mscan->players_list->the_player->lower_name, pl_name))) return mscan->number; mscan = mscan->next_multi; } return 0; } int find_friend_multi_number(player * p) { return find_friend_multi_number_name(p->lower_name); } int players_on_multi(multi * m) { int count = 0; multiplayer *pscan; if (m) { pscan = m->players_list; while (pscan) { if (pscan->the_player) count++; pscan = pscan->next_player; } } return count; } int multi_count(void) { multi *mscan = all_multis; int count = 0; while (mscan) { count++; mscan = mscan->next_multi; } return count; } int assign_friends_multi(player * p) { int mn; mn = find_friend_multi_number(p); if (mn) return mn; mn = multi_get_new_number(); create_friends_multi(p, mn); return mn; } void add_to_friends_multis(player * p) { player *scan; list_ent *l; int mn; for (scan = flatlist_start; scan; scan = scan->flat_next) { l = find_list_entry(scan, p->name); if (l) if (l->flags & FRIEND) { mn = find_friend_multi_number(scan); if (mn) add_to_multi(p, find_multi_from_number(mn)); } } } void add_to_multi(player * p, multi * m) { multiplayer *pscan = NULL, *t = NULL; pscan = m->players_list; while (pscan) { t = pscan; pscan = pscan->next_player; } pscan = (multiplayer *) MALLOC(sizeof(multiplayer)); if (!pscan) { LOGF("multi", "Could not allocate memory for player %s to multi %d!", p->name, m->number); return; } pscan->next_player = NULL; pscan->the_player = p; if (t) t->next_player = pscan; else m->players_list = pscan; } /* creating multis */ void create_friends_multi(player * p, int number) { multi *new_multi = (multi *) MALLOC(sizeof(multi)); list_ent *l; player *p2; if (!new_multi) { LOGF("multi", "Could not create friends' multi for %s!", p->name); return; } new_multi->multi_flags = MULTI_FRIENDSLIST; new_multi->number = number; new_multi->multi_idle = 0; new_multi->next_multi = all_multis; all_multis = new_multi; new_multi->players_list = NULL; add_to_multi(p, new_multi); /* loop through players list */ if (p->saved) { l = p->saved->list_top; if (l) { do { if (l->flags & FRIEND && strcasecmp(l->name, "everyone")) { p2 = find_player_absolute_quiet(l->name); if (p2) add_to_multi(p2, new_multi); } l = l->next; } while (l); } } } /* multi talking stuff */ void multi_number_to_names(player * p, int number, char *str) { char *oldstr = str; multi *m = find_multi_from_number(number); multiplayer *mp; int pls, listed; if (!m) return; pls = players_on_multi(m); listed = 0; if (p == NULL) pls++; mp = m->players_list; while (mp) { if (!(mp->the_player == p)) { if (listed < (pls - 3)) sprintf(str, "%s, ", mp->the_player->name); else if (listed == (pls - 3)) sprintf(str, "%s and ", mp->the_player->name); else sprintf(str, "%s", mp->the_player->name); str = strchr(str, 0); listed++; } mp = mp->next_player; } str = oldstr; } int multi_exists(multi *m) { multi *scan = all_multis; multiplayer *pscan = NULL; int exists = 0, count = players_on_multi(m), count2; while (scan) { if (scan->multi_flags & MULTI_FRIENDSLIST) { scan = scan->next_multi; continue; } if (players_on_multi(scan) == count) { count2 = 0; pscan = scan->players_list; while (pscan) { if (player_on_multi(pscan->the_player, m)) count2++; else break; pscan = pscan->next_player; } if (count == count2) { exists = scan->number; break; } } scan = scan->next_multi; } return exists; } int solve_multi(player * p, char *str) { char *endp, *start, *oldstack = stack; int mn; player *p2; multi *mnew; if (isdigit(*str)) { if (strchr(str, ',')) { start = stack; while (*str && *str != ',') *stack++ = *str++; *stack++ = 0; if (*str) str++; mn = (int) strtol(start, &endp, 10); if (*endp) { tell_player(p, "Please enter a correct multi number\n"); stack = oldstack; return -1; } mnew = find_multi_from_number(mn); if (!mnew) { tell_player(p, "That multi does not exist\n"); stack = oldstack; return -1; } if (!(player_on_multi(p, mnew))) { tell_player(p, "You're not on that multi\n"); stack = oldstack; return -1; } if (mnew->multi_flags & MULTI_FRIENDSLIST) { tell_player(p, "You can't add people to friends multis\n"); stack = oldstack; return -1; } stack = start; while (*str) { start = stack; while (*str && *str != ',') *stack++ = *str++; *stack++ = 0; if (*str) str++; if (!strcasecmp(start, "me")) p2 = NULL; else { command_type |= NO_P_MATCH; p2 = find_player_global(start); command_type &= ~NO_P_MATCH; } if (p2 && !player_on_multi(p2, mnew)) add_to_multi(p2, mnew); stack = start; } return mn; } mn = (int) strtol(str, &endp, 10); if (*endp) { tell_player(p, "Please enter a correct multi number\n"); return -1; } mnew = find_multi_from_number(mn); if (!mnew) { tell_player(p, "No such multi exists\n"); return -1; } if (!(player_on_multi(p, mnew))) { tell_player(p, "You're not on that multi!\n"); return -1; } } else if (!(strcasecmp(str, "friends"))) { mn = find_friend_multi_number(p); } else if (strchr(str, ',')) { mnew = (multi *) MALLOC(sizeof(multi)); if (!mnew) { LOGF("multi", "Could not create multi for %s!", p->name); stack = oldstack; return -1; } mnew->next_multi = all_multis; mn = multi_get_new_number(); mnew->number = mn; mnew->multi_idle = 0; mnew->multi_flags = MULTI_NOIDLEOUT; mnew->players_list = NULL; add_to_multi(p, mnew); while (*str) { start = stack; while (*str && *str != ',') *stack++ = *str++; *stack++ = 0; if (*str) str++; if (!strcasecmp(start, "me")) p2 = NULL; else { command_type |= NO_P_MATCH; p2 = find_player_global(start); command_type &= ~NO_P_MATCH; } if (p2 && !player_on_multi(p2, mnew)) add_to_multi(p2, mnew); stack = start; } mnew->multi_flags &= ~MULTI_NOIDLEOUT; if (!multi_exists(mnew)) all_multis = mnew; else { mn = multi_exists(mnew); FREE(mnew); } } else { p2 = find_player_global(str); mn = find_friend_multi_number(p2); } stack = oldstack; return mn; } void multi_tell(player * p, char *str, char *msg) { char *scan, *mid, pnames[1000]; int mn; multi *m; mn = solve_multi(p, str); if (mn < 1) return; m = find_multi_from_number(mn); for (scan = msg; *scan; scan++); switch (*(--scan)) { case '?': mid = "asks of"; break; case '!': mid = "exclaims to"; break; default: mid = "tells"; break; } if (m->multi_flags & MULTI_FRIENDSLIST) { if (m->players_list->the_player == p) vtell_multi(mn, p, "%s %s friends '%s'\n", mid, their_player(p), msg); else vtell_multi(mn, p, "%s %s's friends '%s'\n", mid, m->players_list->the_player->name, msg); } else { pnames[0] = 0; multi_number_to_names(p, mn, pnames); if (config_flags & cfMULTIVERBOSE) vtell_multi(mn, p, "%s %s '%s'\n", mid, pnames, msg); else vtell_multi(mn, p, "%s you all '%s'\n", mid, msg); } switch (*scan) { case '?': mid = "ask of"; break; case '!': mid = "exclaim to"; break; default: mid = "tell"; break; } sys_color_atm = SYSsc; if (m->multi_flags & MULTI_FRIENDSLIST) { if (m->players_list->the_player == p) TELLPLAYER(p, "(%d) You %s your friends '%s'\n", mn, mid, msg); else TELLPLAYER(p, "(%d) You %s %s's friends '%s'\n", mn, mid, m->players_list->the_player->name, msg); } else { if (config_flags & cfMULTIVERBOSE) TELLPLAYER(p, "(%d) You %s %s '%s'\n", mn, mid, pnames, msg); else TELLPLAYER(p, "(%d) You %s them '%s'\n", mn, mid, msg); } } void multi_remote(player * p, char *str, char *msg) { int mn; multi *m; char pnames[1000]; char tostr[512]; mn = solve_multi(p, str); if (mn < 1) return; m = find_multi_from_number(mn); if (m->multi_flags & MULTI_FRIENDSLIST) { if (m->players_list->the_player == p) { if (config_flags & cfMULTIVERBOSE) vtell_multi(-mn, p, "%s (to %s friends)\n", msg, their_player(p)); else vtell_multi(-mn, p, "%s\n", msg); sys_color_atm = SYSsc; if (emote_no_break(*msg)) { if (config_flags & cfMULTIVERBOSE) TELLPLAYER(p, "(%d) You emote: %s%s (to your friends)\n", mn, p->name, msg); else TELLPLAYER(p, "(%d) You emote: %s%s\n", mn, p->name, msg); } else { if (config_flags & cfMULTIVERBOSE) TELLPLAYER(p, "(%d) You emote: %s %s (to your friends)\n", mn, p->name, msg); else TELLPLAYER(p, "(%d) You emote: %s %s\n", mn, p->name, msg); } } else { if (config_flags & cfMULTIVERBOSE) vtell_multi(-mn, p, "%s (to %s's friends)\n", msg, m->players_list->the_player->name); else vtell_multi(-mn, p, "%s\n", msg); sys_color_atm = SYSsc; if (emote_no_break(*msg)) { if (config_flags & cfMULTIVERBOSE) TELLPLAYER(p, "(%d) You emote: %s%s (to %s's friends)\n", mn, p->name, msg, m->players_list->the_player->name); else TELLPLAYER(p, "(%d) You emote: %s%s\n", mn, p->name, msg); } else { if (config_flags & cfMULTIVERBOSE) TELLPLAYER(p, "(%d) You emote: %s %s (to %s's friends)\n", mn, p->name, msg, m->players_list->the_player->name); else TELLPLAYER(p, "(%d) You emote: %s %s\n", mn, p->name, msg); } } } else { pnames[0] = 0; multi_number_to_names(p, mn, pnames); if (config_flags & cfMULTIVERBOSE) sprintf(tostr, " (to %s)", pnames); else memset(tostr, 0, 512); vtell_multi(-mn, p, "%s%s\n", msg, tostr); sys_color_atm = SYSsc; if (emote_no_break(*msg)) TELLPLAYER(p, "(%d) You emote: %s%s%s\n", mn, p->name, msg, tostr); else TELLPLAYER(p, "(%d) You emote: %s %s%s\n", mn, p->name, msg, tostr); } } void multi_rsing(player * p, char *str, char *msg) { char *oldstack = stack; sprintf(stack, "sings o/~ %s o/~", msg); stack = end_string(stack); multi_remote(p, str, oldstack); stack = oldstack; } void multi_yell(player * p, char *str, char *msg) { char *scan, *mid, pnames[1000]; int mn; multi *m; mn = solve_multi(p, str); if (mn < 1) return; m = find_multi_from_number(mn); for (scan = msg; *scan; scan++); switch (*(--scan)) { case '?': mid = "boggles at"; break; case '!': mid = "hollers at"; break; default: mid = "yells at"; break; } if (m->multi_flags & MULTI_FRIENDSLIST) { if (m->players_list->the_player == p) vtell_multi(mn, p, "\007%s %s friends '%s'\n", mid, their_player(p), msg); else vtell_multi(mn, p, "\007%s %s's friends '%s'\n", mid, m->players_list->the_player->name, msg); } else { pnames[0] = 0; multi_number_to_names(p, mn, pnames); vtell_multi(mn, p, "\007%s %s '%s'\n", mid, pnames, msg); } switch (*scan) { case '?': mid = "boggle at"; break; case '!': mid = "holler at"; break; default: mid = "yell at"; break; } sys_color_atm = SYSsc; if (m->multi_flags & MULTI_FRIENDSLIST) { if (m->players_list->the_player == p) TELLPLAYER(p, "(%d) You %s your friends '%s'\n", mn, mid, msg); else TELLPLAYER(p, "(%d) You %s %s's friends '%s'\n", mn, mid, m->players_list->the_player->name, msg); } else TELLPLAYER(p, "(%d) You %s %s '%s'\n", mn, mid, pnames, msg); } void multi_recho(player * p, char *str, char *msg) { int mn; multi *m; char pnames[1000]; char tostr[512]; mn = solve_multi(p, str); if (mn < 1) return; m = find_multi_from_number(mn); command_type |= ECHO_COM; if (m->multi_flags & MULTI_FRIENDSLIST) { if (m->players_list->the_player == p) { if (config_flags & cfMULTIVERBOSE) sprintf(tostr, " (to %s friends)", their_player(p)); else memset(tostr, 0, 512); vtell_multi(mn, p, "%s%s\n", msg, tostr); sys_color_atm = SYSsc; TELLPLAYER(p, "(%d) You echo: %s (to your friends)\n", mn, msg); } else { if (config_flags & cfMULTIVERBOSE) sprintf(tostr, " (to %s's friends)", m->players_list->the_player->name); else memset(tostr, 0, 512); vtell_multi(mn, p, "%s%s\n", msg, tostr); sys_color_atm = SYSsc; TELLPLAYER(p, "(%d) You echo: %s (to %s's friends)\n", mn, msg, m->players_list->the_player->name); } } else { pnames[0] = 0; multi_number_to_names(p, mn, pnames); if (config_flags & cfMULTIVERBOSE) sprintf(tostr, " (to %s)", pnames); else memset(tostr, 0, 512); vtell_multi(mn, p, "%s%s\n", msg, tostr); sys_color_atm = SYSsc; TELLPLAYER(p, "(%d) You echo: %s%s\n", mn, msg, tostr); } command_type &= ~ECHO_COM; } /* misc commands */ void multi_block(player * p, char *str) { if (*str) { if (strcasecmp(str, "on")) { if (strcasecmp(str, "off")) { tell_player(p, " Format: blockmulti [on/off]\n"); return; } p->tag_flags |= BLOCK_MULTIS; } else p->tag_flags &= ~BLOCK_MULTIS; } else p->tag_flags ^= BLOCK_MULTIS; if (!(p->tag_flags & BLOCK_MULTIS)) tell_player(p, " You decide to get multis again\n"); else tell_player(p, " You block multis\n"); } /* list multis player is on */ void list_multis_me_on(player * p) { multi *mscan = all_multis; char *oldstack = stack; int inuse[32]; int i, j, any = 0; for (i = 0; i < 32; i++) inuse[i] = 0; while (mscan) { if (player_on_multi(p, mscan)) any++; inuse[get_number(mscan->number)] |= (2 << get_bit(mscan->number)); mscan = mscan->next_multi; } if (!any) tell_player(p, " You aren't on any multis\n"); else { sprintf(stack, " You are on %d multis: ", any); stack = strchr(stack, 0); for (i = 0; i < 32; i++) for (j = 0; j < 32; j++) if (inuse[i] & 2 << j) if (player_on_multi(p, find_multi_from_number(get_real_number(i, j)))) { sprintf(stack, "%d, ", get_real_number(i, j)); stack = strchr(stack, 0); } stack--; stack--; *stack++ = '.'; *stack++ = '\n'; *stack++ = 0; tell_player(p, oldstack); } stack = oldstack; } /* staff list multis, only lists those multis that are in use */ void list_all_in_use(player * p) { multi *mscan = all_multis; char *oldstack = stack; int inuse[32]; int i, j, any = 0; for (i = 0; i < 32; i++) inuse[i] = 0; while (mscan) { any++; inuse[get_number(mscan->number)] |= (2 << get_bit(mscan->number)); mscan = mscan->next_multi; } if (!any) tell_player(p, " There are no multis currently in use\n"); else { sprintf(stack, " There are currently %d multis in use: ", any); stack = strchr(stack, 0); for (i = 0; i < 32; i++) for (j = 0; j < 32; j++) if (inuse[i] & 2 << j) { sprintf(stack, "%d, ", get_real_number(i, j)); stack = strchr(stack, 0); } stack--; stack--; *stack++ = '.'; *stack++ = '\n'; *stack++ = 0; tell_player(p, oldstack); } stack = oldstack; } /* * list multis / multi * -without parameters list all multis user is on * -with parameter list members of the multi * -for LOWER_ADMIN and higher, list also all multis in use, if used without * parameters */ void multi_list(player * p, char *str) { char *endp, pnames[1000]; int num; multi *m; if (*str) { num = (int) strtol(str, &endp, 10); if (*endp) { tell_player(p, "Multi number not correct\n"); return; } m = find_multi_from_number(num); if (!m) { tell_player(p, "No such multi exists\n"); return; } if (!(player_on_multi(p, m))) { tell_player(p, "You're not on that multi\n"); return; } if (m->multi_flags & MULTI_FRIENDSLIST) { if (m->players_list && m->players_list->the_player) { if (m->players_list->the_player == p) { pnames[0] = 0; multi_number_to_names(NULL, num, pnames); TELLPLAYER(p, "Multi %d: Your friends (%s)\n", num, pnames); } else TELLPLAYER(p, "Multi %d: Friends of %s\n", num, m->players_list->the_player->name); } else TELLPLAYER(p, "Multi %d has lost its owner\n", num); } else { pnames[0] = 0; multi_number_to_names(NULL, num, pnames); TELLPLAYER(p, "Multi %d: %s\n", num, pnames); } } else { list_multis_me_on(p); if (p->residency & LOWER_ADMIN) list_all_in_use(p); } } void multi_idle(player * p, char *str) { char *endp; int num; multi *m; if (!(*str)) { tell_player(p, " Format: idle_multi <number of multi>\n"); return; } num = (int) strtol(str, &endp, 10); if (*endp) { tell_player(p, " Multi number not correct\n"); return; } m = find_multi_from_number(num); if (!m) { tell_player(p, " No such multi in existence\n"); return; } if (!(player_on_multi(p, m))) { tell_player(p, " You're not on that multi\n"); return; } TELLPLAYER(p, " That multi has been idle for %s\n", word_time(m->multi_idle)); } void multi_kill(player *p, char *str) { multi *the_multi = NULL, *mscan = NULL, *mprev = NULL; int i; char *c = NULL, reason[80]; if (!(*str)) i = find_friend_multi_number_name(p->name); else if (!(p->residency & ADMIN)) { tell_player(p, " Format: kill_multi <multi number>\n"); return; } else { i = (int) strtol(str, &c, 10); if (i < 1 || i > 1024 || (c && *c)) { tell_player(p, " That is not a legal multi number.\n"); return; } } the_multi = find_multi_from_number(i); if (!the_multi) { if (*str) tell_player(p, " That multi doesn't even exist!\n"); else tell_player(p, " You don't have a friends multi to kill.\n"); return; } mscan = all_multis; while (mscan != the_multi) { mprev = mscan; mscan = mscan->next_multi; } strcpy(reason, ""); if (*str) sprintf(reason, " by %s", p->name); else sprintf(reason, " by owner"); (void) remove_multi_player(p, mscan, mprev, reason); tell_player(p, " You've removed the multi\n"); } void multi_remove(player *p, char *str) { int i; multi *the_multi = NULL; char *c; if (!str || !*str) { tell_player(p, " Format: rm_multi <number of multi>\n"); return; } i = (int) strtol(str, &c, 10); if (i < 1 || i > 1024 || (c && *c)) { tell_player(p, " That is not a legal multi number.\n"); return; } the_multi = find_multi_from_number(i); if (!the_multi) { tell_player(p, " You aren't even on that multi!\n"); return; } if (!player_on_multi(p, the_multi)) { tell_player(p, " You aren't even on that multi!\n"); return; } remove_from_multi(p, the_multi); vtell_multi(i, NULL, "%s removes %s from the multi\n", p->name, self_string(p)); tell_player(p, " You removed yourself from the multi.\n"); } void multis_version(void) { sprintf(stack, " -=*> PG+ Multis/Chains v%s (by Segtor) enabled.\n", MULTI_VERSION); stack = strchr(stack, 0); } #endif