Archive for the ‘EVE Online’ Category

Using EVEMon Data with LINQPad

Saturday, July 31st, 2010

LINQPad is an awesome aide to .NET Developers. Written by Joseph Albahari of LinqBridge and the C# In a Nutshell series fame. LINQPad allows the developer to write, compile and run C# or VB.NET Expressions, Statements of Programs outside of Visual Studio.

Everything I am going to show you in this post can be done with Visual Studio simply by wrapping the text in a new console application, and adding references to the DLLs. However I strongly encourage you to download LINQPad and give it a go.

In the event you are using 64-bit windows and are still using LINQPad 2 you will need to download the x86 version of LINQPad 2, as all of the EVEMon assemblies are compiled for x86. If you have LINQPad 4 you don’t need to worry about.

Assuming you have EVEMon installed, the first step is to load the EVEMon.Common.dll assembly into LINQPad:

  1. Go ahead and fire up LINQPad ensure you have a new query window open
  2. Press F4 (Query -> Query Properties).
  3. Click the “Browse…” button at the bottom of the properties window.
  4. Navigate to the EVEMon install directory.
  5. Select “EVEMon.Common.dll”

While you have “Query Properties” open go to the “Additional Namespace Import” tab and add the following two lines:

EVEMon.Common.Data
EVEMon.Common

EVEMon.Common was designed to work as part of a long running process, namely the EVEMon application sitting in your system tray from when you turn your computer on until you turn it off, as such we need load the static data from the data files.

EveClient.Initialize();

Now we get to do some LINQ,

var allItems = from item in StaticItems.AllItems
	       where item.Family == ItemFamily.Ship
	       select new
	       {
	           item.Name,
	           item.Race,
	           CPU = item.Properties[DBConstants.CPUOutputPropertyID].Value.Value,
	           PG = item.Properties[DBConstants.PGOutputPropertyID].Value.Value,
	           item.Description
	       };

I could start to explain the above line by line, but there are lots of really good LINQ articles on the Internet, including one by Joseph Albahari. We will just say that the above pulls all of the ships out of EVEMon’s Items data file and selects the Name, Race, CPU, PowerGrid and Description property for each one.

Now we see my favorite aspect of LINQPad, the .Dump() extension method, simply running the following command:

allItems.Dump();

Will output the data we have just queried as a nice HTML Table:

That is all I have for you for now, I am working on a project that uses this data outside of EVEMon, keep an eye on Twitter where I will hopefully be providing a link for testing in the not too far distant future.

Tracing A Method Signature

Friday, July 16th, 2010

Over the past three weeks I have discovered that many performance problems with Windows Forms applications are down to certain events being fired very rapidly, usually these are down to layout operations being triggered by updates to controls.

Without the use of RedGate Software’s excellent performance profiler I have been forced back into the habit of temporarily peppering the code I suspect of being a problem with trace messages.

For a while I was quite disorganised using trace messages such as “Entered SoAndSoMethod”, “OnSomeEvent Triggered”, etc. Over time I have settled into using the declaring class and method name to identify which method was being called.

Thinking about it today I decided this was still too much work (yeah, I am that lazy), I wondered if System.Reflection could help me:

public static void Trace()
{
    var stackTrace = new StackTrace();
    var frame = stackTrace.GetFrame(1);
    var method = frame.GetMethod();
    var parameters = FormatParameters(method.GetParameters());
    var declaringType = method.DeclaringType.ToString().Replace("EVEMon.", String.Empty);
 
    Trace("{0}.{1}({2})", declaringType, method.Name, parameters);
}
private static string FormatParameters(ParameterInfo[] parameters)
{
    var paramDetail = new StringBuilder();
 
    foreach (var param in parameters)
    {
        if (paramDetail.Length != 0)
            paramDetail.Append(", ");
 
        paramDetail.AppendFormat("{0} {1}", param.GetType().Name, param.Name);
    }
 
    return paramDetail.ToString();
}

This means that with liberal application of:

EveClient.Trace();

Will output the following to the trace:

0d 0h 00m 03s > CharacterMonitor.OnLoad(ParameterInfo e)
0d 0h 00m 03s > CharacterMonitor.multiPanel_SelectionChange(ParameterInfo sender, ParameterInfo e)
0d 0h 00m 03s > CharacterMonitor.multiPanel_SelectionChange(ParameterInfo sender, ParameterInfo e)

Hopefully that will save a few seconds here and there. It is a shame that reflection can’t get the actual values of the parameters from the frame, as that would be even more useful.

Preventing the PictureBox control from locking files

Sunday, February 28th, 2010

