All pastes #181839 Raw Edit

Unnamed

public text v1 · immutable
#181839 ·published 2006-09-25 13:19 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Data;

// Work work
using Grunt.Library;
using Warcraft = Grunt.Library.Warcraft;

namespace Grunt.UI
{
    /// <summary>
    /// Best class in the world :-)
    /// </summary>
    class Program
    {
        /// <summary>
        /// Private variables
        /// </summary>
        private static Warcraft war;
        private static Hashtable objsById;
        private static Hashtable untsById;
        private static Hashtable itemsById;
        private static Random rnd;

        /// <summary>
        /// Private constants
        /// </summary>
        /// <remarks>
        /// Used for parsing the /Data/"obj.Type" file
        /// </remarks>
        private const string START = "#START"; // Object start
        private const string END = "#END"; // Object end
        private const string CUSTOM_START = "#CUSTOM_START";
        private const string CUSTOM_END = "#CUSTOM_END";
        private const string GUID = "OBJECT_FIELD_GUID"; // Object guid
        private static int fileCount;

        public static Hashtable dbc;

        /// <summary>
        /// Application Entry
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.Title = "World of Warcraft - 47 72 75 6E 74";

            #region Introduction Spam

            Console.WriteLine(@"
  _______ ______ _______ _______ _______
 |     __|   __ |   |   |    |  |_     _|    \___/
 |    |  |      <   |   |       | |   |      cO Oc
 |_______|___|__|_______|__|____| |___|  Moo  |_|
  For World of Warcraft 1.10.2 /valvet");
            Console.WriteLine("");
            Console.WriteLine(" 00827024  47 52 55 4E 54 5F 48 45  GRUNT_HE\n" +
                              " 0082702C  4C 4C 4F                 LLO\n");

            Console.WriteLine(" Please minimize me after starting, in order to reduce memory usage.");
            Console.WriteLine(" Starting up..\n");

            #endregion // End spam

            rnd = new Random();
            war = new Warcraft();
            war.Interval = 125;
            war.ThreadPriority = ThreadPriority.Normal;
                       

            Console.WriteLine(" Creating Hashtable.");
            objsById = new Hashtable();
            untsById = new Hashtable();
            itemsById = new Hashtable();

            DateTime startTime = DateTime.Now;

            Console.WriteLine(" Parsing files. This might take a while.");
            string[] dirs = Directory.GetDirectories(@"./Data/");
            if (dirs.Length > 0)
            {
                Console.WriteLine(" Scanning for Object files in {0} directorie(s).", dirs.Length);
                foreach (string dir in dirs)
                {
                    GetDirectories(dir);
                }

                TimeSpan resultTime = DateTime.Now - startTime;
                Console.WriteLine(" Done. Parsed {0} files in {1} sec(s).\n", fileCount, resultTime.TotalSeconds);
            }

            try
            {
                Console.WriteLine(" Creating new instance of Warcraft object.");
                if (war.Start())
                {
                     Console.WriteLine(" Launching update event.\n");
                    war.OnUpdateEvent += new WarcraftUpdateEvent(GruntUpdateEvent);

                    Console.WriteLine(" Started. Have a safe journey!\n");
                }
                else
                {
                    Console.WriteLine(" Unable to start. Please check /Logs/Warcraft.log.");
                }
            }
            catch (Exception E)
            {
                Console.WriteLine("\n -- Cut here --");
                Console.WriteLine(" Caught exception.\n Please report the following to the developers: ");
                Console.WriteLine(" Source: {0}", E.Source);
                Console.WriteLine(" Message: {0}", E.Message);
                Console.WriteLine(" StrackTrace: {0}", E.StackTrace);
                Console.WriteLine(" -- Cut here --\n");
            }

            GC.Collect();
            // Main thread will exit
        }

        #region Parser Specific Functions

