Beispiel #1
0
        public static bool save(string filename, ref OtbList 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(rootattrib_t.ROOT_ATTR_VERSION, property);

                    foreach (OtbItem item in items)
                    {
                        List <itemattrib_t> saveAttributeList = new List <itemattrib_t>();

                        saveAttributeList.Add(itemattrib_t.ITEM_ATTR_SERVERID);

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

                            if (item.minimapColor != 0)
                            {
                                saveAttributeList.Add(itemattrib_t.ITEM_ATTR_MINIMAPCOLOR);
                            }

                            if (item.maxReadWriteChars != 0)
                            {
                                saveAttributeList.Add(itemattrib_t.ITEM_ATTR_07);
                            }

                            if (item.maxReadChars != 0)
                            {
                                saveAttributeList.Add(itemattrib_t.ITEM_ATTR_08);
                            }

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

                            if (item.type == ItemType.Ground)
                            {
                                saveAttributeList.Add(itemattrib_t.ITEM_ATTR_SPEED);
                            }

                            if (item.alwaysOnTop)
                            {
                                saveAttributeList.Add(itemattrib_t.ITEM_ATTR_TOPORDER);
                            }

                            if (item.wareId != 0)
                            {
                                saveAttributeList.Add(itemattrib_t.ITEM_ATTR_WAREID);
                            }

                            if (!string.IsNullOrEmpty(item.name))
                            {
                                saveAttributeList.Add(itemattrib_t.ITEM_ATTR_NAME);
                            }
                        }

                        switch (item.type)
                        {
                        case ItemType.Container: writer.createNode((byte)itemgroup_t.ITEM_GROUP_CONTAINER); break;

                        case ItemType.Fluid: writer.createNode((byte)itemgroup_t.ITEM_GROUP_FLUID); break;

                        case ItemType.Ground: writer.createNode((byte)itemgroup_t.ITEM_GROUP_GROUND); break;

                        case ItemType.Splash: writer.createNode((byte)itemgroup_t.ITEM_GROUP_SPLASH); break;

                        case ItemType.Deprecated: writer.createNode((byte)itemgroup_t.ITEM_GROUP_DEPRECATED); break;

                        default: writer.createNode((byte)itemgroup_t.ITEM_GROUP_NONE); break;
                        }

                        UInt32 flags = 0;
                        if (item.blockObject)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_BLOCK_SOLID;
                        }

                        if (item.blockProjectile)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_BLOCK_PROJECTILE;
                        }

                        if (item.blockPathFind)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_BLOCK_PATHFIND;
                        }

                        if (item.hasHeight)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_HAS_HEIGHT;
                        }

                        if (item.hasUseWith)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_USEABLE;
                        }

                        if (item.isPickupable)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_PICKUPABLE;
                        }

                        if (item.isMoveable)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_MOVEABLE;
                        }

                        if (item.isStackable)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_STACKABLE;
                        }

                        if (item.alwaysOnTop)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_ALWAYSONTOP;
                        }

                        if (item.isReadable)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_READABLE;
                        }

                        if (item.isRotatable)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_ROTABLE;
                        }

                        if (item.isHangable)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_HANGABLE;
                        }

                        if (item.isVertical)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_VERTICAL;
                        }

                        if (item.isHorizontal)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_HORIZONTAL;
                        }

                        if (item.lookThrough)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_LOOKTHROUGH;
                        }

                        if (item.allowDistRead)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_ALLOWDISTREAD;
                        }

                        if (item.isAnimation)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_ANIMATION;
                        }

                        if (item.walkStack)
                        {
                            flags |= (UInt32)itemflags_t.FLAG_WALKSTACK;
                        }

                        writer.writeUInt32(flags, true);

                        foreach (itemattrib_t attribute in saveAttributeList)
                        {
                            switch (attribute)
                            {
                            case itemattrib_t.ITEM_ATTR_SERVERID:
                            {
                                property.Write((UInt16)item.id);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_SERVERID, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_WAREID:
                            {
                                property.Write((UInt16)item.wareId);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_WAREID, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_CLIENTID:
                            {
                                property.Write((UInt16)item.spriteId);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_CLIENTID, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_SPEED:
                            {
                                property.Write((UInt16)item.groundSpeed);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_SPEED, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_NAME:
                            {
                                for (UInt16 i = 0; i < item.name.Length; ++i)
                                {
                                    property.Write((char)item.name[i]);
                                }

                                writer.writeProp(itemattrib_t.ITEM_ATTR_NAME, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_SPRITEHASH:
                            {
                                property.Write(item.spriteHash);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_SPRITEHASH, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_MINIMAPCOLOR:
                            {
                                property.Write((UInt16)item.minimapColor);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_MINIMAPCOLOR, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_07:
                            {
                                property.Write((UInt16)item.maxReadWriteChars);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_07, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_08:
                            {
                                property.Write((UInt16)item.maxReadChars);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_08, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_LIGHT2:
                            {
                                property.Write((UInt16)item.lightLevel);
                                property.Write((UInt16)item.lightColor);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_LIGHT2, property);
                                break;
                            }

                            case itemattrib_t.ITEM_ATTR_TOPORDER:
                            {
                                property.Write((byte)item.alwaysOnTopOrder);
                                writer.writeProp(itemattrib_t.ITEM_ATTR_TOPORDER, property);
                                break;
                            }
                            }
                        }

                        writer.closeNode();
                    }

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

            return(true);
        }
Beispiel #2
0
        public static bool open(string filename, ref OtbList items, bool outputDebug)
        {
            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 ((rootattrib_t)attr == rootattrib_t.ROOT_ATTR_VERSION)
                    {
                        UInt16 datalen = nodeReader.ReadUInt16();
                        if (datalen != 4 + 4 + 4 + 1 * 128)
                        {
                            //error = wxT("items.otb: Size of version header is invalid, updated .otb version?");
                            if (outputDebug)
                            {
                                Trace.WriteLine(String.Format("Size of version header is invalid."));
                            }
                            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
                    {
                        OtbItem item = new OtbItem();

                        byte itemGroup = nodeReader.ReadByte();
                        if (outputDebug)
                        {
                            Trace.WriteLine(String.Format("Node:ItemGroup {0}", (itemgroup_t)itemGroup));
                        }

                        switch ((itemgroup_t)itemGroup)
                        {
                        case itemgroup_t.ITEM_GROUP_NONE: item.type = ItemType.None; break;

                        case itemgroup_t.ITEM_GROUP_GROUND: item.type = ItemType.Ground; break;

                        case itemgroup_t.ITEM_GROUP_SPLASH: item.type = ItemType.Splash; break;

                        case itemgroup_t.ITEM_GROUP_FLUID: item.type = ItemType.Fluid; break;

                        case itemgroup_t.ITEM_GROUP_CONTAINER: item.type = ItemType.Container; break;

                        case itemgroup_t.ITEM_GROUP_DEPRECATED: item.type = ItemType.Deprecated; break;

                        default: break;
                        }

                        itemflags_t flags = (itemflags_t)nodeReader.ReadUInt32();
                        if (outputDebug)
                        {
                            Trace.WriteLine(String.Format("Node:flags {0}", flags));
                        }

                        item.blockObject     = ((flags & itemflags_t.FLAG_BLOCK_SOLID) == itemflags_t.FLAG_BLOCK_SOLID);
                        item.blockProjectile = ((flags & itemflags_t.FLAG_BLOCK_PROJECTILE) == itemflags_t.FLAG_BLOCK_PROJECTILE);
                        item.blockPathFind   = ((flags & itemflags_t.FLAG_BLOCK_PATHFIND) == itemflags_t.FLAG_BLOCK_PATHFIND);
                        item.isPickupable    = ((flags & itemflags_t.FLAG_PICKUPABLE) == itemflags_t.FLAG_PICKUPABLE);
                        item.isMoveable      = ((flags & itemflags_t.FLAG_MOVEABLE) == itemflags_t.FLAG_MOVEABLE);
                        item.isStackable     = ((flags & itemflags_t.FLAG_STACKABLE) == itemflags_t.FLAG_STACKABLE);
                        item.alwaysOnTop     = ((flags & itemflags_t.FLAG_ALWAYSONTOP) == itemflags_t.FLAG_ALWAYSONTOP);
                        item.isVertical      = ((flags & itemflags_t.FLAG_VERTICAL) == itemflags_t.FLAG_VERTICAL);
                        item.isHorizontal    = ((flags & itemflags_t.FLAG_HORIZONTAL) == itemflags_t.FLAG_HORIZONTAL);
                        item.isHangable      = ((flags & itemflags_t.FLAG_HANGABLE) == itemflags_t.FLAG_HANGABLE);
                        item.isRotatable     = ((flags & itemflags_t.FLAG_ROTABLE) == itemflags_t.FLAG_ROTABLE);
                        item.isReadable      = ((flags & itemflags_t.FLAG_READABLE) == itemflags_t.FLAG_READABLE);
                        item.hasUseWith      = ((flags & itemflags_t.FLAG_USEABLE) == itemflags_t.FLAG_USEABLE);
                        item.hasHeight       = ((flags & itemflags_t.FLAG_HAS_HEIGHT) == itemflags_t.FLAG_HAS_HEIGHT);
                        item.lookThrough     = ((flags & itemflags_t.FLAG_LOOKTHROUGH) == itemflags_t.FLAG_LOOKTHROUGH);
                        item.allowDistRead   = ((flags & itemflags_t.FLAG_ALLOWDISTREAD) == itemflags_t.FLAG_ALLOWDISTREAD);
                        item.isAnimation     = ((flags & itemflags_t.FLAG_ANIMATION) == itemflags_t.FLAG_ANIMATION);
                        item.walkStack       = ((flags & itemflags_t.FLAG_WALKSTACK) == itemflags_t.FLAG_WALKSTACK);

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

                            if (outputDebug)
                            {
                                Trace.WriteLine(String.Format("Node[{0}]:attribut {1}, size: {2}",
                                                              reader.currentNodePos, ((itemattrib_t)attribute), datalen, reader.currentNodePos + nodeReader.BaseStream.Position));
                            }

                            switch ((itemattrib_t)attribute)
                            {
                            case itemattrib_t.ITEM_ATTR_SERVERID:
                            {
                                if (datalen != sizeof(UInt16))
                                {
                                    if (outputDebug)
                                    {
                                        Trace.WriteLine(String.Format("Unexpected data length of server id block (Should be 2 bytes)"));
                                    }
                                    return(false);
                                }

                                item.id = nodeReader.ReadUInt16();
                                if (outputDebug)
                                {
                                    System.Diagnostics.Debug.WriteLine(String.Format("Node:attribute:data {0}", item.id));
                                }
                            } break;

                            case itemattrib_t.ITEM_ATTR_CLIENTID:
                            {
                                if (datalen != sizeof(UInt16))
                                {
                                    if (outputDebug)
                                    {
                                        Trace.WriteLine(String.Format("Unexpected data length of client id block (Should be 2 bytes)"));
                                    }
                                    return(false);
                                }

                                item.spriteId = nodeReader.ReadUInt16();
                                if (outputDebug)
                                {
                                    Trace.WriteLine(String.Format("Node:attribute:data {0}", item.spriteId));
                                }
                            } break;

                            case itemattrib_t.ITEM_ATTR_WAREID:
                            {
                                if (datalen != sizeof(UInt16))
                                {
                                    if (outputDebug)
                                    {
                                        Trace.WriteLine(String.Format("Unexpected data length of ware id block (Should be 2 bytes)"));
                                    }
                                    return(false);
                                }

                                item.wareId = nodeReader.ReadUInt16();
                                if (outputDebug)
                                {
                                    Trace.WriteLine(String.Format("Node:attribute:data {0}", item.wareId));
                                }
                            } break;

                            case itemattrib_t.ITEM_ATTR_SPEED:
                            {
                                if (datalen != sizeof(UInt16))
                                {
                                    if (outputDebug)
                                    {
                                        Trace.WriteLine(String.Format("Unexpected data length of speed block (Should be 2 bytes)"));
                                    }
                                    return(false);
                                }

                                item.groundSpeed = nodeReader.ReadUInt16();
                                if (outputDebug)
                                {
                                    Trace.WriteLine(String.Format("Node:attribute:data {0}", item.groundSpeed));
                                }
                            } break;

                            case itemattrib_t.ITEM_ATTR_NAME:
                            {
                                item.name = new string(nodeReader.ReadChars(datalen));
                                if (outputDebug)
                                {
                                    Trace.WriteLine(String.Format("Node:attribute:data {0}", item.name));
                                }
                            } break;

                            case itemattrib_t.ITEM_ATTR_SPRITEHASH:
                            {
                                if (datalen != 16)
                                {
                                    return(false);
                                }

                                item.spriteHash = nodeReader.ReadBytes(16);
                                if (outputDebug)
                                {
                                    Trace.WriteLine(String.Format("Node:attribute:data {0}", item.alwaysOnTopOrder));
                                }
                            } break;

                            case itemattrib_t.ITEM_ATTR_MINIMAPCOLOR:
                            {
                                if (datalen != 2)
                                {
                                    return(false);
                                }

                                item.minimapColor = nodeReader.ReadUInt16();
                                if (outputDebug)
                                {
                                    Trace.WriteLine(String.Format("Node:attribute:data {0}", item.minimapColor));
                                }
                            } break;

                            case itemattrib_t.ITEM_ATTR_07:
                            {
                                //read/write-able
                                if (datalen != 2)
                                {
                                    return(false);
                                }

                                item.maxReadWriteChars = nodeReader.ReadUInt16();
                            } break;

                            case itemattrib_t.ITEM_ATTR_08:
                            {
                                //readable
                                if (datalen != 2)
                                {
                                    return(false);
                                }

                                item.maxReadChars = nodeReader.ReadUInt16();
                            } break;

                            case itemattrib_t.ITEM_ATTR_LIGHT2:
                            {
                                if (datalen != sizeof(UInt16) * 2)
                                {
                                    if (outputDebug)
                                    {
                                        Trace.WriteLine(String.Format("Unexpected data length of item light (2) block"));
                                    }
                                    return(false);
                                }

                                item.lightLevel = nodeReader.ReadUInt16();
                                item.lightColor = nodeReader.ReadUInt16();
                                if (outputDebug)
                                {
                                    Trace.WriteLine(String.Format("Node:attribute:data {0}, {1}", item.lightLevel, item.lightColor));
                                }
                            } break;

                            case itemattrib_t.ITEM_ATTR_TOPORDER:
                            {
                                if (datalen != sizeof(byte))
                                {
                                    if (outputDebug)
                                    {
                                        Trace.WriteLine(String.Format("Unexpected data length of item toporder block (Should be 1 byte)"));
                                    }
                                    return(false);
                                }

                                item.alwaysOnTopOrder = nodeReader.ReadByte();
                                if (outputDebug)
                                {
                                    Trace.WriteLine(String.Format("Node:attribute:data {0}", item.alwaysOnTopOrder));
                                }
                            } break;

                            default:
                            {
                                //skip unknown attributes
                                nodeReader.BaseStream.Seek(datalen, SeekOrigin.Current);
                                if (outputDebug)
                                {
                                    Trace.WriteLine(String.Format("Skipped unknown attribute"));
                                }
                            } break;
                            }
                        }

                        items.Add(item);

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

            return(true);
        }