Compare commits

...

5 Commits

Author SHA1 Message Date
413155d7d5 removed old infos from the README 2021-01-27 23:11:56 +01:00
4e2ead95f4 fixed disconnect screen message 2021-01-27 23:09:23 +01:00
a7b9190645 cancel sending signal if user closes the menu 2021-01-27 22:54:33 +01:00
97de58e8ec initial release 2021-01-27 22:41:16 +01:00
c3ff68b5ce change mod names and package 2021-01-26 23:04:09 +01:00
12 changed files with 102 additions and 216 deletions

View File

@ -1,21 +1,4 @@
# AutoReconnect [1.16+][Fabric]
This mod will automatically try to reconnect you back to a server if you got disconnected.
By default, it will make 4 attempts after 3, 10, 30 and 60 seconds.
### Features
* Multiple individually delayed reconnect attempts
* Displays a countdown on the disconnect screen
* Allows you to exit the disconnect screen quickly by pressing the escape key
* Customizable
* Amount of attempts
* Delay between each attempt
* Client side commands
* `/autoreconnect reload` Reloads the config and displays the settings in chat
* `/autoreconnect config [<delayList>]` Sets the delay between each attempt<br>
`[<delayList>]` must be a Nbt List Tag containing Integers, e.g. `[3, 10, 30, 60]` or `[I;3, 10, 30, 60]`
* Support for several mods
# WolfSignal [1.16+][Fabric]
### Installation
@ -31,12 +14,6 @@ By default, it will make 4 attempts after 3, 10, 30 and 60 seconds.
* [AuthMe](https://www.curseforge.com/minecraft/mc-mods/auth-me) <br>
Cancels the countdown if you click on the Re-authenticate button to revalidate the session of the game
### Screenshots
![countdown](src/main/resources/assets/countdown.png)
![failed](src/main/resources/assets/failed.png)
### License
This mod is available under the CC0 license.

View File

@ -8,9 +8,9 @@ org.gradle.jvmargs=-Xmx1G
loader_version=0.10.8
# Mod Properties
mod_version = 1.1.0
maven_group = net.autoreconnect
archives_base_name = autoreconnect
mod_version = 1.0
maven_group = de.mrgeorgen.wolfSignal
archives_base_name = wolfSignal
# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api

View File

@ -1,4 +1,4 @@
package net.autoreconnect;
package de.mrgeorgen.wolfSignal;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.ArgumentType;
@ -8,7 +8,7 @@ import net.minecraft.client.network.ClientCommandSource;
import java.util.*;
import static net.autoreconnect.AutoReconnect.MOD_ID;
import static de.mrgeorgen.wolfSignal.Main.MOD_ID;
public final class ClientCommands
{

View File

@ -0,0 +1,51 @@
package de.mrgeorgen.wolfSignal;
import com.mojang.brigadier.context.CommandContext;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientCommandSource;
import net.minecraft.client.network.ServerInfo;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static de.mrgeorgen.wolfSignal.ClientCommands.*;
import com.mojang.brigadier.arguments.IntegerArgumentType;
public class Main implements ModInitializer {
public static final String MOD_ID = "wolfsignal";
public static int ticks = -1;
public static ServerInfo lastServerEntry = null;
public static boolean pause = false;
public static int signal = -1;
public static int disconnectTicks = -1;
public static int signalIndex = -1;
public static boolean disconnectedCausedByWolfSignal = false;
@Override
public void onInitialize() {
ClientCommands.register(literal("signal").then(argument("signal", IntegerArgumentType.integer(0, 31)).executes(Main::cmdSignal)));
ClientTickEvents.END_CLIENT_TICK.register(client -> disconnectTimeout());
}
private static int cmdSignal(CommandContext<ClientCommandSource> ctx) {
signal = ctx.getArgument("signal", int.class);
disconnectedCausedByWolfSignal = true;
MinecraftClient.getInstance().world.disconnect();
signalIndex = 4;
setTick();
return SINGLE_SUCCESS;
}
private static void disconnectTimeout() {
if(disconnectTicks >= 0 && --disconnectTicks == 0) {
MinecraftClient.getInstance().world.disconnect();
setTick();
}
}
private static void setTick() {
if(signalIndex >= 0) {
ticks = (signal & 1 << signalIndex--) != 0 ? 12 * 20 : 6 * 20;
}
}
}

View File

@ -1,4 +1,4 @@
package net.autoreconnect;
package de.mrgeorgen.wolfSignal;
import net.minecraft.SharedConstants;
import net.minecraft.client.MinecraftClient;
@ -26,11 +26,11 @@ public class Util
Logger logger = LogManager.getLogger("AutoReconnect");
if (Objects.equals(text.getStyle().getColor(), TextColor.fromFormatting(RED)))
{
logger.error("[AutoReconnect] " + text.getString());
logger.error("[wolfSignal] " + text.getString());
}
else
{
logger.info("[AutoReconnect] " + text.getString());
logger.info("[wolfSignal] " + text.getString());
}
}
else player.sendMessage(text, false);

View File

@ -1,8 +1,8 @@
package net.autoreconnect.mixin;
package de.mrgeorgen.wolfSignal.mixin;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.CommandDispatcher;
import net.autoreconnect.ClientCommands;
import de.mrgeorgen.wolfSignal.ClientCommands;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.network.ClientCommandSource;

View File

@ -1,6 +1,6 @@
package net.autoreconnect.mixin;
package de.mrgeorgen.wolfSignal.mixin;
import net.autoreconnect.ClientCommands;
import de.mrgeorgen.wolfSignal.ClientCommands;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientCommandSource;
import net.minecraft.client.network.ClientPlayNetworkHandler;
@ -12,8 +12,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static net.autoreconnect.Util.err;
import static net.autoreconnect.Util.send;
import static de.mrgeorgen.wolfSignal.Util.err;
import static de.mrgeorgen.wolfSignal.Util.send;
@Mixin(ClientPlayerEntity.class)
public abstract class MixinClientPlayerEntity

View File

@ -1,10 +1,11 @@
package net.autoreconnect.mixin;
package de.mrgeorgen.wolfSignal.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.DisconnectedScreen;
import net.minecraft.client.util.Window;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Formatting;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -12,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import static net.autoreconnect.AutoReconnect.*;
import static de.mrgeorgen.wolfSignal.Main.*;
@Mixin(DisconnectedScreen.class)
public class MixinDisconnectedScreen
@ -31,12 +32,13 @@ public class MixinDisconnectedScreen
@Inject(at = @At("RETURN"), method = "render")
private void render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo info)
{
if(!disconnectedCausedByWolfSignal) return;
Window window = MinecraftClient.getInstance().getWindow();
TextRenderer renderer = MinecraftClient.getInstance().textRenderer;
String text = getMessage();
String text = "sending signal " + signal + "using wolfs";
renderer.draw(matrices, text,
(window.getScaledWidth() - renderer.getWidth(text)) / 2F, // centered
(window.getScaledHeight() - reasonHeight) / 2F - 9 * 4, // 9 * 2 higher than the title which is 9 * 2 higher than the disconnect reason
getColor());
Formatting.WHITE.getColorValue());
}
}

