Esempio n. 1
0
        public byte[] GetObjectBytes()
        {
            while (isDirty)
            {
                // Players must always be locked first
                primaryLock.EnterReadLock();
                var playersInRegion    = primaryObjects.ToArray <ILockable>();
                var currentLastUpdated = regionLastUpdated;
                primaryLock.ExitReadLock();

                var isDone = lockerFactory().Lock(playersInRegion).Do(() =>
                {
                    // Enter write lock but give up all locks if we cant in 1 second just to be safe
                    if (!primaryLock.TryEnterWriteLock(1000))
                    {
                        return(false);
                    }

                    // ReSharper disable ConditionIsAlwaysTrueOrFalse
                    // ReSharper disable HeuristicUnreachableCode
                    if (!isDirty)
                    {
                        primaryLock.ExitWriteLock();
                        return(true);
                    }
                    // ReSharper restore HeuristicUnreachableCode
                    // ReSharper restore ConditionIsAlwaysTrueOrFalse

                    if (currentLastUpdated != regionLastUpdated)
                    {
                        primaryLock.ExitWriteLock();
                        return(false);
                    }

                    var dummyPacket = new Packet();
                    // Write tiles
                    dummyPacket.AddBytes(map);
                    // Write objects
                    dummyPacket.AddUInt16(primaryObjects.Count);
                    foreach (ISimpleGameObject obj in primaryObjects)
                    {
                        PacketHelper.AddToPacket(obj, dummyPacket, true);
                    }

                    objects = dummyPacket.GetPayload();
                    isDirty = false;

                    primaryLock.ExitWriteLock();

                    return(true);
                });

                if (isDone)
                {
                    break;
                }
            }

            return(objects);
        }
Esempio n. 2
0
        public static void HandleAgree(Packet packet, IClient client, bool fromQueue)
        {
            FileType fileType = (FileType)packet.GetChar();

            string fileName;
            InitReply replyCode;

            switch (fileType)
            {
                case FileType.Map:
                    fileName = client.Character.Map.Data.GetPubFile("./tmp/");
                    replyCode = InitReply.FileMap;
                    break;

                case FileType.Item:
                    fileName = "./data/dat001.eif";
                    replyCode = InitReply.FileEIF;
                    break;

                case FileType.NPC:
                    fileName = "./data/dtn001.enf";
                    replyCode = InitReply.FileENF;
                    break;

                case FileType.Spell:
                    fileName = "./data/dsl001.esf";
                    replyCode = InitReply.FileESF;
                    break;

                case FileType.Class:
                    fileName = "./data/dat001.ecf";
                    replyCode = InitReply.FileECF;
                    break;

                default:
                    throw new ArgumentOutOfRangeException("Invalid file type request");
            }

            Packet reply = new Packet(PacketFamily.Init, PacketAction.Init);
            reply.AddChar((byte)replyCode);

            if (fileType != FileType.Map)
                reply.AddChar(1); // File ID

            reply.AddBytes(File.ReadAllBytes(fileName));

            client.Send(reply);
        }
Esempio n. 3
0
        private void GetMiniMapRegion(Session session, Packet packet)
        {
            var reply = new Packet(packet);

            byte regionSubscribeCount;

            try
            {
                regionSubscribeCount = packet.GetByte();
            }
            catch (Exception)
            {
                ReplyError(session, packet, Error.Unexpected);
                return;
            }

            reply.AddByte(regionSubscribeCount);

            for (uint i = 0; i < regionSubscribeCount; ++i)
            {
                ushort regionId;
                try
                {
                    regionId = packet.GetUInt16();
                }
                catch (Exception)
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                MiniMapRegion region;
                if (!world.Regions.MiniMapRegions.TryGetMiniMapRegion(regionId, out region))
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                reply.AddUInt16(regionId);
                reply.AddBytes(region.GetCityBytes());
            }

            session.Write(reply);
        }
