Esempio n. 1
0
        public MainWindow()
        {
            InitializeComponent();

            // test - lets switch to our tab at startup
            tabControl1.SelectedIndex = 2;

            // Lets try to find clients at system
            var clients = ClientInfo.Get();
            if (clients.Length != 0) { // we must remember that we have no warinties that client is cirtanly valid

                // now we need create base uo data storage class, it base class we will use to do any work with uo data, so generally we need to store it as static.
                // but just now for testing we dont do it. (Remember shilw we will write controls in EsseceUDK.Add-ins we need to get manager at EsseceUDK assembly)
                var manager = new UODataManager(new Uri(clients[0].DirectoryPath), UODataType.ClassicAdventuresOnHighSeas, UOLang.Russian, false);

                // ok, we get manager just now let get tiles and set them as sourse to our list. Yeh, it's really simple)
                tileItemView1.ItemsSource = manager.GetItemTile(TileFlag.Wall); // lets get all walls to look throw

                // just now we use same souce for binding to differen controls. So we represent different data viewer for same data.
                var lands = manager.GetLandTile(TileFlag.None).Where(t => t.TileId < 1000); // just now we get first 1000 valid lands for testing (we dont take care what is this)
                tileLandView1.ItemsSource = lands;
                tileTexmView1.ItemsSource = lands;

                // PS xaml is good, but lets devide all properties of controls in two types: visual-style and visual-logic.
                // The first one is part of theme or control design. The second are user customizable or controll changeble,
                // for example - sizes of tiles in tileItemView1 (we just add some Properties to it later). The idea is that if
                // we decide ti rewrite control in future to own we can easily change it without any problems.

            } else {
                // it's seems we cant find clients so we just throw Exception
                throw new Exception("No one \"Ultima Online\" client was founded.");
            }

            
        }
Esempio n. 2
0
        public MainWindow()
        {
            InitializeComponent();
            Application.Current.ApplyTheme("ExpressionDark"); 
            // ThemeManager.GetThemes()[0];

            // test - lets switch to our tab at startup
            tabControl1.SelectedIndex = 6;

            // Lets try to find clients at system
            var clients = ClientInfo.GetInSystem();
            if (clients.Length != 0) { // we must remember that we have no warinties that client is cirtanly valid

                // now we need create base uo data storage class, it base class we will use to do any work with uo data, so generally we need to store it as static.
                // but just now for testing we dont do it. (Remember shilw we will write controls in EsseceUDK.Add-ins we need to get manager at EsseceUDK assembly)
                var manager = new UODataManager(new Uri(clients[0].DirectoryPath), UODataType.ClassicAdventuresOnHighSeas, UOLang.Russian, new UODataOptions(), true);// false);
                userControlTileMerger.UODataManager = manager;

                // ok, we get manager just now let get tiles and set them as sourse to our list. Yeh, it's really simple)
                var items = manager.GetItemTile(TileFlag.None, true);//TileFlag.Wall); // lets get all walls to look throw
                //foreach (var item in items)
                //    item.Surface.GetSurface().GetHammingDistanceForAvrHash(null);
                tileItemView1.ItemsSource = items;
                

                // just now we use same souce for binding to differen controls. So we represent different data viewer for same data.
                var lands = manager.GetLandTile(TileFlag.None).Where(t => t.EntryId < 1000); // just now we get first 1000 valid lands for testing (we dont take care what is this)
                tileLandView1.ItemsSource = lands;
                tileTexmView1.ItemsSource = lands;

                //manager.GetLandTile(0x0001).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\L0x002A.bmp");
                //manager.GetLandTile(0x0002).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\L0x0089.bmp");
                //manager.GetLandTile(0x0003).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\L0x321D.bmp");
                //manager.GetLandTile(0x0004).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\L0x3472.bmp");
                //manager.GetLandTile(0x0005).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\L0x346E.bmp");
                //manager.GetLandTile(0x0006).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\L0x3475.bmp");

                //manager.GetLandTile(0x0001).Texture = manager.CreateSurface(@"E:\______________________\3d\++\ss\T0x002A.bmp");
                //manager.GetLandTile(0x0002).Texture = manager.CreateSurface(@"E:\______________________\3d\++\ss\T0x0089.bmp");
                //manager.GetLandTile(0x0003).Texture = manager.CreateSurface(@"E:\______________________\3d\++\ss\T0x321D.bmp");
                //manager.GetLandTile(0x0004).Texture = manager.CreateSurface(@"E:\______________________\3d\++\ss\T0x3472.bmp");
                //manager.GetLandTile(0x0005).Texture = manager.CreateSurface(@"E:\______________________\3d\++\ss\T0x346E.bmp");
                //manager.GetLandTile(0x0006).Texture = manager.CreateSurface(@"E:\______________________\3d\++\ss\T0x3475.bmp");

                //manager.GetItemTile(0x0001).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\I0xF6C2.bmp");
                //manager.GetItemTile(0x0002).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\I0xF6FC.bmp");
                //manager.GetItemTile(0x0003).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\I0xF6BA.bmp");
                //manager.GetItemTile(0x0004).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\I0x3BB4.bmp");
                //manager.GetItemTile(0x0005).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\I0xF6A2.bmp");
                //manager.GetItemTile(0x0006).Surface = manager.CreateSurface(@"E:\______________________\3d\++\ss\I0x248B.bmp");

                // PS xaml is good, but lets devide all properties of controls in two types: visual-style and visual-logic.
                // The first one is part of theme or control design. The second are user customizable or controll changeble,
                // for example - sizes of tiles in tileItemView1 (we just add some Properties to it later). The idea is that if
                // we decide ti rewrite control in future to own we can easily change it without any problems.  
            } else {
                // it's seems we cant find clients so we just throw Exception
                throw new Exception("No one \"Ultima Online\" client was founded.");
            }

            
            
        }
