Wolf Fivousix.4319:

Hello everyone, after reading about the API’s and seeing what they’re able to do I would like to make something of my own. Unfortunately I don’t have a clue how to start it and would like some directions.

I’m a beginner programmer in C++, but I’m sure I can work my way to whatever I need to learn.

How can I start something very simple, like seeing the value of an item in the trading post, or looking if an event is up, or anything as simple as that – if there is.

Any help is welcome, thank you.

Heimdall.4510:

If you want to see some example code in C/C++ for the Gw2-API have a look at my codeplex repo: https://gw2apicpp.codeplex.com
The API-part is currently not rly managed since I don’t have much time atm.
I would suggest you to start with the official APIs first before implementing the tp-API because for that you need session keys from a login

Killer Rhino.6794:

Wolf, my first suggestion is to stop thinking about your goal in terms of any specific language.

Take a step back and look through the API’s wiki page: http://wiki.guildwars2.com/wiki/API

The main API wiki page lists the services (also referred to as “endpoints”) that can be contacted for specific information. It is a good idea to read through each service’s description to better understand what data you can query Also, this is your chance to consider what specific information you’d be most interested in pulling down first when you eventually start coding.

It’s tempting, as a first-time explorer, to say, “I’m going to get ALL the THINGS!” But, if this really is your first foray, having a simple, concrete goal will keep you focused and less prone to failure.

Next, look through a couple of endpoints on the wiki. It might not be obvious, but all of the services return their data in the same lightweight data-interchange format, called JSON (short for “Javascript Object Notation”).

Portable data formats have come a long way in the last twenty years, and JSON is one of the simplest among them. It only is capable of encoding 6 types of values:

  • string
  • number
  • array
    • ordered collection of other value types
  • boolean (yes/no)
  • object
    • a key/value pair;
    • ‘key’ must be a string;
    • ‘value’ must be one of the 6 other valid types;
    • don’t confuse these with C++-type objects
  • and null
    • aka, a value defined as having “no value”

The entirety of a single JSON response can only be structured in one of two ways: as an array of values (referred to as an ordered set), or an object value (referred to as an unordered set). You will never see a valid JSON response that doesn’t begin with one of these two structures.

  • In the case of the array (ordered set), the JSON response starts and ends with square brackets (“[ … ]”).
  • In the case of an object value (unordered set), the JSON response starts and ends with curly braces (“{ … }”).

JSON has no concept of indentation, or other textual formatting attributes. However, it is often helpful to “pretty-print” your responses; paste your JSON text into JSONLint to see it human readable.

Now, for an example: let’s take a look at the /files endpoint.

This service returns an unordered set of other objects. When we pluck out the first object in the set, we see:


    "map_complete": {
        "file_id": 528724,
        "signature": "5A4E663071250EC72668C09E3C082E595A380BF7"
    },

Turns out, this first object was, itself, an unordered set of other objects.

If we read the documentation for the /files endpoint, we find out that the data returned is meant to be used in conjunction with the render service endpoint. A lot of GW2 services work like this; it’s too much of burden to return every single detail about something, so instead, you’ll get a lot of reference IDs to use as input to other services.

In all, once you’ve comprehended the extent of what information is available from GW2’s APIs, understand the format the data is being transmitted in, and grasp the manner in which services work in tandem, you’re finally ready to write code that does the actual work.

Like XML in it’s heyday, there is no shortage of languages with frameworks which help you work with JSON. I suggest Python, Ruby, or JavaScript (obviously) to start; these languages enable you to query GW2’s APIs in just few lines of code.

To see examples of community-built GW2 frameworks (in various language), check out the list of API wrappers on the wiki.

Wolf Fivousix.4319:

Thank you for your fast and thoroughly response. I spent a lot of time in the API wiki page and thanks to your explanation I realized how to use the render service to provide me the image for a specific item using the item and item_details JSON files, like: https://render.guildwars2.com/file/6F596AB3743DC27A1C7329BF4450A37654914607/339955.png

I believe I could try to do something as simple as that to start with, a program that shows me the picture of an item, or just it’s name.

My problem now is how to make my own program talk with GW2API servers. I had been looking into Heimdall’s code and that’s way beyond me so I got lost, but I don’t think I need to get that far for just getting a picture or an ID from the server. I know some Python but I rather use C++ to get things done, so I can improve my skills in the way.

Thank you.

smiley.1438:

My problem now is how to make my own program talk with GW2API servers.

So before you start anything with the API stuff, you’ll neeed to figure out how to make a common HTTP request - either self written or through a library like cURL.

Heimdall.4510:

If you’re coding on a windows machine there is either the winhttp Lib (more useful for server implementations) or the wininet Lib which i would recommend you.
Another Option would simply be to connect a Socket with the server (Port 443) and Set up the http headers by yourself. If you do so make sure you didn’t forget the ssl handshake

Wolf Fivousix.4319:

Thank you guys, I’ll be studying that and as soon as I get something working with it I’ll come back!

Yes, Heimdall, I’m conding in a windows machine, using Dev C++ by Bloodshed.

Killer Rhino.6794:

Wolf,

This should help you get started: Client/Server Programming with TCP/IP. It’s quite descriptive, with specific client-side C++ examples for Windows using winsock.

Wolf Fivousix.4319:

Thank you very much Killer, I’m still working on the WinINet but I’ll definitely check your link, seems amazing!

Wolf Fivousix.4319:

Ok, I got both WinINet working and Winsock kind of working. I’ll be following with the one that woks while studying more about winsock.

Now I can make requests to the server and I get the text answer. I’ll play a little bit with what I have and try to filter an item name or something.

I’ll be back as soon as I get something more elaborated.

Wolf Fivousix.4319:

Have been playing with it a while and my program that requests and filters the answer for giving me a name of a specific item is working beautifully. Attached if anyone want’s to see how it ended up.


// Created by Wolf Fivousix – 2013.
// Special thanks to Heimdal.4510, Killer Rhino.6794 and smiley.1438
// Don`t forget to put -lwininet in the Parameter > Linker for the Windows library.
#include<iostream>
#include<wininet.h>
using namespace std;
int Request();
char Website4096=“https://api.guildwars2.com/v1/item_details.json?item_id=”;

int main (void)
{
cout<<“20523 for a Dye item.\n”;
cout<< "Item ID: ";
char itemid6;
gets (itemid);
cout<<endl;
strncat (Website, itemid, 6);
Request();
cout<< endl << “———————————————————————————————————————-\n”;
system(“PAUSE”);
}

int Request()
{
HINTERNET connect = InternetOpen(“MyBrowser”,INTERNET_OPEN_TYPE_PRECONFIG,NULL, NULL, 0);
if(!connect){
cout<<“Connection Failed or Syntax error”;
return 0;
}
HINTERNET OpenAddress = InternetOpenUrl(connect,Website, NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE|INTERNET_FLAG_KEEP_CONNECTION, 0);
if ( !OpenAddress )
{
DWORD ErrorNum = GetLastError();
cout<<"Failed to open URL \nError No: "<<ErrorNum;
InternetCloseHandle(connect);
return 0;
}
char DataReceived4096;
DWORD NumberOfBytesRead = 0;
while(InternetReadFile(OpenAddress, DataReceived, 4096, &NumberOfBytesRead) && NumberOfBytesRead )
{
int i;
for (i=0; i <4096; i++)
{
if (DataReceived[i] == ‘n’)
{
if (DataReceived[i+1] == ‘a’)
{
if (DataReceived[i+2] == ‘m’)
{
if (DataReceived[i+3] == ‘e’)
{
cout << "Name of the Item: “;
i = i+7; // Skipping to the name of the item.
break;
}
}
}
}
}
while (DataReceived[i] != ’”’ )
{
cout << DataReceived[i];
i++;
}
}
InternetCloseHandle(OpenAddress);
InternetCloseHandle(connect);
}

