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

@lucesita: Please keep in mind that Textdraws can not display special characters, only letters and numbers. You can show us your code and we will take a look at it.
Reply

example code:
Код:
import net.gtaun.shoebill.common.StringUtils;
import net.gtaun.shoebill.constant.TextDrawAlign;
import net.gtaun.shoebill.constant.TextDrawFont;
import net.gtaun.shoebill.data.Color;
import net.gtaun.shoebill.event.player.PlayerConnectEvent;
import net.gtaun.shoebill.object.Player;
import net.gtaun.shoebill.object.PlayerTextdraw;
import net.gtaun.shoebill.object.Textdraw;
import net.gtaun.shoebill.object.TextdrawBase;
import net.gtaun.shoebill.resource.Gamemode;

/**
 * @author lucesita
 */
public class TextdrawTestGM extends Gamemode {
    private final String latinString = "Recuperar contraseсa";

    @Override
    protected void onEnable() throws Throwable {
        getEventManager().registerHandler(PlayerConnectEvent.class, e -> {
            Player player = e.getPlayer();
            player.toggleSpectating(true); // Remove spawn buttons

            PlayerTextdraw playerTD;
            playerTD = PlayerTextdraw.create(player, 222.363342f, 30.930297f);
            playerTD.setLetterSize(0.227482f, 1.369498f);
            playerTD.setTextSize(40.000000f, 115.287612f);
            playerTD.setAlignment(TextDrawAlign.get(2));
            playerTD.setColor(new Color(-1));
            playerTD.setUseBox(true);
            playerTD.setBoxColor(new Color(84215240));
            playerTD.setShadowSize(0);
            playerTD.setOutlineSize(0);
            playerTD.setBackgroundColor(new Color(255));
            playerTD.setFont(TextDrawFont.get(1));
            playerTD.setProportional(true);
            playerTD.setSelectable(true);
            playerTD.show();

            Textdraw globalTD;
            globalTD = Textdraw.create(222.363342f, 400.930297f);
            globalTD.setLetterSize(0.227482f, 1.369498f);
            globalTD.setTextSize(40.000000f, 115.287612f);
            globalTD.setAlignment(TextDrawAlign.get(2));
            globalTD.setColor(new Color(-1));
            globalTD.setUseBox(true);
            globalTD.setBoxColor(new Color(84215240));
            globalTD.setShadowSize(0);
            globalTD.setOutlineSize(0);
            globalTD.setBackgroundColor(new Color(255));
            globalTD.setFont(TextDrawFont.get(1));
            globalTD.setProportional(true);
            globalTD.setSelectable(true);
            globalTD.show(player);

            // 2 tds showed, global at screen bottom, perplayer at screen top
            playerTD.setText(StringUtils.convertStringForTextdraw("playerTD: " + latinString));
            globalTD.setText(StringUtils.convertStringForTextdraw("globalTD: " + latinString));
        });
    }

    @Override
    protected void onDisable() throws Throwable {

    }
}
this is what i get:

In global textdraw there are a space between "e" and "с" (contrase сa instead of contraseсa), but in perplayer version it gets displayed fine. This is why i think that the problem is when decoding the string from the jvm, because it happens only on global version (which uses a different way to get the string)
Reply