Esempio n. 3
0
 private static IMapFacet GetMapFacet(string[] args, ref int from, UODataManager manager, out byte m, out uint x1, out uint y1, out uint x2, out uint y2)
 {
     m = (byte)StringToUint(args[from++]);
     var f = manager.GetMapFacet(m);
     x1 = StringToUint(args[from++]);
     y1 = StringToUint(args[from++]);
     x2 = StringToUint(args[from++]);
     y2 = StringToUint(args[from++]);
     if (x2 == 0) x2 = f.Width - 1;
     if (y2 == 0) y2 = f.Height - 1;
     return f;
 }
Esempio n. 4
0
 private void btnLoadMuls_Click(object sender, RoutedEventArgs e)
 {
     try {
         UOManager = null;
         var datauri = new Uri(tbPath.Text);
         var dataopt = new UODataOptions();
         dataopt.majorFacet[0] = new FacetDesc("FacetMap-0", (ushort)nudM0W.Value, (ushort)nudM0H.Value, (ushort)nudM0W.Value, (ushort)nudM0H.Value);
         dataopt.majorFacet[1] = new FacetDesc("FacetMap-1", (ushort)nudM1W.Value, (ushort)nudM1H.Value, (ushort)nudM1W.Value, (ushort)nudM1H.Value);
         dataopt.majorFacet[2] = new FacetDesc("FacetMap-2", (ushort)nudM2W.Value, (ushort)nudM2H.Value, (ushort)nudM2W.Value, (ushort)nudM2H.Value);
         dataopt.majorFacet[3] = new FacetDesc("FacetMap-3", (ushort)nudM3W.Value, (ushort)nudM3H.Value, (ushort)nudM3W.Value, (ushort)nudM3H.Value);
         dataopt.majorFacet[4] = new FacetDesc("FacetMap-4", (ushort)nudM4W.Value, (ushort)nudM4H.Value, (ushort)nudM4W.Value, (ushort)nudM4H.Value);
         dataopt.majorFacet[5] = new FacetDesc("FacetMap-5", (ushort)nudM5W.Value, (ushort)nudM5H.Value, (ushort)nudM5W.Value, (ushort)nudM5H.Value);
         var _manager = new UODataManager(datauri,
             cbUT.SelectedIndex == 0 ? UODataType.ClassicMondainsLegacy :
             cbUT.SelectedIndex == 1 ? UODataType.ClassicStygianAbyss   : 
             UODataType.ClassicAdventuresOnHighSeas, UOLang.Russian, dataopt, true);
         UOManager = _manager;
     } catch (Exception ex) {
         UOManager = null;
         MessageBox.Show("While loading data exception was raised.\nCheck path, map sizes and make sure that all data muls are present.");
     }
 }
Esempio n. 5
0
        static void Main(string[] args)
        {
            #if !DEBUG
            try {
            #endif
                int from = 1;
                if (String.Compare(args[0], "--fsutil", true) == 0) {
                    var srsdir = String.Empty;
                    var trgdir = String.Empty;
                    var lspath = String.Empty;
                    var imgcls = String.Empty;
                    var lminid = 0x00000000;
                    var lmaxid = 0x0FFFFFFF;
                    var lcount = 0;
                    var dcount = 0;
                    var trimsp = (int)0;
                    var shmove = (int)0;
                    var outhex = false;
                    var outdel = false;
                    List<uint[]> inrule = null;

                    args = args.Select(a => a.ToLower()).Skip(1).ToArray();
                    var enumerator = args.GetEnumerator();
                    while (enumerator.MoveNext()) {
                        var arg = enumerator.Current as String;
                        if (arg == "-pfx" && enumerator.MoveNext()) {
                            imgcls = enumerator.Current as String;
                        } else

                        if (arg == "-min" && enumerator.MoveNext()) {
                            arg = enumerator.Current as String;
                            lminid = arg.StartsWith("0x") ? Int32.Parse(arg.Substring(2), NumberStyles.AllowHexSpecifier) : Int32.Parse(arg, NumberStyles.None);
                        } else
                        if (arg == "-max" && enumerator.MoveNext()) {
                            arg = enumerator.Current as String;
                            lmaxid = arg.StartsWith("0x") ? Int32.Parse(arg.Substring(2), NumberStyles.AllowHexSpecifier) : Int32.Parse(arg, NumberStyles.None);
                        } else

                        if (arg == "-ren" && enumerator.MoveNext()) {
                            arg = enumerator.Current as String;
                            if (arg != "beg" && arg != "end") {
                                int f = 0;
                                inrule = GetMultiDimentionList(new [] {arg}, ref f);
                            } else
                                trimsp = (arg == "beg") ? 1 : (arg == "end") ? -1 : 0;
                        } else

                        if (arg == "-mov" && enumerator.MoveNext()) {
                            arg = enumerator.Current as String;
                            if ((shmove = arg[0] == '-' ? -1 : arg[0] == '+' ? +1 : 0) != 0)
                                arg = arg.Substring(1); else shmove = +1;
                            shmove *= arg.StartsWith("0x") ? Int32.Parse(arg.Substring(2), NumberStyles.AllowHexSpecifier) : Int32.Parse(arg, NumberStyles.None);
                        } else

                        if (arg == "-len" && enumerator.MoveNext()) {
                            arg = enumerator.Current as String;
                            lcount = arg.StartsWith("0x") ? Int32.Parse(arg.Substring(2), NumberStyles.AllowHexSpecifier) : Int32.Parse(arg, NumberStyles.None);
                        } else
                        if (arg == "-dcn" && enumerator.MoveNext()) {
                            arg = enumerator.Current as String;
                            dcount = arg.StartsWith("0x") ? Int32.Parse(arg.Substring(2), NumberStyles.AllowHexSpecifier) : Int32.Parse(arg, NumberStyles.None);
                        } else
                        if (arg == "-hex") {
                            outhex = true;
                        } else
                        if (arg == "-del") {
                            outdel = true;
                        } else

                        if (String.IsNullOrWhiteSpace(srsdir)) {
                            srsdir = GetFullPath(arg);
                        } else
                        if (String.IsNullOrWhiteSpace(trgdir)) {
                            trgdir = GetFullPath(arg);
                        } else
                        if (String.IsNullOrWhiteSpace(lspath)) {
                            lspath = GetFullPath(arg);
                        } else

                        continue;
                    }
                    if (lcount == 0)
                        lcount = outhex ? 4 : 5;
                    if (dcount == 0)
                        dcount = lcount;
 
                    if (String.IsNullOrWhiteSpace(srsdir) || String.IsNullOrWhiteSpace(trgdir)) 
                        throw new ArgumentException();

                    var searchPattern = new Regex((!String.IsNullOrEmpty(imgcls) ? (@"[\\/][" + imgcls + @"]") : @"[\\/]") + @"(0x[A-F0-9\-]{" + lcount + @"}|[0-9\-]{" + lcount + @"})\.(mde|bmp|png|tif|tiff|gif|wav|vd)$", RegexOptions.IgnoreCase);
                    var lfiles = Directory.GetFiles(srsdir, "*", SearchOption.TopDirectoryOnly).Where(f => searchPattern.IsMatch(f)).Select(f => f.Substring(f.LastIndexOf('\\') + 1).ToLower()).ToArray();
                    var entries = lfiles.Select(f => {
                        var _ext = f.Substring(f.LastIndexOf(@"."));
                        var _nam = f.Substring(0, f.Length - _ext.Length);
                        var _hex = _nam.Contains("0x");
                        var _str = _hex ? _nam.LastIndexOf('x') + 1 : (_nam.Length - _nam.Reverse().SkipWhile(c => !Char.IsDigit(c)).Count());
                        var _len = f.Length - _ext.Length - _str;
                        var _idx = UInt32.Parse(f.Substring(_str, _len), _hex ? NumberStyles.AllowHexSpecifier : NumberStyles.None);
                        return new FileDesc(_ext, _hex, (ushort)_len, (ushort)_idx);
                    }).ToList();
                    if (inrule != null) {
                        for (int i = entries.Count - 1; i >= 0; --i) {
                            var id = entries[i].OrigIndex;
                            var nr = inrule.FirstOrDefault(r => r[0] == id);
                            if (nr == null)
                                entries.RemoveAt(i);
                            else
                                entries[i].SetMoveIndex((int)nr[1]);
                        }
                    }
                    entries = entries.Where(e => e.OrigIndex >= lminid && e.OrigIndex <= lmaxid).ToList();
                    entries.Sort(FileDesc.CompareFileDescByOrigIndex);

                    if (shmove != 0)
                        for (int i = 0; i < entries.Count; ++i)
                            entries[i].SetMoveIndex(entries[i].OrigIndex + shmove);
                    if (trimsp > 0)
                        for (int idx = (int)entries.First().MoveIndex, i = 0; i < entries.Count; ++i)
                            entries[i].SetMoveIndex(idx++);
                    if (trimsp < 0)
                        for (int idx = (int)entries.Last().MoveIndex, i = entries.Count - 1; i >= 0; --i)
                            entries[i].SetMoveIndex(idx--);                

                    var list = String.Empty;
                    enumerator = entries.GetEnumerator();
                    while (enumerator.MoveNext()) {
                        var entry = (FileDesc)enumerator.Current;
                        var path1 = Path.Combine(srsdir, String.Format("{0}{1}{2}", imgcls.ToUpper(), String.Format((entry.HexFormat ? "0x{0:X" : "{0:D") + entry.OrigCount + "}", entry.OrigIndex), entry.Extension));
                        var path2 = Path.Combine(trgdir, String.Format("{0}{1}{2}", imgcls.ToUpper(), String.Format((outhex ? "0x{0:X" : "{0:D") + dcount + "}", entry.MoveIndex), entry.Extension));
                        list += String.Format("0x{0:X5} -> 0x{1:X5}{2}", entry.OrigIndex, entry.MoveIndex, Environment.NewLine);
                        File.Copy(path1, path2);
                        if (outdel)
                            File.Delete(path1);
                    }
                    if (!String.IsNullOrWhiteSpace(lspath))
                        File.WriteAllText(lspath, list);
                } else

                if (String.Compare(args[0], "--create", true) == 0) {
                    ResetProcessStatus(1, "Creating container ");
                    var leng = StringToUint(args[from++]);
                    uint size = 0; string fidx = null;
                    try { size = StringToUint(args[from++]); }
                    catch (Exception e) { --from; fidx = GetFullPath(args[from++]); }
                    var fmul = GetFullPath(args[from++]);
                    var smul = new FileStream(fmul, FileMode.Create, FileAccess.Write, FileShare.Read, 0x1000, false);
                    if (fidx == null) {
                        smul.SetLength(leng * size);
                    } else {
                        smul.SetLength(4);
                        var sidx = new FileStream(fidx, FileMode.Create, FileAccess.Write, FileShare.Read, 0x1000, false);
                        var identry = new byte[12] { 0xFF, 0xFF, 0xFF, 0xFF,   0xFF, 0xFF, 0xFF, 0xFF,   0x00, 0x00, 0x00, 0x00 };
                        for (int i = 0; i < leng; ++i)
                            sidx.Write(identry, 0, 12);
                        sidx.Flush();
                        sidx.Close();
                    }
                    smul.Flush();
                    smul.Close();
                    UpdateProcessStatus(1);
                } else
                if (String.Compare(args[0], "--resize", true) == 0) {
                    var leng = StringToUint(args[from++]);
                    var mulc = GetMulContainer(args, ref from);
                    ResetProcessStatus(mulc.EntryLength, "Resizing container ");
                    mulc.Resize(leng);
                    UpdateProcessStatus(mulc.EntryLength);
                } else
                if (String.Compare(args[0], "--defrag", true) == 0) {
                    var mulc = GetMulContainer(args, ref from);
                    ResetProcessStatus(mulc.EntryLength, "Defragmentating container ");
                    mulc.Defrag();
                    UpdateProcessStatus(mulc.EntryLength);
                } else
                if (String.Compare(args[0], "--export", true) == 0) {
                    var fold = GetFullPath(args[from++]);
                    var mulc = GetMulContainer(args, ref from);
                    ResetProcessStatus(mulc.EntryLength * mulc.EntryItemsCount, "Export data ");
                    for (uint it = 0, i = 0; i < mulc.EntryLength; ++i) {
                        if (!mulc.IsValid(i))
                            continue;
                        for (uint c = 0; c < mulc.EntryItemsCount; ++c) {
                            var id = i * mulc.EntryItemsCount + c;
                            var file = Path.Combine(fold, String.Format("{0:000000}.mde", id));
                            var stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read, 0x1000, false);
                            if (mulc.IsIndexBased)
                                stream.Write(Utils.StructToBuff(mulc.GetExtra(i)), 0, 4);
                            var data = mulc[id, mulc.EntryItemsCount > 1];
                            stream.Write(data, 0, data.Length);
                            stream.Flush();
                            stream.Close();
                            UpdateProcessStatus(++it);
                        }
                        
                    }
                } else
                if (String.Compare(args[0], "--import", true) == 0) {
                    var fold = GetFullPath(args[from++]);
                    var mulc = GetMulContainer(args, ref from);
                    var fils = Directory.GetFiles(fold, "??????.mde", SearchOption.TopDirectoryOnly);
                    uint it = 0;
                    ResetProcessStatus((uint)fils.Length, "Import data ");
                    foreach (var file in fils) {
                        uint i;
                        if (!uint.TryParse(Path.GetFileNameWithoutExtension(file), out i))
                            continue;
                        var stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, 0x1000, false);
                        if (mulc.IsIndexBased) {
                            var edat = new byte[4];
                            stream.Read(edat, 0, 4);
                            mulc.SetExtra(i, Utils.BuffToStruct<uint>(edat, 0, 1)[0]);
                        }
                        var data = new byte[stream.Length - stream.Position];
                        stream.Read(data, 0, data.Length);
                        mulc[i, mulc.EntryItemsCount > 1] = data;
                        UpdateProcessStatus(++it);
                    }
                } else
                if (String.Compare(args[0], "--merger", true) == 0) {
                    var fol1 = GetFullPath(args[from++]);
                    var mul1 = GetMulContainer(args, ref from);
                    var fol2 = GetFullPath(args[from++]);
                    var mul2 = GetMulContainer(args, ref from);
                    if (mul1.EntryItemsCount != mul2.EntryItemsCount || mul1.EntryLength != mul2.EntryLength)
                        throw new Exception("Both mul containers must be same type.");
                    var cmpr = Math.Min(mul1.EntryLength, mul2.EntryLength);
                    var item = mul1.EntryItemsCount > 1;
                    ResetProcessStatus(cmpr * mul1.EntryItemsCount, "Merging data ");
                    for (uint it = 0, i = 0; i < cmpr; ++i) {
                        byte[] dat1 = null; 
                        byte[] dat2 = null;
                        if (!mul1.IsValid(i) && !mul2.IsValid(i)) {
                            //if (mul1.IsValid(i))
                            //    dat1 = mul1[i];
                            //else if (mul2.IsValid(i))
                            //    dat2 = mul2[i];
                            //else {
                                it += mul1.EntryItemsCount;
                                continue;
                            //}
                        }
                        for (uint c = 0; c < mul1.EntryItemsCount; ++c) {
                            var id = i * mul1.EntryItemsCount + c;
                            dat1 = dat1 ?? mul1[id, item];
                            dat2 = dat2 ?? mul2[id, item];
                            if (dat1 != null && dat2 != null && Utils.ArrayIdentical(dat1, dat2)) {
                                ++it;
                                continue;
                            }
                            for (int m = 1; m < 3; ++m) {
                                var data = (m == 1) ? dat1 : dat2;
                                if (data == null)
                                    continue;
                                var mulc = (m == 1) ? mul1 : mul2;
                                var file = Path.Combine((m == 1) ? fol1 : fol2, String.Format("{0:000000}.mde", i));
                                var stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read, 0x1000, false);
                                if (mulc.IsIndexBased)
                                    stream.Write(Utils.StructToBuff(mulc.GetExtra(i)), 0, 4);
                                stream.Write(data, 0, data.Length);
                                stream.Flush();
                                stream.Close();
                            }
                            dat1 = dat2 = null;
                            UpdateProcessStatus(++it);
                        }
                    }   
                } else
                if (String.Compare(args[0], "--convtd", true) == 0) {
                    var file = GetFullPath(args[from++]);
                    var fnew = Boolean.Parse(args[from++]);
                    var mulf = GetFullPath(args[from++]);
                    var virt = ContainerFactory.CreateVirtualMul(null, mulf);
                    var land = ContainerFactory.CreateMul(virt, fnew ? 964u : 836u, 0, 0x4000 >> 5);
                    var item = ContainerFactory.CreateMul(virt, fnew ? 1316u : 1188u, (0x4000 >> 5) * (fnew ? 964u : 836u), 0);
                    var tile = new[] {land, item};
                    var dest = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read, 0x1000, false);
                    var cons = new byte[4] {0x00, 0x00, 0x00, 0x00};
                    ResetProcessStatus(land.EntryLength + item.EntryLength, "Converting tiledata ");
                    for (int it = 0, t = 0; t < 2; ++t) {
                        var size = (t == 0) ? (fnew ? 30 : 26) : (fnew ? 41 : 37);
                        for (uint i = 0; i < tile[t].EntryLength; ++i) {
                            var data = tile[t][i];
                            dest.Write(data, 0, 4);
                            if (fnew) // from new to old
                                for (int offs = 4, e = 0; e < 32; ++e, offs += size) {
                                    dest.Write(data, offs, 4);
                                    dest.Write(data, offs + 8, size - 8);
                                }
                            else // from old to new
                                for (int offs = 4, e = 0; e < 32; ++e, offs += size) {
                                    dest.Write(data, offs, 4);
                                    dest.Write(cons, 0, 4);
                                    dest.Write(data, offs + 4, size - 4);
                                }
                            UpdateProcessStatus((uint)++it);
                        } 
                    }
                    dest.Flush();
                    dest.Close();
                } else
                if (String.Compare(args[0], "--convmt", true) == 0) {
                    var fnew = Boolean.Parse(args[from++]);
                    var idxf = GetFullPath(args[from++]);
                    var mulf = GetFullPath(args[from++]);
                    var mult = ContainerFactory.CreateMul(idxf, mulf);
                    var cons = new byte[4] {0x00, 0x00, 0x00, 0x00};
                    ResetProcessStatus(mult.EntryLength, "Converting multi ");
                    for (uint it = 0, i = 0; i < mult.EntryLength; ++i) {
                        var dbuf = mult[i];
                        var data = new byte[(dbuf.Length / (fnew ? 16 : 12)) * (fnew ? 12 : 16)];
                        if (fnew) // from new to old
                            for (int t = 0, s = 0; s < dbuf.Length; s += 16, t += 12) {
                                Array.Copy(dbuf, s, data, t, 12);
                            }
                        else // from old to new
                            for (int t = 0, s = 0; s < dbuf.Length; s += 12, t += 16) {
                                Array.Copy(dbuf, s, data, t, 12);
                                Array.Copy(cons, 0, data, t + 12, 4);
                            }
                        mult[i] = data;
                        UpdateProcessStatus(++it);
                    }
                } else

                // --------------------------------------------------------------------------
                if (String.Compare(args[0], "--copyid", true) == 0) {
                    var list = GetMultiDimentionList(args, ref from);
                    var mulc = GetMulContainer(args, ref from);
                    var virt = mulc.EntryItemsCount > 1;
                    ResetProcessStatus((uint)list.Count, "Copying entries ");
                    for (int it = 0, i = 0; i < list.Count; ++i) {
                        var sors = list[i][0];
                        var dest = list[i][1];
                        if (mulc.IsIndexBased)
                            mulc.SetExtra(dest, mulc.GetExtra(sors));
                        mulc[dest, virt] = mulc[sors, virt];
                        UpdateProcessStatus((uint)++it);
                    }
                } else
                if (String.Compare(args[0], "--moveid", true) == 0) {
                    var list = GetMultiDimentionList(args, ref from);
                    var mulc = GetMulContainer(args, ref from);
                    var virt = mulc.EntryItemsCount > 1;
                    ResetProcessStatus((uint)list.Count, "Moving entries ");
                    for (int it = 0, i = 0; i < list.Count; ++i) {
                        var sors = list[i][0];
                        var dest = list[i][1];
                        if (mulc.IsIndexBased)
                            mulc.SetExtra(dest, mulc.GetExtra(sors));
                        mulc[dest, virt] = mulc[sors, virt];
                        if (mulc.IsIndexBased)
                            mulc[sors] = null;
                        UpdateProcessStatus((uint)++it);
                    }
                } else
                if (String.Compare(args[0], "--remove", true) == 0) {
                    var list = GetSingleDimentionList(args, ref from);
                    var mulc = GetMulContainer(args, ref from);
                    ResetProcessStatus((uint)list.Count, "Deleting entries ");
                    for (int it = 0, i = 0; i < list.Count; ++i) {
                        mulc[list[i]] = null;
                        UpdateProcessStatus((uint)++it);
                    }
                } else

                // --------------------------------------------------------------------------
                if (String.Compare(args[0], "--facetm", true) == 0) {
                    var folder = GetFullPath(args[from++]);
                    var uodata = (UODataType)StringToUint(args[from++]);
                    var uoopta = args[from++].Split(new []{'|'}, StringSplitOptions.RemoveEmptyEntries).Select(s => (ushort)StringToUint(s)).ToArray();
                    var uoopts = new UODataOptions();
                    for (int a = 0; a < uoopta.Length; a+=3)
                        uoopts.majorFacet[uoopta[a]] = new FacetDesc(String.Format("Facet0{0}", uoopta[a]), uoopta[a+1], uoopta[a+2], uoopta[a+1], uoopta[a+2]);
                    var manager = new UODataManager(new Uri(folder), uodata, Language.English, uoopts, true);
                    var dwriter = manager.DataFactory as IDataFactoryWriter;

                    var frarg = from++;
                    if (String.Compare(args[frarg], "-replid", true) == 0) {
                        byte m; uint x1, y1, x2, y2;
                        var  f = GetMapFacet(args, ref from, manager, out m, out x1, out y1, out x2, out y2);
                        var list = GetMultiDimentionList(args, ref from);
                        ResetProcessStatus((x2 - x1 + 1) * (y2 - y1 + 1), "Replacing land tiles in map ");
                        for (uint it = 1, x = x1; x <= x2; ++x) {
                            for (uint y = y1; y <= y2; ++y, ++it) {
                                var i = f.GetBlockId(x, y);
                                var b = f[i];
                                var c = false;
                                for (uint k = 0; k < 64; ++k) {
                                    var srs = b[k].Land.TileId;
                                    var ent = list.FirstOrDefault(e => e[0] == srs);
                                    if (ent == null)
                                        continue;
                                    b[k].Land.TileId = (ushort)ent[1];
                                    c = true;
                                }
                                if (c) {
                                    var d = b.GetData();
                                    dwriter.SetMapBlock((byte)m, i, d);
                                }
                                UpdateProcessStatus(it);
                                b.Dispose(); 
                            }
                        }
                    } else
                    if (String.Compare(args[frarg], "-reptid", true) == 0) {
                        byte m; uint x1, y1, x2, y2;
                        var  f = GetMapFacet(args, ref from, manager, out m, out x1, out y1, out x2, out y2);
                        var list = GetMultiDimentionList(args, ref from);
                        ResetProcessStatus((x2 - x1 + 1) * (y2 - y1 + 1), "Replacing item tiles in map ");
                        for (uint it = 1, x = x1; x <= x2; ++x) {
                            for (uint y = y1; y <= y2; ++y, ++it) {
                                var i = f.GetBlockId(x, y);
                                var b = f[i];
                                if (b == null) {
                                    UpdateProcessStatus(it);
                                    continue;
                                }
                                var c = false;
                                for (uint k = 0; k < 64; ++k) {
                                    for (int t = 0; t < b[k].Count; ++t) {
                                        var srs = b[k][t].TileId;
                                        var ent = list.FirstOrDefault(e => e[0] == srs);
                                        if (ent == null)
                                            continue;
                                        b[k][t].TileId = (ushort)ent[1];
                                        c = true;
                                    } 
                                }
                                if (c) {
                                    var d = b.GetData();
                                    dwriter.SetMapBlock((byte)m, i, d);
                                }
                                UpdateProcessStatus(it);
                                b.Dispose();
                            }
                        }
                    } else
                    if (String.Compare(args[frarg], "-rephid", true) == 0) {
                        byte m; uint x1, y1, x2, y2;
                        var  f = GetMapFacet(args, ref from, manager, out m, out x1, out y1, out x2, out y2);
                        var list = GetMultiDimentionList(args, ref from);
                        ResetProcessStatus((x2 - x1 + 1) * (y2 - y1 + 1), "Replacing item colors in map ");
                        for (uint it = 1, x = x1; x <= x2; ++x) {
                            for (uint y = y1; y <= y2; ++y, ++it) {
                                var i = f.GetBlockId(x, y);
                                var b = f[i];
                                if (b == null) {
                                    UpdateProcessStatus(it);
                                    continue;
                                }
                                var c = false;
                                for (uint k = 0; k < 64; ++k) {
                                    for (int t = 0; t < b[k].Count; ++t) {
                                        var srs = b[k][t].Palette;
                                        var ent = list.FirstOrDefault(e => e[0] == srs);
                                        if (ent == null)
                                            continue;
                                        b[k][t].Palette = (ushort)ent[1];
                                        c = true;
                                    } 
                                }
                                if (c) {
                                    var d = b.GetData();
                                    dwriter.SetMapBlock((byte)m, i, d);
                                }
                                UpdateProcessStatus(it);
                                b.Dispose();
                            }
                        }
                    } else
                    if (String.Compare(args[frarg], "-render", true) == 0) {
                        byte m; uint x1, y1, x2, y2;
                        var f = GetMapFacet(args, ref from, manager, out m, out x1, out y1, out x2, out y2);
                        var ppt = (byte)  2;
                        var alt = (short)-45;
                        var min = (sbyte)-128;
                        var max = (sbyte)+127;
                        var outpath = "render_out.png";
                        args = args.Skip(from).Select(a => a.ToLower()).ToArray();
                        var enumerator = args.GetEnumerator();
                        while (enumerator.MoveNext()) {
                            var arg = enumerator.Current as String;
                            if (arg == "-ppt" && enumerator.MoveNext()) {
                                arg = enumerator.Current as String;
                                ppt = (byte)Int32.Parse(arg);
                                ++from;
                            } else
                            if (arg == "-alt" && enumerator.MoveNext()) {
                                arg = enumerator.Current as String;
                                alt = (short)Int32.Parse(arg);
                                ++from;
                            } else
                            if (arg == "-min" && enumerator.MoveNext()) {
                                arg = enumerator.Current as String;
                                min = (sbyte)Int32.Parse(arg);
                                ++from;
                            } else
                            if (arg == "-max" && enumerator.MoveNext()) {
                                arg = enumerator.Current as String;
                                max = (sbyte)Int32.Parse(arg);
                                ++from;
                            } else
                                outpath = enumerator.Current as String;
                        }

                        ISurface surf;
                        ResetProcessStatus((x2 - x1 + 1) * (y2 - y1 + 1), "Render flat scaled facet ");
                        manager.FacetRender.SaveFlatMap(out surf, ppt, m, x1, y1, ++x2, ++y2, alt, min, max, SaveFacetCallback);
                        surf.GetSurface().SavePNG(outpath);

                    } else

                        throw new Exception();

                } else


                // --------------------------------------------------------------------------
                if ((String.Compare(args[0], "--help", true) == 0) || (String.Compare(args[0], "-help", true) == 0) 
                    || (String.Compare(args[0], "--h", true) == 0) || (String.Compare(args[0], "-h", true) == 0)
                    || (String.Compare(args[0], "--?", true) == 0) || (String.Compare(args[0], "-?", true) == 0)
                    || (String.Compare(args[0], "\\?", true) == 0) || (String.Compare(args[0], "/?", true) == 0)
                    || (String.Compare(args[0], "help", true) == 0)) {
                    Console.WriteLine(usage);
                } else
                    throw new Exception();
            #if !DEBUG
            } catch(Exception e) {
                Console.WriteLine("Proccess aborted: Ither bad agruments or something real very very bad happened..");
                Console.WriteLine("Run application wiht \"--help\" argumnet for additional info.");              
                var exception = e;
                while (exception != null) {
                    Console.WriteLine("\n\nError: {0}\n\n{1}", exception.Message, exception.StackTrace);
                    exception = exception.InnerException;
                }
            }
            #endif
        }