SubCreator File Replacements

SubCreator has several new build options for updating and making replacements in files
This commit is contained in:
ME1312 2020-06-13 17:53:18 -04:00
parent bb0dd55c95
commit 9d01f46c16
No known key found for this signature in database
GPG Key ID: FEFFE2F698E88FA8
28 changed files with 644 additions and 284 deletions

63
.gitattributes vendored
View File

@ -1,63 +0,0 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

57
.gitignore vendored
View File

@ -1,50 +1,17 @@
# SubServers 2 Ignored Files # Hide System and IDE Generated Files
*.iml
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
*.userprefs
## Directory-based project format:
.idea/
## File-based project format:
*.ipr
*.iws
# IntelliJ
/out/ /out/
.idea/
*.iml
.DS_STORE
# mpeltonen/sbt-idea plugin # Hide Unfinished Projects
.idea_modules/ /SubServers.Test/
# JIRA plugin # Hide Compiled Artifacts
atlassian-ide-plugin.xml /Artifacts/*
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
# Hide Unfinished Project Files
/SubServers.Client/Windows/
/Artifacts/SubServers.Web.jar
/SubServers.Velocity/
/SubServers.Web/
# Hide Others
/Artifacts/-Maven/
/Artifacts/-History/
/Artifacts/-Icon/
/Artifacts/-Lite/
/Artifacts/*.jar
/BungeeCord/ /BungeeCord/
/Javadoc/ /Javadoc/
/SubServers.Test/
/build.ant # Show Interpreted Artifacts
/build.log !/Artifacts/Download/
.DS_STORE !/Artifacts/SubServers.Patcher.sh

Binary file not shown.

View File

@ -14,6 +14,7 @@ import net.ME1312.Galaxi.Library.Config.YAMLConfig;
import net.ME1312.Galaxi.Library.Map.ObjectMap; import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Version.Version; import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger; import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Bungee.Library.ReplacementScanner;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExConfigureHost; import net.ME1312.SubServers.Bungee.Network.Packet.PacketExConfigureHost;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExCreateServer; import net.ME1312.SubServers.Bungee.Network.Packet.PacketExCreateServer;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketExDownloadTemplates; import net.ME1312.SubServers.Bungee.Network.Packet.PacketExDownloadTemplates;
@ -103,24 +104,16 @@ public class ExternalSubCreator extends SubCreator {
final SubCreateEvent event = new SubCreateEvent(player, host, name, template, version, port); final SubCreateEvent event = new SubCreateEvent(player, host, name, template, version, port);
host.plugin.getPluginManager().callEvent(event); host.plugin.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
Container<String> address = new Container<>("$address$");
ReturnCallback<Object, Object> conversion = obj -> convert(obj, new NamedContainer<>("$player$", (player == null)?"":player.toString()), new NamedContainer<>("$name$", name),
new NamedContainer<>("$host$", host.getName()), new NamedContainer<>("$template$", template.getName()), new NamedContainer<>("$type$", template.getType().toString()), new NamedContainer<>("$version$", (version != null)?version.toString():""),
new NamedContainer<>("$address$", address.get()), new NamedContainer<>("$port$", Integer.toString(fport)));
logger.start(); logger.start();
host.queue(new PacketExCreateServer(name, template, version, port, (template.getConfigOptions().contains("Directory"))?conversion.run(template.getConfigOptions().getRawString("Directory")).toString():name, logger.getExternalAddress(), data -> { host.queue(new PacketExCreateServer(player, name, template, version, port, logger.getExternalAddress(), data -> {
try { try {
if (data.getInt(0x0001) == 0) { if (data.getInt(0x0001) == 0) {
Logger.get(prefix).info("Saving..."); Logger.get(prefix).info("Saving...");
address.set(data.getRawString(0x0003));
if (host.plugin.exServers.keySet().contains(name.toLowerCase())) if (host.plugin.exServers.keySet().contains(name.toLowerCase()))
host.plugin.exServers.remove(name.toLowerCase()); host.plugin.exServers.remove(name.toLowerCase());
ObjectMap<String> server = new ObjectMap<String>(); ObjectMap<String> server = new ObjectMap<String>();
ObjectMap<String> config = new ObjectMap<String>((Map<String, ?>) conversion.run(data.getMap(0x0002).get())); ObjectMap<String> config = new ObjectMap<String>((Map<String, ?>) data.getObject(0x0002));
config.remove("\033address");
server.set("Enabled", true); server.set("Enabled", true);
server.set("Display", ""); server.set("Display", "");
@ -157,7 +150,7 @@ public class ExternalSubCreator extends SubCreator {
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, fport, subserver, false, true)); host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, fport, subserver, false, true));
callback(origin, callback, subserver); callback(origin, callback, subserver);
} else { } else {
Logger.get(prefix).info(data.getString(0x0004)); Logger.get(prefix).info(data.getString(0x0003));
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, fport, null, false, false)); host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, template, version, fport, null, false, false));
callback(origin, callback, null); callback(origin, callback, null);
} }
@ -174,28 +167,6 @@ public class ExternalSubCreator extends SubCreator {
return false; return false;
} }
} else return false; } else return false;
} private Object convert(Object value, NamedContainer<String, String>... replacements) {
if (value instanceof Map) {
List<String> list = new ArrayList<String>();
list.addAll(((Map<String, Object>) value).keySet());
for (String key : list) ((Map<String, Object>) value).put(key, convert(((Map<String, Object>) value).get(key), replacements));
return value;
} else if (value instanceof Collection) {
List<Object> list = new ArrayList<Object>();
for (Object val : (Collection<Object>) value) list.add(convert(val, replacements));
return list;
} else if (value.getClass().isArray()) {
List<Object> list = new ArrayList<Object>();
for (int i = 0; i < ((Object[]) value).length; i++) list.add(convert(((Object[]) value)[i], replacements));
return list;
} else if (value instanceof String) {
return replace((String) value, replacements);
} else {
return value;
}
} private String replace(String string, NamedContainer<String, String>... replacements) {
for (NamedContainer<String, String> replacement : replacements) string = string.replace(replacement.name(), replacement.get());
return string;
} private <T> void callback(StackTraceElement[] origin, Callback<T> callback, T value) { } private <T> void callback(StackTraceElement[] origin, Callback<T> callback, T value) {
if (callback != null) try { if (callback != null) try {
callback.run(value); callback.run(value);
@ -222,12 +193,12 @@ public class ExternalSubCreator extends SubCreator {
host.plugin.getPluginManager().callEvent(event); host.plugin.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
logger.start(); logger.start();
host.queue(new PacketExCreateServer(server, version, logger.getExternalAddress(), data -> { host.queue(new PacketExCreateServer(player, server, version, logger.getExternalAddress(), data -> {
Util.isException(() -> Util.reflect(SubServerImpl.class.getDeclaredField("updating"), server, false)); Util.isException(() -> Util.reflect(SubServerImpl.class.getDeclaredField("updating"), server, false));
if (data.getInt(0x0001) == 0) { if (data.getInt(0x0001) == 0) {
Logger.get(prefix).info("Saving..."); Logger.get(prefix).info("Saving...");
} else { } else {
Logger.get(prefix).info(data.getString(0x0004)); Logger.get(prefix).info(data.getString(0x0003));
} }
host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, server.getTemplate(), version, server.getAddress().getPort(), server, true, data.getInt(0x0001) == 0)); host.plugin.getPluginManager().callEvent(new SubCreatedEvent(player, host, name, server.getTemplate(), version, server.getAddress().getPort(), server, true, data.getInt(0x0001) == 0));

View File

@ -8,6 +8,7 @@ import net.ME1312.Galaxi.Library.Callback.ReturnCallback;
import net.ME1312.Galaxi.Library.Config.YAMLSection; import net.ME1312.Galaxi.Library.Config.YAMLSection;
import net.ME1312.Galaxi.Library.Container.Container; import net.ME1312.Galaxi.Library.Container.Container;
import net.ME1312.Galaxi.Library.Container.NamedContainer; import net.ME1312.Galaxi.Library.Container.NamedContainer;
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
import net.ME1312.SubServers.Bungee.Event.SubCreateEvent; import net.ME1312.SubServers.Bungee.Event.SubCreateEvent;
import net.ME1312.SubServers.Bungee.Event.SubCreatedEvent; import net.ME1312.SubServers.Bungee.Event.SubCreatedEvent;
import net.ME1312.SubServers.Bungee.Host.*; import net.ME1312.SubServers.Bungee.Host.*;
@ -17,6 +18,7 @@ import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger;
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException; import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException;
import net.ME1312.SubServers.Bungee.Library.Exception.SubCreatorException; import net.ME1312.SubServers.Bungee.Library.Exception.SubCreatorException;
import net.ME1312.Galaxi.Library.Version.Version; import net.ME1312.Galaxi.Library.Version.Version;
import net.ME1312.SubServers.Bungee.Library.ReplacementScanner;
import net.ME1312.SubServers.Bungee.SubAPI; import net.ME1312.SubServers.Bungee.SubAPI;
import net.ME1312.SubServers.Bungee.SubProxy; import net.ME1312.SubServers.Bungee.SubProxy;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
@ -27,6 +29,9 @@ import java.net.InetSocketAddress;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -51,6 +56,7 @@ public class InternalSubCreator extends SubCreator {
private final int port; private final int port;
private final String prefix; private final String prefix;
private final InternalSubLogger log; private final InternalSubLogger log;
private final HashMap<String, String> replacements;
private final Callback<SubServer> callback; private final Callback<SubServer> callback;
private Process process; private Process process;
@ -63,6 +69,7 @@ public class InternalSubCreator extends SubCreator {
this.version = version; this.version = version;
this.port = port; this.port = port;
this.log = new InternalSubLogger(null, this, prefix = name + File.separator + "Creator", InternalSubCreator.this.log, null); this.log = new InternalSubLogger(null, this, prefix = name + File.separator + "Creator", InternalSubCreator.this.log, null);
this.replacements = new HashMap<String, String>();
this.callback = callback; this.callback = callback;
} }
@ -75,6 +82,7 @@ public class InternalSubCreator extends SubCreator {
this.version = version; this.version = version;
this.port = server.getAddress().getPort(); this.port = server.getAddress().getPort();
this.log = new InternalSubLogger(null, this, prefix = name + File.separator + "Updater", InternalSubCreator.this.log, null); this.log = new InternalSubLogger(null, this, prefix = name + File.separator + "Updater", InternalSubCreator.this.log, null);
this.replacements = new HashMap<String, String>();
this.callback = callback; this.callback = callback;
} }
@ -112,14 +120,24 @@ public class InternalSubCreator extends SubCreator {
server.setAll(template.getConfigOptions()); server.setAll(template.getConfigOptions());
try { try {
Logger.get(prefix).info("Loading Template: " + template.getDisplayName()); Logger.get(prefix).info("Loading Template: " + template.getDisplayName());
Util.copyDirectory(template.getDirectory(), dir); if (template.getBuildOptions().getBoolean("Update-Files", false)) updateDirectory(template.getDirectory(), dir);
else Util.copyDirectory(template.getDirectory(), dir);
for (ObjectMapValue<String> replacement : template.getBuildOptions().getMap("Replacements").getValues()) if (!replacement.isNull()) {
replacements.put(replacement.getHandle().toLowerCase().replace('-', '_').replace(' ', '_'), replacement.asRawString());
}
var.putAll(replacements);
var.put("java", System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"); var.put("java", System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
var.put("mode", (update == null)?"CREATE":"UPDATE"); var.put("mode", (update == null)?"CREATE":"UPDATE");
if (player != null) var.put("player", player.toString().toUpperCase());
else var.remove("player");
var.put("name", name); var.put("name", name);
var.put("host", host.getName()); var.put("host", host.getName());
var.put("template", template.getName()); var.put("template", template.getName());
var.put("type", template.getType().toString().toUpperCase()); var.put("type", template.getType().toString().toUpperCase());
if (version != null) var.put("version", version.toString()); if (version != null) var.put("version", version.toString());
else var.remove("version");
var.put("address", host.getAddress().getHostAddress()); var.put("address", host.getAddress().getHostAddress());
var.put("port", Integer.toString(port)); var.put("port", Integer.toString(port));
switch (template.getType()) { switch (template.getType()) {
@ -203,19 +221,26 @@ public class InternalSubCreator extends SubCreator {
} }
public void run() { public void run() {
ReturnCallback<Object, Object> conversion = obj -> convert(obj, new NamedContainer<>("$player$", (player == null)?"":player.toString()), new NamedContainer<>("$name$", name), Runnable declaration = () -> {
new NamedContainer<>("$host$", host.getName()), new NamedContainer<>("$template$", template.getName()), new NamedContainer<>("$type$", template.getType().toString()), new NamedContainer<>("$version$", (version != null)?version.toString():""), replacements.put("player", (player == null)?"":player.toString());
new NamedContainer<>("$address$", host.getAddress().getHostAddress()), new NamedContainer<>("$port$", Integer.toString(port))); replacements.put("name", name);
replacements.put("host", host.getName());
replacements.put("template", template.getName());
replacements.put("type", template.getType().toString());
replacements.put("version", (version != null)?version.toString():"");
replacements.put("address", host.getAddress().getHostAddress());
replacements.put("port", Integer.toString(port));
};
declaration.run();
File dir = (update != null)?new File(update.getFullPath()):new File(host.getPath(), File dir = (update != null)?new File(update.getFullPath()):new File(host.getPath(),
(template.getConfigOptions().contains("Directory"))?conversion.run(template.getConfigOptions().getRawString("Directory")).toString():name); (template.getConfigOptions().contains("Directory"))?new ReplacementScanner(replacements).replace(template.getConfigOptions().getRawString("Directory")).toString():name);
dir.mkdirs(); dir.mkdirs();
ObjectMap<String> server = new ObjectMap<String>(); ObjectMap<String> server = new ObjectMap<String>();
ObjectMap<String> config; ObjectMap<String> config;
try { try {
config = build(dir, template, new LinkedList<>()); config = build(dir, template, new LinkedList<>());
generateProperties(dir, port);
generateClient(dir, template.getType(), name);
} catch (SubCreatorException e) { } catch (SubCreatorException e) {
config = null; config = null;
} catch (Exception e) { } catch (Exception e) {
@ -223,6 +248,22 @@ public class InternalSubCreator extends SubCreator {
e.printStackTrace(); e.printStackTrace();
} }
declaration.run();
ReplacementScanner replacements = new ReplacementScanner(this.replacements);
if (config != null) {
try {
if (template.getBuildOptions().getBoolean("Install-Client", true)) generateClient(dir, template.getType(), name);
LinkedList<String> masks = new LinkedList<>();
masks.add("/server.properties");
masks.addAll(template.getBuildOptions().getRawStringList("Replace", Collections.emptyList()));
replacements.replace(dir, masks.toArray(new String[0]));
} catch (Exception e) {
config = null;
e.printStackTrace();
}
}
if (config != null) { if (config != null) {
try { try {
Logger.get(prefix).info("Saving..."); Logger.get(prefix).info("Saving...");
@ -231,7 +272,7 @@ public class InternalSubCreator extends SubCreator {
if (host.plugin.exServers.keySet().contains(name.toLowerCase())) if (host.plugin.exServers.keySet().contains(name.toLowerCase()))
host.plugin.exServers.remove(name.toLowerCase()); host.plugin.exServers.remove(name.toLowerCase());
config = new ObjectMap<String>((Map<String, ?>) conversion.run(config.get())); config = new ObjectMap<String>((Map<String, ?>) replacements.replace(config.get()));
server.set("Enabled", true); server.set("Enabled", true);
server.set("Display", ""); server.set("Display", "");
@ -281,28 +322,6 @@ public class InternalSubCreator extends SubCreator {
callback.run(null); callback.run(null);
} }
InternalSubCreator.this.thread.remove(name.toLowerCase()); InternalSubCreator.this.thread.remove(name.toLowerCase());
} private Object convert(Object value, NamedContainer<String, String>... replacements) {
if (value instanceof Map) {
List<String> list = new ArrayList<String>();
list.addAll(((Map<String, Object>) value).keySet());
for (String key : list) ((Map<String, Object>) value).put(key, convert(((Map<String, Object>) value).get(key), replacements));
return value;
} else if (value instanceof Collection) {
List<Object> list = new ArrayList<Object>();
for (Object val : (Collection<Object>) value) list.add(convert(val, replacements));
return list;
} else if (value.getClass().isArray()) {
List<Object> list = new ArrayList<Object>();
for (int i = 0; i < ((Object[]) value).length; i++) list.add(convert(((Object[]) value)[i], replacements));
return list;
} else if (value instanceof String) {
return replace((String) value, replacements);
} else {
return value;
}
} private String replace(String string, NamedContainer<String, String>... replacements) {
for (NamedContainer<String, String> replacement : replacements) string = string.replace(replacement.name(), replacement.get());
return string;
} }
} }
@ -528,7 +547,7 @@ public class InternalSubCreator extends SubCreator {
} }
private static NamedContainer<YAMLSection, Map<String, Object>> subdata = null; private static NamedContainer<YAMLSection, Map<String, Object>> subdata = null;
private Map<String, Object> getSubDataConfig() { private Map<String, Object> getSubData() {
if (subdata == null || host.plugin.config.get() != subdata.name()) { if (subdata == null || host.plugin.config.get() != subdata.name()) {
Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> map = new HashMap<String, Object>();
map.put("Address", host.plugin.config.get().getMap("Settings").getMap("SubData").getRawString("Address", "127.0.0.1").replace("0.0.0.0", "127.0.0.1")); map.put("Address", host.plugin.config.get().getMap("Settings").getMap("SubData").getRawString("Address", "127.0.0.1").replace("0.0.0.0", "127.0.0.1"));
@ -539,21 +558,24 @@ public class InternalSubCreator extends SubCreator {
} }
private void generateClient(File dir, ServerType type, String name) throws IOException { private void generateClient(File dir, ServerType type, String name) throws IOException {
if (new UniversalFile(dir, "subservers.client").exists()) { boolean installed = false;
Files.delete(new UniversalFile(dir, "subservers.client").toPath()); if (type == ServerType.SPIGOT) {
if (type == ServerType.SPIGOT) { installed = true;
if (!new UniversalFile(dir, "plugins").exists()) new UniversalFile(dir, "plugins").mkdirs(); if (!new UniversalFile(dir, "plugins").exists()) new UniversalFile(dir, "plugins").mkdirs();
if (!new UniversalFile(dir, "plugins:SubServers.Client.jar").exists()) if (!new UniversalFile(dir, "plugins:SubServers.Client.jar").exists())
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(dir, "plugins:SubServers.Client.jar").getPath()); Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(dir, "plugins:SubServers.Client.jar").getPath());
} else if (type == ServerType.FORGE || type == ServerType.SPONGE) { } else if (type == ServerType.FORGE || type == ServerType.SPONGE) {
if (!new UniversalFile(dir, "mods").exists()) new UniversalFile(dir, "mods").mkdirs(); installed = true;
if (!new UniversalFile(dir, "mods:SubServers.Client.jar").exists()) if (!new UniversalFile(dir, "mods").exists()) new UniversalFile(dir, "mods").mkdirs();
Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(dir, "mods:SubServers.Client.jar").getPath()); if (!new UniversalFile(dir, "mods:SubServers.Client.jar").exists())
} Util.copyFromJar(SubProxy.class.getClassLoader(), "net/ME1312/SubServers/Bungee/Library/Files/client.jar", new UniversalFile(dir, "mods:SubServers.Client.jar").getPath());
}
if (installed) {
YAMLSection config = new YAMLSection(); YAMLSection config = new YAMLSection();
FileWriter writer = new FileWriter(new UniversalFile(dir, "subdata.json"), false); FileWriter writer = new FileWriter(new UniversalFile(dir, "subdata.json"), false);
config.set("Name", name); config.set("Name", name);
config.setAll(getSubDataConfig()); config.setAll(getSubData());
writer.write(config.toJSON().toString()); writer.write(config.toJSON().toString());
writer.close(); writer.close();
@ -562,15 +584,46 @@ public class InternalSubCreator extends SubCreator {
} }
} }
} }
private void generateProperties(File dir, int port) throws IOException {
File file = new File(dir, "server.properties"); private void updateDirectory(File from, File to) {
if (!file.exists()) file.createNewFile(); if (from.isDirectory() && !Files.isSymbolicLink(from.toPath())) {
InputStream stream = new FileInputStream(file); if (!to.exists()) {
String content = Util.readAll(new BufferedReader(new InputStreamReader(stream))).replaceAll("server-port=.*(\r?\n)", "server-port=" + port + "$1").replaceAll("server-ip=.*(\r?\n)", "server-ip=" + host.getAddress().getHostAddress() + "$1"); to.mkdirs();
stream.close(); }
file.delete();
PrintWriter writer = new PrintWriter(file, "UTF-8"); String files[] = from.list();
writer.write(content);
writer.close(); for (String file : files) {
File srcFile = new File(from, file);
File destFile = new File(to, file);
updateDirectory(srcFile, destFile);
}
} else {
try {
if (!to.exists() || from.length() != to.length() || !Arrays.equals(generateSHA256(to), generateSHA256(from))) {
if (to.exists()) {
if (to.isDirectory()) Util.deleteDirectory(to);
else to.delete();
}
Files.copy(from.toPath(), to.toPath(), LinkOption.NOFOLLOW_LINKS, StandardCopyOption.REPLACE_EXISTING);
}
} catch (Exception e) {
e.printStackTrace();
}
}
} private byte[] generateSHA256(File file) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
FileInputStream fis = new FileInputStream(file);
byte[] dataBytes = new byte[1024];
int nread;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
}
fis.close();
return md.digest();
} }
} }

View File

@ -76,7 +76,7 @@ public class RemotePlayer implements SubDataSerializable {
} }
/** /**
* Get this connection's UUID, if set. * Get the UUID of this player.
* *
* @return the UUID * @return the UUID
*/ */

