Skip to content

Commit

Permalink
Implement full region API
Browse files Browse the repository at this point in the history
  • Loading branch information
Mindgamesnl committed May 19, 2024
1 parent b67dcb9 commit e9dd7b3
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 56 deletions.
70 changes: 64 additions & 6 deletions api/src/main/java/com/craftmend/openaudiomc/api/WorldApi.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.craftmend.openaudiomc.api;

import com.craftmend.openaudiomc.api.exceptions.InvalidRegionException;
import com.craftmend.openaudiomc.api.exceptions.InvalidThreadException;
import com.craftmend.openaudiomc.api.exceptions.UnknownWorldException;
import com.craftmend.openaudiomc.api.regions.AudioRegion;
import com.craftmend.openaudiomc.api.regions.RegionMediaOptions;
import com.craftmend.openaudiomc.api.speakers.BasicSpeaker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -16,6 +20,7 @@ public interface WorldApi {

/**
* Get an instance of the world api. May be null if the plugin is not loaded yet
*
* @return instance
*/
static WorldApi getInstance() {
Expand All @@ -27,9 +32,10 @@ static WorldApi getInstance() {

/**
* Get all regions at a location
* @param x x
* @param y y
* @param z z
*
* @param x x
* @param y y
* @param z z
* @param world world
* @return regions
*/
Expand All @@ -38,13 +44,65 @@ static WorldApi getInstance() {

/**
* Get a speaker at a location, or null if invalid
* @param x x
* @param y y
* @param z z
*
* @param x x
* @param y y
* @param z z
* @param world world
* @return speaker
*/
@Nullable
BasicSpeaker getSpeakerAt(int x, int y, int z, @NotNull String world);

/**
* Register a region in a world.
* Important:
* - this will overwrite current temporary regions
* - this will throw an invalid region exception if the region is not found
* - this will throw an unknown world exception if the world is not loaded
* - this will throw an invalid region exception if the region already has permanent media
* - this will throw an invalid thread exception if not called from the main thread
*
* @param worldName world
* @param regionId id
* @param regionMedia the media to attach
* @throws UnknownWorldException if the world is not loaded
* @throws InvalidRegionException if the region is not found
* @throws com.craftmend.openaudiomc.api.exceptions.InvalidThreadException if not called from the main thread
* @since 6.10.2
*/
void registerRegion(String worldName, String regionId, RegionMediaOptions regionMedia) throws
UnknownWorldException, InvalidThreadException, InvalidRegionException;

/**
* Register a temporary region in a world
* Important:
* - this will overwrite current temporary regions
* - this will throw an invalid region exception if the region is not found
* - this will throw an unknown world exception if the world is not loaded
* - this will throw an invalid region exception if the region already has permanent media
* - this will throw an invalid thread exception if not called from the main thread
*
* @param worldName world
* @param regionId the region to targe
* @param regionMedia the media to attach
* @param duration the duration in seconds
* @throws UnknownWorldException if the world is not loaded
* @throws InvalidRegionException if the region is not found
* @throws com.craftmend.openaudiomc.api.exceptions.InvalidThreadException if not called from the main thread
* @since 6.10.2
*/
void registerTempRegion(String worldName, String regionId, RegionMediaOptions regionMedia, int duration) throws
UnknownWorldException, InvalidThreadException, InvalidRegionException;

/**
* Unregister a region from the world
*
* @param worldName world
* @param regionId region id
* @throws com.craftmend.openaudiomc.api.exceptions.InvalidThreadException if not called from the main thread
* @since 6.10.2
*/
void unregisterRegion(String worldName, String regionId) throws InvalidThreadException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.craftmend.openaudiomc.api.exceptions;

/**
* An exception representing a fatal error during region lookup
*/
public class InvalidRegionException extends Exception {

public InvalidRegionException(String message) {
super(message);
}

public InvalidRegionException() {
super("The given region (with an unknown id) could not be found.");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.craftmend.openaudiomc.api.exceptions;

/**
* Throw when a method is called from an invalid thread
*/
public class InvalidThreadException extends Exception {

public InvalidThreadException() {
super("This method can only be called from the main thread");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.craftmend.openaudiomc.api.exceptions;

/**
* An exception representing a fatal error during world lookup
*/
public class UnknownWorldException extends Exception {

public UnknownWorldException(String worldName) {
super("There is no world with the name '" + worldName + "' loaded. Please ensure that it's typed correctly and that it's loaded.");
}

public UnknownWorldException() {
super("The given world (with an unknown id) could not be found.");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.craftmend.openaudiomc.api.regions;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* Represents media options for a region, this is not a full subset of the normal media options
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RegionMediaOptions {

/**
* If the media should loop
*/
private boolean loop = true;

/**
* If the media should be faded in and out (in milliseconds)
*/
private int fadeTime = 500;

/**
* The volume of the media, 0-100
*/
private int volume = 100;

/**
* The source of the media
*/
private String source = null;

// utility constructors
public RegionMediaOptions(String source) {
this.source = source;
}

public RegionMediaOptions(String source, int volume) {
this.source = source;
this.volume = volume;
}

public RegionMediaOptions(String source, int volume, int fadeTime) {
this.source = source;
this.volume = volume;
this.fadeTime = fadeTime;
}

}
2 changes: 1 addition & 1 deletion plugin/src/main/bash/data.bin
Original file line number Diff line number Diff line change
@@ -1 +1 @@
BUILD_NUM="1430"
BUILD_NUM="1431"
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,34 @@

import com.craftmend.openaudiomc.OpenAudioMc;
import com.craftmend.openaudiomc.api.WorldApi;
import com.craftmend.openaudiomc.api.exceptions.InvalidRegionException;
import com.craftmend.openaudiomc.api.exceptions.InvalidThreadException;
import com.craftmend.openaudiomc.api.exceptions.UnknownWorldException;
import com.craftmend.openaudiomc.api.media.Media;
import com.craftmend.openaudiomc.api.regions.AudioRegion;
import com.craftmend.openaudiomc.api.regions.RegionMediaOptions;
import com.craftmend.openaudiomc.api.speakers.BasicSpeaker;
import com.craftmend.openaudiomc.generic.database.DatabaseService;
import com.craftmend.openaudiomc.generic.platform.Platform;
import com.craftmend.openaudiomc.spigot.OpenAudioMcSpigot;
import com.craftmend.openaudiomc.spigot.modules.regions.RegionModule;
import com.craftmend.openaudiomc.spigot.modules.regions.interfaces.ApiRegion;
import com.craftmend.openaudiomc.spigot.modules.regions.objects.RegionProperties;
import com.craftmend.openaudiomc.spigot.modules.regions.objects.TimedRegionProperties;
import com.craftmend.openaudiomc.spigot.modules.regions.registry.WorldRegionManager;
import com.craftmend.openaudiomc.spigot.modules.speakers.SpeakerService;
import com.craftmend.openaudiomc.spigot.modules.speakers.objects.MappedLocation;
import lombok.AllArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

public class WorldApiImpl implements WorldApi {

Expand Down Expand Up @@ -55,6 +64,124 @@ public BasicSpeaker getSpeakerAt(int x, int y, int z, @NotNull String world) {
return OpenAudioMc.getService(SpeakerService.class).getSpeaker(new MappedLocation(x, y, z, world));
}

@Override
public void registerRegion(String worldName, String regionId, RegionMediaOptions regionMedia) throws InvalidRegionException, InvalidThreadException {
Objects.requireNonNull(worldName, "World name cannot be null");
Objects.requireNonNull(regionId, "Region id cannot be null");
Objects.requireNonNull(regionMedia, "Region media cannot be null");

if (!Bukkit.isPrimaryThread()) {
throw new InvalidThreadException();
}

OpenAudioMcSpigot oams = OpenAudioMcSpigot.getInstance();

if (!oams.getRegionModule().getRegionAdapter().doesRegionExist(regionId)) {
throw new InvalidRegionException("Region " + regionId + " does not exist");
}

WorldRegionManager worldRegionManager = oams.getRegionModule().getWorld(worldName);

// check if this region already is defined
RegionProperties regionProperties = worldRegionManager.getRegionProperties(regionId);
if (regionProperties != null) {
if (regionProperties instanceof TimedRegionProperties) {
TimedRegionProperties timedRegion = (TimedRegionProperties) regionProperties;
worldRegionManager.unregisterRegion(regionId);
timedRegion.destroy();
} else {
throw new InvalidRegionException("The region '" + regionId + "' already has permanent media linked to it.");
}
}

RegionProperties rp = new RegionProperties(
regionMedia.getSource(),
regionMedia.getVolume(),
regionMedia.getFadeTime(),
true,
regionId,
worldName
);

OpenAudioMc.getService(DatabaseService.class).getRepository(RegionProperties.class)
.save(rp);

worldRegionManager.registerRegion(rp);
oams.getRegionModule().forceUpdateRegions();
}

@Override
public void registerTempRegion(String worldName, String regionId, RegionMediaOptions regionMedia, int duration) throws UnknownWorldException, InvalidRegionException, InvalidThreadException {
Objects.requireNonNull(worldName, "World name cannot be null");
Objects.requireNonNull(regionId, "Region id cannot be null");
Objects.requireNonNull(regionMedia, "Region media cannot be null");

if (!Bukkit.isPrimaryThread()) {
throw new InvalidThreadException();
}

OpenAudioMcSpigot oams = OpenAudioMcSpigot.getInstance();

if (!oams.getRegionModule().getRegionAdapter().doesRegionExist(regionId)) {
throw new InvalidRegionException("Region " + regionId + " does not exist");
}

WorldRegionManager worldRegionManager = oams.getRegionModule().getWorld(worldName);

// check if this region already is defined
RegionProperties regionProperties = worldRegionManager.getRegionProperties(regionId);
if (regionProperties != null) {
if (regionProperties instanceof TimedRegionProperties) {
TimedRegionProperties timedRegion = (TimedRegionProperties) regionProperties;
worldRegionManager.unregisterRegion(regionId);
timedRegion.destroy();
} else {
throw new InvalidRegionException("The region '" + regionId + "' already has permanent media linked to it.");
}
}

worldRegionManager.registerRegion(new TimedRegionProperties(
regionMedia.getSource(),
duration,
regionId,
regionMedia.getVolume(),
regionMedia.getFadeTime(),
regionId,
worldName
));

oams.getRegionModule().forceUpdateRegions();
}

@Override
public void unregisterRegion(String worldName, String regionId) throws InvalidThreadException {
Objects.requireNonNull(worldName, "World name cannot be null");
Objects.requireNonNull(regionId, "Region id cannot be null");

if (!Bukkit.isPrimaryThread()) {
throw new InvalidThreadException();
}

OpenAudioMcSpigot oams = OpenAudioMcSpigot.getInstance();
WorldRegionManager worldRegionManager = oams.getRegionModule().getWorld(worldName);

RegionProperties rp = worldRegionManager.getRegionProperties(regionId);
if (rp != null) {
if (rp.getId() != null && !(rp instanceof TimedRegionProperties)) {
OpenAudioMc.getService(DatabaseService.class).getRepository(RegionProperties.class)
.delete(rp);
}

if (rp instanceof TimedRegionProperties) {
((TimedRegionProperties) rp).destroy();
}

worldRegionManager.unregisterRegion(regionId);
}

oams.getRegionModule().forceUpdateRegions();
}

@AllArgsConstructor
private static class WrappedRegion implements AudioRegion {

Expand Down
Loading

0 comments on commit e9dd7b3

Please sign in to comment.