Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions src/plugins/gta3/std.asi/ModuleInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,23 @@ void ThePlugin::LocateCleo()
this->iCleoVersion = CLEO_GetVersion? CLEO_GetVersion() : 0;

Log("CLEO library version %X found at \"%s\"", iCleoVersion, p);
if(this->bHasNoCleoFolder = !IsPath((std::string(loader->gamepath) + "./CLEO/").c_str()))
Log("Warning: No CLEO folder found, may cause problems");

this->asiList.emplace_back(p, nullptr, hCleo);

// assume CLEO directory is located in root by default
this->cleoFolder = std::string(loader->gamepath) + "cleo";

// Try asking newer CLEO 5 where its folder it located
auto CLEO_GetCleoDirectory = (const char* (__stdcall*)()) GetProcAddress(hCleo, "_CLEO_GetCleoDirectory@0");
if(CLEO_GetCleoDirectory)
{
if(const char* cleoDir = CLEO_GetCleoDirectory())
this->cleoFolder = cleoDir;
}

if(this->bHasNoCleoFolder = !IsPath((this->cleoFolder + "\\").c_str()))
Log("Warning: No CLEO folder found, may cause problems");

this->asiList.back().PatchImports();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ namespace hacks
// Get path in iterator compatible with what CLEO.asi expects to receive
char* GetCleoCompatiblePath(char* buf)
{
// CLEO 5 allows relocating the CLEO folder out of the game root
// (e.g. to scripts\cleo), which breaks the "..\" form,
// so always prefer the absolute path.
if(plugin_ptr->cast<ThePlugin>().IsCLEO5())
return GetFullPath(buf);

// CLEO 4.3 needs a existing CLEO folder for the path relativity to work
if(plugin_ptr->cast<ThePlugin>().iCleoVersion > 0x401011E && plugin_ptr->cast<ThePlugin>().bHasNoCleoFolder)
return GetFullPath(buf);
Expand Down
20 changes: 20 additions & 0 deletions src/plugins/gta3/std.asi/args_translator/xtranslator_path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,32 @@ inline void path_translator_base::CallInfo::TranslatePathForMainExecutable(const
}
};

auto CheckCleoFolder = [&]()
{
auto& cleoDir = plugin_ptr->cast<ThePlugin>().cleoFolder;

if(!bSet && !cleoDir.empty())
{
struct PathBase { std::string translationPath; } cleo;
cleo.translationPath = cleoDir;
bSet = CxBuildPath(p, cleo, currdir, arg, build_path, false);
}
};

// Run the tries by priority based on what is the caller
if(asi->bIsCleo)
{
// Cleo scripts first
CheckCleoScripts();
CheckASI();

// File operations worked only by accident in some legacy CLEO scripts,
// because modloader added CLEO folder containing .cleo plugins to search path.
// As CLEO5 moved them to cleo_plugins, we need to keep
// searching there to preserve backward compatibility.
// https://github.com/cleolibrary/CLEO5/issues/589
if(plugin_ptr->cast<ThePlugin>().IsCLEO5())
CheckCleoFolder();
}
else
{
Expand Down
11 changes: 9 additions & 2 deletions src/plugins/gta3/std.asi/asi.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,15 @@ class ThePlugin : public modloader::basic_plugin
typedef std::list<CsInfo> CsInfoList;

// CLEO.ASI version
int iCleoVersion;
bool bHasNoCleoFolder;
int iCleoVersion = 0;
bool bHasNoCleoFolder = false;

// Absolute path to the CLEO data folder, without a trailing path separator.
// Can be ("<game>\cleo") or relative to cleo.asi ("<game>\scripts\cleo")
std::string cleoFolder;

// CLEO 5.0 or newer (support for relocatable CLEO folder and cleo_plugins)
bool IsCLEO5() const { return iCleoVersion >= 0x05000000; }

// Set to true when loading - do not translate relative paths, as we're chdir'd into modloader already
// Set by the DLL Load Notification
Expand Down