static PacketWriter ShowCharacters(MapleAccount acc) { List <MapleCharacter> chars = acc.GetCharsFromDatabase(); PacketWriter pw = new PacketWriter(SendHeader.ShowCharacters); pw.WriteZeroBytes(5); pw.WriteLong(MapleFormatHelper.GetMapleTimeStamp(DateTime.UtcNow)); pw.WriteByte((byte)chars.Count); //Char count foreach (MapleCharacter chr in chars) { MapleCharacter.AddCharEntry(pw, chr); } //pw.WriteHexString("00 00 04 00 00 00 00 00 00 00 30 2A F3 A2 FA 33 D0 01 60 42 F9 64 00 00 00 00 00"); pw.WriteByte(acc.HasPic() ? (byte)1 : (byte)0); //pic state? 4 = refresh, 1 = normal, 0 = create new pic pw.WriteByte(0); pw.WriteInt(4); //char slots pw.WriteInt(0); pw.WriteLong(MapleFormatHelper.GetMapleTimeStamp(DateTime.UtcNow)); pw.WriteHexString("60 42 F9 64"); pw.WriteInt(0); // 1 = namechange button return(pw); }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter newCharacter = MapleCharacter.GetDefaultCharacter(c); bool succesful = false; string name = pr.ReadMapleString(); if (!Functions.IsAlphaNumerical(name)) { return; } bool nameAvailable = !MapleCharacter.CharacterExists(name); if (nameAvailable) { bool basicKeyLayout = pr.ReadInt() == 0; pr.Skip(4); //-1 int jobId = pr.ReadInt(); JobType jobType = (JobType)jobId; bool jobIsEnabled; if (!GameConstants.CreateJobOptions.TryGetValue(jobType, out jobIsEnabled) || !jobIsEnabled) { return; } /*ServerConsole.Debug("Jobtype " + jobId); * PacketWriter pws = new PacketWriter(); * pws.WriteHeader(SendHeader.AddCharacter); * pws.WriteBool(!false); //0 = succesful, 1 = failed * c.SendPacket(pws); * return;*/ short subJob = pr.ReadShort(); byte gender = pr.ReadByte(); byte skinColor = pr.ReadByte(); byte availableInts = pr.ReadByte(); // amount of following integers in the packet representing hair, skin and equips if (pr.Available / 4 != availableInts) //Must be a packet edit { return; } int face = pr.ReadInt(); int hair = pr.ReadInt(); int hairColor = 0; int faceMark = 0; int tamerTail = 0; int tamerEars = 0; Dictionary <MapleEquipPosition, int> items = new Dictionary <MapleEquipPosition, int>(); switch (jobType) { case JobType.Explorer: case JobType.DualBlade: case JobType.Cannonneer: case JobType.Cygnus: pr.Skip(4); //skin color again items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); break; case JobType.Resistance: case JobType.Aran: case JobType.Evan: case JobType.Mihile: hairColor = pr.ReadInt(); pr.Skip(4); //skin color again items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Bottom, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); break; case JobType.Jett: items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Cape, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); break; case JobType.Mercedes: items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); break; case JobType.Phantom: case JobType.Luminous: pr.Skip(4); //skin color again items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Cape, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); break; case JobType.Demon: faceMark = pr.ReadInt(); items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); items.Add(MapleEquipPosition.SecondWeapon, pr.ReadInt()); break; case JobType.Xenon: hairColor = pr.ReadInt(); pr.Skip(4); //skin color again faceMark = pr.ReadInt(); items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); break; case JobType.Hayato: case JobType.Kanna: hairColor = pr.ReadInt(); pr.Skip(4); //skin color again items.Add(MapleEquipPosition.Hat, pr.ReadInt()); items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); break; case JobType.Kaiser: case JobType.AngelicBuster: pr.Skip(4); //skin color again items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); break; case JobType.BeastTamer: pr.Skip(4); //skin color again faceMark = pr.ReadInt(); tamerEars = pr.ReadInt(); tamerTail = pr.ReadInt(); items.Add(MapleEquipPosition.Top, pr.ReadInt()); items.Add(MapleEquipPosition.Shoes, pr.ReadInt()); items.Add(MapleEquipPosition.Weapon, pr.ReadInt()); break; } if (CreateInfo.IsValidCharacter(jobType, gender, hair, face, items, hairColor, skinColor, faceMark, tamerEars, tamerTail)) { if (jobType == JobType.Xenon) { hair = (hair / 10) * 10; //male1 and female1 hair is 36487 and 37467 instead of 36480 and 37460 ... } if (jobType != JobType.Mihile) //Mihile hair color is already in the hair ID, but is still sent in the packet { hair += hairColor; } newCharacter = MapleCharacter.GetDefaultCharacter(c); newCharacter.Name = name; newCharacter.Gender = gender; newCharacter.Skin = skinColor; newCharacter.Face = face; newCharacter.Hair = hair; newCharacter.Job = CreateInfo.GetJobIdByJobType(jobType); newCharacter.SubJob = subJob; newCharacter.FaceMark = faceMark; newCharacter.TamerEars = CreateInfo.GetTamerItemEffectId(tamerEars); newCharacter.TamerTail = CreateInfo.GetTamerItemEffectId(tamerTail); foreach (KeyValuePair <MapleEquipPosition, int> item in items) { WzEquip wzInfo = DataBuffer.GetEquipById(item.Value); if (wzInfo != null) { MapleEquip equip = new MapleEquip(item.Value, "Character creation with jobId: " + jobId, position: (short)item.Key); equip.SetDefaultStats(wzInfo); newCharacter.Inventory.SetItem(equip, MapleInventoryType.Equipped, equip.Position, false); } } if (basicKeyLayout) { newCharacter.SetKeyMap(GameConstants.DefaultBasicKeyBinds); newCharacter.SetQuickSlotKeys(GameConstants.DefaultBasicQuickSlotKeyMap); } else { newCharacter.SetKeyMap(GameConstants.DefaultSecondaryKeyBinds); newCharacter.SetQuickSlotKeys(GameConstants.DefaultSecondaryQuickSlotKeyMap); } CreateInfo.AddBeginnerJobSkills(newCharacter, jobType); newCharacter.InsertCharacter(); newCharacter.Inventory.SaveToDatabase(true); succesful = true; } else { ServerConsole.Warning("Invalid item/hair/face ID on char creation, type: " + Enum.GetName(typeof(JobType), jobType)); } } //AddCharacter response PacketWriter pw = new PacketWriter(); pw.WriteHeader(SendHeader.AddCharacter); pw.WriteBool(!succesful); //0 = succesful, 1 = failed if (succesful) { MapleCharacter.AddCharEntry(pw, newCharacter); } c.SendPacket(pw); //cleanup newCharacter?.Release(); }