Esempio n. 4
0
        public static void HandleRequest(Packet packet, IClient client, bool fromQueue)
        {
            int id = packet.GetInt();

            if (id < 0 || id > client.Account.Characters.Count)
                throw new ArgumentOutOfRangeException("Login character ID out of range");

            client.SelectCharacter(client.Account.Characters[id]);

            Packet reply = new Packet(PacketFamily.Welcome, PacketAction.Reply);

            reply.AddShort((short)WelcomeReply.CharacterInfo);
            reply.AddShort((short)client.Id);
            reply.AddInt(id);
            reply.AddShort((short)client.Character.Map.Data.Id);

            reply.AddBytes(client.Character.Map.Data.RevisionID);
            reply.AddThree((int)client.Character.Map.Data.PubFileLength);

            reply.AddBytes(client.Server.ItemData.revisionId);
            reply.AddShort((short)client.Server.ItemData.Count);

            reply.AddBytes(client.Server.NpcData.revisionId);
            reply.AddShort((short)client.Server.NpcData.Count);

            reply.AddBytes(client.Server.SpellData.revisionId);
            reply.AddShort((short)client.Server.SpellData.Count);

            reply.AddBytes(client.Server.ClassData.revisionId);
            reply.AddShort((short)client.Server.ClassData.Count);

            reply.AddBreakString(client.Character.Name);
            reply.AddBreakString(client.Character.Title ?? "");

            reply.AddBreakString("Guild Name");
            reply.AddBreakString("Guild Rank");

            reply.AddChar(0); // Class
            reply.AddString("TAG"); // Guild tag
            reply.AddChar((byte)client.Character.Admin);

            reply.AddChar(client.Character.Level); // Level
            reply.AddInt(client.Character.Exp); // Exp
            reply.AddInt(client.Character.Usage); // Usage

            reply.AddShort(client.Character.Hp); // HP
            reply.AddShort(client.Character.MaxHp); // MaxHP
            reply.AddShort(client.Character.Tp); // TP
            reply.AddShort(client.Character.MaxTp); // MaxTP
            reply.AddShort(client.Character.MaxSp); // MaxSP
            reply.AddShort(client.Character.StatPoints); // StatPts
            reply.AddShort(client.Character.SkillPoints); // SkillPts
            reply.AddShort(client.Character.Karma); // Karma
            reply.AddShort(client.Character.MinDamage); // MinDam
            reply.AddShort(client.Character.MaxDamage); // MaxDam
            reply.AddShort(client.Character.Accuracy); // Accuracy
            reply.AddShort(client.Character.Evade); // Evade
            reply.AddShort(client.Character.Defence); // Armor

            reply.AddShort(client.Character.Strength); // Str
            reply.AddShort(client.Character.Wisdom); // Wis
            reply.AddShort(client.Character.Intelligence); // Int
            reply.AddShort(client.Character.Agility); // Agi
            reply.AddShort(client.Character.Constitution); // Con
            reply.AddShort(client.Character.Charisma); // Cha

            // Inventory
            reply.AddBreak();

            reply.AddChar(1); // Guild Rank

            reply.AddShort(2); // Jail map
            reply.AddShort(4); // ?
            reply.AddChar(24); // ?
            reply.AddChar(24); // ?
            reply.AddShort(10); // ?
            reply.AddShort(10); // ?
            reply.AddShort(0); // Admin command flood rate
            reply.AddShort(2); // ?
            reply.AddChar(0); // Login warning message
            reply.AddBreak();

            client.Send(reply);
        }
Esempio n. 5
0
        private void GetRegion(Session session, Packet packet)
        {
            var reply = new Packet(packet);

            reply.Option |= (ushort)Packet.Options.Compressed;

            ushort regionId;

            byte regionSubscribeCount;

            try
            {
                regionSubscribeCount = packet.GetByte();

                if (regionSubscribeCount > 15)
                {
                    throw new Exception("Too many regions requested");
                }
            }
            catch (Exception)
            {
                ReplyError(session, packet, Error.Unexpected);
                return;
            }

            reply.AddByte(regionSubscribeCount);

            for (uint i = 0; i < regionSubscribeCount; ++i)
            {
                try
                {
                    regionId = packet.GetUInt16();
                }
                catch (Exception)
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                var region = world.Regions.GetRegion(regionId);
                if (region == null)
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                reply.AddUInt16(regionId);
                reply.AddBytes(region.GetObjectBytes());
                world.Regions.SubscribeRegion(session, regionId);
            }

            byte regionUnsubscribeCount;

            try
            {
                regionUnsubscribeCount = packet.GetByte();

                if (regionUnsubscribeCount > 15)
                {
                    throw new Exception("Too many unsubscribe regions");
                }
            }
            catch (Exception)
            {
                ReplyError(session, packet, Error.Unexpected);
                return;
            }

            for (uint i = 0; i < regionUnsubscribeCount; ++i)
            {
                try
                {
                    regionId = packet.GetUInt16();
                }
                catch (Exception)
                {
                    ReplyError(session, packet, Error.Unexpected);
                    return;
                }

                world.Regions.UnsubscribeRegion(session, regionId);
            }

            if (channel.SubscriptionCount(session) > 30)
            {
                session.CloseSession();
            }
            else
            {
                session.Write(reply);
            }
        }
