fbmuck-6.01/contrib/jresolver/
fbmuck-6.01/contrib/jresolver/org/
fbmuck-6.01/contrib/jresolver/org/fuzzball/
fbmuck-6.01/docs/devel/
fbmuck-6.01/game/
fbmuck-6.01/game/logs/
fbmuck-6.01/game/muf/
fbmuck-6.01/scripts/
fbmuck-6.01/src_docs/
#include "config.h"
#include <math.h>
#include <ctype.h>
#include "params.h"

#include "db.h"
#include "tune.h"
#include "mpi.h"
#include "mcp.h"
#include "externs.h"
#include "props.h"
#include "match.h"
#include "interp.h"
#include "interface.h"
#include "msgparse.h"


struct line *get_new_line(void);

void
show_mcp_error(McpFrame * mfr, char *topic, char *text)
{
	McpMesg msg;
	McpVer supp = mcp_frame_package_supported(mfr, "org-fuzzball-notify");

	if (supp.verminor != 0 || supp.vermajor != 0) {
		mcp_mesg_init(&msg, "org-fuzzball-notify", "error");
		mcp_mesg_arg_append(&msg, "text", text);
		mcp_mesg_arg_append(&msg, "topic", topic);
		mcp_frame_output_mesg(mfr, &msg);
		mcp_mesg_clear(&msg);
	} else {
		notify(mcpframe_to_user(mfr), text);
	}
}



/*
 * reference is in the format objnum.category.misc where objnum is the
 * object reference, and category can be one of the following:
 *    prop     to set a property named by misc.
 *    proplist to store a string proplist named by misc.
 *    prog     to set the program text of the given object.  Ignores misc.
 *    sysparm  to set an @tune value.  Ignores objnum.
 *    user     to return data to a muf program.
 *
 * If the category is prop, then it accepts the following types:
 *    string        to set the property to a string value.
 *    string-list   to set the property to a multi-line string value.
 *    integer       to set the property to an integer value.
 *
 * Any other values are ignored.
 */
