mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-03 06:49:22 +00:00
Move many mods to Deprecated folder, fix spelling
This commit is contained in:
parent
5e822cec8d
commit
0042590aa6
539 changed files with 7475 additions and 3120 deletions
237
BetterContentLoading/DownloadManager/DownloadManager.Core.cs
Normal file
237
BetterContentLoading/DownloadManager/DownloadManager.Core.cs
Normal file
|
@ -0,0 +1,237 @@
|
|||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Networking.API.Responses;
|
||||
using ABI_RC.Core.Networking.IO.Social;
|
||||
using ABI_RC.Core.Savior;
|
||||
|
||||
namespace NAK.BetterContentLoading;
|
||||
|
||||
public partial class DownloadManager
|
||||
{
|
||||
#region Singleton
|
||||
private static DownloadManager _instance;
|
||||
public static DownloadManager Instance => _instance ??= new DownloadManager();
|
||||
#endregion
|
||||
|
||||
private DownloadManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#region Settings
|
||||
public bool IsDebugEnabled { get; set; } = true;
|
||||
public bool PrioritizeFriends { get; set; } = true;
|
||||
public bool PrioritizeDistance { get; set; } = true;
|
||||
public float PriorityDownloadDistance { get; set; } = 25f;
|
||||
public int MaxConcurrentDownloads { get; set; } = 3;
|
||||
public int MaxDownloadBandwidth { get; set; } = 100 * 1024 * 1024; // 100MB default
|
||||
private const int THROTTLE_THRESHOLD = 25 * 1024 * 1024; // 25MB threshold for throttling
|
||||
|
||||
public long MaxAvatarDownloadSize { get; set; } = 25 * 1024 * 1024; // 25MB default
|
||||
public long MaxPropDownloadSize { get; set; } = 25 * 1024 * 1024; // 25MB default
|
||||
|
||||
#endregion Settings
|
||||
|
||||
#region State
|
||||
|
||||
// priority -> downloadtask
|
||||
private readonly SortedList<float, DownloadTask> _downloadQueue = new();
|
||||
|
||||
// downloadId -> downloadtask
|
||||
private readonly Dictionary<string, DownloadTask> _cachedDownloads = new();
|
||||
|
||||
#endregion State
|
||||
|
||||
#region Public Queue Methods
|
||||
|
||||
public void QueueAvatarDownload(
|
||||
in DownloadInfo info,
|
||||
string playerId,
|
||||
CVRLoadingAvatarController loadingController)
|
||||
{
|
||||
if (IsDebugEnabled)
|
||||
{
|
||||
BetterContentLoadingMod.Logger.Msg(
|
||||
$"Queuing Avatar Download:\n{info.GetLogString()}\n" +
|
||||
$"PlayerId: {playerId}\n" +
|
||||
$"LoadingController: {loadingController}");
|
||||
}
|
||||
|
||||
if (!ShouldQueueAvatarDownload(info, playerId))
|
||||
{
|
||||
if (IsDebugEnabled) BetterContentLoadingMod.Logger.Msg($"Avatar Download not eligible: {info.DownloadId}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cachedDownloads.TryGetValue(info.DownloadId, out DownloadTask cachedDownload))
|
||||
{
|
||||
if (IsDebugEnabled) BetterContentLoadingMod.Logger.Msg($"Avatar Download already queued: {info.DownloadId}");
|
||||
cachedDownload.AddInstantiationTarget(playerId);
|
||||
cachedDownload.BasePriority = CalculatePriority(cachedDownload);
|
||||
return;
|
||||
}
|
||||
|
||||
DownloadTask task = new()
|
||||
{
|
||||
Info = info,
|
||||
Type = DownloadTaskType.Avatar
|
||||
};
|
||||
task.AddInstantiationTarget(playerId);
|
||||
task.BasePriority = CalculatePriority(task);
|
||||
}
|
||||
|
||||
private bool ShouldQueueAvatarDownload(
|
||||
in DownloadInfo info,
|
||||
string playerId)
|
||||
{
|
||||
// Check if content is incompatible or banned
|
||||
if (info.TagsData.Incompatible || info.TagsData.AdminBanned)
|
||||
{
|
||||
if (IsDebugEnabled) BetterContentLoadingMod.Logger.Msg($"Avatar is incompatible or banned");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if player is blocked
|
||||
if (MetaPort.Instance.blockedUserIds.Contains(playerId))
|
||||
{
|
||||
if (IsDebugEnabled) BetterContentLoadingMod.Logger.Msg($"Player is blocked: {playerId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if mature content is disabled
|
||||
UgcTagsData tags = info.TagsData;
|
||||
if (!MetaPort.Instance.matureContentAllowed && (tags.Gore || tags.Nudity))
|
||||
{
|
||||
if (IsDebugEnabled) BetterContentLoadingMod.Logger.Msg($"Mature content is disabled");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check file size
|
||||
if (info.FileSize > MaxAvatarDownloadSize)
|
||||
{
|
||||
if (IsDebugEnabled) BetterContentLoadingMod.Logger.Msg($"Avatar Download too large: {info.FileSize} > {MaxAvatarDownloadSize}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get visibility status for the avatar
|
||||
// ForceHidden means player avatar or avatar itself is forced off.
|
||||
// ForceShown will bypass all checks and return true.
|
||||
MetaPort.Instance.SelfModerationManager.GetAvatarVisibility(playerId, info.AssetId,
|
||||
out bool wasForceHidden, out bool wasForceShown);
|
||||
|
||||
if (!wasForceHidden)
|
||||
{
|
||||
if (IsDebugEnabled) BetterContentLoadingMod.Logger.Msg($"Avatar is not visible either because player avatar or avatar itself is forced off");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wasForceShown)
|
||||
{
|
||||
// Check content filter settings if not force shown
|
||||
CVRSettings settings = MetaPort.Instance.settings;
|
||||
bool isLocalPlayer = playerId == MetaPort.Instance.ownerId;
|
||||
bool isFriend = Friends.FriendsWith(playerId);
|
||||
bool CheckFilterSettings(string settingName)
|
||||
{
|
||||
int settingVal = settings.GetSettingInt(settingName);
|
||||
switch (settingVal)
|
||||
{
|
||||
// Only Self
|
||||
case 0 when !isLocalPlayer:
|
||||
// Only Friends
|
||||
case 1 when !isFriend:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CheckFilterSettings("ContentFilterVisibility")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterNudity")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterGore")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterSuggestive")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterFlashingColors")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterFlashingLights")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterScreenEffects")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterExtremelyBright")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterViolence")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterJumpscare")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterExcessivelyHuge")) return false;
|
||||
if (!CheckFilterSettings("ContentFilterExcessivelySmall")) return false;
|
||||
}
|
||||
|
||||
// All eligibility checks passed
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues a prop download.
|
||||
/// </summary>
|
||||
/// <param name="info">The download info.</param>
|
||||
/// <param name="instanceId">The instance ID for the prop.</param>
|
||||
/// <param name="spawnerId">The user who spawned the prop.</param>
|
||||
public void QueuePropDownload(
|
||||
in DownloadInfo info,
|
||||
string instanceId,
|
||||
string spawnerId)
|
||||
{
|
||||
if (IsDebugEnabled)
|
||||
{
|
||||
BetterContentLoadingMod.Logger.Msg(
|
||||
$"Queuing Prop Download:\n{info.GetLogString()}\n" +
|
||||
$"InstanceId: {instanceId}\n" +
|
||||
$"SpawnerId: {spawnerId}");
|
||||
}
|
||||
|
||||
if (_cachedDownloads.TryGetValue(info.DownloadId, out DownloadTask cachedDownload))
|
||||
{
|
||||
if (IsDebugEnabled) BetterContentLoadingMod.Logger.Msg($"Prop Download already queued: {info.DownloadId}");
|
||||
cachedDownload.AddInstantiationTarget(instanceId);
|
||||
cachedDownload.BasePriority = CalculatePriority(cachedDownload);
|
||||
return;
|
||||
}
|
||||
|
||||
DownloadTask task = new()
|
||||
{
|
||||
Info = info,
|
||||
Type = DownloadTaskType.Prop
|
||||
};
|
||||
task.AddInstantiationTarget(instanceId);
|
||||
task.BasePriority = CalculatePriority(task);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queues a world download.
|
||||
/// </summary>
|
||||
/// <param name="info">Download info.</param>
|
||||
/// <param name="joinOnComplete">Whether to load into this world once downloaded.</param>
|
||||
/// <param name="isHomeRequested">Whether the home world is requested.</param>
|
||||
public void QueueWorldDownload(
|
||||
in DownloadInfo info,
|
||||
bool joinOnComplete,
|
||||
bool isHomeRequested)
|
||||
{
|
||||
if (IsDebugEnabled)
|
||||
{
|
||||
BetterContentLoadingMod.Logger.Msg(
|
||||
$"Queuing World Download:\n{info.GetLogString()}\n" +
|
||||
$"JoinOnComplete: {joinOnComplete}\n" +
|
||||
$"IsHomeRequested: {isHomeRequested}");
|
||||
}
|
||||
|
||||
if (_cachedDownloads.TryGetValue(info.DownloadId, out DownloadTask cachedDownload))
|
||||
{
|
||||
if (IsDebugEnabled) BetterContentLoadingMod.Logger.Msg($"World Download already queued: {info.DownloadId}");
|
||||
cachedDownload.BasePriority = CalculatePriority(cachedDownload);
|
||||
return;
|
||||
}
|
||||
|
||||
DownloadTask task = new()
|
||||
{
|
||||
Info = info,
|
||||
Type = DownloadTaskType.World
|
||||
};
|
||||
task.BasePriority = CalculatePriority(task);
|
||||
}
|
||||
|
||||
#endregion Public Queue Methods
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
using ABI_RC.Core.Networking.IO.Social;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Core.Util;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.BetterContentLoading;
|
||||
|
||||
public partial class DownloadManager
|
||||
{
|
||||
internal static bool TryGetPlayerEntity(string playerId, out CVRPlayerEntity playerEntity)
|
||||
{
|
||||
CVRPlayerEntity player = CVRPlayerManager.Instance.NetworkPlayers.Find(p => p.Uuid == playerId);
|
||||
if (player == null)
|
||||
{
|
||||
// BetterContentLoadingMod.Logger.Error($"Player entity not found for ID: {playerId}");
|
||||
playerEntity = null;
|
||||
return false;
|
||||
}
|
||||
playerEntity = player;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool TryGetPropData(string instanceId, out CVRSyncHelper.PropData propData)
|
||||
{
|
||||
CVRSyncHelper.PropData prop = CVRSyncHelper.Props.Find(p => p.InstanceId == instanceId);
|
||||
if (prop == null)
|
||||
{
|
||||
// BetterContentLoadingMod.Logger.Error($"Prop data not found for ID: {instanceId}");
|
||||
propData = null;
|
||||
return false;
|
||||
}
|
||||
propData = prop;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsPlayerLocal(string playerId)
|
||||
{
|
||||
return playerId == MetaPort.Instance.ownerId;
|
||||
}
|
||||
|
||||
private static bool IsPlayerFriend(string playerId)
|
||||
{
|
||||
return Friends.FriendsWith(playerId);
|
||||
}
|
||||
|
||||
private bool IsPlayerWithinPriorityDistance(CVRPlayerEntity player)
|
||||
{
|
||||
if (player.PuppetMaster == null) return false;
|
||||
return player.PuppetMaster.animatorManager.DistanceTo < PriorityDownloadDistance;
|
||||
}
|
||||
|
||||
internal bool IsPropWithinPriorityDistance(CVRSyncHelper.PropData prop)
|
||||
{
|
||||
Vector3 propPosition = new(prop.PositionX, prop.PositionY, prop.PositionZ);
|
||||
return Vector3.Distance(propPosition, PlayerSetup.Instance.GetPlayerPosition()) < PriorityDownloadDistance;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using ABI_RC.Core.Player;
|
||||
|
||||
namespace NAK.BetterContentLoading;
|
||||
|
||||
public partial class DownloadManager
|
||||
{
|
||||
private float CalculatePriority(DownloadTask task)
|
||||
{
|
||||
return task.Type switch
|
||||
{
|
||||
DownloadTaskType.Avatar => CalculateAvatarPriority(task),
|
||||
// DownloadTaskType.Prop => CalculatePropPriority(task2),
|
||||
// DownloadTaskType.World => CalculateWorldPriority(task2),
|
||||
_ => task.Info.FileSize
|
||||
};
|
||||
}
|
||||
|
||||
private float CalculateAvatarPriority(DownloadTask task)
|
||||
{
|
||||
float priority = task.Info.FileSize;
|
||||
|
||||
foreach (string target in task.InstantiationTargets)
|
||||
{
|
||||
if (IsPlayerLocal(target)) return 0f;
|
||||
|
||||
if (!TryGetPlayerEntity(target, out CVRPlayerEntity player))
|
||||
return priority;
|
||||
|
||||
if (PrioritizeFriends && IsPlayerFriend(target))
|
||||
priority *= 0.5f;
|
||||
|
||||
if (PrioritizeDistance && IsPlayerWithinPriorityDistance(player))
|
||||
priority *= 0.75f;
|
||||
}
|
||||
|
||||
return priority;
|
||||
}
|
||||
}
|
33
BetterContentLoading/DownloadManager/DownloadTask.Main.cs
Normal file
33
BetterContentLoading/DownloadManager/DownloadTask.Main.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
namespace NAK.BetterContentLoading;
|
||||
|
||||
public partial class DownloadTask
|
||||
{
|
||||
public DownloadInfo Info { get; set; }
|
||||
public DownloadTaskStatus Status { get; set; }
|
||||
public DownloadTaskType Type { get; set; }
|
||||
|
||||
public float BasePriority { get; set; }
|
||||
public float CurrentPriority => BasePriority * (1 + Progress / 100f);
|
||||
|
||||
public long BytesRead { get; set; }
|
||||
public int Progress { get; set; }
|
||||
|
||||
/// The avatar/prop instances that wish to utilize this bundle.
|
||||
public List<string> InstantiationTargets { get; } = new();
|
||||
|
||||
public void AddInstantiationTarget(string target)
|
||||
{
|
||||
if (InstantiationTargets.Contains(target))
|
||||
return;
|
||||
|
||||
InstantiationTargets.Add(target);
|
||||
}
|
||||
|
||||
public void RemoveInstantiationTarget(string target)
|
||||
{
|
||||
if (!InstantiationTargets.Contains(target))
|
||||
return;
|
||||
|
||||
InstantiationTargets.Remove(target);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
namespace NAK.BetterContentLoading;
|
||||
|
||||
public partial class DownloadTask
|
||||
{
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue