use flags for cli parsing

This commit is contained in:
2026-05-29 19:40:37 +02:00
parent 1193386c47
commit 09f5802c03
2 changed files with 73 additions and 36 deletions
+64 -23
View File
@@ -1,23 +1,51 @@
package hanabi
import "core:flags"
import "core:fmt"
import "core:net"
import "core:os"
import "core:strconv"
import "core:strings"
USAGE :: `usage: hanabi (-c[onnect] <ip:port> | -h[ost] <ip:port> <n players>)
USAGE :: `usage: hanabi <COMMAND> [FLAGS]
note: n players has to be between 2-5
COMMAND can be one of the following, with args and FLAGS specified under:
* connect (c)
<ip:port> // server to connect to
* host (h)
<ip:port> // server to host on
<players> // between 2-5
--hints (-H) // number of hints (default=8)
--lives (-l) // number of lives (default=3). try 1 for instant death difficulty!
example host:
$ hanabi -h 127.0.0.1:42069 4
example:
host $ hanabi host 127.0.0.1:42069 2 --lives 1
player 1 $ hanabi connect 127.0.0.1:42069
player 2 $ hanabi connect 127.0.0.1:42069`
example player 1:
$ hanabi -c 127.0.0.1:42069
example player 2:
$ hanabi -c 127.0.0.1:42069`
Host_Args :: struct {
addr: net.Host_Or_Endpoint `args:"pos=0,required" usage:"ip:port to host on"`,
players: int `args:"pos=1,required" usage:"how many players (2-5)"`,
hints: int `usage:"number of hints (default=8)"`,
lives: int `usage:"number of lives (default=3). try 1 for instant death difficulty!"`,
}
Connect_Args :: struct {
addr: net.Host_Or_Endpoint `args:"pos=0,required" usage:"ip:port to connect to"`,
}
resolve_endpoint :: proc(addr: net.Host_Or_Endpoint) -> (endpoint: net.Endpoint) {
switch v in addr {
case net.Endpoint:
endpoint = v
case net.Host:
ep, err := net.resolve_ip4(v.hostname)
if err != nil do panic(fmt.tprintln("failed to resolve endpoint", err))
endpoint = ep
endpoint.port = v.port
}
return
}
main :: proc() {
ok := false
@@ -25,20 +53,33 @@ main :: proc() {
N := len(os.args) - 2
if N <= 0 do return
switch os.args[1] {
case "-c", "-connect", "--connect":
if N != 1 do return
addr, ok := net.parse_endpoint(os.args[2])
if !ok do panic(fmt.tprintln("failed to parse endpoint:", os.args[2]))
run_client(addr)
case "-h", "-host", "--host":
if N != 2 do return
addr, endpoint_ok := net.parse_endpoint(os.args[2])
if !endpoint_ok do panic(fmt.tprintln("failed to parse endpoint:", os.args[2]))
num_players, int_ok := strconv.parse_int(os.args[3])
if !int_ok do panic(fmt.tprintln("failed to parse number of players:", os.args[3]))
if num_players < 2 || num_players > 5 do return
run_server(addr, num_players)
// aliases
args: [dynamic]string
for a in os.args {
switch a {
case "-H":
append(&args, "--hints")
case "-l":
append(&args, "--lives")
case:
append(&args, a)
}
}
// COMMAND
switch strings.to_lower(args[1]) {
case "connect", "c":
c: Connect_Args
flags.parse(&c, args[2:], .Unix)
endpoint := resolve_endpoint(c.addr)
run_client(endpoint)
case "host", "h":
h: Host_Args
h.hints = 8
h.lives = 3
flags.parse(&h, args[2:], .Unix, strict = true)
endpoint := resolve_endpoint(h.addr)
run_server(endpoint, h.players, h.hints, h.lives)
case:
return
}
+9 -13
View File
@@ -15,6 +15,7 @@ create_comm_world :: proc(
w: Comm_World,
err: net.Network_Error,
) {
fmt.printfln("waiting for players (%d)...", num_conn)
for len(w.sockets) < num_conn {
client_sock, source := net.accept_tcp(listener) or_return
append(&w.sockets, client_sock)
@@ -57,27 +58,22 @@ send_payload :: proc(sock: net.TCP_Socket, pl: Payload) -> net.Network_Error {
return nil
}
// TODO: add cli input for these
DEFAULT_HINT_TOKENS :: 8
DEFAULT_LIVES :: 3
run_server :: proc(
listen_addr: net.Endpoint,
num_players: int,
num_hints := DEFAULT_HINT_TOKENS,
num_lives := DEFAULT_LIVES,
) {
run_server :: proc(listen_addr: net.Endpoint, num_players: int, num_hints: int, num_lives: int) {
listener, list_err := net.listen_tcp(listen_addr)
if list_err != nil do panic(fmt.tprintln("failed to listen:", net.to_string(listen_addr)))
defer net.close(listener)
fmt.println("creating game instance...")
fmt.println("number of players:", num_players)
fmt.println("number of hints:", num_hints)
fmt.println("number of lives:", num_lives)
g := create_game(num_hints, num_lives, num_players)
defer delete_game(&g)
w, comm_err := create_comm_world(listener, num_players)
if comm_err != nil do panic(fmt.tprintln("failed to create comm world:", comm_err))
defer delete_comm_world(&w)
g := create_game(num_hints, num_lives, num_players)
defer delete_game(&g)
current_player := rand.int_max(num_players)
GAME_LOOP: for {
for i in 0 ..< num_players {