diff options
-rw-r--r-- | src/main.zig | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/src/main.zig b/src/main.zig index 773dad8..fd2aa5c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -114,33 +114,56 @@ pub fn main() !void { // Download all the required files - var root_dir = try get_minecraft_root_dir(allocator); - defer root_dir.close(); - try download_version(allocator, &client, &root_dir, release_version); - // std.mem.replace(comptime T: type, input: []const T, needle: []const T, replacement: []const T, output: []T) - - // check the latest.release - // find that in the versions[] by key id - // get the download URL for that https://piston-meta.mojang.com/v1/packages/1f376e6cb981265af345076889f9ef325bb6b9e8/1.20.1.json - - // get arguments.game and arguments.jvm ready to supply ... - // probably just use the system java version for now - // + var root_dir_path = try get_minecraft_root_dir(allocator); + defer allocator.free(root_dir_path); + // try download_version(allocator, &client, root_dir_path, release_version); + try play_version(allocator, root_dir_path, release_version); } -fn download_version(allocator: std.mem.Allocator, client: *HttpClient, root_dir: *const std.fs.Dir, version: Version) !void { - const dir_path = try std.fs.path.join(allocator, &[_][]const u8{"versions", version.id}); +fn play_version(allocator: std.mem.Allocator, root_dir_path: []const u8, version: Version) !void { + // version dir + const dir_path = try version.dir_path(allocator, root_dir_path); defer allocator.free(dir_path); + var dir = try std.fs.openDirAbsolute(dir_path, .{}); + defer dir.close(); + var cmd_buf = std.ArrayList([]const u8).init(allocator); + try cmd_buf.append("java"); + try cmd_buf.append("-cp"); + try cmd_buf.append("*"); + // try cmd_buf.append(version.mainClass); + try cmd_buf.append("net.minecraft.client.main.Main"); + try cmd_buf.append("-accessToken=foo"); + try cmd_buf.append("-version=1.20.1"); + const cmd = try cmd_buf.toOwnedSlice(); + defer allocator.free(cmd); + const cmd_log = try std.mem.join(allocator, " ", cmd); + defer allocator.free(cmd_log); + log.info("running minecraft cmd [{s}] in cwd {s}", .{cmd_log, dir_path}); + var proc = std.ChildProcess.init(cmd, allocator); + proc.stdin_behavior = .Ignore; + proc.cwd = dir_path; + proc.cwd_dir = null; + proc.env_map = null; + proc.expand_arg0 = .no_expand; + _ = try proc.spawnAndWait(); +} + +fn download_version(allocator: std.mem.Allocator, client: *HttpClient, root_dir_path: []const u8, version: Version) !void { + const dir_path = try version.dir_path(allocator, root_dir_path); + defer allocator.free(dir_path); + std.fs.makeDirAbsolute(dir_path) catch |e| switch (e) { + error.PathAlreadyExists => {}, // fine, swallow the error + else => return e, + }; log.info("downloading version {s} to {s}", .{version.id, dir_path}); - try root_dir.makePath(dir_path); - const dir = try root_dir.openDir(dir_path, .{}); + const dir = try std.fs.openDirAbsolute(dir_path, .{}); var client_jar = try dir.createFile("client.jar", .{}); defer client_jar.close(); try download_file(client, &client_jar, version.downloads.client.url); var client_map = try dir.createFile("client.map", .{}); defer client_map.close(); - try download_file(client, &client_jar, version.downloads.client_mappings.url); + try download_file(client, &client_map, version.downloads.client_mappings.url); // TODO server // Dependencies... @@ -334,6 +357,11 @@ const Version = struct { releaseTime: []const u8, time: []const u8, type: []const u8, + + /// Caller must free the result + fn dir_path(self: Version, allocator: std.mem.Allocator, root_dir_path: []const u8) ![]const u8 { + return try std.fs.path.join(allocator, &[_][]const u8{root_dir_path, "versions", self.id}); + } }; @@ -360,20 +388,21 @@ fn download_json(client: *HttpClient, comptime T: type, url: []const u8) !std.js return res; } -fn get_minecraft_root_dir(allocator: std.mem.Allocator) !std.fs.Dir { +/// Root of minecraft data directory. +/// Calling ensures the directory exists. +/// Caller owns the result and must free it +fn get_minecraft_root_dir(allocator: std.mem.Allocator) ![]const u8 { const home_dir = std.os.getenv("HOME") orelse { return error.AppDataDirUnavailable; }; const root_dir_path = try std.fs.path.join(allocator, &[_][]const u8{home_dir, ".minecraft"}); - defer allocator.free(root_dir_path); - const root_dir = std.fs.openDirAbsolute(root_dir_path, .{}) catch |e| switch (e) { - error.FileNotFound => blk: { + _ = std.fs.openDirAbsolute(root_dir_path, .{}) catch |e| switch (e) { + error.FileNotFound => { try std.fs.makeDirAbsolute(root_dir_path); - break :blk try std.fs.openDirAbsolute(root_dir_path, .{}); }, else => return e, }; - return root_dir; + return root_dir_path; } test "heterogenous array" { |