Пример #1
0
        public static void MakeDefault()
        {
            Clear();

            if (!LoadMULFile(UOFileManager.GetUOFilePath("skillgrp.mul")))
            {
                MakeDefaultMiscellaneous();
                MakeDefaultCombat();
                MakeDefaultTradeSkills();
                MakeDefaultMagic();
                MakeDefaultWilderness();
                MakeDefaultThieving();
                MakeDefaultBard();
            }

            foreach (var g in Groups)
            {
                g.Sort();
            }

            Save();
        }
Пример #2
0
        public override Task Load()
        {
            return(Task.Run(() => {
                if (string.IsNullOrEmpty(_cliloc))
                {
                    _cliloc = "Cliloc.enu";
                }

                string path = UOFileManager.GetUOFilePath(_cliloc);

                if (!File.Exists(path))
                {
                    return;
                }

                using (BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read)))
                {
                    reader.ReadInt32();
                    reader.ReadInt16();
                    byte[] buffer = new byte[1024];

                    while (reader.BaseStream.Length != reader.BaseStream.Position)
                    {
                        int number = reader.ReadInt32();
                        byte flag = reader.ReadByte();
                        int length = reader.ReadInt16();

                        if (length > buffer.Length)
                        {
                            buffer = new byte[(length + 1023) & ~1023];
                        }
                        reader.Read(buffer, 0, length);
                        string text = string.Intern(Encoding.UTF8.GetString(buffer, 0, length));

                        _entries[number] = text;
                    }
                }
            }));
        }
Пример #3
0
        public override unsafe Task Load()
        {
            return(Task.Run
                   (
                       () =>
            {
                string path = UOFileManager.GetUOFilePath("speech.mul");

                if (!File.Exists(path))
                {
                    _speech = Array.Empty <SpeechEntry>();

                    return;
                }

                UOFileMul file = new UOFileMul(path);
                List <SpeechEntry> entries = new List <SpeechEntry>();

                while (file.Position < file.Length)
                {
                    int id = file.ReadUShortReversed();
                    int length = file.ReadUShortReversed();

                    if (length > 0)
                    {
                        entries.Add(new SpeechEntry(id, string.Intern(Encoding.UTF8.GetString((byte *)file.PositionAddress, length))));

                        file.Skip(length);
                    }
                }

                _speech = entries.ToArray();
                file.Dispose();
            }
                   ));
        }
Пример #4
0
        static Verdata()
        {
            string path = UOFileManager.GetUOFilePath("verdata.mul");

            if (!System.IO.File.Exists(path))
            {
                Patches = new UOFileIndex5D[0];
                File    = null;
            }
            else
            {
                File = new UOFileMul(path);

                // the scope of this try/catch is to avoid unexpected crashes if servers redestribuite wrong verdata
                try
                {
                    Patches = File.ReadArray <UOFileIndex5D>(File.ReadInt());
                }
                catch
                {
                    Patches = new UOFileIndex5D[0];
                }
            }
        }
