Skip to content

Commit a0de296

Browse files
committed
Экспорт в скрипты функций для работы с кодировками
1 parent cc9b102 commit a0de296

File tree

6 files changed

+96
-61
lines changed

6 files changed

+96
-61
lines changed

Game/Resources_SoC_1.0006/gamedata/scripts/ui_mm_save_load_dialog.script

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ function fill_savedgames_list( wnd )
3030
end
3131

3232
local function delete_save_game(filename)
33+
if game.StringHasUTF8(filename) then
34+
filename = game.StringFromUTF8(filename)
35+
end
3336
local save_file = filename .. ".sav"
3437
local dds_file = filename .. ".dds"
3538
local f = getFS()
@@ -57,7 +60,6 @@ local function file_data(fname)
5760
end
5861
end
5962

60-
6163
class "save_load_item" (CUIListItemEx)
6264
function save_load_item:__init() super()
6365
self:SetWndRect(0,0,430,22)
@@ -238,6 +240,11 @@ function save_load_dialog:OnListItemClickedLoad()
238240

239241
local item_text = item.fn:GetText()
240242
self.file_caption:SetText(item_text)
243+
244+
if game.StringHasUTF8(item_text) then
245+
item_text = game.StringFromUTF8(item_text)
246+
end
247+
241248
self.file_data:SetText(file_data(item_text))
242249

243250
if not getFS():exist("$game_saves$", item_text..".sav") then
@@ -300,6 +307,10 @@ function save_load_dialog:load_game_internal()
300307
local item = list:GetItem(index)
301308
local fname = item.fn:GetText()
302309

310+
if game.StringHasUTF8(fname) then
311+
fname = game.StringFromUTF8(fname)
312+
end
313+
303314
if not alife() then
304315
cmd("disconnect")
305316
cmd("start server(" .. fname .. "/single/alife/load)")
@@ -323,12 +334,23 @@ function save_load_dialog:OnButton_ok_clicked()
323334
end
324335
end
325336

337+
local function safe_file_name( fname ) --Вырезаем неподдерживаемые FS символы и пробелы по краям.
338+
if game.StringHasUTF8(fname) then
339+
fname = game.StringFromUTF8(fname)
340+
end
341+
fname = fname:clear():gsub( '[%(%)]*', "" ):trim()
342+
if fname:len() > 60 then
343+
fname = fname:sub( 1, 58 ) .. "..."
344+
end
345+
return fname
346+
end
347+
326348
function save_load_dialog:OnButton_save_clicked()
327349
local message_box = self.message_box
328350
local main_frame = self:GetFrameWindow("main_frame")
329351

330352
local edit_box = self:GetEditBox("edit_filename")
331-
self.new_save = edit_box:GetText():clear():gsub( '[%(%)]*', "" ):trim() --Вырезаем неподдерживаемые FS символы и пробелы по краям
353+
self.new_save = safe_file_name(edit_box:GetText())
332354
if self.new_save:len() == 0 then
333355
self.msgbox_id = 0
334356
self.message_box:Init("message_box_empty_file_name")
@@ -360,6 +382,9 @@ function save_load_dialog:OnButton_load_clicked()
360382

361383
local item = list:GetItem(index)
362384
local fname = item.fn:GetText()
385+
if game.StringHasUTF8(fname) then
386+
fname = game.StringFromUTF8(fname)
387+
end
363388

364389
if valid_saved_game(fname) then
365390
if level.present() and db.actor_proxy.online and db.actor:alive() then
@@ -412,7 +437,7 @@ end
412437

413438
function save_load_dialog:AddItemToList(file_name, date_time)
414439
local itm = save_load_item()
415-
itm.fn:SetText(file_name)
440+
itm.fn:SetText(itm.fn:IsMultibyteFont() and game.StringToUTF8(file_name) or file_name)
416441
itm.fage:SetText(date_time)
417442

418443
local list_box = self:GetListWnd("list_window")

