private static void LoadOtb(string fileName) { var loader = new FileLoader(); loader.OpenFile(fileName); var node = loader.GetRootNode(); PropertyReader props; if (loader.GetProps(node, out props)) { props.ReadByte(); //junk? // 4 byte flags // attributes // 0x01 = version data var flags = props.ReadUInt32(); var attr = props.ReadByte(); if (attr == 0x01) { var datalen = props.ReadUInt16(); if (datalen != 140) throw new Exception("Invalid item.otb file."); MajorVersion = props.ReadUInt32(); MinorVersion = props.ReadUInt32(); BuildNumber = props.ReadUInt32(); } } if (MajorVersion == 0xFFFFFFFF) Logger.Warn("items.otb using generic client version."); else if (MajorVersion < 3) { throw new Exception("Old version of items.otb detected, a newer version of items.otb is required."); } else if (MajorVersion > 3) { throw new Exception("New version of items.otb detected, a newer version of the server is required."); } //else if(Items::dwMinorVersion != CLIENT_VERSION_861){ // std::cout << "Another (client) version of items.otb is required." << std::endl; // return ERROR_INVALID_FORMAT; //} node = node.Child; while (node != null) { if (!loader.GetProps(node, out props)) throw new Exception("Invalid item.otb file."); var type = new ItemType { Group = (ItemGroup)node.Type }; var flags = (ItemFlags)props.ReadUInt32(); type.IsBlocking = (flags & ItemFlags.BlocksSolid) != 0; type.IsProjectileBlocking = (flags & ItemFlags.BlocksProjectile) != 0; type.IsPathBlocking = (flags & ItemFlags.BlocksPathFinding) != 0; type.HasHeight = (flags & ItemFlags.HasHeight) != 0; type.IsUseable = (flags & ItemFlags.Useable) != 0; type.IsPickupable = (flags & ItemFlags.Pickupable) != 0; type.IsMoveable = (flags & ItemFlags.Moveable) != 0; type.IsStackable = (flags & ItemFlags.Stackable) != 0; type.IsAlwaysOnTop = (flags & ItemFlags.AlwaysOnTop) != 0; type.IsVertical = (flags & ItemFlags.Vertical) != 0; type.IsHorizontal = (flags & ItemFlags.Horizontal) != 0; type.IsHangable = (flags & ItemFlags.Hangable) != 0; type.IsDistanceReadable = (flags & ItemFlags.AllowDistanceRead) != 0; type.IsRotatable = (flags & ItemFlags.Rotatable) != 0; type.IsReadable = (flags & ItemFlags.Readable) != 0; type.HasClientCharges = (flags & ItemFlags.ClientCharges) != 0; type.CanLookThrough = (flags & ItemFlags.LookThrough) != 0; // process flags while (props.PeekChar() != -1) { var attr = props.ReadByte(); var datalen = props.ReadUInt16(); switch ((ItemAttribute)attr) { case ItemAttribute.ServerId: type.Id = props.ReadUInt16(); if (type.Id > 20000) { throw new Exception(string.Format("Invalid item id {0}.", type.Id)); } break; case ItemAttribute.ClientId: type.ClientId = props.ReadUInt16(); break; case ItemAttribute.Speed: type.Speed = props.ReadUInt16(); break; case ItemAttribute.Light2: type.LightLevel = props.ReadUInt16(); type.LightColor = props.ReadUInt16(); break; case ItemAttribute.TopOrder: type.TopOrder = props.ReadByte(); break; default: props.ReadBytes(datalen); break; } } if (TYPES.ContainsKey(type.Id)) Logger.Warn(string.Format("Duplicated item with id {0}", type.Id)); else TYPES.Add(type.Id, type); node = node.Next; } }
public void Load(string fileName) { if (!File.Exists(fileName)) throw new Exception(string.Format("File not found {0}.", fileName)); var loader = new FileLoader(); loader.OpenFile(fileName); var node = loader.GetRootNode(); PropertyReader props; if (!loader.GetProps(node, out props)) throw new Exception("Could not read root property."); props.ReadByte(); // junk? var version = props.ReadUInt32(); var width = props.ReadUInt16(); var height = props.ReadUInt16(); var majorVersionItems = props.ReadUInt32(); var minorVersionItems = props.ReadUInt32(); if (version <= 0) { //In otbm version 1 the count variable after splashes/fluidcontainers and stackables //are saved as attributes instead, this solves alot of problems with items //that is changed (stackable/charges/fluidcontainer/splash) during an update. throw new Exception("This map needs to be upgraded by using the latest map editor version to be able to load correctly."); } if (version > 2) throw new Exception("Unknown OTBM version detected, please update your server."); if (majorVersionItems < 3) throw new Exception("This map needs to be upgraded by using the latest map editor version to be able to load correctly."); //if (MajorVersionItems > ItemInfo.MajorVersion) //{ // Log.Error("The map was saved with a different items.otb version, an upgraded items.otb is required."); // return false; //} if (minorVersionItems < (uint)ClientVersion.ClientVersion810) throw new Exception("This map needs to be updated."); //if (MinorVersionItems > ItemInfo.MinorVersion) // Log.Warn("This map needs an updated items.otb."); //if (MinorVersionItems == (uint)ClientVersion.ClientVersion854Bad) // Log.Warn("This map needs uses an incorrect version of items.otb."); Logger.Info(string.Format("Map size: {0}x{1}", width, height)); node = node.Child; if ((OtbMapNodeType)node.Type != OtbMapNodeType.MapData) throw new Exception("Could not read data node."); if (!loader.GetProps(node, out props)) throw new Exception("Could not read map data attributes."); while (props.PeekChar() != -1) { byte attribute = props.ReadByte(); switch ((OtbmAttribute)attribute) { case OtbmAttribute.Description: var description = props.GetString(); Logger.Info(string.Format("Map Description: {0}", description)); break; case OtbmAttribute.ExtSpawnFile: var spawnFile = props.GetString(); break; case OtbmAttribute.ExtHouseFile: var houseFile = props.GetString(); break; default: throw new Exception("Unknown header node."); } } var nodeMapData = node.Child; while (nodeMapData != null) { switch ((OtbMapNodeType)nodeMapData.Type) { case OtbMapNodeType.TileArea: ParseTileArea(loader, nodeMapData); break; case OtbMapNodeType.Towns: ParseTowns(loader, nodeMapData); break; } nodeMapData = nodeMapData.Next; } }