The online racing simulator
InSim and C++
(8 posts, started )
InSim and C++
Im pretty new to C++ (but am quite experienced in Java/C#) and wanted to see if I could manage to get a working InSim connection. Nothing special yet, just a link. Can someone give me some hint where I could start off, eg. Cpp-Sockets or is there some IS-Lib for Cpp yet? (Didn't find one in here...)
Stupid question, but, why don't you use C# instead? Afaik, we even have libraries for that...
E: Or is your intention actually to learn C++?
Quote from Tanuva :Cpp-Sockets or is there some IS-Lib for Cpp yet? (Didn't find one in here...)

luaLFS is open source and has a lot of components that you'll want - you could rip it straight out and use it in your own project - it should also work cross platform. The downside is that it's C, not C++ which means that it's more objective-c (i.e. no objects in the C++ sense).

It is also little bit more complex than you might want for a beginner. I was planning on ripping it out and maintaining it separately and providing a link for the latest versions etc. If thats something you're interested in let me know.

Networking is probably not something you want to dig straight into if you're using C (or any of its derivatives) for the first time, until you've got to grips with pointers specifically.
Quote from AndroidXP :Stupid question, but, why don't you use C# instead? Afaik, we even have libraries for that...
E: Or is your intention actually to learn C++?

You got it - I already have a working Experiment in C# (thanks to sdether for his great lib!), but since I'm using Linux now and would like to have a Qt4-GUI, C++ is the better choice. And I really need to learn cpp of course! (Not that I dont know the Mono project, but that isn't what I want.)

Quote from the_angry_angel :luaLFS is open source and has a lot of components that you'll want - you could rip it straight out and use it in your own project - it should also work cross platform. The downside is that it's C, not C++ which means that it's more objective-c (i.e. no objects in the C++ sense).

It is also little bit more complex than you might want for a beginner. I was planning on ripping it out and maintaining it separately and providing a link for the latest versions etc. If thats something you're interested in let me know.

Networking is probably not something you want to dig straight into if you're using C (or any of its derivatives) for the first time, until you've got to grips with pointers specifically.

So I hereby "let you know". That would be a good point to start off from, gotta take a look at your code when this cleaned version is finished. Maybe I should play around a bit with lua until then...
#5 - Vain
In LFSpitboard I work with C++ in conjunction with SDLnet. You might already know SDLnet if you come from a unix-background.
But generally it's a snap. Some basic code from LFSpitboard:

IS_TINY header;
SDLNet_TCP_Recv(tcpsock,&header,4);
switch(header.Type)
{
case ISP_TINY:
switch(header.SubT)
{
case TINY_NONE: // A connection-keep-alive packet, respond with a IS_TINY
IS_TINY tmpTINY = { 4, ISP_TINY, 0, TINY_NONE };
SDLNet_TCP_Send(tcpsock,&tmpTINY, sizeof(tmpTINY));
break;
}
break;
case ISP_LAP:
IS_LAP tmpLAP;
SDLNet_TCP_Recv(tcpsock,((char*)&tmpLAP)+4,16); // receive the rest of the IS_LAP, which is 20 bytes long, but we already have 4 of them in the header
tmpLAP.PLID = header.SubT; // Complete the IS_LAP with data from the header
cout << (unsigned int)(tmpLAP.PLID) << " crossed the finish line! << endl;
break;
case default:
char* pBuffer = new char[header.Size];
SDLNet_TCP_Recv(tcpsock,pBuffer,header.Size-4);
delete pBuffer; // discard unknown packets
break;
}

// To-Do: Remove typos, tell everyone who doesn't like my code to STFU! :)

I'm aware that I could also write all packets into a buffer, store the address of the first byte and cast the pointer to *IS_WHATEVER so I don't have to copy data from the header to packets that store something important in the fourth byte, but I do it this way to stay type-save.

Vain
Unless I'm being a fool, theres no provision for multiple or split packets per recv call Vain?
As I stated earlier, here's a "cleaned" up version of libInSim, with a brief example of how it works; http://svn.theangryangel.co.uk/LFS/libInSim/tags/

It doesn't demonstrate how to use the hooks properly though. The general gist is that you create a number of functions which are passed into a struct, which is registered against the library. The library then fires each of the functions as necessary.

There are 5 "events" (or functions);
create - typically you'd use this to allocate any memory into the "ctx" - which is a unique pointer for your set of hooks
connection - occurs on connection - you might want to send an IS_TINY asking for all the players here for isntance
receive - triggered whenever a packet is received - you'd use this to distribute to your other functions
disconnection - connection tracking clear up and other stuff probably
close - deallocating any memory

For instance a hook could be as follows;
void rx_create(struct insim_t *I, void **ctx)
{
*ctx = malloc(sizeof(struct rx_info_t));
memset(*ctx, 0, sizeof(struct rx_info_t));

struct rx_info_t *t = *ctx;
t->version = 0.1;

t->name = malloc(strlen(rx_FULL_NAME) + 1);
memset(t->name, 0, strlen(rx_FULL_NAME) + 1);
memcpy(t->name, rx_FULL_NAME, strlen(rx_FULL_NAME));

printf("%s v%.1f\n", t->name, t->version);
return;
}

void rx_connected(struct insim_t *I, void *ctx)
{
struct rx_info_t *i = ctx;
/*
struct IS_MST t;
memset(&t, 0, sizeof(struct IS_MST));
t.size = sizeof(struct IS_MST);
t.type = ISP_MST;
strncpy(t.Msg, rx_FULL_NAME " started", strlen(rx_FULL_NAME " started"));

insim_send(I, (const char *)&t, sizeof(t));
*/
struct IS_TINY p;
memset(&p, 0, sizeof(struct IS_TINY));
p.size = sizeof(struct IS_TINY);
p.type = ISP_TINY;
p.reqI = 1;
p.subT = TINY_NCN;

insim_send(I, (const char *)&p, sizeof(p));

p.subT = TINY_NPL;
insim_send(I, (const char *)&p, sizeof(p));

return;
}

void rx_recv(struct insim_t *I, void *ctx, void *data, unsigned int size)
{
char *p = data;
unsigned char type = *(p + 1);

switch(type)
{
case ISP_III:
rx_III(I, ctx, (struct IS_III *)p);
break;
case ISP_NCN:
rx_NCN(I, ctx, (struct IS_NCN *)p);
break;
case ISP_CNL:
rx_CNL(I, ctx, (struct IS_CNL *)p);
break;
case ISP_NPL:
rx_NPL(I, ctx, (struct IS_CNL *)p);
break;
case ISP_PLL:
rx_PLL(I, ctx, (struct IS_CNL *)p);
break;
case ISP_RES:
rx_RES(I, ctx, (struct IS_RES *)p);
break;
default:
printf("Unknown packet %d\n", type);
break;
}
return;
}

void rx_disconnected(struct insim_t *I, void *ctx)
{
struct rx_info_t *t = ctx;
list_destroy(&(t->connections));
return;
}

void rx_close(struct insim_t *I, void *ctx)
{
struct rx_info_t *t = ctx;
if (t->name != NULL)
free(t->name);

if (t != NULL)
free(t);

ctx = NULL;
printf("Memory freed\n");
return;
}

Then in main.c you'd create a struct, populating it with all the function pointers
struct hooks_t hook_rx;
memset(&hook_rx, 0, sizeof(struct hooks_t));
strcpy(hook_rx.name, rx_NAME);
hook_rx.fp_create = rx_create;
hook_rx.fp_connected = rx_connected;
hook_rx.fp_recv = rx_recv;
hook_rx.fp_disconnected = rx_disconnected;
hook_rx.fp_close = rx_close;

And add it into the hooks linked list;
list_add(&(I->hooks), (void *)&hook_rx)

Granted that's not perfect and will give you some "interesting" compile warnings, but it'll work in most circumstances.

I told you it was "complex"
You'll notice that the create functions use a double indirection for the ctx pointer - this is so that you can allocate the memory correctly and might be the biggest thing to get your head around
Quote from Tanuva :You got it - I already have a working Experiment in C# (thanks to sdether for his great lib!), but since I'm using Linux now and would like to have a Qt4-GUI, C++ is the better choice. And I really need to learn cpp of course! (Not that I dont know the Mono project, but that isn't what I want.)
....

well, I have attached the source code of the Insim Gateway (Insim v3 to v4) into the Insim Gateway thread too. It is not too complex at the moment, so it might be a good starting point. Also it shows you both TCP and UDP sockets.
And maybe (hopefully) you will be the person who continues this project. I cannot, because I need to continue the TV Director project.

kind regards
Soeren

InSim and C++
(8 posts, started )
FGED GREDG RDFGDR GSFDG