Once you have downloaded the library and added it to you project references you can obtain data by using the static class GwApi.

API Listing

The library is currently broken into 3 sections

Namespace

Description

GwApiNET.GwApi Contains a call for each of the provided GW2 API resources
GwApiNET.Gw2Stats.Gw2StatsApi Contains calls for gw2stats.net api provided by Drakma.1549.
GwApiNET.Gw2PositionReader.Gw2PositionReaderApi Contains mumble link data filled in by GW2 client.  Real time information to Stuff like Character position, Map, Character Name etc..

 

 


GwApi

All data is expected to come in three different forms.

  • Entry (A subclass of ResponseObject)
  • EntryCollection<Entry>
  • EntryDictionary<key, Entry>


    Each API response from GW2 will be broken down into an Entry. There could be multiple Entry values returned from one API request. If there is more than 1 Entry returned, it will be returned in an EntryCollection or EntryDictionary. The EntryCollection implements the IList<T> interface, as such it will be compatible where IList<T> or IEnumerable<T> is required. The EntryDictionary implements IDictionary<T>, as such it is interchangeable with IDictionary<T> and IEnumerable<T> as well.

    API Listening

    Dynamic Events API – BETA

    events.json GwApi.GetEvents(int,int,Guid?,bool)
    event_names.json GwApi.GetEventNames(bool)
    map_names.json GwApi.GetMapNames(bool)
    world_names.json GwApi.GetWorldNames(bool)
    event_details.json GwApi.GetEventDetails(Guid, bool)
    GwApi.GetEventDetails(string, bool)

    WvW API – BETA

    wvw/matches.json GwApi.GetMatches(bool)
    wvw/match_details.json GwApi.GetMatchDetails(string, bool)
    wvw/objective_names.json GwApi.GetObjectiveNames(bool)

    Item and Recipe Database API – BETA

    items.json GwApi.GetItemIds(bool)
    item_details.json GwApi.GetItemDetails(int, bool)
    recipes.json GwApi.GetRecipeIds(bool)
    recipe_details.json GwApi.GetRecipeDetails(int, bool)

    Guild API – BETA

    guild_details.json GwApi.GetGuildDetailsByName(string, bool)
    GwApi.GetGuildDetailsById(string, bool)
    GwApi.GetGuildDetailsById(Guid, bool)

    Map API – BETA

    continents.json GwApi.GetContinents(bool)
    maps.json GwApi.GetMap(bool)
    GwApi.GetMap(int, bool)
    map_floor.json GwApi.GetMapFloor(int, int, bool)

    Miscellaneous APIs – BETA

    colors.json GwApi.GetColors(bool)
    build.json GwApi.GetBuildNumber()
    files.json GwApi.GetFiles(bool)

    Render Service API – BETA

    images (.jpg or .png) GwApi.GetRenderServiceAssetEntry(string, int, string, bool)
    GwApi.GetRenderServiceAssetEntry(FileEntry, string, bool)

     

     


    Dynamic Events API – BETA

    Obtaining Event Information:

    Code Example to print all active events on the Sorrow’s Furnace world:

    // First lets find out what my world ID is
    var worldNames = GwApi.GetWorldNames();
    int world_id = worldNames.Values.Single(w => w.Name == "Sorrow's Furnace").Id;
    
    // now lets get the event names and map names
    // These are lookups keyed on ID value
    var eventNames = GwApi.GetEventNames();
    var maps = GwApi.GetMapNames();
    
    // Now lets get a list of events on my world
    // We can use include whatever information we want to query with
    // In this case we want all events where the world id = world_id
    // we could also reduce our search further by providing a map id or event an event id
    var events = GwApi.GetEvents(world_id, -1, null);
    
    // Lets print all of the active events
    // We can show the map the event is on and it's name
    var activeEvents = events.Where(e => e.State == EventState.Active);
    
    // Lets get the event details for all events
    // we could request a single event detail by providing the event id as well
    var eventDetails = GwApi.GetEventDetails();
    
    // we'll use a StringBuilder to compose our print list
    var sb = new StringBuilder("--- Active Event List ---\n");
    foreach (var e in activeEvents)
    {
        // event detail for current e
        var eventDetail = eventDetails[e.EventId];
        sb.AppendFormat("Name: {0}\n", eventDetail.Name);
        sb.AppendFormat("Map: {0}\n", maps[eventDetail.MapId].Name);
        sb.AppendFormat("Level: {0}\n", eventDetail.Level);
        sb.AppendLine("--------");
    }
    // Print the contents
    Console.WriteLine(sb.ToString());
    
    // We've just downloaded a bunch of data which takes a bit of time
    // Sepcifically the complete event details list
    // If we save this, the next time we need the list it will take very little time
    ResponseCache.Cache.Save();
    

     

    WvW API – BETA

    // Well need this so lets get it now
    var worlds = GwApi.GetWorldNames();
    var objectives = GwApi.GetObjectiveNames();
    
    // Lets get a list of matches
    var matches = GwApi.GetMatches();
    var match = matches.Values.FirstOrDefault();
    // ok lets check out the details of one of these matches
    var details = GwApi.GetMatchDetails(match.Id);
    StringBuilder sb = new StringBuilder("Match Info\n");
    sb.AppendFormat("Worlds:\n");
    sb.AppendFormat("{0} vs. {1} vs. {2}\n", worlds[match.RedWorldId].Name, worlds[match.BlueWorldId].Name, worlds[match.GreenWorldId].Name);
    sb.AppendFormat("Scores: Red - {0}; Blue - {1}; Green - {2}\n", details.Scores[0], details.Scores[1], details.Scores[2]);
    sb.AppendFormat("Start Time: {0}\n", match.StartTime);
    sb.AppendFormat("End Time: {0}\n", match.EndTime);
    sb.AppendFormat("Maps:\n");
    foreach (var map in details.Maps)
    {
        sb.AppendFormat("  {0}\n", map.Type);
        sb.AppendFormat("  Scores: Red - {0}; Blue - {1}; Green - {2}\n", map.Scores[0], map.Scores[1], map.Scores[2]);
        foreach (var objective in map.Objectives)
        {
            sb.AppendFormat("  {0} - {1}\n", objectives[objective.Id].Name, objective.Owner);
            if (objective.OwnerGuildId != Guid.Empty)
                sb.AppendFormat("    Guild: {0}\n", GwApi.GetGuildDetailsById(objective.OwnerGuildId).GuildName);
        }
    }
    
    Console.WriteLine(sb.ToString());
    

    Item and Recipe Database API – BETA

    Obtaining Item Information:

    // Lets get the details of my awesome item.
    var item = GwApi.GetItemDetails(39276);
    StringBuilder sb = new StringBuilder(string.Format("{0} - Item Detail\n", item.ItemId));
    sb.AppendFormat("Name: {0}\n", item.Name);
    sb.AppendFormat("{0}\n", item.Description);
    sb.AppendFormat("Level: {0}\n", item.Level);
    sb.AppendFormat("Rarity: {0}\n", item.Rarity);
    sb.AppendFormat("Type: {0}\n", item.ItemType);
    sb.AppendFormat("Value: {0}\n", item.VendorValue);
    sb.AppendFormat("Buffs:\n");
    sb.AppendFormat("{0}\n", item.TrinketDetails.InfixUpgrade.Buff.Description);
    sb.AppendFormat("Attributes:\n");
    foreach (var attr in item.TrinketDetails.InfixUpgrade.Attributes)
        sb.AppendFormat("\t{0}:{1}\n", attr.Attribute, attr.Modifier);
    sb.AppendFormat("Infusion Slots ({0}):\n", item.TrinketDetails.InfusionSlots.Count);
    for(int i = 0; i < item.TrinketDetails.InfusionSlots.Count; i++)
        sb.AppendFormat("\tType: {1} - {0}\n", item.TrinketDetails.InfusionSlots[i].Item ?? "Unused", string.Join(",", item.TrinketDetails.InfusionSlots[i].Flags));
    
    Console.WriteLine(sb.ToString());
    
    

    Download All Items:

    Keep in mind this can and will take a VERY long time (possibly 20+ minutes).
    This API was not written for efficiency in that manner nor is the GW2 exposed JSON object made available for such efficiency.
    What this API does do however, is allow for us to store this information locally.  Since item information should change very rarely if at all,
    we can cache the information and then retrieve it later.

    Here is the code:

    {
        // lets obtain all the currently known item ids
        var itemIds = GwApi.GetItemIds();
        var itemDetailsDictionary = new EntryDictionary<int, ItemDetailsEntry>(itemIds.Count);
        // This could take 20-30 minutes
        // keep in mind there are currently 27,000+ items at the time of writting this
        foreach (var id in itemIds)
        {
            var item = GwApi.GetItemDetails(id);
            itemDetailsDictionary.Add(id, item);
        }
    
        // This is important, We should save this for nice and fast retrival
        // While our individual items are already stored in the ResponseCache
        // The dictionary is not, and it is much more convenient to just grab the entire dictionary
        // This will allow us easy access to search for items
        // We are going to store it using ItemDetailsDictionary
        ResponseCache.Cache.Add("ItemDetailsDictionary", itemDetailsDictionary);
    }
    
    

    Update Unknown Items:

    Here is another set of code, this will update your previously downloaded list or download the entire item list from GW2.
    Since Item information is essentially static, we can keep the list and just update it on occasion.  You could actually use this code in place
    of the previous code example.

    Here is the code:

    // lets update our complete dictionary of items we've already downloaded earlier
    // first lets obtain the complete list of item ids
    // notice how we passed (true) this time.  This will skip our response cache and for an update.
    // We want to make sure we have a complete list as of right now, not yesterday
    var itemIds = GwApi.GetItemIds(true);
    // Lets get the item dictionary we already have (Remember we stored it in cache)
    var itemDetailsDictionary =
        ResponseCache.Cache.Get("ItemDetailsDictionary") as EntryDictionary<int, ItemDetailsEntry> ?? new EntryDictionary<int, ItemDetailsEntry>();
    // This could take 20-30 minutes
    // keep in mind there are currently 27,000+ items at the time of writting this
    foreach (var id in itemIds)
    {
        if (itemDetailsDictionary.ContainsKey(id) == false)
        {
            var item = GwApi.GetItemDetails(id);
            itemDetailsDictionary.Add(id, item);
        }
    }
    
    // Lets update our ResponseCache with our updated item dictionary
    ResponseCache.Cache.Add("ItemDetailsDictionary", itemDetailsDictionary);
    
    

    Searching Items via LINQ:

    Now that we have all this item information at our fingertips.  What do we do with it.

    Well we could put this into a database, that would allow quick easy random access searching, but the initial overhead to create it may be more than you want.

    How about LINQ?  We are using .NET after all.  This is very useful when we want to do a little searching but the speed is not as much of an issue.

    Here are some examples:

    var itemDetailsDictionary =
        ResponseCache.Cache.Get("ItemDetailsDictionary") as EntryDictionary<int, ItemDetailsEntry> ?? new EntryDictionary<int, ItemDetailsEntry>();
    
    // Search for an item by name
    var item = itemDetailsDictionary.Values.SingleOrDefault(i => i.Name == "Godrock Amulet");
    // Get all lvl 80 items
    var itemsByLevel = itemDetailsDictionary.Values.Where(i => i.Level == 80);
    // What about all lvl 80 weapons
    itemsByLevel = itemDetailsDictionary.Values.Where(i => i.Level == 80 && i.ItemType == ItemType.Weapon);
    // Lets reduce the previous query to all swords; then we'll have all lvl 80 swords
    var swords =
        itemsByLevel.Where(i => i.WeaponDetails.Type == ItemDetailsEntry.WeaponInfo.WeaponType.Sword);
    
    // Lets get all swords within 2 levels of 40
    itemsByLevel = itemDetailsDictionary.Values.Where(i => i.ItemType == ItemType.Weapon && i.WeaponDetails.Type == ItemDetailsEntry.WeaponInfo.WeaponType.Sword && i.Level >= 38 && i.Level <= 42);
    
    

    Download a Recipe:

    Lets do some Recipes

    Lets look up a recipe for an item.  We can use the items dictionary to do our cross referencing, but for simplicity lets just get items individually.

    It should still be pretty quick since all of the items are stored in response cache.

    Here is the code:

    var recipe = GwApi.GetRecipeDetails(1482);
    StringBuilder sb = new StringBuilder(string.Format("{0} - Recipe\n", recipe.RecipeId));
    sb.AppendFormat("Diciplines: {0}\n",string.Join(",", recipe.Diciplines));
    sb.AppendFormat("{0} x{1}\n", GwApi.GetItemDetails(recipe.OuputItemId).Name, recipe.OutputCount);
    sb.AppendFormat("Min Skill Needed: {0}\n", recipe.MinRating);
    sb.AppendFormat("Type: {0}\n", recipe.RecipeType);
    sb.AppendFormat("Crafting Time: {0:#.###}s\n", recipe.TimeToCraftMsec / 1000.0);
    sb.AppendFormat("Ingredients:\n");
    foreach (var ing in recipe.Ingredients)
        sb.AppendFormat("\t{0} x{1}\n", GwApi.GetItemDetails(ing.ItemId).Name, ing.Count);
    
    Console.WriteLine(sb.ToString());
    

    Here is the same code except that we’ll use the Item Dictionary we created in the earlier dictionary to lookup the items.

    TBD

     

    Note: Perhaps you want to download all the recipes.  We can actually use the same algorithm we used in the ItemDetails example. Refer back to the items example.

    Don’t forget to cache the result!  It takes a long time to download all those recipes and they shouldn’t really be changing.

     

     

    Guild API – BETA

    Obtain Guild Info:

    We can obtain some information about a guild.  Currently this is quite limited.  Perhaps it will be expanded to allow insight into member lists, ranks, guild funds etc…

    We can however, obtain emblem information to build the guild emblem.  The information will be part of the response, but building the emblem image isn’t available in this API atm.

    Plans to incorporate emblem building are planned.

    Here is the code:

    var guild = GwApi.GetGuildDetailsByName("Valour Of The Forsaken");
    StringBuilder sb = new StringBuilder("Guild Info\n");
    sb.AppendFormat("Name: {0}\n", guild.GuildName);
    sb.AppendFormat("Tag: {0}\n", guild.Tag);
    sb.AppendFormat("ID: {0}\n", guild.GuildId);
    sb.AppendFormat("We have emblem information too. " +
                    "But we can't display that in console.  " +
                    "I'll leave that up to you to implement for now.\n");
    
    Console.WriteLine(sb.ToString());
    

    Map API – BETA

    The Maps information is more useful when dealing with the tile service.  This contains information about waypoints, points of interest, skill challenges etc… along with map boundaries, continent information and more.  I plan to provide an example on how this would be used in the future.

    Miscellaneous APIs – BETA

    Build:

    While the build value of GW2 isn’t all that interesting, we can use it to know when an update has occurred.  As such this API takes advantage of this information when making caching decisions.  For instance,  Map ames are likely not going to change.  But when they do, it will most likely be after a new build update. As such this API has an interface ICacheStrategy that can be used by the caching engine to determine when an object has expired.

    For example, BuildVersionCacheStrategy uses the build version to determine if an object has expired.  If the build version of the cached object is different than the current build, then it will be considered expired and will attempt to get the new object from the GW2 API servers.  Since this value will never change while someone is logged into the game,  this API only needs to make the call rarely.  As such a static value GwApi.Build is available and it is recommended that any implementation should use this to obtain the build rather than GwApi.GetBuildNumber().  However, if needed, anytime the GwApi.GetBuildNumber() is called, the GwApi.Build property will be updated.

    Here is some code:

     

    Files:

    Lets get some images for our awesome app.  Here is a list of available images provided by GW2 that can’t be found anywhere else in the API.

    Here is the code:

    var files = GwApi.GetFiles();
    StringBuilder sb = new StringBuilder("File Info\n");
    foreach (var file in files.Values)
    {
        sb.AppendFormat("ID: {0}", file.FileID);
        sb.AppendFormat("Signature: {0}", file.Signature);
        sb.AppendLine("Well that wasn't very interesting.\n Now what?");
        sb.AppendLine("Check out the Render Services example on what to do with this boring file information");
    }
    

    Render Service API – BETA

    Download File Images:

    We just downloaded some image file information in a previous example above.  What do we do with this information?  Well we can use the Render Service that GW2 has provided.

    Lets download some images!  Since we can’t display them in a Console, lets save them to a file.  Use any ole image viewer to open them up, or better yet add them to your app!

    Here is the code:

    // Lets get a list of available images
    var files = GwApi.GetFiles();
    foreach (var file in files)
    {   // Lets save them to disk
        var image = GwApi.GetRenderServiceAssetEntry(file.Value, "jpg");
        image.Asset.Save(file.Key + ".jpg");
    }
    // Lets open one of the images in a default image viewer
    Process.Start(files.Keys.First() + ".jpg");
    

     

    Obtain Item Icon/Image:

    Remember when we downloaded all that item information?  Well there is some information that was provided with the item details we downloaded that allows us to obtain images for the items.

    Lets check out some code to see how to do this.

    Code:

    // Lets get an item
    var item = GwApi.GetItemDetails(39276);
    // Now lets download it's icon image
    var image = GwApi.GetRenderServiceAssetEntry(item.IconFileSignature, item.IconFileId, "jpg");
    image.Asset.Save(item.ItemId + ".jpg");
    
    // Lets open the image in a default image viewer
    Process.Start(item.ItemId + ".jpg");
    
    

     

     

     

    API Features

    This library contains a number of features that can be taken advantage of.

    They are not required for the library to work, however, they can aid in the development to provide custom control and debugging.

    • Logging
    • Caching
    • Persistent Settings


    Logging
    A simple logging framework has been implemented.

    Currently there is very little control over the logging framework.
    A List of Logger names can be found in

    Constants.LoggerNames
    


    Logging levels can be turned on or off for each logger using

    // Turns Info logging on for GwApiNETLogger
    GwLogManager.SetLogLevel("GwApiNETLogger", true, LogLevel.Info); 
    // Turns Debug logging off for GwApiNETLogger
    GwLogManager.SetLogLevel("GwApiNETLogger", false, LogLevel.Debug); 
    // Turns all logging off for GwApiNETLogger
    GwLogManager.SetLogLevel("GwApiNETLogger", false); 
    A List of Logger names can be found in Constants.LoggerNames.
    
    // Current Logging levels
    Debug
    Info
    Warn
    Error
    Fatal
    
  • Last edited Sep 1, 2013 at 6:40 AM by cneal13x, version 17

    Comments

    No comments yet.