Skip to content

Commit

Permalink
Fix crash on soft restart and improve autonya
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenAlex committed Jul 24, 2024
1 parent a56fce9 commit b8bcf89
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 89 deletions.
9 changes: 6 additions & 3 deletions include/ImageView.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,24 @@
#include "UnityEngine/Material.hpp"
#include <functional>

DECLARE_CLASS_CODEGEN(NyaUtils, ImageView, UnityEngine::MonoBehaviour,
DECLARE_CLASS_CODEGEN(Nya, ImageView, UnityEngine::MonoBehaviour,
public:

std::string lastImageURL;
std::string tempName;

// AutoNya
float timeSinceLastNya = 0.0f;

DECLARE_CTOR(ctor);
DECLARE_DTOR(dtor);
DECLARE_SIMPLE_DTOR();

DECLARE_INSTANCE_FIELD(HMUI::ImageView*, imageView);
DECLARE_INSTANCE_FIELD(bool, autoNyaRunning);
DECLARE_INSTANCE_FIELD(bool, autoNyaNewImage);
DECLARE_INSTANCE_FIELD(bool, isLoading);
DECLARE_INSTANCE_METHOD(void, Awake);
DECLARE_INSTANCE_METHOD(void, LateUpdate);
DECLARE_INSTANCE_METHOD(void, OnEnable);
DECLARE_INSTANCE_METHOD(void, OnDisable);
DECLARE_INSTANCE_METHOD(void, OnNyaPhysicalClick);
Expand All @@ -42,7 +46,6 @@ DECLARE_CLASS_CODEGEN(NyaUtils, ImageView, UnityEngine::MonoBehaviour,
void SaveImage();
bool HasImageToSave();
void SetErrorImage();
custom_types::Helpers::Coroutine AutoNyaCoro();

// Event to sub to when image started loading, returns isLoading, meaning that the image is loading
UnorderedEventCallback<bool> imageLoadingChange;
Expand Down
2 changes: 1 addition & 1 deletion include/ModifiersMenu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ DECLARE_CLASS_CODEGEN(Nya, ModifiersMenu, UnityEngine::MonoBehaviour,
DECLARE_INSTANCE_FIELD(UnityW<HMUI::ImageView>, NYA);
// DECLARE_INSTANCE_FIELD(bool, );
DECLARE_INSTANCE_FIELD(UnityW<UnityEngine::UI::Button>, nyaButton);
DECLARE_INSTANCE_FIELD(UnityW<NyaUtils::ImageView>, imageView);
DECLARE_INSTANCE_FIELD(UnityW<Nya::ImageView>, imageView);
DECLARE_INSTANCE_FIELD(bool, initialized);


Expand Down
5 changes: 3 additions & 2 deletions include/NyaFloatingUI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "UI/Modals/SettingsMenu.hpp"
#include "ImageView.hpp"
#include "bsml/shared/BSML/FloatingScreen/FloatingScreen.hpp"
#include "bsml/shared/BSML.hpp"


using namespace UnityEngine::UI;
Expand All @@ -34,7 +35,7 @@ DECLARE_CLASS_CODEGEN(Nya, NyaFloatingUI, UnityEngine::MonoBehaviour,
void onUnPause();
void onResultsScreenActivate();
void onResultsScreenDeactivate();
void updateCoordinates(BSML::FloatingScreen* self, const BSML::FloatingScreenHandleEventArgs& args);
void updateCoordinates(UnityW<BSML::FloatingScreen> self, const BSML::FloatingScreenHandleEventArgs& args);
void updateCoordinates(UnityEngine::Transform* transform);
void updateCoordinates(UnityEngine::Vector3 position, UnityEngine::Vector3 eulerRotation);
void OnActiveSceneChanged(UnityEngine::SceneManagement::Scene current, UnityEngine::SceneManagement::Scene _);
Expand All @@ -61,7 +62,7 @@ DECLARE_CLASS_CODEGEN(Nya, NyaFloatingUI, UnityEngine::MonoBehaviour,

// NYA
DECLARE_INSTANCE_FIELD(UnityW<HMUI::ImageView>, NYA);
DECLARE_INSTANCE_FIELD(UnityW<NyaUtils::ImageView>, imageView);
DECLARE_INSTANCE_FIELD(UnityW<Nya::ImageView>, imageView);
DECLARE_INSTANCE_FIELD(UnityW<UnityEngine::Plane>, plane);

DECLARE_INSTANCE_FIELD(UnityW<UnityEngine::UI::Button>, nyaButton);
Expand Down
24 changes: 12 additions & 12 deletions include/UI/Modals/NSFWConsent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,23 +53,23 @@ DECLARE_CLASS_CODEGEN(Nya::UI::Modals, NSFWConsent, UnityEngine::MonoBehaviour,
DECLARE_INSTANCE_METHOD(bool, isShown );

// // Settings buttons and modal
DECLARE_INSTANCE_FIELD(BSML::ModalView*, modal);
DECLARE_INSTANCE_FIELD(UnityW<BSML::ModalView>, modal);

DECLARE_INSTANCE_FIELD(VerticalLayoutGroup *, mainLayout);
DECLARE_INSTANCE_FIELD(HorizontalLayoutGroup *, hornyPastryPufferLayout);
DECLARE_INSTANCE_FIELD(UnityW<VerticalLayoutGroup>, mainLayout);
DECLARE_INSTANCE_FIELD(UnityW<HorizontalLayoutGroup>, hornyPastryPufferLayout);

DECLARE_INSTANCE_FIELD(HorizontalLayoutGroup *, buttonsLayout);
DECLARE_INSTANCE_FIELD(HorizontalLayoutGroup *, sliderLayout);
DECLARE_INSTANCE_FIELD(UnityW<HorizontalLayoutGroup>, buttonsLayout);
DECLARE_INSTANCE_FIELD(UnityW<HorizontalLayoutGroup>, sliderLayout);


DECLARE_INSTANCE_FIELD(TextMeshProUGUI *, topText);
DECLARE_INSTANCE_FIELD(TextMeshProUGUI *, midText);
DECLARE_INSTANCE_FIELD(ImageView *, midImage);
DECLARE_INSTANCE_FIELD(UnityW<TextMeshProUGUI>, topText);
DECLARE_INSTANCE_FIELD(UnityW<TextMeshProUGUI>, midText);
DECLARE_INSTANCE_FIELD(UnityW<HMUI::ImageView>, midImage);


DECLARE_INSTANCE_FIELD(Button *, noButton);
DECLARE_INSTANCE_FIELD(Button *, yesButton);
DECLARE_INSTANCE_FIELD(UnityW<Button>, noButton);
DECLARE_INSTANCE_FIELD(UnityW<Button>, yesButton);

DECLARE_INSTANCE_FIELD(BSML::SliderSetting *, slider);
DECLARE_INSTANCE_FIELD(Button *, submitButton);
DECLARE_INSTANCE_FIELD(UnityW<BSML::SliderSetting>, slider);
DECLARE_INSTANCE_FIELD(UnityW<Button>, submitButton);
)
5 changes: 4 additions & 1 deletion qpm.shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
}
},
"workspace": {
"scripts": {}
"scripts": {},
"qmodIncludeDirs": [],
"qmodIncludeFiles": [],
"qmodOutput": null
},
"dependencies": [
{
Expand Down
102 changes: 39 additions & 63 deletions src/ImageView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,14 @@
#include "Events.hpp"
#include "System/GC.hpp"


// Necessary
DEFINE_TYPE(NyaUtils, ImageView);
DEFINE_TYPE(Nya, ImageView);

using namespace UnityEngine;
using namespace NyaAPI;

// Start
void NyaUtils::ImageView::ctor()
void Nya::ImageView::ctor()
{
this->lastImageURL = "";
this->isNSFW = false;
Expand All @@ -59,20 +58,36 @@ void NyaUtils::ImageView::ctor()
}

// Awake
void NyaUtils::ImageView::Awake()
void Nya::ImageView::Awake()
{
// Get the image view
imageView = this->get_gameObject()->GetComponent<HMUI::ImageView *>();
}

bool NyaUtils::ImageView::HasImageToSave() {
bool Nya::ImageView::HasImageToSave() {
return (this->lastImageURL != "" && this->tempName != "" && Nya::Utils::IsImage(this->tempName));
}

// AutoNya related stuff
void Nya::ImageView::LateUpdate()
{
bool autoNya = getNyaConfig().AutoNya.GetValue();
if (!autoNya || this->isLoading) return;
int autoNyaDelay = getNyaConfig().AutoNyaDelay.GetValue();
// Time in seconds since the last frame
float delta = Time::get_deltaTime();
// Add the time since the last frame to the time since the last nya
this->timeSinceLastNya += delta;

if (this->timeSinceLastNya >= (float) autoNyaDelay) {
// Get new image
this->GetImage(nullptr);
}
}

// TODO: review crash related to this (https://analyzer.questmodding.com/crashes/4V2U)
// filesystem error: in rename: No such file or directory [/sdcard/ModData/com.beatgames.beatsaber/Mods/Nya/Temp/edOwqtb4.png] [/sdcard/ModData/com.beatgames.beatsaber/Mods/Nya/Images/nsfw/edOwqtb4.png]
void NyaUtils::ImageView::SaveImage() {
void Nya::ImageView::SaveImage() {
if (this->lastImageURL != "" && this->tempName != "" && Nya::Utils::IsImage(this->tempName)) {
INFO("MOVING FILE");
std::string original = NyaGlobals::tempPath + this->tempName;
Expand All @@ -91,9 +106,11 @@ void NyaUtils::ImageView::SaveImage() {
}

// Update
void NyaUtils::ImageView::GetImage(std::function<void(bool success)> finished = nullptr)
void Nya::ImageView::GetImage(std::function<void(bool success)> finished = nullptr)
{
this->isLoading = true;
// Reset time since last nya
this->timeSinceLastNya = 0.0f;
if (this->imageLoadingChange.size() > 0) this->imageLoadingChange.invoke(true);

// Delete the last downloaded image
Expand Down Expand Up @@ -269,6 +286,12 @@ void NyaUtils::ImageView::GetImage(std::function<void(bool success)> finished =
this->lastImageURL = url;
this->tempName = fileFullName;
this->isNSFW = NSFWEnabled;

// Check if image view is still valid and if not, don't set the image
if (this->imageView == nullptr || this->imageView->___m_CachedPtr.m_value == nullptr) {
if (finished != nullptr) finished(false);
return;
}

BSML::Utilities::SetImage(this->imageView, "file://" + path, true, BSML::Utilities::ScaleOptions(), false, [finished, this]() {
// Set is loading status
Expand Down Expand Up @@ -296,80 +319,33 @@ void NyaUtils::ImageView::GetImage(std::function<void(bool success)> finished =
}
}

void NyaUtils::ImageView::SetErrorImage()
void Nya::ImageView::SetErrorImage()
{
// If the image view is not valid, don't set the image
if (this->imageView == nullptr || this->imageView->___m_CachedPtr.m_value == nullptr) return;

Nya::Utils::RemoveAnimationUpdater(this->imageView);
this->imageView->set_sprite(BSML::Lite::ArrayToSprite(Assets::Chocola_Dead_png));
}

void NyaUtils::ImageView::dtor()
{
}

void NyaUtils::ImageView::OnNyaPhysicalClick(){
void Nya::ImageView::OnNyaPhysicalClick(){
if (this->isLoading) {
return;
}

this->GetImage(nullptr);
}

void NyaUtils::ImageView::OnEnable()
void Nya::ImageView::OnEnable()
{
// Subscribe to physical click
Nya::GlobalEvents::onControllerNya += {&NyaUtils::ImageView::OnNyaPhysicalClick ,this};

if (getNyaConfig().AutoNya.GetValue() && this->autoNyaRunning == false) {
this->StartCoroutine(custom_types::Helpers::new_coro(this->AutoNyaCoro()));
}
Nya::GlobalEvents::onControllerNya += {&Nya::ImageView::OnNyaPhysicalClick ,this};
}

void NyaUtils::ImageView::OnDisable()
void Nya::ImageView::OnDisable()
{
this->autoNyaRunning = false;
// Unsubscribe to physical click
Nya::GlobalEvents::onControllerNya -= {&NyaUtils::ImageView::OnNyaPhysicalClick ,this};
}


// Coroutine for autonya
custom_types::Helpers::Coroutine NyaUtils::ImageView::AutoNyaCoro()
{
// Extra guard agains simultaneous autonyas just to be sure
if (this->autoNyaRunning) {
co_return;
};
autoNyaNewImage = true;
this->autoNyaRunning = true;

while (true) {
// Check if it's enabled
bool enabled = getNyaConfig().AutoNya.GetValue();

// Quit if not enabled or is not running
if (!enabled || !this->autoNyaRunning) {
this->autoNyaRunning = false;
co_return;
}

if (autoNyaNewImage) {
autoNyaNewImage = false;
int waitTime = getNyaConfig().AutoNyaDelay.GetValue();
co_yield reinterpret_cast<System::Collections::IEnumerator*>(WaitForSeconds::New_ctor(waitTime));

// Check again cause if it's disabled we want to quit after the delay
enabled = getNyaConfig().AutoNya.GetValue();
if (!enabled || !this->autoNyaRunning) {
this->autoNyaRunning = false;
co_return;
}
this->GetImage([this](bool success){
this->autoNyaNewImage = true;
});
}

co_yield nullptr;
}


Nya::GlobalEvents::onControllerNya -= {&Nya::ImageView::OnNyaPhysicalClick ,this};
}
2 changes: 1 addition & 1 deletion src/ModifiersMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace Nya {
NYA->set_sprite(BSML::Lite::ArrayToSprite(Assets::placeholder_png));
auto ele = NYA->get_gameObject()->AddComponent<UnityEngine::UI::LayoutElement*>();
DEBUG("Adds component");
this->imageView = NYA->get_gameObject()->AddComponent<NyaUtils::ImageView*>();
this->imageView = NYA->get_gameObject()->AddComponent<Nya::ImageView*>();
ele->set_preferredHeight(50);
ele->set_preferredWidth(50);

Expand Down
2 changes: 1 addition & 1 deletion src/NyaFloatingUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace Nya {
auto ele = NYA->get_gameObject()->AddComponent<UnityEngine::UI::LayoutElement*>();

DEBUG("Adding image view to the game object");
imageView = NYA->get_gameObject()->AddComponent<NyaUtils::ImageView*>();
imageView = NYA->get_gameObject()->AddComponent<Nya::ImageView*>();
ele->set_preferredHeight(70);
ele->set_preferredWidth(70);

Expand Down
6 changes: 3 additions & 3 deletions src/UI/Modals/SettingsMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void SettingsMenu::Awake() {
{
this->downloadButton =
BSML::Lite::CreateUIButton(horz->get_transform(), "Download Nya", "PracticeButton", [this]() {
auto imageView = this->get_gameObject()->GetComponent<NyaUtils::ImageView*>();
UnityW<Nya::ImageView> imageView = this->get_gameObject()->GetComponent<Nya::ImageView*>();
imageView->SaveImage();
this->downloadButton->set_interactable(false);
this->settingsModal->Hide(true, nullptr);
Expand All @@ -155,7 +155,7 @@ void SettingsMenu::Awake() {
autoNyaButton = BSML::Lite::CreateToggle(horz2, "AutoNya", getNyaConfig().AutoNya.GetValue(), [this](bool value) {
getNyaConfig().AutoNya.SetValue(value);
if (value) {
NyaUtils::ImageView* imageView = this->get_gameObject()->GetComponent<NyaUtils::ImageView*>();
UnityW<Nya::ImageView> imageView = this->get_gameObject()->GetComponent<Nya::ImageView*>();
if (imageView) {
imageView->OnEnable();
}
Expand Down Expand Up @@ -326,7 +326,7 @@ void SettingsMenu::SwitchTab(int idx) {

void SettingsMenu::Show() {
INFO("Settings button clicked");
auto imageView = this->get_gameObject()->GetComponent<NyaUtils::ImageView*>();
UnityW<Nya::ImageView> imageView = this->get_gameObject()->GetComponent<Nya::ImageView*>();
this->downloadButton->set_interactable(imageView->HasImageToSave());

// Run UI on the main thread
Expand Down
4 changes: 2 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,10 @@ MAKE_HOOK_MATCH(FixedUpdateHook, &GlobalNamespace::OculusVRHelper::FixedUpdate,
// Called later on in the game loading - a good time to install function hooks
extern "C" __attribute__((visibility("default"))) void late_load() {
il2cpp_functions::Init();
BSML::Init();

// Should always be before any custom types can possibly be used
custom_types::Register::AutoRegister();

BSML::Init();

// Load the config - make sure this is after il2cpp_functions::Init();
getNyaConfig().Init(modInfo);
Expand Down

0 comments on commit b8bcf89

Please sign in to comment.