Skip to content

Commit

Permalink
옵티파인과 함께 동작할 때 일어나는 이슈 수정
Browse files Browse the repository at this point in the history
- TextInputUtil 클래스 래퍼가 ObfuscatedField를 이용해 값을 가져오게 고침
- 옵티파인은 ChatScreen을 상속받는 GuiChatOF 클래스를 구현하고 있음
- NaraeUtils에서 리플렉션 파트를 ReflectionFieldInfo와 ReflectionFieldMap으로 분리

표지판 크래시 수정
- TextComponentWrapper 인터페이스에서 modifyText(String) 메소드 삭제
  • Loading branch information
sokcuri committed Aug 29, 2019
1 parent 3b1e0db commit 9f049a3
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 93 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.5.0
옵티파인 1.14.4_HD_U_F4_pre3 호환
- 옵티파인과 함께 쓸 때 한글 채팅이 정상 작동하지 않는 문제 수정
표지판 입력기에서 간헐적으로 크래시가 발생하는 버그 수정

## 0.4.0
나래챗 모드 클라이언트에서 서버를 열면 다른 클라이언트 접속이 되지 않던 문제 수정

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* [홈페이지](https://github.com/sokcuri/NaraeChat)
* [다운로드](https://github.com/sokcuri/NaraeChat/releases)
* [업데이트 기록](CHANGELOG.md)
* 버전: 1.14.4-0.4.0 (2019-08-29)
* 버전: 1.14.4-0.5.0 (2019-08-29)
* 마인크래프트 : 1.14.4
* 포지 : 1.14.4-28.0.55
* [라이센스 : LGPL 3.0](LICENSE.txt)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ apply plugin: 'eclipse'
apply plugin: 'maven-publish'

compileJava.options.encoding = 'UTF-8'
version = '1.14.4-0.4.0'
version = '1.14.4-0.5.0'
group = 'kr.neko.sokcuri.naraechat' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'naraechat'

Expand Down
54 changes: 8 additions & 46 deletions src/main/java/kr/neko/sokcuri/naraechat/NaraeUtils.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
package kr.neko.sokcuri.naraechat;

import kr.neko.sokcuri.naraechat.Obfuscated.ReflectionFieldInfo;
import kr.neko.sokcuri.naraechat.Obfuscated.ReflectionFieldMap;
import kr.neko.sokcuri.naraechat.Wrapper.TextComponentWrapper;
import kr.neko.sokcuri.naraechat.Wrapper.TextFieldWidgetWrapper;
import kr.neko.sokcuri.naraechat.Wrapper.TextInputUtilWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.fonts.TextInputUtil;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class NaraeUtils {
public static HashMap<String, ArrayList<String>> inputUtilFieldMap = new HashMap<>();
public static HashMap<String, ArrayList<String>> textFieldWidgetFieldMap = new HashMap<>();

private static ReflectionFieldMap<TextFieldWidget> textFieldWidgetRefMap = new ReflectionFieldMap(TextFieldWidget.class);
private static ReflectionFieldMap<TextInputUtil> textInputUtilRefMap = new ReflectionFieldMap(TextInputUtil.class);

public static TextComponentWrapper getTextComponent() {
TextFieldWidget widget = getWidget();
Expand All @@ -36,53 +38,13 @@ private static TextInputUtil getTextInput() {
Minecraft mc = Minecraft.getInstance();
if (mc.currentScreen == null) return null;

Object o = mc.currentScreen;
String className = o.getClass().getName();

if (!inputUtilFieldMap.containsKey(o.getClass().getName())) {
ArrayList<String> textInputUtilFields = new ArrayList<>();
for (Field field : o.getClass().getDeclaredFields()) {
if (field.getType().getName() == "net.minecraft.client.gui.fonts.TextInputUtil") {
textInputUtilFields.add(field.getName());
}
}
inputUtilFieldMap.put(className, textInputUtilFields);
}

if (inputUtilFieldMap.containsKey(className)) {
for (String fieldName : inputUtilFieldMap.get(className)) {
TextInputUtil inputUtil = (TextInputUtil) ObfuscationReflectionHelper.getPrivateValue((Class)o.getClass(), mc.currentScreen, fieldName);
return inputUtil;
}
}
return null;
return textInputUtilRefMap.findField(mc.currentScreen);
}

private static TextFieldWidget getWidget() {
Minecraft mc = Minecraft.getInstance();
if (mc.currentScreen == null) return null;

Object o = mc.currentScreen;
String className = o.getClass().getName();

if (!textFieldWidgetFieldMap.containsKey(o.getClass().getName())) {
ArrayList<String> textFieldWidgetFields = new ArrayList<>();
for (Field field : o.getClass().getDeclaredFields()) {
if (field.getType().getName() == "net.minecraft.client.gui.widget.TextFieldWidget") {
textFieldWidgetFields.add(field.getName());
}
}
textFieldWidgetFieldMap.put(className, textFieldWidgetFields);
}

if (textFieldWidgetFieldMap.containsKey(className)) {
for (String fieldName : textFieldWidgetFieldMap.get(className)) {
TextFieldWidget widget = (TextFieldWidget) ObfuscationReflectionHelper.getPrivateValue((Class)o.getClass(), mc.currentScreen, fieldName);
if (widget.isFocused()) {
return widget;
}
}
}
return null;
return textFieldWidgetRefMap.findField(mc.currentScreen);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package kr.neko.sokcuri.naraechat.Obfuscated;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.fonts.TextInputUtil;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;

import java.util.function.Consumer;
import java.util.function.Supplier;

public final class ObfuscatedField<O, T> {

Expand Down Expand Up @@ -34,6 +38,26 @@ public static class $TextFieldWidget {
}
}

public static class $TextInputUtil {
public static final ObfuscatedField<TextInputUtil, Minecraft> minecraft;
public static final ObfuscatedField<TextInputUtil, FontRenderer> fontRenderer;
public static final ObfuscatedField<TextInputUtil, Supplier<String>> textSupplier;
public static final ObfuscatedField<TextInputUtil, Consumer<String>> textConsumer;
public static final ObfuscatedField<TextInputUtil, Integer> maxStringLength;
public static final ObfuscatedField<TextInputUtil, Integer> cursorPosition;
public static final ObfuscatedField<TextInputUtil, Integer> cursorPosition2;

static {
minecraft = new ObfuscatedField("field_216900_a", "field_216900_a", TextInputUtil.class, Minecraft.class);
fontRenderer = new ObfuscatedField("field_216901_b", "field_216901_b", TextInputUtil.class, FontRenderer.class);
textSupplier = new ObfuscatedField("field_216902_c", "field_216902_c", TextInputUtil.class, Supplier.class);
textConsumer = new ObfuscatedField("field_216903_d", "field_216903_d", TextInputUtil.class, Consumer.class);
maxStringLength = new ObfuscatedField("field_216904_e", "field_216904_e", TextInputUtil.class, int.class);
cursorPosition = new ObfuscatedField("field_216905_f", "field_216905_f", TextInputUtil.class, int.class);
cursorPosition2 = new ObfuscatedField("field_216906_g", "field_216906_g", TextInputUtil.class, int.class);
}
}

public ObfuscatedField(String deobfName, String obfName, Class<O> owner, Class<T> retClass) {
this.obfName = obfName;
this.deobfName = deobfName;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package kr.neko.sokcuri.naraechat.Obfuscated;

public class ReflectionFieldInfo<O, T> {
static public <O, T> ReflectionFieldInfo create(String name, Class<T> type, Class<O> owner, int depth) {
return new ReflectionFieldInfo(name, type, owner, depth);
}

ReflectionFieldInfo(String name, Class<T> type, Class<O> owner, int depth) {
this.name = name;
this.type = type;
this.owner = owner;
this.depth = depth;
}

private String name;
private Class<T> type;
private Class<O> owner;
private int depth;

public String getName() {
return this.name;
}

public Class<T> getTypeClass() {
return this.type;
}

public Class<O> getOwnerClass() {
return this.owner;
}

public int getDepth() {
return this.depth;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package kr.neko.sokcuri.naraechat.Obfuscated;

import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class ReflectionFieldMap<T> {
private HashMap<String, List<ReflectionFieldInfo>> map = new HashMap<>();
private Class<T> target;

public ReflectionFieldMap(Class<T> target) {
this.target = target;
}

public List<ReflectionFieldInfo> getReflectionArray(List<ReflectionFieldInfo> array, Class<?> owner, int depth) {
for (Field field : owner.getDeclaredFields()) {
array.add(ReflectionFieldInfo.create(field.getName(), field.getType(), owner, depth));
}

if (owner.getSuperclass() != null) {
getReflectionArray(array, owner.getSuperclass(), depth + 1);
}
return array;
}

public T findField(Object owner) {
String className = owner.getClass().getName();
if (!map.containsKey(className)) {
List<ReflectionFieldInfo> fieldInfoArray = getReflectionArray(new ArrayList(), owner.getClass(), 0);
List<ReflectionFieldInfo> savedInfo = new ArrayList<>();

for (ReflectionFieldInfo fieldInfo : fieldInfoArray) {
if (fieldInfo.getTypeClass() == target) {
savedInfo.add(fieldInfo);
}
}

map.put(className, savedInfo);
}

if (map.containsKey(className)) {
for (ReflectionFieldInfo fieldInfo : map.get(className)) {
Object obj = ObfuscationReflectionHelper.getPrivateValue(fieldInfo.getOwnerClass(), owner, fieldInfo.getName());
if (obj instanceof TextFieldWidget) {
if (((TextFieldWidget)obj).isFocused()) {
return (T)obj;
}
} else {
return (T)obj;
}
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@ public interface TextComponentWrapper {

void writeText(String str);

void modifyText(String str);
void modifyText(char str);
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,10 @@ public void writeText(String str) {
}

@Override
public void modifyText(String str) {
public void modifyText(char ch) {
int cursorPosition = getCursorPosition();
setCursorPosition(cursorPosition - 1);
deleteFromCursor(1);
writeText(str);
}

@Override
public void modifyText(char ch) {
modifyText(String.valueOf(Character.toChars(ch)));
writeText(String.valueOf(Character.toChars(ch)));
}
}

0 comments on commit 9f049a3

Please sign in to comment.