functional prototype
This commit is contained in:
parent
f62046ade0
commit
d332c850af
|
@ -2,11 +2,11 @@ import io.gitlab.jfronny.scripts.*
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("jfmod") version "1.3-SNAPSHOT"
|
id("jfmod") version "1.3-SNAPSHOT"
|
||||||
|
id("io.github.juuxel.loom-quiltflower") version "1.8.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
modImplementation("io.gitlab.jfronny.libjf:libjf-config-core-v1:${prop("libjf_version")}")
|
modImplementation("io.gitlab.jfronny.libjf:libjf-config-core-v1:${prop("libjf_version")}")
|
||||||
modImplementation("io.gitlab.jfronny.libjf:libjf-translate-v1:${prop("libjf_version")}")
|
|
||||||
|
|
||||||
// Dev env
|
// Dev env
|
||||||
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-config-ui-tiny-v1:${prop("libjf_version")}")
|
modLocalRuntime("io.gitlab.jfronny.libjf:libjf-config-ui-tiny-v1:${prop("libjf_version")}")
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
package io.gitlab.jfronny.chattransform;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.commons.serialize.gson.api.v1.Ignore;
|
||||||
|
import io.gitlab.jfronny.libjf.config.api.v1.*;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@JfConfig
|
||||||
|
public class Cfg {
|
||||||
|
@Entry public static Map<String, String> substitutions = new LinkedHashMap<>();
|
||||||
|
@Entry public static Mode mode = Mode.Live;
|
||||||
|
|
||||||
|
public enum Mode {
|
||||||
|
Live, OnSend
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preset
|
||||||
|
public static void owo() {
|
||||||
|
substitutions.clear();
|
||||||
|
substitutions.put("r", "w");
|
||||||
|
substitutions.put("l", "w");
|
||||||
|
substitutions.put("R", "W");
|
||||||
|
substitutions.put("L", "W");
|
||||||
|
substitutions.put("no", "nu");
|
||||||
|
substitutions.put("has", "haz");
|
||||||
|
substitutions.put("have", "haz");
|
||||||
|
substitutions.put("you", "uu");
|
||||||
|
substitutions.put("the ", "da ");
|
||||||
|
substitutions.put("The ", "Da ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore private static final String katakanaTable = """
|
||||||
|
a i u e o n
|
||||||
|
ア イ ウ エ オ ン
|
||||||
|
x ァ ィ ゥ ェ ォ
|
||||||
|
k カ キ ク ケ コ
|
||||||
|
ky キャ キュ キョ
|
||||||
|
s サ ス セ ソ
|
||||||
|
sh シャ シ シュ シェ ショ
|
||||||
|
t タ ティ ツ テ ト
|
||||||
|
ts ツ
|
||||||
|
ch チャ チ チュ チェ チョ
|
||||||
|
n ナ ニ ヌ ネ ノ
|
||||||
|
ny ニャ ニュ ニョ
|
||||||
|
h ハ ヒ フ ヘ ホ
|
||||||
|
hy ヒャ ヒュ ヒョ
|
||||||
|
f ファ フィ フ フェ フォ
|
||||||
|
m マ ミ ム メ モ
|
||||||
|
my ミャ ミュ ミョ
|
||||||
|
y ヤ ユ ヨ
|
||||||
|
r ラ リ ル レ ロ
|
||||||
|
ry リャ リィ リュ リェ リョ
|
||||||
|
w ワ ウィ ウェ ヲ
|
||||||
|
g ガ ギ グ ゲ ゴ
|
||||||
|
gy ギャ ギュ ギョ
|
||||||
|
z ザ ズ ゼ ゾ/ヂョ
|
||||||
|
j ジャ/ヂャ ジ/ヂ ジュ/ヂュ ジェ ジョ
|
||||||
|
d ダ ヅ デ ド
|
||||||
|
b バ ビ ブ ベ ボ
|
||||||
|
by ビャ ビュ ビョ
|
||||||
|
p パ ピ プ ペ ポ
|
||||||
|
py ピャ ピュ ピョ
|
||||||
|
v ゔ""";
|
||||||
|
|
||||||
|
@Ignore private static final String hiraganaTable = """
|
||||||
|
a i u e o n
|
||||||
|
あ い う え お ん
|
||||||
|
x ぁ ぃ ぅ ぇ ぉ
|
||||||
|
k か き く け こ
|
||||||
|
ky きゃ きゅ きょ
|
||||||
|
s さ す せ そ
|
||||||
|
sh しゃ し しゅ しょ
|
||||||
|
t た つ て と
|
||||||
|
ts つ
|
||||||
|
ch ちゃ ち ちゅ ちぇ ちょ
|
||||||
|
n な に ぬ ね の
|
||||||
|
ny にゃ にゅ にょ
|
||||||
|
h は ひ ふ へ ほ
|
||||||
|
hy ひゃ ひゅ ひょ
|
||||||
|
f ふ
|
||||||
|
m ま み む め も
|
||||||
|
my みゃ みゅ みょ
|
||||||
|
y や ゆ よ
|
||||||
|
r ら り る れ ろ
|
||||||
|
ry りゃ りぃ りゅ りぇ りょ
|
||||||
|
w わ ゐ ゑ を
|
||||||
|
g が ぎ ぐ げ ご
|
||||||
|
gy ぎゃ ぎゅ ぎょ
|
||||||
|
z ざ ず ぜ ぞ/ぢょ
|
||||||
|
j じゃ/ぢゃ じ/ぢ じゅ/ぢゅ じょ
|
||||||
|
d だ づ で ど
|
||||||
|
b ば び ぶ べ ぼ
|
||||||
|
by びゃ びゅ びょ
|
||||||
|
p ぱ ぴ ぷ ぺ ぽ
|
||||||
|
py ぴゃ ぴゅ ぴょ
|
||||||
|
v ゔ""";
|
||||||
|
|
||||||
|
@Ignore private static final char[] consonants = "bcdfghjklmprstwz".toCharArray();
|
||||||
|
|
||||||
|
private static void fromTable(String table) {
|
||||||
|
String[] rows = table.split("\n");
|
||||||
|
String[] colNames = rows[0].split("\t");
|
||||||
|
for (int i = 1; i < rows.length; i++) {
|
||||||
|
String row = rows[i];
|
||||||
|
String[] cols = row.split("\t");
|
||||||
|
String rowName = cols[0];
|
||||||
|
for (int j = 1; j < cols.length; j++) {
|
||||||
|
String kana = cols[j];
|
||||||
|
String value = rowName + colNames[j];
|
||||||
|
String[] kanas = kana.split("/");
|
||||||
|
for (String singleKana : kanas) {
|
||||||
|
if (!singleKana.isEmpty()) {
|
||||||
|
substitutions.put(value, singleKana);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preset
|
||||||
|
public static void katakana() {
|
||||||
|
substitutions.clear();
|
||||||
|
substitutions.put("-", "ー");
|
||||||
|
// replaceTsus ッ
|
||||||
|
for (char c : consonants) {
|
||||||
|
substitutions.put("" + c + c, "ッ" + c);
|
||||||
|
}
|
||||||
|
// replaceNs ン
|
||||||
|
substitutions.put("nn", "ン");
|
||||||
|
// romajiToKatakanaTrie.convert
|
||||||
|
fromTable(katakanaTable);
|
||||||
|
// substitutions.put("che", "チェ");
|
||||||
|
// substitutions.put(".", "。");
|
||||||
|
// substitutions.put("shu", "シュ");
|
||||||
|
// substitutions.put("sha", "シャ");
|
||||||
|
// substitutions.put("\"", "「");
|
||||||
|
// substitutions.put("\"", "」");
|
||||||
|
// substitutions.put("sho", "ショ");
|
||||||
|
// substitutions.put("jo", "ジョ");
|
||||||
|
// substitutions.put("ⅴi", "ヴィ");
|
||||||
|
// substitutions.put("ju", "ジュ");
|
||||||
|
// substitutions.put("ja", "ジャ");
|
||||||
|
// substitutions.put("ve", "ヴェ");
|
||||||
|
// substitutions.put("ryo", "リョ");
|
||||||
|
// substitutions.put("ryu", "リュ");
|
||||||
|
// substitutions.put("rya", "リャ");
|
||||||
|
// substitutions.put("cho", "チョ");
|
||||||
|
// substitutions.put("chu", "チュ");
|
||||||
|
// substitutions.put("cha", "チャ");
|
||||||
|
// substitutions.put("hyo", "ヒョ");
|
||||||
|
// substitutions.put("hyu", "ヒュ");
|
||||||
|
// substitutions.put("hya", "ヒャ");
|
||||||
|
// substitutions.put("tsi", "ツィ");
|
||||||
|
// substitutions.put("dyo", "ヂョ");
|
||||||
|
// substitutions.put("dyu", "ヂュ");
|
||||||
|
// substitutions.put("dya", "ヂャ");
|
||||||
|
// substitutions.put("fi", "フィ");
|
||||||
|
// substitutions.put("byo", "ビョ");
|
||||||
|
// substitutions.put("byu", "ビュ");
|
||||||
|
// substitutions.put("fe", "フェ");
|
||||||
|
// substitutions.put("bya", "ビャ");
|
||||||
|
// substitutions.put("nyo", "ニョ");
|
||||||
|
// substitutions.put("nyu", "ニュ");
|
||||||
|
// substitutions.put("nya", "ニャ");
|
||||||
|
// substitutions.put("pya", "ピャ");
|
||||||
|
// substitutions.put("pyo", "ピョ");
|
||||||
|
// substitutions.put("pyu", "ピュ");
|
||||||
|
// substitutions.put("ti", "ティ");
|
||||||
|
// substitutions.put("a", "ア");
|
||||||
|
// substitutions.put("i", "イ");
|
||||||
|
// substitutions.put("u", "ウ");
|
||||||
|
// substitutions.put("e", "エ");
|
||||||
|
// substitutions.put("o", "オ");
|
||||||
|
// substitutions.put("ka", "カ");
|
||||||
|
// substitutions.put("ga", "ガ");
|
||||||
|
// substitutions.put("ki", "キ");
|
||||||
|
// substitutions.put("gi", "ギ");
|
||||||
|
// substitutions.put("ku", "ク");
|
||||||
|
// substitutions.put("gu", "グ");
|
||||||
|
// substitutions.put("ke", "ケ");
|
||||||
|
// substitutions.put("ge", "ゲ");
|
||||||
|
// substitutions.put("ko", "コ");
|
||||||
|
// substitutions.put("go", "ゴ");
|
||||||
|
// substitutions.put("sa", "サ");
|
||||||
|
// substitutions.put("za", "ザ");
|
||||||
|
// substitutions.put("shi", "シ");
|
||||||
|
// substitutions.put("ji", "ジ");
|
||||||
|
// substitutions.put("su", "ス");
|
||||||
|
// substitutions.put("zu", "ズ");
|
||||||
|
// substitutions.put("di", "ディ");
|
||||||
|
// substitutions.put("se", "セ");
|
||||||
|
// substitutions.put("wi", "ウィ");
|
||||||
|
// substitutions.put("ze", "ゼ");
|
||||||
|
// substitutions.put("so", "ソ");
|
||||||
|
// substitutions.put("zo", "ゾ");
|
||||||
|
// substitutions.put("ta", "タ");
|
||||||
|
// substitutions.put("da", "ダ");
|
||||||
|
// substitutions.put("chi", "チ");
|
||||||
|
// substitutions.put("ji", "ヂ");
|
||||||
|
// substitutions.put("tsu", "ツ");
|
||||||
|
// substitutions.put("zu", "ヅ");
|
||||||
|
// substitutions.put("te", "テ");
|
||||||
|
// substitutions.put("de", "デ");
|
||||||
|
// substitutions.put("we", "ウェ");
|
||||||
|
// substitutions.put("to", "ト");
|
||||||
|
// substitutions.put("do", "ド");
|
||||||
|
// substitutions.put("na", "ナ");
|
||||||
|
// substitutions.put("ni", "ニ");
|
||||||
|
// substitutions.put("nu", "ヌ");
|
||||||
|
// substitutions.put("ne", "ネ");
|
||||||
|
// substitutions.put("no", "ノ");
|
||||||
|
// substitutions.put("ha", "ハ");
|
||||||
|
// substitutions.put("ba", "バ");
|
||||||
|
// substitutions.put("kya", "キャ");
|
||||||
|
// substitutions.put("pa", "パ");
|
||||||
|
// substitutions.put("hi", "ヒ");
|
||||||
|
// substitutions.put("bi", "ビ");
|
||||||
|
// substitutions.put("pi", "ピ");
|
||||||
|
// substitutions.put("fu", "フ");
|
||||||
|
// substitutions.put("bu", "ブ");
|
||||||
|
// substitutions.put("pu", "プ");
|
||||||
|
// substitutions.put("he", "ヘ");
|
||||||
|
// substitutions.put("be", "ベ");
|
||||||
|
// substitutions.put("pe", "ペ");
|
||||||
|
// substitutions.put("ho", "ホ");
|
||||||
|
// substitutions.put("bo", "ボ");
|
||||||
|
// substitutions.put("kyo", "キョ");
|
||||||
|
// substitutions.put("po", "ポ");
|
||||||
|
// substitutions.put("ma", "マ");
|
||||||
|
// substitutions.put("kyu", "キュ");
|
||||||
|
// substitutions.put("mi", "ミ");
|
||||||
|
// substitutions.put("mu", "ム");
|
||||||
|
// substitutions.put("me", "メ");
|
||||||
|
// substitutions.put("mo", "モ");
|
||||||
|
// substitutions.put("ya", "ヤ");
|
||||||
|
// substitutions.put("yu", "ユ");
|
||||||
|
// substitutions.put("yo", "ヨ");
|
||||||
|
// substitutions.put("ra", "ラ");
|
||||||
|
// substitutions.put("ri", "リ");
|
||||||
|
// substitutions.put("ru", "ル");
|
||||||
|
// substitutions.put("re", "レ");
|
||||||
|
// substitutions.put("ro", "ロ");
|
||||||
|
// substitutions.put("wa", "ワ");
|
||||||
|
// substitutions.put("gyu", "ギュ");
|
||||||
|
// substitutions.put("wo", "ヲ");
|
||||||
|
// substitutions.put("n", "ン");
|
||||||
|
// substitutions.put("gya", "ギャ");
|
||||||
|
// substitutions.put("-", "ー");
|
||||||
|
// substitutions.put("gyo", "ギョ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preset
|
||||||
|
public static void hiragana() {
|
||||||
|
substitutions.clear();
|
||||||
|
substitutions.put("-", "ー");
|
||||||
|
// replaceTsus っ
|
||||||
|
for (char c : consonants) {
|
||||||
|
substitutions.put("" + c + c, "っ" + c);
|
||||||
|
}
|
||||||
|
// replaceNs ん
|
||||||
|
substitutions.put("nn", "ん");
|
||||||
|
// romajiToKatakanaTrie.convert
|
||||||
|
fromTable(hiraganaTable);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package io.gitlab.jfronny.chattransform;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.commons.log.Logger;
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
|
||||||
|
public class ChatTransform implements ClientModInitializer {
|
||||||
|
public static final Logger LOG = Logger.forName("chat-transform");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
LOG.info("Loaded chat-transform");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package io.gitlab.jfronny.chattransform;
|
||||||
|
|
||||||
|
public interface ITextFieldWidget {
|
||||||
|
void chattransform$activate();
|
||||||
|
String chattransform$finalize();
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package io.gitlab.jfronny.chattransform.mixin;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.chattransform.Cfg;
|
||||||
|
import io.gitlab.jfronny.chattransform.ITextFieldWidget;
|
||||||
|
import net.minecraft.client.gui.screen.ChatScreen;
|
||||||
|
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.*;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Mixin(ChatScreen.class)
|
||||||
|
public abstract class ChatScreenMixin {
|
||||||
|
@Shadow protected TextFieldWidget chatField;
|
||||||
|
|
||||||
|
@Inject(at = @At("RETURN"), method = "init()V")
|
||||||
|
void init(CallbackInfo ci) {
|
||||||
|
if (Cfg.mode == Cfg.Mode.Live) ((ITextFieldWidget) chatField).chattransform$activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Redirect(method = "keyPressed(III)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/TextFieldWidget;getText()Ljava/lang/String;"))
|
||||||
|
String finalizeTransforms(TextFieldWidget instance) {
|
||||||
|
String str = ((ITextFieldWidget) chatField).chattransform$finalize();
|
||||||
|
if (Cfg.mode == Cfg.Mode.OnSend) {
|
||||||
|
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()) {
|
||||||
|
str = str.replaceAll(Pattern.quote(e.getKey()), e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
package io.gitlab.jfronny.chattransform.mixin;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.chattransform.*;
|
||||||
|
import net.minecraft.client.gui.DrawableHelper;
|
||||||
|
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.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 {
|
||||||
|
public TextFieldWidgetMixin(int x, int y, int width, int height, Text message) {
|
||||||
|
super(x, y, width, height, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow public abstract String getText();
|
||||||
|
@Shadow private String text;
|
||||||
|
@Shadow private int selectionStart;
|
||||||
|
@Shadow private int selectionEnd;
|
||||||
|
@Shadow private boolean drawsBackground;
|
||||||
|
@Shadow public abstract int getCharacterX(int index);
|
||||||
|
@Shadow public abstract boolean isVisible();
|
||||||
|
@Shadow public abstract void setCursor(int cursor);
|
||||||
|
|
||||||
|
@Shadow private Predicate<String> textPredicate;
|
||||||
|
@Unique private boolean chattransform$active = false;
|
||||||
|
@Override
|
||||||
|
public void chattransform$activate() {
|
||||||
|
chattransform$active = true;
|
||||||
|
ChatTransform.LOG.info("Activated widget " + this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique private boolean chattransform$shouldTransform = false;
|
||||||
|
@Redirect(method = "write(Ljava/lang/String;)V", at = @At(value = "FIELD", target = "Lnet/minecraft/client/gui/widget/TextFieldWidget;text:Ljava/lang/String;", opcode = Opcodes.PUTFIELD))
|
||||||
|
void transformBeforeWrite(TextFieldWidget instance, String value, String tx) {
|
||||||
|
if (chattransform$active) {
|
||||||
|
if (selectionStart == selectionEnd && tx.length() == 1 && !Screen.hasAltDown() && !getText().startsWith("/")) {
|
||||||
|
chattransform$shouldTransform = true;
|
||||||
|
} else {
|
||||||
|
chattransform$start = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "write(Ljava/lang/String;)V", at = @At("TAIL"))
|
||||||
|
void transformAfterWrite(String text, CallbackInfo ci) {
|
||||||
|
if (chattransform$shouldTransform) {
|
||||||
|
chattransform$shouldTransform = false;
|
||||||
|
transform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "setCursor(I)V", at = @At("TAIL"))
|
||||||
|
void updateStartOnSetCursor(int cursor, CallbackInfo ci) {
|
||||||
|
chattransform$start = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unique private Integer chattransform$start = null;
|
||||||
|
void transform() {
|
||||||
|
if (chattransform$start == null) chattransform$start = selectionStart - 1;
|
||||||
|
if (chattransform$start < 0) chattransform$start = 0;
|
||||||
|
if (chattransform$start >= selectionStart) return;
|
||||||
|
String currentString = getText().substring(chattransform$start, selectionStart);
|
||||||
|
Set<Map.Entry<String, String>> complete = getStartingWith(currentString);
|
||||||
|
// Exact match
|
||||||
|
if (Cfg.substitutions.containsKey(currentString) && complete.size() == 1
|
||||||
|
&& substitute(chattransform$start, selectionStart, Cfg.substitutions.get(currentString))) {
|
||||||
|
chattransform$start = selectionStart;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (complete.isEmpty()) {
|
||||||
|
if (chattransform$start == selectionStart - 1) {
|
||||||
|
// Nothing starts with this char
|
||||||
|
chattransform$start++;
|
||||||
|
} else {
|
||||||
|
// Something previously started with this...
|
||||||
|
String previousString = getText().substring(chattransform$start, selectionStart - 1);
|
||||||
|
if (Cfg.substitutions.containsKey(previousString)
|
||||||
|
// ...and matched -> replace
|
||||||
|
&& substitute(chattransform$start, 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)
|
||||||
|
chattransform$start++;
|
||||||
|
transform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String chattransform$finalize() {
|
||||||
|
String str = getText();
|
||||||
|
if (chattransform$start == null || chattransform$start >= selectionStart) return str;
|
||||||
|
String currentString = str.substring(chattransform$start, selectionStart);
|
||||||
|
if (!Cfg.substitutions.containsKey(currentString)
|
||||||
|
|| !substitute(chattransform$start, selectionStart, Cfg.substitutions.get(currentString))) {
|
||||||
|
chattransform$start++;
|
||||||
|
return chattransform$finalize();
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean substitute(int start, int end, String substitution) {
|
||||||
|
ChatTransform.LOG.info("Transforming " + getText().substring(start, end) + " to " + substitution);
|
||||||
|
String sub = text.substring(0, start) + substitution + text.substring(end);
|
||||||
|
if (textPredicate.test(sub)) {
|
||||||
|
this.text = sub;
|
||||||
|
int oldLen = end - start;
|
||||||
|
int newLen = substitution.length();
|
||||||
|
if (selectionStart > end) selectionStart -= oldLen + newLen;
|
||||||
|
else if (selectionStart > start) selectionStart = start + newLen;
|
||||||
|
selectionEnd = selectionStart;
|
||||||
|
return true;
|
||||||
|
} 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) {
|
||||||
|
if (isVisible() && chattransform$start != null) {
|
||||||
|
int x = getCharacterX(chattransform$start);
|
||||||
|
int y = this.drawsBackground ? this.getY() + (this.height - 8) / 2 : this.getY();
|
||||||
|
DrawableHelper.fill(matrices, x, y - 1, x + 1, y + 1 + 9, 0x7f0000ff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"chat-transform.jfconfig.title": "Chat-Transform",
|
||||||
|
"chat-transform.jfconfig.substitutions": "Substitutions",
|
||||||
|
"chat-transform.jfconfig.substitutions.tooltip": "The substitutions to perform on text sent in the chat. See the presets for examples",
|
||||||
|
"chat-transform.jfconfig.mode": "Mode",
|
||||||
|
"chat-transform.jfconfig.mode.tooltip": "When to perform replacements",
|
||||||
|
"chat-transform.jfconfig.enum.Mode.Live": "Live",
|
||||||
|
"chat-transform.jfconfig.enum.Mode.OnSend": "On Send"
|
||||||
|
}
|
|
@ -3,9 +3,9 @@
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "io.gitlab.jfronny.chattransform.mixin",
|
"package": "io.gitlab.jfronny.chattransform.mixin",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_17",
|
||||||
"mixins": [
|
|
||||||
],
|
|
||||||
"client": [
|
"client": [
|
||||||
|
"ChatScreenMixin",
|
||||||
|
"TextFieldWidgetMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
|
@ -1,10 +0,0 @@
|
||||||
package io.gitlab.jfronny.chattransform;
|
|
||||||
|
|
||||||
import net.fabricmc.api.ModInitializer;
|
|
||||||
|
|
||||||
public class Chat_transform implements ModInitializer {
|
|
||||||
@Override
|
|
||||||
public void onInitialize() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package io.gitlab.jfronny.chattransform.client;
|
|
||||||
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
|
||||||
|
|
||||||
public class Chat_transformClient implements ClientModInitializer {
|
|
||||||
@Override
|
|
||||||
public void onInitializeClient() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,23 +2,22 @@
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "chat-transform",
|
"id": "chat-transform",
|
||||||
"version": "${version}",
|
"version": "${version}",
|
||||||
"name": "chat-transform",
|
"name": "Chat-Transform",
|
||||||
"description": "",
|
"description": "",
|
||||||
"authors": [],
|
"authors": [],
|
||||||
"contact": {},
|
"contact": {},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/chat-transform/icon.png",
|
"icon": "assets/chat-transform/icon.png",
|
||||||
"environment": "*",
|
"environment": "client",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"client": [
|
"client": ["io.gitlab.jfronny.chattransform.ChatTransform"],
|
||||||
"io.gitlab.jfronny.chattransform.client.Chat_transformClient"
|
"libjf:config": ["io.gitlab.jfronny.chattransform.JFC_Cfg"]
|
||||||
],
|
|
||||||
"main": [
|
|
||||||
"io.gitlab.jfronny.chattransform.Chat_transform"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"chat-transform.mixins.json"
|
{
|
||||||
|
"config": "chat-transform.client.mixins.json",
|
||||||
|
"environment": "client"
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.14.17",
|
"fabricloader": ">=0.14.17",
|
||||||
|
|
Loading…
Reference in New Issue