Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ layout.json
/src/test
/docs
/gradle-user
.claude/
CLAUDE.md
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
## **Features**

* Markdown pages with YAML frontmatter, navigation metadata, categories, anchors, tables, footnotes, Mermaid, LaTeX, charts, and highlighted text.
* MDX-style runtime tags such as `<ItemLink>`, `<ItemImage>`, `<Recipe>`, `<GameScene>`, `<BlockStats>`, `<Tooltip>`, `<KeyBind>`, and `<PlayerName>`.
* MDX-style runtime tags such as `<ItemLink>`, `<ItemImage>`, `<Recipe>`, `<GameScene>`, `<ContentTabs>`, `<BlockStats>`, `<Tooltip>`, `<KeyBind>`, and `<PlayerName>`.
* Interactive 3D GameScene previews with block/entity placement, StructureLib import, Ponder playback, layer sliders, grid controls, annotations, and block statistics.
* Live guide editing mode with split editor/preview, toolbar actions, debounced saving, external-change handling, and resource-pack page creation.
* Multi-language guide folders with fallback, item index navigation, search, server integration, and resource reload support.
Expand Down Expand Up @@ -112,5 +112,11 @@ Guide.builder(new ResourceLocation("yourmod", "guidenh")).build();

Thanks to persephone for providing the icon textures!

Thanks to the following developers for their contributions to GuideNH:

<a href="https://github.com/GTNewHorizons/GuideNH/graphs/contributors">
<img src="https://contrib.rocks/image?repo=GTNewHorizons/GuideNH&max=1000" alt="contributors" />
</a>

