Ejemplo n.º 1
0
        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);
                });
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
                }
            });
        }
Ejemplo n.º 4
0
        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);
            }
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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);
        }