@@ -370,7 +370,7 @@ public static void OnAdminMessage(NetPeer peer, NetPacketReader reader)
370370
371371 case AdminRequestMode . GlobalToggleThirdPerson :
372372 Require ( peer , PermNodes . ModerationGlobalLock , ( ) =>
373- HandleGlobalToggle ( peer , "Third -person camera" , BasisGlobalLockManager . ToggleThirdPerson ( ) ) ) ;
373+ HandleGlobalFeatureToggle ( peer , "The third -person camera" , BasisGlobalLockManager . ToggleThirdPerson ( ) ) ) ;
374374 break ;
375375
376376 case AdminRequestMode . GlobalToggleAdditionalAvatarDataLock :
@@ -418,7 +418,7 @@ public static void OnAdminMessage(NetPeer peer, NetPacketReader reader)
418418
419419 case AdminRequestMode . GlobalToggleCilbox :
420420 Require ( peer , PermNodes . ModerationGlobalLock , ( ) =>
421- HandleGlobalToggle ( peer , "Avatar Cilbox code" , BasisGlobalLockManager . ToggleCilbox ( ) ) ) ;
421+ HandleGlobalFeatureToggle ( peer , "Avatar Cilbox code" , BasisGlobalLockManager . ToggleCilbox ( ) ) ) ;
422422 break ;
423423
424424 case AdminRequestMode . GlobalToggleImages :
@@ -428,37 +428,37 @@ public static void OnAdminMessage(NetPeer peer, NetPacketReader reader)
428428
429429 case AdminRequestMode . GlobalToggleEndEffectorIK :
430430 Require ( peer , PermNodes . ModerationGlobalLock , ( ) =>
431- HandleGlobalToggle ( peer , "Remote end-effector IK" , BasisGlobalLockManager . ToggleEndEffectorIK ( ) ) ) ;
431+ HandleGlobalFeatureToggle ( peer , "Remote end-effector IK" , BasisGlobalLockManager . ToggleEndEffectorIK ( ) ) ) ;
432432 break ;
433433
434434 case AdminRequestMode . GlobalToggleTextChat :
435435 Require ( peer , PermNodes . ModerationGlobalLock , ( ) =>
436- HandleGlobalToggle ( peer , "Text chat" , BasisGlobalLockManager . ToggleTextChat ( ) ) ) ;
436+ HandleGlobalFeatureToggle ( peer , "Text chat" , BasisGlobalLockManager . ToggleTextChat ( ) ) ) ;
437437 break ;
438438
439439 case AdminRequestMode . GlobalToggleVoiceChat :
440440 Require ( peer , PermNodes . ModerationGlobalLock , ( ) =>
441- HandleGlobalToggle ( peer , "Voice chat" , BasisGlobalLockManager . ToggleVoiceChat ( ) ) ) ;
441+ HandleGlobalFeatureToggle ( peer , "Voice chat" , BasisGlobalLockManager . ToggleVoiceChat ( ) ) ) ;
442442 break ;
443443
444444 case AdminRequestMode . GlobalToggleMediaPlayer :
445445 Require ( peer , PermNodes . ModerationGlobalLock , ( ) =>
446- HandleGlobalToggle ( peer , "Media player " , BasisGlobalLockManager . ToggleMediaPlayer ( ) ) ) ;
446+ HandleGlobalFeatureToggle ( peer , "Media players " , BasisGlobalLockManager . ToggleMediaPlayer ( ) ) ) ;
447447 break ;
448448
449449 case AdminRequestMode . GlobalToggleCameraCapture :
450450 Require ( peer , PermNodes . ModerationGlobalLock , ( ) =>
451- HandleGlobalToggle ( peer , "Camera capture" , BasisGlobalLockManager . ToggleCameraCapture ( ) ) ) ;
451+ HandleGlobalFeatureToggle ( peer , "Camera capture" , BasisGlobalLockManager . ToggleCameraCapture ( ) ) ) ;
452452 break ;
453453
454454 case AdminRequestMode . GlobalTogglePropGrabbing :
455455 Require ( peer , PermNodes . ModerationGlobalLock , ( ) =>
456- HandleGlobalToggle ( peer , "Prop grabbing" , BasisGlobalLockManager . TogglePropGrabbing ( ) ) ) ;
456+ HandleGlobalFeatureToggle ( peer , "Prop grabbing" , BasisGlobalLockManager . TogglePropGrabbing ( ) ) ) ;
457457 break ;
458458
459459 case AdminRequestMode . GlobalToggleSafeDisplayNames :
460460 Require ( peer , PermNodes . ModerationGlobalLock , ( ) =>
461- HandleGlobalToggle ( peer , "Safe display names" , BasisGlobalLockManager . ToggleSafeDisplayNames ( ) ) ) ;
461+ HandleGlobalProtectionToggle ( peer , "Safe display names" , BasisGlobalLockManager . ToggleSafeDisplayNames ( ) ) ) ;
462462 break ;
463463
464464 case AdminRequestMode . SetGlobalAvatarScaleLimits :
@@ -1267,6 +1267,7 @@ private static void BroadcastGlobalLockNotice(NetPeer peer, string adminReply, s
12671267 NetworkServer . BroadcastMessageToClients ( writer , BasisNetworkCommons . AdminChannel , NetworkServer . PeerSnapshot , DeliveryMethod . ReliableOrdered ) ;
12681268 NetworkServer . ReturnWriter ( writer ) ;
12691269
1270+ PersistGlobalLockState ( ) ;
12701271 BasisGlobalLockManager . BroadcastLockState ( ) ;
12711272 }
12721273
@@ -1276,6 +1277,28 @@ private static void HandleGlobalToggle(NetPeer peer, string contentType, bool no
12761277 HandleGlobalStateNotification ( peer , $ "{ contentType } loading has been globally { state } by an admin.") ;
12771278 }
12781279
1280+ /// <summary>
1281+ /// Notification for locks over a live feature rather than content loading (chat, voice,
1282+ /// grabbing, ...). HandleGlobalToggle's "<c>X loading</c>" template reads as nonsense for
1283+ /// these — nothing is being loaded — so they get a plain "<c>X has been ... DISABLED</c>".
1284+ /// </summary>
1285+ private static void HandleGlobalFeatureToggle ( NetPeer peer , string featureName , bool nowLocked )
1286+ {
1287+ string state = nowLocked ? "DISABLED" : "ENABLED" ;
1288+ HandleGlobalStateNotification ( peer , $ "{ featureName } has been globally { state } by an admin.") ;
1289+ }
1290+
1291+ /// <summary>
1292+ /// Notification for a protection that is ENABLED when its flag is set — the opposite sense
1293+ /// to every lock above, so the shared templates would announce the exact inverse of what
1294+ /// the admin just did.
1295+ /// </summary>
1296+ private static void HandleGlobalProtectionToggle ( NetPeer peer , string protectionName , bool nowEnforced )
1297+ {
1298+ string state = nowEnforced ? "ENABLED" : "DISABLED" ;
1299+ HandleGlobalStateNotification ( peer , $ "{ protectionName } has been globally { state } by an admin.") ;
1300+ }
1301+
12791302 /// <summary>
12801303 /// Notifies the toggling admin + all clients with a pre-composed, unambiguous message and
12811304 /// rebroadcasts the lock state. Toggles whose semantics don't fit the
@@ -1297,9 +1320,21 @@ private static void HandleGlobalStateNotification(NetPeer peer, string notificat
12971320 NetworkServer . ReturnWriter ( writer ) ;
12981321
12991322 // Broadcast updated lock state so clients track it
1323+ PersistGlobalLockState ( ) ;
13001324 BasisGlobalLockManager . BroadcastLockState ( ) ;
13011325 }
13021326
1327+ /// <summary>
1328+ /// Mirrors the live global lock state onto Configuration and writes config.xml. Every lock
1329+ /// seeds itself from config at boot, so a toggle that isn't persisted here silently reverts
1330+ /// on the next restart.
1331+ /// </summary>
1332+ private static void PersistGlobalLockState ( )
1333+ {
1334+ BasisGlobalLockManager . WriteToConfig ( NetworkServer . Configuration ) ;
1335+ SaveConfig ( ) ;
1336+ }
1337+
13031338 private static void HandleHeadlessAudioSet ( NetPeer peer , NetPacketReader reader )
13041339 {
13051340 if ( reader . AvailableBytes < 1 )
@@ -1343,6 +1378,9 @@ private static void HandleHeadlessDisallowSet(NetPeer peer, NetPacketReader read
13431378 BasisHeadlessConnectionPolicyManager . DisconnectConnectedHeadlessPeers ( ) ;
13441379 }
13451380
1381+ // Seeded from Configuration.DisallowHeadless at boot — persist or it reverts on restart.
1382+ NetworkServer . Configuration . DisallowHeadless = BasisHeadlessConnectionPolicyManager . HeadlessDisallowed ;
1383+ SaveConfig ( ) ;
13461384 BasisHeadlessConnectionPolicyManager . BroadcastState ( ) ;
13471385 }
13481386
@@ -1378,6 +1416,7 @@ private static void HandleCameraPolicySet(NetPeer peer, NetPacketReader reader)
13781416 BasisGlobalLockManager . SetCameraMetadataDisallowMask ( mask ) ;
13791417 BNL . Log ( $ "Camera photo-metadata disallow mask set to { mask } .") ;
13801418 SendBackMessage ( peer , $ "Camera metadata policy updated (mask { mask } ).") ;
1419+ PersistGlobalLockState ( ) ;
13811420 BasisGlobalLockManager . BroadcastLockState ( ) ;
13821421 }
13831422
0 commit comments