feat: implement debug mode flags

This commit is contained in:
riperiperi 2026-07-18 12:56:06 +01:00
parent b78736bbc5
commit 37db4e62aa
10 changed files with 96 additions and 11 deletions

View file

@ -1729,6 +1729,37 @@ namespace FSO.Server.Servers.Lot.Domain
if (RelationshipsToSave.Count > 0) BatchRelationshipSave();
}
private bool IsAvatarDebug(uint modLevel)
{
if (Config.Archive != null)
{
// Use the archive flags to gate debug features
var flags = Config.Archive.Flags;
if (flags.HasFlag(FSO.Common.ArchiveConfigFlags.DebugFeatures))
{
int requiredLevel = 2;
if (flags.HasFlag(FSO.Common.ArchiveConfigFlags.DebugFeaturesAllUsers))
{
requiredLevel = 0;
}
else if (flags.HasFlag(FSO.Common.ArchiveConfigFlags.DebugFeaturesMods))
{
requiredLevel = 1;
}
return modLevel >= requiredLevel;
}
else
{
return false;
}
}
return modLevel > 0;
}
//Run on the background thread
public void AvatarJoin(IVoltronSession session)
{
@ -1803,6 +1834,8 @@ namespace FSO.Server.Servers.Lot.Domain
}
}
state.AvatarFlags |= IsAvatarDebug((session as VoltronSession)?.ModerationLevel ?? 0) ? VMTSOAvatarFlags.Debug : 0;
Host.RecordStartVisit(session, visitorType);
var hollowLoadMask = (transitionInfo?.GetSurroundingLotMask() ?? HOLLOW_LOAD_ALL);
@ -2119,6 +2152,7 @@ namespace FSO.Server.Servers.Lot.Domain
if (!signalled) return; //give up
VMTSOAvatarPermissions newLevel = VMTSOAvatarPermissions.Visitor;
VMChangePermissionsMode mode = VMChangePermissionsMode.NORMAL;
bool? debug = null;
switch (change)
{
case ChangeType.ADD_ROOMMATE:
@ -2139,6 +2173,7 @@ namespace FSO.Server.Servers.Lot.Domain
var ava = da.Avatars.Get(avatar_id);
var roomies = da.Roommates.GetAvatarsLots(avatar_id);
newLevel = GetAvatarPermissions(ava, roomies);
debug = IsAvatarDebug(ava.moderation_level);
}
break;
}
@ -2150,6 +2185,7 @@ namespace FSO.Server.Servers.Lot.Domain
TargetUID = avatar_id,
Level = newLevel,
Mode = mode,
Debug = debug,
ReplaceUID = replace_id,
Verified = true,
});

View file

@ -597,7 +597,7 @@ namespace FSO.Client.UI.Archive
public static void DebugModeHelp()
{
UIAlert.Alert("Debug interactions", "When enabled, the archive server gives admins the ability to spawn debug objects and use debug interactions. These interactions can optionally be enabled for moderators and all other users.", true);
UIAlert.Alert("Debug interactions", "When enabled, the archive server gives admins the ability to spawn all debug objects from build mode and use debug interactions. These objects/interactions allow users to cheat money/skill, but can potentially cause object errors crash the game. If you want a 'safe' selection of debug objects for all players, you can enable the 'debug' catalog in the events configuration. \nThese interactions can optionally be enabled for moderators and all other users.", true);
}
public static void ArchivedCharacterHelp()

View file

@ -196,7 +196,7 @@ namespace FSO.Client.UI.Panels
public override void Update(UpdateState state)
{
bool allowDebug = (LotController?.ActiveEntity?.TSOState as VMTSOAvatarState)?.Permissions >= VMTSOAvatarPermissions.Admin;
bool allowDebug = (LotController?.ActiveEntity?.TSOState as VMTSOAvatarState)?.Flags.HasFlag(VMTSOAvatarFlags.Debug) ?? false;
if (DebugButton.Visible != allowDebug)
{

View file

@ -450,6 +450,7 @@ namespace FSO.Client.UI.Screens
SkinTone = (byte)settings.DebugSkin,
Gender = (short)(settings.DebugGender ? 0 : 1),
Permissions = SimAntics.Model.TSOPlatform.VMTSOAvatarPermissions.Admin,
AvatarFlags = SimAntics.Model.TSOPlatform.VMTSOAvatarFlags.Debug,
//CustomGUID = 0x396CD3D1,
Budget = 1000000,
};

View file

@ -1018,10 +1018,9 @@ namespace FSO.SimAntics.Engine
//if flags are empty apart from "Non-Empty", force everything but visitor. (a kind of default state)
if (tsoCompare == TSOFlags.NonEmpty) tsoCompare |= TSOFlags.AllowFriends | TSOFlags.AllowRoommates | TSOFlags.AllowObjectOwner;
//DEBUG: enable debug interction for all CSRs.
if ((action.Flags & TTABFlags.Debug) > 0)
{
if ((tsoState & TSOFlags.AllowCSRs) > 0)
if (avatar.AvatarState.Flags.HasFlag(VMTSOAvatarFlags.Debug))
return result; //do not bother running check
else
return null; //disable debug for everyone else.

View file

@ -94,7 +94,7 @@ namespace FSO.SimAntics.Model.Platform
var whitelist = (ava.AvatarState.Permissions == VMTSOAvatarPermissions.Roommate) ? RoomieWhiteList : BuilderWhiteList;
if (item == null || !whitelist.Contains(item.Value.Category))
{
if (ava.AvatarState.Permissions != VMTSOAvatarPermissions.Admin) return PurchaseMode.Disallowed;
if (!ava.AvatarState.Flags.HasFlag(VMTSOAvatarFlags.Debug)) return PurchaseMode.Disallowed;
}
}

View file

@ -5,5 +5,6 @@ namespace FSO.SimAntics.Model.Platform
public interface VMIAvatarState
{
VMTSOAvatarPermissions Permissions { get; set; }
VMTSOAvatarFlags Flags { get; set; }
}
}

