spongepowered / spongeapi Goto Github PK
View Code? Open in Web Editor NEWA Minecraft plugin API
Home Page: http://www.spongepowered.org/
License: MIT License
A Minecraft plugin API
Home Page: http://www.spongepowered.org/
License: MIT License
A plugin that I developed for bukkit requires me to create large structures across many chunks. These chunks have to have already been generated (whether they are loaded or not) and devoid of vanilla ores. I've also gotten requests that I make this plugin compatible with already generated worlds. To make doing this easier I request that the following methods be added to the world class:
/*
* Returns whether a particular chunk has already generated structures, 'the layer', and 'decorations'
* regardless of its load status.
*/
public boolean isGenerated(int x, int z)
/*
* Returns a List of all the chunk coordinates that have already been 'decorated' regardless of load
* status. The list is a snapshot of the world as it was when the method was called. String can be
* replaced by other objects more suited to coordinate retrieval, but otherwise only contain the x & z
* coordinate data of the chunks within the world.
*/
public List<String> getWorldChunkList()
Edit: clarified what I meant by 'generated' .@gratimax pointed out that during chunk generation structures are generated first, then the 'layer' (terrain landforms), and then 'decorators'.
This was discussed previously on IRC.
Currently, the World Border API follows Vanilla, in that only one border exists per world.
Allowing a different world border to set for each player, similar to setting a different scoreboard per player in Bukkit, would afford tremendous flexibility to plugins.
Potential use cases
@mbaxter and I agreed that this was technically possible (nothing in the protocol would prevent this).
However, @Kobata was against this, arguing that it would be difficult to implement.
Other ideas:
(I apologize if I got any information wrong regarding the discussion in IRC)
I've just been looking through the API and noticed something - Almost everything is an interface.
Not only does this allow things like "class Foo implements PlayerEvent, BlockEvent, ChatEvent, Game, PluginManager,..." to be done, it violates standard Java coding conventions.
I realize this is very tedious to change, but I believe it is necessary.
If this is already planned to be changed in the future, or I'm making a big deal over nothing, please inform me.
I think that class shouldn't be called this way, due it's weird to see methods like "Message getDisplayName()" (if that can be used not only in chat) or to see it on signs or books.
ColoredComponent/ChatComponent/StyledText/whatever
I invoke the vote, more suggestions and ideas, please.
I feel this needs to be added for pretty obvious reasons.
The annotation org.spongepowered.api.event.SpongeEventHandler is inconsistent with the rest of the API. To fix this, we can either:
Opinions?
As recipe handling is done on the server, Sponge should have some form of recipe handling.
Classes
Other
This is a placeholder ticket for a permissions API.
From what I can see the VillagerFactory class is useless as all the functionality it provides is also provided by GameRegistry and Career.
Some methods use return types which are imported from "com.flowpowered.math.vector.*":
org.spongepowered.api.block.BlocLoc, line 61: Vector3i getPosition()
org.spongepowered.api.effect.Viewer: All methods have arguments of not exisitng Vector type.
org.spongepowered.api.entity.Entity, line 84 and 91: Vector3f getRotation() and void setRotation(Vector3f)
org.spongepowered.api.entity.ArmorStand, most methods
org.spongepowered.api.entity.living.Living, line 201: Vector3f getEyeLocation()
org.spongepowered.api.entity.projectile.EyeOfEnder, line 39 and 46: "Vector3d getTargetedLocation()" and "void setTargetedLocation(Vector3d)"
org.spongepowered.api.entity.projectile.source.ProjectileSource, line 52: T launchProjectile(Class, Vector3f)
org.spongepowered.api.entity.projectile.source.UnknownProjectileSource, line 42: public T launchProjectile(Class projectileClass, Vector3f velocity)
org.spongepowered.api.entity.minecart.Minecart: Some methods
And more...
I'm proposing that we break away from assuming an entity caused an event (like Bukkit). I have code ready for a PR that establishes:
BlockBreakEvent extends BlockEvent
A generic event for when a block is brokenEntityBlockBreakEvent extends BlockBreakEvent, EntityEvent
A subclass that indicates the break was caused by an entity/Player (note: depends on pr #36 for entity event interface)Per request, I'm posting here before submitting a PR.
Hey,
with bukkit there were often problems if two or more plugins tried to modify chat messages on a per-player basis at the same time: The usual approach was something similar to canceling the PlayerChatEvent and sending each player the specifically modified message manually, which only works well for one plugin..
Possible use-cases:
It would be nice to have this unified in sponges api: so that the PlayerChatEvent offers the possibility to modify the message, formatting and canceling state (similar to the recipients set in bukkit's chat event) for specific players.
Currently there isn't a way to compile the example plugin at all, because it is located in src/example/main/java/
, a path that is completely ignored by Gradle currently. This should probably be separated into another subproject.
I considered that Doxygen would be nice for Documentation. I could host it and keep it up2date.
Most events refer to the target/victim (i.e. EntityEvent), but PlayerEvent currently refers to a player as the initiator.
The Sponge API is in need of maps. A potential map API would most likely look very similar to bukkit's map API, although any improvements are welcome.
Some things to consider:
Currently, one can make a command by extending CommandCallable
. However, we probably want to provide a helper library to go along with it to make the creation of commands easier.
As previously discussed, we want to:
Extent
(extent.setBlock(coords, blockType)
, etc.)BlockLoc
into a API-side proxy like Location
teleport()
on Extent
making zero sense (we may want to move it to World
).This should be done in a branch for further discussion.
Would it make more sense to have cancelled events ignored by default, since they are cancelled? Or perhaps change the ignoreCancelled annotation to something like listenCancelled, and it can be used to intentionally listen to cancelled events.
I don't know if this is planned in conjunction with the Inventory API, but I'd like a way to get the inventory of an offline player.
Use case: Sometimes I want to swap something from my inventory with another player's, but they are offline. With offline access, it could enable trading for offline players. This might be useful for web-based trading areas, which can offer a better UI than Minecraft for trading.
This is not much of a concern but more of a convenience measure for those who use java 7 and above. Currently there is no way to switch case ids for blocks and items against a constant due to the lack of use of enums. However in java 7 switch casing strings is possible and final String constants can be used as the case values.
Further more if just feels right to have access to the vanilla id values as String constants without having to go through the BlockType or ItemType constants located in BlockTypes and ItemTypes.
Something along the lines of a BlockIds and an ItemIds class.
Seeing as the GameMode and GameModes classes consider "game" and "mode" two separate words, I feel as though PlayerChangeGamemodeEvent should do the same for the sake of consistency. However, this is a very minor issue, and may not be worth fixing given the fact that it is breaking between 1.0 and the next release.
I've seen that Sponge is using an "order" now instead a priority which was used in bukkit. You can say that this is a synonym but: I think using both will be great.
So an event listener execution is defined in two ways:
This makes it possible for Sponge and its plugins to specify when they want Sponge to execute their code. The general order explains if it should read the unmodified, modified or completly changed event. The priority says in which order the different listeners should be executed.
For PRE and POST it is possible that the priority is not necessary.
Sponge should have a Ban API.
I believe you could take all the good parts from Bukkit (eg 2 BanList's (IP, NAME)) and combine them with your own ideas.
I would go about doing this with BanManager's.
The functionality should be simple:
You should be able to:
manager.getEntry(String);
BanManager should accessed through Server.
There are a 2 ways you could go about making BanEntry:
If you do it as a class you could pass in all the info like
banManager.addBan(new BanEntry("ExampleTarget", "ExampleSource", "ExampleReason"));
You could also add an optional Date expires
argument.
However if you do it as an interface you would have to create the BanEntry through the banManager like:
BanEntry entry = banManager.createBan("ExampleTarget", "ExampleSource", "ExampleReason")
and add it the same way, and also you could add a optional Date expires
argument.
With events being registered by passing an object like so...
public class Listener {
@subscribe
public void onSomething(SomethingEvent event) {
}
}
game.getEventManager().register(new Listener()));
However would it be possible / good idea to implement it such that if an instance of Class<?> were passed, then we could do this as well.
public class Listener {
@subscribe
public static void onSomething(SomethingEvent event) {
}
}
game.getEventManager().register(Listener.class));
What do you think?
It seems like two conventions are going on at the same time with names of subclasses. In the Entity package it's Entity and LivingEntity, HumanEntity. In the Item package it's Item and ItemBlock rather than BlockItem.
I feel like one convention should be decided.
If I am not mistaken Game.broadcastMessage()
just sends a message to every online player along with the console. So wouldn't it make sense to give it the same overload functionality as Player.sendMessage()
?
The Sponge API still needs selectors. Some things to consider:
@p[team=Red]
should happen with some builders, factories, or even instantiating data classesWe are waiting on @kenzierocks for a possible PR/wip PR. (#297)
I see that a plugin API is among the few API parts that has already been started, and I was a bit surprised by this. From the documents I have read it seems that Sponge is intended to use some of the Flow libraries, and I was therefore suprised that Flow-Plugins was not used.
I am aware that you are probably doing private(or public) discussions about what existing librariess to use, and how new APIs should be designed, and that you therefore may have made a desicion on this. If you have, I am curious about what factors lead you to start a new plugin API/system, and if you have not, I would like to vouch for using Flow-Plugins.
I think everyone here at one point needed to create one or more commands for their mod. You need to create a new Class for each Command or Subcommand (if you implemented such a system) which is quite a drag. I've played around with something in my own mod and I was able to create a method-based commands/subcommands system which makes creating commands for your mods much easier. I would like to implement this in Sponge since I find it much better than the class-based command system and the lack of subcommands. HERE is the code I'm talking about.
It's basically using an annotation and a model class which is then registered. Atm there are 2 annotations (one for commands another for subcommands) but I can merge them into one. I also have custom permission check (other than the per-player permission) and tab completion already implemented. At this point in time not everything is optimized, but I think it could be better if tweaked well enough.
Sooo... what do you guys think? Would this be a good idea for a Sponge commands system?
In Lightning.java there is currently no way to set if the lighning bolt is just an effect.
When building against the 1.1 snapshot I am unable to reference the vector classes from the flow math dependency.
Most notable is this compile warning found near the package deceleration
"The type com.flowpowered.math.vector.Vector3d cannot be resolved. It is indirectly referenced from required .class files"
This was brought up in https://forums.spongepowered.org/t/sponge-api-disconnecting-a-player-user/5197. Preferably a method to force disconnection of an online player coupled with some sort of ban system is best here, although I think having plain setBanned
getBanned
is not enough.
A networking / packet API has been requested.
Order.POST and Order.BEFORE_POST should be used for SOLELY monitoring the outcome and preparing for the monitoring respectively, as was described in their functionality. There should not be any sort of cancellation ability as this may break rollback, logging, or similar plugins who need to know the outcome without it being edited. Any last minute things should be put in LAST.
Either this, or there should be a value specifically for monitoring the outcome that comes after POST.
This of course would be an easy change due to nothing being implemented yet, just 2 javadoc changes and whatever your ideas document is being edited.
The addition of a Extent getParent();
method for Extent
would further improve its usability for what I view it as (a means to redefine origin). World
would return it self and every non world Extent
would (or should) recursively return back to a root World.
What this opens up is for the ability to have Location
represent local coordinates for an extent such that a Location
would have local coordinates while also having the global coordinates of the root World
to call for teleportation and blocks.
Chunk
extends Extent
and is already an example of redefining origin, to a chunk origin is at its corner in steps of 16 from the worlds origin depending on chunk position. A chunk's parent would obviously be the World
it's a chunk of.
As for a use case, say you have an arena plugin with http://pastebin.com/uJ0d2Dbk
Next create some utility to convert World Vector3d
to Arena Vector3d
, lets call it
Vector3d worldToLocal(Extent extent, Vector3d positoon);
this method would convert a vector from world space to the extent's local space, returning the same vector if the extent is world. a similar utility to do the reverse would also be needed
Vector3d localToWorld(Extent extent, Vector3d position);
Moving an arena area to another position or world would now be a simple process, simply iterate over the arena entities and teleport to new Location(arena, worldToLocal(arena, entity.getPosition()));
after setting a new position or world.
Any Extent
regions using the arena as a parent (trap regions, spawn regions) need not be changed if implemented the same way; the coordinates will just recursively be correct as they get converted up the tree.
There should be: BlockInteractEvent
and EntityInteractEvent
for when blocks and entities are interacted with, respectively. PlayerInteractBlockEvent
should exist as well and it should extend PlayerInteractEvent
and BlockInteractEvent
.
Likewise, we may also want EntityInteractBlockEvent
, BlockInteractBlockEvent
, etc., although it is not urgent.
Currently, the Fireball
interface has two subclasses: SmallFireball
and LargeFireball
. SmallFireball
adds no new methods, while LargeFireball
getExplosionPower
and setExplosionPower
. These methods affect the amount of block damage done.
WitherSkull
is currently a subclass of Fireball
. However, it can't really be considered a fireball, though it is an explosive projectile. Additionally, it has no methods its block damage, like LargeFireball
does.
I propose that we create two new interfaces:
ExplosiveProjectile
, which would inherit from the same interfaces as Fireball
currently does.BlockDamagingExplosive
.WitherSkull
and LargeFireball
would each inherit from ExplosiveProjectile
and BlockDamagingExplosive
, while SmallFireball
would only inherit from ExplosiveProjectile
.
Much of the command block 'scripting' ability comes from the command stats concept.
There are five of these in vanilla, SuccessCount
, AffectedBlocks
, AffectedEntities
, AffectedItems
, and QueryResult
. Of these, SuccessCount
and AffectedEntities
have special support inside the command processor.
When running a command, vanilla expands the main target selector, and then runs the command once for each targeted entity. During this process it keeps track of how many times the command succeeded (defined as 'did not throw an exception' because Mojang), this count becomes SuccessCount
and also the return value of the method as command blocks store the count separately for comparator support. The expanded selector's full count becomes the value of AffectedEntities
The rest of the stats (and occasionally AffectedEntities
for commands that do not use the standard selector expansion, see /spreadplayers
) are set by each individual command by calling a function on the command sender.
The basic support for the non-special stats is fairly easy, but getting the automatic SuccessCount
/AffectedEntities
support requires a bunch of changes to the default command implementation in SimpleCommandService
/SimpleDispatcher
, and likely some changes to the command interfaces.
Currently, there is no way short of manipulating packets to edit the information sent to a client when it pings the server. Here is the data sent to the client:
In the proposal, almost all of the data would be editable directly, except for two things: the GameProfiles and the online players number. These would be determined by a List that the plugin could edit, the players visible to the client. There would also be a way to override the default maximum of how many players are in the GameProfile list.
All of these are in my proposal except for the very last. Short of using GameProfile objects themselves, it may be difficult to represent these, since they are a string, the player's name, a UUID, the ID of the player, and a "com.mojang.authlib.properties.PropertyMap" which I am not sure of it's uses. It has name-value-"signature" triplets, and appears to somehow validate these signatures with a public key. I am not sure what to do with it. It's used for skins, and possibly other info. The server doesn't send it to the client in this case however so we can safely say there is no reason to modify it.
A second part of this would be to figure out how it is possible to change the MOTD without the client manually refreshing. It is either that the client does it automatically or that the server can force the client to refresh.
Anyway, here is my proposal so far.
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered.org <http://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.api.event.ping;
import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
import java.util.List;
import org.spongepowered.api.entity.player.Player;
import org.spongepowered.api.text.message.Message;
public interface ServerListPingEvent{
/**
* Get the address pinging the server.
* @return The address pinging the server.
*/
InetSocketAddress getAddress();
/**
* Get the MOTD that will be seen by the pinger.
* @return The MOTD that will be seen by the pinger.
*/
Message getMOTD();
/**
* Sets the MOTD that will be seen by the pinger.
* @param message The new message that will be seen by the pinger.
*/
void setMOTD(Message message);
/**
* Gets the Minecraft version that will be seen by the pinger.
* @return The Minecraft version that will be seen by the pinger.
*/
String getMCVersion();
/**
* Sets the Minecraft version that will be seen by the pinger.
* @param version The new Minecraft version that will be seen by the pinger.
*/
void setMCVersion(String version);
/**
* Gets the Protocol version that will be seen by the pinger.
* @return The Protocol version that will be seen by the pinger.
*/
int getProtocolVersion();
/**
* Sets the Protocol version that will be seen by the pinger.
* @param version The new Protocol version that will be seen by the pinger.
*/
void setProtocolVersion(int version);
/**
* Gets the image that will be seen by the pinger as the server's icon.
* @return The image that will be seen by the pinger as the server's icon.
*/
BufferedImage getFavicon();
/**
* Sets the image that will be seen by the pinger as the server's icon.
* @param image The new image that will be seen by the pinger as the server's icon.
*/
void setFavicon(BufferedImage image);
/**
* Gets the maximum players number that will be seen by the pinger.
* @return The maximum players number that will be seen by the pinger.
*/
int getMaximumPlayers();
/**
* Sets the maximum players number that will be seen by the pinger.
* @param maximumPlayers The new maximum players number that will be seen by the pinger.
*/
void setMaximumPlayers(int maximumPlayers);
/**
* Gets the players that will be seen by the pinger.
* @return The players that will be seen by the pinger.
*/
List<Player> getShownPlayers();
/**
* Sets the players that will be seen by the pinger.
* @param players The new players that will be seen by the pinger.
*/
void setShownPlayers(List<Player> players);
/**
* Gets the amount of players that will be seen in a list by the pinger.
* @return The amount of players that will be seen in a list by the pinger.
*/
int getMaximumListedPlayers();
/**
* Sets the amount of players that will be seen in a list by the pinger.
* @param players The new amount of players that will be seen in a list by the pinger.
*/
void setMaximumListedPlayers(int maximumListedPlayers);
}
The proposal also includes the removal of getMOTD from Server.java, because it is no longer guaranteed to be the MOTD shown to clients. I recommend a ServerProperties object under Server to store the configured MOTD, and other things in server.properties, but that is another Issue.
Currently, We have something for representing data from various sources with DataView
and DataContainer
.
In Issue #256, we have the request for some WorldStorage
to get all existing generated chunks.
Loading chunks is a slow process, and certainly, loading ALL existing chunks into memory will likely slow down the JVM for actually loading and then storing massive objects (hint: the JVM will likely run out of memory first).
So, considering getting things like all existing chunks is something storage related, I've considered making the proposal to adding it to Persistence API.
Here's the proposal:
/**
* A chunk iterator represents a buffer for obtaining chunk data from
* storage without having to explicitly load into memory all available
* chunks.
* <p>This avoid loading all chunks into memory at once, reducing the memory
* footprint and persistence operations.</p>
* <p>The chunks are loaded individually in sequence. Strong references to
* the chunks represented by {@link DataContainer}s should be avoided
* <strong>AT ALL COSTS</strong>. The data represented is a copy and
* therefore shouldn't be considered synchronized to live data.</p>
*
*/
public interface ChunkIterator extends Iterator<DataContainer> {
/**
* Chunks can not be removed by a ChunkIterator.
*
* @throws UnsupportedOperationException Not supported at all
*/
@Override
void remove() throws UnsupportedOperationException;
}
public interface WorldStorage {
/**
* Gets a {@link ChunkIterator}
* @return
*/
ChunkIterator getGeneratedChunks();
}
Essentially, this would allow getting all available chunks through this WorldStorage
and a nifty ChunkIterator
that allows you (the developer) to get all generated chunks according to storage, without having to stress the system of loading all available chunks.
Further additions will be made as the issue is discussed.
Tagging possibly interested parties: @mikeprimm @gratimax @el-minadero @modwizcode
The Sponge API needs scoreboards, see the wiki article for how they work. We're interested in scoreboard API proposals, mostly.
I know @Aaron1011 has been working on this, waiting on him for a PR/wip PR.
Hey,
in the past there were various situations in which I spawn entities temporary in the world via plugins and later remove them again.
It would be useful to add some boolean flag to entities which determines whether or not an entity is going to be saved to disk together with the world data.
Maybe something like:
Entity.isPersistent()
Entity.setPersistent(boolean)
A concrete usecase:
This works fine as long as the server does not crash or gets killed. If the server has saved those entities together with the world data to disk before crashing those entities will still be in the world on the next server restart. Something I originally wanted to prevent.
In the past I worked around this issue by trying to identify and then remove those remaining entities once the server starts up again. This however is/was tricky on craftbukkit because one couldn't be sure when the entity actually was saved to disk. Consider the following concrete scenario:
NPC plugins usally created their own entity classes which extended minecraft's original entity classes for each entity type they want to support, and which simply don't save those entities to disk by overriding the methods which are responsible for that.
However if no other functionality is needed it would be far easier and cause less trouble to simply have the suggested flag and marking the entity to not be saved.
Something I at least would find useful is a tick value incremented by the server every tick with a similar functionallity to System.currentTimeMillis()
. It would only increment while the server is running and would persist through server stopping and starting. The method to get the value would probably be located in Server
and be called currentTimeTicks()
.
The purpose would be to provide a reference point for scheduler based systems to compare a target value with the current value in a manner that is persistent across server restarts. (e.g. Timeline based events that you want to sync against server run time instead of real time)
Another side benefit would be a way to tell how long a Task
has been running by storing the value when the task was created and a method to compare it to what the value is on method call.
I think the Contribution Guidelines should be moved to a CONTRIBUTING.md
file in the root folder of the project (as many other projects have done).
Track at #860
Minor Issues List
Direction:30
GameMode
javadoc uses fully qualified link to Player
DataHolder
are generic although they don't have to. This leads to worse usability / more raw casts. See comment: #221 (comment)AbstractInventoryProperty
could extend AbstractProperty
. See comment: #221 (comment) for moreCheckstyle warnings
File | Problem |
---|
Wouldn't it make more sense to use X and Z instead of X and Y for the coordinate values for the interfaces 'Vector2d' 'Vector2i' and 'Vector2f'?
I say this considering that the primary use of a 2 dimensional vector would most likely be used along the Block/Chunk X/Z axis.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.