Я вижу решение, близкое к желаемому.
Сначала, при старте клиентского интерфейса, выполняется несколько (навскидку - может, и 10 достаточно, а, может, и 100 потребуется, следует определить экспериментально) передач с клиента на сервер, причём используется тот же протокол, который будет впоследствии использован для передачи информации о нажатии, и в каждой передаче в том числе передаётся точное время клиента (с максимально доступной точностью). Приходящие пакеты маркируются точным штампом времени получения (серверное время), с максимально доступной точностью. Полученный массив обрабатывается статистически, и определяется разница точного времени часов клиента и сервера и погрешность этого определения. Если статистическая ошибка велика, процесс повторяется.
Далее, уже в момент нажатия, по той же технологии передаётся пакет с точным клиентским временем нажатия, и по подсчитанной ранее разности определяется точное время нажатия по времени сервера. Для всех клиентов это время сравнивается, и победителем объявляется тот, у кого время нажатия по серверу минимальное.
Такой алгоритм (практически) не зависит от колебания времени доставки пакета от клиента серверу.
Калибровка разности времени при необходимости может повторяться. Частота рекалибровки зависит достижимой точности определения локального и серверного времени и от требуемой точности вычисления разности. По моим очень приблизительным прикидкам, если требуемая точность составляет 100 мс, то рекалибровку следует проводить ежечасно.
Если после 2-3 повторений калибровки установить точное значение разности не удалось - клиенту следует отказать в участии.