From df7bed55b0b0bf46c658f1dda6659a1a2fd260b4 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sun, 3 Dec 2017 14:27:34 +0800 Subject: [PATCH 1/5] Autojoin feature --- .../main/i18n/templates/pgm/PGMUI.properties | 2 + .../java/tc/oc/pgm/PGMModulesManifest.java | 2 + .../tc/oc/pgm/autojoin/AutoJoinManifest.java | 14 +++ .../oc/pgm/autojoin/AutoJoinMatchModule.java | 101 ++++++++++++++++++ .../tc/oc/pgm/autojoin/AutoJoinSetting.java | 18 ++++ .../tc/oc/pgm/picker/PickerMatchModule.java | 55 +++++++--- .../java/tc/oc/pgm/start/StartCountdown.java | 12 +++ 7 files changed, 187 insertions(+), 17 deletions(-) create mode 100644 PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinManifest.java create mode 100644 PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java create mode 100644 PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java diff --git a/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties b/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties index 91c82afd7..c4a085543 100644 --- a/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties +++ b/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties @@ -352,3 +352,5 @@ stats.ui.cores = Cores Leaked: stats.ui.monuments = Monuments Destroyed: stats.ui.teamkills = TK: +autojoin.starting = Match is starting in {0} seconds! Left click the hat to cancel autojoin! +autojoin.cancelled = You have cancelled autojoin! \ No newline at end of file diff --git a/PGM/src/main/java/tc/oc/pgm/PGMModulesManifest.java b/PGM/src/main/java/tc/oc/pgm/PGMModulesManifest.java index edc050fab..7c4eac13a 100644 --- a/PGM/src/main/java/tc/oc/pgm/PGMModulesManifest.java +++ b/PGM/src/main/java/tc/oc/pgm/PGMModulesManifest.java @@ -2,6 +2,7 @@ import tc.oc.commons.core.inject.HybridManifest; import tc.oc.pgm.animation.AnimationManifest; +import tc.oc.pgm.autojoin.AutoJoinManifest; import tc.oc.pgm.broadcast.BroadcastManifest; import tc.oc.pgm.classes.ClassManifest; import tc.oc.pgm.controlpoint.ControlPointManifest; @@ -42,6 +43,7 @@ public class PGMModulesManifest extends HybridManifest { @Override protected void configure() { + install(new AutoJoinManifest()); install(new FilterManifest()); install(new RegionManifest()); install(new KitManifest()); diff --git a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinManifest.java b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinManifest.java new file mode 100644 index 000000000..cfb54ec2d --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinManifest.java @@ -0,0 +1,14 @@ +package tc.oc.pgm.autojoin; + +import tc.oc.commons.bukkit.settings.SettingBinder; +import tc.oc.commons.core.inject.HybridManifest; +import tc.oc.pgm.match.inject.MatchModuleFixtureManifest; + +public class AutoJoinManifest extends HybridManifest { + @Override + protected void configure() { + new SettingBinder(publicBinder()).addBinding().toInstance(AutoJoinSetting.get()); + install(new MatchModuleFixtureManifest(){}); + + } +} diff --git a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java new file mode 100644 index 000000000..fe3736be2 --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java @@ -0,0 +1,101 @@ +package tc.oc.pgm.autojoin; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import tc.oc.commons.bukkit.settings.SettingManagerProvider; +import tc.oc.pgm.events.ListenerScope; +import tc.oc.pgm.events.PlayerChangePartyEvent; +import tc.oc.pgm.join.JoinMatchModule; +import tc.oc.pgm.join.JoinMethod; +import tc.oc.pgm.match.MatchModule; +import tc.oc.pgm.match.MatchPlayer; +import tc.oc.pgm.match.MatchScope; + + +import javax.inject.Inject; + +/** + * New join feature that allows players to join without interfacing with GUI + * with an AutoJoinSetting that allows players to use the legacy join feature + * instead. + */ +@ListenerScope(MatchScope.LOADED) +public class AutoJoinMatchModule extends MatchModule implements Listener { + private Set joiningPlayers; + private final SettingManagerProvider settingManagerProvider; + private final JoinMatchModule joinMatchModule; + + @Inject public AutoJoinMatchModule(SettingManagerProvider settingManagerProvider, JoinMatchModule joinMatchModule) { + this.joiningPlayers = new HashSet<>(); + this.settingManagerProvider = settingManagerProvider; + this.joinMatchModule = joinMatchModule; + } + + @Override + public void disable() { + joiningPlayers.clear(); + } + + // Checks if the player is eligible when they join + @EventHandler(priority = EventPriority.MONITOR) + public void playerJoin(final PlayerChangePartyEvent event) { + MatchPlayer player = event.getPlayer(); + + // Ignore if the match has started + if(match.hasStarted()) return; + + // Remove the player if the player is leaving + if(event.getNewParty() == null) { + joiningPlayers.remove(player); + return; + } + + //Ignore if player is going to participate in a match + if(event.getNewParty().isParticipatingType()) return; + + /* Ignore if player is already known; case: + * Player joined a participating team + * Player left a participating team + */ + // Check exists to only handle cases where Match has not started + if(joiningPlayers.contains(player)) return; + + // Ignore if player explicitly chooses the legacy join feature + if(!settingManagerProvider.getManager(player.getBukkit()).getValue(AutoJoinSetting.get(), Boolean.class, true)) return; + + joiningPlayers.add(player); + } + + // Public accessor methods + + public boolean shouldAutoJoin(MatchPlayer player) { + return joiningPlayers.contains(player); + } + + // Checks if the player is in participating team when match starts + public boolean shouldAlert(MatchPlayer player) { + return shouldAutoJoin(player) && player.getParty().isParticipatingType(); + } + + // Player left clicks hat + public void cancelAutojoin(MatchPlayer player) { + joiningPlayers.remove(player); + } + + public void requestJoin(MatchPlayer player) { + joinMatchModule.requestJoin(player, JoinMethod.USER); + } + + // StartCountdown needs this + public void enterAllPlayers() { + if(!joiningPlayers.isEmpty()) joiningPlayers.forEach(this::requestJoin); + } + + public Stream joiningPlayers() { + return joiningPlayers.stream(); + } +} diff --git a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java new file mode 100644 index 000000000..9d0b071df --- /dev/null +++ b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java @@ -0,0 +1,18 @@ +package tc.oc.pgm.autojoin; + +import me.anxuiz.settings.Setting; +import me.anxuiz.settings.SettingBuilder; +import me.anxuiz.settings.types.BooleanType; + +public class AutoJoinSetting { + private static final Setting INSTANCE = new SettingBuilder() + .name("AutoJoin").alias("aj") + .summary("Toggles the AutoJoin feature") + .type(new BooleanType()) + .defaultValue(false) + .get(); + + public static Setting get() { + return INSTANCE; + } +} diff --git a/PGM/src/main/java/tc/oc/pgm/picker/PickerMatchModule.java b/PGM/src/main/java/tc/oc/pgm/picker/PickerMatchModule.java index 809bdea89..b63e4f1da 100644 --- a/PGM/src/main/java/tc/oc/pgm/picker/PickerMatchModule.java +++ b/PGM/src/main/java/tc/oc/pgm/picker/PickerMatchModule.java @@ -22,7 +22,6 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.player.PlayerLocaleChangeEvent; @@ -40,6 +39,7 @@ import tc.oc.commons.core.chat.Component; import tc.oc.commons.core.formatting.StringUtils; import tc.oc.pgm.PGMTranslations; +import tc.oc.pgm.autojoin.AutoJoinMatchModule; import tc.oc.pgm.blitz.BlitzEvent; import tc.oc.pgm.classes.ClassMatchModule; import tc.oc.pgm.classes.ClassModule; @@ -96,15 +96,22 @@ public boolean matches(MaterialData material) { private final ComponentRenderContext renderer; private final JoinMatchModule jmm; private final BlitzMatchModule bmm; + private final AutoJoinMatchModule autoJoinMatchModule; private final boolean hasTeams; private final boolean hasClasses; private final Set picking = new HashSet<>(); - @Inject PickerMatchModule(ComponentRenderContext renderer, JoinMatchModule jmm, BlitzMatchModule bmm, Optional teamModule, Optional classModule) { + @Inject PickerMatchModule(ComponentRenderContext renderer, + JoinMatchModule jmm, + BlitzMatchModule bmm, + AutoJoinMatchModule autoJoinMatchModule, + Optional teamModule, + Optional classModule) { this.renderer = renderer; this.jmm = jmm; this.bmm = bmm; + this.autoJoinMatchModule = autoJoinMatchModule; this.hasTeams = teamModule.isPresent(); this.hasClasses = classModule.isPresent(); } @@ -288,11 +295,8 @@ public void closeMonitoredInventory(final InventoryCloseEvent event) { } @EventHandler - public void rightClickIcon(final ObserverInteractEvent event) { - if(event.getClickType() != ClickType.RIGHT) return; - + public void handleClickIcon(final ObserverInteractEvent event) { MatchPlayer player = event.getPlayer(); - if(!canUse(player)) return; ItemStack hand = event.getClickedItem(); if(ItemUtils.isNothing(hand)) return; @@ -300,17 +304,34 @@ public void rightClickIcon(final ObserverInteractEvent event) { String displayName = hand.getItemMeta().getDisplayName(); if(displayName == null) return; - if(hand.getType() == Button.JOIN.material) { - event.setCancelled(true); - if(canOpenWindow(player)) { - showWindow(player); - } else { - // If there is nothing to pick, just join immediately - jmm.requestJoin(player, JoinRequest.user()); - } - } else if(hand.getType() == Button.LEAVE.material) { - event.setCancelled(true); - jmm.requestObserve(player); + if(hand.getType() != Button.JOIN.material) return; + + switch(event.getClickType()) { + // Autojoin feature - Player left clicks the hat(cancels Autojoin) + case LEFT: + if(autoJoinMatchModule.shouldAutoJoin(player)) { + autoJoinMatchModule.cancelAutojoin(player); + } + player.sendHotbarMessage(new Component(ChatColor.DARK_PURPLE).translate("autojoin.cancelled").bold(true)); + break; + case RIGHT: + if(!canUse(player)) return; + + if(hand.getType() == Button.JOIN.material) { + event.setCancelled(true); + if(canOpenWindow(player)) { + showWindow(player); + } else { + // If there is nothing to pick, just join immediately + jmm.requestJoin(player, JoinRequest.user()); + } + + //} else if(hand.getType() == Button.LEAVE.material) { + // event.setCancelled(true); + // jmm.requestObserve(player); + // + } + break; } } diff --git a/PGM/src/main/java/tc/oc/pgm/start/StartCountdown.java b/PGM/src/main/java/tc/oc/pgm/start/StartCountdown.java index d0f09da04..2bb51c6fd 100644 --- a/PGM/src/main/java/tc/oc/pgm/start/StartCountdown.java +++ b/PGM/src/main/java/tc/oc/pgm/start/StartCountdown.java @@ -2,6 +2,7 @@ import java.time.Duration; import javax.annotation.Nullable; +import javax.inject.Inject; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; @@ -10,6 +11,7 @@ import org.bukkit.entity.Player; import tc.oc.commons.core.chat.Component; import tc.oc.commons.core.util.Comparables; +import tc.oc.pgm.autojoin.AutoJoinMatchModule; import tc.oc.pgm.match.Match; import tc.oc.pgm.match.MatchState; import tc.oc.pgm.teams.Team; @@ -28,6 +30,7 @@ public class StartCountdown extends PreMatchCountdown { // or implementing some kind of countdown listener system. private final @Nullable TeamMatchModule tmm; private final StartMatchModule smm; + private final AutoJoinMatchModule autoJoinMatchModule; private final Duration huddle; private boolean autoBalanced, balanceWarningSent; protected final boolean forced; @@ -38,6 +41,7 @@ public StartCountdown(Match match, boolean forced, Duration huddle) { this.forced = forced; this.smm = match.needMatchModule(StartMatchModule.class); this.tmm = match.getMatchModule(TeamMatchModule.class); + this.autoJoinMatchModule = match.needMatchModule(AutoJoinMatchModule.class); } protected boolean willHuddle() { @@ -73,11 +77,19 @@ public void onStart(Duration remaining, Duration total) { public void onTick(Duration remaining, Duration total) { super.onTick(remaining, total); + if(remaining.getSeconds() <= 10) { + // Autojoin feature - Send the player hotbar messages and alert them that match is starting + autoJoinMatchModule.joiningPlayers() + .forEach(player -> player.sendHotbarMessage(new Component(ChatColor.DARK_PURPLE).translate("autojoin.starting", + String.valueOf(remaining.getSeconds())).bold(true))); + } + if(remaining.getSeconds() >= 1 && remaining.getSeconds() <= 3) { // Auto-balance runs at match start as well, but try to run it a few seconds in advance if(this.tmm != null && !this.autoBalanced) { this.autoBalanced = true; this.tmm.balanceTeams(); + autoJoinMatchModule.enterAllPlayers(); } } From 2fb1213d3862cafb0dbcca31e10ec1e08a1c87cf Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 4 Dec 2017 19:03:21 +0800 Subject: [PATCH 2/5] improvements to retain element order and others --- .../main/i18n/templates/pgm/PGMUI.properties | 4 ++-- .../tc/oc/pgm/autojoin/AutoJoinManifest.java | 1 - .../oc/pgm/autojoin/AutoJoinMatchModule.java | 23 ++----------------- .../tc/oc/pgm/autojoin/AutoJoinSetting.java | 4 ++-- .../java/tc/oc/pgm/start/StartCountdown.java | 2 +- 5 files changed, 7 insertions(+), 27 deletions(-) diff --git a/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties b/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties index c4a085543..59de625f1 100644 --- a/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties +++ b/Commons/core/src/main/i18n/templates/pgm/PGMUI.properties @@ -352,5 +352,5 @@ stats.ui.cores = Cores Leaked: stats.ui.monuments = Monuments Destroyed: stats.ui.teamkills = TK: -autojoin.starting = Match is starting in {0} seconds! Left click the hat to cancel autojoin! -autojoin.cancelled = You have cancelled autojoin! \ No newline at end of file +autojoin.starting = You will join the match in {0} seconds. Left click the helmet to cancel! +autojoin.cancelled = You will now observe the match. Right click the helmet to join again! \ No newline at end of file diff --git a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinManifest.java b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinManifest.java index cfb54ec2d..6211ca639 100644 --- a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinManifest.java +++ b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinManifest.java @@ -9,6 +9,5 @@ public class AutoJoinManifest extends HybridManifest { protected void configure() { new SettingBinder(publicBinder()).addBinding().toInstance(AutoJoinSetting.get()); install(new MatchModuleFixtureManifest(){}); - } } diff --git a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java index fe3736be2..711bcd634 100644 --- a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java +++ b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java @@ -1,6 +1,6 @@ package tc.oc.pgm.autojoin; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import java.util.stream.Stream; import org.bukkit.event.EventHandler; @@ -30,7 +30,7 @@ public class AutoJoinMatchModule extends MatchModule implements Listener { private final JoinMatchModule joinMatchModule; @Inject public AutoJoinMatchModule(SettingManagerProvider settingManagerProvider, JoinMatchModule joinMatchModule) { - this.joiningPlayers = new HashSet<>(); + this.joiningPlayers = new LinkedHashSet<>(); this.settingManagerProvider = settingManagerProvider; this.joinMatchModule = joinMatchModule; } @@ -40,48 +40,30 @@ public void disable() { joiningPlayers.clear(); } - // Checks if the player is eligible when they join @EventHandler(priority = EventPriority.MONITOR) public void playerJoin(final PlayerChangePartyEvent event) { MatchPlayer player = event.getPlayer(); - // Ignore if the match has started if(match.hasStarted()) return; - // Remove the player if the player is leaving if(event.getNewParty() == null) { joiningPlayers.remove(player); return; } - //Ignore if player is going to participate in a match if(event.getNewParty().isParticipatingType()) return; - /* Ignore if player is already known; case: - * Player joined a participating team - * Player left a participating team - */ - // Check exists to only handle cases where Match has not started if(joiningPlayers.contains(player)) return; - // Ignore if player explicitly chooses the legacy join feature if(!settingManagerProvider.getManager(player.getBukkit()).getValue(AutoJoinSetting.get(), Boolean.class, true)) return; joiningPlayers.add(player); } - // Public accessor methods - public boolean shouldAutoJoin(MatchPlayer player) { return joiningPlayers.contains(player); } - // Checks if the player is in participating team when match starts - public boolean shouldAlert(MatchPlayer player) { - return shouldAutoJoin(player) && player.getParty().isParticipatingType(); - } - - // Player left clicks hat public void cancelAutojoin(MatchPlayer player) { joiningPlayers.remove(player); } @@ -90,7 +72,6 @@ public void requestJoin(MatchPlayer player) { joinMatchModule.requestJoin(player, JoinMethod.USER); } - // StartCountdown needs this public void enterAllPlayers() { if(!joiningPlayers.isEmpty()) joiningPlayers.forEach(this::requestJoin); } diff --git a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java index 9d0b071df..241c30748 100644 --- a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java +++ b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java @@ -7,9 +7,9 @@ public class AutoJoinSetting { private static final Setting INSTANCE = new SettingBuilder() .name("AutoJoin").alias("aj") - .summary("Toggles the AutoJoin feature") + .summary("Toggles the ability to be automatically emplaced into the match") .type(new BooleanType()) - .defaultValue(false) + .defaultValue(true) .get(); public static Setting get() { diff --git a/PGM/src/main/java/tc/oc/pgm/start/StartCountdown.java b/PGM/src/main/java/tc/oc/pgm/start/StartCountdown.java index 2bb51c6fd..9684858bb 100644 --- a/PGM/src/main/java/tc/oc/pgm/start/StartCountdown.java +++ b/PGM/src/main/java/tc/oc/pgm/start/StartCountdown.java @@ -85,11 +85,11 @@ public void onTick(Duration remaining, Duration total) { } if(remaining.getSeconds() >= 1 && remaining.getSeconds() <= 3) { + autoJoinMatchModule.enterAllPlayers(); // Auto-balance runs at match start as well, but try to run it a few seconds in advance if(this.tmm != null && !this.autoBalanced) { this.autoBalanced = true; this.tmm.balanceTeams(); - autoJoinMatchModule.enterAllPlayers(); } } From c74edc2444816ac5a756510a1953c57adda0e446 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Wed, 6 Dec 2017 14:46:05 +0800 Subject: [PATCH 3/5] add comment to document the removal of the leave icon --- PGM/src/main/java/tc/oc/pgm/picker/PickerMatchModule.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PGM/src/main/java/tc/oc/pgm/picker/PickerMatchModule.java b/PGM/src/main/java/tc/oc/pgm/picker/PickerMatchModule.java index b63e4f1da..628f2ff5e 100644 --- a/PGM/src/main/java/tc/oc/pgm/picker/PickerMatchModule.java +++ b/PGM/src/main/java/tc/oc/pgm/picker/PickerMatchModule.java @@ -325,7 +325,7 @@ public void handleClickIcon(final ObserverInteractEvent event) { // If there is nothing to pick, just join immediately jmm.requestJoin(player, JoinRequest.user()); } - + // Removed until this has some use - currently does nothing //} else if(hand.getType() == Button.LEAVE.material) { // event.setCancelled(true); // jmm.requestObserve(player); From 5e4c166c193834510eb817cea3f69bf30b697481 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Wed, 6 Dec 2017 14:50:17 +0800 Subject: [PATCH 4/5] remove extra nl --- PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java | 1 - 1 file changed, 1 deletion(-) diff --git a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java index 711bcd634..0ef82bce6 100644 --- a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java +++ b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinMatchModule.java @@ -15,7 +15,6 @@ import tc.oc.pgm.match.MatchPlayer; import tc.oc.pgm.match.MatchScope; - import javax.inject.Inject; /** From 84d13330ef8c6c970cd4fab29f49ff2c7db4c462 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 11 Dec 2017 13:35:57 +0800 Subject: [PATCH 5/5] Modify settings description message --- PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java index 241c30748..b4d2d1721 100644 --- a/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java +++ b/PGM/src/main/java/tc/oc/pgm/autojoin/AutoJoinSetting.java @@ -7,7 +7,7 @@ public class AutoJoinSetting { private static final Setting INSTANCE = new SettingBuilder() .name("AutoJoin").alias("aj") - .summary("Toggles the ability to be automatically emplaced into the match") + .summary("Automatically join a team when the match starts") .type(new BooleanType()) .defaultValue(true) .get();