// HandleFC handles incoming requests of packet 0xFC: EncryptionKeyResponse func HandleFC(server *Server, sender *player.Player) { pkt := new(packet.EncryptionKeyResponse) pkt.ReadFrom(sender.Conn) // Decrypt shared secret and token with server's private key. var secret, token []byte // var err error secret, _ = rsa.DecryptPKCS1v15(rand.Reader, server.PrivateKey(), pkt.Secret) token, _ = rsa.DecryptPKCS1v15(rand.Reader, server.PrivateKey(), pkt.Token) // Ensure token matches if !bytes.Equal(token, sender.Token) { log.Println("Tokens don't match.") r := &packet.Disconnect{Reason: ReasonPiratedGame} r.WriteTo(sender.Conn) return } // Ensure player is legit if !server.CheckUser(sender.Name, secret) { log.Println("Failed to verify username!") r := packet.Disconnect{"Failed to verify username!"} r.WriteTo(sender.Conn) return } // Send empty EncryptionKeyResponse r := new(packet.EncryptionKeyResponse) r.WriteTo(sender.Conn) // Start AES/CFB8 stream encryption sender.OnlineMode(true, secret) log.Println("Enabling encryption.") }
// HandleFF handles incoming requests of packet 0xFF: Disconnect func HandleFF(server *Server, sender *player.Player) { pkt := new(packet.Disconnect) pkt.ReadFrom(sender.Conn) log.Printf("Player %q exit. Reason: %s", sender.Name, pkt.Reason) // Send message to all other players msg := fmt.Sprintf("%s disconnected.", sender.Name) server.BroadcastMessage(msg) }
// HandleCD handles incoming requests of packet 0xCD: ClientStatuses func HandleCD(server *Server, sender *player.Player) { pkt := new(packet.ClientStatuses) pkt.ReadFrom(sender.Conn) switch pkt.Payload { case 0: server.HandleLogin(sender) case 1: default: log.Println("Weird packet 0xCB payload:", pkt.Payload) r := packet.Disconnect{"Weird packet 0xCB payload"} r.WriteTo(sender.Conn) } }
// HandleFE handles incoming requests of packet 0xFE: ServerListPing func HandleFE(server *Server, sender *player.Player) { pkt := new(packet.ServerListPing) pkt.ReadFrom(sender.Conn) if pkt.Magic != 1 { s := "Invalid %#x packet. Field Magic should be 1, got %d." reason := fmt.Sprintf(s, pkt.Id(), pkt.Magic) resp := packet.Disconnect{reason} resp.WriteTo(sender.Conn) return } in := fmt.Sprintf("%d", server.Players.Len()) max := server.config.Get("server.max_players") resp := ping.Ping(ping.Prepare(server.Motd, in, max)) resp.WriteTo(sender.Conn) }