Skip to content

Commit

Permalink
feat: Implement chat (#66)
Browse files Browse the repository at this point in the history
Players can now use the chat to send messages to each other.
  • Loading branch information
meyfa authored Apr 16, 2024
1 parent 2adba28 commit f32f1f9
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The following features are already working:
- [X] player inventory (limited to creative mode)
- [X] breaking and placing blocks
- [X] multiplayer
- [ ] chat
- [X] chat
- [ ] persisting data across restarts

## How-to
Expand Down
12 changes: 9 additions & 3 deletions src/packets/add-player.cob
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ LINKAGE SECTION.
PROCEDURE DIVISION USING BY REFERENCE LK-HNDL LK-ERRNO LK-ENTITY-ID LK-USERNAME LK-USERNAME-LEN.
MOVE 0 TO PAYLOADLEN

*> TODO: initialize chat, game mode, ping, display name(, skin?)
*> TODO: game mode, ping, display name(, skin?)

*> actions mask=(add player + update listed)
MOVE X"09" TO PAYLOAD(PAYLOADLEN + 1:1)
*> actions mask=(add player + initialize chat + update listed)
MOVE X"0B" TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN

*> number of players
Expand Down Expand Up @@ -59,6 +59,12 @@ PROCEDURE DIVISION USING BY REFERENCE LK-HNDL LK-ERRNO LK-ENTITY-ID LK-USERNAME

*> properties (omitted)

*> --- action: initialize chat ---

*> has signature data: false - hence no other fields in this section
MOVE X"00" TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN

*> --- action: update listed ---

*> listed=true
Expand Down
105 changes: 105 additions & 0 deletions src/packets/player-chat.cob
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. SendPacket-PlayerChat.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 PACKET-ID BINARY-LONG VALUE 55.
*> temporary data used during encoding
01 UINT16 BINARY-SHORT UNSIGNED.
01 INT32 BINARY-LONG.
01 INT64 BINARY-LONG-LONG.
01 BUFFER PIC X(8).
01 BUFFERLEN BINARY-LONG UNSIGNED.
*> buffer used to store the packet data
01 PAYLOAD PIC X(64000).
01 PAYLOADLEN BINARY-LONG UNSIGNED.
LINKAGE SECTION.
01 LK-HNDL PIC X(4).
01 LK-ERRNO PIC 9(3).
01 LK-SENDER-ID BINARY-LONG UNSIGNED.
01 LK-SENDER-NAME PIC X(16).
01 LK-MESSAGE PIC X(256).
01 LK-MESSAGE-LEN BINARY-LONG UNSIGNED.

PROCEDURE DIVISION USING BY REFERENCE LK-HNDL LK-ERRNO LK-SENDER-ID LK-SENDER-NAME LK-MESSAGE LK-MESSAGE-LEN.
MOVE 0 TO PAYLOADLEN

*> --- header ---

*> sender UUID
*> TODO: use a proper UUID, not the entity ID
MOVE X"000000000000" TO PAYLOAD(PAYLOADLEN + 1:12)
ADD 12 TO PAYLOADLEN
CALL "Encode-Int" USING LK-SENDER-ID BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN

*> index
MOVE 0 TO INT32
CALL "Encode-VarInt" USING INT32 BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN

*> message signature present
MOVE X"00" TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN

*> --- body ---

*> message
CALL "Encode-VarInt" USING LK-MESSAGE-LEN BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN
MOVE LK-MESSAGE(1:LK-MESSAGE-LEN) TO PAYLOAD(PAYLOADLEN + 1:LK-MESSAGE-LEN)
ADD LK-MESSAGE-LEN TO PAYLOADLEN

*> signature timestamp and salt
MOVE X"00000000000000000000000000000000" TO PAYLOAD(PAYLOADLEN + 1:16)
ADD 16 TO PAYLOADLEN

*> --- previous messages ---

*> total previous messages
MOVE 0 TO INT32
CALL "Encode-VarInt" USING INT32 BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN

*> --- other ---

*> unsigned content present
MOVE X"00" TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN

*> filter type enum (0: not filtered)
MOVE X"00" TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN

*> --- chat formatting ---

*> chat type
*> TODO: This is a reference to the "minecraft:chat_type" registry. Get the correct value from the registry.
MOVE X"00" TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN

*> sender name (NBT string tag)
MOVE X"08" TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN
COMPUTE UINT16 = FUNCTION STORED-CHAR-LENGTH(LK-SENDER-NAME)
CALL "Encode-Short" USING UINT16 BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN
*> TODO: implement modified UTF-8: https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8
MOVE LK-SENDER-NAME(1:UINT16) TO PAYLOAD(PAYLOADLEN + 1:UINT16)
ADD UINT16 TO PAYLOADLEN

*> has target name
MOVE X"00" TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN

*> Send the packet
CALL "SendPacket" USING LK-HNDL PACKET-ID PAYLOAD PAYLOADLEN LK-ERRNO

GOBACK.

END PROGRAM SendPacket-PlayerChat.
20 changes: 20 additions & 0 deletions src/server.cob
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,26 @@ HandlePlay SECTION.
IF TEMP-INT32 > TELEPORT-RECV(CLIENT-ID) AND TEMP-INT32 <= TELEPORT-SENT(CLIENT-ID)
MOVE TEMP-INT32 TO TELEPORT-RECV(CLIENT-ID)
END-IF
*> Chat message
WHEN 5
CALL "Decode-String" USING PACKET-BUFFER(CLIENT-ID) PACKET-POSITION BYTE-COUNT BUFFER
*> Message may not be longer than 256 characters
IF BYTE-COUNT > 256
PERFORM DisconnectClient
EXIT SECTION
END-IF
*> display the message in the server console
DISPLAY "<" USERNAME(CLIENT-PLAYER(CLIENT-ID))(1:USERNAME-LENGTH(CLIENT-PLAYER(CLIENT-ID))) "> " BUFFER(1:BYTE-COUNT)
*> send the message to all clients in play state
MOVE CLIENT-ID TO TEMP-INT16
MOVE CLIENT-PLAYER(CLIENT-ID) TO TEMP-INT32
PERFORM VARYING CLIENT-ID FROM 1 BY 1 UNTIL CLIENT-ID > MAX-CLIENTS
IF CLIENT-PRESENT(CLIENT-ID) = 1 AND CLIENT-STATE(CLIENT-ID) = 4
CALL "SendPacket-PlayerChat" USING CLIENT-HNDL(CLIENT-ID) ERRNO TEMP-INT32 USERNAME(TEMP-INT32) BUFFER BYTE-COUNT
PERFORM HandleClientError
END-IF
END-PERFORM
MOVE TEMP-INT16 TO CLIENT-ID
*> KeepAlive response
WHEN 21
CALL "Decode-Long" USING PACKET-BUFFER(CLIENT-ID) PACKET-POSITION KEEPALIVE-RECV(CLIENT-ID)
Expand Down

0 comments on commit f32f1f9

Please sign in to comment.