View File

@ -0,0 +1,169 @@
package net.ME1312.SubServers.Bungee.Library;
import net.ME1312.Galaxi.Library.Util;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.regex.Pattern;
/**
* File Replacement Scanner
*/
public class ReplacementScanner {
private final Map<String, String> replacements = new LinkedHashMap<>();
public ReplacementScanner(Map<String, String> replacements) {
TreeMap<Integer, LinkedList<String>> order = new TreeMap<Integer, LinkedList<String>>(Comparator.reverseOrder());
for (String key : replacements.keySet()) {
int length = key.length();
if (!order.keySet().contains(length)) order.put(length, new LinkedList<>());
order.get(length).add(key);
}
for (Integer length : order.keySet()) {
for (String key : order.get(length)) {
this.replacements.put(key, replacements.get(key));
}
}
}
/**
* Get the replacements
*
* @return Replacement Map
*/
public Map<String, String> getReplacements() {
return new HashMap<>(replacements);
}
/**
* Make replacements in a File or Directory
*
* @param dir File or Directory
* @param whitelist File Whitelist
*/
public void replace(File dir, String... whitelist) throws IOException {
List<String> files;
try {
files = Util.reflect(Util.class.getDeclaredMethod("zipsearch", File.class, File.class), null, dir, dir);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new IllegalStateException("Cannot access zipsearch()", e);
}
LinkedHashMap<Pattern, Boolean> rules = new LinkedHashMap<Pattern, Boolean>();
for (String entry : whitelist) {
boolean mode = !entry.startsWith("!");
if (!mode) entry = entry.substring(1);
if (entry.startsWith(".")) entry = entry.substring(1);
StringBuilder rule = new StringBuilder();
if (entry.startsWith("**")) {
entry = entry.substring(2);
rule.append("^.*");
} else if (entry.startsWith("/")) {
rule.append("^");
}
boolean greedyEnding = false;
if (entry.endsWith("**")) {
entry = entry.substring(0, entry.length() - 2);
greedyEnding = true;
} else if (entry.endsWith("/")) {
greedyEnding = true;
}
StringBuilder literal = new StringBuilder();
for (PrimitiveIterator.OfInt i = entry.codePoints().iterator(); i.hasNext(); ) {
int c = i.next();
if ((c == '*' || c == '?' || c == '[') && literal.length() > 0) {
rule.append(Pattern.quote(literal.toString()));
literal = new StringBuilder();
}
switch (c) {
case '\\':
if (i.hasNext()) c = i.next();
literal.appendCodePoint(c);
case '[':
for (boolean escaped = false; i.hasNext() && (c != ']' || escaped); c = i.next()) {
if (c == '\\') escaped = !escaped;
else escaped = false;
literal.appendCodePoint(c);
}
if (c == ']' && literal.length() > 1) {
literal.appendCodePoint(c);
rule.append(literal.toString());
}
literal = new StringBuilder();
break;
case '*':
rule.append("[^/]+");
break;
case '?':
rule.append("[^/]");
break;
default:
literal.appendCodePoint(c);
break;
}
}
if (literal.length() > 0)
rule.append(Pattern.quote(literal.toString()));
if (greedyEnding)
rule.append(".*");
rule.append("$");
rules.put(Pattern.compile(rule.toString()), mode);
}
for (String file : files) {
boolean act = false;
for (Map.Entry<Pattern, Boolean> rule : rules.entrySet()) {
if (rule.getKey().matcher('/' + file.replace(File.separatorChar, '/')).find()) act = rule.getValue();
}
if (act) replaceFile(new File(dir, file));
}
} private void replaceFile(File file) throws IOException {
FileInputStream stream = new FileInputStream(file);
String string = Util.readAll(new InputStreamReader(stream));
stream.close();
for (Map.Entry<String, String> replacement : replacements.entrySet()) string = string.replace("SubServers::" + replacement.getKey(), replacement.getValue());
FileWriter writer = new FileWriter(file, false);
writer.write(string);
writer.close();
}
/**
* Make replacements in an Object
*
* @param value Map, Collection, Array, or String
* @return Object with replaced variables
*/
public Object replace(Object value) {
if (value instanceof Map) {
List<String> list = new ArrayList<String>();
list.addAll(((Map<String, Object>) value).keySet());
for (String key : list) ((Map<String, Object>) value).put(key, replace(((Map<String, Object>) value).get(key)));
return value;
} else if (value instanceof Collection) {
List<Object> list = new ArrayList<Object>();
for (Object val : (Collection<Object>) value) list.add(replace(val));
return list;
} else if (value.getClass().isArray()) {
List<Object> list = new ArrayList<Object>();
for (int i = 0; i < ((Object[]) value).length; i++) list.add(replace(((Object[]) value)[i]));
return list;
} else if (value instanceof String) {
return replaceObj((String) value);
} else {
return value;
}
} private String replaceObj(String string) {
for (Map.Entry<String, String> replacement : replacements.entrySet()) string = string.replace('$' + replacement.getKey() + '$', replacement.getValue());
return string;
}
}

