Skip to content

Instantly share code, notes, and snippets.

@volgar1x
Created August 4, 2012 20:59
Show Gist options
  • Save volgar1x/3259905 to your computer and use it in GitHub Desktop.
Save volgar1x/3259905 to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"fmt"
"io"
"log"
"net"
"strings"
)
const (
DOFUS_VERSION = "1.29.1"
BUFFER_SIZE = 256
NETWORK_PROTOCOL = "tcp"
VERSION_CHECK_STATE = 0
AUTH_PROCESS_STATE = 1
SERVER_SELECTION_STATE = 2
)
var (
address = flag.String("addr", "", "The address to listen on")
port = flag.Int("port", 5555, "The port to listen on")
)
func Clean(buf []byte, n int) string {
msg := string(buf[0:n])
msg = strings.Replace(msg, "\x00", "", -1)
msg = strings.Replace(msg, "\n", "", -1)
return strings.Replace(msg, "\r", "", -1)
}
func NextString() string { // TODO
return strings.Repeat("azertyui", 4) // 32 characters
}
type Client struct {
server *Server
out net.Conn
connected bool
state int
}
func NewClient(s *Server, out net.Conn) *Client {
c := new(Client)
c.server = s
c.out = out
return c
}
func (c *Client) Start() {
c.connected = true
defer c.Close()
c.server.handler.OnConnected(c)
for c.connected {
buf := make([]byte, BUFFER_SIZE)
n, err := c.out.Read(buf)
if err != nil {
c.server.handler.OnError(err)
break
}
msg := Clean(buf, n)
if err := c.server.handler.OnReceived(c, msg); err != nil {
c.server.handler.OnError(err)
}
}
c.server.handler.OnDisconnected(c)
}
func (c *Client) Close() {
c.connected = false
}
func (c *Client) Send(msg string) (int, error) {
msg = fmt.Sprint(msg, "\x00")
n, err := io.WriteString(c.out, msg)
if err != nil {
c.server.handler.OnError(err)
} else {
c.server.handler.OnSent(c, msg)
}
return n, err
}
type Handler interface {
OnError(err error)
OnConnected(c *Client) error
OnDisconnected(c *Client) error
OnSent(c *Client, msg string) error
OnReceived(c *Client, msg string) error
}
type Server struct {
running bool
listener net.Listener
handler Handler
}
func NewServer(h Handler) *Server {
s := new(Server)
s.handler = h
return s
}
func (s *Server) Accept() {
s.running = true
defer s.Stop()
for s.running {
conn, err := s.listener.Accept()
if err != nil {
s.handler.OnError(err)
break
}
c := NewClient(s, conn)
go c.Start()
}
}
func (s *Server) Start() error {
laddr := fmt.Sprint(address, ":", port)
ln, err := net.Listen(NETWORK_PROTOCOL, laddr)
if err != nil {
return err
}
s.listener = ln
go s.Accept()
return nil
}
func (s *Server) Stop() {
s.running = false
}
/**********
* HANDLER *
***********/
type MyHandler struct {
}
func (h MyHandler) OnError(err error) {
log.Fatal("Error:", err.Error())
}
func (h MyHandler) OnConnected(c *Client) error {
log.Println("Client connected !")
_, err := c.Send(fmt.Sprint("HC", NextString()))
return err
}
func (h MyHandler) OnDisconnected(c *Client) error {
log.Println("Client disconnected !")
return nil
}
func (h MyHandler) OnSent(c *Client, msg string) error {
log.Println("Send :", msg)
return nil
}
func (h MyHandler) OnReceived(c *Client, msg string) error {
log.Println("Receive :", msg)
switch c.state {
case VERSION_CHECK_STATE:
if !strings.EqualFold(msg, DOFUS_VERSION) {
log.Fatal("Client with different version (", msg, ") from server")
c.connected = false
} else {
c.state = AUTH_PROCESS_STATE
}
case AUTH_PROCESS_STATE:
log.Println("not implemented")
case SERVER_SELECTION_STATE:
log.Println("not implemented")
}
return nil
}
func main() {
flag.Parse()
s := NewServer(MyHandler{})
if err := s.Start(); err != nil {
log.Fatal("Can't start server because :", err.Error())
} else {
log.Println("Server started")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment