Compare commits

..

2 Commits

Author SHA1 Message Date
77a44be34b Run IRC socket I/O on a dedicated background thread
Some checks failed
continuous-integration/drone/push Build is failing
Auto-connect on CLIENT_STARTED, .irc reconnect and .irc <msg> all used
to open a TCP socket on the render thread with a 5s connect timeout,
freezing client startup and chat input when the server was unreachable.
Dispatch those paths through a single daemon executor instead, and
release the socket plus the executor on CLIENT_STOPPING.
2026-06-21 15:40:02 +06:00
153d85602c Restore Loom mappings and modImplementation for Fabric deps
Loom needs an explicit mappings entry, and Fabric loader / API must be
declared with modImplementation so they get remapped against the active
mappings; the previous commit dropped both, which left the build with
no mappings at all and unremapped Fabric jars. Reference the
loom_version property in the plugin block too so it tracks
gradle.properties.
2026-06-21 15:39:49 +06:00
2 changed files with 36 additions and 16 deletions

View File

@@ -1,5 +1,5 @@
plugins { plugins {
id 'net.fabricmc.fabric-loom' version '1.17-SNAPSHOT' id 'net.fabricmc.fabric-loom' version "${project.loom_version}"
id 'maven-publish' id 'maven-publish'
} }
@@ -30,8 +30,9 @@ repositories {
dependencies { dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}" minecraft "com.mojang:minecraft:${project.minecraft_version}"
implementation "net.fabricmc:fabric-loader:${project.loader_version}" mappings loom.officialMojangMappings()
implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
} }
processResources { processResources {

View File

@@ -11,12 +11,21 @@ import net.minecraft.network.chat.Component;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public final class ClientIrcMod implements ClientModInitializer { public final class ClientIrcMod implements ClientModInitializer {
public static final String MOD_ID = "clientirc"; public static final String MOD_ID = "clientirc";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
private static final String COMMAND_PREFIX = ".irc"; private static final String COMMAND_PREFIX = ".irc";
private static final ExecutorService IO_EXECUTOR = Executors.newSingleThreadExecutor(runnable -> {
Thread thread = new Thread(runnable, "clientirc-io");
thread.setDaemon(true);
return thread;
});
private static IrcConfig config; private static IrcConfig config;
private static IrcService service; private static IrcService service;
@@ -27,10 +36,16 @@ public final class ClientIrcMod implements ClientModInitializer {
ClientLifecycleEvents.CLIENT_STARTED.register(client -> { ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
if (config.autoConnect) { if (config.autoConnect) {
service.connect(resolvePlayerName(client)); String playerName = resolvePlayerName(client);
IO_EXECUTOR.execute(() -> service.connect(playerName));
} }
}); });
ClientLifecycleEvents.CLIENT_STOPPING.register(client -> {
service.disconnect();
IO_EXECUTOR.shutdownNow();
});
ClientTickEvents.END_CLIENT_TICK.register(client -> { ClientTickEvents.END_CLIENT_TICK.register(client -> {
IrcService.DisplayLine line; IrcService.DisplayLine line;
while ((line = service.pollLine()) != null) { while ((line = service.pollLine()) != null) {
@@ -63,9 +78,12 @@ public final class ClientIrcMod implements ClientModInitializer {
} }
if ("reconnect".equalsIgnoreCase(argument)) { if ("reconnect".equalsIgnoreCase(argument)) {
boolean connected = service.reconnect(resolvePlayerName(client)); String playerName = resolvePlayerName(client);
IO_EXECUTOR.execute(() -> {
boolean connected = service.reconnect(playerName);
ChatFormatting color = connected ? ChatFormatting.GREEN : ChatFormatting.RED; ChatFormatting color = connected ? ChatFormatting.GREEN : ChatFormatting.RED;
pushClientChat(client, Component.literal("[IRC] reconnect " + (connected ? "ok" : "failed")).withStyle(color)); pushClientChat(client, Component.literal("[IRC] reconnect " + (connected ? "ok" : "failed")).withStyle(color));
});
return true; return true;
} }
@@ -76,15 +94,16 @@ public final class ClientIrcMod implements ClientModInitializer {
return true; return true;
} }
if (!service.ensureConnected(resolvePlayerName(client))) { String playerName = resolvePlayerName(client);
IO_EXECUTOR.execute(() -> {
if (!service.ensureConnected(playerName)) {
pushClientChat(client, Component.literal("[IRC] server is offline or config is wrong").withStyle(ChatFormatting.RED)); pushClientChat(client, Component.literal("[IRC] server is offline or config is wrong").withStyle(ChatFormatting.RED));
return true; return;
} }
if (!service.sendChat(playerName, argument)) {
boolean sent = service.sendChat(resolvePlayerName(client), argument);
if (!sent) {
pushClientChat(client, Component.literal("[IRC] send failed").withStyle(ChatFormatting.RED)); pushClientChat(client, Component.literal("[IRC] send failed").withStyle(ChatFormatting.RED));
} }
});
return true; return true;
} }