Showing Posts For Ruhrpottpatriot.7293:

Request Language via Accept-Language header

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

The title pretty much says it all. The HTTP 1.1 Protocol (See Section 14.4 for more details) defines an Accept-Language header field which can be used to request content in a specific language.

This is imo the far better choice than url parameters, since it
a) allows more than one value, thus allowing fallback values
b) keeps the url clean(er)

Administrator of GW2.NET: GitHub , Forum , NuGet

API key group size pattern

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Lawton didn’t specify, that is will be a GUID pattern, nor did he specify how long they will be in the future, but that is not a concern of mine. I just want to know, if they will have a well defined format, whatever that might be.

Administrator of GW2.NET: GitHub , Forum , NuGet

Authenticator Status

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

What? No, that’s the point of an API key: to give them to people who you trust with the information (either directly or indirectly, e.g. by giving them to an application). You probably don’t want to go posting them publically, but they’re not very useful if you keep them secret.

I think I misspelled my point. You are right. You want to give out the api key to people you trust, but not publicly. I still think that an information that is a potential security risk should not be exposed by an api, that is (potentially) open to a wide group of people.

Administrator of GW2.NET: GitHub , Forum , NuGet

API key group size pattern

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

We reserve the right to change the key format and/or length.

This was somewhat clear to me. But even if the key format changes, I can assume that they will have a definitive format?

Administrator of GW2.NET: GitHub , Forum , NuGet

API key group size pattern

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

I think this might be the case, but I’m not actually sure myself.
Do the api keys follow a certain pattern? For now I got 8-4-4-4-20-4-4-4-12 as size. Does this hold true for all generated keys, or are there deviations?

Administrator of GW2.NET: GitHub , Forum , NuGet

Authenticator Status

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

There is a great deal of security issues in your proposal.
1. You are asking the members to give out their api key. Never do that. Granted api keys are not passwords, but they should be kept a secret nonetheless. An exposed api key can still be harmful.
Consider the following: You have a website where the user can input his api key and get informations about his account. Now your website is hacked and the hacker gets hold of the api key (leaving the problem of unencrypted private info out of this). He now can systematically check which account has an authenticator, and which not. He will then hack the ones without additional security.

Yes this could happen if he got hold of the passwords too, but we all know you should never use the same password twice. But even if the users have (which is almost every time the case), you are not making it easier for the hacker, in the case of the api key, you actually do.

2. Providing such info via a public api is a no go, for obvious reasons.

Yes, this is a problem for the guild overall, but it is a problem you have to live with. There are best practices for such occasions, such as giving guild banks access only to trusted members or let your members know why an authenticator is better.

Administrator of GW2.NET: GitHub , Forum , NuGet

Launching /v2/characters

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Perhaps it could default to all permissions checked since we can’t pass a parameter of the permissions we require (ideal).

NO! NO! Never ever do that! The less restrictions are accessible by default, the better. A user should have to grant permissions, not revoke them.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

It took us about a week, but we finally released version 1.0.0 of our popular library. We are sorry for the delay, but we had to fix some last minute issues so everything now and in the future is going smoothly.


  • Split the package into smaller packages to make updating and publishing more modular and therefore faster. See bottom of this post more more details!
  • Made GetParameters and GetPathSegment in DiscoveryRequest virtual so they can be used with the /v2/floors url style
  • Changed constructor of abstract class FactoryBase to protected
  • Stylecop fixes across the board
  • Added Support for v2/floors endpoint and made it publicly available although the api endpoint is currently disabled.
  • Added Support for v2/maps endpoint
  • Added Support for v2/skins endpoint
  • Added Support for v2/continents endpoint
  • Added Support for v2/files endpoint
  • Renamed WvW property in Factoryfor V1 to WorldVersusWorld
  • Added missing ObjectInvariant methods.
  • V2 Factories now implement RepositoryFactoryBase to reduce code repitition
  • Added obsolete warnings for all currently available v2 endpoints
  • Added an obsolete error for the v1 events endpoint since it is already disabled
  • Fixed some bugs in the request classes
  • Added interface and model class for v2/files since the old model/interface is not compatible with the new api layout
  • Updated StyleCop settings

