/// <summary> /// Grabs the inventories of both users over both Trading and /// SteamAPI. /// </summary> protected void FetchInventories() { try { // [cmw] OtherItems and MyItems don't appear to be used... the should be removed. // fetch the other player's inventory othersItems = Inventory.GetInventory(OtherSID); if (othersItems == null || othersItems.success != "true") { throw new Exception("Could not fetch other player's inventory via Trading!"); } // fetch our inventory myItems = Inventory.GetInventory(MySteamId); if (myItems == null || myItems.success != "true") { throw new Exception("Could not fetch own inventory via Trading!"); } // fetch other player's inventory from the Steam API. OtherInventory = Inventory.FetchInventory(OtherSID.ConvertToUInt64(), apiKey); if (OtherInventory == null) { throw new Exception("Could not fetch other player's inventory via Steam API!"); } // fetch our inventory from the Steam API. myInventory = Inventory.FetchInventory(MySteamId.ConvertToUInt64(), apiKey); if (myInventory == null) { throw new Exception("Could not fetch own inventory via Steam API!"); } // check that the schema was already successfully fetched if (CurrentSchema == null) { throw new Exception("It seems the item schema was not fetched correctly!"); } if (OnAfterInit != null) { OnAfterInit(); } } catch (Exception e) { if (OnError != null) { OnError("I'm having a problem getting one of our backpacks. The Steam Community might be down. Ensure your backpack isn't private."); } else { throw new TradeException("I'm having a problem getting one of our backpacks. The Steam Community might be down. Ensure your backpack isn't private.", e); } } }
/// <summary> /// This updates the trade. This is called at an interval of a /// default of 800ms, not including the execution time of the /// method itself. /// </summary> /// <returns><c>true</c> if the other trade partner performed an action; otherwise <c>false</c>.</returns> public bool Poll() { bool otherDidSomething = false; if (!TradeStarted) { tradeStarted = true; // since there is no feedback to let us know that the trade // is fully initialized we assume that it is when we start polling. if (OnAfterInit != null) { OnAfterInit(); } } StatusObj status = GetStatus(); if (status == null) { throw new TradeException("The web command to get the trade status failed."); } // I've noticed this when the trade is cancelled. if (status.trade_status == 3) { if (OnError != null) { OnError("Trade was cancelled by other user."); } OtherUserCancelled = true; return(otherDidSomething); } if (status.events != null && numEvents != status.events.Length) { int numLoops = status.events.Length - numEvents; numEvents = status.events.Length; for (int i = numLoops; i > 0; i--) { int EventID; if (numLoops == 1) { EventID = numEvents - 1; } else { EventID = numEvents - i; } bool isBot = status.events [EventID].steamid == MySteamId.ConvertToUInt64().ToString(); /* * * Trade Action ID's * * 0 = Add item (itemid = "assetid") * 1 = remove item (itemid = "assetid") * 2 = Toggle ready * 3 = Toggle not ready * 4 * 5 * 6 * 7 = Chat (message = "text") * */ ulong itemID; switch (status.events [EventID].action) { case 0: itemID = (ulong)status.events [EventID].assetid; if (isBot) { steamMyOfferedItems.Add(itemID); ValidateSteamItemChanged(itemID, true); } else { OtherOfferedItems.Add(itemID); Inventory.Item item = OtherInventory.GetItem(itemID); Schema.Item schemaItem = CurrentSchema.GetItem(item.Defindex); OnUserAddItem(schemaItem, item); } break; case 1: itemID = (ulong)status.events [EventID].assetid; if (isBot) { steamMyOfferedItems.Remove(itemID); ValidateSteamItemChanged(itemID, false); } else { OtherOfferedItems.Remove(itemID); Inventory.Item item = OtherInventory.GetItem(itemID); Schema.Item schemaItem = CurrentSchema.GetItem(item.Defindex); OnUserRemoveItem(schemaItem, item); } break; case 2: if (!isBot) { otherIsReady = true; OnUserSetReady(true); } break; case 3: if (!isBot) { otherIsReady = false; OnUserSetReady(false); } break; case 4: if (!isBot) { OnUserAccept(); } break; case 7: if (!isBot) { OnMessage(status.events [EventID].text); } break; default: // Todo: add an OnWarning or similar event if (OnError != null) { OnError("Unkown Event ID: " + status.events [EventID].action); } break; } if (!isBot) { otherDidSomething = true; } } } // Update Local Variables if (status.them != null) { otherIsReady = status.them.ready == 1 ? true : false; meIsReady = status.me.ready == 1 ? true : false; } // Update version if (status.newversion) { Version = status.version; } if (status.logpos != 0) { LogPos = status.logpos; } return(otherDidSomething); }
/// <summary> /// This updates the trade. This is called at an interval of a /// default of 800ms, not including the execution time of the /// method itself. /// </summary> /// <returns><c>true</c> if the other trade partner performed an action; otherwise <c>false</c>.</returns> public bool Poll() { bool otherDidSomething = false; if (!TradeStarted) { TradeStarted = true; // since there is no feedback to let us know that the trade // is fully initialized we assume that it is when we start polling. if (OnAfterInit != null) { OnAfterInit(); } } TradeStatus status = RetryWebRequest(session.GetStatus); if (status == null) { return(false); } switch (status.trade_status) { // Nothing happened. i.e. trade hasn't closed yet. case 0: break; // Successful trade case 1: HasTradeCompletedOk = true; break; // All other known values (3, 4) correspond to trades closing. default: EnqueueAction(() => FireOnErrorEvent("Trade was closed by other user. Trade status: " + status.trade_status)); OtherUserCancelled = true; break; } if (status.newversion) { // handle item adding and removing session.Version = status.version; HandleTradeVersionChange(status); return(true); } else if (status.version > session.Version) { // oh crap! we missed a version update abort so we don't get // scammed. if we could get what steam thinks what's in the // trade then this wouldn't be an issue. but we can only get // that when we see newversion == true throw new TradeException("The trade version does not match. Aborting."); } // Update Local Variables if (status.them != null) { OtherIsReady = status.them.ready == 1; MeIsReady = status.me.ready == 1; OtherUserAccepted = status.them.confirmed == 1; } var events = status.GetAllEvents(); foreach (var tradeEvent in events) { if (eventList.Contains(tradeEvent)) { continue; } //add event to processed list, as we are taking care of this event now eventList.Add(tradeEvent); bool isBot = tradeEvent.steamid == MySteamId.ConvertToUInt64().ToString(); // dont process if this is something the bot did if (isBot) { continue; } otherDidSomething = true; switch ((TradeEventType)tradeEvent.action) { case TradeEventType.ItemAdded: EnqueueAction(() => FireOnUserAddItem(tradeEvent, MySteamId)); break; case TradeEventType.ItemRemoved: EnqueueAction(() => FireOnUserRemoveItem(tradeEvent)); break; case TradeEventType.CurrencyItemAdded: if (tradeEvent.amount == 0) { EnqueueAction(() => FireOnUserRemoveItem(tradeEvent)); } else { EnqueueAction(() => FireOnUserAddItem(tradeEvent, MySteamId)); } break; case TradeEventType.UserSetReady: EnqueueAction(() => OnUserSetReady(true)); break; case TradeEventType.UserSetUnReady: EnqueueAction(() => OnUserSetReady(false)); break; case TradeEventType.UserAccept: EnqueueAction(() => OnUserAccept()); break; case TradeEventType.UserChat: EnqueueAction(() => OnMessage(tradeEvent.text)); break; default: // Todo: add an OnWarning or similar event EnqueueAction(() => FireOnErrorEvent("Unknown Event ID: " + tradeEvent.action)); break; } } if (status.logpos != 0) { session.LogPos = status.logpos; } return(otherDidSomething); }
private bool HandleTradeOngoing(TradeStatus status) { if (status.newversion) { HandleTradeVersionChange(status); return(true); } else if (status.version > session.Version) { // oh crap! we missed a version update abort so we don't get // scammed. if we could get what steam thinks what's in the // trade then this wouldn't be an issue. but we can only get // that when we see newversion == true throw new TradeException("The trade version does not match. Aborting."); } // Update Local Variables if (status.them != null) { OtherIsReady = status.them.ready == 1; MeIsReady = status.me.ready == 1; OtherUserAccepted = status.them.confirmed == 1; //Similar to the logic Steam uses to determine whether or not to show the "waiting" spinner in the trade window otherUserTimingOut = (status.them.connection_pending || status.them.sec_since_touch >= 5); } bool otherUserDidSomething = false; var events = status.GetAllEvents(); foreach (var tradeEvent in events.OrderBy(o => o.timestamp)) { if (eventList.Contains(tradeEvent)) { continue; } //add event to processed list, as we are taking care of this event now eventList.Add(tradeEvent); bool isBot = tradeEvent.steamid == MySteamId.ConvertToUInt64().ToString(); // dont process if this is something the bot did if (isBot) { continue; } otherUserDidSomething = true; switch ((TradeEventType)tradeEvent.action) { case TradeEventType.ItemAdded: TradeUserAssets newAsset = new TradeUserAssets(tradeEvent.appid, tradeEvent.contextid, tradeEvent.assetid); if (!otherOfferedItems.Contains(newAsset)) { otherOfferedItems.Add(newAsset); FireOnUserAddItem(newAsset); } break; case TradeEventType.ItemRemoved: TradeUserAssets oldAsset = new TradeUserAssets(tradeEvent.appid, tradeEvent.contextid, tradeEvent.assetid); if (otherOfferedItems.Contains(oldAsset)) { otherOfferedItems.Remove(oldAsset); FireOnUserRemoveItem(oldAsset); } break; case TradeEventType.UserSetReady: OnUserSetReady(true); break; case TradeEventType.UserSetUnReady: OnUserSetReady(false); break; case TradeEventType.UserAccept: OnUserAccept(); break; case TradeEventType.UserChat: OnMessage(tradeEvent.text); break; default: throw new TradeException("Unknown event type: " + tradeEvent.action); } } if (status.logpos != 0) { session.LogPos = status.logpos; } return(otherUserDidSomething); }
/// <summary> /// This updates the trade. This is called at an interval of a /// default of 800ms, not including the execution time of the /// method itself. /// </summary> /// <returns><c>true</c> if the other trade partner performed an action; otherwise <c>false</c>.</returns> public bool Poll() { bool otherDidSomething = false; if (!TradeStarted) { tradeStarted = true; // since there is no feedback to let us know that the trade // is fully initialized we assume that it is when we start polling. if (OnAfterInit != null) { OnAfterInit(); } } StatusObj status = GetStatus(); if (status == null) { throw new TradeException("The web command to get the trade status failed."); } // I've noticed this when the trade is cancelled. if (status.trade_status == 3) { if (OnError != null) { OnError("Trade was cancelled by other user."); } OtherUserCancelled = true; return(otherDidSomething); } if (status.events != null) { foreach (TradeEvent trdEvent in status.events) { if (!eventList.Contains(trdEvent)) { eventList.Add(trdEvent);//add event to processed list, as we are taking care of this event now bool isBot = trdEvent.steamid == MySteamId.ConvertToUInt64().ToString(); /* * * Trade Action ID's * * 0 = Add item (itemid = "assetid") * 1 = remove item (itemid = "assetid") * 2 = Toggle ready * 3 = Toggle not ready * 4 * 5 * 6 * 7 = Chat (message = "text") * */ ulong itemID; switch ((TradeEventType)trdEvent.action) { case TradeEventType.ItemAdded: itemID = (ulong)trdEvent.assetid; if (isBot) { steamMyOfferedItems.Add(itemID); ValidateSteamItemChanged(itemID, true); Inventory.Item item = MyInventory.GetItem(itemID); Schema.Item schemaItem = CurrentSchema.GetItem(item.Defindex); } else { OtherOfferedItems.Add(itemID); Inventory.Item item = OtherInventory.GetItem(itemID); Schema.Item schemaItem = CurrentSchema.GetItem(item.Defindex); OnUserAddItem(schemaItem, item); } break; case TradeEventType.ItemRemoved: itemID = (ulong)trdEvent.assetid; if (isBot) { steamMyOfferedItems.Remove(itemID); ValidateSteamItemChanged(itemID, false); Inventory.Item item = MyInventory.GetItem(itemID); Schema.Item schemaItem = CurrentSchema.GetItem(item.Defindex); } else { OtherOfferedItems.Remove(itemID); Inventory.Item item = OtherInventory.GetItem(itemID); Schema.Item schemaItem = CurrentSchema.GetItem(item.Defindex); OnUserRemoveItem(schemaItem, item); } break; case TradeEventType.UserSetReady: if (!isBot) { otherIsReady = true; OnUserSetReady(true); } break; case TradeEventType.UserSetUnReady: if (!isBot) { otherIsReady = false; OnUserSetReady(false); } break; case TradeEventType.UserAccept: if (!isBot) { OnUserAccept(); } break; case TradeEventType.UserChat: if (!isBot) { OnMessage(trdEvent.text); } break; default: // Todo: add an OnWarning or similar event if (OnError != null) { OnError("Unknown Event ID: " + trdEvent.action); } break; } if (!isBot) { otherDidSomething = true; } } //if (!eventList.Contains(trdEvent)) } // foreach (TradeEvent trdEvent in status.events) } //if (status.events != null) // Update Local Variables if (status.them != null) { otherIsReady = status.them.ready == 1 ? true : false; meIsReady = status.me.ready == 1 ? true : false; } // Update version if (status.newversion) { Version = status.version; } if (status.logpos != 0) { LogPos = status.logpos; } return(otherDidSomething); }
/// <summary> /// This updates the trade. This is called at an interval of a /// default of 800ms, not including the execution time of the /// method itself. /// </summary> /// <returns><c>true</c> if the other trade partner performed an action; otherwise <c>false</c>.</returns> public bool Poll() { bool otherDidSomething = false; if (!TradeStarted) { tradeStarted = true; // since there is no feedback to let us know that the trade // is fully initialized we assume that it is when we start polling. if (OnAfterInit != null) { OnAfterInit(); } } TradeStatus status = session.GetStatus(); if (status == null) { throw new TradeException("The web command to get the trade status failed."); } switch (status.trade_status) { // Nothing happened. i.e. trade hasn't closed yet. case 0: break; // Successful trade case 1: HasTradeCompletedOk = true; return(otherDidSomething); // All other known values (3, 4) correspond to trades closing. default: if (OnError != null) { OnError("Trade was closed by other user. Trade status: " + status.trade_status); } OtherUserCancelled = true; return(otherDidSomething); } if (status.newversion) { // handle item adding and removing session.Version = status.version; TradeEvent trdEvent = status.GetLastEvent(); TradeEventType actionType = (TradeEventType)trdEvent.action; HandleTradeVersionChange(status); return(true); } else if (status.version > session.Version) { // oh crap! we missed a version update abort so we don't get // scammed. if we could get what steam thinks what's in the // trade then this wouldn't be an issue. but we can only get // that when we see newversion == true throw new TradeException("The trade version does not match. Aborting."); } var events = status.GetAllEvents(); foreach (var tradeEvent in events) { if (eventList.Contains(tradeEvent)) { continue; } //add event to processed list, as we are taking care of this event now eventList.Add(tradeEvent); bool isBot = tradeEvent.steamid == MySteamId.ConvertToUInt64().ToString(); // dont process if this is something the bot did if (isBot) { continue; } otherDidSomething = true; /* Trade Action ID's * 0 = Add item (itemid = "assetid") * 1 = remove item (itemid = "assetid") * 2 = Toggle ready * 3 = Toggle not ready * 4 = ? * 5 = ? - maybe some sort of cancel * 6 = ? * 7 = Chat (message = "text") */ switch ((TradeEventType)tradeEvent.action) { case TradeEventType.ItemAdded: FireOnUserAddItem(tradeEvent); break; case TradeEventType.ItemRemoved: FireOnUserRemoveItem(tradeEvent); break; case TradeEventType.UserSetReady: otherIsReady = true; OnUserSetReady(true); break; case TradeEventType.UserSetUnReady: otherIsReady = false; OnUserSetReady(false); break; case TradeEventType.UserAccept: OnUserAccept(); break; case TradeEventType.UserChat: OnMessage(tradeEvent.text); break; default: // Todo: add an OnWarning or similar event if (OnError != null) { OnError("Unknown Event ID: " + tradeEvent.action); } break; } } // Update Local Variables if (status.them != null) { otherIsReady = status.them.ready == 1; meIsReady = status.me.ready == 1; } if (status.logpos != 0) { session.LogPos = status.logpos; } return(otherDidSomething); }
/// <summary> /// This updates the trade. This is called at an interval of a /// default of 800ms, not including the execution time of the /// method itself. /// </summary> public void Poll() { if (!TradeStarted) { tradeStarted = true; tradeStartTime = DateTime.Now; lastOtherActionTime = DateTime.Now; } StatusObj status = GetStatus(); if (status == null) { throw new TradeException("The web command to get the trade status failed."); } // I've noticed this when the trade is cancelled. if (status.trade_status == 3) { if (OnError != null) { OnError("Trade was cancelled by other user."); } OtherUserCancelled = true; return; } if (status.events != null && numEvents != status.events.Length) { int numLoops = status.events.Length - numEvents; numEvents = status.events.Length; for (int i = numLoops; i > 0; i--) { int EventID; if (numLoops == 1) { EventID = numEvents - 1; } else { EventID = numEvents - i; } bool isBot = status.events [EventID].steamid == MySteamId.ConvertToUInt64().ToString(); /* * * Trade Action ID's * * 0 = Add item (itemid = "assetid") * 1 = remove item (itemid = "assetid") * 2 = Toggle ready * 3 = Toggle not ready * 4 * 5 * 6 * 7 = Chat (message = "text") * */ ulong itemID; switch (status.events [EventID].action) { case 0: itemID = (ulong)status.events [EventID].assetid; if (isBot) { steamMyOfferedItems.Add(itemID); ValidateSteamItemChanged(itemID, true); } else { OtherOfferedItems.Add(itemID); Inventory.Item item = OtherInventory.GetItem(itemID); Schema.Item schemaItem = CurrentSchema.GetItem(item.Defindex); OnUserAddItem(schemaItem, item); } break; case 1: itemID = (ulong)status.events [EventID].assetid; if (isBot) { steamMyOfferedItems.Remove(itemID); ValidateSteamItemChanged(itemID, false); } else { OtherOfferedItems.Remove(itemID); Inventory.Item item = OtherInventory.GetItem(itemID); Schema.Item schemaItem = CurrentSchema.GetItem(item.Defindex); OnUserRemoveItem(schemaItem, item); } break; case 2: if (!isBot) { otherIsReady = true; OnUserSetReady(true); } break; case 3: if (!isBot) { otherIsReady = false; OnUserSetReady(false); } break; case 4: if (!isBot) { OnUserAccept(); } break; case 7: if (!isBot) { OnMessage(status.events [EventID].text); } break; default: // Todo: add an OnWarning or similar event if (OnError != null) { OnError("Unkown Event ID: " + status.events [EventID].action); } break; } if (!isBot) { lastOtherActionTime = DateTime.Now; } } } else { // check if the user is AFK var now = DateTime.Now; DateTime actionTimeout = lastOtherActionTime.AddSeconds(MaximumActionGap); int untilActionTimeout = (int)Math.Round((actionTimeout - now).TotalSeconds); DateTime tradeTimeout = TradeStartTime.AddSeconds(MaximumTradeTime); int untilTradeTimeout = (int)Math.Round((tradeTimeout - now).TotalSeconds); if (untilActionTimeout <= 0 || untilTradeTimeout <= 0) { if (OnTimeout != null) { OnTimeout(); } CancelTrade(); } else if (untilActionTimeout <= 15 && untilActionTimeout % 5 == 0) { SendMessageWebCmd("Are You AFK? The trade will be canceled in " + untilActionTimeout + " seconds if you don't do something."); } } // Update Local Variables if (status.them != null) { otherIsReady = status.them.ready == 1 ? true : false; meIsReady = status.me.ready == 1 ? true : false; } // Update version if (status.newversion) { Version = status.version; } if (status.logpos != 0) { LogPos = status.logpos; } }