Filter:   InfoImg
download CrashGuard.cs
Language: C#
LOC: 167
Project Info
SunUO
Server: BerliOS (SVN)
Type: svn
...\trunk\scripts\legacy\Misc\
   Animations.cs
   AOS.cs
   AttackMessage.cs
   AutoRestart.cs
   AutoSave.cs
   Broadcasts.cs
   CharacterCreation.cs
   Cleanup.cs
   ClientVerification.cs
   CrashGuard.cs
   DataPath.cs
   DispellableAttribute.cs
   ...llableFieldAttribute.cs
   DoorGenerator.cs
   Email.cs
   Fastwalk.cs
   FindByName.cs
   FindRunes.cs
   FoodDecay.cs
   Guild.cs
   HardwareInfo.cs
   InhumanSpeech.cs
   Keywords.cs
   LightCycle.cs
   LoginStats.cs
   Loot.cs
   LootPack.cs
   MapDefinitions.cs
   NameList.cs
   NameVerification.cs
   Notoriety.cs
   OreInfo.cs
   Paperdoll.cs
   Poison.cs
   ProfanityProtection.cs
   Profile.cs
   ProtocolExtensions.cs
   RegenRates.cs
   RenameRequests.cs
   SE.cs
   ServerList.cs
   ShardPoller.cs
   ShrinkTable.cs
   SkillCheck.cs
   SocketOptions.cs
   TextDefinition.cs
   Titles.cs
   TreasureMapProtection.cs
   uoamVendors.cs
   VendorGenerator.cs
   Weather.cs
   WeightOverloading.cs
   WelcomeTimer.cs
   ZLib.cs

using System;
using System.IO;
using System.Web.Mail;
using System.Collections;
using System.Diagnostics;
using Server;
using Server.Network;
using Server.Accounting;

namespace Server.Misc
{
	public class CrashGuard
	{
		private static bool Enabled = true;
		private static bool SaveBackup = true;
		private static bool GenerateReport = true;

		public static void Initialize()
		{
			if ( Enabled ) // If enabled, register our crash event handler
				EventSink.Crashed += new CrashedEventHandler( CrashGuard_OnCrash );
		}

		public static void CrashGuard_OnCrash( CrashedEventArgs e )
		{
			if ( SaveBackup )
				Backup();

			if ( GenerateReport )
				GenerateCrashReport( e );
		}

		private static void SendEmail( string filePath )
		{
			Console.Write( "Crash: Sending email..." );

			MailMessage message = new MailMessage();

			message.Subject = "Automated SunUO Crash Report";
			message.From = "SunUO";
			message.To = Email.CrashAddresses;
			message.Body = "Automated SunUO Crash Report. See attachment for details.";

			message.Attachments.Add( new MailAttachment( filePath ) );

			if ( Email.Send( message ) )
				Console.WriteLine( "done" );
			else
				Console.WriteLine( "failed" );
		}

		private static void CreateDirectory( string path )
		{
			if ( !Directory.Exists( path ) )
				Directory.CreateDirectory( path );
		}

		private static void CreateDirectory( string path1, string path2 )
		{
			CreateDirectory( Path.Combine( path1, path2 ) );
		}

		private static void CopyFile( string rootOrigin, string rootBackup, string path )
		{
			string originPath = Path.Combine( rootOrigin, path );
			string backupPath = Path.Combine( rootBackup, path );

			try
			{
				if ( File.Exists( originPath ) )
					File.Copy( originPath, backupPath );
			}
			catch
			{
			}
		}

