Scoreboard updaten Spigot?
Moin!
Ich habe folgendes Problem:
Ich weiß nicht, wie ich das Scoreboard update.
Habe schon etwas im Internet recherchiert, aber nichts gefunden.
Der Code: https://pastebin.com/tXTae87Z
Außerdem, was ich genauso nicht verstehe ist:
- warum er den DisplayName nicht dick gedruckt anzeigt
- warum er bei getScore(6); keine freie Zeile lässt (siehe Bild)
Ich möchte auch noch Top 5 Kills demnächst hinzufügen.
Würde mich auf Hilfe freuen! :)
*bin übrigens ein Anfänger, was programmieren angeht! :)
1 Antwort
Hallo, gibt mehrere Möglichkeiten das ganze zu updaten.
Aber erstmal zu den kleinen Problemen:
- Fett: Farbcodes müssen IMMER vor Text-Edit-Codes stehen. Wenn du zuvor §l sagst und danach die Farbe änderst, wird §l überschrieben. Mach es also §3§l und nicht §l§3.
- Leerzeile: Gleiche Zeilen werden gelöscht. Daher bietet es sich an immer einen anderen Farbcode ohne Text in den String zu schreiben, dann ist die Zeile nicht mehr gleich, wird aber leer angezeigt.
Zu dem eigentlichen Problem/Frage:
Es gibt mehrere Möglichkeiten. Für deine Methode, die du verwendest, gibt es aber glaube ich nur eine: Das Scoreboard immer wieder neu setzten. Nachteil: Es flackert.
Am besten wäre es, wenn du alle Zeilen, die geupdatet werden sollen, ein sogenanntes Team erstellst. Dort einfach den Prefix und/oder Suffix setzen und dann in einer updateScoreboard-Methode erneut setzen.
Dass die updateScoreboard-Methode etwa so aussieht:
public static void updateScoreBoard(Player player) throws SQLException{
Scoreboard board = player.getScoreboard();
board.getTeam("coins").setPrefix("§7» §6" + SQLStats.getCoins(player.getUniqueId().toString()));
}
Hab das mal aus meinem System genommen für das Team "coins". Hier noch der Aufbau eines Teams:
Team coins = board.registerNewTeam("coins");
coins.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
coins.setPrefix("§7» §6" + SQLStats.getCoins(player.getUniqueId().toString()));
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(12);
Wenn du noch Fragen hast, kannst du sie mir gerne schreiben,
LG
Ja gut. Ich schick dir hier nochmal eine allgemeine Methode rein, ich hab das jetzt aus meinem Lobbysystem übernommen. Bei dir gibts natürlich keine SQLStats Methode.
public static void updateScoreBoard(Player player) {
Scoreboard board = player.getScoreboard();
board.getTeam("DeinTeam").setPrefix(DeinPrefix);
}
Und hier der Setter:
Team TeamName = board.registerNewTeam("TeamName");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix(DeinPrefix);
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(12);
@EventHandler
public void join(PlayerJoinEvent event) {
Player player = event.getPlayer ();
Scoreboard board = (Scoreboard) Bukkit.getScoreboardManager().getNewScoreboard();
Objective obj = ((org.bukkit.scoreboard.Scoreboard) board).registerNewObjective("1111", "1112");
Team user = board.registerNewTeam("user");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("§3§lPlaceholder Title");
obj.getScore("§2").setScore(6);
obj.getScore("§l§3Kills").setScore(5);
obj.getScore("§b" + player.getStatistic(Statistic.PLAYER_KILLS)).setScore(4);
obj.getScore("§1").setScore(3);
obj.getScore("§l§3Online").setScore(2);
obj.getScore("" + Bukkit.getOnlinePlayers().size()).setScore(1);
player.setScoreboard(board);
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix("Test");
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(12);
}
public static void updateScoreBoard(Player player) {
Scoreboard board = player.getScoreboard();
board.getTeam("user").setPrefix("Team");
}
so sieht es aktuell aus. Weiß leider nicht, was ein Setter ist :)
Mir ist gerade kein anderes Wort eingefallen. Ich mein damit, dass das der Code ist, um das Team ins Scoreboard zu setzen. Aber du hast es schon richtig gemacht. Damit du auch siehst, dass es geupdatet wird, solltest du einen Prefix setzen, der sich immer wieder verändert. Und du musst noch die updateScoreboard-Methode aufrufen.
Wie soll ich ein Prefix machen, dass sich immer verändert ? :D Und wie kann ich es aufrufen? Tut mir leid, bin da wirklich neu. Habe nur Join / Leave Messages, Prefix und BanOnDeath programmiert :P
Alles gut. Naja, wie du einen sich ändernen Prefix machst, weiß ich nicht. Das hängt, wie gesagt, davon ab, was im Scoreboard sein soll. zum Beispiel Bukkit.getOnlinePlayers().size(). Der Integer würde ich immer ändern, wenn ein Spieler joint.
Aufrufen tust du es in einer anderen Klasse oder Methode mit KlassenName#updateScoreboard(player); . Achso, was ich vergessen hab, mach mal die updateScoreboard-Methode static, dann kannst du diese auch in anderen Klassen aufrufen.
@EventHandler
public void join(PlayerJoinEvent event) {
Player player = event.getPlayer ();
Scoreboard board = (Scoreboard) Bukkit.getScoreboardManager().getNewScoreboard();
Objective obj = ((org.bukkit.scoreboard.Scoreboard) board).registerNewObjective("1111", "1112");
Ich bin leicht verwirrt. Die updateScoreboard-Methode ist ja schon static. Aber, irgendwie funktioniert das nicht xd
Team user = board.registerNewTeam("user");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("§3§lPlaceholder Title");
obj.getScore("§2").setScore(6);
obj.getScore("§l§3Kills").setScore(5);
obj.getScore("§b" + player.getStatistic(Statistic.PLAYER_KILLS)).setScore(4);
obj.getScore("§1").setScore(3);
obj.getScore("§l§3Online").setScore(2);
obj.getScore("" + Bukkit.getOnlinePlayers().size()).setScore(1);
player.setScoreboard(board);
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix("Test");
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(12);
updateScoreBoard(player);
}
public static void updateScoreBoard (Player player) {
Scoreboard board = player.getScoreboard();
board.getTeam("user").setPrefix("Team");
}
Ah ja.. Tut mir leid, bin gerade echt durcheinander. Also.
Die Methode ist schon static, ist auch oke so. Was du jetzt statt updateScoreboard(player); machen kannst, ist das:
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreboard(all);
}
Damit wird nochmal für jeden Spieler, der gerade online ist, das Scoreboard geupdatet, wenn jemand joint.
LG
So sieht es jetzt aus:
public void join(PlayerJoinEvent event) {
Player player = event.getPlayer ();
Scoreboard board = (Scoreboard) Bukkit.getScoreboardManager().getNewScoreboard();
Objective obj = ((org.bukkit.scoreboard.Scoreboard) board).registerNewObjective("1111", "1112");
Team user = board.registerNewTeam("user");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("§3§lPlaceholder Title");
obj.getScore("§2").setScore(6);
obj.getScore("§l§3Kills").setScore(5);
obj.getScore("§b" + player.getStatistic(Statistic.PLAYER_KILLS)).setScore(4);
obj.getScore("§1").setScore(3);
obj.getScore("§l§3Online").setScore(2);
obj.getScore("" + Bukkit.getOnlinePlayers().size()).setScore(1);
player.setScoreboard(board);
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix("Test");
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(12);
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreBoard(all);
}
}
public static void updateScoreBoard (Player player) {
Scoreboard board = player.getScoreboard();
board.getTeam("user").setPrefix("Team");
}
Funktionieren tut es aber noch nicht.
Das hier wird auch nicht genutzt:
Team user = board.registerNewTeam("user");
Dann lösch mal die Zeile. Ich weiß nicht, warum die da steht. Die wird nirgendwo gebraucht.
Und was ich gerade noch sehe: Das Team TeamName..., also der 4-Zeilen-Block muss über das .setScoreboard. Das gehört ja noch mit dazu.
Dann sollte es eigentlich gehen.
Leider immer noch nicht.
@EventHandler
public void join(PlayerJoinEvent event) {
Player player = event.getPlayer ();
Scoreboard board = (Scoreboard) Bukkit.getScoreboardManager().getNewScoreboard();
Objective obj = ((org.bukkit.scoreboard.Scoreboard) board).registerNewObjective("1111", "1112");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("§3§lPlaceholder Title");
obj.getScore("§2").setScore(6);
obj.getScore("§l§3Kills").setScore(5);
obj.getScore("§b" + player.getStatistic(Statistic.PLAYER_KILLS)).setScore(4);
obj.getScore("§1").setScore(3);
obj.getScore("§l§3Online").setScore(2);
obj.getScore("" + Bukkit.getOnlinePlayers().size()).setScore(1);
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix("Test");
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(12);
player.setScoreboard(board);
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreBoard(all);
}
}
public static void updateScoreBoard (Player player) {
Scoreboard board = player.getScoreboard();
board.getTeam("user").setPrefix("Team");
}
Das kann ich ja entfernen, oder?
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(12);
So sieht es jetzt aus -> http://prntscr.com/rdcxe4
Ich weiß echt nicht, warum es nicht geht
Stimmt. Er zeigt dort jetzt Team an
Naja. Es geht doch. Jedenfalls so, wie es der Code sagt. Jetzt musst du noch in der letzten Zeile vom 4er-Block den Score ändern und ggf. einen anderen Prefix (Text) setzen. z.B. Bukkit.getOnlinePlayers().size().
Also, ich habe nun oberhalb den setScore(1) gelöscht, bzw. unten wo "Team" war ersetzt. Leider funktioniert es immer noch nicht
@EventHandler
public void join(PlayerJoinEvent event) {
Player player = event.getPlayer ();
Scoreboard board = (Scoreboard) Bukkit.getScoreboardManager().getNewScoreboard();
Objective obj = ((org.bukkit.scoreboard.Scoreboard) board).registerNewObjective("1111", "1112");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("§3§lPlaceholder Title");
obj.getScore("§2").setScore(6);
obj.getScore("§l§3Kills").setScore(5);
obj.getScore("§b" + player.getStatistic(Statistic.PLAYER_KILLS)).setScore(4);
obj.getScore("§1").setScore(3);
obj.getScore("§l§3Online").setScore(2);
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix("Team1");
obj.getScore("§b" + Bukkit.getOnlinePlayers().size()).setScore(1);
player.setScoreboard(board);
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreBoard(all);
}
}
public static void updateScoreBoard (Player player) {
Scoreboard board = player.getScoreboard();
board.getTeam("user").setPrefix("Team");
}
Öhh was hast du denn da jetz gemacht? Ehmm mach das nochmal rückgängig. Bei Teams ist es so: Den Zeileninhalt setzt man über Prefix & Suffix, wie es oben schon irgendwo steht. In der letzten Zeile müssten 2x ChatColor und einmal "" stehen, so wie du es zuvor hattest. Wenn du Bukkit.getOnlinePlayers().size() nutzen willst, dann pack es bitte in die Klammer von team#setPrefix. Vergiss bitte auch nicht, dass du es im updateScoreboard ebenfalls einsetzen musst, sonst wird es sofort überschrieben.
Achso.. Jetzt habe ich es verstanden! Vielen Dank. Ich verstehe zwar noch nicht ganz, wie genau es funktioniert bzw. warum ich das genauso schreiben muss, aber es klappt. Jetzt besteht nur noch das Problem, dass er aber nicht aktualisiert, wenn ich den Server verlasse. Da dachte ich mir, da ja das ganze in einem PlayerJoinEvent geschrieben ist, dass ich einfach genau das gleiche mache (siehe Code) nur mit einem PlayerQuitEvent. Funzt aber nicht
@EventHandler
public void join(PlayerJoinEvent event) {
Player player = event.getPlayer ();
Scoreboard board = (Scoreboard) Bukkit.getScoreboardManager().getNewScoreboard();
Objective obj = ((org.bukkit.scoreboard.Scoreboard) board).registerNewObjective("1111", "1112");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("§3§lPlaceholder Title");
obj.getScore("§2").setScore(6);
obj.getScore("§l§3Kills").setScore(5);
obj.getScore("§b" + player.getStatistic(Statistic.PLAYER_KILLS)).setScore(4);
obj.getScore("§1").setScore(3);
obj.getScore("§l§3Online").setScore(2);
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix(""+ Bukkit.getOnlinePlayers().size());
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(1);
player.setScoreboard(board);
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreBoard(all);
}
}
@EventHandler
public void quit(PlayerQuitEvent event) {
Player player = event.getPlayer ();
Scoreboard board = (Scoreboard) Bukkit.getScoreboardManager().getNewScoreboard();
Objective obj = ((org.bukkit.scoreboard.Scoreboard) board).registerNewObjective("1111", "1112");
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix(""+ Bukkit.getOnlinePlayers().size());
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(1);
player.setScoreboard(board);
}
public static void updateScoreBoard (Player player) {
Scoreboard board = player.getScoreboard();
board.getTeam("user").setPrefix(""+ Bukkit.getOnlinePlayers().size());
}
Hatte das vergessen:
for(Player all : Bukkit.getOnlinePlayers()) {
updateScoreBoard(all);
funktioniert aber nicht
Hmm nein, das brauchst du nicht. Im OnQuit einfach nur wieder die For-Schleife wie im onJoin einfügen:
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreboard(all);
}
Und was genau verstehst du daran nicht, wie es geschrieben wird/es funktioniert? Dann kann ich dir es auch noch kurz erklären.
Ach egal, ich mach das hier einfach kurz:
Also. Der Block für die eine Zeile besteht eben aus 4 Zeilen, wie du es bereits gesehen hast:
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix(""+ Bukkit.getOnlinePlayers().size());
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(1);
Die erste Zeile:
Team TeamName = board.registerNewTeam("user");
Diese registriert ein Team bei dem Scoreboard mit dem Namen "user".
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
Legt einen Entry fest, also, dass die Zeile angezeigt werden soll.. Weiß nicht genau, wie ich addEntry erklären kann..
TeamName.setPrefix(""+ Bukkit.getOnlinePlayers().size());
Setzt den Inhalt/Prefix des Teams und somit der Zeile
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(1);
Das Objective setzt eine neue Zeile mit genau dem Platzhalter sozusagen, den du bei addEntry erstellt hast. Dort muss also exakt das gleiche stehen, wie in der Klammer von addEntry() es steht.
board.getTeam("user").setPrefix(""+ Bukkit.getOnlinePlayers().size());
(Steht im updateScoreboard) Holt sich das Team vom Scoreboard und setzt den Prefix neu.
Noch eine Info: Wenn du mehrere Teams erstellen willst/mehrere Zeilen, die sich updaten, kannst du das genau so machen, jedoch musst du bei registerNewTeam() den Namen ändern und bei addEntry/getScore mindestens eine ChatColor ändern. Sonst haben wir wieder das Problem, dass sich die Zeilen wegen gleichem Entry überschreiben.
Danke! Auf die Erklärung gehe ich gleich ein.
OnQuit funktioniert nicht.
}
@EventHandler
public void join(PlayerJoinEvent event) {
Player player = event.getPlayer ();
Scoreboard board = (Scoreboard) Bukkit.getScoreboardManager().getNewScoreboard();
Objective obj = ((org.bukkit.scoreboard.Scoreboard) board).registerNewObjective("1111", "1112");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("§3§lPlaceholder Title");
obj.getScore("§2").setScore(6);
obj.getScore("§l§3Kills").setScore(5);
obj.getScore("§b" + player.getStatistic(Statistic.PLAYER_KILLS)).setScore(4);
obj.getScore("§1").setScore(3);
obj.getScore("§l§3Online").setScore(2);
obj.getScore("" + Bukkit.getOnlinePlayers().size()).setScore(1);
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix(""+ Bukkit.getOnlinePlayers().size());
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(1);
player.setScoreboard(board);
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreboard(all);
}
}
@EventHandler
public void quit(PlayerQuitEvent event) {
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreboard(all);
}
}
public static void updateScoreboard (Player player) {
Scoreboard board = player.getScoreboard();
board.getTeam("user").setPrefix(""+ Bukkit.getOnlinePlayers().size());
}
Danke für deine Mühe und die Erklärung! Ist echt hilfreich. Ich habe mit Vanilla Scoreboards / Teams nie wirklich gearbeitet. Muss bei TeamName.addEntry die ChatColors stehen?
Nein, muss nicht. Du kannst da auch theoretisch Text hinschreiben, macht man aber nicht. Dieser Text wird dann nämlich trotzdem im Scoreboard angezeigt.
Daher sind ChatColors schon ganz praktisch.
Hmm und wegen dem Quit. Kommen da Fehler? Weil logisch siehts schon aus..
http://prntscr.com/rddgd0 - Negativ, kein Fehler :/
Achso, meinte jetzt eher im Log.. Du hast die neue Version drauf und den Server neugestartet? Weil das sollte eigentlich gehen..
Funzt nach Neustart immer noch nicht
Prüfe mal, ob der Listener überhaupt aufgerufen wird. z.B. durch eine Message an alle Online-Spieler.
Also einfach in die for-schleife all.sendMessage("..."); packen.
Wie vorgeschlagen? Du solltest das Ingame testen, ob die Nachricht überhaupt kommt. Wie kann da was vorgeschlagen werden?
Achso.. Ich meine, in Eclipse wird mir all.sendMessage vorgeschlagen
Jap. Die Message wird geschickt, allerdings 2x
Ja, 2x ist okay. Hauptsache sie kommt. Hmm ist aber sehr seltsam, dass sich das Board nicht updatet...
Ich muss dazu sagen, dass ich noch andere Sachen in der class habe, wie Join / Leave Messages. Wenn ich eine neue class mache, erkennt er die aber nicht. Ich muss die ja glaube in der Main irgendwie verlinken, ich weiß aber nicht wie :P
Ich werde da später mal nach schauen.
Das ist mein aktueller Code:
@EventHandler
public void join(PlayerJoinEvent event) {
Player player = event.getPlayer ();
Scoreboard board = (Scoreboard) Bukkit.getScoreboardManager().getNewScoreboard();
Objective obj = ((org.bukkit.scoreboard.Scoreboard) board).registerNewObjective("1111", "1112");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
obj.setDisplayName("§3§lPlaceholder Title");
obj.getScore("§2").setScore(6);
obj.getScore("§l§3Kills").setScore(5);
obj.getScore("§b" + player.getStatistic(Statistic.PLAYER_KILLS)).setScore(4);
obj.getScore("§1").setScore(3);
obj.getScore("§l§3Online").setScore(2);
Team TeamName = board.registerNewTeam("user");
TeamName.addEntry(ChatColor.BLACK + "" + ChatColor.WHITE);
TeamName.setPrefix(""+ Bukkit.getOnlinePlayers().size () + "§7/" + "§b12");
obj.getScore(ChatColor.BLACK + "" + ChatColor.WHITE).setScore(1);
player.setScoreboard(board);
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreboard(all);
}
}
@EventHandler
public void quit(PlayerQuitEvent event) {
for(Player all : Bukkit.getOnlinePlayers()){
updateScoreboard(all);
all.sendMessage("§csendMessage");
}
}
public static void updateScoreboard (Player player) {
Scoreboard board = player.getScoreboard();
board.getTeam("user").setPrefix("§b"+ Bukkit.getOnlinePlayers().size () + "§7/" + "§b12");
}
Danke! 1. und 2. hat schon mal funktioniert.
Beim updateScoreboard-Methode wird bei mir "SQLStats.getCoins" rot unterstrichen