268,435,465 decimal is 10 00 00 09 hexadecimal. Does that number ever change? What happens when you guest on another world?
The point was that should have a single function that returns the entire response object. You have to do this in order to prevent your script from making multiple HTTP requests for the same json object.
function getItem(itemID) {
var myUrl = "http://www.gw2spidy.com/api/v0.9/json/item/" + escape(itemID);
var jsonData = UrlFetchApp.fetch(myUrl);
var jsonString = jsonData.getContentText();
return JSON.parse(jsonString).result;
}
var item = getItem(the_item_identifier);
var sellValue = item.min_sale_unit_price;
var salePriceChangeLastHour = item.sale_price_change_last_hour ;
var buyValue = item.max_offer_unit_price;
var offerPriceChangeLastHour = item.offer_price_change_last_hour;
We don’t know what the JSON response will look like yet. We’re still waiting for more info on version 2 of the API and its release date.
But a thing I can’t see is prices of the item? The only price I can find is the vendor price?
You’re looking for these:
Hey!
Read these first:
API version 1: https://api.guildwars2.com/v1
API version 2: https://api.guildwars2.com/v2
Note that gw2spidy does not use the official API. It uses the same web service that the game client itself uses to access trading post data. Which is not a supported scenario.
Thanks. Are you converting the flags to bit flags in your code? That’s usually what makes my program crash whenever they add a new value. I wish they would announce these changes, so I don’t have to.
I think this would be categorized as an accessibility feature, similar to screen narrators or magnifiers. So it should be fine.
New item flag: MonsterOnly
Example:
https://api.guildwars2.com/v1/item_details.json?item_id=8469
I like that idea. There’s also HTTP 303 “See Other”. It is similar to HTTP 302, but with a subtle difference that makes it more suitable:
A 303 response to a GET request indicates that the origin server does
not have a representation of the target resource that can be
transferred by the server over HTTP. However, the Location field
value refers to a resource that is descriptive of the target
resource, such that making a retrieval request on that other resource
might result in a representation that is useful to recipients without
implying that it represents the original target resource.
Don’t go yet, I have more riddles for you to solve!
Have a stab at this one:
/v2/eggs?ids=yellow,yellow,green,yellow,red,blue,yellow,yellow
What is the output? You have 5 minutes to solve this quiz.
Okay so this one. Cool. Now let’s update the API so that it throws a non-redundant redundancy error.
It’s not bad code that lets me send duplicate identifiers.
It is the absence of code that guards against it that lets me send duplicate identifiers.
In which universe do you only have to check preconditions on the client side but not on the server side?
Custom code alert.
I can do the same thing through reflection if the response did have the duplicate entries. But the duplicates break the X-Result headers, so we can’t have duplicates. So we can’t have reflection. Unless we get errors.
The API accepts duplicates of the numbers for convinience
That’s funny, I find it very *in*convenient.
(edited by StevenL.3761)
You can do this:
You get it once
Or you can do this:
i don’t want to write it down 40 times
But you cannot combine these two statements in a single response object.
I swear I’m not making this up.
Assuming that you have an error handler that sits somewhere between the code that makes the request and the code that handles the response. This error handler is the same for all services, because the error response is the same for all services. It doesn’t matter which service gives you the finger, because your error handler has got your back.
On the other hand, things gets complicated a lot faster if you have to verify that the response is what you’d expect for each and every request that you make. It is not unlikely that you’d end up writing custom code for each endpoint.
Furthermore, if you know that you will only get what you asked for, you can make other assumptions about your code such as how big an array has to be to fit all elements inside. I know that this doesn’t apply to PHP, but it does in C# and other languages.
Even comparing apples to tomatoes would make more sense.
As you wish
http://www.diffchecker.com/c8dpl9j2
Why would you force someone to change the request even if you could deliver what has been requested?
For the purpose of only ever returning exactly what has been requested. That, or an error. Do you really have no clue why that might be important?
(edited by StevenL.3761)
Dude, why are you so mean? My analogy is not about comparing data to physical objects. It is about comparing public services to public services.
You don’t even realize that what you’re doing is almost exactly what I want the API to do.
HTTP Error 400 Bad request
{
"text" : "You asked for 40x the same string of text. You *can* get it once instead if you simplify your request."
}
Forcing me to try again instead of giving me something I’m not asking.
(edited by StevenL.3761)
You get what you’ve asked for. You wanted $identifier X, you get the data for it. Once. Even if you send it a thousand times, the data will still stay the same.
I didn’t mean it like that. We’re starting to mix up different ideas.
How it is right now
- I ask for 40 yellow easter eggs
- I receive 40 yellow easter eggs
- The receipt says that 35 eggs are in stock
- The receipt says that I received 40 of 35 eggs
How you say it should be
- I ask for 40 yellow easter eggs
- I receive 1 yellow easter egg
- The receipt says that 35 eggs are in stock
- The receipt says I received 1 of 35 eggs
How it should be
- I ask for 40 yellow eggs
- The cashier explains to me that there is only 1 yellow egg
As far as we know the quagans where perhaps still disabled and they just forget to lock them up again.
Well, no. The /v2 page that was posted on twitter didn’t even have an entry for /v2/quaggans. They added quaggans to the list a couple of weeks later, unlocked, presumably to help you and me get acquainted with the new syntax. I don’t know why they never made a public announcement, but that could mean anything (including nothing).
(edited by StevenL.3761)
I don’t know if that’s how they implemented it, but at least that’s how it behaves right now. So I’m using that as the specification.
They may have written it like this:
SELECT * FROM quaggans WHERE ID = "404"
UNION ALL
SELECT * FROM quaggans WHERE ID = "404"
UNION ALL
SELECT * FROM quaggans WHERE ID = "404"
UNION ALL
...
(edited by StevenL.3761)
The output is incorrect, but returning output other than what is requested is also incorrect. I don’t expect a fish when I ask for a basket of eggs.
You’re right about it being a client side error. You’re wrong about allowing the client to continue when it does that.
(edited by StevenL.3761)
We’ve already established that they are not using that particular SQL construct. Otherwise we wouldn’t be getting duplicate objects in the response content.
If you really think the API should act in a way YOUR program expects it to work, you’re wrong.
Exactly my point… it should crash with an error.
{"text":"request contains duplicate identifiers."}
My program doesn’t expect the API to return an error, because I’m not violating any protocols. But instead of leaving my program in an invalid state ( count < expected ), I now have an error code that I can use to throw an exception.
(edited by StevenL.3761)
You suggest that I should be allowed to request ?ids=404,404,404 but get only a single response object even though my program is expecting three objects? Nope, nope, nope, so much nope.
It’s a bug because it is (indirectly) violating a design constraint. The constraint would be:
X-Result-Count <= X-Result-Total
I suppose they could just decide to increase the Total by 1 for each duplicate identifier, but I’d rather get an error.
… is totally valid and would return exactly one line.
That’s not what is happening though. The output contains duplicate objects.
(edited by StevenL.3761)
Bugs in /v2
- duplicate identifiers in bulk requests are allowed
* /v2/quaggans?ids=404,404,404,404,… - As a result, X-Result-Count can be greater than X-Result-Total
* ids=404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,aloha,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404,404
* X-Result-Count:36
* X-Result-Total:35
Nope, just part of my testing habits. I’m preparing my code for future /v2 services.
I found an interesting way to break the /v2 API. You can specify the same identifier more than once. But you can only specify a limited number of characters (~2000) before the API crashes with an error.
/v2/quaggans?ids=404,404,404,404,…
What’s interesting is that this also messes with the response headers: X-Result-Count can be greater than X-Result-Total.
If there is a technical reason, it has to be because Dry Top was released in two parts. I guess they never tested for that scenario when they designed the backend for the tiles service.
Fun fact: the official Atlas has the same problem: http://atlas.guildwars2.com/en/#/map
Okay, I think I get it now. The map has 2 floors, but only floor 1 is unique to that particular instance (map_id 80).
map 80 floor 1: http://pastebin.com/7npdP0rK
So because floor 2 is not unique for map_id 80, it is substituted with floor 2 of the map with the exact same coordinates. In this case Divinity’s Reach (map_id 18).
map 18 floor 2: http://pastebin.com/L8rtaiug
What’s interesting/confusing though is that floor 2 defines parts of the maps that also appear on floor 1.
map 18 floor 1: http://pastebin.com/ysnDenPc
Diff: http://www.diffchecker.com/edwngyb0
So I guess that’s the mechanism that allows different maps to have the same map elements… still confusing.
Thank you. But now I have a different issue. Some maps have floors that do not exist in the map_floor service.
Example: A Society Function (story instance). This map has 2 floors.
- https://api.guildwars2.com/v1/maps.json?map_id=80
"floors":[1, 2]
I would expect to find this map in the output for floors 1 and 2 of map_floor.json .
- https://api.guildwars2.com/v1/map_floor.json?continent_id=1&floor=1
- https://api.guildwars2.com/v1/map_floor.json?continent_id=1&floor=2
The trouble is that floor 2 doesn’t have an entry for map_id 80 at all.
What’s going on here?
I don’t really understand the concept of map floors. I know that:
- A continent has a collection of floors
- A continent has a collection of maps
- A map has a collection of floors
- A map has a default floor
- A map has a collection of points of interest
- A point of interest is located on a floor
The documentation is not very clear on how all of these relate to each other. Can someone explain?
Perhaps the most robust way to get a list of open world maps is to filter out maps that do not have waypoints (points_of_interest.*.type == “waypoint”). It requires a bit of coding effort, but it will save you from having to maintain a spreadsheet.
(edited by StevenL.3761)
I looked into this a little bit more. It is true that “Magic Sucks” is only accessible as part of the story, but it IS actually a map. It lies just north of Rata Sum, and has a single sector labeled “Advanced Metamystics Lab”. Rata Sum has a portal that leads to the map, but it is disabled for some reason.
The only other map on floor 0 without an entrance is “Readings On the Rise”. It has a single sector labeled “Dynamics Union”, which is on the second level of Rata Sum.
So what do these have in common? They’re both story instances that start in Rata Sum. What does that mean? I don’t know.
(edited by StevenL.3761)
New item type: Trait
Example:
https://api.guildwars2.com/v1/item_details.json?item_id=66115
@devs why isn’t this a consumable // unlock // trait type??
(edited by StevenL.3761)
I’m guessing that you’re after a list of maps that count towards world completion? I suspect that floor 0 is what you’re after.
https://api.guildwars2.com/v1/map_floor.json?continent_id=1&floor=0
I added an example of the Link header to the original post.
Well… if soon™ means not now, I’m pretty confident that not anytime soon™ means never.
Easter egg (sort of): try adding extensions at the end of the URL.
Did you just brute force gw2 words to find this?
Hahaha! No, I regularly check the /v2 page to see whether any APIs have been enabled yet. Yesterday I noticed that they added /v2/quaggans to the list.
I’m not sure when this happened, but the first /v2 API has gone public: https://api.guildwars2.com/v2/quaggans
The quaggans API returns a list of quaggan identifiers that correspond to a quaggan image. You can get the image URLs using the /v2 request syntax (see https://api.guildwars2.com/v2).
Examples
- https://api.guildwars2.com/v2/quaggans/404
- https://api.guildwars2.com/v2/quaggans?ids=404,aloha
- https://api.guildwars2.com/v2/quaggans?ids=all
- https://api.guildwars2.com/v2/quaggans?page=0
- https://api.guildwars2.com/v2/quaggans?page=0&page_size=3
Response Headers
Take note that /v2 replies with HTTP response headers that provide additional information:
Requests that return identifiers:
- X-Result-Total (numeric, total count of elements)
Requests that return details for a single identifier:
- Content-Language (text, ISO 639-1 code)
Requests that return details for multiple identifiers:
- Content-Language (text, ISO 639-1 code)
- X-Result-Count (numeric, count of returned array elements)
- X-Result-Total (numeric, total count of elements)
Requests that return details for multiple identifiers (paged):
- Content-Language (text, ISO 639-1 code)
- Link (text, service metadata, rfc5988)
- X-Page-Size (numeric, maximum size of the array)
- X-Page-Total (numeric, total count of pages using X-Page-Size)
- X-Result-Count (numeric, count of returned array elements)
- X-Result-Total (numeric, total count of elements)
Link format
Paged responses are accompanied by a Link header. This header contains 4 comma-separated links:
- The next resource: rel=next
- The current resource: rel=self
- The first resource: rel=first
- The last resource: rel=last
Example
</v2/quaggans?page=1>;rel=next,
</v2/quaggans?page=0>;rel=self,
</v2/quaggans?page=0>;rel=first,
</v2/quaggans?page=11>;rel=last
(edited by StevenL.3761)
After reading this, I deliberately bought a piece of karma armor that wasn’t already in the API (item id 4438: Stentor Leggings) just to find out if it would show up in the API afterwards. It doesn’t. There has to be some other trigger.
https://api.guildwars2.com/v1/item_details.json?item_id=4438
Why are you setting UseCookies to false? Also, did you realize that you are never actually injecting your instance of HttpClientHandler into the HttpClient?
Line 35
UseCookies = true
Line 38
using (httpClient = new HttpClient(httpClientHandler) { BaseAddress = baseAddress })
New container type: OpenUI
Example:
https://api.guildwars2.com/v1/item_details.json?item_id=20313
New gizmo type: ContainerKey
Example:
https://api.guildwars2.com/v1/item_details.json?item_id=19980
(edited by StevenL.3761)
Your JS script calls the API controller on your own server: http://yourserver/tradingpost/listings. This when your C# code takes over. Your API controller first ensures that your server has a valid session, then gets the requested data from the TP service. Returning the data to your script can be as simple as calling ‘Response.Write(json)’. This is when your JS script takes over again. It’s not particularly hard, and I think you’re overthinking this.
tl;dr: your API controller acts as a proxy that hides the complexity of maintaining a session
(edited by StevenL.3761)
Boss rotations have changed since my last post on this thread. Here is the updated XML.
EDIT: fixing errors
Attachments:
(edited by StevenL.3761)
If this is a C# project, then the usual way of dealing with this is to do all of the authentication and stuff on the server side in an ASP.NET Web API project. Your JS script should never need to call the TP service directly. Instead, it should call your own API controller. Your API controller should then take care of network handshakes and all that, then return the requested data from the TP service.
Neither /v2/commerce/exchange nor /v2/commerce/listings recognize HTTP POST requests. This is a clear indicator that these will be read-only APIs. So nothing that you couldn’t already do using unofficial APIs.
Well, I already implemented the details that we know about by reading over the /v2 txt document. But what about response objects? When will we know how responses are serialized?