USER_TDCLS = tdcls(DBASE_TDCLS, RID_TDCLS, AGENT_TDCLS, HEARTBEAT_TDCLS, ATTRIB_TDCLS)
USER_TDCLS.name = "USER_TDCLS"
function USER_TDCLS:create(value)
assert(type(value) == "table", "user::create para not corret")
self:replace_dbase(value)
self:set("ob_type", OB_TYPE_USER)
self:freeze_dbase()
self:set_temp("container", clone_object(CONTAINER_TDCLS, {rid = get_ob_rid(self)}))
end
function USER_TDCLS:destruct()
if self:query_temp("entered_world") then
self:leave_world()
remove_responder_from_raiser(self:get_ob_id())
remove_audience_from_raiser(self:get_ob_id())
USER_D.hiberate(self)
end
local account_ob = find_object_by_rid(self:query("account_rid"))
if is_object(account_ob) then
destruct_object(account_ob)
end
destruct_object(self:get_container())
destruct_object(self:get_ddz_dbase())
self:delete_logout_timer()
end
function USER_TDCLS:get_ob_id()
return (string.format("USER_TDCLS:%s:%s", save_string(self:query("rid")),
save_string(self:query("account_rid"))))
end
function USER_TDCLS:delete_logout_timer()
if is_valid_timer(self.logout_timer) then
delete_timer(self.logout_timer)
self.logout_timer = nil
end
end
function USER_TDCLS:accept_relay(agent, is_reconnect)
agent:relay_comm(self)
self:enter_world()
self:delete_logout_timer()
end
function USER_TDCLS:logout_callback()
USER_D.user_logout(self)
end
function USER_TDCLS:connection_lost(at_once)
self:set("last_logout_time", os.time())
if self:query_temp("login_act_time") ~= nil then
self:add_attrib("all_login_time", os.time() - self:query_temp("login_act_time"))
self:delete_temp("login_act_time")
end
if at_once then
USER_D.user_logout(self)
else
self:close_agent()
if not is_valid_timer(self.logout_timer) then
self.logout_timer = set_timer(30, self.logout_callback, self) end
end
REDIS_D.run_publish(REDIS_USER_CONNECTION_LOST, get_ob_rid(self))
end
function USER_TDCLS:enter_world()
self:set_heartbeat_interval(30000)
self:set_temp("entered_world", true)
raise_issue(EVENT_USER_LOGIN, self)
trace("玩家(%o %s/%s)进入游戏世界。\n", self:query("name"), get_ob_rid(self), self:query("account_rid"))
local data = {
user = self:query(),
item_list = self:get_dump_item(),
equip_list = self:get_dump_equip(),
ddz_info = self:get_ddz_dbase():query(),
}
self:send_message(MSG_ENTER_GAME, data)
self:set_temp("login_act_time", os.time())
local value = {rid=get_ob_rid(self), online=1}
USER_D.publish_user_attr_update(value)
LOG_D.to_log(LOG_TYPE_LOGIN_RECORD, get_ob_rid(self), tostring(self:query("account_rid")), "", "")
REDIS_D.run_publish(REDIS_USER_ENTER_WORLD, encode_json({rid = get_ob_rid(self), server_id = tonumber(SERVER_ID)}))
end
function USER_TDCLS:get_ob_class()
return "USER_TDCLS"
end
function USER_TDCLS:leave_world()
self:delete_hearbeat()
raise_issue(EVENT_USER_LOGOUT, self)
trace("玩家(%s/%s)离开游戏世界。\n", get_ob_rid(self), self:query("account_rid"))
self:delete_temp("entered_world")
local value = {rid=get_ob_rid(self), online=0}
USER_D.publish_user_attr_update(value)
LOG_D.to_log(LOG_TYPE_LOGOUT_RECORD, get_ob_rid(self), tostring(self:query("account_rid")), "", "")
end
function USER_TDCLS:save_to_mapping()
local change_list = self:get_change_list()
local data = {}
for key,_ in pairs(change_list) do
if USER_D.is_in_user_fields(key) then
data[key] = self:query(key)
end
end
return data
end
function USER_TDCLS:get_save_oper()
return "user", { rid = get_ob_rid(self) }
end
function USER_TDCLS:set_change_to_db(callback, arg)
local dbase = self:save_to_mapping()
arg.sql_count = arg.sql_count + 1
if is_empty_table(dbase) then
if callback then callback(arg, 0, {}) end
else
local table_name, condition = self:get_save_oper()
local sql = SQL_D.update_sql(table_name, dbase, condition)
DB_D.execute_db(table_name, sql, callback, arg)
self:freeze_dbase()
end
self:save_sub_content(callback, arg)
end
function USER_TDCLS:save_sub_content(callback, arg)
for pos, ob in pairs(self:get_container():get_carry()) do
assert(is_object(ob))
if is_object(ob) then
local dbase, is_part = ob:save_to_mapping()
if dbase then
local table_name, primary, oper = ob:get_save_oper()
local sql
if oper == "insert" then
sql = SQL_D.insert_sql(table_name, dbase)
elseif oper == "update" then
sql = SQL_D.update_sql(table_name, dbase, {rid = primary})
else
assert(false, "unknow op")
end
arg.sql_count = arg.sql_count + 1
DB_D.execute_db(table_name, sql, callback, arg)
end
end
end
self:save_obj_content(self:get_ddz_dbase(), callback, arg)
end
function USER_TDCLS:save_obj_content(ob, callback, arg)
if is_object(ob) then
ob:set_change_to_db(callback, arg)
end
end
function USER_TDCLS:notify_message_info(message, is_important)
self:send_message(MSG_MESSAGE_TIP, {msg_type = MSG_TYPE_MESSAGE, msg_info = message})
end
function USER_TDCLS:notify_dialog_ok(message, is_important)
self:send_message(MSG_MESSAGE_TIP, {msg_type = MSG_TYPE_DIALOG, msg_info = message})
end
function USER_TDCLS:notify_scroll(message, is_important)
self:send_message(MSG_MESSAGE_TIP, {msg_type = MSG_TYPE_SCROLL, msg_info = message})
end
function USER_TDCLS:is_user()
return true
end
function USER_TDCLS:notify_fields_updated(field_names)
self:notify_property_updated(get_ob_rid(self), field_names)
end
function USER_TDCLS:notify_property_loaded(rid)
local ob = find_object_by_rid(rid)
local appearance = APPEARANCE_D.get_appearance(ob, "SELF")
self:send_message(MSG_PROPERTY_LOADED, get_ob_rid(self), { appearance })
end
function USER_TDCLS:notify_property_delete(rids)
if is_string(rids) then
rids = { rids }
end
self:send_message(MSG_PROPERTY_DELETE, rids )
end
function USER_TDCLS:notify_property_updated(rid, field_names)
if is_string(field_names) then
field_names = { field_names }
end
local ob = find_object_by_rid(rid)
if not ob then
return
end
local info = APPEARANCE_D.build_object_info(ob, field_names)
self:send_message(MSG_OBJECT_UPDATED, rid, info)
end
function USER_TDCLS:save_all()
USER_D.hiberate(self)
end
function USER_TDCLS:get_attr_desc(fields)
local result = {rid=get_ob_rid(self)}
for _,v in ipairs(fields) do
result[v] = self:query(v)
end
return result
end
function USER_TDCLS:query_log_channel()
return self:query_temp("LOG_CHANNEL")
end
function USER_TDCLS:set_log_channel(channel)
self:set_temp("LOG_CHANNEL", channel)
end
function USER_TDCLS:get_container()
return self:query_temp("container")
end
function USER_TDCLS:set_ddz_dbase( ddz_info )
self:set_temp("ddz_info", clone_object(DDZ_INFO_TDCLS, get_ob_rid(self), ddz_info))
end
function USER_TDCLS:get_ddz_dbase()
return self:query_temp("ddz_info")
end
function USER_TDCLS:get_dump_item()
local result = {}
for _, data in pairs(self:get_item_dbase()) do
table.insert(result, data:query())
end
return result
end
function USER_TDCLS:get_item_dbase()
return self:get_container():get_page_carry(PAGE_ITEM)
end
function USER_TDCLS:get_dump_equip()
local result = {}
for _, data in pairs(self:get_equip_dbase()) do
table.insert(result, data:query())
end
return result
end
function USER_TDCLS:get_equip_dbase()
return self:get_container():get_page_carry(PAGE_EQUIP)
end