API for developers
EndlessVehicles' API lets another plugin read and use every feature: vehicles, garages, fuel, models, the shop and events.
Adding the dependency
The endlessvehicles-api module only contains interfaces, records, enums and events: the implementation lives in the plugin. Declare it as provided (it must not be bundled in your jar), and your plugin's plugin.yml needs a depend (or softdepend) on EndlessVehicles.
Maven
<repositories>
<repository>
<id>endless</id>
<url>https://endlesshorizons.it/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>it.endlesshorizons.endlessvehicles</groupId>
<artifactId>endlessvehicles-api</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Gradle
repositories {
maven { url = uri("https://endlesshorizons.it/maven") }
}
dependencies {
compileOnly("it.endlesshorizons.endlessvehicles:endlessvehicles-api:1.0.0")
}
plugin.yml
name: MyPlugin
main: com.example.MyPlugin
api-version: '1.21'
depend: [EndlessVehicles]
How to use it
Get the API with EndlessVehiclesApi.get() (once EndlessVehicles is active, for example in your own onEnable). With EndlessVehiclesApi.find() you get an Optional instead of an exception.
EndlessVehiclesApi api = EndlessVehiclesApi.get();
// the vehicle a player is driving
api.vehicles().getRiddenBy(player.getUniqueId()).ifPresent(vehicle ->
player.sendMessage(vehicle.plate() + ": " + vehicle.fuelLiters() + " L"));
// give a vehicle to a garage
GiveResult result = api.vehicles().give("police", "crown_victoria", null, false, GiveSource.COMMAND);
if (result.isOk()) {
api.fuel().addFuel(result.vehicleId(), 20);
}
// sell a vehicle to a player (payments go through Vault)
PurchaseResult bought = api.shop().buy(player, "offroad_black", new VehicleColor(200, 30, 30), null, false);
The services
| Service | What it does |
|---|---|
api.vehicles() | Reading a vehicle (by id, plate, owner, garage, rider); giving one to a garage; taking it out or back in; putting a player in it; locking, renaming, transferring; speed limit; repairing; health; upgrades; trunk; opening the menu. |
api.garages() | Reading garages; creating, deleting, renaming them, changing owner; members and roles with their permissions; checking a permission; opening the menu. |
api.fuel() | Fuel types, level and capacity, adding or setting fuel, creating and reading a jerrycan, list of pumps. |
api.models() | List and details of models (prices, speed, tank, hitbox, colors) and reloading the files. |
api.shop() | Models a player can buy, buying with payment through Vault, opening the shop. |
Results and snapshots
- Operations that change something return a value (
ApiResult,PurchaseResult,UpgradeResult,RepairResult,EnterResult) instead of throwing exceptions:OKis the only success case. Always handle thedefaultcase too, since new values may appear. - Records like
VehicleInfo,GarageInfoandModelInfoare immutable snapshots: they do not update themselves, request the data again.
Rules to know
- Main thread. Every method must be called from the server's main thread.
- Permissions. Operations are "trusted", like a command run by an administrator: they do not check the garage's roles nor the
ev.*permissions. The only exceptions are methods that act on behalf of a player who pays or gets on board (buy,repair(id, player),upgrade,enter), which respect that player's permissions. - Cancellable events. API calls also fire the cancellable events: another plugin can block them (
CANCELLEDresult). - Version.
EndlessVehiclesApi.API_VERSIONonly grows when the API changes;api.getApiVersion()tells you the installed plugin's version. A published version never changes.
Events
Events are plain Bukkit events, in the it.endlesshorizons.endlessvehicles.api.event package, synchronous and on the main thread. Listen with @EventHandler; the cancellable ones are blocked with setCancelled(true).
@EventHandler
public void onEnter(VehicleEnterEvent event) {
var vehicle = EndlessVehiclesApi.get().vehicles().getVehicle(event.getVehicleId()).orElse(null);
if (vehicle != null && vehicle.category() == VehicleCategory.EMERGENCY && !event.getPlayer().hasPermission("police.drive")) {
event.setCancelled(true);
}
}
| Event | When it fires | Cancellable |
|---|---|---|
VehiclePreSpawnEvent | A player is about to take a vehicle out of the garage | yes |
VehicleSpawnedEvent | The vehicle has appeared in the world | no |
VehicleDespawnEvent | The vehicle is about to be removed from the world (reason, and whether it is forced) | yes (not if forced) |
VehicleEnterEvent, VehicleLeaveEvent | A player gets in or out of a seat | yes |
VehicleClickEvent | A player right-clicks a vehicle | yes |
VehicleLockStateChangeEvent | A vehicle is about to be locked or unlocked | yes |
VehicleCollisionEvent | Impact against a block, a living entity or another vehicle | yes (removes damage and knockback) |
VehicleDestroyEvent | Health reaches zero | yes (leaves 1 health) |
VehicleRefuelEvent | Fuel is about to be added | yes |
VehicleUpgradeEvent | An upgrade is about to be bought, before payment | yes |
VehicleBuyEvent | A player is about to buy a vehicle, before payment | yes |
VehicleGiveEvent | A vehicle is about to enter a garage (command, voucher, shop, transfer) | yes |
VehicleDeleteEvent | A vehicle is about to be deleted for good | yes |
GarageOpenEvent | A garage's menu is about to open | yes |
The API's events fire before the plugin's own internal ones: if you cancel an API event, the operation stops.
For whoever publishes the module
The module is endlessvehicles-api (its own version, independent from the plugin). The instructions to build the Maven repository folder and upload it to the web server are in API-PUBLISHING.md at the project's root.