Skip to content

Instantly share code, notes, and snippets.

@lucko
Created May 8, 2018 12:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucko/788f1240297ac9b7c0c82acd05b4743e to your computer and use it in GitHub Desktop.
Save lucko/788f1240297ac9b7c0c82acd05b4743e to your computer and use it in GitHub Desktop.
/*
* This file is part of factions-relation-tab, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.factionstab;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.event.FPlayerJoinEvent;
import com.massivecraft.factions.event.FPlayerLeaveEvent;
import com.massivecraft.factions.event.FactionCreateEvent;
import com.massivecraft.factions.event.FactionDisbandEvent;
import com.massivecraft.factions.event.FactionRelationEvent;
import com.massivecraft.factions.struct.Relation;
import me.lucko.helper.Events;
import me.lucko.helper.Schedulers;
import me.lucko.helper.metadata.Metadata;
import me.lucko.helper.metadata.MetadataKey;
import me.lucko.helper.plugin.ExtendedJavaPlugin;
import me.lucko.helper.plugin.ap.Plugin;
import me.lucko.helper.promise.Promise;
import me.lucko.helper.scoreboard.PacketScoreboard;
import me.lucko.helper.scoreboard.PacketScoreboardProvider;
import me.lucko.helper.scoreboard.PacketScoreboardTeam;
import me.lucko.helper.scoreboard.ScoreboardTeam;
import me.lucko.helper.text.Text;
import me.lucko.helper.utils.Players;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Plugin(name = "factions-tab-plugin", hardDepends = {"helper", "ProtocolLib", "Factions"})
public class FactionsTabPlugin extends ExtendedJavaPlugin {
private static final MetadataKey<PlayerTab> TAB_KEY = MetadataKey.create("factions-tab", PlayerTab.class);
private FPlayers players;
@Override
protected void enable() {
this.players = FPlayers.getInstance();
PacketScoreboard scoreboard = getService(PacketScoreboardProvider.class).getScoreboard();
Events.subscribe(PlayerJoinEvent.class)
.handler(e -> Schedulers.async().run(() -> {
FPlayer fplayer = this.players.getByPlayer(e.getPlayer());
Rank rank = Rank.determine(e.getPlayer());
// init our tab
PlayerTab tab = new PlayerTab(e.getPlayer(), scoreboard);
for (Player other : Players.all()) {
Rank r = Rank.determine(other);
tab.handleJoin(other, this.players.getByPlayer(other), r);
}
Metadata.provideForPlayer(e.getPlayer()).put(TAB_KEY, tab);
// update the tabs for other players
for (PlayerTab otherTab : Metadata.players().getAllWithKey(TAB_KEY).values()) {
otherTab.handleJoin(e.getPlayer(), fplayer, rank);
}
}))
.bindWith(this);
Events.subscribe(PlayerQuitEvent.class)
.handler(e -> Schedulers.async().run(() -> {
// update the tabs for other players
for (PlayerTab otherTab : Metadata.players().getAllWithKey(TAB_KEY).values()) {
otherTab.handleQuit(e.getPlayer());
}
}))
.bindWith(this);
// update all tabs when faction relations change
Events.merge(Event.class, FPlayerJoinEvent.class, FPlayerLeaveEvent.class, FactionCreateEvent.class, FactionDisbandEvent.class, FactionRelationEvent.class)
.handler(e -> refresh())
.bindWith(this);
}
public void refresh() {
Promise.completed(Players.all())
.thenAcceptAsync(players -> {
for (Player p : players) {
FPlayer fp = this.players.getByPlayer(p);
Rank r = Rank.determine(p);
for (PlayerTab otherTab : Metadata.players().getAllWithKey(TAB_KEY).values()) {
otherTab.handleJoin(p, fp, r);
}
}
});
}
private final class PlayerTab {
private final Player player;
private final FPlayer fPlayer;
private final Map<TeamCombination, ScoreboardTeam> teams = new HashMap<>();
public PlayerTab(Player player, PacketScoreboard sb) {
this.player = player;
this.fPlayer = FactionsTabPlugin.this.players.getByPlayer(player);
for (Relation relation : Relation.values()) {
for (Rank rank : Rank.values()) {
String id = (relation.ordinal() + 1) + "-" + (rank.ordinal() + 1) + "-rel";
PacketScoreboardTeam team = sb.createPlayerTeam(player, id);
team.setPrefix(rank.prefix + relation.getColor().toString());
this.teams.put(new TeamCombination(relation, rank), team);
}
}
// mark ourselves
handleJoin(this.player, this.fPlayer, Rank.determine(this.player));
}
public void handleJoin(Player other, FPlayer fother, Rank otherRank) {
Relation rel = this.fPlayer.getRelationTo(fother);
TeamCombination desired = new TeamCombination(rel, otherRank);
for (Map.Entry<TeamCombination, ScoreboardTeam> team : this.teams.entrySet()) {
if (desired.equals(team.getKey())) {
team.getValue().addPlayer(other);
} else {
team.getValue().removePlayer(other);
}
}
}
public void handleQuit(Player other) {
for (ScoreboardTeam team : this.teams.values()) {
team.removePlayer(other);
}
}
}
private static final class TeamCombination {
private final Relation relation;
private final Rank rank;
private TeamCombination(Relation relation, Rank rank) {
this.relation = relation;
this.rank = rank;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TeamCombination that = (TeamCombination) o;
return this.relation == that.relation &&
this.rank == that.rank;
}
@Override
public int hashCode() {
return Objects.hash(this.relation, this.rank);
}
}
private enum Rank {
// TODO fill with real values
OWNER("&c[Owner] "),
ADMIN("&b[Admin] "),
VIP("&a[VIP] "),
MEMBER("&7[Member] ");
private final String prefix;
Rank(String prefix) {
this.prefix = Text.colorize(prefix);
}
public static Rank determine(Player p) {
// TODO implement
return MEMBER;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment