[Plugin] Squirrel in SA:MP
#1

[Image: logo?cct=1279606100]
squirsamp
Squirrel in SA:MP
Introduction

This plugin, as the name suggests, makes possible the use of Squirrel in SA:MP Servers, an object oriented programming language, which is known by its easy syntax and the various possibilities to do incredible things on it.

This is an experimental project, SA:MP Team may update the server and Squirsamp not, so all your work with Squirrel scripting will be lost until we decide to update the plugin to your SA:MP server version.

Kalcor and I do not recommend the use of this plugin for public servers, this is just an experiment.

And remember that when changing the scripting language, you won't be able to use any other plugin that modifies the language, such as MySQL plugin, YSF, etc. If you have any knowledge in plugin scripting, you may want to modify the source and add your own functions.

Requirements
  • Microsoft Windows 9x/NT 5.0+, we do not support Linux YET
  • SA:MP Server 0.3a R6 to 0.3b
Speed

Unfortunately, as every SA:MP native function passed to C++ and parsed with AMX functions, to transform items in cells, the functions called by C++ are 1.5x slower than called by Pawn, and when called by Squirrel, with all the stack functions, it gets 2x slower then Pawn. See the speed test we made to get these results.

In Alpha versions, the plugin used to loop every function in the function table to find the requested one and then call it. It was very slow. But in actual versions it prepares the table with each function with indexes, so it passes to be vastly faster, comparing to the old method.

Changes from Pawn
  • We currently don't include the SA:MP constants, like MAX_PLAYERS, etc.
  • We have added two callbacks: OnScriptInit and OnScriptExit.
  • The SetTimerEx function was removed and in its place we've added only SetTimer with optional parameters at the end:
    • SetTimer(function, interval, repeat, ...)
    • Remember that the "function" parameter isn't a string
    • You don't have to use the parameters string list anymore
  • Added IsTimerActive(timerid)
  • All the GetPVar* functions don't have referenced parameters anymore
  • Functions with referenced string parameters in Pawn have been changed to return a string, they are:
    • GetPlayerName
    • GetWeaponName
    • GetPlayerIp
    • All the SQLite functions that return strings
  • Functions with referenced float parameters in Pawn have been changed in Squirrel, they are:
    • GetVehicleRotationQuat: returns a table with .w, .x, .y and .z
    • All these functions return a float value:
      • GetPlayerFacingAngle
      • GetVehicleZAngle
      • GetVehicleHealth
      • GetPlayerHealth
      • GetPlayerArmour
    • All these functions return a table with the float values .x, .y and .z:
      • GetPlayerPos
      • GetVehiclePos
      • GetObjectPos
      • GetObjectRot
      • GetPlayerObjectPos
      • GetPlayerObjectRot
      • GetPlayerVelocity
      • GetVehicleVelocity
      • GetPlayerCameraPos
      • GetPlayerCameraFrontVector
      • GetPlayerCameraUpVector
  • Functions with referenced integer parameters in Pawn have been changed in Squirrel, they are:
    • GetPlayerTime: returns a table with .hour and .minute
    • GetPlayerKeys: returns a table with .keys, .updown and .leftright
    • GetVehicleDamageStatus: returns a table with .panels, .doors, .lights and .tires
    • GetPlayerWeaponData: returns a table with .weapon and .ammo
  • Added the RCON/console commands: loadss, unloadss and reloadss (just to clarify: ss = Squirrel Script)
Setting up
  1. Place the file squirsamp.dll into your plugins folder
  2. Add the line "plugins squirsamp.dll" into your server.cfg file
  3. Add the line "scripts" into server.cfg, e.g. "scripts myscript.nut other.nut"
  4. Create the folder "scripts" into your root folder to place your Squirrel scripts
  5. You can't use this plugin with other plugins like YSF
  6. Run your server
Disclaimer

Remember that this code is protected by the Mozilla Public License (MPL 1.1) and you must follow this contract when doing any kind of modification and/or distribution of the source code.

Other

