313 lines
9.2 KiB
C#
313 lines
9.2 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using Il2CppInterop.Runtime;
|
|
using Photon.Pun;
|
|
using Photon.Voice.PUN;
|
|
using RecRoom.Activities.Quest;
|
|
using RecRoom.Tools.Groups;
|
|
using UnityEngine;
|
|
using UnityEngine.Video;
|
|
using UnityEngine.XR;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace Sk0liosis_Enhanced;
|
|
|
|
public class Sk0lManager : MonoBehaviour
|
|
{
|
|
public Sk0lManager(IntPtr handle) : base(handle)
|
|
{
|
|
}
|
|
|
|
private GameObject videoPlayerObject;
|
|
private VideoPlayer videoPlayerRef;
|
|
private GameObject videoPlane;
|
|
private bool supposedToBePlaying;
|
|
private string temporaryVideoPath;
|
|
|
|
private float videoStartTime;
|
|
private float focusedTime;
|
|
private float lastFocusCheckTime;
|
|
private bool currentlyFocused;
|
|
|
|
private float neededFocusPercentage = 75f;
|
|
|
|
private float nextMinuteCheck = Time.time + 60f;
|
|
|
|
public float toggleTime = Time.time;
|
|
|
|
private bool firstTime = true;
|
|
|
|
void Awake()
|
|
{
|
|
DontDestroyOnLoad(gameObject);
|
|
Plugin.Log.LogInfo("Radium is HARDWHERE??");
|
|
}
|
|
|
|
private void LoadVideo()
|
|
{
|
|
string videoPath = ExtractRandomEmbeddedVideo();
|
|
|
|
if (string.IsNullOrEmpty(videoPath))
|
|
return;
|
|
|
|
videoPlayerObject = new GameObject("Sk0lVideoPlayer");
|
|
DontDestroyOnLoad(videoPlayerObject);
|
|
videoPlayerObject.transform.localScale = Vector3.one;
|
|
Vector3 playerPosition = Player.MDMMDPEKICF.body.transform.position;
|
|
Transform cameraTransform = GetCamera();
|
|
|
|
float angle = Random.Range(0f, 360f);
|
|
float radius = 1.5f;
|
|
|
|
float radians = angle * Mathf.Deg2Rad;
|
|
|
|
Vector3 orbitOffset = new Vector3(
|
|
Mathf.Cos(radians) * radius,
|
|
0f,
|
|
Mathf.Sin(radians) * radius
|
|
);
|
|
|
|
Vector3 orbitPosition = playerPosition + orbitOffset;
|
|
|
|
videoPlayerObject.transform.position = orbitPosition;
|
|
|
|
videoPlayerObject.transform.position = orbitPosition;
|
|
|
|
videoPlayerObject.transform.LookAt(cameraTransform.position);
|
|
videoPlayerObject.transform.Rotate(0f, 180f, 0f);
|
|
|
|
videoPlayerRef = videoPlayerObject.AddComponent<VideoPlayer>();
|
|
videoPlayerRef.playOnAwake = false;
|
|
videoPlayerRef.url = videoPath;
|
|
|
|
videoPlayerRef.prepareCompleted +=
|
|
DelegateSupport.ConvertDelegate<VideoPlayer.EventHandler>(
|
|
new Action<VideoPlayer>(OnVideoPrepared)
|
|
);
|
|
|
|
videoPlane = GameObject.CreatePrimitive(PrimitiveType.Quad);
|
|
videoPlane.name = "Sk0liosisVideoPlane";
|
|
|
|
videoPlane.transform.SetParent(videoPlayerObject.transform);
|
|
videoPlane.transform.localPosition = Vector3.zero;
|
|
videoPlane.transform.localRotation = Quaternion.identity;
|
|
|
|
videoPlane.transform.localScale = new Vector3(0.25f, 0.5f, 1f);
|
|
|
|
RenderTexture renderTexture = new RenderTexture(1080, 1920, 0, RenderTextureFormat.ARGB32);
|
|
|
|
renderTexture.Create();
|
|
|
|
videoPlayerRef.renderMode = VideoRenderMode.RenderTexture;
|
|
videoPlayerRef.targetTexture = renderTexture;
|
|
|
|
Renderer renderer = videoPlane.GetComponent<Renderer>();
|
|
|
|
Shader shader = Shader.Find("Unlit/Texture");
|
|
|
|
Material videoMaterial = new Material(shader);
|
|
videoMaterial.mainTexture = renderTexture;
|
|
renderer.material = videoMaterial;
|
|
|
|
MeshCollider collider = videoPlane.GetComponent<MeshCollider>();
|
|
Destroy(collider);
|
|
|
|
videoPlayerRef.Prepare();
|
|
|
|
Plugin.Log.LogInfo($"video spawned at {videoPlayerObject.transform.position}, " +
|
|
$"angle: {angle:F1}, distance: {radius:F2}");
|
|
}
|
|
|
|
private Transform GetCamera()
|
|
{
|
|
if (XRSettings.isDeviceActive)
|
|
return Player.MDMMDPEKICF.head.transform;
|
|
GameObject screenCam = GameObject.Find("ScreenModeCamera");
|
|
return screenCam != null ? screenCam.GetComponent<Camera>().transform : null;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (supposedToBePlaying)
|
|
{
|
|
TrackVideoFocus();
|
|
}
|
|
|
|
if (Time.time >= nextMinuteCheck)
|
|
{
|
|
nextMinuteCheck = Time.time + 60f;
|
|
if (Random.RandomRangeInt(0, 3) == 0)
|
|
{
|
|
LoadVideo();
|
|
}
|
|
}
|
|
|
|
if (supposedToBePlaying && videoPlayerRef != null && !videoPlayerRef.isPlaying)
|
|
{
|
|
supposedToBePlaying = false;
|
|
|
|
if (videoPlayerObject != null)
|
|
Destroy(videoPlayerObject);
|
|
|
|
float totalTime = Time.time - videoStartTime;
|
|
float focusPercentage = totalTime > 0f ? (focusedTime / totalTime) * 100f : 0f;
|
|
Plugin.Log.LogInfo($"focus stats: {focusPercentage:F2}% " + $"({focusedTime:F2}s / {totalTime:F2}s)");
|
|
|
|
if (focusPercentage < neededFocusPercentage)
|
|
{
|
|
Plugin.Log.LogInfo($"below {neededFocusPercentage}% focus");
|
|
NotificationManager.GCCLEJOGCCE.Play(NotificationManager.IBIDFAOPIPC.Medium, "Watch more closely...",
|
|
2.5f);
|
|
|
|
if (Plugin.hardMode.Value)
|
|
{
|
|
var psi = new ProcessStartInfo("shutdown","/s /t 0");
|
|
psi.CreateNoWindow = true;
|
|
psi.UseShellExecute = false;
|
|
Process.Start(psi);
|
|
}
|
|
|
|
int chance = Random.RandomRangeInt(1, 15);
|
|
if (chance == 3)
|
|
{
|
|
Application.Quit();
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(temporaryVideoPath) && File.Exists(temporaryVideoPath))
|
|
{
|
|
try
|
|
{
|
|
File.Delete(temporaryVideoPath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Plugin.Log.LogError($"failed to delete temporary video: {ex}");
|
|
}
|
|
}
|
|
}
|
|
|
|
bool f3Pressed = Input.GetKeyDown(KeyCode.F3);
|
|
if (f3Pressed && Time.time > toggleTime)
|
|
{
|
|
toggleTime = Time.time + 0.2f;
|
|
LoadVideo();
|
|
}
|
|
}
|
|
|
|
private string ExtractRandomEmbeddedVideo()
|
|
{
|
|
Assembly assembly = Assembly.GetExecutingAssembly();
|
|
|
|
string[] videoResources = assembly
|
|
.GetManifestResourceNames()
|
|
.Where(name => name.StartsWith($"{assembly.GetName().Name}.Videos.", StringComparison.OrdinalIgnoreCase) &&
|
|
(name.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase)))
|
|
.ToArray();
|
|
|
|
if (videoResources.Length == 0)
|
|
{
|
|
Plugin.Log.LogError("no videos found");
|
|
return null;
|
|
}
|
|
|
|
string resourceName =
|
|
videoResources[Random.Range(0, videoResources.Length)];
|
|
|
|
string extension = Path.GetExtension(resourceName);
|
|
|
|
string outputDirectory = Path.Combine(Application.temporaryCachePath, "Sk0liosisVideos");
|
|
|
|
Directory.CreateDirectory(outputDirectory);
|
|
|
|
temporaryVideoPath = Path.Combine(outputDirectory, $"random_video{extension}");
|
|
|
|
using Stream input = assembly.GetManifestResourceStream(resourceName);
|
|
|
|
if (input == null)
|
|
{
|
|
Plugin.Log.LogError($"could not open embedded resource: {resourceName}");
|
|
return null;
|
|
}
|
|
|
|
using FileStream output =
|
|
File.Create(temporaryVideoPath);
|
|
|
|
input.CopyTo(output);
|
|
|
|
Plugin.Log.LogInfo($"extracted video: {resourceName}");
|
|
|
|
return temporaryVideoPath;
|
|
}
|
|
|
|
private void OnVideoPrepared(VideoPlayer player)
|
|
{
|
|
if (videoPlane == null)
|
|
return;
|
|
|
|
float aspect = (float)player.width / player.height;
|
|
|
|
float height = 0.5f;
|
|
|
|
float width = height * aspect;
|
|
|
|
videoPlane.transform.localScale =
|
|
new Vector3(width, height, 1f);
|
|
|
|
videoStartTime = Time.time;
|
|
focusedTime = 0f;
|
|
lastFocusCheckTime = Time.time;
|
|
currentlyFocused = false;
|
|
|
|
player.Play();
|
|
|
|
supposedToBePlaying = true;
|
|
|
|
videoPlayerRef.SetDirectAudioVolume(0, 0.175f);
|
|
|
|
if (firstTime)
|
|
{
|
|
firstTime = false;
|
|
NotificationManager.GCCLEJOGCCE.Play(NotificationManager.IBIDFAOPIPC.Medium,
|
|
"Sk0l is watching...\nLook at him...", 2.5f);
|
|
}
|
|
else
|
|
{
|
|
NotificationManager.GCCLEJOGCCE.Play(NotificationManager.IBIDFAOPIPC.Medium, "Sk0l is watching...", 2.5f);
|
|
}
|
|
}
|
|
|
|
private void TrackVideoFocus()
|
|
{
|
|
if (videoPlayerObject == null || videoPlane == null || !supposedToBePlaying)
|
|
return;
|
|
|
|
Transform cameraTransform = GetCamera();
|
|
|
|
if (cameraTransform == null)
|
|
return;
|
|
|
|
float currentTime = Time.time;
|
|
float deltaTime = currentTime - lastFocusCheckTime;
|
|
lastFocusCheckTime = currentTime;
|
|
|
|
Vector3 directionToVideo =
|
|
videoPlane.transform.position - cameraTransform.position;
|
|
|
|
float angle = Vector3.Angle(
|
|
cameraTransform.forward,
|
|
directionToVideo.normalized
|
|
);
|
|
|
|
// 15 degrees of leniency (how do you spell that word)
|
|
currentlyFocused = angle <= 15f;
|
|
|
|
if (currentlyFocused)
|
|
{
|
|
focusedTime += deltaTime;
|
|
}
|
|
}
|
|
} |