mirror of
https://github.com/GTNewHorizons/NotEnoughCharacters.git
synced 2026-11-12 16:27:54 +00:00
spotlessApply & wildcard import
This commit is contained in:
1 parent
1f0560e695
commit
533c4b348e
14 files changed
+430
-260
No files matched your search
@@ -4,6 +4,7 @@ import codechicken.nei.api.API;
|
||||
import codechicken.nei.api.IConfigureNEI;
|
||||
|
||||
public class NEINecharConfig implements IConfigureNEI {
|
||||
|
||||
@Override
|
||||
public void loadConfig() {
|
||||
API.addSearchProvider(new NecharSearchProvider());
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package net.moecraft.nechar;
|
||||
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
import static net.moecraft.nechar.NotEnoughCharacters.CONTEXT;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class NecharSearchFilter implements ItemFilter {
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
|
||||
public class NecharSearchFilter implements ItemFilter {
|
||||
|
||||
protected boolean invalid = false;
|
||||
|
||||
@@ -26,13 +27,13 @@ public class NecharSearchFilter implements ItemFilter {
|
||||
String[] pieces = searchText.split("\\s+");
|
||||
|
||||
for (String piece : pieces) {
|
||||
if (piece.isEmpty())
|
||||
continue;
|
||||
if (piece.isEmpty()) continue;
|
||||
|
||||
switch (piece.charAt(0)) {
|
||||
case '@':
|
||||
if (mod == null) {
|
||||
mod = piece.substring(1).toLowerCase();
|
||||
mod = piece.substring(1)
|
||||
.toLowerCase();
|
||||
continue;
|
||||
} else {
|
||||
invalid = true;
|
||||
@@ -41,7 +42,8 @@ public class NecharSearchFilter implements ItemFilter {
|
||||
|
||||
case '&':
|
||||
if (id == null) {
|
||||
id = piece.substring(1).toLowerCase();
|
||||
id = piece.substring(1)
|
||||
.toLowerCase();
|
||||
continue;
|
||||
} else {
|
||||
invalid = true;
|
||||
@@ -50,7 +52,8 @@ public class NecharSearchFilter implements ItemFilter {
|
||||
|
||||
case '$':
|
||||
if (dict == null) {
|
||||
dict = piece.substring(1).toLowerCase();
|
||||
dict = piece.substring(1)
|
||||
.toLowerCase();
|
||||
continue;
|
||||
} else {
|
||||
invalid = true;
|
||||
@@ -64,11 +67,10 @@ public class NecharSearchFilter implements ItemFilter {
|
||||
|
||||
@Override
|
||||
public boolean matches(ItemStack itemStack) {
|
||||
return !invalid
|
||||
&& matchesMod(itemStack)
|
||||
&& matchesId(itemStack)
|
||||
&& matchesDict(itemStack)
|
||||
&& matchesKeywords(itemStack);
|
||||
return !invalid && matchesMod(itemStack)
|
||||
&& matchesId(itemStack)
|
||||
&& matchesDict(itemStack)
|
||||
&& matchesKeywords(itemStack);
|
||||
}
|
||||
|
||||
protected boolean matchesMod(ItemStack itemStack) {
|
||||
@@ -78,7 +80,8 @@ public class NecharSearchFilter implements ItemFilter {
|
||||
|
||||
GameRegistry.UniqueIdentifier itemId = GameRegistry.findUniqueIdentifierFor(itemStack.getItem());
|
||||
|
||||
return itemId != null && itemId.modId.toLowerCase().contains(mod);
|
||||
return itemId != null && itemId.modId.toLowerCase()
|
||||
.contains(mod);
|
||||
}
|
||||
|
||||
protected boolean matchesId(ItemStack itemStack) {
|
||||
@@ -88,7 +91,8 @@ public class NecharSearchFilter implements ItemFilter {
|
||||
|
||||
String itemId = Item.itemRegistry.getNameForObject(itemStack.getItem());
|
||||
|
||||
return itemId.toLowerCase().contains(id);
|
||||
return itemId.toLowerCase()
|
||||
.contains(id);
|
||||
}
|
||||
|
||||
protected boolean matchesDict(ItemStack itemStack) {
|
||||
@@ -99,8 +103,9 @@ public class NecharSearchFilter implements ItemFilter {
|
||||
int[] oreIds = OreDictionary.getOreIDs(itemStack);
|
||||
|
||||
for (int id : oreIds) {
|
||||
if (OreDictionary.getOreName(id).toLowerCase().contains(dict))
|
||||
return true;
|
||||
if (OreDictionary.getOreName(id)
|
||||
.toLowerCase()
|
||||
.contains(dict)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -121,4 +126,4 @@ public class NecharSearchFilter implements ItemFilter {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import codechicken.nei.SearchField;
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
|
||||
public class NecharSearchProvider implements SearchField.ISearchProvider {
|
||||
|
||||
@Override
|
||||
public boolean isPrimary() {
|
||||
return false;
|
||||
|
||||
@@ -1,64 +1,69 @@
|
||||
package net.moecraft.nechar;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.client.ClientCommandHandler;
|
||||
import net.vfyjxf.nechar.NechCommand;
|
||||
import net.vfyjxf.nechar.NechConfig;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import cpw.mods.fml.common.Mod;
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import me.towdium.pinin.DictLoader;
|
||||
import me.towdium.pinin.PinIn;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.client.ClientCommandHandler;
|
||||
import net.vfyjxf.nechar.NechCommand;
|
||||
import net.vfyjxf.nechar.NechConfig;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
|
||||
@Mod(modid = NotEnoughCharacters.ID, acceptableRemoteVersions="*", useMetadata = true)
|
||||
@Mod(modid = NotEnoughCharacters.ID, acceptableRemoteVersions = "*", useMetadata = true)
|
||||
public class NotEnoughCharacters {
|
||||
|
||||
public static final String ID = "nechar";
|
||||
public static final String VERSION = NotEnoughCharacters.class.getPackage().getImplementationVersion();
|
||||
public static final String VERSION = NotEnoughCharacters.class.getPackage()
|
||||
.getImplementationVersion();
|
||||
public static final Logger logger = LogManager.getLogger("NotEnoughCharacters");
|
||||
|
||||
public static final PinIn CONTEXT = new PinIn(new CustomDictLoader()).config().accelerate(true).commit();
|
||||
public static final PinIn CONTEXT = new PinIn(new CustomDictLoader()).config()
|
||||
.accelerate(true)
|
||||
.commit();
|
||||
|
||||
private static class CustomDictLoader extends DictLoader.Default {
|
||||
|
||||
@Override
|
||||
public void load(BiConsumer<Character, String[]> feed) {
|
||||
super.load(feed);
|
||||
feed.accept('\ue900', new String[]{"lu2", "jinlu"}); // 钅卢
|
||||
feed.accept('\ue901', new String[]{"du4", "jindu"}); //钅杜
|
||||
feed.accept('\ue902', new String[]{"xi3", "jinxi"}); //钅喜
|
||||
feed.accept('\ue903', new String[]{"bo1", "jinbo"}); //钅波
|
||||
feed.accept('\ue904', new String[]{"hei1", "jinhei"}); //钅黑
|
||||
feed.accept('\u9fcf', new String[]{"mai4", "jinmai"});//钅麦
|
||||
feed.accept('\ue906', new String[]{"da2", "jinda"});//钅达
|
||||
feed.accept('\ue907', new String[]{"lun2", "jinlun"});//钅仑
|
||||
feed.accept('\u9fd4', new String[]{"ge1", "jinge"});//钅哥
|
||||
feed.accept('\u9fed', new String[]{"ni3", "jiner"});//钅尔
|
||||
feed.accept('\ue90a', new String[]{"fu1", "jinfu"});//钅夫
|
||||
feed.accept('\ue90c', new String[]{"li4", "jinli"});//钅立
|
||||
feed.accept('\u9fec', new String[]{"tian2", "shitian"});// 石田
|
||||
feed.accept('\u9feb', new String[]{"ao4", "qiao", "aoqi"});//气奥
|
||||
feed.accept('\ue900', new String[] { "lu2", "jinlu" }); // 钅卢
|
||||
feed.accept('\ue901', new String[] { "du4", "jindu" }); // 钅杜
|
||||
feed.accept('\ue902', new String[] { "xi3", "jinxi" }); // 钅喜
|
||||
feed.accept('\ue903', new String[] { "bo1", "jinbo" }); // 钅波
|
||||
feed.accept('\ue904', new String[] { "hei1", "jinhei" }); // 钅黑
|
||||
feed.accept('\u9fcf', new String[] { "mai4", "jinmai" });// 钅麦
|
||||
feed.accept('\ue906', new String[] { "da2", "jinda" });// 钅达
|
||||
feed.accept('\ue907', new String[] { "lun2", "jinlun" });// 钅仑
|
||||
feed.accept('\u9fd4', new String[] { "ge1", "jinge" });// 钅哥
|
||||
feed.accept('\u9fed', new String[] { "ni3", "jiner" });// 钅尔
|
||||
feed.accept('\ue90a', new String[] { "fu1", "jinfu" });// 钅夫
|
||||
feed.accept('\ue90c', new String[] { "li4", "jinli" });// 钅立
|
||||
feed.accept('\u9fec', new String[] { "tian2", "shitian" });// 石田
|
||||
feed.accept('\u9feb', new String[] { "ao4", "qiao", "aoqi" });// 气奥
|
||||
}
|
||||
}
|
||||
|
||||
public static void onConfigChange() {
|
||||
CONTEXT.config()
|
||||
.fZh2Z(NechConfig.EnableFZh2Z)
|
||||
.fSh2S(NechConfig.EnableFSh2S)
|
||||
.fCh2C(NechConfig.EnableFCh2C)
|
||||
.fAng2An(NechConfig.EnableFAng2An)
|
||||
.fIng2In(NechConfig.EnableFIng2In)
|
||||
.fEng2En(NechConfig.EnableFEng2En)
|
||||
.fU2V(NechConfig.EnableFU2V)
|
||||
.keyboard(NechConfig.KeyboardType.get())
|
||||
.commit();
|
||||
.fZh2Z(NechConfig.EnableFZh2Z)
|
||||
.fSh2S(NechConfig.EnableFSh2S)
|
||||
.fCh2C(NechConfig.EnableFCh2C)
|
||||
.fAng2An(NechConfig.EnableFAng2An)
|
||||
.fIng2In(NechConfig.EnableFIng2In)
|
||||
.fEng2En(NechConfig.EnableFEng2En)
|
||||
.fU2V(NechConfig.EnableFU2V)
|
||||
.keyboard(NechConfig.KeyboardType.get())
|
||||
.commit();
|
||||
}
|
||||
|
||||
|
||||
@Mod.EventHandler
|
||||
public void preInit(FMLPreInitializationEvent event) {
|
||||
logger.info("Not Enough Characters - v" + VERSION);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package net.vfyjxf.nechar;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
@@ -8,10 +12,7 @@ import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import net.vfyjxf.nechar.utils.Profiler;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.List;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class NechCommand extends CommandBase {
|
||||
|
||||
@@ -33,7 +34,10 @@ public class NechCommand extends CommandBase {
|
||||
Profiler.Report r = Profiler.run();
|
||||
try (FileOutputStream fos = new FileOutputStream("logs/necharacters-profiler.txt")) {
|
||||
OutputStreamWriter osw = new OutputStreamWriter(fos);
|
||||
osw.write(new GsonBuilder().setPrettyPrinting().create().toJson(r));
|
||||
osw.write(
|
||||
new GsonBuilder().setPrettyPrinting()
|
||||
.create()
|
||||
.toJson(r));
|
||||
osw.flush();
|
||||
sender.addChatMessage(new ChatComponentText(I18n.format("chat.saved")));
|
||||
} catch (IOException e) {
|
||||
@@ -42,8 +46,7 @@ public class NechCommand extends CommandBase {
|
||||
});
|
||||
t.setPriority(Thread.MIN_PRIORITY);
|
||||
t.start();
|
||||
}
|
||||
else if (args.length == 2 && "verbose".equals(args[0])) {
|
||||
} else if (args.length == 2 && "verbose".equals(args[0])) {
|
||||
switch (args[1].toLowerCase()) {
|
||||
case "true":
|
||||
NechConfig.enableVerbose = true;
|
||||
@@ -95,12 +98,20 @@ public class NechCommand extends CommandBase {
|
||||
|
||||
@Override
|
||||
public List addTabCompletionOptions(ICommandSender sender, String[] args) {
|
||||
if (args.length == 1)
|
||||
return getListOfStringsMatchingLastWord(args, "profile", "verbose", "keyboard");
|
||||
if (args.length == 1) return getListOfStringsMatchingLastWord(args, "profile", "verbose", "keyboard");
|
||||
else if (args.length == 2 && "verbose".equals(args[0]))
|
||||
return getListOfStringsMatchingLastWord(args, "true", "false");
|
||||
else if (args.length == 2 && "keyboard".equals(args[0]))
|
||||
return getListOfStringsMatchingLastWord(args, "quanpin", "daqian", "xiaohe", "ziranma", "sougou", "guobiao", "microsoft", "pinyinjiajia", "ziguang");
|
||||
else if (args.length == 2 && "keyboard".equals(args[0])) return getListOfStringsMatchingLastWord(
|
||||
args,
|
||||
"quanpin",
|
||||
"daqian",
|
||||
"xiaohe",
|
||||
"ziranma",
|
||||
"sougou",
|
||||
"guobiao",
|
||||
"microsoft",
|
||||
"pinyinjiajia",
|
||||
"ziguang");
|
||||
else return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package net.vfyjxf.nechar;
|
||||
|
||||
import me.towdium.pinin.Keyboard;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.moecraft.nechar.NotEnoughCharacters;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.moecraft.nechar.NotEnoughCharacters;
|
||||
|
||||
import me.towdium.pinin.Keyboard;
|
||||
|
||||
public class NechConfig {
|
||||
|
||||
@@ -21,79 +21,124 @@ public class NechConfig {
|
||||
public static String[] transformerRegExpAdditionalList = new String[0];
|
||||
public static String[] transformerStringAdditionalList = new String[0];
|
||||
public static String[] transformerMethodBlackList = new String[0];
|
||||
public static String[] defaultTransformerRegExp = new String[]{
|
||||
"appeng.client.me.ItemRepo:updateView",//Applied-Energistics-2 search
|
||||
"net.p455w0rd.wirelesscraftingterminal.client.me.ItemRepo:updateView",//WirelessCraftingTerminal search
|
||||
"com.glodblock.github.client.me.FluidRepo:updateView",//Ae2fc
|
||||
"com.glodblock.github.client.me.EssentiaRepo:updateView"
|
||||
public static String[] defaultTransformerRegExp = new String[] { "appeng.client.me.ItemRepo:updateView", // Applied-Energistics-2
|
||||
// search
|
||||
"net.p455w0rd.wirelesscraftingterminal.client.me.ItemRepo:updateView", // WirelessCraftingTerminal search
|
||||
"com.glodblock.github.client.me.FluidRepo:updateView", // Ae2fc
|
||||
"com.glodblock.github.client.me.EssentiaRepo:updateView"
|
||||
|
||||
};
|
||||
public static String[] defaultTransformerStringList = new String[]{
|
||||
"extracells.gui.GuiFluidTerminal:updateFluids",//Extra Cells FluidTerminal search
|
||||
"extracells.gui.GuiFluidStorage:updateFluids", //Extra Cells wireless terminal search
|
||||
"witchinggadgets.client.ThaumonomiconIndexSearcher:buildEntryList", //Witching Gadgets Thaumonomicon search
|
||||
"net.glease.tc4tweak.modules.researchBrowser.ThaumonomiconIndexSearcher:buildEntryList", // TC4 Tweaks Thaumonomicon search
|
||||
"appeng.client.gui.implementations.GuiInterfaceTerminal:refreshList", //Applied-Energistics-2 InterfaceTerminal
|
||||
"appeng.client.gui.implementations.GuiInterfaceTerminal:itemStackMatchesSearchTerm", //Applied-Energistics-2 InterfaceTerminal
|
||||
"vswe.stevesfactory.components.ComponentMenuLiquid:updateSearch", // Steve's Factory Manager liquid search
|
||||
"vswe.stevesfactory.components.ComponentMenuItem:updateSearch", // Steve's Factory Manager item search
|
||||
"betterquesting.api2.client.gui.panels.lists.CanvasQuestSearch:queryMatches", //Better Questing quest search --gtnh
|
||||
"me.towdium.jecalculation.utils.Utilities$I18n:contains",// Just Enough Calculation
|
||||
"logisticspipes.gui.orderer.GuiOrderer:isSearched", // Logistics Pipes orderer
|
||||
"logisticspipes.gui.orderer.GuiRequestTable:isSearched", // Logistics Pipes request table
|
||||
"mrtjp.projectred.transportation.GuiRequester$$anonfun$stringMatch$1$1:apply", // ProjectRed Expansion Routed Request pipe
|
||||
"com.glodblock.github.client.gui.GuiInterfaceTerminalWireless:refreshList", // ae2fc 2 Wireless Interface Terminal
|
||||
"com.glodblock.github.client.gui.GuiInterfaceTerminalWireless:itemStackMatchesSearchTerm", //ae2fc Wireless Interface Terminal
|
||||
"com.glodblock.github.client.gui.GuiInterfaceWireless$InterfaceWirelessList:updateList", //ae2fc Wireless Interface Terminal
|
||||
"com.glodblock.github.client.gui.GuiInterfaceWireless:itemStackMatchesSearchTerm",
|
||||
"com.glodblock.github.client.gui.GuiLevelTerminal$LevelTerminalList:update",
|
||||
"com.glodblock.github.client.gui.GuiLevelTerminal:itemStackMatchesSearchTerm",
|
||||
"appeng.client.gui.implementations.GuiInterfaceTerminal$InterfaceTerminalList:update",
|
||||
"appeng.client.gui.implementations.GuiInterfaceTerminal:itemStackMatchesSearchTerm",
|
||||
"com.glodblock.github.client.gui.GuiInterfaceWireless$InterfaceWirelessList:update"
|
||||
};
|
||||
public static String[] defaultTransformerStringList = new String[] { "extracells.gui.GuiFluidTerminal:updateFluids", // Extra
|
||||
// Cells
|
||||
// FluidTerminal
|
||||
// search
|
||||
"extracells.gui.GuiFluidStorage:updateFluids", // Extra Cells wireless terminal search
|
||||
"witchinggadgets.client.ThaumonomiconIndexSearcher:buildEntryList", // Witching Gadgets Thaumonomicon search
|
||||
"net.glease.tc4tweak.modules.researchBrowser.ThaumonomiconIndexSearcher:buildEntryList", // TC4 Tweaks
|
||||
// Thaumonomicon search
|
||||
"appeng.client.gui.implementations.GuiInterfaceTerminal:refreshList", // Applied-Energistics-2 InterfaceTerminal
|
||||
"appeng.client.gui.implementations.GuiInterfaceTerminal:itemStackMatchesSearchTerm", // Applied-Energistics-2
|
||||
// InterfaceTerminal
|
||||
"vswe.stevesfactory.components.ComponentMenuLiquid:updateSearch", // Steve's Factory Manager liquid search
|
||||
"vswe.stevesfactory.components.ComponentMenuItem:updateSearch", // Steve's Factory Manager item search
|
||||
"betterquesting.api2.client.gui.panels.lists.CanvasQuestSearch:queryMatches", // Better Questing quest search
|
||||
// --gtnh
|
||||
"me.towdium.jecalculation.utils.Utilities$I18n:contains", // Just Enough Calculation
|
||||
"logisticspipes.gui.orderer.GuiOrderer:isSearched", // Logistics Pipes orderer
|
||||
"logisticspipes.gui.orderer.GuiRequestTable:isSearched", // Logistics Pipes request table
|
||||
"mrtjp.projectred.transportation.GuiRequester$$anonfun$stringMatch$1$1:apply", // ProjectRed Expansion Routed
|
||||
// Request pipe
|
||||
"com.glodblock.github.client.gui.GuiInterfaceTerminalWireless:refreshList", // ae2fc 2 Wireless Interface
|
||||
// Terminal
|
||||
"com.glodblock.github.client.gui.GuiInterfaceTerminalWireless:itemStackMatchesSearchTerm", // ae2fc Wireless
|
||||
// Interface Terminal
|
||||
"com.glodblock.github.client.gui.GuiInterfaceWireless$InterfaceWirelessList:updateList", // ae2fc Wireless
|
||||
// Interface Terminal
|
||||
"com.glodblock.github.client.gui.GuiInterfaceWireless:itemStackMatchesSearchTerm",
|
||||
"com.glodblock.github.client.gui.GuiLevelTerminal$LevelTerminalList:update",
|
||||
"com.glodblock.github.client.gui.GuiLevelTerminal:itemStackMatchesSearchTerm",
|
||||
"appeng.client.gui.implementations.GuiInterfaceTerminal$InterfaceTerminalList:update",
|
||||
"appeng.client.gui.implementations.GuiInterfaceTerminal:itemStackMatchesSearchTerm",
|
||||
"com.glodblock.github.client.gui.GuiInterfaceWireless$InterfaceWirelessList:update" };
|
||||
|
||||
public static void loadConfig(File configFile) {
|
||||
Configuration config = new Configuration(configFile);
|
||||
config.load();
|
||||
config.get("transformers", "DefaultTransformerRegExp", defaultTransformerRegExp,
|
||||
"Default list of methods to transform, of which uses regular expression to match.\n" +
|
||||
"This list is maintained by the mod and will have no effect if you change it.");
|
||||
config.get("transformers", "DefaultTransformerString", defaultTransformerStringList,
|
||||
"Default list of methods to transform, of which uses \"String.contains\" to match.\n" +
|
||||
"This list is maintained by the mod and will have no effect if you change it.");
|
||||
config.get(
|
||||
"transformers",
|
||||
"DefaultTransformerRegExp",
|
||||
defaultTransformerRegExp,
|
||||
"Default list of methods to transform, of which uses regular expression to match.\n"
|
||||
+ "This list is maintained by the mod and will have no effect if you change it.");
|
||||
config.get(
|
||||
"transformers",
|
||||
"DefaultTransformerString",
|
||||
defaultTransformerStringList,
|
||||
"Default list of methods to transform, of which uses \"String.contains\" to match.\n"
|
||||
+ "This list is maintained by the mod and will have no effect if you change it.");
|
||||
|
||||
config.getCategory("transformers").get("DefaultTransformerRegExp").set(defaultTransformerRegExp);
|
||||
config.getCategory("transformers").get("DefaultTransformerString").set(defaultTransformerStringList);
|
||||
config.getCategory("transformers")
|
||||
.get("DefaultTransformerRegExp")
|
||||
.set(defaultTransformerRegExp);
|
||||
config.getCategory("transformers")
|
||||
.get("DefaultTransformerString")
|
||||
.set(defaultTransformerStringList);
|
||||
|
||||
transformerRegExpAdditionalList = config.get("transformers", "AdditionalTransformerRegExpList", new String[0],
|
||||
"Additional list of methods to transform, of which uses regular expression to match.\n" +
|
||||
"The format is \"full.class.path$InnerClass:methodName\"").getStringList();
|
||||
transformerRegExpAdditionalList = config
|
||||
.get(
|
||||
"transformers",
|
||||
"AdditionalTransformerRegExpList",
|
||||
new String[0],
|
||||
"Additional list of methods to transform, of which uses regular expression to match.\n"
|
||||
+ "The format is \"full.class.path$InnerClass:methodName\"")
|
||||
.getStringList();
|
||||
|
||||
transformerStringAdditionalList = config.get("transformers", "AdditionalTransformerStringList", new String[0],
|
||||
"Additional list of methods to transform, of which uses \"String.contains\" to match.\n" +
|
||||
"The format is \"full.class.path$InnerClass:methodName\"").getStringList();
|
||||
transformerStringAdditionalList = config
|
||||
.get(
|
||||
"transformers",
|
||||
"AdditionalTransformerStringList",
|
||||
new String[0],
|
||||
"Additional list of methods to transform, of which uses \"String.contains\" to match.\n"
|
||||
+ "The format is \"full.class.path$InnerClass:methodName\"")
|
||||
.getStringList();
|
||||
|
||||
transformerMethodBlackList = config.get("transformers", "transformerMethodBlackList", new String[0],
|
||||
"Blacklist of methods to transform\n" +
|
||||
"The format is \"full.class.path$InnerClass:methodName\"").getStringList();
|
||||
transformerMethodBlackList = config
|
||||
.get(
|
||||
"transformers",
|
||||
"transformerMethodBlackList",
|
||||
new String[0],
|
||||
"Blacklist of methods to transform\n" + "The format is \"full.class.path$InnerClass:methodName\"")
|
||||
.getStringList();
|
||||
|
||||
//Fuzzy config
|
||||
EnableFU2V = config.get("fuzzy", "EnableFU2V", false, "Set to true to enable fuzzy U <=> V").getBoolean();
|
||||
EnableFZh2Z = config.get("fuzzy", "EnableFZh2Z", false, "Set to true to enable fuzzy Zh <=> Z").getBoolean();
|
||||
EnableFSh2S = config.get("fuzzy", "EnableFSh2S", false, "Set to true to enable fuzzy Sh <=> S").getBoolean();
|
||||
EnableFCh2C = config.get("fuzzy", "EnableFCh2C", false, "Set to true to enable fuzzy Ch <=> C").getBoolean();
|
||||
EnableFAng2An = config.get("fuzzy", "EnableFAng2An", false, "Set to true to enable fuzzy Ang <=> An").getBoolean();
|
||||
EnableFIng2In = config.get("fuzzy", "EnableFIng2In", false, "Set to true to enable fuzzy Ing <=> In").getBoolean();
|
||||
EnableFEng2En = config.get("fuzzy", "EnableFEng2En", false, "Set to true to enable fuzzy Eng <=> En").getBoolean();
|
||||
// Fuzzy config
|
||||
EnableFU2V = config.get("fuzzy", "EnableFU2V", false, "Set to true to enable fuzzy U <=> V")
|
||||
.getBoolean();
|
||||
EnableFZh2Z = config.get("fuzzy", "EnableFZh2Z", false, "Set to true to enable fuzzy Zh <=> Z")
|
||||
.getBoolean();
|
||||
EnableFSh2S = config.get("fuzzy", "EnableFSh2S", false, "Set to true to enable fuzzy Sh <=> S")
|
||||
.getBoolean();
|
||||
EnableFCh2C = config.get("fuzzy", "EnableFCh2C", false, "Set to true to enable fuzzy Ch <=> C")
|
||||
.getBoolean();
|
||||
EnableFAng2An = config.get("fuzzy", "EnableFAng2An", false, "Set to true to enable fuzzy Ang <=> An")
|
||||
.getBoolean();
|
||||
EnableFIng2In = config.get("fuzzy", "EnableFIng2In", false, "Set to true to enable fuzzy Ing <=> In")
|
||||
.getBoolean();
|
||||
EnableFEng2En = config.get("fuzzy", "EnableFEng2En", false, "Set to true to enable fuzzy Eng <=> En")
|
||||
.getBoolean();
|
||||
|
||||
// keyboard type config
|
||||
String keyboardTypeString = config.get("general", "KeyboardType", "quanpin", "Set the type of the keyboard, acceptable options are: quanpin, daqian, xiaohe and ziranma.").getString();
|
||||
try{
|
||||
String keyboardTypeString = config
|
||||
.get(
|
||||
"general",
|
||||
"KeyboardType",
|
||||
"quanpin",
|
||||
"Set the type of the keyboard, acceptable options are: quanpin, daqian, xiaohe and ziranma.")
|
||||
.getString();
|
||||
try {
|
||||
KeyboardType = Spell.valueOf(keyboardTypeString.toUpperCase());
|
||||
} catch (IllegalArgumentException e) {
|
||||
NotEnoughCharacters.logger.error("Invalid keyboard type: " + keyboardTypeString);
|
||||
//use default value
|
||||
// use default value
|
||||
KeyboardType = Spell.QUANPIN;
|
||||
}
|
||||
|
||||
@@ -106,10 +151,15 @@ public class NechConfig {
|
||||
}
|
||||
|
||||
public enum Spell {
|
||||
QUANPIN(Keyboard.QUANPIN), DAQIAN(Keyboard.DAQIAN),
|
||||
XIAOHE(Keyboard.XIAOHE), ZIRANMA(Keyboard.ZIRANMA),
|
||||
SOUGOU(Keyboard.SOUGOU), GUOBIAO(Keyboard.GUOBIAO),
|
||||
MICROSOFT(Keyboard.MICROSOFT), PINYINPP(Keyboard.PINYINPP),
|
||||
|
||||
QUANPIN(Keyboard.QUANPIN),
|
||||
DAQIAN(Keyboard.DAQIAN),
|
||||
XIAOHE(Keyboard.XIAOHE),
|
||||
ZIRANMA(Keyboard.ZIRANMA),
|
||||
SOUGOU(Keyboard.SOUGOU),
|
||||
GUOBIAO(Keyboard.GUOBIAO),
|
||||
MICROSOFT(Keyboard.MICROSOFT),
|
||||
PINYINPP(Keyboard.PINYINPP),
|
||||
ZIGUANG(Keyboard.ZIGUANG);
|
||||
|
||||
public final Keyboard keyboard;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/jecharacters/core/JechClassTransformer.java)
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/
|
||||
* jecharacters/core/JechClassTransformer.java)
|
||||
* 原文件协议为MIT
|
||||
*/
|
||||
|
||||
@@ -10,6 +11,7 @@ import net.vfyjxf.nechar.transform.Transformer;
|
||||
import net.vfyjxf.nechar.transform.TransformerRegistry;
|
||||
|
||||
public class NechClassTransformer implements IClassTransformer {
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
@Override
|
||||
public byte[] transform(String s, String s1, byte[] bytes) {
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package net.vfyjxf.nechar.core;
|
||||
|
||||
import cpw.mods.fml.relauncher.IFMLCallHook;
|
||||
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
|
||||
import net.vfyjxf.nechar.transform.TransformerRegistry;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import net.vfyjxf.nechar.transform.TransformerRegistry;
|
||||
|
||||
import cpw.mods.fml.relauncher.IFMLCallHook;
|
||||
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
|
||||
|
||||
public class NechCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
|
||||
|
||||
public static boolean INITIALIZED = false;
|
||||
|
||||
@Override
|
||||
public String[] getASMTransformerClass() {
|
||||
return new String[]{"net.vfyjxf.nechar.core.NechClassTransformer"};
|
||||
return new String[] { "net.vfyjxf.nechar.core.NechClassTransformer" };
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,51 +1,79 @@
|
||||
/*
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/jecharacters/transform/Transformer.java)
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/
|
||||
* jecharacters/transform/Transformer.java)
|
||||
* 原文件协议为MIT
|
||||
*/
|
||||
|
||||
package net.vfyjxf.nechar.transform;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import net.moecraft.nechar.NotEnoughCharacters;
|
||||
import net.vfyjxf.nechar.NechConfig;
|
||||
import org.objectweb.asm.*;
|
||||
import org.objectweb.asm.tree.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
import net.moecraft.nechar.NotEnoughCharacters;
|
||||
import net.vfyjxf.nechar.NechConfig;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Handle;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnNode;
|
||||
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.tree.TypeInsnNode;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
public interface Transformer {
|
||||
|
||||
static Optional<MethodNode> findMethod(ClassNode c, String name) {
|
||||
Optional<MethodNode> ret = c.methods.stream().filter(methodNode -> methodNode.name.equals(name))
|
||||
.findFirst();
|
||||
Optional<MethodNode> ret = c.methods.stream()
|
||||
.filter(methodNode -> methodNode.name.equals(name))
|
||||
.findFirst();
|
||||
String s = ret.isPresent() ? "," : ", not";
|
||||
NotEnoughCharacters.logger.info("Finding method " + name + " in class " + c.name + s + " found.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Optional<MethodNode> findMethod(ClassNode c, String name, String desc) {
|
||||
Optional<MethodNode> ret = c.methods.stream().filter(methodNode -> methodNode.name.equals(name))
|
||||
.filter(methodNode -> methodNode.desc.equals(desc)).findFirst();
|
||||
Optional<MethodNode> ret = c.methods.stream()
|
||||
.filter(methodNode -> methodNode.name.equals(name))
|
||||
.filter(methodNode -> methodNode.desc.equals(desc))
|
||||
.findFirst();
|
||||
String s = ret.isPresent() ? "," : ", not";
|
||||
NotEnoughCharacters.logger.info("Finding method " + name + desc + " in class " + c.name + s + " found.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static boolean transformInvoke(
|
||||
MethodNode methodNode, String owner, String name, String newOwner, String newName,
|
||||
String id, boolean isInterface, int op, @Nullable String arg1, @Nullable String arg2) {
|
||||
NotEnoughCharacters.logger.info("Transforming invoke of " + owner + "." + name +
|
||||
" to " + newOwner + "." + newName + " in method " + methodNode.name + ".");
|
||||
static boolean transformInvoke(MethodNode methodNode, String owner, String name, String newOwner, String newName,
|
||||
String id, boolean isInterface, int op, @Nullable String arg1, @Nullable String arg2) {
|
||||
NotEnoughCharacters.logger.info(
|
||||
"Transforming invoke of " + owner
|
||||
+ "."
|
||||
+ name
|
||||
+ " to "
|
||||
+ newOwner
|
||||
+ "."
|
||||
+ newName
|
||||
+ " in method "
|
||||
+ methodNode.name
|
||||
+ ".");
|
||||
|
||||
Iterator<AbstractInsnNode> iterator = methodNode.instructions.iterator();
|
||||
|
||||
boolean ret = false;
|
||||
while (iterator.hasNext()) {
|
||||
AbstractInsnNode node = iterator.next();
|
||||
if (node instanceof MethodInsnNode && (node.getOpcode() == Opcodes.INVOKEVIRTUAL ||
|
||||
node.getOpcode() == Opcodes.INVOKESPECIAL || node.getOpcode() == Opcodes.INVOKESTATIC)) {
|
||||
if (node instanceof MethodInsnNode
|
||||
&& (node.getOpcode() == Opcodes.INVOKEVIRTUAL || node.getOpcode() == Opcodes.INVOKESPECIAL
|
||||
|| node.getOpcode() == Opcodes.INVOKESTATIC)) {
|
||||
MethodInsnNode insnNode = ((MethodInsnNode) node);
|
||||
if (insnNode.owner.equals(owner) && insnNode.name.equals(name)) {
|
||||
methodNode.instructions.set(insnNode, new MethodInsnNode(op, newOwner, newName, id, isInterface));
|
||||
@@ -53,15 +81,20 @@ public interface Transformer {
|
||||
}
|
||||
}
|
||||
if (node instanceof InvokeDynamicInsnNode && node.getOpcode() == Opcodes.INVOKEDYNAMIC
|
||||
&& arg1 != null && arg2 != null) {
|
||||
&& arg1 != null
|
||||
&& arg2 != null) {
|
||||
InvokeDynamicInsnNode insnNode = ((InvokeDynamicInsnNode) node);
|
||||
if (insnNode.bsmArgs[1] instanceof Handle) {
|
||||
Handle h = ((Handle) insnNode.bsmArgs[1]);
|
||||
if (h.getOwner().equals(owner) && h.getName().equals(name)) {
|
||||
@SuppressWarnings("deprecation") Object[] args = {Type.getType(arg1),
|
||||
new Handle(6, newOwner, newName, id), Type.getType(arg2)};
|
||||
methodNode.instructions.set(insnNode,
|
||||
new InvokeDynamicInsnNode(insnNode.name, insnNode.desc, insnNode.bsm, args));
|
||||
if (h.getOwner()
|
||||
.equals(owner)
|
||||
&& h.getName()
|
||||
.equals(name)) {
|
||||
@SuppressWarnings("deprecation")
|
||||
Object[] args = { Type.getType(arg1), new Handle(6, newOwner, newName, id),
|
||||
Type.getType(arg2) };
|
||||
methodNode.instructions
|
||||
.set(insnNode, new InvokeDynamicInsnNode(insnNode.name, insnNode.desc, insnNode.bsm, args));
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
@@ -71,8 +104,8 @@ public interface Transformer {
|
||||
}
|
||||
|
||||
static void transformConstruct(MethodNode methodNode, String desc, String destNew) {
|
||||
NotEnoughCharacters.logger.info("Transforming constructor of " + desc +
|
||||
" to " + destNew + " in method " + methodNode.name + ".");
|
||||
NotEnoughCharacters.logger
|
||||
.info("Transforming constructor of " + desc + " to " + destNew + " in method " + methodNode.name + ".");
|
||||
Iterator<AbstractInsnNode> i = methodNode.instructions.iterator();
|
||||
int cnt = 0;
|
||||
while (i.hasNext()) {
|
||||
@@ -100,8 +133,8 @@ public interface Transformer {
|
||||
while (i.hasNext()) {
|
||||
AbstractInsnNode node = i.next();
|
||||
if (node instanceof InsnNode && node.getOpcode() == Opcodes.RETURN) {
|
||||
methodNode.instructions.insertBefore(node, new MethodInsnNode(Opcodes.INVOKESTATIC,
|
||||
owner, name, id, false));
|
||||
methodNode.instructions
|
||||
.insertBefore(node, new MethodInsnNode(Opcodes.INVOKESTATIC, owner, name, id, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,6 +144,7 @@ public interface Transformer {
|
||||
byte[] transform(byte[] bytes);
|
||||
|
||||
abstract class Default implements Transformer {
|
||||
|
||||
@Override
|
||||
public byte[] transform(byte[] bytes) {
|
||||
ClassNode classNode = new ClassNode();
|
||||
@@ -126,6 +160,7 @@ public interface Transformer {
|
||||
}
|
||||
|
||||
abstract class Configurable extends Default {
|
||||
|
||||
protected MethodDecoder md = new MethodDecoder();
|
||||
|
||||
protected abstract String[] getDefault();
|
||||
@@ -140,7 +175,9 @@ public interface Transformer {
|
||||
protected void transform(ClassNode c) {
|
||||
NotEnoughCharacters.logger.info("Transforming class " + c.name + " for " + getName() + ".");
|
||||
Set<String> ms = md.getMethodsForClass(c.name.replace('/', '.'));
|
||||
if (!ms.isEmpty()) c.methods.stream().filter(m -> ms.contains(m.name)).forEach(this::transform);
|
||||
if (!ms.isEmpty()) c.methods.stream()
|
||||
.filter(m -> ms.contains(m.name))
|
||||
.forEach(this::transform);
|
||||
else NotEnoughCharacters.logger.info("No function matched in class " + c.name);
|
||||
}
|
||||
|
||||
@@ -159,6 +196,7 @@ public interface Transformer {
|
||||
}
|
||||
|
||||
class MethodDecoder {
|
||||
|
||||
HashMultimap<String, String> methods = HashMultimap.create();
|
||||
|
||||
public static void logError(String s) {
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/*
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/jecharacters/transform/TransformerRegistry.java)
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/
|
||||
* jecharacters/transform/TransformerRegistry.java)
|
||||
* 原文件协议为MIT
|
||||
*/
|
||||
|
||||
package net.vfyjxf.nechar.transform;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.vfyjxf.nechar.transform.transformers.TransformerRegExp;
|
||||
import net.vfyjxf.nechar.transform.transformers.TransformerString;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TransformerRegistry {
|
||||
|
||||
public static ArrayList<Transformer.Configurable> configurables = new ArrayList<>();
|
||||
public static ArrayList<Transformer> transformers = new ArrayList<>();
|
||||
|
||||
@@ -23,8 +25,7 @@ public class TransformerRegistry {
|
||||
public static ArrayList<Transformer> getTransformer(String name) {
|
||||
ArrayList<Transformer> ret = new ArrayList<>();
|
||||
for (Transformer t : transformers) {
|
||||
if (t.accepts(name))
|
||||
ret.add(t);
|
||||
if (t.accepts(name)) ret.add(t);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/jecharacters/transform/transformers/TransformerRegExp.java)
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/
|
||||
* jecharacters/transform/transformers/TransformerRegExp.java)
|
||||
* 原文件协议为MIT
|
||||
*/
|
||||
|
||||
@@ -7,6 +8,7 @@ package net.vfyjxf.nechar.transform.transformers;
|
||||
|
||||
import net.vfyjxf.nechar.NechConfig;
|
||||
import net.vfyjxf.nechar.transform.Transformer;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
@@ -16,7 +18,6 @@ public class TransformerRegExp extends Transformer.Configurable {
|
||||
reload();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String[] getDefault() {
|
||||
return NechConfig.defaultTransformerRegExp;
|
||||
@@ -27,7 +28,6 @@ public class TransformerRegExp extends Transformer.Configurable {
|
||||
return NechConfig.transformerRegExpAdditionalList;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getName() {
|
||||
return "regular expression";
|
||||
@@ -36,18 +36,27 @@ public class TransformerRegExp extends Transformer.Configurable {
|
||||
@Override
|
||||
protected void transform(MethodNode n) {
|
||||
Transformer.transformInvoke(
|
||||
n, "java/util/regex/Pattern", "matcher",
|
||||
"net/vfyjxf/nechar/utils/Match", "matcher",
|
||||
"(Ljava/util/regex/Pattern;Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;",
|
||||
false, Opcodes.INVOKESTATIC, null, null
|
||||
);
|
||||
n,
|
||||
"java/util/regex/Pattern",
|
||||
"matcher",
|
||||
"net/vfyjxf/nechar/utils/Match",
|
||||
"matcher",
|
||||
"(Ljava/util/regex/Pattern;Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;",
|
||||
false,
|
||||
Opcodes.INVOKESTATIC,
|
||||
null,
|
||||
null);
|
||||
Transformer.transformInvoke(
|
||||
n, "java/lang/String", "matches",
|
||||
"net/vfyjxf/nechar/utils/Match", "matches",
|
||||
"(Ljava/lang/String;Ljava/lang/CharSequence;)Z",
|
||||
false, Opcodes.INVOKESTATIC, "(Ljava/lang/Object;)Z", "(Ljava/lang/String;)Z"
|
||||
);
|
||||
n,
|
||||
"java/lang/String",
|
||||
"matches",
|
||||
"net/vfyjxf/nechar/utils/Match",
|
||||
"matches",
|
||||
"(Ljava/lang/String;Ljava/lang/CharSequence;)Z",
|
||||
false,
|
||||
Opcodes.INVOKESTATIC,
|
||||
"(Ljava/lang/Object;)Z",
|
||||
"(Ljava/lang/String;)Z");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/jecharacters/transform/transformers/TransformerString.java)
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/
|
||||
* jecharacters/transform/transformers/TransformerString.java)
|
||||
* 原文件协议为MIT
|
||||
*/
|
||||
|
||||
@@ -7,12 +8,13 @@ package net.vfyjxf.nechar.transform.transformers;
|
||||
|
||||
import net.vfyjxf.nechar.NechConfig;
|
||||
import net.vfyjxf.nechar.transform.Transformer;
|
||||
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
public class TransformerString extends Transformer.Configurable {
|
||||
|
||||
public TransformerString(){
|
||||
public TransformerString() {
|
||||
reload();
|
||||
}
|
||||
|
||||
@@ -26,7 +28,6 @@ public class TransformerString extends Transformer.Configurable {
|
||||
return NechConfig.transformerStringAdditionalList;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getName() {
|
||||
return "string contains";
|
||||
@@ -35,10 +36,15 @@ public class TransformerString extends Transformer.Configurable {
|
||||
@Override
|
||||
protected void transform(MethodNode n) {
|
||||
Transformer.transformInvoke(
|
||||
n, "java/lang/String", "contains",
|
||||
"net/vfyjxf/nechar/utils/Match", "contains",
|
||||
"(Ljava/lang/String;Ljava/lang/CharSequence;)Z",
|
||||
false, Opcodes.INVOKESTATIC, "(Ljava/lang/Object;)Z", "(Ljava/lang/String;)Z"
|
||||
);
|
||||
n,
|
||||
"java/lang/String",
|
||||
"contains",
|
||||
"net/vfyjxf/nechar/utils/Match",
|
||||
"contains",
|
||||
"(Ljava/lang/String;Ljava/lang/CharSequence;)Z",
|
||||
false,
|
||||
Opcodes.INVOKESTATIC,
|
||||
"(Ljava/lang/Object;)Z",
|
||||
"(Ljava/lang/String;)Z");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/jecharacters/transform/transformers/TransformerRegExp.java)
|
||||
* 基于Towdium的JustEnoughCharacters(https://github.com/Towdium/JustEnoughCharacters/blob/1.12.0/src/main/java/me/towdium/
|
||||
* jecharacters/transform/transformers/TransformerRegExp.java)
|
||||
* 原文件协议为MIT
|
||||
*/
|
||||
|
||||
@@ -26,15 +27,18 @@ public class Match {
|
||||
}
|
||||
|
||||
public static boolean contains(String s, CharSequence cs) {
|
||||
// NotEnoughCharacters.logger.info("contains(" + s + ',' + cs + ")->" + b);
|
||||
// NotEnoughCharacters.logger.info("contains(" + s + ',' + cs + ")->" + b);
|
||||
return CONTEXT.contains(s, cs.toString());
|
||||
}
|
||||
|
||||
|
||||
public static Matcher matcher(Pattern test, CharSequence name) {
|
||||
boolean result;
|
||||
if ((test.flags() & Pattern.CASE_INSENSITIVE) != 0 || (test.flags() & Pattern.UNICODE_CASE) != 0) {
|
||||
result = matches(name.toString().toLowerCase(), test.toString().toLowerCase());
|
||||
result = matches(
|
||||
name.toString()
|
||||
.toLowerCase(),
|
||||
test.toString()
|
||||
.toLowerCase());
|
||||
} else {
|
||||
result = matches(name.toString(), test.toString());
|
||||
}
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
package net.vfyjxf.nechar.utils;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.moecraft.nechar.NotEnoughCharacters;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
@@ -10,19 +23,12 @@ import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.TypeInsnNode;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.zip.ZipFile;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class Profiler {
|
||||
|
||||
private static final JarContainer[] EMPTY_JC = new JarContainer[]{};
|
||||
private static final String[] EMPTY_STR = new String[]{};
|
||||
private static final JarContainer[] EMPTY_JC = new JarContainer[] {};
|
||||
private static final String[] EMPTY_STR = new String[] {};
|
||||
|
||||
public static Report run() {
|
||||
File modDirectory = new File("mods");
|
||||
@@ -38,7 +44,8 @@ public class Profiler {
|
||||
Consumer<JarContainer> callback = jcs::add;
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isFile() && file.getName().endsWith(".jar")) {
|
||||
if (file.isFile() && file.getName()
|
||||
.endsWith(".jar")) {
|
||||
try (ZipFile mod = new ZipFile(file)) {
|
||||
scanJar(mod, callback);
|
||||
} catch (IOException e) {
|
||||
@@ -58,34 +65,49 @@ public class Profiler {
|
||||
ArrayList<String> methodsSuffix = new ArrayList<>();
|
||||
ArrayList<String> methodsStrsKt = new ArrayList<>();
|
||||
JarContainer ret = new JarContainer();
|
||||
f.stream().forEach(entry -> {
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
try (InputStream is = f.getInputStream(entry)) {
|
||||
long size = entry.getSize() + 4;
|
||||
if (size > Integer.MAX_VALUE) {
|
||||
NotEnoughCharacters.logger.info("Class file " + entry.getName()
|
||||
+ " in jar file " + f.getName() + " is too large, skip.");
|
||||
} else {
|
||||
scanClass(is, methodsString::add, methodsRegExp::add, methodsSuffix::add, methodsStrsKt::add);
|
||||
f.stream()
|
||||
.forEach(entry -> {
|
||||
if (entry.getName()
|
||||
.endsWith(".class")) {
|
||||
try (InputStream is = f.getInputStream(entry)) {
|
||||
long size = entry.getSize() + 4;
|
||||
if (size > Integer.MAX_VALUE) {
|
||||
NotEnoughCharacters.logger.info(
|
||||
"Class file " + entry.getName()
|
||||
+ " in jar file "
|
||||
+ f.getName()
|
||||
+ " is too large, skip.");
|
||||
} else {
|
||||
scanClass(
|
||||
is,
|
||||
methodsString::add,
|
||||
methodsRegExp::add,
|
||||
methodsSuffix::add,
|
||||
methodsStrsKt::add);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NotEnoughCharacters.logger
|
||||
.info("Fail to read file " + entry.getName() + " in jar file " + f.getName() + ", skip.");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NotEnoughCharacters.logger.info("Fail to read file " + entry.getName()
|
||||
+ " in jar file " + f.getName() + ", skip.");
|
||||
}
|
||||
} else if (entry.getName().equals("mcmod.info")) {
|
||||
Gson gson = new Gson();
|
||||
try (InputStream is = f.getInputStream(entry)) {
|
||||
try {
|
||||
ret.mods = gson.fromJson(new InputStreamReader(is), ModContainer[].class);
|
||||
} catch (Exception e) {
|
||||
ret.mods = new ModContainer[]{gson.fromJson(new InputStreamReader(is), ModContainer.class)};
|
||||
} else if (entry.getName()
|
||||
.equals("mcmod.info")) {
|
||||
Gson gson = new Gson();
|
||||
try (InputStream is = f.getInputStream(entry)) {
|
||||
try {
|
||||
ret.mods = gson.fromJson(new InputStreamReader(is), ModContainer[].class);
|
||||
} catch (Exception e) {
|
||||
ret.mods = new ModContainer[] {
|
||||
gson.fromJson(new InputStreamReader(is), ModContainer.class) };
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NotEnoughCharacters.logger
|
||||
.info("Fail to read mod info in jar file " + f.getName() + ", skip.");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NotEnoughCharacters.logger.info("Fail to read mod info in jar file " + f.getName() + ", skip.");
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!methodsString.isEmpty() || !methodsRegExp.isEmpty() || !methodsSuffix.isEmpty() || !methodsStrsKt.isEmpty()) {
|
||||
});
|
||||
if (!methodsString.isEmpty() || !methodsRegExp.isEmpty()
|
||||
|| !methodsSuffix.isEmpty()
|
||||
|| !methodsStrsKt.isEmpty()) {
|
||||
ret.methodsString = methodsString.toArray(EMPTY_STR);
|
||||
ret.methodsRegExp = methodsRegExp.toArray(EMPTY_STR);
|
||||
ret.methodsSuffix = methodsSuffix.toArray(EMPTY_STR);
|
||||
@@ -95,14 +117,15 @@ public class Profiler {
|
||||
}
|
||||
|
||||
private static void scanClass(InputStream is, Consumer<String> string, Consumer<String> regexp,
|
||||
Consumer<String> suffix, Consumer<String> strskt) throws IOException {
|
||||
Consumer<String> suffix, Consumer<String> strskt) throws IOException {
|
||||
ClassNode classNode = new ClassNode();
|
||||
ClassReader classReader = new ClassReader(is);
|
||||
try {
|
||||
classReader.accept(classNode, 0);
|
||||
} catch (Exception e) {
|
||||
if (classNode.name != null) {
|
||||
NotEnoughCharacters.logger.info("File decoding of class " + classNode.name + " failed. Try to continue.");
|
||||
NotEnoughCharacters.logger
|
||||
.info("File decoding of class " + classNode.name + " failed. Try to continue.");
|
||||
} else {
|
||||
throw new IOException(e);
|
||||
}
|
||||
@@ -115,30 +138,40 @@ public class Profiler {
|
||||
if (node instanceof MethodInsnNode) {
|
||||
MethodInsnNode mNode = ((MethodInsnNode) node);
|
||||
if (mNode.getOpcode() == Opcodes.INVOKEVIRTUAL && mNode.owner.equals("java/lang/String")
|
||||
&& mNode.name.equals("contains") && mNode.desc.equals("(Ljava/lang/CharSequence;)Z")) {
|
||||
string.accept((classNode.name + ":" + methodNode.name + ":" + methodNode.desc).replace('/', '.'));
|
||||
&& mNode.name.equals("contains")
|
||||
&& mNode.desc.equals("(Ljava/lang/CharSequence;)Z")) {
|
||||
string
|
||||
.accept((classNode.name + ":" + methodNode.name + ":" + methodNode.desc).replace('/', '.'));
|
||||
break;
|
||||
} else if (mNode.getOpcode() == Opcodes.INVOKEVIRTUAL && mNode.owner.equals("java/lang/String")
|
||||
&& mNode.name.equals("matches") && mNode.desc.equals("(Ljava/lang/String;)Z")) {
|
||||
regexp.accept((classNode.name + ":" + methodNode.name + ":" + methodNode.desc).replace('/', '.'));
|
||||
break;
|
||||
} else if (mNode.getOpcode() == Opcodes.INVOKEVIRTUAL && mNode.owner.equals("java/util/regex/Pattern")
|
||||
&& mNode.name.equals("matches")
|
||||
&& mNode.desc.equals("(Ljava/lang/String;)Z")) {
|
||||
regexp.accept(
|
||||
(classNode.name + ":" + methodNode.name + ":" + methodNode.desc).replace('/', '.'));
|
||||
break;
|
||||
} else
|
||||
if (mNode.getOpcode() == Opcodes.INVOKEVIRTUAL && mNode.owner.equals("java/util/regex/Pattern")
|
||||
&& mNode.name.equals("matcher")
|
||||
&& mNode.desc.equals("(Ljava/lang/CharSequence;)Ljava/util/regex/Matcher;")) {
|
||||
regexp.accept((classNode.name + ":" + methodNode.name + ":" + methodNode.desc).replace('/', '.'));
|
||||
break;
|
||||
} else if (mNode.getOpcode() == Opcodes.INVOKESTATIC && mNode.owner.equals("kotlin/text/StringsKt")
|
||||
&& mNode.name.equals("contains") && mNode.desc.equals("(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Z)Z")) {
|
||||
strskt.accept((classNode.name + ":" + methodNode.name + ":" + methodNode.desc).replace('/', '.'));
|
||||
break;
|
||||
}
|
||||
regexp.accept(
|
||||
(classNode.name + ":" + methodNode.name + ":" + methodNode.desc).replace('/', '.'));
|
||||
break;
|
||||
} else
|
||||
if (mNode.getOpcode() == Opcodes.INVOKESTATIC && mNode.owner.equals("kotlin/text/StringsKt")
|
||||
&& mNode.name.equals("contains")
|
||||
&& mNode.desc.equals("(Ljava/lang/CharSequence;Ljava/lang/CharSequence;Z)Z")) {
|
||||
strskt.accept(
|
||||
(classNode.name + ":" + methodNode.name + ":" + methodNode.desc)
|
||||
.replace('/', '.'));
|
||||
break;
|
||||
}
|
||||
} else if (node instanceof TypeInsnNode) {
|
||||
TypeInsnNode tNode = ((TypeInsnNode) node);
|
||||
if (tNode.getOpcode() == Opcodes.NEW && (
|
||||
tNode.desc.equals("net/minecraft/client/util/SuffixArray")
|
||||
|| tNode.desc.equals("cgx")) || tNode.desc.equals("cgz")) {
|
||||
suffix.accept((classNode.name + ":" + methodNode.name + ":" + methodNode.desc)
|
||||
.replace('/', '.'));
|
||||
if (tNode.getOpcode() == Opcodes.NEW
|
||||
&& (tNode.desc.equals("net/minecraft/client/util/SuffixArray") || tNode.desc.equals("cgx"))
|
||||
|| tNode.desc.equals("cgz")) {
|
||||
suffix
|
||||
.accept((classNode.name + ":" + methodNode.name + ":" + methodNode.desc).replace('/', '.'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -148,6 +181,7 @@ public class Profiler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static class Report {
|
||||
|
||||
String version = "@VERSION@";
|
||||
String mcversion = MinecraftForge.MC_VERSION;
|
||||
String date;
|
||||
@@ -161,6 +195,7 @@ public class Profiler {
|
||||
}
|
||||
|
||||
private static class JarContainer {
|
||||
|
||||
ModContainer[] mods;
|
||||
String[] methodsString;
|
||||
String[] methodsRegExp;
|
||||
@@ -170,6 +205,7 @@ public class Profiler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class ModContainer {
|
||||
|
||||
String modid;
|
||||
String name;
|
||||
String version;
|
||||
|
||||
Reference in new issue
Block a user