/// <summary> /// Attempts to remove the item from the server, if the ticket doesn't exist on the servers side due to it timing out and such then /// it will not be removed. /// </summary> /// <returns><c>true</c>, if item from server was removed, <c>false</c> otherwise.</returns> /// <param name="ticket">Ticket.</param> public bool RemoveItemFromServer(ItemTicket ticket) { // Ensure the ticket is both valid to prevent wasting the servers time if (ticket && ticket.IsValid() && ticket == m_itemRequestResponse) { if (Network.isServer) { PropagateRemovalAtIndex(ticket); } else { networkView.RPC("PropagateRemovalAtIndex", RPCMode.Server, ticket.uniqueID, ticket.itemID, ticket.itemIndex); } // Reset the response to maintain security of the inventory ResetResponse(false); // Transaction completed successfully return(true); } // If this point has been reached then a problem has occurred Debug.LogError(name + ": NetworkInventory.RemoveItemFromServer() transaction failed."); ResetResponse(false); return(false); }
/// <summary> /// Attempts to add an item to the inventory, note if you haven't been given express permission from your latest request this will fail. /// Also it's worth noting that the return value doesn't mean the server will definitely add the item, if any error occurs it will not exist. /// </summary> /// <returns><c>true</c>, if the transaction goes through, <c>false</c> otherwise.</returns> /// <param name="ticket">The ticket given by the server which authorises your transaction.</param> public bool AddItemToServer(ItemTicket ticket) { // Check the item exists and whether the transaction has been authorised if (ticket && ticket.IsValid() && ticket == m_itemAddResponse) { // Unity silliness again if (Network.isServer) { ServerAddItem(ticket); } else { networkView.RPC("ServerAddItem", RPCMode.Server, ticket.uniqueID, ticket.itemID, ticket.itemIndex); } // Reset the response to ensure the security of future transactions ResetResponse(false); // Transaction processed successfully return(true); } // If this point has been reached then a problem has occurred Debug.LogError(name + ".NetworkInventory.AddItemToServer() transaction failed."); ResetResponse(false); return(false); }
// Used to ensure the validity of a ticket just before handing it in public void RequestTicketValidityCheck(ItemTicket ticket) { if (ticket && ticket.IsValid()) { // Reset the response, don't call the function otherwise it will break AddItemToServer() and RemoveItemFromServer() m_hasServerResponded = false; m_ticketValidityResponse = false; // All that needs to be done is just contact the server to find out if the ticket still exists in the list if (Network.isServer) { TicketValidityCheck(ticket, m_blankMessage); } else { networkView.RPC("TicketValidityCheck", RPCMode.Server, ticket.uniqueID, ticket.itemID, ticket.itemIndex); } } else { ResetResponse(true); } }
// Used to perform a synchronised removal void PropagateRemovalAtIndex(ItemTicket ticket) { //Debug.Log(ticket.ToString()); if (ticket.IsValid()) { // The correct index is guaranteed for the clients so only determine it for the server int index = Network.isServer ? DetermineTicketIndex(ticket) : ticket.itemIndex; //Debug.Log("Index: " + index); // Check if it is valid if (IsValidIndex(index)) { // Remove or null the item based on the passed parameter if (m_nullRemovedItems) { m_inventory[index] = null; m_isItemRequested[index] = false; } else { //Debug.Log("Removing at: " + index); m_inventory.RemoveAt(index); m_isItemRequested.RemoveAt(index); // Reset the ticket so the expiration coroutine knows it has been removed m_requestTickets.RemoveAt(index); } // Propagate the change to the clients if (Network.isServer) { // Give clients the correct index ticket.itemIndex = index; // Propagate the removal Debug.Log("Sending removal notification to others."); networkView.RPC("PropagateRemovalAtIndex", RPCMode.Others, ticket.uniqueID, ticket.itemID, ticket.itemIndex); } } else { Debug.LogError("Attempt to remove an item from " + name + " with an invalid or expired ticket."); } } }
void ServerAddItem(ItemTicket ticket) { if (ticket.IsValid()) { // Attempt to find the first null value, if a position hasn't been specified if (m_nullRemovedItems && !IsValidIndex(ticket.itemIndex)) { ticket.itemIndex = FindFirstNull(); } // Finally propagate the addition PropagateItemAtIndex(ticket.itemIndex, ticket.itemID); } else { Debug.LogError("Attempt to add item with invalid or expired ticket in " + name + ".NetworkInventory"); } }
// An ItemTicket version is provided to increase performance as items time out. void RequestCancel(ItemTicket ticket) { if (ticket.IsValid()) { // If the index is invalid we know that the ticket is an add request if (!IsValidIndex(ticket.itemIndex)) { --addRequests; } else { // The index of the cancellation int index = DetermineTicketIndex(ticket); // Attempt to cancel the ticket if (IsValidIndex(index)) { // Reset the ticket m_requestTickets[index].Reset(); m_isItemRequested[index] = false; // Check to see if the desired index was a null item, this means that it was an add requests if (!m_inventory[index]) { --addRequests; } } else { Debug.LogError("An attempt was made to cancel a request which doesn't exist in " + name + ".NetworkInventory."); } } } else { Debug.LogError("Attempt to cancel invalid ticket in " + name + ".NetworkInventory"); } }
// Causes the server to cancel a request so that others can request the item public void RequestServerCancel(ItemTicket ticket) { Debug.Log("Cancelling ticket: " + ticket); // Ensure we are not wasting time by checking if the ticket is valid if (ticket && ticket.IsValid()) { if (Network.isServer) { RequestCancel(ticket); } else { networkView.RPC("RequestCancel", RPCMode.Server, ticket.uniqueID, ticket.itemID, ticket.itemIndex); } } // Reset the response since we know they've received it ResetResponse(false); }
// This function should be called using Invoke() after the desired period of time IEnumerator ExpireItemTicket(ItemTicket toExpire, float timeToWait) { //Debug.Log("Waiting to expire ticket: " + toExpire + " in " + timeToWait); // Wait for the desired amount of time yield return(new WaitForSeconds(timeToWait)); // Tickets which have been redeemed will be reset to the standard ticket if (toExpire.IsValid()) { // Only the server needs to manage whether the item is flagged as requested or not if (Network.isServer) { // Obtain the index int index = DetermineTicketIndex(toExpire); // Flag the item as unrequested if (IsValidIndex(index)) { // Reset the request m_isItemRequested[index] = false; } // Must be an add request else { --addRequests; } } // Reset the ticket to ensure it's invalid toExpire.Reset(); Debug.Log("Expiring ItemTicket: " + toExpire.uniqueID + " / " + toExpire.itemID + " / " + toExpire.itemIndex); } }