From 075d03107586ee0bd9c6f14233e96d8d6047078e Mon Sep 17 00:00:00 2001 From: DVONIKS <88653131+DVOniksWyvern@users.noreply.github.com> Date: Tue, 9 Jul 2024 18:51:00 +0300 Subject: [PATCH 1/7] =?UTF-8?q?=D0=A3=D0=B1=D0=B8=D0=B9=D1=81=D1=82=D0=B2?= =?UTF-8?q?=D0=BE=20=D0=B0=D0=B2=D1=82=D0=BE=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=8B=20v.1.00=20(#431)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Убийство автозамены v.1.00 Удалено ГОВНО Добавлены говняшки поменьше, но спрятанные за "%". Первая версия, будет дополняться. * Update slang.json --- Resources/White/ChatFilters/slang.json | 526 +++---------------------- 1 file changed, 54 insertions(+), 472 deletions(-) diff --git a/Resources/White/ChatFilters/slang.json b/Resources/White/ChatFilters/slang.json index 1dd0ab4a1c..d7700875c7 100644 --- a/Resources/White/ChatFilters/slang.json +++ b/Resources/White/ChatFilters/slang.json @@ -1,474 +1,56 @@ { - "срп": "стандартные рабочие процедуры", - "ерп": "секс", - "фапать": "дрочить", - "фапал": "дрочил", - "фапали": "дрочили", - "бабиджон": "элемент", - "бабиджону": "элементу", - "бабиджона": "элемента", - "бабиджонов": "элементов", - "дек": "детектив", - "дек": "детектив", - "деку": "детективу", - "дека": "детектива", - "дэк": "детектив", - "дэку": "детективу", - "мед": "медицинский", - "дэка": "детектива", - "инжи": "инженеры", - "инж": "инженер", - "инжам": "инженерам", - "инжы": "инженеры", - "инжу": "инженеру", - "гиб": "взрыв", - "гибнулся": "разорвался", - "гибнет": "разорвет", - "гибнут": "разорвут", - "гибнутся": "разорвутся", - "гибнется": "разорвется", - "лимитка": "бомба", - "лимитку": "бомбу", - "лимитки": "бомбы", - "лимиток": "бомб", - "таблы": "таблетки", - "ихний": "их", - "читер": "волшебник", - "читеры": "волшебники", - "читера": "волшебника", - "читеру": "волшебнику", - "читеров": "волшебников", - "читераст": "волшебник", - "читерасту": "волшебнику", - "читерасты": "волшебники", - "читерастов": "волшебников", - "читераста": "волшебника", - "читы": "магия", - "мш": "имплант защиты разума", - "миссклик": "случайность", - "мис клик": "случайность", - "мисс клик": "случайность", - "лкм": "левая рука", - "пкм": "правая рука", - "бан": "наказание", - "банец": "наказание", - "рп": "нормы общества", - "по рп": "по нормам общества", - "рп игра": "жизнь", - "ролеплей": "реальность", - "нон рп": "выход из реальности", - "нонрп": "выход из реальности", - "нрп": "выход из реальности", - "рдм": "безумие", - "мрп": "дебилизм", - "лрп": "дебилизм", - "хрп": "дебилизм", - "дм": "безумие", - "фрикил": "убийство", - "фрикилл": "убийство", - "фри килл": "убийство", - "фри кил": "убийство", - "админ": "бог", - "админы": "боги", - "админов": "богов", - "админами": "богами", - "админам": "богам", - "педаль": "бог", - "педали": "боги", - "педалей": "богов", - "педалями": "богами", - "педалям": "богам", - "метагейм": "недоступные знания", - "метагей": "гад", - "мета гейм": "недоступные знания", - "гриф": "безумие", - "ахелп": "божественный суд", - "иц": "наш мир", - "ic": "наш мир", - "ооц": "загробный мир", - "оос": "загробный мир", - "ooc": "загробный мир", - "оок": "загробный мир", - "лооц": "загробный мир", - "лоок": "загробный мир", - "looc": "загробный мир", - "щиткур": "гандон", - "щиткура": "гандона", - "щиткуры": "гандоны", - "щиткурити": "гандонство", - "дизарм": "обезоружить", - "разгерм": "разгерметизация", - "разгерма": "разгерметизация", - "разгерму": "разгерметизацию", - "разгерме": "разгерметизации", - "разгермы": "разгерметизации", - "крит": "критическое состояние", - "крите": "критическом состоянии", - "ситх": "предатель", - "ситха": "предателя", - "ситху": "предателю", - "ситхи": "предатели", - "ситхам": "предателям", - "ситхов": "предателей", - "рева": "революция", - "рёва": "революция", - "рево": "революция", - "рев": "революционер", - "хз": "я не знаю", - "раш": "штурм", - "рашим": "штурмуем", - "рашит": "штурмует", - "рус": "древний", - "русы": "древние", - "украина": "древнее государство", - "россия": "древнее государство", - "росия": "древнее государство", - "америка": "древнее государство", - "американец": "древний", - "пендосы": "древний", - "байкал": "озеро", - "байкала": "озера", - "байкале": "озере", - "баф": "усиление", - "бафф": "усиление", - "бафнул": "усилил", - "баффнул": "усилил", - "забаффал": "усилил", - "забафал": "усилил", - "крип": "лох", - "крипа": "лоха", - "крипов": "лохов", - "крипу": "лоху", - "крипы": "лохи", - "нуб": "лох", - "нуба": "лоха", - "нубов": "лохов", - "нубу": "лоху", - "нубы": "лохи", - "нубик": "лох", - "нубика": "лоха", - "нубиков": "лохов", - "нубику": "лоху", - "нубики": "лохи", - "дота": "игра", - "дотер": "умственно-отсталый", - "доту": "игру", - "амогус": "космонавт", - "амонгас": "космонавт", - "амонг ас": "космонавт", - "графика": "окружение", - "вики": "путеводитель", - "лаги": "ноги не ходят", - "лагает": "ноги не ходят", - "лагало": "ноги не ходили", - "отлагало": "ноги не ходили", - "го": "пошли", - "гоу": "пошли", - "оч": "очень", - "магмы": "магнитные ботинки", - "изоли": "изолирующие перчатки", - "изольки": "изолирующие перчатки", - "изолек": "изолирующих перчаток", - "неко": "кошка", - "нэко": "кошка", - "рофл": "смешно", - "рофлишь": "смеешься", - "рофлинка": "смешинка", - "рофлик": "смешное", - "пранк": "прикол", - "пранки": "приколы", - "пранкер": "приколист", - "пранкеры": "приколисты", - "пранкеров": "приколистов", - "пранкеру": "приколисту", - "пранканул": "прикольнул", - "пранканули": "прикольнули", - "ясн": "ясно", - "тп": "телепортация", - "тпшнулся": "телепортировался", - "тпшнись": "телепортируйся", - "тпнули": "телепортировали", - "тпнись": "телепортируйся", - "кз": "космический закон", - "пон": "понял", - "контрить": "противодействовать", - "контрил": "противодействовал", - "законтрить": "противодействовать", - "законтрил": "противодействовал", - "понты": "выебоны", - "панты": "выебоны", - "понтовался": "выебывался", - "пантовался": "выебывался", - "понтонулся": "выебывался", - "пантонулся": "выебывался", - "всм": "всмысле", - "чзх": "что за херня", - "лут": "барахло", - "лутался": "собирал барахло", - "лутаемся": "собираем барахло", - "лутайся": "собирай барахло", - "лутовался": "собирал барахло", - "соло": "один", - "тильт": "депрессия", - "тильтанул": "упал в депрессию", - "тильте": "депрессии", - "чел": "мужик", - "челы": "мужики", - "челу": "мужику", - "челик": "мужик", - "челикс": "мужик", - "нюк": "оперативник", - "лив": "уход", - "ливаю": "ухожу", - "ливнул": "вышел", - "збс": "заебись", - "нюка": "оперативник", - "поридж": "манная каша", - "бб": "пока", - "быро": "быстро", - "непон": "не понял", - "заробастил": "победил", - "анробаст": "слабый", - "голо": "голопаразит", - "гойда": "я даун", - "гойду": "я даун", - "гойды": "я даун", - "кек": "смешно", - "лол": "смешно", - "лмао": "смешно", - "чип и дейл": "космобурундуки", - "корвакс": "тоталитарная вселенная", - "корваксе": "тоталитарной вселенной", - "вайт дрим": "замечательная вселенная", - "вд": "замечательная вселенная", - "чат": "разговор", - "пермач": "наказание", - "запермили": "наказали", - "запермят": "накажут", - "дискорд": "передовое средство коммуникации", - "дискорде": "передовом средстве коммуникации", - "дискорда": "передового средства коммуникации", - "тикток": "телевизор", - "фембой": "лох", - "фембою": "лоху", - "фембоя": "лоха", - "фембоев": "лохов", - "фембойчик": "лох", - "фембойчиков": "лохов", - "фембойчику": "лоху", - "фембойчика": "лоха", - "кринж": "стыд", - "кринжанул": "пристыдился", - "кринге": "стыд", - "нипон": "не понял", - "разлокать": "разблокировать", - "юзать": "использовать", - "юзай": "используй", - "юзнул": "использовал", - "кста": "кстати", - "кст": "кстати", - "нинада": "не надо", - "гг": "хорошо сработано", - "диз": "дизейблер", - "прост": "просто", - "?": "м?", - "!": "а!", - "..": "У меня нет слов", - "...": "У меня нет слов", - "....": "У меня нет слов", - " ,": ",", - "синга": "сингулярность", - "синг": "сингулярность", - "сингу": "сингулярность", - "синги": "сингулярности", - "+": "плюс", - "=": "равно", - ")": "я удовлетворен", - "(": "я недоволен", - "чекай": "смотри", - "чекнул": "смотрел", - "чекнули": "смотрели", - "чекнешь": "осмотришь", - "чекни": "смотри", - "чекали": "смотрели", - "чекал": "смотрел", - "хилл": "лечение", - "подхиль": "полечи", - "хильни": "полечи", - "лекай": "лечи", - "полекай": "полечи", - "лекани": "полечи", - "када": "когда", - "чо": "че", - "бебра": "форма жизни", - "фурри": "животные", - "фури": "животные", - "фуррятина": "животные", - "изи": "легко", - "найс": "круто", - "фулл": "полный", - "фул": "полный", - "фулловый": "полный", - "изично": "легко", - "пруф": "доказательство", - "пруфани": "докажи", - "пруфанул": "доказал", - "чилить": "отдыхать", - "чилл": "отдых", - "чиллит": "отдыхает", - "чиллим": "отдыхаем", - "жиза": "жизненно", - "анома": "аномалия", - "аному": "аномалию", - "аномы": "аномалии", - "аномов": "аномалий", - "аномах": "аномалиях", - "сус": "подозрительно", - "сасно": "привлекательно", - "сасный": "привлекательный", - "майнкрафт": "древняя игра", - "синди": "синдикат", - "синдик": "синдикат", - "синд": "синдикат", - "топ": "круто", - "топово": "круто", - "топовый": "крутой", - "топчик": "круто", - "буллинг": "издевательства", - "булинг": "издевательства", - "буллил": "издевался", - "булил": "издевался", - "забулил": "издевался", - "забуллил": "издевался", - "бургер кинг": "говно", - "ревенант": "что-то непонятное", - "ержан": "мужик", - "нюкеры": "оперативники", - "нюкер": "оперативник", - "яо": "ядерные оперативники", - "яой": "ядерные оперативники", - "яошники": "ядерные оперативники", - "яойшики": "ядерные оперативники", - "яойники": "ядерные оперативники", - "уч": "ускоритель частиц", - "нагибатор": "сильный мужик", - "нагебатор": "сильный мужик", - "трейтор": "предатель", - "тритор": "предатель", - "брух": "братан...", - "имба": "нечестно", - "мб": "может быть", - "баг": "проблема", - "бага": "проблемы", - "багов": "проблем", - "баги": "проблемы", - "багнутый": "проблемный", - "баганутый": "проблемный", - "багованный": "проблемный", - "багованый": "проблемный", - "спс": "спасибо", - "плиз": "пожалуйста", - "плз": "пожалуйста", - "плс": "пожалуйста", - "пж": "пожалуйста", - "кеп": "капитан", - "ку": "привет", - "хелп": "помоги", - "хелпани": "помоги", - "хелпанул": "помог", - "прив": "привет", - "эвак": "эвакуацию", - "уже эвак": "уже эвакуация", - "там эвак": "там эвакуация", - "где эвак": "где эвакуация", - "когда эвак": "когда эвакуация", - "скоро эвак": "скоро эвакуация", - "рядом эвак": "рядом эвакуация", - "срочник": "неумеха", - "срочники": "неумехи", - "срочников": "неумех", - "срочникам": "неумехам", - "срочников": "неумех", - "райан гослинг": "знаменитый актер", - "гитлер": "синдикат", - "адольф гитлер": "синдикат", - "путин": "я даун", - "вв": "высоковольтные", - "св": "средневольтные", - "нв": "низковольтные", - "кк": "красный код", - "зк": "зеленый код", - "ск": "синий код", - "жк": "желтый код", - "жк": "желтый код", - "крч": "короче", - "пог": "смешно", - "мем": "смешно", - "мемно": "смешно", - "перемога": "победа", - "зрада": "поражение", - "аирлок": "шлюз", - "я в ссд": "я засыпаю", - "он в ссд": "он уснул", - "это ссд": "он спит", - "это ссдшник": "он спит", - "ссд": "сон", - "вард": "варден", - "ультанул": "обосрался", - "ульта": "обсер", - "ультил": "обосрался", - "аниме": "мультики", - "анимэ": "мультики", - "коопер": "гандон", - "кооперы": "гандоны", - "кооперов": "гандонов", - "коопера": "гандона", - "тян": "девушка", - "тянка": "девушка", - "тяночка": "девушка", - "тяночку": "девушку", - "тяночке": "девушке", - "тяночки": "девушки", - "сигма": "даун", - "сигмы": "дауны", - "скибиди": "я даун", - "гигачад": "обосранец", - "гигачаду": "обосранцу", - "гигачады": "обосранцы", - "гигачадов": "обосранцев", - "гигачадах": "обосранцах", - "гигачада": "обосранца", - "негр": "чернокожий", - "негры": "чернокожие", - "негра": "чернокожего", - "негров": "чернокожих", - "нигер": "чернокожий", - "нигеры": "чернокожие", - "нигера": "чернокожего", - "нигеров": "чернокожих", - "ниггер": "чернокожий", - "ниггеры": "чернокожие", - "ниггера": "чернокожего", - "ниггеров": "чернокожих", - "nigger": "чернокожий", - "niggers": "чернокожие", - "niger": "чернокожий", - "nigers": "чернокожие", - "пидор": "гей", - "пидоры": "геи", - "пидора": "гея", - "пидоров": "геев", - "пидорский": "гейский", - "пидар": "гей", - "пидары": "геи", - "пидара": "гея", - "пидаров": "геев", - "пидарский": "гейский", - "faggot": "гей", - "fagot": "гей", - "fag": "гей", - "куколд": "олень", - "куколды": "олени", - "куколда": "оленя", - "куколдов": "оленей" +"%срп": "стандартные рабочие процедуры", +"%дек": "детектив", +"%дек": "детектив", +"%деку": "детективу", +"%дека": "детектива", +"%дэк": "детектив", +"%дэку": "детективу", +"%мед": "медицинский", +"%дэка": "детектива", +"%инжи": "инженеры", +"%инж": "инженер", +"%инжам": "инженерам", +"%инжы": "инженеры", +"%инжу": "инженеру", +"%таблы": "таблетки", +"%мш": "имплант защиты разума", +"%разгерм": "разгерметизация", +"%разгерма": "разгерметизация", +"%разгерму": "разгерметизацию", +"%разгерме": "разгерметизации", +"%разгермы": "разгерметизации", +"%крит": "критическое состояние", +"%крите": "критическом состоянии", +"%рева": "революция", +"%рёва": "революция", +"%рево": "революция", +"%рев": "революционер", +"%хз": "я не знаю", +"%магмы": "магнитные ботинки", +"%изоли": "изолирующие перчатки", +"%изольки": "изолирующие перчатки", +"%изолек": "изолирующих перчаток", +"%кз": "космический закон", +"%синга": "сингулярность", +"%синг": "сингулярность", +"%сингу": "сингулярность", +"%синги": "сингулярности", +"%яо": "ядерные оперативники", +"%яой": "ядерные оперативники", +"%яошники": "ядерные оперативники", +"%яойшики": "ядерные оперативники", +"%яойники": "ядерные оперативники", +"%уч": "ускоритель частиц", +"%спс": "спасибо", +"%плиз": "пожалуйста", +"%эвак": "эвакуацию", +"%вв": "высоковольтные", +"%св": "средневольтные", +"%нв": "низковольтные", +"%кк": "красный код", +"%зк": "зеленый код", +"%ск": "синий код", +"%жк": "желтый код", +"%жк": "желтый код" } From 5bf080f4f24493dc26293490b3df6ff1f7e10609 Mon Sep 17 00:00:00 2001 From: RavmorganButOnCocaine Date: Tue, 9 Jul 2024 15:52:04 +0000 Subject: [PATCH 2/7] Automatic changelog update --- Resources/Changelog/ChangelogWhite.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Resources/Changelog/ChangelogWhite.yml b/Resources/Changelog/ChangelogWhite.yml index 8bb19a1d7a..61eb964ff0 100644 --- a/Resources/Changelog/ChangelogWhite.yml +++ b/Resources/Changelog/ChangelogWhite.yml @@ -5607,3 +5607,14 @@ id: 363 time: '2024-07-07T09:40:00.0000000+00:00' url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/429 +- author: DVOniksWyvern + changes: + - message: "55 \u0441\u043E\u043A\u0440\u0430\u0449\u0435\u043D\u0438\u0439 \u0447\ + \u0435\u0440\u0435\u0437 %" + type: Add + - message: "\u0410\u0432\u0442\u043E\u0437\u0430\u043C\u0435\u043D\u0430 \u0431\u043E\ + \u043B\u044C\u0448\u0435 400 \u0441\u043B\u043E\u0432" + type: Remove + id: 364 + time: '2024-07-09T15:51:01.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/431 From dc5a30e6eea3607691aee8b02dbdb4d49a3ff55a Mon Sep 17 00:00:00 2001 From: ThereDrD0 <88589686+ThereDrD0@users.noreply.github.com> Date: Wed, 10 Jul 2024 14:02:03 +0300 Subject: [PATCH 3/7] fix: fix slang regex (#433) --- .../Chat/Managers/ChatSanitizationManager.cs | 2 +- Resources/White/ChatFilters/slang.json | 109 +++++++++--------- 2 files changed, 56 insertions(+), 55 deletions(-) diff --git a/Content.Server/Chat/Managers/ChatSanitizationManager.cs b/Content.Server/Chat/Managers/ChatSanitizationManager.cs index c68eaa2009..adeff51b50 100644 --- a/Content.Server/Chat/Managers/ChatSanitizationManager.cs +++ b/Content.Server/Chat/Managers/ChatSanitizationManager.cs @@ -161,7 +161,7 @@ public sealed class ChatSanitizationManager : IChatSanitizationManager //WD-EDIT public string SanitizeOutSlang(string input) { - var pattern = @"(^\!|^\?|[\p{L}\d'`-]+)"; + var pattern = @"(^\!|^\?|[\p{L}\d'`%-]+)"; var newMessage = Regex.Replace(input, pattern , match => _slangToNormal.ContainsKey(match.Groups[1].Value.ToLower()) ? _slangToNormal[match.Groups[1].Value.ToLower()] : match.Value, RegexOptions.IgnoreCase); diff --git a/Resources/White/ChatFilters/slang.json b/Resources/White/ChatFilters/slang.json index d7700875c7..d9f87cdbe4 100644 --- a/Resources/White/ChatFilters/slang.json +++ b/Resources/White/ChatFilters/slang.json @@ -1,56 +1,57 @@ { -"%срп": "стандартные рабочие процедуры", -"%дек": "детектив", -"%дек": "детектив", -"%деку": "детективу", -"%дека": "детектива", -"%дэк": "детектив", -"%дэку": "детективу", -"%мед": "медицинский", -"%дэка": "детектива", -"%инжи": "инженеры", -"%инж": "инженер", -"%инжам": "инженерам", -"%инжы": "инженеры", -"%инжу": "инженеру", -"%таблы": "таблетки", -"%мш": "имплант защиты разума", -"%разгерм": "разгерметизация", -"%разгерма": "разгерметизация", -"%разгерму": "разгерметизацию", -"%разгерме": "разгерметизации", -"%разгермы": "разгерметизации", -"%крит": "критическое состояние", -"%крите": "критическом состоянии", -"%рева": "революция", -"%рёва": "революция", -"%рево": "революция", -"%рев": "революционер", -"%хз": "я не знаю", -"%магмы": "магнитные ботинки", -"%изоли": "изолирующие перчатки", -"%изольки": "изолирующие перчатки", -"%изолек": "изолирующих перчаток", -"%кз": "космический закон", -"%синга": "сингулярность", -"%синг": "сингулярность", -"%сингу": "сингулярность", -"%синги": "сингулярности", -"%яо": "ядерные оперативники", -"%яой": "ядерные оперативники", -"%яошники": "ядерные оперативники", -"%яойшики": "ядерные оперативники", -"%яойники": "ядерные оперативники", -"%уч": "ускоритель частиц", -"%спс": "спасибо", -"%плиз": "пожалуйста", -"%эвак": "эвакуацию", -"%вв": "высоковольтные", -"%св": "средневольтные", -"%нв": "низковольтные", -"%кк": "красный код", -"%зк": "зеленый код", -"%ск": "синий код", -"%жк": "желтый код", -"%жк": "желтый код" + "%срп": "стандартные рабочие процедуры", + "%дек": "детектив", + "%деку": "детективу", + "%дека": "детектива", + "%дэк": "детектив", + "%дэку": "детективу", + "%мед": "медицинский", + "%дэка": "детектива", + "%инжи": "инженеры", + "%инж": "инженер", + "%инжам": "инженерам", + "%инжы": "инженеры", + "%инжу": "инженеру", + "%таблы": "таблетки", + "%мш": "имплант защиты разума", + "%мщ": "имплант защиты разума", + "%разгерм": "разгерметизация", + "%разгерма": "разгерметизация", + "%разгерму": "разгерметизацию", + "%разгерме": "разгерметизации", + "%разгермы": "разгерметизации", + "%крит": "критическое состояние", + "%крите": "критическом состоянии", + "%рева": "революция", + "%рёва": "революция", + "%рево": "революция", + "%рев": "революционер", + "%хз": "я не знаю", + "%магмы": "магнитные ботинки", + "%изоли": "изолирующие перчатки", + "%изольки": "изолирующие перчатки", + "%изолек": "изолирующих перчаток", + "%кз": "космический закон", + "%синга": "сингулярность", + "%синг": "сингулярность", + "%сингу": "сингулярность", + "%синги": "сингулярности", + "%яо": "ядерные оперативники", + "%яой": "ядерные оперативники", + "%яошники": "ядерные оперативники", + "%яойшики": "ядерные оперативники", + "%яойники": "ядерные оперативники", + "%уч": "ускоритель частиц", + "%спс": "спасибо", + "%плиз": "пожалуйста", + "%эвак": "эвакуацию", + "%вв": "высоковольтные", + "%св": "средневольтные", + "%нв": "низковольтные", + "%кк": "красный код", + "%зк": "зеленый код", + "%ск": "синий код", + "%жк": "желтый код", + "%стим": "стимулятор", + "%стимы": "стимуляторы" } From 86aa9a5ba3ada92bcfae110d502bffd8949ff1cd Mon Sep 17 00:00:00 2001 From: RavmorganButOnCocaine Date: Wed, 10 Jul 2024 11:03:06 +0000 Subject: [PATCH 4/7] Automatic changelog update --- Resources/Changelog/ChangelogWhite.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Resources/Changelog/ChangelogWhite.yml b/Resources/Changelog/ChangelogWhite.yml index 61eb964ff0..88f140c4d7 100644 --- a/Resources/Changelog/ChangelogWhite.yml +++ b/Resources/Changelog/ChangelogWhite.yml @@ -5618,3 +5618,13 @@ id: 364 time: '2024-07-09T15:51:01.0000000+00:00' url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/431 +- author: ThereDrD + changes: + - message: "\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\ + \u0435 \u0430\u0432\u0442\u043E\u0437\u0430\u043C\u0435\u043D\u044B \u0447\u0435\ + \u0440\u0435\u0437 % \u0441\u043D\u043E\u0432\u0430 \u0440\u0430\u0431\u043E\ + \u0442\u0430\u0435\u0442" + type: Fix + id: 365 + time: '2024-07-10T11:02:03.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/433 From 0b374ebd7cc39f86f7841d591149ffc88fa99f37 Mon Sep 17 00:00:00 2001 From: RedBurningPhoenix <147742474+RedBurningPhoenix@users.noreply.github.com> Date: Wed, 10 Jul 2024 16:11:32 +0500 Subject: [PATCH 5/7] HTN_Speaker (#432) Needed for phrases --- .../NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs | 9 +++++++-- Resources/Prototypes/NPCs/medibot.yml | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs b/Content.Server/NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs index cf07831959..613a15d21b 100644 --- a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs +++ b/Content.Server/NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs @@ -1,13 +1,16 @@ using Content.Server.Chat.Systems; +using Content.Shared.Random.Helpers; +using Robust.Shared.Random; namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators; public sealed partial class SpeakOperator : HTNOperator { private ChatSystem _chat = default!; + private IRobustRandom _random = default!; [DataField("speech", required: true)] - public string Speech = string.Empty; + public List Speech { get; set; } = new(); /// /// Whether to hide message from chat window and logs. @@ -19,13 +22,15 @@ public sealed partial class SpeakOperator : HTNOperator { base.Initialize(sysManager); _chat = IoCManager.Resolve().GetEntitySystem(); + _random = IoCManager.Resolve(); } public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime) { var speaker = blackboard.GetValue(NPCBlackboard.Owner); + var message = Loc.GetString(_random.Pick(Speech)); - _chat.TrySendInGameICMessage(speaker, Loc.GetString(Speech), InGameICChatType.Speak, hideChat: Hidden, hideLog: Hidden); + _chat.TrySendInGameICMessage(speaker, message, InGameICChatType.Speak, hideChat: Hidden, hideLog: Hidden); return base.Update(blackboard, frameTime); } } diff --git a/Resources/Prototypes/NPCs/medibot.yml b/Resources/Prototypes/NPCs/medibot.yml index c0853984ee..d96c64700f 100644 --- a/Resources/Prototypes/NPCs/medibot.yml +++ b/Resources/Prototypes/NPCs/medibot.yml @@ -20,7 +20,10 @@ - !type:HTNPrimitiveTask operator: !type:SpeakOperator - speech: medibot-start-inject + speech: + - Пожалуйста, не двигайтесь. + - Пожалуйста, стойте на месте. + - Пожалуйста, не шевелитесь. hidden: true - !type:HTNPrimitiveTask From 8deece00911e2a25633b07c4840a0e52026102c8 Mon Sep 17 00:00:00 2001 From: Spatison <137375981+Spatison@users.noreply.github.com> Date: Wed, 10 Jul 2024 16:26:50 +0300 Subject: [PATCH 6/7] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BB=D0=B5?= =?UTF-8?q?=D0=B6=D0=B0=D0=BD=D0=B8=D1=8F=20(#430)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix * commit * clear * commit * / WD EDIT --- .../Options/UI/Tabs/KeyRebindTab.xaml.cs | 8 ++++ .../Standing/StandingStateSystem.cs | 2 +- .../Rotation/RotationVisualizerSystem.cs | 41 +++++++++++++++++++ .../Buckle/SharedBuckleSystem.Buckle.cs | 16 -------- .../Standing/StandingStateComponent.cs | 21 +++++++--- .../Systems/SharedStandingStateSystem.cs | 37 +++++++++++++++-- Content.Shared/Stunnable/SharedStunSystem.cs | 3 +- .../_White/Standing/StandingStateSystem.cs | 29 +++++++++++++ Content.Shared/_White/WhiteCVars.cs | 6 +++ .../Wizard/Timestop/FreezeContactsSystem.cs | 6 +++ .../en-US/escape-menu/ui/options-menu.ftl | 1 + .../ru-RU/escape-menu/ui/options-menu.ftl | 1 + 12 files changed, 145 insertions(+), 26 deletions(-) create mode 100644 Content.Client/_White/Rotation/RotationVisualizerSystem.cs create mode 100644 Content.Shared/_White/Standing/StandingStateSystem.cs diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs index 883f517ad5..b5449c99d2 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -2,6 +2,7 @@ using System.Numerics; using Content.Client.Stylesheets; using Content.Shared.CCVar; using Content.Shared.Input; +using Content.Shared._White; using Robust.Client.AutoGenerated; using Robust.Client.Input; using Robust.Client.UserInterface; @@ -97,6 +98,12 @@ namespace Content.Client.Options.UI.Tabs _deferCommands.Add(_inputManager.SaveToUserData); } + private void HandleToggleAutoGetUp(BaseButton.ButtonToggledEventArgs args) // WD EDIT + { + _cfg.SetCVar(WhiteCVars.AutoGetUp, args.Pressed); + _cfg.SaveToFile(); + } + private void HandleStaticStorageUI(BaseButton.ButtonToggledEventArgs args) { _cfg.SetCVar(CCVars.StaticStorageUI, args.Pressed); @@ -185,6 +192,7 @@ namespace Content.Client.Options.UI.Tabs AddButton(ContentKeyFunctions.RotateStoredItem); AddButton(ContentKeyFunctions.SaveItemLocation); AddButton(ContentKeyFunctions.LieDown); // WD EDIT + AddCheckBox("ui-options-function-auto-get-up", _cfg.GetCVar(WhiteCVars.AutoGetUp), HandleToggleAutoGetUp); // WD EDIT AddHeader("ui-options-header-interaction-adv"); AddButton(ContentKeyFunctions.SmartEquipBackpack); diff --git a/Content.Client/Standing/StandingStateSystem.cs b/Content.Client/Standing/StandingStateSystem.cs index dcc4b97d2e..42f2e62427 100644 --- a/Content.Client/Standing/StandingStateSystem.cs +++ b/Content.Client/Standing/StandingStateSystem.cs @@ -6,4 +6,4 @@ namespace Content.Client.Standing; public sealed class StandingStateSystem : SharedStandingStateSystem { -} \ No newline at end of file +} diff --git a/Content.Client/_White/Rotation/RotationVisualizerSystem.cs b/Content.Client/_White/Rotation/RotationVisualizerSystem.cs new file mode 100644 index 0000000000..74d31fb1f5 --- /dev/null +++ b/Content.Client/_White/Rotation/RotationVisualizerSystem.cs @@ -0,0 +1,41 @@ +using Content.Shared.Rotation; +using Robust.Client.GameObjects; + +namespace Content.Client._White.Rotation; + +public sealed class RotationVisualizerSystem : EntitySystem +{ + [Dependency] private readonly AppearanceSystem _appearance = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + public override void Initialize() + { + SubscribeLocalEvent(OnMove); + } + + private void OnMove(EntityUid uid, RotationVisualsComponent component, ref MoveEvent args) + { + if (!TryComp(uid, out var sprite) || + !TryComp(uid, out var appearance)) + return; + + _appearance.TryGetData(uid, RotationVisuals.RotationState, out var state, appearance); + + var rotation = _transform.GetWorldRotation(uid); + + if (rotation.GetDir() is Direction.East or Direction.North or Direction.NorthEast or Direction.SouthEast) + { + if (state == RotationState.Horizontal && + sprite.Rotation == component.DefaultRotation) + { + sprite.Rotation = Angle.FromDegrees(270); + } + + return; + } + if (state == RotationState.Horizontal && + sprite.Rotation == Angle.FromDegrees(270)) + { + sprite.Rotation = component.DefaultRotation; + } + } +} diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs index ec4693b3f4..3287ced1bc 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs @@ -10,8 +10,6 @@ using Content.Shared.Interaction; using Content.Shared.Mobs.Components; using Content.Shared.Movement.Events; using Content.Shared.Popups; -using Content.Shared.Standing; -using Content.Shared.Standing.Systems; using Content.Shared.Storage.Components; using Content.Shared.Stunnable; using Content.Shared.Throwing; @@ -35,8 +33,6 @@ public abstract partial class SharedBuckleSystem SubscribeLocalEvent(OnBuckleInsertIntoEntityStorageAttempt); SubscribeLocalEvent(OnBucklePreventCollide); - SubscribeLocalEvent(OnBuckleDownAttempt); - SubscribeLocalEvent(OnBuckleStandAttempt); SubscribeLocalEvent(OnBuckleThrowPushbackAttempt); SubscribeLocalEvent(OnBuckleUpdateCanMove); } @@ -114,18 +110,6 @@ public abstract partial class SharedBuckleSystem args.Cancelled = true; } - private void OnBuckleDownAttempt(EntityUid uid, BuckleComponent component, DownAttemptEvent args) - { - if (component.Buckled) - args.Cancel(); - } - - private void OnBuckleStandAttempt(EntityUid uid, BuckleComponent component, StandAttemptEvent args) - { - if (component.Buckled) - args.Cancel(); - } - private void OnBuckleThrowPushbackAttempt(EntityUid uid, BuckleComponent component, ThrowPushbackAttemptEvent args) { if (component.Buckled) diff --git a/Content.Shared/Standing/StandingStateComponent.cs b/Content.Shared/Standing/StandingStateComponent.cs index 3db3488084..7af773cdb7 100644 --- a/Content.Shared/Standing/StandingStateComponent.cs +++ b/Content.Shared/Standing/StandingStateComponent.cs @@ -1,11 +1,12 @@ using Content.Shared.Standing.Systems; +using Content.Shared._White.Standing; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Serialization; namespace Content.Shared.Standing { - [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedStandingStateSystem))] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedStandingStateSystem), typeof(StandingStateSystem))] public sealed partial class StandingStateComponent : Component { [ViewVariables(VVAccess.ReadWrite), DataField] @@ -23,19 +24,29 @@ namespace Content.Shared.Standing // WD EDIT [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public bool CanLieDown = false; - + + // WD EDIT + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] + public bool AutoGetUp = false; + /// /// List of fixtures that had their collision mask changed when the entity was downed. /// Required for re-adding the collision mask. /// [DataField, AutoNetworkedField] public List ChangedFixtures = new(); - + } } [Serializable, NetSerializable] -public sealed class ChangeStandingStateEvent : EntityEventArgs +public sealed class ChangeStandingStateEvent : CancellableEntityEventArgs +{ +} + +// WD EDIT +[Serializable, NetSerializable] +public sealed class CheckAutoGetUpEvent : CancellableEntityEventArgs { } @@ -45,4 +56,4 @@ public enum StandingState Lying, GettingUp, Standing -} \ No newline at end of file +} diff --git a/Content.Shared/Standing/Systems/SharedStandingStateSystem.cs b/Content.Shared/Standing/Systems/SharedStandingStateSystem.cs index 35f1fccff8..58344769a7 100644 --- a/Content.Shared/Standing/Systems/SharedStandingStateSystem.cs +++ b/Content.Shared/Standing/Systems/SharedStandingStateSystem.cs @@ -7,6 +7,9 @@ using Content.Shared.Physics; using Content.Shared.Rotation; using Content.Shared.Slippery; using Content.Shared.Stunnable; +using Content.Shared._White.Wizard.Timestop; +using Content.Shared.Buckle; +using Content.Shared.Buckle.Components; using Robust.Shared.Audio.Systems; using Robust.Shared.Input.Binding; using Robust.Shared.Physics; @@ -14,6 +17,7 @@ using Robust.Shared.Physics.Systems; using Robust.Shared.Player; using Robust.Shared.Serialization; + namespace Content.Shared.Standing.Systems; public abstract partial class SharedStandingStateSystem : EntitySystem @@ -25,6 +29,9 @@ public abstract partial class SharedStandingStateSystem : EntitySystem [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; // WD EDIT [Dependency] private readonly SharedStunSystem _stun = default!; // WD EDIT [Dependency] private readonly MobStateSystem _mobState = default!; // WD EDIT + [Dependency] private readonly SharedBuckleSystem _buckle = default!; // WD EDIT + [Dependency] private readonly SharedTransformSystem _transform = default!; // WD EDIT + [Dependency] private readonly SharedRotationVisualsSystem _rotation = default!; // WD EDIT // If StandingCollisionLayer value is ever changed to more than one layer, the logic needs to be edited. private const int StandingCollisionLayer = (int)CollisionGroup.MidImpassable; @@ -53,6 +60,9 @@ public abstract partial class SharedStandingStateSystem : EntitySystem private void OnChangeState(ChangeStandingStateEvent ev, EntitySessionEventArgs args) { + if (TryComp(args.SenderSession.AttachedEntity, out _)) // WD EDIT + return; + if (!args.SenderSession.AttachedEntity.HasValue) { return; @@ -60,6 +70,11 @@ public abstract partial class SharedStandingStateSystem : EntitySystem var uid = args.SenderSession.AttachedEntity.Value; + if (!TryComp(uid, out StandingStateComponent? standing)) // WD EDIT + return; + + RaiseNetworkEvent(new CheckAutoGetUpEvent()); + if (_stun.IsParalyzed(uid)) { return; @@ -70,18 +85,23 @@ public abstract partial class SharedStandingStateSystem : EntitySystem return; } - if (IsDown(uid)) + if (IsDown(uid, standing)) { - TryStandUp(uid); + TryStandUp(uid, standing); } else { - TryLieDown(uid); + TryLieDown(uid, standing); } } private void OnStandingUpDoAfter(EntityUid uid, StandingStateComponent component, StandingUpDoAfterEvent args) { + if (args.Handled) // WD EDIT + { + component.CurrentState = StandingState.Lying; + return; + } Stand(uid); } @@ -192,6 +212,9 @@ public abstract partial class SharedStandingStateSystem : EntitySystem // Optional component. Resolve(uid, ref appearance, ref hands, false); + if (TryComp(uid, out BuckleComponent? buckle) && buckle.Buckled && !_buckle.TryUnbuckle(uid, uid, buckleComp: buckle)) // WD EDIT + return false; + // This is just to avoid most callers doing this manually saving boilerplate // 99% of the time you'll want to drop items but in some scenarios (e.g. buckling) you don't want to. // We do this BEFORE downing because something like buckle may be blocking downing but we want to drop hand items anyway @@ -212,6 +235,14 @@ public abstract partial class SharedStandingStateSystem : EntitySystem standingState.CurrentState = StandingState.Lying; Dirty(uid, standingState); + + var rotation = _transform.GetWorldRotation(uid); + + if (rotation.GetDir() is Direction.East or Direction.North or Direction.NorthEast or Direction.SouthEast) + _rotation.SetHorizontalAngle(uid, Angle.FromDegrees(270)); + else + _rotation.ResetHorizontalAngle(uid); + RaiseLocalEvent(uid, new DownedEvent()); // Seemed like the best place to put it diff --git a/Content.Shared/Stunnable/SharedStunSystem.cs b/Content.Shared/Stunnable/SharedStunSystem.cs index 8586e46a9a..f278665576 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.cs @@ -104,6 +104,7 @@ public abstract class SharedStunSystem : EntitySystem private void OnKnockInit(EntityUid uid, KnockedDownComponent component, ComponentInit args) { + RaiseNetworkEvent(new CheckAutoGetUpEvent()); // WD EDIT _standingState.Down(uid); } @@ -111,7 +112,7 @@ public abstract class SharedStunSystem : EntitySystem { // WD EDIT START // Don't stand up if we can lie down via keybind - if (!TryComp(uid, out StandingStateComponent? standing) || standing.CanLieDown) + if (!TryComp(uid, out StandingStateComponent? standing) || !(!standing.CanLieDown || standing.AutoGetUp)) // WD EDIT return; _standingState.Stand(uid, standing); diff --git a/Content.Shared/_White/Standing/StandingStateSystem.cs b/Content.Shared/_White/Standing/StandingStateSystem.cs new file mode 100644 index 0000000000..f0c4f77771 --- /dev/null +++ b/Content.Shared/_White/Standing/StandingStateSystem.cs @@ -0,0 +1,29 @@ +using Content.Shared.Standing; +using Robust.Shared.Configuration; + +namespace Content.Shared._White.Standing; + +public sealed class StandingStateSystem : EntitySystem +{ + + [Dependency] private readonly INetConfigurationManager _cfg = default!; + public override void Initialize() + { + SubscribeNetworkEvent(OnCheckAutoGetUp); + } + + + private void OnCheckAutoGetUp(CheckAutoGetUpEvent ev, EntitySessionEventArgs args) + { + if (!args.SenderSession.AttachedEntity.HasValue) + return; + + var uid = args.SenderSession.AttachedEntity.Value; + + if (!TryComp(uid, out StandingStateComponent? standing)) + return; + + standing.AutoGetUp = _cfg.GetClientCVar(args.SenderSession.Channel, WhiteCVars.AutoGetUp); + Dirty(args.SenderSession.AttachedEntity.Value, standing); + } +} diff --git a/Content.Shared/_White/WhiteCVars.cs b/Content.Shared/_White/WhiteCVars.cs index 98c13db7d3..da434e771b 100644 --- a/Content.Shared/_White/WhiteCVars.cs +++ b/Content.Shared/_White/WhiteCVars.cs @@ -307,6 +307,12 @@ public sealed class WhiteCVars public static readonly CVarDef LogChatActions = CVarDef.Create("white.log_to_chat", true, CVar.CLIENT | CVar.ARCHIVE | CVar.REPLICATED); + /// + /// Determines whether automatic get up is required + /// + public static readonly CVarDef AutoGetUp = + CVarDef.Create("white.auto_get_up", true, CVar.CLIENT | CVar.ARCHIVE | CVar.REPLICATED); + /* * Aspects */ diff --git a/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs b/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs index 4db8bbecaa..3880c11dd3 100644 --- a/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs +++ b/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs @@ -36,6 +36,7 @@ public sealed class FreezeContactsSystem : EntitySystem SubscribeLocalEvent(OnRemove); SubscribeLocalEvent(OnPreventCollide); SubscribeLocalEvent(OnGetInserted); + SubscribeLocalEvent(OnStandingUpDoAfter); SubscribeLocalEvent(OnAttempt); SubscribeLocalEvent(OnAttempt); @@ -61,6 +62,11 @@ public sealed class FreezeContactsSystem : EntitySystem args.Cancel(); } + private void OnStandingUpDoAfter(EntityUid uid, FrozenComponent component, StandingUpDoAfterEvent args) + { + args.Handled = true; + } + private void OnAttempt(EntityUid uid, FrozenComponent component, CancellableEntityEventArgs args) { args.Cancel(); diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl index 36429c843d..19afd1efdb 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -137,6 +137,7 @@ ui-options-function-swap-hands = Swap hands ui-options-function-move-stored-item = Move stored item ui-options-function-rotate-stored-item = Rotate stored item ui-options-function-lie-down = Lie down/Get up +ui-options-function-auto-get-up = Automatically get up when falling ui-options-function-save-item-location = Save item location ui-options-static-storage-ui = Lock storage window to hotbar diff --git a/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl b/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl index 11008c1f2b..f87208afd3 100644 --- a/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl @@ -139,6 +139,7 @@ ui-options-function-swap-hands = Поменять руки ui-options-function-move-stored-item = Переместить хранящийся объект ui-options-function-rotate-stored-item = Повернуть хранящийся объект ui-options-function-lie-down = Лечь/встать +ui-options-function-auto-get-up = Автоматически вставать при падении ui-options-function-save-item-location = Сохранить позицию предмета ui-options-static-storage-ui = Закрепить интерфейс хранилища на хотбаре From fa00ea8ae1b0d72b40505a9c63ddb2fb0fb64a64 Mon Sep 17 00:00:00 2001 From: RavmorganButOnCocaine Date: Wed, 10 Jul 2024 13:27:53 +0000 Subject: [PATCH 7/7] Automatic changelog update --- Resources/Changelog/ChangelogWhite.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Resources/Changelog/ChangelogWhite.yml b/Resources/Changelog/ChangelogWhite.yml index 88f140c4d7..c02f3ef82f 100644 --- a/Resources/Changelog/ChangelogWhite.yml +++ b/Resources/Changelog/ChangelogWhite.yml @@ -5628,3 +5628,21 @@ id: 365 time: '2024-07-10T11:02:03.0000000+00:00' url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/433 +- author: Spatison + changes: + - message: "\u0411\u043E\u043B\u044C\u0448\u0435 \u043D\u0435\u043B\u044C\u0437\u044F\ + \ \u0432\u0441\u0442\u0430\u0442\u044C \u043F\u0440\u0438 \u043E\u0441\u0442\ + \u0430\u043D\u043E\u0432\u043A\u0435 \u0432\u0440\u0435\u043C\u044F" + type: Fix + - message: "\u0418\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E \u043F\u043E\ + \u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u043B\u0435\u0436\u0430" + type: Fix + - message: "Cvar \u0432\u0441\u0442\u0430\u0432\u0430\u043D\u0438\u044F \u043F\u0440\ + \u0438 \u043F\u0430\u0434\u0435\u043D\u0438\u0438" + type: Tweak + - message: "\u041E\u0442\u043A\u0440\u0435\u043F\u043B\u0435\u043D\u0438\u0435 \u043F\ + \u0440\u0438 \u043F\u0430\u0434\u0435\u043D\u0438\u0438" + type: Tweak + id: 366 + time: '2024-07-10T13:26:50.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/430