SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Plugin Development

Reply
 
Thread Tools Display Modes
Old 15/05/2016, 04:03 PM   #861
lucesita
Big Clucker
 
Join Date: Feb 2016
Posts: 69
Reputation: 10
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

Hi again. I have a question: I want to test my code. Everything was fine, I created "mock" implementations of Player, Vehicle, etc, to use in tests. Now, the problem is that everytime I get a NullPointerException when I use commons dialogs. Why? Because dialogs uses SampObjectManager.get() to be created.

Seeing the impl, it just asks to Shoebill.get().getSampObjectManager. Now my question: How can I inject my "own" instance of shoebill? I need to create a "mock" instance to test everything, like this:

PHP Code:
class MockShoebill implements Shoebill {
    ...     
 
    @
Override
    
public SampObjectManager getObjectManager() {
        return new 
SampObjectManager() {
            
createDialogId(..) {
                return 
MockDialogId(..);
            }
        }
    }

    ...

to decouple shoebill from runtime dependencies. My first idea was to use a proxy, then intercept shoebill "get". However, I dont know if its possible to intercept interface default methods.
lucesita is offline   Reply With Quote
Old 15/05/2016, 04:28 PM   #862
ZachKnoxx
Huge Clucker
 
Join Date: Oct 2013
Location: Canada
Posts: 205
Reputation: 118
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

This looks great. I might try my luck with this.
ZachKnoxx is offline   Reply With Quote
Old 15/05/2016, 04:36 PM   #863
dusk
High-roller
 
dusk's Avatar
 
Join Date: Jul 2008
Posts: 1,113
Reputation: 46
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

Quote:
Originally Posted by lucesita View Post
Hi again. I have a question: I want to test my code. Everything was fine, I created "mock" implementations of Player, Vehicle, etc, to use in tests. Now, the problem is that everytime I get a NullPointerException when I use commons dialogs. Why? Because dialogs uses SampObjectManager.get() to be created.

Seeing the impl, it just asks to Shoebill.get().getSampObjectManager. Now my question: How can I inject my "own" instance of shoebill? I need to create a "mock" instance to test everything, like this:

PHP Code:
class MockShoebill implements Shoebill {
    ...     
 
    @
Override
    
public SampObjectManager getObjectManager() {
        return new 
SampObjectManager() {
            
createDialogId(..) {
                return 
MockDialogId(..);
            }
        }
    }

