401 lines
15 KiB
JavaScript
401 lines
15 KiB
JavaScript
#!/usr/bin/djs
|
|
"use strict";
|
|
|
|
(function(constants, libassets, liblang){
|
|
const me = {'tasks':{}, 'parsing':{},'sanatizing':{}};
|
|
|
|
const note = function() {
|
|
var args = ["[note]"];
|
|
for(var i in arguments) args.push(arguments[i]);
|
|
print.apply(this, args);
|
|
}
|
|
const warn = function() {
|
|
var args = ["[warn]"];
|
|
for(var i in arguments) args.push(arguments[i]);
|
|
print.apply(this, args);
|
|
}
|
|
const pass = function() {
|
|
var args = ["[pass]"];
|
|
for(var i in arguments) args.push(arguments[i]);
|
|
print.apply(this, args);
|
|
}
|
|
const fail = function() {
|
|
var args = ["[fail]"];
|
|
for(var i in arguments) args.push(arguments[i]);
|
|
print.apply(this, args);
|
|
}
|
|
|
|
me.tasks.map_regnames_blockstate_filenames = function() {
|
|
const cwd = fs.cwd();
|
|
const rnmap = constants.registryname_map_112_114;
|
|
if(rnmap === undefined) {
|
|
note("Blockstate file renaming skipped, no mapping defined.");
|
|
return;
|
|
}
|
|
try {
|
|
if(!fs.chdir(constants.local_assets_root()+"/blockstates")) throw new Error("Failed to switch to blockstates dir.");
|
|
for(var oldname in rnmap) {
|
|
const oldfile = oldname+".json";
|
|
const newfile = rnmap[oldname]+".json";
|
|
if(oldfile==newfile) continue;
|
|
if(fs.isfile(oldname+".json")) {
|
|
if(fs.isfile(newfile)) {
|
|
note("blockstate file skipped: '" + oldfile + "' -> '" + newfile + "' (new file already exists)");
|
|
} else if(!fs.rename(oldfile, newfile)) {
|
|
note("blockstate file rename failed: '" + oldfile + "' -> '" + newfile + "'");
|
|
} else {
|
|
note("blockstate file: '" + oldfile + "' -> '" + newfile + "'");
|
|
}
|
|
}
|
|
}
|
|
pass("Blockstate file renaming done.");
|
|
} catch(ex) {
|
|
fail("Blockstate file renaming failed:"+ex);
|
|
} finally {
|
|
fs.chdir(cwd);
|
|
}
|
|
};
|
|
|
|
me.tasks.map_regnames_lang_file_keys = function() {
|
|
const cwd = fs.cwd();
|
|
const rnmap = constants.registryname_map_112_114;
|
|
const block_prefix = "block." + constants.modid + ".";
|
|
const item_prefix = "item." + constants.modid + ".";
|
|
try {
|
|
if(!fs.chdir(constants.local_assets_root()+"/lang")) throw new Error("Failed to switch to lang dir.");
|
|
const langfiles = fs.readdir();
|
|
for(var i_langfile in langfiles) {
|
|
const original_lang = JSON.parse(fs.readfile(langfiles[i_langfile]));
|
|
const replaced_lang = {}
|
|
for(var key in original_lang) {
|
|
if(key.search(block_prefix)===0) {
|
|
const regname = key.replace(block_prefix,"").replace(/[\.].*$/,"");
|
|
if(rnmap[regname] !== undefined) {
|
|
const sfind = block_prefix + regname;
|
|
const srepl = block_prefix + rnmap[regname];
|
|
const newkey = key.replace(sfind, srepl);
|
|
replaced_lang[newkey] = original_lang[key];
|
|
continue;
|
|
}
|
|
} else if(key.search(item_prefix)===0) {
|
|
const regname = key.replace(item_prefix,"").replace(/[\.].*$/,"");
|
|
if(rnmap[regname] !== undefined) {
|
|
const sfind = item_prefix + regname;
|
|
const srepl = item_prefix + rnmap[regname];
|
|
const newkey = key.replace(sfind, srepl);
|
|
replaced_lang[newkey] = original_lang[key];
|
|
continue;
|
|
}
|
|
}
|
|
// replacements must continue
|
|
replaced_lang[key] = original_lang[key];
|
|
}
|
|
fs.writefile(langfiles[i_langfile], JSON.stringify(replaced_lang,null,1));
|
|
}
|
|
pass("Lang file key mappings done.");
|
|
} catch(ex) {
|
|
warn("Lang file key mapping failed:"+ex);
|
|
} finally {
|
|
fs.chdir(cwd);
|
|
}
|
|
};
|
|
|
|
me.tasks.patch_texture_paths_in_models = function() {
|
|
const cwd = fs.cwd();
|
|
const replacements = {};
|
|
replacements['"' + constants.modid+":blocks/"] = '"' + constants.modid+":block/"
|
|
try {
|
|
if(!fs.chdir(constants.local_assets_root()+"/models")) throw new Error("Failed to switch to models dir.");
|
|
fs.find(".", "*.json", function(path){
|
|
const original_text = fs.readfile(path);
|
|
var replaced_text = ""+original_text;
|
|
JSON.parse(replaced_text); // to throw on load error
|
|
for(var sfind in replacements) replaced_text = replaced_text.split(sfind).join(replacements[sfind]);
|
|
if(replaced_text !== original_text) {
|
|
note("Replacements in model '"+path+"'");
|
|
fs.writefile(path, replaced_text);
|
|
}
|
|
return false;
|
|
});
|
|
pass("Model file texture paths done.");
|
|
} catch(ex) {
|
|
fail("Model file texture paths failed:"+ex);
|
|
} finally {
|
|
fs.chdir(cwd);
|
|
}
|
|
};
|
|
|
|
me.tasks.create_missing_block_items = function() {
|
|
const cwd = fs.cwd();
|
|
const blockstate_models = {};
|
|
try {
|
|
if(!fs.chdir(constants.local_assets_root())) throw new Error("Failed to switch to assets dir.");
|
|
fs.find("blockstates", "*.json", function(path){
|
|
const blockstate = fs.basename(path).replace(".json","");
|
|
const json = JSON.parse(fs.readfile(path));
|
|
if(json["forge_marker"] !== undefined) {
|
|
var model = json["defaults"]["model"];
|
|
if(model.search(constants.modid+":block/") < 0) {
|
|
model = model.replace(constants.modid+":", constants.modid+":block/");
|
|
}
|
|
blockstate_models[blockstate] = model;
|
|
}
|
|
if(blockstate_models[blockstate] === undefined) {
|
|
throw new Error("IMPLEMENT use first found model.");
|
|
}
|
|
return false;
|
|
});
|
|
for(var blockstate in blockstate_models) {
|
|
const item_model_file = "models/item/"+blockstate+".json";
|
|
if(fs.isfile(item_model_file)) continue;
|
|
if(!fs.writefile(item_model_file, JSON.stringify({parent:blockstate_models[blockstate]}))) {
|
|
throw new Error("Failed to write item model file '" + item_model_file + "'");
|
|
}
|
|
}
|
|
pass("Missing item models done.");
|
|
} catch(ex) {
|
|
fail("Missing item models failed:"+ex);
|
|
} finally {
|
|
fs.chdir(cwd);
|
|
}
|
|
};
|
|
|
|
me.tasks.patch_registry_names_in_java_files = function() {
|
|
const cwd = fs.cwd();
|
|
const rnmap = constants.registryname_map_112_114;
|
|
if(rnmap === undefined) {
|
|
pass("Registry name mapping in java files skipped, no mappings defined.");
|
|
return;
|
|
}
|
|
try {
|
|
if(!fs.chdir("src/main/java")) throw new Error("Failed to switch to 'src/main/java'.");
|
|
fs.find(".", "*.java", function(path){
|
|
const original_code = fs.readfile(path);
|
|
var replaced_code = ""+original_code;
|
|
if(original_code===undefined) throw new Error("Failed to read '"+ path +"'.");
|
|
for(var oldname in rnmap) {
|
|
if(oldname == rnmap[oldname]) {
|
|
continue;
|
|
}
|
|
{
|
|
const sfind = '"'+constants.modid+':'+oldname+'"';
|
|
const srepl = '"'+constants.modid+':'+rnmap[oldname]+'"';
|
|
if(replaced_code.search(sfind) >= 0) {
|
|
replaced_code = replaced_code.split(sfind).join(srepl);
|
|
note(fs.basename(path), ":", sfind, "->" , srepl);
|
|
}
|
|
}
|
|
{
|
|
const sfind = '"'+oldname+'"';
|
|
const srepl = '"'+rnmap[oldname]+'"';
|
|
if(replaced_code.search(sfind) >= 0) {
|
|
replaced_code = replaced_code.split(sfind).join(srepl);
|
|
note(fs.basename(path), ":", sfind, "->" , srepl);
|
|
}
|
|
}
|
|
}
|
|
if(replaced_code !== original_code) {
|
|
if(!fs.writefile(path, replaced_code)) throw new Error("Failed to write '"+ path +"'.");
|
|
}
|
|
return false;
|
|
});
|
|
pass("Registry name mapping in java files patched.");
|
|
} catch(ex) {
|
|
fail("Registry name mapping in java files failed:"+ex);
|
|
} finally {
|
|
fs.chdir(cwd);
|
|
}
|
|
};
|
|
|
|
me.tasks.patch_forge_blockstates = function() {
|
|
const cwd = fs.cwd();
|
|
try {
|
|
if(!fs.chdir(constants.local_assets_root()+"/blockstates")) throw new Error("Failed to switch to blockstates dir.");
|
|
const blockstate_files = fs.readdir(".");
|
|
for(var fit in blockstate_files) {
|
|
const jtxt = fs.readfile(blockstate_files[fit]);
|
|
if(!jtxt) throw new Error("Failed read blockstate file '" + blockstate_files[fit] + "'.");
|
|
const json = JSON.parse(jtxt);
|
|
if(json["forge_marker"] !== 1) continue;
|
|
// now simply text replace to keep the formatting
|
|
var njtext = jtxt.replace(/"normal"[\s]*:/, '"":');
|
|
njtext = njtext.replace(/"inventory"[\s]*:[\s]*\[[\s]*\{[\s]*\}[\s]*][\s]*[,]?[\s]*/, '');
|
|
njtext = njtext.replace(/"model":[\s]*"/g, '"model": "');
|
|
const pref = '"model": "' + constants.modid + ':';
|
|
njtext = njtext.replace(new RegExp(pref, "g"), pref + 'block/'); // actually faster to simply replace all and correct doubles.
|
|
njtext = njtext.replace(new RegExp(pref + 'block/block/', "g"), pref + 'block/');
|
|
njtext = njtext.replace("\n\n", "\n");
|
|
if(jtxt !== njtext) {
|
|
fs.writefile(blockstate_files[fit], njtext);
|
|
note("Forge blockstate '"+ fs.basename(blockstate_files[fit]) +"' patched.");
|
|
}
|
|
}
|
|
pass("Forge blockstates patched.");
|
|
} catch(ex) {
|
|
fail("Forge blockstate patching failed:"+ex);
|
|
} finally {
|
|
fs.chdir(cwd);
|
|
}
|
|
};
|
|
|
|
me.tasks.map_recipe_filenames = function() {
|
|
const cwd = fs.cwd();
|
|
const rnmap = constants.registryname_map_112_114;
|
|
if(rnmap === undefined) {
|
|
pass("Recipe file name mapping skipped, no mappings defined.");
|
|
return;
|
|
}
|
|
try {
|
|
if(!fs.chdir(constants.local_data_root()+"/recipes")) throw new Error("Failed to switch to recipes dir.");
|
|
fs.find(".", "*.json", function(path){
|
|
const file_name = fs.basename(path);
|
|
if(file_name.search("_")===0) return;
|
|
const oldfile = path;
|
|
var newfile = "";
|
|
for(var oldname in rnmap) {
|
|
const newname = rnmap[oldname];
|
|
if(file_name.search(oldname)===0) {
|
|
newfile = fs.dirname(path) + "/" + fs.basename(path).replace(oldname, newname);
|
|
newfile = newfile.replace(".json","");
|
|
if((newfile.search(/_recipe$/)<0) && (newfile.search(/_backcycle$/)<0) && (newfile.search(/_standalone$/)<0)) {
|
|
newfile += "_recipe";
|
|
}
|
|
newfile += ".json";
|
|
break;
|
|
}
|
|
}
|
|
if(newfile == "") {
|
|
// no match
|
|
} else if(oldfile === newfile) {
|
|
note("skip identical file " + newfile);
|
|
} else {
|
|
note(oldfile + " -> " + newfile);
|
|
fs.rename(oldfile, newfile);
|
|
}
|
|
});
|
|
pass("Recipe file name mapping done.");
|
|
} catch(ex) {
|
|
fail("Recipe file name mapping failed:"+ex);
|
|
} finally {
|
|
fs.chdir(cwd);
|
|
}
|
|
};
|
|
|
|
me.tasks.map_recipe_contents = function() {
|
|
const modid = constants.modid;
|
|
const cwd = fs.cwd();
|
|
const rnmap = constants.registryname_map_112_114;
|
|
if(rnmap === undefined) {
|
|
pass("Recipe json data mapping skipped, no mappings defined.");
|
|
return;
|
|
}
|
|
try {
|
|
if(!fs.chdir(constants.local_data_root()+"/recipes")) throw new Error("Failed to switch to recipes dir.");
|
|
fs.find(".", "*.json", function(path){
|
|
if(fs.basename(path).search("_")===0) return;
|
|
const txt = fs.readfile(path);
|
|
if(txt === undefined) {
|
|
note("Failed to read file '" + path + "'");
|
|
return;
|
|
}
|
|
// The easy stuff fist, text replace regnames
|
|
for(var key in rnmap) {
|
|
const oldname = modid+":"+key
|
|
const newname = modid+":"+rnmap[key];
|
|
txt = txt.split('"'+oldname+'"').join('"'+newname+'"');
|
|
}
|
|
txt = JSON.stringify(JSON.parse(txt));
|
|
txt = txt.replace(/,"data":0/g, "");
|
|
var recipe = JSON.parse(txt);
|
|
if(recipe.conditions === undefined) recipe.conditions = {};
|
|
recipe.conditions.type = modid+":grc"
|
|
recipe.conditions.result = recipe.result;
|
|
fs.writefile(path, JSON.stringify(recipe,null,1));
|
|
if((recipe.result===undefined) || (recipe.result.item===undefined)) {
|
|
warn("Recipe '" + path + "': No result item?!");
|
|
return;
|
|
}
|
|
const filename_check = recipe.result.item.replace(/^.*?:/,"");
|
|
if(fs.basename(path).search(filename_check) < 0) {
|
|
warn("Recipe filename '" + path + "' does not contain the result '"+ filename_check +"'.");
|
|
//const newfile = fs.dirname(path) + "/" + filename_check + "_recipe.json";
|
|
//if(!fs.isfile(newfile)) fs.rename(path, newfile);
|
|
}
|
|
});
|
|
pass("Recipe json data mappings done.");
|
|
} catch(ex) {
|
|
fail("Recipe json data mappings failed:"+ex);
|
|
} finally {
|
|
fs.chdir(cwd);
|
|
}
|
|
};
|
|
|
|
me.tasks.lang_json_text_replacements = function() {
|
|
var file_list = (function() {
|
|
var ls = [];
|
|
const dir = "./" + constants.local_assets_root() + "/lang";
|
|
if(fs.isdir(dir)) {
|
|
ls = ls.concat(fs.find(dir, '*.json'));
|
|
for(var i in ls) ls[i] = ls[i].replace(/\\/g,"/");
|
|
}
|
|
ls.sort();
|
|
return ls;
|
|
})();
|
|
|
|
for(var file_i in file_list) {
|
|
var file = file_list[file_i];
|
|
var txt = fs.readfile(file);
|
|
if(txt===undefined) throw new Error("Failed to read '" + file + "'");
|
|
txt = txt.replace(/\\\\n/g,"\\n");
|
|
fs.writefile(file, txt);
|
|
}
|
|
};
|
|
|
|
|
|
me.stdtasks = {};
|
|
me.stdtasks["assets"] = function() {
|
|
me.tasks.map_regnames_blockstate_filenames();
|
|
me.tasks.patch_texture_paths_in_models();
|
|
me.tasks.create_missing_block_items();
|
|
me.tasks.patch_registry_names_in_java_files();
|
|
me.tasks.patch_forge_blockstates();
|
|
me.tasks.map_recipe_filenames();
|
|
me.tasks.map_recipe_contents();
|
|
me.tasks.map_regnames_lang_file_keys();
|
|
};
|
|
|
|
me.stdtasks["datagen"] = function() {
|
|
sys.exec("gradlew.bat", ["--no-daemon", "runData"]);
|
|
// double check and really only copy json files.
|
|
const dst = fs.realpath("src/main/resources/data/" + constants.modid);
|
|
const src = fs.realpath("src/generated/resources/data/" + constants.modid);
|
|
if(!dst || !src) throw "Source or destination directory not found.";
|
|
const src_files = fs.find(src, "*.json");
|
|
const upath = function(s) { return s.replace(/[\\]/g,"/").replace(/^[\/]/,""); } // for correct display on win32
|
|
if(src_files===undefined) return 1;
|
|
for(var i in src_files) {
|
|
const srcfile = src_files[i];
|
|
const dstfile = srcfile.replace(src, dst);
|
|
const dstdir = fs.dirname(dstfile);
|
|
if(!fs.isdir(dstdir)) fs.mkdir(dstdir);
|
|
if(!fs.isfile(dstfile)) {
|
|
print("[copy] ", upath(srcfile.replace(src,"")));
|
|
fs.copy(srcfile, dstdir);
|
|
} else if(sys.hash.sha1(srcfile,true) != sys.hash.sha1(dstfile,true)) {
|
|
print("[edit] ", upath(srcfile.replace(src,"")));
|
|
fs.unlink(dstfile);
|
|
fs.copy(srcfile, dstdir);
|
|
}
|
|
}
|
|
};
|
|
|
|
me.stdtasks["lang-json-fixes"] = function() {
|
|
me.tasks.lang_json_text_replacements();
|
|
}
|
|
|
|
Object.freeze(me);
|
|
Object.freeze(me.tasks);
|
|
Object.freeze(me.parsing);
|
|
Object.freeze(me.sanatizing);
|
|
return me;
|
|
});
|