View File

@ -18,6 +18,7 @@ import java.util.UUID;
*/ */
public class PacketExCreateServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> { public class PacketExCreateServer implements PacketObjectIn<Integer>, PacketObjectOut<Integer> {
private static HashMap<UUID, Callback<ObjectMap<Integer>>[]> callbacks = new HashMap<UUID, Callback<ObjectMap<Integer>>[]>(); private static HashMap<UUID, Callback<ObjectMap<Integer>>[]> callbacks = new HashMap<UUID, Callback<ObjectMap<Integer>>[]>();
private UUID player;
private String name; private String name;
private SubCreator.ServerTemplate template; private SubCreator.ServerTemplate template;
private Version version; private Version version;
@ -36,14 +37,16 @@ public class PacketExCreateServer implements PacketObjectIn<Integer>, PacketObje
/** /**
* New PacketExCreateServer (Out) * New PacketExCreateServer (Out)
* *
* @param player Player
* @param server Server to Update * @param server Server to Update
* @param version Server Version * @param version Server Version
* @param log Log Address * @param log Log Address
* @param callback Callbacks * @param callback Callbacks
*/ */
@SafeVarargs @SafeVarargs
public PacketExCreateServer(SubServer server, Version version, UUID log, Callback<ObjectMap<Integer>>... callback) { public PacketExCreateServer(UUID player, SubServer server, Version version, UUID log, Callback<ObjectMap<Integer>>... callback) {
if (Util.isNull(server, log, callback)) throw new NullPointerException(); if (Util.isNull(server, log, callback)) throw new NullPointerException();
this.player = player;
this.name = server.getName(); this.name = server.getName();
this.template = server.getTemplate(); this.template = server.getTemplate();
this.version = version; this.version = version;
@ -57,22 +60,22 @@ public class PacketExCreateServer implements PacketObjectIn<Integer>, PacketObje
/** /**
* New PacketExCreateServer (Out) * New PacketExCreateServer (Out)
* *
* @param player Player
* @param name Server Name * @param name Server Name
* @param template Server Template * @param template Server Template
* @param version Server Version * @param version Server Version
* @param port Server Port Number * @param port Server Port Number
* @param directory Server Directory
* @param log Log Address * @param log Log Address
* @param callback Callbacks * @param callback Callbacks
*/ */
@SafeVarargs @SafeVarargs
public PacketExCreateServer(String name, SubCreator.ServerTemplate template, Version version, int port, String directory, UUID log, Callback<ObjectMap<Integer>>... callback) { public PacketExCreateServer(UUID player, String name, SubCreator.ServerTemplate template, Version version, int port, UUID log, Callback<ObjectMap<Integer>>... callback) {
if (Util.isNull(name, template, port, log, callback)) throw new NullPointerException(); if (Util.isNull(name, template, port, log, callback)) throw new NullPointerException();
this.player = player;
this.name = name; this.name = name;
this.template = template; this.template = template;
this.version = version; this.version = version;
this.port = port; this.port = port;
this.dir = directory;
this.log = log; this.log = log;
this.tracker = Util.getNew(callbacks.keySet(), UUID::randomUUID); this.tracker = Util.getNew(callbacks.keySet(), UUID::randomUUID);
callbacks.put(tracker, callback); callbacks.put(tracker, callback);
@ -89,8 +92,9 @@ public class PacketExCreateServer implements PacketObjectIn<Integer>, PacketObje
data.set(0x0003, template.getName()); data.set(0x0003, template.getName());
data.set(0x0004, version); data.set(0x0004, version);
data.set(0x0005, port); data.set(0x0005, port);
data.set(0x0006, dir); data.set(0x0006, log);
data.set(0x0007, log); if (player != null)
data.set(0x0007, player);
} }
return data; return data;
} }

View File

@ -137,28 +137,29 @@ public final class SubProxy extends BungeeCord implements Listener {
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip"), new UniversalFile(dir, "Templates")); Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Created ./SubServers/Templates/Sponge"); Logger.get("SubServers").info("Created ./SubServers/Templates/Sponge");
} else { } else {
if (new UniversalFile(dir, "Templates:Vanilla:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Vanilla:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.15a+")) != 0) { long stamp = Math.round(Math.random() * 100000);
Files.move(new UniversalFile(dir, "Templates:Vanilla").toPath(), new UniversalFile(dir, "Templates:Vanilla.old" + Math.round(Math.random() * 100000) + ".x").toPath()); if (new UniversalFile(dir, "Templates:Vanilla:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Vanilla:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.16a+")) != 0) {
Files.move(new UniversalFile(dir, "Templates:Vanilla").toPath(), new UniversalFile(dir, "Templates:Vanilla." + stamp + ".x").toPath());
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/vanilla.zip"), new UniversalFile(dir, "Templates")); Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/vanilla.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Updated ./SubServers/Templates/Vanilla"); Logger.get("SubServers").info("Updated ./SubServers/Templates/Vanilla");
} }
if (new UniversalFile(dir, "Templates:Spigot:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Spigot:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.15a+")) != 0) { if (new UniversalFile(dir, "Templates:Spigot:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Spigot:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.16a+")) != 0) {
Files.move(new UniversalFile(dir, "Templates:Spigot").toPath(), new UniversalFile(dir, "Templates:Spigot.old" + Math.round(Math.random() * 100000) + ".x").toPath()); Files.move(new UniversalFile(dir, "Templates:Spigot").toPath(), new UniversalFile(dir, "Templates:Spigot." + stamp + ".x").toPath());
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip"), new UniversalFile(dir, "Templates")); Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Updated ./SubServers/Templates/Spigot"); Logger.get("SubServers").info("Updated ./SubServers/Templates/Spigot");
} }
if (new UniversalFile(dir, "Templates:Paper:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Paper:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.15a+")) != 0) { if (new UniversalFile(dir, "Templates:Paper:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Paper:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.16a+")) != 0) {
Files.move(new UniversalFile(dir, "Templates:Paper").toPath(), new UniversalFile(dir, "Templates:Paper.old" + Math.round(Math.random() * 100000) + ".x").toPath()); Files.move(new UniversalFile(dir, "Templates:Paper").toPath(), new UniversalFile(dir, "Templates:Paper." + stamp + ".x").toPath());
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip"), new UniversalFile(dir, "Templates")); Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/paper.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Updated ./SubServers/Templates/Paper"); Logger.get("SubServers").info("Updated ./SubServers/Templates/Paper");
} }
if (new UniversalFile(dir, "Templates:Forge:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Forge:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.15a+")) != 0) { if (new UniversalFile(dir, "Templates:Forge:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Forge:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.16a+")) != 0) {
Files.move(new UniversalFile(dir, "Templates:Forge").toPath(), new UniversalFile(dir, "Templates:Forge.old" + Math.round(Math.random() * 100000) + ".x").toPath()); Files.move(new UniversalFile(dir, "Templates:Forge").toPath(), new UniversalFile(dir, "Templates:Forge." + stamp + ".x").toPath());
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip"), new UniversalFile(dir, "Templates")); Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Updated ./SubServers/Templates/Forge"); Logger.get("SubServers").info("Updated ./SubServers/Templates/Forge");
} }
if (new UniversalFile(dir, "Templates:Sponge:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Sponge:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.15a+")) != 0) { if (new UniversalFile(dir, "Templates:Sponge:template.yml").exists() && ((new YAMLConfig(new UniversalFile(dir, "Templates:Sponge:template.yml"))).get().getVersion("Version", new Version(0))).compareTo(new Version("2.16a+")) != 0) {
Files.move(new UniversalFile(dir, "Templates:Sponge").toPath(), new UniversalFile(dir, "Templates:Sponge.old" + Math.round(Math.random() * 100000) + ".x").toPath()); Files.move(new UniversalFile(dir, "Templates:Sponge").toPath(), new UniversalFile(dir, "Templates:Sponge." + stamp + ".x").toPath());
Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip"), new UniversalFile(dir, "Templates")); Util.unzip(SubProxy.class.getResourceAsStream("/net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip"), new UniversalFile(dir, "Templates"));
Logger.get("SubServers").info("Updated ./SubServers/Templates/Sponge"); Logger.get("SubServers").info("Updated ./SubServers/Templates/Sponge");
} }

