@mflrevan/ucp 0.4.0 → 0.4.1
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 +2 -2
- package/package.json +8 -2
- package/bridge/com.ucp.bridge/CHANGELOG.md +0 -128
- package/bridge/com.ucp.bridge/CHANGELOG.md.meta +0 -7
- package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs +0 -576
- package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Bridge.meta +0 -8
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs +0 -530
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs +0 -230
- package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs +0 -26
- package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs +0 -18
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs +0 -438
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs +0 -145
- package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs +0 -319
- package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs +0 -288
- package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs +0 -295
- package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs +0 -93
- package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs +0 -84
- package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs +0 -242
- package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs +0 -533
- package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs +0 -269
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs +0 -125
- package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs +0 -104
- package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs +0 -227
- package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs +0 -240
- package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs +0 -611
- package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Controllers.meta +0 -8
- package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs +0 -53
- package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs +0 -80
- package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs +0 -358
- package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Protocol.meta +0 -8
- package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs +0 -37
- package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Editor/Scripts.meta +0 -8
- package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef +0 -16
- package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef.meta +0 -7
- package/bridge/com.ucp.bridge/Editor.meta +0 -8
- package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef +0 -14
- package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef.meta +0 -7
- package/bridge/com.ucp.bridge/Runtime.meta +0 -8
- package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs +0 -670
- package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs.meta +0 -2
- package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef +0 -12
- package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef.meta +0 -7
- package/bridge/com.ucp.bridge/Tests/Editor.meta +0 -8
- package/bridge/com.ucp.bridge/Tests.meta +0 -8
- package/bridge/com.ucp.bridge/package.json +0 -27
- package/bridge/com.ucp.bridge/package.json.meta +0 -7
|
@@ -1,611 +0,0 @@
|
|
|
1
|
-
using System;
|
|
2
|
-
using System.Collections.Generic;
|
|
3
|
-
using System.Linq;
|
|
4
|
-
using UnityEditor;
|
|
5
|
-
using UnityEditor.VersionControl;
|
|
6
|
-
using UnityEngine;
|
|
7
|
-
|
|
8
|
-
namespace UCP.Bridge
|
|
9
|
-
{
|
|
10
|
-
/// <summary>
|
|
11
|
-
/// Version control operations via UnityEditor.VersionControl (Unity VCS / Plastic SCM).
|
|
12
|
-
/// All commands go through the Editor's VC provider — the active provider must be configured
|
|
13
|
-
/// in Unity's Project Settings > Version Control.
|
|
14
|
-
/// </summary>
|
|
15
|
-
public static class VcsController
|
|
16
|
-
{
|
|
17
|
-
public static void Register(CommandRouter router)
|
|
18
|
-
{
|
|
19
|
-
router.Register("vcs/info", HandleInfo);
|
|
20
|
-
router.Register("vcs/status", HandleStatus);
|
|
21
|
-
router.Register("vcs/checkout", HandleCheckout);
|
|
22
|
-
router.Register("vcs/revert", HandleRevert);
|
|
23
|
-
router.Register("vcs/commit", HandleCommit);
|
|
24
|
-
router.Register("vcs/diff", HandleDiff);
|
|
25
|
-
router.Register("vcs/incoming", HandleIncoming);
|
|
26
|
-
router.Register("vcs/update", HandleUpdate);
|
|
27
|
-
router.Register("vcs/branches", HandleBranches);
|
|
28
|
-
router.Register("vcs/lock", HandleLock);
|
|
29
|
-
router.Register("vcs/unlock", HandleUnlock);
|
|
30
|
-
router.Register("vcs/history", HandleHistory);
|
|
31
|
-
router.Register("vcs/resolve", HandleResolve);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// ── Helpers ──────────────────────────────────────────────
|
|
35
|
-
|
|
36
|
-
private static void EnsureVcsActive()
|
|
37
|
-
{
|
|
38
|
-
if (!Provider.enabled || !Provider.isActive)
|
|
39
|
-
throw new InvalidOperationException(
|
|
40
|
-
"Version control is not active. Enable it in Project Settings > Version Control.");
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
private static bool WaitForTask(UnityEditor.VersionControl.Task task, int timeoutMs = 30000)
|
|
44
|
-
{
|
|
45
|
-
if (task == null) return false;
|
|
46
|
-
task.Wait();
|
|
47
|
-
return task.success;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private static List<string> ParsePaths(string paramsJson)
|
|
51
|
-
{
|
|
52
|
-
var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
|
|
53
|
-
if (p == null) return new List<string>();
|
|
54
|
-
|
|
55
|
-
if (p.TryGetValue("paths", out var pathsObj) && pathsObj is List<object> list)
|
|
56
|
-
return list.Select(x => x?.ToString()).Where(x => !string.IsNullOrEmpty(x)).ToList();
|
|
57
|
-
|
|
58
|
-
if (p.TryGetValue("path", out var pathObj) && pathObj != null)
|
|
59
|
-
{
|
|
60
|
-
var s = pathObj.ToString();
|
|
61
|
-
if (!string.IsNullOrEmpty(s)) return new List<string> { s };
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return new List<string>();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private static AssetList ToAssetList(IEnumerable<string> paths)
|
|
68
|
-
{
|
|
69
|
-
var list = new AssetList();
|
|
70
|
-
foreach (var path in paths)
|
|
71
|
-
{
|
|
72
|
-
var asset = Provider.GetAssetByPath(path);
|
|
73
|
-
if (asset != null) list.Add(asset);
|
|
74
|
-
}
|
|
75
|
-
return list;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private static Dictionary<string, object> AssetToDict(Asset asset)
|
|
79
|
-
{
|
|
80
|
-
return new Dictionary<string, object>
|
|
81
|
-
{
|
|
82
|
-
["path"] = asset.path ?? "",
|
|
83
|
-
["state"] = asset.state.ToString(),
|
|
84
|
-
["isFolder"] = asset.isFolder,
|
|
85
|
-
["name"] = asset.name ?? "",
|
|
86
|
-
["locked"] = asset.IsState(Asset.States.LockedLocal) || asset.IsState(Asset.States.LockedRemote),
|
|
87
|
-
["lockedLocal"] = asset.IsState(Asset.States.LockedLocal),
|
|
88
|
-
["lockedRemote"] = asset.IsState(Asset.States.LockedRemote),
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// ── Handlers ─────────────────────────────────────────────
|
|
93
|
-
|
|
94
|
-
private static object HandleInfo(string paramsJson)
|
|
95
|
-
{
|
|
96
|
-
EnsureVcsActive();
|
|
97
|
-
|
|
98
|
-
// Return plugin and workspace info
|
|
99
|
-
var plugin = Provider.GetActivePlugin();
|
|
100
|
-
|
|
101
|
-
return new Dictionary<string, object>
|
|
102
|
-
{
|
|
103
|
-
["enabled"] = Provider.enabled,
|
|
104
|
-
["active"] = Provider.isActive,
|
|
105
|
-
["onlineState"] = Provider.onlineState.ToString(),
|
|
106
|
-
["offlineReason"] = Provider.offlineReason,
|
|
107
|
-
["plugin"] = plugin?.name ?? "unknown",
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
private static object HandleStatus(string paramsJson)
|
|
112
|
-
{
|
|
113
|
-
EnsureVcsActive();
|
|
114
|
-
|
|
115
|
-
var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
|
|
116
|
-
var paths = ParsePaths(paramsJson);
|
|
117
|
-
bool all = paths.Count == 0;
|
|
118
|
-
|
|
119
|
-
// If specific paths, query those; otherwise query all changes under Assets
|
|
120
|
-
UnityEditor.VersionControl.Task statusTask;
|
|
121
|
-
if (all)
|
|
122
|
-
statusTask = Provider.Status("Assets", true);
|
|
123
|
-
else
|
|
124
|
-
statusTask = Provider.Status(ToAssetList(paths), true);
|
|
125
|
-
|
|
126
|
-
WaitForTask(statusTask);
|
|
127
|
-
|
|
128
|
-
var items = new List<object>();
|
|
129
|
-
if (statusTask.assetList != null)
|
|
130
|
-
{
|
|
131
|
-
foreach (var asset in statusTask.assetList)
|
|
132
|
-
{
|
|
133
|
-
// Skip clean assets (no pending state) when showing full status
|
|
134
|
-
if (all && !HasPendingState(asset)) continue;
|
|
135
|
-
items.Add(AssetToDict(asset));
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return new Dictionary<string, object>
|
|
140
|
-
{
|
|
141
|
-
["count"] = items.Count,
|
|
142
|
-
["assets"] = items,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
private static bool HasPendingState(Asset a)
|
|
147
|
-
{
|
|
148
|
-
var states = a.state;
|
|
149
|
-
return (states & (Asset.States.CheckedOutLocal | Asset.States.CheckedOutRemote
|
|
150
|
-
| Asset.States.AddedLocal | Asset.States.AddedRemote
|
|
151
|
-
| Asset.States.DeletedLocal | Asset.States.DeletedRemote
|
|
152
|
-
| Asset.States.LockedLocal | Asset.States.LockedRemote
|
|
153
|
-
| Asset.States.Conflicted
|
|
154
|
-
| Asset.States.MovedLocal
|
|
155
|
-
| Asset.States.MovedRemote | Asset.States.Updating
|
|
156
|
-
| Asset.States.OutOfSync
|
|
157
|
-
)) != 0;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
private static object HandleCheckout(string paramsJson)
|
|
161
|
-
{
|
|
162
|
-
EnsureVcsActive();
|
|
163
|
-
|
|
164
|
-
var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
|
|
165
|
-
var paths = ParsePaths(paramsJson);
|
|
166
|
-
bool all = p?.ContainsKey("all") == true && Convert.ToBoolean(p["all"]);
|
|
167
|
-
|
|
168
|
-
AssetList assets;
|
|
169
|
-
if (all)
|
|
170
|
-
{
|
|
171
|
-
// Checkout everything that's modified / added under Assets
|
|
172
|
-
var statusTask = Provider.Status("Assets", true);
|
|
173
|
-
WaitForTask(statusTask);
|
|
174
|
-
assets = new AssetList();
|
|
175
|
-
if (statusTask.assetList != null)
|
|
176
|
-
{
|
|
177
|
-
foreach (var a in statusTask.assetList)
|
|
178
|
-
{
|
|
179
|
-
if (HasPendingState(a) || a.IsState(Asset.States.ReadOnly))
|
|
180
|
-
assets.Add(a);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
else
|
|
185
|
-
{
|
|
186
|
-
if (paths.Count == 0)
|
|
187
|
-
throw new ArgumentException("Provide 'path', 'paths', or 'all: true'");
|
|
188
|
-
assets = ToAssetList(paths);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (assets.Count == 0)
|
|
192
|
-
return new Dictionary<string, object> { ["count"] = 0, ["message"] = "Nothing to checkout" };
|
|
193
|
-
|
|
194
|
-
var task = Provider.Checkout(assets, CheckoutMode.Both);
|
|
195
|
-
bool ok = WaitForTask(task);
|
|
196
|
-
|
|
197
|
-
return new Dictionary<string, object>
|
|
198
|
-
{
|
|
199
|
-
["success"] = ok,
|
|
200
|
-
["count"] = assets.Count,
|
|
201
|
-
["paths"] = assets.Select(a => a.path).ToList(),
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
private static object HandleRevert(string paramsJson)
|
|
206
|
-
{
|
|
207
|
-
EnsureVcsActive();
|
|
208
|
-
|
|
209
|
-
var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
|
|
210
|
-
var paths = ParsePaths(paramsJson);
|
|
211
|
-
bool all = p?.ContainsKey("all") == true && Convert.ToBoolean(p["all"]);
|
|
212
|
-
|
|
213
|
-
AssetList assets;
|
|
214
|
-
if (all)
|
|
215
|
-
{
|
|
216
|
-
var statusTask = Provider.Status("Assets", true);
|
|
217
|
-
WaitForTask(statusTask);
|
|
218
|
-
assets = new AssetList();
|
|
219
|
-
if (statusTask.assetList != null)
|
|
220
|
-
{
|
|
221
|
-
foreach (var a in statusTask.assetList)
|
|
222
|
-
{
|
|
223
|
-
if (HasPendingState(a))
|
|
224
|
-
assets.Add(a);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
else
|
|
229
|
-
{
|
|
230
|
-
if (paths.Count == 0)
|
|
231
|
-
throw new ArgumentException("Provide 'path', 'paths', or 'all: true'");
|
|
232
|
-
assets = ToAssetList(paths);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (assets.Count == 0)
|
|
236
|
-
return new Dictionary<string, object> { ["count"] = 0, ["message"] = "Nothing to revert" };
|
|
237
|
-
|
|
238
|
-
var revertMode = RevertMode.Normal;
|
|
239
|
-
if (p?.ContainsKey("keepLocal") == true && Convert.ToBoolean(p["keepLocal"]))
|
|
240
|
-
revertMode = RevertMode.KeepModifications;
|
|
241
|
-
|
|
242
|
-
var task = Provider.Revert(assets, revertMode);
|
|
243
|
-
bool ok = WaitForTask(task);
|
|
244
|
-
|
|
245
|
-
return new Dictionary<string, object>
|
|
246
|
-
{
|
|
247
|
-
["success"] = ok,
|
|
248
|
-
["count"] = assets.Count,
|
|
249
|
-
["paths"] = assets.Select(a => a.path).ToList(),
|
|
250
|
-
};
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
private static object HandleCommit(string paramsJson)
|
|
254
|
-
{
|
|
255
|
-
EnsureVcsActive();
|
|
256
|
-
|
|
257
|
-
var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
|
|
258
|
-
if (p == null || !p.TryGetValue("message", out var msgObj) || string.IsNullOrEmpty(msgObj?.ToString()))
|
|
259
|
-
throw new ArgumentException("Missing 'message' parameter");
|
|
260
|
-
|
|
261
|
-
var message = msgObj.ToString();
|
|
262
|
-
var paths = ParsePaths(paramsJson);
|
|
263
|
-
bool all = paths.Count == 0;
|
|
264
|
-
|
|
265
|
-
// Build changeset
|
|
266
|
-
AssetList assets;
|
|
267
|
-
if (all)
|
|
268
|
-
{
|
|
269
|
-
var statusTask = Provider.Status("Assets", true);
|
|
270
|
-
WaitForTask(statusTask);
|
|
271
|
-
assets = new AssetList();
|
|
272
|
-
if (statusTask.assetList != null)
|
|
273
|
-
{
|
|
274
|
-
foreach (var a in statusTask.assetList)
|
|
275
|
-
{
|
|
276
|
-
if (HasPendingState(a))
|
|
277
|
-
assets.Add(a);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
else
|
|
282
|
-
{
|
|
283
|
-
assets = ToAssetList(paths);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
if (assets.Count == 0)
|
|
287
|
-
return new Dictionary<string, object> { ["success"] = false, ["message"] = "No pending changes to commit" };
|
|
288
|
-
|
|
289
|
-
var changeset = new ChangeSet("", "");
|
|
290
|
-
var task = Provider.Submit(changeset, assets, message, true);
|
|
291
|
-
bool ok = WaitForTask(task);
|
|
292
|
-
|
|
293
|
-
return new Dictionary<string, object>
|
|
294
|
-
{
|
|
295
|
-
["success"] = ok,
|
|
296
|
-
["count"] = assets.Count,
|
|
297
|
-
["commitMessage"] = message,
|
|
298
|
-
["paths"] = assets.Select(a => a.path).ToList(),
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
private static object HandleDiff(string paramsJson)
|
|
303
|
-
{
|
|
304
|
-
EnsureVcsActive();
|
|
305
|
-
|
|
306
|
-
var paths = ParsePaths(paramsJson);
|
|
307
|
-
|
|
308
|
-
if (paths.Count == 0)
|
|
309
|
-
{
|
|
310
|
-
// Return summary of changes (no specific diff)
|
|
311
|
-
var statusTask = Provider.Status("Assets", true);
|
|
312
|
-
WaitForTask(statusTask);
|
|
313
|
-
|
|
314
|
-
var summary = new Dictionary<string, int>
|
|
315
|
-
{
|
|
316
|
-
["modified"] = 0,
|
|
317
|
-
["added"] = 0,
|
|
318
|
-
["deleted"] = 0,
|
|
319
|
-
["moved"] = 0,
|
|
320
|
-
["conflicted"] = 0,
|
|
321
|
-
["outOfSync"] = 0
|
|
322
|
-
};
|
|
323
|
-
var items = new List<object>();
|
|
324
|
-
if (statusTask.assetList != null)
|
|
325
|
-
{
|
|
326
|
-
foreach (var a in statusTask.assetList)
|
|
327
|
-
{
|
|
328
|
-
if (!HasPendingState(a)) continue;
|
|
329
|
-
items.Add(AssetToDict(a));
|
|
330
|
-
|
|
331
|
-
if (a.IsState(Asset.States.CheckedOutLocal))
|
|
332
|
-
summary["modified"]++;
|
|
333
|
-
if (a.IsState(Asset.States.AddedLocal)) summary["added"]++;
|
|
334
|
-
if (a.IsState(Asset.States.DeletedLocal)) summary["deleted"]++;
|
|
335
|
-
if (a.IsState(Asset.States.MovedLocal)) summary["moved"]++;
|
|
336
|
-
if (a.IsState(Asset.States.Conflicted))
|
|
337
|
-
summary["conflicted"]++;
|
|
338
|
-
if (a.IsState(Asset.States.OutOfSync)) summary["outOfSync"]++;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return new Dictionary<string, object>
|
|
343
|
-
{
|
|
344
|
-
["summary"] = summary,
|
|
345
|
-
["count"] = items.Count,
|
|
346
|
-
["assets"] = items,
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
else
|
|
350
|
-
{
|
|
351
|
-
// Diff specific files — launch diff tool if running interactively
|
|
352
|
-
// For CLI, return status info for the requested paths
|
|
353
|
-
var statusTask = Provider.Status(ToAssetList(paths), true);
|
|
354
|
-
WaitForTask(statusTask);
|
|
355
|
-
|
|
356
|
-
var items = new List<object>();
|
|
357
|
-
if (statusTask.assetList != null)
|
|
358
|
-
{
|
|
359
|
-
foreach (var a in statusTask.assetList)
|
|
360
|
-
items.Add(AssetToDict(a));
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
return new Dictionary<string, object>
|
|
364
|
-
{
|
|
365
|
-
["count"] = items.Count,
|
|
366
|
-
["assets"] = items,
|
|
367
|
-
};
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
private static object HandleIncoming(string paramsJson)
|
|
372
|
-
{
|
|
373
|
-
EnsureVcsActive();
|
|
374
|
-
|
|
375
|
-
var task = Provider.Incoming();
|
|
376
|
-
WaitForTask(task);
|
|
377
|
-
|
|
378
|
-
var items = new List<object>();
|
|
379
|
-
if (task.assetList != null)
|
|
380
|
-
{
|
|
381
|
-
foreach (var a in task.assetList)
|
|
382
|
-
items.Add(AssetToDict(a));
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
return new Dictionary<string, object>
|
|
386
|
-
{
|
|
387
|
-
["count"] = items.Count,
|
|
388
|
-
["assets"] = items,
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
private static object HandleUpdate(string paramsJson)
|
|
393
|
-
{
|
|
394
|
-
EnsureVcsActive();
|
|
395
|
-
|
|
396
|
-
// Get incoming changes and apply them
|
|
397
|
-
var incomingTask = Provider.Incoming();
|
|
398
|
-
WaitForTask(incomingTask);
|
|
399
|
-
|
|
400
|
-
if (incomingTask.assetList == null || incomingTask.assetList.Count == 0)
|
|
401
|
-
return new Dictionary<string, object> { ["success"] = true, ["count"] = 0, ["message"] = "Already up to date" };
|
|
402
|
-
|
|
403
|
-
var task = Provider.GetLatest(incomingTask.assetList);
|
|
404
|
-
bool ok = WaitForTask(task);
|
|
405
|
-
|
|
406
|
-
return new Dictionary<string, object>
|
|
407
|
-
{
|
|
408
|
-
["success"] = ok,
|
|
409
|
-
["count"] = incomingTask.assetList.Count,
|
|
410
|
-
["assets"] = incomingTask.assetList.Select(a => a.path).ToList(),
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
private static object HandleBranches(string paramsJson)
|
|
415
|
-
{
|
|
416
|
-
EnsureVcsActive();
|
|
417
|
-
|
|
418
|
-
// Use the cm CLI tool to list branches — Provider API doesn't expose branches directly
|
|
419
|
-
// Fall back to reporting what we can from the provider
|
|
420
|
-
var result = new Dictionary<string, object>
|
|
421
|
-
{
|
|
422
|
-
["onlineState"] = Provider.onlineState.ToString(),
|
|
423
|
-
["plugin"] = Provider.GetActivePlugin()?.name ?? "unknown",
|
|
424
|
-
};
|
|
425
|
-
|
|
426
|
-
// Try running "cm find branches" via process if Plastic SCM is available
|
|
427
|
-
try
|
|
428
|
-
{
|
|
429
|
-
var psi = new System.Diagnostics.ProcessStartInfo
|
|
430
|
-
{
|
|
431
|
-
FileName = "cm",
|
|
432
|
-
Arguments = "find branches --format={name} --nototal",
|
|
433
|
-
RedirectStandardOutput = true,
|
|
434
|
-
RedirectStandardError = true,
|
|
435
|
-
UseShellExecute = false,
|
|
436
|
-
CreateNoWindow = true,
|
|
437
|
-
};
|
|
438
|
-
var proc = System.Diagnostics.Process.Start(psi);
|
|
439
|
-
var output = proc.StandardOutput.ReadToEnd();
|
|
440
|
-
proc.WaitForExit(10000);
|
|
441
|
-
|
|
442
|
-
var branches = output
|
|
443
|
-
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
|
444
|
-
.Select(b => b.Trim())
|
|
445
|
-
.Where(b => !string.IsNullOrEmpty(b))
|
|
446
|
-
.ToList();
|
|
447
|
-
|
|
448
|
-
result["branches"] = branches;
|
|
449
|
-
result["count"] = branches.Count;
|
|
450
|
-
}
|
|
451
|
-
catch
|
|
452
|
-
{
|
|
453
|
-
result["branches"] = new List<string>();
|
|
454
|
-
result["count"] = 0;
|
|
455
|
-
result["note"] = "Could not list branches. Ensure 'cm' CLI is available in PATH.";
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
// Try getting current branch
|
|
459
|
-
try
|
|
460
|
-
{
|
|
461
|
-
var psi = new System.Diagnostics.ProcessStartInfo
|
|
462
|
-
{
|
|
463
|
-
FileName = "cm",
|
|
464
|
-
Arguments = "status --header --machinereadable",
|
|
465
|
-
RedirectStandardOutput = true,
|
|
466
|
-
RedirectStandardError = true,
|
|
467
|
-
UseShellExecute = false,
|
|
468
|
-
CreateNoWindow = true,
|
|
469
|
-
};
|
|
470
|
-
var proc = System.Diagnostics.Process.Start(psi);
|
|
471
|
-
var output = proc.StandardOutput.ReadToEnd();
|
|
472
|
-
proc.WaitForExit(10000);
|
|
473
|
-
|
|
474
|
-
// First line usually contains the current changeset/branch info
|
|
475
|
-
result["currentInfo"] = output.Trim().Split('\n').FirstOrDefault() ?? "";
|
|
476
|
-
}
|
|
477
|
-
catch { /* cm not available */ }
|
|
478
|
-
|
|
479
|
-
return result;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
private static object HandleLock(string paramsJson)
|
|
483
|
-
{
|
|
484
|
-
EnsureVcsActive();
|
|
485
|
-
|
|
486
|
-
var paths = ParsePaths(paramsJson);
|
|
487
|
-
if (paths.Count == 0)
|
|
488
|
-
throw new ArgumentException("Provide 'path' or 'paths' to lock");
|
|
489
|
-
|
|
490
|
-
var assets = ToAssetList(paths);
|
|
491
|
-
var task = Provider.Checkout(assets, CheckoutMode.Exact);
|
|
492
|
-
bool ok = WaitForTask(task);
|
|
493
|
-
|
|
494
|
-
return new Dictionary<string, object>
|
|
495
|
-
{
|
|
496
|
-
["success"] = ok,
|
|
497
|
-
["count"] = assets.Count,
|
|
498
|
-
["paths"] = assets.Select(a => a.path).ToList(),
|
|
499
|
-
};
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
private static object HandleUnlock(string paramsJson)
|
|
503
|
-
{
|
|
504
|
-
EnsureVcsActive();
|
|
505
|
-
|
|
506
|
-
var paths = ParsePaths(paramsJson);
|
|
507
|
-
if (paths.Count == 0)
|
|
508
|
-
throw new ArgumentException("Provide 'path' or 'paths' to unlock");
|
|
509
|
-
|
|
510
|
-
var assets = ToAssetList(paths);
|
|
511
|
-
var task = Provider.Revert(assets, RevertMode.Normal);
|
|
512
|
-
bool ok = WaitForTask(task);
|
|
513
|
-
|
|
514
|
-
return new Dictionary<string, object>
|
|
515
|
-
{
|
|
516
|
-
["success"] = ok,
|
|
517
|
-
["count"] = assets.Count,
|
|
518
|
-
["paths"] = assets.Select(a => a.path).ToList(),
|
|
519
|
-
};
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
private static object HandleHistory(string paramsJson)
|
|
523
|
-
{
|
|
524
|
-
EnsureVcsActive();
|
|
525
|
-
|
|
526
|
-
var paths = ParsePaths(paramsJson);
|
|
527
|
-
if (paths.Count == 0)
|
|
528
|
-
paths = new List<string> { "Assets" };
|
|
529
|
-
|
|
530
|
-
// Try cm log for richer history
|
|
531
|
-
try
|
|
532
|
-
{
|
|
533
|
-
var cmPaths = string.Join(" ", paths.Select(p => $"\"{p}\""));
|
|
534
|
-
var psi = new System.Diagnostics.ProcessStartInfo
|
|
535
|
-
{
|
|
536
|
-
FileName = "cm",
|
|
537
|
-
Arguments = $"log --csformat=\"{{changesetid}}|{{date}}|{{owner}}|{{comment}}\" -n 20",
|
|
538
|
-
RedirectStandardOutput = true,
|
|
539
|
-
RedirectStandardError = true,
|
|
540
|
-
UseShellExecute = false,
|
|
541
|
-
CreateNoWindow = true,
|
|
542
|
-
};
|
|
543
|
-
var proc = System.Diagnostics.Process.Start(psi);
|
|
544
|
-
var output = proc.StandardOutput.ReadToEnd();
|
|
545
|
-
proc.WaitForExit(10000);
|
|
546
|
-
|
|
547
|
-
var entries = new List<object>();
|
|
548
|
-
foreach (var line in output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
|
|
549
|
-
{
|
|
550
|
-
var parts = line.Split('|');
|
|
551
|
-
if (parts.Length >= 4)
|
|
552
|
-
{
|
|
553
|
-
entries.Add(new Dictionary<string, object>
|
|
554
|
-
{
|
|
555
|
-
["changeset"] = parts[0].Trim(),
|
|
556
|
-
["date"] = parts[1].Trim(),
|
|
557
|
-
["author"] = parts[2].Trim(),
|
|
558
|
-
["comment"] = parts[3].Trim(),
|
|
559
|
-
});
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
return new Dictionary<string, object>
|
|
564
|
-
{
|
|
565
|
-
["count"] = entries.Count,
|
|
566
|
-
["entries"] = entries,
|
|
567
|
-
};
|
|
568
|
-
}
|
|
569
|
-
catch
|
|
570
|
-
{
|
|
571
|
-
// Fallback: no cm CLI available, try Provider API
|
|
572
|
-
throw new InvalidOperationException(
|
|
573
|
-
"History requires the 'cm' CLI. Ensure Plastic SCM / Unity VCS client is installed.");
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
private static object HandleResolve(string paramsJson)
|
|
578
|
-
{
|
|
579
|
-
EnsureVcsActive();
|
|
580
|
-
|
|
581
|
-
var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
|
|
582
|
-
var paths = ParsePaths(paramsJson);
|
|
583
|
-
|
|
584
|
-
if (paths.Count == 0)
|
|
585
|
-
throw new ArgumentException("Provide 'path' or 'paths' to resolve");
|
|
586
|
-
|
|
587
|
-
var resolveMethod = ResolveMethod.UseMerged;
|
|
588
|
-
if (p?.TryGetValue("method", out var methodObj) == true)
|
|
589
|
-
{
|
|
590
|
-
var m = methodObj?.ToString()?.ToLower();
|
|
591
|
-
resolveMethod = m switch
|
|
592
|
-
{
|
|
593
|
-
"mine" => ResolveMethod.UseMine,
|
|
594
|
-
"theirs" => ResolveMethod.UseTheirs,
|
|
595
|
-
_ => ResolveMethod.UseMerged,
|
|
596
|
-
};
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
var assets = ToAssetList(paths);
|
|
600
|
-
var task = Provider.Resolve(assets, resolveMethod);
|
|
601
|
-
bool ok = WaitForTask(task);
|
|
602
|
-
|
|
603
|
-
return new Dictionary<string, object>
|
|
604
|
-
{
|
|
605
|
-
["success"] = ok,
|
|
606
|
-
["count"] = assets.Count,
|
|
607
|
-
["paths"] = assets.Select(a => a.path).ToList(),
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
using System;
|
|
2
|
-
using System.Collections.Generic;
|
|
3
|
-
using UnityEngine;
|
|
4
|
-
|
|
5
|
-
namespace UCP.Bridge
|
|
6
|
-
{
|
|
7
|
-
/// <summary>
|
|
8
|
-
/// Routes JSON-RPC method names to handler functions.
|
|
9
|
-
/// </summary>
|
|
10
|
-
public class CommandRouter
|
|
11
|
-
{
|
|
12
|
-
public delegate object CommandHandler(string paramsJson);
|
|
13
|
-
|
|
14
|
-
private readonly Dictionary<string, CommandHandler> _handlers = new();
|
|
15
|
-
|
|
16
|
-
public void Register(string method, CommandHandler handler)
|
|
17
|
-
{
|
|
18
|
-
_handlers[method] = handler;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public JsonRpcResponse Dispatch(string method, long id, string paramsJson)
|
|
22
|
-
{
|
|
23
|
-
if (!_handlers.TryGetValue(method, out var handler))
|
|
24
|
-
{
|
|
25
|
-
return JsonRpcResponse.Error(id, ErrorCodes.MethodNotFound,
|
|
26
|
-
$"Method not found: {method}");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
try
|
|
30
|
-
{
|
|
31
|
-
var result = handler(paramsJson);
|
|
32
|
-
return JsonRpcResponse.Success(id, result);
|
|
33
|
-
}
|
|
34
|
-
catch (ArgumentException ex)
|
|
35
|
-
{
|
|
36
|
-
return JsonRpcResponse.Error(id, ErrorCodes.InvalidParams, ex.Message);
|
|
37
|
-
}
|
|
38
|
-
catch (UnauthorizedAccessException ex)
|
|
39
|
-
{
|
|
40
|
-
return JsonRpcResponse.Error(id, ErrorCodes.FileAccessDenied, ex.Message);
|
|
41
|
-
}
|
|
42
|
-
catch (Exception ex)
|
|
43
|
-
{
|
|
44
|
-
Debug.LogError($"[UCP] Error handling '{method}': {ex}");
|
|
45
|
-
return JsonRpcResponse.Error(id, ErrorCodes.InternalError, ex.Message);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public bool HasMethod(string method) => _handlers.ContainsKey(method);
|
|
50
|
-
|
|
51
|
-
public IEnumerable<string> RegisteredMethods => _handlers.Keys;
|
|
52
|
-
}
|
|
53
|
-
}
|