func HandshakeResponse(v int) (p *net.Packet) {
	return &net.Packet{FrameBuffer: []byte{byte(v)}}
}
HandshakeResponse Builds a bare net with the login response code.
package world
import (
	"strconv"
	"github.com/spkaeros/rscgo/pkg/definitions"
	"github.com/spkaeros/rscgo/pkg/game/entity"
	"github.com/spkaeros/rscgo/pkg/game/net"
	"github.com/spkaeros/rscgo/pkg/rand"
	"github.com/spkaeros/rscgo/pkg/strutil"
	"github.com/spkaeros/rscgo/pkg/log"
)
func FriendList(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(71)
	p.AddUint8(byte(player.FriendList.Size()))
	for s := range player.FriendList.EntrySet() {
		hash := strutil.Base37.Encode(s)
		p.AddUint64(hash)
		p1, ok := Players.FindHash(hash)
		if p1 != nil && ok && (p1.FriendList.Contains(player.Username()) || !p1.FriendBlocked()) {
			p.AddUint8(0xFF)
		} else {
			p.AddUint8(0)
		}
	}
	return p
}
func PrivateMessage(hash uint64, msg string) (p *net.Packet) {
	p = net.NewEmptyPacket(120)
	p.AddUint64(hash)
	p.AddUint32(rand.Rng.Uint32())  
	for _, c := range []byte(strutil.ChatFilter.Format(msg)) {
		p.AddUint8(c)
	}
	return p
}
func IgnoreList(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(109)
	p.AddUint8(byte(len(player.IgnoreList)))
	for _, hash := range player.IgnoreList {
		p.AddUint64(hash)
	}
	return p
}
func FriendUpdate(hash uint64, online bool) (p *net.Packet) {
	p = net.NewEmptyPacket(149)
	p.AddUint64(hash)
	if online {
		p.AddUint8(0xFF)
	} else {
		p.AddUint8(0)
	}
	return
}
func NpcEvents(player *Player) (p *net.Packet) {
	events, ok := player.VarChecked(npcEvents).([]interface{})
	p = net.NewEmptyPacket(104)
	eventCount := uint16(len(events))
	if eventCount <= 0 {
		return nil
	}
	p.AddUint16(eventCount)
	if ok && eventCount > 0 {
		var newList []interface{}
		for _, e := range events {
			switch e.(type) {
			case HitSplat:
				splat := e.(HitSplat)
				if AsNpc(splat.Owner) != nil {
					p.AddUint16(uint16(splat.Owner.ServerIndex()))
					p.AddUint8(2)
					p.AddUint8(uint8(splat.Damage))
					p.AddUint8(uint8(splat.Owner.Skills().Current(entity.StatHits)))
					p.AddUint8(uint8(splat.Owner.Skills().Maximum(entity.StatHits)))
				}
			case ChatMessage:
				msg := e.(ChatMessage)
				if msg.Owner.IsNpc() {
					p.AddUint16(uint16(msg.Owner.ServerIndex()))
					p.AddUint8(1)
					p.AddUint16(uint16(msg.Target.ServerIndex()))
					p.AddEncryptedString(msg.string)  
				}
			default:
				log.Debugf("Unknown NPC event found in queue: {var event %T = %v\n}", e, e)
				continue
			}
		}
		player.SetVar(npcEvents, newList)
	}
	return
}
var ShopClose = net.NewEmptyPacket(137)
func ShopOpen(shop *Shop) (p *net.Packet) {
	p = net.NewEmptyPacket(101)
	p.AddUint8(uint8(shop.Inventory.Size()))
	p.AddBoolean(shop.BuysUnstocked)
	p.AddUint8(uint8(shop.BasePurchasePercent))
	p.AddUint8(uint8(shop.BaseSalePercent))
	shop.Inventory.Range(func(item *Item) bool {
		p.AddUint16(uint16(item.ID))
		p.AddUint16(uint16(item.Amount))
		p.AddUint8(uint8(shop.DeltaPercentMod(item)))
		return false
	})
	return p
}
func SleepWord(player *Player) (p *net.Packet) {
	return net.NewEmptyPacket(117)
}
func SleepFatigue(player *Player) (p *net.Packet) {
	return net.NewEmptyPacket(244).AddUint16(uint16(player.VarInt("sleepFatigue", 0)))
}
var SleepClose = net.NewEmptyPacket(84)
var SleepWrong = net.NewEmptyPacket(194)
func PrivacySettings(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(51)
	p.AddBoolean(player.ChatBlocked())
	p.AddBoolean(player.FriendBlocked())
	p.AddBoolean(player.TradeBlocked())
	p.AddBoolean(player.DuelBlocked())
	return
}
func OptionMenuOpen(questions ...string) (p *net.Packet) {
	p = net.NewEmptyPacket(245)
	p.AddUint8(uint8(len(questions)))
	for _, question := range questions {
		p.AddFramedString(question)
	}
	return p
}
var OptionMenuClose = net.NewEmptyPacket(252)
func NPCPositions(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(79)
	p.AddBitmask(player.LocalNPCs.Size(), 8)
	var removed = []*NPC{}
	changed := 0
	player.LocalNPCs.RangeNpcs(func(n *NPC) bool {
		changed++
		n.RLock()
		mask := n.SyncMask
		if !player.Near(n, player.ViewRadius()-1) || mask&SyncRemoved == SyncRemoved || n.VarBool("removed", false) {
			p.AddBitmask(0xF, 4)
			removed = append(removed, n)
		} else if mask&SyncMoved == SyncMoved {
			p.AddBitmask(2, 2)
			p.AddBitmask(n.Direction(), 3)
		} else if mask&SyncSprite == SyncSprite {
			p.AddBitmask(3, 2)
			p.AddBitmask(n.Direction(), 4)
		} else {
			p.AddBitmask(0, 1)
			changed--
		}
		n.RUnlock()
		return false
	})
	for _, n := range removed {
		if player.LocalNPCs.Contains(n) {
		player.LocalNPCs.Remove(n)
		}
	}
	newCount := 0
	player.NewNPCs().RangeNpcs(func(n *NPC) bool {
		if player.LocalNPCs.Size() >= 255 {
			return true
		}
		if newCount >= 25 {
			if player.ViewRadius() > 1 {
				player.Dec("viewRadius", 1)
			}
			return true
		}
		if player.ViewRadius() < 15 {
			player.Inc("viewRadius", 1)
		}
		newCount++
		p.AddBitmask(n.ServerIndex(), 12)
		p.AddSignedBits(player.TheirDeltaX(n), 5)
		p.AddSignedBits(player.TheirDeltaY(n), 5)
		p.AddBitmask(n.Direction(), 4)
		p.AddBitmask(n.ID, 10)
		player.LocalNPCs.Add(n)
		return false
	})
	if updates := newCount + changed; updates <= 0 {
		return nil
	}
	return
}
func PrayerStatus(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(206)
	for i := 0; i < len(player.Mob.Prayers); i++ {
		p.AddBoolean(player.PrayerActivated(i))
	}
	return p
}
func QuestStatus(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(5)
	for i := 0; i < 50; i++ {
		p.AddBoolean(player.VarBool("quest"+strconv.Itoa(i), false))
	}
	return p
}
func PlayerPositions(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(191)
	p.AddBitmask(player.X(), 11)
	p.AddBitmask(player.Y(), 13)
	p.AddBitmask(player.Direction(), 4)
	updates := player.LocalPlayers.Size()
	p.AddBitmask(updates, 8)
	changed := 0
	var removed = []entity.MobileEntity{}
	if updates > 0 {
		player.LocalPlayers.RangePlayers(func(p1 *Player) bool {
			changed++
			p1.RLock()
			mask := p1.SyncMask
			if !player.Near(p1, player.ViewRadius()) || mask&SyncRemoved == SyncRemoved {
				p.AddBitmask(0xF, 4)
				removed = append(removed, p1)
			} else if mask&SyncMoved == SyncMoved {
				p.AddBitmask(2, 2)
				p.AddBitmask(p1.Direction(), 3)
			} else if mask&SyncSprite == SyncSprite {
				p.AddBitmask(3, 2)
				p.AddBitmask(p1.Direction(), 4)
			} else {
				p.AddBitmask(0, 1)
				changed--
			}
			p1.RUnlock()
			return false
		})
		for _, p1 := range removed {
			player.LocalPlayers.Remove(p1)
		}
	}
	newPlayerCount := 0
	player.NewPlayers().RangePlayers(func(p1 *Player) bool {
		if player.LocalPlayers.Size() >= 255 {
			return true
		}
		if newPlayerCount >= 50 {
			if player.ViewRadius() > 1 {
				player.Dec("viewRadius", 1)
			}
			return true
		}
		for player.ViewRadius() < 15 {
			player.Inc("viewRadius", 1)
		}
		newPlayerCount++
		player.LocalPlayers.Add(p1)
		p.AddBitmask(p1.ServerIndex(), 11)
		p.AddSignedBits(player.TheirDeltaX(p1), 5)
		p.AddSignedBits(player.TheirDeltaY(p1), 5)
		p.AddBitmask(p1.Direction(), 4)
		if ticket, hasPlayerTicket := player.Var(strconv.Itoa(p1.ServerIndex()) + "=" + strconv.Itoa(p1.AppearanceTicket())); !hasPlayerTicket || ticket != p1.AppearanceTicket() || p1.SyncMask&(SyncRemoved|SyncAppearance) != 0 {
			player.enqueue(playerEvents, map[string]int {"index": int(p1.ServerIndex()), "ticket": int(p1.AppearanceTicket())})
		}
		return false
	})
	return
}
func PlayerAppearances(ourPlayer *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(234)
	list, ok := ourPlayer.VarChecked(playerEvents).([]interface{})
	if !ok || len(list) == 0 {
		return nil
	}
	p.AddUint16(uint16(len(list)))
	if ok {
		for _, e := range list {
			switch e.(type) {
			case ItemBubble:
				bubble := e.(ItemBubble)
				p.AddUint16(uint16(bubble.Owner.ServerIndex()))  
				p.AddUint8(0)                                    
				p.AddUint16(uint16(bubble.Item))                 
			case ChatMessage:
				msg := e.(ChatMessage)
				p.AddUint16(uint16(msg.Owner.ServerIndex()))  
				if msg.Target == nil {
					p.AddUint8(1)
					p.AddUint8(uint8(ourPlayer.Rank()))
					if len(msg.string) > 84 {
						msg.string = msg.string[:84]
					}
					p.AddEncryptedString(msg.string)
				} else {
					p.AddUint8(6)
					p.AddEncryptedString(msg.string)
				}
			case HitSplat:
				splat := e.(HitSplat)
				p.AddUint16(uint16(splat.Owner.ServerIndex()))                    
				p.AddUint8(2)                                                     
				p.AddUint8(uint8(splat.Damage))                                   
				p.AddUint8(uint8(splat.Owner.Skills().Current(entity.StatHits)))  
				p.AddUint8(uint8(splat.Owner.Skills().Maximum(entity.StatHits)))  
			case Projectile:
				shot := e.(Projectile)
				p.AddUint16(uint16(shot.Owner.ServerIndex()))  
				if shot.Target.IsNpc() {
					p.AddUint8(3)
				} else if shot.Target.IsPlayer() {
					p.AddUint8(4)
				} else {
					p.Rewind(2)
					continue
				}
				p.AddUint16(uint16(shot.Kind))                  
				p.AddUint16(uint16(shot.Target.ServerIndex()))  
			case map[string]int:
				ticket := e.(map[string]int)
				idx, ok := ticket["index"]
				if !ok {
					continue
				}
				ticketID, ok := ticket["ticket"]
				if !ok {
					continue
				}
				p1, ok := Players.FindIndex(int(idx))
				if p1.AppearanceTicket() != int(ticketID) || !ok {
					continue
				}
				ourPlayer.SetVar("ticket" + strconv.Itoa(p1.ServerIndex()), ticketID)
				p.AddUint16(uint16(p1.ServerIndex()))  
				p.AddUint8(5)                              
				p.AddUint16(uint16(ticketID))  
				p.AddFramedString(p1.Username())
				p.AddFramedString(p1.Username())
				sprites := p1.Equips()
				p.AddUint8(uint8(len(sprites)))  
				for i := 0; i < len(sprites); i += 1 {
					animID := uint8(sprites[i] & 0xFF)
					if animID < 0 || animID >= 229 {
						p.AddUint8(0)
					} else {
						p.AddUint8(animID)
					}
				}
				p.AddUint8(uint8(p1.Appearance.HeadColor))
				p.AddUint8(uint8(p1.Appearance.BodyColor))
				p.AddUint8(uint8(p1.Appearance.LegsColor))
				p.AddUint8(uint8(p1.Appearance.SkinColor))
				p.AddUint8(uint8(p1.Skills().CombatLevel()))
				p.AddBoolean(p1.Skulled())
			default:
				log.Debugf("Unknown player event found in queue: {var event %T = %v\n}", e, e)
				continue
			}
		}
		ourPlayer.UnsetVar(playerEvents)
	}
	return
}
func ClearDistantChunks(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(211)
	ichunks, ok := player.Var("distantChunks")
	if !ok {
		return nil
	}
	chunks := ichunks.([]entity.Location)
	if len(chunks) <= 0 {
		return nil
	}
	for _, chunk := range chunks {
		p.AddUint16(uint16(chunk.X() - player.X()))
		p.AddUint16(uint16(chunk.Y() - player.Y()))
	}
	player.UnsetVar("distantChunks")
	return
}
func ObjectLocations(player *Player) (p *net.Packet) {
	changed := 0
	p = net.NewEmptyPacket(48)
	var removed []entity.Entity
	player.LocalObjects.Range(func(e entity.Entity) {
		if o, ok := e.(*Object); ok {
			if o.Boundary {
				return
			}
			if !player.Near(o, player.ViewRadius()<<1) || GetObject(o.X(), o.Y()) != o {
				if !player.Near(o, player.ViewRadius()*3) {
					if chunks, ok := player.Var("distantChunks"); ok {
						player.SetVar("distantChunks", append(chunks.([]entity.Location), o.Clone()))
					} else {
						player.SetVar("distantChunks", []entity.Location{o.Clone()})
					}
				} else {
					p.AddUint16(60000)
					p.AddUint8(byte(o.X() - player.X()))
					p.AddUint8(byte(o.Y() - player.Y()))
					changed++
				}
				removed = append(removed, o)
			}
		}
		return
	})
	for _, r := range removed {
		player.LocalObjects.Remove(r)
	}
	for _, o := range player.NewObjects() {
		if o.Boundary {
			continue
		}
		p.AddUint16(uint16(o.ID))
		p.AddUint8(byte(o.X() - player.X()))
		p.AddUint8(byte(o.Y() - player.Y()))
		player.LocalObjects.Add(o)
		changed++
	}
	if changed == 0 {
		return nil
	}
	return
}
func BoundaryLocations(player *Player) (p *net.Packet) {
	changed := 0
	p = net.NewEmptyPacket(91)
	var removed []entity.Entity
	player.LocalObjects.Range(func(o entity.Entity) {
		if o, ok := o.(*Object); ok {
			if !o.Boundary {
				return
			}
			if !player.Near(o, player.ViewRadius()+5) {
				removed = append(removed, o)
				if !player.Near(o, (player.ViewRadius()+5)*3) {
					if !player.Near(o, player.ViewRadius()*9) {
						if chunks, ok := player.Var("distantChunks"); ok {
							player.SetVar("distantChunks", append(chunks.([]entity.Location), o.Clone()))
						} else {
							player.SetVar("distantChunks", []entity.Location{o.Clone()})
						}
					} else {
						p.AddUint8(0xFF)
						p.AddUint8(uint8(o.X()))
						p.AddUint8(uint8(o.Y()))
						changed++
					}
				}
			} else if o1 := GetObject(o.X(), o.Y()); o1 != o {
				changed++
				if o1 == nil {
					p.AddUint16(0x10)
					p.AddUint8(uint8(player.TheirDeltaX(o)))
					p.AddUint8(uint8(player.TheirDeltaY(o)))
					p.AddUint8(o.Direction)
					return
				}
				p.AddUint16(uint16(o1.ID))
				p.AddUint8(uint8(player.TheirDeltaX(o1)))
				p.AddUint8(uint8(player.TheirDeltaY(o1)))
				p.AddUint8(o.Direction)
			}
		}
	})
	for _, o1 := range removed {
		player.LocalObjects.Remove(o1)
	}
	for _, o := range player.NewObjects() {
		if !o.Boundary {
			continue
		}
		p.AddUint16(uint16(o.ID))
		p.AddUint8(byte(player.TheirDeltaX(o)))
		p.AddUint8(byte(player.TheirDeltaY(o)))
		p.AddUint8(o.Direction)
		player.LocalObjects.Add(o)
		changed++
	}
	if changed <= 0 {
		return nil
	}
	return
}
func ItemLocations(player *Player) (p *net.Packet) {
	changed := 0
	p = net.NewEmptyPacket(99)
	var removed []entity.Entity
	player.LocalItems.Range(func (i entity.Entity) {
		if i, ok := i.(*GroundItem); ok {
			x, y := i.X(), i.Y()
			if !player.Near(i, player.ViewRadius()*3) {
				if !player.Near(i, player.ViewRadius()*9) {
					if chunks, ok := player.Var("distantChunks"); ok {
						player.SetVar("distantChunks", append(chunks.([]entity.Location), i.Location.Clone()))
					} else {
						player.SetVar("distantChunks", []entity.Location{i.Location.Clone()})
					}
				} else {
					p.AddUint8(255)
					p.AddUint8(byte(player.TheirDeltaX(i)))
					p.AddUint8(byte(player.TheirDeltaY(i)))
					changed++
				}
				removed = append(removed, i)
			} else if !i.VisibleTo(player) || !Region(x, y).Items.Contains(i) {
				p.AddUint16(uint16(i.ID | (1<<15)))  
				p.AddUint8(byte(player.TheirDeltaX(i)))
				p.AddUint8(byte(player.TheirDeltaY(i)))
				changed++
				removed = append(removed, i)
			}
		}
	})
	for _, i := range removed {
		player.LocalItems.Remove(i)
	}
	for _, i := range player.NewItems() {
		p.AddUint16(uint16(i.ID))
		p.AddUint8(byte(player.TheirDeltaX(i)))
		p.AddUint8(byte(player.TheirDeltaY(i)))
		player.LocalItems.Add(i)
		changed++
	}
	if changed == 0 {
		return nil
	}
	return
}
var OpenChangeAppearance = net.NewEmptyPacket(59)
func InventoryItems(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(53)
	p.AddUint8(uint8(player.Inventory.Size()))
	player.Inventory.Range(func(item *Item) bool {
		if item.Worn {
			p.AddUint16(uint16(item.ID) | 1<<15)
		} else {
			p.AddUint16(uint16(item.ID))
		}
		if definitions.Items[item.ID].Stackable {
			p.AddSmart1632(item.Amount)
		}
		return true
	})
	return
}
func FightMode(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(132)
	p.AddUint8(byte(player.FightMode()))
	return p
}
func Fatigue(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(114)
	p.AddUint16(uint16(player.Fatigue() / 100))
	return p
}
func ClientSettings(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(240)
	p.AddBoolean(player.GetClientSetting(0))
	p.AddBoolean(player.GetClientSetting(2))
	p.AddBoolean(player.GetClientSetting(3))
	return
}
func PlayerStats(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(156)
	for i := 0; i < 18; i++ {
		p.AddUint8(uint8(player.Skills().Current(i)))
	}
	for i := 0; i < 18; i++ {
		p.AddUint8(uint8(player.Skills().Maximum(i)))
	}
	for i := 0; i < 18; i++ {
		p.AddUint32(uint32(player.Skills().Experience(i)))
	}
	return p
}
func PlayerExperience(player *Player, idx int) (p *net.Packet) {
	p = net.NewEmptyPacket(33)
	p.AddUint8(byte(idx))
	p.AddUint32(uint32(player.Skills().Experience(idx)))
	return p
}
func PlayerStat(player *Player, idx int) (p *net.Packet) {
	p = net.NewEmptyPacket(159)
	p.AddUint8(byte(idx))
	p.AddUint8(byte(player.Skills().Current(idx)))
	p.AddUint8(byte(player.Skills().Maximum(idx)))
	p.AddUint32(uint32(player.Skills().Experience(idx)))
	return p
}
func EquipmentStats(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(153)
	p.AddUint8(uint8(player.ArmourPoints()))
	p.AddUint8(uint8(player.AimPoints()))
	p.AddUint8(uint8(player.PowerPoints()))
	p.AddUint8(uint8(player.MagicPoints()))
	p.AddUint8(uint8(player.PrayerPoints()))
	p.AddUint8(uint8(player.RangedPoints()))
	p.AddUint8(uint8(player.VarInt("questPoints", 0xFF)))
	return
}
var BankClose = net.NewEmptyPacket(203)
func BankOpen(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(42)
	p.AddUint8(uint8(player.bank.Size()))
	p.AddUint8(uint8(player.bank.Capacity))
	player.bank.Range(func(item *Item) bool {
		p.AddUint16(uint16(item.ID))
		p.AddSmart1632(item.Amount)
		return true
	})
	return p
}
func BankUpdateItem(index, id, amount int) (p *net.Packet) {
	p = net.NewEmptyPacket(249)
	p.AddUint8(uint8(index))
	p.AddUint16(uint16(id))
	p.AddSmart1632(amount)
	return p
}
func DuelOpen(targetIndex int) (p *net.Packet) {
	return net.NewEmptyPacket(176).AddUint16(uint16(targetIndex))
}
func DuelUpdate(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(6)
	p.AddUint8(uint8(player.DuelOffer.Size()))
	player.DuelOffer.Range(func(item *Item) bool {
		p.AddUint16(uint16(item.ID))
		p.AddUint32(uint32(item.Amount))
		return true
	})
	return
}
func DuelTargetAccept(accepted bool) (p *net.Packet) {
	return net.NewEmptyPacket(253).AddBoolean(accepted)
}
func DuelOptions(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(30)
	p.AddBoolean(!player.VarBool("duelCanRetreat", true))
	p.AddBoolean(!player.VarBool("duelCanMagic", true))
	p.AddBoolean(!player.VarBool("duelCanPrayer", true))
	p.AddBoolean(!player.VarBool("duelCanEquip", true))
	return p
}
func DuelConfirmationOpen(player, other *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(172)
	p.AddUint64(other.UsernameHash())
	p.AddUint8(uint8(other.DuelOffer.Size()))
	other.DuelOffer.Range(func(item *Item) bool {
		p.AddUint16(uint16(item.ID))
		p.AddUint32(uint32(item.Amount))
		return true
	})
	p.AddUint8(uint8(player.DuelOffer.Size()))
	player.DuelOffer.Range(func(item *Item) bool {
		p.AddUint16(uint16(item.ID))
		p.AddUint32(uint32(item.Amount))
		return true
	})
	p.AddBoolean(!player.VarBool("duelCanRetreat", true))
	p.AddBoolean(!player.VarBool("duelCanMagic", true))
	p.AddBoolean(!player.VarBool("duelCanPrayer", true))
	p.AddBoolean(!player.VarBool("duelCanEquip", true))
	return
}
var DuelClose = net.NewEmptyPacket(225)
var TradeClose = net.NewEmptyPacket(128)
func TradeOpen(targetIndex int) (p *net.Packet) {
	return net.NewEmptyPacket(92).AddUint16(uint16(targetIndex))
}
func TradeUpdate(player *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(97)
	p.AddUint8(uint8(player.TradeOffer.Size()))
	player.TradeOffer.Range(func(item *Item) bool {
		p.AddUint16(uint16(item.ID))
		p.AddUint32(uint32(item.Amount))
		return true
	})
	return
}
func TradeTargetAccept(accepted bool) (p *net.Packet) {
	return net.NewEmptyPacket(162).AddBoolean(accepted)
}
func TradeAccept(accepted bool) (p *net.Packet) {
	return net.NewEmptyPacket(15).AddBoolean(accepted)
}
func TradeConfirmationOpen(player, other *Player) (p *net.Packet) {
	p = net.NewEmptyPacket(20)
	p.AddUint64(other.UsernameHash())
	p.AddUint8(uint8(other.TradeOffer.Size()))
	other.TradeOffer.Range(func(item *Item) bool {
		p.AddUint16(uint16(item.ID))
		p.AddUint32(uint32(item.Amount))
		return true
	})
	p.AddUint8(uint8(player.TradeOffer.Size()))
	player.TradeOffer.Range(func(item *Item) bool {
		p.AddUint16(uint16(item.ID))
		p.AddUint32(uint32(item.Amount))
		return true
	})
	return p
}
var Logout = net.NewEmptyPacket(4)
var WelcomeMessage = ServerMessage("Welcome to RuneScape")
var Death = net.NewEmptyPacket(83)
var ResponsePong = net.NewEmptyPacket(9)
var CannotLogout = net.NewEmptyPacket(183)
var DefaultActionMessage = ServerMessage("Nothing interesting happens.")
func ServerMessage(msg string) (p *net.Packet) {
	p = net.NewEmptyPacket(131)
	p.AddUint8(0)  
	p.AddUint8(0)  
	p.AddFramedString(msg)
	return
}
func TeleBubble(offsetX, offsetY int) (p *net.Packet) {
	p = net.NewEmptyPacket(36)
	p.AddUint8(0)  
	p.AddUint8(uint8(offsetX))
	p.AddUint8(uint8(offsetY))
	return
}
func SystemUpdate(t int64) (p *net.Packet) {
	p = net.NewEmptyPacket(52)
	p.AddUint16(uint16(t / 640))
	return p
}
func Sound(name string) (p *net.Packet) {
	p = net.NewEmptyPacket(204)
	p.AddFramedString(name)
	return
}
func LoginBox(inactiveDays int, lastIP string) (p *net.Packet) {
	p = net.NewEmptyPacket(182)
	i, err := strconv.Atoi(strutil.IPToInteger(lastIP).String())
	if err != nil {
		p.AddUint32(127<<24 | 1)
	} else {
		p.AddUint32(uint32(i))  
	}
	p.AddUint16(uint16(inactiveDays))  
	p.AddUint8(201)  
	p.AddUint16(0)  
	return p
}
func BigInformationBox(msg string) (p *net.Packet) {
	return net.NewEmptyPacket(222).AddFramedString(msg)
}
var AppearanceKeepalive = net.NewEmptyPacket(213)
func InformationBox(msg string) (p *net.Packet) {
	return net.NewEmptyPacket(89).AddFramedString(msg)
}