One of our more regular contributors to EVEMon posted on our forums showing that the application was incapable of updating cached files (specifically images), after a bit testing I discovered the following Exception was being thrown when trying to overwrite the file in question:

System.IO.IOException: The process cannot access the file 'path\filename' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite)
   at System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite)
   at EVEMon.Common.FileHelper.OverwriteOrWarnTheUser(String srcFileName, String destFileName) in EVEMon.Common\FileHelper.cs:line 108
   at EVEMon.Common.FileHelper.OverwriteOrWarnTheUser(String destFileName, Func`2 writeContentFunc) in EVEMon.Common\FileHelper.cs:line 82
   at EVEMon.Common.Controls.CharacterPortrait.SavePortraitToCache(Image newImage) in EVEMon.Common\Controls\CharacterPortrait.cs:line 248

After a bit of searching around I discovered a post on StackOverflow identifying that System.Drawing.Bitmap(string filename) would lock the filename until the Bitmap was disposed of. The post presented a solution but no code, A bit of further searching confirmed my expectation that Image.FromFile(string filename) was subject to the same locking behaviour:

The file remains locked until the Image is disposed.

A bit more searching identified another post on StackOverflow which gave me the basic syntax and structure for the code I was going to need to implement this in EVEMon. The final code looks like this:

MemoryStream stream = new MemoryStream();
 
byte[] imageBytes = File.ReadAllBytes(cacheFileName);
stream.Write(imageBytes, 0, imageBytes.Length);
stream.Position = 0;
 
var image = Image.FromStream(stream);
return image;

It appears that GDI+ will lock any image that is loaded into a control in WinForms and WPF, several comments on StackOverflow and byte.com suggested that even disposing of the control and the FileStream was not a reliable way of being able to write to the file so the above method is seems to be be the best solution all round.

Debugging “Just My Code”

Saturday, December 5th, 2009

Within EVEMon we have started making heavy use of LINQBridge which uses Visual Studio 2008′s Multi-Targeting capabilities to allow a .NET 2.0 applications to use the compiler functionality of C# 3.0. This reduces our need to push EVEMon towards .NET 3.5, and simplifies our dependency stack for the end user (.NET 2.0 is pre-installed on Vista and above, .NET 3.5 is pre-installed in Windows 7 and above).

One of the annoyances I have run into is every time there is a problem with a LINQ statement the debugger will stop in the LINQBridge project rather than EVEMon’s code; this usually tells you nothing useful forcing you to dig into the exception to find the stack trace to find out which line caused the exception.

I found a natty attribute in DebuggerNonUserCode that allows you to tell the debugger to treat a class as Non-User Code:

[System.Diagnostics.DebuggerNonUserCode]

So far, I have not found a disadvantage in doing this. I am being conservative with my use in case I find some glaring problem, however LINQBridge has proven a stable project, and quite frankly I would much rather be looking at my own broken code when something goes wrong, rather than LINQBridges working code.

Long time no blog…

Saturday, October 10th, 2009

I had been intending to post up all sorts of bits of news about life, driving, programming and cats but it didn’t happen. I have been busy which is good, however it doesn’t leave very much room for blogging. This post is going to be one really quick catch up entry to try and get me back into the swing of it.

I finally passed my driving test at the beginning of the summer, it was my fourth try and I passed with three minors which was a great feeling… since then I have driven once, as part of PassPlus, which didn’t really feel vastly different, although it was more enjoyable knowing that I didn’t have a test coming up. Catherine and I have decided to wait for a bit before we get a car so we can assess what Catherine will need in terms of model and adaptations in a car to allow her to get the most out of it.

Zoe and KerrySadly Kerry, Zoe’s sister died a few months after Zoe, as a family we weren’t ready to lose her, although it wouldn’t have been fair to let her suffer an operation that might not help anyway, so my parents decided it was best to have her put down. My brother and I got a chance to say good bye to her, she wasn’t her normal self and was in a lot of pain. We are all very sad.

In programming land I spent last weekend learning SQL Server Integration Services and this weekend I plan to get into Analysis Services. Have been doing some utility programming at work to automate some of the file server operations we do, I am trying to automate as much as possible using something similar to duck tape programming to free me up to do more programming to create a more unified and friendly framework for managing the school network. Started using CodeRush Xpress both at home and at work.

In sys. admin world I have been continuing to use and learn Windows 7, I now have RTM installed at work still waiting for RTM to arrive at home on or around the 22nd. Been reading and listening to various resources surrounding Windows 2008 R2 particularly some excellent podcasts on RunAs radio.

Fixing EVEMon’s Crashy C++ DLLs

Saturday, April 18th, 2009

I have been working on EVEMon for about two months now, taking on the responsibility of committing changes to the trunk, fixing bugs and adding new features. As a project I have been involved for several years submitting bug fixes and little features, it was down to my experiences with EVEMon that I decided to implement Subversion and Trac at work.

Unfortunately the first time it came to me to be responsible for a release, it seemed to go terribly wrong. The updated installer worked fine, and it seemed initially there were no problems with the updated code base. However BattleClinic shortly went a little mad with bug reports similar to this one:

EVEMon Version: 1.2.7.1283
.NET Runtime Version: 2.0.50727.1434
Operating System: Microsoft Windows NT 6.0.6001 Service Pack 1
Executable Path: “C:\Program Files\EVEMon\EVEMon.exe”

System.IO.FileLoadException: Could not load file or assembly ‘lgLCDNETWrapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null’ or one of its dependencies. The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log for more detail. (Exception from HRESULT: 0x800736B1)
File name: ‘lgLCDNETWrapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null’ —> System.Runtime.InteropServices.COMException (0x800736B1): The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log for more detail. (Exception from HRESULT: 0x800736B1)
at EVEMon.LogitechG15.Lcdisplay.Dispose(Boolean bDisposing)
at EVEMon.LogitechG15.Lcdisplay.Finalize() in D:\EVEMon\EveMon.LogitechG15\Lcdisplay.cs:line 70

For those who are not familiar the above is the crash report generated by EVEMon when a .NET exception is unhandled. lgLCDNETWrapper is the C++ library EVEMon uses to communicate with the Logitech G15. A similar error was generated for EVEMons other C++ component the window relocator.

Tonto Auri quickly spotted that the problem was something to do with the re-compiled C++ DLLs and switching the new DLLs with those from an older package resolved the problems. Whilst this was a fix, I wasn’t willing to just revert the changes and give up on the changes we had made to the G15 library, additionally I was concerned that we had not made changes to the window relocation code and that was causing at least one person a problem.

Quite a bit of searching about with Google and Stack Overflow resulting in finding these two little gems of information:

These two posts basically gave me the tools and the knowledge to fix EVEMon’s problems.

First I made the sudden (and “facepalm”) realization that EVEMon deployed the Visual Studio 2005 Redistributable; we had moved to Visual Studio 2008 SP1 about a month before the release of 1.2.7. I confirmed this with the Dependency Walker utility, by walking lgLCDNETWrapper.dll I was able to confirm that version 9.0.21022.8 of the Microsoft CRT Library (Microsoft.VC90.CRT) would be required.

The next trick was figuring out which re-distributables to deploy with EVEMon to ensure the end user would have all the dependencies required to use all of the features; frustratingly it seems that Microsoft only bundles the latest version of the re-distributables with Visual Studio 2008 and that was version 9.0.30729.1 which was not going to cut it.

Enter Nuonsofts excellent article providing a step by step guide on adding the required compiler flags to ensure the latest version of the CRT was bound. I did find a nice GUI resource editor that was capable of getting the manifests out in XN Resource Editor which made the process a little faster.

A little bit of hacking later the updated Visual Studio 2008 SP1 CRT DLLs and manifest file were deployed to the Microsoft.VC90.CRT folder within the EVEMon program files directory as the VC80 CRT libraries were in the past and the two C++ projects were setup to bind to the latest version with the _BIND_TO_CURRENT_CRT_VERSION=1 preprocessor definition.

A bit more poking arround with XN Resource Editor and Dependency Walker showed we were now in a far better position to have a working copy of EVEMon in the hands of our end users.

Learn a Little More About Richard Slater

Saturday, December 13th, 2008

Graeme Arthur tagged me, normally I hate these things but this is kind of a reverse chain letter… sort of… maybe if i re-write the rules slightly.

Rules:

  • Link to the original tagger(s), and list these rules on my blog.
  • Share 7 facts about myself in the post – some random, some weird.
  • Tag 7 people at the end of your post by leaving their names and the links to their blogs.
  • Let them know they’ve been tagged by leaving a comment on their blogs and/or Twitter.

7 Facts About Me:

  1. At the time of writing I have been alive for approximately 871 million seconds.
  2. I first started programming (in Spectrum BASIC) at about the age of 8 since then I have coded projects in Visual Basic, Pascal, C/C++, Java, Ada, PHP and C#.
  3. I have played EVE Online for almost five years now, have been playing less often of late however I still get to enjoy the time I do spend in EVE, although it is getting increasingly more and more lonely in space.
  4. I have been learning about Sharepoint over the past few weeks, I have already completed most of the Microsoft e-Learning on the topic and read several blogs, I recently signed up to the Sharepoint User Group UK.
  5. I wrote my dissertation on the future of MMOGs, I disagree with a good proportion of what I wrote, however it was one of the most enjoyable parts of my Degree.
  6. I type at between 40 and 60 words per minute, it has taken me 5 minutes to get to 300 words in this blog post, some of them however were copied and pasted from Graeme’s post.
  7. Like Graeme I also play bass (albeit I play badly) and dabble in live PA, although I don’t really enjoy the later any more.

7 people to tag:

  1. Catherine over at I Married You
  2. Haly over at Halycopter
  3. Tim over at Thoughts of a musing pedant
  4. CrazyKinux over at CrazyKinux’s Musing
  5. Winterblink over at winterblink.com
  6. James Glass over at Outthere
  7. Peter Arthur over at Robotii

I know the last two were on Graeme’s list, however I honestly can’t think of anyone who would appreciate it most of the blogs I read are a strictly one way thing. I was tempted to link JoCo, Felicia Day and Mark Russinovich – however I really don’t think they would appreciate it.

Nate Combs on “Security” as an resource

Monday, September 17th, 2007

Nate Combs has again posted on Terra Nova about what makes rare minerals rare. Nate makes the very good point; that rare minerals are not as scarce as the name might suggest. It is well worth a read as his his personal “scratchpad”.

Economics of Virtual Worlds

Tuesday, September 11th, 2007

I have been thinking about the economics of Online Games (specificly MMORPGs) for some time. Most of my interest comes from writing my undergraduate dissertation which was more of an overview of the future of MMOGs than any specific focus. Lately, and most importantly with EVE Online, economics has shot into the public eye.

First CCP Employed an Economist, Dr. Eyjólfur Guðmundsson, which as it turns out is probably the first time an Economist has been employed to study and create reports based upon an ingame economy. Dr Guðmundsson has already posted a blog item about the Mineral Market in EVE Online although he describes it himself as more of a “statistical overview” than an in-depth study.

I am certainly not alone in my interest in Virtual World Economics as there is at least one “research network” who actively post about research found on the internet and in acedemia. A good number of posts over the past few years over at Terra Nova have considered the implications of applying real world economic principals to Virtual Worlds, Edward Castronova wrote a book about them, of which I have a copy which I still haven’t read.

The thing that facinates me most is probably they way you can maniuplate a virtual world’s market and not get sent to prison for it. You can collude with other players to fix prices buy up entire stocks of a particular item only to put it back on the market again at an artificially inflated rate! I am sure that people reading this who play EVE would say that that is unfair or even worthy of outwrite wrath. However who is to say that it is a bad thing? it all leads on to the Good vs. Evil argument and the question “is it wrong to do something in a virtual world just because it is wrong in the real world?”

So what does the future hold for virtual economys, well I can see lots of research comming from big university’s… I mean why wouldn’t they, if an economy such as EVE Online’s can act so much like that of the real world why not use it as a economic study. I also expect real world corporations to start accepting virtual economy “experence” as a creadable experence for job applicants. This has already started happening with MDs and CEOs of small technology companies getting the job because of past leadership experence within World of Warcraft.

Fogot to Blog

Friday, September 2nd, 2005

All the mad hat stuff going on arround here and I have been forgetting to blog, that said before this weekend there was virtualy nothing to blog about!

OK… will start from last Thursday, headed off to RiverCamp at about 10:30. For those that don’t know I am a Christian, I go to a church and count myself as part of an church organisation called Elim (Elim Foursquare Gospel Alliance technicaly) and RiverCamp is our yearly prayer, worship and teaching event. Jon and Carol Arnott were doing most of the teaching this year, which was great for the most part, even though I missed the teaching that you would get at Spring Harvest or similar. All in all it was a really great weekend I feel that RiverCamp is still very young and very much in its infancy but it is growning up fast, huge future ahead of us I am sure.

It seems to be all change season in Radio land, Hitch has left EVE-Radio, it wasn’t a huge surprise as Hitch is one of the more mature (as in responsable) DJs and it seems that there are certain members of E-R management and community who do not agree with his point of view, to the point of totaly annialating his farewell posts and banning his account. All is not lost however as Hitch is going to be creating some more THH Pod Casts, which is much better, because I can listen to them when I have time rather than having to stop listening half way through because I have to do some work or get some much needed sleep. In local radio land Juice FM‘s Brooksy is leaving the morning slot and moving up ‘t north, according to the Argus he is being suceeded by Terry Garagan… do do doo doo do do doo do, do do doo do doo da da, do do do doo do doo doo doo, Last Bus To Whitehawk.