mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 15:14:52 +09:00
Working inventory imports resolves #50
This commit is contained in:
1 parent
f9a2e8519b
commit
c4ead8c699
3 files changed
+181
-96
No files matched your search
@@ -4,25 +4,26 @@ const pluginConfig = require("./config.js");
|
||||
|
||||
const functions = require("./interfacingFunctions");
|
||||
|
||||
console.log("/silent-command game.print('InventoryImports enabled')\n");
|
||||
console.log("/silent-command game.print('InventoryImports enabled')");
|
||||
|
||||
var config = {};
|
||||
process.stdin.setEncoding('utf8');
|
||||
process.stdin.on('readable', () => {
|
||||
var chunk = process.stdin.read();
|
||||
console.log(chunk)
|
||||
if (chunk !== null && isNaN(chunk) && config && !isJson(chunk)){
|
||||
// console.log(chunk)
|
||||
if (chunk !== null && isNaN(chunk) && config && isJson(chunk) && !JSON.parse(chunk).factorioPort){
|
||||
// example chunk Stdout: {1:{inventory:{['iron-ore']:100,['steel-plate']:5800,['iron-ore']:50,},
|
||||
// requestSlots:{['underground-belt']:50, ['fast-transport-belt']:50, ['express-underground-belt']:50, ['underground-belt']:50, }},}
|
||||
// returns JS object, throws if there are syntax errors in input string
|
||||
let inventory = functions.parseJsString(chunk);
|
||||
console.log(inventory);
|
||||
// let inventory = functions.parseJsString(chunk);
|
||||
let inventory = JSON.parse(chunk)
|
||||
// console.log(inventory);
|
||||
// process inventory of players and ask master for more stuff
|
||||
functions.handleInventory(inventory, config);
|
||||
} else if(isJson(chunk) && JSON.parse(chunk).factorioPort){
|
||||
config = JSON.parse(chunk);
|
||||
// if its a LUA table message returning with the exports send em off to master
|
||||
} else if(!isJson(chunk) && !!chunk && config){
|
||||
}/* else if(!isJson(chunk) && !!chunk && config){
|
||||
let thing = functions.parseJsString(chunk.replace(/=/g, ":"));
|
||||
Object.keys(thing).forEach(function(playerName){
|
||||
Object.keys(thing[playerName]).forEach(function(itemName){
|
||||
@@ -34,7 +35,7 @@ process.stdin.on('readable', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}*/
|
||||
});
|
||||
process.stdin.on('end', () => {
|
||||
process.stdout.write('end');
|
||||
@@ -42,6 +43,6 @@ process.stdin.on('end', () => {
|
||||
|
||||
// poll inventories
|
||||
setInterval(function(){
|
||||
console.log("Polling inventories")
|
||||
// console.log("Polling inventories\n")
|
||||
console.log(functions.pollInventories(pluginConfig.scriptOutputFileSubscription));
|
||||
}, 10000);
|
||||
@@ -1,5 +1,6 @@
|
||||
const objectOps = require("../../lib/objectOps.js");
|
||||
const needle = require("needle");
|
||||
const pluginConfig = require("./config")
|
||||
|
||||
// returns JS object, throws if there are syntax errors in input string
|
||||
function parseJsString(string){
|
||||
@@ -28,90 +29,104 @@ function parseJsString(string){
|
||||
}}}
|
||||
*/
|
||||
}
|
||||
function handleInventory(inventory, config){
|
||||
// we want to seperate players, parse their inventory and compare to request slots
|
||||
// then ask master for the difference
|
||||
// we must then prepare it all and inject it into players inventories with lua before
|
||||
// the next inventory report arrives to avoid duplicating orders
|
||||
if(inventory && typeof inventory != "string" && typeof inventory == "object"){
|
||||
function handleInventory(json, config){
|
||||
/*
|
||||
json is one of these two samples
|
||||
{"players":{"1":{"inventory":{"stone":12,"iron-ore":120,"raw-wood":10,"iron-plate":8,"steel-plate":480},"requestSlots":{}}}}
|
||||
{"exports":{"1":[{"name":"iron-ore","count":0},{"name":"steel-plate","count":0}]}}
|
||||
|
||||
we want to seperate players, parse their json and compare to request slots
|
||||
then ask master for the difference
|
||||
we must then prepare it all and inject it into players inventories with lua before
|
||||
the next json report arrives to avoid duplicating orders
|
||||
*/
|
||||
if(json && typeof json != "string" && typeof json == "object"){
|
||||
let exports = {};
|
||||
let players = Object.keys(inventory);
|
||||
for(let i = 0; i < players.length; i++) {
|
||||
let pinv = inventory[players[i]];
|
||||
// create a copy of player.requestSlots
|
||||
let toRequest = objectOps.deepclone(pinv.requestSlots);
|
||||
// create a place to store the object we have confirmed for importing
|
||||
let confirmedItems = {};
|
||||
let itemsToConfirm = Object.keys(pinv.inventory).length;
|
||||
|
||||
// subtract items already in inventory
|
||||
Object.keys(pinv.inventory).forEach(function(key){
|
||||
let itemCount = pinv.inventory[key];
|
||||
if(toRequest[key]){
|
||||
toRequest[key] -= itemCount;
|
||||
}
|
||||
if(toRequest[key] > 0){
|
||||
let request = {
|
||||
name:key,
|
||||
count:toRequest[key],
|
||||
}
|
||||
// request the difference from master
|
||||
needle.post(config.masterIP + ":" + config.masterPort + '/api/remove', request, function (err, response, body) {
|
||||
if (response && response.body && typeof response.body == "object") {
|
||||
// confirmed orders, already removed from master inventory
|
||||
//response.body.name: response.body.count
|
||||
let stack = {name:response.body.name,count:response.body.count}
|
||||
collectStacks(stack);
|
||||
|
||||
// this is an inventory report, check whats missing and request from master
|
||||
// {"players":{"1":{"inventory":{"stone":12,"iron-ore":120,"raw-wood":10,"iron-plate":8,"steel-plate":480},"requestSlots":{}}}}
|
||||
if(json.players){
|
||||
let playerNames = Object.keys(json.players);
|
||||
for(let i = 0; i < playerNames.length; i++) {
|
||||
// haha, this turned into bit of a mess didn't it?
|
||||
let playerInv = json.players[playerNames[i]];
|
||||
// create a copy of player.requestSlots
|
||||
let toRequest = objectOps.deepclone(playerInv.requestSlots);
|
||||
let inventory = playerInv.inventory;
|
||||
let itemsToConfirm = Object.keys(toRequest).length;
|
||||
// create a place to store the object we have confirmed for importing
|
||||
let confirmedItems = {};
|
||||
let collectStacks = function(stack){
|
||||
itemsToConfirm--;
|
||||
if(stack){
|
||||
if(confirmedItems[stack.name]){
|
||||
confirmedItems[stack.name] += stack.count;
|
||||
} else {
|
||||
collectStacks(false);
|
||||
confirmedItems[stack.name] = stack.count;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
function collectStacks(stack){
|
||||
itemsToConfirm--;
|
||||
if(stack){
|
||||
if(confirmedItems[stack.name]){
|
||||
confirmedItems[stack.name] += stack.count;
|
||||
} else {
|
||||
confirmedItems[stack.name] = stack.count;
|
||||
}
|
||||
if(itemsToConfirm == 0 && Object.keys(confirmedItems).length > 0){
|
||||
// make lua table
|
||||
// we gotta construct a string because I can't find any nice library for this
|
||||
let itemTable = "{";
|
||||
Object.keys(confirmedItems).forEach(function(name){
|
||||
let count = confirmedItems[name];
|
||||
itemTable += '["'+name+'"]='+count+',';
|
||||
});
|
||||
itemTable += "}";
|
||||
let outputFile = pluginConfig.scriptOutputFileSubscription;
|
||||
// a="'+players[i]+'"
|
||||
// b='+itemTable+'
|
||||
console.log('/silent-command local a="'+playerNames[i]+'"local b='+itemTable+'local c={}if game.players[a]and game.players[a].connected then local d='+"'"+'{"exports":{"'+"'"+'..a..'+"'"+'":['+"'"+'local e=false;for f,g in pairs(b)do local h=game.players[a].insert{name=f,count=g}if e then d=d..'+"'"+','+"'"+'else e=true end;d=d..'+"'"+'{"name":"'+"'"+'..f..'+"'"+'","count":'+"'"+'..g-h..'+"'"+'}'+"'"+'end;d=d..'+"'"+']}}'+"'"+'game.write_file("'+outputFile+'",d)end');
|
||||
}
|
||||
}
|
||||
if(itemsToConfirm <= 0){
|
||||
// make lua table
|
||||
// we gotta construct a string because I can't find any nice library for this
|
||||
let itemTable = "{";
|
||||
Object.keys(confirmedItems).forEach(function(name){
|
||||
let count = confirmedItems[name];
|
||||
itemTable += '["'+name+'"]='+count+',';
|
||||
});
|
||||
itemTable += "}";
|
||||
|
||||
console.log('/c local a="'+players[i]+'"local b='+itemTable+'local c={}if game.players[a]and game.players[a].connected then for d,e in pairs(b)do local f=game.players[a].insert{name=d,count=e}if not c[a]then c[a]={}end;if c[a][d]then c[a][d]=c[a][d]+e-f else c[a][d]=e-f end end;game.write_file("'+outputFile+'",serpent.line(c,{["comment"]=false,["compact"]=true}))end');
|
||||
}
|
||||
}
|
||||
|
||||
// handle exports (why would they be there? I don't know!)
|
||||
if(pinv.exports){
|
||||
Object.keys(pinv.exports).forEach(function(name){
|
||||
if(exports[name]){
|
||||
exports[name] += pinv.exports[name];
|
||||
// subtract items already in inventory
|
||||
Object.keys(playerInv.requestSlots).forEach(function(key){
|
||||
// if this item in inventory is also in a request slot, subtract invCount from requestCount
|
||||
if(inventory[key]){
|
||||
toRequest[key] -= inventory[key];
|
||||
}
|
||||
// if the difference is more than 0, request item from master
|
||||
if(toRequest[key] > 0){
|
||||
let request = {
|
||||
name:key,
|
||||
count:toRequest[key],
|
||||
}
|
||||
//console.log("Requesting: "+JSON.stringify(request));
|
||||
// request the difference from master
|
||||
needle.post(config.masterIP + ":" + config.masterPort + '/api/remove', request, function (err, response, body) {
|
||||
if (response && response.body && typeof response.body == "object") {
|
||||
// confirmed orders, already removed from master inventory
|
||||
//response.body.name: response.body.count
|
||||
let stack = {name:response.body.name,count:Number(response.body.count)}
|
||||
collectStacks(stack);
|
||||
} else {
|
||||
collectStacks(false);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
exports[name] = pinv.exports[name];
|
||||
collectStacks(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// keep handling exports here, now we send em off
|
||||
Object.keys(exports).forEach(function(name){
|
||||
needle.post(config.masterIP + ":" + config.masterPort + '/api/place', {
|
||||
name: name,
|
||||
count: exports[name]
|
||||
}, function (err, resp, body) {
|
||||
// console.log(body);
|
||||
// {"exports":{"1":[{"name":"iron-ore","count":0},{"name":"steel-plate","count":0}]}}
|
||||
// this is a report of stuff we didn't have space for, send back to master
|
||||
if(json.exports){
|
||||
// loop over players (normally only one, but whatever)
|
||||
Object.keys(json.exports).forEach(function(playerName){
|
||||
// loop over simpleItemStacks to export
|
||||
let stackArray = json.exports[playerName];
|
||||
for(let i = 0; i < stackArray.length; i++){
|
||||
if(stackArray[i].count > 0){
|
||||
console.log("Returning overflow: " + JSON.stringify(stackArray[i]));
|
||||
needle.post(config.masterIP + ":" + config.masterPort + '/api/place', stackArray[i], function (err, resp, body) {
|
||||
// console.log(body);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
} else return false; // inventory is falsey or a string
|
||||
}
|
||||
function pollInventories(outputFile){
|
||||
@@ -119,7 +134,8 @@ function pollInventories(outputFile){
|
||||
// console.log("Running inventory LUA")
|
||||
//console.log("/silent-command "+'local a=game.players["Danielv123"].get_inventory(defines.inventory.player_main).get_contents()local b=game.players["Danielv123"].get_quickbar().get_contents()local c={}for d=1,game.players["Danielv123"].force.character_logistic_slot_count do c[d]=game.players["Danielv123"].character.get_request_slot(d)end;local e="{inventory:{"for f,g in pairs(a)do e=e.."['+"'"+'"..f.."'+"'"+']:"..g..","end;for f,g in pairs(b)do e=e.."['+"'"+'"..f.."'+"'"+']:"..g..","end;e=e.."},requestSlots:{"for f,g in pairs(c)do e=e.."['+"'"+'"..g["name"].."'+"'"+']:"..g["count"]..", "end;e=e.."}}"game.write_file("'+pluginConfig.scriptOutputFileSubscription+'",e)')
|
||||
// console.log("/silent-command "+'local a="{"for b,c in pairs(game.players)do local d=game.players[b].get_inventory(defines.inventory.player_main).get_contents()local e=game.players[b].get_quickbar().get_contents()local f={}for g=1,game.players[b].force.character_logistic_slot_count do f[g]=game.players[b].character.get_request_slot(g)end;a=a..b..":{inventory:{"for h,i in pairs(d)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;for h,i in pairs(e)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;a=a.."},requestSlots:{"for h,i in pairs(f)do a=a.."['+"'"+'"..i["name"].."'+"'"+']:"..i["count"]..", "end;a=a.."}},"end;a=a.."}"game.write_file("'+pluginConfig.scriptOutputFileSubscription+'",a)')
|
||||
return "/silent-command "+'local a="{"for b,c in pairs(game.players)do if c.connected then local d=game.players[b].get_inventory(defines.inventory.player_main).get_contents()local e=game.players[b].get_quickbar().get_contents()local f={}for g=1,game.players[b].force.character_logistic_slot_count do f[g]=game.players[b].character.get_request_slot(g)end;a=a..b..":{inventory:{"for h,i in pairs(d)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;for h,i in pairs(e)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;a=a.."},requestSlots:{"for h,i in pairs(f)do a=a.."['+"'"+'"..i["name"].."'+"'"+']:"..i["count"]..", "end;a=a.."}},"end end;a=a.."}"game.write_file("'+outputFile+'",a)'
|
||||
//return "/silent-command "+'local a="{"for b,c in pairs(game.players)do if c.connected then local d=game.players[b].get_inventory(defines.inventory.player_main).get_contents()local e=game.players[b].get_quickbar().get_contents()local f={}for g=1,game.players[b].force.character_logistic_slot_count do f[g]=game.players[b].character.get_request_slot(g)end;a=a..b..":{inventory:{"for h,i in pairs(d)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;for h,i in pairs(e)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;a=a.."},requestSlots:{"for h,i in pairs(f)do a=a.."['+"'"+'"..i["name"].."'+"'"+']:"..i["count"]..", "end;a=a.."}},"end end;a=a.."}"game.write_file("'+outputFile+'",a)'
|
||||
return '/silent-command '+'local a='+"'"+'{"players":{'+"'"+'local b=false;for c,d in pairs(game.players)do if d.connected then if b then a=a..'+"'"+','+"'"+'else b=true end;local e=game.players[c].get_inventory(defines.inventory.player_main).get_contents()local f=game.players[c].get_quickbar().get_contents()local g={}for h=1,game.players[c].force.character_logistic_slot_count do g[h]=game.players[c].character.get_request_slot(h)end;a=a..'+"'"+'"'+"'"+'..c..'+"'"+'":{"inventory":{'+"'"+'local i=false;for j,k in pairs(e)do if i then a=a..'+"'"+','+"'"+'else i=true end;a=a..'+"'"+'"'+"'"+'..j..'+"'"+'":'+"'"+'..k end;for j,k in pairs(f)do if i then a=a..'+"'"+','+"'"+'else i=true end;a=a..'+"'"+'"'+"'"+'..j..'+"'"+'":'+"'"+'..k end;a=a..'+"'"+'},"requestSlots":{'+"'"+'i=false;for j,k in pairs(g)do if i then a=a..'+"'"+','+"'"+'else i=true end;a=a..'+"'"+'"'+"'"+'..k['+"'"+'name'+"'"+']..'+"'"+'":'+"'"+'..k['+"'"+'count'+"'"+']end;a=a..'+"'"+'}}'+"'"+'end end;a=a.."}}"game.write_file("'+outputFile+'",a)'
|
||||
/*
|
||||
needle.post(config.masterIP+':'+config.masterPort+'/api/editSlaveMeta', {slaveID: config.unique, password: config.clientPassword, meta: {UPS:UPS}}, function(err, resp) {
|
||||
// success?
|
||||
|
||||
@@ -22,11 +22,18 @@ for k,v in pairs(requests) do
|
||||
end
|
||||
game.print(o)
|
||||
|
||||
-- sum up our inventory and request slots
|
||||
-- sum up our inventory and request slots and print it as valid JSON
|
||||
-- turns out the valid part is important
|
||||
/c
|
||||
local o = "{"
|
||||
local o = '{"players":{'
|
||||
local notFirst = false
|
||||
for a,b in pairs(game.players) do
|
||||
if b.connected then
|
||||
if notFirst then
|
||||
o = o .. ','
|
||||
else
|
||||
notFirst = true
|
||||
end
|
||||
local inventory = game.players[a].get_inventory(defines.inventory.player_main).get_contents()
|
||||
local quickbar = game.players[a].get_quickbar().get_contents()
|
||||
--[[ Get contents of requester slots into a table ]]
|
||||
@@ -35,27 +42,46 @@ for a,b in pairs(game.players) do
|
||||
requests[i] = game.players[a].character.get_request_slot(i)
|
||||
end
|
||||
|
||||
o = o..a..":{inventory:{"
|
||||
--[[ generate JS table (not JSON) ]]
|
||||
o = o..'"'..a..'":{"inventory":{'
|
||||
--[[ generate JSON table ]]
|
||||
local addComma = false
|
||||
for k,v in pairs(inventory) do
|
||||
o = o.."['"..k.."']:"..v..","
|
||||
if addComma then
|
||||
o = o..','
|
||||
else
|
||||
addComma = true
|
||||
end
|
||||
o = o..'"'..k..'":'..v
|
||||
end
|
||||
for k,v in pairs(quickbar) do
|
||||
o = o.."['"..k.."']:"..v..","
|
||||
if addComma then
|
||||
o = o..','
|
||||
else
|
||||
addComma = true
|
||||
end
|
||||
o = o..'"'..k..'":'..v
|
||||
end
|
||||
|
||||
o = o.."},requestSlots:{"
|
||||
o = o..'},"requestSlots":{'
|
||||
addComma = false
|
||||
for k,v in pairs(requests) do
|
||||
o = o.."['"..v["name"].."']:"..v["count"]..", "
|
||||
if addComma then
|
||||
o = o..','
|
||||
else
|
||||
addComma = true
|
||||
end
|
||||
o = o..'"'..v['name']..'":'..v['count']
|
||||
end
|
||||
o = o.."}},"
|
||||
o = o..'}}' --[[ We need a comma after these two if there is more than 1 player, handled up top by notFirst]]
|
||||
end
|
||||
end
|
||||
o = o.."}"
|
||||
o = o.."}}"
|
||||
game.write_file("t.txt", o)
|
||||
game.print(o)
|
||||
game.write_file("test.txt", o)
|
||||
|
||||
--[[
|
||||
Example output
|
||||
{"players":{"1":{"inventory":{"stone":12,"iron-ore":120,"raw-wood":10,"iron-plate":8,"steel-plate":480},"requestSlots":{}}}}
|
||||
|
||||
Minification procedure:
|
||||
|
||||
@@ -63,12 +89,13 @@ Run through https://mothereff.in/lua-minifier
|
||||
Replace ' with '+"'"+'
|
||||
Prepend /silent-command
|
||||
remove game.print(o)
|
||||
replace "test.txt" with "'+outputFile+'"
|
||||
replace "t.txt" with "'+outputFile+'"
|
||||
enclose in ''
|
||||
|
||||
]]
|
||||
|
||||
-- minified strings (newest on the top)
|
||||
local a='+"'"+'{"players":{'+"'"+'local b=false;for c,d in pairs(game.players)do if d.connected then if b then a=a..'+"'"+','+"'"+'else b=true end;local e=game.players[c].get_inventory(defines.inventory.player_main).get_contents()local f=game.players[c].get_quickbar().get_contents()local g={}for h=1,game.players[c].force.character_logistic_slot_count do g[h]=game.players[c].character.get_request_slot(h)end;a=a..'+"'"+'"'+"'"+'..c..'+"'"+'":{"inventory":{'+"'"+'local i=false;for j,k in pairs(e)do if i then a=a..'+"'"+','+"'"+'else i=true end;a=a..'+"'"+'"'+"'"+'..j..'+"'"+'":'+"'"+'..k end;for j,k in pairs(f)do if i then a=a..'+"'"+','+"'"+'else i=true end;a=a..'+"'"+'"'+"'"+'..j..'+"'"+'":'+"'"+'..k end;a=a..'+"'"+'},"requestSlots":{'+"'"+'i=false;for j,k in pairs(g)do if i then a=a..'+"'"+','+"'"+'else i=true end;a=a..'+"'"+'"'+"'"+'..k['+"'"+'name'+"'"+']..'+"'"+'":'+"'"+'..k['+"'"+'count'+"'"+']end;a=a..'+"'"+'}}'+"'"+'end end;a=a.."}}"game.write_file("'+outputFile+'",a)
|
||||
-- offline playes
|
||||
local a="{"for b,c in pairs(game.players)do if c.connected then local d=game.players[b].get_inventory(defines.inventory.player_main).get_contents()local e=game.players[b].get_quickbar().get_contents()local f={}for g=1,game.players[b].force.character_logistic_slot_count do f[g]=game.players[b].character.get_request_slot(g)end;a=a..b..":{inventory:{"for h,i in pairs(d)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;for h,i in pairs(e)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;a=a.."},requestSlots:{"for h,i in pairs(f)do a=a.."['+"'"+'"..i["name"].."'+"'"+']:"..i["count"]..", "end;a=a.."}},"end end;a=a.."}"game.print(a)
|
||||
-- multiple players
|
||||
@@ -81,7 +108,7 @@ local inventory = game.players["Danielv123"].get_inventory(defines.inventory.pla
|
||||
-- name should be players[i]
|
||||
|
||||
/c
|
||||
local name = "Danielv123"
|
||||
local name = "1"
|
||||
local items = {["iron-ore"]=30, ["steel-plate"]=120}
|
||||
local items_failed = {}
|
||||
if(game.players[name] and game.players[name].connected) then
|
||||
@@ -96,17 +123,58 @@ if(game.players[name] and game.players[name].connected) then
|
||||
items_failed[name][item] = count - i
|
||||
end
|
||||
end
|
||||
game.write_file("t.txt", serpent.line(items_failed, {["comment"]=false, ["compact"]=true}))
|
||||
game.write_file("t.txt", serpent.line({["exports"]=items_failed}, {["comment"]=false, ["compact"]=true}))
|
||||
end
|
||||
|
||||
--[[
|
||||
Writes something like
|
||||
|
||||
{exports={["1"]={["iron-ore"]=0,["steel-plate"]=0}}}
|
||||
|
||||
converting to JS would be
|
||||
replace "[" and "]" with ""???
|
||||
replace "=" with ":"
|
||||
]]
|
||||
|
||||
--[[
|
||||
JSON edition
|
||||
|
||||
{"exports":{"1":[{"name":"iron-ore","count":0},{"name":"steel-plate","count":0}]}}
|
||||
|
||||
Should always return valid JSON
|
||||
]]
|
||||
/c
|
||||
local name = "1"
|
||||
local items = {["iron-ore"]=30, ["steel-plate"]=120}
|
||||
if(game.players[name] and game.players[name].connected) then
|
||||
local o = '{"exports":{"'..name..'":['
|
||||
local addComma = false
|
||||
for item,count in pairs(items) do
|
||||
local i = game.players[name].insert{name=item,count=count}
|
||||
if addComma then
|
||||
o = o..','
|
||||
else
|
||||
addComma = true
|
||||
end
|
||||
o = o .. '{"name":"'..item..'","count":'..count - i..'}'
|
||||
end
|
||||
o = o .. ']}}'
|
||||
game.write_file("t.txt", o)
|
||||
end
|
||||
|
||||
--[[
|
||||
Minification procedure:
|
||||
|
||||
Run through https://mothereff.in/lua-minifier
|
||||
Replace ' with '+"'"+'
|
||||
Prepend /silent-command
|
||||
replace "t.txt" with "'+outputFile+'"
|
||||
enclose in ''
|
||||
]]
|
||||
|
||||
|
||||
-- JSON outputFile
|
||||
local a="1"local b={["iron-ore"]=30,["steel-plate"]=120}local c={}if game.players[a]and game.players[a].connected then local d='+"'"+'{"exports":{"'+"'"+'..a..'+"'"+'":['+"'"+'local e=false;for f,g in pairs(b)do local h=game.players[a].insert{name=f,count=g}if e then d=d..'+"'"+','+"'"+'else e=true end;d=d..'+"'"+'{"name":"'+"'"+'..f..'+"'"+'","count":'+"'"+'..g-h..'+"'"+'}'+"'"+'end;d=d..'+"'"+']}}'+"'"+'game.write_file("'+outputFile+'",d)end
|
||||
-- output to serpented LUA table
|
||||
local a="Danielv123"local b={["iron-ore"]=30,["steel-plate"]=120}local c={}if game.players[a]and game.players[a].connected then for d,e in pairs(b)do local f=game.players[a].insert{name=d,count=e}if not c[a]then c[a]={}end;if c[a][d]then c[a][d]=c[a][d]+e-f else c[a][d]=e-f end end;game.write_file("'+outputFile+'",serpent.line(c,{["comment"]=false,["compact"]=true}))end
|
||||
|
||||
Reference in new issue
Block a user