		private static void Backup()
		{
			Console.Write( "Crash: Backing up..." );

			try
			{
				string crashedDir = Path.Combine(Core.Config.BackupDirectory, "Crashed");
				string rootBackup = Path.Combine(crashedDir, GetTimeStamp());
				string rootOrigin = Core.Config.SaveDirectory;

				// Create new directories
				CreateDirectory( rootBackup );
				CreateDirectory( rootBackup, "Accounts/" );
				CreateDirectory( rootBackup, "Items/" );
				CreateDirectory( rootBackup, "Mobiles/" );
				CreateDirectory( rootBackup, "Guilds/" );
				CreateDirectory( rootBackup, "Regions/" );

				// Copy files
				CopyFile( rootOrigin, rootBackup, "Accounts/Accounts.xml" );

				CopyFile( rootOrigin, rootBackup, "Items/Items.bin" );
				CopyFile( rootOrigin, rootBackup, "Items/Items.idx" );
				CopyFile( rootOrigin, rootBackup, "Items/Items.tdb" );

				CopyFile( rootOrigin, rootBackup, "Mobiles/Mobiles.bin" );
				CopyFile( rootOrigin, rootBackup, "Mobiles/Mobiles.idx" );
				CopyFile( rootOrigin, rootBackup, "Mobiles/Mobiles.tdb" );

				CopyFile( rootOrigin, rootBackup, "Guilds/Guilds.bin" );
				CopyFile( rootOrigin, rootBackup, "Guilds/Guilds.idx" );

				CopyFile( rootOrigin, rootBackup, "Regions/Regions.bin" );
				CopyFile( rootOrigin, rootBackup, "Regions/Regions.idx" );

				Console.WriteLine( "done" );
			}
			catch
			{
				Console.WriteLine( "failed" );
			}
		}

		private static void GenerateCrashReport( CrashedEventArgs e )
		{
			Console.Write( "Crash: Generating report..." );

			try
			{
				string timeStamp = GetTimeStamp();
				string fileName = String.Format( "Crash {0}.log", timeStamp );
				string filePath = Path.Combine(Core.Config.LogDirectory,
											   fileName);

				using ( StreamWriter op = new StreamWriter( filePath ) )
				{
					Version ver = Core.Assembly.GetName().Version;

					op.WriteLine( "Server Crash Report" );
					op.WriteLine( "===================" );
					op.WriteLine();
					op.WriteLine( "SunUO Version {0}.{1}.{3}, Build {2}", ver.Major, ver.Minor, ver.Revision, ver.Build );
					op.WriteLine( "Operating System: {0}", Environment.OSVersion );
					op.WriteLine( ".NET Framework: {0}", Environment.Version );
					op.WriteLine( "Time: {0}", Core.Now );

					try { op.WriteLine( "Mobiles: {0}", World.Mobiles.Count ); }
					catch {}

					try { op.WriteLine( "Items: {0}", World.Items.Count ); }
					catch {}

					op.WriteLine( "Clients:" );

					try
					{
						ArrayList states = NetState.Instances;

						op.WriteLine( "- Count: {0}", states.Count );

						for ( int i = 0; i < states.Count; ++i )
						{
							NetState state = (NetState)states[i];

							op.Write( "+ {0}:", state );

							Account a = state.Account as Account;

							if ( a != null )
								op.Write( " (account = {0})", a.Username );

							Mobile m = state.Mobile;

							if ( m != null )
								op.Write( " (mobile = 0x{0:X} '{1}')", m.Serial.Value, m.Name );

							op.WriteLine();
						}
					}
					catch
					{
						op.WriteLine( "- Failed" );
					}

					op.WriteLine();

					op.WriteLine( "Exception:" );
					op.WriteLine( e.Exception );
				}

				Console.WriteLine( "done" );

				if ( Email.CrashAddresses != null )
					SendEmail( filePath );
			}
			catch
			{
				Console.WriteLine( "failed" );
			}
		}

		private static string GetTimeStamp()
		{
			DateTime now = Core.Now;

			return String.Format( "{0}-{1}-{2}-{3}-{4}-{5}",
					now.Day,
					now.Month,
					now.Year,
					now.Hour,
					now.Minute,
					now.Second
				);
		}
	}
}