From 880e5560b78d4d81e9a34871f615f6e1d764600b Mon Sep 17 00:00:00 2001 From: Casefir <106693177+Casefir@users.noreply.github.com> Date: Fri, 6 Nov 2026 20:54:18 -0700 Subject: [PATCH 1/7] Rebrand README to Krypto Client --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 07237743e42..2f5af0bb2c9 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -

-meteor-client-logo +krypto-client-logo

-

Meteor

+

Krypto

A Minecraft Fabric Utility Mod for anarchy servers.

@@ -43,7 +42,7 @@ Please provide as much information as you can to best help us understand your is All of our work is completely free and non-profit (donations pay only for hosting costs), therefore we are very grateful for all donations made to support us in running our community. Donations can be made via our [website](https://meteorclient.com/donate) and the minimum amount to get donor benefits is €5. You will be rewarded with a role on our Discord server and a customisable in-game cape. -⚠️ _Make sure to create a Meteor account and link your Discord and Minecraft accounts to fully experience your rewards._ ⚠️ +⚠️ _Make sure to create a Krypto account and link your Discord and Minecraft accounts to fully experience your rewards._ ⚠️ ## Credits [Cabaletta](https://github.com/cabaletta) and [WagYourTail](https://github.com/wagyourtail) for [Baritone](https://github.com/cabaletta/baritone) @@ -53,7 +52,7 @@ The [Fabric Team](https://github.com/FabricMC) for [Fabric](https://github.com/F This project is licensed under the [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html). If you use **ANY** code from the source: -- You must disclose the source code of your modified work and the source code you took from this project. This means you are not allowed to use code from this project (even partially) in a closed-source and/or obfuscated application. +- You must disclose the source code of your modified work and the source code you took from this project. This means you are not allowed to use code from this project (even partially) in a closed-source application. - You must state clearly and obviously to all end users that you are using code from this project. - Your application must also be licensed under the same license. From 27148757f938593667e8a97bc7471e49d8c13795 Mon Sep 17 00:00:00 2001 From: Casefir <106693177+Casefir@users.noreply.github.com> Date: Fri, 6 Nov 2026 20:57:52 -0700 Subject: [PATCH 2/7] Clarify README description as upstream fork of Meteor Client Updated project description to clarify that this is an upstream fork of Meteor Client. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f5af0bb2c9..4c080844213 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

Krypto

-

A Minecraft Fabric Utility Mod for anarchy servers.

+

A upstream fork of Meteor Client, A Minecraft Fabric Utility Mod for anarchy servers.

Discord From 7fbd8ddd8a1f355136835a1e85f79f8c04813847 Mon Sep 17 00:00:00 2001 From: Casefir <106693177+Casefir@users.noreply.github.com> Date: Sat, 7 Nov 2026 09:13:08 -0700 Subject: [PATCH 3/7] Revise issue tracker link and clean up README Updated issue tracker link and removed donation section. --- README.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4c080844213..b8b91677244 100644 --- a/README.md +++ b/README.md @@ -35,15 +35,9 @@ We will review and help with all reasonable pull requests as long as the guideli - If you need help, check out the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html) for a reference. ## Bugs and Suggestions -Bug reports and suggestions should be made in this repo's [issue tracker](https://github.com/MeteorDevelopment/meteor-client/issues) using the templates provided. +Bug reports and suggestions should be made in this repo's [issue tracker](https://github.com/casefir/krypto-client/issues) using the templates provided. Please provide as much information as you can to best help us understand your issue and give a better chance of it being resolved. -## Donations -All of our work is completely free and non-profit (donations pay only for hosting costs), therefore we are very grateful for all donations made to support us in running our community. -Donations can be made via our [website](https://meteorclient.com/donate) and the minimum amount to get donor benefits is €5. -You will be rewarded with a role on our Discord server and a customisable in-game cape. -⚠️ _Make sure to create a Krypto account and link your Discord and Minecraft accounts to fully experience your rewards._ ⚠️ - ## Credits [Cabaletta](https://github.com/cabaletta) and [WagYourTail](https://github.com/wagyourtail) for [Baritone](https://github.com/cabaletta/baritone) The [Fabric Team](https://github.com/FabricMC) for [Fabric](https://github.com/FabricMC/fabric-loader) and [Yarn](https://github.com/FabricMC/yarn) @@ -54,6 +48,6 @@ This project is licensed under the [GNU General Public License v3.0](https://www If you use **ANY** code from the source: - You must disclose the source code of your modified work and the source code you took from this project. This means you are not allowed to use code from this project (even partially) in a closed-source application. - You must state clearly and obviously to all end users that you are using code from this project. -- Your application must also be licensed under the same license. +- Your application must also be licensed under the same license. [METOR CLIENT](https://github.com/MetorDevelopment/) -*If you have any other questions, check our [FAQ](https://meteorclient.com/faq) or ask in our [Discord](https://meteorclient.com/discord) server.* +*If you have any other questions, check our [FAQ](https://meteorclient.com/faq)* From 57ed454253aeb316c4b93a1c59886901a3a4d0a9 Mon Sep 17 00:00:00 2001 From: Casefir <106693177+Casefir@users.noreply.github.com> Date: Sat, 7 Nov 2026 09:56:32 -0700 Subject: [PATCH 4/7] Add client-side player load notifier module --- .../meteorclient/systems/modules/Modules.java | 1 + .../modules/misc/PlayerLoadNotifier.java | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/main/java/meteordevelopment/meteorclient/systems/modules/misc/PlayerLoadNotifier.java diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java index 99cdcb14e2b..3e0fffc806d 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java @@ -589,6 +589,7 @@ private void initMisc() { add(new Notifier()); add(new PacketCanceller()); add(new PacketLogger()); + add(new PlayerLoadNotifier()); add(new ServerSpoof()); add(new SoundBlocker()); add(new Spam()); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/PlayerLoadNotifier.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/PlayerLoadNotifier.java new file mode 100644 index 00000000000..55c253c4c36 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/PlayerLoadNotifier.java @@ -0,0 +1,25 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.systems.modules.misc; + +import meteordevelopment.meteorclient.events.entity.EntityAddedEvent; +import meteordevelopment.meteorclient.systems.modules.Categories; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.world.entity.player.Player; + +public class PlayerLoadNotifier extends Module { + public PlayerLoadNotifier() { + super(Categories.Misc, "player-load-notifier", "Notifies you when another player loads into your client world."); + } + + @EventHandler + private void onEntityAdded(EntityAddedEvent event) { + if (!(event.entity instanceof Player player) || mc.player == null || player == mc.player) return; + + info("%s loaded.", player.getName().getString()); + } +} From 01d721800b8c289d48aa09051a8da05f0173a680 Mon Sep 17 00:00:00 2001 From: Casefir <106693177+Casefir@users.noreply.github.com> Date: Sat, 7 Nov 2026 13:28:00 -0700 Subject: [PATCH 5/7] Remove badges and Discord link from README Removed shield images and Discord link from README. --- README.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/README.md b/README.md index b8b91677244..f69a028ff18 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,6 @@

