Пример #1
0
        public static bool Save(string filename, ref ServerItemList items)
        {
            FileStream fileStream = new FileStream(filename, FileMode.Create);

            try
            {
                using (OtbLoader writer = new OtbLoader(fileStream))
                {
                    writer.WriteUInt32(0, false);             //version, always 0

                    writer.CreateNode(0);                     //root node
                    writer.WriteUInt32(0, true);              //flags, unused for root node

                    VersionInfo vi = new VersionInfo();

                    vi.dwMajorVersion = items.dwMajorVersion;
                    vi.dwMinorVersion = items.dwMinorVersion;
                    vi.dwBuildNumber  = items.dwBuildNumber;
                    vi.CSDVersion     = String.Format("OTB {0}.{1}.{2}-{3}.{4}", vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, items.clientVersion / 100, items.clientVersion % 100);

                    MemoryStream ms       = new MemoryStream();
                    BinaryWriter property = new BinaryWriter(ms);
                    property.Write(vi.dwMajorVersion);
                    property.Write(vi.dwMinorVersion);
                    property.Write(vi.dwBuildNumber);
                    byte[] CSDVersion = System.Text.Encoding.ASCII.GetBytes(vi.CSDVersion);
                    Array.Resize(ref CSDVersion, 128);
                    property.Write(CSDVersion);

                    writer.WriteProp(RootAttribute.ROOT_ATTR_VERSION, property);

                    foreach (ServerItem item in items)
                    {
                        List <ItemAttribute> saveAttributeList = new List <ItemAttribute>();
                        saveAttributeList.Add(ItemAttribute.SERVER_ID);

                        if (item.type == ItemType.Deprecated)
                        {
                            //no other attributes should be saved for this type
                        }
                        else
                        {
                            saveAttributeList.Add(ItemAttribute.CLIENT_ID);
                            saveAttributeList.Add(ItemAttribute.SPRITE_HASH);

                            if (item.minimapColor != 0)
                            {
                                saveAttributeList.Add(ItemAttribute.MINIMAP_COLOR);
                            }

                            if (item.maxReadWriteChars != 0)
                            {
                                saveAttributeList.Add(ItemAttribute.MAX_READ_WRITE_CHARS);
                            }

                            if (item.maxReadChars != 0)
                            {
                                saveAttributeList.Add(ItemAttribute.MAX_READ_CHARS);
                            }

                            if (item.lightLevel != 0 || item.lightColor != 0)
                            {
                                saveAttributeList.Add(ItemAttribute.LIGHT);
                            }

                            if (item.type == ItemType.Ground)
                            {
                                saveAttributeList.Add(ItemAttribute.GROUND_SPEED);
                            }

                            if (item.alwaysOnTop)
                            {
                                saveAttributeList.Add(ItemAttribute.TOP_ORDER);
                            }

                            if (item.tradeAs != 0)
                            {
                                saveAttributeList.Add(ItemAttribute.TRADE_AS);
                            }

                            if (!string.IsNullOrEmpty(item.name))
                            {
                                saveAttributeList.Add(ItemAttribute.NAME);
                            }
                        }

                        switch (item.type)
                        {
                        case ItemType.Container: writer.CreateNode((byte)ItemGroup.CONTAINER); break;

                        case ItemType.Fluid: writer.CreateNode((byte)ItemGroup.FLUID); break;

                        case ItemType.Ground: writer.CreateNode((byte)ItemGroup.GROUND); break;

                        case ItemType.Splash: writer.CreateNode((byte)ItemGroup.SPLASH); break;

                        case ItemType.Deprecated: writer.CreateNode((byte)ItemGroup.DEPRECATED); break;

                        default: writer.CreateNode((byte)ItemGroup.NONE); break;
                        }

                        UInt32 flags = 0;
                        if (item.isUnpassable)
                        {
                            flags |= (UInt32)ItemFlag.BLOCK_SOLID;
                        }
                        if (item.blockMissiles)
                        {
                            flags |= (UInt32)ItemFlag.BLOCK_MISSILE;
                        }
                        if (item.blockPathfinder)
                        {
                            flags |= (UInt32)ItemFlag.BLOCK_PATHFINDER;
                        }
                        if (item.hasElevation)
                        {
                            flags |= (UInt32)ItemFlag.HAS_ELEVATION;
                        }
                        if (item.multiUse)
                        {
                            flags |= (UInt32)ItemFlag.USEABLE;
                        }
                        if (item.isPickupable)
                        {
                            flags |= (UInt32)ItemFlag.PICKUPABLE;
                        }
                        if (item.isMoveable)
                        {
                            flags |= (UInt32)ItemFlag.MOVEABLE;
                        }
                        if (item.isStackable)
                        {
                            flags |= (UInt32)ItemFlag.STACKABLE;
                        }
                        if (item.alwaysOnTop)
                        {
                            flags |= (UInt32)ItemFlag.ALWAYS_ON_TOP;
                        }
                        if (item.isReadable)
                        {
                            flags |= (UInt32)ItemFlag.READABLE;
                        }
                        if (item.isRotatable)
                        {
                            flags |= (UInt32)ItemFlag.ROTABLE;
                        }
                        if (item.isHangable)
                        {
                            flags |= (UInt32)ItemFlag.HANGABLE;
                        }
                        if (item.isVertical)
                        {
                            flags |= (UInt32)ItemFlag.VERTICAL_WALL;
                        }
                        if (item.isHorizontal)
                        {
                            flags |= (UInt32)ItemFlag.HORIZONTAL_WALL;
                        }
                        if (item.ignoreLook)
                        {
                            flags |= (UInt32)ItemFlag.IGNORE_LOOK;
                        }
                        if (item.allowDistRead)
                        {
                            flags |= (UInt32)ItemFlag.ALLOW_DISTANCE_READ;
                        }
                        if (item.isAnimation)
                        {
                            flags |= (UInt32)ItemFlag.ANIMATION;
                        }
                        if (item.fullGround)
                        {
                            flags |= (UInt32)ItemFlag.FULL_GROUND;
                        }

                        writer.WriteUInt32(flags, true);

                        foreach (ItemAttribute attribute in saveAttributeList)
                        {
                            switch (attribute)
                            {
                            case ItemAttribute.SERVER_ID:
                                property.Write((UInt16)item.id);
                                writer.WriteProp(ItemAttribute.SERVER_ID, property);

                                break;

                            case ItemAttribute.TRADE_AS:
                                property.Write((UInt16)item.tradeAs);
                                writer.WriteProp(ItemAttribute.TRADE_AS, property);
                                break;

                            case ItemAttribute.CLIENT_ID:
                                property.Write((UInt16)item.spriteId);
                                writer.WriteProp(ItemAttribute.CLIENT_ID, property);
                                break;

                            case ItemAttribute.GROUND_SPEED:
                                property.Write((UInt16)item.groundSpeed);
                                writer.WriteProp(ItemAttribute.GROUND_SPEED, property);
                                break;

                            case ItemAttribute.NAME:
                                for (UInt16 i = 0; i < item.name.Length; ++i)
                                {
                                    property.Write((char)item.name[i]);
                                }
                                writer.WriteProp(ItemAttribute.NAME, property);
                                break;

                            case ItemAttribute.SPRITE_HASH:
                                property.Write(item.SpriteHash);
                                writer.WriteProp(ItemAttribute.SPRITE_HASH, property);
                                break;

                            case ItemAttribute.MINIMAP_COLOR:
                                property.Write((UInt16)item.minimapColor);
                                writer.WriteProp(ItemAttribute.MINIMAP_COLOR, property);
                                break;

                            case ItemAttribute.MAX_READ_WRITE_CHARS:
                                property.Write((UInt16)item.maxReadWriteChars);
                                writer.WriteProp(ItemAttribute.MAX_READ_WRITE_CHARS, property);
                                break;

                            case ItemAttribute.MAX_READ_CHARS:
                                property.Write((UInt16)item.maxReadChars);
                                writer.WriteProp(ItemAttribute.MAX_READ_CHARS, property);
                                break;

                            case ItemAttribute.LIGHT:
                                property.Write((UInt16)item.lightLevel);
                                property.Write((UInt16)item.lightColor);
                                writer.WriteProp(ItemAttribute.LIGHT, property);
                                break;

                            case ItemAttribute.TOP_ORDER:
                                property.Write((byte)item.alwaysOnTopOrder);
                                writer.WriteProp(ItemAttribute.TOP_ORDER, property);
                                break;
                            }
                        }

                        writer.CloseNode();
                    }

                    writer.CloseNode();
                }
            }
            finally
            {
                fileStream.Close();
            }

            return(true);
        }
