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

@Urukhay: You can use Java's threads (https://docs.oracle.com/javase/8/doc...ng/Thread.html) but if you want to call anything related to SA:MP's functions, you will have to use Shoebill.get().runOnSampThread() as dusk already said. So you can technically calculate big numbers while your players are not experiencing any lag.
Reply

Some general questions...
I'm new to maven and I'm curious about my Shoebill gamemode structure.
I'm planning to implement different systems (each of them is going to include a lot of interfaces, classes and so on). So I want to write them as separate components (i.e. different projects) and I'm not definitely sure how to do this. That's why I need your help (at least some advice)

Let's say, there are gamemode (lets call it GM for shot), house system, business system and vehicle system - they are written independently and as a separate projects. I want to include all those systems in GM. So my steps are gonna be next (correct me if I'm wrong):
0. (Like prerequisites) Those systems should be written as Shoebill plugin.
1. Add dependencies to GM's pom.xml
2. Add .jars to shoebill/plugins folder and to resources.yml

And finally, the list of my questions:
1. Can I include those systems (for example) not as plugins, but as other libraries and frameworks (like JDBC)? If yes, then could you please tell me how to do that (cause I was trying to include streamer-wrapper in that way and I failed) and what are advantages (if there are ones) and disadvantages of doing so?
2. Can I create a wrapper of libraries (didn't come up with better name) which will contain other libraries? An example, just to clarify what am I asking for:
Suppose (again) there are GM, house system, business system and vehicle system (as different projects). Also, there is a library, named "common", which include dependencies of house system, business system and vehicle system. So I want to include ONLY "common" library to GM and access all classes and methods from vehicle system, house system and so on. Is it possible?

@mk124, I would like you to answer those questions (even if others already did that) with very short examples with your WL-WORLD project, cause I've managed to find where only 2 components included (wl-common and wl-language). Curious about others
Thanks.
Reply

@valych: Shoebill was build to allow modular development, so it is no problem to accomplish this.

Steps:
1. Write your Systems as Shoebill Plugins (make sure you add a plugin.yml to resources folder like gamemode.yml)
2. You don't actually add the GM to your Plugin's dependencies because they would not be independent anymore. You only go one way, and that's from your GM to your Plugin, not the other way. With this technique, you can use your Plugins in any other project you want.
3. Add the .jars to the plugins folder and make sure you add them to the resources.yml.

Your questions:
1. I don't actually understand what exactly you are trying to say. If you want to add the streamer-wrapper or any other project to your GM, you simply add the dependency to your pom.xml (and if it's a Shoebill plugin also to the resources.yml).
2. I think the dependencies you add in one project can not be used in the other project. At runtime they would be there, but I am not sure if you could compile the project.

I think you are really looking at Maven like it's a complex system but it really isn't that hard. If you create a Plugin and deploy it somewhere to a server or a local repository (which happens by default I think) you will be able to add a <dependency> node to your pom.xml's game mode and access classes and methods that have the correct access modifiers (public, protected, private). I will give you one example:

Take a look at the example-vehicle-manager-plugin:
https://github.com/Shoebill/example-...manager-plugin

You can add the dependency to your GM by adding this dependency to your <dependencies>:
Код:
        <dependency>
            <groupId>net.gtaun.shoebill</groupId>
            <artifactId>example-vehicle-manager-plugin</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
This will either download the .jar from http://repo.gtaun.net/ or use a local one if you compiled it yourself.

What you will want to do now, is to somehow access your Plugin in your Gamemode. You can do that by using the Plugin.get(PluginClass.class) method. Here is an example for the example-vehicle-manager-plugin in your GM:
Код:
public void onEnable() {
        VehicleManagerPlugin plugin = null;
        if((plugin = Plugin.get(VehicleManagerPlugin.class)) == null) {
            logger.error("Could not find the VehicleManagerPlugin, please make sure that it is getting loaded.");
            System.exit(1); //Exit because dependencies are not satisfied
        }
        //Do things with plugin
}
It is obviously that the VehicleManagerPlugin does not offer any public methods that could be accessed from there on, but you could add some of course. If you start developing your own Plugin, you will want to forget about your GM for a moment and try build it as modular and flexible as possible.
Reply

Thank you a lot again. I guess everything is clear for me now.

Quote:
Originally Posted by mk124
Посмотреть сообщение
Your questions:
1. I don't actually understand what exactly you are trying to say. If you want to add the streamer-wrapper or any other project to your GM, you simply add the dependency to your pom.xml (and if it's a Shoebill plugin also to the resources.yml).
//Edited a bit: I was asking (in other words) : if a project, that I want to include is not a Shoebill plugin, then how do I do that if I have only .jar file? As I have noticed, to add a dependency, the jar file should be allocated in folders according to package + in version_name folder.
With SQLite JDBC - I have included it in Project Structure (Ctrl + Alt + Shift + S in IntelliJ IDEA) -> Libraries -> Press + and select a path to the sqlite_jdbc_<version>.jar. But now, I can't find where it is included (neither in GM libraries nor in pom.xml dependencies). But never mind, it is working so be it
Reply

