Dynamic Maps coded.
Map Copies coded.
Scene Files coded.
Database File:
Code:
namespace Kibou.Database { using System; using System.Collections.Generic; using System.IO; using System.Text; public static class Maps { public static SortedList<uint, string> MapPaths = new SortedList<uint, string>(); public static List<uint> RejectAgate = new List<uint>(); public static uint NextDynamicIdentity_Base = 9999; public static uint NextDynamicIdentity { get { return NextDynamicIdentity_Base += 1; } } public static void Load() { Program.WriteLine("Loading KMap System..."); MySqlReader r = new MySqlReader("SELECT * FROM `kb_maps`"); while (r.Reader.Read()) { uint identity = uint.Parse(r.Reader["Identity"].ToString()); int status = int.Parse(r.Reader["Status"].ToString()); if (status < 0) status = 0; if (int.Parse(r.Reader["Reject Agate"].ToString()) > 0) RejectAgate.Add(identity); if (!MapPaths.ContainsKey(identity)) { string path = r.Reader["Path"].ToString(); new World.Map(path, new Connections.Packets.MapStatus(identity, uint.Parse(r.Reader["Base Identity"].ToString()), (uint)status, ushort.Parse(r.Reader["Unknown"].ToString()), ushort.Parse(r.Reader["Unknown2"].ToString())), false, null); MapPaths.Add(identity, path); } } if (MapPaths.Count < 1) { if (File.Exists(Environment.CurrentDirectory + "\\Database\\GameMap.dat")) { FileStream filestream = new FileStream(Environment.CurrentDirectory + "\\Database\\GameMap.dat", FileMode.Open); BinaryReader binaryreader = new BinaryReader(filestream); uint MapCount = binaryreader.ReadUInt32(); for (uint i = 0; i < MapCount; i++) { uint identity = binaryreader.ReadUInt32(); string path = Encoding.ASCII.GetString(binaryreader.ReadBytes(binaryreader.ReadInt32())); if (identity >= 1712 && identity <= 1720) { binaryreader.ReadUInt32(); continue; } if (path.EndsWith(".7z")) { path = path.Remove(path.Length - 3, 3); path += ".dmap"; } if (!MapPaths.ContainsKey(identity)) { new World.Map(path, new Connections.Packets.MapStatus(identity, identity, 0, 0, 0), false, null); MapPaths.Add(identity, path); } binaryreader.ReadInt32(); new MySqlCmd("INSERT INTO `kb_maps` (Identity, `Base Identity`, Path, Status) VALUES (" + identity + ", " + identity + ", '" + path + "', " + -1 + ")"); } binaryreader.Close(); filestream.Close(); binaryreader.Dispose(); filestream.Dispose(); } } r.Dispose(); r = null; } public static void SaveMap(uint baseIdentity, World.Floor floor) { if (!File.Exists(Environment.CurrentDirectory + "\\Database\\Maps\\" + baseIdentity + ".kmap")) { FileStream stream = new FileStream(Environment.CurrentDirectory + "\\Database\\Maps\\" + baseIdentity + ".kmap", FileMode.Create); BinaryWriter writer = new BinaryWriter(stream); writer.Write((uint)floor.Bounds.Width); writer.Write((uint)floor.Bounds.Height); for (int y = 0; y < floor.Bounds.Height; y++) for (int x = 0; x < floor.Bounds.Width; x++) writer.Write(floor[x, y]); writer.Close(); stream.Close(); writer.Dispose(); stream.Dispose(); } } } }
Code:
namespace Kibou.World { using System.Collections.Concurrent; using System.Drawing; using System; using System.IO; using System.Text; using System.Collections.Specialized; using Connections.Packets; using System.Collections.Generic; using Kibou.Connections.Enums; public class Map { public uint Identity, BaseIdentity; public string Path; public MapStatus Status; public bool Dynamic = false; public Client Owner; public ConcurrentDictionary<uint, Client> Players = new ConcurrentDictionary<uint, Client>(); public ConcurrentDictionary<uint, NpcSpawn> Npcs = new ConcurrentDictionary<uint, NpcSpawn>(); public ConcurrentDictionary<uint, FloorItem> FloorItems = new ConcurrentDictionary<uint, FloorItem>(); public Action<uint> RemoveThisMap = new Action<uint>(RemoveMap); public Floor Floor = new Floor(0, 0); private SceneFile[] Scenes; public Map(string path, MapStatus status, bool dynamic, Client owner) { if (!Kernel.Maps.ContainsKey(status.Identity)) Kernel.Maps.TryAdd(status.Identity, this); Identity = status.Identity; BaseIdentity = status.BaseIdentity; if (dynamic) { Owner = owner; Kernel.DynamicMaps.TryAdd(status.Identity, this); Dynamic = true; } Status = status; if (path == "") path = Database.Maps.MapPaths[status.BaseIdentity]; Path = path.Replace("map/map", "map"); #region Load Floor if (File.Exists(Environment.CurrentDirectory + "\\Database\\Maps\\" + status.BaseIdentity + ".kmap")) { MemoryStream memory = new MemoryStream(File.ReadAllBytes(Environment.CurrentDirectory + "\\Database\\Maps\\" + status.BaseIdentity + ".kmap")); BinaryReader br = new BinaryReader(memory); int width = br.ReadInt32(); int height = br.ReadInt32(); Floor = new Floor(width, height); for (ushort y = 0; y < height; y++) for (ushort x = 0; x < width; x++) Floor[x, y] = br.ReadByte(); br.Close(); br.Dispose(); memory.Close(); memory.Dispose(); memory = null; br = null; } else if (File.Exists(Environment.CurrentDirectory + "\\Database\\DMaps\\" + Path)) { MemoryStream memory = new MemoryStream(File.ReadAllBytes(Environment.CurrentDirectory + "\\Database\\DMaps\\" + Path)); BinaryReader br = new BinaryReader(memory); br.ReadBytes(268); int width = br.ReadInt32(); int height = br.ReadInt32(); Floor = new Floor(width, height); for (ushort y = 0; y < height; y++) { for (ushort x = 0; x < width; x++) { Floor[x, y] = Convert.ToByte(!Convert.ToBoolean(br.ReadInt16())); br.BaseStream.Seek(4L, SeekOrigin.Current); } br.BaseStream.Seek(4L, SeekOrigin.Current); } uint amount = br.ReadUInt32(); br.BaseStream.Seek(amount * 12, SeekOrigin.Current); int num = br.ReadInt32(); List<SceneFile> list = new List<SceneFile>(); for (int i = 0; i < num; i++) switch (br.ReadInt32()) { case 1: list.Add(this.CreateSceneFile(br)); break; case 4: br.BaseStream.Seek(0x1a0L, SeekOrigin.Current); break; case 10: br.BaseStream.Seek(0x48L, SeekOrigin.Current); break; case 15: br.BaseStream.Seek(0x114L, SeekOrigin.Current); break; } Scenes = list.ToArray(); for (int i = 0; i < Scenes.Length; i++) foreach (ScenePart part in Scenes[i].Parts) for (int j = 0; j < part.Size.Width; j++) for (int k = 0; k < part.Size.Height; k++) { Point point = new Point(); point.X = ((Scenes[i].Location.X + part.StartPosition.X) + j) - part.Size.Width + 1; point.Y = ((Scenes[i].Location.Y + part.StartPosition.Y) + k) - part.Size.Height + 1; Floor[(ushort)(point.X), (ushort)(point.Y)] = Convert.ToByte(part.NoAccess[(part.Size.Width - 1) - j, (part.Size.Height - 1) - k]); } br.Close(); br.Dispose(); memory.Close(); memory.Dispose(); Database.Maps.SaveMap(BaseIdentity, Floor); } #endregion Database.Npcs.Load(this); } private SceneFile CreateSceneFile(BinaryReader Reader) { SceneFile file = new SceneFile(); file.SceneFileName = Encoding.ASCII.GetString(Reader.ReadBytes(260)).TrimEnd('\0'); if (file.SceneFileName.Contains("\0")) file.SceneFileName = file.SceneFileName.Remove(file.SceneFileName.IndexOf("\0")); file.SceneFileName = file.SceneFileName.Replace("map\\Scene", "Scene"); file.Location = new Point(Reader.ReadInt32(), Reader.ReadInt32()); using (BinaryReader reader = new BinaryReader(new FileStream(Environment.CurrentDirectory + "\\Database\\DMaps\\" + file.SceneFileName, FileMode.Open))) { ScenePart[] partArray = new ScenePart[reader.ReadInt32()]; for (int i = 0; i < partArray.Length; i++) { reader.BaseStream.Seek(0x14cL, SeekOrigin.Current); partArray[i].Size = new Size(reader.ReadInt32(), reader.ReadInt32()); reader.BaseStream.Seek(4L, SeekOrigin.Current); partArray[i].StartPosition = new Point(reader.ReadInt32(), reader.ReadInt32()); reader.BaseStream.Seek(4L, SeekOrigin.Current); partArray[i].NoAccess = new bool[partArray[i].Size.Width, partArray[i].Size.Height]; for (int j = 0; j < partArray[i].Size.Height; j++) { for (int k = 0; k < partArray[i].Size.Width; k++) { partArray[i].NoAccess[k, j] = reader.ReadInt32() == 0; reader.BaseStream.Seek(8L, SeekOrigin.Current); } } } file.Parts = partArray; reader.Close(); reader.Dispose(); } return file; } public void AddNpc(NpcSpawn npc, bool space) { if (!Npcs.ContainsKey(npc.Identity)) { Npcs.TryAdd(npc.Identity, npc); if (space) for (int i = npc.X - 1; i < npc.X + 1; i++) for (int j = npc.Y - 1; j < npc.Y + 1; j++) Floor[i, j] = Tile.NotAvailable; } } public void AddFloorItem(FloorItem obj) { FloorItems.TryAdd(obj.Identity, obj); Floor[obj.X, obj.Y] = Tile.Item; } public bool RemoveFloorItem(uint identity, out FloorItem flooritem) { FloorItems.TryRemove(identity, out flooritem); if (flooritem.Owner != null) { FloorItems.TryAdd(flooritem.Identity, flooritem); return false; } if (Floor[flooritem.X, flooritem.Y] == Tile.Item) Floor[flooritem.X, flooritem.Y] = Tile.Available; foreach (Client client in Players.Values) if (!Kernel.ObjOutScreen(client.Character.X, client.Character.Y, flooritem.X, flooritem.Y)) client.Screen.Remove(flooritem, false); return true; } public void AddPlayer(Client client) { if (!Players.ContainsKey(client.Identity)) Players.TryAdd(client.Identity, client); } public void RemovePlayer(uint identity) { Client client = null; if (Players.ContainsKey(identity)) Players.TryRemove(identity, out client); if (Players.Count < 1) if (Dynamic) RemoveThisMap(Identity); } private static void RemoveMap(uint identity) { Kernel.DynamicMaps[identity] = null; Kernel.Maps[identity] = null; Map m = null; Kernel.DynamicMaps.TryRemove(identity, out m); m = null; Kernel.Maps.TryRemove(identity, out m); m = null; } } public class Floor { public Size Bounds; private BitVector Tiles; public Floor(int width, int height) { Bounds = new Size(width, height); Tiles = new BitVector(width * height * BitVector.BYTE_FIELD_SIZE); } public byte this[int x, int y] { get { if (Bounds.Height == 0 || Bounds.Width == 0) return 1; if (y >= Bounds.Height || x >= Bounds.Width || y < 0 || x < 0) return 0; return Tiles.GetByte((x * Bounds.Width) + y); } set { if (Bounds.Height == 0 || Bounds.Width == 0) return; if (y >= Bounds.Height || x >= Bounds.Width || y < 0 || x < 0) return; Tiles.SetByte((x * Bounds.Width) + y, value); } } } }
Code:
namespace Kibou.World { using System.Drawing; public struct SceneFile { public string SceneFileName { get; set; } public Point Location { get; set; } public ScenePart[] Parts { get; set; } } public struct ScenePart { public string Animation; public string PartFile; public Point Offset; public int aniInterval; public Size Size; public int Thickness; public Point StartPosition; public bool[,] NoAccess; } }
Code:
public class Tile { public const byte NotAvailable = 0, Available = 1, Item = 5; }
(Customly coded by Hybrid for my Map System- released with permission):
Code:
#define _x64_OPTIMIZATIONS /* WRITTEN BY: Roy Khan (Infamous Noone / Hybrid) * DATE: JUNE 25 2011 * LANGUAGE: C# */ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace System.Collections.Specialized { public unsafe class BitVector { #if _x64_OPTIMIZATIONS private const int FIELD_SIZE = 64; private ulong[] bits; #else private const int FIELD_SIZE = 32; private uint[] bits; #endif public const int BYTE_FIELD_SIZE = 8; public const int SHORT_FIELD_SIZE = 16; public const int INT_FIELD_SIZE = 32; #if _x64_OPTIMIZATIONS public const int LONG_FIELD_SIZE = 64; #endif public int Size { get { return FIELD_SIZE * bits.Length; } } public int SizeInBytes { get { return Size / BYTE_FIELD_SIZE; } } public int SizeInShorts { get { return Size / SHORT_FIELD_SIZE; } } public int SizeInInts { get { return Size / INT_FIELD_SIZE; } } #if _x64_OPTIMIZATIONS public int SizeInLongs { get { return Size / LONG_FIELD_SIZE; } } #endif public BitVector(int BitCount) { int sections = BitCount / FIELD_SIZE; if (BitCount % FIELD_SIZE != 0) sections += 1; #if _x64_OPTIMIZATIONS bits = new ulong[sections]; #else bits = new uint[sections]; #endif } public byte GetByte(int index) { if (index > SizeInBytes || index < 0) throw new IndexOutOfRangeException(); fixed (void* ptr = bits) return ((byte*)ptr)[index]; } public void SetByte(int index, byte value) { if (index > SizeInBytes || index < 0) throw new IndexOutOfRangeException(); fixed (void* ptr = bits) ((byte*)ptr)[index] = value; } public short GetShort(int index) { if (index > SizeInShorts || index < 0) throw new IndexOutOfRangeException(); fixed (void* ptr = bits) return ((short*)ptr)[index]; } public void SetShort(int index, short value) { if (index > SizeInShorts || index < 0) throw new IndexOutOfRangeException(); fixed (void* ptr = bits) ((short*)ptr)[index] = value; } public int GetInt(int index) { if (index > SizeInInts || index < 0) throw new IndexOutOfRangeException(); fixed (void* ptr = bits) return ((int*)ptr)[index]; } public void SetInt(int index, int value) { if (index > SizeInInts || index < 0) throw new IndexOutOfRangeException(); fixed (void* ptr = bits) ((int*)ptr)[index] = value; } #if _x64_OPTIMIZATIONS public long GetLong(int index) { if (index > SizeInLongs || index < 0) throw new IndexOutOfRangeException(); fixed (void* ptr = bits) return ((long*)ptr)[index]; } public void SetLong(int index, long value) { if (index > SizeInLongs || index < 0) throw new IndexOutOfRangeException(); fixed (void* ptr = bits) ((long*)ptr)[index] = value; } #endif public bool this[int index] { get { int idx = index / FIELD_SIZE; #if _x64_OPTIMIZATIONS ulong bit = 1ul << (index % FIELD_SIZE); #else uint bit = 1u << (index % FIELD_SIZE); #endif return ((bits[idx] & bit) == bit); } set { int idx = index / FIELD_SIZE; #if _x64_OPTIMIZATIONS ulong bit = 1ul << (index % FIELD_SIZE); #else uint bit = 1u << (index % FIELD_SIZE); #endif if (value) bits[idx] |= bit; else bits[idx] &= ~bit; } } } }
Fang
PS: -1 in the database means that I didn't record it in my proxy.