@@ -18,12 +18,14 @@ import (
1818 "github.com/fatih/color"
1919)
2020
21- // ErrSuccessfullyHandledMOTDRequest means the Minecraft client requested for MOTD
22- // and has been correctly handled by program. This used to skip the data forward
23- // process and directly go to the end of this connection.
24- var ErrSuccessfullyHandledMOTDRequest = errors .New ("" )
25-
26- var ErrRejectedLogin = ErrSuccessfullyHandledMOTDRequest // don't cry baby
21+ var (
22+ // ErrSuccessfullyHandledMOTDRequest means the Minecraft client requested for MOTD
23+ // and has been correctly handled by program. This used to skip the data forward
24+ // process and directly go to the end of this connection.
25+ ErrSuccessfullyHandledMOTDRequest = errors .New ("" )
26+ ErrRejectedLogin = ErrSuccessfullyHandledMOTDRequest // don't cry baby
27+ ErrBadPlayerName = ErrSuccessfullyHandledMOTDRequest
28+ )
2729
2830func badPacketPanicRecover (s * config.ConfigProxyService ) {
2931 // Non-Minecraft packet which uses `go-mc` packet scan method may cause panic.
@@ -147,23 +149,35 @@ func NewConnHandler(s *config.ConfigProxyService,
147149 // else: login
148150
149151 // Server bound : Login Start
150- // This packet shall be at most 1+mcprotocol.MaxVarIntLen+16+1+16=39 bytes long.
151- // 1 stands for packet ID.
152- // mcprotocol.MaxVarIntLen stands for player name length.
153- // 16 stands for the maximum length of a valid player name.
154- // 1 stands for boolean which decides whether the UUID will be sent.
155- // 16 stands for optional UUID length.
152+ // We only read its packet length and the player name, ignoring the rest part.
153+ // Unread part would be sent to target during the copy stage.
154+ // The reason for doing this is that this packet format has been modified many times in the history
155+ // and it would take a lot of code to make it all compatible. So why not just forward it?
156156 // Get player name and check the profile
157157 buffer .Reset (mcprotocol .MaxVarIntLen )
158- err = conn . ReadLimitedPacket ( buffer , 1 + mcprotocol .MaxVarIntLen + 16 + 1 + 16 )
158+ loginStartLen , _ , err := mcprotocol .ReadVarIntFrom ( c )
159159 if err != nil {
160160 return nil , err
161161 }
162- var playerName string
163- err = mcprotocol .Scan (buffer , & packetID , & playerName )
162+ _ , _ , err = mcprotocol .ReadVarIntFrom (c ) // skip packet ID
164163 if err != nil {
165164 return nil , err
166165 }
166+ var playerName string
167+ {
168+ playerNameLen , _ , err := mcprotocol .ReadVarIntFrom (c )
169+ if err != nil {
170+ return nil , err
171+ }
172+ if playerNameLen > 16 || playerNameLen <= 0 {
173+ return nil , ErrBadPlayerName
174+ }
175+ _ , err = buffer .ReadFullFrom (c , int (playerNameLen ))
176+ if err != nil {
177+ return nil , err
178+ }
179+ playerName = string (buffer .Bytes ())
180+ }
167181
168182 if s .Minecraft .OnlineCount .EnableMaxLimit && s .Minecraft .OnlineCount .Max <= int (options .OnlineCount .Load ()) {
169183 log .Printf ("Service %s : %s Rejected a new Minecraft player login request due to online player number limit: %s" , s .Name , ctx .ColoredID , playerName )
@@ -293,7 +307,8 @@ func NewConnHandler(s *config.ConfigProxyService,
293307 if err != nil {
294308 return nil , err
295309 }
296- err = remoteMC .WritePacket (buffer )
310+ mcprotocol .AppendPacketLength (buffer , int (loginStartLen ))
311+ _ , err = remote .Write (buffer .Bytes ())
297312 if err != nil {
298313 return nil , err
299314 }
0 commit comments