View File

@ -1,4 +1,4 @@
package net.autoreconnect.mixin;
package de.mrgeorgen.wolfSignal.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.*;
@ -10,8 +10,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static net.autoreconnect.AutoReconnect.*;
import static net.autoreconnect.Util.log;
import static de.mrgeorgen.wolfSignal.Main.*;
import static de.mrgeorgen.wolfSignal.Util.log;
@Mixin(MinecraftClient.class)
public class MixinMinecraftClient
@ -35,45 +35,28 @@ public class MixinMinecraftClient
// if not paused, decrements countdown until its negative, succeeds if its 0
if (ticks >= 0 && --ticks == 0)
{
if (lastServerEntry == null)
{
resetAttempts();
}
else
if (lastServerEntry != null)
{
MinecraftClient mc = MinecraftClient.getInstance();
mc.openScreen(new ConnectScreen(new MultiplayerScreen(new TitleScreen()), mc, lastServerEntry));
if(disconnectedCausedByWolfSignal = signalIndex >= 0) {
disconnectTicks = 2 * 20;
}
}
}
}
@Inject(at = @At("INVOKE"), method = "openScreen")
private void openScreen(Screen newScreen, CallbackInfo info)
{
private void openScreen(Screen newScreen, CallbackInfo info) {
// old and new screen must not be the same type, actually happens very often for some reason
if ((currentScreen == null ? null : currentScreen.getClass()) != (newScreen == null ? null : newScreen.getClass()))
{
if ((currentScreen == null ? null : currentScreen.getClass()) != (newScreen == null ? null : newScreen.getClass())) {
if (currentScreen instanceof DisconnectedScreen && ( // exited disconnect screen using...
newScreen instanceof MultiplayerScreen || // ...cancel button on disconnect screen
newScreen instanceof TitleScreen || // ...escape key
newScreen != null && newScreen.getClass().getSimpleName().equals("AuthScreen")) || // ...AuthMe re-authenticate button
(currentScreen instanceof ConnectScreen && !(newScreen instanceof DisconnectedScreen))) // connection successful or cancelled using cancel button on connect screen
newScreen instanceof TitleScreen || // ...escape key
newScreen != null && newScreen.getClass().getSimpleName().equals("AuthScreen")) || // ...AuthMe re-authenticate button
(currentScreen instanceof ConnectScreen && !(newScreen instanceof DisconnectedScreen))) // connection successful or cancelled using cancel button on connect screen
{
resetAttempts();
}
// player got disconnected
else if (newScreen instanceof DisconnectedScreen)
{
// if last known server is not null and next attempt is configured
if (lastServerEntry != null && ++attempt < delayList.length)
{
ticks = delayList[attempt] * 20;
}
else
{
resetAttempts();
}
log("lastServerEntry: %s, attempt: %d", lastServerEntry == null ? "null" : lastServerEntry.name, attempt);
ticks = -1;
disconnectedCausedByWolfSignal = false;
}
}
}

View File

