Getting the following when starting up the server, have tried on spongeforge-1.10.2-2221-5.2.0-BETA-2223 and spongeforge-1.10.2-2221-5.1.0-BETA-2210.
[20:28:47] [Server thread/ERROR] [Sponge]: Could not pass FMLServerStartedEvent to Plugin{id=webapi, name=Web-API, version=2.0, description=Access Minecraft through a Web API, url=https://github.com/Valandur/Web-API, authors=[Valandur], source=/home/minecraft/mc/mods/webapi-2.0-sponge-5.1.0-SNAPSHOT.jar}
java.lang.NullPointerException
at valandur.webapi.cache.CachedCommand.copyFrom(CachedCommand.java:28) ~[CachedCommand.class:?]
at valandur.webapi.cache.DataCache.updateCommands(DataCache.java:264) ~[DataCache.class:?]
at valandur.webapi.WebAPI.onServerStart(WebAPI.java:289) ~[WebAPI.class:?]
at org.spongepowered.common.event.listener.GameStartedServerEventListener_WebAPI_onServerStart62.handle(Unknown Source) ~[?:?]
at org.spongepowered.common.event.RegisteredListener.handle(RegisteredListener.java:95) ~[RegisteredListener.class:1.10.2-2221-5.2.0-BETA-2223]
at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:313) [SpongeModEventManager.class:1.10.2-2221-5.2.0-BETA-2223]
at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:342) [SpongeModEventManager.class:1.10.2-2221-5.2.0-BETA-2223]
at org.spongepowered.mod.SpongeMod.onStateEvent(SpongeMod.java:234) [SpongeMod.class:1.10.2-2221-5.2.0-BETA-2223]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_111]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_111]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) [minecraft_server.1.10.2.jar:?]
at net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:243) [LoadController.class:?]
at net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:221) [LoadController.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_111]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_111]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) [minecraft_server.1.10.2.jar:?]
at net.minecraftforge.fml.common.LoadController.redirect$onPost$zzb000(LoadController.java:552) [LoadController.class:?]
at net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:145) [LoadController.class:?]
at net.minecraftforge.fml.common.Loader.serverStarted(Loader.java:868) [Loader.class:?]
at net.minecraftforge.fml.common.FMLCommonHandler.handleServerStarted(FMLCommonHandler.java:297) [FMLCommonHandler.class:?]
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:433) [MinecraftServer.class:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111]
Tried running a command using webAPI, but didnāt work.
What other plugins have you got on the server?
Web-API tries to cache all commands that can be run on the server when starting, and it sounds like that is failing. Maybe because a plugin has a type of command that isnāt supported by the Web-API yet?
Will look into it, possible fix on Monday
Released version 2.0.1 on github & ore which fixes the bug. Still a prerelease though, might contain more bugs.
I realised i didnt make any command examples, so here is one:
Assuming you have a hook in the command part of the hooks.conf file that looks similar to this:
...
{
name = "redeem"
address = "http://localhost:25000/"
method = POST
headers = [{
name = "x-webapi-key"
value = "supersecretkey"
}]
params = [{
name = player
type = player
}]
...
}
...
Now you can run the command /webapi notify redeem @p on the server, and the webserver listening on localhost:25000 (the adress specified) will receive a POST request with a json body which looks similar to this:
[20:41:20] [Server thread/ERROR] [Sponge]: Could not pass DestructEntityEvent$Death$Impl to Plugin{id=webapi, name=Web-API, version=2.0.1, description=Access Minecraft through a Web API, ur
l=https://github.com/Valandur/Web-API, authors=[Valandur], source=/home/minecraft/mc/mods/webapi-2.0.1-sponge-5.1.0-SNAPSHOT.jar}
java.lang.ClassCastException: com.pixelmonmod.pixelmon.entities.pixelmon.EntityPixelmon cannot be cast to org.spongepowered.api.entity.living.player.Player
at valandur.webapi.WebAPI.onEntityDespawn(WebAPI.java:344) ~[WebAPI.class:?]
at org.spongepowered.common.event.listener.DestructEntityEventListener_WebAPI_onEntityDespawn59.handle(Unknown Source) ~[?:?]
at org.spongepowered.common.event.RegisteredListener.handle(RegisteredListener.java:95) ~[RegisteredListener.class:1.10.2-2221-5.1.0-BETA-2210]
at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:313) [SpongeModEventManager.class:1.10.2-2221-5.1.0-BETA-2210]
at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:297) [SpongeModEventManager.class:1.10.2-2221-5.1.0-BETA-2210]
at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:338) [SpongeModEventManager.class:1.10.2-2221-5.1.0-BETA-2210]
at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:326) [SpongeModEventManager.class:1.10.2-2221-5.1.0-BETA-2210]
at org.spongepowered.common.SpongeImpl.postEvent(SpongeImpl.java:143) [SpongeImpl.class:1.10.2-2221-5.1.0-BETA-2210]
at org.spongepowered.common.event.SpongeCommonEventFactory.callDestructEntityEventDeath(SpongeCommonEventFactory.java:497) [SpongeCommonEventFactory.class:1.10.2-2221-5.1.0-BETA-221
0]
at net.minecraft.entity.EntityLivingBase.func_70645_a(EntityLivingBase.java:3080) [sf.class:?]
at net.minecraft.entity.passive.EntityTameable.func_70645_a(SourceFile:204) [sq.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity3HasStats.func_70645_a(Entity3HasStats.java:316) [Entity3HasStats.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity8HoldsItems.func_70645_a(Entity8HoldsItems.java:213) [Entity8HoldsItems.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.EntityPixelmon.func_70645_a(EntityPixelmon.java:144) [EntityPixelmon.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity6CanBattle.func_70097_a(Entity6CanBattle.java:255) [Entity6CanBattle.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity10CanBreed.func_70097_a(Entity10CanBreed.java:1159) [Entity10CanBreed.class:?]
at net.minecraft.entity.EntityLivingBase.func_70030_z(EntityLivingBase.java:273) [sf.class:?]
at net.minecraft.entity.EntityLiving.func_70030_z(EntityLiving.java:208) [sg.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity7HasAI.func_70030_z(Entity7HasAI.java:110) [Entity7HasAI.class:?]
at net.minecraft.entity.Entity.func_70071_h_(Entity.java:359) [rw.class:?]
at net.minecraft.entity.EntityLivingBase.func_70071_h_(EntityLivingBase.java:1932) [sf.class:?]
at net.minecraft.entity.EntityLiving.func_70071_h_(EntityLiving.java:295) [sg.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity1Base.func_70071_h_(Entity1Base.java:339) [Entity1Base.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity2HasModel.func_70071_h_(Entity2HasModel.java:255) [Entity2HasModel.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity3HasStats.func_70071_h_(Entity3HasStats.java:536) [Entity3HasStats.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity4Textures.func_70071_h_(Entity4Textures.java:413) [Entity4Textures.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity5Rideable.func_70071_h_(Entity5Rideable.java:409) [Entity5Rideable.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity8HoldsItems.func_70071_h_(Entity8HoldsItems.java:75) [Entity8HoldsItems.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.Entity10CanBreed.func_70071_h_(Entity10CanBreed.java:109) [Entity10CanBreed.class:?]
at com.pixelmonmod.pixelmon.entities.pixelmon.EntityPixelmon.func_70071_h_(EntityPixelmon.java:328) [EntityPixelmon.class:?]
at org.spongepowered.common.event.tracking.TrackingUtil.tickEntity(TrackingUtil.java:156) [TrackingUtil.class:1.10.2-2221-5.1.0-BETA-2210]
at net.minecraft.world.WorldServer.redirect$onCallEntityUpdate$zjn000(WorldServer.java:2810) [ls.class:?]
at net.minecraft.world.World.func_72866_a(World.java:4071) [aid.class:?]
at net.minecraft.world.WorldServer.func_72866_a(WorldServer.java:839) [ls.class:?]
at net.minecraft.world.World.func_72870_g(World.java:1934) [aid.class:?]
at net.minecraft.world.World.func_72939_s(World.java:5954) [aid.class:?]
at net.minecraft.world.WorldServer.func_72939_s(WorldServer.java:2153) [ls.class:?]
at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:709) [MinecraftServer.class:?]
at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:387) [ld.class:?]
at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:613) [MinecraftServer.class:?]
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:471) [MinecraftServer.class:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111]
Also, how do I send POST variables over? Have this:
command=[
{
# This is the address of the endpoint. It may contain parameters that are replaced when being called.
# Parameters have to be placed in curly braces, { and }, and will be a simple string (uuid of object
# where applicable)
address="http://domain.com/command.php"
# Set to true or omit to enable the endpoint.
enabled=true
# This is a list of additional headers that is sent to the server. You can use this to e.g. specify a secret
# key which ensures that the server knows the requests are coming from the Web-API. You may also use variables
# here (same format as in "address"). Please note the headers "User-Agent", "Content-Type" and "Content-Length"
# will always be overridden by the WebAPI.
headers=[
{
name=X-WEBAPI-KEY
value=MY-SUPER-SECRET-KEY
},
{
name=X-TEST-HEADER
value="{player}"
}
]
# This is the http method that is used (GET, PUT, POST or DELETE)
method=POST
# This is the name of the endpoint, which is used to call it via the webapi command.
name=test
# Here you have to specify what parameters are used in the address, headers and body.
# Parameters in the address and headers have to be used explicitly, the body automatically contains all the
# parameters that are listed here. The parameters are expected to show up in this order when calling the command
params=[
{
name=player
type=player
}
]
}
]
I released another version that should fix most issues still around. Version 2.0.2 is on Ore and GitHub.
Please note that the hooks.conf and cache.conf file structures have changed
@tridaak concerning the POST array: I added a new property to the hooks in the config. You can now set dataType = FORM on the hook and the data will be sent as form-urlencoded instead of json (The data itself is still json). You would then access it on php with $data = json_decode($_POST["body"]).
Hmm, so some time has passed and have gotten to tinker a bit more with it, and have some concerns and suggestions:
-Was wondering if you could add command nodes to the web-api, so that players to be able to execute certain commands. Ie, webapi.notify.test for the command /webapi notify test
āAlong with this, it would be nice if aliases could be assigned to it (although not a big issue, there is the aliases plugin)
āReason something like this would be useful is for custom commands.
-Using the web-hook for commands (sends data to the server whenever someone runs a command, the source isnāt identifying the player properly:
Sample output for when I run /help: {ātimestampā:1490319422,ācommandā:āhelpā,āargsā:[""],āsourceā:(raw value ā[RawValue of type java.lang.String]ā),āresultā:{}}
-When the server closes, it does not fire the player_leave event, if using player_join and player_leave to calculate the amount of time the person has been playing on the server, it could lead to a problem.
Aside from that, really enjoying the changes, thanks for adding the waitTime and waitLines variables when executing commands
I am assuming with ācommand nodesā you mean permissions? These are already provided (I forgot to document them). The permission name is āwebapi.command.notify.[name]ā where name is the name of the command.
Iām still not sure about the aliases, it feels like itās not part of the scope of the project, but Iāll think about.
I fixed the json output of the players, that will be in the next update.
Iām not sure if the server closing should be part of the sponge functionality, but Iāll look into it
Add class name and parent class name to /class endpoint
I did not make the server closing call PLAYER_LEAVE hooks, however there is a SERVER_STOP hook which can be subscribed to. (Sponge itself doesnāt fire PlayerLeave events when the server is closing, so it didnāt feel right to do that. Maybe Iāll add this later)
Finally got the chance to update webapi, getting the following:
[03:02:47] [Server thread/INFO] [webapi]: Starting Web Server...
[03:02:47] [Server thread/INFO] [webapi]: jetty-9.4.z-SNAPSHOT
[03:02:47] [Server thread/INFO] [webapi]: Started o.e.j.s.h.ContextHandler@6342efb1{/,null,AVAILABLE}
[03:02:47] [Server thread/INFO] [webapi]: Started o.e.j.s.h.ContextHandler@13708ff3{/docs,null,AVAILABLE}
[03:02:47] [Server thread/INFO] [webapi]: Started o.e.j.s.ServletContextHandler@28878ab7{/api,null,AVAILABLE}
[03:02:47] [Server thread/INFO] [webapi]: Started ServerConnector@d6a4865{HTTP/1.1,[http/1.1]}{localhost:8080}
[03:02:47] [Server thread/INFO] [webapi]: Started @53385ms
[03:02:47] [Server thread/INFO] [webapi]: Web server running on http://localhost:8080/
[03:02:47] [Server thread/ERROR] [Sponge]: Could not pass FMLServerStartedEvent to Plugin{id=webapi, name=Web-API, version=2.1.0-S5.1, description=Access Minecraft through a Web API, url=ht
tps://github.com/Valandur/Web-API, authors=[Valandur], source=/home/minecraft/mc/mods/webapi-2.1.0-S5.1.jar}
java.lang.AbstractMethodError: Method net/minecraftforge/fml/common/event/FMLServerStartedEvent.getCause()Lorg/spongepowered/api/event/cause/Cause; is abstract
at net.minecraftforge.fml.common.event.FMLServerStartedEvent.getCause(FMLServerStartedEvent.java) ~[FMLServerStartedEvent.class:?]
at valandur.webapi.WebAPI.onServerStart(WebAPI.java:287) ~[WebAPI.class:?]
at org.spongepowered.common.event.listener.GameStartedServerEventListener_WebAPI_onServerStart74.handle(Unknown Source) ~[?:?]
at org.spongepowered.common.event.RegisteredListener.handle(RegisteredListener.java:95) ~[RegisteredListener.class:1.10.2-2254-5.2.0-BETA-2272]
at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:313) [SpongeModEventManager.class:1.10.2-2254-5.2.0-BETA-2272]
at org.spongepowered.mod.event.SpongeModEventManager.post(SpongeModEventManager.java:342) [SpongeModEventManager.class:1.10.2-2254-5.2.0-BETA-2272]
at org.spongepowered.mod.SpongeMod.onStateEvent(SpongeMod.java:234) [SpongeMod.class:1.10.2-2254-5.2.0-BETA-2272]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_111]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_111]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) [minecraft_server.1.10.2.jar:?]
at net.minecraftforge.fml.common.LoadController.sendEventToModContainer(LoadController.java:243) [LoadController.class:?]
at net.minecraftforge.fml.common.LoadController.propogateStateMessage(LoadController.java:221) [LoadController.class:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_111]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_111]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_111]
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304) [minecraft_server.1.10.2.jar:?]
at com.google.common.eventbus.EventBus.post(EventBus.java:275) [minecraft_server.1.10.2.jar:?]
at net.minecraftforge.fml.common.LoadController.redirect$onPost$zzb000(LoadController.java:552) [LoadController.class:?]
at net.minecraftforge.fml.common.LoadController.distributeStateMessage(LoadController.java:145) [LoadController.class:?]
at net.minecraftforge.fml.common.Loader.serverStarted(Loader.java:868) [Loader.class:?]
at net.minecraftforge.fml.common.FMLCommonHandler.handleServerStarted(FMLCommonHandler.java:297) [FMLCommonHandler.class:?]
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:433) [MinecraftServer.class:?]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_111]
I released a first version of v3, although I marked it as a pre-release because it might still have some issues, it should be mostly stable.
Quite a few response objects from /entity, /tile-entity, /player and /world have changed. Please make sure your code still works with the new endpoints when updating.
I have implemented the following changes:
Add /block endpoint to query & set blocks in the world
Rework endpoints to provide more consistent and better structured data
Add fine grained permission nodes for commands run via /cmd endpoint
Add 100% more error messages for endpoints
The releases are for SpongeAPI 5.2 and 6.0. 5.2 should work for 5.1 aswell.
That is exactly what hooks are meant for. If you check in the webapi/hooks.conf config file you will find some description there. I will try and explain it real quick.
The hooks listed in events are called when certain minecraft events happen. So for example all the hooks listed in events.player_join are called when a player joins.
A hook is basically just another endpoint (URL) which the Web-API contacts. A simple example could look like this:
events {
player_join=[
{
address="http://localhost:25000"
method=POST
#dataType=FORM # Add this if you're using PHP since it makes it easier to read the data
}
]
}
This would send a POST request to http://localhost:25000 whenever a player joins. The request would contain a json body containing information about the player that joined.
I hope that clears things up, and I will try to add more tutorials as soon as I can
You can add constant headers (such as the X-WEBAPI-KEY). Parameters in headers, such as {source} donāt work in events (the data should already be included in the request body), they only work with the command hooks.