Still there are some things to consider when upgrading:
First of all: We changed the ID of the NuGet package to be in line with the namespaces we use in the project itself. However updating from 0.×.x to 1.0.1 is still possible with a helper package. To use this helper package you don’t have to do anything besides updating your GW2.NET NuGet Package. The helper package is appropriately labeled and will download all required packages by itself. After the update process has been completed you can remove the helper package without consequences.

You then might notice that you have dozens of GW2.NET.xyz packages in your package manager. As already stated in the changelog we have split our one big package into multiple smaller ones so we can deliver updates more frequently in the future. This also allows users to modularise the packages according to their needs.
For erxample: A website which only displays WvW scores will definitely not need the items package. So the developers can simply download GW2.NET World versus World Matches and be done with it.
This of course requires more work form the user since he by himself has to create and maintain the repositoriesby himself, which is currently done by the GW2.NET main package, but this is not hard and documentation on this topic will be updated in the next weeks.

This said: For the masses of developers installing the GW2.NET main package is absolutely sufficient!

For anything else, just leave a message here or read the documentation over at Codeplex

And now: Happy coding

~~ Ruhrpottpatriot

P.S. We will be moving to another OSS provider in the near future. We will keep you appraised of that, should anything change for you.

Administrator of GW2.NET: GitHub , Forum , NuGet

HEADS UP: OAuth2 being replaced next week

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Not going for an EVE-style permission system.

Me is sad
Well I guess you have your reasons for doing so. Maybe we will get something down the road.
Still I like the migration to API keys, this makes developing non-web applications so much easier.

And to all the “API-Key-Hater” (for a lack of better wording), you really should look how EVE and CCP do it. It is an awesome system and they have ran with it for years and never had any big problems.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

So everyone. I haven’t posted here in a while, since I was busy with my university classes.
You can expect a new release this weekend. The release will NOT contain any of the new authenticated endpoints.

To clarify:
With the next release we are officially moving out of Beta and into version 1.0. This version will be the last to support the v1 endpoints. Future versions will throw a warning and at some point an error (expect this to be around 1.5 or so).
Of course this does not hold true for endpoints which are not yet available through the v2 interface.

Since 1.0 is a good foundation to implement bigger changes in the deployment process and the like, you will also see a change in Version numbers. From 1.0 onwards we are using semantic versioning so you can finetune which versions you want to use and which not.

As for the authenticated endpoints, expect them around 1.1 or 1.2, that will be released in a month or so (I hope).

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

I updated the Nuget feed to be the same version as the Codeplex page. Should work now too.

@Steven: If you update to a new version, send me a mail. There is a greater chance I’ll see that

Administrator of GW2.NET: GitHub , Forum , NuGet

Launching /v2/account (w/ Authentication)

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

OAuth2 is more-or-less designed for web applications.

If there’s a lot of demand for native applications we can look into adding EVE-style API keys (wherein the user can generate a long-lived token via the account site and copy-paste it into your application), but for now just assume that you need a webserver.

Also, unrelated, I pushed my example Go application to the Github repo.

I’d love to see EVE style API keys (seriously EVE probably has the best game API out there).
Since we from GW2.NET develop towards both ends (i.e. Web and Desktop) we are in need of something which does not need a callback server. Building towards only one end is in my eyes a bit narrow minded and we would like to see support for API-Keys.

I really think the demand is there. If we look at the wrapper section in the wiki we can see that a good portion of them are written in languages mainly used for desktop applications. The list of applications looks a bit different, still a good portion of desktop stlye applications. However I think most of these applications will use one of the previously listed wrappers, especially if it gets to complicated things like authentication, since this makes everything a lot easier.

Administrator of GW2.NET: GitHub , Forum , NuGet

(edited by Ruhrpottpatriot.7293)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

So I finally got to update the first post. Now with more information for everyone free of charge.

So that you know: We are currently implementing the last of the recently released endpoints. They should be finished in a week, not because they are so hard to implement, but it takes time and between university exams and a job most of the team is currently busy elsewhere.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

MERRY CHRISTMAS FOLKS (or whatever you might celebrate these days)

