private void OnJoin(Packet packet) { //TODO: Use all fields. var characterId = packet.ReadInt32(); var patchVersion = packet.ReadByte(); var hdInfo = packet.ReadString(); Character = User.Characters.FirstOrDefault(c => c.Id == characterId); if (Character != null) { Console.WriteLine(Character.GetHashCode()); InventoryItems = new ItemContainer <InventoryItem>(Character, Character.InventoryItems, (byte)Define.MAX_INVENTORY, (byte)Define.MAX_HUMAN_PARTS, Constants.InventorySlots); QuestItems = new ItemContainer <QuestItem>(Character, Character.QuestItems, (byte)Define.MAX_INVENTORY, 0, Constants.QuestSlots); StorageItems = new ItemContainer <StorageItem>(Character, Character.StorageItems, 0, 0, new byte[] { }); //TODO: Implement storage items. var response = new Packet(Opcode.JOIN_RIGHT); response.WriteInt32(characterId); response.WriteInt32(Character.WorldId); response.WritePosition(Character.Position); response.WriteBoolean(false); //Is festival response.WriteInt32(0); //Festival 'yday' Send(response); var joinSnapshot = new Snapshot(); joinSnapshot.SetType(SnapshotType.UPDATE_SERVER_TIME); joinSnapshot.WriteInt32(DateTime.UtcNow.GetUnixTimestamp()); WriteObjectData(joinSnapshot, Character, true); Send(joinSnapshot); var spawnNearPlayers = new Snapshot(); foreach (var player in NearPlayers) { WriteObjectData(spawnNearPlayers, player.Character); } Send(spawnNearPlayers); var spawnNewPlayer = new Snapshot(); WriteObjectData(spawnNewPlayer, Character); SendNearPlayers(spawnNewPlayer); } else { //NOTE: In theory, it's possible to send JOIN_ERROR and an error code, but the client doesn't seem to use it. Disconnect(); } }
private void OnJoin(Packet packet) { //TODO: Use all fields. var characterId = packet.ReadInt32(); var patchVersion = packet.ReadByte(); var hdInfo = packet.ReadString(); Character = User.Characters.FirstOrDefault(c => c.Id == characterId); if (Character != null) { Console.WriteLine(Character.GetHashCode()); InventoryItems = new ItemContainer<InventoryItem>(Character, Character.InventoryItems, (byte) Define.MAX_INVENTORY, (byte) Define.MAX_HUMAN_PARTS, Constants.InventorySlots); QuestItems = new ItemContainer<QuestItem>(Character, Character.QuestItems, (byte) Define.MAX_INVENTORY, 0, Constants.QuestSlots); StorageItems = new ItemContainer<StorageItem>(Character, Character.StorageItems, 0, 0, new byte[] { }); //TODO: Implement storage items. var response = new Packet(Opcode.JOIN_RIGHT); response.WriteInt32(characterId); response.WriteInt32(Character.WorldId); response.WritePosition(Character.Position); response.WriteBoolean(false); //Is festival response.WriteInt32(0); //Festival 'yday' Send(response); var joinSnapshot = new Snapshot(); joinSnapshot.SetType(SnapshotType.UPDATE_SERVER_TIME); joinSnapshot.WriteInt32(DateTime.UtcNow.GetUnixTimestamp()); WriteObjectData(joinSnapshot, Character, true); Send(joinSnapshot); var spawnNearPlayers = new Snapshot(); foreach (var player in NearPlayers) WriteObjectData(spawnNearPlayers, player.Character); Send(spawnNearPlayers); var spawnNewPlayer = new Snapshot(); WriteObjectData(spawnNewPlayer, Character); SendNearPlayers(spawnNewPlayer); } else { //NOTE: In theory, it's possible to send JOIN_ERROR and an error code, but the client doesn't seem to use it. Disconnect(); } }
public static void Serialize(this Item item, Packet packet) { packet.WriteByte(item.Slot); packet.WriteInt32(item.ItemId); packet.WriteUInt32(0x00000000); //EC D9 14 91 (Serial Number) packet.WriteX(item.StackSize); packet.WriteX(0); //CF 46 00 00 (Hitpoints => Current Durability?) packet.WriteX(0); //18 47 00 00 (Maximum Hitpoints => Maximum Durability?) packet.WriteUInt32(0x00000000); //00 00 00 00 (Word => ?) packet.WriteByte(0x00); //00 (Ability Option => ?) packet.WriteByte(0x00); //00 (Item Resistance => ?) packet.WriteByte(0x00); //00 (Resistance Ability Option => ?) packet.WriteX(0x00000000); //00 00 00 00 (Keep Time) packet.WriteByte(0x00); //00 (Item Lock) packet.WriteUInt32(0x00000000); //00 00 00 00 (Bind End Time) packet.WriteByte(0x00); //00 (Stability => ?) packet.WriteByte(0x00); //00 (Quality => ?) packet.WriteByte(0x00); //00 (Ability Rate => ?) packet.WriteX(0); //00 00 00 00 (Use Time => ?) packet.WriteX(0); //00 00 00 00 (Buy 'tm' => Buy Time?) packet.WriteX(0); //00 00 00 00 (Price => Sell/Buy?) packet.WriteX(0); //00 00 00 00 (Pay 银币 => ?) packet.WriteX(0); //00 00 00 00 (Free 银币 => ?) packet.WriteUInt32(Constants.ServerId); packet.WriteByte(0); //Attributes }
public void WriteTaskBarItems(Packet packet, List <TaskBarItem> items) { packet.WriteInt32(items.Count); foreach (var taskbarItem in items) { packet.WriteInt32(taskbarItem.Line); packet.WriteInt32(taskbarItem.Grid); packet.WriteInt32(taskbarItem.Shortcut); packet.WriteInt32(taskbarItem.ShortcutId); packet.WriteInt32(taskbarItem.Type); packet.WriteInt32(taskbarItem.Index); packet.WriteInt32(taskbarItem.UserId); packet.WriteInt32(taskbarItem.Data); packet.WriteString(taskbarItem.String); } }
public void WriteTaskBarItems(Packet packet, List<TaskBarItem> items) { packet.WriteInt32(items.Count); foreach (var taskbarItem in items) { packet.WriteInt32(taskbarItem.Line); packet.WriteInt32(taskbarItem.Grid); packet.WriteInt32(taskbarItem.Shortcut); packet.WriteInt32(taskbarItem.ShortcutId); packet.WriteInt32(taskbarItem.Type); packet.WriteInt32(taskbarItem.Index); packet.WriteInt32(taskbarItem.UserId); packet.WriteInt32(taskbarItem.Data); packet.WriteString(taskbarItem.String); } }
private void OnCertify(Packet packet) { var name = packet.ReadString(); var password = packet.ReadString(); //TODO: Find out what all the unused fields are and use them. var hdsn = packet.ReadString(); var ipKey = packet.ReadBytes(21); var version = packet.ReadUInt32(); var realVersion = packet.ReadUInt32(); var opFlag = packet.ReadByte(); var otpPassword = packet.ReadString(); var user = Database.Users.FirstOrDefault(c => c.Name == name); //TODO: Add ECard. if (user != null) { if (user.Password == password) { if (!Server.Connections.Any(c => c.User != null && c.User.Name == user.Name)) { if (realVersion == Constants.Version) { User = user; var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int)Error.CERT_OK); result.WriteInt32(0); //Not required to fill in real name. result.WriteBoolean(false); //Expansion Send(result); CharacterList(); } else { var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int)(realVersion < Constants.Version ? Error.ERR_VERSION_TOO_LOW : Error.ERR_VERSION_MAINTAIN)); Send(result); Disconnect(); } } else { var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int)Error.ERR_ACCOUNT_EXIST); Send(result); Disconnect(); } } else { var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int)((uint)Error.CERT_CHARGE_CERTIFY_FAILED << 16)); Send(result); } } else { var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int)((uint)Error.CERT_CHARGE_CERTIFY_FAILED << 16 | 1)); Send(result); } }
private void OnCreatePlayer(Packet packet) { var result = new Packet(Opcode.CREATEPLAYERRESULT); var name = packet.ReadString(); var hdHash = packet.ReadString(); var slot = packet.ReadInt32(); var job = packet.ReadByte(); var gender = packet.ReadByte(); var hairMesh = packet.ReadByte(); var hairColor = packet.ReadUInt32(); var headMesh = packet.ReadByte(); var city = packet.ReadInt32(); var zodiacSign = packet.ReadInt32(); var country = packet.ReadByte(); var snCard = packet.ReadString(); var cardType = packet.ReadInt32(); var hdSerialNumber = packet.ReadString(); var binAccount = packet.ReadString(); var clothList = new int[5]; for (var i = 0; i < 5; i++) clothList[i] = packet.ReadInt32(); if (!Constants.CharacterCreationEnabled) { result.WriteInt32((int) Error.ERR_NOCREATE_ALL); } else if (Database.Characters.Any(c => c.Name == name)) { result.WriteInt32((int) Error.ERR_PLAYER_EXIST); } else if (User.Characters.Count(c => !c.Deleted && !c.Blocked) > 3 || User.Characters.Count > 10 || User.Characters.Any(c => c.Slot == slot)) //TODO: Check items. { result.WriteInt32((int) Error.ERR_NOCREATE); } else { var character = new Character { Name = name, Slot = slot, Job = job, Gender = gender, Appearance = new CharacterAppearance { HairMesh = hairMesh, HairColor = (int) hairColor, HeadMesh = headMesh }, PersonalInformation = new PersonalInformation { City = city, ZodiacSign = zodiacSign }, Closet = new Closet() }; for (var i = 0; i < 5; i++) { if (clothList[i] == 0) continue; character.Closet.Items.Add(new ClosetItem { ItemId = clothList[i], Index = i + 1, DateTime = DateTime.UtcNow, Equipped = true }); } User.Characters.Add(character); User.AcceptedAgreement = true; Database.SaveChanges(); //TODO: Fix this, shouldn't do a full DB update for this... result.WriteInt32((int) Error.ERR_SUCCESS); Send(result); var playerSlot = new Packet(Opcode.PLAYERSLOT); playerSlot.WriteInt32(character.Slot); playerSlot.WriteString(character.Name); playerSlot.WriteInt32(character.Id); playerSlot.WriteInt32(character.WorldId); playerSlot.WriteByte(character.Gender); playerSlot.WritePosition(character.Position); playerSlot.WriteInt32(character.Level); playerSlot.WriteInt32(character.Job); playerSlot.WriteInt32(character.Stats.STR); playerSlot.WriteInt32(character.Stats.STA); playerSlot.WriteInt32(character.Stats.DEX); playerSlot.WriteInt32(character.Stats.INT); playerSlot.WriteInt32(character.Stats.SPI); playerSlot.WriteInt32(character.Appearance.HairMesh); playerSlot.WriteUInt32((uint) character.Appearance.HairColor); playerSlot.WriteInt32(character.Appearance.HeadMesh); playerSlot.WriteInt32(character.Blocked ? 1 : 0); playerSlot.WriteInt32(character.BlockTime); //TODO: Clean this up. var container = new ItemContainer<InventoryItem>(character, character.InventoryItems, (byte) Define.MAX_INVENTORY, (byte) Define.MAX_HUMAN_PARTS, Constants.InventorySlots); var equipmentItems = container.EquippedItems.ToList(); playerSlot.WriteInt32(equipmentItems.Count); //TODO: Implement non-fashion items. // for i = 1, count do // parts = LAr:ReadByte(ar) // item_id = LAr:ReadDword(ar) // flag = LAr:ReadDword(ar) // attr = LAr:ReadInt(ar) // end foreach (var fashionItem in character.Closet.Items.Where(item => item.Equipped)) playerSlot.WriteInt32(fashionItem.ItemId); playerSlot.WriteInt32(User.Characters.Count(c => c.Deleted)); Send(playerSlot); return; } Send(result); }
private void CharacterList() { var packet = new Packet(Opcode.PLAYERLIST); packet.WriteInt32(DateTime.UtcNow.GetUnixTimestamp()); packet.WriteByte((byte) (User.AcceptedAgreement ? 0 : 1)); var characters = User.Characters.Where(c => !c.Deleted && !c.Blocked).ToList(); packet.WriteByte((byte) characters.Count); foreach (var character in characters) { packet.WriteInt32(character.Slot); packet.WriteString(character.Name); packet.WriteInt32(character.Id); packet.WriteInt32(character.WorldId); packet.WriteByte(character.Gender); packet.WritePosition(character.Position); packet.WriteInt32(character.Level); packet.WriteInt32(character.Job); packet.WriteInt32(character.Stats.STR); packet.WriteInt32(character.Stats.STA); packet.WriteInt32(character.Stats.DEX); packet.WriteInt32(character.Stats.INT); packet.WriteInt32(character.Stats.SPI); packet.WriteInt32(character.Appearance.HairMesh); packet.WriteUInt32((uint) character.Appearance.HairColor); packet.WriteInt32(character.Appearance.HeadMesh); packet.WriteInt32(character.Blocked ? 1 : 0); packet.WriteInt32(character.BlockTime); //TODO: Clean this up. var container = new ItemContainer<InventoryItem>(character, character.InventoryItems, (byte) Define.MAX_INVENTORY, (byte) Define.MAX_HUMAN_PARTS, Constants.InventorySlots); var equipmentItems = container.EquippedItems.ToList(); packet.WriteInt32(equipmentItems.Count); //TODO: Implement non-fashion items. // for i = 1, count do // parts = LAr:ReadByte(ar) // item_id = LAr:ReadDword(ar) // flag = LAr:ReadDword(ar) // attr = LAr:ReadInt(ar) // end for(var i = 1; i <= 5; i++) { var item = character.Closet.Items.FirstOrDefault(c => c.Equipped && c.Index == i); packet.WriteInt32(item != null ? item.ItemId : 0); } } packet.WriteInt32(User.Characters.Count(c => c.Deleted)); //TODO: Implement city/province. packet.WriteInt32(0); //City Id packet.WriteInt32(0); //Province Id packet.WriteSByte(20); //TODO: Find out what this is. Send(packet); }
private void OnCertify(Packet packet) { var name = packet.ReadString(); var password = packet.ReadString(); //TODO: Find out what all the unused fields are and use them. var hdsn = packet.ReadString(); var ipKey = packet.ReadBytes(21); var version = packet.ReadUInt32(); var realVersion = packet.ReadUInt32(); var opFlag = packet.ReadByte(); var otpPassword = packet.ReadString(); var user = Database.Users.FirstOrDefault(c => c.Name == name); //TODO: Add ECard. if (user != null) { if(user.Password == password) { if (!Server.Connections.Any(c => c.User != null && c.User.Name == user.Name)) { if (realVersion == Constants.Version) { User = user; var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int) Error.CERT_OK); result.WriteInt32(0); //Not required to fill in real name. result.WriteBoolean(false); //Expansion Send(result); CharacterList(); } else { var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int) (realVersion < Constants.Version ? Error.ERR_VERSION_TOO_LOW : Error.ERR_VERSION_MAINTAIN)); Send(result); Disconnect(); } } else { var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int) Error.ERR_ACCOUNT_EXIST); Send(result); Disconnect(); } } else { var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int) ((uint) Error.CERT_CHARGE_CERTIFY_FAILED << 16)); Send(result); } } else { var result = new Packet(Opcode.CERTIFYRESULT); result.WriteInt32((int) ((uint)Error.CERT_CHARGE_CERTIFY_FAILED << 16 | 1)); Send(result); } }
private void OnCreatePlayer(Packet packet) { var result = new Packet(Opcode.CREATEPLAYERRESULT); var name = packet.ReadString(); var hdHash = packet.ReadString(); var slot = packet.ReadInt32(); var job = packet.ReadByte(); var gender = packet.ReadByte(); var hairMesh = packet.ReadByte(); var hairColor = packet.ReadUInt32(); var headMesh = packet.ReadByte(); var city = packet.ReadInt32(); var zodiacSign = packet.ReadInt32(); var country = packet.ReadByte(); var snCard = packet.ReadString(); var cardType = packet.ReadInt32(); var hdSerialNumber = packet.ReadString(); var binAccount = packet.ReadString(); var clothList = new int[5]; for (var i = 0; i < 5; i++) { clothList[i] = packet.ReadInt32(); } if (!Constants.CharacterCreationEnabled) { result.WriteInt32((int)Error.ERR_NOCREATE_ALL); } else if (Database.Characters.Any(c => c.Name == name)) { result.WriteInt32((int)Error.ERR_PLAYER_EXIST); } else if (User.Characters.Count(c => !c.Deleted && !c.Blocked) > 3 || User.Characters.Count > 10 || User.Characters.Any(c => c.Slot == slot)) //TODO: Check items. { result.WriteInt32((int)Error.ERR_NOCREATE); } else { var character = new Character { Name = name, Slot = slot, Job = job, Gender = gender, Appearance = new CharacterAppearance { HairMesh = hairMesh, HairColor = (int)hairColor, HeadMesh = headMesh }, PersonalInformation = new PersonalInformation { City = city, ZodiacSign = zodiacSign }, Closet = new Closet() }; for (var i = 0; i < 5; i++) { if (clothList[i] == 0) { continue; } character.Closet.Items.Add(new ClosetItem { ItemId = clothList[i], Index = i + 1, DateTime = DateTime.UtcNow, Equipped = true }); } User.Characters.Add(character); User.AcceptedAgreement = true; Database.SaveChanges(); //TODO: Fix this, shouldn't do a full DB update for this... result.WriteInt32((int)Error.ERR_SUCCESS); Send(result); var playerSlot = new Packet(Opcode.PLAYERSLOT); playerSlot.WriteInt32(character.Slot); playerSlot.WriteString(character.Name); playerSlot.WriteInt32(character.Id); playerSlot.WriteInt32(character.WorldId); playerSlot.WriteByte(character.Gender); playerSlot.WritePosition(character.Position); playerSlot.WriteInt32(character.Level); playerSlot.WriteInt32(character.Job); playerSlot.WriteInt32(character.Stats.STR); playerSlot.WriteInt32(character.Stats.STA); playerSlot.WriteInt32(character.Stats.DEX); playerSlot.WriteInt32(character.Stats.INT); playerSlot.WriteInt32(character.Stats.SPI); playerSlot.WriteInt32(character.Appearance.HairMesh); playerSlot.WriteUInt32((uint)character.Appearance.HairColor); playerSlot.WriteInt32(character.Appearance.HeadMesh); playerSlot.WriteInt32(character.Blocked ? 1 : 0); playerSlot.WriteInt32(character.BlockTime); //TODO: Clean this up. var container = new ItemContainer <InventoryItem>(character, character.InventoryItems, (byte)Define.MAX_INVENTORY, (byte)Define.MAX_HUMAN_PARTS, Constants.InventorySlots); var equipmentItems = container.EquippedItems.ToList(); playerSlot.WriteInt32(equipmentItems.Count); //TODO: Implement non-fashion items. // for i = 1, count do // parts = LAr:ReadByte(ar) // item_id = LAr:ReadDword(ar) // flag = LAr:ReadDword(ar) // attr = LAr:ReadInt(ar) // end foreach (var fashionItem in character.Closet.Items.Where(item => item.Equipped)) { playerSlot.WriteInt32(fashionItem.ItemId); } playerSlot.WriteInt32(User.Characters.Count(c => c.Deleted)); Send(playerSlot); return; } Send(result); }
private void CharacterList() { var packet = new Packet(Opcode.PLAYERLIST); packet.WriteInt32(DateTime.UtcNow.GetUnixTimestamp()); packet.WriteByte((byte)(User.AcceptedAgreement ? 0 : 1)); var characters = User.Characters.Where(c => !c.Deleted && !c.Blocked).ToList(); packet.WriteByte((byte)characters.Count); foreach (var character in characters) { packet.WriteInt32(character.Slot); packet.WriteString(character.Name); packet.WriteInt32(character.Id); packet.WriteInt32(character.WorldId); packet.WriteByte(character.Gender); packet.WritePosition(character.Position); packet.WriteInt32(character.Level); packet.WriteInt32(character.Job); packet.WriteInt32(character.Stats.STR); packet.WriteInt32(character.Stats.STA); packet.WriteInt32(character.Stats.DEX); packet.WriteInt32(character.Stats.INT); packet.WriteInt32(character.Stats.SPI); packet.WriteInt32(character.Appearance.HairMesh); packet.WriteUInt32((uint)character.Appearance.HairColor); packet.WriteInt32(character.Appearance.HeadMesh); packet.WriteInt32(character.Blocked ? 1 : 0); packet.WriteInt32(character.BlockTime); //TODO: Clean this up. var container = new ItemContainer <InventoryItem>(character, character.InventoryItems, (byte)Define.MAX_INVENTORY, (byte)Define.MAX_HUMAN_PARTS, Constants.InventorySlots); var equipmentItems = container.EquippedItems.ToList(); packet.WriteInt32(equipmentItems.Count); //TODO: Implement non-fashion items. // for i = 1, count do // parts = LAr:ReadByte(ar) // item_id = LAr:ReadDword(ar) // flag = LAr:ReadDword(ar) // attr = LAr:ReadInt(ar) // end for (var i = 1; i <= 5; i++) { var item = character.Closet.Items.FirstOrDefault(c => c.Equipped && c.Index == i); packet.WriteInt32(item != null ? item.ItemId : 0); } } packet.WriteInt32(User.Characters.Count(c => c.Deleted)); //TODO: Implement city/province. packet.WriteInt32(0); //City Id packet.WriteInt32(0); //Province Id packet.WriteSByte(20); //TODO: Find out what this is. Send(packet); }