Archive for the ‘Source code’ Category

LockToKey examples

March 14, 2007

The DC++ wiki is down, so all you developers out there are out of luck. Until now… Well, at least for one thing;

The LockToKey examples. Since it’s quite a complicating thing to reverse engineer, here’s the examples that could be found through the wiki.

Note that I haven’t written any or have any knowledge about them.

Sorry about .doc, but WordPress didn’t allow .rar. Just rename the file to .rar. (The reason I’m not pointing to the cached Google page is because it might change over night.)

Don’t forget that you can make topic suggestions for blog posts in our “Blog Topic Suggestion Box!”

Time left: 584 million years

March 14, 2007

In the upcoming version, there will be a fix for (as noted by the changelog) “time issues with DC++ running for more than 49 days”. This changelog entry mean that if you have your system for running more than 49 days, DC++ will most likely crash. This isn’t a new issue, it has existed for a while, though no one had gotten around to fixing it. (Though, fulDC has had it fixed a couple of versions.)

When the system starts, a specific variable is set that keep track of how long ago it was since your computer had started. When creating the variable, one must set its size as well. If you set the size of it to 100, and you assign the variable 102, the variable will overflow and nasty things will happen. This is also what has happened with DC++.

The size for this specific variable is 32-bit. This mean that the maximum size is 2^32, or 4294967296.

Like I said, this variable keep track of when the system was started, in milli-seconds. So if the variable would read 10000 it would mean that there have been 10 seconds since the start. Let us now convert the maximum amount of milli-seconds to maximum amount of days. This yeild; 4294967296 / 1000 / 3600 / 24 = 49,7102… days. Now look back on the changelog entry. It says 49 days, too.

So, if this is fixed, how is it fixed?

This is fixed by setting a new maximum size for this variable. “But… Then you’ll just end up having to fix that, too!” Well… That’s true. Sort of. If you’re planning on living for a couple of million years, that is.

The new maximum size is 64-bit. This mean that the maximum size is 2^64, or 18446744073709551616 milli-seconds. Let us convert this to days, again. 18446744073709551616 / 1000 / 3600 / 24 = 213503982334,6… days. Seems days aren’t enough. That’s 584942417,3 years. Yikes! OK, this mean that there’s 584 million years until DC++ will crash!

So you see, you don’t need to worry about this issue any more. :)

[If current DC++ crashes, and you restart it, your system will obviously still be running for more than 49.7 days. However, as the variable overflow, it is also reset, so you'll have another 49.7 days until DC++ crashes again. Repeat ad infinitum.]

Don’t forget that you can make topic suggestions for blog posts in our “Blog Topic Suggestion Box!”

DC++ like Visual Studio with a Service Pack

December 21, 2006

When work on 0.699 begun, it was noted that it will require Visual Studio 2005 (or ‘8′) to be able to be compiled. When the DC++ version was complete, service pack one for Visual Studio had been released, and it is now a requirement for DC++’s entire feature set. DC++ will still be able to be compiled without the SP, but you will most likely encounter some warnings and weird crashes if you aren’t.

Don’t forget that you can make topic suggestions for blog posts in our “Blog Topic Suggestion Box!”

We can always hope…

October 21, 2006

In my last post, I talked about how you added a feature to the protocol and how you signal that you support it. However, you may have gotten the impression that you have to signal that you support something, but this is not true. Even if you support a particular feature, you don’t actually have to signal it.

Let me take an example. In NMDC, there is a distinction (well, not in the protocol, but by the hubs and clients) between “hub topic” and “hub description”. The hub description is used for when a hublist checks you hub, and then displays that description on their website or something. But “topic” is the name of the hub smashed together with the topic, separated with a “-”. (Yes, this is very ugly.) In ADC, there is also no way of saying “this is the topic”. However, due to ADC’s easily extensible interface, it is possible to have the hub send a parameter that isn’t in the base protocol, and one we don’t actually need to advertise we know (before we send it).

There are two possible things the hub can send, depending on whom should get it. Let us think about who would want a topic vs description. 1) the users in the hub or 2) a hublist bot.

