Opik
Новичок
Синхронизация действий
Задача: написать скрипт, позволющий двум или более игрокам драться друг против друга в онлайн игре.
Используется БД mySQL для хранения серий ударов.
1 размен ударами между игроками (далее 1 ход) - 1 игрок ударяет второго, а второй в свою очередь бьет первого.
Механизм работы скрипта:
1) Получаем всех игроков противоложной команды.
2) Получаем тех, кого я уже бил (есть записи в БД и удар помечен как неотвеченный)
3) Из тех, кого получили в п. 1 убираем тех, кто в п.2, т.е получаем тех. кого нужно ударить.
4) Выбираем рандомно 1 игрока. Показываем форму удара.
Механизм удара:
Если пришли POST данные
1) Проверяем, действительно ли игрок ударяет своего соперника.
2) Проверяем, бил ли игрок уже этого соперника, если да, то ничего не делаем с этим. просто заного идет вышеописанный алгоритм , нет - п. 2.а
а) Проверяем, бил ли игрока соперник (его удар в режиме ожидания.) Если бил - п. 2.б), если нет - п.2.в
б) По формулам вычитаем силу удара, разные приемы и так далее. одним словом - завершаем удар и помечаем его как завершенный.
в) заносим в базу новый, неотвеченный удар.
3) и так далее пока не выиграет 1 команда.
Из-за повышенной нагрузки на сервер и замедлении времени выполнения скрипт периодически появляется проблема:
В базе оказывается 2 записи:
1) Игрок ударил соперника (незавершенный)
2) Соперника ударил игрока (незавершенный)
Если посмотреть алгоримт боев. то видно, что игрок уже не сможет ударить своего соперника. и наоборот. идет таймаут в бою (что бы не игроки специально не затягивали бои)
и в итоге плачевные результаты.
Предполагаемая ошибка:
Скрипты выполняются дольше среднего. Игрок начал бить соперника. в это же время соперник начал бить игрока.
У обоих прошли обе проверки. (т.к на тот момент ударов ещё не было в базе) и добавилось 2 неотвеченных удара.
Вариант решения:
Если пришли ПОСТ данные, блокировать таблицу на чтение, завершать все действия, разблокировать таблицу и так далее. Проблема будет решена.
НО таким образом доступ к таблице будет однопоточный. т.е всем придеться ждать разблокировки таблицы. что в целом неприемлимо.
Собсвенно сейчас в недоумении что делать. есть ли альтернативы блокировки таблицы? или может изменить логику скрипта, если да, то как?
Задача: написать скрипт, позволющий двум или более игрокам драться друг против друга в онлайн игре.
Используется БД mySQL для хранения серий ударов.
1 размен ударами между игроками (далее 1 ход) - 1 игрок ударяет второго, а второй в свою очередь бьет первого.
Механизм работы скрипта:
1) Получаем всех игроков противоложной команды.
2) Получаем тех, кого я уже бил (есть записи в БД и удар помечен как неотвеченный)
3) Из тех, кого получили в п. 1 убираем тех, кто в п.2, т.е получаем тех. кого нужно ударить.
4) Выбираем рандомно 1 игрока. Показываем форму удара.
Механизм удара:
Если пришли POST данные
1) Проверяем, действительно ли игрок ударяет своего соперника.
2) Проверяем, бил ли игрок уже этого соперника, если да, то ничего не делаем с этим. просто заного идет вышеописанный алгоритм , нет - п. 2.а
а) Проверяем, бил ли игрока соперник (его удар в режиме ожидания.) Если бил - п. 2.б), если нет - п.2.в
б) По формулам вычитаем силу удара, разные приемы и так далее. одним словом - завершаем удар и помечаем его как завершенный.
в) заносим в базу новый, неотвеченный удар.
3) и так далее пока не выиграет 1 команда.
Из-за повышенной нагрузки на сервер и замедлении времени выполнения скрипт периодически появляется проблема:
В базе оказывается 2 записи:
1) Игрок ударил соперника (незавершенный)
2) Соперника ударил игрока (незавершенный)
Если посмотреть алгоримт боев. то видно, что игрок уже не сможет ударить своего соперника. и наоборот. идет таймаут в бою (что бы не игроки специально не затягивали бои)
и в итоге плачевные результаты.
Предполагаемая ошибка:
Скрипты выполняются дольше среднего. Игрок начал бить соперника. в это же время соперник начал бить игрока.
У обоих прошли обе проверки. (т.к на тот момент ударов ещё не было в базе) и добавилось 2 неотвеченных удара.
Вариант решения:
Если пришли ПОСТ данные, блокировать таблицу на чтение, завершать все действия, разблокировать таблицу и так далее. Проблема будет решена.
НО таким образом доступ к таблице будет однопоточный. т.е всем придеться ждать разблокировки таблицы. что в целом неприемлимо.
Собсвенно сейчас в недоумении что делать. есть ли альтернативы блокировки таблицы? или может изменить логику скрипта, если да, то как?