IrrNet - Irrlicht Network Framework 0.36 (Now Windows/Linux)

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
Ico
Posts: 289
Joined: Tue Aug 22, 2006 11:35 pm

Post by Ico »

To be honest I haven't tried IrrNet yet but already used Enet a little bit some time ago. Here's what I did to send/receive my class objects (packets). Maybe it will help you some way.

It may sound a little bit "quick and dirty" but worked quite well and never had any problems with it. :)

I created a base class with an attribute "packettype" and a method "process" - or however you want to call them.

Now for each packet type (i.e. loginrequest, loginresponse, etc) I derivated a new class from this base class and set packettype to a unique value within its constructor.

To send a packet, I just sent the memory range where the object resided (with the correct length).
Once received I first casted the received data to the base class to read the "packettype" attribute. Once I got this, I casted the packet to its real class and called the "process" method. Done.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

sio2 wrote:

Code: Select all


static const SFrameRange NULLRANGE = {
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	0};
Use "static const SFrameRange NULLRANGE = {};" and the struct will be initialised to zeros. This is part of the language spec.
Whoa thanks for telling me this it will save me writing all those 0's next time hahaha.
monkeycracks wrote:It'd be really awesome if you added the capability to send a struct as a packet.
Look at Packets.CPP and Packets.h, the part that lets you send a vector3df. Just do exactly what I did but using your struct type instead. (Define the struct type somewhere in the Packets.h and you should be sweet.)

@Ico, That sounds pretty awesome, I think I get the jist of it. But I don't really understand how you can just send a "memory range" it sounds confusing and unstable to me. If you can write me an example I can test it and if it works good it may help me with improving irrNet somehow. You propose a very interesting bitstreaming concept... Thank you.
Ico
Posts: 289
Joined: Tue Aug 22, 2006 11:35 pm

Post by Ico »

Forgot to mention: The whole thing will stop working once you try to send classes containing pointers which should be quite logical. :)

Just some snippets - should be enough to figure it out. Don't have the full code here right now. The handle() functions can be excluded from the client using #IFDEFs if needed.

The "basic" packet:

Code: Select all

class Packet
{
public:
	unsigned int id;
	Packet();
	~Packet();
	bool handle(ENetHost*,ENetPeer*);
};

Packet::Packet() { this->id=-1; }
Packet::~Packet() {}

bool Packet::handle(ENetHost* host,ENetPeer* peer)
{
	return false;
}
A "log me in!" packet as an example:

Code: Select all

class LoginPacket : public Packet
{
private:
	wchar_t name[21];
	wchar_t pass[21];
	unsigned int version;
public:
	LoginPacket(const wchar_t *lname,const wchar_t *lpass);
	bool handle(ENetHost*,ENetPeer*);
};

LoginPacket::LoginPacket(const wchar_t *lname, const wchar_t *lpass)
{
	wcscpy_s(this->name,20,lname);
	wcscpy_s(this->pass,20,lpass);
	this->id=1;
	this->version=GAME_VERSION;
}

bool LoginPacket::handle(ENetHost* host,ENetPeer* peer)
{
// ...
}
This is the function I use to "send" packets to the server or all connected hosts (dependent on this executables current role):

Code: Select all

bool SendPacket(void *pPacket, size_t PacketSize, ENetHost *host, ENetPeer *peer=NULL, int channel=0)
{
	ENetPacket *packet=enet_packet_create(pPacket,PacketSize,ENET_PACKET_FLAG_RELIABLE);
	if(peer)
		enet_peer_send(peer,channel,packet);
	else
		enet_host_broadcast(host,channel,packet);
	enet_host_flush(host);
	return true;
}
When the client wants to login he sends a "loginpacket class" just by using...

Code: Select all

SendPacket(&LoginPacket("myname","sesame"),sizeof(LoginPacket),client,peer,0);
Both client and server use a "packet handler" to call the different handle() methods:

Code: Select all

bool HandlePackage(void *data,size_t len,ENetHost *host,ENetPeer *peer)
{
	switch(((Packet*)data)->id)
	{
#ifdef GAME_CLIENT
	case 0:
		return ((ErrorPacket*)data)->handle(host,peer);
//...
	default:
		wchar_t temp[256];
		enet_peer_disconnect_now(peer,0);
		swprintf_s(temp,255,L"%s sent unhandled packet %x!",peer->data,((Packet*)data)->id);
		con_error(temp);
#endif
#ifdef GAME_SERVER
	case 1:
		return ((LoginPacket*)data)->handle(host,peer);
// ...
	default:
		wchar_t temp[256];
		enet_peer_disconnect_now(peer,0);
		swprintf_s(temp,255,L"%s sent unhandled packet %u!",((Account*)peer->data)->Name,((Packet*)data)->id);
		con_error(temp);
#endif
	}
	return false;
}
edenshaw
Posts: 1
Joined: Wed May 30, 2007 8:56 pm

