问Fabric服务端创建的原理
Fabric-Installer源码地址:https://github.com/FabricMC/fabric-installer
可惜我只学过C++和Python,看不懂
求大佬帮忙看一下代码里是怎么创建的Fabric服务端
Fabric-Installer源码地址:https://github.com/FabricMC/fabric-installer
可惜我只学过C++和Python,看不懂
求大佬帮忙看一下代码里是怎么创建的Fabric服务端
 本帖最后由 PercyDan 于 2021-3-7 11:23 编辑 
https://github.com/FabricMC/fabr ... erverInstaller.java
复制代码
https://github.com/FabricMC/fabr ... erverInstaller.java
 
- public class ServerInstaller {
 
-         private static final String servicesDir = "META-INF/services/";
 
 
-         public static void install(File dir, String loaderVersion, String gameVersion, InstallerProgress progress) throws IOException {
 
-                 progress.updateProgress(new MessageFormat(Utils.BUNDLE.getString("progress.installing.server")).format(new Object[]{String.format("%s(%s)", loaderVersion, gameVersion)}));
 
-                 File libsDir = new File(Utils.findDefaultUserDir(), ".cache" + File.separator + "fabric-installer" + File.separator + "libraries"); // 检查依赖文件夹
 
-                 if (!libsDir.exists()) { //没有则创建
 
-                         if (!libsDir.mkdirs()) {
 
-                                 throw new IOException("Could not create " + libsDir.getAbsolutePath() + "!");
 
-                         }
 
-                 }
 
-                 if(!dir.exists()){
 
-                         if (!dir.mkdirs()) {
 
-                                 throw new IOException("Could not create " + dir.getAbsolutePath() + "!");
 
-                         }
 
-                 }
 
 
-                 progress.updateProgress(Utils.BUNDLE.getString("progress.download.libraries"));
 
 
-                 URL profileUrl = new URL(Reference.getMetaServerEndpoint(String.format("v2/versions/loader/%s/%s/server/json", gameVersion, loaderVersion))); //获取依赖信息
 
-                 Json json = Json.read(Utils.readTextFile(profileUrl));
 
 
-                 List<File> libraryFiles = new ArrayList<>();
 
 
-                 for (Json libraryJson : json.at("libraries").asJsonList()) {
 
-                         Library library = new Library(libraryJson); //遍历并下载依赖
 
 
-                         progress.updateProgress(new MessageFormat(Utils.BUNDLE.getString("progress.download.library.entry")).format(new Object[]{library.name}));
 
-                         File libraryFile = new File(libsDir, library.getFileName());
 
-                         Utils.downloadFile(new URL(library.getURL()), libraryFile.toPath());
 
-                         libraryFiles.add(libraryFile);
 
-                 }
 
 
-                 progress.updateProgress(Utils.BUNDLE.getString("progress.generating.launch.jar"));
 
-                 
 
-                 //创建Jar
 
-                 File launchJar = new File(dir, "fabric-server-launch.jar");
 
-                 String mainClass = json.at("mainClass").asString();
 
-                 makeLaunchJar(launchJar, mainClass, libraryFiles, progress);
 
 
-                 progress.updateProgress(new MessageFormat(Utils.BUNDLE.getString("progress.done.start.server")).format(new Object[]{launchJar.getName()}));
 
-         }
 
 
-         private static void makeLaunchJar(File file, String mainclass, List<File> libraryFiles, InstallerProgress progress) throws IOException {
 
-                 if (file.exists()) {
 
-                         if (!file.delete()) {
 
-                                 throw new IOException("Could not delete file: " + file.getAbsolutePath());
 
-                         }
 
-                 }
 
 
-                 FileOutputStream outputStream = new FileOutputStream(file);
 
-                 ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
 
 
-                 Set<String> addedEntries = new HashSet<>();
 
 
-                 {
 
-                         //写Manifest
 
-                         addedEntries.add("META-INF/MANIFEST.MF");
 
-                         zipOutputStream.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
 
 
-                         Manifest manifest = new Manifest();
 
-                         manifest.getMainAttributes().put(new Attributes.Name("Manifest-Version"), "1.0");
 
-                         manifest.getMainAttributes().put(new Attributes.Name("Main-Class"), "net.fabricmc.loader.launch.server.FabricServerLauncher");
 
-                         manifest.write(zipOutputStream);
 
 
-                         zipOutputStream.closeEntry();
 
 
-                         addedEntries.add("fabric-server-launch.properties");
 
-                         zipOutputStream.putNextEntry(new ZipEntry("fabric-server-launch.properties"));
 
-                         zipOutputStream.write(("launch.mainClass=" + mainclass + "\n").getBytes(StandardCharsets.UTF_8));
 
-                         zipOutputStream.closeEntry();
 
 
-                         Map<String, Set<String>> services = new HashMap<>();
 
-                         byte[] buffer = new byte[32768];
 
-                         
 
-                         //遍历并打包依赖
 
-                         for (File f : libraryFiles) {
 
-                                 progress.updateProgress(new MessageFormat(Utils.BUNDLE.getString("progress.generating.launch.jar.library")).format(new Object[]{f.getName()}));
 
 
-                                 // read service definitions (merging them), copy other files
 
-                                 try (
 
-                                                 FileInputStream is = new FileInputStream(f);
 
-                                                 JarInputStream jis = new JarInputStream(is)
 
-                                 ) {
 
-                                         JarEntry entry;
 
-                                         while ((entry = jis.getNextJarEntry()) != null) {
 
-                                                 if (entry.isDirectory()) continue;
 
 
-                                                 String name = entry.getName();
 
 
-                                                 if (name.startsWith(servicesDir) && name.indexOf('/', servicesDir.length()) < 0) { // service definition file
 
-                                                         parseServiceDefinition(name, jis, services);
 
-                                                 } else if (!addedEntries.add(name)) {
 
-                                                         System.out.printf("duplicate file: %s%n", name);
 
-                                                 } else {
 
-                                                         JarEntry newEntry = new JarEntry(name);
 
-                                                         zipOutputStream.putNextEntry(newEntry);
 
 
-                                                         int r;
 
-                                                         while ((r = jis.read(buffer, 0, buffer.length)) >= 0) {
 
-                                                                 zipOutputStream.write(buffer, 0, r);
 
-                                                         }
 
 
-                                                         zipOutputStream.closeEntry();
 
-                                                 }
 
-                                         }
 
-                                 }
 
-                         }
 
 
-                         // write service definitions
 
-                         for (Map.Entry<String, Set<String>> entry : services.entrySet()) {
 
-                                 JarEntry newEntry = new JarEntry(entry.getKey());
 
-                                 zipOutputStream.putNextEntry(newEntry);
 
 
-                                 writeServiceDefinition(entry.getValue(), zipOutputStream);
 
 
-                                 zipOutputStream.closeEntry();
 
-                         }
 
-                 }
 
 
-                 zipOutputStream.close();
 
-                 outputStream.close();
 
-         }
 
 
-         private static void parseServiceDefinition(String name, InputStream rawIs, Map<String, Set<String>> services) throws IOException {
 
-                 Collection<String> out = null;
 
-                 BufferedReader reader = new BufferedReader(new InputStreamReader(rawIs, StandardCharsets.UTF_8));
 
-                 String line;
 
 
-                 while ((line = reader.readLine()) != null) {
 
-                         int pos = line.indexOf('#');
 
-                         if (pos >= 0) line = line.substring(0, pos);
 
-                         line = line.trim();
 
 
-                         if (!line.isEmpty()) {
 
-                                 if (out == null) out = services.computeIfAbsent(name, ignore -> new LinkedHashSet<>());
 
 
-                                 out.add(line);
 
-                         }
 
-                 }
 
-         }
 
 
-         private static void writeServiceDefinition(Collection<String> defs, OutputStream os) throws IOException {
 
-                 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8));
 
 
-                 for (String def : defs) {
 
-                         writer.write(def);
 
-                         writer.write('\n');
 
-                 }
 
 
-                 writer.flush();
 
-         }
 
- }
如果你只是要安装的话,可以看看这里用命令行的方式来安装
https://fabricmc.net/wiki/install#cli_installation
如果说原理的话,无非就是下载依赖,和打包 jar 而已。
https://fabricmc.net/wiki/install#cli_installation
如果说原理的话,无非就是下载依赖,和打包 jar 而已。