@ -1,126 +0,0 @@
package net.autoreconnect;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.mojang.brigadier.context.CommandContext;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.network.ClientCommandSource;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.nbt.*;
import net.minecraft.util.Formatting;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.IntStream;
import static com.mojang.brigadier.Command.SINGLE_SUCCESS;
import static net.autoreconnect.ClientCommands.*;
import static net.autoreconnect.Util.*;
import static net.minecraft.command.arguments.NbtTagArgumentType.nbtTag;
import static net.minecraft.util.Formatting.*;
public class AutoReconnect implements ModInitializer
{
public static final String MOD_ID = "autoreconnect";
public static int[] delayList = { 3, 10, 30, 60 };
public static int ticks = -1;
public static int attempt = -1;
public static ServerInfo lastServerEntry = null;
public static boolean pause = false;
@Override
public void onInitialize()
{
ClientCommands.register(literal("reload").executes(AutoReconnect::cmdReload));
ClientCommands.register(literal("config").then(argument("delayList", nbtTag()).executes(AutoReconnect::cmdConfig)));
loadConfig();
}
private static int cmdReload(CommandContext<ClientCommandSource> ctx)
{
loadConfig();
return SINGLE_SUCCESS;
}
private static int cmdConfig(CommandContext<ClientCommandSource> ctx)
{
Tag tag = ctx.getArgument("delayList", Tag.class);
try
{
// if tag is not a list or a list not containing integers it will pass null or an empty list
setDelayList(tag instanceof AbstractListTag ? ((AbstractListTag<? extends Tag>) tag).stream().filter(IntTag.class::isInstance).map(IntTag.class::cast).mapToInt(IntTag::getInt).toArray() : null);
saveConfig();
send(colored("Current configuration: " + Arrays.toString(delayList), GREEN));
}
catch (IOException | IllegalArgumentException ex)
{
send(err(ex));
}
return SINGLE_SUCCESS;
}
private static void loadConfig()
{
Path configPath = FabricLoader.getInstance().getConfigDir().resolve(MOD_ID + ".json");
try
{
setDelayList(new Gson().fromJson(Files.newBufferedReader(configPath), int[].class));
send(colored("Current configuration: " + Arrays.toString(delayList), GREEN));
}
catch (IOException | IllegalArgumentException | JsonParseException ex)
{
send(err(ex));
try
{
send(colored("Creating default config...", GREEN));
saveConfig();
}
catch (IOException ex2)
{
send(err(ex2));
}
}
}
private static void saveConfig() throws IOException
{
Path configPath = FabricLoader.getInstance().getConfigDir().resolve(MOD_ID + ".json");
File configFile = configPath.toFile();
// if file already exists or could successfully be created
if (configFile.exists() || configFile.createNewFile())
{
Files.write(configPath, new Gson().toJson(delayList).getBytes());
send(colored("Saved config", GREEN));
}
}
private static void setDelayList(int[] delayList) throws IllegalArgumentException
{
// if null or empty or contains negatives or zeros
if (delayList == null || delayList.length == 0 || IntStream.of(delayList).anyMatch(i -> i <= 0))
throw new IllegalArgumentException("delayList must be a non-empty list of strictly positive integers");
AutoReconnect.delayList = delayList;
}
public static void resetAttempts()
{
ticks = -1;
attempt = -1;
log("reset");
}
public static String getMessage()
{
return attempt < 0 ? "Could not reconnect" : String.format("Reconnect in %d...", ticks / 20 + 1);
}
public static int getColor()
{
return Optional.of(attempt < 0 ? RED : GREEN).filter(Formatting::isColor).map(Formatting::getColorValue).orElse(0xFFFFFF);
}
}

View File

@ -1,17 +1,16 @@
{
"schemaVersion": 1,
"id": "autoreconnect",
"version": "1.1.0",
"id": "wolfsignal",
"version": "1.0",
"name": "AutoReconnect",
"description": "This mod will automatically try to reconnect you back to a server if you got disconnected.\nBy default, it will make 4 attempts after 3, 10, 30 and 60 seconds.",
"name": "Wolf Signal",
"description": "send redstone signals thrpugh wolfs",
"authors": [
"Bstn1802"
"MrGeorgen"
],
"contact": {
"homepage": "https://www.curseforge.com/minecraft/mc-mods/autoreconnect",
"sources": "https://github.com/Bstn1802/AutoReconnect",
"issues": "https://github.com/Bstn1802/AutoReconnect/issues"
"homepage": "https://git.redstoneunion.de/MrGeorgen/wolf-signal",
"sources": "https://git.redstoneunion.de/MrGeorgen/wolf-signal"
},
"license": "CC0-1.0",
@ -20,11 +19,11 @@
"environment": "client",
"entrypoints": {
"main": [
"net.autoreconnect.AutoReconnect"
"de.mrgeorgen.wolfSignal.Main"
]
},
"mixins": [
"autoreconnect.mixins.json"
"wolfsignal.mixins.json"
],
"depends": {

View File

@ -1,7 +1,7 @@
{
"required": true,
"minVersion": "0.8",
"package": "net.autoreconnect.mixin",
"package": "de.mrgeorgen.wolfSignal.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
],