Connection problems

Post by edenshaw »

Hi, I'm new in the irrnet thing. I downloaded all the necesary (I think) and I went to the examples and run example 3-server in a PC and example3client in other but How do I do to fixed the connection failed issue ?????

I noticed that there is a xml file with the direction inside but How do I create that xml file for my projects.

How I setup my network connection????

Help Me please.

Thank you for the time

PS: Sorry for my english
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

There are 2 ways to set the connection for irrNet.

1.You can change the XML file to the correct ip address.

2. You can use setCustomAddress(stringc address, u32 port) before setting up the client or server to manually specify the address in your code. Please read the documentation provided with setCustomAddress, and remember to only bind servers to "127.0.01" unless you know what you are doing.

In both cases as with anything else you must port forward the port you are using on the server in order to access it remotely from the internet. Read your router/modem documentation on how to do this.
mmasters
Posts: 11
Joined: Mon Jun 11, 2007 11:11 pm

Post by mmasters »

This is a big newbie question, but is there any documentation on how to integrate this into Irrlicht?

Thanks,
Michael Masters
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Yes it comes with it if you download it. Its in the doc folder.
xxxD
Posts: 1
Joined: Sat Jun 23, 2007 2:44 pm

Post by xxxD »

this tropic is very old .... but i have a question :D :

Code: Select all

make.exe -f "c:\Dokumente und Einstellungen\user\Desktop\irr\irrlicht-1.3.1\examplesNet\N_Example\Makefile.win" all
g++.exe obj/example1.o  -o "bin\example1.exe" -L"C:/Dev-Cpp/lib" ../../lib/Win32-gcc/libIrrlicht.a ../../../../../../../Dev-Cpp/lib/libws2_32.a ../../libNet/enet.a  

obj/example1.o(.text+0x2c0):example1.cpp: undefined reference to `irr::net::INetManager::INetManager(irr::IrrlichtDevice*)'
obj/example1.o(.text+0x331):example1.cpp: undefined reference to `irr::net::INetManager::setVerbose(bool)'
obj/example1.o(.text+0x345):example1.cpp: undefined reference to `irr::net::INetManager::setUpClient()'
obj/example1.o(.text+0x35c):example1.cpp: undefined reference to `irr::net::INetManager::setUpServer()'
obj/example1.o(.text+0x435):example1.cpp: undefined reference to `irr::net::INetManager::addNetSphereSceneNode(float, int, irr::core::vector3d<float>, irr::core::vector3d<float>, irr::core::vector3d<float>)'
obj/example1.o(.text+0x452):example1.cpp: undefined reference to `irr::net::INetManager::sendPositionAuto(irr::scene::ISceneNode*, unsigned int)'
obj/example1.o(.text+0x51c):example1.cpp: undefined reference to `irr::net::INetManager::addNetSphereSceneNode(float, int, irr::core::vector3d<float>, irr::core::vector3d<float>, irr::core::vector3d<float>)'
obj/example1.o(.text+0x53d):example1.cpp: undefined reference to `irr::net::INetManager::sendPositionAuto(irr::scene::ISceneNode*, unsigned int)'

