MOO-cows Mailing List Archive

[Prev][Next][Index][Thread]

TELNET GOAHEAD protocol support patch to server




Another patch to mull over.

I wanted to add a 'mud' like prompt capability to the code.  Here's what 
I came up with.  Please peruse and comment.

This requires a version of network_send_line that does not add the newline
sequence onto the end of the string.  ie.  notify() will always print the
text, and then start a new line on the users screen. 

First, a patch to network.h to prototype the function.

----- PATCH network.h -----
69,77d68
< extern void		network_send_ut_line(network_handle nh,
< 					     const char *line);
< 				/* The given line should be queued for output
< 				 * on the specified connection.  'line' does
< 				 * NOT end in a newline; AND NOTHING IS ADDED.
< 				 * This is intended for prompt's only.
< 				 * UnTerminated.
< 				 */
< 
141,146d131
<  * Revision 2.1  1995/05/16  08:15:29  ian
<  * Added un-terminated notify (ut_notify, bf_ut_notify) and support functions
<  *
<  * Revision 2.0  1995/05/15  23:12:33  ian
<  * Initial revision as received from parcftp.xerox.com version 1.7.8p4
<  *
----------

Then, a patch to net_multi.c

----- PATCH net_multi.c -----
356,389d355
< void
< network_send_ut_line(network_handle nh, const char *line)
< {
<     nhandle    *h = nh.ptr;
<     unsigned	line_length = strlen(line);
<     char       *buffer = (char *) mymalloc(line_length * sizeof(char),
<                          M_NETWORK);
<     text_block *block = (text_block *) mymalloc(sizeof(text_block), M_NETWORK);
< 
<     if (h->output_length + line_length > MAX_QUEUED_OUTPUT) {
< 	int		to_flush;
< 	text_block     *b;
< 	
< 	(void) push_output(h);
< 	to_flush = h->output_length + line_length - MAX_QUEUED_OUTPUT;
< 	while (to_flush > 0  &&  (b = h->output_head)) {
< 	    h->output_length -= b->length;
< 	    to_flush -= b->length;
< 	    h->output_lines_flushed++;
< 	    h->output_head = b->next;
< 	    free_text_block(b);
< 	}
< 	if (h->output_head == 0)
< 	    h->output_tail = &(h->output_head);
<     }
<     memcpy(buffer, line, line_length);
<     block->buffer = block->start = buffer;
<     block->length = line_length;
<     block->next = 0;
<     *(h->output_tail) = block;
<     h->output_tail = &(block->next);
<     h->output_length += line_length;
< }
< 
468c434
< char rcsid_net_multi[] = "$Id: net_multi.c,v 2.1 1995/05/16 08:13:54 ian Exp ian $";
---
> char rcsid_net_multi[] = "$Id: net_multi.c,v 1.16 1993/08/12 21:10:13 pavel Exp $";
471,476d436
<  * Revision 2.1  1995/05/16  08:13:54  ian
<  * Added un-terminated notify (ut_notify, bf_ut_notify) and support functions
<  *
<  * Revision 2.0  1995/05/15  23:12:33  ian
<  * Initial revision as received from parcftp.xerox.com version 1.7.8p4
<  *
----------

Ok.  Now you need to patch server.c to give a moo level verb, ut_notify(). 
It's functionally identical to notify(), same perms required, etc.  Just
it calls network_send_ut_line() instead of network_send_line(). 

----- PATCH server.c -----
572,580d571
< ut_notify(Objid player, const char *message)
< {
<     shandle    *h = find_shandle(player);
< 
<     if (h)
< 	network_send_ut_line(h->nhandle, message);
< }
< 
< void
853,866d843
< bf_ut_notify(Var arglist, Byte next, void *vdata, Objid progr)
< { /* (player, string) */
< 
<     if (!is_wizard(progr) && progr != arglist.v.list[1].v.obj) {
< 	free_var(arglist);
< 	return make_error_pack(E_PERM);
<     } 
<     
<     ut_notify(arglist.v.list[1].v.obj, arglist.v.list[2].v.str);
<     free_var(arglist);
<     return no_var_pack();
< }
< 
< static package
898,899d874
<     (void) register_function("ut_notify", 2, 2, bf_ut_notify,
<     			     TYPE_OBJ, TYPE_STR);
903c878
< char rcsid_server[] = "$Id: server.c,v 2.1 1995/05/16 08:13:54 ian Exp ian $";
---
> char rcsid_server[] = "$Id: server.c,v 1.19 1992/10/23 23:03:47 pavel Exp $";
906,911d880
<  * Revision 2.1  1995/05/16  08:13:54  ian
<  * Added un-terminated notify (ut_notify, bf_ut_notify) and support functions
<  *
<  * Revision 2.0  1995/05/15  23:12:33  ian
<  * Initial revision as received from parcftp.xerox.com version 1.7.8p4
<  *
----------

