From ad4efeb8c2a033137249eaba1042469adcd75fa2 Mon Sep 17 00:00:00 2001 From: dozens Date: Tue, 28 Dec 2021 09:38:41 -0700 Subject: [PATCH] hello world - add readme - make an echo server --- docs/README.md | 46 +++++++++++++++++++++++++++++++ docs/learning.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 62 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 docs/README.md create mode 100644 docs/learning.md create mode 100644 main.go diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..ee45a8e --- /dev/null +++ b/docs/README.md @@ -0,0 +1,46 @@ +# gomud + +multi-user dungeon engine written in go + +## motivation + +- learn go +- make something super fun + +## current status + +- echo server + +## game features + +- text based rpg +- it's super fun + +## application features + +- auth (TLS?): user, password, characters +- connect via telnet or netcat +- persistance (database) + +## entities + +- characters/heroes + - level (experience) + - stats + - skills (not classes?) + - ancestry (not races) +- items + - weapons (wieldable) + - armour (wearable) +- npcs + - monsters + - friendlies +- environment +- rooms +- quests + +## roadmap + +- scriptable: should be able to create content in game +- exploration to scale: wilderness map +- websocket support diff --git a/docs/learning.md b/docs/learning.md new file mode 100644 index 0000000..cb27bdb --- /dev/null +++ b/docs/learning.md @@ -0,0 +1,70 @@ +# learning + +stuff we learned along the way + +## 2021-12-28 + +Stuff i learned about go + + +- `:=` short assignment, infers type: `x := 4`. vs "long" assignment: `var x int; x = 4` +- expressive ifs: declare, assign, evaluate + + ``` + if x := isBar(); x > 10 { + println("big number") + } else { + println("it's kind of small") + } + ``` + +- `defer` wrapup (e.g. `conn.Close()`) +- data structures are array (fixed), slice (variable), and channel +- mulitiple returns. common convention: + + ``` + foo, err := bar() + if err != nil { + return err + } + ``` +- pointers 😬 +- use `make` to make arrays, slices, channels +- `for` is the only loop. +- structs and interfaces. here's a pair type: + + ``` + type pair struct { + x, y int + } + ``` + + and here's a toString interface: + + ``` + type Stringer interface { + toString() string + } + ``` + + and here's adding a method to a struct to implement the interface: + + ``` + func(p pair) toString() string { + return fmt.Sprintf("(%d, %d)", p.x, p.y) + } + ``` + + and here's using the compiler to check the interface: + + ``` + var p Stringer = pair{3, 4} + ``` + +resources + +- https://learnxinyminutes.com/docs/go/ +- https://www.youtube.com/watch?v=Eb1Q98PmyLQ +- https://www.youtube.com/watch?v=oyKrI8e1-9U&t +- https://pkg.go.dev/net/http +- https://github.com/josa42/coc-go diff --git a/main.go b/main.go new file mode 100644 index 0000000..66f113f --- /dev/null +++ b/main.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + "log" + "net" +) + +func handleConnection(conn net.Conn) error { + buff := make([]byte, 4096) + defer conn.Close() + + welcome := "=== Hola, Wikipedia! ===" + conn.Write([]byte(welcome + "\n")) + + for { + if n, err := conn.Read(buff); err != nil { + return err + } else if n == 0 { + log.Println("Zero bytes, connection closed") + break + } else { + msg := buff[0 : n-2] // trim "\r\n" + log.Print(fmt.Sprintf("msg: %s", msg)) + + resp := fmt.Sprintf("You said: \"%s\"\r\n", msg) + if n, err := conn.Write([]byte(resp)); err != nil { + return err + } else if n == 0 { + log.Println("zero bytes, closing connection") + break + } + } + } + return nil +} + +func startSever() error { + if ln, err := net.Listen("tcp", ":8008"); err != nil { + return err + } else { + for { + if conn, err := ln.Accept(); err != nil { + log.Printf("Error accepting connection", err) + continue + } else { + log.Println("New connection accepted") + go func() { + if err := handleConnection(conn); err != nil { + log.Println("Error handling connection", err) + } + }() + } + } + } +} + +func main() { + if err := startSever(); err != nil { + log.Fatal(err) + } +}