func (chunk *Chunk) reqInteractBlock(player gamerules.IPlayerClient, held gamerules.Slot, target *BlockXyz, againstFace Face) { // TODO use held item to better check of if the player is trying to place a // block vs. perform some other interaction (e.g hoeing dirt). This is // perhaps best solved by sending held item type and the face to // blockType.Aspect.Interact() blockInstance, blockType, ok := chunk.blockInstanceAndType(target) if !ok { return } if _, isBlockHeld := held.ItemTypeId.ToBlockId(); isBlockHeld && blockType.Attachable { // The player is interacting with a block that can be attached to. // Work out the position to put the block at. dx, dy, dz := againstFace.Dxyz() destLoc := target.AddXyz(dx, dy, dz) if destLoc == nil { // there is overflow with the translation, so do nothing return } player.PlaceHeldItem(*destLoc, held) } else { // Player is otherwise interacting with the block. blockType.Aspect.Interact(blockInstance, player) } return }
func cmdSay(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) { args := strings.Split(message, " ") if len(args) < 2 { player.EchoMessage(sayUsage) return } msg := strings.Join(args[1:], " ") cmdHandler.BroadcastMessage("§d" + msg) }
func cmdTell(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) { args := strings.Split(message, " ") if len(args) < 3 { player.EchoMessage(tellUsage) return } /* TODO Get player to send message, too player := args[1] message := strings.Join(args[2:], " ") */ player.EchoMessage(msgNotImplemented) }
func cmdTp(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) { args := strings.Split(message, " ") if len(args) < 3 { player.EchoMessage(tpUsage) return } teleportee := cmdHandler.PlayerByName(args[1]) destination := cmdHandler.PlayerByName(args[2]) if teleportee == nil { msg := fmt.Sprintf("'%s' is not logged in", args[1]) player.EchoMessage(msg) return } if destination == nil { msg := fmt.Sprintf("'%s' is not logged in", args[2]) player.EchoMessage(msg) return } pos, look := destination.PositionLook() // TODO: Remove this hack or figure out what needs to happen instead pos.Y += 1.63 teleportee.EchoMessage(fmt.Sprintf("Hold still! You are being teleported to %s", args[2])) msg := fmt.Sprintf("Teleporting %s to %s at (%.2f, %.2f, %.2f)", args[1], args[2], pos.X, pos.Y, pos.Z) log.Printf("Message: %s", msg) player.EchoMessage(msg) teleportee.SetPositionLook(pos, look) }
func (chunk *Chunk) reqTakeItem(player gamerules.IPlayerClient, entityId EntityId) { if entity, ok := chunk.entities[entityId]; ok { if item, ok := entity.(*gamerules.Item); ok { player.GiveItemAtPosition(*item.Position(), *item.GetSlot()) // Tell all subscribers to animate the item flying at the // player. buf := new(bytes.Buffer) proto.WriteItemCollect(buf, entityId, player.GetEntityId()) chunk.reqMulticastPlayers(-1, buf.Bytes()) chunk.removeEntity(item) } } }
func (chunk *Chunk) reqSubscribeChunk(entityId EntityId, player gamerules.IPlayerClient, notify bool) { if _, ok := chunk.subscribers[entityId]; ok { // Already subscribed. return } chunk.subscribers[entityId] = player // Transmit the chunk data to the new player. buf := new(bytes.Buffer) // chunk.shard.pktSerial.WritePacketsBuffer(buf, &proto.PacketPreChunk{ //@TODO 1.5.1 // ChunkLoc: chunk.loc, // Mode: ChunkInit, // }) player.TransmitPacket(buf.Bytes()) player.TransmitPacket(chunk.chunkPacket()) if notify { player.NotifyChunkLoad() } // Send spawn packets for all entities in the chunk to the player. if len(chunk.entities) > 0 { buf := new(bytes.Buffer) for _, entity := range chunk.entities { pkts := entity.SpawnPackets(nil) chunk.shard.pktSerial.WritePacketsBuffer(buf, pkts...) } player.TransmitPacket(buf.Bytes()) } // Spawn existing players for new player. if len(chunk.playersData) > 0 { buf := new(bytes.Buffer) for _, existing := range chunk.playersData { if existing.entityId != entityId { pkts := existing.SpawnPackets(nil) chunk.shard.pktSerial.WritePacketsBuffer(buf, pkts...) } } player.TransmitPacket(buf.Bytes()) } }
func (chunk *Chunk) reqSubscribeChunk(entityId EntityId, player gamerules.IPlayerClient, notify bool) { if _, ok := chunk.subscribers[entityId]; ok { // Already subscribed. return } chunk.subscribers[entityId] = player buf := new(bytes.Buffer) proto.WritePreChunk(buf, &chunk.loc, ChunkInit) player.TransmitPacket(buf.Bytes()) player.TransmitPacket(chunk.chunkPacket()) if notify { player.NotifyChunkLoad() } // Send spawns packets for all entities in the chunk. if len(chunk.entities) > 0 { buf := new(bytes.Buffer) for _, e := range chunk.entities { e.SendSpawn(buf) } player.TransmitPacket(buf.Bytes()) } // Spawn existing players for new player. if len(chunk.playersData) > 0 { playersPacket := new(bytes.Buffer) for _, existing := range chunk.playersData { if existing.entityId != entityId { existing.sendSpawn(playersPacket) } } player.TransmitPacket(playersPacket.Bytes()) } }
func cmdKill(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) { // TODO inflict damage to player player.EchoMessage(msgNotImplemented) }
func cmdGive(player gamerules.IPlayerClient, message string, cmdHandler gamerules.IGame) { args := strings.Split(message, " ") if len(args) < 3 || len(args) > 5 { player.EchoMessage(giveUsage) return } args = args[1:] // Check to make sure this is a valid player name (at the moment command // is being run, the player may log off before command completes). target := cmdHandler.PlayerByName(args[0]) if target == nil { msg := fmt.Sprintf("'%s' is not logged in", args[0]) player.EchoMessage(msg) return } itemNum, err := strconv.Atoi(args[1]) itemType, ok := cmdHandler.ItemTypeById(itemNum) if err != nil || !ok { msg := fmt.Sprintf("'%s' is not a valid item id", args[1]) player.EchoMessage(msg) return } quantity := 1 if len(args) >= 3 { quantity, err = strconv.Atoi(args[2]) if err != nil { player.EchoMessage(giveUsage) return } if quantity > 512 { msg := "Cannot give more than 512 items at once" player.EchoMessage(msg) return } } data := 0 if len(args) >= 4 { data, err = strconv.Atoi(args[2]) if err != nil { player.EchoMessage(giveUsage) return } } // Perform the actual give msg := fmt.Sprintf("Giving %d of '%s' to %s", quantity, itemType.Name, args[0]) player.EchoMessage(msg) maxStack := int(itemType.MaxStack) for quantity > 0 { count := quantity if count > maxStack { count = maxStack } item := gamerules.Slot{ ItemTypeId: itemType.Id, Count: ItemCount(count), Data: ItemData(data), } target.GiveItem(item) quantity -= count } if player != target { msg = fmt.Sprintf("%s gave you %d of '%s'", player, quantity, itemType.Name) target.EchoMessage(msg) } }
func cmdHelp(player gamerules.IPlayerClient, message string, cmdFramework *CommandFramework, cmdHandler gamerules.IGame) { args := strings.Split(message, " ") if len(args) > 2 { player.EchoMessage(helpUsage) return } cmds := cmdFramework.Commands() if len(args) == 2 { cmd := args[1] if command, ok := cmds[cmd]; ok { player.EchoMessage("Command: " + cmdFramework.Prefix() + command.Trigger) player.EchoMessage("Usage: " + command.Usage) player.EchoMessage("Description: " + command.Description) return } player.EchoMessage(msgUnknownCommand) return } var resp string if len(cmds) == 0 { resp = "No commands available." } else { resp = "Commands:" for trigger, _ := range cmds { resp += " " + trigger + "," } resp = resp[:len(resp)-1] } player.EchoMessage(resp) }