# Wednesday, 03 June 2009

I’ve been a fan of SharePoint since WSSv2 first came out.  Development on the platform wasn’t all that great though.  Things changed in a big way with WSSv3, and had I known just how easy things had become, I would have started this project a long time ago.

After being introduced to Trac a few years ago, I immediately set up a site and linked it to my private repository.  Having a wiki and source browser tied together can be immensely useful.  The one thing I’ve always had an issue with regarding Trac is how it supports documents (barely at all).  You can attach them to pages or put them in your repository, that’s it.  SharePoint, however,  was designed for document management; it just doesn’t have a way to browse a source repository.  I decided to fix that.

After fetching SharpSvn I set about figuring out how to get it integrated with SharePoint.  Eventually things came together, and I ended up with this:

wss-svn-browser

That wasn’t enough though.  I needed to be able to view those files too, and of course I wanted syntax highlighting.  I don’t remember how I found this, but it works great.  A bit more tinkering and…

wss-svn-file

Just need to do a bit of clean up and finish making the UI seamless with SharePoint.

posted on Wednesday, 03 June 2009 15:08:00 (Central Daylight Time, UTC-05:00)  #    Comments [0] Trackback
# Tuesday, 17 February 2009

So I’ve been motivated to work on Decal lately for some reason.  Maybe it was Virindi and Flynn talking about it; maybe I was just bored with my other projects.  I spent a few days on bugs here and there, hopefully fixing the vendor bug in adapter and another one with world iterators, and decide to test some of my own plugins.  Of course the biggest one is QuickBuff, since it’s the least simple, and of course it crashes horribly whenever I click start.  It seems somewhere along the line the ‘magic’ COM-thread marshaling quit working.  I’m not sure if it’s because of Vista or a recent .NET update, but either way, QB was dead.

I knew the issue was thread marshaling because the error was obvious:  COM Interface not found.  Of course I don’t want to debug this issue because I don’t really know how Mekle fixed it in the first place.  Instead I start converting everything to use the Invoke method that was already present in my framework to move all COM calls to the main thread.  After half a day of refactoring my task class everything looks good.  Until I get around to testing things.  It looks like my Invoke method isn’t working at all.

It turned out that I didn’t do enough research when I was looking up synchronization methods.  I had found and decided on the SynchronizationContext object, but the class doesn’t actually do anything.  Apparently it’s meant to be more of an example to implement a custom sync context.  After many, many false starts and even more crashes, I eventually went back to the good old Control.Invoke method.  I wanted to avoid this to keep from having a dependency on System.Windows.Forms, but aside from implementing my own sync context, I didn’t have much choice.

All said and done, this turned out to be a great batch of work.  The plugin is way faster and smoother than it was before and seemingly more stable too.  I even went ahead and implemented the adhoc/smart buffing feature, and I’m considering going forward with rebuilding the profile editor using the current view system.

I’ll do a release after I clean up the adhoc view some more, probably this weekend.

posted on Tuesday, 17 February 2009 14:58:08 (Central Standard Time, UTC-06:00)  #    Comments [0] Trackback
# Thursday, 22 January 2009

So a dev buddy popped a question in IRC the other day.  He was trying to host an ad/offer thing inside of an iframe, but the offer checked for this and redirected the top page to itself.  He had been wracking his brain trying to work around this, and it looked like an interesting problem, so I stepped up to the plate.

First we attempted to simply overwrite location.replace with an empty function.  This seemed to work on IE but did nothing on FF3.  It also became apparent that this method would fail as a subsequent refresh gave us different javascript that simply changed the location.href.  FAIL.

I did a bit of googling on the issue and stumbled across a forum post suggesting the use of onBeforeUnload on the parent page.  I played around with this idea, getting mixed results, but since there seemed like no other way, I dug a bit deeper.  I was trying to do this by hand, with no libraries, and decided to bring in a little help since I didn't care to handle all the x-browser event nonsense.  I loaded up prototype.js and reworked my code to use it.  The following emerged:

function windowUnload(evt) {
var ifr = $('ifr');

if (ifr == evt.element()) {
evt.stop();
}
}

Event.observe(window, 'unload', windowUnload);
$('ifr').observe('unload', windowUnload);

The id 'ifr' is the iframe holding the offer/ad.  This also manages to prevent any unload checks that the embedded page might popup.

Enjoy!

posted on Thursday, 22 January 2009 14:45:01 (Central Standard Time, UTC-06:00)  #    Comments [2] Trackback
# Tuesday, 04 March 2008

So we've been both working on and putting off the new view system in Decal for ages.  Checksum did a lot of work to give us something to extend, and we've been chugging along with that.  We have a couple of semi-usable controls, and a simple form/view loader.  The integration with Decal still lacks a great deal, but there's one very big problem with the system:  It's fugly.