Now I moved a little bit further and tried to show the names of all item going from 1 to 99999, so I could “mine” the server for the names and their ID’s, BUT my program keeps closing after some requests (arond 66). So I assume the server would be dropping my connection for too many requests?

Does anyone know if there’s a limit for the number of requests that can be done for the server?

Going to the next step I would like to retrieve the image of an item. I know how to construct the link for it and with some modifications on my code I can get it to request that image, but how can I display a .PNG image in my program? I assume I can’t do that using the command prompt window, so what should I do?

Anen.1742:

for (i=0; i <4096; i++)
{if (DataReceived[i] == ‘n’)
{
if (DataReceived[i+1] == ‘a’)
{
if (DataReceived[i+2] == ‘m’)
{
if (DataReceived[i+3] == ‘e’)
{
cout << "Name of the Item: “;
i = i+7; // Skipping to the name of the item.
break;

You may want to have a JSON parser instead of this ugly code.

Wolf Fivousix.4319:

Thank you Anen, I’ll be looking at JSON parser to see what I find, any recommendation of one I could use with C++ ?

I added 1s delay to the multiple request code but it still closing at the same spot, any clue about what it could be?

Heimdall.4510:

You could use the one I created for my API project there’s one written in C++ and one in pure C. If you care about Efficiency you might be more interested in the C Version but it’s also the more trickier one.

Wolf Fivousix.4319:

Heimdall, I tried to figure out your JSON parser, but that’s too advanced for me, can’t find a way to integrate that in my program =( . As I learn more about C++ and programming I will go back to it.

I solved the problem in my program, so I could dump the 49.102 current item list in a txt file so I can start playing around with different kind of itens.

Any idea of what I could do next? I saw a topic about the Trading Post but I want play a round a little more before going to that, since I know I’ll need a session key and that will probably get complicated.

I was thinking about creating a non MS-DOS window to show information (maybe I can play with some events info). I know some BGI graphics and will be trying to use it to display images taken from the server. Anyone know how I can make my program download a png or jpg in the item ID link, like this one: https://render.guildwars2.com/file/02EFB1C5E11B2FF4B4AC25A84E2302D244C82AA3/66958.png ?

Thank you.

Heimdall.4510:

If you access the link via the wininet Library for example you get the img data as response. This means you could either save the Data in a file or use it directly from your memory to display it.

Wolf Fivousix.4319:

Heimdall, I have been struggling to make the download of the image. By my researches I can use the WinInet function InternetReadFile to download the file. Do you have any direction that I could use?

sorenrye.7238:

Anyone know how I can make my program download a png or jpg in the item ID link, like this one: https://render.guildwars2.com/file/02EFB1C5E11B2FF4B4AC25A84E2302D244C82AA3/66958.png ?

I have been struggling to make the download of the image. By my researches I can use the WinInet function InternetReadFile to download the file. Do you have any direction that I could use?

Here is a small example of how you can use wininet to download a file:

http://stackoverflow.com/questions/6960084/downloading-binary-files-with-wininet

Open the link and search the page for this text “program that fetches”. Below the text you will see a small example program that shows you how to use wininet to download a file.

Start visual studio, create a new project ’Win32 Console Application". Copy the code example from stackoverflow into your new project and build the project.

Currently the program downloads stackoverflows main page and writes it to the file output.txt. You should run the compiled program to test that this is the case.

If you change this line in the program from:

  const ::WCHAR URL[] = L"http://stackoverflow.com/";

to

  const ::WCHAR URL[] = L"https://render.guildwars2.com/file/02EFB1C5E11B2FF4B4AC25A84E2302D244C82AA3/66958.png";

Then the program will download the image to the file output.txt. Rename the file to output.png and view it in your browser to verify that this is the case. Note that each line above (theWCHAR URL lines) are a single lines – your browser may wrap the lines.

I tested the example on an old PC that had visual studio 2010 installed, and it worked fine.

If you are new at programming, you should learn by example. Stackoverflow has a lot of other examples that you can learn from.

I wish you luck in your endeavors.

PS. You may want to change the inline filenames to command line arguments. I don’t know in which context you want to use this, but for testing purposes the example is ok. I am not associated with stackoverflow in any way, and I hope I didn’t break any forum rules by refering to stackoverflow.

PPS: You may want to take a look at the microsoft project: C++ REST SDK (codename “Casablanca”). The framework is designed to be easier to use than wininet. Especially wrt async transfers/jobs.

Heimdall.4510:

This is just a little example using the wininet-lib to save some binary data into a file.
There’s no need to save the data within a file if you save it in a buffer in your memory from there you can access it directly.


open = InternetOpen(TEXT(APP_AGENT), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 1);
request = InternetOpenUrl(open, convertToWideChar(loadURLFromDB()), NULL, NULL, 
INTERNET_FLAG_SECURE, 1);
ofstream out("image.png", ios::out|ios::binary);
char buffer;
DWORD size;
while(InternetReadFile(request, &buffer, 1, &size)){
                                 if(size != 1)
                                 break;
                                 out.write((char*)&buffer, sizeof(char));
}
out.close();
InternetCloseHandle(request);
InternetCloseHandle(open);

Wolf Fivousix.4319:

Thank you Sorenrye and Heimdall, I managed to make both codes work, but I still can’t see how I’d got into this stuff even playing around with the functions. I’m sure that’s a lot I still need to learn to dig through this codes and really understand them.

About the inline functions, I don’t see where I use them, but I suppose they’re inside the WinInet code, which is something I don’t fully understand but I’m going through until I have more knowledge to fix them.

C++ REST SDK (codename “Casablanca”) seems really nice, but for the sake of continuity I’ll keep using WinINet for this API, thank you for the tip though, I’ll study it further in the road, once I understand more about all of this.

I’ll be using the Heimdall code as a base since I can understand it more than the exemple in stackoverflow. I want to play around a little bit with this code before going further, hopefully I’ll manage to learn more once I break and fix it.

As soon as I get something concrete I’ll come back to let you know.

Thank you very much.

sorenrye.7238:

About the inline functions, I don’t see where I use them, but I suppose they’re inside the WinInet code, which is something I don’t fully understand but I’m going through until I have more knowledge to fix them.

0) Inside the WinInet code.
The WinInet code is build on sockets. Goole ‘socket programming in c’. Here is the first search result, a small introduction to socket programming (it can’t get smaller than that):

http://www.codeproject.com/Articles/586000/Networking-and-Socket-programming-tutorial-in-C

If you want to understand the core components of network programming, you should look at socket programing. The example link above is for unix socket programming. You may want to refine your google search to find out the small differences to make it work on windows or to find examples for windows. When you have learned the absolute basics, you will want to look into blocking/non-blocking I/O and/or asynchronous I/O (ioctl handlers and/or multi-theading).

I am not sure what you mean by ‘the inline functions … inside the wininet code’. But see below ‘Documentation’.

1) Documentation
Use msdn to view documentation about the microsoft functions. Google is your friend. Usually I just google the function, fx ‘google internetreadfile’. Then I look for a link to msdn.com. The first link if you google is ‘InternetReadFile function (Windows) – MSDN – Microsoft’. Read the page. And if you have the time, spend some time browsing msdn. When you have read about the function then search for examples using the function. Always use google to (or books) to see documentation for the individual functions. To learn general windows programing I recommend the book ‘Programming Windows, 5th Edition, by Charles Petzold’. If you don’t have it already, get the C bible ‘Kernighan and Ritchie: The C Programming Language’. Also get the C++ bible ‘The C++ Programming Language by Bjarne Stroustrup’. Bjarne has written some additional books, fx books that describe C++11. I don’t think MSVC supports C++11 fully yet – if you want to play with C++11 you should install a unix like operating systsem (using a vm if you like) and take a look at the CLANG compiler and play around with it. The good thing about CLANG (and you should use the VIM editor) is that you can get additional modules for it that enables you to beautify your code, test for memory leaks, stack/buffer under/overflows, race conditions etc. So CLANG is really IMO top of the pops with regards to C++ compilers atm.

2) Learn by example
You should try to develop some examples from scratch by yourself. This is a very good learning process. Also, if you can find a book or links that contains examples or exercises and solutions – do that.

3) Divide and conquer / Keep it simple
You should try to make your projects as small as possible. Each project should be about something that you will eventually use in y our bigger projects. Some examples could be:
- a program that combines 2 images (image files/buffers) into another image (image file/buffer).
- a program that reads a file from the internet (examples are already mentioned above)
- a program that plays with JSON data.
- etc

4) Encapsulate your code to make it robust and re-usable
When you divide and conquer and keep things simple, it enables you to more easily encapsulate your code. And eventually it will make it easy to reuse your small projects in your bigger projects.

sorenrye.7238:

There’s no need to save the data within a file if you save it in a buffer in your memory from there you can access it directly.

The point was to show him how to use InternetReadFile(). The example has some bad code (fx it doesn’t break the loop if a read error occurs, main() doesn’t return an interger, it writes the ouput to a file, etc and so on). But it shows how to use InternetReadFile().



InternetReadFile(request, &buffer, 1, &size)

When reading or writing data from/to anywhere, you should never read or write 1 byte at a time. Always read and write as many bytes as possible. Sorry for being pedantic. But performance can really suffer if you don’t use this rule of thumb. I assume you read 1 byte at a time to make the example simple and easier to read.

Heimdall.4510:

sorenrye.7238

I don’t think MSVC supports C++11 fully yet

In fact MSVC was the first compiler featuring full C++11 Support it has even some of the fixes coming with C++14.
With my example code you’re absolutely right this snipped is not meant to be used like I presented it. I took it out of an application I build for personal purpose. This section and some more are handled by an observer which handles all trouble occurances. Just the bitwise read operation is really intended because the benefit of gained performance if you use larger buffers is negligible here (especially in cobination with some inline asm I dropped off here).

sorenrye.7238:

sorenrye.7238

I don’t think MSVC supports C++11 fully yet

In fact MSVC was the first compiler featuring full C++11 Support it has even some of the fixes coming with C++14.

First let me say, that you may be right. I am not a Visual Studio C++ guru.

I think you are mistaken though. Earlier, when development of the C++11 features was ongoing, it was the leading compiler in that regard. Check fx:

http://cpprocks.com/c11-compiler-support-shootout-visual-studio-gcc-clang-intel/

At the moment it has already implemented all C++14 features:

http://clang.llvm.org/cxx_status.html
http://www.phoronix.com/scan.php?page=news_item&px=MTM1NjM
http://en.wikipedia.org/wiki/Clang

If I am in the wrong, please let me know. But the point I was trying to make, is that CLANG is the leading edge when it comes to support of the new C++xx standards.

Another nice feature, that I forgot to mention, is that intel developed a module that converts old C++ code to C++11 code. Very neat. And if the programmers of the old C++ code have been ‘slacking’ significant performance increases may be achieved by using this conversion tool.

Unfortunately CLANG is not mature on the Windows platform yet. Hence the hint to check it out on a unix like OS.

sorenrye.7238:

To Wolf Fivousix.4319:

If u are new to C++ and want an easy time working with the GW2 json based service, you really should look more at the REST API. Check this:

http://msdn.microsoft.com/en-us/library/jj950082.aspx

Isn’t that easy and simple?

Killer Rhino.6794:

To Wolf Fivousix.4319:

If u are new to C++ and want an easy time working with the GW2 json based service, you really should look more at the REST API. Check this:

http://msdn.microsoft.com/en-us/library/jj950082.aspx

Here is the MSDN Blog post about Casablanca from back in February, which, I feel, could help provide some context for less experienced coders.

Wolf Fivousix.4319:

I spent some time working with http://msdn.microsoft.com/en-us/library/windows/desktop/aa385473%28v=vs.85%29.aspx and http://www.cplusplus.com/doc/tutorial/files/ so now I understand a little bit better how things are working, although the 1 byte read/write still confusing I shall leave like that since they’re small images and I’m not really concerned about performance at this point.

Thank you for the directions and the references, they will be valuable sources of knowledge. Casablanca looks nice to work with, but I plan using it to remake the program once I finish it, so I can clearly see the differences between them.

This is the final version of the program downloading one image and saving it in my computer for further use.


// Created by Wolf Fivousix – 2013.
// Special thanks to sorenrye.7238 and Heimdall.4510.
// This proram will go to GW2render and get the image saving it in my computer.
// Don`t forget to put -lwininet in the Parameter > Linker for the Windows library.
#include<iostream>
#include<wininet.h>
#include<fstream>
using namespace std;
int Request(char IMAGE_WEBSITE[]);

int main (void)
{
// Link of the image to be downloaded.
char render_image_link4096=“https://render.guildwars2.com/file/02EFB1C5E11B2FF4B4AC25A84E2302D244C82AA3/66958.png”;
Request(render_image_link);
// Open the downloaded file.
system(“Image.png”);
}

int Request(char IMAGE_WEBSITE[])
{
// Initializes an application’s use of the WinINet functions. (Creates the handleE for the function to work.)
HINTERNET link_open = InternetOpen(IMAGE_WEBSITE,INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
// Checks if InternetOpen() got a correct handle.
if(!link_open)
{
cout<<“InternetOpen() problem.”;
}
// Opens a resource specified by a complete FTP or HTTP URL.
HINTERNET open_url = InternetOpenUrl(link_open,IMAGE_WEBSITE, NULL, 0, INTERNET_FLAG_SECURE, 0);
// Checks for errors of InternetOpenUrl().
if(!open_url)
{
DWORD ErrorNum = GetLastError();
cout<<"Failed to open URL \nError No: “<<ErrorNum;
InternetCloseHandle(link_open);
}
// Open the file for output through binary.
ofstream IMAGE (”Image.png", ios::out|ios::binary);
char Data_Received;
DWORD NumberOfBytesRead;
// Write on the file.
while(InternetReadFile(open_url, &Data_Received, 1, &NumberOfBytesRead))
{
if (NumberOfBytesRead != 1)
break;
IMAGE.write((char*)&Data_Received, sizeof(char));
}
// Closes the file.
IMAGE.close();
// Closes the handle.
InternetCloseHandle(open_url);
InternetCloseHandle(link_open);
}

Now I’ll play around a little bit and learn how to display images using Borland Graphic Interface before coming back to make the API interact with the Black Lion Trading Company. I saw an extensive post about making API work with the BLTC and I’ve got a lot of reading and testing to go through before asking another question.

I would like to thank you once more for the invaluable help offered.
See you all in a couple of weeks (hopefully with a screen shot of something more visual).

sorenrye.7238:

I tried to create a bare minimum simple example, for people that want use the GW2 Api and learn C++ – both with regards to readability and ease of use. The example requires Windows XP and Visual Studio.

For json parsing I looked at rapidjson, BOOST and REST (casablanca) and decided to use rapidjson (most portable, easiest to install and supports unicode fully) (REST requires Windows 7 and BOOST doesn’t fully support unicode).

   http://pastebin.com/54YmUN0J

Have fun.

sorenrye.7238:

Was so lazy I forgot to add newlines and spacing in the output – sorry. Here is the example again, with some more comments.