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); }
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); }
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); }
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); }
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); } }
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); }