void
mcppkg_simpleedit(McpFrame * mfr, McpMesg * msg, McpVer ver, void *context)
{
	if (!string_compare(msg->mesgname, "set")) {
		dbref obj = NOTHING;
		char *reference;
		char *valtype;
		char category[BUFFER_LEN];
		char *ptr;
		int lines;
		dbref player;
		char buf[BUFFER_LEN];
		char *content;
		int line;
		int descr;

		reference = mcp_mesg_arg_getline(msg, "reference", 0);
		valtype = mcp_mesg_arg_getline(msg, "type", 0);
		lines = mcp_mesg_arg_linecount(msg, "content");
		player = mcpframe_to_user(mfr);
		descr = mcpframe_to_descr(mfr);

		/* extract object number.  -1 for none.  */
		if (isdigit(*reference)) {
			obj = 0;
			while (isdigit(*reference)) {
				obj = (10 * obj) + (*reference++ - '0');
				if (obj >= 100000000) {
					show_mcp_error(mfr, "simpleedit-set", "Bad reference object.");
					return;
				}
			}
		}
		if (*reference != '.') {
			show_mcp_error(mfr, "simpleedit-set", "Bad reference value.");
			return;
		}
		reference++;

		/* extract category string */
		ptr = category;
		while (*reference && *reference != '.') {
			*ptr++ = *reference++;
		}
		*ptr = '\0';
		if (*reference != '.') {
			show_mcp_error(mfr, "simpleedit-set", "Bad reference value.");
			return;
		}
		reference++;

		/* the rest is category specific data. */
		if (!string_compare(category, "prop")) {
			if (obj < 0 || obj >= db_top || Typeof(obj) == TYPE_GARBAGE) {
				show_mcp_error(mfr, "simpleedit-set", "Bad reference object.");
				return;
			}
			if (!controls(player, obj)) {
				show_mcp_error(mfr, "simpleedit-set", "Permission denied.");
				return;
			}
			for (ptr = reference; *ptr; ptr++) {
				if (*ptr == ':') {
					show_mcp_error(mfr, "simpleedit-set", "Bad property name.");
					return;
				}
			}
			if (Prop_System(reference) || (!Wizard(player) && (Prop_SeeOnly(reference) || Prop_Hidden(reference)))) {
				show_mcp_error(mfr, "simpleedit-set", "Permission denied.");
				return;
			}
			if (!string_compare(valtype, "string-list") || !string_compare(valtype, "string")) {
				int left = BUFFER_LEN - 1;
				int len;

				buf[0] = '\0';
				for (line = 0; line < lines; line++) {
					content = mcp_mesg_arg_getline(msg, "content", line);
					if (line > 0) {
						if (left >= 1) {
							strcatn(buf, sizeof(buf), "\r");
							left--;
						} else {
							break;
						}
					}
					len = strlen(content);
					if (len >= left - 1) {
						strncat(buf, content, left);
						left = 0;
						break;
					} else {
						strcatn(buf, sizeof(buf), content);
						left -= len;
					}
				}
				buf[BUFFER_LEN - 1] = '\0';
				add_property(obj, reference, buf, 0);

			} else if (!string_compare(valtype, "integer")) {
				if (lines != 1) {
					show_mcp_error(mfr, "simpleedit-set", "Bad integer value.");
					return;
				}
				content = mcp_mesg_arg_getline(msg, "content", 0);
				add_property(obj, reference, NULL, atoi(content));
			}

		} else if (!string_compare(category, "proplist")) {
			if (obj < 0 || obj >= db_top || Typeof(obj) == TYPE_GARBAGE) {
				show_mcp_error(mfr, "simpleedit-set", "Bad reference object.");
				return;
			}
			if (!controls(player, obj)) {
				show_mcp_error(mfr, "simpleedit-set", "Permission denied.");
				return;
			}
			for (ptr = reference; *ptr; ptr++) {
				if (*ptr == ':') {
					show_mcp_error(mfr, "simpleedit-set", "Bad property name.");
					return;
				}
			}
			if (Prop_System(reference) || (!Wizard(player) && (Prop_SeeOnly(reference) || Prop_Hidden(reference)))) {
				show_mcp_error(mfr, "simpleedit-set", "Permission denied.");
				return;
			}
			if (!string_compare(valtype, "string-list")) {

				if (lines == 0) {
					snprintf(buf, sizeof(buf), "%s#", reference);
					remove_property(obj, buf);
				} else {
					snprintf(buf, sizeof(buf), "%s#", reference);
					remove_property(obj, buf);
					add_property(obj, buf, "", lines);
					for (line = 0; line < lines; line++) {
						content = mcp_mesg_arg_getline(msg, "content", line);
						if (!content || !*content) {
							content = " ";
						}
						snprintf(buf, sizeof(buf), "%s#/%d", reference, line + 1);
						add_property(obj, buf, content, 0);
					}
				}
			} else if (!string_compare(valtype, "string") ||
					   !string_compare(valtype, "integer")) {
				show_mcp_error(mfr, "simpleedit-set", "Bad value type for proplist.");
				return;
			}

		} else if (!string_compare(category, "prog")) {
			struct line *tmpline;
			struct line *curr = NULL;
			struct line *new_line;

			if (obj < 0 || obj >= db_top || Typeof(obj) == TYPE_GARBAGE) {
				show_mcp_error(mfr, "simpleedit-set", "Bad reference object.");
				return;
			}
			if (Typeof(obj) != TYPE_PROGRAM || !controls(player, obj)) {
				show_mcp_error(mfr, "simpleedit-set", "Permission denied.");
				return;
			}
			if (!Mucker(player)) {
				show_mcp_error(mfr, "simpleedit-set", "Permission denied.");
				return;
			}
			if (FLAGS(obj) & INTERNAL) {
				show_mcp_error(mfr, "simpleedit-set",
							   "Sorry, this program is currently being edited.  Try again later.");
				return;
			}
			tmpline = PROGRAM_FIRST(obj);
			PROGRAM_SET_FIRST(obj, NULL);

			for (line = 0; line < lines; line++) {
				new_line = get_new_line();
				content = mcp_mesg_arg_getline(msg, "content", line);
				if (!content || !*content) {
					new_line->this_line = alloc_string(" ");
				} else {
					new_line->this_line = alloc_string(content);
				}
				new_line->next = NULL;
				if (line == 0) {
					PROGRAM_SET_FIRST(obj, new_line);
				} else {
					curr->next = new_line;
				}
				curr = new_line;
			}

			log_status("PROGRAM SAVED: %s by %s(%d)\n",
					   unparse_object(player, obj), NAME(player), player);

			write_program(PROGRAM_FIRST(obj), obj);

			if (tp_log_programs)
				log_program_text(PROGRAM_FIRST(obj), player, obj);

			do_compile(descr, player, obj, 1);

			free_prog_text(PROGRAM_FIRST(obj));

			PROGRAM_SET_FIRST(obj, tmpline);

			DBDIRTY(player);
			DBDIRTY(obj);

		} else if (!string_compare(category, "sysparm")) {
			if (!Wizard(player)) {
				show_mcp_error(mfr, "simpleedit-set", "Permission denied.");
				return;
			}
			if (lines != 1) {
				show_mcp_error(mfr, "simpleedit-set", "Bad @tune value.");
				return;
			}
			content = mcp_mesg_arg_getline(msg, "content", 0);
			tune_setparm(reference, content);

		} else if (!string_compare(category, "user")) {
		} else {
			show_mcp_error(mfr, "simpleedit-set", "Unknown reference category.");
			return;
		}
	}
}