Compare commits

...

6 Commits

Author SHA1 Message Date
Johannes Frohnmeyer 4e47338803
feat: finish port to 1.20.5
ci/woodpecker/push/jfmod Pipeline was successful Details
ci/woodpecker/tag/jfmod Pipeline was successful Details
2024-04-26 09:45:01 +02:00
Johannes Frohnmeyer 7a1dec5e1a
feat: start working on 1.20.5 port
ci/woodpecker/push/jfmod Pipeline was successful Details
2024-04-25 20:45:06 +02:00
Johannes Frohnmeyer bfd812ddbc
chore: update to 1.20.4 2023-12-07 21:09:41 +01:00
Johannes Frohnmeyer 0c2bffe0be
chore: update to 1.20.2
ci/woodpecker/push/jfmod Pipeline was successful Details
2023-09-22 21:45:30 +02:00
Johannes Frohnmeyer 8c5c2e168e
Update to 1.20 and use String2ObjectMap
ci/woodpecker/push/jfmod Pipeline was successful Details
ci/woodpecker/tag/jfmod Pipeline was successful Details
2023-06-09 17:16:19 +02:00
Johannes Frohnmeyer 857774fa2c Didn't mean to push that
ci/woodpecker/push/jfmod Pipeline was successful Details
ci/woodpecker/tag/jfmod Pipeline was successful Details
2023-03-23 08:42:04 +01:00
9 changed files with 103 additions and 118 deletions

View File

@ -1,18 +1,42 @@
import io.gitlab.jfronny.scripts.*
plugins {
id("jfmod") version "1.3-SNAPSHOT"
id("io.github.juuxel.loom-quiltflower") version "1.8.0"
id("jfmod") version "1.6-SNAPSHOT"
}
allprojects { group = "io.gitlab.jfronny" }
base.archivesName = "chat-transform"
jfMod {
minecraftVersion = "1.20.5"
yarn("build.1")
loaderVersion = "0.15.10"
libJfVersion = "3.15.6"
fabricApiVersion = "0.97.6+1.20.5"
modrinth {
projectId = "chat-transform"
requiredDependencies.add("libjf")
optionalDependencies.add("modmenu")
}
curseforge {
projectId = "839175"
requiredDependencies.add("libjf")
optionalDependencies.add("modmenu")
}
}
dependencies {
modImplementation("io.gitlab.jfronny.libjf:libjf-config-core-v1:${prop("libjf_version")}")
include(modImplementation(fabricApi.module("fabric-message-api-v1", prop("fabric_version")))!!)
include(modImplementation(fabricApi.module("fabric-command-api-v2", prop("fabric_version")))!!)
modImplementation(fabricApi.module("fabric-networking-api-v1", prop("fabric_version")))
modImplementation("io.gitlab.jfronny.libjf:libjf-config-core-v2")
include(modImplementation("net.fabricmc.fabric-api:fabric-message-api-v1")!!)
include(modImplementation("net.fabricmc.fabric-api:fabric-command-api-v2")!!)
modImplementation("net.fabricmc.fabric-api:fabric-networking-api-v1")
// Dev env
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-config-ui-tiny-v1:${prop("libjf_version")}")
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil:${prop("libjf_version")}")
modLocalRuntime("com.terraformersmc:modmenu:6.1.0-rc.4")
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-config-ui-tiny")
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil")
modLocalRuntime("com.terraformersmc:modmenu:10.0.0-beta.1")
// for modmenu
modLocalRuntime("net.fabricmc.fabric-api:fabric-resource-loader-v0")
modLocalRuntime("net.fabricmc.fabric-api:fabric-screen-api-v1")
modLocalRuntime("net.fabricmc.fabric-api:fabric-key-binding-api-v1")
}

View File

@ -1,17 +0,0 @@
# https://fabricmc.net/develop/
minecraft_version=1.19.4
yarn_mappings=build.1
loader_version=0.14.17
maven_group=io.gitlab.jfronny
archives_base_name=chat-transform
modrinth_id=chat-transform
modrinth_required_dependencies=libjf
modrinth_optional_dependencies=modmenu
curseforge_id=839175
curseforge_required_dependencies=libjf
curseforge_optional_dependencies=modmenu
libjf_version=3.7.1
fabric_version=0.75.3+1.19.4

View File

@ -1,6 +1,7 @@
package io.gitlab.jfronny.chattransform.client.mixin;
import io.gitlab.jfronny.chattransform.*;
import io.gitlab.jfronny.chattransform.Cfg;
import io.gitlab.jfronny.chattransform.ChatTransform;
import io.gitlab.jfronny.chattransform.client.ITextFieldWidget;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.widget.TextFieldWidget;

