// Handle0A handles incoming requests of packet 0x0A: Player func Handle0A(server *Server, sender *player.Player) { pkt := new(packet.Player) pkt.ReadFrom(sender.Conn) resp := &packet.Entity{sender.Id()} server.BroadcastPacket(resp) }
// Handle02 handles incoming requests of packet 0x02: Handshake func Handle02(server *Server, sender *player.Player) { pkt := new(packet.Handshake) pkt.ReadFrom(sender.Conn) log.Printf("Handshake from: %q [%s]", pkt.Username, sender.RemoteAddr()) if pkt.Version != constants.ProtoNum { log.Printf("Wrong Protocol version. Player: %d, Server: %d\n", pkt.Version, constants.ProtoNum) return } // Save player to list sender.Name = pkt.Username server.AddPlayer(sender) log.Println("online_mode =", server.config.Get("server.online_mode")) if server.config.Get("server.online_mode") == "true" { // Succesful handshake, prepare Encryption Request r := packet.EncryptionKeyRequest{ ServerId: server.Id(), PublicKey: server.PublicKey(), Token: auth.EncryptionBytes(), } r.WriteTo(sender.Conn) sender.Token = r.Token } else { // BUG(toqueteos): server: Add online_mode=false support. } }
// 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.") }
func (s *Server) HandleLogin(sender *player.Player) { var r packet.Packet r = &packet.LoginInfo{ Entity: 33, LevelType: "default", GameMode: 1, Dimension: 0, Difficulty: 2, MaxPlayers: 32, } r.WriteTo(sender.Conn) // BUG(toqueteos): Load nearby chunks for z := int32(-1); z < 2; z++ { for x := int32(-1); x < 2; x++ { VirtualChunks(x, z, 64).WriteTo(sender.Conn) } } const ( startX = 8.0 startY = 65.0 startZ = 8.0 ) // Client's spawn position r = &packet.SpawnPosition{X: int32(startX), Y: int32(startY), Z: int32(startZ)} r.WriteTo(sender.Conn) // Client Pos & Look r = &packet.PlayerPosLook{ startX, startY, startZ, // X, Y, Z startY + 1.6, // Stance 0.0, 0.0, // Yaw + Pitch true, // OnGround } r.WriteTo(sender.Conn) // Send nearby clients new client's info r = &packet.EntityNamedSpawn{ Entity: sender.Id(), Name: sender.Name, X: startX, Y: startY, Z: startZ, Yaw: 0.0, Pitch: 0.0, Item: 0, Metadata: player.JustLoginMetadata(sender.Name), } s.BroadcastPacket(r) // Instantiate all other users on new client s.BroadcastLogin(sender) // Save player to server list s.AddPlayer(sender) }
// Handle0C handles incoming requests of packet 0x0C: PlayerLook func Handle0C(server *Server, sender *player.Player) { pkt := new(packet.PlayerLook) pkt.ReadFrom(sender.Conn) resp := &packet.EntityLook{ Entity: sender.Id(), Yaw: pkt.Yaw, Pitch: pkt.Pitch, } server.BroadcastPacket(resp) }
// Handle0D handles incoming requests of packet 0x0D: PlayerPosLook func Handle0D(server *Server, sender *player.Player) { pkt := new(packet.PlayerPosLook) pkt.ReadFrom(sender.Conn) if pkt.Y > pkt.Stance { r := &packet.Disconnect{"Weird packet 0x0D. Server didn't switch Y with Stance."} r.WriteTo(sender.Conn) return } // Player is ready for broadcasts sender.SetReady() // Save position sender.SetPos(pkt.X, pkt.Y, pkt.Z) sender.SetLook(pkt.Pitch, pkt.Yaw) var p packet.Packet // BUG(toqueteos): NMS handle relative movements with other packet // `packet.EntityRelMove` right now we just teleport to the destination. p = &packet.EntityTeleport{ Entity: sender.Id(), X: pkt.X, Y: pkt.Y, Z: pkt.Z, Yaw: pkt.Yaw, Pitch: pkt.Pitch, } server.BroadcastPacket(p) p = &packet.EntityHeadLook{ Entity: sender.Id(), HeadYaw: pkt.Yaw, } server.BroadcastPacket(p) }
// Handle03 handles incoming requests of packet 0x03: ChatMessage func Handle03(server *Server, sender *player.Player) { pkt := new(packet.ChatMessage) pkt.ReadFrom(sender.Conn) log.Printf("ChatMessage: %+v", pkt) // Messages prefixed with / are treated like commands if strings.HasPrefix(pkt.Message, "/") { var parts = strings.Fields(pkt.Message[1:]) // Empty commands are noops. if len(parts) == 0 { return } var cmdName, cmdArgs = parts[0], parts[1:] var cmd cmd.Cmder var ok bool // Command not found if cmd, ok = server.Cmds[cmdName]; !ok { msg := fmt.Sprintf("Unknown command %q.", cmdName) log.Println(msg) sender.SendMessage(msg) return } ok = cmd.Do(sender, cmdArgs) if !ok { msg := "An error ocurred executing command %q." log.Println(msg) sender.SendMessage(msg) return } } // Send message to all other players msg := fmt.Sprintf("<%s> %s", sender.Name, pkt.Message) sender.BroadcastMessage(server.Players.Copy(), msg) }
// Kick kicks a player from the server func (s *Server) Kick(p *player.Player) { p.SendMessage("You were kicked from the server.") msg := fmt.Sprintf("Player %q was kicked from the server.", p.Name) s.BroadcastMessage(msg) }