Online archive access

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Online archive access

Post by sudi »

I was bored last night and after i saw the the thread with the FileArchive from memory i thought well try something different.
So i wrote a little helper class that allows to grab files from a http server.

INFO: you will need the function from http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=39758 for this to work

Example:

Code: Select all

int main(void)
{
    irr::IrrlichtDevice* Device = irr::createDevice(irr::video::EDT_OPENGL);
    irr::io::IFileSystem* fs = Device->getFileSystem();

    SOnlineStorageAccess access;
    access.addOnlineArchive(fs, "localhost", 80, "Test.zip", 100000000);

    irr::gui::IGUIImage* img = Device->getGUIEnvironment()->addImage(irr::core::rect<irr::s32>(0,0,640,480));
    img->setImage(Device->getVideoDriver()->getTexture("hello.png"));
    img->setScaleImage(true);
    while (Device->run())
    {
        Device->getVideoDriver()->beginScene();
        Device->getGUIEnvironment()->drawAll();
        Device->getVideoDriver()->endScene();
    }
    return 0;
};

The AccessClass

Code: Select all

#include <enet/enet.h>
#include <irrlicht.h>
struct SOnlineStorageAccess
{
    SOnlineStorageAccess(void)
    {
        enet_initialize();
    }
    ~SOnlineStorageAccess(void)
    {
        enet_deinitialize();
    }
    bool sendDataToServer(const char* ip, const short& port, const char* varname, const char* var)
    {
        bool pError = false;

        ENetAddress address;
        enet_address_set_host(&address, ip);
        address.port = port;

        ENetSocket s = enet_socket_create(ENET_SOCKET_TYPE_STREAM);

        if(pError==false)
        {
            if(enet_socket_connect(s, &address) < 0)
            {
                printf("Couldn't connect\n");
                pError = true;
                return !pError;
            }
        }
        else
        {
            return !pError;
        }

        if (pError)
            printf("ERROR\n");

        char command[1000];
        sprintf(command, "POST /%s=%s\r\n\r\n", varname, var);
        ENetBuffer CommandBuffer;
        CommandBuffer.data = command;
        CommandBuffer.dataLength =  sizeof(command);
        enet_socket_send(s, 0, &CommandBuffer, 1);

        enet_socket_destroy(s);

        return !pError;
    }
    bool grabFileFromServer(const char* ip, const short& port, const char* filename, char* buffer, unsigned long& buffersize)
    {
        bool pError = false;

        ENetAddress address;
        enet_address_set_host(&address, ip);
        address.port = port;

        ENetSocket s = enet_socket_create(ENET_SOCKET_TYPE_STREAM);

        if(pError==false)
        {
            if(enet_socket_connect(s, &address) < 0)
            {
                printf("Couldn't connect\n");
                pError = true;
                return !pError;
            }
        }
        else
        {
            return !pError;
        }

        if (pError)
            printf("ERROR\n");

        char command[1000];
        sprintf(command, "GET /%s\r\n\r\n", filename);
        ENetBuffer CommandBuffer;
        CommandBuffer.data = command;
        CommandBuffer.dataLength =  sizeof(command);
        enet_socket_send(s, 0, &CommandBuffer, 1);


        ENetBuffer ReceiveBuffer;
        ReceiveBuffer.data = buffer;
        ReceiveBuffer.dataLength = buffersize;
        long index = 0;
        int tries = 5;
        while (index < buffersize)
        {
            ReceiveBuffer.data = &buffer[index];
            ReceiveBuffer.dataLength = buffersize-index;
            long d = enet_socket_receive(s, 0, &ReceiveBuffer, 1);
            if (d < 0)
            {
                pError = true;
                break;
            }
            index += d;
            if (d == 0)
            {
                tries--;
                if (tries <= 0)
                    break;
            }
        }

        buffersize = index;

        realloc(buffer, buffersize);

        printf("Received %i bytes\n", buffersize);

        enet_socket_destroy(s);

        return !pError;
    }

    irr::io::IReadFile* grabFileFromServer(irr::io::IFileSystem* filesystem, const char* ip, const short& port, const char* filename, const unsigned long& buffersize)
    {
        unsigned long size = buffersize;
        char* buffer = new char[size];
        if (!grabFileFromServer(ip, port, filename, buffer, size))
        {
            printf("Failed grabbing File\n");
            delete [] buffer;
            return 0;
        }
        irr::io::IReadFile* file = filesystem->createMemoryReadFile(buffer, size, filename, true);
        return file;
    }

    bool addOnlineArchive(irr::io::IFileSystem* filesystem, const char* ip, const short& port, const char* filename, const unsigned long& archivesize)
    {
        irr::io::IReadFile* file = grabFileFromServer(filesystem, ip, port, filename, archivesize);
        printf("Downloaded Archive is %i bytes long\n",file->getSize());
        bool added = false;
        if (file)
            added = filesystem->addFileArchive(file, true, false, false, "");
        if (file && !added)
            file->drop();
        return added;
    }
};
Last edited by sudi on Tue Aug 31, 2010 2:27 pm, edited 2 times in total.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

ahh cool. that can be used for in-game advertisement.
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

Virion wrote:ahh cool. that can be used for in-game advertisement.
nice idea didn't even think about that. actually thought about easy patching or serverlist downloads.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

...or some nasty online protection.

"A permanent internet connection is required to play the game." :)
Never take advice from someone who likes to give advice, so take my advice and don't take it.
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

Bate wrote:...or some nasty online protection.

"A permanent internet connection is required to play the game." :)
yeah possible as well. downloading all gamecontent everytime you wanna play.....and only after you logged in or something...to prevent copieng the game. or to protect game assets....but yeah that would really suck....

i think my next game will feature that...haha
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

Hehe, that's the Ubisoft way :)
Never take advice from someone who likes to give advice, so take my advice and don't take it.
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Post by REDDemon »

it is multithreaded or we have to do a particular code for waiting the server response? Or the code just freeze while waiting the response?
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

Its not multithreaded...it just freezes while waiting for the response. But multithreading it would be actually easy but would also introduce another dependencie here...so now u can choose you favorite threading lib here to make it work.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
freetimecoder
Posts: 226
Joined: Fri Aug 22, 2008 8:50 pm
Contact:

Post by freetimecoder »

This is great!
Not so much for the archive thing (which is great, too, of course) but because I plan to write a downloader with enet for a project and this comes just in time :D

One question: Is there a way to determine the filesize of the download before the file finished downloading? (e.g. for a progress display)

greetings
Sylence
Posts: 725
Joined: Sat Mar 03, 2007 9:01 pm
Location: Germany
Contact:

Post by Sylence »

You just send a HTTP GET request to the webserver and it will response with with something like

Code: Select all

HTTP/1.1
Content-Length: 12345
[TWO linebreaks]
[data]
So you just read the header and you know the length of the response stream.
Software documentation is like sex. If it's good you want more. If it's bad it's better than nothing.
freetimecoder
Posts: 226
Joined: Fri Aug 22, 2008 8:50 pm
Contact:

Post by freetimecoder »

Thanks :D
That works.

greetings
eye776
Posts: 94
Joined: Sun Dec 28, 2008 11:07 pm

Post by eye776 »

Go ahead Ubisoft make me PROUD! :D :D
Post Reply