Finally after months of hard work we have released version 0.9.12 of our popular library. Much has been done since the last version. Finally everything the ANet API has to offer is present in our library. You can query your Quaggans as well as you can use the integrated GW2 Mumble support.

But what has changed exactly? Now that’s too much to remember, but here are the key points:

  • Every endpoint covered
  • Unified query system for everything, safe some few nodes where appropriate documentation is written as you read this text here. You don’t have to keep in mind that the maps endpoint is queried in a different way than events, or items. We did the work for you, so you can code more efficiently and with less errors.
  • Many optimizations to the codebase. Now almost everything can run in parallel. This means, you can query the whole items database in around 30 seconds, opposed to the previous 15 minutes.
  • More strongly typed object, meaning less magic strings and thus even less errors than before.

But where to go from here on?
Sadly we have to announce that this release will be the last release for .NET 4. Operating systems based on XP or even older are in steady decline. With the release of Windows 10 in a few months XP will be more than 13 years old and it’s time to retire it. This and the move to open source for the .NET framework means a wider audience for .NET 4.5 and above. Of course we want to get the biggest user base we can have and this is not possible with .NET 4 anymore.
Therefore we will move to at least .NET 4.5 with the coming versions. We waited so long because we didn’T forget the XP users out there and we wanted to give them the best experience we could offer.
But as I already said: Windows 10 and an open source .NET framework put the nails in the coffin for the current framework version.

I know not everyone is happy about this, but it is final.

So long folks. Happy coding over your (hopefully) free days.

P.S. Yes I know the first post and the Codeplex site are not updated yet. This will happen in the next few hours and days.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

We released version 0.9.6.0 and the hotfix 0.9.6.1 for the main GW2.NET library, we also released 0.9.6.0 for the Rest# specific implementation, as always you can grab it via NuGet as alwys

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

So it has been some busy weeks for me, as you could have guessed for the lack of updates I did. Gladly the team did not stop working and we put out three new releases!

Some of you might have gotten them already from out Codeplex site, but those who rely on NuGet were surely disappointed.

Rejoice! I have updated the packages and you can get them just by updating the package in your solution.

Have fun coding.

Administrator of GW2.NET: GitHub , Forum , NuGet

[API Suggestion] Separate Item APIs

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

If everything goes smoothly with GW2.NET you only have to download it once every patch and then you can access and filter it as you like.

I personally don’t see a reason to change the api for that, in my opinion this is a job for the clients to do.
A reason why there is only one endnote might have something with the /v1/items node which dumps all the items ids in a big list.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

A bit late for an Easter present, but we had to tackle some stuff, so forgive us.

Here is version 0.9.0.0 of the GW2.NET library. It already implements the new skins endpoint and is otherwise a spring cleaned version, with many improvements.

We also provide you now with a second package which uses RestSharp to make the API calls, if you prefer that install the additional package too.