image

Above you can see NVS or Decal.Forms in our test container.  It's not going to win any beauty pageants for some time.

We do have a powerful theme system that goes along with NVS though.  Once the controls stabilize, and we start working on performance, it shouldn't be hard to make things look great.  Of course, none of us have any artistic talent so it'll never look that good (unless we can con an artsy person into the core team).

In support of this effort (though mostly just so I can say I finally finished rewriting it) I've put some effort into reviving Portal Opus.  I had been sitting on the framework for ages now and decided a couple of days ago to go ahead and integrate Ken's DatUtils to speed up the progress (his spell table object probably saved me an entire night of coding easily).  Right now it supports all of the textures that Decal supports and loads the skill and spell tables.  I'm going to fool-proof it a bit and post an alpha in the near future.  After that, I'm going to start building a model viewer into it too.

image

posted on Tuesday, 04 March 2008 03:30:53 (Central Standard Time, UTC-06:00)  #    Comments [0] Trackback
# Thursday, 29 November 2007

So I've been working with mass archiving Office documents at work lately.  Part of this process is extracting meta data information from the files such as subject and author.  Microsoft has had a "sample" component out for a while to accomplish this:  DSOFile.  Using this component brings up COM Interop fun which I like to avoid if possible.

Having a bit of free time on my hands, I set about looking at rewriting DSOFile using C++/CLI.  This actually turned out to be pretty easy once I figured out how msclr::com::ptr worked and DSOFileNET was born.

posted on Thursday, 29 November 2007 21:55:49 (Central Standard Time, UTC-06:00)  #    Comments [0] Trackback
# Monday, 17 September 2007

The ASP.NET AJAX UpdateProgress control is rather limited.  It only shows up for UpdatePanels and then only for one at a time.  This was highly annoying, since I needed it to display for the CascadingDropDown in particular.  After a few failed attempts, I found that it is very easy to create your own control that will work for any and all requests.

The secret for this method is found in Sys.Net.WebRequestManager.  This object contains two methods:  add_invokingRequest and add_completedRequest.  Using these two events, we can set a short timeout, and using a ModalPopupExtender, show a progress alert for every background action.

var wrm = Sys.Net.WebRequestManager;

wrm.add_invokingRequest(BeginRequest);
wrm.add_completedRequest(EndReqest);

function BeginRequest(sender, args)
{
setTimeout('ShowProgress()', 800);
}

function ShowProgress()
{
// show the modal
}

