abandon gorm for mariadb/sql

This commit is contained in:
jtieri 2021-09-08 21:14:06 -05:00
parent cd11807251
commit 6ad1717bc9
19 changed files with 327 additions and 284 deletions

View File

@ -4,8 +4,8 @@ server:
maxconns: 2
debug: true
db:
user: ""
password: ""
host: ""
port: 0
name: ""
user: "root"
password: "password"
host: "127.0.0.1"
port: 3306
name: "habbgo"

View File

@ -67,11 +67,11 @@ func InitDefaultConfig() *Config {
Debug: true,
}
db := &DatabaseCfg{
User: "",
Password: "",
Host: "",
Port: 0,
Name: "",
User: "root",
Password: "password",
Host: "127.0.0.1",
Port: 3306,
Name: "habbgo",
}
return &Config{
Server: server,

View File

@ -1,24 +0,0 @@
package database
// Categories retrieves the navigator categories found in database table room_categories and returns them as a slice of
// Category structs.
//func (navRepo *NavRepo) Categories() []model.Category {
// rows, err := navRepo.database.Query("SELECT * FROM room_categories")
// if err != nil {
// log.Printf("%v", err)
// }
// defer rows.Close()
//
// var categories []model.Category
// for rows.Next() {
// var cat model.Category
// err = rows.Scan(&cat.Id, &cat.Pid, &cat.Node, &cat.Name, &cat.Public, &cat.Trading, &cat.MinRankAccess)
// if err != nil {
// log.Printf("%v", err)
// }
//
// categories = append(categories, cat)
// }
//
// return categories
//}

View File

@ -1,55 +0,0 @@
package database
//func Login(player *model.Player, username string, password string) bool {
// var pw, name string
// err := player.Session.Database().QueryRow("SELECT P.passwrd, P.username FROM Players P WHERE P.username = ?", username).Scan(&pw, &name)
//
// if err != nil {
// log.Printf("%v ", err) // TODO log database errors properly
// }
//
// if password == pw {
// player.Details.Username = name
// fillDetails(player)
// return true
// }
//
// return false
//}
//func LoadBadges(player *model.Player) {
// rows, err := player.Session.Database().Query("SELECT P.badge FROM Players_Badges P WHERE P.pid = ?", player.Details.Id)
// if err != nil {
// log.Printf("%v ", err) // TODO properly log error
// }
// defer rows.Close()
//
// var badges []string
// for rows.Next() {
// var badge string
// err := rows.Scan(&badge)
// if err != nil {
// log.Printf("%v ", err) // TODO properly log error
// }
//
// badges = append(badges, badge)
// }
//
// player.Details.Badges = badges
//}
//func fillDetails(p *model.Player) {
// query := "SELECT P.id, P.username, P.sex, P.figure, P.pool_figure, P.film, P.credits, P.tickets, P.motto, " +
// "P.console_motto, P.current_badge, P.display_badge, P.last_online, P.sound_enabled " +
// "FROM Players P " +
// "WHERE P.username = ?"
//
// err := p.Session.Database().QueryRow(query, p.Details.Username).Scan(&p.Details.Id, &p.Details.Username,
// &p.Details.Sex, &p.Details.Figure, &p.Details.PoolFigure, &p.Details.Film, &p.Details.Credits,
// &p.Details.Tickets, &p.Details.Motto, &p.Details.ConsoleMotto, &p.Details.CurrentBadge, &p.Details.DisplayBadge,
// &p.Details.LastOnline, &p.Details.SoundEnabled)
//
// if err != nil {
// log.Printf("%v ", err) // TODO log database errors properly
// }
//}

View File

@ -1,33 +0,0 @@
package database
//func (rr *RoomRepo) RoomsByPlayerId(id int) []*model.Room {
// stmt, err := rr.database.Prepare("SELECT r.id, r.cat_id, r.name, r.`desc`, r.ccts, r.wallpaper, r.floor, r.landscape, r.owner_id, r.owner_name, r.show_owner, r.sudo_users, r.access_type, r.password, r.current_visitors, r.max_visitors, r.rating FROM rooms r WHERE r.owner_id = ?")
// if err != nil {
// log.Printf("%v", err)
// }
// defer stmt.Close()
//
// rows, err := stmt.Query(id)
// if err != nil {
// log.Printf("%v", err)
// }
// defer rows.Close()
//
// var rooms []*model.Room
// for rows.Next() {
// room := new(model.Room)
// room.Details = new(model.Data)
//
// err := rows.Scan(&room.Details.Id, &room.Details.CatId, &room.Details.Name, &room.Details.Desc, &room.Details.CCTs,
// &room.Details.Wallpaper, &room.Details.Floor, &room.Details.Landscape, &room.Details.Owner_Id, &room.Details.Owner_Name,
// &room.Details.ShowOwner, &room.Details.SudoUsers, &room.Details.AccessType, &room.Details.Password,
// &room.Details.CurrentVisitors, &room.Details.MaxVisitors, &room.Details.Rating)
// if err != nil {
// log.Printf("%v", err)
// }
//
// rooms = append(rooms, room)
// }
//
// return rooms
//}

View File

@ -0,0 +1,38 @@
package navigator
import (
"database/sql"
"log"
)
type NavRepo struct {
database *sql.DB
}
// NewNavRepo returns a new instance of NavRepo for use in the navigator service.
func NewNavRepo(db *sql.DB) *NavRepo {
return &NavRepo{database: db}
}
// Categories retrieves the navigator categories found in database table room_categories and returns them as a slice of
// Category structs.
func (navRepo *NavRepo) Categories() []Category {
rows, err := navRepo.database.Query("SELECT * FROM room_categories")
if err != nil {
log.Printf("%v", err)
}
defer rows.Close()
var categories []Category
for rows.Next() {
var cat Category
err = rows.Scan(&cat.Id, &cat.Pid, &cat.Node, &cat.Name, &cat.Public, &cat.Trading, &cat.MinRankAccess)
if err != nil {
log.Printf("%v", err)
}
categories = append(categories, cat)
}
return categories
}

View File

@ -1,8 +1,8 @@
package navigator
import (
room2 "github.com/jtieri/HabbGo/habbgo/game/room"
"gorm.io/gorm"
"database/sql"
"github.com/jtieri/HabbGo/habbgo/game/room"
"sync"
)
@ -10,9 +10,9 @@ var ns *navService
var nonce sync.Once
type navService struct {
//repo *database.NavRepo
nav *Navigator
mux *sync.Mutex
repo *NavRepo
nav *Navigator
mux *sync.Mutex
}
// NavigatorService will initialize the single instance of navService if it is the first time it is called and then it
@ -20,9 +20,9 @@ type navService struct {
func NavigatorService() *navService {
nonce.Do(func() {
ns = &navService{
nav: new(Navigator),
mux: &sync.Mutex{},
repo: nil,
nav: new(Navigator),
mux: &sync.Mutex{},
}
})
@ -30,14 +30,14 @@ func NavigatorService() *navService {
}
// SetDBCon is called when a NavService struct is allocated initially so that it has access to the applications db.
func (ns *navService) SetDBCon(db gorm.DB) {
//ns.repo = database.NewNavRepo(db)
func (ns *navService) SetDBCon(db *sql.DB) {
ns.repo = NewNavRepo(db)
}
// BuildNavigator retrieves the room categories from the database and builds the in-game Navigator with them.
//func (ns *navService) BuildNavigator() {
// ns.nav.Categories = ns.repo.Categories()
//}
func (ns *navService) BuildNavigator() {
ns.nav.Categories = ns.repo.Categories()
}
// CategoryById retrieves a navigator category given the int parameter id and returns it if there is a match.
func (ns *navService) CategoryById(id int) *Category {
@ -66,9 +66,9 @@ func (ns *navService) CategoriesByParentId(pid int) []*Category {
func CurrentVisitors(cat *Category) int {
visitors := 0
for _, room := range room2.RoomService().Rooms() {
if room.Details.CatId == cat.Id {
visitors += room.Details.CurrentVisitors
for _, r := range room.RoomService().Rooms() {
if r.Details.CatId == cat.Id {
visitors += r.Details.CurrentVisitors
}
}
@ -78,9 +78,9 @@ func CurrentVisitors(cat *Category) int {
func MaxVisitors(cat *Category) int {
visitors := 0
for _, room := range room2.RoomService().Rooms() {
if room.Details.CatId == cat.Id {
visitors += room.Details.MaxVisitors
for _, r := range room.RoomService().Rooms() {
if r.Details.CatId == cat.Id {
visitors += r.Details.MaxVisitors
}
}

View File

@ -1,6 +1,7 @@
package player
import (
"database/sql"
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
)
@ -32,6 +33,7 @@ type Session interface {
Send(packet *packets.OutgoingPacket)
Queue(packet *packets.OutgoingPacket)
Flush(packet *packets.OutgoingPacket)
Database() *sql.DB
Close()
}

View File

@ -0,0 +1,59 @@
package player
import (
"log"
)
func LoginDB(player *Player, username string, password string) bool {
var pw, name string
err := player.Session.Database().QueryRow("SELECT P.passwrd, P.username FROM Players P WHERE P.username = ?", username).Scan(&pw, &name)
if err != nil {
log.Printf("%v ", err) // TODO log database errors properly
}
if password == pw {
player.Details.Username = name
fillDetails(player)
return true
}
return false
}
func LoadBadges(player *Player) {
rows, err := player.Session.Database().Query("SELECT P.badge FROM Players_Badges P WHERE P.pid = ?", player.Details.Id)
if err != nil {
log.Printf("%v ", err) // TODO properly log error
}
defer rows.Close()
var badges []string
for rows.Next() {
var badge string
err := rows.Scan(&badge)
if err != nil {
log.Printf("%v ", err) // TODO properly log error
}
badges = append(badges, badge)
}
player.Details.Badges = badges
}
func fillDetails(p *Player) {
query := "SELECT P.id, P.username, P.sex, P.figure, P.pool_figure, P.film, P.credits, P.tickets, P.motto, " +
"P.console_motto, P.current_badge, P.display_badge, P.last_online, P.sound_enabled " +
"FROM Players P " +
"WHERE P.username = ?"
err := p.Session.Database().QueryRow(query, p.Details.Username).Scan(&p.Details.Id, &p.Details.Username,
&p.Details.Sex, &p.Details.Figure, &p.Details.PoolFigure, &p.Details.Film, &p.Details.Credits,
&p.Details.Tickets, &p.Details.Motto, &p.Details.ConsoleMotto, &p.Details.CurrentBadge, &p.Details.DisplayBadge,
&p.Details.LastOnline, &p.Details.SoundEnabled)
if err != nil {
log.Printf("%v ", err) // TODO log database errors properly
}
}

View File

@ -8,7 +8,7 @@ func Login(player *Player) {
// Check if player is banned & if so send USER_BANNED
// Log IP address to Conn
// database.LoadBadges(player)
LoadBadges(player)
// If Config has alerts enabled, send player ALERT

View File

@ -0,0 +1,50 @@
package room
import (
"database/sql"
"log"
)
type RoomRepo struct {
database *sql.DB
}
func NewRoomRepo(db *sql.DB) *RoomRepo {
return &RoomRepo{database: db}
}
func (rr *RoomRepo) RoomsByPlayerId(id int) []*Room {
stmt, err := rr.database.Prepare("SELECT r.id, r.cat_id, r.name, r.`desc`, r.ccts, r.wallpaper, r.floor, r.landscape, r.owner_id, r.owner_name, r.show_owner, r.sudo_users, r.access_type, r.password, r.current_visitors, r.max_visitors, r.rating FROM rooms r WHERE r.owner_id = ?")
if err != nil {
log.Printf("%v", err)
}
defer stmt.Close()
rows, err := stmt.Query(id)
if err != nil {
log.Printf("%v", err)
}
defer rows.Close()
var rooms []*Room
for rows.Next() {
r := new(Room)
r.Details = new(Data)
err := rows.Scan(&r.Details.Id, &r.Details.CatId, &r.Details.Name, &r.Details.Desc, &r.Details.CCTs,
&r.Details.Wallpaper, &r.Details.Floor, &r.Details.Landscape, &r.Details.Owner_Id, &r.Details.Owner_Name,
&r.Details.ShowOwner, &r.Details.SudoUsers, &r.Details.AccessType, &r.Details.Password,
&r.Details.CurrentVisitors, &r.Details.MaxVisitors, &r.Details.Rating)
if err != nil {
log.Printf("%v", err)
}
rooms = append(rooms, r)
}
return rooms
}
func (rr *RoomRepo) fillData(data *Data) {
}

View File

@ -1,7 +1,7 @@
package room
import (
"gorm.io/gorm"
"database/sql"
"strings"
"sync"
)
@ -12,14 +12,14 @@ var ronce sync.Once
const PublicRoomOffset = 1000
type roomService struct {
//repo *database.RoomRepo
repo *RoomRepo
rooms map[int]*Room
}
func RoomService() *roomService {
ronce.Do(func() {
rs = &roomService{
repo: nil,
rooms: make(map[int]*Room, 50),
}
})
@ -27,8 +27,8 @@ func RoomService() *roomService {
return rs
}
func (rs *roomService) SetDBConn(db gorm.DB) {
//rs.repo = database.NewRoomRepo(db)
func (rs *roomService) SetDBConn(db *sql.DB) {
rs.repo = NewRoomRepo(db)
}
func (rs *roomService) Rooms() []*Room {
@ -46,9 +46,9 @@ func (rs *roomService) RoomById(id int) *Room {
return nil
}
//func (rs *roomService) RoomsByPlayerId(id int) []*model.Room {
// return rs.repo.RoomsByPlayerId(id)
//}
func (rs *roomService) RoomsByPlayerId(id int) []*Room {
return rs.repo.RoomsByPlayerId(id)
}
func (rs *roomService) RoomByModelName(name string) *Room {
return &Room{}

View File

@ -1,11 +1,13 @@
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jtieri/HabbGo/habbgo/config"
"github.com/jtieri/HabbGo/habbgo/game/navigator"
"github.com/jtieri/HabbGo/habbgo/game/room"
"github.com/jtieri/HabbGo/habbgo/server"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"log"
)
@ -16,34 +18,27 @@ func main() {
c := config.LoadConfig("config.yml")
log.Println("Attempting to make connection with the database... ")
db, err := gorm.Open(sqlite.Open(c.DB.Name), &gorm.Config{})
host := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v", c.DB.User, c.DB.Password, c.DB.Host, c.DB.Port, c.DB.Name)
db, err := sql.Open("mysql", host)
if err != nil {
log.Fatal("Failed to connect to the database: " + err.Error())
log.Fatal(err)
}
/*
host := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v", c.DB.User, c.DB.Password, c.DB.Host, c.DB.Port, c.DB.Name)
err = db.Ping()
if err != nil {
log.Fatalf("Failed to connect to database %v at %v:%v %v", c.DB.Name, c.DB.Host, c.DB.Port, err)
}
defer db.Close()
log.Printf("Successfully connected to database %v at %v:%v ", c.DB.Name, c.DB.Host, c.DB.Port)
db, err := sql.Open("mysql", host)
if err != nil {
log.Fatal(err)
}
log.Printf("Setting up in-game services and models...")
navigator.NavigatorService().SetDBCon(db)
navigator.NavigatorService().BuildNavigator()
err = db.Ping()
if err != nil {
log.Fatalf("Failed to connect to database %v at %v:%v %v", c.DB.Name, c.DB.Host, c.DB.Port, err)
}
defer db.Close()
log.Printf("Successfully connected to database %v at %v:%v ", c.DB.Name, c.DB.Host, c.DB.Port)
*/
room.RoomService().SetDBConn(db)
//log.Printf("Setting up in-game services and models...")
//service.NavigatorService().SetDBCon(db)
//service.NavigatorService().BuildNavigator()
//
//service.RoomService().SetDBConn(db)
//
//log.Println("Starting the game server... ")
log.Println("Starting the game server... ")
gameServer := server.New(c, db)
gameServer.Start()

View File

@ -9,7 +9,8 @@ import (
"strings"
)
func ComposeNavNodeInfo(player *player.Player, cat *navigator.Category, nodeMask bool, subcats []*navigator.Category, rooms []*room.Room, currentVisitors int, maxVisitors int) *packets.OutgoingPacket {
func ComposeNavNodeInfo(player *player.Player, cat *navigator.Category, nodeMask bool, subcats []*navigator.Category,
rooms []*room.Room, currentVisitors int, maxVisitors int) *packets.OutgoingPacket {
p := packets.NewOutgoing(220) // Base64 Header C\
p.WriteBool(nodeMask) // hideCategory
@ -30,9 +31,9 @@ func ComposeNavNodeInfo(player *player.Player, cat *navigator.Category, nodeMask
p.WriteInt(len(rooms))
}
for _, room := range rooms {
if room.Details.Owner_Id == 0 { // if room is public
desc := room.Details.Desc
for _, r := range rooms {
if r.Details.Owner_Id == 0 { // if r is public
desc := r.Details.Desc
var door int
if strings.Contains(desc, "/") {
@ -41,33 +42,33 @@ func ComposeNavNodeInfo(player *player.Player, cat *navigator.Category, nodeMask
door, _ = strconv.Atoi(data[1])
}
//p.WriteInt(room.Details.Id + room.PublicRoomOffset) // writeInt roomId
p.WriteInt(1) // writeInt 1
p.WriteString(room.Details.Name) // writeString roomName
p.WriteInt(room.Details.CurrentVisitors) // writeInt currentVisitors
p.WriteInt(room.Details.MaxVisitors) // writeInt maxVisitors
p.WriteInt(room.Details.CatId) // writeInt catId
p.WriteString(desc) // writeString roomDesc
p.WriteInt(room.Details.Id) // writeInt roomId
p.WriteInt(door) // writeInt door
p.WriteString(room.Details.CCTs) // writeString roomCCTs
p.WriteInt(0) // writeInt 0
p.WriteInt(1) // writeInt 1
p.WriteInt(r.Details.Id + room.PublicRoomOffset) // writeInt roomId
p.WriteInt(1) // writeInt 1
p.WriteString(r.Details.Name) // writeString roomName
p.WriteInt(r.Details.CurrentVisitors) // writeInt currentVisitors
p.WriteInt(r.Details.MaxVisitors) // writeInt maxVisitors
p.WriteInt(r.Details.CatId) // writeInt catId
p.WriteString(desc) // writeString roomDesc
p.WriteInt(r.Details.Id) // writeInt roomId
p.WriteInt(door) // writeInt door
p.WriteString(r.Details.CCTs) // writeString roomCCTs
p.WriteInt(0) // writeInt 0
p.WriteInt(1) // writeInt 1
} else {
p.WriteInt(room.Details.Id)
p.WriteString(room.Details.Name)
p.WriteInt(r.Details.Id)
p.WriteString(r.Details.Name)
// TODO check that player is owner of room, that room is showing owner name, or that player has right SEE_ALL_ROOMOWNERS
if player.Details.Username == room.Details.Owner_Name {
p.WriteString(room.Details.Owner_Name)
// TODO check that player is owner of r, that r is showing owner name, or that player has right SEE_ALL_ROOMOWNERS
if player.Details.Username == r.Details.Owner_Name {
p.WriteString(r.Details.Owner_Name)
} else {
p.WriteString("-")
}
//p.WriteString(room.AccessType(room.Details.AccessType))
p.WriteInt(room.Details.CurrentVisitors)
p.WriteInt(room.Details.MaxVisitors)
p.WriteString(room.Details.Desc)
p.WriteString(room.AccessType(r.Details.AccessType))
p.WriteInt(r.Details.CurrentVisitors)
p.WriteInt(r.Details.MaxVisitors)
p.WriteString(r.Details.Desc)
}
}

View File

@ -1,25 +1,26 @@
package composers
import (
"strconv"
"github.com/jtieri/HabbGo/habbgo/game/player"
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
"strconv"
)
func ComposeUserObj(player *player.Player) *packets.OutgoingPacket {
p := packets.NewOutgoing(5) // Base64 Header @E
func ComposeUserObj(p *player.Player) *packets.OutgoingPacket {
packet := packets.NewOutgoing(5) // Base64 Header @E
p.WriteString(strconv.Itoa(player.Details.Id))
p.WriteString(player.Details.Username)
p.WriteString(player.Details.Figure)
p.WriteString(player.Details.Sex)
p.WriteString(player.Details.Motto)
p.WriteInt(player.Details.Tickets)
p.WriteString(player.Details.PoolFigure)
p.WriteInt(player.Details.Film)
//p.WriteInt(directMail)
packet.WriteString(strconv.Itoa(p.Details.Id))
packet.WriteString(p.Details.Username)
packet.WriteString(p.Details.Figure)
packet.WriteString(p.Details.Sex)
packet.WriteString(p.Details.Motto)
packet.WriteInt(p.Details.Tickets)
packet.WriteString(p.Details.PoolFigure)
packet.WriteInt(p.Details.Film)
//packet.WriteInt(directMail)
return p
return packet
}
func ComposeCreditBalance(credits int) *packets.OutgoingPacket {
@ -28,23 +29,23 @@ func ComposeCreditBalance(credits int) *packets.OutgoingPacket {
return p
}
func ComposeAvailableBadges(player *player.Player) *packets.OutgoingPacket {
p := packets.NewOutgoing(229) // Base64 Header
func ComposeAvailableBadges(p *player.Player) *packets.OutgoingPacket {
packet := packets.NewOutgoing(229) // Base64 Header
p.WriteInt(len(player.Details.Badges))
packet.WriteInt(len(p.Details.Badges))
var bSlot int
for i, b := range player.Details.Badges {
p.WriteString(b)
for i, b := range p.Details.Badges {
packet.WriteString(b)
if b == player.Details.CurrentBadge {
if b == p.Details.CurrentBadge {
bSlot = i
}
}
p.WriteInt(bSlot)
p.WriteBool(player.Details.DisplayBadge)
return p
packet.WriteInt(bSlot)
packet.WriteBool(p.Details.DisplayBadge)
return packet
}
func ComposeSoundSetting(ss int) *packets.OutgoingPacket {

View File

@ -18,25 +18,25 @@ func HandleGetSessionParams(player *player.Player, packet *packets.IncomingPacke
player.Session.Send(composers.ComposeSessionParams())
}
func HandleSSO(player *player.Player, packet *packets.IncomingPacket) {
func HandleSSO(p *player.Player, packet *packets.IncomingPacket) {
token := packet.ReadString()
// TODO if player login with token is success login, otherwise send LOCALISED ERROR & disconnect from server
// TODO if p login with token is success login, otherwise send LOCALISED ERROR & disconnect from server
if token == "" {
//player.Login(player)
player.Login(p)
} else {
}
}
func HandleTryLogin(player *player.Player, packet *packets.IncomingPacket) {
//username := packet.ReadString()
//password := packet.ReadString()
func HandleTryLogin(p *player.Player, packet *packets.IncomingPacket) {
username := packet.ReadString()
password := packet.ReadString()
//if database.Login(player, username, password) {
// service.Login(player)
// player.Session.Send(composers.ComposeLoginOk())
//} else {
// // TODO send LOCALISED ERROR
//}
if player.LoginDB(p, username, password) {
player.Login(p)
p.Session.Send(composers.ComposeLoginOk())
} else {
// TODO send LOCALISED ERROR
}
}

View File

@ -1,43 +1,51 @@
package handlers
//func HandleNavigate(player *model.Player, packet *packets.IncomingPacket) {
// roomService := service.RoomService()
//
// nodeMask := packet.ReadInt()==1
// catId := packet.ReadInt()
//
// if catId >= service.PublicRoomOffset {
// room := roomService.RoomById(catId - service.PublicRoomOffset)
// if room != nil {
// catId = room.Details.CatId
// }
// }
//
// category := service.NavigatorService().CategoryById(catId)
//
// // TODO also check that access rank isnt higher than players rank
// if category == nil {
// return
// }
//
// subCategories := service.NavigatorService().CategoriesByParentId(category.Id)
// // sort categories by player count
//
// currentVisitors := service.CurrentVisitors(category)
// maxVisitors := service.MaxVisitors(category)
//
// var rooms []*model.Room
// if category.Public {
// for _, room := range roomService.ReplaceRooms(roomService.RoomsByPlayerId(0)) {
// if room.Details.CatId == category.Id && (!nodeMask) && room.Details.CurrentVisitors < room.Details.MaxVisitors {
// rooms = append(rooms, room)
// }
// }
// } else {
// // TODO finish private room logic
// }
//
// // TODO sort rooms by player count before sending NavNodeInfo
//
// player.Session.Send(composers.ComposeNavNodeInfo(player, category, nodeMask, subCategories, rooms, currentVisitors, maxVisitors))
//}
import (
"github.com/jtieri/HabbGo/habbgo/game/navigator"
"github.com/jtieri/HabbGo/habbgo/game/player"
"github.com/jtieri/HabbGo/habbgo/game/room"
"github.com/jtieri/HabbGo/habbgo/protocol/composers"
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
)
func HandleNavigate(player *player.Player, packet *packets.IncomingPacket) {
roomService := room.RoomService()
nodeMask := packet.ReadInt() == 1
catId := packet.ReadInt()
if catId >= room.PublicRoomOffset {
r := roomService.RoomById(catId - room.PublicRoomOffset)
if r != nil {
catId = r.Details.CatId
}
}
category := navigator.NavigatorService().CategoryById(catId)
// TODO also check that access rank isnt higher than players rank
if category == nil {
return
}
subCategories := navigator.NavigatorService().CategoriesByParentId(category.Id)
// sort categories by player count
currentVisitors := navigator.CurrentVisitors(category)
maxVisitors := navigator.MaxVisitors(category)
var rooms []*room.Room
if category.Public {
for _, room := range roomService.ReplaceRooms(roomService.RoomsByPlayerId(0)) {
if room.Details.CatId == category.Id && (!nodeMask) && room.Details.CurrentVisitors < room.Details.MaxVisitors {
rooms = append(rooms, room)
}
}
} else {
// TODO finish private room logic
}
// TODO sort rooms by player count before sending NavNodeInfo
player.Session.Send(composers.ComposeNavNodeInfo(player, category, nodeMask, subCategories, rooms, currentVisitors, maxVisitors))
}

View File

@ -1,8 +1,8 @@
package server
import (
"database/sql"
"github.com/jtieri/HabbGo/habbgo/config"
"gorm.io/gorm"
"log"
"net"
"os"
@ -12,12 +12,12 @@ import (
type Server struct {
Config *config.Config
Database *gorm.DB
Database *sql.DB
activeSessions []*Session
}
// New returns a pointer to a newly allocated server struct.
func New(config *config.Config, db *gorm.DB) *Server {
func New(config *config.Config, db *sql.DB) *Server {
return &Server{
Config: config,
Database: db,

View File

@ -3,19 +3,20 @@ package server
import (
"bufio"
"bytes"
"database/sql"
"log"
"net"
"sync"
"github.com/jtieri/HabbGo/habbgo/game/player"
"github.com/jtieri/HabbGo/habbgo/protocol/composers"
"github.com/jtieri/HabbGo/habbgo/protocol/encoding"
"github.com/jtieri/HabbGo/habbgo/protocol/packets"
"gorm.io/gorm"
"log"
"net"
"sync"
)
type Session struct {
connection net.Conn
database *gorm.DB
database *sql.DB
buffer *buffer
active bool
server *Server
@ -119,7 +120,7 @@ func (session *Session) Queue(packet *packets.OutgoingPacket) {
}
}
// Send finalizes an outgoing packet with 0x01 and then attempts flush the packet to a Sessions's buffer.
// Flush Send finalizes an outgoing packet with 0x01 and then attempts flush the packet to a Sessions's buffer.
func (session *Session) Flush(packet *packets.OutgoingPacket) {
session.buffer.mux.Lock()
defer session.buffer.mux.Unlock()
@ -135,7 +136,7 @@ func (session *Session) Flush(packet *packets.OutgoingPacket) {
}
// Database returns a pointer to a Session's Conn access struct.
func (session *Session) Database() *gorm.DB {
func (session *Session) Database() *sql.DB {
return session.database
}