obj/example1.o(.text+0x87e):example1.cpp: undefined reference to `irr::net::INetManager::updateClient()'
obj/example1.o(.text+0x8cb):example1.cpp: undefined reference to `irr::net::INetManager::sendVelocity(irr::scene::ISceneNode*, irr::core::vector3d<float>, bool)'
obj/example1.o(.text+0x8f6):example1.cpp: undefined reference to `irr::net::INetManager::setLocalVelocity(irr::scene::ISceneNode*, irr::core::vector3d<float>)'
obj/example1.o(.text+0x922):example1.cpp: undefined reference to `irr::net::INetManager::updateServer()'
obj/example1.o(.text+0x957):example1.cpp: undefined reference to `irr::net::INetManager::getCustomVar(irr::scene::ISceneNode*, unsigned short)'
obj/example1.o(.text+0x97f):example1.cpp: undefined reference to `irr::net::INetManager::sendCustomVar(irr::scene::ISceneNode*, unsigned short, unsigned int)'
obj/example1.o(.text+0x9aa):example1.cpp: undefined reference to `irr::net::INetManager::getCustomVar(irr::scene::ISceneNode*, unsigned short)'
obj/example1.o(.text+0x9d3):example1.cpp: undefined reference to `irr::net::INetManager::sendCustomVar(irr::scene::ISceneNode*, unsigned short, unsigned int)'
obj/example1.o(.text+0x9fe):example1.cpp: undefined reference to `irr::net::INetManager::getCustomVar(irr::scene::ISceneNode*, unsigned short)'
obj/example1.o(.text+0xa27):example1.cpp: undefined reference to `irr::net::INetManager::sendCustomVar(irr::scene::ISceneNode*, unsigned short, unsigned int)'
obj/example1.o(.text+0xa4f):example1.cpp: undefined reference to `irr::net::INetManager::getCustomVar(irr::scene::ISceneNode*, unsigned short)'
obj/example1.o(.text+0xa78):example1.cpp: undefined reference to `irr::net::INetManager::sendCustomVar(irr::scene::ISceneNode*, unsigned short, unsigned int)'
obj/example1.o(.text+0xacd):example1.cpp: undefined reference to `irr::net::INetManager::sendVelocity(irr::scene::ISceneNode*, irr::core::vector3d<float>, bool)'
obj/example1.o(.text+0xafa):example1.cpp: undefined reference to `irr::net::INetManager::setLocalVelocity(irr::scene::ISceneNode*, irr::core::vector3d<float>)'