Esempio n. 6
0
		public void Save(string fileName)
		{
			Packet file = new Packet(PacketFamily.Internal, PacketAction.Server) {ReadPos = 0, WritePos = 0};

			//map header
			file.AddString("EMF");
			file.AddBytes(Rid);

			byte[] tmpName = _encodeMapString(Name);
			byte[] rawName = new byte[24];
			for (int i = rawName.Length - 1; i >= 0; --i) rawName[i] = 0xFF;
			Array.Copy(tmpName, 0, rawName, rawName.Length - tmpName.Length, tmpName.Length);
			file.AddBytes(rawName);

			file.AddChar(pkByte);
			file.AddChar((byte)Effect);
			file.AddChar(Music);
			file.AddChar(MusicExtra);
			file.AddShort(AmbientNoise);
			file.AddChar(Width);
			file.AddChar(Height);
			file.AddShort(FillTile);
			file.AddChar(availByte);
			file.AddChar(scrollByte);
			file.AddChar(RelogX);
			file.AddChar(RelogY);
			file.AddChar(Unknown2);

			//NPC Spawns
			file.AddChar((byte)NPCSpawns.Count);
			foreach (NPCSpawn spawn in NPCSpawns)
			{
				file.AddChar(spawn.x);
				file.AddChar(spawn.y);
				file.AddShort(spawn.id);
				file.AddChar(spawn.spawnType);
				file.AddShort(spawn.spawnTime);
				file.AddChar(spawn.amount);
			}

			//unknowns
			file.AddChar((byte)Unknowns.Count);
			foreach(byte[] b in Unknowns)
				file.AddBytes(b);

			//chests
			file.AddChar((byte)Chests.Count);
			foreach (MapChest chest in Chests)
			{
				file.AddChar(chest.x);
				file.AddChar(chest.y);
				file.AddShort((short)chest.key);
				file.AddChar(chest.slot);
				file.AddShort(chest.item);
				file.AddShort(chest.time);
				file.AddThree(chest.amount);
			}

			//tile specs
			file.AddChar((byte)TileRows.Count);
			foreach (TileRow tr in TileRows)
			{
				file.AddChar(tr.y);
				file.AddChar((byte)tr.tiles.Count);
				foreach (Tile tt in tr.tiles)
				{
					file.AddChar(tt.x);
					file.AddChar((byte)tt.spec);
				}
			}

			//warps
			file.AddChar((byte)WarpRows.Count);
			foreach (WarpRow wr in WarpRows)
			{
				file.AddChar(wr.y);
				file.AddChar((byte)wr.tiles.Count);
				foreach (Warp ww in wr.tiles)
				{
					file.AddChar(ww.x);
					file.AddShort(ww.warpMap);
					file.AddChar(ww.warpX);
					file.AddChar(ww.warpY);
					file.AddChar(ww.levelRequirement);
					file.AddShort((short)ww.door);
				}
			}

			//gfx
			for (int layer = 0; layer < (int) MapLayers.NUM_LAYERS; ++layer)
			{
				file.AddChar((byte)GfxRows[layer].Count);
				foreach (GFXRow row in GfxRows[layer])
				{
					file.AddChar(row.y);
					file.AddChar((byte)row.tiles.Count);
					foreach (GFX gfx in row.tiles)
					{
						file.AddChar(gfx.x);
						file.AddShort((short)gfx.tile);
					}
				}
			}

			//signs
			file.AddChar((byte)Signs.Count);
			foreach (MapSign sign in Signs)
			{
				file.AddChar(sign.x);
				file.AddChar(sign.y);
				file.AddShort((short)(sign.message.Length + sign.title.Length + 1));
				
				byte[] fileMsg = new byte[sign.message.Length + sign.title.Length];
				byte[] rawTitle = _encodeMapString(sign.title);
				byte[] rawMessage = _encodeMapString(sign.message);
				Array.Copy(rawTitle, fileMsg, fileMsg.Length);
				Array.Copy(rawMessage, 0, fileMsg, rawTitle.Length, rawMessage.Length);
				file.AddBytes(fileMsg);
				file.AddChar((byte)rawTitle.Length);
			}

			File.WriteAllBytes(fileName, file.Data);
		}