From 7d05e23d4c52b185ee25e8e4aacef581ceeb3f2d Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Sat, 16 May 2020 11:21:33 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=97=B6=E5=88=87=E6=8D=A2=E7=9B=AE=E6=A0=87=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _server/editor_mode.js | 14 ++++++-------- _server/editor_table.js | 8 ++++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/_server/editor_mode.js b/_server/editor_mode.js index 5ca0f7b0..d7b8e728 100644 --- a/_server/editor_mode.js +++ b/_server/editor_mode.js @@ -97,14 +97,12 @@ editor_mode = function (editor) { } editor_mode.prototype.onmode = function (mode, callback) { - //setTimeout(function(){ - if (editor_mode.mode != mode) { - if (mode === 'save') editor_mode.doActionList(editor_mode.mode, editor_mode.actionList, callback); - if (editor_mode.mode === 'nextChange' && mode) editor_mode.showMode(mode); - if (mode !== 'save') editor_mode.mode = mode; - editor_mode.actionList = []; - } - //}) + if (editor_mode.mode != mode) { + if (mode === 'save') editor_mode.doActionList(editor_mode.mode, editor_mode.actionList, callback); + if (editor_mode.mode === 'nextChange' && mode) editor_mode.showMode(mode); + if (mode !== 'save') editor_mode.mode = mode; + editor_mode.actionList = []; + } } editor_mode.prototype.showMode = function (mode) { diff --git a/_server/editor_table.js b/_server/editor_table.js index 1788515b..bfb38185 100644 --- a/_server/editor_table.js +++ b/_server/editor_table.js @@ -224,8 +224,10 @@ editor_table_wrapper = function (editor) { var listen = function (guids) { // 每个叶节点的事件绑定 + var tableid = editor.util.guid(); + editor.mode.currentTable=tableid; guids.forEach(function (guid) { - editor.table.guidListen(guid, obj, commentObj) + editor.table.guidListen(guid, tableid, obj, commentObj) }); } return { "HTML": outstr.join(''), "guids": guids, "listen": listen }; @@ -309,7 +311,7 @@ editor_table_wrapper = function (editor) { * 监听一个guid对应的表格项 * @param {String} guid */ - editor_table.prototype.guidListen = function (guid, obj, commentObj) { + editor_table.prototype.guidListen = function (guid, tableid, obj, commentObj) { // tr>td[title=field] // >td[title=comment,cobj=cobj:json] // >td>div>input[value=thiseval] @@ -318,6 +320,7 @@ editor_table_wrapper = function (editor) { var field = thisTr.children[0].getAttribute('title'); var cobj = JSON.parse(thisTr.children[1].getAttribute('cobj')); var modeNode = thisTr.parentNode; + thisTr.setAttribute('tableid',tableid) while (!editor_mode._ids.hasOwnProperty(modeNode.getAttribute('id'))) { modeNode = modeNode.parentNode; } @@ -341,6 +344,7 @@ editor_table_wrapper = function (editor) { */ editor_table.prototype.onchange = function (guid, obj, commentObj, thisTr, input, field, cobj, modeNode) { editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]); + if (editor.mode.currentTable!=thisTr.getAttribute('tableid')) return; var thiseval = null; if (input.checked != null) input.value = input.checked; try { From f264ba9e533eae0d97c163438155d8fa1a678335 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Sat, 16 May 2020 11:51:26 +0800 Subject: [PATCH 2/5] fix types of some eval-blocks --- _server/MotaAction.g4 | 32 ++++++++++++-------------------- _server/editor_blockly.js | 10 +++++----- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index bc5e64cd..ef872b1f 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -2510,6 +2510,10 @@ expression | idString_e | evFlag_e | evTemp_e + | enemyattr_e + | blockId_e + | blockCls_e + | equip_e | evalString_e @@ -2597,13 +2601,11 @@ return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; -//这一条不会被antlr识别,总是会被归到idString_e -idString_3_e +enemyattr_e : '怪物' IdString '的' EnemyId_List -/* idString_3_e -colour : this.idstring_eColor +/* enemyattr_e default : ['greenSlime',"攻击"] //todo 将其output改成'idString_e' var code = 'enemy:'+IdString_0+':'+EnemyId_List_0; @@ -2611,39 +2613,33 @@ return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; -//这一条不会被antlr识别,总是会被归到idString_e -idString_4_e +blockId_e : '图块ID:' Int ',' Int -/* idString_4_e -colour : this.idstring_eColor +/* blockId_e default : [0,0] var code = 'blockId:'+Int_0+','+Int_1; return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; -//这一条不会被antlr识别,总是会被归到idString_e -idString_5_e +blockCls_e : '图块类别:' Int ',' Int -/* idString_5_e -colour : this.idstring_eColor +/* blockCls_e default : [0,0] var code = 'blockCls:'+Int_0+','+Int_1; return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; -//这一条不会被antlr识别,总是会被归到idString_e -idString_6_e +equip_e : '装备孔:' Int -/* idString_6_e -colour : this.idstring_eColor +/* equip_e default : [0] var code = 'equip:'+Int_0; return [code, Blockly.JavaScript.ORDER_ATOMIC]; @@ -2901,10 +2897,6 @@ this.evisitor.mapColor=175; delete(this.block('negate_e').inputsInline); this.block('idString_1_e').output='idString_e'; this.block('idString_2_e').output='idString_e'; -this.block('idString_3_e').output='idString_e'; -this.block('idString_4_e').output='idString_e'; -this.block('idString_5_e').output='idString_e'; -this.block('idString_6_e').output='idString_e'; this.block('evFlag_e').output='idString_e'; this.block('evTemp_e').output='idString_e'; */ diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index c1908d51..f47ca6d2 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -227,10 +227,10 @@ editor_blockly = function () { MotaActionBlocks['idString_e'].xmlText(), MotaActionBlocks['idString_1_e'].xmlText(), MotaActionBlocks['idString_2_e'].xmlText(), - MotaActionBlocks['idString_3_e'].xmlText(), - MotaActionBlocks['idString_4_e'].xmlText(), - MotaActionBlocks['idString_5_e'].xmlText(), - MotaActionBlocks['idString_6_e'].xmlText(), + MotaActionBlocks['enemyattr_e'].xmlText(), + MotaActionBlocks['blockId_e'].xmlText(), + MotaActionBlocks['blockCls_e'].xmlText(), + MotaActionBlocks['equip_e'].xmlText(), MotaActionBlocks['evalString_e'].xmlText(), ], '常见事件模板':[ @@ -1011,7 +1011,7 @@ function omitedcheckUpdateFunction(event) { } // 对怪物ID提供补全 - if ((type == 'idString_3_e' || type == 'battle_s' || type == 'setEnemy_s') && name == 'IdString_0') { + if ((type == 'enemyattr_e' || type == 'battle_s' || type == 'setEnemy_s') && name == 'IdString_0') { return filter(allEnemys, content); } From 80a5d6491842e49826f4fc333855a4611149763d Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Sat, 16 May 2020 12:41:52 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E8=B0=83=E6=95=B4blockly=E4=B8=ADidString?= =?UTF-8?q?=E7=B1=BB=E5=88=AB=E7=9A=84id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _server/MotaAction.g4 | 39 ++++++++++++++++++--------------------- _server/editor_blockly.js | 12 ++++++------ 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index ef872b1f..c92c3f26 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -2507,9 +2507,11 @@ expression : expression Arithmetic_List expression | negate_e | bool_e + | idFixedList_e + | idFlag_e + | idTemp_e + | idIdList_e | idString_e - | evFlag_e - | evTemp_e | enemyattr_e | blockId_e | blockCls_e @@ -2575,27 +2577,23 @@ var code = IdString_0; return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; -//这一条不会被antlr识别,总是会被归到idString_e -idString_1_e +idIdList_e : Id_List ':' IdText -/* idString_1_e +/* idIdList_e colour : this.idstring_eColor default : [null,"自定义flag"] -//todo 将其output改成'idString_e' var code = MotaActionFunctions.replaceFromName(MotaActionFunctions.replaceToName(Id_List_0+':'+IdText_0)); return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; -//这一条不会被antlr识别,总是会被归到idString_e -idString_2_e +idFixedList_e : FixedId_List -/* idString_2_e +/* idFixedList_e colour : this.idstring_eColor -//todo 将其output改成'idString_e' var code = FixedId_List_0; return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; @@ -2607,7 +2605,6 @@ enemyattr_e /* enemyattr_e default : ['greenSlime',"攻击"] -//todo 将其output改成'idString_e' var code = 'enemy:'+IdString_0+':'+EnemyId_List_0; return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; @@ -2646,11 +2643,11 @@ return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; -evFlag_e +idFlag_e : '独立开关' Letter_List -/* evFlag_e +/* idFlag_e colour : this.idstring_eColor default : ["A"] var code = "switch:"+Letter_List_0; @@ -2658,11 +2655,11 @@ return [code, Blockly.JavaScript.ORDER_ATOMIC]; */; -evTemp_e +idTemp_e : '临时变量' Letter_List -/* evTemp_e +/* idTemp_e colour : this.idstring_eColor default : ["A"] var code = "temp:"+Letter_List_0; @@ -2895,10 +2892,10 @@ this.evisitor.mapColor=175; /* Function_1 delete(this.block('negate_e').inputsInline); -this.block('idString_1_e').output='idString_e'; -this.block('idString_2_e').output='idString_e'; -this.block('evFlag_e').output='idString_e'; -this.block('evTemp_e').output='idString_e'; +this.block('idIdList_e').output='idString_e'; +this.block('idFixedList_e').output='idString_e'; +this.block('idFlag_e').output='idString_e'; +this.block('idTemp_e').output='idString_e'; */ /* Functions @@ -3822,12 +3819,12 @@ ActionParser.prototype.tryToUseEvFlag_e = function(defaultType, args, isShadow, var match=/^switch:([A-Z])$/.exec(args[0]) if(match){ args[0]=match[1] - return MotaActionBlocks['evFlag_e'].xmlText(args, isShadow, comment); + return MotaActionBlocks['idFlag_e'].xmlText(args, isShadow, comment); } match=/^temp:([A-Z])$/.exec(args[0]) if(match){ args[0]=match[1] - return MotaActionBlocks['evTemp_e'].xmlText(args, isShadow, comment); + return MotaActionBlocks['idTemp_e'].xmlText(args, isShadow, comment); } return MotaActionBlocks[defaultType||'evalString_e'].xmlText(args, isShadow, comment); } diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index f47ca6d2..75754601 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -97,7 +97,7 @@ editor_blockly = function () { ], '数据相关':[ MotaActionBlocks['setValue_s'].xmlText([ - MotaActionBlocks['idString_1_e'].xmlText(['status','生命']), '=', '', false + MotaActionBlocks['idIdList_e'].xmlText(['status','生命']), '=', '', false ]), MotaActionBlocks['setEnemy_s'].xmlText(), MotaActionBlocks['setFloor_s'].xmlText(), @@ -217,16 +217,16 @@ editor_blockly = function () { ], '值块':[ MotaActionBlocks['setValue_s'].xmlText([ - MotaActionBlocks['idString_1_e'].xmlText(['status','生命']), '=', '', false + MotaActionBlocks['idIdList_e'].xmlText(['status','生命']), '=', '', false ]), MotaActionBlocks['expression_arithmetic_0'].xmlText(), - MotaActionBlocks['evFlag_e'].xmlText(), - MotaActionBlocks['evTemp_e'].xmlText(), + MotaActionBlocks['idFlag_e'].xmlText(), + MotaActionBlocks['idTemp_e'].xmlText(), MotaActionBlocks['negate_e'].xmlText(), MotaActionBlocks['bool_e'].xmlText(), MotaActionBlocks['idString_e'].xmlText(), - MotaActionBlocks['idString_1_e'].xmlText(), - MotaActionBlocks['idString_2_e'].xmlText(), + MotaActionBlocks['idIdList_e'].xmlText(), + MotaActionBlocks['idFixedList_e'].xmlText(), MotaActionBlocks['enemyattr_e'].xmlText(), MotaActionBlocks['blockId_e'].xmlText(), MotaActionBlocks['blockCls_e'].xmlText(), From d5989d9d53ba399b95322ecfc540378dfb0597b9 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Sat, 16 May 2020 12:54:53 +0800 Subject: [PATCH 4/5] expandevalblock --- _server/MotaAction.g4 | 49 ++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index c92c3f26..ebd6571d 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -2946,7 +2946,7 @@ ActionParser.prototype.parse = function (obj,type) { var text_choices = null; for(var ii=obj.length-1,choice;choice=obj[ii];ii--) { text_choices=MotaActionBlocks['levelCase'].xmlText([ - MotaActionBlocks['evalString_e'].xmlText([choice.need]),choice.title,choice.clear||false,this.parseList(choice.action),text_choices]); + this.expandEvalBlock([choice.need]),choice.title,choice.clear||false,this.parseList(choice.action),text_choices]); } return MotaActionBlocks['level_m'].xmlText([text_choices]); @@ -3403,14 +3403,14 @@ ActionParser.prototype.parseAction = function() { break case "setValue": this.next = MotaActionBlocks['setValue_s'].xmlText([ - this.tryToUseEvFlag_e('idString_e', [data.name]), data["operator"]||'=', - MotaActionBlocks['evalString_e'].xmlText([data.value]), + this.expandIdBlock([data.name]), data["operator"]||'=', + this.expandEvalBlock([data.value]), data.norefresh || false, this.next]); break; case "setEnemy": this.next = MotaActionBlocks['setEnemy_s'].xmlText([ - data.id, data.name, MotaActionBlocks['evalString_e'].xmlText([data.value]), this.next]); + data.id, data.name, this.expandEvalBlock([data.value]), this.next]); break; case "setFloor": this.next = MotaActionBlocks['setFloor_s'].xmlText([ @@ -3439,14 +3439,14 @@ ActionParser.prototype.parseAction = function() { case "if": // 条件判断 if (data["false"]) { this.next = MotaActionBlocks['if_s'].xmlText([ - this.tryToUseEvFlag_e('evalString_e', [data.condition]), + this.expandEvalBlock([data.condition]), this.insertActionList(data["true"]), this.insertActionList(data["false"]), this.next]); } else { this.next = MotaActionBlocks['if_1_s'].xmlText([ - this.tryToUseEvFlag_e('evalString_e', [data.condition]), + this.expandEvalBlock([data.condition]), this.insertActionList(data["true"]), this.next]); } @@ -3462,11 +3462,10 @@ ActionParser.prototype.parseAction = function() { var case_caseList = null; for(var ii=data.caseList.length-1,caseNow;caseNow=data.caseList[ii];ii--) { case_caseList=MotaActionBlocks['switchCase'].xmlText([ - this.isset(caseNow.case)?MotaActionBlocks['evalString_e'].xmlText([caseNow.case]):"值",caseNow.nobreak,this.insertActionList(caseNow.action),case_caseList]); + this.isset(caseNow.case)?this.expandEvalBlock([caseNow.case]):"值",caseNow.nobreak,this.insertActionList(caseNow.action),case_caseList]); } this.next = MotaActionBlocks['switch_s'].xmlText([ - // MotaActionBlocks['evalString_e'].xmlText([data.condition]), - this.tryToUseEvFlag_e('evalString_e', [data.condition]), + this.expandEvalBlock([data.condition]), case_caseList,this.next]); break; case "choices": // 提供选项 @@ -3483,30 +3482,28 @@ ActionParser.prototype.parseAction = function() { break; case "for": // 循环遍历 this.next = MotaActionBlocks['for_s'].xmlText([ - this.tryToUseEvFlag_e('evalString_e', [data.name]), + this.expandEvalBlock([data.name]), data.from || 0, data.to || 0, data.step || 0, this.insertActionList(data.data), this.next]); break; case "forEach": // 循环遍历列表 this.next = MotaActionBlocks['forEach_s'].xmlText([ - this.tryToUseEvFlag_e('evalString_e', [data.name]), + this.expandEvalBlock([data.name]), JSON.stringify(data.list), this.insertActionList(data.data), this.next]); break; case "while": // 前置条件循环处理 this.next = MotaActionBlocks['while_s'].xmlText([ - // MotaActionBlocks['evalString_e'].xmlText([data.condition]), - this.tryToUseEvFlag_e('evalString_e', [data.condition]), + this.expandEvalBlock([data.condition]), this.insertActionList(data.data), this.next]); break; case "dowhile": // 后置条件循环处理 this.next = MotaActionBlocks['dowhile_s'].xmlText([ this.insertActionList(data.data), - // MotaActionBlocks['evalString_e'].xmlText([data.condition]), - this.tryToUseEvFlag_e('evalString_e', [data.condition]), + this.expandEvalBlock([data.condition]), this.next]); break; case "break": // 跳出循环 @@ -3815,7 +3812,7 @@ ActionParser.prototype.Colour = function(color) { return color?JSON.stringify(color).slice(1,-1):null; } -ActionParser.prototype.tryToUseEvFlag_e = function(defaultType, args, isShadow, comment) { +ActionParser.prototype.expandIdBlock = function(args, isShadow, comment) { var match=/^switch:([A-Z])$/.exec(args[0]) if(match){ args[0]=match[1] @@ -3826,7 +3823,25 @@ ActionParser.prototype.tryToUseEvFlag_e = function(defaultType, args, isShadow, args[0]=match[1] return MotaActionBlocks['idTemp_e'].xmlText(args, isShadow, comment); } - return MotaActionBlocks[defaultType||'evalString_e'].xmlText(args, isShadow, comment); + return MotaActionBlocks['idString_e'].xmlText(args, isShadow, comment); +} + +ActionParser.prototype.expandEvalBlock = function(args, isShadow, comment) { + var match=/^switch:([A-Z])$/.exec(args[0]) + if(match){ + args[0]=match[1] + return MotaActionBlocks['idFlag_e'].xmlText(args, isShadow, comment); + } + match=/^temp:([A-Z])$/.exec(args[0]) + if(match){ + args[0]=match[1] + return MotaActionBlocks['idTemp_e'].xmlText(args, isShadow, comment); + } + // todo + // 1. 将「数值设置」的名称尽可能替换掉;如果是 FixedId_List 那就用它;否则如果是 独立开关/临时变量 那就用对应的;否则用 A:B 的那个框 + // 2. 将「值块」尽可能替换掉,主要是「独立开关」,「临时变量」,「非 - 独立开关」,「非-临时变量」;以及true/false替换成勾选框;对于其他变量/属性等之类也尽可能进行替换 + + return MotaActionBlocks['evalString_e'].xmlText(args, isShadow, comment); } MotaActionFunctions.actionParser = new ActionParser(); From a67cc8595bc3e44de80c345597a7e181136514a1 Mon Sep 17 00:00:00 2001 From: YouWei Zhao Date: Sat, 16 May 2020 15:00:53 +0800 Subject: [PATCH 5/5] expand id --- _server/MotaAction.g4 | 45 +++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index ebd6571d..95e2450e 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -3812,31 +3812,48 @@ ActionParser.prototype.Colour = function(color) { return color?JSON.stringify(color).slice(1,-1):null; } -ActionParser.prototype.expandIdBlock = function(args, isShadow, comment) { - var match=/^switch:([A-Z])$/.exec(args[0]) +ActionParser.prototype.matchId = function(args, isShadow, comment) { + var rt=function(xml){ + return {xml:xml,ret:true} + } + var match = /nothing/.exec('nothing') + // 固定列表 + var FixedId_List=MotaActionBlocks.idFixedList_e.json.args0[0].options; // [["生命", "status:hp"], ...] + match=new RegExp('^('+FixedId_List.map(function(v){return v[1]}).join('|')+')$').exec(args[0]) + if(match){ + return rt(MotaActionBlocks['idFixedList_e'].xmlText(args, isShadow, comment)); + } + // 独立开关 + match=/^switch:([A-Z])$/.exec(args[0]) if(match){ args[0]=match[1] - return MotaActionBlocks['idFlag_e'].xmlText(args, isShadow, comment); + return rt(MotaActionBlocks['idFlag_e'].xmlText(args, isShadow, comment)); } + // 临时变量 match=/^temp:([A-Z])$/.exec(args[0]) if(match){ args[0]=match[1] - return MotaActionBlocks['idTemp_e'].xmlText(args, isShadow, comment); + return rt(MotaActionBlocks['idTemp_e'].xmlText(args, isShadow, comment)); } + // id列表 + var Id_List = MotaActionBlocks.idIdList_e.json.args0[0].options; // [["变量", "flag"], ...] + match=new RegExp('^('+Id_List.map(function(v){return v[1]}).join('|')+'):([a-zA-Z0-9_\\u4E00-\\u9FCC]+)$').exec(args[0]) + if(match){ + args=[match[1],match[2]].concat(args.slice(1)) + return rt(MotaActionBlocks['idIdList_e'].xmlText(args, isShadow, comment)); + } + return {xml:'',ret:false} +} + +ActionParser.prototype.expandIdBlock = function(args, isShadow, comment) { + var ret=this.matchId(args, isShadow, comment) + if (ret.ret) return ret.xml; return MotaActionBlocks['idString_e'].xmlText(args, isShadow, comment); } ActionParser.prototype.expandEvalBlock = function(args, isShadow, comment) { - var match=/^switch:([A-Z])$/.exec(args[0]) - if(match){ - args[0]=match[1] - return MotaActionBlocks['idFlag_e'].xmlText(args, isShadow, comment); - } - match=/^temp:([A-Z])$/.exec(args[0]) - if(match){ - args[0]=match[1] - return MotaActionBlocks['idTemp_e'].xmlText(args, isShadow, comment); - } + var ret=this.matchId(args, isShadow, comment) + if (ret.ret) return ret.xml; // todo // 1. 将「数值设置」的名称尽可能替换掉;如果是 FixedId_List 那就用它;否则如果是 独立开关/临时变量 那就用对应的;否则用 A:B 的那个框 // 2. 将「值块」尽可能替换掉,主要是「独立开关」,「临时变量」,「非 - 独立开关」,「非-临时变量」;以及true/false替换成勾选框;对于其他变量/属性等之类也尽可能进行替换