add getting of map

This commit is contained in:
Rokas Puzonas 2024-08-10 00:37:46 +03:00
parent 7ac17313d1
commit 7a1b7971a9
2 changed files with 86 additions and 41 deletions

View File

@ -22,6 +22,8 @@ token: ?[]u8 = null,
item_codes: std.ArrayList([]u8),
// ------------------------- API errors ------------------------
pub const APIError = error {
ServerUnavailable,
RequestFailed,
@ -122,6 +124,8 @@ pub const EquipError = APIError || error {
CharacterInCooldown,
};
// ------------------------- API result structs ------------------------
pub const EquipmentSlot = enum {
weapon,
shield,
@ -624,6 +628,48 @@ pub const EquipResult = struct {
}
};
pub const MapResult = struct {
pub const MapContent = struct {
type: []u8,
code: []u8,
};
name: []u8,
skin: []u8,
x: i64,
y: i64,
content: ?MapContent,
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap, allocator: Allocator) !MapResult {
_ = api;
var content: ?MapContent = null;
if (json_utils.getObject(obj, "content")) |content_obj| {
content = MapContent{
.type = (try json_utils.dupeString(allocator, content_obj, "type")) orelse return error.MissingProperty,
.code = (try json_utils.dupeString(allocator, content_obj, "code")) orelse return error.MissingProperty,
};
}
return MapResult{
.name = (try json_utils.dupeString(allocator, obj, "name")) orelse return error.MissingProperty,
.skin = (try json_utils.dupeString(allocator, obj, "skin")) orelse return error.MissingProperty,
.x = json_utils.getInteger(obj, "x") orelse return error.MissingProperty,
.y = json_utils.getInteger(obj, "y") orelse return error.MissingProperty,
.content = content
};
}
pub fn deinit(self: MapResult, allocator: Allocator) void {
allocator.free(self.name);
allocator.free(self.skin);
if (self.content) |content| {
allocator.free(content.type);
allocator.free(content.code);
}
}
};
pub const ArtifactsFetchResult = struct {
arena: std.heap.ArenaAllocator,
status: std.http.Status,
@ -634,6 +680,8 @@ pub const ArtifactsFetchResult = struct {
}
};
// ------------------------- General API methods ------------------------
pub fn init(allocator: Allocator) !ArtifactsAPI {
const server = try allocator.dupe(u8, "https://api.artifactsmmo.com");
const server_uri = std.Uri.parse(server) catch unreachable;
@ -922,7 +970,6 @@ pub fn getItemCode(self: *const ArtifactsAPI, id: ItemId) ?[]const u8 {
return self.item_codes.items[id];
}
// ------------------------- Endpoints ------------------------
pub fn getServerStatus(self: *ArtifactsAPI) !ServerStatus {
@ -935,7 +982,7 @@ pub fn getServerStatus(self: *ArtifactsAPI) !ServerStatus {
);
}
pub fn getCharacter(self: *ArtifactsAPI, name: []const u8) !?Character {
pub fn getCharacter(self: *ArtifactsAPI, allocator: Allocator, name: []const u8) APIError!?Character {
const path = try std.fmt.allocPrint(self.allocator, "/characters/{s}", .{name});
defer self.allocator.free(path);
@ -943,46 +990,20 @@ pub fn getCharacter(self: *ArtifactsAPI, name: []const u8) !?Character {
APIError,
null,
Character,
Character.parse, .{ self.allocator },
Character.parse, .{ allocator },
.{ .method = .GET, .path = path }
);
}
pub fn listMyCharacters(self: *ArtifactsAPI) !CharacterList {
const path = try std.fmt.allocPrint(self.allocator, "/my/characters", .{});
defer self.allocator.free(path);
const result = try self.fetch(.{ .method = .GET, .path = path });
defer result.deinit();
if (result.status != .ok) {
return APIError.RequestFailed;
}
if (result.body == null) {
return APIError.ParseFailed;
}
const body = json_utils.asArray(result.body.?) orelse return APIError.ParseFailed;
var characters = try std.ArrayList(Character).initCapacity(self.allocator, body.items.len);
errdefer {
for (characters.items) |*char| {
char.deinit();
}
characters.deinit();
}
for (body.items) |character_json| {
const character_obj = json_utils.asObject(character_json) orelse return APIError.ParseFailed;
const char = Character.parse(character_obj, self.allocator, self) catch return APIError.ParseFailed;
characters.appendAssumeCapacity(char);
}
return CharacterList{
.allocator = self.allocator,
.items = characters.items
};
pub fn listMyCharacters(self: *ArtifactsAPI, allocator: Allocator) APIError!std.ArrayList(Character) {
return self.fetchArray(
allocator,
APIError,
null,
Character,
Character.parse, .{ allocator },
.{ .method = .GET, .path = "/my/characters" }
);
}
pub fn actionFight(self: *ArtifactsAPI, name: []const u8) FightError!FightResult {
@ -1187,9 +1208,9 @@ pub fn getBankGold(self: *ArtifactsAPI) APIError!u64 {
return @intCast(quantity);
}
pub fn getBankItems(self: *ArtifactsAPI) APIError!std.ArrayList(ItemQuantity) {
pub fn getBankItems(self: *ArtifactsAPI, allocator: Allocator) APIError!std.ArrayList(ItemQuantity) {
return self.fetchArray(
self.allocator,
allocator,
APIError,
null,
ItemQuantity,
@ -1198,6 +1219,30 @@ pub fn getBankItems(self: *ArtifactsAPI) APIError!std.ArrayList(ItemQuantity) {
);
}
pub fn getMap(self: *ArtifactsAPI, allocator: Allocator, x: i64, y: i64) APIError!?MapResult {
const path = try std.fmt.allocPrint(self.allocator, "/maps/{}/{}", .{x, y});
defer self.allocator.free(path);
return self.fetchOptionalObject(
APIError,
null,
MapResult,
MapResult.parse, .{ allocator },
.{ .method = .GET, .path = path }
);
}
pub fn getMaps(self: *ArtifactsAPI, allocator: Allocator) APIError!ObjectList(MapResult) {
return self.fetchArray(
allocator,
APIError,
null,
MapResult,
MapResult.parse, .{ allocator },
.{ .method = .GET, .path = "/maps", .paginated = true }
);
}
test "parse date time" {
try std.testing.expectEqual(1723069394.105, parseDateTime("2024-08-07T22:23:14.105Z").?);
}

View File

@ -196,7 +196,7 @@ equipment: Equipment,
inventory_max_items: i64,
inventory: Inventory,
pub fn parse(obj: json.ObjectMap, child_allocator: Allocator, api: *ArtifactsAPI) !Character {
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap, child_allocator: Allocator) !Character {
var arena = try child_allocator.create(std.heap.ArenaAllocator);
errdefer child_allocator.destroy(arena);