        /// <summary>
        /// Gets all the directories at the specified path
        /// </summary>
        /// <param name="path">Path to look in</param>
        private static void GetDirectories(string path)
        {
            string[] dirs = Directory.GetDirectories(path);
            if (dirs.Length > 0)
            {
                foreach (string subDir in dirs)
                {
                    GetDirectories(subDir);
                }
            }

            string[] files = Directory.GetFiles(path);
            if (files.Length > 0)
            {
                foreach (string fileName in files)
                {
                    FileInfo fileInfo = new FileInfo(fileName);

                    Console.WriteLine(" Parsing file: {0}, size: {1} bytes.", fileName, fileInfo.Length);
                    ParseFile(fileName);

                    fileCount++;
                }
            }
        }

        /// <summary>
        /// Parses specified file and adds them to the our collection
        /// </summary>
        /// <param name="fileName">File to parse</param>
        private static void ParseFile(string fileName)
        {
            bool active = false;
            StreamReader sr = new StreamReader(fileName);

            string line;

            while ((line = sr.ReadLine()) != null)
            {
                if (line.StartsWith(START))
                {
                    active = true;
                }
                else if (line.StartsWith(END))
                {
                    active = false;
                }
                else
                {
                    if (active)
                    {
                        int ispace = line.IndexOf(" ");
                        line = line.Insert(ispace, ":");

                        string[] parts = line.Split(":".ToCharArray());
                        string key = parts[0].Trim();
                        string val = parts[1].Trim();

                        if (key.StartsWith(GUID))
                        {
                            if (!objsById.Contains(long.Parse(val)))
                                objsById.Add(long.Parse(val), "invalid");
                        }
                        else
                        {
                            //Console.WriteLine(" Unrecognized line " + line);
                        }
                    }
                }
            }

            sr.Close();
        }

        #endregion

        /// <summary>
        /// Our callback event for the WarcraftUpdateEvent in the library
        /// </summary>
        /// <remarks>
        /// This will update every 125 ms by default. You can change the interval
        /// by modifying war.Interval = integer; -- Don't set too high!
        /// </remarks>
        /// <param name="sender">Warcraft object</param>
        private static void GruntUpdateEvent(Warcraft sender)
        {
            foreach (War_Object obj in war.Objects.Values)
            {
                if (!obj.IsValid)
                    return;

                switch (obj.Type)
                {
                    case War_ObjectType.Object:
                        {                           
                            // TODO
                            break;
                        }

                    case War_ObjectType.Item:
                        {
                            if (!itemsById.Contains(obj.ReadStorageInt(0xC)))
                            {
                                //Console.WriteLine(" Item Name: {0}", obj.Name);
                                itemsById.Add(obj.ReadStorageInt(0xC), obj);
                                ObjectToFile(obj);
                            }

                            break;
                        }

                    case War_ObjectType.Container:
                        {
                            // TODO
                            break;
                        }

                    case War_ObjectType.Unit:
                        {
                            /*
                            if (!untsById.Contains(obj.ReadStorageInt(0x0)))
                            {
                                Console.WriteLine(" Unit Name: {0}", obj.Name);
                                Console.WriteLine(" Unit BasePtr: {0}", obj.BasePtr);
                                untsById.Add(obj.ReadStorageInt(0x0), obj);
                                ObjectToFile(obj);
                            }
                            addUnit(obj);
                             */
                            //ds.Tables["Units"].WriteXml(@"./XmlData/dsUnitsObjects.xml");
                            break;
                        }

                    case War_ObjectType.Player:
                        {
                            // TODO
                            break;
                        }

                    case War_ObjectType.AIGroup:
                        {
                            Console.WriteLine("Hello AIGroup.");
                            break;
                        }

                    case War_ObjectType.Areatrigger:
                        {
                            Console.WriteLine("Hello Areatrigger.");
                            break;
                        }

                    case War_ObjectType.GameObject:
                        {
                            // Name was blank, try again later.
                            if (obj.Name.Length < 1)
                                return;

                            if (obj.Name == "Duel Flag")
                                return; // We don't want duel flags

                            // TODO: Do some more checking of bogus objects
                            //       like Traps and such.

                            if (!objsById.Contains(obj.GUID.Full))
                            {
                                Console.WriteLine("Name {0}  Type: {1}({2})", obj.Name, (War_GameObjectType)obj.ReadStorageInt(war.Descriptors[obj.Type, "GAMEOBJECT_TYPE_ID"]), obj.ReadStorageInt(war.Descriptors[obj.Type, "GAMEOBJECT_TYPE_ID"]));

                                //Console.WriteLine(" GO Name: {0}", obj.Name);
                                //Console.WriteLine(" GO BasePtr: {0}", obj.BasePtr);
                                objsById.Add(obj.GUID.Full, obj);                                
                                //ObjectToFile(obj);

                                //Console.WriteLine("Name {0}, padding(id?): {1}, bob: {2}, flags: {3}", obj.Name, obj.ReadStorageInt(0x14), obj.ReadStorageInt(0xE8), obj.ReadStorageInt(0x24));
                                                                                              
                                
                            }

                            break;
                        }

                    case War_ObjectType.Dynamic:
                        {
                            // TODO
                            break;
                        }

                    case War_ObjectType.Corpse:
                        {
                            // TODO
                            break;
                        }

                    default:
                        {
                            Console.WriteLine("\n -- Cut here --");
                            Console.WriteLine(" Strange.. Unknown Object type returned.\n Please report the following to the developers:");
                            Console.WriteLine(" Returned Object Type: {0}.", obj.Type);
                            Console.WriteLine(" -- Cut here --\n");
                            break;
                        }
                }
            }

            // Let's try and sleep a little.. maybe that'll fix the
            // name returning blank sometimes on objects.
            Thread.Sleep(1000 + rnd.Next(500));
        }

        /// <summary>
        /// Writes all descriptor fields to a file
        /// </summary>
        /// <param name="obj">War_Object object</param>
        /// <remarks>
        /// We need to check all the ReadStorage functions that they're
        /// being used correctly. Eg. ReadStorageInt where the return value is
        /// integer, Long where it's long and so forth.
        /// </remarks>
        private static void ObjectToFile(War_Object obj)
        {
            if (!Directory.Exists(@"./Data/" + obj.Type))
                Directory.CreateDirectory(@"./Data/" + obj.Type);

            using (StreamWriter sw = new StreamWriter(@"./Data/" + obj.Type + "/" + obj.Name, true))
            {
                sw.WriteLine("#START"); // Object start

                sw.WriteLine("OBJECT_FIELD_GUID {0}", obj.ReadStorageLong(0x0));
                sw.WriteLine("OBJECT_FIELD_GUID+1 {0}", obj.ReadStorageLong(0x4));

                sw.WriteLine("#START_CUSTOM"); // Start custom descriptors

                sw.WriteLine("OBJECT_FIELD_NAME {0}", obj.Name); // Custom
                sw.WriteLine("GAMEOBJECT_CONTINENT {0}", obj.Continent); // Custom
                sw.WriteLine("GAMEOBJECT_CREATED_BY_NAME {0}", obj.CreatedByName); // Custom

                sw.WriteLine("OBJECT_FIELD_GUID_FULL {0}", obj.GUID.Full); // Custom
                sw.WriteLine("OBJECT_FIELD_GUID_HIGH {0}", obj.GUID.High); // Custom
                sw.WriteLine("OBJECT_FIELD_GUID_LOW {0}", obj.GUID.Low); // Custom

                sw.WriteLine("GAMEOBJECT_SOUND {0}", obj.Sound0); // Custom
                sw.WriteLine("GAMEOBJECT_SOUND+1 {0}", obj.Sound1); // Custom
                sw.WriteLine("GAMEOBJECT_SOUND+2 {0}", obj.Sound2); // Custom
                sw.WriteLine("GAMEOBJECT_SOUND+3 {0}", obj.Sound3); // Custom
                sw.WriteLine("GAMEOBJECT_SOUND+4 {0}", obj.Sound4); // Custom
                sw.WriteLine("GAMEOBJECT_SOUND+5 {0}", obj.Sound5); // Custom
                sw.WriteLine("GAMEOBJECT_SOUND+6 {0}", obj.Sound6); // Custom
                sw.WriteLine("GAMEOBJECT_SOUND+7 {0}", obj.Sound7); // Custom
                sw.WriteLine("GAMEOBJECT_SOUND+8 {0}", obj.Sound8); // Custom
                sw.WriteLine("GAMEOBJECT_SOUND+9 {0}", obj.Sound9); // Custom
                
                sw.WriteLine("#END_CUSTOM"); // End custom descriptors
                
                sw.WriteLine("OBJECT_FIELD_TYPE {0}", obj.ReadStorageInt(0x8));
                sw.WriteLine("OBJECT_FIELD_ENTRY {0}", obj.ReadStorageInt(0xC));
                sw.WriteLine("OBJECT_FIELD_SCALE_X {0}", obj.ReadStorageFloat(0x10));
                sw.WriteLine("OBJECT_FIELD_PADDING {0}", obj.ReadStorageFloat(0x14));

                // TODO: Figure out how this workes
                //       Perhaps the first or second is GUID of the creator.
                sw.WriteLine("OBJECT_FIELD_CREATED_BY {0}", obj.ReadStorageLong(0x18));
                sw.WriteLine("OBJECT_FIELD_CREATED_BY+1 {0}", obj.ReadStorageLong(0x1C));

                sw.WriteLine("GAMEOBJECT_DISPLAYID {0}", obj.ReadStorageInt(0x20));
                sw.WriteLine("GAMEOBJECT_FLAGS {0}", obj.ReadStorageInt(0x24));
                sw.WriteLine("GAMEOBJECT_ROTATION {0}", obj.ReadStorageFloat(0x28));
                sw.WriteLine("GAMEOBJECT_ROTATION+1 {0}", obj.ReadStorageFloat(0x2C));
                sw.WriteLine("GAMEOBJECT_ROTATION+2 {0}", obj.ReadStorageFloat(0x30));
                sw.WriteLine("GAMEOBJECT_ROTATION+3 {0}", obj.ReadStorageFloat(0x34)); // 0x34
                sw.WriteLine("GAMEOBJECT_STATE {0}", obj.ReadStorageInt(0x38));

                // TODO: Figure out how to calculate to real DateTime
                sw.WriteLine("GAMEOBJECT_TIMESTAMP {0}", obj.ReadStorageLong(0x3C));

                sw.WriteLine("GAMEOBJECT_POS_X {0}", obj.ReadStorageFloat(0x40));
                sw.WriteLine("GAMEOBJECT_POS_Y {0}", obj.ReadStorageFloat(0x44));
                sw.WriteLine("GAMEOBJECT_POS_Z {0}", obj.ReadStorageFloat(0x48));
                sw.WriteLine("GAMEOBJECT_FACING {0}", obj.ReadStorageFloat(0x4C));
                sw.WriteLine("GAMEOBJECT_DYN_FLAGS {0}", obj.ReadStorageInt(0x50));
                sw.WriteLine("GAMEOBJECT_FACTION {0}", obj.ReadStorageInt(0x54));
                sw.WriteLine("GAMEOBJECT_TYPE_ID {0}", obj.ReadStorageInt(0x58));
                sw.WriteLine("GAMEOBJECT_LEVEL {0}", obj.ReadStorageInt(0x5C));

                sw.WriteLine("#END"); // Object end
                sw.WriteLine("");
            }
        }

        /// <summary>
        /// Class destructor
        /// </summary>
        ~Program()
        {
            objsById = null;
            GC.Collect();
        }
    }
}