/// <summary> /// New system in v1.110+ for delve info. delve is cached by client in extra file, stored locally. /// </summary> /// <param name="info"></param> public override void SendDelveInfo(string info) { var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.DelveInfo)); pak.WriteString(info, 2048); pak.WriteByte(0); // 0-terminated SendTCP(pak); }
//Packets #region IPacketLib Members public virtual void SendVersionAndCryptKey() { //Construct the new packet using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.CryptKey))) { //Enable encryption #if !NOENCRYPTION pak.WriteByte(0x01); #else pak.WriteByte(0x00); #endif //if(is_si) pak.WriteByte(0x32); //else // pak.WriteByte(0x31); pak.WriteByte(ParseVersion((int) m_gameClient.Version, true)); pak.WriteByte(ParseVersion((int) m_gameClient.Version, false)); //pak.WriteByte(build); pak.WriteByte(0x00); #if !NOENCRYPTION byte[] publicKey = new byte[500]; UInt32 keyLen = CryptLib168.ExportRSAKey(publicKey, (UInt32) 500, false); pak.WriteShort((ushort) keyLen); pak.Write(publicKey, 0, (int) keyLen); //From now on we expect RSA! ((PacketEncoding168) m_gameClient.PacketProcessor.Encoding).EncryptionState = PacketEncoding168.eEncryptionState.RSAEncrypted; #endif SendTCP(pak); } }
public override void SendKeepRemove(AbstractGameKeep keep) { GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.KeepRemove)); pak.WriteShort((ushort)keep.KeepID); SendTCP(pak); }
public override void SendCombatAnimation(GameObject attacker, GameObject defender, ushort weaponID, ushort shieldID, int style, byte stance, byte result, byte targetHealthPercent) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.CombatAnimation))) { if (attacker != null) pak.WriteShort((ushort)attacker.ObjectID); else pak.WriteShort(0x00); if (defender != null) pak.WriteShort((ushort)defender.ObjectID); else pak.WriteShort(0x00); pak.WriteShort(weaponID); pak.WriteShort(shieldID); pak.WriteShortLowEndian((ushort)style); pak.WriteByte(stance); pak.WriteByte(result); // If Health Percent is invalid get the living Health. if (defender is GameLiving && targetHealthPercent > 100) { targetHealthPercent = (defender as GameLiving).HealthPercent; } pak.WriteByte(targetHealthPercent); pak.WriteByte(0);//unk SendTCP(pak); } }
public override void SendPlayerTitles() { IList titles = m_gameClient.Player.Titles; GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.DetailWindow)); pak.WriteByte(1); // new in 1.75 pak.WritePascalString("Player Statistics"); //window caption byte line = 1; foreach (string str in m_gameClient.Player.FormatStatistics()) { pak.WriteByte(line++); pak.WritePascalString(str); } pak.WriteByte(200); long titlesCountPos = pak.Position; pak.WriteByte(0); // length of all titles part pak.WriteByte((byte)titles.Count); line = 0; foreach (IPlayerTitle title in titles) { pak.WriteByte(line++); pak.WritePascalString(title.GetDescription(m_gameClient.Player)); } long titlesLen = (pak.Position - titlesCountPos - 1); // include titles count if (titlesLen > byte.MaxValue) log.WarnFormat("Titles block is too long! {0} (player: {1})", titlesLen, m_gameClient.Player); //Trailing Zero! pak.WriteByte(0); //Set titles length pak.Position = titlesCountPos; pak.WriteByte((byte)titlesLen); // length of all titles part SendTCP(pak); }
public override void SendPlayerPositionAndObjectID() { if (m_gameClient.Player == null) return; using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.PositionAndObjectID))) { pak.WriteShort((ushort)m_gameClient.Player.ObjectID); //This is the player's objectid not Sessionid!!! pak.WriteShort((ushort)m_gameClient.Player.Z); pak.WriteInt((uint)m_gameClient.Player.X); pak.WriteInt((uint)m_gameClient.Player.Y); pak.WriteShort(m_gameClient.Player.Heading); int flags = 0; if (m_gameClient.Player.CurrentZone.IsDivingEnabled) flags = 0x80 | (m_gameClient.Player.IsUnderwater ? 0x01 : 0x00); pak.WriteByte((byte)(flags)); pak.WriteByte(0x00); //TODO Unknown Zone zone = m_gameClient.Player.CurrentZone; if (zone == null) return; pak.WriteShort((ushort)(zone.XOffset / 0x2000)); pak.WriteShort((ushort)(zone.YOffset / 0x2000)); //Dinberg - Changing to allow instances... pak.WriteShort(m_gameClient.Player.CurrentRegion.Skin); pak.WriteShort(0x00); //TODO: unknown, new in 1.71 SendTCP(pak); } }
public override void SendPlayerCreate(GamePlayer playerToCreate) { Region playerRegion = playerToCreate.CurrentRegion; if (playerRegion == null) { if (log.IsWarnEnabled) log.Warn("SendPlayerCreate: playerRegion == null"); return; } Zone playerZone = playerToCreate.CurrentZone; if (playerZone == null) { if (log.IsWarnEnabled) log.Warn("SendPlayerCreate: playerZone == null"); return; } if (m_gameClient.Player == null || playerToCreate.IsVisibleTo(m_gameClient.Player) == false) return; GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.PlayerCreate172)); pak.WriteShort((ushort)playerToCreate.Client.SessionID); pak.WriteShort((ushort)playerToCreate.ObjectID); pak.WriteShort(playerToCreate.Model); pak.WriteShort((ushort)playerToCreate.Z); //Dinberg:Instances - Zoneskin ID for clientside positioning 'bluff'. pak.WriteShort(playerZone.ZoneSkinID); pak.WriteShort((ushort)playerRegion.GetXOffInZone(playerToCreate.X, playerToCreate.Y)); pak.WriteShort((ushort)playerRegion.GetYOffInZone(playerToCreate.X, playerToCreate.Y)); pak.WriteShort(playerToCreate.Heading); pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.EyeSize)); //1-4 = Eye Size / 5-8 = Nose Size pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.LipSize)); //1-4 = Ear size / 5-8 = Kin size pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.EyeColor)); //1-4 = Skin Color / 5-8 = Eye Color pak.WriteByte(playerToCreate.GetDisplayLevel(m_gameClient.Player)); pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.HairColor)); //Hair: 1-4 = Color / 5-8 = unknown pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.FaceType)); //1-4 = Unknown / 5-8 = Face type pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.HairStyle)); //1-4 = Unknown / 5-8 = Hair Style int flags = (GameServer.ServerRules.GetLivingRealm(m_gameClient.Player, playerToCreate) & 0x03) << 2; if (playerToCreate.IsAlive == false) flags |= 0x01; if (playerToCreate.IsUnderwater) flags |= 0x02; //swimming if (playerToCreate.IsStealthed) flags |= 0x10; if (playerToCreate.IsWireframe) flags |= 0x20; pak.WriteByte((byte)flags); pak.WritePascalString(GameServer.ServerRules.GetPlayerName(m_gameClient.Player, playerToCreate)); pak.WritePascalString(GameServer.ServerRules.GetPlayerGuildName(m_gameClient.Player, playerToCreate)); pak.WritePascalString(GameServer.ServerRules.GetPlayerLastName(m_gameClient.Player, playerToCreate)); pak.WriteByte(0x00); //Trialing 0 ... needed! SendTCP(pak); //if (GameServer.ServerRules.GetColorHandling(m_gameClient) == 1) // PvP SendObjectGuildID(playerToCreate, playerToCreate.Guild); //used for nearest friendly/enemy object buttons and name colors on PvP server }
public override void SendSetControlledHorse(GamePlayer player) { if (player == null || player.ObjectState != GameObject.eObjectState.Active) return; GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.ControlledHorse)); if (player.HasHorse) { pak.WriteShort(0); // for set self horse OID must be zero pak.WriteByte(player.ActiveHorse.ID); if (player.ActiveHorse.BardingColor == 0 && player.ActiveHorse.Barding != 0 && player.Guild != null) { int newGuildBitMask = (player.Guild.Emblem & 0x010000) >> 9; pak.WriteByte((byte)(player.ActiveHorse.Barding | newGuildBitMask)); pak.WriteShort((ushort)player.Guild.Emblem); } else { pak.WriteByte(player.ActiveHorse.Barding); pak.WriteShort(player.ActiveHorse.BardingColor); } pak.WriteByte(player.ActiveHorse.Saddle); pak.WriteByte(player.ActiveHorse.SaddleColor); pak.WriteByte(player.ActiveHorse.Slots); pak.WriteByte(player.ActiveHorse.Armor); pak.WritePascalString(player.ActiveHorse.Name == null ? "" : player.ActiveHorse.Name); } else { pak.Fill(0x00, 8); } SendTCP(pak); }
public override void SendTradeWindow() { if (m_gameClient.Player == null) return; if (m_gameClient.Player.TradeWindow == null) return; using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.TradeWindow))) { lock (m_gameClient.Player.TradeWindow.Sync) { foreach (InventoryItem item in m_gameClient.Player.TradeWindow.TradeItems) { pak.WriteByte((byte)item.SlotPosition); } pak.Fill(0x00, 10 - m_gameClient.Player.TradeWindow.TradeItems.Count); pak.WriteShort(0x0000); pak.WriteShort((ushort)Money.GetMithril(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetPlatinum(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetGold(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetSilver(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetCopper(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort(0x0000); pak.WriteShort((ushort)Money.GetMithril(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetPlatinum(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetGold(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetSilver(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetCopper(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort(0x0000); ArrayList items = m_gameClient.Player.TradeWindow.PartnerTradeItems; if (items != null) { pak.WriteByte((byte)items.Count); pak.WriteByte(0x01); } else { pak.WriteShort(0x0000); } pak.WriteByte((byte)(m_gameClient.Player.TradeWindow.Repairing ? 0x01 : 0x00)); pak.WriteByte((byte)(m_gameClient.Player.TradeWindow.Combine ? 0x01 : 0x00)); if (items != null) { foreach (InventoryItem item in items) { pak.WriteByte((byte)item.SlotPosition); WriteItemData(pak, item); } } if (m_gameClient.Player.TradeWindow.Partner != null) pak.WritePascalString("Trading with " + m_gameClient.Player.GetName(m_gameClient.Player.TradeWindow.Partner)); // transaction with ... else pak.WritePascalString("Selfcrafting"); // transaction with ... SendTCP(pak); } } }
public override void SendKeepRealmUpdate(AbstractGameKeep keep) { GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.KeepRealmUpdate)); pak.WriteShort((ushort)keep.KeepID); pak.WriteByte((byte)keep.Realm); pak.WriteByte((byte)keep.Level); SendTCP(pak); }
public override void SendKeepRemove(IGameKeep keep) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.KeepRemove))) { pak.WriteShort((ushort)keep.KeepID); SendTCP(pak); } }
protected override void SendQuestWindow(GameNPC questNPC, GamePlayer player, DataQuest quest, bool offer) { GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.Dialog)); ushort QuestID = quest.ClientQuestID; pak.WriteShort((offer) ? (byte)0x22 : (byte)0x21); // Dialog pak.WriteShort(QuestID); pak.WriteShort((ushort)questNPC.ObjectID); pak.WriteByte(0x00); // unknown pak.WriteByte(0x00); // unknown pak.WriteByte(0x00); // unknown pak.WriteByte(0x00); // unknown pak.WriteByte((offer) ? (byte)0x02 : (byte)0x01); // Accept/Decline or Finish/Not Yet pak.WriteByte(0x01); // Wrap pak.WritePascalString(quest.Name); String personalizedSummary = BehaviourUtils.GetPersonalizedMessage(quest.Description, player); if (personalizedSummary.Length > 255) { pak.WritePascalString(personalizedSummary.Substring(0, 255)); // Summary is max 255 bytes ! } else { pak.WritePascalString(personalizedSummary); } if (offer) { //String personalizedStory = BehaviourUtils.GetPersonalizedMessage(quest.Story, player); pak.WriteShort((ushort)quest.Story.Length); pak.WriteStringBytes(quest.Story); } else { pak.WriteShort((ushort)quest.FinishText.Length); pak.WriteStringBytes(quest.FinishText); } pak.WriteShort(QuestID); pak.WriteByte((byte)quest.StepTexts.Count); // #goals count foreach (string text in quest.StepTexts) { pak.WritePascalString(String.Format("{0}\r", text)); } pak.WriteInt((uint)(0)); pak.WriteByte((byte)0); pak.WriteByte((byte)quest.FinalRewards.Count); foreach (ItemTemplate reward in quest.FinalRewards) { WriteItemData(pak, GameInventoryItem.Create<ItemTemplate>(reward)); } pak.WriteByte((byte)quest.NumOptionalRewardsChoice); pak.WriteByte((byte)quest.OptionalRewards.Count); foreach (ItemTemplate reward in quest.OptionalRewards) { WriteItemData(pak, GameInventoryItem.Create<ItemTemplate>(reward)); } SendTCP(pak); }
public override void SendXFireInfo(byte flag) { if (m_gameClient == null || m_gameClient.Player == null) return; GSTCPPacketOut pak = new GSTCPPacketOut((byte)eServerPackets.XFire); pak.WriteShort((ushort)m_gameClient.Player.ObjectID); pak.WriteByte(flag); pak.WriteByte(0x00); SendTCP(pak); }
public override void SendLivingEquipmentUpdate(GameLiving living) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.EquipmentUpdate))) { ICollection<InventoryItem> items = null; if (living.Inventory != null) items = living.Inventory.VisibleItems; pak.WriteShort((ushort)living.ObjectID); pak.WriteByte((byte)living.VisibleActiveWeaponSlots); pak.WriteByte((byte)living.CurrentSpeed); // new in 189b+, speed pak.WriteByte((byte)((living.IsCloakInvisible ? 0x01 : 0x00) | (living.IsHelmInvisible ? 0x02 : 0x00))); // new in 189b+, cloack/helm visibility pak.WriteByte((byte)((living.IsCloakHoodUp ? 0x01 : 0x00) | (int)living.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver if (items != null) { pak.WriteByte((byte)items.Count); foreach (InventoryItem item in items) { ushort model = (ushort)(item.Model & 0x1FFF); int slot = item.SlotPosition; //model = GetModifiedModel(model); int texture = item.Emblem != 0 ? item.Emblem : item.Color; if (item.SlotPosition == Slot.LEFTHAND || item.SlotPosition == Slot.CLOAK) // for test only cloack and shield slot = slot | ((texture & 0x010000) >> 9); // slot & 0x80 if new emblem pak.WriteByte((byte)slot); if ((texture & ~0xFF) != 0) model |= 0x8000; else if ((texture & 0xFF) != 0) model |= 0x4000; if (item.Effect != 0) model |= 0x2000; pak.WriteShort(model); if (item.SlotPosition > Slot.RANGED || item.SlotPosition < Slot.RIGHTHAND) pak.WriteByte((byte)item.Extension); if ((texture & ~0xFF) != 0) pak.WriteShort((ushort)texture); else if ((texture & 0xFF) != 0) pak.WriteByte((byte)texture); if (item.Effect != 0) pak.WriteByte((byte)item.Effect); } } else { pak.WriteByte(0x00); } SendTCP(pak); } }
public override void SendLoginGranted(byte color) { GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.LoginGranted)); pak.WritePascalString(m_gameClient.Account.Name); pak.WritePascalString(GameServer.Instance.Configuration.ServerNameShort); //server name pak.WriteByte(0x0C); //Server ID pak.WriteByte(color); pak.WriteByte(0x00); pak.WriteByte(0x00); SendTCP(pak); }
public override void SendBlinkPanel(byte flag) { GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.VisualEffect)); GamePlayer player = base.m_gameClient.Player; pak.WriteShort((ushort)player.ObjectID); pak.WriteByte((byte)8); pak.WriteByte((byte)flag); pak.WriteByte((byte)0); SendTCP(pak); }
public override void SendNonHybridSpellLines() { base.SendNonHybridSpellLines(); using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.VariousUpdate))) { pak.WriteByte(0x02); //subcode pak.WriteByte(0x00); pak.WriteByte(99); //subtype (new subtype 99 in 1.80e) pak.WriteByte(0x00); SendTCP(pak); } }
public override void SendNonHybridSpellLines() { if (m_gameClient.Player == null) return; base.SendNonHybridSpellLines(); GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.VariousUpdate)); pak.WriteByte(0x02); //subcode pak.WriteByte(0x00); pak.WriteByte(99); //subtype (new subtype 99 in 1.80e) pak.WriteByte(0x00); SendTCP(pak); }
public override void SendKeepInfo(AbstractGameKeep keep) { GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.KeepInfo)); pak.WriteShort((ushort)keep.KeepID); pak.WriteShort(0);//zone id not sure pak.WriteInt((uint)keep.X); pak.WriteInt((uint)keep.Y); pak.WriteShort((ushort)keep.Heading); pak.WriteByte((byte)keep.Realm); pak.WriteByte((byte)keep.Level);//level(not sure) pak.WriteShort(0);//unk pak.WriteByte(0x57);//model= 5-8Bit =lvl 1-4bit = Keep Type //uncertain pak.WriteByte(0xB7);//unk SendTCP(pak); }
public override void SendFindGroupWindowUpdate(GamePlayer[] list) { if (m_gameClient.Player==null) return; using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.FindGroupUpdate))) { if (list!=null) { pak.WriteByte((byte)list.Length); byte nbleader=0; byte nbsolo=0x1E; foreach(GamePlayer player in list) { if (player.Group!=null) { pak.WriteByte(nbleader++); } else { pak.WriteByte(nbsolo++); } pak.WriteByte(player.Level); pak.WritePascalString(player.Name); pak.WriteString(player.CharacterClass.Name, 4); //Dinberg:Instances - We use ZoneSkinID to bluff our way to victory and //trick the client for positioning objects (as IDs are hard coded). if(player.CurrentZone != null) pak.WriteShort(player.CurrentZone.ZoneSkinID); else pak.WriteShort(0); // ? pak.WriteByte(0); // duration pak.WriteByte(0); // objective pak.WriteByte(0); pak.WriteByte(0); pak.WriteByte((byte) (player.Group!=null ? 1 : 0)); pak.WriteByte(0); } } else { pak.WriteByte(0); } SendTCP(pak); } }
public override void SendUpdatePoints() { if (m_gameClient.Player == null) return; GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.CharacterPointsUpdate)); pak.WriteInt((uint)m_gameClient.Player.RealmPoints); pak.WriteShort(m_gameClient.Player.LevelPermill); pak.WriteShort((ushort)m_gameClient.Player.SkillSpecialtyPoints); pak.WriteInt((uint)m_gameClient.Player.BountyPoints); pak.WriteShort((ushort)m_gameClient.Player.RealmSpecialtyPoints); pak.WriteShort(m_gameClient.Player.ChampionLevelPermill); pak.WriteLongLowEndian((ulong)m_gameClient.Player.Experience); pak.WriteLongLowEndian((ulong)m_gameClient.Player.ExperienceForNextLevel); pak.WriteLongLowEndian(0);//champExp pak.WriteLongLowEndian(0);//champExpNextLevel SendTCP(pak); }
protected override void SendQuestWindow(GameNPC questNPC, GamePlayer player, RewardQuest quest, bool offer) { GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.Dialog)); ushort QuestID = QuestMgr.GetIDForQuestType(quest.GetType()); pak.WriteShort((offer) ? (byte)0x22 : (byte)0x21); // Dialog pak.WriteShort(QuestID); pak.WriteShort((ushort)questNPC.ObjectID); pak.WriteByte(0x00); // unknown pak.WriteByte(0x00); // unknown pak.WriteByte(0x00); // unknown pak.WriteByte(0x00); // unknown pak.WriteByte((offer) ? (byte)0x02 : (byte)0x01); // Accept/Decline or Finish/Not Yet pak.WriteByte(0x01); // Wrap pak.WritePascalString(quest.Name); if (quest.Summary.Length > 255) pak.WritePascalString(quest.Summary.Substring(0,255)); else pak.WritePascalString(quest.Summary); if (offer) { pak.WriteShort((ushort)quest.Story.Length); pak.WriteStringBytes(quest.Story); } else { pak.WriteShort((ushort)quest.Conclusion.Length); pak.WriteStringBytes(quest.Conclusion); } pak.WriteShort(QuestID); pak.WriteByte((byte)quest.Goals.Count); // #goals count foreach (RewardQuest.QuestGoal goal in quest.Goals) { pak.WritePascalString(String.Format("{0}\r", goal.Description)); } pak.WriteByte((byte)quest.Level); pak.WriteByte((byte)quest.Rewards.MoneyPercent); pak.WriteByte((byte)quest.Rewards.ExperiencePercent(player)); pak.WriteByte((byte)quest.Rewards.BasicItems.Count); foreach (ItemTemplate reward in quest.Rewards.BasicItems) WriteTemplateData(pak, reward, 1); pak.WriteByte((byte)quest.Rewards.ChoiceOf); pak.WriteByte((byte)quest.Rewards.OptionalItems.Count); foreach (ItemTemplate reward in quest.Rewards.OptionalItems) WriteTemplateData(pak, reward, 1); SendTCP(pak); }
public override void SendObjectCreate(GameObject obj) { if (obj == null || m_gameClient.Player == null) return; if (obj.IsVisibleTo(m_gameClient.Player) == false) return; GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.ObjectCreate)); pak.WriteShort((ushort)obj.ObjectID); if (obj is GameStaticItem) pak.WriteShort((ushort)(obj as GameStaticItem).Emblem); else pak.WriteShort(0); pak.WriteShort(obj.Heading); pak.WriteShort((ushort)obj.Z); pak.WriteInt((uint)obj.X); pak.WriteInt((uint)obj.Y); int flag = ((byte)obj.Realm & 3) << 4; ushort model = obj.Model; if (obj.IsUnderwater) { if (obj is GameNPC) model |= 0x8000; else flag |= 0x01; // Underwater } pak.WriteShort(model); if (obj is GameKeepBanner) flag |= 0x08; if (obj is GameStaticItemTimed && m_gameClient.Player != null && ((GameStaticItemTimed)obj).IsOwner(m_gameClient.Player)) flag |= 0x04; pak.WriteShort((ushort)flag); pak.WriteInt(0x0); //TODO: unknown, new in 1.71 pak.WritePascalString(obj.Name); if (obj is IDoor) { pak.WriteByte(4); pak.WriteInt((uint)(obj as IDoor).DoorID); } else pak.WriteByte(0x00); SendTCP(pak); }
public override void SendCustomTextWindow(string caption, IList<string> text) { if (text == null) return; GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.DetailWindow)); pak.WriteByte(0); // new in 1.75 if (caption == null) caption = ""; if (caption.Length > byte.MaxValue) caption = caption.Substring(0, byte.MaxValue); pak.WritePascalString(caption); //window caption WriteCustomTextWindowData(pak, text); //Trailing Zero! pak.WriteByte(0); SendTCP(pak); }
protected override void SendQuestPacket(AbstractQuest quest, int index) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.QuestEntry))) { pak.WriteByte((byte) index); if (quest.Step <= 0) { pak.WriteByte(0); pak.WriteByte(0); pak.WriteByte(0); pak.WriteByte(0); } else { string name = quest.Name; string desc = quest.Description; if (name.Length > byte.MaxValue) { if (log.IsWarnEnabled) log.Warn(quest.GetType().ToString() + ": name is too long for 1.71 clients ("+name.Length+") '"+name+"'"); name = name.Substring(0, byte.MaxValue); } if (desc.Length > ushort.MaxValue) { if (log.IsWarnEnabled) log.Warn(quest.GetType().ToString() + ": description is too long for 1.71 clients ("+desc.Length+") '"+desc+"'"); desc = desc.Substring(0, ushort.MaxValue); } if (name.Length + desc.Length > 2048-10) { if (log.IsWarnEnabled) log.Warn(quest.GetType().ToString() + ": name + description length is too long and would have crashed the client.\nName ("+name.Length+"): '"+name+"'\nDesc ("+desc.Length+"): '"+desc+"'"); name = name.Substring(0, 32); desc = desc.Substring(0, 2048-10 - name.Length); // all that's left } pak.WriteByte((byte)name.Length); pak.WriteShortLowEndian((ushort)desc.Length); pak.WriteByte(0); pak.WriteStringBytes(name); //Write Quest Name without trailing 0 pak.WriteStringBytes(desc); //Write Quest Description without trailing 0 } SendTCP(pak); } }
/// <summary> /// Reply on Server Opening to Client Encryption Request /// Actually forces Encryption Off to work with Portal. /// </summary> public override void SendVersionAndCryptKey() { //Construct the new packet using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.CryptKey))) { pak.WriteByte((byte)m_gameClient.ClientType); //Disable encryption (1110+ always encrypt) pak.WriteByte(0x00); // Reply with current version pak.WriteString((((int)m_gameClient.Version) / 1000) + "." + (((int)m_gameClient.Version) - 1000), 5); // revision, last seen (c) 0x63 pak.WriteByte(0x00); // Build number pak.WriteByte(0x00); // last seen : 0x44 0x05 pak.WriteByte(0x00); SendTCP(pak); } }
public override void SendStatusUpdate(byte sittingFlag) { if (m_gameClient.Player == null) return; GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.CharacterStatusUpdate)); pak.WriteByte(m_gameClient.Player.HealthPercent); pak.WriteByte(m_gameClient.Player.ManaPercent); pak.WriteByte(sittingFlag); pak.WriteByte(m_gameClient.Player.EndurancePercent); pak.WriteByte(m_gameClient.Player.ConcentrationPercent); // pak.WriteShort((byte) (m_gameClient.Player.IsAlive ? 0x00 : 0x0f)); // 0x0F if dead ??? where it now ? pak.WriteByte(0);// unk pak.WriteShort((ushort)m_gameClient.Player.MaxMana); pak.WriteShort((ushort)m_gameClient.Player.MaxEndurance); pak.WriteShort((ushort)m_gameClient.Player.MaxConcentration); pak.WriteShort((ushort)m_gameClient.Player.MaxHealth); pak.WriteShort((ushort)m_gameClient.Player.Health); pak.WriteShort((ushort)m_gameClient.Player.Endurance); pak.WriteShort((ushort)m_gameClient.Player.Mana); pak.WriteShort((ushort)m_gameClient.Player.Concentration); SendTCP(pak); }
public override void SendKeepComponentInfo(GameKeepComponent keepComponent) { GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.KeepComponentInfo)); pak.WriteShort((ushort)keepComponent.Keep.KeepID); pak.WriteShort((ushort)keepComponent.ID); pak.WriteInt((uint)keepComponent.ObjectID); pak.WriteByte((byte)keepComponent.Skin); pak.WriteByte((byte)(keepComponent.ComponentX));//relative to keep pak.WriteByte((byte)(keepComponent.ComponentY));//relative to keep pak.WriteByte((byte)keepComponent.ComponentHeading); pak.WriteByte((byte)keepComponent.Height); pak.WriteByte(keepComponent.HealthPercent); byte flag = keepComponent.Status; if (keepComponent.IsRaized) // Only for towers flag |= 0x04; if (flag == 0x00 && keepComponent.Climbing) flag = 0x02; pak.WriteByte(flag); pak.WriteByte(0x00); //unk SendTCP(pak); }
protected override void SendQuestPacket(AbstractQuest quest, int index) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.QuestEntry))) { pak.WriteByte((byte) index); if (quest == null) { pak.WriteByte(0); pak.WriteByte(0); pak.WriteByte(0); pak.WriteByte(0); pak.WriteByte(0); } else { string name = string.Format("{0} (Level {1})", quest.Name, quest.Level); string desc = string.Format("[Step #{0}]: {1}", quest.Step, quest.Description); if (name.Length > byte.MaxValue) { if (log.IsWarnEnabled) log.Warn(quest.GetType().ToString() + ": name is too long for 1.68+ clients (" + name.Length + ") '" + name + "'"); name = name.Substring(0, byte.MaxValue); } if (desc.Length > byte.MaxValue) { if (log.IsWarnEnabled) log.Warn(quest.GetType().ToString() + ": description is too long for 1.68+ clients (" + desc.Length + ") '" + desc + "'"); desc = desc.Substring(0, byte.MaxValue); } pak.WriteByte((byte)name.Length); pak.WriteShortLowEndian((ushort)desc.Length); pak.WriteByte(0); // Quest Zone ID ? pak.WriteByte(0); pak.WriteStringBytes(name); //Write Quest Name without trailing 0 pak.WriteStringBytes(desc); //Write Quest Description without trailing 0 } SendTCP(pak); } }
protected override void SendInventorySlotsUpdateRange(ICollection <int> slots, eInventoryWindowType windowType) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.InventoryUpdate))) { pak.WriteByte((byte)(slots == null ? 0 : slots.Count)); pak.WriteByte((byte)((m_gameClient.Player.IsCloakHoodUp ? 0x01 : 0x00) | (int)m_gameClient.Player.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver pak.WriteByte((byte)m_gameClient.Player.VisibleActiveWeaponSlots); pak.WriteByte((byte)windowType); if (slots != null) { foreach (int updatedSlot in slots) { if (updatedSlot >= (int)eInventorySlot.Consignment_First && updatedSlot <= (int)eInventorySlot.Consignment_Last) { pak.WriteByte((byte)(updatedSlot - (int)eInventorySlot.Consignment_First + (int)eInventorySlot.HousingInventory_First)); } else { pak.WriteByte((byte)(updatedSlot)); } InventoryItem item = null; item = m_gameClient.Player.Inventory.GetItem((eInventorySlot)updatedSlot); if (item == null) { pak.Fill(0x00, 19); continue; } pak.WriteByte((byte)item.Level); int value1; // some object types use this field to display count int value2; // some object types use this field to display count switch (item.Object_Type) { case (int)eObjectType.Arrow: case (int)eObjectType.Bolt: case (int)eObjectType.Poison: case (int)eObjectType.GenericItem: value1 = item.Count; value2 = item.SPD_ABS; break; case (int)eObjectType.Thrown: value1 = item.DPS_AF; value2 = item.Count; break; case (int)eObjectType.Instrument: value1 = (item.DPS_AF == 2 ? 0 : item.DPS_AF); value2 = 0; break; // unused case (int)eObjectType.Shield: value1 = item.Type_Damage; value2 = item.DPS_AF; break; case (int)eObjectType.AlchemyTincture: case (int)eObjectType.SpellcraftGem: value1 = 0; value2 = 0; /* * must contain the quality of gem for spell craft and think same for tincture */ break; case (int)eObjectType.GardenObject: value1 = 0; value2 = item.SPD_ABS; /* * Value2 byte sets the width, only lower 4 bits 'seem' to be used (so 1-15 only) * * The byte used for "Hand" (IE: Mini-delve showing a weapon as Left-Hand * usabe/TwoHanded), the lower 4 bits store the height (1-15 only) */ break; default: value1 = item.DPS_AF; value2 = item.SPD_ABS; break; } pak.WriteByte((byte)value1); pak.WriteByte((byte)value2); if (item.Object_Type == (int)eObjectType.GardenObject) { pak.WriteByte((byte)(item.DPS_AF)); } else { pak.WriteByte((byte)(item.Hand << 6)); } pak.WriteByte((byte)((item.Type_Damage > 3 ? 0 : item.Type_Damage << 6) | item.Object_Type)); pak.WriteShort((ushort)item.Weight); pak.WriteByte(item.ConditionPercent); // % of con pak.WriteByte(item.DurabilityPercent); // % of dur pak.WriteByte((byte)item.Quality); // % of qua pak.WriteByte((byte)item.Bonus); // % bonus pak.WriteShort((ushort)item.Model); pak.WriteByte((byte)item.Extension); if (item.Emblem != 0) { pak.WriteShort((ushort)item.Emblem); } else { pak.WriteShort((ushort)item.Color); } pak.WriteShort((ushort)item.Effect); string name = item.Name; if (item.Count > 1) { name = item.Count + " " + name; } if (item.SellPrice > 0) { if (ServerProperties.Properties.CONSIGNMENT_USE_BP) { name += "[" + item.SellPrice.ToString() + " BP]"; } else { name += "[" + Money.GetString(item.SellPrice) + "]"; } } pak.WritePascalString(name); } } SendTCP(pak); } }
public override void SendLivingEquipmentUpdate(GameLiving living) { if (m_gameClient.Player == null || living.IsVisibleTo(m_gameClient.Player) == false) { return; } using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.EquipmentUpdate))) { ICollection <InventoryItem> items = null; if (living.Inventory != null) { items = living.Inventory.VisibleItems; } pak.WriteShort((ushort)living.ObjectID); pak.WriteByte((byte)((living.IsCloakHoodUp ? 0x01 : 0x00) | (int)living.ActiveQuiverSlot)); //bit0 is hood up bit4 to 7 is active quiver pak.WriteByte((byte)living.VisibleActiveWeaponSlots); if (items != null) { pak.WriteByte((byte)items.Count); foreach (InventoryItem item in items) { pak.WriteByte((byte)item.SlotPosition); ushort model = (ushort)(item.Model & 0x1FFF); if (model > 2952) { model = 0; } int texture = (item.Emblem != 0) ? item.Emblem : item.Color; if ((texture & ~0xFF) != 0) { model |= 0x8000; } else if ((texture & 0xFF) != 0) { model |= 0x4000; } if (item.Effect != 0) { model |= 0x2000; } pak.WriteShort(model); if (item.SlotPosition > Slot.RANGED || item.SlotPosition < Slot.RIGHTHAND) { pak.WriteByte((byte)item.Extension); } if ((texture & ~0xFF) != 0) { pak.WriteShort((ushort)texture); } else if ((texture & 0xFF) != 0) { pak.WriteByte((byte)texture); } if (item.Effect != 0) { pak.WriteShort((ushort)item.Effect); } } } else { pak.WriteByte(0x00); } SendTCP(pak); } }
public override void SendPlayerCreate(GamePlayer playerToCreate) { Region playerRegion = playerToCreate.CurrentRegion; if (playerRegion == null) { if (log.IsWarnEnabled) { log.Warn("SendPlayerCreate: playerRegion == null"); } return; } Zone playerZone = playerToCreate.CurrentZone; if (playerZone == null) { if (log.IsWarnEnabled) { log.Warn("SendPlayerCreate: playerZone == null"); } return; } if (m_gameClient.Player == null || playerToCreate.IsVisibleTo(m_gameClient.Player) == false) { return; } using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.PlayerCreate172))) { pak.WriteShort((ushort)playerToCreate.Client.SessionID); pak.WriteShort((ushort)playerToCreate.ObjectID); pak.WriteShort(playerToCreate.Model); pak.WriteShort((ushort)playerToCreate.Z); //Dinberg:Instances - Zoneskin ID for clientside positioning 'bluff'. pak.WriteShort(playerZone.ZoneSkinID); pak.WriteShort((ushort)playerRegion.GetXOffInZone(playerToCreate.X, playerToCreate.Y)); pak.WriteShort((ushort)playerRegion.GetYOffInZone(playerToCreate.X, playerToCreate.Y)); pak.WriteShort(playerToCreate.Heading); pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.EyeSize)); //1-4 = Eye Size / 5-8 = Nose Size pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.LipSize)); //1-4 = Ear size / 5-8 = Kin size pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.EyeColor)); //1-4 = Skin Color / 5-8 = Eye Color pak.WriteByte(playerToCreate.GetDisplayLevel(m_gameClient.Player)); pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.HairColor)); //Hair: 1-4 = Color / 5-8 = unknown pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.FaceType)); //1-4 = Unknown / 5-8 = Face type pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.HairStyle)); //1-4 = Unknown / 5-8 = Hair Style int flags = (GameServer.ServerRules.GetLivingRealm(m_gameClient.Player, playerToCreate) & 0x03) << 2; if (playerToCreate.IsAlive == false) { flags |= 0x01; } if (playerToCreate.IsUnderwater) { flags |= 0x02; //swimming } if (playerToCreate.IsStealthed) { flags |= 0x10; } if (playerToCreate.IsWireframe) { flags |= 0x20; } pak.WriteByte((byte)flags); pak.WritePascalString(GameServer.ServerRules.GetPlayerName(m_gameClient.Player, playerToCreate)); pak.WritePascalString(GameServer.ServerRules.GetPlayerGuildName(m_gameClient.Player, playerToCreate)); pak.WritePascalString(GameServer.ServerRules.GetPlayerLastName(m_gameClient.Player, playerToCreate)); pak.WriteByte(0x00); //Trialing 0 ... needed! SendTCP(pak); } // Update Cache m_gameClient.GameObjectUpdateArray[new Tuple <ushort, ushort>(playerToCreate.CurrentRegionID, (ushort)playerToCreate.ObjectID)] = GameTimer.GetTickCount(); SendObjectGuildID(playerToCreate, playerToCreate.Guild); //used for nearest friendly/enemy object buttons and name colors on PvP server }
public override void SendTradeWindow() { if (m_gameClient.Player == null) { return; } if (m_gameClient.Player.TradeWindow == null) { return; } using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.TradeWindow))) { lock (m_gameClient.Player.TradeWindow.Sync) { foreach (InventoryItem item in m_gameClient.Player.TradeWindow.TradeItems) { pak.WriteByte((byte)item.SlotPosition); } pak.Fill(0x00, 10 - m_gameClient.Player.TradeWindow.TradeItems.Count); pak.WriteShort(0x0000); pak.WriteShort((ushort)Money.GetMithril(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetPlatinum(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetGold(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetSilver(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetCopper(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort(0x0000); pak.WriteShort((ushort)Money.GetMithril(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetPlatinum(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetGold(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetSilver(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetCopper(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort(0x0000); ArrayList items = m_gameClient.Player.TradeWindow.PartnerTradeItems; if (items != null) { pak.WriteByte((byte)items.Count); pak.WriteByte(0x01); } else { pak.WriteShort(0x0000); } pak.WriteByte((byte)(m_gameClient.Player.TradeWindow.Repairing ? 0x01 : 0x00)); pak.WriteByte((byte)(m_gameClient.Player.TradeWindow.Combine ? 0x01 : 0x00)); if (items != null) { foreach (InventoryItem item in items) { pak.WriteByte((byte)item.SlotPosition); pak.WriteByte((byte)item.Level); pak.WriteByte((byte)item.DPS_AF); // dps_af pak.WriteByte((byte)item.SPD_ABS); //spd_abs pak.WriteByte((byte)(item.Hand << 6)); pak.WriteByte((byte)((item.Type_Damage > 3 ? 0 : item.Type_Damage << 6) | item.Object_Type)); pak.WriteShort((ushort)item.Weight); // weight pak.WriteByte(item.ConditionPercent); // con % pak.WriteByte(item.DurabilityPercent); // dur % pak.WriteByte((byte)item.Quality); // qua % pak.WriteByte((byte)item.Bonus); // bon % pak.WriteShort((ushort)item.Model); //model if (item.SlotPosition > Slot.RANGED || item.SlotPosition < Slot.RIGHTHAND) { pak.WriteByte((byte)item.Extension); } pak.WriteShort((ushort)item.Color); //color pak.WriteShort((ushort)item.Effect); //weaponproc if (item.Count > 1) { pak.WritePascalString(item.Count + " " + item.Name); } else { pak.WritePascalString(item.Name); //size and name item } } } if (m_gameClient.Player.TradeWindow.Partner != null) { pak.WritePascalString("Trading with " + m_gameClient.Player.GetName(m_gameClient.Player.TradeWindow.Partner)); // transaction with ... } else { pak.WritePascalString("Selfcrafting"); // transaction with ... } SendTCP(pak); } } }
protected override void WriteTemplateData(GSTCPPacketOut pak, ItemTemplate template, int count) { if (template == null) { pak.Fill(0x00, 20); // 1.109 +1 byte return; } pak.WriteByte((byte)template.Level); int value1; int value2; switch (template.Object_Type) { case (int)eObjectType.Arrow: case (int)eObjectType.Bolt: case (int)eObjectType.Poison: case (int)eObjectType.GenericItem: value1 = count; // Count value2 = template.SPD_ABS; break; case (int)eObjectType.Thrown: value1 = template.DPS_AF; value2 = count; // Count break; case (int)eObjectType.Instrument: value1 = (template.DPS_AF == 2 ? 0 : template.DPS_AF); value2 = 0; break; case (int)eObjectType.Shield: value1 = template.Type_Damage; value2 = template.DPS_AF; break; case (int)eObjectType.AlchemyTincture: case (int)eObjectType.SpellcraftGem: value1 = 0; value2 = 0; /* * must contain the quality of gem for spell craft and think same for tincture */ break; case (int)eObjectType.GardenObject: value1 = 0; value2 = template.SPD_ABS; /* * Value2 byte sets the width, only lower 4 bits 'seem' to be used (so 1-15 only) * * The byte used for "Hand" (IE: Mini-delve showing a weapon as Left-Hand * usabe/TwoHanded), the lower 4 bits store the height (1-15 only) */ break; default: value1 = template.DPS_AF; value2 = template.SPD_ABS; break; } pak.WriteByte((byte)value1); pak.WriteByte((byte)value2); if (template.Object_Type == (int)eObjectType.GardenObject) { pak.WriteByte((byte)(template.DPS_AF)); } else { pak.WriteByte((byte)(template.Hand << 6)); } pak.WriteByte((byte)((template.Type_Damage > 3 ? 0 : template.Type_Damage << 6) | template.Object_Type)); pak.Fill(0x00, 1); // 1.109, +1 byte, no clue what this is - Tolakram pak.WriteShort((ushort)template.Weight); pak.WriteByte(template.BaseConditionPercent); pak.WriteByte(template.BaseDurabilityPercent); pak.WriteByte((byte)template.Quality); pak.WriteByte((byte)template.Bonus); pak.WriteShort((ushort)template.Model); pak.WriteByte((byte)template.Extension); if (template.Emblem != 0) { pak.WriteShort((ushort)template.Emblem); } else { pak.WriteShort((ushort)template.Color); } pak.WriteByte((byte)0); // Flag pak.WriteByte((byte)template.Effect); if (count > 1) { pak.WritePascalString(String.Format("{0} {1}", count, template.Name)); } else { pak.WritePascalString(template.Name); } }
public override void SendTradeWindow() { if (m_gameClient.Player == null) { return; } if (m_gameClient.Player.TradeWindow == null) { return; } using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.TradeWindow))) { lock (m_gameClient.Player.TradeWindow.Sync) { foreach (InventoryItem item in m_gameClient.Player.TradeWindow.TradeItems) { pak.WriteByte((byte)item.SlotPosition); } pak.Fill(0x00, 10 - m_gameClient.Player.TradeWindow.TradeItems.Count); pak.WriteShort(0x0000); pak.WriteShort((ushort)Money.GetMithril(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetPlatinum(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetGold(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetSilver(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort((ushort)Money.GetCopper(m_gameClient.Player.TradeWindow.TradeMoney)); pak.WriteShort(0x0000); pak.WriteShort((ushort)Money.GetMithril(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetPlatinum(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetGold(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetSilver(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort((ushort)Money.GetCopper(m_gameClient.Player.TradeWindow.PartnerTradeMoney)); pak.WriteShort(0x0000); ArrayList items = m_gameClient.Player.TradeWindow.PartnerTradeItems; if (items != null) { pak.WriteByte((byte)items.Count); pak.WriteByte(0x01); } else { pak.WriteShort(0x0000); } pak.WriteByte((byte)(m_gameClient.Player.TradeWindow.Repairing ? 0x01 : 0x00)); pak.WriteByte((byte)(m_gameClient.Player.TradeWindow.Combine ? 0x01 : 0x00)); if (items != null) { foreach (InventoryItem item in items) { pak.WriteByte((byte)item.SlotPosition); WriteItemData(pak, item); } } if (m_gameClient.Player.TradeWindow.Partner != null) { pak.WritePascalString("Trading with " + m_gameClient.Player.GetName(m_gameClient.Player.TradeWindow.Partner)); // transaction with ... } else { pak.WritePascalString("Selfcrafting"); // transaction with ... } SendTCP(pak); } } }
protected virtual void WriteItemData(GSTCPPacketOut pak, InventoryItem item) { if (item == null) { pak.Fill(0x00, 19); return; } // Create a GameInventoryItem so item will display correctly in inventory window item = GameInventoryItem.Create(item); pak.WriteByte((byte)item.Level); int value1; // some object types use this field to display count int value2; // some object types use this field to display count switch (item.Object_Type) { case (int)eObjectType.GenericItem: value1 = item.Count & 0xFF; value2 = (item.Count >> 8) & 0xFF; break; case (int)eObjectType.Arrow: case (int)eObjectType.Bolt: case (int)eObjectType.Poison: value1 = item.Count; value2 = item.SPD_ABS; break; case (int)eObjectType.Thrown: value1 = item.DPS_AF; value2 = item.Count; break; case (int)eObjectType.Instrument: value1 = (item.DPS_AF == 2 ? 0 : item.DPS_AF); value2 = 0; break; // unused case (int)eObjectType.Shield: value1 = item.Type_Damage; value2 = item.DPS_AF; break; case (int)eObjectType.AlchemyTincture: case (int)eObjectType.SpellcraftGem: value1 = 0; value2 = 0; /* * must contain the quality of gem for spell craft and think same for tincture */ break; case (int)eObjectType.HouseWallObject: case (int)eObjectType.HouseFloorObject: case (int)eObjectType.GardenObject: value1 = 0; value2 = item.SPD_ABS; /* * Value2 byte sets the width, only lower 4 bits 'seem' to be used (so 1-15 only) * * The byte used for "Hand" (IE: Mini-delve showing a weapon as Left-Hand * usabe/TwoHanded), the lower 4 bits store the height (1-15 only) */ break; default: value1 = item.DPS_AF; value2 = item.SPD_ABS; break; } pak.WriteByte((byte)value1); pak.WriteByte((byte)value2); // ChatUtil.SendDebugMessage(m_gameClient, string.Format("WriteItemDate189: name {0}, level {1}, object {2}, value1 {3}, value2 {4}", item.Id_nb, item.Level, item.Object_Type, value1, value2)); if (item.Object_Type == (int)eObjectType.GardenObject) { pak.WriteByte((byte)(item.DPS_AF)); } else { pak.WriteByte((byte)(item.Hand << 6)); } pak.WriteByte((byte)((item.Type_Damage > 3 ? 0 : item.Type_Damage << 6) | item.Object_Type)); pak.WriteShort((ushort)item.Weight); pak.WriteByte(item.ConditionPercent); // % of con pak.WriteByte(item.DurabilityPercent); // % of dur pak.WriteByte((byte)item.Quality); // % of qua pak.WriteByte((byte)item.Bonus); // % bonus pak.WriteShort((ushort)item.Model); pak.WriteByte((byte)item.Extension); int flag = 0; if (item.Emblem != 0) { pak.WriteShort((ushort)item.Emblem); flag |= (item.Emblem & 0x010000) >> 16; // = 1 for newGuildEmblem } else { pak.WriteShort((ushort)item.Color); } flag |= 0x02; // enable salvage button // Enable craft button if the item can be modified and the player has alchemy or spellcrafting eCraftingSkill skill = CraftingMgr.GetCraftingSkill(item); switch (skill) { case eCraftingSkill.ArmorCrafting: case eCraftingSkill.Fletching: case eCraftingSkill.Tailoring: case eCraftingSkill.WeaponCrafting: if (m_gameClient.Player.CraftingSkills.ContainsKey(eCraftingSkill.Alchemy) || m_gameClient.Player.CraftingSkills.ContainsKey(eCraftingSkill.SpellCrafting)) { flag |= 0x04; // enable craft button } break; default: break; } ushort icon1 = 0; ushort icon2 = 0; string spell_name1 = ""; string spell_name2 = ""; if (item.Object_Type != (int)eObjectType.AlchemyTincture) { SpellLine chargeEffectsLine = SkillBase.GetSpellLine(GlobalSpellsLines.Item_Effects); if (chargeEffectsLine != null) { if (item.SpellID > 0 /* && item.Charges > 0*/) { Spell spell = SkillBase.FindSpell(item.SpellID, chargeEffectsLine); if (spell != null) { flag |= 0x08; icon1 = spell.Icon; spell_name1 = spell.Name; // or best spl.Name ? } } if (item.SpellID1 > 0 /* && item.Charges > 0*/) { Spell spell = SkillBase.FindSpell(item.SpellID1, chargeEffectsLine); if (spell != null) { flag |= 0x10; icon2 = spell.Icon; spell_name2 = spell.Name; // or best spl.Name ? } } } } pak.WriteByte((byte)flag); if ((flag & 0x08) == 0x08) { pak.WriteShort((ushort)icon1); pak.WritePascalString(spell_name1); } if ((flag & 0x10) == 0x10) { pak.WriteShort((ushort)icon2); pak.WritePascalString(spell_name2); } pak.WriteByte((byte)item.Effect); string name = item.Name; if (item.Count > 1) { name = item.Count + " " + name; } if (item.SellPrice > 0) { if (ServerProperties.Properties.CONSIGNMENT_USE_BP) { name += "[" + item.SellPrice.ToString() + " BP]"; } else { name += "[" + Money.GetShortString(item.SellPrice) + "]"; } } if (name.Length > MAX_NAME_LENGTH) { name = name.Substring(0, MAX_NAME_LENGTH); } pak.WritePascalString(name); }
public override void SendPetWindow(GameLiving pet, ePetWindowAction windowAction, eAggressionState aggroState, eWalkState walkState) { using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.PetWindow))) { pak.WriteShort((ushort)(pet == null ? 0 : pet.ObjectID)); pak.WriteByte(0x00); //unused pak.WriteByte(0x00); //unused switch (windowAction) //0-released, 1-normal, 2-just charmed? | Roach: 0-close window, 1-update window, 2-create window { case ePetWindowAction.Open: pak.WriteByte(2); break; case ePetWindowAction.Update: pak.WriteByte(1); break; default: pak.WriteByte(0); break; } switch (aggroState) //1-aggressive, 2-defensive, 3-passive { case eAggressionState.Aggressive: pak.WriteByte(1); break; case eAggressionState.Defensive: pak.WriteByte(2); break; case eAggressionState.Passive: pak.WriteByte(3); break; default: pak.WriteByte(0); break; } switch (walkState) //1-follow, 2-stay, 3-goto, 4-here { case eWalkState.Follow: pak.WriteByte(1); break; case eWalkState.Stay: pak.WriteByte(2); break; case eWalkState.GoTarget: pak.WriteByte(3); break; case eWalkState.ComeHere: pak.WriteByte(4); break; default: pak.WriteByte(0); break; } pak.WriteByte(0x00); //unused if (pet != null) { lock (pet.EffectList) { ArrayList icons = new ArrayList(); foreach (IGameEffect effect in pet.EffectList) { if (icons.Count >= 8) { break; } if (effect.Icon == 0) { continue; } icons.Add(effect.Icon); } pak.WriteByte((byte)icons.Count); // effect count // 0x08 - null terminated - (byte) list of shorts - spell icons on pet foreach (ushort icon in icons) { pak.WriteShort(icon); } } } else { pak.WriteByte((byte)0); // effect count } SendTCP(pak); } }
public override void SendObjectCreate(GameObject obj) { if (obj == null) return; if (obj.IsVisibleTo(m_gameClient.Player) == false) return; GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.ObjectCreate)); pak.WriteShort((ushort)obj.ObjectID); if (obj is GameStaticItem) pak.WriteShort((ushort)(obj as GameStaticItem).Emblem); else pak.WriteShort(0); pak.WriteShort(obj.Heading); pak.WriteShort((ushort)obj.Z); pak.WriteInt((uint)obj.X); pak.WriteInt((uint)obj.Y); int flag = ((byte)obj.Realm & 3) << 4; ushort model = obj.Model; if (obj.IsUnderwater) { if (obj is GameNPC) model |= 0x8000; else flag |= 0x01; // Underwater } pak.WriteShort(model); if (obj is Keeps.GameKeepBanner) flag |= 0x08; if (obj is GameStaticItemTimed && m_gameClient.Player != null && ((GameStaticItemTimed)obj).IsOwner(m_gameClient.Player)) flag |= 0x04; pak.WriteShort((ushort)flag); if (obj is GameStaticItem) { int newEmblemBitMask = ((obj as GameStaticItem).Emblem & 0x010000) << 9; pak.WriteInt((uint)newEmblemBitMask);//TODO other bits } else pak.WriteInt(0); string name = obj.Name; LanguageDataObject translation = null; if (obj is GameStaticItem) { translation = LanguageMgr.GetTranslation(m_gameClient, (GameStaticItem)obj); if (translation != null) { if (obj is WorldInventoryItem) { //if (!Util.IsEmpty(((DBLanguageItem)translation).Name)) // name = ((DBLanguageItem)translation).Name; } else { if (!Util.IsEmpty(((DBLanguageGameObject)translation).Name)) name = ((DBLanguageGameObject)translation).Name; } } } pak.WritePascalString(name.Length > 48 ? name.Substring(0, 48) : name); if (obj is IDoor) { pak.WriteByte(4); pak.WriteInt((uint)(obj as IDoor).DoorID); } else pak.WriteByte(0x00); SendTCP(pak); }
protected override void WriteGroupMemberUpdate(GSTCPPacketOut pak, bool updateIcons, GameLiving living) { pak.WriteByte((byte)(living.GroupIndex + 1)); // From 1 to 8 bool sameRegion = living.CurrentRegion == m_gameClient.Player.CurrentRegion; GamePlayer player = null; if (sameRegion) { player = living as GamePlayer; if (player != null) { pak.WriteByte(player.CharacterClass.HealthPercentGroupWindow); } else { pak.WriteByte(living.HealthPercent); } pak.WriteByte(living.ManaPercent); pak.WriteByte(living.EndurancePercent); // new in 1.69 byte playerStatus = 0; if (!living.IsAlive) { playerStatus |= 0x01; } if (living.IsMezzed) { playerStatus |= 0x02; } if (living.IsDiseased) { playerStatus |= 0x04; } if (SpellHelper.FindEffectOnTarget(living, "DamageOverTime") != null) { playerStatus |= 0x08; } if (living is GamePlayer) { if ((living as GamePlayer).Client.ClientState == GameClient.eClientState.Linkdead) { playerStatus |= 0x10; } } if (!sameRegion) { playerStatus |= 0x20; } if (living.DebuffCategory[(int)eProperty.SpellRange] != 0 || living.DebuffCategory[(int)eProperty.ArcheryRange] != 0) { playerStatus |= 0x40; } pak.WriteByte(playerStatus); // 0x00 = Normal , 0x01 = Dead , 0x02 = Mezzed , 0x04 = Diseased , // 0x08 = Poisoned , 0x10 = Link Dead , 0x20 = In Another Region, 0x40 - NS if (updateIcons) { pak.WriteByte((byte)(0x80 | living.GroupIndex)); lock (living.EffectList) { byte i = 0; foreach (IGameEffect effect in living.EffectList) { if (effect is GameSpellEffect) { i++; } } pak.WriteByte(i); foreach (IGameEffect effect in living.EffectList) { if (effect is GameSpellEffect) { pak.WriteByte(0); pak.WriteShort(effect.Icon); } } } } WriteGroupMemberMapUpdate(pak, living); } else { pak.WriteInt(0x20); if (updateIcons) { pak.WriteByte((byte)(0x80 | living.GroupIndex)); pak.WriteByte(0); } } }