diff --git a/habbgo/server/session.go b/habbgo/server/session.go index 3af85e8..748bc25 100644 --- a/habbgo/server/session.go +++ b/habbgo/server/session.go @@ -2,22 +2,29 @@ package server import ( "bufio" + "bytes" "github.com/jtieri/HabbGo/habbgo/server/protocol/packets" "github.com/jtieri/HabbGo/habbgo/utils/encoding" "log" "net" + "sync" ) type Session struct { connection net.Conn - buffer bufio.Writer + buffer *buffer + active bool server *server } +type buffer struct { + mux sync.Mutex + buff *bufio.Writer +} + // Listen starts listening for incoming data from a Session and handles it appropriately. func (session *Session) Listen() { - // TODO Create Player - + // TODO create player and add to list of online players reader := bufio.NewReader(session.connection) // TODO Send HELLO packet to initialize connection @@ -30,7 +37,7 @@ func (session *Session) Listen() { b, err := reader.ReadByte() if err != nil { - // TODO handle errors reading packets + // TODO handle errors parsing packets session.Close() return } @@ -38,45 +45,71 @@ func (session *Session) Listen() { } length := encoding.DecodeB64(encodedLen) - // Get Base64 encoded packet header - rawHeader := make([]byte, 2) - for i := 0; i < 2; i++ { - rawHeader[i], _ = reader.ReadByte() - } - // Check if data is junk before handling - var rawPacket []byte + rawPacket := make([]byte, length) bytesRead, err := reader.Read(rawPacket) if length == 0 || err != nil || bytesRead < length { - // TODO handle logging junk packets + log.Println("Junk packet received.") // TODO handle logging junk packets continue } + // Get Base64 encoded packet header + payload := bytes.NewBuffer(rawPacket) + rawHeader := make([]byte, 2) + for i := 0; i < 2; i++ { + rawHeader[i], _ = payload.ReadByte() + } + // Create a struct for the packet, and pass it on to be handled. - packet := packets.NewIncoming(rawHeader, rawPacket) - log.Printf("Received packet %v with contents: %v ", packet.HeaderId, packet.Payload.String()) // TODO REMOVE THIS DUMB TEST + packet := packets.NewIncoming(rawHeader, payload) + log.Printf("Received packet [{%v} - %v] with contents: %v ", packet.Header, packet.HeaderId, packet.Payload.String()) // TODO handle packets coming in from player's Session } } func (session *Session) Send(packet *packets.OutgoingPacket) { packet.Finish() - session.buffer.Write(packet.Payload.Bytes()) - session.buffer.Flush() + session.buffer.mux.Lock() + defer session.buffer.mux.Unlock() + + _, err := session.buffer.buff.Write(packet.Payload.Bytes()) + if err != nil { + log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.connection.LocalAddr(), err) + } + + err = session.buffer.buff.Flush() + if err != nil { + log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.connection.LocalAddr(), err) + } } func (session *Session) Queue(packet *packets.OutgoingPacket) { packet.Finish() - session.buffer.Write(packet.Payload.Bytes()) + session.buffer.mux.Lock() + defer session.buffer.mux.Unlock() + + _, err := session.buffer.buff.Write(packet.Payload.Bytes()) + if err != nil { + log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.connection.LocalAddr(), err) + } } func (session *Session) Flush(packet *packets.OutgoingPacket) { - session.buffer.Flush() + session.buffer.mux.Lock() + defer session.buffer.mux.Unlock() + + err := session.buffer.buff.Flush() + if err != nil { + log.Printf("Error sending packet %v to session %v \n %v ", packet.Header, session.connection.LocalAddr(), err) + } } // Close disconnects a Session from the server. func (session *Session) Close() { + log.Printf("Closing session for address: %v ", session.connection.LocalAddr()) session.server.RemoveSession(session) session.server = nil - session.connection.Close() + session.buffer = nil + _ = session.connection.Close() + session.active = false }