This commit is contained in:
恍兮惚兮 2024-11-04 10:11:02 +08:00
parent 0d56af06d8
commit 6e36963790
6 changed files with 169 additions and 165 deletions

View File

@ -1,14 +1,12 @@
## Detailed Explanation of HOOK Settings ## HOOK Settings
### Parameter Meanings of HOOK Settings 1. #### Code Page
**1. Code Page**
?> This setting is meaningful only when the text extracted from the game is a **multi-byte string with an unspecified encoding within the HOOK engine**. When the HOOK engine has already specified a code page, or the text is a **wide character string** or **UTF32** string, this setting has no meaning. ?> This setting is meaningful only when the text extracted from the game is a **multi-byte string with an unspecified encoding within the HOOK engine**. When the HOOK engine has already specified a code page, or the text is a **wide character string** or **UTF32** string, this setting has no meaning.
This setting generally does not need to be modified. It is only necessary when some old engines (e.g., Yuris) may have GBK/BIG5/UTF8 in their official Chinese versions. If you cannot find the correct text, please send an [issue](https://lunatranslator.org/Resource/game_support) directly to me; modifying this setting is usually futile. This setting generally does not need to be modified. It is only necessary when some old engines (e.g., Yuris) may have GBK/BIG5/UTF8 in their official Chinese versions. If you cannot find the correct text, please send an [issue](https://lunatranslator.org/Resource/game_support) directly to me; modifying this setting is usually futile.
**2. Refresh Delay** 1. #### Refresh Delay
?> Relatively speaking, this is the most practical option. ?> Relatively speaking, this is the most practical option.
@ -24,21 +22,21 @@ For **1 and 2**, because the game text is displayed too slowly, and the refresh
For **3**, you can **appropriately reduce the refresh delay** while paying attention not to cause situations **1 and 2**. For **3**, you can **appropriately reduce the refresh delay** while paying attention not to cause situations **1 and 2**.
**3. Maximum Buffer Length** 1. #### Maximum Buffer Length
Sometimes, text will refresh repeatedly without stopping. If the refresh delay is high and cannot be reduced, it will continue to receive text until the buffer is filled or the text stops refreshing to meet the refresh delay (usually when the game loses focus, so it generally waits until the buffer is filled). Sometimes, text will refresh repeatedly without stopping. If the refresh delay is high and cannot be reduced, it will continue to receive text until the buffer is filled or the text stops refreshing to meet the refresh delay (usually when the game loses focus, so it generally waits until the buffer is filled).
To solve this problem, you can appropriately reduce the buffer length, but be careful not to make the buffer length too short to be less than the actual text length. To solve this problem, you can appropriately reduce the buffer length, but be careful not to make the buffer length too short to be less than the actual text length.
**4. Maximum Cached Text Length** 1. #### Maximum Cached Text Length
Received historical text is cached. When viewing the content of a text item in the text selection window, the historical cached text is queried. If there are too many text items or the text refreshes repeatedly, it will cause too much cached text, making it more sluggish to view text (sometimes even when not viewing). In fact, most of the cached text here is useless; useful historical text can be viewed in historical translations. You can arbitrarily lower this value (default is 1000000, but it can be lowered to 1000). Received historical text is cached. When viewing the content of a text item in the text selection window, the historical cached text is queried. If there are too many text items or the text refreshes repeatedly, it will cause too much cached text, making it more sluggish to view text (sometimes even when not viewing). In fact, most of the cached text here is useless; useful historical text can be viewed in historical translations. You can arbitrarily lower this value (default is 1000000, but it can be lowered to 1000).
**5. Filter Lines Containing Garbled Text** 1. #### Filter Lines Containing Garbled Text
The garbled text filtering in text processing only filters out garbled characters, while this filter, upon receiving text, will discard the entire line of text if any garbled characters are detected. When the game refreshes a large number of sentences containing garbled text, you can appropriately use this option to filter out invalid sentences and improve performance. The garbled text filtering in text processing only filters out garbled characters, while this filter, upon receiving text, will discard the entire line of text if any garbled characters are detected. When the game refreshes a large number of sentences containing garbled text, you can appropriately use this option to filter out invalid sentences and improve performance.
**6. Use YAPI Injection** 1. #### Use YAPI Injection
This option can sometimes slightly improve comfort, but it may have compatibility issues, so it is not recommended. This option can sometimes slightly improve comfort, but it may have compatibility issues, so it is not recommended.
@ -63,11 +61,11 @@ The settings made in the settings interface -> HOOK settings are default setting
To set specific HOOK settings for a game, you need to open the **Game Management** interface, open the **Game Settings** interface, switch to the HOOK sub-tab in the game settings tab, and uncheck **Follow Default** to set specific HOOK settings for the game. To set specific HOOK settings for a game, you need to open the **Game Management** interface, open the **Game Settings** interface, switch to the HOOK sub-tab in the game settings tab, and uncheck **Follow Default** to set specific HOOK settings for the game.
**1. Special Code** 1. #### Special Code
When **Insert Special Code** and **Select Special Code Text**, this special code will be recorded, and it will be automatically inserted the next time it starts. This setting records all previously recorded special codes and allows adding or deleting special codes. When **Insert Special Code** and **Select Special Code Text**, this special code will be recorded, and it will be automatically inserted the next time it starts. This setting records all previously recorded special codes and allows adding or deleting special codes.
**2. Delayed Injection** 1. #### Delayed Injection
Sometimes, the position in the game that needs to be hooked, on the DLL, requires the game to run for a short while before the DLL is loaded. We also need to wait for the DLL to load before injecting. Sometimes, the position in the game that needs to be hooked, on the DLL, requires the game to run for a short while before the DLL is loaded. We also need to wait for the DLL to load before injecting.

View File

@ -1,14 +1,12 @@
## Подробное объяснение настроек HOOK ## настроек HOOK
### Значение параметров настроек HOOK 1. #### Кодовая страница
**1. Кодовая страница**
?> Эта настройка имеет значение только тогда, когда текст, извлеченный из игры, является **строкой с неопределенной кодировкой внутри движка HOOK** и **многобайтовой строкой**. Когда движок HOOK уже указал кодовую страницу, или текст является **широкой символьной строкой** или **строкой UTF32**, эта настройка не имеет никакого значения. ?> Эта настройка имеет значение только тогда, когда текст, извлеченный из игры, является **строкой с неопределенной кодировкой внутри движка HOOK** и **многобайтовой строкой**. Когда движок HOOK уже указал кодовую страницу, или текст является **широкой символьной строкой** или **строкой UTF32**, эта настройка не имеет никакого значения.
Эта настройка обычно не требует изменения. Она необходима только для некоторых старых движков (например, Yuris), официальные китайские версии которых могут иметь GBK/BIG5/UTF8. Если вы не можете найти правильный текст, отправьте [issue](https://lunatranslator.org/Resource/game_support) напрямую мне; изменение этой настройки обычно бесполезно. Эта настройка обычно не требует изменения. Она необходима только для некоторых старых движков (например, Yuris), официальные китайские версии которых могут иметь GBK/BIG5/UTF8. Если вы не можете найти правильный текст, отправьте [issue](https://lunatranslator.org/Resource/game_support) напрямую мне; изменение этой настройки обычно бесполезно.
**2. Задержка обновления** 1. #### Задержка обновления
?> Относительно, это самый практичный вариант. ?> Относительно, это самый практичный вариант.
@ -24,21 +22,21 @@
Для **3**, вы можете **уменьшить задержку обновления**, одновременно обращая внимание на то, чтобы не возникали ситуации **1 и 2**. Для **3**, вы можете **уменьшить задержку обновления**, одновременно обращая внимание на то, чтобы не возникали ситуации **1 и 2**.
**3. Максимальная длина буфера** 1. #### Максимальная длина буфера
Иногда текст будет повторяться без остановки. В этом случае, если задержка обновления высокая и не может быть уменьшена, это приведет к постоянному получению текста до тех пор, пока текст не заполнит буфер или не перестанет обновляться, чтобы удовлетворить задержку обновления (обычно игра теряет фокус, чтобы остановить обновление, поэтому обычно ждут, пока буфер не заполнится). Иногда текст будет повторяться без остановки. В этом случае, если задержка обновления высокая и не может быть уменьшена, это приведет к постоянному получению текста до тех пор, пока текст не заполнит буфер или не перестанет обновляться, чтобы удовлетворить задержку обновления (обычно игра теряет фокус, чтобы остановить обновление, поэтому обычно ждут, пока буфер не заполнится).
Чтобы решить эту проблему, можно соответствующим образом уменьшить длину буфера, но обратите внимание, чтобы длина буфера не была слишком низкой, чтобы быть меньше фактической длины текста. Чтобы решить эту проблему, можно соответствующим образом уменьшить длину буфера, но обратите внимание, чтобы длина буфера не была слишком низкой, чтобы быть меньше фактической длины текста.
**4. Максимальная длина кэшированного текста** 1. #### Максимальная длина кэшированного текста
Полученный исторический текст будет кэшироваться, и когда вы просматриваете содержимое какого-либо текста в окне выбора текста, будет запрашиваться исторический кэшированный текст. Если есть слишком много элементов текста или текст повторяется, это приведет к слишком большому кэшированному тексту, что сделает просмотр текста более медленным (иногда даже без просмотра). На самом деле большая часть кэшированного текста здесь бесполезна; полезный исторический текст можно просмотреть в исторических переводах, и это значение можно свободно уменьшить (по умолчанию 1000000, но на самом деле достаточно 1000). Полученный исторический текст будет кэшироваться, и когда вы просматриваете содержимое какого-либо текста в окне выбора текста, будет запрашиваться исторический кэшированный текст. Если есть слишком много элементов текста или текст повторяется, это приведет к слишком большому кэшированному тексту, что сделает просмотр текста более медленным (иногда даже без просмотра). На самом деле большая часть кэшированного текста здесь бесполезна; полезный исторический текст можно просмотреть в исторических переводах, и это значение можно свободно уменьшить (по умолчанию 1000000, но на самом деле достаточно 1000).
**5. Фильтрация строк, содержащих глифы** 1. #### Фильтрация строк, содержащих глифы
Фильтрация глифов в обработке текста будет фильтровать только глифы, а эта фильтрация, при получении текста, если обнаруживается, что строка текста содержит какие-либо глифы, будет полностью отброшена. Когда игра обновляет большое количество предложений, содержащих глифы, можно соответствующим образом использовать этот параметр, чтобы отфильтровать недействительные предложения и повысить производительность. Фильтрация глифов в обработке текста будет фильтровать только глифы, а эта фильтрация, при получении текста, если обнаруживается, что строка текста содержит какие-либо глифы, будет полностью отброшена. Когда игра обновляет большое количество предложений, содержащих глифы, можно соответствующим образом использовать этот параметр, чтобы отфильтровать недействительные предложения и повысить производительность.
**6. Использование YAPI для инъекции** 1. #### Использование YAPI для инъекции
Этот параметр иногда может немного повысить комфорт, но может быть проблемы с совместимостью, поэтому не рекомендуется использовать. Этот параметр иногда может немного повысить комфорт, но может быть проблемы с совместимостью, поэтому не рекомендуется использовать.
@ -63,11 +61,11 @@
Чтобы сделать специальные настройки HOOK для игры, необходимо открыть интерфейс **Управление играми**, открыть интерфейс **Настройки игры**, переключиться на вкладку HOOK во вкладке настроек игры, отключить **Следовать по умолчанию**, чтобы сделать специальные настройки HOOK для игры. Чтобы сделать специальные настройки HOOK для игры, необходимо открыть интерфейс **Управление играми**, открыть интерфейс **Настройки игры**, переключиться на вкладку HOOK во вкладке настроек игры, отключить **Следовать по умолчанию**, чтобы сделать специальные настройки HOOK для игры.
**1. Специальный код** 1. #### Специальный код**
Когда **вставлен специальный код** и **выбран текст специального кода**, этот специальный код будет записан, и при следующем запуске он будет автоматически вставлен. Эта настройка записывает все ранее записанные специальные коды и позволяет добавлять или удалять специальные коды. Когда **вставлен специальный код** и **выбран текст специального кода**, этот специальный код будет записан, и при следующем запуске он будет автоматически вставлен. Эта настройка записывает все ранее записанные специальные коды и позволяет добавлять или удалять специальные коды.
**2. Задержка инъекции** 1. #### Задержка инъекции**
Иногда место в игре, которое нужно зацепить, в dll требует, чтобы игра немного поработала, прежде чем загрузится dll. Нам также нужно подождать, пока загрузится dll, прежде чем проводить инъекцию. Иногда место в игре, которое нужно зацепить, в dll требует, чтобы игра немного поработала, прежде чем загрузится dll. Нам также нужно подождать, пока загрузится dll, прежде чем проводить инъекцию.

View File

@ -1,15 +1,12 @@
## 详解HOOK设置 ## HOOK设置
### HOOK设置的参数含义 1. #### 代码页
**1. 代码页**
?> 这一设置当且仅当从游戏中提取的文本是**HOOK引擎内部未指定编码**的**多字节字符串**时才有意义当HOOK引擎内部已经指定了代码页或者文本是**宽字符字符串**或者**UTF32**字符串时,这一设置没有任何意义 ?> 这一设置当且仅当从游戏中提取的文本是**HOOK引擎内部未指定编码**的**多字节字符串**时才有意义当HOOK引擎内部已经指定了代码页或者文本是**宽字符字符串**或者**UTF32**字符串时,这一设置没有任何意义
这一设置一般没有修改的必要,当且仅当部分古老引擎(例如Yuris)的官方中文版可能会有GBK/BIG5/UTF8。如果找不到正确的文本直接向我发[issue](https://lunatranslator.org/Resource/game_support),修改这个设置通常是徒劳的。 这一设置一般没有修改的必要,当且仅当部分古老引擎(例如Yuris)的官方中文版可能会有GBK/BIG5/UTF8。如果找不到正确的文本直接向我发[issue](https://lunatranslator.org/Resource/game_support),修改这个设置通常是徒劳的。
1. #### 刷新延迟
**2. 刷新延迟**
?> 相对来说,这个算是最实用的选项了 ?> 相对来说,这个算是最实用的选项了
@ -25,30 +22,24 @@
对于**3**,你可以**适当的降低刷新延迟**,降低值的同时注意不要出现**1、2**的情况。 对于**3**,你可以**适当的降低刷新延迟**,降低值的同时注意不要出现**1、2**的情况。
1. #### 最大缓冲区长度
**3. 最大缓冲区长度**
有时,文本会反复的不停刷新,这时,如果刷新延迟较高且不能降低,会导致一直接收文本直到文本填满缓冲区、或不再刷新以满足刷新延迟(通常是游戏失去焦点时才停止刷新,因此一般是等到填满缓冲区)。 有时,文本会反复的不停刷新,这时,如果刷新延迟较高且不能降低,会导致一直接收文本直到文本填满缓冲区、或不再刷新以满足刷新延迟(通常是游戏失去焦点时才停止刷新,因此一般是等到填满缓冲区)。
为了解决这个问题,可以适当降低缓冲区长度,且要注意不要使缓冲区长度过低到小于实际文本长度。 为了解决这个问题,可以适当降低缓冲区长度,且要注意不要使缓冲区长度过低到小于实际文本长度。
1. #### 最大缓存文本长度
**4. 最大缓存文本长度**
接收到的历史文本会被缓存下来,当在文本选择窗口中,查看某条文本的内容时,会查询历史缓存文本。如果文本条目过多,或因文本反复刷新,会导致缓存的文本过多,查看文本时会变得较为卡顿(有时甚至不查看时也会卡顿)。实际上这里缓存的大部分都是无用文本有用的历史文本可以在历史翻译里面查看可以将这个数值随意调低默认是1000000但其实调到1000就行 接收到的历史文本会被缓存下来,当在文本选择窗口中,查看某条文本的内容时,会查询历史缓存文本。如果文本条目过多,或因文本反复刷新,会导致缓存的文本过多,查看文本时会变得较为卡顿(有时甚至不查看时也会卡顿)。实际上这里缓存的大部分都是无用文本有用的历史文本可以在历史翻译里面查看可以将这个数值随意调低默认是1000000但其实调到1000就行
1. #### 过滤包含乱码的文本行
**5. 过滤包含乱码的文本行**
文本处理中的过滤乱码只会过滤掉其中的乱码字符,而这个过滤会在接收到文本时,如果检查到文本行中包含任意乱码字符,会将整行文本直接整个舍弃。当游戏刷新大量包含乱码的句子时,可以适当使用这个选项,来筛选掉无效句子,提高性能。 文本处理中的过滤乱码只会过滤掉其中的乱码字符,而这个过滤会在接收到文本时,如果检查到文本行中包含任意乱码字符,会将整行文本直接整个舍弃。当游戏刷新大量包含乱码的句子时,可以适当使用这个选项,来筛选掉无效句子,提高性能。
1. #### 使用YAPI注入
**6. 使用YAPI注入**
这个选项有时可以稍微提高一下舒适度,但可能有兼容性问题,因此不推荐使用。 这个选项有时可以稍微提高一下舒适度,但可能有兼容性问题,因此不推荐使用。
<details> <details>
<summary>具体解释</summary> <summary>具体解释</summary>
向游戏注入Dll时一般注入Dll的进程和被注入Dll的进程需要有相同的位数。 向游戏注入Dll时一般注入Dll的进程和被注入Dll的进程需要有相同的位数。
@ -71,11 +62,11 @@ YAPI中如果游戏进程和Luna进程的位数相同则会正常注入
若要对游戏进行专用HOOK设置需要在**游戏管理**中,打开**游戏设置**界面在其中的游戏设置选择卡中切换到HOOK子选项卡取消**跟随默认**后即可为游戏设置专用的HOOK设置。 若要对游戏进行专用HOOK设置需要在**游戏管理**中,打开**游戏设置**界面在其中的游戏设置选择卡中切换到HOOK子选项卡取消**跟随默认**后即可为游戏设置专用的HOOK设置。
**1. 特殊码** 1. #### 特殊码
当**插入特殊码**并**选中特殊码的文本**时,才会记录这个条特殊码,下一次启动时会自动插入这条特殊码。这个设置中记录了之前记录的所有特殊码,可以在其中添加或删除特殊码。 当**插入特殊码**并**选中特殊码的文本**时,才会记录这个条特殊码,下一次启动时会自动插入这条特殊码。这个设置中记录了之前记录的所有特殊码,可以在其中添加或删除特殊码。
**2. 延迟注入** 1. #### 延迟注入
有时游戏需要被插入钩子的位置在dll上需要游戏稍微运行一小会儿后才会加载dll。我们也需要等dll加载后再进行注入 有时游戏需要被插入钩子的位置在dll上需要游戏稍微运行一小会儿后才会加载dll。我们也需要等dll加载后再进行注入
@ -84,3 +75,59 @@ YAPI中如果游戏进程和Luna进程的位数相同则会正常注入
![img](https://image.lunatranslator.org/zh/gamesettings/2.jpg) ![img](https://image.lunatranslator.org/zh/gamesettings/2.jpg)
## 附录
### 特殊码格式
<a id="hookcode"></a>
1. #### HOOK
{H|B}{A|B|C|W|I|S|Q|U|V}[F][N][codepage#][padding+]data_offset[*deref_offset][:split_offset[*deref_offset]]@addr[:module[:func]]
H是inlineHookB是vehhook
单字符A/B是小端/大端的mbcsC是UTF8W是UTF16I是UTF32。
字符串S是默认ascii字符串Q是UTF16U是UTF32V是UTF8。
F每次读取字符串后添加换行符
N无视上下文
寄存器的data_offset
* 32位 -4 for EAX, -8 for ECX, -C for EDX, -10 for EBX, -14 for ESP, -18 for EBP, -1C for ESI, -20 for EDI
* 64位 -C for RAX, -14 for RBX, -1C for RCX, -24 for RDX, and so on for RSP, RBP, RSI, RDI, R8-R15
1. #### JIT HOOK
{H|B}{A|B|C|W|I|S|Q|M|U|V}[F][N][codepage#][padding+]arg_index[*deref_offset][:split_offset[*deref_offset]]@{info}:JIT:{UNITY|YUZU|PPSSPP|VITA3K|RPCS3}
arg_index是JIT函数的参数index。M为C#字符串仅UNITY可用。
UNITY的info为[程序集]:[命名空间]:[类名]:[函数名]:[参数量]
YUZU/PPSSPP/VITA3K/RPCS3的info为被模拟地址
1. #### 内嵌
E[D][S][N|O]HOOKCODE
E是使用内嵌的标注HOOKCODE是JIT特殊码或HOOK特殊码。
D写入时转换中文字符为日语字符集
S提取时使用HOOKCODE指定的文本提取方式
N写入时创建新的字符串并交换字符串指针
O写入时在原字符串上覆写
1. #### 直接内存读取
R{S|Q|V|U}[codepage#]@addr
R是直接内存读取的标志
S是默认ascii字符串Q是UTF16U是UTF32V是UTF8

View File

@ -82,49 +82,6 @@ class QButtonGroup_switch_widegt(QWidget):
self.wlist.append(widget) self.wlist.append(widget)
hookcodehelp = r"""
1内存读取
R{S|Q|V|U}[codepage#]@addr
R是内存读取码标志
S是默认ascii字符串Q是UTF16U是UTF32V是UTF8
2HOOK
{H|B}{A|B|W|I|S|Q|U|V}[F][N][codepage#][padding+]data_offset[*deref_offset][:split_offset[*deref_offset]]@addr[:module[:func]]
H是inlineHookB是vehhook
单字符A/B是小端/大端的mbcsW是UTF16I是UTF32
字符串S是默认ascii字符串Q是UTF16U是UTF32V是UTF8
F每次读取字符串后添加换行符
N无视上下文
-4 for EAX, -8 for ECX, -C for EDX, -10 for EBX, -14 for ESP, -18 for EBP, -1C for ESI, -20 for EDI
-C for RAX, -14 for RBX, -1C for RCX, -24 for RDX, and so on for RSP, RBP, RSI, RDI, R8-R15
3JIT
{H|B}{A|B|W|I|S|Q|M|U|V}[F][N][codepage#][padding+]arg_index[*deref_offset][:split_offset[*deref_offset]]@{info}:JIT:{UNITY|YUZU|PPSSPP|VITA3K|RPCS3}
arg_index是JIT函数的参数indexM为C#字符串仅UNITY可用。
UNITY的info为[程序集]:[命名空间]:类名:函数名:参数量
YUZU/PPSSPP/VITA3K/RPCS3的info为模拟地址
4内嵌
E[D][S][N|O]HOOKCODE
E是使用内嵌的标注HOOKCODE是JIT特殊码或HOOK特殊码
D写入时转换中文字符为日语字符集
S提取时使用HOOKCODE指定的文本提取方式
N写入时创建新的字符串并交换字符串指针
O写入时在原字符串上覆写
"""
@Singleton_close
class dialog_showinfo(QDialog):
def __init__(self, parent) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
self.setWindowTitle("HOOKCODE")
l = QLabel(hookcodehelp)
l.setWordWrap(True)
layout = QHBoxLayout()
layout.addWidget(l)
self.setLayout(layout)
self.show()
class HexValidator(QValidator): class HexValidator(QValidator):
def validate(self, input_str, pos): def validate(self, input_str, pos):
# 检查输入是否是有效的16进制数 # 检查输入是否是有效的16进制数
@ -662,7 +619,11 @@ class hookselect(closeashidewindow):
self.searchtextlayout.addWidget(self.userhookinsert) self.searchtextlayout.addWidget(self.userhookinsert)
self.userhookinsert = QPushButton(icon=qtawesome.icon("fa.question")) self.userhookinsert = QPushButton(icon=qtawesome.icon("fa.question"))
self.userhookinsert.clicked.connect(lambda: dialog_showinfo(self)) self.userhookinsert.clicked.connect(
lambda: gobject.baseobject.openlink(
dynamiclink("{docs_server}/#/zh/hooksettings?id=hookcode")
)
)
self.searchtextlayout.addWidget(self.userhookinsert) self.searchtextlayout.addWidget(self.userhookinsert)
self.userhookfind = LPushButton("搜索特殊码") self.userhookfind = LPushButton("搜索特殊码")

View File

@ -274,7 +274,7 @@ def titlechangedtask(gameuid, title):
class gamepath2uid_index_helper(dict): class gamepath2uid_index_helper(dict):
def __init__(self, d, uid): def __init__(self, d, uid):
super.__init__(d) super().__init__(d)
self.uid = uid self.uid = uid
def __setitem__(self, key, value): def __setitem__(self, key, value):
@ -290,7 +290,7 @@ class gamepath2uid_index_helper(dict):
if absv not in gamepath2uid_index: if absv not in gamepath2uid_index:
gamepath2uid_index[absv] = [] gamepath2uid_index[absv] = []
gamepath2uid_index[absv].append(self.uid) gamepath2uid_index[absv].append(self.uid)
super.__setitem__(key, value) super().__setitem__(key, value)
def initanewitem(title): def initanewitem(title):

View File

@ -29,7 +29,7 @@ include(generate_product_version)
set(VERSION_MAJOR 5) set(VERSION_MAJOR 5)
set(VERSION_MINOR 55) set(VERSION_MINOR 55)
set(VERSION_PATCH 1) set(VERSION_PATCH 2)
add_library(pch pch.cpp) add_library(pch pch.cpp)
target_precompile_headers(pch PUBLIC pch.h) target_precompile_headers(pch PUBLIC pch.h)