    ...

to decouple shoebill from runtime dependencies. My first idea was to use a proxy, then intercept shoebill "get". However, I dont know if its possible to intercept interface default methods.
Why did you create your own implementations of Shoebill objects?
dusk is offline   Reply With Quote
Old 15/05/2016, 04:49 PM   #864
Su37Erich
Huge Clucker
 
Su37Erich's Avatar
 
Join Date: Dec 2013
Location: USEA Strangereal
Posts: 343
Reputation: 16
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

Hello again
I have a question about the timers again.
I want to create an AntiSpawnKill by setting the health of the player to 10000.0 and after 40 seconds it will be reseted to 100.0.
I am planning on creating a normal timer and keeping the Timer Id for each player since when the player dies for whatever reason before the "callback" is called or disconnects the timer will be stopped.
I have more doubts about the timers because I saw timers stop working when you disconnect from the server but I have no idea how it works.
More problems I could have:
(When I want to send everyone a message or something else after the player disconnects, i.g. 1 minute later guess the timer won't work)
__________________
Neucom Inc.
Su37Erich is offline   Reply With Quote
Old 15/05/2016, 05:49 PM   #865
lucesita
Big Clucker
 
Join Date: Feb 2016
Posts: 69
Reputation: 10
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

Quote:
Originally Posted by dusk View Post
Why did you create your own implementations of Shoebill objects?
For testing. There are a maven step called test, which will execute all unit tests that you have under test/java folder. You cant call samp functions here, because you need to link samp server with the java virtual machine for that.
I want to create shoebill implementations that "simulates" a running server
lucesita is offline   Reply With Quote
Old 15/05/2016, 08:53 PM   #866
mk124
Huge Clucker
 
mk124's Avatar
 
Join Date: Jul 2007
Location: Nanning, China
Posts: 319
Reputation: 59
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

@Su37Erich: Here is an example on how to create a hp reset after 40 seconds. It is important that you only have one instance of a timer for each player active. Because when the player dies twice in these 40 seconds, the timer will be started multiple times. It is also important that you check that the player is still connected after these 40 seconds. In this example, I will use the PlayerLifecycleHolder:

PHP Code:
class UserData extends PlayerLifecycleObject {

    private static final 
int HEALTH_RESET_INTERVAL 40000//40 secs
    
private Timer healthReset;

    public 
UserData(EventManager eventManagerPlayer player) {
        
super(eventManagerplayer);
    }

    @
Override
    
protected void onInit() {
        
eventManagerNode.registerHandler(PlayerDeathEvent.class, HandlerPriority.NORMAL,
                
Attentions.create().object(player), deathEvent -> {

                    if(
deathEvent.getPlayer() != player) return; //The event will maybe fire when the killer is the player, and we don't want that. We only want this event if the died player is the player.                   

                    
if (healthReset != null && healthReset.isRunning())
                        
healthReset.stop(); //Stop previous timer if it was running
                    
healthReset Timer.create(HEALTH_RESET_INTERVAL1-> {
                        if (
player.isOnline()) {
                            
player.setHealth(100f);
                        }
                        
healthReset null;
                    });
                    
healthReset.start();

                    
EventManagerNode spawnNode eventManagerNode.createChildNode();
                    
spawnNode.registerHandler(PlayerSpawnEvent.class, HandlerPriority.NORMAL,
                            
Attentions.create().object(player), spawnEvent -> {
                                
player.setHealth(100000f);
                                
spawnNode.destroy();
                            });

                });
    }

    @
Override
    
protected void onDestroy() {

    }

Let me explain what this code is doing:
When the UserData class gets initialized by the PlayerLifecycleHolder, a new event handler for the PlayerDeath event is registered, but only for the specific player (look at the Attentions.create().object(player) part. The "player" field gets inherited from the PlayerLifecycleObject superclass). When the event gets fired, it will check if a healthReset timer is already running, and if it is, it will be stopped. After that, a new timer will be created that will fire once after 40 seconds. When the timer gets fired, it will check if the player is still connected, and if it is, it will set the health of the player to 100 HP. After that, the timer will set itself to null, just to mark it as "not in use". When the timer has been setted up in the DeathEvent, it will be started. But we also want that the player's health will be set to 10000 HP when he spawns again, so we register a new event manager node with a new handler for the PlayerSpawnEvent but only for the specific player (see Attentions.create()....). In the event, the health of the player will be set to 10000 HP and after that, the handler will destroy itself.
__________________
mk124 is offline   Reply With Quote
Old 27/05/2016, 09:34 PM   #867
Su37Erich
Huge Clucker
 
Su37Erich's Avatar
 
Join Date: Dec 2013
Location: USEA Strangereal
Posts: 343
Reputation: 16
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

Thank you!
It helped me a lot!
Byt the way it would be really nice if you could add something like:
DialogCloseEvent.DialogCloseType PLAYERDISCONNECT
Guess I need to do a workaround if want to detect the dialog id when a player disconnects?
__________________
Neucom Inc.
Su37Erich is offline   Reply With Quote
Old 28/05/2016, 04:22 PM   #868
mk124
Huge Clucker
 
mk124's Avatar
 
Join Date: Jul 2007
Location: Nanning, China
Posts: 319
Reputation: 59
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

@Su37Erich: I added this to the Issue Tracker: http://youtrack.gtaun.net/issue/SA-5 and will implement it in Shoebill 2.0.
__________________
mk124 is offline   Reply With Quote
Old 28/05/2016, 07:38 PM   #869
Su37Erich
Huge Clucker
 
Su37Erich's Avatar
 
Join Date: Dec 2013
Location: USEA Strangereal
Posts: 343
Reputation: 16
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

Thank you
I would like to know if there is some problem with the streamer-wrapper, every time I want to create an object I get the follwing exception:
Code:
[2016-05-28 14:23:31][ERROR][err] kotlin.KotlinNullPointerException
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.streamer.Functions.createDynamicObject(Functions.kt:185)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.streamer.data.DynamicObject$Companion.create(DynamicObject.kt:145)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.streamer.data.DynamicObject$Companion.create$default(DynamicObject.kt:141)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.streamer.data.DynamicObject.create(DynamicObject.kt)
[2016-05-28 14:23:32][ERROR][err] 	at dev.acesamp.Maps.Map.loadObjects(Map.java:48)
[2016-05-28 14:23:32][ERROR][err] 	at dev.acesamp.Maps.Map.<init>(Map.java:20)
[2016-05-28 14:23:32][ERROR][err] 	at dev.acesamp.Maps$LoadedMap.<init>(Maps.java:33)
[2016-05-28 14:23:32][ERROR][err] 	at dev.acesamp.Maps.Maps.<init>(Maps.java:78)
[2016-05-28 14:23:32][ERROR][err] 	at dev.acesamp.MyGamemode.onEnable(MyGamemode.java:38)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.resource.Resource.enable(Resource.java:91)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.resource.ResourceManagerImpl.loadGamemode(ResourceManagerImpl.java:179)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.resource.ResourceManagerImpl.loadAllResource(ResourceManagerImpl.java:62)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.ShoebillImpl.loadPluginsAndGamemode(ShoebillImpl.java:289)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.ShoebillImpl.access$100(ShoebillImpl.java:47)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.ShoebillImpl$1.onAmxLoad(ShoebillImpl.java:233)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.samp.SampCallbackManagerImpl$1.lambda$null$80(SampCallbackManagerImpl.java:60)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.util.TryUtils.tryTo(TryUtils.java:21)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.util.TryUtils.tryTo(TryUtils.java:14)
[2016-05-28 14:23:32][ERROR][err] 	at net.gtaun.shoebill.samp.SampCallbackManagerImpl$1.lambda$onAmxLoad$81(SampCallbackManagerImpl.java:60)
[2016-05-28 14:23:32][ERROR][err] 	at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
[2016-05-28 14:23:32][ERROR][err] 	at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
[2016-05-28 14:23:32][ERROR][err] 	at java.util.concurrent.ConcurrentLinkedQueue$CLQSpliterator.forEachRemaining(ConcurrentLinkedQueue.java:851)
[2016-05-28 14:23:32][ERROR][err] 	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
[2016-05-28 14:23:32][ERROR][err] 	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
[2016-05-28 14:23:32][ERROR][err] 	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
[2016-05-28 14:23:33][ERROR][err] 	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
[2016-05-28 14:23:33][ERROR][err] 	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
[2016-05-28 14:23:33][ERROR][err] 	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
[2016-05-28 14:23:33][ERROR][err] 	at net.gtaun.shoebill.samp.SampCallbackManagerImpl$1.onAmxLoad(SampCallbackManagerImpl.java:60)
My code
Code:
streamerObjects.add(DynamicObject.create(model, new Location(x, y, z, interior, virtualWorld), new Vector3D(rx, ry, rz), streamDistance, distance));

The data:

model: 18449, x: 2953.3, y: -781.94, z:11.45, rx: 0, ry: 0, rz:357.43, distance: 700, streamDistance: 400, interior: -1, virtualworld: -1

I tested it with the 2.7.9 and 2.8.1 streamer plugin version
__________________
Neucom Inc.
Su37Erich is offline   Reply With Quote
Old 29/05/2016, 10:48 AM   #870
mk124
Huge Clucker
 
mk124's Avatar
 
Join Date: Jul 2007
Location: Nanning, China
Posts: 319
Reputation: 59
Default Re: Shoebill 1.1 - SA-MP Java Development Kit

@Su37Erich: Looks like the native function for creating a dynamic object was not found. Are you sure that you load the streamer plugin before Shoebill? Make sure that the streamer entry is positioned before the Shoebill entry in the plugins section in the server.cfg.
__________________
mk124 is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
[FilterScript] [SHOEBILL] Gamemode Reloader mk124 Tools and Files 10 16/05/2016 06:29 PM
[Plugin] [ALPHA] Project Shoebill - Java for SA:MP Development Kit - Milestone 1 (20110701) mk124 Plugin Development 57 05/04/2016 08:23 PM
[GameMode] [Java] PROJECT NEW WL-World (Based on Shoebill, WIP) mk124 Gamemode Scripts 12 01/11/2014 11:16 PM
[FilterScript] Dealership plugin for shoebill (Java) 123marvin123 Filterscripts 4 08/06/2014 02:17 PM


All times are GMT. The time now is 12:35 PM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.