diff --git a/src/de/steamwar/bungeecore/ArenaMode.java b/src/de/steamwar/bungeecore/ArenaMode.java index 6c27feb4..5c1889eb 100644 --- a/src/de/steamwar/bungeecore/ArenaMode.java +++ b/src/de/steamwar/bungeecore/ArenaMode.java @@ -26,10 +26,11 @@ public class ArenaMode { return byInternal.get(name); } - public static List getAllChatNames() { + public static List getAllChatNames(boolean historic) { List chatNames = new LinkedList<>(); for(ArenaMode mode : byInternal.values()){ - chatNames.addAll(mode.chatNames); + if(historic == mode.historic) + chatNames.addAll(mode.chatNames); } return chatNames; } @@ -48,6 +49,7 @@ public class ArenaMode { private final String serverJar; private final List maps; private final boolean historic; + private final boolean ranked; private ArenaMode(String internalName, Configuration config){ this.internalName = internalName; @@ -56,6 +58,7 @@ public class ArenaMode { this.chatNames = config.getStringList("chatNames"); this.maps = config.getStringList("maps"); this.historic = config.getBoolean("historic"); + this.ranked = config.getBoolean("ranked"); allModes.add(this); byInternal.put(internalName, this); @@ -106,4 +109,8 @@ public class ArenaMode { public boolean isHistoric(){ return historic; } + + public boolean isRanked() { + return ranked; + } } diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index 85d43d7d..d334823c 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -95,6 +95,8 @@ public class BungeeCore extends Plugin { new RegelnCommand(); new HistoricCommand(); new CheckCommand(); + new RankedCommand(); + new RankCommand(); new EventStarter(); new Broadcaster(); diff --git a/src/de/steamwar/bungeecore/commands/ChallengeCommand.java b/src/de/steamwar/bungeecore/commands/ChallengeCommand.java index 8cfa08df..68ec0228 100644 --- a/src/de/steamwar/bungeecore/commands/ChallengeCommand.java +++ b/src/de/steamwar/bungeecore/commands/ChallengeCommand.java @@ -72,7 +72,7 @@ public class ChallengeCommand extends BasicCommand { @Override public Iterable onTabComplete(CommandSender commandSender, String[] args) { if(args.length == 2) - return ArenaMode.getAllChatNames(); + return ArenaMode.getAllChatNames(false); return new ArrayList<>(); } } diff --git a/src/de/steamwar/bungeecore/commands/FightCommand.java b/src/de/steamwar/bungeecore/commands/FightCommand.java index 3a5a9795..5355b3ca 100644 --- a/src/de/steamwar/bungeecore/commands/FightCommand.java +++ b/src/de/steamwar/bungeecore/commands/FightCommand.java @@ -26,7 +26,7 @@ public class FightCommand extends BasicCommand { super("fight", "", "f"); } - private static ArenaMode getMode(CommandSender sender, String arg){ + static ArenaMode getMode(CommandSender sender, String arg){ ArenaMode mode = ArenaMode.getByChat(arg); if(mode != null) return mode; @@ -152,7 +152,7 @@ public class FightCommand extends BasicCommand { @Override public Iterable onTabComplete(CommandSender commandSender, String[] args) { if(args.length == 1){ - return ArenaMode.getAllChatNames(); + return ArenaMode.getAllChatNames(false); }else if(args.length == 2){ ArenaMode mode = ArenaMode.getByChat(args[1]); if(mode == null) diff --git a/src/de/steamwar/bungeecore/commands/HistoricCommand.java b/src/de/steamwar/bungeecore/commands/HistoricCommand.java index b83cbe42..034de52a 100644 --- a/src/de/steamwar/bungeecore/commands/HistoricCommand.java +++ b/src/de/steamwar/bungeecore/commands/HistoricCommand.java @@ -33,7 +33,7 @@ public class HistoricCommand extends BasicCommand { @Override public Iterable onTabComplete(CommandSender commandSender, String[] args) { if(args.length == 1){ - return ArenaMode.getAllChatNames(); + return ArenaMode.getAllChatNames(true); }else if(args.length == 2){ ArenaMode mode = ArenaMode.getByChat(args[1]); if(mode == null) diff --git a/src/de/steamwar/bungeecore/commands/RankCommand.java b/src/de/steamwar/bungeecore/commands/RankCommand.java new file mode 100644 index 00000000..4658e6eb --- /dev/null +++ b/src/de/steamwar/bungeecore/commands/RankCommand.java @@ -0,0 +1,14 @@ +package de.steamwar.bungeecore.commands; + +import net.md_5.bungee.api.CommandSender; + +public class RankCommand extends BasicCommand { + public RankCommand() { + super("rank", null); + } + + @Override + public void execute(CommandSender sender, String[] args) { + + } +} diff --git a/src/de/steamwar/bungeecore/commands/RankedCommand.java b/src/de/steamwar/bungeecore/commands/RankedCommand.java new file mode 100644 index 00000000..f8f9aa0d --- /dev/null +++ b/src/de/steamwar/bungeecore/commands/RankedCommand.java @@ -0,0 +1,125 @@ +package de.steamwar.bungeecore.commands; + +import de.steamwar.bungeecore.ArenaMode; +import de.steamwar.bungeecore.BungeeCore; +import de.steamwar.bungeecore.Servertype; +import de.steamwar.bungeecore.Subserver; +import de.steamwar.bungeecore.sql.Elo; +import de.steamwar.bungeecore.sql.SteamwarUser; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class RankedCommand extends BasicCommand { + + private static Map queues = new HashMap(); + + public RankedCommand() { + super("ranked", null); + for(ArenaMode mode : ArenaMode.getAllModes()) + if(mode.isRanked()) + queues.put(mode, new WaitingQueue(mode)); + + ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::checkForGames, 1, TimeUnit.SECONDS); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(args.length < 1){ + BungeeCore.send(sender, BungeeCore.CHAT_PREFIX + "§8/§7ranked §8[§eSpielmodus§8]"); + return; + }else if(!(sender instanceof ProxiedPlayer)) + return; + + ArenaMode mode = FightCommand.getMode(sender, args[0]); + if(mode == null) + return; + else if(!mode.isRanked()){ + BungeeCore.send(sender, BungeeCore.CHAT_PREFIX + "§cDieser Spielmodus ist nicht für Ranglistenspiele freigeschalten"); + return; + } + + ProxiedPlayer player = (ProxiedPlayer) sender; + queues.get(mode) + } + + private void checkForGames(){ + for(WaitingQueue queue : queues.values()){ + queue.checkForGames(); + } + } + + private static class WaitingQueue{ + + Set players = new HashSet<>(); + private final ArenaMode mode; + + private WaitingQueue(ArenaMode mode) { + this.mode = mode; + } + + private void addPlayer(ProxiedPlayer player){ + players.add(new WaitingPlayer(player, mode)); + } + + private void checkForGames(){ + players.removeIf(wp -> !wp.doesStillWait()); + for(WaitingPlayer wp1 : players){ + for(WaitingPlayer wp2 : players){ + if(wp1 == wp2) + continue; + + if(wp1.inRange(wp2)){ + //TODO: Open game opportunity + } + } + wp1.increment(); + } + } + } + + private static class WaitingPlayer{ + private int currentRange; + private final int elo; + private final ProxiedPlayer player; + + private WaitingPlayer(ProxiedPlayer player, String gameMode){ + this.player = player; + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + elo = Elo.getElo(user.getId(), gameMode); + currentRange = 0; + } + + private boolean inRange(WaitingPlayer player){ + return Math.abs(elo - player.elo) <= this.currentRange; + } + + private void increment(){ + currentRange++; + } + + private boolean doesStillWait(){ + if(!player.isConnected()) + return false; + + //TODO: Check if has open match + + Subserver subserver = Subserver.getSubserver(player); + if(subserver == null) + return true; + if(subserver.getType() == Servertype.ARENA){ + BungeeCore.send(player, BungeeCore.CHAT_PREFIX + "§cRanglistenspiel-Warteschlange abgebrochen"); + return false; + } + + return true; + } + } + + private static class OpenMatch{ + //TODO: Open matches + } +} diff --git a/src/de/steamwar/bungeecore/sql/Elo.java b/src/de/steamwar/bungeecore/sql/Elo.java new file mode 100644 index 00000000..8c693e56 --- /dev/null +++ b/src/de/steamwar/bungeecore/sql/Elo.java @@ -0,0 +1,32 @@ +package de.steamwar.bungeecore.sql; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class Elo { + private Elo(){} + + public static int getElo(int userID, String gameMode){ + ResultSet rs = SQL.select("SELECT Elo FROM Elo WHERE UserID = ? AND GameMode = ?", userID, gameMode); + int elo = 1000; + try { + if(rs.next()) + elo = rs.getInt("Elo"); + } catch (SQLException e) { + throw new SecurityException("Could not get Elo", e); + } + return elo; + } + + public static int getPlacement(int elo, String gameMode){ + ResultSet rs = SQL.select("SELECT COUNT(*) AS Place FROM Elo WHERE GameMode = ? AND Elo > ?", gameMode, elo); + try{ + if(!rs.next()) + throw new SecurityException("Could not get place"); + + return rs.getInt("Place"); + }catch(SQLException e){ + throw new SecurityException("Could not get place", e); + } + } +}