View file

@ -13,6 +13,10 @@ namespace FSO.SimAntics.Model.TS1Platform
{
get; set;
}
public VMTSOAvatarFlags Flags
{
get; set;
}
public override void Deserialize(BinaryReader reader)
{

View file

@ -11,7 +11,7 @@ namespace FSO.SimAntics.Model.TSOPlatform
public VMTSOAvatarPermissions Permissions { get; set; } = VMTSOAvatarPermissions.Visitor;
public HashSet<uint> IgnoredAvatars = new HashSet<uint>();
public Dictionary<short, VMTSOJobInfo> JobInfo = new Dictionary<short, VMTSOJobInfo>();
public VMTSOAvatarFlags Flags;
public VMTSOAvatarFlags Flags { get; set; }
public bool IsSpectator => Flags.HasFlag(VMTSOAvatarFlags.Spectator);
public Color ChatColor = Color.White;
public sbyte ChatTTSPitch; //-100 to 100.
@ -106,9 +106,29 @@ namespace FSO.SimAntics.Model.TSOPlatform
[Flags]
public enum VMTSOAvatarFlags : uint
{
/// <summary>
/// Isn't a roomie or owner of another lot.
/// </summary>
CanBeRoommate = 1, //TODO: update on becoming roomie of another lot, while on this lot.
NewPlayer = 2, //under a week old
Mayor = 4, //is mayor of this neighborhood
Spectator = 8, //read-only visitor in spectator mode
/// <summary>
/// Under a week old.
/// </summary>
NewPlayer = 2,
/// <summary>
/// Is mayor of this neighborhood.
/// </summary>
Mayor = 4,
/// <summary>
/// Read-only visitor in spectator mode.
/// </summary>
Spectator = 8,
/// <summary>
/// Can use debug interactions. Tends to be set on moderators/administrators, but archive mode can enforce extra rules.
/// </summary>
Debug = 16,
}
}

View file

@ -1,7 +1,5 @@
using FSO.SimAntics.Model;
using FSO.SimAntics.Model.TSOPlatform;
using System.Collections.Generic;
using System.IO;
namespace FSO.SimAntics.NetPlay.Model.Commands
{
@ -10,6 +8,7 @@ namespace FSO.SimAntics.NetPlay.Model.Commands
public uint TargetUID;
public VMTSOAvatarPermissions Level;
public VMChangePermissionsMode Mode;
public bool? Debug;
public uint ReplaceUID; //for object inherit modes. Set implicitly for owner replacement.
public bool Verified;
public override bool Execute(VM vm)
@ -113,6 +112,22 @@ namespace FSO.SimAntics.NetPlay.Model.Commands
if (level >= VMTSOAvatarPermissions.BuildBuyRoommate) vm.TSOState.BuildRoommates.Add(obj.PersistID);
if (level == VMTSOAvatarPermissions.Owner) vm.TSOState.OwnerID = pid;
else if (vm.TSOState.OwnerID == pid) vm.TSOState.OwnerID = 0;
if (Debug != null)
{
var flags = obj.AvatarState.Flags;
if (Debug.Value)
{
flags |= VMTSOAvatarFlags.Debug;
}
else
{
flags &= ~VMTSOAvatarFlags.Debug;
}
obj.AvatarState.Flags = flags;
}
}
return roomieChange && playerOwned;
}
@ -167,6 +182,12 @@ namespace FSO.SimAntics.NetPlay.Model.Commands
writer.Write(ReplaceUID);
writer.Write((byte)Level);
writer.Write((byte)Mode);
writer.Write(Debug.HasValue);
if (Debug.HasValue)
{
writer.Write(Debug.Value);
}
}
public override void Deserialize(BinaryReader reader)
@ -176,6 +197,9 @@ namespace FSO.SimAntics.NetPlay.Model.Commands
ReplaceUID = reader.ReadUInt32();
Level = (VMTSOAvatarPermissions)reader.ReadByte();
Mode = (VMChangePermissionsMode)reader.ReadByte();
var hasDebug = reader.ReadBoolean();
Debug = hasDebug ? reader.ReadBoolean() : null;
}
#endregion