8.7 KiB
8.7 KiB
Журнал ревью
Сводка: ../reviewed.md. Индекс среза: README.md.
Срез 8. Сессия и темп
- Фазы: 38–40
- Проверен на:
1c3ae9a, 2026-08-20 - Пути:
src/HSchool.Server/{Session,Api/SessionEndpoints.cs,Api/SchoolAccess.cs,Game/SchoolOwnership.cs,Game/UserStore.cs,Net/ClientRegistry.cs,Net/GameSocketHandler.cs,Game/GameLoopService.cs},src/HSchool.Simulation/{ClockSpeed.cs,GameClock.cs,School.cs,SimulationOptions.cs},src/HSchool.Client/src/{ui/sessionGate.ts,ui/mainMenu.ts,ui/gameScreen.ts,ui/schoolCard.ts,net/protocol.ts,net/api.ts,main.ts},docs/protocol.md,../../design/08-session/session.md,tests/HSchool.AppHost.Tests/{SessionApiTests.cs,SchoolOwnerApiTests.cs,GameSocketTests.cs},tests/HSchool.Simulation.Tests/{ClockTempoTests.cs,GameClockTests.cs},src/HSchool.Client/src/ui/{sessionGate,gameScreen,schoolCard,mainMenu}.test.ts - Итог: обещания 38–40 на месте; дописано 4 теста; вторая вкладка с той же кукой больше не получает Welcome. Срез 9 (44/45/47) в работе — не ревьюился
Что подтверждено:
- 38:
HSchool:AlphaPassword(пустой —ValidateOnStart);POST/GET/DELETE /api/session; кука HttpOnly,SameSite=Lax,Path=/,Max-AgeизSessionCookieDays(14);users.jsonканоническое имя; повтор другим регистром — та же запись; игровой HTTP без куки —401;/healthи три ручки сессии — без неё; сокет без куки — closePolicyViolation, без Welcome; Hello по-прежнему версия + локаль; клиент — сначала сессия, потом сокет; хостовые тесты логинятся вResetAsync/LoginAsync. Версия протокола не бампилась (v8). - 39:
MaxSchools= 2 на игрока,MaxSchoolsTotal= 16 (в AppHost-тестах Total = 7); create пишетowner;limit-reachedв коде —school-limit-reached(как вprotocol.md);server-full;GET /api/schools—schools/others,mine,ownerилиnull; Welcome.MaxSchools— слоты игрока; гость: найм403not-owner,SetRunningне меняетrunning; бесхозная вothers, удаляется вторым; меню «Мои»/«Чужие»; в чужой школе нет «Управление» и кнопок часов. Портретный POST безRequireManage. Формат сейва не бампился. - 40: база 1 игровая минута/с; таблица
0.5, 1, 2, 5, 10вClockSpeed,protocol.tsиprotocol.md; 20 импульсов ×1 = 1 минута, индексы 3/4 = 5 и 10 минут; на ×10 тяжёлые 10 раз с квантом 1; на ×5 — 5 раз; индекс 5 игнорируется; воркер по-прежнему 20 Гц и потолок догона 5; пять кнопок на экране.HSchool.Simulationбез ASP.NET.
Дописано:
SessionApiTests.Login_SetsHttpOnlyLaxSessionCookieSessionApiTests.SecondWebSocket_ForAnOnlineName_ClosesWithoutWelcomeClockTempoTests.AtX5_TwentyImpulses_RunHeavyFiveTimesAndAdvanceFiveGameMinutes(и календарь +1 на ×1 вAtX1_…)mainMenu.test.ts— чужая карточка без удаления, бесхозная с удалением
Исправлено:
- Второй WebSocket того же имени принимался и слал Welcome:
POSTпроверял «онлайн», upgrade — нет. Две вкладки с живой кукой обходили409name-online. ТеперьClientRegistry.TryClaimUserNameпод тем же замком, второй сокет закрываетсяPolicyViolationбез Welcome.
Открыто:
POST /api/sessionс другим именем при живой куке перезаписывает сессию безDELETE. Дизайн: «Без выхода второе имя с той же куки не взять». Кода ошибки нет — новый HTTP-код молча не вводился.AddDataProtection()без ключей рядом сsaves/. Рестарт того же профиля Windows куки, скорее всего, не сбрасывает; новый контейнер — может.- Текст фазы 39 пишет
limit-reached; живой код иprotocol.md—school-limit-reached(так было до среза). Не менялось. - Бесхозная карточка показывает «Хозяин: —», не голый прочерк.
GET /api/schools/{id}из дизайна нет:mine/ownerживут в списке меню.
Перепроверка. Срез 8. Сессия и темп
- Фазы: 38–40
- Проверен на:
7100065, 2026-08-20 - Пути:
src/HSchool.Server/{Session,Api/SessionEndpoints.cs,Api/SchoolAccess.cs,Game/SchoolOwnership.cs,Game/UserStore.cs,Game/SchoolStore.cs,Net/ClientRegistry.cs,Net/GameSocketHandler.cs,Game/GameLoopService.cs},src/HSchool.Simulation/{ClockSpeed.cs,GameClock.cs,School.cs,SimulationOptions.cs},src/HSchool.Client/src/{ui/sessionGate.ts,ui/mainMenu.ts,ui/gameScreen.ts,ui/schoolCard.ts,net/protocol.ts,net/api.ts,main.ts},docs/protocol.md,../../design/08-session/session.md,tests/HSchool.AppHost.Tests/{SessionApiTests.cs,SchoolOwnerApiTests.cs,GameSocketTests.cs},tests/HSchool.Simulation.Tests/{ClockTempoTests.cs,GameClockTests.cs},tests/HSchool.Server.Tests/SchoolStoreTests.cs,src/HSchool.Client/src/ui/{sessionGate,gameScreen,schoolCard,mainMenu}.test.ts - Итог: перепроверка после дрейфа с
1c3ae9a. Обещания 38–40 держатся;users.jsonбольше не читается как сейв школы; бесхозная карточка показывает голый прочерк. Следующий срез не брался.
Что подтверждено:
- Дрейф после
1c3ae9a:UserStore.FileNameоткрыт дляSchoolStore.LoadAll(пропускusers.json);GameLoopService/School.Tickполучили речь и talk-circle на страйде тяжёлых систем. Сессия, хозяин, таблица скоростей иTryClaimUserNameне разъехались. - Все тесты из списков фаз 38–40 на месте: сессия 401/200,
users.jsonи регистр,name-online, сокет без куки и второй сокетPolicyViolation, клиентский пароль без сетки; два игрока по две школы /server-full/ гость 403 иSetRunning/ бесхозная вothers; ×1 = 1 минута, индексы 3/4, страйд ×5/×10, индекс 5, пять кнопок. - Протокол на проводе сейчас v9 (срез 9, talk-circle); раскладка Hello/Welcome/
SetSpeedи смыслMaxSchoolsне менялись.HSchool.Simulationбез ASP.NET. Воркер 20 Гц, потолок догона 5.
Дописано:
ClockTempoTests.LowSpeed_EveryImpulseRunsHeavySystems— ×½ и ×2 каждый импульс, не только ×1schoolCard.test.ts— бесхозная карточка с голым прочерком, не «Хозяин: —»
Исправлено:
- Бесхозная карточка оборачивала «—» в шаблон «Хозяин: {owner}». Меню теперь отдаёт уже готовую подпись: чужая — «Хозяин: Bob», бесхозная — «—».
Открыто:
POST /api/sessionс другим именем при живой куке перезаписывает сессию безDELETE. Дизайн: «Без выхода второе имя с той же куки не взять». Кода ошибки нет — новый HTTP-код молча не вводился.AddDataProtection()без ключей рядом сsaves/. Рестарт того же профиля Windows куки, скорее всего, не сбрасывает; новый контейнер — может.- Текст фазы 39 пишет
limit-reached; живой код иprotocol.md—school-limit-reached(так было до среза). Не менялось. GET /api/schools/{id}из дизайна нет:mine/ownerживут в списке меню (schoolFromList).