GuideNH is based on ideas from [GuideME](https://github.com/AppliedEnergistics/GuideME), distributed under LGPL-3.0.
It also uses open-source libraries including SnakeYAML, Apache Lucene, Apache Commons Lang, FlatBuffers Java, and JLaTeXMath.
8 changes: 7 additions & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
## **功能**

* 支持带 YAML 表头的 Markdown 页面、导航元数据、分类、锚点、表格、脚注、Mermaid、LaTeX、图表与文本高亮。
* 支持 `<ItemLink>`、`<ItemImage>`、`<Recipe>`、`<GameScene>`、`<BlockStats>`、`<Tooltip>`、`<KeyBind>`、`<PlayerName>` 等 MDX 风格运行时标签。
* 支持 `<ItemLink>`、`<ItemImage>`、`<Recipe>`、`<GameScene>`、`<ContentTabs>`、`<BlockStats>`、`<Tooltip>`、`<KeyBind>`、`<PlayerName>` 等 MDX 风格运行时标签。
* 支持交互式 3D GameScene 预览,包括方块/实体放置、StructureLib 导入、Ponder 播放、层滑条、网格按钮、注解与方块统计表。
* 支持游戏内指南编辑模式,包括编辑/预览分屏、工具栏操作、短延迟自动保存、外部变更处理与资源包页面创建。
* 支持多语言指南目录与回退、物品索引跳转、搜索、服务端集成和资源重载。
Expand Down Expand Up @@ -112,5 +112,11 @@ Guide.builder(new ResourceLocation("yourmod", "guidenh")).build();

感谢Persephone提供了图标纹理!

感谢以下开发者对 GuideNH 的贡献:

<a href="https://github.com/GTNewHorizons/GuideNH/graphs/contributors">
<img src="https://contrib.rocks/image?repo=GTNewHorizons/GuideNH&max=1000" alt="contributors" />
</a>

GuideNH 借鉴了 [GuideME](https://github.com/AppliedEnergistics/GuideME) 的设计思路,GuideME 使用 LGPL-3.0 分发。
本项目还使用了 SnakeYAML、Apache Lucene、Apache Commons Lang、FlatBuffers Java、JLaTeXMath 等开源库。
6 changes: 4 additions & 2 deletions dependencies.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies {

api("com.github.GTNewHorizons:GTNHLib:0.10.3:dev")
api("com.github.GTNewHorizons:GTNHLib:0.10.8:dev")
implementation("io.github.legacymoddingmc:unimixins:0.3.1:dev")

shadowImplementation("org.yaml:snakeyaml:1.33") { transitive = false }
Expand All @@ -23,15 +23,17 @@ dependencies {
devOnlyNonPublishable("com.github.GTNewHorizons:nei-custom-diagram:1.8.20:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:EnhancedLootBags:1.3.4:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:BetterQuesting:3.8.40-GTNH:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:Angelica:2.1.32:dev")
devOnlyNonPublishable("com.github.GTNewHorizons:TX-Loader:1.8.11:dev")
devOnlyNonPublishable("curse.maven:cofh-core-69162:2388751")

runtimeOnlyNonPublishable("com.github.GTNewHorizons:Baubles-Expanded:2.2.13-GTNH:dev")
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Botania:1.13.16-GTNH:dev")
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Botanic-horizons:1.12.8-GTNH:dev")
runtimeOnlyNonPublishable("com.github.GTNewHorizons:BlockRenderer6343:1.4.12:dev") { transitive = false }
runtimeOnlyNonPublishable("com.github.GTNewHorizons:Angelica:2.1.19:dev")
runtimeOnlyNonPublishable(rfg.deobf("curse.maven:spark-361579:4271867"))

compileOnlyApi("com.github.slprime:ChromaticTooltips:1.0.28-GTNH:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:TinkersConstruct:1.14.64-GTNH:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:Mantle:0.5.1:dev") { transitive = false }
compileOnlyApi("com.github.GTNewHorizons:Mobs-Info:0.5.14-GTNH:dev") { transitive = false }
Expand Down
10 changes: 5 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ modGroup = com.hfstudio.guidenh

# Whether to use modGroup as the maven publishing group.
# When false, com.github.GTNewHorizons is used.
useModGroupForPublishing = true
useModGroupForPublishing = false

# Updates your build.gradle and settings.gradle automatically whenever an update is available.
autoUpdateBuildScript = false
Expand Down Expand Up @@ -166,7 +166,7 @@ usesMavenPublishing = true
#
# The project's ID on Modrinth. Can be either the slug or the ID.
# Leave this empty if you don't want to publish to Modrinth.
modrinthProjectId = guidenh
modrinthProjectId =

# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
# Syntax: scope1-type1:name1;scope2-type2:name2;...
Expand All @@ -175,21 +175,21 @@ modrinthProjectId = guidenh
# and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
modrinthRelations = required-project:gtnhlib;optional-project:notenoughitems-unofficial
modrinthRelations =

# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
#
# The project's numeric ID on CurseForge. You can find this in the About Project box.
# Leave this empty if you don't want to publish on CurseForge.
curseForgeProjectId = 1559237
curseForgeProjectId =

# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge.
# Syntax: type1:name1;type2:name2;...
# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible],
# and the name is the CurseForge project slug of the other mod.
# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
curseForgeRelations = requiredDependency:gtnhlib
curseForgeRelations =

# Optional parameter to customize the produced artifacts. Use this to preserve artifact naming when migrating older
# projects. New projects should not use this parameter.
Expand Down
143 changes: 129 additions & 14 deletions src/main/java/com/hfstudio/guidenh/ClientProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,69 @@
import com.hfstudio.guidenh.client.command.GuideNhClientBridgeController;
import com.hfstudio.guidenh.client.command.GuideNhClientCommand;
import com.hfstudio.guidenh.client.hotkey.CycleRegionWandModeHotkey;
import com.hfstudio.guidenh.client.hotkey.GuidePageHistoryHotkey;
import com.hfstudio.guidenh.client.hotkey.OpenGuideHomeHotkey;
import com.hfstudio.guidenh.client.hotkey.OpenGuideHotkey;
import com.hfstudio.guidenh.client.hotkey.OpenSceneEditorHotkey;
import com.hfstudio.guidenh.config.ModConfig;
import com.hfstudio.guidenh.guide.internal.GuideDevWatcherPump;
import com.hfstudio.guidenh.guide.internal.GuideDevelopmentResourcePackWatcher;
import com.hfstudio.guidenh.guide.internal.GuideME;
import com.hfstudio.guidenh.guide.internal.GuideOnStartup;
import com.hfstudio.guidenh.guide.internal.GuideRegistry;
import com.hfstudio.guidenh.guide.internal.GuideReloadListener;
import com.hfstudio.guidenh.guide.internal.GuideScreenMemory;
import com.hfstudio.guidenh.guide.internal.GuideWarmupPump;
import com.hfstudio.guidenh.guide.internal.home.GuideScreenHomeHistory;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.TagAttributeRegistry;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.AnchorProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.AttributeNameProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.AttributePresetValueProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.AutocompleteProviders;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.BlockIdProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.BooleanValueProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.ColorProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.CommandProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.DomainProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.EntityNameProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.EnumValueProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.ExpressionProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.FencedBlockLanguageProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.FormatPatternProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.FrontmatterKeyProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.FrontmatterValueProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.ImagePathProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.ItemIdProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.KeyBindProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.NumericValueProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.OreDictProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.PageReferenceProvider;
import com.hfstudio.guidenh.guide.internal.editor.autocomplete.provider.TagNameProvider;
import com.hfstudio.guidenh.guide.internal.host.LytHost;
import com.hfstudio.guidenh.guide.internal.host.LytHostWorkItem;
import com.hfstudio.guidenh.guide.internal.host.scripts.BlockImageScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.CategoryScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.CommandLinkScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.CsvTableScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.FloatingImageScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.ImageScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.ItemGridScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.ItemImageScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.ItemLinkScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.KeyBindScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.MermaidScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.PlayerNameScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.QuestCardScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.QuestLinkScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.RecipeScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.SceneScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.SoundLinkScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.SpecialScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.StructureScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.SubPagesScript;
import com.hfstudio.guidenh.guide.internal.host.scripts.TooltipScript;
import com.hfstudio.guidenh.guide.internal.scheduler.DevWatchWorkItem;
import com.hfstudio.guidenh.guide.internal.scheduler.LytHostPreheatItem;
import com.hfstudio.guidenh.guide.internal.scheduler.MasterScheduler;
import com.hfstudio.guidenh.guide.internal.scheduler.SearchIndexWorkItem;
import com.hfstudio.guidenh.guide.scene.level.GuidebookFakeWorld;
import com.hfstudio.guidenh.guide.scene.level.GuidebookLevel;
import com.hfstudio.guidenh.guide.scene.support.GuideDebugLog;
import com.hfstudio.guidenh.integration.GuideNhClientIntegrationBootstrap;
import com.hfstudio.guidenh.integration.Mods;
import com.hfstudio.guidenh.integration.ae2.network.Ae2NetworkRegistration;
Expand All @@ -47,6 +95,12 @@

public class ClientProxy extends CommonProxy {

private static final LytHost lytHost = new LytHost();

public static LytHost getLytHost() {
return lytHost;
}

private final GuideNhRuntimeBridge runtimeBridge = new GuideNhRuntimeBridge();

@Override
Expand Down Expand Up @@ -79,12 +133,76 @@ public void init(FMLInitializationEvent event) {
}
OpenGuideHomeHotkey.init();
OpenGuideHotkey.init();
GuidePageHistoryHotkey.init();
OpenSceneEditorHotkey.init();
AutocompleteProviders.register(new ItemIdProvider());
TagAttributeRegistry.initialize();
AutocompleteProviders.register(new AttributeNameProvider());

AutocompleteProviders.register(new ColorProvider());
AutocompleteProviders.register(new OreDictProvider());
AutocompleteProviders.register(new BlockIdProvider());
AutocompleteProviders.register(new EntityNameProvider());
AutocompleteProviders.register(new KeyBindProvider());
AutocompleteProviders.register(new PageReferenceProvider());
AutocompleteProviders.register(new AnchorProvider());
AutocompleteProviders.register(new CommandProvider());
AutocompleteProviders.register(new AttributePresetValueProvider());
AutocompleteProviders.register(new NumericValueProvider());
AutocompleteProviders.register(new BooleanValueProvider());
AutocompleteProviders.register(new EnumValueProvider());
AutocompleteProviders.register(new ExpressionProvider());
AutocompleteProviders.register(new DomainProvider());
AutocompleteProviders.register(new FormatPatternProvider());
AutocompleteProviders.register(new TagNameProvider());
AutocompleteProviders.register(new FencedBlockLanguageProvider());
AutocompleteProviders.register(new FrontmatterKeyProvider());
AutocompleteProviders.register(new FrontmatterValueProvider());

AutocompleteProviders.register(new ImagePathProvider());
CycleRegionWandModeHotkey.init();
MinecraftForge.EVENT_BUS.register(new RegionWandRenderer());
GuideWarmupPump.init();
MasterScheduler.init();
MasterScheduler.getInstance()
.submit(new LytHostWorkItem(lytHost));
MasterScheduler.getInstance()
.submit(new LytHostPreheatItem(lytHost));
MasterScheduler.getInstance()
.submit(new SearchIndexWorkItem());

// Phase 3: LytScript registrations
lytHost.registerScript("CommandLink", new CommandLinkScript());
lytHost.registerScript("Img", new ImageScript());
lytHost.registerScript("FloatingImage", new FloatingImageScript());
lytHost.registerScript("PlayerName", new PlayerNameScript());
lytHost.registerScript("KeyBind", new KeyBindScript());
lytHost.registerScript("SoundLink", new SoundLinkScript());
lytHost.registerScript("Structure", new StructureScript());
lytHost.registerScript("SubPages", new SubPagesScript());
lytHost.registerScript("Tooltip", new TooltipScript());
lytHost.registerScript("ItemGrid", new ItemGridScript());
lytHost.registerScript("ItemImage", new ItemImageScript());
lytHost.registerScript("ItemLink", new ItemLinkScript());
lytHost.registerScript("Category", new CategoryScript());
lytHost.registerScript("Special", new SpecialScript());
lytHost.registerScript("BlockImage", new BlockImageScript());
lytHost.registerScript("CsvTable", new CsvTableScript());
lytHost.registerScript("Mermaid", new MermaidScript());
lytHost.registerScript("QuestLink", new QuestLinkScript());
lytHost.registerScript("QuestCard", new QuestCardScript());
// Phase 3: SceneScript handles Scene and GameScene
SceneScript sceneScript = new SceneScript();
lytHost.registerScript("Scene", sceneScript);
lytHost.registerScript("GameScene", sceneScript);
// Phase 3: RecipeScript handles Recipe, RecipeFor, RecipeUsage, RecipesFor
RecipeScript recipeScript = new RecipeScript();
lytHost.registerScript("Recipe", recipeScript);
lytHost.registerScript("RecipeFor", recipeScript);
lytHost.registerScript("RecipeUsage", recipeScript);
lytHost.registerScript("RecipesFor", recipeScript);

MinecraftForge.EVENT_BUS.register(this);
GuideNH.LOG.info(
GuideDebugLog.infoAlways(
"GuideNH runtime bridge configuration loaded. enabled={}, hostConfigured={}, port={}, tokenConfigured={}",
ModConfig.runtimeBridge.enabled,
ModConfig.runtimeBridge.host != null && !ModConfig.runtimeBridge.host.trim()
Expand Down Expand Up @@ -113,20 +231,17 @@ public void postInit(FMLPostInitializationEvent event) {
public void completeInit(FMLLoadCompleteEvent event) {
super.completeInit(event);
GuideDevelopmentResourcePackWatcher.init();
GuideDevWatcherPump.init();
MasterScheduler.getInstance()
.submit(new DevWatchWorkItem());
GuideOnStartup.init();
}

@SubscribeEvent
public void onClientDisconnect(FMLNetworkEvent.ClientDisconnectionFromServerEvent event) {
GuideNH.LOG.info("Minecraft client disconnected. Stopping GuideNH runtime bridge session state");
GuideDebugLog.infoAlways("Minecraft client disconnected. Stopping GuideNH runtime bridge session state");
runtimeBridge.stop();
GuideME.closeSearch();
GuideScreenMemory.clear();
GuideScreenHomeHistory.shared()
lytHost.getNavigation()
.clear();
for (var guide : GuideRegistry.getAll()) {
guide.resetWarmup();
}
}
}
4 changes: 0 additions & 4 deletions src/main/java/com/hfstudio/guidenh/GuideNH.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
import static com.hfstudio.guidenh.GuideNH.MODID;
import static com.hfstudio.guidenh.GuideNH.MODNAME;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.hfstudio.guidenh.guide.internal.GuideCommand;
import com.hfstudio.guidenh.guide.internal.GuideNhBridgeCommand;
import com.hfstudio.guidenh.guide.internal.item.GuideItem;
Expand Down Expand Up @@ -35,7 +32,6 @@ public class GuideNH {
public static final String MODNAME = Tags.MODNAME;
public static final String VERSION = Tags.VERSION;
public static final String AUTHOR = "HFstudio";
public static final Logger LOG = LogManager.getLogger(MODID);

public static boolean debug = false;

Expand Down
Loading