There are several code tests on the source.
If you know how to call the filterscripts callbacks on Linux (see the inline-assembly for Windows in callbacks.cpp), post here. Because that's one more thing left we should do to release this plugin for Linux.

This is an Alpha version and may have some bugs, reporting them will help us making this plugin better.

Download
squirsamp.dll

SHA1 Checksum: a19be886684caf71c90f4b2fcb16e009ca4b1afa

Please, no mirrors.

Source

This code is hosted on ****** Code and can be found here.
You can also checkout the code with SVN.

Source summary
Code:
========================================================================
    DYNAMIC LINK LIBRARY : Squirrel in SA:MP Project Overview
========================================================================

This file contains a summary of what you will find in each of the files that
make up this application.

squirsamp.sln
    The Visual Studio Solution file, it contains the project file "squirrel.vcxproj".
    All these VC++ files are for the 2010 version of Visual Studio.

squirrel.vcxproj
    This is the main project file for VC++ projects. 
    It contains information about the version of Visual C++ that generated the file, and 
    information about the platforms, configurations, and project features.

squirrel.vcxproj.filters
    This is the filters file for VC++ projects.
    It contains information about the association between the files in your project 
    and the filters. This association is used in the IDE to show grouping of files with
    similar extensions under a specific node (for e.g. ".cpp" files are associated with the
    "Source" filter).

main.cpp
    This is the main DLL source file. It initializes all the other functions and
    verifies all the needed information to the application run correctly.

global.h
    This file contains the general configuration for the project and the needed includes.

squirsamp.cpp
    Contains the main class definition where all the other classes are defined and
    initialized.

squirsamp.h
    Contains the main class declaration and lines importing all the external references.
    This file has to be included in any other file in the project to be linked correctly.

callback.cpp
    This file is responsible to do the check between the versions of SA:MP Server to then
    initialize all the hooks used along the files.
    This file also contains the functions Call and Unlock that are property from ******
    (Alex "******" Cole), extracted from the YSF plugin made by him release on the SA:MP
    Official Forums.
    The initial purpose of this file was to do the callbacks hook, but now it does every
    hook on the project.

callback.h
    This is the header file for callback.cpp that contains the CCallback class declaration
    and the callbacks struct to store the initial callback addresses from filterscripts.

callbacks.cpp
    This file contains all the callbacks that are passed to the Squirel scripts along the
    server execution routine. For more information, see the comments inside it.

callbacks.h
    This file is the header for callbacks.cpp that contains the callbacks declarations
    inside it, so other files can use the callbacks name.

function.cpp
    Contains the CFunctions class definition that stores and initializes all the function
    addresses and names. It also contains the function that parse C++ parameters to
    Pawn's virtual machine parameters so the target function can be called corretly.

function.h
    This is the header file for function.cpp. It contains the functions struct and the
    enumaration indexes for the SA:MP native functions.

functions.cpp
    This file contains all the SA:MP native functions that are passed to the Squirrel
    scripts. It also contains customized functions like SetTimer and CallRemoteFunction.
    It's responsible to register all the functions on the Squirrel actual virtual machine.

functions.h
    This is the header file for functions.cpp. It only contains the declaration of
    sq_register_pawn for use in scripts.cpp.

scripts.cpp
    This file contains the CScripts class that are responsible for (un)loading Squirrel
    files into the SA:MP Server.

scripts.h
    This is the header file for scripts.cpp and contains the class declaration for it.
    It also contains the struct responsible for storing the Squirrel scripts in.

squser.cpp
    This file contains all the functions that are in the "Squirrel syntax". Such as the
    functions to handle the virtual machine's stack, etc.

squser.h
    The header file for squser.cpp, only with functions' declarations.

timer.cpp
    This file contains all the functions to handle the timers for Squirrel Scripts.
    The functions are stored in the class CTimers, and the timers are stored in the
    "Timer timers[MAX_TIMERS]" struct array.

timer.h
    This is the header file for timer.cpp that contains the class declaration for it and
    the "Timer" struct declaration.

