2023-06-05 20:42:22 -04:00
|
|
|
#include <Geode/DefaultInclude.hpp>
|
|
|
|
|
|
|
|
#ifdef GEODE_IS_ANDROID
|
|
|
|
|
|
|
|
using namespace geode::prelude;
|
|
|
|
|
|
|
|
#include <Geode/utils/cocos.hpp>
|
|
|
|
#include <Geode/loader/Dirs.hpp>
|
|
|
|
#include <Geode/utils/web.hpp>
|
|
|
|
#include <ghc/filesystem.hpp>
|
|
|
|
|
2023-10-03 10:51:12 -04:00
|
|
|
#include <jni.h>
|
|
|
|
#include <Geode/cocos/platform/android/jni/JniHelper.h>
|
|
|
|
|
2023-10-01 16:25:13 -04:00
|
|
|
bool utils::clipboard::write(std::string const& data) {
|
2023-10-03 10:51:12 -04:00
|
|
|
JniMethodInfo t;
|
|
|
|
if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", "writeClipboard", "(Ljava/lang/String;)V")) {
|
|
|
|
jstring stringArg1 = t.env->NewStringUTF(data.c_str());
|
|
|
|
|
|
|
|
t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg1);
|
|
|
|
|
|
|
|
t.env->DeleteLocalRef(stringArg1);
|
|
|
|
t.env->DeleteLocalRef(t.classID);
|
|
|
|
return true;
|
|
|
|
}
|
2023-10-01 16:25:13 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string utils::clipboard::read() {
|
2023-10-03 10:51:12 -04:00
|
|
|
JniMethodInfo t;
|
|
|
|
if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", "readClipboard", "()Ljava/lang/String;")) {
|
|
|
|
jstring stringResult = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID);
|
|
|
|
|
|
|
|
std::string result = JniHelper::jstring2string(stringResult);
|
|
|
|
|
|
|
|
t.env->DeleteLocalRef(stringResult);
|
|
|
|
t.env->DeleteLocalRef(t.classID);
|
|
|
|
return result;
|
|
|
|
}
|
2023-10-01 16:25:13 -04:00
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2023-10-03 10:51:12 -04:00
|
|
|
CCPoint cocos::getMousePos() {
|
|
|
|
return CCPoint(0, 0);
|
|
|
|
}
|
|
|
|
|
2023-06-05 20:42:22 -04:00
|
|
|
ghc::filesystem::path dirs::getGameDir() {
|
2023-09-16 10:11:36 -04:00
|
|
|
return ghc::filesystem::path(
|
|
|
|
"/storage/emulated/0/Android/data/com.geode.launcher/files/game"
|
|
|
|
// "/data/user/0/com.geode.launcher/files/"
|
|
|
|
/*CCFileUtils::sharedFileUtils()->getWritablePath().c_str()*/
|
|
|
|
);
|
2023-06-05 20:42:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
ghc::filesystem::path dirs::getSaveDir() {
|
2023-09-16 10:11:36 -04:00
|
|
|
return ghc::filesystem::path(
|
|
|
|
"/storage/emulated/0/Android/data/com.geode.launcher/files/save"
|
|
|
|
// "/data/user/0/com.geode.launcher/files/"
|
|
|
|
/*CCFileUtils::sharedFileUtils()->getWritablePath().c_str()*/
|
|
|
|
);
|
2023-06-05 20:42:22 -04:00
|
|
|
}
|
|
|
|
|
2023-09-16 10:22:30 -04:00
|
|
|
ghc::filesystem::path dirs::getModRuntimeDir() {
|
|
|
|
return ghc::filesystem::path(
|
|
|
|
"/data/user/0/com.geode.launcher/files/geode/unzipped"
|
|
|
|
);
|
|
|
|
// return dirs::getGeodeDir() / "unzipped";
|
|
|
|
}
|
|
|
|
|
2023-06-05 20:42:22 -04:00
|
|
|
void utils::web::openLinkInBrowser(std::string const& url) {
|
|
|
|
CCApplication::sharedApplication()->openURL(url.c_str());
|
|
|
|
}
|
|
|
|
|
2023-10-03 10:51:12 -04:00
|
|
|
bool utils::file::openFolder(ghc::filesystem::path const& path) {
|
|
|
|
JniMethodInfo t;
|
|
|
|
if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", "openFolder", "(Ljava/lang/String;)Z")) {
|
|
|
|
jstring stringArg1 = t.env->NewStringUTF(path.string().c_str());
|
|
|
|
|
|
|
|
jboolean result = t.env->CallStaticBooleanMethod(t.classID, t.methodID, stringArg1);
|
|
|
|
|
|
|
|
t.env->DeleteLocalRef(stringArg1);
|
|
|
|
t.env->DeleteLocalRef(t.classID);
|
|
|
|
return result;
|
|
|
|
}
|
2023-06-05 20:42:22 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-10-08 09:38:17 -04:00
|
|
|
|
|
|
|
static utils::MiniFunction<void(ghc::filesystem::path)> s_fileCallback;
|
|
|
|
static utils::MiniFunction<void(std::vector<ghc::filesystem::path>)> s_filesCallback;
|
|
|
|
static utils::MiniFunction<void()> s_failedCallback;
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
JNIEXPORT void JNICALL Java_com_geode_launcher_utils_GeodeUtils_selectFileCallback(
|
|
|
|
JNIEnv *env,
|
|
|
|
jobject,
|
|
|
|
jstring data
|
|
|
|
) {
|
|
|
|
auto isCopy = jboolean();
|
|
|
|
auto dataStr = env->GetStringUTFChars(data, &isCopy);
|
|
|
|
|
|
|
|
log::debug("Selected file: {}", dataStr);
|
|
|
|
|
|
|
|
s_fileCallback(dataStr);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
JNIEXPORT void JNICALL Java_com_geode_launcher_utils_GeodeUtils_selectFilesCallback(
|
|
|
|
JNIEnv *env,
|
|
|
|
jobject,
|
|
|
|
jobjectArray datas
|
|
|
|
) {
|
|
|
|
auto isCopy = jboolean();
|
|
|
|
auto count = env->GetArrayLength(datas);
|
|
|
|
auto result = std::vector<ghc::filesystem::path>();
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
auto data = (jstring)env->GetObjectArrayElement(datas, i);
|
|
|
|
auto dataStr = env->GetStringUTFChars(data, &isCopy);
|
|
|
|
result.push_back(dataStr);
|
|
|
|
|
|
|
|
log::debug("Selected file {}: {}", i, dataStr);
|
|
|
|
}
|
|
|
|
|
|
|
|
s_filesCallback(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
JNIEXPORT void JNICALL Java_com_geode_launcher_utils_GeodeUtils_failedCallback(
|
|
|
|
JNIEnv *env,
|
|
|
|
jobject
|
|
|
|
) {
|
|
|
|
if (s_failedCallback) s_failedCallback();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<ghc::filesystem::path> file::pickFile(file::PickMode mode, file::FilePickOptions const& options) {
|
|
|
|
return Err("Use the callback version");
|
|
|
|
}
|
|
|
|
|
|
|
|
void file::pickFile(
|
|
|
|
PickMode mode, FilePickOptions const& options,
|
|
|
|
utils::MiniFunction<void(ghc::filesystem::path)> callback,
|
|
|
|
utils::MiniFunction<void()> failed
|
|
|
|
) {
|
|
|
|
s_fileCallback = callback;
|
|
|
|
s_failedCallback = failed;
|
|
|
|
|
|
|
|
std::string method;
|
|
|
|
switch (mode) {
|
|
|
|
case file::PickMode::OpenFile:
|
|
|
|
method = "selectFile";
|
|
|
|
break;
|
|
|
|
case file::PickMode::SaveFile:
|
|
|
|
method = "createFile";
|
|
|
|
break;
|
|
|
|
case file::PickMode::OpenFolder:
|
|
|
|
method = "selectFolder";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
JniMethodInfo t;
|
|
|
|
if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", method.c_str(), "(Ljava/lang/String;)Z")) {
|
|
|
|
jstring stringArg1 = t.env->NewStringUTF(options.defaultPath.value_or(ghc::filesystem::path()).string().c_str());
|
|
|
|
|
|
|
|
jboolean result = t.env->CallStaticBooleanMethod(t.classID, t.methodID, stringArg1);
|
|
|
|
|
|
|
|
t.env->DeleteLocalRef(stringArg1);
|
|
|
|
t.env->DeleteLocalRef(t.classID);
|
|
|
|
if (result) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (s_failedCallback) s_failedCallback();
|
|
|
|
}
|
|
|
|
|
|
|
|
Result<std::vector<ghc::filesystem::path>> file::pickFiles(file::FilePickOptions const& options) {
|
|
|
|
return Err("Use the callback version");
|
|
|
|
}
|
|
|
|
|
|
|
|
void file::pickFiles(
|
|
|
|
FilePickOptions const& options,
|
|
|
|
utils::MiniFunction<void(std::vector<ghc::filesystem::path>)> callback,
|
|
|
|
utils::MiniFunction<void()> failed
|
|
|
|
) {
|
|
|
|
s_filesCallback = callback;
|
|
|
|
s_failedCallback = failed;
|
|
|
|
|
|
|
|
JniMethodInfo t;
|
|
|
|
if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", "selectFiles", "(Ljava/lang/String;)Z")) {
|
|
|
|
jstring stringArg1 = t.env->NewStringUTF(options.defaultPath.value_or(ghc::filesystem::path()).string().c_str());
|
|
|
|
|
|
|
|
jboolean result = t.env->CallStaticBooleanMethod(t.classID, t.methodID, stringArg1);
|
|
|
|
|
|
|
|
t.env->DeleteLocalRef(stringArg1);
|
|
|
|
t.env->DeleteLocalRef(t.classID);
|
|
|
|
if (result) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (s_failedCallback) s_failedCallback();
|
2023-06-05 20:42:22 -04:00
|
|
|
}
|
|
|
|
|
2023-09-14 08:56:51 -04:00
|
|
|
void geode::utils::game::launchLoaderUninstaller(bool deleteSaveData) {
|
|
|
|
log::error("Launching Geode uninstaller is not supported on android");
|
|
|
|
}
|
|
|
|
|
|
|
|
void geode::utils::game::exit() {
|
2023-10-03 10:51:12 -04:00
|
|
|
if (CCApplication::sharedApplication() &&
|
|
|
|
(GameManager::get()->m_playLayer || GameManager::get()->m_levelEditorLayer)) {
|
|
|
|
log::error("Cannot exit in PlayLayer or LevelEditorLayer!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
AppDelegate::get()->trySaveGame();
|
|
|
|
// AppDelegate::get()->showLoadingCircle(false, true);
|
|
|
|
|
2023-10-01 12:18:40 -04:00
|
|
|
CCDirector::get()->getActionManager()->addAction(CCSequence::create(
|
|
|
|
CCDelayTime::create(0.5f),
|
|
|
|
CCCallFunc::create(nullptr, callfunc_selector(MenuLayer::endGame)),
|
|
|
|
nullptr
|
2023-10-03 10:51:12 -04:00
|
|
|
), CCDirector::get()->getRunningScene(), false);
|
2023-09-14 08:56:51 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void geode::utils::game::restart() {
|
2023-10-03 10:51:12 -04:00
|
|
|
if (CCApplication::sharedApplication() &&
|
|
|
|
(GameManager::get()->m_playLayer || GameManager::get()->m_levelEditorLayer)) {
|
|
|
|
log::error("Cannot restart in PlayLayer or LevelEditorLayer!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
class Exit : public CCObject {
|
|
|
|
public:
|
|
|
|
void restart() {
|
|
|
|
JniMethodInfo t;
|
|
|
|
if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", "restartGame", "()V")) {
|
|
|
|
t.env->CallStaticVoidMethod(t.classID, t.methodID);
|
|
|
|
|
|
|
|
t.env->DeleteLocalRef(t.classID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2023-09-14 08:56:51 -04:00
|
|
|
// Not implemented
|
2023-10-03 10:51:12 -04:00
|
|
|
// log::error("Restarting the game is not implemented on android");
|
|
|
|
|
|
|
|
AppDelegate::get()->trySaveGame();
|
|
|
|
// AppDelegate::get()->showLoadingCircle(false, true);
|
|
|
|
|
|
|
|
CCDirector::get()->getActionManager()->addAction(CCSequence::create(
|
|
|
|
CCDelayTime::create(0.5f),
|
|
|
|
CCCallFunc::create(nullptr, callfunc_selector(Exit::restart)),
|
|
|
|
nullptr
|
|
|
|
), CCDirector::get()->getRunningScene(), false);
|
2023-09-14 08:56:51 -04:00
|
|
|
}
|
|
|
|
|
2023-06-05 20:42:22 -04:00
|
|
|
#endif
|