@valych: if you need some examples, also look here for two easy Shoebill systems (plugins) https://github.com/Alf21 or https://sampforum.blast.hk/showthread.php?tid=599317
Reply

@Alf21, thanks, but now I need an answer to this question:

Quote:
Originally Posted by valych
Посмотреть сообщение
I was asking (in other words) : if a project, that I want to include is not a Shoebill plugin, then how do I do that if I have only .jar file? As I have noticed, to add a dependency, the jar file should be allocated in folders according to package + in version_name folder.
Reply

@valych

As far as i know you can easily add the project, so a .jar file, to the used libraries the way like programming other Java applications. There are two different library folders (eg in eclipse luna), the maven Library and the normal Library, so add the project to your build path and it will included the project/library into the normal library.

I hope this will help you but mk124 will explain it better^^
Reply

@valych: That depends on your IDE. If you use IDEA you can take a look at this: http://stackoverflow.com/questions/1...j-idea-project

Eclipse has something similar but I personally don't use Eclipse. I'm not sure, but you might also have to add the .jar library to your runtimes section in the resources.yml file, depending on your build settings.
Reply

Is there a way for plugins to share events? For example, if one plugin dispatches an event, a different would could register a handler to it.
Reply

@dusk: You simply make your event's class public. Then you can use it in any other gamemode or plugin by registering a handler.
Reply

Hello again!
Is it recommeded to have only a MySQL connection for everything?
Because I got this error sometimes:
Quote:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsExce ption: The last packet successfully received from the server was 58,393,529 milliseconds ago. The last packet sent successfully to the server was 58,393,539 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

Here is my code to connect to the database:

Код:
public static Connection createConnection(String server, String user, String password, String dataBase){
        Connection connection = null;
        try{
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection("jdbc:mysql://"+server+":3306/?autoReconnect=true"+dataBase, user, password);
        }catch(ClassNotFoundException | SQLException e){
            connection = null;
        }
        return connection;
    }
I read that connections should be only opened and closed every time you use them, and I should use a thing called connection pool, I tried it but it simply doesn't work for me:
Код:
public class Player{
    private static DataSource ds;
    static{
        try{
            InitialContext context = new InitialContext();
            ds = (DataSource)context.lookup("java:comp/env/jdbc/MySQLDB");
        }catch(NamingException e){
            System.out.println("Error: "+e);
        }
    }
static{
        Connection connection = null;
        Statement st = null;
        ResultSet result = null;
        try{
            connection = ds.getConnection();
            st = connection.createStatement();
            result = st.executeQuery("SELECT Value FROM Settings WHERE ValueName='Max Players Online'");
            if(result.next()){
                maxPlayersOn = result.getByte(1);
            }else{
                maxPlayersOn = 0;
            }
        }catch(SQLException e){
            System.out.println("SQL Error "+e);
        }finally{
            if(result != null){try{result.close();}catch(SQLException ignored){}}
            if(st != null){try{st.close();} catch(SQLException ignored){}}
            if(connection != null){try{connection.close();} catch(SQLException ignored){}
            }
        }
    }
}
But I get:
Quote:

Error javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial

Now I am very frustrated since in Pawn you just needed only one connection and everything worked fine, but using Java the things become very complex for me, I do not know what even means context or datasource and the relationship with MySQL!
I really appreciate any help
Reply

@Su37Erich: This might be a problem with your MySQL server. I recommend you using MongoDB if your are not bound to MySQL. If you don't want to switch to MongoDB, you might have to search for a solution on the internet because I do not use MySQL anymore. I don't think that a connection pool is required and I believe that there is no problem with keeping the MySQL connection alive. You might have to play with your MySQL server's configuration a little bit.
Reply

Reply

@zugg48 I have the same "issue". From what I found it is caused by multiple versions of slf4j being loaded... Never found a solution, so i chose to ignore it, everything still works fine.
Reply

Hey once again. Is anyone having issues with player.cancelSelectTextDraw? It simply doesn't work for me, I use the latest shoebill. What is the getResponse on PlayerClickTextDrawEvent event? OnPlayerClickTextDraw didn't have it in Pawn..
Reply

@TuoXin: Thank you
@dusk: I haven't tested it right now, but it should work perfectly fine. Are you sure that you are in select mode? Please note that .cancelSelectTextDraw() fires OnPlayerClickTextDraw with an invalid id (null in Shoebill).
Reply

New issue:
The public OnPlayerDisconnect in pawn is not being called when server is running with Shoebill plugin. I tested this on bare.pwn:
PHP код:
public OnPlayerDisconnect(playeridreason)
{
    
printf("OnPlayerDisconnect - playerid = %d, reason = %d"playeridreason);
    return 
1;

So when I run the server with Shoebill plugin (start with startup.bat), there is no message when player disconnects. But when I run it with samp-server.exe, message is being displayed.
Reply

@valych: Are you somewhere in your Java code calling .disallow() on the PlayerDisconnectEvent ?
Reply

@mk124, nope. I even tried to remove all events from java code, but the result was the same, unfortunately.
Reply

How include Streamer functions to the maven with Shoebill?
Reply


Forum Jump:


Users browsing this thread: 26 Guest(s)