public List <ItemSchema.ItemDBSchema> GetUserInventory(string userName) { var queryRequest = new QueryRequest() .Statement("SELECT meta(`FarmWorld`).id, * FROM FarmWorld WHERE userName=$1 AND uniqueName IS NOT MISSING;") .AddPositionalParameter(userName) .ScanConsistency(ScanConsistency.RequestPlus); var result = _bucket.Query <dynamic>(queryRequest); if (!result.Success) { Console.WriteLine(String.Format("Getting items for user {0} failed with error {1}.", userName, result.Errors)); return(null); } List <ItemSchema.ItemDBSchema> ret = new List <ItemSchema.ItemDBSchema>(result.Rows.Count); foreach (var row in result.Rows) { Newtonsoft.Json.Linq.JObject itemJson = row.GetValue("FarmWorld"); string id = row.GetValue("id"); ItemSchema.ItemDBSchema item = new ItemSchema.ItemDBSchema(); item.id = id; item.quantity = itemJson.Value <int>("quantity"); item.uniqueName = itemJson.Value <string>("uniqueName"); item.userName = itemJson.Value <string>("userName"); ret.Add(item); } return(ret); }
public static ItemSchema.ItemDBSchema ItemPerHit(IMineableSubMineableType subType, string userName) { var item = new ItemSchema.ItemDBSchema(); if (subType.Value == ObjectSchema.ObjectTypes.IMineableSubMineableType.OAK.Value) { item.uniqueName = ItemSchema.ItemNames.Wood.Value; } else if (subType.Value == ObjectSchema.ObjectTypes.IMineableSubMineableType.IRON.Value) { item.uniqueName = ItemSchema.ItemNames.Ore.Value; } else if (subType.Value == ObjectSchema.ObjectTypes.IMineableSubMineableType.STONE.Value) { item.uniqueName = ItemSchema.ItemNames.Ore.Value; } else { throw new ArgumentException(String.Format("subType not recignized {0}", subType.Value)); } item.userName = userName; item.quantity = 1; return(item); }
void OnEndMiningPacketReceived(Packet.EndMining em, NetPeer peer) { Packet.EndMining emCopy = em.Copy(); try { ValidatePacket(emCopy); } catch (ArgumentException ex) { Console.WriteLine(String.Format("Failed to validate packet in OnEndMiningPacketReceived from {0}: {1}", peer.EndPoint, ex.ToString())); return; } var p = _connectedPlayers[emCopy.userName]; // Add item to user inventory var item = new ItemSchema.ItemDBSchema(); if (p.miningState.minableSubType == ObjectSchema.ObjectTypes.IMineableSubMineableType.OAK.Value) { item.uniqueName = ItemSchema.ItemNames.Wood.Value; } else if (p.miningState.minableSubType == ObjectSchema.ObjectTypes.IMineableSubMineableType.IRON.Value) { item.uniqueName = ItemSchema.ItemNames.Ore.Value; } else if (p.miningState.minableSubType == ObjectSchema.ObjectTypes.IMineableSubMineableType.STONE.Value) { item.uniqueName = ItemSchema.ItemNames.Ore.Value; } else { throw new ArgumentException(String.Format("smCopy.minableType type {0} not recognized.", p.miningState.minableSubType)); } item.userName = p._userName; item.quantity = p.miningState.minedInSession; _db.AddToUserInventory(item); SendInventoryToPlayer(p); // Send inventory to player. if (!_db.Unlock(emCopy.id)) // Unlock object in database. { throw new Exception(String.Format("Failed to unlock mining object id '{0}' started mining by '{1}', this should never happen. Did object get unlocked somewhere else?", emCopy.id, emCopy.userName)); } // TODO: Update object quantity in db. // TODO: Validate that player isn't cheating. AddXPToPlayerAndSendReceivedXP(p, GameStatistics.GameStatistics.XpForMining(p.miningState.minableSubType, "MEDIUM")); // TODO: Add size. p.EndMining(emCopy.id); SendToAllOtherPlayers(em.userName, Write <Packet.EndMining>(em)); }
void OnFishCaughtPacketReceived(Packet.FishCaught fw, NetPeer peer) { var fwCopy = fw.Copy(); try { ValidatePacket(fwCopy); } catch (ArgumentException ex) { Console.WriteLine(String.Format("Failed to validate packet in OnFishSuccessfulCatchPacketReceived from {0}: {1}", peer.EndPoint, ex.ToString())); return; } var p = _connectedPlayers[fwCopy.userName]; if (!fwCopy.success) { p.FishUnsuccessfulCatch(); SendToAllPlayers(this.Write(new Packet.FishCaught { userName = p._userName, success = false })); return; } p.FishSuccessfulCatch(); var item = new ItemSchema.ItemDBSchema(); item.uniqueName = ItemSchema.ItemNames.Herring.Value; item.userName = p._userName; item.quantity = 1; _db.AddToUserInventory(item); SendToAllPlayers(this.Write(new Packet.FishCaught { userName = p._userName, success = false, fishItem = item })); SendInventoryToPlayer(p); }
public void AddToUserInventory(ItemSchema.ItemDBSchema item) { var queryRequest = new QueryRequest() .Statement("SELECT meta(`FarmWorld`).id, * FROM `FarmWorld` WHERE userName=$1 AND uniqueName=$2") .AddPositionalParameter(item.userName) .AddPositionalParameter(item.uniqueName); var result = _bucket.Query <dynamic>(queryRequest); if (!result.Success) { throw new Exception(String.Format("AddToUserInventory initial queryRequest failed: {0}", result.Status)); } if (result.Rows.Count > 1) { throw new Exception(String.Format("AddToUserInventory initial query returned more than 1 row for uuesr {0} item {1}", item.userName, item.uniqueName)); } if (result.Rows.Count == 0) // TODO: Potential race here if 2 items are added at same time on an item that did not exist before. { var idResult = _bucket.Increment("UserItemInventoryCounter"); if (!idResult.Success) { Console.WriteLine("Failed to get next increment for UserItemInventoryCounter."); return; } var document = new Document <dynamic> { Id = "item" + idResult.Value.ToString(), Content = item }; var upsert = _bucket.Upsert(document); if (!upsert.Success) { throw new Exception(String.Format("Upserting item failed for user {0} and item {1} and quantity {2}", item.userName, item.uniqueName, item.quantity)); } } else { var row = result.Rows[0]; string id = row.GetValue("id"); var lockResult = _bucket.GetAndLock <dynamic>(id, 1); // TODO: Implement wait and retry. if (!lockResult.Success) { if (lockResult.Status == Couchbase.IO.ResponseStatus.Locked) { Console.WriteLine(String.Format("Item with id {0} already DB locked for user {1}.", id, item.userName)); } else if (lockResult.Status == Couchbase.IO.ResponseStatus.KeyNotFound) { throw new Exception(String.Format("Locking item failed for user {0} and item {1} and quantity {2}", item.userName, item.uniqueName, item.quantity)); } else { throw new NotImplementedException(String.Format("Lock operation threw status {0} which is not handled on id {1}.", lockResult.Status, id)); } } Newtonsoft.Json.Linq.JObject obj = lockResult.Value; obj["quantity"] = item.quantity + obj.Value <int>("quantity"); IOperationResult replaceResult = _bucket.Replace(id, obj, lockResult.Cas); // This replaces the object and releases the DB lock. if (!replaceResult.Success) { throw new Exception(String.Format("Replace on item id '{0}' did not work: {1}.", id, replaceResult.Status)); } } }