From 152b5eb76d40a501ae58a63cd0daf5237580a3b9 Mon Sep 17 00:00:00 2001 From: Martin Ashby Date: Sun, 10 Sep 2023 20:01:55 +0100 Subject: finish parsing client.json --- src/main.zig | 137 ++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 97 insertions(+), 40 deletions(-) diff --git a/src/main.zig b/src/main.zig index 8ca780b..4b6fdd5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,46 @@ const std = @import("std"); +/// Minecraft launcher! +pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{ .safety = false }){}; // TODO turn safety back on + defer _ = gpa.deinit(); + const allocator = gpa.allocator(); + var client = std.http.Client{ .allocator = allocator }; + defer client.deinit(); + + const manifest_wrap = try download_json(&client, Manifest, Manifest.uri); + defer manifest_wrap.deinit(); + const manifest = manifest_wrap.value; + std.log.info("release: {s} snapshot: {s}", .{ manifest.latest.release, manifest.latest.snapshot }); + + // Find the release version + const release_version_url = for (manifest.versions) |v| { + if (std.mem.eql(u8, v.id, manifest.latest.release)) { + break v.url; + } + } else { + return error.NoReleaseVersionFound; + }; + + var release_version_wrap = try download_json(&client, Version, release_version_url); + defer release_version_wrap.deinit(); + const release_version = release_version_wrap.value; + _ = release_version; + + // Download all the bits + + // 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 + // +} + +/// https://minecraft.fandom.com/wiki/Version_manifest.json const Manifest = struct { const uri = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"; @@ -17,6 +58,7 @@ const Manifest = struct { }, }; +/// https://minecraft.fandom.com/wiki/Client.json const Version = struct { const Rule = struct { const Feature = struct { @@ -75,53 +117,68 @@ const Version = struct { } } }; + const Download = struct { + sha1: []const u8, + size: u64, + url: []const u8, + }; + const Library = struct { + downloads: struct { + artifact: struct { + path: []const u8, + sha1: []const u8, + size: u64, + url: []const u8, + }, + }, + name: []const u8, + rules: ?[]Rule = null, + }; arguments: struct { game: []Arg, jvm: []Arg, }, + assetIndex: struct { + id:[]const u8, + sha1: []const u8, + size: u64, + totalSize: u64, + url: []const u8, + }, + assets: []const u8, + complianceLevel: u8, + downloads: struct { + client: Download, + client_mappings: Download, + server: Download, + server_mappings: Download, + }, + id: []const u8, + javaVersion: struct { + component: []const u8, + majorVersion: u8, + }, + libraries: []Library, + logging: struct { + client: struct { + argument: []const u8, + file: struct { + id: []const u8, + sha1: []const u8, + size: u64, + url: []const u8, + }, + type: []const u8, + }, + }, + mainClass: []const u8, + minimumLauncherVersion: u8, + releaseTime: []const u8, + time: []const u8, + type: []const u8, }; -/// Minecraft launcher! -pub fn main() !void { - var gpa = std.heap.GeneralPurposeAllocator(.{ .safety = false }){}; // TODO turn safety back on - defer _ = gpa.deinit(); - const a = gpa.allocator(); - var client = std.http.Client{ .allocator = a }; - defer client.deinit(); - - const m_wrap = try download_json(&client, Manifest, Manifest.uri); - defer m_wrap.deinit(); - const m = m_wrap.value; - std.log.info("release: {s} snapshot: {s}", .{ m.latest.release, m.latest.snapshot }); - - // Find the release version - const rvu = for (m.versions) |v| { - if (std.mem.eql(u8, v.id, m.latest.release)) { - break v.url; - } - } else { - return error.NoReleaseVersionFound; - }; - std.log.info("found release version url {s}", .{rvu}); - var rv_wrap = try download_json(&client, Version, rvu); - defer rv_wrap.deinit(); - const rv = rv_wrap.value; - for (rv.arguments.game) |ga| { - std.log.info("game arg: {}", .{ga}); - } - // Download the manifest for that - - // 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 - // -} /// Caller is responsible for calling deinit on the resulting Parsed struct. fn download_json(client: *std.http.Client, comptime T: type, url_maybe_https: []const u8) !std.json.Parsed(T) { -- cgit v1.2.3-ZIG