Writing C++ Modules - Quickstart Examples
[Guides]

Learn to write modules like a pro! More...
Writing Furnarchy 2 modules is a structurally much simpler departure from Furnarchy 3. The Furnarchy API has been greatly condensed and simplified, and the scaffolding required for well-formed modules is now almost nil.

Project Setup

Furnarchy native modules are DLLs, so you should start by creating a Win32 DLL project.

To make use of the Furnarchy API, you need to include the furn2.h header and link against the furn2.lib import library. Both these files come bundled with every Furnarchy 2 installation.

For C++ projects, the furnarchy 2 API will be contained in the furn2 namespace.

Event Handlers

Furnarchy modules are entirely event-based. Thus, all you do will ultimately be a reaction to an event coming through one of the event handlers:

To use event handlers, you just need to define one. Furnarchy will automatically discover it when it loads your module and call it whenever an appropriate event comes up.

Example: "Hello, World!"

As a simple example, here's a module that prints "Hello, World!" to the chat buffer when the player logs in:
#include "C:\Program Files\Furnarchy2\furn2.h"

using namespace furn2;

/* Define the on_world handler to receive world events. */
F2EXPORT intptr_t F2CALL on_world( World_Event e, intptr_t param )
{
   if (e == WO_EVENT_LOGGEDIN)   // Player has logged in!
      // Print a message to the chat buffer.
      f2_speak( "Hello, World!" );
   
   return 0;
}

Example: "Hello, World!" (Part Deux)

To illustrate sending network data and command line processing, here's a module that makes the player say "Hello, World!" to everyone nearby when the player types "@sayhello":
#include "C:\Program Files\Furnarchy2\furn2.h"
#include <cstring>

using namespace furn2;
using namespace std;

/* Define the on_command handler to receive commmand line input. */
F2EXPORT bool F2CALL on_command( int argc, char* argv[] )
{
   // If the user typed "@sayhello"
   if (argc >= 1 && strcmp( argv[ 0 ], "sayhello" ) == 0)
   {
      // Send out a chat command.
      f2_netoutline( "\"Hello, World!" );
      
      return true;   // Tell Furnarchy that we handled it.
   }
   
   return false;
}

Example: "Hello, World!" (Part Trois)

To illustrate handling windows messages, here's a module that makes the player say "Hello, World!" to everyone nearby when the player presses CTRL+S:
#include "C:\Program Files\Furnarchy2\furn2.h"

using namespace furn2;

/* Define the on_wndproc handler to process windows messages. */
F2EXPORT bool F2CALL on_wndproc( WNDPROCPARAMS* params )
{
   if (params->msg == WM_CHAR)
   {
      if (params->wparam == 's' &&
          !(params->lparam & 0x40000000) &&
          GetKeyState( VK_CONTROL ) & 0x80000000)
      {
         // Ctrl + S pressed!
         // Send out a chat command.
         f2_netoutline( "\"Hello, World!" );
         
         // Tell Furnarchy we handled it.
         params->retval = 0;
         return true; 
      }
   }
   
   return false;
}

Example: Chat Alert

To illustrate processing inbound network data, here's a module that flashes the Furcadia window whenever something is about to be posted to the chat buffer:
#include "C:\Program Files\Furnarchy2\furn2.h"

using namespace furn2;

bool g_enabled = false;

/* Define the on_module handler to process module events. */
F2EXPORT intptr_t F2CALL on_module( Module_Event e, intptr_t param )
{
   // Keep track of whether we're enabled or not.
   if (e == MOD_EVENT_ENABLE)
      g_enabled = true;
   else if (e == MOD_EVENT_DISABLE)
      g_enabled = false;
   
   return 0;
}

/* Define the on_inet handler to process server to client network lines. */
F2EXPORT void F2CALL on_inet( Revision pass, const char* line, int from, size_t num )
{
   if (!g_enabled) // Don't do anything if we're not enabled.
      return;
   
   if (pass == REV_FINAL)  // Only interested in the end product.
   {
      if (line[ 0 ] == '(')   // Chat buffer line command prefix.
      {
         /* Flash the window 3 times. */
         FLASHWINFO fwi = { sizeof( FLASHWINFO ), f2_getwnd( ), 
                            FLASHW_ALL, 3, 0 };
         FlashWindowEx( &fwi );
      }
   }
}

Example: Reverse Speech

To illustrate manipulating outbound network data, here's a module that reverses normal chat coming from the player:
#include "C:\Program Files\Furnarchy2\furn2.h"
#include <string>

using namespace furn2;
using namespace std;

bool g_enabled = false;

/* Define the on_module handler to process module events. */
F2EXPORT intptr_t F2CALL on_module( Module_Event e, intptr_t param )
{
   // Keep track of whether we're enabled or not.
   if (e == MOD_EVENT_ENABLE)
      g_enabled = true;
   else if (e == MOD_EVENT_DISABLE)
      g_enabled = false;
   
   return 0;
}

/* Define the on_onet handler to process client to server network lines. */
F2EXPORT void F2CALL on_onet( Revision pass, const char* line, int from, size_t num )
{
   if (!g_enabled) // Don't do anything if we're not enabled.
      return;
   
   if (pass == REV_REVISING)  // Can only modify the line during this pass.
   {
      if (line[ 0 ] == '"')   // Speech command prefix.
      {
         /* Reverse the chat string. */
         string reversed = "\"";
         
         if (*(++line)) {
            const char* end = line + ( strlen( line ) - 1 );
            while (end != line) reversed.push_back( *(end--) );
         }
         
         // Submit the modified line.
         f2_reviseline( reversed.c_str( ) );
      }
   }
}

Where To Go From Here

To get the most out of Furnarchy, you should read more on the event handlers, browse the API Functions and look at the other guides. The forums at http://www.heroinpuppy.com/forums are also an excellent place to go for help with module making.

Generated on Tue Jun 24 12:24:08 2008 for Furnarchy Module by  doxygen 1.5.5