This repository has been archived on 2026-10-17. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
rsx-modloader/bridge/src/main/java/rsx/EchoPacket.java
T
SashegDev b5ffe0e9d7 Пинг и потери: считаем сами, потому что считать нечем
Вендор заменил сетевой слой на свой Netty-обработчик, поля задержки в нём нет,
а сам класс в маппингах не восстановлен. Ванильный getLag() не достать, и игра
пинг нигде не показывает.

Остаётся то, что есть всегда: сервер шлёт keep-alive раз в 15 секунд по своему
собственному расписанию. Отклонение интервала прихода - это и есть сеть, и
скользящее среднее по нему даёт оценку на любом сервере. Грубые интервалы
(потерянный пакет удваивает интервал) в среднее не попадают.

Число помечается как оценка: Rsx.pingExact() false, в строке "ping~". Эхо со
своим nonce в имени канала осталось в коде, но в этой сборке обработчик
кастомного payload у клиента не найден, поэтому профиль его не объявляет и эхо
просто недоступно - точность пока такая, какая есть.

Период keep-alive читается из -Drsx.keepalivePeriod: прокси иногда шлют иначе, и
стенду нужен короткий, чтобы проверить математику за секунды.

Заодно: Resolver игнорировал "принудительный" скан и отдавал устаревший индекс
замет позапрошенных классов. HUD-гейт читался в первый кадр и не находил экран.

Стенд кормитkeep-alive с интервалом 240 мс при периоде 200 и ждёт оценку около
50 мс - ровно то отклонение, которое он и создал.
2026-10-17 03:42:32 +03:00

68 lines
2.2 KiB
Java

package rsx;
/**
* Builds the echo packet.
*
* The nonce travels in the packet's channel name, so no payload buffer has to
* be built or parsed: a server that supports the mod echoes the channel back
* and the client recognises its own echo by the name.
*
* The packet class is vendor code with no stable name, so the profile has to
* carry it. When it does not, the echo is simply unavailable and the modloader
* falls back to the keep-alive estimate - which is why nothing here fails loudly
* on a build it does not recognise.
*/
public final class EchoPacket {
public static final String CHANNEL = "rsx_echo";
private EchoPacket() {
}
/**
* @return a packet carrying the nonce, or null when this build has no echo
*/
public static Object create(Object netHandlerPlayClient, int nonce) {
Profile p = Resolver.profile();
if (p == null) {
return null;
}
String[] ctor = p.member("rsx.net.echoPacket", "ctor");
if (ctor == null) {
return null;
}
try {
Class<?> cls = Resolver.findLoaded(p.obf("rsx.net.echoPacket"));
if (cls == null) {
return null;
}
Class<?> buffer = Resolver.findLoaded(
p.obf("rsx.net.echoBuffer"));
java.lang.reflect.Constructor<?> c = cls.getDeclaredConstructor(
String.class, buffer);
c.setAccessible(true);
return c.newInstance(CHANNEL + ":" + nonce, null);
} catch (Throwable t) {
return null;
}
}
/** The nonce from a channel name, or -1 when it is not ours. */
public static int nonceOf(String channel) {
if (channel == null || !channel.startsWith(CHANNEL + ":")) {
return -1;
}
try {
return Integer.parseInt(channel.substring(CHANNEL.length() + 1));
} catch (Throwable t) {
return -1;
}
}
/** True when this build can send an echo at all. */
public static boolean available() {
Profile p = Resolver.profile();
return p != null && p.member("rsx.net.echoPacket", "ctor") != null;
}
}