As always you can either grab the library as binarys on our download site or via NuGet (R# implementation). NuGet is totally recommended over that standard download way.

Administrator of GW2.NET: GitHub , Forum , NuGet

Unit Testing the API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

First here is the correct link Steven posted:

http://gw2dotnet.codeplex.com/SourceControl/latest#GW2.NET-Http/GW2.NET Tests/V1/Core/Items/Details/ItemTest.cs
(The forum cuts the url at the space it has and codeplex refuses to accept %20 or + as safe characters, please copy and past the url into your address bar)

Another approach which I used in the early days of “GW2.NET”: https://gw2dotnet.codeplex.com/ was the following:

  • We know from the wiki which response to expect.
  • You fetch the data which is preseted at the wiki and write your tests to compare it
  • If your fetched data is equal to the data you have in the wiki (hardcode it into your tests or something) you know your code works.

Another approach, since querying some nodes (e.g. items.json) is time consuming, is to use mocking. Basically you pass the data to your method you know the api is going to return (in this case a JSON formatted string) and then work with that on your code. This is usually better than querying the api every time, since we expect the api to return data and it is not your responsibility to unit test the ANet api. So here is what you would do:

  • Take the data the api is going to return (from the api itself or otherwise) and pass it to your code via a mocking framework.
  • Test your code with unit tests and the mocking framework.

I personally recommend Moq as mocking framework and NUnit as testing framework. I have made great experience with both. But this is a personal preference use what ever you like.

Administrator of GW2.NET: GitHub , Forum , NuGet

(edited by Ruhrpottpatriot.7293)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

So a little heads up on what we are doing right now:

We are in the finishing steps of our big rework wich will make the library much easier to use for you and for us to maintain. The latest version which you can grab via our Codeplex page includes every endpoint the API has (except mumble), on contrast to the previous version which didn’t include the image endpoint.

Currently we are working on a way to reliable store the contents of the api after you fetched them. We are completely aware, that querying the item API is not the way to go as the content of that endpoint is not going to change often.
However, going with our design philosophy we want to make the library as much extendible as possible. Each user has it’s own preferences on how to store the cache, some will want to store them as JSON files again, some will want to use a backend database and some will want to use another method. We want to satisfy all of them and because of that we are not ready to release the new version just yet.

With the new release we will provide one standard implementation, so the whole package is ready to go directly after you installed it, but if something does not suit you, you can easily change it through dependency injection.

One of our coders (Steven Liekens) has written an example page. He will upload it in the next few days, so you can see what you can do with our library. After the release of the new version we will provide more examples (definitely a WPF integration, WinForms is still up to debate, as that API is going to vanish sooner or later)

Now back from the future to some current problems:

  • I am aware that the current version is not working with the latest GW2 patch, since it introduced a new property for items and therefore deserializing the JSON response will break. We will release a hotfix for that problem today or tomorrow.
  • I am also aware that the current documentation on NuDoq is not working. I am in contact with the site and hope to change that in the next few days.
  • I am more than aware that the documentation on the Codeplex page is not complete (far from it). I am currently a bit stressed with my university homework and have not much time for writing it. I hope to get it done in the next days.

At the end I want to thank my team for putting so much effort into this. Without you we would not be here today.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

A small bug fix release: Grab it via Codeplex or NuGet

Changes:

  • Fixed a bug where the source code would not build in release mode thanks to a wrong csproj element.
  • Changed version number to 0.8.0.2
  • Ran R# code cleanup function to unify code looks.
  • Removed optimize code from debug config for easier debugging.
  • Added x86 and x64 as platform targets to solution.
Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

We just released version 0.8.01 of our api. With this release the current API implementation is done (save mumble and chat links).
You can grab the new version on the Codeplex Download page or via NuGet .

The new documentation is up in parts and the rest will follow shorty (I hope).

Have fun with the new version.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

So heads up for the days after christmas:

I hope to get the events implementation done before new year, but cannot guarantee it. Before that I’ll update the package with better documentation that will be available online via NuDoq.

Have a happy christmas and new year

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Soooooo…..
Nothing new on the development front, well almost.
I took some time to get a NuGet package up and running. Now updating will be even easier. You can grab the NuGet package here

Administrator of GW2.NET: GitHub , Forum , NuGet

Allow querying for multiple event_id's

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Thumbs up for specifying event (and item/recipe) ids in the request body, not just the url.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Long time no see!

After a few months on hiatus (Real Life, at least for me) we are back in action. We just released version 0.7.0.1 of the library and are working (hard) on the next bigger release.
You can grab the pre-compiled binaries HERE.
Of course you are also invited to grab the Source Code directly and modify it according to our license.

I also updated the first post with lots of new information, look around if you have the time!

As always we are looking for developers to help us out. If you think you have it in you, contact me here on the forum (with your Codepley username) or on Codeplex directly.

See you in the game.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

where should I return an interface? could you point me to the code in question?

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

I’m proud to tell you taht we just released version 0.5.0.0 of our GW2.NET library. This marks our first official release besides the usual source code.
You can grab the pre compiled binaries together with the dependencies and the xml documentation files from our Codeplex Download page.

This is only a first step in the direction we want to go.
Our goal is to make this library as easy to use as a Bobby-Car! If you want to know where we are headed and want to follow us just drop by at our Codeplex page and subscribe.

Have fun working with this release.

Ruhrpottpatriot

Administrator of GW2.NET: GitHub , Forum , NuGet

Request for example code for "beginners"?

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

yeah if you want to learn something then it’s better to write your own implementation

Administrator of GW2.NET: GitHub , Forum , NuGet

Request for example code for "beginners"?

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

That’s exactly why I wrote my Perl module,

Well that’s something different. If I’d code in C# and there are only c++ wrapper around I’d write something for myself. That’s not reinventing the wheel.

On the other hand if there are already five c# implementations out there I’d probably grab one of those, since it’s far less time consuming.

@Steckums: GW2.Net also has an WvW implementation (and I might add a more complete one)

Administrator of GW2.NET: GitHub , Forum , NuGet

Guild API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

there is already a topic for guild api suggestion I recommend you put your proposal there.

Administrator of GW2.NET: GitHub , Forum , NuGet

Is the API really this limited?

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Api is still beta and in development, so you can expect to get more features as time goes on. However there won’t be any function in the api that is also in the game.

What you can do with the current API?
Well more accurate and tamper proof dragon-timers, you could also get an Item by it’s name and then query the recipes api to get all recipes which use that particular item.

There are already many possibilities, they just require the developers to work a bit.

Administrator of GW2.NET: GitHub , Forum , NuGet

Request for example code for "beginners"?

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

As you are developing in C#/Asp.Net you could use GW2.NET to have wrapper around the API.
Why reinvent the wheel if you can get one for free

Administrator of GW2.NET: GitHub , Forum , NuGet

Simple C# Example - Rating Calculation

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Also: Holy mother of spaghetti code

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Ok a litte heads up for the people who don’t harcore spam F5 in the codeplex source tab or have it subscribed via RSS

Since the last update we have fixed many bugs, especially in the items wrapper. We have added a guild lookup functionality and we have updated the colours api to support the latest changes.

I hope we can keep up the current pace and start with the async support in a few days.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Yeah I think I’ll test that out in the next few days when I’ve got a bit more time.

// edit: It further seems that if I use the syntactic sugar (i.e. from, in, select, where) with linq it performs slower than the method query (which makes somewhat sense, but I’d have to see the IL to confirm this).
Second: It also seems that if you specify the output type of a linq query instead of using var linq also performs slower.
See here and especially the comment from “Pavel” further down. (Keep in mind however that the first code is built upon a beta of LINQ and the code from pavel upon the final .Net 3.5 release. And I’m currently using 4.0 which is even faster)
Third: It also makes a huge difference to run the release code instead of just the VS code. All my tests I have made have used the debug release version. I’d have to make some tests with the release build

Administrator of GW2.NET: GitHub , Forum , NuGet

(edited by Ruhrpottpatriot.7293)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

To use Enum.HasFlag() I’d have to decorate all enums with the Flags attribute and mark everything with bits. Enum.Has() flag is furthermore not in LINQ itself.

Since I did all the above tests with LINQ and my code as it is in the repository I cannot use the HasFlag() method.

/edit: I did some research on List<T> (since I did all the tests with List<Item>) seems the backing part of a list is in fact an array which holds – as per .Net specification the internal array has a size for up to 500 items. If the item count exceeds the list will double it’s capacity to allow storing more items.

I haven’t found out if the second resize is from 1000 to 2000 or simply from 1000 to 1500.

This would explain why the first of 1000 method calls in the first example takes 5000 ticks (create the list and add the first item) and all subsequent calls (simple adds) are that fast.

Administrator of GW2.NET: GitHub , Forum , NuGet

(edited by Ruhrpottpatriot.7293)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

The code needs to run more than once when you are looking for different items at different times.

That’s why every single lookup first looks if there is a cache and pulls the single item from the cache. Not before is a connection to the server made and the single item from the server pulled.

This is not implemented at every data provider, but I’m working to do that.

Also The next thing I want to include is asnyc support and then I want to change the data provider so that they can get the items from the disk or a database in addition to the server.

Also I have to correct myself the result for the iteration over the bigger list is
Average time 6144 items out of 1753344: 0.010616829 ms(106.16829 ticks) in the above code I was still iterating over the small list. Still the ms count is under 1 ms, so not noticeable.

As for your query: I ran this query:

accountBound = biggerList.Where(item => item.Flags.Contains(ItemFlags.AccountBound) && item.Flags.Contains(ItemFlags.NoSalvage));

and the result is: Average time 5376 items out of 1753344: 0.00635732 ms(63.5732 ticks)

and with the Unqique flag in addition: Average time 0 items out of 1753344: 0.006504914 ms(65.04914 ticks)

and

accountBound = biggerList.Where(item => item.Flags.Contains(ItemFlags.NoSell) && item.Flags.Contains(ItemFlags.SoulbindOnAcquire));

results in: Average time 2816 items out of 1753344: 0.010707205 ms(107.07205 ticks)

So from the results I make that more flags == faster. Which confirms my suspicion that the truly resouce intensive progress is the adding to the list. Which also explains that it takes 500ms to run the complete test, but only about 0.006 ms to run the LINQ query.

Administrator of GW2.NET: GitHub , Forum , NuGet

(edited by Ruhrpottpatriot.7293)

Mapping the API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Here is a sample guild without emblem flags I will post the flags further below:


{
	"guild_id": "FBEACB6E-975B-4E10-9E52-B4E140F1C3B8",
	"guild_name": "Gaiscíoch",
	"tag": "GSCH",
	"emblem": {
		"background_id": 1,
		"foreground_id": 33,
		"flags": [],
		"background_color_id": 473,
		"foreground_primary_color_id": 617,
		"foreground_secondary_color_id": 443
	}
}

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

The thing is: Why should the code get run more than once? There is no need to run multiple subsequent queries to filter the data. And even then. My test did exactly that. 1000 iterations of the LINQ code. The first was at 5000 ticks the other 999 were at 0 to 2 ticks or ~0,0001 milliseconds, that is simply not measurable for the human.

Even if we are talking about 5000 ticks or 0,5 ms – the time of the first query – a normal human will not be able to make the difference between 0,5ms or 1ms. After all the average human reaction time is 1 second or 1000 ms.

It is the same with Google, you just feel it is faster because google tells you with a number it is faster the human brain will not be able to tell if it’s faster.

I will start thinking about changing the background code if we get to times about 150 to 200ms but we are far from that.

Just for teh lulz I ran the following code:



 Stopwatch watch = new Stopwatch();

            watch.Start();

            string[] lineArray = File.ReadAllLines(@"C:\recipe_created_items.json");

            string jsonString = string.Join(string.Empty, lineArray);

            var items = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<int, Item>>>(jsonString)["items"].Values;

            var biggerList = items.ToList();

            biggerList.AddRange(items);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);

            var totalItems = biggerList.Count;
            
            IEnumerable<Item> accountBound = null;

            for (int i = 0; i < 1000; i++)
            {
                accountBound = items.Where(item => item.Flags.Contains(ItemFlags.AccountBound));
            }

            watch.Stop();

            Debug.WriteLine("Average time {3} items out of {2}: {1} ms({0} ticks)", watch.ElapsedTicks, (watch.ElapsedTicks / TimeSpan.TicksPerMillisecond), totalItems, accountBound.Count());

