using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Photon.Pun;
using UnityEngine;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("XandImmersion")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+cbe3960eb2e020714dd18782bb9665520294abed")]
[assembly: AssemblyProduct("RepoXandIMod")]
[assembly: AssemblyTitle("RepoXandIMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
[Serializable]
public class ArielSound
{
public AudioSource Source;
public List<AudioClip> Sounds = new List<AudioClip>();
private AudioLowPassLogic LowPassLogic;
private bool HasLowPassLogic;
public AudioType Type;
[Range(0f, 1f)]
public float Volume = 0.5f;
[Range(0f, 1f)]
public float VolumeRandom = 0.1f;
[Range(0f, 5f)]
public float Pitch = 1f;
[Range(0f, 2f)]
public float PitchRandom = 0.1f;
[Range(0f, 1f)]
public float SpatialBlend = 1f;
[Range(0f, 5f)]
public float Doppler = 1f;
[Range(0f, 1f)]
public float ReverbMix = 1f;
[Range(0f, 5f)]
public float FalloffMultiplier = 1f;
[Space]
[Range(0f, 1f)]
public float OffscreenVolume = 1f;
[Range(0f, 1f)]
public float OffscreenFalloff = 1f;
[Space]
public List<Collider> LowPassIgnoreColliders = new List<Collider>();
private AudioClip LoopClip;
internal float LoopVolume;
internal float LoopVolumeCurrent;
internal float LoopVolumeFinal;
internal float LoopPitch;
internal float LoopFalloff;
internal float LoopFalloffFinal;
private float LoopOffScreenTime = 0.25f;
private float LoopOffScreenTimer;
private bool LoopOffScreen;
private float LoopOffScreenVolume;
private float LoopOffScreenFalloff;
internal float StartTimeOverride = 999999f;
private bool AudioInfoFetched;
public AudioSource Play(AudioSource audioSource, float volumeMultiplier = 1f, float falloffMultiplier = 1f, float offscreenVolumeMultiplier = 1f, float offscreenFalloffMultiplier = 1f)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Expected I4, but got Unknown
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
int index = 0;
if (Sounds.Count == 0)
{
return null;
}
AudioClip val = Sounds[index];
float pitch = Pitch + Random.Range(0f - PitchRandom, PitchRandom);
if (!Object.op_Implicit((Object)(object)audioSource))
{
GameObject audioDefault = AudioManager.instance.AudioDefault;
AudioType type = Type;
AudioType val2 = type;
switch (val2 - 1)
{
case 0:
audioDefault = AudioManager.instance.AudioHighFalloff;
break;
case 1:
audioDefault = AudioManager.instance.AudioFootstep;
break;
case 2:
audioDefault = AudioManager.instance.AudioMaterialImpact;
break;
case 3:
audioDefault = AudioManager.instance.AudioCutscene;
break;
case 4:
audioDefault = AudioManager.instance.AudioAmbienceBreaker;
break;
case 5:
audioDefault = AudioManager.instance.AudioLowFalloff;
break;
case 6:
audioDefault = AudioManager.instance.AudioGlobal;
break;
case 7:
audioDefault = AudioManager.instance.AudioHigherFalloff;
break;
case 8:
audioDefault = AudioManager.instance.AudioAttack;
break;
case 9:
audioDefault = AudioManager.instance.AudioPersistent;
break;
}
}
else if (!((Behaviour)audioSource).enabled)
{
return null;
}
audioSource.minDistance *= FalloffMultiplier;
audioSource.minDistance *= falloffMultiplier;
audioSource.maxDistance *= FalloffMultiplier;
audioSource.maxDistance *= falloffMultiplier;
audioSource.clip = Sounds[index];
audioSource.volume = (Volume + Random.Range(0f - VolumeRandom, VolumeRandom)) * volumeMultiplier;
if (SpatialBlend > 0f && (OffscreenVolume * offscreenVolumeMultiplier < 1f || OffscreenFalloff * offscreenFalloffMultiplier < 1f) && !SemiFunc.OnScreen(((Component)audioSource).transform.position, 0.1f, 0.1f))
{
audioSource.volume *= OffscreenVolume * offscreenVolumeMultiplier;
audioSource.minDistance *= OffscreenFalloff * offscreenFalloffMultiplier;
audioSource.maxDistance *= OffscreenFalloff * offscreenFalloffMultiplier;
}
audioSource.spatialBlend = SpatialBlend;
audioSource.reverbZoneMix = ReverbMix;
audioSource.dopplerLevel = Doppler;
audioSource.pitch = pitch;
audioSource.loop = false;
audioSource.volume = 2f;
if (SpatialBlend > 0f)
{
StartLowPass(audioSource);
}
audioSource.Play();
return audioSource;
}
public void Stop()
{
Source.Stop();
}
private void StartLowPass(AudioSource source)
{
LowPassLogic = ((Component)source).GetComponent<AudioLowPassLogic>();
if (Object.op_Implicit((Object)(object)LowPassLogic))
{
if (LowPassIgnoreColliders.Count > 0)
{
LowPassLogic.LowPassIgnoreColliders.AddRange(LowPassIgnoreColliders);
}
LowPassLogic.Setup();
HasLowPassLogic = true;
}
}
public void PlayLoop(bool playing, float fadeInSpeed, float fadeOutSpeed, float pitchMultiplier = 1f)
{
if (!AudioInfoFetched)
{
LoopClip = Sounds[Random.Range(0, Sounds.Count)];
Source.clip = LoopClip;
}
if (!playing)
{
if (Source.isPlaying)
{
LoopVolumeCurrent -= fadeOutSpeed * Time.deltaTime;
LoopVolumeCurrent = Mathf.Clamp(LoopVolumeCurrent, 0f, LoopVolume);
LoopOffScreenLogic();
Source.pitch = LoopPitch * pitchMultiplier;
if (HasLowPassLogic)
{
LowPassLogic.Volume = LoopVolumeFinal;
}
else
{
Source.volume = LoopVolumeFinal;
}
if (LoopVolumeFinal <= 0f)
{
Source.Stop();
}
}
}
else if (!Source.isPlaying)
{
LoopVolume = Volume + Random.Range(0f - VolumeRandom, VolumeRandom);
LoopPitch = Pitch + Random.Range(0f - PitchRandom, PitchRandom);
LoopVolumeCurrent = 0f;
LoopVolumeFinal = LoopVolumeCurrent;
Source.volume = LoopVolumeCurrent;
Source.pitch = LoopPitch * pitchMultiplier;
Source.spatialBlend = SpatialBlend;
Source.reverbZoneMix = ReverbMix;
Source.dopplerLevel = Doppler;
AudioSource source = Source;
source.minDistance *= FalloffMultiplier;
AudioSource source2 = Source;
source2.maxDistance *= FalloffMultiplier;
LoopFalloff = Source.maxDistance;
Source.time = Random.Range(0f, Source.clip.length);
if (StartTimeOverride != 999999f)
{
Source.time = StartTimeOverride;
}
Source.loop = true;
StartLowPass(Source);
Source.Play();
}
else
{
LoopVolumeCurrent += fadeInSpeed * Time.deltaTime;
LoopVolumeCurrent = Mathf.Clamp(LoopVolumeCurrent, 0f, LoopVolume);
LoopOffScreenLogic();
Source.pitch = LoopPitch * pitchMultiplier;
if (HasLowPassLogic)
{
LowPassLogic.Volume = LoopVolumeFinal;
}
else
{
Source.volume = LoopVolumeFinal;
}
}
}
private void LoopOffScreenLogic()
{
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
LoopVolumeFinal = LoopVolumeCurrent;
if (!(SpatialBlend > 0f) || (!(OffscreenVolume < 1f) && !(OffscreenFalloff < 1f)))
{
return;
}
if (LoopOffScreenTimer <= 0f)
{
LoopOffScreenTimer = LoopOffScreenTime;
LoopOffScreen = !SemiFunc.OnScreen(((Component)Source).transform.position, 0.1f, 0.1f);
}
else
{
LoopOffScreenTimer -= Time.deltaTime;
}
if (OffscreenVolume < 1f)
{
if (LoopOffScreen)
{
LoopOffScreenVolume = Mathf.Lerp(LoopOffScreenVolume, OffscreenVolume, 15f * Time.deltaTime);
}
else
{
LoopOffScreenVolume = Mathf.Lerp(LoopOffScreenVolume, 1f, 15f * Time.deltaTime);
}
LoopVolumeFinal *= LoopOffScreenVolume;
}
if (OffscreenFalloff < 1f)
{
if (LoopOffScreen)
{
LoopFalloffFinal = Mathf.Lerp(LoopFalloffFinal, LoopFalloff * OffscreenFalloff, 15f * Time.deltaTime);
}
else
{
LoopFalloffFinal = Mathf.Lerp(LoopFalloffFinal, LoopFalloff, 15f * Time.deltaTime);
}
if (HasLowPassLogic)
{
LowPassLogic.Falloff = LoopFalloffFinal;
}
else
{
Source.maxDistance = LoopFalloffFinal;
}
}
}
public static void CopySound(Sound from, Sound to)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
to.Source = from.Source;
to.Sounds = from.Sounds;
to.Type = from.Type;
to.Volume = from.Volume;
to.VolumeRandom = from.VolumeRandom;
to.Pitch = from.Pitch;
to.PitchRandom = from.PitchRandom;
to.SpatialBlend = from.SpatialBlend;
to.ReverbMix = from.ReverbMix;
to.Doppler = from.Doppler;
}
}
public static class SettingsLoader
{
public static Root Load(string filePath)
{
string text = File.ReadAllText(filePath);
return JsonConvert.DeserializeObject<Root>(text);
}
}
public class Assets
{
public List<Valuable> valuables { get; set; }
}
public class Keys
{
public string diagen { get; set; }
public string ariel { get; set; }
}
public class Root
{
public Keys keys { get; set; }
public Assets assets { get; set; }
}
public class Valuable
{
public string asset { get; set; }
public string name { get; set; }
[JsonProperty("use_stt")]
public bool useSTT { get; set; }
public string personality { get; set; }
[JsonProperty("talkingTime")]
public float talkingTime { get; set; }
[JsonProperty("ariel_speaker")]
public string arielSpeaker { get; set; }
public Valuable(string asset, string name, bool useSTT, string personality, float talkingTime, string arielSpeaker)
{
this.asset = asset;
this.name = name;
this.useSTT = useSTT;
this.personality = personality;
this.talkingTime = talkingTime;
this.arielSpeaker = arielSpeaker;
}
}
public class ValuableInteraction : MonoBehaviourPunCallbacks
{
public class Message
{
public string message;
public AudioClip? audio;
public bool played;
public Message(string msg)
{
message = msg;
audio = null;
played = false;
}
}
public struct DiagenResponse
{
public string StatusMessage;
public readonly bool Error;
public readonly string? ErrorMessage;
public DiagenResponse(string errorMessage, bool isError)
{
StatusMessage = (isError ? errorMessage : "");
Error = isError;
ErrorMessage = (isError ? errorMessage : null);
}
public DiagenResponse(string statusMessage)
{
StatusMessage = statusMessage;
Error = false;
ErrorMessage = null;
}
}
private struct DiagenRequestData
{
public string npc_name;
public string player_name;
public string core_description;
public object llama_generation_params;
public int history_length;
public string[] history;
}
public struct ArielResponse
{
public AudioClip? audioClip;
public readonly bool Error;
public readonly string? StatusMessage;
public ArielResponse(string statusMessage, bool isError = false)
{
audioClip = null;
Error = isError;
StatusMessage = statusMessage;
}
public ArielResponse(AudioClip audioClip, string statusMessage)
{
Error = false;
this.audioClip = audioClip;
StatusMessage = statusMessage;
}
}
public struct ArielRequestData
{
public string sentence;
public string audio_stream;
public float temperature;
public bool static_save;
}
private PhysGrabObject? physGrabObject;
private AudioSource? audioSource;
public ArielSound? voiceMessage;
private PhotonView photonView;
private Task? diagenTask = null;
private Task? arielTask = null;
private Root settings;
private Valuable valuable;
[Header("API Keys & Settings")]
public string DiagenApiKey = "dd82386c-8ea9-4cd3-85b0-9dbad5216be7";
public string ArielApiKey = "8a58d8c8-6a61-438b-8d95-6723b3d8aa1b";
private int apiErrorCount = 0;
public string ArielSpeaker = "Kid 3";
public float talkingTime = 15f;
public string Personality = "You are a weird Vodoo Doll that is super annoyed by the player that it is being disturbed.";
private string Instruction = "You try to be as annoying as possible to the player.";
public string PlayerName = "Player";
public string NpcName = "Alan";
private const int HistoryLength = 10;
public List<Message> messages = new List<Message>();
private bool isSpeakingSessionActive = false;
private float currentSessionTimeRemaining = 0f;
private int nextMessageToPlayIndex = 0;
private void Start()
{
photonView = ((Component)this).GetComponent<PhotonView>();
if ((Object)(object)photonView == (Object)null)
{
Debug.LogError((object)"ValuableInteraction is missing a PhotonView component. Please add one.");
((Behaviour)this).enabled = false;
return;
}
if ((Object)(object)((Component)this).GetComponent<AudioSource>() == (Object)null)
{
audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
}
else
{
audioSource = ((Component)this).GetComponent<AudioSource>();
}
string filePath = Path.Combine(Paths.PluginPath, "XandImmersion-RepoXandIMod", "settings.json");
settings = SettingsLoader.Load(filePath);
DiagenApiKey = settings.keys.diagen;
ArielApiKey = settings.keys.ariel;
valuable = settings.assets.valuables.FirstOrDefault((Valuable v) => ((Object)this).name.Contains(v.asset, StringComparison.OrdinalIgnoreCase));
if (valuable == null)
{
valuable = new Valuable(((Object)this).name, NpcName, useSTT: true, Personality, talkingTime, ArielSpeaker);
}
physGrabObject = ((Component)this).GetComponent<PhysGrabObject>();
if ((Object)(object)physGrabObject == (Object)null)
{
Debug.LogWarning((object)"PhysGrabObject not found on this GameObject.");
}
else
{
Debug.Log((object)"PhysGrabObject successfully accessed!");
}
Debug.Log((object)"Listing all components on this GameObject:");
Component[] components = ((Component)this).GetComponents<Component>();
foreach (Component val in components)
{
Debug.Log((object)(" - " + ((object)val).GetType().Name));
}
voiceMessage = new ArielSound();
}
private void Update()
{
if (PhotonNetwork.IsMasterClient)
{
MasterClientUpdate();
}
else if (isSpeakingSessionActive)
{
currentSessionTimeRemaining -= Time.deltaTime;
if (currentSessionTimeRemaining < 0f)
{
currentSessionTimeRemaining = 0f;
}
}
}
private void MasterClientUpdate()
{
if (apiErrorCount > 10)
{
return;
}
int num = messages.Count((Message m) => !m.played);
if (!isSpeakingSessionActive)
{
bool flag = false;
PlayerAvatar[] array = Object.FindObjectsOfType<PlayerAvatar>();
PlayerAvatar[] array2 = array;
foreach (PlayerAvatar playerAvatar in array2)
{
if (PlayerIsInSight(playerAvatar) && PlayerIsTalking(playerAvatar))
{
flag = true;
break;
}
}
if (flag && ((Object)(object)audioSource == (Object)null || !audioSource.isPlaying) && num > 0)
{
photonView.RPC("StartSpeakingSessionRPC", (RpcTarget)0, new object[1] { valuable.talkingTime });
}
}
else
{
currentSessionTimeRemaining -= Time.deltaTime;
if (currentSessionTimeRemaining <= 0f && ((Object)(object)audioSource == (Object)null || !audioSource.isPlaying))
{
photonView.RPC("StopSpeakingSessionRPC", (RpcTarget)0, Array.Empty<object>());
}
else if ((Object)(object)audioSource == (Object)null || !audioSource.isPlaying)
{
int num2 = FindNextUnplayedMessageIndex(-1);
if (num2 < messages.Count)
{
Message message = messages[num2];
if ((Object)(object)message.audio != (Object)null && !message.played)
{
photonView.RPC("PlayMessageRPC", (RpcTarget)0, new object[1] { num2 });
}
else if ((Object)(object)message.audio == (Object)null && !message.played && (arielTask == null || arielTask.IsCompleted))
{
arielTask = HandleArielAsyncCall(num2, message.message);
}
}
}
}
if (num <= 2 && (diagenTask == null || diagenTask.IsCompleted))
{
diagenTask = HandleDiagenInteractionAsync();
}
if (messages.Count <= 0 || (arielTask != null && !arielTask.IsCompleted))
{
return;
}
for (int j = 0; j < messages.Count; j++)
{
if ((Object)(object)messages[j].audio == (Object)null && !messages[j].played)
{
arielTask = HandleArielAsyncCall(j, messages[j].message);
break;
}
}
}
private void AttemptPlayMessageAtIndex(int messageIndex)
{
if (messageIndex >= messages.Count || messageIndex < 0)
{
return;
}
Message message = messages[messageIndex];
if (!((Object)(object)message.audio != (Object)null) || message.played)
{
return;
}
if (voiceMessage == null)
{
voiceMessage = new ArielSound();
}
if ((Object)(object)physGrabObject != (Object)null)
{
voiceMessage.Sounds = new List<AudioClip> { message.audio };
Debug.Log((object)$"Time: [{Time.time}]AttemptPlayMessageAtIndex: Playing message {messageIndex} ('{message.message}') with physGrabObject context.");
AudioSource val = voiceMessage.Play(audioSource);
if ((Object)(object)val != (Object)null)
{
audioSource = val;
}
}
else
{
Debug.LogWarning((object)$"AttemptPlayMessageAtIndex: physGrabObject is null for message {messageIndex}. Cannot determine play position.");
audioSource.clip = message.audio;
audioSource.Play();
}
}
[PunRPC]
private void StartSpeakingSessionRPC(float duration)
{
isSpeakingSessionActive = true;
currentSessionTimeRemaining = duration;
Debug.Log((object)$"RPC: Speaking session started by Master. Duration: {duration}");
}
[PunRPC]
private void StopSpeakingSessionRPC()
{
isSpeakingSessionActive = false;
currentSessionTimeRemaining = 0f;
if ((Object)(object)audioSource != (Object)null && audioSource.isPlaying)
{
audioSource.Stop();
}
Debug.Log((object)"RPC: Speaking session stopped by Master.");
}
[PunRPC]
private void AddNewMessagesRPC(string[] newDialogues)
{
bool flag = false;
foreach (string dialogue in newDialogues)
{
if (!string.IsNullOrWhiteSpace(dialogue) && !messages.Any((Message m) => m.message == dialogue.Trim()))
{
messages.Add(new Message(dialogue.Trim()));
flag = true;
}
}
if (flag)
{
Debug.Log((object)$"RPC: Added {newDialogues.Length} new message(s). Total messages: {messages.Count}");
}
}
[PunRPC]
private async void PlayMessageRPC(int messageIndex)
{
if (messageIndex < 0 || messageIndex >= messages.Count)
{
Debug.LogError((object)$"PlayMessageRPC: Invalid index {messageIndex}. Total messages: {messages.Count}");
return;
}
Message messageToPlay = messages[messageIndex];
if (messageToPlay.played && !PhotonNetwork.IsMasterClient)
{
Debug.LogWarning((object)$"PlayMessageRPC: Client already marked message {messageIndex} as played. Will play again if audio source is free.");
}
if ((Object)(object)messageToPlay.audio == (Object)null)
{
Debug.Log((object)$"PlayMessageRPC: Message {messageIndex} ('{messageToPlay.message}') has no audio locally. Attempting to fetch.");
AudioClip fetchedAudio = await CallAriel(messageToPlay.message);
if (!((Object)(object)fetchedAudio != (Object)null))
{
Debug.LogError((object)$"PlayMessageRPC: Failed to fetch audio for message {messageIndex} ('{messageToPlay.message}'). Cannot play.");
return;
}
messageToPlay.audio = fetchedAudio;
}
AttemptPlayMessageAtIndex(messageIndex);
if (!messageToPlay.played)
{
messageToPlay.played = true;
Debug.Log((object)$"RPC: Message {messageIndex} ('{messageToPlay.message}') is now being played and marked as played.");
}
else
{
Debug.Log((object)$"RPC: Message {messageIndex} ('{messageToPlay.message}') was already marked played, re-playing.");
}
}
private async Task HandleDiagenInteractionAsync()
{
if (!PhotonNetwork.IsMasterClient)
{
return;
}
try
{
int originalMessageCount = messages.Count;
if (await CallDiagen() && messages.Count > originalMessageCount)
{
List<string> newTexts = new List<string>();
for (int i = originalMessageCount; i < messages.Count; i++)
{
newTexts.Add(messages[i].message);
}
PhotonView obj = photonView;
object[] array = newTexts.ToArray();
obj.RPC("AddNewMessagesRPC", (RpcTarget)3, array);
}
}
catch (Exception ex)
{
Debug.LogError((object)$"Master HandleDiagenInteractionAsync Exception: {ex}");
}
}
private async Task HandleArielAsyncCall(int index, string message)
{
if (PhotonNetwork.IsMasterClient && index >= 0 && index < messages.Count && (Object)(object)messages[index].audio == (Object)null)
{
AudioClip audioClip = await CallAriel(message);
if ((Object)(object)audioClip != (Object)null)
{
messages[index].audio = audioClip;
Debug.Log((object)$"Master HandleArielAsyncCall: Audio fetched for message index {index}.");
}
}
}
public async Task<AudioClip?> CallAriel(string sentence)
{
ArielResponse arielResponse = await TextToAudio(sentence, valuable.arielSpeaker, ArielApiKey);
if (arielResponse.Error)
{
Debug.LogError((object)("CallAriel API Error: " + arielResponse.StatusMessage + " for sentence: " + sentence));
if (PhotonNetwork.IsMasterClient)
{
apiErrorCount++;
}
return null;
}
return arielResponse.audioClip;
}
private int FindNextUnplayedMessageIndex(int searchStartIndex)
{
for (int i = searchStartIndex + 1; i < messages.Count; i++)
{
if (!messages[i].played && (Object)(object)messages[i].audio != (Object)null)
{
return i;
}
if ((Object)(object)messages[i].audio == (Object)null && !messages[i].played)
{
return messages.Count;
}
}
return messages.Count;
}
private bool PlayerIsInSight(PlayerAvatar playerAvatar)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
Vector3 position = ((Component)this).transform.position;
if ((Object)(object)playerAvatar == (Object)null || (Object)(object)((Component)playerAvatar).transform == (Object)null)
{
Debug.LogError((object)"[Interaction] PlayerAvatar is null or its transform is null.");
return false;
}
Vector3 position2 = ((Component)playerAvatar).transform.position;
RaycastHit val = default(RaycastHit);
bool flag = Physics.Linecast(position, position2, ref val);
float num = Vector3.Distance(position, position2);
return num <= 6f && flag;
}
private bool PlayerIsTalking(PlayerAvatar playerAvatar, float volumeThreshold = 0.001f)
{
if ((Object)(object)playerAvatar == (Object)null)
{
return false;
}
if ((Object)(object)playerAvatar.voiceChat == (Object)null)
{
return false;
}
return playerAvatar.voiceChat.isTalking && playerAvatar.voiceChat.clipLoudness > volumeThreshold;
}
public async Task<bool> CallDiagen()
{
CleanupHistory();
DiagenResponse diagenResponse = await GenerateText(valuable.name, Instruction, valuable.personality, PlayerName, "Api-Key " + DiagenApiKey);
if (diagenResponse.Error)
{
Debug.LogError((object)("Diagen API Error: " + diagenResponse.ErrorMessage));
return false;
}
return true;
}
private void CleanupHistory()
{
if (messages.Count > 10)
{
int count = messages.Count - 10;
messages.RemoveRange(0, count);
}
}
public async Task<DiagenResponse> GenerateText(string npc_name, string instruction, string core_description, string player_name = "Player", string apiKey = "")
{
if (string.IsNullOrEmpty(apiKey))
{
Debug.LogError((object)"[PlayAriel] API Key is empty or null.");
return new DiagenResponse("API Key is required.", isError: true);
}
string[] history = new string[0];
int index = 0;
foreach (Message msg2 in this.messages)
{
history = ((index % 2 != 0) ? new string[0] : new string[1] { msg2.message });
index++;
}
DiagenRequestData requestData = new DiagenRequestData
{
npc_name = npc_name,
player_name = player_name,
core_description = core_description + " Answer in no more than 3 sentences.",
llama_generation_params = new
{
max_tokens = 80,
temperature = 1.243,
stream = true
},
history_length = 10,
history = history
};
string jsonBody = JsonConvert.SerializeObject((object)requestData);
byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonBody);
string url = "https://diagen-api.xandimmersion.com/generate-stream";
UnityWebRequest www = new UnityWebRequest(url, "POST");
try
{
www.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
www.SetRequestHeader("Content-Type", "application/json");
www.SetRequestHeader("Authorization", apiKey);
UnityWebRequestAsyncOperation operation = www.SendWebRequest();
while (!((AsyncOperation)operation).isDone)
{
await Task.Yield();
}
if ((int)www.result == 1)
{
string responseText = www.downloadHandler.text;
string[] messages = Regex.Replace(responseText, "\\s+", " ").Split(new char[3] { '.', '!', '?' }, StringSplitOptions.RemoveEmptyEntries);
if (messages.Length == 0 && !string.IsNullOrEmpty(responseText))
{
messages = new string[1] { responseText };
}
string[] array = messages;
foreach (string msg in array)
{
if (!string.IsNullOrWhiteSpace(msg))
{
this.messages.Add(new Message(msg.Trim()));
}
}
return new DiagenResponse("Stream processed successfully.");
}
Debug.LogError((object)("[PlayAriel] Diagen API Error: " + www.error));
Debug.LogError((object)$"[PlayAriel] Diagen API Response Code: {www.responseCode}");
string errorDetails = www.error ?? "Unknown error";
if (www.downloadHandler != null && !string.IsNullOrEmpty(www.downloadHandler.text))
{
errorDetails = errorDetails + ". Body: " + www.downloadHandler.text;
}
apiErrorCount++;
Debug.LogError((object)("[PlayAriel] Full Diagen API Error Details: " + errorDetails));
return new DiagenResponse($"Diagen API Error ({www.responseCode}): {www.error}", isError: true);
}
finally
{
((IDisposable)www)?.Dispose();
}
}
public async Task<ArielResponse> TextToAudio(string sentence, string speaker, string apiKey = "")
{
string url = "https://ariel-api.xandimmersion.com/tts/" + Uri.EscapeDataString(speaker);
ArielRequestData requestData = new ArielRequestData
{
sentence = sentence,
audio_stream = "true",
temperature = 0f,
static_save = true
};
string jsonBody = JsonConvert.SerializeObject((object)requestData);
byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonBody);
UnityWebRequest www = new UnityWebRequest(url, "POST");
try
{
www.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
www.downloadHandler = (DownloadHandler)new DownloadHandlerAudioClip(www.uri, (AudioType)20);
www.SetRequestHeader("Content-Type", "application/json");
www.SetRequestHeader("Authorization", "Api-Key " + apiKey);
UnityWebRequestAsyncOperation operation = www.SendWebRequest();
while (!((AsyncOperation)operation).isDone)
{
await Task.Yield();
}
if ((int)www.result != 1)
{
apiErrorCount++;
return new ArielResponse("Error While Sending: " + www.error, isError: true);
}
AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www);
if ((Object)(object)audioClip != (Object)null)
{
return new ArielResponse(audioClip, "AudioClip created succesfully.");
}
return new ArielResponse("AudioClip creation failed");
}
finally
{
((IDisposable)www)?.Dispose();
}
}
}
namespace RepoXandIMod
{
[BepInPlugin("XandImmersion.RepoXandIMod", "RepoXandIMod", "1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class RepoXandIMod : BaseUnityPlugin
{
private void Awake()
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"RepoXandIMod loaded!");
}
}
}