-
Notifications
You must be signed in to change notification settings - Fork 13
/
hacking-lambda-moo-server-non-html5.html
154 lines (147 loc) · 7.06 KB
/
hacking-lambda-moo-server-non-html5.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<html>
<title>Hacking LambdaMOO</title>
<h1>The source code for this file was taken from <a href="http://lions.cs.ndsu.nodak.edu/~vender/LambdaMOO/hacking.html">http://lions.cs.ndsu.nodak.edu/~vender/LambdaMOO/hacking.html</a> and is stored in this repository for posterity. It is not HTML5.</h1>
<P>Okay, I got annoyed trying to write parts of the automatic core updater
utility, so I started digging through the server code and have discovered
some things:
<P>
<H1>What happens when a connection is made to the LambdaMOO server</h1>
<P>The another program connects to a port the server is listening on,
is accepts the connection after some minimal amount of error checking
or black list checking, and then creates a task with the following
associates: a unique identifier for that connection (a negative object
reference), and the object responsible for responding to that port.
In the default case, this object will be #0 (the system object).
To determine what objects are responsible for which ports, the built in
function listeners() can be used.
<P>
After creating the previously mentioned association and task, the server pushes
an empty string into the input queue of that task. The interesting thing
at this point is that this empty string is what causes the welcome message
in the LambdaCore database to be generated. What happens is this<P>
<UL><LI>Server calls the managing objects "do_login_command" with the
input string<LI>
<LI>The input string fails to match any known verbs</LI>
<LI>do_login_command defaults to a verb named "?" to handle the input<LI>
<LI>"?" displays the contents of $login.welcome_message, along with a command
summary<LI>
</UL>
If you don't believe this, start up a copy of your favorite MOO core, connect
as a wizard, and @rmprop $login.welcome_message and then login in again.
You should receive a fairly bizarre trace back error.
<P>
In the normal flow of events, one of the verbs called by "do_login_command"
will return an object reference, or end the connection by calling boot_player.
Assuming that an object reference is returned, that task becomes promoted
to command task, and the rules for dealing with user input changes radically.
<P>
For input tasks, the flow of execution is as follows:
<UL><LI>parse input into basic tokens delimited by spaces<LI>
<LI>Check for input and output prefixes</LI>
<LI>If input or output prefixes aren't detected, try executing
"do_command" on the object associated with that connection from before</LI>
<LI>If "do_command" doesn't exist, or returns a false value, perform the
normal verb matching proceedure and execute the located verb as an
input task.</LI>
<LI>If all else fails, call "huh", or as a last resort report
"I didn't understand that." to the connection</LI>
</UL>
<P>1. It is possible to completely redefine how the server deals with
user input by defining a "do_command" verb on the object the player
has logged into on. do_command is called before the normal processing
of input lines into psuedo-english phrases. However, doing macro
processing (as Mr. Fish was wondering about) would require doing all of the
normal text processing functions in LambdaMOO code, since it is not possible
since there are no destructive list maninpulation functions.
<P>
Each port the server is listening on is associated with an object. The
port bound by the server on start up is associated with object #0
(The system object). do_command gets passed the input string after
it has been broken up into white space delimited tokens. So, if for example
#0:do_command looks like
<PRE>
player:tell(@args);
if (length(args)==3)
return 1;
else
return 0;
endif;
</PRE>
then a player connected through #0 who typed
<PRE>
l at me
</PRE>
would see the text
<PRE>
lame
</PRE>
echoed back to them, and that command would never receive normal processing.
Interestingly enough, the command ".pr*ogram" in the form
<PRE>
.program Object:verb
</PRE>
is hard coded into the server for programmer players before the check for
"do_command". Interestingly enough, do_command isn't defined for either
the Sell Game, or Planet Oit.
<P>
2. Server options
<P>
Yes, the server options to work. Essentially, the documentation is unclear
about where the properties are supposed to be found. The server code
expects them to be on $server_options, or rather that $server_options is
expected to be an object reference which defines the properties.
<P>
3. Forking tasks
<P>
Granted that it looks like the server code for dealing with queued tasks
is fairly complicated, it doesn't look like the overhead for forking a task
is too much more that the overhead for invoking a verb on an object.
<P>
4. Server startup scripts
<P>
The verb #0:server_started is run when the server starts up, after the
database is loaded and the network code initialized. This would be the
place to put things like the http server initializations for the Sell Game
and Planet Oit.
<P>
5. I've been looking through the server code for the MudOS LPC style
mud server, and managed to locate the main loop of the server. My major
reaction to the MudOS code is that it makes the LambdaMOO server code
(even the confusing parts) look blindingly straight forward. Essentially,
LPC muds implement a large amount of swapping objects out of memory,
calling reset functions every so often, and maintaining a circular list of
objects to call a heart_beat function periodically, all while trying to take
up more disk space than memory. Of course, LambdaMOO servers try to do
the exact opposite by trying to take up more virtual memory than disk space.
In any event, I honestly don't see why (if periodic resets and heart_beat
functions were desired) these two functions could be implemented by carefully
written LambdaMOO code.
<P>
6. I still haven't found a good way of introducing a good destructive list
append function into the Lambda server. At the moment, it appears that
this would involve adding a built in function, and as such the naming
convention would be
static package bf_ItsName(...)
and then call
register_function("ItsName",?,?,bf_ItsName,ArgType,ArgType,ArgType,...);
The notation in functions.c says
<PRE>
/*****************************************************************************
* This is the table of procedures that register MOO built-in functions. To
* add new built-in functions to the server, add to the list below the name of
* a C function that will register your new MOO built-ins; your C function will
* be called exactly once, during server initialization. Also add a
* declaration of that C function to `bf_register.h' and add the necessary .c
* files to the `CSRCS' line in the Makefile.
****************************************************************************/
</PRE>
Which is interesting, and I'll have to give it a try soon.
<P>
Conceivably, adding file io would not be necessarily very involved, once
the appropriate interfaces were defined. For adding destructive set
maninpulations, all that would be necessary would be to figure out how to
dissasociate the previous copy of the variable from the reference counting
scheme, modify it, and then reintroduce it to the ref counters.
</P>
<P>
</html>