To have 1), one would need to change all clients to accept a new parameter. Eg, “TP” (“ToPic”). The hub will then send NIthisismyname DEthis_description_should_be_used_for_hublists TPthis_is_some_random_topic. And if the clients doesn’t understand TP, then they’ll simply ignore it and use the DE-parameter as a topic. This solution’s main problem is that so many clients “need” to change its behaviour and accept TP. This is where 2) is better.

To have 2), one would “only” need to change all hublist bots. Eg, “HD” (“Hublist description”). The hub will then send, instead of TP as in the previous example, but HDsome_description_for_the_hublist. This solution is somewhat better then 1) because there aren’t that many hublist bots that need to be changed. (Heck, at the time of writing, I only know of one hublist bot for the ADC protocol anyway.)

However, the point here is that the hub/client doesn’t need to advertise it supports TP or HD (or any other command or parameter). The client/hub can just send the information, and hope (yes, hope) the other end understand it.

Don’t forget that you can make topic suggestions for blog posts in our “Blog Topic Suggestion Box!”

SUP? I’m good, I have ADC, Ya Know?

October 20, 2006

One of the most interesting features in ADC is the ability to signal that the client or hub support some feature, and that others can take advantage of that. This is not all too different from NMDC’s (hacked) $Supports. In fact, they represent the same thing; The ability to support a particular feature. These features should only be things that are being transmitted between clients and/or to the hub, since it’s no use signaling that you have the ability to have a Notepad built in the client.

There are three ways a client will signal it supports something.
1) To the hub (usually/probably in the initial connection state). Here, hubs may (should) decide to allow clients that support a particular feature the hub owner(s) would want users to have. The hub may restrict clients if the clients signal they support a particular feature, or if they lack the support of another. It’s all very “hey, I support this and that. May I enter?” If the hub sees the clients supporting a feature the hub doesn’t know about, it can/should let the clients through. With ’should’ in that sentence, the clients have the ability to be up to date with features, while the hub could be extremely old and without any piece of knowledge about the new features. In NMDC, hubs and clients need to be updated when one either are updated with a new feature.
This part is signaled as HSUP ADfeaturename ADanotherfeature. All clients and hubs must support BASE, which is the ADC draft. Every feature must be 4 characters, and all upper case.
2) To all clients, in a broadcast manor (usually/probably in the connection stage). This is signaled in the INF, where you send BINF SUfeature, otherfeature,nfeature. (B == broadcast) As far as I know, there is no way to signal to specifically add or remove a feature in this way, so the client probably need to send the entire feature list. Again, this must be 4 characters and all upper case.
3) To specific client (usually in the connecting stage for a download). Here, you can send the SUP list or the INF list, which ever you find appropriate.

Sometimes, the user (or client) may want to say “hey, I don’t want to support/use this feature anymore, so don’t query me about it”. A simple checkbox in the client/hub can suffice for the meaning of “enable/disable this feature”. This is an interesting feature (in ADC) that NMDC doesn’t. NMDC has no way of saying (while connected to the hub) that the client doesn’t want to support a particular feature. But in ADC, the client can signal that it doesn’t want to support something any time it want to. (Whether the hub will approve of removing a that feature is something else. It may get you kicked out of the hub.)
Clients (and hubs) can signal that it has stopped supporting a feature by using HSUP RMremovethisfeature.