Krypto

A upstream fork of Meteor Client, A Minecraft Fabric Utility Mod for anarchy servers.

-
- Discord -
- GitHub last commit - GitHub commit activity - GitHub contributors -
- GitHub code size in bytes - GitHub lines of code -
- ## Usage ### Building From f61539c0e5c93dd0bfe3a8027042484012495ece Mon Sep 17 00:00:00 2001 From: Casefir <106693177+Casefir@users.noreply.github.com> Date: Sun, 8 Nov 2026 15:27:01 -0700 Subject: [PATCH 6/7] Add persistent player history and search command --- .../meteorclient/commands/Commands.java | 1 + .../commands/PlayerHistoryCommand.java | 68 ++++++ .../meteorclient/systems/Systems.java | 2 + .../systems/playerhistory/PlayerHistory.java | 204 ++++++++++++++++++ 4 files changed, 275 insertions(+) create mode 100644 src/main/java/meteordevelopment/meteorclient/commands/commands/PlayerHistoryCommand.java create mode 100644 src/main/java/meteordevelopment/meteorclient/systems/playerhistory/PlayerHistory.java diff --git a/src/main/java/meteordevelopment/meteorclient/commands/Commands.java b/src/main/java/meteordevelopment/meteorclient/commands/Commands.java index f5e2d99451e..350af807915 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/Commands.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/Commands.java @@ -60,6 +60,7 @@ public static void init() { add(new BindsCommand()); add(new GiveCommand()); add(new NameHistoryCommand()); + add(new PlayerHistoryCommand()); add(new BindCommand()); add(new FovCommand()); add(new RotationCommand()); diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/PlayerHistoryCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/PlayerHistoryCommand.java new file mode 100644 index 00000000000..264b29efd62 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/PlayerHistoryCommand.java @@ -0,0 +1,68 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.commands.commands; + +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import meteordevelopment.meteorclient.commands.Command; +import meteordevelopment.meteorclient.systems.playerhistory.PlayerHistory; +import net.minecraft.client.multiplayer.ClientSuggestionProvider; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +public class PlayerHistoryCommand extends Command { + private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") + .withZone(ZoneId.systemDefault()); + + public PlayerHistoryCommand() { + super("player-history", "Searches your locally saved player sightings.", "phistory"); + } + + @Override + public void build(LiteralArgumentBuilder builder) { + builder.then(literal("search") + .then(argument("player", StringArgumentType.word()).executes(context -> { + String query = StringArgumentType.getString(context, "player"); + var results = PlayerHistory.get().search(query); + + if (results.isEmpty()) { + info("No saved sightings found for %s.", query); + return SINGLE_SUCCESS; + } + + info("--- Player sightings for %s (latest %d) ---", query, results.size()); + for (PlayerHistory.Sighting sighting : results) { + info("%s: %s at %d, %d, %d in %s; gear: %s", + sighting.name, + DATE_FORMAT.format(Instant.ofEpochMilli(sighting.timestamp)), + sighting.x, sighting.y, sighting.z, + sighting.dimension, + sighting.gear + ); + } + return SINGLE_SUCCESS; + })) + ); + + builder.then(literal("list").executes(_ -> { + info("Player history contains %d sightings. Search with %s search .", PlayerHistory.get().size(), this); + return SINGLE_SUCCESS; + })); + + builder.then(literal("clear").executes(_ -> { + PlayerHistory.get().clear(); + info("Cleared player history for this server."); + return SINGLE_SUCCESS; + })); + + builder.executes(_ -> { + info("Use %s search , %s list, or %s clear.", this, this, this); + return SINGLE_SUCCESS; + }); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/systems/Systems.java b/src/main/java/meteordevelopment/meteorclient/systems/Systems.java index 803d5706b84..1d33ca1b53d 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/Systems.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/Systems.java @@ -14,6 +14,7 @@ import meteordevelopment.meteorclient.systems.hud.Hud; import meteordevelopment.meteorclient.systems.macros.Macros; import meteordevelopment.meteorclient.systems.modules.Modules; +import meteordevelopment.meteorclient.systems.playerhistory.PlayerHistory; import meteordevelopment.meteorclient.systems.profiles.Profiles; import meteordevelopment.meteorclient.systems.proxies.Proxies; import meteordevelopment.meteorclient.systems.waypoints.Waypoints; @@ -49,6 +50,7 @@ public static void init() { add(new Friends()); add(new Accounts()); add(new Waypoints()); + add(new PlayerHistory()); add(new Profiles()); add(new Proxies()); add(new Hud()); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/playerhistory/PlayerHistory.java b/src/main/java/meteordevelopment/meteorclient/systems/playerhistory/PlayerHistory.java new file mode 100644 index 00000000000..80abe7c7d89 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/systems/playerhistory/PlayerHistory.java @@ -0,0 +1,204 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.systems.playerhistory; + +import meteordevelopment.meteorclient.MeteorClient; +import meteordevelopment.meteorclient.events.entity.EntityAddedEvent; +import meteordevelopment.meteorclient.events.game.GameJoinedEvent; +import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.systems.System; +import meteordevelopment.meteorclient.systems.Systems; +import meteordevelopment.meteorclient.utils.Utils; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.core.UUIDUtil; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import org.jspecify.annotations.NonNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.UUID; + +public class PlayerHistory extends System { + private static final long RECORD_INTERVAL_MS = 30_000; + private static final int MAX_ENTRIES = 10_000; + private static final int MAX_RESULTS = 5; + + private final List sightings = new ArrayList<>(); + private final java.util.Map lastRecorded = new java.util.HashMap<>(); + private long nextPeriodicRecord; + + public PlayerHistory() { + super(null); + } + + public static PlayerHistory get() { + return Systems.get(PlayerHistory.class); + } + + @EventHandler + private void onGameJoined(GameJoinedEvent event) { + sightings.clear(); + lastRecorded.clear(); + load(); + nextPeriodicRecord = 0; + } + + @EventHandler + private void onEntityAdded(EntityAddedEvent event) { + if (event.entity instanceof Player player) record(player); + } + + @EventHandler + private void onTick(TickEvent.Post event) { + if (System.currentTimeMillis() < nextPeriodicRecord || mc.level == null) return; + + nextPeriodicRecord = System.currentTimeMillis() + RECORD_INTERVAL_MS; + for (Player player : mc.level.players()) record(player); + } + + private void record(Player player) { + if (mc.player == null || mc.level == null || player == mc.player) return; + + long now = System.currentTimeMillis(); + Long previous = lastRecorded.get(player.getUUID()); + if (previous != null && now - previous < RECORD_INTERVAL_MS) return; + lastRecorded.put(player.getUUID(), now); + + sightings.add(new Sighting( + player.getUUID(), + player.getName().getString(), + now, + mc.level.dimension().identifier().toString(), + player.getBlockX(), + player.getBlockY(), + player.getBlockZ(), + getGear(player) + )); + + if (sightings.size() > MAX_ENTRIES) sightings.removeFirst(); + save(); + } + + private String getGear(Player player) { + return "head=" + itemName(player.getItemBySlot(EquipmentSlot.HEAD)) + + ", chest=" + itemName(player.getItemBySlot(EquipmentSlot.CHEST)) + + ", legs=" + itemName(player.getItemBySlot(EquipmentSlot.LEGS)) + + ", feet=" + itemName(player.getItemBySlot(EquipmentSlot.FEET)) + + ", mainhand=" + itemName(player.getMainHandItem()) + + ", offhand=" + itemName(player.getOffhandItem()); + } + + private String itemName(ItemStack stack) { + return stack.isEmpty() ? "empty" : stack.getHoverName().getString(); + } + + public List search(String name) { + String query = name.toLowerCase(java.util.Locale.ROOT); + return sightings.stream() + .filter(sighting -> sighting.name.toLowerCase(java.util.Locale.ROOT).contains(query)) + .sorted(Comparator.comparingLong((Sighting sighting) -> sighting.timestamp).reversed()) + .limit(MAX_RESULTS) + .toList(); + } + + public int size() { + return sightings.size(); + } + + public void clear() { + sightings.clear(); + lastRecorded.clear(); + save(); + } + + @Override + public File getFile() { + if (!Utils.canUpdate()) return null; + return new File(new File(MeteorClient.FOLDER, "player-history"), Utils.getFileWorldName() + ".nbt"); + } + + @Override + public CompoundTag toTag() { + CompoundTag tag = new CompoundTag(); + ListTag list = new ListTag(); + for (Sighting sighting : sightings) list.add(sighting.toTag()); + tag.put("sightings", list); + return tag; + } + + @Override + public PlayerHistory fromTag(CompoundTag tag) { + sightings.clear(); + lastRecorded.clear(); + + for (Tag item : tag.getListOrEmpty("sightings")) { + if (!(item instanceof CompoundTag sightingTag)) continue; + try { + Sighting sighting = new Sighting(sightingTag); + sightings.add(sighting); + lastRecorded.merge(sighting.uuid, sighting.timestamp, Math::max); + } catch (IllegalArgumentException ignored) { + // Ignore malformed records while preserving the rest of the history. + } + } + + if (sightings.size() > MAX_ENTRIES) { + sightings.subList(0, sightings.size() - MAX_ENTRIES).clear(); + } + return this; + } + + public static class Sighting { + public final UUID uuid; + public final String name; + public final long timestamp; + public final String dimension; + public final int x, y, z; + public final String gear; + + private Sighting(UUID uuid, String name, long timestamp, String dimension, int x, int y, int z, String gear) { + this.uuid = uuid; + this.name = name; + this.timestamp = timestamp; + this.dimension = dimension; + this.x = x; + this.y = y; + this.z = z; + this.gear = gear; + } + + private Sighting(CompoundTag tag) { + this.uuid = tag.read("uuid", UUIDUtil.CODEC).orElseThrow(() -> new IllegalArgumentException("Missing UUID")); + this.name = tag.getStringOr("name", ""); + this.timestamp = tag.getLongOr("timestamp", 0); + this.dimension = tag.getStringOr("dimension", "unknown"); + this.x = tag.getIntOr("x", 0); + this.y = tag.getIntOr("y", 0); + this.z = tag.getIntOr("z", 0); + this.gear = tag.getStringOr("gear", "unknown"); + } + + private CompoundTag toTag() { + CompoundTag tag = new CompoundTag(); + tag.store("uuid", UUIDUtil.CODEC, uuid); + tag.putString("name", name); + tag.putLong("timestamp", timestamp); + tag.putString("dimension", dimension); + tag.putInt("x", x); + tag.putInt("y", y); + tag.putInt("z", z); + tag.putString("gear", gear); + return tag; + } + } +} From 89f57cf5f5ea5249910b2ccfca4da6bdb7cc1050 Mon Sep 17 00:00:00 2001 From: Casefir <106693177+Casefir@users.noreply.github.com> Date: Sun, 8 Nov 2026 19:09:15 -0700 Subject: [PATCH 7/7] Fix player history Minecraft accessor --- .../systems/playerhistory/PlayerHistory.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/playerhistory/PlayerHistory.java b/src/main/java/meteordevelopment/meteorclient/systems/playerhistory/PlayerHistory.java index 80abe7c7d89..a991ef49dd0 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/playerhistory/PlayerHistory.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/playerhistory/PlayerHistory.java @@ -20,12 +20,14 @@ import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import org.jspecify.annotations.NonNull; import java.io.File; import java.util.ArrayList; import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.UUID; public class PlayerHistory extends System { @@ -34,7 +36,7 @@ public class PlayerHistory extends System { private static final int MAX_RESULTS = 5; private final List sightings = new ArrayList<>(); - private final java.util.Map lastRecorded = new java.util.HashMap<>(); + private final Map lastRecorded = new HashMap<>(); private long nextPeriodicRecord; public PlayerHistory() { @@ -60,14 +62,14 @@ private void onEntityAdded(EntityAddedEvent event) { @EventHandler private void onTick(TickEvent.Post event) { - if (System.currentTimeMillis() < nextPeriodicRecord || mc.level == null) return; + if (System.currentTimeMillis() < nextPeriodicRecord || MeteorClient.mc.level == null) return; nextPeriodicRecord = System.currentTimeMillis() + RECORD_INTERVAL_MS; - for (Player player : mc.level.players()) record(player); + for (Player player : MeteorClient.mc.level.players()) record(player); } private void record(Player player) { - if (mc.player == null || mc.level == null || player == mc.player) return; + if (MeteorClient.mc.player == null || MeteorClient.mc.level == null || player == MeteorClient.mc.player) return; long now = System.currentTimeMillis(); Long previous = lastRecorded.get(player.getUUID()); @@ -78,7 +80,7 @@ private void record(Player player) { player.getUUID(), player.getName().getString(), now, - mc.level.dimension().identifier().toString(), + MeteorClient.mc.level.dimension().identifier().toString(), player.getBlockX(), player.getBlockY(), player.getBlockZ(), @@ -103,9 +105,9 @@ private String itemName(ItemStack stack) { } public List search(String name) { - String query = name.toLowerCase(java.util.Locale.ROOT); + String query = name.toLowerCase(Locale.ROOT); return sightings.stream() - .filter(sighting -> sighting.name.toLowerCase(java.util.Locale.ROOT).contains(query)) + .filter(sighting -> sighting.name.toLowerCase(Locale.ROOT).contains(query)) .sorted(Comparator.comparingLong((Sighting sighting) -> sighting.timestamp).reversed()) .limit(MAX_RESULTS) .toList();