Utility Library


I've decided it's about time to take the various helper/utility classes that I've posted on the site and put them together (along with a couple new ones) into a library, which I've named CUL (Craig's Utility Library). The library contains items for:

  • Compression
  • Encryption
  • Image Manipulation
  • HTML and CSS file manipulation
  • RSS
  • SQL
  • VCalendar
  • VCard

And a couple other items. The big items that I've added that aren't found on the blog thus far are in the area of encryption (since my AES code seems to be rather popular for some reason). You should find classes for AES, Caesar, DES, Triple DES, RSA, and Vernam (as well as MD5 and SHA1 hash functions). I plan on adding a couple other ones in that area as well (RC2, DSA, etc.). I'm also planning on adding classes to deal with Exchange, Active Directory, etc. at some point in the future as well as some file format helpers (ATOM, OPML, etc.). Anyway, I hope the library helps you out and if you feel like modifying it feel free (I'm using the MIT license on this item). So take a look, leave feedback, and happy coding.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by James Craig on Thursday, October 02, 2008 4:54 PM
Permalink | Comments (0) | Post RSSRSS comment feed

SQL Helper Class and Jack Thompson


I've got a couple things to talk about today. The first is code that you might find useful. The other day I was bored and rather annoyed at dealing with the SQL helper class we have at work, so I went and created a new one:

SQLHelper.zip (1.37 kb)

The class handles connections, stored procedures (it was only designed to deal with stored procedures actually), etc. Pretty much everything that the old class did with one exception. When you are getting data, you supply the function with a default value.  If the value returned by the call is null or an empty string or something, it returns the default value that you supplied. I've been using it in a set of data layer objects that I had to create and it has definitely helped cut down on my screaming and cursing at the shear number of null values this database has... And don't get me started on the fact that it's due to bad design in the first place... Anyway, use the code and hopefully it will make your day a bit easier as well. 

Now for the fun part of the post... Jack Thompson looks like he's going to be disbarred (perhaps for 10 years). I have nothing against people who feel that kids shouldn't play adult themed games. I like the idea of checking IDs to buy them, I think parents should be better informed, etc. (I feel the same about movies, etc.) I also have nothing against lawyers. I work for lawyers, heck, I'm married to a lawyer. But damn that man is crazy... So to me, him being disbarred=good thing. Although I have to say that he scares me. I keep waiting for him to snap and just start killing everyone in sight.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,
Categories: ASP.Net | C# | Database
Posted by James Craig on Thursday, June 05, 2008 12:34 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Lunar Engine Error Logging System


