v3.2
This commit is contained in:
1 parent
a9fd8da7f5
commit
c993d4fdac
11 files changed
+482
-33
No files matched your search
+4
-10
@@ -1,23 +1,17 @@
|
||||
# v3.1
|
||||
# v3.2
|
||||
|
||||
## novedades
|
||||
|
||||
- aviso para actualizar
|
||||
|
||||
### adiciones
|
||||
|
||||
#### módulos nuevos:
|
||||
|
||||
- resaltado de entidades: wallhack para entidades, modo de caja y de brillo
|
||||
- hitboxes: cambia el color de las hitboxes de f3+b
|
||||
- dupe de bundle: robado de .gg/dupes, usando un bundle y un libro de bookbot, dupea 63 del ítem deseado
|
||||
- j. k. rowling: rellena libros con caca de manera automática
|
||||
|
||||
### arreglos / mejoras
|
||||
|
||||
- más opciones para amortiguar caídas con tobillos fuertes
|
||||
- selección de minado ahora solo renderizará el contorno si su ajuste está activado
|
||||
- prioridad de selección de minado, cuantos más clics tenga un bloque, mayor será su prioridad. también la opción de deseleccionar un bloque.
|
||||
- opción para minar bloques en orden forzosamente en selección de minado (no funciona del todo)
|
||||
- evitar romper la caña si está a punto de romperse en auto pesca
|
||||
- ahora el aviso de actualizaciones ya funciona bien
|
||||
|
||||
## problemas reconocidos
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.retucio.sputnik;
|
||||
|
||||
import com.ibm.icu.text.CaseMap;
|
||||
import me.retucio.sputnik.cape.CapeManager;
|
||||
import me.retucio.sputnik.command.CommandManager;
|
||||
import me.retucio.sputnik.command.commands.BindCommand;
|
||||
@@ -9,6 +10,7 @@ import me.retucio.sputnik.config.ConfigManager;
|
||||
import me.retucio.sputnik.event.EventBus;
|
||||
import me.retucio.sputnik.event.SubscribeEvent;
|
||||
import me.retucio.sputnik.event.events.ShutdownEvent;
|
||||
import me.retucio.sputnik.event.events.interact.OpenScreenEvent;
|
||||
import me.retucio.sputnik.event.events.sputnik.LoadCapeManagerEvent;
|
||||
import me.retucio.sputnik.event.events.sputnik.LoadClickGUIEvent;
|
||||
import me.retucio.sputnik.event.events.sputnik.LoadCommandManagerEvent;
|
||||
@@ -42,6 +44,7 @@ import net.minecraft.SharedConstants;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.ChatScreen;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.TitleScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.AbstractCommandBlockScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.AbstractSignEditScreen;
|
||||
import net.minecraft.client.gui.screen.ingame.AnvilScreen;
|
||||
@@ -133,11 +136,6 @@ public class Sputnik implements ClientModInitializer {
|
||||
settingsApplied = true;
|
||||
}
|
||||
|
||||
if (VersionChecker.shouldShowScreen && !(mc.currentScreen instanceof UpdateScreen)) {
|
||||
VersionChecker.shouldShowScreen = false;
|
||||
CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS).execute(() -> mc.execute(() -> mc.setScreen(new UpdateScreen())));
|
||||
}
|
||||
|
||||
ModuleManager.INSTANCE.getEnabledModules().forEach(Module::onTick);
|
||||
mc.getWindow().setTitle(ClientSettingsFrame.guiSettings.windowTitle.getValue());
|
||||
}
|
||||
@@ -244,6 +242,16 @@ public class Sputnik implements ClientModInitializer {
|
||||
|| mc.currentScreen instanceof AbstractCommandBlockScreen;
|
||||
}
|
||||
|
||||
// notificar al usuario de que hay una actualización disponible, si la hay
|
||||
@SubscribeEvent
|
||||
public void onSetScreen(OpenScreenEvent event) {
|
||||
if (VersionChecker.shouldShowScreen && event.getScreen() instanceof TitleScreen) {
|
||||
event.cancel();
|
||||
VersionChecker.shouldShowScreen = false;
|
||||
mc.execute(() -> mc.currentScreen = new UpdateScreen());
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onStop(ShutdownEvent event) {
|
||||
ConfigManager.save();
|
||||
|
||||
@@ -9,11 +9,14 @@ import me.retucio.sputnik.event.events.TickEvent;
|
||||
import me.retucio.sputnik.event.events.interact.UseItemEvent;
|
||||
import me.retucio.sputnik.module.ModuleManager;
|
||||
import me.retucio.sputnik.module.modules.player.FastUse;
|
||||
import me.retucio.sputnik.ui.screen.UpdateScreen;
|
||||
import me.retucio.sputnik.util.VersionChecker;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Hand;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import org.spongepowered.asm.mixin.injection.*;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@@ -32,6 +35,10 @@ public abstract class MinecraftClientMixin {
|
||||
|
||||
// eventos
|
||||
|
||||
@Shadow
|
||||
@Nullable
|
||||
public Screen currentScreen;
|
||||
|
||||
@Inject(method = "tick", at = @At("HEAD"))
|
||||
private void onTickPre(CallbackInfo ci) {
|
||||
Sputnik.INSTANCE.onTick();
|
||||
@@ -67,7 +74,6 @@ public abstract class MinecraftClientMixin {
|
||||
if (event.isCancelled()) ci.cancel();
|
||||
}
|
||||
|
||||
|
||||
// telemetría
|
||||
|
||||
@Inject(method = "isTelemetryEnabledByApi", at = @At("RETURN"), cancellable = true)
|
||||
|
||||
@@ -84,7 +84,9 @@ public class ModuleManager {
|
||||
private void addMisc() {
|
||||
add(new AntiInvis());
|
||||
add(new AnvilFont());
|
||||
add(new BookBot());
|
||||
add(new BossbarStack());
|
||||
add(new BundleDupe());
|
||||
add(new ChatPlus());
|
||||
add(new CreativeInventoryHotbarKeybinds());
|
||||
add(new FakePlayer());
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
package me.retucio.sputnik.module.modules.misc;
|
||||
|
||||
import me.retucio.sputnik.event.SubscribeEvent;
|
||||
import me.retucio.sputnik.event.events.network.DisconnectEvent;
|
||||
import me.retucio.sputnik.module.Category;
|
||||
import me.retucio.sputnik.module.Module;
|
||||
import me.retucio.sputnik.module.setting.SettingGroup;
|
||||
import me.retucio.sputnik.module.setting.settings.BooleanSetting;
|
||||
import me.retucio.sputnik.module.setting.settings.NumberSetting;
|
||||
import me.retucio.sputnik.module.setting.settings.StringSetting;
|
||||
import me.retucio.sputnik.util.ChatUtil;
|
||||
import me.retucio.sputnik.util.InventoryUtil;
|
||||
import net.minecraft.client.font.TextHandler;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.component.type.WritableBookContentComponent;
|
||||
import net.minecraft.component.type.WrittenBookContentComponent;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.network.packet.c2s.play.BookUpdateC2SPacket;
|
||||
import net.minecraft.text.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Random;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
||||
public class BookBot extends Module {
|
||||
|
||||
private final SettingGroup sgBook = addSg(new SettingGroup("libro", true));
|
||||
|
||||
private final NumberSetting delay = sgGeneral.add(new NumberSetting(
|
||||
"delay",
|
||||
"delay entre la escritura de libros",
|
||||
20,
|
||||
1,
|
||||
200,
|
||||
1
|
||||
));
|
||||
|
||||
private final BooleanSetting toggleOnDisconnect = sgGeneral.add(new BooleanSetting(
|
||||
"desactivar al desconectarse",
|
||||
".",
|
||||
true
|
||||
));
|
||||
|
||||
private final StringSetting name = sgBook.add(new StringSetting(
|
||||
"nombre",
|
||||
"nombre a usar para los libros",
|
||||
"mortadela y filetón",
|
||||
100
|
||||
));
|
||||
|
||||
private final BooleanSetting count = sgBook.add(new BooleanSetting(
|
||||
"contar",
|
||||
"contar los libros y añadir el número al final del nombre",
|
||||
true
|
||||
));
|
||||
|
||||
private final NumberSetting pages = sgBook.add(new NumberSetting(
|
||||
"páginas",
|
||||
"número de páginas a llenar con mierda",
|
||||
50,
|
||||
1,
|
||||
100,
|
||||
1
|
||||
));
|
||||
|
||||
private final BooleanSetting sign = sgBook.add(new BooleanSetting(
|
||||
"firmar",
|
||||
"firmar el libro",
|
||||
true
|
||||
));
|
||||
|
||||
private final BooleanSetting onlyAscii = sgBook.add(new BooleanSetting(
|
||||
"solo ascii",
|
||||
"usar solamente caracteres ascii",
|
||||
false
|
||||
));
|
||||
|
||||
private int delayTimer, bookCount;
|
||||
private Random random;
|
||||
|
||||
public BookBot() {
|
||||
super("j. k. rowling", "rellena libros con caca", Category.MISC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
random = new Random();
|
||||
delayTimer = delay.getIntValue();
|
||||
bookCount = 0;
|
||||
super.onEnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (mc.player == null) return;
|
||||
|
||||
Predicate<ItemStack> bookPredicate = stack -> {
|
||||
WritableBookContentComponent component = stack.get(DataComponentTypes.WRITABLE_BOOK_CONTENT);
|
||||
return stack.getItem() == Items.WRITABLE_BOOK && (component == null || component.pages().isEmpty());
|
||||
};
|
||||
|
||||
ItemStack book = InventoryUtil.find(bookPredicate);
|
||||
if (book == null) {
|
||||
ChatUtil.warn("no se encontró ningún libro");
|
||||
toggle();
|
||||
return;
|
||||
}
|
||||
|
||||
if (mc.player.getMainHandStack() != book) {
|
||||
InventoryUtil.swapWithHotbar(
|
||||
mc.player.getInventory().getSlotWithStack(book),
|
||||
mc.player.getInventory().getSelectedSlot()
|
||||
);
|
||||
}
|
||||
|
||||
if (delayTimer > 0) {
|
||||
delayTimer--;
|
||||
return;
|
||||
}
|
||||
|
||||
delayTimer = delay.getIntValue();
|
||||
|
||||
int origin = onlyAscii.getValue() ? 0x21 : 0x0800;
|
||||
int bound = onlyAscii.getValue() ? 0x7E : 0x10FFFF;
|
||||
|
||||
writeBook(random.ints(origin, bound)
|
||||
.filter(i -> !Character.isWhitespace(i)
|
||||
&& i != '\r' && i != '\n')
|
||||
.iterator()
|
||||
);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
private void onDisconnect(DisconnectEvent event) {
|
||||
if (toggleOnDisconnect.getValue()) {
|
||||
toggle();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeBook(PrimitiveIterator.OfInt chars) {
|
||||
ArrayList<String> pages = new ArrayList<>();
|
||||
ArrayList<RawFilteredPair<Text>> filteredPages = new ArrayList<>();
|
||||
int maxPages = this.pages.getIntValue();
|
||||
|
||||
TextHandler.WidthRetriever widthRetriever = mc.textRenderer.getTextHandler().widthRetriever;
|
||||
int pageIndex = 0;
|
||||
int lineIndex = 0;
|
||||
final StringBuilder page = new StringBuilder();
|
||||
float lineWidth = 0;
|
||||
|
||||
while (chars.hasNext() && pageIndex < maxPages) {
|
||||
int c = chars.nextInt();
|
||||
|
||||
if (c == '\r' || c == '\n') {
|
||||
page.append('\n');
|
||||
lineWidth = 0;
|
||||
lineIndex++;
|
||||
} else {
|
||||
float charWidth = widthRetriever.getWidth(c, Style.EMPTY);
|
||||
|
||||
if (lineWidth + charWidth > 114f) {
|
||||
page.append('\n');
|
||||
lineWidth = charWidth;
|
||||
lineIndex++;
|
||||
if (lineIndex != 14) page.appendCodePoint(c);
|
||||
} else if (lineWidth == 0f && c == ' ') {
|
||||
continue;
|
||||
} else {
|
||||
lineWidth += charWidth;
|
||||
page.appendCodePoint(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (lineIndex == 14) {
|
||||
filteredPages.add(RawFilteredPair.of(Text.of(page.toString())));
|
||||
pages.add(page.toString());
|
||||
page.setLength(0);
|
||||
pageIndex++;
|
||||
lineIndex = 0;
|
||||
lineWidth = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!page.isEmpty() && pageIndex < maxPages) {
|
||||
filteredPages.add(RawFilteredPair.of(Text.of(page.toString())));
|
||||
pages.add(page.toString());
|
||||
}
|
||||
|
||||
if (bookCount > 0) {
|
||||
ChatUtil.info("creado libro n. " + bookCount);
|
||||
}
|
||||
|
||||
createBook(pages, filteredPages);
|
||||
}
|
||||
|
||||
private void processLinesToPages(List<StringVisitable> lines, ArrayList<String> pages, ArrayList<RawFilteredPair<Text>> filteredPages, int maxPages) {
|
||||
int pageIndex = 0;
|
||||
int lineIndex = 0;
|
||||
StringBuilder currentPage = new StringBuilder();
|
||||
|
||||
for (StringVisitable line : lines) {
|
||||
String lineText = line.getString();
|
||||
|
||||
if (!currentPage.isEmpty()) {
|
||||
currentPage.append('\n');
|
||||
}
|
||||
|
||||
currentPage.append(lineText);
|
||||
lineIndex++;
|
||||
|
||||
if (lineIndex == 14) {
|
||||
filteredPages.add(RawFilteredPair.of(Text.of(currentPage.toString())));
|
||||
pages.add(currentPage.toString());
|
||||
currentPage.setLength(0);
|
||||
pageIndex++;
|
||||
lineIndex = 0;
|
||||
|
||||
if (pageIndex == maxPages) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentPage.isEmpty() && pageIndex < maxPages) {
|
||||
filteredPages.add(RawFilteredPair.of(Text.of(currentPage.toString())));
|
||||
pages.add(currentPage.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void createBook(ArrayList<String> pages, ArrayList<RawFilteredPair<Text>> filteredPages) {
|
||||
String title = name.getValue();
|
||||
if (count.getValue() && bookCount != 0) title += " #" + bookCount;
|
||||
|
||||
mc.player.getMainHandStack().set(DataComponentTypes.WRITTEN_BOOK_CONTENT, new WrittenBookContentComponent(
|
||||
RawFilteredPair.of(title),
|
||||
mc.player.getGameProfile().name(),
|
||||
0,
|
||||
filteredPages,
|
||||
true
|
||||
));
|
||||
|
||||
mc.player.networkHandler.sendPacket(new BookUpdateC2SPacket(
|
||||
mc.player.getInventory().getSelectedSlot(),
|
||||
pages,
|
||||
sign.getValue()
|
||||
? Optional.of(title)
|
||||
: Optional.empty()
|
||||
));
|
||||
|
||||
bookCount++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package me.retucio.sputnik.module.modules.misc;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||
import me.retucio.sputnik.event.SubscribeEvent;
|
||||
import me.retucio.sputnik.event.events.network.DisconnectEvent;
|
||||
import me.retucio.sputnik.event.events.network.PacketEvent;
|
||||
import me.retucio.sputnik.module.Category;
|
||||
import me.retucio.sputnik.module.Module;
|
||||
import me.retucio.sputnik.module.setting.settings.NumberSetting;
|
||||
import me.retucio.sputnik.util.ChatUtil;
|
||||
import net.minecraft.network.packet.c2s.common.KeepAliveC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import net.minecraft.screen.sync.ItemStackHash;
|
||||
import net.minecraft.util.Hand;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
// versión simplificada del módulo de Numberz y Nummernuts, del mod de DupersUnited (https://discord.gg/dupes)
|
||||
public class BundleDupe extends Module {
|
||||
|
||||
private final NumberSetting timeoutSeconds = sgGeneral.add(new NumberSetting(
|
||||
"tiempo de espera",
|
||||
"tiempo a esperar en segundos antes de ser kickeado",
|
||||
30,
|
||||
1,
|
||||
120,
|
||||
1
|
||||
));
|
||||
|
||||
private final NumberSetting clickslotPackets = sgGeneral.add(new NumberSetting(
|
||||
"paquetes",
|
||||
"paquetes a enviar",
|
||||
200,
|
||||
1,
|
||||
1000,
|
||||
1
|
||||
));
|
||||
|
||||
private boolean cancelKeepAlive = false;
|
||||
private boolean dupeActivated = false;
|
||||
private boolean waitingForKeepAlive = false;
|
||||
|
||||
private final ScheduledExecutorService delayedExecutor = new ScheduledThreadPoolExecutor(2);
|
||||
|
||||
public BundleDupe() {
|
||||
super("dupe de bundle",
|
||||
"dupea items usando un bundle y un libro",
|
||||
Category.MISC
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
dupeActivated = true;
|
||||
dupe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
this.cancelKeepAlive = false;
|
||||
this.dupeActivated = false;
|
||||
this.waitingForKeepAlive = false;
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
private void onDisconnect(DisconnectEvent event) {
|
||||
this.toggle();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
private void onPacketSend(PacketEvent.Send event) {
|
||||
if (this.dupeActivated && event.getPacket() instanceof PlayerActionC2SPacket) {
|
||||
event.cancel();
|
||||
}
|
||||
|
||||
if (event.getPacket() instanceof KeepAliveC2SPacket) {
|
||||
if (waitingForKeepAlive) {
|
||||
waitingForKeepAlive = false;
|
||||
cancelKeepAlive = true;
|
||||
ChatUtil.info("KeepAlive enviado, esperando " + this.timeoutSeconds.getValue() + " segundos...");
|
||||
delayedExecutor.schedule(() -> {
|
||||
if (isEnabled()) {
|
||||
sendInteractItem();
|
||||
sendClickSlots();
|
||||
toggle();
|
||||
}
|
||||
}, timeoutSeconds.getIntValue() * 1000L, TimeUnit.MILLISECONDS);
|
||||
} else if (cancelKeepAlive) {
|
||||
event.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dupe() {
|
||||
if (mc.player == null || mc.getNetworkHandler() == null) return;
|
||||
|
||||
sendClickSlots();
|
||||
sendInteractItem();
|
||||
mc.getNetworkHandler().sendPacket(PlayerInteractEntityC2SPacket.attack(mc.player, false));
|
||||
|
||||
sendClickSlots();
|
||||
delayedExecutor.schedule(() -> {
|
||||
if (isEnabled()) {
|
||||
this.toggle();
|
||||
}
|
||||
}, 100L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void sendInteractItem() {
|
||||
if (mc.player == null || mc.getNetworkHandler() == null) return;
|
||||
|
||||
PlayerInteractItemC2SPacket packet = new PlayerInteractItemC2SPacket(Hand.MAIN_HAND, 0, mc.player.getYaw(), this.mc.player.getPitch());
|
||||
mc.getNetworkHandler().sendPacket(packet);
|
||||
}
|
||||
|
||||
private void sendClickSlots() {
|
||||
if (mc.player == null || mc.getNetworkHandler() == null) return;
|
||||
|
||||
for (int i = 0; i < this.clickslotPackets.getIntValue(); i++) {
|
||||
ClickSlotC2SPacket packet = new ClickSlotC2SPacket(0, 0, (short) 0, (byte) 0, SlotActionType.PICKUP, new Int2ObjectArrayMap<>(), ItemStackHash.EMPTY);
|
||||
this.mc.getNetworkHandler().sendPacket(packet);
|
||||
}
|
||||
|
||||
ChatUtil.info(clickslotPackets.getIntValue() + " paquetes ClickSlot enviados");
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import net.minecraft.util.hit.HitResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// todo: implementar otros tipos de MLGs (cama, miel, slime, heno, ...)
|
||||
// todo: arreglar MLGs con bloques
|
||||
public class NoFall extends Module {
|
||||
|
||||
private boolean placed;
|
||||
|
||||
@@ -4,6 +4,7 @@ import me.retucio.sputnik.Sputnik;
|
||||
import me.retucio.sputnik.util.VersionChecker;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.Click;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.DirectionalLayoutWidget;
|
||||
@@ -21,8 +22,6 @@ public class UpdateScreen extends Screen {
|
||||
private final MinecraftClient mc = MinecraftClient.getInstance();
|
||||
private final DirectionalLayoutWidget grid = DirectionalLayoutWidget.vertical();
|
||||
|
||||
private final Text outdatedText = Text.of("version desactualizada: " + Sputnik.MOD_VERSION);
|
||||
private final Text updateText = Text.of("descarga la última versión (" + VersionChecker.getLatestVersion() + ") desde aquí:");
|
||||
private final URI updateLink = URI.create(FabricLoader.getInstance()
|
||||
.getModContainer(Sputnik.MOD_ID)
|
||||
.orElseThrow()
|
||||
@@ -33,6 +32,20 @@ public class UpdateScreen extends Screen {
|
||||
+ "/releases/latest"
|
||||
);
|
||||
|
||||
private final Text outdatedText = Text.of("version desactualizada: " + Sputnik.MOD_VERSION);
|
||||
private final Text updateText = Text.of("descarga la última versión (" + VersionChecker.getLatestVersion() + ") desde aquí:");
|
||||
|
||||
private final ButtonWidget idgafButton = ButtonWidget.builder(
|
||||
Text.of("me la pela"),
|
||||
button -> this.close()
|
||||
).build();
|
||||
|
||||
private final ButtonWidget updateButton = ButtonWidget.builder(
|
||||
Text.of("CLIC AQUÍ"),
|
||||
button -> handleOpenUri(mc, this, updateLink)
|
||||
).build();
|
||||
|
||||
|
||||
public UpdateScreen() {
|
||||
super(Text.literal(Formatting.BOLD + "actualizar"));
|
||||
}
|
||||
@@ -48,18 +61,7 @@ public class UpdateScreen extends Screen {
|
||||
|
||||
this.grid.getMainPositioner().margin(2);
|
||||
|
||||
ButtonWidget updateButton = ButtonWidget.builder(
|
||||
Text.of("CLIC AQUÍ"),
|
||||
button -> {
|
||||
handleOpenUri(mc, this, updateLink);
|
||||
}
|
||||
).build();
|
||||
this.grid.add(updateButton);
|
||||
|
||||
ButtonWidget idgafButton = ButtonWidget.builder(
|
||||
Text.of("me la pela"),
|
||||
button -> this.close()
|
||||
).build();
|
||||
this.grid.add(idgafButton);
|
||||
|
||||
this.grid.refreshPositions();
|
||||
@@ -76,4 +78,9 @@ public class UpdateScreen extends Screen {
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInterruptOtherScreen() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import net.minecraft.text.Text;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static me.retucio.sputnik.Sputnik.mc;
|
||||
|
||||
@@ -36,6 +37,17 @@ public class InventoryUtil {
|
||||
|
||||
private static Inventory echestInv;
|
||||
|
||||
public static ItemStack find(Predicate<ItemStack> predicate) {
|
||||
if (mc.player == null) return null;
|
||||
for (int i = 0; i <= mc.player.getInventory().size(); i++) {
|
||||
ItemStack stack = mc.player.getInventory().getStack(i);
|
||||
if (predicate.test(stack)) {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getStackOf(Item item) {
|
||||
if (mc.player == null) return null;
|
||||
for (ItemStack stack : mc.player.getInventory())
|
||||
@@ -82,6 +94,10 @@ public class InventoryUtil {
|
||||
mc.interactionManager.clickSlot(syncId, containerSlot1, 0, SlotActionType.PICKUP, mc.player);
|
||||
}
|
||||
|
||||
public static void swapWithHotbar(int containerSlot, int hotbarSlot) {
|
||||
swapWithHotbar(containerSlot, hotbarSlot, mc.player.playerScreenHandler);
|
||||
}
|
||||
|
||||
public static void swapWithHotbar(int containerSlot, int hotbarSlot, HandledScreen<?> screen) {
|
||||
swapWithHotbar(containerSlot, hotbarSlot, screen.getScreenHandler());
|
||||
}
|
||||
|
||||
@@ -34,16 +34,18 @@ public class VersionChecker {
|
||||
latestRemoteVersion = extract(gradleProperties);
|
||||
|
||||
if (latestRemoteVersion != null) {
|
||||
String remoteVersion = (latestRemoteVersion);
|
||||
String remoteVersion = cleanVersion(latestRemoteVersion);
|
||||
String localVersion = cleanVersion(currentVersion);
|
||||
|
||||
if (!remoteVersion.equals(localVersion)) {
|
||||
if (compareVersions(localVersion, remoteVersion) == -1) {
|
||||
updateAvailable = true;
|
||||
Sputnik.LOGGER.info("actualización disponible. local: {}, más reciente: {}",
|
||||
currentVersion, latestRemoteVersion);
|
||||
shouldShowScreen = true;
|
||||
} else {
|
||||
} else if (compareVersions(localVersion, remoteVersion) == 0){
|
||||
Sputnik.LOGGER.info("el mod está al día: v{}", currentVersion);
|
||||
} else {
|
||||
Sputnik.LOGGER.info("mod en estado de desarrollo: v{}", currentVersion);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -84,6 +86,32 @@ public class VersionChecker {
|
||||
return version.trim();
|
||||
}
|
||||
|
||||
private static int compareVersions(String version1, String version2) {
|
||||
if (version1 == null || version2 == null) return 0;
|
||||
|
||||
String[] parts1 = version1.split("\\.");
|
||||
String[] parts2 = version2.split("\\.");
|
||||
|
||||
int maxLength = Math.max(parts1.length, parts2.length);
|
||||
|
||||
for (int i = 0; i < maxLength; i++) {
|
||||
int v1 = (i < parts1.length) ? parseVersionPart(parts1[i]) : 0;
|
||||
int v2 = (i < parts2.length) ? parseVersionPart(parts2[i]) : 0;
|
||||
|
||||
if (v1 < v2) return -1;
|
||||
if (v1 > v2) return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int parseVersionPart(String part) {
|
||||
try {
|
||||
return Integer.parseInt(part);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static URI getFileURI() {
|
||||
try {
|
||||
|
||||
@@ -14,6 +14,7 @@ accessible class net/minecraft/client/network/ClientCommonNetworkHandler$Confirm
|
||||
# texto
|
||||
accessible method net/minecraft/client/font/FontManager getStorageInternal (Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/font/FontStorage;
|
||||
accessible class net/minecraft/client/font/TextRenderer$Drawer
|
||||
accessible field net/minecraft/client/font/TextHandler widthRetriever Lnet/minecraft/client/font/TextHandler$WidthRetriever;
|
||||
|
||||
# entidad
|
||||
accessible field net/minecraft/entity/LivingEntity jumpingCooldown I
|
||||
|
||||
Reference in new issue
Block a user