Skip to content

Commit e9dd7b3

Browse files
committed
Implement full region API
1 parent b67dcb9 commit e9dd7b3

File tree

12 files changed

+361
-56
lines changed

12 files changed

+361
-56
lines changed

api/src/main/java/com/craftmend/openaudiomc/api/WorldApi.java

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.craftmend.openaudiomc.api;
22

3+
import com.craftmend.openaudiomc.api.exceptions.InvalidRegionException;
4+
import com.craftmend.openaudiomc.api.exceptions.InvalidThreadException;
5+
import com.craftmend.openaudiomc.api.exceptions.UnknownWorldException;
36
import com.craftmend.openaudiomc.api.regions.AudioRegion;
7+
import com.craftmend.openaudiomc.api.regions.RegionMediaOptions;
48
import com.craftmend.openaudiomc.api.speakers.BasicSpeaker;
59
import org.jetbrains.annotations.NotNull;
610
import org.jetbrains.annotations.Nullable;
@@ -16,6 +20,7 @@ public interface WorldApi {
1620

1721
/**
1822
* Get an instance of the world api. May be null if the plugin is not loaded yet
23+
*
1924
* @return instance
2025
*/
2126
static WorldApi getInstance() {
@@ -27,9 +32,10 @@ static WorldApi getInstance() {
2732

2833
/**
2934
* Get all regions at a location
30-
* @param x x
31-
* @param y y
32-
* @param z z
35+
*
36+
* @param x x
37+
* @param y y
38+
* @param z z
3339
* @param world world
3440
* @return regions
3541
*/
@@ -38,13 +44,65 @@ static WorldApi getInstance() {
3844

3945
/**
4046
* Get a speaker at a location, or null if invalid
41-
* @param x x
42-
* @param y y
43-
* @param z z
47+
*
48+
* @param x x
49+
* @param y y
50+
* @param z z
4451
* @param world world
4552
* @return speaker
4653
*/
4754
@Nullable
4855
BasicSpeaker getSpeakerAt(int x, int y, int z, @NotNull String world);
4956

57+
/**
58+
* Register a region in a world.
59+
* Important:
60+
* - this will overwrite current temporary regions
61+
* - this will throw an invalid region exception if the region is not found
62+
* - this will throw an unknown world exception if the world is not loaded
63+
* - this will throw an invalid region exception if the region already has permanent media
64+
* - this will throw an invalid thread exception if not called from the main thread
65+
*
66+
* @param worldName world
67+
* @param regionId id
68+
* @param regionMedia the media to attach
69+
* @throws UnknownWorldException if the world is not loaded
70+
* @throws InvalidRegionException if the region is not found
71+
* @throws com.craftmend.openaudiomc.api.exceptions.InvalidThreadException if not called from the main thread
72+
* @since 6.10.2
73+
*/
74+
void registerRegion(String worldName, String regionId, RegionMediaOptions regionMedia) throws
75+
UnknownWorldException, InvalidThreadException, InvalidRegionException;
76+
77+
/**
78+
* Register a temporary region in a world
79+
* Important:
80+
* - this will overwrite current temporary regions
81+
* - this will throw an invalid region exception if the region is not found
82+
* - this will throw an unknown world exception if the world is not loaded
83+
* - this will throw an invalid region exception if the region already has permanent media
84+
* - this will throw an invalid thread exception if not called from the main thread
85+
*
86+
* @param worldName world
87+
* @param regionId the region to targe
88+
* @param regionMedia the media to attach
89+
* @param duration the duration in seconds
90+
* @throws UnknownWorldException if the world is not loaded
91+
* @throws InvalidRegionException if the region is not found
92+
* @throws com.craftmend.openaudiomc.api.exceptions.InvalidThreadException if not called from the main thread
93+
* @since 6.10.2
94+
*/
95+
void registerTempRegion(String worldName, String regionId, RegionMediaOptions regionMedia, int duration) throws
96+
UnknownWorldException, InvalidThreadException, InvalidRegionException;
97+
98+
/**
99+
* Unregister a region from the world
100+
*
101+
* @param worldName world
102+
* @param regionId region id
103+
* @throws com.craftmend.openaudiomc.api.exceptions.InvalidThreadException if not called from the main thread
104+
* @since 6.10.2
105+
*/
106+
void unregisterRegion(String worldName, String regionId) throws InvalidThreadException;
107+
50108
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.craftmend.openaudiomc.api.exceptions;
2+
3+
/**
4+
* An exception representing a fatal error during region lookup
5+
*/
6+
public class InvalidRegionException extends Exception {
7+
8+
public InvalidRegionException(String message) {
9+
super(message);
10+
}
11+
12+
public InvalidRegionException() {
13+
super("The given region (with an unknown id) could not be found.");
14+
}
15+
16+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.craftmend.openaudiomc.api.exceptions;
2+
3+
/**
4+
* Throw when a method is called from an invalid thread
5+
*/
6+
public class InvalidThreadException extends Exception {
7+
8+
public InvalidThreadException() {
9+
super("This method can only be called from the main thread");
10+
}
11+
12+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.craftmend.openaudiomc.api.exceptions;
2+
3+
/**
4+
* An exception representing a fatal error during world lookup
5+
*/
6+
public class UnknownWorldException extends Exception {
7+
8+
public UnknownWorldException(String worldName) {
9+
super("There is no world with the name '" + worldName + "' loaded. Please ensure that it's typed correctly and that it's loaded.");
10+
}
11+
12+
public UnknownWorldException() {
13+
super("The given world (with an unknown id) could not be found.");
14+
}
15+
16+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.craftmend.openaudiomc.api.regions;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Data;
5+
import lombok.NoArgsConstructor;
6+
7+
/**
8+
* Represents media options for a region, this is not a full subset of the normal media options
9+
*/
10+
@Data
11+
@AllArgsConstructor
12+
@NoArgsConstructor
13+
public class RegionMediaOptions {
14+
15+
/**
16+
* If the media should loop
17+
*/
18+
private boolean loop = true;
19+
20+
/**
21+
* If the media should be faded in and out (in milliseconds)
22+
*/
23+
private int fadeTime = 500;
24+
25+
/**
26+
* The volume of the media, 0-100
27+
*/
28+
private int volume = 100;
29+
30+
/**
31+
* The source of the media
32+
*/
33+
private String source = null;
34+
35+
// utility constructors
36+
public RegionMediaOptions(String source) {
37+
this.source = source;
38+
}
39+
40+
public RegionMediaOptions(String source, int volume) {
41+
this.source = source;
42+
this.volume = volume;
43+
}
44+
45+
public RegionMediaOptions(String source, int volume, int fadeTime) {
46+
this.source = source;
47+
this.volume = volume;
48+
this.fadeTime = fadeTime;
49+
}
50+
51+
}

plugin/src/main/bash/data.bin

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
BUILD_NUM="1430"
1+
BUILD_NUM="1431"

plugin/src/main/java/com/craftmend/openaudiomc/generic/api/implementaions/WorldApiImpl.java

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,34 @@
22

33
import com.craftmend.openaudiomc.OpenAudioMc;
44
import com.craftmend.openaudiomc.api.WorldApi;
5+
import com.craftmend.openaudiomc.api.exceptions.InvalidRegionException;
6+
import com.craftmend.openaudiomc.api.exceptions.InvalidThreadException;
7+
import com.craftmend.openaudiomc.api.exceptions.UnknownWorldException;
58
import com.craftmend.openaudiomc.api.media.Media;
69
import com.craftmend.openaudiomc.api.regions.AudioRegion;
10+
import com.craftmend.openaudiomc.api.regions.RegionMediaOptions;
711
import com.craftmend.openaudiomc.api.speakers.BasicSpeaker;
12+
import com.craftmend.openaudiomc.generic.database.DatabaseService;
813
import com.craftmend.openaudiomc.generic.platform.Platform;
914
import com.craftmend.openaudiomc.spigot.OpenAudioMcSpigot;
1015
import com.craftmend.openaudiomc.spigot.modules.regions.RegionModule;
1116
import com.craftmend.openaudiomc.spigot.modules.regions.interfaces.ApiRegion;
1217
import com.craftmend.openaudiomc.spigot.modules.regions.objects.RegionProperties;
18+
import com.craftmend.openaudiomc.spigot.modules.regions.objects.TimedRegionProperties;
19+
import com.craftmend.openaudiomc.spigot.modules.regions.registry.WorldRegionManager;
1320
import com.craftmend.openaudiomc.spigot.modules.speakers.SpeakerService;
1421
import com.craftmend.openaudiomc.spigot.modules.speakers.objects.MappedLocation;
1522
import lombok.AllArgsConstructor;
1623
import org.bukkit.Bukkit;
24+
import org.bukkit.ChatColor;
1725
import org.bukkit.Location;
1826
import org.jetbrains.annotations.NotNull;
1927
import org.jetbrains.annotations.Nullable;
2028

2129
import java.util.ArrayList;
2230
import java.util.Collection;
2331
import java.util.List;
32+
import java.util.Objects;
2433

2534
public class WorldApiImpl implements WorldApi {
2635

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

67+
@Override
68+
public void registerRegion(String worldName, String regionId, RegionMediaOptions regionMedia) throws InvalidRegionException, InvalidThreadException {
69+
Objects.requireNonNull(worldName, "World name cannot be null");
70+
Objects.requireNonNull(regionId, "Region id cannot be null");
71+
Objects.requireNonNull(regionMedia, "Region media cannot be null");
72+
73+
if (!Bukkit.isPrimaryThread()) {
74+
throw new InvalidThreadException();
75+
}
76+
77+
OpenAudioMcSpigot oams = OpenAudioMcSpigot.getInstance();
78+
79+
if (!oams.getRegionModule().getRegionAdapter().doesRegionExist(regionId)) {
80+
throw new InvalidRegionException("Region " + regionId + " does not exist");
81+
}
82+
83+
WorldRegionManager worldRegionManager = oams.getRegionModule().getWorld(worldName);
84+
85+
// check if this region already is defined
86+
RegionProperties regionProperties = worldRegionManager.getRegionProperties(regionId);
87+
if (regionProperties != null) {
88+
if (regionProperties instanceof TimedRegionProperties) {
89+
TimedRegionProperties timedRegion = (TimedRegionProperties) regionProperties;
90+
worldRegionManager.unregisterRegion(regionId);
91+
timedRegion.destroy();
92+
} else {
93+
throw new InvalidRegionException("The region '" + regionId + "' already has permanent media linked to it.");
94+
}
95+
}
96+
97+
RegionProperties rp = new RegionProperties(
98+
regionMedia.getSource(),
99+
regionMedia.getVolume(),
100+
regionMedia.getFadeTime(),
101+
true,
102+
regionId,
103+
worldName
104+
);
105+
106+
OpenAudioMc.getService(DatabaseService.class).getRepository(RegionProperties.class)
107+
.save(rp);
108+
109+
worldRegionManager.registerRegion(rp);
110+
oams.getRegionModule().forceUpdateRegions();
111+
}
112+
113+
@Override
114+
public void registerTempRegion(String worldName, String regionId, RegionMediaOptions regionMedia, int duration) throws UnknownWorldException, InvalidRegionException, InvalidThreadException {
115+
Objects.requireNonNull(worldName, "World name cannot be null");
116+
Objects.requireNonNull(regionId, "Region id cannot be null");
117+
Objects.requireNonNull(regionMedia, "Region media cannot be null");
118+
119+
if (!Bukkit.isPrimaryThread()) {
120+
throw new InvalidThreadException();
121+
}
122+
123+
OpenAudioMcSpigot oams = OpenAudioMcSpigot.getInstance();
124+
125+
if (!oams.getRegionModule().getRegionAdapter().doesRegionExist(regionId)) {
126+
throw new InvalidRegionException("Region " + regionId + " does not exist");
127+
}
128+
129+
WorldRegionManager worldRegionManager = oams.getRegionModule().getWorld(worldName);
130+
131+
// check if this region already is defined
132+
RegionProperties regionProperties = worldRegionManager.getRegionProperties(regionId);
133+
if (regionProperties != null) {
134+
if (regionProperties instanceof TimedRegionProperties) {
135+
TimedRegionProperties timedRegion = (TimedRegionProperties) regionProperties;
136+
worldRegionManager.unregisterRegion(regionId);
137+
timedRegion.destroy();
138+
} else {
139+
throw new InvalidRegionException("The region '" + regionId + "' already has permanent media linked to it.");
140+
}
141+
}
142+
143+
worldRegionManager.registerRegion(new TimedRegionProperties(
144+
regionMedia.getSource(),
145+
duration,
146+
regionId,
147+
regionMedia.getVolume(),
148+
regionMedia.getFadeTime(),
149+
regionId,
150+
worldName
151+
));
152+
153+
oams.getRegionModule().forceUpdateRegions();
154+
}
155+
156+
@Override
157+
public void unregisterRegion(String worldName, String regionId) throws InvalidThreadException {
158+
Objects.requireNonNull(worldName, "World name cannot be null");
159+
Objects.requireNonNull(regionId, "Region id cannot be null");
160+
161+
if (!Bukkit.isPrimaryThread()) {
162+
throw new InvalidThreadException();
163+
}
164+
165+
OpenAudioMcSpigot oams = OpenAudioMcSpigot.getInstance();
166+
WorldRegionManager worldRegionManager = oams.getRegionModule().getWorld(worldName);
167+
168+
RegionProperties rp = worldRegionManager.getRegionProperties(regionId);
169+
if (rp != null) {
170+
if (rp.getId() != null && !(rp instanceof TimedRegionProperties)) {
171+
OpenAudioMc.getService(DatabaseService.class).getRepository(RegionProperties.class)
172+
.delete(rp);
173+
}
174+
175+
if (rp instanceof TimedRegionProperties) {
176+
((TimedRegionProperties) rp).destroy();
177+
}
178+
179+
worldRegionManager.unregisterRegion(regionId);
180+
}
181+
182+
oams.getRegionModule().forceUpdateRegions();
183+
}
184+
58185
@AllArgsConstructor
59186
private static class WrappedRegion implements AudioRegion {
60187

0 commit comments

Comments
 (0)