ROOM_TDCLS = tdcls()
ROOM_TDCLS.name = "ROOM_TDCLS"
function ROOM_TDCLS:create(value)
assert(is_table(value), "room:create para not correct")
self.data = value
self.room_entity = {}
self:init_desk_entity()
end
function ROOM_TDCLS:destruct()
for _,data in pairs(dup(self.room_entity)) do
self:entity_destruct(data)
end
for _,table in pairs(self.desk_entity) do
destruct_object(table)
end
end
function ROOM_TDCLS:init_desk_entity()
self.desk_entity = {}
local desk_num = self.data["desk_num"] or 100
for i=1,desk_num do
self.desk_entity[i] = clone_object(self:get_desk_class(), self, i)
end
end
function ROOM_TDCLS:get_ob_id()
return (string.format("ROOM_TDCLS:%s", save_string(self:get_room_name())))
end
function ROOM_TDCLS:time_update()
for _,data in pairs(dup(self.room_entity)) do
self:entity_update(data)
end
for _,table in pairs(self.desk_entity) do
table:time_update()
end
end
function ROOM_TDCLS:entity_update(entity)
if entity.last_logout_time and os.time() - entity.last_logout_time > 10 then
if not self:is_user_playing(entity.user_rid) then
self:entity_destruct(entity.user_rid)
end
end
end
function ROOM_TDCLS:broadcast_message(msg, ...)
local size = sizeof(self.room_entity)
local config_amount = ROOM_D.get_msg_amount(msg)
local find_object_by_rid = find_object_by_rid
local is_object = is_object
local user
local msg_buf = pack_message(msg, ...)
local send_raw_message = get_class_func(USER_TDCLS, "send_raw_message")
if not msg_buf then
trace("广播消息(%d)打包消息失败。\n", msg)
return
end
for rid, info in pairs(self.room_entity) do
if info.ob_type == OB_TYPE_USER then
if math.random(1, size) < config_amount then
user = find_object_by_rid(rid)
if is_object(user) then
send_raw_message(user, msg_buf)
else
self.room_entity[rid] = nil
end
end
end
end
del_message(msg_buf)
end
function ROOM_TDCLS:entity_enter(server_id, user_rid, info)
local data = self.room_entity[user_rid]
if data then
data.server_id = server_id
data.last_op_time = os.time()
data.info = info
else
self.room_entity[user_rid] = {
user_rid = user_rid,
server_id = server_id,
last_logout_time = nil,
last_op_time = os.time(),
enter_desk_time = nil,
enter_desk_idx = nil,
info = info,
}
end
self:send_rid_message(user_rid, {}, MSG_ROOM_MESSAGE, "success_enter_room", {rid = user_rid, room_name = self:get_room_name()})
if data and data.enter_desk_idx then
self:send_rid_message(user_rid, {}, MSG_ROOM_MESSAGE, "pre_desk", {rid = user_rid, enter_desk_idx = data.enter_desk_idx})
end
return 0
end
function ROOM_TDCLS:is_user_playing(user_rid)
local entity = self.room_entity[user_rid]
if not entity then
return false
end
if not entity.enter_desk_idx then
return false
end
local desk = self.desk_entity[entity.enter_desk_idx]
if not desk then
return false
end
return desk:is_playing(user_rid)
end
function ROOM_TDCLS:entity_leave(user_rid)
if not self.room_entity[user_rid] then
LOG.err("Error:对象%s离开房间%s时找不到自己\n", user_rid, self:get_room_name())
end
local entity = self.room_entity[user_rid]
entity.last_logout_time = os.time()
if not self:is_user_playing(user_rid) then
if entity.enter_desk_idx then
local desk = self.desk_entity[entity.enter_desk_idx]
if not desk:is_playing() then
desk:user_leave(user_rid)
end
end
self:entity_destruct(user_rid)
trace("玩家不在游戏状态,掉线时离开桌子")
return
end
return 0
end
function ROOM_TDCLS:entity_destruct(user_rid)
if not self.room_entity[user_rid] then
LOG.err("Error:对象%s析构时找不到自己\n", user_rid)
end
local entity = remove_get(self.room_entity, user_rid)
return 0
end
function ROOM_TDCLS:get_can_enter_desk()
for idx, t in ipairs(self.desk_entity) do
if not t:is_full_user() then
return idx
end
end
return nil
end
function ROOM_TDCLS:enter_desk(user_rid, idx, enter_method)
local data = self.room_entity[user_rid]
if not data then
LOG.err("Error:%s进入桌子时找不到自己\n", user_rid)
return -1
end
if idx and idx == data.enter_desk_idx then
data.enter_desk_idx = nil
elseif idx == nil then
if data.enter_desk_idx then
idx = data.enter_desk_idx
data.enter_desk_idx = nil
else
idx = self:get_can_enter_desk()
end
end
if data.enter_desk_idx then
LOG.err("Error:%s已在%d桌,无法进入\n", user_rid, data.enter_desk_idx)
return -1
end
if not idx then
LOG.err("桌子已用完,无可用桌子")
return -1
end
local desk = self.desk_entity[idx]
if not desk then
LOG.err("Error:%o桌号不存在\n", idx)
return -1
end
desk:user_enter(user_rid)
data.enter_desk_idx = idx
return 0
end
function ROOM_TDCLS:send_rid_message(user_rid, record, msg, ...)
local msg_buf = pack_message(msg, ...)
if not msg_buf then
trace("广播消息(%s)打包消息失败。\n", msg)
return
end
self:send_rid_raw_message(user_rid, record, msg_buf)
del_message(msg_buf)
end
function ROOM_TDCLS:send_rid_raw_message(user_rid, record, msg_buf)
local data = self:get_data_by_rid(user_rid)
if not data or not data.server_id then
trace("获取用户%s数据失败", user_rid)
return
end
INTERNAL_COMM_D.send_server_raw_message(data.server_id, user_rid, record or {}, msg_buf:get_data())
end
function ROOM_TDCLS:desk_op(user_rid, info)
local data = self.room_entity[user_rid]
if not data then
return -1
end
local desk = self.desk_entity[data.enter_desk_idx or 0]
if not desk then
return -1
end
desk:op_info(user_rid, info)
end
function ROOM_TDCLS:get_room_name()
return self.data["room_name"]
end
function ROOM_TDCLS:get_game_type()
return self.data["game_type"]
end
function ROOM_TDCLS:get_room_entity()
return self.room_entity
end
function ROOM_TDCLS:get_data_by_rid(user_rid)
return self.room_entity[user_rid]
end
function ROOM_TDCLS:get_base_info_by_rid(user_rid)
local data = self.room_entity[user_rid]
if not data then
return nil
end
return data.info
end
function ROOM_TDCLS:is_vip()
if self.data["is_vip"] == 1 then
return true
else
return nil
end
end
function ROOM_TDCLS:get_level()
return self.data["level"]
end
function ROOM_TDCLS:get_desk_class()
return DESK_TDCLS
end
function ROOM_TDCLS:is_room()
return true
end
function ROOM_TDCLS:update_entity(rid, pkg_info)
if self.room_entity[rid] and
self.room_entity[rid]["packet"] then
self.room_entity[rid]["packet"] = pkg_info
end
end
function ROOM_TDCLS:get_listen_channel()
return string.format(REDIS_ROOM_MSG_CHANNEL_USER, self:get_room_name())
end
function ROOM_TDCLS:get_respone_channel()
return string.format(REDIS_RESPONE_ROOM_INFO, self:get_room_name())
end