and this code



string[] lineArray = File.ReadAllLines(@"C:\recipe_created_items.json");

            string jsonString = string.Join(string.Empty, lineArray);

            var items = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<int, Item>>>(jsonString)["items"].Values;

            var biggerList = items.ToList();

            biggerList.AddRange(items);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);
            biggerList.AddRange(biggerList);

            var totalItems = biggerList.Count;

            Stopwatch watch = new Stopwatch();

            List<long> ticksCounter = new List<long>();

            IEnumerable<Item> accountBound = null;

            for (int i = 0; i < 1000; i++)
            {
                watch.Start();

                accountBound = items.Where(item => item.Flags.Contains(ItemFlags.AccountBound));
                watch.Stop();

                ticksCounter.Add(watch.ElapsedTicks);
                watch.Reset();
            }

            var averageTicks = ticksCounter.Average();

            Debug.WriteLine("Average time {3} items out of {2}: {1} ms({0} ticks)", averageTicks, (averageTicks / TimeSpan.TicksPerMillisecond), totalItems, accountBound.Count());

The first one took 500ms to run, the second took 0.0897975 ms or 897.975 ticks. If I increase the for loop runs to 100000 it takes 0.003133942 ms or 31.33942 ticks to get all items that are flagged as account bound out of a list of 1753344.

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

