Skip to content

Commit

Permalink
Finally fixed unicode paths trouble
Browse files Browse the repository at this point in the history
So, we are finally can put LunaLUA-SMBX into any folders like C:\Users\Вася Пупкин\Documents\...
  • Loading branch information
Wohlstand committed Mar 24, 2016
1 parent 02f5abc commit 08d531b
Show file tree
Hide file tree
Showing 29 changed files with 398 additions and 201 deletions.
21 changes: 19 additions & 2 deletions LunaDLL.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ INCLUDEPATH += $$PWD/LunaDll/libs/lua_mingw/include
INCLUDEPATH += $$PWD/LunaDll/libs/luabind-include
INCLUDEPATH += $$PWD/LunaDll/libs/sdl/include
INCLUDEPATH += $$PWD/LunaDll/libs/glew/include
INCLUDEPATH += $$PWD/LunaDll/libs/glew/include
INCLUDEPATH += $$PWD/LunaDll/libs/freeimage
LIBS += -L$$PWD/LunaDll/libs/lua_mingw/lib
LIBS += -L$$PWD/LunaDll/libs/sdl_mingw/lib
LIBS += -static -lkernel32 -static -luser32 -static -lgdi32 -static -lcomdlg32 -static -lmsimg32 #-static -lcomsuppw
Expand Down Expand Up @@ -253,7 +255,14 @@ HEADERS += \
LunaDll/SMBXInternal/Tile.h \
LunaDll/Misc/PerfTracker.h \
LunaDll/EventStateMachine.h \
LunaDll/Misc/UniPath.h
LunaDll/Misc/UniPath.h \
LunaDll/Misc/TestMode.h \
LunaDll/Rendering/GL/GLFramebuffer.h \
LunaDll/Rendering/BitBltEmulation.h \
LunaDll/Rendering/FrameCapture.h \
LunaDll/Rendering/SMBXMaskedImage.h \
LunaDll/SMBXInternal/BaseItemArray.h \
LunaDll/SMBXInternal/HardcodedGraphicsAccess.h

SOURCES += \
LunaDll/Autocode/Commands/AC_HeartSystem.cpp \
Expand Down Expand Up @@ -432,5 +441,13 @@ SOURCES += \
LunaDll/Misc/PerfTracker.cpp \
LunaDll/Rendering/GL/GLEngineCmds.cpp \
LunaDll/EventStateMachine.cpp \
LunaDll/Misc/UniPath.cpp
LunaDll/Misc/UniPath.cpp \
LunaDll/LuaMain/LuaProxyFFI.cpp \
LunaDll/Misc/RuntimeHookComponents/RuntimeHookCharacterId.cpp \
LunaDll/Misc/TestMode.cpp \
LunaDll/Rendering/GL/GLFramebuffer.cpp \
LunaDll/Rendering/BitBltEmulation.cpp \
LunaDll/Rendering/FrameCapture.cpp \
LunaDll/Rendering/SMBXMaskedImage.cpp \
LunaDll/SMBXInternal/HardcodedGraphicsAccess.cpp

3 changes: 3 additions & 0 deletions LunaDll/Changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
v0.7.3.1 BETA
* Added non-ASCII paths support! (LunaLUA-SMBX's root finally can be placed into path with non-ASCII characters. But limit is: don't mix codepages (example: both Russian and Chinese characters in a path, or you will get VB Error "File not found". Same happens on Vanilla SMBX if you have been used non-local characters.))

v0.7.3 BETA
* Added new compareLunaVersion for version checking
* Added new event onKeyboardPress which handles raw keyboard input
Expand Down
196 changes: 149 additions & 47 deletions LunaDll/GlobalFuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,58 @@ bool is_number(const std::string& s)