Пример #2
0
        public static bool Open(string filename, ref ServerItemList items)
        {
            FileStream fileStream = new FileStream(filename, FileMode.Open);

            try
            {
                using (OtbLoader reader = new OtbLoader(fileStream))
                {
                    //get root node
                    BinaryReader nodeReader = reader.getRootNode();
                    if (nodeReader == null)
                    {
                        return(false);
                    }

                    nodeReader.ReadByte();                     //first byte of otb is 0
                    nodeReader.ReadUInt32();                   //4 bytes flags, unused

                    byte attr = nodeReader.ReadByte();
                    if ((RootAttribute)attr == RootAttribute.ROOT_ATTR_VERSION)
                    {
                        UInt16 datalen = nodeReader.ReadUInt16();
                        if (datalen != 140)                         // 4 + 4 + 4 + 1 * 128
                        {
                            Trace.WriteLine(String.Format("Size of version header is invalid, updated .otb version?"));
                            return(false);
                        }

                        items.dwMajorVersion = nodeReader.ReadUInt32();                         //major, file version
                        items.dwMinorVersion = nodeReader.ReadUInt32();                         //minor, client version
                        items.dwBuildNumber  = nodeReader.ReadUInt32();                         //build number, revision
                        nodeReader.BaseStream.Seek(128, SeekOrigin.Current);
                    }

                    nodeReader = reader.getChildNode();
                    if (nodeReader == null)
                    {
                        return(false);
                    }

                    do
                    {
                        ServerItem item = new ServerItem();

                        byte itemGroup = nodeReader.ReadByte();

                        switch ((ItemGroup)itemGroup)
                        {
                        case ItemGroup.NONE: item.type = ItemType.None; break;

                        case ItemGroup.GROUND: item.type = ItemType.Ground; break;

                        case ItemGroup.SPLASH: item.type = ItemType.Splash; break;

                        case ItemGroup.FLUID: item.type = ItemType.Fluid; break;

                        case ItemGroup.CONTAINER: item.type = ItemType.Container; break;

                        case ItemGroup.DEPRECATED: item.type = ItemType.Deprecated; break;

                        default: break;
                        }

                        ItemFlag flags = (ItemFlag)nodeReader.ReadUInt32();

                        item.isUnpassable    = ((flags & ItemFlag.BLOCK_SOLID) == ItemFlag.BLOCK_SOLID);
                        item.blockMissiles   = ((flags & ItemFlag.BLOCK_MISSILE) == ItemFlag.BLOCK_MISSILE);
                        item.blockPathfinder = ((flags & ItemFlag.BLOCK_PATHFINDER) == ItemFlag.BLOCK_PATHFINDER);
                        item.isPickupable    = ((flags & ItemFlag.PICKUPABLE) == ItemFlag.PICKUPABLE);
                        item.isMoveable      = ((flags & ItemFlag.MOVEABLE) == ItemFlag.MOVEABLE);
                        item.isStackable     = ((flags & ItemFlag.STACKABLE) == ItemFlag.STACKABLE);
                        item.alwaysOnTop     = ((flags & ItemFlag.ALWAYS_ON_TOP) == ItemFlag.ALWAYS_ON_TOP);
                        item.isVertical      = ((flags & ItemFlag.VERTICAL_WALL) == ItemFlag.VERTICAL_WALL);
                        item.isHorizontal    = ((flags & ItemFlag.HORIZONTAL_WALL) == ItemFlag.HORIZONTAL_WALL);
                        item.isHangable      = ((flags & ItemFlag.HANGABLE) == ItemFlag.HANGABLE);
                        item.isRotatable     = ((flags & ItemFlag.ROTABLE) == ItemFlag.ROTABLE);
                        item.isReadable      = ((flags & ItemFlag.READABLE) == ItemFlag.READABLE);
                        item.multiUse        = ((flags & ItemFlag.USEABLE) == ItemFlag.USEABLE);
                        item.hasElevation    = ((flags & ItemFlag.HAS_ELEVATION) == ItemFlag.HAS_ELEVATION);
                        item.ignoreLook      = ((flags & ItemFlag.IGNORE_LOOK) == ItemFlag.IGNORE_LOOK);
                        item.allowDistRead   = ((flags & ItemFlag.ALLOW_DISTANCE_READ) == ItemFlag.ALLOW_DISTANCE_READ);
                        item.isAnimation     = ((flags & ItemFlag.ANIMATION) == ItemFlag.ANIMATION);
                        item.fullGround      = ((flags & ItemFlag.FULL_GROUND) == ItemFlag.FULL_GROUND);

                        while (nodeReader.PeekChar() != -1)
                        {
                            ItemAttribute attribute = (ItemAttribute)nodeReader.ReadByte();
                            UInt16        datalen   = nodeReader.ReadUInt16();

                            switch (attribute)
                            {
                            case ItemAttribute.SERVER_ID:
                                item.id = nodeReader.ReadUInt16();
                                break;

                            case ItemAttribute.CLIENT_ID:
                                item.spriteId = nodeReader.ReadUInt16();
                                break;

                            case ItemAttribute.GROUND_SPEED:
                                item.groundSpeed = nodeReader.ReadUInt16();
                                break;

                            case ItemAttribute.NAME:
                                item.name = new string(nodeReader.ReadChars(datalen));
                                break;

                            case ItemAttribute.SPRITE_HASH:
                                item.SpriteHash = nodeReader.ReadBytes(datalen);
                                break;

                            case ItemAttribute.MINIMAP_COLOR:
                                item.minimapColor = nodeReader.ReadUInt16();
                                break;

                            case ItemAttribute.MAX_READ_WRITE_CHARS:
                                item.maxReadWriteChars = nodeReader.ReadUInt16();
                                break;

                            case ItemAttribute.MAX_READ_CHARS:
                                item.maxReadChars = nodeReader.ReadUInt16();
                                break;

                            case ItemAttribute.LIGHT:
                                item.lightLevel = nodeReader.ReadUInt16();
                                item.lightColor = nodeReader.ReadUInt16();
                                break;

                            case ItemAttribute.TOP_ORDER:
                                item.alwaysOnTopOrder = nodeReader.ReadByte();
                                break;

                            case ItemAttribute.TRADE_AS:
                                item.tradeAs = nodeReader.ReadUInt16();
                                break;

                            default:
                                nodeReader.BaseStream.Seek(datalen, SeekOrigin.Current);
                                break;
                            }
                        }

                        if (item.SpriteHash == null && item.type != ItemType.Deprecated)
                        {
                            item.SpriteHash = new byte[16];
                        }

                        items.Add(item);
                        nodeReader = reader.getNextNode();
                    } while (nodeReader != null);
                }
            }
            finally
            {
                fileStream.Close();
            }

            return(true);
        }