Adding first code for new go-based dedicated server.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/*****************************************************************************
|
||||
* PokerTH dedicated server *
|
||||
* Copyright (C) 2014 Lothar May *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* *
|
||||
* Additional permission under GNU AGPL version 3 section 7 *
|
||||
* *
|
||||
* If you modify this program, or any covered work, by linking or *
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a *
|
||||
* modified version of that library), containing parts covered by the *
|
||||
* terms of the OpenSSL or SSLeay licenses, the authors of PokerTH *
|
||||
* (Felix Hammer, Florian Thauer, Lothar May) grant you additional *
|
||||
* permission to convey the resulting work. *
|
||||
* Corresponding Source for a non-source form of such a combination *
|
||||
* shall include the source code for the parts of OpenSSL used as well *
|
||||
* as that of the covered work. *
|
||||
*****************************************************************************/
|
||||
package gameserver
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
type Dispatcher struct {
|
||||
handler PacketHandler
|
||||
receiver chan SessionPacket
|
||||
lastSessionId uint32
|
||||
}
|
||||
|
||||
func NewDispatcher(handler PacketHandler) *Dispatcher {
|
||||
return &Dispatcher{handler, make(chan SessionPacket, RECV_DISPATCHER_NUM_PACKET_BUF), 0}
|
||||
}
|
||||
|
||||
func (d *Dispatcher) GetReceiver() *chan SessionPacket {
|
||||
return &d.receiver
|
||||
}
|
||||
|
||||
func (d *Dispatcher) GetNextSessionId() uint32 {
|
||||
return atomic.AddUint32(&d.lastSessionId, 1)
|
||||
}
|
||||
|
||||
func (d *Dispatcher) Run() {
|
||||
var sessionPacket SessionPacket
|
||||
for {
|
||||
select {
|
||||
case sessionPacket = <-d.receiver:
|
||||
log.Printf("Packet in dispatcher session %d type %d", sessionPacket.session.id, sessionPacket.packet.GetMessageType())
|
||||
d.handler.HandlePacket(sessionPacket.session, sessionPacket.packet)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*****************************************************************************
|
||||
* PokerTH dedicated server *
|
||||
* Copyright (C) 2014 Lothar May *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* *
|
||||
* Additional permission under GNU AGPL version 3 section 7 *
|
||||
* *
|
||||
* If you modify this program, or any covered work, by linking or *
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a *
|
||||
* modified version of that library), containing parts covered by the *
|
||||
* terms of the OpenSSL or SSLeay licenses, the authors of PokerTH *
|
||||
* (Felix Hammer, Florian Thauer, Lothar May) grant you additional *
|
||||
* permission to convey the resulting work. *
|
||||
* Corresponding Source for a non-source form of such a combination *
|
||||
* shall include the source code for the parts of OpenSSL used as well *
|
||||
* as that of the covered work. *
|
||||
*****************************************************************************/
|
||||
package gameserver
|
||||
|
||||
import (
|
||||
"code.google.com/p/goprotobuf/proto"
|
||||
"container/list"
|
||||
"log"
|
||||
"pokerth"
|
||||
)
|
||||
|
||||
type PacketHandler interface {
|
||||
HandlePacket(session *Session, packet *pokerth.PokerTHMessage)
|
||||
}
|
||||
|
||||
type Lobby struct {
|
||||
sessions *list.List
|
||||
}
|
||||
|
||||
func NewLobby() *Lobby {
|
||||
return &Lobby{list.New()}
|
||||
}
|
||||
|
||||
func (l *Lobby) AddSession(session *Session) {
|
||||
log.Print("New session")
|
||||
l.sessions.PushBack(session)
|
||||
announce := &pokerth.PokerTHMessage{
|
||||
MessageType: pokerth.PokerTHMessage_PokerTHMessageType.Enum(pokerth.PokerTHMessage_Type_AnnounceMessage),
|
||||
AnnounceMessage: &pokerth.AnnounceMessage{
|
||||
ProtocolVersion: &pokerth.AnnounceMessage_Version{
|
||||
MajorVersion: proto.Uint32(NET_VERSION_MAJOR),
|
||||
MinorVersion: proto.Uint32(NET_VERSION_MINOR),
|
||||
},
|
||||
LatestGameVersion: &pokerth.AnnounceMessage_Version{
|
||||
MajorVersion: proto.Uint32(POKERTH_VERSION_MAJOR),
|
||||
MinorVersion: proto.Uint32(POKERTH_VERSION_MINOR),
|
||||
},
|
||||
LatestBetaRevision: proto.Uint32(0),
|
||||
ServerType: pokerth.AnnounceMessage_ServerType.Enum(pokerth.AnnounceMessage_serverTypeInternetAuth),
|
||||
NumPlayersOnServer: proto.Uint32(0),
|
||||
},
|
||||
}
|
||||
session.sender <- announce
|
||||
}
|
||||
|
||||
func (l *Lobby) HandlePacket(session *Session, packet *pokerth.PokerTHMessage) {
|
||||
log.Print("packet")
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*****************************************************************************
|
||||
* PokerTH dedicated server *
|
||||
* Copyright (C) 2014 Lothar May *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* *
|
||||
* Additional permission under GNU AGPL version 3 section 7 *
|
||||
* *
|
||||
* If you modify this program, or any covered work, by linking or *
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a *
|
||||
* modified version of that library), containing parts covered by the *
|
||||
* terms of the OpenSSL or SSLeay licenses, the authors of PokerTH *
|
||||
* (Felix Hammer, Florian Thauer, Lothar May) grant you additional *
|
||||
* permission to convey the resulting work. *
|
||||
* Corresponding Source for a non-source form of such a combination *
|
||||
* shall include the source code for the parts of OpenSSL used as well *
|
||||
* as that of the covered work. *
|
||||
*****************************************************************************/
|
||||
package gameserver
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"pokerth"
|
||||
)
|
||||
|
||||
const NET_HEADER_SIZE uint32 = 4
|
||||
|
||||
type PacketSerializer interface {
|
||||
ReadPacket(buf []byte, num uint32) (uint32, *pokerth.PokerTHMessage)
|
||||
WritePacket(buf []byte, packet *pokerth.PokerTHMessage) uint32
|
||||
}
|
||||
|
||||
func readPacketRaw(buf []byte, num uint32) (uint32, *pokerth.PokerTHMessage) {
|
||||
packet := &pokerth.PokerTHMessage{}
|
||||
err := packet.Unmarshal(buf[0:num])
|
||||
if err != nil {
|
||||
packet = nil
|
||||
}
|
||||
return num, packet
|
||||
}
|
||||
|
||||
func readPacketWithHeader(buf []byte, num uint32) (uint32, *pokerth.PokerTHMessage) {
|
||||
var bytesScanned uint32 = 0
|
||||
var packetSize uint32 = 0
|
||||
packet := &pokerth.PokerTHMessage{}
|
||||
if num >= NET_HEADER_SIZE {
|
||||
packetSize = binary.BigEndian.Uint32(buf[0:NET_HEADER_SIZE])
|
||||
if packetSize <= 0 {
|
||||
bytesScanned = NET_HEADER_SIZE
|
||||
} else if num >= NET_HEADER_SIZE+packetSize {
|
||||
bytesScanned, packet = readPacketRaw(buf[NET_HEADER_SIZE:], NET_HEADER_SIZE+packetSize)
|
||||
}
|
||||
}
|
||||
return bytesScanned, packet
|
||||
}
|
||||
|
||||
func writePacketGeneric(buf []byte, packet *pokerth.PokerTHMessage, headerSize uint32) uint32 {
|
||||
var bytesWritten uint32 = 0
|
||||
num, err := packet.MarshalTo(buf[headerSize:])
|
||||
if err == nil {
|
||||
if headerSize > 0 {
|
||||
binary.BigEndian.PutUint32(buf[0:headerSize], uint32(num))
|
||||
bytesWritten = uint32(num) + headerSize
|
||||
} else {
|
||||
bytesWritten = uint32(num)
|
||||
}
|
||||
}
|
||||
return bytesWritten
|
||||
}
|
||||
|
||||
type RawPacketSerializer struct {
|
||||
}
|
||||
|
||||
func (RawPacketSerializer) ReadPacket(buf []byte, num uint32) (uint32, *pokerth.PokerTHMessage) {
|
||||
return readPacketRaw(buf, num)
|
||||
}
|
||||
|
||||
func (RawPacketSerializer) WritePacket(buf []byte, packet *pokerth.PokerTHMessage) uint32 {
|
||||
return writePacketGeneric(buf, packet, 0)
|
||||
}
|
||||
|
||||
type HeaderPacketSerializer struct {
|
||||
}
|
||||
|
||||
func (HeaderPacketSerializer) ReadPacket(buf []byte, num uint32) (uint32, *pokerth.PokerTHMessage) {
|
||||
return readPacketWithHeader(buf, num)
|
||||
}
|
||||
|
||||
func (HeaderPacketSerializer) WritePacket(buf []byte, packet *pokerth.PokerTHMessage) uint32 {
|
||||
return writePacketGeneric(buf, packet, NET_HEADER_SIZE)
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*****************************************************************************
|
||||
* PokerTH dedicated server *
|
||||
* Copyright (C) 2014 Lothar May *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* *
|
||||
* Additional permission under GNU AGPL version 3 section 7 *
|
||||
* *
|
||||
* If you modify this program, or any covered work, by linking or *
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a *
|
||||
* modified version of that library), containing parts covered by the *
|
||||
* terms of the OpenSSL or SSLeay licenses, the authors of PokerTH *
|
||||
* (Felix Hammer, Florian Thauer, Lothar May) grant you additional *
|
||||
* permission to convey the resulting work. *
|
||||
* Corresponding Source for a non-source form of such a combination *
|
||||
* shall include the source code for the parts of OpenSSL used as well *
|
||||
* as that of the covered work. *
|
||||
*****************************************************************************/
|
||||
package gameserver
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"pokerth"
|
||||
)
|
||||
|
||||
const POKERTH_VERSION_MAJOR = 1
|
||||
const POKERTH_VERSION_MINOR = 11
|
||||
|
||||
const NET_VERSION_MAJOR = 5
|
||||
const NET_VERSION_MINOR = 1
|
||||
|
||||
const MAX_PACKET_SIZE uint32 = 384
|
||||
const RECV_BUF_SIZE uint32 = 4 * MAX_PACKET_SIZE
|
||||
const SEND_BUF_SIZE uint32 = 2 * MAX_PACKET_SIZE
|
||||
const SEND_NUM_PACKET_BUF = 2048
|
||||
const RECV_DISPATCHER_NUM_PACKET_BUF = 2048
|
||||
|
||||
type Session struct {
|
||||
id uint32
|
||||
PacketSerializer
|
||||
Connection net.Conn
|
||||
sender chan *pokerth.PokerTHMessage
|
||||
receiver *chan SessionPacket
|
||||
}
|
||||
|
||||
type SessionPacket struct {
|
||||
session *Session
|
||||
packet *pokerth.PokerTHMessage
|
||||
}
|
||||
|
||||
func NewSession(id uint32, serializer PacketSerializer, conn net.Conn, receiver *chan SessionPacket) *Session {
|
||||
return &Session{id, serializer, conn, make(chan *pokerth.PokerTHMessage, SEND_NUM_PACKET_BUF), receiver}
|
||||
}
|
||||
|
||||
func (s *Session) Run() {
|
||||
// run sender as separate goroutine
|
||||
go s.handleSend()
|
||||
s.handleReceive()
|
||||
}
|
||||
|
||||
func (s *Session) handleReceive() {
|
||||
// close connection on exit
|
||||
defer s.Connection.Close()
|
||||
|
||||
var buf [RECV_BUF_SIZE]byte
|
||||
var bufPos uint32 = 0
|
||||
for {
|
||||
// read upto RECV_BUF_SIZE bytes
|
||||
num, err := s.Connection.Read(buf[bufPos:])
|
||||
bufPos += uint32(num)
|
||||
if err != nil {
|
||||
log.Printf("Read error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
bytesScanned, packet := s.ReadPacket(buf[0:bufPos], bufPos)
|
||||
|
||||
if bytesScanned > 0 {
|
||||
if packet == nil {
|
||||
log.Print("Invalid packet")
|
||||
} else {
|
||||
log.Printf("Packet in: %d\n", packet.GetMessageType())
|
||||
*s.receiver <- SessionPacket{s, packet}
|
||||
remainingBytes := bufPos - bytesScanned
|
||||
if remainingBytes > 0 {
|
||||
copy(buf[0:], buf[bytesScanned:remainingBytes])
|
||||
bufPos = remainingBytes
|
||||
} else {
|
||||
bufPos = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) handleSend() {
|
||||
var buf [RECV_BUF_SIZE]byte
|
||||
var packet *pokerth.PokerTHMessage
|
||||
for {
|
||||
select {
|
||||
case packet = <-s.sender:
|
||||
packetSize := s.WritePacket(buf[0:RECV_BUF_SIZE], packet)
|
||||
if packetSize > 0 {
|
||||
var bufStart uint32 = 0
|
||||
for bufStart < packetSize {
|
||||
num, err := s.Connection.Write(buf[bufStart:packetSize])
|
||||
if err != nil {
|
||||
log.Printf("Write error: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
bufStart += uint32(num)
|
||||
}
|
||||
log.Printf("Packet out: %d, size: %d\n", packet.GetMessageType(), packetSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*****************************************************************************
|
||||
* PokerTH dedicated server *
|
||||
* Copyright (C) 2014 Lothar May *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
* *
|
||||
* Additional permission under GNU AGPL version 3 section 7 *
|
||||
* *
|
||||
* If you modify this program, or any covered work, by linking or *
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a *
|
||||
* modified version of that library), containing parts covered by the *
|
||||
* terms of the OpenSSL or SSLeay licenses, the authors of PokerTH *
|
||||
* (Felix Hammer, Florian Thauer, Lothar May) grant you additional *
|
||||
* permission to convey the resulting work. *
|
||||
* Corresponding Source for a non-source form of such a combination *
|
||||
* shall include the source code for the parts of OpenSSL used as well *
|
||||
* as that of the covered work. *
|
||||
*****************************************************************************/
|
||||
package main
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.net/websocket"
|
||||
"gameserver"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var lobby *gameserver.Lobby
|
||||
var dispatcher *gameserver.Dispatcher
|
||||
|
||||
func main() {
|
||||
lobby = gameserver.NewLobby()
|
||||
dispatcher = gameserver.NewDispatcher(lobby)
|
||||
go dispatcher.Run()
|
||||
|
||||
listener, err := net.Listen("tcp", ":7234")
|
||||
if err != nil {
|
||||
log.Fatalf("Listen error: %s", err.Error())
|
||||
}
|
||||
go acceptSockets(listener)
|
||||
|
||||
server := websocket.Server{Handler: handleWebsocketConn}
|
||||
http.Handle("/pokerthwebsocket", server)
|
||||
http.ListenAndServe(":7233", nil)
|
||||
}
|
||||
|
||||
func acceptSockets(listener net.Listener) {
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
if err != nil {
|
||||
log.Fatalf("Accept error: %s\n", err.Error())
|
||||
}
|
||||
s := gameserver.NewSession(dispatcher.GetNextSessionId(), gameserver.HeaderPacketSerializer{}, conn, dispatcher.GetReceiver())
|
||||
lobby.AddSession(s)
|
||||
go s.Run()
|
||||
}
|
||||
}
|
||||
|
||||
func handleWebsocketConn(ws *websocket.Conn) {
|
||||
ws.PayloadType = websocket.BinaryFrame
|
||||
s := gameserver.NewSession(dispatcher.GetNextSessionId(), gameserver.RawPacketSerializer{}, ws, dispatcher.GetReceiver())
|
||||
lobby.AddSession(s)
|
||||
s.Run()
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user