Skip to content

Commit

Permalink
Move to new API + update to latest zig
Browse files Browse the repository at this point in the history
  • Loading branch information
Beyley committed Nov 6, 2023
1 parent af582b0 commit 5138649
Show file tree
Hide file tree
Showing 4 changed files with 280 additions and 482 deletions.
5 changes: 4 additions & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@ pub fn build(b: *std.Build) !void {
});
const zboxer_lib = zboxer.artifact("boxer");

const refresh_api_zig = b.dependency("refresh_api", .{});

const exe = b.addExecutable(.{
.name = "FreshPresence",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
exe.addModule("api", refresh_api_zig.module("refresh-api-zig"));
//If we are on MacOS, we need to import the xcode frameworks
if (target.getOsTag() == .macos) {
@import("xcode_frameworks").addPaths(b, exe);
@import("xcode_frameworks").addPaths(exe);
}
if (optimize == .ReleaseSmall) {
exe.strip = true;
Expand Down
16 changes: 10 additions & 6 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
.version = "0.0.0",
.dependencies = .{
.@"zig-discord" = .{
.url = "https://github.com/Beyley/zig-discord/archive/8cb14f10a68889da2c5e452731da286cb927c47d.tar.gz",
.hash = "122064b18beed5aac15b259c20f188401db5b2eebcae9ae99680f09e78d2e5cee928",
.url = "https://github.com/Beyley/zig-discord/archive/fdd066607b51273cdaf49eb2f21ea8957f602c07.tar.gz",
.hash = "1220f3dbc1ca2363df655adebfae12d03c2b6e9b02a0959cdc8d187a9447608f9970",
},
.zBoxer = .{
.url = "https://github.com/Beyley/zBoxer/archive/5b559cff447c654f9fe57c7b3c0ba9cfb655ef4b.tar.gz",
.hash = "12201edf78b182f8b1e4b0909d415ebbc7c648f957a7b27707746aec9f0d73b9adb4",
.url = "https://github.com/Beyley/zBoxer/archive/9801620f2763cc5f4d2f9eeaaafbb347d2b6f05f.tar.gz",
.hash = "1220e98a7d3873585aa43a07ba4a009cc48c348f6840eacdb0b71cca0275a9854f79",
},
.zini = .{
.url = "https://github.com/Beyley/zini/archive/48af291bf585a71960e8fc4dcbaf42e92a79d5df.tar.gz",
Expand All @@ -19,8 +19,12 @@
.hash = "122048992ca58a78318b6eba4f65c692564be5af3b30fbef50cd4abeda981b2e7fa5",
},
.xcode_frameworks = .{
.url = "https://github.com/der-teufel-programming/xcode-frameworks-pkg/archive/8e01bf7edf3d0295a6ec6f12c374f430506a12f9.tar.gz",
.hash = "1220f1d9bded5649fcd8892128d162fe4cf31ea70f2fa67a956cb9ccbd19fe64067c",
.url = "https://github.com/hexops/xcode-frameworks/archive/8a920385383cc4c0a2a4f55b084d402a9400a5a8.tar.gz",
.hash = "122051b3c616c62d55a82207c1cb76e2264b26e8378f56b1e5376d7684bd13616589",
},
.refresh_api = .{
.url = "https://github.com/LittleBigRefresh/refresh-api-zig/archive/4a4aa2b9e5b7fdb77827c51b1999d99bb7d6614b.tar.gz",
.hash = "122041fed4926eeeaa38b75ef8fe1026f4f1c16cc261e333ae5fb5ca3f34d152cb61",
},
},
.paths = .{
Expand Down
259 changes: 1 addition & 258 deletions src/lbp.zig
Original file line number Diff line number Diff line change
@@ -1,269 +1,12 @@
const std = @import("std");

pub fn instanceInfo(allocator: std.mem.Allocator, uri: std.Uri) !std.json.Parsed(InstanceInfo) {
return try makeRequestAndParse(allocator, InstanceInfo, uri, "/api/v3/instance");
}

pub const RequestError = error{
ErrorCode404,
UnknownHttpErrorCode,
};

fn makeRequestAndParse(allocator: std.mem.Allocator, comptime T: type, uri: std.Uri, path: []const u8) !std.json.Parsed(T) {
var client = std.http.Client{ .allocator = allocator };
defer client.deinit();

var new_url = uri;
new_url.path = path;

//Create a request to the Instance v3 API to get server info
var request = try client.request(.GET, new_url, .{ .allocator = allocator }, .{});
defer request.deinit();
try request.start(.{});

//Wait for the response
try request.wait();

if (request.response.status == .not_found) {
return RequestError.ErrorCode404;
} else if (request.response.status != .ok) {
std.log.err("got unknown response code {s}", .{@tagName(request.response.status)});
return RequestError.UnknownHttpErrorCode;
}

var reader = request.reader();

var json_reader = std.json.reader(allocator, reader);
defer json_reader.deinit();
return try std.json.parseFromTokenSource(T, allocator, &json_reader, .{
//If we have no runtime safety, ignore unknown fields
.ignore_unknown_fields = !std.debug.runtime_safety,
});
}

pub fn ApiResponse(comptime T: type) type {
return struct {
success: bool,
data: T,
};
}

pub const InstanceInfo = ApiResponse(struct {
instanceName: []const u8,
instanceDescription: []const u8,
softwareName: []const u8,
softwareVersion: []const u8,
softwareType: []const u8,
registrationEnabled: bool,
maximumAssetSafetyLevel: i32,
announcements: []const struct {
announcementId: []const u8,
title: []const u8,
text: []const u8,
createdAt: []const u8,
},
richPresenceConfiguration: struct {
applicationId: []const u8,
partyIdPrefix: []const u8,
assetConfiguration: struct {
useApplicationAssets: bool,
podAsset: ?[]const u8,
moonAsset: ?[]const u8,
remoteMoonAsset: ?[]const u8,
developerAsset: ?[]const u8,
developerAdventureAsset: ?[]const u8,
dlcAsset: ?[]const u8,
fallbackAsset: ?[]const u8,
},
},
maintenanceModeEnabled: bool,
grafanaDashboardUrl: []const u8,
});

pub fn getLevel(allocator: std.mem.Allocator, uri: std.Uri, id: i32) !?std.json.Parsed(ApiGameLevel) {
var url = std.ArrayList(u8).init(allocator);
defer url.deinit();
try std.fmt.format(url.writer(), "/api/v3/levels/id/{d}", .{id});

var parsed = makeRequestAndParse(allocator, ApiGameLevel, uri, url.items) catch |err| {
if (err == RequestError.ErrorCode404) {
return null;
} else {
return err;
}
};

return parsed;
}

pub const ApiGameLevel = ApiResponse(struct {
levelId: i32,
publisher: ApiGameUser,
title: []const u8,
iconHash: []const u8,
description: []const u8,
location: ApiGameLocation,
rootLevelHash: []const u8,
gameVersion: u32,
publishDate: []const u8,
updateDate: []const u8,
minPlayers: u3,
maxPlayers: u3,
enforceMinMaxPlayers: bool,
sameScreenGame: bool,
skillRewards: []const ApiGameSkillReward,
yayRatings: i32,
booRatings: i32,
hearts: i32,
uniquePlays: i32,
teamPicked: bool,
levelType: enum(u8) {
normal = 0,
versus = 1,
cutscene = 2,
},
isLocked: bool,
isSubLevel: bool,
isCopyable: bool,
});

pub const ApiGameSkillReward = struct {
id: i32,
enabled: bool,
title: ?[]const u8,
requiredAmount: f32,
conditionType: enum(i32) {
score = 0,
time = 1,
lives = 2,
},
};

pub const ApiGameUser = struct {
userId: []const u8,
username: []const u8,
iconHash: []const u8,
description: []const u8,
location: ApiGameLocation,
joinDate: []const u8,
};

pub const ApiGameLocation = struct {
x: i32,
y: i32,
};

pub fn getUserRoom(allocator: std.mem.Allocator, uri: std.Uri, username: []const u8) !?std.json.Parsed(ApiRoom) {
var url = std.ArrayList(u8).init(allocator);
defer url.deinit();
try std.fmt.format(url.writer(), "/api/v3/rooms/username/{s}", .{username});

var parsed = makeRequestAndParse(allocator, ApiRoom, uri, url.items) catch |err| {
if (err == RequestError.ErrorCode404) {
return null;
} else {
return err;
}
};

return parsed;
}

pub fn getUser(allocator: std.mem.Allocator, uri: std.Uri, username: []const u8) !?std.json.Parsed(ApiResponse(ApiGameUser)) {
var url = std.ArrayList(u8).init(allocator);
defer url.deinit();
try std.fmt.format(url.writer(), "/api/v3/users/name/{s}", .{username});

var parsed = makeRequestAndParse(allocator, ApiResponse(ApiGameUser), uri, url.items) catch |err| {
if (err == RequestError.ErrorCode404) {
return null;
} else {
return err;
}
};

return parsed;
}

pub const ApiRoom = ApiResponse(struct {
roomId: []const u8,
playerIds: []const ApiRoomPlayer,
roomState: ApiRoomState,
roomMood: ApiRoomMood,
levelType: ApiRoomSlotType,
levelId: i32,
platform: ApiPlatform,
game: ApiGame,
});

pub const ApiPlatform = enum(i32) {
ps3 = 0,
rpcs3 = 1,
vita = 2,
website = 3,
_,
};

pub const ApiGame = enum(i32) {
lbp1,
lbp2,
lbp3,
lbpvita,
lbppsp,
website,
_,
};

pub const ApiRoomSlotType = enum(i32) {
story = 0,
online = 1,
moon = 2,
moon_group = 3,
story_group = 4,
pod = 5,
fake = 6,
remote_moon = 7,
dlc_level = 8,
dlc_pack = 9,
playlist = 10,
story_adventure = 11,
story_adventure_planet = 12,
story_aventure_area = 13,
adventure_planet_published = 14,
adventure_planet_local = 15,
adventure_level_local = 16,
adventure_area_level = 17,
_,
};

pub const ApiRoomState = enum(i32) {
idle = 0,
loading = 1,
diving_in = 3,
waiting_for_players = 4,
_,
};

pub const ApiRoomMood = enum(i32) {
rejecting_all = 0,
rejecting_all_but_friends = 1,
rejecting_only_friends = 2,
allowing_all = 3,
_,
};

pub const ApiRoomPlayer = struct {
username: []const u8,
userId: ?[]const u8,
};

pub fn qualifyAsset(allocator: std.mem.Allocator, uri: std.Uri, asset: []const u8, use_application_asset: bool) ![]const u8 {
var qualified_asset = std.ArrayList(u8).init(allocator);

//If the asset length matches a SHA1 hex string,
if (!use_application_asset) {
//Assume it is a server asset
try uri.format("+", .{}, qualified_asset.writer());
try uri.format(":+", .{}, qualified_asset.writer());
try std.fmt.format(qualified_asset.writer(), "/api/v3/assets/{s}/image", .{asset});
} else {
//Assume it is a discord asset
Expand Down
Loading

0 comments on commit 5138649

Please sign in to comment.