view gara/main.go @ 71:75de5903355c

Giagantic changes that update Dowa library to be more align with stb style array and hashmap. Updated Seobeo to be caching on server side instead of file level caching. Deleted bunch of things I don't really use.
author June Park <parkjune1995@gmail.com>
date Sun, 28 Dec 2025 20:34:22 -0800
parents c2706ffb442b
children
line wrap: on
line source

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)
  }
}