概要
terminal ページタイプでは、受講者がブラウザ内のターミナル風 UI でコマンドを入力し、授業データで定義したシミュレーション出力が表示されます。オプションで トポロジ を指定すると、ping 実行時に React Flow 上の経路に沿ってパケット(往路・復路)がアニメーション表示されます。
基本データ構造
| プロパティ | 型 | 必須 | 説明 |
|---|---|---|---|
| instruction | string | ○ | 画面上部の説明文 |
| prompt | string | - | プロンプト表示(未指定時は "$ ") |
| initialOutput | string | - | 表示開始時に出しておくテキスト |
| commandOutputs | Record<string, string> | ○ | コマンド(正規化後)→ 表示する出力のマップ |
| requiredCommands | string[] | ○ | すべて実行した時点でクリアになるコマンドのリスト |
| topology | TerminalTopology? | - | トポロジを表示し、ping 時にパケットをアニメーション |
| deviceIps | Record<string, string>? | - | デバイス ID → IP。ping の宛先解決に使用 |
| defaultSourceDeviceId | string? | - | ping の送信元デバイス(未指定時は topology.devices[0]) |
コマンドの正規化
入力されたコマンドは 先頭・末尾の空白削除 と 連続空白を 1 文字に したうえでcommandOutputs のキーや requiredCommands と照合されます。未定義のコマンドは「command not found」風のメッセージが表示され、クリア条件には含まれません。
トポロジと ping 連携(オプション)
terminalData.topology を指定すると、ターミナル上部に ネットワークトポロジ(React Flow)が表示されます。受講者が ping <IP またはデバイスID> を実行すると、次のように動きます。
- 宛先の解決:
deviceIpsで IP からデバイス ID を解決。または、引数がトポロジのデバイス ID そのものであればそのまま使用。 - 経路計算: 送信元(
defaultSourceDeviceIdまたは先頭デバイス)から宛先まで BFS で経路を算出。 - アニメーション: 往路(送信元→宛先)のエッジを順に光らせたあと、復路(宛先→送信元)を同じエッジを逆方向に流して表示。終了後にターミナルに ping の結果(
commandOutputsまたはデフォルト文)を表示。
TerminalTopology
SandboxDevice / SandboxConnection の形式は サンドボックス・パケットシミュレーター仕様 を参照してください。
トポロジ付きの例
ping 192.168.1.2→ 宛先はserver。経路は client → router → server(往路)、server → router → client(復路)。ping serverのようにデバイス ID を直接指定しても同じ経路でアニメーションされます。
実装の対応
- UI:
src/components/lesson/TerminalContent.tsx… ターミナル入力・出力とクリア判定。 - トポロジ表示:
src/components/lesson/TerminalTopologyView.tsx… React Flow でトポロジを描画し、activeEdgeId/activeEdgeReversedでパケット表示。 - 経路計算:
src/utils/terminal-topology.ts…getPathEdgeIds(BFS)、getDeviceIdByIp(IP → デバイス ID)。 - エッジの逆方向アニメーション:
src/components/packet-sim/AnimatedPacketEdge.tsxのdata.isReversedで復路を逆向きに表示。
XP と進捗
terminal ページのクリア時には sandbox と同様に 20 XP が付与されます(useLessonXp.ts の getPageXp)。