I'm interested in helping out in any way I can with MUSHclient's development, is there anything needing doing that I could tackle as a newcomer to the MUSHclient codebase? On that train of thought, do you have an SVN or Git repository where one could get the bleeding-edge code?
Twisol said: On that train of thought, do you have an SVN or Git repository where one could get the bleeding-edge code?
I was maintaining a bzr repository for a bit with the releases, but as there was basically no interest in it I stopped. Even so, it was more of a source mirror with history than a container for the most recent code.
If you actually want to play with the C++ code, the very first requirement would be, being able to compile it yourself. I know it can be done, there was a recent post about that, and I am happy to help with any minor problems you have getting it set up.
However to do that you need the MS compiler, and not the free one either, because it uses MFC which they don't give away.
As for the bleeding edge source - it isn't that exciting I am afraid. Basically it is the source for version 4.43 with the extra stuff added for the change to allow you to edit script files slightly differently.
I am not operating a SVN repository that is publicly available, I use CVS here on a private server.
If you have trouble merging the patches with the last full release I can make up another full release if that helps.
Your offer is appreciated, however right now I don't have a big list of changes to the core client. Most enhancements these days are being done as plugins (and I am exploring ways of improving those, basically by just smartening up the plugins themselves).
If you are able to compile the source, and are reasonably comfortable with how it is organized, perhaps get back with a specific suggestion, like "would you like me to add feature X?" and we can talk about it.
Yeah, I was the one recently who asked about compiling the source. I can compile it fine (I'm using Visual Studio 2005), in fact I've been tinkering with minor behavioral tweaks just to see how it works. A minor issue I recently had was that using DoAfter* functions when you're disconnected won't work as you'd expect, because the created timers don't have the "Active when disconnected" option. I've been making little changes in the CMUSHclientDoc::DoAfterSpecial code to see how I can modify it without breaking existing functionality - if you're interesting in what I come up with, I'd be glad to let you know.
Also, if you'd like me to maintain a VS2005 project file, I could do that too.
I'm having a problem with my source compilation, where when I disconnect from the server by any means, MUSHclient crashes hard during a call to _vscprintf(). One of the stack frames shows this line of code:
FormatV(lpszFormat, argList);
// (The arguments in this stack frame show:
// lpszFormat: "--- Connected for %i day%s, %i hour%s, %i minute%s, %i second%s. ---"
// argList: ""
No idea what's going on here...
Full stack trace:
> msvcr80d.dll!_output_l(_iobuf * stream=0x0012f4c4, const char * format=0x00af2187, localeinfo_struct * plocinfo=0x00000000, char * argptr=0x0012f7dc) Line 1648 + 0x1f bytes C++
msvcr80d.dll!_vscprintf_helper(int (_iobuf *, const char *, localeinfo_struct *, char *)* outfn=0x65182820, const char * format=0x00af2148, localeinfo_struct * plocinfo=0x00000000, char * ap=0x0012f7bc) Line 405 + 0x13 bytes C
msvcr80d.dll!_vscprintf(const char * format=0x00af2148, char * ap=0x0012f7bc) Line 414 + 0x14 bytes C
mfc80d.dll!ATL::ChTraitsCRT<char>::GetFormattedLength(const char * pszFormat=0x00af2148, char * args=0x0012f7bc) Line 473 + 0xe bytes C++
mfc80d.dll!ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > >::FormatV(const char * pszFormat=0x00af2148, char * args=0x0012f7bc) Line 2142 + 0xd bytes C++
MUSHclient.exe!CFormat::CFormat(const char * lpszFormat=0x00af2148, char * argList=0x0012f7bc) Line 42 + 0x13 bytes C++
MUSHclient.exe!TFormat(const char * sFormat=0x00af2148, ...) Line 2835 + 0x16 bytes C++
MUSHclient.exe!CWorldSocket::OnClose(int nErrorCode=0) Line 145 + 0x108 bytes C++
mfc80d.dll!CAsyncSocket::DoCallBack(unsigned int wParam=584, long lParam=32) Line 639 C++
mfc80d.dll!CSocket::ProcessAuxQueue() Line 919 C++
mfc80d.dll!CSocketWnd::OnSocketNotify(unsigned int wParam=584, long lParam=32) Line 1242 C++
mfc80d.dll!CWnd::OnWndMsg(unsigned int message=883, unsigned int wParam=584, long lParam=32, long * pResult=0x0012fc60) Line 2004 + 0x11 bytes C++
mfc80d.dll!CWnd::WindowProc(unsigned int message=883, unsigned int wParam=584, long lParam=32) Line 1741 + 0x20 bytes C++
mfc80d.dll!AfxCallWndProc(CWnd * pWnd=0x040efa90, HWND__ * hWnd=0x00f60e42, unsigned int nMsg=883, unsigned int wParam=584, long lParam=32) Line 240 + 0x1c bytes C++
mfc80d.dll!AfxWndProc(HWND__ * hWnd=0x00f60e42, unsigned int nMsg=883, unsigned int wParam=584, long lParam=32) Line 389 C++
mfc80d.dll!AfxWndProcBase(HWND__ * hWnd=0x00f60e42, unsigned int nMsg=883, unsigned int wParam=584, long lParam=32) Line 411 + 0x15 bytes C++
user32.dll!77351a10()
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]
user32.dll!77351ae8()
user32.dll!77351a91()
user32.dll!77352a47()
user32.dll!77343c8a()
mfc80d.dll!AfxInternalPumpMessage() Line 183 C++
mfc80d.dll!CWinThread::PumpMessage() Line 896 C++
mfc80d.dll!CWinThread::Run() Line 625 + 0xd bytes C++
mfc80d.dll!CWinApp::Run() Line 894 C++
mfc80d.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00d23e6e, int nCmdShow=1) Line 47 + 0xd bytes C++
MUSHclient.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00d23e6e, int nCmdShow=1) Line 33 C++
MUSHclient.exe!__tmainCRTStartup() Line 589 + 0x35 bytes C
MUSHclient.exe!WinMainCRTStartup() Line 414 C
kernel32.dll!776b3823()
ntdll.dll!77a7a9bd()
MUSHclient.exe!CChatSocket::Process_File_start(const ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > > strMessage="RèÌüÿƒÄˆ…küÿÿ‹ôtüÿÿÿÐŒµ") Line 1183 + 0x38 bytes C++
MUSHclient.exe!CMUSHclientDoc::FixSendText(const ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > > strSource=<Bad Ptr>, const int iSendTo=361582797, const t_regexp * regexp=0x006d009c, const char * sLanguage=0xf62183e8, const bool bMakeWildcardsLower=true, const bool bExpandVariables=true, const bool bExpandWildcards=true, const bool bFixRegexps=false, const bool bIsRegexp=true, const bool bThrowExceptions=true) Line 1303 + 0xe bytes C++
fff5ef75()
The simplest way of sharing code is to send me, or post here, context diffs. I do that for showing changes from one version to the next. I do it from CVS, but basically you do a diff -c naming the old file and the new file (or whole directories).
The DoAfter fix is a good idea, I think.
As for the crash, is this related to using chat? I see this in the backtrace:
No, all I had to do to reliably get the crash is start MUSHclient, have a world connect to anything (Achaea in this case), then disconnect. No chat involved. The crash doesn't occur in my 'live' version.
I believe the only changes I made were the fixes between our versions of Visual Studio, which I posted in that initial thread about compiling. I'll download the most recent codebase and try again.
For what it's worth, I have a preference for releasing the source as a full archive, and not a diff, so that it's easy to get the whole, correct version of a given release. Also, the diff/patch tools tend to get kind of confused when the diffs or the files being diffed are in Windows line-ending format -- I had no end of trouble with that when I was maintaining the bzr repository. (Then again, I was doing that on Linux, so that could be it...)
All I can suggest for now is to try making a test of the offending line, by putting somewhere near the start of MUSHclient (like in InitInstance), lines like this:
If you've merged in the changes I made from my last thread by then, is there any chance you could zip up the 4.43 source? It would save me some time fixing the code again to compile under VS2005.
I, too, would love to see a full archive with each release of the source code. The diffs are much less convenient and have actually failed for me in a few instances, mostly because of the binary files.
It would be REALLY great to get an archive with projects for VS2005 and/or VS2008, since the newer versions of VS don't open and convert the old workspaces well at all. Best I could come up with was to track down all intermediate versions of VS between 6.0 and 2008 to convert the workspace in a sort of cascading method, and that's not very ideal. Failing that, though, we have to make a brand new project and fiddle with a lot of things until it finally compiles... and maybe it'll run.
I've been using the MUSHclient code as a great reference for things I'm working on myself, so I'd really like to take this opportunity to just thank you, Nick, for all the work you've done on this and for sharing it all with us! Thanks!
Alright... With a fresh codebase, and after re-following the original compiling-from-source thread, I re-tested by running MUSH, connecting, and disconnecting, and.... it crashed.
Just an update (as I see we still have a week to go before you're back ;) ), but I've been trying to get it to work properly with no success. I also tried compiling a Release build, but that died at the linker stage because of some duplicate-definition problem with a __PreCom__ identifier, in accelerators.cpp.
Any advice from anyone would be appreciated. I'm excited to hack around in the source, but it's hard to do that when everything's unstable.
In the interest of getting at least one helpful fix in, I commented out the offending TString() call so I could at least test my changes. The only line I changed is in methods.cpp, within the body of CMUSHclientDoc::DoAfterSpecial():
timer_item->bActiveWhenClosed = !IsConnected();
The !IsConnected() value will cause DoAfter()s made while disconnected to fire properly, yet maintain the previous behavior of DoAfter()s made while connected. This might not be the best way to make this change, but it does work to solve the problem I had initially mentioned.
If that code is from where I think it is, I would just change it to:
timer_item->bActiveWhenClosed = true;
Otherwise, it is likely to cause unintended effects, that if the DoAfter is done when you are not connected, it won't fire if it switches to when you are connected. (For example, you might want to save the world file every hour, connected or not).
*nod* My change was intended to maintain compatibility (where timers created while connected wouldn't actually fire when disconnected), but if you think it would be beneficial to make DoAfter timers work always, then I have no further reservations. :)
I had a look at what it would take to get the latest Visual Studio. Apart from the cost of about $US 199, which I don't particularly want to pay, there is a 6 Gb download. This seems ridiculous to me, to have to download 6 Gb to get a C++ compiler. Previously the Visual Studio I had fitted on a single CDROM.
I thought someone had got MUSHclient to work under Visual Studio 2005, or whatever it is called?
I had MUSHclient somewhat working under Visual Studio 2005, after converting the workspace and fixing up the projects to compile with the newer options. Some of that broke down when things like DirectSound and SQLite were added, mostly because I haven't taken the time to make it work again.
I'm using the source now as a reference for my own sort of client, which I'm developing using Visual Studio 2008. I decided to use 2008 to gain access to the new MFC Feature Pack, with the Office 2007 look-and-feel and all that fun stuff.
It would still be very nice to have a copy of MUSHclient that runs under 2005 or 2008, just for doing run-time comparisons and tracing through the functions and variables in the debugger.
@Nick - Well, Visual Studio these days is packed (you might even say bloated) with extra tools and features, which might account for the size... I can't blame you at all, though!
@Larkin - Did you ever have a problem with MUSHclient where disconnecting would crash MUSH within a GetFormatLength() call? I haven't been able to figure out what in the world is going on.
Tried it out with the above source dump, and also converted the project file properly (having converted the line endings first). That weird crash still persists. I have no idea what's causing it.
I SOLVED IT!!!!!!!! Excuse the excess, but holy cow, this was annoying.
Basically, in the newer MFC, it seems that CTimeSpan's get*() methods return a LONGLONG type - a 64-bit int. The format specifier, however, expects a relatively measly long (32-bit). This type mismatch corrupts the rest of the arguments, because the va_arg() call retrieves only 32 bits, when the argument is actually 64 bits.
After a LOT of debugging to figure this out - I will have a lifelong hatred of varargs because of this! - it's as simple as casting the ts.Get*() return values to longs.
The above code is in worldsock.cpp, in the CWorldSocket::OnClose method.
EDIT: As you can see from this cached page[1], all of the Get*() functions utilized in that code return 'int's, except for GetDays() which is a long. No wonder it worked flawlessly in VC6.
In the time since I fixed the disconnecting crash, I wrote some new functionality into my local MUSHclient build. I don't know if anyone else cares about it (although I know at least one person who inspired me to write it), but I've added functionality to store MUSHclient arrays between sessions.
This means that if I run the following code, save the world, and restart MUSHclient, the array will be loaded right back into the world data just as before:
ArrayCreate("foo")
ArraySet("foo", "42", "It's the Answer")
ArraySet("foo", "43", "It's the Answer, Plus One")
It's saved with the following XML format:
<arrays
muclient_version="4.40"
world_file_version="15"
date_saved="2009-10-09 01:49:48"
>
<array name="foo">
<key name="42">It's the Answer</key>
<key name="43">It's the Answer, Plus One</key>
</array>
</arrays>
If anyone's interested please let me know, I'd be glad to post the sources. (Also, I'm sure I missed something or could have done it better, so I'd be glad to have a critical eye scan over it as well.)
Last question for a while, hopefully... How do I edit the MUSHclient resources? I'm trying to add a new identifier IDC_ARRAYS (for the Import XML dialog) but I can't figure out where to set it up.
After a LOT of debugging to figure this out - I will have a lifelong hatred of varargs because of this! - it's as simple as casting the ts.Get*() return values to longs.
The above code is in worldsock.cpp, in the CWorldSocket::OnClose method.
EDIT: As you can see from this cached page[1], all of the Get*() functions utilized in that code return 'int's, except for GetDays() which is a long. No wonder it worked flawlessly in VC6.
Yes, they must have changed that definition since my version. Shows how subtle changes can screw you up.
Well done for finding that. I must admit when it crashes on TFormat or CFormat I look for accidentally using a CString without casting it (eg. (LPCTSTR) mystring), however since that particular case didn't use strings I didn't mention it.
I have amended the official source to incorporate that change, to save future problems. Also the DoAfter change you mentioned (changing DoAfter to always work that is).
Thanks! Are you interested in the changes for the array saving/loading perhaps? And if I wanted to edit a dialog and add/remove a control, how would I do that?
How should I go about getting the diff files to you?
EDIT: Okay, I've generated a diff file. I was using WinMerge, but its patch creator gave infinite context around changes instead of just three lines. The main things it contains are:
1) Changes to allow the source to compile under VS2005, back when this whole thing started. I think you more or less have all of these.
2) The DoAfter fix and TFormat() casting fix. I'm positive you already have these but I'm including them for completeness.
3) The array serialization code. This is the bulk of the patch; I'm working on adding an arrays option to the Import XML dialog right now, but for now the patch ignores arrays there. It should save/load in the world and in plugins, though.
I understand that you have full authority over which changes get merged into the official source. However, it would be much appreciated - regardless of the eventual usage of the changes - to have some feedback on the changes themselves. Did I miss anything important?
Hi Nick, did you perhaps overlook my above post from a couple days ago? Just checking in; if it was a more complex question I'd've waited longer to bother you again.
Hmm, that just contains 'en.dll'. I'm still unable to find exactly where the visual dialog controls and such are set up and created. 'resource.h' #defines the various identifiers used to refer to the resources, but I can't find the actual .rc that creates them.
***************
*** 47,53 ****
// lines of code and more reliable than turning on SS_NOTIFY in OnCtlColor
// because Windows doesn't send WM_CTLCOLOR to bitmap static controls.
//
! UINT CStaticLink::OnNcHitTest(CPoint point)
{
return HTCLIENT;
}
--- 47,53 ----
// lines of code and more reliable than turning on SS_NOTIFY in OnCtlColor
// because Windows doesn't send WM_CTLCOLOR to bitmap static controls.
//
! LRESULT CStaticLink::OnNcHitTest(CPoint point)
{
return HTCLIENT;
}
However I had already changed it back (to the current state), see this post:
Hmm, that just contains 'en.dll'. I'm still unable to find exactly where the visual dialog controls and such are set up and created. 'resource.h' #defines the various identifiers used to refer to the resources, but I can't find the actual .rc that creates them.
Hmm, that just contains 'en.dll'. I'm still unable to find exactly where the visual dialog controls and such are set up and created. 'resource.h' #defines the various identifiers used to refer to the resources, but I can't find the actual .rc that creates them.
EDIT (later that night): I modified the resources to add a control to the Import XML dialog, and made further changes to the actual source to support the change. I'll be sending you this patch as well once I put together the diffs.
(Please let me know if I'm stepping on your toes or anything else at all. I'm just excited to be contributing!)