View File

@ -1,22 +1,22 @@
package io.gitlab.jfronny.chattransform.client.mixin;
import io.gitlab.jfronny.chattransform.*;
import io.gitlab.jfronny.chattransform.Cfg;
import io.gitlab.jfronny.chattransform.ChatTransform;
import io.gitlab.jfronny.chattransform.client.*;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@Mixin(TextFieldWidget.class)
public abstract class TextFieldWidgetMixin extends ClickableWidget implements ITextFieldWidget {
@ -31,7 +31,7 @@ public abstract class TextFieldWidgetMixin extends ClickableWidget implements IT
@Shadow private boolean drawsBackground;
@Shadow public abstract int getCharacterX(int index);
@Shadow public abstract boolean isVisible();
@Shadow public abstract void setCursor(int cursor);
@Shadow public abstract void setCursor(int cursor, boolean shiftKeyPressed);
@Shadow private Predicate<String> textPredicate;
@Shadow @Final private TextRenderer textRenderer;
@ -63,8 +63,8 @@ public abstract class TextFieldWidgetMixin extends ClickableWidget implements IT
}
}
@Inject(method = "setCursor(I)V", at = @At("TAIL"))
void updateStartOnSetCursor(int cursor, CallbackInfo ci) {
@Inject(method = "setCursor(IZ)V", at = @At("TAIL"))
void updateStartOnSetCursor(int cursor, boolean shiftKeyPressed, CallbackInfo ci) {
transformStart.clear();
lastSubstitution = null;
}
@ -75,29 +75,32 @@ public abstract class TextFieldWidgetMixin extends ClickableWidget implements IT
if (!transformStart.isAvailable()) transformStart.set(selectionStart - 1);
if (transformStart.get() >= selectionStart) return;
String currentString = getText().substring(transformStart.get(), selectionStart);
Set<Map.Entry<String, String>> complete = getStartingWith(currentString);
// Exact match
if (Cfg.substitutions.containsKey(currentString) && complete.size() == 1
&& substitute(transformStart.get(), selectionStart, Cfg.substitutions.get(currentString))) {
transformStart.set(selectionStart);
Iterator<? extends Map.Entry<String, String>> complete = Cfg.substitutions.getKeyValuePairsForKeysStartingWith(currentString).iterator();
if (complete.hasNext()) {
Map.Entry<String, String> substitution = complete.next();
if (substitution.getKey().length() == currentString.length() // Match without "overshoot"
&& !complete.hasNext() // No other options
&& substitute(transformStart.get(), selectionStart, substitution.getValue())) {
transformStart.set(selectionStart);
}
return;
}
if (complete.isEmpty()) {
if (transformStart.get() == selectionStart - 1) {
// Nothing starts with this char
transformStart.increment();
// No matches
if (transformStart.get() == selectionStart - 1) {
// Nothing starts with this char
transformStart.increment();
} else {
// Something previously started with this...
String previousString = getText().substring(transformStart.get(), selectionStart - 1);
String substitution = Cfg.substitutions.get(previousString);
if (substitution != null
// ...and matched -> replace
&& substitute(transformStart.get(), selectionStart - 1, substitution)) {
setCursor(selectionStart + 1, false);
} else {
// Something previously started with this...
String previousString = getText().substring(transformStart.get(), selectionStart - 1);
if (Cfg.substitutions.containsKey(previousString)
// ...and matched -> replace
&& substitute(transformStart.get(), selectionStart - 1, Cfg.substitutions.get(previousString))) {
setCursor(selectionStart + 1);
} else {
// ...and didn't match -> move transform start and call transform again (substring might have matched)
transformStart.increment();
transform();
}
// ...and didn't match -> move transform start and call transform again (substring might have matched)
transformStart.increment();
transform();
}
}
}
@ -107,8 +110,8 @@ public abstract class TextFieldWidgetMixin extends ClickableWidget implements IT
String str = getText();
if (!transformStart.isAvailable() || transformStart.get() >= selectionStart) return str;
String currentString = str.substring(transformStart.get(), selectionStart);
if (!Cfg.substitutions.containsKey(currentString)
|| !substitute(transformStart.get(), selectionStart, Cfg.substitutions.get(currentString))) {
String substitution = Cfg.substitutions.get(currentString);
if (substitution == null || !substitute(transformStart.get(), selectionStart, substitution)) {
transformStart.increment();
return chattransform$finalize();
}
@ -130,32 +133,28 @@ public abstract class TextFieldWidgetMixin extends ClickableWidget implements IT
} else return false;
}
Set<Map.Entry<String, String>> getStartingWith(String start) {
return Cfg.substitutions.entrySet().stream().filter(s -> s.getKey().startsWith(start)).collect(Collectors.toUnmodifiableSet());
}
@Inject(method = "renderButton(Lnet/minecraft/client/util/math/MatrixStack;IIF)V", at = @At(value = "TAIL"))
void renderTransformStart(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) {
@Inject(method = "renderWidget(Lnet/minecraft/client/gui/DrawContext;IIF)V", at = @At(value = "TAIL"))
void renderTransformStart(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (isVisible() && Cfg.Client.visualize) {
int y = this.drawsBackground ? this.getY() + (this.height - 8) / 2 : this.getY();
if (transformStart.isAvailable()) {
int x = getCharacterX(transformStart.get());
chattransform$fill(matrices, x, y - 1, x + 1, y + 1 + 9, 0x7f0000ff);
chattransform$fill(context, x, y - 1, x + 1, y + 1 + 9, 0x7f0000ff);
}
if (transformStart.showPrevious()) {
int x = getCharacterX(transformStart.getPrevious());
chattransform$fill(matrices, x, y - 1, x + 1, y + 1 + 9, 0x7fff0000);
chattransform$fill(context, x, y - 1, x + 1, y + 1 + 9, 0x7fff0000);
}
if (lastSubstitution != null && lastSubstitution.shouldShow()) {
int start = getCharacterX(lastSubstitution.start());
int end = getCharacterX(Math.min(lastSubstitution.end() + 1, text.length()));
chattransform$fill(matrices, start, y - 1, end, y + 1 + 9, 0x7fffff00);
chattransform$fill(context, start, y - 1, end, y + 1 + 9, 0x7fffff00);
}
}
}
@Unique
private void chattransform$fill(MatrixStack matrices, int x1, int y1, int x2, int y2, int color) {
private void chattransform$fill(DrawContext context, int x1, int y1, int x2, int y2, int color) {
if (x1 < 0) x1 = 0;
if (x2 < 0) x2 = 0;
int maxX = getX() + getWidth();
@ -174,7 +173,7 @@ public abstract class TextFieldWidgetMixin extends ClickableWidget implements IT
y2 = i;
}
textRenderer.draw(matrices, "X={" + x1 + ";" + x2 + "} Y={" + y1 + ";" + y2 + "}", 0, 0, 0xFF000000);
fill(matrices, x1, y1, x2, y2, color);
context.drawText(textRenderer, "X={" + x1 + ";" + x2 + "} Y={" + y1 + ";" + y2 + "}", 0, 0, 0xFF000000, false);
context.fill(x1, y1, x2, y2, color);
}
}

View File

@ -5,8 +5,8 @@
"chat-transform.jfconfig.client.title": "Client Settings",
"chat-transform.jfconfig.client.mode": "Mode",
"chat-transform.jfconfig.client.mode.tooltip": "When to perform replacements",
"chat-transform.jfconfig.enum.Mode.Live": "Live",
"chat-transform.jfconfig.enum.Mode.OnSend": "On Send",
"chat-transform.jfconfig.client.enum.Mode.Live": "Live",
"chat-transform.jfconfig.client.enum.Mode.OnSend": "On Send",
"chat-transform.jfconfig.client.visualize": "Visualize",
"chat-transform.jfconfig.client.visualize.tooltip": "Visualize transformations as you type in live mode",
"chat-transform.jfconfig.server.title": "Server Settings",
@ -17,5 +17,8 @@
"chat-transform.jfconfig.server.playerConfigurable": "Player Configurable",
"chat-transform.jfconfig.server.playerConfigurable.tooltip": "Whether players should be able to toggle chat transformation",
"chat-transform.jfconfig.server.defaultEnable": "Default Enable",
"chat-transform.jfconfig.server.defaultEnable.tooltip": "Whether players' chat should be transformed by default"
"chat-transform.jfconfig.server.defaultEnable.tooltip": "Whether players' chat should be transformed by default",
"chat-transform.jfconfig.owo": "OwO",
"chat-transform.jfconfig.katakana": "Katakana",
"chat-transform.jfconfig.hiragana": "Hiragana"
}

View File

@ -1,13 +1,15 @@
package io.gitlab.jfronny.chattransform;
import io.gitlab.jfronny.commons.serialize.gson.api.v1.Ignore;
import io.gitlab.jfronny.libjf.config.api.v1.*;
import io.gitlab.jfronny.commons.data.String2ObjectMap;
import io.gitlab.jfronny.commons.serialize.annotations.Ignore;
import io.gitlab.jfronny.libjf.config.api.v2.*;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
@JfConfig
public class Cfg {
@Entry public static Map<String, String> substitutions = Map.of();
@Entry public static String2ObjectMap<String> substitutions = new String2ObjectMap<>();
@Category
public static class Client {
@ -29,7 +31,7 @@ public class Cfg {
@Preset
public static void owo() {
substitutions = new LinkedHashMap<>();
substitutions = new String2ObjectMap<>();
substitutions.put("r", "w");
substitutions.put("l", "w");
substitutions.put("R", "W");
@ -40,21 +42,15 @@ public class Cfg {
substitutions.put("you", "uu");
substitutions.put("the ", "da ");
substitutions.put("The ", "Da ");
}
@Preset
public static void demonstrationPurposesOnly() {
substitutions = new LinkedHashMap<>();
substitutions.put("chat-transform", "Chat-Transform (this mod)");
substitutions.put(":tm:", "");
substitutions.put("(c)", "©");
substitutions.put("This", "Dis");
substitutions.put("this", "dis");
}
@Ignore private static final char[] consonants = "bcdfghjklmprstwz".toCharArray();
@Preset
public static void katakana() {
substitutions = new LinkedHashMap<>();
substitutions = new String2ObjectMap<>();
substitutions.put("-", "");
for (char c : consonants) {
substitutions.put("" + c + c, "" + c);
@ -66,7 +62,7 @@ public class Cfg {
@Preset
public static void hiragana() {
substitutions = new LinkedHashMap<>();
substitutions = new String2ObjectMap<>();
substitutions.put("-", "");
for (char c : consonants) {
substitutions.put("" + c + c, "" + c);

View File

@ -1,28 +1,12 @@
package io.gitlab.jfronny.chattransform;
import io.gitlab.jfronny.commons.log.Logger;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
public class ChatTransform {
public static final String MOD_ID = "chat-transform";
public static final Logger LOG = Logger.forName(MOD_ID);
public static final SystemLoggerPlus LOG = SystemLoggerPlus.forName(MOD_ID);
public static String transform(String text) {
for (Map.Entry<String, String> e : Cfg.substitutions
.entrySet()
.stream()
.collect(Collectors.groupingBy(s -> s.getKey().length()))
.entrySet()
.stream()
.sorted(Map.Entry.<Integer, List<Map.Entry<String, String>>>comparingByKey().reversed())
.map(Map.Entry::getValue)
.flatMap(Collection::stream)
.toList()) {
text = text.replaceAll(Pattern.quote(e.getKey()), e.getValue());
}
return text;
return Cfg.substitutions.asSubstitution().apply(text);
}
}

View File

@ -3,23 +3,18 @@ package io.gitlab.jfronny.chattransform.server;
import com.mojang.brigadier.Command;
import io.gitlab.jfronny.chattransform.Cfg;
import io.gitlab.jfronny.chattransform.ChatTransform;
import io.gitlab.jfronny.libjf.config.api.v1.ConfigInstance;
import io.gitlab.jfronny.libjf.config.api.v2.ConfigInstance;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.message.v1.ServerMessageDecoratorEvent;
import net.fabricmc.fabric.api.networking.v1.ServerLoginConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.network.packet.s2c.play.ChatMessageS2CPacket;
import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.*;
import org.spongepowered.asm.mixin.Mutable;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import static net.minecraft.server.command.CommandManager.*;
import static net.minecraft.server.command.CommandManager.literal;
public class ChatTransformServer implements DedicatedServerModInitializer {
public static final ConfigInstance CONFIG_INSTANCE = Objects.requireNonNull(ConfigInstance.get(ChatTransform.MOD_ID));
@ -92,7 +87,7 @@ public class ChatTransformServer implements DedicatedServerModInitializer {
});
ServerMessageDecoratorEvent.EVENT.register(ServerMessageDecoratorEvent.CONTENT_PHASE, (sender, message) -> {
return CompletableFuture.completedFuture(sender != null && get(sender) ? transform(message) : message);
return sender != null && get(sender) ? transform(message) : message;
});
}
@ -134,8 +129,8 @@ public class ChatTransformServer implements DedicatedServerModInitializer {
else args[i] = args[i];
}
return new TranslatableTextContent(tx.getKey(), ChatTransform.transform(tx.getFallback()), args);
} else if (source instanceof LiteralTextContent tx) {
return new LiteralTextContent(ChatTransform.transform(tx.string()));
} else if (source instanceof PlainTextContent.Literal tx) {
return new PlainTextContent.Literal(ChatTransform.transform(tx.string()));
} else {
return source;
}

View File

@ -26,6 +26,6 @@
],
"depends": {
"fabricloader": ">=0.14.17",
"minecraft": "1.19.4"
"minecraft": "*"
}
}