Hi again, seems the gamemode reloader isn't working anymore, it doesn't reload the gamemode once I updated it, I must close it and then start it again with startup.bat (On Windwos, I haven't tested it on Linux)
PHP код:
# Additional plugins
plugins:
  - 
net.gtaun:shoebill-gamemode-reloader:1.0-SNAPSHOT
# Your gamemode
gamemode:dev.acesamp:Gamemode:1.0-SNAPSHOT 
Another thing is the mapandreas class. I tried using mapandreas using the following class:
PHP код:
/*
* MapAndreas mapAndreas = new MapAndreas(new File(getDataDir(), "SAfull.hmap"));
* float z = mapAndreas.findZ(player.getLocation().x, player.getLocation().y);
* mapAndreas.close();
*
* */
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class 
MapAndreas
{
    private 
MappedByteBuffer mappedByteBuffer;
    public 
MapAndreas(File mapAndreadDatathrows IOException
    
{
        
FileInputStream in = new FileInputStream(mapAndreadData);
        
FileChannel fileChannel in.getChannel();
        
mappedByteBuffer fileChannel.map(FileChannel.MapMode.READ_ONLY0fileChannel.size());
        
fileChannel.close();
        
in.close();
    }
    public 
void close()
    {
        if (
mappedByteBuffer == null) return;
        
synchronized (mappedByteBuffer)
        {
            
mappedByteBuffer null;
        }
    }
    public 
float findZ(float xfloat y)
    {
        if (
mappedByteBuffer == null) return 0.0f;
        if (
< -3000.0f || 3000.0f || 3000.0f || < -3000.0f) return 0.0f;
        
synchronized (mappedByteBuffer)
        {
            
int gridX = ((int) x) + 3000;
            
int gridY = (((int) y) - 3000) * -1;
            
int dataPos = (gridY 6000) + gridX;
            
mappedByteBuffer.position(dataPos);
            
int ch1 Byte.toUnsignedInt(mappedByteBuffer.get()), ch2 Byte.toUnsignedInt(mappedByteBuffer.get());
            return ((float) ((
ch2 << 8) + (ch1))) / 100.0f;
        }
    }

And this is my code:
PHP код:
try {
            
mapObject = new MapAndreas(new File(Gamemode.getInstance().getDataDir(), "SAfull.hmap"));
        } catch (
IOException e) {
            
e.printStackTrace();
        } 
PHP код:
public void onPlayerClickMap(Player playerVector3D pos){
            
float z Server.getMapAndreas().findZ(pos.getX(), pos.getY());
            
player.setLocation(pos.getX(), pos.getY(), z);
        }
    } 
But it teleports me most of the time 100 meters above or 1 meter below the map.
Reply

@lucesita: I fixed this issue with this commit: https://github.com/Shoebill/Shoebill...25fa9cd730b6db

You can download the new version of the plugin by using the shoebill updater (execute update-shoebill.sh / .bat).

@Su37Erich: I will take a look at the MapAndreas plugin. When did the problem with the game mode reloader started to occur? Do you see the "Gamemode has been modified. Reloading..." message when you change your game mode? Are you sure that File observation is possible in your environment (not possible on network share for example)?
Reply

Well, I think it happened since I updated the shoebill plugin (March 21st) but I am not sure because I stopped coding for about a month.
When I "compile" the source files with IntelliJ, simply nothing happens in the prompt, so I must shut down the server and start it again
Quote:

Are you sure that File observation is possible in your environment (not possible on network share for example)?

I think it is possible since I didn't any changes except the update of the plugin and it worked before.
Reply

@Su37Erich: I just tested it and it was working fine and reloaded immediately after I recompiled my project in IDEA. Are you sure that the GamemodeReloader is getting loaded and is located in the resources.yml under the plugins section?
Reply

Yes it is, it says in the prompt:
Код:
[INFO][ResourceManagerImpl] Load plugin: Gamemodereloader
[INFO][ResourceManagerImpl] Load gamemode: Gamemode
Loading filterscript etc.
Number of vehicle models: 132
After I compile:
Код:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 35.409 s
[INFO] Finished at: 2016-03-26T18:01:33-06:00
[INFO] Final Memory: 16M/38M
[INFO] ------------------------------------------------------------------------

Process finished with exit code 0
The prompt says the same:
Код:
[INFO][ResourceManagerImpl] Load plugin: Gamemodereloader
[INFO][ResourceManagerImpl] Load gamemode: Gamemode
Loading filterscript etc.
Number of vehicle models: 132
Of course I made changes in the gamemode, even I tried deleting a class
Код:
repositories:
  - id: central
    url: http://repo1.maven.org/maven2/nl673838c6...5.36594035  - id: gtaun-public-repo
    url: http://repo.gtaun.net/content/groups/pub...5.36594035  - id: sonatype-oss-snapshots
    url: https://oss.sonatype.org/content/reposit...5.36594035# When to update cache?
# Options: always / daily / interval:[minutes]
cacheUpdatePolicy: daily

# If Maven checks for Updates or use old artifacts
offlineMode: false

# Your needed runtimes
runtimes:
  - net.gtaun:shoebill-runtime:1.2-SNAPSHOT
  - net.gtaun:shoebill-common:1.2-SNAPSHOT

# Additional plugins
plugins:
  - net.gtaun:shoebill-gamemode-reloader:1.0-SNAPSHOT

# Your gamemode
gamemode: dev.acesamp:Gamemode:1.0-SNAPSHOT
Reply

@Su37Erich: Do you use a blank filterscript with the OnRconCommand() callback in it? I think it is necessary for this to work. Here is my blank filterscript with the OnRconCommand callback in it: https://www.dropbox.com/s/qh1dzsqo5m...asefs.amx?dl=1

(.pwn): https://www.dropbox.com/s/aamesvaqyx...asefs.pwn?dl=1
Reply

I don't but I just added it and still not working
Reply

@Su37Erich: That's strange, and I don't know what is causing this. Maybe this is an issue with your environment and the WatchService from Java, but I am not really sure.
Reply

I have a similar problem with reloader plugin. In my case shoebill does not load my jar correctly, for example, in my gamemode I load some classpath resources (like sql scripts, property files, etc) using getResourceAsStream, and, when my server is restarted by reloader plugin, sometimes I get random uncompressing ZIP exception, like "reached end of file", " invalid chunk length " and others. This doesn't happens if I start my server manually.
I think it happens because the server is restarted when the jar file is still beign writted by maven, and shoebill gets a corrupted version of the file.

Maybe this error can be fixed in reloaderplugin by sleeping inside the infinite loop for about a half second.

Also sometimes reloaderplugin reloads my gm fine, but when i enter the server it is the last gamemode, not the new compiled one, and again, I think that the problem is that shoebill simply gets the old version.
Reply

I think I asked about this before but couldn't find the answer. Can you pass arrays to Pawn? My current test with float array failed.

Java
Код:
float[] data = new float[]{5f, 1.2f, 35.4f, 21.f};
System.out.println("data length:" + data.length);
Object returned = m.call(data, data.length);
System.out.println("nativeMethod returned: " + returned);
Pawn:
pawn Код:
forward arrayTest(Float:data[], len);
public arrayTest(Float:data[], len)
{
    printf("arrayTest called len:%d", len);
    for(new i = 0; i < len; i++)
    {
        printf("i:%d. val:%f", i, data[i]);
    }
    printf("arrayTest is done");
}
Output
Код:
[2016-03-28 22:50:53][INFO][out] data length:4
[2016-03-28 22:50:53][INFO][out] nativeMethod returned: 0
[22:50:53] arrayTest called len:0
[22:50:53] arrayTest is done
Reply

@dusk: Currently not, but I might add this in the future when I find some time.
@lucesita: You are right, that could be the case. I added a 500ms sleep time in the latest commit, maybe you can test it out (http://ci.gtaun.net/job/shoebill-gamemode-reloader/3/).

//Edit: I also added watchService.close() in this commit: http://ci.gtaun.net/job/shoebill-gamemode-reloader/4/.
Reply

So I was trying to implement array support for callPublic by myself. Everything works great with primitive arrays, but if I pass an object wrapper, for example Float it does not work. If I treat it as an jobjectArray it crashes and if I cast it to jfloatArray the values are all 0. Crashdump http://pastebin.com/ar1zXbDP
Код:
jobjectArray ar = (jobjectArray)object;
int len = env->GetArrayLength(ar);
cell data[10];
for (int i = 0; i < len; i++)
{
	auto o = env->GetObjectArrayElement(ar, i);
	auto oclass = env->GetObjectClass(o); // This line crashes
	auto bjf = env->GetMethodID(objectclass, "floatValue", "()F");
	auto ffloat = env->CallFloatMethod(object, bjf);
	data[i] = amx_ftoc(ffloat);
}
This code works for primitives, but prints 0s with Float object array:
Код:
jfloatArray ar = (jfloatArray)object;
int len = env->GetArrayLength(ar);
float *fdata = env->GetFloatArrayElements(ar, 0);
cell data[10];
for (int i = 0; i < len; i++)
{
	printf("I:%d val:%f\n", i, fdata[i]);
	data[i] = amx_ftoc(fdata[i]);
}
env->ReleaseFloatArrayElements(ar, fdata, 0);
cell arrCell;
amx_PushArray(amx, &arrCell, NULL, data, len);
Reply

@dusk: I'll take a look at it myself today.

//Edit: It will probably take some more time than just today.
Reply

@dusk: I added array support in this commit: https://github.com/Shoebill/Shoebill...d6735451e09bbc

Currently it is only working with Integers and Floats, Strings are somehow not working correctly but I don't know why at the moment. You can update your plugin via the shoebill-updater.

This is how to use it:
pawn Код:
forward testJavaPawn(Float:values[], valLen, second[], secondLen);
public testJavaPawn(Float:values[], valLen, second[], secondLen)
{
    for(new i = 0; i < valLen; i++)
    {
        printf("Value in Values slot #%i: %f", i, values[i]);
    }
    for(new i = 0; i < secondLen; i++)
    {
        printf("Value in Second slot #%i: %i", i, second[i]);
    }
    return 1;
}
After your array declaration in the header, you will always have to add a parameter for the length, because it can't be received via sizeof. You can not use primitive types such as int or float, you have to use Float and Integer as Objects. You can cast a primitive int to an Integer by using:
PHP код:
Integer integer = (Integer) myPrimitiveInt
If you want to call a public function via callPublic and you only use one array as an argument, it is important that you cast your array to an Object, because otherwise the compiler will be confused if you want to call the method as varargs or non-varargs. If you pass two or more parameters, this should not be a problem. Here is a full example:

PHP код:
        AmxCallable callback null;
        for(
AmxInstance instance AmxInstanceManager.get().getAmxInstances()) {
            if((
callback instance.getPublic("testJavaPawn")) != null)
                break;
        }
        
assert callback != null;
        
Float[] values = new Float[] {5.3f12.4f5.75f7.1f88.897f};
        
callback.call((Object) values); //Cast to Object because of varargs confusion.
        //callback.call(values, myNumber); <--- No need to cast because there are 2 parameters. 
Reply

Nice as always.

On a side note, why does it only support objects? I myself successfully implemented it for primitives aswell, or there are other issues?
Reply

@dusk: I just forgot to implement it. I added it and also fixed some unsafe code: https://github.com/Shoebill/Shoebill...6ec6ce65151a92

As always, you can update via shoebill-updater.

//Edit: I found some bugs, I will push a commit soon.
//Edit2: Commit: https://github.com/Shoebill/Shoebill...c7cfcb9aecd64e

Everything should work now (except strings).
Reply

Hello again.
What does the following mean?
[13:13:40] > Error: Codepage already in use, 862=CP862
[13:13:40] > Error: Codepage already in use, 874=CP874
[13:13:40] > Error: Codepage already in use, 932=SHIFT_JIS
[13:13:40] > Error: Codepage already in use, 936=GBK
[13:13:40] > Error: Codepage already in use, 949=CP949
[13:13:40] > Error: Codepage already in use, 950=BIG5
[13:13:40] > Error: Codepage already in use, 1250=CP1250
[13:13:40] > Error: Codepage already in use, 1251=CP1251
[13:13:40] > Error: Codepage already in use, 1252=CP1252
[13:13:40] > Error: Codepage already in use, 1253=CP1253
[13:13:40] > Error: Codepage already in use, 1254=CP1254
[13:13:40] > Error: Codepage already in use, 1255=CP1255
[13:13:40] > Error: Codepage already in use, 1256=CP1256
[13:13:40] > Error: Codepage already in use, 1257=CP1257
[13:13:40] > Error: Codepage already in use, 1258=CP1258
[13:13:40] > Shoebill has been initialized.
Reply

@Su37Erich: It means that there is already a definition for the codepages, but it's alright if you didn't change the codepages.txt. I guess this issue appears when you reload your server instead of fully restarting it, right? I am currently doing a overhaul of the ShoebillPlugin and cleaning it up. I will fix this issue in the next build.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)