Skip to content

Commit 61779e8

Browse files
authored
Merge pull request #19 from Streamline-Essentials/dev
Auto PR: Merge dev into master
2 parents 714986f + f8095fa commit 61779e8

16 files changed

Lines changed: 444 additions & 279 deletions

File tree

api/src/main/java/net/streamline/api/base/commands/GivenCommands.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,29 @@ public class GivenCommands {
1111
@Getter @Setter
1212
private static PlaytimeCommand playtimeCommand;
1313
@Getter @Setter
14+
private static PTagCommand pTagCommand;
15+
@Getter @Setter
1416
private static ReloadCommand reloadCommand;
1517
@Getter @Setter
18+
private static SetServerCommand setServerCommand;
19+
@Getter @Setter
1620
private static SyncCommand syncCommand;
1721

1822
public static void init() {
1923
setModulesCommand(new ModulesCommand());
2024
setParseCommand(new ParseCommand());
2125
setPlaytimeCommand(new PlaytimeCommand());
26+
setPTagCommand(new PTagCommand());
2227
setReloadCommand(new ReloadCommand());
28+
setSetServerCommand(new SetServerCommand());
2329
setSyncCommand(new SyncCommand());
2430

2531
getModulesCommand().register();
2632
getParseCommand().register();
2733
getPlaytimeCommand().register();
34+
getPTagCommand().register();
2835
getReloadCommand().register();
36+
getSetServerCommand().register();
2937
getSyncCommand().register();
3038
}
3139
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package net.streamline.api.base.timers;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
import singularity.configs.given.GivenConfigs;
6+
import singularity.data.teleportation.TPTicket;
7+
import singularity.utils.MessageUtils;
8+
9+
import java.util.concurrent.CompletableFuture;
10+
import java.util.concurrent.ConcurrentSkipListMap;
11+
import java.util.concurrent.ConcurrentSkipListSet;
12+
import java.util.concurrent.atomic.AtomicLong;
13+
import java.util.concurrent.atomic.AtomicReference;
14+
15+
public abstract class AbstractPlayerTeleporter extends Thread {
16+
public static final long TICKING_FREQUENCY = 50L; // Milliseconds
17+
18+
@Getter @Setter
19+
private static AbstractPlayerTeleporter instance;
20+
21+
@Getter @Setter
22+
private static AtomicReference<TeleportStage> stage = new AtomicReference<>(TeleportStage.READY);
23+
24+
@Getter @Setter
25+
private static AtomicLong lastRun = new AtomicLong(0);
26+
27+
public enum TeleportStage {
28+
COLLECTION,
29+
TELEPORTATION,
30+
READY;
31+
}
32+
33+
/**
34+
* Start the teleporter instance.
35+
*/
36+
public static synchronized void startInstance() {
37+
if (instance == null) {
38+
throw new IllegalStateException("Teleporter instance is not set.");
39+
}
40+
if (! instance.isAlive()) {
41+
instance.start();
42+
}
43+
}
44+
45+
/**
46+
* Stop the teleporter instance safely.
47+
*/
48+
public static synchronized void stopInstance() {
49+
if (instance != null && instance.isAlive()) {
50+
instance.interrupt();
51+
try {
52+
instance.join(); // Wait for the thread to finish
53+
} catch (InterruptedException e) {
54+
Thread.currentThread().interrupt(); // Restore interrupt status
55+
} finally {
56+
instance = null;
57+
}
58+
}
59+
}
60+
61+
/**
62+
* Check if the teleporter can tick again based on the last run time.
63+
*/
64+
public static boolean isAbleToRunAgain() {
65+
long currentTime = System.currentTimeMillis();
66+
long lastRunTime = lastRun.get();
67+
68+
if (lastRunTime == 0 || (lastRunTime + TICKING_FREQUENCY < currentTime)) {
69+
lastRun.set(currentTime);
70+
return true;
71+
}
72+
return false;
73+
}
74+
75+
/**
76+
* Abstract constructor with a custom thread name.
77+
*/
78+
public AbstractPlayerTeleporter() {
79+
super("SL - Player Teleporter");
80+
}
81+
82+
/**
83+
* Main run loop for the teleporter thread.
84+
*/
85+
@Override
86+
public void run() {
87+
while (! isInterrupted()) {
88+
try {
89+
tick();
90+
} catch (Throwable e) {
91+
MessageUtils.logWarning("Error during teleporter tick: ", e);
92+
}
93+
try {
94+
Thread.sleep(TICKING_FREQUENCY);
95+
} catch (InterruptedException e) {
96+
Thread.currentThread().interrupt(); // Preserve interrupt status
97+
break; // Exit the loop
98+
}
99+
}
100+
}
101+
102+
@Getter @Setter
103+
private static AtomicReference<CompletableFuture<ConcurrentSkipListSet<TPTicket>>> atomicTicketsPending = new AtomicReference<>(null);
104+
105+
public CompletableFuture<ConcurrentSkipListSet<TPTicket>> getTicketsPending() {
106+
if (getAtomicTicketsPending().get() == null) {
107+
getAtomicTicketsPending().set(GivenConfigs.getMainDatabase().pullAllTPTickets());
108+
}
109+
110+
return getAtomicTicketsPending().get();
111+
}
112+
113+
public void unpendTickets() {
114+
getAtomicTicketsPending().set(null);
115+
}
116+
117+
public boolean areTicketsPending() {
118+
return getAtomicTicketsPending().get() != null;
119+
}
120+
121+
/**
122+
* Perform a single tick action if the teleporter is ready.
123+
*/
124+
public void contemplateTick() {
125+
if (isAbleToRunAgain()) {
126+
tick();
127+
}
128+
}
129+
130+
/**
131+
* Abstract tick method to be implemented by subclasses.
132+
*/
133+
public abstract void tick();
134+
135+
/**
136+
* Clear the ticket and log the action.
137+
*
138+
* @param ticket The teleportation ticket to clear.
139+
* @param instance The instance ID for logging.
140+
*/
141+
private static void clearTicket(TPTicket ticket, int instance) {
142+
if (ticket != null) {
143+
ticket.clear();
144+
MessageUtils.logInfo("Cleared teleportation ticket for player " + ticket.getIdentifier() + ". [" + instance + "]");
145+
}
146+
}
147+
}

build.gradle

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ subprojects {
4747
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
4848
maven { url "https://oss.sonatype.org/content/repositories/central" }
4949
// Paper / Velocity
50-
maven { url "https://repo.papermc.io/repository/maven-public" }
50+
maven {
51+
name = 'papermc'
52+
url = 'https://repo.papermc.io/repository/maven-public/'
53+
}
5154
// Fabric
5255
maven { url "https://maven.fabricmc.net" }
5356
maven { url "https://libraries.minecraft.net" }
@@ -69,6 +72,11 @@ subprojects {
6972
maven { url "https://repo.extendedclip.com/content/repositories/placeholderapi" }
7073
}
7174

75+
java {
76+
sourceCompatibility = JavaVersion.VERSION_11
77+
targetCompatibility = JavaVersion.VERSION_11
78+
}
79+
7280
processResources {
7381
// Debugging: Print values
7482
doFirst {
@@ -80,9 +88,6 @@ subprojects {
8088
inputs.property("main", project.ext.pluginMain.toString())
8189
outputs.dir(file("build/generated-src"))
8290

83-
java.sourceCompatibility = JavaVersion.VERSION_11
84-
java.targetCompatibility = JavaVersion.VERSION_11
85-
8691
filesMatching("**/plugin.yml") {
8792
expand (
8893
"name": rootProject.name.toString(),
Lines changed: 33 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,65 @@
11
package net.streamline.base.runnables;
22

3-
import lombok.Getter;
4-
import lombok.Setter;
53
import net.md_5.bungee.api.ServerConnectRequest;
64
import net.md_5.bungee.api.config.ServerInfo;
75
import net.md_5.bungee.api.connection.ProxiedPlayer;
86
import net.md_5.bungee.api.event.ServerConnectEvent;
7+
import net.streamline.api.base.timers.AbstractPlayerTeleporter;
98
import net.streamline.base.Streamline;
109
import singularity.configs.given.GivenConfigs;
1110
import singularity.data.teleportation.TPTicket;
11+
import singularity.utils.MessageUtils;
1212

1313
import java.util.Date;
1414
import java.util.UUID;
1515
import java.util.concurrent.ConcurrentSkipListSet;
16-
import java.util.concurrent.atomic.AtomicLong;
17-
import java.util.concurrent.atomic.AtomicReference;
16+
import java.util.concurrent.ExecutorService;
17+
import java.util.concurrent.Executors;
1818

19-
public class PlayerTeleporter extends Thread {
20-
public static final long TICKING_FREQUENCY = 50L;
21-
22-
@Getter @Setter
23-
private static PlayerTeleporter instance;
19+
public class PlayerTeleporter extends AbstractPlayerTeleporter {
20+
// private static final ExecutorService executor = Executors.newFixedThreadPool(4); // Adjust as needed
2421

2522
public static void init() {
26-
instance = new PlayerTeleporter();
27-
instance.start();
23+
setInstance(new PlayerTeleporter());
24+
startInstance();
2825
}
2926

30-
public static void stopInstance() {
31-
try {
32-
if (instance != null) {
33-
instance.interrupt();
34-
instance = null;
35-
}
36-
} catch (Exception e) {
37-
// ignore
38-
}
39-
}
40-
41-
@Getter @Setter
42-
private static AtomicReference<TeleportStage> stage = new AtomicReference<>(TeleportStage.READY);
43-
@Getter @Setter
44-
private static AtomicLong lastRun = new AtomicLong(0);
45-
46-
public enum TeleportStage {
47-
COLLECTION,
48-
TELEPORTATION,
49-
READY,
50-
;
51-
}
27+
@Override
28+
public void tick() {
29+
if (areTicketsPending()) return;
5230

53-
public static boolean isAbleToRunAgain() {
54-
return lastRun.get() + TICKING_FREQUENCY < System.currentTimeMillis();
55-
}
31+
getStage().set(TeleportStage.COLLECTION);
32+
ConcurrentSkipListSet<TPTicket> tickets = getTicketsPending().join();
5633

57-
public static void setLastRun() {
58-
lastRun.set(System.currentTimeMillis());
59-
}
34+
getStage().set(TeleportStage.TELEPORTATION);
35+
// tickets.forEach(ticket -> executor.submit(() -> processTicket(ticket)));
36+
tickets.forEach(this::processTicket);
6037

61-
public PlayerTeleporter() {
62-
super("SL - Player Teleporter");
38+
unpendTickets();
39+
getStage().set(TeleportStage.READY);
6340
}
6441

65-
@Override
66-
public void run() {
67-
if (! isAbleToRunAgain()) return;
68-
69-
setLastRun();
70-
71-
stage.set(TeleportStage.COLLECTION);
72-
ConcurrentSkipListSet<TPTicket> tickets = GivenConfigs.getMainDatabase().pullAllTPTickets().join();
73-
74-
stage.set(TeleportStage.TELEPORTATION);
75-
tickets.forEach(ticket -> {
76-
if (ticket.getCreateDate().before(new Date(System.currentTimeMillis() - 7 * 1000))) {
77-
ticket.clear();
42+
private void processTicket(TPTicket ticket) {
43+
try {
44+
if (ticket.getCreateDate().before(new Date(System.currentTimeMillis() - (7 * 1000)))) {
45+
clearTicket(ticket, 1);
7846
return;
7947
}
8048

8149
ProxiedPlayer player = Streamline.getInstance().getProxy().getPlayer(UUID.fromString(ticket.getIdentifier()));
8250
if (player == null) {
83-
ticket.clear();
51+
clearTicket(ticket, 2);
8452
return;
8553
}
8654

8755
teleportPlayerAsync(player, ticket.getTargetServer().getIdentifier());
88-
});
89-
90-
stage.set(TeleportStage.READY);
56+
// clearTicket(ticket, 3); // Handled by the Spigot side
57+
} catch (Exception e) {
58+
MessageUtils.logWarning("Error processing ticket: " + ticket.getIdentifier(), e);
59+
}
9160
}
9261

93-
private static void teleportPlayerAsync(ProxiedPlayer player, String server) {
62+
private void teleportPlayerAsync(ProxiedPlayer player, String server) {
9463
ServerInfo targetServer = Streamline.getInstance().getProxy().getServerInfo(server);
9564
if (targetServer != null) {
9665
ServerConnectRequest request = ServerConnectRequest.builder()
@@ -100,4 +69,9 @@ private static void teleportPlayerAsync(ProxiedPlayer player, String server) {
10069
player.connect(request);
10170
}
10271
}
72+
73+
private static void clearTicket(TPTicket ticket, int instance) {
74+
ticket.clear();
75+
MessageUtils.logInfo("Cleared teleportation ticket for player " + ticket.getIdentifier() + ". [" + instance + "]");
76+
}
10377
}

dependencies.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
ext {
22
IMPL = [
33
"com.github.ben-manes.caffeine:caffeine:3.1.8",
4-
"com.github.server-utilities:TheBase:${rootProject.properties['base-version']}",
4+
"com.github.Server-Utilities:TheBase:master-SNAPSHOT",
55
"org.pf4j:pf4j:3.10.0",
66
"commons-codec:commons-codec:1.5",
77
]
88
SHADOW = [
99
"com.github.ben-manes.caffeine:caffeine:3.1.8",
10-
"com.github.server-utilities:TheBase:${rootProject.properties['base-version']}",
10+
"com.github.Server-Utilities:TheBase:master-SNAPSHOT",
1111
"org.pf4j:pf4j:3.10.0",
1212
"commons-codec:commons-codec:1.5",
1313
]
1414
ANNO = [
1515
"com.github.ben-manes.caffeine:caffeine:3.1.8",
16-
"com.github.server-utilities:TheBase:${rootProject.properties['base-version']}",
16+
"com.github.Server-Utilities:TheBase:master-SNAPSHOT",
1717
"org.pf4j:pf4j:3.10.0"
1818
]
1919
COMP_ONLY = [

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ org.gradle.vfs.watch = false
99
# Other properties
1010
name = StreamlineCore
1111
group = com.github.Streamline-Essentials.StreamlineCore
12-
version = 2.5.0.0
12+
version = 2.5.3.0
1313

14-
base-version = c8388399
14+
base-version = 6f2e7e2d
1515

1616
plugin.main = default

0 commit comments

Comments
 (0)