Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement player list ("tab list") #53

Merged
merged 1 commit into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/packets/add-player.cob
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. SendPacket-AddPlayer.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 PACKET-ID BINARY-LONG VALUE 60.
*> buffer used to store the packet data
01 PAYLOAD PIC X(1024).
01 PAYLOADLEN BINARY-LONG UNSIGNED.
*> temporary data
01 INT32 BINARY-LONG.
01 BUFFER PIC X(8).
01 BUFFERLEN BINARY-LONG UNSIGNED.
LINKAGE SECTION.
01 LK-HNDL PIC X(4).
01 LK-ERRNO PIC 9(3).
01 LK-ENTITY-ID BINARY-LONG.
01 LK-USERNAME PIC X(16).
01 LK-USERNAME-LEN BINARY-LONG UNSIGNED.

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?)

*> actions mask=(add player + update listed)
MOVE FUNCTION CHAR((1 + 8) + 1) TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN

*> number of players
*> TODO: support sending multiple players
MOVE 1 TO INT32
CALL "Encode-VarInt" USING INT32 BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN

*> player UUID
*> TODO: use a proper UUID
MOVE X"000000000000" TO PAYLOAD(PAYLOADLEN + 1:12)
ADD 12 TO PAYLOADLEN
CALL "Encode-Int" USING LK-ENTITY-ID BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN

*> --- action: add player ---

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

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

*> properties (omitted)

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

*> listed=true
MOVE FUNCTION CHAR(2) TO PAYLOAD(PAYLOADLEN + 1:1)
ADD 1 TO PAYLOADLEN

*> send packet
CALL "SendPacket" USING LK-HNDL PACKET-ID PAYLOAD PAYLOADLEN LK-ERRNO
GOBACK.

END PROGRAM SendPacket-AddPlayer.
13 changes: 6 additions & 7 deletions src/packets/login-play.cob
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@ WORKING-STORAGE SECTION.
LINKAGE SECTION.
01 LK-HNDL PIC X(4).
01 LK-ERRNO PIC 9(3).
01 LK-ENTITY-ID BINARY-LONG.

PROCEDURE DIVISION USING BY REFERENCE LK-HNDL LK-ERRNO.
PROCEDURE DIVISION USING BY REFERENCE LK-HNDL LK-ERRNO LK-ENTITY-ID.
MOVE 0 TO PAYLOADLEN

*> entity ID=0x00000001 (suffix of UUID)
PERFORM 4 TIMES
ADD 1 TO PAYLOADLEN
MOVE FUNCTION CHAR(1) TO PAYLOAD(PAYLOADLEN:1)
END-PERFORM
MOVE FUNCTION CHAR(2) TO PAYLOAD(PAYLOADLEN:1)
*> entity ID
CALL "Encode-Int" USING LK-ENTITY-ID BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN

*> is hardcore=false
ADD 1 TO PAYLOADLEN
Expand Down
41 changes: 41 additions & 0 deletions src/packets/remove-player.cob
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. SendPacket-RemovePlayer.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 PACKET-ID BINARY-LONG VALUE 59.
*> buffer used to store the packet data
01 PAYLOAD PIC X(1024).
01 PAYLOADLEN BINARY-LONG UNSIGNED.
*> temporary data
01 INT32 BINARY-LONG.
01 BUFFER PIC X(8).
01 BUFFERLEN BINARY-LONG UNSIGNED.
LINKAGE SECTION.
01 LK-HNDL PIC X(4).
01 LK-ERRNO PIC 9(3).
01 LK-ENTITY-ID BINARY-LONG.

PROCEDURE DIVISION USING BY REFERENCE LK-HNDL LK-ERRNO LK-ENTITY-ID.
MOVE 0 TO PAYLOADLEN

*> number of players
*> TODO: support sending multiple players
MOVE 1 TO INT32
CALL "Encode-VarInt" USING INT32 BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN

*> player UUID
*> TODO: use a proper UUID
MOVE X"000000000000" TO PAYLOAD(PAYLOADLEN + 1:12)
ADD 12 TO PAYLOADLEN
CALL "Encode-Int" USING LK-ENTITY-ID BUFFER BUFFERLEN
MOVE BUFFER(1:BUFFERLEN) TO PAYLOAD(PAYLOADLEN + 1:BUFFERLEN)
ADD BUFFERLEN TO PAYLOADLEN

*> send packet
CALL "SendPacket" USING LK-HNDL PACKET-ID PAYLOAD PAYLOADLEN LK-ERRNO
GOBACK.

END PROGRAM SendPacket-RemovePlayer.
45 changes: 41 additions & 4 deletions src/server.cob
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,13 @@ InsertClient SECTION.
DisconnectClient SECTION.
DISPLAY "Client " CLIENT-ID " disconnected"

*> Reset this early to avoid infinite loops in case of errors when sending packets to other clients
MOVE 0 TO CLIENT-PRESENT(CLIENT-ID)

CALL "Socket-Close" USING CLIENT-HNDL(CLIENT-ID) ERRNO
PERFORM HandleServerError

*> If the client was playing, send a leave message to all other clients
*> If the client was playing, send a leave message to all other clients, and remove the player from their world
IF CLIENT-STATE(CLIENT-ID) = 4
*> send "<username> left the game" to all clients in play state, except the current client
MOVE 0 TO BYTE-COUNT
Expand All @@ -226,9 +229,19 @@ DisconnectClient SECTION.
MOVE " left the game" TO BUFFER(BYTE-COUNT + 1:14)
ADD 14 TO BYTE-COUNT
PERFORM BroadcastMessageExceptCurrent

*> remove the player from the player list
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 AND CLIENT-ID NOT = TEMP-INT16
CALL "SendPacket-RemovePlayer" USING CLIENT-HNDL(CLIENT-ID) ERRNO TEMP-INT32
PERFORM HandleClientError
END-IF
END-PERFORM
MOVE TEMP-INT16 TO CLIENT-ID
END-IF

MOVE 0 TO CLIENT-PRESENT(CLIENT-ID)
MOVE X"00000000" TO CLIENT-HNDL(CLIENT-ID)
MOVE -1 TO CLIENT-STATE(CLIENT-ID)
MOVE 0 TO CONFIG-FINISH(CLIENT-ID)
Expand Down Expand Up @@ -543,8 +556,9 @@ HandleConfiguration SECTION.
DISPLAY " Acknowledged finish configuration"
ADD 1 TO CLIENT-STATE(CLIENT-ID)

*> send "Login (play)"
CALL "SendPacket-LoginPlay" USING CLIENT-HNDL(CLIENT-ID) ERRNO
*> send "Login (play)" with player index as entity ID
MOVE CLIENT-PLAYER(CLIENT-ID) TO TEMP-INT32
CALL "SendPacket-LoginPlay" USING CLIENT-HNDL(CLIENT-ID) ERRNO TEMP-INT32
IF ERRNO NOT = 0
PERFORM HandleClientError
EXIT SECTION
Expand Down Expand Up @@ -614,6 +628,18 @@ HandleConfiguration SECTION.
END-IF
END-PERFORM

*> send the player list (including the new player) to the new player
PERFORM VARYING TEMP-INT16 FROM 1 BY 1 UNTIL TEMP-INT16 > MAX-CLIENTS
IF CLIENT-PRESENT(TEMP-INT16) = 1 AND CLIENT-STATE(TEMP-INT16) = 4
MOVE CLIENT-PLAYER(TEMP-INT16) TO TEMP-INT32
CALL "SendPacket-AddPlayer" USING CLIENT-HNDL(CLIENT-ID) ERRNO TEMP-INT32 USERNAME(TEMP-INT32) USERNAME-LENGTH(TEMP-INT32)
IF ERRNO NOT = 0
PERFORM HandleClientError
EXIT SECTION
END-IF
END-IF
END-PERFORM

*> send position ("Synchronize Player Position")
CALL "SendPacket-SetPlayerPosition" USING CLIENT-HNDL(CLIENT-ID) ERRNO PLAYER-POSITION(CLIENT-PLAYER(CLIENT-ID)) PLAYER-ROTATION(CLIENT-PLAYER(CLIENT-ID))
IF ERRNO NOT = 0
Expand All @@ -623,6 +649,17 @@ HandleConfiguration SECTION.

*> TODO: receive "Confirm Teleportation"

*> send the new player to all other players
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 AND CLIENT-ID NOT = TEMP-INT16
CALL "SendPacket-AddPlayer" USING CLIENT-HNDL(CLIENT-ID) ERRNO TEMP-INT32 USERNAME(TEMP-INT32) USERNAME-LENGTH(TEMP-INT32)
PERFORM HandleClientError
END-IF
END-PERFORM
MOVE TEMP-INT16 TO CLIENT-ID

*> send "<username> joined the game" to all clients in play state, except the current client
*> TODO: factor this out and reuse for join and leave messages
MOVE 0 TO BYTE-COUNT
Expand Down