func (player *Player) PacketWindowClick(windowId WindowId, slotId SlotId, rightClick bool, txId TxId, shiftClick bool, expectedSlot *proto.WindowSlot) { player.lock.Lock() defer player.lock.Unlock() // Note that the expectedSlot parameter is currently ignored. The item(s) // involved are worked out from the server-side data. // TODO use the expectedSlot as a conditions for the click, and base the // transaction result on that. // Determine which inventory window is involved. // TODO support for more windows var clickedWindow window.IWindow if windowId == WindowIdInventory { clickedWindow = &player.inventory } else if player.curWindow != nil && player.curWindow.WindowId() == windowId { clickedWindow = player.curWindow } else { log.Printf( "Warning: ignored window click on unknown window ID %d", windowId) } expectedSlotContent := &gamerules.Slot{ ItemTypeId: expectedSlot.ItemTypeId, Count: expectedSlot.Count, Data: expectedSlot.Data, } // The client tends to send item IDs even when the count is zero. expectedSlotContent.Normalize() txState := TxStateRejected click := gamerules.Click{ SlotId: slotId, Cursor: player.cursor, RightClick: rightClick, ShiftClick: shiftClick, TxId: txId, } click.ExpectedSlot.SetWindowSlot(expectedSlot) if clickedWindow != nil { txState = clickedWindow.Click(&click) } switch txState { case TxStateAccepted, TxStateRejected: // Inform client of operation status. buf := new(bytes.Buffer) proto.WriteWindowTransaction(buf, windowId, txId, txState == TxStateAccepted) player.cursor = click.Cursor player.cursor.SendUpdate(buf, WindowIdCursor, SlotIdCursor) player.TransmitPacket(buf.Bytes()) case TxStateDeferred: // The remote inventory should send the transaction outcome. } }
func (player *Player) handlePacketWindowClick(pkt *proto.PacketWindowClick) { // Note that the expectedSlot parameter is currently ignored. The item(s) // involved are worked out from the server-side data. // TODO use the expectedSlot as a conditions for the click, and base the // transaction result on that. // Determine which inventory window is involved. // TODO support for more windows var clickedWindow window.IWindow if pkt.WindowId == WindowIdInventory { clickedWindow = &player.inventory } else if player.curWindow != nil && player.curWindow.WindowId() == pkt.WindowId { clickedWindow = player.curWindow } else { log.Printf( "Warning: ignored window click on unknown window ID %d", pkt.WindowId) } txState := TxStateRejected click := gamerules.Click{ SlotId: pkt.Slot, Cursor: player.cursor, RightClick: pkt.RightClick == 1, ShiftClick: pkt.Mode == 1, TxId: pkt.TxId, } //click.ExpectedSlot.SetItemSlot(&pkt.ExpectedSlot) @TODO 1.5.1 if clickedWindow != nil { txState = clickedWindow.Click(&click) } switch txState { case TxStateAccepted, TxStateRejected: // Inform client of operation status. data := player.txPktSerial.SerializePackets(&proto.PacketWindowTransaction{pkt.WindowId, pkt.TxId, txState == TxStateAccepted}) player.TransmitPacket(data) case TxStateDeferred: // The remote inventory should send the transaction outcome. } }