SteamWar/BungeeCore
Archiviert
13
2

Ranked #333

Zusammengeführt
Lixfel hat 18 Commits von Ranked nach master 2022-04-11 08:23:14 +02:00 zusammengeführt
2 geänderte Dateien mit 78 neuen und 9 gelöschten Zeilen

Datei anzeigen

@ -23,18 +23,29 @@ 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 de.steamwar.bungeecore.sql.*;
import lombok.RequiredArgsConstructor;
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 {
private Map<String, LinkedList<Game>> gameModeGames = new HashMap<>();
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);
}
Lixfel markierte diese Unterhaltung als gelöst Veraltet
Veraltet
Review

Du musst das Processing in einen Task auslagern (dauert zu lange, insbesondere mit dem ganzen Fight-Gedöns).

Du musst das Processing in einen Task auslagern (dauert zu lange, insbesondere mit dem ganzen Fight-Gedöns).
Veraltet
Review

Machst du das nicht seit dem DB update (da dispatched du doch auch die plugin messages async)

Machst du das nicht seit dem DB update (da dispatched du doch auch die plugin messages async)
@Override
public void handle(ByteArrayDataInput in, ServerInfo info) {
FightEndsPacket fightEndsPacket = new FightEndsPacket(in);
@ -66,6 +77,23 @@ public class FightEndsHandler implements SpigotHandler {
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;
}
}
YoyoNow markierte diese Unterhaltung als gelöst Veraltet
Veraltet
Review

Da hier häufig Einträge zu Beginn der Liste entfernt werden, wäre eine LinkedList wahrscheinlich die bessere Datenstruktur

Da hier häufig Einträge zu Beginn der Liste entfernt werden, wäre eine LinkedList wahrscheinlich die bessere Datenstruktur
Veraltet
Review

Das removeIf sollte ich dann aber auch noch einmal optimieren, weil ich ja die Reihenfolge kenne. Und damit nur immer über den Anfang der List drüber gehen muss.

Das removeIf sollte ich dann aber auch noch einmal optimieren, weil ich ja die Reihenfolge kenne. Und damit nur immer über den Anfang der List drüber gehen muss.
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 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) {
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)));
if (noPlayerRank) return;
double winTeamExpectation = 1 / (1 + Math.pow(10, (eloTeamEnemy - eloTeamOwn) / 600f));
double winTeamExpectation = calsWinExpectation(eloTeamOwn, eloTeamEnemy);
for (int player : players) {
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) {
Lixfel markierte diese Unterhaltung als gelöst Veraltet
Veraltet
Review

Du dürftest hier möglicherweise (Concurrency) auch den eigenen Fight zurückbekommen...

Du dürftest hier möglicherweise (Concurrency) auch den eigenen Fight zurückbekommen...
Veraltet
Review

Wie kann ich das verhindern bzw rausfiltern?

Wie kann ich das verhindern bzw rausfiltern?
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);
YoyoNow markierte diese Unterhaltung als gelöst Veraltet
Veraltet
Review

Hier bitte stattdessen verunden.

Hier bitte stattdessen verunden.
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);
}
}
}

Datei anzeigen

@ -56,7 +56,7 @@ public class UserElo {
}, userID, gameMode, Season.getSeason()));
}
private static int getFightsOfSeason(int userID, String gameMode) {
public static int getFightsOfSeason(int userID, String gameMode) {
return fightsOfSeason.select(rs -> {
if (rs.next())
return rs.getInt("Fights");