About
BillingAPI is a pretty fail-safe API which concentrates on providing a safe platform for cash-shops to build upon.
Features
What BillingAPI does, is send items to players in a safe manner.
If the player is online and logged in, it sends the item using the adbill protocol, which means the user will receive it instantly.
If they are not online, or if their inventory is full, the item will be mailed to them. (New in version 1.7)
Example
Here's a small example of how it can be used.
Spoiler:
Sending a single item:
PHP Code:
<?php
// Include the API. include("./api/procedural.php");
// Create a connection to MsSQL and select the character database. $mssql_socket = mssql_connect("SQL Server", "Username", "Password", false); mssql_select_db("CHARACTER_01_DBF", $mssql_socket);
// Send the item. billing_send_item("127.0.0.1", $mssql_socket, $adbill_object);
// Close MsSQL connection. mssql_close($mssql_socket);
?>
Sending multiple items:
PHP Code:
<?php
// Include the API. include("./api/procedural.php");
// Create a connection to MsSQL and select the character database. $mssql_socket = mssql_connect("SQL Server", "Username", "Password", false); mssql_select_db("CHARACTER_01_DBF", $mssql_socket);
// Close MsSQL connection. mssql_close($mssql_socket);
?>
Note
You are responsible for filtering eventual data being inputted into the API.
The API has no filtering functions and will never have.
The API
Copy and paste this into a PHP document and you're ready to go.
Don't forget to include the API in the script that will use the API functions.
PHP Code:
<?php
// FlyFF Billing API Version 1.7 // Copyright (C) 2011, SpikensbroR.
// Optimized procedural billing API.
// Sends a single item to a player. function billing_send_item($billing_ip, $mssql_socket, $adbill_object) { // Create a connection to the adbill server. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_connect($socket, $billing_ip, 29000);
// If any connections failed, return false. if(!$socket || !$mssql_socket) { return false; }
// Send item through adbill first, if that fails, send through MsSQL. if(!billing_internal_adbill_send($socket, $adbill_object)) { billing_internal_mssql_send($mssql_socket, $adbill_object); }
// Close socket. socket_close($socket);
// Everything went well, return true. return true; }
// Sends multiple items to a player. function billing_send_items($billing_ip, $mssql_socket, $adbill_objects) { // Create a connection to the adbill server. $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_connect($socket, $billing_ip, 29000);
// If any connections failed, return false. if(!$socket || !$mssql_socket) { return false; }
// Define a variable to specify if on first loop. $first_loop = true;
// Define a variable to specify wether user is on or not. $user_online = true;
// For every adbill object in the adbill object array. foreach($adbill_objects as $adbill_object) { // If iterator is on the first loop through. if($first_loop) { // Specify that first loop is done. $first_loop = false;
// If sending the item through adbill fails, set the user status to offline. if(!billing_internal_adbill_send($socket, $adbill_object)) { $user_online = false; } // If not, skip the rest of the loop and begin on the next object. else { continue; } }
// If user is online, send through adbill. if($user_online) { billing_internal_adbill_send($socket, $adbill_object); } // If not, send through MsSQL. else { billing_internal_mssql_send($mssql_socket, $adbill_object); } }
// Close socket. socket_close($socket);
// Everything went well, return true. return true; }
// Creates an adbill item object. function billing_create_item($server_index, $player_id, $item_id, $item_count) { return new AdbillObject($server_index, $player_id, $item_id, $item_count); }
// Internal procedural operations.
// Mails the item to the player. function billing_internal_mssql_send($mssql_socket, $adbill_object) { // Initialize the procedure. $procedure = mssql_init("[dbo].[uspMailItemToCharacter]", $mssql_socket);
// Execute and free memory. mssql_execute($procedure); mssql_free_statement($procedure); }
// Internal abill protocol operation. function billing_internal_adbill_send($billing_socket, $adbill_object) { // Construct the packet from the adbill object data. $packet = pack("VVVVV", $adbill_object->server_index, $adbill_object->player_id, 0000001, $adbill_object->item_id, $adbill_object->item_count) . str_pad("", 24, ' ') . pack("V", 0);
// Write the packet to the socket. socket_write($billing_socket, $packet, 48);
// Create a receive buffer. $buffer = "";
// If socket failed to receive to the buffer, return false. if(!socket_recv($billing_socket, $buffer, 2048, MSG_WAITALL)) { return false; }
// Retrieve the return value from the buffer. $return = unpack("V", substr($buffer, strlen($buffer) - 4));
// Return the value. return (bool)$return[1]; }
// Adbill item object. class AdbillObject { // Server index holder. public $server_index = null;
// Player id holder. public $player_id = null;
// Item id and count holders. public $item_id = null; public $item_count = null;
// Constructor. public function __construct($server_index, $player_id, $item_id, $item_count) { // Set all values. $this->server_index = $server_index; $this->player_id = $player_id; $this->item_id = $item_id; $this->item_count = $item_count; } }
?>
You will also need this stored procedure, as it will enable the API to mail the player if their inventory is full, or if they are offline:
Code:
USE [CHARACTER_01_DBF]
GO
/****** Object: StoredProcedure [dbo].[uspMailItemToCharacter] Script Date: 03/11/2011 16:54:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE proc [dbo].[uspMailItemToCharacter]
@serverindex CHAR(2),
@idPlayer CHAR(7) = '0000000',
@idItem INT = 21,
@numItem INT = 1
as
set nocount on
declare @iserverindex char(2)
set @iserverindex = cast((cast(@serverindex as int) + 50) as char(2))
DECLARE @bBinds int
SET @bBinds = 0
-- ?? ??? ?? ??
DECLARE @nMaxMailID int
SELECT @nMaxMailID = MAX(nMail)+1 from MAIL_TBL where serverindex = @iserverindex
SET @nMaxMailID = ISNULL( @nMaxMailID, 0 )
-- ??? ??
DECLARE @szTitle VARCHAR(128)
DECLARE @szText VARCHAR(1024)
SET @szTitle = 'Cash Shop'
SET @szText = ''
Sends multiple items to the adbill server/mssql database.
Code:
$billing_ip - The IP to the billing server.
$mssql_socket - Link identifier to a mssql connection.
$adbill_objects - An array of item objects to be sent.
$server_index - Server index of the player that the item should be sent to.
$player_id - ID of the player that the item should be sent to.
$item_id - ID of the item to be sent.
$item_count - Amount of items to be sent.
13-02-11
VLxTormented
Re: BillingAPI (With instant send, etc)
is this a part of etunia ?
13-02-11
spikensbror
Re: BillingAPI (With instant send, etc)
Nope, I made it today.
13-02-11
zcoolmax
Re: BillingAPI (With instant send, etc)
nice release ^^
more
When adding values to column m_nAbilityOption,nUMPiercedSize the data fail
how to fix add values to column m_nAbilityOption,nUMPiercedSize
13-02-11
spikensbror
Re: BillingAPI (With instant send, etc)
What are you talking about?
13-02-11
VLxTormented
Re: BillingAPI (With instant send, etc)
Awesome :) ! Ill test if it works ;o!
13-02-11
spikensbror
Re: BillingAPI (With instant send, etc)
I tested it, and it works for me.
Just give me the word if you don't have the procedure and I'll upload it.
14-02-11
Nick1337
Re: BillingAPI (With instant send, etc)
I like the idea of it.
Amazing coding skills as always :)
14-02-11
djhulk001
Re: BillingAPI (With instant send, etc)
This is a nice release. How you came with the idea?
14-02-11
VLxTormented
Re: BillingAPI (With instant send, etc)
How he came with this idea ? Lmfao
It's probably cause most servers give donations manually o.o
---------- Post added at 10:39 AM ---------- Previous post was at 10:05 AM ----------
Is it possible to add this to Treachery's Shop Thing ?
14-02-11
caja
Re: BillingAPI (With instant send, etc)
Quote:
Originally Posted by VLxTormented
[/COLOR]Is it possible to add this to Treachery's Shop Thing ?
Yes, it's not very difficult.
14-02-11
rockzz
Re: BillingAPI (With instant send, etc)
It's not working for me it's always giving 'NOT ON1' back to me but my character is logged in and how to find out the billing port? of my account server if i change it from 29000 to 28000 it's giving me out other errors
14-02-11
Detox
Re: BillingAPI (With instant send, etc)
It's easy adding it to Treachery's shop thing.
Just use the "cash" column at Account table ;)
15-02-11
Mootie
Re: BillingAPI (With instant send, etc)
1. I don't know why spiken posted this, we worked together on this method and I told him not to release it. The actual implementation is pretty, yeah. It's kind of useless though(the excessive object oriented structuring for such a small application), the performance a simple <3ms operation(including send/receive). I find it kinda ridiculous to use all of those static calls for the a call that takes less than 3ms to complete(it probably would be faster just to make a simple dynamic function if you want to get technical).
In PHP, a static value is only stored for the duration of the PHP call(usually a few ms). The only useful implementation of such static functions/variables in php is in large(huge) applications like vBulletin or IPB. Even then, they would usually use an external cache engine for storing static data. PHP isn't meant for instancing in general, its best to avoid static calls for the most part.
Not like anyone here except spiken understood that... Oh well.
15-02-11
R3fl3x
Re: BillingAPI (With instant send, etc)
Found one bug. If your inventory is full, you won't get the item.
Currently looking for a solution, if you got something, let me know :x