Jump to content

[Events] Chat Nachrichten speichern


Empfohlene Beiträge

Moin,

Ich möchte wenn eine bestimmte Zeichen und Buchstabenreihenfolge im Chat eingegeben wird. Dies Nachricht gespeichert wird. Zum Beispiel: schreibt man Wieviele Slots hat der Server #frage wird diese Nachricht in der Config gespeichert.

Dies könnte man doch durch das PlayerChatEvent machen? oder?

Und wenn! wie? :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also das PlayerChatEvent ist Deprecated, also veraltet. Das liegt daran, dass das AsyncPlayerChatEvent eingeführt wurde. Und damit lässt sich das machen. Hier der Code:

ArrayList<String> messages = new ArrayList<>();String word = "Hier gesuchte Zeichenfolge eingeben";@EventHandlerpublic void onPlayerChat(AsyncPlayerChatEvent e) {	String message = e.getMessage();	if (message.contains(word)) messages.add(message);}

Viel Spaß damit ;) Wenn du noch weitere Hilfe benötigst, so bin ich entweder hier im Forum, oder auf Skype (Minecraftforum.de) erreichbar! Wenn ich dir geholfen habe, so würde ich mich sehr darüber freuen, wenn du das mit einem "Gefällt mir" am unteren rechten Beitragsrand honorierst! :)

Liebe Grüße,

Baustein

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hm, da ich zwar die Funktion, aber nicht den Sinn, Bausteins Codes entdeckt habe, frage ich doch erstmal etwas allgemeiner. Was möchtest du machen?

- Alle Texte, die irgendjemand schreibt, speichern? Dazu kannst du den log nutzen.

- Speichern, dass jemand etwas bestimmtes eingegeben hat? Was soll da gespeichert werden?

Oder was sonst?

Bausteins Code prüft, ob eine Chat-Nachricht eine bestimmte Zeichenfolge enthält und legt dann die Ausgangszeichenfolge in eine Laufzeitvariable (ist also weg, wenn der Server neu gestartet wird). Aber wozu sollte das gut sein. Bitte klär mich auf :)

Liebe Grüße

Arcalio

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du kannst das alles natürlich auch noch in externen Dateien speichern, am einfachsten (und nicht schönsten, dafür werde ich eh gleich wieder von Arcalio gehatet) ist da die Config, da es für sie schon vorgefertigte Methoden von Bukkit gibt.

Liebe Grüße,

Baustein

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du kannst das alles natürlich auch noch in externen Dateien speichern, am einfachsten (und nicht schönsten, dafür werde ich eh gleich wieder von Arcalio gehatet) ist da die Config, da es für sie schon vorgefertigte Methoden von Bukkit gibt.

Liebe Grüße,

Baustein

Configs sind, wie der Name schon sagt, natürlich für Konfigurationswerte vorgesehen. Man kann sie auch anders nutzen, ist aber nicht zu empfehlen. Zumal es ein leichtes ist, Strings in einer einfachen Datendatei zu speichern und wieder auszulesen.

Mir geht es voralle darum, erstmal dein konkretes Problem genau zu verstehen :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Zum Beispiel: schreibt man Wieviele Slots hat der Server #frage wird diese Nachricht in der Config gespeichert.

Ich verstehe nicht, was es da nicht zu verstehen gibt.

Der TE möchte, dass wen jemand X in den Thread eingibt, X ist hier das Äquivalent zu #frage, so soll seine Nachricht in der Config gespeichert sein. Der TE hat also noch dazu meinen Lösungsvorschlag schon in seinem Post gehabt o.O

Liebe Grüße,

Baustein

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was sollte das für einen Sinn haben? Ich habe seinen Post durchaus gelesen, verstehe aber einfach den Anwendungsfall nicht...

Wieso sollte ich irgendeine Zeichenfolge aus dem Chat speichern? Zumal ich diese Zeichenfolge ja bereits vor dem Eingeben kenne. Die einzige (!) Information, die ich dann gewinne, ist, wie oft diese Zeichenfolge geschrieben wurde. Und dafür nimmst sogar du, lieber Baustein, Integer! :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es gibt mehr als du siehst ;)

Was geht es uns an, was der TE damit machen will? Ganz oft schreibe ich im Bukkit Forum meine Fragen, und da kann und will ich nicht den gesamten Sinn meines Plugins erläutern, da er 1. vielleicht häufig nicht einfach zu verstehen ist und 2. ihn eventuell auch nicht jeder vor meinem Release wissen sollte.

Liebe Grüße,

Baustein

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es gibt mehr als du siehst wink.png

