110 lines
3.2 KiB
Clojure
110 lines
3.2 KiB
Clojure
(ns wiktionary-tf2.main
|
|
(:require [clojure.java.io :as io]
|
|
[babashka.fs :as fs]
|
|
[babashka.process :as p]
|
|
[clj-rcon.core :as rcon]
|
|
[clojure.tools.logging :as l]
|
|
[clojure.string :as str]
|
|
[hawkeye.core :as hawk])
|
|
(:gen-class))
|
|
|
|
(def log-file
|
|
(-> "~/.local/share/Steam/steamapps/common/Team Fortress 2/tf/console.log"
|
|
fs/expand-home
|
|
fs/file))
|
|
|
|
(def words-file "words.gz")
|
|
|
|
(def ^:dynamic *rcon*)
|
|
|
|
(defn lookup-word [word]
|
|
(->> (p/shell {:out :string}
|
|
"zgrep"
|
|
(format "^%s\t" word)
|
|
words-file)
|
|
:out
|
|
str/split-lines
|
|
(map #(nth (re-matches #"([^\t]*)\t(.*)\n?" %)
|
|
2 nil))
|
|
(filter #(not (empty? %))) ; remove nil and ""
|
|
first))
|
|
|
|
(defn parse-chat-message [x]
|
|
(when-let [[_ _dead? author body]
|
|
(re-matches #"(\*사망\* )?(.*?) : (.*)" x)]
|
|
{:author author :body body}))
|
|
|
|
(defn say-word [word]
|
|
(->> (format "%s: %s" word (or (lookup-word word)
|
|
"no entry found }:("))
|
|
(take 128)
|
|
(apply str)
|
|
(format "say \"%s\"")
|
|
(rcon/exec *rcon*)))
|
|
|
|
(defn find-word [s]
|
|
(some-> (or (re-find #"\[\[([^]]+)]]" s)
|
|
(re-find #"define\s+(\w+)" s))
|
|
second))
|
|
|
|
(defn do-definition [s]
|
|
(when-some [w (find-word s)]
|
|
(l/infof "looking up word: %s" w)
|
|
(say-word w)))
|
|
|
|
(defn rcon-connect [host port password]
|
|
(l/info "attempting rcon connection...")
|
|
(or (try (let [c @(rcon/connect host port password)]
|
|
@(rcon/exec c "echo \"WIKTIONARY CONNECTED!!!\"")
|
|
(l/info "connected to rcon!")
|
|
c)
|
|
(catch java.net.ConnectException e
|
|
(l/info (ex-message e))
|
|
nil))
|
|
(do (Thread/sleep 5000)
|
|
(recur host port password))))
|
|
|
|
(defn handle-console-event [s]
|
|
(l/infof "! %s" s)
|
|
(when-let [{:keys [author body]} (parse-chat-message s)]
|
|
(do-definition body)))
|
|
|
|
(defonce prev-size
|
|
(atom (if (fs/exists? log-file)
|
|
(-> log-file slurp count)
|
|
0)))
|
|
|
|
(defn handler []
|
|
(let [prev @prev-size
|
|
content (slurp log-file)
|
|
size (count content)]
|
|
(try (cond (< prev size) (-> content
|
|
(subs prev)
|
|
str/trim-newline
|
|
handle-console-event)
|
|
(< size prev) (l/warn "log file shrunk?")
|
|
:else nil)
|
|
(finally (reset! prev-size size)))))
|
|
|
|
(defn start-watcher! []
|
|
(hawk/watch (str (fs/parent log-file))
|
|
(bound-fn* (fn [ev]
|
|
(when (= (str (fs/file-name log-file))
|
|
(:file ev))
|
|
(handler))))
|
|
(fn [e ctx]
|
|
(l/error e "error in watcher"))))
|
|
|
|
(defn start-logger! []
|
|
@(rcon/exec *rcon* (format "con_logfile %s"
|
|
(fs/file-name log-file)))
|
|
@(rcon/exec *rcon* "echo \"wiktionary logging now\"")
|
|
(Thread/sleep 400)
|
|
(l/info "logfile has been set up!"))
|
|
|
|
(defn -main []
|
|
(binding [*rcon* (rcon-connect "127.0.0.1" 27015 "monitor")]
|
|
(start-logger!)
|
|
(start-watcher!)
|
|
(read-line)))
|