Dieser Commit ist enthalten in:
Ursprung
a3e1db4fbb
Commit
d29ef7749d
@ -144,7 +144,6 @@ public class BungeeCore extends Plugin {
|
|||||||
new ChallengeCommand();
|
new ChallengeCommand();
|
||||||
new HistoricCommand();
|
new HistoricCommand();
|
||||||
new CheckCommand();
|
new CheckCommand();
|
||||||
new RankedCommand();
|
|
||||||
|
|
||||||
new Broadcaster();
|
new Broadcaster();
|
||||||
}else{
|
}else{
|
||||||
|
@ -22,6 +22,7 @@ package de.steamwar.bungeecore.commands;
|
|||||||
import de.steamwar.bungeecore.ArenaMode;
|
import de.steamwar.bungeecore.ArenaMode;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.bungeecore.sql.Elo;
|
import de.steamwar.bungeecore.sql.Elo;
|
||||||
|
import de.steamwar.bungeecore.sql.Season;
|
||||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||||
import net.md_5.bungee.api.CommandSender;
|
import net.md_5.bungee.api.CommandSender;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
@ -40,7 +41,7 @@ public class RankCommand extends BasicCommand {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||||
Message.send("RANK_HEADER", player);
|
Message.send("RANK_HEADER", player, Season.convertSeasonToString(Season.getSeason()));
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
for(ArenaMode mode : ArenaMode.getAllModes()){
|
for(ArenaMode mode : ArenaMode.getAllModes()){
|
||||||
if(!mode.isRanked())
|
if(!mode.isRanked())
|
||||||
|
@ -1,216 +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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
|
||||||
|
|
||||||
import de.steamwar.bungeecore.*;
|
|
||||||
import de.steamwar.bungeecore.sql.Elo;
|
|
||||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.md_5.bungee.api.CommandSender;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
|
||||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
|
||||||
import net.md_5.bungee.api.chat.HoverEvent;
|
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class RankedCommand extends BasicCommand {
|
|
||||||
|
|
||||||
private static Map<ArenaMode, WaitingQueue> 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, 1, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(CommandSender sender, String[] args) {
|
|
||||||
if(!(sender instanceof ProxiedPlayer)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(args.length < 1){
|
|
||||||
getModes(sender, "/ranked ");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArenaMode mode = FightCommand.getMode(sender, args[0]);
|
|
||||||
if(mode == null)
|
|
||||||
return;
|
|
||||||
else if(!mode.isRanked()){
|
|
||||||
Message.send("RANKED_NO_RANKED_MODE", sender);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
|
||||||
queues.get(mode).togglePlayer(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
|
|
||||||
if(args.length > 1)
|
|
||||||
return new ArrayList<>();
|
|
||||||
|
|
||||||
List<String> result = ArenaMode.getAllRankedChatNames();
|
|
||||||
result.removeIf(name -> !name.startsWith(args[0]));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getModes(CommandSender sender, String precommand){
|
|
||||||
TextComponent start = new TextComponent();
|
|
||||||
TextComponent current = start;
|
|
||||||
for(ArenaMode mode : ArenaMode.getAllModes()){
|
|
||||||
if(mode.withoutChatName() || !mode.isRanked())
|
|
||||||
continue;
|
|
||||||
String command = precommand + mode.getChatName();
|
|
||||||
current.setBold(true);
|
|
||||||
current.setColor(ChatColor.GRAY);
|
|
||||||
current.setText(mode.getChatName() + " ");
|
|
||||||
current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§e" + command).create()));
|
|
||||||
current.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command));
|
|
||||||
if(current != start)
|
|
||||||
start.addExtra(current);
|
|
||||||
current = new TextComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
sender.sendMessage(start);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkForGames(){
|
|
||||||
for(WaitingQueue queue : queues.values())
|
|
||||||
queue.checkForGames();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class WaitingQueue{
|
|
||||||
|
|
||||||
Set<WaitingPlayer> players = new HashSet<>();
|
|
||||||
private final ArenaMode mode;
|
|
||||||
|
|
||||||
private WaitingQueue(ArenaMode mode) {
|
|
||||||
this.mode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void togglePlayer(ProxiedPlayer player){
|
|
||||||
for(WaitingPlayer wp : players){
|
|
||||||
if(wp.player == player){
|
|
||||||
Message.send("RANKED_QUEUE_LEFT", player);
|
|
||||||
players.remove(wp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Message.send("RANKED_QUEUE_JOINED", player);
|
|
||||||
Message.send("RANKED_QUEUE_HOW_TO_LEAVE", player);
|
|
||||||
players.add(new WaitingPlayer(player, mode.getSchemType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeFromAll(ProxiedPlayer player){
|
|
||||||
for(WaitingQueue queue : queues.values()){
|
|
||||||
Iterator<WaitingPlayer> it = queue.players.iterator();
|
|
||||||
while(it.hasNext()){
|
|
||||||
WaitingPlayer wp = it.next();
|
|
||||||
if(wp.player == player){
|
|
||||||
it.remove();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkForGames(){
|
|
||||||
players.removeIf(wp -> !wp.doesStillWait());
|
|
||||||
Map<WaitingPlayer, WaitingPlayer> inRange = new HashMap<>();
|
|
||||||
|
|
||||||
//Find games
|
|
||||||
for(WaitingPlayer wp1 : players){
|
|
||||||
if(inRange.containsValue(wp1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for(WaitingPlayer wp2 : players){
|
|
||||||
if(wp1 == wp2 || inRange.containsKey(wp2) || inRange.containsValue(wp2))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(wp1.inRange(wp2))
|
|
||||||
inRange.putIfAbsent(wp1, wp2);
|
|
||||||
}
|
|
||||||
wp1.increment();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Map.Entry<WaitingPlayer, WaitingPlayer> entry : inRange.entrySet()){
|
|
||||||
WaitingPlayer wp1 = entry.getKey();
|
|
||||||
WaitingPlayer wp2 = entry.getValue();
|
|
||||||
Message.send("RANKED_ENEMY_SPOTTED", wp1.player);
|
|
||||||
Message.send("RANKED_ENEMY_SPOTTED", wp2.player);
|
|
||||||
removeFromAll(wp1.player);
|
|
||||||
removeFromAll(wp2.player);
|
|
||||||
|
|
||||||
Subserver arena = SubserverSystem.startArena(mode, mode.getRandomMap(), 0, 0, 0, 0, null, null, wp1.player.getUniqueId(), wp2.player.getUniqueId(), true);
|
|
||||||
arena.sendPlayer(wp1.player);
|
|
||||||
arena.sendPlayer(wp2.player);
|
|
||||||
|
|
||||||
Message.broadcast("RANKED_BROADCAST", "RANKED_BROADCAST_HOVER",
|
|
||||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), wp1.player.getName(), wp2.player.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
Subserver subserver = Subserver.getSubserver(player);
|
|
||||||
if(subserver == null)
|
|
||||||
return true;
|
|
||||||
if(subserver.getType() == Servertype.ARENA){
|
|
||||||
Message.send("RANKED_QUEUE_LEFT", player);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,24 +21,32 @@ package de.steamwar.bungeecore.sql;
|
|||||||
|
|
||||||
public class Elo {
|
public class Elo {
|
||||||
|
|
||||||
private static final Statement elo = new Statement("SELECT Elo FROM Elo WHERE UserID = ? AND GameMode = ?");
|
private static final Statement elo = new Statement("SELECT Elo FROM Elo WHERE UserID = ? AND GameMode = ? AND Season = ?");
|
||||||
private static final Statement place = new Statement("SELECT COUNT(*) AS Place FROM Elo WHERE GameMode = ? AND Elo > ?");
|
private static final Statement place = new Statement("SELECT COUNT(*) AS Place FROM Elo WHERE GameMode = ? AND Elo > ? AND Season = ?");
|
||||||
|
|
||||||
private Elo(){}
|
private Elo(){}
|
||||||
|
|
||||||
public static int getElo(int userID, String gameMode){
|
public static int getElo(int userID, String gameMode){
|
||||||
|
return getElo(Season.getSeason(), userID, gameMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getElo(int season, int userID, String gameMode){
|
||||||
return elo.select(rs -> {
|
return elo.select(rs -> {
|
||||||
if(rs.next())
|
if(rs.next())
|
||||||
return rs.getInt("Elo");
|
return rs.getInt("Elo");
|
||||||
return 1000;
|
return 1000;
|
||||||
}, userID, gameMode);
|
}, userID, gameMode, season);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getPlacement(int elo, String gameMode){
|
public static int getPlacement(int elo, String gameMode){
|
||||||
|
return getPlacement(Season.getSeason(), elo, gameMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getPlacement(int season, int elo, String gameMode){
|
||||||
return place.select(rs -> {
|
return place.select(rs -> {
|
||||||
if(rs.next())
|
if(rs.next())
|
||||||
return rs.getInt("Place");
|
return rs.getInt("Place");
|
||||||
return -1;
|
return -1;
|
||||||
}, gameMode, elo);
|
}, gameMode, elo, season);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
49
src/de/steamwar/bungeecore/sql/Season.java
Normale Datei
49
src/de/steamwar/bungeecore/sql/Season.java
Normale Datei
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.sql;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
public class Season {
|
||||||
|
private Season() {}
|
||||||
|
|
||||||
|
public static int getSeason() {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
int yearIndex = calendar.get(Calendar.MONTH) / 3;
|
||||||
|
return (calendar.get(Calendar.YEAR) * 3 + yearIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String convertSeasonToString(int season){
|
||||||
|
if (season == -1) return "";
|
||||||
|
int yearSeason = season % 3;
|
||||||
|
int year = (season - yearSeason) / 3;
|
||||||
|
return String.format("%d-%d", year, yearSeason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int convertSeasonToNumber(String season){
|
||||||
|
if (season.isEmpty()) return -1;
|
||||||
|
String[] split = season.split("-");
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(split[0]) * 3 + Integer.parseInt(split[1]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -302,7 +302,7 @@ POLL_ANSWER_REFRESH=§aDeine Antwort wurde aktualisiert.
|
|||||||
POLL_ANSWER_NEW=§aDeine Antwort wurde registriert.
|
POLL_ANSWER_NEW=§aDeine Antwort wurde registriert.
|
||||||
|
|
||||||
#RankCommand
|
#RankCommand
|
||||||
RANK_HEADER=§7§lPlatzierungen
|
RANK_HEADER=§7§lPlatzierungen {0}
|
||||||
RANK_UNPLACED=§7{0}§8: §eunplatziert
|
RANK_UNPLACED=§7{0}§8: §eunplatziert
|
||||||
RANK_PLACED=§7{0}§8: §e{1}§8. §7mit §e{2} §7Elo§8.
|
RANK_PLACED=§7{0}§8: §e{1}§8. §7mit §e{2} §7Elo§8.
|
||||||
|
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren