Some work on mail/auction.

This commit is contained in:
tomrus88 2010-03-25 13:19:21 +03:00
parent 4234c685b8
commit 50c96da112
8 changed files with 83 additions and 66 deletions

1
sql/333/1_mail.sql Normal file
View file

@ -0,0 +1 @@
alter table `characters`.`mail` add column `body` longtext CHARSET utf8 COLLATE utf8_general_ci NULL after `subject`;

View file

@ -120,12 +120,12 @@ void WorldSession::SendAuctionOutbiddedMail(AuctionEntry *auction, uint32 newPri
if(oldBidder || oldBidder_accId)
{
std::ostringstream msgAuctionOutbiddedSubject;
msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED;
msgAuctionOutbiddedSubject << auction->item_template << ":0:" << AUCTION_OUTBIDDED << ":0:0";
if (oldBidder)
oldBidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, _player->GetGUID(), newPrice, auction->GetAuctionOutBid(), auction->item_template);
MailDraft(msgAuctionOutbiddedSubject.str())
MailDraft(msgAuctionOutbiddedSubject.str(), "", 0)
.AddMoney(auction->bid)
.SendMailTo(MailReceiver(oldBidder, auction->bidder), auction);
}
@ -145,9 +145,9 @@ void WorldSession::SendAuctionCancelledToBidderMail( AuctionEntry* auction )
if(bidder || bidder_accId)
{
std::ostringstream msgAuctionCancelledSubject;
msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER;
msgAuctionCancelledSubject << auction->item_template << ":0:" << AUCTION_CANCELLED_TO_BIDDER << ":0:0";
MailDraft(msgAuctionCancelledSubject.str())
MailDraft(msgAuctionCancelledSubject.str(), "", 0)
.AddMoney(auction->bid)
.SendMailTo(MailReceiver(bidder, auction->bidder), auction);
}
@ -161,7 +161,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
recv_data >> auctioneer;
recv_data.read_skip<uint32>(); // const 1?
recv_data >> item;
recv_data.read_skip<uint32>(); // unk 3.2.2, const 1?
recv_data.read_skip<uint32>(); // stack size
recv_data >> bid;
recv_data >> buyout;
recv_data >> etime;
@ -204,14 +204,14 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data )
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
Item *it = pl->GetItemByGuid( item );
//do not allow to sell already auctioned items
// do not allow to sell already auctioned items
if(sAuctionMgr.GetAItem(GUID_LOPART(item)))
{
sLog.outError("AuctionError, player %s is sending item id: %u, but item is already in another auction", pl->GetName(), GUID_LOPART(item));
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR);
return;
}
// prevent sending bag with items (cheat: can be placed in bag after adding equiped empty bag to auction)
// prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to auction)
if(!it)
{
SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND);
@ -450,10 +450,10 @@ void WorldSession::HandleAuctionRemoveItem( WorldPacket & recv_data )
}
// Return the item by mail
std::ostringstream msgAuctionCanceledOwner;
msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED;
msgAuctionCanceledOwner << auction->item_template << ":0:" << AUCTION_CANCELED << ":0:0";
// item will deleted or added to received mail list
MailDraft(msgAuctionCanceledOwner.str())
MailDraft(msgAuctionCanceledOwner.str(), "", 0)
.AddItem(pItem)
.SendMailTo(pl, auction);
}

View file

@ -256,7 +256,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction )
if(owner || owner_accId)
{
std::ostringstream subject;
subject << auction->item_template << ":0:" << AUCTION_EXPIRED;
subject << auction->item_template << ":0:" << AUCTION_EXPIRED << ":0:0";
if ( owner )
owner->GetSession()->SendAuctionOwnerNotification( auction );
@ -264,7 +264,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail( AuctionEntry * auction )
RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !!
// will delete item or place to receiver mail list
MailDraft(subject.str())
MailDraft(subject.str(), "", 0)
.AddItem(pItem)
.SendMailTo(MailReceiver(owner,auction->owner), auction);
}

View file

@ -241,7 +241,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data )
bool needItemDelay = false;
MailDraft draft(subject, itemTextId);
MailDraft draft(subject, body, itemTextId);
if (items_count > 0 || money > 0)
{
@ -400,7 +400,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data )
// send back only to players and simple drop for other cases
if (m->messageType == MAIL_NORMAL)
{
MailDraft draft(m->subject, m->itemTextId);
MailDraft draft(m->subject, m->body, m->itemTextId);
if (m->mailTemplateId)
draft = MailDraft(m->mailTemplateId,false); // items already included
@ -499,7 +499,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket & recv_data )
// check player existence
if(receive || sender_accId)
{
MailDraft(m->subject)
MailDraft(m->subject, "", 0)
.AddMoney(m->COD)
.SendMailTo(MailReceiver(receive,m->sender),MailSender(MAIL_NORMAL,m->receiver), MAIL_CHECK_MASK_COD_PAYMENT);
}
@ -598,7 +598,7 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data )
uint8 item_count = (*itr)->items.size(); // max count is MAX_MAIL_ITEMS (12)
size_t next_mail_size = 2+4+1+((*itr)->messageType == MAIL_NORMAL ? 8 : 4)+4*8+((*itr)->subject.size()+1)+1+item_count*(1+4+4+7*3*4+4+4+4+4+4+4+1);
size_t next_mail_size = 2+4+1+((*itr)->messageType == MAIL_NORMAL ? 8 : 4)+4*8+((*itr)->subject.size()+1)+((*itr)->body.size()+1)+1+item_count*(1+4+4+7*3*4+4+4+4+4+4+4+1);
if(data.wpos()+next_mail_size > maxPacketSize)
{
@ -634,14 +634,14 @@ void WorldSession::HandleGetMailList(WorldPacket & recv_data )
}
data << uint32((*itr)->COD); // COD
data << uint32((*itr)->itemTextId); // sure about this
data << uint32(0); // unknown
data << uint32((*itr)->itemTextId); // probably changed in 3.3.3
data << uint32((*itr)->stationery); // stationery (Stationery.dbc)
data << uint32((*itr)->money); // Gold
data << uint32(show_flags); // unknown, 0x4 - auction, 0x10 - normal
data << float(((*itr)->expire_time-time(NULL))/DAY);// Time
data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc)
data << (*itr)->subject; // Subject string - once 00, when mail type = 3
data << (*itr)->subject; // Subject string - once 00, when mail type = 3, max 256
data << (*itr)->body; // message? max 8000
data << uint8(item_count); // client limit is 0x10
@ -710,7 +710,7 @@ void WorldSession::HandleItemTextQuery(WorldPacket & recv_data )
sLog.outDebug("CMSG_ITEM_TEXT_QUERY itemguid: %u, mailId: %u, unk: %u", itemTextId, mailId, unk);
WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, (4+10));// guess size
data << itemTextId;
data << uint32(itemTextId);
data << sObjectMgr.GetItemText( itemTextId );
SendPacket(&data);
}
@ -729,7 +729,6 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket & recv_data )
recv_data >> mailbox;
recv_data >> mailId;
recv_data.read_skip<uint32>(); // mailTemplateId, non need, Mail store own 100% correct value anyway
if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX))
return;
@ -909,12 +908,12 @@ MailReceiver::MailReceiver( Player* receiver,uint32 receiver_lowguid ) : m_recei
}
/**
* Creates a new MailDraft object using subject and contect texts.
* Creates a new MailDraft object using subject and content texts.
*
* @param subject The subject of the mail.
* @param itemText The text of the body of the mail.
*/
MailDraft::MailDraft( std::string subject, std::string text ) : m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject),
MailDraft::MailDraft( std::string subject, std::string text ) : m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_body(text),
m_bodyId(!text.empty() ? sObjectMgr.CreateItemText(text) : 0), m_money(0), m_COD(0)
{
@ -948,9 +947,9 @@ void MailDraft::prepareItems(Player* receiver)
uint32 max_slot = mailLoot.GetMaxSlotInLootFor(receiver);
for(uint32 i = 0; m_items.size() < MAX_MAIL_ITEMS && i < max_slot; ++i)
{
if (LootItem* lootitem = mailLoot.LootItemInSlot(i,receiver))
if (LootItem* lootitem = mailLoot.LootItemInSlot(i, receiver))
{
if (Item* item = Item::CreateItem(lootitem->itemid,lootitem->count,receiver))
if (Item* item = Item::CreateItem(lootitem->itemid, lootitem->count, receiver))
{
item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted
AddItem(item);
@ -981,7 +980,7 @@ void MailDraft::deleteIncludedItems( bool inDB /**= false*/ )
* Returns a mail to its sender.
* @param sender_acc The id of the account of the sender.
* @param sender_guid The low part of the GUID of the sender.
* @param receiver_guid The low part of the GUID of the reciever.
* @param receiver_guid The low part of the GUID of the receiver.
*/
void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid )
{
@ -1058,12 +1057,16 @@ void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sende
// Add to DB
std::string safe_subject = GetSubject();
CharacterDatabase.BeginTransaction();
CharacterDatabase.escape_string(safe_subject);
CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,itemTextId,has_items,expire_time,deliver_time,money,cod,checked) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%u', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')",
mailId, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGUIDLow(), safe_subject.c_str(), GetBodyId(), (m_items.empty() ? 0 : 1), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked);
std::string safe_body = GetBody();
CharacterDatabase.BeginTransaction();
CharacterDatabase.escape_string(safe_body);
CharacterDatabase.PExecute("INSERT INTO mail (id,messageType,stationery,mailTemplateId,sender,receiver,subject,body,itemTextId,has_items,expire_time,deliver_time,money,cod,checked) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%s', '%s', '%u', '%u', '" UI64FMTD "','" UI64FMTD "', '%u', '%u', '%d')",
mailId, sender.GetMailMessageType(), sender.GetStationery(), GetMailTemplateId(), sender.GetSenderId(), receiver.GetPlayerGUIDLow(), safe_subject.c_str(), safe_body.c_str(), GetBodyId(), (m_items.empty() ? 0 : 1), (uint64)expire_time, (uint64)deliver_time, m_money, m_COD, checked);
for(MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter)
{
@ -1081,6 +1084,7 @@ void MailDraft::SendMailTo(MailReceiver const& receiver, MailSender const& sende
m->messageID = mailId;
m->mailTemplateId = GetMailTemplateId();
m->subject = GetSubject();
m->body = GetBody();
m->itemTextId = GetBodyId();
m->money = GetMoney();
m->COD = GetCOD();

View file

@ -73,8 +73,8 @@ enum MailCheckMask
*/
enum MailStationery
{
MAIL_STATIONERY_UNKNOWN = 1,
MAIL_STATIONERY_NORMAL = 41,
MAIL_STATIONERY_TEST = 1,
MAIL_STATIONERY_DEFAULT = 41,
MAIL_STATIONERY_GM = 61,
MAIL_STATIONERY_AUCTION = 62,
MAIL_STATIONERY_VAL = 64,
@ -118,11 +118,11 @@ class MailSender
* @param stationery The stationary associated with this MailSender.
*
*/
MailSender(MailMessageType messageType, uint32 sender_guidlow_or_entry, MailStationery stationery = MAIL_STATIONERY_NORMAL)
MailSender(MailMessageType messageType, uint32 sender_guidlow_or_entry, MailStationery stationery = MAIL_STATIONERY_DEFAULT)
: m_messageType(messageType), m_senderId(sender_guidlow_or_entry), m_stationery(stationery)
{
}
MailSender(Object* sender, MailStationery stationery = MAIL_STATIONERY_NORMAL);
MailSender(Object* sender, MailStationery stationery = MAIL_STATIONERY_DEFAULT);
MailSender(AuctionEntry* sender);
public: // Accessors
/// The Messagetype of this MailSender.
@ -192,10 +192,10 @@ class MailDraft
* @param subject The subject of the mail.
* @param itemTextId The id of the body of the mail.
*/
MailDraft(std::string subject, uint32 itemTextId = 0)
: m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_bodyId(itemTextId), m_money(0), m_COD(0) {}
MailDraft(std::string subject, std::string body, uint32 itemTextId)
: m_mailTemplateId(0), m_mailTemplateItemsNeed(false), m_subject(subject), m_body(body), m_bodyId(itemTextId), m_money(0), m_COD(0) {}
/**
* Creates a new MailDraft object using subject and contect texts.
* Creates a new MailDraft object using subject and content texts.
*
* @param subject The subject of the mail.
* @param itemText The text of the body of the mail.
@ -206,9 +206,11 @@ class MailDraft
uint16 GetMailTemplateId() const { return m_mailTemplateId; }
/// Returns the subject of this MailDraft.
std::string const& GetSubject() const { return m_subject; }
/// Returns the subject of this MailDraft.
std::string const& GetBody() const { return m_body; }
/// Returns the ID of the text of this MailDraft.
uint32 GetBodyId() const { return m_bodyId; }
/// Returns the ammount of money in this MailDraft.
/// Returns the amount of money in this MailDraft.
uint32 GetMoney() const { return m_money; }
/// Returns the Cost of delivery of this MailDraft.
uint32 GetCOD() const { return m_COD; }
@ -239,6 +241,8 @@ class MailDraft
bool m_mailTemplateItemsNeed;
/// The subject of the MailDraft.
std::string m_subject;
/// The body of the MailDraft.
std::string m_body;
/// The ID of the body of the MailDraft.
uint32 m_bodyId;
/// A map of items in this MailDraft.
@ -276,6 +280,8 @@ struct Mail
uint32 receiver;
/// the subject of the mail
std::string subject;
/// the body of the mail
std::string body;
/// The ID of the itemtext.
uint32 itemTextId;
/// A vector containing Information about the items in this mail.
@ -338,7 +344,7 @@ struct Mail
/*
* Checks whether a mail contains items or not.
* HasItems() checks wether the mail contains items or not.
* HasItems() checks whether the mail contains items or not.
*
* @returns true if the mail contains items, false otherwise.
*

View file

@ -697,7 +697,7 @@ enum Opcodes
CMSG_MEETINGSTONE_CHEAT = 0x294, // not found 3.3
SMSG_MEETINGSTONE_SETQUEUE = 0x295, // string, showed in console
CMSG_MEETINGSTONE_INFO = 0x296, // EVENT_LFG_UPDATE
SMSG_MEETINGSTONE_COMPLETE = 0x297, // EVENT_MAIL_SHOW
SMSG_MEETINGSTONE_COMPLETE = 0x297, // mail open from gossip?, EVENT_MAIL_SHOW
SMSG_MEETINGSTONE_IN_PROGRESS = 0x298, // uint32, some UPDATE_COOLDOWN events
SMSG_MEETINGSTONE_MEMBER_ADDED = 0x299, // uint32, errors: ERR_NOT_IN_GROUP (2,51) and ERR_NOT_IN_RAID (3,39,40)
CMSG_GMTICKETSYSTEM_TOGGLE = 0x29A,
@ -1324,14 +1324,14 @@ enum Opcodes
UMSG_UNKNOWN_1287 = 0x507, // not found
CMSG_UNKNOWN_1288 = 0x508, // lua: SetAllowLowLevelRaid
CMSG_UNKNOWN_1289 = 0x509, // lua: SetAllowLowLevelRaid
SMSG_UNKNOWN_1290 = 0x50A, // camera shake?
SMSG_UNKNOWN_1290 = 0x50A, // uint32 SpellEffectCameraShakes.dbc uint32, camera shake?
SMSG_UNKNOWN_1291 = 0x50B, // some item update packet?
UMSG_UNKNOWN_1292 = 0x50C, // not found
UMSG_UNKNOWN_1293 = 0x50D, // not found - disconnect
SMSG_UNKNOWN_1293 = 0x50D, //
CMSG_UNKNOWN_1294 = 0x50E, // something with networking
UMSG_UNKNOWN_1295 = 0x50F, // not found - disconnect
SMSG_UNKNOWN_1295 = 0x50F, //
CMSG_UNKNOWN_1296 = 0x510, // something with networking
UMSG_UNKNOWN_1297 = 0x511, // not found - crash
SMSG_UNKNOWN_1297 = 0x511, //
CMSG_UNKNOWN_1298 = 0x512, // something with networking
UMSG_UNKNOWN_1299 = 0x513, // not found
SMSG_UNKNOWN_1300 = 0x514, // SMSG

View file

@ -4005,8 +4005,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// remove signs from petitions (also remove petitions if owner);
RemovePetitionsAndSigns(playerguid, 10);
// return back all mails with COD and Item 0 1 2 3 4 5 6 7
QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,messageType,mailTemplateId,sender,subject,itemTextId,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid);
// return back all mails with COD and Item 0 1 2 3 4 5 6 7 8
QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,messageType,mailTemplateId,sender,subject,body,itemTextId,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid);
if(resultMail)
{
do
@ -4018,9 +4018,10 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
uint16 mailTemplateId= fields[2].GetUInt16();
uint32 sender = fields[3].GetUInt32();
std::string subject = fields[4].GetCppString();
uint32 itemTextId = fields[5].GetUInt32();
uint32 money = fields[6].GetUInt32();
bool has_items = fields[7].GetBool();
std::string body = fields[5].GetCppString();
uint32 itemTextId = fields[6].GetUInt32();
uint32 money = fields[7].GetUInt32();
bool has_items = fields[8].GetBool();
//we can return mail now
//so firstly delete the old one
@ -4034,9 +4035,9 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
continue;
}
MailDraft draft(subject, itemTextId);
MailDraft draft(subject, body, itemTextId);
if (mailTemplateId)
draft = MailDraft(mailTemplateId,false); // itesm already included
draft = MailDraft(mailTemplateId, false); // items already included
if(has_items)
{
@ -15637,7 +15638,7 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
// fill mail
MailDraft draft(subject);
MailDraft draft(subject, "There's were problems with equipping item.", 0);
for(int i = 0; !problematicItems.empty() && i < MAX_MAIL_ITEMS; ++i)
{
@ -15700,8 +15701,8 @@ void Player::_LoadMailedItems(Mail *mail)
void Player::_LoadMail()
{
m_mail.clear();
//mails are in right order 0 1 2 3 4 5 6 7 8 9 10 11 12 13
QueryResult *result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,subject,itemTextId,has_items,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId FROM mail WHERE receiver = '%u' ORDER BY id DESC",GetGUIDLow());
//mails are in right order 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
QueryResult *result = CharacterDatabase.PQuery("SELECT id,messageType,sender,receiver,subject,body,itemTextId,has_items,expire_time,deliver_time,money,cod,checked,stationery,mailTemplateId FROM mail WHERE receiver = '%u' ORDER BY id DESC", GetGUIDLow());
if(result)
{
do
@ -15713,15 +15714,16 @@ void Player::_LoadMail()
m->sender = fields[2].GetUInt32();
m->receiver = fields[3].GetUInt32();
m->subject = fields[4].GetCppString();
m->itemTextId = fields[5].GetUInt32();
bool has_items = fields[6].GetBool();
m->expire_time = (time_t)fields[7].GetUInt64();
m->deliver_time = (time_t)fields[8].GetUInt64();
m->money = fields[9].GetUInt32();
m->COD = fields[10].GetUInt32();
m->checked = fields[11].GetUInt32();
m->stationery = fields[12].GetUInt8();
m->mailTemplateId = fields[13].GetInt16();
m->body = fields[5].GetCppString();
m->itemTextId = fields[6].GetUInt32();
bool has_items = fields[7].GetBool();
m->expire_time = (time_t)fields[8].GetUInt64();
m->deliver_time = (time_t)fields[9].GetUInt64();
m->money = fields[10].GetUInt32();
m->COD = fields[11].GetUInt32();
m->checked = fields[12].GetUInt32();
m->stationery = fields[13].GetUInt8();
m->mailTemplateId = fields[14].GetInt16();
if(m->mailTemplateId && !sMailTemplateStore.LookupEntry(m->mailTemplateId))
{
@ -15742,7 +15744,7 @@ void Player::_LoadMail()
void Player::LoadPet()
{
//fixme: the pet should still be loaded if the player is not in world
// fixme: the pet should still be loaded if the player is not in world
// just not added to the map
if(IsInWorld())
{
@ -19632,7 +19634,7 @@ void Player::AutoUnequipOffhandIfNeed()
CharacterDatabase.CommitTransaction();
std::string subject = GetSession()->GetMangosString(LANG_NOT_EQUIPPED_ITEM);
MailDraft(subject).AddItem(offItem).SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM));
MailDraft(subject, "There's were problems with equipping this item.", 0).AddItem(offItem).SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM));
}
}

View file

@ -252,6 +252,10 @@ int WorldSocket::open (void *a)
packet << uint32(0x6E8547B9); // random data
packet << uint32(0x9A6AA2F8); // random data
packet << uint32(0xA4F170F4); // random data
packet << uint32(0xF3539DA3); // random data
packet << uint32(0x6E8547B9); // random data
packet << uint32(0x9A6AA2F8); // random data
packet << uint32(0xA4F170F4); // random data
if (SendPacket (packet) == -1)
return -1;