--[[ Descripttion:战斗房间 version: Author: Neo,Huang Date: 2023-11-16 23:24:42 LastEditors: Neo,Huang LastEditTime: 2023-11-16 23:25:34 --]] local lib_battle_redis = require("lib_battle_redis") local timeUtil = require("utils.timeUtil") local redisBattleUtil = require("redisBattleUtil") local util_player = require("utils.util_player") local battleData = require("data.battle") local boxAdapt = require("adapt.boxAdapt") local root = {} local function _get_global_room_key() return "global:room" end local function _get_room_key(id) return string.format("room:%s", tostring(id)) end local function _get_active_room_id_key() return "active:rooms" end -- 分配房间ID function root:gen_room_id() local key = _get_global_room_key() local subKey = "max:room:id" local id = lib_battle_redis:hincrby(key, subKey, 1) if id > 200000000 then id = 1 lib_battle_redis:hset(key, subKey, id) end return id end -- 获取当前活跃房间ID列表 function root:get_active_room_id_list() local key = _get_active_room_id_key() return lib_battle_redis:smembers(key) end -- 打包房间玩家信息 function root:pack_room_player_info(roomId, uid) local info = self:get_room_player_info(roomId, uid) if is_empty(info) then return end info.playerInfo = util_player:get_base_info(uid) return info end -- 打包房间玩家信息列表 function root:pack_room_player_info_list(playerList) if is_empty(playerList) then return end local infoList = {} for _, v in ipairs(playerList) do local info = { playerInfo = util_player:get_base_info(v.uid), seatId = v.seatId, status = v.status } table.insert(infoList, info) end return infoList end -- 打包房间信息 function root:pack_room_info(roomId) if is_empty(roomId) then return end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then return end local info = { roomId = roomId, playCount = redisBattleUtil.hget_int(key, "playCount"), battleBoxList = redisBattleUtil.hget_json(key, "boxIdList"), status = redisBattleUtil.hget_int(key, "status"), createTime = redisBattleUtil.hget_int(key, "createTime") } -- 玩家信息列表 local playerList = redisBattleUtil.hget_json(key, "playerList") info.playerList = self:pack_room_player_info_list(playerList) return info end -- 打包所有房间信息 function root:pack_room_info_list() local roomIdList = self:get_active_room_id_list() if is_empty(roomIdList) then return end local roomInfoList = {} for _, v in ipairs(roomIdList) do local roomId = tonumber(v) local info = self:pack_room_info(roomId) if not is_empty(info) then table.insert(roomInfoList, info) end end return roomInfoList end -- 打包玩家房间信息 function root:pack_player_room_info(uid) if is_empty(uid) then return end local roomId = battleData:get_room_id(uid) if is_empty(roomId) then return end return self:pack_room_info(roomId) end -- 创建房间 function root:create_room(uid, playCount, boxIdList) if is_empty(uid) then return false end if is_empty(playCount) or playCount < 2 or playCount > 3 then return false end if is_empty(boxIdList) or #boxIdList < 1 then return false end local roomId = self:gen_room_id() -- 设置房间信息 local playerList = {{uid = uid, seatId = 1, status = 1}} local key = _get_room_key(roomId) redisBattleUtil.hset(key, "createTime", timeUtil.now()) -- 创建时间 redisBattleUtil.hset(key, "hostUid", uid) -- 房主 redisBattleUtil.hset(key, "playCount", playCount) -- 战斗人数 redisBattleUtil.hset(key, "boxIdList", boxIdList) -- 战斗箱子ID列表 redisBattleUtil.hset(key, "playerList", playerList) -- 玩家列表 redisBattleUtil.hset(key, "status", 0) -- 战斗状态 -- 房间进入准备战斗集合 key = _get_active_room_id_key() lib_battle_redis:sadd(key, roomId) return true, roomId end -- 房间是否存在 function root:is_room_exist(roomId) local key = _get_room_key(roomId) -- 房间是否存在 return lib_battle_redis:exists(key) end -- 座位是否已被占 function root:get_seat_player(roomId, seatId) if is_empty(roomId) or is_empty(seatId) then return end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then return end local playerList = redisBattleUtil.hget_json(key, "playerList") for _, v in ipairs(playerList) do if v.seatId and v.seatId == seatId then return v.uid end end end -- 进入房间 function root:enter_room(uid, roomId) if is_empty(uid) or is_empty(roomId) then return false end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then return false end local playerList = redisBattleUtil.hget_json(key, "playerList") for _, v in ipairs(playerList) do if v.uid == uid then -- 玩家已进入房间 return false end end table.insert(playerList, {uid = uid, status = 0}) redisBattleUtil.hset(key, "playerList", playerList) return true end -- 坐下 function root:seat_down(uid, roomId, seatId) if is_empty(uid) or is_empty(roomId) or is_empty(seatId) then return false end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then return false end local isMatch = false local playerList = redisBattleUtil.hget_json(key, "playerList") for _, v in ipairs(playerList) do if v.uid == uid then v.seatId = seatId v.status = 1 isMatch = true break end end if not isMatch then table.insert(playerList, {uid = uid, seatId = seatId, status = 1}) end redisBattleUtil.hset(key, "playerList", playerList) return true end -- 站起 function root:stand_up(uid, roomId) if is_empty(uid) or is_empty(roomId) then return false end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then return false end local isMatch = false local playerList = redisBattleUtil.hget_json(key, "playerList") for _, v in ipairs(playerList) do if v.uid == uid then if v.seatId == nil or v.seatId == 0 then return false end v.seatId = nil v.status = 0 isMatch = true break end end if not isMatch then return false end redisBattleUtil.hset(key, "playerList", playerList) return true end -- 离开房间 function root:leave(uid, roomId) if is_empty(uid) or is_empty(roomId) then return false end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then return false end local playerList = redisBattleUtil.hget_json(key, "playerList") for k, v in ipairs(playerList) do if v.uid == uid then table.remove(playerList, k) break end end redisBattleUtil.hset(key, "playerList", playerList) return true end -- 获取房间玩家信息 function root:get_room_player_info(roomId, uid) if is_empty(roomId) or is_empty(uid) then return end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then return end local playerList = redisBattleUtil.hget_json(key, "playerList") for _, v in ipairs(playerList) do if v.uid == uid then return v end end end -- 获取房间消耗价格 function root:get_room_price(roomId) local key = _get_room_key(roomId) local boxIdList = redisBattleUtil.hget_json(key, "boxIdList") if is_empty(boxIdList) then return end return boxAdapt:battle_get_box_price(boxIdList) end -- 获取房间状态 -- 0:等待 1:进行中 2:结算 3:销毁 function root:get_room_status(roomId) if is_empty(roomId) then return 3 end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then return 3 end local status = redisBattleUtil.hget_int(key, "status") return status end -- 销毁房间 function root:destroy_room(roomId) if is_empty(roomId) then return false end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then -- 从活跃房间集合删除 lib_battle_redis:sismerber(_get_active_room_id_key(), roomId) return false end local status = redisBattleUtil.hget_int(key, "status") if status >= 0 then -- 战斗已开始 return false end -- 删除房间信息 lib_battle_redis:del(key) -- 从活跃房间集合删除 lib_battle_redis:sismerber(_get_active_room_id_key(), roomId) return true end -- 是否等待开战结束 function root:is_wait_battle_end(roomId) if is_empty(roomId) then return false end local key = _get_room_key(roomId) -- 房间是否存在 local isExist = lib_battle_redis:exists(key) if not isExist then return true end local currTime = timeUtil.now() local createTime = redisBattleUtil.hget_int(key, "createTime") local waitSeconds = 10 if currTime < createTime + waitSeconds then return false end return true end -- 房间是否开始战斗 function root:is_room_start_battle(roomId) local status = self:get_room_status(roomId) if status > 0 then return false end local seatCount = 0 local key = _get_room_key(roomId) local playerList = redisBattleUtil.hget_json(key, "playerList") for _, v in ipairs(playerList) do if v.seatId and v.seatId > 0 then seatCount = seatCount + 1 end end local playCount = redisBattleUtil.hget_int(key, "playCount") return seatCount >= playCount end ---------------------------------------- -- 接口 ---------------------------------------- local bagData = require("data.bag") -- 绑定房间 function root:band_room(uid, roomId, costItems) if is_empty(uid) or is_empty(costItems) then return end battleData:band_room(uid, roomId, costItems) -- 消耗道具 local keyEvent = string.format("room-seat-down-%s", tostring(roomId)) bagData:consume_items(uid, costItems, keyEvent) end -- 解绑房间 -- ty - 解绑类型: leave:离开 dismiss:解散 seat:更换座位 settle:结算 function root:unband_room(uid, ty) if is_empty(uid) then return end local costItems = battleData:get_room_cost_items(uid) if (ty == "leave" or ty == "dismiss" or ty == "seat") and not is_empty(costItems) then -- 返回物品 local keyEvent = string.format("room-%s", ty) bagData:add_items(uid, costItems, keyEvent) end battleData:band_room(uid) return true end return root