View File

@ -47,7 +47,7 @@ public class RemotePlayer {
} }
/** /**
* Get this connection's UUID, if set. * Get the UUID of this player.
* *
* @return the UUID * @return the UUID
*/ */

View File

@ -49,7 +49,7 @@ public class RemotePlayer {
} }
/** /**
* Get this connection's UUID, if set. * Get the UUID of this player.
* *
* @return the UUID * @return the UUID
*/ */

View File

@ -1 +0,0 @@
{}

View File

@ -1,4 +1,4 @@
Version: '2.15a+' Version: '2.16a+'
Template: Template:
Enabled: true Enabled: true
Icon: 'anvil' Icon: 'anvil'

View File

@ -1 +0,0 @@
{}

View File

@ -1,4 +1,4 @@
Version: '2.15a+' Version: '2.16a+'
Template: Template:
Enabled: true Enabled: true
Icon: 'paper' Icon: 'paper'

View File

@ -1,4 +1,4 @@
Version: '2.15a+' Version: '2.16a+'
Template: Template:
Enabled: true Enabled: true
Icon: 'lava_bucket' Icon: 'lava_bucket'

View File

@ -1,4 +1,4 @@
Version: '2.15a+' Version: '2.16a+'
Template: Template:
Enabled: true Enabled: true
Icon: 'sponge' Icon: 'sponge'

