diff options
| author | 2025-12-30 19:33:39 +0300 | |
|---|---|---|
| committer | 2025-12-30 19:33:39 +0300 | |
| commit | d317e8f6df0e0e16445db606da1d683a6b35f531 (patch) | |
| tree | 4b80de04e17a137cff2dc309508b5f841f48c994 /cmd | |
| download | qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.tar.gz qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.tar.bz2 qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.tar.xz qchat-d317e8f6df0e0e16445db606da1d683a6b35f531.zip | |
начальный коммит
Diffstat (limited to 'cmd')
| -rw-r--r-- | cmd/qchat/main.go | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/cmd/qchat/main.go b/cmd/qchat/main.go new file mode 100644 index 0000000..0e28ab5 --- /dev/null +++ b/cmd/qchat/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "context" + "encoding/pem" + "errors" + "flag" + "fmt" + "log/slog" + "os" + "os/signal" + + "go.neonxp.ru/qchat/internal/chat" + "go.neonxp.ru/qchat/internal/config" + "go.neonxp.ru/qchat/internal/server" + "golang.org/x/crypto/ed25519" + "golang.org/x/crypto/ssh" + "golang.org/x/sync/errgroup" +) + +var ( + configFile = flag.String("config", "./config.json", "Config file") + debug = flag.Bool("debug", false, "Debug mode") + version string +) + +func main() { + flag.Parse() + if *configFile == "" { + flag.Usage() + os.Exit(1) + } + + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill) + defer cancel() + + slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{}))) + if *debug { + slog.SetLogLoggerLevel(slog.LevelDebug) + } + + slog.InfoContext(ctx, "qChat by NeonXP. https://neonxp.ru/", slog.String("version", version)) + + cfg, err := config.Load(*configFile) + if err != nil && !errors.Is(err, os.ErrNotExist) { + panic(err) + } + if err != nil { + hostname, err := os.Hostname() + if err != nil { + panic(err) + } + _, privKey, err := ed25519.GenerateKey(nil) + if err != nil { + panic(err) + } + + privateKeyOpenSSH, err := ssh.MarshalPrivateKey(privKey, "") + if err != nil { + panic(fmt.Sprintf("Failed to marshal private key: %v", err)) + } + + cfg = &config.Config{ + Server: config.Server{ + PrivateKey: string(pem.EncodeToMemory(privateKeyOpenSSH)), + Addr: ":1337", + Name: hostname, + }, + Channels: []config.Channel{ + {Name: "main"}, + }, + } + + slog.InfoContext(ctx, "no config file. creating new.", slog.String("config", *configFile)) + if err := config.Save(*configFile, cfg); err != nil { + panic(err) + } + } + + ch := chat.New(cfg) + + serv := server.New(cfg, ch) + + eg, ectx := errgroup.WithContext(ctx) + + eg.Go(func() error { return ch.Run(ectx) }) + + eg.Go(func() error { return serv.Run(ectx) }) + + if err := eg.Wait(); err != nil { + panic(err) + } +} |
