优化输出日志的颜色

This commit is contained in:
xu_yanfeng 2024-12-24 21:09:13 +08:00
parent d62cc0a26c
commit 27f4884216
13 changed files with 199 additions and 181 deletions

View File

@ -1,18 +1,3 @@
export function injectScript(url: string) {
if (chrome && chrome.runtime && chrome.runtime.getURL) {
let content = chrome.runtime.getURL(url)
const script = document.createElement("script")
script.setAttribute("type", "text/javascript")
script.setAttribute("src", content)
script.onload = function () {
document.head.removeChild(script);
}
document.head.appendChild(script)
console.log(`inject script success: ${content}`);
} else {
console.log("inject script failed")
}
}
interface LogOptions { interface LogOptions {
data: any; data: any;

View File

@ -20,19 +20,20 @@ export abstract class PortMan {
public onDisconnect: (port: chrome.runtime.Port) => void | null = null; public onDisconnect: (port: chrome.runtime.Port) => void | null = null;
public onMessage: (data: PluginEvent) => void | null = null; public onMessage: (data: PluginEvent) => void | null = null;
public terminal: Terminal = null; public terminal: Terminal = null;
public timestamp: number = 0;
constructor(tab: chrome.tabs.Tab, port: chrome.runtime.Port) { constructor(tab: chrome.tabs.Tab, port: chrome.runtime.Port) {
this.timestamp = Date.now();
this.port = port; this.port = port;
this.tab = tab; this.tab = tab;
this.name = port.name; this.name = port.name;
this.id = tab.id; this.id = tab.id;
this.url = tab.url; this.url = tab.url;
this.title = tab.title; this.title = tab.title;
this.terminal = new Terminal(`Port-${this.name}/ID-${this.id}`); this.terminal = new Terminal(`Port-${this.name}`);
port.onMessage.addListener((data: any, sender: any) => { port.onMessage.addListener((data: any, port: chrome.runtime.Port) => {
const str = `${sender.name}\n${JSON.stringify(data)}` console.log(... this.terminal.message(JSON.stringify(data)));
console.log(... this.terminal.green(str));
// 如果多个页面都监听 onMessage 事件,对于某一次事件只有第一次调用 sendResponse() 能成功发出回应,所有其他回应将被忽略。 // 如果多个页面都监听 onMessage 事件,对于某一次事件只有第一次调用 sendResponse() 能成功发出回应,所有其他回应将被忽略。
// sender.postMessage(data); // port.postMessage(data);
const cls = PluginEvent.create(data); const cls = PluginEvent.create(data);
if (this.onMessage) { if (this.onMessage) {
this.onMessage(cls); this.onMessage(cls);

View File

@ -70,7 +70,7 @@ export class PortMgr {
id: port.id, id: port.id,
url: port.url url: port.url
}); });
str.push(`[${i + 1}] name:${port.name}, id:${port.id}, url:${port.url}`); str.push(`[${i + 1}] time:${new Date(port.timestamp).toLocaleString()}, name:${port.name}, id:${port.id}, url:${port.url}`);
} }
if (arr.length) { if (arr.length) {
@ -92,9 +92,11 @@ export class PortMgr {
this.getCurrentUseContent()?.postMessage(data); this.getCurrentUseContent()?.postMessage(data);
} }
sendDevtoolMsg(data: PluginEvent) { sendDevtoolMsg(data: PluginEvent) {
const portMan = this.portArray.find(el => el.isDevtoolsPort()); const portManArray = this.portArray.filter(el => el.isDevtoolsPort());
if (portMan) { if (portManArray.length) {
portMan.port.postMessage(data); portManArray.forEach(portMan => {
portMan.port.postMessage(data);
})
} else { } else {
console.log('not find devtools port'); console.log('not find devtools port');
} }

View File

@ -2,61 +2,67 @@
// 但是不共享js,要想访问页面js,只能通过注入的方式 // 但是不共享js,要想访问页面js,只能通过注入的方式
import { ChromeConst } from "cc-plugin/src/chrome/const"; import { ChromeConst } from "cc-plugin/src/chrome/const";
import { Msg, Page, PluginEvent } from "../core/types"; import { Msg, Page, PluginEvent } from "../core/types";
import { injectScript } from "../core/util"; import { Terminal } from "./terminal";
injectScript(ChromeConst.script.inject);
class Content { export function injectScript(url: string) {
private connect: chrome.runtime.Port | null = null; if (chrome && chrome.runtime && chrome.runtime.getURL) {
let content = chrome.runtime.getURL(url)
constructor() { const script = document.createElement("script")
console.log("init content"); script.setAttribute("type", "text/javascript")
// 接受来自inject.js的消息数据,然后中转到background.js script.setAttribute("src", content)
window.addEventListener("message", (event) => { script.onload = function () {
let data: PluginEvent = event.data; document.head.removeChild(script);
if (PluginEvent.check(data, Page.Inject, Page.Content)) {
console.log("[Window-Message]: ", data);
PluginEvent.reset(data, Page.Content, Page.Devtools)
this.connect?.postMessage(data)
}
}, false);
}
// 和background.js保持长连接通讯background和content的交互也要通过这个链接进行通讯
private connectToBackground() {
this.connect = chrome.runtime.connect({ name: Page.Content })
this.connect.onMessage.addListener((data: PluginEvent, sender) => {
if (PluginEvent.check(data, Page.Background, Page.Content)) {
// console.log(`%c[Connect-Message] ${JSON.stringify(data)}`, "color:green;")
console.log("[Connect-Message]: ", data);
PluginEvent.reset(data, Page.Content, Page.Inject)
window.postMessage(data, "*");
}
})
}
private sendMessageToBackground(data: PluginEvent) {
if (this.connect) {
this.connect.postMessage(data);
}
}
run() {
this.connectToBackground();
this.checkGame();
}
private checkGame() {
let gameCanvas = document.querySelector("#GameCanvas");
if (!gameCanvas) {
let sendData = new PluginEvent(Page.Content, Page.Devtools, Msg.Support, {
support: false,
msg: "未发现GameCanvas,不支持调试游戏!"
})
this.sendMessageToBackground(sendData)
} }
document.head.appendChild(script)
console.log(...terminal.green(`inject script success: ${content}`));
} else {
console.log(...terminal.red("inject script failed"));
} }
} }
const terminal = new Terminal(Page.Content);
console.log(...terminal.init());
// 和background.js保持长连接通讯background和content的交互也要通过这个链接进行通讯
let connect: chrome.runtime.Port | null = chrome.runtime.connect({ name: Page.Content })
connect.onDisconnect.addListener(() => {
console.log(...terminal.disconnect(""));
connect = null
})
connect.onMessage.addListener((data: PluginEvent, sender: chrome.runtime.Port) => {
if (PluginEvent.check(data, Page.Background, Page.Content)) {
console.log(...terminal.message(JSON.stringify(data)));
PluginEvent.reset(data, Page.Content, Page.Inject)
window.postMessage(data, "*");
}
})
// 接受来自inject.js的消息数据,然后中转到background.js
window.addEventListener("message", (event) => {
let data: PluginEvent = event.data;
if (PluginEvent.check(data, Page.Inject, Page.Content)) {
console.log(...terminal.message(JSON.stringify(data)));
PluginEvent.reset(data, Page.Content, Page.Devtools)
if (connect) {
connect.postMessage(data)
} else {
console.log(...terminal.log(`connect is null`));
debugger;
}
}
}, false);
const content = new Content(); function checkGame() {
content.run(); let gameCanvas = document.querySelector("#GameCanvas");
const sendData = new PluginEvent(Page.Content, Page.Devtools, Msg.Support, {
support: !!gameCanvas,
msg: "未发现GameCanvas,不支持调试游戏!"
})
if (connect) {
connect.postMessage(sendData)
} else {
console.log(...terminal.log(`connect is null`));
debugger;
}
}
injectScript(ChromeConst.script.inject);
checkGame();

View File

@ -5,6 +5,7 @@ import { ArrayData, BoolData, ColorData, DataType, EngineData, Group, ImageData,
import { getValue, trySetValueWithConfig } from "./setValue"; import { getValue, trySetValueWithConfig } from "./setValue";
import { BuildArrayOptions, BuildImageOptions, BuildObjectOptions, BuildVecOptions } from "./types"; import { BuildArrayOptions, BuildImageOptions, BuildObjectOptions, BuildVecOptions } from "./types";
import { isHasProperty } from "./util"; import { isHasProperty } from "./util";
import { Terminal } from "../terminal";
declare const cc: any; declare const cc: any;
@ -23,9 +24,9 @@ class CCInspector {
} }
}, 300); }, 300);
} }
private terminal = new Terminal('Inject', 'blue', 'gray');
init() { init() {
console.log("cc-inspector init ~~~"); console.log(...this.terminal.init());
this.watchIsCocosGame(); this.watchIsCocosGame();
window.addEventListener("message", (event) => { window.addEventListener("message", (event) => {
// 接受来自content的事件有可能也会受到其他插件的 // 接受来自content的事件有可能也会受到其他插件的
@ -34,10 +35,7 @@ class CCInspector {
} }
let pluginEvent: PluginEvent = event.data; let pluginEvent: PluginEvent = event.data;
if (PluginEvent.check(pluginEvent, Page.Content, Page.Inject)) { if (PluginEvent.check(pluginEvent, Page.Content, Page.Inject)) {
console.log( console.log(...this.terminal.message(JSON.stringify(pluginEvent)));
`%c[Inject] ${JSON.stringify(pluginEvent)}`,
"color:green;"
);
PluginEvent.finish(pluginEvent); PluginEvent.finish(pluginEvent);
switch (pluginEvent.msg) { switch (pluginEvent.msg) {
case Msg.Support: { case Msg.Support: {

View File

@ -1,36 +1,54 @@
export class Terminal { export class Terminal {
color = 'red'; /**
background = 'yellow'; *
*/
tag = 'terminal'; tag = 'terminal';
constructor(tag: string, color: string = 'red', background: string = 'yellow') { /**
this.color = color; *
this.background = background; */
tagColor = 'red';
/**
*
*/
tagBackground = 'yellow';
/**
*
*/
txtColor = 'black';
constructor(tag: string, tagColor: string = 'red', tagBackground: string = 'yellow') {
this.tagColor = tagColor;
this.tagBackground = tagBackground;
this.tag = tag; this.tag = tag;
} }
init(): string[] { init(): string[] {
return this.log(`init`); return this.log(`init`);
} }
public log(message: string, newline: boolean = false): string[] { public log(message: string, newline: boolean = false): string[] {
return [`%c${this.tag}%c${newline ? '\n' : ''}${message}`, `color:${this.color};background:${this.background};padding:0 4px`, "color:black;margin-left:5px"]; return [`%c${this.tag}%c${newline ? '\n' : ''}${message}`, `color:${this.tagColor};background:${this.tagBackground};padding:0 4px`, `color:${this.txtColor};margin-left:5px`];
} }
public blue(message: string): string[] { public blue(message: string): string[] {
this.color = 'blue'; this.txtColor = 'blue';
return this.log(message); return this.log(message);
} }
public green(message: string): string[] { public green(message: string): string[] {
this.color = 'green'; this.txtColor = 'green';
return this.log(message); return this.log(message);
} }
public red(message: string): string[] { public red(message: string): string[] {
this.color = 'red'; this.txtColor = 'red';
return this.log(message); return this.log(message);
} }
message(msg: string): string[] {
this.txtColor = 'black';
return this.log(`[message] ${msg}`);
}
connect(msg: string): string[] { connect(msg: string): string[] {
this.txtColor = 'black';
return this.log(`[connect] ${msg}`); return this.log(`[connect] ${msg}`);
} }
disconnect(msg: string): string[] { disconnect(msg: string): string[] {
this.txtColor = 'black';
return this.log(`[disconnect] ${msg}`); return this.log(`[disconnect] ${msg}`);
} }
} }

View File

@ -0,0 +1,69 @@
import CCP from "cc-plugin/src/ccp/entry-render";
import { Msg, Page, PluginEvent } from "../../core/types";
import { TestClient, testServer, TestServer } from "./test/server";
import { Terminal } from "../../scripts/terminal";
export type BridgeCallback = (data: PluginEvent, sender: chrome.runtime.Port) => void;
if (chrome.devtools) {
console.log("chrome devtools")
}
class Bridge implements TestClient {
/**
* callback保存为变量便
*/
public onMessage: BridgeCallback | null = null;
/**
* background建立的链接
*/
private connect: chrome.runtime.Port | null = null;
private terminal = new Terminal(Page.Devtools);
constructor() {
this.init();
}
private init() {
if (CCP.Adaptation.Env.isChromeRuntime) {
this.connect = chrome.runtime.connect({ name: Page.Devtools });
this.connect.onDisconnect.addListener(() => {
console.log(...this.terminal.disconnect(""))
this.connect = null;
})
this.connect.onMessage.addListener((event, sender: chrome.runtime.Port) => {
console.log(...this.terminal.message(JSON.stringify(event)));
const data = PluginEvent.create(event);
if (this.onMessage) {
this.onMessage(data, sender);
}
});
} else {
testServer.add(this);
}
}
recv(event: PluginEvent): void {
this.doMessage(event);
}
doMessage(data: PluginEvent) {
if (this.onMessage) {
this.onMessage(data, null);
}
}
send(msg: Msg, data?: any) {
if (CCP.Adaptation.Env.isChromeDevtools) {
if (this.connect) {
let sendData = new PluginEvent(Page.Devtools, Page.Background, msg, data)
this.connect.postMessage(sendData)
} else {
console.warn(...this.terminal.log("重新和background建立链接"))
this.init();
this.send(msg, data)
}
} else {
testServer.recv(msg, data);
}
}
}
export const bridge = new Bridge();

View File

@ -1,69 +0,0 @@
import CCP from "cc-plugin/src/ccp/entry-render";
import { Msg, Page, PluginEvent } from "../../core/types";
import { TestClient, testServer, TestServer } from "./test/server";
export type BackgroundCallback = (data: PluginEvent, sender: any) => void;
if (chrome.devtools) {
console.log("chrome devtools")
}
class ConnectBackground implements TestClient {
connect: chrome.runtime.Port | null = null;
constructor() {
this._initConnect();
}
private _initConnect() {
if (CCP.Adaptation.Env.isChromeRuntime) {
this.connect = chrome.runtime.connect({ name: Page.Devtools });
this.connect.onDisconnect.addListener(() => {
console.log(`%c[Connect-Dis]`, "color:red;")
this.connect = null;
})
} else {
testServer.add(this);
}
}
/**
* callback保存为变量便
*/
private callback: BackgroundCallback | null = null;
onBackgroundMessage(cb: BackgroundCallback) {
this.callback = cb;
if (this.connect) {
this.connect.onMessage.addListener((event, sender) => {
cb && cb(event, sender)
});
}
}
recv(event: PluginEvent): void {
this.doCallback(event);
}
doCallback(data: PluginEvent) {
if (this.callback) {
this.callback(data, null);
}
}
sendMsgToContentScript(msg: Msg, data?: any) {
if (CCP.Adaptation.Env.isChromeDevtools) {
this.postMessageToBackground(msg, data);
} else {
testServer.recv(msg, data);
}
}
postMessageToBackground(msg: Msg, data?: any) {
if (CCP.Adaptation.Env.isChromeDevtools) {
if (this.connect) {
let sendData = new PluginEvent(Page.Devtools, Page.Background, msg, data)
this.connect.postMessage(sendData)
} else {
console.warn("重新和background建立链接")
this._initConnect();
this.postMessageToBackground(msg, data)
}
} else {
testServer.recv(msg, data);
}
}
}
export const connectBackground = new ConnectBackground();

View File

@ -48,7 +48,7 @@ import { defineComponent, nextTick, onMounted, PropType, reactive, Ref, ref, toR
import PluginConfig from "../../../cc-plugin.config"; import PluginConfig from "../../../cc-plugin.config";
import { Msg, Page, PluginEvent } from "../../core/types"; import { Msg, Page, PluginEvent } from "../../core/types";
import Bus, { BusMsg } from "./bus"; import Bus, { BusMsg } from "./bus";
import { connectBackground } from "./connectBackground"; import { bridge } from "./bridge";
import { EngineData, FrameDetails, Info, NodeInfoData, ObjectData, ObjectItemRequestData, TreeData } from "./data"; import { EngineData, FrameDetails, Info, NodeInfoData, ObjectData, ObjectItemRequestData, TreeData } from "./data";
import { appStore, RefreshType } from "./store"; import { appStore, RefreshType } from "./store";
import Test from "./test/test.vue"; import Test from "./test/test.vue";
@ -274,12 +274,12 @@ export default defineComponent({
} }
}; };
// background.js // background.js
connectBackground.onBackgroundMessage((data: PluginEvent, sender: any) => { bridge.onMessage = (data: PluginEvent, sender: any) => {
if (!data) { if (!data) {
return; return;
} }
if (data.target === Page.Devtools) { debugger;
console.log("[Devtools]", data); if (data.isTargetDevtools()) {
PluginEvent.finish(data); PluginEvent.finish(data);
const { msg } = data; const { msg } = data;
if (msg) { if (msg) {
@ -290,8 +290,10 @@ export default defineComponent({
console.warn(`没有${msg}消息的函数`); console.warn(`没有${msg}消息的函数`);
} }
} }
} else {
debugger;
} }
}); };
} }
_initChromeRuntimeConnect(); _initChromeRuntimeConnect();
window.addEventListener( window.addEventListener(
@ -310,13 +312,13 @@ export default defineComponent({
return; return;
} }
requestList.push({ id: data.id, cb }); requestList.push({ id: data.id, cb });
connectBackground.sendMsgToContentScript(Msg.GetObjectItemData, data); bridge.send(Msg.GetObjectItemData, data);
}); });
Bus.on(BusMsg.UpdateSettings, () => { Bus.on(BusMsg.UpdateSettings, () => {
syncSettings(); syncSettings();
}); });
Bus.on(BusMsg.LogData, (data: string[]) => { Bus.on(BusMsg.LogData, (data: string[]) => {
connectBackground.sendMsgToContentScript(Msg.LogData, data); bridge.send(Msg.LogData, data);
}); });
onMounted(() => { onMounted(() => {
syncSettings(); syncSettings();
@ -381,7 +383,7 @@ export default defineComponent({
} }
function updateNodeInfo() { function updateNodeInfo() {
if (selectedUUID) { if (selectedUUID) {
connectBackground.sendMsgToContentScript(Msg.NodeInfo, selectedUUID); bridge.send(Msg.NodeInfo, selectedUUID);
} }
} }
let selectedUUID: string | null = null; let selectedUUID: string | null = null;
@ -389,10 +391,12 @@ export default defineComponent({
(elTree.value as any)?.filter(val); (elTree.value as any)?.filter(val);
} }
function onBtnClickUpdateTree() { function onBtnClickUpdateTree() {
connectBackground.sendMsgToContentScript(Msg.TreeInfo, frameID); const id = toRaw(frameID.value);
bridge.send(Msg.TreeInfo, id);
} }
function onChangeFrame() { function onChangeFrame() {
connectBackground.sendMsgToContentScript(Msg.UseFrame, frameID); const id = toRaw(frameID.value);
bridge.send(Msg.UseFrame, id);
} }
const elLeft = ref<HTMLDivElement>(); const elLeft = ref<HTMLDivElement>();
const version = ref(PluginConfig.manifest.version); const version = ref(PluginConfig.manifest.version);
@ -451,10 +455,10 @@ export default defineComponent({
}, },
onBtnClickUpdatePage() { onBtnClickUpdatePage() {
connectBackground.sendMsgToContentScript(Msg.Support); bridge.send(Msg.Support);
}, },
onMemoryTest() { onMemoryTest() {
connectBackground.sendMsgToContentScript(Msg.MemoryInfo); bridge.send(Msg.MemoryInfo);
}, },
onChangeFrame, onChangeFrame,

View File

@ -1,5 +1,7 @@
import CCP from "cc-plugin/src/ccp/entry-render"; import CCP from "cc-plugin/src/ccp/entry-render";
import { ChromeConst } from "cc-plugin/src/chrome/const"; import { ChromeConst } from "cc-plugin/src/chrome/const";
import { bridge } from "./bridge";
import { Msg } from "../../core/types";
export function init() { export function init() {
if (chrome && chrome.devtools) { if (chrome && chrome.devtools) {
// 对应的是Elements面板的边栏 // 对应的是Elements面板的边栏
@ -18,7 +20,7 @@ export function init() {
panel.onShown.addListener((window) => { panel.onShown.addListener((window) => {
// 面板显示查询是否是cocos游戏 // 面板显示查询是否是cocos游戏
console.log("panel show"); console.log("panel show");
// connectBackground.postMessageToBackground(Msg.Support, null) // bridge.sendToBackground(Msg.Support, null)
}); });
panel.onHidden.addListener(() => { panel.onHidden.addListener(() => {
// 面板隐藏 // 面板隐藏

View File

@ -15,7 +15,7 @@ import ccui from "@xuyanfeng/cc-ui";
import { ITreeData } from "@xuyanfeng/cc-ui/types/cc-tree/const"; import { ITreeData } from "@xuyanfeng/cc-ui/types/cc-tree/const";
import { defineComponent, ref } from "vue"; import { defineComponent, ref } from "vue";
import { Msg, Page, PluginEvent } from "../../../core/types"; import { Msg, Page, PluginEvent } from "../../../core/types";
import { connectBackground } from "../connectBackground"; import { bridge } from "../bridge";
import { FrameDetails, Group, Info, InvalidData, NodeInfoData, TreeData } from "../data"; import { FrameDetails, Group, Info, InvalidData, NodeInfoData, TreeData } from "../data";
import { testServer, TestServer } from "./server"; import { testServer, TestServer } from "./server";
const { CCButton, CCSection } = ccui.components; const { CCButton, CCSection } = ccui.components;
@ -70,7 +70,7 @@ export default defineComponent({
children: [], children: [],
}; };
const event = new PluginEvent(Page.Inject, Page.Devtools, Msg.TreeInfo, data); const event = new PluginEvent(Page.Inject, Page.Devtools, Msg.TreeInfo, data);
connectBackground.doCallback(event); bridge.doMessage(event);
}, },
onFrames() { onFrames() {
const data: FrameDetails[] = [ const data: FrameDetails[] = [

View File

@ -14,7 +14,7 @@
<script lang="ts"> <script lang="ts">
import ccui from "@xuyanfeng/cc-ui"; import ccui from "@xuyanfeng/cc-ui";
import { defineComponent, PropType, ref, watch } from "vue"; import { defineComponent, PropType, ref, toRaw, watch } from "vue";
import Bus, { BusMsg } from "../bus"; import Bus, { BusMsg } from "../bus";
import { Group } from "../data"; import { Group } from "../data";
import UiProp from "./ui-prop.vue"; import UiProp from "./ui-prop.vue";
@ -53,7 +53,8 @@ export default defineComponent({
return { return {
fold, fold,
onLog() { onLog() {
Bus.emit(BusMsg.LogData, [props.group.id]); const raw = toRaw(props);
Bus.emit(BusMsg.LogData, [raw.group.id]);
}, },
}; };
}, },

View File

@ -35,7 +35,7 @@ import { nextTick } from "process";
import { defineComponent, onMounted, onUnmounted, PropType, ref, toRaw, watch } from "vue"; import { defineComponent, onMounted, onUnmounted, PropType, ref, toRaw, watch } from "vue";
import { Msg } from "../../../core/types"; import { Msg } from "../../../core/types";
import Bus, { BusMsg } from "../bus"; import Bus, { BusMsg } from "../bus";
import { connectBackground } from "../connectBackground"; import { bridge } from "../bridge";
import { DataType, EngineData, EnumData, ImageData, Info, NumberData, Property, StringData, TextData, Vec2Data, Vec3Data } from "../data"; import { DataType, EngineData, EnumData, ImageData, Info, NumberData, Property, StringData, TextData, Vec2Data, Vec3Data } from "../data";
import Engine from "./property-engine.vue"; import Engine from "./property-engine.vue";
import PropertyImage from "./property-image.vue"; import PropertyImage from "./property-image.vue";
@ -139,7 +139,8 @@ export default defineComponent({
}, },
onChangeValue() { onChangeValue() {
if (!props.value.readonly) { if (!props.value.readonly) {
connectBackground.postMessageToBackground(Msg.SetProperty, toRaw(props.value)); const raw = toRaw(props.value);
bridge.send(Msg.SetProperty, raw);
} }
}, },
}; };