9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2025-12-30 04:29:05 +00:00

Fix data managers

This commit is contained in:
Daniel Mills
2020-09-18 15:28:54 -04:00
parent 6e430861d7
commit 03f3b4f8d3
42 changed files with 3480 additions and 951 deletions

View File

@@ -40,35 +40,10 @@ public class IrisDataManager
private ResourceLoader<IrisBlockData> blockLoader;
private ObjectResourceLoader objectLoader;
public void hotloaded()
{
if(prod)
{
return;
}
File packs = this.packs.getName().equals("packs") ? this.packs : dataFolder;
packs.mkdirs();
this.lootLoader = new ResourceLoader<>(packs, "loot", "Loot", IrisLootTable.class);
this.entityLoader = new ResourceLoader<>(packs, "entities", "Entity", IrisEntity.class);
this.regionLoader = new ResourceLoader<>(packs, "regions", "Region", IrisRegion.class);
this.biomeLoader = new ResourceLoader<>(packs, "biomes", "Biome", IrisBiome.class);
this.dimensionLoader = new ResourceLoader<>(packs, "dimensions", "Dimension", IrisDimension.class);
this.structureLoader = new ResourceLoader<>(packs, "structures", "Structure", IrisStructure.class);
this.generatorLoader = new ResourceLoader<>(packs, "generators", "Generator", IrisGenerator.class);
this.blockLoader = new ResourceLoader<>(packs, "blocks", "Block", IrisBlockData.class);
this.objectLoader = new ObjectResourceLoader(packs, "objects", "Object");
if(packs.getName().equals("packs"))
{
writeExamples();
}
}
public IrisDataManager(File dataFolder)
{
this.dataFolder = dataFolder;
this.packs = new File(dataFolder, "packs");
this.packs = new File(dataFolder, ProjectManager.workspaceName);
boolean pr = false;
if(!packs.exists())
{
@@ -83,6 +58,31 @@ public class IrisDataManager
prod = pr;
}
public void hotloaded()
{
if(prod)
{
return;
}
File packs = this.packs.getName().equals(ProjectManager.workspaceName) ? this.packs : dataFolder;
packs.mkdirs();
this.lootLoader = new ResourceLoader<>(packs, "loot", "Loot", IrisLootTable.class);
this.entityLoader = new ResourceLoader<>(packs, "entities", "Entity", IrisEntity.class);
this.regionLoader = new ResourceLoader<>(packs, "regions", "Region", IrisRegion.class);
this.biomeLoader = new ResourceLoader<>(packs, "biomes", "Biome", IrisBiome.class);
this.dimensionLoader = new ResourceLoader<>(packs, "dimensions", "Dimension", IrisDimension.class);
this.structureLoader = new ResourceLoader<>(packs, "structures", "Structure", IrisStructure.class);
this.generatorLoader = new ResourceLoader<>(packs, "generators", "Generator", IrisGenerator.class);
this.blockLoader = new ResourceLoader<>(packs, "blocks", "Block", IrisBlockData.class);
this.objectLoader = new ObjectResourceLoader(packs, "objects", "Object");
if(packs.getName().equals(ProjectManager.workspaceName))
{
writeExamples();
}
}
public void dump()
{
biomeLoader.clearCache();

View File

@@ -27,7 +27,7 @@ public class IrisHotloadManager
else
{
w = new FolderWatcher(Iris.instance.getDataFolder("packs"));
w = new FolderWatcher(Iris.proj.getWorkspaceFolder());
}
latch = new ChronoLatch(3000);

View File

@@ -0,0 +1,621 @@
package com.volmit.iris.manager;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.WorldType;
import org.zeroturnaround.zip.ZipUtil;
import com.google.gson.Gson;
import com.volmit.iris.Iris;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.gen.IrisTerrainProvider;
import com.volmit.iris.gen.nms.NMSCreator;
import com.volmit.iris.gen.provisions.ProvisionBukkit;
import com.volmit.iris.gen.scaffold.IrisGenConfiguration;
import com.volmit.iris.gen.scaffold.TerrainTarget;
import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.object.IrisBiomeMutation;
import com.volmit.iris.object.IrisBlockData;
import com.volmit.iris.object.IrisDimension;
import com.volmit.iris.object.IrisEntity;
import com.volmit.iris.object.IrisGenerator;
import com.volmit.iris.object.IrisLootTable;
import com.volmit.iris.object.IrisObjectPlacement;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.object.IrisStructure;
import com.volmit.iris.object.IrisStructureTile;
import com.volmit.iris.util.C;
import com.volmit.iris.util.ChronoLatch;
import com.volmit.iris.util.Form;
import com.volmit.iris.util.IO;
import com.volmit.iris.util.J;
import com.volmit.iris.util.JSONArray;
import com.volmit.iris.util.JSONObject;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.M;
import com.volmit.iris.util.MortarSender;
import com.volmit.iris.util.O;
import com.volmit.iris.util.PrecisionStopwatch;
import lombok.Data;
@Data
public class IrisProject
{
private File path;
private String name;
private IrisTerrainProvider activeProvider;
public IrisProject(File path)
{
this.path = path;
this.name = path.getName();
}
private static void flush()
{
Iris.globaldata.dump();
Iris.globaldata.preferFolder(null);
}
public boolean isOpen()
{
return activeProvider != null;
}
public void open(MortarSender sender)
{
open(sender, () ->
{
});
}
public void open(MortarSender sender, Runnable onDone)
{
if(isOpen())
{
close();
}
flush();
IrisDimension d = Iris.globaldata.getDimensionLoader().load(getName());
J.attemptAsync(() ->
{
try
{
File f = d.getLoadFile().getParentFile().getParentFile();
for(File i : f.listFiles())
{
if(i.getName().endsWith(".code-workspace"))
{
sender.sendMessage("Updating Workspace...");
J.a(() ->
{
updateWorkspace();
sender.sendMessage("Workspace Updated");
});
if(IrisSettings.get().openVSCode)
{
Desktop.getDesktop().open(i);
}
break;
}
}
}
catch(Throwable e)
{
e.printStackTrace();
}
});
if(d == null)
{
sender.sendMessage("Can't find dimension: " + getName());
return;
}
Iris.globaldata.dump();
String wfp = "iris/" + UUID.randomUUID();
//@builder
ProvisionBukkit gen = Iris.instance
.createProvisionBukkit(IrisGenConfiguration.builder()
.threads(IrisSettings.get().threads)
.dimension(getName())
.target(TerrainTarget.builder()
.environment(d.getEnvironment())
.folder(new File(wfp))
.name(wfp)
.seed(1337)
.build())
.build());
//@done
IrisTerrainProvider gx = (IrisTerrainProvider) gen.getProvider();
gx.setDev(true);
sender.sendMessage("Generating with " + IrisSettings.get().threads + " threads per chunk");
O<Boolean> done = new O<Boolean>();
done.set(false);
activeProvider = gx;
J.a(() ->
{
double last = 0;
int req = 740;
double lpc = 0;
boolean c = false;
while(!done.get())
{
boolean derp = false;
double v = (double) gx.getGenerated() / (double) req;
c = lpc != v;
lpc = v;
if(last > v || v > 1)
{
derp = true;
v = last;
}
else
{
last = v;
}
if(c)
{
sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + (derp ? (C.GRAY + " (Waiting on Server...)") : (C.GRAY + " (" + (req - gx.getGenerated()) + " Left)")));
}
J.sleep(3000);
if(gx.isFailing())
{
sender.sendMessage("Generation Failed!");
return;
}
}
});
//@builder
World world = NMSCreator.createWorld(new WorldCreator(wfp)
.seed(1337)
.generator(gen)
.generateStructures(d.isVanillaStructures())
.type(WorldType.NORMAL)
.environment(d.getEnvironment()), false);
//@done
gx.getTarget().setRealWorld(world);
Iris.linkMultiverseCore.removeFromConfig(world);
done.set(true);
sender.sendMessage("Generating 100%");
if(sender.isPlayer())
{
sender.player().teleport(new Location(world, 0, 0, world.getHighestBlockYAt(0, 0)));
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () ->
{
sender.sendMessage("Hotloading Active! Change any files and watch them appear as you load new chunks!");
if(sender.isPlayer())
{
sender.player().setGameMode(GameMode.SPECTATOR);
}
onDone.run();
}, 0);
}
public void close()
{
activeProvider.close();
File folder = activeProvider.getTarget().getFolder();
Iris.linkMultiverseCore.removeFromConfig(activeProvider.getTarget().getName());
Bukkit.unloadWorld(activeProvider.getTarget().getName(), false);
flush();
J.attemptAsync(() -> IO.delete(folder));
activeProvider = null;
}
public File getCodeWorkspaceFile()
{
return new File(path, getName() + ".code-workspace");
}
public void updateWorkspace()
{
getPath().mkdirs();
File ws = getCodeWorkspaceFile();
try
{
PrecisionStopwatch p = PrecisionStopwatch.start();
Iris.info("Updating Workspace: " + ws.getPath());
JSONObject j = createCodeWorkspaceConfig();
IO.writeAll(ws, j.toString(4));
p.end();
Iris.info("Updated Workspace: " + ws.getPath() + " in " + Form.duration(p.getMilliseconds(), 2));
}
catch(Throwable e)
{
Iris.warn("Project invalid: " + ws.getAbsolutePath() + " Re-creating. You may loose some vs-code workspace settings! But not your actual project!");
ws.delete();
try
{
IO.writeAll(ws, createCodeWorkspaceConfig());
}
catch(IOException e1)
{
e1.printStackTrace();
}
}
}
public JSONObject createCodeWorkspaceConfig()
{
Iris.globaldata.clearLists();
JSONObject ws = new JSONObject();
JSONArray folders = new JSONArray();
JSONObject folder = new JSONObject();
folder.put("path", ".");
folders.put(folder);
ws.put("folders", folders);
JSONObject settings = new JSONObject();
settings.put("workbench.colorTheme", "Monokai");
settings.put("workbench.preferredDarkColorTheme", "Solarized Dark");
settings.put("workbench.tips.enabled", false);
settings.put("workbench.tree.indent", 24);
settings.put("files.autoSave", "onFocusChange");
JSONObject jc = new JSONObject();
jc.put("editor.autoIndent", "brackets");
jc.put("editor.acceptSuggestionOnEnter", "smart");
jc.put("editor.cursorSmoothCaretAnimation", true);
jc.put("editor.dragAndDrop", false);
jc.put("files.trimTrailingWhitespace", true);
jc.put("diffEditor.ignoreTrimWhitespace", true);
jc.put("files.trimFinalNewlines", true);
jc.put("editor.suggest.showKeywords", false);
jc.put("editor.suggest.showSnippets", false);
jc.put("editor.suggest.showWords", false);
JSONObject st = new JSONObject();
st.put("strings", true);
jc.put("editor.quickSuggestions", st);
jc.put("editor.suggest.insertMode", "replace");
settings.put("[json]", jc);
settings.put("json.maxItemsComputed", 15000);
String gg = Iris.globaldata.getBiomeLoader().getPreferredFolder();
Iris.globaldata.preferFolder(getName());
JSONArray schemas = new JSONArray();
schemas.put(getSchemaEntry(IrisDimension.class, Iris.globaldata, "/dimensions/*.json"));
schemas.put(getSchemaEntry(IrisEntity.class, Iris.globaldata, "/entities/*.json"));
schemas.put(getSchemaEntry(IrisBiome.class, Iris.globaldata, "/biomes/*.json"));
schemas.put(getSchemaEntry(IrisRegion.class, Iris.globaldata, "/regions/*.json"));
schemas.put(getSchemaEntry(IrisGenerator.class, Iris.globaldata, "/generators/*.json"));
schemas.put(getSchemaEntry(IrisStructure.class, Iris.globaldata, "/structures/*.json"));
schemas.put(getSchemaEntry(IrisBlockData.class, Iris.globaldata, "/blocks/*.json"));
schemas.put(getSchemaEntry(IrisLootTable.class, Iris.globaldata, "/loot/*.json"));
Iris.globaldata.preferFolder(gg);
settings.put("json.schemas", schemas);
ws.put("settings", settings);
return ws;
}
public JSONObject getSchemaEntry(Class<?> i, IrisDataManager dat, String... fileMatch)
{
Iris.verbose("Processing Folder " + i.getSimpleName() + " " + fileMatch[0]);
JSONObject o = new JSONObject();
o.put("fileMatch", new JSONArray(fileMatch));
o.put("schema", new SchemaBuilder(i, dat).compute());
return o;
}
public File compilePackage(MortarSender sender, boolean obfuscate, boolean minify)
{
String dim = getName();
Iris.globaldata.dump();
Iris.globaldata.preferFolder(null);
String dimm = dim;
IrisDimension dimension = Iris.globaldata.getDimensionLoader().load(dimm);
File folder = new File(Iris.instance.getDataFolder(), "exports/" + dimension.getLoadKey());
folder.mkdirs();
Iris.info("Packaging Dimension " + dimension.getName() + " " + (obfuscate ? "(Obfuscated)" : ""));
KSet<IrisRegion> regions = new KSet<>();
KSet<IrisBiome> biomes = new KSet<>();
KSet<IrisEntity> entities = new KSet<>();
KSet<IrisStructure> structures = new KSet<>();
KSet<IrisGenerator> generators = new KSet<>();
KSet<IrisLootTable> loot = new KSet<>();
KSet<IrisBlockData> blocks = new KSet<>();
Iris.globaldata.preferFolder(dim);
for(String i : Iris.globaldata.getBlockLoader().getPreferredKeys())
{
blocks.add(Iris.globaldata.getBlockLoader().load(i));
}
Iris.globaldata.preferFolder(null);
dimension.getRegions().forEach((i) -> regions.add(Iris.globaldata.getRegionLoader().load(i)));
dimension.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i)));
regions.forEach((i) -> biomes.addAll(i.getAllBiomes(null)));
biomes.forEach((i) -> i.getGenerators().forEach((j) -> generators.add(j.getCachedGenerator(null))));
regions.forEach((i) -> i.getStructures().forEach((j) -> structures.add(j.getStructure(null))));
biomes.forEach((i) -> i.getStructures().forEach((j) -> structures.add(j.getStructure(null))));
regions.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i))));
biomes.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i))));
structures.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i))));
structures.forEach((b) -> b.getTiles().forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i)))));
structures.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
structures.forEach((s) -> s.getTiles().forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity())))));
biomes.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
regions.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
dimension.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity())));
structures.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
structures.forEach((s) -> s.getTiles().forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity())))));
biomes.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
regions.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
dimension.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity())));
KMap<String, String> renameObjects = new KMap<>();
String a = "";
StringBuilder b = new StringBuilder();
StringBuilder c = new StringBuilder();
sender.sendMessage("Serializing Objects");
for(IrisStructure i : structures)
{
for(IrisStructureTile j : i.getTiles())
{
b.append(j.hashCode());
KList<String> newNames = new KList<>();
for(String k : j.getObjects())
{
if(renameObjects.containsKey(k))
{
newNames.add(renameObjects.get(k));
continue;
}
String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", "");
b.append(name);
newNames.add(name);
renameObjects.put(k, name);
}
j.setObjects(newNames);
}
}
for(IrisBiome i : biomes)
{
for(IrisObjectPlacement j : i.getObjects())
{
b.append(j.hashCode());
KList<String> newNames = new KList<>();
for(String k : j.getPlace())
{
if(renameObjects.containsKey(k))
{
newNames.add(renameObjects.get(k));
continue;
}
String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", "");
b.append(name);
newNames.add(name);
renameObjects.put(k, name);
}
j.setPlace(newNames);
}
}
for(IrisBiomeMutation i : dimension.getMutations())
{
for(IrisObjectPlacement j : i.getObjects())
{
b.append(j.hashCode());
KList<String> newNames = new KList<>();
for(String k : j.getPlace())
{
if(renameObjects.containsKey(k))
{
newNames.add(renameObjects.get(k));
continue;
}
String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", "");
b.append(name);
newNames.add(name);
renameObjects.put(k, name);
}
j.setPlace(newNames);
}
}
KMap<String, KList<String>> lookupObjects = renameObjects.flip();
StringBuilder gb = new StringBuilder();
ChronoLatch cl = new ChronoLatch(1000);
O<Integer> ggg = new O<Integer>();
ggg.set(0);
biomes.forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) ->
{
try
{
File f = Iris.globaldata.getObjectLoader().findFile(lookupObjects.get(k).get(0));
IO.copyFile(f, new File(folder, "objects/" + k + ".iob"));
gb.append(IO.hash(f));
ggg.set(ggg.get() + 1);
if(cl.flip())
{
int g = ggg.get();
ggg.set(0);
sender.sendMessage("Wrote another " + g + " Objects");
}
}
catch(Throwable e)
{
}
})));
structures.forEach((i) -> i.getTiles().forEach((j) -> j.getObjects().forEach((k) ->
{
try
{
File f = Iris.globaldata.getObjectLoader().findFile(lookupObjects.get(k).get(0));
IO.copyFile(f, new File(folder, "objects/" + k + ".iob"));
gb.append(IO.hash(f));
ggg.set(ggg.get() + 1);
if(cl.flip())
{
int g = ggg.get();
ggg.set(0);
sender.sendMessage("Wrote another " + g + " Objects");
}
}
catch(Throwable e)
{
}
})));
dimension.getMutations().forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) ->
{
try
{
File f = Iris.globaldata.getObjectLoader().findFile(lookupObjects.get(k).get(0));
IO.copyFile(f, new File(folder, "objects/" + k + ".iob"));
gb.append(IO.hash(f));
ggg.set(ggg.get() + 1);
if(cl.flip())
{
int g = ggg.get();
ggg.set(0);
sender.sendMessage("Wrote another " + g + " Objects");
}
}
catch(Throwable e)
{
}
})));
b.append(IO.hash(gb.toString()));
c.append(IO.hash(b.toString()));
b = new StringBuilder();
Iris.info("Writing Dimensional Scaffold");
try
{
a = new JSONObject(new Gson().toJson(dimension)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "dimensions/" + dimension.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
for(IrisGenerator i : generators)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "generators/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
c.append(IO.hash(b.toString()));
b = new StringBuilder();
for(IrisRegion i : regions)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "regions/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisBlockData i : blocks)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "blocks/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisStructure i : structures)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "structures/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisBiome i : biomes)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "biomes/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisEntity i : entities)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "entities/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisLootTable i : loot)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "loot/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
c.append(IO.hash(b.toString()));
b = new StringBuilder();
String finalHash = IO.hash(c.toString());
JSONObject meta = new JSONObject();
meta.put("hash", finalHash);
meta.put("time", M.ms());
meta.put("version", dimension.getVersion());
IO.writeAll(new File(folder, "package.json"), meta.toString(minify ? 0 : 4));
File p = new File(Iris.instance.getDataFolder(), "exports/" + dimension.getLoadKey() + ".iris");
Iris.info("Compressing Package");
ZipUtil.pack(folder, p, 9);
IO.delete(folder);
sender.sendMessage("Package Compiled!");
return p;
}
catch(Throwable e)
{
e.printStackTrace();
}
sender.sendMessage("Failed!");
return null;
}
}

