Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

8 changed files with 34 additions and 98 deletions

View File

@ -1,31 +1,19 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins { plugins {
id 'java' id 'java'
id 'com.gradleup.shadow' version '9.0.0-beta4' id 'application'
} }
group = 'net.pixtaded' group = 'net.pixtaded'
version = projectVersion version = '1.0-SNAPSHOT'
repositories { repositories {
mavenCentral() mavenCentral()
} }
application {
mainClass = 'net.pixtaded.crab.Main'
}
dependencies { dependencies {
implementation('org.xerial:sqlite-jdbc:3.47.1.0') implementation('org.xerial:sqlite-jdbc:3.47.1.0')
}
tasks.build.dependsOn tasks.shadowJar
tasks.named('jar', Jar) {
manifest {
attributes 'Main-Class': 'net.pixtaded.crab.Main'
}
}
tasks.named('shadowJar', ShadowJar) {
archiveBaseName = 'crab'
archiveClassifier = ''
archiveVersion = projectVersion
} }

View File

@ -1 +0,0 @@
projectVersion=1.0.5

View File

@ -1,7 +1,6 @@
package net.pixtaded.crab.client; package net.pixtaded.crab.client;
import net.pixtaded.crab.common.Crab; import net.pixtaded.crab.common.Crab;
import net.pixtaded.crab.common.Logs;
import net.pixtaded.crab.common.Sanitizer; import net.pixtaded.crab.common.Sanitizer;
import java.io.*; import java.io.*;
@ -19,7 +18,6 @@ public class CrabClient implements Crab {
private BufferedReader in; private BufferedReader in;
private int lastBufferLength = 0; private int lastBufferLength = 0;
private String nickname; private String nickname;
private Logs cache = new Logs(0, "");
public CrabClient() { public CrabClient() {
this.nickname = ""; this.nickname = "";
@ -39,6 +37,7 @@ public class CrabClient implements Crab {
try { try {
if (this.serverAddress == null) if (this.serverAddress == null)
setup(); setup();
connect();
communicate(); communicate();
} catch (IOException e) { } catch (IOException e) {
System.err.println("Error connecting to the server: " + e.getMessage()); System.err.println("Error connecting to the server: " + e.getMessage());
@ -69,7 +68,7 @@ public class CrabClient implements Crab {
System.out.print("Enter your nickname (leave empty for no nickname): "); System.out.print("Enter your nickname (leave empty for no nickname): ");
nickname = scanner.nextLine(); nickname = scanner.nextLine();
if (!nickname.isEmpty()) if (nickname != "")
nickname = "<" + nickname + "> "; nickname = "<" + nickname + "> ";
} }
@ -83,7 +82,9 @@ public class CrabClient implements Crab {
private void communicate() throws IOException { private void communicate() throws IOException {
Scanner scanner = new Scanner(System.in); Scanner scanner = new Scanner(System.in);
String message; String message;
while (true) { while (true) {
System.out.print("\033[H\033[2J");
getLogs(); getLogs();
System.out.print("Enter a message (or type '/exit' to exit): "); System.out.print("Enter a message (or type '/exit' to exit): ");
message = scanner.nextLine(); message = scanner.nextLine();
@ -97,14 +98,12 @@ public class CrabClient implements Crab {
} }
private void sendPacket(byte PID, String argument) throws IOException { private void sendPacket(byte PID, String argument) throws IOException {
connect();
String formattedMessage = String.valueOf((char) PID) + argument + "\n"; String formattedMessage = String.valueOf((char) PID) + argument + "\n";
out.print(formattedMessage); out.print(formattedMessage);
out.flush(); out.flush();
receiveResponse(PID); receiveResponse(PID);
closeConnection();
} }
private void receiveResponse(byte PID) throws IOException { private void receiveResponse(byte PID) throws IOException {
@ -114,15 +113,13 @@ public class CrabClient implements Crab {
int response = in.read(buffer); int response = in.read(buffer);
lastBufferLength = Integer.parseInt(new String(buffer).trim()); lastBufferLength = Integer.parseInt(new String(buffer).trim());
} case LOGS -> { } case LOGS -> {
if (cache.sizeInBytes() != lastBufferLength) { byte[] bytes = socket.getInputStream().readNBytes(lastBufferLength);
byte[] bytes = socket.getInputStream().readNBytes(lastBufferLength); System.out.print(Sanitizer.sanitizeString(new String(bytes, StandardCharsets.UTF_8), false));
cache = new Logs(lastBufferLength, new String(bytes, StandardCharsets.UTF_8));
}
clearScreen();
System.out.print(Sanitizer.sanitizeString(cache.content(), false));
} default -> { } default -> {
} }
} }
closeConnection();
connect();
} }
private void closeConnection() { private void closeConnection() {
@ -139,9 +136,4 @@ public class CrabClient implements Crab {
sendPacket(LOGS_SIZE, ""); sendPacket(LOGS_SIZE, "");
sendPacket(LOGS, ""); sendPacket(LOGS, "");
} }
private void clearScreen() {
System.out.print("\033[999999S\033[H\033[2J");
}
} }

View File

@ -1,4 +0,0 @@
package net.pixtaded.crab.common;
public record Logs(int sizeInBytes, String content) {
}

View File

@ -2,15 +2,11 @@ package net.pixtaded.crab.common;
public class Sanitizer { public class Sanitizer {
public static String sanitizeString(String s, boolean sanitizeNewlines) { public static String sanitizeString(String s, boolean sanitizeNewlines) {
String sanitized = s.replaceAll("[\010\015\033]", ""); String sanitized = s.replaceAll("\033", "");
if (sanitizeNewlines) { if (sanitizeNewlines) {
sanitized = sanitized.replaceAll("\n", "\\\\n"); sanitized = sanitized.replaceAll("\n", "\\\\n");
if (!s.endsWith("\n")) sanitized += '\n'; if (!s.endsWith("\n")) sanitized += '\n';
} }
return sanitized; return sanitized;
} }
public static String formatMessage(long timeMillis, String address, String content) {
return String.format("[%td.%1$tm.%1$tY %1$tR] {%s} %s", timeMillis, address, content);
}
} }

View File

@ -1,6 +1,5 @@
package net.pixtaded.crab.server; package net.pixtaded.crab.server;
import net.pixtaded.crab.common.Crab; import net.pixtaded.crab.common.Crab;
import net.pixtaded.crab.common.Logs;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
@ -13,8 +12,7 @@ public class CrabServer implements Crab {
private Socket socket; private Socket socket;
private boolean isStopped = false; private boolean isStopped = false;
private int port; private int port;
private final Database db; private Database db;
public Logs cache = new Logs(0, "");
public CrabServer() { public CrabServer() {
this.db = new Database("data.db"); this.db = new Database("data.db");
@ -30,7 +28,6 @@ public class CrabServer implements Crab {
try { try {
if (this.port == 0) if (this.port == 0)
setup(); setup();
this.cache = getDb().getLogs();
listen(); listen();
} catch (IOException e) { } catch (IOException e) {
if (!isStopped) System.err.println("Error starting server: " + e.getMessage()); if (!isStopped) System.err.println("Error starting server: " + e.getMessage());
@ -69,9 +66,9 @@ public class CrabServer implements Crab {
} }
} }
public synchronized void stop() { public void stop() {
isStopped = true;
try { try {
isStopped = true;
if (socket != null) socket.close(); if (socket != null) socket.close();
if (serverSocket != null) serverSocket.close(); if (serverSocket != null) serverSocket.close();
} catch (IOException e) { } catch (IOException e) {

View File

@ -1,14 +1,15 @@
package net.pixtaded.crab.server; package net.pixtaded.crab.server;
import net.pixtaded.crab.common.Logs;
import net.pixtaded.crab.common.Sanitizer; import net.pixtaded.crab.common.Sanitizer;
import java.sql.*; import java.sql.*;
import java.util.Date; import java.util.Date;
import java.util.Locale;
public class Database implements AutoCloseable { public class Database {
private Connection connection; private Connection connection;
private String logs = "";
public Database(String dbName) { public Database(String dbName) {
try { try {
@ -49,23 +50,22 @@ public class Database implements AutoCloseable {
} }
} }
public Logs getLogs() { public String getLogs() {
StringBuilder s = new StringBuilder(); StringBuilder s = new StringBuilder();
try (ResultSet rs = query("SELECT time, address, msg FROM messages")) { try (ResultSet rs = query("SELECT time, address, msg FROM messages")) {
while (rs.next()) { while (rs.next()) {
s.append(Sanitizer.formatMessage(rs.getLong(1), rs.getString(2), rs.getString(3))); s.append(String.format("[%td.%1$tm.%1$tY %1$tR] {%s} %s", rs.getLong(1), rs.getString(2), rs.getString(3)));
} }
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
String logsString = s.toString(); logs = s.toString();
return new Logs(logsString.isEmpty() ? 0 : logsString.getBytes().length, logsString); return logs;
} }
@Override public int getLogSize() {
public void close() throws SQLException { if (logs.isEmpty()) return 0;
if (connection != null && !connection.isClosed()) { else return logs.getBytes().length;
connection.close();
}
} }
} }

View File

@ -1,8 +1,5 @@
package net.pixtaded.crab.server; package net.pixtaded.crab.server;
import net.pixtaded.crab.common.Logs;
import net.pixtaded.crab.common.Sanitizer;
import java.io.*; import java.io.*;
import java.net.Socket; import java.net.Socket;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -33,30 +30,18 @@ public class ServerThread implements Runnable {
public void run() { public void run() {
try { try {
byte[] PID = input.readNBytes(1); byte[] PID = input.readNBytes(1);
if (PID.length == 0) {
socket.close();
return;
}
switch (PID[0]) { switch (PID[0]) {
case MESSAGE -> { case MESSAGE -> {
Date date = new Date(); server.getDb().logMessage(new Date(), socket.getInetAddress().getHostAddress(), new String(input.readNBytes(4096), StandardCharsets.UTF_8).trim());
String msg = new String(input.readNBytes(4096), StandardCharsets.UTF_8).trim(); socket.close();
String address = socket.getInetAddress().getHostAddress();
String s = Sanitizer.sanitizeString(msg, true);
String newContent = server.cache.content() + Sanitizer.formatMessage(date.getTime(), address, s);
server.cache = new Logs(newContent.getBytes().length, newContent);
new Thread(new LogDBThread(date, address, msg)).start();
} case LOGS -> { } case LOGS -> {
respond(server.cache.content()); respond(server.getDb().getLogs());
} case LOGS_SIZE -> { } case LOGS_SIZE -> {
respond(String.valueOf(server.cache.sizeInBytes())); respond(String.valueOf(server.getDb().getLogSize()));
} default -> { } default -> {
System.out.println("PID not implemented: " + PID[0]); System.out.println("PID not implemented: " + PID[0]);
} }
} }
socket.close();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -65,27 +50,10 @@ public class ServerThread implements Runnable {
private void respond(byte[] data) throws IOException { private void respond(byte[] data) throws IOException {
socket.getOutputStream().write(data); socket.getOutputStream().write(data);
socket.getOutputStream().flush(); socket.getOutputStream().flush();
socket.close();
} }
private void respond(String utf8) throws IOException { private void respond(String utf8) throws IOException {
respond(utf8.getBytes(StandardCharsets.UTF_8)); respond(utf8.getBytes(StandardCharsets.UTF_8));
} }
private class LogDBThread implements Runnable {
Date date;
String msg;
String address;
public LogDBThread(Date date, String address, String msg) {
this.date = date;
this.msg = msg;
this.address = address;
}
@Override
public void run() {
server.getDb().logMessage(date, address, msg);
}
}
} }