From 0b3007d22dc4e0298a66236a8dcca2fbd3ae06f4 Mon Sep 17 00:00:00 2001 From: axapaxa123 <49201376+axapaxa123@users.noreply.github.com> Date: Mon, 13 May 2019 19:22:55 +0200 Subject: [PATCH 1/8] New NN, updated required data --- lib/dole_nn_base.js | 99 +++++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 25 deletions(-) diff --git a/lib/dole_nn_base.js b/lib/dole_nn_base.js index e4dda0b6..52fae744 100644 --- a/lib/dole_nn_base.js +++ b/lib/dole_nn_base.js @@ -47,31 +47,76 @@ function Dose(numreq,instore,store_last_tick,dole,carry,prev_req,numreq_total_ad var b=Math.trunc(prev_req/instore_adj*numreq); var inp1=[numreq,instore_adj,store_last_tick/numreq,dole,carry];//0..4 - var inp2=[prev_req/numreq,numreq/numreq_total_adj,store_last_tick/numreq_total_adj,prev_req/instore_adj,b];//5..9 + var inp2=[prev_req/numreq,numreq/numreq_total_adj,store_last_tick/numreq_total_adj,prev_req/instore_adj,b,numreq_total_adj,store_last_tick];//5..11 var inputs=inp1.concat(inp2); - var internal=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; - var outputs=[0,0,0]; + var internal=new Array(20).fill(0); + var outputs=[0,0,0,0]; //NN: Please don't touch :), code is generated -outputs[0]=inputs[2]*3.101320028; -outputs[0]=outputs[0]+inputs[7]*0.5471593142; -outputs[0]=outputs[0]+inputs[3]*2.691268921; -outputs[0]=outputs[0]+outputs[1]*-1.64255929; -outputs[0]=outputs[0]+inputs[6]*0.7746122479; +internal[2]=internal[6]*7.267292023; +internal[2]=internal[2]+inputs[6]*-0.5385144949; +internal[2]=internal[2]+inputs[4]*7.982471466; +internal[2]=internal[2]+inputs[7]*-4.120764256; +internal[2]=internal[2]+internal[8]*0.6542916298; +internal[2]=internal[2]+internal[10]*1.781727672; +internal[2]=internal[2]+internal[12]*-0.3893937171; +internal[2]=sigmoid0(internal[2]); +internal[6]=inputs[7]*-1.472857833; +internal[6]=internal[6]+inputs[2]*0.8619997501; +internal[6]=internal[6]+inputs[9]*1.951734781; +internal[6]=internal[6]+inputs[3]*-1.689901233; +internal[6]=internal[6]+internal[9]*3.475469828; +internal[6]=sigmoid0(internal[6]); +internal[8]=sigmoid0(internal[8]); +internal[9]=inputs[10]*-1.441205978; +internal[9]=internal[9]+inputs[1]*5.842033863; +internal[9]=internal[9]+inputs[9]*2.132386684; +internal[9]=internal[9]+inputs[5]*0.9830219746; +internal[9]=sigmoid0(internal[9]); +internal[10]=internal[14]*1.186838627; +internal[10]=internal[10]+inputs[4]*2.864197493; +internal[10]=internal[10]+inputs[2]*1.245233774; +internal[10]=internal[10]+inputs[7]*-3.596544981; +internal[10]=internal[10]+inputs[5]*0.2605635822; +internal[10]=internal[10]+inputs[6]*0.4522094429; +internal[10]=internal[10]+inputs[0]*-0.9868286252; +internal[10]=internal[10]+1.0*0.9270827174; +internal[10]=sigmoid0(internal[10]); +internal[12]=inputs[11]*-0.7495238185; +internal[12]=internal[12]+inputs[10]*-0.2499841005; +internal[12]=internal[12]+inputs[7]*-1.974439263; +internal[12]=internal[12]+1.0*1.85799706; +internal[12]=internal[12]+inputs[0]*0.413690418; +internal[12]=internal[12]+inputs[9]*1.894246459; +internal[12]=internal[12]+inputs[4]*-2.371104717; +internal[12]=sigmoid0(internal[12]); +internal[14]=inputs[9]*-1.812304616; +internal[14]=internal[14]+inputs[10]*-0.3029920459; +internal[14]=internal[14]+inputs[5]*-0.3064728975; +internal[14]=internal[14]+inputs[1]*0.5113605857; +internal[14]=internal[14]+inputs[6]*-0.3487350941; +internal[14]=internal[14]+inputs[0]*0.701588273; +internal[14]=internal[14]+1.0*0.693169713; +internal[14]=internal[14]+inputs[4]*-1.443944097; +internal[14]=internal[14]+inputs[2]*-2.836822033; +internal[14]=internal[14]+inputs[11]*-0.6553236842; +internal[14]=internal[14]+inputs[3]*-1.075786948; +internal[14]=internal[14]+inputs[8]*0.2613089979; +internal[14]=sigmoid0(internal[14]); +outputs[0]=inputs[1]*1.726672769; outputs[0]=sigmoid0(outputs[0]); -outputs[1]=inputs[2]*-0.9946503043; -outputs[1]=outputs[1]+inputs[1]*0.2128598392; outputs[1]=sigmoid0(outputs[1]); -outputs[2]=sigmoid2(outputs[2]); +outputs[2]=sigmoid0(outputs[2]); +outputs[3]=internal[2]*-2.092440128; +outputs[3]=sigmoid0(outputs[3]); - outputs[0]=Number(outputs[0]); - if (outputs[0]<0) outputs[0]=0; - outputs[0]=outputs[0]*numreq; - var res1=Math.round(outputs[0]); + var res1=Math.round(Number(outputs[0])*numreq)+Math.round(outputs[3]); + if (res1>numreq) res1=numreq; if (res1>instore) res1=instore; if (res1<0) res1=0; - carry=sigmoid0(outputs[2]); + res1=res1 || 0;//Safeguard against wrong values + carry=sigmoid0(outputs[2]*carry+outputs[0]) || 0; return [res1,sigmoid0(outputs[1]),carry]; } @@ -91,22 +136,26 @@ function Tick(instore,dole,store_last_tick,numreq_total_adj) var instore_adj=instore; if (instore_adj==0) instore_adj=0.1; var inputs=[instore,dole,store_last_tick/instore_adj,store_last_tick/numreq_total_adj]; - var internal=[0,0,0,0,0]; + var internal=new Array(10).fill(0); var outputs=[0,0]; //NN: Please don't touch :), code is generated +internal[2]=inputs[3]*-0.3051533401; +internal[2]=internal[2]+1.0*1.657034278; internal[2]=sigmoid0(internal[2]); -outputs[0]=internal[2]*0.4049594998; -outputs[0]=outputs[0]+1.0*-5.026565075; -outputs[0]=outputs[0]+inputs[0]*0.9100194573; -outputs[0]=outputs[0]+inputs[1]*-1.063795686; +internal[5]=inputs[1]*1.691301703; +internal[5]=internal[5]+inputs[0]*1.238131285; +internal[5]=sigmoid0(internal[5]); +outputs[0]=1.0*0.309109062; +outputs[0]=outputs[0]*inputs[0]*1.836197853; outputs[0]=sigmoid1(outputs[0]); -outputs[1]=outputs[0]*1.049500823; -outputs[1]=outputs[1]*inputs[0]*3.437163115; +outputs[1]=inputs[3]*1.100017905; +outputs[1]=outputs[1]+internal[5]*0.9273151159; +outputs[1]=outputs[1]+1.0*-2.498474121; +outputs[1]=outputs[1]+inputs[0]*1.087127209; +outputs[1]=outputs[1]+internal[2]*-0.896425426; outputs[1]=sigmoid0(outputs[1]); - - avg=outputs[1]; if (numreq_total_adj<0.11) avg=1;//When no item's are requested, result is 0.1 ; In that case there is no deficit, so return 1 = 100% demand fulfilled if (avg>1) avg=1; From d719a7332844bcbdb5e6c3816f9829bf633d2f27 Mon Sep 17 00:00:00 2001 From: axapaxa123 Date: Sun, 2 Jun 2019 15:13:49 +0200 Subject: [PATCH 2/8] New NN, added debt system --- lib/dole_nn_base.js | 108 ++++++++++++------------------------------- routes/api/remove.js | 7 ++- 2 files changed, 35 insertions(+), 80 deletions(-) diff --git a/lib/dole_nn_base.js b/lib/dole_nn_base.js index 52fae744..ba00188c 100644 --- a/lib/dole_nn_base.js +++ b/lib/dole_nn_base.js @@ -33,12 +33,14 @@ function sigmoid3(x) //carry - carry for item X slave Y //prev_req - Numreq for previous request for item X slave Y //* doleinfo_last - Object with 2 values for last "tick period": numreq - total number or requests for item, numslave - number of slaves requesting that item +//debt - debt for item X slave Y //Returns: Array of 3 elements //0.Number of items to give in that dose //1.New dole for item X //2.New carry for item X slave Y -function Dose(numreq,instore,store_last_tick,dole,carry,prev_req,numreq_total_adj) +//3.New debt +function Dose(numreq,instore,store_last_tick,dole,carry,prev_req,numreq_total_adj,debt) { numreq=Number(numreq); instore=Number(instore); @@ -47,77 +49,37 @@ function Dose(numreq,instore,store_last_tick,dole,carry,prev_req,numreq_total_ad var b=Math.trunc(prev_req/instore_adj*numreq); var inp1=[numreq,instore_adj,store_last_tick/numreq,dole,carry];//0..4 - var inp2=[prev_req/numreq,numreq/numreq_total_adj,store_last_tick/numreq_total_adj,prev_req/instore_adj,b,numreq_total_adj,store_last_tick];//5..11 + var inp2=[prev_req/numreq,numreq/numreq_total_adj,store_last_tick/numreq_total_adj,prev_req/instore_adj,b,numreq_total_adj,store_last_tick,debt];//5..12 var inputs=inp1.concat(inp2); var internal=new Array(20).fill(0); var outputs=[0,0,0,0]; //NN: Please don't touch :), code is generated -internal[2]=internal[6]*7.267292023; -internal[2]=internal[2]+inputs[6]*-0.5385144949; -internal[2]=internal[2]+inputs[4]*7.982471466; -internal[2]=internal[2]+inputs[7]*-4.120764256; -internal[2]=internal[2]+internal[8]*0.6542916298; -internal[2]=internal[2]+internal[10]*1.781727672; -internal[2]=internal[2]+internal[12]*-0.3893937171; -internal[2]=sigmoid0(internal[2]); -internal[6]=inputs[7]*-1.472857833; -internal[6]=internal[6]+inputs[2]*0.8619997501; -internal[6]=internal[6]+inputs[9]*1.951734781; -internal[6]=internal[6]+inputs[3]*-1.689901233; -internal[6]=internal[6]+internal[9]*3.475469828; -internal[6]=sigmoid0(internal[6]); -internal[8]=sigmoid0(internal[8]); -internal[9]=inputs[10]*-1.441205978; -internal[9]=internal[9]+inputs[1]*5.842033863; -internal[9]=internal[9]+inputs[9]*2.132386684; -internal[9]=internal[9]+inputs[5]*0.9830219746; -internal[9]=sigmoid0(internal[9]); -internal[10]=internal[14]*1.186838627; -internal[10]=internal[10]+inputs[4]*2.864197493; -internal[10]=internal[10]+inputs[2]*1.245233774; -internal[10]=internal[10]+inputs[7]*-3.596544981; -internal[10]=internal[10]+inputs[5]*0.2605635822; -internal[10]=internal[10]+inputs[6]*0.4522094429; -internal[10]=internal[10]+inputs[0]*-0.9868286252; -internal[10]=internal[10]+1.0*0.9270827174; -internal[10]=sigmoid0(internal[10]); -internal[12]=inputs[11]*-0.7495238185; -internal[12]=internal[12]+inputs[10]*-0.2499841005; -internal[12]=internal[12]+inputs[7]*-1.974439263; -internal[12]=internal[12]+1.0*1.85799706; -internal[12]=internal[12]+inputs[0]*0.413690418; -internal[12]=internal[12]+inputs[9]*1.894246459; -internal[12]=internal[12]+inputs[4]*-2.371104717; -internal[12]=sigmoid0(internal[12]); -internal[14]=inputs[9]*-1.812304616; -internal[14]=internal[14]+inputs[10]*-0.3029920459; -internal[14]=internal[14]+inputs[5]*-0.3064728975; -internal[14]=internal[14]+inputs[1]*0.5113605857; -internal[14]=internal[14]+inputs[6]*-0.3487350941; -internal[14]=internal[14]+inputs[0]*0.701588273; -internal[14]=internal[14]+1.0*0.693169713; -internal[14]=internal[14]+inputs[4]*-1.443944097; -internal[14]=internal[14]+inputs[2]*-2.836822033; -internal[14]=internal[14]+inputs[11]*-0.6553236842; -internal[14]=internal[14]+inputs[3]*-1.075786948; -internal[14]=internal[14]+inputs[8]*0.2613089979; -internal[14]=sigmoid0(internal[14]); -outputs[0]=inputs[1]*1.726672769; -outputs[0]=sigmoid0(outputs[0]); +outputs[0]=inputs[7]*0.8058582544; +outputs[0]=sigmoid2(outputs[0]); outputs[1]=sigmoid0(outputs[1]); outputs[2]=sigmoid0(outputs[2]); -outputs[3]=internal[2]*-2.092440128; +outputs[3]=inputs[6]*0.2294657379; outputs[3]=sigmoid0(outputs[3]); - var res1=Math.round(Number(outputs[0])*numreq)+Math.round(outputs[3]); + debt=debt || 0; + if (outputs[0]>0.99) outputs[0]=1.0; + + var res1=Number(outputs[0])*numreq+outputs[3]+debt; + var res_capped=Math.round(res1); + + if (res_capped>numreq) res_capped=numreq; + if (res_capped>instore) res_capped=instore; + if (res_capped<0) res_capped=0; + + res1=res1 || 0; + res_capped=res_capped || 0;//Safeguard against wrong values + debt=res1-res_capped; + debt_cap=Math.round(numreq*1.5)+5; + if (debt>debt_cap) debt=debt_cap; - if (res1>numreq) res1=numreq; - if (res1>instore) res1=instore; - if (res1<0) res1=0; - res1=res1 || 0;//Safeguard against wrong values carry=sigmoid0(outputs[2]*carry+outputs[0]) || 0; - return [res1,sigmoid0(outputs[1]),carry]; + return [res_capped,dole+outputs[1],carry,debt]; } //TICK - Updates values for item X, should be called once for each item for each round of all slaves requesting that item @@ -135,26 +97,16 @@ function Tick(instore,dole,store_last_tick,numreq_total_adj) { var instore_adj=instore; if (instore_adj==0) instore_adj=0.1; - var inputs=[instore,dole,store_last_tick/instore_adj,store_last_tick/numreq_total_adj]; + var inputs=[instore,dole,store_last_tick/instore_adj,store_last_tick/numreq_total_adj,store_last_tick,numreq_total_adj]; var internal=new Array(10).fill(0); var outputs=[0,0]; //NN: Please don't touch :), code is generated -internal[2]=inputs[3]*-0.3051533401; -internal[2]=internal[2]+1.0*1.657034278; -internal[2]=sigmoid0(internal[2]); -internal[5]=inputs[1]*1.691301703; -internal[5]=internal[5]+inputs[0]*1.238131285; -internal[5]=sigmoid0(internal[5]); -outputs[0]=1.0*0.309109062; -outputs[0]=outputs[0]*inputs[0]*1.836197853; -outputs[0]=sigmoid1(outputs[0]); -outputs[1]=inputs[3]*1.100017905; -outputs[1]=outputs[1]+internal[5]*0.9273151159; -outputs[1]=outputs[1]+1.0*-2.498474121; -outputs[1]=outputs[1]+inputs[0]*1.087127209; -outputs[1]=outputs[1]+internal[2]*-0.896425426; -outputs[1]=sigmoid0(outputs[1]); +outputs[0]=inputs[3]*0.9364774823; +outputs[0]=outputs[0]*1.0*0.4590721726; +outputs[0]=sigmoid2(outputs[0]); +outputs[1]=outputs[0]*1.828422785; +outputs[1]=sigmoid3(outputs[1]); avg=outputs[1]; if (numreq_total_adj<0.11) avg=1;//When no item's are requested, result is 0.1 ; In that case there is no deficit, so return 1 = 100% demand fulfilled @@ -164,4 +116,4 @@ outputs[1]=sigmoid0(outputs[1]); return [sigmoid0(outputs[0]),avg]; } -module.exports = {Dose,Tick} +module.exports = {Dose,Tick} \ No newline at end of file diff --git a/routes/api/remove.js b/routes/api/remove.js index 18feabb1..a29d1165 100644 --- a/routes/api/remove.js +++ b/routes/api/remove.js @@ -33,6 +33,7 @@ class neuralDole { this.carry = {} this.lastRequest = {} this.stats=[] + this.debt= {} setInterval(()=>{ for(let name in this.items){ @@ -71,7 +72,8 @@ class neuralDole { this.dole[object.name], this.carry[object.name+" "+object.instanceID] || 0, this.lastRequest[object.name+"_"+object.instanceID+"_"+object.instanceName] || 0, - this.getRequestStats(object.name,5) + this.getRequestStats(object.name,5), + this.debt[object.name+" "+object.instanceID] || 0 ) if ((this.stats[object.name] || []).length>0) { @@ -84,6 +86,7 @@ class neuralDole { //2.New carry for item X slave Y this.dole[object.name] = magicData[1] this.carry[object.name+" "+object.instanceID] = magicData[2] + this.debt[object.name+" "+object.instanceID] = magicData[3] // Remove item from DB and send it if(this.items.removeItem({count: magicData[0], name: object.name})){ @@ -177,4 +180,4 @@ function doleDivider({ module.exports = { doleDivider, neuralDole -} +} \ No newline at end of file From 66ba706c56c6cec8fe163d3bb786369704d8c856 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sun, 2 Jun 2019 15:27:50 +0200 Subject: [PATCH 3/8] Use neural net dole divider by default on new installs See "useNeuralNetDoleDivider": true, If this causes issues, simply set it to false in config.json. If you find normal dole division to work badly as well, set disableFairItemDistribution to true. --- config.json.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json.dist b/config.json.dist index 1c598664..d7f6a6b3 100644 --- a/config.json.dist +++ b/config.json.dist @@ -49,7 +49,7 @@ "logItemTransfers": false, "__comment6.5": "When the master is undersupplied, we have 3 different modes to 'fairly' distribute items. First to ask gets all, dole division using weird formula or experimental neural net tries to make stuff as fair as possible. Feel free to play around.", "disableFairItemDistribution": false, - "useNeuralNetDoleDivider": false, + "useNeuralNetDoleDivider": true, "uploadModsToMaster": true, "msBetweenCommands": 10, "allowRemoteCommandExecution": true, From d66d22a9cdf4963d7a57482dda9e039e1ec0cf76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vest=C3=B8l?= Date: Fri, 5 Jul 2019 23:07:25 +0200 Subject: [PATCH 4/8] Updated rcon-client --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 51ee37db..9e8d861f 100644 --- a/package.json +++ b/package.json @@ -56,20 +56,20 @@ "node-factorio-api": "^0.3.1-alpha", "node-forge": "^0.7.1", "prom-client": "^10.2.3", - "rcon-client": "^3.0.2", + "rcon-client": "^3.1.6", "request": "^2.83.0", "right-pad": "^1.0.1", "rmdir-sync": "^1.0.1", "sanitizer": "^0.1.3", "simple-git": "^1.96.0", "single-line-log": "^1.1.2", + "snyk": "^1.134.2", "socket.io": "^2.0.4", "socket.io-client": "^2.0.4", "socket.io-prometheus": "^0.2.1", "sync-request": "^4.0.1", "typescript-collections": "^1.3.2", - "underscore": "^1.8.3", - "snyk": "^1.134.2" + "underscore": "^1.8.3" }, "devDependencies": { "documentation": "^5.4.0", From f35be2f355e3937a76c1c283157be3fd57ffa4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vest=C3=B8l?= Date: Fri, 5 Jul 2019 23:42:51 +0200 Subject: [PATCH 5/8] Set max pending rcon requests to 1 --- client.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client.js b/client.js index aded5348..5c6222c7 100644 --- a/client.js +++ b/client.js @@ -364,12 +364,14 @@ write-data=${ path.resolve(config.instanceDirectory, instance) }\r\n data = data.toString("utf8").replace(/(\r\n\t|\n|\r\t)/gm,""); console.log(data); if(data.includes("Starting RCON interface")){ - let client = new Rcon(); + let client = new Rcon({ + packetResponseTimeout: 2000, + maxPending: 1 + }); client.connect({ host: 'localhost', port: Number(process.env.RCONPORT) || instconf.clientPort, - password: instconf.clientPassword, - timeout: 5000 + password: instconf.clientPassword }); client.onDidAuthenticate(() => { console.log('Clusterio | RCON Authenticated!'); From a122f2b09e78a43e62fd87921c120be026010b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vest=C3=B8l?= Date: Sat, 6 Jul 2019 00:46:22 +0200 Subject: [PATCH 6/8] Increased rcon timeout to 20s, increased maxPending to 5 --- client.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client.js b/client.js index 5c6222c7..a0413bb3 100644 --- a/client.js +++ b/client.js @@ -365,8 +365,8 @@ write-data=${ path.resolve(config.instanceDirectory, instance) }\r\n console.log(data); if(data.includes("Starting RCON interface")){ let client = new Rcon({ - packetResponseTimeout: 2000, - maxPending: 1 + packetResponseTimeout: 20000, + maxPending: 5 }); client.connect({ host: 'localhost', From 6c32271c56897c345ad0f5d377b8d46b24949504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vest=C3=B8l?= Date: Sat, 6 Jul 2019 12:44:31 +0200 Subject: [PATCH 7/8] Fixed rcon timeout in the right place, set to 200s for 1250kB commands --- client.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/client.js b/client.js index a0413bb3..ce67a6a8 100644 --- a/client.js +++ b/client.js @@ -365,7 +365,7 @@ write-data=${ path.resolve(config.instanceDirectory, instance) }\r\n console.log(data); if(data.includes("Starting RCON interface")){ let client = new Rcon({ - packetResponseTimeout: 20000, + packetResponseTimeout: 200000, maxPending: 5 }); client.connect({ @@ -495,8 +495,10 @@ write-data=${ path.resolve(config.instanceDirectory, instance) }\r\n // connect to the server with rcon if(true || process.platform != "linux"){ // IP, port, password - client = new Rcon(); - + client = new Rcon({ + packetResponseTimeout: 200000, // 200s, should allow for commands up to 1250kB in length + maxPending: 5 + }); // check the logfile to see if the RCON interface is running as there is no way to continue without it // we read the log every 2 seconds and stop looping when we start connecting to factorio function checkRcon() { @@ -507,7 +509,6 @@ write-data=${ path.resolve(config.instanceDirectory, instance) }\r\n host: 'localhost', port: args["rcon-port"] || Number(process.env.RCONPORT) || instanceconfig.clientPort, password: args["rcon-password"] || instanceconfig.clientPassword, - timeout: 5000 }); } else { setTimeout(function(){ From 1f8ac50950095c1a86a2e6cf1ed8263154da1e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vest=C3=B8l?= Date: Tue, 9 Jul 2019 22:50:28 +0200 Subject: [PATCH 8/8] Better error message for statisticsExporter --- sharedPlugins/statisticsExporter/masterPlugin.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sharedPlugins/statisticsExporter/masterPlugin.js b/sharedPlugins/statisticsExporter/masterPlugin.js index 89b1a97b..7a5da91e 100644 --- a/sharedPlugins/statisticsExporter/masterPlugin.js +++ b/sharedPlugins/statisticsExporter/masterPlugin.js @@ -50,7 +50,10 @@ class masterPlugin { console.log(e) }; } else { - res.send("failure"); + res.send({ + ok:false, + msg:"Invalid request parameters" + }); } }); }