Skip to content
This repository was archived by the owner on Feb 15, 2022. It is now read-only.

Commit 1842e8c

Browse files
committed
Implemented server-side timer API
0 parents  commit 1842e8c

File tree

11 files changed

+841
-0
lines changed

11 files changed

+841
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.iml
2+
.idea/
3+
target/
4+
.project
5+
.classpath

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Turtle Entertainment Online, Inc
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

pom.xml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>net.badlion</groupId>
8+
<artifactId>timer-api</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<packaging>jar</packaging>
12+
13+
<repositories>
14+
<repository>
15+
<id>spigot-repo</id>
16+
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
17+
</repository>
18+
</repositories>
19+
20+
<dependencies>
21+
<dependency>
22+
<groupId>org.spigotmc</groupId>
23+
<artifactId>spigot-api</artifactId>
24+
<version>1.8.8-R0.1-SNAPSHOT</version>
25+
<scope>provided</scope>
26+
</dependency>
27+
</dependencies>
28+
29+
<build>
30+
<plugins>
31+
<plugin>
32+
<groupId>org.apache.maven.plugins</groupId>
33+
<artifactId>maven-compiler-plugin</artifactId>
34+
<version>3.8.0</version>
35+
36+
<configuration>
37+
<source>1.7</source>
38+
<target>1.7</target>
39+
<encoding>UTF-8</encoding>
40+
</configuration>
41+
</plugin>
42+
43+
<plugin>
44+
<groupId>org.apache.maven.plugins</groupId>
45+
<artifactId>maven-resources-plugin</artifactId>
46+
<version>3.1.0</version>
47+
48+
<configuration>
49+
<encoding>UTF-8</encoding>
50+
</configuration>
51+
</plugin>
52+
</plugins>
53+
</build>
54+
</project>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package net.badlion.timers;
2+
3+
import net.badlion.timers.api.TimerApiImpl;
4+
import net.badlion.timers.impl.NmsManager;
5+
import net.badlion.timers.listeners.TimerListener;
6+
import org.bukkit.plugin.java.JavaPlugin;
7+
8+
import java.nio.charset.Charset;
9+
10+
public class TimerPlugin extends JavaPlugin {
11+
12+
public static final String CHANNEL_NAME = "BLC|T";
13+
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8"); // Do not use Guava because of 1.7
14+
15+
private TimerApiImpl timerApi;
16+
17+
@Override
18+
public void onEnable() {
19+
NmsManager.init(this);
20+
21+
this.timerApi = new TimerApiImpl(this);
22+
23+
this.getServer().getMessenger().registerOutgoingPluginChannel(this, TimerPlugin.CHANNEL_NAME);
24+
25+
this.getServer().getPluginManager().registerEvents(new TimerListener(this), this);
26+
27+
this.getServer().getScheduler().runTaskTimer(this, new Runnable() {
28+
@Override
29+
public void run() {
30+
TimerPlugin.this.timerApi.tickTimers();
31+
}
32+
}, 1L, 1L);
33+
34+
this.getServer().getScheduler().runTaskTimer(this, new Runnable() {
35+
@Override
36+
public void run() {
37+
TimerPlugin.this.timerApi.syncTimers();
38+
}
39+
}, 60L, 60L);
40+
}
41+
42+
@Override
43+
public void onDisable() {
44+
45+
}
46+
47+
public TimerApiImpl getTimerApi() {
48+
return this.timerApi;
49+
}
50+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package net.badlion.timers.api;
2+
3+
import org.bukkit.entity.Player;
4+
import org.bukkit.inventory.ItemStack;
5+
6+
import java.util.Collection;
7+
8+
public interface Timer {
9+
10+
// Getters and setters
11+
12+
/**
13+
* Get the timer's id
14+
*
15+
* @return Id as unique long value
16+
*/
17+
long getId();
18+
19+
/**
20+
* Get the timer's name
21+
*
22+
* @return Name as string
23+
*/
24+
String getName();
25+
26+
/**
27+
* Set the timer's name
28+
* Will be the text displayed in the client
29+
*
30+
* @param name Name as string
31+
*/
32+
void setName(String name);
33+
34+
/**
35+
* Get the item displayed in the client
36+
*
37+
* @return Item as a Bukkit ItemStack
38+
*/
39+
ItemStack getItem();
40+
41+
/**
42+
* Set the item displayed in the client
43+
* Cannot be a null value
44+
* <p>
45+
* Note : Item metas are currently not implemented,
46+
* but enchantments should work fine
47+
*
48+
* @param item Item as a Bukkit ItemStack
49+
*/
50+
void setItem(ItemStack item);
51+
52+
/**
53+
* Get if the timer is repeating or not
54+
*
55+
* @return Repeating value as a boolean
56+
*/
57+
boolean isRepeating();
58+
59+
/**
60+
* Set whether the timer should repeat when reaching 0 or not
61+
*
62+
* @param repeating {@code true} if repeating, {@code false} otherwise
63+
*/
64+
void setRepeating(boolean repeating);
65+
66+
/**
67+
* Get the timer countdown time
68+
*
69+
* @return Timer countdown time as a long number of ticks
70+
*/
71+
long getTime();
72+
73+
/**
74+
* Set the timer countdown time
75+
* Note : This implies a call to {@link Timer#reset()}
76+
*
77+
* @param time Timer countdown time as a long number of ticks
78+
*/
79+
void setTime(long time);
80+
81+
// Player functions
82+
83+
/**
84+
* Add a receiver to the timer
85+
* Note : A disconnecting player will automatically
86+
* be removed from the timer
87+
*
88+
* @param player Player instance to add
89+
*/
90+
void addReceiver(Player player);
91+
92+
/**
93+
* Manually remove a receiver form the timer
94+
*
95+
* @param player Player instance to remove
96+
*/
97+
void removeReceiver(Player player);
98+
99+
/**
100+
* Clear all players receiving this timer
101+
*/
102+
void clearReceivers();
103+
104+
/**
105+
* Get all the players that are receiving this timer
106+
*
107+
* @return Collection of receivers as a thread-safe collection
108+
*/
109+
Collection<Player> getReceivers();
110+
111+
// Other functions
112+
113+
/**
114+
* Reset the current countdown to the {@link Timer#getTime()} value
115+
*/
116+
void reset();
117+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package net.badlion.timers.api;
2+
3+
import org.bukkit.entity.Player;
4+
import org.bukkit.inventory.ItemStack;
5+
6+
public abstract class TimerApi {
7+
static TimerApi instance;
8+
9+
/**
10+
* Get the API instance.
11+
*
12+
* @return The API instance
13+
*/
14+
public static TimerApi getInstance() {
15+
return TimerApi.instance;
16+
}
17+
18+
/**
19+
* Create a new timer and register it into the API.
20+
* <p>
21+
* A timer will automatically handle synchronizing with its receivers,
22+
* and will repeat itself if it's mark as repeating. If not, it'll be
23+
* automatically removed from the API.
24+
*
25+
* @param item Item to show in the client
26+
* @param repeating {@code true} if the timer is repeating, {@code false} otherwise
27+
* @param time Countdown time, in ticks (20 per seconds)
28+
* @return The new timer instance
29+
*/
30+
public abstract Timer createTimer(ItemStack item, boolean repeating, long time);
31+
32+
/**
33+
* Create a new timer and register it into the API.
34+
* <p>
35+
* A timer will automatically handle synchronizing with its receivers,
36+
* and will repeat itself if it's mark as repeating. If not, it'll be
37+
* automatically removed from the API.
38+
*
39+
* @param name Name to show in the client
40+
* @param item Item to show in the client
41+
* @param repeating {@code true} if the timer is repeating, {@code false} otherwise
42+
* @param time Countdown time, in ticks (20 per seconds)
43+
* @return The new timer instance
44+
*/
45+
public abstract Timer createTimer(String name, ItemStack item, boolean repeating, long time);
46+
47+
/**
48+
* Remove a timer from the API, disabling all API features about it.
49+
*
50+
* @param timer The timer instance to remove
51+
*/
52+
public abstract void removeTimer(Timer timer);
53+
54+
/**
55+
* Clear all timers for a player.
56+
*
57+
* @param player The player instance to remove
58+
*/
59+
public abstract void clearTimers(Player player);
60+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package net.badlion.timers.api;
2+
3+
import net.badlion.timers.TimerPlugin;
4+
import net.badlion.timers.impl.NmsManager;
5+
import net.badlion.timers.impl.TimerImpl;
6+
import org.bukkit.entity.Player;
7+
import org.bukkit.inventory.ItemStack;
8+
9+
import java.util.Collections;
10+
import java.util.Set;
11+
import java.util.concurrent.ConcurrentHashMap;
12+
import java.util.concurrent.atomic.AtomicInteger;
13+
14+
public class TimerApiImpl extends TimerApi {
15+
16+
private final TimerPlugin plugin;
17+
private final AtomicInteger idGenerator;
18+
private final Set<TimerImpl> allTimers;
19+
20+
public TimerApiImpl(TimerPlugin plugin) {
21+
this.plugin = plugin;
22+
this.idGenerator = new AtomicInteger(1);
23+
this.allTimers = Collections.newSetFromMap(new ConcurrentHashMap<TimerImpl, Boolean>());
24+
25+
TimerApi.instance = this;
26+
}
27+
28+
@Override
29+
public Timer createTimer(ItemStack item, boolean repeating, long time) {
30+
return this.createTimer(null, item, repeating, time);
31+
}
32+
33+
@Override
34+
public Timer createTimer(String name, ItemStack item, boolean repeating, long time) {
35+
TimerImpl timer = new TimerImpl(this.plugin, this.idGenerator.getAndIncrement(), name, item, repeating, time);
36+
37+
this.allTimers.add(timer);
38+
39+
return timer;
40+
}
41+
42+
@Override
43+
public void removeTimer(Timer timer) {
44+
// Failsafe
45+
if (timer instanceof TimerImpl) {
46+
TimerImpl timerImpl = (TimerImpl) timer;
47+
48+
this.allTimers.remove(timerImpl);
49+
}
50+
51+
timer.clearReceivers();
52+
}
53+
54+
@Override
55+
public void clearTimers(Player player) {
56+
for (TimerImpl timer : this.allTimers) {
57+
timer.getReceivers().remove(player);
58+
}
59+
60+
NmsManager.sendPluginMessage(player, TimerPlugin.CHANNEL_NAME, "REMOVE_ALL_TIMERS|{}".getBytes(TimerPlugin.UTF_8_CHARSET));
61+
}
62+
63+
public void tickTimers() {
64+
for (TimerImpl timer : this.allTimers) {
65+
timer.tick();
66+
}
67+
}
68+
69+
public void syncTimers() {
70+
for (TimerImpl timer : this.allTimers) {
71+
timer.syncTimer();
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)