AMFPHP Scripting

From Flashpoint Datahub
Revision as of 20:09, 3 April 2025 by Al 2712 (talk | contribs) (Created page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

When curating, there's a chance you'll come across a game that requests a URL that returns a unique binary response with an application/x-amf header. This means the game is communicating with an AMFPHP server.

What is AMFPHP

AMFPHP is a PHP library that serializes ActionScript objects in a binary format, and it uses PHP classes to configure and serve the data. More in depth specifications can be found on its website https://amfphp.org/

Identifying AMFPHP Games

You should be able to check all of these in the Network tab, if these are true, it could use AMFPHP

  • The game makes a request with "gateway" in its url
  • The request payload of the PHP script contains a TargetURI
  • The script's Content-Type is application/x-amf

Here's an example of a game that uses AMFPHP, it's requesting gateway.php to return team data:

https://www.neopets.com/games/play_flash.phtml?va=&game_id=1288&width=670&height=600&quality=low

Notes Before Proceeding

Curating games that use AMFPHP requires the scripts PHP code to be recreated, which requires some PHP programing knowledge. Continue the tutorial if you're familiar with the PHP programing language. If at any point you need help or are confused on something, feel free to ask in the #hackers chat of the Flashpoint Discord. Below are also a few resources if you're interested in learning PHP:

https://www.php.net/docs.php

https://www.w3schools.com/php/

It's also expected that you've followed the Curation Tutorial to understand the curation process. Please follow that before moving on.

All games that use AMFPHP scripts must also have the mount parameter -extract --server=apache

Scripting Steps

You'll first want to create the gateway script where the game is requesting it. If your game is requesting the url without the .php extension, you should also make an htaccess file to redirect the request to your script.

Next you'll add the gateway code into the PHP script. The example code here can be used for most cases:

require dirname($_SERVER['DOCUMENT_ROOT']) . '/vendor/autoload.php';
$config = new Amfphp_Core_Config();
$voFolders = array(dirname(__FILE__) . '/vo/');
$config->pluginsConfig['AmfphpVoConverter'] = array('voFolders' => $voFolders);
$config->serviceFolders = array(dirname(__FILE__) . '/services/');
$gateway = Amfphp_Core_HttpRequestGatewayFactory::createGateway($config);
$gateway->service();
$gateway->output();

Explanation: This loads AMFPHP through Vendor and creates an AMFPHP config that sets the services folder so it can find the custom class scripts you make. The service function then runs the class function based on the requests, then the output function outputs the serialized response.

Next you'll make a services folder in the same folder as your gateway script. This is where you'll put custom class scripts the game requires, by reverse engineering the responses from the live site. There are several ways to go about this, which will be listed next.

AMFPHP Use Cases

In order to create the classes, it's first important to understand a few use cases and techniques for dealing with scripts.

TargetURIs

TargetURIs are the format containing the service and function name, separated by either a "." or "/". An example would be AltadorCupService.getTeamInfo, with AltadorCupService being the name of the Service, and getTeamInfo being the function in the service.

TargetURIs with more than 1 separator include additional directories to nest your service in. For example the TargetURI slxdev.cfc.BioChem.getAllModuleInfo would have BioChem.php at slxdev\cfc\BioChem.php, with getAllModuleInfo being the function it's calling.

Explicit Types

Some function may need to return objects with explicit types. This can be done by creating a class of the same name, or by using the FIELD_EXPLICIT_TYPE constant in the following example code:

$response = new stdClass();
$responseTypeField = Amfphp_Core_Amf_Constants::FIELD_EXPLICIT_TYPE;
$response->$responseTypeField = "flex.messaging.messages.AcknowledgeMessage";

The responseTypeField string would be changed to the type you are wanting to create.

Using the Explicit Type constant is also useful for types that have special characters, like ".".

Headers

Sometimes games will send an AMF request with headers. If so, you can access this data with the variable Amfphp_Core_Amf_Handler::$requestPacket->headers[0]->data;

Curated Examples

Listed bellow are some games in the Flashpoint database that use AMFPHP, and are a good reference for understanding the script format.

Game UUID
Bloons Super Monkey 2 0ea6fb47-3af9-4cbe-981d-ab47f37d5f79
mini racers 225eea1f-020a-4cc8-a1ac-0665e9bccad5
Sensory World be359a9b-4738-4932-ab70-6dd07f7f2eae
Fizzy's Lunch Lab: Fizzy's Balance Bots b0e4d5c8-8ed5-4177-a6af-5ba110305735