Skip to content

Commit 81b0f50

Browse files
committed
Reapply "Update for Custom_Tool Fix and Detection"
This reverts commit f423c2f.
1 parent b5265a7 commit 81b0f50

19 files changed

+846
-348
lines changed

CustomTools/RoslynRuntimeCompilation/ManageRuntimeCompilation.cs

Lines changed: 33 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ namespace MCPForUnity.Editor.Tools
1919
{
2020
/// <summary>
2121
/// Runtime compilation tool for MCP Unity.
22-
/// Compiles and loads C# code at runtime without triggering domain reload.
22+
/// Compiles and loads C# code at runtime without triggering domain reload via Roslyn Runtime Compilation, where in traditional Unity workflow it would take seconds to reload assets and reset script states for each script change.
2323
/// </summary>
24-
[McpForUnityTool("runtime_compilation")]
24+
[McpForUnityTool(
25+
name:"runtime_compilation",
26+
Description = "Enable runtime compilation of C# code within Unity without domain reload via Roslyn.")]
2527
public static class ManageRuntimeCompilation
2628
{
2729
private static readonly Dictionary<string, LoadedAssemblyInfo> LoadedAssemblies = new Dictionary<string, LoadedAssemblyInfo>();
@@ -42,7 +44,7 @@ public static object HandleCommand(JObject @params)
4244

4345
if (string.IsNullOrEmpty(action))
4446
{
45-
return Response.Error("Action parameter is required. Valid actions: compile_and_load, list_loaded, get_types, execute_with_roslyn, get_history, save_history, clear_history");
47+
return new ErrorResponse("Action parameter is required. Valid actions: compile_and_load, list_loaded, get_types, execute_with_roslyn, get_history, save_history, clear_history");
4648
}
4749

4850
switch (action)
@@ -69,31 +71,28 @@ public static object HandleCommand(JObject @params)
6971
return ClearCompilationHistory();
7072

7173
default:
72-
return Response.Error($"Unknown action '{action}'. Valid actions: compile_and_load, list_loaded, get_types, execute_with_roslyn, get_history, save_history, clear_history");
74+
return new ErrorResponse($"Unknown action '{action}'. Valid actions: compile_and_load, list_loaded, get_types, execute_with_roslyn, get_history, save_history, clear_history");
7375
}
7476
}
7577

7678
private static object CompileAndLoad(JObject @params)
7779
{
7880
#if !USE_ROSLYN
79-
return Response.Error(
81+
return new ErrorResponse(
8082
"Runtime compilation requires Roslyn. Please install Microsoft.CodeAnalysis.CSharp NuGet package and add USE_ROSLYN to Scripting Define Symbols. " +
8183
"See ManageScript.cs header for installation instructions."
8284
);
8385
#else
8486
try
8587
{
8688
string code = @params["code"]?.ToString();
87-
var assemblyToken = @params["assembly_name"];
88-
string assemblyName = assemblyToken == null || string.IsNullOrWhiteSpace(assemblyToken.ToString())
89-
? $"DynamicAssembly_{DateTime.Now.Ticks}"
90-
: assemblyToken.ToString().Trim();
89+
string assemblyName = @params["assembly_name"]?.ToString() ?? $"DynamicAssembly_{DateTime.Now.Ticks}";
9190
string attachTo = @params["attach_to"]?.ToString();
9291
bool loadImmediately = @params["load_immediately"]?.ToObject<bool>() ?? true;
9392

9493
if (string.IsNullOrEmpty(code))
9594
{
96-
return Response.Error("'code' parameter is required");
95+
return new ErrorResponse("'code' parameter is required");
9796
}
9897

9998
// Ensure unique assembly name
@@ -104,21 +103,8 @@ private static object CompileAndLoad(JObject @params)
104103

105104
// Create output directory
106105
Directory.CreateDirectory(DynamicAssembliesPath);
107-
string basePath = Path.GetFullPath(DynamicAssembliesPath);
108-
Directory.CreateDirectory(basePath);
109-
string safeFileName = SanitizeAssemblyFileName(assemblyName);
110-
string dllPath = Path.GetFullPath(Path.Combine(basePath, $"{safeFileName}.dll"));
111-
112-
if (!dllPath.StartsWith(basePath, StringComparison.Ordinal))
113-
{
114-
return Response.Error("Assembly name must resolve inside the dynamic assemblies directory.");
115-
}
116-
117-
if (File.Exists(dllPath))
118-
{
119-
dllPath = Path.GetFullPath(Path.Combine(basePath, $"{safeFileName}_{DateTime.Now.Ticks}.dll"));
120-
}
121-
106+
string dllPath = Path.Combine(DynamicAssembliesPath, $"{assemblyName}.dll");
107+
122108
// Parse code
123109
var syntaxTree = CSharpSyntaxTree.ParseText(code);
124110

@@ -137,7 +123,7 @@ private static object CompileAndLoad(JObject @params)
137123

138124
// Emit to file
139125
EmitResult emitResult;
140-
using (var stream = new FileStream(dllPath, FileMode.Create, FileAccess.Write, FileShare.None))
126+
using (var stream = new FileStream(dllPath, FileMode.Create))
141127
{
142128
emitResult = compilation.Emit(stream);
143129
}
@@ -156,7 +142,7 @@ private static object CompileAndLoad(JObject @params)
156142
})
157143
.ToList();
158144

159-
return Response.Error("Compilation failed", new
145+
return new ErrorResponse("Compilation failed", new
160146
{
161147
errors = errors,
162148
error_count = errors.Count
@@ -222,7 +208,7 @@ private static object CompileAndLoad(JObject @params)
222208
}
223209
}
224210

225-
return Response.Success("Runtime compilation completed successfully", new
211+
return new SuccessResponse("Runtime compilation completed successfully", new
226212
{
227213
assembly_name = assemblyName,
228214
dll_path = dllPath,
@@ -235,15 +221,15 @@ private static object CompileAndLoad(JObject @params)
235221
}
236222
catch (Exception ex)
237223
{
238-
return Response.Error($"Runtime compilation failed: {ex.Message}", new
224+
return new ErrorResponse($"Runtime compilation failed: {ex.Message}", new
239225
{
240226
exception = ex.GetType().Name,
241227
stack_trace = ex.StackTrace
242228
});
243229
}
244230
#endif
245231
}
246-
232+
247233
private static object ListLoadedAssemblies()
248234
{
249235
var assemblies = LoadedAssemblies.Values.Select(info => new
@@ -254,33 +240,26 @@ private static object ListLoadedAssemblies()
254240
type_count = info.TypeNames.Count,
255241
types = info.TypeNames
256242
}).ToList();
257-
258-
return Response.Success($"Found {assemblies.Count} loaded dynamic assemblies", new
243+
244+
return new SuccessResponse($"Found {assemblies.Count} loaded dynamic assemblies", new
259245
{
260246
count = assemblies.Count,
261247
assemblies = assemblies
262248
});
263249
}
264250

265-
private static string SanitizeAssemblyFileName(string assemblyName)
266-
{
267-
var invalidChars = Path.GetInvalidFileNameChars();
268-
var sanitized = new string(assemblyName.Where(c => !invalidChars.Contains(c)).ToArray());
269-
return string.IsNullOrWhiteSpace(sanitized) ? $"DynamicAssembly_{DateTime.Now.Ticks}" : sanitized;
270-
}
271-
272251
private static object GetAssemblyTypes(JObject @params)
273252
{
274253
string assemblyName = @params["assembly_name"]?.ToString();
275254

276255
if (string.IsNullOrEmpty(assemblyName))
277256
{
278-
return Response.Error("'assembly_name' parameter is required");
257+
return new ErrorResponse("'assembly_name' parameter is required");
279258
}
280259

281260
if (!LoadedAssemblies.TryGetValue(assemblyName, out var info))
282261
{
283-
return Response.Error($"Assembly '{assemblyName}' not found in loaded assemblies");
262+
return new ErrorResponse($"Assembly '{assemblyName}' not found in loaded assemblies");
284263
}
285264

286265
var types = info.Assembly.GetTypes().Select(t => new
@@ -294,7 +273,7 @@ private static object GetAssemblyTypes(JObject @params)
294273
base_type = t.BaseType?.FullName
295274
}).ToList();
296275

297-
return Response.Success($"Retrieved {types.Count} types from {assemblyName}", new
276+
return new SuccessResponse($"Retrieved {types.Count} types from {assemblyName}", new
298277
{
299278
assembly_name = assemblyName,
300279
type_count = types.Count,
@@ -318,7 +297,7 @@ private static object ExecuteWithRoslyn(JObject @params)
318297

319298
if (string.IsNullOrEmpty(code))
320299
{
321-
return Response.Error("'code' parameter is required");
300+
return new ErrorResponse("'code' parameter is required");
322301
}
323302

324303
// Get or create the RoslynRuntimeCompiler instance
@@ -336,7 +315,7 @@ private static object ExecuteWithRoslyn(JObject @params)
336315

337316
if (targetObject == null)
338317
{
339-
return Response.Error($"Target GameObject '{targetObjectName}' not found");
318+
return new ErrorResponse($"Target GameObject '{targetObjectName}' not found");
340319
}
341320
}
342321

@@ -352,7 +331,7 @@ out string errorMessage
352331

353332
if (success)
354333
{
355-
return Response.Success($"Code compiled and executed successfully", new
334+
return new SuccessResponse($"Code compiled and executed successfully", new
356335
{
357336
class_name = className,
358337
method_name = methodName,
@@ -363,15 +342,15 @@ out string errorMessage
363342
}
364343
else
365344
{
366-
return Response.Error($"Execution failed: {errorMessage}", new
345+
return new ErrorResponse($"Execution failed: {errorMessage}", new
367346
{
368347
diagnostics = compiler.lastCompileDiagnostics
369348
});
370349
}
371350
}
372351
catch (Exception ex)
373352
{
374-
return Response.Error($"Failed to execute with Roslyn: {ex.Message}", new
353+
return new ErrorResponse($"Failed to execute with Roslyn: {ex.Message}", new
375354
{
376355
exception = ex.GetType().Name,
377356
stack_trace = ex.StackTrace
@@ -402,15 +381,15 @@ private static object GetCompilationHistory()
402381
: entry.sourceCode
403382
}).ToList();
404383

405-
return Response.Success($"Retrieved {historyData.Count} history entries", new
384+
return new SuccessResponse($"Retrieved {historyData.Count} history entries", new
406385
{
407386
count = historyData.Count,
408387
history = historyData
409388
});
410389
}
411390
catch (Exception ex)
412391
{
413-
return Response.Error($"Failed to get history: {ex.Message}");
392+
return new ErrorResponse($"Failed to get history: {ex.Message}");
414393
}
415394
}
416395

@@ -425,20 +404,20 @@ private static object SaveCompilationHistory()
425404

426405
if (compiler.SaveHistoryToFile(out string savedPath, out string error))
427406
{
428-
return Response.Success($"History saved successfully", new
407+
return new SuccessResponse($"History saved successfully", new
429408
{
430409
path = savedPath,
431410
entry_count = compiler.CompilationHistory.Count
432411
});
433412
}
434413
else
435414
{
436-
return Response.Error($"Failed to save history: {error}");
415+
return new ErrorResponse($"Failed to save history: {error}");
437416
}
438417
}
439418
catch (Exception ex)
440419
{
441-
return Response.Error($"Failed to save history: {ex.Message}");
420+
return new ErrorResponse($"Failed to save history: {ex.Message}");
442421
}
443422
}
444423

@@ -453,11 +432,11 @@ private static object ClearCompilationHistory()
453432
int count = compiler.CompilationHistory.Count;
454433
compiler.ClearHistory();
455434

456-
return Response.Success($"Cleared {count} history entries");
435+
return new SuccessResponse($"Cleared {count} history entries");
457436
}
458437
catch (Exception ex)
459438
{
460-
return Response.Error($"Failed to clear history: {ex.Message}");
439+
return new ErrorResponse($"Failed to clear history: {ex.Message}");
461440
}
462441
}
463442

CustomTools/RoslynRuntimeCompilation/RoslynRuntime.md

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)