SA-MP Gamemodes with PHP
#1

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:
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(playeridnamesizeof(name));
    
format(stringsizeof(string), "%s has joined the server."name);
    
SendClientMessageToAll(0xC4C4C4FFstring);
    return 
1;

This is very much code for such a simple task. So in plain PHP this would look like:
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;

And now using PHP in connection with our framework it looks like:
PHP Code:
Event::on('PlayerConnect', function($player)
{
    
SendClientMessageToAll(0xC4C4C4FF$player->getName()." has joined the server.");
}); 
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:
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); 
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:

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);
}); 
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:
PHP Code:
new gIsCheater[MAX_PLAYERS]; 
and then do
PHP Code:
gIsCheater[playerid] = true
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:
PHP Code:
$player->isCheater true
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:
PHP Code:
$player->on(‘Update’, function($player) {
    echo 
“Only called for .$player->getName();
}); 
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:
First way:
1. Download the binary for your OS from a link below.
2. Copy the contained libphp5.so to /usr/local/lib
3. Run ldconfig
(On CentOS 5.9: "/sbin/ldconfig /usr/local/lib"
4. Done. :-)
Second way:
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.
Windows
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.zip
libphp5.so: http://www.sney.net/files/libphp5.so.zip
Downloads for CentOS 5.9 x86/x86_64:
SAMPHP Binary: http://www.sney.net/files/samphp-release-centos.zip
libphp5.so: http://www.sney.net/files/libphp5.so_centos.zip
Downloads for Windows:
SAMPHP Binary: http://www.sney.net/files/samphp-release-windows.zip
Compiling 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
Reply
#2

I like what I am seeing. A nice usage of OOP.
Reply
#3

This is totally awesome. It's your first post :0
Reply
#4

This is really an awesome plugin, even though im not into PHP, i can see the great work done here
good job
Reply
#5

This is amazing.

Digging into it now~

~Whats the lowest compatible version of PHP? Or what version was it scripted on?

This may be an error on my part, but trying to start a server with it plugged in I get this.

Code:
[01:46:38]  Loading plugin: samphp
[01:46:38]   Failed (plugins/samphp: ELF file OS ABI invalid)
[01:46:38]  Loaded 0 plugins.
Reply
#6

This is amazing, does it use the PHP Version on the server box or is it it's own "version"?
Reply
#7

Quote:
Originally Posted by Rsmiley
View Post
This is amazing.

Digging into it now~

~Whats the lowest compatible version of PHP? Or what version was it scripted on?

This may be an error on my part, but trying to start a server with it plugged in I get this.

Code:
[01:46:38]  Loading plugin: samphp
[01:46:38]   Failed (plugins/samphp: ELF file OS ABI invalid)
[01:46:38]  Loaded 0 plugins.
The framework requires PHP 5.4, but without the framework you can also use 5.3.
But here PHP doesnt seem to be the problem, but the binary seems to be incompatible to your os. What Linux are you running?
Quote:
Originally Posted by Memoryz
View Post
This is amazing, does it use the PHP Version on the server box or is it it's own "version"?
It uses the php from the installed shared php library. If you have other programms using the shared library the both use the same version, but I dont know any software that uses the php embed library.
Reply
#8

Quote:
Originally Posted by lapayo
View Post
The framework requires PHP 5.4, but without the framework you can also use 5.3.
But here PHP doesnt seem to be the problem, but the binary seems to be incompatible to your os. What Linux are you running?
Well, I'm running PHP 5.3.22 and Operating system: CentOS Linux 5.9

And I assume 5.3 wouldn't work, from this?

[root@meow samp2]# php php/gamemode.php
PHP Parse error: syntax error, unexpected T_STRING in /home/user/samp2/php/core/modelevent.php on line 2
Reply
#9

Pretty impressive ! I wish that you could make a Windows version for it. Good luck !
Reply
#10

Quote:
Originally Posted by Rsmiley
View Post
Well, I'm running PHP 5.3.22 and Operating system: CentOS Linux 5.9

And I assume 5.3 wouldn't work, from this?

[root@meow samp2]# php php/gamemode.php
PHP Parse error: syntax error, unexpected T_STRING in /home/user/samp2/php/core/modelevent.php on line 2
Well your problem doesnt seem to be based on the php version, because the loading of the plugin already fails.
I am trying to figure the problem out. What version are you using? 32 bit or 64 bit? At the moment it is only tested on Debian 7 32bit and Ubuntu 12.10 32bit.
(The last on is of course php related, but this isnt a problem, because samphp uses an independent php library )

Quote:
Originally Posted by Red_Dragon.
View Post
I wish that you could make a Windows version for it. Good luck !
Working on it.
Reply
#11

