Skip to content

add: возможность копировать интегралки текстом#8483

Open
kkadmor wants to merge 22 commits intoss220-space:master220from
kkadmor:import-and-export-integrated-circuitprinter
Open

add: возможность копировать интегралки текстом#8483
kkadmor wants to merge 22 commits intoss220-space:master220from
kkadmor:import-and-export-integrated-circuitprinter

Conversation

@kkadmor
Copy link
Contributor

@kkadmor kkadmor commented Jan 30, 2026

Что этот ПР делает

  • Копировать плату
    В принтере плат рядом с каждой сохраненной платой появилась кнопка "Export". При нажатии появляется окно для ввода, со вставленным текстом платы. Текст платы - закодированные в таком виде данные: "[json_data].[hmac_base64]". Для уверенности в том, что плату не подделали (не поменяли определенные параметры) используется электронная подпись HMAC SHA-256

  • Импортировать плату с помощью полученного текста
    В принтере плат сверху появилась кнопка "Import". При нажатии появляется окно ввода, куда пользователь пишет заранее полученный код. После чего код расшифровывается и проверяется (проверка на правильность данных, сравнение переданного и полученного HMAC)

  • В конфиг (config/config.txt) добавленна переменная HMAC_KEY которая хранит HMAC ключ в виде HEX в строке. По умолчанию "ffffffffffffffffffffffffffffffffffffffff", при деплое необходимо поменять на любой HEX из 40 символов и не менять (изменение ключа приведет к тому, что ранее скопированные платы перестанут импортироваться)

Почему это хорошо для игры

Неудобно каждый раз заново делать платы, которые уже придуманы. Позволяет игрокам делать более сложные и интересные платы

Демонстрация изменений

Демонстрации изменений

image image image

Тестирование

На локалке. Пробовал менять случайные символы полученного кода.

@kkadmor kkadmor requested a review from Bizzonium as a code owner January 30, 2026 06:38
@github-actions github-actions bot added 💻 TGUI PR содержит изменения в файлах TGUI. ⚙️ Изменение конфига PR изменяет конфигурационные файлы сервера или клиента. Merge Conflict PR содержит изменения, конфликтующие с master-веткой. labels Jan 30, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Аналитический отчёт от Большого Брата. Обработка запроса завершена.

Приветствую! Я проанализировал предложенные Вами изменения. С технической точки зрения, работа выглядит требующей доработок.

Сводка анализа:

  • 🔴 Критических замечаний: 2
  • 🟡 Рекомендаций: 7
  • 💡 Предложений: 0

[При наличии] 🔴 Критические замечания (требуют обязательного исправления):

  • code/modules/wiremod/core/hmac.dm:20: Некорректное дополнение ключа в реализации HMAC, что приводит к неверной подписи.
  • code/modules/research/circuitprinter.dm:465: Ошибка в логике проверки импортируемой строки, которая будет отклонять все корректные платы.

[При наличии] 🟡 Рекомендации по улучшению:

  • code/__HELPERS/text.dm:65: Комментарий в коде должен быть на английском языке согласно стайлгайду.
  • code/modules/research/circuitprinter.dm:312: Комментарий в коде должен быть на английском языке согласно стайлгайду.
  • code/modules/research/circuitprinter.dm:324-343: Повторяющийся код проверки JSON-полей можно улучшить для повышения читаемости и упрощения поддержки.
  • code/modules/research/circuitprinter.dm:347: Комментарий в коде должен быть на английском языке согласно стайлгайду.
  • code/modules/research/circuitprinter.dm:348-352: Избыточный вызов json_decode в save_circuit_by_json, что снижает производительность.
  • code/modules/research/circuitprinter.dm:442: Комментарий в коде должен быть на английском языке согласно стайлгайду.
  • code/modules/wiremod/core/hmac.dm:90-92: Неочевидная логика валидации длины ключа HMAC.

Пожалуйста, ознакомьтесь с комментариями к отдельным строкам кода для получения более подробной информации.

