diff --git a/ts3-client/core/src/main/java/com/ts3client/chatlog/ChatLogScope.java b/ts3-client/core/src/main/java/com/ts3client/chatlog/ChatLogScope.java new file mode 100644 index 0000000..e1fd0ac --- /dev/null +++ b/ts3-client/core/src/main/java/com/ts3client/chatlog/ChatLogScope.java @@ -0,0 +1,7 @@ +package com.ts3client.chatlog; + +public enum ChatLogScope { + SERVER, + CHANNEL, + PRIVATE +} diff --git a/ts3-client/core/src/main/java/com/ts3client/chatlog/ChatLogStore.java b/ts3-client/core/src/main/java/com/ts3client/chatlog/ChatLogStore.java new file mode 100644 index 0000000..21f9603 --- /dev/null +++ b/ts3-client/core/src/main/java/com/ts3client/chatlog/ChatLogStore.java @@ -0,0 +1,239 @@ +package com.ts3client.chatlog; + +import com.ts3client.text.BBCode; +import com.ts3client.text.TsLink; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Reads and writes TeamSpeak-compatible chat logs. The file layout and HTML + * records match the native client closely enough for both clients to consume + * each other's logs. + */ +public final class ChatLogStore { + public static final int HISTORY_LIMIT = 1000; + + private static final DateTimeFormatter BEGIN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + private static final DateTimeFormatter TIME = DateTimeFormatter.ofPattern("HH:mm:ss"); + private static final String HTML_HEADER = + "
(entries.subList(entries.size() - limit, entries.size()));
+ }
+
+ private static List " + infoIcon()
+ + "*** " + kind + " begins " + BEGIN.format(timestamp) + " "
+ + (outgoing ? outgoingIcon() : incomingIcon())
+ + "<" + TIME.format(timestamp) + "> "
+ + userLink(clientId, uniqueId, nickname)
+ + ": " + BBCode.toHtml(message) + " " + infoIcon()
+ + "<" + TIME.format(timestamp) + "> "
+ + "" + html + "";
+ }
+
+ private static String incomingIcon() {
+ return "
";
+ }
+
+ private static String outgoingIcon() {
+ return "
";
+ }
+
+ private static String encode(String value) {
+ return Base64.getEncoder().encodeToString(safe(value).getBytes(StandardCharsets.UTF_8));
+ }
+
+ private static String safe(String value) {
+ return value == null ? "" : value;
+ }
+
+ private record LogFiles(Path txt, Path html) {
+ }
+}
diff --git a/ts3-client/core/src/test/java/com/ts3client/chatlog/ChatLogStoreTest.java b/ts3-client/core/src/test/java/com/ts3client/chatlog/ChatLogStoreTest.java
new file mode 100644
index 0000000..96a27cf
--- /dev/null
+++ b/ts3-client/core/src/test/java/com/ts3client/chatlog/ChatLogStoreTest.java
@@ -0,0 +1,43 @@
+package com.ts3client.chatlog;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class ChatLogStoreTest {
+
+ @TempDir
+ Path temp;
+
+ @Test
+ void writesTs3CompatibleClientLogNamesAndEntries() throws Exception {
+ ChatLogStore logs = new ChatLogStore(temp, "+Tyg2JtxE8vRNZp+JiUBnmBh0MY=");
+
+ logs.begin();
+ logs.appendPrivateMessage("cckqISCrfr6Lq2SLMC//afsbO9w=", true,
+ 610, "bdrlePoB9hU8K8CyjCabY07t3Wo=", "ericek111", "hello");
+
+ Path serverDir = temp.resolve("K1R5ZzJKdHhFOHZSTlpwK0ppVUJubUJoME1ZPQ==");
+ Path clientHtml = serverDir.resolve("clients")
+ .resolve("Y2NrcUlTQ3JmcjZMcTJTTE1DLy9hZnNiTzl3PQ==.html");
+ Path clientTxt = serverDir.resolve("clients")
+ .resolve("Y2NrcUlTQ3JmcjZMcTJTTE1DLy9hZnNiTzl3PQ==.txt");
+
+ assertTrue(Files.isRegularFile(serverDir.resolve("server.html")));
+ assertTrue(Files.isRegularFile(serverDir.resolve("channel.html")));
+ assertTrue(Files.isRegularFile(clientHtml));
+ assertEquals(1, Files.readAllLines(clientTxt).size());
+
+ List