diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json
index 923668a..c5bdd0b 100755
--- a/DataCollection/gamedata.json
+++ b/DataCollection/gamedata.json
@@ -234,8 +234,8 @@
"you_offering":"You are offering %PLAYERNAME% the following: ",
- "add_items":"^T6Add additional trade items:^D58|ADD^R1^H",
- "other_offering":"%PLAYERNAME% is offering you the following:",
+ "add_items":"^T6Add additional trade items:^D58|ADD^R1",
+ "other_offering":"^H%PLAYERNAME% is offering you the following:",
"when_done_click":"^T8When you are done offering things click ^D59|DONE^R1",
"cancel_anytime":"^T6You may cancel trade at any time^B1J%PLAYERID%^R1",
diff --git a/Horse Isle Server/HorseIsleServer/Game/Messages.cs b/Horse Isle Server/HorseIsleServer/Game/Messages.cs
index 9001dfe..6d73a8d 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Messages.cs
+++ b/Horse Isle Server/HorseIsleServer/Game/Messages.cs
@@ -45,9 +45,9 @@ namespace HISP.Game
public static string TradeOfferItem;
public static string TradeOfferItemFormat;
- public static string TradeOfferObjectOtherPlayerInvFull;
+ public static string TradeOfferItemOtherPlayerInvFull;
- // Trading : Money Offer Submenu
+ // Trading : Offer Submenu
public static string TradeMoneyOfferSubmenuFormat;
public static string TradeItemOfferSubmenuFormat;
diff --git a/Horse Isle Server/HorseIsleServer/Game/Meta.cs b/Horse Isle Server/HorseIsleServer/Game/Meta.cs
index f270b7d..e618468 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Meta.cs
+++ b/Horse Isle Server/HorseIsleServer/Game/Meta.cs
@@ -41,6 +41,7 @@ namespace HISP.Game
User[] playersAt = GameServer.GetUsersAt(x, y, true, true);
if(playersAt.Length > 1)
{
+ playersHere += Messages.Seperator;
playersHere += Messages.PlayersHere;
int count = 0;
foreach(User playerAt in playersAt)
@@ -406,11 +407,114 @@ namespace HISP.Game
throw new Exception("A mathematically impossible error occured. please check wether the laws of physics still apply.");
}
+ public static string BuildTradeAdd(Trade trade)
+ {
+ string message = Messages.FormatTradeWhatToOffer(trade.OtherTrade.Trader.Username);
+ message += Messages.TradeOfferMoney;
+ message += Messages.TradeOfferHorse;
+ foreach(HorseInstance horse in trade.Trader.HorseInventory.HorseList)
+ {
+ bool tacked = (horse.Equipment.Saddle != null || horse.Equipment.SaddlePad != null || horse.Equipment.Bridle != null || horse.Equipment.Companion != null);
+ message += Messages.FormatTradeOfferHorse(horse.Name, tacked, horse.RandomId);
+ }
+
+ if(trade.Trader.Inventory.Count >= trade.Trader.MaxItems)
+ {
+ message += Messages.TradeOfferItemOtherPlayerInvFull;
+ }
+ else
+ {
+ message += Messages.TradeOfferItem;
+ foreach(InventoryItem item in trade.Trader.Inventory.GetItemList())
+ {
+ Item.ItemInformation itemInfo = Item.GetItemById(item.ItemId);
+ message += Messages.FormatTradeOfferItem(itemInfo.IconId, itemInfo.Name, item.ItemInstances.Count, item.ItemId);
+ }
+ }
+
+ message += Messages.BackToMap;
+ message += Messages.MetaTerminator;
+ return message;
+
+ }
+
+ public static string BuildTradeAddItem(int totalItems)
+ {
+ string message = "";
+ message += Messages.FormatTradeOfferItemSubmenu(totalItems);
+ message += Messages.BackToMap;
+ message += Messages.MetaTerminator;
+ return message;
+ }
+ public static string BuildTradeAddMoney(int curMoney)
+ {
+ string message = "";
+ message += Messages.FormatTradeOfferMoneySubmenu(curMoney);
+ message += Messages.BackToMap;
+ message += Messages.MetaTerminator;
+ return message;
+ }
public static string BuildTrade(Trade trade)
{
- bool otherAccepted = (trade.OtherTrade.Stage == "ACCEPTED");
- bool youAccepted = trade.Stage == "ACCEPTED";
+
string message = "";
+ message += Messages.FormatTradeWithPlayer(trade.OtherTrade.Trader.Username);
+
+ if (trade.Stage == "DONE" && trade.OtherTrade.Stage == "DONE")
+ message += Messages.TradeFinalReview;
+ else if (trade.Stage == "DONE")
+ message += Messages.TradeWaitingForOtherDone;
+ else if (trade.OtherTrade.Stage == "DONE")
+ message += Messages.TradeOtherPlayerIsDone;
+
+
+ message += Messages.FormatTradeYourOffering(trade.OtherTrade.Trader.Username);
+ if (trade.MoenyOffered == 0 && trade.ItemsOffered.Count == 0 && trade.HorsesOffered.Count == 0)
+ message += Messages.TradeOfferingNothing;
+ if (trade.MoenyOffered > 0)
+ message += Messages.FormatTradeMoneyOffer(trade.MoenyOffered);
+ if(trade.HorsesOffered.Count > 0)
+ foreach(HorseInstance horse in trade.HorsesOffered)
+ message += Messages.FormatTradeHorseOffer(horse.Name, horse.RandomId);
+ if(trade.ItemsOffered.Count > 0)
+ foreach(ItemInstance[] item in trade.ItemsOffered)
+ {
+ Item.ItemInformation itemInfo = item[0].GetItemInfo();
+ string name = itemInfo.Name;
+ if (item.Length > 1)
+ name = itemInfo.PluralName;
+
+ message += Messages.FormatTradeItemOffer(item.Length, name);
+ }
+
+ if(trade.Stage == "OPEN")
+ message += Messages.TradeAddItems;
+
+ message += Messages.FormatTradeOtherOffering(trade.OtherTrade.Trader.Username);
+ if (trade.OtherTrade.MoenyOffered == 0 && trade.OtherTrade.ItemsOffered.Count == 0 && trade.OtherTrade.HorsesOffered.Count == 0)
+ message += Messages.TradeOfferingNothing;
+ if (trade.OtherTrade.MoenyOffered > 0)
+ message += Messages.FormatTradeMoneyOffer(trade.OtherTrade.MoenyOffered);
+ if (trade.OtherTrade.HorsesOffered.Count > 0)
+ foreach (HorseInstance horse in trade.OtherTrade.HorsesOffered)
+ message += Messages.FormatTradeHorseOffer(horse.Name, horse.RandomId);
+ if (trade.OtherTrade.ItemsOffered.Count > 0)
+ foreach (ItemInstance[] item in trade.OtherTrade.ItemsOffered)
+ {
+ Item.ItemInformation itemInfo = item[0].GetItemInfo();
+ string name = itemInfo.Name;
+ if (item.Length > 1)
+ name = itemInfo.PluralName;
+
+ message += Messages.FormatTradeItemOffer(item.Length, name);
+ }
+
+ if (trade.Stage == "OPEN")
+ message += Messages.TradeWhenDoneClick;
+ if (((trade.Stage == "DONE" || trade.Stage == "ACCEPTED") && (trade.OtherTrade.Stage == "DONE" || trade.Stage == "ACCEPTED")) )
+ message += Messages.TradeAcceptTrade;
+
+ message += Messages.TradeCancelAnytime;
return message;
}
diff --git a/Horse Isle Server/HorseIsleServer/Player/Trade.cs b/Horse Isle Server/HorseIsleServer/Player/Trade.cs
index e8ae1fc..cfc4f77 100644
--- a/Horse Isle Server/HorseIsleServer/Player/Trade.cs
+++ b/Horse Isle Server/HorseIsleServer/Player/Trade.cs
@@ -1,6 +1,8 @@
-using HISP.Game.Horse;
+using HISP.Game;
+using HISP.Game.Horse;
using HISP.Game.Items;
using HISP.Security;
+using HISP.Server;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -25,7 +27,38 @@ namespace HISP.Player
public int MoenyOffered = 0;
public List HorsesOffered = new List();
- public List ItemsOffered = new List();
+ public List ItemsOffered = new List();
+
+ 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 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();
+ }
}
}
diff --git a/Horse Isle Server/HorseIsleServer/Player/User.cs b/Horse Isle Server/HorseIsleServer/Player/User.cs
index 40b5230..aea7ef4 100755
--- a/Horse Isle Server/HorseIsleServer/Player/User.cs
+++ b/Horse Isle Server/HorseIsleServer/Player/User.cs
@@ -78,6 +78,7 @@ namespace HISP.Player
public string PawneerOrderColor = "";
public string PawneerOrderGender = "";
+ public int PendingTradeTo;
public Mailbox MailBox;
public Friends Friends;
public string Password; // For chat filter.
diff --git a/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs b/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs
index 2cd6acc..c3176ee 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs
+++ b/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs
@@ -838,7 +838,7 @@ namespace HISP.Server
Messages.TradeWhenDoneClick = gameData.messages.meta.player_interaction.trade.when_done_click;
Messages.TradeCancelAnytime = gameData.messages.meta.player_interaction.trade.cancel_anytime;
- Messages.TradeAcceptedMessage = gameData.messages.meta.player_interaction.trade.accept_trade;
+ Messages.TradeAcceptTrade = gameData.messages.meta.player_interaction.trade.accept_trade;
Messages.TradeOfferingNothing = gameData.messages.meta.player_interaction.trade.offering_nothing;
Messages.TradeOfferingMoneyFormat = gameData.messages.meta.player_interaction.trade.offering_money;
@@ -856,7 +856,7 @@ namespace HISP.Server
Messages.TradeOfferItem = gameData.messages.meta.player_interaction.trade.offer_object;
Messages.TradeOfferItemFormat = gameData.messages.meta.player_interaction.trade.offer_object_format;
- Messages.TradeOfferObjectOtherPlayerInvFull = gameData.messages.meta.player_interaction.trade.offer_object_inv_full;
+ Messages.TradeOfferItemOtherPlayerInvFull = gameData.messages.meta.player_interaction.trade.offer_object_inv_full;
// Trading : Offer Submenu
@@ -879,6 +879,7 @@ namespace HISP.Server
Messages.TradeAcceptedMessage = gameData.messages.meta.player_interaction.trade.trade_accepted;
Messages.TradeCanceledByYouMessage = gameData.messages.meta.player_interaction.trade.you_canceled;
Messages.TradeCanceledByOtherPlayerFormat = gameData.messages.meta.player_interaction.trade.other_canceled;
+ Messages.TradeCanceledBecuasePlayerMovedMessage = gameData.messages.meta.player_interaction.trade.trade_canceled_moved;
Messages.TradeCanceledInterupted = gameData.messages.meta.player_interaction.trade.trade_interupted;
Messages.TradeYouCantHandleMoreHorses = gameData.messages.meta.player_interaction.trade.cant_handle_more_horses;
diff --git a/Horse Isle Server/HorseIsleServer/Server/GameServer.cs b/Horse Isle Server/HorseIsleServer/Server/GameServer.cs
index a24ea1c..a10edaa 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameServer.cs
+++ b/Horse Isle Server/HorseIsleServer/Server/GameServer.cs
@@ -200,6 +200,124 @@ namespace HISP.Server
Logger.ErrorPrint(sender.RemoteIp + " Requested Bird Map when not logged in.");
return;
}
+ byte method = packet[1];
+ switch(method)
+ {
+ case PacketBuilder.PLAYER_INTERACTION_TRADE_REJECT:
+ if (sender.LoggedinUser.TradingWith != null)
+ sender.LoggedinUser.TradingWith.CancelTrade();
+ break;
+ case PacketBuilder.PLAYER_INTERACTION_ADD_ITEM:
+ if (sender.LoggedinUser.TradingWith == null)
+ break;
+ if (packet.Length < 5)
+ break;
+
+ string packetStr = Encoding.UTF8.GetString(packet);
+ string idStr = packetStr.Substring(2, packetStr.Length - 4);
+ char firstChar = idStr[0];
+ switch(firstChar)
+ {
+ case '3': // Money
+
+ if (sender.LoggedinUser.Bids.Count > 0)
+ {
+ byte[] cantBuyWhileAuctioning = PacketBuilder.CreateChat(Messages.AuctionNoOtherTransactionAllowed, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(cantBuyWhileAuctioning);
+ break;
+ }
+
+
+ byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildTradeAddMoney(sender.LoggedinUser.Money));
+ sender.SendPacket(metaPacket);
+
+ break;
+ case '2': // Horse
+ string horseRandomIdStr = idStr.Substring(1);
+ int horseRandomId = -1;
+ try
+ {
+ horseRandomId = int.Parse(horseRandomIdStr);
+ }
+ catch (FormatException)
+ {
+ break;
+ }
+
+ if (!sender.LoggedinUser.HorseInventory.HorseIdExist(horseRandomId))
+ break;
+
+ HorseInstance horse = sender.LoggedinUser.HorseInventory.GetHorseById(horseRandomId);
+ sender.LoggedinUser.TradingWith.HorsesOffered.Add(horse);
+
+ UpdateArea(sender);
+ UpdateArea(sender.LoggedinUser.TradingWith.Trader.LoggedinClient);
+
+ break;
+ case '1': // Item
+ string itemIdStr = idStr.Substring(1);
+ int itemId = -1;
+ try
+ {
+ itemId = int.Parse(itemIdStr);
+ }
+ catch(FormatException)
+ {
+ break;
+ }
+
+ if (!sender.LoggedinUser.Inventory.HasItemId(itemId))
+ break;
+
+ InventoryItem item = sender.LoggedinUser.Inventory.GetItemByItemId(itemId);
+ byte[] addItemPacket = PacketBuilder.CreateMetaPacket(Meta.BuildTradeAddItem(item.ItemInstances.Count));
+ sender.SendPacket(addItemPacket);
+ break;
+
+ }
+ break;
+ case PacketBuilder.PLAYER_INTERACTION_TRADE:
+ packetStr = Encoding.UTF8.GetString(packet);
+ string playerIdStr = packetStr.Substring(2, packetStr.Length - 4);
+ int playerId = -1;
+ try
+ {
+ playerId = int.Parse(playerIdStr);
+ }
+ catch(FormatException)
+ {
+ Logger.InfoPrint(sender.LoggedinUser.Username + " tried to trade with User ID NaN.");
+ }
+ if(IsUserOnline(playerId))
+ {
+ User user = GetUserById(playerId);
+ byte[] tradeMsg = PacketBuilder.CreateChat(Messages.TradeRequiresBothPlayersMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(tradeMsg);
+
+ sender.LoggedinUser.PendingTradeTo = user.Id;
+
+ if (user.PendingTradeTo == sender.LoggedinUser.Id)
+ {
+ // Start Trade
+ Trade tradeWithYou = new Trade(sender.LoggedinUser);
+ Trade tradeWithOther = new Trade(user);
+ tradeWithYou.OtherTrade = tradeWithOther;
+ tradeWithOther.OtherTrade = tradeWithYou;
+
+ sender.LoggedinUser.TradingWith = tradeWithYou;
+ user.TradingWith = tradeWithOther;
+
+ UpdateArea(sender);
+ UpdateArea(user.LoggedinClient);
+ }
+
+ }
+ break;
+ default:
+ Logger.DebugPrint("Unknown Player interaction Method: 0x" + method.ToString("X") + " Packet: "+BitConverter.ToString(packet).Replace("-", " "));
+ break;
+ }
+ return;
}
public static void OnBirdMapRequested(GameClient sender, byte[] packet)
{
@@ -2288,6 +2406,25 @@ namespace HISP.Server
metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildMiscStats(sender.LoggedinUser));
sender.SendPacket(metaPacket);
break;
+ case "58": // Add new item to trade
+ if(sender.LoggedinUser.TradingWith != null)
+ {
+ sender.LoggedinUser.MetaPriority = true;
+ metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildTradeAdd(sender.LoggedinUser.TradingWith));
+ sender.SendPacket(metaPacket);
+ }
+ break;
+ case "59": // Done
+ if (sender.LoggedinUser.TradingWith != null)
+ {
+ sender.LoggedinUser.TradingWith.Stage = "DONE";
+
+ if (sender.LoggedinUser.TradingWith.OtherTrade.Trader.MetaPriority == false)
+ UpdateArea(sender.LoggedinUser.TradingWith.OtherTrade.Trader.LoggedinClient);
+ UpdateArea(sender);
+
+ }
+ break;
case "60": // Ranch Sell
sender.LoggedinUser.MetaPriority = true;
metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildRanchSellConfirmation());
@@ -3874,6 +4011,9 @@ namespace HISP.Server
}
}
+ if (loggedInUser.TradingWith != null)
+ loggedInUser.TradingWith.CancelTradeMoved();
+
byte[] moveResponse = PacketBuilder.CreateMovementPacket(loggedInUser.X, loggedInUser.Y, loggedInUser.CharacterId, loggedInUser.Facing, direction, true);
sender.SendPacket(moveResponse);
}
@@ -6193,6 +6333,13 @@ namespace HISP.Server
return;
}
+ if(forClient.LoggedinUser.TradingWith != null)
+ {
+ forClient.LoggedinUser.MetaPriority = true;
+ byte[] tradeMeta = PacketBuilder.CreateMetaPacket(Meta.BuildTrade(forClient.LoggedinUser.TradingWith));
+ forClient.SendPacket(tradeMeta);
+ return;
+ }
forClient.LoggedinUser.MetaPriority = false;
diff --git a/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs b/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs
index 81f2ff8..3757570 100755
--- a/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs
+++ b/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs
@@ -52,7 +52,9 @@ namespace HISP.Server
public const byte PACKET_AUCTION = 0x24;
public const byte PACKET_PLAYER_INTERACTION = 0x2A;
- public const byte PLAYER_INTERACTION_TRADE = 0x31;
+ public const byte PLAYER_INTERACTION_TRADE = 0x28;
+ public const byte PLAYER_INTERACTION_ADD_ITEM = 0x29;
+ public const byte PLAYER_INTERACTION_TRADE_REJECT = 0x2B;
public const byte AUCTION_BID_100 = 0x29;
public const byte AUCTION_BID_1K = 0x2A;