Спасибо за ваш вклад в проект!


var/hmac_key = CONFIG_GET(string/hmac_key) ? CONFIG_GET(string/hmac_key) : ""

if(!text || findtext(text, "."))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

🔴 Критическая ошибка: Условие if(!text || findtext(text, ".")) некорректно. Оно приводит к тому, что любая корректная строка для импорта (которая должна содержать точку в качестве разделителя) будет отклонена. findtext возвращает позицию, и если точка найдена, условие становится истинным, что вызывает ошибку. Условие следует инвертировать, чтобы проверять отсутствие точки.

			if(!text || !findtext(text, "."))

key_bin = hex_to_bin(md5(key_bin))

if(length(key_bin) < HMAC_BLOCK_SIZE)
key_bin += repeat_string(HMAC_BLOCK_SIZE - length(key_bin), "0")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

🔴 Критическая ошибка безопасности: Ключ HMAC дополняется символом '0' (ascii2text(48)) вместо нулевого байта (ascii2text(0)). Согласно стандарту HMAC, дополнение должно производиться нулевыми байтами. Эта ошибка приводит к генерации неверной HMAC-подписи, что полностью нарушает механизм проверки целостности данных.

        key_bin += repeat_string(HMAC_BLOCK_SIZE - length(key_bin), ascii2text(0))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Нулевой байт не добавляет ничего к строке и она никак не меняется. Поэтому "0"

for(var/i in 1 to times)
. += string

// Создает строку используя список из ASCII
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по стилю: Комментарий в коде должен быть на английском языке. Это требование стайлгайда (пункт 4.1, строка 68) для обеспечения согласованности кодовой базы.

// Creates a string using a list of ASCII codes
References
  1. Комментарии в коде должны быть на английском. (link)


update_static_data_for_all_viewers()

// Проверяет наличие всех данных
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по стилю: Комментарий в коде должен быть на английском языке. Это требование стайлгайда (пункт 4.1, строка 68) для обеспечения согласованности кодовой базы.

// Checks for presence of all data
References
  1. Комментарии в коде должны быть на английском. (link)

Comment on lines 324 to 343
if(!LAZYACCESS(data, "dupe_data"))
return FALSE

if(!LAZYACCESS(data, "name"))
return FALSE

if(!LAZYACCESS(data, "materials"))
return FALSE

if(!LAZYACCESS(data, "integrated_circuit"))
return FALSE

if(!LAZYACCESS(data, "Icon"))
return FALSE

if(!LAZYACCESS(data, "IconState"))
return FALSE

if(!LAZYACCESS(data, "desc"))
return FALSE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по улучшению: Блок проверки полей JSON содержит много однотипных проверок. Для улучшения читаемости и упрощения дальнейшей поддержки кода, этот блок можно отрефакторить, используя цикл по списку обязательных ключей.

	var/list/required_keys = list("dupe_data", "name", "materials", "integrated_circuit", "Icon", "IconState", "desc")
	for(var/key in required_keys)
		if(!LAZYACCESS(data, key))
			return FALSE


return TRUE

// Для иморта платы
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по стилю: Комментарий в коде должен быть на английском языке. Это требование стайлгайда (пункт 4.1, строка 68) для обеспечения согласованности кодовой базы.

// For board import
References
  1. Комментарии в коде должны быть на английском. (link)

Comment on lines +348 to +352
/obj/machinery/r_n_d/circuit_imprinter/proc/save_circuit_by_json(mob/living/user, json_data)
if(!can_save_circuit_by_json(user, json_data))
return

var/list/data = json_decode(json_data)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по производительности: Процедура save_circuit_by_json вызывает can_save_circuit_by_json, которая уже выполняет json_decode. Затем save_circuit_by_json выполняет json_decode повторно. Это избыточно и немного снижает производительность. Рекомендуется передавать уже декодированные данные из can_save_circuit_by_json или изменить логику, чтобы избежать двойного декодирования.


