[Plugin] Shoebill 1.1 - SA-MP Java Development Kit

Quote:
Originally Posted by mk124
Посмотреть сообщение
@Anarkien: You just need to add a mysql / mongodb connector to your maven dependencies, and shoebill will download the needed connector automatically if you use maven. You can use every already existing java librarie with shoebill.

For example, you can see my project, it used Mongo DB: https://github.com/GTAUN/wl-vehicle-manager
Great, thanks! Not being a huge Java fan, I might need some time to read back up on it before trying, but anything that provides easy MongoDB connection is a plus in my book!
Reply

[Image: 17Rd42A]

- Hook callbacks & call natives
- A amx with all callbacks in it is not needed anymore. Shoebill will find the callbacks automatically


We are happy to announce the new update. With this update, you can hook custom callbacks from other plugins.

Please make sure, that you use the shoebill-updater (update-shoebill.bat/sh in your server-dir), because many files have changed (shoebill-runtime, launcher, plugin, api)

In this example, I will show you how to hook a callback from FCNPC and call native functions from it:
(plugin url: https://sampforum.blast.hk/showthread.php?tid=428066)

Add a Hook (Make sure, that you remove the hook when you unload your gamemode / plugin):
Код:
@Override
protected void onEnable() throws Throwable {
    Shoebill.get().getAmxInstanceManager().hookCallback("FCNPC_OnCreate", amxCallEvent -> {
        System.out.println("FCNPC created a npc with id " + amxCallEvent.getParameters()[0]);
    }, "i");
}

@Override
protected void onDisable() throws Throwable {
    Shoebill.get().getAmxInstanceManager().unhookCallback("FCNPC_OnCreate"); //remove hook when unloaded.
}
The callback for FCNPC_OnCreate looks like this:
public FCNPC_OnCreate(npcid);

As you can see, it contains 1 parameter of type integer. So, you will need to register the first parameter in the .hookCallback() method at the end.

i -> Integer
f -> Float
s -> String

So, if you have a callback that looks like this:
public OnPlayerChangeName(id, old_name, new_name[]);

you'll have to pass the parameter as following:

Код:
Shoebill.get().getAmxInstanceManager().hookCallback("OnPlayerChangeName", amxCallEvent -> {

}, "iss");
If you want to create a new npc, you will have to do the following (e.g. in a command or when server starts):
The native to create a FCNPC NPC is looking like this:
native FCNPC_Create(name[]);

This native will return the created id, so you will do this to call it:
Код:
@Command
public boolean createnpc(Player player, String name) {
    AmxCallable nativeMethod = null;
    for(AmxInstance instance : Shoebill.get().getAmxInstanceManager().getAmxInstances()) { //loop through all amxs
        if((nativeMethod = instance.getNative("FCNPC_Create")) != null) //check if the amx contains the native
            break; //if yes, break out of the loop
    }
    if(nativeMethod != null) { //when the native method was found, execute it
        player.sendMessage(Color.ORANGE, "* Exec with result: " + nativeMethod.call(name)); //call the native with parameter name and send the return value back to the player.
    } else {
        player.sendMessage(Color.ORANGE, "* Not found!"); //native was not found (plugin not loaded or typo?)
    }
    return true;
}
Reply

[Image: 1EjGiVY]

- This update allows you to call natives & public functions that contain references (e.g. GetPlayerPos, GetPlayerName)

You will need to update the plugin & shoebill-api to use this new feature. (update-shoebill.bat/sh in your root server folder)

This is how to use it:

Код:
@Command
public boolean getmyname(Player player) { // /getmyname command
    AmxCallable nativeMethod = null;
    for(AmxInstance instance : Shoebill.get().getAmxInstanceManager().getAmxInstances()) {
        if((nativeMethod = instance.getNative("GetPlayerName")) != null)
            break;
    }
    if(nativeMethod != null) {
        ReferenceString str = new ReferenceString("", 32);
        nativeMethod.call(player.getId(), str, str.getLength()); //native GetPlayerName(playerid, str[], len);
        player.sendMessage(Color.ORANGE, "Your name is " + str.getValue());
    } else player.sendMessage(Color.ORANGE, "* Not found!");
    return true;
}
Of course, this code is not really useful, because you can just call player.getName(); from Java, but you can also call native methods from other plugins (e.g. FCNPC_GetPosition).

These 3 datatypes are available for referencing:

+ ReferenceString
+ ReferenceFloat
+ ReferenceInt

they are all located in the net.gtaun.shoebill.amx.types.
Reply

[Image: 1c7aqIZ]

We are happy to announce that Shoebill now supports the new 0.3.7 update. If you want to update, please use the enclosed updater within you server's root directory. Just use the update-shoebill.bat/sh file, and shoebill will download all needed files. Make sure you start your server to download all the new dependencies (shoebill-runtime, shoebill-api).
For a list of new features, you can take a look at https://sampwiki.blast.hk/wiki/Category:Added_in_0.3.7. You can also take a look at the GitHub commits:

shoebill-runtime: https://github.com/Shoebill/shoebill...587ba81004ae0e
shoebill-api: https://github.com/Shoebill/shoebill...7785066a162a9f
shoebill-launcher: https://github.com/Shoebill/shoebill...ef2cda47d1095a
ShoebillPlugin: https://github.com/Shoebill/Shoebill...5aabb422a6d9f4

If you don't want to use any of our updaters, you can download every file manually:

shoebill-runtime (0.3.7): http://ci.gtaun.net/job/shoebill-run...1-SNAPSHOT.jar
shoebill-launcher (0.3.7): http://ci.gtaun.net/job/shoebill-lau...1-SNAPSHOT.jar
shoebill-api (0.3.7): http://ci.gtaun.net/job/shoebill-api...1-SNAPSHOT.jar
ShoebillPlugin (0.3.7):
- Windows: http://catboy5.bplaced.net/updater/b...s/Shoebill.dll
- Linux: http://catboy5.bplaced.net/updater/binaries/Shoebill

If you want to start develop your gamemode with 0.3.7 features, you just need to reimport the maven project dependencies (update dependencies).

(bugs may occur)
Reply

it's amazing! thank you!
Reply

@denizx: Thanks for your feedback If you have any questions, feel free to ask.

Btw: I just pushed a little update for the add siren parameter in the CreateVehicle & AddStaticVehicleEx function. You can now access it via Vehicle.create(...);. There is one constructor that contains the add siren parameter, please use it if you have to.
Reply

Appreciated mate...good going
Reply

Thanks for your feedback, if you have any questions you can always post them here.
Reply

I just added a video on how to setup a simple gamemode in eclipse:

https://www.youtube.com/watch?v=Bg0pNhY1vgE
Reply

It's nice to see that this plugin is still being developed

What are your goals? What do you plan on adding next?

And the one thing that has been bugging me the most: why did you name it after the bird, "Shoebill"?
Reply

Thanks for you reply. There are currently no special goals for Shoebill except bug fixes (if found) and future sa-mp version support. There is no exact reason for the name "Shoebill", I just think that the "Shoebill"-Bird is interesting and that's why I used this name, and because I just needed one
Reply

Okay. Player Lifecycle objects. I've created a GamePlayer class:
Код:
public class GamePlayer extends PlayerLifecycleObject {

    private int userId;
    private String password;

    public GamePlayer(EventManager manager, Player p, int userid, String password) {
        super(manager, p);
        this.userId = userid;
        this.password = password;
    }

    @Override
    protected void onInit() {

    }

    @Override
    protected void onDestroy() {

    }


    public int getUserId() {
        return userId;
    }
}
My problem is the constructor. I want it to take those values(and probably a lot more in the future). How am I suppose to register it?

My plan is:
Creating a Auth manager for login and registration.
If a player enters his correct password, I find his data by name name and password
I dispatch a successful login event which contains GamePlayer instance.
Reply

Hehe. This is some pretty cool work. Keep going buddy!
Reply

@dusk: The PlayerlifecycleObject will be created when the player connects, so it's not possible to create it when he enters the correct password. You could just add a boolean to your GameData class that indicates if the player is logged in or not. And if you want to add custom parameters to your constructor, you can do that by using a custom PlayerLifecycleObjectFactory, like this:

Код:
lifecycleHolder.registerClass(GameData.class, new PlayerLifecycleHolder.PlayerLifecycleObjectFactory<GameData>() {
    @Override
    public GameData create(EventManager eventManager, Player player) {
        return new GameData(eventManager, player);
    }
});
in short form, you can also use a lambda expression (I like it more):

Код:
lifecycleHolder.registerClass(GameData.class, (eventManager1, player) -> {
    return new GameData(eventManager1, player);
});
@Kapersky™: Thank you
Reply

Thanks. I have another question. Are command names case-sensitive?

For example:
Код:
@Command
public boolean cmd(Player p) {
  
}

@Command
public boolean cMd(Player p) {

}
Will these to commands be the same?

The reason I ask is because I want to name my command "goto" and that is a Java keyword(don't have the hardware to test it myself right now )



And how do these commands work? What can be command function arguments? I mean I can't just add whatever I need and hope that shoebilll will do everything for me, can I?
For example
Код:
@Command
public boolean command(Player p, Player p2) {

}
Can I somewhat control how the command will be found? I mean what will happen if player enters "/command non-existant palyer name" will this get called with p2 being null?
Reply

@dusk:

You can choose yourself, if your command should be case sensitive or not, and you can also set it's priority. Sadly, you can't use java keywords as command names such as "goto". You just need to add some parameters to the @Command Annotation like this:

Код:
@Command(priority = 1, caseSensitive = true)
public boolean test(Player player) {
    player.sendMessage(Color.RED, "Hello! from case sensitive test-command with priority 1");
    return true;
}
Function Parameters can be everything, but you need to make sure that shoebill knows how to handle the text that the user inputs. You can add your own "Type-Parser" in your CommandManager instance like this:

Код:
commandManager.replaceTypeParser(Player.class, s -> {
    return Player.getByPartOfName(s);
});
You can do that with all classes, even your custom ones, but you need to provide a way for shoebill to get a object from the user's inputed text. I will give you one more example:

Код:
commandManager.replaceTypeParser(House.class, s -> {
    return House.findById(Integer.parseInt(s));
});

//A sample command
@Command
public boolean edithouse(Player player, House house) {
    if(house == null) {
        player.sendMessage(Color.RED, "* Invalid house id!");
        return true;
    }
    //Access house instance like everything in java ;)
    return true;
}
Already existing types are:

- String
- int & Integer
- short & Short
- byte & Byte
- char & Character
- float & Float
- double & Double
- Boolean
- Player
- Color

but you can also overwrite them yourself, if you are not happy with it's behavior.
Reply

Wow, type parsers seem VERY useful. I was thinking about making commands that would have a house, which player is near, as an argument. I'm quite sure type-parsers will let me easily achieve this.


Once again: great plugin
Reply

Thank you, we've put much work in it, but not many people are using it, sadly.
Reply

Is it updated for 0.3.7?

ill certainly use it mate
Reply

Yes, it is updated for 0.3.7
Reply


Forum Jump:


Users browsing this thread: 9 Guest(s)