Skip to content

Commit

Permalink
Major update: custom error message.
Browse files Browse the repository at this point in the history
+ A submodule called mcchat is added, to handle chat message part.
+ Config file updated, custom error message syntax added.
+ Favicon part is added, but currently not functional.
+ Config is now (not completely) validated after loaded.
* Fix: for status request, kick message is now a valid status response.
* Tried to fix that sometimes disconnection reason is netty exception.
! Seems hover and click events in status response is ignored, don't know
  if there is any way to make them work.
  • Loading branch information
jackyyf committed Feb 12, 2015
1 parent e6573e0 commit b2a97dc
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 56 deletions.
33 changes: 24 additions & 9 deletions mcchat/mcchat.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ var color_string = [...]string{
}

type Event struct {
Action string
Value string
Action string `json:"action"`
Value string `json:"value"`
}

type Style int32
type Style int

const (
BOLD Style = 1 << iota
Expand All @@ -65,12 +65,12 @@ const (
)

type ChatMsg struct {
Text string
Bold bool `json:",omitempty"`
Italic bool `json:",omitempty"`
Underlined bool `json:",omitempty"`
Strikethrough bool `json:",omitempty"`
Color string `json:",omitempty"`
Text string `json:"text"`
Bold bool `json:"bold,omitempty"`
Italic bool `json:"italic,omitempty"`
Underlined bool `json:"underlined,omitempty"`
Strikethrough bool `json:"strikethrough,omitempty"`
Color string `json:"color,omitempty"`
OnClick *Event `json:"clickEvent,omitempty"`
OnHover *Event `json:"hoverEvent,omitempty"`
ExtraMsg []*ChatMsg `json:"extra,omitempty"`
Expand Down Expand Up @@ -149,6 +149,12 @@ func (msg *ChatMsg) ClickTarget(target string) {
}
}

func (msg *ChatMsg) AppendMsg(message string) (new_msg *ChatMsg) {
new_msg = NewMsg(message)
msg.ExtraMsg = append(msg.ExtraMsg, new_msg)
return
}

func (msg *ChatMsg) AsJson() (json_data []byte) {
json_data, _ = json.Marshal(msg)
return
Expand All @@ -163,3 +169,12 @@ func (msg *ChatMsg) AsChatString() (chat_string []byte) {
buffer.Write(json_data)
return buffer.Bytes()
}

func GetColor(color string) (res Style) {
for idx, val := range color_string {
if val == color {
return Style((idx << 5) | 16)
}
}
return -1
}
12 changes: 10 additions & 2 deletions minegate/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

type Config struct {
Listen_addr string "listen"
Upstream []Upstream "upstreams"
Listen_addr string "listen"
Upstream []*Upstream "upstreams"
}

var config Config
Expand All @@ -22,6 +22,12 @@ func SetConfig(conf string) {
config_file = conf
}

func validateConfig() {
for _, upstream := range config.Upstream {
upstream.Validate()
}
}

func ConfInit() {
Debug("call: ConfInit")
content, err := ioutil.ReadFile(config_file)
Expand All @@ -34,6 +40,7 @@ func ConfInit() {
if err != nil {
Fatalf("error when parsing config file %s: %s", config_file, err.Error())
}
validateConfig()
Info("config loaded.")
Info("server listen on: " + config.Listen_addr)
Infof("%d upstream server(s) found", len(config.Upstream))
Expand All @@ -60,6 +67,7 @@ func ConfReload() {
if err != nil {
Errorf("error when parsing config file %s: %s", config_file, err.Error())
}
validateConfig()
Info("config reloaded.")
if config.Listen_addr != prev_listen {
Warnf("config reload will not reopen server socket, thus no effect on listen address")
Expand Down
16 changes: 10 additions & 6 deletions minegate/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ upstreams:
-
hostname: server1.local
upstream: 127.0.0.1:25568
motd: first sample server!
limit: 20
onerror:
text: 'Server is down :P'
color: red
bold: true
hover: 'Hover Test!'
click: 'https://jackyyf.com/'
-
hostname: '*.local'
upstream: 127.0.0.1:25566
motd: all local server!
limit: 10
onerror:
text: 'Hey, why do you want to go to this server? It does not exists!'
# If no server matched, player will be kicked, you can use a server with hostname: * to avoid such cases.
-
hostname: '*'
upstream: 127.0.0.1:25567
motd: default fallback server!
limit: 100
onerror:
text: 'Fallback is just a joke dude!'
82 changes: 61 additions & 21 deletions minegate/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@ import (

var total_online uint32

type Handshake struct {
version int
host string
port uint16
isPing bool
}

func handlePing(conn net.Conn, upstream *Upstream) {

func WaitTillClose(conn *net.TCPConn) {
buff := Allocate()
for {
n, err := conn.Read(buff)
if n > 0 {
continue
}
if err != nil {
conn.Close()
return
}
}
}

func ReadTo(conn net.Conn, queue BufferQueue, notifyqueue chan byte) {
func ReadTo(conn *net.TCPConn, queue BufferQueue, notifyqueue chan byte) {
for {
buff := Allocate()
n, err := conn.Read(buff)
Expand All @@ -28,6 +31,7 @@ func ReadTo(conn net.Conn, queue BufferQueue, notifyqueue chan byte) {
case <-notifyqueue:
close(queue)
Info("recv side signaled, closing.")
Free(buff)
return
case queue <- buff[:n]:
Debugf("recv %d bytes from %s", n, conn.RemoteAddr())
Expand All @@ -43,7 +47,7 @@ func ReadTo(conn net.Conn, queue BufferQueue, notifyqueue chan byte) {
}
}

func WriteTo(conn net.Conn, queue BufferQueue, notifyqueue chan byte) {
func WriteTo(conn *net.TCPConn, queue BufferQueue, notifyqueue chan byte) {
for {
select {
case buff := <-queue:
Expand All @@ -55,6 +59,7 @@ func WriteTo(conn net.Conn, queue BufferQueue, notifyqueue chan byte) {
select {
case <-notifyqueue:
close(queue)
Free(buff)
return
default:
}
Expand All @@ -70,17 +75,47 @@ func WriteTo(conn net.Conn, queue BufferQueue, notifyqueue chan byte) {
}
}

func startProxy(conn net.Conn, upstream *Upstream, initial []byte) {
if _, _, err := net.SplitHostPort(upstream.Server); err != nil {
upstream.Server += ":25565"
func startProxy(conn *net.TCPConn, upstream *Upstream, initial_pkt *Handshake, initial []byte, after_initial []byte) {
addr, perr := net.ResolveTCPAddr("tcp", upstream.Server)
var err error
var upconn *net.TCPConn
if perr == nil {
upconn, err = net.DialTCP("tcp", nil, addr)
}
upconn, err := net.Dial("tcp", upstream.Server)
if err != nil {
buff := Allocate()
if len(after_initial) > 0 {
if !initial_pkt.isPing || len(after_initial) != 2 {
// ping request
copy(buff, after_initial)
Warnf("has %d bytes extra data!", len(after_initial))
}
}
if err != nil || perr != nil {
if err == nil {
err = perr
}
Errorf("Unable to connect to upstream %s", upstream.Server)
KickClient(conn, "502 Bad Gateway.")
// KickClient(conn, "502 Bad Gateway.")
if initial_pkt.isPing {
Info("ping packet")
ResponsePing(conn, upstream.ChatMsg)
n := len(after_initial)
t, _ := conn.Read(buff[n:])
Debugf("recved %d bytes", t)
n += t
Debugf("ping.packet(%dbytes): "+string(buff[:n]), n)
_, _ = conn.Write(buff[:n])
WaitTillClose(conn)
} else {
Info("login packet")
Debug("kick.msg = " + string(upstream.ChatMsg.AsChatString()))
KickClientRaw(conn, upstream.ChatMsg.AsChatString())
WaitTillClose(conn)
}
conn.Close()
return
}
upconn.SetNoDelay(false)
c2squeue := NewBufferQueue(4)
s2cqueue := NewBufferQueue(32)
c2sstatus := make(chan byte, 1)
Expand All @@ -93,7 +128,11 @@ func startProxy(conn net.Conn, upstream *Upstream, initial []byte) {
}

func ServerSocket() {
s, err := net.Listen("tcp", config.Listen_addr)
addr, err := net.ResolveTCPAddr("tcp", config.Listen_addr)
if err != nil {
Fatalf("error parse address %s: %s", config.Listen_addr, err.Error())
}
s, err := net.ListenTCP("tcp", addr)
if err != nil {
Fatalf("error listening on %s: %s", config.Listen_addr, err.Error())
}
Expand All @@ -102,17 +141,18 @@ func ServerSocket() {
// 4 MB pool
InitPool(1024, 4096)
for {
conn, err := s.Accept()
conn, err := s.AcceptTCP()
if err != nil {
Warnf("listen_socket: error when accepting: %s", err.Error())
continue
}
conn.SetNoDelay(false)
Infof("listen_socket: new client %s", conn.RemoteAddr())
go ClientSocket(conn)
}
}

func ClientSocket(conn net.Conn) {
func ClientSocket(conn *net.TCPConn) {
buff := Allocate()
orig := buff
n, err := conn.Read(buff)
Expand Down Expand Up @@ -180,5 +220,5 @@ func ClientSocket(conn net.Conn) {
conn.Close()
return
}
go startProxy(conn, upstream, orig[:lenlen+curlen])
go startProxy(conn, upstream, init_packet, orig[:lenlen+curlen], pkt[pktlen:curlen])
}
Loading

0 comments on commit b2a97dc

Please sign in to comment.