TypeScript · 2984 bytes Raw Blame History
1 // src/hooks/useCommandExecution.ts
2 import { useState, useCallback } from 'react';
3 import { gameApi, CommandResponse, TreeNode, GameStats } from '@/lib/api';
4
5 interface CommandHistoryEntry {
6 command: string;
7 output: string;
8 success: boolean;
9 }
10
11 export const useCommandExecution = (
12 treeId: number | null,
13 sessionId: number | null,
14 onLocationChange: (newLocation: string) => void,
15 onMoleKilled: (response: CommandResponse) => void,
16 onTreeUpdate: (updater: (tree: TreeNode) => TreeNode) => void,
17 onGameComplete?: (stats: GameStats) => void
18 ) => {
19 const [executing, setExecuting] = useState(false);
20 const [commandHistory, setCommandHistory] = useState<CommandHistoryEntry[]>([]);
21
22 const addToHistory = useCallback((entry: CommandHistoryEntry) => {
23 setCommandHistory(prev => [...prev, entry]);
24 }, []);
25
26 const clearHistory = useCallback(() => {
27 setCommandHistory([]);
28 }, []);
29
30 const executeCommand = useCallback(async (cmd: string) => {
31 if (!treeId || !cmd.trim() || executing) return;
32
33 setExecuting(true);
34 try {
35 const response = await gameApi.executeCommand(treeId, cmd, sessionId || undefined);
36
37 // Build output with timer warnings
38 let output = response.output;
39 if (response.timer_warnings && response.timer_warnings.length > 0) {
40 const warnings = response.timer_warnings.map(w => `⚠️ ${w.level}: ${w.message}`).join('\n');
41 output = warnings + (output ? '\n' + output : '');
42 }
43
44 addToHistory({
45 command: cmd,
46 output,
47 success: response.success,
48 });
49
50 // Update player location if it changed
51 if (response.current_path) {
52 onLocationChange(response.current_path);
53 }
54
55 // Handle mole killed
56 if (response.mole_spawned) {
57 onMoleKilled(response);
58 }
59
60 // Handle game completion
61 if (response.game_completed && response.final_stats && onGameComplete) {
62 onGameComplete(response.final_stats);
63 }
64
65 // Handle mole location updates in tree
66 if (response.new_mole_location) {
67 onTreeUpdate((tree) => {
68 const updateMoleInTree = (node: TreeNode, molePath: string): TreeNode => {
69 return {
70 ...node,
71 has_mole: node.path === molePath,
72 children: node.children.map(child => updateMoleInTree(child, molePath))
73 };
74 };
75 return updateMoleInTree(tree, response.new_mole_location!);
76 });
77 }
78 } catch (error) {
79 console.error('Command execution failed:', error);
80 addToHistory({
81 command: cmd,
82 output: 'Error: Failed to execute command',
83 success: false,
84 });
85 } finally {
86 setExecuting(false);
87 }
88 }, [treeId, sessionId, executing, onLocationChange, onMoleKilled, onTreeUpdate, onGameComplete, addToHistory]);
89
90 return {
91 executing,
92 commandHistory,
93 executeCommand,
94 addToHistory,
95 clearHistory,
96 };
97 };