Чат и список игроков
- Протокол: Chat (что сказал сервер), ChatSend (что сказал клиент) и PlayerList (весь список игроков с их режимами). - Сервер: сообщения уходят всем, а имя отправителя ставит сервер, поэтому подделать его нельзя. Список игроков уходит всем целиком, когда он меняется. Команды сервера: /help и /players. - Клиент: перевод наших пакетов в игровые (SPacketChat и SPacketPlayerListItem), уходящий чат перехватывается патчем, список игроков обновляется по разнице (ушедших убираем, пришедших добавляем). - Тесты: два игрока, один пишет - второй слышит с правильным именем; список игроков приходит обоим и меняется, когда кто-то выходит. Попутно: run-server.ps1 теперь знает про rsx-plugin-api, иначе сервер не запускался (нет класса Hitboxes в classpath). Тесты: протокол 34, сервер 87. Форк собирается чисто.
This commit is contained in:
@@ -161,6 +161,15 @@ public final class Packets {
|
||||
/** The client hits something. */
|
||||
public static final int ATTACK = 0x2D;
|
||||
|
||||
/** What somebody said. */
|
||||
public static final int CHAT = 0x2E;
|
||||
|
||||
/** The client says something. */
|
||||
public static final int CHAT_SEND = 0x2F;
|
||||
|
||||
/** Who is in the world. */
|
||||
public static final int PLAYER_LIST = 0x30;
|
||||
|
||||
/**
|
||||
* One slot of the inventory and what is in it now.
|
||||
*
|
||||
@@ -1604,6 +1613,100 @@ public final class Packets {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* What somebody said.
|
||||
*
|
||||
* The name of the sender is here, because the server is the one who
|
||||
* decides who said what: a client cannot claim to be somebody else.
|
||||
*/
|
||||
public static final class Chat implements Packet {
|
||||
|
||||
/** The name of the sender, or empty when the server speaks. */
|
||||
public final String from;
|
||||
|
||||
public final String text;
|
||||
|
||||
public Chat(String from, String text) {
|
||||
this.from = from == null ? "" : from;
|
||||
this.text = text == null ? "" : text;
|
||||
}
|
||||
|
||||
public Buf write() {
|
||||
Buf buf = new Buf(64 + this.text.length());
|
||||
buf.writeString(this.from);
|
||||
buf.writeString(this.text);
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static Chat read(Buf in) {
|
||||
return new Chat(in.readString(MAX_TEXT), in.readString(MAX_TEXT));
|
||||
}
|
||||
}
|
||||
|
||||
/** The client says something. */
|
||||
public static final class ChatSend implements Packet {
|
||||
|
||||
public final String text;
|
||||
|
||||
public ChatSend(String text) {
|
||||
this.text = text == null ? "" : text;
|
||||
}
|
||||
|
||||
public Buf write() {
|
||||
Buf buf = new Buf(64 + this.text.length());
|
||||
buf.writeString(this.text);
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static ChatSend read(Buf in) {
|
||||
return new ChatSend(in.readString(MAX_TEXT));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Who is in the world.
|
||||
*
|
||||
* The whole list, every time it changes: the list of a server with a
|
||||
* handful of players is small, and a full list cannot get out of step
|
||||
* with itself the way a difference can.
|
||||
*/
|
||||
public static final class PlayerList implements Packet {
|
||||
|
||||
public final String[] names;
|
||||
|
||||
/** The game mode of each player, in the same order. */
|
||||
public final int[] gameModes;
|
||||
|
||||
public PlayerList(String[] names, int[] gameModes) {
|
||||
this.names = names;
|
||||
this.gameModes = gameModes;
|
||||
}
|
||||
|
||||
public Buf write() {
|
||||
Buf buf = new Buf(32 + this.names.length * 24);
|
||||
buf.writeVarInt(this.names.length);
|
||||
for (int i = 0; i < this.names.length; i++) {
|
||||
buf.writeString(this.names[i]);
|
||||
buf.writeVarInt(i < this.gameModes.length ? this.gameModes[i] : 0);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static PlayerList read(Buf in) {
|
||||
int count = in.readVarInt();
|
||||
if (count < 0 || count > 4096) {
|
||||
throw new ProtocolException("that many players is not real");
|
||||
}
|
||||
String[] names = new String[count];
|
||||
int[] gameModes = new int[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
names[i] = in.readString(MAX_TEXT);
|
||||
gameModes[i] = in.readVarInt();
|
||||
}
|
||||
return new PlayerList(names, gameModes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Every packet id this build knows, and what it decodes into.
|
||||
*
|
||||
@@ -1648,6 +1751,9 @@ public final class Packets {
|
||||
map.put(Integer.valueOf(HITBOX_INSTANCES), "HitboxInstances");
|
||||
map.put(Integer.valueOf(HITBOXES_RELOAD), "HitboxesReload");
|
||||
map.put(Integer.valueOf(ATTACK), "Attack");
|
||||
map.put(Integer.valueOf(CHAT), "Chat");
|
||||
map.put(Integer.valueOf(CHAT_SEND), "ChatSend");
|
||||
map.put(Integer.valueOf(PLAYER_LIST), "PlayerList");
|
||||
map.put(Integer.valueOf(DISCONNECT), "Disconnect");
|
||||
return map;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user