Torrent API for Web-based game installer.

Started by
12 comments, last by ApochPiQ 12 years, 9 months ago
Hello :).

I am developing a video game (screenshot), and have developed a web-based installer for it:
installerss.th.jpg

It currently uses libCURL to to download the game-data from HTTP/FTP sources. Because of the demand on servers, I am looking into adding p2p torrent support. Does anyone know of a good, bittorrent implementation? Preferably written in C and cross-platform with webseed support. A library that implements everything would be great if someone knows of one, but if none exist does anyone know a good torrent-protocol tutorial?

Thanks beforehand :).
Advertisement
libtorrent: http://www.rasterbar.com/products/libtorrent/ C++ though, BSD.
MartinsM: Thanks! I don't really like boost, but then again libtorrent has a nice license :).
Just make sure to have it disabled by default and be completely optional.

With increased data caps you can break user's data cap and incur extra costs.

Bit torrent also has bad reputation and large number of connections can trigger various alerts.

I won't say this is the biggest problem, but so far Blizzard is the only one I can recall using BT and they might get privileged treatment.

Because of the demand on servers[/quote]

What kind of servers and how much traffic? How do AppEngine or S3 prices compare to that?
Antheus: Thanks for your reply. There has been a lot of thought put into this, and BitTorrent is the best option for Galactic Vice :). I am also not too concerned about the potential problems BitTorrent may present, as users would be able to disable if if necessary.

Does anyone know of an alternative to libtorrent, one that doesn't boost?
Out of sheer curiosity, why don't you like Boost? It's basically a waiting-room for the next C++ standard library wink.gif

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


Out of sheer curiosity, why don't you like Boost? It's basically a waiting-room for the next C++ standard library wink.gif

Well, I don't want to start a debate or anything, but I am a die-hard Scheme/C fan (that should say it all :D). IMHO C++ (and especially Boost), implement very bad programming techniques. Yes, programming in a low-level language is hard and meticulous for those used to high-level programming, but it uses a completely different coding mindset/technique that once mastered is far easier than the high-level programming. It allows for cross-platform, screaming-fast, and minimalistic/non-bloated programs to be written with elegant simplism.

On the other hand, C++ often leads to code like this:
#include <stdio.h>

enum { SCALElog=15, SCALE=1<<SCALElog, mSCALE=SCALE-1, hSCALE=SCALE/2 };

template< int DECODE >
struct Rangecoder {
enum { NUM=4, sTOP=0x01000000U, Thres=0xFF000000U };

typedef unsigned long long int qword;
unsigned range, code, FFNum, Cache; qword lowc; FILE* f;

void Init( FILE* _f ) {
f = _f; range = 0xFFFFFFFF; lowc = 0; FFNum = 0; Cache = 0;
if( DECODE==1 ) for( unsigned _=0; _<NUM+1; _++ ) (code<<=8)+=getc(f);
}

void Quit( void ) { if( DECODE==0 ) for( unsigned _=0; _<NUM+1; _++ ) ShiftLow(); }

unsigned Process( unsigned freq, unsigned bit ) {
unsigned rnew = (qword(range)*(freq<<(32-SCALElog)))>>32;
if( DECODE ) bit = (code>=rnew);
bit ? range-=rnew, (DECODE ? code-=rnew : lowc+=rnew) : range=rnew;
while( range<sTOP ) range<<=8, (DECODE ? (code<<=8)+=getc(f) : ShiftLow());
return bit;
}

unsigned ShiftLow( void ) {
unsigned Carry = unsigned(lowc>>32), low = unsigned(lowc);
if( low<Thres || Carry ) {
putc( Cache+Carry, f );
for (;FFNum != 0;FFNum--) putc( Carry-1, f );
Cache = low>>24;
} else FFNum++;
return lowc = (low<<8);
}
};

struct Predictor {
short cxt;
short p[256-1];

Predictor() { for( unsigned i=0; i<sizeof(p)/sizeof(p[0]); i++ ) p=hSCALE; byte(); }
int P() const { return p[cxt-1]; }
unsigned byte( void ) { unsigned c=cxt; cxt=1; return c; }

void update( unsigned y ) {
if( y ) p[cxt-1] -= ( p[cxt-1] >> 5), cxt+=cxt+1;
else p[cxt-1] += ((SCALE - p[cxt-1]) >> 5), cxt+=cxt+0;
}
};

template< class Predictor, class Rangecoder >
void proc( Predictor& p, Rangecoder& rc, unsigned y=0 ) { p.update( rc.Process( p.P(), y ) ); }

unsigned flen( FILE* f ) {
fseek( f, 0, SEEK_END );
unsigned len = ftell(f);
fseek( f, 0, SEEK_SET );
return len;
}

int main( int argc, char** argv ) {
unsigned i,c,f_len = 0;
if( argc<4 ) return 1;
FILE* f = fopen( argv[2], "rb" ); if( f==0 ) return 2;
FILE* g = fopen( argv[3], "wb" ); if( g==0 ) return 3;
Predictor p;
if( argv[1][0]=='c' ) {
f_len = flen( f );
fwrite( &f_len, 1,4, g );
Rangecoder<0> rc; rc.Init(g);
for( i=0; i<f_len; i++ ) {
c = getc(f); p.byte();
proc(p,rc,c&0x80); proc(p,rc,c&0x40); proc(p,rc,c&0x20); proc(p,rc,c&0x10);
proc(p,rc,c&0x08); proc(p,rc,c&0x04); proc(p,rc,c&0x02); proc(p,rc,c&0x01);
} rc.Quit();
} else {
fread( &f_len, 1,4, f );
Rangecoder<1> rc; rc.Init(f);
for( i=0; i<f_len; i++ ) {
proc(p,rc); proc(p,rc); proc(p,rc); proc(p,rc); proc(p,rc); proc(p,rc); proc(p,rc); proc(p,rc);
putc( p.byte(), g );
}
}
fclose( f );
fclose( g );
return 0;
}


Yes, that's a range coder. Yes, It's horribly slow. And yes, I think I just went blind xD.


Back to the original topic:
Does anyone know of an alternative to libtorrent, one that doesn't boost?
Well...

I think that's an absolutely worthless argument with so many holes it makes a block of Swiss cheese jealous; but I won't hijack your thread into a debate about boost unless you really want to.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


Well...

I think that's an absolutely worthless argument with so many holes it makes a block of Swiss cheese jealous; but I won't hijack your thread into a debate about boost unless you really want to.

Please, lets not. Lets continue this in a PM :).

Yes, that's a range coder. Yes, It's horribly slow. And yes, I think I just went blind xD.


The funniest thing is, that is C code, not C++. It's just wrapped into a class.

This topic is closed to new replies.

Advertisement