From 94549c51e02934cae7488228dfd0ea35e21c55b0 Mon Sep 17 00:00:00 2001 From: MeexReay <127148610+MeexReay@users.noreply.github.com> Date: Mon, 29 May 2023 23:04:11 +0300 Subject: [PATCH] mega update --- .github/workflows/build.yml | 40 --- .gitignore | 40 --- build.gradle | 11 + gradle.properties | 18 +- .../java/net/fabricmc/example/ExampleMod.java | 21 -- .../fabricmc/example/mixin/ExampleMixin.java | 16 - .../themixray/repeating/mod/RepeatingMod.java | 338 ++++++++++++++++++ .../repeating/mod/mixin/MovementMixin.java | 92 +++++ src/main/resources/assets/modid/icon.png | Bin 453 -> 0 bytes .../assets/repeating-mod/lang/en_us.json | 26 ++ .../assets/repeating-mod/lang/ru_ru.json | 27 ++ src/main/resources/fabric.mod.json | 22 +- ....mixins.json => repeating-mod.mixins.json} | 5 +- 13 files changed, 518 insertions(+), 138 deletions(-) delete mode 100644 .github/workflows/build.yml delete mode 100644 .gitignore delete mode 100644 src/main/java/net/fabricmc/example/ExampleMod.java delete mode 100644 src/main/java/net/fabricmc/example/mixin/ExampleMixin.java create mode 100644 src/main/java/themixray/repeating/mod/RepeatingMod.java create mode 100644 src/main/java/themixray/repeating/mod/mixin/MovementMixin.java delete mode 100644 src/main/resources/assets/modid/icon.png create mode 100644 src/main/resources/assets/repeating-mod/lang/en_us.json create mode 100644 src/main/resources/assets/repeating-mod/lang/ru_ru.json rename src/main/resources/{modid.mixins.json => repeating-mod.mixins.json} (66%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index e2fa68a..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Automatically build the project and run any configured tests for every push -# and submitted pull request. This can help catch issues that only occur on -# certain platforms or Java versions, and provides a first line of defence -# against bad commits. - -name: build -on: [pull_request, push] - -jobs: - build: - strategy: - matrix: - # Use these Java versions - java: [ - 17, # Current Java LTS & minimum supported by Minecraft - ] - # and run on both Linux and Windows - os: [ubuntu-22.04, windows-2022] - runs-on: ${{ matrix.os }} - steps: - - name: checkout repository - uses: actions/checkout@v3 - - name: validate gradle wrapper - uses: gradle/wrapper-validation-action@v1 - - name: setup jdk ${{ matrix.java }} - uses: actions/setup-java@v3 - with: - java-version: ${{ matrix.java }} - distribution: 'microsoft' - - name: make gradle wrapper executable - if: ${{ runner.os != 'Windows' }} - run: chmod +x ./gradlew - - name: build - run: ./gradlew build - - name: capture build artifacts - if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from latest java on one OS - uses: actions/upload-artifact@v3 - with: - name: Artifacts - path: build/libs/ diff --git a/.gitignore b/.gitignore deleted file mode 100644 index c476faf..0000000 --- a/.gitignore +++ /dev/null @@ -1,40 +0,0 @@ -# gradle - -.gradle/ -build/ -out/ -classes/ - -# eclipse - -*.launch - -# idea - -.idea/ -*.iml -*.ipr -*.iws - -# vscode - -.settings/ -.vscode/ -bin/ -.classpath -.project - -# macos - -*.DS_Store - -# fabric - -run/ - -# java - -hs_err_*.log -replay_*.log -*.hprof -*.jfr diff --git a/build.gradle b/build.gradle index 5af2ddd..3c6b0f5 100644 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,7 @@ repositories { // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. // See https://docs.gradle.org/current/userguide/declaring_repositories.html // for more information about repositories. + maven { url 'https://maven.wispforest.io' } } dependencies { @@ -27,6 +28,16 @@ dependencies { // These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. // modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}" + + modImplementation "io.wispforest:owo-lib:${project.owo_version}" + // only if you plan to use owo-config + annotationProcessor "io.wispforest:owo-lib:${project.owo_version}" + + // include this if you don't want force your users to install owo + // sentinel will warn them and give the option to download it automatically + include "io.wispforest:owo-sentinel:${project.owo_version}" + // https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple + implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1' } base { diff --git a/gradle.properties b/gradle.properties index 710b01f..2bf89a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,15 +3,17 @@ org.gradle.jvmargs=-Xmx1G org.gradle.parallel=true # Fabric Properties - # check these on https://fabricmc.net/develop - minecraft_version=1.19.4 - yarn_mappings=1.19.4+build.1 - loader_version=0.14.17 +# check these on https://fabricmc.net/develop +minecraft_version=1.19.3 +yarn_mappings=1.19.3+build.1 +loader_version=0.14.17 # Mod Properties - mod_version = 1.0.0 - maven_group = com.example - archives_base_name = fabric-example-mod +mod_version = 1.0.0 +maven_group = themixray.repeating.mod +archives_base_name = repeating-mod # Dependencies - fabric_version=0.75.3+1.19.4 +fabric_version=0.76.1+1.19.3 + +owo_version=0.10.3+1.19.3 diff --git a/src/main/java/net/fabricmc/example/ExampleMod.java b/src/main/java/net/fabricmc/example/ExampleMod.java deleted file mode 100644 index a964189..0000000 --- a/src/main/java/net/fabricmc/example/ExampleMod.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.fabricmc.example; - -import net.fabricmc.api.ModInitializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ExampleMod implements ModInitializer { - // This logger is used to write text to the console and the log file. - // It is considered best practice to use your mod id as the logger's name. - // That way, it's clear which mod wrote info, warnings, and errors. - public static final Logger LOGGER = LoggerFactory.getLogger("modid"); - - @Override - public void onInitialize() { - // This code runs as soon as Minecraft is in a mod-load-ready state. - // However, some things (like resources) may still be uninitialized. - // Proceed with mild caution. - - LOGGER.info("Hello Fabric world!"); - } -} diff --git a/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java b/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java deleted file mode 100644 index 356cb38..0000000 --- a/src/main/java/net/fabricmc/example/mixin/ExampleMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.fabricmc.example.mixin; - -import net.fabricmc.example.ExampleMod; -import net.minecraft.client.gui.screen.TitleScreen; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(TitleScreen.class) -public class ExampleMixin { - @Inject(at = @At("HEAD"), method = "init()V") - private void init(CallbackInfo info) { - ExampleMod.LOGGER.info("This line is printed by an example mod mixin!"); - } -} diff --git a/src/main/java/themixray/repeating/mod/RepeatingMod.java b/src/main/java/themixray/repeating/mod/RepeatingMod.java new file mode 100644 index 0000000..40a36bf --- /dev/null +++ b/src/main/java/themixray/repeating/mod/RepeatingMod.java @@ -0,0 +1,338 @@ +package themixray.repeating.mod; + +import com.google.common.collect.Lists; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; +import net.fabricmc.fabric.api.renderer.v1.RendererAccess; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.util.InputUtil; +import net.minecraft.entity.MovementType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.resource.Resource; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourceType; +import net.minecraft.text.Text; +import net.minecraft.util.Hand; +import net.minecraft.util.Identifier; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import org.lwjgl.glfw.GLFW; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.InputStream; +import java.util.*; + +public class RepeatingMod implements ClientModInitializer { + public static final Logger LOGGER = LoggerFactory.getLogger("repeating-mod"); + public static final MinecraftClient client = MinecraftClient.getInstance(); + public static final FabricLoader loader = FabricLoader.getInstance(); + public static RepeatingMod me; + + public List record = new ArrayList<>(); + public boolean is_recording = false; + public Date last_record = null; + + public Thread replay = null; + public boolean is_replaying = false; + public boolean loop_replay = false; + public static boolean replay_sneaking = false; + + public static RepeatingScreen menu; + private static KeyBinding menu_key; + private static KeyBinding toggle_replay_key; + private static KeyBinding toggle_record_key; + + public double record_blocks_limit = 2; + public long record_time_limit = 50; + + public EasyConfig conf; + + @Override + public void onInitializeClient() { + LOGGER.info("Repeating mod initialized"); + me = this; + + Map def = new HashMap<>(); + def.put("record_blocks_limit", record_blocks_limit); + def.put("record_time_limit", record_time_limit); + conf = new EasyConfig(new File(loader.getConfigDir().toFile(),"repeating-mod").toPath(),def); + + record_blocks_limit = (double) conf.data.get("record_blocks_limit"); + record_time_limit = (long) conf.data.get("record_time_limit"); + + menu_key = KeyBindingHelper.registerKeyBinding(new KeyBinding( + "key.repeating-mod.menu",InputUtil.Type.KEYSYM, + GLFW.GLFW_KEY_J,"text.repeating-mod.name")); + toggle_replay_key = KeyBindingHelper.registerKeyBinding(new KeyBinding( + "key.repeating-mod.toggle_replay",InputUtil.Type.KEYSYM, + -1,"text.repeating-mod.name")); + toggle_record_key = KeyBindingHelper.registerKeyBinding(new KeyBinding( + "key.repeating-mod.toggle_record",InputUtil.Type.KEYSYM, + -1,"text.repeating-mod.name")); + + menu = new RepeatingScreen(); + ClientTickEvents.END_CLIENT_TICK.register(client -> { + if (menu_key.wasPressed()) { + client.setScreen(menu); + } + if (toggle_replay_key.wasPressed()) { + if (!is_recording) { + if (is_replaying) + stopReplay(); + else startReplay(); + menu.update_btns(); + } + } + if (toggle_record_key.wasPressed()) { + if (!is_replaying) { + if (is_recording) + stopRecording(); + else startRecording(); + menu.update_btns(); + } + } + }); + } + + public RecordEvent getLastRecord(String t) { + for (RecordEvent r:Lists.reverse(new ArrayList<>(record))) { + if (r.getType().equals(t)) { + return r; + } + } + return null; + } + + + public void startRecording() { + is_recording = true; + menu.update_btns(); + record.clear(); + sendMessage(Text.translatable("message.repeating-mod.record_start")); + } + + public void recordTick(RecordEvent e) { + Date now = new Date(); + if (last_record != null) { + long diff = now.getTime() - last_record.getTime(); + if (diff >= 0) record.add(new RecordDelayEvent(diff)); + } + record.add(e); + last_record = now; + } + + public void stopRecording() { + is_recording = false; + menu.update_btns(); + last_record = null; + sendMessage(Text.translatable("message.repeating-mod.record_stop")); + } + + + public void startReplay() { + is_recording = false; + is_replaying = true; + menu.update_btns(); + client.player.setNoGravity(true); + replay = new Thread(() -> { + while (true) { + for (RecordEvent e : record) + if (is_replaying) + e.callback(); + if (!loop_replay || !is_replaying) break; + } + stopReplay(); + }); + replay.start(); + sendMessage(Text.translatable("message.repeating-mod.replay_start")); + } + + public void stopReplay() { + is_recording = false; + is_replaying = false; + menu.update_btns(); + client.player.setNoGravity(false); + sendMessage(Text.translatable("message.repeating-mod.replay_stop")); + } + + public static double round(double value, int places) { + if (places < 0) throw new IllegalArgumentException(); + long factor = (long) Math.pow(10, places); + return (double) Math.round(value * factor) / factor; + } + + public static void sendMessage(Text text) { + client.player.sendMessage(Text.literal("[") + .append(Text.translatable("text.repeating-mod.name")) + .append("] ").append(text)); + } + + public static abstract class RecordEvent { + abstract void callback(); + abstract String toText(); + abstract String getType(); + + public static RecordEvent fromText(String t) { + try { + String type = String.valueOf(t.charAt(0)); + String[] args = t.substring(2).split("&"); + if (type.equals("d")) { + return new RecordDelayEvent( + Long.parseLong(args[0])); + } else if (type.equals("m")) { + return new RecordMoveEvent(new Vec3d( + Double.parseDouble(args[0]), + Double.parseDouble(args[1]), + Double.parseDouble(args[2])), + Float.parseFloat(args[3]), + Float.parseFloat(args[4])); + } else if (type.equals("s")) { + return new RecordSneakEvent( + args[0].equals("1")); + } else if (type.equals("b")) { + return new RecordBlockBreakEvent(new BlockPos( + Integer.parseInt(args[0]), + Integer.parseInt(args[1]), + Integer.parseInt(args[2]))); + } else if (type.equals("i")) { + return new RecordBlockInteractEvent( + Hand.valueOf(args[5]), + new BlockHitResult(new Vec3d( + Double.parseDouble(args[0]), + Double.parseDouble(args[1]), + Double.parseDouble(args[2])), + Direction.byId(Integer.parseInt(args[4])), + new BlockPos( + Integer.parseInt(args[0]), + Integer.parseInt(args[1]), + Integer.parseInt(args[2])), + args[3].equals("1"))); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + } + + public static class RecordDelayEvent extends RecordEvent { + public long delay; + + public RecordDelayEvent(long delay) { + this.delay = delay; + } + + public void callback() { + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public String toText() { + return "d="+delay; + } + public String getType() { + return "delay"; + } + } + + public static class RecordMoveEvent extends RecordEvent { + public Vec3d vec; + public float yaw; + public float pitch; + + public RecordMoveEvent(Vec3d vec,float yaw,float pitch) { + this.vec = vec; + this.yaw = yaw; + this.pitch = pitch; + } + + public void callback() { + Vec3d p = client.player.getPos(); + Vec3d v = new Vec3d(vec.getX()-p.getX(),vec.getY()-p.getY(),vec.getZ()-p.getZ()); + client.player.move(MovementType.SELF,v); + client.player.setYaw(yaw); + client.player.setPitch(pitch); + } + + public String toText() { + return "m="+vec.getX()+"&"+vec.getY()+"&"+vec.getZ()+"&"+yaw+"&"+pitch; + } + public String getType() { + return "move"; + } + } + + public static class RecordSneakEvent extends RecordEvent { + public boolean sneaking; + + public RecordSneakEvent(boolean sneaking) { + this.sneaking = sneaking; + } + + public void callback() { + RepeatingMod.replay_sneaking = sneaking; + } + + public String toText() { + return "s="+(sneaking?"1":"0"); + } + public String getType() { + return "sneak"; + } + } + + public static class RecordBlockBreakEvent extends RecordEvent { + public BlockPos pos; + + public RecordBlockBreakEvent( + BlockPos pos) { + this.pos = pos; + } + + public void callback() { + client.interactionManager.breakBlock(pos); + } + + public String toText() { + return "b="+pos.getX()+"&"+pos.getY()+"&"+pos.getZ(); + } + public String getType() { + return "block_break"; + } + } + + public static class RecordBlockInteractEvent extends RecordEvent { + public Hand hand; + public BlockHitResult hitResult; + + public RecordBlockInteractEvent(Hand hand, BlockHitResult hitResult) { + this.hand = hand; + this.hitResult = hitResult; + } + + public void callback() { + client.interactionManager.interactBlock(client.player,hand,hitResult); + } + + public String toText() { + return "i="+hitResult.getBlockPos().getX()+"&"+hitResult.getBlockPos().getY()+"&"+hitResult.getBlockPos().getZ()+ + "&"+(hitResult.isInsideBlock()?"1":"0")+"&"+hitResult.getSide().getId()+"&"+hand.name(); + } + public String getType() { + return "block_interact"; + } + } +} diff --git a/src/main/java/themixray/repeating/mod/mixin/MovementMixin.java b/src/main/java/themixray/repeating/mod/mixin/MovementMixin.java new file mode 100644 index 0000000..83a18e5 --- /dev/null +++ b/src/main/java/themixray/repeating/mod/mixin/MovementMixin.java @@ -0,0 +1,92 @@ +package themixray.repeating.mod.mixin; + +import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents; +import net.fabricmc.fabric.api.event.player.UseBlockCallback; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.entity.MovementType; +import net.minecraft.text.Text; +import net.minecraft.util.ActionResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.Vec3d; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import themixray.repeating.mod.RepeatingMod; + +import java.util.Date; + +@Mixin(ClientPlayerEntity.class) +public abstract class MovementMixin { + public Vec3d lastVec = null; + @Shadow public abstract void sendMessage(Text message); + @Shadow @Final protected MinecraftClient client; + @Shadow public abstract float getYaw(float tickDelta); + @Shadow private float lastYaw; + @Shadow private float lastPitch; + + @Inject(at = @At(value = "HEAD"), method = "init") + private void init(CallbackInfo ci) { + PlayerBlockBreakEvents.AFTER.register((world, player, pos, blockState, blockEntity) -> { + if (RepeatingMod.me.is_recording) + RepeatingMod.me.recordTick(new RepeatingMod.RecordBlockBreakEvent(pos)); + }); + + UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> { + if (hitResult.getType().equals(HitResult.Type.BLOCK)) + if (RepeatingMod.me.is_recording) + RepeatingMod.me.recordTick(new RepeatingMod.RecordBlockInteractEvent(hand,hitResult)); + return ActionResult.PASS; + }); + } + + @Inject(at = @At(value = "HEAD"), method = "move") + private void onMove(MovementType movementType, Vec3d vec, CallbackInfo ci) { + if (RepeatingMod.me.is_recording) { + if (vec != lastVec) { + double dist = 0; + if (lastVec != null) + dist = vec.distanceTo(lastVec); + if (dist > 0.0) { + Vec3d c = client.player.getPos(); + + RepeatingMod.RecordMoveEvent ev = new RepeatingMod.RecordMoveEvent( + new Vec3d(c.getX() + vec.getX(), + c.getY() + vec.getY(), + c.getZ() + vec.getZ()), + lastYaw, lastPitch); + + boolean just_add = true; + Date now = new Date(); + if (RepeatingMod.me.last_record != null) { + long diff = now.getTime() - RepeatingMod.me.last_record.getTime(); + boolean add_delay = true; + if (diff > 0) { + RepeatingMod.RecordEvent last_ev = RepeatingMod.me.record.get(RepeatingMod.me.record.size()-1); + if (last_ev instanceof RepeatingMod.RecordMoveEvent) { + RepeatingMod.RecordMoveEvent last_ev1 = (RepeatingMod.RecordMoveEvent) last_ev; + if (last_ev1.vec.distanceTo(ev.vec) < RepeatingMod.me.record_blocks_limit && + diff < RepeatingMod.me.record_time_limit) { + just_add = false; + add_delay = false; + last_ev1.vec = ev.vec; + } + } + } + if (add_delay) { + RepeatingMod.me.record.add(new RepeatingMod.RecordDelayEvent(diff)); + } + } + if (just_add) { + RepeatingMod.me.record.add(ev); + RepeatingMod.me.last_record = now; + } + } + } + lastVec = vec; + } + } +} diff --git a/src/main/resources/assets/modid/icon.png b/src/main/resources/assets/modid/icon.png deleted file mode 100644 index 047b91f2347de5cf95f23284476fddbe21ba23fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 453 zcmV;$0XqJPP)QAFYGys`80vegN0XDFh0OXKz&i8?Le#x7{1X)R+00000NkvXXu0mjf73i~T diff --git a/src/main/resources/assets/repeating-mod/lang/en_us.json b/src/main/resources/assets/repeating-mod/lang/en_us.json new file mode 100644 index 0000000..57f79f0 --- /dev/null +++ b/src/main/resources/assets/repeating-mod/lang/en_us.json @@ -0,0 +1,26 @@ +{ + "key.repeating-mod.menu": "Repeating menu", + "key.repeating-mod.toggle_replay": "Toggle replay", + "key.repeating-mod.toggle_record": "Toggle recording", + + "text.repeating-mod.name": "Repeating Mod", + "text.repeating-mod.record": "record", + "text.repeating-mod.replay": "replay", + "text.repeating-mod.start": "Start", + "text.repeating-mod.stop": "Stop", + "text.repeating-mod.export": "Export record", + "text.repeating-mod.import": "Import record", + "text.repeating-mod.basic": "Basic mode", + "text.repeating-mod.parkour": "Parkour mode", + "text.repeating-mod.settings": "Settings", + "text.repeating-mod.dev": "In development...", + "text.repeating-mod.block_limit": "Block limit: %s", + "text.repeating-mod.block_limit_tooltip": "Two recording events will\nbe summed up if the\ndistance between them is\nless than the limit.", + "text.repeating-mod.time_limit": "Time limit: %s ms", + "text.repeating-mod.time_limit_tooltip": "Two recording events will\nbe summed up if the time\nbetween them is less than\nthe limit.", + + "message.repeating-mod.replay_start": "Replay started", + "message.repeating-mod.replay_stop": "Replay finished", + "message.repeating-mod.record_start": "Record started", + "message.repeating-mod.record_stop": "Record finished" +} \ No newline at end of file diff --git a/src/main/resources/assets/repeating-mod/lang/ru_ru.json b/src/main/resources/assets/repeating-mod/lang/ru_ru.json new file mode 100644 index 0000000..8b62f15 --- /dev/null +++ b/src/main/resources/assets/repeating-mod/lang/ru_ru.json @@ -0,0 +1,27 @@ +{ + "key.repeating-mod.menu": "Меню репитинга", + "key.repeating-mod.toggle_replay": "Вкл/выкл повтор", + "key.repeating-mod.toggle_record": "Вкл/выкл запись", + + "text.repeating-mod.name": "Репитинг Мод", + "text.repeating-mod.record": "запись", + "text.repeating-mod.replay": "повтор", + "text.repeating-mod.start": "Начать", + "text.repeating-mod.stop": "Остановить", + "text.repeating-mod.export": "Экспорт записи", + "text.repeating-mod.import": "Импорт записи", + "text.repeating-mod.basic": "Обычный режим", + "text.repeating-mod.parkour": "Режим паркура", + "text.repeating-mod.settings": "Настройки", + "text.repeating-mod.dev": "В разработке...", + "text.repeating-mod.block_limit": "Лимит блоков: %s", + "text.repeating-mod.block_limit_tooltip": "Два ивента записи будут\nсуммироваться, если\nрасстояние между ними\nменьше лимита.", + "text.repeating-mod.time_limit": "Лимит времени: %s мс", + "text.repeating-mod.time_limit_tooltip": "Два ивента записи будут\nсуммироваться, если время\nмежду ними меньше лимита.", + + "message.repeating-mod.replay_start": "Повтор начат", + "message.repeating-mod.replay_stop": "Повтор закончен", + "message.repeating-mod.record_start": "Запись начата", + "message.repeating-mod.record_stop": "Запись закончена" +} + diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 021d9e7..5328b3f 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,12 +1,12 @@ { "schemaVersion": 1, - "id": "modid", + "id": "repeating-mod", "version": "${version}", - "name": "Example Mod", - "description": "This is an example description! Tell everyone what your mod is about!", + "name": "Repeating Mod", + "description": "Mod that repeats your actions. ", "authors": [ - "Me!" + "TheMixRay" ], "contact": { "homepage": "https://fabricmc.net/", @@ -14,22 +14,22 @@ }, "license": "CC0-1.0", - "icon": "assets/modid/icon.png", + "icon": "icon.png", - "environment": "*", + "environment": "client", "entrypoints": { - "main": [ - "net.fabricmc.example.ExampleMod" + "client": [ + "themixray.repeating.mod.RepeatingMod" ] }, "mixins": [ - "modid.mixins.json" + "repeating-mod.mixins.json" ], "depends": { - "fabricloader": ">=0.14.17", + "fabricloader": ">=0.14.14", "fabric-api": "*", - "minecraft": "~1.19.4", + "minecraft": "~1.19.3", "java": ">=17" }, "suggests": { diff --git a/src/main/resources/modid.mixins.json b/src/main/resources/repeating-mod.mixins.json similarity index 66% rename from src/main/resources/modid.mixins.json rename to src/main/resources/repeating-mod.mixins.json index 7c42cb4..50f497d 100644 --- a/src/main/resources/modid.mixins.json +++ b/src/main/resources/repeating-mod.mixins.json @@ -1,12 +1,13 @@ { "required": true, "minVersion": "0.8", - "package": "net.fabricmc.example.mixin", + "package": "themixray.repeating.mod.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ ], "client": [ - "ExampleMixin" + "MovementMixin", + "InputMixin" ], "injectors": { "defaultRequire": 1