mirror of
https://github.com/tbamud/tbamud.git
synced 2025-09-22 05:50:48 +02:00
Removed hsedit.c mailedit.c protocol.c and protocol.h which were interfering with compiling.
This commit is contained in:
parent
479dbb6cbd
commit
6dadf24c51
4 changed files with 0 additions and 4563 deletions
1134
src/hsedit.c
1134
src/hsedit.c
File diff suppressed because it is too large
Load diff
898
src/mailedit.c
898
src/mailedit.c
|
@ -1,898 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
* File: mailedit.c Part of tbaMUD *
|
|
||||||
* Usage: Oasis OLC - Mudmail. *
|
|
||||||
* *
|
|
||||||
* Copyright 1996 Harvey Gilpin. 1997-2001 George Greer. 2010 Stefan Cole. *
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "conf.h"
|
|
||||||
#include "sysdep.h"
|
|
||||||
#include "structs.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "interpreter.h"
|
|
||||||
#include "db.h"
|
|
||||||
#include "comm.h"
|
|
||||||
#include "handler.h"
|
|
||||||
#include "modify.h"
|
|
||||||
#include "mail.h"
|
|
||||||
#include "oasis.h"
|
|
||||||
#include "improved-edit.h"
|
|
||||||
|
|
||||||
/* External functions */
|
|
||||||
void list_obj_to_char(struct obj_data *list, struct char_data *ch, int mode, int show);
|
|
||||||
|
|
||||||
/* external global variables */
|
|
||||||
extern const struct mail_group mail_groups[];
|
|
||||||
|
|
||||||
/* utility functions */
|
|
||||||
ACMD(do_mailedit)
|
|
||||||
{
|
|
||||||
struct descriptor_data *d;
|
|
||||||
|
|
||||||
d = ch->desc;
|
|
||||||
|
|
||||||
/* Give descriptor an OLC structure. */
|
|
||||||
if (d->olc) {
|
|
||||||
mudlog(BRF, ADMLVL_IMMORT, TRUE,
|
|
||||||
"SYSERR: do_oasis_medit: Player already had olc structure.");
|
|
||||||
free(d->olc);
|
|
||||||
}
|
|
||||||
|
|
||||||
CREATE(d->olc, struct oasis_olc_data, 1);
|
|
||||||
|
|
||||||
OLC_ZNUM(d) = NOWHERE;
|
|
||||||
OLC_NUM(d) = 0;
|
|
||||||
|
|
||||||
mailedit_setup(d);
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
|
|
||||||
/* Display messages to the players in the same room as the
|
|
||||||
player and also log it. */
|
|
||||||
act("$n starts editing mail.", TRUE, ch, 0, 0, TO_ROOM);
|
|
||||||
SET_BIT_AR(PLR_FLAGS(ch), PLR_MAILING);
|
|
||||||
SET_BIT_AR(PLR_FLAGS(ch), PLR_WRITING);
|
|
||||||
STATE(d) = CON_MAILEDIT;
|
|
||||||
|
|
||||||
mudlog(CMP, ADMLVL_IMMORT, TRUE,"MAIL: %s starts editing mudmail in room %d",
|
|
||||||
GET_NAME(ch), world[IN_ROOM(d->character)].number);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No 'new' or 'existing' to edit - just set up the mudmail structures */
|
|
||||||
void mailedit_setup(struct descriptor_data *d)
|
|
||||||
{
|
|
||||||
struct mail_edit_data *mail_info;
|
|
||||||
|
|
||||||
/* Allocate a scratch mudmails structure. */
|
|
||||||
CREATE(mail_info, struct mail_edit_data, 1);
|
|
||||||
|
|
||||||
mail_info->mail = create_mail();
|
|
||||||
mail_info->recipients = NULL;
|
|
||||||
|
|
||||||
OLC_MAIL(d) = mail_info;
|
|
||||||
|
|
||||||
/* Has changed flag. (It hasn't so far, we just made it.) */
|
|
||||||
OLC_VAL(d) = FALSE;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear up memory used by the mudmail structures */
|
|
||||||
void mailedit_cleanup(struct descriptor_data *d)
|
|
||||||
{
|
|
||||||
struct mail_edit_data *mail_info;
|
|
||||||
struct mail_data *single_mail;
|
|
||||||
struct obj_data *obj;
|
|
||||||
|
|
||||||
mail_info = OLC_MAIL(d);
|
|
||||||
single_mail = mail_info->mail;
|
|
||||||
|
|
||||||
if (single_mail) {
|
|
||||||
/* Any leftover attachments should be passed back to the owner */
|
|
||||||
while (single_mail->attachment) {
|
|
||||||
obj = single_mail->attachment;
|
|
||||||
obj_from_mail(obj);
|
|
||||||
obj_to_char(obj, d->character);
|
|
||||||
}
|
|
||||||
/* Any leftover gold is returned too */
|
|
||||||
if ((single_mail->coins > 0) && !IS_SET_AR(single_mail->mail_flags, MAIL_COD)) {
|
|
||||||
GET_GOLD(d->character) += single_mail->coins;
|
|
||||||
single_mail->coins = 0;
|
|
||||||
}
|
|
||||||
if (single_mail->subject) free(single_mail->subject);
|
|
||||||
if (single_mail->body) free(single_mail->body);
|
|
||||||
single_mail = NULL;
|
|
||||||
free (mail_info->mail);
|
|
||||||
}
|
|
||||||
clear_recipients(mail_info);
|
|
||||||
mail_info = NULL;
|
|
||||||
free(OLC_MAIL(d));
|
|
||||||
OLC_MAIL(d) = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Menu functions */
|
|
||||||
/* The 'main menu' - displays inbox, with options */
|
|
||||||
void mailedit_disp_menu(struct descriptor_data *d)
|
|
||||||
{
|
|
||||||
get_char_colors(d->character);
|
|
||||||
clear_screen(d);
|
|
||||||
|
|
||||||
write_to_output(d, "tbaMUD Mail Editor\r\n");
|
|
||||||
show_inbox_to_char(d->character);
|
|
||||||
if (CONFIG_DRAFTS_ALLOWED)
|
|
||||||
write_to_output(d, "%s(%sC%s)%s Create %s(%sV%s)%s View %s(%sR%s)%s Reply %s(%sF%s)%s Forward \r\n"
|
|
||||||
"%s(%sE%s)%s Receive %s(%sD%s)%s Delete %s(%sO%s)%s Outbox %s(%sQ%s)%s Quit \r\n",
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm );
|
|
||||||
else
|
|
||||||
write_to_output(d, "%s(%sC%s)%s Create %s(%sV%s)%s View %s(%sR%s)%s Reply %s(%sF%s)%s Forward \r\n"
|
|
||||||
"%s(%sE%s)%s Receive %s(%sD%s)%s Delete %s(%sQ%s)%s Quit \r\n",
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm );
|
|
||||||
write_to_output(d, "Enter Selection: ");
|
|
||||||
|
|
||||||
OLC_MODE(d) = MAILEDIT_INBOX;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mailedit_disp_outbox(struct descriptor_data *d)
|
|
||||||
{
|
|
||||||
get_char_colors(d->character);
|
|
||||||
clear_screen(d);
|
|
||||||
|
|
||||||
write_to_output(d, "tbaMUD Mail Editor\r\n");
|
|
||||||
show_outbox_to_char(d->character);
|
|
||||||
write_to_output(d, "%s(%sE%s)%s Edit %s(%sV%s)%s View %s(%sD%s)%s Delete %s(%sI%s)%s Inbox %s(%sQ%s)%s Quit\r\n",
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm,
|
|
||||||
cyn, yel, cyn, nrm );
|
|
||||||
write_to_output(d, "Enter Selection: ");
|
|
||||||
|
|
||||||
OLC_MODE(d) = MAILEDIT_OUTBOX;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mailedit_disp_mail(struct descriptor_data *d)
|
|
||||||
{
|
|
||||||
char att[15], gold[25];
|
|
||||||
int gold_amt;
|
|
||||||
|
|
||||||
get_char_colors(d->character);
|
|
||||||
clear_screen(d);
|
|
||||||
bool can_attach = TRUE;
|
|
||||||
|
|
||||||
if (count_recipients(OLC_MAIL(d)) > 1) can_attach = FALSE;
|
|
||||||
|
|
||||||
if (attachment_count(OLC_MAIL(d)->mail) > 0)
|
|
||||||
sprintf(att, "%s%d object%s", can_attach ? "@r" : "@y", attachment_count(OLC_MAIL(d)->mail), attachment_count(OLC_MAIL(d)->mail) > 1 ? "s" : "");
|
|
||||||
else
|
|
||||||
sprintf(att, "<None>");
|
|
||||||
|
|
||||||
if (MAILEDIT_GOLD > 0) {
|
|
||||||
sprintf(gold, "%s%s coins", can_attach ? "@r" : "@y", add_commas(MAILEDIT_GOLD));
|
|
||||||
} else {
|
|
||||||
sprintf(gold, "<None>");
|
|
||||||
}
|
|
||||||
|
|
||||||
gold_amt = CONFIG_STAMP_COST + (attachment_count(OLC_MAIL(d)->mail) * CONFIG_OBJECT_COST);
|
|
||||||
|
|
||||||
write_to_output(d, "tbaMUD Mail Editor\r\n");
|
|
||||||
if (GET_LEVEL(d->character) < CONFIG_FREE_MAIL_LEVEL) {
|
|
||||||
write_to_output(d, "Current cost to send this mail: %s%d%s coins\r\n", yel, gold_amt, nrm);
|
|
||||||
} else {
|
|
||||||
write_to_output(d, "Current cost to send this mail: %sFree!%s\r\n", yel, nrm);
|
|
||||||
}
|
|
||||||
write_to_output(d, "%sA%s)%s Recipients : %s%s\r\n"
|
|
||||||
"%sB%s)%s Subject : %s%s\r\n"
|
|
||||||
"%sC%s)%s Urgency : %s%s\r\n"
|
|
||||||
"%sD%s)%s Attachments : %s%s\r\n"
|
|
||||||
"%sE%s)%s Gold : %s%s\r\n"
|
|
||||||
"%sF%s)%s Gold Mode : %s%s\r\n"
|
|
||||||
"%sG%s)%s Body Text : \r\n%s%s\r\n"
|
|
||||||
"%sS%s)%s Send Mail\r\n"
|
|
||||||
"%sX%s)%s Clear Mail data\r\n"
|
|
||||||
"%sQ%s)%s Quit without sending\r\n",
|
|
||||||
yel, cyn, nrm, yel, OLC_MAIL(d)->recipients ? recipient_list(OLC_MAIL(d)) : "<None!>",
|
|
||||||
yel, cyn, nrm, yel, MAILEDIT_SUBJECT == NULL ? "- No Subject -" : MAILEDIT_SUBJECT,
|
|
||||||
yel, cyn, nrm, yel, MAILEDIT_URGENT ? "@RUrgent!" : "Normal",
|
|
||||||
yel, cyn, CONFIG_CAN_MAIL_OBJ ? nrm : gry, CONFIG_CAN_MAIL_OBJ ? yel : gry, att,
|
|
||||||
yel, cyn, CONFIG_CAN_MAIL_GOLD ? nrm : gry, CONFIG_CAN_MAIL_GOLD ? yel : gry, gold,
|
|
||||||
yel, cyn, nrm, yel, MAILEDIT_COD ? "Cash-on-Delivery (COD)" : "Send Gold",
|
|
||||||
yel, cyn, nrm, yel, MAILEDIT_BODYTEXT == NULL ? "No Text" : MAILEDIT_BODYTEXT,
|
|
||||||
yel, cyn, nrm,
|
|
||||||
yel, cyn, nrm,
|
|
||||||
yel, cyn, nrm);
|
|
||||||
|
|
||||||
write_to_output(d, "Enter Selection: ");
|
|
||||||
|
|
||||||
OLC_MODE(d) = MAILEDIT_MAILEDIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mailedit_disp_recipients(struct descriptor_data *d)
|
|
||||||
{
|
|
||||||
get_char_colors(d->character);
|
|
||||||
clear_screen(d);
|
|
||||||
write_to_output(d, "tbaMUD Mail Recipient Editor\r\n");
|
|
||||||
write_to_output(d, "Current Recipient List:\r\n");
|
|
||||||
write_to_output(d, "%s%s%s\r\n", yel, OLC_MAIL(d)->recipients ? recipient_list(OLC_MAIL(d)) : "<None!>", nrm);
|
|
||||||
write_to_output(d, "%sA%s)%s Add a Recipient\r\n"
|
|
||||||
"%sB%s)%s Delete a Recipient\r\n"
|
|
||||||
"%sC%s)%s Clear all Recipients\r\n"
|
|
||||||
"%sQ%s)%s Quit (back to Editor)\r\n",
|
|
||||||
yel, cyn, nrm,
|
|
||||||
yel, cyn, nrm,
|
|
||||||
yel, cyn, nrm,
|
|
||||||
yel, cyn, nrm);
|
|
||||||
write_to_output(d, "Enter Selection: ");
|
|
||||||
|
|
||||||
OLC_MODE(d) = MAILEDIT_RECIP_MENU;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mailedit_disp_attachments(struct descriptor_data *d)
|
|
||||||
{
|
|
||||||
get_char_colors(d->character);
|
|
||||||
clear_screen(d);
|
|
||||||
write_to_output(d, "tbaMUD Mail Attachment Editor\r\n");
|
|
||||||
write_to_output(d, "Current Attached Objects:\r\n");
|
|
||||||
list_obj_to_char((OLC_MAIL(d)->mail)->attachment, d->character, 1, TRUE);
|
|
||||||
write_to_output(d, "\r\n");
|
|
||||||
write_to_output(d, "%sA%s)%s Add an Object\r\n"
|
|
||||||
"%sB%s)%s Remove an Object\r\n"
|
|
||||||
"%sC%s)%s Remove all Objects\r\n"
|
|
||||||
"%sQ%s)%s Quit (back to Editor)\r\n",
|
|
||||||
yel, cyn, nrm,
|
|
||||||
yel, cyn, nrm,
|
|
||||||
yel, cyn, nrm,
|
|
||||||
yel, cyn, nrm);
|
|
||||||
write_to_output(d, "Enter Selection: ");
|
|
||||||
|
|
||||||
OLC_MODE(d) = MAILEDIT_ATTACH_MENU;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mailedit_parse(struct descriptor_data *d, char *arg)
|
|
||||||
{
|
|
||||||
int i, num;
|
|
||||||
long mail_id, diff, gold;
|
|
||||||
struct mail_data *ml;
|
|
||||||
struct obj_data *obj;
|
|
||||||
char *oldtext = NULL;
|
|
||||||
|
|
||||||
switch (OLC_MODE(d)) {
|
|
||||||
case MAILEDIT_ASK_DRAFT:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'y':
|
|
||||||
case 'Y':
|
|
||||||
/* Save the mail as a draft. */
|
|
||||||
save_as_draft(d->character, OLC_MAIL(d)->mail);
|
|
||||||
clear_mail_data(OLC_MAIL(d)->mail);
|
|
||||||
mailedit_disp_outbox(d);
|
|
||||||
return;
|
|
||||||
case 'n':
|
|
||||||
case 'N':
|
|
||||||
clear_mail_data(OLC_MAIL(d)->mail);
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
write_to_output(d, "Invalid choice!\r\n");
|
|
||||||
write_to_output(d, "Do you wish to save this mail as a draft? (Y/N): ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_ASK_QUIT:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'y':
|
|
||||||
case 'Y':
|
|
||||||
clear_mail_data(OLC_MAIL(d)->mail);
|
|
||||||
mailedit_disp_outbox(d);
|
|
||||||
return;
|
|
||||||
case 'n':
|
|
||||||
case 'N':
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
write_to_output(d, "Invalid choice!\r\n");
|
|
||||||
write_to_output(d, "Do you wish to quit and lose your changes? (Y/N): ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_INBOX:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'q':
|
|
||||||
case 'Q':
|
|
||||||
if (count_deleted(d->character) > 0) {
|
|
||||||
|
|
||||||
write_to_output(d, "You have mail marked for deletion.\r\n");
|
|
||||||
write_to_output(d, "Do you wish to purge all marked mails now? (Y/N)\r\n");
|
|
||||||
OLC_MODE(d) = MAILEDIT_PURGE_N_QUIT;
|
|
||||||
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_MAILING);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
REMOVE_BIT_AR(PLR_FLAGS(d->character), PLR_MAILING);
|
|
||||||
cleanup_olc(d, CLEANUP_ALL);
|
|
||||||
return;
|
|
||||||
case 'c':
|
|
||||||
case 'C':
|
|
||||||
if ((GET_LEVEL(d->character) < CONFIG_FREE_MAIL_LEVEL) && (GET_GOLD(d->character) < CONFIG_STAMP_COST)) {
|
|
||||||
write_to_output(d, "Mails cost %d coins, and you can't afford that!\r\n", CONFIG_STAMP_COST);
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
clear_mail_data(OLC_MAIL(d)->mail);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
case 'V':
|
|
||||||
write_to_output(d, "Which mail do you wish to view? : ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_VIEW;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
case 'R':
|
|
||||||
if ((GET_LEVEL(d->character) < CONFIG_FREE_MAIL_LEVEL) && (GET_GOLD(d->character) < CONFIG_STAMP_COST)) {
|
|
||||||
write_to_output(d, "Mails cost %d coins, and you can't afford that!\r\n", CONFIG_STAMP_COST);
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
write_to_output(d, "Which mail do you wish to reply to? : ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_REPLY;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
if ((GET_LEVEL(d->character) < CONFIG_FREE_MAIL_LEVEL) && (GET_GOLD(d->character) < CONFIG_STAMP_COST)) {
|
|
||||||
write_to_output(d, "Mails cost %d coins, and you can't afford that!\r\n", CONFIG_STAMP_COST);
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
write_to_output(d, "Which mail do you wish to forward? : ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_FORWARD;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
write_to_output(d, "Which mail do you wish to delete? : ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_DELETE;
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
write_to_output(d, "Which mail do you wish to receive? : ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_RECEIVE;
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
case 'O':
|
|
||||||
mailedit_disp_outbox(d);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
write_to_output(d, "Invalid Choice!\r\nEnter Selection : ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_OUTBOX:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'q':
|
|
||||||
case 'Q':
|
|
||||||
cleanup_olc(d, CLEANUP_ALL);
|
|
||||||
return;
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
if ((GET_LEVEL(d->character) < CONFIG_FREE_MAIL_LEVEL) && (GET_GOLD(d->character) < CONFIG_STAMP_COST)) {
|
|
||||||
write_to_output(d, "Mails cost %d coins, and you can't afford that!\r\n", CONFIG_STAMP_COST);
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
write_to_output(d, "Which mail do you wish to edit? : ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_OUTEDIT;
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
case 'V':
|
|
||||||
write_to_output(d, "Which mail do you wish to view? : ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_OUTVIEW;
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
case 'I':
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
write_to_output(d, "Which mail do you wish to delete? : ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_OUTDELETE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
write_to_output(d, "Invalid Choice!\r\nEnter Selection : ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_VIEW:
|
|
||||||
num = atoi(arg);
|
|
||||||
if (num == 0) {
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_id = get_id_by_inbox_num(d->character, num);
|
|
||||||
if (mail_id == NO_MAIL) {
|
|
||||||
write_to_output(d, "Invalid mail number.\r\n");
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_view(d->character, mail_id);
|
|
||||||
write_to_output(d, "-- Press Enter to Continue! --\r\n");
|
|
||||||
OLC_MODE(d) = MAILEDIT_BACK_TO_MENU;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_REPLY:
|
|
||||||
num = atoi(arg);
|
|
||||||
if (num == 0) {
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_id = get_id_by_inbox_num(d->character, num);
|
|
||||||
if (mail_id == NO_MAIL) {
|
|
||||||
write_to_output(d, "Invalid mail number.\r\n");
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((ml = create_mail()) != NULL) {
|
|
||||||
load_mail(mail_id, ml);
|
|
||||||
copy_mail(OLC_MAIL(d)->mail, ml, MAIL_COPY_REPLY);
|
|
||||||
for (i=0; i<ML_ARRAY_MAX; i++)
|
|
||||||
ml->mail_flags[i] = 0;
|
|
||||||
(OLC_MAIL(d)->mail)->mail_id = NO_MAIL;
|
|
||||||
(OLC_MAIL(d)->mail)->sender = GET_ID(d->character);
|
|
||||||
add_recipient(OLC_MAIL(d), ml->sender);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_FORWARD:
|
|
||||||
num = atoi(arg);
|
|
||||||
if (num == 0) {
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_id = get_id_by_inbox_num(d->character, num);
|
|
||||||
if (mail_id == NO_MAIL) {
|
|
||||||
write_to_output(d, "Invalid mail number.\r\n");
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((ml = create_mail()) != NULL) {
|
|
||||||
load_mail(mail_id, ml);
|
|
||||||
copy_mail(OLC_MAIL(d)->mail, ml, MAIL_COPY_FORWARD);
|
|
||||||
for (i=0; i<ML_ARRAY_MAX; i++)
|
|
||||||
ml->mail_flags[i] = 0;
|
|
||||||
(OLC_MAIL(d)->mail)->mail_id = NO_MAIL;
|
|
||||||
(OLC_MAIL(d)->mail)->sender = GET_ID(d->character);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_DELETE:
|
|
||||||
num = atoi(arg);
|
|
||||||
if (num == 0) {
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_id = get_id_by_inbox_num(d->character, num);
|
|
||||||
if (mail_id == NO_MAIL) {
|
|
||||||
write_to_output(d, "Invalid mail number.\r\n");
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_delmark(d->character, mail_id);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_RECEIVE:
|
|
||||||
num = atoi(arg);
|
|
||||||
if (num == 0) {
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_id = get_id_by_inbox_num(d->character, num);
|
|
||||||
if (mail_id == NO_MAIL) {
|
|
||||||
write_to_output(d, "Invalid mail number.\r\n");
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mail_receive(d->character, mail_id))
|
|
||||||
write_to_output(d, "Mail received into your inventory.\r\n");
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_OUTEDIT:
|
|
||||||
num = atoi(arg);
|
|
||||||
if (num == 0) {
|
|
||||||
mailedit_disp_outbox(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_id = get_id_by_outbox_num(d->character, num);
|
|
||||||
if (mail_id == NO_MAIL) {
|
|
||||||
write_to_output(d, "Invalid mail number.\r\n");
|
|
||||||
mailedit_disp_outbox(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((ml = create_mail()) != NULL) {
|
|
||||||
load_mail(mail_id, ml);
|
|
||||||
copy_mail(OLC_MAIL(d)->mail, ml, MAIL_COPY_NORMAL);
|
|
||||||
(OLC_MAIL(d)->mail)->sender = GET_ID(d->character);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_OUTVIEW:
|
|
||||||
num = atoi(arg);
|
|
||||||
if (num == 0) {
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_id = get_id_by_outbox_num(d->character, num);
|
|
||||||
if (mail_id == NO_MAIL) {
|
|
||||||
write_to_output(d, "Invalid mail number.\r\n");
|
|
||||||
mailedit_disp_outbox(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_view(d->character, mail_id);
|
|
||||||
write_to_output(d, "-- Press Enter to Continue! --\r\n");
|
|
||||||
OLC_MODE(d) = MAILEDIT_BACK_TO_MENU;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_OUTDELETE:
|
|
||||||
num = atoi(arg);
|
|
||||||
if (num == 0) {
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_id = get_id_by_outbox_num(d->character, num);
|
|
||||||
if (mail_id == NO_MAIL) {
|
|
||||||
write_to_output(d, "Invalid mail number.\r\n");
|
|
||||||
mailedit_disp_outbox(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mail_delmark(d->character, mail_id);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_BACK_TO_MENU:
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_RECIP_MENU:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'a':
|
|
||||||
case 'A':
|
|
||||||
/* Mail with attachments can only have one recipient */
|
|
||||||
if (count_recipients(OLC_MAIL(d)) > 0) {
|
|
||||||
if (((OLC_MAIL(d)->mail)->attachment) || ((OLC_MAIL(d)->mail)->coins > 0 && !IS_SET_AR((OLC_MAIL(d)->mail)->mail_flags, MAIL_COD))) {
|
|
||||||
write_to_output(d, "Sorry, mail with attachments cannot be sent to more than one person!\r\n");
|
|
||||||
mailedit_disp_recipients(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write_to_output(d, "Enter a player name to add: ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_ADD_RECIP;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
case 'B':
|
|
||||||
write_to_output(d, "Enter a player name to remove: ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_DEL_RECIP;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
case 'C':
|
|
||||||
write_to_output(d, "Are you sure you wish to remove ALL recipients? (Y/N): ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_CLR_RECIP;
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
case 'Q':
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_ADD_RECIP:
|
|
||||||
/* check 'special cases' (mail groups) */
|
|
||||||
if ((mail_id = get_mail_group_by_name(arg)) == MAIL_TO_NOBODY) {
|
|
||||||
if ((mail_id = get_id_by_name(arg)) < 0 || !mail_recip_ok(arg)) {
|
|
||||||
write_to_output(d, "No one by that name is registered here!\r\n");
|
|
||||||
mailedit_disp_recipients(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mail_id == MAIL_TO_ALL && GET_LEVEL(d->character) < CONFIG_MIN_SEND_TO_ALL) {
|
|
||||||
write_to_output(d, "Sorry, you don't have sufficient access to send to 'all'\r\n");
|
|
||||||
mailedit_disp_recipients(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
add_recipient(OLC_MAIL(d), mail_id);
|
|
||||||
mailedit_disp_recipients(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_DEL_RECIP:
|
|
||||||
if ((mail_id = get_id_by_name(arg)) < 0 || !mail_recip_ok(arg)) {
|
|
||||||
write_to_output(d, "No one by that name is registered here!\r\n");
|
|
||||||
mailedit_disp_recipients(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
remove_recipient(OLC_MAIL(d), mail_id);
|
|
||||||
mailedit_disp_recipients(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_CLR_RECIP:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'y':
|
|
||||||
case 'Y':
|
|
||||||
clear_recipients(OLC_MAIL(d));
|
|
||||||
mailedit_disp_recipients(d);
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
case 'N':
|
|
||||||
mailedit_disp_recipients(d);
|
|
||||||
break;
|
|
||||||
default : write_to_output(d, "Invalid choice!\r\nAre you sure you wish to remove ALL recipients? (Y/N): ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_ATTACH_MENU:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'a':
|
|
||||||
case 'A':
|
|
||||||
/* Mail with attachments can only have one recipient */
|
|
||||||
if (count_recipients(OLC_MAIL(d)) > 1) {
|
|
||||||
write_to_output(d, "Sorry, mail with multiple recipients cannot have attachments!\r\n");
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ((d->character)->carrying == NULL) {
|
|
||||||
write_to_output(d, "Your inventory seems to be empty - you cannot attach anything.\r\n");
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
list_attachments_numbered((d->character)->carrying, d->character);
|
|
||||||
write_to_output(d, "Enter a object to add: ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_ADD_ATTACH;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
case 'B':
|
|
||||||
if ((OLC_MAIL(d)->mail)->attachment == NULL) {
|
|
||||||
write_to_output(d, "There are no attachments - you cannot remove anything.\r\n");
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
list_attachments_numbered((OLC_MAIL(d)->mail)->attachment, d->character);
|
|
||||||
write_to_output(d, "Enter an object to remove: ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_DEL_ATTACH;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
case 'C':
|
|
||||||
write_to_output(d, "Are you sure you wish to remove ALL objects? (Y/N): ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_CLR_ATTACH;
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
case 'Q':
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_ADD_ATTACH:
|
|
||||||
num = atoi(arg);
|
|
||||||
if ((obj = get_attachment_numbered(d->character, (d->character)->carrying, num)) == NULL) {
|
|
||||||
write_to_output(d, "That object number is not in your inventory\r\n");
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
obj_from_char(obj);
|
|
||||||
obj_to_mail(obj, OLC_MAIL(d)->mail);
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_DEL_ATTACH:
|
|
||||||
num = atoi(arg);
|
|
||||||
if ((obj = get_attachment_numbered(d->character, (OLC_MAIL(d)->mail)->attachment, num)) == NULL) {
|
|
||||||
write_to_output(d, "That object number is not attached.\r\n");
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
obj_from_mail(obj);
|
|
||||||
obj_to_char(obj, d->character);
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_CLR_ATTACH:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'y':
|
|
||||||
case 'Y':
|
|
||||||
while ((OLC_MAIL(d)->mail)->attachment) {
|
|
||||||
obj = (OLC_MAIL(d)->mail)->attachment;
|
|
||||||
obj_from_mail(obj);
|
|
||||||
obj_to_char(obj, d->character);
|
|
||||||
}
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
case 'N':
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
break;
|
|
||||||
default : write_to_output(d, "Invalid choice!\r\nAre you sure you wish to remove ALL attachments? (Y/N): ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_GET_GOLD:
|
|
||||||
gold = atol(arg);
|
|
||||||
diff = (gold - (OLC_MAIL(d)->mail)->coins);
|
|
||||||
if (diff > GET_GOLD(d->character)) {
|
|
||||||
write_to_output(d, "@RYou don't have that much gold!@n\r\n");
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GET_GOLD(d->character) -= diff;
|
|
||||||
(OLC_MAIL(d)->mail)->coins = gold;
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_GET_SUBJECT:
|
|
||||||
if ((OLC_MAIL(d)->mail)->subject)
|
|
||||||
free ((OLC_MAIL(d)->mail)->subject);
|
|
||||||
(OLC_MAIL(d)->mail)->subject = strdup(arg);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_MAILEDIT:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'q':
|
|
||||||
case 'Q':
|
|
||||||
if (CONFIG_DRAFTS_ALLOWED) {
|
|
||||||
write_to_output(d, "Do you wish to save this mail as a draft? (Y/N): ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_ASK_DRAFT;
|
|
||||||
} else {
|
|
||||||
write_to_output(d, "Do you wish to quit and lose your changes? (Y/N): ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_ASK_QUIT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
case 'A':
|
|
||||||
mailedit_disp_recipients(d);
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
case 'B':
|
|
||||||
write_to_output(d, "Enter a subject for this mail: ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_GET_SUBJECT;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
case 'C':
|
|
||||||
TOGGLE_BIT_AR((OLC_MAIL(d)->mail)->mail_flags, MAIL_URGENT);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
if (CONFIG_CAN_MAIL_OBJ) {
|
|
||||||
mailedit_disp_attachments(d);
|
|
||||||
} else {
|
|
||||||
write_to_output(d, "@RSorry, object attachments are disabled!@n\r\n");
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
if (CONFIG_CAN_MAIL_GOLD) {
|
|
||||||
write_to_output(d, "Enter a number of gold coins: ");
|
|
||||||
OLC_MODE(d) = MAILEDIT_GET_GOLD;
|
|
||||||
} else {
|
|
||||||
write_to_output(d, "@RSorry, gold attachments are disabled!@n\r\n");
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
/* Flicking between COD and 'send money', we need to give/take gold from the player */
|
|
||||||
if (IS_SET_AR((OLC_MAIL(d)->mail)->mail_flags, MAIL_COD) && ((OLC_MAIL(d)->mail)->coins > 0)) {
|
|
||||||
diff = (OLC_MAIL(d)->mail)->coins;
|
|
||||||
if (diff > GET_GOLD(d->character)) {
|
|
||||||
write_to_output(d, "@RYou don't have enough gold to do that!@n\r\n");
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
GET_GOLD(d->character) -= diff;
|
|
||||||
} else if (!IS_SET_AR((OLC_MAIL(d)->mail)->mail_flags, MAIL_COD) && ((OLC_MAIL(d)->mail)->coins > 0)) {
|
|
||||||
diff = (OLC_MAIL(d)->mail)->coins;
|
|
||||||
GET_GOLD(d->character) += diff;
|
|
||||||
}
|
|
||||||
TOGGLE_BIT_AR((OLC_MAIL(d)->mail)->mail_flags, MAIL_COD);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
case 'G':
|
|
||||||
OLC_MODE(d) = MAILEDIT_GET_BODYTEXT;
|
|
||||||
send_editor_help(d);
|
|
||||||
write_to_output(d, "Enter the main body text for this mail:\r\n\r\n");
|
|
||||||
if ((OLC_MAIL(d)->mail)->body) {
|
|
||||||
write_to_output(d, "%s", (OLC_MAIL(d)->mail)->body);
|
|
||||||
oldtext = strdup((OLC_MAIL(d)->mail)->body);
|
|
||||||
}
|
|
||||||
string_write(d, &(OLC_MAIL(d)->mail)->body, MAX_MAIL_SIZE, 0, oldtext);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
case 'S':
|
|
||||||
if (GET_LEVEL(d->character) < CONFIG_FREE_MAIL_LEVEL) {
|
|
||||||
gold = CONFIG_STAMP_COST + (attachment_count(OLC_MAIL(d)->mail) * CONFIG_OBJECT_COST);
|
|
||||||
} else {
|
|
||||||
gold = 0;
|
|
||||||
}
|
|
||||||
if (gold > 0 && GET_GOLD(d->character) < gold ) {
|
|
||||||
write_to_output(d, "This mail costs %ld coins, and you can't afford that!\r\n", gold );
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(OLC_MAIL(d)->mail)->sender = GET_ID(d->character);
|
|
||||||
if (perform_send_edited(d->character, OLC_MAIL(d)) == FALSE) {
|
|
||||||
write_to_output(d, "@RERROR: Unable to send Mail: Please tell an Imm!@n\r\n");
|
|
||||||
/* Sending failed - return to editor, so they can choose to save as draft */
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Sending was successful - clean up */
|
|
||||||
if (gold) GET_GOLD(d->character) -= gold;
|
|
||||||
clear_mail_data(OLC_MAIL(d)->mail);
|
|
||||||
clear_recipients(OLC_MAIL(d));
|
|
||||||
write_to_output(d, "Sending of mail successful! Press Enter to continue.\r\n");
|
|
||||||
OLC_MODE(d) = MAILEDIT_BACK_TO_MENU;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
clear_mail_data(OLC_MAIL(d)->mail);
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
write_to_output(d, "Invalid Choice!\r\nEnter Selection : ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAILEDIT_PURGE_N_QUIT:
|
|
||||||
switch (*arg) {
|
|
||||||
case 'y':
|
|
||||||
case 'Y':
|
|
||||||
num = purge_marked_mail(d->character);
|
|
||||||
if (num > 0) {
|
|
||||||
write_to_output(d, "%d deleted mail%s ha%s been purged.", num, num == 1 ? "" : "s", num == 1 ? "s" : "ve");
|
|
||||||
}
|
|
||||||
cleanup_olc(d, CLEANUP_ALL);
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
case 'N':
|
|
||||||
cleanup_olc(d, CLEANUP_ALL);
|
|
||||||
break;
|
|
||||||
default : write_to_output(d, "Invalid choice!\r\nDo you wish to purge all marked mails now? (Y/N): ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
write_to_output(d, "Sorry - There appears to be a problem, returning to inbox.\r\n");
|
|
||||||
log("SYSERR: mailedit: Invalid submode (%d)", OLC_MODE(d));
|
|
||||||
mailedit_disp_menu(d);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mailedit_string_cleanup(struct descriptor_data *d, int terminator)
|
|
||||||
{
|
|
||||||
switch (OLC_MODE(d)) {
|
|
||||||
case MAILEDIT_GET_BODYTEXT:
|
|
||||||
mailedit_disp_mail(d);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
2078
src/protocol.c
2078
src/protocol.c
File diff suppressed because it is too large
Load diff
453
src/protocol.h
453
src/protocol.h
|
@ -1,453 +0,0 @@
|
||||||
/**************************************************************************
|
|
||||||
* File: protocol.h Part of tbaMUD *
|
|
||||||
* Usage: MXP, MSDP, ATCP, NAWS, TTYPE, CHARSET, 256-Colors *
|
|
||||||
* Author: KaVir *
|
|
||||||
* *
|
|
||||||
* All rights reserved. See license.doc for complete information. *
|
|
||||||
* *
|
|
||||||
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef PROTOCOL_H
|
|
||||||
#define PROTOCOL_H
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
Set your MUD_NAME, and change descriptor_t if necessary.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#define MUD_NAME "Unknown MUD"
|
|
||||||
|
|
||||||
typedef struct descriptor_data descriptor_t;
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
Symbolic constants.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#define PROTOCOL_BUFFER 2048
|
|
||||||
#define MAX_OUTPUT_BUFFER 8192
|
|
||||||
|
|
||||||
#define TELOPT_SEND 1
|
|
||||||
#define TELOPT_ACCEPTED 2
|
|
||||||
#define TELOPT_REJECTED 3
|
|
||||||
|
|
||||||
#define TELOPT_TTYPE 24
|
|
||||||
#define TELOPT_NAWS 31
|
|
||||||
#define TELOPT_CHARSET 42
|
|
||||||
#define TELOPT_MSDP 69
|
|
||||||
#define TELOPT_MSSP 70
|
|
||||||
#define TELOPT_MCCP 86 /* This is MCCP version 2 */
|
|
||||||
#define TELOPT_MSP 90
|
|
||||||
#define TELOPT_MXP 91
|
|
||||||
#define TELOPT_ATCP 200
|
|
||||||
|
|
||||||
#define MSDP_VAR 1
|
|
||||||
#define MSDP_VAL 2
|
|
||||||
#define MAX_MSDP_SIZE 100
|
|
||||||
|
|
||||||
#define MSSP_VAR 1
|
|
||||||
#define MSSP_VAL 2
|
|
||||||
|
|
||||||
#define UNICODE_MALE 9794
|
|
||||||
#define UNICODE_FEMALE 9792
|
|
||||||
#define UNICODE_NEUTER 9791
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
Types.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
false,
|
|
||||||
true
|
|
||||||
} bool_t;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
eUNKNOWN,
|
|
||||||
eNO,
|
|
||||||
eSOMETIMES,
|
|
||||||
eYES
|
|
||||||
} support_t;
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
eMSDP_NONE = -1, /* This must always be first. */
|
|
||||||
|
|
||||||
/* General */
|
|
||||||
eMSDP_CHARACTER_NAME,
|
|
||||||
eMSDP_SERVER_ID,
|
|
||||||
eMSDP_SERVER_TIME,
|
|
||||||
|
|
||||||
/* Character */
|
|
||||||
eMSDP_AFFECTS,
|
|
||||||
eMSDP_ALIGNMENT,
|
|
||||||
eMSDP_EXPERIENCE,
|
|
||||||
eMSDP_EXPERIENCE_MAX,
|
|
||||||
eMSDP_EXPERIENCE_TNL,
|
|
||||||
eMSDP_HEALTH,
|
|
||||||
eMSDP_HEALTH_MAX,
|
|
||||||
eMSDP_LEVEL,
|
|
||||||
eMSDP_RACE,
|
|
||||||
eMSDP_CLASS,
|
|
||||||
eMSDP_MANA,
|
|
||||||
eMSDP_MANA_MAX,
|
|
||||||
eMSDP_WIMPY,
|
|
||||||
eMSDP_PRACTICE,
|
|
||||||
eMSDP_MONEY,
|
|
||||||
eMSDP_MOVEMENT,
|
|
||||||
eMSDP_MOVEMENT_MAX,
|
|
||||||
eMSDP_HITROLL,
|
|
||||||
eMSDP_DAMROLL,
|
|
||||||
eMSDP_AC,
|
|
||||||
eMSDP_STR,
|
|
||||||
eMSDP_INT,
|
|
||||||
eMSDP_WIS,
|
|
||||||
eMSDP_DEX,
|
|
||||||
eMSDP_CON,
|
|
||||||
eMSDP_STR_PERM,
|
|
||||||
eMSDP_INT_PERM,
|
|
||||||
eMSDP_WIS_PERM,
|
|
||||||
eMSDP_DEX_PERM,
|
|
||||||
eMSDP_CON_PERM,
|
|
||||||
|
|
||||||
/* Combat */
|
|
||||||
eMSDP_OPPONENT_HEALTH,
|
|
||||||
eMSDP_OPPONENT_HEALTH_MAX,
|
|
||||||
eMSDP_OPPONENT_LEVEL,
|
|
||||||
eMSDP_OPPONENT_NAME,
|
|
||||||
|
|
||||||
/* World */
|
|
||||||
eMSDP_AREA_NAME,
|
|
||||||
eMSDP_ROOM_EXITS,
|
|
||||||
eMSDP_ROOM_NAME,
|
|
||||||
eMSDP_ROOM_VNUM,
|
|
||||||
eMSDP_WORLD_TIME,
|
|
||||||
|
|
||||||
/* Configuration */
|
|
||||||
eMSDP_CLIENT_ID,
|
|
||||||
eMSDP_CLIENT_VERSION,
|
|
||||||
eMSDP_PLUGIN_ID,
|
|
||||||
eMSDP_ANSI_COLORS,
|
|
||||||
eMSDP_XTERM_256_COLORS,
|
|
||||||
eMSDP_UTF_8,
|
|
||||||
eMSDP_SOUND,
|
|
||||||
eMSDP_MXP,
|
|
||||||
|
|
||||||
/* GUI variables */
|
|
||||||
eMSDP_BUTTON_1,
|
|
||||||
eMSDP_BUTTON_2,
|
|
||||||
eMSDP_BUTTON_3,
|
|
||||||
eMSDP_BUTTON_4,
|
|
||||||
eMSDP_BUTTON_5,
|
|
||||||
eMSDP_GAUGE_1,
|
|
||||||
eMSDP_GAUGE_2,
|
|
||||||
eMSDP_GAUGE_3,
|
|
||||||
eMSDP_GAUGE_4,
|
|
||||||
eMSDP_GAUGE_5,
|
|
||||||
|
|
||||||
eMSDP_MAX /* This must always be last */
|
|
||||||
} variable_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
variable_t Variable; /* The enum type of this variable */
|
|
||||||
char *pName; /* The string name of this variable */
|
|
||||||
bool_t bString; /* Is this variable a string or a number? */
|
|
||||||
bool_t bConfigurable; /* Can it be configured by the client? */
|
|
||||||
bool_t bWriteOnce; /* Can only set this variable once */
|
|
||||||
bool_t bGUI; /* It's a special GUI configuration variable */
|
|
||||||
int Min; /* The minimum valid value or string length */
|
|
||||||
int Max; /* The maximum valid value or string length */
|
|
||||||
int Default; /* The default value for a number */
|
|
||||||
const char *pDefault; /* The default value for a string */
|
|
||||||
} variable_name_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
bool_t bReport; /* Is this variable being reported? */
|
|
||||||
bool_t bDirty; /* Does this variable need to be sent again? */
|
|
||||||
int ValueInt; /* The numeric value of the variable */
|
|
||||||
char *pValueString; /* The string value of the variable */
|
|
||||||
} MSDP_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
const char *pName; /* The name of the MSSP variable */
|
|
||||||
const char *pValue; /* The value of the MSSP variable */
|
|
||||||
} MSSP_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int WriteOOB; /* Used internally to indicate OOB data */
|
|
||||||
bool_t bNegotiated; /* Indicates client successfully negotiated */
|
|
||||||
bool_t bBlockMXP; /* Used internally based on MXP version */
|
|
||||||
bool_t bTTYPE; /* The client supports TTYPE */
|
|
||||||
bool_t bNAWS; /* The client supports NAWS */
|
|
||||||
bool_t bCHARSET; /* The client supports CHARSET */
|
|
||||||
bool_t bMSDP; /* The client supports MSDP */
|
|
||||||
bool_t bATCP; /* The client supports ATCP */
|
|
||||||
bool_t bMSP; /* The client supports MSP */
|
|
||||||
bool_t bMXP; /* The client supports MXP */
|
|
||||||
support_t b256Support; /* The client supports XTerm 256 colors */
|
|
||||||
int ScreenWidth; /* The client's screen width */
|
|
||||||
int ScreenHeight; /* The client's screen height */
|
|
||||||
char *pMXPVersion; /* The version of MXP supported */
|
|
||||||
char *pLastTTYPE; /* Used for the cyclic TTYPE check */
|
|
||||||
MSDP_t **pVariables; /* The MSDP variables */
|
|
||||||
} protocol_t;
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
Protocol functions.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Function: ProtocolCreate
|
|
||||||
*
|
|
||||||
* Creates, initialises and returns a structure containing protocol data for a
|
|
||||||
* single user. This should be called when the descriptor is initialised.
|
|
||||||
*/
|
|
||||||
protocol_t *ProtocolCreate( void );
|
|
||||||
|
|
||||||
/* Function: ProtocolDestroy
|
|
||||||
*
|
|
||||||
* Frees the memory allocated by the specified structure. This should be
|
|
||||||
* called just before a descriptor is freed.
|
|
||||||
*/
|
|
||||||
void ProtocolDestroy( protocol_t *apProtocol );
|
|
||||||
|
|
||||||
/* Function: ProtocolNegotiate
|
|
||||||
*
|
|
||||||
* Negatiates with the client to see which protocols the user supports, and
|
|
||||||
* stores the results in the user's protocol structure. Call this when you
|
|
||||||
* wish to perform negotiation (but only call it once). It is usually called
|
|
||||||
* either immediately after the user has connected, or just after they have
|
|
||||||
* entered the game.
|
|
||||||
*/
|
|
||||||
void ProtocolNegotiate( descriptor_t *apDescriptor );
|
|
||||||
|
|
||||||
/* Function: ProtocolInput
|
|
||||||
*
|
|
||||||
* Extracts any negotiation sequences from the input buffer, and passes back
|
|
||||||
* whatever is left for the mud to parse normally. Call this after data has
|
|
||||||
* been read into the input buffer, before it is used for anything else.
|
|
||||||
*/
|
|
||||||
void ProtocolInput( descriptor_t *apDescriptor, char *apData, int aSize, char *apOut );
|
|
||||||
|
|
||||||
/* Function: ProtocolOutput
|
|
||||||
*
|
|
||||||
* This function takes a string, applies colour codes to it, and returns the
|
|
||||||
* result. It should be called just before writing to the output buffer.
|
|
||||||
*
|
|
||||||
* The special character used to indicate the start of a colour sequence is
|
|
||||||
* '\t' (i.e., a tab, or ASCII character 9). This makes it easy to include
|
|
||||||
* in help files (as you can literally press the tab key) as well as strings
|
|
||||||
* (where you can use \t instead). However players can't send tabs (on most
|
|
||||||
* muds at least), so this stops them from sending colour codes to each other.
|
|
||||||
*
|
|
||||||
* The predefined colours are:
|
|
||||||
*
|
|
||||||
* n: no colour (switches colour off)
|
|
||||||
* r: dark red R: bright red
|
|
||||||
* g: dark green G: bright green
|
|
||||||
* b: dark blue B: bright blue
|
|
||||||
* y: dark yellow Y: bright yellow
|
|
||||||
* m: dark magenta M: bright magenta
|
|
||||||
* c: dark cyan C: bright cyan
|
|
||||||
* w: dark white W: bright white
|
|
||||||
* o: dark orange O: bright orange
|
|
||||||
*
|
|
||||||
* So for example "This is \tOorange\tn." will colour the word "orange". You
|
|
||||||
* can add more colours yourself just by updating the switch statement.
|
|
||||||
*
|
|
||||||
* It's also possible to explicitly specify an RGB value, by including the four
|
|
||||||
* character colour sequence (as used by ColourRGB) within square brackets, eg:
|
|
||||||
*
|
|
||||||
* This is a \t[F010]very dark green foreground\tn.
|
|
||||||
*
|
|
||||||
* The square brackets can also be used to send unicode characters, like this:
|
|
||||||
*
|
|
||||||
* Boat: \t[U9973/B]
|
|
||||||
* Rook: \t[U9814/C]
|
|
||||||
*
|
|
||||||
* For example you might use 'B' to represent a boat on your ASCII map, or a 'C'
|
|
||||||
* to represent a castle - but players with UTF-8 support would actually see the
|
|
||||||
* appropriate unicode characters for a boat or a rook (the chess playing piece).
|
|
||||||
*
|
|
||||||
* The exact syntax is '\t' (tab), '[', 'U' (indicating unicode), then the decimal
|
|
||||||
* number of the unicode character (see http://www.unicode.org/charts), then '/'
|
|
||||||
* followed by the ASCII character/s that should be used if the client doesn't
|
|
||||||
* support UTF-8. The ASCII sequence can be up to 7 characters in length, but in
|
|
||||||
* most cases you'll only want it to be one or two characters (so that it has the
|
|
||||||
* same alignment as the unicode character).
|
|
||||||
*
|
|
||||||
* Finally, this function also allows you to embed MXP tags. The easiest and
|
|
||||||
* safest way to do this is via the ( and ) bracket options:
|
|
||||||
*
|
|
||||||
* From here, you can walk \t(north\t).
|
|
||||||
*
|
|
||||||
* However it's also possible to include more explicit MSP tags, like this:
|
|
||||||
*
|
|
||||||
* The baker offers to sell you a \t<send href="buy pie">pie\t</send>.
|
|
||||||
*
|
|
||||||
* Note that the MXP tags will automatically be removed if the user doesn't
|
|
||||||
* support MXP, but it's very important you remember to close the tags.
|
|
||||||
*/
|
|
||||||
const char *ProtocolOutput( descriptor_t *apDescriptor, const char *apData, int *apLength );
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
Copyover save/load functions.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Function: CopyoverGet
|
|
||||||
*
|
|
||||||
* Returns the protocol values stored as a short string. If your mud uses
|
|
||||||
* copyover, you should call this for each player and insert it after their
|
|
||||||
* name in the temporary text file.
|
|
||||||
*/
|
|
||||||
const char *CopyoverGet( descriptor_t *apDescriptor );
|
|
||||||
|
|
||||||
/* Function: CopyoverSet
|
|
||||||
*
|
|
||||||
* Call this function for each player after a copyover, passing in the string
|
|
||||||
* you added to the temporary text file. This will restore their protocol
|
|
||||||
* settings, and automatically renegotiate MSDP/ATCP.
|
|
||||||
*
|
|
||||||
* Note that the client doesn't recognise a copyover, and therefore refuses to
|
|
||||||
* renegotiate certain telnet options (to avoid loops), so they really need to
|
|
||||||
* be saved. However MSDP/ATCP is handled through scripts, and we don't want
|
|
||||||
* to have to save all of the REPORT variables, so it's easier to renegotiate.
|
|
||||||
*
|
|
||||||
* Client name and version are not saved. It is recommended you save these in
|
|
||||||
* the player file, as then you can grep to collect client usage stats.
|
|
||||||
*/
|
|
||||||
void CopyoverSet( descriptor_t *apDescriptor, const char *apData );
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
MSDP functions.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Function: MSDPUpdate
|
|
||||||
*
|
|
||||||
* Call this regularly (I'd suggest at least once per second) to flush every
|
|
||||||
* dirty MSDP variable that has been requested by the client via REPORT. This
|
|
||||||
* will automatically use ATCP instead if MSDP is not supported by the client.
|
|
||||||
*/
|
|
||||||
void MSDPUpdate( descriptor_t *apDescriptor );
|
|
||||||
|
|
||||||
/* Function: MSDPSend
|
|
||||||
*
|
|
||||||
* Send the specified MSDP variable to the player. You shouldn't ever really
|
|
||||||
* need to do this manually, except perhaps when debugging something. This
|
|
||||||
* will automatically use ATCP instead if MSDP is not supported by the client.
|
|
||||||
*/
|
|
||||||
void MSDPSend( descriptor_t *apDescriptor, variable_t aMSDP );
|
|
||||||
|
|
||||||
/* Function: MSDPSendPair
|
|
||||||
*
|
|
||||||
* Send the specified strings to the user as an MSDP variable/value pair. This
|
|
||||||
* will automatically use ATCP instead if MSDP is not supported by the client.
|
|
||||||
*/
|
|
||||||
void MSDPSendPair( descriptor_t *apDescriptor, const char *apVariable, const char *apValue );
|
|
||||||
|
|
||||||
/* Function: MSDPSetNumber
|
|
||||||
*
|
|
||||||
* Call this whenever an MSDP integer variable has changed. The easiest
|
|
||||||
* approach is to send every MSDP variable within an update function (and
|
|
||||||
* this is what the snippet does by default), but if the variable is only
|
|
||||||
* set in one place you can just move its MDSPSend() call to there.
|
|
||||||
*
|
|
||||||
* You can also this function for bools, chars, enums, short ints, etc.
|
|
||||||
*/
|
|
||||||
void MSDPSetNumber( descriptor_t *apDescriptor, variable_t aMSDP, int aValue );
|
|
||||||
|
|
||||||
/* Function: MSDPSetString
|
|
||||||
*
|
|
||||||
* Call this whenever an MSDP string variable has changed. The easiest
|
|
||||||
* approach is to send every MSDP variable within an update function (and
|
|
||||||
* this is what the snippet does by default), but if the variable is only
|
|
||||||
* set in one place you can just move its MDSPSend() call to there.
|
|
||||||
*/
|
|
||||||
void MSDPSetString( descriptor_t *apDescriptor, variable_t aMSDP, char *apValue );
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
MSSP functions.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Function: MSSPSetPlayers
|
|
||||||
*
|
|
||||||
* Stores the current number of players. The first time it's called, it also
|
|
||||||
* stores the uptime.
|
|
||||||
*/
|
|
||||||
void MSSPSetPlayers( int aPlayers );
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
MXP functions.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Function: MXPCreateTag
|
|
||||||
*
|
|
||||||
* Puts the specified tag into a secure line, if MXP is supported. If the user
|
|
||||||
* doesn't support MXP they will see the string unchanged, meaning they will
|
|
||||||
* see the <send> tags or whatever. You should therefore check for support and
|
|
||||||
* provide a different sequence for other users, or better yet just embed MXP
|
|
||||||
* tags for the ProtocolOutput() function.
|
|
||||||
*/
|
|
||||||
char *MXPCreateTag( descriptor_t *apDescriptor, char *apTag );
|
|
||||||
|
|
||||||
/* Function: MXPSendTag
|
|
||||||
*
|
|
||||||
* This works like MXPCreateTag, but instead of returning the string it sends
|
|
||||||
* it directly to the user. This is mainly useful for the <VERSION> tag.
|
|
||||||
*/
|
|
||||||
void MXPSendTag( descriptor_t *apDescriptor, char *apTag );
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
Sound functions.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Function: SoundSend
|
|
||||||
*
|
|
||||||
* Sends the specified sound trigger to the player, using MSDP or ATCP if
|
|
||||||
* supported, MSP if not. The trigger string itself is a relative path and
|
|
||||||
* filename, eg: SoundSend( pDesc, "monster/growl.wav" );
|
|
||||||
*/
|
|
||||||
void SoundSend( descriptor_t *apDescriptor, const char *apTrigger );
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
Colour functions.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Function: ColourRGB
|
|
||||||
*
|
|
||||||
* Returns a colour as an escape code, based on the RGB value provided. The
|
|
||||||
* string must be four characters, where the first is either 'f' for foreground
|
|
||||||
* or 'b' for background (case insensitive), and the other three characters are
|
|
||||||
* numeric digits in the range 0 to 5, representing red, green and blue.
|
|
||||||
*
|
|
||||||
* For example "F500" returns a red foreground, "B530" an orange background,
|
|
||||||
* and so on. An invalid colour will clear whatever you've set previously.
|
|
||||||
*
|
|
||||||
* If the user doesn't support XTerm 256 colours, this function will return the
|
|
||||||
* best-fit ANSI colour instead.
|
|
||||||
*
|
|
||||||
* If you wish to embed colours in strings, use ProtocolOutput().
|
|
||||||
*/
|
|
||||||
const char *ColourRGB( descriptor_t *apDescriptor, const char *apRGB );
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
Unicode (UTF-8 conversion) functions.
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
/* Function: UnicodeGet
|
|
||||||
*
|
|
||||||
* Returns the UTF-8 sequence for the specified unicode value.
|
|
||||||
*/
|
|
||||||
char *UnicodeGet( int aValue );
|
|
||||||
|
|
||||||
/* Function: UnicodeAdd
|
|
||||||
*
|
|
||||||
* Adds the UTF-8 sequence for the specified unicode value onto the end of the
|
|
||||||
* string, without adding a NUL character at the end.
|
|
||||||
*/
|
|
||||||
void UnicodeAdd( char **apString, int aValue );
|
|
||||||
|
|
||||||
#endif // PROTOCOL_H
|
|
Loading…
Add table
Add a link
Reference in a new issue