var/hmac_key = CONFIG_GET(string/hmac_key) ? CONFIG_GET(string/hmac_key) : ""

// Создает HMAC если ключ корректен
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по стилю: Комментарий в коде должен быть на английском языке. Это требование стайлгайда (пункт 4.1, строка 68) для обеспечения согласованности кодовой базы.

			// Creates HMAC if the key is correct
References
  1. Комментарии в коде должны быть на английском. (link)

Comment on lines 90 to 92
var/len = length(hex_key)
if(len != 40 && len != 64)
return FALSE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по улучшению: Функция validate_hmac_key проверяет длину ключа на равенство 40 или 64 символам. В описании пулл-реквеста и в файле конфигурации упоминается только длина в 40 символов. Причина для поддержки 64-символьной длины не ясна. Рекомендуется либо добавить комментарий, объясняющий эту логику, либо убрать проверку на 64 символа для соответствия документации.

@github-actions github-actions bot removed the Merge Conflict PR содержит изменения, конфликтующие с master-веткой. label Jan 30, 2026
@kkadmor
Copy link
Contributor Author

kkadmor commented Jan 30, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Аналитический отчёт от Большого Брата. Обработка запроса завершена.

Приветствую! Я проанализировал предложенные Вами изменения. С технической точки зрения, работа выглядит требующей доработок.

Сводка анализа:

  • 🔴 Критических замечаний: 1
  • 🟡 Рекомендаций: 6
  • 💡 Предложений: 0

🔴 Критические замечания (требуют обязательного исправления):

  • code/modules/wiremod/core/hmac.dm:19-20: Обнаружена критическая уязвимость в реализации HMAC. Ключ дополняется некорректно, что может привести к возможности подделки данных плат.

🟡 Рекомендации по улучшению:

  • code/modules/research/circuitprinter.dm:313-319: Процедура can_save_circuit_by_json не обрабатывает некорректный JSON, что может привести к ошибке выполнения.
  • code/modules/research/circuitprinter.dm:440: В логике импорта обнаружен повторяющийся вызов функции, что снижает производительность и читаемость кода.
  • code/modules/research/circuitprinter.dm:450: Аналогично, обнаружен повторяющийся вызов функции.
  • code/__HELPERS/text.dm:65: Комментарий в коде должен быть на английском языке в соответствии со стайлгайдом проекта.
  • code/modules/research/circuitprinter.dm:312: Комментарии в коде должны быть на английском языке.
  • code/modules/wiremod/core/hmac.dm:5-9: Комментарии в коде должны быть на английском языке.

Пожалуйста, ознакомьтесь с комментариями к отдельным строкам кода для получения более подробной информации.

Спасибо за ваш вклад в проект!

Comment on lines +19 to +20
if(length(key_bin) < HMAC_BLOCK_SIZE)
key_bin += repeat_string(HMAC_BLOCK_SIZE - length(key_bin), "0")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

🔴 Критично: Некорректная реализация HMAC. Ключ дополняется ASCII-символами '0' ("0") вместо нулевых байтов. Согласно RFC 2104, ключ, который короче размера блока, должен быть дополнен до размера блока нулевыми байтами. Текущая реализация использует символ "0", что приводит к неверной генерации подписи и создаёт уязвимость, позволяющую подделку данных платы.

	if(length(key_bin) < HMAC_BLOCK_SIZE)
		key_bin += repeat_string(HMAC_BLOCK_SIZE - length(key_bin), ascii2text(0))

Comment on lines 313 to 319
/obj/machinery/r_n_d/circuit_imprinter/proc/can_save_circuit_by_json(mob/living/user, json_data)
var/list/data = json_decode(json_data)
var/list/required_keys = list("dupe_data", "name", "materials", "integrated_circuit", "Icon", "IconState", "desc")
for(var/key in required_keys)
if(!LAZYACCESS(data, key))
return FALSE
return TRUE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