obj/example1.o(.text+0xb29):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xb6d):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xb9a):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xbd6):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xbed):example1.cpp: undefined reference to `irr::net::INetManager::getCustomVar(irr::scene::ISceneNode*, unsigned short)'
obj/example1.o(.text+0xc24):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xc60):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xc77):example1.cpp: undefined reference to `irr::net::INetManager::getCustomVar(irr::scene::ISceneNode*, unsigned short)'
obj/example1.o(.text+0xcaf):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xceb):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xd02):example1.cpp: undefined reference to `irr::net::INetManager::getCustomVar(irr::scene::ISceneNode*, unsigned short)'
obj/example1.o(.text+0xd3a):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xd76):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
obj/example1.o(.text+0xd8d):example1.cpp: undefined reference to `irr::net::INetManager::getCustomVar(irr::scene::ISceneNode*, unsigned short)'
obj/example1.o(.text+0xdc5):example1.cpp: undefined reference to `irr::net::INetManager::getSceneNodeFromNetId(unsigned short)'
collect2: ld returned 1 exit status

make.exe: *** [bin/example1.exe] Error 1
i use the newst files from the www.sf.net
i use devcpp.
what do i forget?
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Hey you must include the irrnet files as part of the project, so add the files themselves to the project, and then you must add the enet files (the c files) also and define WIN32. Also you must add include directory for enet and irrnet.

If you need more info please read the starting page of the documentation as it explains this in detail.

Cheers

-BSide
Ico
Posts: 289
Joined: Tue Aug 22, 2006 11:35 pm

Post by Ico »

Had some time to try it myself now.

Three things:

- In your packet handler you should replace all the "if"s with one big "switch" - or at least replace the "if"s with "else if"s. That should save quite some instructions especially with a lot of packets sent.

- Settings like host/port should be optional parameters of SetupClient()/SetupServer()

- SetupClient should accept 2 string/char parameters for easy username/password authentication (without having to worry about that using custom packets while the server already updates that client or so).

EDIT:

Fourth and fifth thingy :)

- There should be some way to assign objects to "groups" and then assign player ids to those "groups" too. This way it should be possible to host parallel "sessions" on one host under the same ip.

- Would be more advanced feature (option to activate - not permanent active): Assign each player a position (i.e. transfer camera's position) and set a max sync distance at which objects are updated/created. Objects further away will be destroyed/not updated. This could save bandwith and also allow somehow to create "groups" mentioned above without any additional assignments.
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Wow thanks Ico those are some nice suggestions. I don't know why I left it all if's for the default packet handling I made many wrong turns when I started this wrapper and they kinda stuck.. Although it works fine for the most part, I would definately rewrite it if I had the chance.

The Host/Port can already be set using a function, but I guess the optional parameters thing can be more practical.

I had the MaxDistance idea for a while too but never got around to implementing it, mainly because at the moment the server broadcasts data to everyone, and to implement MaxDistance I should set up a system where it filters which information goes where (This wont be too hard however as you can define which client to send to in the sendOutPacket function and also NetNodes have an identifier stating which client they "belong" to.) What I though is that the user will have to decide what position to calculate this distance from for each client. So maybe have a function like "setMainNode" or "setClientEyePosition" for the server to actually know where the client is (The client can have up to 100 scene nodes at a time so these functions I mentioned would help decide a specific position).

Oh I am rambling on too much, anyway if you want to make the changes (I may be a little too busy) then PM me ur SourceForge account name and I can give u access to the SVN.

Cheers.
XFactor
Posts: 39
Joined: Fri Jun 03, 2005 5:30 am

Post by XFactor »

Hi. I'm having difficulty setting up IrrNet. I know I'm doing something wrong. I need to know how to set it up. Thanks.

I'm using msvc 8.0.

These are the linker errors I'm getting.

Code: Select all

1>main.obj : error LNK2019: unresolved external symbol "public: class irr::scene::ISceneNode * __thiscall irr::net::INetManager::getSceneNodeFromNetId(unsigned short)" (?getSceneNodeFromNetId@INetManager@net@irr@@QAEPAVISceneNode@scene@3@G@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall irr::net::INetManager::sendCustomVar(class irr::scene::ISceneNode *,unsigned short,unsigned int)" (?sendCustomVar@INetManager@net@irr@@QAEXPAVISceneNode@scene@3@GI@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: unsigned int __thiscall irr::net::INetManager::getCustomVar(class irr::scene::ISceneNode *,unsigned short)" (?getCustomVar@INetManager@net@irr@@QAEIPAVISceneNode@scene@3@G@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall irr::net::INetManager::updateServer(void)" (?updateServer@INetManager@net@irr@@QAEXXZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall irr::net::INetManager::setLocalVelocity(class irr::scene::ISceneNode *,class irr::core::vector3d<float>)" (?setLocalVelocity@INetManager@net@irr@@QAEXPAVISceneNode@scene@3@V?$vector3d@M@core@3@@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall irr::net::INetManager::sendVelocity(class irr::scene::ISceneNode *,class irr::core::vector3d<float>,bool)" (?sendVelocity@INetManager@net@irr@@QAEXPAVISceneNode@scene@3@V?$vector3d@M@core@3@_N@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall irr::net::INetManager::updateClient(void)" (?updateClient@INetManager@net@irr@@QAEXXZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall irr::net::INetManager::sendPositionAuto(class irr::scene::ISceneNode *,unsigned int)" (?sendPositionAuto@INetManager@net@irr@@QAEXPAVISceneNode@scene@3@I@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: class irr::scene::ISceneNode * __thiscall irr::net::INetManager::addNetSphereSceneNode(float,int,class irr::core::vector3d<float>,class irr::core::vector3d<float>,class irr::core::vector3d<float>)" (?addNetSphereSceneNode@INetManager@net@irr@@QAEPAVISceneNode@scene@3@MHV?$vector3d@M@core@3@00@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall irr::net::INetManager::setUpServer(void)" (?setUpServer@INetManager@net@irr@@QAEXXZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall irr::net::INetManager::setUpClient(void)" (?setUpClient@INetManager@net@irr@@QAEXXZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall irr::net::INetManager::setVerbose(bool)" (?setVerbose@INetManager@net@irr@@QAEX_N@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall irr::net::INetManager::INetManager(class irr::IrrlichtDevice *)" (??0INetManager@net@irr@@QAE@PAVIrrlichtDevice@2@@Z) referenced in function _main
IRRLICHT ROCKS!!!!
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

hey it is very easy to set up in VC8.0

First I recommend to read documentation in doc folder. It is included in the zip (not svn), and also to download enet included in the zip (not svn). Remember that you must include the irrNet files as part of your project. (So you must choose addExistingFiles)

Cheers.
XFactor
Posts: 39
Joined: Fri Jun 03, 2005 5:30 am

Post by XFactor »

Thank you BlindSide. I got it to work.

Good work btw ;)
IRRLICHT ROCKS!!!!
MerlinCAM
Posts: 6
Joined: Sun Jul 08, 2007 9:11 pm

irrNet error nmaterial.texture1

Post by MerlinCAM »

i keep getting this error that nmaterial.texture1 is not right, when i look at the members of nmaterial, i see textures as an array.. but if i try textures[0] i get tons of errors.

This is when trying to compile one of the examples and i'm using the newest irrlicht. in studio 2003.

Can anyone give me a working .net 2003 or 2005 working project of the example project?
Post Reply