View File

@ -1,4 +1,4 @@
Version: '2.15a+' Version: '2.16a+'
Template: Template:
Enabled: true Enabled: true
Icon: 'bukkit:grass' Icon: 'bukkit:grass'

View File

@ -5,6 +5,7 @@ import net.ME1312.Galaxi.Library.Config.YAMLSection;
import net.ME1312.Galaxi.Library.Container.NamedContainer; import net.ME1312.Galaxi.Library.Container.NamedContainer;
import net.ME1312.Galaxi.Library.Map.ObjectMap; import net.ME1312.Galaxi.Library.Map.ObjectMap;
import net.ME1312.Galaxi.Library.Container.Container; import net.ME1312.Galaxi.Library.Container.Container;
import net.ME1312.Galaxi.Library.Map.ObjectMapValue;
import net.ME1312.Galaxi.Library.UniversalFile; import net.ME1312.Galaxi.Library.UniversalFile;
import net.ME1312.Galaxi.Library.Util; import net.ME1312.Galaxi.Library.Util;
import net.ME1312.Galaxi.Library.Version.Version; import net.ME1312.Galaxi.Library.Version.Version;
@ -13,6 +14,7 @@ import net.ME1312.SubServers.Host.ExHost;
import net.ME1312.SubServers.Host.Library.Exception.InvalidServerException; import net.ME1312.SubServers.Host.Library.Exception.InvalidServerException;
import net.ME1312.SubServers.Host.Library.Exception.InvalidTemplateException; import net.ME1312.SubServers.Host.Library.Exception.InvalidTemplateException;
import net.ME1312.SubServers.Host.Library.Exception.SubCreatorException; import net.ME1312.SubServers.Host.Library.Exception.SubCreatorException;
import net.ME1312.SubServers.Host.Library.ReplacementScanner;
import net.ME1312.SubServers.Host.Network.API.SubCreator.ServerType; import net.ME1312.SubServers.Host.Network.API.SubCreator.ServerType;
import net.ME1312.SubServers.Host.Network.Packet.PacketExCreateServer; import net.ME1312.SubServers.Host.Network.Packet.PacketExCreateServer;
import net.ME1312.SubServers.Host.Network.Packet.PacketOutExLogMessage; import net.ME1312.SubServers.Host.Network.Packet.PacketOutExLogMessage;
@ -23,6 +25,9 @@ import java.io.*;
import java.net.URL; import java.net.URL;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.util.*; import java.util.*;
/** /**
@ -198,25 +203,27 @@ public class SubCreatorImpl {
private class CreatorTask extends Thread { private class CreatorTask extends Thread {
private final SubServerImpl update; private final SubServerImpl update;
private final UUID player;
private final String name; private final String name;
private final ServerTemplate template; private final ServerTemplate template;
private final Version version; private final Version version;
private final int port; private final int port;
private final File dir;
private final UUID address; private final UUID address;
private final UUID tracker; private final UUID tracker;
private final SubLoggerImpl log; private final SubLoggerImpl log;
private final HashMap<String, String> replacements;
private Process process; private Process process;
private CreatorTask(String name, ServerTemplate template, Version version, int port, String dir, UUID address, UUID tracker) { private CreatorTask(UUID player, String name, ServerTemplate template, Version version, int port, UUID address, UUID tracker) {
super(SubAPI.getInstance().getAppInfo().getName() + "::SubCreator_Process_Handler(" + name + ')'); super(SubAPI.getInstance().getAppInfo().getName() + "::SubCreator_Process_Handler(" + name + ')');
this.update = host.servers.getOrDefault(name.toLowerCase(), null); this.update = host.servers.getOrDefault(name.toLowerCase(), null);
this.player = player;
this.name = name; this.name = name;
this.template = template; this.template = template;
this.version = version; this.version = version;
this.port = port; this.port = port;
this.dir = new File(host.host.getRawString("Directory"), dir);
this.log = new SubLoggerImpl(null, this, name + File.separator + ((update == null)?"Creator":"Updater"), address, new Container<Boolean>(true), null); this.log = new SubLoggerImpl(null, this, name + File.separator + ((update == null)?"Creator":"Updater"), address, new Container<Boolean>(true), null);
this.replacements = new HashMap<String, String>();
this.address = address; this.address = address;
this.tracker = tracker; this.tracker = tracker;
} }
@ -260,15 +267,25 @@ public class SubCreatorImpl {
try { try {
log.logger.info.println("Loading Template: " + template.getDisplayName()); log.logger.info.println("Loading Template: " + template.getDisplayName());
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Loading Template: " + template.getDisplayName())); ((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketOutExLogMessage(address, "Loading Template: " + template.getDisplayName()));
Util.copyDirectory(template.getDirectory(), dir); if (template.getBuildOptions().getBoolean("Update-Files", false)) updateDirectory(template.getDirectory(), dir);
else Util.copyDirectory(template.getDirectory(), dir);
for (ObjectMapValue<String> replacement : template.getBuildOptions().getMap("Replacements").getValues()) if (!replacement.isNull()) {
replacements.put(replacement.getHandle().toLowerCase().replace('-', '_').replace(' ', '_'), replacement.asRawString());
}
var.putAll(replacements);
var.put("java", System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"); var.put("java", System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
var.put("mode", (update == null)?"CREATE":"UPDATE"); var.put("mode", (update == null)?"CREATE":"UPDATE");
if (player != null) var.put("player", player.toString().toUpperCase());
else var.remove("player");
var.put("name", name); var.put("name", name);
if (SubAPI.getInstance().getSubDataNetwork()[0] != null) var.put("host", SubAPI.getInstance().getName()); var.put("host", SubAPI.getInstance().getName());
var.put("template", template.getName()); var.put("template", template.getName());
var.put("type", template.getType().toString().toUpperCase()); var.put("type", template.getType().toString().toUpperCase());
if (version != null) var.put("version", version.toString()); if (version != null) var.put("version", version.toString());
var.put("address", host.config.get().getMap("Settings").getRawString("Server-Bind")); else var.remove("version");
var.put("address", getAddress());
var.put("port", Integer.toString(port)); var.put("port", Integer.toString(port));
switch (template.getType()) { switch (template.getType()) {
case SPONGE: case SPONGE:
@ -354,22 +371,51 @@ public class SubCreatorImpl {
return server; return server;
} }
@SuppressWarnings("unchecked")
public void run() { public void run() {
Runnable declaration = () -> {
replacements.put("player", (player == null)?"":player.toString());
replacements.put("name", name);
replacements.put("host", SubAPI.getInstance().getName());
replacements.put("template", template.getName());
replacements.put("type", template.getType().toString());
replacements.put("version", (version != null)?version.toString():"");
replacements.put("address", getAddress());
replacements.put("port", Integer.toString(port));
};
declaration.run();
File dir = (update != null)?new File(update.getFullPath()):new File(host.host.getRawString("Directory"),
(template.getConfigOptions().contains("Directory"))?new ReplacementScanner(replacements).replace(template.getConfigOptions().getRawString("Directory")).toString():name);
dir.mkdirs(); dir.mkdirs();
ObjectMap<String> server;
ObjectMap<String> config;
try { try {
server = build(dir, template, new LinkedList<>()); config = build(dir, template, new LinkedList<>());
generateProperties(dir, port);
generateClient(dir, template.getType(), name);
} catch (SubCreatorException e) { } catch (SubCreatorException e) {
server = null; config = null;
} catch (Exception e) { } catch (Exception e) {
server = null; config = null;
log.logger.error.println(e); log.logger.error.println(e);
} }
ObjectMap<String> config = template.getConfigOptions().clone();
if (server != null) { declaration.run();
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketExCreateServer(0, null, config, host.config.get().getMap("Settings").getRawString("Server-Bind"), tracker)); ReplacementScanner replacements = new ReplacementScanner(this.replacements);
if (config != null) {
try {
if (template.getBuildOptions().getBoolean("Install-Client", true)) generateClient(dir, template.getType(), name);
LinkedList<String> masks = new LinkedList<>();
masks.add("/server.properties");
masks.addAll(template.getBuildOptions().getRawStringList("Replace", Collections.emptyList()));
replacements.replace(dir, masks.toArray(new String[0]));
} catch (Exception e) {
config = null;
e.printStackTrace();
}
}
if (config != null) {
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketExCreateServer(0, null, (Map<String, ?>) replacements.replace(config.get()), tracker));
} else { } else {
log.logger.info.println("Couldn't build the server jar. Check the SubCreator logs for more detail."); log.logger.info.println("Couldn't build the server jar. Check the SubCreator logs for more detail.");
((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketExCreateServer(-1, "Couldn't build the server jar. Check the SubCreator logs for more detail.", tracker)); ((SubDataClient) SubAPI.getInstance().getSubDataNetwork()[0]).sendPacket(new PacketExCreateServer(-1, "Couldn't build the server jar. Check the SubCreator logs for more detail.", tracker));
@ -389,9 +435,9 @@ public class SubCreatorImpl {
this.thread = new TreeMap<>(); this.thread = new TreeMap<>();
} }
public boolean create(String name, ServerTemplate template, Version version, int port, String dir, UUID address, UUID tracker) { public boolean create(UUID player, String name, ServerTemplate template, Version version, int port, UUID address, UUID tracker) {
if (Util.isNull(name, template, port, dir, address)) throw new NullPointerException(); if (Util.isNull(name, template, port, address)) throw new NullPointerException();
CreatorTask task = new CreatorTask(name, template, version, port, dir, address, tracker); CreatorTask task = new CreatorTask(player, name, template, version, port, address, tracker);
this.thread.put(name.toLowerCase(), task); this.thread.put(name.toLowerCase(), task);
task.start(); task.start();
return true; return true;
@ -444,8 +490,16 @@ public class SubCreatorImpl {
return this.thread.get(name).log; return this.thread.get(name).log;
} }
private static NamedContainer<YAMLSection, String> address = null;
private String getAddress() {
if (address == null || host.config.get() != address.name()) {
address = new NamedContainer<>(host.config.get(), host.config.get().getMap("Settings").getRawString("Server-Bind"));
}
return address.get();
}
private static NamedContainer<YAMLSection, Map<String, Object>> subdata = null; private static NamedContainer<YAMLSection, Map<String, Object>> subdata = null;
private Map<String, Object> getSubDataConfig() { private Map<String, Object> getSubData() {
if (subdata == null || host.config.get() != subdata.name()) { if (subdata == null || host.config.get() != subdata.name()) {
Map<String, Object> map = new HashMap<String, Object>(); Map<String, Object> map = new HashMap<String, Object>();
map.put("Address", host.config.get().getMap("Settings").getMap("SubData").getRawString("Address")); map.put("Address", host.config.get().getMap("Settings").getMap("SubData").getRawString("Address"));
@ -456,21 +510,24 @@ public class SubCreatorImpl {
} }
private void generateClient(File dir, ServerType type, String name) throws IOException { private void generateClient(File dir, ServerType type, String name) throws IOException {
if (new UniversalFile(dir, "subservers.client").exists()) { boolean installed = false;
Files.delete(new UniversalFile(dir, "subservers.client").toPath()); if (type == ServerType.SPIGOT) {
if (type == ServerType.SPIGOT) { installed = true;
if (!new UniversalFile(dir, "plugins").exists()) new UniversalFile(dir, "plugins").mkdirs(); if (!new UniversalFile(dir, "plugins").exists()) new UniversalFile(dir, "plugins").mkdirs();
if (!new UniversalFile(dir, "plugins:SubServers.Client.jar").exists()) if (!new UniversalFile(dir, "plugins:SubServers.Client.jar").exists())
Util.copyFromJar(ExHost.class.getClassLoader(), "net/ME1312/SubServers/Host/Library/Files/client.jar", new UniversalFile(dir, "plugins:SubServers.Client.jar").getPath()); Util.copyFromJar(ExHost.class.getClassLoader(), "net/ME1312/SubServers/Host/Library/Files/client.jar", new UniversalFile(dir, "plugins:SubServers.Client.jar").getPath());
} else if (type == ServerType.FORGE || type == ServerType.SPONGE) { } else if (type == ServerType.FORGE || type == ServerType.SPONGE) {
if (!new UniversalFile(dir, "mods").exists()) new UniversalFile(dir, "mods").mkdirs(); installed = true;
if (!new UniversalFile(dir, "mods:SubServers.Client.jar").exists()) if (!new UniversalFile(dir, "mods").exists()) new UniversalFile(dir, "mods").mkdirs();
Util.copyFromJar(ExHost.class.getClassLoader(), "net/ME1312/SubServers/Host/Library/Files/client.jar", new UniversalFile(dir, "mods:SubServers.Client.jar").getPath()); if (!new UniversalFile(dir, "mods:SubServers.Client.jar").exists())
} Util.copyFromJar(ExHost.class.getClassLoader(), "net/ME1312/SubServers/Host/Library/Files/client.jar", new UniversalFile(dir, "mods:SubServers.Client.jar").getPath());
}
if (installed) {
YAMLSection config = new YAMLSection(); YAMLSection config = new YAMLSection();
FileWriter writer = new FileWriter(new UniversalFile(dir, "subdata.json"), false); FileWriter writer = new FileWriter(new UniversalFile(dir, "subdata.json"), false);
config.set("Name", name); config.set("Name", name);
config.setAll(getSubDataConfig()); config.setAll(getSubData());
writer.write(config.toJSON().toString()); writer.write(config.toJSON().toString());
writer.close(); writer.close();
@ -479,15 +536,46 @@ public class SubCreatorImpl {
} }
} }
} }
private void generateProperties(File dir, int port) throws IOException {
File file = new File(dir, "server.properties"); private void updateDirectory(File from, File to) {
if (!file.exists()) file.createNewFile(); if (from.isDirectory() && !Files.isSymbolicLink(from.toPath())) {
FileInputStream is = new FileInputStream(file); if (!to.exists()) {
String content = Util.readAll(new BufferedReader(new InputStreamReader(is))).replaceAll("server-port=.*(\r?\n)", "server-port=" + port + "$1").replaceAll("server-ip=.*(\r?\n)", "server-ip=" + host.config.get().getMap("Settings").getRawString("Server-Bind") + "$1"); to.mkdirs();
is.close(); }
file.delete();
PrintWriter writer = new PrintWriter(file, "UTF-8"); String files[] = from.list();
writer.write(content);
writer.close(); for (String file : files) {
File srcFile = new File(from, file);
File destFile = new File(to, file);
updateDirectory(srcFile, destFile);
}
} else {
try {
if (!to.exists() || from.length() != to.length() || !Arrays.equals(generateSHA256(to), generateSHA256(from))) {
if (to.exists()) {
if (to.isDirectory()) Util.deleteDirectory(to);
else to.delete();
}
Files.copy(from.toPath(), to.toPath(), LinkOption.NOFOLLOW_LINKS, StandardCopyOption.REPLACE_EXISTING);
}
} catch (Exception e) {
e.printStackTrace();
}
}
} private byte[] generateSHA256(File file) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
FileInputStream fis = new FileInputStream(file);
byte[] dataBytes = new byte[1024];
int nread;
while ((nread = fis.read(dataBytes)) != -1) {
md.update(dataBytes, 0, nread);
}
fis.close();
return md.digest();
} }
} }

View File

@ -283,14 +283,23 @@ public class SubServerImpl {
} }
/** /**
* Get the Server Directory * Get the Server Directory Path
* *
* @return Server Directory * @return Server Directory Path
*/ */
public String getDirectory() { public String getPath() {
return dir; return dir;
} }
/**
* Get the Full Server Directory Path
*
* @return Full Server Directory Path
*/
public String getFullPath() {
return directory.getPath();
}
/** /**
* Get the Server's Executable String * Get the Server's Executable String
* *

View File

@ -0,0 +1,169 @@
package net.ME1312.SubServers.Host.Library;
import net.ME1312.Galaxi.Library.Util;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.regex.Pattern;
/**
* File Replacement Scanner
*/
public class ReplacementScanner {
private final Map<String, String> replacements = new LinkedHashMap<>();
public ReplacementScanner(Map<String, String> replacements) {
TreeMap<Integer, LinkedList<String>> order = new TreeMap<Integer, LinkedList<String>>(Comparator.reverseOrder());
for (String key : replacements.keySet()) {
int length = key.length();
if (!order.keySet().contains(length)) order.put(length, new LinkedList<>());
order.get(length).add(key);
}
for (Integer length : order.keySet()) {
for (String key : order.get(length)) {
this.replacements.put(key, replacements.get(key));
}
}
}
/**
* Get the replacements
*
* @return Replacement Map
*/
public Map<String, String> getReplacements() {
return new HashMap<>(replacements);
}
/**
* Make replacements in a File or Directory
*
* @param dir File or Directory
* @param whitelist File Whitelist
*/
public void replace(File dir, String... whitelist) throws IOException {
List<String> files;
try {
files = Util.reflect(Util.class.getDeclaredMethod("zipsearch", File.class, File.class), null, dir, dir);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new IllegalStateException("Cannot access zipsearch()", e);
}
LinkedHashMap<Pattern, Boolean> rules = new LinkedHashMap<Pattern, Boolean>();
for (String entry : whitelist) {
boolean mode = !entry.startsWith("!");
if (!mode) entry = entry.substring(1);
if (entry.startsWith(".")) entry = entry.substring(1);
StringBuilder rule = new StringBuilder();
if (entry.startsWith("**")) {
entry = entry.substring(2);
rule.append("^.*");
} else if (entry.startsWith("/")) {
rule.append("^");
}
boolean greedyEnding = false;
if (entry.endsWith("**")) {
entry = entry.substring(0, entry.length() - 2);
greedyEnding = true;
} else if (entry.endsWith("/")) {
greedyEnding = true;
}
StringBuilder literal = new StringBuilder();
for (PrimitiveIterator.OfInt i = entry.codePoints().iterator(); i.hasNext(); ) {
int c = i.next();
if ((c == '*' || c == '?' || c == '[') && literal.length() > 0) {
rule.append(Pattern.quote(literal.toString()));
literal = new StringBuilder();
}
switch (c) {
case '\\':
if (i.hasNext()) c = i.next();
literal.appendCodePoint(c);
case '[':
for (boolean escaped = false; i.hasNext() && (c != ']' || escaped); c = i.next()) {
if (c == '\\') escaped = !escaped;
else escaped = false;
literal.appendCodePoint(c);
}
if (c == ']' && literal.length() > 1) {
literal.appendCodePoint(c);
rule.append(literal.toString());
}
literal = new StringBuilder();
break;
case '*':
rule.append("[^/]+");
break;
case '?':
rule.append("[^/]");
break;
default:
literal.appendCodePoint(c);
break;
}
}
if (literal.length() > 0)
rule.append(Pattern.quote(literal.toString()));
if (greedyEnding)
rule.append(".*");
rule.append("$");
rules.put(Pattern.compile(rule.toString()), mode);
}
for (String file : files) {
boolean act = false;
for (Map.Entry<Pattern, Boolean> rule : rules.entrySet()) {
if (rule.getKey().matcher('/' + file.replace(File.separatorChar, '/')).find()) act = rule.getValue();
}
if (act) replaceFile(new File(dir, file));
}
} private void replaceFile(File file) throws IOException {
FileInputStream stream = new FileInputStream(file);
String string = Util.readAll(new InputStreamReader(stream));
stream.close();
for (Map.Entry<String, String> replacement : replacements.entrySet()) string = string.replace("SubServers::" + replacement.getKey(), replacement.getValue());
FileWriter writer = new FileWriter(file, false);
writer.write(string);
writer.close();
}
/**
* Make replacements in an Object
*
* @param value Map, Collection, Array, or String
* @return Object with replaced variables
*/
public Object replace(Object value) {
if (value instanceof Map) {
List<String> list = new ArrayList<String>();
list.addAll(((Map<String, Object>) value).keySet());
for (String key : list) ((Map<String, Object>) value).put(key, replace(((Map<String, Object>) value).get(key)));
return value;
} else if (value instanceof Collection) {
List<Object> list = new ArrayList<Object>();
for (Object val : (Collection<Object>) value) list.add(replace(val));
return list;
} else if (value.getClass().isArray()) {
List<Object> list = new ArrayList<Object>();
for (int i = 0; i < ((Object[]) value).length; i++) list.add(replace(((Object[]) value)[i]));
return list;
} else if (value instanceof String) {
return replaceObj((String) value);
} else {
return value;
}
} private String replaceObj(String string) {
for (Map.Entry<String, String> replacement : replacements.entrySet()) string = string.replace('$' + replacement.getKey() + '$', replacement.getValue());
return string;
}
}

