HACKER.TXT written by Melvin Smith 03/95
---------------------------------------------------------------------------
OO = Object Oriented
OOP = Object Oriented Programming
OOD = Object Oriented Design
---------------------------------------------------------------------------
If want to try this code but you dont have a C++ compiler, you can
get gcc/g++ free from ftp. Try the GNU ftp site:
ftp://prep.ai.mit.edu/pub/gnu/gcc-*.tar.gz
Send bug reports to the mud++ discussion list at mud-list@spice.com
Please include the version you are running, the machine it is on, and
what compiler you are using.
NOTE: If you have a bug fix or idea, I welcome you to send the code
along with it, and if it is used I will credit you in CHANGES.LOG.
Please do NOT send me copyrighted code. It will just go straight to /dev/null.
This may sound cheap, but one of the main reasons I designed my own code
base was to get away from multiple copyrights and headers throughout
the code. I have sole ownership/rights to the code so anything I do will not
be hindered by someone elses copyrights.
* Tips and warnings to read before you try to hack/develop on this code.
MUD++ is designed/written in C++, NOT C.
I will get this out of the way now: If you develop on this game, do it the
OOP way. If you don't know much C++ don't worry. The basic concepts
required to make simple/moderate changes don't take too long to grasp
for a C programmer. The fastest way is to look at the code. If you want
a new who list, you should have no problem hacking the existing one even
if you have never seen a piece of C++ code. Edit the file pc.cc (player)
and go to PC::do_who(). I also recommend that you read C++.TXT. It is
a little faq/tutorial on C++ written by Furey and some code examples by me.
The whole OOP technique implys a few things that to traditional C programmers
may look inefficient, the most important being the method of using member
functions to access data in a stucture/class instead of the simple . or ->
dereference. The reason for designing with member functions is the
enforcement of encapsulation, abstraction of lower level code to the top
level builder, and the concept of programming by contract.
A good example in general is implementation of linked lists. If you
have ever coded much on Diku\Merc\Circle base code then you have probably
seen the crashes that can happen when a link is removed, OR freed but not
removed, etc. The rewriting of code is also tiresome, for in every function
that iterates through the char/object list the loop code must be written the
same way.
A typical loop example:
CHAR_DATA *ch;
for( ch = ch_list; ch; ch = ch_next )
{
ch_next = ch->next;
.
.
Some code, if you decide to remove a link then its more trouble.
.
.
}
A C++ implementation in MUD++ looks like this:
list->reset(); // set the "current" pointer to head
while( list->peek() )
{
.
.
Some code
.
.
list++; // Visit next node ( "current" )
}
Reset sets the pointer to the head of the list. Peek returns the current
object or NULL if at end. list++ goes to the next object. Here the ++
operator is overloaded for the DLList class.
There isnt a LOT of size difference here but it becomes more apparent when
a link is removed, and so forth. Mainly, it is much cleaner and encapsulated.
In MUD++, objects are seldom passed as arguments. Usually things are done
with member functions so the target object is the local scope. When you add
new commands/features, etc. try to adhere to the same method. The development
of this game is headed towards complete OO Design, not C
backwards compatibility.
OK... THE FUN BEGINS!
Where is what?!?!?
Order is from lowest level utility stuff to high level MUD related stuff.
o socket.h, socket.cc
Socket class. Handles connections, IO, TCP structs, etc. Directly
derived from the Berkely struct sockaddr_in and can be passed to the
standard Berkely socket functions although the socket functions are
now implemented as interface to the Socket object.
o server.h, server.cc
Server class. Uses the Socket objects but takes care of IO multiplexing
timing, new connections, dropping links, etc. The control socket is
a Socket object itself. More than one Server object can be created
to accept connections on multiple ports but only one Server should be
used for timing.
o Nanny function that handles all new connections. Name from Diku.
o io.h, io.cc
My replacement for C++ cout, cin (ostream, istream, etc.)
IStream uses memory mapped IO for fast reads and complete IN-RAM parsing
of files. OStream uses user defined cache-buffer size.
o file.h, file.cc
Derived from io.h, io.cc defines actual parsing functions like
getword, getstring, getnum, getlong and the << and >> operators.
o string.h, string.cc
My pride and joy. Quite a full String implementation. Its not as
big as GNU's String in libg++ but I think it has about everything
you could want in a string class. Does sharing, use counts,
with copy on write.
o random.h, random.cc
A caching random number generator object. Should only create one instance
of this. It outperforms the system functions, check out the profiling
specs I included in random.h
o bit.h
Bit field definition and macros for unlimited bits. Basically identical
to the berkely socket fd_set struct.
o vector.h
A vector 3d position. Not used yet.
o index.h, index.cc
Index class. This is the unique lookup key system instead of vnums.
Format is <scope>:<key> where a sword in mahn-tor may be called
mahn-tor:sword-black. Everything in mahn-tor is of scope 'mahn-tor'
When doing loads, etc. the local area is used as a default in the case
that no scope is specified. To override scope use : preceding the
key which will look globally. ofind :sword returns sword in all areas.
Just like C++ :: operator. Lot of potential.
o indexable.h, indexable.cc
Lookup container that uses Index class to hold object, rooms, etc.
Uses LList for now but will be hashed soon.
Example: Object *obj = objIndex.lookupObj( "drow:sword" );
o llist.h, llist.cc
Class template for linked list objects. This object can hold
any data type or class. This is the way I choose to do my template
instantiation. There are other ways that you can use without the
-fno-implicit-templates compile flag but I think you will find this the
faster and cleanest way. NOTE: It you define a new LList, for example
you decide you want to keep a global list of a new Box object then you
would need to add
o rmpc.h, rmpc.cc
Remote Mud Procedure Call (RMPC) - Alpha stages.
Non-blocking concurrent procedure calls amongst Nodes of the server
cluster. Each RMPC has a unique id.
o node.h, node.cc
A physical server Node of a distributed server. Each Node has its own
Socket and a queue of pending RMPC's.
Nodes connect based off of mud++/etc/HOSTS file.
o process.h
Mud concurrent processes. Not used yet.
o edit.h, editarea.cc, editobj.cc, editroom.cc, editnpc.cc, edittext.cc
Editor classes. When doing online editing, this is used instead of the
classic connected state. Instead if the player has an Editor * then
the command is passwd to player->getEditor()->command( arg );
Example: PC::oedit( "drow:sword" )
Object *pObj = lookupObject( "drow:sword" );
if( pObj )
editor = new ObjectEditor( pObj );
EditText class contains the text editing utils including line mode,
replaces, cut/paste, etc.
o affect.h
Affect class. A magical affect that contains mods to some object/player.
DEF_DLLIST( Box );
to generate the intances even though the variable may be defined in
main as DLList<Box> BoxList; The compiler must have an instance generated
because for each class type. Some compilers do this automatically
with smart or external template generation. Rather than say anymore,
I recommend reading a C++ book. Templates are usually one of the toughest
things to grasp about C++.
o mud.h ( will be obsolete, don't need the classic 1 big header)
A general MUD header file that hold centralized defines and defs.
I have let it get too big, a more OOP way would be to move all of
the classes out into seperate headers, which is what I'm doing now.
o area.h, area.cc
Area class. Each area object contains its own Index of rooms, objects
etc. as well as environment. The global lookup functions run through
the Area list and call pArea->lookupObj( arg ). An area can be reloaded
from file singly and also unlinked.
o exit.h
Exit class. Contains an Index to a Room and a Room pointer as well as
flags and text.
o room.h, room.cc
Room class. Includes room description text, object, player list, flags
and Exit array. Each room has its own Repop list.
o nameable.cc
Something that can have name keywords.
o thing.h, thing.cc
A physical "Thing" which derives from Nameable. Things can also be
read and written to files. Thing is an abstract class providing interface
for all Things but not implementation.
o object.h, object.cc
Derived from Thing. An Object or item. Weight, volume, affects, values, etc.
o char.h, char.cc
Derived from Thing. A generic Char ( organism )
Defines interface for things an organism can do like get things,
manipulate, look, communicate, move.
o char_combat.cc
Combat definition. PCs and NPCs will fight pretty much with the same
ability including magic.
o npc.h, npc.cc
Derived from Char. NPC class (Non-Player Character)
o shopkeeper.h, shopkeeper.cc
Derived from NPC
o pc.h, pc.cc
Derived from Char. PCs have a Socket of course as well as many stats
similar to NPCs. PC interface, prompting, paging, etc.
o pc_act.cc, pc_combat.cc, pc_info.cc, pc_olc.cc, pc_wiz.cc
Mostly PC commands.
o pc_combat.cc
PC combat specific commands. Mostly the command interface for something
in char_combat.cc
o utils.h, utils.cc
Various honorable mentions. Some functions that may be included in an
OS or compiler such as ltoa, itoa and low level string stuff. I'm
trying to remove as much char * stuff as I can in favor of String class
but some of it is just good to have around.
o parse.h, parse.cc
char * based string parsing. A get_arg( ... ) function for getting
tokens from char *. Need to convert to String member.
Thats all for now, Ill update this when I release.
-Fusion