Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/3-get current server #7

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Bungeecord-Expansion

Expansion for bungeecord placeholders
[![Build Status](http://ci.extendedclip.com/buildStatus/icon?job=Bungeecord-Expansion)](http://ci.extendedclip.com/job/Bungeecord-Expansion/)
[![Build Status](http://ci.extendedclip.com/buildStatus/icon?job=Bungeecord-Expansion)](http://ci.extendedclip.com/job/Bungeecord-Expansion/)
9 changes: 4 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.extendedclip.papi.bungeeexpansion</groupId>
<artifactId>bungee-expansion</artifactId>
<version>2.0-SNAPSHOT</version>
<version>3.0-SNAPSHOT</version>

<name>PAPI-Expansion-Bungee</name>
<description>PlaceholderAPI expansion for bungeecord placeholders</description>
Expand All @@ -29,13 +29,13 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.15.2-R0.1-SNAPSHOT</version>
<version>1.18-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.6</version>
<version>2.11.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Expand All @@ -58,5 +58,4 @@
</plugin>
</plugins>
</build>

</project>
271 changes: 142 additions & 129 deletions src/main/java/com/extendedclip/papi/bungeeexpansion/BungeeExpansion.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageListener;
import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collections;
import java.util.HashMap;
Expand All @@ -22,134 +24,145 @@

public final class BungeeExpansion extends PlaceholderExpansion implements PluginMessageListener, Taskable, Configurable {

private static final String MESSAGE_CHANNEL = "BungeeCord";
private static final String SERVERS_CHANNEL = "GetServers";
private static final String PLAYERS_CHANNEL = "PlayerCount";
private static final String CONFIG_INTERVAL = "check_interval";

private static final Splitter SPLITTER = Splitter.on(",").trimResults();


private final Map<String, Integer> counts = new HashMap<>();
private final AtomicReference<BukkitTask> cached = new AtomicReference<>();


@Override
public String getIdentifier() {
return "bungee";
}

@Override
public String getAuthor() {
return "clip";
}

@Override
public String getVersion() {
return "2.0";
}

@Override
public Map<String, Object> getDefaults() {
return Collections.singletonMap(CONFIG_INTERVAL, 30);
}


@Override
public String onRequest(final OfflinePlayer player, String identifier) {
final int value;

switch (identifier.toLowerCase()) {
case "all":
case "total":
value = counts.values().stream().mapToInt(Integer::intValue).sum();
break;
default:
value = counts.getOrDefault(identifier.toLowerCase(), 0);
break;
}

return String.valueOf(value);
}

@Override
public void start() {
final BukkitTask task = Bukkit.getScheduler().runTaskTimer(getPlaceholderAPI(), () -> {

if (counts.isEmpty()) {
sendServersChannelMessage();
}
else {
counts.keySet().forEach(this::sendPlayersChannelMessage);
}

}, 20L * 2L, 20L * getLong(CONFIG_INTERVAL, 30));


final BukkitTask prev = cached.getAndSet(task);
if (prev != null) {
prev.cancel();
} else {
Bukkit.getMessenger().registerOutgoingPluginChannel(getPlaceholderAPI(), MESSAGE_CHANNEL);
Bukkit.getMessenger().registerIncomingPluginChannel(getPlaceholderAPI(), MESSAGE_CHANNEL, this);
}
}

@Override
public void stop() {
final BukkitTask prev = cached.getAndSet(null);
if (prev == null) {
return;
}

prev.cancel();
counts.clear();

Bukkit.getMessenger().unregisterOutgoingPluginChannel(getPlaceholderAPI(), MESSAGE_CHANNEL);
Bukkit.getMessenger().unregisterIncomingPluginChannel(getPlaceholderAPI(), MESSAGE_CHANNEL, this);
}


@Override
public void onPluginMessageReceived(final String channel, final Player player, final byte[] message) {
if (!MESSAGE_CHANNEL.equals(channel)) {
return;
}

//noinspection UnstableApiUsage
final ByteArrayDataInput in = ByteStreams.newDataInput(message);
switch (in.readUTF()) {
case PLAYERS_CHANNEL:
counts.put(in.readUTF(), in.readInt());
break;
case SERVERS_CHANNEL:
SPLITTER.split(in.readUTF()).forEach(serverName -> counts.putIfAbsent(serverName, 0));
break;
}
}


private void sendServersChannelMessage() {
sendMessage(SERVERS_CHANNEL, out -> { });
}

private void sendPlayersChannelMessage(final String serverName) {
sendMessage(PLAYERS_CHANNEL, out -> out.writeUTF(serverName));
}

private void sendMessage(final String channel, final Consumer<ByteArrayDataOutput> consumer) {
final Player player = Iterables.getFirst(Bukkit.getOnlinePlayers(), null);
if (player == null) {
return;
}

//noinspection UnstableApiUsage
final ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF(channel);

consumer.accept(out);

player.sendPluginMessage(getPlaceholderAPI(), MESSAGE_CHANNEL, out.toByteArray());
}
private static final String MESSAGE_CHANNEL = "BungeeCord";

// BungeeCord Subchannels
private static final String SERVER_SUBCHANNEL = "GetServer";
private static final String SERVERS_SUBCHANNEL = "GetServers";
private static final String PLAYERS_SUBCHANNEL = "PlayerCount";

private static final String CONFIG_INTERVAL = "check_interval";
private static final Splitter SPLITTER = Splitter.on(",").trimResults();

private final Map<String, Integer> counts = new HashMap<>();
private final AtomicReference<BukkitTask> cached = new AtomicReference<>();

private String serverName = "";

@Override
public @NotNull String getIdentifier() {
return "bungee";
}

@Override
public @NotNull String getAuthor() {
return "clip";
}

@Override
public @NotNull String getVersion() {
return "3.0";
}

@Override
public Map<String, Object> getDefaults() {
return Collections.singletonMap(CONFIG_INTERVAL, 30);
}

@Override
public String onRequest(final OfflinePlayer player, @NotNull String identifier) {
switch (identifier) {
case "count":
return Integer.toString(counts.getOrDefault(serverName, 0));

case "server_name":
return serverName.isEmpty() ? "" : serverName;
}

if (identifier.startsWith("count_")) {
final int value;
switch (identifier) {
case "count_all":
case "count_total":
value = counts.values().stream().mapToInt(Integer::intValue).sum();
break;

default:
String serverName = identifier.substring(identifier.indexOf('_') + 1);
value = counts.getOrDefault(serverName, 0);
break;
}
return Integer.toString(value);
}
return null;
}

@Override
public void start() {
final BukkitTask task = Bukkit.getScheduler().runTaskTimer(getPlaceholderAPI(), () -> {
if (counts.isEmpty()) {
sendServersSubchannelMessage();
} else {
counts.keySet().forEach(this::sendPlayersSubchannelMessage);
}
}, 20L * 2L, 20L * getLong(CONFIG_INTERVAL, 30));

final BukkitTask prev = cached.getAndSet(task);
if (prev != null) {
prev.cancel();
} else {
Bukkit.getMessenger().registerOutgoingPluginChannel(getPlaceholderAPI(), MESSAGE_CHANNEL);
Bukkit.getMessenger().registerIncomingPluginChannel(getPlaceholderAPI(), MESSAGE_CHANNEL, this);
}

sendServerSubchannelMessage();
}

@Override
public void stop() {
final BukkitTask prev = cached.getAndSet(null);
if (prev == null) return;

prev.cancel();
counts.clear();

Bukkit.getMessenger().unregisterOutgoingPluginChannel(getPlaceholderAPI(), MESSAGE_CHANNEL);
Bukkit.getMessenger().unregisterIncomingPluginChannel(getPlaceholderAPI(), MESSAGE_CHANNEL, this);
}

@Override
public void onPluginMessageReceived(final @NotNull String channel, final @NotNull Player player, final byte[] message) {
if (!MESSAGE_CHANNEL.equals(channel)) return;

//noinspection UnstableApiUsage
final ByteArrayDataInput in = ByteStreams.newDataInput(message);
switch (in.readUTF()) {
case PLAYERS_SUBCHANNEL:
counts.put(in.readUTF(), in.readInt());
break;

case SERVER_SUBCHANNEL:
serverName = in.readUTF();
break;

case SERVERS_SUBCHANNEL:
SPLITTER.split(in.readUTF()).forEach(serverName -> counts.putIfAbsent(serverName, 0));
break;
}
}

private void sendServerSubchannelMessage() {
sendChanncelMessage(SERVER_SUBCHANNEL, null);
}

private void sendServersSubchannelMessage() {
sendChanncelMessage(SERVERS_SUBCHANNEL, null);
}

private void sendPlayersSubchannelMessage(@NotNull final String serverName) {
sendChanncelMessage(PLAYERS_SUBCHANNEL, out -> out.writeUTF(serverName));
}

private void sendChanncelMessage(@NotNull final String channel, @Nullable final Consumer<ByteArrayDataOutput> consumer) {
final Player player = Iterables.getFirst(Bukkit.getOnlinePlayers(), null);
if (player == null) return;

final ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF(channel);

if (consumer != null) consumer.accept(out);

player.sendPluginMessage(getPlaceholderAPI(), MESSAGE_CHANNEL, out.toByteArray());
}

}