Remove inventoryImports plugin

Remove defunct and coding horror inventoryImports.  The functionality
provided in it should be added as an optional extra to subspace_storage.
This commit is contained in:
Hornwitser committed 2020-10-23 21:22:45 +02:00
1 parent 24397b75cc
commit e5e82ba2fb
10 files changed
-637

No files matched your search

-46
View File
@@ -1,46 +0,0 @@
/**
* Helper functions related to objects
* @module lib/objectOps
*/
"use strict";
/**
* Deep clones an object, is actually just JSON.parse(JSON.stringify()) but looks cleaner.
* @param {object} obj to clone
* @returns {object} The cloned object.
*
* @example
* a = {"thingy":"with a value"};
* b = a;
* a == b; // true
* c = objectOps.deepclone(a);
* a == c; // false
*/
module.exports.deepclone = function(obj){
return JSON.parse(JSON.stringify(obj));
};
/**
* Checks if a string is valid JSON using try/catch. If passed an object it will always return true.
* @param {string} string to verify
* @returns {boolean} true if valid JSON.
*
* @example
* objectOps.isJSON("99 bottles of beer"); // false
* objectOps.isJSON("99"); // true
* objectOps.isJSON({"thingy":"that is an object"}); // true
* objectOps.isJSON(JSON.stringify({"thingy":"that is an object"})); // true
*/
module.exports.isJSON = function(string){
let stringIsJson = false;
let x;
try {
x = JSON.parse(string);
} catch (e){
return false;
}
if (typeof x === "object" || typeof string === "object"){
stringIsJson = true;
}
return stringIsJson;
};
-18
View File
@@ -1,18 +0,0 @@
/*
This clusterio plugin is tasked to read your inventory and logistic request slots
it will then attempt to fulfill those requests using items provided by the master
server. There *should* be an in game GUI to toggle this.
*/
module.exports = {
// Name of package. For display somewhere I guess.
name: "inventoryImports",
version: "1.0.0",
arguments: ["index.js"],
description: "Clusterio plugin to fill character logistic slots with master imports",
// We'll send everything in this file to your stdin. Beware.
scriptOutputFileSubscription: "inventoryImports.txt",
fileReadDelay: 100,
}
-27
View File
@@ -1,27 +0,0 @@
const needle = require("needle");
const isJson = require("./isJson");
const pluginConfig = require("./config");
const functions = require("./interfacingFunctions");
// poll inventories
class inventoryImports {
constructor(slaveConfig, messageInterface){
this.config = slaveConfig;
this.messageInterface = messageInterface;
messageInterface("/silent-command game.print('InventoryImports enabled')");
setInterval(function(){
// messageInterface("Polling inventories\n")
messageInterface(functions.pollInventories(pluginConfig.scriptOutputFileSubscription));
}, 10000);
}
scriptOutput(data){
if(data !== null && isJson(data)){
let inventory = JSON.parse(data);
// process inventory of players and ask master for more stuff
functions.handleInventory(inventory, this.config, this.messageInterface);
}
}
}
module.exports = inventoryImports;
@@ -1,149 +0,0 @@
const objectOps = require("@clusterio/lib/objectOps");
const needle = require("needle");
const pluginConfig = require("./config")
const isJson = require("./isJson")
function handleInventory(json, config, callback){
/*
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 = {};
// 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){
// because of the way we collect data in a keyed JSON object, this first part of the IF cannot happen.
/* istanbul ignore next */
if(confirmedItems[stack.name] && confirmedItems[stack.name] > 0){
confirmedItems[stack.name] += stack.count;
} else {
confirmedItems[stack.name] = stack.count;
}
}
if(itemsToConfirm == 0 && Object.keys(confirmedItems).length > 0){
// return LUA
callback(insertItemsFromObject(confirmedItems, playerNames[i]));
}
}
// 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
function callback(err, response, body) {
if (!err && response && response.body && (typeof response.body == "object" || isJson(response.body))) {
// confirmed orders, already removed from master inventory
//response.body.name: response.body.count
if(typeof response.body == "string") response.body = JSON.parse(response.body);
let stack = {name:response.body.name,count:Number(response.body.count)}
collectStacks(stack);
} else {
collectStacks(false);
}
}
needle.post(
config.masterURL + '/api/remove',
request,
{json:true,headers: {'x-access-token': config.masterAuthToken}},
callback
);
} else {
collectStacks(false);
}
});
}
}
// {"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.masterURL + '/api/place',
stackArray[i],
{headers: {'x-access-token': config.masterAuthToken}},
function (err, resp, body) {
// console.log(body);
}
);
}
}
});
}
} else return false; // inventory is falsey or a string
}
function insertItemsFromObject(confirmedItems, playerName){
// expeced input
// {["iron-plate"]:100, coal:20}
// make lua table
// we gotta construct a string because I can't find any nice library for this
if(playerName && confirmedItems){
if(typeof playerName != "string") {
throw new Error("playerName is: '"+typeof playerName+"' instead of string!");
}
let itemTable = "{";
Object.keys(confirmedItems).forEach(function(name){
let count = confirmedItems[name];
if(count > 0){
itemTable += '["'+name+'"]='+Math.floor(count)+',';
}
});
itemTable += "}";
let outputFile = pluginConfig.scriptOutputFileSubscription;
// a="'+players[i]+'"
// b='+itemTable+'
return '/silent-command local a="'+playerName+'"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,true,0)end';
}
}
function pollInventories(outputFile){
// 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={}local d="{inventory:{"for e,f in pairs(a)do d=d.."['+"'"+'"..e.."'+"'"+']:"..f..","end;for e,f in pairs(b)do d=d.."['+"'"+'"..e.."'+"'"+']:"..f..","end;d=d.."},requestSlots:{"for e,f in pairs(c)do d=d.."['+"'"+'"..e.."'+"'"+']:"..f..","end;d=d.."}}"game.write_file("'+pluginConfig.scriptOutputFileSubscription+'",d)');
// 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='+"'"+'{"players":{'+"'"+'local b=false;for c,d in pairs(game.players)do if d.connected and d.character 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={}local z={}for j,k in pairs(e)do if z[j] ~= nil then z[j] = z[j] + k else z[j] = k end end for j,k in pairs(f)do if z[j] ~= nil then z[j] = z[j] + k else z[j] = k end end 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(z)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,true,0)'
// Warning: This command is not in sync with lua commands.lua
return `/silent-command local a='{"players":{'local b=false;for c,d in pairs(game.players)do if d.connected and d.character then if b then a=a..','else b=true end;local e=game.players[c].get_inventory(defines.inventory.character_main).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;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,true,0)`
}
module.exports = {
handleInventory: handleInventory,
pollInventories: pollInventories,
insertItemsFromObject: insertItemsFromObject,
}
-11
View File
@@ -1,11 +0,0 @@
module.exports = function(x){
if(x === false || x === true || x === null) return true; // === false is valid JSON, so is true and null
var isNotJson = false
try{
JSON.parse(x);
} catch (e) {
isNotJson = true;
}
return !isNotJson;
}
@@ -1,181 +0,0 @@
-- WARNING: The commands in this file is not in sync with interfacingFunctions.js
-- Lua cheatsheet
/c game.write_file("test.txt",serpent.block(game.players["Danielv123"].get_quickbar().get_contents()))
/c game.write_file("test.txt",serpent.block(game.players["Danielv123"].get_inventory(defines.inventory.character_main).get_contents()))
-- print JSON of entire inventory and request slots to file
-- TODO: Get requester slot data as well
-- requester slot data is game.players.character.get_request_slot(slot)
-- returns {name="copper-plate", count=47} or nil if nothing is set
-- maybe game.players.character.item_requests? http://lua-api.factorio.com/latest/LuaEntity.html#LuaEntity.item_requests
/c
local requests = {}
for i = 1, game.player.force.character_logistic_slot_count do
requests[i] = game.players["Danielv123"].character.get_request_slot(i)
end
local o = "Requests: "
for k,v in pairs(requests) do
o = o..v["name"]..": "..v["count"]..", "
end
game.print(o)
-- sum up our inventory and request slots and print it as valid JSON
-- turns out the valid part is important
/c
local o = '{"players":{'
local notFirst = false
for a,b in pairs(game.players) do
if b.connected and b.character then
if notFirst then
o = o .. ','
else
notFirst = true
end
local inventory = game.players[a].get_inventory(defines.inventory.character_main).get_contents()
local quickbar = game.players[a].get_quickbar().get_contents()
--[[ Get contents of requester slots into a table ]]
local requests = {}
for i = 1, game.players[a].force.character_logistic_slot_count do
requests[i] = game.players[a].character.get_request_slot(i)
end
o = o..'"'..a..'":{"inventory":{'
--[[ generate JSON table ]]
local addComma = false
for k,v in pairs(inventory) do
if addComma then
o = o..','
else
addComma = true
end
o = o..'"'..k..'":'..v
end
for k,v in pairs(quickbar) do
if addComma then
o = o..','
else
addComma = true
end
o = o..'"'..k..'":'..v
end
o = o..'},"requestSlots":{'
addComma = false
for k,v in pairs(requests) do
if addComma then
o = o..','
else
addComma = true
end
o = o..'"'..v['name']..'":'..v['count']
end
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.."}}"
game.write_file("t.txt", o, true, 0)
game.print(o)
--[[
Example output
{"players":{"1":{"inventory":{"stone":12,"iron-ore":120,"raw-wood":10,"iron-plate":8,"steel-plate":480},"requestSlots":{}}}}
Minification procedure:
Run through https://mothereff.in/lua-minifier
Replace ' with '+"'"+'
Prepend /silent-command
remove game.print(o)
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.character_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,true,0)
-- 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.character_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
local a="{"for b,c in pairs(game.players)do local d=game.players[b].get_inventory(defines.inventory.character_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.print(a)
local a=game.players["Danielv123"].get_inventory(defines.inventory.character_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.print(e)
local inventory = game.players["Danielv123"].get_inventory(defines.inventory.character_main).get_contents()local quickbar = game.players["Danielv123"].get_quickbar().get_contents()local requests = {}for i = 1, game.player.force.character_logistic_slot_count do requests[i] = game.players["Danielv123"].character.get_request_slot(i) end local o = "{inventory:{" for k,v in pairs(inventory) do o = o.."['+"'"+'"..k.."'+"'"+']:"..v.."," end for k,v in pairs(quickbar) do o = o.."['+"'"+'"..k.."'+"'"+']:"..v.."," end o = o.."},requestSlots:{" for k,v in pairs(requests) do o = o.."['+"'"+'"..v["name"].."'+"'"+']:"..v["count"]..", " end o = o.."}}" game.write_file("test.txt", o,true,0)
-- insert items in players inventory and export leftovers
-- name should be players[i]
/c
local name = "1"
local items = {["iron-ore"]=30, ["steel-plate"]=120}
local items_failed = {}
if(game.players[name] and game.players[name].connected) then
for item,count in pairs(items) do
local i = game.players[name].insert{name=item,count=count}
if not items_failed[name] then
items_failed[name] = {}
end
if items_failed[name][item] then
items_failed[name][item] = items_failed[name][item] + count - i
else
items_failed[name][item] = count - i
end
end
game.write_file("t.txt", serpent.line({["exports"]=items_failed}, {["comment"]=false, ["compact"]=true}),true,0)
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,true,0)
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,true,0)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}),true,0)end
@@ -1,159 +0,0 @@
const assert = require("assert");
const child_process = require("child_process");
const functions = require("../interfacingFunctions");
const luamin = require("luamin");
const isFactorioCommand = require("@clusterio/lib/isFactorioCommand");
const nock = require("nock");
// sinon does weird prototype manipulation and so doen't need to be saved to anything.
require("mocha-sinon");
const sinon = require("sinon");
describe("inventoryImports/interfacingFunctions.js", function(){
describe("handleInventory(inventory, config)", function(){
let config = {
masterURL:"http://localhost:8080",
masterAuthToken:"",
}
it("returns false if given invalid input", function(){
assert(functions.handleInventory("this is a string") === false, "when given strings it should return false and do nothing");
});
it("Sends post requests and outputs factorio commands", function(done){
let inventory = {
"players":{
"Danielv123":{
"inventory":{
"stone":12,
"iron-ore":120,
"raw-wood":10,
"iron-plate":8,
"steel-plate":480
},
"requestSlots":{
"iron-plate":100,
"steel-plate":480,
"raw-wood":20,
"bullshit":0,
}
}
}
}
var scope = nock('http://localhost:8080')
.post('/api/remove', function(body){
// check that we are requesting the right things, () to convert to boolean
// 92 because 100 requested and 8 already in inventory
if(body.name == "iron-plate") assert(body.count == "92");
// nock wants us to return true if this is the correct body and we should reply
// if we return false we won't send a reply.
return true;
})
// nock destroys the endpoints after being hit once, this changes the number of hits required for destruction
.times(10)
// respond with JSON object instead of url query parameters
.reply(200,function(uri, req){
return req
},{
'Content-Type': 'application/json',
'Accept': 'application/json'
})
// nock logging statement .log((data) => console.log(data));
functions.handleInventory(inventory, config, callback);
function callback(x){
assert(x.includes(92) && x.includes("iron-plate"), "it should have included the items it was going to import");
assert(!x.includes("steel-plate"), "Inventory is already filled with steel so shouldn't be importing that");
assert(isFactorioCommand(x), "it should have returned a valid factorio command");
assert(x.includes('"Danielv123"'), "it should include the name of the player that will recieve the items");
done();
}
});
it("posts leftovers to master", function(done){
let inventory2 = {
"exports":{
"1":[
{"name":"iron-ore","count":1200},
{"name":"steel-plate","count":1337},
{"name":"copper-plate","count":0},
]
}
}
let timesRan = 0;
let callback = function(){
timesRan++
assert(timesRan <= 2, "placed more than 2 items, unexpeceted test result");
if(timesRan == 2){
done();
}
}
var scope = nock('http://localhost:8080')
.post('/api/place', function(body){
// check that we are requesting the right things
assert(body.name != "copper-plate", "copper plate should not be placed because it is 0");
assert(body.count > 0, "no need for placing 0 things");
assert(Number(body.count) != NaN, "count should be a number");
callback();
return true;
})
// nock destroys the endpoints after being hit once, this changes the number of hits required for destruction
.times(10)
.reply(200,"affirmative")
// if it tries using the nonexisting callback (argv 3) it will throw. It shoudln't.
assert.doesNotThrow(function(){
functions.handleInventory(inventory2, config);
}, "this here threw for some reason, remove assert.doesNotThrow for easier debugging of this issue");
});
});
describe("pollInventories(outputfile)", function(){
it("Returns a big factorio command as string", function(){
let x = functions.pollInventories("output.txt");
assert(typeof x == "string", "pollInventories() should always return a string");
assert(isFactorioCommand(x), "This is not a command factorio will accept, please prepend /c");
assert(x.length > 20, "LUA string seems to short, this ain't good");
});
it("Returns valid LUA", function(){
let x = functions.pollInventories("output.txt");
// remove string added to make factorio interpret as command
x = x.replace("/silent-command ","").replace("/c ","");
let y = false;
// luamin throws when it recieves something that is invalid LUA
assert.doesNotThrow(function(){
y = luamin.minify(x);
}, "Invalid LUA supplied");
assert(typeof y == "string", "luamin does not return string???");
assert(y.length > 20, "Minified LUA too short, something is up");
});
});
describe("insertItemsFromObject(object)", function(){
let testObject = {"copper-plate":100, "iron-ore":1337}
let playerName = "Danielv123"
it("Returns undefined if any of the parameters are missing", function(){
let x = functions.insertItemsFromObject();
assert(x === undefined);
let y = functions.insertItemsFromObject(testObject);
assert(y === undefined);
let z = functions.insertItemsFromObject(undefined, playerName);
assert(z === undefined);
});
it("Throws if player name is not a string", function(){
assert.throws(function(){
let x = functions.insertItemsFromObject(testObject, testObject);
}, Error("playerName is: 'object' instead of string!"));
});
it("Returns a big factorio command as string", function(){
let x = functions.insertItemsFromObject(testObject, playerName);
assert(typeof x == "string", "LUA returned should be a string");
assert(x.length > 20, "LUA strings are quite long");
assert(isFactorioCommand(x), "This is not a command factorio will accept, please prepend /c");
});
it("The returned string is a valid factorio command", function(){
let x = functions.insertItemsFromObject(testObject, playerName);
assert(isFactorioCommand(x) == true);
});
});
});
@@ -1,20 +0,0 @@
const isJson = require("../isJson");
const assert = require("assert");
describe("inventoryImports/isJson.js()", function(){
it("checks if a thing is valid JSON", function(){
assert(isJson("string") === false);
assert(isJson("{js_object_notation='very false'}") === false);
assert(isJson('{ "name":"John", "age":31, "city":"New York" }') === true, "This is valid JSON, lib disagrees");
});
it("recognizes that true and false are both valid JSON", function(){
assert(isJson(true) === true);
assert(isJson(false) === true);
});
it("Handles null as valid JSON (after spec)", function(){
assert(isJson(null) === true);
});
it("Recognizes that JSON doesn't allow trailing commas (,)", function(){
assert(isJson('["a", "b", ]') === false, "JSON should not allow trailing commas");
});
});
@@ -1,4 +0,0 @@
// These are libraries that does not have any units test, they are
// required here in order to track coverage for them.
require('../index');
-22
View File
@@ -1,22 +0,0 @@
"use strict";
var assert = require("assert");
var libObjectOps = require("@clusterio/lib/object_ops");
describe("lib/object_ops", function(){
describe("deepclone()", function(){
it("deep clones javascript objects", function(){
var obj1 = { hello: "world", cat: { legs: 4, name: "Kitty", colors: ["brown", "yellow", "purple"] }};
var obj2 = {};
obj2 = libObjectOps.deepclone(obj1);
obj1.cat.colors = "black";
assert.equal(obj1.cat.colors, "black");
assert.equal(obj2.cat.colors[1], "yellow");
});
it("throws on non JSON parameters", function(){
assert.throws(function(){
let y = libObjectOps.deepclone(libObjectOps.deepclone);
});
});
});
});