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}