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
15-02-11
spikensbror
Re: BillingAPI (With instant send, etc)
Optimized the API.
Version 1.5 is available on top post!
18-02-11
spikensbror
Re: BillingAPI (With instant send, etc)
I would appreciate some feedback on the new code.
18-02-11
R3fl3x
Re: BillingAPI (With instant send, etc)
Quote:
Originally Posted by spikensbror
I would appreciate some feedback on the new code.
If your inventory is full, you won't get the items (not via mail or relog [= sent via MSSQL table])
There should be a function to check for it.
Btw.: Checking the INVENTORY_TBL for the inventory being full won't help since it just reloads when you relog or when the server is doing the regular save.
If you would have a cool tipp on this issue, the api would be more than insanely good :D
18-02-11
rockzz
Re: BillingAPI (With instant send, etc)
For me the send via mssql if char isn't logging in is not working correctly its inserting it in the ITEM_SEND_TBL but with the wrong id and I don't know why if the char is logged in it's working fine
19-02-11
spikensbror
Re: BillingAPI (With instant send, etc)
What ID should it insert and what is it inserting?
19-02-11
Treachery
Re: BillingAPI (With instant send, etc)
I noticed this myself. If the ID was greater than 0000007, then it would read it as 0. If I just put in 8, for example, then it would work contrary to putting in 0000008.
19-02-11
rockzz
Re: BillingAPI (With instant send, etc)
Quote:
Originally Posted by spikensbror
What ID should it insert and what is it inserting?
As example when I buy the item with ID 26455 (Gold Battery) than in the ITEM_SEND_TBL it's item ID 87 and this can't be send
And there is another bug if your character have full inventory like r3fl3x said
I will try to fix the thing with the item id wrong later but with the bug r3fl3x mentioned I have no idea about how to fix because I don't know anything about the billing function in the source so I don't know how to check if the char has full inventory EDIT: maybe it would be a good idea to send the items via postbox if inventory is full
EDIT2:
I got the think with mssql to work now only the think with full inventory is there to fix now
19-02-11
Jub
Re: BillingAPI (With instant send, etc)
There are other ways (just as efficient ways/just as fast ways) to do the API without opening ports. Personally I find the socket part of this API not needed, but I suppose you have your reasons.
Although I like how you are packing the data to increase the speed of the API (smart).
Nice job.
19-02-11
spikensbror
Re: BillingAPI (With instant send, etc)
The socket part of the API has to do with getting items to players that are logged in, instantly.
If you would've tried it, you would've known.
Anyways, v1.6 is up, fixed up the data formats on the procedure bindings as well as added documentation and better examples.
20-02-11
Sanctin
Re: BillingAPI (With instant send, etc)
Thanks, I like the 1.6
10-03-11
ZappeL
Re: BillingAPI (With instant send, etc)
Hi spikensbror, i've ported our code to the actual sqlsrv module because mssql functions are not supported in php 5.3
Here is the rewrite of our code(nice release :thumbup:):
billing.api.php:
PHP Code:
<?php
/*************************************
* addBill-API (spikensbror) *
* API-rewrite and Port by *
* ZappeL 2011 *
*************************************/
If u disagree with this post, let me know it. I'm not a leecher.. ;)
But maybe you put this code-snippets in your main post.. ;)
But i've a little question: the socket command to provide the bill directly to the char is clear, but do you know if there is a command to remove an item from a char?
regards,
ZappeL
11-03-11
spikensbror
Re: BillingAPI (With instant send, etc)
I got mssql functions running on PHP 5.3 as I developed and tested this using the PHP 5.3 API.
11-03-11
ZappeL
Re: BillingAPI (With instant send, etc)
Yes, i on my linux machine it runs fine, but on winslow, i decided to use the M$ sql-functions.. because the php_mssql.dll is missing in the installers. If u re interested, here is the M$ link: MS-Downloadpage
Uhm, but the last question is still unanswerd.. ;) If there is a Command to remove items instantly (via socket) from the inventory..
11-03-11
spikensbror
Re: BillingAPI (With instant send, etc)
Updated to 1.7.
New features:
- Mails the player the item if they are offline or if their inventory is full.
11-03-11
rockzz
Re: BillingAPI (With instant send, etc)
What exactly did you change in V1.7 so I could edit it manually in the api that I have already edited for my usage
11-03-11
spikensbror
Re: BillingAPI (With instant send, etc)
Just a change to the internal MsSQL send function.
12-03-11
MercAngel
Re: BillingAPI (With instant send, etc)
i get the item in the inv but the script locks up until it times out
13-05-11
DeadMouse
Re: BillingAPI (With instant send, etc)
How did you make the script reload or whatever the database of the character?
Because this should work for example with
penya, stats etc...
Correct me if im wrong
and help me if im correct!
Please!
13-05-11
asakapa1
Re: BillingAPI (With instant send, etc)
DO NOT USE IT !
IT IS OPEN PORT 29000 FOR ANY ONE CAN USE PHP SCRIPT TO SEND ITEM TO PLAYER
MEAN , OPEN PORT 29000 FOR HACK ! loool
14-05-11
Emkyub
Re: BillingAPI (With instant send, etc)
@asa
lol, it depends how you manage your port, its just you are a nab, :S
14-05-11
rtosoftware
Re: BillingAPI (With instant send, etc)
Quote:
Originally Posted by asakapa1
DO NOT USE IT !
IT IS OPEN PORT 29000 FOR ANY ONE CAN USE PHP SCRIPT TO SEND ITEM TO PLAYER
MEAN , OPEN PORT 29000 FOR HACK ! loool
Use it :lol:
You don't need to open the port 29000.