b5ffe0e9d7
Вендор заменил сетевой слой на свой Netty-обработчик, поля задержки в нём нет, а сам класс в маппингах не восстановлен. Ванильный getLag() не достать, и игра пинг нигде не показывает. Остаётся то, что есть всегда: сервер шлёт keep-alive раз в 15 секунд по своему собственному расписанию. Отклонение интервала прихода - это и есть сеть, и скользящее среднее по нему даёт оценку на любом сервере. Грубые интервалы (потерянный пакет удваивает интервал) в среднее не попадают. Число помечается как оценка: Rsx.pingExact() false, в строке "ping~". Эхо со своим nonce в имени канала осталось в коде, но в этой сборке обработчик кастомного payload у клиента не найден, поэтому профиль его не объявляет и эхо просто недоступно - точность пока такая, какая есть. Период keep-alive читается из -Drsx.keepalivePeriod: прокси иногда шлют иначе, и стенду нужен короткий, чтобы проверить математику за секунды. Заодно: Resolver игнорировал "принудительный" скан и отдавал устаревший индекс замет позапрошенных классов. HUD-гейт читался в первый кадр и не находил экран. Стенд кормитkeep-alive с интервалом 240 мс при периоде 200 и ждёт оценку около 50 мс - ровно то отклонение, которое он и создал.
97 lines
3.8 KiB
Java
97 lines
3.8 KiB
Java
// Drives the fake client the way the game would, so the bridge can be tested
|
|
// end to end: bring the client up, hand the mods to the vendor loader, then tick.
|
|
//
|
|
// The mod jars are NOT loaded here - the agent finds them in build/testrun/mods
|
|
// and feeds them to ilxq one by one, exactly as it does in the game. The last
|
|
// one loaded is the only one whose getRunnableList() the vendor keeps, so the
|
|
// first two only work if the bridge really has a single shared drain.
|
|
//
|
|
// The HUD part mimics the one path that matters: the compass widget renders, and
|
|
// only while the HUD screen's gate is open. Toggling the gate is what the game's
|
|
// own hide key does, so the test can check the panel follows it.
|
|
|
|
public class FakeMain {
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
System.out.println("[fake] class loader: " + FakeMain.class.getClassLoader());
|
|
System.out.println("[fake] joml.fastmath = " + System.getProperty("joml.fastmath"));
|
|
|
|
wwk client = new wwk();
|
|
wwk.WA = client;
|
|
ddvqd player = new ddvqd("Steve", 35789);
|
|
player.g = 10.5;
|
|
player.F = 64.0;
|
|
player.a = -3.25;
|
|
client.zb = player;
|
|
oisywi world = new oisywi();
|
|
world.isRemoteFlag = true;
|
|
world.time = 1000L;
|
|
client.ta = world;
|
|
client.S = null;
|
|
client.Zb = "TIMER";
|
|
client.jC = "RENDER";
|
|
client.pC = new pvdafug("http://snoop.minecraft.net/report");
|
|
System.out.println("[fake] client up, telemetry scheduled");
|
|
|
|
// ---- the latency estimate, from the server's keep-alive cadence.
|
|
//
|
|
// The server keeps a 15 s cadence measured on its own clock, so the
|
|
// deviation of the arrival interval is the network's. The stand compress
|
|
// that into milliseconds; what matters is that a constant offset shows
|
|
// up in the estimate.
|
|
cxaddrz play = new cxaddrz();
|
|
System.out.println("[fake] feeding keep-alive arrivals, 240 ms apart, period 200");
|
|
for (int i = 0; i < 6; i++) {
|
|
Thread.sleep(240);
|
|
play.onKeepAlive(new Object());
|
|
}
|
|
System.out.println("[fake] keep-alives fed");
|
|
Thread.sleep(2500);
|
|
System.out.println("[fake] ticking 8 times");
|
|
for (int i = 0; i < 8; i++) {
|
|
if (i == 2) {
|
|
client.S = new bsh();
|
|
System.out.println("[fake] opened a screen");
|
|
}
|
|
if (i == 4) {
|
|
client.S = null;
|
|
System.out.println("[fake] closed the screen");
|
|
}
|
|
client.tick();
|
|
Thread.sleep(200);
|
|
}
|
|
|
|
// ---- the HUD, drawn by the compass widget the way the game draws it
|
|
fakecompass compass = new fakecompass();
|
|
fakectx ctx = new fakectx();
|
|
fakescreen screen = fakescreen.SINGLE;
|
|
|
|
System.out.println("[fake] HUD visible for 3 frames");
|
|
for (int i = 0; i < 3; i++) {
|
|
fakebatch.reset();
|
|
if (!screen.isHidden()) {
|
|
compass.render(ctx);
|
|
}
|
|
System.out.println("[fake] frame " + i + " commands=" + fakebatch.DRAWN.size()
|
|
+ (fakebatch.DRAWN.isEmpty() ? ""
|
|
: " first=" + fakebatch.DRAWN.get(0)
|
|
+ " last=" + fakebatch.DRAWN.get(
|
|
fakebatch.DRAWN.size() - 1)));
|
|
}
|
|
|
|
System.out.println("[fake] HUD hidden (what F3 does) for 3 frames");
|
|
screen.setHidden(true);
|
|
for (int i = 0; i < 3; i++) {
|
|
fakebatch.reset();
|
|
if (!screen.isHidden()) {
|
|
compass.render(ctx);
|
|
}
|
|
System.out.println("[fake] frame " + i + " commands=" + fakebatch.DRAWN.size());
|
|
}
|
|
screen.setHidden(false);
|
|
|
|
|
|
System.out.println("[fake] done");
|
|
}
|
|
}
|