function EndRequest(sender, args0
{
// hide the modal
}

I leave the rest as an exercise for the reader.

posted on Monday, 17 September 2007 16:25:15 (Central Daylight Time, UTC-05:00)  #    Comments [0] Trackback
# Tuesday, 21 August 2007

Something that I happened upon this week after reading one-to-many post saying that VSTO Add-ins can't be installed for all users under Office 2007.  I knew it worked that way under Office 2003, and they couldn't have broken compatability that much in '07.  I was determined to find a workable solution to this problem because the sheer administrative overhead of needing each user to run the install or another patch mechanism was rediculous.

First, I had to identify the major difference between '03 and '07 when dealing with VSTO:  '07 supports it natively.  In '03 all VSTO Add-ins are loaded via a generic shim and are essentially regular COM add-ins.  In '07 the add-ins are loaded directly by the Office app, ignoring the shim.  To get around this issue, you have to cause '07 to load your add-in the same way that '03 would:  as a COM-shimmed add-in.  Invoking this behavior is a simple stroke of the delete key.

Setup your installer as normal, except having all registry entries defined under HKLM instead of HKCU.  Then navigate to HKLM/Software/Microsoft/Office/[APP]/Addins/[YourAddin].  Remove the "Manifest" value from this key.  This value being missing causes '07 to load your add-in via the ProgID [YourAddin], which eventually leads it to the VSTO AddinLoader and your real add-in via the Manifest defined under your CLSID/[GUID] entry.

There is a downside to this method:  If your add-in crashes, it will take out all other add-in using the AddinLoader via Office's disabled list.

posted on Tuesday, 21 August 2007 12:38:41 (Central Daylight Time, UTC-05:00)  #    Comments [0] Trackback
# Tuesday, 06 June 2006

It's been a while since I've said anything about Decal so today I've decided to share some things about the next public release of Decal.  We've come a long way with Adapter and our new rendering code so this upcoming release will likely be the last time you guys see the old view system.  You can also expect a few other components to be completely redone and at least one to be gone forever.

There are two new features in Adapter that will be the focus of today's article.  One will make life easier for devs, the other will make things much more interesting for them.  Firstly, to make development and maintenance easier, I've added another code hook-up attribute to the system, BaseEvent.  The purpose of BaseEvent is very much like that of ControlEvent.  It works on the protected 'system' events that exist as part of PluginBase (which mostly come from ACHooks in the Decal core).  When applied to an event handler, these attributes will automatically hook up and tear down the connection to that event.

[WireUpBaseEvents]
public class Test : PluginBase
{
protected override void Startup()
{
// Network events
// this is the old way of doing it
//this.ServerDispatch += new EventHandler<NetworkMessageEventArgs>(Test_ServerDispatch);
}

[BaseEvent("ServerDispatch")]
void Test_ServerDispatch(object sender, NetworkMessageEventArgs e)
{
throw new Exception("The method or operation is not implemented.");
}

protected override void Shutdown()
{
// old tear down
//this.ServerDispatch -= this.Test_ServerDispatch;
}
}

This may not look like much since once you add the attribute, you only save one line of code.  What it does for you, is guarantee proper shutdown of all of your events.  I've found many times in my code where my tear-down code missed several events.

Now for the more interesting stuff.  Plugin devs often want to share the functionality of their plugin with others.  They also sometimes want to get information from other plugins.  This can't always be implemented to suit all (depending on language/knowledge/etc) so we've added a message notification system to Adapter to help things along.  With the next release of Decal, all Adapter plugins will be able to consume a single event "AdapterMessage", and they will be notified of all messages sent between plugins.  Sending a message is very simple as well, you just derive an object from AdapterMessageEventArgs, add in the information you want to share, and call SendAdapterMessage.

I'll talk a bit more about messages tomorrow, along with some examples on how to use it.

posted on Tuesday, 06 June 2006 09:30:53 (Central Daylight Time, UTC-05:00)  #    Comments [0] Trackback
# Friday, 09 December 2005

Brain drain's kept me from generating as much code as I'd need to start the series describing the rewrite of ACAim.  I'm slowly chugging along at it and will start posting once I'm a bit more comfortable with my progress.

posted on Friday, 09 December 2005 13:52:32 (Central Standard Time, UTC-06:00)  #    Comments [0] Trackback
# Thursday, 20 October 2005

Well,  I wanted to officially give an update on the status of my various projects.  First, Plugin Manager has been updated and works the same as before.  Second, I've started a project to redo the "engine" portion of NB2 in c#.  I'll be releasing this once it's stable as a profile-runner.  It won't have any edit functions, but at least you'll be able to use what you have.

I may continue this project as a replacement for NB2 in the future.  I haven't really decided yet how to progress on that particular matter.

Lastly for the developers, we've been working hard on getting a new and better HUD implementation, and I can honestly say we've made some progress.  Some of it more humorous than others (There should only be *3* images in the shot).

posted on Thursday, 20 October 2005 08:47:52 (Central Daylight Time, UTC-05:00)  #    Comments [1] Trackback
# Monday, 17 October 2005

Well, after much pain and suffering, mostly on Haz's part, the new HUD system is finally making progress, and since I'm in a mood, I'm going to talk a bit about how it will work in the .NET Native Framework in an upcoming alpha release.

Firstly, creating a HUD:

// hudRect defines the area of the screen on which we draw
Rectangle hudRect = new Rectangle(10, 50, 300, 16);
Decal.Adapter.Wrappers.HUD hud = Host.Huds.CreateHUD(hudRect);

Now that we have a HUD, lets make it colorful!

Color myBGColor = Color.FromArgb(64, Color.Gray);
hud.Fill(myBGColor);

This gives us a nice, mostly transparent grey background.  Lastly, we'll render some text:

hud.BeginText("Times New Roman", 16);
hud.WriteText("SomeText", Color.White);
hud.EndText();

And that's IT!  Of course there are other neat features that need to be tweaked a bit, and some issues that need to be solved, but we'll have progress or kill someone trying!  Lastly I leave you with a potential outcome of the above code, of course with some additions.

working hud

posted on Monday, 17 October 2005 23:29:40 (Central Daylight Time, UTC-05:00)  #    Comments [0] Trackback
# Wednesday, 21 September 2005

Since it's been quiet on most fronts with the alpha, our continued development, and the impending patch, I just wanted to let everyone know things are rolling along.  I've been having some trouble with my development setup the past few days that has hindered me, but I've mostly solved that as of a short while ago.  Tonight I'll be hitting the new rendering system hard, and may even have some good news or screenies by the end of the week.

Also, here's a quick overview of the status of the plugins/utilities that I maintain:

Zone Launcher -- Retired.  I did however hack up a quick version that works with the new launcher.  It apparently has a naming conflict with some other app that was announced a few days after I posted the update.  Oh well.

Plugin Manager -- Limbo.  I will be updating this as soon as I figure out how.

Mouse Wheel 2 -- Actually updated already.  It just needs to stay current with our changes.  It's also waiting on QueryKeyboardMap to work again.

AC AIM -- Planning.  I will not exactly be updating this;  I'll be completely rewriting it using the new .NET framework.  I'll also be using that time to write a series of articles detailing the development process using the new framework.

Nerfus Buffus 2 -- In Progress.  NB is broken.  Very broken.  I will be updating it, but I'm having to rewrite large chunks of it.  I don't really have an ETA other than to say it will NOT be ready when decal releases.  If time permits, I plan to do my best to have it out with in the month following decal.

posted on Wednesday, 21 September 2005 00:47:50 (Central Daylight Time, UTC-05:00)  #    Comments [1] Trackback
# Thursday, 15 September 2005

Going further into how and why we're breaking things, I'd like to take a moment to cover our protocol system.  As many of you know, we keep a huge xml file that documents the known AC protocol.  Well, in the downtime, this file has seen MASSIVE reorganization.  Ken has been kind enough to do this work almost alone.  This has included updating all of the old packets that have changed with ToD and also some much needed upgrades to the file for clarity, new features, and ease of use.  Another point in this massive upgrade, was a change in the objects plugins use to access protocol information:  IMessage[2] and IMessageMember.

NB2 is a heavy user of protocol information.  Even though it uses filters, there is still quite a bit of parsing that occurs.  The usual method for updating a plugins protocol functions tends to only involve changing the packet type or renaming a few fields.  This time around however, many, many packets were renumbered, and with Ken's hard work, probably 3/4 of the fields have been renamed.  Then comes the kicker, with the changes to IMessage the Member method no longer exists.  This means NB2 won't even compile until I replace all of the calls to the proper replacements.  Then I have to go back to changing the numbers and field names.  One last fun bit is the inclusion of many new "types" in the protocol.  This means that anyone parsing data might have to add some extra calls in their code.  That may seem annoying at first, but it makes much more sense with the changes.

Another, but slightly less annoying, change keeping it down is the removal of several methods from IPluginSite.  Any function that in the past used a memloc in PluginSite has been removed and is now only found in ACHooks.  Well, NB2 is old enough that ACHooks was still rather young, and didn't get used much.  These changes are generally not very difficult.

Next time we'll cover either the new .NET Plugin Framework or what will eventually be Decal's new rendering engine (depending on how far into it I get).

posted on Thursday, 15 September 2005 00:38:05 (Central Daylight Time, UTC-05:00)  #    Comments [0] Trackback
# Monday, 12 September 2005

So many of you know that we've been "fixing" Decal lately.  Some of you are also aware that we've broken compat with the old version.  What very few know, beyond those of us doing the work, is just how extensive this breakage has been.  I'll try to further explain the damage we've done, starting with a history lesson.

In Decal 1.x, there were about 4 modules:  DenAgent, Inject, DecalNet, and DecalControls.  DenAgent is the familiar windows gui everyone uses to configure their plugins.  DecalControls is obviously the home for all of the buttons decal shows in-game.  DecalNet is our network parser.  That leaves behind Inject.  While the name implies that it might have something to do with injecting the Decal code into AC, that's only a fraction of what it did.  Inject *WAS* Decal.  It handled all of the hooking, all of the rendering, all of the input.  Every interaction except reading packets passed through Inject in some way.

When Cibo came back and gave us his vision of Decal2, we gained a few more modules:  Decal, DecalFilters, and DecalInput.  The idea here was to shift core functionality away from Inject and into Decal.  For plugins and filters this happened about 50%.  Decal now started and stopped "services" which loaded the plugins and filters.  Unfortunately, Inject kept a tight grasp on the Rendering and Input code.  Even though we now had a module named DecalInput, it only contained services to let plugins generate input, it didn't help process input from AC at all.

So this is where we arrive.  We've tried through the years to patch functionality into this model with out breaking it.  We have so much legacy code and cross referenced crap to maintain most of us babble code non-sense in our sleep.  Finally ToD has given us a chance to fix all of that.  With the massive changes to AC's rendering engine, our graphics code died.  We've hacked together a temp solution so that we can get the rest of decal working, but we have grand plans indeed for a new one.  We've also taken several more functions away from Inject, and will continue to do so until it does little more than... well inject.

Next we'll go over some of the more specific things that have been changed, or maybe give a little more insight into the depths of Decal.

posted on Monday, 12 September 2005 17:05:26 (Central Daylight Time, UTC-05:00)  #    Comments [0] Trackback