Skip to content

fix(punishments): restrict freeze and unfreeze to the senior god - #4199

Open
bylins wants to merge 1 commit into
masterfrom
fix/freeze-senior-imm-only
Open

bylins wants to merge 1 commit into
masterfrom
fix/freeze-senior-imm-only

Conversation

@bylins

@bylins bylins commented Nov 14, 2026

Copy link
Copy Markdown
Owner

Задача: заморозка — только старшему имму (34).

Почему одной правки уровня мало

В таблице команд стоит kLvlFreeze (structs.h:91), и он равен kLvlGreatGod, то есть 33. Но поднять его до 34 бесполезно: для иммортальских команд уровень не проверяется вообще.

// privilege.cpp:129
if (check_level && !mode && cmd_info[cmd_number].minimum_level < kLvlImmortal
    && GetRealLevel(ch) >= cmd_info[cmd_number].minimum_level) {
    return true;
}

Короткий путь по уровню работает только при minimum_level < kLvlImmortal. Для всего, что 31 и выше, решает privilege.xml: владелец, флаг FullAccess или команда в списке. Отсюда два следствия:

  • kLvlFreeze ни на что не влияет;
  • заморозить может любой бог с FullAccess, а их сейчас семеро.

Где поставлена проверка

Не в команде, а в punishments::SetFreeze, потому что туда сходятся все пять путей:

путь файл
заморозить / freeze do_wizutil.cpp:73
set <чар> frozen do_set.cpp:399, 409
set all frozen do_set_all.cpp:74, 92
снятие из unfreeze do_unfreeze.cpp:63

Одна проверка закрывает и заморозку, и разморозку: в SetFreeze они обе, times == 0 размораживает. Иначе бог 33-го смог бы снять то, что поставил 34-й.

if (!privilege::IsOwner(ch) && GetRealLevel(ch) < kLvlImplementator) {
    SendMsgToChar("Замораживать и размораживать может только старший бог.\r\n", ch);
    return false;
}

Все вызывающие уже умеют обрабатывать false.

Кого это затрагивает

Богов с FullAccess ниже 34-го уровня: они перестанут замораживать и размораживать. Владелец (проверяется по имени, privilege.cpp:63) и любой 34-й — могут.

Проверено

  • Сборка build/ (release, с тестами) без предупреждений.
  • ./tests/tests — 872 проходят, 3 отключены давно.

Замечено, не тронуто

kLvlFreeze в structs.h:91 теперь окончательно мёртвая константа. Удалять её в этом PR не стал — она ещё стоит в таблице команд и выпиливается отдельно.

🤖 Generated with Claude Code

Заморозка должна быть доступна только старшему имму (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 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant