06.06.2013, 20:24
(
Last edited by lapayo; 29/06/2014 at 01:07 PM.
)
I wanted to share a nice plugin with you, that a friend of mine and I created.
With this plugin you can write SA-MP gamemodes using only PHP.
There was already a plugin that did this, but it appears to be down and the guy does not seem to be active anymore.
At the moment nearly all official 0.3x functions are supported in PHP.
Some functions, that returned values via reference have been changed, so that you do not have to work with references. You simply have to leave the references out and the function will return an associative array containing the values.
Example: GetPlayerPos($playerid) returns [x => 0.0, y => 0.0, z => 0.0].
Using PHP allows you to write much cleaner code than you could do with Pawn and due to PHPs dynamic nature it should be much more comfortable. (No need to convert between data types, dynamic growing arrays, associative arrays, just to give a few examples)
Also PHP comes up with a lot of native functions for that you would normally need many extra plugins (MySQL, RegEx, FTP, time functions, file functions and so on. :)) what sometimes even don’t work that well.
Also this bundle contains some functions, that you don’t even have when using Pawn, like PDO with prepared statements or you could even use a third party ORM like Doctrine, so you can have very easy and secure database access (For many database types, not only MySQL).
But this is not everything, now a gamemode would look like a pawn gamemode with PHP syntax and some php functions.
PHP has a very cool feature: OOP.
Unfortunately the SA-MP functions are all made for procedural programming.
But we have developed something that eliminates this flaw when creating gamemodes with PHP.
We have created a whole framework in PHP that helps you create very cool and extensible gamemodes.
Let me give you an example:
In pawn you would write:
This is very much code for such a simple task. So in plain PHP this would look like:
And now using PHP in connection with our framework it looks like:
This is not only much shorter, but also much more fluent. Also you can have as many Event::on(‘PlayerConnect’) as you want in your code and not only one like with pawn or plain php.
This give you the ability to perfectly separate your logics when your code grows.
But lets talk about another feature of the framework:
Dialogs in SA-MP can get somewhat complicated, because you have to deal with ids, put everything in one OnDialogResponse, have to maintain ids and the according values and so on.
We have created a new way of showing a dialog:
I think you can see the advantages. You have the rowtext and the according value on one line, so you do not have to deal with row numbers and breaking your code when you have to insert a new line in the beginning.
Also you dont have to deal with DIALOG_IDs and sorting out the right one in the OnDialogResponse callback. Also you have the response action directly with the dialog code and not 3000 lines below in the OnDialogResponse callback.
So dealing with dialogs gets much easier and less error-prone.
Thanks to the fact that you dont have to deal with dialog ids you can also have an unlimited amount of dialogs and can also create dialogs on demand for example in a callback.
Also adding commands is much easier with the framework than in pawn.
You simply have to add the following somewhere in the gamemode file:
This function automatically listens for /vehicle, /v and /veh and calls the callback when the user enters this command. Then it gets the players position and rotations and spawns a vehicle right in the player.
Also in Pawn you often have to create many arrays to store information about the player.
Using our framework this gets much easier:
Lets say you are in the command callback above and have the player instance in $player:
Now you want to temporarily store an information about this player. In Pawn you would create an array:
and then do
and on player disconnect you have to reset this value.
With our framework you dont have to define anything.
Simply take the player instance $player and call:
Thats it. As soon as the player disconnects, the framework will automatically delete all the information stored in this instance, so you dont have to deal with cleaning up.
Especially when you have more and more arrays this gets very comfortable and way easier to maintain. Also it gets less error-prone because you cant forget cleaning up. When you have very many arrays it might also get less memory consuming than pawn, because it doesnt take up space, as long as you dont save anything inside the instance, where in pawn it always takes the full memory even if no player is connected.
Another cool feature concering event management is:
Lets say you have an event especially for one player, than you could watch Event::on(‘PlayerUpdate’) and sort out all the wrong players or you use the following way:
There are many other cool functions, just check them out.
Unfortunately there is no documentation for the framework right now, but itґs pretty easy to learn when you simply look which functions exist on the classes. (Look inside the server-files/php/core folder)
If you want to see it in action, take a look at this file: https://github.com/Lapayo/SAMPHP/blo...c/gamemode.php
This script provides the same functionality as the grandlarc gamemode from the samp examples, but is much shorter and in my opinion much cleaner and also easier to understand and to change.
Installation
Linux
1. Download the bundle (See link below)
2. Extract it into a directory.
3. Move the files/folders from the server-folder directory to your server folder
4. Add “plugins samphp” to your server.cfg
5. If you get an “missing libphp5.so” error see "Installing libphp5.so"
(6. You should set gamemode0 to "empty")
Installing libphp5.so
There are two ways for installing libphp5.so:
1. Download the bundle (See link below)
2. Extract it into a directory.
3. Move the files/folders from the server-folder directory to your server folder
4. Add “plugins samphp” to your server.cfg
5. If you get a message that "msvcr110.dll" is missing, you have to install http://www.microsoft.com/de-de/downl....aspx?id=30679
(6. You should set gamemode0 to "empty")
Start coding
First way: Simply create a gamemode.php inside the php folder, include “core/bootstrap.php” and start coding your php gamemode. :-)
Second way:
1. Create a folder "mygamemode" inside the php folder and create a gamemode.php inside this folder, include “core/bootstrap.php” and start coding your php gamemode. :-)
2. Add "samphpmode mygamemode" to your server.cfg
Links:
GitHub
ChangeLog
New Binary Build by erorcun:
http://forum.sa-mp.com/showthread.ph...40#post3036240
Downloads for Debian/Ubuntu/Linux Mint x86/x86_64:
1. Clone the GitHub repository to your harddrive.
2. Install SAMP GDK.
3. Install libphp5 using the script.
4. start build.sh in the samphp folder.
5. Copy the created samphp file to your plugins folder.
Thanks for your interest and reading this very long post.
If you have any recommendations for this project, found a bug, or still know something, that is complicated or you have a “vision” how things could work more easily, just leave a post in this thread or open a issue at GitHub. :-)
Simon :-)
Successfully tested on
- Debian 7 x86
- Debian 7 x86_64 (using precompiled Debian/Ubuntu x86 libphp5.so)
- Ubuntu 13.04 x86_64
- Linux Mint 14 x86
- CentOS 5.9 x86
- Windows 7 Enterprise 64 bit
With this plugin you can write SA-MP gamemodes using only PHP.
There was already a plugin that did this, but it appears to be down and the guy does not seem to be active anymore.
At the moment nearly all official 0.3x functions are supported in PHP.
Some functions, that returned values via reference have been changed, so that you do not have to work with references. You simply have to leave the references out and the function will return an associative array containing the values.
Example: GetPlayerPos($playerid) returns [x => 0.0, y => 0.0, z => 0.0].
Using PHP allows you to write much cleaner code than you could do with Pawn and due to PHPs dynamic nature it should be much more comfortable. (No need to convert between data types, dynamic growing arrays, associative arrays, just to give a few examples)
Also PHP comes up with a lot of native functions for that you would normally need many extra plugins (MySQL, RegEx, FTP, time functions, file functions and so on. :)) what sometimes even don’t work that well.
Also this bundle contains some functions, that you don’t even have when using Pawn, like PDO with prepared statements or you could even use a third party ORM like Doctrine, so you can have very easy and secure database access (For many database types, not only MySQL).
But this is not everything, now a gamemode would look like a pawn gamemode with PHP syntax and some php functions.
PHP has a very cool feature: OOP.
Unfortunately the SA-MP functions are all made for procedural programming.
But we have developed something that eliminates this flaw when creating gamemodes with PHP.
We have created a whole framework in PHP that helps you create very cool and extensible gamemodes.
Let me give you an example:
In pawn you would write:
PHP Code:
public OnPlayerConnect(playerid)
{
//Get the name of the player that connected and display a join message to other players
new name[MAX_PLAYER_NAME+1], string[24+MAX_PLAYER_NAME+1];
GetPlayerName(playerid, name, sizeof(name));
format(string, sizeof(string), "%s has joined the server.", name);
SendClientMessageToAll(0xC4C4C4FF, string);
return 1;
}
PHP Code:
function OnPlayerConnect($playerid)
{
//Get the name of the player that connected and display a join message to other players
$playername = GetPlayerName($playerid);
SendClientMessageToAll(0xC4C4C4FF, "$playername has joined the server.");
return true;
}
PHP Code:
Event::on('PlayerConnect', function($player)
{
SendClientMessageToAll(0xC4C4C4FF, $player->getName()." has joined the server.");
});
This give you the ability to perfectly separate your logics when your code grows.
But lets talk about another feature of the framework:
Dialogs in SA-MP can get somewhat complicated, because you have to deal with ids, put everything in one OnDialogResponse, have to maintain ids and the according values and so on.
We have created a new way of showing a dialog:
PHP Code:
Dialog::createList("Spawn Vehicle", "Okay", "Oh no")
->addRow("Stallion", 439)
->addRow("Pizzaboy", 448)
->addRow("Turismo", 451)
->addRow("Flatbed", 455)
->addRow("Yankee", 456)
->on("Success", function($player, $dialog, $id) {
$pos = $player->getPos();
$facing = $player->getFacingAngle();
$vehicle = Vehicle::create($id, $pos->x, $pos->y, $pos->z, $facing);
$player->putInVehicle($vehicle);
})->showPlayer($player);
Also you dont have to deal with DIALOG_IDs and sorting out the right one in the OnDialogResponse callback. Also you have the response action directly with the dialog code and not 3000 lines below in the OnDialogResponse callback.
So dealing with dialogs gets much easier and less error-prone.
Thanks to the fact that you dont have to deal with dialog ids you can also have an unlimited amount of dialogs and can also create dialogs on demand for example in a callback.
Also adding commands is much easier with the framework than in pawn.
You simply have to add the following somewhere in the gamemode file:
PHP Code:
CommandText::register(['/vehicle', '/v', '/veh'], function($player, $params) {
$pos = $player->getPos();
$facing = $player->getFacingAngle();
$vehicle = Vehicle::create($params, $pos->x, $pos->y, $pos->z, $facing);
$player->putInVehicle($vehicle);
});
Also in Pawn you often have to create many arrays to store information about the player.
Using our framework this gets much easier:
Lets say you are in the command callback above and have the player instance in $player:
Now you want to temporarily store an information about this player. In Pawn you would create an array:
PHP Code:
new gIsCheater[MAX_PLAYERS];
PHP Code:
gIsCheater[playerid] = true;
With our framework you dont have to define anything.
Simply take the player instance $player and call:
PHP Code:
$player->isCheater = true;
Especially when you have more and more arrays this gets very comfortable and way easier to maintain. Also it gets less error-prone because you cant forget cleaning up. When you have very many arrays it might also get less memory consuming than pawn, because it doesnt take up space, as long as you dont save anything inside the instance, where in pawn it always takes the full memory even if no player is connected.
Another cool feature concering event management is:
Lets say you have an event especially for one player, than you could watch Event::on(‘PlayerUpdate’) and sort out all the wrong players or you use the following way:
PHP Code:
$player->on(‘Update’, function($player) {
echo “Only called for “.$player->getName();
});
Unfortunately there is no documentation for the framework right now, but itґs pretty easy to learn when you simply look which functions exist on the classes. (Look inside the server-files/php/core folder)
If you want to see it in action, take a look at this file: https://github.com/Lapayo/SAMPHP/blo...c/gamemode.php
This script provides the same functionality as the grandlarc gamemode from the samp examples, but is much shorter and in my opinion much cleaner and also easier to understand and to change.
Installation
Linux
1. Download the bundle (See link below)
2. Extract it into a directory.
3. Move the files/folders from the server-folder directory to your server folder
4. Add “plugins samphp” to your server.cfg
5. If you get an “missing libphp5.so” error see "Installing libphp5.so"
(6. You should set gamemode0 to "empty")
Installing libphp5.so
There are two ways for installing libphp5.so:
First way:Windows1. Download the binary for your OS from a link below.Second way:
2. Copy the contained libphp5.so to /usr/local/lib
3. Run ldconfig
(On CentOS 5.9: "/sbin/ldconfig /usr/local/lib"
4. Done. :-)1. Install libxml2-dev and other build tools like gcc and headers
2. Run "install_libphp.sh" as root (Downloads, compiles and installs libphp5.so)
3. Done.
1. Download the bundle (See link below)
2. Extract it into a directory.
3. Move the files/folders from the server-folder directory to your server folder
4. Add “plugins samphp” to your server.cfg
5. If you get a message that "msvcr110.dll" is missing, you have to install http://www.microsoft.com/de-de/downl....aspx?id=30679
(6. You should set gamemode0 to "empty")
Start coding
First way: Simply create a gamemode.php inside the php folder, include “core/bootstrap.php” and start coding your php gamemode. :-)
Second way:
1. Create a folder "mygamemode" inside the php folder and create a gamemode.php inside this folder, include “core/bootstrap.php” and start coding your php gamemode. :-)
2. Add "samphpmode mygamemode" to your server.cfg
Links:
GitHub
ChangeLog
New Binary Build by erorcun:
http://forum.sa-mp.com/showthread.ph...40#post3036240
Downloads for Debian/Ubuntu/Linux Mint x86/x86_64:
SAMPHP Binary: http://www.sney.net/files/samphp-release-linux.zipDownloads for CentOS 5.9 x86/x86_64:
libphp5.so: http://www.sney.net/files/libphp5.so.zip
SAMPHP Binary: http://www.sney.net/files/samphp-release-centos.zipDownloads for Windows:
libphp5.so: http://www.sney.net/files/libphp5.so_centos.zip
SAMPHP Binary: http://www.sney.net/files/samphp-release-windows.zipCompiling SAMPHP on your own: Linux
1. Clone the GitHub repository to your harddrive.
2. Install SAMP GDK.
3. Install libphp5 using the script.
4. start build.sh in the samphp folder.
5. Copy the created samphp file to your plugins folder.
Thanks for your interest and reading this very long post.
If you have any recommendations for this project, found a bug, or still know something, that is complicated or you have a “vision” how things could work more easily, just leave a post in this thread or open a issue at GitHub. :-)
Simon :-)
Successfully tested on
- Debian 7 x86
- Debian 7 x86_64 (using precompiled Debian/Ubuntu x86 libphp5.so)
- Ubuntu 13.04 x86_64
- Linux Mint 14 x86
- CentOS 5.9 x86
- Windows 7 Enterprise 64 bit