So, let us create a feature, and see what we need to do. Say we want a way to tell people when (you’re) searching that you also want to receive back the entered e-mail the other user got. (Why? Well, I don’t know…)
Now, let us call it SINF (“search inf”), where we have also abstracted it so much that one should be able to “want” anything from the INF. Eg, the client version or the e-mail. So we signal SUP ADSINF (for the hub), and then INF SUSINF (for the clients). Now, we also say that everyone that is able to send the request, should also be able to send the result back. (So we don’t have to come up with another command. Now, whenever we send a search we also signal “EM1″, meaning “give me the information in EM. (EM == e-mail). The other clients that support the SINF feature, will then send back “EMthis.is.my@email.com”. What is particularly interesting here is that the hub doesn’t have to send the EM1 to every client in the hub. The hub can keep a list of everyone that support SINF, and only forward that part to those clients. There’s no reason a client should get EM1 if it doesn’t even comprehend what that means. A little more hub work == less bandwidth cost for many. (The client, if it see something it doesn’t know, will anyway only discard it.)

There aren’t any particular restriction when signaling. You have to make sure the extension and/or command name is unique, since otherwise it could lead to clashes. And of course that everything transmitted in ADC (command names etc) are always in upper case. Beyond that, what restricts the programmer is the amount of combinations for feature name (A-Z, 0-9) and the programmer’s imagination.

(Yes, I know, I used lower case for the above features, but it didn’t look so nice with upper case, and the blog is weird when it comes to certain brackets…)

Don’t forget that you can make topic suggestions for blog posts in our “Blog Topic Suggestion Box!”

Visual Studio 2005

October 19, 2006

As of the next release of DC++, the project files will be incompatible with Visual Studio 2003 (see: svn 677). For many developers, myself included, this means an upgrade. Previously, Microsoft published Visual C++ .NET [2002] and Visual C++ .NET 2003, which were priced at around $100, and would compile DC++ just fine. For their “2005″ product line, they dropped the standalone C++ environment, leaving me in a bind. It turns out that owners of Visual C++ .NET 2002/2003 are qualified to purchase the Visual Studio Standard 2005 upgrade, which retails for $200. I just ordered received my copy and if this post isn’t updated, you can safely assume it works for compiling DC++.

The Visual Studio Express 2005 package is free, but it doesn’t include ATL. The above is the least expensive way to compile DC++, really.

Don’t forget that you can make topic suggestions for blog posts in our “Blog Topic Suggestion Box!”

Compiling DC++ with Visual Studio 2003

September 27, 2006

This guide is about compiling DC++ on Windows, with Visual studio 2003.

To compile DC++, you will need a few things.

First, download the DC++ source, and unpack it in C:\dcplusplus\dcplusplus696\. (So you got C:\dcplusplus\dcplusplus696\windows, C:\dcplusplus\dcplusplus696\client etc.)

Download STLport, and unpack it in C:\dcplusplus\STL so you got C:\dcplusplus\STL\config etc.

Download WTL and unpack it in C:\dcplusplus\WTL so you got C:\dcplusplus\WTL\include etc.

Download the latest SDK, or get the natupnp.h file from Bugzilla. Place it in C:\dcplusplus\natupnp\. (I think I have it in some Visual Studio include path, but this should work fine too.)

Download YaSSL and unpack it in C:\dcplusplus\YaSSL so you got C:\dcplusplus\YaSSL\certs etc.

Download Python and install it. (I got mine in the default folder)

Enter C:\dcplusplus\dcplusplus696\. Open up DCPlusPlus.rc and change the line #include “wtl\\atlres.h” to #include “atlres.h”

Open up the workspace (DCPlusPlus.sln)

Under the Tools menu, press Options.

Go to Projects and then VC++ Directories.

Under ‘Show directories for’ select ‘Include files’.

Add the STL folder, WTL\include folder, YaSSL folder and then the natupnp folder. (They should be in the top.)

Under the Build menu, press Build solution and Visual Studio should compile you an executable that is located in C:\dcplusplus\dcplusplus696\app\.

To change Python path, go to client->Header Files->StringDefs.h->Properties->Custom build step and change the appropriate values.

SETTING the settings

June 24, 2006

So you’ve gotten bored and you started looking in StringDefs.h. You notice that there’s a bunch of SETTING_SOME_OBSCURE_OPTION. When you search for it in other places in the source, you end up in resource.h and SomePage.cpp (and of course StringDefs.h) (where ‘SomePage’ is the name of one of the settings pages).

“How can these options then be used elsewhere if there’s no code to back it up? So DC++ completely ignores every single option there is?”
No, DC++ doesn’t. You see, all of the things in StringDefs.h that have SETTINGS_ before it are captions (text) in the settings pages. Meaning, they aren’t used as options. The names of the settings are instead SOME_OBSCURE_OPTION, and if you search for that, I assure you that you will see more places than above files. (And you can call the option with SETTING(SOME_OBSCURE_OPTION) or BOOLSETTING(SOME_OBSCURE_OPTION).)

SCH proudly presents $Search

June 19, 2006

Ah, yes, today is a “why the NMDC protocol suck and ADC is so great”-post. And today’s protocol bit is brought to you by $Search (paid and sponsored by SCH in ADC) and the file types used. (You should have a look at the Search types post I made a while ago.)

Now, on to the (NMDC) protocol bit. All of the search types are “hard coded” into the protocol, meaning you will need to upgrade other clients to respond to your file type searches. This is unfortunately not enough of the NMDC silliness. When you pick a certain file type in DC++, DC++ will change the caption of your choice (“Audio” eg) and to a number. This number is predefined (as the wiki post says) and cannot be changed (because otherwise, you’d receive wrong search results or not get any – depending on what you change the number to). This basically means that you cannot tell DC++ (code wise, considering there is no way to do it in the GUI) to “search for _filename_ but only include audio extension AND video extension”. This is because there is no way to combine the different numbers. Now you’re thinking “but can’t you add them and the send that number out?”, and sure, you can do that. But you won’t get the result your after. Eg, “Audio” is 2 and “Compressed files” is 3. Now, if you add these, they (of course) become 5. Now, the problem is that 5 is “Executables”, making all of the other clients think you’re after “executables” and not “audio” and “compressed files”.

“Sigh… Every time you talk about NMDC, I hear something bad… Fine. So, what’s so good with ADC then?”

Ah, my dearest Watson, it is very simple. In ADC’s SCH, one can specify a “EX” (“extension”)Â when searching, and the responding client have to match files with at least one of those EXs. This means that we can specify completely what kind of file types we want – even if the other client hasn’t hard coded any file extensions in its client).