One of the main problems with working on any sort of project, whether it is a game or not, is how to detect and report bugs to the developers in an easy/straightforward manner.  In a previous post I talked a bit about various options out there and proposed using a database. Using a database for this sort of work has a number of advantages (some of which I mentioned previously and some that I didn't):

  • It's quick and designed specifically to store information
  • It is easy to search through and gather information from
  • It's easy to setup and get running

So with that in mind, I've decided to use this approach within the Lunar Engine. I also decided that I was going to use MySQL as the backend portion. And while I'm not going to go over setting it up (although there is a good tutorial here), I will go over the code and database itself:

The Table

The table that I'm using for saving the errors is rather straightforward and used the following statement to set it up

CREATE TABLE  errors (
  `ErrorID` int(10) unsigned NOT NULL auto_increment,
  `ErrorText` varchar(5000) NOT NULL,
  `ErrorType` int(10) unsigned NOT NULL,
  `File` varchar(1024) NOT NULL,
  `Line` int(10) unsigned NOT NULL,
  `StartTime` datetime NOT NULL,
  `Method` varchar(1024) NOT NULL,
  PRIMARY KEY  (`ErrorID`)
)

This allows us to store information about the error including the error message, error type (general, lost input device, etc.), file it occurred in, line it occurred on, time that the program was started, and the method in which the error occurred. There are a few other items that we could save, but this will do for our purposes. The next step is setting up the code:

The Code

 

using System;
using System.IO;

namespace LunarEngine
{
    public class ErrorLog
    {
        public ErrorLog()
        {
#if DEBUG
            try
            {
                string ConnectionString = "DRIVER={MySQL ODBC 3.51 Driver};" +
                          "SERVER=localhost;" +        //The server location should go here
                          "DATABASE=errorlog;" +     //The database name, in this case ErrorLog
                          "UID=user;" +                     //Whatever you've setup as the user name for the database
                          "PASSWORD=password;"+   //Whatever you've setup as the password for the database
                          "OPTION=3";

                Connection = new System.Data.Odbc.OdbcConnection(ConnectionString);
                Connection.Open();

                Run = DateTime.Now;
            }
            catch (Exception a)
            {
                throw a;
            }
#else
            File = new FileStream("./Logs/Errors.txt", FileMode.CreateNew,FileAccess.Write);
            Writer = new StreamWriter(File);
#endif
        }

        public void Write(string Message, ErrorType ErrorType)
        {
            try
            {
#if DEBUG
                System.Diagnostics.StackFrame CallStack = new System.Diagnostics.StackFrame(1, true);
                string File = CallStack.GetFileName().Replace("\\","\\\\");
                string Method = CallStack.GetMethod().Name;
                int Line = CallStack.GetFileLineNumber();


                System.Data.Odbc.OdbcCommand Command;
                string CommandString = "insert into errors(ErrorText,ErrorType,File,Line,StartTime,Method)"+

                         "values (\"" +
                         Message + "\"," + ((int)ErrorType).ToString() + ",\"" +
                         File + "\"," + Line.ToString() + ",\""+
                         Run.ToString("yyyy-MM-dd hh:mm:ss")+"\",\""+Method+"\");";
                Command = new System.Data.Odbc.OdbcCommand(CommandString, Connection);
                int LinesInserted = Command.ExecuteNonQuery();
#else
                Writer.Write(((int)ErrorType).ToString()+" "+Message);
#endif
            }
            catch (Exception a)
            {
                throw a;
            }
        }

        public void Cleanup()
        {
#if DEBUG
            if(Connection!=null)
            {


            if(Connection.State!=System.Data.ConnectionState.Closed)
            {
                Connection.Close();
            }


            }
#else
            Writer.Close();
            File.Close();
#endif
        }

        private System.Data.Odbc.OdbcConnection Connection;
        private FileStream File;
        private StreamWriter Writer;
        private DateTime Run;


        public enum ErrorType
        {
            General = 1
        };
    }
}

 

Final Word

There are a couple of areas where the code might confuse you:

Why am I not passing in the file, method, and line information to the function? 

Well in C# there is no __FILE__ or __LINE__ constants. The only way to really get that information is to use the StackFrame class. It's a bit awkward but it will let you know what you need. Also note though that it will not work in release mode as the debug information that it uses isn't available.

Why are you using this system only in debug builds?

The reasons for using a more traditional file system to record this information in release is two fold. First, we would have to setup the ODBC driver on the end user's machine. The second issue is that it could be just a bit too slow. While it is fast enough when the database is on the same machine as the application, the error message would have to be sent to the server, a response sent back, etc. if it were left in during release. To be honest that isn't really something we want to deal with. There are ways we could address that issue, run the error logging system in its own thread for example, but we should save those threads for items that would enhance our game.

This approach as you can see is easy to setup though and fast enough for our purposes when it comes to debugging the system. There's another advantage that I haven't talked much about yet, our ability to search through the information. We can easily setup a website to use the information to present it in a readable manner that can allow us to filter out the noise and get to the info we want. I will say that I've talked enough though and I'll go over this further in a future post.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by James Craig on Tuesday, February 26, 2008 5:19 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Recent comments

None

Calendar

<<  January 2009  >>
SuMoTuWeThFrSa
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

Sponsors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2009