View File

@ -49,7 +49,7 @@ public class RemotePlayer {
} }
/** /**
* Get this connection's UUID, if set. * Get the UUID of this player.
* *
* @return the UUID * @return the UUID
*/ */

View File

@ -80,7 +80,7 @@ public class PacketExAddServer implements PacketObjectIn<Integer>, PacketObjectO
if (host.servers.keySet().contains(name.toLowerCase())) { if (host.servers.keySet().contains(name.toLowerCase())) {
SubServerImpl server = host.servers.get(name.toLowerCase()); SubServerImpl server = host.servers.get(name.toLowerCase());
if (server.getPort() == port && server.getExecutable().equals(exec) && server.getDirectory().equals(dir)) { if (server.getPort() == port && server.getExecutable().equals(exec) && server.getPath().equals(dir)) {
if (server.isEnabled() != enabled || server.getLogger().isLogging() != log || !server.getStopCommand().equals(stopcmd)) { if (server.isEnabled() != enabled || server.getLogger().isLogging() != log || !server.getStopCommand().equals(stopcmd)) {
server.setEnabled(enabled); server.setEnabled(enabled);
server.setLogging(log); server.setLogging(log);

View File

@ -8,6 +8,7 @@ import net.ME1312.SubData.Client.Protocol.PacketObjectOut;
import net.ME1312.SubData.Client.SubDataSender; import net.ME1312.SubData.Client.SubDataSender;
import net.ME1312.SubServers.Host.ExHost; import net.ME1312.SubServers.Host.ExHost;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
/** /**
@ -17,8 +18,7 @@ public class PacketExCreateServer implements PacketObjectIn<Integer>, PacketObje
private ExHost host; private ExHost host;
private int response; private int response;
private String message; private String message;
private ObjectMap<String> info; private Map<String, ?> info;
private String address;
private UUID tracker; private UUID tracker;
/** /**
@ -51,15 +51,13 @@ public class PacketExCreateServer implements PacketObjectIn<Integer>, PacketObje
* @param response Response ID * @param response Response ID
* @param message Message * @param message Message
* @param info Creator Info * @param info Creator Info
* @param address Internal Server Address
* @param tracker Receiver ID * @param tracker Receiver ID
*/ */
public PacketExCreateServer(int response, String message, ObjectMap<String> info, String address, UUID tracker) { public PacketExCreateServer(int response, String message, Map<String, ?> info, UUID tracker) {
if (Util.isNull(response)) throw new NullPointerException(); if (Util.isNull(response)) throw new NullPointerException();
this.response = response; this.response = response;
this.message = message; this.message = message;
this.info = info; this.info = info;
this.address = address;
this.tracker = tracker; this.tracker = tracker;
} }
@ -69,8 +67,7 @@ public class PacketExCreateServer implements PacketObjectIn<Integer>, PacketObje
if (tracker != null) data.set(0x0000, tracker); if (tracker != null) data.set(0x0000, tracker);
data.set(0x0001, response); data.set(0x0001, response);
if (info != null) data.set(0x0002, info); if (info != null) data.set(0x0002, info);
if (address != null) data.set(0x0003, address); if (message != null) data.set(0x0003, message);
if (message != null) data.set(0x0004, message);
return data; return data;
} }
@ -90,11 +87,10 @@ public class PacketExCreateServer implements PacketObjectIn<Integer>, PacketObje
String template = data.getRawString(0x0003); String template = data.getRawString(0x0003);
Version version = (data.contains(0x0004)?data.getVersion(0x0004):null); Version version = (data.contains(0x0004)?data.getVersion(0x0004):null);
Integer port = data.getInt(0x0005); Integer port = data.getInt(0x0005);
String dir = data.getRawString(0x0006).replace("$address$", host.config.get().getMap("Settings").getRawString("Server-Bind")); UUID log = data.getUUID(0x0006);
UUID log = data.getUUID(0x0007); UUID player = (data.contains(0x0007)?data.getUUID(0x0007):null);
host.creator.create(name, host.templates.get(template.toLowerCase()), version, host.creator.create(player, name, host.templates.get(template.toLowerCase()), version, port, log, tracker);
port, dir, log, tracker);
} }
} catch (Throwable e) { } catch (Throwable e) {
host.log.error.println(e); host.log.error.println(e);

View File

@ -78,7 +78,7 @@ public class PacketExDeleteServer implements PacketObjectIn<Integer>, PacketObje
new Thread(() -> { new Thread(() -> {
UniversalFile to = new UniversalFile(GalaxiEngine.getInstance().getRuntimeDirectory(), "Recently Deleted:" + server.getName().toLowerCase()); UniversalFile to = new UniversalFile(GalaxiEngine.getInstance().getRuntimeDirectory(), "Recently Deleted:" + server.getName().toLowerCase());
try { try {
File from = new File(host.host.getRawString("Directory"), server.getDirectory()); File from = new File(host.host.getRawString("Directory"), server.getPath());
if (from.exists()) { if (from.exists()) {
log.info("Removing Files..."); log.info("Removing Files...");
if (recycle) { if (recycle) {

View File

@ -49,7 +49,7 @@ public class RemotePlayer {
} }
/** /**
* Get this connection's UUID, if set. * Get the UUID of this player.
* *
* @return the UUID * @return the UUID
*/ */