Archiviert
1
0

Merge pull request 'Ranked' (#306) from Ranked into master

Reviewed-on: SteamWar/BungeeCore#306
Reviewed-by: Lixfel <lixfel@steamwar.de>
Dieser Commit ist enthalten in:
Lixfel 2022-03-13 20:26:15 +01:00
Commit e34dfa9166
9 geänderte Dateien mit 265 neuen und 70 gelöschten Zeilen

Datei anzeigen

@ -25,10 +25,7 @@ import de.steamwar.bungeecore.commands.*;
import de.steamwar.bungeecore.comms.SpigotReceiver;
import de.steamwar.bungeecore.listeners.*;
import de.steamwar.bungeecore.listeners.mods.*;
import de.steamwar.bungeecore.sql.Punishment;
import de.steamwar.bungeecore.sql.Statement;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.bungeecore.sql.Team;
import de.steamwar.bungeecore.sql.*;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
@ -156,6 +153,7 @@ public class BungeeCore extends Plugin {
getProxy().getScheduler().schedule(this, () -> {
SteamwarUser.clearCache();
UserElo.clearCache();
Team.clearCache();
}, 1, 1, TimeUnit.HOURS);

Datei anzeigen

@ -20,15 +20,65 @@
package de.steamwar.bungeecore.comms.handlers;
import com.google.common.io.ByteArrayDataInput;
import de.steamwar.bungeecore.ArenaMode;
import de.steamwar.bungeecore.comms.SpigotHandler;
import de.steamwar.bungeecore.comms.packets.FightEndsPacket;
import de.steamwar.bungeecore.sql.SchemElo;
import de.steamwar.bungeecore.sql.SchematicNode;
import de.steamwar.bungeecore.sql.SchematicType;
import de.steamwar.bungeecore.sql.UserElo;
import net.md_5.bungee.api.config.ServerInfo;
import java.util.List;
public class FightEndsHandler implements SpigotHandler {
private int K = 20;
@Override
public void handle(ByteArrayDataInput in, ServerInfo info) {
FightEndsPacket fightEndsPacket = new FightEndsPacket(in);
if (!ArenaMode.getBySchemType(SchematicType.fromDB(fightEndsPacket.getGameMode())).isRanked()) {
return;
}
int bluePlayerSize = fightEndsPacket.getBluePlayers().size();
int redPlayerSize = fightEndsPacket.getRedPlayers().size();
double playerRatio = bluePlayerSize > redPlayerSize ? (double) redPlayerSize / bluePlayerSize : (double) bluePlayerSize / redPlayerSize;
if (playerRatio < 0.6) {
return;
}
boolean bluePublic = SchematicNode.getSchematicNode(fightEndsPacket.getBlueSchem()).getId() == 0;
boolean redPublic = SchematicNode.getSchematicNode(fightEndsPacket.getRedSchem()).getId() == 0;
if (bluePublic ^ redPublic) {
return;
}
double blueResult;
if (fightEndsPacket.getWin() == 0) {
blueResult = 0.5;
} else if (fightEndsPacket.getWin() == 1) {
blueResult = 1;
} else {
blueResult = 0;
}
int blueSchemElo = SchemElo.getElo(fightEndsPacket.getBlueSchem());
int redSchemElo = SchemElo.getElo(fightEndsPacket.getRedSchem());
calculateEloOfTeam(fightEndsPacket.getBlueSchem(), blueSchemElo, redSchemElo, blueResult, fightEndsPacket.getBluePlayers(), fightEndsPacket.getGameMode());
calculateEloOfTeam(fightEndsPacket.getRedSchem(), redSchemElo, blueSchemElo, 1 - blueResult, fightEndsPacket.getRedPlayers(), fightEndsPacket.getGameMode());
}
private void calculateEloOfTeam(int schemId, int eloOwn, int eloEnemy, double result, List<Integer> players, String gameMode) {
double winExpectation = 1 / (1 + Math.pow(10, (eloOwn - eloEnemy) / 600f));
SchemElo.setElo(schemId, (int) Math.round(eloOwn + K * (result - winExpectation)));
for (int player : players) {
int playerElo = UserElo.getEloOrDefault(player, gameMode);
UserElo.setElo(player, gameMode, (int) Math.round(playerElo + K * (result - winExpectation)));
}
}
}

Datei anzeigen

@ -23,10 +23,7 @@ import de.steamwar.bungeecore.*;
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
import de.steamwar.bungeecore.commands.TpCommand;
import de.steamwar.bungeecore.comms.packets.PingPacket;
import de.steamwar.bungeecore.sql.Punishment;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.bungeecore.sql.Team;
import de.steamwar.bungeecore.sql.UserGroup;
import de.steamwar.bungeecore.sql.*;
import net.md_5.bungee.api.*;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
@ -200,7 +197,7 @@ public class ChatListener extends BasicListener {
}
private void publicChat(SteamwarUser user, ProxiedPlayer sender, String message){
String name = sender.getDisplayName();
String name = UserElo.getEmblem(user) + sender.getDisplayName();
String chatcolor = user.getUserGroup().getChatColorCode();
if(user.getUserGroup() != UserGroup.Member || user.getTeam() == 12 || user.getTeam() == 285 || user.getTeam() == 54)

Datei anzeigen

@ -76,7 +76,7 @@ public class ConnectionListener extends BasicListener {
if(user.getUserGroup() != UserGroup.Member) {
player.setPermission(YOUTUBER_MODS, true);
player.setDisplayName(user.getUserGroup().getColorCode() + user.getUserGroup().name() + " " + player.getName() + "§r");
player.setDisplayName(user.getUserGroup().getColorCode() + user.getUserGroup().getChatPrefix() + " " + player.getName() + "§r");
player.setPermission("bungeecore.group." + user.getUserGroup().name().toLowerCase(), true);
}else {
player.setDisplayName(player.getName());

Datei anzeigen

@ -1,52 +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.sql;
public class 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, 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, season);
}
}

Datei anzeigen

@ -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 static de.steamwar.bungeecore.sql.UserElo.ELO_DEFAULT;
public class SchemElo {
private SchemElo() {}
private static final Statement elo = new Statement("SELECT Elo FROM SchemElo WHERE SchemID = ? AND Season = ?");
private static final Statement setElo = new Statement("UPDATE SchemElo SET Elo = ? WHERE Season = ? AND SchemID = ?");
public static int getElo(int schemID) {
return getElo(Season.getSeason(), schemID);
}
public static int getElo(int season, int schemID) {
return elo.select(rs -> {
if (rs.next())
return rs.getInt("Elo");
return ELO_DEFAULT;
}, schemID, season);
}
public static void setElo(int schemID, int elo) {
setElo(Season.getSeason(), schemID, elo);
}
public static void setElo(int season, int schemID, int elo) {
setElo.update(elo, season, schemID);
}
}

Datei anzeigen

@ -30,6 +30,11 @@ public class Season {
return (calendar.get(Calendar.YEAR) * 3 + yearIndex);
}
public static String getSeasonStart() {
Calendar calendar = Calendar.getInstance();
return calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) / 3 * 3 + 1) + "-1";
}
public static String convertSeasonToString(int season){
if (season == -1) return "";
int yearSeason = season % 3;

Datei anzeigen

@ -0,0 +1,142 @@
/*
* 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 de.steamwar.bungeecore.ArenaMode;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class UserElo {
private UserElo() {
}
public static final int ELO_DEFAULT = 1000;
private static final Map<String, Map<Integer, Optional<Integer>>> gameModeUserEloCache = new HashMap<>();
private static final Map<String, Integer> maxEloCache = new HashMap<>();
private static final Map<Integer, String> emblemCache = new HashMap<>();
private static final Statement elo = new Statement("SELECT Elo FROM UserElo WHERE UserID = ? AND GameMode = ? AND Season = ?");
private static final Statement setElo = new Statement("UPDATE UserElo SET Elo = ? WHERE Season = ? AND UserID = ? AND GameMode = ?");
private static final Statement place = new Statement("SELECT COUNT(*) AS Place FROM UserElo WHERE GameMode = ? AND Elo > ? AND Season = ?");
private static final Statement maxElo = new Statement("SELECT MAX(Elo) AS MaxElo FROM UserElo WHERE Season = ? AND GameMode = ?");
private static final Statement fightsOfSeason = new Statement("SELECT COUNT(*) AS Fights FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID WHERE UserID = ? AND GameMode = ? AND UNIX_TIMESTAMP(StartTime) + Duration >= UNIX_TIMESTAMP(?)");
public static int getEloOrDefault(int userID, String gameMode) {
return getElo(userID, gameMode).orElse(ELO_DEFAULT);
}
public static Optional<Integer> getElo(int userID, String gameMode) {
return gameModeUserEloCache.computeIfAbsent(gameMode, gm -> {
return new HashMap<>();
}).computeIfAbsent(userID, uid -> {
return elo.select(rs -> {
if (rs.next())
return Optional.of(rs.getInt("Elo"));
return Optional.empty();
}, userID, gameMode, Season.getSeason());
});
}
public static int getFightsOfSeason(int userID, String gameMode) {
return fightsOfSeason.select(rs -> {
if (rs.next())
return rs.getInt("Fights");
return 0;
}, userID, gameMode, Season.getSeasonStart());
}
public static int getMaxElo(String gameMode) {
return maxEloCache.computeIfAbsent(gameMode, gm -> {
return maxElo.select(rs -> {
if (rs.next())
return rs.getInt("MaxElo");
return 0;
}, Season.getSeason(), gameMode);
});
}
public static void setElo(int userId, String gameMode, int elo) {
emblemCache.remove(userId);
gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).put(userId, Optional.of(elo));
maxEloCache.compute(gameMode, (gm, max) -> {
if (max == null || max < elo) {
emblemCache.clear();
return elo;
}
return max;
});
setElo.update(elo, Season.getSeason(), userId, gameMode);
}
public static int getPlacement(int elo, String gameMode) {
return place.select(rs -> {
if (rs.next())
return rs.getInt("Place");
return -1;
}, gameMode, elo, Season.getSeason());
}
public static String getEmblem(SteamwarUser user) {
if (emblemCache.containsKey(user.getId())) {
return emblemCache.get(user.getId());
}
int maxEloOfPlayer = 0;
ArenaMode arenaMode = null;
for (ArenaMode mode : ArenaMode.getAllModes()) {
if (!mode.isRanked()) continue;
if (UserElo.getFightsOfSeason(user.getId(), mode.getSchemType()) < 10) continue;
Optional<Integer> currentElo = UserElo.getElo(user.getId(), mode.getSchemType());
if (currentElo.isPresent() && currentElo.get() > maxEloOfPlayer) {
maxEloOfPlayer = currentElo.get();
arenaMode = mode;
}
}
if (arenaMode == null) {
emblemCache.put(user.getId(), "");
return "";
}
int maxEloOfGameMode = UserElo.getMaxElo(arenaMode.getSchemType());
String emblem = getEmblem(maxEloOfPlayer, maxEloOfGameMode);
emblemCache.put(user.getId(), emblem);
return emblem;
}
private static String getEmblem(int maxEloOfPlayer, int maxEloOfGameMode) {
if (maxEloOfPlayer > maxEloOfGameMode * 0.99) return "§5❂ ";
if (maxEloOfPlayer > maxEloOfGameMode * 0.97) return "§c✹ ";
if (maxEloOfPlayer > maxEloOfGameMode * 0.94) return "§b✸ ";
if (maxEloOfPlayer > maxEloOfGameMode * 0.88) return "§a✷ ";
if (maxEloOfPlayer > maxEloOfGameMode * 0.76) return "§e✶ ";
if (maxEloOfPlayer > maxEloOfGameMode * 0.51) return "§f✦ ";
return "§7✧ ";
}
public static void clearCache() {
gameModeUserEloCache.clear();
maxEloCache.clear();
emblemCache.clear();
}
}

Datei anzeigen

@ -24,24 +24,26 @@ import java.util.stream.Collectors;
public enum UserGroup {
Admin("§4", "§e", true, true, true, true),
Developer("§3", "§f", true, true, true, true),
Moderator("§c", "§f", true, true, true, true),
Supporter("§9", "§f", false, true, true, true),
Builder("§2", "§f", false, true, false, true),
YouTuber("§5", "§f", false, false, false, true),
Member("§7", "§7", false, false, false, false);
Admin("§4", "§e", "Admin", true, true, true, true),
Developer("§3", "§f", "Dev", true, true, true, true),
Moderator("§c", "§f", "Mod", true, true, true, true),
Supporter("§9", "§f", "Sup", false, true, true, true),
Builder("§2", "§f", "Arch", false, true, false, true),
YouTuber("§5", "§f", "YT", false, false, false, true),
Member("§7", "§7", "", false, false, false, false);
private final String colorCode;
private final String chatColorCode;
private final String chatPrefix;
private final boolean adminGroup;
private final boolean teamGroup;
private final boolean checkSchematics;
private final boolean privilegedMods;
UserGroup(String colorCode, String chatColorCode, boolean adminGroup, boolean teamGroup, boolean checkSchematics, boolean privilegedMods) {
UserGroup(String colorCode, String chatColorCode, String chatPrefix, boolean adminGroup, boolean teamGroup, boolean checkSchematics, boolean privilegedMods) {
this.colorCode = colorCode;
this.chatColorCode = chatColorCode;
this.chatPrefix = chatPrefix;
this.adminGroup = adminGroup;
this.teamGroup = teamGroup;
this.checkSchematics = checkSchematics;
@ -75,4 +77,8 @@ public enum UserGroup {
public static UserGroup getUsergroup(String name) {
return Arrays.stream(UserGroup.values()).filter(userGroup -> userGroup.name().equalsIgnoreCase(name)).collect(Collectors.toList()).get(0);
}
public String getChatPrefix() {
return chatPrefix;
}
}