BlitzMax Forums/Brucey's Modules/RakNet

Retimer(Posted 2009) [#1]
You're going to hate me even more. Brucey, you mentioned you had wrapped RakNet a while back....

I'm not sure if anyone else is still using jimons wrapper of RakNet (requires no .dll) aside from myself, but that was back during v 3.2, and there has been a fair amount of updates since then to RakNet itself.

His wrapper has been stable enough to use live, but there are plenty of features missing, or not working that would be a nice plus to have.

I made a miserable attempt to update the wrapper to the latest version, but the whole memory override with raknet overpowered me as it seems to have changed a lot. Unfortunately, that leads me to bug you again =(

Any hopes of adding the mod to the svn? It seriously has to be the one of the greatest network libs in existence, and i'm sure more than myself could get a lot of use from the updated version.

Brucey(Posted 2009) [#2]
What's not working?

Retimer(Posted 2009) [#3]
Security functions seem glitched, rakvoice wasn't included, and many other functions that were left out. On the bare minimum of it, it has the highest priority of features (bitstream being the main)'s just missing a few 'extras' that would be nice, along with lacking some bug fixes from the updated versions.

It would have been easier for me to impliment the rest of the functions in 3.2, but i'm unable to find the rest of raknet source for that version, and it seems like it would be backtracking to update an older version of a library.

Stu_ovine(Posted 2009) [#4]
Ive stayed with v3.32 of jimons wrapper but had to add a few functions to get it to work exactly as I wanted. (if you want 3.32 src rtime I can upload a copy np)

I found that the statistics side of things didnt seem to work correctly but I skipped past it as I didnt really need it (along with RakVoice)

One major lacking function I had to add was

const char* GetIPAddressFromIndex( int index );

All in all its a nice wrapper but IM with reTimer, its a shame its not been updated (Raknet is constantly being updated)

Brucey(Posted 2009) [#5]
My API ain't flat like jimons.... (as you'd expect, I suppose?)

Retimer(Posted 2009) [#6]
const char* GetIPAddressFromIndex( int index );

Yeah haha, I went ahead and came up with this for getting remote ips with a simplified wrap of jimons wrap I made called EasyRak. Nothing needed to be done to jimons source. Been a while since I made the module and had to use the function, but I think this is what I used:

Method GetRemoteIp:String(Index:Int) 
	Return EasyRak_DotIP(RN_SystemAddressGetBinaryAddress(RN_GetSystemAddressFromIndex(Self.Interface, Index))) 
End Method

Function EasyRak_DotIP:String(IP:Int) 
	Return (ip & 255) + "." + (ip Shr 8 & 255) + "." + (ip Shr 16 & 255) + "." + (ip Shr 24) 
End Function

I also forgot to mention about the statistics, thanks for mentioning that.

And if you could, I would really appreciate a link to that 3.2 source as I think Bruceys plate is too full or has other foods for thought at the moment. I'm unsure why there isn't older versions provided on the rak website =/

Brucey(Posted 2009) [#7]
Actually, I've been fighting this line of late :
rakPeer1.InitializeSecurity(Null, Null, p, q)

The bugger locks up inside of Raknet...

Brucey(Posted 2009) [#8]
The bugger locks up inside of Raknet...

So, I've found a bug in Raknet... I've fixed it, but I can't say I'm impressed... given that I've wasted a few hours of my life debugging RCACrypt.. joys :-p

Brucey(Posted 2009) [#9]
It seriously has to be the one of the greatest network libs in existence

I'm not so sure :-p

I rewrote my own code 3 times before attacking RakNet for the problem... I am at this moment, not filled with optimism towards some of the other parts of the API I've still to venture upon...

Retimer(Posted 2009) [#10]
I'm not so sure :-p

I understand where you're coming from with the actual source though..between updates of raknet, there's a lot of undocumented and screwy transitions I noticed comparing the limited source I have between 3.2 and the new 3.3.x.
It's nothing short of a challenge, and if you want to focus on other things that's totally cool. When I ask for assistance, I feel like an ass because I don't get this tier of help from paid customer support.

I thought maybe you had already done a complete wrap of it, and was just asking if you could publish it, but if there's too much work to be done with it, no worries.

I may be wrong anyhow...I figured there was more people out there looking for a better/easier library to work with for online games/apps, but it appears there's only a couple of us with high hopes.

Brucey(Posted 2009) [#11]
I thought maybe you had already done a complete wrap

Just a "most" wrap, since I hadn't intended using things like the RSA functionality ;-)

Currently I'm just going through and porting those samples, and tweaking my code as I go... (which would be now much more complete were I not bugfixing Raknet )

Anyhoo, if you have a lot of Raknet integration already, you may not want to re-code it to support a OOP API.

Retimer(Posted 2009) [#12]
(which would be now much more complete were I not bugfixing Raknet )

Nice find! I wonder how long it has been like that...

Anyhoo, if you have a lot of Raknet integration already, you may not want to re-code it to support a OOP API.

The wrap of a wrap I used (posted in blitzmax programming) would make it less difficult to go through such a transition. For what it's worth i'm as excited as a kid in toys'r'us about your work on this. Very anticipated.

Brucey(Posted 2009) [#13]
I wonder how long it has been like that...

Possibly a while. I think the fact I develop on Mac helps to pick up on these, as it tends to lock up as soon as you step out of bounds (data-wise).

Very anticipated.

The examples are making me crazy at the moment. I can almost port straight to BlitzMax, but I keep missing *stupid* things which have me spending far too much time-wasting on.

Example :
peer2->Connect("", 60000,0,0)

The third param is passwordData, a String. Obviously, if you pass 0 in BlitzMax you actually pass "0", unlike in C++ which is Null. So you get weird things happening... and you look at the code til you're blue in the face, and can't "see" the problem :-p

Anyhoo... I think I'm on top of it now ;-)

I've also knocked together a little CEGUI-based "helper" framework for some of the samples, since the C++ samples mix text output with no-wait key input. So I went the route of a Graphics window, and CEGUI dialogs for text input. Works rather well actually, and of course runs concurrently with the network processing, so while you are typing something in, you may see a message pop up in the background.

Anyway, back to the examples - there's a lot of them!!

Retimer(Posted 2009) [#14]
I've also knocked together a little CEGUI-based "helper" framework for some of the samples

Nice. I tend to be using cegui for everything nowadays as well - so little work required to make something look fancy. Glad you're getting somewhere with it.

I'm really looking forward to the rakVoice support =p. Nothing like a little p2p support for voice chat haha.

Brucey(Posted 2009) [#15]
I'm really looking forward to the rakVoice support

Yeah... I dunno how I'm going to test that!?!

Retimer(Posted 2009) [#16]
The one example I used allowed you to output sound, and it would reverb back a second later. I think they all work that way (the examples appear to just be different sound systems). Otherwise, i'm available if you need an additional client/host to test with.

Brucey(Posted 2009) [#17]
Just so there's something to play with for now while I work through the rest of the examples : raknet_example_win32.rar (2.7 meg)

Showing the CEGUI-based framework for the examples. In this one, it's the basic Chat Client/Server. Not the most exciting in the world, but it does show things like banning and stats, which may be of interest.

As usual, the wrap compares closely with the original API...

	printf("My GUID is %s\n", client->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS).ToString());


	AddMessage "My GUID is " + client.GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS).ToString()




		rss = client.GetStatistics(client.GetSystemAddressFromIndex(0))

Which makes porting the examples a case of copy/paste/tweak... more or less ;-)

Retimer(Posted 2009) [#18]
Good stuff. Working perfect on my side.

Stu_ovine(Posted 2009) [#19]
Works perfectly here too, exciting stuff

Retimer(Posted 2009) [#20]
! Just noticed that you added raknet.mod to the svn along with a few more examples...all of which appear to be working perfect as well.

Either my chair massager is on or i'm just excited =p

Brucey(Posted 2009) [#21]
The examples were taking longer than I thought they would - as I have to rearrange things a little to fit into my helper-framework. So I thought I may as well drop the module into SVN for now.

I think most of the core stuff is complete.
Still working my way through the "plugins".
I've decided that RakVoice will be best kept as another module. Same with Lobby2. Otherwise you'd get all of that extra stuff compiled in, every time. This way, you get to choose.
I could probably do the same for some of those other plugins, but they seemed small enough not to matter too much.

Edit : it's the documentation that takes most of the time though.... *phew*

Retimer(Posted 2009) [#22]
Edit : it's the documentation that takes most of the time though.... *phew*

I bet!...I assume you have to rely on good documentation on the other side, and sometimes figure out what the heck a function does on your own a lot of the time.

As for the examples, perhaps me and/or Ovine (if he's up for it?) can save you some time by referring to your current examples and setting up the other examples (the ones without the use of rakvoice/lobby/updater/..) in the same way, and throwing them back to you for review?

This module was an important request to me so i'de love to help in any way i'm capable if it means you can forward the time saved on the rest of the features sooner.

Brucey(Posted 2009) [#23]
I might try and implement the Voice callback stuff in C++ - most of which doesn't really require BlitzMax interaction anyway - since all it needs to do is feed audio buffers with data.
That way, I should avoid any potential issues with threads.

I was considering perhaps a base BaH.RakVoice, then one for each of, FMOD, BASS, irrKlang, OpenAL, PortAudio... - well, no harm in having some options available?
Since there are already basic examples for PortAudio, DSound and FMOD, it shouldn't be too hard to work out the rest.

I've also swapped libspeex with the latest version - it appears to compile, but until I try to build an app, won't know if everything has linked properly :-p

Retimer(Posted 2009) [#24]
That sounds pretty awesome. I can't imagine the possibilities with that....I look forward to creating a p2p voice chat feature for my lobby so people can spam music in their own channels (as...ofcourse they will clearly do).

A bit unrelated, but will there be a method for TRKBitStream, for 'ignorebits'? It doesn't appear to be supported within the type..maybe i'm missing it.

Brucey(Posted 2009) [#25]
...for 'ignorebits'

Ooops. Added now.

Retimer(Posted 2009) [#26]

I just tried to port over BigPacketTest example, and it appears to work, however for the sake of sanity BIG_PACKET_SIZE should probobly be 20739, or 207390, but 2073900 as the size nearly freezes my (well above average) dev computer....i'm thinking it's because of how the string is assigned differently from the port.


Brucey(Posted 2009) [#27]
Cool. Thanks.

I've tweaked it a little here and there, to store/compare the data as per the original. (and set it to use that full 2073900 bytes)
The "freezing" was because of calling GetData()[i] in the loop. Function calls are expensive ;-)
Working on the Byte Ptr itself solved the loooong delay!


Brucey(Posted 2009) [#28]
.... trying to get my head around a design for the rakvoice mods...

Needs to be fairly flexible, and transparent for you lot to use :-p

Retimer(Posted 2009) [#29]
The "freezing" was because of calling GetData()[i] in the loop. Function calls are expensive ;-)

Local pdata:Byte Ptr = packet.GetData()

woops! I knew they were more expensive...I wasn't aware they were that much more costly though. Learn a new thing every day.
And ofcourse, the example is working great now.

.... trying to get my head around a design for the rakvoice mods...

Needs to be fairly flexible, and transparent for you lot to use :-p

Yeah, I think you turned that into a much larger scale for a project, but in a rank of coolness i'm sure it will be on the top.

Brucey(Posted 2009) [#30]
I've committed the initial work. (BaH.RaknetVoice and BaH.RaknetVoiceFMOD).
The example is working here on Mac ;-)
However, it may not even compile (libspeex) yet on Windows... so be aware before trying it out.
I'll check the Win32 stuff tomorrow.

On Mac at least, you need to run two separate instances of the example. Doesn't work (rec+play) on
the same app. But I don't see that as being very important.

BlitzMax and audio chatting... very cool :-)

DavidDC(Posted 2009) [#31]
BlitzMax and audio chatting... very cool :-)


Retimer(Posted 2009) [#32]
So much for getting a good nights rest, svn'ing now :)

Retimer(Posted 2009) [#33]
Everything appears to compile fine.

Edit: But the fmod example for it doesn't appear to do anything. Win32. I haven't tried on mac to see if i'm doing something wrong or not yet.

Brucey(Posted 2009) [#34]
Remember that one of the "clients" needs to start on a different "local port". If I start them both using the default, it doesn't work.
Once the two are running, (C)onnect with one of them using the appropriate details. If successful you should get a connect message appearing on each. After that, the audio should be working.

But I'll test Win32 shortly...

Brucey(Posted 2009) [#35]
Wooo! Tested on XP with my Logitech USB headset, and it worked first time :-)

If you follow the method in the previous post, that should sort you out.
I'll give Linux a run this evening.

So, now that I've proved it does actually work, I'll have to finish the example, the Voice API, and see about implementing some of the other "audio adapters".
For PortAudio, I'll use Skid's Axe.PortAudio module.
Might even be able to get it working with Redi's maxmod2 ?

Retimer(Posted 2009) [#36]
Hmm, thought I tried that. It's working now :) nice!

xlsior(Posted 2009) [#37]
BlitzMax and audio chatting... very cool :-)

Hm.... I suppose it could be combined with ESCAPI ( , )

to whip up your own little webcam chat program.

Might even be able to get it working with Redi's maxmod2 ?

that would be neat.

plash(Posted 2009) [#38]
@xlsior: What would be nice is cross-platform camera support! (OpenCV - hint hint)

Brucey(Posted 2009) [#39]
Voice stuff now building on Linux... not tested yet, as *someone* left the headset at the office :-p

Retimer(Posted 2009) [#40]
Any chance to get a rakvoicebass.mod next? :)

Brucey(Posted 2009) [#41]
Possibly... if I can work out how to use the "push" interface... (rather than via the callbacks).
I think I'll be better coding it in C... so expect it not to be working properly for a while :-p

Retimer(Posted 2009) [#42]
Just noticed RakNetRooms.mod from the svn. I had actually never touched the sample for raknet before but after reading the description i'm in awe..

I was actually just about to start working on a 'table' system for a game for users to join through a lobby, but apparently blitzmax is going to have a perfect library for just that. Top notch.

Brucey(Posted 2009) [#43]
Just noticed RakNetRooms.mod from the svn.

It's not finished yet! :-p
I just needed to get what I'd done so far, committed. There's a lot to it... mostly callbacks... which I've yet to figure out the best implementation.

Retimer(Posted 2009) [#44]
It's not finished yet!

I know =p just looking forward to it when it's finished.

byo(Posted 2009) [#45]
Keep up the good work.
They're looking good so far.

Retimer(Posted 2009) [#46]
I have just begun converting my work to your raknet module from jimons and all has been great, except for the bitstreams.

I noticed in comparison to jimons work, he had support for signed/unsigned integers with the bitstream class, and you were able to send a single bit (bool). It wouldn't be difficult to subtract for signed vs unsigned, but since this is blitzmax, and not is a bit more work for reading/writing on the users end to do that...what would you think of an additional argument on the read/write commands, for having a value for signed/unsigned? And is it possible to get a writebit function within the trkbitstream class?

Sorry if I missed anything for this, i'm still going through the module to understand the differences between the two for use with blitzmax better.

Ole JR(Posted 2009) [#47]
Got a quick question.

Does raknetrooms.mod, in it's current state, compile on linux for you?

Because if it does, there's something missing on my side :)

I get an error in /src/Rooms/ProfanityFilter.cpp:51: error: 'strlwr' was not declared in this scope.

Not that I use it for anything. But I'm lazy and check out all the bah.mods :-P

Brucey(Posted 2009) [#48]
Does raknetrooms.mod, in it's current state, compile on linux for you?

raknetrooms is turning into a big pain. It would appear that it's only been tested on Windows, and at that, Visual Studio.... given all the errors I'm getting trying to compile it with MinGW..

However, I added an ifdef at the top (and actually re-wrote bits of ProfanityFilter.cpp) to assist in the compilation on Mac :
#ifdef __APPLE__

I think changing this to
#ifndef WIN32

will help compilation on Linux.

I'll test it properly on Linux it tonight. :-)

Brucey(Posted 2009) [#49]
Does raknetrooms.mod, in it's current state, compile on linux for you?

Fix committed.

Brucey(Posted 2009) [#50]
he had support for signed/unsigned integers with the bitstream class.

I've added support for UShort and UInt calls, as well as Bool and Bit functionality.

I also noticed, which I was referring to jimon's wrap (better to see what you mean), that he was passing Int to all the functions, and in the C++ glue accepting things such as char, short, etc. Very dangerous. I'm guessing noone on Mac ever tried that mod, as it would be very likely to nuke on a first call to a function with invalid parameters. (Much in the same way that for some reason you can't pass a Long back from C++ to BlitzMax - it is unreliable and can corrupt your data. But I use a workaround for that.)

Retimer(Posted 2009) [#51]
Ahhh thank you!

that he was passing Int to all the functions, and in the C++ glue accepting things such as char, short, etc. Very dangerous.

Yeah i'm not sure what jimons focus was since none of us had any real chance to chat with him (no forum access?), but he may have just thrown it together to get rid of the dll requirement on a specific OS (likely windows).

But...that is just another reason why I was really anticipating your version of the module. Cheers

Retimer(Posted 2009) [#52]
Just a few updates on the trkbitstream:

-Identifier 'WriteBool' not found (latest svn + built) [trkbitstream.writebool]

Some ideas, or missing features:

-GetLength() / GetWrittenBitcount()

And there appears to be no WriteCompressed<Vartype>(<val>) methods, but I might have overlooked something.

Brucey(Posted 2009) [#53]
I have this :
	Method WriteBool(value:Int)

As well as :
	Method Write0()

	Method Write1()


which I was sure I'd checked in...

<EDIT>Just updated my Win32 source and those methods appear there as I'd expect.

Brucey(Posted 2009) [#54]
Some ideas, or missing features

I'll get onto those presently, as well as the WriteCompressed methods :-)

Retimer(Posted 2009) [#55]
I have this :

Yeah they were showing up properly in blide, but writebool(<0/1>) wouldn't build for me, and I definitely built the mod lol. I'll try forcing rebuild or something and see how that works out.

Retimer(Posted 2009) [#56]
I'm getting an error on CreateFromData. I'm trying to use bitstreams without using RPC, but i'm becoming stumped here.

Self.Reader is a trkbitstream
packet is a trkpacket

Self.packet = Interface.Receive()
If (Self.packet) Then
	Local Data:Byte Ptr = packet.GetData()
	Self.reader.CreateFromData(Data, packet.GetLength() , False)

In jimons source, he had:

RN_API BitStream * RN2_API RN_BitStreamCreateFromPacket(Packet *packet)
	BitStream *b = new BitStream((unsigned char*)packet->data,packet->length,0);
	return b;

Which as far as I can tell, is exactly what i'm doing in my code with your version, but i'm receiving an error instead (unhandled memory excep.). I haven't a clue what's going wrong here =(

Brucey(Posted 2009) [#57]
This is in the bigpacket example :
			Local packet:TRKPacket = peer1.Receive()
			While packet
				If packet.GetData()[0] = ID_DOWNLOAD_PROGRESS Then
					Local progressBS:TRKBitStream = TRKBitStream.CreateFromData(packet.GetData(), packet.GetLength(), False)

Note that CreateFromData is a function, if that makes any difference?

Retimer(Posted 2009) [#58]
Thanks, i've gotten beyond that now, however something seems out of whack when I attempt to readbyte from a bitstream =(

writeint/readint doesn't cause an error, but no value is returned (other then zero), but readbyte only gives me an Unhandled Memory Exception Error

It appears to be linked with:

bool bmx_BitStream_ReadByte(RakNet::BitStream * stream, unsigned char * value) {
	return stream->Read(value);

Nothing appears to happen with the value? not sure.


Method Create_BitStream_From_Packet(Packet:TRKPacket)
	Self.Reader = New TRKBitStream.CreateFromData(Self.packet.GetData(), Self.packet.GetLength(), False)
End Method

Method ReadByte:Byte()
	Local Val:Byte
	Return Val
End Method

And I use this for writing the packets:

Method Create_BitStream(MessageID:Int, Compressed:Byte = 0)
	Self.Writer = New TRKBitStream.CreateBitStream()
	Writer.WriteByte((MessageID + ID_USER_PACKET_ENUM))
End Method

Method WriteByte(Value:Byte)
End Method

The packet writes and recieves alright, but as for retreiving the data using the read commands - nada. Nothing appears to be wrong with write<datatype> methods though.

Retimer(Posted 2009) [#59]
I'de like to bring up this issue again...The thrown together example below should provide better detail when run:

I'm still using jimons version because I can't seem to get beyond this issue :(

Brucey(Posted 2009) [#60]
Under investigation...

interestingly... this :
Print packet.GetData()[0]
Print Short Ptr(packet.GetData() + 1)[0]
Print Int Ptr(packet.GetData() + 3)[0]

prints the expected values...
So it seems Bitstream is a tad sickly...

Brucey(Posted 2009) [#61]
Ah haa.... I appear to have solved the problem...

Apologies for my ineptitude...

Retimer(Posted 2009) [#62]
Ah haa.... I appear to have solved the problem...

Thanks, that was fast. I've been looking forward to using your wrap forever, and now I finally can :)

Htbaa(Posted 2009) [#63]
I've read on that RakNet is now free to use for Indie Developers.

Free Indy license

A free Indy license allows you to use RakNet in a single downloadable application for the PC, Mac, or Linux only, any operating system.

Read the entire agreement online. If you do not agree with the license terms or have questions about the terms, please contact us

Key terms:

* Gross revenue under 250K
* Must display RakNet logo in your game's splash screen or credits.
* Downloadable distribution
* PC, Mac, or Linux


Retimer(Posted 2009) [#64]
Great news, thanks for sharing!

Stu_ovine(Posted 2009) [#65]
The fix you did seems to have not worked for writelong


is wrong ?

	Local Val4:Long = 7


        Print b.ReadLong()

returns 20506055076151060

Ive just tried it with "Zeke"s version, does the same in there too.

Stu_ovine(Posted 2009) [#66]
Looking thru the code it seems that WriteTime and ReadTime use longs in the stream too, those calls are also broken ?

Seems they all cast long using "BBInt64" is that the fault ? - Is there a problem with c -> longs -> Max ?