🟡 Рекомендация: Обнаружена потенциальная ошибка выполнения в процедуре can_save_circuit_by_json. Функция json_decode() может вернуть null, если json_data содержит некорректный JSON. В этом случае последующее обращение к data в цикле for вызовет ошибку. Рекомендую добавить проверку if(!islist(data)) return FALSE после вызова json_decode() для предотвращения падения сервера.

/obj/machinery/r_n_d/circuit_imprinter/proc/can_save_circuit_by_json(mob/living/user, json_data)
	var/list/data = json_decode(json_data)
	if(!islist(data))
		return FALSE
	var/list/required_keys = list("dupe_data", "name", "materials", "integrated_circuit", "Icon", "IconState", "desc")
	for(var/key in required_keys)
		if(!LAZYACCESS(data, key))
			return FALSE
	return TRUE
References
  1. Требовать проверку на null (if(!variable)) перед использованием объекта, особенно после locate(), find_in_view() и т.п. (link)

for(var/i in 1 to times)
. += string

// Создает строку используя список из ASCII
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по стилю: Согласно стайлгайду (пункт 4.1, правило о комментариях), все комментарии в коде должны быть на английском языке.

// Creates a string using a list of ASCII codes
References
  1. Комментарии должны быть на английском языке и объяснять 'почему', а не 'что'. (link)


update_static_data_for_all_viewers()

// Проверяет наличие всех данных
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по стилю: Согласно стайлгайду (пункт 4.1, правило о комментариях), все комментарии в коде должны быть на английском языке. В этом файле несколько таких комментариев.

// Checks if all data is present
References
  1. Комментарии должны быть на английском языке и объяснять 'почему', а не 'что'. (link)

var/mob/user = ui.user

var/text = tgui_input_text(user, "Вставьте текст интегральной платы", "Импорт схемы", encode=FALSE, max_length = 999999999)
text = text && ascii_list2text(rustlib_decode_base64(text)) ? ascii_list2text(rustlib_decode_base64(text)) : ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по улучшению: Вызов ascii_list2text(rustlib_decode_base64(text)) повторяется. Для улучшения читаемости и производительности, результат можно сохранить в переменную.

			var/list/decoded_list = rustlib_decode_base64(text)
			text = text && decoded_list ? ascii_list2text(decoded_list) : ""


var/list/parts = splittext(text, ".") // [1] - json в виде списка ASCII [2] - HMAC в виде списка ASCII

var/json_data = ascii_list2text(rustlib_decode_base64(parts[1])) ? ascii_list2text(rustlib_decode_base64(parts[1])) : ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по улучшению: Аналогично предыдущему замечанию, вызов ascii_list2text(rustlib_decode_base64(parts[1])) повторяется. Рекомендуется сохранить результат в переменную.

			var/list/decoded_json_b64 = rustlib_decode_base64(parts[1])
			var/json_data = decoded_json_b64 ? ascii_list2text(decoded_json_b64) : ""

Comment on lines +5 to +9
/*
* Основная функция HMAC-MD5
* hex_key - ключ в hex-формате
* data - данные для подписи
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

🟡 Рекомендация по стилю: Согласно стайлгайду (пункт 4.1, правило о комментариях), все комментарии в коде должны быть на английском языке.

/*
 * Main HMAC-MD5 function
 * hex_key - key in hex format
 * data - data to be signed
 */
References
  1. Комментарии должны быть на английском языке и объяснять 'почему', а не 'что'. (link)

@github-actions github-actions bot added the Merge Conflict PR содержит изменения, конфликтующие с master-веткой. label Jan 31, 2026
@kkadmor
Copy link
Contributor Author

kkadmor commented Feb 10, 2026

Ожидает ревью и тд.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 TGUI PR содержит изменения в файлах TGUI. ⚙️ Изменение конфига PR изменяет конфигурационные файлы сервера или клиента. Merge Conflict PR содержит изменения, конфликтующие с master-веткой.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant