public void MoveToInventory(VM vm, VMMultitileGroup obj, VMAsyncInventorySaveCallback callback, bool runSync) { var objectPID = obj.BaseObject.PersistID; var objb = obj.BaseObject; uint guid = objb.Object.OBJ.GUID; if (objb.MasterDefinition != null) { guid = objb.MasterDefinition.GUID; } var isNew = objectPID == 0; var state = new VMStandaloneObjectMarshal(obj); var dbState = GenerateObjectPersist(obj); dbState.lot_id = null; //we're removing this object from the lot if (runSync) { SaveInventoryState(isNew, objectPID, state, dbState, guid, callback, true); } else { Host.InBackground(() => { SaveInventoryState(isNew, objectPID, state, dbState, guid, callback, false); }); } }
private VMMultitileGroup CreateObjGroup(VMEODSecureTradeObject item) { var data = item.Data; VMStandaloneObjectMarshal state = null; if (data != null) { state = new VMStandaloneObjectMarshal(); try { using (var reader = new BinaryReader(new MemoryStream(data))) { state.Deserialize(reader); } foreach (var e in state.Entities) { ((VMGameObjectMarshal)e).Disabled = 0; } } catch (Exception) { //failed to restore state state = null; } } VMMultitileGroup BuyItem; if (state != null) { BuyItem = state.CreateInstance(LotController.vm, true); BuyItem.ChangePosition(LotView.Model.LotTilePos.OUT_OF_WORLD, LotView.Model.Direction.NORTH, LotController.vm.Context, VMPlaceRequestFlags.UserPlacement); if (BuyItem.Objects.Count == 0) { BuyItem = null; } } else { BuyItem = LotController.vm.Context.CreateObjectInstance(item.GUID, LotView.Model.LotTilePos.OUT_OF_WORLD, LotView.Model.Direction.NORTH, true); if (BuyItem == null || BuyItem.Objects.Count == 0) { BuyItem = null; return(null); //uh } } return(BuyItem); }
public void PurchaseFromOwner(VM vm, VMMultitileGroup obj, uint purchaserPID, VMAsyncInventorySaveCallback callback, VMAsyncTransactionCallback tcallback) { var objectPID = obj.BaseObject.PersistID; var objb = obj.BaseObject; uint guid = objb.Object.OBJ.GUID; if (objb.MasterDefinition != null) { guid = objb.MasterDefinition.GUID; } var isNew = objectPID == 0; var state = new VMStandaloneObjectMarshal(obj); var dbState = GenerateObjectPersist(obj); var salePrice = obj.SalePrice; var owner = ((VMTSOObjectState)objb.TSOState).OwnerID; //object will stay on lot for now. Host.InBackground(() => { using (var da = DAFactory.Get()) { SaveInventoryState(isNew, objectPID, state, dbState, guid, (bool success, uint objPID) => { if (success) { //todo: transaction-ify this whole thing? might need a large scale rollback... var tresult = da.Avatars.Transaction(purchaserPID, owner, salePrice, 0); if (tresult == null) { tresult = new Database.DA.Avatars.DbTransactionResult() { success = false } } ; //update the budgets of the respective characters. var finalAmount = salePrice; tcallback(tresult.success, tresult.amount, purchaserPID, (uint)tresult.source_budget, owner, (uint)tresult.dest_budget); if (tresult.success) { dbState.owner_id = purchaserPID; dbState.lot_id = null; da.Objects.UpdatePersistState(objPID, dbState); //perform the final object transfer. todo: logging callback(true, objPID); } else { callback(false, objPID); } } else { callback(false, objPID); } }, true); } }); }
private void SaveInventoryState(bool isNew, uint objectPID, VMStandaloneObjectMarshal state, DbObject dbState, uint guid, VMAsyncInventorySaveCallback callback, bool runSync) { try { if (isNew) { try { using (var db = DAFactory.Get()) { dbState.type = guid; dbState.shard_id = Context.ShardId; var id = db.Objects.Create(dbState); dbState.object_id = id; objectPID = id; } } catch (Exception) { callback(false, objectPID); } } var objStr = objectPID.ToString("x8"); //make sure this exists Directory.CreateDirectory(Path.Combine(Config.SimNFS, "Objects/" + objStr + "/")); byte[] data; using (var stream = new MemoryStream()) { var writer = new BinaryWriter(stream); state.SerializeInto(writer); data = stream.ToArray(); } var file = File.Open(Path.Combine(Config.SimNFS, "Objects/" + objStr + "/inventoryState.fsoo"), FileMode.Create); if (runSync) { file.Write(data, 0, data.Length); using (var db = DAFactory.Get()) { //todo: race where inventory object could potentially be placed on the lot before the old instance of it is deleted //probably just block objects with same persist id from being placed. db.Objects.UpdatePersistState(objectPID, dbState); callback(true, objectPID); } file.Close(); } else { file.WriteAsync(data, 0, data.Length).ContinueWith((x) => { using (var db = DAFactory.Get()) { db.Objects.UpdatePersistState(objectPID, dbState); callback(true, objectPID); } file.Close(); }); } } catch (Exception e) { //todo: specific types of exception that can be thrown here? instead of just catching em all LOG.Error(e, "Failed to save inventory state for object " + objectPID.ToString("x8") + "!"); callback(false, objectPID); } }
private bool TryPlace(VM vm, VMAvatar caller) { if (!vm.TSOState.CanPlaceNewUserObject(vm)) { return(false); } VMStandaloneObjectMarshal state; if ((Data?.Length ?? 0) == 0) { state = null; } else { state = new VMStandaloneObjectMarshal(); try { using (var reader = new BinaryReader(new MemoryStream(Data))) { state.Deserialize(reader); } foreach (var e in state.Entities) { ((VMGameObjectMarshal)e).Disabled = 0; } } catch (Exception) { //failed to restore state state = null; } } if (state != null) { CreatedGroup = state.CreateInstance(vm); CreatedGroup.ChangePosition(new LotTilePos(x, y, level), dir, vm.Context, VMPlaceRequestFlags.UserPlacement); if (CreatedGroup.Objects.Count == 0) { return(false); } if (CreatedGroup.BaseObject.Position == LotTilePos.OUT_OF_WORLD) { return(false); } } else { var catalog = Content.Content.Get().WorldCatalog; var item = catalog.GetItemByGUID(GUID); CreatedGroup = vm.Context.CreateObjectInstance(GUID, LotTilePos.OUT_OF_WORLD, dir); if (CreatedGroup == null) { return(false); } CreatedGroup.ChangePosition(new LotTilePos(x, y, level), dir, vm.Context, VMPlaceRequestFlags.UserPlacement); CreatedGroup.ExecuteEntryPoint(11, vm.Context); //User Placement if (CreatedGroup.Objects.Count == 0) { return(false); } if (CreatedGroup.BaseObject.Position == LotTilePos.OUT_OF_WORLD) { return(false); } } foreach (var obj in CreatedGroup.Objects) { if (obj is VMGameObject) { ((VMTSOObjectState)obj.TSOState).OwnerID = caller.PersistID; } obj.PersistID = ObjectPID; ((VMGameObject)obj).DisableIfTSOCategoryWrong(vm.Context); } vm.Context.ObjectQueries.RegisterMultitilePersist(CreatedGroup, ObjectPID); //is this my sim's object? try remove it from our local inventory representaton if (((VMTSOObjectState)CreatedGroup.BaseObject.TSOState).OwnerID == vm.MyUID) { var index = vm.MyInventory.FindIndex(x => x.ObjectPID == ObjectPID); if (index != -1) { vm.MyInventory.RemoveAt(index); } } vm.SignalChatEvent(new VMChatEvent(caller.PersistID, VMChatEventType.Arch, caller.Name, vm.GetUserIP(caller.PersistID), "placed (from inventory) " + CreatedGroup.BaseObject.ToString() + " at (" + x / 16f + ", " + y / 16f + ", " + level + ")" )); return(true); }
private bool TryPlace(VM vm, VMAvatar caller) { var internalMode = caller == null; if (Mode != PurchaseMode.Donate && !vm.PlatformState.CanPlaceNewUserObject(vm)) { return(false); } if (Mode == PurchaseMode.Donate && !vm.PlatformState.CanPlaceNewDonatedObject(vm)) { return(false); } VMStandaloneObjectMarshal state; var catalog = Content.Content.Get().WorldCatalog; var item = catalog.GetItemByGUID(Info.GUID); if (caller != null && (item?.DisableLevel ?? 0) > 2) { //object cannot be placed (disable level 3) return(false); } if ((Info.Data?.Length ?? 0) == 0) { state = null; } else { state = new VMStandaloneObjectMarshal(); try { using (var reader = new BinaryReader(new MemoryStream(Info.Data))) { state.Deserialize(reader); } foreach (var e in state.Entities) { ((VMGameObjectMarshal)e).Disabled = 0; } } catch (Exception) { //failed to restore state state = null; } } if (state != null) { CreatedGroup = state.CreateInstance(vm, false); CreatedGroup.ChangePosition(new LotTilePos(x, y, level), dir, vm.Context, VMPlaceRequestFlags.UserPlacement); CreatedGroup.ExecuteEntryPoint(11, vm.Context); //User Placement if (CreatedGroup.Objects.Count == 0) { return(false); } if (CreatedGroup.BaseObject.Position == LotTilePos.OUT_OF_WORLD && !internalMode) { return(false); } } else { CreatedGroup = vm.Context.CreateObjectInstance(Info.GUID, LotTilePos.OUT_OF_WORLD, dir); if (CreatedGroup == null) { return(false); } CreatedGroup.ChangePosition(new LotTilePos(x, y, level), dir, vm.Context, VMPlaceRequestFlags.UserPlacement); CreatedGroup.ExecuteEntryPoint(11, vm.Context); //User Placement if (CreatedGroup.Objects.Count == 0) { return(false); } if (CreatedGroup.BaseObject.Position == LotTilePos.OUT_OF_WORLD && !internalMode) { return(false); } } foreach (var obj in CreatedGroup.Objects) { var tsostate = (obj.PlatformState as VMTSOObjectState); if (tsostate != null) { if (caller != null) { tsostate.OwnerID = caller.PersistID; } bool reinitRequired = false; if (Info.UpgradeLevel > tsostate.UpgradeLevel) { tsostate.UpgradeLevel = Info.UpgradeLevel; reinitRequired = true; } obj.UpdateTuning(vm); if (reinitRequired) { VMNetUpgradeCmd.TryReinit(obj, vm, tsostate.UpgradeLevel); } } obj.PersistID = ObjectPID; ((VMGameObject)obj).DisableIfTSOCategoryWrong(vm.Context); } vm.Context.ObjectQueries.RegisterMultitilePersist(CreatedGroup, ObjectPID); //is this my sim's object? try remove it from our local inventory representaton if (((VMTSOObjectState)CreatedGroup.BaseObject.TSOState).OwnerID == vm.MyUID && Info.RestoreType != VMInventoryRestoreType.CopyOOW) { var index = vm.MyInventory.FindIndex(x => x.ObjectPID == ObjectPID); if (index != -1) { vm.MyInventory.RemoveAt(index); } } if (Mode == PurchaseMode.Donate) { //this object should be donated. (CreatedGroup.BaseObject.TSOState as VMTSOObjectState).Donate(vm, CreatedGroup.BaseObject); } if (caller != null) { vm.SignalChatEvent(new VMChatEvent(caller, VMChatEventType.Arch, caller.Name, vm.GetUserIP(caller.PersistID), "placed (from inventory) " + CreatedGroup.BaseObject.ToString() + " at (" + x / 16f + ", " + y / 16f + ", " + level + ")" )); } return(true); }