Me, myself and Unsigned

June 12, 2006

One of the problems when creating software is to predict and know what kind of input people will give when they fiddle around in the settings of the program. DC++ no less also has this issue. Though, while it’s easy to picture (as a programmer) what the user input will be, the code outcome might not always be what the programmer originally intended.

The issue I’m going to talk about today is an issue that arose with people upgrading from DC++ 0.674 to 0.691. (I don’t know if the problem was or not possible with 0.674.)

A bug report and patch was swiftly created and will most likely be introduced in “0.692″ (upcoming version).

If you look at the patch, you will see that lines starting with ‘-’ is removed and ‘+’ is added. With this knowledge, the only “real” change you will see in the patch is that instead of “short” it says “unsigned short”. What this change really does lies in the way C++ (DC++ is written in C++) is designed.
(If you have programming knowledge, you know a short is a type for variables/functions etc. For the no-programming-knowledge-people; Consider that you have a box. This box can store a value, but only one, at any given time. Now, this box have to have a ‘type’, meaning it can only contain values of that certain type. short is one of those types.)

In C++, if a type has nothing before it, it is ’signed’; This means that it can contain values up to 2^15. The problem is that socket ports can reach 2^16. And this is where the ‘unsigned’ comes in the picture. If a type has ‘unsigned’ before, it not only support 2^15, but also 2^16. We come to the conclusion that using ‘unsigned’ before removes our issue.

Another thing you might notice with the current behaviour, it is that if you input a value above 2^15 (but below 2^16), you will then use – 2^16, this of course leading to a negative value. An interesting thing is that if you input something above 2^16, the value used will then also be – 2^16.