From b75515ada109cad3a9b5d8e1d9f6294ee11fd1de Mon Sep 17 00:00:00 2001 From: stribog Date: Sat, 14 Nov 2026 20:19:26 +0100 Subject: [PATCH] fix(punishments): restrict freeze and unfreeze to the senior god MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Заморозка должна быть доступна только старшему имму (34). Сейчас это не так, и уровень тут вообще ни при чём. Как устроено на самом деле: - В таблице команд стоит kLvlFreeze (structs.h:91), и он равен kLvlGreatGod, то есть 33. Но для иммортальских команд уровень не проверяется ВООБЩЕ: ModernHasPrivilege (privilege.cpp:129) сверяет уровень только при minimum_level < kLvlImmortal. Для всего, что 31 и выше, решает privilege.xml. - Значит kLvlFreeze ни на что не влияет, а заморозить может любой бог с флагом FullAccess. Сейчас таких семеро. Поэтому проверка поставлена не в команду, а в punishments::SetFreeze -- туда сходятся все пять путей: "заморозить"/"freeze", "unfreeze", "set <чар> frozen", "set all frozen" и снятие из do_unfreeze. Одна проверка закрывает и заморозку, и разморозку: в SetFreeze они обе, times == 0 размораживает. Условие: privilege::IsOwner(ch) || GetRealLevel(ch) >= kLvlImplementator. Все вызывающие уже умеют обрабатывать false. Сборка без предупреждений, 872 теста проходят. Co-Authored-By: Claude Opus 5 --- src/administration/punishments.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/administration/punishments.cpp b/src/administration/punishments.cpp index 9429de217..5b62467e8 100644 --- a/src/administration/punishments.cpp +++ b/src/administration/punishments.cpp @@ -163,6 +163,17 @@ bool SetFreeze(CharData *ch, CharData *vict, char *reason, long times) { if (IsPunishCannotBeApplied(ch, vict, pundata, reason)) { return false; } + // Заморозка и разморозка -- только старший имм. Проверка стоит здесь, а не в самих + // командах, потому что сюда сходятся все пять путей: "заморозить"/"freeze", + // "unfreeze", "set <чар> frozen", "set all frozen" и снятие из do_unfreeze. + // Уровень из таблицы команд для иммортальских команд не смотрится вовсе + // (privilege.cpp:129 -- проверка уровня работает только при minimum_level < + // kLvlImmortal), поэтому до сих пор заморозить мог любой бог с флагом FullAccess, + // а kLvlFreeze в structs.h ни на что не влиял. + if (!privilege::IsOwner(ch) && GetRealLevel(ch) < kLvlImplementator) { + SendMsgToChar("Замораживать и размораживать может только старший бог.\r\n", ch); + return false; + } if (times == 0) { ClearPundata(pundata); if (!vict->IsFlagged(EPlrFlag::kFrozen)) {