GW2.NET a .NET wrapper around the GW2 API

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

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: DarkSpirit.7046

DarkSpirit.7046

You are converting to a List first anyway and that is still an O(n) operation compared to mine which is an O(1) operation. Furthermore, to check for the flag, my client only needs 1 line of code so the complexity is much lower.

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: DarkSpirit.7046

DarkSpirit.7046

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.

Well like you said, I do deem it to be more efficient because it is O(1) versus O(n). You are comparing the speed at which a computer processor performs a bitwise-AND versus FindAll. Even though I like LINQ myself, there is just no comparison the bitwise-AND operation is going to be faster. Sorry you would just have to trust my words since I don’t have the time to do performance testing.

Like I have said, if you prefer my approach, I am willing to share my code to reduce the amount of work you guys need to use it. My code uses the dynamic type, from .NET 4, so I hesitated to share it earlier.

(edited by DarkSpirit.7046)

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: DarkSpirit.7046

DarkSpirit.7046

That seems to be a fair analysis and in the end, it is your call. Thanks for looking into it though.

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

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: DarkSpirit.7046

DarkSpirit.7046

Lol…I knew the bottle-neck would be the server which was why I asked you to take the data dump in the first place.

https://forum-en.gw2archive.eu/forum/community/api/NET-Implementation/first#post2131073

This would impact performance even more than what we talked about recently. Asking your user to wait 15 to 30 minutes is extremely long.

You should try a bitwise-AND operation and see how many ticks it takes, if it even registers. If you take the outer loop of going through nth items in your list + going through your Flags enum List, your algorithm becomes O(n-square) while mine would be O(n). If ArenaNet introduces more items and Flags in the future, which they probably would, your algorithm performance would be impacted more than mine, at least in theory. But I can understand if you think that bitwise operations are not as intuitive and you decided to sacrifice efficiency to make your code look more intuitive.

(edited by DarkSpirit.7046)

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: DarkSpirit.7046

DarkSpirit.7046

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

I am not sure if you are seeing this from the perspective of an actual app. Performance is critical when you are displaying large amounts of data where the code to access the item data don’t just get run once, but many times. Any performance inefficiency in your core library data accessors get multiplied.

That said, I don’t wish to sound all “doom-and-gloom” if you don’t use bitwise operations. Your library performance may just be good enough for most apps, plus you do have better code readability your way, I’ll give you that.

I am not ready to drop my dll yet as I am in the middle of making changes. But I can share my code to deserialize JSON flags to bit flags so you can copy-and-paste to integrate it to yours and test it, if you wish.

(edited by DarkSpirit.7046)

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: DarkSpirit.7046

DarkSpirit.7046

The code needs to run more than once when you are looking for different items at different times. The performance does look good enough. I am curious though, if you need to check more than one flag (e.g. AccountBound + SoulBound, etc), how much does the performance differ, if at all.

(edited by DarkSpirit.7046)

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)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: DarkSpirit.7046

DarkSpirit.7046

Thanks for the experiments. I dont think there should be any big performance issue with that so I am convinced.

On a side note, for enum flags, you can also use the Enum.HasFlag method to make your code more readable instead of checking the bit states yourself.

(edited by DarkSpirit.7046)

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: DarkSpirit.7046

DarkSpirit.7046

I don’t use flags on all my enums either. I only use enum flags in GameType, Item Flags, Restrictions, Infusion slot flags (i.e. Defense, Offense, Utility), and upgrade component flags because these come in the form of JSON arrays and can hold more than one enum value. But yes, I agree there would be quite a bit of work involved if you do the change.

You can pass a capacity parameter to the List constructor and test your theory.

(edited by DarkSpirit.7046)

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

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

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

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: DarkSpirit.7046

DarkSpirit.7046

Code looks pretty clean. Why don’t you return an interface to the client instead of a class?

I suggest looking into the Inversion of Control design pattern That should help make your *Data objects pluggable with test classes using test data or other data providers.

(edited by DarkSpirit.7046)

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: DarkSpirit.7046

DarkSpirit.7046

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

I am on vacation right now but, if I recall, by looking at your code in the past, didn’t you return ItemData to the client?

If you did, then you have created a dependency between the client code and your class.
Look into the design pattern to loosen the coupling between client code and your lib. For example, your Gw2ApiManager class seems like it can be modified into a Service Locator or you may decide to use a Dependency Injection pattern.

These are just some suggestions to loosen the coupling with your client code, so you may choose to ignore them if you like. I will not be offended.

(edited by DarkSpirit.7046)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: timidobserver.7925

timidobserver.7925

So, is anyone able to help me figure out where I am going wrong at trying to get this to work. Here are my steps.

1.Downloaded the 0.5.0.0 release(this doesn’t happen if I use the latest source code. It works fine with the latest source code.)
2. Opened visual studio 2012 professional.
3. Started new project.
4. Right click references and added all of the dlls in the place that I saved the latest release.
5. Put using gw2dotnet.v1 in my new project.
6. Put the following items in my code directly from the example.
GW2DotNET.V1.World.WorldManager wm = new

GW2DotNET.V1.World.WorldManager();
var allEvents = wm.Events.ToList();

I got the following error.
Newtonsoft.Json.JsonSerializationException was unhandled
HResult=-2146233088
Message=Error converting value “Inactive” to type ‘GW2DotNET.V1.World.Models.GwEventState’. Path ‘events10.state’, line 11, position 99.
Source=Newtonsoft.Json

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: poke.3712

poke.3712

1.Downloaded the 0.5.0.0 release(this doesn’t happen if I use the latest source code. It works fine with the latest source code.)

And that’s the problem The 0.5.0.0 release was released when the `Inactive` event status did not exist in the API yet. So whenever the API outputs an inactive event, the deserialization fails because there is no equivalent enum value it can map to.

Support for the status was apparently added in the version directly after the 0.5.0.0 release, so you should be fine using any newer version than the released one.

@poke // GW2W //

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: timidobserver.7925

timidobserver.7925

Makes sense. Thank you.

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

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

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

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

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

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: StevenL.3761

StevenL.3761

Thanks for taking the time to post all that. You saved me a lot of typing. :P

Here’s the demo website that was mentioned in the post above: http://guildwars2netdemo.apphb.com/

This website is also entirely open-source (currently without a license, but I’m leaning towards the MIT license). To anyone reading this: I am desperately in need of someone who knows how to tame HTML/CSS/JavaScript and has experience with (or is willing to learn about) ASP.NET MVC 4.

Your job will be to:

  • figure out how to use the GW2.NET library (with my personal guidance)
  • provide feedback about code that we’ve written
  • develop example applications that demonstrate how the library can be put to good use

If you are this person, send me a private message. I check these forums at least daily.

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

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: StevenL.3761

StevenL.3761

v0.9.1.0

I’ve gone ahead and updated the library to include all of the latest bugfixes and features that didn’t make it into the previous release. Mostly regarding the item_details endpoint.

You can get the updated binaries from the project page. The updated Nuget package should follow soon(ish).

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

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: StevenL.3761

StevenL.3761

Hey guys

I published version 0.9.9.0 of GW2.NET on the Codeplex project page.
This release adds support for all /v2/commerce services.

https://gw2dotnet.codeplex.com/

Enjoy!

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: StevenL.3761

StevenL.3761

Hello again

You can now download version 0.9.10.0 of the library. This release adds support for the /v2/items service, and fixes some issues with the implementation for the /v1/item_details.json service.

https://gw2dotnet.codeplex.com/releases/view/133598

Enjoy!

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: Aerodin.2795

Aerodin.2795

Awesome work, as always. Thanks guys!!

Author of GW2 PAO

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: TehGear.8702

TehGear.8702

Hey Steven,

I currently have an issue with this method: IDictionaryRange<TKey, TValue> FindAll(ICollection<TKey> identifiers); it gives back no prices at all. (GW2DotNET.V2.Commerce.PriceService)

Regards

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: StevenL.3761

StevenL.3761

Can you give me the collection of identifiers that causes the problem? I’ll take a look at what’s going on.

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: TehGear.8702

TehGear.8702

var prices = PriceService.FindAll(new Collection<int>() { 9591, 12852 }); //Doesn’t work

var p1 = PriceService.Find(9591); // Works
var p2 = PriceService.Find(12852); // Works

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: StevenL.3761

StevenL.3761

I’m taking a look at it. Bug confirmed, but I’m not sure why this is happening. Both “Find()” and “FindAll()” use the exact same serialization engine. The only difference is that one object is part of a collection, the other isn’t.

Edit

Turns out it is a copy-paste-programming error. The ‘FindAll()’ method is talking to the /commerce/listings service instead of the /commerce/prices service. Thanks for the feedback!

(edited by StevenL.3761)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: TehGear.8702

TehGear.8702

I was trying to find it myself, but I couldn’t find out how to reference the projects correctly.

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: StevenL.3761

StevenL.3761

You only have to reference GW2.NET.dll and GW2.NET.Core.dll for that. Don’t reference the Contracts.dll libraries. You can reference other libraries, but you don’t have to.

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: TehGear.8702

TehGear.8702

I mean I tried to find the bug, with debugging, but I couldn’t find out how to reference the projects properly.

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: StevenL.3761

StevenL.3761

  • Open your solution
  • Select your main project in the solution explorer
  • Project | Add Existing Item… | GW2.NET.csproj
  • Project | Add Existing Item… | GW2.NET.Core.csproj
  • Project | Add Reference… | Solution | Projects | GW2.NET, GW2.NET.Core

edit

I see the problem now. The GW2.NET.Core.csproj configuration file wasn’t source controlled for some reason.

(edited by StevenL.3761)

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: StevenL.3761

StevenL.3761

I uploaded version 0.9.11.0 of the library. This is a bugfix release that, among others, fixes the problem with the ‘FindAll()’ method on the prices service.

https://gw2dotnet.codeplex.com/releases/view/133644

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: TehGear.8702

TehGear.8702

I’m not sure if it’s FindAll or in general, but when I call the FindAll function with more than 350 Ids, it get’s a parser error instead of the endpoint is limited to 200 error.

I think, it’s because of the hardlimit of the URL.

GW2.NET a .NET wrapper around the GW2 API

in API Development

Posted by: StevenL.3761

StevenL.3761

That’s just our error logic tripping over the HTML response when it was expecting JSON instead. Nothing much that I can do about besides ensuring that the content type header is application/json before attempting to parse the error content.