And then finally, to make the prompting work, there must be a mod to
tasks.c to display the prompt when required.  The way I've done it is to 
use the same technique (copied, in fact) that Pavel uses to call various 
#0 verbs.

Now, if there is a #0:do_prompt verb, it will be called *every* time the
player is prompted for input.  Even if the player just presses 'return' or
'enter'. 

----- PATCH tasks.c -----
405,410d404
< 	{
< 	    char *s = str_dup("");
< 	    run_server_task(pi.player, SYSTEM_OBJECT, "do_prompt",
< 			    parse_into_wordlist(s), s, 0);
< 	    free_str(s);
< 	    free_pi(&pi, 0);
412d405
< 	}
446,454d438
< 
< 	    free_var(result);
< 
< 	    {
< 		char *s = str_dup("");
< 		run_server_task(pi.player, SYSTEM_OBJECT, "do_prompt",
< 				parse_into_wordlist(s), s, 0);
< 		free_str(s);
< 	    }
1260c1244
< char rcsid_tasks[] = "$Id: tasks.c,v 2.2 1995/05/16 08:39:26 ian Exp ian $";
---
> char rcsid_tasks[] = "$Id: tasks.c,v 1.15 1992/10/23 23:03:47 pavel Exp $";
1263,1272d1246
<  * Revision 2.2  1995/05/16  08:39:26  ian
<  * Added call to #0:do_prompt in do_command_task.  For MUD style prompts
<  * which can be edited within the database easily.
<  *
<  * Revision 2.1  1995/05/16  08:35:37  ian
<  * Fixed memory leak (possible) in do_command_task.  free_var(result);
<  *
<  * Revision 2.0  1995/05/15  23:12:33  ian
<  * Initial revision as received from parcftp.xerox.com version 1.7.8p4
<  *
----------

That patch above, as the RCS comment section notes, includes a call to
free_var(result).  It may be justified, I don't know.  While browsing 
further through the code, and looking at mymalloc, I see that Pavel has 
some good memory-leak tracking capabilities, so it seems kinda improbable 
that anything slipped past.

Anyway, to actually use that code to any extent, you should have a 
#0:do_prompt verb.  Here's a real dumb one :)

-----
.program #0:do_prompt
ut_notify(player, ">" + chr(255) + chr(249));
.
-----

The 255d 249d (\377 \371) (0xFF, 0xF9) sequence is the IAC GOAHEAD
sequence that is part of the Telnet protocol. 

It should work with most if not all terminals and clients.

Naturally, your do_prompt should do appropriate perm/caller() checking 
etc, or whatever is suitable for your system.

The ut_notify() would probably only be useful to those who are writing
combat oriented MOO's.  However, you could possibly use it in 'normal'
Moo's to change the way #0:do_login works.  For example to prompt users
for passwords, and switch echo off, so the password cannot be read from
behind.  Perhaps a good idea for students who could get their passwords
stolen like that. 

As to #0:do_prompt, I intend to use it with various substitution verbs, and 
will allow the players to customise their prompts a bit.

As always, comments appreciated.

Regards,

Ian.

+--------------------------------------------------------------------+
| Ian Macintosh         | P.O. Box 24-036 | Anything really worth    |
| General Manager       | Royal Oak       | doing, is worth doing    |
| Sytek New Zealand Ltd | Auckland 1      | badly.     - Duncan Shaw |
+--------------------------------------------------------------------+




Home | Subject Index | Thread Index