public void CreateEmptyOTB(string filePath, SupportedClient client, bool isTemporary = true) { ServerItem item = new ServerItem(); item.SpriteHash = new byte[16]; item.ClientId = 100; item.ID = 100; ServerItemList items = new ServerItemList(); items.MajorVersion = 3; items.MinorVersion = client.OtbVersion; items.BuildNumber = 1; items.ClientVersion = client.Version; items.Add(item); if (!File.Exists(filePath)) { using (File.Create(filePath)) { //// } } OtbWriter writer = new OtbWriter(items); if (writer.Write(filePath)) { this.Open(filePath); this.IsTemporary = isTemporary; this.Saved = !isTemporary; } }
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); }
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); }
public void Open(string path = null) { if (string.IsNullOrEmpty(path)) { FileDialog dialog = new OpenFileDialog(); dialog.Filter = "OTB files (*.otb)|*.otb"; dialog.Title = "Open OTB File"; if (dialog.ShowDialog() != DialogResult.OK || dialog.FileName.Length == 0) { return; } path = dialog.FileName; this.IsTemporary = false; this.Saved = true; } if (this.Loaded) { this.Clear(); } OtbReader reader = new OtbReader(); if (reader.Read(path)) { this.serverItems = reader.Items; this.CurrentOtbFullPath = path; this.CurrentOtbVersion = this.serverItems.MinorVersion; // try find a plugin that can handle this version of otb this.CurrentPlugin = Program.plugins.AvailablePlugins.Find(this.CurrentOtbVersion); if (this.CurrentPlugin == null) { this.serverItems.Clear(); MessageBox.Show(string.Format("Could not find a plugin that could handle client version {0}", this.CurrentOtbVersion)); return; } if (!this.LoadClient(this.CurrentPlugin, this.CurrentOtbVersion)) { this.Clear(false); return; } this.fileSaveAsMenuItem.Enabled = true; this.fileSaveMenuItem.Enabled = true; this.editCreateItemMenuItem.Enabled = true; this.editFindItemMenuItem.Enabled = true; this.viewShowOnlyMismatchedMenuItem.Enabled = true; this.viewShowDecaptedItemsMenuItem.Enabled = true; this.viewUpdateItemsListMenuItem.Enabled = true; this.toolsUpdateVersionMenuItem.Enabled = true; this.toolsReloadItemAttributesMenuItem.Enabled = true; this.toolStripSaveButton.Enabled = true; this.toolStripSaveAsButton.Enabled = true; this.toolStripFindItemButton.Enabled = true; this.serverItemListBox.Plugin = this.CurrentPlugin.Instance; this.serverItemListBox.Enabled = true; this.newItemButton.Enabled = true; this.duplicateItemButton.Enabled = true; this.reloadItemButton.Enabled = true; this.findItemButton.Enabled = true; this.Loaded = true; this.BuildItemsListBox(); } }