bool file_existsX(const std::string& name)
{
if (FILE *file = fopen(name.c_str(), "r")) {
if (FILE *file = _wfopen(Str2WStr(name).c_str(), L"r")) {
fclose(file);
return true;
} else {
return false;
}
}

void removeFilePathW(std::wstring &path)
{
for(int i = path.size(); i > 3; i--) {
if((path[i] == L'\\')||(path[i] == L'/'))
{
path.resize(i);
break;
}
}
}

void removeFilePathW(wchar_t*path, int length)
{
for(int i = length; i > 3; i--) {
if((path[i] == L'\\')||(path[i] == L'/'))
{
path[i] = 0;
break;
}
}
}

void removeFilePathA(std::string &path)
{
for(int i = path.size(); i > 3; i--) {
if((path[i] == '\\')||(path[i] == '/'))
{
path.resize(i);
break;
}
}
}

void removeFilePathA(char*path, int length)
{
for(int i = length; i > 3; i--) {
if((path[i] == '\\')||(path[i] == '/'))
{
path[i] = 0;
break;
}
}
}

void ResetLunaModule()
{
gLunaEnabled = true;
Expand Down Expand Up @@ -317,6 +361,38 @@ static bool IsWindowsVistaOrNewer() {
conditionMask);
}

/*!
* \brief Initializes game root folder variables
*/
void initAppPaths()
{
HMODULE hModule = GetModuleHandleW(NULL);
wchar_t fullPath[MAX_PATH];
int count = GetModuleFileNameW(hModule, fullPath, MAX_PATH);

//Check is path has a mixed charsets
std::string apath=WStr2StrA(fullPath);
FILE *mainexe=fopen(apath.c_str(), "r");
removeFilePathW(fullPath, count);

if(!mainexe)
{
std::wstringstream msg;
msg << L"LunaLUA is located in a path which contains mixed charsets (for example, your locale is configured to Europan, "
<< L"but in the path are Cyrillic or Chinese characters which are not fits into your local charset). "
<< L"SMBX will crash if you will continue running of it.\n\nPlease move SMBX folder into path which has "
<< L" only characters of your current locale or ASCII-only to avoid this warning message.\n\nDetected full path:\n"
<< fullPath;
MessageBoxW(NULL, msg.str().c_str(), L"Mixed charsets in path has been detected", MB_OK|MB_ICONWARNING);
} else {
fclose(mainexe);
}

gAppPathWCHAR = fullPath;
gAppPathUTF8 = WStr2Str(fullPath);
gAppPathANSI = WStr2StrA(fullPath);
}

/// INIT GLOBALS
void InitGlobals()
{
Expand Down Expand Up @@ -352,12 +428,14 @@ void InitGlobals()
/// Init autocode manager

gAutoMan.Clear(true);
gAutoMan.ReadGlobals(getModulePath());
gAutoMan.ReadGlobals(gAppPathWCHAR);
gAutoMan.m_GlobalEnabled = true;

std::wstring configFolderPath = gAppPathWCHAR+L"\\config";

// Be sure that the config folder exist
if (GetFileAttributesW(L"config") & INVALID_FILE_ATTRIBUTES) {
CreateDirectoryW(L"config", NULL);
if (GetFileAttributesW(configFolderPath.c_str()) & INVALID_FILE_ATTRIBUTES) {
CreateDirectoryW(configFolderPath.c_str(), NULL);
}

}
Expand Down Expand Up @@ -437,36 +515,36 @@ bool vecStrFind(const std::vector<std::wstring>& vecStr, const std::wstring& fin
return false;
}

HMODULE getModule(std::string moduleName)
{
HMODULE ret = 0;
if( !(ret = GetModuleHandleA(moduleName.c_str())) ){
ret = LoadLibraryA(moduleName.c_str());
}
return ret;
}

std::wstring getModulePath()
{
HMODULE hModule = GetModuleHandleW(NULL);
WCHAR path[MAX_PATH];
int count = GetModuleFileNameW(hModule, path, MAX_PATH);
for(int i = count; i > 3; i--) {
if(path[i] == L'\\') {
path[i] = 0;
break;
}
}
return std::wstring(path);
}
//HMODULE getModule(std::string moduleName)
//{
// HMODULE ret = 0;
// if( !(ret = GetModuleHandleA(moduleName.c_str())) ){
// ret = LoadLibraryA(moduleName.c_str());
// }
// return ret;
//}

//std::wstring getModulePath()
//{
// HMODULE hModule = GetModuleHandleW(NULL);
// WCHAR path[MAX_PATH];
// int count = GetModuleFileNameW(hModule, path, MAX_PATH);
// for(int i = count; i > 3; i--) {
// if(path[i] == L'\\') {
// path[i] = 0;
// break;
// }
// }
// return std::wstring(path);
//}

bool readFile(std::wstring &content, std::wstring path, std::wstring errMsg /*= std::wstring()*/)
{
std::wifstream theFile(path, std::ios::binary| std::ios::in);
if(!theFile.is_open()){
theFile.close();
if(!errMsg.empty())
MessageBoxW(NULL, errMsg.c_str(), L"Error", NULL);
MessageBoxW(NULL, errMsg.c_str(), L"Error", NULL);
return false;
}

Expand All @@ -476,15 +554,30 @@ bool readFile(std::wstring &content, std::wstring path, std::wstring errMsg /*=

bool readFile(std::string &content, std::string path, std::string errMsg /*= std::string()*/)
{
std::ifstream theFile(path, std::ios::binary | std::ios::in);
if (!theFile.is_open()) {
theFile.close();
if (!errMsg.empty())
MessageBoxA(NULL, errMsg.c_str(), "Error", NULL);
std::wstring wpath = Str2WStr(path);
FILE* theFile = _wfopen(wpath.c_str(), L"rb");
if(!theFile)
{
MessageBoxA(NULL, errMsg.c_str(), "Error", NULL);
return false;
}

content = std::string((std::istreambuf_iterator<char>(theFile)), std::istreambuf_iterator<char>());
fseek(theFile, 0, SEEK_END);
size_t len = ftell(theFile);
if(len>0)
{
content.resize(len);
fread((char*)content.c_str(), 1, len, theFile);
fclose(theFile);
}
// bool res=readFile(wcontent, wpath, )
// std::wifstream theFile(wpath, std::ios::binary | std::ios::in);
// if (!theFile.is_open()) {
// theFile.close();
// if (!errMsg.empty())
// MessageBoxA(NULL, errMsg.c_str(), "Error", NULL);
// return false;
// }
//content = std::string((std::istreambuf_iterator<char>(theFile)), std::istreambuf_iterator<char>());
return true;
}

Expand Down Expand Up @@ -518,14 +611,22 @@ std::string generateTimestampForFilename()

bool writeFile(const std::string &content, const std::string &path)
{
std::ofstream theFile(path, std::ios::binary | std::ios::out);
if (!theFile.is_open()){
theFile.close();
std::wstring wpath = Str2WStr(path);
FILE* theFile = _wfopen(wpath.c_str(), L"wb");
if(!theFile)
{
return false;
}
theFile << content;
theFile.close();
fwrite(content.c_str(), 1, content.size(), theFile);
fclose(theFile);
return true;
// std::ofstream theFile(path, std::ios::binary | std::ios::out);
// if (!theFile.is_open()){
// theFile.close();
// return false;
// }
// theFile << content;
// theFile.close();
}


Expand Down Expand Up @@ -572,23 +673,24 @@ std::vector<std::string> listOfDir(const std::string& path, DWORD fileAttributes
{
std::vector<std::string> out;
HANDLE dir;
WIN32_FIND_DATAA file_data;
WIN32_FIND_DATAW file_data;
std::wstring wpath = Str2WStr(path);

if ((dir = FindFirstFileA((path + "/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
if ((dir = FindFirstFileW((wpath + L"/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
return out; /* No files found */

do {
const std::string file_name = file_data.cFileName;
const std::wstring wfile_name = file_data.cFileName;
const bool skipFile = (file_data.dwFileAttributes & fileAttributes) == 0;

if (file_name[0] == '.')
if (wfile_name[0] == L'.')
continue;

if (skipFile)
continue;

std::string file_name = WStr2Str(wfile_name);
out.push_back(file_name);
} while (FindNextFileA(dir, &file_data));
} while (FindNextFileW(dir, &file_data));

FindClose(dir);

Expand Down Expand Up @@ -639,8 +741,8 @@ std::wstring getLatestFile(const std::initializer_list<std::wstring>& paths)
std::wstring getLatestConfigFile(const std::wstring& configname)
{
return getLatestFile({
getModulePath() + L"//" + configname,
getModulePath() + L"//config//" + configname
gAppPathWCHAR + L"//" + configname,
gAppPathWCHAR + L"//config//" + configname
});
}

Expand Down
10 changes: 8 additions & 2 deletions LunaDll/GlobalFuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@ bool file_existsX(const std::string& name);
bool isAbsolutePath(const std::wstring& path);
bool isAbsolutePath(const std::string& path);

extern void removeFilePathW(std::wstring &path);
extern void removeFilePathW(wchar_t*path, int length);
void removeFilePathA(std::string &path);
void removeFilePathA(char*path, int length);

/// Functions ///
void initAppPaths();
void ResetLunaModule();
void InitGlobals();
void ResetFreeGlob();
Expand All @@ -67,15 +73,15 @@ std::vector<std::string> split( std::string str, char delimiter);
bool vecStrFind(const std::vector<std::wstring>& vecStr, const std::wstring& find);
std::string url_encode(const std::string &value);
// Module Helper Funcs
HMODULE getModule(std::string moduleName);
//HMODULE getModule(std::string moduleName);

// File/Path Helper Funcs
bool readFile(std::wstring &content, std::wstring path, std::wstring errMsg = std::wstring());
bool readFile(std::string &content, std::string path, std::string errMsg = std::string());
bool writeFile(const std::string &content, const std::string &path);
std::vector<std::string> listFilesOfDir(const std::string& path);
std::vector<std::string> listOfDir(const std::string& path, DWORD fileAttributes);
std::wstring getModulePath();
//std::wstring getModulePath();
std::wstring getCustomFolderPath();
std::wstring getLatestFile(const std::initializer_list<std::wstring>& paths);
std::wstring getLatestConfigFile(const std::wstring& configname);
Expand Down
7 changes: 7 additions & 0 deletions LunaDll/Globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,10 @@ GeneralLunaConfig gGeneralConfig;
CLunaLua gLunaLua;


// Paths
std::string gAppPathANSI;

std::string gAppPathUTF8;

std::wstring gAppPathWCHAR;

5 changes: 5 additions & 0 deletions LunaDll/Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ extern GeneralLunaConfig gGeneralConfig;

extern CLunaLua gLunaLua;

// Paths
extern std::string gAppPathANSI;
extern std::string gAppPathUTF8;
extern std::wstring gAppPathWCHAR;

/// HELPER MACROS ///
/*
if(!hRunProc){
Expand Down
Loading

0 comments on commit 08d531b

Please sign in to comment.