diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java index e22f5bd..0e66d6d 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.java @@ -98,6 +98,7 @@ public class FightSystem extends JavaPlugin { new ClickAnalyzer(); new BlockPlaceCollision(); new HotbarKit.HotbarKitListener(); + new JoinRequestListener(); new OneShotStateDependent(ArenaMode.All, FightState.PreSchemSetup, () -> Fight.playSound(SWSound.BLOCK_NOTE_PLING.getSound(), 100.0f, 2.0f)); new EnterHandler(); @@ -136,12 +137,10 @@ public class FightSystem extends JavaPlugin { new LeaveCommand(); new KitCommand(); new RemoveCommand(); - new AcceptCommand(); + new RequestsCommand(); new WGCommand(); new TBCommand(); - new DeclineCommand(); new GamemodeCommand(); - new InviteCommand(); new ReadyCommand(); new AkCommand(); new LeaderCommand(); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties index 7a0114a..a6ab2ab 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem.properties @@ -25,13 +25,6 @@ FIGHT_ALREADY_STARTED=§cThe fight already started NOT_LEADER=§cYou aren't a leader PLAYER_UNAVAILABLE=§cThe player is not in an arena -NO_INVITATION=§cYou weren't invited by any team -INVITATION_DECLINED=§cInvitation declined -INVITATION_DECLINED_TEAM=§e{0} §chas declined the invitation -PLAYER_IN_TEAM=§e{0} §cis already in a team -ALREADY_INVITED=§e{0} §cwas invited -INVITATION_SENT=§e{0} §7invited - NOT_IN_TEAM=§e{0} §cis not in your team KIT_UNAVAILABLE=§cThis kit does not exist @@ -41,8 +34,6 @@ GAMEMODE_NOT_ALLOWED=§cChanging gamemode is not permitted GAMEMODE_UNKNOWN=§cUnknown gamemode {0} GAMEMODE_HELP=§8/§7gm §8[§egamemode§8] -INVITE_HELP=§8/§einvite §8[§eplayer§8] - LEADER_FULL=§cAll teams already have a leader ALREADY_IN_TEAM=§cYou are already in a team @@ -58,12 +49,6 @@ WIN_HELP=§8/§7win §8[§eteam §8or §etie§8] # GUI -INVITATION_TITLE=Invitation from {0} -INVITATION_ACCEPT=§aAccept -INVITATION_DECLINE=§cDecline -INVITATION_CHAT_ACCEPT=§8/§aaccept§8, §7to §aaccept§7 the invitation -INVITATION_CHAT_DECLINE=§8/§cdecline§8, §7to §cdecline§7 the invitation - STATE_TITLE=Fight state STATE_PRE_LEADER_SETUP=§7Team leader waiting phase STATE_PRE_SCHEM_SETUP=§7Schematic selection phase @@ -73,8 +58,6 @@ STATE_RUNNING=§eFighting phase STATE_SPECTATE_WIN=§7Victory {0} STATE_SPECTATE_TIE=§7Draw -INVITE_TITLE=Invite player - REMOVE_TITLE=Kick player KIT_SELECTION_TITLE=Kit selection @@ -119,7 +102,6 @@ SKIP_NOT_READY=§c§mSkipping to next event TEAM_CHAT={0}{1}§8» {0}{2} CHOOSE_KIT=§eChoose kit RESPAWN=§eRespawn -INVITE_PLAYERS=§eInvite player REMOVE_PLAYERS=§cKick player CHOOSE_SCHEMATIC=§eChoose {0} SCHEMATIC_REQUIRED=§cChoose a schematic first @@ -244,3 +226,22 @@ WIN_CREWMATE_DEAD={0} §7killed all team mates AMONG_US_IMPOSTER_MESSAGE = §4You are the Imposter§8! §7Kill all your team mates to win the game! AMONG_US_IMPOSTER_AMONG_MESSAGE = §4There is an Imposter among us§8! §7Kill him to win the game! + + +# Invites +JOIN_REQUEST=§7Request join +JOIN_REQUEST_TITLE=Request join +JOIN_REQUEST_ALREADY=§cYou have already sent a join request +JOIN_REQUEST_TEAM=§7Join {0} +JOIN_REQUEST_CONFIRMATION=§7Join request submitted +JOIN_REQUEST_NOTIFICATION=§e{0} §7requests joining team {1}§8. §7Accept or decline using §8/§erequests + +REQUESTS=§7Open join requests +REQUESTS_TITLE=Open join requests +REQUEST_DECLINED=§cJoin of {0} declined +REQUEST_YOUR_DECLINED=§cYour join request was declined +REQUESTS_LEFT_CLICK=§eLeft click §7to §eaccept§8! +REQUESTS_RIGHT_CLICK=§eRight click §7to §edecline§8! + +NO_JOIN_REQUEST=§cThe player did not request joining +NO_CONFIRMATION=§cNo confirmation necessary \ No newline at end of file diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties index fff7bc4..415652c 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties +++ b/FightSystem_Core/src/de/steamwar/fightsystem/FightSystem_de.properties @@ -23,13 +23,6 @@ FIGHT_ALREADY_STARTED=§cDer Kampf hat bereits begonnen NOT_LEADER=§cDu bist kein Leader PLAYER_UNAVAILABLE=§cDer Spieler ist nicht in der Arena -NO_INVITATION=§cDu wurdest von keinem Team eingeladen -INVITATION_DECLINED=§cEinladung abgelehnt -INVITATION_DECLINED_TEAM=§e{0} §chat die Einladung abgelehnt -PLAYER_IN_TEAM=§e{0} §cist bereits in einem Team -ALREADY_INVITED=§e{0} §cwurde bereits eingeladen -INVITATION_SENT=§e{0} §7eingeladen - NOT_IN_TEAM=§e{0} §cist nicht in deinem Team KIT_UNAVAILABLE=§cDieses Kit gibt es nicht @@ -39,8 +32,6 @@ GAMEMODE_NOT_ALLOWED=§cSpielmodusänderung verboten GAMEMODE_UNKNOWN=§cUnbekannter Spielmodus {0} GAMEMODE_HELP=§8/§7gm §8[§eSpielmodus§8] -INVITE_HELP=§8/§einvite §8[§eSpieler§8] - LEADER_FULL=§cAlle Teams haben bereits einen Leader ALREADY_IN_TEAM=§cDu bist bereits in einem Team @@ -56,12 +47,6 @@ WIN_HELP=§8/§7win §8[§eTeam §8oder §etie§8] # GUI -INVITATION_TITLE=Einladung von {0} -INVITATION_ACCEPT=§aAnnehmen -INVITATION_DECLINE=§cAblehnen -INVITATION_CHAT_ACCEPT=§8/§aaccept§8, §7um die Einladung §aanzunehmen -INVITATION_CHAT_DECLINE=§8/§cdecline§8, §7um die Einladung §cabzulehnen - STATE_TITLE=Kampfstatus STATE_PRE_LEADER_SETUP=§7Teamleaderwartephase STATE_PRE_SCHEM_SETUP=§7Schemauswahlphase @@ -71,8 +56,6 @@ STATE_RUNNING=§eKampfphase STATE_SPECTATE_WIN=§7Sieg {0} STATE_SPECTATE_TIE=§7Unentschieden -INVITE_TITLE=Spieler einladen - REMOVE_TITLE=Spieler rauswerfen KIT_SELECTION_TITLE=Kitauswahl @@ -116,7 +99,6 @@ SKIP_READY=§aBeschleunigung zum nächsten Event SKIP_NOT_READY=§c§mBeschleunigung zum nächsten Event CHOOSE_KIT=§eKit wählen RESPAWN=§eRespawn -INVITE_PLAYERS=§eSpieler einladen REMOVE_PLAYERS=§cSpieler rauswerfen CHOOSE_SCHEMATIC=§e{0} wählen SCHEMATIC_REQUIRED=§cZuerst muss eine Schematic gewählt sein @@ -228,4 +210,22 @@ WIN_IMPOSTER_DEAD={0} §7 hat den Imposter getötet WIN_CREWMATE_DEAD={0} §7 hat alle Kameraden getötet AMONG_US_IMPOSTER_MESSAGE = §4Du bist ein Imposter§8! §7Du musst alle Kameraden töten, um zu gewinnen. -AMONG_US_IMPOSTER_AMONG_MESSAGE = §4Es ist ein Imposter unter uns§8! §7Tötet ihn, um das Spiel zu gewinnen! \ No newline at end of file +AMONG_US_IMPOSTER_AMONG_MESSAGE = §4Es ist ein Imposter unter uns§8! §7Tötet ihn, um das Spiel zu gewinnen! + +# Invites +JOIN_REQUEST=§7Teambeitritt anfragen +JOIN_REQUEST_TITLE=Teambeitritt anfragen +JOIN_REQUEST_ALREADY=§cDu hast bereits ein Team um Beitritt angefragt +JOIN_REQUEST_TEAM={0} §7beitreten +JOIN_REQUEST_CONFIRMATION=§7Teambeitritt angefragt +JOIN_REQUEST_NOTIFICATION=§e{0} §7möchte Team {1} §7beitreten§8. §7Akzeptiere oder lehne ab mit §8/§erequests + +REQUESTS=§7Offene Beitrittsanfragen +REQUESTS_TITLE=Offene Beitrittsanfragen +REQUEST_DECLINED=§cBeitritt von {0} abgelehnt +REQUEST_YOUR_DECLINED=§cDeine Betrittsanfrage wurde abgelehnt +REQUESTS_LEFT_CLICK=§eLinksklick §7um §eanzunehmen§8! +REQUESTS_RIGHT_CLICK=§eRechtsklick §7um §eabzulehnen§8! + +NO_JOIN_REQUEST=§cDer Spieler hat noch keinen Beitritt angefragt +NO_CONFIRMATION=§cKeine Zustimmung nötig diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/commands/AcceptCommand.java b/FightSystem_Core/src/de/steamwar/fightsystem/commands/AcceptCommand.java deleted file mode 100644 index 0e23db4..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/commands/AcceptCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.fightsystem.commands; - -import de.steamwar.fightsystem.ArenaMode; -import de.steamwar.fightsystem.states.FightState; -import de.steamwar.fightsystem.states.StateDependentCommand; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class AcceptCommand implements CommandExecutor { - - public AcceptCommand() { - new StateDependentCommand(ArenaMode.VariableTeams, FightState.Setup, "accept", this); - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if(!(sender instanceof Player)) { - return false; - } - Player player = (Player) sender; - - Commands.acceptInvitation(player); - return false; - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/commands/Commands.java b/FightSystem_Core/src/de/steamwar/fightsystem/commands/Commands.java index 5ff08b0..6102728 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/commands/Commands.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/commands/Commands.java @@ -47,14 +47,6 @@ public class Commands { return false; } - private static FightTeam checkGetInvitedTeam(Player p){ - FightTeam fightTeam = Fight.getInvitedTeam(p); - if(fightTeam == null){ - FightSystem.getMessage().sendPrefixless("NO_INVITATION", p, ChatMessageType.ACTION_BAR); - } - return fightTeam; - } - private static FightPlayer checkGetPlayer(Player p){ FightPlayer fightPlayer = Fight.getFightPlayer(p); if(fightPlayer == null){ @@ -104,30 +96,6 @@ public class Commands { fightTeam.skip(); } - static void acceptInvitation(Player p){ - if(checkSetup(p)) - return; - - FightTeam team = checkGetInvitedTeam(p); - if(team == null) - return; - - team.addMember(p); - } - - static void declineInvitation(Player p){ - if(checkSetup(p)) - return; - - FightTeam team = checkGetInvitedTeam(p); - if(team == null) - return; - - FightSystem.getMessage().sendPrefixless("INVITATION_DECLINED", p, ChatMessageType.ACTION_BAR); - team.broadcast("INVITATION_DECLINED_TEAM", p.getName()); - team.getInvited().remove(p); - } - static void leaveTeam(Player p){ if(checkSetup(p)) return; @@ -139,37 +107,6 @@ public class Commands { fightTeam.removePlayer(p); } - static void invite(Player p, String invited){ - if(checkSetup(p)) - return; - - FightTeam fightTeam = checkGetTeam(p); - if(fightTeam == null) - return; - - FightPlayer fightPlayer = checkGetLeader(p); - if(fightPlayer == null) - return; - - Player target = checkGetPlayer(p, invited); - if(target == null) - return; - - if(Fight.getPlayerTeam(target) != null) { - FightSystem.getMessage().sendPrefixless("PLAYER_IN_TEAM", p, ChatMessageType.ACTION_BAR, target.getName()); - return; - } - - if(Fight.getOpposite(fightTeam).getInvited().contains(target) || fightTeam.getInvited().contains(target)) { - FightSystem.getMessage().sendPrefixless("ALREADY_INVITED", p, ChatMessageType.ACTION_BAR, target.getName()); - return; - } - - FightSystem.getMessage().sendPrefixless("INVITATION_SENT", p, ChatMessageType.ACTION_BAR, target.getName()); - fightTeam.getInvited().add(target); - GUI.invitation(p, target); - } - static void kick(Player p, String kicked){ if(checkSetup(p)) return; diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/commands/DeclineCommand.java b/FightSystem_Core/src/de/steamwar/fightsystem/commands/DeclineCommand.java deleted file mode 100644 index 3fa9906..0000000 --- a/FightSystem_Core/src/de/steamwar/fightsystem/commands/DeclineCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - This file is a part of the SteamWar software. - - Copyright (C) 2020 SteamWar.de-Serverteam - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ - -package de.steamwar.fightsystem.commands; - -import de.steamwar.fightsystem.ArenaMode; -import de.steamwar.fightsystem.states.FightState; -import de.steamwar.fightsystem.states.StateDependentCommand; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class DeclineCommand implements CommandExecutor { - - public DeclineCommand() { - new StateDependentCommand(ArenaMode.VariableTeams, FightState.Setup, "decline", this); - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if(!(sender instanceof Player)) { - return false; - } - Player player = (Player) sender; - - Commands.declineInvitation(player); - return false; - } -} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java b/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java index 5b04b80..cb63550 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/commands/GUI.java @@ -21,12 +21,10 @@ package de.steamwar.fightsystem.commands; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; -import de.steamwar.fightsystem.fight.Fight; -import de.steamwar.fightsystem.fight.FightPlayer; -import de.steamwar.fightsystem.fight.FightTeam; -import de.steamwar.fightsystem.fight.Kit; +import de.steamwar.fightsystem.fight.*; import de.steamwar.fightsystem.listener.PersonalKitCreator; import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.utils.ColorConverter; import de.steamwar.inventory.*; import de.steamwar.message.Message; import de.steamwar.sql.PersonalKit; @@ -47,23 +45,27 @@ public class GUI { private static final Message msg = FightSystem.getMessage(); - static void invitation(Player p, Player target){ - SWInventory inv = new SWInventory(target, 9, msg.parse("INVITATION_TITLE", target, p.getName())); - inv.setItem(0, SWItem.getDye(10), (byte)10, msg.parse("INVITATION_ACCEPT", target), (ClickType click) ->{ - Commands.acceptInvitation(target); - target.closeInventory(); + @SuppressWarnings("deprecation") + private static void addTeamRequest(Player p, SWInventory inv, int pos, FightTeam team) { + byte colorCode = ColorConverter.chat2dye(team.getColor()).getDyeData(); + inv.setItem(pos, SWItem.getDye(colorCode), colorCode, msg.parse("JOIN_REQUEST_TEAM", p, team.getColoredName()), click -> { + p.closeInventory(); + new JoinRequest(p, team); }); - inv.setItem(8, SWItem.getDye(1), (byte)1, msg.parse("INVITATION_DECLINE", target), (ClickType click) ->{ - Commands.declineInvitation(target); - target.closeInventory(); - }); - inv.addCloseCallback((ClickType click) ->{ - if(Fight.getInvitedTeam(target) != null){ - msg.sendPrefixless("INVITATION_CHAT_ACCEPT", target); - msg.sendPrefixless("INVITATION_CHAT_DECLINE", target); - } - }); - inv.setCallback(-999, (ClickType click) -> target.closeInventory()); + } + + public static void joinRequest(Player p) { + if(JoinRequest.get(p) != null) { + msg.sendPrefixless("JOIN_REQUEST_ALREADY", p, ChatMessageType.ACTION_BAR); + return; + } + + SWInventory inv = new SWInventory(p, 9, msg.parse("JOIN_REQUEST_TITLE", p)); + FightTeam team = Fight.getPlayerTeam(p); + if(team != Fight.getRedTeam()) + addTeamRequest(p, inv, team == null ? 0 : 4, Fight.getBlueTeam()); + if(team != Fight.getBlueTeam()) + addTeamRequest(p, inv, team == null ? 8 : 4, Fight.getRedTeam()); inv.open(); } @@ -84,12 +86,11 @@ public class GUI { inv.open(); } - public static void chooseInvitation(Player p){ - List> players = SWListInv.createPlayerList(p.getUniqueId()); - players.removeIf(swItemUUIDPair -> Fight.getFightPlayer(Bukkit.getPlayer(swItemUUIDPair.getObject())) != null); - SWListInv inv = new SWListInv<>(p, msg.parse("INVITE_TITLE", p), players, (ClickType click, UUID player) -> { - Commands.invite(p, SteamwarUser.get(player).getUserName()); + public static void chooseJoinRequests(Player p){ + List> players = JoinRequest.openRequests(p, Fight.getPlayerTeam(p)); + SWListInv inv = new SWListInv<>(p, msg.parse("REQUESTS_TITLE", p), players, (ClickType click, Player player) -> { p.closeInventory(); + RequestsCommand.onJoinRequest(p, player, click.isLeftClick() ? JoinRequest::accept : JoinRequest::decline); }); inv.setCallback(-999, (ClickType click) -> p.closeInventory()); inv.open(); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/commands/InviteCommand.java b/FightSystem_Core/src/de/steamwar/fightsystem/commands/RequestsCommand.java similarity index 53% rename from FightSystem_Core/src/de/steamwar/fightsystem/commands/InviteCommand.java rename to FightSystem_Core/src/de/steamwar/fightsystem/commands/RequestsCommand.java index 67cf6b1..36c2a1e 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/commands/InviteCommand.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/commands/RequestsCommand.java @@ -21,6 +21,10 @@ package de.steamwar.fightsystem.commands; import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.fight.FightPlayer; +import de.steamwar.fightsystem.fight.FightTeam; +import de.steamwar.fightsystem.fight.JoinRequest; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentCommand; import org.bukkit.command.Command; @@ -28,25 +32,46 @@ import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -public class InviteCommand implements CommandExecutor { +import java.util.function.BiConsumer; - public InviteCommand() { - new StateDependentCommand(ArenaMode.VariableTeams, FightState.Setup, "invite", this); +public class RequestsCommand implements CommandExecutor { + + public RequestsCommand() { + new StateDependentCommand(ArenaMode.VariableTeams, FightState.AntiSpectate, "request", this); + new StateDependentCommand(ArenaMode.VariableTeams, FightState.AntiSpectate, "requests", this); } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if(!(sender instanceof Player)) { + if(!(sender instanceof Player)) return false; - } Player player = (Player) sender; - - if(args.length != 1){ - FightSystem.getMessage().sendPrefixless("INVITE_HELP", player); + FightPlayer fp = Fight.getFightPlayer(player); + if(fp == null || !(fp.isLeader() || fp.isLiving())) { + GUI.joinRequest(player); return false; } - Commands.invite(player, args[0]); + if(Commands.checkGetLeader(player) == null) + return false; + + GUI.chooseJoinRequests(player); return false; } + + public static void onJoinRequest(Player player, Player target, BiConsumer handleJoinRequest) { + JoinRequest request = JoinRequest.get(target); + if(request == null) { + FightSystem.getMessage().send("NO_JOIN_REQUEST", player); + return; + } + + FightTeam team = Fight.getPlayerTeam(player); + if(!request.required(team)) { + FightSystem.getMessage().send("NO_CONFIRMATION", player); + return; + } + + handleJoinRequest.accept(request, team); + } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java index c27fc2b..c5c19b5 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/countdown/EnternCountdown.java @@ -25,17 +25,32 @@ import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.utils.Message; import de.steamwar.fightsystem.utils.SWSound; import de.steamwar.techhider.ProtocolUtils; +import de.steamwar.fightsystem.winconditions.Wincondition; import net.md_5.bungee.api.ChatMessageType; import java.util.List; public class EnternCountdown extends Countdown { + private static int calcTime(FightPlayer fp) { + int time = Config.EnterStages.get(fp.getKit().getEnterStage()); + + Countdown countdown = Wincondition.getTimeOverCountdown(); + if(countdown != null) { + time -= Config.TimeoutTime - countdown.getTimeLeft(); + + if(time < 0) + time = 0; + } + + return time; + } + private final FightPlayer fightPlayer; private List chunkPos; public EnternCountdown(FightPlayer fp) { - super(Config.EnterStages.get(fp.getKit().getEnterStage()), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false); + super(calcTime(fp), new Message("ENTERN_COUNTDOWN"), SWSound.BLOCK_NOTE_PLING, false); fightPlayer = fp; enable(); } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java index 750941e..6f465e8 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/Fight.java @@ -62,14 +62,6 @@ public class Fight { throw new IllegalArgumentException(); } - public static FightTeam getInvitedTeam(Player player){ - if(redTeam.getInvited().contains(player)) - return redTeam; - else if(blueTeam.getInvited().contains(player)) - return blueTeam; - return null; - } - public static FightPlayer getFightPlayer(Player player) { if(redTeam.isPlayerInTeam(player)) return redTeam.getFightPlayer(player); diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java index 5f3651a..ed2e6d5 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightPlayer.java @@ -23,11 +23,15 @@ import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.countdown.EnternCountdown; import de.steamwar.sql.PersonalKit; import de.steamwar.sql.SteamwarUser; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; +import java.util.UUID; + public class FightPlayer { - private final Player player; + private final UUID uuid; + private Player player; private final FightTeam team; private boolean isOut; private Kit kit; @@ -35,6 +39,7 @@ public class FightPlayer { private EnternCountdown enternCountdown = null; FightPlayer(Player player, FightTeam team) { + this.uuid = player.getUniqueId(); this.player = player; this.team = team; this.isOut = false; @@ -48,13 +53,18 @@ public class FightPlayer { kills = 0; } + public void revive() { + isOut = false; + } + public void setOut() { isOut = true; stopEnternCountdown(); } - public void setEnternCountdown(EnternCountdown countdown){ - enternCountdown = countdown; + public void startEnternCountdown() { + if(Config.EnterStages.size() > kit.getEnterStage() && kit.getEnterStage() >= 0) + enternCountdown = new EnternCountdown(this); } public void stopEnternCountdown(){ @@ -65,7 +75,10 @@ public class FightPlayer { } public Player getPlayer() { - return this.player; + Player bukkit = Bukkit.getPlayer(uuid); + if(bukkit != null) + player = bukkit; + return player; } public boolean isLiving() { diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java index 70036c7..ca19f3b 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/FightTeam.java @@ -46,6 +46,7 @@ import org.bukkit.scoreboard.NameTagVisibility; import org.bukkit.scoreboard.Team; import java.util.*; +import java.util.function.Consumer; public class FightTeam { @@ -67,7 +68,7 @@ public class FightTeam { setKitButton(notReadyKit, true); if(!ArenaMode.RankedEvent.contains(Config.mode)){ - notReadyKit.setItem(2, "INVITE_PLAYERS", new ItemBuilder(Material.PAPER).removeAllAttributes().build(), GUI::chooseInvitation); + notReadyKit.setItem(2, "REQUESTS", new ItemBuilder(Material.PAPER).removeAllAttributes().build(), GUI::chooseJoinRequests); notReadyKit.setItem(3, "REMOVE_PLAYERS", new ItemBuilder(SWItem.getMaterial("FIREWORK_CHARGE")).removeAllAttributes().build(), GUI::chooseRemove); } @@ -90,8 +91,7 @@ public class FightTeam { private FightPlayer leader; private int schemRank; - private final Map players = new HashMap<>(); - private final Set invited = new HashSet<>(); + private final Map players = new HashMap<>(); private String name; private String prefix; @@ -165,11 +165,11 @@ public class FightTeam { } public void teleportToSpawn(){ - players.forEach((player, fp) -> player.teleport(spawn)); + players.forEach((player, fp) -> Objects.requireNonNull(Bukkit.getPlayer(player)).teleport(spawn)); } public FightPlayer getFightPlayer(Player player) { - return players.get(player); + return players.get(player.getUniqueId()); } public boolean allPlayersOut() { @@ -181,7 +181,7 @@ public class FightTeam { } public boolean isPlayerInTeam(Player player) { - return players.containsKey(player); + return players.containsKey(player.getUniqueId()); } public boolean canPlayerEntern(Player player) { @@ -199,24 +199,24 @@ public class FightTeam { skip = false; ready = false; schematic.reset(); - invited.clear(); - Set playerSet = new HashSet<>(players.keySet()); - for(Player player : playerSet){ - if(!Bukkit.getOnlinePlayers().contains(player)) + Set playerSet = new HashSet<>(players.keySet()); + for(UUID uuid : playerSet){ + Player player = Bukkit.getPlayer(uuid); + if(player == null) removePlayer(player); } FightPlayer leaderBackup = leader; - playerSet.removeIf(player -> !Bukkit.getOnlinePlayers().contains(player)); + playerSet.removeIf(uuid -> Bukkit.getPlayer(uuid) == null); players.clear(); leader = null; if(leaderBackup != null){ - playerSet.remove(leaderBackup.getPlayer()); + playerSet.remove(leaderBackup.getPlayer().getUniqueId()); addMember(leaderBackup.getPlayer(), true); } - playerSet.forEach(p -> addMember(p, true)); + playerSet.forEach(uuid -> addMember(Bukkit.getPlayer(uuid), true)); if(ArenaMode.VariableTeams.contains(Config.mode) && isLeaderless()){ List onlinePlayers = new ArrayList<>(Bukkit.getOnlinePlayers()); @@ -231,36 +231,52 @@ public class FightTeam { } public void broadcast(String message, Object... params) { - players.forEach((player, fp) -> FightSystem.getMessage().sendPrefixless(message, player, ChatMessageType.ACTION_BAR, params)); + broadcast(player -> FightSystem.getMessage().sendPrefixless(message, player, ChatMessageType.ACTION_BAR, params)); } public void broadcastSystem(String message, Object... params) { - players.forEach((player, fp) -> FightSystem.getMessage().send(message, player, params)); + broadcast(player -> FightSystem.getMessage().send(message, player, params)); } public void broadcastChat(Player sender, String message) { - players.forEach((player, fp) -> FightSystem.getMessage().sendPrefixless("TEAM_CHAT", player, ChatMessageType.CHAT, prefix, sender.getName(), message)); + broadcast(player -> FightSystem.getMessage().sendPrefixless("TEAM_CHAT", player, ChatMessageType.CHAT, prefix, sender.getName(), message)); + } + + private void broadcast(Consumer f) { + players.forEach((uuid, fightPlayer) -> { + Player player = Bukkit.getPlayer(uuid); + if(player != null) + f.accept(player); + }); } public void addMember(Player player) { addMember(player, false); } - public void addMember(Player player, boolean silent) { + private void addMember(Player player, boolean silent) { final List chunksToReload = FightSystem.getTechHider().prepareChunkReload(player, false); - FightPlayer fightPlayer = new FightPlayer(player, this); - players.put(player, fightPlayer); - invited.remove(player); + FightPlayer fightPlayer = getFightPlayer(player) != null ? getFightPlayer(player) : new FightPlayer(player, this); + fightPlayer.revive(); + players.put(player.getUniqueId(), fightPlayer); Permanent.getSpectatorTeam().removeEntry(player.getName()); team.addEntry(player.getName()); - Fight.setPlayerGamemode(player, GameMode.SURVIVAL); player.setHealth(20); player.setFoodLevel(20); player.getInventory().clear(); BountifulWrapper.impl.setAttackSpeed(player); player.teleport(spawn); - memberKit.loadToPlayer(player); + + if(FightState.Spectate.contains(FightState.getFightState())) { + Fight.setPlayerGamemode(player, GameMode.SPECTATOR); + } else { + Fight.setPlayerGamemode(player, GameMode.SURVIVAL); + (FightState.ingame() ? fightPlayer.getKit() : memberKit).loadToPlayer(player); + } + if(FightState.Running.contains(FightState.getFightState())) + fightPlayer.startEnternCountdown(); + GlobalRecorder.getInstance().playerJoins(player); FightSystem.getTechHider().reloadChunks(player, chunksToReload, false); @@ -275,7 +291,7 @@ public class FightTeam { PersonalKitCreator.closeIfInKitCreator(player); List chunksToReload = FightSystem.getTechHider().prepareChunkReload(player, true); - players.remove(player); + players.remove(player.getUniqueId()); team.removeEntry(player.getName()); Permanent.getSpectatorTeam().addEntry(player.getName()); @@ -291,6 +307,9 @@ public class FightTeam { if(player.isOnline()){ FightSystem.getTechHider().reloadChunks(player, chunksToReload, true); + + if(ArenaMode.VariableTeams.contains(Config.mode)) + HotbarKit.SPECTATOR_KIT.loadToPlayer(player); } } @@ -419,10 +438,6 @@ public class FightTeam { } } - public Set getInvited() { - return invited; - } - public String getName() { return name; } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java index ef2e3a3..8310d2c 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/HotbarKit.java @@ -23,10 +23,13 @@ import de.steamwar.core.Core; import de.steamwar.fightsystem.ArenaMode; import de.steamwar.fightsystem.Config; import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.commands.GUI; import de.steamwar.fightsystem.listener.PersonalKitCreator; import de.steamwar.fightsystem.states.FightState; import de.steamwar.fightsystem.states.StateDependentListener; import de.steamwar.fightsystem.states.StateDependentTask; +import de.steamwar.fightsystem.utils.ItemBuilder; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -45,6 +48,12 @@ import java.util.function.Consumer; public class HotbarKit extends Kit { + public static final HotbarKit SPECTATOR_KIT = new HotbarKit(); + static { + for(int i = 0; i < 9; i++) + SPECTATOR_KIT.setItem(i, "JOIN_REQUEST", new ItemBuilder(Material.PAPER).removeAllAttributes().build(), GUI::joinRequest); + } + private static final int HOTBAR_SIZE = 9; private final String[] nameTags; @@ -87,8 +96,8 @@ public class HotbarKit extends Kit { private static final Set clicked = new HashSet<>(); public HotbarKitListener() { - new StateDependentListener(ArenaMode.AntiReplay, FightState.Setup, this); - new StateDependentTask(ArenaMode.AntiReplay, FightState.Setup, clicked::clear, 10, 10); + new StateDependentListener(ArenaMode.AntiReplay, FightState.All, this); + new StateDependentTask(ArenaMode.AntiReplay, FightState.All, clicked::clear, 10, 10); } @EventHandler diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/fight/JoinRequest.java b/FightSystem_Core/src/de/steamwar/fightsystem/fight/JoinRequest.java new file mode 100644 index 0000000..13ab67a --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/fight/JoinRequest.java @@ -0,0 +1,104 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2022 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.fightsystem.fight; + +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.inventory.SWItem; +import de.steamwar.inventory.SWListInv; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.ClickEvent; +import org.bukkit.entity.Player; + +import java.util.*; +import java.util.stream.Collectors; + +public class JoinRequest { + + private static final Map activeRequests = new HashMap<>(); + + public static List> openRequests(Player p, FightTeam team) { + return activeRequests.values().stream().filter( + request -> request.waitOnApproval.contains(team) + ).map(request -> { + SWItem item = SWItem.getPlayerSkull(request.player); + item.setLore(Arrays.asList( + FightSystem.getMessage().parse("REQUESTS_LEFT_CLICK", p), + FightSystem.getMessage().parse("REQUESTS_RIGHT_CLICK", p) + )); + return new SWListInv.SWListEntry<>(item, request.player); + }).collect(Collectors.toList()); + } + + public static void clearRequests() { + activeRequests.clear(); + } + + public static JoinRequest get(Player player) { + return activeRequests.get(player); + } + + private final Player player; + private final FightTeam team; + private final Set waitOnApproval; + + public JoinRequest(Player player, FightTeam team) { + this.player = player; + this.team = team; + this.waitOnApproval = new HashSet<>(FightState.ingame() ? Fight.teams() : Collections.singleton(team)); + for(FightTeam t : waitOnApproval) { + FightPlayer leader = t.getLeader(); + if(leader == null) + continue; + + Player leaderPlayer = leader.getPlayer(); + if(leaderPlayer == null) + continue; + + FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_NOTIFICATION", leaderPlayer, "REQUESTS", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/requests"), player.getName(), team.getColoredName()); + } + + activeRequests.put(player, this); + FightSystem.getMessage().sendPrefixless("JOIN_REQUEST_CONFIRMATION", player, ChatMessageType.ACTION_BAR); + } + + public boolean required(FightTeam decider) { + return waitOnApproval.contains(decider); + } + + public void accept(FightTeam acceptor) { + waitOnApproval.remove(acceptor); + + if(waitOnApproval.isEmpty()) { + team.addMember(player); + activeRequests.remove(player); + } + } + + public void decline(FightTeam declinor) { + FightSystem.getMessage().sendPrefixless("REQUEST_YOUR_DECLINED", player, ChatMessageType.ACTION_BAR); + waitOnApproval.forEach(t -> t.broadcast("REQUEST_DECLINED", player.getName())); + silentDecline(); + } + + public void silentDecline() { + activeRequests.remove(player); + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/JoinRequestListener.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/JoinRequestListener.java new file mode 100644 index 0000000..1ed3fe8 --- /dev/null +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/JoinRequestListener.java @@ -0,0 +1,74 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2022 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ + +package de.steamwar.fightsystem.listener; + +import de.steamwar.fightsystem.ArenaMode; +import de.steamwar.fightsystem.Config; +import de.steamwar.fightsystem.FightSystem; +import de.steamwar.fightsystem.fight.Fight; +import de.steamwar.fightsystem.fight.FightPlayer; +import de.steamwar.fightsystem.fight.HotbarKit; +import de.steamwar.fightsystem.fight.JoinRequest; +import de.steamwar.fightsystem.states.FightState; +import de.steamwar.fightsystem.states.OneShotStateDependent; +import de.steamwar.fightsystem.states.StateDependentListener; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; + +public class JoinRequestListener implements Listener { + + public JoinRequestListener() { + new OneShotStateDependent(ArenaMode.VariableTeams, FightState.PreLeaderSetup, () -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), JoinRequest::clearRequests)); + new OneShotStateDependent(ArenaMode.VariableTeams, FightState.PreRunning, () -> Bukkit.getScheduler().runTask(FightSystem.getPlugin(), JoinRequest::clearRequests)); + + new StateDependentListener(ArenaMode.VariableTeams, FightState.All, this); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + FightPlayer fp = Fight.getFightPlayer(player); + + if (!Config.ArenaLeaveable && (fp == null || !fp.isLiving())) { + HotbarKit.SPECTATOR_KIT.loadToPlayer(player); + } + } + + @EventHandler + public void handlePlayerRespawn(PlayerRespawnEvent event) { + Player player = event.getPlayer(); + if(Fight.fighting(player)) { + HotbarKit.SPECTATOR_KIT.loadToPlayer(player); + } + } + + @EventHandler + public void onLeave(PlayerQuitEvent event) { + JoinRequest request = JoinRequest.get(event.getPlayer()); + if(request != null) + request.silentDecline(); + } +} diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java index 4ae1875..b5cb0e7 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/listener/Permanent.java @@ -93,11 +93,15 @@ public class Permanent implements Listener { event.setJoinMessage(null); Player player = event.getPlayer(); + FightPlayer fp = Fight.getFightPlayer(player); - if (!Config.ArenaLeaveable && !Fight.fighting(player)) { + if (!Config.ArenaLeaveable && fp == null) { Fight.setPlayerGamemode(player, GameMode.SPECTATOR); spectatorTeam.addEntry(player.getName()); player.teleport(Config.SpecSpawn); + } else if(fp != null && !fp.isLiving()) { + Fight.setPlayerGamemode(player, GameMode.SPECTATOR); + player.teleport(fp.getTeam().getSpawn()); } } diff --git a/FightSystem_Core/src/de/steamwar/fightsystem/utils/EnterHandler.java b/FightSystem_Core/src/de/steamwar/fightsystem/utils/EnterHandler.java index cec63a4..ee5aa79 100644 --- a/FightSystem_Core/src/de/steamwar/fightsystem/utils/EnterHandler.java +++ b/FightSystem_Core/src/de/steamwar/fightsystem/utils/EnterHandler.java @@ -19,8 +19,6 @@ package de.steamwar.fightsystem.utils; -import de.steamwar.fightsystem.Config; -import de.steamwar.fightsystem.countdown.EnternCountdown; import de.steamwar.fightsystem.fight.Fight; import de.steamwar.fightsystem.fight.FightPlayer; import de.steamwar.fightsystem.fight.FightTeam; @@ -53,8 +51,7 @@ public class EnterHandler implements IStateDependent { private void registerTeam(FightTeam team){ for(FightPlayer fp : team.getPlayers()){ - if(Config.EnterStages.size() > fp.getKit().getEnterStage() && fp.getKit().getEnterStage() >= 0) - fp.setEnternCountdown(new EnternCountdown(fp)); + fp.startEnternCountdown(); } } diff --git a/FightSystem_Core/src/plugin.yml b/FightSystem_Core/src/plugin.yml index a740a86..abc32f9 100644 --- a/FightSystem_Core/src/plugin.yml +++ b/FightSystem_Core/src/plugin.yml @@ -12,10 +12,9 @@ api-version: "1.13" commands: ak: - accept: - decline: + request: + requests: leave: - invite: ready: kit: remove: