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@mailhost.net Please include the version you are running, your OS, 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. The MUD++ source is now provided under the GNU Public License. I and the other developers have agreed to place our code under this license for freedom and protection, however we still own rights to the software and may at any time release under any copyright terms that we choose. Currently there are two active developers, Melvin Smith (myself) and Artur 'Revinor' Biesiadowski. * 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, neither do I. 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 CPP.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.next(); // 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.next() goes to the next object. 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. NOTE: There is now a macro called for_each() which basically takes a list and a pointer of type that the list holds and iterates through the list: for_each( list, item ) { item->do_something(); } 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. ** WARNING: THIS SECTION IS SO FAR OUT OF DATE THAT I BARELY EVEN REMEMBER WRITING IT! WE TERRIBLY NEED TO GET THIS DOC UP TO DATE AND FINISHED FOR NEW HACKERS. --Melvin Last updated 12/20/95 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. Happy hacking, --Fusion