Пример #5
0
        public override Task Load()
        {
            return(Task.Run(() =>
            {
                if (SkillsCount > 0)
                {
                    return;
                }

                string path = UOFileManager.GetUOFilePath("skills.mul");
                string pathidx = UOFileManager.GetUOFilePath("Skills.idx");

                FileSystemHelper.EnsureFileExists(path);
                FileSystemHelper.EnsureFileExists(pathidx);

                _file = new UOFileMul(path, pathidx, 0, 16);
                _file.FillEntries(ref Entries);

                for (int i = 0, count = 0; i < Entries.Length; i++)
                {
                    ref var entry = ref GetValidRefEntry(i);

                    if (entry.Length > 0)
                    {
                        _file.Seek(entry.Offset);
                        var hasAction = _file.ReadBool();
                        var name = Encoding.UTF8.GetString(_file.ReadArray <byte>(entry.Length - 1)).TrimEnd('\0');
                        var skill = new SkillEntry(count++, name, hasAction);

                        Skills.Add(skill);
                    }
                }

                SortedSkills.AddRange(Skills);
                SortedSkills.Sort((a, b) => a.Name.CompareTo(b.Name));
            }));
Пример #6
0
        public override unsafe Task Load()
        {
            return(Task.Run(() =>
            {
                bool foundOneMap = false;

                for (int i = 0; i < Constants.MAPS_COUNT; i++)
                {
                    string path = UOFileManager.GetUOFilePath($"map{i}LegacyMUL.uop");

                    if (Client.IsUOPInstallation && File.Exists(path))
                    {
                        _filesMap[i] = new UOFileUop(path, $"build/map{i}legacymul/{{0:D8}}.dat");
                        Entries[i] = new UOFileIndex[((UOFileUop)_filesMap[i]).TotalEntriesCount];
                        ((UOFileUop)_filesMap[i]).FillEntries(ref Entries[i], false);
                        foundOneMap = true;
                    }
                    else
                    {
                        path = UOFileManager.GetUOFilePath($"map{i}.mul");

                        if (File.Exists(path))
                        {
                            _filesMap[i] = new UOFileMul(path);

                            foundOneMap = true;
                        }

                        path = UOFileManager.GetUOFilePath($"mapdifl{i}.mul");

                        if (File.Exists(path))
                        {
                            _mapDifl[i] = new UOFileMul(path);
                            _mapDif[i] = new UOFileMul(UOFileManager.GetUOFilePath($"mapdif{i}.mul"));
                            _staDifl[i] = new UOFileMul(UOFileManager.GetUOFilePath($"stadifl{i}.mul"));
                            _staDifi[i] = new UOFileMul(UOFileManager.GetUOFilePath($"stadifi{i}.mul"));
                            _staDif[i] = new UOFileMul(UOFileManager.GetUOFilePath($"stadif{i}.mul"));
                        }
                    }

                    path = UOFileManager.GetUOFilePath($"statics{i}.mul");
                    if (File.Exists(path))
                    {
                        _filesStatics[i] = new UOFileMul(path);
                    }
                    path = UOFileManager.GetUOFilePath($"staidx{i}.mul");
                    if (File.Exists(path))
                    {
                        _filesIdxStatics[i] = new UOFileMul(path);
                    }
                }

                if (!foundOneMap)
                {
                    throw new FileNotFoundException("No maps found.");
                }

                int mapblocksize = sizeof(MapBlock);

                if (_filesMap[0].Length / mapblocksize == 393216 || Client.Version < ClientVersion.CV_4011D)
                {
                    MapsDefaultSize[0, 0] = MapsDefaultSize[1, 0] = 6144;
                }

                // This is an hack to patch correctly all maps when you have to fake map1
                if (_filesMap[1] == null || _filesMap[1].StartAddress == IntPtr.Zero)
                {
                    _filesMap[1] = _filesMap[0];
                    _filesStatics[1] = _filesStatics[0];
                    _filesIdxStatics[1] = _filesIdxStatics[0];
                }

                //for (int i = 0; i < MAPS_COUNT; i++)
                Parallel.For(0, Constants.MAPS_COUNT, i =>
                {
                    MapBlocksSize[i, 0] = MapsDefaultSize[i, 0] >> 3;
                    MapBlocksSize[i, 1] = MapsDefaultSize[i, 1] >> 3;
                    LoadMap(i);
                });

                Entries = null;
            }));
        }
Пример #7
0
        private string[] ReadCityTextFile(int count)
        {
            string path = UOFileManager.GetUOFilePath("citytext.enu");

            if (!File.Exists(path))
            {
                return(null);
            }

            string[] descr = new string[count];

            // TODO: stackalloc ?
            byte[] data = new byte[4];

            StringBuilder name = new StringBuilder();
            StringBuilder text = new StringBuilder();

            using (FileStream stream = File.OpenRead(path))
            {
                int cityIndex = 0;

                while (stream.Position < stream.Length)
                {
                    int r = stream.Read(data, 0, 4);

                    if (r == -1)
                    {
                        break;
                    }

                    string dataText = Encoding.UTF8.GetString(data, 0, 4);

                    if (dataText == "END\0")
                    {
                        name.Clear();

                        while (stream.Position < stream.Length)
                        {
                            char b = (char)stream.ReadByte();

                            if (b == '<')
                            {
                                stream.Position -= 1;

                                break;
                            }

                            name.Append(b);
                        }

                        text.Clear();

                        while (stream.Position < stream.Length)
                        {
                            char b;

                            while ((b = (char)stream.ReadByte()) != '\0')
                            {
                                text.Append(b);
                            }

                            if (text.Length != 0)
                            {
                                string t = text + "\n\n";
                                text.Clear();

                                text.Append(t);
                            }

                            long pos = stream.Position;
                            byte end = (byte)stream.ReadByte();
                            stream.Position = pos;

                            if (end == 0x2E)
                            {
                                break;
                            }

                            int r1 = stream.Read(data, 0, 4);
                            stream.Position = pos;

                            if (r1 == -1)
                            {
                                break;
                            }

                            string dataText1 = Encoding.UTF8.GetString(data, 0, 4);

                            if (dataText1 == "END\0")
                            {
                                break;
                            }
                        }

                        if (descr.Length <= cityIndex)
                        {
                            break;
                        }

                        descr[cityIndex++] = text.ToString();
                    }
                    else
                    {
                        stream.Position -= 3;
                    }
                }
            }

            return(descr);
        }
Пример #8
0
        public override Task Load()
        {
            return(Task.Run(() => {
                string path = UOFileManager.GetUOFilePath("gumpartLegacyMUL.uop");

                if (Client.IsUOPInstallation && File.Exists(path))
                {
                    _file = new UOFileUop(path, "build/gumpartlegacymul/{0:D8}.tga", true);
                    Entries = new UOFileIndex[Constants.MAX_GUMP_DATA_INDEX_COUNT];
                    Client.UseUOPGumps = true;
                }
                else
                {
                    path = UOFileManager.GetUOFilePath("gumpart.mul");
                    string pathidx = UOFileManager.GetUOFilePath("gumpidx.mul");

                    if (!File.Exists(path))
                    {
                        path = UOFileManager.GetUOFilePath("Gumpart.mul");
                    }

                    if (!File.Exists(pathidx))
                    {
                        pathidx = UOFileManager.GetUOFilePath("Gumpidx.mul");
                    }

                    _file = new UOFileMul(path, pathidx, Constants.MAX_GUMP_DATA_INDEX_COUNT, 12);

                    Client.UseUOPGumps = false;
                }
                _file.FillEntries(ref Entries);

                string pathdef = UOFileManager.GetUOFilePath("gump.def");

                if (!File.Exists(pathdef))
                {
                    return;
                }

                using (DefReader defReader = new DefReader(pathdef, 3))
                {
                    while (defReader.Next())
                    {
                        int ingump = defReader.ReadInt();

                        if (ingump < 0 || ingump >= Constants.MAX_GUMP_DATA_INDEX_COUNT ||
                            ingump >= Entries.Length ||
                            Entries[ingump].Length > 0)
                        {
                            continue;
                        }

                        int[] group = defReader.ReadGroup();

                        if (group == null)
                        {
                            continue;
                        }

                        for (int i = 0; i < group.Length; i++)
                        {
                            int checkIndex = group[i];

                            if (checkIndex < 0 || checkIndex >= Constants.MAX_GUMP_DATA_INDEX_COUNT || checkIndex >= Entries.Length ||
                                Entries[checkIndex].Length <= 0)
                            {
                                continue;
                            }

                            Entries[ingump] = Entries[checkIndex];

                            Entries[ingump].Hue = (ushort)defReader.ReadInt();

                            break;
                        }
                    }
                }
            }));
        }
Пример #9
0
        public override Task Load()
        {
            return(Task.Run(() =>
            {
                bool result = false;

                FileInfo file = new FileInfo(UOFileManager.GetUOFilePath("Prof.txt"));

                if (file.Exists)
                {
                    if (file.Length > 0x100000) //1megabyte limit of string file
                    {
                        throw new InternalBufferOverflowException($"{file.FullName} exceeds the maximum 1Megabyte allowed size for a string text file, please, check that the file is correct and not corrupted -> {file.Length} file size");
                    }

                    //what if file doesn't exist? we skip section completely...directly into advanced selection
                    TextFileParser read = new TextFileParser(File.ReadAllText(file.FullName), new[] { ' ', '\t', ',' }, new[] { '#', ';' }, new[] { '"', '"' });

                    while (!read.IsEOF())
                    {
                        List <string> strings = read.ReadTokens();

                        if (strings.Count > 0)
                        {
                            if (strings[0].ToLower() == "begin")
                            {
                                result = ParseFilePart(read);

                                if (!result)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }

                Professions[new ProfessionInfo
                            {
                                Name = "Advanced",
                                Localization = 1061176,
                                Description = 1061226,
                                Graphic = 5545,
                                TopLevel = true,
                                Type = PROF_TYPE.PROFESSION,
                                DescriptionIndex = -1,
                                TrueName = "advanced"
                            }] = null;

                foreach (KeyValuePair <ProfessionInfo, List <ProfessionInfo> > kvp in Professions)
                {
                    kvp.Key.Childrens = null;

                    if (kvp.Value != null)
                    {
                        foreach (ProfessionInfo info in kvp.Value)
                        {
                            info.Childrens = null;
                        }
                    }
                }
            }));
        }
Пример #10
0
        public override Task Load()
        {
            return(Task.Run(() =>
            {
                string path = UOFileManager.GetUOFilePath("tiledata.mul");

                FileSystemHelper.EnsureFileExists(path);

                UOFileMul tiledata = new UOFileMul(path);


                bool isold = Client.Version < ClientVersion.CV_7090;
                const int LAND_SIZE = 512;

                int land_group = isold ? Marshal.SizeOf <LandGroupOld>() : Marshal.SizeOf <LandGroupNew>();
                int static_group = isold ? Marshal.SizeOf <StaticGroupOld>() : Marshal.SizeOf <StaticGroupNew>();
                int staticscount = (int)(((tiledata.Length - (LAND_SIZE * land_group))) / static_group);

                if (staticscount > 2048)
                {
                    staticscount = 2048;
                }

                tiledata.Seek(0);

                _landData = new LandTiles[Constants.MAX_LAND_DATA_INDEX_COUNT];
                _staticData = new StaticTiles[staticscount * 32];
                byte[] bufferString = new byte[20];

                for (int i = 0; i < 512; i++)
                {
                    tiledata.Skip(4);

                    for (int j = 0; j < 32; j++)
                    {
                        if (tiledata.Position + (isold ? 4 : 8) + 2 + 20 > tiledata.Length)
                        {
                            goto END;
                        }

                        int idx = i * 32 + j;
                        ulong flags = isold ? tiledata.ReadUInt() : tiledata.ReadULong();
                        ushort textId = tiledata.ReadUShort();
                        tiledata.Fill(ref bufferString, 20);
                        string name = string.Intern(Encoding.UTF8.GetString(bufferString).TrimEnd('\0'));

                        LandData[idx] = new LandTiles(flags, textId, name);
                    }
                }

                END:

                for (int i = 0; i < staticscount; i++)
                {
                    if (tiledata.Position >= tiledata.Length)
                    {
                        break;
                    }

                    tiledata.Skip(4);

                    for (int j = 0; j < 32; j++)
                    {
                        if (tiledata.Position + (isold ? 4 : 8) + 13 + 20 > tiledata.Length)
                        {
                            goto END_2;
                        }

                        int idx = i * 32 + j;

                        ulong flags = isold ? tiledata.ReadUInt() : tiledata.ReadULong();
                        byte weight = tiledata.ReadByte();
                        byte layer = tiledata.ReadByte();
                        int count = tiledata.ReadInt();
                        ushort animId = tiledata.ReadUShort();
                        ushort hue = tiledata.ReadUShort();
                        ushort lightIndex = tiledata.ReadUShort();
                        byte height = tiledata.ReadByte();
                        tiledata.Fill(ref bufferString, 20);
                        string name = string.Intern(Encoding.UTF8.GetString(bufferString).TrimEnd('\0'));

                        StaticData[idx] = new StaticTiles(flags, weight, layer, count, animId, hue, lightIndex, height, name);
                    }
                }


                //path = Path.Combine(FileManager.UoFolderPath, "tileart.uop");

                //if (File.Exists(path))
                //{
                //    UOFileUop uop = new UOFileUop(path, ".bin");
                //    DataReader reader = new DataReader();
                //    for (int i = 0; i < uop.Entries.Length; i++)
                //    {
                //        long offset = uop.Entries[i].Offset;
                //        int csize = uop.Entries[i].Length;
                //        int dsize = uop.Entries[i].DecompressedLength;

                //        if (offset == 0)
                //            continue;

                //        uop.Seek(offset);
                //        byte[] cdata = uop.ReadArray<byte>(csize);
                //        byte[] ddata = new byte[dsize];

                //        ZLib.Decompress(cdata, 0, ddata, dsize);

                //        reader.SetData(ddata, dsize);

                //        ushort version = reader.ReadUShort();
                //        uint stringDicOffset = reader.ReadUInt();
                //        uint tileID = reader.ReadUInt();

                //        reader.Skip(1 + // bool unk
                //                    1 + // unk
                //                    4 + // float unk
                //                    4 + // float unk
                //                    4 + // fixed zero ?
                //                    4 + // old id ?
                //                    4 + // unk
                //                    4 + // unk
                //                    1 + // unk
                //                    4 + // 3F800000
                //                    4 + // unk
                //                    4 + // float light
                //                    4 + // float light
                //                    4   // unk
                //                    );

                //        ulong flags = reader.ReadULong();
                //        ulong flags2 = reader.ReadULong();

                //        reader.Skip(4); // unk

                //        reader.Skip(24); // EC IMAGE OFFSET
                //        byte[] imageOffset = reader.ReadArray(24); // 2D IMAGE OFFSET


                //        if (tileID + 0x4000 == 0xa28d)
                //        {
                //            TileFlag f = (TileFlag) flags;

                //        }

                //        int count = reader.ReadByte();
                //        for (int j = 0; j < count; j++)
                //        {
                //            byte prop = reader.ReadByte();
                //            uint value = reader.ReadUInt();
                //        }

                //        count = reader.ReadByte();
                //        for (int j = 0; j < count; j++)
                //        {
                //            byte prop = reader.ReadByte();
                //            uint value = reader.ReadUInt();
                //        }

                //        count = reader.ReadInt(); // Gold Silver
                //        for (int j = 0; j < count; j++)
                //        {
                //            uint amount = reader.ReadUInt();
                //            uint id = reader.ReadUInt();
                //        }

                //        count = reader.ReadInt();

                //        for (int j = 0; j < count; j++)
                //        {
                //            byte val = reader.ReadByte();

                //            if (val != 0)
                //            {
                //                if (val == 1)
                //                {
                //                    byte unk = reader.ReadByte();
                //                    uint unk1 = reader.ReadUInt();
                //                }

                //            }
                //            else
                //            {
                //                int subCount = reader.ReadInt();

                //                for (int k = 0; k < subCount; k++)
                //                {
                //                    uint unk = reader.ReadUInt();
                //                    uint unk1 = reader.ReadUInt();
                //                }
                //            }
                //        }

                //        count = reader.ReadByte();

                //        if (count != 0)
                //        {
                //            uint unk = reader.ReadUInt();
                //            uint unk1 = reader.ReadUInt();
                //            uint unk2 = reader.ReadUInt();
                //            uint unk3 = reader.ReadUInt();
                //        }


                //        if (StaticData[tileID].AnimID == 0)
                //        {
                //            //StaticData[tileID] = new StaticTiles(flags, 0, 0, 0, );
                //        }


                //    }

                //    uop.Dispose();
                //    reader.ReleaseData();
                //}

                string pathdef = UOFileManager.GetUOFilePath("art.def");

                if (File.Exists(pathdef))
                {
                    using (DefReader reader = new DefReader(pathdef, 1))
                    {
                        while (reader.Next())
                        {
                            int index = reader.ReadInt();

                            if (index < 0 || index >= Constants.MAX_LAND_DATA_INDEX_COUNT + StaticData.Length)
                            {
                                continue;
                            }

                            int[] group = reader.ReadGroup();

                            if (group == null)
                            {
                                continue;
                            }

                            for (int i = 0; i < group.Length; i++)
                            {
                                int checkIndex = group[i];

                                if (checkIndex < 0 || checkIndex >= Constants.MAX_LAND_DATA_INDEX_COUNT + StaticData.Length)
                                {
                                    continue;
                                }

                                if (index < Constants.MAX_LAND_DATA_INDEX_COUNT && checkIndex < Constants.MAX_LAND_DATA_INDEX_COUNT && checkIndex < LandData.Length && index < LandData.Length && !LandData[checkIndex].Equals(default) && LandData[index].Equals(default))
Пример #11
0
        public override Task Load()
        {
            return(Task.Run
                   (
                       () =>
            {
                string path = UOFileManager.GetUOFilePath("soundLegacyMUL.uop");

                if (Client.IsUOPInstallation && File.Exists(path))
                {
                    _file = new UOFileUop(path, "build/soundlegacymul/{0:D8}.dat");
                    Entries = new UOFileIndex[Math.Max(((UOFileUop)_file).TotalEntriesCount, Constants.MAX_SOUND_DATA_INDEX_COUNT)];
                }
                else
                {
                    path = UOFileManager.GetUOFilePath("sound.mul");
                    string idxpath = UOFileManager.GetUOFilePath("soundidx.mul");

                    if (File.Exists(path) && File.Exists(idxpath))
                    {
                        _file = new UOFileMul(path, idxpath, Constants.MAX_SOUND_DATA_INDEX_COUNT);
                    }
                    else
                    {
                        throw new FileNotFoundException("no sounds found");
                    }
                }

                _file.FillEntries(ref Entries);

                string def = UOFileManager.GetUOFilePath("Sound.def");

                if (File.Exists(def))
                {
                    using (DefReader reader = new DefReader(def))
                    {
                        while (reader.Next())
                        {
                            int index = reader.ReadInt();

                            if (index < 0 || index >= Constants.MAX_SOUND_DATA_INDEX_COUNT ||
                                index >= _file.Length || Entries[index].Length != 0)
                            {
                                continue;
                            }

                            int[] group = reader.ReadGroup();

                            if (group == null)
                            {
                                continue;
                            }

                            for (int i = 0; i < group.Length; i++)
                            {
                                int checkIndex = group[i];

                                if (checkIndex < -1 || checkIndex >= Constants.MAX_SOUND_DATA_INDEX_COUNT)
                                {
                                    continue;
                                }

                                ref UOFileIndex ind = ref Entries[index];

                                if (checkIndex == -1)
                                {
                                    ind = default;
                                }
                                else
                                {
                                    ref readonly UOFileIndex outInd = ref Entries[checkIndex];
Пример #12
0
        public override Task Load()
        {
            return(Task.Run
                   (
                       () =>
            {
                if (string.IsNullOrEmpty(_cliloc))
                {
                    _cliloc = "Cliloc.enu";
                }

                string path = UOFileManager.GetUOFilePath(_cliloc);

                if (!File.Exists(path))
                {
                    Log.Error($"cliloc not found: '{path}'");
                    return;
                }

                if (string.Compare(_cliloc, "cliloc.enu", StringComparison.InvariantCultureIgnoreCase) != 0)
                {
                    string enupath = UOFileManager.GetUOFilePath("Cliloc.enu");

                    using (BinaryReader reader = new BinaryReader(new FileStream(enupath, FileMode.Open, FileAccess.Read)))
                    {
                        reader.ReadInt32();
                        reader.ReadInt16();

                        byte[] buffer = System.Buffers.ArrayPool <byte> .Shared.Rent(1024);

                        try
                        {
                            while (reader.BaseStream.Length != reader.BaseStream.Position)
                            {
                                int number = reader.ReadInt32();
                                byte flag = reader.ReadByte();
                                int length = reader.ReadInt16();

                                if (length > buffer.Length)
                                {
                                    System.Buffers.ArrayPool <byte> .Shared.Return(buffer);

                                    buffer = System.Buffers.ArrayPool <byte> .Shared.Rent((length + 1023) & ~1023);
                                }

                                reader.Read(buffer, 0, length);
                                string text = string.Intern(Encoding.UTF8.GetString(buffer, 0, length));

                                _entries[number] = text;
                            }
                        }
                        finally
                        {
                            System.Buffers.ArrayPool <byte> .Shared.Return(buffer);
                        }
                    }
                }

                using (BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read)))
                {
                    reader.ReadInt32();
                    reader.ReadInt16();
                    byte[] buffer = System.Buffers.ArrayPool <byte> .Shared.Rent(1024);

                    try
                    {
                        while (reader.BaseStream.Length != reader.BaseStream.Position)
                        {
                            int number = reader.ReadInt32();
                            byte flag = reader.ReadByte();
                            int length = reader.ReadInt16();

                            if (length > buffer.Length)
                            {
                                System.Buffers.ArrayPool <byte> .Shared.Return(buffer);

                                buffer = System.Buffers.ArrayPool <byte> .Shared.Rent((length + 1023) & ~1023);
                            }

                            reader.Read(buffer, 0, length);
                            string text = string.Intern(Encoding.UTF8.GetString(buffer, 0, length));

                            _entries[number] = text;
                        }
                    }
                    finally
                    {
                        System.Buffers.ArrayPool <byte> .Shared.Return(buffer);
                    }
                }
            }
                   ));
        }
Пример #13
0
            internal void CheckForShardMapFile(int mapId)
            {
                if (Entries == null)
                {
                    Entries = new UOFileIndex[Constants.MAPS_COUNT][];
                }

                string oldMap     = UOFileManager.GetUOFilePath($"map{mapId}.mul");
                string oldStaIdx  = UOFileManager.GetUOFilePath($"staidx{mapId}.mul");
                string oldStatics = UOFileManager.GetUOFilePath($"statics{mapId}.mul");

                //create file names
                string mapPath     = Path.Combine(_UL.ShardName, $"map{mapId}.mul");
                string staIdxPath  = Path.Combine(_UL.ShardName, $"staidx{mapId}.mul");
                string staticsPath = Path.Combine(_UL.ShardName, $"statics{mapId}.mul");

                if (!File.Exists(mapPath))
                {
                    UOFile mapFile = GetMapFile(mapId);

                    if (mapFile == null)
                    {
                        CreateNewPersistentMap(mapId, mapPath, staIdxPath, staticsPath);
                    }
                    else
                    {
                        if (mapFile is UOFileUop uop)
                        {
                            Entries[mapId] = new UOFileIndex[uop.TotalEntriesCount];
                            uop.FillEntries(ref Entries[mapId]);

                            Log.Trace($"UltimaLive -> converting file:\t{mapPath} from {uop.FilePath}");

                            using (FileStream stream = File.Create(mapPath))
                            {
                                for (int x = 0; x < Entries[mapId].Length; x++)
                                {
                                    uop.Seek(Entries[mapId][x].Offset);

                                    stream.Write(uop.ReadArray(Entries[mapId][x].Length), 0, Entries[mapId][x].Length);
                                }

                                stream.Flush();
                            }
                        }
                        else
                        {
                            CopyFile(oldMap, mapPath);
                        }
                    }
                }

                if (!File.Exists(staticsPath))
                {
                    CopyFile(oldStatics, staticsPath);
                }

                if (!File.Exists(staIdxPath))
                {
                    CopyFile(oldStaIdx, staIdxPath);
                }
            }
Пример #14
0
        public override Task Load()
        {
            return(Task.Run(() => {
                string path = UOFileManager.GetUOFilePath("gumpartLegacyMUL.uop");

                if (File.Exists(path))
                {
                    _file = new UOFileUop(path, "build/gumpartlegacymul/{0:D8}.tga", true);
                    Entries = new UOFileIndex[Constants.MAX_GUMP_DATA_INDEX_COUNT];
                    Client.UseUOPGumps = true;
                }
                else
                {
                    //Changed these filenames to be all lower-case as it was causing problems with File.Exists on iOS
                    //Checked a few shard installations, these files seem to be all lower-case anyways
                    path = UOFileManager.GetUOFilePath("gumpart.mul");
                    string pathidx = UOFileManager.GetUOFilePath("gumpidx.mul");

                    if (File.Exists(path) && File.Exists(pathidx))
                    {
                        _file = new UOFileMul(path, pathidx, Constants.MAX_GUMP_DATA_INDEX_COUNT, 12);
                    }
                    Client.UseUOPGumps = false;
                }
                _file.FillEntries(ref Entries);

                string pathdef = UOFileManager.GetUOFilePath("gump.def");

                if (!File.Exists(pathdef))
                {
                    return;
                }

                using (DefReader defReader = new DefReader(pathdef, 3))
                {
                    while (defReader.Next())
                    {
                        int ingump = defReader.ReadInt();

                        if (ingump < 0 || ingump >= Constants.MAX_GUMP_DATA_INDEX_COUNT ||
                            ingump >= Entries.Length ||
                            Entries[ingump].Length > 0)
                        {
                            continue;
                        }

                        int[] group = defReader.ReadGroup();

                        for (int i = 0; i < group.Length; i++)
                        {
                            int checkIndex = group[i];

                            if (checkIndex < 0 || checkIndex >= Constants.MAX_GUMP_DATA_INDEX_COUNT || checkIndex >= Entries.Length ||
                                Entries[checkIndex].Length <= 0)
                            {
                                continue;
                            }

                            Entries[ingump] = Entries[checkIndex];

                            break;
                        }
                    }
                }
            }));
        }
Пример #15
0
        public override Task Load()
        {
            return(Task.Run(() =>
            {
                bool foundOneMap = false;

                for (int i = 0; i < MAPS_COUNT; i++)
                {
                    string path = UOFileManager.GetUOFilePath($"map{i}LegacyMUL.uop");

                    if (File.Exists(path))
                    {
                        _filesMap[i] = new UOFileUop(path, $"build/map{i}legacymul/{{0:D8}}.dat");
                        Entries[i] = new UOFileIndex[((UOFileUop)_filesMap[i]).TotalEntriesCount];
                        ((UOFileUop)_filesMap[i]).FillEntries(ref Entries[i], false);
                        foundOneMap = true;
                    }
                    else
                    {
                        path = UOFileManager.GetUOFilePath($"map{i}.mul");

                        if (File.Exists(path))
                        {
                            _filesMap[i] = new UOFileMul(path);

                            foundOneMap = true;
                        }

                        path = UOFileManager.GetUOFilePath($"mapdifl{i}.mul");

                        if (File.Exists(path))
                        {
                            _mapDifl[i] = new UOFileMul(path);
                            _mapDif[i] = new UOFileMul(UOFileManager.GetUOFilePath($"mapdif{i}.mul"));
                            _staDifl[i] = new UOFileMul(UOFileManager.GetUOFilePath($"stadifl{i}.mul"));
                            _staDifi[i] = new UOFileMul(UOFileManager.GetUOFilePath($"stadifi{i}.mul"));
                            _staDif[i] = new UOFileMul(UOFileManager.GetUOFilePath($"stadif{i}.mul"));
                        }
                    }

                    path = UOFileManager.GetUOFilePath($"statics{i}.mul");
                    if (File.Exists(path))
                    {
                        _filesStatics[i] = new UOFileMul(path);
                    }
                    path = UOFileManager.GetUOFilePath($"staidx{i}.mul");
                    if (File.Exists(path))
                    {
                        _filesIdxStatics[i] = new UOFileMul(path);
                    }
                }

                if (!foundOneMap)
                {
                    throw new FileNotFoundException("No maps found.");
                }

                int mapblocksize = UnsafeMemoryManager.SizeOf <MapBlock>();

                if (_filesMap[0].Length / mapblocksize == 393216 || Client.Version < ClientVersion.CV_4011D)
                {
                    MapsDefaultSize[0, 0] = MapsDefaultSize[1, 0] = 6144;
                }

                //for (int i = 0; i < MAPS_COUNT; i++)
                Parallel.For(0, MAPS_COUNT, i =>
                {
                    MapBlocksSize[i, 0] = MapsDefaultSize[i, 0] >> 3;
                    MapBlocksSize[i, 1] = MapsDefaultSize[i, 1] >> 3;
                    LoadMap(i);
                });

                Entries = null;
            }));
        }
Пример #16
0
        public static void Load()
        {
            Log.Trace(">>>>>>>>>>>>> Loading >>>>>>>>>>>>>");

            string clientPath = Settings.GlobalSettings.UltimaOnlineDirectory;

            Log.Trace($"Ultima Online installation folder: {clientPath}");

            Log.Trace("Loading files...");

            if (!string.IsNullOrWhiteSpace(Settings.GlobalSettings.ClientVersion))
            {
                // sanitize client version
                Settings.GlobalSettings.ClientVersion = Settings.GlobalSettings.ClientVersion.Replace(",", ".").Replace(" ", "").ToLower();
            }

            string clientVersionText = Settings.GlobalSettings.ClientVersion;

            // check if directory is good
            if (!Directory.Exists(clientPath))
            {
                Log.Error("Invalid client directory: " + clientPath);
                ShowErrorMessage($"'{clientPath}' is not a valid UO directory");
                throw new InvalidClientDirectory($"'{clientPath}' is not a valid directory");
            }

            // try to load the client version
            if (!ClientVersionHelper.IsClientVersionValid(clientVersionText, out ClientVersion clientVersion))
            {
                Log.Warn($"Client version [{clientVersionText}] is invalid, let's try to read the client.exe");

                // mmm something bad happened, try to load from client.exe
                if (!ClientVersionHelper.TryParseFromFile(Path.Combine(clientPath, "client.exe"), out clientVersionText) ||
                    !ClientVersionHelper.IsClientVersionValid(clientVersionText, out clientVersion))
                {
                    Log.Error("Invalid client version: " + clientVersionText);
                    ShowErrorMessage($"Impossible to define the client version.\nClient version: '{clientVersionText}'");
                    throw new InvalidClientVersion($"Invalid client version: '{clientVersionText}'");
                }

                Log.Trace($"Found a valid client.exe [{clientVersionText} - {clientVersion}]");

                // update the wrong/missing client version in settings.json
                Settings.GlobalSettings.ClientVersion = clientVersionText;
            }

            Version           = clientVersion;
            ClientPath        = clientPath;
            IsUOPInstallation = Version >= ClientVersion.CV_7000 && File.Exists(UOFileManager.GetUOFilePath("MainMisc.uop"));
            Protocol          = ClientFlags.CF_T2A;

            if (Version >= ClientVersion.CV_200)
            {
                Protocol |= ClientFlags.CF_RE;
            }
            if (Version >= ClientVersion.CV_300)
            {
                Protocol |= ClientFlags.CF_TD;
            }
            if (Version >= ClientVersion.CV_308)
            {
                Protocol |= ClientFlags.CF_LBR;
            }
            if (Version >= ClientVersion.CV_308Z)
            {
                Protocol |= ClientFlags.CF_AOS;
            }
            if (Version >= ClientVersion.CV_405A)
            {
                Protocol |= ClientFlags.CF_SE;
            }
            if (Version >= ClientVersion.CV_60144)
            {
                Protocol |= ClientFlags.CF_SA;
            }

            Log.Trace($"Client path: '{clientPath}'");
            Log.Trace($"Client version: {clientVersion}");
            Log.Trace($"Protocol: {Protocol}");
            Log.Trace("UOP? " + (IsUOPInstallation ? "yes" : "no"));

            // ok now load uo files
            UOFileManager.Load();
            StaticFilters.Load();

            Log.Trace("Network calibration...");
            PacketHandlers.Load();
            //ATTENTION: you will need to enable ALSO ultimalive server-side, or this code will have absolutely no effect!
            //UltimaLive.Enable();
            PacketsTable.AdjustPacketSizeByVersion(Version);

            if (Settings.GlobalSettings.Encryption != 0)
            {
                Log.Trace("Calculating encryption by client version...");
                EncryptionHelper.CalculateEncryption(Version);
                Log.Trace($"encryption: {EncryptionHelper.Type}");

                if (EncryptionHelper.Type != (ENCRYPTION_TYPE)Settings.GlobalSettings.Encryption)
                {
                    Log.Warn($"Encryption found: {EncryptionHelper.Type}");
                    Settings.GlobalSettings.Encryption = (byte)EncryptionHelper.Type;
                }
            }

            Log.Trace("Done!");

            Log.Trace("Loading plugins...");

            foreach (var p in Settings.GlobalSettings.Plugins)
            {
                Plugin.Create(p);
            }
            Log.Trace("Done!");

            //UoAssist.Start();

            Log.Trace(">>>>>>>>>>>>> DONE >>>>>>>>>>>>>");
        }
Пример #17
0
        //private readonly List<uint> _usedIndex = new List<uint>();


        public override Task Load()
        {
            return(Task.Run(() =>
            {
                string path = UOFileManager.GetUOFilePath("texmaps.mul");
                string pathidx = UOFileManager.GetUOFilePath("texidx.mul");

                FileSystemHelper.EnsureFileExists(path);
                FileSystemHelper.EnsureFileExists(pathidx);

                _file = new UOFileMul(path, pathidx, Constants.MAX_LAND_TEXTURES_DATA_INDEX_COUNT, 10);
                _file.FillEntries(ref Entries);
                string pathdef = UOFileManager.GetUOFilePath("TexTerr.def");

                if (!File.Exists(pathdef))
                {
                    return;
                }

                using (DefReader defReader = new DefReader(pathdef))
                {
                    while (defReader.Next())
                    {
                        int index = defReader.ReadInt();

                        if (index < 0 || index >= Constants.MAX_LAND_TEXTURES_DATA_INDEX_COUNT)
                        {
                            continue;
                        }

                        int[] group = defReader.ReadGroup();

                        for (int i = 0; i < group.Length; i++)
                        {
                            int checkindex = group[i];

                            if (checkindex < 0 || checkindex >= Constants.MAX_LAND_TEXTURES_DATA_INDEX_COUNT)
                            {
                                continue;
                            }

                            Entries[index] = Entries[checkindex];
                        }
                    }
                }

                //using (StreamReader reader = new StreamReader(File.OpenRead(pathdef)))
                //{
                //    string line;

                //    while ((line = reader.ReadLine()) != null)
                //    {
                //        line = line.Trim();

                //        if (line.Length <= 0 || line[0] == '#')
                //            continue;

                //        string[] defs = line.Split(new[]
                //        {
                //            '\t', ' ', '#'
                //        }, StringSplitOptions.RemoveEmptyEntries);

                //        if (defs.Length < 2)
                //            continue;
                //        int index = int.Parse(defs[0]);

                //        if (index < 0 || index >= TEXTMAP_COUNT)
                //            continue;
                //        int first = defs[1].IndexOf("{");
                //        int last = defs[1].IndexOf("}");

                //        string[] newdef = defs[1].Substring(first + 1, last - 1).Split(new[]
                //        {
                //            ' ', ','
                //        }, StringSplitOptions.RemoveEmptyEntries);

                //        foreach (string s in newdef)
                //        {
                //            int checkindex = int.Parse(s);

                //            if (checkindex < 0 || checkindex >= TEXTMAP_COUNT)
                //                continue;
                //            _file.Entries[index] = _file.Entries[checkindex];
                //        }
                //    }
                //}
            }));
        }
Пример #18
0
        public static void Main(string[] args)
        {
            CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

            Log.Start(LogTypes.All);

            CUOEnviroment.GameThread      = Thread.CurrentThread;
            CUOEnviroment.GameThread.Name = "CUO_MAIN_THREAD";

#if !DEBUG
            AppDomain.CurrentDomain.UnhandledException += (s, e) =>
            {
                System.Text.StringBuilder sb = new System.Text.StringBuilder();
                sb.AppendLine("######################## [START LOG] ########################");

#if DEV_BUILD
                sb.AppendLine($"ClassicUO [DEV_BUILD] - {CUOEnviroment.Version} - {DateTime.Now}");
#else
                sb.AppendLine($"ClassicUO [STANDARD_BUILD] - {CUOEnviroment.Version} - {DateTime.Now}");
#endif

                sb.AppendLine
                    ($"OS: {Environment.OSVersion.Platform} {(Environment.Is64BitOperatingSystem ? "x64" : "x86")}");

                sb.AppendLine($"Thread: {Thread.CurrentThread.Name}");
                sb.AppendLine();

                if (Settings.GlobalSettings != null)
                {
                    sb.AppendLine($"Shard: {Settings.GlobalSettings.IP}");
                    sb.AppendLine($"ClientVersion: {Settings.GlobalSettings.ClientVersion}");
                    sb.AppendLine();
                }

                sb.AppendFormat("Exception:\n{0}\n", e.ExceptionObject);
                sb.AppendLine("######################## [END LOG] ########################");
                sb.AppendLine();
                sb.AppendLine();

                Log.Panic(e.ExceptionObject.ToString());
                string path = Path.Combine(CUOEnviroment.ExecutablePath, "Logs");

                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                using (LogFile crashfile = new LogFile(path, "crash.txt"))
                {
                    crashfile.WriteAsync(sb.ToString()).RunSynchronously();
                }
            };
#endif
            ReadSettingsFromArgs(args);

#if DEV_BUILD
            if (!_skipUpdates)
            {
                Network.Updater updater = new Network.Updater();
                if (updater.Check())
                {
                    return;
                }
            }
#endif

            if (!_skipUpdates)
            {
                if (CheckUpdate(args))
                {
                    return;
                }
            }

            if (CUOEnviroment.IsHighDPI)
            {
                Environment.SetEnvironmentVariable("FNA_GRAPHICS_ENABLE_HIGHDPI", "1");
            }

            Environment.SetEnvironmentVariable("FNA3D_BACKBUFFER_SCALE_NEAREST", "1");
            Environment.SetEnvironmentVariable("FNA3D_OPENGL_FORCE_COMPATIBILITY_PROFILE", "1");
            Environment.SetEnvironmentVariable(SDL.SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");

            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + Path.Combine(CUOEnviroment.ExecutablePath, "Data", "Plugins"));

            string globalSettingsPath = Settings.GetSettingsFilepath();

            if (!Directory.Exists(Path.GetDirectoryName(globalSettingsPath)) || !File.Exists(globalSettingsPath))
            {
                // settings specified in path does not exists, make new one
                {
                    // TODO:
                    Settings.GlobalSettings.Save();
                }
            }

            Settings.GlobalSettings  = ConfigurationResolver.Load <Settings>(globalSettingsPath);
            CUOEnviroment.IsOutlands = Settings.GlobalSettings.ShardType == 2;

            ReadSettingsFromArgs(args);

            // still invalid, cannot load settings
            if (Settings.GlobalSettings == null)
            {
                Settings.GlobalSettings = new Settings();
                Settings.GlobalSettings.Save();
            }

            if (!CUOEnviroment.IsUnix)
            {
                string libsPath = Path.Combine(CUOEnviroment.ExecutablePath, Environment.Is64BitProcess ? "x64" : "x86");

                SetDllDirectory(libsPath);
            }


            if (string.IsNullOrWhiteSpace(Settings.GlobalSettings.UltimaOnlineDirectory))
            {
                Settings.GlobalSettings.UltimaOnlineDirectory = CUOEnviroment.ExecutablePath;
            }

            const uint INVALID_UO_DIRECTORY = 0x100;
            const uint INVALID_UO_VERSION   = 0x200;

            uint flags = 0;

            if (!Directory.Exists(Settings.GlobalSettings.UltimaOnlineDirectory) || !File.Exists(UOFileManager.GetUOFilePath("tiledata.mul")))
            {
                flags |= INVALID_UO_DIRECTORY;
            }

            string clientVersionText = Settings.GlobalSettings.ClientVersion;

            if (!ClientVersionHelper.IsClientVersionValid(Settings.GlobalSettings.ClientVersion, out ClientVersion clientVersion))
            {
                Log.Warn($"Client version [{clientVersionText}] is invalid, let's try to read the client.exe");

                // mmm something bad happened, try to load from client.exe [windows only]
                if (!ClientVersionHelper.TryParseFromFile(Path.Combine(Settings.GlobalSettings.UltimaOnlineDirectory, "client.exe"), out clientVersionText) || !ClientVersionHelper.IsClientVersionValid(clientVersionText, out clientVersion))
                {
                    Log.Error("Invalid client version: " + clientVersionText);

                    flags |= INVALID_UO_VERSION;
                }
                else
                {
                    Log.Trace($"Found a valid client.exe [{clientVersionText} - {clientVersion}]");

                    // update the wrong/missing client version in settings.json
                    Settings.GlobalSettings.ClientVersion = clientVersionText;
                }
            }

            if (flags != 0)
            {
                if ((flags & INVALID_UO_DIRECTORY) != 0)
                {
                    Client.ShowErrorMessage(ResGeneral.YourUODirectoryIsInvalid);
                }
                else if ((flags & INVALID_UO_VERSION) != 0)
                {
                    Client.ShowErrorMessage(ResGeneral.YourUOClientVersionIsInvalid);
                }

                PlatformHelper.LaunchBrowser(ResGeneral.ClassicUOLink);
            }
            else
            {
                switch (Settings.GlobalSettings.ForceDriver)
                {
                case 1:     // OpenGL
                    Environment.SetEnvironmentVariable("FNA3D_FORCE_DRIVER", "OpenGL");

                    break;

                case 2:     // Vulkan
                    Environment.SetEnvironmentVariable("FNA3D_FORCE_DRIVER", "Vulkan");

                    break;
                }

                Client.Run();
            }

            Log.Trace("Closing...");
        }
Пример #19
0
        static void Main(string[] args)
        {
            // - check for update
            // - launcher & user setup
            // - game setup
            // - game launch
            // - enjoy

            CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

            Log.Start(LogTypes.All);

            CUOEnviroment.GameThread      = Thread.CurrentThread;
            CUOEnviroment.GameThread.Name = "CUO_MAIN_THREAD";


#if !DEBUG
            AppDomain.CurrentDomain.UnhandledException += (s, e) =>
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("######################## [START LOG] ########################");

#if DEV_BUILD
                sb.AppendLine($"ClassicUO [DEV_BUILD] - {CUOEnviroment.Version}");
#else
                sb.AppendLine($"ClassicUO [STANDARD_BUILD] - {CUOEnviroment.Version}");
#endif

                sb.AppendLine($"OS: {Environment.OSVersion.Platform} x{(Environment.Is64BitOperatingSystem ? "64" : "86")}");
                sb.AppendLine($"Thread: {Thread.CurrentThread.Name}");
                sb.AppendLine();

                sb.AppendLine($"Protocol: {Client.Protocol}");
                sb.AppendLine($"ClientFeatures: {World.ClientFeatures.Flags}");
                sb.AppendLine($"ClientLockedFeatures: {World.ClientLockedFeatures.Flags}");
                sb.AppendLine($"ClientVersion: {Client.Version}");

                sb.AppendLine();
                sb.AppendFormat("Exception:\n{0}\n", e.ExceptionObject);
                sb.AppendLine("######################## [END LOG] ########################");
                sb.AppendLine();
                sb.AppendLine();

                Log.Panic(e.ExceptionObject.ToString());
                string path = Path.Combine(CUOEnviroment.ExecutablePath, "Logs");

                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                using (LogFile crashfile = new LogFile(path, "crash.txt"))
                {
                    crashfile.WriteAsync(sb.ToString()).RunSynchronously();
                }
            };
#endif
            ReadSettingsFromArgs(args);

#if DEV_BUILD
            if (!_skipUpdates)
            {
                Updater updater = new Updater();
                if (updater.Check())
                {
                    return;
                }
            }
#endif

            if (!_skipUpdates)
            {
                if (CheckUpdate(args))
                {
                    return;
                }
            }

            if (CUOEnviroment.IsHighDPI)
            {
                Log.Trace("HIGH DPI - ENABLED");
                Environment.SetEnvironmentVariable("FNA_GRAPHICS_ENABLE_HIGHDPI", "1");
            }
            Environment.SetEnvironmentVariable("FNA3D_BACKBUFFER_SCALE_NEAREST", "1");
            Environment.SetEnvironmentVariable("FNA3D_OPENGL_FORCE_COMPATIBILITY_PROFILE", "1");
            Environment.SetEnvironmentVariable(SDL.SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + Path.Combine(CUOEnviroment.ExecutablePath, "Data", "Plugins"));


            string globalSettingsPath = Settings.GetSettingsFilepath();

            if ((!Directory.Exists(Path.GetDirectoryName(globalSettingsPath)) ||
                 !File.Exists(globalSettingsPath)))
            {
                // settings specified in path does not exists, make new one
                {
                    // TODO:
                    Settings.GlobalSettings.Save();
                }
            }

            Settings.GlobalSettings  = ConfigurationResolver.Load <Settings>(globalSettingsPath);
            CUOEnviroment.IsOutlands = Settings.GlobalSettings.ShardType == 2;

            ReadSettingsFromArgs(args);

            // still invalid, cannot load settings
            if (Settings.GlobalSettings == null)
            {
                Settings.GlobalSettings = new Settings();
                Settings.GlobalSettings.Save();
            }

            if (!CUOEnviroment.IsUnix)
            {
                string libsPath = Path.Combine(CUOEnviroment.ExecutablePath, Environment.Is64BitProcess ? "x64" : "x86");
                SetDllDirectory(libsPath);
            }

            // FIXME: force to use OpenGL in osx and linux contexts. Metal wants texture converted in .Color instead of BGRA5551.
            //        Check the branch "fna3d-macos-fix"

            /*if (CUOEnviroment.IsUnix)
             * {
             *  Environment.SetEnvironmentVariable("FNA3D_FORCE_DRIVER", "OpenGL");
             * }
             */

            if (string.IsNullOrWhiteSpace(Settings.GlobalSettings.UltimaOnlineDirectory))
            {
                Settings.GlobalSettings.UltimaOnlineDirectory = CUOEnviroment.ExecutablePath;
            }


            const uint INVALID_UO_DIRECTORY = 0x100;
            const uint INVALID_UO_VERSION   = 0x200;

            uint flags = 0;


            if (!Directory.Exists(Settings.GlobalSettings.UltimaOnlineDirectory) || !File.Exists(UOFileManager.GetUOFilePath("tiledata.mul")))
            {
                flags |= INVALID_UO_DIRECTORY;
            }


            string clientVersionText = Settings.GlobalSettings.ClientVersion;

            if (!ClientVersionHelper.IsClientVersionValid(Settings.GlobalSettings.ClientVersion, out var clientVersion))
            {
                Log.Warn($"Client version [{clientVersionText}] is invalid, let's try to read the client.exe");

                // mmm something bad happened, try to load from client.exe [windows only]
                if (!ClientVersionHelper.TryParseFromFile(Path.Combine(Settings.GlobalSettings.UltimaOnlineDirectory, "client.exe"), out clientVersionText) ||
                    !ClientVersionHelper.IsClientVersionValid(clientVersionText, out clientVersion))
                {
                    Log.Error("Invalid client version: " + clientVersionText);

                    flags |= INVALID_UO_VERSION;
                }
                else
                {
                    Log.Trace($"Found a valid client.exe [{clientVersionText} - {clientVersion}]");

                    // update the wrong/missing client version in settings.json
                    Settings.GlobalSettings.ClientVersion = clientVersionText;
                }
            }


            if (flags != 0)
            {
                if ((flags & INVALID_UO_DIRECTORY) != 0)
                {
                    Client.ShowErrorMessage("Your Ultima Online directory seems to be invalid.\nDownload the official Launcher to setup and run your game.\n\nLink: classicuo.eu");
                }
                else if ((flags & INVALID_UO_VERSION) != 0)
                {
                    Client.ShowErrorMessage("Your Ultima Online client version seems to be invalid.\nDownload the official Launcher to setup and run your game.\n\nLink: classicuo.eu");
                }

                try
                {
                    Process.Start("https://classicuo.eu");
                }
                catch { }
            }
            else
            {
                switch (Settings.GlobalSettings.ForceDriver)
                {
                case 1:     // OpenGL
                    Environment.SetEnvironmentVariable("FNA3D_FORCE_DRIVER", "OpenGL");

                    break;

                case 2:     // Vulkan
                    Environment.SetEnvironmentVariable("FNA3D_FORCE_DRIVER", "Vulkan");

                    break;
                }

                Client.Run();
            }


            Log.Trace("Closing...");
        }
Пример #20
0
        public static void LoadDefault()
        {
            FileInfo info = new FileInfo(UOFileManager.GetUOFilePath("skillgrp.mul"));

            if (!info.Exists)
            {
                Log.Info("skillgrp.mul not present, using CUO defaults!");
                MakeCUODefault();

                return;
            }

            Groups.Clear();
            Log.Info("Loading skillgrp.mul...");

            try
            {
                int  skillidx = 0;
                bool unicode  = false;

                using (BinaryReader bin = new BinaryReader(File.OpenRead(info.FullName)))
                {
                    int start  = 4;
                    int strlen = 17;
                    int count  = bin.ReadInt32();

                    if (count == -1)
                    {
                        unicode = true;
                        count   = bin.ReadInt32();
                        start  *= 2;
                        strlen *= 2;
                    }

                    List <string> groups = new List <string>
                    {
                        "Miscellaneous"
                    };
                    Groups.Add("Miscellaneous", new List <int>());
                    StringBuilder sb = new StringBuilder(17);

                    for (int i = 0; i < count - 1; ++i)
                    {
                        short strbuild;
                        bin.BaseStream.Seek(start + i * strlen, SeekOrigin.Begin);

                        if (unicode)
                        {
                            while ((strbuild = bin.ReadInt16()) != 0)
                            {
                                sb.Append((char)strbuild);
                            }
                        }
                        else
                        {
                            while ((strbuild = bin.ReadByte()) != 0)
                            {
                                sb.Append((char)strbuild);
                            }
                        }

                        groups.Add(sb.ToString());
                        Groups.Add(sb.ToString(), new List <int>());
                        sb.Clear();
                    }

                    bin.BaseStream.Seek(start + (count - 1) * strlen, SeekOrigin.Begin);

                    while (bin.BaseStream.Length != bin.BaseStream.Position)
                    {
                        int grp = bin.ReadInt32();

                        if (grp < groups.Count && skillidx + 1 < UOFileManager.Skills.SkillsCount)
                        {
                            Groups[groups[grp]].Add(skillidx++);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Debug($"Error while reading skillgrp.mul, using CUO defaults! exception given is: {e}");
                MakeCUODefault();
            }
        }