diff --git a/modules/client_entergame/characterlist.lua b/modules/client_entergame/characterlist.lua index df51596f..6ca101ec 100644 --- a/modules/client_entergame/characterlist.lua +++ b/modules/client_entergame/characterlist.lua @@ -111,7 +111,12 @@ end function onGameConnectionError(message, code) CharacterList.destroyLoadBox() - local text = tr('Your connection has been lost. (err: %d)', code) + local text + if g_game.getProtocolGame() and g_game.getProtocolGame():isConnecting() then + text = tr('Unable to establish a connection. (err: %d)%s', code) + else + text = tr('Your connection has been lost. (err: %d)', code) + end errorBox = displayErrorBox(tr("Connection Error"), text) errorBox.onOk = function() errorBox = nil diff --git a/modules/client_entergame/entergame.lua b/modules/client_entergame/entergame.lua index e2cb9027..5a4fd4a2 100644 --- a/modules/client_entergame/entergame.lua +++ b/modules/client_entergame/entergame.lua @@ -211,7 +211,7 @@ function EnterGame.doLogin() g_settings.set('port', G.port) protocolLogin = ProtocolLogin.create() - protocolLogin.onError = onError + protocolLogin.onLoginError = onError protocolLogin.onMotd = onMotd protocolLogin.onCharacterList = onCharacterList protocolLogin.onUpdateNeeded = onUpdateNeeded diff --git a/modules/gamelib/protocollogin.lua b/modules/gamelib/protocollogin.lua index 61f2be78..a65c5ec3 100644 --- a/modules/gamelib/protocollogin.lua +++ b/modules/gamelib/protocollogin.lua @@ -85,6 +85,7 @@ function ProtocolLogin:sendLoginPacket() end function ProtocolLogin:onConnect() + self.gotConnection = true self:sendLoginPacket() end @@ -155,6 +156,11 @@ function ProtocolLogin:parseOpcode(opcode, msg) end function ProtocolLogin:onError(msg, code) - local text = tr('Your connection has been lost. (err: %d)', code) - signalcall(self.onLoginError, self, opcode, text) + local text + if self:isConnecting() then + text = tr('Unable to establish a connection. (err: %d)', code) + else + text = tr('Your connection has been lost. (err: %d)', code) + end + signalcall(self.onLoginError, self, text) end \ No newline at end of file diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 60070058..b5c1f647 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -184,7 +184,7 @@ message(STATUS "Build revision: ${BUILD_REVISION}") add_definitions(-D"BUILD_REVISION=\\\"${BUILD_REVISION}\\\"") # find boost -set(REQUIRED_BOOST_COMPONENTS locale system filesystem regex thread chrono) +set(REQUIRED_BOOST_COMPONENTS system filesystem thread chrono) if(WIN32) set(Boost_THREADAPI win32) set(framework_DEFINITIONS ${framework_DEFINITIONS} -DBOOST_THREAD_USE_LIB) # fix boost thread linkage @@ -262,8 +262,7 @@ else() set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -rdynamic -Wl,-rpath,./libs") # rdynamic is needed by backtrace.h used in crash handler set(SYSTEM_LIBRARIES dl) endif() - find_package(ICU) - set(framework_LIBRARIES ${framework_LIBRARIES} ${ICU_LIBRARIES} ${SYSTEM_LIBRARIES}) + set(framework_LIBRARIES ${framework_LIBRARIES} ${SYSTEM_LIBRARIES}) endif() if(FRAMEWORK_GRAPHICS) diff --git a/src/framework/core/application.cpp b/src/framework/core/application.cpp index 46aef63a..29a0df7a 100644 --- a/src/framework/core/application.cpp +++ b/src/framework/core/application.cpp @@ -74,10 +74,9 @@ void Application::init(std::vector& args) #endif // setup locale - boost::locale::generator locgen; - std::locale::global(locgen.generate("")); - std::locale utf8Loc = locgen.generate("en_US.UTF-8"); - boost::filesystem::path::imbue(utf8Loc); + std::locale::global(std::locale()); + std::locale utf8("en_US.UTF-8"); + boost::filesystem::path::imbue(utf8); // process args encoding g_platform.processArgs(args); diff --git a/src/framework/platform/win32platform.cpp b/src/framework/platform/win32platform.cpp index ef1d4367..37da156c 100644 --- a/src/framework/platform/win32platform.cpp +++ b/src/framework/platform/win32platform.cpp @@ -28,7 +28,6 @@ #include #include - void Platform::processArgs(std::vector& args) { int nargs; diff --git a/src/framework/stdext/string.cpp b/src/framework/stdext/string.cpp index d863ae95..aca42c1e 100644 --- a/src/framework/stdext/string.cpp +++ b/src/framework/stdext/string.cpp @@ -25,7 +25,6 @@ #include #include #include -#include namespace stdext { @@ -71,44 +70,144 @@ uint64_t hex_to_dec(const std::string& str) bool is_valid_utf8(const std::string& src) { - try { - boost::locale::conv::from_utf(src, "ISO-8859-1", boost::locale::conv::stop); - return true; - } catch(...) { + const unsigned char *bytes = (const unsigned char *)src.c_str(); + while(*bytes) { + if( (// ASCII + // use bytes[0] <= 0x7F to allow ASCII control characters + bytes[0] == 0x09 || + bytes[0] == 0x0A || + bytes[0] == 0x0D || + (0x20 <= bytes[0] && bytes[0] <= 0x7E) + ) + ) { + bytes += 1; + continue; + } + if( (// non-overlong 2-byte + (0xC2 <= bytes[0] && bytes[0] <= 0xDF) && + (0x80 <= bytes[1] && bytes[1] <= 0xBF) + ) + ) { + bytes += 2; + continue; + } + if( (// excluding overlongs + bytes[0] == 0xE0 && + (0xA0 <= bytes[1] && bytes[1] <= 0xBF) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) + ) || + (// straight 3-byte + ((0xE1 <= bytes[0] && bytes[0] <= 0xEC) || + bytes[0] == 0xEE || + bytes[0] == 0xEF) && + (0x80 <= bytes[1] && bytes[1] <= 0xBF) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) + ) || + (// excluding surrogates + bytes[0] == 0xED && + (0x80 <= bytes[1] && bytes[1] <= 0x9F) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) + ) + ) { + bytes += 3; + continue; + } + if( (// planes 1-3 + bytes[0] == 0xF0 && + (0x90 <= bytes[1] && bytes[1] <= 0xBF) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) && + (0x80 <= bytes[3] && bytes[3] <= 0xBF) + ) || + (// planes 4-15 + (0xF1 <= bytes[0] && bytes[0] <= 0xF3) && + (0x80 <= bytes[1] && bytes[1] <= 0xBF) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) && + (0x80 <= bytes[3] && bytes[3] <= 0xBF) + ) || + (// plane 16 + bytes[0] == 0xF4 && + (0x80 <= bytes[1] && bytes[1] <= 0x8F) && + (0x80 <= bytes[2] && bytes[2] <= 0xBF) && + (0x80 <= bytes[3] && bytes[3] <= 0xBF) + ) + ) { + bytes += 4; + continue; + } return false; } + return true; } std::string utf8_to_latin1(const std::string& src) { - return boost::locale::conv::from_utf(src, "ISO-8859-1"); -} - -std::wstring utf8_to_utf16(const std::string& src) -{ - return boost::locale::conv::utf_to_utf(src); -} - -std::string utf16_to_utf8(const std::wstring& src) -{ - return boost::locale::conv::utf_to_utf(src); -} - -std::string utf16_to_latin1(const std::wstring& src) -{ - return boost::locale::conv::from_utf(src, "ISO-8859-1"); + std::string out; + for(uint i=0;i= 32 && c < 128) + out += c; + else if(c == 0xc2 || c == 0xc3) { + uchar c2 = src[i++]; + if(c == 0xc2) { + if(c2 > 0xa1 && c2 < 0xbb) + out += c2; + } else if(c == 0xc3) + out += 64 + c2; + } else if(c >= 0xc4 && c <= 0xdf) + i += 1; + else if(c >= 0xe0 && c <= 0xed) + i += 2; + else if(c >= 0xf0 && c <= 0xf4) + i += 3; + } + return out; } std::string latin1_to_utf8(const std::string& src) { - return boost::locale::conv::to_utf(src, "ISO-8859-1"); + std::string out; + for(uchar c : src) { + if(c >= 32 && c < 128) + out += c; + else { + out += 0xc2 + (c > 0xbf); + out += 0x80 + (c & 0x3f); + } + } + return out; +} + +#ifdef WIN32 +#include +std::wstring utf8_to_utf16(const std::string& src) +{ + std::wstring res; + wchar_t out[4096]; + if(MultiByteToWideChar(CP_UTF8, 0, src.c_str(), -1, out, 4096)) + res = out; + return res; +} + +std::string utf16_to_utf8(const std::wstring& src) +{ + std::string res; + char out[4096]; + if(WideCharToMultiByte(CP_UTF8, 0, src.c_str(), -1, out, 4096, NULL, NULL)) + res = out; + return res; } std::wstring latin1_to_utf16(const std::string& src) { - return boost::locale::conv::to_utf(src, "ISO-8859-1"); + return utf8_to_utf16(latin1_to_utf8(src)); } +std::string utf16_to_latin1(const std::wstring& src) +{ + return utf8_to_latin1(utf16_to_utf8(src)); +} +#endif + void tolower(std::string& str) { std::transform(str.begin(), str.end(), str.begin(), lochar); diff --git a/src/framework/stdext/string.h b/src/framework/stdext/string.h index e5afb312..0ad09a17 100644 --- a/src/framework/stdext/string.h +++ b/src/framework/stdext/string.h @@ -54,11 +54,14 @@ void replace_all(std::string& str, const std::string& search, const std::string& bool is_valid_utf8(const std::string& src); std::string utf8_to_latin1(const std::string& src); +std::string latin1_to_utf8(const std::string& src); + +#ifdef WIN32 std::wstring utf8_to_utf16(const std::string& src); std::string utf16_to_utf8(const std::wstring& src); std::string utf16_to_latin1(const std::wstring& src); -std::string latin1_to_utf8(const std::string& src); std::wstring latin1_to_utf16(const std::string& src); +#endif std::vector split(const std::string& str, const std::string& separators = " "); template std::vector split(const std::string& str, const std::string& separators = " ") {