Quote:
Originally Posted by lapayo
View Post
Well your problem doesnt seem to be based on the php version, because the loading of the plugin already fails.
I am trying to figure the problem out. What version are you using? 32 bit or 64 bit? At the moment it is only tested on Debian 7 32bit and Ubuntu 12.10 32bit.
(The last on is of course php related, but this isnt a problem, because samphp uses an independent php library )
It's 32bit.
Reply
#12

Awesome, I'll give a try, thank you man.
Reply
#13

The best part is that MySQL is integrated into PHP and we can use it in this plugin. Very nice job!
Reply
#14

I just logged in to tell you that this is an awesome piece of software.

The idea is obviously great and the implementation looks excellent, you managed to create a great core structure!

I just have a couple of question:

- How does it work? Is the PHP thread kept always running and events are fired from the plugin? - just out of curiosity
- Have you made a trial running it for a long time and testing with some regular players? How did it went in terms of performance and such?
- Any Benchmarks yet?

Will be waiting for the Windows Version to test it out

> If you need an help with documentation of the core let me know, I'm willing to help! <

PHP is such a powerful language, that evolved so much since the early times, too bad some people still imagine it as a crappy functional language instead of the swiss army knife it is!

If you manage to get a cross-platform version of it and manage to keep it updated well, just forget PAWN, C++, .NET and Java.
I really really hope for the best for this project.

Heads up for this.
Reply
#15

Quote:
Originally Posted by Rsmiley
View Post
It's 32bit.
Okay, I am downloading a copy right now and will try to make it running tomorrow.

Quote:
Originally Posted by Whiteagle
View Post
How does it work? Is the PHP thread kept always running and events are fired from the plugin?
Yes, the PHP script including its environment stays in the memory as long as the server is running.
On events the plugin calls back in the PHP context
Quote:
Originally Posted by Whiteagle
View Post
Have you made a trial running it for a long time and testing with some regular players? How did it went in terms of performance and such?
Not really, I also dont really, I have a server running, but I restarted it very often because of new features
Iґll try to leave it running now
Quote:
Originally Posted by Whiteagle
View Post
Any Benchmarks yet?
No, but I will try to make some in the future, because this is something that is very interesting to me. But at first I have to complete some other tasks before I can concentrate on this.

Quote:
Originally Posted by Whiteagle
View Post
> If you need an help with documentation of the core let me know, I'm willing to help! <
Help would be really awesome. I will contact you when I start with the documentation

And thanks to everyone for the nice words
Reply
#16

Thank you lapayo!

I'll check back in later or tomorrow!
If you'd like any help with testing or anything (once its workin on CentOS that is), let me know and I'll do my best to assist
Reply
#17

Quote:
Originally Posted by Rsmiley
View Post
Thank you lapayo!

I'll check back in later or tomorrow!
If you'd like any help with testing or anything (once its workin on CentOS that is), let me know and I'll do my best to assist
I successfully compiled a version on centos 5.9
You can download it here:
http://www.sney.net/files/samphp-release-centos.zip

If you need the libphp5.so you can download it here:
http://www.sney.net/files/libphp5.so_centos.zip
(Download it, extract libphp5.so to /usr/local/lib and run "/sbin/ldconfig /usr/local/lib" as root)

Please let me know if these binaries work for you, so I can add them to the first post

And now: Sleeping (4 A.M.)
Reply
#18

Oh dude!
This is Awesome! I'm going to give it a try.
Reply
#19

Quote:
Originally Posted by lapayo
View Post
I successfully compiled a version on centos 5.9
You can download it here:
http://www.sney.net/files/samphp-release-centos.zip

If you need the libphp5.so you can download it here:
http://www.sney.net/files/libphp5.so_centos.zip
(Download it, extract libphp5.so to /usr/local/lib and run "/sbin/ldconfig /usr/local/lib" as root)

Please let me know if these binaries work for you, so I can add them to the first post

And now: Sleeping (4 A.M.)
It works now! After arguing with it a little, and I recommend putting the libphp5.so instructions in the first post. I was wondering why you were fresh installing php, until I re-read this post.

Also, a protip to people trying to use this. Be sure to load a gamemode, even an empty one. The PHP one will load with the gamemode in server.cfg. I'm just using this lol

Code:
#include <a_samp>

main()
{
	print("\n----------------------------------");
	print(" Blank Gamemode");
	print("----------------------------------\n");
}
public OnGameModeInit()
{
	return 1;
}
public OnGameModeExit()
{
	return 1;
}
Thanks again! Gonna play with it more tomorrow and see if I can't throw together some simple GMs to start~
Reply
#20

Quote:
Originally Posted by Emmet_
View Post
The best part is that MySQL is integrated into PHP and we can use it in this plugin. Very nice job!
Thought about it straight away, eliminates the damn MySQL plugins which usually cause problems to launch a server.

Perfect work, could not wish for anything more, just improvements of this. However, I am a little concerned about performance in execution speed.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)