Was geht es uns an, was der TE damit machen will? Ganz oft schreibe ich im Bukkit Forum meine Fragen, und da kann und will ich nicht den gesamten Sinn meines Plugins erläutern, da er 1. vielleicht häufig nicht einfach zu verstehen ist und 2. ihn eventuell auch nicht jeder vor meinem Release wissen sollte.

Liebe Grüße,

Baustein

Das ist schon klar. Aber man muss zumindest so viel sagen, dass die potentiellen Helfer auch wissen, um was für ein Problem es sich überhaupt handelt. Und offensichtlich weißt du es ja auch nicht :P

Link zu diesem Kommentar
Auf anderen Seiten teilen

Nope, ich weiß nicht, wofür er das braucht, aber ich bin mir sicher, dass ich seine Frage verstanden habe. Lass uns für das Weiterführen der Diskussion doch warten, bis der TE geantwortet hat, sonst bricht hier noch der dritte Weltkrieg aus, und Putin sowie Obama sind auf meiner Seite, also pass lieber auf :P

Liebe Grüße,

Baustein

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn ein User eine Frage an irgendwen stellt. Zum Beispiel an einen YouTuber. Und der zugewiesene Hash Tag darin vorkommt. Wird seine Nachricht gespeichert wie bei Baustein. Nur halt in einer Datei. Cfg da darin noch Platz ist. Wenn der in diesem Falle der YouTube jetzt /HT (sein Name) eingibt werden die Nachrichten angezeigt. Finde ich eleganter als mit /fragyoutuber. In der Konfig wird nun auch alles gespeichert. Aber ja bei jedem neuen das alte über schrieben . Also müsste da noch was gemacht werden. Und wie lese ich das dann aus damit es über sichtlich bleibt. Vllt Speichers ich das pet p.getPlayer().getName()

Link zu diesem Kommentar
Auf anderen Seiten teilen

Zu der Frage soll es ja nicht nur eine Antwort geben. Wenn jmd ne Frage an einen Youtuber hat macht welche Projekte kommen demnächst #youtubername. Der YouTube r muss aber registriert sein. Baue die dann ein. Dann kann der YouTube in einem Video /YouTube Namedesytery eingeben und sieht die um diese zu beantworten .

Link zu diesem Kommentar
Auf anderen Seiten teilen

Kein Problem. Ich mach dir gleich nen Codeschnipsel, schau' am besten mal so in etwa 30 Minuten vorbei ;)

Liebe Grüße,

Baustein

Also dann. Ich habe dir mal das gesamte Plugin geschrieben, werde im Folgenden aber den Code erklären.

Herunterladen kannst du es dir unterhttp://downloads.baustein.me/plugins/615Power.jar.

Komischerweise scheint es nicht sehr performant zu sein, was mich wirklich wundert, weil eigentlich nicht viel passiert. Da ich mich aber gleich zu einem wichtigen Termin begeben muss bin ich gerade sehr in Eile und konnte dem nicht mehr auf den Grund gehen. Viel Spaß, Arcalio ;D

Das Plugin besteht aus zwei Klassen. Der Main-Klasse und der ChatListener-Klasse.

Gehen wir zuerst in die Main.java:

public static Main plugin;public void onEnable() {	plugin = this;	this.getServer().getPluginManager().registerEvents(new ChatListener(), this);}

Zuerst erstelle ich ein Objekt des Typs Main, um später auf Methoden aus dieser Klasse zugreifen zu können. Dieses Objekt instanziiere ich in der onEnable(), die bei jedem Server-Start / -Reload ausgeführt wird.

In der onEnable() registriere ich außerdem das Event, nämlich das AsyncPlayerChatEvent, auf welches in der Klasse ChatListener eingegangen wird.

@Overridepublic boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {	if (cmd.getName().equalsIgnoreCase("Messages")) {					if (!sender.hasPermission("615Power.Messages")) {			sender.sendMessage(ChatColor.RED + "No permission.");			return true;		}				if (sender instanceof ConsoleCommandSender) {			if (args.length != 1) {				sender.sendMessage(ChatColor.GOLD + "Usage: " + ChatColor.WHITE + "/messages <PlayerName>");				return true;			}						String seekedPlayer = args[0];			sendMessages(sender, getMessages(seekedPlayer));			return true;		}						Player p = (Player) sender;		sendMessages(sender, getMessages(p.getName()));											}	return true;}

Hier wird das einzige Kommando, welches mein Plugin einführt, behandelt: /Messages.

Mit diesem Kommando können Spieler ihre eingegangenen Nachrichten anschauen. Ich habe es mal /Messages genannt, da ich keinen Grund sehe, warum das nur für YouTuber vorhanden sein sollte. Aber das kannst du natürlich selbst nach deinem Belieben ändern ;)

