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