Aw address C example 2

From ActiveWiki
Jump to navigation Jump to search

Lookup and announce the IP address of any user who comes within visible range of the bot.

#include "Aw.h"
#include <stdio.h>
#include <stdlib.h>

void handle_avatar_add (void);
void handle_avatar_delete (void);
void handle_address (int rc);

#define MAX_AVATARS_IN_SCENE 32

struct AVATAR
{
  int session;
  char name[18];
};

/* Name and session number of avatars that are visible to the bot */
struct AVATAR avatars[MAX_AVATARS_IN_SCENE];

int main(int argc, char *argv[])
{
  int rc;
  
  /* Check command line */
  if (argc < 4)
  {
    printf ("Usage: %s number password world\n", argv[0]);
    return 1;
  }   
  
  /* Initialize Active Worlds API */
  rc = aw_init (AW_BUILD);
  if (rc != RC_SUCCESS)
  {
    printf ("Unable to initialize API (reason %d)\n", rc);
    return 1;
  }
  
  /* Install handler for avatar_add and avatar_delete events */
  aw_event_set (AW_EVENT_AVATAR_ADD, handle_avatar_add);
  aw_event_set (AW_EVENT_AVATAR_DELETE, handle_avatar_delete);
  
  /* Install callback for aw_address */
  aw_callback_set (AW_CALLBACK_ADDRESS, handle_address);
  
  /* Create bot instance */
  rc = aw_create (NULL, 0, NULL);
  if (rc != RC_SUCCESS)
  {
    printf ("Unable to create bot instance (reason %d)\n", rc);
    return 1;
  }
  
  /* Log bot into the universe */
  aw_int_set (AW_LOGIN_OWNER, atoi (argv[1]));
  aw_string_set (AW_LOGIN_PRIVILEGE_PASSWORD, argv[2]);
  aw_string_set (AW_LOGIN_APPLICATION, "aw_address sample application #1");
  aw_string_set (AW_LOGIN_NAME, "MyBot");
  rc = aw_login ();
  if (rc != RC_SUCCESS)
  {
    printf ("Unable to login (reason %d)\n", rc);
    return 1;
  }
  
  /* Enter bot into the world */
  rc = aw_enter (argv[3]);
  if (rc != RC_SUCCESS)
  {
    printf ("Unable to enter world (reason %d)\n", rc);
    return 1;
  }
  
  /* Announce position in the world */
  aw_int_set (AW_MY_X, 1000); /* 1W */
  aw_int_set (AW_MY_Z, 1000); /* 1N */
  aw_int_set (AW_MY_YAW, 2250); /* Face towards GZ */
  rc = aw_state_change ();
  if (rc != RC_SUCCESS)
  {
    printf ("Unable to change state (reason %d)\n", rc);
    return 1;
  }
  
  /* Main event loop */
  while (aw_wait (-1) == RC_SUCCESS);
  
  /* Close everything down */
  aw_destroy ();
  aw_term ();
  
  return 0;
}

void handle_avatar_add (void)
{
  int i;
  int rc;
  
  /* Add avatar to the scene */
  for (i = 0; i < MAX_AVATARS_IN_SCENE; i++)
  {
    if (avatars[i].session == 0) /* Checking for unused struct to store name and session inside */
    {
      avatars[i].session = aw_int (AW_AVATAR_SESSION);
      strcpy(avatars[i].name, aw_string (AW_AVATAR_NAME));
      break;
    }
  }
  
  /* This function call will return without waiting for the IP address query to complete.
     Possible failures here are such that they're impossible to communicate to the user.
     Such as RC_NOT_INITIALIZED, RC_NO_INSTANCE and RC_NO_CONNECTION. */
  aw_address (aw_int (AW_AVATAR_SESSION));
}

void handle_avatar_delete (void)
{
  int i;
  
  /* Remove avatar from the scene */
  for (i = 0; i < MAX_AVATARS_IN_SCENE; i++)
  {
    if (avatars[i].session == aw_int (AW_CHAT_SESSION))
    {
      avatars[i].session = 0; /* Mark struct as unused */
      strcpy(avatars[i].name, "");
      break;
    }
  }
}

void handle_address (int rc)
{
  /* Keep in mind that AW_AVATAR_NAME is not defined within the context of this callback */
  
  int i;
  char name[256];
  char msg[256];
  
  strcpy(name, "<UNKNOWN>");
  
  /* Find name of the avatar */
  for (i = 0; i < MAX_AVATARS_IN_SCENE; i++)
  {
    if (avatars[i].session == aw_int (AW_AVATAR_SESSION)
    {
      strcpy(name, avatars[i].name);
      break;
    }
  }
  
  if (rc != RC_SUCCESS)
  {
    sprintf (msg, "%s, I cannot determine your IP address (reason %d)", name, rc);
  }
  else
  {
    int           address;
    unsigned char *p = (unsigned char*)&address;
    
    address = aw_int (AW_AVATAR_ADDRESS);
    
    /* The address is in network byte order which means that the most significant byte comes first in memory */
    sprintf (msg, "%s, your IP address is %u.%u.%u.%u", name, p[0], p[1], p[2], p[3]);
  }
  aw_say (msg);
}