a geicko-2 based round robin ranking system designed to test c++ battleship submissions battleship.dunkirk.sh
1//go:build windows 2// +build windows 3 4package coninput 5 6import ( 7 "fmt" 8 "syscall" 9 "unsafe" 10 11 "golang.org/x/sys/windows" 12) 13 14var ( 15 modkernel32 = windows.NewLazySystemDLL("kernel32.dll") 16 procReadConsoleInputW = modkernel32.NewProc("ReadConsoleInputW") 17 procPeekConsoleInputW = modkernel32.NewProc("PeekConsoleInputW") 18 procGetNumberOfConsoleInputEvents = modkernel32.NewProc("GetNumberOfConsoleInputEvents") 19 procFlushConsoleInputBuffer = modkernel32.NewProc("FlushConsoleInputBuffer") 20) 21 22// NewStdinHandle is a shortcut for windows.GetStdHandle(windows.STD_INPUT_HANDLE). 23func NewStdinHandle() (windows.Handle, error) { 24 return windows.GetStdHandle(windows.STD_INPUT_HANDLE) 25} 26 27// WinReadConsoleInput is a thin wrapper around the Windows console API function 28// ReadConsoleInput (see 29// https://docs.microsoft.com/en-us/windows/console/readconsoleinput). In most 30// cases it is more practical to either use ReadConsoleInput or 31// ReadNConsoleInputs. 32func WinReadConsoleInput(consoleInput windows.Handle, buffer *InputRecord, 33 length uint32, numberOfEventsRead *uint32) error { 34 r, _, e := syscall.Syscall6(procReadConsoleInputW.Addr(), 4, 35 uintptr(consoleInput), uintptr(unsafe.Pointer(buffer)), uintptr(length), 36 uintptr(unsafe.Pointer(numberOfEventsRead)), 0, 0) 37 if r == 0 { 38 return error(e) 39 } 40 41 return nil 42} 43 44// ReadNConsoleInputs is a wrapper around ReadConsoleInput (see 45// https://docs.microsoft.com/en-us/windows/console/readconsoleinput) that 46// automates the event buffer allocation in oder to provide io.Reader-like 47// sematics. maxEvents must be greater than zero. 48func ReadNConsoleInputs(console windows.Handle, maxEvents uint32) ([]InputRecord, error) { 49 if maxEvents == 0 { 50 return nil, fmt.Errorf("maxEvents cannot be zero") 51 } 52 53 var inputRecords = make([]InputRecord, maxEvents) 54 n, err := ReadConsoleInput(console, inputRecords) 55 56 return inputRecords[:n], err 57} 58 59// ReadConsoleInput provides an ideomatic interface to the Windows console API 60// function ReadConsoleInput (see 61// https://docs.microsoft.com/en-us/windows/console/readconsoleinput). The size 62// of inputRecords must be greater than zero. 63func ReadConsoleInput(console windows.Handle, inputRecords []InputRecord) (uint32, error) { 64 if len(inputRecords) == 0 { 65 return 0, fmt.Errorf("size of input record buffer cannot be zero") 66 } 67 68 var read uint32 69 err := WinReadConsoleInput(console, &inputRecords[0], uint32(len(inputRecords)), &read) 70 71 return read, err 72} 73 74// WinPeekConsoleInput is a thin wrapper around the Windows console API function 75// PeekConsoleInput (see 76// https://docs.microsoft.com/en-us/windows/console/peekconsoleinput). In most 77// cases it is more practical to either use PeekConsoleInput or 78// PeekNConsoleInputs. 79func WinPeekConsoleInput(consoleInput windows.Handle, buffer *InputRecord, 80 length uint32, numberOfEventsRead *uint32) error { 81 r, _, e := syscall.Syscall6(procPeekConsoleInputW.Addr(), 4, 82 uintptr(consoleInput), uintptr(unsafe.Pointer(buffer)), uintptr(length), 83 uintptr(unsafe.Pointer(numberOfEventsRead)), 0, 0) 84 if r == 0 { 85 return error(e) 86 } 87 88 return nil 89 90} 91 92// PeekNConsoleInputs is a wrapper around PeekConsoleInput (see 93// https://docs.microsoft.com/en-us/windows/console/peekconsoleinput) that 94// automates the event buffer allocation in oder to provide io.Reader-like 95// sematics. maxEvents must be greater than zero. 96func PeekNConsoleInputs(console windows.Handle, maxEvents uint32) ([]InputRecord, error) { 97 if maxEvents == 0 { 98 return nil, fmt.Errorf("maxEvents cannot be zero") 99 } 100 101 var inputRecords = make([]InputRecord, maxEvents) 102 n, err := PeekConsoleInput(console, inputRecords) 103 104 return inputRecords[:n], err 105} 106 107// PeekConsoleInput provides an ideomatic interface to the Windows console API 108// function PeekConsoleInput (see 109// https://docs.microsoft.com/en-us/windows/console/peekconsoleinput). The size 110// of inputRecords must be greater than zero. 111func PeekConsoleInput(console windows.Handle, inputRecords []InputRecord) (uint32, error) { 112 if len(inputRecords) == 0 { 113 return 0, fmt.Errorf("size of input record buffer cannot be zero") 114 } 115 116 var read uint32 117 118 err := WinPeekConsoleInput(console, &inputRecords[0], uint32(len(inputRecords)), &read) 119 120 return read, err 121} 122 123// WinGetNumberOfConsoleInputEvents provides an ideomatic interface to the 124// Windows console API function GetNumberOfConsoleInputEvents (see 125// https://docs.microsoft.com/en-us/windows/console/getnumberofconsoleinputevents). 126func WinGetNumberOfConsoleInputEvents(consoleInput windows.Handle, numberOfEvents *uint32) error { 127 r, _, e := syscall.Syscall6(procGetNumberOfConsoleInputEvents.Addr(), 2, 128 uintptr(consoleInput), uintptr(unsafe.Pointer(numberOfEvents)), 0, 129 0, 0, 0) 130 if r == 0 { 131 return error(e) 132 } 133 134 return nil 135} 136 137// GetNumberOfConsoleInputEvents provides an ideomatic interface to the Windows 138// console API function GetNumberOfConsoleInputEvents (see 139// https://docs.microsoft.com/en-us/windows/console/getnumberofconsoleinputevents). 140func GetNumberOfConsoleInputEvents(console windows.Handle) (uint32, error) { 141 var nEvents uint32 142 err := WinGetNumberOfConsoleInputEvents(console, &nEvents) 143 144 return nEvents, err 145} 146 147func FlushConsoleInputBuffer(consoleInput windows.Handle) error { 148 r, _, e := syscall.Syscall(procFlushConsoleInputBuffer.Addr(), 1, uintptr(consoleInput), 0, 0) 149 if r == 0 { 150 return error(e) 151 } 152 153 return nil 154}