Zuerst mache ich eine Permissions-Abfrage. Du müsstest bei mir also allen Spielern, die /Messages eingeben dürfen sollen die Berechtigung "615Power.Messages" geben.

Danach checke ich, ob der Sender nicht vielleicht die Konsole ist. Wenn ja, dann benötige ich ein Argument, nämlich den Spielernamen, für den die Nachrichten angesehen werden sollen. Sollte dieses Argument nicht vorhanden sein --> Meldung.

Wenn doch, dann wird auf die Methode sendMessages() und getMessages() zugegriffen, die ich später erkläre.

Falls der Sender nicht die Konsole ist, so erstelle ich erstmal wieder ein Objekt des Typs Player und schicke auch diesem die entsprechenden Nachrichten.

public List<String> getMessages(String playerName) {	List<String> messages = new  ArrayList<String>();		int amount = 0;	boolean goOn = true;		while(goOn) {		if (this.getConfig().contains("Messages." + playerName + "." + amount)) {			String message = this.getConfig().getString("Messages." + playerName + "." + amount);			messages.add(message);						amount++;		}		else goOn = false;	}		return messages;}

Hier geht's ans Eingemachte.

Zuerst erstelle ich eine leere Liste die String beinhaltet. In diese Liste sollen alle Nachrichten reingepackt werden, die der Spieler mit dem Spielernamen playerName empfangen hat.

Danach erstelle ich eine Integer mit dem Wert 0, diese wird gleich zum Durchzählen verschiedener Werte genutzt. Außerdem erstelle ich ein boolean, das erstmal auf true gesetzt wird.

while(goOn) ist böse. Ich schreibe nämlich eigentlich while(true). Ich glaube, da werden sich wieder Arcalios Nackenhaare sträuben. Aber auch hier: Zeitdruck :P Und der Wert des booleans wird später in der while-Schleife auch gewechselt.

Denn in der Schleife an sich schaue ich, ob die Config einen Eintrag des Formats

"Messages." + playerName + "." + amount

beinhaltet. Ein Beispiel wäre:

Messages.Baustein.102

für die 103. Nachricht an mich (103 weil ich auch hier bei 0 anfange, zu zählen).

Wenn ein solcher Eintrag vorhanden ist, so füge ich ihn zur List hinzu und erhöhe amount um eins.

Das führt dazu, dass jetzt beim nächsten Durchgang nach

Messages.Baustein.103

gesucht wird, also nach dem nächsten Eintrag.

Sollte dieser auch noch vorhanden sein, so fängt das Spiel wieder von vorne an. Aber wenn er nicht da ist, dann wird goOn auf false gestellt und die Schleife somit beendet.

Danach wird nur noch die List zurückgegeben ;)

private void sendMessages(CommandSender sender, List<String> messages) {	sender.sendMessage(ChatColor.YELLOW + "?- - - - - - - - - -  - - -  - -?");	for (String message : messages) {		if (message == null) continue;		sender.sendMessage(message);	}	sender.sendMessage(ChatColor.YELLOW + "?- - - - - - - - - -  - - -  - -?");}

Diese Methode dient nur dazu, dass ich nicht zweimal denselben Code schreibe (bei der Konsole und beim Spieler). Sie schickt dem Sender die Nachrichten, die für ihn angekommen sind.

In den Zeilen 74 und 79 schicke ich nur nette kleine Formatierungslinien zur Deko.

Dazwischen habe ich eine for-each-Schleife, in der ich für jede Nachricht, die ich mit getMessages() für den spezifischen Spieler bekommen habe, eine Nachricht an den Sender schicke.

Ich sage hier immer Sender, weil der Sender ja sowohl die Konsole als auch ein Spieler sein kann.

Mit der Main-Klasse sind wir also durch. Kommen wir zum ChatListener:

@EventHandler	public void onPlayerChat(AsyncPlayerChatEvent e) {		if (!e.getMessage().startsWith("#")) return;				Player p = e.getPlayer();		String message = e.getMessage().replaceFirst("#", "");		String seekedPlayer;				if (message.contains(" ")) seekedPlayer = message.substring(0, message.indexOf(" "));		else {			p.sendMessage(ChatColor.RED + "You have to enter a message.");			return;		}		                seekedPlayer = seekedPlayer.replace("_", " ");		Main.plugin.getConfig().set("Messages." + seekedPlayer + "." + Main.plugin.getMessages(seekedPlayer).size(), "?9" + p.getName() + "?f:" + message.replaceFirst(seekedPlayer, ""));		Main.plugin.saveConfig();				p.sendMessage(ChatColor.GREEN + "Message sent!");						e.setCancelled(true);	}

