Merge remote-tracking branch 'origin/main' into 1.18
This commit is contained in:
commit
7a4c027d0f
|
|
@ -1,18 +1,23 @@
|
||||||
package org.embeddedt.modernfix;
|
package org.embeddedt.modernfix;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.InputConstants;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import net.minecraft.client.KeyMapping;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
import net.minecraft.client.gui.components.DebugScreenOverlay;
|
||||||
import net.minecraft.client.gui.screens.ConnectScreen;
|
import net.minecraft.client.gui.screens.ConnectScreen;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
import net.minecraft.util.MemoryReserve;
|
import net.minecraft.util.MemoryReserve;
|
||||||
|
import net.minecraftforge.client.ClientRegistry;
|
||||||
|
import net.minecraftforge.client.ConfigGuiHandler;
|
||||||
import net.minecraftforge.client.event.ScreenEvent;
|
import net.minecraftforge.client.event.ScreenEvent;
|
||||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
import net.minecraft.network.syncher.EntityDataAccessor;
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
import net.minecraft.network.syncher.SynchedEntityData;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraftforge.client.event.*;
|
import net.minecraftforge.client.event.*;
|
||||||
import net.minecraftforge.client.gui.ForgeIngameGui;
|
import net.minecraftforge.client.gui.ForgeIngameGui;
|
||||||
|
import net.minecraftforge.client.settings.KeyConflictContext;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.event.TagsUpdatedEvent;
|
import net.minecraftforge.event.TagsUpdatedEvent;
|
||||||
import net.minecraftforge.event.TickEvent;
|
import net.minecraftforge.event.TickEvent;
|
||||||
|
|
@ -20,13 +25,18 @@ import net.minecraftforge.event.server.ServerStartingEvent;
|
||||||
import net.minecraftforge.event.world.WorldEvent;
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
import net.minecraftforge.eventbus.api.EventPriority;
|
import net.minecraftforge.eventbus.api.EventPriority;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.IExtensionPoint;
|
||||||
import net.minecraftforge.fml.ModContainer;
|
import net.minecraftforge.fml.ModContainer;
|
||||||
import net.minecraftforge.fml.ModList;
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.fml.ModLoadingContext;
|
||||||
|
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
|
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
|
||||||
import net.minecraftforge.network.NetworkEvent;
|
import net.minecraftforge.network.NetworkEvent;
|
||||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||||
import org.embeddedt.modernfix.packet.EntityIDSyncPacket;
|
import org.embeddedt.modernfix.packet.EntityIDSyncPacket;
|
||||||
|
import org.embeddedt.modernfix.screen.ModernFixConfigScreen;
|
||||||
import org.embeddedt.modernfix.world.IntegratedWatchdog;
|
import org.embeddedt.modernfix.world.IntegratedWatchdog;
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
|
|
@ -52,6 +62,27 @@ public class ModernFixClient {
|
||||||
if(mfContainer.isPresent())
|
if(mfContainer.isPresent())
|
||||||
brandingString = "ModernFix " + mfContainer.get().getModInfo().getVersion().toString();
|
brandingString = "ModernFix " + mfContainer.get().getModInfo().getVersion().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup);
|
||||||
|
ModLoadingContext.get().registerExtensionPoint(
|
||||||
|
ConfigGuiHandler.ConfigGuiFactory.class,
|
||||||
|
() -> new ConfigGuiHandler.ConfigGuiFactory((mc, screen) -> new ModernFixConfigScreen(screen))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyMapping configKey;
|
||||||
|
|
||||||
|
private void clientSetup(FMLClientSetupEvent event) {
|
||||||
|
configKey = new KeyMapping("key.modernfix.config", KeyConflictContext.UNIVERSAL, InputConstants.UNKNOWN, "key.modernfix");
|
||||||
|
ClientRegistry.registerKeyBinding(configKey);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onConfigKey(TickEvent.ClientTickEvent event) {
|
||||||
|
if(event.phase == TickEvent.Phase.START && configKey.consumeClick()) {
|
||||||
|
Minecraft.getInstance().setScreen(new ModernFixConfigScreen(Minecraft.getInstance().screen));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetWorldLoadStateMachine() {
|
public void resetWorldLoadStateMachine() {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ public class ModernFixEarlyConfig {
|
||||||
|
|
||||||
public static final boolean OPTIFINE_PRESENT;
|
public static final boolean OPTIFINE_PRESENT;
|
||||||
|
|
||||||
|
private File configFile;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
boolean hasOfClass = false;
|
boolean hasOfClass = false;
|
||||||
try {
|
try {
|
||||||
|
|
@ -34,7 +36,8 @@ public class ModernFixEarlyConfig {
|
||||||
return FMLLoader.getLoadingModList().getModFileById(modId) != null;
|
return FMLLoader.getLoadingModList().getModFileById(modId) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModernFixEarlyConfig() {
|
private ModernFixEarlyConfig(File file) {
|
||||||
|
this.configFile = file;
|
||||||
// Defines the default rules which can be configured by the user or other mods.
|
// Defines the default rules which can be configured by the user or other mods.
|
||||||
// You must manually add a rule for any new mixins not covered by an existing package rule.
|
// You must manually add a rule for any new mixins not covered by an existing package rule.
|
||||||
this.addMixinRule("core", true); // TODO: Don't actually allow the user to disable this
|
this.addMixinRule("core", true); // TODO: Don't actually allow the user to disable this
|
||||||
|
|
@ -188,7 +191,7 @@ public class ModernFixEarlyConfig {
|
||||||
* created. The file on disk will then be updated to include any new options.
|
* created. The file on disk will then be updated to include any new options.
|
||||||
*/
|
*/
|
||||||
public static ModernFixEarlyConfig load(File file) {
|
public static ModernFixEarlyConfig load(File file) {
|
||||||
ModernFixEarlyConfig config = new ModernFixEarlyConfig();
|
ModernFixEarlyConfig config = new ModernFixEarlyConfig(file);
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
if(file.exists()) {
|
if(file.exists()) {
|
||||||
try (FileInputStream fin = new FileInputStream(file)){
|
try (FileInputStream fin = new FileInputStream(file)){
|
||||||
|
|
@ -200,7 +203,7 @@ public class ModernFixEarlyConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
config.writeConfig(file, props);
|
config.save();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOGGER.warn("Could not write configuration file", e);
|
LOGGER.warn("Could not write configuration file", e);
|
||||||
}
|
}
|
||||||
|
|
@ -208,8 +211,8 @@ public class ModernFixEarlyConfig {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeConfig(File file, Properties props) throws IOException {
|
public void save() throws IOException {
|
||||||
File dir = file.getParentFile();
|
File dir = configFile.getParentFile();
|
||||||
|
|
||||||
if (!dir.exists()) {
|
if (!dir.exists()) {
|
||||||
if (!dir.mkdirs()) {
|
if (!dir.mkdirs()) {
|
||||||
|
|
@ -219,23 +222,24 @@ public class ModernFixEarlyConfig {
|
||||||
throw new IOException("The parent file is not a directory");
|
throw new IOException("The parent file is not a directory");
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Writer writer = new FileWriter(file)) {
|
try (Writer writer = new FileWriter(configFile)) {
|
||||||
writer.write("# This is the configuration file for ModernFix.\n");
|
writer.write("# This is the configuration file for ModernFix.\n");
|
||||||
writer.write("#\n");
|
writer.write("#\n");
|
||||||
writer.write("# The following options can be enabled or disabled if there is a compatibility issue.\n");
|
writer.write("# The following options can be enabled or disabled if there is a compatibility issue.\n");
|
||||||
writer.write("# Add a line mixin.example_name=true/false without the # sign to enable/disable a rule.\n");
|
writer.write("# Add a line mixin.example_name=true/false without the # sign to enable/disable a rule.\n");
|
||||||
List<String> lines = this.options.keySet().stream()
|
List<String> keys = this.options.keySet().stream()
|
||||||
.filter(key -> !key.equals("mixin.core"))
|
.filter(key -> !key.equals("mixin.core"))
|
||||||
.sorted()
|
.sorted()
|
||||||
.map(key -> "# " + key + "\n")
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
for(String line : lines) {
|
for(String line : keys) {
|
||||||
writer.write(line);
|
if(!line.equals("mixin.core"))
|
||||||
|
writer.write("# " + line + "\n");
|
||||||
}
|
}
|
||||||
for (Map.Entry<Object, Object> entry : props.entrySet()) {
|
|
||||||
String key = (String) entry.getKey();
|
for (String key : keys) {
|
||||||
String value = (String) entry.getValue();
|
Option option = this.options.get(key);
|
||||||
writer.write(key + "=" + value + "\n");
|
if(option.isUserDefined())
|
||||||
|
writer.write(key + "=" + option.isEnabled() + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -254,4 +258,8 @@ public class ModernFixEarlyConfig {
|
||||||
.filter(Option::isOverridden)
|
.filter(Option::isOverridden)
|
||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Option> getOptionMap() {
|
||||||
|
return Collections.unmodifiableMap(this.options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,15 @@ public class Option {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean enabled, boolean userDefined) {
|
public void setEnabled(boolean enabled, boolean userDefined) {
|
||||||
|
if(this.enabled == enabled)
|
||||||
|
return;
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
this.userDefined = userDefined;
|
this.userDefined = userDefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addModOverride(boolean enabled, String modId) {
|
public void addModOverride(boolean enabled, String modId) {
|
||||||
|
if(this.enabled == enabled)
|
||||||
|
return;
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
|
|
||||||
if (this.modDefined == null) {
|
if (this.modDefined == null) {
|
||||||
|
|
@ -57,6 +61,10 @@ public class Option {
|
||||||
this.modDefined = null;
|
this.modDefined = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearUserDefined() {
|
||||||
|
this.userDefined = false;
|
||||||
|
}
|
||||||
|
|
||||||
public Collection<String> getDefiningMods() {
|
public Collection<String> getDefiningMods() {
|
||||||
return this.modDefined != null ? Collections.unmodifiableCollection(this.modDefined) : Collections.emptyList();
|
return this.modDefined != null ? Collections.unmodifiableCollection(this.modDefined) : Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.embeddedt.modernfix.screen;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
import net.minecraft.network.chat.CommonComponents;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class ModernFixConfigScreen extends Screen {
|
||||||
|
private OptionList optionList;
|
||||||
|
private Screen lastScreen;
|
||||||
|
|
||||||
|
public boolean madeChanges = false;
|
||||||
|
private Button doneButton;
|
||||||
|
public ModernFixConfigScreen(@Nullable Screen lastScreen) {
|
||||||
|
super(new TranslatableComponent("modernfix.config"));
|
||||||
|
this.lastScreen = lastScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
this.optionList = new OptionList(this, this.minecraft);
|
||||||
|
this.addWidget(this.optionList);
|
||||||
|
this.doneButton = new Button(this.width / 2 - 100, this.height - 29, 200, 20, CommonComponents.GUI_DONE, (arg) -> {
|
||||||
|
this.minecraft.setScreen(lastScreen);
|
||||||
|
});
|
||||||
|
this.addRenderableWidget(this.doneButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(PoseStack poseStack, int mouseX, int mouseY, float partialTicks) {
|
||||||
|
this.renderBackground(poseStack);
|
||||||
|
this.optionList.render(poseStack, mouseX, mouseY, partialTicks);
|
||||||
|
drawCenteredString(poseStack, this.font, this.title, this.width / 2, 8, 16777215);
|
||||||
|
this.doneButton.setMessage(madeChanges ? new TranslatableComponent("modernfix.config.done_restart") : CommonComponents.GUI_DONE);
|
||||||
|
super.render(poseStack, mouseX, mouseY, partialTicks);
|
||||||
|
}
|
||||||
|
}
|
||||||
125
src/main/java/org/embeddedt/modernfix/screen/OptionList.java
Normal file
125
src/main/java/org/embeddedt/modernfix/screen/OptionList.java
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
package org.embeddedt.modernfix.screen;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import net.minecraft.ChatFormatting;
|
||||||
|
import net.minecraft.client.KeyMapping;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.components.Button;
|
||||||
|
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
|
||||||
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
import net.minecraft.client.gui.components.toasts.SystemToast;
|
||||||
|
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.MutableComponent;
|
||||||
|
import net.minecraft.network.chat.TextComponent;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
|
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||||
|
import org.embeddedt.modernfix.core.config.Option;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
|
||||||
|
private final int maxNameWidth;
|
||||||
|
|
||||||
|
private static final Component OPTION_ON = new TranslatableComponent("modernfix.option.on").withStyle(style -> style.withColor(ChatFormatting.GREEN));
|
||||||
|
private static final Component OPTION_OFF = new TranslatableComponent("modernfix.option.off").withStyle(style -> style.withColor(ChatFormatting.RED));
|
||||||
|
|
||||||
|
private ModernFixConfigScreen mainScreen;
|
||||||
|
|
||||||
|
|
||||||
|
public OptionList(ModernFixConfigScreen arg, Minecraft arg2) {
|
||||||
|
super(arg2,arg.width + 45, arg.height, 43, arg.height - 32, 20);
|
||||||
|
|
||||||
|
this.mainScreen = arg;
|
||||||
|
|
||||||
|
int maxW = 0;
|
||||||
|
Map<String, Option> optionMap = ModernFixMixinPlugin.config.getOptionMap();
|
||||||
|
List<String> sortedKeys = optionMap.keySet().stream().filter(key -> !key.equals("mixin.core")).sorted().collect(Collectors.toList());
|
||||||
|
for(String key : sortedKeys) {
|
||||||
|
Option option = optionMap.get(key);
|
||||||
|
int w = this.minecraft.font.width(key);
|
||||||
|
maxW = Math.max(w, maxW);
|
||||||
|
this.addEntry(new OptionEntry(key, option));
|
||||||
|
}
|
||||||
|
this.maxNameWidth = maxW;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getScrollbarPosition() {
|
||||||
|
return super.getScrollbarPosition() + 15 + 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRowWidth() {
|
||||||
|
return super.getRowWidth() + 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
class OptionEntry extends Entry {
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private final Button toggleButton;
|
||||||
|
private final Option option;
|
||||||
|
|
||||||
|
public OptionEntry(String optionName, Option option) {
|
||||||
|
this.name = optionName;
|
||||||
|
this.option = option;
|
||||||
|
this.toggleButton = new Button(0, 0, 95, 20, new TextComponent(""), (arg) -> {
|
||||||
|
this.option.setEnabled(!this.option.isEnabled(), !this.option.isUserDefined());
|
||||||
|
try {
|
||||||
|
ModernFixMixinPlugin.config.save();
|
||||||
|
if(!OptionList.this.mainScreen.madeChanges) {
|
||||||
|
OptionList.this.mainScreen.madeChanges = true;
|
||||||
|
}
|
||||||
|
} catch(IOException e) {
|
||||||
|
// revert
|
||||||
|
this.option.setEnabled(!this.option.isEnabled(), !this.option.isUserDefined());
|
||||||
|
ModernFix.LOGGER.error("Unable to save config", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(PoseStack matrixStack, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean isMouseOver, float partialTicks) {
|
||||||
|
MutableComponent nameComponent = new TextComponent(this.name);
|
||||||
|
if(this.option.isUserDefined())
|
||||||
|
nameComponent = nameComponent.withStyle(ChatFormatting.ITALIC).append(new TranslatableComponent("modernfix.config.not_default"));
|
||||||
|
OptionList.this.minecraft.font.draw(matrixStack, nameComponent, (float)(left + 160 - OptionList.this.maxNameWidth), (float)(top + height / 2 - 4), 16777215);
|
||||||
|
this.toggleButton.x = left + 175;
|
||||||
|
this.toggleButton.y = top;
|
||||||
|
this.toggleButton.setMessage(getOptionMessage(this.option));
|
||||||
|
this.toggleButton.render(matrixStack, mouseX, mouseY, partialTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Component getOptionMessage(Option option) {
|
||||||
|
return option.isEnabled() ? OPTION_ON : OPTION_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<? extends GuiEventListener> children() {
|
||||||
|
return ImmutableList.of(this.toggleButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||||
|
return this.toggleButton.mouseClicked(mouseX, mouseY, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||||
|
return this.toggleButton.mouseReleased(mouseX, mouseY, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<? extends NarratableEntry> narratables() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class Entry extends ContainerObjectSelectionList.Entry<Entry> {
|
||||||
|
public Entry() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
{
|
{
|
||||||
|
"key.modernfix": "ModernFix",
|
||||||
|
"key.modernfix.config": "Open config screen",
|
||||||
"modernfix.jei_load": "Loading JEI, this may take a while",
|
"modernfix.jei_load": "Loading JEI, this may take a while",
|
||||||
"modernfix.no_lazydfu": "ModernFix detected that DFU rules were compiled on startup. This slows down game launching. Installing LazyDFU to resolve this is highly recommended.",
|
"modernfix.no_lazydfu": "ModernFix detected that DFU rules were compiled on startup. This slows down game launching. Installing LazyDFU to resolve this is highly recommended.",
|
||||||
|
"modernfix.config": "ModernFix mixin config",
|
||||||
|
"modernfix.config.done_restart": "Done (restart required)",
|
||||||
|
"modernfix.option.on": "on",
|
||||||
|
"modernfix.option.off": "off",
|
||||||
|
"modernfix.config.not_default": " (modified)",
|
||||||
"asynclocator.map.locating": "Map (Locating...)",
|
"asynclocator.map.locating": "Map (Locating...)",
|
||||||
"asynclocator.map.none": "Map (No nearby feature found)"
|
"asynclocator.map.none": "Map (No nearby feature found)"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user