refactor config, cleanup

This commit is contained in:
1e99 2024-12-16 16:54:33 +01:00
parent b1c33bfba1
commit af40cb9974
6 changed files with 92 additions and 131 deletions

View file

@ -0,0 +1,11 @@
package eu.e99.pixelchat.fabric;
import com.google.gson.annotations.SerializedName;
public class Config {
@SerializedName("image_hosts")
public String[] imageHosts = new String[]{
"https://pc.1e99.eu"
};
}

View file

@ -1,13 +1,18 @@
package eu.e99.pixelchat.fabric;
import eu.e99.pixelchat.fabric.image.ImageUploader;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import eu.e99.pixelchat.fabric.image.ImageUploads;
import eu.e99.pixelchat.fabric.image.PixelChatUploader;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class PixelChat implements ClientModInitializer {
public static final String NAMESPACE = "pixelchat";
@ -16,12 +21,38 @@ public class PixelChat implements ClientModInitializer {
@Override
public void onInitializeClient() {
Config config = this.loadConfig();
UPLOADS = new ImageUploads(
MinecraftClient.getInstance(),
new ImageUploader[]{
new PixelChatUploader("https://pc.1e99.eu"),
new PixelChatUploader("http://localhost:3000")
}
config.imageHosts
);
}
private Config loadConfig() {
try {
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
FabricLoader loader = FabricLoader.getInstance();
Path path = loader.getConfigDir();
path = path.resolve("pixelchat.json");
if (Files.exists(path)) {
String string = Files.readString(path);
return gson.fromJson(string, Config.class);
}
Config config = new Config();
String string = gson.toJson(config);
Files.writeString(path, string);
return config;
} catch (IOException e) {
LOGGER.error("Failed to read config, defaulting to default config", e);
return new Config();
}
}
}

View file

@ -1,55 +0,0 @@
package eu.e99.pixelchat.fabric;
import java.util.ArrayList;
import java.util.List;
/**
* A StringList is a list of strings encoded like this: [string1,string2,string3]
* Strings can contain any character except '[', ']' and ','
*/
public class StringList {
public static List<String> fromString(String str) {
List<String> tags = new ArrayList<>();
char[] chars = str.toCharArray();
int i = 0;
if (chars[i++] != '[') {
return null;
}
while (i < chars.length && chars[i] != ']') {
StringBuilder builder = new StringBuilder();
while (i < chars.length && chars[i] != ',' && chars[i] != ']') {
builder.append(chars[i]);
i++;
}
tags.add(builder.toString());
i++;
}
for (String tag : tags) {
System.out.printf("%s%n", tag);
}
return tags;
}
public static String toString(List<String> tags) {
StringBuilder builder = new StringBuilder();
builder.append('[');
int length = tags.size();
for (int i = 0; i < length; i++) {
builder.append(tags.get(i));
if (i < length - 1) {
builder.append(',');
}
}
builder.append(']');
return builder.toString();
}
}

View file

@ -1,11 +0,0 @@
package eu.e99.pixelchat.fabric.image;
import java.nio.file.Path;
public interface ImageUploader {
/**
* @return An URL to a downloadable PNG file
*/
String upload(Path path) throws Throwable;
}

View file

@ -7,17 +7,24 @@ import net.minecraft.client.gui.hud.ClientBossBar;
import net.minecraft.entity.boss.BossBar;
import net.minecraft.text.Text;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.util.List;
import java.util.UUID;
public class ImageUploads {
private final MinecraftClient client;
private final ImageUploader[] uploaders;
private final MinecraftClient minecraft;
private final String[] hosts;
private final HttpClient client;
public ImageUploads(MinecraftClient client, ImageUploader[] uploaders) {
this.client = client;
this.uploaders = uploaders;
public ImageUploads(MinecraftClient minecraft, String[] hosts) {
this.minecraft = minecraft;
this.hosts = hosts;
this.client = HttpClient.newHttpClient();
}
public void uploadImage(Path path) {
@ -25,7 +32,7 @@ public class ImageUploads {
}
private void innerUploadImage(Path path) {
BossBars bossBars = (BossBars) client.inGameHud.getBossBarHud();
BossBars bossBars = (BossBars) minecraft.inGameHud.getBossBarHud();
ClientBossBar bossBar = new ClientBossBar(
UUID.randomUUID(),
Text.translatable("pixelchat.uploading"),
@ -37,12 +44,12 @@ public class ImageUploads {
false
);
this.client.send(() -> bossBars.add(bossBar.getUuid(), bossBar));
this.minecraft.send(() -> bossBars.add(bossBar.getUuid(), bossBar));
String url = null;
for (ImageUploader uploader : this.uploaders) {
for (String host : this.hosts) {
try {
url = uploader.upload(path);
url = this.upload(host, path);
break;
} catch (Throwable e) {
PixelChat.LOGGER.warn("Failed to upload", e);
@ -51,7 +58,7 @@ public class ImageUploads {
// IntelliJ complains otherwise
String finalUrl = url;
this.client.send(() -> {
this.minecraft.send(() -> {
if (finalUrl == null) {
PixelChat.LOGGER.error("No uploader succeeded");
bossBar.setName(Text.translatable("pixelchat.upload_failed"));
@ -65,12 +72,12 @@ public class ImageUploads {
bossBar.setColor(BossBar.Color.GREEN);
// TODO: Are we actually playing?
if (this.client.player == null) {
if (this.minecraft.player == null) {
return;
}
this.client.inGameHud.getChatHud().addToMessageHistory(finalUrl);
this.client.player.networkHandler.sendChatMessage(finalUrl);
this.minecraft.inGameHud.getChatHud().addToMessageHistory(finalUrl);
this.minecraft.player.networkHandler.sendChatMessage(finalUrl);
});
try {
@ -78,6 +85,29 @@ public class ImageUploads {
} catch (InterruptedException ignored) {
}
this.client.send(() -> bossBars.remove(bossBar.getUuid()));
this.minecraft.send(() -> bossBars.remove(bossBar.getUuid()));
}
private String upload(String host, Path path) throws Throwable {
String uri = url(host, "");
HttpRequest req = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofFile(path))
.uri(URI.create(uri))
.build();
HttpResponse<String> res = this.client.send(
req,
HttpResponse.BodyHandlers.ofString()
);
if (res.statusCode() != 201) {
throw new RuntimeException(String.format("Failed to upload, expected status 201, got %d", res.statusCode()));
}
String id = res.body();
return url(host, id);
}
private static String url(String host, String path) {
return String.format("%s/%s", host, path);
}
}

View file

@ -1,45 +0,0 @@
package eu.e99.pixelchat.fabric.image;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class PixelChatUploader implements ImageUploader {
private final HttpClient client;
private final String host;
/**
* @param host A valid URI to the server. Must not end with a slash. Valid examples are: {@code https://pc.1e99.eu} or {@code http://localhost:3000}.
*/
public PixelChatUploader(String host) {
this.client = HttpClient.newHttpClient();
this.host = host;
}
@Override
public String upload(Path path) throws Throwable {
String uri = this.url("");
HttpRequest req = HttpRequest.newBuilder()
.POST(HttpRequest.BodyPublishers.ofFile(path))
.uri(URI.create(uri))
.build();
HttpResponse<String> res = this.client.send(
req,
HttpResponse.BodyHandlers.ofString()
);
if (res.statusCode() != 201) {
throw new RuntimeException(String.format("Failed to upload, expected status 201, got %d", res.statusCode()));
}
String id = res.body();
return this.url(id);
}
private String url(String path) {
return String.format("%s/%s", this.host, path);
}
}