View File

@@ -1,24 +1,10 @@
package com.volmit.iris.manager;
import java.awt.Desktop;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.WorldCreator;
import org.bukkit.WorldType;
import org.bukkit.block.Biome;
import org.bukkit.potion.PotionEffectType;
import org.zeroturnaround.zip.ZipUtil;
import org.zeroturnaround.zip.commons.FileUtils;
@@ -26,56 +12,31 @@ import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.volmit.iris.Iris;
import com.volmit.iris.IrisSettings;
import com.volmit.iris.gen.IrisTerrainProvider;
import com.volmit.iris.gen.nms.NMSCreator;
import com.volmit.iris.gen.provisions.ProvisionBukkit;
import com.volmit.iris.gen.scaffold.IrisGenConfiguration;
import com.volmit.iris.gen.scaffold.TerrainTarget;
import com.volmit.iris.object.DecorationPart;
import com.volmit.iris.object.InterpolationMethod;
import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.object.IrisBiomeGeneratorLink;
import com.volmit.iris.object.IrisBiomeMutation;
import com.volmit.iris.object.IrisBlockData;
import com.volmit.iris.object.IrisDimension;
import com.volmit.iris.object.IrisEntity;
import com.volmit.iris.object.IrisGenerator;
import com.volmit.iris.object.IrisInterpolator;
import com.volmit.iris.object.IrisLootTable;
import com.volmit.iris.object.IrisNoiseGenerator;
import com.volmit.iris.object.IrisObjectPlacement;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.object.IrisStructure;
import com.volmit.iris.object.IrisStructureTile;
import com.volmit.iris.object.NoiseStyle;
import com.volmit.iris.object.StructureTileCondition;
import com.volmit.iris.util.C;
import com.volmit.iris.util.ChronoLatch;
import com.volmit.iris.util.Form;
import com.volmit.iris.util.IO;
import com.volmit.iris.util.J;
import com.volmit.iris.util.JSONArray;
import com.volmit.iris.util.JSONException;
import com.volmit.iris.util.JSONObject;
import com.volmit.iris.util.KList;
import com.volmit.iris.util.KMap;
import com.volmit.iris.util.KSet;
import com.volmit.iris.util.M;
import com.volmit.iris.util.MortarSender;
import com.volmit.iris.util.O;
import com.volmit.iris.util.PrecisionStopwatch;
import com.volmit.iris.util.TaskExecutor;
import com.volmit.iris.util.TaskExecutor.TaskGroup;
import lombok.Data;
@Data
public class ProjectManager
{
public static final String workspaceName = "packs";
private KMap<String, String> cacheListing = null;
private IrisTerrainProvider currentProject;
private TaskExecutor tx = new TaskExecutor(8, Thread.MIN_PRIORITY, "Iris Compiler");
private ReentrantLock lock = new ReentrantLock();
private IrisProject activeProject;
public ProjectManager()
{
@@ -83,7 +44,7 @@ public class ProjectManager
{
J.a(() ->
{
File ignore = Iris.instance.getDataFile("packs", ".gitignore");
File ignore = getWorkspaceFile(".gitignore");
if(!ignore.exists())
{
@@ -133,7 +94,7 @@ public class ProjectManager
File zip = Iris.getNonCachedFile("pack-" + trim + "-" + repo, url);
File temp = Iris.getTemp();
File work = new File(temp, "dl-" + UUID.randomUUID());
File packs = Iris.instance.getDataFolder("packs");
File packs = getWorkspaceFolder();
sender.sendMessage("Unpacking " + repo);
ZipUtil.unpack(zip, work);
File dir = work.listFiles().length == 1 && work.listFiles()[0].isDirectory() ? work.listFiles()[0] : null;
@@ -243,7 +204,7 @@ public class ProjectManager
public boolean isProjectOpen()
{
return currentProject != null;
return activeProject != null && activeProject.isOpen();
}
public void open(MortarSender sender, String dimm)
@@ -255,442 +216,44 @@ public class ProjectManager
public void open(MortarSender sender, String dimm, Runnable onDone)
{
Iris.globaldata.dump();
Iris.globaldata.preferFolder(null);
IrisDimension d = Iris.globaldata.getDimensionLoader().load(dimm);
J.attemptAsync(() ->
{
try
{
File f = d.getLoadFile().getParentFile().getParentFile();
for(File i : f.listFiles())
{
if(i.getName().endsWith(".code-workspace"))
{
sender.sendMessage("Updating Workspace...");
J.a(() ->
{
updateWorkspace(i);
sender.sendMessage("Workspace Updated");
});
if(IrisSettings.get().openVSCode)
{
Desktop.getDesktop().open(i);
}
break;
}
}
}
catch(Throwable e)
{
e.printStackTrace();
}
});
if(d == null)
{
sender.sendMessage("Can't find dimension: " + dimm);
return;
}
if(isProjectOpen())
{
sender.sendMessage("Please Wait. Closing Current Project...");
close();
}
Iris.globaldata.dump();
sender.sendMessage("Loading " + dimm + "...");
String wfp = "iris/" + UUID.randomUUID();
ProvisionBukkit gen = Iris.instance.createProvisionBukkit(IrisGenConfiguration.builder().threads(IrisSettings.get().threads).dimension(dimm).target(TerrainTarget.builder().environment(d.getEnvironment()).folder(new File(wfp)).name(wfp).seed(1337).build()).build());
//@done
IrisProject project = new IrisProject(new File(getWorkspaceFolder(), dimm));
activeProject = project;
project.open(sender, onDone);
}
IrisTerrainProvider gx = (IrisTerrainProvider) gen.getProvider();
currentProject = gx;
gx.setDev(true);
sender.sendMessage("Generating with " + IrisSettings.get().threads + " threads per chunk");
O<Boolean> done = new O<Boolean>();
done.set(false);
public File getWorkspaceFolder(String... sub)
{
return Iris.instance.getDataFolderList(workspaceName, sub);
}
J.a(() ->
{
double last = 0;
int req = 740;
double lpc = 0;
boolean c = false;
while(!done.get())
{
boolean derp = false;
double v = (double) gx.getGenerated() / (double) req;
c = lpc != v;
lpc = v;
if(last > v || v > 1)
{
derp = true;
v = last;
}
else
{
last = v;
}
if(c)
{
sender.sendMessage(C.WHITE + "Generating " + Form.pc(v) + (derp ? (C.GRAY + " (Waiting on Server...)") : (C.GRAY + " (" + (req - gx.getGenerated()) + " Left)")));
}
J.sleep(3000);
if(gx.isFailing())
{
sender.sendMessage("Generation Failed!");
return;
}
}
});
// @NoArgsConstructor
World world = NMSCreator.createWorld(new WorldCreator(wfp).seed(1337).generator(gen).generateStructures(d.isVanillaStructures()).type(WorldType.NORMAL).environment(d.getEnvironment()), false);
//@done
gx.getTarget().setRealWorld(world);
Iris.linkMultiverseCore.removeFromConfig(world);
done.set(true);
sender.sendMessage("Generating 100%");
if(sender.isPlayer())
{
sender.player().teleport(new Location(world, 150, 150, 275));
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Iris.instance, () ->
{
sender.sendMessage("Hotloading Active! Change any files and watch them appear as you load new chunks!");
if(sender.isPlayer())
{
sender.player().setGameMode(GameMode.SPECTATOR);
}
onDone.run();
}, 0);
public File getWorkspaceFile(String... sub)
{
return Iris.instance.getDataFileList(workspaceName, sub);
}
public void close()
{
if(isProjectOpen())
{
currentProject.close();
File folder = currentProject.getTarget().getFolder();
Iris.linkMultiverseCore.removeFromConfig(currentProject.getTarget().getName());
Bukkit.unloadWorld(currentProject.getTarget().getName(), false);
currentProject = null;
Iris.globaldata.dump();
Iris.globaldata.preferFolder(null);
J.attemptAsync(() -> IO.delete(folder));
activeProject.close();
activeProject = null;
}
}
public File compilePackage(MortarSender sender, String dim, boolean obfuscate, boolean minify)
public File compilePackage(MortarSender sender, String d, boolean obfuscate, boolean minify)
{
Iris.globaldata.dump();
Iris.globaldata.preferFolder(null);
String dimm = dim;
IrisDimension dimension = Iris.globaldata.getDimensionLoader().load(dimm);
File folder = new File(Iris.instance.getDataFolder(), "exports/" + dimension.getLoadKey());
folder.mkdirs();
Iris.info("Packaging Dimension " + dimension.getName() + " " + (obfuscate ? "(Obfuscated)" : ""));
KSet<IrisRegion> regions = new KSet<>();
KSet<IrisBiome> biomes = new KSet<>();
KSet<IrisEntity> entities = new KSet<>();
KSet<IrisStructure> structures = new KSet<>();
KSet<IrisGenerator> generators = new KSet<>();
KSet<IrisLootTable> loot = new KSet<>();
KSet<IrisBlockData> blocks = new KSet<>();
Iris.globaldata.preferFolder(dim);
for(String i : Iris.globaldata.getBlockLoader().getPreferredKeys())
{
blocks.add(Iris.globaldata.getBlockLoader().load(i));
}
Iris.globaldata.preferFolder(null);
dimension.getRegions().forEach((i) -> regions.add(Iris.globaldata.getRegionLoader().load(i)));
dimension.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i)));
regions.forEach((i) -> biomes.addAll(i.getAllBiomes(null)));
biomes.forEach((i) -> i.getGenerators().forEach((j) -> generators.add(j.getCachedGenerator(null))));
regions.forEach((i) -> i.getStructures().forEach((j) -> structures.add(j.getStructure(null))));
biomes.forEach((i) -> i.getStructures().forEach((j) -> structures.add(j.getStructure(null))));
regions.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i))));
biomes.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i))));
structures.forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i))));
structures.forEach((b) -> b.getTiles().forEach((r) -> r.getLoot().getTables().forEach((i) -> loot.add(Iris.globaldata.getLootLoader().load(i)))));
structures.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
structures.forEach((s) -> s.getTiles().forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity())))));
biomes.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
regions.forEach((r) -> r.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
dimension.getEntitySpawnOverrides().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity())));
structures.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
structures.forEach((s) -> s.getTiles().forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity())))));
biomes.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
regions.forEach((r) -> r.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity()))));
dimension.getEntityInitialSpawns().forEach((sp) -> entities.add(Iris.globaldata.getEntityLoader().load(sp.getEntity())));
KMap<String, String> renameObjects = new KMap<>();
String a = "";
StringBuilder b = new StringBuilder();
StringBuilder c = new StringBuilder();
sender.sendMessage("Serializing Objects");
for(IrisStructure i : structures)
{
for(IrisStructureTile j : i.getTiles())
{
b.append(j.hashCode());
KList<String> newNames = new KList<>();
for(String k : j.getObjects())
{
if(renameObjects.containsKey(k))
{
newNames.add(renameObjects.get(k));
continue;
}
String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", "");
b.append(name);
newNames.add(name);
renameObjects.put(k, name);
}
j.setObjects(newNames);
}
}
for(IrisBiome i : biomes)
{
for(IrisObjectPlacement j : i.getObjects())
{
b.append(j.hashCode());
KList<String> newNames = new KList<>();
for(String k : j.getPlace())
{
if(renameObjects.containsKey(k))
{
newNames.add(renameObjects.get(k));
continue;
}
String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", "");
b.append(name);
newNames.add(name);
renameObjects.put(k, name);
}
j.setPlace(newNames);
}
}
for(IrisBiomeMutation i : dimension.getMutations())
{
for(IrisObjectPlacement j : i.getObjects())
{
b.append(j.hashCode());
KList<String> newNames = new KList<>();
for(String k : j.getPlace())
{
if(renameObjects.containsKey(k))
{
newNames.add(renameObjects.get(k));
continue;
}
String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", "");
b.append(name);
newNames.add(name);
renameObjects.put(k, name);
}
j.setPlace(newNames);
}
}
KMap<String, KList<String>> lookupObjects = renameObjects.flip();
StringBuilder gb = new StringBuilder();
ChronoLatch cl = new ChronoLatch(1000);
O<Integer> ggg = new O<Integer>();
ggg.set(0);
biomes.forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) ->
{
try
{
File f = Iris.globaldata.getObjectLoader().findFile(lookupObjects.get(k).get(0));
IO.copyFile(f, new File(folder, "objects/" + k + ".iob"));
gb.append(IO.hash(f));
ggg.set(ggg.get() + 1);
if(cl.flip())
{
int g = ggg.get();
ggg.set(0);
sender.sendMessage("Wrote another " + g + " Objects");
}
}
catch(Throwable e)
{
}
})));
structures.forEach((i) -> i.getTiles().forEach((j) -> j.getObjects().forEach((k) ->
{
try
{
File f = Iris.globaldata.getObjectLoader().findFile(lookupObjects.get(k).get(0));
IO.copyFile(f, new File(folder, "objects/" + k + ".iob"));
gb.append(IO.hash(f));
ggg.set(ggg.get() + 1);
if(cl.flip())
{
int g = ggg.get();
ggg.set(0);
sender.sendMessage("Wrote another " + g + " Objects");
}
}
catch(Throwable e)
{
}
})));
dimension.getMutations().forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) ->
{
try
{
File f = Iris.globaldata.getObjectLoader().findFile(lookupObjects.get(k).get(0));
IO.copyFile(f, new File(folder, "objects/" + k + ".iob"));
gb.append(IO.hash(f));
ggg.set(ggg.get() + 1);
if(cl.flip())
{
int g = ggg.get();
ggg.set(0);
sender.sendMessage("Wrote another " + g + " Objects");
}
}
catch(Throwable e)
{
}
})));
b.append(IO.hash(gb.toString()));
c.append(IO.hash(b.toString()));
b = new StringBuilder();
Iris.info("Writing Dimensional Scaffold");
try
{
a = new JSONObject(new Gson().toJson(dimension)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "dimensions/" + dimension.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
for(IrisGenerator i : generators)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "generators/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
c.append(IO.hash(b.toString()));
b = new StringBuilder();
for(IrisRegion i : regions)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "regions/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisBlockData i : blocks)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "blocks/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisStructure i : structures)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "structures/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisBiome i : biomes)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "biomes/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisEntity i : entities)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "entities/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
for(IrisLootTable i : loot)
{
a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4);
IO.writeAll(new File(folder, "loot/" + i.getLoadKey() + ".json"), a);
b.append(IO.hash(a));
}
c.append(IO.hash(b.toString()));
b = new StringBuilder();
String finalHash = IO.hash(c.toString());
JSONObject meta = new JSONObject();
meta.put("hash", finalHash);
meta.put("time", M.ms());
meta.put("version", dimension.getVersion());
IO.writeAll(new File(folder, "package.json"), meta.toString(minify ? 0 : 4));
File p = new File(Iris.instance.getDataFolder(), "exports/" + dimension.getLoadKey() + ".iris");
Iris.info("Compressing Package");
ZipUtil.pack(folder, p, 9);
IO.delete(folder);
sender.sendMessage("Package Compiled!");
return p;
}
catch(Throwable e)
{
e.printStackTrace();
}
sender.sendMessage("Failed!");
return null;
return new IrisProject(new File(getWorkspaceFolder(), d)).compilePackage(sender, obfuscate, minify);
}
public void createFrom(String existingPack, String newName)
{
File importPack = Iris.instance.getDataFolder("packs", existingPack);
File newPack = Iris.instance.getDataFolder("packs", newName);
File importPack = getWorkspaceFolder(existingPack);
File newPack = getWorkspaceFolder(newName);
if(importPack.listFiles().length == 0)
{
@@ -749,8 +312,9 @@ public class ProjectManager
try
{
JSONObject ws = newWorkspaceConfig(Iris.instance.getDataFolder("packs", newName));
IO.writeAll(Iris.instance.getDataFile("packs", newName, newName + ".code-workspace"), ws.toString(0));
IrisProject p = new IrisProject(getWorkspaceFolder(newName));
JSONObject ws = p.createCodeWorkspaceConfig();
IO.writeAll(getWorkspaceFile(newName, newName + ".code-workspace"), ws.toString(0));
}
catch(JSONException | IOException e)
@@ -762,7 +326,7 @@ public class ProjectManager
public void create(MortarSender sender, String s, String downloadable)
{
boolean shouldDelete = false;
File importPack = Iris.instance.getDataFolder("packs", downloadable);
File importPack = getWorkspaceFolder(downloadable);
if(importPack.listFiles().length == 0)
{
@@ -794,7 +358,7 @@ public class ProjectManager
{
importPack.delete();
}
Iris.proj.open(sender, s);
open(sender, s);
}
public void create(MortarSender sender, String s)
@@ -811,7 +375,7 @@ public class ProjectManager
dimension.setLoadKey(s);
dimension.setName(Form.capitalizeWords(s.replaceAll("\\Q-\\E", " ")));
if(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "dimensions", dimension.getLoadKey() + ".json").exists())
if(getWorkspaceFile(dimension.getLoadKey(), "dimensions", dimension.getLoadKey() + ".json").exists())
{
sender.sendMessage("Project Already Exists! Open it instead!");
return false;
@@ -872,18 +436,18 @@ public class ProjectManager
exampleRegion.getShoreBiomes().add(exampleShore1.getLoadKey());
exampleRegion.getSeaBiomes().add(exampleOcean1.getLoadKey());
dimension.getRegions().add(exampleRegion.getLoadKey());
IrisProject project = new IrisProject(getWorkspaceFolder(dimension.getLoadKey()));
try
{
JSONObject ws = newWorkspaceConfig(Iris.instance.getDataFolder("packs", dimension.getLoadKey()));
IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "dimensions", dimension.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(dimension)).toString(4));
IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "regions", exampleRegion.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleRegion)).toString(4));
IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", exampleLand1.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleLand1)).toString(4));
IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", exampleLand2.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleLand2)).toString(4));
IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", exampleShore1.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleShore1)).toString(4));
IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "biomes", exampleOcean1.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleOcean1)).toString(4));
IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), "generators", gen.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(gen)).toString(4));
IO.writeAll(Iris.instance.getDataFile("packs", dimension.getLoadKey(), dimension.getLoadKey() + ".code-workspace"), ws.toString(0));
JSONObject ws = project.createCodeWorkspaceConfig();
IO.writeAll(getWorkspaceFile(dimension.getLoadKey(), "dimensions", dimension.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(dimension)).toString(4));
IO.writeAll(getWorkspaceFile(dimension.getLoadKey(), "regions", exampleRegion.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleRegion)).toString(4));
IO.writeAll(getWorkspaceFile(dimension.getLoadKey(), "biomes", exampleLand1.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleLand1)).toString(4));
IO.writeAll(getWorkspaceFile(dimension.getLoadKey(), "biomes", exampleLand2.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleLand2)).toString(4));
IO.writeAll(getWorkspaceFile(dimension.getLoadKey(), "biomes", exampleShore1.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleShore1)).toString(4));
IO.writeAll(getWorkspaceFile(dimension.getLoadKey(), "biomes", exampleOcean1.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(exampleOcean1)).toString(4));
IO.writeAll(getWorkspaceFile(dimension.getLoadKey(), "generators", gen.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(gen)).toString(4));
IO.writeAll(getWorkspaceFile(dimension.getLoadKey(), dimension.getLoadKey() + ".code-workspace"), ws.toString(0));
}
catch(JSONException | IOException e)
@@ -896,366 +460,11 @@ public class ProjectManager
return true;
}
private JSONObject newWorkspaceConfig(File pack)
public void updateWorkspace()
{
Iris.globaldata.clearLists();
JSONObject ws = new JSONObject();
JSONArray folders = new JSONArray();
JSONObject folder = new JSONObject();
folder.put("path", ".");
folders.put(folder);
ws.put("folders", folders);
JSONObject settings = new JSONObject();
settings.put("workbench.colorTheme", "Monokai");
settings.put("workbench.preferredDarkColorTheme", "Solarized Dark");
settings.put("workbench.tips.enabled", false);
settings.put("workbench.tree.indent", 24);
settings.put("files.autoSave", "onFocusChange");
JSONObject jc = new JSONObject();
jc.put("editor.autoIndent", "brackets");
jc.put("editor.acceptSuggestionOnEnter", "smart");
jc.put("editor.cursorSmoothCaretAnimation", true);
jc.put("editor.dragAndDrop", false);
jc.put("files.trimTrailingWhitespace", true);
jc.put("diffEditor.ignoreTrimWhitespace", true);
jc.put("files.trimFinalNewlines", true);
jc.put("editor.suggest.showKeywords", false);
jc.put("editor.suggest.showSnippets", false);
jc.put("editor.suggest.showWords", false);
JSONObject st = new JSONObject();
st.put("strings", true);
jc.put("editor.quickSuggestions", st);
jc.put("editor.suggest.insertMode", "replace");
settings.put("[json]", jc);
settings.put("json.maxItemsComputed", 15000);
JSONArray schemas = buildSchemas(Iris.globaldata, pack);
settings.put("json.schemas", schemas);
ws.put("settings", settings);
return ws;
}
public File getWorkspaceFile(String dim)
{
return Iris.instance.getDataFile("packs", dim, dim + ".code-workspace");
}
public void updateWorkspace(File ws)
{
try
if(isProjectOpen())
{
PrecisionStopwatch p = PrecisionStopwatch.start();
Iris.info("Updating Workspace: " + ws.getPath());
J.attemptAsync(() -> writeDocs(ws.getParentFile()));
JSONObject j = newWorkspaceConfig(ws.getParentFile());
IO.writeAll(ws, j.toString(4));
p.end();
Iris.info("Updated Workspace: " + ws.getPath() + " in " + Form.duration(p.getMilliseconds(), 2));
activeProject.updateWorkspace();
}
catch(Throwable e)
{
Iris.warn("Project invalid: " + ws.getAbsolutePath() + " Re-creating. You may loose some vs-code workspace settings! But not your actual project!");
try
{
IO.writeAll(ws, newWorkspaceConfig(ws.getParentFile()));
}
catch(IOException e1)
{
e1.printStackTrace();
}
}
}
private void ex(JSONArray schemas, Class<?> c, IrisDataManager dat, String v, File pack)
{
JSONObject o = getSchemaEntry(c, dat, v);
lock.lock();
schemas.put(o);
lock.unlock();
J.a(() ->
{
File f = new File(pack, "_docs/schema/" + c.getSimpleName().replaceAll("\\QIris\\E", "").toLowerCase() + ".json");
f.getParentFile().mkdirs();
try
{
IO.writeAll(f, o.toString(4));
}
catch(JSONException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
});
}
private JSONArray buildSchemas(IrisDataManager dat, File pack)
{
String gg = dat.getBiomeLoader().getPreferredFolder();
dat.preferFolder(pack.getName());
JSONArray schemas = new JSONArray();
TaskGroup g = tx.startWork();
g.queue(() -> ex(schemas, IrisDimension.class, dat, "/dimensions/*.json", pack));
g.queue(() -> ex(schemas, IrisEntity.class, dat, "/entities/*.json", pack));
g.queue(() -> ex(schemas, IrisBiome.class, dat, "/biomes/*.json", pack));
g.queue(() -> ex(schemas, IrisRegion.class, dat, "/regions/*.json", pack));
g.queue(() -> ex(schemas, IrisGenerator.class, dat, "/generators/*.json", pack));
g.queue(() -> ex(schemas, IrisStructure.class, dat, "/structures/*.json", pack));
g.queue(() -> ex(schemas, IrisBlockData.class, dat, "/blocks/*.json", pack));
g.queue(() -> ex(schemas, IrisLootTable.class, dat, "/loot/*.json", pack));
g.execute();
dat.preferFolder(gg);
return schemas;
}
public JSONObject getSchemaEntry(Class<?> i, IrisDataManager dat, String... fileMatch)
{
Iris.verbose("Processing Folder " + i.getSimpleName() + " " + fileMatch[0]);
JSONObject o = new JSONObject();
o.put("fileMatch", new JSONArray(fileMatch));
o.put("schema", new SchemaBuilder(i, dat).compute());
return o;
}
public KList<String> analyzeFolder(File folder, String fn, Object t)
{
KList<String> a = new KList<String>();
if(!new File(folder, fn).exists())
{
return a;
}
if(!new File(folder, fn).isDirectory())
{
a.add("ERROR: " + new File(folder, fn).getAbsolutePath() + " must be a folder, not a file!");
return a;
}
for(File i : new File(folder, fn).listFiles())
{
if(i.isFile() && i.getName().endsWith(".json"))
{
if(!i.getName().toLowerCase().equals(i.getName()))
{
a.add("WARN: " + i.getAbsolutePath() + " has upper case letters in the file name.");
}
if(i.getName().contains(" "))
{
a.add("WARN: " + i.getAbsolutePath() + " has spaces in the file name.");
}
Object o;
JSONObject j;
try
{
Iris.info("Reading " + i.getPath());
j = new JSONObject(IO.readAll(i));
o = new Gson().fromJson(j.toString(), t.getClass());
a.addAll(analyze(o, i));
verify(j, o, a, i);
}
catch(Throwable e)
{
a.add("ERROR: Failed to read " + i.getAbsolutePath() + ": " + e.getMessage());
}
}
else
{
a.add("WARN: " + i.getAbsolutePath() + " should not be in this directory.");
}
}
return a;
}
private void verify(JSONObject j, Object o, KList<String> a, File m)
{
for(String i : j.keySet())
{
try
{
JSONObject jj = j.getJSONObject(i);
try
{
Field f = o.getClass().getDeclaredField(i);
if(f.isEnumConstant() || f.getType().isEnum() || f.getType().isPrimitive())
{
a.add("ERROR: Unexptected type: " + i + " into " + f.getType() + " expected. Got a jsonObject in " + o.getClass() + " in " + m.getAbsolutePath());
continue;
}
f.setAccessible(true);
Object oo = f.get(o);
if(oo == null)
{
a.add("WARN: Incorrect injection on " + o.getClass() + "." + i);
}
verify(jj, oo, a, m);
}
catch(Throwable e)
{
a.add("WARN: Unexptected Field: " + i + " in " + o.getClass().getSimpleName() + " from " + m.getAbsolutePath() + " " + e.getClass().getSimpleName() + " " + e.getMessage());
}
}
catch(Throwable enn)
{
}
}
}
public KList<String> analyze(File project)
{
KList<String> a = new KList<String>();
a.addAll(analyzeFolder(project, "dimensions", new IrisDimension()));
a.addAll(analyzeFolder(project, "biomes", new IrisBiome()));
a.addAll(analyzeFolder(project, "regions", new IrisRegion()));
a.addAll(analyzeFolder(project, "generators", new IrisGenerator()));
a.addAll(analyzeFolder(project, "structures", new IrisStructure()));
return a;
}
public KList<String> analyze(Object o, File file)
{
KList<String> a = new KList<String>();
String t;
try
{
t = IO.readAll(file);
}
catch(IOException e1)
{
a.add("ERROR: Unable to read " + file.getAbsolutePath() + ": " + e1.getMessage());
return a;
}
JSONObject j;
try
{
j = new JSONObject(t);
}
catch(Throwable e)
{
a.add("ERROR: Unable to parse json " + file.getAbsolutePath() + ": " + e.getMessage());
return a;
}
for(String i : j.keySet())
{
try
{
Field f = o.getClass().getDeclaredField(i);
if(f == null)
{
throw new NullPointerException();
}
}
catch(Throwable e)
{
a.add("WARN: Unreconized Field (key): " + i + " in " + file.getAbsolutePath() + ". Delete this key/value pair: " + o.getClass().getSimpleName());
}
}
return a;
}
public void writeDocs(File folder) throws IOException, JSONException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException
{
File of = new File(folder, "_docs");
KList<String> m = new KList<>();
for(Biome i : Biome.values())
{
m.add(i.name());
}
IO.writeAll(new File(of, "biomes.txt"), m.toString("\n"));
m = new KList<>();
for(Particle i : Particle.values())
{
m.add(i.name());
}
IO.writeAll(new File(of, "particles.txt"), m.toString("\n"));
m = new KList<>();
for(NoiseStyle i : NoiseStyle.values())
{
m.add(i.name());
}
IO.writeAll(new File(of, "noise-style.txt"), m.toString("\n"));
m = new KList<>();
for(DecorationPart i : DecorationPart.values())
{
m.add(i.name());
}
IO.writeAll(new File(of, "decoration-part.txt"), m.toString("\n"));
m = new KList<>();
for(Environment i : Environment.values())
{
m.add(i.name());
}
IO.writeAll(new File(of, "environment.txt"), m.toString("\n"));
m = new KList<>();
for(StructureTileCondition i : StructureTileCondition.values())
{
m.add(i.name());
}
IO.writeAll(new File(of, "structure-tile-condition.txt"), m.toString("\n"));
m = new KList<>();
for(InterpolationMethod i : InterpolationMethod.values())
{
m.add(i.name());
}
IO.writeAll(new File(of, "interpolation-method.txt"), m.toString("\n"));
m = new KList<>();
for(PotionEffectType i : PotionEffectType.values())
{
m.add(i.getName().toUpperCase().replaceAll("\\Q \\E", "_"));
}
IO.writeAll(new File(of, "potioneffects.txt"), m.toString("\n"));
}
}