geforkt von SteamWar/BungeeCore
Add new rank system
Dieser Commit ist enthalten in:
Ursprung
a3e1db4fbb
Commit
d29ef7749d
@ -144,7 +144,6 @@ public class BungeeCore extends Plugin {
|
||||
new ChallengeCommand();
|
||||
new HistoricCommand();
|
||||
new CheckCommand();
|
||||
new RankedCommand();
|
||||
|
||||
new Broadcaster();
|
||||
}else{
|
||||
|
@ -22,6 +22,7 @@ package de.steamwar.bungeecore.commands;
|
||||
import de.steamwar.bungeecore.ArenaMode;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.sql.Elo;
|
||||
import de.steamwar.bungeecore.sql.Season;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
@ -40,7 +41,7 @@ public class RankCommand extends BasicCommand {
|
||||
return;
|
||||
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
Message.send("RANK_HEADER", player);
|
||||
Message.send("RANK_HEADER", player, Season.convertSeasonToString(Season.getSeason()));
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
for(ArenaMode mode : ArenaMode.getAllModes()){
|
||||
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 {
|
||||
|
||||
private static final Statement elo = new Statement("SELECT Elo FROM Elo WHERE UserID = ? AND GameMode = ?");
|
||||
private static final Statement place = new Statement("SELECT COUNT(*) AS Place FROM Elo WHERE GameMode = ? AND Elo > ?");
|
||||
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 > ? AND Season = ?");
|
||||
|
||||
private Elo(){}
|
||||
|
||||
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 -> {
|
||||
if(rs.next())
|
||||
return rs.getInt("Elo");
|
||||
return 1000;
|
||||
}, userID, gameMode);
|
||||
}, userID, gameMode, season);
|
||||
}
|
||||
|
||||
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 -> {
|
||||
if(rs.next())
|
||||
return rs.getInt("Place");
|
||||
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.
|
||||
|
||||
#RankCommand
|
||||
RANK_HEADER=§7§lPlatzierungen
|
||||
RANK_HEADER=§7§lPlatzierungen {0}
|
||||
RANK_UNPLACED=§7{0}§8: §eunplatziert
|
||||
RANK_PLACED=§7{0}§8: §e{1}§8. §7mit §e{2} §7Elo§8.
|
||||
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren