mirror of
https://github.com/riperiperi/FreeSO
synced 2026-08-13 20:26:13 -04:00
155 lines
6.3 KiB
C#
155 lines
6.3 KiB
C#
using System.IO;
|
|
using FSO.SimAntics.Model;
|
|
using FSO.SimAntics.Model.TSOPlatform;
|
|
using FSO.SimAntics.Model.Platform;
|
|
|
|
namespace FSO.SimAntics.NetPlay.Model.Commands
|
|
{
|
|
public class VMNetDeleteObjectCmd : VMNetCommandBodyAbstract
|
|
{
|
|
public short ObjectID;
|
|
public uint ObjectPID;
|
|
public bool CleanupAll;
|
|
public bool Verified;
|
|
public bool Success;
|
|
|
|
public DeleteMode Mode = DeleteMode.Delete;
|
|
|
|
public override bool Execute(VM vm, VMAvatar caller)
|
|
{
|
|
if (Mode == DeleteMode.Delete)//ObjectPID == 0) //only has value when this is an inventory move.
|
|
{
|
|
VMEntity obj = vm.GetObjectById(ObjectID);
|
|
if (obj == null || (!vm.TS1 && caller == null)) return false;
|
|
var value = (obj.PersistID != 0 || vm.TS1) ? obj.MultitileGroup.Price : 0;
|
|
|
|
obj.ExecuteEntryPoint(12, vm.Context, true);
|
|
obj.Delete(CleanupAll, vm.Context);
|
|
|
|
// If we're the server, tell the global link to give their money back.
|
|
if (vm.GlobalLink != null)
|
|
{
|
|
vm.GlobalLink.PerformTransaction(vm, false, uint.MaxValue, caller?.PersistID ?? uint.MaxValue,
|
|
value,
|
|
(bool success, int transferAmount, uint uid1, uint budget1, uint uid2, uint budget2) =>
|
|
{
|
|
|
|
});
|
|
}
|
|
vm.SignalChatEvent(new VMChatEvent(caller, VMChatEventType.Arch,
|
|
caller?.Name ?? "Unknown",
|
|
vm.GetUserIP(caller?.PersistID ?? 0),
|
|
"deleted " + obj.ToString()
|
|
));
|
|
}
|
|
else
|
|
{
|
|
//inventory move. Just delete the object.
|
|
VMEntity obj = vm.GetObjectByPersist(ObjectPID);
|
|
if (obj == null) return false;
|
|
|
|
if (Success)
|
|
{
|
|
if (((VMTSOObjectState)obj.TSOState).OwnerID == vm.MyUID)
|
|
{
|
|
//if the owner is here, tell them this object is now in their inventory.
|
|
//if they're elsewhere, they'll see it the next time their inventory updates.
|
|
//Inventory accesses are not by index, but PID, and straight to DB... so this won't cause any race conditions.
|
|
vm.MyInventory.Add(new VMInventoryItem()
|
|
{
|
|
ObjectPID = ObjectPID,
|
|
GUID = (obj.MasterDefinition?.GUID) ?? obj.Object.OBJ.GUID,
|
|
Name = obj.MultitileGroup.Name,
|
|
Value = (uint)obj.MultitileGroup.Price,
|
|
Graphic = (ushort)obj.GetValue(VMStackObjectVariable.Graphic),
|
|
DynFlags1 = obj.DynamicSpriteFlags,
|
|
DynFlags2 = obj.DynamicSpriteFlags2,
|
|
});
|
|
}
|
|
vm.Context.ObjectQueries.RemoveMultitilePersist(vm, obj.PersistID);
|
|
foreach (var o in obj.MultitileGroup.Objects) o.PersistID = 0; //no longer representative of the object in db.
|
|
obj.Delete(CleanupAll, vm.Context);
|
|
|
|
vm.SignalChatEvent(new VMChatEvent(caller, VMChatEventType.Arch,
|
|
caller?.Name ?? "disconnected user",
|
|
vm.GetUserIP(caller.PersistID),
|
|
"sent " + obj.ToString() + " back to the inventory of its owner."
|
|
));
|
|
} else
|
|
{
|
|
//something bad happened. just unlock the object.
|
|
foreach (var o in obj.MultitileGroup.Objects)
|
|
((VMGameObject)o).Disabled &= VMGameObjectDisableFlags.TransactionIncomplete;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override bool Verify(VM vm, VMAvatar caller)
|
|
{
|
|
if (Verified) return true;
|
|
ObjectPID = 0;
|
|
VMEntity obj = vm.GetObjectById(ObjectID);
|
|
|
|
if (!vm.TS1)
|
|
{
|
|
Mode = vm.PlatformState.Validator.GetDeleteMode(Mode, caller, obj);
|
|
if (Mode == DeleteMode.Disallowed) return false;
|
|
if (caller.AvatarState.Permissions == VMTSOAvatarPermissions.Admin)
|
|
{
|
|
VMNetLockCmd.LockObj(vm, obj);
|
|
return true; //admins can always deete
|
|
}
|
|
}
|
|
else if (vm.Context.Cheats.MoveObjects) //for ts1 moveobjects cheat
|
|
return true;
|
|
if (obj == null || (obj is VMAvatar) || obj.IsUserMovable(vm.Context, true) != VMPlacementError.Success) return false;
|
|
if ((((VMGameObject)obj).Disabled & VMGameObjectDisableFlags.TransactionIncomplete) > 0) return false; //can't delete objects mid trasaction...
|
|
VMNetLockCmd.LockObj(vm, obj);
|
|
|
|
if (Mode == DeleteMode.Delete)
|
|
{
|
|
//straight up delete this object. another check will be done at the execution stage.
|
|
return true;
|
|
} else
|
|
{
|
|
//send to the owner's inventory
|
|
ObjectPID = obj.PersistID; //we don't want to accidentally delete the wrong object - so use its real persist id.
|
|
vm.GlobalLink.MoveToInventory(vm, obj.MultitileGroup, (bool success, uint pid) =>
|
|
{
|
|
Success = success;
|
|
Verified = true;
|
|
vm.ForwardCommand(this);
|
|
});
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#region VMSerializable Members
|
|
|
|
public override void SerializeInto(BinaryWriter writer)
|
|
{
|
|
base.SerializeInto(writer);
|
|
writer.Write(ObjectID);
|
|
writer.Write(ObjectPID);
|
|
writer.Write(CleanupAll);
|
|
writer.Write(Success);
|
|
|
|
writer.Write((byte)Mode);
|
|
}
|
|
|
|
public override void Deserialize(BinaryReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
ObjectID = reader.ReadInt16();
|
|
ObjectPID = reader.ReadUInt32();
|
|
CleanupAll = reader.ReadBoolean();
|
|
Success = reader.ReadBoolean();
|
|
|
|
Mode = (DeleteMode)reader.ReadByte();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|