Zuerst schaue ich nach, ob die Nachricht auf wirklich mit "#" anfängt. Wenn nicht, dann ist sie für mich nicht von Interesse und ich lasse sie links liegen.

Danach schnappe ich mir wieder den Spieler. Nichts Besonderes ;)

Jetzt wird's wieder schwieriger. Ich erstelle einen String namens message mit dem Wert seiner Nachricht, nur ohne die Raute am Anfang. Die ersetze ich mit replaceFirst().

Nun will ich aber herausfinden, welcher Spieler die Nachricht bekommen soll. Und das ist nicht ganz so einfach.

Als erstes trenne ich die Nachricht vom Empfänger. Das mag ich nicht groß erklären, weil ich nicht weiß wie, falls das ein anderer Dev hinkriegt, Glückwunsch, aber meiner Meinung nach muss man das irgendwie für sich selbst verstehen ^^

Dann ersetze ich für den seekedPlayer noch alle Unterstriche mit Leerzeichen. Das hat den einfachen Sinn, dass ich sonst nicht unterscheiden könnte, ob der Spieler, der eine Nachricht abschicken möchte, noch den Empfänger schreibt, oder schon seine Nachricht. Wenn der Empfänger also eine Lücke im Namen hat, dann muss der Verfasser einen Unterstrich statt der Lücke schreiben.

(Gibt auch hier bessere Wege --> Zeitdruck.)

Zum Ende setze ich noch den neuen Wert in der Config und speicher diese.

Alles kein Hexenwerk ;)

Bei weiteren Fragen stehe ich dir hier natürlich zur Verfügung, ansonsten auch auf Skype (Minecraftforum.de). Wenn ich dir geholfen habe, so würde es mich sehr freuen, wenn du am unteren rechten Beitragsrand auf "Gefällt mir" klickst! :)

Hoffentlich kümmert sich noch möglichst schnell wer um das Performance-Problem, ich bin jetzt weg. Tschüdelü!

Liebe Grüße,

Baustein

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich möchte das ja auch verstehen :D deshalb werde ich den DL nicht nutzen. Es werden aber immer noch Fehler angestrichen.

- sendMessage The method sendMessages(CommandSender, List<String>) is undefined for the type MainCmd

- sendMessagesvoid is an invalid type for the variable sendMessages

Danke für das hilfreiche Tutorial. Wo kommt dieses sendMessages denn her?

Ich muss morgen nochmal gucken woher das kommen könnte

bearbeitet von 615Power
Link zu diesem Kommentar
Auf anderen Seiten teilen

The method sendMessages(CommandSender, List<String>) is undefined for the type MainCmd

void is an invalid type for the variable sendMessages

Kann es sein, dass du vergessen hast, bei der Hauptklasse extends JavaPlugin zu machen, bzw. die bukkit.jar als external Library einzubinden?

sendMessages() ist eine Methode, die ich selber gemacht habe, sie fängt in Zeile 73 an.

Und den Download solltest du ruhig nutzen, schon, damit du das fertige Plugin einfach dekompilieren kannst, um den kompletten Code einsehen zu können.

Liebe Grüße,

Baustein

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke aber wie kann ich das Plugin decompilen? Und auch wenn es funktioniert macht es ja nicht das was es soll. Es soll ja mit /messages ALLE Nachrichten von allen Spielern zeigen. Sonst bringt es ja nix

Was für ein Programm und wie mache ich es nun das alle Nachrichten angezeigt werden?

Link zu diesem Kommentar
Auf anderen Seiten teilen

:D Habs gar nicht gesehen das da ein Link war. Danke. Nochmal zur Funktion des Plugins.

Wenn ein YouTuber registriert wird von mir in dem Plugin bekommt er einen Hashtag. Beispielweise #BeispielLP. Schreibt jetzt ein User eine Frage mit dem Hashtag.

615Power: Wie heißt dein Kanal? #BeispielLP

Der BeispielLP kann nun wenn er ein Video aufnimmt und fragen beantworten möchte währen des Spiels auf dem Server /messages #BeispieLP machen und sieht alle Fragen an ihn. Fand ich eine nette Idee für den YTer Rang. In dem Plugin gibt es schon andere Befehle wie /yt screen von daher ist es etwas undurchsichtig. Habe dir übrigends eine Skype Anfrage geschickt

Link zu diesem Kommentar
Auf anderen Seiten teilen

Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren

Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen. Es ist einfach!

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde dich hier an.

Jetzt anmelden
×
×
  • Neu erstellen...
B
B