Dieser Commit ist enthalten in:
Commit
35bac7bbf7
@ -23,18 +23,29 @@ import com.google.common.io.ByteArrayDataInput;
|
|||||||
import de.steamwar.bungeecore.ArenaMode;
|
import de.steamwar.bungeecore.ArenaMode;
|
||||||
import de.steamwar.bungeecore.comms.SpigotHandler;
|
import de.steamwar.bungeecore.comms.SpigotHandler;
|
||||||
import de.steamwar.bungeecore.comms.packets.FightEndsPacket;
|
import de.steamwar.bungeecore.comms.packets.FightEndsPacket;
|
||||||
import de.steamwar.bungeecore.sql.SchemElo;
|
import de.steamwar.bungeecore.sql.*;
|
||||||
import de.steamwar.bungeecore.sql.SchematicNode;
|
import lombok.RequiredArgsConstructor;
|
||||||
import de.steamwar.bungeecore.sql.SchematicType;
|
|
||||||
import de.steamwar.bungeecore.sql.UserElo;
|
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class FightEndsHandler implements SpigotHandler {
|
public class FightEndsHandler implements SpigotHandler {
|
||||||
|
|
||||||
|
private Map<String, LinkedList<Game>> gameModeGames = new HashMap<>();
|
||||||
|
|
||||||
private int K = 20;
|
private int K = 20;
|
||||||
|
|
||||||
|
private long defaultFightRange = 1000 /* Milliseconds */ * 60 /* Seconds */ * 15L /* Minutes */;
|
||||||
|
private Map<String, Long> fightRanges = new HashMap<>();
|
||||||
|
private long defaultFightCount = 1;
|
||||||
|
private Map<String, Long> fightCounts = new HashMap<>();
|
||||||
|
|
||||||
|
{
|
||||||
|
fightRanges.put("miniwargear", 1000 /* Milliseconds */ * 60 /* Seconds */ * 30L /* Minutes */);
|
||||||
|
fightCounts.put("miniwargear", 3L);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(ByteArrayDataInput in, ServerInfo info) {
|
public void handle(ByteArrayDataInput in, ServerInfo info) {
|
||||||
FightEndsPacket fightEndsPacket = new FightEndsPacket(in);
|
FightEndsPacket fightEndsPacket = new FightEndsPacket(in);
|
||||||
@ -66,6 +77,23 @@ public class FightEndsHandler implements SpigotHandler {
|
|||||||
blueResult = 0;
|
blueResult = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Die nächsten Zeilen filtern ein Fight innerhalb eines Teams nicht gewertet wird, bzw auch wenn nur Teile beider Teams im
|
||||||
|
// gleichen Team sind dieser ungewertet ist.
|
||||||
|
Set<Integer> teamsIds = fightEndsPacket.getBluePlayers().stream().map(SteamwarUser::get).map(SteamwarUser::getTeam).collect(Collectors.toSet());
|
||||||
|
for (int redPlayer : fightEndsPacket.getRedPlayers()) {
|
||||||
|
if (teamsIds.contains(SteamwarUser.get(redPlayer).getTeam())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (teamComboExistedAlready(fightEndsPacket.getBluePlayers(), fightEndsPacket.getRedPlayers(), fightEndsPacket.getGameMode())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
gameModeGames.computeIfAbsent(fightEndsPacket.getGameMode(), s -> new LinkedList<>()).add(new Game(fightEndsPacket.getBluePlayers(), fightEndsPacket.getRedPlayers()));
|
||||||
|
}
|
||||||
|
|
||||||
int blueSchemElo = SchemElo.getElo(fightEndsPacket.getBlueSchem());
|
int blueSchemElo = SchemElo.getElo(fightEndsPacket.getBlueSchem());
|
||||||
int redSchemElo = SchemElo.getElo(fightEndsPacket.getRedSchem());
|
int redSchemElo = SchemElo.getElo(fightEndsPacket.getRedSchem());
|
||||||
|
|
||||||
@ -77,14 +105,55 @@ public class FightEndsHandler implements SpigotHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void calculateEloOfTeam(int schemId, int eloSchemOwn, int eloSchemEnemy, int eloTeamOwn, int eloTeamEnemy, double result, List<Integer> players, String gameMode, boolean noPlayerRank) {
|
private void calculateEloOfTeam(int schemId, int eloSchemOwn, int eloSchemEnemy, int eloTeamOwn, int eloTeamEnemy, double result, List<Integer> players, String gameMode, boolean noPlayerRank) {
|
||||||
double winSchemExpectation = 1 / (1 + Math.pow(10, (eloSchemEnemy - eloSchemOwn) / 600f));
|
double winSchemExpectation = calsWinExpectation(eloSchemOwn, eloSchemEnemy);
|
||||||
SchemElo.setElo(schemId, (int) Math.round(eloSchemOwn + K * (result - winSchemExpectation)));
|
SchemElo.setElo(schemId, (int) Math.round(eloSchemOwn + K * (result - winSchemExpectation)));
|
||||||
|
|
||||||
if (noPlayerRank) return;
|
if (noPlayerRank) return;
|
||||||
double winTeamExpectation = 1 / (1 + Math.pow(10, (eloTeamEnemy - eloTeamOwn) / 600f));
|
double winTeamExpectation = calsWinExpectation(eloTeamOwn, eloTeamEnemy);
|
||||||
for (int player : players) {
|
for (int player : players) {
|
||||||
int playerElo = UserElo.getEloOrDefault(player, gameMode);
|
int playerElo = UserElo.getEloOrDefault(player, gameMode);
|
||||||
UserElo.setElo(player, gameMode, (int) Math.round(playerElo + K * (result - winTeamExpectation)));
|
int fights = UserElo.getFightsOfSeason(player, gameMode);
|
||||||
|
UserElo.setElo(player, gameMode, (int) Math.round(playerElo + getK(fights) * (result - winTeamExpectation)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calsWinExpectation(int eloOwn, int eloEnemy) {
|
||||||
|
return 1 / (1 + Math.pow(10, (eloEnemy - eloOwn) / 600f));
|
||||||
|
}
|
||||||
|
|
||||||
|
private double getK(int fights) {
|
||||||
|
return K * Math.max(1.3 - (fights / 200.0), 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean teamComboExistedAlready(List<Integer> bluePlayers, List<Integer> redPlayers, String gameMode) {
|
||||||
|
if (!gameModeGames.containsKey(gameMode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LinkedList<Game> games = gameModeGames.get(gameMode);
|
||||||
|
long lifetime = fightRanges.getOrDefault(gameMode, defaultFightRange);
|
||||||
|
while (!games.isEmpty()) {
|
||||||
|
Game game = games.getFirst();
|
||||||
|
if (game.livedMillis() > lifetime) {
|
||||||
|
games.removeFirst();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return games.stream().filter(game -> game.isSame(bluePlayers, redPlayers)).count() > fightCounts.getOrDefault(gameMode, defaultFightCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
private static class Game {
|
||||||
|
private long time = System.currentTimeMillis();
|
||||||
|
private final List<Integer> bluePlayers;
|
||||||
|
private final List<Integer> redPlayers;
|
||||||
|
|
||||||
|
public long livedMillis() {
|
||||||
|
return System.currentTimeMillis() - time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSame(List<Integer> bluePlayers, List<Integer> redPlayers) {
|
||||||
|
return bluePlayers.containsAll(this.bluePlayers) && redPlayers.containsAll(this.redPlayers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,6 @@ import net.md_5.bungee.event.EventHandler;
|
|||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.charset.UnsupportedCharsetException;
|
import java.nio.charset.UnsupportedCharsetException;
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -48,9 +46,6 @@ public class Fabric extends BasicListener {
|
|||||||
|
|
||||||
private final Set<String> neededMods = new HashSet<>();
|
private final Set<String> neededMods = new HashSet<>();
|
||||||
|
|
||||||
public static final Map<ProxiedPlayer, Integer> checkedPlayers = new HashMap<>();
|
|
||||||
private static final Map<ProxiedPlayer, Long> expectPluginMessage = new HashMap<>();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
neededMods.add("java");
|
neededMods.add("java");
|
||||||
neededMods.add("minecraft");
|
neededMods.add("minecraft");
|
||||||
@ -58,9 +53,9 @@ public class Fabric extends BasicListener {
|
|||||||
neededMods.add("steamwarmodsender");
|
neededMods.add("steamwarmodsender");
|
||||||
|
|
||||||
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
||||||
synchronized (expectPluginMessage) {
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
for (Map.Entry<ProxiedPlayer, Long> entry : expectPluginMessage.entrySet()) {
|
for (Map.Entry<ProxiedPlayer, Long> entry : Storage.fabricExpectPluginMessage.entrySet()) {
|
||||||
if (!checkedPlayers.containsKey(entry.getKey())) {
|
if (!Storage.fabricCheckedPlayers.containsKey(entry.getKey())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (System.currentTimeMillis() - entry.getValue() > TimeUnit.SECONDS.toMillis(20)) {
|
if (System.currentTimeMillis() - entry.getValue() > TimeUnit.SECONDS.toMillis(20)) {
|
||||||
@ -84,15 +79,15 @@ public class Fabric extends BasicListener {
|
|||||||
ProxiedPlayer player = (ProxiedPlayer) e.getSender();
|
ProxiedPlayer player = (ProxiedPlayer) e.getSender();
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
|
|
||||||
if (!checkedPlayers.containsKey(player)) {
|
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
||||||
synchronized (expectPluginMessage) {
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
if (expectPluginMessage.containsKey(player)) {
|
if (Storage.fabricExpectPluginMessage.containsKey(player)) {
|
||||||
banPlayer(user, player);
|
banPlayer(user, player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expectPluginMessage.remove(player);
|
Storage.fabricExpectPluginMessage.remove(player);
|
||||||
|
|
||||||
List<Mod> mods = new LinkedList<>();
|
List<Mod> mods = new LinkedList<>();
|
||||||
|
|
||||||
@ -141,15 +136,15 @@ public class Fabric extends BasicListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(Utils.handleMods(player,mods)) {
|
if(Utils.handleMods(player,mods)) {
|
||||||
if (checkedPlayers.containsKey(player)) {
|
if (Storage.fabricCheckedPlayers.containsKey(player)) {
|
||||||
long current = checkedPlayers.get(player);
|
long current = Storage.fabricCheckedPlayers.get(player);
|
||||||
if (current != dataString.hashCode()) {
|
if (current != dataString.hashCode()) {
|
||||||
banPlayer(user, player);
|
banPlayer(user, player);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Message.send("MODIFICATION_CHECK_SUCCESS", player);
|
Message.send("MODIFICATION_CHECK_SUCCESS", player);
|
||||||
checkedPlayers.put(player, dataString.hashCode());
|
Storage.fabricCheckedPlayers.put(player, dataString.hashCode());
|
||||||
}
|
}
|
||||||
Storage.fabricPlayers.remove(player);
|
Storage.fabricPlayers.remove(player);
|
||||||
}
|
}
|
||||||
@ -158,8 +153,8 @@ public class Fabric extends BasicListener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onServerSwitchEvent(ServerSwitchEvent e) {
|
public void onServerSwitchEvent(ServerSwitchEvent e) {
|
||||||
if (e.getFrom() == null) return;
|
if (e.getFrom() == null) return;
|
||||||
synchronized (expectPluginMessage) {
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
expectPluginMessage.put(e.getPlayer(), System.currentTimeMillis());
|
Storage.fabricExpectPluginMessage.put(e.getPlayer(), System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,9 +184,9 @@ public class Fabric extends BasicListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void remove(ProxiedPlayer player) {
|
public static void remove(ProxiedPlayer player) {
|
||||||
checkedPlayers.remove(player);
|
Storage.fabricCheckedPlayers.remove(player);
|
||||||
synchronized (expectPluginMessage) {
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
expectPluginMessage.remove(player);
|
Storage.fabricExpectPluginMessage.remove(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class ModLoaderBlocker extends BasicListener {
|
|||||||
|
|
||||||
if(new String(e.getData()).contains("fabric")){
|
if(new String(e.getData()).contains("fabric")){
|
||||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
ProxiedPlayer p = (ProxiedPlayer) sender;
|
||||||
if (!Fabric.checkedPlayers.containsKey(p) && !Storage.fabricPlayers.contains(p)) {
|
if (!Storage.fabricCheckedPlayers.containsKey(p) && !Storage.fabricPlayers.contains(p)) {
|
||||||
Storage.fabricPlayers.add(p);
|
Storage.fabricPlayers.add(p);
|
||||||
Message.send("MODLOADER_INSTALLED_FABRIC", p, "Fabric");
|
Message.send("MODLOADER_INSTALLED_FABRIC", p, "Fabric");
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class Fight {
|
public class Fight {
|
||||||
|
|
||||||
private static final Statement getPage = new Statement("SELECT f.FightID, f.GameMode, f.Server, f.StartTime, f.BlueLeader, f.RedLeader, (b.NodeId IS NULL OR b.AllowReplay) AND (r.NodeId IS NULL OR r.AllowReplay) AS ReplayAllowed, f.Win, f.Replay IS NOT NULL AS ReplayExists FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId ORDER BY FightID DESC LIMIT ?, ?");
|
private static final Statement getPage = new Statement("SELECT f.FightID, f.GameMode, f.Server, f.StartTime, f.BlueLeader, f.RedLeader, (b.NodeId IS NULL OR b.AllowReplay) AND (r.NodeId IS NULL OR r.AllowReplay) AS ReplayAllowed, f.Win, (SELECT COUNT(1) FROM Replay WHERE Replay.FightID = f.FightID) as ReplayAvailable FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId ORDER BY FightID DESC LIMIT ?, ?");
|
||||||
|
|
||||||
private final int fightID;
|
private final int fightID;
|
||||||
private final String gameMode;
|
private final String gameMode;
|
||||||
@ -22,8 +22,8 @@ public class Fight {
|
|||||||
private final int redLeader;
|
private final int redLeader;
|
||||||
private final int win;
|
private final int win;
|
||||||
|
|
||||||
private final boolean replayExists;
|
|
||||||
private final boolean replayAllowed;
|
private final boolean replayAllowed;
|
||||||
|
private final boolean replayAvailable;
|
||||||
|
|
||||||
private final List<FightPlayer> bluePlayers = new ArrayList<>();
|
private final List<FightPlayer> bluePlayers = new ArrayList<>();
|
||||||
private final List<FightPlayer> redPlayers = new ArrayList<>();
|
private final List<FightPlayer> redPlayers = new ArrayList<>();
|
||||||
@ -36,8 +36,8 @@ public class Fight {
|
|||||||
blueLeader = rs.getInt("BlueLeader");
|
blueLeader = rs.getInt("BlueLeader");
|
||||||
redLeader = rs.getInt("RedLeader");
|
redLeader = rs.getInt("RedLeader");
|
||||||
replayAllowed = rs.getBoolean("ReplayAllowed");
|
replayAllowed = rs.getBoolean("ReplayAllowed");
|
||||||
|
replayAvailable = rs.getBoolean("ReplayAvailable");
|
||||||
win = rs.getInt("Win");
|
win = rs.getInt("Win");
|
||||||
replayExists = rs.getBoolean("ReplayExists");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initPlayers(List<FightPlayer> fightPlayers) {
|
private void initPlayers(List<FightPlayer> fightPlayers) {
|
||||||
@ -118,6 +118,6 @@ public class Fight {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean replayExists() {
|
public boolean replayExists() {
|
||||||
return replayExists && getGameMode() != null;
|
return getGameMode() != null && replayAvailable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ public class UserElo {
|
|||||||
}, userID, gameMode, Season.getSeason()));
|
}, userID, gameMode, Season.getSeason()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getFightsOfSeason(int userID, String gameMode) {
|
public static int getFightsOfSeason(int userID, String gameMode) {
|
||||||
return fightsOfSeason.select(rs -> {
|
return fightsOfSeason.select(rs -> {
|
||||||
if (rs.next())
|
if (rs.next())
|
||||||
return rs.getInt("Fights");
|
return rs.getInt("Fights");
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren