diff --git a/docs-java/start/basic/server-dir-structure.md b/docs-java/start/basic/server-dir-structure.md
index 4d568766f..bf9f450f2 100644
--- a/docs-java/start/basic/server-dir-structure.md
+++ b/docs-java/start/basic/server-dir-structure.md
@@ -3,43 +3,50 @@ title: 服务端结构
sidebar_position: 3
---
+import FileTree from '@site/src/components/FileTree';
+
# 服务端结构
我们先来简单看一眼 插件端 的文件夹结构 (以 Purpur 为例):
-
-```c
-├─assets // 储存 Minecraft 音效贴图等重要文件,不要乱动
-├─cache // 缓存文件夹,一般放置 Minecraft 原版服务器
-├─config // Paper fork 服务器特有的配置文件,用于放置 Paper 的配置文件
-├─crash-reports // 存放服务器崩溃的完整报告
-├─libraries // 存放服务器及部分插件的依赖库
-├─logs // 存放服务端日志的文件夹
-├─plugins // 存放插件的文件夹
-├─versions // 存放对应版本需要的依赖 jar
-├─world // 主世界文件夹
-│ ├─advancements // 成就文件夹
-│ ├─data // 世界数据文件夹
-│ ├─datapacks // 数据包
-│ │ └─bukkit
-│ ├─entities // 实体数据
-│ ├─playerdata // 玩家数据
-│ ├─poi // 兴趣点数据
-│ ├─region // 区块数据
-│ └─stats // 统计信息
-├─world_nether // 地狱世界文件夹
-│ └─DIM-1
-│ ├─data
-│ ├─entities
-│ ├─poi
-│ └─region
-└─world_the_end // 末地世界文件夹
- └─DIM1
- ├─data
- ├─entities
- ├─poi
- └─region
-```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
对于类似 Catserver 的混合服务器,文件夹结构是类似的,基本就多了 `/mods` 文件夹,少了 Bukkit 的下游服务器特有的配置 (如 `purpur.yml` 等)。
diff --git a/src/components/FileTree/index.tsx b/src/components/FileTree/index.tsx
new file mode 100644
index 000000000..ed2acdc7d
--- /dev/null
+++ b/src/components/FileTree/index.tsx
@@ -0,0 +1,83 @@
+import React, { useState } from 'react';
+import { FolderOpenOutlined, FolderOutlined, FileOutlined, FileTextOutlined } from '@ant-design/icons';
+import clsx from 'clsx';
+
+interface FileTreeProps {
+ children: React.ReactNode;
+ className?: string;
+}
+
+interface ItemProps {
+ name: string;
+ comment?: string;
+ children?: React.ReactNode;
+ defaultOpen?: boolean;
+}
+
+const FileTreeContext = React.createContext<{ level: number }>({ level: 0 });
+
+export function FileTree({ children, className }: FileTreeProps) {
+ return (
+
+ );
+}
+
+function Folder({ name, comment, children, defaultOpen = true }: ItemProps) {
+ const { level } = React.useContext(FileTreeContext);
+ const [isOpen, setIsOpen] = useState(defaultOpen);
+
+ return (
+
+
setIsOpen(!isOpen)}
+ >
+
+ {isOpen ? : }
+
+ {name}
+ {comment && // {comment}}
+
+ {isOpen && children && (
+
+
+ {/* Adjust margin to align with the folder icon center roughly, or just use padding */}
+ {/* Actually, the level padding in children handles indentation.
+ But to draw lines, we might need more complex CSS.
+ For now, let's stick to simple indentation. */}
+ {children}
+
+
+ )}
+
+ );
+}
+
+function File({ name, comment }: ItemProps) {
+ const { level } = React.useContext(FileTreeContext);
+
+ return (
+
+
+
+
+ {name}
+ {comment && // {comment}}
+
+ );
+}
+
+FileTree.Folder = Folder;
+FileTree.File = File;
+
+export default FileTree;