705 lines
21 KiB
TypeScript
Raw Normal View History

2019-03-15 10:08:39 +08:00
// eval 注入脚本的代码,变量尽量使用var,后来发现在import之后,let会自动变为var
2024-12-09 16:23:58 +08:00
import { uniq } from "lodash";
import { Msg, Page, PluginEvent } from "../../core/types";
import { ArrayData, BoolData, ColorData, DataType, EngineData, Group, ImageData, Info, InvalidData, NodeInfoData, NumberData, ObjectData, ObjectItemRequestData, Property, StringData, TreeData, Vec2Data, Vec3Data } from "../../views/devtools/data";
2024-12-09 16:23:58 +08:00
import { getValue, trySetValueWithConfig } from "./setValue";
import { BuildArrayOptions, BuildImageOptions, BuildObjectOptions, BuildVecOptions } from "./types";
2024-01-08 19:50:06 +08:00
import { isHasProperty } from "./util";
2024-12-24 21:09:13 +08:00
import { Terminal } from "../terminal";
2021-11-04 22:22:11 +08:00
2021-11-06 20:19:21 +08:00
declare const cc: any;
2021-04-22 19:09:35 +08:00
2021-04-26 22:27:47 +08:00
class CCInspector {
2024-01-08 19:50:06 +08:00
inspectorGameMemoryStorage: Record<string, any> = {};
2019-03-18 12:05:07 +08:00
2021-11-18 22:49:11 +08:00
private watchIsCocosGame() {
const timer = setInterval(() => {
2021-05-08 22:05:59 +08:00
if (this._isCocosGame()) {
2024-01-08 19:50:06 +08:00
clearInterval(timer);
2021-05-08 22:05:59 +08:00
// @ts-ignore
cc.director.on(cc.Director.EVENT_AFTER_SCENE_LAUNCH, () => {
2024-02-26 09:07:01 +08:00
const isCocosGame = this._isCocosGame();
2024-01-08 19:50:06 +08:00
this.notifySupportGame(isCocosGame);
});
2021-05-08 22:05:59 +08:00
}
2024-01-08 19:50:06 +08:00
}, 300);
2021-11-18 22:49:11 +08:00
}
private terminal = new Terminal('Inject ');
2021-11-18 22:49:11 +08:00
init() {
2024-12-24 21:09:13 +08:00
console.log(...this.terminal.init());
2021-11-18 22:49:11 +08:00
this.watchIsCocosGame();
2021-04-28 13:59:16 +08:00
window.addEventListener("message", (event) => {
// 接受来自content的事件有可能也会受到其他插件的
2021-04-26 22:27:47 +08:00
if (!event || !event.data) {
2024-01-08 19:50:06 +08:00
return;
2021-04-26 22:27:47 +08:00
}
let pluginEvent: PluginEvent = event.data;
2021-04-28 19:49:26 +08:00
if (PluginEvent.check(pluginEvent, Page.Content, Page.Inject)) {
2024-12-24 21:09:13 +08:00
console.log(...this.terminal.message(JSON.stringify(pluginEvent)));
2024-01-08 19:50:06 +08:00
PluginEvent.finish(pluginEvent);
2021-04-28 13:59:16 +08:00
switch (pluginEvent.msg) {
case Msg.Support: {
let isCocosGame = this._isCocosGame();
2024-01-08 19:50:06 +08:00
this.notifySupportGame(isCocosGame);
2021-04-28 13:59:16 +08:00
break;
}
case Msg.TreeInfo: {
2021-04-28 19:49:26 +08:00
this.updateTreeInfo();
2021-04-28 13:59:16 +08:00
break;
}
case Msg.NodeInfo: {
2021-04-28 19:49:26 +08:00
let nodeUUID = pluginEvent.data;
this.getNodeInfo(nodeUUID);
2021-04-28 13:59:16 +08:00
break;
}
case Msg.SetProperty: {
2021-05-08 17:52:29 +08:00
const data: Info = pluginEvent.data;
2021-06-14 18:46:45 +08:00
let value = data.data;
if (data.type === DataType.Color) {
// @ts-ignore
value = cc.color().fromHEX(value);
}
2021-11-09 15:24:10 +08:00
if (this.setValue(data.path, value)) {
this.sendMsgToContent(Msg.UpdateProperty, data);
} else {
2024-01-08 19:50:06 +08:00
console.warn(`设置失败:${data.path}`);
2021-11-09 15:24:10 +08:00
}
2021-05-08 17:52:29 +08:00
break;
2021-04-28 13:59:16 +08:00
}
2021-12-05 18:21:00 +08:00
case Msg.LogData: {
const data: string[] = pluginEvent.data;
const value = getValue(this.inspectorGameMemoryStorage, data);
2021-12-05 20:56:12 +08:00
// 直接写console.log会被tree shaking
const logFunction = console.log;
logFunction(value);
2021-12-05 18:21:00 +08:00
break;
}
2021-11-06 20:19:21 +08:00
case Msg.GetObjectItemData: {
const data: ObjectData = pluginEvent.data;
2021-11-09 15:24:10 +08:00
let val = getValue(this.inspectorGameMemoryStorage, data.path);
2021-11-06 20:19:21 +08:00
if (val) {
let itemData: Property[] = this._buildObjectItemData({
data: data,
path: data.path,
value: val,
filterKey: false,
});
let result: ObjectItemRequestData = {
id: data.id,
data: itemData,
2024-01-08 19:50:06 +08:00
};
2021-11-06 20:19:21 +08:00
this.sendMsgToContent(Msg.GetObjectItemData, result);
}
break;
}
2021-04-26 22:27:47 +08:00
}
2019-03-18 18:03:07 +08:00
}
2021-04-22 19:09:35 +08:00
});
}
2021-04-28 13:59:16 +08:00
sendMsgToContent(msg: Msg, data: any) {
// 发送给content.js处理也会导致发送给了自身死循环
2024-02-26 09:07:01 +08:00
window.postMessage(new PluginEvent(Page.Inject, Page.Content, msg, data), "*");
2021-04-28 13:59:16 +08:00
}
2021-04-28 19:49:26 +08:00
notifySupportGame(b: boolean) {
this.sendMsgToContent(Msg.Support, b);
2021-04-22 19:09:35 +08:00
}
2019-03-18 13:30:06 +08:00
updateTreeInfo() {
2021-04-22 19:09:35 +08:00
let isCocosCreatorGame = this._isCocosGame();
2019-03-18 12:05:07 +08:00
if (isCocosCreatorGame) {
2021-04-22 19:09:35 +08:00
//@ts-ignore
2019-03-18 12:05:07 +08:00
let scene = cc.director.getScene();
if (scene) {
2021-05-08 17:52:29 +08:00
let treeData = new TreeData();
2024-01-08 19:50:06 +08:00
this.getNodeChildren(scene, treeData);
2021-05-08 17:52:29 +08:00
this.sendMsgToContent(Msg.TreeInfo, treeData);
2019-03-18 12:05:07 +08:00
} else {
2024-01-08 19:50:06 +08:00
console.warn("can't execute api : cc.director.getScene");
2021-11-21 21:36:16 +08:00
this.notifySupportGame(false);
2019-03-18 12:05:07 +08:00
}
2021-04-28 19:49:26 +08:00
} else {
2024-01-08 19:50:06 +08:00
this.notifySupportGame(false);
2019-03-18 12:05:07 +08:00
}
2021-04-22 19:09:35 +08:00
}
2021-06-14 18:46:45 +08:00
// @ts-ignore
draw: cc.Graphics = null;
_drawRect(node: any) {
let draw = this.draw;
if (!draw) {
// @ts-ignore
let node = new cc.Node("draw-node");
2021-06-14 18:46:45 +08:00
// @ts-ignore
cc.director.getScene().addChild(node);
// @ts-ignore
draw = this.draw = node.addComponent(cc.Graphics);
}
2024-01-08 19:50:06 +08:00
draw.clear();
2021-06-14 18:46:45 +08:00
draw.lineWidth = 10;
// @ts-ignore
2024-01-08 19:50:06 +08:00
draw.strokeColor = new cc.Color().fromHEX("#ff0000");
const { anchorX, anchorY, width, height, x, y } = node;
2021-06-14 18:46:45 +08:00
let halfWidth = width / 2;
let halfHeight = height / 2;
2024-01-08 19:50:06 +08:00
let leftBottom = node.convertToWorldSpaceAR(cc.v2(-halfWidth, -halfHeight));
2021-06-14 18:46:45 +08:00
let leftTop = node.convertToWorldSpaceAR(cc.v2(-halfWidth, halfHeight));
let rightBottom = node.convertToWorldSpaceAR(cc.v2(halfWidth, -halfHeight));
let rightTop = node.convertToWorldSpaceAR(cc.v2(halfWidth, halfHeight));
function line(began: any, end: any) {
draw.moveTo(began.x, began.y);
draw.lineTo(end.x, end.y);
}
2024-01-08 19:50:06 +08:00
line(leftBottom, rightBottom);
line(rightBottom, rightTop);
line(rightTop, leftTop);
line(leftTop, leftBottom);
2021-06-14 18:46:45 +08:00
this.draw.stroke();
}
2021-04-05 19:31:34 +08:00
// 收集节点信息
2021-05-08 17:52:29 +08:00
getNodeChildren(node: any, data: TreeData) {
data.id = node.uuid;
data.text = node.name;
2021-05-11 22:15:29 +08:00
// @ts-ignore
if (node instanceof cc.Scene) {
// 场景不允许获取active引擎会报错
} else {
data.active = !!node.active;
}
2021-04-05 19:31:34 +08:00
this.inspectorGameMemoryStorage[node.uuid] = node;
2021-11-07 18:31:49 +08:00
let nodeChildren = node.children;
2021-04-05 19:31:34 +08:00
for (let i = 0; i < nodeChildren.length; i++) {
let childItem = nodeChildren[i];
2021-05-08 17:52:29 +08:00
let treeData = new TreeData();
this.getNodeChildren(childItem, treeData);
2024-01-08 19:50:06 +08:00
data.children.push(treeData);
2021-04-05 19:31:34 +08:00
}
2021-04-22 19:09:35 +08:00
}
_isCocosGame() {
// @ts-ignore 检测是否包含cc变量
return typeof cc !== "undefined";
}
2021-11-07 23:03:06 +08:00
getAllPropertyDescriptors(obj: Object): string[] {
let keys: string[] = [];
function circle(root: Object) {
const descriptors = Object.getOwnPropertyDescriptors(root);
for (let descriptorsKey in descriptors) {
if (Object.hasOwnProperty.call(descriptors, descriptorsKey)) {
const value = descriptors[descriptorsKey];
// 不可枚举的属性并且允许修改get set的才有效
if (!value.enumerable && value.configurable) {
keys.push(descriptorsKey);
}
}
}
const proto = Object.getPrototypeOf(root);
if (proto) {
2024-01-08 19:50:06 +08:00
circle(proto);
2021-11-07 23:03:06 +08:00
}
}
2024-01-08 19:50:06 +08:00
circle(obj);
2021-11-07 23:03:06 +08:00
return keys;
}
2021-04-22 19:09:35 +08:00
_getNodeKeys(node: any) {
2021-11-07 23:03:06 +08:00
// 3.x变成了getter
2021-04-07 17:26:16 +08:00
let excludeProperty = [
2024-01-08 19:50:06 +08:00
"children",
"quat",
"node",
"components",
"parent",
2021-04-07 17:26:16 +08:00
// 生命周期函数
2024-01-08 19:50:06 +08:00
"onFocusInEditor",
"onRestore",
"start",
"lateUpdate",
"update",
"resetInEditor",
"onLostFocusInEditor",
"onEnable",
"onDisable",
"onDestroy",
"onLoad",
2021-04-07 17:26:16 +08:00
];
2021-11-07 23:03:06 +08:00
const keyHidden = this.getAllPropertyDescriptors(node);
const keyVisible1 = Object.keys(node); // Object不走原型链
let keyVisible2: string[] = [];
2024-01-08 19:50:06 +08:00
for (let nodeKey in node) {
// 走原型链
keyVisible2.push(nodeKey);
2021-04-05 18:38:44 +08:00
}
2024-01-08 19:50:06 +08:00
let allKeys: string[] = uniq(
keyHidden.concat(keyVisible1, keyVisible2)
).sort();
allKeys = allKeys.filter((key) => {
2021-11-07 23:03:06 +08:00
return !key.startsWith("_") && !excludeProperty.includes(key);
});
2024-01-08 19:50:06 +08:00
allKeys = allKeys.filter((key) => {
2021-11-07 23:03:06 +08:00
try {
2024-01-08 19:50:06 +08:00
return typeof node[key] !== "function";
2021-11-07 23:03:06 +08:00
} catch (e) {
// console.warn(`属性${key}出现异常:\n`, e);
return false;
}
2024-01-08 19:50:06 +08:00
});
2021-11-07 23:03:06 +08:00
return allKeys;
2021-04-22 19:09:35 +08:00
}
2024-01-08 19:50:06 +08:00
_getPairProperty(key: string): null | { key: string; values: string[] } {
2021-04-22 19:09:35 +08:00
let pairProperty: Record<string, any> = {
2021-04-05 18:38:44 +08:00
rotation: ["rotationX", "rotationY"],
anchor: ["anchorX", "anchorY"],
size: ["width", "height"],
skew: ["skewX", "skewY"],
2021-11-10 22:04:51 +08:00
position: ["x", "y", "z"], // position比较特殊过来的key就是position也需要能处理
2021-04-05 18:38:44 +08:00
scale: ["scaleX", "scaleY", "scaleZ"],
};
2021-11-10 22:04:51 +08:00
for (let pairPropertyKey in pairProperty) {
if (pairProperty.hasOwnProperty(pairPropertyKey)) {
let pair = pairProperty[pairPropertyKey];
if (pair.includes(key) || key === pairPropertyKey) {
2024-01-08 19:50:06 +08:00
return { key: pairPropertyKey, values: pair };
2021-04-22 19:09:35 +08:00
}
2021-04-05 18:38:44 +08:00
}
}
return null;
2021-04-22 19:09:35 +08:00
}
2021-11-04 22:22:11 +08:00
_buildVecData(options: BuildVecOptions) {
2021-06-14 18:46:45 +08:00
const ctor: Function = options.ctor;
const keys: Array<string> = options.keys;
const value: Object = options.value;
const data: Vec3Data | Vec2Data = options.data;
const path: Array<string> = options.path;
if (ctor && value instanceof ctor) {
2024-01-08 19:50:06 +08:00
let hasUnOwnProperty = keys.find((key) => !value.hasOwnProperty(key));
2021-06-14 18:46:45 +08:00
if (!hasUnOwnProperty) {
for (let key in keys) {
let propName = keys[key];
if (value.hasOwnProperty(propName)) {
let propPath = path.concat(propName);
2024-01-08 19:50:06 +08:00
let itemData = this._genInfoData(value, propName, propPath);
2021-06-14 18:46:45 +08:00
if (itemData) {
2024-01-08 19:50:06 +08:00
data.add(new Property(propName, itemData));
2021-06-14 18:46:45 +08:00
}
}
}
return data;
}
}
return null;
}
2021-11-04 22:22:11 +08:00
_buildImageData(options: BuildImageOptions) {
2021-06-14 19:41:58 +08:00
const ctor: Function = options.ctor;
const value: Object = options.value;
const data: ImageData = options.data;
const path: Array<string> = options.path;
if (ctor && value instanceof ctor) {
2021-11-07 18:31:49 +08:00
data.path = path;
2021-11-09 15:24:10 +08:00
// 2.4.6 没有了这个属性
if (value.hasOwnProperty("_textureFilename")) {
2021-06-14 19:41:58 +08:00
//@ts-ignore
data.data = `${window.location.origin}/${value._textureFilename}`;
2021-11-07 18:31:49 +08:00
} else {
data.data = null;
2021-06-14 19:41:58 +08:00
}
2021-11-07 18:31:49 +08:00
return data;
2021-06-14 19:41:58 +08:00
}
return null;
}
2024-01-08 19:50:06 +08:00
_genInfoData(
node: any,
key: string | number,
path: Array<string>,
filterKey = true
): Info | null {
2021-05-08 20:36:32 +08:00
let propertyValue = node[key];
2021-04-05 18:38:44 +08:00
let info = null;
2021-11-07 00:09:02 +08:00
let invalidType = this._isInvalidValue(propertyValue);
if (invalidType) {
info = new InvalidData(invalidType);
} else {
switch (typeof propertyValue) {
case "boolean":
info = new BoolData(propertyValue);
break;
case "number":
info = new NumberData(propertyValue);
break;
case "string":
info = new StringData(propertyValue);
break;
default:
2021-04-22 19:09:35 +08:00
//@ts-ignore
2021-11-07 00:09:02 +08:00
if (propertyValue instanceof cc.Color) {
let hex = propertyValue.toHEX();
info = new ColorData(`#${hex}`);
} else if (Array.isArray(propertyValue)) {
let keys: number[] = [];
for (let i = 0; i < propertyValue.length; i++) {
keys.push(i);
}
info = this._buildArrayData({
data: new ArrayData(),
path: path,
value: propertyValue,
keys: keys,
2024-01-08 19:50:06 +08:00
});
2021-11-07 00:09:02 +08:00
} else {
2024-01-08 19:50:06 +08:00
!info &&
(info = this._buildVecData({
// @ts-ignore
ctor: cc.Vec3,
path: path,
data: new Vec3Data(),
keys: ["x", "y", "z"],
value: propertyValue,
}));
!info &&
(info = this._buildVecData({
// @ts-ignore
ctor: cc.Vec2,
path: path,
data: new Vec2Data(),
keys: ["x", "y"],
value: propertyValue,
}));
!info &&
(info = this._buildImageData({
//@ts-ignore
ctor: cc.SpriteFrame,
data: new ImageData(),
path: path,
value: propertyValue,
}));
2021-11-07 00:09:02 +08:00
if (!info) {
if (typeof propertyValue === "object") {
2021-11-07 12:14:50 +08:00
let ctorName = propertyValue.constructor?.name;
if (ctorName) {
2024-01-08 19:50:06 +08:00
if (
ctorName.startsWith("cc_") ||
2021-11-07 18:31:49 +08:00
// 2.4.0
2024-01-08 19:50:06 +08:00
ctorName === "CCClass"
) {
2021-11-07 12:14:50 +08:00
info = new EngineData();
info.engineType = ctorName;
info.engineName = propertyValue.name;
info.engineUUID = propertyValue.uuid;
}
2021-11-07 18:31:49 +08:00
}
if (!info) {
2021-11-07 12:14:50 +08:00
// 空{}
2021-11-07 18:31:49 +08:00
// MaterialVariant 2.4.0
2021-11-07 00:09:02 +08:00
info = this._buildObjectData({
data: new ObjectData(),
path: path,
value: propertyValue,
filterKey: filterKey,
2024-01-08 19:50:06 +08:00
});
2021-11-07 00:09:02 +08:00
}
2021-06-19 19:51:05 +08:00
}
}
}
2021-11-07 00:09:02 +08:00
break;
}
2021-04-05 18:38:44 +08:00
}
2021-04-07 17:26:16 +08:00
if (info) {
2024-01-08 19:50:06 +08:00
info.readonly = this._isReadonly(node, key);
2021-04-07 17:26:16 +08:00
info.path = path;
} else {
2021-04-05 18:38:44 +08:00
console.error(`暂不支持的属性值`, propertyValue);
}
return info;
2021-04-22 19:09:35 +08:00
}
2024-01-08 19:50:06 +08:00
_buildArrayData({ value, path, data, keys }: BuildArrayOptions) {
keys = keys.filter((key) => !key.toString().startsWith("_"));
2021-11-06 20:19:21 +08:00
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let propPath = path.concat(key.toString());
let itemData = this._genInfoData(value, key, propPath);
if (itemData) {
2024-01-08 19:50:06 +08:00
data.add(new Property(key.toString(), itemData));
2021-11-06 20:19:21 +08:00
}
}
return data;
2021-11-04 22:22:11 +08:00
}
2024-01-08 19:50:06 +08:00
_buildObjectItemData({
value,
path,
data,
filterKey,
}: BuildObjectOptions): Property[] {
2021-11-06 20:19:21 +08:00
let keys = Object.keys(value);
if (filterKey) {
2024-01-08 19:50:06 +08:00
keys = this.filterKeys(keys); // 不再进行开发者定义的数据
2021-11-06 20:19:21 +08:00
}
2024-01-08 19:50:06 +08:00
let ret: Property[] = [];
2021-11-06 20:19:21 +08:00
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let propPath = path.concat(key.toString());
let itemData = this._genInfoData(value, key, propPath, filterKey);
if (itemData) {
2024-01-08 19:50:06 +08:00
ret.push(new Property(key, itemData));
2021-11-06 20:19:21 +08:00
}
}
return ret;
2021-11-04 22:22:11 +08:00
}
2021-11-06 20:19:21 +08:00
filterKeys(keys: string[]) {
2021-07-16 16:36:00 +08:00
// 剔除_开头的属性
2024-01-08 19:50:06 +08:00
return keys.filter((key) => !key.toString().startsWith("_"));
2021-11-06 20:19:21 +08:00
}
2021-11-06 21:42:37 +08:00
_isInvalidValue(value: any) {
2021-11-07 00:09:02 +08:00
// !!Infinity=true
2024-01-08 19:50:06 +08:00
if (
(value && value !== Infinity) ||
value === 0 ||
value === false ||
value === ""
) {
2021-11-07 00:09:02 +08:00
return false;
}
if (value === null) {
2024-01-08 19:50:06 +08:00
return "null";
2021-11-07 00:09:02 +08:00
} else if (value === Infinity) {
2024-01-08 19:50:06 +08:00
return "Infinity";
2021-11-07 00:09:02 +08:00
} else if (value === undefined) {
2024-01-08 19:50:06 +08:00
return "undefined";
2021-11-07 00:09:02 +08:00
} else if (Number.isNaN(value)) {
return "NaN";
} else {
2024-01-08 19:50:06 +08:00
debugger;
2021-11-07 00:09:02 +08:00
return false;
}
2021-11-06 21:42:37 +08:00
}
2024-01-08 19:50:06 +08:00
_buildObjectData({ value, path, data, filterKey }: BuildObjectOptions) {
2021-11-06 20:19:21 +08:00
let keys = Object.keys(value);
if (filterKey) {
2024-01-08 19:50:06 +08:00
keys = this.filterKeys(keys);
2021-11-06 20:19:21 +08:00
}
// 只返回一级key更深层级的key需要的时候再获取防止circle object导致的死循环
let desc: Record<string, any> = {};
2021-06-17 22:35:37 +08:00
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let propPath = path.concat(key.toString());
2021-11-06 20:19:21 +08:00
let propValue = (value as any)[key];
let keyDesc = "";
if (Array.isArray(propValue)) {
// 只收集一级key
2024-02-26 09:07:01 +08:00
propValue.forEach((item) => { });
2024-01-08 19:50:06 +08:00
keyDesc = `(${propValue.length}) [...]`;
} else if (this._isInvalidValue(propValue)) {
// 不能改变顺序
2021-11-06 21:42:37 +08:00
keyDesc = propValue;
2021-11-06 20:19:21 +08:00
} else if (typeof propValue === "object") {
keyDesc = `${propValue.constructor.name} {...}`;
} else {
keyDesc = propValue;
2021-06-17 22:35:37 +08:00
}
2021-11-06 20:19:21 +08:00
desc[key] = keyDesc;
2021-06-17 22:35:37 +08:00
}
2021-11-06 20:19:21 +08:00
data.data = JSON.stringify(desc);
2021-06-17 22:35:37 +08:00
return data;
}
private getCompName(comp: any): string {
const nameKeys = [
"__classname__", // 2.4.0 验证通过
];
for (let i = 0; i < nameKeys.length; i++) {
let key = nameKeys[i];
// 一般来说这里的name是不会出现假值
if (comp[key]) {
return comp[key];
}
}
return comp.constructor.name;
}
2021-11-12 21:20:57 +08:00
// 校验keys的有效性3.x有position没有x,y,z
_checkKeysValid(obj: any, keys: string[]) {
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (!isHasProperty(obj, key)) {
return false;
}
}
return true;
}
2021-04-22 19:09:35 +08:00
_getGroupData(node: any) {
const name = this.getCompName(node);
2021-12-05 18:21:00 +08:00
let nodeGroup = new Group(name, node.uuid);
2021-04-05 19:31:34 +08:00
let keys = this._getNodeKeys(node);
2024-02-26 09:07:01 +08:00
for (let i = 0; i < keys.length;) {
2021-04-05 19:31:34 +08:00
let key = keys[i];
let pair = this._getPairProperty(key);
2021-11-12 21:20:57 +08:00
if (pair && this._checkKeysValid(node, pair.values)) {
2021-05-08 18:44:10 +08:00
let bSplice = false;
2021-04-05 19:31:34 +08:00
// 把这个成对的属性剔除掉
2021-04-22 19:09:35 +08:00
pair.values.forEach((item: string) => {
2024-01-08 19:50:06 +08:00
let index = keys.findIndex((el) => el === item);
2021-04-05 19:31:34 +08:00
if (index !== -1) {
keys.splice(index, 1);
2021-11-10 22:04:51 +08:00
if (pair && item === pair.key) {
// 切掉了自己,才能步进+1
bSplice = true;
}
2021-04-05 19:31:34 +08:00
}
});
// 序列化成对的属性
2021-04-22 19:09:35 +08:00
let info: Vec2Data | Vec3Data | null = null;
2021-04-05 19:31:34 +08:00
let pairValues = pair.values;
if (pairValues.length === 2) {
info = new Vec2Data();
} else if (pairValues.length === 3) {
info = new Vec3Data();
}
2021-11-12 00:02:58 +08:00
// todo path
2021-04-22 19:09:35 +08:00
pairValues.forEach((el: string) => {
2021-11-12 21:20:57 +08:00
let propertyPath = [node.uuid, el];
let vecData = this._genInfoData(node, el, propertyPath);
if (vecData) {
info && info.add(new Property(el, vecData));
2021-04-05 19:31:34 +08:00
}
});
if (info) {
let property = new Property(pair.key, info);
nodeGroup.addProperty(property);
}
2021-05-08 18:44:10 +08:00
if (!bSplice) {
i++;
}
2021-04-05 19:31:34 +08:00
} else {
2021-04-07 17:26:16 +08:00
let propertyPath = [node.uuid, key];
2021-05-08 20:36:32 +08:00
let info = this._genInfoData(node, key, propertyPath);
2021-04-05 19:31:34 +08:00
if (info) {
nodeGroup.addProperty(new Property(key, info));
}
2021-05-08 18:44:10 +08:00
i++;
2021-04-05 19:31:34 +08:00
}
}
2021-05-08 18:44:10 +08:00
nodeGroup.sort();
2021-04-05 19:31:34 +08:00
return nodeGroup;
2021-04-22 19:09:35 +08:00
}
2021-11-04 22:22:11 +08:00
// 获取节点信息只获取一级key即可后续
2021-04-22 19:09:35 +08:00
getNodeInfo(uuid: string) {
2019-03-18 13:30:06 +08:00
let node = this.inspectorGameMemoryStorage[uuid];
2019-03-15 10:08:39 +08:00
if (node) {
2021-04-05 19:31:34 +08:00
let groupData = [];
// 收集节点信息
let nodeGroup = this._getGroupData(node);
groupData.push(nodeGroup);
// 收集组件信息
2021-11-20 21:57:54 +08:00
const nodeComp = node._components;
2021-04-05 19:31:34 +08:00
for (let i = 0; i < nodeComp.length; i++) {
let itemComp = nodeComp[i];
this.inspectorGameMemoryStorage[itemComp.uuid] = itemComp;
let compGroup = this._getGroupData(itemComp);
groupData.push(compGroup);
2021-04-05 18:38:44 +08:00
}
const data: NodeInfoData = new NodeInfoData(uuid, groupData);
2021-11-20 21:57:54 +08:00
this.sendMsgToContent(Msg.NodeInfo, data);
2019-03-15 10:08:39 +08:00
} else {
// 未获取到节点数据
console.log("未获取到节点数据");
}
2021-04-22 19:09:35 +08:00
}
logValue(uuid: string, key: string) {
2021-04-07 17:26:16 +08:00
let nodeOrComp = this.inspectorGameMemoryStorage[uuid];
if (nodeOrComp) {
console.log(nodeOrComp[key]);
}
2021-04-22 19:09:35 +08:00
}
2021-11-04 22:22:11 +08:00
_isReadonly(base: Object, key: string | number): boolean {
2024-01-08 19:50:06 +08:00
let ret = Object.getOwnPropertyDescriptor(base, key);
if (ret) {
return !(ret.set || ret.writable);
2021-05-08 20:36:32 +08:00
} else {
let proto = Object.getPrototypeOf(base);
2021-11-09 15:24:10 +08:00
if (proto) {
2024-01-08 19:50:06 +08:00
return this._isReadonly(proto, key);
2021-11-09 15:24:10 +08:00
} else {
return false;
}
2021-05-08 20:36:32 +08:00
}
}
2021-11-09 15:24:10 +08:00
setValue(pathArray: Array<string>, value: string): boolean {
let target = this.inspectorGameMemoryStorage;
2021-11-09 15:24:10 +08:00
// 尝试设置creator3.x的数据
if (trySetValueWithConfig(pathArray, target, value)) {
return true;
}
for (let i = 0; i < pathArray.length; i++) {
let path = pathArray[i];
if (i === pathArray.length - 1) {
// 到最后的key了
if (this._isReadonly(target, path)) {
console.warn(`值不允许修改`);
} else {
target[path] = value;
2021-11-09 15:24:10 +08:00
return true;
}
2021-05-08 20:36:32 +08:00
} else {
2021-11-09 15:24:10 +08:00
// creator3.x的enumerable导致无法判断
if (target.hasOwnProperty(path) || target[path]) {
target = target[path];
2021-11-09 15:24:10 +08:00
} else {
return false;
}
2021-05-08 17:52:29 +08:00
}
2021-04-07 17:26:16 +08:00
}
2021-11-09 15:24:10 +08:00
return false;
2021-11-06 20:19:21 +08:00
}
2019-03-18 18:03:07 +08:00
onMemoryInfo() {
2024-01-08 19:50:06 +08:00
const memory = console["memory"];
2021-04-28 13:59:16 +08:00
this.sendMsgToContent(Msg.MemoryInfo, {
2019-03-18 18:03:07 +08:00
performance: {
2021-04-22 19:09:35 +08:00
// @ts-ignore
2019-03-18 18:03:07 +08:00
jsHeapSizeLimit: window.performance.memory.jsHeapSizeLimit,
2021-04-22 19:09:35 +08:00
// @ts-ignore
2019-03-18 18:03:07 +08:00
totalJSHeapSize: window.performance.memory.totalJSHeapSize,
2021-04-22 19:09:35 +08:00
// @ts-ignore
2019-03-18 18:03:07 +08:00
usedJSHeapSize: window.performance.memory.usedJSHeapSize,
},
2024-01-08 19:50:06 +08:00
2019-03-18 18:03:07 +08:00
console: {
2024-01-08 19:50:06 +08:00
jsHeapSizeLimit: memory.jsHeapSizeLimit,
totalJSHeapSize: memory.totalJSHeapSize,
usedJSHeapSize: memory.usedJSHeapSize,
2019-03-18 18:03:07 +08:00
},
});
}
2021-04-22 19:09:35 +08:00
}
2024-02-26 09:07:01 +08:00
const inspector = new CCInspector();
2021-04-22 19:09:35 +08:00
inspector.init();
2021-04-26 22:27:47 +08:00
//@ts-ignore
2021-04-22 19:09:35 +08:00
window.CCInspector = inspector;