room.go 4.58 KB
package roomrank

import (
	"apigame/configs/confroomrank"
	"apigame/service-common/svmysql"
	"apigame/util/util-lx/lxalilog"
	"apigame/util/util-lx/lxtime"
)

func tryInitTable(gameId string, room *Room) {
	svmysql.InitTable(room, gameId, false)
}

// SaveRoom 存储数据
func SaveRoom(gameId string, room *Room) {
	tryInitTable(gameId, room)

	room.UpdateTime = lxtime.NowUninx()
	room.Encode()

	err := svmysql.Save(room, gameId)
	if err != nil {
		lxalilog.Errors(err, "roomrank.SaveRoom error", gameId, room.Id, room.ActivityId)
		return
	}
}

// LoadRoom 获取数据
func LoadRoom(gameId string, activityId int64, roomUid int64) (room *Room, has bool) {
	room = &Room{Id: roomUid, ActivityId: activityId}
	if roomUid == 0 {
		has = false
		return
	}
	tryInitTable(gameId, room)

	var err error
	has, err = svmysql.First(room, gameId)
	if err != nil {
		lxalilog.Errors(err, "roomrank.LoadRoom error", gameId, roomUid, activityId)
		return
	}
	room.Decode()

	return
}

func CreateRoom(gameId string, activityId int64, roomConfigId int) (room *Room, has bool) {
	room = new(Room)
	room.ActivityId = activityId
	room.ConfigId = roomConfigId
	room.Closed = false
	room.CreateTime = lxtime.NowUninx()
	details := new(RoomDetails)
	details.Players = make([]*RoomPlayer, 0)
	room.Details = details

	err := svmysql.Save(room, gameId)
	if err != nil {
		has = false
	} else {
		has = true
	}
	return
}

// FindRoom 查找
func FindRoom(gameId string, activityId int64, roomConfigId int) (rooms []*Room, has bool) {
	roomDemo := &Room{ActivityId: activityId}
	tryInitTable(gameId, roomDemo)
	info := roomDemo.MysqlInfo(gameId)

	info.DbMysql = info.DbMysql.Where("config_id = ? AND closed = false", roomConfigId)
	has, _ = svmysql.Find(&rooms, info)
	for _, room := range rooms {
		room.Decode()
	}

	return
}

// TryGetRoom 尝试获取房间
func TryGetRoom(gameId string, player *Player, config *confroomrank.ActivityConfig, playerLevel int) (room *Room, hasRoom bool) {
	hasRoom = false
	if player.SettleHas {
		return
	}
	if player.ActivityId != config.Id {
		player.ActivityId = config.Id
	}
	// 查找玩家所在的房间
	room, hasRoom = LoadRoom(gameId, config.Id, player.RoomUid)
	if hasRoom {
		return
	}

	// 根据等级和分数范围查找合适的房间配置ID
	roomConfigId := 0
	roomConfig := confroomrank.RoomConfig{}
	for _, i2 := range config.Room {
		if playerLevel >= i2.Levels[0] &&
			playerLevel <= i2.Levels[1] &&
			player.UserClass == i2.UserClass {
			roomConfigId = i2.Id
			roomConfig = i2
		}
	}
	if roomConfigId == 0 {
		lxalilog.Errors("TryGetRoom find roomConfigId error", playerLevel, player.UserClass)
		return
	}
	// 数据库查找合适条件的房间列表
	rooms, has := FindRoom(gameId, config.Id, roomConfigId)
	if has {
		for i := 0; i < len(rooms); i++ {
			roomTemp := rooms[i]
			TryCloseRoom(gameId, roomTemp, roomConfig)
			if roomTemp.Closed {
				continue
			}
			// 可容纳玩家类型数量
			canJoinCount := GetTypeCanJoinCount(roomTemp, roomConfig, player.UserType)
			if canJoinCount > 0 {
				room = roomTemp
				hasRoom = true
				break
			}
		}
	}
	if hasRoom {
		// 如果有 就加入
		PlayerJoinRoom(room, player)
	} else {
		// 如果没有合适条件的房间 创建一个
		roomCreate, hasCreate := CreateRoom(gameId, config.Id, roomConfigId)
		if hasCreate {
			room = roomCreate
			PlayerJoinRoom(room, player)
			hasRoom = hasCreate
		}
	}

	return
}

func PlayerJoinRoom(room *Room, player *Player) {
	roomPlayer := NewRoomPlayer(player)
	room.Details.Players = append(room.Details.Players, roomPlayer)
	player.RoomUid = room.Id
}

// TryCloseRoom 尝试关闭房间
func TryCloseRoom(gameId string, room *Room, roomConfig confroomrank.RoomConfig) {
	secNow := lxtime.NowUninx()
	if secNow > room.CreateTime+RoomCloseSecond {
		room.Closed = true
		// 根据缺口自动填充机器人
		for i := 0; i < len(roomConfig.PlayerTypeCount); i++ {
			pair := roomConfig.PlayerTypeCount[i]
			userType := pair[0]
			canJoinCount := pair[1] - room.GetPlayerTypeCount(userType)
			robotConfigId := roomConfig.AutoRobot[i]
			for i := 0; i < canJoinCount; i++ {
				roomPlayer := NewRoomRobot(robotConfigId, userType)
				room.Details.Players = append(room.Details.Players, roomPlayer)
			}
		}
		SaveRoom(gameId, room)
	}
}

// GetTypeCanJoinCount 房间获取某种类型玩家可加入数量
func GetTypeCanJoinCount(room *Room, roomConfig confroomrank.RoomConfig, userType int) int {
	maxCount := 0
	for i := 0; i < len(roomConfig.PlayerTypeCount); i++ {
		pair := roomConfig.PlayerTypeCount[i]
		if pair[0] == userType {
			maxCount = pair[1]
			break
		}
	}
	return maxCount - room.GetPlayerTypeCount(userType)
}