From 41b28d2f21eb5436dbd4bab9a4acd0ecde18bf5a Mon Sep 17 00:00:00 2001 From: Justin T <37750742+jtieri@users.noreply.github.com> Date: Mon, 13 Apr 2020 11:02:47 -0500 Subject: [PATCH] eye dee kay Old commit I had stashed. I believe I was decoupling some of the dependencies and working on making the design consistent. Should have free time soon. May refactor the shit out of this or may just start from scratch. --- habbgo/database/room_repo.go | 42 ++++++- habbgo/game/model/room.go | 4 +- habbgo/game/service/navigator_service.go | 24 ++++ habbgo/game/service/player_service.go | 2 - habbgo/game/service/room_service.go | 106 +++++++++++++++- .../protocol/composers/navigator_composers.go | 117 +++++++++++------- .../protocol/handlers/handshake_handlers.go | 1 + .../protocol/handlers/navigator_handlers.go | 36 ++++-- 8 files changed, 268 insertions(+), 64 deletions(-) diff --git a/habbgo/database/room_repo.go b/habbgo/database/room_repo.go index 11c3d95..bec6c19 100644 --- a/habbgo/database/room_repo.go +++ b/habbgo/database/room_repo.go @@ -1,6 +1,10 @@ package database -import "database/sql" +import ( + "database/sql" + "github.com/jtieri/HabbGo/habbgo/game/model" + "log" +) type RoomRepo struct { database *sql.DB @@ -9,3 +13,39 @@ type RoomRepo struct { func NewRoomRepo(db *sql.DB) *RoomRepo { return &RoomRepo{database: db} } + +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 +} + +func (rr *RoomRepo) fillData(data *model.Data) { + +} \ No newline at end of file diff --git a/habbgo/game/model/room.go b/habbgo/game/model/room.go index 92af7b2..ecb3273 100644 --- a/habbgo/game/model/room.go +++ b/habbgo/game/model/room.go @@ -3,7 +3,7 @@ package model type Room struct { Details *Data Model *Model - Map *Map + //Map *Map } type Data struct { @@ -25,8 +25,6 @@ type Data struct { CurrentVisitors int MaxVisitors int Rating int - CreatedAt string - UpdatedAt string ChildRooms []*Room } diff --git a/habbgo/game/service/navigator_service.go b/habbgo/game/service/navigator_service.go index 5de485f..2a51de6 100644 --- a/habbgo/game/service/navigator_service.go +++ b/habbgo/game/service/navigator_service.go @@ -63,3 +63,27 @@ func (ns *navService) CategoriesByParentId(pid int) []*model.Category { return categories } + +func CurrentVisitors(cat *model.Category) int { + visitors := 0 + + for _, room := range RoomService().Rooms() { + if room.Details.CatId == cat.Id { + visitors += room.Details.CurrentVisitors + } + } + + return visitors +} + +func MaxVisitors(cat *model.Category) int { + visitors := 0 + + for _, room := range RoomService().Rooms() { + if room.Details.CatId == cat.Id { + visitors += room.Details.MaxVisitors + } + } + + return visitors +} diff --git a/habbgo/game/service/player_service.go b/habbgo/game/service/player_service.go index 7648b55..4dbd635 100644 --- a/habbgo/game/service/player_service.go +++ b/habbgo/game/service/player_service.go @@ -3,7 +3,6 @@ package service import ( "github.com/jtieri/HabbGo/habbgo/database" "github.com/jtieri/HabbGo/habbgo/game/model" - "github.com/jtieri/HabbGo/habbgo/protocol/composers" ) func Login(player *model.Player) { @@ -15,7 +14,6 @@ func Login(player *model.Player) { // Log IP address to Conn database.LoadBadges(player) - go player.Session.Send(composers.ComposeLoginOk()) // If Config has alerts enabled, send player ALERT diff --git a/habbgo/game/service/room_service.go b/habbgo/game/service/room_service.go index 873ad88..b6cf5fd 100644 --- a/habbgo/game/service/room_service.go +++ b/habbgo/game/service/room_service.go @@ -4,22 +4,24 @@ import ( "database/sql" "github.com/jtieri/HabbGo/habbgo/database" "github.com/jtieri/HabbGo/habbgo/game/model" + "strings" "sync" ) var rs *roomService var ronce sync.Once +const PublicRoomOffset = 1000 type roomService struct { repo *database.RoomRepo - rooms []*model.Room + rooms map[int]*model.Room } func RoomService() *roomService { ronce.Do(func() { rs = &roomService{ repo: nil, - rooms: make([]*model.Room, 50), + rooms: make(map[int]*model.Room, 50), } }) @@ -29,3 +31,103 @@ func RoomService() *roomService { func (rs *roomService) SetDBConn(db *sql.DB) { rs.repo = database.NewRoomRepo(db) } + +func (rs *roomService) Rooms() []*model.Room { + var rooms []*model.Room + for _, room := range rs.rooms { + rooms = append(rooms, room) + } + return rooms +} + +func (rs *roomService) RoomById(id int) *model.Room { + if room, ok := rs.rooms[id]; ok { + return room + } + return nil +} + +func (rs *roomService) RoomsByPlayerId(id int) []*model.Room { + return rs.repo.RoomsByPlayerId(id) +} + +func (rs *roomService) RoomByModelName(name string) *model.Room { + return &model.Room{} +} + +func (rs *roomService) ReplaceRooms(queryRooms []*model.Room) []*model.Room { + var rooms []*model.Room + + for _, room := range queryRooms { + if _, ok := rs.rooms[room.Details.Id]; ok { + rooms = append(rooms, rs.RoomById(room.Details.Id)) + } else { + rooms = append(rooms, room) + } + } + + return rooms +} + +func AccessType(accessId int) string { + switch accessId { + case 1: + return "closed" + case 2: + return "password" + default: + return "open" + } +} + +func (rs *roomService) PublicRoom(room *model.Room) bool { + if room.Details.Owner_Id == 0 { + return true + } else { + return false + } +} + +func (rs *roomService) PublicName(room *model.Room) string { + if rs.PublicRoom(room) { + if strings.HasPrefix(room.Details.Name, "Upper Hallways") { + return "Upper Hallways" + } + + if strings.HasPrefix(room.Details.Name, "Lower Hallways") { + return "Lower Hallways" + } + + if strings.HasPrefix(room.Details.Name, "Club Massiva") { + return "Club Massiva" + } + + if strings.HasPrefix(room.Details.Name, "The Chromide Club") { + return "The Chromide Club" + } + + if room.Details.CCTs == "hh_room_gamehall,hh_games" { + return "Cunning Fox Gamehall" + } + } + + return room.Details.Name +} + +func (rs *roomService) CurrentVisitors() int { + var visitors int + + return visitors +} + +func (rs *roomService) MaxVisitors() int { + var visitors int + + return visitors +} + +func (rs *roomService) LoadChildRooms(room *model.Room) { + if room.Model.Name == "gate_park" { + room.Details.ChildRooms = append(room.Details.ChildRooms, ) + } +} \ No newline at end of file diff --git a/habbgo/protocol/composers/navigator_composers.go b/habbgo/protocol/composers/navigator_composers.go index 8f0019c..0bc597d 100644 --- a/habbgo/protocol/composers/navigator_composers.go +++ b/habbgo/protocol/composers/navigator_composers.go @@ -2,66 +2,87 @@ package composers import ( "github.com/jtieri/HabbGo/habbgo/game/model" + "github.com/jtieri/HabbGo/habbgo/game/service" "github.com/jtieri/HabbGo/habbgo/protocol/packets" + "strconv" + "strings" ) -func ComposeNavNodeInfo(player *model.Player, cat *model.Category, nodeMask bool) *packets.OutgoingPacket { +func ComposeNavNodeInfo(player *model.Player, cat *model.Category, nodeMask bool, subcats []*model.Category, rooms []*model.Room, currentVisitors int, maxVisitors int) *packets.OutgoingPacket { p := packets.NewOutgoing(220) // Base64 Header C\ - // player - // category - // rooms - // nodemask - // subCategories - // currentVisitors - // maxVisitors - // accessRank + p.WriteBool(nodeMask) // hideCategory + p.WriteInt(cat.Id) - p.WriteBool(nodeMask) // writeBool NodeMask - p.WriteInt(cat.Id) // writeInt CategoryId - p.WriteBool(cat.Public) // writeBool publicSpace - p.WriteString(cat.Name) // writeString CategoryName - // writeInt categoryCurrentVisitors - // writeInt categoryMaxVisitors - // writeInt parentCategoryId - - // if category is for public rooms writeInt numberOfRooms if cat.Public { - + p.WriteInt(0) + } else { + p.WriteInt(2) } - // iterate over rooms - // if room is public - // writeInt roomId - // writeInt 1 - // writeString roomName - // writeInt currentVisitors - // writeInt maxVisitors - // writeInt catId - // writeString roomDesc - // writeInt roomId - // writeInt door - // writeString roomCCTs - // writeInt 0 - // writeInt 1 + p.WriteString(cat.Name) + p.WriteInt(currentVisitors) + p.WriteInt(maxVisitors) + p.WriteInt(cat.Pid) - // if room is not private - // writeInt roomId - // writeString roomName - // writeString ownerName or - - // writeString accessType - // writeInt currentVisitors - // writeInt maxVisitors - // writeString roomDesc + if !cat.Public { + p.WriteInt(len(rooms)) + } + + for _, room := range rooms { + if room.Details.Owner_Id == 0 { // if room is public + desc := room.Details.Desc + + var door int + if strings.Contains(desc, "/") { + data := strings.Split(desc, "/") + desc = data[0] + door, _ = strconv.Atoi(data[1]) + } + + p.WriteInt(room.Details.Id + service.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 + } else { + p.WriteInt(room.Details.Id) + p.WriteString(room.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) + } else { + p.WriteString("-") + } + + p.WriteString(service.AccessType(room.Details.AccessType)) + p.WriteInt(room.Details.CurrentVisitors) + p.WriteInt(room.Details.MaxVisitors) + p.WriteString(room.Details.Desc) + } + } // iterate over sub-categories - // if user can access sub-cats - // writeInt subCategoryId - // writeInt 0 - // writeString subCatName - // writeInt currentVisitors - // writeInt maxVisitors - // writeInt categoryId + for _, subcat := range subcats { + if subcat.MinRankAccess > 1 { + continue + } + + p.WriteInt(subcat.Id) + p.WriteInt(0) + p.WriteString(subcat.Name) + p.WriteInt(service.CurrentVisitors(subcat))// writeInt currentVisitors + p.WriteInt(service.MaxVisitors(subcat))// writeInt maxVisitors + p.WriteInt(cat.Id) + } return p } diff --git a/habbgo/protocol/handlers/handshake_handlers.go b/habbgo/protocol/handlers/handshake_handlers.go index 4a9d3cd..2c7a282 100644 --- a/habbgo/protocol/handlers/handshake_handlers.go +++ b/habbgo/protocol/handlers/handshake_handlers.go @@ -37,6 +37,7 @@ func HandleTryLogin(player *model.Player, packet *packets.IncomingPacket) { if database.Login(player, username, password) { service.Login(player) + player.Session.Send(composers.ComposeLoginOk()) } else { // TODO send LOCALISED ERROR } diff --git a/habbgo/protocol/handlers/navigator_handlers.go b/habbgo/protocol/handlers/navigator_handlers.go index a7a4cdb..fad21c7 100644 --- a/habbgo/protocol/handlers/navigator_handlers.go +++ b/habbgo/protocol/handlers/navigator_handlers.go @@ -8,23 +8,43 @@ import ( ) func HandleNavigate(player *model.Player, packet *packets.IncomingPacket) { - nodeMask := packet.ReadBool() + roomService := service.RoomService() + + nodeMask := packet.ReadInt()==1 catId := packet.ReadInt() - // get category using catID + 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 } - // if minrank for cat is > playerRank then return without sending response - - // get sub categories of category + subCategories := service.NavigatorService().CategoriesByParentId(category.Id) // sort categories by player count - // get category currentvisitors - // get category maxvisitors + currentVisitors := service.CurrentVisitors(category) + maxVisitors := service.MaxVisitors(category) - player.Session.Send(composers.ComposeNavNodeInfo(player, category, nodeMask)) + 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)) }