yeah well one millisecond are 10000 ticks so half a millisecond is still fast enough. Even if Anet introduces so much flags that it goes up another 5000 ticks, no one should complain about the speed. We are not in real life business applications where every ms counts or you loose half a million Dollar

In my eyes using bitwise flags for every bit of efficiency is a little bit over engineering the code.

But If you drop me your dll and a sample unit test code I’ll gladly run it through LINQ-Pad

Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

So, I did the following query in LINQPad, with a slightly modified data dump from this forum (all I did was to add {"items":{ to the beginning, so I could parse it more easily and I attached the modified json to this post).



//read from file to leave the api call time out
string[] lineArray = File.ReadAllLines(@"C:\recipe_created_items.json");
string jsonString = string.Join("", lineArray);

/Deserialize
var items = JsonConvert.DeserializeObject&lt;Dictionary&lt;string, Dictionary&lt;int, Item&gt;&gt;&gt;(jsonString)["items"].Values;


Stopwatch watch = new Stopwatch();

List&lt;long&gt; ticksCounter = new List&lt;long&gt;();

for (int i = 0; i &lt; 1000; i++)
{
        watch.Start();

        var accountBound = items.Where(item =&gt; item.Flags.Contains(ItemFlags.AccountBound));
        watch.Stop();

        ticksCounter.Add(watch.ElapsedTicks);

        watch.Reset();
}

var averageTicks = ticksCounter.Average();

Debug.WriteLine("Average time 24 items out of 6849: {1} ms({0} ticks)", averageTicks, averageTicks / TimeSpan.TicksPerMillisecond);

// Result: Average time 24 items out of 6849: 0.0003 ms(3 ticks)

If I convert the query into a list I get the following result:
[qutote]
Average time 24 items out of 6849: 0.5012394 ms(5012.394 ticks)
[/quote]
I had to measure the ticks, milliseconds was too inaccurate, all I got was 0 :P

And I guess I can live with 3 ticks and even with ~5000ticks time. The real bottleneck is not LINQ but the server, if you do a whole query you will wait about 15 to 30 munutes :P
Btw: the first call takes about 4600 ticks every query after that goes between 0 and 2 ticks.

Administrator of GW2.NET: GitHub , Forum , NuGet

[API Suggestion] Colors

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Great now I spent one whole hour at Starbucks and drank three whole Choclate Mocca and made a colour conversion code and now you just waltz in here and throw us the rgb bone… you just cost me 12€! To the walk of shame with you :P

Just kidding thanks for the rgb values!

Administrator of GW2.NET: GitHub , Forum , NuGet

Mapping the API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Here is the colours object. I formatted the first and last expression and deleted the ones in the middle.



{
	"colors":
	{
		"1231":
		{
			"name":"Glacial Teal",
			"cloth":
			{
				"brightness":27,
				"contrast":1.83594,
				"hue":175,
				"saturation":0.117188,
				"lightness":0.78125
			},
			"leather":
			{
				"brightness":32,
				"contrast":1.83594,
				"hue":175,
				"saturation":0.0976563,
				"lightness":0.78125
			},
			"metal":
			{
				"brightness":32,
				"contrast":1.99219,
				"hue":175,
				"saturation":0.078125,
				"lightness":0.917969
			}
		},
		// additional colours go here here
		"1221":
		{
			"name":"Key Lime",
			"default":
			{
				"brightness":2,
				"contrast":1.09375,
				"hue":130,
				"saturation":0.78125,
				"lightness":0.996094
			}
		}
	}
}
Administrator of GW2.NET: GitHub , Forum , NuGet

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

I’m not denying that your method is faster, I’m aware of that. However things that speak against your code:

  • The expression if ((pair.Value.Flags & GW2APIFlagsEnum.AccountBound) != 0) {…} is not per se more friendly for the end user. My code on the other hand tells the user what it does. In the statement itemsReturn.Where(item => item.Flags.Contains(ItemFlags.AccountBound)) even a newcomer to c# can see what is happening. Even more so id use I’d query notation.
  • Your code has 60 characters (without anything in-between the curly brackets, which is still needed and without the call to the api/cache to get the items in the first place). My code is 95 characters in length (with conversion to the final collection, but without the call to the api/cache). Therefore I deem your code – without knowing a more detailed example – marginally shorter than mine.
  • It is more work to implement. Not harder to implement not necessarily harder, but it is more work. Therefore it is more error prone and more time consuming than a simple conversion to a collection.

On the other hand your code is definitely faster. I’m currently running a simple stopwatch experiment to get the rough time it needs to call the api, get all items and filter the items that are account bound. I’ll post the times as soon as I get them.

For me personally I don’t deem the performance gain via the use of bitwise-AND to be great enough to justify a lengthier implementation time (we might have the current api complete but who knows what will come in the future and how many enums we might need) with potentially more errors.

I also want to make the code as easy to use for the end user as it possibly can be. I also want to keep as many doors open as I can, therefore the simple conversion to a collection of enums, no more no less (side effect: I simply declare them and leave Json.Net to do the rest)

In the end I have to decline thankfully to your offer.

/edit: I find this post from a SO user on the performance cost of LINQ pretty good.

Administrator of GW2.NET: GitHub , Forum , NuGet

(edited by Ruhrpottpatriot.7293)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

The fist line is to get the general collection, this is needed at your code too I presume.

Furthermore with LINQ you don’t have to convert it into a list. I just wrote the operation upon the existing unit test I had in place for geting al items.

I’m currently in the train to get home and the mobile internet is mediocre and I don’t have the VS (my MBA is running low on battery), but I can assure you that the whole operation is also possible with an IEnumerable. It should be SelectMany<TSource, TResult>(IEnumerable<TSource>, Func<TSource, IEnumerable<TResult>>) or something in that direction.

// Get all items
ItemManager manger = new Manger();

// use SelectMany() to get all items that are account bound
var items = manger.Items.SelectMany(accountBound =>accountBound.Flags.Contains(ItemFlags.AccountBound));

Yes in the end your operation is faster (duh! its O(1) after all :P), but I deem the speed benefit not great enough to justify the additional work I and the other developers have to do, unless you can prove that it is really that much faster.

Administrator of GW2.NET: GitHub , Forum , NuGet

(edited by Ruhrpottpatriot.7293)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

First: I’m deserializing into a collection not a list (IEnumerable<T> is specifically not a list, for good reasons)

Second: On first sight it may look like deserializing into a collection is more work, but if you use LINQ (which is the recommended way of accessing the collections in this wrapper), the code becomes much shorter. Example: I want to get all items that are account bound, I’d do it like this:

ItemsManager manager = new ItemsManager();

// need to convert to a list for the Find all method but everything is also doable with just IEnumerable<T>
var itemsCollection = manager.Items.ToList();

var accountBoundItems = itemsCollection.FindAll(i => i.Flags.Contains(ItemFlags.AccountBound));

It’s slightly longer than your code, but it’s much easier to implement for the developer on the wrapper side.

You can do so much with LINQ, and the performance cost of being evaluated each time the function is called can easily be circumvented and is usually (even here in collections with 8k to 10k items in a collection) negligible)

Administrator of GW2.NET: GitHub , Forum , NuGet

Mapping the API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

You should include “Booze” into the list of consumable types.

Administrator of GW2.NET: GitHub , Forum , NuGet

[How To] Colors API

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

Yep, that’s probably it. Colors only have a defined range. in RGB you simply cannot go beyond 255 and below zero. So any values above or below the max/min part should be interpreted as their respective max/min values.

I think that the values above or below the normed values come from mathematical conversion. WE don’t know if ANet uses the same way to storage the color values in the game as they give us via the api.

Administrator of GW2.NET: GitHub , Forum , NuGet

[API suggestion] Server names

in API Development

Posted by: Ruhrpottpatriot.7293

Ruhrpottpatriot.7293

You could do an RegEx to get that part from the name into it’s own variable.
Personally I don’t have a problem with the language being a part of the name.

Administrator of GW2.NET: GitHub , Forum , NuGet