Add Feature pt1

This commit is contained in:
Silica 2022-03-07 07:08:47 -05:00
parent a184e4d735
commit 092534e331
131 changed files with 3113 additions and 1418 deletions

View file

@ -0,0 +1,99 @@
using HISP.Server;
using System;
using System.Collections.Generic;
namespace HISP.Player
{
public class Award
{
public struct AwardEntry
{
public int Id;
public int Sort;
public string Title;
public int IconId;
public int MoneyBonus;
public string CompletionText;
public string Description;
}
public static AwardEntry[] GlobalAwardList;
public static AwardEntry GetAwardById(int id)
{
//99% fo the time this will work
try
{
AwardEntry award = GlobalAwardList[id - 1];
if (award.Id == id)
return award;
}
catch (Exception) { };
// Incase it doesnt...
foreach(AwardEntry award in GlobalAwardList)
{
if (award.Id == id)
return award;
}
throw new KeyNotFoundException("Award ID " + id + " Does not exist.");
}
private List<AwardEntry> awardsEarned;
private User baseUser;
public AwardEntry[] AwardsEarned
{
get
{
return awardsEarned.ToArray();
}
}
public bool HasAward(AwardEntry award)
{
foreach(AwardEntry awardEntry in AwardsEarned)
{
if (awardEntry.Id == award.Id)
return true;
}
return false;
}
public void AddAward(AwardEntry award,bool addToDatabase=true)
{
if (HasAward(award))
return;
if (addToDatabase)
{
Database.AddAward(baseUser.Id, award.Id);
baseUser.AddMoney(award.MoneyBonus);
byte[] chatPacket = PacketBuilder.CreateChat(award.CompletionText, PacketBuilder.CHAT_BOTTOM_RIGHT);
baseUser.LoggedinClient.SendPacket(chatPacket);
}
awardsEarned.Add(award);
}
public Award(User user)
{
baseUser = user;
int[] awards = Database.GetAwards(user.Id);
awardsEarned = new List<AwardEntry>();
foreach (int awardid in awards)
{
AddAward(GetAwardById(awardid), false);
}
}
}
}

View file

@ -0,0 +1,91 @@
using HISP.Server;
using System;
using System.Threading;
namespace HISP.Player
{
public class Dance : IDisposable
{
public const int DanceSpeed = 1000;
private Timer danceTimer;
public string Moves;
public int MoveIndex;
private User baseUser;
public Dance(User BaseUser, string DanceMoves)
{
baseUser = BaseUser;
baseUser.ActiveDance = this;
Moves = DanceMoves.ToLower();
MoveIndex = -1;
danceTimer = new Timer(new TimerCallback(onDanceTick), null, DanceSpeed, DanceSpeed);
}
private void onDanceTick(object state)
{
MoveIndex++;
if (MoveIndex >= Moves.Length)
goto done;
int onHorse = 0;
int facing = baseUser.Facing;
while (facing >= 5)
{
facing -= 5;
onHorse++;
}
char moveInDir = Moves[MoveIndex];
int direction;
switch(moveInDir)
{
case 'u':
direction = PacketBuilder.DIRECTION_UP;
break;
case 'd':
direction = PacketBuilder.DIRECTION_DOWN;
break;
case 'l':
direction = PacketBuilder.DIRECTION_LEFT;
break;
case 'r':
direction = PacketBuilder.DIRECTION_RIGHT;
break;
default:
goto done;
}
baseUser.Facing = direction + (onHorse * 5);
byte[] moveResponse = PacketBuilder.CreateMovementPacket(baseUser.X, baseUser.Y, baseUser.CharacterId, baseUser.Facing, PacketBuilder.DIRECTION_NONE, false);
baseUser.LoggedinClient.SendPacket(moveResponse);
GameServer.UpdateUserFacingAndLocation(baseUser);
done:;
if (MoveIndex < Moves.Length)
{
danceTimer.Change(DanceSpeed, DanceSpeed);
}
else
{
this.Dispose();
}
}
public void Dispose()
{
baseUser.ActiveDance = null;
baseUser = null;
Moves = null;
danceTimer.Dispose();
danceTimer = null;
MoveIndex = -1;
}
}
}

View file

@ -0,0 +1,117 @@
using HISP.Game;
using HISP.Server;
using HISP.Game.Items;
namespace HISP.Player.Equips
{
public class CompetitionGear
{
public const int MISC_FLAG_HEAD = 1;
public const int MISC_FLAG_BODY = 2;
public const int MISC_FLAG_LEGS = 3;
public const int MISC_FLAG_FEET = 4;
private int playerId;
public CompetitionGear(int PlayerId)
{
playerId = PlayerId;
if (!Database.HasCompetitionGear(PlayerId))
Database.InitCompetitionGear(PlayerId);
int itemId = Database.GetCompetitionGearHeadPeice(PlayerId);
if (itemId != 0)
head = Item.GetItemById(itemId);
itemId = Database.GetCompetitionGearBodyPeice(PlayerId);
if (itemId != 0)
body = Item.GetItemById(itemId);
itemId = Database.GetCompetitionGearLegPeice(PlayerId);
if (itemId != 0)
legs = Item.GetItemById(itemId);
itemId = Database.GetCompetitionGearFeetPeice(PlayerId);
if (itemId != 0)
feet = Item.GetItemById(itemId);
}
public Item.ItemInformation Head
{
get
{
return head;
}
set
{
if (value == null)
{
head = null;
Database.SetCompetitionGearHeadPeice(playerId, 0);
return;
}
Database.SetCompetitionGearHeadPeice(playerId, value.Id);
head = value;
}
}
public Item.ItemInformation Body
{
get
{
return body;
}
set
{
if (value == null)
{
body = null;
Database.SetCompetitionGearBodyPeice(playerId, 0);
return;
}
Database.SetCompetitionGearBodyPeice(playerId, value.Id);
body = value;
}
}
public Item.ItemInformation Legs
{
get
{
return legs;
}
set
{
if (value == null)
{
legs = null;
Database.SetCompetitionGearLegPeice(playerId, 0);
return;
}
Database.SetCompetitionGearLegPeice(playerId, value.Id);
legs = value;
}
}
public Item.ItemInformation Feet
{
get
{
return feet;
}
set
{
if (value == null)
{
feet = null;
Database.SetCompetitionGearFeetPeice(playerId, 0);
return;
}
Database.SetCompetitionGearFeetPeice(playerId, value.Id);
feet = value;
}
}
private Item.ItemInformation head;
private Item.ItemInformation body;
private Item.ItemInformation legs;
private Item.ItemInformation feet;
}
}

View file

@ -0,0 +1,113 @@
using HISP.Game;
using HISP.Server;
using HISP.Game.Items;
namespace HISP.Player.Equips
{
public class Jewelry
{
private int playerId;
public Jewelry(int PlayerId)
{
playerId = PlayerId;
if (!Database.HasJewelry(PlayerId))
Database.InitJewelry(PlayerId);
int itemId = Database.GetJewelrySlot1(PlayerId);
if (itemId != 0)
slot1 = Item.GetItemById(itemId);
itemId = Database.GetJewelrySlot2(PlayerId);
if (itemId != 0)
slot2 = Item.GetItemById(itemId);
itemId = Database.GetJewelrySlot3(PlayerId);
if (itemId != 0)
slot3 = Item.GetItemById(itemId);
itemId = Database.GetJewelrySlot4(PlayerId);
if (itemId != 0)
slot4 = Item.GetItemById(itemId);
}
public Item.ItemInformation Slot1
{
get
{
return slot1;
}
set
{
if (value == null)
{
slot1 = null;
Database.SetJewelrySlot1(playerId, 0);
return;
}
Database.SetJewelrySlot1(playerId, value.Id);
slot1 = value;
}
}
public Item.ItemInformation Slot2
{
get
{
return slot2;
}
set
{
if (value == null)
{
slot2 = null;
Database.SetJewelrySlot2(playerId, 0);
return;
}
Database.SetJewelrySlot2(playerId, value.Id);
slot2 = value;
}
}
public Item.ItemInformation Slot3
{
get
{
return slot3;
}
set
{
if (value == null)
{
slot3 = null;
Database.SetJewelrySlot3(playerId, 0);
return;
}
Database.SetJewelrySlot3(playerId, value.Id);
slot3 = value;
}
}
public Item.ItemInformation Slot4
{
get
{
return slot4;
}
set
{
if (value == null)
{
slot4 = null;
Database.SetJewelrySlot4(playerId, 0);
return;
}
Database.SetJewelrySlot4(playerId, value.Id);
slot4 = value;
}
}
private Item.ItemInformation slot1;
private Item.ItemInformation slot2;
private Item.ItemInformation slot3;
private Item.ItemInformation slot4;
}
}

View file

@ -0,0 +1,126 @@
using System.Collections.Generic;
using HISP.Game;
using HISP.Server;
namespace HISP.Player
{
public class Friends
{
private User baseUser;
private List<int> list;
public int[] List
{
get
{
return list.ToArray();
}
}
public int Count
{
get
{
return List.Length;
}
}
public void RemoveFromLocalList(int value)
{
list.Remove(value);
}
public void AddToLocalList(int value)
{
list.Add(value);
}
public Friends(User user)
{
baseUser = user;
list = new List<int>();
int[] friends = Database.GetBuddyList(user.Id);
foreach(int friendId in friends)
{
list.Add(friendId);
}
}
public bool IsFriend(int friendUserId)
{
foreach (int userId in List)
if (userId == friendUserId)
return true;
return false;
}
public void RemoveFriend(int userid)
{
Database.RemoveBuddy(baseUser.Id, userid);
// Remove buddy from there list if they are logged in
try
{
User removeFrom = GameServer.GetUserById(userid);
removeFrom.Friends.RemoveFromLocalList(baseUser.Id);
}
catch (KeyNotFoundException) { /* User is offline, remove from database is sufficent */ };
baseUser.Friends.RemoveFromLocalList(userid);
}
public void AddFriend(User userToFriend)
{
if(baseUser.MuteBuddy)
{
byte[] cantFriend = PacketBuilder.CreateChat(Messages.CantSendBuddyRequestWhileMuted, PacketBuilder.CHAT_BOTTOM_RIGHT);
baseUser.LoggedinClient.SendPacket(cantFriend);
return;
}
else if(userToFriend.MuteBuddyRequests)
{
byte[] cantFriend = PacketBuilder.CreateChat(Messages.PlayerIgnoringAllBuddyRequests, PacketBuilder.CHAT_BOTTOM_RIGHT);
baseUser.LoggedinClient.SendPacket(cantFriend);
return;
}
else if(userToFriend.MutePlayer.IsUserMuted(userToFriend))
{
byte[] cantFriend = PacketBuilder.CreateChat(Messages.PlayerIgnoringYourBuddyRequests, PacketBuilder.CHAT_BOTTOM_RIGHT);
baseUser.LoggedinClient.SendPacket(cantFriend);
return;
}
if (userToFriend.PendingBuddyRequestTo == baseUser)
{
Database.AddBuddy(baseUser.Id, userToFriend.Id);
list.Add(userToFriend.Id);
userToFriend.Friends.AddToLocalList(baseUser.Id);
byte[] nowFriendsMsg = PacketBuilder.CreateChat(Messages.FormatAddBuddyConfirmed(userToFriend.Username), PacketBuilder.CHAT_BOTTOM_RIGHT);
byte[] nowFriendsOther = PacketBuilder.CreateChat(Messages.FormatAddBuddyConfirmed(baseUser.Username), PacketBuilder.CHAT_BOTTOM_RIGHT);
userToFriend.LoggedinClient.SendPacket(nowFriendsOther);
baseUser.LoggedinClient.SendPacket(nowFriendsMsg);
if(!baseUser.MajorPriority)
GameServer.UpdateArea(baseUser.LoggedinClient);
if (!userToFriend.MajorPriority)
GameServer.UpdateArea(userToFriend.LoggedinClient);
}
else
{
baseUser.PendingBuddyRequestTo = userToFriend;
byte[] pendingMsg = PacketBuilder.CreateChat(Messages.AddBuddyPending, PacketBuilder.CHAT_BOTTOM_RIGHT);
byte[] pendingMsgOther = PacketBuilder.CreateChat(Messages.FormatAddBuddyPendingOther(baseUser.Username), PacketBuilder.CHAT_BOTTOM_RIGHT);
baseUser.LoggedinClient.SendPacket(pendingMsg);
if(!userToFriend.MuteBuddyRequests && !userToFriend.MuteAll)
userToFriend.LoggedinClient.SendPacket(pendingMsgOther);
}
}
}
}

View file

@ -0,0 +1,186 @@
using HISP.Server;
using System.Collections.Generic;
namespace HISP.Player
{
public class Highscore
{
public class HighscoreTableEntry
{
public int UserId;
public string GameName;
public int Wins;
public int Looses;
public int TimesPlayed;
public int Score;
public string Type;
}
public HighscoreTableEntry[] HighscoreList
{
get
{
return highScoreList.ToArray();
}
}
private User baseUser;
private List<HighscoreTableEntry> highScoreList = new List<HighscoreTableEntry>();
public Highscore(User user)
{
baseUser = user;
HighscoreTableEntry[] highscores = Database.GetPlayerHighScores(user.Id);
foreach (HighscoreTableEntry highscore in highscores)
highScoreList.Add(highscore);
}
public HighscoreTableEntry GetHighscore(string gameTitle)
{
foreach (HighscoreTableEntry highscore in HighscoreList)
{
if (highscore.GameName == gameTitle)
{
return highscore;
}
}
throw new KeyNotFoundException("Highscore for " + gameTitle + " Not found.");
}
public bool HasHighscore(string gameTitle)
{
foreach(HighscoreTableEntry highscore in HighscoreList)
{
if(highscore.GameName == gameTitle)
{
return true;
}
}
return false;
}
public bool Loose(string gameTitle)
{
bool isNewScore = true;
if (!HasHighscore(gameTitle))
{
Database.AddNewWinner(baseUser.Id, gameTitle, 0, 1);
HighscoreTableEntry newHighscore = new HighscoreTableEntry();
newHighscore.UserId = baseUser.Id;
newHighscore.GameName = gameTitle;
newHighscore.Wins = 0;
newHighscore.Looses = 0;
newHighscore.TimesPlayed = 1;
newHighscore.Wins = 0;
newHighscore.Looses = 1;
newHighscore.Type = "WINLOSS";
highScoreList.Add(newHighscore);
return isNewScore;
}
else
{
Database.UpdateHighscoreLooseGame(baseUser.Id, gameTitle);
for (int i = 0; i < highScoreList.Count; i++)
{
if (highScoreList[i].GameName == gameTitle)
{
highScoreList[i].TimesPlayed += 1;
highScoreList[i].Looses++;
}
}
return isNewScore;
}
}
public bool Win(string gameTitle)
{
bool isNewScore = true;
if (!HasHighscore(gameTitle))
{
Database.AddNewWinner(baseUser.Id, gameTitle, 1, 0);
HighscoreTableEntry newHighscore = new HighscoreTableEntry();
newHighscore.UserId = baseUser.Id;
newHighscore.GameName = gameTitle;
newHighscore.Wins = 0;
newHighscore.Looses = 0;
newHighscore.TimesPlayed = 1;
newHighscore.Wins = 1;
newHighscore.Looses = 0;
newHighscore.Type = "WINLOSS";
highScoreList.Add(newHighscore);
return isNewScore;
}
else
{
Database.UpdateHighscoreWinGame(baseUser.Id, gameTitle);
for (int i = 0; i < highScoreList.Count; i++)
{
if (highScoreList[i].GameName == gameTitle)
{
highScoreList[i].TimesPlayed += 1;
highScoreList[i].Wins++;
}
}
return isNewScore;
}
}
public bool UpdateHighscore(string gameTitle, int score, bool time)
{
bool isNewScore = true;
if (!HasHighscore(gameTitle))
{
string type = time ? "TIME" : "SCORE";
Database.AddNewHighscore(baseUser.Id, gameTitle, score, type);
HighscoreTableEntry newHighscore = new HighscoreTableEntry();
newHighscore.UserId = baseUser.Id;
newHighscore.GameName = gameTitle;
newHighscore.Wins = 0;
newHighscore.Looses = 0;
newHighscore.TimesPlayed = 1;
newHighscore.Score = score;
newHighscore.Type = type;
highScoreList.Add(newHighscore);
return isNewScore;
}
else
{
int currentScore = GetHighscore(gameTitle).Score;
if (score < currentScore)
{
score = currentScore;
isNewScore = false;
}
Database.UpdateHighscore(baseUser.Id, gameTitle, score);
for(int i = 0; i < highScoreList.Count; i++)
{
if(highScoreList[i].GameName == gameTitle)
{
highScoreList[i].TimesPlayed += 1;
highScoreList[i].Score = score;
}
}
return isNewScore;
}
}
}
}

View file

@ -0,0 +1,123 @@
using HISP.Game;
using HISP.Game.Inventory;
using HISP.Game.Items;
using HISP.Server;
using System.Collections.Generic;
namespace HISP.Player
{
public class Mailbox
{
private User baseUser;
private List<Mail> mails = new List<Mail>();
public int MailCount
{
get
{
return MailMessages.Length;
}
}
public int UnreadMailCount
{
get
{
int i = 0;
foreach (Mail mail in MailMessages)
{
if (!mail.Read)
{
i++;
}
}
return i;
}
}
public Mail[] MailMessages
{
get
{
return mails.ToArray();
}
}
public class Mail
{
public int RandomId;
public bool Read;
public int FromUser;
public int ToUser;
public string Subject;
public string Message;
public int Timestamp;
}
public void RipUpMessage(Mail message)
{
Database.DeleteMail(message.RandomId);
mails.Remove(message);
InventoryItem item = baseUser.Inventory.GetItemByItemId(Item.MailMessage);
foreach(ItemInstance instance in item.ItemInstances)
{
if (instance.Data == message.RandomId)
{
baseUser.Inventory.Remove(instance);
break;
}
}
byte[] rippedUpMessage = PacketBuilder.CreateChat(Messages.MailRippedMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
baseUser.LoggedinClient.SendPacket(rippedUpMessage);
GameServer.UpdateInventory(baseUser.LoggedinClient);
}
public void ReadAllMail()
{
Database.ReadAllMail(baseUser.Id);
for (int i = 0; i < MailCount; i++)
{
if(!mails[i].Read)
{
ItemInstance mailMessageFromPlayer = new ItemInstance(Item.MailMessage, -1, mails[i].RandomId);
baseUser.Inventory.AddIgnoringFull(mailMessageFromPlayer);
}
mails[i].Read = true;
}
GameServer.UpdatePlayer(baseUser.LoggedinClient);
}
public void AddMail(Mail mailMessage)
{
mails.Add(mailMessage);
Database.AddMail(mailMessage.RandomId, mailMessage.ToUser, mailMessage.FromUser, mailMessage.Subject, mailMessage.Message, mailMessage.Timestamp, mailMessage.Read);
}
public bool MessageExists(int randomId)
{
foreach (Mail mail in MailMessages)
{
if (mail.RandomId == randomId)
return true;
}
return false;
}
public Mail GetMessageByRandomId(int randomId)
{
foreach(Mail mail in MailMessages)
{
if (mail.RandomId == randomId)
return mail;
}
throw new KeyNotFoundException("Mail w id " + randomId + " NOT FOUND.");
}
public Mailbox(User user)
{
baseUser = user;
Mail[] mailMessages = Database.LoadMailbox(user.Id);
foreach (Mail mailMessage in mailMessages)
mails.Add(mailMessage);
}
}
}

View file

@ -0,0 +1,40 @@
using HISP.Server;
using System.Collections.Generic;
namespace HISP.Player
{
public class MutedPlayers
{
private User baseUser;
private List<int> userIds;
public MutedPlayers(User BaseUser)
{
userIds = new List<int>();
baseUser = BaseUser;
int[] userids = Database.GetMutedPlayers(BaseUser.Id);
foreach (int userid in userids)
userIds.Add(userid);
}
public bool IsUserMuted(User user)
{
return userIds.Contains(user.Id);
}
public void MuteUser(User user)
{
userIds.Add(user.Id);
Database.AddMutedPlayer(baseUser.Id, user.Id);
}
public void UnmuteUser(User user)
{
userIds.Remove(user.Id);
Database.DeleteMutedPlayer(baseUser.Id, user.Id);
}
}
}

View file

@ -0,0 +1,53 @@
using System.Collections.Generic;
using HISP.Server;
namespace HISP.Player
{
public class PlayerQuests
{
private List<TrackedQuest> trackedQuests = new List<TrackedQuest>();
public User BaseUser;
public TrackedQuest[] QuestList
{
get
{
return trackedQuests.ToArray();
}
}
public void Add(int questId, int timesCompleted)
{
TrackedQuest quest = new TrackedQuest(BaseUser.Id, questId, 0);
quest.TimesCompleted = timesCompleted;
trackedQuests.Add(quest);
}
public int GetTrackedQuestAmount(int questId)
{
foreach(TrackedQuest quest in QuestList)
{
if (quest.QuestId == questId)
return quest.TimesCompleted;
}
return 0;
}
public void TrackQuest(int questId)
{
foreach (TrackedQuest quest in QuestList)
{
if (quest.QuestId == questId)
{
quest.TimesCompleted++;
return;
}
}
Add(questId, 1);
}
public PlayerQuests(User user)
{
BaseUser = user;
TrackedQuest[] quests = Database.GetTrackedQuests(user.Id);
foreach (TrackedQuest quest in quests)
trackedQuests.Add(quest);
}
}
}

View file

@ -0,0 +1,30 @@
using System;
using HISP.Server;
namespace HISP
{
public class TrackedQuest
{
public TrackedQuest(int playerID, int questID, int timesComplete)
{
playerId = playerID;
QuestId = questID;
timesCompleted = timesComplete;
}
public int QuestId;
private int playerId;
public int TimesCompleted
{
get
{
return timesCompleted;
}
set
{
Database.SetTrackedQuestCompletedCount(playerId, QuestId, value);
timesCompleted = value;
}
}
private int timesCompleted;
}
}

View file

@ -0,0 +1,312 @@
using HISP.Game;
using HISP.Game.Horse;
using HISP.Game.Inventory;
using HISP.Game.Items;
using HISP.Security;
using HISP.Server;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace HISP.Player
{
public class Trade
{
public Trade(User me)
{
RandomId = RandomID.NextRandomId();
Trader = me;
}
public int RandomId;
public User Trader;
public Trade OtherTrade;
public string Stage = "OPEN";
public int MoneyOffered = 0;
private List<HorseInstance> horsesOffered = new List<HorseInstance>();
private List<ItemInstance[]> itemsOffered = new List<ItemInstance[]>();
public ItemInstance[][] ItemsOffered
{
get
{
return itemsOffered.ToArray();
}
}
public HorseInstance[] HorsesOffered
{
get
{
return horsesOffered.ToArray();
}
}
public void RemoveOfferedHorse(HorseInstance horse)
{
horsesOffered.Remove(horse);
}
public void OfferHorse(HorseInstance horse)
{
horsesOffered.Add(horse);
}
public void OfferItems(ItemInstance[] items)
{
itemsOffered.Add(items);
}
public void RemoveOfferedItems(ItemInstance[] items)
{
itemsOffered.Remove(items);
}
private void endTrade()
{
Trader.PendingTradeTo = 0;
Trader.TradingWith = null;
OtherTrade.Trader.PendingTradeTo = 0;
OtherTrade.Trader.TradingWith = null;
GameServer.UpdateArea(Trader.LoggedinClient);
GameServer.UpdateArea(OtherTrade.Trader.LoggedinClient);
}
public bool Fail = false;
public void CompleteTrade()
{
/*
* Money Checks
*/
// Check if other player has no money
if (MoneyOffered > 0 && OtherTrade.Trader.Money < 0)
{
byte[] otherNegativeMoneyNotAllowed = PacketBuilder.CreateChat(Messages.TradeOtherPlayerHasNegativeMoney, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(otherNegativeMoneyNotAllowed);
Fail = true;
OtherTrade.Fail = true;
}
// Check if current player has no money
if (OtherTrade.MoneyOffered > 0 && Trader.Money < 0)
{
byte[] negativeMoneyNotAllowed = PacketBuilder.CreateChat(Messages.TradeYouHaveNegativeMoney, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(negativeMoneyNotAllowed);
Fail = true;
OtherTrade.Fail = true;
}
// Check if other player has any bids
if (OtherTrade.Trader.Bids.Length > 0)
{
byte[] tradeNotAllowedWhileOtherBidding = PacketBuilder.CreateChat(Messages.TradeNotAllowedWhileOtherBidding, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeNotAllowedWhileOtherBidding);
Fail = true;
OtherTrade.Fail = true;
}
// check if current player has bids'
if (Trader.Bids.Length > 0)
{
byte[] tradeNotAllowedWhileBidding = PacketBuilder.CreateChat(Messages.TradeNotAllowedWhileBidding, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeNotAllowedWhileBidding);
Fail = true;
OtherTrade.Fail = true;
}
// Check if other player has max money
if (MoneyOffered > 0 && OtherTrade.Trader.Money + MoneyOffered > 2100000000)
{
byte[] tradeOtherHasTooMuchMoney = PacketBuilder.CreateChat(Messages.TradeWillGiveOtherTooMuchMoney, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeOtherHasTooMuchMoney);
Fail = true;
OtherTrade.Fail = true;
}
// Check if you have no money
if (OtherTrade.MoneyOffered > 0 && Trader.Money + OtherTrade.MoneyOffered > 2100000000)
{
byte[] tradeYouHasTooMuchMoney = PacketBuilder.CreateChat(Messages.TradeWillGiveYouTooMuchMoney, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeYouHasTooMuchMoney);
Fail = true;
OtherTrade.Fail = true;
}
/*
* Horse Checks
*/
// Check if other player has max horses
if (HorsesOffered.Length > 0 && OtherTrade.Trader.HorseInventory.HorseList.Length + HorsesOffered.Length > OtherTrade.Trader.MaxHorses)
{
byte[] tradeYouHaveTooManyHorses = PacketBuilder.CreateChat(Messages.TradeYouCantHandleMoreHorses, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeYouHaveTooManyHorses);
Fail = true;
OtherTrade.Fail = true;
}
// Check if current player has max horses
if (OtherTrade.HorsesOffered.Length > 0 && Trader.HorseInventory.HorseList.Length + OtherTrade.HorsesOffered.Length > Trader.MaxHorses)
{
byte[] tradeYouHaveTooManyHorses = PacketBuilder.CreateChat(Messages.TradeYouCantHandleMoreHorses, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeYouHaveTooManyHorses);
Fail = true;
OtherTrade.Fail = true;
}
/*
* Item Checks
*/
if (OtherTrade.ItemsOffered.Length > 0)
{
foreach (ItemInstance[] inst in OtherTrade.ItemsOffered)
{
if (Trader.Inventory.HasItemId(inst[0].ItemId))
{
InventoryItem items = Trader.Inventory.GetItemByItemId(inst[0].ItemId);
if (items.ItemInstances.Length + inst.Length > Item.MAX_STACK)
{
byte[] tradeTooManyItems = PacketBuilder.CreateChat(Messages.TradeYouCantCarryMoreItems, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeTooManyItems);
Fail = true;
OtherTrade.Fail = true;
}
}
}
}
if (ItemsOffered.Length > 0)
{
foreach (ItemInstance[] inst in ItemsOffered)
{
if (OtherTrade.Trader.Inventory.HasItemId(inst[0].ItemId))
{
InventoryItem items = OtherTrade.Trader.Inventory.GetItemByItemId(inst[0].ItemId);
if (items.ItemInstances.Length + inst.Length > Item.MAX_STACK)
{
byte[] tradeTooManyItems = PacketBuilder.CreateChat(Messages.TradeOtherCantCarryMoreItems, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeTooManyItems);
Fail = true;
OtherTrade.Fail = true;
}
}
}
}
if (this.Fail)
goto cancelTrade;
else
goto acceptTrade;
acceptTrade:;
byte[] tradeAccepted = PacketBuilder.CreateChat(Messages.TradeAcceptedMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeAccepted);
// Transfer Money
if (MoneyOffered > 0)
{
Trader.TakeMoney(MoneyOffered);
byte[] tradeSpentMoney = PacketBuilder.CreateChat(Messages.FormatTradeYouSpent(MoneyOffered), PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeSpentMoney);
}
if(OtherTrade.MoneyOffered > 0)
{
Trader.AddMoney(OtherTrade.MoneyOffered);
byte[] tradeReceivedMoney = PacketBuilder.CreateChat(Messages.FormatTradeYouReceived(OtherTrade.MoneyOffered), PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeReceivedMoney);
}
foreach (HorseInstance inst in HorsesOffered) // Transfer Horses
{
inst.Owner = OtherTrade.Trader.Id;
// Dismount horse if its traded
if (Trader.CurrentlyRidingHorse != null)
{
if (Trader.CurrentlyRidingHorse.RandomId == inst.RandomId)
{
byte[] disMounted = PacketBuilder.CreateChat(Messages.TradeRiddenHorse, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.Facing %= 5;
Trader.CurrentlyRidingHorse = null;
Trader.LoggedinClient.SendPacket(disMounted);
}
}
Trader.HorseInventory.DeleteHorse(inst, false);
OtherTrade.Trader.HorseInventory.AddHorse(inst, false);
}
foreach (ItemInstance[] item in ItemsOffered) // Transfer Items
{
foreach (ItemInstance itm in item)
{
Trader.Inventory.Remove(itm);
OtherTrade.Trader.Inventory.AddIgnoringFull(itm);
}
}
Trader.TrackedItems.GetTrackedItem(Tracking.TrackableItem.Trading).Count++;
if (Trader.TrackedItems.GetTrackedItem(Tracking.TrackableItem.Trading).Count >= 100)
Trader.Awards.AddAward(Award.GetAwardById(29)); // Trader
if (Trader.TrackedItems.GetTrackedItem(Tracking.TrackableItem.Trading).Count >= 1000)
Trader.Awards.AddAward(Award.GetAwardById(50)); // Pro Trader
endTrade();
return;
cancelTrade:;
InteruptTrade();
return;
}
public void InteruptTrade()
{
byte[] tradeCanceled = PacketBuilder.CreateChat(Messages.TradeCanceledInterupted, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeCanceled);
endTrade();
}
public void AcceptTrade()
{
byte[] waitingForAccept = PacketBuilder.CreateChat(Messages.TradeWaitingForOthersToAcceptMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(waitingForAccept);
if (OtherTrade.Stage == "ACCEPTED")
{
CompleteTrade();
OtherTrade.CompleteTrade();
}
Stage = "ACCEPTED";
}
public void CancelTrade()
{
byte[] tradeCanceled = PacketBuilder.CreateChat(Messages.TradeCanceledByYouMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(tradeCanceled);
byte[] tradeCanceledOther = PacketBuilder.CreateChat(Messages.FormatTradeCanceledByPlayer(Trader.Username), PacketBuilder.CHAT_BOTTOM_RIGHT);
OtherTrade.Trader.LoggedinClient.SendPacket(tradeCanceledOther);
endTrade();
}
public void CancelTradeMoved()
{
byte[] playerMoved = PacketBuilder.CreateChat(Messages.TradeCanceledBecuasePlayerMovedMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
Trader.LoggedinClient.SendPacket(playerMoved);
OtherTrade.Trader.LoggedinClient.SendPacket(playerMoved);
endTrade();
}
}
}

View file

@ -0,0 +1,699 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HISP.Game;
using HISP.Server;
using HISP.Player.Equips;
using HISP.Game.Services;
using HISP.Game.Inventory;
using HISP.Game.Horse;
namespace HISP.Player
{
public class User
{
private List<Auction.AuctionBid> bids = new List<Auction.AuctionBid>();
private List<User> beingSocializedBy = new List<User>();
private int chatViolations;
private int charId;
private int subscribedUntil;
private bool subscribed;
private string profilePage;
private string privateNotes;
private int x;
private bool stealth = false;
private int y;
private int questPoints;
private double bankMoney;
private int experience;
private int hunger;
private int thirst;
private int tired;
private bool noClip = false;
public bool NoClip
{
get
{
if(CurrentlyRidingHorse != null)
{
if(CurrentlyRidingHorse.Breed != null)
{
if (CurrentlyRidingHorse.Breed.Type == "pegasus")
{
return true;
}
if (CurrentlyRidingHorse.Breed.Id == 170)
{
return true;
}
}
}
return noClip;
}
set
{
noClip = true;
}
}
public Trade TradingWith = null;
public int AttemptingToOfferItem;
public bool TradeMenuPriority = false;
public byte[] SecCodeSeeds = new byte[3];
public int SecCodeInc = 0;
public int SecCodeCount = 0;
public int Id;
public string Username;
public bool Administrator = false;
public bool Moderator = false;
public bool NewPlayer = false;
public GameClient LoggedinClient;
public CompetitionGear EquipedCompetitionGear;
public Jewelry EquipedJewelry;
public bool MuteAds = false;
public bool MuteGlobal = false;
public bool MuteIsland = false;
public bool MuteNear = false;
public bool MuteHere = false;
public bool MuteBuddy = false;
public bool MutePrivateMessage = false;
public bool MuteBuddyRequests = false;
public bool MuteSocials = false;
public bool MuteAll = false;
public bool MuteLogins = false;
public string Gender;
public bool UserInfoSend = false;
public bool MajorPriority = false;
public bool MinorPriority = false;
public bool HorseWindowOpen = false;
public bool Idle;
public int Facing;
public HorseInfo.Breed PawneerOrderBreed = null;
public string PawneerOrderColor = "";
public string PawneerOrderGender = "";
public bool InRealTimeQuiz = false;
public int PendingTradeTo;
public Mailbox MailBox;
public Friends Friends;
public string Password; // For chat filter.
public PlayerInventory Inventory;
public Npc.NpcEntry LastTalkedToNpc;
public Shop LastShoppedAt;
public Inn LastVisitedInn;
public HorseInventory HorseInventory;
public HorseInstance LastViewedHorse;
public HorseInstance LastViewedHorseOther;
public int LastRiddenHorse = 0;
public HorseInstance CurrentlyRidingHorse;
public Tracking TrackedItems;
public Ranch OwnedRanch = null;
public PlayerQuests Quests;
public Highscore Highscores;
public MutedPlayers MutePlayer;
public Riddler LastRiddle;
public Award Awards;
public User SocializingWith;
public User PendingBuddyRequestTo;
public Dance ActiveDance;
public bool CanUseAdsChat = true;
public int CapturingHorseId;
public DateTime LoginTime;
public string LastSeenWeather;
public string AutoReplyText = "";
public int LastClickedRanchBuilding = 0;
public int TotalGlobalChatMessages = 1;
public User[] BeingSocializedBy
{
get
{
return beingSocializedBy.ToArray();
}
}
public Auction.AuctionBid[] Bids
{
get
{
return bids.ToArray();
}
}
public int MaxItems
{
get
{
int baseValue = 40;
if (Subscribed)
{
if (OwnedRanch != null)
{
baseValue += 20 * OwnedRanch.GetBuildingCount(4); // Shed
if (baseValue > 80) // 2 sheds max!
baseValue = 80;
}
}
return baseValue;
}
}
public int MaxHorses
{
get
{
if (Subscribed)
{
int baseValue = 11;
if(OwnedRanch != null)
{
baseValue += OwnedRanch.GetBuildingCount(1) * 4; // Barn
baseValue += OwnedRanch.GetBuildingCount(10) * 8; // Big Barn
baseValue += OwnedRanch.GetBuildingCount(11) * 12; // Gold Barn
}
return baseValue;
}
return 7; // will change when ranches are implemented.
}
}
public void TakeMoney(int amount)
{
int money = Money;
money -= amount;
Database.SetPlayerMoney(money, Id);
GameServer.UpdatePlayer(LoggedinClient);
}
public void AddMoney(int amount)
{
int money = Money;
try
{
checked
{
money += amount;
}
}
catch(OverflowException)
{
money = 2147483647;
}
Database.SetPlayerMoney(money, Id);
GameServer.UpdatePlayer(LoggedinClient);
}
public string GetWeatherSeen()
{
string weather = "SUNNY";
if (World.InTown(this.X, this.Y))
weather = World.GetTown(this.X, this.Y).Weather;
if (World.InIsle(this.X, this.Y))
weather = World.GetIsle(this.X, this.Y).Weather;
LastSeenWeather = weather;
return weather;
}
public void DoRanchActions()
{
if(OwnedRanch != null)
{
Tiredness = 1000; // All ranches fully rest you.
if(OwnedRanch.GetBuildingCount(2) > 0)
{
Thirst = 1000;
foreach (HorseInstance horse in HorseInventory.HorseList)
horse.BasicStats.Thirst = 1000;
}
if (OwnedRanch.GetBuildingCount(3) > 0)
{
foreach (HorseInstance horse in HorseInventory.HorseList)
horse.BasicStats.Hunger = 1000;
}
if(OwnedRanch.GetBuildingCount(9) > 0)
{
Hunger = 1000;
}
if( (OwnedRanch.GetBuildingCount(1) > 0)|| (OwnedRanch.GetBuildingCount(10) > 0) || (OwnedRanch.GetBuildingCount(11) > 0))
{
foreach (HorseInstance horse in HorseInventory.HorseList)
horse.BasicStats.Tiredness = 1000;
}
}
}
public DateTime SubscribedUntil
{
get
{
return Util.UnixTimeStampToDateTime(subscribedUntil);
}
}
public int FreeMinutes
{
get
{
int freeTime = Database.GetFreeTime(Id);
return freeTime;
}
set
{
Database.SetFreeTime(Id, value);
}
}
public bool Subscribed
{
get
{
if (ConfigReader.AllUsersSubbed)
return true;
if (Administrator)
return true;
int Timestamp = Convert.ToInt32(new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds());
if(Timestamp > subscribedUntil && subscribed) // sub expired.
{
Logger.InfoPrint(Username + "'s Subscription expired. (timestamp now: " + Timestamp + " exp date: " + subscribedUntil+" )");
Database.SetUserSubscriptionStatus(this.Id, false);
subscribed = false;
}
return subscribed;
}
set
{
Database.SetUserSubscriptionStatus(this.Id, value);
}
}
public bool Stealth
{
get
{
return stealth;
}
set
{
if (value)
Database.RemoveOnlineUser(this.Id);
else
Database.AddOnlineUser(this.Id, this.Administrator, this.Moderator, this.Subscribed, this.NewPlayer);
stealth = value;
}
}
public int ChatViolations
{
get
{
return chatViolations;
}
set
{
Database.SetChatViolations(value,Id);
chatViolations = value;
}
}
public string PrivateNotes
{
get
{
return privateNotes;
}
set
{
privateNotes = value.Trim();
Database.SetPlayerNotes(Id, privateNotes);
}
}
public string ProfilePage {
get
{
return profilePage;
}
set
{
profilePage = value.TrimEnd();
Database.SetPlayerProfile(profilePage, Id);
}
}
public int Money
{
get
{
return Database.GetPlayerMoney(Id);
}
}
public int Experience
{
get
{
return experience;
}
set
{
Database.SetExperience(Id, value);
experience = value;
}
}
public int QuestPoints
{
get
{
return questPoints;
}
set
{
Database.SetPlayerQuestPoints(value, Id);
questPoints = value;
}
}
public double BankInterest
{
get
{
return Database.GetPlayerBankInterest(Id);
}
set
{
if (value > 9999999999.9999)
value = 9999999999.9999;
Database.SetPlayerBankInterest(value, Id);
}
}
public double BankMoney
{
get
{
return bankMoney;
}
set
{
if (value > 9999999999.9999)
value = 9999999999.9999;
Database.SetPlayerBankMoney(value, Id);
bankMoney = value;
BankInterest = value;
}
}
public int X
{
get
{
return x;
}
set
{
Database.SetPlayerX(value, Id);
x = value;
}
}
public int Y
{
get
{
return y;
}
set
{
Database.SetPlayerY(value, Id);
y = value;
}
}
public int CharacterId
{
get
{
return charId;
}
set
{
Database.SetPlayerCharId(value, Id);
charId = value;
}
}
public int Hunger
{
get
{
return hunger;
}
set
{
if (value >= 1000)
value = 1000;
if (value <= 0)
value = 0;
Database.SetPlayerHunger(Id, value);
hunger = value;
}
}
public int Thirst
{
get
{
return thirst;
}
set
{
if (value >= 1000)
value = 1000;
if (value <= 0)
value = 0;
Database.SetPlayerThirst(Id, value);
thirst = value;
}
}
public int Tiredness
{
get
{
return tired;
}
set
{
if (value >= 1000)
value = 1000;
if (value <= 0)
value = 0;
Database.SetPlayerTiredness(Id, value);
tired = value;
}
}
public void ClearSocailizedWith()
{
beingSocializedBy.Clear();
}
public void RemoveSocailizedWith(User user)
{
beingSocializedBy.Remove(user);
}
public void AddSocailizedWith(User user)
{
beingSocializedBy.Add(user);
}
public void AddBid(Auction.AuctionBid bid)
{
bids.Add(bid);
}
public void RemoveBid(Auction.AuctionBid bid)
{
bids.Remove(bid);
}
public int GetPlayerListIcon()
{
int icon = -1;
if (NewPlayer)
icon = Messages.NewUserIcon;
if (Subscribed)
{
int months = (SubscribedUntil.Month - DateTime.UtcNow.Month) + ((SubscribedUntil.Year - DateTime.UtcNow.Year) * 12);
if (months >= 3)
icon = Messages.ThreeMonthSubscripitionIcon;
else if(months >= (12+3))
icon = Messages.YearSubscriptionIcon;
else
icon = Messages.MonthSubscriptionIcon;
}
if (Moderator)
icon = Messages.ModeratorIcon;
if (Administrator)
icon = Messages.AdminIcon;
return icon;
}
public void Teleport(int newX, int newY)
{
Logger.DebugPrint("Teleporting: " + Username + " to: " + newX.ToString() + "," + newY.ToString());
User[] onScreenBefore = GameServer.GetOnScreenUsers(X, Y, true, true);
User[] onScreenNow = GameServer.GetOnScreenUsers(newX, newY, true, true);
X = newX;
Y = newY;
byte[] MovementPacket = PacketBuilder.CreateMovementPacket(X, Y, CharacterId, Facing, PacketBuilder.DIRECTION_TELEPORT, true);
LoggedinClient.SendPacket(MovementPacket);
GameServer.UpdateWeather(LoggedinClient);
User[] goneOffScreen = onScreenBefore.Except(onScreenNow).ToArray();
User[] goneOnScreen = onScreenNow.Except(onScreenBefore).ToArray();
// Players now offscreen tell the client is at 1000,1000.
foreach (User offScreenUsers in goneOffScreen)
{
if (offScreenUsers.Id == this.Id)
continue;
byte[] playerInfoBytes = PacketBuilder.CreatePlayerInfoUpdateOrCreate(1000 + 4, 1000 + 1, this.Facing, this.CharacterId, this.Username);
offScreenUsers.LoggedinClient.SendPacket(playerInfoBytes);
}
// Tell players now on screen there locations
foreach (User onScreenUsers in goneOnScreen)
{
if (onScreenUsers.Id == this.Id)
continue;
byte[] playerInfoBytes = PacketBuilder.CreatePlayerInfoUpdateOrCreate(onScreenUsers.X, onScreenUsers.Y, onScreenUsers.Facing, onScreenUsers.CharacterId, onScreenUsers.Username);
LoggedinClient.SendPacket(playerInfoBytes);
}
GameServer.Update(LoggedinClient);
}
public byte[] GenerateSecCode()
{
var i = 0;
SecCodeCount++;
SecCodeSeeds[SecCodeCount % 3] = (byte)(SecCodeSeeds[SecCodeCount % 3] + SecCodeInc);
SecCodeSeeds[SecCodeCount % 3] = (byte)(SecCodeSeeds[SecCodeCount % 3] % 92);
i = SecCodeSeeds[0] + SecCodeSeeds[1] * SecCodeSeeds[2] - SecCodeSeeds[1];
i = Math.Abs(i);
i = i % 92;
byte[] SecCode = new byte[4];
SecCode[0] = (byte)(SecCodeSeeds[0] + 33);
SecCode[1] = (byte)(SecCodeSeeds[1] + 33);
SecCode[2] = (byte)(SecCodeSeeds[2] + 33);
SecCode[3] = (byte)(i + 33);
Logger.DebugPrint("Expecting "+Username+" To send Sec Code: "+BitConverter.ToString(SecCode).Replace("-", " "));
return SecCode;
}
public User(GameClient baseClient, int UserId)
{
if (!Database.CheckUserExist(UserId))
throw new KeyNotFoundException("User " + UserId + " not found in database!");
if (!Database.CheckUserExtExists(UserId))
{
Database.CreateUserExt(UserId);
NewPlayer = true;
}
EquipedCompetitionGear = new CompetitionGear(UserId);
EquipedJewelry = new Jewelry(UserId);
Id = UserId;
Username = Database.GetUsername(UserId);
Administrator = Database.CheckUserIsAdmin(Username);
Moderator = Database.CheckUserIsModerator(Username);
chatViolations = Database.GetChatViolations(UserId);
x = Database.GetPlayerX(UserId);
y = Database.GetPlayerY(UserId);
charId = Database.GetPlayerCharId(UserId);
Facing = PacketBuilder.DIRECTION_DOWN;
experience = Database.GetExperience(UserId);
//money = Database.GetPlayerMoney(UserId);
bankMoney = Database.GetPlayerBankMoney(UserId);
questPoints = Database.GetPlayerQuestPoints(UserId);
subscribed = Database.IsUserSubscribed(UserId);
subscribedUntil = Database.GetUserSubscriptionExpireDate(UserId);
profilePage = Database.GetPlayerProfile(UserId);
privateNotes = Database.GetPlayerNotes(UserId);
hunger = Database.GetPlayerHunger(UserId);
thirst = Database.GetPlayerThirst(UserId);
tired = Database.GetPlayerTiredness(UserId);
if(Ranch.IsRanchOwned(this.Id))
{
OwnedRanch = Ranch.GetRanchOwnedBy(this.Id);
}
Gender = Database.GetGender(UserId);
MailBox = new Mailbox(this);
Highscores = new Highscore(this);
Awards = new Award(this);
MutePlayer = new MutedPlayers(this);
TrackedItems = new Tracking(this);
HorseInventory = new HorseInventory(this);
// Generate SecCodes
SecCodeSeeds[0] = (byte)GameServer.RandomNumberGenerator.Next(40, 60);
SecCodeSeeds[1] = (byte)GameServer.RandomNumberGenerator.Next(40, 60);
SecCodeSeeds[2] = (byte)GameServer.RandomNumberGenerator.Next(40, 60);
SecCodeInc = (byte)GameServer.RandomNumberGenerator.Next(40, 60);
Friends = new Friends(this);
LoginTime = DateTime.UtcNow;
LoggedinClient = baseClient;
Inventory = new PlayerInventory(this);
Quests = new PlayerQuests(this);
// Get auctions
foreach(Auction auction in Auction.AuctionRooms)
{
foreach(Auction.AuctionEntry auctionEntry in auction.AuctionEntries)
{
if(auctionEntry.HighestBidder == this.Id)
{
Auction.AuctionBid bid = new Auction.AuctionBid();
bid.BidUser = this;
bid.BidAmount = auctionEntry.HighestBid;
bid.AuctionItem = auctionEntry;
if(bid.BidAmount > 0)
{
bids.Add(bid);
auctionEntry.AddBid(bid);
}
}
}
}
}
}
}