diff gara/main.go @ 42:c2706ffb442b

[Gara] Peer to peer chat terminal app using go.
author MrJuneJune <me@mrjunejune.com>
date Mon, 01 Dec 2025 21:00:10 -0800
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gara/main.go	Mon Dec 01 21:00:10 2025 -0800
@@ -0,0 +1,139 @@
+package main
+
+import (
+  "fmt"
+  "bytes"
+  "net"
+)
+
+type Client struct {
+  name string
+  conn net.Conn
+  message []byte
+}
+
+var clients map[string]Client = make(map[string]Client)
+var allowedCharacters = map[byte]bool{
+    'a': true, 'b': true, 'c': true, 'd': true, 'e': true,
+    'f': true, 'g': true, 'h': true, 'i': true, 'j': true,
+    'k': true, 'l': true, 'm': true, 'n': true, 'o': true,
+    'p': true, 'q': true, 'r': true, 's': true, 't': true,
+    'u': true, 'v': true, 'w': true, 'x': true, 'y': true, 'z': true,
+    'A': true, 'B': true, 'C': true, 'D': true, 'E': true,
+    'F': true, 'G': true, 'H': true, 'I': true, 'J': true,
+    'K': true, 'L': true, 'M': true, 'N': true, 'O': true,
+    'P': true, 'Q': true, 'R': true, 'S': true, 'T': true,
+    'U': true, 'V': true, 'W': true, 'X': true, 'Y': true, 'Z': true,
+}
+
+func IsChacterAllowed(chars []byte) bool {
+  for _, b := range chars {
+    if !allowedCharacters[b] {
+      return false
+    }
+  }
+  return true
+}
+
+func ResetClient(client Client) {
+  ResetClientMessage(client)
+  delete(clients, client.conn.RemoteAddr().String())
+  client.conn.Close()
+}
+
+func ResetClientMessage(client Client) {
+  for i := range client.message {
+    client.message[i] = 0
+  }
+}
+
+func Loggers(value string) {
+  fmt.Println(value)
+}
+
+func SendString(client Client, value string) {
+  fmt.Println("Notifying User: ", client.name)
+  client.conn.Write(([]byte)(value+"\n"))
+}
+
+func SendToAll(currentClient Client) {
+  for key, client := range clients {
+    if currentClient.conn.RemoteAddr().String() == key {
+      continue
+    }
+    formattedMessage := fmt.Sprintf("%v: %v", currentClient.name, (string)(currentClient.message))
+    SendString(client, formattedMessage)
+  }
+}
+
+func HandleConnection(conn net.Conn) {
+  client := Client{name: "unknown", conn: conn, message: make([]byte, 100)}
+  defer ResetClient(client)
+
+  SendString(client, "Hello good sir. What is your name?(less than 100 character and no special characters)\n")
+  for {
+    _, err := conn.Read(client.message)
+    if err != nil {
+      SendString(client, "Something went wrong. Try again.")
+      continue
+    }
+
+    for i := 0; i < len(client.message) - 1; i++ {
+      if (string)(client.message[i:i+2]) == "\r\n" {
+        client.name = (string)(client.message[:i])
+        break;
+      }
+    }
+
+    if !IsChacterAllowed(([]byte)(client.name)) {
+      SendString(client, "Only allow alphabets.")
+      continue
+    }
+    if client.name[0] == (byte)('\r') {
+      continue
+    }
+    ResetClientMessage(client)
+    break
+  }
+
+  clients[client.conn.RemoteAddr().String()] = client
+
+  // Hnadle all messages.
+  for {
+    err_n := 0
+
+    if err_n > 10 {
+      break;
+    }
+
+    _, err := conn.Read(client.message)
+    if err != nil {
+      Loggers("Something went wrong")
+      err_n += 1
+    }
+    if bytes.Equal(([]byte)("close"), client.message[:5]) { 
+      break
+    } else {
+      fmt.Println("Working....")
+      SendToAll(client)
+    }
+  }
+}
+
+func main() { 
+  PORT := ":4200";
+  server_conn, err := net.Listen("tcp", PORT)
+  fmt.Println("Running on ", server_conn.Addr().String())
+
+  if err != nil {
+    Loggers("Couldn't run the server")
+  }
+  for {
+    conn, err := server_conn.Accept()
+    if err != nil {
+      Loggers("Couldn't accept a client")
+    }
+    go HandleConnection(conn)
+  }
+}
+