Skip to content

Commit aba11e5

Browse files
committed
✨ Add the new code of conduct packet
1 parent 45a3707 commit aba11e5

7 files changed

Lines changed: 235 additions & 5 deletions

File tree

api/src/main/java/net/transferproxy/api/network/connection/PlayerConnection.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,19 @@ default void transfer(final @NotNull String host) {
7676
*/
7777
void sendStatusResponse(final @NotNull StatusResponse response);
7878

79+
/**
80+
* Sends the code of conduct to the client.
81+
* @param codeOfConduct The code of conduct to send.
82+
* @return A CompletableFuture that will be completed when the code of conduct has been accepted by the client.
83+
* @throws IllegalStateException if the code of conduct has already been sent and not yet accepted.
84+
*/
85+
@NotNull CompletableFuture<Void> sendCodeOfConduct(final @NotNull String codeOfConduct);
86+
87+
/**
88+
* Triggers the acceptance of the code of conduct.
89+
*/
90+
void triggerAcceptCodeOfConduct();
91+
7992
/**
8093
* Fetches a client-stored cookie using a {@link Key} reference.
8194
*

core/src/main/java/net/transferproxy/network/connection/PlayerConnectionImpl.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@
5757
import org.slf4j.LoggerFactory;
5858

5959
import java.net.SocketException;
60-
import java.util.*;
60+
import java.util.Collections;
61+
import java.util.Map;
62+
import java.util.Objects;
63+
import java.util.UUID;
6164
import java.util.concurrent.CompletableFuture;
6265
import java.util.concurrent.ConcurrentHashMap;
6366

@@ -82,6 +85,9 @@ public class PlayerConnectionImpl extends SimpleChannelInboundHandler<Serverboun
8285
private volatile boolean fromTransfer;
8386
private String brand;
8487

88+
private final Object codeOfConductLock = new Object();
89+
private CompletableFuture<Void> codeOfConductFuture;
90+
8591
public PlayerConnectionImpl(final @NotNull Channel channel) {
8692
this.channel = Objects.requireNonNull(channel, "channel must not be null");
8793
}
@@ -116,6 +122,33 @@ public void sendStatusResponse(final @NotNull StatusResponse response) {
116122
this.sendPacket(new StatusResponsePacket(response));
117123
}
118124

125+
@Override
126+
public @NotNull CompletableFuture<Void> sendCodeOfConduct(final @NotNull String codeOfConduct) {
127+
final CompletableFuture<Void> future = new CompletableFuture<>();
128+
synchronized (this.codeOfConductLock) {
129+
if (this.codeOfConductFuture != null) {
130+
throw new IllegalStateException("Code of conduct already sent");
131+
}
132+
this.codeOfConductFuture = future;
133+
}
134+
this.sendPacket(new CodeOfConductPacket(codeOfConduct));
135+
return future;
136+
}
137+
138+
@Override
139+
public void triggerAcceptCodeOfConduct() {
140+
final CompletableFuture<Void> future;
141+
synchronized (this.codeOfConductLock) {
142+
future = this.codeOfConductFuture;
143+
if (future != null) {
144+
this.codeOfConductFuture = null;
145+
}
146+
}
147+
if (future != null) {
148+
future.complete(null);
149+
}
150+
}
151+
119152
@Override
120153
public synchronized @NotNull CompletableFuture<byte[]> fetchCookie(final @NotNull String cookieKey) {
121154
Objects.requireNonNull(cookieKey, "Cookie key must not be null");
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2025 Yvan Mazy
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.transferproxy.network.packet.config.clientbound;
26+
27+
import io.netty.buffer.ByteBuf;
28+
import net.transferproxy.api.network.packet.Packet;
29+
import net.transferproxy.api.network.protocol.Protocolized;
30+
import org.jetbrains.annotations.NotNull;
31+
32+
import static net.transferproxy.util.BufUtil.readString;
33+
import static net.transferproxy.util.BufUtil.writeString;
34+
35+
public record CodeOfConductPacket(String codeOfConduct) implements Packet {
36+
37+
public CodeOfConductPacket(final @NotNull ByteBuf buf) {
38+
this(readString(buf));
39+
}
40+
41+
@Override
42+
public void write(final @NotNull Protocolized protocolized, final @NotNull ByteBuf buf) {
43+
writeString(buf, this.codeOfConduct);
44+
}
45+
46+
@Override
47+
public int getId() {
48+
return 0x13;
49+
}
50+
51+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2025 Yvan Mazy
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.transferproxy.network.packet.config.serverbound;
26+
27+
import io.netty.buffer.ByteBuf;
28+
import net.transferproxy.api.network.connection.PlayerConnection;
29+
import net.transferproxy.api.network.packet.serverbound.ServerboundPacket;
30+
import net.transferproxy.api.network.protocol.Protocolized;
31+
import org.jetbrains.annotations.NotNull;
32+
33+
public record AcceptCodeOfConductPacket() implements ServerboundPacket {
34+
35+
public AcceptCodeOfConductPacket(final @SuppressWarnings("unused") @NotNull ByteBuf buf) {
36+
this();
37+
}
38+
39+
@Override
40+
public void handle(final @NotNull PlayerConnection connection) {
41+
connection.triggerAcceptCodeOfConduct();
42+
}
43+
44+
@Override
45+
public void write(final @NotNull Protocolized protocolized, final @NotNull ByteBuf buf) {
46+
// nothing to write
47+
}
48+
49+
@Override
50+
public int getId() {
51+
return 0x09;
52+
}
53+
54+
}

core/src/main/java/net/transferproxy/network/packet/provider/impl/LatestPacketProviderGroup.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@
3030
import net.transferproxy.network.packet.config.FinishConfigurationPacket;
3131
import net.transferproxy.network.packet.config.KeepAlivePacket;
3232
import net.transferproxy.network.packet.config.PluginMessagePacket;
33-
import net.transferproxy.network.packet.config.serverbound.ClientInformationPacket;
34-
import net.transferproxy.network.packet.config.serverbound.ClientSelectKnownPacksPacket;
35-
import net.transferproxy.network.packet.config.serverbound.ConfigCookieResponsePacket;
36-
import net.transferproxy.network.packet.config.serverbound.ResourcePackResponsePacket;
33+
import net.transferproxy.network.packet.config.serverbound.*;
3734
import net.transferproxy.network.packet.handshake.HandshakePacket;
3835
import net.transferproxy.network.packet.login.serverbound.LoginAcknowledgedPacket;
3936
import net.transferproxy.network.packet.login.serverbound.LoginCookieResponsePacket;
@@ -62,6 +59,8 @@ public class LatestPacketProviderGroup implements PacketProviderGroup {
6259
.putNull() // Pong packet
6360
.putOnlyBuffer(ResourcePackResponsePacket::new)
6461
.putOnlyBuffer(ClientSelectKnownPacksPacket::from)
62+
.putNull() // Custom Click Action packet
63+
.putOnlyBuffer(AcceptCodeOfConductPacket::new)
6564
.build();
6665
// @formatter:on
6766

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2025 Yvan Mazy
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.transferproxy.network.packet.config.clientbound;
26+
27+
import net.transferproxy.network.packet.PacketTestBase;
28+
import org.junit.jupiter.api.Test;
29+
30+
class CodeOfConductPacketTest extends PacketTestBase {
31+
32+
@Test
33+
void testWriteReadConsistency() {
34+
this.testOnlyBuffer(new CodeOfConductPacket("My code of conduct"), CodeOfConductPacket::new);
35+
this.testOnlyBuffer(new CodeOfConductPacket("a".repeat(Short.MAX_VALUE)), CodeOfConductPacket::new);
36+
}
37+
38+
@Test
39+
void testWriteTooLongCodeOfConduct() {
40+
this.testFailOnlyBuffer(new CodeOfConductPacket("a".repeat(Short.MAX_VALUE + 1)), CodeOfConductPacket::new);
41+
}
42+
43+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2025 Yvan Mazy
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.transferproxy.network.packet.config.serverbound;
26+
27+
import net.transferproxy.network.packet.PacketTestBase;
28+
import org.junit.jupiter.api.Test;
29+
30+
class AcceptCodeOfConductPacketTest extends PacketTestBase {
31+
32+
@Test
33+
void testWriteReadConsistency() {
34+
this.testOnlyBuffer(new AcceptCodeOfConductPacket(), AcceptCodeOfConductPacket::new);
35+
}
36+
37+
}

0 commit comments

Comments
 (0)