ogsr_engine/xrCore/_std_extensions.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,13 @@ std::string StringToUTF8(const char* in)
4949
std::use_facet<std::ctype<wchar_t>>(locale).widen(in, in + len, wstr.data());
5050
return wcvt{}.to_bytes(wstr.data(), wstr.data() + wstr.size());
5151
}
52+
53+
std::string StringFromUTF8(const char* in)
54+
{
55+
using wcvt = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
56+
const std::wstring wstr = wcvt{}.from_bytes(in);
57+
static const std::locale locale{""};
58+
std::string result(wstr.size(), '\0');
59+
std::use_facet<std::ctype<wchar_t>>(locale).narrow(wstr.data(), wstr.data() + wstr.size(), '?', result.data());
60+
return result;
61+
}

ogsr_engine/xrCore/_std_extensions.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,53 @@ inline char* xr_strconcat(StrType& dest, const StrType2& arg1, const Args&... ar
169169
#define xr_strcat strcat_s
170170

171171
XRCORE_API std::string StringToUTF8(const char* in);
172+
XRCORE_API std::string StringFromUTF8(const char* in);
173+
// Определяет есть ли в строке юникодные символы
174+
inline bool StringHasUTF8(const char* str)
175+
{
176+
const unsigned char* p = reinterpret_cast<const unsigned char*>(str);
177+
while (*p != 0)
178+
{
179+
if (*p < 0x80)
180+
{
181+
// однобайтовый символ в UTF-8, пропускаем
182+
p++;
183+
}
184+
else if (*p < 0xc2 || *p > 0xf4)
185+
{
186+
// байт не может быть первым байтом в UTF-8, строка содержит ошибку
187+
return false;
188+
}
189+
else if (*p < 0xe0)
190+
{
191+
// двухбайтовый символ в UTF-8
192+
if (*(p + 1) < 0x80 || *(p + 1) > 0xbf)
193+
{
194+
// неправильный второй байт, строка содержит ошибку
195+
return false;
196+
}
197+
p += 2;
198+
}
199+
else if (*p < 0xf0)
200+
{
201+
// трехбайтовый символ в UTF-8
202+
if (*(p + 1) < 0x80 || *(p + 1) > 0xbf || *(p + 2) < 0x80 || *(p + 2) > 0xbf)
203+
{
204+
// неправильные второй и/или третий байты, строка содержит ошибку
205+
return false;
206+
}
207+
p += 3;
208+
}
209+
else
210+
{
211+
// четырехбайтовый символ в UTF-8
212+
if (*(p + 1) < 0x80 || *(p + 1) > 0xbf || *(p + 2) < 0x80 || *(p + 2) > 0xbf || *(p + 3) < 0x80 || *(p + 3) > 0xbf)
213+
{
214+
// неправильные второй, третий и/или четвертый байты, строка содержит ошибку
215+
return false;
216+
}
217+
p += 4;
218+
}
219+
}
220+
return true;
221+
}

ogsr_engine/xrGame/game_sv_base_script.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ void game_sv_GameState::script_register(lua_State* L)
140140
def("set_hud_anm_time", SetBlendAnmTime),
141141
//def("set_next_hud_motion_speed", SetNextHudMotionSpeed),
142142

143-
def("generate_id", &generate_id)
143+
def("generate_id", &generate_id),
144+
145+
def("StringHasUTF8", &StringHasUTF8), def("StringToUTF8", &StringToUTF8), def("StringFromUTF8", &StringFromUTF8)
144146
];
145147

146148
module(L)[

ogsr_engine/xrGame/ui/UIStatic_script.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include "stdafx.h"
22
#include "UIStatic.h"
3-
4-
void CUIStatic__set_color_a(CUIStatic* self, u8 alpha) { self->SetColor(subst_alpha(self->GetColor(), alpha)); }
3+
#include "UILines.h"
54

65
using namespace luabind;
76

@@ -14,6 +13,7 @@ void CUIStatic::script_register(lua_State* L)
1413
.def("SetText", (void(CUIStatic::*)(LPCSTR))(&CUIStatic::SetText))
1514
.def("SetTextST", (void(CUIStatic::*)(LPCSTR))(&CUIStatic::SetTextST))
1615
.def("GetText", &CUIStatic::GetText)
16+
.def("IsMultibyteFont", [](CUIStatic* self) -> bool { return self->m_pLines->GetFont()->IsMultibyte(); })
1717

1818
.def("SetTextX", &CUIStatic::SetTextX)
1919
.def("SetTextY", &CUIStatic::SetTextY)
@@ -22,7 +22,7 @@ void CUIStatic::script_register(lua_State* L)
2222

2323
.def("SetColor", &CUIStatic::SetColor)
2424
.def("GetColor", &CUIStatic::GetColor)
25-
.def("SetColorA", &CUIStatic__set_color_a)
25+
.def("SetColorA", [](CUIStatic* self, u8 alpha) { self->SetColor(subst_alpha(self->GetColor(), alpha)); })
2626
.def("SetTextColor", &CUIStatic::SetTextColor_script)
2727
.def("Init", (void(CUIStatic::*)(float, float, float, float)) & CUIStatic::Init)
2828
.def("Init", (void(CUIStatic::*)(LPCSTR, float, float, float, float)) & CUIStatic::Init)

ogsr_engine/xr_3da/DiscordRPC.cpp

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,58 +3,6 @@
33
#include "DiscordRPC.hpp"
44
#include "../xr_3da/x_ray.h"
55

6-
7-
// Определяет есть ли в строке юникодные символы
8-
static inline bool has_utf8(const char* str)
9-
{
10-
const unsigned char* p = reinterpret_cast<const unsigned char*>(str);
11-
while (*p != 0)
12-
{
13-
if (*p < 0x80)
14-
{
15-
// однобайтовый символ в UTF-8, пропускаем
16-
p++;
17-
}
18-
else if (*p < 0xc2 || *p > 0xf4)
19-
{
20-
// байт не может быть первым байтом в UTF-8, строка содержит ошибку
21-
return false;
22-
}
23-
else if (*p < 0xe0)
24-
{
25-
// двухбайтовый символ в UTF-8
26-
if (*(p + 1) < 0x80 || *(p + 1) > 0xbf)
27-
{
28-
// неправильный второй байт, строка содержит ошибку
29-
return false;
30-
}
31-
p += 2;
32-
}
33-
else if (*p < 0xf0)
34-
{
35-
// трехбайтовый символ в UTF-8
36-
if (*(p + 1) < 0x80 || *(p + 1) > 0xbf || *(p + 2) < 0x80 || *(p + 2) > 0xbf)
37-
{
38-
// неправильные второй и/или третий байты, строка содержит ошибку
39-
return false;
40-
}
41-
p += 3;
42-
}
43-
else
44-
{
45-
// четырехбайтовый символ в UTF-8
46-
if (*(p + 1) < 0x80 || *(p + 1) > 0xbf || *(p + 2) < 0x80 || *(p + 2) > 0xbf || *(p + 3) < 0x80 || *(p + 3) > 0xbf)
47-
{
48-
// неправильные второй, третий и/или четвертый байты, строка содержит ошибку
49-
return false;
50-
}
51-
p += 4;
52-
}
53-
}
54-
return true;
55-
}
56-
57-
586
constexpr const char* DISCORD_LIBRARY_DLL{"discord-rpc.dll"};
597

608
ENGINE_API DiscordRPC Discord;
@@ -122,7 +70,7 @@ void DiscordRPC::Update(const char* level_name_translated, const char* level_nam
12270

12371
if (active_task_text)
12472
{
125-
task_txt = has_utf8(active_task_text) ? active_task_text : StringToUTF8(active_task_text);
73+
task_txt = StringHasUTF8(active_task_text) ? active_task_text : StringToUTF8(active_task_text);
12674
presenseInfo.state = task_txt.c_str(); //Активное задание
12775
}
12876

@@ -131,7 +79,7 @@ void DiscordRPC::Update(const char* level_name_translated, const char* level_nam
13179

13280
if (current_level_name)
13381
{
134-
lname = has_utf8(current_level_name) ? current_level_name : StringToUTF8(current_level_name);
82+
lname = StringHasUTF8(current_level_name) ? current_level_name : StringToUTF8(current_level_name);
13583
presenseInfo.details = lname.c_str(); //название уровня
13684
}
13785

0 commit comments

Comments
 (0)