@mflrevan/ucp 0.4.3 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bridge/com.ucp.bridge/CHANGELOG.md +145 -0
- package/bridge/com.ucp.bridge/CHANGELOG.md.meta +7 -0
- package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs +583 -0
- package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Bridge.meta +8 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs +425 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetImportSupport.cs +355 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetImportSupport.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs +233 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs +26 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs +31 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs +527 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs +141 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs +326 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ImporterController.cs +209 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ImporterController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs +409 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs +354 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs +93 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PackagesController.cs +503 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PackagesController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs +188 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs +260 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ProfilerController.cs +1679 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ProfilerController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs +563 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs +166 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs +318 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs +125 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs +104 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs +227 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs +240 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs +611 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers.meta +8 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs +53 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs +80 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs +358 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Protocol.meta +8 -0
- package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs +37 -0
- package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Scripts.meta +8 -0
- package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef +16 -0
- package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef.meta +7 -0
- package/bridge/com.ucp.bridge/Editor.meta +8 -0
- package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef +14 -0
- package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef.meta +7 -0
- package/bridge/com.ucp.bridge/Runtime.meta +8 -0
- package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs +1085 -0
- package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef +12 -0
- package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef.meta +7 -0
- package/bridge/com.ucp.bridge/Tests/Editor.meta +8 -0
- package/bridge/com.ucp.bridge/Tests.meta +8 -0
- package/bridge/com.ucp.bridge/package.json +27 -0
- package/bridge/com.ucp.bridge/package.json.meta +7 -0
- package/package.json +2 -2
- package/scripts/install.js +4 -6
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using UnityEngine;
|
|
4
|
+
|
|
5
|
+
namespace UCP.Bridge
|
|
6
|
+
{
|
|
7
|
+
/// <summary>
|
|
8
|
+
/// JSON-RPC 2.0 message types for the UCP protocol.
|
|
9
|
+
/// </summary>
|
|
10
|
+
|
|
11
|
+
[Serializable]
|
|
12
|
+
public class JsonRpcRequest
|
|
13
|
+
{
|
|
14
|
+
public string jsonrpc = "2.0";
|
|
15
|
+
public long id;
|
|
16
|
+
public string method;
|
|
17
|
+
public string @params; // raw JSON string - parsed by handlers
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
[Serializable]
|
|
21
|
+
public class JsonRpcResponse
|
|
22
|
+
{
|
|
23
|
+
public string jsonrpc = "2.0";
|
|
24
|
+
public long? id;
|
|
25
|
+
public object result;
|
|
26
|
+
public JsonRpcError error;
|
|
27
|
+
|
|
28
|
+
public static JsonRpcResponse Success(long id, object data)
|
|
29
|
+
{
|
|
30
|
+
return new JsonRpcResponse { id = id, result = data };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public static JsonRpcResponse Error(long id, int code, string message, object data = null)
|
|
34
|
+
{
|
|
35
|
+
return new JsonRpcResponse
|
|
36
|
+
{
|
|
37
|
+
id = id,
|
|
38
|
+
error = new JsonRpcError { code = code, message = message, data = data }
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
[Serializable]
|
|
44
|
+
public class JsonRpcError
|
|
45
|
+
{
|
|
46
|
+
public int code;
|
|
47
|
+
public string message;
|
|
48
|
+
public object data;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
[Serializable]
|
|
52
|
+
public class JsonRpcNotification
|
|
53
|
+
{
|
|
54
|
+
public string jsonrpc = "2.0";
|
|
55
|
+
public string method;
|
|
56
|
+
public object @params;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// <summary>
|
|
60
|
+
/// Standard UCP error codes.
|
|
61
|
+
/// </summary>
|
|
62
|
+
public static class ErrorCodes
|
|
63
|
+
{
|
|
64
|
+
public const int ParseError = -32700;
|
|
65
|
+
public const int InvalidRequest = -32600;
|
|
66
|
+
public const int MethodNotFound = -32601;
|
|
67
|
+
public const int InvalidParams = -32602;
|
|
68
|
+
public const int InternalError = -32603;
|
|
69
|
+
public const int UnityError = -32000;
|
|
70
|
+
public const int SceneNotLoaded = -32001;
|
|
71
|
+
public const int CompilationFailed = -32002;
|
|
72
|
+
public const int PlayModeConflict = -32003;
|
|
73
|
+
public const int FileAccessDenied = -32004;
|
|
74
|
+
public const int TestFailed = -32005;
|
|
75
|
+
public const int ScreenshotFailed = -32006;
|
|
76
|
+
public const int ObjectNotFound = -32007;
|
|
77
|
+
public const int Timeout = -32008;
|
|
78
|
+
public const int AuthFailed = -32009;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MiniJson - A minimal JSON parser/serializer for Unity.
|
|
3
|
+
* Based on the public domain MiniJSON by Calvin Rien.
|
|
4
|
+
* Handles Dictionary<string, object>, List<object>, string, long, double, bool, null.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
using System;
|
|
8
|
+
using System.Collections;
|
|
9
|
+
using System.Collections.Generic;
|
|
10
|
+
using System.Globalization;
|
|
11
|
+
using System.IO;
|
|
12
|
+
using System.Text;
|
|
13
|
+
|
|
14
|
+
namespace UCP.Bridge
|
|
15
|
+
{
|
|
16
|
+
public static class MiniJson
|
|
17
|
+
{
|
|
18
|
+
public static object Deserialize(string json)
|
|
19
|
+
{
|
|
20
|
+
if (json == null) return null;
|
|
21
|
+
return Parser.Parse(json);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public static string Serialize(object obj)
|
|
25
|
+
{
|
|
26
|
+
return Serializer.Serialize(obj);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private sealed class Parser : IDisposable
|
|
30
|
+
{
|
|
31
|
+
private StringReader _reader;
|
|
32
|
+
|
|
33
|
+
private Parser(string jsonString)
|
|
34
|
+
{
|
|
35
|
+
_reader = new StringReader(jsonString);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public static object Parse(string jsonString)
|
|
39
|
+
{
|
|
40
|
+
using var parser = new Parser(jsonString);
|
|
41
|
+
return parser.ParseValue();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public void Dispose()
|
|
45
|
+
{
|
|
46
|
+
_reader?.Dispose();
|
|
47
|
+
_reader = null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private object ParseValue()
|
|
51
|
+
{
|
|
52
|
+
EatWhitespace();
|
|
53
|
+
var c = PeekChar();
|
|
54
|
+
switch (c)
|
|
55
|
+
{
|
|
56
|
+
case '{': return ParseObject();
|
|
57
|
+
case '[': return ParseArray();
|
|
58
|
+
case '"': return ParseString();
|
|
59
|
+
case '-':
|
|
60
|
+
case '0':
|
|
61
|
+
case '1':
|
|
62
|
+
case '2':
|
|
63
|
+
case '3':
|
|
64
|
+
case '4':
|
|
65
|
+
case '5':
|
|
66
|
+
case '6':
|
|
67
|
+
case '7':
|
|
68
|
+
case '8':
|
|
69
|
+
case '9':
|
|
70
|
+
return ParseNumber();
|
|
71
|
+
default:
|
|
72
|
+
return ParseLiteral();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private Dictionary<string, object> ParseObject()
|
|
77
|
+
{
|
|
78
|
+
ReadChar(); // {
|
|
79
|
+
var dict = new Dictionary<string, object>();
|
|
80
|
+
|
|
81
|
+
while (true)
|
|
82
|
+
{
|
|
83
|
+
EatWhitespace();
|
|
84
|
+
if (PeekChar() == '}') { ReadChar(); return dict; }
|
|
85
|
+
if (PeekChar() == ',') { ReadChar(); continue; }
|
|
86
|
+
|
|
87
|
+
var key = ParseString();
|
|
88
|
+
EatWhitespace();
|
|
89
|
+
ReadChar(); // :
|
|
90
|
+
dict[key] = ParseValue();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private List<object> ParseArray()
|
|
95
|
+
{
|
|
96
|
+
ReadChar(); // [
|
|
97
|
+
var list = new List<object>();
|
|
98
|
+
|
|
99
|
+
while (true)
|
|
100
|
+
{
|
|
101
|
+
EatWhitespace();
|
|
102
|
+
if (PeekChar() == ']') { ReadChar(); return list; }
|
|
103
|
+
if (PeekChar() == ',') { ReadChar(); continue; }
|
|
104
|
+
|
|
105
|
+
list.Add(ParseValue());
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private string ParseString()
|
|
110
|
+
{
|
|
111
|
+
ReadChar(); // opening "
|
|
112
|
+
var sb = new StringBuilder();
|
|
113
|
+
|
|
114
|
+
while (true)
|
|
115
|
+
{
|
|
116
|
+
var c = ReadChar();
|
|
117
|
+
if (c == '"') return sb.ToString();
|
|
118
|
+
if (c == '\\')
|
|
119
|
+
{
|
|
120
|
+
c = ReadChar();
|
|
121
|
+
switch (c)
|
|
122
|
+
{
|
|
123
|
+
case '"': case '\\': case '/': sb.Append(c); break;
|
|
124
|
+
case 'b': sb.Append('\b'); break;
|
|
125
|
+
case 'f': sb.Append('\f'); break;
|
|
126
|
+
case 'n': sb.Append('\n'); break;
|
|
127
|
+
case 'r': sb.Append('\r'); break;
|
|
128
|
+
case 't': sb.Append('\t'); break;
|
|
129
|
+
case 'u':
|
|
130
|
+
var hex = new char[4];
|
|
131
|
+
for (int i = 0; i < 4; i++) hex[i] = ReadChar();
|
|
132
|
+
sb.Append((char)Convert.ToUInt16(new string(hex), 16));
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else
|
|
137
|
+
{
|
|
138
|
+
sb.Append(c);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private object ParseNumber()
|
|
144
|
+
{
|
|
145
|
+
var sb = new StringBuilder();
|
|
146
|
+
bool isFloat = false;
|
|
147
|
+
|
|
148
|
+
while (true)
|
|
149
|
+
{
|
|
150
|
+
var c = PeekChar();
|
|
151
|
+
if (c == '.' || c == 'e' || c == 'E') isFloat = true;
|
|
152
|
+
if ((c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+' || c == 'e' || c == 'E')
|
|
153
|
+
{
|
|
154
|
+
sb.Append(ReadChar());
|
|
155
|
+
}
|
|
156
|
+
else break;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
var s = sb.ToString();
|
|
160
|
+
if (isFloat)
|
|
161
|
+
return double.Parse(s, CultureInfo.InvariantCulture);
|
|
162
|
+
return long.Parse(s, CultureInfo.InvariantCulture);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private object ParseLiteral()
|
|
166
|
+
{
|
|
167
|
+
var sb = new StringBuilder();
|
|
168
|
+
while (true)
|
|
169
|
+
{
|
|
170
|
+
var c = PeekChar();
|
|
171
|
+
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
|
|
172
|
+
sb.Append(ReadChar());
|
|
173
|
+
else break;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
var s = sb.ToString();
|
|
177
|
+
return s switch
|
|
178
|
+
{
|
|
179
|
+
"true" => (object)true,
|
|
180
|
+
"false" => (object)false,
|
|
181
|
+
"null" => null,
|
|
182
|
+
_ => throw new FormatException($"Unexpected literal: {s}")
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private void EatWhitespace()
|
|
187
|
+
{
|
|
188
|
+
while (true)
|
|
189
|
+
{
|
|
190
|
+
var c = PeekChar();
|
|
191
|
+
if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
|
|
192
|
+
ReadChar();
|
|
193
|
+
else break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private char PeekChar()
|
|
198
|
+
{
|
|
199
|
+
int c = _reader.Peek();
|
|
200
|
+
return c < 0 ? '\0' : (char)c;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private char ReadChar()
|
|
204
|
+
{
|
|
205
|
+
int c = _reader.Read();
|
|
206
|
+
return c < 0 ? '\0' : (char)c;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private sealed class Serializer
|
|
211
|
+
{
|
|
212
|
+
private readonly StringBuilder _sb = new();
|
|
213
|
+
|
|
214
|
+
public static string Serialize(object obj)
|
|
215
|
+
{
|
|
216
|
+
var s = new Serializer();
|
|
217
|
+
s.WriteValue(obj);
|
|
218
|
+
return s._sb.ToString();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private void WriteValue(object obj)
|
|
222
|
+
{
|
|
223
|
+
switch (obj)
|
|
224
|
+
{
|
|
225
|
+
case null:
|
|
226
|
+
_sb.Append("null");
|
|
227
|
+
break;
|
|
228
|
+
case string s:
|
|
229
|
+
WriteString(s);
|
|
230
|
+
break;
|
|
231
|
+
case bool b:
|
|
232
|
+
_sb.Append(b ? "true" : "false");
|
|
233
|
+
break;
|
|
234
|
+
case IDictionary dict:
|
|
235
|
+
WriteDict(dict);
|
|
236
|
+
break;
|
|
237
|
+
case IList list:
|
|
238
|
+
WriteArray(list);
|
|
239
|
+
break;
|
|
240
|
+
case float f:
|
|
241
|
+
_sb.Append(f.ToString("R", CultureInfo.InvariantCulture));
|
|
242
|
+
break;
|
|
243
|
+
case double d:
|
|
244
|
+
_sb.Append(d.ToString("R", CultureInfo.InvariantCulture));
|
|
245
|
+
break;
|
|
246
|
+
case int i:
|
|
247
|
+
_sb.Append(i);
|
|
248
|
+
break;
|
|
249
|
+
case long l:
|
|
250
|
+
_sb.Append(l);
|
|
251
|
+
break;
|
|
252
|
+
case Enum e:
|
|
253
|
+
_sb.Append(Convert.ToInt32(e));
|
|
254
|
+
break;
|
|
255
|
+
default:
|
|
256
|
+
// For anonymous types and other objects, use reflection
|
|
257
|
+
WriteObject(obj);
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
private void WriteString(string s)
|
|
263
|
+
{
|
|
264
|
+
_sb.Append('"');
|
|
265
|
+
foreach (var c in s)
|
|
266
|
+
{
|
|
267
|
+
switch (c)
|
|
268
|
+
{
|
|
269
|
+
case '"': _sb.Append("\\\""); break;
|
|
270
|
+
case '\\': _sb.Append("\\\\"); break;
|
|
271
|
+
case '\b': _sb.Append("\\b"); break;
|
|
272
|
+
case '\f': _sb.Append("\\f"); break;
|
|
273
|
+
case '\n': _sb.Append("\\n"); break;
|
|
274
|
+
case '\r': _sb.Append("\\r"); break;
|
|
275
|
+
case '\t': _sb.Append("\\t"); break;
|
|
276
|
+
default:
|
|
277
|
+
if (c < ' ')
|
|
278
|
+
_sb.AppendFormat("\\u{0:x4}", (int)c);
|
|
279
|
+
else
|
|
280
|
+
_sb.Append(c);
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
_sb.Append('"');
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
private void WriteDict(IDictionary dict)
|
|
288
|
+
{
|
|
289
|
+
_sb.Append('{');
|
|
290
|
+
bool first = true;
|
|
291
|
+
foreach (DictionaryEntry entry in dict)
|
|
292
|
+
{
|
|
293
|
+
if (!first) _sb.Append(',');
|
|
294
|
+
first = false;
|
|
295
|
+
WriteString(entry.Key.ToString());
|
|
296
|
+
_sb.Append(':');
|
|
297
|
+
WriteValue(entry.Value);
|
|
298
|
+
}
|
|
299
|
+
_sb.Append('}');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
private void WriteArray(IList list)
|
|
303
|
+
{
|
|
304
|
+
_sb.Append('[');
|
|
305
|
+
for (int i = 0; i < list.Count; i++)
|
|
306
|
+
{
|
|
307
|
+
if (i > 0) _sb.Append(',');
|
|
308
|
+
WriteValue(list[i]);
|
|
309
|
+
}
|
|
310
|
+
_sb.Append(']');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
private void WriteObject(object obj)
|
|
314
|
+
{
|
|
315
|
+
var type = obj.GetType();
|
|
316
|
+
var props = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
|
317
|
+
var fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
|
318
|
+
|
|
319
|
+
_sb.Append('{');
|
|
320
|
+
bool first = true;
|
|
321
|
+
|
|
322
|
+
foreach (var prop in props)
|
|
323
|
+
{
|
|
324
|
+
if (!prop.CanRead) continue;
|
|
325
|
+
try
|
|
326
|
+
{
|
|
327
|
+
var val = prop.GetValue(obj);
|
|
328
|
+
if (!first) _sb.Append(',');
|
|
329
|
+
first = false;
|
|
330
|
+
// Convert PascalCase to camelCase
|
|
331
|
+
var name = char.ToLowerInvariant(prop.Name[0]) + prop.Name.Substring(1);
|
|
332
|
+
WriteString(name);
|
|
333
|
+
_sb.Append(':');
|
|
334
|
+
WriteValue(val);
|
|
335
|
+
}
|
|
336
|
+
catch { }
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
foreach (var field in fields)
|
|
340
|
+
{
|
|
341
|
+
try
|
|
342
|
+
{
|
|
343
|
+
var val = field.GetValue(obj);
|
|
344
|
+
if (!first) _sb.Append(',');
|
|
345
|
+
first = false;
|
|
346
|
+
var name = char.ToLowerInvariant(field.Name[0]) + field.Name.Substring(1);
|
|
347
|
+
WriteString(name);
|
|
348
|
+
_sb.Append(':');
|
|
349
|
+
WriteValue(val);
|
|
350
|
+
}
|
|
351
|
+
catch { }
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
_sb.Append('}');
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
namespace UCP.Bridge
|
|
2
|
+
{
|
|
3
|
+
/// <summary>
|
|
4
|
+
/// Interface for UCP scripts - editor automation sequences auto-discovered by the bridge.
|
|
5
|
+
/// Implement this interface in any Editor script to make it callable via `ucp exec`.
|
|
6
|
+
///
|
|
7
|
+
/// Example:
|
|
8
|
+
/// <code>
|
|
9
|
+
/// public class ValidateScene : IUCPScript
|
|
10
|
+
/// {
|
|
11
|
+
/// public string Name => "validate-scene";
|
|
12
|
+
/// public string Description => "Check that the active scene meets quality requirements";
|
|
13
|
+
/// public object Execute(string paramsJson)
|
|
14
|
+
/// {
|
|
15
|
+
/// var errors = new List<string>();
|
|
16
|
+
/// // ... validation logic ...
|
|
17
|
+
/// return new { valid = errors.Count == 0, errors };
|
|
18
|
+
/// }
|
|
19
|
+
/// }
|
|
20
|
+
/// </code>
|
|
21
|
+
/// </summary>
|
|
22
|
+
public interface IUCPScript
|
|
23
|
+
{
|
|
24
|
+
/// <summary>Unique name used to invoke this script via CLI (e.g., "validate-scene").</summary>
|
|
25
|
+
string Name { get; }
|
|
26
|
+
|
|
27
|
+
/// <summary>Short human-readable description of what this script does.</summary>
|
|
28
|
+
string Description { get; }
|
|
29
|
+
|
|
30
|
+
/// <summary>
|
|
31
|
+
/// Execute the script. Runs on Unity's main thread.
|
|
32
|
+
/// </summary>
|
|
33
|
+
/// <param name="paramsJson">Optional JSON string with parameters. Defaults to "{}".</param>
|
|
34
|
+
/// <returns>Any serializable object - will be returned as JSON to the CLI.</returns>
|
|
35
|
+
object Execute(string paramsJson);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "UCP.Bridge.Editor",
|
|
3
|
+
"rootNamespace": "UCP.Bridge",
|
|
4
|
+
"references": [],
|
|
5
|
+
"includePlatforms": [
|
|
6
|
+
"Editor"
|
|
7
|
+
],
|
|
8
|
+
"excludePlatforms": [],
|
|
9
|
+
"allowUnsafeCode": false,
|
|
10
|
+
"overrideReferences": false,
|
|
11
|
+
"precompiledReferences": [],
|
|
12
|
+
"autoReferenced": true,
|
|
13
|
+
"defineConstraints": [],
|
|
14
|
+
"versionDefines": [],
|
|
15
|
+
"noEngineReferences": false
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "UCP.Bridge.Runtime",
|
|
3
|
+
"rootNamespace": "UCP.Bridge.Runtime",
|
|
4
|
+
"references": [],
|
|
5
|
+
"includePlatforms": [],
|
|
6
|
+
"excludePlatforms": [],
|
|
7
|
+
"allowUnsafeCode": false,
|
|
8
|
+
"overrideReferences": false,
|
|
9
|
+
"precompiledReferences": [],
|
|
10
|
+
"autoReferenced": true,
|
|
11
|
+
"defineConstraints": [],
|
|
12
|
+
"versionDefines": [],
|
|
13
|
+
"noEngineReferences": false
|
|
14
|
+
}
|