SDK/ Filter
    All the files inside this filter are licensed to their own authors which are
    distributed "as-is" with their own purposes.
    The squirrel/ folder contains all the Squirrel source files.
    The amx/ folder contains the AMX architeture and definitions for SA:MP plugins.
    All the other files are extracted from the "Hello World" SA:MP Plugin SDK released on
    the official SA:MP site (http://www.sa-mp.com/)nl674b4d0b9c1148.4...17463Other notes:

MAX_FILTERSCRIPTS
    It doesn't need to match the actual max filtescripts supported by the executed
    SA:MP Server version. It needs to be the maximum ammount of filterscripts ever
    supported by all SA:MP Server versions.

MAX_SCRIPTS
    This is a user-configurable option which I prefer to use the same ammount as
    MAX_FILTERSCRIPTS to mantain a standard amount of scripts.

MAX_TIMERS
    It can be any value you like.

MIN_TIMER_INTERVAL
    This option was made to avoid execution problems while parsing the timers, because it
    may be slow if the user choices a low interval ammount for his timers.

See copyright notice in the file "COPYRIGHT".

/////////////////////////////////////////////////////////////////////////////
Thanks everyone,

Flбvio Toribio and Jones Nathan.
Reply
#2

nice job
Reply
#3

Yeah, I know.

If you look into the README file, there are all the credits to you.

But I don't want to do that kind of thing just for now (hooking the structures, and other things like that), as I said, it's just for testing.

You know, I could entirely used your YSF plugin, but that's the thing I don't want to do, otherwise, it turns to your plugin. The Multithreaded and YSF are plugins that were made with a big amount of code, in future tests I can implement things like these on the brushes folder, but for now, I like the way it is...

EDIT: I saw your edit, I also saw this code in your plugins, thanks for the link.
Reply
#4

I wish you the best of luck on development with this. Squirrel is a nice language, and would go great with script development for sa-mp
Reply
#5

I didn't meant you were implying me for using your plugin too, I'm just thanking you for giving us your useful codes, they really helped me a lot with my learning in hooks, etc.

giovanni94m, Aztecking and joemomma53, thanks!

EDIT: I kinda used this pointer method with the natives array, but I was just wondering that it is very hard to do with methods I don't know, for example... I don't know the SA:MP structure, I can't even imagine in what class are some function, in what address are this function, etc, so I just hooked a array with no class.

The problem is that this array contains the native functions made for Pawn VM, so I have to make its parameters, etc. So I decided to look at a disassembled native function, trying to find out if this function, being used for Pawn VM, calls another function, that are the function which make all the things. For example, I was trying to find if the functions on the SA:MP Server are made like this:

Code:
cell AMX_NATIVE_CALL n_GivePlayerMoney(AMX *amx, cell *params)
{
    //some code to check some things...
    return GivePlayerMoney(params[1], params[2]);
}
Or like this:

Code:
cell AMX_NATIVE_CALL n_GivePlayerMoney(AMX *amx, cell *params)
{
    //all the code that must be in the "GivePlayerMoney" called in the code above
    //that means... the RakNet things, send the packet, etc.
}
If the source is something like the first example, it will be easier to call a function with the maximum speed we can reach...

But if it is like the second example, we will have to pass through the AMX VM to call the function we wanna call. And that's what I'm doing for now, because I don't now if it's like the first or the second example. Assuming that the second example is more easy to call, and we have to use only one memory address pointing to the natives list, I used that. But even if with the first method we'd have to use several memory addresses (one for each function), I'd use it. Because it's more efficient.
Reply
#6

Is it squirrel 2.x.x or 3.0?
Reply
#7

It's 3.0 beta 1.
Reply
#8

Is there any good editor for it? except Eclipse which is damn slow

Edit: found a syntax file for Vim, looks good

Edit2: also, for SciTE - http://solidfiles.com/d/224b/
Reply
#9

I script it in Notepad, but I saw many people saying that Notepad++ is very good.

EDIT: Code::Blocks has a native syntax highlighting for Squirrel, but I never used it...
Reply
#10

the squirrel highlighting in code::blocks is fine, it does its job great
Reply
#11

Nice work, looks like a pretty interesting plugin/wrapper for Squirrel, also beneficial for when I plan on using Squirrel for another mod.
Reply
#12

Quote:
Originally Posted by ******
View Post
It's a mix - it depends on the function. Some just call another function, some have all the code there - it depends on what the function does, how complicated it is, wether that function is used from within the server too, what the compiler decided and what the coder felt like at the time.

I do have an idea for a method to hook natives and callbacks fairly fast - not as fast as calling things directly but faster than going through the PAWN VM and without the need for any addresses, but I'll see if I can get it working first.
Yeah... I wish luck with this.

Calgon, thank you.
Reply
#13

Very nice, good job, But I don't think I will learn Squirrel.
Reply
#14

Well, this is only a choice.

While you do this example in Pawn:

pawn Код:
public OnPlayerSpawn(playerid)
{
    new string[256], pname[MAX_PLAYER_NAME];
    GetPlayerName(playerid, pname, sizeof pname);
    format(string, sizeof string, "Your name is %s, and you spawned", pname);
    SendClientMessage(playerid, 0xFFFFFFFF, string);

    new Float:x, Float:y, Float:z;
    GetPlayerPos(playerid, x, y, z);
    new vehicleid = CreateVehicle(411, x, y, z, 90.0, -1, -1, 60000);
    PutPlayerInVehicle(playerid, vehicleid, 0);
    return 1;
}
The same thing in Squirrel, if you do player and vehicle classes (which I use), is:

Код:
function Player::OnSpawn()
{
    SendMessage(0xFFFFFFFF, "Your name is " + GetName() + ", and you spawned");
    PutInVehicle(Vehicle(411, GetPos(), 90.0, -1, -1, 60000).GetID(), 0);
    return 1;
}
Reply
#15

Nice idea..I will surely test it in the next days
Reply
#16

Good stuff. I'll definitely use it if it's not so slow. Until then I'll test it.
Reply
#17

Hey, just a note, it's not really acceptable to steal source code from open source projects, the whole timer source of your project here is whiped straight from VC-Players (Located here:http://code.******.com/p/vice-players/ )
Reply
#18

This isnt just a wrapper correct? If it's not just a wrapper, I'm interested in seeing the result of this as a stable release, good luck with it.
Reply
#19

Quote:
Originally Posted by ******
Посмотреть сообщение
Some of the code in there looks a lot like the code from YSF - given the number of times you mentioned it I assume you know about it. Anyway, my point is that YSF has both Windows and Linux code and can call into the server properly (although the addresses need updating).

I have also removed a large amount of inline ASM and replaced it with standard C as they removed inline assembly in the 64bit version of the Visual Studio compiler. For some bizzare reason my server is not responding at the moment, but when it's back I suggest you have a look at how I do it. For example the C++ code to call a random address as an object method is something like:

Код:
*((CClass *)RANDOM_VARIABLE).(*METHOD_ADDRESS)(parameters);
I can't remember the exact code, but the point is you don't need inline assembly and there is already code in YSF (also released under the MPL so you can safely mix it) to do it for Windows and Linux.

Edit: I found the information: http://mdzahidh.wordpress.com/2008/0...thod-pointers/

The way I did it, as you don't really have the class data, is to define a fake class like so:

Код:
class CFake
{
}

typedef
	int (CFake::*ZeroParMethod_t)();

// Actually - casting to a method pointer is not quite this easy.
ZeroParMethod_t
	On‌GameModeInit = (ZeroParMethod_t)0x0045E360;

CFake *
	pGameMode = *(CFake **)0xFFFFFFFF;
Calling a method anywhere in the server is then as easy as:

Код:
(pGameMode->*OnGameModeInit)();
your epic words.. i got lost at "some"
Reply
#20

any chance you or someone else continues the development of this ?
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)