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), item_codes: std.ArrayList([]u8),
// ------------------------- API errors ------------------------
pub const APIError = error { pub const APIError = error {
ServerUnavailable, ServerUnavailable,
RequestFailed, RequestFailed,
@ -122,6 +124,8 @@ pub const EquipError = APIError || error {
CharacterInCooldown, CharacterInCooldown,
}; };
// ------------------------- API result structs ------------------------
pub const EquipmentSlot = enum { pub const EquipmentSlot = enum {
weapon, weapon,
shield, 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 { pub const ArtifactsFetchResult = struct {
arena: std.heap.ArenaAllocator, arena: std.heap.ArenaAllocator,
status: std.http.Status, status: std.http.Status,
@ -634,6 +680,8 @@ pub const ArtifactsFetchResult = struct {
} }
}; };
// ------------------------- General API methods ------------------------
pub fn init(allocator: Allocator) !ArtifactsAPI { pub fn init(allocator: Allocator) !ArtifactsAPI {
const server = try allocator.dupe(u8, "https://api.artifactsmmo.com"); const server = try allocator.dupe(u8, "https://api.artifactsmmo.com");
const server_uri = std.Uri.parse(server) catch unreachable; 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]; return self.item_codes.items[id];
} }
// ------------------------- Endpoints ------------------------ // ------------------------- Endpoints ------------------------
pub fn getServerStatus(self: *ArtifactsAPI) !ServerStatus { 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}); const path = try std.fmt.allocPrint(self.allocator, "/characters/{s}", .{name});
defer self.allocator.free(path); defer self.allocator.free(path);
@ -943,46 +990,20 @@ pub fn getCharacter(self: *ArtifactsAPI, name: []const u8) !?Character {
APIError, APIError,
null, null,
Character, Character,
Character.parse, .{ self.allocator }, Character.parse, .{ allocator },
.{ .method = .GET, .path = path } .{ .method = .GET, .path = path }
); );
} }
pub fn listMyCharacters(self: *ArtifactsAPI) !CharacterList { pub fn listMyCharacters(self: *ArtifactsAPI, allocator: Allocator) APIError!std.ArrayList(Character) {
const path = try std.fmt.allocPrint(self.allocator, "/my/characters", .{}); return self.fetchArray(
defer self.allocator.free(path); allocator,
APIError,
const result = try self.fetch(.{ .method = .GET, .path = path }); null,
defer result.deinit(); Character,
Character.parse, .{ allocator },
if (result.status != .ok) { .{ .method = .GET, .path = "/my/characters" }
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 actionFight(self: *ArtifactsAPI, name: []const u8) FightError!FightResult { pub fn actionFight(self: *ArtifactsAPI, name: []const u8) FightError!FightResult {
@ -1187,9 +1208,9 @@ pub fn getBankGold(self: *ArtifactsAPI) APIError!u64 {
return @intCast(quantity); 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( return self.fetchArray(
self.allocator, allocator,
APIError, APIError,
null, null,
ItemQuantity, 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" { test "parse date time" {
try std.testing.expectEqual(1723069394.105, parseDateTime("2024-08-07T22:23:14.105Z").?); 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_max_items: i64,
inventory: Inventory, 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); var arena = try child_allocator.create(std.heap.ArenaAllocator);
errdefer child_allocator.destroy(arena); errdefer child_allocator.destroy(arena);