func ConfReload() { // Do not panic! defer func() { if r := recover(); r != nil { log.Errorf("paniced when reloading config %s, recovered.", config_file) log.Errorf("panic: %s", r) } }() log.Warn("Reloading config") content, err := ioutil.ReadFile(config_file) if err != nil { log.Errorf("unable to reload config %s: %s", config_file, err.Error()) return } prev_listen := config.Listen_addr config_lock.Lock() err = yaml.Unmarshal(content, &config) if err != nil { log.Errorf("error when parsing config file %s: %s", config_file, err.Error()) return } validateConfig() config_lock.Unlock() log.Info("config reloaded.") if config.Listen_addr != prev_listen { log.Warnf("config reload will not reopen server socket, thus no effect on listen address") } log.Infof("%d upstream server(s) found", len(config.Upstream)) }
func (upstream *Upstream) Validate() (valid bool) { var host, port string host, port, err := net.SplitHostPort(upstream.Server) if err != nil { server := upstream.Server + ":25565" if host, port, err = net.SplitHostPort(server); err != nil { log.Error("Invalid upstream server: " + upstream.Server) return false } log.Infof("no port information found in %s, assume 25565", upstream.Server) upstream.Server = server } p, err := strconv.ParseUint(port, 10, 16) if err != nil { log.Errorf("Invalid port %s: %s", port, err.Error()) return false } host = strings.ToLower(host) if !CheckHost(host) { log.Error("Invalid upstream host: " + host) return false } upstream.Server = net.JoinHostPort(host, fmt.Sprintf("%d", p)) upstream.Pattern = strings.ToLower(upstream.Pattern) if !CheckPattern(upstream.Pattern) { log.Error("Invalid pattern: " + upstream.Pattern) return false } if upstream.ErrorMsg.Text == "" { log.Warnf("Empty error text for %s, use default string", upstream.Server) upstream.ErrorMsg.Text = "Connection failed to " + upstream.Server } upstream.ChatMsg = ToChatMsg(&upstream.ErrorMsg) return true }
func ServerSocket() { addr, err := net.ResolveTCPAddr("tcp", config.Listen_addr) if err != nil { log.Fatalf("error parse address %s: %s", config.Listen_addr, err.Error()) } s, err := net.ListenTCP("tcp", addr) if err != nil { log.Fatalf("error listening on %s: %s", config.Listen_addr, err.Error()) } log.Infof("Server listened on %s", config.Listen_addr) for { conn, err := s.AcceptTCP() if err != nil { log.Warnf("listen_socket: error when accepting: %s", err.Error()) continue } go func(conn *WrapedSocket) { event := new(PostAcceptEvent) event.RemoteAddr = conn.RemoteAddr().(*net.TCPAddr) event.connID = conn.Id() PostAccept(event) if event.Rejected() { conn.Warnf("connection rejected.") conn.Close() return } log.Infof("connection accepted.") ClientSocket(conn, event) }(WrapClientSocket(conn)) } }
func (upstream *Upstream) GetExtra(path string) (val interface{}, err error) { defer func() { if r := recover(); r != nil { log.Errorf("Recovered panic: upstream.GetExtra(%s), err=%+v", path, r) log.Debugf("Upstream: %+v", upstream) val = nil err = errors.New("panic when getting config.") return } }() paths := strings.Split(path, ".") cur := reflect.ValueOf(upstream.Extras) // ROOT can't be an array, so assume no config path starts with # for _, path := range paths { index := strings.Split(path, "#") prefix, index := index[0], index[1:] if cur.Kind() != reflect.Map { log.Warnf("upstream.GetExtra(%s): unable to fetch key %s, not a map.", path, prefix) return nil, fmt.Errorf("index key on non-map type") } cur = reflect.ValueOf(cur.MapIndex(reflect.ValueOf(prefix)).Interface()) for _, idx := range index { i, err := strconv.ParseInt(idx, 0, 0) if err != nil { log.Errorf("upstream.GetExtra(%s): unable to parse %s: %s", path, idx, err.Error()) return nil, fmt.Errorf("Unable to parse %s: %s", idx, err.Error()) } if cur.Kind() != reflect.Slice { log.Warnf("upstream.GetExtra(%s): unable to index value, not a slice", path) return nil, errors.New("Unable to index value, not a slice.") } if int(i) >= cur.Len() { log.Warnf("upstream.GetExtra(%s): index %d out of range", path, i) return nil, errors.New("Index out of range.") } cur = reflect.ValueOf(cur.Index(int(i)).Interface()) } } return cur.Interface(), nil }
func GetUpstream(hostname string) (upstream *Upstream, err *mcchat.ChatMsg) { config_lock.Lock() defer config_lock.Unlock() log.Debugf("hostname=%s", hostname) for _, u := range config.Upstream { log.Debugf("pattern=%s", u.Pattern) if matched, _ := path.Match(u.Pattern, hostname); matched { log.Infof("matched server: %s", u.Server) return u, nil } } log.Warnf("no match for %s", hostname) return nil, config.chatNotFound }
func ToChatMsg(msg *ChatMessage) (res *mcchat.ChatMsg) { res = mcchat.NewMsg(msg.Text) msg.Color = strings.ToLower(msg.Color) if msg.Color != "" { color := mcchat.GetColor(msg.Color) if color == -1 { log.Warnf("Invalid color: %s, assume white.", msg.Color) msg.Color = "white" color = mcchat.GetColor("white") } res.SetColor(color) } res.SetBold(msg.Bold) res.SetItalic(msg.Italic) res.SetUnderlined(msg.Underlined) res.SetStrikeThrough(msg.Strikethrough) if msg.Hover != "" { res.HoverMsg(msg.Hover) } if msg.Click != "" { res.ClickTarget(msg.Click) } return }
func (event *NetworkEvent) Warnf(format string, v ...interface{}) { if event.log_prefix == "" { event.log_prefix = fmt.Sprintf("[#%d %s]", event.connID, event.RemoteAddr) } log.Warnf(event.log_prefix+format, v...) }
func (ws *WrapedSocket) Warnf(format string, v ...interface{}) { log.Warnf(ws.log_prefix+format, v...) }