mirror of
https://github.com/tbamud/tbamud.git
synced 2025-12-21 01:30:12 +01:00
Added Rhade's new history command, cleaned up more files --Rumble
This commit is contained in:
parent
42377c319a
commit
355095bdb6
26 changed files with 454 additions and 693 deletions
2
FAQ
2
FAQ
|
|
@ -10,7 +10,7 @@ This FAQ was originally written by Ryan Watkins (VampLestat) and later
|
|||
maintained by Alex Flectcher (Furry).
|
||||
|
||||
Another great resource is online at: http://www.circlemud.org/cdp/wtfaq/
|
||||
But, alot of the information has not been maintained and is outdated.
|
||||
But, a lot of the information has not been maintained and is outdated.
|
||||
______________________________________________________________________
|
||||
|
||||
Table of Contents
|
||||
|
|
|
|||
2
README
2
README
|
|
@ -68,7 +68,7 @@ Other Documentation
|
|||
If this information isn't enough to get you running, there's a lot more
|
||||
information available. All documentation (other than this file) is in
|
||||
the "doc" directory. Most of the files in the /doc directory are old and
|
||||
have not been updated in years, but they still contain alot of pertinent
|
||||
have not been updated in years, but they still contain a lot of pertinent
|
||||
information.
|
||||
|
||||
"The CircleMUD Administrator's Guide" (admin.pdf)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
*************************************************************************
|
||||
* The following people have reached immortality on tbaMUD. *
|
||||
*************************************************************************
|
||||
*************************************************************************
|
||||
* The following people have reached immortality on tbaMUD. *
|
||||
*************************************************************************
|
||||
|
||||
Immortals
|
||||
~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
*************************************************************************
|
||||
* The following people have reached immortality on tbaMUD. *
|
||||
*************************************************************************
|
||||
*************************************************************************
|
||||
* The following people have reached immortality on tbaMUD. *
|
||||
*************************************************************************
|
||||
|
||||
Implementors
|
||||
~~~~~~~~~~~~
|
||||
|
|
|
|||
179
src/act.comm.c
179
src/act.comm.c
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
#include "conf.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
|
||||
#include "structs.h"
|
||||
#include "utils.h"
|
||||
#include "comm.h"
|
||||
|
|
@ -48,16 +46,23 @@ ACMD(do_say)
|
|||
if (!*argument)
|
||||
send_to_char(ch, "Yes, but WHAT do you want to say?\r\n");
|
||||
else {
|
||||
char buf[MAX_INPUT_LENGTH + 14];
|
||||
char buf[MAX_INPUT_LENGTH + 14], *msg;
|
||||
|
||||
snprintf(buf, sizeof(buf), "$n says, '%s@n'", argument);
|
||||
act(buf, FALSE, ch, 0, 0, TO_ROOM | DG_NO_TRIG | LOG_MESSG);
|
||||
snprintf(buf, sizeof(buf), "$n@n says, '%s@n'", argument);
|
||||
msg = act(buf, FALSE, ch, 0, 0, TO_ROOM | DG_NO_TRIG);
|
||||
|
||||
struct char_data *vict;
|
||||
for (vict = world[IN_ROOM(ch)].people; vict; vict = vict->next_in_room)
|
||||
if (vict != ch && GET_POS(vict) > POS_SLEEPING)
|
||||
add_history(vict, msg, HIST_SAY);
|
||||
|
||||
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT))
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
else {
|
||||
delete_doubledollar(argument);
|
||||
send_to_char(ch, "You say, '%s@n'\r\n", argument);
|
||||
sprintf(buf, "You say, '%s@n'", argument);
|
||||
msg = act(buf, FALSE, ch, 0, 0, TO_CHAR | DG_NO_TRIG);
|
||||
add_history(ch, msg, HIST_SAY);
|
||||
}
|
||||
}
|
||||
/* trigger check */
|
||||
|
|
@ -65,7 +70,6 @@ ACMD(do_say)
|
|||
speech_wtrigger(ch, argument);
|
||||
}
|
||||
|
||||
|
||||
ACMD(do_gsay)
|
||||
{
|
||||
struct char_data *k;
|
||||
|
|
@ -90,10 +94,10 @@ ACMD(do_gsay)
|
|||
snprintf(buf, sizeof(buf), "$n tells the group, '%s@n'", argument);
|
||||
|
||||
if (AFF_FLAGGED(k, AFF_GROUP) && (k != ch))
|
||||
act(buf, FALSE, ch, 0, k, TO_VICT | TO_SLEEP | LOG_MESSG);
|
||||
act(buf, FALSE, ch, 0, k, TO_VICT | TO_SLEEP);
|
||||
for (f = k->followers; f; f = f->next)
|
||||
if (AFF_FLAGGED(f->follower, AFF_GROUP) && (f->follower != ch))
|
||||
act(buf, FALSE, ch, 0, f->follower, TO_VICT | TO_SLEEP | LOG_MESSG);
|
||||
act(buf, FALSE, ch, 0, f->follower, TO_VICT | TO_SLEEP);
|
||||
|
||||
if (PRF_FLAGGED(ch, PRF_NOREPEAT))
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
|
|
@ -102,23 +106,20 @@ ACMD(do_gsay)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void perform_tell(struct char_data *ch, struct char_data *vict, char *arg)
|
||||
{
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
char buf[MAX_STRING_LENGTH], *msg;
|
||||
|
||||
send_to_char(vict, "%s", CCRED(vict, C_NRM));
|
||||
snprintf(buf, sizeof(buf), "$n tells you, '%s'", arg);
|
||||
act(buf, FALSE, ch, 0, vict, TO_VICT | TO_SLEEP | LOG_MESSG);
|
||||
send_to_char(vict, "%s", CCNRM(vict, C_NRM));
|
||||
snprintf(buf, sizeof(buf), "%s$n tells you, '%s'%s", CCRED(vict, C_NRM), arg, CCNRM(vict, C_NRM));
|
||||
msg = act(buf, FALSE, ch, 0, vict, TO_VICT | TO_SLEEP);
|
||||
add_history(vict, msg, HIST_TELL);
|
||||
|
||||
if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_NOREPEAT))
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
else {
|
||||
send_to_char(ch, "%s", CCRED(ch, C_CMP));
|
||||
snprintf(buf, sizeof(buf), "You tell $N, '%s'", arg);
|
||||
act(buf, FALSE, ch, 0, vict, TO_CHAR | TO_SLEEP);
|
||||
send_to_char(ch, "%s", CCNRM(ch, C_CMP));
|
||||
snprintf(buf, sizeof(buf), "%sYou tell $N, '%s'%s", CCRED(ch, C_NRM), arg, CCNRM(ch, C_NRM));
|
||||
msg = act(buf, FALSE, ch, 0, vict, TO_CHAR | TO_SLEEP);
|
||||
add_history(ch, msg, HIST_TELL);
|
||||
}
|
||||
|
||||
if (!IS_NPC(vict) && !IS_NPC(ch))
|
||||
|
|
@ -145,10 +146,8 @@ int is_tell_ok(struct char_data *ch, struct char_data *vict)
|
|||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Yes, do_tell probably could be combined with whisper and ask, but
|
||||
* called frequently, and should IMHO be kept as tight as possible.
|
||||
*/
|
||||
/* Yes, do_tell probably could be combined with whisper and ask, but
|
||||
* called frequently, and should IMHO be kept as tight as possible. */
|
||||
ACMD(do_tell)
|
||||
{
|
||||
struct char_data *vict = NULL;
|
||||
|
|
@ -194,7 +193,6 @@ ACMD(do_tell)
|
|||
perform_tell(ch, vict, buf2);
|
||||
}
|
||||
|
||||
|
||||
ACMD(do_reply)
|
||||
{
|
||||
struct char_data *tch = character_list;
|
||||
|
|
@ -209,18 +207,12 @@ ACMD(do_reply)
|
|||
else if (!*argument)
|
||||
send_to_char(ch, "What is your reply?\r\n");
|
||||
else {
|
||||
/*
|
||||
* Make sure the person you're replying to is still playing by searching
|
||||
/* Make sure the person you're replying to is still playing by searching
|
||||
* for them. Note, now last tell is stored as player IDnum instead of
|
||||
* a pointer, which is much better because it's safer, plus will still
|
||||
* work if someone logs out and back in again.
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX: A descriptor list based search would be faster although
|
||||
* we could not find link dead people. Not that they can
|
||||
* hear tells anyway. :) -gg 2/24/98
|
||||
*/
|
||||
* work if someone logs out and back in again. A descriptor list based
|
||||
* search would be faster although we could not find link dead people.
|
||||
* Not that they can hear tells anyway. :) -gg 2/24/98 */
|
||||
while (tch != NULL && (IS_NPC(tch) || GET_IDNUM(tch) != GET_LAST_TELL(ch)))
|
||||
tch = tch->next;
|
||||
|
||||
|
|
@ -231,7 +223,6 @@ ACMD(do_reply)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ACMD(do_spec_comm)
|
||||
{
|
||||
char buf[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];
|
||||
|
|
@ -270,7 +261,7 @@ ACMD(do_spec_comm)
|
|||
char buf1[MAX_STRING_LENGTH];
|
||||
|
||||
snprintf(buf1, sizeof(buf1), "$n %s you, '%s'", action_plur, buf2);
|
||||
act(buf1, FALSE, ch, 0, vict, TO_VICT | LOG_MESSG);
|
||||
act(buf1, FALSE, ch, 0, vict, TO_VICT);
|
||||
|
||||
if (PRF_FLAGGED(ch, PRF_NOREPEAT))
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
|
|
@ -280,11 +271,7 @@ ACMD(do_spec_comm)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* buf1, buf2 = MAX_OBJECT_NAME_LENGTH
|
||||
* (if it existed)
|
||||
*/
|
||||
/* buf1, buf2 = MAX_OBJECT_NAME_LENGTH (if it existed) */
|
||||
ACMD(do_write)
|
||||
{
|
||||
struct obj_data *paper, *pen = NULL;
|
||||
|
|
@ -339,7 +326,6 @@ ACMD(do_write)
|
|||
pen = GET_EQ(ch, WEAR_HOLD);
|
||||
}
|
||||
|
||||
|
||||
/* ok.. now let's see what kind of stuff we've found */
|
||||
if (GET_OBJ_TYPE(pen) != ITEM_PEN)
|
||||
act("$p is no good for writing with.", FALSE, ch, pen, 0, TO_CHAR);
|
||||
|
|
@ -362,8 +348,6 @@ ACMD(do_write)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ACMD(do_page)
|
||||
{
|
||||
struct descriptor_data *d;
|
||||
|
|
@ -384,13 +368,13 @@ ACMD(do_page)
|
|||
if (GET_LEVEL(ch) > LVL_GOD) {
|
||||
for (d = descriptor_list; d; d = d->next)
|
||||
if (STATE(d) == CON_PLAYING && d->character)
|
||||
act(buf, FALSE, ch, 0, d->character, TO_VICT | LOG_MESSG);
|
||||
act(buf, FALSE, ch, 0, d->character, TO_VICT);
|
||||
} else
|
||||
send_to_char(ch, "You will never be godly enough to do that!\r\n");
|
||||
return;
|
||||
}
|
||||
if ((vict = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD)) != NULL) {
|
||||
act(buf, FALSE, ch, 0, vict, TO_VICT | LOG_MESSG);
|
||||
act(buf, FALSE, ch, 0, vict, TO_VICT);
|
||||
if (PRF_FLAGGED(ch, PRF_NOREPEAT))
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
else
|
||||
|
|
@ -400,16 +384,12 @@ ACMD(do_page)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* generalized communication func, originally by Fred C. Merkel (Torg) *
|
||||
*********************************************************************/
|
||||
|
||||
/* generalized communication func, originally by Fred C. Merkel (Torg) */
|
||||
ACMD(do_gen_comm)
|
||||
{
|
||||
struct descriptor_data *i;
|
||||
char color_on[24];
|
||||
char buf1[MAX_INPUT_LENGTH];
|
||||
char buf1[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH], *msg;
|
||||
|
||||
/* Array of flags which must _not_ be set in order for comm to be heard */
|
||||
int channels[] = {
|
||||
|
|
@ -422,12 +402,18 @@ ACMD(do_gen_comm)
|
|||
0
|
||||
};
|
||||
|
||||
/*
|
||||
* com_msgs: [0] Message if you can't perform the action because of noshout
|
||||
int hist_type[] = {
|
||||
HIST_HOLLER,
|
||||
HIST_SHOUT,
|
||||
HIST_GOSSIP,
|
||||
HIST_AUCTION,
|
||||
HIST_GRATS,
|
||||
};
|
||||
|
||||
/* com_msgs: [0] Message if you can't perform the action because of noshout
|
||||
* [1] name of the action
|
||||
* [2] message if you're not on the channel
|
||||
* [3] a color string.
|
||||
*/
|
||||
* [3] a color string. */
|
||||
const char *com_msgs[][4] = {
|
||||
{"You cannot holler!!\r\n",
|
||||
"holler",
|
||||
|
|
@ -518,8 +504,11 @@ ACMD(do_gen_comm)
|
|||
/* first, set up strings to be given to the communicator */
|
||||
if (PRF_FLAGGED(ch, PRF_NOREPEAT))
|
||||
send_to_char(ch, "%s", CONFIG_OK);
|
||||
else
|
||||
send_to_char(ch, "%sYou %s, '%s'%s\r\n", COLOR_LEV(ch) >= C_CMP ? color_on : "", com_msgs[subcmd][1], argument, CCNRM(ch, C_CMP));
|
||||
else {
|
||||
snprintf(buf1, sizeof(buf1), "%sYou %s, '%s'%s", COLOR_LEV(ch) >= C_CMP ? color_on : "", com_msgs[subcmd][1], argument, CCNRM(ch, C_CMP));
|
||||
msg = act(buf1, FALSE, ch, 0, 0, TO_CHAR);
|
||||
add_history(ch, msg, hist_type[subcmd]);
|
||||
}
|
||||
|
||||
snprintf(buf1, sizeof(buf1), "$n %ss, '%s'", com_msgs[subcmd][1], argument);
|
||||
|
||||
|
|
@ -538,15 +527,12 @@ ACMD(do_gen_comm)
|
|||
!AWAKE(i->character)))
|
||||
continue;
|
||||
|
||||
if (COLOR_LEV(i->character) >= C_NRM)
|
||||
send_to_char(i->character, "%s", color_on);
|
||||
act(buf1, FALSE, ch, 0, i->character, TO_VICT | TO_SLEEP | LOG_MESSG);
|
||||
if (COLOR_LEV(i->character) >= C_NRM)
|
||||
send_to_char(i->character, "%s", KNRM);
|
||||
snprintf(buf2, sizeof(buf2), "%s%s%s", (COLOR_LEV(i->character) >= C_NRM) ? color_on : "", buf1, KNRM);
|
||||
msg = act(buf2, FALSE, ch, 0, i->character, TO_VICT | TO_SLEEP);
|
||||
add_history(i->character, msg, hist_type[subcmd]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ACMD(do_qcomm)
|
||||
{
|
||||
if (!PRF_FLAGGED(ch, PRF_QUEST)) {
|
||||
|
|
@ -577,71 +563,10 @@ ACMD(do_qcomm)
|
|||
}
|
||||
for (i = descriptor_list; i; i = i->next)
|
||||
if (STATE(i) == CON_PLAYING && i != ch->desc && PRF_FLAGGED(i->character, PRF_QUEST))
|
||||
act(buf, 0, ch, 0, i->character, TO_VICT | TO_SLEEP | LOG_MESSG);
|
||||
act(buf, 0, ch, 0, i->character, TO_VICT | TO_SLEEP);
|
||||
}
|
||||
}
|
||||
|
||||
#define HIST_LENGTH 100
|
||||
|
||||
void free_hist_messg(struct descriptor_data *d)
|
||||
{
|
||||
struct txt_block *tmp = d->comms, *ftmp;
|
||||
while (tmp) {
|
||||
ftmp = tmp;
|
||||
tmp = tmp->next;
|
||||
if (ftmp->text)
|
||||
free(ftmp->text);
|
||||
free(ftmp);
|
||||
}
|
||||
d->comms = NULL;
|
||||
}
|
||||
|
||||
void new_hist_messg(struct descriptor_data *d, const char *msg)
|
||||
{
|
||||
struct txt_block *tmp = d->comms;
|
||||
int l = 0;
|
||||
if (!tmp) {
|
||||
CREATE(d->comms, struct txt_block, 1);
|
||||
d->comms->text = strdup(msg);
|
||||
return;
|
||||
}
|
||||
while (tmp->next)
|
||||
tmp = tmp->next;
|
||||
CREATE(tmp->next, struct txt_block, 1);
|
||||
tmp->next->text = strdup(msg);
|
||||
|
||||
for (tmp = d->comms; tmp ; tmp= tmp->next)
|
||||
l++;
|
||||
|
||||
for (; l > HIST_LENGTH && d->comms; l--) {
|
||||
tmp = d->comms;
|
||||
d->comms = tmp->next;
|
||||
if (tmp->text)
|
||||
free(tmp->text);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
ACMD(do_list_history)
|
||||
{
|
||||
struct txt_block *tmp;
|
||||
struct descriptor_data *d = ch->desc;
|
||||
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
if (!d->comms) {
|
||||
write_to_output(d, "No communications in history.\r\n");
|
||||
return;
|
||||
}
|
||||
write_to_output(d, "Last %d communications:\r\n", HIST_LENGTH);
|
||||
|
||||
for (tmp = d->comms;tmp;tmp = tmp->next)
|
||||
write_to_output(d, "%s%s%s", QWHT, tmp->text, QNRM);
|
||||
|
||||
free_hist_messg(d);
|
||||
}
|
||||
|
||||
void handle_webster_file(void) {
|
||||
FILE *fl;
|
||||
struct char_data *ch = find_char(last_webster_teller);
|
||||
|
|
@ -676,8 +601,6 @@ void handle_webster_file(void) {
|
|||
}
|
||||
fclose(fl);
|
||||
|
||||
|
||||
send_to_char(ch, "You get this feedback from Merriam-Webster:\r\n");
|
||||
page_string(ch->desc, info, 1);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,12 +100,10 @@ void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mode)
|
|||
{
|
||||
if (!obj || !ch) {
|
||||
log("SYSERR: NULL pointer in show_obj_to_char(): obj=%p ch=%p", obj, ch);
|
||||
/* SYSERR_DESC:
|
||||
* Somehow a NULL pointer was sent to show_obj_to_char() in either the
|
||||
* 'obj' or the 'ch' variable. The error will indicate which was NULL
|
||||
* by listing both of the pointers passed to it. This is often a
|
||||
* difficult one to trace, and may require stepping through a debugger.
|
||||
*/
|
||||
/* SYSERR_DESC: Somehow a NULL pointer was sent to show_obj_to_char() in
|
||||
* either the 'obj' or the 'ch' variable. The error will indicate which
|
||||
* was NULL by listing both of the pointers passed to it. This is often a
|
||||
* difficult one to trace, and may require stepping through a debugger. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -153,13 +151,11 @@ void show_obj_to_char(struct obj_data *obj, struct char_data *ch, int mode)
|
|||
|
||||
default:
|
||||
log("SYSERR: Bad display mode (%d) in show_obj_to_char().", mode);
|
||||
/* SYSERR_DESC:
|
||||
* show_obj_to_char() has some predefined 'mode's (argument #3) to tell
|
||||
* it what to display to the character when it is called. If the mode
|
||||
* is not one of these, it will output this error, and indicate what
|
||||
* mode was passed to it. To correct it, you will need to find the
|
||||
* call with the incorrect mode and change it to an acceptable mode.
|
||||
*/
|
||||
/* SYSERR_DESC: show_obj_to_char() has some predefined 'mode's (argument
|
||||
* #3) to tell it what to display to the character when it is called. If
|
||||
* the mode is not one of these, it will output this error, and indicate
|
||||
* what mode was passed to it. To correct it, you will need to find the
|
||||
* call with the incorrect mode and change it to an acceptable mode. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -564,14 +560,10 @@ char *find_exdesc(char *word, struct extra_descr_data *list)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the argument "look at <target>", figure out what object or char
|
||||
* matches the target. First, see if there is another char in the room
|
||||
* with the name. Then check local objs for exdescs.
|
||||
*
|
||||
* Thanks to Angus Mezick <angus@EDGIL.CCMAIL.COMPUSERVE.COM> for the
|
||||
* suggested fix to this problem.
|
||||
*/
|
||||
/* Given the argument "look at <target>", figure out what object or char
|
||||
* matches the target. First, see if there is another char in the room with
|
||||
* the name. Then check local objs for exdescs. Thanks to Angus Mezick
|
||||
* <angus@EDGIL.CCMAIL.COMPUSERVE.COM> for the suggested fix to this problem. */
|
||||
void look_at_target(struct char_data *ch, char *arg)
|
||||
{
|
||||
int bits, found = FALSE, j, fnum, i = 0;
|
||||
|
|
@ -861,7 +853,6 @@ ACMD(do_score)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ACMD(do_inventory)
|
||||
{
|
||||
send_to_char(ch, "You are carrying:\r\n");
|
||||
|
|
@ -905,14 +896,11 @@ ACMD(do_time)
|
|||
(time_info.hours % 12 == 0) ? 12 : (time_info.hours % 12),
|
||||
time_info.hours >= 12 ? "pm" : "am", weekdays[weekday]);
|
||||
|
||||
/*
|
||||
* Peter Ajamian <peter@PAJAMIAN.DHS.ORG> supplied the following as a fix
|
||||
/* Peter Ajamian <peter@PAJAMIAN.DHS.ORG> supplied the following as a fix
|
||||
* for a bug introduced in the ordinal display that caused 11, 12, and 13
|
||||
* to be incorrectly displayed as 11st, 12nd, and 13rd. Nate Winters
|
||||
* <wintersn@HOTMAIL.COM> had already submitted a fix, but it hard-coded a
|
||||
* limit on ordinal display which I want to avoid. -dak
|
||||
*/
|
||||
|
||||
* limit on ordinal display which I want to avoid. -dak */
|
||||
suf = "th";
|
||||
|
||||
if (((day % 100) / 10) != 1) {
|
||||
|
|
@ -1352,7 +1340,7 @@ ACMD(do_users)
|
|||
}
|
||||
} /* end while (parser) */
|
||||
send_to_char(ch,
|
||||
"Num Class Name State Idl Login@@ Site\r\n"
|
||||
"Num Class Name State Idl Login@@ Site\r\n"
|
||||
"--- ------- ------------ -------------- ----- -------- ------------------------\r\n");
|
||||
|
||||
one_argument(argument, arg);
|
||||
|
|
@ -2102,3 +2090,86 @@ ACMD(do_commands)
|
|||
if (no % 7 != 1)
|
||||
send_to_char(ch, "\r\n");
|
||||
}
|
||||
|
||||
void free_history(struct char_data *ch, int type)
|
||||
{
|
||||
struct txt_block *tmp = GET_HISTORY(ch, type), *ftmp;
|
||||
|
||||
while ((ftmp = tmp)) {
|
||||
tmp = tmp->next;
|
||||
if (ftmp->text)
|
||||
free(ftmp->text);
|
||||
free(ftmp);
|
||||
}
|
||||
GET_HISTORY(ch, type) = NULL;
|
||||
}
|
||||
|
||||
ACMD(do_history)
|
||||
{
|
||||
char arg[MAX_INPUT_LENGTH];
|
||||
|
||||
one_argument(argument, arg);
|
||||
|
||||
int type = search_block(arg, history_types, FALSE);
|
||||
if (!*arg || type < 0) {
|
||||
int i;
|
||||
|
||||
send_to_char(ch, "Usage: history <");
|
||||
for (i = 0; *history_types[i] != '\n'; i++) {
|
||||
send_to_char(ch, " %s ", history_types[i]);
|
||||
if (*history_types[i + 1] == '\n')
|
||||
send_to_char(ch, ">\r\n");
|
||||
else
|
||||
send_to_char(ch, "|");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (GET_HISTORY(ch, type) && GET_HISTORY(ch, type)->text && *GET_HISTORY(ch, type)->text) {
|
||||
struct txt_block *tmp;
|
||||
for (tmp = GET_HISTORY(ch, type); tmp; tmp = tmp->next)
|
||||
send_to_char(ch, "%s", tmp->text);
|
||||
/* Make this a 1 if you want history to clear after viewing */
|
||||
#if 0
|
||||
free_history(ch, type);
|
||||
#endif
|
||||
} else
|
||||
send_to_char(ch, "You have no history in that channel.\r\n");
|
||||
}
|
||||
|
||||
#define HIST_LENGTH 100
|
||||
void add_history(struct char_data *ch, char *str, int type)
|
||||
{
|
||||
int i = 0;
|
||||
struct txt_block *tmp = GET_HISTORY(ch, type);
|
||||
char time_str[MAX_STRING_LENGTH], buf[MAX_STRING_LENGTH];
|
||||
|
||||
time_t ct = time(0);
|
||||
strftime(time_str, sizeof(time_str), "%H:%M ", localtime(&ct));
|
||||
|
||||
sprintf(buf, "%s%s", time_str, str);
|
||||
|
||||
if (!tmp) {
|
||||
CREATE(GET_HISTORY(ch, type), struct txt_block, 1);
|
||||
GET_HISTORY(ch, type)->text = strdup(buf);
|
||||
}
|
||||
else {
|
||||
while (tmp->next)
|
||||
tmp = tmp->next;
|
||||
CREATE(tmp->next, struct txt_block, 1);
|
||||
tmp->next->text = strdup(buf);
|
||||
|
||||
for (tmp = GET_HISTORY(ch, type); tmp; tmp = tmp->next, i++);
|
||||
|
||||
for (; i > HIST_LENGTH && GET_HISTORY(ch, type); i--) {
|
||||
tmp = GET_HISTORY(ch, type);
|
||||
GET_HISTORY(ch, type) = tmp->next;
|
||||
if (tmp->text)
|
||||
free(tmp->text);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
/* add this history message to ALL */
|
||||
if (type != HIST_ALL)
|
||||
add_history(ch, str, HIST_ALL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2152,7 +2152,7 @@ ACMD(do_force)
|
|||
ACMD(do_wiznet)
|
||||
{
|
||||
char buf1[MAX_INPUT_LENGTH + MAX_NAME_LENGTH + 32],
|
||||
buf2[MAX_INPUT_LENGTH + MAX_NAME_LENGTH + 32];
|
||||
buf2[MAX_INPUT_LENGTH + MAX_NAME_LENGTH + 32], *msg;
|
||||
struct descriptor_data *d;
|
||||
char emote = FALSE;
|
||||
char any = FALSE;
|
||||
|
|
@ -2213,21 +2213,25 @@ ACMD(do_wiznet)
|
|||
return;
|
||||
}
|
||||
if (level > LVL_IMMORT) {
|
||||
snprintf(buf1, sizeof(buf1), "%s: <%d> %s%s\r\n", GET_NAME(ch), level, emote ? "<--- " : "", argument);
|
||||
snprintf(buf2, sizeof(buf1), "Someone: <%d> %s%s\r\n", level, emote ? "<--- " : "", argument);
|
||||
snprintf(buf1, sizeof(buf1), "@c%s: <%d> %s%s@n\r\n", GET_NAME(ch), level, emote ? "<--- " : "", argument);
|
||||
snprintf(buf2, sizeof(buf1), "@cSomeone: <%d> %s%s@n\r\n", level, emote ? "<--- " : "", argument);
|
||||
} else {
|
||||
snprintf(buf1, sizeof(buf1), "%s: %s%s\r\n", GET_NAME(ch), emote ? "<--- " : "", argument);
|
||||
snprintf(buf2, sizeof(buf1), "Someone: %s%s\r\n", emote ? "<--- " : "", argument);
|
||||
snprintf(buf1, sizeof(buf1), "@c%s: %s%s@n\r\n", GET_NAME(ch), emote ? "<--- " : "", argument);
|
||||
snprintf(buf2, sizeof(buf1), "@cSomeone: %s%s@n\r\n", emote ? "<--- " : "", argument);
|
||||
}
|
||||
|
||||
for (d = descriptor_list; d; d = d->next) {
|
||||
if (IS_PLAYING(d) && (GET_LEVEL(d->character) >= level) &&
|
||||
(!PRF_FLAGGED(d->character, PRF_NOWIZ))
|
||||
&& (d != ch->desc || !(PRF_FLAGGED(d->character, PRF_NOREPEAT)))) {
|
||||
send_to_char(d->character, "%s", CCCYN(d->character, C_NRM));
|
||||
if (CAN_SEE(d->character, ch)) {
|
||||
msg = strdup(buf1);
|
||||
send_to_char(d->character, "%s", buf1);
|
||||
new_hist_messg(d, buf1);
|
||||
send_to_char(d->character, "%s", CCNRM(d->character, C_NRM));
|
||||
} else {
|
||||
msg = strdup(buf2);
|
||||
send_to_char(d->character, "%s", buf2);
|
||||
}
|
||||
add_history(d->character, msg, HIST_WIZNET);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ void aedit_parse(struct descriptor_data * d, char *arg) {
|
|||
break;
|
||||
default:
|
||||
write_to_output(d, "Invalid choice!\r\n"
|
||||
"Do you wish to save your changes? ");
|
||||
"Do you wish to save your changes? : ");
|
||||
break;
|
||||
}
|
||||
return; /* end of AEDIT_CONFIRM_SAVESTRING */
|
||||
|
|
@ -418,7 +418,7 @@ void aedit_parse(struct descriptor_data * d, char *arg) {
|
|||
switch (*arg) {
|
||||
case 'q': case 'Q':
|
||||
if (OLC_VAL(d)) { /* Something was modified */
|
||||
write_to_output(d, "Do you wish to save your changes? ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
OLC_MODE(d) = AEDIT_CONFIRM_SAVESTRING;
|
||||
}
|
||||
else cleanup_olc(d, CLEANUP_ALL);
|
||||
|
|
|
|||
|
|
@ -810,7 +810,7 @@ void cedit_parse(struct descriptor_data *d, char *arg)
|
|||
return;
|
||||
default :
|
||||
write_to_output(d, "\r\nThat is an invalid choice!\r\n");
|
||||
write_to_output(d, "Do you wish to save your changes? (y/n) : ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -850,7 +850,7 @@ void cedit_parse(struct descriptor_data *d, char *arg)
|
|||
|
||||
case 'q':
|
||||
case 'Q':
|
||||
write_to_output(d, "Do you wish to save your changes? (y/n) : ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
OLC_MODE(d) = CEDIT_CONFIRM_SAVESTRING;
|
||||
break;
|
||||
|
||||
|
|
|
|||
453
src/comm.c
453
src/comm.c
|
|
@ -47,10 +47,8 @@
|
|||
# include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Note, most includes for all platforms are in sysdep.h. The list of
|
||||
* files that is included is controlled by conf.h for that platform.
|
||||
*/
|
||||
/* Note, most includes for all platforms are in sysdep.h. The list of
|
||||
* files that is included is controlled by conf.h for that platform. */
|
||||
|
||||
#include "structs.h"
|
||||
#include "utils.h"
|
||||
|
|
@ -112,7 +110,7 @@ ush_int port;
|
|||
socket_t mother_desc;
|
||||
int log_this_messg;
|
||||
|
||||
/* functions in this file */
|
||||
/* local functions */
|
||||
RETSIGTYPE reread_wizlists(int sig);
|
||||
RETSIGTYPE unrestrict_game(int sig);
|
||||
RETSIGTYPE reap(int sig);
|
||||
|
|
@ -156,11 +154,10 @@ sigfunc *my_signal(int signo, sigfunc *func);
|
|||
byte webster_file_ready = FALSE;/* signal: SIGUSR2 */
|
||||
RETSIGTYPE websterlink(int sig);
|
||||
extern void handle_webster_file();
|
||||
void copyover_recover( void );
|
||||
void copyover_recover(void);
|
||||
size_t proc_colors(char *txt, size_t maxlen, int parse);
|
||||
void free_hist_messg(struct descriptor_data *d);
|
||||
|
||||
/* extern fcnts */
|
||||
/* extern functions */
|
||||
void reboot_wizlists(void);
|
||||
void boot_world(void);
|
||||
void affect_update(void); /* In magic.c */
|
||||
|
|
@ -188,18 +185,12 @@ void new_hist_messg(struct descriptor_data *d, const char *msg);
|
|||
#define FD_CLR(x, y)
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* main game loop and related stuff *
|
||||
***********************************************************************/
|
||||
/* main game loop and related stuff */
|
||||
|
||||
#if defined(CIRCLE_WINDOWS) || defined(CIRCLE_MACINTOSH)
|
||||
|
||||
/*
|
||||
* Windows doesn't have gettimeofday, so we'll simulate it.
|
||||
* The Mac doesn't have gettimeofday either.
|
||||
* Borland C++ warns: "Undefined structure 'timezone'"
|
||||
*/
|
||||
/* Windows doesn't have gettimeofday, so we'll simulate it. The Mac doesn't
|
||||
* have gettimeofday either. Borland C++ warns: "Undefined structure
|
||||
* 'timezone'" */
|
||||
void gettimeofday(struct timeval *t, struct timezone *dummy)
|
||||
{
|
||||
#if defined(CIRCLE_WINDOWS)
|
||||
|
|
@ -215,7 +206,6 @@ void gettimeofday(struct timeval *t, struct timezone *dummy)
|
|||
|
||||
#endif /* CIRCLE_WINDOWS || CIRCLE_MACINTOSH */
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int pos = 1;
|
||||
|
|
@ -226,21 +216,16 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
|
||||
#ifdef CIRCLE_MACINTOSH
|
||||
/*
|
||||
* ccommand() calls the command line/io redirection dialog box from
|
||||
* Codewarriors's SIOUX library
|
||||
*/
|
||||
/* ccommand() calls the command line/io redirection dialog box from
|
||||
* Codewarriors's SIOUX library. */
|
||||
argc = ccommand(&argv);
|
||||
/* Initialize the GUSI library calls. */
|
||||
GUSIDefaultSetup();
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/** Load the game configuration. **/
|
||||
/** We must load BEFORE we use any of the constants stored in constants.c. **/
|
||||
/** Otherwise, there will be no variables set to set the rest of the vars **/
|
||||
/** to, which will mean trouble --> Mythran **/
|
||||
/****************************************************************************/
|
||||
/* Load the game configuration. We must load BEFORE we use any of the
|
||||
* constants stored in constants.c. Otherwise, there will be no variables
|
||||
* set to set the rest of the vars to, which will mean trouble --> Mythran */
|
||||
CONFIG_CONFFILE = NULL;
|
||||
while ((pos < argc) && (*(argv[pos]) == '-')) {
|
||||
if (*(argv[pos] + 1) == 'f') {
|
||||
|
|
@ -355,10 +340,8 @@ int main(int argc, char **argv)
|
|||
/* All arguments have been parsed, try to open log file. */
|
||||
setup_log(CONFIG_LOGNAME, STDERR_FILENO);
|
||||
|
||||
/*
|
||||
* Moved here to distinguish command line options and to show up
|
||||
* in the log if stderr is redirected to a file.
|
||||
*/
|
||||
/* Moved here to distinguish command line options and to show up
|
||||
* in the log if stderr is redirected to a file. */
|
||||
log("Using %s for configuration.", CONFIG_CONFFILE);
|
||||
log("%s", circlemud_version);
|
||||
log("%s", oasisolc_version);
|
||||
|
|
@ -551,12 +534,8 @@ void init_game(ush_int port)
|
|||
log("Normal termination of game.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* init_socket sets up the mother descriptor - creates the socket, sets
|
||||
* its options up, binds it, and listens.
|
||||
*/
|
||||
/* init_socket sets up the mother descriptor - creates the socket, sets
|
||||
* its options up, binds it, and listens. */
|
||||
socket_t init_socket(ush_int port)
|
||||
{
|
||||
socket_t s;
|
||||
|
|
@ -575,11 +554,9 @@ socket_t init_socket(ush_int port)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 4 = stdin, stdout, stderr, mother_desc. Windows might
|
||||
* keep sockets and files separate, in which case this isn't
|
||||
* necessary, but we will err on the side of caution.
|
||||
*/
|
||||
/* 4 = stdin, stdout, stderr, mother_desc. Windows might keep sockets and
|
||||
* files separate, in which case this isn't necessary, but we will err on
|
||||
* the side of caution. */
|
||||
if ((wsaData.iMaxSockets - 4) < max_players) {
|
||||
max_players = wsaData.iMaxSockets - 4;
|
||||
}
|
||||
|
|
@ -592,16 +569,14 @@ socket_t init_socket(ush_int port)
|
|||
}
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* Should the first argument to socket() be AF_INET or PF_INET? I don't
|
||||
/* Should the first argument to socket() be AF_INET or PF_INET? I don't
|
||||
* know, take your pick. PF_INET seems to be more widely adopted, and
|
||||
* Comer (_Internetworking with TCP/IP_) even makes a point to say that
|
||||
* people erroneously use AF_INET with socket() when they should be using
|
||||
* PF_INET. However, the man pages of some systems indicate that AF_INET
|
||||
* is correct; some such as ConvexOS even say that you can use either one.
|
||||
* All implementations I've seen define AF_INET and PF_INET to be the same
|
||||
* number anyway, so the point is (hopefully) moot.
|
||||
*/
|
||||
* number anyway, so the point is (hopefully) moot. */
|
||||
|
||||
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
perror("SYSERR: Error creating socket");
|
||||
|
|
@ -619,11 +594,9 @@ socket_t init_socket(ush_int port)
|
|||
|
||||
set_sendbuf(s);
|
||||
|
||||
/*
|
||||
* The GUSI sockets library is derived from BSD, so it defines
|
||||
* SO_LINGER, even though setsockopt() is unimplimented.
|
||||
* (from Dean Takemori <dean@UHHEPH.PHYS.HAWAII.EDU>)
|
||||
*/
|
||||
/* The GUSI sockets library is derived from BSD, so it defines SO_LINGER, even
|
||||
* though setsockopt() is unimplimented. (from Dean Takemori
|
||||
* <dean@UHHEPH.PHYS.HAWAII.EDU>) */
|
||||
#if defined(SO_LINGER) && !defined(CIRCLE_MACINTOSH)
|
||||
{
|
||||
struct linger ld;
|
||||
|
|
@ -652,7 +625,6 @@ socket_t init_socket(ush_int port)
|
|||
return (s);
|
||||
}
|
||||
|
||||
|
||||
int get_max_players(void)
|
||||
{
|
||||
#ifndef CIRCLE_UNIX
|
||||
|
|
@ -662,10 +634,8 @@ int get_max_players(void)
|
|||
int max_descs = 0;
|
||||
const char *method;
|
||||
|
||||
/*
|
||||
* First, we'll try using getrlimit/setrlimit. This will probably work
|
||||
* on most systems. HAS_RLIMIT is defined in sysdep.h.
|
||||
*/
|
||||
/* First, we'll try using getrlimit/setrlimit. This will probably work
|
||||
* on most systems. HAS_RLIMIT is defined in sysdep.h. */
|
||||
#ifdef HAS_RLIMIT
|
||||
{
|
||||
struct rlimit limit;
|
||||
|
|
@ -701,11 +671,9 @@ int get_max_players(void)
|
|||
max_descs = OPEN_MAX; /* Uh oh.. rlimit didn't work, but we have
|
||||
* OPEN_MAX */
|
||||
#elif defined (_SC_OPEN_MAX)
|
||||
/*
|
||||
* Okay, you don't have getrlimit() and you don't have OPEN_MAX. Time to
|
||||
/* Okay, you don't have getrlimit() and you don't have OPEN_MAX. Time to
|
||||
* try the POSIX sysconf() function. (See Stevens' _Advanced Programming
|
||||
* in the UNIX Environment_).
|
||||
*/
|
||||
* in the UNIX Environment_). */
|
||||
method = "POSIX sysconf";
|
||||
errno = 0;
|
||||
if ((max_descs = sysconf(_SC_OPEN_MAX)) < 0) {
|
||||
|
|
@ -735,15 +703,11 @@ int get_max_players(void)
|
|||
#endif /* CIRCLE_UNIX */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* game_loop contains the main loop which drives the entire MUD. It
|
||||
/* game_loop contains the main loop which drives the entire MUD. It
|
||||
* cycles once every 0.10 seconds and is responsible for accepting new
|
||||
* new connections, polling existing connections for input, dequeueing
|
||||
* output and sending it out to players, and calling "heartbeat" functions
|
||||
* such as mobile_activity().
|
||||
*/
|
||||
* such as mobile_activity(). */
|
||||
void game_loop(socket_t mother_desc)
|
||||
{
|
||||
fd_set input_set, output_set, exc_set, null_set;
|
||||
|
|
@ -796,20 +760,16 @@ void game_loop(socket_t mother_desc)
|
|||
FD_SET(d->descriptor, &exc_set);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we have completed all input, output and heartbeat
|
||||
/* At this point, we have completed all input, output and heartbeat
|
||||
* activity from the previous iteration, so we have to put ourselves
|
||||
* to sleep until the next 0.1 second tick. The first step is to
|
||||
* calculate how long we took processing the previous iteration.
|
||||
*/
|
||||
* calculate how long we took processing the previous iteration. */
|
||||
|
||||
gettimeofday(&before_sleep, (struct timezone *) 0); /* current time */
|
||||
timediff(&process_time, &before_sleep, &last_time);
|
||||
|
||||
/*
|
||||
* If we were asleep for more than one pass, count missed pulses and sleep
|
||||
* until we're resynchronized with the next upcoming pulse.
|
||||
*/
|
||||
/* If we were asleep for more than one pass, count missed pulses and sleep
|
||||
* until we're resynchronized with the next upcoming pulse. */
|
||||
if (process_time.tv_sec == 0 && process_time.tv_usec < OPT_USEC) {
|
||||
missed_pulses = 0;
|
||||
} else {
|
||||
|
|
@ -865,12 +825,10 @@ void game_loop(socket_t mother_desc)
|
|||
for (d = descriptor_list; d; d = next_d) {
|
||||
next_d = d->next;
|
||||
|
||||
/*
|
||||
* Not combined to retain --(d->wait) behavior. -gg 2/20/98
|
||||
* If no wait state, no subtraction. If there is a wait
|
||||
* state then 1 is subtracted. Therefore we don't go less
|
||||
* than 0 ever and don't require an 'if' bracket. -gg 2/27/99
|
||||
*/
|
||||
/* Not combined to retain --(d->wait) behavior. -gg 2/20/98 If no wait
|
||||
* state, no subtraction. If there is a wait state then 1 is subtracted.
|
||||
* Therefore we don't go less than 0 ever and don't require an 'if'
|
||||
* bracket. -gg 2/27/99 */
|
||||
if (d->character) {
|
||||
GET_WAIT_STATE(d->character) -= (GET_WAIT_STATE(d->character) > 0);
|
||||
|
||||
|
|
@ -937,11 +895,9 @@ void game_loop(socket_t mother_desc)
|
|||
close_socket(d);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, we execute as many pulses as necessary--just one if we haven't
|
||||
/* Now, we execute as many pulses as necessary--just one if we haven't
|
||||
* missed any pulses, or make up for lost time if we missed a few
|
||||
* pulses by sleeping for too long.
|
||||
*/
|
||||
* pulses by sleeping for too long. */
|
||||
missed_pulses++;
|
||||
|
||||
if (missed_pulses <= 0) {
|
||||
|
|
@ -984,7 +940,6 @@ void game_loop(socket_t mother_desc)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void heartbeat(int heart_pulse)
|
||||
{
|
||||
static int mins_since_crashsave = 0;
|
||||
|
|
@ -1031,21 +986,11 @@ void heartbeat(int heart_pulse)
|
|||
extract_pending_chars();
|
||||
}
|
||||
|
||||
|
||||
/* ******************************************************************
|
||||
* general utility stuff (for local use) *
|
||||
****************************************************************** */
|
||||
|
||||
/*
|
||||
* new code to calculate time differences, which works on systems
|
||||
* for which tv_usec is unsigned (and thus comparisons for something
|
||||
* being < 0 fail). Based on code submitted by ss@sirocco.cup.hp.com.
|
||||
*/
|
||||
|
||||
/*
|
||||
* code to return the time difference between a and b (a-b).
|
||||
* always returns a nonnegative value (floors at 0).
|
||||
*/
|
||||
/* new code to calculate time differences, which works on systems for which
|
||||
* tv_usec is unsigned (and thus comparisons for something being < 0 fail).
|
||||
* Based on code submitted by ss@sirocco.cup.hp.com. Code to return the time
|
||||
* difference between a and b (a-b). Always returns a nonnegative value
|
||||
* (floors at 0). */
|
||||
void timediff(struct timeval *rslt, struct timeval *a, struct timeval *b)
|
||||
{
|
||||
if (a->tv_sec < b->tv_sec)
|
||||
|
|
@ -1067,11 +1012,8 @@ void timediff(struct timeval *rslt, struct timeval *a, struct timeval *b)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add 2 time values.
|
||||
*
|
||||
* Patch sent by "d. hall" <dhall@OOI.NET> to fix 'static' usage.
|
||||
*/
|
||||
/* Add 2 time values. Patch sent by "d. hall" <dhall@OOI.NET> to fix 'static'
|
||||
* usage. */
|
||||
void timeadd(struct timeval *rslt, struct timeval *a, struct timeval *b)
|
||||
{
|
||||
rslt->tv_sec = a->tv_sec + b->tv_sec;
|
||||
|
|
@ -1083,7 +1025,6 @@ void timeadd(struct timeval *rslt, struct timeval *a, struct timeval *b)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void record_usage(void)
|
||||
{
|
||||
int sockets_connected = 0, sockets_playing = 0;
|
||||
|
|
@ -1107,14 +1048,9 @@ void record_usage(void)
|
|||
ru.ru_utime.tv_sec, ru.ru_stime.tv_sec, ru.ru_maxrss);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Turn off echoing (specific to telnet client)
|
||||
*/
|
||||
/* Turn off echoing (specific to telnet client) */
|
||||
void echo_off(struct descriptor_data *d)
|
||||
{
|
||||
char off_string[] =
|
||||
|
|
@ -1128,10 +1064,7 @@ void echo_off(struct descriptor_data *d)
|
|||
write_to_output(d, "%s", off_string);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Turn on echoing (specific to telnet client)
|
||||
*/
|
||||
/* Turn on echoing (specific to telnet client) */
|
||||
void echo_on(struct descriptor_data *d)
|
||||
{
|
||||
char on_string[] =
|
||||
|
|
@ -1205,15 +1138,11 @@ size_t proc_colors(char *txt, size_t maxlen, int parse)
|
|||
break;
|
||||
}
|
||||
}
|
||||
/* If we couldn't find any correct color code
|
||||
* let's just skip it
|
||||
* - Welcor
|
||||
*/
|
||||
/* If we couldn't find any correct color code let's just skip it - Welcor */
|
||||
s++;
|
||||
|
||||
} /* for loop */
|
||||
|
||||
|
||||
/* make sure txt is NULL - terminated */
|
||||
d = '\0';
|
||||
strncpy(txt, p, maxlen-1);
|
||||
|
|
@ -1300,10 +1229,7 @@ char *make_prompt(struct descriptor_data *d)
|
|||
return (prompt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: 'txt' must be at most MAX_INPUT_LENGTH big.
|
||||
*/
|
||||
/* NOTE: 'txt' must be at most MAX_INPUT_LENGTH big. */
|
||||
void write_to_q(const char *txt, struct txt_q *queue, int aliased)
|
||||
{
|
||||
struct txt_block *newt;
|
||||
|
|
@ -1323,10 +1249,7 @@ void write_to_q(const char *txt, struct txt_q *queue, int aliased)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: 'dest' must be at least MAX_INPUT_LENGTH big.
|
||||
*/
|
||||
/* NOTE: 'dest' must be at least MAX_INPUT_LENGTH big. */
|
||||
int get_from_q(struct txt_q *queue, char *dest, int *aliased)
|
||||
{
|
||||
struct txt_block *tmp;
|
||||
|
|
@ -1346,7 +1269,6 @@ int get_from_q(struct txt_q *queue, char *dest, int *aliased)
|
|||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/* Empty the queues before closing connection */
|
||||
void flush_queues(struct descriptor_data *d)
|
||||
{
|
||||
|
|
@ -1362,7 +1284,6 @@ void flush_queues(struct descriptor_data *d)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add a new string to a player's output queue. For outside use. */
|
||||
size_t write_to_output(struct descriptor_data *t, const char *txt, ...)
|
||||
{
|
||||
|
|
@ -1376,7 +1297,6 @@ size_t write_to_output(struct descriptor_data *t, const char *txt, ...)
|
|||
return left;
|
||||
}
|
||||
|
||||
|
||||
/* Add a new string to a player's output queue. */
|
||||
size_t vwrite_to_output(struct descriptor_data *t, const char *format, va_list args)
|
||||
{
|
||||
|
|
@ -1398,21 +1318,17 @@ size_t vwrite_to_output(struct descriptor_data *t, const char *format, va_list a
|
|||
strcpy(txt + size - strlen(text_overflow), text_overflow); /* strcpy: OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* If the text is too big to fit into even a large buffer, truncate
|
||||
/* If the text is too big to fit into even a large buffer, truncate
|
||||
* the new text to make it fit. (This will switch to the overflow
|
||||
* state automatically because t->bufspace will end up 0.)
|
||||
*/
|
||||
* state automatically because t->bufspace will end up 0.) */
|
||||
if (size + t->bufptr + 1 > LARGE_BUFSIZE) {
|
||||
size = LARGE_BUFSIZE - t->bufptr - 1;
|
||||
txt[size] = '\0';
|
||||
buf_overflows++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have enough space, just write to buffer and that's it! If the
|
||||
* text just barely fits, then it's switched to a large buffer instead.
|
||||
*/
|
||||
/* If we have enough space, just write to buffer and that's it! If the
|
||||
* text just barely fits, then it's switched to a large buffer instead. */
|
||||
if (t->bufspace > size) {
|
||||
strcpy(t->output + t->bufptr, txt); /* strcpy: OK (size checked above) */
|
||||
t->bufspace -= size;
|
||||
|
|
@ -1458,20 +1374,12 @@ void free_bufpool(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* ******************************************************************
|
||||
* socket handling *
|
||||
****************************************************************** */
|
||||
|
||||
|
||||
/*
|
||||
* get_bind_addr: Return a struct in_addr that should be used in our
|
||||
/* socket handling */
|
||||
/* get_bind_addr: Return a struct in_addr that should be used in our
|
||||
* call to bind(). If the user has specified a desired binding
|
||||
* address, we try to bind to it; otherwise, we bind to INADDR_ANY.
|
||||
* Note that inet_aton() is preferred over inet_addr() so we use it if
|
||||
* we can. If neither is available, we always bind to INADDR_ANY.
|
||||
*/
|
||||
|
||||
* we can. If neither is available, we always bind to INADDR_ANY. */
|
||||
struct in_addr *get_bind_addr()
|
||||
{
|
||||
static struct in_addr bind_addr;
|
||||
|
|
@ -1501,11 +1409,8 @@ struct in_addr *get_bind_addr()
|
|||
}
|
||||
|
||||
#ifdef HAVE_INET_ATON
|
||||
|
||||
/*
|
||||
* inet_aton's interface is the same as parse_ip's: 0 on failure, non-0 if
|
||||
* successful
|
||||
*/
|
||||
/* inet_aton's interface is the same as parse_ip's: 0 on failure, non-0 if
|
||||
* successful. */
|
||||
int parse_ip(const char *addr, struct in_addr *inaddr)
|
||||
{
|
||||
return (inet_aton(addr, inaddr));
|
||||
|
|
@ -1527,7 +1432,6 @@ int parse_ip(const char *addr, struct in_addr *inaddr)
|
|||
}
|
||||
|
||||
#else
|
||||
|
||||
/* If you have neither function - sorry, you can't do specific binding. */
|
||||
int parse_ip(const char *addr, struct in_addr *inaddr)
|
||||
{
|
||||
|
|
@ -1535,11 +1439,8 @@ int parse_ip(const char *addr, struct in_addr *inaddr)
|
|||
"functions to parse IP addresses (how bizarre!)");
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* INET_ATON and INET_ADDR */
|
||||
|
||||
|
||||
|
||||
/* Sets the kernel's send buffer size for the descriptor */
|
||||
int set_sendbuf(socket_t s)
|
||||
{
|
||||
|
|
@ -1649,16 +1550,12 @@ int new_descriptor(socket_t s)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send all of the output that we've accumulated for a player out to
|
||||
* the player's descriptor.
|
||||
*
|
||||
* 32 byte GARBAGE_SPACE in MAX_SOCK_BUF used for:
|
||||
/* Send all of the output that we've accumulated for a player out to the
|
||||
* player's descriptor. 32 byte GARBAGE_SPACE in MAX_SOCK_BUF used for:
|
||||
* 2 bytes: prepended \r\n
|
||||
* 14 bytes: overflow message
|
||||
* 2 bytes: extra \r\n for non-comapct
|
||||
* 14 bytes: unused
|
||||
*/
|
||||
* 14 bytes: unused */
|
||||
int process_output(struct descriptor_data *t)
|
||||
{
|
||||
char i[MAX_SOCK_BUF], *osb = i + 2;
|
||||
|
|
@ -1681,10 +1578,8 @@ int process_output(struct descriptor_data *t)
|
|||
/* add a prompt */
|
||||
strcat(i, make_prompt(t)); /* strcpy: OK (i:MAX_SOCK_BUF reserves space) */
|
||||
|
||||
/*
|
||||
* now, send the output. If this is an 'interruption', use the prepended
|
||||
* CRLF, otherwise send the straight output sans CRLF.
|
||||
*/
|
||||
/* now, send the output. If this is an 'interruption', use the prepended
|
||||
* CRLF, otherwise send the straight output sans CRLF. */
|
||||
if (t->has_prompt) {
|
||||
t->has_prompt = FALSE;
|
||||
result = write_to_descriptor(t->descriptor, i);
|
||||
|
|
@ -1705,10 +1600,8 @@ int process_output(struct descriptor_data *t)
|
|||
|
||||
/* The common case: all saved output was handed off to the kernel buffer. */
|
||||
if (result >= t->bufptr) {
|
||||
/*
|
||||
* if we were using a large buffer, put the large buffer on the buffer pool
|
||||
* and switch back to the small one
|
||||
*/
|
||||
/* If we were using a large buffer, put the large buffer on the buffer pool
|
||||
* and switch back to the small one. */
|
||||
if (t->large_outbuf) {
|
||||
t->large_outbuf->next = bufpool;
|
||||
bufpool = t->large_outbuf;
|
||||
|
|
@ -1720,11 +1613,9 @@ int process_output(struct descriptor_data *t)
|
|||
t->bufptr = 0;
|
||||
*(t->output) = '\0';
|
||||
|
||||
/*
|
||||
* If the overflow message or prompt were partially written, try to save
|
||||
/* If the overflow message or prompt were partially written, try to save
|
||||
* them. There will be enough space for them if this is true. 'result'
|
||||
* is effectively unsigned here anyway.
|
||||
*/
|
||||
* is effectively unsigned here anyway. */
|
||||
if ((unsigned int)result < strlen(osb)) {
|
||||
size_t savetextlen = strlen(osb + result);
|
||||
|
||||
|
|
@ -1744,26 +1635,18 @@ int process_output(struct descriptor_data *t)
|
|||
return (result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* perform_socket_write: takes a descriptor, a pointer to text, and a
|
||||
/* perform_socket_write: takes a descriptor, a pointer to text, and a
|
||||
* text length, and tries once to send that text to the OS. This is
|
||||
* where we stuff all the platform-dependent stuff that used to be
|
||||
* ugly #ifdef's in write_to_descriptor().
|
||||
*
|
||||
* This function must return:
|
||||
*
|
||||
* ugly #ifdef's in write_to_descriptor(). This function must return:
|
||||
* -1 If a fatal error was encountered in writing to the descriptor.
|
||||
* 0 If a transient failure was encountered (e.g. socket buffer full).
|
||||
* >0 To indicate the number of bytes successfully written, possibly
|
||||
* fewer than the number the caller requested be written.
|
||||
*
|
||||
* Right now there are two versions of this function: one for Windows,
|
||||
* and one for all other platforms.
|
||||
*/
|
||||
* and one for all other platforms. */
|
||||
|
||||
#if defined(CIRCLE_WINDOWS)
|
||||
|
||||
ssize_t perform_socket_write(socket_t desc, const char *txt, size_t length)
|
||||
{
|
||||
ssize_t result;
|
||||
|
|
@ -1815,11 +1698,8 @@ ssize_t perform_socket_write(socket_t desc, const char *txt, size_t length)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* result < 0, so an error was encountered - is it transient?
|
||||
* Unfortunately, different systems use different constants to
|
||||
* indicate this.
|
||||
*/
|
||||
/* result < 0, so an error was encountered - is it transient? Unfortunately,
|
||||
* different systems use different constants to indicate this. */
|
||||
|
||||
#ifdef EAGAIN /* POSIX */
|
||||
if (errno == EAGAIN)
|
||||
|
|
@ -1839,20 +1719,13 @@ ssize_t perform_socket_write(socket_t desc, const char *txt, size_t length)
|
|||
/* Looks like the error was fatal. Too bad. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#endif /* CIRCLE_WINDOWS */
|
||||
|
||||
|
||||
/*
|
||||
* write_to_descriptor takes a descriptor, and text to write to the
|
||||
* descriptor. It keeps calling the system-level write() until all
|
||||
* the text has been delivered to the OS, or until an error is
|
||||
* encountered.
|
||||
*
|
||||
* Returns:
|
||||
/* write_to_descriptor takes a descriptor, and text to write to the descriptor.
|
||||
* It keeps calling the system-level write() until all the text has been
|
||||
* delivered to the OS, or until an error is encountered. Returns:
|
||||
* >=0 If all is well and good.
|
||||
* -1 If an error was encountered, so that the player should be cut off.
|
||||
*/
|
||||
* -1 If an error was encountered, so that the player should be cut off. */
|
||||
int write_to_descriptor(socket_t desc, const char *txt)
|
||||
{
|
||||
ssize_t bytes_written;
|
||||
|
|
@ -1878,11 +1751,8 @@ int write_to_descriptor(socket_t desc, const char *txt)
|
|||
return (write_total);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Same information about perform_socket_write applies here. I like
|
||||
* standards, there are so many of them. -gg 6/30/98
|
||||
*/
|
||||
/* Same information about perform_socket_write applies here. I like
|
||||
* standards, there are so many of them. -gg 6/30/98 */
|
||||
ssize_t perform_socket_read(socket_t desc, char *read_point, size_t space_left)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
|
@ -1905,9 +1775,7 @@ ssize_t perform_socket_read(socket_t desc, char *read_point, size_t space_left)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* read returned a value < 0: there was an error
|
||||
*/
|
||||
/* Read returned a value < 0: there was an error. */
|
||||
|
||||
#if defined(CIRCLE_WINDOWS) /* Windows */
|
||||
if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINTR)
|
||||
|
|
@ -1941,27 +1809,22 @@ ssize_t perform_socket_read(socket_t desc, char *read_point, size_t space_left)
|
|||
|
||||
#endif /* CIRCLE_WINDOWS */
|
||||
|
||||
/*
|
||||
* We don't know what happened, cut them off. This qualifies for
|
||||
* a SYSERR because we have no idea what happened at this point.
|
||||
*/
|
||||
/* We don't know what happened, cut them off. This qualifies for
|
||||
* a SYSERR because we have no idea what happened at this point.*/
|
||||
perror("SYSERR: perform_socket_read: about to lose connection");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ASSUMPTION: There will be no newlines in the raw input buffer when this
|
||||
/* ASSUMPTION: There will be no newlines in the raw input buffer when this
|
||||
* function is called. We must maintain that before returning.
|
||||
*
|
||||
* Ever wonder why 'tmp' had '+8' on it? The crusty old code could write
|
||||
* MAX_INPUT_LENGTH+1 bytes to 'tmp' if there was a '$' as the final
|
||||
* character in the input buffer. This would also cause 'space_left' to
|
||||
* drop to -1, which wasn't very happy in an unsigned variable. Argh.
|
||||
* So to fix the above, 'tmp' lost the '+8' since it doesn't need it
|
||||
* and the code has been changed to reserve space by accepting one less
|
||||
* character. (Do you really need 256 characters on a line?)
|
||||
* -gg 1/21/2000
|
||||
*/
|
||||
* MAX_INPUT_LENGTH+1 bytes to 'tmp' if there was a '$' as the final character
|
||||
* in the input buffer. This would also cause 'space_left' to drop to -1,
|
||||
* which wasn't very happy in an unsigned variable. Argh. So to fix the
|
||||
* above, 'tmp' lost the '+8' since it doesn't need it and the code has been
|
||||
* changed to reserve space by accepting one less character. (Do you really
|
||||
* need 256 characters on a line?) -gg 1/21/2000 */
|
||||
int process_input(struct descriptor_data *t)
|
||||
{
|
||||
int buf_length, failed_subst;
|
||||
|
|
@ -2000,16 +1863,14 @@ int process_input(struct descriptor_data *t)
|
|||
read_point += bytes_read;
|
||||
space_left -= bytes_read;
|
||||
|
||||
/*
|
||||
* on some systems such as AIX, POSIX-standard nonblocking I/O is broken,
|
||||
/* on some systems such as AIX, POSIX-standard nonblocking I/O is broken,
|
||||
* causing the MUD to hang when it encounters input not terminated by a
|
||||
* newline. This was causing hangs at the Password: prompt, for example.
|
||||
* I attempt to compensate by always returning after the _first_ read, instead
|
||||
* of looping forever until a read returns -1. This simulates non-blocking
|
||||
* I/O because the result is we never call read unless we know from select()
|
||||
* that data is ready (process_input is only called if select indicates that
|
||||
* this descriptor is in the read set). JE 2/23/95.
|
||||
*/
|
||||
* this descriptor is in the read set). JE 2/23/95. */
|
||||
#if !defined(POSIX_NONBLOCK_BROKEN)
|
||||
} while (nl_pos == NULL);
|
||||
#else
|
||||
|
|
@ -2019,10 +1880,8 @@ int process_input(struct descriptor_data *t)
|
|||
return (0);
|
||||
#endif /* POSIX_NONBLOCK_BROKEN */
|
||||
|
||||
/*
|
||||
* okay, at this point we have at least one newline in the string; now we
|
||||
* can copy the formatted data to a new array for further processing.
|
||||
*/
|
||||
/* okay, at this point we have at least one newline in the string; now we
|
||||
* can copy the formatted data to a new array for further processing. */
|
||||
|
||||
read_point = t->inbuf;
|
||||
|
||||
|
|
@ -2115,12 +1974,9 @@ int process_input(struct descriptor_data *t)
|
|||
return (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* perform substitution for the '^..^' csh-esque syntax orig is the
|
||||
* orig string, i.e. the one being modified. subst contains the
|
||||
* substition string, i.e. "^telm^tell"
|
||||
*/
|
||||
* substition string, i.e. "^telm^tell" */
|
||||
int perform_subst(struct descriptor_data *t, char *orig, char *subst)
|
||||
{
|
||||
char newsub[MAX_INPUT_LENGTH + 5];
|
||||
|
|
@ -2168,8 +2024,6 @@ int perform_subst(struct descriptor_data *t, char *orig, char *subst)
|
|||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void close_socket(struct descriptor_data *d)
|
||||
{
|
||||
struct descriptor_data *temp;
|
||||
|
|
@ -2231,8 +2085,6 @@ void close_socket(struct descriptor_data *d)
|
|||
free(d->history);
|
||||
}
|
||||
|
||||
free_hist_messg(d);
|
||||
|
||||
if (d->showstr_head)
|
||||
free(d->showstr_head);
|
||||
if (d->showstr_count)
|
||||
|
|
@ -2257,8 +2109,6 @@ void close_socket(struct descriptor_data *d)
|
|||
free(d);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void check_idle_passwords(void)
|
||||
{
|
||||
struct descriptor_data *d, *next_d;
|
||||
|
|
@ -2278,15 +2128,11 @@ void check_idle_passwords(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* I tried to universally convert Circle over to POSIX compliance, but
|
||||
/* I tried to universally convert Circle over to POSIX compliance, but
|
||||
* alas, some systems are still straggling behind and don't have all the
|
||||
* appropriate defines. In particular, NeXT 2.x defines O_NDELAY but not
|
||||
* O_NONBLOCK. Krusty old NeXT machines! (Thanks to Michael Jones for
|
||||
* this and various other NeXT fixes.)
|
||||
*/
|
||||
* this and various other NeXT fixes.) */
|
||||
|
||||
#if defined(CIRCLE_WINDOWS)
|
||||
|
||||
|
|
@ -2341,22 +2187,16 @@ void nonblock(socket_t s)
|
|||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CIRCLE_UNIX || CIRCLE_OS2 || CIRCLE_MACINTOSH */
|
||||
|
||||
|
||||
/* ******************************************************************
|
||||
* signal-handling functions (formerly signals.c). UNIX only. *
|
||||
****************************************************************** */
|
||||
|
||||
/* signal-handling functions (formerly signals.c). UNIX only. */
|
||||
#if defined(CIRCLE_UNIX) || defined(CIRCLE_MACINTOSH)
|
||||
|
||||
RETSIGTYPE reread_wizlists(int sig)
|
||||
{
|
||||
reread_wizlist = TRUE;
|
||||
}
|
||||
|
||||
|
||||
RETSIGTYPE unrestrict_game(int sig)
|
||||
{
|
||||
emergency_unban = TRUE;
|
||||
|
|
@ -2389,30 +2229,24 @@ RETSIGTYPE checkpointing(int sig)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Dying anyway... */
|
||||
RETSIGTYPE hupsig(int sig)
|
||||
{
|
||||
log("SYSERR: Received SIGHUP, SIGINT, or SIGTERM. Shutting down...");
|
||||
exit(1); /* perhaps something more elegant should
|
||||
* substituted */
|
||||
exit(1); /* perhaps something more elegant should substituted */
|
||||
}
|
||||
|
||||
#endif /* CIRCLE_UNIX */
|
||||
|
||||
/*
|
||||
* This is an implementation of signal() using sigaction() for portability.
|
||||
/* This is an implementation of signal() using sigaction() for portability.
|
||||
* (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced
|
||||
* Programming in the UNIX Environment_. We are specifying that all system
|
||||
* calls _not_ be automatically restarted for uniformity, because BSD systems
|
||||
* do not restart select(), even if SA_RESTART is used.
|
||||
*
|
||||
* Note that NeXT 2.x is not POSIX and does not have sigaction; therefore,
|
||||
* I just define it to be the old signal. If your system doesn't have
|
||||
* sigaction either, you can use the same fix.
|
||||
*
|
||||
* SunOS Release 4.0.2 (sun386) needs this too, according to Tim Aldric.
|
||||
*/
|
||||
* SunOS Release 4.0.2 (sun386) needs this too, according to Tim Aldric. */
|
||||
|
||||
#ifndef POSIX
|
||||
#define my_signal(signo, func) signal(signo, func)
|
||||
|
|
@ -2435,7 +2269,6 @@ sigfunc *my_signal(int signo, sigfunc *func)
|
|||
}
|
||||
#endif /* POSIX */
|
||||
|
||||
|
||||
void signal_setup(void)
|
||||
{
|
||||
#ifndef CIRCLE_MACINTOSH
|
||||
|
|
@ -2445,16 +2278,12 @@ void signal_setup(void)
|
|||
/* user signal 1: reread wizlists. Used by autowiz system. */
|
||||
my_signal(SIGUSR1, reread_wizlists);
|
||||
|
||||
/*
|
||||
* user signal 2: unrestrict game. Used for emergencies if you lock
|
||||
* yourself out of the MUD somehow. (Duh...)
|
||||
*/
|
||||
/* user signal 2: unrestrict game. Used for emergencies if you lock
|
||||
* yourself out of the MUD somehow. */
|
||||
my_signal(SIGUSR2, websterlink);
|
||||
|
||||
/*
|
||||
* set up the deadlock-protection so that the MUD aborts itself if it gets
|
||||
* caught in an infinite loop for more than 3 minutes.
|
||||
*/
|
||||
/* set up the deadlock-protection so that the MUD aborts itself if it gets
|
||||
* caught in an infinite loop for more than 3 minutes. */
|
||||
interval.tv_sec = 180;
|
||||
interval.tv_usec = 0;
|
||||
itime.it_interval = interval;
|
||||
|
|
@ -2473,11 +2302,7 @@ void signal_setup(void)
|
|||
}
|
||||
|
||||
#endif /* CIRCLE_UNIX || CIRCLE_MACINTOSH */
|
||||
|
||||
/* ****************************************************************
|
||||
* Public routines for system-to-player-communication *
|
||||
**************************************************************** */
|
||||
|
||||
/* Public routines for system-to-player-communication. */
|
||||
size_t send_to_char(struct char_data *ch, const char *messg, ...)
|
||||
{
|
||||
if (ch->desc && messg && *messg) {
|
||||
|
|
@ -2492,7 +2317,6 @@ size_t send_to_char(struct char_data *ch, const char *messg, ...)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void send_to_all(const char *messg, ...)
|
||||
{
|
||||
struct descriptor_data *i;
|
||||
|
|
@ -2511,7 +2335,6 @@ void send_to_all(const char *messg, ...)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void send_to_outdoor(const char *messg, ...)
|
||||
{
|
||||
struct descriptor_data *i;
|
||||
|
|
@ -2533,8 +2356,6 @@ void send_to_outdoor(const char *messg, ...)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void send_to_room(room_rnum room, const char *messg, ...)
|
||||
{
|
||||
struct char_data *i;
|
||||
|
|
@ -2581,15 +2402,11 @@ void send_to_range(room_vnum start, room_vnum finish, const char *messg, ...)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
const char *ACTNULL = "<NULL>";
|
||||
|
||||
#define CHECK_NULL(pointer, expression) \
|
||||
if ((pointer) == NULL) i = ACTNULL; else i = (expression);
|
||||
|
||||
|
||||
/* higher-level communication: the act() function */
|
||||
void perform_act(const char *orig, struct char_data *ch, struct obj_data *obj,
|
||||
char *perform_act(const char *orig, struct char_data *ch, struct obj_data *obj,
|
||||
const void *vict_obj, const struct char_data *to)
|
||||
{
|
||||
const char *i = NULL;
|
||||
|
|
@ -2706,37 +2523,32 @@ void perform_act(const char *orig, struct char_data *ch, struct obj_data *obj,
|
|||
*(++buf) = '\n';
|
||||
*(++buf) = '\0';
|
||||
|
||||
if (to->desc) {
|
||||
if (to->desc)
|
||||
write_to_output(to->desc, "%s", CAP(lbuf));
|
||||
if (log_this_messg)
|
||||
new_hist_messg(to->desc, lbuf);
|
||||
}
|
||||
log_this_messg = 0;
|
||||
|
||||
if ((IS_NPC(to) && dg_act_check) && (to != ch))
|
||||
act_mtrigger(to, lbuf, ch, dg_victim, obj, dg_target, dg_arg);
|
||||
|
||||
return strdup(lbuf);
|
||||
}
|
||||
|
||||
|
||||
void act(const char *str, int hide_invisible, struct char_data *ch,
|
||||
char *act(const char *str, int hide_invisible, struct char_data *ch,
|
||||
struct obj_data *obj, const void *vict_obj, int type)
|
||||
{
|
||||
char *msg = NULL;
|
||||
const struct char_data *to;
|
||||
int to_sleeping;
|
||||
|
||||
if (!str || !*str)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Warning: the following TO_SLEEP code is a hack.
|
||||
*
|
||||
/* Warning: the following TO_SLEEP code is a hack.
|
||||
* I wanted to be able to tell act to deliver a message regardless of sleep
|
||||
* without adding an additional argument. TO_SLEEP is 128 (a single bit
|
||||
* high up). It's ONLY legal to combine TO_SLEEP with one other TO_x
|
||||
* command. It's not legal to combine TO_x's with each other otherwise.
|
||||
* TO_SLEEP only works because its value "happens to be" a single bit;
|
||||
* do not change it to something else. In short, it is a hack.
|
||||
*/
|
||||
* do not change it to something else. In short, it is a hack. */
|
||||
|
||||
/* check if TO_SLEEP is there, and remove it if it is. */
|
||||
if ((to_sleeping = (type & TO_SLEEP)))
|
||||
|
|
@ -2747,37 +2559,34 @@ void act(const char *str, int hide_invisible, struct char_data *ch,
|
|||
if (!(dg_act_check = !IS_SET(type, DG_NO_TRIG)))
|
||||
REMOVE_BIT(type, DG_NO_TRIG);
|
||||
|
||||
/* And this too.. */
|
||||
log_this_messg = IS_SET(type, LOG_MESSG);
|
||||
if (log_this_messg)
|
||||
REMOVE_BIT(type, LOG_MESSG);
|
||||
|
||||
if (type == TO_CHAR) {
|
||||
if (ch && SENDOK(ch))
|
||||
perform_act(str, ch, obj, vict_obj, ch);
|
||||
return;
|
||||
return perform_act(str, ch, obj, vict_obj, ch);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (type == TO_VICT) {
|
||||
if ((to = (const struct char_data *) vict_obj) != NULL && SENDOK(to))
|
||||
perform_act(str, ch, obj, vict_obj, to);
|
||||
return;
|
||||
return perform_act(str, ch, obj, vict_obj, to);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include "screen.h"
|
||||
if (type == TO_GMOTE) {
|
||||
struct descriptor_data *i;
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
|
||||
for (i = descriptor_list; i; i = i->next) {
|
||||
if (!i->connected && i->character &&
|
||||
!PRF_FLAGGED(i->character, PRF_NOGOSS) &&
|
||||
!PLR_FLAGGED(i->character, PLR_WRITING) &&
|
||||
!ROOM_FLAGGED(IN_ROOM(i->character), ROOM_SOUNDPROOF)) {
|
||||
|
||||
send_to_char(i->character, "%s", CCYEL(i->character, C_NRM));
|
||||
perform_act(str, ch, obj, vict_obj, i->character);
|
||||
send_to_char(i->character, "%s", CCNRM(i->character, C_NRM));
|
||||
sprintf(buf, "%s%s%s", CCYEL(i->character, C_NRM), str, CCNRM(i->character, C_NRM));
|
||||
msg = perform_act(buf, ch, obj, vict_obj, i->character);
|
||||
}
|
||||
}
|
||||
return;
|
||||
return msg;
|
||||
}
|
||||
/* ASSUMPTION: at this point we know type must be TO_NOTVICT or TO_ROOM */
|
||||
|
||||
|
|
@ -2787,7 +2596,7 @@ void act(const char *str, int hide_invisible, struct char_data *ch,
|
|||
to = world[IN_ROOM(obj)].people;
|
||||
else {
|
||||
log("SYSERR: no valid target to act()!");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (; to; to = to->next_in_room) {
|
||||
|
|
@ -2797,11 +2606,11 @@ void act(const char *str, int hide_invisible, struct char_data *ch,
|
|||
continue;
|
||||
if (type != TO_ROOM && to == vict_obj)
|
||||
continue;
|
||||
perform_act(str, ch, obj, vict_obj, to);
|
||||
msg = perform_act(str, ch, obj, vict_obj, to);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
/* Prefer the file over the descriptor. */
|
||||
void setup_log(const char *filename, int fd)
|
||||
{
|
||||
|
|
|
|||
28
src/comm.h
28
src/comm.h
|
|
@ -12,20 +12,20 @@
|
|||
#define COPYOVER_FILE "copyover.dat"
|
||||
|
||||
/* comm.c */
|
||||
size_t send_to_char(struct char_data *ch, const char *messg, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
void send_to_all(const char *messg, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
void send_to_room(room_rnum room, const char *messg, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
void send_to_outdoor(const char *messg, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
void send_to_range(room_vnum start, room_vnum finish, const char *messg, ...) __attribute__ ((format (printf, 3, 4)));
|
||||
size_t send_to_char(struct char_data *ch, const char *messg, ...) __attribute__
|
||||
((format (printf, 2, 3)));
|
||||
void send_to_all(const char *messg, ...) __attribute__ ((format (printf, 1,
|
||||
2)));
|
||||
void send_to_room(room_rnum room, const char *messg, ...) __attribute__ ((format
|
||||
(printf, 2, 3)));
|
||||
void send_to_outdoor(const char *messg, ...) __attribute__ ((format (printf, 1,
|
||||
2)));
|
||||
void send_to_range(room_vnum start, room_vnum finish, const char *messg, ...)
|
||||
__attribute__ ((format (printf, 3, 4)));
|
||||
|
||||
|
||||
void close_socket(struct descriptor_data *d);
|
||||
|
||||
void perform_act(const char *orig, struct char_data *ch,
|
||||
struct obj_data *obj, const void *vict_obj, const struct char_data *to);
|
||||
|
||||
void act(const char *str, int hide_invisible, struct char_data *ch,
|
||||
struct obj_data *obj, const void *vict_obj, int type);
|
||||
void close_socket(struct descriptor_data *d);
|
||||
char * perform_act(const char *orig, struct char_data *ch, struct obj_data *obj, const void *vict_obj, const struct char_data *to);
|
||||
char * act(const char *str, int hide_invisible, struct char_data *ch, struct obj_data *obj, const void *vict_obj, int type);
|
||||
|
||||
#define TO_ROOM 1
|
||||
#define TO_VICT 2
|
||||
|
|
@ -34,7 +34,7 @@ void act(const char *str, int hide_invisible, struct char_data *ch,
|
|||
#define TO_GMOTE 5
|
||||
#define TO_SLEEP 128 /* to char, even if sleeping */
|
||||
#define DG_NO_TRIG 256 /* don't check act trigger */
|
||||
#define LOG_MESSG 512 /* log to message history */
|
||||
|
||||
/* I/O functions */
|
||||
void write_to_q(const char *txt, struct txt_q *queue, int aliased);
|
||||
int write_to_descriptor(socket_t desc, const char *txt);
|
||||
|
|
|
|||
|
|
@ -13,14 +13,9 @@
|
|||
#include "structs.h"
|
||||
#include "interpreter.h" /* alias_data */
|
||||
|
||||
cpp_extern const char *circlemud_version =
|
||||
"tbaMUD, version 3.52";
|
||||
|
||||
cpp_extern const char *oasisolc_version =
|
||||
"OasisOLC 2.0.6";
|
||||
|
||||
cpp_extern const char *ascii_pfiles_version =
|
||||
"ASCII Player Files 3.0.1";
|
||||
cpp_extern const char *circlemud_version = "tbaMUD, version 3.52";
|
||||
cpp_extern const char *oasisolc_version = "OasisOLC 2.0.6";
|
||||
cpp_extern const char *ascii_pfiles_version = "ASCII Player Files 3.0.1";
|
||||
|
||||
/* strings corresponding to ordinals/bitvectors in structs.h */
|
||||
/* (Note: strings for class definitions in class.c instead of here) */
|
||||
|
|
@ -82,10 +77,7 @@ const char *sector_types[] = {
|
|||
"\n"
|
||||
};
|
||||
|
||||
/*
|
||||
* SEX_x
|
||||
* Not used in sprinttype() so no \n.
|
||||
*/
|
||||
/* SEX_x. Not used in sprinttype() so no \n. */
|
||||
const char *genders[] =
|
||||
{
|
||||
"neutral",
|
||||
|
|
@ -256,10 +248,7 @@ const char *connected_types[] = {
|
|||
"\n"
|
||||
};
|
||||
|
||||
/*
|
||||
* WEAR_x - for eq list
|
||||
* Not use in sprinttype() so no \n.
|
||||
*/
|
||||
/* WEAR_x - for eq list. Not used in sprinttype() so no \n. */
|
||||
const char *wear_where[] = {
|
||||
"<used as light> ",
|
||||
"<worn on finger> ",
|
||||
|
|
@ -436,8 +425,7 @@ const char *drinks[] =
|
|||
"\n"
|
||||
};
|
||||
|
||||
/* other constants for liquids ******************************************/
|
||||
/* one-word alias for each drink */
|
||||
/* Other constants for liquids, one-word alias for each drink. */
|
||||
const char *drinknames[] =
|
||||
{
|
||||
"water",
|
||||
|
|
@ -501,10 +489,7 @@ const char *color_liquid[] =
|
|||
"\n"
|
||||
};
|
||||
|
||||
/*
|
||||
* level of fullness for drink containers
|
||||
* Not used in sprinttype() so no \n.
|
||||
*/
|
||||
/* level of fullness for drink containers. Not used in sprinttype() so no \n. */
|
||||
const char *fullness[] =
|
||||
{
|
||||
"less than half ",
|
||||
|
|
@ -836,12 +821,22 @@ const char *wtrig_types[] = {
|
|||
"\n"
|
||||
};
|
||||
|
||||
const char *history_types[] = {
|
||||
"all",
|
||||
"say",
|
||||
"gossip",
|
||||
"wiznet",
|
||||
"tell",
|
||||
"shout",
|
||||
"grats",
|
||||
"holler",
|
||||
"auction",
|
||||
"\n"
|
||||
};
|
||||
/* --- End of constants arrays. --- */
|
||||
|
||||
/*
|
||||
* Various arrays we count so we can check the world files. These
|
||||
* must be at the bottom of the file so they're pre-declared.
|
||||
*/
|
||||
/* Various arrays we count so we can check the world files. These
|
||||
* must be at the bottom of the file so they're pre-declared. */
|
||||
size_t room_bits_count = sizeof(room_bits) / sizeof(room_bits[0]) - 1,
|
||||
action_bits_count = sizeof(action_bits) / sizeof(action_bits[0]) - 1,
|
||||
affected_bits_count = sizeof(affected_bits) / sizeof(affected_bits[0]) - 1,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
/* ************************************************************************
|
||||
* File: constants.h Part of tbaMUD *
|
||||
* Usage: Header file for constants. *
|
||||
* All rights reserved. See license for complete information. *
|
||||
* *
|
||||
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
|
||||
* tbaMUD is based on CircleMUD and DikuMUD, Copyright (C) 1990, 1991. *
|
||||
************************************************************************ */
|
||||
|
||||
extern const char *circlemud_version;
|
||||
extern const char *oasisolc_version;
|
||||
extern const char *ascii_pfiles_version;
|
||||
|
|
@ -38,6 +47,7 @@ extern int drink_aff[][3];
|
|||
extern const char *trig_types[];
|
||||
extern const char *otrig_types[];
|
||||
extern const char *wtrig_types[];
|
||||
extern const char *history_types[];
|
||||
extern size_t room_bits_count;
|
||||
extern size_t action_bits_count;
|
||||
extern size_t affected_bits_count;
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ void trigedit_parse(struct descriptor_data *d, char *arg)
|
|||
if (!GET_TRIG_TYPE(OLC_TRIG(d))) {
|
||||
write_to_output(d, "Invalid Trigger Type! Answer a to abort quit!\r\n");
|
||||
}
|
||||
write_to_output(d, "Do you wish to save the changes to the trigger? (y/n): ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
OLC_MODE(d) = TRIGEDIT_CONFIRM_SAVESTRING;
|
||||
} else
|
||||
cleanup_olc(d, CLEANUP_ALL);
|
||||
|
|
|
|||
18
src/fight.c
18
src/fight.c
|
|
@ -302,13 +302,11 @@ void make_corpse(struct char_data *ch)
|
|||
|
||||
/* transfer gold */
|
||||
if (GET_GOLD(ch) > 0) {
|
||||
/*
|
||||
* following 'if' clause added to fix gold duplication loophole
|
||||
* The above line apparently refers to the old "partially log in,
|
||||
* kill the game character, then finish login sequence" duping
|
||||
* bug. The duplication has been fixed (knock on wood) but the
|
||||
* test below shall live on, for a while. -gg 3/3/2002
|
||||
*/
|
||||
/* following 'if' clause added to fix gold duplication loophole. The above
|
||||
* line apparently refers to the old "partially log in, kill the game
|
||||
* character, then finish login sequence" duping bug. The duplication has
|
||||
* been fixed (knock on wood) but the test below shall live on, for a
|
||||
* while. -gg 3/3/2002 */
|
||||
if (IS_NPC(ch) || ch->desc) {
|
||||
money = create_money(GET_GOLD(ch));
|
||||
obj_to_obj(money, corpse);
|
||||
|
|
@ -564,14 +562,16 @@ void dam_message(int dam, struct char_data *ch, struct char_data *victim,
|
|||
act(buf, FALSE, ch, NULL, victim, TO_NOTVICT);
|
||||
|
||||
/* damage message to damager */
|
||||
send_to_char(ch, "@Y(%d)", dam);
|
||||
if (GET_LEVEL(ch) >= LVL_IMMORT)
|
||||
send_to_char(ch, "(%d) ", dam);
|
||||
buf = replace_string(dam_weapons[msgnum].to_char,
|
||||
attack_hit_text[w_type].singular, attack_hit_text[w_type].plural);
|
||||
act(buf, FALSE, ch, NULL, victim, TO_CHAR);
|
||||
send_to_char(ch, CCNRM(ch, C_CMP));
|
||||
|
||||
/* damage message to damagee */
|
||||
send_to_char(victim, "@R(%d)", dam);
|
||||
if (GET_LEVEL(ch) >= LVL_IMMORT)
|
||||
send_to_char(victim, "@R(%d)", dam);
|
||||
buf = replace_string(dam_weapons[msgnum].to_victim,
|
||||
attack_hit_text[w_type].singular, attack_hit_text[w_type].plural);
|
||||
act(buf, FALSE, ch, NULL, victim, TO_VICT | TO_SLEEP);
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@ void hedit_parse(struct descriptor_data *d, char *arg)
|
|||
cleanup_olc(d, CLEANUP_ALL);
|
||||
break;
|
||||
default:
|
||||
write_to_output(d, "Invalid choice!\r\nDo you wish to save this help entry internally? : \r\n");
|
||||
write_to_output(d, "Invalid choice!\r\nDo you wish to save your changes? : \r\n");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
|
@ -294,7 +294,7 @@ void hedit_parse(struct descriptor_data *d, char *arg)
|
|||
case 'q':
|
||||
case 'Q':
|
||||
if (OLC_VAL(d)) { /* Something has been modified. */
|
||||
write_to_output(d, "Do you wish to save this help entry? : ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
OLC_MODE(d) = HEDIT_CONFIRM_SAVESTRING;
|
||||
} else {
|
||||
log("this is a test of quit out of hedit");
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include "conf.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
#include "structs.h"
|
||||
#include "comm.h"
|
||||
#include "interpreter.h"
|
||||
|
|
@ -73,17 +72,20 @@ ACMD(do_alias);
|
|||
ACMD(do_assist);
|
||||
ACMD(do_astat);
|
||||
ACMD(do_at);
|
||||
ACMD(do_attach);
|
||||
ACMD(do_backstab);
|
||||
ACMD(do_ban);
|
||||
ACMD(do_bash);
|
||||
ACMD(do_cast);
|
||||
ACMD(do_changelog);
|
||||
ACMD(do_checkloadstatus);
|
||||
ACMD(do_commands);
|
||||
ACMD(do_consider);
|
||||
ACMD(do_copyover);
|
||||
ACMD(do_credits);
|
||||
ACMD(do_date);
|
||||
ACMD(do_dc);
|
||||
ACMD(do_detach);
|
||||
ACMD(do_diagnose);
|
||||
ACMD(do_dig);
|
||||
ACMD(do_display);
|
||||
|
|
@ -96,6 +98,8 @@ ACMD(do_equipment);
|
|||
ACMD(do_examine);
|
||||
ACMD(do_exit);
|
||||
ACMD(do_exits);
|
||||
ACMD(do_export_zone);
|
||||
ACMD(do_file);
|
||||
ACMD(do_flee);
|
||||
ACMD(do_follow);
|
||||
ACMD(do_force);
|
||||
|
|
@ -115,6 +119,7 @@ ACMD(do_gsay);
|
|||
ACMD(do_hcontrol);
|
||||
ACMD(do_help);
|
||||
ACMD(do_hindex);
|
||||
ACMD(do_history);
|
||||
ACMD(do_helpcheck);
|
||||
ACMD(do_hide);
|
||||
ACMD(do_hit);
|
||||
|
|
@ -126,9 +131,31 @@ ACMD(do_kill);
|
|||
ACMD(do_last);
|
||||
ACMD(do_leave);
|
||||
ACMD(do_levels);
|
||||
ACMD(do_links);
|
||||
ACMD(do_load);
|
||||
ACMD(do_look);
|
||||
ACMD(do_masound);
|
||||
ACMD(do_mat);
|
||||
ACMD(do_mdamage);
|
||||
ACMD(do_mdoor);
|
||||
ACMD(do_mecho);
|
||||
ACMD(do_mechoaround);
|
||||
ACMD(do_mfollow);
|
||||
ACMD(do_mforce);
|
||||
ACMD(do_mgoto);
|
||||
ACMD(do_mhunt);
|
||||
ACMD(do_mjunk);
|
||||
ACMD(do_mkill);
|
||||
ACMD(do_mload);
|
||||
/* ACMD(do_move); -- interpreter.h */
|
||||
ACMD(do_mpurge);
|
||||
ACMD(do_msend);
|
||||
ACMD(do_mteleport);
|
||||
ACMD(do_mremember);
|
||||
ACMD(do_mforget);
|
||||
ACMD(do_mtransform);
|
||||
ACMD(do_mzoneecho);
|
||||
ACMD(do_mrecho);
|
||||
ACMD(do_not_here);
|
||||
ACMD(do_order);
|
||||
ACMD(do_page);
|
||||
|
|
@ -171,13 +198,16 @@ ACMD(do_teleport);
|
|||
ACMD(do_tell);
|
||||
ACMD(do_time);
|
||||
ACMD(do_title);
|
||||
ACMD(do_tlist);
|
||||
ACMD(do_toggle);
|
||||
ACMD(do_track);
|
||||
ACMD(do_trans);
|
||||
ACMD(do_tstat);
|
||||
ACMD(do_unban);
|
||||
ACMD(do_ungroup);
|
||||
ACMD(do_use);
|
||||
ACMD(do_users);
|
||||
ACMD(do_vdelete);
|
||||
ACMD(do_visible);
|
||||
ACMD(do_vnum);
|
||||
ACMD(do_vstat);
|
||||
|
|
@ -191,63 +221,22 @@ ACMD(do_wizlock);
|
|||
ACMD(do_wiznet);
|
||||
ACMD(do_wizutil);
|
||||
ACMD(do_write);
|
||||
ACMD(do_zcheck);
|
||||
ACMD(do_zreset);
|
||||
ACMD(do_zpurge);
|
||||
|
||||
/* DG Script ACMD's */
|
||||
ACMD(do_attach);
|
||||
ACMD(do_detach);
|
||||
ACMD(do_tstat);
|
||||
ACMD(do_masound);
|
||||
ACMD(do_mkill);
|
||||
ACMD(do_mjunk);
|
||||
ACMD(do_mdoor);
|
||||
ACMD(do_mechoaround);
|
||||
ACMD(do_msend);
|
||||
ACMD(do_mecho);
|
||||
ACMD(do_mload);
|
||||
ACMD(do_mpurge);
|
||||
ACMD(do_mgoto);
|
||||
ACMD(do_mat);
|
||||
ACMD(do_mdamage);
|
||||
ACMD(do_mteleport);
|
||||
ACMD(do_mforce);
|
||||
ACMD(do_mhunt);
|
||||
ACMD(do_mremember);
|
||||
ACMD(do_mforget);
|
||||
ACMD(do_mtransform);
|
||||
ACMD(do_mzoneecho);
|
||||
ACMD(do_mrecho);
|
||||
ACMD(do_vdelete);
|
||||
ACMD(do_mfollow);
|
||||
ACMD(do_tlist);
|
||||
|
||||
/* TBA specifics */
|
||||
ACMD(do_file);
|
||||
ACMD(do_checkloadstatus);
|
||||
ACMD(do_links);
|
||||
ACMD(do_zcheck);
|
||||
ACMD(do_list_history);
|
||||
ACMD(do_export_zone);
|
||||
|
||||
|
||||
struct command_info *complete_cmd_info;
|
||||
|
||||
/* This is the Master Command List(tm).
|
||||
|
||||
* You can put new commands in, take commands out, change the order
|
||||
* they appear in, etc. You can adjust the "priority" of commands
|
||||
* simply by changing the order they appear in the command list.
|
||||
* (For example, if you want "as" to mean "assist" instead of "ask",
|
||||
* just put "assist" above "ask" in the Master Command List(tm).
|
||||
*
|
||||
* In general, utility commands such as "at" should have high priority;
|
||||
* infrequently used and dangerously destructive commands should have low
|
||||
* priority.
|
||||
*/
|
||||
/* This is the Master Command List. You can put new commands in, take commands
|
||||
* out, change the order they appear in, etc. You can adjust the "priority"
|
||||
* of commands simply by changing the order they appear in the command list.
|
||||
* (For example, if you want "as" to mean "assist" instead of "ask", just put
|
||||
* "assist" above "ask" in the Master Command List. In general, utility
|
||||
* commands such as "at" should have high priority; infrequently used and
|
||||
* dangerously destructive commands should have low priority. */
|
||||
|
||||
cpp_extern const struct command_info cmd_info[] = {
|
||||
{ "RESERVED", "", 0, 0, 0, 0 }, /* this must be first -- for specprocs */
|
||||
{ "RESERVED", "", 0, 0, 0, 0 }, /* this must be first -- for specprocs */
|
||||
|
||||
/* directions must come before other commands but after RESERVED */
|
||||
{ "north" , "n" , POS_STANDING, do_move , 0, SCMD_NORTH },
|
||||
|
|
@ -340,7 +329,7 @@ cpp_extern const struct command_info cmd_info[] = {
|
|||
{ "hide" , "hi" , POS_RESTING , do_hide , 1, 0 },
|
||||
{ "handbook" , "handb" , POS_DEAD , do_gen_ps , LVL_IMMORT, SCMD_HANDBOOK },
|
||||
{ "hcontrol" , "hcontrol", POS_DEAD , do_hcontrol , LVL_GRGOD, 0 },
|
||||
{ "history" , "histo" , POS_DEAD , do_list_history, 1, 0},
|
||||
{ "history" , "history" , POS_DEAD , do_history, 0, 0},
|
||||
{ "hit" , "hit" , POS_FIGHTING, do_hit , 0, SCMD_HIT },
|
||||
{ "hold" , "hold" , POS_RESTING , do_grab , 1, 0 },
|
||||
{ "holler" , "holler" , POS_RESTING , do_gen_comm , 1, SCMD_HOLLER },
|
||||
|
|
@ -536,7 +525,6 @@ cpp_extern const struct command_info cmd_info[] = {
|
|||
|
||||
{ "\n", "zzzzzzz", 0, 0, 0, 0 } }; /* this must be last */
|
||||
|
||||
|
||||
const char *fill[] =
|
||||
{
|
||||
"in",
|
||||
|
|
@ -1467,6 +1455,7 @@ void nanny(struct descriptor_data *d, char *arg)
|
|||
REMOVE_BIT(PLR_FLAGS(d->character),
|
||||
PLR_WRITING | PLR_MAILING | PLR_CRYO);
|
||||
REMOVE_BIT(AFF_FLAGS(d->character), AFF_GROUP);
|
||||
d->character->player.time.logon = time(0);
|
||||
write_to_output(d, "Password: ");
|
||||
echo_off(d);
|
||||
d->idle_tics = 0;
|
||||
|
|
|
|||
40
src/limits.c
40
src/limits.c
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#include "conf.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
#include "structs.h"
|
||||
#include "utils.h"
|
||||
#include "spells.h"
|
||||
|
|
@ -54,16 +53,12 @@ int graf(int grafage, int p0, int p1, int p2, int p3, int p4, int p5, int p6)
|
|||
return (p6); /* >= 80 */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The hit_limit, mana_limit, and move_limit functions are gone. They
|
||||
* added an unnecessary level of complexity to the internal structure,
|
||||
* weren't particularly useful, and led to some annoying bugs. From the
|
||||
* players' point of view, the only difference the removal of these
|
||||
* functions will make is that a character's age will now only affect
|
||||
* the HMV gain per tick, and _not_ the HMV maximums.
|
||||
*/
|
||||
|
||||
/* The hit_limit, mana_limit, and move_limit functions are gone. They added an
|
||||
* unnecessary level of complexity to the internal structure, weren't
|
||||
* particularly useful, and led to some annoying bugs. From the players' point
|
||||
* of view, the only difference the removal of these functions will make is
|
||||
* that a character's age will now only affect the HMV gain per tick, and _not_
|
||||
* the HMV maximums. */
|
||||
/* manapoint gain pr. game hour */
|
||||
int mana_gain(struct char_data *ch)
|
||||
{
|
||||
|
|
@ -105,7 +100,6 @@ int mana_gain(struct char_data *ch)
|
|||
return (gain);
|
||||
}
|
||||
|
||||
|
||||
/* Hitpoint gain pr. game hour */
|
||||
int hit_gain(struct char_data *ch)
|
||||
{
|
||||
|
|
@ -149,8 +143,6 @@ int hit_gain(struct char_data *ch)
|
|||
return (gain);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* move gain pr. game hour */
|
||||
int move_gain(struct char_data *ch)
|
||||
{
|
||||
|
|
@ -163,10 +155,7 @@ int move_gain(struct char_data *ch)
|
|||
gain = graf(age(ch)->year, 16, 20, 24, 20, 16, 12, 10);
|
||||
|
||||
/* Class/Level calculations */
|
||||
|
||||
/* Skill/Spell calculations */
|
||||
|
||||
|
||||
/* Position calculations */
|
||||
switch (GET_POS(ch)) {
|
||||
case POS_SLEEPING:
|
||||
|
|
@ -190,8 +179,6 @@ int move_gain(struct char_data *ch)
|
|||
return (gain);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_title(struct char_data *ch, char *title)
|
||||
{
|
||||
if (title == NULL) {
|
||||
|
|
@ -210,7 +197,6 @@ void set_title(struct char_data *ch, char *title)
|
|||
GET_TITLE(ch) = strdup(title);
|
||||
}
|
||||
|
||||
|
||||
void run_autowiz(void)
|
||||
{
|
||||
#if defined(CIRCLE_UNIX) || defined(CIRCLE_WINDOWS)
|
||||
|
|
@ -237,8 +223,6 @@ void run_autowiz(void)
|
|||
#endif /* CIRCLE_UNIX || CIRCLE_WINDOWS */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void gain_exp(struct char_data *ch, int gain)
|
||||
{
|
||||
int is_altered = FALSE;
|
||||
|
|
@ -281,7 +265,6 @@ void gain_exp(struct char_data *ch, int gain)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void gain_exp_regardless(struct char_data *ch, int gain)
|
||||
{
|
||||
int is_altered = FALSE;
|
||||
|
|
@ -314,7 +297,6 @@ void gain_exp_regardless(struct char_data *ch, int gain)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void gain_condition(struct char_data *ch, int condition, int value)
|
||||
{
|
||||
bool intoxicated;
|
||||
|
|
@ -349,7 +331,6 @@ void gain_condition(struct char_data *ch, int condition, int value)
|
|||
|
||||
}
|
||||
|
||||
|
||||
void check_idling(struct char_data *ch)
|
||||
{
|
||||
if (++(ch->char_specials.timer) > CONFIG_IDLE_VOID) {
|
||||
|
|
@ -389,8 +370,6 @@ void check_idling(struct char_data *ch)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update PCs, NPCs, and objects */
|
||||
void point_update(void)
|
||||
{
|
||||
|
|
@ -425,7 +404,8 @@ void point_update(void)
|
|||
update_char_objects(i);
|
||||
if (GET_LEVEL(i) < CONFIG_IDLE_MAX_LEVEL)
|
||||
check_idling(i);
|
||||
}
|
||||
else
|
||||
(i->char_specials.timer)++;}
|
||||
}
|
||||
|
||||
/* objects */
|
||||
|
|
@ -464,8 +444,8 @@ void point_update(void)
|
|||
extract_obj(j);
|
||||
}
|
||||
}
|
||||
/* If the timer is set, count it down and at 0, try the trigger */
|
||||
/* note to .rej hand-patchers: make this last in your point-update() */
|
||||
/* If the timer is set, count it down and at 0, try the trigger
|
||||
* note to .rej hand-patchers: make this last in your point-update() */
|
||||
else if (GET_OBJ_TIMER(j)>0) {
|
||||
GET_OBJ_TIMER(j)--;
|
||||
if (!GET_OBJ_TIMER(j))
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ void medit_parse(struct descriptor_data *d, char *arg)
|
|||
return;
|
||||
default:
|
||||
write_to_output(d, "Invalid choice!\r\n");
|
||||
write_to_output(d, "Do you wish to save the mobile? : ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
@ -484,7 +484,7 @@ void medit_parse(struct descriptor_data *d, char *arg)
|
|||
case 'q':
|
||||
case 'Q':
|
||||
if (OLC_VAL(d)) { /* Anything been changed? */
|
||||
write_to_output(d, "Do you wish to save the changes to the mobile? (y/n) : ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
OLC_MODE(d) = MEDIT_CONFIRM_SAVESTRING;
|
||||
} else
|
||||
cleanup_olc(d, CLEANUP_ALL);
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
#include "conf.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
|
||||
#include "structs.h"
|
||||
#include "comm.h"
|
||||
#include "handler.h"
|
||||
|
|
@ -70,10 +68,7 @@ int objsave_write_rentcode(FILE *fl, int rentcode, int cost_per_day, struct char
|
|||
int objsave_save_obj_record(struct obj_data *obj, FILE *fl, int location);
|
||||
void strip_cr(char *buffer);
|
||||
|
||||
/*
|
||||
* Writes one object record to FILE.
|
||||
* Old name: Obj_to_store()
|
||||
*/
|
||||
/* Writes one object record to FILE. Old name: Obj_to_store() */
|
||||
int objsave_save_obj_record(struct obj_data *obj, FILE *fp, int locate)
|
||||
{
|
||||
int counter2;
|
||||
|
|
@ -90,6 +85,7 @@ int objsave_save_obj_record(struct obj_data *obj, FILE *fp, int locate)
|
|||
}
|
||||
|
||||
if (obj->action_description) {
|
||||
|
||||
strcpy(buf1, obj->action_description);
|
||||
strip_cr(buf1);
|
||||
} else
|
||||
|
|
|
|||
|
|
@ -730,7 +730,7 @@ void oedit_parse(struct descriptor_data *d, char *arg)
|
|||
return;
|
||||
default:
|
||||
write_to_output(d, "Invalid choice!\r\n");
|
||||
write_to_output(d, "Do you wish to save this object?\r\n");
|
||||
write_to_output(d, "Do you wish to save your changes? : \r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -740,7 +740,7 @@ void oedit_parse(struct descriptor_data *d, char *arg)
|
|||
case 'q':
|
||||
case 'Q':
|
||||
if (OLC_VAL(d)) { /* Something has been modified. */
|
||||
write_to_output(d, "Do you wish to save this object? : ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
OLC_MODE(d) = OEDIT_CONFIRM_SAVESTRING;
|
||||
} else
|
||||
cleanup_olc(d, CLEANUP_ALL);
|
||||
|
|
|
|||
|
|
@ -490,7 +490,7 @@ void redit_parse(struct descriptor_data *d, char *arg)
|
|||
cleanup_olc(d, CLEANUP_ALL);
|
||||
break;
|
||||
default:
|
||||
write_to_output(d, "Invalid choice!\r\nDo you wish to save this room ? : ");
|
||||
write_to_output(d, "Invalid choice!\r\nDo you wish to save your changes ? : ");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
|
@ -500,7 +500,7 @@ void redit_parse(struct descriptor_data *d, char *arg)
|
|||
case 'q':
|
||||
case 'Q':
|
||||
if (OLC_VAL(d)) { /* Something has been modified. */
|
||||
write_to_output(d, "Do you wish to save this room ? : ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
OLC_MODE(d) = REDIT_CONFIRM_SAVESTRING;
|
||||
} else
|
||||
cleanup_olc(d, CLEANUP_ALL);
|
||||
|
|
|
|||
|
|
@ -471,7 +471,7 @@ void sedit_parse(struct descriptor_data *d, char *arg)
|
|||
case 'q':
|
||||
case 'Q':
|
||||
if (OLC_VAL(d)) { /* Anything been changed? */
|
||||
write_to_output(d, "Do you wish to save the changes to the shop? (y/n) : ");
|
||||
write_to_output(d, "Do you wish to save your changes? : ");
|
||||
OLC_MODE(d) = SEDIT_CONFIRM_SAVESTRING;
|
||||
} else
|
||||
cleanup_olc(d, CLEANUP_ALL);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* ************************************************************************
|
||||
* File: structs.h Part of CircleMUD *
|
||||
* Usage: header file for central structures and contstants *
|
||||
* Usage: header file for central structures and constants *
|
||||
* All rights reserved. See license.doc for complete information. *
|
||||
* *
|
||||
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University *
|
||||
|
|
@ -88,6 +88,20 @@
|
|||
#define SECT_UNDERWATER 9 /* Underwater */
|
||||
|
||||
/* char and mob-related defines */
|
||||
|
||||
/* History */
|
||||
#define HIST_ALL 0
|
||||
#define HIST_SAY 1
|
||||
#define HIST_GOSSIP 2
|
||||
#define HIST_WIZNET 3
|
||||
#define HIST_TELL 4
|
||||
#define HIST_SHOUT 5
|
||||
#define HIST_GRATS 6
|
||||
#define HIST_HOLLER 7
|
||||
#define HIST_AUCTION 8
|
||||
|
||||
#define NUM_HIST 9
|
||||
|
||||
/* PC classes */
|
||||
#define CLASS_UNDEFINED (-1)
|
||||
#define CLASS_MAGIC_USER 0
|
||||
|
|
@ -528,14 +542,14 @@ struct extra_descr_data {
|
|||
/* object flags; used in obj_data */
|
||||
struct obj_flag_data {
|
||||
int value[NUM_OBJ_VAL_POSITIONS]; /* Values of the item (see list) */
|
||||
byte type_flag; /* Type of item */
|
||||
int level; /* Minimum level of object. */
|
||||
byte type_flag; /* Type of item */
|
||||
int level; /* Minimum level of object */
|
||||
int /*bitvector_t*/ wear_flags; /* Where you can wear it */
|
||||
int /*bitvector_t*/ extra_flags; /* If it hums, glows, etc. */
|
||||
int weight; /* Weigt what else */
|
||||
int cost; /* Value when sold (gp.) */
|
||||
int cost_per_day; /* Cost to keep pr. real day */
|
||||
int timer; /* Timer for object */
|
||||
int weight; /* Weight what else */
|
||||
int cost; /* Value when sold (gp.) */
|
||||
int cost_per_day; /* Cost to keep pr. real day */
|
||||
int timer; /* Timer for object */
|
||||
long /*bitvector_t*/ bitvector; /* To set chars bits */
|
||||
};
|
||||
|
||||
|
|
@ -752,7 +766,7 @@ struct player_special_data_saved {
|
|||
long /*bitvector_t*/ pref; /* preference flags for PC's. */
|
||||
ubyte bad_pws; /* number of bad password attemps */
|
||||
sbyte conditions[3]; /* Drunk, hunger, thirst */
|
||||
|
||||
struct txt_block *comm_hist[NUM_HIST]; /* Player's communcations history */
|
||||
ubyte page_length;
|
||||
int spells_to_learn; /* How many can you learn yet this level*/
|
||||
int olc_zone;
|
||||
|
|
@ -875,7 +889,6 @@ struct descriptor_data {
|
|||
int bufspace; /* space left in the output buffer */
|
||||
struct txt_block *large_outbuf; /* ptr to large buffer, if we need it */
|
||||
struct txt_q input; /* q of unprocessed input */
|
||||
struct txt_block *comms; /* latest comms history. */
|
||||
struct char_data *character; /* linked to char */
|
||||
struct char_data *original; /* original char if switched */
|
||||
struct descriptor_data *snooping; /* Who is this char snooping */
|
||||
|
|
|
|||
|
|
@ -6,22 +6,9 @@
|
|||
* Copyright (C) 1993 The Trustees of The Johns Hopkins University *
|
||||
************************************************************************* */
|
||||
|
||||
|
||||
/*
|
||||
WARNING: THIS CODE IS A HACK. WE CAN NOT AND WILL NOT BE RESPONSIBLE
|
||||
FOR ANY NASUEA, DIZZINESS, VOMITING, OR SHORTNESS OF BREATH RESULTING
|
||||
FROM READING THIS CODE. PREGNANT WOMEN AND INDIVIDUALS WITH BACK
|
||||
INJURIES, HEART CONDITIONS, OR ARE UNDER THE CARE OF A PHYSICIAN SHOULD
|
||||
NOT READ THIS CODE.
|
||||
|
||||
-- The Management
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "structs.h"
|
||||
#include "utils.h"
|
||||
#include "db.h"
|
||||
|
|
@ -59,7 +46,6 @@ struct control_rec level_params[] =
|
|||
{0, ""}
|
||||
};
|
||||
|
||||
|
||||
struct level_rec *levels = 0;
|
||||
|
||||
void initialize(void)
|
||||
|
|
@ -76,7 +62,6 @@ void initialize(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void read_file(void)
|
||||
{
|
||||
void add_name(byte level, char *name);
|
||||
|
|
@ -111,12 +96,10 @@ void read_file(void)
|
|||
!(IS_SET(flags, PINDEX_NOWIZLIST)) &&
|
||||
!(IS_SET(flags, PINDEX_DELETED)))
|
||||
add_name(level, name);
|
||||
}
|
||||
|
||||
}
|
||||
fclose(fl);
|
||||
}
|
||||
|
||||
|
||||
void add_name(byte level, char *name)
|
||||
{
|
||||
struct name_rec *tmp;
|
||||
|
|
@ -142,7 +125,6 @@ void add_name(byte level, char *name)
|
|||
curr_level->names = tmp;
|
||||
}
|
||||
|
||||
|
||||
void sort_names(void)
|
||||
{
|
||||
struct level_rec *curr_level;
|
||||
|
|
@ -162,7 +144,6 @@ void sort_names(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void write_wizlist(FILE * out, int minlev, int maxlev)
|
||||
{
|
||||
char buf[100];
|
||||
|
|
@ -172,10 +153,7 @@ void write_wizlist(FILE * out, int minlev, int maxlev)
|
|||
|
||||
fprintf(out,
|
||||
"*************************************************************************\n"
|
||||
"* The following people have reached immortality on CircleMUD. They are *\n"
|
||||
"* to be treated with respect and awe. Occasional prayers to them are *\n"
|
||||
"* advisable. Annoying them is not recommended. Stealing from them is *\n"
|
||||
"* punishable by immediate death. *\n"
|
||||
"* The following people have reached immortality on tbaMUD. *\n"
|
||||
"*************************************************************************\n\n");
|
||||
|
||||
for (curr_level = levels; curr_level; curr_level = curr_level->next) {
|
||||
|
|
@ -231,9 +209,6 @@ void write_wizlist(FILE * out, int minlev, int maxlev)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int wizlevel, immlevel, pid = 0;
|
||||
|
|
@ -278,14 +253,10 @@ char *CAP(char *txt)
|
|||
return (txt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_line reads the next non-blank line off of the input stream.
|
||||
* The newline character is removed from the input. Lines which begin
|
||||
* with '*' are considered to be comments.
|
||||
*
|
||||
* Returns the number of lines advanced in the file.
|
||||
*/
|
||||
/* get_line reads the next non-blank line off of the input stream. The newline
|
||||
* character is removed from the input. Lines which begin with '*' are
|
||||
* considered to be comments. Returns the number of lines advanced in the
|
||||
* file. */
|
||||
int get_line(FILE * fl, char *buf)
|
||||
{
|
||||
char temp[256];
|
||||
|
|
@ -303,7 +274,6 @@ int get_line(FILE * fl, char *buf)
|
|||
return (lines);
|
||||
}
|
||||
|
||||
|
||||
bitvector_t asciiflag_conv(char *flag)
|
||||
{
|
||||
bitvector_t flags = 0;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ bool circle_follow(struct char_data *ch, struct char_data *victim);
|
|||
|
||||
/* in act.informative.c */
|
||||
void look_at_room(struct char_data *ch, int mode);
|
||||
void add_history(struct char_data *ch, char *msg, int type);
|
||||
|
||||
/* in act.movmement.c */
|
||||
int do_simple_move(struct char_data *ch, int dir, int following);
|
||||
|
|
@ -329,7 +330,7 @@ void update_pos(struct char_data *victim);
|
|||
#define GET_LAST_TELL(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->last_tell))
|
||||
#define GET_PREF(ch) ((ch)->pref)
|
||||
#define GET_HOST(ch) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->host))
|
||||
|
||||
#define GET_HISTORY(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.comm_hist[i]))
|
||||
|
||||
#define GET_SKILL(ch, i) CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.skills[i]))
|
||||
#define SET_SKILL(ch, i, pct) do { CHECK_PLAYER_SPECIAL((ch), (ch)->player_specials->saved.skills[i]) = pct; } while(0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue