PHP: Difference between revisions

From ActiveWiki
Jump to navigation Jump to search
mNo edit summary
mNo edit summary
Line 351: Line 351:


// optionally, retrieve world attributes and events
// optionally, retrieve world attributes and events
// this loop keeps the script running:
while (true) {
while (true) {
   if ($sdk->aw_wait(WAIT_CYCLE) == 0 && $sdk->aw_session() != 0) {
   if ($sdk->aw_wait(WAIT_CYCLE) == 0 && $sdk->aw_session() != 0) {

Revision as of 00:00, 4 January 2023


PHP

This article describes use of the PHP scripting language using the COM_SDK. The semantics used by the COM_SDK are very close to C/C++. You can use the common SDK Help pages of this wiki as a reference in use with PHP.

PHP scripting of SDK Apps is addressed to world- and universe- owners in particular. Typical usage scenarios include game scripting, as well as implementing account management and billing systems. PHP is also handy handling databases, thereby extending scenario specific storages, for example scores of a game.

Other examples, written in PHP since 2008, include AWPortals' web services and statistics (these stats only cover landing zones of certain worlds, not the whole universe).

Basic SDK Concepts and References

PHP Specifics

PHP Preconfiguration


PHP SDK Definitions Include

The COM_SDK comes with a version specific PHP include. It defines the COM Module, as well as the most commonly used attributes.

<?php
if(php_sapi_name() !== 'cli')
   exit(0);

include_once("aw_sdk_125.php");
…
?>

Loading the COM_SDK

It is handy to keep a reference to the loaded COM_SDK module as GLOBAL variable of PHP, since you will need it in your own sub-functions and classes. The definition of AWSDK_CLASS or AW_BUILD, for example, is taken from the include file aw_sdk_xxx.php.

<?php
if(php_sapi_name() !== 'cli')
   exit(0);

include_once("aw_sdk_125.php");

// GLOBAL handle to the SDK
global $sdk;

// Load the COM module
$sdk = new COM(AWSDK_CLASS) or die ("Error loading SDK COM Module");

// Initialize the SDK
if ($rc = $sdk->aw_init (AW_BUILD))
    die ("Error initialzing SDK [".$rc."]");
…
?>

App specific definitions

It's handy to use an application specific definition file, defining static parameters used by your application, easy to change later. Include this definition file to you PHP main file. An example of my_app_config.php:

<?php
if(php_sapi_name() !== 'cli')
   exit(0);

define('MYAPP_HOST', 'auth.activeworlds.com');
define('MYAPP_PORT', 6670);

define('MYAPP_LOGIN_OWNER', 123456);
define('MYAPP_LOGIN_PPWD', '<MyPrivilegePassword>');
define('MYAPP_LOGIN_NAME', 'MyApp');
define('MYAPP_LOGIN_APP', 'MyApp PHP-Script 2018 version 1.0 by William Rogers');

define('MYAPP_ENTER_WORLD', 'MyWorld');
define('MYAPP_ENTER_GLOBAL', 1);

define('WAIT_CYCLE', 1000); // in milliseconds

define('ONE_MINUTE', 60);   // in seconds
define('ONE_HOUR', 3600);
define('ONE_DAY', 86400);
define('ONE_WEEK', 604800);
define('ONE_MONTH', 18144000);   // in seconds or 30 days


?>

Create SDK Instance, Login and Enter World

The code below creates an App Instance, authenticates your App credentials with the universe, and finally enters a world. In most cases it will not be necessary to show an avatar in world, unless you're using non-privileged authentication credentials. Privileged authentication credentials are Universe Administrators or Caretakers of the entered world.

<?php
if(php_sapi_name() !== 'cli')
   exit(0);

include_once("aw_sdk_125.php");
include_once("my_app_config.php");

// GLOBAL handle to the SDK
global $sdk;
// Load the COM module
$sdk = new COM(AWSDK_CLASS) or die ("Error loading SDK COM Module");
// Initialize the SDK
if ($rc = $sdk->aw_init (AW_BUILD))
    die ("Error initialzing SDK [".$rc".]");

// Create SDK App instance, connects to universe
if ($rc = $sdk->aw_create(MYAPP_HOST, MYAPP_PORT) )
    die("aw_create failed [".$rc."]");

// Authenticate with the universe
$sdk->aw_int_set(AW_LOGIN_OWNER, MYAPP_LOGIN_OWNER);
$sdk->aw_string_set(AW_LOGIN_PRIVILEGE_PASSWORD, MYAPP_LOGIN_PPWD);
$sdk->aw_string_set(AW_LOGIN_NAME, MYAPP_LOGIN_NAME);
$sdk->aw_string_set(AW_LOGIN_APPLICATION, MYAPP_LOGIN_APP);

if ($rc = $sdk->aw_login())
    die("aw_login failed [".$rc."]");

// optionally, retrieve first attributes
$sdk->aw_wait(WAIT_CYCLE);

// Enter your world
$sdk->aw_int_set(AW_ENTER_GLOBAL, MYAPP_ENTER_GLOBAL);
if ($rc = $sdk->aw_enter(MYAPP_ENTER_WORLD))
    die("Failed to enter world ".MYAPP_ENTER_WORLD." [".$rc."]");

// optionally, set an avatar's position in world
// and make the avatar visible to visitors
$sdk->aw_int_set(AW_MY_TYPE, 0);
$sdk->aw_int_set(AW_MY_X, 1000);
$sdk->aw_int_set(AW_MY_Y, 400);
$sdk->aw_int_set(AW_MY_Z, 1000);
$sdk->aw_int_set(AW_MY_YAW, 0);
$sdk->aw_state_change();

// optionally, retrieve world attributes and events
$sdk->aw_wait(WAIT_CYCLE);

…
?>

Event and Callback Listener

PHP handles events and callbacks via a sink interface to COM. Events will call your application defined functions of your event sink class applied to the PHP COM Module.

class SDKEventSinker
{
    function EventDialogAnswer()
    {
        global $sdk;

        // do something here, example:
        $session = $sdk->aw_int(AW_DLG_ANSWER_RECIPIENT_SESSION);
        $answer = $sdk->aw_int(AW_DLG_ANSWER_OPTION);
        echo "EventDialogAnswer $session | $answer \n";
    }

    function EventAvatarAdd()
    {
        global $sdk;

        // do something here, example:
        $name = $sdk->aw_string(AW_AVATAR_NAME);
        $citizen = $sdk->aw_int(AW_AVATAR_CITIZEN);
        echo "EventAvatarAdd $citizen | $name\n";
    }
    function EventAvatarDelete()
    {
        global $sdk;

        // do something here, example:
        $name = $sdk->aw_string(AW_AVATAR_NAME);
        $citizen = $sdk->aw_int(AW_AVATAR_CITIZEN);
        echo "EventAvatarDelete $citizen | $name\n";
    }

} // class SDKEventSinker


… somewhere in your PHP main script

// Create and instance of the event sink class
$sink = new SDKEventSinker();

// PHP method to assign your event sink $sink class to the handle of the [[COM_SDK]] $sdk.
com_event_sink($sdk, $sink, AWSDK_CLASS);

// Enable the events for the SDK, which must be defined in your event sink class:
$sdk->aw_event_set(AW_EVENT_AVATAR_ADD);
$sdk->aw_event_set(AW_EVENT_AVATAR_DELETE);
$sdk->aw_event_set(AW_EVENT_DIALOG_ANSWER);

Example

The example below is a simple dialog asking all citizens in a world "Do you like Activeworlds?" and retrieve the answers. Dialogs can be in particular useful within a game flow, to query decisions from players and determining the game's flow.

<?php
if(php_sapi_name() !== 'cli')
   exit(0);

include_once("aw_sdk_125.php");
include_once("my_app_config.php");

// GLOBAL handle to the SDK
global $sdk;

// App specific global variables
global $sessionsInWorld;
$sessionsInWorld = array();

// App specific event handler
class SDKEventSinker
{
    function EventDialogAnswer()
    {
        global $sdk;
        global $sessionsInWorld;

        // do something here, example:
        $session = $sdk->aw_int(AW_DLG_ANSWER_RECIPIENT_SESSION);
        $answer = $sdk->aw_int(AW_DLG_ANSWER_OPTION);

        if (isset($sessionsInWorld[$session])) {
            $name = $sessionsInWorld[$session];
            switch($answer) {
               case AW_DLG_OPTION_YES:
                   echo "EventDialogAnswer $session | $name likes Activeworlds \n";
                   break;
               case AW_DLG_OPTION_NO:
                   echo "EventDialogAnswer $session | $name does not like Activeworlds \n";
                   break;
               case AW_DLG_OPTION_CANCEL:
                   echo "EventDialogAnswer $session | $name cancelled the dialog \n";
                   break;
               case AW_DLG_OPTION_TIMEOUT:
                   echo "EventDialogAnswer $session | $name did not answer, dialog timeout \n";
                   break;
               default:
                   echo "EventDialogAnswer $session | $name | failure $answer \n";
                   break;
            }
        }
    }

    function EventAvatarAdd()
    {
        global $sdk;
        global $sessionsInWorld;

        // do something here, example:
        $name = $sdk->aw_string(AW_AVATAR_NAME);
        $citizen = $sdk->aw_int(AW_AVATAR_CITIZEN);
        $session = $sdk->aw_int(AW_AVATAR_SESSION);

        // send a dialog to the user
        $sdk->aw_int_set(AW_DLG_ORIGINATOR_SESSION, $sdk->aw_session());
        $sdk->aw_int_set(AW_DLG_RECIPIENT_SESSION, $session);
        $sdk->aw_int_set(AW_DLG_REFERENCE, $sdk->aw_session());
        $sdk->aw_int_set(AW_DLG_OPTION, AW_DLG_OPTION_YES | AW_DLG_OPTION_NO);
        $sdk->aw_string_set(AW_DLG_TITLE, "Survey");
        $sdk->aw_string_set(AW_DLG_TEXT, "Do you like Activeworlds?");
        $sdk->aw_dialog();

        $sessionsInWorld[$session] = $name;

        echo "EventAvatarAdd dialog sent to $citizen | $session | $name\n";

    }
    function EventAvatarDelete()
    {
        global $sdk;
        global $sessionsInWorld;

        // do something here, example:
        $name = $sdk->aw_string(AW_AVATAR_NAME);
        $citizen = $sdk->aw_int(AW_AVATAR_CITIZEN);
        $session = $sdk->aw_int(AW_AVATAR_SESSION);

        unset($sessionsInWorld[$session]);
        echo "EventAvatarDelete $citizen | $name\n";

    }

} // class SDKEventSinker


// Load the COM module
$sdk = new COM(AWSDK_CLASS) or die ("Error loading SDK COM Module");

// Initialize the SDK
if ($rc = $sdk->aw_init (AW_BUILD))
    die ("Error initialzing SDK [".$rc".]");

// Create and instance of the event sink class
$sink = new SDKEventSinker();

// PHP method to assign your event sink $sink class to the handle of the [[COM_SDK]] $sdk.
com_event_sink($sdk, $sink, AWSDK_CLASS);

// Enable the events for the SDK, defined in your event sink class:
$sdk->aw_event_set(AW_EVENT_AVATAR_ADD);
$sdk->aw_event_set(AW_EVENT_AVATAR_DELETE);
$sdk->aw_event_set(AW_EVENT_DIALOG_ANSWER);

// Create SDK App instance, connects to universe
if ($rc = $sdk->aw_create(MYAPP_HOST, MYAPP_PORT) )
    die("aw_create failed [".$rc."]");

// Authenticate with the universe
$sdk->aw_int_set(AW_LOGIN_OWNER, MYAPP_LOGIN_OWNER);
$sdk->aw_string_set(AW_LOGIN_PRIVILEGE_PASSWORD, MYAPP_LOGIN_PPWD);
$sdk->aw_string_set(AW_LOGIN_NAME, MYAPP_LOGIN_NAME);
$sdk->aw_string_set(AW_LOGIN_APPLICATION, MYAPP_LOGIN_APP);

if ($rc = $sdk->aw_login())
    die("aw_login failed [".$rc."]");

// optionally, retrieve first attributes
$sdk->aw_wait(WAIT_CYCLE);

// Enter your world
$sdk->aw_int_set(AW_ENTER_GLOBAL, MYAPP_ENTER_GLOBAL);
if ($rc = $sdk->aw_enter(MYAPP_ENTER_WORLD))
    die("Failed to enter world ".MYAPP_ENTER_WORLD." [".$rc."]");

// optionally, set an avatar's position in world
// and make the avatar visible to visitors
$sdk->aw_int_set(AW_MY_TYPE, 0);
$sdk->aw_int_set(AW_MY_X, 1000);
$sdk->aw_int_set(AW_MY_Y, 400);
$sdk->aw_int_set(AW_MY_Z, 1000);
$sdk->aw_int_set(AW_MY_YAW, 0);
$sdk->aw_state_change();

// optionally, retrieve world attributes and events

// this loop keeps the script running:
while (true) {
   if ($sdk->aw_wait(WAIT_CYCLE) == 0 && $sdk->aw_session() != 0) {
        // optionally execute scheduled methods
        // e.g. query the world or user list
   } else {
        // likely disconnected, probably check AW_DISCONNECT_REASON
        $sdk->aw_wait(WAIT_CYCLE * 5);
   }
}

?>